From 022a3ae20eaba895fff6b21ddba2b86034848b87 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Thu, 9 Apr 2015 18:17:04 -0400 Subject: [PATCH] Migrated the GTK+ backend to the new uiControl/uiSizing system. --- button_unix.c | 30 ++++++++-------- checkbox_unix.c | 34 +++++++++--------- entry_unix.c | 19 +++++----- newcontrol_unix.c | 90 +++++++++++++++++++++++------------------------ ui_unix.h | 8 +++-- uipriv_unix.h | 3 -- 6 files changed, 91 insertions(+), 93 deletions(-) diff --git a/button_unix.c b/button_unix.c index c458e688..da090824 100644 --- a/button_unix.c +++ b/button_unix.c @@ -2,16 +2,16 @@ #include "uipriv_unix.h" struct button { - uiControl *c; void (*onClicked)(uiControl *, void *); void *onClickedData; }; -#define B(x) ((struct button *) (x)) - -static void onClicked(GtkButton *b, gpointer data) +static void onClicked(GtkButton *button, gpointer data) { - (*(B(data)->onClicked))(B(data)->c, B(data)->onClickedData); + uiControl *c = (uiControl *) data; + struct button *b = (struct button *) (c->data); + + (*(b->onClicked))(c, b->onClickedData); } static void defaultOnClicked(uiControl *c, void *data) @@ -28,23 +28,24 @@ static void onDestroy(GtkWidget *widget, gpointer data) uiControl *uiNewButton(const char *text) { + uiControl *c; struct button *b; GtkWidget *widget; - b = uiNew(struct button); - - b->c = uiUnixNewControl(GTK_TYPE_BUTTON, - FALSE, FALSE, b, + c = uiUnixNewControl(GTK_TYPE_BUTTON, + FALSE, FALSE, "label", text, NULL); - widget = GTK_WIDGET(uiControlHandle(b->c)); + widget = GTK_WIDGET(uiControlHandle(c)); + g_signal_connect(widget, "clicked", G_CALLBACK(onClicked), c); + + b = uiNew(struct button); g_signal_connect(widget, "destroy", G_CALLBACK(onDestroy), b); - g_signal_connect(widget, "clicked", G_CALLBACK(onClicked), b); - b->onClicked = defaultOnClicked; + c->data = b; - return b->c; + return c; } char *uiButtonText(uiControl *c) @@ -59,9 +60,8 @@ void uiButtonSetText(uiControl *c, const char *text) void uiButtonOnClicked(uiControl *c, void (*f)(uiControl *, void *), void *data) { - struct button *b; + struct button *b = (struct button *) (c->data); - b = (struct button *) uiUnixControlData(c); b->onClicked = f; b->onClickedData = data; } diff --git a/checkbox_unix.c b/checkbox_unix.c index ac0544dc..c0d509ef 100644 --- a/checkbox_unix.c +++ b/checkbox_unix.c @@ -2,16 +2,16 @@ #include "uipriv_unix.h" struct checkbox { - uiControl *c; void (*onToggled)(uiControl *, void *); void *onToggledData; }; -#define C(x) ((struct checkbox *) (x)) - static void onToggled(GtkToggleButton *b, gpointer data) { - (*(C(data)->onToggled))(C(data)->c, C(data)->onToggledData); + uiControl *c = (uiControl *) data; + struct checkbox *cc = (struct checkbox *) (c->data); + + (*(cc->onToggled))(c, cc->onToggledData); } static void defaultOnToggled(uiControl *c, void *data) @@ -21,30 +21,31 @@ static void defaultOnToggled(uiControl *c, void *data) static void onDestroy(GtkWidget *widget, gpointer data) { - struct checkbox *c = (struct checkbox *) data; + struct checkbox *cc = (struct checkbox *) data; - uiFree(c); + uiFree(cc); } uiControl *uiNewCheckbox(const char *text) { - struct checkbox *c; + uiControl *c; + struct checkbox *cc; GtkWidget *widget; - c = uiNew(struct checkbox); - - c->c = uiUnixNewControl(GTK_TYPE_CHECK_BUTTON, - FALSE, FALSE, c, + c = uiUnixNewControl(GTK_TYPE_CHECK_BUTTON, + FALSE, FALSE, "label", text, NULL); - widget = GTK_WIDGET(uiControlHandle(c->c)); - g_signal_connect(widget, "destroy", G_CALLBACK(onDestroy), c); + widget = GTK_WIDGET(uiControlHandle(c)); g_signal_connect(widget, "toggled", G_CALLBACK(onToggled), c); - c->onToggled = defaultOnToggled; + cc = uiNew(struct checkbox); + g_signal_connect(widget, "destroy", G_CALLBACK(onDestroy), cc); + cc->onToggled = defaultOnToggled; + c->data = cc; - return c->c; + return c; } char *uiCheckboxText(uiControl *c) @@ -59,9 +60,8 @@ void uiCheckboxSetText(uiControl *c, const char *text) void uiCheckboxOnToggled(uiControl *c, void (*f)(uiControl *, void *), void *data) { - struct checkbox *cc; + struct checkbox *cc = (struct checkbox *) (c->data); - cc = (struct checkbox *) uiUnixControlData(c); cc->onToggled = f; cc->onToggledData = data; } diff --git a/entry_unix.c b/entry_unix.c index 04005d35..43caea32 100644 --- a/entry_unix.c +++ b/entry_unix.c @@ -2,11 +2,8 @@ #include "uipriv_unix.h" struct entry { - uiControl *c; }; -#define E(x) ((struct entry *) (x)) - static void onDestroy(GtkWidget *widget, gpointer data) { struct entry *e = (struct entry *) data; @@ -16,19 +13,21 @@ static void onDestroy(GtkWidget *widget, gpointer data) uiControl *uiNewEntry(void) { + uiControl *c; struct entry *e; GtkWidget *widget; - e = uiNew(struct entry); - - e->c = uiUnixNewControl(GTK_TYPE_ENTRY, - FALSE, FALSE, e, + c = uiUnixNewControl(GTK_TYPE_ENTRY, + FALSE, FALSE, NULL); - widget = GTK_WIDGET(uiControlHandle(e->c)); - g_signal_connect(widget, "destroy", G_CALLBACK(onDestroy), e); + widget = GTK_WIDGET(uiControlHandle(c)); - return e->c; + e = uiNew(struct entry); + g_signal_connect(widget, "destroy", G_CALLBACK(onDestroy), e); + c->data = e; + + return c; } char *uiEntryText(uiControl *c) diff --git a/newcontrol_unix.c b/newcontrol_unix.c index 870406c9..14c1988c 100644 --- a/newcontrol_unix.c +++ b/newcontrol_unix.c @@ -1,32 +1,32 @@ // 7 april 2015 #include "uipriv_unix.h" -typedef struct uiSingleWidgetControl uiSingleWidgetControl; +typedef struct singleWidget singleWidget; -struct uiSingleWidgetControl { - uiControl control; +struct singleWidget { GtkWidget *widget; GtkWidget *scrolledWindow; GtkWidget *immediate; // the widget that is added to the parent container; either widget or scrolledWindow - void *data; uintptr_t parent; }; -#define S(c) ((uiSingleWidgetControl *) (c)) - static void singleDestroy(uiControl *c) { - gtk_widget_destroy(S(c)->immediate); + singleWidget *s = (singleWidget *) (c->internal); + + gtk_widget_destroy(s->immediate); } static uintptr_t singleHandle(uiControl *c) { - return (uintptr_t) (S(c)->widget); + singleWidget *s = (singleWidget *) (c->internal); + + return (uintptr_t) (s->widget); } static void singleSetParent(uiControl *c, uintptr_t parent) { - uiSingleWidgetControl *s = S(c); + singleWidget *s = (singleWidget *) (c->internal); s->parent = parent; gtk_container_add(GTK_CONTAINER(s->parent), s->immediate); @@ -35,7 +35,7 @@ static void singleSetParent(uiControl *c, uintptr_t parent) static void singleRemoveParent(uiControl *c) { - uiSingleWidgetControl *s = S(c); + singleWidget *s = (singleWidget *) (c->internal); uintptr_t oldparent; oldparent = s->parent; @@ -44,59 +44,62 @@ static void singleRemoveParent(uiControl *c) updateParent(oldparent); } -static uiSize singlePreferredSize(uiControl *c, uiSizing *d) +static void singlePreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height) { - uiSize size; + singleWidget *s = (singleWidget *) (c->internal); GtkRequisition natural; // use the natural size as the minimum size is an *absolute* minimum // for example, if a label has ellipsizing on, it can be the width of the ellipses, not the text // there is a warning about height-for-width sizing, but in my tests this isn't an issue - gtk_widget_get_preferred_size(S(c)->widget, NULL, &natural); - size.width = natural.width; - size.height = natural.height; - return size; + gtk_widget_get_preferred_size(s->widget, NULL, &natural); + *width = natural.width; + *height = natural.height; } static void singleResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d) { + singleWidget *s = (singleWidget *) (c->internal); GtkAllocation a; a.x = x; a.y = y; a.width = width; a.height = height; - gtk_widget_size_allocate(S(c)->immediate, &a); + gtk_widget_size_allocate(s->immediate, &a); } static void onDestroy(GtkWidget *widget, gpointer data) { - uiSingleWidgetControl *c = (uiSingleWidgetControl *) data; + uiControl *c = (uiControl *) data; + singleWidget *s = (singleWidget *) (c->internal); + uiFree(s); uiFree(c); } -uiControl *uiUnixNewControl(GType type, gboolean inScrolledWindow, gboolean scrolledWindowHasBorder, void *data, const char *firstProperty, ...) +uiControl *uiUnixNewControl(GType type, gboolean inScrolledWindow, gboolean scrolledWindowHasBorder, const char *firstProperty, ...) { - uiSingleWidgetControl *c; + uiControl *c; + singleWidget *s; va_list ap; - c = uiNew(uiSingleWidgetControl); + s = uiNew(singleWidget); va_start(ap, firstProperty); - c->widget = GTK_WIDGET(g_object_new_valist(type, firstProperty, ap)); + s->widget = GTK_WIDGET(g_object_new_valist(type, firstProperty, ap)); va_end(ap); - c->immediate = c->widget; + s->immediate = s->widget; if (inScrolledWindow) { - c->scrolledWindow = gtk_scrolled_window_new(NULL, NULL); - if (!GTK_IS_SCROLLABLE(c->widget)) - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(c->scrolledWindow), c->widget); + s->scrolledWindow = gtk_scrolled_window_new(NULL, NULL); + if (!GTK_IS_SCROLLABLE(s->widget)) + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(s->scrolledWindow), s->widget); else - gtk_container_add(GTK_CONTAINER(c->scrolledWindow), c->widget); + gtk_container_add(GTK_CONTAINER(s->scrolledWindow), s->widget); if (scrolledWindowHasBorder) - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(c->scrolledWindow), GTK_SHADOW_IN); - c->immediate = c->scrolledWindow; + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(s->scrolledWindow), GTK_SHADOW_IN); + s->immediate = s->scrolledWindow; } // we need to keep an extra reference on the immediate widget @@ -108,23 +111,20 @@ uiControl *uiUnixNewControl(GType type, gboolean inScrolledWindow, gboolean scro // - end user call works (shoudn't be in any container) // - call in uiContainer works (both refs freed) // this also ensures singleRemoveParent() works properly - g_object_ref_sink(c->immediate); - // and let's free the uiSingleWidgetControl with it - g_signal_connect(c->immediate, "destroy", G_CALLBACK(onDestroy), c); + g_object_ref_sink(s->immediate); - c->control.destroy = singleDestroy; - c->control.handle = singleHandle; - c->control.setParent = singleSetParent; - c->control.removeParent = singleRemoveParent; - c->control.preferredSize = singlePreferredSize; - c->control.resize = singleResize; + c = uiNew(uiControl); + // assign s later; we still need it for one more thing + c->destroy = singleDestroy; + c->handle = singleHandle; + c->setParent = singleSetParent; + c->removeParent = singleRemoveParent; + c->preferredSize = singlePreferredSize; + c->resize = singleResize; - c->data = data; + // and let's free everything with the immediate widget + g_signal_connect(s->immediate, "destroy", G_CALLBACK(onDestroy), c); - return (uiControl *) c; -} - -void *uiUnixControlData(uiControl *c) -{ - return S(c)->data; + c->internal = s; + return c; } diff --git a/ui_unix.h b/ui_unix.h index 4e4f6e8d..1fa341d0 100644 --- a/ui_unix.h +++ b/ui_unix.h @@ -10,9 +10,11 @@ This file assumes that you have included and "ui.h" beforehand. It p // uiUnixNewControl() creates a new uiControl with the given GTK+ control inside. // The first parameter is the type of the control, as passed to the first argument of g_object_new(). // The two scrolledWindow parameters allow placing scrollbars on the new control. -// The data parameter can be accessed with uiUnixControlData(). // The firstProperty parameter and beyond allow passing construct properties to the new control, as with g_object_new(); end this list with NULL. -extern uiControl *uiUnixNewControl(GType type, gboolean inScrolledWindow, gboolean scrolledWindowHasBorder, void *data, const char *firstProperty, ...); -extern void *uiUnixControlData(uiControl *c); +extern uiControl *uiUnixNewControl(GType type, gboolean inScrolledWindow, gboolean scrolledWindowHasBorder, const char *firstProperty, ...); + +struct uiSizingSys { + // this structure currently left blank +}; #endif diff --git a/uipriv_unix.h b/uipriv_unix.h index b51bda5d..97e16e11 100644 --- a/uipriv_unix.h +++ b/uipriv_unix.h @@ -8,9 +8,6 @@ #include "ui_unix.h" // container_unix.c -struct uiSizing { - uiSizingCommon -}; #define uiContainerType (uiContainer_get_type()) #define uiContainer(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), uiContainerType, uiContainer)) #define uiIsContainer(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), uiContainerType))