From 89445cabfcd4d19b151760ea91c83c94c75d4784 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Thu, 2 Jul 2015 02:11:42 -0400 Subject: [PATCH] Started to bring back the shared uiBox implementation. Need to figure out why the child clip area is 0x0... --- redo/unix/GNUmakeinc.mk | 1 + redo/unix/container.c | 146 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 redo/unix/container.c diff --git a/redo/unix/GNUmakeinc.mk b/redo/unix/GNUmakeinc.mk index 06908b7b..57f6ca62 100644 --- a/redo/unix/GNUmakeinc.mk +++ b/redo/unix/GNUmakeinc.mk @@ -6,6 +6,7 @@ osCFILES = \ unix/button.c \ unix/checkbox.c \ unix/combobox.c \ + unix/container.c \ unix/control.c \ unix/datetimepicker.c \ unix/entry.c \ diff --git a/redo/unix/container.c b/redo/unix/container.c new file mode 100644 index 00000000..892a4bf7 --- /dev/null +++ b/redo/unix/container.c @@ -0,0 +1,146 @@ +// 28 april 2015 +#include "uipriv_unix.h" + +#define containerWidgetType (containerWidget_get_type()) +#define containerWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), containerWidgetType, containerWidget)) +#define IscontainerWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), containerWidgetType)) +#define containerWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), containerWidgetType, containerWidgetClass)) +#define IscontainerWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), containerWidget)) +#define GetcontainerWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), containerWidgetType, containerWidgetClass)) + +typedef struct containerWidget containerWidget; +typedef struct containerWidgetClass containerWidgetClass; + +struct containerWidget { + GtkContainer parent_instance; + uiControl *c; + GPtrArray *widgets; // for for_each()/for_all() +}; + +struct containerWidgetClass { + GtkContainerClass parent_class; +}; + +G_DEFINE_TYPE(containerWidget, containerWidget, GTK_TYPE_CONTAINER) + +static void containerWidget_init(containerWidget *c) +{ + c->widgets = g_ptr_array_new(); + gtk_widget_set_has_window(GTK_WIDGET(c), FALSE); +} + +static void containerWidget_dispose(GObject *obj) +{ + G_OBJECT_CLASS(containerWidget_parent_class)->dispose(obj); +} + +static void containerWidget_finalize(GObject *obj) +{ + containerWidget *c = containerWidget(obj); + + g_ptr_array_unref(c->widgets); + G_OBJECT_CLASS(containerWidget_parent_class)->finalize(obj); +} + +static void containerWidget_add(GtkContainer *container, GtkWidget *widget) +{ + containerWidget *c = containerWidget(container); + + gtk_widget_set_parent(widget, GTK_WIDGET(c)); + g_ptr_array_add(c->widgets, widget); +} + +static void containerWidget_remove(GtkContainer *container, GtkWidget *widget) +{ + containerWidget *c = containerWidget(container); + + gtk_widget_unparent(widget); + if (g_ptr_array_remove(c->widgets, widget) == FALSE) + complain("widget %p not found in containerWidget gtk_container_remove()", widget); +} + +static void containerWidget_size_allocate(GtkWidget *widget, GtkAllocation *allocation) +{ + containerWidget *c = containerWidget(widget); + uiSizing *d; + intmax_t x, y, width, height; + + gtk_widget_set_allocation(GTK_WIDGET(c), allocation); + x = allocation->x; + y = allocation->y; + width = allocation->width; + height = allocation->height; + d = uiUnixNewSizing(); + uiControlResize(c->c, x, y, width, height, d); + uiFreeSizing(d); +} + +static void containerWidget_get_preferred_height(GtkWidget *widget, gint *minimum, gint *natural) +{ + containerWidget *c = containerWidget(widget); + intmax_t width, height; + uiSizing *d; + + d = uiUnixNewSizing(); + uiControlPreferredSize(uiControl(c->c), d, &width, &height); + uiFreeSizing(d); + *minimum = 0; // allow arbitrary resize + *natural = height; +} + +static void containerWidget_get_preferred_width(GtkWidget *widget, gint *minimum, gint *natural) +{ + containerWidget *c = containerWidget(widget); + intmax_t width, height; + uiSizing *d; + + d = uiUnixNewSizing(); + uiControlPreferredSize(uiControl(c->c), d, &width, &height); + uiFreeSizing(d); + *minimum = 0; // allow arbitrary resize + *natural = width; +} + +struct forall { + GtkCallback callback; + gpointer data; +}; + +static void doforall(gpointer obj, gpointer data) +{ + struct forall *s = (struct forall *) data; + + (*(s->callback))(GTK_WIDGET(obj), s->data); +} + +static void containerWidget_forall(GtkContainer *container, gboolean includeInternals, GtkCallback callback, gpointer data) +{ + containerWidget *c = containerWidget(container); + struct forall s; + + s.callback = callback; + s.data = data; + g_ptr_array_foreach(c->widgets, doforall, &s); +} + +static void containerWidget_class_init(containerWidgetClass *class) +{ + G_OBJECT_CLASS(class)->dispose = containerWidget_dispose; + G_OBJECT_CLASS(class)->finalize = containerWidget_finalize; + GTK_WIDGET_CLASS(class)->size_allocate = containerWidget_size_allocate; + GTK_WIDGET_CLASS(class)->get_preferred_height = containerWidget_get_preferred_height; + GTK_WIDGET_CLASS(class)->get_preferred_width = containerWidget_get_preferred_width; + GTK_CONTAINER_CLASS(class)->add = containerWidget_add; + GTK_CONTAINER_CLASS(class)->remove = containerWidget_remove; + GTK_CONTAINER_CLASS(class)->forall = containerWidget_forall; +} + +uintptr_t uiMakeContainer(uiControl *c) +{ + GtkWidget *widget; + + widget = GTK_WIDGET(g_object_new(containerWidgetType, NULL)); + uiUnixMakeSingleWidgetControl(c, widget); + containerWidget(widget)->c = c; + return (uintptr_t) widget; +}