frang75 / nappgui_src

SDK for building cross-platform desktop apps in ANSI-C
https://www.nappgui.com
MIT License
503 stars 50 forks source link

Assertion failure when programmatically resizing a window when ekWINDOW_RESIZE is not set. #158

Open colugomusic opened 1 month ago

colugomusic commented 1 month ago

The window_size implementation currently performs this cassert:

    cassert(window->flags & ekWINDOW_RESIZE);

I want to be able to create a window which cannot be resized by the end-user (i.e. they cannot drag the edges of the window frame to resize it) but I still need to be able to set the window size programmatically, so removing this assert altogether would allow this.

Alternatively, perhaps there could be a way to remove the ekWINDOW_RESIZE flag after creating it and setting the size, to disallow resizing by the user, but I assume that would be more difficult to implement.

frang75 commented 1 month ago

Not really. This guard is there to prevent misuse of the SDK. When you create a non-resizable window (e.g. DialogBox), the final size will be determined by the child elements. The steps to follow are:

Ultimately, it's a bottom-up strategy. Here https://nappgui.com/en/gui/layout.html you have more info.

When you create resizable windows the steps are the same but, in addition, you have to define how the columns/rows of the layout will be resized (by default proportionally). layout_hexpand() and others. In this scenario, it makes sense to do a window_size() because layouts know how to handle size changes imposed by the parent window.

colugomusic commented 1 month ago

I think I understand, but in my case, all i have is a window, a panel, a layout, and a view. How should I set the size of the non-resizable window? Calling view_size seems to have no effect.

frang75 commented 1 month ago

It must work

/*---------------------------------------------------------------------------*/

static void i_OnDraw(App *app, Event *e)
{
    const EvDraw *p = event_params(e, EvDraw);
    draw_clear(p->ctx, kCOLOR_BLUE);
}

/*---------------------------------------------------------------------------*/

static Panel *i_panel(App *app)
{
    Panel *panel = panel_create();
    Layout *layout = layout_create(1, 1);
    View *view = view_create();
    view_size(view, s2df(300, 200));
    view_OnDraw(view, listener(app, i_OnDraw, App));
    layout_view(layout, view, 0, 0);
    panel_layout(panel, layout);
    return panel;
}

one_single_view

colugomusic commented 1 month ago

I see, there is a hidden rule in the API.

This doesn't work, the window will have the wrong size:

    layout_view(...);
    panel_layout(...);
    window_panel(...);
    view_size(...);

But this does work:

    layout_view(...);
    view_size(...);
    panel_layout(...);
    window_panel(...);

So I assume it is not possible to change the view size at runtime, and have the window automatically resize itself to accommodate it, but this is OK for me.

frang75 commented 1 month ago

Effectively. When you call to window_panel() the SDK recursively calculates the final position and sizes of all children. Once the window have been composed, any external change requires a window_update().

You have shortcuts to update content: window_update() layout_update() panel_update()

all of them have the same effect: Recompute the window and children dimensions.

image

frang75 commented 1 month ago

Its a good point to improve the documentation

colugomusic commented 1 month ago

I see, thank you for the help!