We continue to work on the Data Keeper pilot project, which in the future should replace My Visual Database (MVDB). We add a new type of stored data – logical. And for visualization, a new type of user interface component, since the TdbCheckBox available in MVDB in Windows 10 does not look very presentable.

The switch consists of a TdbPanel (1), which contains three TdbImages (2), each of which is responsible for one of the three switch states:

  • On – enabled; displayed if property value = ‘Yes’
  • Off – turned off; displayed if property value = ‘No’
  • Null – not defined; displayed if property value = NULL

When you use a radio button, the text box is reduced in size and the radio button panel appears on top of it. Below is a fragment of the efmObject_OnShow() procedure in which the switch is created/activated:

    // switch
    if tmpControlID = 7 then
    begin
      tmpEdit.Width := 32;
      FindC(tmpForm,'panData_'+intToStr(tmpCount),tmpPanel,False);
      if tmpPanel = nil then
        tmpPanel := TdbPanel.Create(tmpForm);
      with tmpPanel do
      begin
        parent := tmpParent;
        name := 'panData_'+intToStr(tmpCount);
        caption := '';
        top := tmpEdit.Top;
        left := tmpEdit.Left;
        width := tmpEdit.width;
        height := tmpEdit.height;
        bevelWidth := 0;
        color := tmpParent.color;
        visible := True;
      end;
      //
      FindC(tmpForm,'imgDataOn_'+intToStr(tmpCount),tmpImageOn,False);
      if tmpImageOn = nil then
        tmpImageOn := TdbImage.Create(tmpForm);
      with tmpImageOn do
      begin
        parent := tmpPanel;
        name := 'imgDataOn_'+intToStr(tmpCount);
        align := alClient;
        center := True;
        picture.LoadFromFile( ExtractFilePath(Application.ExeName) + 'images\toggle\toggle_on.png' );
        onClick := 'Toggle_Off';
      end;
      //
      FindC(tmpForm,'imgDataOff_'+intToStr(tmpCount),tmpImageOff,False);
      if tmpImageOff = nil then
        tmpImageOff := TdbImage.Create(tmpForm);
      with tmpImageOff do
      begin
        parent := tmpPanel;
        name := 'imgDataOff_'+intToStr(tmpCount);
        align := alClient;
        center := True;
        picture.LoadFromFile( ExtractFilePath(Application.ExeName) + 'images\toggle\toggle_off.png' );
        onClick := 'Toggle_On';
      end;
      //
      FindC(tmpForm,'imgDataNull_'+intToStr(tmpCount),tmpImageNull,False);
      if tmpImageNull = nil then
        tmpImageNull := TdbImage.Create(tmpForm);
      with tmpImageNull do
      begin
        parent := tmpPanel;
        name := 'imgDataNull_'+intToStr(tmpCount);
        align := alClient;
        center := True;
        picture.LoadFromFile( ExtractFilePath(Application.ExeName) + 'images\toggle\toggle_indeterminate.png' );
        onClick := 'Toggle_On';
      end;
      case VarToStr( SQLExecute('SELECT value_s FROM oproperty WHERE id_object = '+IntToStr( efmObject.btnSave.dbGeneralTableId  )+' AND id_cproperty = '+tmpDataSet.FieldByName('id').asString +' AND orderNum is NULL' ) ) of
      'Да':
      begin
        tmpImageNull.Visible := False;
        tmpImageOff.Visible := False;
        tmpImageOn.Visible := True;
      end;
      'Нет':
      begin
        tmpImageNull.Visible := False;
        tmpImageOff.Visible := True;
        tmpImageOn.Visible := False;
      end;
      else
      begin
        tmpImageNull.Visible := True;
        tmpImageOff.Visible := False;
        tmpImageOn.Visible := False;
      end;
      end;
    end;Code language: PHP (php)

Image click handlers not only change the visibility of pictures, but also write the necessary data in the edit field:

procedure Toggle_On(Sender: TObject);
var
  tmpForm: TForm;
  tmpImageOn: TdbImage;
  tmpImageOff: TdbImage;
  tmpImageNull: TdbImage;
  tmpEdit: TdbEdit;
begin
  CForm(Sender,tmpForm);
  FindC(tmpForm,'imgDataOn_'+GetSuffix(TdbImage(Sender).Name),tmpImageOn);
  FindC(tmpForm,'imgDataOff_'+GetSuffix(TdbImage(Sender).Name),tmpImageOff);
  FindC(tmpForm,'imgDataNull_'+GetSuffix(TdbImage(Sender).Name),tmpImageNull);
  FindC(tmpForm,'edtData_'+GetSuffix(TdbImage(Sender).Name),tmpEdit);
  tmpImageOff.Visible := False;
  tmpImageNull.Visible := False;
  tmpImageOn.Visible := True;
  tmpEdit.Text := 'Да';
end;

procedure Toggle_Off(Sender: TObject);
var
  tmpForm: TForm;
  tmpImageOn: TdbImage;
  tmpImageOff: TdbImage;
  tmpEdit: TdbEdit;
  tmpImageNull: TdbImage;
begin
  CForm(Sender,tmpForm);
  FindC(tmpForm,'imgDataOff_'+GetSuffix(TdbImage(Sender).Name),tmpImageOff);
  FindC(tmpForm,'imgDataOn_'+GetSuffix(TdbImage(Sender).Name),tmpImageOn);
  FindC(tmpForm,'imgDataNull_'+GetSuffix(TdbImage(Sender).Name),tmpImageNull);
  FindC(tmpForm,'edtData_'+GetSuffix(TdbImage(Sender).Name),tmpEdit);
  tmpImageOff.Visible := True;
  tmpImageOn.Visible := False;
  tmpImageNull.Visible := False;
  tmpEdit.Text := 'Нет';
end;Code language: PHP (php)

There are two handlers, since the switch state diagram is not circular:

Not defined – enabled – disabled

Settings

Registering a new element in the UI components directory

Add a new class of stored values

Now it can be used when describing the properties of objects

Results

The table view displays the usual “Yes” or “No” values (2), and the editing form has a modern switch (1) in the style of Windows 10.

Unfortunately, MVDB does not have the ability to code change the color of PNG images, so this switch will not look good with all styles. This can be solved in several ways:

  • For each style, store your own switch images
  • use the BMP image format and change it using a script
  • draw a switch on the panel canvas
  • use TShape components to display the switch

The last option seems to me the most promising, but within the Data Keeper project there is no need to improve the appearance of the program, since the main goal is to develop the operating principle and basic algorithms for generating forms based on the data structure.

And in this matter, progress is obvious: instead of designing tables for relational databases, Data Keeper offers, it seems to me, a more understandable system for describing object classes. However, so far I have not received a single comment and, perhaps, users are expecting even simpler versions of constructors. For example, integration with voice assistants or fashionable intelligent systems like ChatGPT, which for some reason are called Artificial Intelligence.

Make everything good

In order to do everything well, you will need to add service (not deleted or changeable) classes to the class tree that are responsible for the appearance of the application. You can start with forms and menus. And it is better to display the tree itself in parts, separating user data from system data.

In addition, we need to think again whether the data (objects) themselves need to be stored in a hierarchical structure, or whether the tree should be used only as an auxiliary visualization tool when designing an application.

Leave a Reply

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