В программах иногда приходится хранить значение цвета. В Delphi для записи цвета используется шестнадцатеричное представление вида

$AABBGGRRCode language: PHP (php)
  • AA – прозрачность
  • BB – синяя составляющая цвета
  • GG – зелёная составляющая цвета
  • RR – красная составляющая цвета

Так как в My Visual Database нет компонента для отображения и редактирования цвета, сделаем его своими руками на базе компонента TdbEdit.

Дизайн

К стандартному полю ввода (1) мы добавим панельку (TdbPanel) для отображения цвета (2), которая будет располагаться над нашим базовым компонентом, визуально – справа внутри поля ввода. Также нам понадобится кнопка (TdbButton) (2), нажатие которой вызовет стандартный диалог Windows для выбора цвета.

Скрипты

Нам потребуется несколько скриптов, но явным образом вызываться будет только один, который превратит обычное поле ввода в новый компонент.

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

ColorEdit_Create()

const
  CED_BUTTON_NAME = 'Palette'; // название для кнопки

procedure ColorEdit_Create(AEdit: TdbEdit);
// редактирование цвета
// цвет хранится как текст: $00BBGGRR
var
  tmpForm: TAForm; // форма
  tmpName: string; // имя
  tmpButton: TdbButton; // кнопка выбора цвета
  tmpPanel: TdbPanel; // панель для отображения образца цвета
begin
  try
    CForm(AEdit, tmpForm);
    tmpName := T_BUTTON + CED_BUTTON_NAME + '_' + AEdit.Name;
    FindC(tmpForm, tmpName ,tmpButton,False);
    // вызывается процедура однократно, но если вызвали повторно
    // то ошибки или задвоения не будет
    if tmpButton = nil then
    begin
      AEdit.OnChange := 'ColorEdit_Edit_OnChange';
      AEdit.OnExit := 'ColorEdit_Edit_OnExit';
      AEdit.TextHint := '$AABBGGRR';
      tmpButton := TdbButton.Create( tmpForm );
      with tmpButton do // создаем кнопку
      begin
        name := tmpName;
        parent := AEdit.Parent;
        Caption := '';
        imageAlignment := iaCenter;
        Top := AEdit.Top - 1;
        Height := AEdit.Height + 2;
        Width := Height + 2 ;
        Left := AEdit.Left + AEdit.Width - Width;
        onClick := 'ColorEdit_btnSelectColor_OnClick';
        AEdit.Width := AEdit.Width - Width;
      end;
      Images_SetButton(tmpButton);
      tmpPanel := TdbPanel.Create( tmpForm );
      with tmpPanel do // панель для отображения образца цвета
      begin
        name := T_PANEL + CED_BUTTON_NAME + '_' + AEdit.Name;
        parent := AEdit.Parent;
        Caption := '';
        BevelWidth := 0;
        Color := AEdit.Color;
        Top := AEdit.Top + 1;
        Height := AEdit.Height - 2;
        Width := Height - 2 ;
        Left := AEdit.Left + AEdit.Width - Width - 1;
      end;
    end;
  except
    RaiseException('ColorEdit_Create() ' + ExceptionMessage);
  end;
end;
Code language: PHP (php)
  • CForm – определяет форму, на которой находится компонент
  • FindC – находит компонент по имени
  • Images_SetButton – помещает изображение на кнопку

Чтобы на кнопке появилась картинка, необходимо поместить в папку \images\buttons две картинки

  • palette.png – обычная картинка
  • palette_s.png – картинка, которая будет появляться при наведении на кнопку курсора

Логику работы обеспечивают обработчики событий, которые вызываются при нажатии кнопки, изменении текста или когда фокус ввода уходит из поля ввода данных.

procedure ColorEdit_Edit_OnChange(Sender: TObject);
// проверка и отображение выбранного значения
var
  tmpForm: TAForm;
  tmpName: string;
  tmpEdit: TdbEdit;
  tmpPanel: TdbPanel; // цветной маркер
begin
  try
    tmpEdit := TdbEdit(Sender);
    tmpForm := TAForm(TComponent(Sender).Owner);
    tmpName := T_PANEL + CED_BUTTON_NAME + '_' + tmpEdit.Name;
    FindC(tmpForm, tmpName, tmpPanel);
    tmpPanel.Color := StrToColor(tmpEdit.Text);
  except
    RaiseException('ColorEdit_Edit_OnChange ' + ExceptionMessage);
  end;
