[maemo-commits] [maemo-commits] r13889 - in projects/haf/trunk/gtk+: . gtk
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Tue Sep 18 15:10:31 EEST 2007
- Previous message: [maemo-commits] r13888 - projects/haf/trunk/gtk+
- Next message: [maemo-commits] r13890 - in projects/haf/trunk/gtk+: . gtk
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: tko Date: 2007-09-18 15:10:27 +0300 (Tue, 18 Sep 2007) New Revision: 13889 Modified: projects/haf/trunk/gtk+/ChangeLog projects/haf/trunk/gtk+/gtk/gtkhbbox.c Log: Make GtkHButtonBox better handle allocation < requisition 2007-09-18 Tommi Komulainen <tommi.komulainen at nokia.com> Patch from Xan Lopez, with small cleanups. * gtk/gtkhbbox.c (gtk_hbutton_box_get_children_sizes): New function to calculate the widths for all visible child widgets, and primary and secondary button groups. If there is not enough space for the buttons to have homogeneous width, each button gets their size requisition + any extra space evenly divided between the children. (gtk_hbutton_box_size_allocate): Refactored to not assume homogeneous layout and deal with heterogeneous layout. NB#63578 Modified: projects/haf/trunk/gtk+/ChangeLog =================================================================== --- projects/haf/trunk/gtk+/ChangeLog 2007-09-18 11:48:05 UTC (rev 13888) +++ projects/haf/trunk/gtk+/ChangeLog 2007-09-18 12:10:27 UTC (rev 13889) @@ -1,3 +1,16 @@ +2007-09-18 Tommi Komulainen <tommi.komulainen at nokia.com> + + Patch from Xan Lopez, with small cleanups. + + * gtk/gtkhbbox.c (gtk_hbutton_box_get_children_sizes): New function to + calculate the widths for all visible child widgets, and primary and + secondary button groups. If there is not enough space for the buttons + to have homogeneous width, each button gets their size requisition + + any extra space evenly divided between the children. + (gtk_hbutton_box_size_allocate): Refactored to not assume homogeneous + layout and deal with heterogeneous layout. + NB#63578 + 2007-09-17 Michael Natterer <mitch at imendio.com> Reintroduce GScanner cache. Addresses NB#61907: Modified: projects/haf/trunk/gtk+/gtk/gtkhbbox.c =================================================================== --- projects/haf/trunk/gtk+/gtk/gtkhbbox.c 2007-09-18 11:48:05 UTC (rev 13888) +++ projects/haf/trunk/gtk+/gtk/gtkhbbox.c 2007-09-18 12:10:27 UTC (rev 13889) @@ -164,11 +164,261 @@ } +#if defined(MAEMO_CHANGES) +/* This function is pretty much an abomination against reason. + More or less it's supposed to: + - If an homogeneous layout is possible: + + primary_width and secondary_width will be the sizes of the primary and + secondary groups (basically the homogeneous width times the number of items). + + children_widths will contain the homogeneous width for all items + - If an homogeneous layout is NOT possible: + + primary_width and secondary_width will contain the sum of the widths for each + group + + children_width will contain the heterogeneous width of each button, being this + its requisition plus any possible extra width added + + All the other parameters come straight from _gtk_button_box_child_requisition +*/ +static gint* +gtk_hbutton_box_get_children_sizes (GtkWidget *widget, + gint *primary_width, + gint *secondary_width, + gint *child_height, + gint *nvis_children, + gint *n_secondaries) +{ + GtkAllocation *allocation = &widget->allocation; + gint *children_widths; + gint child_width; + gint total_width; + gint total_spacing; + gint i; + + _gtk_button_box_child_requisition (widget, + nvis_children, + n_secondaries, + &child_width, + child_height); + + children_widths = g_slice_alloc (sizeof (gint) * (*nvis_children)); + + total_width = *nvis_children * child_width; + total_spacing = (*nvis_children - 1) * GTK_BOX (widget)->spacing; + + if (total_width + total_spacing > allocation->width) + { + /* homogeneous allocation too wide to fit container, shrink the buttons + * to their size requisition */ + GList *children; + gint extra_space; + + *primary_width = 0; + *secondary_width = 0; + children = GTK_BOX (widget)->children; + i = 0; + + while (children) + { + GtkBoxChild *child = children->data; + GtkWidget *child_widget = child->widget; + children = children->next; + + if (GTK_WIDGET_VISIBLE (child_widget)) + { + GtkRequisition req; + + /* FIXME: take child-min-width and child-internal-pad-x style + * properties into account + */ + + gtk_widget_size_request (child_widget, &req); + + if (! child->is_secondary) + *primary_width += req.width; + else + *secondary_width += req.width; + + children_widths[i++] = req.width; + } + } + + total_width = *primary_width + *secondary_width; + extra_space = allocation->width - (total_width + total_spacing); + + /* If extra space available, distribute it evenly to the buttons. + * XXX: Smallest buttons should probably get the biggest share instead, + * to maximize button sizes and approximate homogeneous allocation. + * + * XXX: If extra_space is < 0 the layout will be broken (label truncation + * etc.) but we should still shrink the children + */ + if (extra_space > 0) + { + gint extra; + + extra = extra_space / *nvis_children; + children = GTK_BOX (widget)->children; + i = 0; + + while (children) + { + GtkBoxChild *child = children->data; + GtkWidget *child_widget = child->widget; + children = children->next; + + if (GTK_WIDGET_VISIBLE (child_widget)) + { + children_widths[i++] += extra; + + if (! child->is_secondary) + *primary_width += extra; + else + *secondary_width += extra; + } + } + } + } + else + { + /* homogeneous allocation */ + *primary_width = child_width * (*nvis_children - *n_secondaries); + *secondary_width = child_width * *n_secondaries; + for (i = 0; i < *nvis_children; i++) + children_widths[i] = child_width; + } +} + static void gtk_hbutton_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { + gint primary_width, secondary_width, child_height; + gint *children_widths; + gint x, y; + gint secondary_x; + gint nvis_children, n_secondaries, childspacing; + gint n_primaries, inner_width; + GList *children; + GtkBoxChild *child; + gint i; + GtkButtonBoxStyle layout; + + widget->allocation = *allocation; + + children_widths = gtk_hbutton_box_get_children_sizes (widget, + &primary_width, + &secondary_width, + &child_height, + &nvis_children, + &n_secondaries); + + n_primaries = nvis_children - n_secondaries; + inner_width = allocation->width - 2 * GTK_CONTAINER (widget)->border_width; +#define primary_spacing (childspacing * (n_primaries - 1)) +#define secondary_spacing (childspacing * (n_secondaries - 1)) + + layout = GTK_BUTTON_BOX (widget)->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE + ? GTK_BUTTON_BOX (widget)->layout_style : default_layout_style; + + switch (layout) + { + case GTK_BUTTONBOX_SPREAD: + childspacing = (inner_width + - (primary_width + secondary_width)) / (nvis_children + 1); + x = allocation->x + GTK_CONTAINER (widget)->border_width + childspacing; + secondary_x = x + primary_width + primary_spacing + childspacing; + break; + case GTK_BUTTONBOX_EDGE: + if (nvis_children >= 2) + { + childspacing = (inner_width + - (primary_width + secondary_width)) / (nvis_children + 1); + x = allocation->x + GTK_CONTAINER (widget)->border_width; + secondary_x = x + primary_width + primary_spacing + childspacing; + } + else + { + /* one or zero children, just center */ + childspacing = inner_width; + x = secondary_x = allocation->x + (allocation->width - primary_width) / 2; + } + break; + case GTK_BUTTONBOX_START: + childspacing = GTK_BOX (widget)->spacing; + x = allocation->x + GTK_CONTAINER (widget)->border_width; + secondary_x = allocation->x + allocation->width + - secondary_width + - secondary_spacing + - GTK_CONTAINER (widget)->border_width; + break; + case GTK_BUTTONBOX_END: + childspacing = GTK_BOX (widget)->spacing; + x = allocation->x + allocation->width + - primary_width + - primary_spacing + - GTK_CONTAINER (widget)->border_width; + secondary_x = allocation->x + GTK_CONTAINER (widget)->border_width; + break; + case GTK_BUTTONBOX_CENTER: + childspacing = GTK_BOX (widget)->spacing; + x = allocation->x + + (allocation->width + - (primary_width + primary_spacing))/2 + + (secondary_width + secondary_spacing + childspacing)/2; + secondary_x = allocation->x + GTK_CONTAINER (widget)->border_width; + break; + default: + g_assert_not_reached(); + break; + } +#undef primary_spacing +#undef secondary_spacing + + y = allocation->y + (allocation->height - child_height) / 2; + + children = GTK_BOX (widget)->children; + i = 0; + while (children) + { + child = children->data; + children = children->next; + + if (GTK_WIDGET_VISIBLE (child->widget)) + { + GtkAllocation child_allocation; + gint child_width = children_widths[i++]; + + child_allocation.width = child_width; + child_allocation.height = child_height; + child_allocation.y = y; + + if (child->is_secondary) + { + child_allocation.x = secondary_x; + secondary_x += child_width + childspacing; + } + else + { + child_allocation.x = x; + x += child_width + childspacing; + } + + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + child_allocation.x = (allocation->x + allocation->width) - (child_allocation.x + child_width - allocation->x); + + gtk_widget_size_allocate (child->widget, &child_allocation); + } + } + + g_slice_free1 (sizeof (gint) * nvis_children, children_widths); +} + +#else +static void +gtk_hbutton_box_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ GtkBox *base_box; GtkButtonBox *box; GtkBoxChild *child; @@ -285,6 +535,7 @@ } } } +#endif #define __GTK_HBUTTON_BOX_C__ #include "gtkaliasdef.c"
- Previous message: [maemo-commits] r13888 - projects/haf/trunk/gtk+
- Next message: [maemo-commits] r13890 - in projects/haf/trunk/gtk+: . gtk
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]