FreshLib GUI templates

The GUI library in FreshLib (later FreshGUI) is OOP based and is designed to be portable across supported platforms.

The library is still not suitable for production, because misses enough features, but the API seems to be pretty stable, so I will try to incrementally document it in this article.

1. The templates

The templates engine of FreshGUI allows description of the GUI widget hierarchies in design time, combined with flexible assigning of the GUI objects parameters.

The base of the template is the macro ObjTemplate defined following way:

macro ObjTemplate  flags, class, name, [idparam] {
....
}

The parameters of the macro are:

flags - contains some of the following flags, combined with OR: tfEnd, tfParent, tfChild;

tfParent indicates that the next ObjTemplate definition will be the first of the children for the given element.

tfEnd indicates that this element is the last child for its parent.

tfChild indicates that this element is a child of its parent. Default value, can be ommited.

class is the GUI element class. Must be descendant of TWindow in order to be handled properly by the templates engine.

name the name of the GUI control (window). Can be NONE or some label name, existing or not. If the value is NONE, no variable is created. If the label already exists, it is assumed that it points to dword variable and the created object instance will be written there. If the label does not exists, it will be created as a dword variable.

idparam - zero or more object parameters assignments. The syntax is "param_name = param_value". The specified values will be assigned to the object instance during the template creation.

The values can be following types:

Number - it is handled as a dword value and is assigned to the parameter directly.

String enclosed in quotes or generally every byte string, as defined in db directive. If contains more than one element, must be enclosed in angled brackets. For example <"first line", 13, 10, "second", 13, 10>. Such strings are defined inside the template and pointer to its beginning is assigned to the object parameter.

Address (label) enclosed in squre brackets: [label] - the value of the parameter is extracted from this address during the object creation. Notice, that in run-time, this variable must contains the proper value before creating the object instance from the template.

Here is one example of usage for the templates for creating the main window of the program (from "freshlib/test_code0/TestTVmain.asm", the project "freshlib/test_code0/TestTV.fpr"):

TemplateMainForm:
        ObjTemplate  tfParent or tfEnd, TForm, frmMain,         \
                     x = 100,                                   \
                     y = 50,                                    \
                     width = 418,                               \
                     height = 250,                              \
                     OnCreate = FormOnCreate,                   \
                     OnClose = MainFormOnClose,                 \
                     OnDestroy = FormOnDestroy,                 \
                     SplitGrid = SplitTest,                     \
                     Caption = 'The new GUI toolkit test form.'

          ObjTemplate tfChild, TEdit, editDir,                  \
                     Text = "/home",                            \
                     MarginLeft= 2,                             \
                     MarginRight= 2,                            \
                     OnCreate = EditOnCreate,                   \
                     SplitCell = SplitTest.cellEdit,            \
                     Visible = TRUE

          ObjTemplate  tfChild, TButton, btnArrowRight,         \
                     Icon = [iconArrowRight],                   \
                     IconPosition = iposCenter,                 \
                     SplitCell = SplitTest.cellButton,          \
                     OnClick = ReadFolderClick,                 \
                     Visible = TRUE

          ObjTemplate  tfChild or tfEnd, TTreeView, tvFolders,  \
                     SplitCell = SplitTest.cellTree,            \
                     Visible = TRUE

This example creates the following window:

!template_example.png

2. Split grids

In the above example, you can notice, that the coordinates and sizes of the children widgets are not set. This is because the Window frmMain have assigned a split grid - structure that handles the layout of the window and positions and resizes the children elements automatically.

The parent window have the SplitGrid assigned to the parameter SplitGrid and the children have SplitCell parameter assigned with the cell of the grid they have to reside.

Below is the definition of the split grid, from the same test example:

SplitStart SplitTest

  Split stVert or stJustGap , 4, 24, 16, 48
    Split stHoriz or stOriginBR or stJustGap, 4, 64, 48, 200
      Cell cellEdit
      Cell cellButton

    Cell cellTree

SplitEnd

The SplitGrid is defined by dividing the window client area horizontally of vertically until the needed layout is fully defined.

The SplitGrid has two types of elements: Split and Cell.

The Split element always has two children elements - left and right (or top and bottom). Every of the children elements can be Split or Cell element.

The Cell element has no children and only can contain and handle some GUI widget.

The used macros are defined following way:

macro SplitStart name {}
macro SplitEnd {}

macro Split type, width, pos, min, max {}
macro Cell name {}

The SplitStart defines the name for the whole splitgrid.

The SplitEnd ends the definition and check for consistency. If the structure is not consistents it fills the missing children with empty cells. In this case, a compile time warning message will be displayed.

The Cell defines a name for the widget cell. The name is defined as a local name of the split grid name. (See in the above example for examples).

The Split parameters are the following:

type - one or several (combined by OR) values of:

stHoriz - default, can be omitted. The cell is splitted horizontally on left and right parts.

stVert - the cell is split vertically on top and bottom parts.

stRelative - the sizes of the parts are specified in relative units instead of absolute. One unit is 1/32768 of the whole. The relatively sized cells will change its size proportionally when the parent cell resizes. In contrary, on sizing the parent, only the one of the absolutely sized cells will change.

stOriginBR - The size is specified for the right/bottom cell of the split. When not specified, the left/top parts are sized.

stJustGap - The cell is split but not user resizeable. If not specified, a draggable splitter control is placed in the gap between the parts of the cell. If specified, the control is not placed and the user can't drag it in order to resize the parts.

width - The width of the gap between the cell parts. Can be empty or draggable splitter control (`stJustGap`).

pos - the initial size of the left/top part of the rectangle. (If stOriginBR is specified, this is the size of the right/bottom part). The units are pixels, or relative units (`stRelative`);

min, max - specify the minimal and maximal size of the left/top part of the cell. (or right/bottom if stOriginBR is specified). The units are the same as for pos parameter.

3. Creating windows from templates.

Once the template is created, the instance of the window is created by calling the procedure defined following way:

proc CreateFromTemplate, .ptrTemplate, .parent

Here is how it looks on the above example template:

        stdcall CreateFromTemplate, TemplateMainForm, 0

Notice that the pointer to the main window is returned in EBX register. Pointers to the all created windows are stored in the respective name variables in the template.


At the end, here is how the example program looks in action (the example source is in the repository):

!template_example2.png

Last modified on: 11.09.2016 10:02:22

Comment now:

Preview

e-mail
Will not be published. ( Why is required? )
Name

Subject
Title

Comments formating:

(for full reference, read MiniMagAsm manual)

Separate paragraphs by empty line:

This is
paragraph1

This is paragraph2

Text formatting:

*BOLD* = BOLD
/Italic/ = Italic
_Underlined_ = Underlined
`Monospaced` = Monospaced
_/*Combined*/_ = Combined

Code block:

;begin
  code here
;end

Links syntax - don't start it on the first column:

   [URL][Link text] - hyperlink.
   [!URL][Alt text] - block image.
   [?URL][Alt text] - inline image.

How to make blockquote:

;quote label_text
 quoted text
;end

The blockquotes can be nested and can contain formatted text.

Comments

Title: Filename: