Skip to content

Commit

Permalink
drawing,config,callbacks: add arrowtype option that allows to set arr…
Browse files Browse the repository at this point in the history
…ow position

* drawing, config, callbacks: add arrowtype option allowing arrow heads at both line ends

re #67

* main.h: enum names changed for arrow types

* config: don't set arrow type to none when size is defined

---------

Co-authored-by: Christian Beier <info@christianbeier.net>
  • Loading branch information
pascal-niklaus and bk138 authored Mar 11, 2024
1 parent c0886ec commit aa1c807
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 37 deletions.
43 changes: 34 additions & 9 deletions src/callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,10 @@ void on_monitors_changed ( GdkScreen *screen,
parse_config(data); // also calls paint_context_new() :-(


data->default_pen = paint_context_new (data, GROMIT_PEN,
data->red, 7, 0, 1, G_MAXUINT);
data->default_eraser = paint_context_new (data, GROMIT_ERASER,
data->red, 75, 0, 1, G_MAXUINT);
data->default_pen = paint_context_new (data, GROMIT_PEN, data->red, 7,
0, GROMIT_ARROW_END, 1, G_MAXUINT);
data->default_eraser = paint_context_new (data, GROMIT_ERASER, data->red, 75,
0, GROMIT_ARROW_END, 1, G_MAXUINT);

if(!data->composited) // set shape
{
Expand Down Expand Up @@ -399,6 +399,17 @@ gboolean on_motion (GtkWidget *win,
if (type == GROMIT_LINE)
{
draw_line (data, ev->device, devdata->lastx, devdata->lasty, ev->x, ev->y);
if (devdata->cur_context->arrowsize > 0)
{
GromitArrowType atype = devdata->cur_context->arrow_type;
gint width = devdata->cur_context->arrowsize * devdata->cur_context->width / 2;
gfloat direction =
atan2(ev->y - devdata->lasty, ev->x - devdata->lastx);
if (atype & GROMIT_ARROW_END)
draw_arrow(data, ev->device, ev->x, ev->y, width * 2, direction);
if (atype & GROMIT_ARROW_START)
draw_arrow(data, ev->device, devdata->lastx, devdata->lasty, width * 2, M_PI + direction);
}
}
else if (type == GROMIT_RECT)
{
Expand Down Expand Up @@ -451,15 +462,27 @@ gboolean on_buttonrelease (GtkWidget *win,

if (devdata->cur_context->arrowsize != 0)
{
GromitArrowType atype = devdata->cur_context->arrow_type;
if (type == GROMIT_LINE)
{
direction = atan2 (ev->y - devdata->lasty, ev->x - devdata->lastx);
draw_arrow(data, ev->device, ev->x, ev->y, width * 2, direction);
if (atype & GROMIT_ARROW_END)
draw_arrow(data, ev->device, ev->x, ev->y, width * 2, direction);
if (atype & GROMIT_ARROW_START)
draw_arrow(data, ev->device, devdata->lastx, devdata->lasty, width * 2, M_PI + direction);
}
else if (coord_list_get_arrow_param (data, ev->device, width * 3,
&width, &direction))
else
{
draw_arrow (data, ev->device, ev->x, ev->y, width, direction);
gint x0, y0;
if ((atype & GROMIT_ARROW_END) &&
coord_list_get_arrow_param (data, ev->device, width * 3,
GROMIT_ARROW_END, &x0, &y0, &width, &direction))
draw_arrow (data, ev->device, x0, y0, width, direction);
if ((atype & GROMIT_ARROW_START) &&
coord_list_get_arrow_param (data, ev->device, width * 3,
GROMIT_ARROW_START, &x0, &y0, &width, &direction)) {
draw_arrow (data, ev->device, x0, y0, width, direction);
}
}
}

Expand Down Expand Up @@ -591,7 +614,9 @@ void on_mainapp_selection_received (GtkWidget *widget,
g_printerr ("Unable to parse color. "
"Keeping default.\n");
}
GromitPaintContext* line_ctx = paint_context_new(data, GROMIT_PEN, fg_color, thickness, 0, thickness, thickness);
GromitPaintContext* line_ctx =
paint_context_new(data, GROMIT_PEN, fg_color, thickness,
0, GROMIT_ARROW_END, thickness, thickness);

GdkRectangle rect;
rect.x = MIN (startX,endX) - thickness / 2;
Expand Down
41 changes: 37 additions & 4 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ gboolean parse_config (GromitData *data)
GromitPaintType type;
GdkRGBA *fg_color=NULL;
guint width, arrowsize, minwidth, maxwidth;
GromitArrowType arrowtype;

/* try user config location */
filename = g_strjoin (G_DIR_SEPARATOR_S,
Expand Down Expand Up @@ -188,8 +189,9 @@ gboolean parse_config (GromitData *data)
g_scanner_scope_add_symbol (scanner, 2, "size", (gpointer) 1);
g_scanner_scope_add_symbol (scanner, 2, "color", (gpointer) 2);
g_scanner_scope_add_symbol (scanner, 2, "arrowsize", (gpointer) 3);
g_scanner_scope_add_symbol (scanner, 2, "minsize", (gpointer) 4);
g_scanner_scope_add_symbol (scanner, 2, "maxsize", (gpointer) 5);
g_scanner_scope_add_symbol (scanner, 2, "arrowtype", (gpointer) 4);
g_scanner_scope_add_symbol (scanner, 2, "minsize", (gpointer) 5);
g_scanner_scope_add_symbol (scanner, 2, "maxsize", (gpointer) 6);

g_scanner_set_scope (scanner, 0);
scanner->config->scope_0_fallback = 0;
Expand Down Expand Up @@ -225,6 +227,7 @@ gboolean parse_config (GromitData *data)
type = GROMIT_PEN;
width = 7;
arrowsize = 0;
arrowtype = GROMIT_ARROW_END;
minwidth = 1;
maxwidth = G_MAXUINT;
fg_color = data->red;
Expand All @@ -246,6 +249,7 @@ gboolean parse_config (GromitData *data)
type = context_template->type;
width = context_template->width;
arrowsize = context_template->arrowsize;
arrowtype = context_template->arrow_type;
minwidth = context_template->minwidth;
maxwidth = context_template->maxwidth;
fg_color = context_template->paint_color;
Expand Down Expand Up @@ -338,6 +342,34 @@ gboolean parse_config (GromitData *data)
arrowsize = scanner->value.v_float;
}
else if ((intptr_t) scanner->value.v_symbol == 4)
{
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_EQUAL_SIGN)
{
g_printerr ("Missing \"=\"... aborting\n");
goto cleanup;
}
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_STRING)
{
g_printerr ("Missing Arrowsize (string)... "
"aborting\n");
goto cleanup;
}
if (! strcasecmp(scanner->value.v_string, "end"))
arrowtype = GROMIT_ARROW_END;
else if (! strcasecmp(scanner->value.v_string, "start"))
arrowtype = GROMIT_ARROW_START;
else if (! strcasecmp(scanner->value.v_string, "double"))
arrowtype = GROMIT_ARROW_DOUBLE;
else
{
g_printerr ("Arrow type must be \"start\", \"end\", or \"double\"... "
"aborting\n");
goto cleanup;
}
}
else if ((intptr_t) scanner->value.v_symbol == 5)
{
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_EQUAL_SIGN)
Expand All @@ -354,7 +386,7 @@ gboolean parse_config (GromitData *data)
}
minwidth = scanner->value.v_float;
}
else if ((intptr_t) scanner->value.v_symbol == 5)
else if ((intptr_t) scanner->value.v_symbol == 6)
{
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_EQUAL_SIGN)
Expand Down Expand Up @@ -396,7 +428,8 @@ gboolean parse_config (GromitData *data)
goto cleanup;
}

