app: add utility function gimp_canvas_handle_calc_size()

which is the code that calculates handle size based on pointer
proximity. Use the new function in GimpToolHandleGrid and
GimpToolLine, and clean up some stuff in GimpToolLine.
This commit is contained in:
Michael Natterer 2017-06-20 01:02:23 +02:00
parent e2d1a57ebd
commit 625ec4b773
4 changed files with 75 additions and 91 deletions

View File

@ -547,6 +547,38 @@ gimp_canvas_handle_set_position (GimpCanvasItem *handle,
gimp_canvas_item_end_change (handle);
}
gint
gimp_canvas_handle_calc_size (GimpCanvasItem *item,
gdouble mouse_x,
gdouble mouse_y,
gint normal_size,
gint hover_size)
{
gdouble x, y;
gdouble distance;
gdouble size;
gint full_threshold_sq = SQR (hover_size / 2) * 9;
gint partial_threshold_sq = full_threshold_sq * 5;
g_return_val_if_fail (GIMP_IS_CANVAS_HANDLE (item), normal_size);
gimp_canvas_handle_get_position (item, &x, &y);
distance = gimp_canvas_item_transform_distance_square (item,
mouse_x,
mouse_y,
x, y);
/* calculate the handle size based on distance from the cursor */
size = (1.0 - (distance - full_threshold_sq) /
(partial_threshold_sq - full_threshold_sq));
size = CLAMP (size, 0.0, 1.0);
return (gint) CLAMP ((size * hover_size),
normal_size,
hover_size);
}
void
gimp_canvas_handle_get_size (GimpCanvasItem *handle,
gint *width,

View File

@ -71,6 +71,12 @@ void gimp_canvas_handle_set_position (GimpCanvasItem *handle,
gdouble x,
gdouble y);
gint gimp_canvas_handle_calc_size (GimpCanvasItem *item,
gdouble mouse_x,
gdouble mouse_y,
gint normal_size,
gint hover_size);
void gimp_canvas_handle_get_size (GimpCanvasItem *handle,
gint *width,
gint *height);

View File

@ -951,26 +951,6 @@ gimp_tool_handle_grid_get_cursor (GimpToolWidget *widget,
return TRUE;
}
static gint
calc_handle_diameter (gdouble distance)
{
#define HANDLE_DIAMETER (2 * GIMP_CANVAS_HANDLE_SIZE_CIRCLE)
#define POINT_GRAB_THRESHOLD_SQ (SQR (HANDLE_DIAMETER / 2))
#define FULL_HANDLE_THRESHOLD_SQ (POINT_GRAB_THRESHOLD_SQ * 9)
#define PARTIAL_HANDLE_THRESHOLD_SQ (FULL_HANDLE_THRESHOLD_SQ * 5)
/* Calculate the handle size based on distance from the cursor
*/
gdouble size = (1.0 - (distance - FULL_HANDLE_THRESHOLD_SQ) /
(PARTIAL_HANDLE_THRESHOLD_SQ - FULL_HANDLE_THRESHOLD_SQ));
size = CLAMP (size, 0.0, 1.0);
return (gint) CLAMP ((size * HANDLE_DIAMETER),
GIMP_CANVAS_HANDLE_SIZE_CIRCLE,
HANDLE_DIAMETER);
}
static void
gimp_tool_handle_grid_update_hilight (GimpToolHandleGrid *grid)
{
@ -983,16 +963,12 @@ gimp_tool_handle_grid_update_hilight (GimpToolHandleGrid *grid)
if (item)
{
gdouble x, y;
gdouble dist;
gdouble diameter;
gimp_canvas_handle_get_position (item, &x, &y);
dist = gimp_canvas_item_transform_distance_square (item,
private->mouse_x,
private->mouse_y,
x, y);
diameter = calc_handle_diameter (dist);
gdouble diameter =
gimp_canvas_handle_calc_size (item,
private->mouse_x,
private->mouse_y,
GIMP_CANVAS_HANDLE_SIZE_CIRCLE,
2 * GIMP_CANVAS_HANDLE_SIZE_CIRCLE);
gimp_canvas_handle_set_size (item, diameter, diameter);
gimp_canvas_item_set_highlight (item, (i + 1) == private->handle);

View File

@ -41,13 +41,7 @@
#include "gimptoolline.h"
#define SHOW_LINE TRUE
#define HANDLE_CROSS_DIAMETER 18
#define HANDLE_DIAMETER 40
#define POINT_GRAB_THRESHOLD_SQ (SQR (HANDLE_DIAMETER / 2))
#define FULL_HANDLE_THRESHOLD_SQ (POINT_GRAB_THRESHOLD_SQ * 9)
#define PARTIAL_HANDLE_THRESHOLD_SQ (FULL_HANDLE_THRESHOLD_SQ * 5)
#define SHOW_LINE TRUE
typedef enum
@ -226,8 +220,8 @@ gimp_tool_line_constructed (GObject *object)
GIMP_HANDLE_CIRCLE,
private->x1,
private->y1,
HANDLE_DIAMETER,
HANDLE_DIAMETER,
2 * GIMP_CANVAS_HANDLE_SIZE_CROSS,
2 * GIMP_CANVAS_HANDLE_SIZE_CROSS,
GIMP_HANDLE_ANCHOR_CENTER);
private->start_handle_cross =
@ -235,8 +229,8 @@ gimp_tool_line_constructed (GObject *object)
GIMP_HANDLE_CROSS,
private->x1,
private->y1,
HANDLE_CROSS_DIAMETER,
HANDLE_CROSS_DIAMETER,
GIMP_CANVAS_HANDLE_SIZE_CROSS,
GIMP_CANVAS_HANDLE_SIZE_CROSS,
GIMP_HANDLE_ANCHOR_CENTER);
private->end_handle_circle =
@ -244,8 +238,8 @@ gimp_tool_line_constructed (GObject *object)
GIMP_HANDLE_CIRCLE,
private->x2,
private->y2,
HANDLE_DIAMETER,
HANDLE_DIAMETER,
2 * GIMP_CANVAS_HANDLE_SIZE_CROSS,
2 * GIMP_CANVAS_HANDLE_SIZE_CROSS,
GIMP_HANDLE_ANCHOR_CENTER);
private->end_handle_cross =
@ -253,8 +247,8 @@ gimp_tool_line_constructed (GObject *object)
GIMP_HANDLE_CROSS,
private->x2,
private->y2,
HANDLE_CROSS_DIAMETER,
HANDLE_CROSS_DIAMETER,
GIMP_CANVAS_HANDLE_SIZE_CROSS,
GIMP_CANVAS_HANDLE_SIZE_CROSS,
GIMP_HANDLE_ANCHOR_CENTER);
}
@ -526,19 +520,6 @@ gimp_tool_line_point_motion (GimpToolLine *line,
return FALSE;
}
static gint
calc_handle_diameter (gdouble distance)
{
/* Calculate the handle size based on distance from the cursor
*/
gdouble size = (1.0 - (distance - FULL_HANDLE_THRESHOLD_SQ) /
(PARTIAL_HANDLE_THRESHOLD_SQ - FULL_HANDLE_THRESHOLD_SQ));
size = CLAMP (size, 0.0, 1.0);
return (gint) (size * HANDLE_DIAMETER);
}
static void
gimp_tool_line_update_hilight (GimpToolLine *line)
{
@ -555,34 +536,24 @@ gimp_tool_line_update_hilight (GimpToolLine *line)
}
else
{
gdouble dist;
dist = gimp_canvas_item_transform_distance_square (private->line,
private->mouse_x,
private->mouse_y,
private->x1,
private->y1);
start_diameter = calc_handle_diameter (dist);
start_diameter = gimp_canvas_handle_calc_size (private->start_handle_circle,
private->mouse_x,
private->mouse_y,
0,
2 * GIMP_CANVAS_HANDLE_SIZE_CROSS);
start_visible = start_diameter > 2;
dist = gimp_canvas_item_transform_distance_square (private->line,
private->mouse_x,
private->mouse_y,
private->x2,
private->y2);
end_diameter = calc_handle_diameter (dist);
end_diameter = gimp_canvas_handle_calc_size (private->end_handle_circle,
private->mouse_x,
private->mouse_y,
0,
2 * GIMP_CANVAS_HANDLE_SIZE_CROSS);
end_visible = end_diameter > 2;
}
gimp_canvas_item_set_visible (private->start_handle_circle, start_visible);
gimp_canvas_item_set_visible (private->end_handle_circle, end_visible);
/* Update hilights */
if (private->grabbed_point)
hilight_point = private->grabbed_point;
else
hilight_point = gimp_tool_line_get_point (line);
if (start_visible)
gimp_canvas_handle_set_size (private->start_handle_circle,
start_diameter, start_diameter);
@ -591,6 +562,12 @@ gimp_tool_line_update_hilight (GimpToolLine *line)
gimp_canvas_handle_set_size (private->end_handle_circle,
end_diameter, end_diameter);
/* Update hilights */
if (private->grabbed_point)
hilight_point = private->grabbed_point;
else
hilight_point = gimp_tool_line_get_point (line);
gimp_canvas_item_set_highlight (private->start_handle_circle,
hilight_point == POINT_START);
gimp_canvas_item_set_highlight (private->start_handle_cross,
@ -606,26 +583,19 @@ static GimpToolLinePoint
gimp_tool_line_get_point (GimpToolLine *line)
{
GimpToolLinePrivate *private = line->private;
gdouble dist;
/* Check the points in the reverse order of drawing */
/* Check end point */
dist = gimp_canvas_item_transform_distance_square (private->line,
private->mouse_x,
private->mouse_y,
private->x2,
private->y2);
if (dist < POINT_GRAB_THRESHOLD_SQ)
if (gimp_canvas_item_hit (private->end_handle_circle,
private->mouse_x,
private->mouse_y))
return POINT_END;
/* Check start point */
dist = gimp_canvas_item_transform_distance_square (private->line,
private->mouse_x,
private->mouse_y,
private->x1,
private->y1);
if (dist < POINT_GRAB_THRESHOLD_SQ)
if (gimp_canvas_item_hit (private->start_handle_circle,
private->mouse_x,
private->mouse_y))
return POINT_START;
/* No point found */