clui/docs/widget.md

6.1 KiB

About Widgets

Creating a widget

Every widget should have parent at creation time otherwise the widget will be invisible and will not recieve any message. Parent and minimal width are the only common arguments of all functions that creates a new widget. Other arguments may vary but there are set of common ones. Generic create function may look like this (except Frame that has its own argument 'frameWidth': BorderThick or BorderThin) - note that it is not real function:

CreateWidget(parent, minimalWidth, minimalHeight, title, scale)

parent - is a container which created widget belongs;

minimalWidth and minimalHeight - are limits for the widget sizes when its parent is resized. Some widgets does not used minimalHeight because they cannot be higher than 1 symbol - those widgets are Radio, CheckBox, and EditField. If the widget should not have certain minimal size you can set it to AutoSize. In this case minimal size will be either calculated on the fly (e.g, Label minimal width is length of its title) or defaults are used (Frame gets width equals 5 and height equals 3 if they are not provided by caller). Minimal sizes can be changed later by calling a widget function widget.SetConstraints(newMinimalWidth, newMinimalHeight). Please note that if you want to change only one value, you can set the other one to constant KeepValue, e.g widget.SetConstraints(KeepValue, 10)` changes only minimalHeight to 10 and keeps old minimalWidth value;

title - a text displayed on the widget. Half of widgets does not have it. Titles can include special tags to be display in various colors. A more details about it a bit later;

scale - defines how fast the widget changes its size when its parent is resizing (e.g, if a container has two widgets and the first has scale 1 while the second has scale 2 then the latter widget grows twice faster when the container is growing). Setting scale to a special constant Fixed forbids resizing the control, so it always has the constant size.

Basic widget methods

All methods follow one rule: for every property there is a SetProperty method to change it and there is a Property method to read it. Below only setters are mentioned:

  1. Size and position: SetSize(width, height), SetPos(x, y)
  2. Minimal size: SetConstraints(minWidth, minHeight)
  3. Title/text/caption: SetTitle(string)
  4. Disable or enable widget - SetEnable(bool). Disabled controls usually has its own look and does not respond to mouse and keyboard events
  5. Activate control - SetActive(bool). A Window can has only one active widget at a time, so SetActive deactivates previously activated control before activating a new one

How scaling works

Every container has its starting size that calculated as maximum of two values: its minimal size and sum of minimal sizes of its children. When the container changes its size then a layout manager does children resizing:

  1. The difference between new size and starting size(Delta) is calculated
  2. It calculates the total scale size of all children(TotalScaleSize). Fixed children have scale coefficient equals 0
  3. Each child that has scale greater than 0(except the last one) gets increased by the value: child.Scale * Delta / TotalScaleSize. The number is rounded down Delta decreased by the value. The latter child gets increased by the value that remains in Delta. So, in real life one widget can grow more than the other one even their scales equal (example: two children have scale 1, parent size increased by 3, then the former gets increased by floor(1 * (3 / (1 + 1))) = 1, and the latter gets increased by (3 - 1) = 2

Title color tags

Every widget can display colored texts: Labels, Frames, even ListBox items can be colorized. The way of using colors in output strings is similar to te way HTML uses. Every color tag must start with <Letter:ColorValue>. Letter must be one of 'c', 't', 'f', or 'b' (if Letter is not one of the list or colon does not follow the Letter then the text displayed as is. So, you do not need to escape angle brackets to display them in text. Use tag b to change background color, and c, t or f to change text or foreground color (c means color). ColroValue is a one color value or a list of color and its modifier separated with space, + or |. Supported colors are black, white, green, yellow, blue, magenta, cyan, red, and default. The last value default means that the corresponding widget color should be used - background for b:default, and foreground for f:default. Supported modifiers are bold(or bright instead of it), underline(spelling underlined supported as well), and reverse. Examples of correct tags: <t:red bold>, <t:underline+blue>.

All tags inside the string works as triggers: when drawing function runs into the tag it changes the current color to tag's one until the end of line of another tag is met. After printing all the string the colors are back to default ones. In other words, colors inside a string are temporary and you do not need to reset colors to normal ones at the end.

Sometimes you need to just hilight only a part of with different color and keep all the rest with default colors. Just enclose the part of text between <c:Color> and <c:default>. For the default case there is a shortcut - empty tag <b:> or <c:>. Example: Label has text The <c:green>green<c:> text displays "green" with green text color while the rest of the string is displayed with Label text color that can be green as well.

The library has a set of public functions to use in custom widgets:

UnColorizeText - retuns a text with all color tags removed

AlignColorizedText - align the text with tags inside an area with certain width

SliceColorized - smart text slicing that keeps the tag from the beginning if the tag is not included into slice range. Example: SliceColorized("abc<c:green>def<c:red>hg", 4, -1) == "<c:green>f<c:red>hg"

StringToColor - get the string in tag format and returns a color value that can be used in functions like SetTextColor. Can be useful to read colors from configuration file. ColorToString - does the opposite it returns a color description that can be used in tags