The style selection mechanism in My Visual Database applications is like buying a pig in a poke* : it is impossible to imagine what the program will look like with the selected style until a reboot. A few lines of code will help us solve this problem.

* in Russian: купить кота в мешке

Solution

Unfortunately, you won’t be able to programmatically render the style, but you can prepare images in advance that will show the key elements of the interface using the selected style and display them in sync with the list of styles.

Pictures can be placed in the same folder as the style files, with names that match the names of the styles themselves. You also need to add another picture, which will show the program without applying the style (by default).

Appearance of the program using RubyGraphite style

Scripts

const
  STYLE_VIEWRE_FORM = 'frmStyleViewer';

procedure Style_StyleViewer;
// display view form and style selection
var
  tmpForm: TForm;
  tmpList: TListBox;
  tmpImage: TImage;
  tmpPanel: TPanel;
  tmpButton: TdbButton;
  i: integer;
begin
  tmpForm := GetFormByName(STYLE_VIEWRE_FORM);
  if tmpForm = nil then
  begin
    tmpForm := TForm.Create(Application);
    with tmpForm do
    begin
      Name := STYLE_VIEWRE_FORM;
      Caption := R('STYLE_VIEWRE_FORM_CAPTION',STYLE_VIEWRE_FORM_CAPTION);
      Width := STYLE_VIEWRE_FORM_WIDTH;
      Height := STYLE_VIEWRE_FORM_HEIGHT;
      Position := poScreenCenter;
      Scaled := False;
      BorderStyle := bsSingle;
      BorderIcons := biSystemMenu;
      onShow := 'Style_StyleViewer_OnShow';
    end;
    // bottom of form
    tmpPanel := TPanel.Create(tmpForm);
    with tmpPanel do
    begin
      Parent := tmpForm;
      Color := clGray;
      Height := 44;
      BorderWidth := 0;
      Align := alBottom;
    end;
    tmpButton := TdbButton.Create(tmpForm);
    AssignEvents(tmpButton);
    with tmpButton do
    begin
      Parent := tmpPanel;
      Name := 'btnCancel';
      Font.Name := 'Segoe UI';
      Font.Size := 11;
      Caption := R('BUTTON_CAPTION_CANCEL',BUTTON_CAPTION_CANCEL);
      dbActionType := adbCloseForm;
      Height := 36;
      Width := 109;
      Left := tmpPanel.Width - Width - 4;
      Top := 4;
      Anchors := akRight + akTop;
      Cancel := True;
      Default := False;
    end;
    Button_SetImage(tmpButton);
    //
    tmpButton := TdbButton.Create(tmpForm);
    AssignEvents(tmpButton);
    with tmpButton do
    begin
      Parent := tmpPanel;
      Name := 'btnSave';
      Font.Name := 'Segoe UI';
      Font.Size := 11;
      Caption := R('BUTTON_CAPTION_SAVE',BUTTON_CAPTION_SAVE);
      Height := 36;
      Width := 119;
      dbActionType := adbCloseForm;
      OnClick := 'Style_StyleViewer_btnSave_OnClick';
      Left := tmpPanel.Width - Width - 4 - 109 - 4;
      Top := 4;
      Anchors := akRight + akTop;
      Cancel := False;
      Default := True;
    end;
    Button_SetImage(tmpButton);
    // main body of the form
    tmpPanel := TPanel.Create(tmpForm);
    with tmpPanel do
    begin
      Parent := tmpForm;
      BorderWidth := 0;
      Align := alClient;
    end;
    tmpList := TListBox.Create(tmpForm);
    with tmpList do
    begin
      Name := 'lstStyles';
      Font.Name := 'Segoe UI';
      Font.Size := 11;
      Parent := tmpPanel;
      Width := 200;
      Align := alLeft;

      for i := 0 to Length(arStyles) - 1 do
      begin
        Items.add( arStyles[i] );
      end;
      OnClick := 'Style_StyleViewer_ListOnClick';
    end;
    tmpImage := TImage.Create( tmpForm );
    with tmpImage do
    begin
      Parent := tmpPanel;
      Name := 'imgPreview';
      Align := alClient;
//      Stretch := True;
      Proportional := True;
      Center := True;
    end;
  end;
  FindC(tmpForm,'lstStyles',tmpList);
  for i:=0 to tmpList.Items.Count - 1 do
  begin
    if tmpList.Items.Strings[ i ] = currentStyleName then
    begin
      tmpList.ItemIndex := i;
      Style_StyleViewer_ListOnClick(tmpList); // upload picture
      break;
    end
  end;
  tmpForm.ShowModal;
end;
Code language: Delphi (delphi)

The Style_StyleViewer() procedure is used to display the view form and select a style. This form looks like an editing form: at the bottom there is a panel with the “Save” and “Cancel” buttons, on the left – a list of styles, and in the middle – an image of the program with the selected style.

Style selection form
const
  STYLE_PREVIEW_EXT = '.png';

procedure Style_StyleViewer_ListOnClick(Sender: TObject);
// click or select list item with keyboard arrows
var
  tmpList: TListBox;
  tmpFileName: string;
  tmpStyleName: string;
  tmpForm: TForm;
  tmpImage: TImage;
begin
  CForm(Sender,tmpForm);
  tmpList := TListBox(Sender);
  tmpStyleName := tmpList.Items.Strings[ tmpList.ItemIndex ];
  tmpFileName := ExtractFilePath(Application.ExeName) + STYLE_DIR + tmpStyleName + STYLE_PREVIEW_EXT;
  FindC(tmpForm,'imgPreview',tmpImage);
  if not FileExists(tmpFileName) then
    tmpFileName := ExtractFilePath(Application.ExeName) + STYLE_DIR + 'default' + STYLE_PREVIEW_EXT;
  //
  tmpImage.Picture.LoadFromFile(tmpFileName);
end;
Code language: Delphi (delphi)

When a style is selected from the list, the Style_StyleViewer_ListOnClick() procedure finds the corresponding image and loads it for viewing. If the image is not found (which is quite expected for the first item in the list of styles), then the name of the image is changed to default.png

procedure Style_StyleViewer_btnSave_OnClick(Sender: TObject; var Cancel:boolean);
// saving and applying a style
var
  tmpList: TListBox;
  tmpStyleName: string;
  tmpForm: TForm;
begin
  CForm(Sender,tmpForm);
  FindC(tmpForm,'lstStyles',tmpList);
  tmpStyleName := tmpList.Items.Strings[ tmpList.ItemIndex ];
  Style_SetStyle(tmpStyleName);
end;
Code language: Delphi (delphi)

When you click the “Save” button, the style is applied by calling the Style_SetStyle() procedure.

Other improvements

  • Style_StyleViewer_OnShow() – display style view form, list focus
  • Resource_CreateMenu() – added an option that by default creates a language selection item inside the “Options” menu item
  • Style_AddToMenu() – Create a menu item for interactive style selection.
  • Style_mniStyleViewer_OnClick() – menu item handler for calling the style selection form.
  • Button_SetImage() – a simplified procedure for assigning an image to a button
  • english.txt, russian.txt – new data added to resource localization files
  • Added application icon ClassExplorer.ico, it is built into ClassExplorer_.exe, as the ClassExplorer.exe file will be overwritten each time the project is changed.

Links

Leave a Reply

Your email address will not be published. Required fields are marked *