[gnome-control-center] display: Switch to a toggle buttons design for scale
- From: Rui Matos <rtcm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] display: Switch to a toggle buttons design for scale
- Date: Tue, 22 Aug 2017 17:27:32 +0000 (UTC)
commit 7c7c0b75d50bdc762a1cfacb9d77d111eb5cde2d
Author: Rui Matos <tiagomatos gmail com>
Date: Tue Aug 22 17:57:18 2017 +0200
display: Switch to a toggle buttons design for scale
The slider design wasn't fit for this since we allow only a finite set
of scales.
panels/display/cc-display-panel.c | 177 ++++++++++++++++++++++--------------
1 files changed, 108 insertions(+), 69 deletions(-)
---
diff --git a/panels/display/cc-display-panel.c b/panels/display/cc-display-panel.c
index 46a93fb..e244496 100644
--- a/panels/display/cc-display-panel.c
+++ b/panels/display/cc-display-panel.c
@@ -1078,46 +1078,6 @@ n_supported_scales (CcDisplayMode *mode)
return n;
}
-static void
-setup_scale_slider (GtkWidget *slider,
- CcDisplayMonitor *output)
-{
- CcDisplayMode *mode;
- const double *scales;
- double current_scale;
- int current_index = -1;
- guint i, n;
-
- mode = cc_display_monitor_get_mode (output);
- scales = cc_display_mode_get_supported_scales (mode);
- n = n_supported_scales (mode);
-
- gtk_range_set_range (GTK_RANGE (slider), 0, n-1);
-
- current_scale = cc_display_monitor_get_scale (output);
- gtk_scale_clear_marks (GTK_SCALE (slider));
-
- for (i = 0; i < n; ++i)
- {
- double integral;
- double fractional = modf (scales[i], &integral);
- gchar *s = NULL;
-
- if (scales[i] == current_scale || (current_index < 0 && scales[i] == 1.0))
- current_index = i;
-
- if (fractional != 0)
- s = NULL;
- else
- s = g_strdup_printf ("%d", (int) integral);
-
- gtk_scale_add_mark (GTK_SCALE (slider), i, GTK_POS_TOP, s);
- g_free (s);
- }
-
- gtk_range_set_value (GTK_RANGE (slider), current_index);
-}
-
static gboolean
should_show_scale_row (CcDisplayMonitor *output)
{
@@ -1135,52 +1095,131 @@ scale_row_sync_visibility (GtkWidget *row,
gtk_widget_show (row);
}
-static double
-scale_slider_get_selected_scale (GtkRange *slider,
- CcDisplayPanel *panel)
+static void
+scale_buttons_active (CcDisplayPanel *panel,
+ GParamSpec *pspec,
+ GtkWidget *button)
{
- CcDisplayPanelPrivate *priv = panel->priv;
- CcDisplayMode *mode = cc_display_monitor_get_mode (priv->current_output);
- const double *scales = cc_display_mode_get_supported_scales (mode);
- int selected = gtk_range_get_value (slider);
+ double scale = *(double*) g_object_get_data (G_OBJECT (button), "scale");
- g_return_val_if_fail (selected < n_supported_scales (mode), 1.0);
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
+ {
+ cc_display_monitor_set_scale (panel->priv->current_output, scale);
+ update_apply_button (panel);
+ }
+}
- return scales[selected];
+static GtkWidget *
+make_label_for_scale (double scale)
+{
+ gchar *text = g_strdup_printf (" %d%% ", (int) round (scale*100));
+ GtkWidget *label = gtk_label_new (text);
+ g_free (text);
+ return label;
}
+#define MAX_N_SCALES 5
static void
-scale_slider_changed (GtkRange *slider,
- CcDisplayPanel *panel)
+get_display_scales (CcDisplayMonitor *output,
+ double *scales)
{
- cc_display_monitor_set_scale (panel->priv->current_output,
- scale_slider_get_selected_scale (slider, panel));
- update_apply_button (panel);
+ CcDisplayMode *mode;
+ const double *all_scales;
+ double preferred;
+ double increment;
+ guint n, i, j;
+
+ mode = cc_display_monitor_get_mode (output);
+ all_scales = cc_display_mode_get_supported_scales (mode);
+ n = n_supported_scales (mode);
+ if (n <= MAX_N_SCALES)
+ {
+ memcpy (scales, all_scales, n * sizeof (double));
+ return;
+ }
+
+ preferred = cc_display_mode_get_preferred_scale (mode);
+ increment = (all_scales[n - 1] - all_scales[0]) / (double) (MAX_N_SCALES - 1);
+
+ scales[0] = all_scales[0];
+
+ for (i = j = 1; i < n && j < MAX_N_SCALES; i++)
+ if (all_scales[i] >= scales[0] + increment*j || all_scales[i] == preferred)
+ scales[j++] = all_scales[i];
+}
+
+static void
+setup_scale_buttons (GtkWidget *bbox,
+ CcDisplayMonitor *output)
+{
+ CcDisplayPanel *panel;
+ GtkRadioButton *group;
+ double scales[MAX_N_SCALES + 1] = { 0 };
+ double *scale;
+
+ panel = g_object_get_data (G_OBJECT (bbox), "panel");
+
+ gtk_container_foreach (GTK_CONTAINER (bbox), (GtkCallback) gtk_widget_destroy, NULL);
+
+ get_display_scales (output, scales);
+
+ group = NULL;
+ for (scale = scales; *scale != 0.0; scale++)
+ {
+ GtkWidget *button = gtk_radio_button_new_from_widget (group);
+
+ gtk_button_set_image (GTK_BUTTON (button), make_label_for_scale (*scale));
+ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
+
+ g_object_set_data_full (G_OBJECT (button), "scale", g_memdup (scale, sizeof (double)), g_free);
+
+ g_signal_connect_object (button, "notify::active", G_CALLBACK (scale_buttons_active),
+ panel, G_CONNECT_SWAPPED);
+ gtk_container_add (GTK_CONTAINER (bbox), button);
+ group = GTK_RADIO_BUTTON (button);
+ }
+
+ gtk_widget_show_all (bbox);
+}
+#undef MAX_N_SCALES
+
+static void
+scale_buttons_sync (GtkWidget *bbox,
+ CcDisplayMonitor *output)
+{
+ GList *children, *l;
+
+ children = gtk_container_get_children (GTK_CONTAINER (bbox));
+ for (l = children; l; l = l->next)
+ {
+ GtkWidget *button = l->data;
+ double scale = *(double*) g_object_get_data (G_OBJECT (button), "scale");
+ if (scale == cc_display_monitor_get_scale (output))
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+ }
+ g_list_free (children);
}
static GtkWidget *
make_scale_row (CcDisplayPanel *panel, CcDisplayMonitor *output)
{
- GtkWidget *row, *slider;
+ GtkWidget *row, *bbox, *label;
- slider = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL);
- gtk_widget_set_size_request (slider, 200, -1);
+ label = gtk_label_new (_("Scale"));
- g_signal_connect_object (slider, "value-changed",
- G_CALLBACK (scale_slider_changed), panel, 0);
+ bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_EXPAND);
- gtk_scale_set_draw_value (GTK_SCALE (slider), FALSE);
- gtk_scale_set_has_origin (GTK_SCALE (slider), FALSE);
- gtk_scale_set_digits (GTK_SCALE (slider), 0);
- gtk_range_set_increments (GTK_RANGE (slider), 1, 1);
+ row = make_row (NULL, label, bbox);
- setup_scale_slider (slider, output);
+ g_object_set_data (G_OBJECT (bbox), "panel", panel);
+ g_signal_connect_object (output, "mode", G_CALLBACK (setup_scale_buttons),
+ bbox, G_CONNECT_SWAPPED);
+ setup_scale_buttons (bbox, output);
- row = make_row (panel->priv->rows_size_group, gtk_label_new (_("Scale")), slider);
- gtk_widget_set_margin_top (gtk_bin_get_child (GTK_BIN (row)), 0);
- gtk_widget_set_margin_bottom (gtk_bin_get_child (GTK_BIN (row)), 0);
- g_signal_connect_object (output, "mode", G_CALLBACK (setup_scale_slider),
- slider, G_CONNECT_SWAPPED);
+ g_signal_connect_object (output, "scale", G_CALLBACK (scale_buttons_sync),
+ bbox, G_CONNECT_SWAPPED);
+ scale_buttons_sync (bbox, output);
gtk_widget_show_all (row);
gtk_widget_set_no_show_all (row, TRUE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]