[gtk+] Add a 'fine adjustment' mode to ranges
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] Add a 'fine adjustment' mode to ranges
- Date: Fri, 27 Apr 2012 16:07:37 +0000 (UTC)
commit 22eb687264ea60498532fd5ce5f541271782bd3e
Author: Matthias Clasen <mclasen redhat com>
Date: Thu Apr 26 17:51:13 2012 -0400
Add a 'fine adjustment' mode to ranges
Shift-click in the slider now starts a drag in 'fine adjustment'
mode, where we move the slider 10-times slower than the mouse.
This can be very helpful when scrolling through a very long document
or webpage, and moving the scrollbar even a single pixel already
jumps too far in the content.
https://bugzilla.gnome.org/show_bug.cgi?id=563688
gtk/gtkrange.c | 42 ++++++++++++++++++++++++++++++++++--------
1 files changed, 34 insertions(+), 8 deletions(-)
---
diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
index a224f4f..29384f7 100644
--- a/gtk/gtkrange.c
+++ b/gtk/gtkrange.c
@@ -138,6 +138,9 @@ struct _GtkRangePrivate
/* The range has an origin, should be drawn differently. Used by GtkScale */
guint has_origin : 1;
+ /* Whether we're doing fine adjustment */
+ guint zoom : 1;
+
/* Fill level */
guint show_fill_level : 1;
guint restrict_to_fill_level : 1;
@@ -2367,6 +2370,8 @@ range_grab_remove (GtkRange *range)
if (gtk_range_update_mouse_location (range) ||
location != MOUSE_OUTSIDE)
gtk_widget_queue_draw (GTK_WIDGET (range));
+
+ priv->zoom = FALSE;
}
static GtkScrollType
@@ -2433,7 +2438,7 @@ range_get_scroll_for_grab (GtkRange *range)
static gdouble
coord_to_value (GtkRange *range,
- gint coord)
+ gdouble coord)
{
GtkRangePrivate *priv = range->priv;
gdouble frac;
@@ -2635,6 +2640,12 @@ gtk_range_button_press (GtkWidget *widget,
*/
need_value_update = TRUE;
}
+ else
+ {
+ /* Shift-click in the slider = fine adjustment */
+ if (event->state & GDK_SHIFT_MASK)
+ priv->zoom = TRUE;
+ }
if (priv->orientation == GTK_ORIENTATION_VERTICAL)
{
@@ -2667,13 +2678,14 @@ update_slider_position (GtkRange *range,
gint mouse_y)
{
GtkRangePrivate *priv = range->priv;
- gint delta;
- gint c;
+ gdouble delta;
+ gdouble c;
gdouble new_value;
gboolean handled;
gdouble next_value;
gdouble mark_value;
gdouble mark_delta;
+ gdouble zoom;
gint i;
if (priv->orientation == GTK_ORIENTATION_VERTICAL)
@@ -2681,11 +2693,25 @@ update_slider_position (GtkRange *range,
else
delta = mouse_x - priv->slide_initial_coordinate;
- c = priv->slide_initial_slider_position + delta;
+ if (priv->zoom)
+ {
+ zoom = MIN(1.0, (priv->orientation == GTK_ORIENTATION_VERTICAL ?
+ priv->trough.height : priv->trough.width) /
+ (gtk_adjustment_get_upper (priv->adjustment) -
+ gtk_adjustment_get_lower (priv->adjustment) -
+ gtk_adjustment_get_page_size (priv->adjustment)));
+ /* the above is ineffective for scales, so just set a zoom factor */
+ if (zoom == 1.0)
+ zoom = 0.25;
+ }
+ else
+ zoom = 1.0;
+
+ c = priv->slide_initial_slider_position + zoom * delta;
new_value = coord_to_value (range, c);
next_value = coord_to_value (range, c + 1);
- mark_delta = fabs (next_value - new_value);
+ mark_delta = fabs (next_value - new_value);
for (i = 0; i < priv->n_marks; i++)
{
@@ -2699,13 +2725,13 @@ update_slider_position (GtkRange *range,
break;
}
}
- }
+ }
g_signal_emit (range, signals[CHANGE_VALUE], 0, GTK_SCROLL_JUMP, new_value,
&handled);
}
-static void
+static void
stop_scrolling (GtkRange *range)
{
range_grab_remove (range);
@@ -2726,7 +2752,7 @@ gtk_range_grab_broken (GtkWidget *widget,
priv->grab_location != MOUSE_OUTSIDE)
{
if (priv->grab_location == MOUSE_SLIDER)
- update_slider_position (range, priv->mouse_x, priv->mouse_y);
+ update_slider_position (range, priv->mouse_x, priv->mouse_y);
stop_scrolling (range);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]