142 lines
3.5 KiB
C
142 lines
3.5 KiB
C
|
// 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, uiprivGTKYPadding);
|
||
|
gtk_grid_set_column_spacing(g->grid, uiprivGTKXPadding);
|
||
|
} 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;
|
||
|
}
|