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
|
// 28 april 2015
|
||||||
#include "uipriv_unix.h"
|
#include "uipriv_unix.h"
|
||||||
|
|
||||||
struct bin {
|
int binHasOSParent(uiBin *b)
|
||||||
uiContainer c;
|
|
||||||
void (*baseDestroy)(uiControl *);
|
|
||||||
uiControl *mainControl;
|
|
||||||
intmax_t marginLeft;
|
|
||||||
intmax_t marginTop;
|
|
||||||
intmax_t marginRight;
|
|
||||||
intmax_t marginBottom;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void binDestroy(uiControl *c)
|
|
||||||
{
|
{
|
||||||
struct bin *b = (struct bin *) c;
|
|
||||||
GtkWidget *binWidget;
|
GtkWidget *binWidget;
|
||||||
|
|
||||||
// ensure clean removal by making sure the bin has no OS parent
|
|
||||||
binWidget = GTK_WIDGET(uiControlHandle(uiControl(b)));
|
binWidget = GTK_WIDGET(uiControlHandle(uiControl(b)));
|
||||||
if (gtk_widget_get_parent(binWidget) != NULL)
|
return 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
GtkWidget *binWidget;
|
||||||
intmax_t marginX, marginY;
|
|
||||||
|
|
||||||
if (b->mainControl == NULL) {
|
binWidget = GTK_WIDGET(uiControlHandle(uiControl(b)));
|
||||||
*width = 0;
|
gtk_container_add(GTK_CONTAINER(osParent), binWidget);
|
||||||
*height = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uiControlPreferredSize(b->mainControl, d, width, height);
|
|
||||||
marginX = b->marginLeft + b->marginRight;
|
|
||||||
marginY = b->marginTop + b->marginBottom;
|
|
||||||
*width += marginX;
|
|
||||||
*height += marginY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
binWidget = GTK_WIDGET(uiControlHandle(uiControl(b)));
|
||||||
return;
|
oldparent = gtk_widget_get_parent(binWidget);
|
||||||
x += b->marginLeft;
|
gtk_container_remove(GTK_CONTAINER(oldparent), binWidget);
|
||||||
y += b->marginTop;
|
|
||||||
width -= b->marginLeft + b->marginRight;
|
|
||||||
height -= b->marginTop + b->marginBottom;
|
|
||||||
uiControlResize(b->mainControl, x, y, width, height, d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uiContainer *newBin(void)
|
void binResizeRootAndUpdate(uiBin *b, intmax_t x, intmax_t y, intmax_t width, intmax_t height)
|
||||||
{
|
{
|
||||||
struct bin *b;
|
// not used on GTK+
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
// not used on GTK+
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
24
unix/tab.c
24
unix/tab.c
|
@ -10,7 +10,8 @@ struct tab {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tabPage {
|
struct tabPage {
|
||||||
uiContainer *bin;
|
uiBin *bin;
|
||||||
|
// TODO remove the need for this
|
||||||
GtkWidget *binWidget;
|
GtkWidget *binWidget;
|
||||||
int margined;
|
int margined;
|
||||||
};
|
};
|
||||||
|
@ -27,8 +28,7 @@ static void onDestroy(void *data)
|
||||||
// we need to remove them from the tab first; see below
|
// we need to remove them from the tab first; see below
|
||||||
for (i = 0; i < t->pages->len; i++) {
|
for (i = 0; i < t->pages->len; i++) {
|
||||||
p = &g_array_index(t->pages, struct tabPage, i);
|
p = &g_array_index(t->pages, struct tabPage, i);
|
||||||
// this does the job of binSetParent()
|
uiBinRemoveOSParent(p->bin);
|
||||||
gtk_container_remove(t->container, p->binWidget);
|
|
||||||
uiControlDestroy(uiControl(p->bin));
|
uiControlDestroy(uiControl(p->bin));
|
||||||
}
|
}
|
||||||
// then free ourselves
|
// then free ourselves
|
||||||
|
@ -52,9 +52,9 @@ static void tabAppendPage(uiTab *tt, const char *name, uiControl *child)
|
||||||
struct tabPage p;
|
struct tabPage p;
|
||||||
|
|
||||||
p.bin = newBin();
|
p.bin = newBin();
|
||||||
binSetMainControl(p.bin, child);
|
uiBinSetMainControl(p.bin, child);
|
||||||
// and add it as a tab page
|
// 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)));
|
p.binWidget = GTK_WIDGET(uiControlHandle(uiControl(p.bin)));
|
||||||
gtk_notebook_set_tab_label_text(t->notebook, p.binWidget, name);
|
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;
|
struct tabPage p;
|
||||||
|
|
||||||
p.bin = newBin();
|
p.bin = newBin();
|
||||||
binSetMainControl(p.bin, child);
|
uiBinSetMainControl(p.bin, child);
|
||||||
// and add it as a tab page
|
// 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)));
|
p.binWidget = GTK_WIDGET(uiControlHandle(uiControl(p.bin)));
|
||||||
gtk_notebook_set_tab_label_text(t->notebook, p.binWidget, name);
|
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);
|
p = &g_array_index(t->pages, struct tabPage, n);
|
||||||
|
|
||||||
// make sure the page's control isn't destroyed
|
// make sure the page's control isn't destroyed
|
||||||
binSetMainControl(p->bin, NULL);
|
uiBinSetMainControl(p->bin, NULL);
|
||||||
|
|
||||||
// now destroy the page
|
// now destroy the page
|
||||||
// this will also remove the tab
|
// this will also remove the tab
|
||||||
// why? simple: both gtk_notebook_remove_tab() and gtk_widget_destroy() call gtk_container_remove()
|
// 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
|
// 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
|
// (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()
|
// TODO redo this comment
|
||||||
gtk_container_remove(t->container, p->binWidget);
|
uiBinRemoveOSParent(p->bin);
|
||||||
uiControlDestroy(uiControl(p->bin));
|
uiControlDestroy(uiControl(p->bin));
|
||||||
|
|
||||||
g_array_remove_index(t->pages, n);
|
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 = &g_array_index(t->pages, struct tabPage, n);
|
||||||
p->margined = margined;
|
p->margined = margined;
|
||||||
if (p->margined)
|
if (p->margined)
|
||||||
binSetMargins(p->bin, gtkXMargin, gtkYMargin, gtkXMargin, gtkYMargin);
|
uiBinSetMargins(p->bin, gtkXMargin, gtkYMargin, gtkXMargin, gtkYMargin);
|
||||||
else
|
else
|
||||||
binSetMargins(p->bin, 0, 0, 0, 0);
|
uiBinSetMargins(p->bin, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uiTab *uiNewTab(void)
|
uiTab *uiNewTab(void)
|
||||||
|
|
|
@ -14,7 +14,7 @@ struct window {
|
||||||
|
|
||||||
GtkWidget *menubar;
|
GtkWidget *menubar;
|
||||||
|
|
||||||
uiContainer *bin;
|
uiBin *bin;
|
||||||
|
|
||||||
int hidden;
|
int hidden;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ static void windowDestroy(uiControl *c)
|
||||||
gtk_widget_hide(w->widget);
|
gtk_widget_hide(w->widget);
|
||||||
// now destroy the bin
|
// now destroy the bin
|
||||||
// we need to remove the bin from its parent first
|
// we need to remove the bin from its parent first
|
||||||
binSetParent(w->bin, 0);
|
uiBinRemoveOSParent(w->bin);
|
||||||
uiControlDestroy(uiControl(w->bin));
|
uiControlDestroy(uiControl(w->bin));
|
||||||
// now destroy the menus, if any
|
// now destroy the menus, if any
|
||||||
if (w->menubar != NULL)
|
if (w->menubar != NULL)
|
||||||
|
@ -146,7 +146,7 @@ static void windowSetChild(uiWindow *ww, uiControl *child)
|
||||||
{
|
{
|
||||||
struct window *w = (struct window *) ww;
|
struct window *w = (struct window *) ww;
|
||||||
|
|
||||||
binSetMainControl(w->bin, child);
|
uiBinSetMainControl(w->bin, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int windowMargined(uiWindow *ww)
|
static int windowMargined(uiWindow *ww)
|
||||||
|
@ -162,9 +162,9 @@ static void windowSetMargined(uiWindow *ww, int margined)
|
||||||
|
|
||||||
w->margined = margined;
|
w->margined = margined;
|
||||||
if (w->margined)
|
if (w->margined)
|
||||||
binSetMargins(w->bin, gtkXMargin, gtkYMargin, gtkXMargin, gtkYMargin);
|
uiBinSetMargins(w->bin, gtkXMargin, gtkYMargin, gtkXMargin, gtkYMargin);
|
||||||
else
|
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)
|
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_halign(binWidget, GTK_ALIGN_FILL);
|
||||||
gtk_widget_set_vexpand(binWidget, TRUE);
|
gtk_widget_set_vexpand(binWidget, TRUE);
|
||||||
gtk_widget_set_valign(binWidget, GTK_ALIGN_FILL);
|
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
|
// show everything in the vbox, but not the GtkWindow itself
|
||||||
gtk_widget_show_all(w->vboxWidget);
|
gtk_widget_show_all(w->vboxWidget);
|
||||||
|
|
Loading…
Reference in New Issue