diff --git a/gtk/gtkswitch.c b/gtk/gtkswitch.c index abc37ab863..8ade76acdb 100644 --- a/gtk/gtkswitch.c +++ b/gtk/gtkswitch.c @@ -65,6 +65,7 @@ #include "gtkprivate.h" #include "gtkprogresstrackerprivate.h" #include "gtksettingsprivate.h" +#include "gtkstylecontextprivate.h" #include "gtkwidgetprivate.h" #include "a11y/gtkswitchaccessible.h" @@ -280,6 +281,54 @@ gtk_switch_activate (GtkSwitch *sw) gtk_switch_begin_toggle_animation (sw); } +static void +gtk_switch_update_state_labels (GtkSwitch *sw) +{ + /* Glyphs for the ON state, in descending order of preference */ + const char *on_glyphs[] = { + "⏽", /* U+23FD POWER ON SYMBOL */ + "❙", /* U+2759 MEDIUM VERTICAL BAR */ + }; + + /* Glyphs for the OFF state, in descending order of preference */ + const char *off_glyphs[] = { + "⭘", /* U+2B58 HEAVY CIRCLE */ + "○", /* U+25CB WHITE CIRCLE */ + }; + + GtkSwitchPrivate *priv = gtk_switch_get_instance_private (sw); + GtkWidget *widget = GTK_WIDGET (sw); + int i; + + for (i = 0; i < G_N_ELEMENTS (on_glyphs); i++) + { + PangoLayout *layout = gtk_widget_create_pango_layout (widget, on_glyphs[i]); + + if (pango_layout_get_unknown_glyphs_count (layout) == 0) + { + gtk_label_set_text (GTK_LABEL (priv->on_label), on_glyphs[i]); + g_object_unref (layout); + break; + } + + g_object_unref (layout); + } + + for (i = 0; i < G_N_ELEMENTS (off_glyphs); i++) + { + PangoLayout *layout = gtk_widget_create_pango_layout (widget, off_glyphs[i]); + + if (pango_layout_get_unknown_glyphs_count (layout) == 0) + { + gtk_label_set_text (GTK_LABEL (priv->off_label), off_glyphs[i]); + g_object_unref (layout); + break; + } + + g_object_unref (layout); + } +} + static void gtk_switch_measure (GtkWidget *widget, GtkOrientation orientation, @@ -351,6 +400,31 @@ gtk_switch_size_allocate (GtkWidget *widget, gtk_widget_size_allocate (priv->off_label, &child_alloc, -1); } +static void +gtk_switch_style_updated (GtkWidget *widget) +{ + GtkSwitch *self = GTK_SWITCH (widget); + GtkCssStyleChange *change; + GtkStyleContext *context; + + GTK_WIDGET_CLASS (gtk_switch_parent_class)->style_updated (widget); + + context = gtk_widget_get_style_context (widget); + change = gtk_style_context_get_change (context); + + if (change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT)) + gtk_switch_update_state_labels (self); +} + +static void +gtk_switch_display_changed (GtkWidget *widget, + GdkDisplay *previous_display) +{ + GtkSwitch *self = GTK_SWITCH (widget); + + gtk_switch_update_state_labels (self); +} + static void gtk_switch_set_action_name (GtkActionable *actionable, const gchar *action_name) @@ -543,6 +617,8 @@ gtk_switch_class_init (GtkSwitchClass *klass) widget_class->measure = gtk_switch_measure; widget_class->size_allocate = gtk_switch_size_allocate; + widget_class->style_updated = gtk_switch_style_updated; + widget_class->display_changed = gtk_switch_display_changed; klass->activate = gtk_switch_activate; klass->state_set = state_set; @@ -639,14 +715,17 @@ gtk_switch_init (GtkSwitch *self) gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture)); priv->pan_gesture = gesture; - priv->on_label = gtk_label_new ("⏽"); + + priv->on_label = gtk_label_new (""); gtk_widget_set_parent (priv->on_label, GTK_WIDGET (self)); - priv->off_label = gtk_label_new ("⭘"); + priv->off_label = gtk_label_new (""); gtk_widget_set_parent (priv->off_label, GTK_WIDGET (self)); priv->slider = gtk_gizmo_new ("slider", NULL, NULL, NULL); gtk_widget_set_parent (priv->slider, GTK_WIDGET (self)); + + gtk_switch_update_state_labels (self); } /**