X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktoolitemgroup.c;h=d6aa8258c6bdcc9371231fb29f75f081dfc744e5;hb=d97861bd8b338c3d25d7ffb5496edee9eee9bfbb;hp=58312de7cf1ce340269a11368eab52e511ec5fdf;hpb=ac7b0c91ae8394b869c00ece5ccadcb433aaecd6;p=~andy%2Fgtk diff --git a/gtk/gtktoolitemgroup.c b/gtk/gtktoolitemgroup.c index 58312de7c..d6aa8258c 100644 --- a/gtk/gtktoolitemgroup.c +++ b/gtk/gtktoolitemgroup.c @@ -12,21 +12,22 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * License along with this library. If not, see . * * Authors: * Mathias Hasselmann * Jan Arne Petersen */ -#include "gtktoolpaletteprivate.h" +#include "config.h" -#include #include #include -#define P_(msgid) (msgid) +#include "gtktoolpaletteprivate.h" +#include "gtktypebuiltins.h" +#include "gtkprivate.h" +#include "gtkintl.h" #define ANIMATION_TIMEOUT 50 #define ANIMATION_DURATION (ANIMATION_TIMEOUT * 4) @@ -34,25 +35,27 @@ #define DEFAULT_EXPANDER_SIZE 16 #define DEFAULT_HEADER_SPACING 2 -#define DEFAULT_NAME NULL +#define DEFAULT_LABEL "" #define DEFAULT_COLLAPSED FALSE #define DEFAULT_ELLIPSIZE PANGO_ELLIPSIZE_NONE /** - * SECTION:GtkToolItemGroup - * @short_description: A sub container used in a tool palette - * @include: gtktoolitemgroup.h + * SECTION:gtktoolitemgroup + * @Short_description: A sub container used in a tool palette + * @Title: GtkToolItemGroup * - * An #GtkToolItemGroup is used together with #GtkToolPalette to add #GtkToolItems to a palette like container - * with different categories and drag and drop support. + * A #GtkToolItemGroup is used together with #GtkToolPalette to add + * #GtkToolItems to a palette like container with different + * categories and drag and drop support. * - * Since: 2.18 + * Since: 2.20 */ enum { PROP_NONE, - PROP_NAME, + PROP_LABEL, + PROP_LABEL_WIDGET, PROP_COLLAPSED, PROP_ELLIPSIZE, PROP_RELIEF @@ -73,16 +76,14 @@ typedef struct _GtkToolItemGroupChild GtkToolItemGroupChild; struct _GtkToolItemGroupPrivate { GtkWidget *header; + GtkWidget *label_widget; GList *children; - gboolean animation; gint64 animation_start; GSource *animation_timeout; - GtkExpanderStyle expander_style; gint expander_size; gint header_spacing; - PangoEllipsizeMode ellipsize; gulong focus_set_id; GtkWidget *toplevel; @@ -90,6 +91,9 @@ struct _GtkToolItemGroupPrivate GtkSettings *settings; gulong settings_connection; + PangoEllipsizeMode ellipsize; + + guint animation : 1; guint collapsed : 1; }; @@ -114,13 +118,6 @@ gtk_tool_item_group_get_alignment (GtkToolItemGroup *group) return gtk_bin_get_child (GTK_BIN (group->priv->header)); } -static GtkWidget* -gtk_tool_item_group_get_label (GtkToolItemGroup *group) -{ - GtkWidget *alignment = gtk_tool_item_group_get_alignment (group); - return gtk_bin_get_child (GTK_BIN (alignment)); -} - static GtkOrientation gtk_tool_item_group_get_orientation (GtkToolShell *shell) { @@ -173,17 +170,6 @@ gtk_tool_item_group_get_text_alignment (GtkToolShell *shell) static GtkOrientation gtk_tool_item_group_get_text_orientation (GtkToolShell *shell) { - GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (shell)); - - if (GTK_IS_TOOL_PALETTE (parent)) - { - GtkOrientation orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (parent)); - if (GTK_ORIENTATION_HORIZONTAL == orientation && - (GTK_TOOLBAR_TEXT == gtk_tool_item_group_get_style (shell)/* || - GTK_TOOLBAR_BOTH_HORIZ == gtk_tool_item_group_get_style (shell)*/)) - return GTK_ORIENTATION_VERTICAL; - } - return GTK_ORIENTATION_HORIZONTAL; } @@ -219,10 +205,8 @@ gtk_tool_item_group_settings_change_notify (GtkSettings *settings, const GParamSpec *pspec, GtkToolItemGroup *group) { - if (! strcmp (pspec->name, "gtk-enable-animations")) - { + if (strcmp (pspec->name, "gtk-enable-animations") == 0) animation_change_notify (group); - } } static void @@ -233,18 +217,19 @@ gtk_tool_item_group_screen_changed (GtkWidget *widget, GtkToolItemGroupPrivate* priv = group->priv; GtkSettings *old_settings = priv->settings; GtkSettings *settings; - + if (gtk_widget_has_screen (GTK_WIDGET (group))) settings = gtk_widget_get_settings (GTK_WIDGET (group)); else settings = NULL; - + if (settings == old_settings) return; - + if (old_settings) { g_signal_handler_disconnect (old_settings, priv->settings_connection); + priv->settings_connection = 0; g_object_unref (old_settings); } @@ -275,99 +260,113 @@ gtk_tool_item_group_tool_shell_init (GtkToolShellIface *iface) } static gboolean -gtk_tool_item_group_header_expose_event_cb (GtkWidget *widget, - GdkEventExpose *event, - gpointer data) +gtk_tool_item_group_header_draw_cb (GtkWidget *widget, + cairo_t *cr, + gpointer data) { GtkToolItemGroup *group = GTK_TOOL_ITEM_GROUP (data); - GtkExpanderStyle expander_style; + GtkToolItemGroupPrivate* priv = group->priv; GtkOrientation orientation; - gint x, y; + gint x, y, width, height; GtkTextDirection direction; + GtkStyleContext *context; + GtkStateFlags state = 0; orientation = gtk_tool_shell_get_orientation (GTK_TOOL_SHELL (group)); - expander_style = group->priv->expander_style; direction = gtk_widget_get_direction (widget); + width = gtk_widget_get_allocated_width (widget); + height = gtk_widget_get_allocated_height (widget); + context = gtk_widget_get_style_context (widget); + state = gtk_widget_get_state_flags (widget); + + if (!priv->collapsed) + state |= GTK_STATE_FLAG_ACTIVE; + + gtk_style_context_save (context); + gtk_style_context_set_state (context, state); + gtk_style_context_add_class (context, GTK_STYLE_CLASS_EXPANDER); if (GTK_ORIENTATION_VERTICAL == orientation) { + gtk_style_context_add_class (context, GTK_STYLE_CLASS_VERTICAL); + if (GTK_TEXT_DIR_RTL == direction) - x = widget->allocation.x + widget->allocation.width - group->priv->expander_size / 2; + x = width; else - x = widget->allocation.x + group->priv->expander_size / 2; - y = widget->allocation.y + widget->allocation.height / 2; + x = 0; + + y = height / 2 - priv->expander_size / 2; } else { - x = widget->allocation.x + widget->allocation.width / 2; - y = widget->allocation.y + group->priv->expander_size / 2; - - /* Unfortunatly gtk_paint_expander() doesn't support rotated drawing - * modes. Luckily the following shady arithmetics produce the desired - * result. */ - expander_style = GTK_EXPANDER_EXPANDED - expander_style; /* XXX */ + gtk_style_context_add_class (context, GTK_STYLE_CLASS_HORIZONTAL); + x = width / 2 - priv->expander_size / 2; + y = 0; } - gtk_paint_expander (widget->style, widget->window, - group->priv->header->state, - &event->area, GTK_WIDGET (group), - "tool-palette-header", x, y, - expander_style); + gtk_render_expander (context, cr, x, y, + priv->expander_size, + priv->expander_size); - return FALSE; -} + gtk_style_context_restore (context); -static void -gtk_tool_item_group_header_size_request_cb (GtkWidget *widget G_GNUC_UNUSED, - GtkRequisition *requisition, - gpointer data) -{ - GtkToolItemGroup *group = GTK_TOOL_ITEM_GROUP (data); - requisition->height = MAX (requisition->height, group->priv->expander_size); + return FALSE; } static void -gtk_tool_item_group_header_clicked_cb (GtkButton *button G_GNUC_UNUSED, +gtk_tool_item_group_header_clicked_cb (GtkButton *button, gpointer data) { GtkToolItemGroup *group = GTK_TOOL_ITEM_GROUP (data); + GtkToolItemGroupPrivate* priv = group->priv; GtkWidget *parent = gtk_widget_get_parent (data); - if (group->priv->collapsed || + if (priv->collapsed || !GTK_IS_TOOL_PALETTE (parent) || !gtk_tool_palette_get_exclusive (GTK_TOOL_PALETTE (parent), data)) - gtk_tool_item_group_set_collapsed (group, !group->priv->collapsed); + gtk_tool_item_group_set_collapsed (group, !priv->collapsed); } static void gtk_tool_item_group_header_adjust_style (GtkToolItemGroup *group) { GtkWidget *alignment = gtk_tool_item_group_get_alignment (group); - GtkWidget *label = gtk_bin_get_child (GTK_BIN (alignment)); + GtkWidget *label_widget = gtk_bin_get_child (GTK_BIN (alignment)); GtkWidget *widget = GTK_WIDGET (group); + GtkToolItemGroupPrivate* priv = group->priv; gint dx = 0, dy = 0; GtkTextDirection direction = gtk_widget_get_direction (widget); gtk_widget_style_get (widget, - "header-spacing", &group->priv->header_spacing, - "expander-size", &group->priv->expander_size, + "header-spacing", &(priv->header_spacing), + "expander-size", &(priv->expander_size), NULL); + + gtk_widget_set_size_request (alignment, -1, priv->expander_size); switch (gtk_tool_shell_get_orientation (GTK_TOOL_SHELL (group))) { case GTK_ORIENTATION_HORIZONTAL: - dy = group->priv->header_spacing + group->priv->expander_size; - gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_NONE); - if (GTK_TEXT_DIR_RTL == direction) - gtk_label_set_angle (GTK_LABEL (label), -90); - else - gtk_label_set_angle (GTK_LABEL (label), 90); - break; + dy = priv->header_spacing + priv->expander_size; + + if (GTK_IS_LABEL (label_widget)) + { + gtk_label_set_ellipsize (GTK_LABEL (label_widget), PANGO_ELLIPSIZE_NONE); + if (GTK_TEXT_DIR_RTL == direction) + gtk_label_set_angle (GTK_LABEL (label_widget), -90); + else + gtk_label_set_angle (GTK_LABEL (label_widget), 90); + } + break; case GTK_ORIENTATION_VERTICAL: - dx = group->priv->header_spacing + group->priv->expander_size; - gtk_label_set_ellipsize (GTK_LABEL (label), group->priv->ellipsize); - gtk_label_set_angle (GTK_LABEL (label), 0); + dx = priv->header_spacing + priv->expander_size; + + if (GTK_IS_LABEL (label_widget)) + { + gtk_label_set_ellipsize (GTK_LABEL (label_widget), priv->ellipsize); + gtk_label_set_angle (GTK_LABEL (label_widget), 0); + } break; } @@ -378,45 +377,42 @@ static void gtk_tool_item_group_init (GtkToolItemGroup *group) { GtkWidget *alignment; - GtkWidget *label; + GtkToolItemGroupPrivate* priv; gtk_widget_set_redraw_on_allocate (GTK_WIDGET (group), FALSE); - group->priv = G_TYPE_INSTANCE_GET_PRIVATE (group, + group->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (group, GTK_TYPE_TOOL_ITEM_GROUP, GtkToolItemGroupPrivate); - group->priv->children = NULL; - group->priv->header_spacing = DEFAULT_HEADER_SPACING; - group->priv->expander_size = DEFAULT_EXPANDER_SIZE; - group->priv->expander_style = GTK_EXPANDER_EXPANDED; + priv->children = NULL; + priv->header_spacing = DEFAULT_HEADER_SPACING; + priv->expander_size = DEFAULT_EXPANDER_SIZE; - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + priv->label_widget = gtk_label_new (NULL); + gtk_widget_set_halign (priv->label_widget, GTK_ALIGN_START); + gtk_widget_set_valign (priv->label_widget, GTK_ALIGN_CENTER); alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0); - gtk_container_add (GTK_CONTAINER (alignment), label); + gtk_container_add (GTK_CONTAINER (alignment), priv->label_widget); gtk_widget_show_all (alignment); gtk_widget_push_composite_child (); - group->priv->header = gtk_button_new (); - gtk_widget_set_composite_name (group->priv->header, "header"); + priv->header = gtk_button_new (); + gtk_widget_set_composite_name (priv->header, "header"); gtk_widget_pop_composite_child (); - g_object_ref_sink (group->priv->header); - gtk_button_set_focus_on_click (GTK_BUTTON (group->priv->header), FALSE); - gtk_container_add (GTK_CONTAINER (group->priv->header), alignment); - gtk_widget_set_parent (group->priv->header, GTK_WIDGET (group)); + g_object_ref_sink (priv->header); + gtk_button_set_focus_on_click (GTK_BUTTON (priv->header), FALSE); + gtk_container_add (GTK_CONTAINER (priv->header), alignment); + gtk_widget_set_parent (priv->header, GTK_WIDGET (group)); gtk_tool_item_group_header_adjust_style (group); - g_signal_connect_after (alignment, "expose-event", - G_CALLBACK (gtk_tool_item_group_header_expose_event_cb), - group); - g_signal_connect_after (alignment, "size-request", - G_CALLBACK (gtk_tool_item_group_header_size_request_cb), + g_signal_connect_after (alignment, "draw", + G_CALLBACK (gtk_tool_item_group_header_draw_cb), group); - g_signal_connect (group->priv->header, "clicked", + g_signal_connect (priv->header, "clicked", G_CALLBACK (gtk_tool_item_group_header_clicked_cb), group); } @@ -431,10 +427,14 @@ gtk_tool_item_group_set_property (GObject *object, switch (prop_id) { - case PROP_NAME: - gtk_tool_item_group_set_name (group, g_value_get_string (value)); + case PROP_LABEL: + gtk_tool_item_group_set_label (group, g_value_get_string (value)); break; + case PROP_LABEL_WIDGET: + gtk_tool_item_group_set_label_widget (group, g_value_get_object (value)); + break; + case PROP_COLLAPSED: gtk_tool_item_group_set_collapsed (group, g_value_get_boolean (value)); break; @@ -442,9 +442,11 @@ gtk_tool_item_group_set_property (GObject *object, case PROP_ELLIPSIZE: gtk_tool_item_group_set_ellipsize (group, g_value_get_enum (value)); break; + case PROP_RELIEF: gtk_tool_item_group_set_header_relief (group, g_value_get_enum(value)); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -461,8 +463,13 @@ gtk_tool_item_group_get_property (GObject *object, switch (prop_id) { - case PROP_NAME: - g_value_set_string (value, gtk_tool_item_group_get_name (group)); + case PROP_LABEL: + g_value_set_string (value, gtk_tool_item_group_get_label (group)); + break; + + case PROP_LABEL_WIDGET: + g_value_set_object (value, + gtk_tool_item_group_get_label_widget (group)); break; case PROP_COLLAPSED: @@ -501,17 +508,26 @@ static void gtk_tool_item_group_dispose (GObject *object) { GtkToolItemGroup *group = GTK_TOOL_ITEM_GROUP (object); + GtkToolItemGroupPrivate* priv = group->priv; - if (group->priv->toplevel) + if (priv->toplevel) { /* disconnect focus tracking handler */ - g_signal_handler_disconnect (group->priv->toplevel, - group->priv->focus_set_id); + g_signal_handler_disconnect (priv->toplevel, + priv->focus_set_id); - group->priv->focus_set_id = 0; - group->priv->toplevel = NULL; + priv->focus_set_id = 0; + priv->toplevel = NULL; + } + + if (priv->settings_connection > 0) + { + g_signal_handler_disconnect (priv->settings, priv->settings_connection); + priv->settings_connection = 0; } + g_clear_object (&priv->settings); + G_OBJECT_CLASS (gtk_tool_item_group_parent_class)->dispose (object); } @@ -533,21 +549,23 @@ static void gtk_tool_item_group_size_request (GtkWidget *widget, GtkRequisition *requisition) { - const gint border_width = GTK_CONTAINER (widget)->border_width; GtkToolItemGroup *group = GTK_TOOL_ITEM_GROUP (widget); + GtkToolItemGroupPrivate* priv = group->priv; GtkOrientation orientation; GtkRequisition item_size; gint requested_rows; + guint border_width; - if (group->priv->children && gtk_tool_item_group_get_name (group)) + if (priv->children && gtk_tool_item_group_get_label_widget (group)) { - gtk_widget_size_request (group->priv->header, requisition); - gtk_widget_show (group->priv->header); + gtk_widget_get_preferred_size (priv->header, + requisition, NULL); + gtk_widget_show (priv->header); } else { requisition->width = requisition->height = 0; - gtk_widget_hide (group->priv->header); + gtk_widget_hide (priv->header); } gtk_tool_item_group_get_item_size (group, &item_size, FALSE, &requested_rows); @@ -559,10 +577,36 @@ gtk_tool_item_group_size_request (GtkWidget *widget, else requisition->height = MAX (requisition->height, item_size.height * requested_rows); + border_width = gtk_container_get_border_width (GTK_CONTAINER (widget)); requisition->width += border_width * 2; requisition->height += border_width * 2; } +static void +gtk_tool_item_group_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + GtkRequisition requisition; + + gtk_tool_item_group_size_request (widget, &requisition); + + *minimum = *natural = requisition.width; +} + +static void +gtk_tool_item_group_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + GtkRequisition requisition; + + gtk_tool_item_group_size_request (widget, &requisition); + + *minimum = *natural = requisition.height; +} + + static gboolean gtk_tool_item_group_is_item_visible (GtkToolItemGroup *group, GtkToolItemGroupChild *child) @@ -580,7 +624,7 @@ gtk_tool_item_group_is_item_visible (GtkToolItemGroup *group, return FALSE; return - (GTK_WIDGET_VISIBLE (child->item)) && + (gtk_widget_get_visible (GTK_WIDGET (child->item))) && (GTK_ORIENTATION_VERTICAL == orientation ? gtk_tool_item_get_visible_vertical (child->item) : gtk_tool_item_get_visible_horizontal (child->item)); @@ -598,19 +642,19 @@ gtk_tool_item_group_real_size_query (GtkWidget *widget, GtkAllocation *allocation, GtkRequisition *inquery) { - const gint border_width = GTK_CONTAINER (widget)->border_width; GtkToolItemGroup *group = GTK_TOOL_ITEM_GROUP (widget); + GtkToolItemGroupPrivate* priv = group->priv; GtkRequisition item_size; GtkAllocation item_area; GtkOrientation orientation; - GtkToolbarStyle style; gint min_rows; + guint border_width; + border_width = gtk_container_get_border_width (GTK_CONTAINER (widget)); orientation = gtk_tool_shell_get_orientation (GTK_TOOL_SHELL (group)); - style = gtk_tool_shell_get_style (GTK_TOOL_SHELL (group)); /* figure out the size of homogeneous items */ gtk_tool_item_group_get_item_size (group, &item_size, TRUE, &min_rows); @@ -620,11 +664,16 @@ gtk_tool_item_group_real_size_query (GtkWidget *widget, else item_size.height = MIN (item_size.height, allocation->height); + item_size.width = MAX (item_size.width, 1); + item_size.height = MAX (item_size.height, 1); + item_area.width = 0; item_area.height = 0; - /* figure out the required columns (n_columns) and rows (n_rows) to place all items */ - if (!group->priv->collapsed || !group->priv->animation || group->priv->animation_timeout) + /* figure out the required columns (n_columns) and rows (n_rows) + * to place all items + */ + if (!priv->collapsed || !priv->animation || priv->animation_timeout) { guint n_columns; gint n_rows; @@ -640,7 +689,7 @@ gtk_tool_item_group_real_size_query (GtkWidget *widget, n_columns = MAX (item_area.width / item_size.width, 1); /* calculate required rows for n_columns columns */ - for (it = group->priv->children; it != NULL; it = it->next) + for (it = priv->children; it != NULL; it = it->next) { GtkToolItemGroupChild *child = it->data; @@ -668,7 +717,8 @@ gtk_tool_item_group_real_size_query (GtkWidget *widget, GtkRequisition req = {0, 0}; guint width; - gtk_widget_size_request (GTK_WIDGET (child->item), &req); + gtk_widget_get_preferred_size (GTK_WIDGET (child->item), + &req, NULL); width = udiv (req.width, item_size.width); col += width; @@ -697,8 +747,10 @@ gtk_tool_item_group_real_size_query (GtkWidget *widget, row_min_width = g_new0 (guint, n_rows); - /* calculate minimal and maximal required cols and minimal required rows */ - for (it = group->priv->children; it != NULL; it = it->next) + /* calculate minimal and maximal required cols and minimal + * required rows + */ + for (it = priv->children; it != NULL; it = it->next) { GtkToolItemGroupChild *child = it->data; @@ -726,7 +778,8 @@ gtk_tool_item_group_real_size_query (GtkWidget *widget, GtkRequisition req = {0, 0}; guint width; - gtk_widget_size_request (GTK_WIDGET (child->item), &req); + gtk_widget_get_preferred_size (GTK_WIDGET (child->item), + &req, NULL); width = udiv (req.width, item_size.width); @@ -747,13 +800,15 @@ gtk_tool_item_group_real_size_query (GtkWidget *widget, min_col = MAX (min_col, row_min_width[i]); } - /* simple linear search for minimal required columns for the given maximal number of rows (n_rows) */ + /* simple linear search for minimal required columns + * for the given maximal number of rows (n_rows) + */ for (n_columns = min_col; n_columns < max_col; n_columns ++) { new_row = TRUE; row = -1; /* calculate required rows for n_columns columns */ - for (it = group->priv->children; it != NULL; it = it->next) + for (it = priv->children; it != NULL; it = it->next) { GtkToolItemGroupChild *child = it->data; @@ -781,7 +836,8 @@ gtk_tool_item_group_real_size_query (GtkWidget *widget, GtkRequisition req = {0, 0}; guint width; - gtk_widget_size_request (GTK_WIDGET (child->item), &req); + gtk_widget_get_preferred_size (GTK_WIDGET (child->item), + &req, NULL); width = udiv (req.width, item_size.width); col += width; @@ -809,11 +865,12 @@ gtk_tool_item_group_real_size_query (GtkWidget *widget, inquery->height = 0; /* figure out header widget size */ - if (GTK_WIDGET_VISIBLE (group->priv->header)) + if (gtk_widget_get_visible (priv->header)) { GtkRequisition child_requisition; - gtk_widget_size_request (group->priv->header, &child_requisition); + gtk_widget_get_preferred_size (priv->header, + &child_requisition, NULL); if (GTK_ORIENTATION_VERTICAL == orientation) inquery->height += child_requisition.height; @@ -827,11 +884,11 @@ gtk_tool_item_group_real_size_query (GtkWidget *widget, } static void -gtk_tool_item_group_real_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) +gtk_tool_item_group_real_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) { - const gint border_width = GTK_CONTAINER (widget)->border_width; GtkToolItemGroup *group = GTK_TOOL_ITEM_GROUP (widget); + GtkToolItemGroupPrivate* priv = group->priv; GtkRequisition child_requisition; GtkAllocation child_allocation; @@ -839,17 +896,19 @@ gtk_tool_item_group_real_size_allocate (GtkWidget *widget, GtkAllocation item_area; GtkOrientation orientation; - GtkToolbarStyle style; GList *it; gint n_columns, n_rows = 1; gint min_rows; + guint border_width; + GtkTextDirection direction; - GtkTextDirection direction = gtk_widget_get_direction (widget); + border_width = gtk_container_get_border_width (GTK_CONTAINER (widget)); + + direction = gtk_widget_get_direction (widget); orientation = gtk_tool_shell_get_orientation (GTK_TOOL_SHELL (group)); - style = gtk_tool_shell_get_style (GTK_TOOL_SHELL (group)); /* chain up */ GTK_WIDGET_CLASS (gtk_tool_item_group_parent_class)->size_allocate (widget, allocation); @@ -858,9 +917,10 @@ gtk_tool_item_group_real_size_allocate (GtkWidget *widget, child_allocation.y = border_width; /* place the header widget */ - if (GTK_WIDGET_VISIBLE (group->priv->header)) + if (gtk_widget_get_visible (priv->header)) { - gtk_widget_size_request (group->priv->header, &child_requisition); + gtk_widget_get_preferred_size (priv->header, + &child_requisition, NULL); if (GTK_ORIENTATION_VERTICAL == orientation) { @@ -876,7 +936,7 @@ gtk_tool_item_group_real_size_allocate (GtkWidget *widget, child_allocation.x = allocation->width - border_width - child_allocation.width; } - gtk_widget_size_allocate (group->priv->header, &child_allocation); + gtk_widget_size_allocate (priv->header, &child_allocation); if (GTK_ORIENTATION_VERTICAL == orientation) child_allocation.y += child_allocation.height; @@ -891,6 +951,9 @@ gtk_tool_item_group_real_size_allocate (GtkWidget *widget, /* figure out the size of homogeneous items */ gtk_tool_item_group_get_item_size (group, &item_size, TRUE, &min_rows); + item_size.width = MAX (item_size.width, 1); + item_size.height = MAX (item_size.height, 1); + /* figure out the available columns and size of item_area */ if (GTK_ORIENTATION_VERTICAL == orientation) { @@ -920,11 +983,11 @@ gtk_tool_item_group_real_size_allocate (GtkWidget *widget, item_area.y = child_allocation.y; /* when expanded or in transition, place the tool items in a grid like layout */ - if (!group->priv->collapsed || !group->priv->animation || group->priv->animation_timeout) + if (!priv->collapsed || !priv->animation || priv->animation_timeout) { gint col = 0, row = 0; - for (it = group->priv->children; it != NULL; it = it->next) + for (it = priv->children; it != NULL; it = it->next) { GtkToolItemGroupChild *child = it->data; gint col_child; @@ -941,7 +1004,8 @@ gtk_tool_item_group_real_size_allocate (GtkWidget *widget, if (!child->homogeneous) { - gtk_widget_size_request (GTK_WIDGET (child->item), &child_requisition); + gtk_widget_get_preferred_size (GTK_WIDGET (child->item), + &child_requisition, NULL); child_requisition.width = MIN (child_requisition.width, item_area.width); } @@ -1010,7 +1074,7 @@ gtk_tool_item_group_real_size_allocate (GtkWidget *widget, else { - for (it = group->priv->children; it != NULL; it = it->next) + for (it = priv->children; it != NULL; it = it->next) { GtkToolItemGroupChild *child = it->data; @@ -1025,16 +1089,17 @@ gtk_tool_item_group_size_allocate (GtkWidget *widget, { gtk_tool_item_group_real_size_allocate (widget, allocation); - if (GTK_WIDGET_MAPPED (widget)) - gdk_window_invalidate_rect (widget->window, NULL, FALSE); + if (gtk_widget_get_mapped (widget)) + gdk_window_invalidate_rect (gtk_widget_get_window (widget), NULL, FALSE); } static void -gtk_tool_item_group_set_focus_cb (GtkWidget *window G_GNUC_UNUSED, +gtk_tool_item_group_set_focus_cb (GtkWidget *window, GtkWidget *widget, gpointer user_data) { GtkAdjustment *adjustment; + GtkAllocation allocation, p_allocation; GtkWidget *p; /* Find this group's parent widget in the focused widget's anchestry. */ @@ -1050,48 +1115,51 @@ gtk_tool_item_group_set_focus_cb (GtkWidget *window G_GNUC_UNUSED, /* Check that the focused widgets is fully visible within * the group's parent widget and make it visible otherwise. */ - adjustment = gtk_tool_palette_get_hadjustment (GTK_TOOL_PALETTE (p)); - adjustment = gtk_tool_palette_get_vadjustment (GTK_TOOL_PALETTE (p)); + adjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (p)); if (adjustment) { int y; + gtk_widget_get_allocation (widget, &allocation); + gtk_widget_get_allocation (p, &p_allocation); + /* Handle vertical adjustment. */ if (gtk_widget_translate_coordinates (widget, p, 0, 0, NULL, &y) && y < 0) { - y += adjustment->value; - gtk_adjustment_clamp_page (adjustment, y, y + widget->allocation.height); + y += gtk_adjustment_get_value (adjustment); + gtk_adjustment_clamp_page (adjustment, y, y + allocation.height); } - else if (gtk_widget_translate_coordinates - (widget, p, 0, widget->allocation.height, NULL, &y) && - y > p->allocation.height) + else if (gtk_widget_translate_coordinates (widget, p, 0, allocation.height, NULL, &y) && + y > p_allocation.height) { - y += adjustment->value; - gtk_adjustment_clamp_page (adjustment, y - widget->allocation.height, y); + y += gtk_adjustment_get_value (adjustment); + gtk_adjustment_clamp_page (adjustment, y - allocation.height, y); } } - adjustment = gtk_tool_palette_get_hadjustment (GTK_TOOL_PALETTE (p)); + adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (p)); if (adjustment) { int x; + gtk_widget_get_allocation (widget, &allocation); + gtk_widget_get_allocation (p, &p_allocation); + /* Handle horizontal adjustment. */ if (gtk_widget_translate_coordinates (widget, p, 0, 0, &x, NULL) && x < 0) { - x += adjustment->value; - gtk_adjustment_clamp_page (adjustment, x, x + widget->allocation.width); + x += gtk_adjustment_get_value (adjustment); + gtk_adjustment_clamp_page (adjustment, x, x + allocation.width); } - else if (gtk_widget_translate_coordinates - (widget, p, widget->allocation.width, 0, &x, NULL) && - x > p->allocation.width) + else if (gtk_widget_translate_coordinates (widget, p, allocation.width, 0, &x, NULL) && + x > p_allocation.width) { - x += adjustment->value; - gtk_adjustment_clamp_page (adjustment, x - widget->allocation.width, x); + x += gtk_adjustment_get_value (adjustment); + gtk_adjustment_clamp_page (adjustment, x - allocation.width, x); } return; @@ -1103,16 +1171,18 @@ static void gtk_tool_item_group_set_toplevel_window (GtkToolItemGroup *group, GtkWidget *toplevel) { - if (toplevel != group->priv->toplevel) + GtkToolItemGroupPrivate* priv = group->priv; + + if (toplevel != priv->toplevel) { - if (group->priv->toplevel) + if (priv->toplevel) { /* Disconnect focus tracking handler. */ - g_signal_handler_disconnect (group->priv->toplevel, - group->priv->focus_set_id); + g_signal_handler_disconnect (priv->toplevel, + priv->focus_set_id); - group->priv->focus_set_id = 0; - group->priv->toplevel = NULL; + priv->focus_set_id = 0; + priv->toplevel = NULL; } if (toplevel) @@ -1126,12 +1196,12 @@ gtk_tool_item_group_set_toplevel_window (GtkToolItemGroup *group, * 3) Catch focus grabs not only for direct children, * but also for nested widgets. */ - group->priv->focus_set_id = + priv->focus_set_id = g_signal_connect (toplevel, "set-focus", G_CALLBACK (gtk_tool_item_group_set_focus_cb), group); - group->priv->toplevel = toplevel; + priv->toplevel = toplevel; } } } @@ -1139,40 +1209,45 @@ gtk_tool_item_group_set_toplevel_window (GtkToolItemGroup *group, static void gtk_tool_item_group_realize (GtkWidget *widget) { + GtkAllocation allocation; GtkWidget *toplevel_window; - const gint border_width = GTK_CONTAINER (widget)->border_width; - gint attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + GdkWindow *window; GdkWindowAttr attributes; - GdkDisplay *display; + gint attributes_mask; + guint border_width; + GtkStyleContext *context; + + gtk_widget_set_realized (widget, TRUE); + + border_width = gtk_container_get_border_width (GTK_CONTAINER (widget)); + context = gtk_widget_get_style_context (widget); + + gtk_widget_get_allocation (widget, &allocation); attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x + border_width; - attributes.y = widget->allocation.y + border_width; - attributes.width = widget->allocation.width - border_width * 2; - attributes.height = widget->allocation.height - border_width * 2; + attributes.x = allocation.x + border_width; + attributes.y = allocation.y + border_width; + attributes.width = allocation.width - border_width * 2; + attributes.height = allocation.height - border_width * 2; attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK - | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - | GDK_BUTTON_MOTION_MASK; + attributes.event_mask = gtk_widget_get_events (widget) + | GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK + | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + | GDK_BUTTON_MOTION_MASK; + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); + window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gtk_widget_set_window (widget, window); - display = gdk_drawable_get_display (widget->window); + gtk_widget_register_window (widget, window); - if (gdk_display_supports_composite (display)) - gdk_window_set_composited (widget->window, TRUE); - - gdk_window_set_user_data (widget->window, widget); - widget->style = gtk_style_attach (widget->style, widget->window); - gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); + gtk_style_context_set_background (context, window); gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) gtk_widget_set_parent_window, - widget->window); + window); gtk_widget_queue_resize_no_redraw (widget); @@ -1189,11 +1264,10 @@ gtk_tool_item_group_unrealize (GtkWidget *widget) } static void -gtk_tool_item_group_style_set (GtkWidget *widget, - GtkStyle *previous_style) +gtk_tool_item_group_style_updated (GtkWidget *widget) { gtk_tool_item_group_header_adjust_style (GTK_TOOL_ITEM_GROUP (widget)); - GTK_WIDGET_CLASS (gtk_tool_item_group_parent_class)->style_set (widget, previous_style); + GTK_WIDGET_CLASS (gtk_tool_item_group_parent_class)->style_updated (widget); } static void @@ -1212,12 +1286,14 @@ gtk_tool_item_group_remove (GtkContainer *container, GtkWidget *child) { GtkToolItemGroup *group; + GtkToolItemGroupPrivate* priv; GList *it; g_return_if_fail (GTK_IS_TOOL_ITEM_GROUP (container)); group = GTK_TOOL_ITEM_GROUP (container); + priv = group->priv; - for (it = group->priv->children; it != NULL; it = it->next) + for (it = priv->children; it != NULL; it = it->next) { GtkToolItemGroupChild *child_info = it->data; @@ -1227,7 +1303,7 @@ gtk_tool_item_group_remove (GtkContainer *container, gtk_widget_unparent (child); g_free (child_info); - group->priv->children = g_list_delete_link (group->priv->children, it); + priv->children = g_list_delete_link (priv->children, it); gtk_widget_queue_resize (GTK_WIDGET (container)); break; @@ -1242,18 +1318,19 @@ gtk_tool_item_group_forall (GtkContainer *container, gpointer callback_data) { GtkToolItemGroup *group = GTK_TOOL_ITEM_GROUP (container); + GtkToolItemGroupPrivate* priv = group->priv; GList *children; - if (internals && group->priv->header) - callback (group->priv->header, callback_data); + if (internals && priv->header) + callback (priv->header, callback_data); - children = group->priv->children; + children = priv->children; while (children) { GtkToolItemGroupChild *child = children->data; children = children->next; /* store pointer before call to callback because the child pointer is invalid if the - child->item is removed from the item group + child->item is removed from the item group in callback */ callback (GTK_WIDGET (child->item), callback_data); @@ -1261,7 +1338,7 @@ gtk_tool_item_group_forall (GtkContainer *container, } static GType -gtk_tool_item_group_child_type (GtkContainer *container G_GNUC_UNUSED) +gtk_tool_item_group_child_type (GtkContainer *container) { return GTK_TYPE_TOOL_ITEM; } @@ -1374,7 +1451,9 @@ gtk_tool_item_group_set_item_packing (GtkToolItemGroup *group, gtk_widget_thaw_child_notify (GTK_WIDGET (item)); - if (changed && GTK_WIDGET_VISIBLE (group) && GTK_WIDGET_VISIBLE (item)) + if (changed + && gtk_widget_get_visible (GTK_WIDGET (group)) + && gtk_widget_get_visible (GTK_WIDGET (item))) gtk_widget_queue_resize (GTK_WIDGET (group)); } @@ -1498,12 +1577,13 @@ gtk_tool_item_group_class_init (GtkToolItemGroupClass *cls) oclass->finalize = gtk_tool_item_group_finalize; oclass->dispose = gtk_tool_item_group_dispose; - wclass->size_request = gtk_tool_item_group_size_request; - wclass->size_allocate = gtk_tool_item_group_size_allocate; - wclass->realize = gtk_tool_item_group_realize; - wclass->unrealize = gtk_tool_item_group_unrealize; - wclass->style_set = gtk_tool_item_group_style_set; - wclass->screen_changed = gtk_tool_item_group_screen_changed; + wclass->get_preferred_width = gtk_tool_item_group_get_preferred_width; + wclass->get_preferred_height = gtk_tool_item_group_get_preferred_height; + wclass->size_allocate = gtk_tool_item_group_size_allocate; + wclass->realize = gtk_tool_item_group_realize; + wclass->unrealize = gtk_tool_item_group_unrealize; + wclass->style_updated = gtk_tool_item_group_style_updated; + wclass->screen_changed = gtk_tool_item_group_screen_changed; cclass->add = gtk_tool_item_group_add; cclass->remove = gtk_tool_item_group_remove; @@ -1512,37 +1592,40 @@ gtk_tool_item_group_class_init (GtkToolItemGroupClass *cls) cclass->set_child_property = gtk_tool_item_group_set_child_property; cclass->get_child_property = gtk_tool_item_group_get_child_property; - g_object_class_install_property (oclass, PROP_NAME, - g_param_spec_string ("name", - P_("Name"), - P_("The name of this item group"), - DEFAULT_NAME, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + g_object_class_install_property (oclass, PROP_LABEL, + g_param_spec_string ("label", + P_("Label"), + P_("The human-readable title of this item group"), + DEFAULT_LABEL, + GTK_PARAM_READWRITE)); + + g_object_class_install_property (oclass, PROP_LABEL_WIDGET, + g_param_spec_object ("label-widget", + P_("Label widget"), + P_("A widget to display in place of the usual label"), + GTK_TYPE_WIDGET, + GTK_PARAM_READWRITE)); g_object_class_install_property (oclass, PROP_COLLAPSED, g_param_spec_boolean ("collapsed", P_("Collapsed"), - P_("Wether the group has been collapsed and items are hidden"), + P_("Whether the group has been collapsed and items are hidden"), DEFAULT_COLLAPSED, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + GTK_PARAM_READWRITE)); g_object_class_install_property (oclass, PROP_ELLIPSIZE, g_param_spec_enum ("ellipsize", P_("ellipsize"), P_("Ellipsize for item group headers"), PANGO_TYPE_ELLIPSIZE_MODE, DEFAULT_ELLIPSIZE, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + GTK_PARAM_READWRITE)); - g_object_class_install_property (oclass, PROP_ELLIPSIZE, + g_object_class_install_property (oclass, PROP_RELIEF, g_param_spec_enum ("header-relief", - P_("header-relif"), + P_("Header Relief"), P_("Relief of the group header button"), GTK_TYPE_RELIEF_STYLE, GTK_RELIEF_NORMAL, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + GTK_PARAM_READWRITE)); gtk_widget_class_install_style_property (wclass, g_param_spec_int ("expander-size", @@ -1551,8 +1634,7 @@ gtk_tool_item_group_class_init (GtkToolItemGroupClass *cls) 0, G_MAXINT, DEFAULT_EXPANDER_SIZE, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + GTK_PARAM_READABLE)); gtk_widget_class_install_style_property (wclass, g_param_spec_int ("header-spacing", @@ -1561,40 +1643,35 @@ gtk_tool_item_group_class_init (GtkToolItemGroupClass *cls) 0, G_MAXINT, DEFAULT_HEADER_SPACING, - G_PARAM_READABLE | G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + GTK_PARAM_READABLE)); gtk_container_class_install_child_property (cclass, CHILD_PROP_HOMOGENEOUS, g_param_spec_boolean ("homogeneous", P_("Homogeneous"), P_("Whether the item should be the same size as other homogeneous items"), TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + GTK_PARAM_READWRITE)); gtk_container_class_install_child_property (cclass, CHILD_PROP_EXPAND, g_param_spec_boolean ("expand", P_("Expand"), - P_("Whether the item should receive extra space when the toolbar grows"), + P_("Whether the item should receive extra space when the group grows"), FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + GTK_PARAM_READWRITE)); gtk_container_class_install_child_property (cclass, CHILD_PROP_FILL, g_param_spec_boolean ("fill", P_("Fill"), - P_("Whether the item should fill the avaiable space"), + P_("Whether the item should fill the available space"), TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + GTK_PARAM_READWRITE)); gtk_container_class_install_child_property (cclass, CHILD_PROP_NEW_ROW, g_param_spec_boolean ("new-row", P_("New Row"), P_("Whether the item should start a new row"), FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + GTK_PARAM_READWRITE)); gtk_container_class_install_child_property (cclass, CHILD_PROP_POSITION, g_param_spec_int ("position", @@ -1603,122 +1680,181 @@ gtk_tool_item_group_class_init (GtkToolItemGroupClass *cls) 0, G_MAXINT, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + GTK_PARAM_READWRITE)); g_type_class_add_private (cls, sizeof (GtkToolItemGroupPrivate)); } /** * gtk_tool_item_group_new: - * @name: the name of the new group. + * @label: the label of the new group * - * Creates a new tool item group with name @name. + * Creates a new tool item group with label @label. * * Returns: a new #GtkToolItemGroup. * - * Since: 2.18 + * Since: 2.20 */ GtkWidget* -gtk_tool_item_group_new (const gchar *name) +gtk_tool_item_group_new (const gchar *label) { - return g_object_new (GTK_TYPE_TOOL_ITEM_GROUP, "name", name, NULL); + return g_object_new (GTK_TYPE_TOOL_ITEM_GROUP, "label", label, NULL); } /** - * gtk_tool_item_group_set_name: - * @group: an #GtkToolItemGroup. - * @name: the new name of of the group. + * gtk_tool_item_group_set_label: + * @group: a #GtkToolItemGroup + * @label: the new human-readable label of of the group * - * Sets the name of the tool item group. The name is displayed in the header + * Sets the label of the tool item group. The label is displayed in the header * of the group. * - * Since: 2.18 + * Since: 2.20 */ void -gtk_tool_item_group_set_name (GtkToolItemGroup *group, - const gchar *name) +gtk_tool_item_group_set_label (GtkToolItemGroup *group, + const gchar *label) { - const gchar *current_name; - GtkWidget *label; - g_return_if_fail (GTK_IS_TOOL_ITEM_GROUP (group)); - current_name = gtk_tool_item_group_get_name (group); - if (current_name != name && (!current_name || !name || strcmp (current_name, name))) + if (!label) + gtk_tool_item_group_set_label_widget (group, NULL); + else { - label = gtk_tool_item_group_get_label (group); - gtk_label_set_text (GTK_LABEL (label), name); + GtkWidget *child = gtk_label_new (label); + gtk_widget_show (child); - if (name && group->priv->children) - gtk_widget_show (group->priv->header); - else - gtk_widget_hide (group->priv->header); + gtk_tool_item_group_set_label_widget (group, child); + } + + g_object_notify (G_OBJECT (group), "label"); +} + +/** + * gtk_tool_item_group_set_label_widget: + * @group: a #GtkToolItemGroup + * @label_widget: the widget to be displayed in place of the usual label + * + * Sets the label of the tool item group. + * The label widget is displayed in the header of the group, in place + * of the usual label. + * + * Since: 2.20 + */ +void +gtk_tool_item_group_set_label_widget (GtkToolItemGroup *group, + GtkWidget *label_widget) +{ + GtkToolItemGroupPrivate* priv; + GtkWidget *alignment; + + g_return_if_fail (GTK_IS_TOOL_ITEM_GROUP (group)); + g_return_if_fail (label_widget == NULL || GTK_IS_WIDGET (label_widget)); + g_return_if_fail (label_widget == NULL || gtk_widget_get_parent (label_widget) == NULL); + + priv = group->priv; + + if (priv->label_widget == label_widget) + return; + + alignment = gtk_tool_item_group_get_alignment (group); - g_object_notify (G_OBJECT (group), "name"); + if (priv->label_widget) + { + gtk_widget_set_state_flags (priv->label_widget, 0, TRUE); + gtk_container_remove (GTK_CONTAINER (alignment), priv->label_widget); } + + + if (label_widget) + gtk_container_add (GTK_CONTAINER (alignment), label_widget); + + priv->label_widget = label_widget; + + if (gtk_widget_get_visible (GTK_WIDGET (group))) + gtk_widget_queue_resize (GTK_WIDGET (group)); + + /* Only show the header widget if the group has children: */ + if (label_widget && priv->children) + gtk_widget_show (priv->header); + else + gtk_widget_hide (priv->header); + + g_object_freeze_notify (G_OBJECT (group)); + g_object_notify (G_OBJECT (group), "label-widget"); + g_object_notify (G_OBJECT (group), "label"); + g_object_thaw_notify (G_OBJECT (group)); } /** - * gtk_tool_item_group_header_relief: - * @group: an #GtkToolItemGroup. - * @style: The GtkReliefStyle + * gtk_tool_item_group_set_header_relief: + * @group: a #GtkToolItemGroup + * @style: the #GtkReliefStyle * - * Set the button relief of the group header. See #gtk_button_set_relief for - * details + * Set the button relief of the group header. + * See gtk_button_set_relief() for details. * - * Since: 2.18 + * Since: 2.20 */ void -gtk_tool_item_group_set_header_relief (GtkToolItemGroup *group, - GtkReliefStyle style) +gtk_tool_item_group_set_header_relief (GtkToolItemGroup *group, + GtkReliefStyle style) { g_return_if_fail (GTK_IS_TOOL_ITEM_GROUP (group)); - gtk_button_set_relief (GTK_BUTTON(group->priv->header), style); + + gtk_button_set_relief (GTK_BUTTON (group->priv->header), style); } static gint64 gtk_tool_item_group_get_animation_timestamp (GtkToolItemGroup *group) { - GTimeVal now; - g_source_get_current_time (group->priv->animation_timeout, &now); - return (now.tv_sec * G_USEC_PER_SEC + now.tv_usec - group->priv->animation_start) / 1000; + return (g_source_get_time (group->priv->animation_timeout) - + group->priv->animation_start) / 1000; } static void gtk_tool_item_group_force_expose (GtkToolItemGroup *group) { - if (GTK_WIDGET_REALIZED (group->priv->header)) + GtkToolItemGroupPrivate* priv = group->priv; + GtkWidget *widget = GTK_WIDGET (group); + + if (gtk_widget_get_realized (priv->header)) { + GtkAllocation alignment_allocation; GtkWidget *alignment = gtk_tool_item_group_get_alignment (group); GdkRectangle area; - + /* Find the header button's arrow area... */ - area.x = alignment->allocation.x; - area.y = alignment->allocation.y + (alignment->allocation.height - group->priv->expander_size) / 2; - area.height = group->priv->expander_size; - area.width = group->priv->expander_size; + gtk_widget_get_allocation (alignment, &alignment_allocation); + area.x = alignment_allocation.x; + area.y = alignment_allocation.y + (alignment_allocation.height - priv->expander_size) / 2; + area.height = priv->expander_size; + area.width = priv->expander_size; /* ... and invalidated it to get it animated. */ - gdk_window_invalidate_rect (group->priv->header->window, &area, TRUE); + gdk_window_invalidate_rect (gtk_widget_get_window (priv->header), &area, TRUE); } - if (GTK_WIDGET_REALIZED (group)) + if (gtk_widget_get_realized (widget)) { - GtkWidget *widget = GTK_WIDGET (group); + GtkAllocation allocation; GtkWidget *parent = gtk_widget_get_parent (widget); int x, y, width, height; /* Find the tool item area button's arrow area... */ - width = widget->allocation.width; - height = widget->allocation.height; + gtk_widget_get_allocation (widget, &allocation); + width = allocation.width; + height = allocation.height; gtk_widget_translate_coordinates (widget, parent, 0, 0, &x, &y); - if (GTK_WIDGET_VISIBLE (group->priv->header)) + if (gtk_widget_get_visible (priv->header)) { - height -= group->priv->header->allocation.height; - y += group->priv->header->allocation.height; + GtkAllocation header_allocation; + + gtk_widget_get_allocation (priv->header, &header_allocation); + height -= header_allocation.height; + y += header_allocation.height; } /* ... and invalidated it to get it animated. */ @@ -1730,102 +1866,83 @@ static gboolean gtk_tool_item_group_animation_cb (gpointer data) { GtkToolItemGroup *group = GTK_TOOL_ITEM_GROUP (data); + GtkToolItemGroupPrivate* priv = group->priv; gint64 timestamp = gtk_tool_item_group_get_animation_timestamp (group); + gboolean retval; + + gdk_threads_enter (); /* Enque this early to reduce number of expose events. */ gtk_widget_queue_resize_no_redraw (GTK_WIDGET (group)); - /* Figure out current style of the expander arrow. */ - if (group->priv->collapsed) - { - if (group->priv->expander_style == GTK_EXPANDER_EXPANDED) - group->priv->expander_style = GTK_EXPANDER_SEMI_COLLAPSED; - else - group->priv->expander_style = GTK_EXPANDER_COLLAPSED; - } - else - { - if (group->priv->expander_style == GTK_EXPANDER_COLLAPSED) - group->priv->expander_style = GTK_EXPANDER_SEMI_EXPANDED; - else - group->priv->expander_style = GTK_EXPANDER_EXPANDED; - } - gtk_tool_item_group_force_expose (group); /* Finish animation when done. */ if (timestamp >= ANIMATION_DURATION) - group->priv->animation_timeout = NULL; + priv->animation_timeout = NULL; - /* Ensure that all composited windows and child windows are repainted, before - * the parent widget gets its expose-event. This is needed to avoid heavy - * rendering artifacts. GTK+ should take care about this issue by itself I - * guess, but currently it doesn't. Also I don't understand the parameters - * of this issue well enough yet, to file a bug report. - */ - gdk_window_process_updates (GTK_WIDGET (group)->window, TRUE); + retval = (priv->animation_timeout != NULL); + + gdk_threads_leave (); - return (group->priv->animation_timeout != NULL); + return retval; } /** * gtk_tool_item_group_set_collapsed: - * @group: an #GtkToolItemGroup. - * @collapsed: whether the @group should be collapsed or expanded. + * @group: a #GtkToolItemGroup + * @collapsed: whether the @group should be collapsed or expanded * * Sets whether the @group should be collapsed or expanded. * - * Since: 2.18 + * Since: 2.20 */ void gtk_tool_item_group_set_collapsed (GtkToolItemGroup *group, gboolean collapsed) { - g_return_if_fail (GTK_IS_TOOL_ITEM_GROUP (group)); GtkWidget *parent; + GtkToolItemGroupPrivate* priv; + + g_return_if_fail (GTK_IS_TOOL_ITEM_GROUP (group)); + + priv = group->priv; parent = gtk_widget_get_parent (GTK_WIDGET (group)); if (GTK_IS_TOOL_PALETTE (parent) && !collapsed) _gtk_tool_palette_set_expanding_child (GTK_TOOL_PALETTE (parent), GTK_WIDGET (group)); - if (collapsed != group->priv->collapsed) + if (collapsed != priv->collapsed) { - if (group->priv->animation) + if (priv->animation) { - GTimeVal now; - - g_get_current_time (&now); - - if (group->priv->animation_timeout) - g_source_destroy (group->priv->animation_timeout); + if (priv->animation_timeout) + g_source_destroy (priv->animation_timeout); - group->priv->animation_start = (now.tv_sec * G_USEC_PER_SEC + now.tv_usec); - group->priv->animation_timeout = g_timeout_source_new (ANIMATION_TIMEOUT); + priv->animation_start = g_get_monotonic_time (); + priv->animation_timeout = g_timeout_source_new (ANIMATION_TIMEOUT); - g_source_set_callback (group->priv->animation_timeout, + g_source_set_callback (priv->animation_timeout, gtk_tool_item_group_animation_cb, group, NULL); - - g_source_attach (group->priv->animation_timeout, NULL); - } - else - { - group->priv->expander_style = GTK_EXPANDER_COLLAPSED; - gtk_tool_item_group_force_expose (group); + g_source_attach (priv->animation_timeout, NULL); } - group->priv->collapsed = collapsed; + else + gtk_tool_item_group_force_expose (group); + + priv->collapsed = collapsed; g_object_notify (G_OBJECT (group), "collapsed"); } } /** * gtk_tool_item_group_set_ellipsize: - * @group: an #GtkToolItemGroup. - * @ellipsize: the #PangoEllipsizeMode labels in @group should use. + * @group: a #GtkToolItemGroup + * @ellipsize: the #PangoEllipsizeMode labels in @group should use * * Sets the ellipsization mode which should be used by labels in @group. * - * Since: 2.18 + * Since: 2.20 */ void gtk_tool_item_group_set_ellipsize (GtkToolItemGroup *group, @@ -1843,86 +1960,115 @@ gtk_tool_item_group_set_ellipsize (GtkToolItemGroup *group, } /** - * gtk_tool_item_group_get_name: - * @group: an #GtkToolItemGroup. + * gtk_tool_item_group_get_label: + * @group: a #GtkToolItemGroup * - * Gets the name of @group. + * Gets the label of @group. * - * Returns: the name of @group. The name is an internal string of @group and must not be modified. + * Returns: the label of @group. The label is an internal string of @group + * and must not be modified. Note that %NULL is returned if a custom + * label has been set with gtk_tool_item_group_set_label_widget() * - * Since: 2.18 + * Since: 2.20 */ -G_CONST_RETURN gchar* -gtk_tool_item_group_get_name (GtkToolItemGroup *group) +const gchar* +gtk_tool_item_group_get_label (GtkToolItemGroup *group) { - GtkWidget *label; + GtkToolItemGroupPrivate *priv; + + g_return_val_if_fail (GTK_IS_TOOL_ITEM_GROUP (group), NULL); + + priv = group->priv; - g_return_val_if_fail (GTK_IS_TOOL_ITEM_GROUP (group), DEFAULT_NAME); + if (GTK_IS_LABEL (priv->label_widget)) + return gtk_label_get_label (GTK_LABEL (priv->label_widget)); + else + return NULL; +} + +/** + * gtk_tool_item_group_get_label_widget: + * @group: a #GtkToolItemGroup + * + * Gets the label widget of @group. + * See gtk_tool_item_group_set_label_widget(). + * + * Returns: (transfer none): the label widget of @group + * + * Since: 2.20 + */ +GtkWidget* +gtk_tool_item_group_get_label_widget (GtkToolItemGroup *group) +{ + GtkWidget *alignment = gtk_tool_item_group_get_alignment (group); - label = gtk_tool_item_group_get_label (group); - return gtk_label_get_text (GTK_LABEL (label)); + return gtk_bin_get_child (GTK_BIN (alignment)); } /** * gtk_tool_item_group_get_collapsed: - * @group: an GtkToolItemGroup. + * @group: a GtkToolItemGroup * * Gets whether @group is collapsed or expanded. * - * Returns: %TRUE if @group is collapsed, %FALSE if it is expanded. + * Returns: %TRUE if @group is collapsed, %FALSE if it is expanded * - * Since: 2.18 + * Since: 2.20 */ gboolean gtk_tool_item_group_get_collapsed (GtkToolItemGroup *group) { g_return_val_if_fail (GTK_IS_TOOL_ITEM_GROUP (group), DEFAULT_COLLAPSED); + return group->priv->collapsed; } /** * gtk_tool_item_group_get_ellipsize: - * @group: an #GtkToolItemGroup. + * @group: a #GtkToolItemGroup * * Gets the ellipsization mode of @group. * - * Returns: the #PangoEllipsizeMode of @group. + * Returns: the #PangoEllipsizeMode of @group * - * Since: 2.18 + * Since: 2.20 */ PangoEllipsizeMode gtk_tool_item_group_get_ellipsize (GtkToolItemGroup *group) { g_return_val_if_fail (GTK_IS_TOOL_ITEM_GROUP (group), DEFAULT_ELLIPSIZE); + return group->priv->ellipsize; } /** * gtk_tool_item_group_get_header_relief: - * @group: an #GtkToolItemGroup. + * @group: a #GtkToolItemGroup * * Gets the relief mode of the header button of @group. * * Returns: the #GtkReliefStyle * - * Since: 2.18 + * Since: 2.20 */ GtkReliefStyle gtk_tool_item_group_get_header_relief (GtkToolItemGroup *group) { g_return_val_if_fail (GTK_IS_TOOL_ITEM_GROUP (group), GTK_RELIEF_NORMAL); + return gtk_button_get_relief (GTK_BUTTON (group->priv->header)); } /** * gtk_tool_item_group_insert: - * @group: an #GtkToolItemGroup. - * @item: the #GtkToolItem to insert into @group. - * @position: the position of @item in @group, starting with 0. The position -1 means end of list. + * @group: a #GtkToolItemGroup + * @item: the #GtkToolItem to insert into @group + * @position: the position of @item in @group, starting with 0. + * The position -1 means end of list. * * Inserts @item at @position in the list of children of @group. * - * Since: 2.18 + * Since: 2.20 */ void gtk_tool_item_group_insert (GtkToolItemGroup *group, @@ -1960,13 +2106,15 @@ gtk_tool_item_group_insert (GtkToolItemGroup *group, /** * gtk_tool_item_group_set_item_position: - * @group: an #GtkToolItemGroup. - * @item: the #GtkToolItem to move to a new position, should be a child of @group. - * @position: the new position of @item in @group, starting with 0. The position -1 means end of list. + * @group: a #GtkToolItemGroup + * @item: the #GtkToolItem to move to a new position, should + * be a child of @group. + * @position: the new position of @item in @group, starting with 0. + * The position -1 means end of list. * * Sets the position of @item in the list of children of @group. * - * Since: 2.18 + * Since: 2.20 */ void gtk_tool_item_group_set_item_position (GtkToolItemGroup *group, @@ -1976,37 +2124,39 @@ gtk_tool_item_group_set_item_position (GtkToolItemGroup *group, gint old_position; GList *link; GtkToolItemGroupChild *child; + GtkToolItemGroupPrivate* priv; g_return_if_fail (GTK_IS_TOOL_ITEM_GROUP (group)); g_return_if_fail (GTK_IS_TOOL_ITEM (item)); - g_return_if_fail (position >= -1); child = gtk_tool_item_group_get_child (group, item, &old_position, &link); + priv = group->priv; g_return_if_fail (child != NULL); if (position == old_position) return; - group->priv->children = g_list_delete_link (group->priv->children, link); - group->priv->children = g_list_insert (group->priv->children, child, position); + priv->children = g_list_delete_link (priv->children, link); + priv->children = g_list_insert (priv->children, child, position); gtk_widget_child_notify (GTK_WIDGET (item), "position"); - if (GTK_WIDGET_VISIBLE (group) && GTK_WIDGET_VISIBLE (item)) + if (gtk_widget_get_visible (GTK_WIDGET (group)) && + gtk_widget_get_visible (GTK_WIDGET (item))) gtk_widget_queue_resize (GTK_WIDGET (group)); } /** * gtk_tool_item_group_get_item_position: - * @group: an #GtkToolItemGroup. - * @item: a #GtkToolItem. + * @group: a #GtkToolItemGroup + * @item: a #GtkToolItem * * Gets the position of @item in @group as index. * - * Returns: the index of @item in @group or -1 if @item is no child of @group. + * Returns: the index of @item in @group or -1 if @item is no child of @group * - * Since: 2.18 + * Since: 2.20 */ gint gtk_tool_item_group_get_item_position (GtkToolItemGroup *group, @@ -2025,13 +2175,13 @@ gtk_tool_item_group_get_item_position (GtkToolItemGroup *group, /** * gtk_tool_item_group_get_n_items: - * @group: an #GtkToolItemGroup. + * @group: a #GtkToolItemGroup * - * Gets the number of tool items in group. + * Gets the number of tool items in @group. * - * Returns: the number of tool items in group. + * Returns: the number of tool items in @group * - * Since: 2.18 + * Since: 2.20 */ guint gtk_tool_item_group_get_n_items (GtkToolItemGroup *group) @@ -2043,14 +2193,14 @@ gtk_tool_item_group_get_n_items (GtkToolItemGroup *group) /** * gtk_tool_item_group_get_nth_item: - * @group: an #GtkToolItemGroup. - * @index: the index. + * @group: a #GtkToolItemGroup + * @index: the index * - * Gets the tool item at index in group. + * Gets the tool item at @index in group. * - * Returns: the #GtkToolItem at index. + * Returns: (transfer none): the #GtkToolItem at index * - * Since: 2.18 + * Since: 2.20 */ GtkToolItem* gtk_tool_item_group_get_nth_item (GtkToolItemGroup *group, @@ -2065,34 +2215,32 @@ gtk_tool_item_group_get_nth_item (GtkToolItemGroup *group, return child != NULL ? child->item : NULL; } -/** +/** * gtk_tool_item_group_get_drop_item: - * @group: an #GtkToolItemGroup. - * @x: the x position. - * @y: the y position. + * @group: a #GtkToolItemGroup + * @x: the x position + * @y: the y position * * Gets the tool item at position (x, y). * - * Returns: the #GtkToolItem at position (x, y). + * Returns: (transfer none): the #GtkToolItem at position (x, y) * - * Since: 2.18 + * Since: 2.20 */ GtkToolItem* gtk_tool_item_group_get_drop_item (GtkToolItemGroup *group, gint x, gint y) { - GtkAllocation *allocation; - GtkOrientation orientation; + GtkAllocation allocation; GList *it; g_return_val_if_fail (GTK_IS_TOOL_ITEM_GROUP (group), NULL); - allocation = >K_WIDGET (group)->allocation; - orientation = gtk_tool_shell_get_orientation (GTK_TOOL_SHELL (group)); + gtk_widget_get_allocation (GTK_WIDGET (group), &allocation); - g_return_val_if_fail (x >= 0 && x < allocation->width, NULL); - g_return_val_if_fail (y >= 0 && y < allocation->height, NULL); + g_return_val_if_fail (x >= 0 && x < allocation.width, NULL); + g_return_val_if_fail (y >= 0 && y < allocation.height, NULL); for (it = group->priv->children; it != NULL; it = it->next) { @@ -2103,13 +2251,13 @@ gtk_tool_item_group_get_drop_item (GtkToolItemGroup *group, if (!item || !gtk_tool_item_group_is_item_visible (group, child)) continue; - allocation = >K_WIDGET (item)->allocation; + gtk_widget_get_allocation (GTK_WIDGET (item), &allocation); - x0 = x - allocation->x; - y0 = y - allocation->y; + x0 = x - allocation.x; + y0 = y - allocation.y; - if (x0 >= 0 && x0 < allocation->width && - y0 >= 0 && y0 < allocation->height) + if (x0 >= 0 && x0 < allocation.width && + y0 >= 0 && y0 < allocation.height) return item; } @@ -2126,15 +2274,10 @@ _gtk_tool_item_group_item_size_request (GtkToolItemGroup *group, GList *it; gint rows = 0; gboolean new_row = TRUE; - GtkOrientation orientation; - GtkToolbarStyle style; g_return_if_fail (GTK_IS_TOOL_ITEM_GROUP (group)); g_return_if_fail (NULL != item_size); - orientation = gtk_tool_shell_get_orientation (GTK_TOOL_SHELL (group)); - style = gtk_tool_shell_get_style (GTK_TOOL_SHELL (group)); - item_size->width = item_size->height = 0; for (it = group->priv->children; it != NULL; it = it->next) @@ -2153,7 +2296,8 @@ _gtk_tool_item_group_item_size_request (GtkToolItemGroup *group, if (!child->homogeneous && child->expand) new_row = TRUE; - gtk_widget_size_request (GTK_WIDGET (child->item), &child_requisition); + gtk_widget_get_preferred_size (GTK_WIDGET (child->item), + &child_requisition, NULL); if (!homogeneous_only || child->homogeneous) item_size->width = MAX (item_size->width, child_requisition.width); @@ -2168,45 +2312,51 @@ void _gtk_tool_item_group_paint (GtkToolItemGroup *group, cairo_t *cr) { + GtkAllocation allocation; GtkWidget *widget = GTK_WIDGET (group); + GtkToolItemGroupPrivate* priv = group->priv; - gdk_cairo_set_source_pixmap (cr, widget->window, - widget->allocation.x, - widget->allocation.y); + gtk_widget_get_allocation (widget, &allocation); - if (group->priv->animation_timeout) + gdk_cairo_set_source_window (cr, gtk_widget_get_window (widget), + allocation.x, + allocation.y); + + if (priv->animation_timeout) { + GtkAllocation header_allocation; GtkOrientation orientation = gtk_tool_item_group_get_orientation (GTK_TOOL_SHELL (group)); cairo_pattern_t *mask; gdouble v0, v1; if (GTK_ORIENTATION_VERTICAL == orientation) - v1 = widget->allocation.height; + v1 = allocation.height; else - v1 = widget->allocation.width; + v1 = allocation.width; v0 = v1 - 256; - if (!GTK_WIDGET_VISIBLE (group->priv->header)) + gtk_widget_get_allocation (priv->header, &header_allocation); + if (!gtk_widget_get_visible (priv->header)) v0 = MAX (v0, 0); else if (GTK_ORIENTATION_VERTICAL == orientation) - v0 = MAX (v0, group->priv->header->allocation.height); + v0 = MAX (v0, header_allocation.height); else - v0 = MAX (v0, group->priv->header->allocation.width); + v0 = MAX (v0, header_allocation.width); v1 = MIN (v0 + 256, v1); if (GTK_ORIENTATION_VERTICAL == orientation) { - v0 += widget->allocation.y; - v1 += widget->allocation.y; + v0 += allocation.y; + v1 += allocation.y; mask = cairo_pattern_create_linear (0.0, v0, 0.0, v1); } else { - v0 += widget->allocation.x; - v1 += widget->allocation.x; + v0 += allocation.x; + v1 += allocation.x; mask = cairo_pattern_create_linear (v0, 0.0, v1, 0.0); } @@ -2231,10 +2381,12 @@ _gtk_tool_item_group_get_size_for_limit (GtkToolItemGroup *group, gboolean animation) { GtkRequisition requisition; + GtkToolItemGroupPrivate* priv = group->priv; - gtk_widget_size_request (GTK_WIDGET (group), &requisition); + gtk_widget_get_preferred_size (GTK_WIDGET (group), + &requisition, NULL); - if (!group->priv->collapsed || group->priv->animation_timeout) + if (!priv->collapsed || priv->animation_timeout) { GtkAllocation allocation = { 0, 0, requisition.width, requisition.height }; GtkRequisition inquery; @@ -2252,13 +2404,13 @@ _gtk_tool_item_group_get_size_for_limit (GtkToolItemGroup *group, else inquery.width -= requisition.width; - if (group->priv->animation_timeout && animation) + if (priv->animation_timeout && animation) { gint64 timestamp = gtk_tool_item_group_get_animation_timestamp (group); timestamp = MIN (timestamp, ANIMATION_DURATION); - if (group->priv->collapsed) + if (priv->collapsed) timestamp = ANIMATION_DURATION - timestamp; if (vertical) @@ -2298,7 +2450,7 @@ _gtk_tool_item_group_get_width_for_height (GtkToolItemGroup *group, static void gtk_tool_palette_reconfigured_foreach_item (GtkWidget *child, - gpointer data G_GNUC_UNUSED) + gpointer data) { if (GTK_IS_TOOL_ITEM (child)) gtk_tool_item_toolbar_reconfigured (GTK_TOOL_ITEM (child));