Thread: [Xournal-devel] Arrow Tool / Getting into development
Brought to you by:
andreasb123,
auroux
From: Homo F. <gor...@gm...> - 2017-01-28 12:22:37
|
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. |
From: Denis A. <au...@ma...> - 2017-01-28 19:10:27
|
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 > Xou...@li... > https://lists.sourceforge.net/lists/listinfo/xournal-devel > -- Denis Auroux UC Berkeley, Department of Mathematics 817 Evans Hall, Berkeley CA 94720-3840, USA au...@ma... |
From: Hans R. <gor...@gm...> - 2017-03-17 21:25:46
|
Hi, thanks for your very in depth answer. I just got to try this two days ago and got it working!. I've added a few more points to the existing polyline inside continue_stroke() to create an arrow head. Now I wanted to switch between the ordinary ruler and my modified one. This was quite a hurdle and certainly isn't nice looking code. I didn't want to create a new tool from scratch, as that would have taken a lot longer. Instead I added a new int to the UIData struct, that serves as a switch for the different "ruler tools". This int can be modified by a GtkMenuToolButton in the toolbar, which has multiple radio items (the button itself does nothing). All these items are connected to the same handler and by comparing the sender's label to strings the int value gets set (What could possibly go wrong? Well translation is an issue for sure. I think there is a possibility to send this data over the gpointer user_data, but I didn't try that one). With this information I can select the tool that will be applied inside continue_stroke(). Currently the UI looks like this (i don't know if embedded pictures will work here): [image: Inline-Bild 1] [image: Inline-Bild 2] Its not really clean and forward, but I have to leave it at that for now. Changing the ruler toggle button into a radio control required changing code in parts of Xournal that caused a myriad of new problems. I didn't want to face those without a debugger. Maybe you have a better idea on how to handle all this. As it is now, I'm quite happy as these were my most wanted features. Thanks again, Mo. |
From: dmg <dm...@tu...> - 2017-03-18 01:44:48
|
Hi Hans, thank you for trying this. Is there a place where we can download the patches? thank you! --dmg On Fri, Mar 17, 2017 at 2:25 PM, Hans Rochus <gor...@gm...> wrote: > Hi, > > thanks for your very in depth answer. I just got to try this two days ago > and got it working!. I've added a few more points to the existing polyline > inside continue_stroke() to create an arrow head. Now I wanted to switch > between the ordinary ruler and my modified one. This was quite a hurdle and > certainly isn't nice looking code. I didn't want to create a new tool from > scratch, as that would have taken a lot longer. Instead I added a new int > to the UIData struct, that serves as a switch for the different "ruler > tools". This int can be modified by a GtkMenuToolButton in the toolbar, > which has multiple radio items (the button itself does nothing). All these > items are connected to the same handler and by comparing the sender's label > to strings the int value gets set (What could possibly go wrong? Well > translation is an issue for sure. I think there is a possibility to send > this data over the gpointer user_data, but I didn't try that one). With > this information I can select the tool that will be applied > inside continue_stroke(). Currently the UI looks like this (i don't know if > embedded pictures will work here): > > [image: Inline-Bild 1] > [image: Inline-Bild 2] > Its not really clean and forward, but I have to leave it at that for now. > Changing the ruler toggle button into a radio control required changing > code in parts of Xournal that caused a myriad of new problems. I didn't > want to face those without a debugger. > Maybe you have a better idea on how to handle all this. As it is now, I'm > quite happy as these were my most wanted features. > > Thanks again, > > 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 > Xou...@li... > https://lists.sourceforge.net/lists/listinfo/xournal-devel > > -- --dmg --- Daniel M. German http://turingmachine.org |