From 19b85182b83e1eb6d8b91209594adb2f405a19bf Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Mon, 13 Apr 2015 12:05:14 -0400 Subject: Did the GTK+ conversion to uiParent. Now to build. --- new/parent_unix.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 new/parent_unix.c (limited to 'new/parent_unix.c') diff --git a/new/parent_unix.c b/new/parent_unix.c new file mode 100644 index 0000000..f9c8db1 --- /dev/null +++ b/new/parent_unix.c @@ -0,0 +1,183 @@ +// 13 august 2014 +#include "uipriv_unix.h" + +#define uipParentType (uipParent_get_type()) +#define uipParent(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), uipParentType, uipParent)) +#define uipIsParent(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), uipParentType)) +#define uipParentClass(class) (G_TYPE_CHECK_CLASS_CAST((class), uipParentType, uipParentClass)) +#define uipIsParentClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), uipParent)) +#define uipGetParentClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), uipParentType, uipParentClass)) + +typedef struct uipParent uipParent; +typedef struct uipParentClass uipParentClass; + +struct uipParent { + GtkContainer parent_instance; + // this is what triggers the resizing of all the children + uiControl *child; + // these are the actual children widgets of the container as far as GTK+ is concerned + GPtrArray *children; // for forall() + intmax_t marginLeft; + intmax_t marginTop; + intmax_t marginRight; + intmax_t marginBottom; +}; + +struct uipParentClass { + GtkContainerClass parent_class; +}; + +G_DEFINE_TYPE(uipParent, uipParent, GTK_TYPE_CONTAINER) + +static void uipParent_init(uipParent *p) +{ + if (options.debugLogAllocations) + fprintf(stderr, "%p alloc uipParent\n", p); + p->children = g_ptr_array_new(); + gtk_widget_set_has_window(GTK_WIDGET(c), FALSE); +} + +// instead of having GtkContainer itself unref all our controls, we'll run our own uiControlDestroy() functions for child, which will do that and more +// we still chain up because we need to, but by that point there will be no children for GtkContainer to free +static void uipParent_dispose(GObject *obj) +{ + uipParent *p = uipParent(obj); + + if (p->children != NULL) { + g_ptr_array_unref(c->children); + p->children = NULL; + } + if (p->child != NULL) { + uiControlDestroy(c->child); + p->child = NULL; + } + G_OBJECT_CLASS(uipParent_parent_class)->dispose(obj); +} + +static void uipParent_finalize(GObject *obj) +{ + G_OBJECT_CLASS(uipParent_parent_class)->finalize(obj); + if (options.debugLogAllocations) + fprintf(stderr, "%p free\n", obj); +} + +static void uipParent_add(GtkContainer *container, GtkWidget *widget) +{ + uipParent *p = uipParent(container); + + gtk_widget_set_parent(widget, GTK_WIDGET(c)); + if (p->children != NULL) + g_ptr_array_add(p->children, widget); +} + +static void uipParent_remove(GtkContainer *container, GtkWidget *widget) +{ + uipParent *p = uipParent(container); + + gtk_widget_unparent(widget); + if (p->children != NULL) + g_ptr_array_remove(p->children, widget); +} + +#define gtkXPadding 12 +#define gtkYPadding 6 + +static void uipParent_size_allocate(GtkWidget *widget, GtkAllocation *allocation) +{ + uipParent *p = uipParent(widget); + uiSizing d; + intmax_t x, y, width, height; + + gtk_widget_set_allocation(GTK_WIDGET(c), allocation); + if (c->child == NULL) + return; + x = allocation->x + p->marginLeft; + y = allocation->y + p->marginTop; + width = allocation->width - (p->marginLeft + p->marginRight); + height = allocation->height - (p->marginTop + p->marginBottom); + d.xPadding = gtkXPadding; + d.yPadding = gtkYPadding; + uiControlResize(c->child, x, y, width, height, &d); +} + +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 uipParent_forall(GtkContainer *container, gboolean includeInternals, GtkCallback callback, gpointer data) +{ + uipParent *p = uipParent(container); + struct forall s; + + s.callback = callback; + s.data = data; + if (p->children != NULL) + g_ptr_array_foreach(c->children, doforall, &s); +} + +static void uipParent_class_init(uipParentClass *class) +{ + G_OBJECT_CLASS(class)->dispose = uipParent_dispose; + G_OBJECT_CLASS(class)->finalize = uipParent_finalize; + GTK_WIDGET_CLASS(class)->size_allocate = uipParent_size_allocate; + GTK_CONTAINER_CLASS(class)->add = uipParent_add; + GTK_CONTAINER_CLASS(class)->remove = uipParent_remove; + GTK_CONTAINER_CLASS(class)->forall = uipParent_forall; +} + +static uintptr_t parentHandle(uiParent *p) +{ + uipParent *pp = uipParent(p->Internal); + + return (uintptr_t) pp; +} + +static void parentSetChild(uiParent *p, uiControl *child) +{ + uipParent *pp = uipParent(p->Internal); + + pp->child = child; + if (pp->child != NULL) + uiControlSetParent(child, p); +} + +static void parentSetMargins(uiParent *p, intmax_t left, intmax_t top, intmax_t right, intmax_t bottom) +{ + uipParent *pp = uipParent(p->Internal); + + pp->marginLeft = left; + pp->marginTop = top; + pp->marginRight = right; + pp->marginBottom = bottom; +} + +static void parentUpdate(uiParent *p) +{ + uipParent *pp = uipParent(p->Internal); + + gtk_queue_resize(GTK_WIDGET(pp)); +} + +uiParent *uiNewParent(uintptr_t osParent) +{ + uiParent *p; + + p = uiNew(uiParent); + p->Internal = g_object_new(uipParentType, NULL); + p->Handle = parentHandle; + p->SetChild = parentSetChild; + p->SetMargins = parentSetMargins; + p->Update = parentUpdate; + gtk_container_add(GTK_CONTAINER(osParent), GTK_WIDGET(p->Internal)); + // and make it visible by default + gtk_widget_show_all(GTK_WIDGET(p->internal)); + return p; +} -- cgit v1.2.3