window and subwindow handling; see: doc/ref/window.html

/* A window or a subwindow */ struct mbtk_window_s { union { void *ptr[32]; long int i[32]; } backend_data; /* opaque backend data */ mbtk_display_t *display; mbtk_widget_t *in_widget; /* if not a native window but an embedded window (subwindow) */ hvbox_t *root; long x, y; /* native window: last known screen coords; embedded window: coords relative to the parent widget's window (calculated) */ long w, h; /* actual width and height in pixels */ long min_w_user, min_h_user; /* the user doesn't want the window smaller */ long min_w_layout, min_h_layout; /* the widget layout doesn't let the window smaller */ long min_w_last, min_h_last; /* last minimum window size actually set (larger of _user and _layout) */ long content_x0, content_y0; /* subwindow: when scrolled, this is the top-left corner pixel coordinate of the content that should be drawn from the subwindow 0;0 corner */ unsigned focus_has_pointer:1; /* whether the mouse pointer is within the focused widget */ unsigned scrolled:1; /* when set, the root widget can be as large as it wants to be and the window is going to show only a portion of it */ unsigned draw_dirty:1; unsigned layout_dirty:1; unsigned entered:1; /* if mouse pointer has entered the window */ void *user_data; /* application may use this to attach data to the window */ struct { /* last known mouse cursor pos (see also: entered) */ long last_x, last_y; } mouse; gdl_elem_t link; /* in display->gt;windows */ /* widget states arouns events */ mbtk_widget_t *focus; mbtk_widget_t *origin; /* drag&drop origin widget; set by the handler, cleared by central event code on release */ long origin_x, origin_y; /* drag&drop origin coords in window coordinate system; set and cleared by central event code on release */ /* lists of resources */ htpxid_t binds; /* pixmap bindings key: (mbtk_pixmap_t *); value: mbtk_px_id_t */ gdl_list_t handlers; /* handlers with extra allocation are registered into a window for destroying handlers when window is destroyed */ vtp0_t watch_close; /* (int *) that are increased if mbtk_window_close() is called on this window */ /* Optional: in case of a subwindow if this call is not NULL, these are called in low level rendering when the rendering context is already set up. Argument native_ctx is the backend-specific rendering context to be used. This call is useful for backend-native rendering code on canvas, e.g. the canvas_native widget. Pre is called before normal miniboxtk rendering, post is called after. These functions should not set viewport or flush, those are done by the backend code. */ int (*native_draw_pre)(mbtk_window_t *subwin, void *native_ctx); /* if returns non-zero, skip normal draw */ void (*native_draw_post)(mbtk_window_t *subwin, void *native_ctx); }; typedef enum mbtk_window_type_e { /* base type */ MBTK_WNTY_NORMAL = 0x0001, /* top window, dialog; non-modal */ MBTK_WNTY_MODAL = 0x0002, /* top window, dialog; modal (input grab) */ MBTK_WNTY_DROPDOWN_MENU = 0x0003, /* window of a menu open from the main menu system */ MBTK_WNTY_POPUP_MENU = 0x0004, /* window of a popup-menu */ MBTK_WNTY_TEAROFF_MENU = 0x0005, /* window of a torn-off menu (floating dialog) */ MBTK_WNTY_COMBO = 0x0006, /* combo box menu/selections */ MBTK_WNTY_TOOLTIP = 0x0007, /* tooltip popup only */ /* bitfield */ MBTK_WNTY_OPENGL = 0x0100, MBTK_WNTY_VULKAN = 0x0200 } mbtk_window_type_t; /* Open a new window */ mbtk_window_t *mbtk_window_new(mbtk_display_t *disp, mbtk_window_type_t type, const char *title, long x, long y, long w, long h); /* Create a new subwindow within a widget (within an existing window or subwindow) */ mbtk_window_t *mbtk_subwindow_new(mbtk_display_t *disp, mbtk_widget_t *parent, long x, long y, long w, long h); /* Change the title of an existing window */ void mbtk_window_set_title(mbtk_window_t *win, const char *title); /* Move window on top of the windowing stack */ void mbtk_window_raise(mbtk_window_t *win); /* Change whether the window is hidden or shown */ void mbtk_window_hide(mbtk_window_t *win); void mbtk_window_show(mbtk_window_t *win); /* win is transient for tr_for; this matters in modality and stacking, depending on the WM. May be a no-op. */ void mbtk_window_transient4(mbtk_window_t *win, mbtk_window_t *tr_for); /* Fill in x and y with the last known mouse coordinates. Returns 1 or 0 if mouse cursor is within the window or not. */ int mbtk_window_get_last_mouse_coords(mbtk_window_t *win, long *x, long *y); /* Immediately close a window (does not generate win close event) */ void mbtk_window_close(mbtk_window_t *win); /* Set minimum or actual size; actual size has to be greater or equal to minimum size. */ void mbtk_window_set_min_size(mbtk_window_t *win, long w, long h); void mbtk_window_set_size(mbtk_window_t *win, long w, long h); /* Set window's root widget's "win_close" callback; it is called when the window is requested to be closed by the user through the window manager. If it returns MBTK_EVENT_HANDLED, processing stops and the window is not closed. */ void mbtk_window_callback_close(mbtk_window_t *win, mbtk_event_handled_t (*cb)(mbtk_widget_t *w, mbtk_kw_t id, void *user_data), void *user_data); /* Return the root widget that was added by the caller (first child of the built-in hvbox root) */ MBTK_INLINE mbtk_widget_t *mbtk_window_get_root(mbtk_window_t *win) { return ((win == NULL) || (win->gt;root == NULL)) ? NULL : (mbtk_widget_t *)(win->gt;root->gt;ch_first); } MBTK_INLINE void mbtk_window_get_pos(mbtk_window_t *win, long *x, long *y) { *x = win->gt;x; *y = win->gt;y; } MBTK_INLINE void mbtk_window_get_size(mbtk_window_t *win, long *w, long *h) { *w = win->gt;w; *h = win->gt;h; } #define mbtk_win_dirty_layout(win) \ do { \ (win)->gt;layout_dirty = 1; \ if ((win)->gt;display != NULL) \ (win)->gt;display->gt;need_win_redraw = 1; \ } while(0) #define mbtk_win_dirty_draw(win) \ do { \ (win)->gt;draw_dirty = 1; \ (win)->gt;display->gt;need_win_redraw = 1; \ } while(0) /* Recalculate the layout of a window if needed (or if forced). Useful when widget content changed and new dimensions need to be known immediately, e.g. for setting scroll offsets. */ void mbtk_win_update_layout(mbtk_window_t *win, mbtk_bool_t force);