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 @@
-
- 1
- none
- 0
+
-
diff --git a/gtk/ui/gtkvolumebutton.ui b/gtk/ui/gtkvolumebutton.ui
index 7859505c6c..cf0db3ff86 100644
--- a/gtk/ui/gtkvolumebutton.ui
+++ b/gtk/ui/gtkvolumebutton.ui
@@ -1,17 +1,13 @@
-
- 1
- 0.02
- 0.2
-
- 1
- 1
- none
- 0
- vertical
- adjustment
+
+
+ 1
+ 0.02
+ 0.2
+
+
audio-volume-muted
audio-volume-high
audio-volume-low
diff --git a/testsuite/gtk/focus-chain/widget-factory2.tab b/testsuite/gtk/focus-chain/widget-factory2.tab
index 139d7417a8..6f7a2eb1d7 100644
--- a/testsuite/gtk/focus-chain/widget-factory2.tab
+++ b/testsuite/gtk/focus-chain/widget-factory2.tab
@@ -1,6 +1,6 @@
GtkSpinButton GtkText
-GtkVolumeButton
-GtkScaleButton
+GtkToggleButton
+GtkToggleButton
GtkTextView
GtkToggleButton
GtkToggleButton
diff --git a/testsuite/gtk/focus-chain/widget-factory2.tab-backward b/testsuite/gtk/focus-chain/widget-factory2.tab-backward
index 942daff4e9..a803ce791f 100644
--- a/testsuite/gtk/focus-chain/widget-factory2.tab-backward
+++ b/testsuite/gtk/focus-chain/widget-factory2.tab-backward
@@ -30,8 +30,8 @@ GtkToggleButton
GtkToggleButton
GtkToggleButton
GtkTextView
-GtkScaleButton
-GtkVolumeButton
+GtkToggleButton
+GtkToggleButton
GtkSpinButton GtkText
GtkToggleButton
GtkToggleButton