end;

procedure ColorEdit_Edit_OnExit(Sender: TObject);
// проверка и отображение выбранного значения
var
  tmpForm: TAForm;
  tmpName: string;
  tmpEdit: TdbEdit;
  tmpPanel: TdbPanel; // цветной маркер
begin
  try
    tmpEdit := TdbEdit(Sender);
    tmpForm := TAForm(TComponent(Sender).Owner);
    tmpName := T_PANEL + CED_BUTTON_NAME + '_' + tmpEdit.Name;
    FindC(tmpForm, tmpName, tmpPanel);
    tmpPanel.Color := StrToColor(tmpEdit.Text);
    tmpEdit.Text := ColorToStr(tmpPanel.Color);
  except
    RaiseException('ColorEdit_Edit_OnChange ' + ExceptionMessage);
  end;
end;Code language: JavaScript (javascript)

Эти два обработчика отличаются одной строчкой и служат для того, чтобы индикаторная панель окрасилась в цвет, который ввел или выбрал пользователь. Если в процессе ручного ввода пользователь допустил ошибку (ввел неверный символ или недопустимую последовательность), то после потери фокуса в поле редактирования автоматически выставляется значение $00000000 (черный цвет).

procedure ColorEdit_btnSelectColor_OnClick( Sender: TObject; var Cancel:boolean );
// открыть диалог для выбора цвета
var
  tmpName: string;
  tmpForm: TAForm;
  tmpEdit: TdbEdit;
  d: TColorDialog;
begin
  try
    CForm(Sender, tmpForm);
    tmpName := DeletePrefix(TComponent(Sender).Name);
    FindC(tmpForm, tmpName, tmpEdit);
    d := TColorDialog.Create(tmpForm);
    try
      d.Color := StrToColor( tmpEdit.Text );
      if d.Execute then
      begin
        tmpEdit.Text := ColorToStr(d.Color);
      end;
    finally
      d.free;
    end;
  except
    RaiseException('ColorEdit_btnSelectColor_OnClick() ' + ExceptionMessage);
  end;
end;Code language: JavaScript (javascript)

Обработчик нажатия кнопки вызывает диалог выбора цвета и записывает выбранное значение в виде текста в поле ввода.

Для преобразований цвета в текст и обратно применяются функции StrToColor() и ColorToStr(). Если вы захотите использовать другой формат для текстового представления цвета (например тот, что принят у веб-дизайнеров), то вам нужно будет модифицировать только эти две функции.

function StrToColor( AText: string): TColor;
// конвертация кода в цвет
var
  R: Byte;
  G: Byte;
  B: Byte;
begin
  try
    B := StrToInt( '$'+copy( AText, 4,2 ) );
    G := StrToInt( '$'+copy( AText, 6,2 ) );
    R := StrToInt( '$'+copy( AText, 8,2 ) );
    Result := RGB(R,G,B);
  except
    Result := 0;
  end;
end;

function ColorToStr( AColor:TColor ): string;
// преобразование цвета в строку
begin
  Result := '$00' + IntToHex(AColor, 6);
end;
Code language: PHP (php)

Поскольку данные о цвете могут нам понадобиться в табличном представлении, то не лишней будет функция Grid_ShowColor(), которая визуализирует цвет. Она имеет всего два параметра: таблицу (компонент TdbStringGrid) и колонку, в которой находятся значения цветов.

procedure Grid_ShowColor(Sender: TObject; ACol: integer);
// отобразить цвет в колонке
var
  i: integer;
  tmpGrid: TdbStringGridEx;
begin
  tmpGrid := TdbStringGridEx(Sender);
  for i:=0 to tmpGrid.RowCount - 1 do
  begin
    tmpGrid.cell[ACol,i].Color := StrToColor( tmpGrid.cells[ACol,i] );
    tmpGrid.cells[ACol,i] := '';
  end;
end;Code language: JavaScript (javascript)

Использование

Перед отображением формы необходимо инициализировать компонент редактирования цвета. Также необходимо добавить обработчик события OnChange, в котором разместить вызов процедуры Grid_ShowColor()

ColorEdit_Create(efmSoundLetter.edtColor);
DTF_GetGrid('dtfSoundLetter').dbOnChange := 'dtfSoundLetter_OnChange';

...

procedure dtfSoundLetter_OnChange(Sender: TObject);
begin
  Grid_ShowColor( Sender, 2);
end;
Code language: JavaScript (javascript)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *