Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
end


unit 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.005 c
15-1242244143
T&F
2009-05-13 23:49
2009.07.12
Intel оштрафовали на миллиард евро o_O


2-1242982981
dort12
2009-05-22 13:03
2009.07.12
Проблема с прекреплением attachment


2-1242877845
NaRuTo
2009-05-21 07:50
2009.07.12
Как узнать продолжительность звукового файла?


2-1242845683
MQIndrik
2009-05-20 22:54
2009.07.12
Вывод результатов


15-1242218440
Медвежонок Пятачок
2009-05-13 16:40
2009.07.12
забороть HTTP протокол





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский