Topic: Change form color and some controls in real time

Hello everybody. I use MVD 5.6 and I wanted to create a script that would allow the end user to change the color of the application's forms and some of its controls. It was good, but maybe the code could be simplified. I do not currently have a deeper knowledge of MVD to improve the project. Any help to improve it is always welcome.

Post's attachments

Attachment icon form e controle customizados.zip 339.53 kb, 50 downloads since 2024-01-20 

Roberto Alencar

Re: Change form color and some controls in real time

Hi Roberto,

Let's simplify the script a little.
Something like this

Post's attachments

Attachment icon fcontrcustom mm.zip 333.38 kb, 53 downloads since 2024-01-21 

Re: Change form color and some controls in real time

sparrow wrote:

Hi Roberto,

Let's simplify the script a little.
Something like this


Hello Sparrow! Congratulations, it turned out great! You used 1/3 the number of lines I used in my script to get the same result. I'm glad we have experts like you on the forum. Thank you very much.

Roberto Alencar

Re: Change form color and some controls in real time

Hi Roberto, Sparrow,
Am I correct in thinking that you need to populate your tables manually (with SQLiteStudio or something like that ) with default values otherwise the application crashes?
But the main puzzle for me is when you change (and save) the edit foreground colour - it displays correctly but then when you try to type anything in the edit field, it reverts to the default color.  And yet this doesn't happen with the memo field - that behaves as it should.
Do either of you have any suggestions how to fix that?
Attached is my attempt at changing colors although I used my own example so it is not directly comparable to yours.
One thing I did add is a 'reset' button so that all the colors revert to their default settings (perhaps useful when the form starts to look like a 1970s disco big_smile )
Regards,
Derek.

Post's attachments

Attachment icon change color scheme.zip 451.75 kb, 41 downloads since 2024-01-21 

Re: Change form color and some controls in real time

Hi Derek.

