X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkswitch.c;h=dfcfedc4bd351664ebbe959f2ceb984646212547;hb=17d3775555888151780fa404242e734a8e7f6b21;hp=e67fce66ca847599e0fcd17631065af9da2c4ef4;hpb=fdc2e29d69a6c3435e3c5fd3f0c826553a786a99;p=~andy%2Fgtk diff --git a/gtk/gtkswitch.c b/gtk/gtkswitch.c index e67fce66c..dfcfedc4b 100644 --- a/gtk/gtkswitch.c +++ b/gtk/gtkswitch.c @@ -14,9 +14,7 @@ * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . * * Author: * Emmanuele Bassi @@ -49,6 +47,7 @@ #include "gtkapplicationprivate.h" #include "gtkactionable.h" #include "a11y/gtkswitchaccessible.h" +#include "gtkactionhelper.h" #include @@ -59,10 +58,7 @@ struct _GtkSwitchPrivate { GdkWindow *event_window; GtkAction *action; - - gchar *action_name; - GVariant *action_target; - GSimpleActionObserver *action_observer; + GtkActionHelper *action_helper; gint handle_x; gint offset; @@ -97,9 +93,6 @@ static guint signals[LAST_SIGNAL] = { 0 }; static GParamSpec *switch_props[LAST_PROP] = { NULL, }; -static void gtk_switch_hierarchy_changed (GtkWidget *widget, - GtkWidget *previous_toplevel); - static void gtk_switch_actionable_iface_init (GtkActionableInterface *iface); static void gtk_switch_activatable_interface_init (GtkActivatableIface *iface); @@ -310,7 +303,6 @@ gtk_switch_get_preferred_width (GtkWidget *widget, gint *minimum, gint *natural) { - GtkSwitchPrivate *priv = GTK_SWITCH (widget)->priv; GtkStyleContext *context; GtkStateFlags state; GtkBorder padding; @@ -319,14 +311,10 @@ gtk_switch_get_preferred_width (GtkWidget *widget, PangoRectangle logical_rect; context = gtk_widget_get_style_context (widget); - state = gtk_widget_get_state_flags (widget); - - if (priv->is_active) - state |= GTK_STATE_FLAG_ACTIVE; + state = gtk_style_context_get_state (context); gtk_style_context_save (context); - gtk_style_context_set_state (context, state); gtk_style_context_add_class (context, GTK_STYLE_CLASS_SLIDER); gtk_style_context_get_padding (context, state, &padding); @@ -373,7 +361,6 @@ gtk_switch_get_preferred_height (GtkWidget *widget, gint *minimum, gint *natural) { - GtkSwitchPrivate *priv = GTK_SWITCH (widget)->priv; GtkStyleContext *context; GtkStateFlags state; GtkBorder padding; @@ -383,14 +370,10 @@ gtk_switch_get_preferred_height (GtkWidget *widget, gchar *str; context = gtk_widget_get_style_context (widget); - state = gtk_widget_get_state_flags (widget); - - if (priv->is_active) - state |= GTK_STATE_FLAG_ACTIVE; + state = gtk_style_context_get_state (context); gtk_style_context_save (context); - gtk_style_context_set_state (context, state); gtk_style_context_add_class (context, GTK_STYLE_CLASS_SLIDER); gtk_style_context_get_padding (context, state, &padding); @@ -475,7 +458,7 @@ gtk_switch_realize (GtkWidget *widget) priv->event_window = gdk_window_new (parent_window, &attributes, attributes_mask); - gdk_window_set_user_data (priv->event_window, widget); + gtk_widget_register_window (widget, priv->event_window); } static void @@ -485,7 +468,7 @@ gtk_switch_unrealize (GtkWidget *widget) if (priv->event_window != NULL) { - 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; } @@ -520,17 +503,9 @@ gtk_switch_paint_handle (GtkWidget *widget, cairo_t *cr, GdkRectangle *box) { - GtkSwitchPrivate *priv = GTK_SWITCH (widget)->priv; GtkStyleContext *context = gtk_widget_get_style_context (widget); - GtkStateFlags state; - - state = gtk_widget_get_state_flags (widget); - - if (priv->is_active) - 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_SLIDER); gtk_render_slider (context, cr, @@ -549,15 +524,12 @@ gtk_switch_draw (GtkWidget *widget, GtkStyleContext *context; GdkRectangle handle; PangoLayout *layout; - PangoFontDescription *desc; - const PangoFontDescription *style_desc; PangoRectangle rect; gint label_x, label_y; - GtkStateFlags state; GtkBorder padding; + GtkStateFlags state; gint focus_width, focus_pad; gint x, y, width, height; - gint font_size, style_font_size; gtk_widget_style_get (widget, "focus-line-width", &focus_width, @@ -567,12 +539,8 @@ gtk_switch_draw (GtkWidget *widget, context = gtk_widget_get_style_context (widget); state = gtk_widget_get_state_flags (widget); - if (priv->is_active) - 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_SLIDER); gtk_style_context_get_padding (context, state, &padding); @@ -594,7 +562,6 @@ gtk_switch_draw (GtkWidget *widget, gtk_style_context_save (context); gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH); - gtk_style_context_set_state (context, state); gtk_render_background (context, cr, x, y, width, height); gtk_render_frame (context, cr, x, y, width, height); @@ -615,20 +582,6 @@ gtk_switch_draw (GtkWidget *widget, */ layout = gtk_widget_create_pango_layout (widget, C_("switch", "ON")); - /* FIXME: this should be really done in the theme, but overriding font size - * from it doesn't currently work. So we have to hardcode this here and - * below for the "OFF" label. - */ - desc = pango_font_description_new (); - - style_desc = gtk_style_context_get_font (context, state); - style_font_size = pango_font_description_get_size (style_desc); - font_size = MAX (style_font_size - 1 * PANGO_SCALE, ceil (style_font_size * PANGO_SCALE_SMALL)); - - pango_font_description_set_size (desc, font_size); - - pango_layout_set_font_description (layout, desc); - pango_layout_get_extents (layout, NULL, &rect); pango_extents_to_pixels (&rect, NULL); @@ -643,7 +596,6 @@ gtk_switch_draw (GtkWidget *widget, * glyphs then use WHITE CIRCLE (U+25CB) as the text for the state */ layout = gtk_widget_create_pango_layout (widget, C_("switch", "OFF")); - pango_layout_set_font_description (layout, desc); pango_layout_get_extents (layout, NULL, &rect); pango_extents_to_pixels (&rect, NULL); @@ -666,8 +618,6 @@ gtk_switch_draw (GtkWidget *widget, gtk_switch_paint_handle (widget, cr, &handle); - pango_font_description_free (desc); - return FALSE; } @@ -699,49 +649,16 @@ gtk_switch_set_use_action_appearance (GtkSwitch *sw, } } -static void -gtk_switch_update_action_observer (GtkSwitch *sw) -{ - GtkWidget *window; - - /* we are the only owner so this will clear all the signals */ - g_clear_object (&sw->priv->action_observer); - - window = gtk_widget_get_toplevel (GTK_WIDGET (sw)); - - if (GTK_IS_APPLICATION_WINDOW (window) && sw->priv->action_name) - { - GSimpleActionObserver *observer; - - observer = gtk_application_window_get_observer (GTK_APPLICATION_WINDOW (window), - sw->priv->action_name, - sw->priv->action_target); - - if (g_object_class_find_property (G_OBJECT_GET_CLASS (sw), "active")) - g_object_bind_property (observer, "active", sw, "active", G_BINDING_SYNC_CREATE); - g_object_bind_property (observer, "enabled", sw, "sensitive", G_BINDING_SYNC_CREATE); - - sw->priv->action_observer = observer; - } -} - static void gtk_switch_set_action_name (GtkActionable *actionable, const gchar *action_name) { GtkSwitch *sw = GTK_SWITCH (actionable); - g_return_if_fail (GTK_IS_SWITCH (sw)); + if (!sw->priv->action_helper) + sw->priv->action_helper = gtk_action_helper_new (actionable); - if (g_strcmp0 (action_name, sw->priv->action_name) != 0) - { - g_free (sw->priv->action_name); - sw->priv->action_name = g_strdup (action_name); - - gtk_switch_update_action_observer (sw); - - g_object_notify (G_OBJECT (sw), "action-name"); - } + gtk_action_helper_set_action_name (sw->priv->action_helper, action_name); } static void @@ -750,24 +667,10 @@ gtk_switch_set_action_target_value (GtkActionable *actionable, { GtkSwitch *sw = GTK_SWITCH (actionable); - g_return_if_fail (GTK_IS_SWITCH (sw)); - - if (action_target != sw->priv->action_target && - (!action_target || !sw->priv->action_target || - !g_variant_equal (action_target, sw->priv->action_target))) - { - if (sw->priv->action_target) - g_variant_unref (sw->priv->action_target); - - sw->priv->action_target = NULL; + if (!sw->priv->action_helper) + sw->priv->action_helper = gtk_action_helper_new (actionable); - if (action_target) - sw->priv->action_target = g_variant_ref_sink (action_target); - - gtk_switch_update_action_observer (sw); - - g_object_notify (G_OBJECT (sw), "action-target"); - } + gtk_action_helper_set_action_target_value (sw->priv->action_helper, action_target); } static const gchar * @@ -775,7 +678,7 @@ gtk_switch_get_action_name (GtkActionable *actionable) { GtkSwitch *sw = GTK_SWITCH (actionable); - return sw->priv->action_name; + return gtk_action_helper_get_action_name (sw->priv->action_helper); } static GVariant * @@ -783,7 +686,7 @@ gtk_switch_get_action_target_value (GtkActionable *actionable) { GtkSwitch *sw = GTK_SWITCH (actionable); - return sw->priv->action_target; + return gtk_action_helper_get_action_target_value (sw->priv->action_helper); } static void @@ -795,28 +698,6 @@ gtk_switch_actionable_iface_init (GtkActionableInterface *iface) iface->set_action_target_value = gtk_switch_set_action_target_value; } -static void -gtk_switch_hierarchy_changed (GtkWidget *widget, - GtkWidget *previous_toplevel) -{ - GtkSwitch *sw = GTK_SWITCH (widget); - GtkWidgetClass *parent_class; - - parent_class = GTK_WIDGET_CLASS (gtk_switch_parent_class); - if (parent_class->hierarchy_changed) - parent_class->hierarchy_changed (widget, previous_toplevel); - - if (sw->priv->action_name) - { - GtkWidget *toplevel; - - toplevel = gtk_widget_get_toplevel (widget); - - if (toplevel != previous_toplevel) - gtk_switch_update_action_observer (sw); - } -} - static void gtk_switch_set_property (GObject *gobject, guint prop_id, @@ -875,11 +756,11 @@ gtk_switch_get_property (GObject *gobject, break; case PROP_ACTION_NAME: - g_value_set_string (value, priv->action_name); + g_value_set_string (value, gtk_action_helper_get_action_name (priv->action_helper)); break; case PROP_ACTION_TARGET: - g_value_set_variant (value, priv->action_target); + g_value_set_variant (value, gtk_action_helper_get_action_target_value (priv->action_helper)); break; default: @@ -892,13 +773,7 @@ gtk_switch_dispose (GObject *object) { GtkSwitchPrivate *priv = GTK_SWITCH (object)->priv; - g_clear_object (&priv->action_observer); - - if (priv->action_name) - { - g_free (priv->action_name); - priv->action_name = NULL; - } + g_clear_object (&priv->action_helper); if (priv->action) { @@ -960,7 +835,6 @@ gtk_switch_class_init (GtkSwitchClass *klass) widget_class->motion_notify_event = gtk_switch_motion; widget_class->enter_notify_event = gtk_switch_enter; widget_class->leave_notify_event = gtk_switch_leave; - widget_class->hierarchy_changed = gtk_switch_hierarchy_changed; klass->activate = gtk_switch_activate; @@ -1050,16 +924,13 @@ gtk_switch_set_active (GtkSwitch *sw, if (priv->is_active != is_active) { AtkObject *accessible; - GtkWidget *widget; - GtkStyleContext *context; - widget = GTK_WIDGET (sw); priv->is_active = is_active; g_object_notify_by_pspec (G_OBJECT (sw), switch_props[PROP_ACTIVE]); - if (priv->action_observer) - g_simple_action_observer_activate (priv->action_observer); + if (priv->action_helper) + gtk_action_helper_activate (priv->action_helper); if (priv->action) gtk_action_activate (priv->action); @@ -1067,13 +938,10 @@ gtk_switch_set_active (GtkSwitch *sw, accessible = gtk_widget_get_accessible (GTK_WIDGET (sw)); atk_object_notify_state_change (accessible, ATK_STATE_CHECKED, priv->is_active); - if (gtk_widget_get_realized (widget)) - { - context = gtk_widget_get_style_context (widget); - gtk_style_context_notify_state_change (context, - gtk_widget_get_window (widget), - NULL, GTK_STATE_ACTIVE, is_active); - } + if (priv->is_active) + gtk_widget_set_state_flags (GTK_WIDGET (sw), GTK_STATE_FLAG_ACTIVE, FALSE); + else + gtk_widget_unset_state_flags (GTK_WIDGET (sw), GTK_STATE_FLAG_ACTIVE); gtk_widget_queue_draw (GTK_WIDGET (sw)); }