Форум: "Прочее";
Текущий архив: 2009.07.12;
Скачать: [xml.tar.bz2];
ВнизКак повторить интерфейс Яндекс.Картинок. Найти похожие ветки
← →
Kolan © (2009-05-06 13:12) [0]Здравствуйте!
Хочу узнать на сколько Дельфи подойдет для реализации программы, которой сейчас занимаюсь.
Интерфейс получается похожим на выдачу Яндекс.Картинок. Прототип: http://img-fotki.yandex.ru/get/3410/ksoftware.9/0_25426_cc847473_orig
Калибровка — это документ. Внизу окна есть список калибровок, он прокручивается (пример — см. Яндекс.Картинки). Данные выбранной калибровки показываются в верхней части как предпросмотр для печати (тут надеюсь на Fast Report).
Мне кажется, что такие контейнеры для калибровок (с инфоскроллом и всем остальным) придется рисовать вручную...
Вопросы
Получится ли такое сделать на Дельфи, как считаете?
Что можно использовать для реализации?
Как бы вы подошли к реализации такого интерфейса?
Какие книжки почитать про рисование в Виндоусе и Дельфи?
← →
Игорь Шевченко © (2009-05-06 13:39) [1]
> Получится ли такое сделать на Дельфи
получится
← →
Kolan © (2009-05-06 13:48) [2]А меня берут сомнения... А рисовать самому?
← →
Игорь Шевченко © (2009-05-06 13:55) [3]
> А рисовать самому?
можно кого-нибудь попросить.
> А меня берут сомнения...
Глаза боятся, руки делают. Я не вижу ничего принципиального в твоей картинке, что нельзя было бы сделать на Delphi.
← →
KSergey © (2009-05-06 14:03) [4]Если это калибровки для типографии или, того хуже, медицины, т.е. где надо не просто градиент черого показать, а правильный градиент) - то лучше или забросить или хорошо изучить вопрос.
Я как-то взялся делать для типографии "заменитель корела" (ха-ха; не, ну про заменитель я потом узнал, изначально все выглядело весьма невинно и не про типографию).
Короче получилась откровенная какашка. Ну в сравнении с корелом. А так - вроде не плохо, да и по ТЗ.
← →
Kolan © (2009-05-06 14:18) [5]Калибровки — это просто документы. Можно о них думать, как об отчетах, выгруженных из базы каким-нибудь Фаст Репортом и сохраненных в виде *.doc файлов. Градиент — просто способ показать, что один документ создан раньше другого.
> Глаза боятся, руки делают.
Угу, боятся.
Технических знаний из «Delphi 5 Руководство разработчика» хватит для реализации, или надо еще что-то почитать?
← →
KSergey © (2009-05-06 14:23) [6]> Kolan © (06.05.09 14:18) [5]
> Технических знаний из «Delphi 5 Руководство разработчика» хватит для реализации, или надо еще что-то почитать?
Предлагаю начать делать, потом уже по конкретным вопросам что-то искать. Заранее всех книг не прочитать.
← →
@!!ex © (2009-05-06 14:24) [7]А в чем собственно проблема?
← →
Kolan © (2009-05-06 14:38) [8]
> А в чем собственно проблема?
Как обычно — с чего начать? Вот допустим есть у меня список дат. Для каждой даты надо нарисовать картинку, дату поместить снизу и чтобы все это прокручивалось. И скролл самодельный, чтобы на него даты выводились.
С чего начать? От чего унаследоваться?
← →
Игорь Шевченко © (2009-05-06 14:39) [9]
> Технических знаний из «Delphi 5 Руководство разработчика»
> хватит для реализации, или надо еще что-то почитать?
Читать надо чем больше, тем лучше. И при конкретных вопросах, смотреть в гугле, что сделали другие для решения подобных технических задач.
Могу простой пример привести - мне понадобилось в свое время обзавестись отображением бизнес-графики (диаграммы, пироги и прочие chart-ы). То, что сделано в TChart, меня категорически не устраивало, сторонние бесплатные компоненты тоже целиком, без доработки напильником, не устраивали, а дорабатывать сторонние не видел большого смысла.
После недолго поиска в гугле и пары недель разработки по идеям аналогов был написан устраивающий меня набор полукомпонент для отображения бизнес-графики.
← →
Kolan © (2009-05-06 14:43) [10]Ладно, понял, благодарю.
← →
@!!ex © (2009-05-06 15:14) [11]> [8] Kolan © (06.05.09 14:38)
> С чего начать? От чего унаследоваться?
Ни от чего наследовать не надо.
:
1) Класс пустой
2) ДОбавляем к нему Items
3) Делаем отображение Items с учетом Shift
4) Делаем скролл, который меняет Shift
← →
Игорь Шевченко © (2009-05-06 15:29) [12]
> Вот допустим есть у меня список дат. Для каждой даты надо
> нарисовать картинку, дату поместить снизу и чтобы все это
> прокручивалось.
ScrollBox ?
← →
clickmaker © (2009-05-06 15:52) [13]> дату поместить снизу и чтобы все это прокручивалось. И скролл
> самодельный, чтобы на него даты
предлагаю несколько трэкбаров: один для дня недели, второй для недель, 3-й для месяца
← →
Kolan © (2009-05-14 12:21) [14]
> clickmaker
Места жалко.
Решил нарисовать весь компонент ручную. Надо понять как это делается. Создал наследникаTCustomControl
.
Если я правильно понял теорию, то всё рисование надо делать в методеPaint;
, так?
---
Столкнулся с тем, что не понимаю как нарисовать сабж.
Допустим я умею нарисовать картиночки для каждого элемента, но как быть на краях? Как часть картинки нарисовать, а часть нет?
http://img-fotki.yandex.ru/get/3408/ksoftware.9/0_266ef_affbcc1e_orig
Может можно наложить какую-то маску?
То есть вопрос в в теории рисования такого компонента.
← →
@!!ex © (2009-05-14 12:29) [15]Рисовать блитингом на TBitMap.Canvas,Handle, с краями заморачиваться не нужно, самое все нормально обрежется.
← →
Kolan © (2009-05-14 12:42) [16]Так у TCustomControl"a нет TBitMap...
@!!ex, пожалуйста, поподробнее. Как рисовать этим самым «блиттингом» и где его взять?
Вот кр примеру я рисую:procedure TItemsList.Paint;
var
R: TRect;
I: Integer;
begin
inherited;
R.TopLeft := Point(Left, Top);
R.BottomRight := Point(Width - Left, Height - Top);
Canvas.Brush.Color := clWhite;
Canvas.FillRect(R);
for I := 0 to 20 - 1 do
begin
R.TopLeft := Point(10 + I*10, 10);
R.BottomRight := Point(20 + I*10, 20);
Canvas.Rectangle(R);
end;
end;
Все вылазит, ничего не обрезается. Можно небольшой приме, если не трудно.
← →
Servy © (2009-05-14 13:02) [17]> Как рисовать этим самым «блиттингом» и где его взять?
Создавать TBitmap в памяти нужного размера и рисовать на него. Потом копировать в место назначения. При этом, очевидно, то, что не влезло в битмап в последствии скопировано в место назначения не будет ^_^.
Также, есть небезынтересная функция SelectClipRgn, позволяющая ограничить регион канваса, на котором должно происходить рисование. А вот небольшой пример из справки:This example creates a region and selects this region as the clipping rectangle for the Image component"s canvas. It then sets the canvas"s brush color to red and calls FillRect using the ClipRect as the area to fill. Lastly, the ClipRect is reset to the original value that it contained by calling SelectClipRect with nil as the second parameter and deletes the region.
procedure Form1.Button1Click(Sender: TObject);
var
MyRgn: HRGN ;
begin
MyRgn := CreateRectRgn(100,100,200,200);
SelectClipRgn(Image1.Canvas.Handle,MyRgn);
Image1.Canvas.Brush.Color := clRed;
Image1.Canvas.FillRect(Image1.Canvas.ClipRect);
Image1.Invalidate;
SelectClipRgn(Image1.Canvas.Handle,nil);
DeleteObject(MyRgn);
end;
← →
Игорь Шевченко © (2009-05-14 13:09) [18]
> Столкнулся с тем, что не понимаю как нарисовать сабж
у программиста проконсультироваться ?
← →
Kolan © (2009-05-14 14:48) [19]
> у программиста проконсультироваться ?
>
Что, собственно, я и делаю. :)
Servy, как-то примерно так?procedure TItemsList.Paint;
var
R, RR: TRect;
I: Integer;
Bitmap: TBitmap;
begin
inherited;
Bitmap := TBitmap.Create;
try
Bitmap.Width := 100;
Bitmap.Height := 10;
for I := 0 to 10 - 1 do
begin
R := Rect(I*10, 0, I*10+10, 10);
Bitmap.Canvas.Rectangle(R);
end;
R := Rect(0, 0, Bitmap.Width, Bitmap.Height);
RR := Rect(0, 0, 100, 10);
Canvas.CopyRect(RR, Bitmap.Canvas, R);
finally
Bitmap.Free;
end;
end;
Про SelectClipRgn вроде понял, спасибо.
← →
Игорь Шевченко © (2009-05-14 14:57) [20]
> как-то примерно так?
ты представляешь, сколько раз у тебя будет вызываться Paint ?
И на каждый раз ты будешь создавать/уничтожать Bitmap фиксированного размера для использования в качестве буфера. А потом народ удивляется - а че это все так тормозит нипадеццки ?
← →
Kolan © (2009-05-14 15:01) [21]Нет, я думал сделать его полем. А принципиально? Так и нужно рисовать?
← →
Eraser © (2009-05-14 15:07) [22]> [21] Kolan © (14.05.09 15:01)
рисовать нужно на битмапе 1 раз, а потом в WM_PAINT прорисовывать нужные части битмапа на окно.
← →
Игорь Шевченко © (2009-05-14 15:09) [23]
> Нет, я думал сделать его полем. А принципиально? Так и нужно
> рисовать?
А я не знаю, что тебе нужно рисовать - пока что в твоем коде я никакого рисования не увидел
← →
Игорь Шевченко © (2009-05-14 15:10) [24]
> Допустим я умею нарисовать картиночки для каждого элемента,
> но как быть на краях? Как часть картинки нарисовать, а
> часть нет?
>
> http://img-fotki.yandex.ru/get/3408/ksoftware.9/0_266ef_affbcc1e_orig
>
> Может можно наложить какую-то маску?
>
> То есть вопрос в в теории рисования такого компонента.
тебе какую картинку по ссылке надо нарисовать - верхнюю или нижнюю ?
← →
Kolan © (2009-05-14 15:12) [25]Верхнюю. Пока вместо картинок рисую квадратики.
← →
Игорь Шевченко © (2009-05-14 15:53) [26]
> Верхнюю. Пока вместо картинок рисую квадратики.
Лови пример:object Form1: TForm1
Left = 0
Top = 0
Caption = "Form1"
ClientHeight = 286
ClientWidth = 577
Color = clWhite
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = "Tahoma"
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnPaint = FormPaint
PixelsPerInch = 96
TextHeight = 13
object SpinEdit1: TSpinEdit
Left = 84
Top = 248
Width = 121
Height = 22
MaxValue = 70
MinValue = 0
TabOrder = 0
Value = 0
OnChange = SpinEdit1Change
end
endunit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Spin;
type
TForm1 = class(TForm)
SpinEdit1: TSpinEdit;
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure SpinEdit1Change(Sender: TObject);
private
FImages: array[1..10] of TBitmap;
FClipperPos: TPoint;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
const
ImgHeight = 40;
ImgWidth = 25;
Colors: array[1..10] of TColor = (
TColor($60C1FF),TColor($B4835C),TColor($7C58A5), TColor($657C6C),
TColor($6379E6),
TColor($9AA05B),TColor($605DCF), TColor($6A8846),TColor($61A3F5),
TColor($58999E)
);
StartOfImages: TPoint = (X: 40; Y: 40);
Spacing = 20;
ClipperWidth = 150;
ClipperHeight = 60;
ClipperInc = 5;
procedure TForm1.FormCreate(Sender: TObject);
var
I: Integer;
begin
for I := Low(FImages) to High(FImages) do
begin
FImages[I] := TBitmap.Create;
FImages[I].Width := ImgWidth;
FImages[I].Height := ImgHeight;
with FImages[I].Canvas do
begin
Brush.Color := Colors[I];
FillRect(Rect(0, 0, ImgWidth, ImgHeight));
end;
end;
FClipperPos := Point(StartOfImages.X - 5, StartOfImages.Y - 5);
end;
procedure TForm1.FormPaint(Sender: TObject);
var
P: TPoint;
Image: TBitmap;
R, Clipper: TRect;
begin
Clipper := Rect(FClipperPos.X, FClipperPos.Y, FClipperPos.X + ClipperWidth,
FClipperPos.Y + ClipperHeight);
IntersectClipRect(Canvas.Handle, Clipper.Left, Clipper.Top, Clipper.Right,
Clipper.Bottom);
P := StartOfImages;
R := Rect(P.X-2, P.Y - 2, P.X + ImgWidth + 2, P.Y + ImgHeight + 2);
Canvas.Brush.Color := clBtnShadow;
for Image in FImages do
begin
Canvas.Draw(P.X, P.Y, Image);
Canvas.FrameRect(R);
Inc(P.X, Image.Width + Spacing);
OffsetRect(R, Image.Width + Spacing, 0);
end;
//Draw Clipper
InflateRect(Clipper, -1, -1);
Canvas.Brush.Color := clBlack;
Canvas.FrameRect(Clipper);
IntersectClipRect(Canvas.Handle, 0, 0, Width, Height);
end;
procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
FClipperPos.X := (StartOfImages.X - 5) + SpinEdit1.Value * ClipperInc;
Invalidate;
end;
end.
← →
Kolan © (2009-05-14 16:29) [27]Очень даже похоже, и цвета даже — благодарю.
Не понятно осталось вот что:
ПочемуIntersectClipRect
, а неSelectClipRgn
?
ЗачемInflateRect(Clipper, -1, -1);
?
АIntersectClipRect(Canvas.Handle, 0, 0, Width, Height);
в конце делается, чтобыIntersectClipRect(Canvas.Handle, Clipper.Left...
в начале сработало, так?
← →
Kolan © (2009-05-14 16:33) [28]Мне правда нужен обратный эффект, когда двигается внутренность (как в Я.Картинках). Еще до примера сделал так:
procedure TItemsList.Paint;
var
R, RR: TRect;
I: Integer;
Bitmap: TBitmap;
begin
inherited;
Bitmap := TBitmap.Create;
try
Bitmap.Width := 300;
Bitmap.Height := 10;
for I := 0 to 10 - 1 do
begin
R := Rect(I*10 + FX, 0, I*10+10+FX, 10);
Bitmap.Canvas.Rectangle(R);
end;
R := Rect(0, 0, Bitmap.Width, Bitmap.Height);
RR := Rect(0, 0, 300, 10);
Canvas.CopyRect(RR, Bitmap.Canvas, R);
finally
Bitmap.Free;
end;
end;
То есть все что не влазит по ширине в 300 просто не влазит на битмап. Такой подход нормален?
*Про то что так битмапы создавать и удалять плохо — знаю.
← →
Игорь Шевченко © (2009-05-14 17:02) [29]
> Не понятно осталось вот что:
>
> Почему IntersectClipRect, а не SelectClipRgn?
> Зачем InflateRect(Clipper, -1, -1);?
> А IntersectClipRect(Canvas.Handle, 0, 0, Width, Height);
> в конце делается, чтобы IntersectClipRect(Canvas.Handle,
> Clipper.Left... в начале сработало, так?
А справка человеку на что дадена ?
> Мне правда нужен обратный эффект, когда двигается внутренность
> (как в Я.Картинках). Еще до примера сделал так:
Все то же самое, что в примере, только окно остается неподвижным (не меняется FClipperPos), а меняется начальная точка отображения картинок, то есть вместо
P := StartOfImages;
пишется P.X := StartOfImages.X - желаемое тебе смещение
← →
Kolan © (2009-05-14 17:11) [30]
> А справка человеку на что дадена ?
Справку я, конечно, прочел.
Я не понял в чем цель вызова InflateRect, зачем делать так, чтобы 1 пиксель торчал?
Все остальное понял, попробую сделать, благодарю еще раз.
← →
Игорь Шевченко © (2009-05-14 17:27) [31]то есть, примерно так: (только дополнения)
const
MoveImages: Boolean = true;...
IntersectClipRect(Canvas.Handle, Clipper.Left, Clipper.Top, Clipper.Right,
Clipper.Bottom);
if MoveImages then
begin
P.X := StartOfImages.X - (SpinEdit1.Value * ClipperInc);
P.Y := StartOfImages.Y;
end
else
P := StartOfImages;procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
if not MoveImages then
FClipperPos.X := (StartOfImages.X - 5) + SpinEdit1.Value * ClipperInc
else
FClipperPos := Point(StartOfImages.X - 5, StartOfImages.Y - 5);
Invalidate;
end;
← →
Игорь Шевченко © (2009-05-14 17:31) [32]
> Я не понял в чем цель вызова InflateRect, зачем делать так,
> чтобы 1 пиксель торчал?
чтобы рамка гарантированно не отсекалась.
← →
Kolan © (2009-05-15 10:23) [33]Благодарю Игорь, очень хороший пример. :)
← →
Игорь Шевченко © (2009-05-15 10:54) [34]Kolan © (15.05.09 10:23) [33]
> Благодарю Игорь, очень хороший пример. :)
Я к чему - ты не так давно задавал вопросы, можно ли нечто сделать на Delphi. Можно. Труда это займет не так много, как кажется поначалу.
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2009.07.12;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.008 c