// 11 june 2015 #include "uipriv_unix.h" struct group { uiGroup g; 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; uiControl *child; void (*baseCommitDestroy)(uiControl *); }; uiDefineControlType(uiGroup, uiTypeGroup, struct group) static void groupCommitDestroy(uiControl *c) { struct group *g = (struct group *) c; if (g->child != NULL) { binSetChild(g->bin, 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); } static void groupContainerUpdateState(uiControl *c) { struct group *g = (struct group *) c; if (g->child != NULL) uiControlUpdateState(g->child); } static char *groupTitle(uiGroup *gg) { struct group *g = (struct group *) gg; return uiUnixStrdupText(gtk_frame_get_label(g->frame)); } static void groupSetTitle(uiGroup *gg, 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) { struct group *g = (struct group *) gg; if (g->child != NULL) binSetChild(g->bin, NULL); g->child = child; if (g->child != NULL) { binSetChild(g->bin, g->child); uiControlQueueResize(g->child); } } static int groupMargined(uiGroup *gg) { struct group *g = (struct group *) gg; return binMargined(g->bin); } // TODO this includes the label static void groupSetMargined(uiGroup *gg, int margined) { struct group *g = (struct group *) gg; binSetMargined(g->bin, margined); uiControlQueueResize(uiControl(g)); } uiGroup *uiNewGroup(const char *text) { struct group *g; gfloat yalign; GtkLabel *label; PangoAttribute *bold; PangoAttrList *boldlist; g = (struct group *) 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 // preserve default y-alignment gtk_frame_get_label_align(g->frame, NULL, &yalign); gtk_frame_set_label_align(g->frame, 0, yalign); gtk_frame_set_shadow_type(g->frame, GTK_SHADOW_NONE); label = GTK_LABEL(gtk_frame_get_label_widget(g->frame)); // this is the boldness level used by GtkPrintUnixDialog // (it technically uses "bold" but see pango's pango-enum-types.c for the name conversion; GType is weird) bold = pango_attr_weight_new(PANGO_WEIGHT_BOLD); boldlist = pango_attr_list_new(); pango_attr_list_insert(boldlist, bold); 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))); uiControl(g)->Handle = groupHandle; g->baseCommitDestroy = uiControl(g)->CommitDestroy; uiControl(g)->CommitDestroy = groupCommitDestroy; 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); }