Panel
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
Panel* | panel_create (void) |
Panel* | panel_scroll (...) |
Panel* | panel_custom (...) |
void | panel_data (...) |
type* | panel_get_data (...) |
void | panel_size (...) |
uint32_t | panel_layout (...) |
Layout* | panel_get_layout (...) |
void | panel_visible_layout (...) |
void | panel_update (...) |
real32_t | panel_scroll_width (...) |
real32_t | panel_scroll_height (...) |
A Panel is a control within a window that groups other controls. It defines its own reference system, that is, if we move a panel all its descendants will move in unison since their locations will be relative to its origin. It will support other (sub)-panels as descendants, which allows to form a Window Hierarchy (Figure 1). For portability, this Gui library does not support specific coordinates and sizes for elements linked to a panel, but the association is carried out by a Layout object which is responsible for calculating at runtime the final locations of controls based on the platform and window manager. In Hello Subpanel! you have an elementary example of using panels.
- Use panel_create to create a new panel.
- Use panel_scroll to create a panel with scroll bars.
- Use panel_custom to create a new fully configurable panel.
- Use panel_layout to add child controls to the panel.
- Use panel_size to set the default size of the visible area.
1. Multi-layout panel
Each panel supports several layouts and allows you to switch between them at runtime (Figure 2). This allows to create dynamic responsive interfaces with very little effort, since the panel itself is responsible for linking and sizing the controls according to the active layout in each case. In Hello Multi-layout! you have an example.
- Use panel_visible_layout to change the layout.
Because the layouts are logical structures outside the window hierarchy, they can share controls as they are linked to the same panel (Figure 3). What is not allowed is to use the same objects in different panels, due to the hierarchy concept.
Unlike panels, layouts do not create any native control (GtkWidget, HWND, NSView, etc.).
2. Understanding panel sizing
We are going to show, by means of an example, the logic behind the composition and dimensioning of panels. We start with (Listing 1) where we create a relatively large panel in height.
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 |
static Window *i_window(void) { uint32_t i, n = 20; Window *window_create(ekWINDOW_STDRES); Panel *panel = panel_create(); Layout *layout = layout_create(2, n); for (i = 0; i < n; ++i) { char_t text[64]; Label *label = label_create(); Edit *edit = edit_create(); bstd_sprintf(text, sizeof(text), "Value %02d", i); label_text(label, text); bstd_sprintf(text, sizeof(text), "Edit here value %02d", i); edit_text(edit, text); layout_label(layout, label, 0, i); layout_edit(layout, edit, 1, i); } for (i = 0; i < n - 1; ++i) layout_vmargin(layout, i, 3); layout_hmargin(layout, 0, 5); layout_margin4(layout, 10, 10, 10, 10); panel_layout(panel, layout); window_panel(window, panel); return window; } |
- Lines 3-6 create the window, panel, and layout.
- Loop 8-19 adds various labels and edit boxes to the layout.
- Loop 21-22 establishes a small gap between rows.
- Lines 24-25 establish a column spacing and border margin.
- Lines 26-27 link the layout to the panel and the layout to the window.
The result of this code is the Natural sizing of the panel (Figure 4), which defaults to a width of 100 pixels for the editing controls. Labels fit to the text they contain. Separations and margins have also been applied.
In this case it is possible to resize the window, since we have used the ekWINDOW_STDRES flag when creating it (Figure 5).
This behavior may not be the most appropriate for the case at hand. By default, the layout performs the Cell expansion proportionally. But what we really want is to "stretch" the editing controls so that the rows keep their default height (Listing 2).
|
Layout *layout = layout_create(2, n + 1); ... layout_hexpand(layout, 1); layout_vexpand(layout, n); |
The previous lines cause the horizontal expansion to fall exclusively on column 1 (that of the EditBoxes). On the other hand, an extra empty row has been created, pouring all the vertical expansion into it (Figure 6).
Although the panel now behaves correctly when the window grows, we have difficulties when we want to "shrink" it below a certain limit (Figure 7). This is because natural dimensioning imposes a minimum size, since there comes a time when it is impossible to reduce the controls associated with the layout.
This can be a problem as we may have panels large enough that they even exceed the size of the monitor and cannot be fully displayed. To solve this, we can set a default size for the entire panel (Listing 3), which will be the one displayed when the window starts (Figure 8).
|
... panel_size(panel, s2df(400, 300)); ... |
This command decouples, in a way, the size of the panel from the size of its content. In this way, the Layout is free to reduce the size of the view, regardless of whether or not it can display the entire content (Figure 9).
And finally, if we want, we can create the panel with scroll bars (Listing 4) and scroll through the non-visible content (Figure 10).
|
... Panel *panel = panel_scroll(TRUE, TRUE); ... |
And, of course, everything said will work the same on any platform (Figure 11).
panel_create ()
Create a panel.
Panel* panel_create(void);
Return
The new panel.
panel_scroll ()
Create a panel with scroll bars.
Panel* panel_scroll(const bool_t hscroll, const bool_t vscroll);
hscroll |
|
vscroll |
|
Return
The new panel.
Remarks
See Understanding panel sizing.
panel_custom ()
Create a fully configurable panel.
Panel* panel_custom(const bool_t hscroll, const bool_t vscroll, const bool_t border);
hscroll |
|
vscroll |
|
border |
|
Return
The new panel.
Remarks
See Understanding panel sizing.
panel_data ()
Associate user data with the panel.
void panel_data(Panel *panel, type **data, FPtr_destroy func_destroy_data, type);
panel | The panel. |
data | User data. |
func_destroy_data | Destructor of user data. It will be called when the panel is destroyed. |
type | Type of user data. |
panel_get_data ()
Get the user data associated with the panel.
type* panel_get_data(const Panel *panel, type);
panel | The panel. |
type | Type of user data. |
Return
User data.
panel_size ()
Sets the default size of the visible area of a panel.
void panel_size(Panel *panel, const S2Df size);
panel | The panel. |
size | The default size. |
Remarks
See Understanding panel sizing.
panel_layout ()
Add a layout to a panel.
uint32_t panel_layout(Panel *panel, Layout *layout);
panel | The panel. |
layout | Layout. |
Return
The newly added layout index.
panel_get_layout ()
Get a layout of a panel.
Layout* panel_get_layout(Panel *panel, const uint32_t index);
panel | The panel. |
index | The layout index. |
Return
Layout.
panel_visible_layout ()
Set the active layout inside the panel.
void panel_visible_layout(Panel *panel, const uint32_t index);
panel | The panel. |
index | The layout index. |
Remarks
To make the change effective, you have to call panel_update.
panel_update ()
Update the window that contains the panel.
void panel_update(Panel *panel);
panel | The panel. |
Remarks
It is equivalent to calling window_update.
panel_scroll_width ()
Gets the width of the scroll bar of the associated panel.
real32_t panel_scroll_width(const Panel *panel);
panel | The panel. |
Return
The width of the bar.
Remarks
Only valid if the panel has been created with panel_scroll. Useful if we want to take into account the size of the scroll bars when setting the margins of the Layout.
panel_scroll_height ()
Gets the height of the scroll bar.
real32_t panel_scroll_height(const Panel *panel);
panel | The panel. |
Return
The height of the bar.
Remarks
See panel_scroll_width.