app: add compact style for spin scales
Add a boolean "compact" style property for GimpSpinScale. When TRUE, the widget uses a narrower layout, and the different upper/ lower-half behavior is gone. Instead, the behavior depends on the mouse button used: left-click is used for absolute adjustment (similar to the upper-half behavior), middle-click is used for relative adjustment (similar to the lower-half behavior), and right click is used for manual value entry (similar for clicking on the text area). Add a new "Compact sliders" toggle to the Interface prefernces, to control the spin-scale style. Apply the style globally through the themerc file, and update it when the option changes. Use the compact style by default, because otherwise no one would find it. Theming in GTK3 works differently, and spin scales in master need more work regardless, so this stays in 2.10 for now.
This commit is contained in:
@ -64,6 +64,7 @@ enum
|
||||
PROP_RESTORE_SESSION,
|
||||
PROP_RESTORE_MONITOR,
|
||||
PROP_SAVE_TOOL_OPTIONS,
|
||||
PROP_COMPACT_SLIDERS,
|
||||
PROP_SHOW_TOOLTIPS,
|
||||
PROP_TEAROFF_MENUS,
|
||||
PROP_CAN_CHANGE_ACCELS,
|
||||
@ -236,6 +237,13 @@ gimp_gui_config_class_init (GimpGuiConfigClass *klass)
|
||||
TRUE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_COMPACT_SLIDERS,
|
||||
"compact-sliders",
|
||||
"Compact sliders",
|
||||
COMPACT_SLIDERS_BLURB,
|
||||
TRUE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_TOOLTIPS,
|
||||
"show-tooltips",
|
||||
"Show tooltips",
|
||||
@ -625,6 +633,9 @@ gimp_gui_config_set_property (GObject *object,
|
||||
case PROP_SAVE_TOOL_OPTIONS:
|
||||
gui_config->save_tool_options = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_COMPACT_SLIDERS:
|
||||
gui_config->compact_sliders = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_SHOW_TOOLTIPS:
|
||||
gui_config->show_tooltips = g_value_get_boolean (value);
|
||||
break;
|
||||
@ -816,6 +827,9 @@ gimp_gui_config_get_property (GObject *object,
|
||||
case PROP_SAVE_TOOL_OPTIONS:
|
||||
g_value_set_boolean (value, gui_config->save_tool_options);
|
||||
break;
|
||||
case PROP_COMPACT_SLIDERS:
|
||||
g_value_set_boolean (value, gui_config->compact_sliders);
|
||||
break;
|
||||
case PROP_SHOW_TOOLTIPS:
|
||||
g_value_set_boolean (value, gui_config->show_tooltips);
|
||||
break;
|
||||
|
@ -53,6 +53,7 @@ struct _GimpGuiConfig
|
||||
gboolean restore_session;
|
||||
gboolean restore_monitor;
|
||||
gboolean save_tool_options;
|
||||
gboolean compact_sliders;
|
||||
gboolean show_tooltips;
|
||||
gboolean tearoff_menus;
|
||||
gboolean can_change_accels;
|
||||
|
@ -49,6 +49,11 @@ _("How to handle embedded color profiles when opening a file.")
|
||||
#define COLOR_PROFILE_PATH_BLURB \
|
||||
_("Sets the default folder path for all color profile file dialogs.")
|
||||
|
||||
#define COMPACT_SLIDERS_BLURB \
|
||||
_("Use compact style for sliders. In this mode, left-click is used for " \
|
||||
"absolute adjustment, middle-click is used for relative adjustment, and " \
|
||||
"right-click is used for manual entry.")
|
||||
|
||||
#define CURSOR_MODE_BLURB \
|
||||
_("Sets the type of mouse pointers to use.")
|
||||
|
||||
|
@ -1812,6 +1812,13 @@ prefs_dialog_new (Gimp *gimp,
|
||||
prefs_language_combo_box_add (object, "language", GTK_BOX (vbox2));
|
||||
#endif
|
||||
|
||||
/* Style */
|
||||
vbox2 = prefs_frame_new (_("Style"), GTK_CONTAINER (vbox), FALSE);
|
||||
|
||||
button = prefs_check_button_add (object, "compact-sliders",
|
||||
_("Use co_mpact sliders"),
|
||||
GTK_BOX (vbox2));
|
||||
|
||||
/* Previews */
|
||||
vbox2 = prefs_frame_new (_("Previews"), GTK_CONTAINER (vbox), FALSE);
|
||||
|
||||
|
@ -41,8 +41,11 @@
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static void themes_write_style (GimpGuiConfig *config,
|
||||
GOutputStream *output,
|
||||
GError **error);
|
||||
static void themes_apply_theme (Gimp *gimp,
|
||||
const gchar *theme_name);
|
||||
GimpGuiConfig *config);
|
||||
static void themes_list_themes_foreach (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data);
|
||||
@ -143,7 +146,7 @@ themes_init (Gimp *gimp)
|
||||
g_list_free_full (path, (GDestroyNotify) g_object_unref);
|
||||
}
|
||||
|
||||
themes_apply_theme (gimp, config->theme);
|
||||
themes_apply_theme (gimp, config);
|
||||
|
||||
themerc = gimp_personal_rc_file ("themerc");
|
||||
gtk_rc_parse (themerc);
|
||||
@ -154,6 +157,9 @@ themes_init (Gimp *gimp)
|
||||
g_signal_connect (config, "notify::theme",
|
||||
G_CALLBACK (themes_theme_change_notify),
|
||||
gimp);
|
||||
g_signal_connect (config, "notify::compact-sliders",
|
||||
G_CALLBACK (themes_theme_change_notify),
|
||||
gimp);
|
||||
}
|
||||
|
||||
void
|
||||
@ -272,8 +278,28 @@ themes_get_theme_file (Gimp *gimp,
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
themes_apply_theme (Gimp *gimp,
|
||||
const gchar *theme_name)
|
||||
themes_write_style (GimpGuiConfig *config,
|
||||
GOutputStream *output,
|
||||
GError **error)
|
||||
{
|
||||
if (! *error)
|
||||
{
|
||||
g_output_stream_printf (
|
||||
output, NULL, NULL, error,
|
||||
"style \"gimp-spin-scale-style\"\n"
|
||||
"{\n"
|
||||
" GimpSpinScale::compact = %d\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"class \"GimpSpinScale\" style \"gimp-spin-scale-style\"\n"
|
||||
"\n",
|
||||
config->compact_sliders);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
themes_apply_theme (Gimp *gimp,
|
||||
GimpGuiConfig *config)
|
||||
{
|
||||
GFile *themerc;
|
||||
GOutputStream *output;
|
||||
@ -296,7 +322,7 @@ themes_apply_theme (Gimp *gimp,
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *theme_dir = themes_get_theme_dir (gimp, theme_name);
|
||||
GFile *theme_dir = themes_get_theme_dir (gimp, config->theme);
|
||||
GFile *gtkrc_user;
|
||||
GSList *gtkrc_files = NULL;
|
||||
GSList *iter;
|
||||
@ -336,6 +362,8 @@ themes_apply_theme (Gimp *gimp,
|
||||
"\n",
|
||||
gimp_file_get_utf8_name (gtkrc_user));
|
||||
|
||||
themes_write_style (config, output, &error);
|
||||
|
||||
for (iter = gtkrc_files; ! error && iter; iter = g_slist_next (iter))
|
||||
{
|
||||
GFile *file = iter->data;
|
||||
@ -419,7 +447,7 @@ themes_theme_change_notify (GimpGuiConfig *config,
|
||||
GParamSpec *pspec,
|
||||
Gimp *gimp)
|
||||
{
|
||||
themes_apply_theme (gimp, config->theme);
|
||||
themes_apply_theme (gimp, config);
|
||||
|
||||
gtk_rc_reparse_all ();
|
||||
|
||||
|
@ -54,6 +54,8 @@ typedef struct _GimpSpinScalePrivate GimpSpinScalePrivate;
|
||||
|
||||
struct _GimpSpinScalePrivate
|
||||
{
|
||||
gboolean compact;
|
||||
|
||||
gchar *label;
|
||||
gchar *label_text;
|
||||
gchar *label_pattern;
|
||||
@ -163,6 +165,12 @@ gimp_spin_scale_class_init (GimpSpinScaleClass *klass)
|
||||
g_param_spec_string ("label", NULL, NULL,
|
||||
NULL,
|
||||
GIMP_PARAM_READWRITE));
|
||||
|
||||
gtk_widget_class_install_style_property (widget_class,
|
||||
g_param_spec_boolean ("compact",
|
||||
NULL, NULL,
|
||||
FALSE,
|
||||
GIMP_PARAM_READABLE));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -261,17 +269,21 @@ gimp_spin_scale_size_request (GtkWidget *widget,
|
||||
GtkStyle *style = gtk_widget_get_style (widget);
|
||||
PangoContext *context = gtk_widget_get_pango_context (widget);
|
||||
PangoFontMetrics *metrics;
|
||||
gint height;
|
||||
|
||||
GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
|
||||
|
||||
metrics = pango_context_get_metrics (context, style->font_desc,
|
||||
pango_context_get_language (context));
|
||||
|
||||
height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
|
||||
pango_font_metrics_get_descent (metrics));
|
||||
if (! private->compact)
|
||||
{
|
||||
gint height;
|
||||
|
||||
requisition->height += height;
|
||||
height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
|
||||
pango_font_metrics_get_descent (metrics));
|
||||
|
||||
requisition->height += height;
|
||||
}
|
||||
|
||||
if (private->label)
|
||||
{
|
||||
@ -299,6 +311,10 @@ gimp_spin_scale_style_set (GtkWidget *widget,
|
||||
GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style);
|
||||
|
||||
g_clear_object (&private->layout);
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
"compact", &private->compact,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static PangoAttrList *
|
||||
@ -362,7 +378,8 @@ gimp_spin_scale_expose (GtkWidget *widget,
|
||||
h = gdk_window_get_height (event->window);
|
||||
|
||||
/* upper/lower halves highlight */
|
||||
if (event->window == gtk_entry_get_text_window (GTK_ENTRY (widget)) &&
|
||||
if (! private->compact &&
|
||||
event->window == gtk_entry_get_text_window (GTK_ENTRY (widget)) &&
|
||||
gtk_widget_get_sensitive (widget) &&
|
||||
(private->target == TARGET_UPPER || private->target == TARGET_LOWER))
|
||||
{
|
||||
@ -556,41 +573,61 @@ gimp_spin_scale_expose (GtkWidget *widget,
|
||||
static SpinScaleTarget
|
||||
gimp_spin_scale_get_target (GtkWidget *widget,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
gdouble y,
|
||||
gint button)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
PangoRectangle logical;
|
||||
gint layout_x;
|
||||
gint layout_y;
|
||||
GimpSpinScalePrivate *private = GET_PRIVATE (widget);
|
||||
GtkAllocation allocation;
|
||||
PangoRectangle logical;
|
||||
gint layout_x;
|
||||
gint layout_y;
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
gtk_entry_get_layout_offsets (GTK_ENTRY (widget), &layout_x, &layout_y);
|
||||
pango_layout_get_pixel_extents (gtk_entry_get_layout (GTK_ENTRY (widget)),
|
||||
NULL, &logical);
|
||||
|
||||
if (x >= layout_x && x < layout_x + logical.width &&
|
||||
y >= layout_y && y < layout_y + logical.height)
|
||||
if (x >= layout_x && x < layout_x + logical.width &&
|
||||
y >= layout_y && y < layout_y + logical.height &&
|
||||
(! private->compact || gtk_widget_has_focus (widget)))
|
||||
{
|
||||
return TARGET_NUMBER;
|
||||
}
|
||||
else if (y >= allocation.height / 2)
|
||||
{
|
||||
return TARGET_LOWER;
|
||||
}
|
||||
|
||||
return TARGET_UPPER;
|
||||
if (private->compact)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
default:
|
||||
return TARGET_UPPER;
|
||||
|
||||
case 2:
|
||||
return TARGET_LOWER;
|
||||
|
||||
case 3:
|
||||
return TARGET_NUMBER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y >= allocation.height / 2)
|
||||
return TARGET_LOWER;
|
||||
else
|
||||
return TARGET_UPPER;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_spin_scale_update_target (GtkWidget *widget,
|
||||
GdkWindow *window,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
gdouble y,
|
||||
gint button)
|
||||
{
|
||||
GimpSpinScalePrivate *private = GET_PRIVATE (widget);
|
||||
SpinScaleTarget target;
|
||||
|
||||
target = gimp_spin_scale_get_target (widget, x, y);
|
||||
target = gimp_spin_scale_get_target (widget, x, y, button);
|
||||
|
||||
if (target != private->target)
|
||||
{
|
||||
@ -742,7 +779,7 @@ gimp_spin_scale_button_press (GtkWidget *widget,
|
||||
if (event->window == gtk_entry_get_text_window (GTK_ENTRY (widget)))
|
||||
{
|
||||
gimp_spin_scale_update_target (widget, event->window,
|
||||
event->x, event->y);
|
||||
event->x, event->y, event->button);
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
@ -751,7 +788,8 @@ gimp_spin_scale_button_press (GtkWidget *widget,
|
||||
case TARGET_UPPER:
|
||||
private->changing_value = TRUE;
|
||||
|
||||
gtk_widget_grab_focus (widget);
|
||||
if (! private->compact)
|
||||
gtk_widget_grab_focus (widget);
|
||||
|
||||
gimp_spin_scale_change_value (widget, event->x);
|
||||
|
||||
@ -760,7 +798,8 @@ gimp_spin_scale_button_press (GtkWidget *widget,
|
||||
case TARGET_LOWER:
|
||||
private->changing_value = TRUE;
|
||||
|
||||
gtk_widget_grab_focus (widget);
|
||||
if (! private->compact)
|
||||
gtk_widget_grab_focus (widget);
|
||||
|
||||
private->relative_change = TRUE;
|
||||
private->start_x = event->x;
|
||||
@ -772,6 +811,17 @@ gimp_spin_scale_button_press (GtkWidget *widget,
|
||||
|
||||
return TRUE;
|
||||
|
||||
case TARGET_NUMBER:
|
||||
if (private->compact && ! gtk_widget_has_focus (widget))
|
||||
{
|
||||
gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
|
||||
|
||||
gtk_widget_grab_focus (widget);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -807,7 +857,7 @@ gimp_spin_scale_button_release (GtkWidget *widget,
|
||||
|
||||
if (private->hover)
|
||||
gimp_spin_scale_update_target (widget, event->window,
|
||||
event->x, event->y);
|
||||
event->x, event->y, 0);
|
||||
else
|
||||
gimp_spin_scale_clear_target (widget, event->window);
|
||||
|
||||
@ -945,7 +995,7 @@ gimp_spin_scale_motion_notify (GtkWidget *widget,
|
||||
private->hover)
|
||||
{
|
||||
gimp_spin_scale_update_target (widget, event->window,
|
||||
event->x, event->y);
|
||||
event->x, event->y, 0);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
Reference in New Issue
Block a user