aboutsummaryrefslogtreecommitdiff
path: root/src/libui_sdl/libui/unix/grid.c
blob: 6d9813b35d922a919fdd0eda166045a6a69b7eaa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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;
}