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.
This commit is contained in:
parent
c50062a48b
commit
7c7c0b75d5
1 changed files with 108 additions and 69 deletions
|
@ -1078,46 +1078,6 @@ n_supported_scales (CcDisplayMode *mode)
|
||||||
return n;
|
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
|
static gboolean
|
||||||
should_show_scale_row (CcDisplayMonitor *output)
|
should_show_scale_row (CcDisplayMonitor *output)
|
||||||
{
|
{
|
||||||
|
@ -1135,52 +1095,131 @@ scale_row_sync_visibility (GtkWidget *row,
|
||||||
gtk_widget_show (row);
|
gtk_widget_show (row);
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static void
|
||||||
scale_slider_get_selected_scale (GtkRange *slider,
|
scale_buttons_active (CcDisplayPanel *panel,
|
||||||
CcDisplayPanel *panel)
|
GParamSpec *pspec,
|
||||||
|
GtkWidget *button)
|
||||||
{
|
{
|
||||||
CcDisplayPanelPrivate *priv = panel->priv;
|
double scale = *(double*) g_object_get_data (G_OBJECT (button), "scale");
|
||||||
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);
|
|
||||||
|
|
||||||
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
|
||||||
|
get_display_scales (CcDisplayMonitor *output,
|
||||||
|
double *scales)
|
||||||
|
{
|
||||||
|
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
|
static void
|
||||||
scale_slider_changed (GtkRange *slider,
|
setup_scale_buttons (GtkWidget *bbox,
|
||||||
CcDisplayPanel *panel)
|
CcDisplayMonitor *output)
|
||||||
{
|
{
|
||||||
cc_display_monitor_set_scale (panel->priv->current_output,
|
CcDisplayPanel *panel;
|
||||||
scale_slider_get_selected_scale (slider, panel));
|
GtkRadioButton *group;
|
||||||
update_apply_button (panel);
|
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 *
|
static GtkWidget *
|
||||||
make_scale_row (CcDisplayPanel *panel, CcDisplayMonitor *output)
|
make_scale_row (CcDisplayPanel *panel, CcDisplayMonitor *output)
|
||||||
{
|
{
|
||||||
GtkWidget *row, *slider;
|
GtkWidget *row, *bbox, *label;
|
||||||
|
|
||||||
slider = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL);
|
label = gtk_label_new (_("Scale"));
|
||||||
gtk_widget_set_size_request (slider, 200, -1);
|
|
||||||
|
|
||||||
g_signal_connect_object (slider, "value-changed",
|
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
|
||||||
G_CALLBACK (scale_slider_changed), panel, 0);
|
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_EXPAND);
|
||||||
|
|
||||||
gtk_scale_set_draw_value (GTK_SCALE (slider), FALSE);
|
row = make_row (NULL, label, bbox);
|
||||||
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);
|
|
||||||
|
|
||||||
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);
|
g_signal_connect_object (output, "scale", G_CALLBACK (scale_buttons_sync),
|
||||||
gtk_widget_set_margin_top (gtk_bin_get_child (GTK_BIN (row)), 0);
|
bbox, G_CONNECT_SWAPPED);
|
||||||
gtk_widget_set_margin_bottom (gtk_bin_get_child (GTK_BIN (row)), 0);
|
scale_buttons_sync (bbox, output);
|
||||||
g_signal_connect_object (output, "mode", G_CALLBACK (setup_scale_slider),
|
|
||||||
slider, G_CONNECT_SWAPPED);
|
|
||||||
|
|
||||||
gtk_widget_show_all (row);
|
gtk_widget_show_all (row);
|
||||||
gtk_widget_set_no_show_all (row, TRUE);
|
gtk_widget_set_no_show_all (row, TRUE);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue