app: implement GimpToolWidget::hit() in all tool widgets
... and move the common functionality of their hit() and hover()
implementation to a separate function.
(cherry picked from commit 52a92a34d8
)
This commit is contained in:
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user