diff options
Diffstat (limited to 'src/libui_sdl/libui/unix/grid.c')
-rw-r--r-- | src/libui_sdl/libui/unix/grid.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/libui_sdl/libui/unix/grid.c b/src/libui_sdl/libui/unix/grid.c new file mode 100644 index 0000000..6d9813b --- /dev/null +++ b/src/libui_sdl/libui/unix/grid.c @@ -0,0 +1,141 @@ +// 9 june 2016 +#include "uipriv_unix.h" + +struct gridChild { + uiControl *c; + GtkWidget *label; + gboolean oldhexpand; + GtkAlign oldhalign; + gboolean oldvexpand; + GtkAlign oldvalign; +}; + +struct uiGrid { + uiUnixControl c; + GtkWidget *widget; + GtkContainer *container; + GtkGrid *grid; + GArray *children; + int padded; +}; + +uiUnixControlAllDefaultsExceptDestroy(uiGrid) + +#define ctrl(g, i) &g_array_index(g->children, struct gridChild, i) + +static void uiGridDestroy(uiControl *c) +{ + uiGrid *g = uiGrid(c); + struct gridChild *gc; + guint i; + + // free all controls + for (i = 0; i < g->children->len; i++) { + gc = ctrl(g, i); + uiControlSetParent(gc->c, NULL); + uiUnixControlSetContainer(uiUnixControl(gc->c), g->container, TRUE); + uiControlDestroy(gc->c); + } + g_array_free(g->children, TRUE); + // and then ourselves + g_object_unref(g->widget); + uiFreeControl(uiControl(g)); +} + +#define TODO_MASSIVE_HACK(c) \ + if (!uiUnixControl(c)->addedBefore) { \ + g_object_ref_sink(GTK_WIDGET(uiControlHandle(uiControl(c)))); \ + gtk_widget_show(GTK_WIDGET(uiControlHandle(uiControl(c)))); \ + uiUnixControl(c)->addedBefore = TRUE; \ + } + +static const GtkAlign gtkAligns[] = { + [uiAlignFill] = GTK_ALIGN_FILL, + [uiAlignStart] = GTK_ALIGN_START, + [uiAlignCenter] = GTK_ALIGN_CENTER, + [uiAlignEnd] = GTK_ALIGN_END, +}; + +static const GtkPositionType gtkPositions[] = { + [uiAtLeading] = GTK_POS_LEFT, + [uiAtTop] = GTK_POS_TOP, + [uiAtTrailing] = GTK_POS_RIGHT, + [uiAtBottom] = GTK_POS_BOTTOM, +}; + +static GtkWidget *prepare(struct gridChild *gc, uiControl *c, int hexpand, uiAlign halign, int vexpand, uiAlign valign) +{ + GtkWidget *widget; + + gc->c = c; + widget = GTK_WIDGET(uiControlHandle(gc->c)); + gc->oldhexpand = gtk_widget_get_hexpand(widget); + gc->oldhalign = gtk_widget_get_halign(widget); + gc->oldvexpand = gtk_widget_get_vexpand(widget); + gc->oldvalign = gtk_widget_get_valign(widget); + gtk_widget_set_hexpand(widget, hexpand != 0); + gtk_widget_set_halign(widget, gtkAligns[halign]); + gtk_widget_set_vexpand(widget, vexpand != 0); + gtk_widget_set_valign(widget, gtkAligns[valign]); + return widget; +} + +void uiGridAppend(uiGrid *g, uiControl *c, int left, int top, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign) +{ + struct gridChild gc; + GtkWidget *widget; + + widget = prepare(&gc, c, hexpand, halign, vexpand, valign); + uiControlSetParent(gc.c, uiControl(g)); + TODO_MASSIVE_HACK(uiUnixControl(gc.c)); + gtk_grid_attach(g->grid, widget, + left, top, + xspan, yspan); + g_array_append_val(g->children, gc); +} + +void uiGridInsertAt(uiGrid *g, uiControl *c, uiControl *existing, uiAt at, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign) +{ + struct gridChild gc; + GtkWidget *widget; + + widget = prepare(&gc, c, hexpand, halign, vexpand, valign); + uiControlSetParent(gc.c, uiControl(g)); + TODO_MASSIVE_HACK(uiUnixControl(gc.c)); + gtk_grid_attach_next_to(g->grid, widget, + GTK_WIDGET(uiControlHandle(existing)), gtkPositions[at], + xspan, yspan); + g_array_append_val(g->children, gc); +} + +int uiGridPadded(uiGrid *g) +{ + return g->padded; +} + +void uiGridSetPadded(uiGrid *g, int padded) +{ + g->padded = padded; + if (g->padded) { + gtk_grid_set_row_spacing(g->grid, gtkYPadding); + gtk_grid_set_column_spacing(g->grid, gtkXPadding); + } else { + gtk_grid_set_row_spacing(g->grid, 0); + gtk_grid_set_column_spacing(g->grid, 0); + } +} + +uiGrid *uiNewGrid(void) +{ + uiGrid *g; + + uiUnixNewControl(uiGrid, g); + + g->widget = gtk_grid_new(); + g->container = GTK_CONTAINER(g->widget); + g->grid = GTK_GRID(g->widget); + + g->children = g_array_new(FALSE, TRUE, sizeof (struct gridChild)); + + return g; +} |