The first question from the program can be easily solved. For example, like this:

  for i := 0 to Screen.formCount - 1 do
  begin
    if (TAForm(Screen.Forms[i]).KeyPreview) and
       (SQLExecute('SELECT COUNT(id) FROM tbl_forms WHERE nome_form = '''+TAForm(Screen.Forms[i]).name+'''') = 0) then
          SQLExecute('INSERT INTO tbl_forms (nome_form, cor_form, cor_lbl_form, cor_textbox, cor_fore_textbox, cor_fore_memo, cor_memo, cor_panel) '+
          'VALUES('''+TAForm(Screen.Forms[i]).name+''', 15790320, 0, 16777215, 0, 16777215, 0, 15790320)');
  end;

But I haven’t checked the second one and it’s an interesting question to look into.

6 (edited by k245 2024-01-22 08:56:04)

Re: Change form color and some controls in real time

The topic is interesting, but you need to dig deeper. In one of the projects, I implemented color palettes: color data was stored in a database, the user could create/customize the palette and select it. And on the code side, I made several procedures that updated all the colors according to the selected scheme.

https://myvisualdatabase.com/forum/misc.php?action=pun_attachment&item=10223&download=0

I also repainted the images in the desired color, but this only works with images in the BMP format.


Below are the basic procedures.

procedure Colors_LoadTheme(AID: string);
// загрузка схемы
var
  tmpSQL: string;
  tmpDataSet: TDataSet;
  tmpIndex: Integer;
  tmpName: string;
begin
  try
    // извлекаем цвета, в приоритете - индекс, если данных по схеме ещё нет в базе, все цвета будут чёрными.
    tmpSQL := 'SELECT ci.id, coalesce(cu.color,0) as color, coalesce(cu.id_color_item1,0) as colorIndex, ci.name ' +
      ' FROM color_item ci ' + ' LEFT JOIN color_ui cu on ci.id = cu.id_color_item ' +
      'WHERE cu.id_color_theme = ' + AID;
    SQLQuery(tmpSQL, tmpDataSet);
    while not tmpDataSet.EOF do
    begin
      tmpName := tmpDataSet.FieldByName('name').asString;
      tmpIndex := Colors_GetColorIndex(tmpName);
      if tmpIndex = -1 then
        ErrMsg('Colors_LoadTheme', 'Не найден цвет с именем ' + tmpName)
      else
      begin
        UIColors[tmpIndex] := tmpDataSet.FieldByName('color').asInteger;
        UICIndex[tmpIndex] := tmpDataSet.FieldByName('colorIndex').asInteger - 1;
      end;
      tmpDataSet.Next;
    end;
  finally
    tmpDataSet.Free;
  end;
  // инициализировать цветные картинки
  Colors_Image_Init;
end;

procedure Form_UpdateColor(AForm: TAForm);
// обновить цвета на форме
var
  i: integer;
  tmpPanel: TdbPanel;
  tmpFormColor: TColor;
begin
  // обновление цветов у элементов формы
  tmpFormColor := Colors_Get(FORM_COLOR); // цвет формы
  AForm.Color := Colors_Get(FORM_FRAME_COLOR); // цвет рамки
  FindC(AForm, 'panWork', tmpPanel);
  tmpPanel.Color := tmpFormColor;
  FindC(AForm, 'panBottom', tmpPanel, False);
  if tmpPanel <> nil then
    tmpPanel.Color := tmpFormColor;
  FindC(AForm, 'panTop', tmpPanel, False);
  if tmpPanel <> nil then
    tmpPanel.Color := tmpFormColor;
  FindC(AForm, 'panTopFilter', tmpPanel, False);
  if tmpPanel <> nil then
    tmpPanel.Color := tmpFormColor;
  FindC(AForm, 'panRight', tmpPanel, False);
  if tmpPanel <> nil then
    tmpPanel.Color := tmpFormColor;
  // обновить цвета у компонент
  for i := 0 to AForm.ComponentCount - 1 do
  begin
    VC_UpdateColor(AForm.Components[i]); // обновление цветов у компонент
  end;

end;


procedure VC_UpdateColor(AComponent: TComponent;);
// обновление цвета
begin
  try
    case GetVClassName(AComponent.Name) of
      T_FORM_CAPTION:
        FormCaption_UpdateColor(TdbPanel(AComponent));
      T_USER_DATA_PANEL:
        UserDataPanel_UpdateColor(TdbPanel(AComponent));
      T_ROUNDED_LABEL:
        RoundedLabel_UpdateColor(TdbLabel(AComponent));
      T_ROUNDED_PANEL:
        RoundedPanel_UpdateColor(TdbPanel(AComponent));
      T_ROUNDED_BUTTON:
        RoundedButton_UpdateColor(TdbButton(AComponent));
      T_ROUNDED_CHECKBOX:
        RoundedCheckbox_UpdateColor(TdbCheckbox(AComponent));
      T_ROUNDED_RADIOBOX:
        RoundedRadiobox_UpdateColor(TdbCheckbox(AComponent));
      T_ROUNDED_GRID:
        RoundedGrid_UpdateColor(TdbStringGridEx(AComponent));
      T_ROUNDED_COMBOBOX:
        RoundedCombobox_UpdateColor(TdbComboBox(AComponent));
      T_PARENT_COMBOBOX:
        ParentCombobox_UpdateColor(TdbEdit(AComponent));
      T_ROUNDED_MEMO:
        RoundedMemo_UpdateColor(TdbMemo(AComponent));
      T_ROUNDED_PAGECONTROL:
        RoundedPagecontrol_UpdateColor(TdbPageControl(AComponent));
      T_ROUNDED_DATEPICKER:
        RoundedDatePicker_UpdateColor(TdbDateTimePicker(AComponent));
      T_IMAGE_EDIT:
        ImageEdit_UpdateColor(TdbImage(AComponent));
      T_ROUNDED_EDIT:
        RoundedEdit_UpdateColor(TdbEdit(AComponent));
      T_FILESTORE:
        FileStore_UpdateColor(TdbEdit(AComponent));
      T_ROUNDED_TREE:
        RoundedTree_UpdateColor(TdbStringGridEx(AComponent));
      T_PHONE_EDIT:
        PhoneEdit_UpdateColor(TdbEdit(AComponent));
      T_EDIT_PAGECONTROL:
        EditPagecontrol_UpdateColor(TdbPageControl(AComponent));
      T_ROUNDED_SPLITTER:
        RoundedSplitter_UpdateColor(TdbPanel(AComponent));
      T_MAIN_MENU:
        MainMenu_UpdateColor(TdbPanel(AComponent));
      T_WIDGET:
        Widget_UpdateColor(TdbPanel(AComponent));
      T_SCROLL_BAR:
        ScrollBar_UpdateColor(TdbPanel(AComponent));
      T_ROUNDED_COLOR_EDIT:
        RoundedColorEdit_UpdateColor(TdbEdit(AComponent));
      T_CURRENCY_EDIT:
        CurrencyEdit_UpdateColor(TdbEdit(AComponent));
      T_NEWS_PANEL:
        NewsPanel_UpdateColor(TdbPanel(AComponent));
      T_DROP_DOWN_PANEL:
        DropDownPanel_UpdateColor(TdbPanel(AComponent));
      T_POP_UP_PANEL:
        PopUpPanel_UpdateColor(TdbPanel(AComponent));
      T_TOOLBAR:
        ToolBar_UpdateColor(TdbPanel(AComponent));
      T_ROUNDED_LIGHT_COMBO:
        RoundedLightCombo_UpdateColor(TdbEdit(AComponent));
      T_TASK_LEGEND_PANEL:
        TaskLegendPanel_UpdateColor(TdbPanel(AComponent));
    end;
  except
    ErrMsg('VC_UpdateColor(' + AComponent.Name + ')');
  end;
end;

procedure RoundedLabel_UpdateColor(ALabel: TdbLabel);
// обновить цвет
var
  S: TShape;
  tmpForm: TAForm;
  tmpName: string;
begin
  CForm(ALabel, tmpForm);
  tmpName := DeleteClassName(ALabel.Name);
  //
  ALabel.Color := Colors_Get(LABEL_COLOR);
  ALabel.Font.Color := Colors_Get(LABEL_TEXT_COLOR);
  if not ALabel.Transparent then
  begin
    S := TShape(tmpForm.FindComponent(T_SHAPE + tmpName + SX_RIGHT));
    S.Pen.Color := ALabel.Color;
    S.Brush.Color := ALabel.Color;
  end;
end;

Unfortunately, I don’t have a simple example, but I hope the principle itself will be clear.

Post's attachments

Attachment icon изображение_2024-01-22_114629331.png 7.21 kb, 10 downloads since 2024-01-22 

Визуальное программирование: блог и телеграм-канал.

Re: Change form color and some controls in real time

Thank you Derek and K245 for your contributions.

Roberto Alencar

Re: Change form color and some controls in real time

I have attached again the project that allows changing the colors of a form and some of its respective controls at run time. Here are some observations:

➤ I used the script developed by Sparrow. Derek's is very good too;
➤ I used Derek's suggestion to create a button to reset the color settings;
➤ I placed the procedure of the same name in the "OnChange" property of TextBox fields, which is below, to correct the error pointed out by Derek (which is an MVD bug), which does not maintain the text color (foreground) in the field TextBox type, when this is changed. It's the solution I managed to find....using part of the code written by Sparrow.
➤ As soon as the forms are opened, they create a record in the tbl_forms table, which will store the colors defined by the end user;
➤ included the option to increase or decrease the font size of form labels and text in textbox and memo fields

procedure OnChange (Sender: TObject);
//*** to fix MVD bug that does not maintain the foreground color when typing
var
     i: integer;
     tmpFrm: TAForm;
begin
       for i := 0 to Screen.formCount - 1 do
       begin
         if TAForm(Screen.Forms[i]).name = frm_custom.Edit_form_custom.text then tmpFrm := TAForm(Screen.Forms[i]);
       end;
       CompLoad(tmpFrm);
end;
Post's attachments

Attachment icon fcontrcustom.rar 304.48 kb, 36 downloads since 2024-01-24 

Roberto Alencar

9 (edited by sparrow 2024-01-24 22:36:47)

Re: Change form color and some controls in real time

Hi Derek, Roberto


Some fixes and improvements have been made.
Completely (hopefully) fixed typing in color in Edit.


P.S.  I am posting the corrected version below in the posts.

Re: Change form color and some controls in real time

sparrow wrote:

Hi Derek, Roberto


Some fixes and improvements have been made.
Completely (hopefully) fixed typing in color in Edit.


Hello Sparrow, Show de Bola! Here in Brazil we use the expression "Show de Bola" - which has its origins in our football - to say that it was really good! Congratulations and thank you!

Roberto Alencar

Re: Change form color and some controls in real time

Roberto,


When checking, it turned out that there were some colors that caused the color switching effect when typing.
I'm posting the corrected version.
Thank you.

Post's attachments

Attachment icon fcontrcustom m1.zip 339.77 kb, 43 downloads since 2024-01-24