Layout
This page has been automatically translated using the Google Translate API services. We are working on improving texts. Thank you for your understanding and patience.
Functions
A Layout is a virtual and transparent grid always linked with a Panel which serves to locate the different interface elements (Figure 1). Its inner cells have the ability to be automatically sized according to their content, which results in great portability because it is not necessary to indicate specific coordinates or sizes for the controls. To illustrate the concept, we will slightly simplify the code of Hello Edit and UpDown! (Listing 1), whose result we can see in (Figure 2).
- Use layout_create to create a new layout.
- Use layout_label and similars to place controls in the different cells.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
Layout *layout = layout_create(2, 5); Label *label1 = label_create(); Label *label2 = label_create(); Label *label3 = label_create(); Label *label4 = label_create(); Label *label5 = label_create(); Edit *edit1 = edit_create(); Edit *edit2 = edit_create(); Edit *edit3 = edit_create(); Edit *edit4 = edit_create(); Edit *edit5 = edit_create(); label_text(label1, "User Name:"); label_text(label2, "Password:"); label_text(label3, "Address:"); label_text(label4, "City:"); label_text(label5, "Phone:"); edit_text(edit1, "Amanda Callister"); edit_text(edit2, "aQwe56nhjJk"); edit_text(edit3, "35, Tuam Road"); edit_text(edit4, "Galway - Ireland"); edit_text(edit5, "+35 654 333 000"); edit_passmode(edit2, TRUE); layout_label(layout, label1, 0, 0); layout_label(layout, label2, 0, 1); layout_label(layout, label3, 0, 2); layout_label(layout, label4, 0, 3); layout_label(layout, label5, 0, 4); layout_edit(layout, edit1, 1, 0); layout_edit(layout, edit2, 1, 1); layout_edit(layout, edit3, 1, 2); layout_edit(layout, edit4, 1, 3); layout_edit(layout, edit5, 1, 4); |
1. Natural sizing
The result of (Figure 2), although it is not very aesthetic, it is what we call natural sizing which is the default layout applied depending on the content of the cells. In (Table 1) we have the default measurements of each control. The column width is fixed to that of the widest element and the height of the rows is calculated in the same way. The final size of the layout will be the sum of the measures of both columns and rows.
Control | Width | Height |
Label | Adjusted to the text. | Adjusted to the text considering '\n' . |
Button (push) | Adjusted to text + margin. | According to the theme of the OS. |
Button (check/radio) | Adjusted to text + icon. | Adjusted to the icon. |
Button (flat) | Adjusted to the icon + margin. | Adjusted to the icon + margin. |
PopUp | Adjusted to the longest text. | According to the theme of the OS. |
Edit | 100 Units (px). | Adjusted to text + margin. |
Combo | 100 Units (px). | According to the theme of the OS. |
ListBox | 128 px or listbox_size. | 128 px or listbox_size. |
UpDown | According to the theme of the OS. | According to the theme of the OS. |
Slider (horizontal) | 100 Units (px). | According to the theme of the OS. |
Slider (vertical) | According to the theme of the OS. | 100 Units (px). |
Progress | 100 Units (px). | According to the theme of the OS. |
View | 128 px or view_size. | 128 px or view_size. |
TextView | 256 px or textview_size. | 144 px or textview_size. |
ImageView | 64 px or imageview_size. | 64 px or imageview_size. |
TableView | 256 px or tableview_size. | 128 px or tableview_size. |
SplitView | 128 px or splitview_size. | 128 px or splitview_size. |
Panel | Natural size. | Natural size. |
Panel (with scroll) | 256 px or panel_size. | 256 px or panel_size. |
The margins and constants applied to the controls are those necessary to comply with the human guidelines of each window manager. This means that a PushButton with the text "Hello"
will not have the same dimensions in WindowsXP as in macOS Mavericks or Ubuntu 16.
Empty cells will be 0-sized and will not affect the composition.
2. Margins and format
The natural sizing we have just seen adjusts the panel to the minimum size necessary to correctly house all the controls, but it is not always aesthetic. We can shape it by adding margins or forcing a given size for rows and columns (Listing 2) (Figure 3).
- Use layout_hsize to force the width of a column.
- Use layout_vsize to force the height of a row.
- Use layout_hmargin to establish an inter-column margin.
- Use layout_vmargin to establish an inter-row margin.
- Use layout_margin to set a margin at the edge of the layout.
1 2 3 4 5 6 7 |
layout_hsize(layout, 1, 235); layout_hmargin(layout, 0, 5); layout_vmargin(layout, 0, 5); layout_vmargin(layout, 1, 5); layout_vmargin(layout, 2, 5); layout_vmargin(layout, 3, 5); layout_margin(layout, 10); |
3. Alignment
It is usual for the width of a control to be less than the width of the column that contains it, either because a fixed width has been forced or because there are wider elements in the same column. In these cases, we can indicate the horizontal or vertical alignment of the control with respect to the cell (Figure 4). In (Table 2) you have the default alignments.
- Use layout_halign to change the horizontal alignment of a cell.
- Use layout_valign to change the vertical alignment of a cell.
Control | Horizontal | Vertical |
Label | ekLEFT | ekCENTER |
Button (push) | ekJUSTIFY | ekCENTER |
Button (others) | ekLEFT | ekCENTER |
PopUp | ekJUSTIFY | ekCENTER |
Edit | ekJUSTIFY | ekTOP |
Edit (multiline) | ekJUSTIFY | ekJUSTIFY |
Combo | ekJUSTIFY | ekCENTER |
ListBox | ekJUSTIFY | ekJUSTIFY |
UpDown | ekJUSTIFY | ekJUSTIFY |
Slider (horizontal) | ekJUSTIFY | ekCENTER |
Slider (vertical) | ekCENTER | ekJUSTIFY |
Progress | ekJUSTIFY | ekCENTER |
View | ekJUSTIFY | ekJUSTIFY |
TextView | ekJUSTIFY | ekJUSTIFY |
ImageView | ekJUSTIFY | ekJUSTIFY |
TableView | ekJUSTIFY | ekJUSTIFY |
SplitView | ekJUSTIFY | ekJUSTIFY |
Layout (sublayout) | ekJUSTIFY | ekJUSTIFY |
Panel | ekJUSTIFY | ekJUSTIFY |
4. Sub-layouts
Consider now the panel of (Figure 5). It is not difficult to realize that this arrangement does not fit in any way in a rectangular grid, so it is time to use sublayouts. In addition to individual controls, a cell also supports another layout, so we can divide the original panel into as many parts as necessary until the desired layout is achieved. The main layout will size each sublayout recursively and integrate it into the final composition. In Hello Sublayout! you have the code that generates this example.
- Use layout_layout to assign a complete layout to a cell in another layout.
In this case we have applied the philosophy of divide and conquer, to ensure that each part fits into an individual grid (Figure 6). Each sublayout has been coded in an independent function to give greater consistency to the code, applying margins and format individually within each of them (Listing 3).
1 2 3 4 5 6 7 8 9 10 11 |
static Layout *i_main_layout(void) { Layout *layout1 = layout_create(1, 2); Layout *layout2 = i_top_layout(); Layout *layout3 = i_bottom_layout(); layout_layout(layout1, layout2, 0, 0); layout_layout(layout1, layout3, 0, 1); layout_margin(layout1, 5); layout_vmargin(layout1, 0, 5); return layout1; } |
5. Cell expansion
On certain occasions, the size of a layout is forced by external conditions. This happens when we have a sublayout in a cell with ekJUSTIFY alignment (internal expansion) or when the user changes the size of a resizable window (external expansion). This will produce an "pixel excess" between the natural sizing and the actual cell size (Figure 7). This situation is resolved by distributing the pixel surplus equally among all the sublayout columns, which in turn, will be recursively expanding until they reach an empty cell or an individual control. We can change this equitable distribution through these functions:
- Use layout_hexpand to expand a single cell and leave the rest with its default size.
- Use layout_hexpand2 to expand two cells indicating the growth rate of each.
- Use layout_hexpand3 to expand three cells.
The vertical expansion works exactly the same, distributing the excess space between the rows of the layout.
6. Tabstops
Normally we will use the [TAB]
key and the [SHIFT]+[TAB]
combination to navigate through the different controls of a window or form. Terms like taborder or tabstop refer to both the navigation order and the membership (or not) of an element in said list. While it is possible to arrange the elements of a tab-list randomly, layouts provide a coherent natural order based on the placement of controls. By default, each layout creates a tab-list going through all its cells by rows (Figure 8), but we can change it:
- Use layout_taborder to arrange the tab-list by rows or columns.
- Use layout_tabstop to add or remove controls from the tab-list.
Not every cell in a layout has to be a tabstop, since it doesn't make sense for static controls like Label to receive keyboard focus. In (Table 3) you have which controls are included by default in that list. With layout_tabstop you can add or remove controls from the tab-list. Most of the time we will use it than allowing certain custom views View to receive keyboard focus.
When the taborder enters a sublayout, it will follow the local order of the latter. When exiting the sublayout it will continue with the main order.
layout_create ()
Create a new layout specifying the number of columns and rows.
Layout* layout_create(const uint32_t ncols, const uint32_t nrows);
ncols | The number of columns. |
nrows | The number of rows. |
Return
The layout.
layout_cell ()
Get a layout cell.
Cell* layout_cell(Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The cell.
layout_control ()
Gets the control assigned to a cell in the layout.
GuiControl* layout_control(Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_label ()
Insert a Label control in a layout.
void layout_label(Layout *layout, Label *label, const uint32_t col, const uint32_t row);
layout | The layout. |
label | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_button ()
Insert a Button control in a layout.
void layout_button(Layout *layout, Button *button, const uint32_t col, const uint32_t row);
layout | The layout. |
button | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_popup ()
Insert a PopUp control in a layout.
void layout_popup(Layout *layout, PopUp *popup, const uint32_t col, const uint32_t row);
layout | The layout. |
popup | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_edit ()
Insert an Edit control in a layout.
void layout_edit(Layout *layout, Edit *edit, const uint32_t col, const uint32_t row);
layout | The layout. |
edit | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_combo ()
Insert a Combo control in a layout.
void layout_combo(Layout *layout, Combo *combo, const uint32_t col, const uint32_t row);
layout | The layout. |
combo | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_listbox ()
Insert a ListBox control in a layout.
void layout_listbox(Layout *layout, ListBox *list, const uint32_t col, const uint32_t row);
layout | The layout. |
list | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_updown ()
Insert an UpDown control in a layout.
void layout_updown(Layout *layout, UpDown *updown, const uint32_t col, const uint32_t row);
layout | The layout. |
updown | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_slider ()
Insert an Slider control in a layout.
void layout_slider(Layout *layout, Slider *slider, const uint32_t col, const uint32_t row);
layout | The layout. |
slider | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_progress ()
Insert a Progress control in a layout.
void layout_progress(Layout *layout, Progress *progress, const uint32_t col, const uint32_t row);
layout | The layout. |
progress | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_view ()
Insert View in a layout.
void layout_view(Layout *layout, View *view, const uint32_t col, const uint32_t row);
layout | The layout. |
view | The view to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_textview ()
Insert a TextView control in a layout.
void layout_textview(Layout *layout, TextView *view, const uint32_t col, const uint32_t row);
layout | The layout. |
view | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_imageview ()
Insert an ImageView control in a layout.
void layout_imageview(Layout *layout, ImageView *view, const uint32_t col, const uint32_t row);
layout | The layout. |
view | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_tableview ()
Insert an TableView control in a layout.
void layout_tableview(Layout *layout, TableView *view, const uint32_t col, const uint32_t row);
layout | The layout. |
view | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_splitview ()
Insert an SplitView control in a layout.
void layout_splitview(Layout *layout, SplitView *view, const uint32_t col, const uint32_t row);
layout | The layout. |
view | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_panel ()
Insert a Panel control in a layout.
void layout_panel(Layout *layout, Panel *panel, const uint32_t col, const uint32_t row);
layout | The layout. |
panel | The control to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_layout ()
Insert a layout into a cell in another layout.
void layout_layout(Layout *layout, Layout *sublayout, const uint32_t col, const uint32_t row);
layout | The main layout. |
sublayout | The layout to insert. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
layout_get_label ()
Gets the Label of a cell.
Label* layout_get_label(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_get_button ()
Gets the Button of a cell.
Button* layout_get_button(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_get_popup ()
Gets the PopUp of a cell.
PopUp* layout_get_popup(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_get_edit ()
Gets the Edit of a cell.
Edit* layout_get_edit(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_get_combo ()
Gets the Combo of a cell.
Combo* layout_get_combo(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_get_listbox ()
Gets the ListBox of a cell.
ListBox* layout_get_listbox(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_get_updown ()
Gets the UpDown of a cell.
UpDown* layout_get_updown(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_get_slider ()
Gets the Slider of a cell.
Slider* layout_get_slider(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_get_progress ()
Gets the Progress of a cell.
Progress* layout_get_progress(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_get_view ()
Gets the View of a cell.
View* layout_get_view(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The view.
layout_get_textview ()
Gets the TextView of a cell.
TextView* layout_get_textview(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_get_imageview ()
Gets the ImageView of a cell.
ImageView* layout_get_imageview(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_get_tableview ()
Gets the TableView of a cell.
TableView* layout_get_tableview(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_get_splitview ()
Gets the SplitView of a cell.
SplitView* layout_get_splitview(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The control.
layout_get_panel ()
Gets the Panel of a cell.
Panel* layout_get_panel(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The panel.
layout_get_layout ()
Gets the Layout of a cell.
Layout* layout_get_layout(const Layout *layout, const uint32_t col, const uint32_t row);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
Return
The sublayout.
layout_taborder ()
Set how the keyboard focus will move when you press [TAB]
.
void layout_taborder(Layout *layout, const gui_orient_t order);
layout | The layout. |
order | Loop through rows or columns. |
Remarks
See Tabstops.
layout_tabstop ()
Sets whether or not a cell in the layout will receive keyboard focus when navigating with [TAB]-[SHIFT][TAB]
.
void layout_tabstop(Layout *layout, const uint32_t col, const uint32_t row, const bool_t tabstop);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
tabstop | Enable or disable cell tabstop. |
Remarks
See Tabstops.
layout_hsize ()
Set a fixed width for a layout column.
void layout_hsize(Layout *layout, const uint32_t col, const real32_t width);
layout | The layout. |
col | Column index. |
width | Width. |
layout_vsize ()
Force a fixed height for the layout row.
void layout_vsize(Layout *layout, const uint32_t row, const real32_t height);
layout | The layout. |
row | Row index. |
height | Height. |
layout_hmargin ()
Establish an inter-column margin within the layout. It is the separation between two consecutive columns.
void layout_hmargin(Layout *layout, const uint32_t col, const real32_t margin);
layout | The layout. |
col | Index of the column. The index 0 refers to the separation between column 0 and column 1. |
margin | Margin. |
layout_vmargin ()
Set an inter-row margin within the layout. It is the separation between two consecutive rows.
void layout_vmargin(Layout *layout, const uint32_t row, const real32_t margin);
layout | The layout. |
row | Row index Index 0 refers to the separation between row 0 and row 1. |
margin | Margin. |
layout_hexpand ()
Set the column to expand horizontally.
void layout_hexpand(Layout *layout, const uint32_t col);
layout | The layout. |
col | Column index. |
Remarks
See Cell expansion.
layout_hexpand2 ()
Set the two columns that will expand horizontally.
void layout_hexpand2(Layout *layout, const uint32_t col1, const uint32_t col2, const real32_t exp);
layout | The layout. |
col1 | Index of column 1. |
col2 | Index of column 2. |
exp | Expansion of |
Remarks
The expansion of col2 = 1 - exp
. See Cell expansion.
layout_hexpand3 ()
Set the three columns that will expand horizontally.
void layout_hexpand3(Layout *layout, const uint32_t col1, const uint32_t col2, const uint32_t col3, const real32_t exp1, const real32_t exp2);
layout | The layout. |
col1 | Index of column 1. |
col2 | Index of column 2. |
col3 | Index of column 3. |
exp1 | Expansion of |
exp2 | Expansion of |
Remarks
exp1 + exp2 < = 1
. The expansion of col3 = 1 - exp1 - exp2
. See Cell expansion.
layout_vexpand ()
Set the row that will expand vertically.
void layout_vexpand(Layout *layout, const uint32_t row);
layout | The layout. |
row | Row index. |
Remarks
See Cell expansion.
layout_vexpand2 ()
Set the two rows that will expand vertically.
void layout_vexpand2(Layout *layout, const uint32_t row1, const uint32_t row2, const real32_t exp);
layout | The layout. |
row1 | Index of row 1. |
row2 | Index of row 2. |
exp | Expansion of |
Remarks
The expansion of row2 = 1 - exp
. See Cell expansion.
layout_vexpand3 ()
Set the three rows that will expand horizontally.
void layout_vexpand3(Layout *layout, const uint32_t row1, const uint32_t row2, const uint32_t row3, const real32_t exp1, const real32_t exp2);
layout | The layout. |
row1 | Index of row 1. |
row2 | Index of row 2. |
row3 | Index of row 3. |
exp1 | Expansion of |
exp2 | Expansion of |
Remarks
exp1 + exp2 < = 1
. The expansion of row3 = 1 - exp1 - exp2
. See Cell expansion.
layout_halign ()
Sets the horizontal alignment of a cell. It will take effect when the column is wider than the cell.
void layout_halign(Layout *layout, const uint32_t col, const uint32_t row, const align_t align);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
align | Horizontal alignment. |
layout_valign ()
Sets the vertical alignment of a cell. It will take effect when the row is taller than the cell.
void layout_valign(Layout *layout, const uint32_t col, const uint32_t row, const align_t align);
layout | The layout. |
col | Column, cell x coordinate. |
row | Row, cell y coordinate. |
align | Vertical alignment. |
layout_show_col ()
Show or hide a layout column.
void layout_show_col(Layout *layout, const uint32_t col, const bool_t visible);
layout | The layout. |
col | Column index. |
visible | Visible or hidden. |
layout_show_row ()
Show or hide a layout row.
void layout_show_row(Layout *layout, const uint32_t row, const bool_t visible);
layout | The layout. |
row | Row index. |
visible | Visible or hidden. |
layout_margin ()
Set a uniform margin for the layout border.
void layout_margin(Layout *layout, const real32_t mall);
layout | The layout. |
mall | Margin for all four sides (left, right, up and down). |
layout_margin2 ()
Set a horizontal and vertical margin for the layout edge.
void layout_margin2(Layout *layout, const real32_t mtb, const real32_t mlr);
layout | The layout. |
mtb | Upper and lower margin. |
mlr | Left and right margin. |
layout_margin4 ()
Set margins for the layout border.
void layout_margin4(Layout *layout, const real32_t mt, const real32_t mr, const real32_t mb, const real32_t ml);
layout | The layout. |
mt | Top edge margin. |
mr | Right edge margin. |
mb | Bottom edge margin. |
ml | Left edge margin. |
layout_bgcolor ()
Assign a background color to the layout.
void layout_bgcolor(Layout *layout, const color_t color);
layout | The layout. |
color | The color. With |
layout_skcolor ()
Assign a color to the edge of the layout.
void layout_skcolor(Layout *layout, const color_t color);
layout | The layout. |
color | The color. With |
layout_update ()
Update the window associated with the layout.
void layout_update(Layout *layout);
layout | The layout. |
Remarks
It is equivalent to calling window_update.
layout_dbind ()
Associate a type struct
with a layout.
void layout_dbind(Layout *layout, Listener *listener, type);
layout | The layout. |
listener | Will notify through this |
type | The |
Remarks
See GUI Data binding.
layout_dbind_obj ()
Associate an object with a layout to view and edit it.
void layout_dbind_obj(Layout *layout, type *obj, type);
layout | The layout. |
obj | The object to edit. |
type | Object type. |
Remarks
See GUI Data binding.
layout_dbind_update ()
Updates the interface of the object associated with the layout.
void layout_dbind_update(Layout *layout, type, mtype, mname);
layout | The layout. |
type | The object type. |
mtype | The type of the field to update. |
mname | The name of the field to update. |
Remarks
See GUI Data binding.