X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkrange.c;h=8339e52b70c195a829185fd0ddad7217012e3d79;hb=HEAD;hp=a224f4fd602ab4c07ae8f274b5e6b0ffbb029297;hpb=162614aab46441479fa2e562fa76ff8f2a71fc24;p=~andy%2Fgtk diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c index a224f4fd6..8339e52b7 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; @@ -1735,7 +1738,7 @@ gtk_range_realize (GtkWidget *widget) priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); - gdk_window_set_user_data (priv->event_window, range); + gtk_widget_register_window (widget, priv->event_window); } static void @@ -1746,7 +1749,7 @@ gtk_range_unrealize (GtkWidget *widget) gtk_range_remove_step_timer (range); - gdk_window_set_user_data (priv->event_window, NULL); + gtk_widget_unregister_window (widget, priv->event_window); gdk_window_destroy (priv->event_window); priv->event_window = NULL; @@ -2007,6 +2010,7 @@ gtk_range_draw (GtkWidget *widget, gboolean draw_trough = TRUE; gboolean draw_slider = TRUE; GtkStyleContext *context; + GtkBorder margin; context = gtk_widget_get_style_context (widget); @@ -2104,10 +2108,16 @@ gtk_range_draw (GtkWidget *widget, gtk_style_context_save (context); gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH); + gtk_style_context_get_margin (context, widget_state, &margin); + + x += margin.left; + y += margin.top; + width -= margin.left + margin.right; + height -= margin.top + margin.bottom; if (draw_trough) { - if (!priv->has_origin) + if (!priv->has_origin || !draw_slider) { gtk_render_background (context, cr, x, y, width, height); @@ -2233,13 +2243,6 @@ gtk_range_draw (GtkWidget *widget, fill_y += priv->trough.height - fill_height; } -#if 0 - if (fill_level < gtk_adjustment_get_upper (priv->adjustment) - gtk_adjustment_get_page_size (priv->adjustment)) - fill_detail = "trough-fill-level-full"; - else - fill_detail = "trough-fill-level"; -#endif - gtk_render_activity (context, cr, fill_x, fill_y, fill_width, fill_height); @@ -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; @@ -2517,6 +2522,8 @@ gtk_range_button_press (GtkWidget *widget, GtkRangePrivate *priv = range->priv; GdkDevice *device, *source_device; GdkInputSource source; + gboolean primary_warps; + gint page_increment_button, warp_button; if (!gtk_widget_has_focus (widget)) gtk_widget_grab_focus (widget); @@ -2535,6 +2542,20 @@ gtk_range_button_press (GtkWidget *widget, if (gtk_range_update_mouse_location (range)) gtk_widget_queue_draw (widget); + g_object_get (gtk_widget_get_settings (widget), + "gtk-primary-button-warps-slider", &primary_warps, + NULL); + if (primary_warps) + { + warp_button = GDK_BUTTON_PRIMARY; + page_increment_button = GDK_BUTTON_SECONDARY; + } + else + { + warp_button = GDK_BUTTON_MIDDLE; + page_increment_button = GDK_BUTTON_PRIMARY; + } + if (priv->mouse_location == MOUSE_SLIDER && gdk_event_triggers_context_menu ((GdkEvent *)event)) { @@ -2547,7 +2568,7 @@ gtk_range_button_press (GtkWidget *widget, if (source != GDK_SOURCE_TOUCHSCREEN && priv->mouse_location == MOUSE_TROUGH && - event->button == GDK_BUTTON_SECONDARY) + event->button == page_increment_button) { /* button 2 steps by page increment, as with button 2 on a stepper */ @@ -2598,7 +2619,7 @@ gtk_range_button_press (GtkWidget *widget, } else if ((priv->mouse_location == MOUSE_TROUGH && (source == GDK_SOURCE_TOUCHSCREEN || - event->button == GDK_BUTTON_PRIMARY)) || + event->button == warp_button)) || priv->mouse_location == MOUSE_SLIDER) { gboolean need_value_update = FALSE; @@ -2635,6 +2656,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 +2694,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 +2709,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 +2741,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 +2768,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); @@ -3557,13 +3599,15 @@ gtk_range_calc_layout (GtkRange *range, GtkRangePrivate *priv = range->priv; gint slider_width, stepper_size, focus_width, trough_border, stepper_spacing; gint slider_length; - GtkBorder border; + GtkBorder border, trough_margin; gint n_steppers; gboolean has_steppers_ab; gboolean has_steppers_cd; gboolean trough_under_steppers; GdkRectangle range_rect; GtkWidget *widget; + GtkStyleContext *context; + GtkStateFlags state; if (!priv->need_recalc) return; @@ -3579,6 +3623,13 @@ gtk_range_calc_layout (GtkRange *range, */ widget = GTK_WIDGET (range); + context = gtk_widget_get_style_context (widget); + + state = gtk_widget_get_state_flags (widget); + gtk_style_context_save (context); + gtk_style_context_add_class (context, GTK_STYLE_CLASS_TROUGH); + gtk_style_context_get_margin (context, state, &trough_margin); + gtk_style_context_restore (context); gtk_range_get_props (range, &slider_width, &stepper_size, @@ -3847,7 +3898,6 @@ gtk_range_calc_layout (GtkRange *range, */ priv->trough.x = priv->stepper_b.x + priv->stepper_b.width + stepper_spacing * has_steppers_ab; priv->trough.y = range_rect.y; - priv->trough.width = priv->stepper_c.x - priv->trough.x - stepper_spacing * has_steppers_cd; priv->trough.height = range_rect.height;