Migrated the GTK+ backend to the new uiBin system.
This commit is contained in:
parent
41030b0a03
commit
8f24dffa01
111
unix/bin.c
111
unix/bin.c
|
@ -1,117 +1,38 @@
|
|||
// 28 april 2015
|
||||
#include "uipriv_unix.h"
|
||||
|
||||
struct bin {
|
||||
uiContainer c;
|
||||
void (*baseDestroy)(uiControl *);
|
||||
uiControl *mainControl;
|
||||
intmax_t marginLeft;
|
||||
intmax_t marginTop;
|
||||
intmax_t marginRight;
|
||||
intmax_t marginBottom;
|
||||
};
|
||||
|
||||
static void binDestroy(uiControl *c)
|
||||
int binHasOSParent(uiBin *b)
|
||||
{
|
||||
struct bin *b = (struct bin *) c;
|
||||
GtkWidget *binWidget;
|
||||
|
||||
// ensure clean removal by making sure the bin has no OS parent
|
||||
binWidget = GTK_WIDGET(uiControlHandle(uiControl(b)));
|
||||
if (gtk_widget_get_parent(binWidget) != NULL)
|
||||
complain("attempt to destroy bin %p while it has an OS parent", b);
|
||||
// don't chain up to base here; we need to destroy children ourselves first
|
||||
if (b->mainControl != NULL) {
|
||||
uiControlSetParent(b->mainControl, NULL);
|
||||
uiControlDestroy(b->mainControl);
|
||||
}
|
||||
// NOW we can chain up to base
|
||||
(*(b->baseDestroy))(uiControl(b));
|
||||
uiFree(b);
|
||||
return gtk_widget_get_parent(binWidget) != NULL;
|
||||
}
|
||||
|
||||
static void binPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
|
||||
void binSetOSParent(uiBin *b, uintptr_t osParent)
|
||||
{
|
||||
struct bin *b = (struct bin *) c;
|
||||
intmax_t marginX, marginY;
|
||||
GtkWidget *binWidget;
|
||||
|
||||
if (b->mainControl == NULL) {
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
return;
|
||||
}
|
||||
uiControlPreferredSize(b->mainControl, d, width, height);
|
||||
marginX = b->marginLeft + b->marginRight;
|
||||
marginY = b->marginTop + b->marginBottom;
|
||||
*width += marginX;
|
||||
*height += marginY;
|
||||
binWidget = GTK_WIDGET(uiControlHandle(uiControl(b)));
|
||||
gtk_container_add(GTK_CONTAINER(osParent), binWidget);
|
||||
}
|
||||
|
||||
static void binResizeChildren(uiContainer *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
|
||||
void binRemoveOSParent(uiBin *b)
|
||||
{
|
||||
struct bin *b = (struct bin *) c;
|
||||
GtkWidget *binWidget;
|
||||
GtkWidget *oldparent;
|
||||
|
||||
if (b->mainControl == NULL)
|
||||
return;
|
||||
x += b->marginLeft;
|
||||
y += b->marginTop;
|
||||
width -= b->marginLeft + b->marginRight;
|
||||
height -= b->marginTop + b->marginBottom;
|
||||
uiControlResize(b->mainControl, x, y, width, height, d);
|
||||
binWidget = GTK_WIDGET(uiControlHandle(uiControl(b)));
|
||||
oldparent = gtk_widget_get_parent(binWidget);
|
||||
gtk_container_remove(GTK_CONTAINER(oldparent), binWidget);
|
||||
}
|
||||
|
||||
uiContainer *newBin(void)
|
||||
void binResizeRootAndUpdate(uiBin *b, intmax_t x, intmax_t y, intmax_t width, intmax_t height)
|
||||
{
|
||||
struct bin *b;
|
||||
|
||||
b = uiNew(struct bin);
|
||||
|
||||
uiMakeContainer(uiContainer(b));
|
||||
|
||||
b->baseDestroy = uiControl(b)->Destroy;
|
||||
uiControl(b)->Destroy = binDestroy;
|
||||
uiControl(b)->PreferredSize = binPreferredSize;
|
||||
|
||||
uiContainer(b)->ResizeChildren = binResizeChildren;
|
||||
|
||||
return uiContainer(b);
|
||||
// not used on GTK+
|
||||
}
|
||||
|
||||
void binSetMainControl(uiContainer *c, uiControl *mainControl)
|
||||
void binTranslateMargins(uiBin *b, intmax_t *left, intmax_t *top, intmax_t *right, intmax_t *bottom, uiSizing *d)
|
||||
{
|
||||
struct bin *b = (struct bin *) c;
|
||||
|
||||
if (b->mainControl != NULL)
|
||||
uiControlSetParent(b->mainControl, NULL);
|
||||
b->mainControl = mainControl;
|
||||
if (b->mainControl != NULL)
|
||||
uiControlSetParent(b->mainControl, uiContainer(b));
|
||||
uiContainerUpdate(uiContainer(b));
|
||||
}
|
||||
|
||||
void binSetMargins(uiContainer *c, intmax_t left, intmax_t top, intmax_t right, intmax_t bottom)
|
||||
{
|
||||
struct bin *b = (struct bin *) c;
|
||||
|
||||
b->marginLeft = left;
|
||||
b->marginRight = right;
|
||||
b->marginTop = top;
|
||||
b->marginBottom = bottom;
|
||||
uiContainerUpdate(uiContainer(b));
|
||||
}
|
||||
|
||||
void binSetParent(uiContainer *c, uintptr_t osParent)
|
||||
{
|
||||
struct bin *b = (struct bin *) c;
|
||||
GtkWidget *widget;
|
||||
GtkContainer *newContainer, *oldContainer;
|
||||
|
||||
widget = GTK_WIDGET(uiControlHandle(uiControl(b)));
|
||||
if (osParent == 0) {
|
||||
oldContainer = GTK_CONTAINER(gtk_widget_get_parent(widget));
|
||||
gtk_container_remove(oldContainer, widget);
|
||||
return;
|
||||
}
|
||||
newContainer = GTK_CONTAINER(osParent);
|
||||
gtk_container_add(newContainer, widget);
|
||||
// not used on GTK+
|
||||
}
|
||||
|
|
24
unix/tab.c
24
unix/tab.c
|
@ -10,7 +10,8 @@ struct tab {
|
|||
};
|
||||
|
||||
struct tabPage {
|
||||
uiContainer *bin;
|
||||
uiBin *bin;
|
||||
// TODO remove the need for this
|
||||
GtkWidget *binWidget;
|
||||
int margined;
|
||||
};
|
||||
|
@ -27,8 +28,7 @@ static void onDestroy(void *data)
|
|||
// we need to remove them from the tab first; see below
|
||||
for (i = 0; i < t->pages->len; i++) {
|
||||
p = &g_array_index(t->pages, struct tabPage, i);
|
||||
// this does the job of binSetParent()
|
||||
gtk_container_remove(t->container, p->binWidget);
|
||||
uiBinRemoveOSParent(p->bin);
|
||||
uiControlDestroy(uiControl(p->bin));
|
||||
}
|
||||
// then free ourselves
|
||||
|
@ -52,9 +52,9 @@ static void tabAppendPage(uiTab *tt, const char *name, uiControl *child)
|
|||
struct tabPage p;
|
||||
|
||||
p.bin = newBin();
|
||||
binSetMainControl(p.bin, child);
|
||||
uiBinSetMainControl(p.bin, child);
|
||||
// and add it as a tab page
|
||||
binSetParent(p.bin, (uintptr_t) (t->container));
|
||||
uiBinSetOSParent(p.bin, (uintptr_t) (t->container));
|
||||
p.binWidget = GTK_WIDGET(uiControlHandle(uiControl(p.bin)));
|
||||
gtk_notebook_set_tab_label_text(t->notebook, p.binWidget, name);
|
||||
|
||||
|
@ -67,9 +67,9 @@ static void tabInsertPageBefore(uiTab *tt, const char *name, uintmax_t n, uiCont
|
|||
struct tabPage p;
|
||||
|
||||
p.bin = newBin();
|
||||
binSetMainControl(p.bin, child);
|
||||
uiBinSetMainControl(p.bin, child);
|
||||
// and add it as a tab page
|
||||
binSetParent(p.bin, (uintptr_t) (t->container));
|
||||
uiBinSetOSParent(p.bin, (uintptr_t) (t->container));
|
||||
p.binWidget = GTK_WIDGET(uiControlHandle(uiControl(p.bin)));
|
||||
gtk_notebook_set_tab_label_text(t->notebook, p.binWidget, name);
|
||||
|
||||
|
@ -85,15 +85,15 @@ static void tabDeletePage(uiTab *tt, uintmax_t n)
|
|||
p = &g_array_index(t->pages, struct tabPage, n);
|
||||
|
||||
// make sure the page's control isn't destroyed
|
||||
binSetMainControl(p->bin, NULL);
|
||||
uiBinSetMainControl(p->bin, NULL);
|
||||
|
||||
// now destroy the page
|
||||
// this will also remove the tab
|
||||
// why? simple: both gtk_notebook_remove_tab() and gtk_widget_destroy() call gtk_container_remove()
|
||||
// we need to remove them from the tab first, though, otherwise they won't really be destroyed properly
|
||||
// (the GtkNotebook will still have the tab in it because its reference ISN'T destroyed, and we crash resizing a bin that no longer exists
|
||||
// this also does the job of binSetParent()
|
||||
gtk_container_remove(t->container, p->binWidget);
|
||||
// TODO redo this comment
|
||||
uiBinRemoveOSParent(p->bin);
|
||||
uiControlDestroy(uiControl(p->bin));
|
||||
|
||||
g_array_remove_index(t->pages, n);
|
||||
|
@ -123,9 +123,9 @@ static void tabSetMargined(uiTab *tt, uintmax_t n, int margined)
|
|||
p = &g_array_index(t->pages, struct tabPage, n);
|
||||
p->margined = margined;
|
||||
if (p->margined)
|
||||
binSetMargins(p->bin, gtkXMargin, gtkYMargin, gtkXMargin, gtkYMargin);
|
||||
uiBinSetMargins(p->bin, gtkXMargin, gtkYMargin, gtkXMargin, gtkYMargin);
|
||||
else
|
||||
binSetMargins(p->bin, 0, 0, 0, 0);
|
||||
uiBinSetMargins(p->bin, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
uiTab *uiNewTab(void)
|
||||
|
|
|
@ -14,7 +14,7 @@ struct window {
|
|||
|
||||
GtkWidget *menubar;
|
||||
|
||||
uiContainer *bin;
|
||||
uiBin *bin;
|
||||
|
||||
int hidden;
|
||||
|
||||
|
@ -47,7 +47,7 @@ static void windowDestroy(uiControl *c)
|
|||
gtk_widget_hide(w->widget);
|
||||
// now destroy the bin
|
||||
// we need to remove the bin from its parent first
|
||||
binSetParent(w->bin, 0);
|
||||
uiBinRemoveOSParent(w->bin);
|
||||
uiControlDestroy(uiControl(w->bin));
|
||||
// now destroy the menus, if any
|
||||
if (w->menubar != NULL)
|
||||
|
@ -146,7 +146,7 @@ static void windowSetChild(uiWindow *ww, uiControl *child)
|
|||
{
|
||||
struct window *w = (struct window *) ww;
|
||||
|
||||
binSetMainControl(w->bin, child);
|
||||
uiBinSetMainControl(w->bin, child);
|
||||
}
|
||||
|
||||
static int windowMargined(uiWindow *ww)
|
||||
|
@ -162,9 +162,9 @@ static void windowSetMargined(uiWindow *ww, int margined)
|
|||
|
||||
w->margined = margined;
|
||||
if (w->margined)
|
||||
binSetMargins(w->bin, gtkXMargin, gtkYMargin, gtkXMargin, gtkYMargin);
|
||||
uiBinSetMargins(w->bin, gtkXMargin, gtkYMargin, gtkXMargin, gtkYMargin);
|
||||
else
|
||||
binSetMargins(w->bin, 0, 0, 0, 0);
|
||||
uiBinSetMargins(w->bin, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar)
|
||||
|
@ -199,7 +199,7 @@ uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar)
|
|||
gtk_widget_set_halign(binWidget, GTK_ALIGN_FILL);
|
||||
gtk_widget_set_vexpand(binWidget, TRUE);
|
||||
gtk_widget_set_valign(binWidget, GTK_ALIGN_FILL);
|
||||
binSetParent(w->bin, (uintptr_t) (w->vboxContainer));
|
||||
uiBinSetOSParent(w->bin, (uintptr_t) (w->vboxContainer));
|
||||
|
||||
// show everything in the vbox, but not the GtkWindow itself
|
||||
gtk_widget_show_all(w->vboxWidget);
|
||||
|
|
Loading…
Reference in New Issue