Cross-platform C SDK logo

Cross-platform C SDK

Window

❮ Back
Next ❯
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

Window*window_create (...)
voidwindow_destroy (...)
voidwindow_panel (...)
voidwindow_OnClose (...)
voidwindow_OnMoved (...)
voidwindow_OnResize (...)
voidwindow_title (...)
voidwindow_show (...)
voidwindow_hide (...)
voidwindow_overlay (...)
uint32_twindow_modal (...)
voidwindow_stop_modal (...)
voidwindow_hotkey (...)
voidwindow_clear_hotkeys (...)
voidwindow_cycle_tabstop (...)
gui_focus_twindow_next_tabstop (...)
gui_focus_twindow_previous_tabstop (...)
gui_focus_twindow_focus (...)
GuiControl*window_get_focus (...)
voidwindow_focus_info (...)
voidwindow_update (...)
voidwindow_origin (...)
voidwindow_size (...)
V2Dfwindow_get_origin (...)
S2Dfwindow_get_size (...)
S2Dfwindow_get_client_size (...)
R2Dfwindow_control_frame (...)
V2Dfwindow_client_to_screen (...)
voidwindow_defbutton (...)
voidwindow_cursor (...)

Window objects are the highest-level containers within the user interface (Figure 1). They are made up of the title bar, where the close, maximize and minimize buttons are located, the interior area and the frame. If the window supports resizing, said frame can be dragged with the mouse to change its size. The interior or client area (Figure 2) is where the controls that make up the interface itself reside and is configured through a main panel. In Hello World! you have a simple example of composition and sample of a window.

  • Use window_create to create a window.
  • Use window_panel to assign the main panel.
  • Use window_show to show a window.
  • Use the ekWINDOW_TITLE flag to include the title bar.
  • Use window_title to assign a title.
  • Screenshot of the Windows 3 operating system.
    Figure 1: The concept of a window appears from the first desktop systems.
    Client area of a window.
    Figure 2: The client area is the inner part of the window.
NAppGUI does not distinguish between window, dialog box, message box, etc. The role of each window will depend on the controls it contains, its location and its behavior.

1. Window size

In principle, the size of the window is calculated automatically based on the Natural sizing of its main panel, but it can be altered at any time.

  • Use window_size to resize the main panel.
  • Use the ekWINDOW_MAX flag to include the maximize button in the title bar.
  • Use the ekWINDOW_MIN flag to include the minimize button in the title bar.
  • Use the ekWINDOW_RESIZE flag to create a window with resizable borders.

The change in the dimensions of the client area implies a relocation and re-sizing of the interior controls. This is handled automatically through the layout objects, depending on how your Cell expansion has been configured and will recursively propagate through all sublayouts. In Die you have an example of resizing a window (Figure 3).

Shows how the excess is distributed among the controls when resizing the window.
Figure 3: Resizing the window in the demo Die.

2. Closing the window

Normally a window is closed by pressing the [X] button located to the right of the title bar. But sometimes it can be useful to also close it with the [ENTER] or [ESC] keys. Closing a window implies hiding it, but not destroying it. That is, we can show an already closed window again using window_show. In the case that the closing is conditioned to a state of the application, such as saving a file for example, we must assign a handler through window_OnClose and decide there whether to close it or not.

By destroying a window, all its internal elements and controls are implicitly destroyed.

3. Modal windows

They are those that, when launched, block the previous window (or parent) until it is closed (Figure 4). Being "modal" or not is not a characteristic of the window itself, but of the way it is launched. In Hello Modal Window! you have an example of use.

  • Use window_modal to display a window in modal mode.
  • Use window_stop_modal to hide it and stop the modal loop.
  • Various modal windows.
    Figure 4: Multiple modal windows.

After calling window_modal, the program stops at this point, waiting for the window to close, which can be done using [X], [ENTER], [ESC] or by calling window_stop_modal (Listing 2). The value returned by this function will be:

  • ekGUI_CLOSE_ESC (1). If the modal window was closed by pressing [ESC].
  • ekGUI_CLOSE_INTRO (2). If the modal window was closed by pressing [ENTER].
  • ekGUI_CLOSE_BUTTON (3). If the modal window was closed by pressing [X].
  • The value indicated in window_stop_modal.
  • Listing 2: Using modal windows.
     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
    
    static void i_OnAcceptClick(Window *window, Event *e)
    {
        window_stop_modal(window, 300);
    }
    
    Window *window = i_create_window_with_accept_button();
    // The program will stop HERE until window is closed
    uint32_t ret = window_modal(window);
    
    if (ret == 1)
    {
        // Closed by ESC
    }
    else if (ret == 2)
    {
        // Closed by INTRO
    }
    else if (ret == 3)
    {
        // Closed by [X]
    }
    else if (ret == 300)
    {
        // Closed by window_stop_modal
    }
    
    window_destroy(&window);
    

By default, the modal window will be hidden after receiving the call to window_stop_modal, but it will not be destroyed as we indicated above. On certain occasions (although not very common), we may want to relaunch the window after finishing the modal cycle without producing an unsightly "flicker" due to a new (and fast) display after closing the window.

  • Use the ekWINDOW_MODAL_NOHIDE flag when creating the window to prevent it from being hidden after the modal loop.

4. Overlay windows

Sometimes it can be useful to display small windows on top of the main one that temporarily include additional controls. It is a similar case to modal windows, with the difference that the "parent" window will not be deactivated and will continue to receive events from the operating system, while the secondary one remains visible. They usually do not include a border or title bar. In Hello Overlay Window! you have the source code for (Figure 5).

Small window superimposed on the main one.
Figure 5: Overlay window with additional controls.

It is common that we have to position the overlay windows taking as reference some control inside the window, but the origin of the window must be provided in screen coordinates. (Listing 3) shows how to correctly perform the coordinate transformation of (Figure 5).

Listing 3: Alignment of the overlay window with respect to an Editbox.
 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
static void i_OnIdleLaunch(FlyOut *flyout, Event *e)
{
    /* Edit control bounds in window coordinates */
    R2Df frame = window_control_frame(flyout->parent, flyout->edit);
    /* Top-Left edit control in screen coordinates */
    V2Df pos = window_client_to_screen(flyout->parent, frame.pos);
    /* Flyout window size */
    S2Df size = window_get_size(flyout->flywin);

    switch (flyout->align) {
    case 0:
        pos.y += frame.size.height;
        break;
    case 1:
        pos.y -= size.height;
        break;
    case 2:
        pos.x -= size.width - frame.size.width;
        pos.y += frame.size.height;
        break;
    case 3:
        pos.x -= size.width - frame.size.width;
        pos.y -= size.height;
        break;
    }

    /* Position in screen coordinates */
    window_origin(flyout->flywin, pos);
    window_overlay(flyout->flywin, flyout->parent);
    unref(e);
}

If we click on the parent window, the secondary window will be deactivated and hidden automatically. We will have to call window_overlay again to show it. If we want to avoid closing due to deactivation, we must consider the value ekGUI_CLOSE_DEACT in window_OnClose. Of course, we can also include the ekGUI_CLOSE_ESC and ekGUI_CLOSE_INTRO flags to close the window using the keyboard.


5. Keyboard focus

Certain windows, such as dialog boxes, make extensive use of the keyboard. It is even possible that the user will have to manage data entry without using the mouse. This is why we have to be very clear about how the different elements behave when keystrokes. The only control that receives key events within a given window is called keyboard focus. Typically this control appears with the highlighted border (Figure 6).

  • Use window_get_focus to get the keyboard focus control.
  • Two list controls, where one of them, the one on the left, has keyboard focus.
    Figure 6: The control on the left has keyboard focus.

5.1. Focus change

The keyboard focus is automatically assigned to the first control in the tab-list when the window is activated and can be changed in different ways:

  • Using [TAB] or [SHIFT]+[TAB] we will move through the controls included in the tab-list, as we already saw in Tabstops.
  • Clicking on the control to which we want to connect the keyboard.
  • Using window_focus, which will set it to the desired control via code.
  • Using window_next_tabstop which is equivalent to pressing [TAB]. In Hello IP-Input! you have several Edit that move to the next control when exactly three numbers are entered.
  • Using window_previous_tabstop which is equivalent to pressing [SHIFT]+[TAB].
These functions will return a gui_focus_t to indicate whether the focus change was successful or not.

5.2. Focus protocol

Changing focus between controls is not direct, but rather follows a protocol (Figure 7). Generally we don't have to worry about this, since each control has a default behavior when releasing or accepting focus. The points to keep in mind are the following:

  • Edit controls can retain focus in response to an OnChange event, as we saw in Filter texts.
  • Custom views allow you to make a decision at runtime using the OnResignFocus and OnAcceptFocus events, as we also saw in Using the keyboard. By default, they will accept both cases.
  • Use window_focus_info within edit_OnChange or view_OnResignFocus to obtain additional information about the focus change operation.

For example, if we press [TAB] on an Edit, the OnChange event will be raised, which may return FALSE as a reply. In this case, the keyboard focus will remain on that Edit and will not jump to the next control.

Graphic showing the exchange of messages to change keyboard focus to a new control.
Figure 7: Protocol for changing the focus.

5.3. Tablist without cycles

Returning to navigation using the [TAB] key, the usual thing will be for the tabstops to work cyclically (by default). That is, if the last control in the tab-list has focus and we press [TAB], the focus will go back to the first control in the tab-list. It is possible to disable this behavior, leaving the focus fixed on the last control even if we repeatedly press the [TAB] key. Likewise, the focus will remain fixed on the first control even if we press [SHIFT]+[TAB].


6. Default button

The default button is the one that appears highlighted within the window and that will receive an OnClick event every time the [RETURN] key is pressed, regardless of which control have keyboard focus. In principle, there is no button by default, it must be indicated explicitly in the window.


7. Keyboard shortcuts

As we have already indicated, the keyboard focus will be fixed on some control inside the window, be it a Edit, Button, View, etc. But it is possible that we want to define global actions associated with a specific key.

The hotkeys will have priority over the keyboard focus (Figure 9). That is, if we have an action linked to the [F9] key, the window will capture the ekGUI_EVENT_KEYDOWN event (F9) and this will not reach the control that currently has the keyboard focus.

Keyboard shortcut.
Figure 9: Processing a keyboard shortcut.

To conclude, we summarize all the points to take into account when carrying out correct keyboard management.

  • Close the window with [RETURN] or [ESC.
  • Correctly manage the tab-list and keyboard focus.
  • Define a default button, which is activated when pressing [RETURN].
  • Define the appropriate keyboard shortcuts.
❮ Back
Next ❯

window_create ()

Create a new window.

Window*
window_create(const uint32_t flags);
flags

Combination of window_flag_t values.

Return

The window.


window_destroy ()

Destroy the window and all its contents.

void
window_destroy(Window **window);
window

The window. Will be set to NULL after destruction.

Remarks

Panels, layouts and components will be recursively destroyed.


window_panel ()

Associate the main panel with a window.

void
window_panel(Window *window,
             Panel *panel);
window

The window.

panel

Main panel, which integrates all the content of the window (views, controls, etc).

Remarks

The size of the window will be adjusted based on the Natural sizing of the main panel.


window_OnClose ()

Set an event handler for the window closing.

void
window_OnClose(Window *window,
               Listener *listener);
window

The window.

listener

Callback function to be called before closing a window.

Remarks

See Closing the window.


window_OnMoved ()

Set an event handler for moving the window on the desktop.

void
window_OnMoved(Window *window,
               Listener *listener);
window

The window.

listener

Callback function to be called as the title bar is dragged and the window moves across the desktop.

Remarks

See GUI Events.


window_OnResize ()

Set an event handler for window resizing.

void
window_OnResize(Window *window,
                Listener *listener);
window

The window.

listener

Callback function to be called as the outer edges of the window are dragged to resize.

Remarks

The resizing and relocation of elements is done automatically based on the main Layout, so it is not usually necessary for the application to respond to this event. See GUI Events.


window_title ()

Set the text that will display the window in the title bar.

void
window_title(Window *window,
             const char_t *text);
window

The window.

text

UTF8 C-string terminated in null character '\0'.


window_show ()

Show the window. By default windows are created hidden. You have to show them explicitly.

void
window_show(Window *window);
window

The window.


window_hide ()

Hide the window.

void
window_hide(Window *window);
window

The window.


window_overlay ()

Launch an overlay window.

void
window_overlay(Window *window,
               Window *parent);
window

The window.

parent

The main window.

Remarks

See Overlay windows.


window_modal ()

Launch a window in modal mode.

uint32_t
window_modal(Window *window,
             Window *parent);
window

The window.

parent

The parent window.

Return

Value returned by window_stop_modal.

Remarks

parent stop receiving events until you call window_stop_modal. See Modal windows.


window_stop_modal ()

Ends the modal cycle of a window.

void
window_stop_modal(Window *window,
                  const uint32_t return_value);
window

The window previously launched with window_modal.

return_value

Value to be returned window_modal.

Remarks

See Modal windows.


window_hotkey ()

Sets an action associated with pressing a key.

void
window_hotkey(Window *window,
              const vkey_t key,
              const uint32_t modifiers,
              Listener *listener);
window

The window.

key

The key.

modifiers

Modifiers. 0 or combination of mkey_t.

listener

Handler of the event associated with the key press. If NULL, removes the event associated with the key (if one exists).

Remarks

See Keyboard shortcuts.


window_clear_hotkeys ()

Removes all keyboard shortcuts associated with the window.

void
window_clear_hotkeys(Window *window);
window

The window.

Remarks

See Keyboard shortcuts.


window_cycle_tabstop ()

Activate or deactivate the cyclic behavior of tabstops.

void
window_cycle_tabstop(Window *window,
                     const bool_t cycle);
window

The window.

cycle

TRUE to activate cycles in tabstops (default).

Remarks

See Tablist without cycles.


window_next_tabstop ()

Moves keyboard focus to the next control in the tab-list. It has the same effect as pressing [TAB].

gui_focus_t
window_next_tabstop(Window *window);
window

The window.

Return

Result of the focus change operation.

Remarks

See Focus change.


window_previous_tabstop ()

Moves the keyboard focus to the previous control in the tab-list. This has the same effect as pressing [SHIFT]+[TAB].

gui_focus_t
window_previous_tabstop(Window *window);
window

The window.

Return

Result of the focus change operation.

Remarks

See Focus change.


window_focus ()

Set keyboard focus to a specific control.

gui_focus_t
window_focus(Window *window,
             GuiControl *control);
window

The window.

control

The control that will receive the focus.

Return

Result of the focus change operation.

Remarks

See Focus change.


window_get_focus ()

Gets the control that keyboard focus has.

GuiControl*
window_get_focus(Window *window);
window

The window.

Return

The control.


window_focus_info ()

Gets additional information about a keyboard focus change operation.

void
window_focus_info(Window *window,
                  FocusInfo *info);
window

The ventana.

info

Structure where the operation data will be returned.

Remarks

Sometimes the decision to release keyboard focus for a control requires context information. For example, what action caused the change (press [TAB], click on another control) or what control will receive the focus. See Focus protocol.


window_update ()

Recalculate the position and size of the controls after modifying any Layout.

void
window_update(Window *window);
window

The window.


window_origin ()

Move the window to specific desktop coordinates.

void
window_origin(Window *window,
              const V2Df origin);
window

The window.

origin

Position (x,y) of the upper-left corner of the window.


window_size ()

Set the size of the client area of the window.

void
window_size(Window *window,
            const S2Df size);
window

The window.

size

Main panel size.

Remarks

The final size will depend on the window frame and desktop theme settings. This measure only refers to the interior area.


window_get_origin ()

Get the window position.

V2Df
window_get_origin(const Window *window);
window

The window.

Return

Position (x,y) from the upper-left corner of the window.


window_get_size ()

Get the total dimensions of the window.

S2Df
window_get_size(const Window *window);
window

The window.

Return

Window size.

Remarks

The frame and title bar are taken into account.


window_get_client_size ()

Get the dimensions of the client area of the window.

S2Df
window_get_client_size(const Window *window);
window

The window.

Return

Main panel size.


window_control_frame ()

Gets the position and size of a control in window coordinates.

R2Df
window_control_frame(const Window *window,
                     const GuiControl *control);
window

The window.

control

The control.

Return

Frame in window coordinates.

Remarks

control must belong to the window, be active and visible. The point (0,0) corresponds to the upper left vertex of the client area of the window. See Overlay windows.


window_client_to_screen ()

Transforms a point expressed in window coordinates to screen coordinates.

V2Df
window_client_to_screen(const Window *window,
                        const V2Df point);
window

The window.

point

The point in window coordinates.

Return

The point in screen coordinates.

Remarks

point is an inner point, where (0,0) corresponds to the top left vertex of the client area of the window. See Overlay windows.


window_defbutton ()

Set the default window button. It will be activated when pressed [Intro].

void
window_defbutton(Window *window,
                 Button *button);
window

The window.

button

The button.

Remarks

This function disables the possible previous default button. For the new button to be set, it must exist in the active layout, which requires this function to be called after window_panel. See Default button.


window_cursor ()

Change the mouse cursor.

void
window_cursor(Window *window,
              const gui_cursor_t cursor,
              const Image *image,
              const real32_t hot_x,
              const real32_t hot_y);
window

The window.

cursor

Identifier of the new cursor.

image

Custom image. Only valid in ekGUI_CURSOR_USER.

hot_x

The x coordinate of the click point. Only valid in ekGUI_CURSOR_USER.

hot_y

The y coordinate of the click point. Only valid in ekGUI_CURSOR_USER.

Remarks

hot_x, hot_y indicate the "sensitive" point within the image, which will indicate the exact position of the mouse.

❮ Back
Next ❯