context = paint_context_new (data, type, fg_color, width, arrowsize, minwidth, maxwidth);
context = paint_context_new (data, type, fg_color, width,
arrowsize, arrowtype, minwidth, maxwidth);
g_hash_table_insert (data->tool_config, name, context);
}
else if (token == G_TOKEN_SYMBOL &&
Expand Down
38 changes: 25 additions & 13 deletions src/drawing.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

#include <math.h>
#include "drawing.h"
#include "main.h"

typedef struct
{
Expand Down Expand Up @@ -153,14 +154,20 @@ void coord_list_free (GromitData *data,
devdata->coordlist = NULL;
}


gboolean coord_list_get_arrow_param (GromitData *data,
GdkDevice *dev,
gint search_radius,
gint *ret_width,
gfloat *ret_direction)
/*
* for double-ended arrows, two separate calls are required
*/

gboolean coord_list_get_arrow_param (GromitData *data,
GdkDevice *dev,
gint search_radius,
GromitArrowType arrow_end,
gint *x0,
gint *y0,
gint *ret_width,
gfloat *ret_direction)
{
gint x0, y0, r2, dist;
gint r2, dist;
gboolean success = FALSE;
GromitStrokeCoordinate *cur_point, *valid_point;
/* get the data for this device */
Expand All @@ -172,20 +179,25 @@ gboolean coord_list_get_arrow_param (GromitData *data,

if (ptr)
{
if (arrow_end == GROMIT_ARROW_START)
ptr = g_list_last(ptr);
cur_point = ptr->data;
x0 = cur_point->x;
y0 = cur_point->y;
*x0 = cur_point->x;
*y0 = cur_point->y;
r2 = search_radius * search_radius;
dist = 0;

while (ptr && dist < r2)
{
ptr = ptr->next;
if (arrow_end == GROMIT_ARROW_END)
ptr = ptr->next;
else
ptr = ptr->prev;
if (ptr)
{
cur_point = ptr->data;
dist = (cur_point->x - x0) * (cur_point->x - x0) +
(cur_point->y - y0) * (cur_point->y - y0);
dist = (cur_point->x - *x0) * (cur_point->x - *x0) +
(cur_point->y - *y0) * (cur_point->y - *y0);
width = cur_point->width * devdata->cur_context->arrowsize;
if (width * 2 <= dist &&
(!valid_point || valid_point->width < cur_point->width))
Expand All @@ -197,7 +209,7 @@ gboolean coord_list_get_arrow_param (GromitData *data,
{
*ret_width = MAX (valid_point->width * devdata->cur_context->arrowsize,
2);
*ret_direction = atan2 (y0 - valid_point->y, x0 - valid_point->x);
*ret_direction = atan2 (*y0 - valid_point->y, *x0 - valid_point->x);
success = TRUE;
}
}
Expand Down
11 changes: 7 additions & 4 deletions src/drawing.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ void draw_line (GromitData *data, GdkDevice *dev, gint x1, gint y1, gint x2, gin
void draw_arrow (GromitData *data, GdkDevice *dev, gint x1, gint y1, gint width, gfloat direction);

gboolean coord_list_get_arrow_param (GromitData *data,
GdkDevice *dev,
gint search_radius,
gint *ret_width,
gfloat *ret_direction);
GdkDevice *dev,
gint search_radius,
GromitArrowType arrow_end,
gint *x0,
gint *y0,
gint *ret_width,
gfloat *ret_direction);
void coord_list_prepend (GromitData *data, GdkDevice* dev, gint x, gint y, gint width);
void coord_list_free (GromitData *data, GdkDevice* dev);

Expand Down
28 changes: 22 additions & 6 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ GromitPaintContext *paint_context_new (GromitData *data,
GdkRGBA *paint_color,
guint width,
guint arrowsize,
GromitArrowType arrowtype,
guint minwidth,
guint maxwidth)
{
Expand All @@ -50,6 +51,7 @@ GromitPaintContext *paint_context_new (GromitData *data,
context->type = type;
context->width = width;
context->arrowsize = arrowsize;
context->arrow_type = arrowtype;
context->minwidth = minwidth;
context->maxwidth = maxwidth;
context->paint_color = paint_color;
Expand Down Expand Up @@ -100,6 +102,20 @@ void paint_context_print (gchar *name,
g_printerr ("minwidth: %u, ", context->minwidth);
g_printerr ("maxwidth: %u, ", context->maxwidth);
g_printerr ("arrowsize: %.2f, ", context->arrowsize);
if (context->arrowsize > 0)
{
switch (context->arrow_type) {
case GROMIT_ARROW_START:
g_printerr(" arrowtype: start, ");
break;
case GROMIT_ARROW_END:
g_printerr(" arrowtype: end, ");
break;
case GROMIT_ARROW_DOUBLE:
g_printerr(" arrowtype: double, ");
break;
}
}
g_printerr ("color: %s\n", gdk_rgba_to_string(context->paint_color));
}

Expand Down Expand Up @@ -758,12 +774,12 @@ void setup_main_app (GromitData *data, int argc, char ** argv)

data->modified = 0;

data->default_pen = paint_context_new (data, GROMIT_PEN,
data->red, 7, 0, 1, G_MAXUINT);
data->default_eraser = paint_context_new (data, GROMIT_ERASER,
data->red, 75, 0, 1, G_MAXUINT);


data->default_pen =
paint_context_new (data, GROMIT_PEN, data->red, 7,
0, GROMIT_ARROW_END, 1, G_MAXUINT);
data->default_eraser =
paint_context_new (data, GROMIT_ERASER, data->red, 75,
0, GROMIT_ARROW_END, 1, G_MAXUINT);

gdk_event_handler_set ((GdkEventFunc) main_do_event, data, NULL);
gtk_key_snooper_install (snoop_key_press, data);
Expand Down
11 changes: 10 additions & 1 deletion src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,19 @@ typedef enum
GROMIT_RECOLOR
} GromitPaintType;

typedef enum
{
GROMIT_ARROW_START = 1,
GROMIT_ARROW_END = 2,
GROMIT_ARROW_DOUBLE = (GROMIT_ARROW_START | GROMIT_ARROW_END )
} GromitArrowType;

typedef struct
{
GromitPaintType type;
guint width;
gfloat arrowsize;
GromitArrowType arrow_type;
guint minwidth;
guint maxwidth;
GdkRGBA *paint_color;
Expand Down Expand Up @@ -171,7 +179,8 @@ void redo_drawing (GromitData *data);
void clear_screen (GromitData *data);

GromitPaintContext *paint_context_new (GromitData *data, GromitPaintType type,
GdkRGBA *fg_color, guint width, guint arrowsize,
GdkRGBA *fg_color, guint width,
guint arrowsize, GromitArrowType arrowtype,
guint minwidth, guint maxwidth);
void paint_context_free (GromitPaintContext *context);

Expand Down

0 comments on commit aa1c807

Please sign in to comment.