diff --git a/redo/unix/bin.c b/redo/unix/bin.c deleted file mode 100644 index ddb3470d..00000000 --- a/redo/unix/bin.c +++ /dev/null @@ -1,82 +0,0 @@ -// 30 june 2015 -#include "uipriv_unix.h" - -// This is a uiControl wrapper a la GtkBin. -// It serves the function of tabPage on Windows: it allows uiWindow and uiTab to give their children a real uiControl as a parent while not screwing with the internal GtkWidget structure of those uiControls. -// It also provides margins. - -struct bin { - uiControl c; - GtkWidget *widget; - GtkContainer *container; - GtkBox *box; // GtkBin is abstract and none of the implementations seem adequate (GtkFrame is the closest but eh) - uiControl *child; - int margined; -}; - -uiDefineControlType(bin, binType, struct bin) - -static uintptr_t binHandle(uiControl *c) -{ - struct bin *b = (struct bin *) c; - - return (uintptr_t) (b->widget); -} - -uiControl *newBin(void) -{ - struct bin *b; - - b = (struct bin *) uiNewControl(binType()); - - b->widget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - b->container = GTK_CONTAINER(b->widget); - b->box = GTK_BOX(b->widget); - uiUnixMakeSingleWidgetControl(uiControl(b), b->widget); - - // a uiBox is theoretically used in a context where this shouldn't be necessary but because of uiWindow we'll do it anyway - gtk_widget_set_hexpand(b->widget, TRUE); - gtk_widget_set_halign(b->widget, GTK_ALIGN_FILL); - gtk_widget_set_vexpand(b->widget, TRUE); - gtk_widget_set_valign(b->widget, GTK_ALIGN_FILL); - - uiControl(b)->Handle = binHandle; - - return uiControl(b); -} - -void binSetChild(uiControl *c, uiControl *child) -{ - struct bin *b = (struct bin *) c; - GtkWidget *childWidget; - - if (b->child != NULL) - uiControlSetParent(b->child, NULL); - b->child = child; - if (b->child != NULL) { - uiControlSetParent(b->child, uiControl(b)); - childWidget = GTK_WIDGET(uiControlHandle(b->child)); - gtk_widget_set_hexpand(childWidget, TRUE); - gtk_widget_set_halign(childWidget, GTK_ALIGN_FILL); - gtk_widget_set_vexpand(childWidget, TRUE); - gtk_widget_set_valign(childWidget, GTK_ALIGN_FILL); - } -} - -int binMargined(uiControl *c) -{ - struct bin *b = (struct bin *) c; - - return b->margined; -} - -void binSetMargined(uiControl *c, int margined) -{ - struct bin *b = (struct bin *) c; - - b->margined = margined; - if (b->margined) - gtk_container_set_border_width(b->container, gtkXMargin); - else - gtk_container_set_border_width(b->container, 0); -} diff --git a/redo/unix/container.c b/redo/unix/container.c deleted file mode 100644 index 892a4bf7..00000000 --- a/redo/unix/container.c +++ /dev/null @@ -1,146 +0,0 @@ -// 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; -} diff --git a/redo/unix/group.c b/redo/unix/group.c index 058d040f..74d019eb 100644 --- a/redo/unix/group.c +++ b/redo/unix/group.c @@ -1,107 +1,99 @@ // 11 june 2015 #include "uipriv_unix.h" -struct group { - uiGroup g; +struct uiGroup { + uiUnixControl c; GtkWidget *widget; GtkContainer *container; GtkFrame *frame; // unfortunately, even though a GtkFrame is a GtkBin, calling gtk_container_set_border_width() on it /includes/ the GtkFrame's label; we don't want tht - uiControl *bin; + GtkWidget *box; uiControl *child; - void (*baseCommitDestroy)(uiControl *); + int margined; }; -uiDefineControlType(uiGroup, uiTypeGroup, struct group) +static void onDestroy(uiGroup *); -static void groupCommitDestroy(uiControl *c) +uiUnixDefineControlWithOnDestroy( + uiGroup, // type name + uiGroupType, // type function + onDestroy(this); // on destroy +) + +static void onDestroy(uiGroup *g) { - struct group *g = (struct group *) c; - if (g->child != NULL) { - binSetChild(g->bin, NULL); + uiControlSetParent(g->child, NULL); uiControlDestroy(g->child); } - uiControlDestroy(g->bin); - (*(g->baseCommitDestroy))(uiControl(g)); -} - -static uintptr_t groupHandle(uiControl *c) -{ - struct group *g = (struct group *) c; - - return (uintptr_t) (g->widget); + gtk_widget_destroy(g->box); } static void groupContainerUpdateState(uiControl *c) { - struct group *g = (struct group *) c; + uiGroup *g = uiGroup(c); if (g->child != NULL) uiControlUpdateState(g->child); } -static char *groupTitle(uiGroup *gg) +char *uiGroupTitle(uiGroup *g) { - struct group *g = (struct group *) gg; - return uiUnixStrdupText(gtk_frame_get_label(g->frame)); } -static void groupSetTitle(uiGroup *gg, const char *text) +void uiGroupSetTitle(uiGroup *g, const char *text) { - struct group *g = (struct group *) gg; - gtk_frame_set_label(g->frame, text); // changing the text might necessitate a change in the groupbox's size uiControlQueueResize(uiControl(g)); } -static void groupSetChild(uiGroup *gg, uiControl *child) +void uiGroupSetChild(uiGroup *g, uiControl *child) { struct group *g = (struct group *) gg; - if (g->child != NULL) - binSetChild(g->bin, NULL); + if (g->child != NULL) { + gtk_container_remove(GTK_CONTAINER(g->bin), + GTK_WIDGET(uiControlHandle(g->child))); + uiControlSetParent(g->child, NULL); + } g->child = child; if (g->child != NULL) { - binSetChild(g->bin, g->child); + uiControlSetParent(g->child, uiControl(g)); + gtk_container_add(GTK_CONTAINER(g->bin), + GTK_WIDGET(uiControlHandle(g->child))); uiControlQueueResize(g->child); } } -static int groupMargined(uiGroup *gg) +int uiGroupMargined(uiGroup *g) { - struct group *g = (struct group *) gg; - - return binMargined(g->bin); + return g->margined; } -// TODO this includes the label -static void groupSetMargined(uiGroup *gg, int margined) +void uiGroupSetMargined(uiGroup *g, int margined) { - struct group *g = (struct group *) gg; - - binSetMargined(g->bin, margined); + g->margined = margined; + setMargined(GTK_CONTAINER(g->box), g->margined); uiControlQueueResize(uiControl(g)); } uiGroup *uiNewGroup(const char *text) { - struct group *g; + uiGroup *g; gfloat yalign; GtkLabel *label; PangoAttribute *bold; PangoAttrList *boldlist; - g = (struct group *) uiNewControl(uiTypeGroup()); + g = (uiGroup *) uiNewControl(uiTypeGroup()); g->widget = gtk_frame_new(text); g->container = GTK_CONTAINER(g->widget); g->frame = GTK_FRAME(g->widget); - uiUnixMakeSingleWidgetControl(uiControl(g), g->widget); // with GTK+, groupboxes by default have frames and slightly x-offset regular text // they should have no frame and fully left-justified, bold text @@ -118,22 +110,12 @@ uiGroup *uiNewGroup(const char *text) gtk_label_set_attributes(label, boldlist); pango_attr_list_unref(boldlist); // thanks baedert in irc.gimp.net/#gtk+ - g->bin = newBin(); - // can't use uiControlSetParent() because we didn't set the vtable yet - gtk_container_add(g->container, GTK_WIDGET(uiControlHandle(g->bin))); - // TODO this is a mess - gtk_widget_show(GTK_WIDGET(uiControlHandle(g->bin))); + g->box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_container_add(g->container, g->box); + gtk_widget_show(g->box); - uiControl(g)->Handle = groupHandle; - g->baseCommitDestroy = uiControl(g)->CommitDestroy; - uiControl(g)->CommitDestroy = groupCommitDestroy; + uiUnixFinishNewControl(g, uiGroup); uiControl(g)->ContainerUpdateState = groupContainerUpdateState; - uiGroup(g)->Title = groupTitle; - uiGroup(g)->SetTitle = groupSetTitle; - uiGroup(g)->SetChild = groupSetChild; - uiGroup(g)->Margined = groupMargined; - uiGroup(g)->SetMargined = groupSetMargined; - - return uiGroup(g); + return g; } diff --git a/redo/unix/uipriv_unix.h b/redo/unix/uipriv_unix.h index d4f6a343..fb2600b5 100644 --- a/redo/unix/uipriv_unix.h +++ b/redo/unix/uipriv_unix.h @@ -22,8 +22,5 @@ extern void uninitMenus(void); extern void initAlloc(void); extern void uninitAlloc(void); -// bin.c -extern uiControl *newBin(void); -extern void binSetChild(uiControl *, uiControl *); -extern int binMargined(uiControl *); -extern void binSetMargined(uiControl *, int); +// util.c +extern void setMargined(GtkContainer *, int); diff --git a/redo/unix/util.c b/redo/unix/util.c index 34f5d5d9..260e0ae8 100644 --- a/redo/unix/util.c +++ b/redo/unix/util.c @@ -12,19 +12,10 @@ void complain(const char *fmt, ...) g_error("[libui] %s\n", msg); } -uiSizing *uiUnixNewSizing(void) +void setMargined(GtkContainer *c, int margined) { - uiSizing *d; - - d = uiNew(uiSizing); - d->XPadding = gtkXPadding; - d->YPadding = gtkYPadding; - d->Sys = uiNew(uiSizingSys); - return d; -} - -void uiFreeSizing(uiSizing *d) -{ - uiFree(d->Sys); - uiFree(d); + if (b->margined) + gtk_container_set_border_width(c, gtkXMargin); + else + gtk_container_set_border_width(c, 0); }