diff --git a/app/display/gimptoolcompass.c b/app/display/gimptoolcompass.c index c86d591bc5..617e5e9f35 100644 --- a/app/display/gimptoolcompass.c +++ b/app/display/gimptoolcompass.c @@ -130,6 +130,10 @@ static void gimp_tool_compass_motion (GimpToolWidget *widget const GimpCoords *coords, guint32 time, GdkModifierType state); +static GimpHit gimp_tool_compass_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity); static void gimp_tool_compass_hover (GimpToolWidget *widget, const GimpCoords *coords, GdkModifierType state, @@ -146,6 +150,8 @@ static gboolean gimp_tool_compass_get_cursor (GimpToolWidget *widget GimpToolCursorType *tool_cursor, GimpCursorModifier *modifier); +static gint gimp_tool_compass_get_point (GimpToolCompass *compass, + const GimpCoords *coords); static void gimp_tool_compass_update_hilight (GimpToolCompass *compass); @@ -170,6 +176,7 @@ gimp_tool_compass_class_init (GimpToolCompassClass *klass) widget_class->button_press = gimp_tool_compass_button_press; widget_class->button_release = gimp_tool_compass_button_release; widget_class->motion = gimp_tool_compass_motion; + widget_class->hit = gimp_tool_compass_hit; widget_class->hover = gimp_tool_compass_hover; widget_class->leave_notify = gimp_tool_compass_leave_notify; widget_class->motion_modifier = gimp_tool_compass_motion_modifier; @@ -781,6 +788,20 @@ gimp_tool_compass_motion (GimpToolWidget *widget, } } +GimpHit +gimp_tool_compass_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity) +{ + GimpToolCompass *compass = GIMP_TOOL_COMPASS (widget); + + if (gimp_tool_compass_get_point (compass, coords) >= 0) + return GIMP_HIT_DIRECT; + else + return GIMP_HIT_INDIRECT; +} + void gimp_tool_compass_hover (GimpToolWidget *widget, const GimpCoords *coords, @@ -789,85 +810,71 @@ gimp_tool_compass_hover (GimpToolWidget *widget, { GimpToolCompass *compass = GIMP_TOOL_COMPASS (widget); GimpToolCompassPrivate *private = compass->private; - gint point = -1; - gint i; + gint point; private->mouse_x = coords->x; private->mouse_y = coords->y; - for (i = 0; i < private->n_points; i++) + point = gimp_tool_compass_get_point (compass, coords); + + if (point >= 0) { - if (gimp_canvas_item_hit (private->handles[i], - coords->x, coords->y)) + GdkModifierType extend_mask = gimp_get_extend_selection_mask (); + GdkModifierType toggle_mask = gimp_get_toggle_behavior_mask (); + gchar *status; + + if (state & toggle_mask) { - GdkModifierType extend_mask = gimp_get_extend_selection_mask (); - GdkModifierType toggle_mask = gimp_get_toggle_behavior_mask (); - gchar *status; - - point = i; - - if (state & toggle_mask) - { - if (state & GDK_MOD1_MASK) - { - status = gimp_suggest_modifiers (_("Click to place " - "vertical and " - "horizontal guides"), - 0, - NULL, NULL, NULL); - } - else - { - status = gimp_suggest_modifiers (_("Click to place a " - "horizontal guide"), - GDK_MOD1_MASK & ~state, - NULL, NULL, NULL); - } - - gimp_tool_widget_set_status (widget, status); - g_free (status); - break; - } - if (state & GDK_MOD1_MASK) { - status = gimp_suggest_modifiers (_("Click to place a " - "vertical guide"), - toggle_mask & ~state, - NULL, NULL, NULL); - gimp_tool_widget_set_status (widget, status); - g_free (status); - break; - } - - if ((state & extend_mask) && - ! ((i == 0) && (private->n_points == 3))) - { - status = gimp_suggest_modifiers (_("Click-Drag to add a " - "new point"), - (toggle_mask | - GDK_MOD1_MASK) & ~state, + status = gimp_suggest_modifiers (_("Click to place " + "vertical and " + "horizontal guides"), + 0, NULL, NULL, NULL); } else { - if ((i == 0) && (private->n_points == 3)) - state |= extend_mask; - status = gimp_suggest_modifiers (_("Click-Drag to move this " - "point"), - (extend_mask | - toggle_mask | - GDK_MOD1_MASK) & ~state, + status = gimp_suggest_modifiers (_("Click to place a " + "horizontal guide"), + GDK_MOD1_MASK & ~state, NULL, NULL, NULL); } - - gimp_tool_widget_set_status (widget, status); - g_free (status); - break; } - } + else if (state & GDK_MOD1_MASK) + { + status = gimp_suggest_modifiers (_("Click to place a " + "vertical guide"), + toggle_mask & ~state, + NULL, NULL, NULL); + } + else if ((state & extend_mask) && + ! ((point == 0) && (private->n_points == 3))) + { + status = gimp_suggest_modifiers (_("Click-Drag to add a " + "new point"), + (toggle_mask | + GDK_MOD1_MASK) & ~state, + NULL, NULL, NULL); + } + else + { + if ((point == 0) && (private->n_points == 3)) + state |= extend_mask; - if (point == -1) + status = gimp_suggest_modifiers (_("Click-Drag to move this " + "point"), + (extend_mask | + toggle_mask | + GDK_MOD1_MASK) & ~state, + NULL, NULL, NULL); + } + + gimp_tool_widget_set_status (widget, status); + + g_free (status); + } + else { if ((private->n_points > 1) && (state & GDK_MOD1_MASK)) { @@ -1009,6 +1016,25 @@ gimp_tool_compass_get_cursor (GimpToolWidget *widget, return FALSE; } +static gint +gimp_tool_compass_get_point (GimpToolCompass *compass, + const GimpCoords *coords) +{ + GimpToolCompassPrivate *private = compass->private; + gint i; + + for (i = 0; i < private->n_points; i++) + { + if (gimp_canvas_item_hit (private->handles[i], + coords->x, coords->y)) + { + return i; + } + } + + return -1; +} + static void gimp_tool_compass_update_hilight (GimpToolCompass *compass) { diff --git a/app/display/gimptoolgyroscope.c b/app/display/gimptoolgyroscope.c index ebd22dbea2..0d5f4a57e5 100644 --- a/app/display/gimptoolgyroscope.c +++ b/app/display/gimptoolgyroscope.c @@ -127,6 +127,10 @@ static void gimp_tool_gyroscope_motion (GimpToolWidget *wi const GimpCoords *coords, guint32 time, GdkModifierType state); +static GimpHit gimp_tool_gyroscope_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity); static void gimp_tool_gyroscope_hover (GimpToolWidget *widget, const GimpCoords *coords, GdkModifierType state, @@ -173,6 +177,7 @@ gimp_tool_gyroscope_class_init (GimpToolGyroscopeClass *klass) widget_class->button_press = gimp_tool_gyroscope_button_press; widget_class->button_release = gimp_tool_gyroscope_button_release; widget_class->motion = gimp_tool_gyroscope_motion; + widget_class->hit = gimp_tool_gyroscope_hit; widget_class->hover = gimp_tool_gyroscope_hover; widget_class->key_press = gimp_tool_gyroscope_key_press; widget_class->motion_modifier = gimp_tool_gyroscope_motion_modifier; @@ -509,6 +514,15 @@ gimp_tool_gyroscope_motion (GimpToolWidget *widget, gimp_tool_gyroscope_rotate (gyroscope, &axis); } +static GimpHit +gimp_tool_gyroscope_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity) +{ + return GIMP_HIT_INDIRECT; +} + static void gimp_tool_gyroscope_hover (GimpToolWidget *widget, const GimpCoords *coords, diff --git a/app/display/gimptoolhandlegrid.c b/app/display/gimptoolhandlegrid.c index 8238ea71ea..53b032b35c 100644 --- a/app/display/gimptoolhandlegrid.c +++ b/app/display/gimptoolhandlegrid.c @@ -113,6 +113,10 @@ static void gimp_tool_handle_grid_motion (GimpToolWidget *widge const GimpCoords *coords, guint32 time, GdkModifierType state); +static GimpHit gimp_tool_handle_grid_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity); static void gimp_tool_handle_grid_hover (GimpToolWidget *widget, const GimpCoords *coords, GdkModifierType state, @@ -125,6 +129,8 @@ static gboolean gimp_tool_handle_grid_get_cursor (GimpToolWidget *widge GimpToolCursorType *tool_cursor, GimpCursorModifier *modifier); +static gint gimp_tool_handle_grid_get_handle (GimpToolHandleGrid *grid, + const GimpCoords *coords); static void gimp_tool_handle_grid_update_hilight (GimpToolHandleGrid *grid); static void gimp_tool_handle_grid_update_matrix (GimpToolHandleGrid *grid); @@ -169,6 +175,7 @@ gimp_tool_handle_grid_class_init (GimpToolHandleGridClass *klass) widget_class->button_press = gimp_tool_handle_grid_button_press; widget_class->button_release = gimp_tool_handle_grid_button_release; widget_class->motion = gimp_tool_handle_grid_motion; + widget_class->hit = gimp_tool_handle_grid_hit; widget_class->hover = gimp_tool_handle_grid_hover; widget_class->leave_notify = gimp_tool_handle_grid_leave_notify; widget_class->get_cursor = gimp_tool_handle_grid_get_cursor; @@ -795,6 +802,39 @@ gimp_tool_handle_grid_motion (GimpToolWidget *widget, private->last_y = coords->y; } +static GimpHit +gimp_tool_handle_grid_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity) +{ + GimpToolHandleGrid *grid = GIMP_TOOL_HANDLE_GRID (widget); + GimpToolHandleGridPrivate *private = grid->private; + + if (proximity) + { + gint handle = gimp_tool_handle_grid_get_handle (grid, coords); + + switch (private->handle_mode) + { + case GIMP_HANDLE_MODE_ADD_TRANSFORM: + if (handle > 0) + return GIMP_HIT_DIRECT; + else + return GIMP_HIT_INDIRECT; + break; + + case GIMP_HANDLE_MODE_MOVE: + case GIMP_HANDLE_MODE_REMOVE: + if (private->handle > 0) + return GIMP_HIT_DIRECT; + break; + } + } + + return GIMP_HIT_NONE; +} + static void gimp_tool_handle_grid_hover (GimpToolWidget *widget, const GimpCoords *coords, @@ -804,24 +844,12 @@ gimp_tool_handle_grid_hover (GimpToolWidget *widget, GimpToolHandleGrid *grid = GIMP_TOOL_HANDLE_GRID (widget); GimpToolHandleGridPrivate *private = grid->private; gchar *status = NULL; - gint i; private->hover = TRUE; private->mouse_x = coords->x; private->mouse_y = coords->y; - private->handle = 0; - - for (i = 0; i < 4; i++) - { - if (private->handles[i + 1] && - gimp_canvas_item_hit (private->handles[i + 1], - coords->x, coords->y)) - { - private->handle = i + 1; - break; - } - } + private->handle = gimp_tool_handle_grid_get_handle (grid, coords); if (proximity) { @@ -957,6 +985,26 @@ gimp_tool_handle_grid_get_cursor (GimpToolWidget *widget, return TRUE; } +static gint +gimp_tool_handle_grid_get_handle (GimpToolHandleGrid *grid, + const GimpCoords *coords) +{ + GimpToolHandleGridPrivate *private = grid->private; + gint i; + + for (i = 0; i < 4; i++) + { + if (private->handles[i + 1] && + gimp_canvas_item_hit (private->handles[i + 1], + coords->x, coords->y)) + { + return i + 1; + } + } + + return 0; +} + static void gimp_tool_handle_grid_update_hilight (GimpToolHandleGrid *grid) { diff --git a/app/display/gimptoolline.c b/app/display/gimptoolline.c index 792a2188ec..8ab3485b29 100644 --- a/app/display/gimptoolline.c +++ b/app/display/gimptoolline.c @@ -154,6 +154,10 @@ static void gimp_tool_line_motion (GimpToolWidget *widget, const GimpCoords *coords, guint32 time, GdkModifierType state); +static GimpHit gimp_tool_line_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity); static void gimp_tool_line_hover (GimpToolWidget *widget, const GimpCoords *coords, GdkModifierType state, @@ -172,6 +176,9 @@ static gboolean gimp_tool_line_get_cursor (GimpToolWidget *widget, GimpToolCursorType *tool_cursor, GimpCursorModifier *modifier); +static gint gimp_tool_line_get_hover (GimpToolLine *line, + const GimpCoords *coords, + GdkModifierType state); static GimpControllerSlider * gimp_tool_line_get_slider (GimpToolLine *line, gint slider); @@ -224,6 +231,7 @@ gimp_tool_line_class_init (GimpToolLineClass *klass) widget_class->button_press = gimp_tool_line_button_press; widget_class->button_release = gimp_tool_line_button_release; widget_class->motion = gimp_tool_line_motion; + widget_class->hit = gimp_tool_line_hit; widget_class->hover = gimp_tool_line_hover; widget_class->leave_notify = gimp_tool_line_leave_notify; widget_class->key_press = gimp_tool_line_key_press; @@ -810,6 +818,29 @@ gimp_tool_line_motion (GimpToolWidget *widget, gimp_tool_line_update_status (line, state, TRUE); } +GimpHit +gimp_tool_line_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity) +{ + GimpToolLine *line = GIMP_TOOL_LINE (widget); + + if (! (state & GRAB_LINE_MASK)) + { + gint hover = gimp_tool_line_get_hover (line, coords, state); + + if (hover != GIMP_TOOL_LINE_HANDLE_NONE) + return GIMP_HIT_DIRECT; + } + else + { + return GIMP_HIT_INDIRECT; + } + + return GIMP_HIT_NONE; +} + void gimp_tool_line_hover (GimpToolWidget *widget, const GimpCoords *coords, @@ -818,80 +849,14 @@ gimp_tool_line_hover (GimpToolWidget *widget, { GimpToolLine *line = GIMP_TOOL_LINE (widget); GimpToolLinePrivate *private = line->private; - gint i; private->mouse_x = coords->x; private->mouse_y = coords->y; - private->hover = GIMP_TOOL_LINE_HANDLE_NONE; - if (! (state & GRAB_LINE_MASK)) - { - /* find the closest handle to the cursor */ - gdouble min_dist = G_MAXDOUBLE; - gint first_handle = private->sliders->len - 1; - - /* skip the sliders if the two endpoints are the same, in particular so - * that if the line is created during a button-press event (as in the - * blend tool), the end endpoint is dragged, instead of a slider. - */ - if (private->x1 == private->x2 && private->y1 == private->y2) - first_handle = -1; - - for (i = first_handle; i > GIMP_TOOL_LINE_HANDLE_NONE; i--) - { - GimpCanvasItem *handle; - - if (GIMP_TOOL_LINE_HANDLE_IS_SLIDER (i)) - { - const GimpControllerSlider *slider; - - slider = gimp_tool_line_get_slider (line, i); - - if (! slider->visible || ! slider->selectable) - continue; - } - - handle = gimp_tool_line_get_handle (line, i); - - if (gimp_tool_line_handle_hit (handle, - private->mouse_x, - private->mouse_y, - &min_dist)) - { - private->hover = i; - } - } - - if (private->hover == GIMP_TOOL_LINE_HANDLE_NONE) - { - gboolean constrain; - gdouble value; - gdouble dist; - - constrain = (state & gimp_get_constrain_behavior_mask ()) != 0; - - value = gimp_tool_line_project_point (line, - private->mouse_x, - private->mouse_y, - constrain, - &dist); - - if (value >= 0.0 && value <= 1.0 && dist <= LINE_VICINITY) - { - gboolean can_add; - - g_signal_emit (line, line_signals[CAN_ADD_SLIDER], 0, - value, &can_add); - - if (can_add) - { - private->hover = HOVER_NEW_SLIDER; - private->new_slider_value = value; - } - } - } - } + private->hover = gimp_tool_line_get_hover (line, coords, state); + else + private->hover = GIMP_TOOL_LINE_HANDLE_NONE; gimp_tool_line_update_handles (line); gimp_tool_line_update_circle (line); @@ -1121,6 +1086,85 @@ gimp_tool_line_get_cursor (GimpToolWidget *widget, return FALSE; } +static gint +gimp_tool_line_get_hover (GimpToolLine *line, + const GimpCoords *coords, + GdkModifierType state) +{ + GimpToolLinePrivate *private = line->private; + gint hover = GIMP_TOOL_LINE_HANDLE_NONE; + gdouble min_dist; + gint first_handle; + gint i; + + /* find the closest handle to the cursor */ + min_dist = G_MAXDOUBLE; + first_handle = private->sliders->len - 1; + + /* skip the sliders if the two endpoints are the same, in particular so + * that if the line is created during a button-press event (as in the + * blend tool), the end endpoint is dragged, instead of a slider. + */ + if (private->x1 == private->x2 && private->y1 == private->y2) + first_handle = -1; + + for (i = first_handle; i > GIMP_TOOL_LINE_HANDLE_NONE; i--) + { + GimpCanvasItem *handle; + + if (GIMP_TOOL_LINE_HANDLE_IS_SLIDER (i)) + { + const GimpControllerSlider *slider; + + slider = gimp_tool_line_get_slider (line, i); + + if (! slider->visible || ! slider->selectable) + continue; + } + + handle = gimp_tool_line_get_handle (line, i); + + if (gimp_tool_line_handle_hit (handle, + private->mouse_x, + private->mouse_y, + &min_dist)) + { + hover = i; + } + } + + if (hover == GIMP_TOOL_LINE_HANDLE_NONE) + { + gboolean constrain; + gdouble value; + gdouble dist; + + constrain = (state & gimp_get_constrain_behavior_mask ()) != 0; + + value = gimp_tool_line_project_point (line, + private->mouse_x, + private->mouse_y, + constrain, + &dist); + + if (value >= 0.0 && value <= 1.0 && dist <= LINE_VICINITY) + { + gboolean can_add; + + g_signal_emit (line, line_signals[CAN_ADD_SLIDER], 0, + value, &can_add); + + if (can_add) + { + hover = HOVER_NEW_SLIDER; + private->new_slider_value = value; + } + } + } + + return hover; +} + static GimpControllerSlider * gimp_tool_line_get_slider (GimpToolLine *line, gint slider) diff --git a/app/display/gimptoolpath.c b/app/display/gimptoolpath.c index 0632136c4c..6b31f128a9 100644 --- a/app/display/gimptoolpath.c +++ b/app/display/gimptoolpath.c @@ -151,6 +151,10 @@ static void gimp_tool_path_motion (GimpToolWidget *widget, const GimpCoords *coords, guint32 time, GdkModifierType state); +static GimpHit gimp_tool_path_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity); static void gimp_tool_path_hover (GimpToolWidget *widget, const GimpCoords *coords, GdkModifierType state, @@ -164,6 +168,11 @@ static gboolean gimp_tool_path_get_cursor (GimpToolWidget *widget, GimpToolCursorType *tool_cursor, GimpCursorModifier *modifier); +static GimpVectorFunction + gimp_tool_path_get_function (GimpToolPath *path, + const GimpCoords *coords, + GdkModifierType state); + static void gimp_tool_path_update_status (GimpToolPath *path, GdkModifierType state, gboolean proximity); @@ -212,6 +221,7 @@ gimp_tool_path_class_init (GimpToolPathClass *klass) widget_class->button_press = gimp_tool_path_button_press; widget_class->button_release = gimp_tool_path_button_release; widget_class->motion = gimp_tool_path_motion; + widget_class->hit = gimp_tool_path_hit; widget_class->hover = gimp_tool_path_hover; widget_class->key_press = gimp_tool_path_key_press; widget_class->get_cursor = gimp_tool_path_get_cursor; @@ -1009,243 +1019,52 @@ gimp_tool_path_motion (GimpToolWidget *widget, private->last_y = coords->y; } +GimpHit +gimp_tool_path_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity) +{ + GimpToolPath *path = GIMP_TOOL_PATH (widget); + + switch (gimp_tool_path_get_function (path, coords, state)) + { + case VECTORS_SELECT_VECTOR: + case VECTORS_MOVE_ANCHOR: + case VECTORS_MOVE_ANCHORSET: + case VECTORS_MOVE_HANDLE: + case VECTORS_MOVE_CURVE: + case VECTORS_MOVE_STROKE: + case VECTORS_DELETE_ANCHOR: + case VECTORS_DELETE_SEGMENT: + case VECTORS_INSERT_ANCHOR: + case VECTORS_CONNECT_STROKES: + case VECTORS_CONVERT_EDGE: + return GIMP_HIT_DIRECT; + + case VECTORS_CREATE_VECTOR: + case VECTORS_CREATE_STROKE: + case VECTORS_ADD_ANCHOR: + case VECTORS_MOVE_VECTORS: + return GIMP_HIT_INDIRECT; + + case VECTORS_FINISHED: + return GIMP_HIT_NONE; + } + + return GIMP_HIT_NONE; +} + void gimp_tool_path_hover (GimpToolWidget *widget, const GimpCoords *coords, GdkModifierType state, gboolean proximity) { - GimpToolPath *path = GIMP_TOOL_PATH (widget); - GimpToolPathPrivate *private = path->private; - GimpAnchor *anchor = NULL; - GimpAnchor *anchor2 = NULL; - GimpStroke *stroke = NULL; - gdouble position = -1; - gboolean on_handle = FALSE; - gboolean on_curve = FALSE; - gboolean on_vectors = FALSE; + GimpToolPath *path = GIMP_TOOL_PATH (widget); + GimpToolPathPrivate *private = path->private; - private->modifier_lock = FALSE; - - /* are we hovering the current vectors on the current display? */ - if (private->vectors) - { - on_handle = gimp_canvas_item_on_vectors_handle (private->path, - private->vectors, - coords, - GIMP_CANVAS_HANDLE_SIZE_CIRCLE, - GIMP_CANVAS_HANDLE_SIZE_CIRCLE, - GIMP_ANCHOR_ANCHOR, - private->sel_count > 2, - &anchor, &stroke); - - if (! on_handle) - on_curve = gimp_canvas_item_on_vectors_curve (private->path, - private->vectors, - coords, - GIMP_CANVAS_HANDLE_SIZE_CIRCLE, - GIMP_CANVAS_HANDLE_SIZE_CIRCLE, - NULL, - &position, &anchor, - &anchor2, &stroke); - } - - if (! on_handle && ! on_curve) - { - on_vectors = gimp_canvas_item_on_vectors (private->path, - coords, - GIMP_CANVAS_HANDLE_SIZE_CIRCLE, - GIMP_CANVAS_HANDLE_SIZE_CIRCLE, - NULL, NULL, NULL, NULL, NULL, - NULL); - } - - private->cur_position = position; - private->cur_anchor = anchor; - private->cur_anchor2 = anchor2; - private->cur_stroke = stroke; - - switch (private->edit_mode) - { - case GIMP_VECTOR_MODE_DESIGN: - if (! private->vectors) - { - if (on_vectors) - { - private->function = VECTORS_SELECT_VECTOR; - } - else - { - private->function = VECTORS_CREATE_VECTOR; - private->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC; - private->modifier_lock = TRUE; - } - } - else if (on_handle) - { - if (anchor->type == GIMP_ANCHOR_ANCHOR) - { - if (state & TOGGLE_MASK) - { - private->function = VECTORS_MOVE_ANCHORSET; - } - else - { - if (private->sel_count >= 2 && anchor->selected) - private->function = VECTORS_MOVE_ANCHORSET; - else - private->function = VECTORS_MOVE_ANCHOR; - } - } - else - { - private->function = VECTORS_MOVE_HANDLE; - - if (state & TOGGLE_MASK) - private->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC; - else - private->restriction = GIMP_ANCHOR_FEATURE_NONE; - } - } - else if (on_curve) - { - if (gimp_stroke_point_is_movable (stroke, anchor, position)) - { - private->function = VECTORS_MOVE_CURVE; - - if (state & TOGGLE_MASK) - private->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC; - else - private->restriction = GIMP_ANCHOR_FEATURE_NONE; - } - else - { - private->function = VECTORS_FINISHED; - } - } - else - { - if (private->sel_stroke && - private->sel_anchor && - gimp_stroke_is_extendable (private->sel_stroke, - private->sel_anchor) && - ! (state & TOGGLE_MASK)) - private->function = VECTORS_ADD_ANCHOR; - else - private->function = VECTORS_CREATE_STROKE; - - private->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC; - private->modifier_lock = TRUE; - } - - break; - - case GIMP_VECTOR_MODE_EDIT: - if (! private->vectors) - { - if (on_vectors) - { - private->function = VECTORS_SELECT_VECTOR; - } - else - { - private->function = VECTORS_FINISHED; - } - } - else if (on_handle) - { - if (anchor->type == GIMP_ANCHOR_ANCHOR) - { - if (! (state & TOGGLE_MASK) && - private->sel_anchor && - private->sel_anchor != anchor && - gimp_stroke_is_extendable (private->sel_stroke, - private->sel_anchor) && - gimp_stroke_is_extendable (stroke, anchor)) - { - private->function = VECTORS_CONNECT_STROKES; - } - else - { - if (state & TOGGLE_MASK) - { - private->function = VECTORS_DELETE_ANCHOR; - } - else - { - if (private->polygonal) - private->function = VECTORS_MOVE_ANCHOR; - else - private->function = VECTORS_MOVE_HANDLE; - } - } - } - else - { - if (state & TOGGLE_MASK) - private->function = VECTORS_CONVERT_EDGE; - else - private->function = VECTORS_MOVE_HANDLE; - } - } - else if (on_curve) - { - if (state & TOGGLE_MASK) - { - private->function = VECTORS_DELETE_SEGMENT; - } - else if (gimp_stroke_anchor_is_insertable (stroke, anchor, position)) - { - private->function = VECTORS_INSERT_ANCHOR; - } - else - { - private->function = VECTORS_FINISHED; - } - } - else - { - private->function = VECTORS_FINISHED; - } - - break; - - case GIMP_VECTOR_MODE_MOVE: - if (! private->vectors) - { - if (on_vectors) - { - private->function = VECTORS_SELECT_VECTOR; - } - else - { - private->function = VECTORS_FINISHED; - } - } - else if (on_handle || on_curve) - { - if (state & TOGGLE_MASK) - { - private->function = VECTORS_MOVE_VECTORS; - } - else - { - private->function = VECTORS_MOVE_STROKE; - } - } - else - { - if (on_vectors) - { - private->function = VECTORS_SELECT_VECTOR; - } - else - { - private->function = VECTORS_MOVE_VECTORS; - } - } - break; - } + private->function = gimp_tool_path_get_function (path, coords, state); gimp_tool_path_update_status (path, state, proximity); } @@ -1419,6 +1238,246 @@ gimp_tool_path_get_cursor (GimpToolWidget *widget, return TRUE; } +static GimpVectorFunction +gimp_tool_path_get_function (GimpToolPath *path, + const GimpCoords *coords, + GdkModifierType state) +{ + GimpToolPathPrivate *private = path->private; + GimpAnchor *anchor = NULL; + GimpAnchor *anchor2 = NULL; + GimpStroke *stroke = NULL; + gdouble position = -1; + gboolean on_handle = FALSE; + gboolean on_curve = FALSE; + gboolean on_vectors = FALSE; + GimpVectorFunction function = VECTORS_FINISHED; + + private->modifier_lock = FALSE; + + /* are we hovering the current vectors on the current display? */ + if (private->vectors) + { + on_handle = gimp_canvas_item_on_vectors_handle (private->path, + private->vectors, + coords, + GIMP_CANVAS_HANDLE_SIZE_CIRCLE, + GIMP_CANVAS_HANDLE_SIZE_CIRCLE, + GIMP_ANCHOR_ANCHOR, + private->sel_count > 2, + &anchor, &stroke); + + if (! on_handle) + on_curve = gimp_canvas_item_on_vectors_curve (private->path, + private->vectors, + coords, + GIMP_CANVAS_HANDLE_SIZE_CIRCLE, + GIMP_CANVAS_HANDLE_SIZE_CIRCLE, + NULL, + &position, &anchor, + &anchor2, &stroke); + } + + if (! on_handle && ! on_curve) + { + on_vectors = gimp_canvas_item_on_vectors (private->path, + coords, + GIMP_CANVAS_HANDLE_SIZE_CIRCLE, + GIMP_CANVAS_HANDLE_SIZE_CIRCLE, + NULL, NULL, NULL, NULL, NULL, + NULL); + } + + private->cur_position = position; + private->cur_anchor = anchor; + private->cur_anchor2 = anchor2; + private->cur_stroke = stroke; + + switch (private->edit_mode) + { + case GIMP_VECTOR_MODE_DESIGN: + if (! private->vectors) + { + if (on_vectors) + { + function = VECTORS_SELECT_VECTOR; + } + else + { + function = VECTORS_CREATE_VECTOR; + private->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC; + private->modifier_lock = TRUE; + } + } + else if (on_handle) + { + if (anchor->type == GIMP_ANCHOR_ANCHOR) + { + if (state & TOGGLE_MASK) + { + function = VECTORS_MOVE_ANCHORSET; + } + else + { + if (private->sel_count >= 2 && anchor->selected) + function = VECTORS_MOVE_ANCHORSET; + else + function = VECTORS_MOVE_ANCHOR; + } + } + else + { + function = VECTORS_MOVE_HANDLE; + + if (state & TOGGLE_MASK) + private->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC; + else + private->restriction = GIMP_ANCHOR_FEATURE_NONE; + } + } + else if (on_curve) + { + if (gimp_stroke_point_is_movable (stroke, anchor, position)) + { + function = VECTORS_MOVE_CURVE; + + if (state & TOGGLE_MASK) + private->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC; + else + private->restriction = GIMP_ANCHOR_FEATURE_NONE; + } + else + { + function = VECTORS_FINISHED; + } + } + else + { + if (private->sel_stroke && + private->sel_anchor && + gimp_stroke_is_extendable (private->sel_stroke, + private->sel_anchor) && + ! (state & TOGGLE_MASK)) + function = VECTORS_ADD_ANCHOR; + else + function = VECTORS_CREATE_STROKE; + + private->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC; + private->modifier_lock = TRUE; + } + + break; + + case GIMP_VECTOR_MODE_EDIT: + if (! private->vectors) + { + if (on_vectors) + { + function = VECTORS_SELECT_VECTOR; + } + else + { + function = VECTORS_FINISHED; + } + } + else if (on_handle) + { + if (anchor->type == GIMP_ANCHOR_ANCHOR) + { + if (! (state & TOGGLE_MASK) && + private->sel_anchor && + private->sel_anchor != anchor && + gimp_stroke_is_extendable (private->sel_stroke, + private->sel_anchor) && + gimp_stroke_is_extendable (stroke, anchor)) + { + function = VECTORS_CONNECT_STROKES; + } + else + { + if (state & TOGGLE_MASK) + { + function = VECTORS_DELETE_ANCHOR; + } + else + { + if (private->polygonal) + function = VECTORS_MOVE_ANCHOR; + else + function = VECTORS_MOVE_HANDLE; + } + } + } + else + { + if (state & TOGGLE_MASK) + function = VECTORS_CONVERT_EDGE; + else + function = VECTORS_MOVE_HANDLE; + } + } + else if (on_curve) + { + if (state & TOGGLE_MASK) + { + function = VECTORS_DELETE_SEGMENT; + } + else if (gimp_stroke_anchor_is_insertable (stroke, anchor, position)) + { + function = VECTORS_INSERT_ANCHOR; + } + else + { + function = VECTORS_FINISHED; + } + } + else + { + function = VECTORS_FINISHED; + } + + break; + + case GIMP_VECTOR_MODE_MOVE: + if (! private->vectors) + { + if (on_vectors) + { + function = VECTORS_SELECT_VECTOR; + } + else + { + function = VECTORS_FINISHED; + } + } + else if (on_handle || on_curve) + { + if (state & TOGGLE_MASK) + { + function = VECTORS_MOVE_VECTORS; + } + else + { + function = VECTORS_MOVE_STROKE; + } + } + else + { + if (on_vectors) + { + function = VECTORS_SELECT_VECTOR; + } + else + { + function = VECTORS_MOVE_VECTORS; + } + } + break; + } + + return function; +} + static void gimp_tool_path_update_status (GimpToolPath *path, GdkModifierType state, diff --git a/app/display/gimptoolpolygon.c b/app/display/gimptoolpolygon.c index a32cbd57d2..3e3571fd81 100644 --- a/app/display/gimptoolpolygon.c +++ b/app/display/gimptoolpolygon.c @@ -162,6 +162,10 @@ static void gimp_tool_polygon_motion (GimpToolWidget *widget const GimpCoords *coords, guint32 time, GdkModifierType state); +static GimpHit gimp_tool_polygon_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity); static void gimp_tool_polygon_hover (GimpToolWidget *widget, const GimpCoords *coords, GdkModifierType state, @@ -184,6 +188,9 @@ static gboolean gimp_tool_polygon_get_cursor (GimpToolWidget *widget GimpToolCursorType *tool_cursor, GimpCursorModifier *modifier); +static gint gimp_tool_polygon_get_segment_index (GimpToolPolygon *polygon, + const GimpCoords *coords); + G_DEFINE_TYPE (GimpToolPolygon, gimp_tool_polygon, GIMP_TYPE_TOOL_WIDGET) @@ -207,6 +214,7 @@ gimp_tool_polygon_class_init (GimpToolPolygonClass *klass) widget_class->button_press = gimp_tool_polygon_button_press; widget_class->button_release = gimp_tool_polygon_button_release; widget_class->motion = gimp_tool_polygon_motion; + widget_class->hit = gimp_tool_polygon_hit; widget_class->hover = gimp_tool_polygon_hover; widget_class->leave_notify = gimp_tool_polygon_leave_notify; widget_class->key_press = gimp_tool_polygon_key_press; @@ -1190,6 +1198,29 @@ gimp_tool_polygon_motion (GimpToolWidget *widget, gimp_tool_polygon_changed (widget); } +static GimpHit +gimp_tool_polygon_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity) +{ + GimpToolPolygon *polygon = GIMP_TOOL_POLYGON (widget); + GimpToolPolygonPrivate *priv = polygon->private; + + if ((priv->n_points > 0 && ! priv->polygon_closed) || + gimp_tool_polygon_get_segment_index (polygon, coords) != INVALID_INDEX) + { + return GIMP_HIT_DIRECT; + } + else if (priv->polygon_closed && + gimp_canvas_item_hit (priv->polygon, coords->x, coords->y)) + { + return GIMP_HIT_INDIRECT; + } + + return GIMP_HIT_NONE; +} + static void gimp_tool_polygon_hover (GimpToolWidget *widget, const GimpCoords *coords, @@ -1200,36 +1231,10 @@ gimp_tool_polygon_hover (GimpToolWidget *widget, GimpToolPolygonPrivate *priv = polygon->private; gboolean hovering_first_point; - priv->grabbed_segment_index = INVALID_INDEX; + priv->grabbed_segment_index = gimp_tool_polygon_get_segment_index (polygon, + coords); priv->hover = TRUE; - if (! priv->supress_handles) - { - gdouble shortest_dist = POINT_GRAB_THRESHOLD_SQ; - gint i; - - for (i = 0; i < priv->n_segment_indices; i++) - { - gdouble dist; - GimpVector2 *point; - - point = &priv->points[priv->segment_indices[i]]; - - dist = gimp_canvas_item_transform_distance_square (priv->polygon, - coords->x, - coords->y, - point->x, - point->y); - - if (dist < shortest_dist) - { - shortest_dist = dist; - - priv->grabbed_segment_index = i; - } - } - } - hovering_first_point = gimp_tool_polygon_should_close (polygon, NO_CLICK_TIME_AVAILABLE, @@ -1383,6 +1388,43 @@ gimp_tool_polygon_get_cursor (GimpToolWidget *widget, return FALSE; } +static gint +gimp_tool_polygon_get_segment_index (GimpToolPolygon *polygon, + const GimpCoords *coords) +{ + GimpToolPolygonPrivate *priv = polygon->private; + gint segment_index = INVALID_INDEX; + + if (! priv->supress_handles) + { + gdouble shortest_dist = POINT_GRAB_THRESHOLD_SQ; + gint i; + + for (i = 0; i < priv->n_segment_indices; i++) + { + gdouble dist; + GimpVector2 *point; + + point = &priv->points[priv->segment_indices[i]]; + + dist = gimp_canvas_item_transform_distance_square (priv->polygon, + coords->x, + coords->y, + point->x, + point->y); + + if (dist < shortest_dist) + { + shortest_dist = dist; + + segment_index = i; + } + } + } + + return segment_index; +} + /* public functions */ diff --git a/app/display/gimptoolrectangle.c b/app/display/gimptoolrectangle.c index d24030653b..c2057c5e95 100644 --- a/app/display/gimptoolrectangle.c +++ b/app/display/gimptoolrectangle.c @@ -301,6 +301,10 @@ static void gimp_tool_rectangle_motion (GimpToolWidget *widg const GimpCoords *coords, guint32 time, GdkModifierType state); +static GimpHit gimp_tool_rectangle_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity); static void gimp_tool_rectangle_hover (GimpToolWidget *widget, const GimpCoords *coords, GdkModifierType state, @@ -332,6 +336,10 @@ static void gimp_tool_rectangle_synthesize_motion gdouble new_x, gdouble new_y); +static GimpRectangleFunction + gimp_tool_rectangle_calc_function (GimpToolRectangle *rectangle, + const GimpCoords *coords, + gboolean proximity); static void gimp_tool_rectangle_check_function (GimpToolRectangle *rectangle); static gboolean gimp_tool_rectangle_coord_outside (GimpToolRectangle *rectangle, @@ -449,6 +457,7 @@ gimp_tool_rectangle_class_init (GimpToolRectangleClass *klass) widget_class->button_press = gimp_tool_rectangle_button_press; widget_class->button_release = gimp_tool_rectangle_button_release; widget_class->motion = gimp_tool_rectangle_motion; + widget_class->hit = gimp_tool_rectangle_hit; widget_class->hover = gimp_tool_rectangle_hover; widget_class->leave_notify = gimp_tool_rectangle_leave_notify; widget_class->key_press = gimp_tool_rectangle_key_press; @@ -1660,6 +1669,50 @@ gimp_tool_rectangle_motion (GimpToolWidget *widget, private->lasty = snapped_y; } +GimpHit +gimp_tool_rectangle_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity) +{ + GimpToolRectangle *rectangle = GIMP_TOOL_RECTANGLE (widget); + GimpToolRectanglePrivate *private = rectangle->private; + GimpRectangleFunction function; + + if (private->suppress_updates) + { + function = gimp_tool_rectangle_get_function (rectangle); + } + else + { + function = gimp_tool_rectangle_calc_function (rectangle, + coords, proximity); + } + + switch (function) + { + case GIMP_TOOL_RECTANGLE_RESIZING_UPPER_LEFT: + case GIMP_TOOL_RECTANGLE_RESIZING_UPPER_RIGHT: + case GIMP_TOOL_RECTANGLE_RESIZING_LOWER_LEFT: + case GIMP_TOOL_RECTANGLE_RESIZING_LOWER_RIGHT: + case GIMP_TOOL_RECTANGLE_RESIZING_LEFT: + case GIMP_TOOL_RECTANGLE_RESIZING_RIGHT: + case GIMP_TOOL_RECTANGLE_RESIZING_TOP: + case GIMP_TOOL_RECTANGLE_RESIZING_BOTTOM: + return GIMP_HIT_DIRECT; + + case GIMP_TOOL_RECTANGLE_CREATING: + case GIMP_TOOL_RECTANGLE_MOVING: + return GIMP_HIT_INDIRECT; + + case GIMP_TOOL_RECTANGLE_DEAD: + case GIMP_TOOL_RECTANGLE_AUTO_SHRINK: + case GIMP_TOOL_RECTANGLE_EXECUTING: + default: + return GIMP_HIT_NONE; + } +} + void gimp_tool_rectangle_hover (GimpToolWidget *widget, const GimpCoords *coords, @@ -1668,7 +1721,7 @@ gimp_tool_rectangle_hover (GimpToolWidget *widget, { GimpToolRectangle *rectangle = GIMP_TOOL_RECTANGLE (widget); GimpToolRectanglePrivate *private = rectangle->private; - GimpRectangleFunction function = GIMP_TOOL_RECTANGLE_DEAD; + GimpRectangleFunction function; if (private->suppress_updates) { @@ -1676,75 +1729,7 @@ gimp_tool_rectangle_hover (GimpToolWidget *widget, return; } - if (! proximity) - { - function = GIMP_TOOL_RECTANGLE_DEAD; - } - else if (gimp_tool_rectangle_coord_outside (rectangle, coords)) - { - /* The cursor is outside of the rectangle, clicking should - * create a new rectangle. - */ - function = GIMP_TOOL_RECTANGLE_CREATING; - } - else if (gimp_tool_rectangle_coord_on_handle (rectangle, - coords, - GIMP_HANDLE_ANCHOR_NORTH_WEST)) - { - function = GIMP_TOOL_RECTANGLE_RESIZING_UPPER_LEFT; - } - else if (gimp_tool_rectangle_coord_on_handle (rectangle, - coords, - GIMP_HANDLE_ANCHOR_SOUTH_EAST)) - { - function = GIMP_TOOL_RECTANGLE_RESIZING_LOWER_RIGHT; - } - else if (gimp_tool_rectangle_coord_on_handle (rectangle, - coords, - GIMP_HANDLE_ANCHOR_NORTH_EAST)) - { - function = GIMP_TOOL_RECTANGLE_RESIZING_UPPER_RIGHT; - } - else if (gimp_tool_rectangle_coord_on_handle (rectangle, - coords, - GIMP_HANDLE_ANCHOR_SOUTH_WEST)) - { - function = GIMP_TOOL_RECTANGLE_RESIZING_LOWER_LEFT; - } - else if (gimp_tool_rectangle_coord_on_handle (rectangle, - coords, - GIMP_HANDLE_ANCHOR_WEST)) - { - function = GIMP_TOOL_RECTANGLE_RESIZING_LEFT; - } - else if (gimp_tool_rectangle_coord_on_handle (rectangle, - coords, - GIMP_HANDLE_ANCHOR_EAST)) - { - function = GIMP_TOOL_RECTANGLE_RESIZING_RIGHT; - } - else if (gimp_tool_rectangle_coord_on_handle (rectangle, - coords, - GIMP_HANDLE_ANCHOR_NORTH)) - { - function = GIMP_TOOL_RECTANGLE_RESIZING_TOP; - } - else if (gimp_tool_rectangle_coord_on_handle (rectangle, - coords, - GIMP_HANDLE_ANCHOR_SOUTH)) - { - function = GIMP_TOOL_RECTANGLE_RESIZING_BOTTOM; - } - else if (gimp_tool_rectangle_coord_on_handle (rectangle, - coords, - GIMP_HANDLE_ANCHOR_CENTER)) - { - function = GIMP_TOOL_RECTANGLE_MOVING; - } - else - { - function = GIMP_TOOL_RECTANGLE_DEAD; - } + function = gimp_tool_rectangle_calc_function (rectangle, coords, proximity); gimp_tool_rectangle_set_function (rectangle, function); } @@ -2235,6 +2220,82 @@ swap_doubles (gdouble *i, *j = tmp; } +static GimpRectangleFunction +gimp_tool_rectangle_calc_function (GimpToolRectangle *rectangle, + const GimpCoords *coords, + gboolean proximity) +{ + if (! proximity) + { + return GIMP_TOOL_RECTANGLE_DEAD; + } + else if (gimp_tool_rectangle_coord_outside (rectangle, coords)) + { + /* The cursor is outside of the rectangle, clicking should + * create a new rectangle. + */ + return GIMP_TOOL_RECTANGLE_CREATING; + } + else if (gimp_tool_rectangle_coord_on_handle (rectangle, + coords, + GIMP_HANDLE_ANCHOR_NORTH_WEST)) + { + return GIMP_TOOL_RECTANGLE_RESIZING_UPPER_LEFT; + } + else if (gimp_tool_rectangle_coord_on_handle (rectangle, + coords, + GIMP_HANDLE_ANCHOR_SOUTH_EAST)) + { + return GIMP_TOOL_RECTANGLE_RESIZING_LOWER_RIGHT; + } + else if (gimp_tool_rectangle_coord_on_handle (rectangle, + coords, + GIMP_HANDLE_ANCHOR_NORTH_EAST)) + { + return GIMP_TOOL_RECTANGLE_RESIZING_UPPER_RIGHT; + } + else if (gimp_tool_rectangle_coord_on_handle (rectangle, + coords, + GIMP_HANDLE_ANCHOR_SOUTH_WEST)) + { + return GIMP_TOOL_RECTANGLE_RESIZING_LOWER_LEFT; + } + else if (gimp_tool_rectangle_coord_on_handle (rectangle, + coords, + GIMP_HANDLE_ANCHOR_WEST)) + { + return GIMP_TOOL_RECTANGLE_RESIZING_LEFT; + } + else if (gimp_tool_rectangle_coord_on_handle (rectangle, + coords, + GIMP_HANDLE_ANCHOR_EAST)) + { + return GIMP_TOOL_RECTANGLE_RESIZING_RIGHT; + } + else if (gimp_tool_rectangle_coord_on_handle (rectangle, + coords, + GIMP_HANDLE_ANCHOR_NORTH)) + { + return GIMP_TOOL_RECTANGLE_RESIZING_TOP; + } + else if (gimp_tool_rectangle_coord_on_handle (rectangle, + coords, + GIMP_HANDLE_ANCHOR_SOUTH)) + { + return GIMP_TOOL_RECTANGLE_RESIZING_BOTTOM; + } + else if (gimp_tool_rectangle_coord_on_handle (rectangle, + coords, + GIMP_HANDLE_ANCHOR_CENTER)) + { + return GIMP_TOOL_RECTANGLE_MOVING; + } + else + { + return GIMP_TOOL_RECTANGLE_DEAD; + } +} + /* gimp_tool_rectangle_check_function() is needed to deal with * situations where the user drags a corner or edge across one of the * existing edges, thereby changing its function. Ugh. diff --git a/app/display/gimptooltransformgrid.c b/app/display/gimptooltransformgrid.c index 954d1db9e9..7957c01523 100644 --- a/app/display/gimptooltransformgrid.c +++ b/app/display/gimptooltransformgrid.c @@ -173,6 +173,10 @@ static void gimp_tool_transform_grid_motion (GimpToolWidget * const GimpCoords *coords, guint32 time, GdkModifierType state); +static GimpHit gimp_tool_transform_grid_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity); static void gimp_tool_transform_grid_hover (GimpToolWidget *widget, const GimpCoords *coords, GdkModifierType state, @@ -189,6 +193,9 @@ static gboolean gimp_tool_transform_grid_get_cursor (GimpToolWidget * GimpToolCursorType *tool_cursor, GimpCursorModifier *modifier); +static GimpTransformHandle + gimp_tool_transform_grid_get_handle (GimpToolTransformGrid *grid, + const GimpCoords *coords); static void gimp_tool_transform_grid_update_hilight (GimpToolTransformGrid *grid); static void gimp_tool_transform_grid_update_box (GimpToolTransformGrid *grid); static void gimp_tool_transform_grid_update_matrix (GimpToolTransformGrid *grid); @@ -217,6 +224,7 @@ gimp_tool_transform_grid_class_init (GimpToolTransformGridClass *klass) widget_class->button_press = gimp_tool_transform_grid_button_press; widget_class->button_release = gimp_tool_transform_grid_button_release; widget_class->motion = gimp_tool_transform_grid_motion; + widget_class->hit = gimp_tool_transform_grid_hit; widget_class->hover = gimp_tool_transform_grid_hover; widget_class->leave_notify = gimp_tool_transform_grid_leave_notify; widget_class->hover_modifier = gimp_tool_transform_grid_hover_modifier; @@ -1916,6 +1924,23 @@ gimp_tool_transform_get_area_handle (GimpToolTransformGrid *grid, return handle; } +GimpHit +gimp_tool_transform_grid_hit (GimpToolWidget *widget, + const GimpCoords *coords, + GdkModifierType state, + gboolean proximity) +{ + GimpToolTransformGrid *grid = GIMP_TOOL_TRANSFORM_GRID (widget); + GimpTransformHandle handle; + + handle = gimp_tool_transform_grid_get_handle (grid, coords); + + if (handle != GIMP_TRANSFORM_HANDLE_NONE) + return GIMP_HIT_DIRECT; + + return GIMP_HIT_INDIRECT; +} + void gimp_tool_transform_grid_hover (GimpToolWidget *widget, const GimpCoords *coords, @@ -1924,18 +1949,9 @@ gimp_tool_transform_grid_hover (GimpToolWidget *widget, { GimpToolTransformGrid *grid = GIMP_TOOL_TRANSFORM_GRID (widget); GimpToolTransformGridPrivate *private = grid->private; - GimpTransformHandle handle = GIMP_TRANSFORM_HANDLE_NONE; - GimpTransformHandle i; + GimpTransformHandle handle; - for (i = GIMP_TRANSFORM_HANDLE_NONE + 1; i < GIMP_N_TRANSFORM_HANDLES; i++) - { - if (private->handles[i] && - gimp_canvas_item_hit (private->handles[i], coords->x, coords->y)) - { - handle = i; - break; - } - } + handle = gimp_tool_transform_grid_get_handle (grid, coords); if (handle == GIMP_TRANSFORM_HANDLE_NONE) { @@ -2236,6 +2252,25 @@ gimp_tool_transform_grid_get_cursor (GimpToolWidget *widget, return TRUE; } +static GimpTransformHandle +gimp_tool_transform_grid_get_handle (GimpToolTransformGrid *grid, + const GimpCoords *coords) +{ + GimpToolTransformGridPrivate *private = grid->private; + GimpTransformHandle i; + + for (i = GIMP_TRANSFORM_HANDLE_NONE + 1; i < GIMP_N_TRANSFORM_HANDLES; i++) + { + if (private->handles[i] && + gimp_canvas_item_hit (private->handles[i], coords->x, coords->y)) + { + return i; + } + } + + return GIMP_TRANSFORM_HANDLE_NONE; +} + static void gimp_tool_transform_grid_update_hilight (GimpToolTransformGrid *grid) {