diff --git a/demos/widget-factory/widget-factory.c b/demos/widget-factory/widget-factory.c index 0d78b1bb89..56088fcca5 100644 --- a/demos/widget-factory/widget-factory.c +++ b/demos/widget-factory/widget-factory.c @@ -442,24 +442,17 @@ on_entry_icon_release (GtkEntry *entry, #define EPSILON (1e-10) -static gboolean -on_scale_button_query_tooltip (GtkWidget *button, - gint x, - gint y, - gboolean keyboard_mode, - GtkTooltip *tooltip, - gpointer user_data) +static void +on_scale_button_value_changed (GtkScaleButton *button, + gdouble value, + gpointer user_data) { - GtkScaleButton *scale_button = GTK_SCALE_BUTTON (button); GtkAdjustment *adjustment; gdouble val; gchar *str; - AtkImage *image; - image = ATK_IMAGE (gtk_widget_get_accessible (button)); - - adjustment = gtk_scale_button_get_adjustment (scale_button); - val = gtk_scale_button_get_value (scale_button); + adjustment = gtk_scale_button_get_adjustment (button); + val = gtk_scale_button_get_value (button); if (val < (gtk_adjustment_get_lower (adjustment) + EPSILON)) { @@ -478,19 +471,10 @@ on_scale_button_query_tooltip (GtkWidget *button, str = g_strdup_printf (C_("volume percentage", "%d %%"), percent); } - gtk_tooltip_set_text (tooltip, str); - atk_image_set_image_description (image, str); + gtk_widget_set_tooltip_text (GTK_WIDGET (button), str); + atk_object_set_description (gtk_widget_get_accessible (GTK_WIDGET (button)), str); + g_free (str); - - return TRUE; -} - -static void -on_scale_button_value_changed (GtkScaleButton *button, - gdouble value, - gpointer user_data) -{ - gtk_widget_trigger_tooltip_query (GTK_WIDGET (button)); } static void @@ -1774,7 +1758,6 @@ activate (GApplication *app) gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope), "on_entry_icon_release", (GCallback)on_entry_icon_release, "on_scale_button_value_changed", (GCallback)on_scale_button_value_changed, - "on_scale_button_query_tooltip", (GCallback)on_scale_button_query_tooltip, "on_record_button_toggled", (GCallback)on_record_button_toggled, "on_page_combo_changed", (GCallback)on_page_combo_changed, "on_range_from_changed", (GCallback)on_range_from_changed, diff --git a/demos/widget-factory/widget-factory.ui b/demos/widget-factory/widget-factory.ui index 4d8b74e8c8..7e8df27601 100644 --- a/demos/widget-factory/widget-factory.ui +++ b/demos/widget-factory/widget-factory.ui @@ -1510,7 +1510,6 @@ microphone-sensitivity-medium-symbolic center .5 center - 0 diff --git a/gtk/a11y/gtkscalebuttonaccessible.c b/gtk/a11y/gtkscalebuttonaccessible.c index 1db9db7ba8..98b685382a 100644 --- a/gtk/a11y/gtkscalebuttonaccessible.c +++ b/gtk/a11y/gtkscalebuttonaccessible.c @@ -27,7 +27,7 @@ static void atk_action_interface_init (AtkActionIface *iface); static void atk_value_interface_init (AtkValueIface *iface); -G_DEFINE_TYPE_WITH_CODE (GtkScaleButtonAccessible, gtk_scale_button_accessible, GTK_TYPE_BUTTON_ACCESSIBLE, +G_DEFINE_TYPE_WITH_CODE (GtkScaleButtonAccessible, gtk_scale_button_accessible, GTK_TYPE_WIDGET_ACCESSIBLE, G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init) G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init)); diff --git a/gtk/a11y/gtkscalebuttonaccessible.h b/gtk/a11y/gtkscalebuttonaccessible.h index f5f1d4e17e..2437cda587 100644 --- a/gtk/a11y/gtkscalebuttonaccessible.h +++ b/gtk/a11y/gtkscalebuttonaccessible.h @@ -39,14 +39,14 @@ typedef struct _GtkScaleButtonAccessiblePrivate GtkScaleButtonAccessiblePrivate; struct _GtkScaleButtonAccessible { - GtkButtonAccessible parent; + GtkWidgetAccessible parent; GtkScaleButtonAccessiblePrivate *priv; }; struct _GtkScaleButtonAccessibleClass { - GtkButtonAccessibleClass parent_class; + GtkWidgetAccessibleClass parent_class; }; GDK_AVAILABLE_IN_ALL diff --git a/gtk/gtkscalebutton.c b/gtk/gtkscalebutton.c index 76c2173d49..809e790857 100644 --- a/gtk/gtkscalebutton.c +++ b/gtk/gtkscalebutton.c @@ -39,7 +39,7 @@ #include "gtkadjustment.h" #include "gtkbox.h" #include "gtkbuttonprivate.h" -#include "gtkimage.h" +#include "gtktogglebutton.h" #include "gtkeventcontrollerscroll.h" #include "gtkframe.h" #include "gtkgesture.h" @@ -52,6 +52,7 @@ #include "gtkrangeprivate.h" #include "gtkscale.h" #include "gtktypebuiltins.h" +#include "gtkwidgetprivate.h" #include "gtkwindowprivate.h" #include "gtknative.h" @@ -102,12 +103,13 @@ enum typedef struct { + GtkWidget *button; + GtkWidget *plus_button; GtkWidget *minus_button; GtkWidget *dock; GtkWidget *box; GtkWidget *scale; - GtkWidget *image; GtkWidget *active_button; GtkOrientation orientation; @@ -139,9 +141,15 @@ static void gtk_scale_button_size_allocate (GtkWidget *widget, int width, int height, int baseline); +static void gtk_scale_button_measure (GtkWidget *widget, + GtkOrientation orientation, + int for_size, + int *minimum, + int *natural, + int *minimum_baseline, + int *natural_baseline); static void gtk_scale_button_set_orientation_private (GtkScaleButton *button, GtkOrientation orientation); -static void gtk_scale_button_clicked (GtkButton *button); static void gtk_scale_button_popup (GtkWidget *widget); static void gtk_scale_button_popdown (GtkWidget *widget); static void cb_button_clicked (GtkWidget *button, @@ -157,10 +165,9 @@ static gboolean gtk_scale_button_scroll_controller_scroll (GtkEventControllerScr gdouble dy, GtkScaleButton *button); -G_DEFINE_TYPE_WITH_CODE (GtkScaleButton, gtk_scale_button, GTK_TYPE_BUTTON, +G_DEFINE_TYPE_WITH_CODE (GtkScaleButton, gtk_scale_button, GTK_TYPE_WIDGET, G_ADD_PRIVATE (GtkScaleButton) - G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, - NULL)) + G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL)) static guint signals[LAST_SIGNAL] = { 0, }; @@ -169,7 +176,6 @@ gtk_scale_button_class_init (GtkScaleButtonClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass); gobject_class->constructed = gtk_scale_button_constructed; gobject_class->finalize = gtk_scale_button_finalize; @@ -177,9 +183,11 @@ gtk_scale_button_class_init (GtkScaleButtonClass *klass) gobject_class->set_property = gtk_scale_button_set_property; gobject_class->get_property = gtk_scale_button_get_property; + widget_class->measure = gtk_scale_button_measure; widget_class->size_allocate = gtk_scale_button_size_allocate; + widget_class->focus = gtk_widget_focus_child; + widget_class->grab_focus = gtk_widget_grab_focus_child; - button_class->clicked = gtk_scale_button_clicked; /** * GtkScaleButton:orientation: @@ -326,19 +334,19 @@ gtk_scale_button_class_init (GtkScaleButtonClass *klass) gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/ui/gtkscalebutton.ui"); + gtk_widget_class_bind_template_child_private (widget_class, GtkScaleButton, button); gtk_widget_class_bind_template_child_internal_private (widget_class, GtkScaleButton, plus_button); gtk_widget_class_bind_template_child_internal_private (widget_class, GtkScaleButton, minus_button); gtk_widget_class_bind_template_child_private (widget_class, GtkScaleButton, dock); gtk_widget_class_bind_template_child_private (widget_class, GtkScaleButton, box); gtk_widget_class_bind_template_child_private (widget_class, GtkScaleButton, scale); - gtk_widget_class_bind_template_child_private (widget_class, GtkScaleButton, image); gtk_widget_class_bind_template_callback (widget_class, cb_button_clicked); gtk_widget_class_bind_template_callback (widget_class, cb_scale_value_changed); gtk_widget_class_bind_template_callback (widget_class, cb_popup_mapped); gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_SCALE_BUTTON_ACCESSIBLE); - gtk_widget_class_set_css_name (widget_class, I_("button")); + gtk_widget_class_set_css_name (widget_class, I_("scalebutton")); } static gboolean @@ -373,6 +381,28 @@ button_pressed_cb (GtkGesture *gesture, priv->autoscroll_timeout = g_timeout_add (200, start_autoscroll, button); } +static void +gtk_scale_button_toggled (GtkScaleButton *button) +{ + GtkScaleButtonPrivate *priv = gtk_scale_button_get_instance_private (button); + gboolean active; + + active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->button)); + + if (active) + gtk_popover_popup (GTK_POPOVER (priv->dock)); + else + gtk_popover_popdown (GTK_POPOVER (priv->dock)); +} + +static void +gtk_scale_button_closed (GtkScaleButton *button) +{ + GtkScaleButtonPrivate *priv = gtk_scale_button_get_instance_private (button); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button), FALSE); +} + static void gtk_scale_button_init (GtkScaleButton *button) { @@ -399,6 +429,11 @@ gtk_scale_button_init (GtkScaleButton *button) button); gtk_widget_add_controller (GTK_WIDGET (button), controller); + g_signal_connect_swapped (priv->dock, "closed", + G_CALLBACK (gtk_scale_button_closed), button); + g_signal_connect_swapped (priv->button, "toggled", + G_CALLBACK (gtk_scale_button_toggled), button); + g_signal_connect (gtk_button_get_gesture (GTK_BUTTON (priv->plus_button)), "pressed", G_CALLBACK (button_pressed_cb), button); g_signal_connect (gtk_button_get_gesture (GTK_BUTTON (priv->minus_button)), @@ -505,6 +540,7 @@ gtk_scale_button_dispose (GObject *object) GtkScaleButtonPrivate *priv = gtk_scale_button_get_instance_private (button); g_clear_pointer (&priv->dock, gtk_widget_unparent); + g_clear_pointer (&priv->button, gtk_widget_unparent); if (priv->click_id != 0) { @@ -722,43 +758,6 @@ gtk_scale_button_get_popup (GtkScaleButton *button) return priv->dock; } -static void -apply_orientation (GtkScaleButton *button, - GtkOrientation orientation) -{ - GtkScaleButtonPrivate *priv = gtk_scale_button_get_instance_private (button); - - if (priv->applied_orientation != orientation) - { - priv->applied_orientation = orientation; - gtk_orientable_set_orientation (GTK_ORIENTABLE (priv->box), orientation); - - if (orientation == GTK_ORIENTATION_HORIZONTAL) - { - gtk_box_reorder_child_after (GTK_BOX (priv->box), priv->plus_button, NULL); - gtk_box_reorder_child_after (GTK_BOX (priv->box), priv->scale, NULL); - } - else - { - gtk_box_reorder_child_after (GTK_BOX (priv->box), priv->scale, NULL); - gtk_box_reorder_child_after (GTK_BOX (priv->box), priv->plus_button, NULL); - } - - gtk_orientable_set_orientation (GTK_ORIENTABLE (priv->scale), orientation); - - if (orientation == GTK_ORIENTATION_VERTICAL) - { - gtk_widget_set_size_request (GTK_WIDGET (priv->scale), -1, SCALE_SIZE); - gtk_range_set_inverted (GTK_RANGE (priv->scale), TRUE); - } - else - { - gtk_widget_set_size_request (GTK_WIDGET (priv->scale), SCALE_SIZE, -1); - gtk_range_set_inverted (GTK_RANGE (priv->scale), FALSE); - } - } -} - static void gtk_scale_button_set_orientation_private (GtkScaleButton *button, GtkOrientation orientation) @@ -798,34 +797,13 @@ gtk_scale_button_scroll_controller_scroll (GtkEventControllerScroll *scroll, * button callbacks. */ -static gboolean +static void gtk_scale_popup (GtkWidget *widget) { GtkScaleButton *button = GTK_SCALE_BUTTON (widget); GtkScaleButtonPrivate *priv = gtk_scale_button_get_instance_private (button); - GtkWidget *toplevel; - GtkBorder border; - GtkRequisition req; - gint w, h; - gint size; - gtk_popover_popup (GTK_POPOVER (priv->dock)); - - toplevel = GTK_WIDGET (gtk_widget_get_root (widget)); - _gtk_window_get_shadow_width (GTK_WINDOW (toplevel), &border); - w = gtk_widget_get_allocated_width (toplevel) - border.left - border.right; - h = gtk_widget_get_allocated_height (toplevel) - border.top - border.bottom; - gtk_widget_get_preferred_size (priv->dock, NULL, &req); - size = MAX (req.width, req.height); - - if (size > w) - apply_orientation (button, GTK_ORIENTATION_VERTICAL); - else if (size > h) - apply_orientation (button, GTK_ORIENTATION_HORIZONTAL); - else - apply_orientation (button, priv->orientation); - - return TRUE; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button), TRUE); } static void @@ -834,13 +812,7 @@ gtk_scale_button_popdown (GtkWidget *widget) GtkScaleButton *button = GTK_SCALE_BUTTON (widget); GtkScaleButtonPrivate *priv = gtk_scale_button_get_instance_private (button); - gtk_popover_popdown (GTK_POPOVER (priv->dock)); -} - -static void -gtk_scale_button_clicked (GtkButton *button) -{ - gtk_scale_popup (GTK_WIDGET (button)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button), FALSE); } static void @@ -918,7 +890,7 @@ gtk_scale_button_update_icon (GtkScaleButton *button) if (!priv->icon_list || priv->icon_list[0][0] == '\0') { - gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), "image-missing"); + gtk_button_set_icon_name (GTK_BUTTON (priv->button), "image-missing"); return; } @@ -927,7 +899,7 @@ gtk_scale_button_update_icon (GtkScaleButton *button) /* The 1-icon special case */ if (num_icons == 1) { - gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), priv->icon_list[0]); + gtk_button_set_icon_name (GTK_BUTTON (priv->button), priv->icon_list[0]); return; } @@ -945,7 +917,7 @@ gtk_scale_button_update_icon (GtkScaleButton *button) else name = priv->icon_list[1]; - gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), name); + gtk_button_set_icon_name (GTK_BUTTON (priv->button), name); return; } @@ -968,7 +940,7 @@ gtk_scale_button_update_icon (GtkScaleButton *button) name = priv->icon_list[i]; } - gtk_image_set_from_icon_name (GTK_IMAGE (priv->image), name); + gtk_button_set_icon_name (GTK_BUTTON (priv->button), name); } static void @@ -1003,6 +975,26 @@ cb_popup_mapped (GtkWidget *popup, gtk_widget_grab_focus (priv->scale); } +static void +gtk_scale_button_measure (GtkWidget *widget, + GtkOrientation orientation, + int for_size, + int *minimum, + int *natural, + int *minimum_baseline, + int *natural_baseline) +{ + GtkScaleButton *button = GTK_SCALE_BUTTON (widget); + GtkScaleButtonPrivate *priv = gtk_scale_button_get_instance_private (button); + + gtk_widget_measure (priv->button, + orientation, + for_size, + minimum, natural, + minimum_baseline, natural_baseline); + +} + static void gtk_scale_button_size_allocate (GtkWidget *widget, int width, @@ -1012,7 +1004,9 @@ gtk_scale_button_size_allocate (GtkWidget *widget, GtkScaleButton *button = GTK_SCALE_BUTTON (widget); GtkScaleButtonPrivate *priv = gtk_scale_button_get_instance_private (button); - GTK_WIDGET_CLASS (gtk_scale_button_parent_class)->size_allocate (widget, width, height, baseline); + gtk_widget_size_allocate (priv->button, + &(GtkAllocation) { 0, 0, width, height }, + baseline); gtk_native_check_resize (GTK_NATIVE (priv->dock)); } diff --git a/gtk/ui/gtkscalebutton.ui b/gtk/ui/gtkscalebutton.ui index 1714b8b126..f7611fa481 100644 --- a/gtk/ui/gtkscalebutton.ui +++ b/gtk/ui/gtkscalebutton.ui @@ -1,13 +1,12 @@ -