§ 20. Создание приложений

20.4. Создание приложения «Графический редактор»

Программа должна давать возможность открыть и сохранить файл, выбрать цвет линии и цвет фона, установить толщину линии. Рисование производится выбранным цветом линии при нажатой левой клавиши мыши. При нажатии правой клавиши мыши происходит перекраска цветом фона ограниченной области.

Сначала спроектируем форму, разместив на ней следующие компоненты (пример 20.13):

  • область для рисования — Image1;
  • палитру основных 16 цветов — ColorGrid1 (панель компонентов Samples);
  • компоненты, отображающие выбранный цвет для рисования и цвет фона — Panel1, Panel2;
  • компонент выбора цвета — ColorDialog1;
  • компонент для выбора толщины линии — SpinEdit1 (панель компонентов Samples);
  • главное меню — MainMenu1 и компоненты для работы с файлами — OpenPictureDialog1, SavePictureDialog1.

У свойства GridOrdening для компонента ColorGrid1 установить значение go8x2, которое позволит разместить компонент горизонтально.

На этапе конструирования установить значение свойства Color у компонентов Panel1 и Panel2, clBlack и clWhite соответственно.

У свойств Value и MinValue для компонента SpinEdit1 установить значение 1.

Структура меню показана в примере 20.14. Обработчики событий приведены в примере 20.15.

Для того, чтобы программа загружалась с видимой областью для рисования, нужно при создании формы выполнить какое-либо обращение к Image1, например, закрасить белым цветом пиксел с координатами (0; 0).

Для проверки нажатой клавиши мыши опишем обработчик события OnMouseDown для компонента Image1. Параметр Button у этого обработчика может принимать значения mbLeft или mbRight в зависимости от нажатой левой или правой клавиши мыши.

Для отслеживания траектории движения мыши по компоненту Image1 создаем обработчик события OnMouseMove. Параметр Shift у обработчика позволяет определить, какая из клавиш мыши была нажата, а параметры x, y  возвращают координаты точки, в которой произошло нажатие кнопки.

Для перемещения мыши нужно использовать методы Canvas: LineTo(x, y) — перемещение со следом и MoveTo(x, y) — перемещение без следа.

Обработчик события OnChange для компонента ColorGrid1 позволит определить выбранный цвет. Свойства ForegroundColor и BackgroundColor у этого компонента, отвечающие за основной и фоновый цвета, изменяются при нажатии левой и правой кнопок соответственно. Параллельно изменяется цвет панелей.

Толщина линии определяется значением свойства Value для компонента SpinEdit1. Обработчик события — OnChange.

Обработчики событий для компонентов OpenPictureDialog1, SavePictureDialog1, вызываются из соответствующих пунктов меню и аналогичны обработчикам, описанным для программы Блокнот. Для сохранения и загрузки файлов нужно описать глобальную строковую переменную FileName. Приложение может сохранять и загружать файлы формата bmp.

С помощью компонента ColorDialog1 можно выбрать цвет линии или заливки, отсутствующие на панели ColorGrid1. Пункты меню Цвет, позволяют выбрать цвет линии или заливки соответственно. При выборе цвета на панели ColorGrid1 доступны только 16 базовых цветов, при выборе цета из меню — стандартная RGB палитра.

Создание рисунка и загрузка файла в приложение приведены в примере 20.16.

Пример 20.13. Форма на этапе конструирования:

Пример 20.14. Структура меню:

Пример 20.15. Обработчики событий:

void __fastcall TForm1::FormCreate
               (TObject *Sender)

{

  OpenPictureDialog1->InitialDir = 

    ExtractFilePath(ParamStr(0));

  SavePictureDialog1->InitialDir = 

    OpenPictureDialog1->InitialDir;

  Image1->Canvas->Pixels[0][0] = clWhite;

}

 

void __fastcall TForm1::
Image1MouseDown(TObject *Sender, 
TMouseButton Button, TShiftState Shift, 
int X, int Y)

{

  //нажата левая клавиша мыши

  if (Button == mbLeft)

  Image1->Canvas->MoveTo(X,Y);

  //нажата правая клавиша мыши

  if (Button == mbRight)

  Image1->Canvas->FloodFill

    (X, Y, Image1->Canvas->

    Pixels[X][Y],fsSurface);

}

 

void __fastcall TForm1::

Image1MouseMove(TObject *Sender, 
TShiftState Shift, int X, int Y)

{

  //перемещение с нажатой левой

  //кнопкой мыши

  if (Shift.Contains(ssLeft))

  Image1->Canvas->LineTo(X,Y);

}

 

void __fastcall TForm1::

ColorGrid1Change(TObject *Sender)

{

  //выбор основного цвета

  //левой клавишей мыши

  Image1->Canvas->Pen->Color = 

    ColorGrid1->ForegroundColor;

  Panel1->Color = 

    ColorGrid1->ForegroundColor;

  //выбор фонового цвета

  //правой клавишей мыши

  Image1->Canvas->Brush->Color = 

    ColorGrid1->BackgroundColor;

  Panel2->Color = 

    ColorGrid1->BackgroundColor;

}

 

void __fastcall TForm1::

SpinEdit1Change(TObject *Sender)

{

  Image1->Canvas->Pen->Width = 

    SpinEdit1->Value;

}

 

void __fastcall TForm1::N2Click

(TObject *Sender)

{

  Image1->Picture = NULL;

  Image1->Canvas->Pixels[0][0] = clWhite;

  SpinEdit1->Value = 1;

  Panel1->Color = clWhite;

  Panel2->Color = clBlack;

}

 

void __fastcall TForm1::N3Click

(TObject *Sender)

{

  if (OpenPictureDialog1->Execute()) {

  FileName = OpenPictureDialog1->FileName;

  Image1->Picture->LoadFromFile(FileName);

  Form1->Caption = "MyPaint " + FileName;

  }

}

 

void __fastcall TForm1::N4Click

(TObject *Sender)

{

  if (SavePictureDialog1->Execute()) {

  FileName = SavePictureDialog1->FileName;

  Image1->Picture->SaveToFile(FileName);

  Form1->Caption = "MyPaint " + FileName;

  }

}

 

void __fastcall TForm1::N6Click

(TObject *Sender)

{

  Form1->Close();

}

 

void __fastcall TForm1::N8Click

(TObject *Sender)

{

  if (ColorDialog1->Execute()) {

    Panel1->Color = ColorDialog1->Color;

    Image1->Canvas->Pen->Color = 

      ColorDialog1->Color;

  }

}

 

void __fastcall TForm1::N9Click

(TObject *Sender)

{

  if (ColorDialog1->Execute()) {

    Panel2->Color = ColorDialog1->Color;

    Image1->Canvas->Brush->Color = 

      ColorDialog1->Color;

  }

}

Пример 20.16. Работающее приложение: