Cross-platform C SDK logo

Cross-platform C SDK

View

❮ 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

View*view_create (void)
View*view_scroll (void)
View*view_custom (...)
voidview_data (...)
type*view_get_data (...)
voidview_size (...)
voidview_OnDraw (...)
voidview_OnOverlay (...)
voidview_OnSize (...)
voidview_OnEnter (...)
voidview_OnExit (...)
voidview_OnMove (...)
voidview_OnDown (...)
voidview_OnUp (...)
voidview_OnClick (...)
voidview_OnDrag (...)
voidview_OnWheel (...)
voidview_OnKeyDown (...)
voidview_OnKeyUp (...)
voidview_OnFocus (...)
voidview_OnResignFocus (...)
voidview_OnAcceptFocus (...)
voidview_OnScroll (...)
voidview_keybuf (...)
voidview_get_size (...)
voidview_content_size (...)
voidview_scroll_x (...)
voidview_scroll_y (...)
voidview_scroll_size (...)
voidview_scroll_visible (...)
voidview_viewport (...)
voidview_point_scale (...)
voidview_update (...)
void*view_native (...)

The View controls or custom views (Figure 1) are blank areas within the window that allow us to implement our own components. We will have total freedom to draw and capture the mouse or keyboard events that allow us to interact with it.


1. Draw in views

The contents of the drawing area will need to be refreshed on certain occasions. Either because the operating system must update a previously overlapping part, or because the drawing itself has changed (animations, user actions, etc.). When the time comes, the window manager will launch an OnDraw event that the application must capture to implement the drawing commands that allow the content to be recreated.

The OnDraw event handler will receive a drawing context, on which the different Drawing primitives (Listing 1) can be applied.

Listing 1: Basic drawing in custom views.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
static void i_OnDraw(App *app, Event *e)
{
    const EvDraw *p = event_params(e, EvDraw);
    draw_clear(p->ctx, kCOLOR_RED);
    draw_line_width(p->ctx, 10.f);,
    draw_line_color(p->ctx, kCOLOR_GREEN);
    draw_rect(p->ctx, ekSTROKE, 0, 0, p->width, p->height);
}
...
view_OnDraw(view, listener(app, i_OnDraw, App));

In Die you have a simple example application that implements drawing custom views. It represents the figure of a die, allowing us to edit certain parameters of the drawing. This interaction will launch a series of events that will require the redrawing of our figure. The entire cycle can be summarized in these steps (Figure 2):

  • Some event occurs that requires updating the content of the view.
  • The application calls the view_update method to notify that the view must be updated.
  • At the appropriate moment, the system will send an OnDraw event with a DCtx context ready to draw.
  • Chart with the different phases of updating a view.
    Figure 2: Refresh cycle of a custom view.
The operating system can launch OnDraw events at any time without previously calling view_update.

2. Scrolling views

It is possible that the "scene" to be rendered is much larger than the control itself, so it will show only a small fragment of it (Figure 3). In these cases we will say that the view is a viewport of the scene. We can manage it in two ways:

Relationship of a 2D scene to the viewport where it is displayed.
Figure 3: Scene and view (viewport).
  • Use draw_matrixf at the beginning of OnDraw to indicate the transformation that integrates the displacement, zoom and possible rotation of the viewport with respect to the scene. All of this must be managed by the application and we do not have to do anything special, except call view_update every time it is necessary to refresh.
  • Use scroll bars that allow the user to move freely through the content. In this case, managing the view is a bit more complicated. This is what we must take into account:

Something important to keep in mind is to avoid drawing non-visible elements, especially in very large scenes or with a multitude of objects. The operating system will send successive OnDraw() events as the user manipulates the scrollbars, indicating the viewport parameters in the EvDraw structure. In DrawBig you have an example application that shows how to correctly manage this type of cases.

It is possible that the dimensions of the viewport received in OnDraw are somewhat larger than the size of the control. This is because certain window managers force you to draw in certain non-visible areas close to the edges, in order to avoid flickering when scrolling very quickly.

3. Drawing overlays

An overlay is a graphic layer that is drawn on top of the main content dumped by the OnDraw event. It uses the coordinate system of the View control where the coordinate (0,0) corresponds to the top-left border (Figure 4) (Listing 2). Therefore, the overlays remain fixed, regardless of the movement of the scroll bars. They are useful for drawing markers or information that we do not want to be displaced. They can also be used in views without scroll bars.

Animation showing the drawing of an overlay.
Figure 4: Overlay drawing. Animation at https://nappgui.com/img/gui/overlay.gif.
Listing 2: Code to generate the overlay.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
static void i_OnOverlay(App *app, Event *e)
{
    const EvDraw *p = event_params(e, EvDraw);
    cassert_no_null(app);
    if (app->overlay == TRUE)
    {
        draw_fill_color(p->ctx, kCOLOR_BLACK);
        draw_text_color(p->ctx, kCOLOR_WHITE);
        draw_rect(p->ctx, ekFILL, 5, 5, 80, 20);
        draw_text(p->ctx, "OVERLAY", 5, 5);
    }
}
...
view_OnOverlay(view, listener(app, i_OnOverlay, App));

4. Using the mouse

In order to interact with the control, it is necessary to define handlers for the different mouse events (Listing 3), (Figure 5). The operating system will notify the user's actions so that the application can launch the relevant actions. It is not necessary to use all of them, only the essential ones in each case.

Listing 3: Response to mouse events.
1
2
3
4
5
6
7
static void i_OnMove(App *app, Event *e)
{
    const EvMouse *p = event_params(e, Event);
    do_something_onmouse_moved(app, p->x, p->y);
}
...
view_OnMove(view, listener(app, i_OnMove, App));
Illustration of mouse events in a 2d view.
Figure 5: View position events.
  • Use view_OnEnter to know when the cursor enters the view.
  • Use view_OnExit to know when the cursor leaves the view.
  • Use view_OnMove to know when the cursor is moving through the view.
  • Use view_OnDown to know when a button is pressed within the view.
  • Use view_OnUp to know when a button is released inside the view.
  • Use view_OnClick to identify a click (Fast Up + Down).
  • Use view_OnDrag to move the cursor with a pressed button.
  • Use view_OnWheel to use the mouse wheel.
If the view uses scroll bars, the cursor (x,y) position passed to EvMouse in each event, refers to the global coordinates of the scene, taking into account the displacement. In views without scroll bars, they are the control local coordinates. The local coordinates of the viewport are in (lx,ly).

5. Using the keyboard

When a view receives Keyboard focus, all keystrokes will be directed to it, so we must implement the appropriate handlers.

  • Use view_OnKeyDown to detect when a key is pressed.
  • Uses view_OnKeyUp to detect when a key is released.
  • Use view_OnFocus to notify the application whenever the view receives (or loses) keyboard focus. In (Figure 6), the view changes the color of the active cell when it has focus.
  • Use view_OnResignFocus to prevent the view from losing keyboard focus.
  • Use view_OnAcceptFocus to prevent the view from getting keyboard focus.
  • Changing keyboard focus between two controls.
    Figure 6: View without keyboard focus (left) and with it (right).
If a view does not need to use the keyboard, make sure it cannot receive focus when you press [TAB] Tabstops. It also implements view_OnAcceptFocus to prevent it from getting focus when you click on it.

In the KeyDown and KeyUp events a vkey_t will be received with the value of the pressed key. In (Figure 7) and (Figure 8) the correspondence of these codes is shown. In Synchronous applications we may need to know if a key is pressed or not during the update cycle (synchronous) where we do not have access to the OnKeyDown and OnKeyUp events (asynchronous). This can be done by assigning the view a keyboard buffer using view_keybuf, which will capture the events associated with each key and allow us to consult its status at any time in a comfortable way.

Representation of a keyboard with the code of each key.
Figure 7: Keyboard codes.
Representation of an extended keyboard with the code of each extended key.
Figure 8: Keyboard Extended Codes.
❮ Back
Next ❯

view_create ()

Create a new custom view.

View*
view_create(void);

Return

The view.


view_scroll ()

Create a new custom view with scrollbars.

View*
view_scroll(void);

Return

The view.


view_custom ()

Create a new view with all the options.

View*
view_custom(const bool_t scroll,
            const bool_t border);
scroll

Use of scroll bars.

border

Draw a border.

Return

The view.

Remarks

Many window managers highlight the border when the view has keyboard focus.


view_data ()

Associate user data with the view.

void
view_data(View *view,
          type **data,
          FPtr_destroy func_destroy_data,
          type);
view

The view.

data

User data.

func_destroy_data

Destructor of user data. It will be called upon destroying the view.

type

Type of user data.


view_get_data ()

Obtiene los datos de usuario asociados con la vista.

type*
view_get_data(const View *view,
              type);
view

The view.

type

Type of user data.

Return

Los datos de usuario.


view_size ()

Set the default view size.

void
view_size(View *view,
          const S2Df size);
view

The view.

size

The size.

Remarks

It corresponds to Natural sizing of control Default 128x128.


view_OnDraw ()

Set an event handler to draw in the view.

void
view_OnDraw(View *view,
            Listener *listener);
view

The view.

listener

Callback function to be called every time the drawing needs to be refreshed.

Remarks

See Draw in views and GUI Events.


view_OnOverlay ()

Sets an event handler to draw the overlay.

void
view_OnOverlay(View *view,
               Listener *listener);
view

The view.

listener

Callback function to be called every time the overlay needs to be refreshed.

Remarks

Ver Drawing overlays and GUI Events.


view_OnSize ()

Set an event handler for resizing.

void
view_OnSize(View *view,
            Listener *listener);
view

The view.

listener

Callback function to be called every time the view changes size.

Remarks

See GUI Events.


view_OnEnter ()

Set an event handler for mouse enter.

void
view_OnEnter(View *view,
             Listener *listener);
view

The view.

listener

Callback function to be called when the mouse cursor enters the view area.

Remarks

See Using the mouse and GUI Events.


view_OnExit ()

Set an event handle for mouse exit.

void
view_OnExit(View *view,
            Listener *listener);
view

The view.

listener

Callback function to be called when the mouse cursor exits the view area.

Remarks

See Using the mouse and GUI Events.


view_OnMove ()

Set an event handler for mouse movement.

void
view_OnMove(View *view,
            Listener *listener);
view

The view.

listener

Callback function to be called as the mouse cursor moves over the view.

Remarks

See Using the mouse and GUI Events.


view_OnDown ()

Sets an event handler for a mouse button down.

void
view_OnDown(View *view,
            Listener *listener);
view

The view.

listener

Callback function that will be called every time the button is down.

Remarks

See Using the mouse and GUI Events.


view_OnUp ()

Sets an event handler for a mouse button up.

void
view_OnUp(View *view,
          Listener *listener);
view

The view.

listener

Callback function that will be called every time the button is up.

Remarks

See Using the mouse and GUI Events.


view_OnClick ()

Set an event handler for mouse click.

void
view_OnClick(View *view,
             Listener *listener);
view

The view.

listener

Callback function that will be called every time the view is clicked.

Remarks

See Using the mouse and GUI Events.


view_OnDrag ()

Set an event handler for mouse drag.

void
view_OnDrag(View *view,
            Listener *listener);
view

The view.

listener

Callback function to be called while dragging the mouse cursor over the view.

Remarks

"Drag" is to move the mouse with one of the buttons pressed. See Using the mouse and GUI Events.


view_OnWheel ()

Set an event handler for mouse wheel.

void
view_OnWheel(View *view,
             Listener *listener);
view

The view.

listener

Callback function that will be called when the mouse wheel moves over the view.

Remarks

See Using the mouse and GUI Events.


view_OnKeyDown ()

Set an event handler for a keystroke.

void
view_OnKeyDown(View *view,
               Listener *listener);
view

The view.

listener

Callback function to be called when a key is pressed and the view has the keyboard focus.

Remarks

See Using the keyboard and GUI Events.


view_OnKeyUp ()

Set an event handler for releasing a key.

void
view_OnKeyUp(View *view,
             Listener *listener);
view

The view.

listener

Callback function to be called when a key is released and the view has the keyboard focus.

Remarks

See Using the keyboard and GUI Events.


view_OnFocus ()

Sets an event handler for keyboard focus.

void
view_OnFocus(View *view,
             Listener *listener);
view

The view.

listener

Callback function to be called when keyboard focus is received or lost.

Remarks

See Using the keyboard and GUI Events.


view_OnResignFocus ()

Set a handler to avoid losing keyboard focus.

void
view_OnResignFocus(View *view,
                   Listener *listener);
view

The view.

listener

Callback function that is called when the view is about to lose focus. If we return FALSE, the focus will not go to another control, it will remain in the view.

Remarks

See Using the keyboard and GUI Events.


view_OnAcceptFocus ()

Set a handler to prevent getting keyboard focus.

void
view_OnAcceptFocus(View *view,
                   Listener *listener);
view

The view.

listener

Callback function that is called when the view is about to get focus. If we return FALSE, the focus will remain on the current control and will not move to the view.

Remarks

See Using the keyboard and GUI Events.


view_OnScroll ()

Set an event handler for the scroll bars.

void
view_OnScroll(View *view,
              Listener *listener);
view

The view.

listener

Callback function to be called when the user manipulates the scroll bars.

Remarks

It is not common to have to respond to these events, since the view generates OnDraw events automatically when the scroll bars are manipulated. See Scrolling views and GUI Events.


view_keybuf ()

Sets a keyboard buffer for synchronous or asynchronous query of key state.

void
view_keybuf(View *view,
            Keybuf *buffer);
view

The view.

buffer

Keyboard buffer that will be maintained by the view, capturing the OnKeyDown and OnKeyUpevents.

Remarks

It just keeps a reference to the buffer, which will need to be destroyed by the object that created it. See Keyboard buffer. The application will still be able to receive keyboard events through view_OnKeyDown and view_OnKeyUp.


view_get_size ()

Gets the current size of the view.

void
view_get_size(const View *view,
              S2Df *size);
view

The view.

size

The size.


view_content_size ()

Set the size of the drawing area when scroll bars exist.

void
view_content_size(View *view,
                  const S2Df size);
view

The view.

size

The internal size of the drawing area.

Remarks

When creating a scroll view, this method indicates the entire drawing area. The control will use it to size and position the scroll bars.


view_scroll_x ()

Move the horizontal scroll bar to the indicated position.

void
view_scroll_x(View *view,
              const real32_t pos);
view

The view.

pos

New horizontal bar position.


view_scroll_y ()

Move the vertical scroll bar to the indicated position.

void
view_scroll_y(View *view,
              const real32_t pos);
view

The view.

pos

New vertical bar position.


view_scroll_size ()

Gets the measurements of the scroll bars.

void
view_scroll_size(const View *view,
                 real32_t *width,
                 real32_t *height);
view

The view.

width

The width of the vertical bar.

height

The height of the horizontal bar.

Remarks

Useful to consider what the scroll bars occupy when drawing. If the bars overlap, 0 will be returned.


view_scroll_visible ()

Show or hide the scroll bars.

void
view_scroll_visible(View *view,
                    const bool_t horizontal,
                    const bool_t vertical);
view

The view.

horizontal

Horizontal bar.

vertical

Vertical bar.


view_viewport ()

Gets the dimensions of the visible area of the view.

void
view_viewport(const View *view,
              V2Df *pos,
              S2Df *size);
view

The view.

pos

The position of the viewport. It can be NULL.

size

The size of the viewport. It can be NULL.

Remarks

If the view does not have scroll bars, pos will be (0,0).


view_point_scale ()

Gets the scaling of the point.

void
view_point_scale(const View *view,
                 real32_t *scale);
view

The view.

scale

The scaling.

Remarks

The view size and drawing coordinates are expressed in points, which typically correspond to pixels (1pt = 1px). In Retina displays it can happen that (1pt = 2px). Although 2D Contexts handles this automatically, we may need to know the number of pixels to create another type of framebuffers (OpenGL, DirectX, etc). Pixels = view_get_size * view_point_scale.


view_update ()

Send an order to the operating system that the view should be refreshed.

void
view_update(View *view);
view

The view.


view_native ()

Gets a pointer to the native control.

void*
view_native(View *view);
view

The view.

Return

HWND in Windows, GtkWidget in Linux and NSView in macOS.

Remarks

Do not use this function if you do not know very well what you are doing.

❮ Back
Next ❯