Added a bin type to the GTK+ backend to handle uiWindow parenting and uiWindow/uiTab margins.

This commit is contained in:
Pietro Gagliardi 2015-06-30 22:30:00 -04:00
parent 8e89f60330
commit dc617bcfe2
4 changed files with 101 additions and 15 deletions

View File

@ -2,6 +2,7 @@
osCFILES = \
unix/alloc.c \
unix/bin.c \
unix/box.c \
unix/button.c \
unix/checkbox.c \

82
redo/unix/bin.c Normal file
View File

@ -0,0 +1,82 @@
// 30 june 2015
#include "uipriv_unix.h"
// This is a uiControl wrapper a la GtkBin.
// It serves the function of tabPage on Windows: it allows uiWindow and uiTab to give their children a real uiControl as a parent while not screwing with the internal GtkWidget structure of those uiControls.
// It also provides margins.
struct bin {
uiControl c;
GtkWidget *widget;
GtkContainer *container;
GtkBox *box; // GtkBin is abstract and none of the implementations seem adequate (GtkFrame is the closest but eh)
uiControl *child;
int margined;
};
uiDefineControlType(bin, binType, struct bin)
static uintptr_t binHandle(uiControl *c)
{
struct bin *b = (struct bin *) c;
return (uintptr_t) (b->widget);
}
uiControl *newBin(void)
{
struct bin *b;
b = (struct bin *) uiNewControl(binType());
b->widget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
b->container = GTK_CONTAINER(b->widget);
b->box = GTK_BOX(b->widget);
uiUnixMakeSingleWidgetControl(uiControl(b), b->widget);
// a uiBox is theoretically used in a context where this shouldn't be necessary but because of uiWindow we'll do it anyway
gtk_widget_set_hexpand(b->widget, TRUE);
gtk_widget_set_halign(b->widget, GTK_ALIGN_FILL);
gtk_widget_set_vexpand(b->widget, TRUE);
gtk_widget_set_valign(b->widget, GTK_ALIGN_FILL);
uiControl(b)->Handle = binHandle;
return uiControl(b);
}
void binSetChild(uiControl *c, uiControl *child)
{
struct bin *b = (struct bin *) c;
GtkWidget *childWidget;
if (b->child != NULL)
uiControlSetParent(b->child, NULL);
b->child = child;
if (b->child != NULL) {
uiControlSetParent(b->child, uiControl(b));
childWidget = GTK_WIDGET(uiControlHandle(b->child));
gtk_widget_set_hexpand(childWidget, TRUE);
gtk_widget_set_halign(childWidget, GTK_ALIGN_FILL);
gtk_widget_set_vexpand(childWidget, TRUE);
gtk_widget_set_valign(childWidget, GTK_ALIGN_FILL);
}
}
int binMargined(uiControl *c)
{
struct bin *b = (struct bin *) c;
return b->margined;
}
void binSetMargined(uiControl *c, int margined)
{
struct bin *b = (struct bin *) c;
b->margined = margined;
if (b->margined)
gtk_container_set_border_width(b->container, gtkXMargin);
else
gtk_container_set_border_width(b->container, 0);
}

View File

@ -22,5 +22,11 @@ extern void uninitMenus(void);
extern void initAlloc(void);
extern void uninitAlloc(void);
// bin.c
extern uiControl *newBin(void);
extern void binSetChild(uiControl *, uiControl *);
extern int binMargined(uiControl *);
extern void binSetMargined(uiControl *, int);
// TODO
#define PUT_CODE_HERE 0

View File

@ -16,11 +16,11 @@ struct window {
GtkWidget *menubar;
uiControl *bin;
uiControl *child;
int (*onClosing)(uiWindow *, void *);
void *onClosingData;
int margined;
void (*baseCommitDestroy)(uiControl *c);
};
@ -49,8 +49,10 @@ static void windowCommitDestroy(uiControl *c)
// first hide ourselves
gtk_widget_hide(w->widget);
// now destroy the child
uiControlSetParent(w->child, NULL);
binSetChild(w->bin, NULL);
uiControlDestroy(w->child);
// and destroy the bin
uiControlDestroy(w->bin);
// now destroy the menus, if any
if (w->menubar != NULL)
freeMenubar(w->menubar);
@ -112,32 +114,24 @@ static void windowSetChild(uiWindow *ww, uiControl *child)
struct window *w = (struct window *) ww;
if (w->child != NULL)
uiControlSetParent(w->child, NULL);
binSetChild(w->bin, NULL);
w->child = child;
if (w->child != NULL) {
//TODO uiControlSetParent(w->child, w->child);
gtk_widget_set_hexpand(GTK_WIDGET(uiControlHandle(w->child)), TRUE);
gtk_widget_set_halign(GTK_WIDGET(uiControlHandle(w->child)), GTK_ALIGN_FILL);
gtk_widget_set_vexpand(GTK_WIDGET(uiControlHandle(w->child)), TRUE);
gtk_widget_set_valign(GTK_WIDGET(uiControlHandle(w->child)), GTK_ALIGN_FILL);
gtk_container_add(w->vboxContainer, GTK_WIDGET(uiControlHandle(w->child)));
uiControlQueueResize(w->child);
}
if (w->child != NULL)
binSetChild(w->bin, w->child);
}
static int windowMargined(uiWindow *ww)
{
struct window *w = (struct window *) ww;
return w->margined;
return binMargined(w->bin);
}
static void windowSetMargined(uiWindow *ww, int margined)
{
struct window *w = (struct window *) ww;
w->margined = margined;
// TODO
binSetMargined(w->bin, margined);
uiControlQueueResize(uiControl(w));
}
@ -178,6 +172,9 @@ uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar)
gtk_container_add(w->vboxContainer, w->menubar);
}
w->bin = newBin();
gtk_container_add(w->vboxContainer, GTK_WIDGET(uiControlHandle(w->bin)));
// show everything in the vbox, but not the GtkWindow itself
gtk_widget_show_all(w->vboxWidget);