range: Use GtkGesture for event management

A multipress gesture takes care of clicks, and where those happened.
If the click is meant to move the slider while pressed, the drag gesture
takes over, dragging the slider while active.
This commit is contained in:
Carlos Garnacho 2014-06-05 15:29:14 +02:00
parent fbb3fdda8c
commit 26dff0d783

View File

@ -94,7 +94,6 @@ struct _GtkRangePrivate
GtkSensitivityType lower_sensitivity; GtkSensitivityType lower_sensitivity;
GtkSensitivityType upper_sensitivity; GtkSensitivityType upper_sensitivity;
GdkDevice *grab_device;
GdkRectangle range_rect; /* Area of entire stepper + trough assembly in widget->window coords */ GdkRectangle range_rect; /* Area of entire stepper + trough assembly in widget->window coords */
/* These are in widget->window coordinates */ /* These are in widget->window coordinates */
GdkRectangle stepper_a; GdkRectangle stepper_a;
@ -151,11 +150,12 @@ struct _GtkRangePrivate
GtkScrollType autoscroll_mode; GtkScrollType autoscroll_mode;
guint autoscroll_id; guint autoscroll_id;
GtkGesture *multipress_gesture;
GtkGesture *drag_gesture;
/* Fill level */ /* Fill level */
guint show_fill_level : 1; guint show_fill_level : 1;
guint restrict_to_fill_level : 1; guint restrict_to_fill_level : 1;
guint grab_button : 8; /* 0 if none */
}; };
@ -214,24 +214,35 @@ static void gtk_range_map (GtkWidget *widget);
static void gtk_range_unmap (GtkWidget *widget); static void gtk_range_unmap (GtkWidget *widget);
static gboolean gtk_range_draw (GtkWidget *widget, static gboolean gtk_range_draw (GtkWidget *widget,
cairo_t *cr); cairo_t *cr);
static gboolean gtk_range_button_press (GtkWidget *widget,
GdkEventButton *event); static void gtk_range_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
static gboolean gtk_range_button_release (GtkWidget *widget, guint n_press,
GdkEventButton *event); gdouble x,
static gboolean gtk_range_motion_notify (GtkWidget *widget, gdouble y,
GdkEventMotion *event); GtkRange *range);
static gboolean gtk_range_enter_notify (GtkWidget *widget, static void gtk_range_multipress_gesture_released (GtkGestureMultiPress *gesture,
GdkEventCrossing *event); guint n_press,
static gboolean gtk_range_leave_notify (GtkWidget *widget, gdouble x,
GdkEventCrossing *event); gdouble y,
static gboolean gtk_range_grab_broken (GtkWidget *widget, GtkRange *range);
GdkEventGrabBroken *event); static void gtk_range_drag_gesture_update (GtkGestureDrag *gesture,
static void gtk_range_grab_notify (GtkWidget *widget, gdouble offset_x,
gboolean was_grabbed); gdouble offset_y,
static void gtk_range_state_flags_changed (GtkWidget *widget, GtkRange *range);
GtkStateFlags previous_state); static void gtk_range_drag_gesture_end (GtkGestureDrag *gesture,
gdouble offset_x,
gdouble offset_y,
GtkRange *range);
static void gtk_range_long_press_gesture_pressed (GtkGestureLongPress *gesture,
gdouble x,
gdouble y,
GtkRange *range);
static gboolean gtk_range_scroll_event (GtkWidget *widget, static gboolean gtk_range_scroll_event (GtkWidget *widget,
GdkEventScroll *event); GdkEventScroll *event);
static gboolean gtk_range_event (GtkWidget *widget,
GdkEvent *event);
static void gtk_range_style_updated (GtkWidget *widget); static void gtk_range_style_updated (GtkWidget *widget);
static void update_slider_position (GtkRange *range, static void update_slider_position (GtkRange *range,
gint mouse_x, gint mouse_x,
@ -317,15 +328,8 @@ gtk_range_class_init (GtkRangeClass *class)
widget_class->map = gtk_range_map; widget_class->map = gtk_range_map;
widget_class->unmap = gtk_range_unmap; widget_class->unmap = gtk_range_unmap;
widget_class->draw = gtk_range_draw; widget_class->draw = gtk_range_draw;
widget_class->button_press_event = gtk_range_button_press; widget_class->event = gtk_range_event;
widget_class->button_release_event = gtk_range_button_release;
widget_class->motion_notify_event = gtk_range_motion_notify;
widget_class->scroll_event = gtk_range_scroll_event; widget_class->scroll_event = gtk_range_scroll_event;
widget_class->enter_notify_event = gtk_range_enter_notify;
widget_class->leave_notify_event = gtk_range_leave_notify;
widget_class->grab_broken_event = gtk_range_grab_broken;
widget_class->grab_notify = gtk_range_grab_notify;
widget_class->state_flags_changed = gtk_range_state_flags_changed;
widget_class->style_updated = gtk_range_style_updated; widget_class->style_updated = gtk_range_style_updated;
widget_class->key_press_event = gtk_range_key_press; widget_class->key_press_event = gtk_range_key_press;
@ -740,7 +744,6 @@ gtk_range_init (GtkRange *range)
priv->mouse_x = -1; priv->mouse_x = -1;
priv->mouse_y = -1; priv->mouse_y = -1;
priv->grab_location = MOUSE_OUTSIDE; priv->grab_location = MOUSE_OUTSIDE;
priv->grab_button = 0;
priv->lower_sensitivity = GTK_SENSITIVITY_AUTO; priv->lower_sensitivity = GTK_SENSITIVITY_AUTO;
priv->upper_sensitivity = GTK_SENSITIVITY_AUTO; priv->upper_sensitivity = GTK_SENSITIVITY_AUTO;
priv->lower_sensitive = TRUE; priv->lower_sensitive = TRUE;
@ -750,6 +753,39 @@ gtk_range_init (GtkRange *range)
priv->restrict_to_fill_level = TRUE; priv->restrict_to_fill_level = TRUE;
priv->fill_level = G_MAXDOUBLE; priv->fill_level = G_MAXDOUBLE;
priv->timer = NULL; priv->timer = NULL;
priv->multipress_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (range));
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->multipress_gesture),
FALSE);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->multipress_gesture),
GTK_PHASE_BUBBLE);
g_signal_connect (priv->multipress_gesture, "pressed",
G_CALLBACK (gtk_range_multipress_gesture_pressed), range);
g_signal_connect (priv->multipress_gesture, "released",
G_CALLBACK (gtk_range_multipress_gesture_released), range);
priv->drag_gesture = gtk_gesture_drag_new (GTK_WIDGET (range));
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->drag_gesture),
FALSE);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->drag_gesture),
GDK_BUTTON_PRIMARY);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->drag_gesture),
GTK_PHASE_BUBBLE);
g_signal_connect (priv->drag_gesture, "drag-update",
G_CALLBACK (gtk_range_drag_gesture_update), range);
g_signal_connect (priv->drag_gesture, "drag-end",
G_CALLBACK (gtk_range_drag_gesture_end), range);
priv->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (range));
gtk_gesture_group (priv->drag_gesture, priv->long_press_gesture);
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->long_press_gesture),
FALSE);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->long_press_gesture),
GDK_BUTTON_PRIMARY);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->long_press_gesture),
GTK_PHASE_BUBBLE);
g_signal_connect (priv->long_press_gesture, "pressed",
G_CALLBACK (gtk_range_long_press_gesture_pressed), range);
} }
/** /**
@ -1505,6 +1541,8 @@ gtk_range_destroy (GtkWidget *widget)
gtk_range_remove_step_timer (range); gtk_range_remove_step_timer (range);
g_clear_object (&priv->drag_gesture);
g_clear_object (&priv->multipress_gesture);
g_clear_object (&priv->long_press_gesture); g_clear_object (&priv->long_press_gesture);
if (priv->adjustment) if (priv->adjustment)
@ -2320,23 +2358,16 @@ gtk_range_draw (GtkWidget *widget,
static void static void
range_grab_add (GtkRange *range, range_grab_add (GtkRange *range,
GdkDevice *device, MouseLocation location)
MouseLocation location,
gint button)
{ {
GtkRangePrivate *priv = range->priv; GtkRangePrivate *priv = range->priv;
if (device == priv->grab_device)
return;
/* Don't perform any GDK/GTK+ grab here. Since a button /* Don't perform any GDK/GTK+ grab here. Since a button
* is down, there's an ongoing implicit grab on * is down, there's an ongoing implicit grab on
* priv->event_window, which pretty much guarantees this * priv->event_window, which pretty much guarantees this
* is the only widget receiving the pointer events. * is the only widget receiving the pointer events.
*/ */
priv->grab_location = location; priv->grab_location = location;
priv->grab_button = button;
priv->grab_device = device;
if (gtk_range_update_mouse_location (range)) if (gtk_range_update_mouse_location (range))
gtk_widget_queue_draw (GTK_WIDGET (range)); gtk_widget_queue_draw (GTK_WIDGET (range));
@ -2359,55 +2390,39 @@ update_zoom_state (GtkRange *range,
range->priv->zoom = enabled; range->priv->zoom = enabled;
} }
static void
update_zoom_set (GtkRange *range,
gboolean zoom_set)
{
if (zoom_set)
g_clear_object (&range->priv->long_press_gesture);
range->priv->zoom_set = zoom_set;
}
static void static void
range_grab_remove (GtkRange *range) range_grab_remove (GtkRange *range)
{ {
GtkRangePrivate *priv = range->priv; GtkRangePrivate *priv = range->priv;
MouseLocation location; MouseLocation location;
if (priv->grab_device)
{
GdkDevice *grab_device = priv->grab_device;
priv->grab_device = NULL;
gtk_device_grab_remove (GTK_WIDGET (range), grab_device);
}
location = priv->grab_location; location = priv->grab_location;
priv->grab_location = MOUSE_OUTSIDE; priv->grab_location = MOUSE_OUTSIDE;
priv->grab_button = 0;
if (gtk_range_update_mouse_location (range) || if (gtk_range_update_mouse_location (range) ||
location != MOUSE_OUTSIDE) location != MOUSE_OUTSIDE)
gtk_widget_queue_draw (GTK_WIDGET (range)); gtk_widget_queue_draw (GTK_WIDGET (range));
update_zoom_state (range, FALSE); update_zoom_state (range, FALSE);
update_zoom_set (range, FALSE); range->priv->zoom_set = FALSE;
} }
static GtkScrollType static GtkScrollType
range_get_scroll_for_grab (GtkRange *range) range_get_scroll_for_grab (GtkRange *range)
{ {
GtkRangePrivate *priv = range->priv; GtkRangePrivate *priv = range->priv;
guint grab_button;
gboolean invert; gboolean invert;
invert = should_invert (range); invert = should_invert (range);
grab_button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (range->priv->multipress_gesture));
switch (priv->grab_location) switch (priv->grab_location)
{ {
/* Backward stepper */ /* Backward stepper */
case MOUSE_STEPPER_A: case MOUSE_STEPPER_A:
case MOUSE_STEPPER_C: case MOUSE_STEPPER_C:
switch (priv->grab_button) switch (grab_button)
{ {
case GDK_BUTTON_PRIMARY: case GDK_BUTTON_PRIMARY:
return invert ? GTK_SCROLL_STEP_FORWARD : GTK_SCROLL_STEP_BACKWARD; return invert ? GTK_SCROLL_STEP_FORWARD : GTK_SCROLL_STEP_BACKWARD;
@ -2424,7 +2439,7 @@ range_get_scroll_for_grab (GtkRange *range)
/* Forward stepper */ /* Forward stepper */
case MOUSE_STEPPER_B: case MOUSE_STEPPER_B:
case MOUSE_STEPPER_D: case MOUSE_STEPPER_D:
switch (priv->grab_button) switch (grab_button)
{ {
case GDK_BUTTON_PRIMARY: case GDK_BUTTON_PRIMARY:
return invert ? GTK_SCROLL_STEP_BACKWARD : GTK_SCROLL_STEP_FORWARD; return invert ? GTK_SCROLL_STEP_BACKWARD : GTK_SCROLL_STEP_FORWARD;
@ -2519,7 +2534,8 @@ gtk_range_key_press (GtkWidget *widget,
device = gdk_event_get_device ((GdkEvent *) event); device = gdk_event_get_device ((GdkEvent *) event);
device = gdk_device_get_associated_device (device); device = gdk_device_get_associated_device (device);
if (device == priv->grab_device && if (gtk_gesture_is_active (priv->drag_gesture) &&
device == gtk_gesture_get_device (priv->drag_gesture) &&
event->keyval == GDK_KEY_Escape && event->keyval == GDK_KEY_Escape &&
priv->grab_location != MOUSE_OUTSIDE) priv->grab_location != MOUSE_OUTSIDE)
{ {
@ -2536,39 +2552,44 @@ gtk_range_key_press (GtkWidget *widget,
} }
static void static void
hold_action (GtkGestureLongPress *gesture, gtk_range_long_press_gesture_pressed (GtkGestureLongPress *gesture,
gdouble x, gdouble x,
gdouble y, gdouble y,
GtkRange *range) GtkRange *range)
{ {
update_zoom_state (range, TRUE); update_zoom_state (range, TRUE);
update_zoom_set (range, TRUE); range->priv->zoom_set = TRUE;
} }
static gint static void
gtk_range_button_press (GtkWidget *widget, gtk_range_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
GdkEventButton *event) guint n_press,
gdouble x,
gdouble y,
GtkRange *range)
{ {
GtkRange *range = GTK_RANGE (widget); GtkWidget *widget = GTK_WIDGET (range);
GtkRangePrivate *priv = range->priv; GtkRangePrivate *priv = range->priv;
GdkDevice *device, *source_device; GdkDevice *source_device;
GdkEventSequence *sequence;
const GdkEvent *event;
GdkInputSource source; GdkInputSource source;
gboolean primary_warps; gboolean primary_warps;
gint page_increment_button, warp_button; gint page_increment_button, warp_button;
guint button;
if (!gtk_widget_has_focus (widget)) if (!gtk_widget_has_focus (widget))
gtk_widget_grab_focus (widget); gtk_widget_grab_focus (widget);
/* ignore presses when we're already doing something else. */ sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
if (priv->grab_location != MOUSE_OUTSIDE) button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
return FALSE; event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
device = gdk_event_get_device ((GdkEvent *) event);
source_device = gdk_event_get_source_device ((GdkEvent *) event); source_device = gdk_event_get_source_device ((GdkEvent *) event);
source = gdk_device_get_source (source_device); source = gdk_device_get_source (source_device);
priv->mouse_x = event->x; priv->mouse_x = x;
priv->mouse_y = event->y; priv->mouse_y = y;
if (gtk_range_update_mouse_location (range)) if (gtk_range_update_mouse_location (range))
gtk_widget_queue_draw (widget); gtk_widget_queue_draw (widget);
@ -2594,12 +2615,12 @@ gtk_range_button_press (GtkWidget *widget,
g_signal_emit_by_name (widget, "popup-menu", &handled); g_signal_emit_by_name (widget, "popup-menu", &handled);
return TRUE; return;
} }
if (source != GDK_SOURCE_TOUCHSCREEN && if (source != GDK_SOURCE_TOUCHSCREEN &&
priv->mouse_location == MOUSE_TROUGH && priv->mouse_location == MOUSE_TROUGH &&
event->button == page_increment_button) button == page_increment_button)
{ {
/* button 2 steps by page increment, as with button 2 on a stepper /* button 2 steps by page increment, as with button 2 on a stepper
*/ */
@ -2608,30 +2629,28 @@ gtk_range_button_press (GtkWidget *widget,
click_value = coord_to_value (range, click_value = coord_to_value (range,
priv->orientation == GTK_ORIENTATION_VERTICAL ? priv->orientation == GTK_ORIENTATION_VERTICAL ?
event->y : event->x); y : x);
priv->trough_click_forward = click_value > gtk_adjustment_get_value (priv->adjustment); priv->trough_click_forward = click_value > gtk_adjustment_get_value (priv->adjustment);
range_grab_add (range, device, MOUSE_TROUGH, event->button); range_grab_add (range, MOUSE_TROUGH);
scroll = range_get_scroll_for_grab (range); scroll = range_get_scroll_for_grab (range);
gtk_range_add_step_timer (range, scroll); gtk_range_add_step_timer (range, scroll);
return TRUE;
} }
else if ((priv->mouse_location == MOUSE_STEPPER_A || else if ((priv->mouse_location == MOUSE_STEPPER_A ||
priv->mouse_location == MOUSE_STEPPER_B || priv->mouse_location == MOUSE_STEPPER_B ||
priv->mouse_location == MOUSE_STEPPER_C || priv->mouse_location == MOUSE_STEPPER_C ||
priv->mouse_location == MOUSE_STEPPER_D) && priv->mouse_location == MOUSE_STEPPER_D) &&
(event->button == GDK_BUTTON_PRIMARY || (button == GDK_BUTTON_PRIMARY ||
event->button == GDK_BUTTON_MIDDLE || button == GDK_BUTTON_MIDDLE ||
event->button == GDK_BUTTON_SECONDARY)) button == GDK_BUTTON_SECONDARY))
{ {
GtkAllocation allocation; GtkAllocation allocation;
GdkRectangle *stepper_area; GdkRectangle *stepper_area;
GtkScrollType scroll; GtkScrollType scroll;
range_grab_add (range, device, priv->mouse_location, event->button); range_grab_add (range, priv->mouse_location);
gtk_widget_get_allocation (widget, &allocation); gtk_widget_get_allocation (widget, &allocation);
stepper_area = get_area (range, priv->mouse_location); stepper_area = get_area (range, priv->mouse_location);
@ -2645,12 +2664,10 @@ gtk_range_button_press (GtkWidget *widget,
scroll = range_get_scroll_for_grab (range); scroll = range_get_scroll_for_grab (range);
if (scroll != GTK_SCROLL_NONE) if (scroll != GTK_SCROLL_NONE)
gtk_range_add_step_timer (range, scroll); gtk_range_add_step_timer (range, scroll);
return TRUE;
} }
else if ((priv->mouse_location == MOUSE_TROUGH && else if ((priv->mouse_location == MOUSE_TROUGH &&
(source == GDK_SOURCE_TOUCHSCREEN || (source == GDK_SOURCE_TOUCHSCREEN ||
event->button == warp_button)) || button == warp_button)) ||
priv->mouse_location == MOUSE_SLIDER) priv->mouse_location == MOUSE_SLIDER)
{ {
gboolean need_value_update = FALSE; gboolean need_value_update = FALSE;
@ -2666,12 +2683,12 @@ gtk_range_button_press (GtkWidget *widget,
slider_high_value = slider_high_value =
coord_to_value (range, coord_to_value (range,
priv->orientation == GTK_ORIENTATION_VERTICAL ? priv->orientation == GTK_ORIENTATION_VERTICAL ?
event->y : event->x); y : x);
slider_low_value = slider_low_value =
coord_to_value (range, coord_to_value (range,
priv->orientation == GTK_ORIENTATION_VERTICAL ? priv->orientation == GTK_ORIENTATION_VERTICAL ?
event->y - priv->slider.height : y - priv->slider.height :
event->x - priv->slider.width); x - priv->slider.width);
/* compute new value for warped slider */ /* compute new value for warped slider */
new_value = slider_low_value + (slider_high_value - slider_low_value) / 2; new_value = slider_low_value + (slider_high_value - slider_low_value) / 2;
@ -2689,53 +2706,55 @@ gtk_range_button_press (GtkWidget *widget,
} }
else else
{ {
GdkModifierType state_mask;
gdk_event_get_state (event, &state_mask);
/* Shift-click in the slider = fine adjustment */ /* Shift-click in the slider = fine adjustment */
if (event->state & GDK_SHIFT_MASK) if (state_mask & GDK_SHIFT_MASK)
{ {
update_zoom_state (range, TRUE); update_zoom_state (range, TRUE);
update_zoom_set (range, TRUE); range->priv->zoom_set = TRUE;
}
else
{
if (!priv->long_press_gesture)
{
priv->long_press_gesture =
gtk_gesture_long_press_new (widget);
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->long_press_gesture),
FALSE);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->long_press_gesture), 1);
g_signal_connect (priv->long_press_gesture, "pressed",
G_CALLBACK (hold_action), range);
}
gtk_event_controller_handle_event (GTK_EVENT_CONTROLLER (priv->long_press_gesture),
(const GdkEvent*) event);
} }
} }
if (priv->orientation == GTK_ORIENTATION_VERTICAL) if (priv->orientation == GTK_ORIENTATION_VERTICAL)
{ {
priv->slide_initial_slider_position = priv->slider.y; priv->slide_initial_slider_position = priv->slider.y;
priv->slide_initial_coordinate_delta = event->y - priv->slider.y; priv->slide_initial_coordinate_delta = y - priv->slider.y;
} }
else else
{ {
priv->slide_initial_slider_position = priv->slider.x; priv->slide_initial_slider_position = priv->slider.x;
priv->slide_initial_coordinate_delta = event->x - priv->slider.x; priv->slide_initial_coordinate_delta = x - priv->slider.x;
} }
range_grab_add (range, device, MOUSE_SLIDER, event->button); range_grab_add (range, MOUSE_SLIDER);
gtk_widget_queue_draw (widget); gtk_widget_queue_draw (widget);
if (need_value_update) if (need_value_update)
update_slider_position (range, event->x, event->y); update_slider_position (range, x, y);
return TRUE;
} }
return FALSE; if (priv->grab_location == MOUSE_SLIDER)
gtk_gesture_set_state (priv->drag_gesture, GTK_EVENT_SEQUENCE_CLAIMED);
else if (priv->grab_location != MOUSE_OUTSIDE)
gtk_gesture_set_state (priv->multipress_gesture, GTK_EVENT_SEQUENCE_CLAIMED);
}
static void
gtk_range_multipress_gesture_released (GtkGestureMultiPress *gesture,
guint n_press,
gdouble x,
gdouble y,
GtkRange *range)
{
GtkRangePrivate *priv = range->priv;
priv->mouse_x = x;
priv->mouse_y = y;
stop_scrolling (range);
} }
/* During a slide, move the slider as required given new mouse position */ /* During a slide, move the slider as required given new mouse position */
@ -2870,72 +2889,6 @@ stop_scrolling (GtkRange *range)
remove_autoscroll (range); remove_autoscroll (range);
} }
static gboolean
gtk_range_grab_broken (GtkWidget *widget,
GdkEventGrabBroken *event)
{
GtkRange *range = GTK_RANGE (widget);
GtkRangePrivate *priv = range->priv;
GdkDevice *device;
device = gdk_event_get_device ((GdkEvent *) event);
if (device == priv->grab_device &&
priv->grab_location != MOUSE_OUTSIDE)
{
if (priv->grab_location == MOUSE_SLIDER)
update_slider_position (range, priv->mouse_x, priv->mouse_y);
stop_scrolling (range);
return TRUE;
}
return FALSE;
}
static gint
gtk_range_button_release (GtkWidget *widget,
GdkEventButton *event)
{
GtkRange *range = GTK_RANGE (widget);
GtkRangePrivate *priv = range->priv;
GdkDevice *device;
if (event->window == priv->event_window)
{
priv->mouse_x = event->x;
priv->mouse_y = event->y;
}
else
{
gdk_window_get_device_position (priv->event_window,
event->device,
&priv->mouse_x,
&priv->mouse_y,
NULL);
}
device = gdk_event_get_device ((GdkEvent *) event);
if (priv->grab_device == device &&
priv->grab_button == event->button)
{
if (priv->grab_location == MOUSE_SLIDER)
{
if (priv->long_press_gesture)
gtk_event_controller_handle_event (GTK_EVENT_CONTROLLER (priv->long_press_gesture),
(const GdkEvent*) event);
}
stop_scrolling (range);
return TRUE;
}
return FALSE;
}
/** /**
* _gtk_range_get_wheel_delta: * _gtk_range_get_wheel_delta:
* @range: a #GtkRange * @range: a #GtkRange
@ -3049,85 +3002,57 @@ update_autoscroll_mode (GtkRange *range)
} }
} }
static void
gtk_range_drag_gesture_update (GtkGestureDrag *gesture,
gdouble offset_x,
gdouble offset_y,
GtkRange *range)
{
GtkRangePrivate *priv = range->priv;
gdouble start_x, start_y;
gtk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
priv->mouse_x = start_x + offset_x;
priv->mouse_y = start_y + offset_y;
update_autoscroll_mode (range);
if (priv->autoscroll_mode == GTK_SCROLL_NONE)
update_slider_position (range, priv->mouse_x, priv->mouse_y);
}
static void
gtk_range_drag_gesture_end (GtkGestureDrag *gesture,
gdouble offset_x,
gdouble offset_y,
GtkRange *range)
{
stop_scrolling (range);
}
static gboolean static gboolean
gtk_range_motion_notify (GtkWidget *widget, gtk_range_event (GtkWidget *widget,
GdkEventMotion *event) GdkEvent *event)
{ {
GtkRange *range = GTK_RANGE (widget); GtkRange *range = GTK_RANGE (widget);
GtkRangePrivate *priv = range->priv; GtkRangePrivate *priv = range->priv;
gdouble x, y;
gdk_event_request_motions (event); if (event->type == GDK_LEAVE_NOTIFY)
priv->mouse_x = event->x;
priv->mouse_y = event->y;
if (gtk_range_update_mouse_location (range))
gtk_widget_queue_draw (widget);
if (priv->grab_location == MOUSE_SLIDER)
{ {
if (!priv->zoom_set && priv->long_press_gesture != NULL) priv->mouse_x = -1;
gtk_event_controller_handle_event (GTK_EVENT_CONTROLLER (priv->long_press_gesture), priv->mouse_y = -1;
(const GdkEvent*) event); }
else if (gdk_event_get_coords (event, &x, &y))
update_autoscroll_mode (range); {
if (priv->autoscroll_mode == GTK_SCROLL_NONE) priv->mouse_x = x;
update_slider_position (range, event->x, event->y); priv->mouse_y = y;
} }
/* We handled the event if the mouse was in the range_rect */
return priv->mouse_location != MOUSE_OUTSIDE;
}
static gboolean
gtk_range_enter_notify (GtkWidget *widget,
GdkEventCrossing *event)
{
GtkRange *range = GTK_RANGE (widget);
GtkRangePrivate *priv = range->priv;
priv->mouse_x = event->x;
priv->mouse_y = event->y;
if (gtk_range_update_mouse_location (range)) if (gtk_range_update_mouse_location (range))
gtk_widget_queue_draw (widget); gtk_widget_queue_draw (widget);
return TRUE;
}
static gboolean return GDK_EVENT_PROPAGATE;
gtk_range_leave_notify (GtkWidget *widget,
GdkEventCrossing *event)
{
GtkRange *range = GTK_RANGE (widget);
GtkRangePrivate *priv = range->priv;
priv->mouse_x = -1;
priv->mouse_y = -1;
if (gtk_range_update_mouse_location (range))
gtk_widget_queue_draw (widget);
return TRUE;
}
static void
gtk_range_grab_notify (GtkWidget *widget,
gboolean was_grabbed)
{
GtkRangePrivate *priv = GTK_RANGE (widget)->priv;
if (priv->grab_device &&
gtk_widget_device_is_shadowed (widget, priv->grab_device))
stop_scrolling (GTK_RANGE (widget));
}
static void
gtk_range_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state)
{
if (!gtk_widget_is_sensitive (widget))
stop_scrolling (GTK_RANGE (widget));
} }
#define check_rectangle(rectangle1, rectangle2) \ #define check_rectangle(rectangle1, rectangle2) \