add undo in arrow mode - gramscii - A simple editor for ASCII box-and-arrow charts DIR Log DIR Files DIR Refs DIR Tags DIR README DIR LICENSE --- DIR commit f660595c236a21555d3558dd51afae4a67d651a3 DIR parent 47996e708ad2ab7e6a18633576c95e93d08e816a HTML Author: KatolaZ <katolaz@freaknet.org> Date: Thu, 1 Aug 2019 09:56:13 +0100 add undo in arrow mode Diffstat: M TODO | 14 +++++++------- M draw.c | 7 +++++-- M gramscii.1 | 6 +++--- M gramscii.h | 57 +++++++++++++++++++++---------- 4 files changed, 54 insertions(+), 30 deletions(-) --- DIR diff --git a/TODO b/TODO @@ -1,8 +1,8 @@ + optimize redraws (redraw only the modified rectangle) + undo (by storing lines changed across insert/remove operations) * re-organise undo-ring management - - add undo for arrow mode - - add undo for text mode + * add undo for arrow mode + * add undo for text mode - add undo for erase mode - fix bug with 'g' commands in arrow mode - add screen geometry option (-g 25x80?) @@ -18,16 +18,16 @@ + parse arrows (text-mode will allow movements as well) - (?) implement CTRL+G as abort (aside ESC) - (?) remove extra blanks until EOL when saving to file -+ visual selection - - crop-to - * yank - * fill - * cut - manage special chars (DEL/CANC) during text insert (also do not print unmanaged chars!) - allow scrolling (both vertical and horizontal) - catch SIGWINCH and react appropriately (after scrolling is enabled) +* visual selection + * crop-to-rectangle + * yank + * fill + * cut * put yanked content (p) * turn screen into a lineset * change alloc/ensure functions to work on line_t* and lineset_t* DIR diff --git a/draw.c b/draw.c @@ -173,7 +173,7 @@ void draw_arrow(int x, int y, char *a, int a_len, int fix){ char line; void (*f)(int, int, char); - + a_miny = a_maxy = y; if (fix == FIX) f = set_xy; else @@ -198,6 +198,8 @@ void draw_arrow(int x, int y, char *a, int a_len, int fix){ line = (a[i] & DIR_L) || (a[i] & DIR_R) ? line_h : line_v; x += progr_x(a[i]); y += progr_y(a[i]); + if (y < a_miny) a_miny = y; + if (y > a_maxy) a_maxy = y; f(x, y, line); } /* f(x,y,mark_end);*/ @@ -250,8 +252,9 @@ update_arrow: show_cursor(); } if (c == 'a' || c == '\n'){ - invalidate_undo(); + copy_lines_to_ring(a_miny, a_maxy, PRV_STATE); draw_arrow(orig_x, orig_y, arrow, arrow_len, FIX); + copy_lines_to_ring(a_miny, a_maxy, NEW_STATE); modified = 1; } redraw(); DIR diff --git a/gramscii.1 b/gramscii.1 @@ -538,10 +538,10 @@ gramscii currently manages only a fixed screen of the same size of the screen where it starts from. This will be changed in a future release to support scrolling and "virtual" screens of any (reasonable) size. .PP -Undo commands are only available in box, visual (cut, fill), and text -mode, and for copy/paste operations. gramscii currently does +Undo commands are only available in box, visual (cut, fill), arrow, and +text mode, and for copy/paste operations. gramscii currently does .B not -support undo commands for arrow and erase mode. This will be fixed soon. +support undo commands for erase mode. This will be fixed soon. .SH AUTHORS gramscii is written and maintained by Vincenzo "KatolaZ" Nicosia <katolaz@freaknet.org>. You can use, copy, modify, and redistribute DIR diff --git a/gramscii.h b/gramscii.h @@ -9,13 +9,16 @@ /** constants **/ +/* modes */ #define MOVE 0x00 #define BOX 0x01 #define ARROW 0x02 #define TEXT 0x04 #define DEL 0x08 #define VIS 0x10 +/**/ +/* directions */ #define DIR_N 0x00 #define DIR_R 0x01 #define DIR_U 0x02 @@ -24,11 +27,12 @@ #define DIR_HOR (DIR_R | DIR_L) #define DIR_VER (DIR_D | DIR_U) - +/**/ #define NOFIX 0x0 #define FIX 0x1 +/* markers */ #define BG ' ' #define PTR '+' #define UND '_' @@ -36,21 +40,28 @@ #define ARR_R '>' #define ARR_U '^' #define ARR_D 'v' +/**/ +/* global positions */ #define HOME 0x01 #define END 0x02 #define MIDDLE 0x04 +/**/ +/* video modes */ #define VIDEO_NRM 0 #define VIDEO_REV 7 +/**/ +/* undo buffer elem types */ #define PRV_STATE 0x01 #define NEW_STATE 0x02 +/**/ /** types **/ typedef struct{ - int sz;/* allocated size*/ + int sz;/* allocated size */ int n;/* line number */ int lst;/* last visible char (before the first \0) */ char *s; @@ -75,45 +86,52 @@ typedef struct{ /** global variables **/ -lineset_t screen; -lineset_t cutbuf; -lineset_t *undo; +lineset_t screen; /* what is visualised */ +lineset_t cutbuf; /* cut/paste buffer */ +lineset_t *undo; /* undo list */ -int undo_sz; -int undo_cur; -int undo_lst; +int undo_sz;/* allocated size of undo list*/ +int undo_cur;/* undo position */ +int undo_lst;/* last valid undo position */ int WIDTH, HEIGHT; -int mode; -int dir; +int mode;/* mode */ +int dir;/* line direction */ int x; int y; -int step; -int mult; +int step;/* current step */ +int mult;/* current multiplier */ int force_new; -char cursor; char corner; +/* number of available markers for each type */ int hlines_sz; int vlines_sz; int corners_sz; int stmarks_sz; int endmarks_sz; +/**/ +/* line and arrow markers */ int cur_hl, cur_vl, cur_corn, cur_start, cur_end; char line_h; char line_v; char mark_st; char mark_end; +/**/ -char modified; +char modified; /* set to 1 if screen modified since last save */ char fname[256]; -char visual; -char silent; -char autoend; +char silent; /* set to 1 in script-mode */ +char autoend; /* set to 1 in auto-arrow mode */ + +/* Used by draw_arrow to identify the bounding box */ +int a_miny; +int a_maxy; +/**/ struct termios t1, t2, t3; @@ -141,6 +159,7 @@ void go_to(int where); void crop_to_nonblank(); void crop_to_rect(); void erase_blank_lines(int y1, int y2); +/**/ /** drawing-related functions **/ int change_style(char c); @@ -152,15 +171,16 @@ void visual_box(FILE *fc); void paste(); void undo_change(); void redo_change(); +/**/ /** file-related functions **/ void write_file(FILE *fc); void check_modified(FILE *fc); void load_file(FILE *fc); void new_file(FILE *fc); +/**/ /** line-related functions **/ - void dump_lines(lineset_t ls, FILE *f); void alloc_line(line_t *l); void ensure_line_length(line_t *l, int len); @@ -169,5 +189,6 @@ void yank_region(int x1, int y1, int x2, int y2); void paste_region(int x1, int y1); void copy_lines_to_ring(int y1, int y2, int which); void invalidate_undo(); +/**/ #endif