X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkexpander.c;h=6f6a196a6f4da67b286e615180a7d6a203a4dc39;hb=b9e189150bfd62c9e956e29324622058672600f0;hp=7e173bcdca135f33ecc37fe2877f8182f24855cd;hpb=3e348181ed4fe724a9c6f03d09b72876fad7a0e3;p=~andy%2Fgtk diff --git a/gtk/gtkexpander.c b/gtk/gtkexpander.c index 7e173bcdc..6f6a196a6 100644 --- a/gtk/gtkexpander.c +++ b/gtk/gtkexpander.c @@ -13,9 +13,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . * * Authors: * Mark McLoughlin @@ -34,7 +32,7 @@ * to add it to the expander. When the expander is toggled, it will take * care of showing and hiding the child automatically. * - *
+ * * Special Usage * * There are situations in which you may prefer to show and hide the @@ -45,6 +43,7 @@ * its expansion state. You should watch this property with a signal * connection as follows: * + * * * expander = gtk_expander_new_with_mnemonic ("_More Options"); * g_signal_connect (expander, "notify::expanded", @@ -71,7 +70,8 @@ * } * } * - *
+ * + * * * GtkExpander as GtkBuildable * @@ -95,6 +95,7 @@ * ]]> * * + * */ #include "config.h" @@ -111,6 +112,7 @@ #include "gtkintl.h" #include "gtkprivate.h" #include "gtkdnd.h" +#include "a11y/gtkexpanderaccessible.h" #define DEFAULT_EXPANDER_SIZE 10 @@ -125,7 +127,8 @@ enum PROP_USE_MARKUP, PROP_SPACING, PROP_LABEL_WIDGET, - PROP_LABEL_FILL + PROP_LABEL_FILL, + PROP_RESIZE_TOPLEVEL }; struct _GtkExpanderPrivate @@ -142,6 +145,7 @@ struct _GtkExpanderPrivate guint button_down : 1; guint prelight : 1; guint label_fill : 1; + guint resize_toplevel : 1; }; static void gtk_expander_set_property (GObject *object, @@ -328,6 +332,22 @@ gtk_expander_class_init (GtkExpanderClass *klass) FALSE, GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + /** + * GtkExpander:resize-toplevel: + * + * When this property is %TRUE, the expander will resize the toplevel + * widget containing the expander upon expanding and collapsing. + * + * Since: 3.2 + */ + g_object_class_install_property (gobject_class, + PROP_RESIZE_TOPLEVEL, + g_param_spec_boolean ("resize-toplevel", + P_("Resize toplevel"), + P_("Whether the expander will resize the toplevel window upon expanding and collapsing"), + FALSE, + GTK_PARAM_READWRITE)); + gtk_widget_class_install_style_property (widget_class, g_param_spec_int ("expander-size", P_("Expander Size"), @@ -354,6 +374,8 @@ gtk_expander_class_init (GtkExpanderClass *klass) NULL, NULL, _gtk_marshal_VOID__VOID, G_TYPE_NONE, 0); + + gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_EXPANDER_ACCESSIBLE); } static void @@ -379,6 +401,7 @@ gtk_expander_init (GtkExpander *expander) priv->prelight = FALSE; priv->label_fill = FALSE; priv->expand_timer = 0; + priv->resize_toplevel = 0; gtk_drag_dest_set (GTK_WIDGET (expander), 0, NULL, 0, 0); gtk_drag_dest_set_track_motion (GTK_WIDGET (expander), TRUE); @@ -435,6 +458,9 @@ gtk_expander_set_property (GObject *object, case PROP_LABEL_FILL: gtk_expander_set_label_fill (expander, g_value_get_boolean (value)); break; + case PROP_RESIZE_TOPLEVEL: + gtk_expander_set_resize_toplevel (expander, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -475,6 +501,9 @@ gtk_expander_get_property (GObject *object, case PROP_LABEL_FILL: g_value_set_boolean (value, priv->label_fill); break; + case PROP_RESIZE_TOPLEVEL: + g_value_set_boolean (value, gtk_expander_get_resize_toplevel (expander)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -548,7 +577,7 @@ gtk_expander_realize (GtkWidget *widget) priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); - gdk_window_set_user_data (priv->event_window, widget); + gtk_widget_register_window (widget, priv->event_window); } static void @@ -558,7 +587,7 @@ gtk_expander_unrealize (GtkWidget *widget) if (priv->event_window) { - gdk_window_set_user_data (priv->event_window, NULL); + gtk_widget_unregister_window (widget, priv->event_window); gdk_window_destroy (priv->event_window); priv->event_window = NULL; } @@ -856,39 +885,37 @@ gtk_expander_paint (GtkExpander *expander, widget = GTK_WIDGET (expander); context = gtk_widget_get_style_context (widget); + state = gtk_widget_get_state_flags (widget); get_expander_bounds (expander, &clip); gtk_widget_get_allocation (widget, &allocation); gtk_style_context_save (context); + state &= ~(GTK_STATE_FLAG_PRELIGHT); if (expander->priv->prelight) { - state = GTK_STATE_FLAG_PRELIGHT; + state |= GTK_STATE_FLAG_PRELIGHT; gtk_style_context_set_state (context, state); gtk_expander_paint_prelight (expander, cr); } gtk_widget_style_get (widget, "expander-size", &size, NULL); - state = gtk_style_context_get_state (context); - /* Set active flag as per the expanded state */ if (priv->expanded) state |= GTK_STATE_FLAG_ACTIVE; + else + state &= ~(GTK_STATE_FLAG_ACTIVE); gtk_style_context_set_state (context, state); gtk_style_context_add_class (context, GTK_STYLE_CLASS_EXPANDER); - /* The expander is the only animatable region */ - gtk_style_context_push_animatable_region (context, GUINT_TO_POINTER (1)); - gtk_render_expander (context, cr, clip.x - allocation.x, clip.y - allocation.y, size, size); - gtk_style_context_pop_animatable_region (context); gtk_style_context_restore (context); } @@ -985,7 +1012,7 @@ gtk_expander_draw (GtkWidget *widget, gtk_expander_paint (expander, cr); - if (gtk_widget_has_focus (widget)) + if (gtk_widget_has_visible_focus (widget)) gtk_expander_paint_focus (expander, cr); GTK_WIDGET_CLASS (gtk_expander_parent_class)->draw (widget, cr); @@ -999,7 +1026,7 @@ gtk_expander_button_press (GtkWidget *widget, { GtkExpander *expander = GTK_EXPANDER (widget); - if (event->button == 1 && event->window == expander->priv->event_window) + if (event->button == GDK_BUTTON_PRIMARY && event->window == expander->priv->event_window) { expander->priv->button_down = TRUE; return TRUE; @@ -1014,7 +1041,7 @@ gtk_expander_button_release (GtkWidget *widget, { GtkExpander *expander = GTK_EXPANDER (widget); - if (event->button == 1 && expander->priv->button_down) + if (event->button == GDK_BUTTON_PRIMARY && expander->priv->button_down) { gtk_widget_activate (widget); expander->priv->button_down = FALSE; @@ -1224,6 +1251,7 @@ get_next_site (GtkExpander *expander, case GTK_DIR_RIGHT: return FOCUS_WIDGET; } + break; case FOCUS_WIDGET: switch (direction) { @@ -1237,8 +1265,8 @@ get_next_site (GtkExpander *expander, return FOCUS_LABEL; case GTK_DIR_RIGHT: return ltr ? FOCUS_LABEL : FOCUS_NONE; - break; } + break; case FOCUS_LABEL: switch (direction) { @@ -1252,8 +1280,8 @@ get_next_site (GtkExpander *expander, return FOCUS_CHILD; case GTK_DIR_RIGHT: return ltr ? FOCUS_CHILD : FOCUS_WIDGET; - break; } + break; case FOCUS_CHILD: switch (direction) { @@ -1266,12 +1294,54 @@ get_next_site (GtkExpander *expander, case GTK_DIR_RIGHT: return FOCUS_NONE; } + break; } g_assert_not_reached (); return FOCUS_NONE; } +static void +gtk_expander_resize_toplevel (GtkExpander *expander) +{ + GtkExpanderPrivate *priv = expander->priv; + GtkWidget *child = gtk_bin_get_child (GTK_BIN (expander)); + + if (child && priv->resize_toplevel && + gtk_widget_get_realized (GTK_WIDGET (expander))) + { + GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (expander)); + + if (toplevel && gtk_widget_get_realized (toplevel)) + { + GtkAllocation toplevel_allocation; + + gtk_widget_get_allocation (toplevel, &toplevel_allocation); + + if (priv->expanded) + { + GtkRequisition child_requisition; + + gtk_widget_get_preferred_size (child, &child_requisition, NULL); + + toplevel_allocation.height += child_requisition.height; + } + else + { + GtkAllocation child_allocation; + + gtk_widget_get_allocation (child, &child_allocation); + + toplevel_allocation.height -= child_allocation.height; + } + + gtk_window_resize (GTK_WINDOW (toplevel), + toplevel_allocation.width, + toplevel_allocation.height); + } + } +} + static gboolean gtk_expander_focus (GtkWidget *widget, GtkDirectionType direction) @@ -1637,34 +1707,16 @@ gtk_expander_set_expanded (GtkExpander *expander, if (priv->expanded != expanded) { GtkWidget *widget = GTK_WIDGET (expander); - GtkSettings *settings = gtk_widget_get_settings (widget); - GtkStyleContext *context; - gboolean enable_animations; - context = gtk_widget_get_style_context (widget); priv->expanded = expanded; - g_object_get (settings, "gtk-enable-animations", &enable_animations, NULL); - - if (enable_animations && gtk_widget_get_realized (widget)) - { - gtk_style_context_save (context); - gtk_style_context_add_class (context, GTK_STYLE_CLASS_EXPANDER); - - gtk_style_context_notify_state_change (context, - gtk_widget_get_window (widget), - GUINT_TO_POINTER (1), - GTK_STATE_ACTIVE, - expanded); - gtk_style_context_restore (context); - } - child = gtk_bin_get_child (GTK_BIN (expander)); if (child) { gtk_widget_set_child_visible (child, priv->expanded); gtk_widget_queue_resize (widget); + gtk_expander_resize_toplevel (expander); } g_object_notify (G_OBJECT (expander), "expanded"); @@ -1794,7 +1846,7 @@ gtk_expander_set_label (GtkExpander *expander, * * Since: 2.4 */ -G_CONST_RETURN char * +const char * gtk_expander_get_label (GtkExpander *expander) { GtkExpanderPrivate *priv; @@ -2045,3 +2097,45 @@ gtk_expander_get_label_fill (GtkExpander *expander) return expander->priv->label_fill; } + +/** + * gtk_expander_set_resize_toplevel: + * @expander: a #GtkExpander + * @resize_toplevel: whether to resize the toplevel + * + * Sets whether the expander will resize the toplevel widget + * containing the expander upon resizing and collpasing. + * + * Since: 3.2 + */ +void +gtk_expander_set_resize_toplevel (GtkExpander *expander, + gboolean resize_toplevel) +{ + g_return_if_fail (GTK_IS_EXPANDER (expander)); + + if (expander->priv->resize_toplevel != resize_toplevel) + { + expander->priv->resize_toplevel = resize_toplevel ? TRUE : FALSE; + g_object_notify (G_OBJECT (expander), "resize-toplevel"); + } +} + +/** + * gtk_expander_get_resize_toplevel: + * @expander: a #GtkExpander + * + * Returns whether the expander will resize the toplevel widget + * containing the expander upon resizing and collpasing. + * + * Return value: the "resize toplevel" setting. + * + * Since: 3.2 + */ +gboolean +gtk_expander_get_resize_toplevel (GtkExpander *expander) +{ + g_return_val_if_fail (GTK_IS_EXPANDER (expander), FALSE); + + return expander->priv->resize_toplevel; +}