Hi there,

Just adding points to ui.cur_path.coords (and adjusting num_points) is 
not necessarily enough, because that is just a temporary points array 
used while drawing -- at the end of the process, ui.cur_path will 
eventually get inserted into the page and drawn.  For regular drawing, 
create_new_stroke() allocates ui.cur_item and fills some of the data; 
continue_stroke() updates ui.cur_path and draws segments as the pen is 
being moved; and finalize_stroke() takes care of finishing the job: 
cleans up the data in ui.cur_path, copies it into ui.cur_item->path, 
updates the gnome canvas structures, and adds ui.cur_item onto 
ui.cur_layer->items to make it part of the page's data structures.

You won't need to do all these things yourself, but you do need to make 
sure that the place where you modify ui.cur_path's contents is before 
the moment where it gets copied into data structures that will remain in 
place in the journal.

Easy case: If your arrow is going to be part of the same polyline as the 
stroke is goes onto, i.e. the stroke + arrow are all a single connected 
polygonal shape, then you can indeed insert it at the beginning of 
finalize_stroke() (updating ui.cur_path.coords and num_points) and the 
code will take care of it.

Hard case: If the arrow is its own separate polyline, then it will 
become a distinct item both in gnomecanvas (for display) and in 
ui.cur_layer (for data storage), so you need to make sure those get 
created, and that the creation operation can be undone. The best place 
to look for such things is indeed the shape recognizer.

In xo-shapes.c, try_arrow() will take existing strokes and create 
several strokes, if you look at the end of the code for try_arrow(), we 
create several stroke items by hand. The fastest way to do it is just 
the same as the way the arrow head is created at the end of try_arrow():

   realloc_cur_path(3);
   ui.cur_path.num_points = 3;
   ui.cur_path.coords[0] = x2 - dist*cos(angle+delta);
   ui.cur_path.coords[1] = y2 - dist*sin(angle+delta);
   ui.cur_path.coords[2] = x2;
   ui.cur_path.coords[3] = y2;
   ui.cur_path.coords[4] = x2 - dist*cos(angle-delta);
   ui.cur_path.coords[5] = y2 - dist*sin(angle-delta);
   insert_recognized_curpath();

We make sure cur_path is large enough for 3 points, fill in the 
coordinates, and then insert the new curpath into the journal.

*However* you can't use insert_recognized_curpath() as is, because it 
assumes that a recognizer operation is in progress and the undo stack 
contains an "ITEM_RECOGNIZER" entry, with a list of erasures already in 
place. (See the first 6 lines of code in remove_recognized_strokes(), 
which gets called before any call to insert_recognized_curpath(): we 
create a new undo item).

You can either piggyback on this, making your arrows in a "recognizer" 
undo operation (this has implications for the undo process, it'll undo 
in two stages) but with no erasures if you are not removing any 
user-drawn stroke to replace it with the arrow, and calling 
insert_recognized_curpath();  or make a different function similar to 
insert_recognized_curpath() but that doesn't place information into the 
undo stack in this particular way (instead makes an ITEM_STROKE undo 
operation).

Sorry if this is technical, but that is not the easiest part of the code 
to modify if you want to create an extra polyline along the way -- 
easiest if you just make the arrowhead part of the same continuously 
drawn polyline as the stroke, in that case just add your arrow points to 
ui.cur_path at the beginning of finalize_stroke() (before cur_path gets 
copied into other data structures and redrawn on screen).

Denis

On 01/28/2017 07:22 AM, Homo Fürst wrote:
> Hi,
>
> I just got around to building xournal-next on Windows and would like to
> add a few tools (not using the shape recognizer, as i want more control
> over size and position), although I can't seem to understand the source
> code all that well. For guidance I looked at code which defines the
> ruler paths in xo_paint.c in the following functions:
>
> - void create_new_stroke(GdkEvent *event)
> - void continue_stroke(GdkEvent *event)
> - void finalize_stroke(void)
>
> Now my idea is to add new points to that path, so I can add an arrow
> head after the straight line (like this: ----|>) . Where would one
> insert these points? In xo_shapes.c make_circle_shape() adds points to
> the ui.cur_path.coords array, but I can't seem to get it to work this way.
>
> I'd be grateful for any guidance in this direction.
>
> Also, it took me quite some time getting Xournal and gtk2 to build on
> Windows (using MSYS2 / mingw64). If anyone is interested, I posted
> updated instructions in the SourceForge forum
>
> Thanks,
>
> Mo.
>
>
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, SlashDot.org! http://sdm.link/slashdot
>
>
>
> _______________________________________________
> Xournal-devel mailing list
> Xournal-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/xournal-devel
>

-- 
Denis Auroux
UC Berkeley, Department of Mathematics
817 Evans Hall, Berkeley CA 94720-3840, USA
aur...@math.berkeley.edu

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Xournal-devel mailing list
Xournal-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/xournal-devel

Reply via email to