From 847178be96f11d555d4ef05641382b5a97367f88 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sun, 18 Mar 2018 15:04:06 +0100 Subject: Create a run when placing cursor in an empty paragraph --- src/frame.c | 38 ++++++++++++++++++++++++++++++++++++++ src/frame.h | 2 ++ src/sc_editor.c | 5 ++--- src/sc_parse.c | 37 +++++++++++++++++++++++++++++++++++++ src/sc_parse.h | 2 ++ 5 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/frame.c b/src/frame.c index a125ce6..62fe72c 100644 --- a/src/frame.c +++ b/src/frame.c @@ -699,6 +699,44 @@ void sort_positions(struct edit_pos *a, struct edit_pos *b) } +void ensure_run(struct frame *fr, struct edit_pos cpos) +{ + SCBlock *bl; + Paragraph *para = fr->paras[cpos.para]; + if ( para->n_runs > 0 ) return; + + if ( para->type != PARA_TYPE_TEXT ) return; + + if ( para->scblock != para->rscblock ) { + fprintf(stderr, "Need to add run, but paragraph not editable\n"); + return; + } + + if ( para->scblock != NULL ) { + + bl = sc_block_prepend(para->scblock, fr->scblocks); + if ( bl == NULL ) { + fprintf(stderr, "Couldn't prepend block\n"); + return; + } + sc_block_set_contents(bl, strdup("")); + + } else { + + /* If the paragraph's SCBlock is NULL, it means this paragraph + * is right at the end of the document. The last thing in the + * document is something like \newpara. */ + bl = sc_block_append_end(fr->scblocks, NULL, NULL, strdup("")); + + } + + para->scblock = bl; + para->rscblock = bl; + add_run(para, bl, bl, fr->fontdesc, fr->col); + wrap_paragraph(para, NULL, fr->w - fr->pad_l - fr->pad_r, 0, 0); +} + + int find_cursor(struct frame *fr, double x, double y, struct edit_pos *pos) { double pad = fr->pad_t; diff --git a/src/frame.h b/src/frame.h index 8eae26a..36cdca1 100644 --- a/src/frame.h +++ b/src/frame.h @@ -159,6 +159,8 @@ extern int find_cursor(struct frame *fr, double x, double y, extern void sort_positions(struct edit_pos *a, struct edit_pos *b); +extern void ensure_run(struct frame *fr, struct edit_pos cpos); + extern int positions_equal(struct edit_pos a, struct edit_pos b); extern int get_para_highlight(struct frame *fr, int cursor_para, diff --git a/src/sc_editor.c b/src/sc_editor.c index 36ea899..51b50a5 100644 --- a/src/sc_editor.c +++ b/src/sc_editor.c @@ -1188,11 +1188,9 @@ static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event, /* Position cursor and prepare for possible drag */ e->cursor_frame = clicked; - printf("position cursor...\n"); check_paragraph(e->cursor_frame, e->pc, sc_block_child(fr->scblocks)); - printf("find..\n"); find_cursor(clicked, x-fr->x, y-fr->y, &e->cpos); - printf("done\n"); + ensure_run(e->cursor_frame, e->cpos); e->start_corner_x = x; e->start_corner_y = y; @@ -1250,6 +1248,7 @@ static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event, sc_block_child(clicked->scblocks)); } find_cursor(clicked, x-clicked->x, y-clicked->y, &e->cpos); + ensure_run(e->cursor_frame, e->cpos); } diff --git a/src/sc_parse.c b/src/sc_parse.c index f4717f1..5a653cf 100644 --- a/src/sc_parse.c +++ b/src/sc_parse.c @@ -87,6 +87,43 @@ const char *sc_block_contents(const SCBlock *bl) } +static SCBlock *sc_find_previous(SCBlock *top, SCBlock *find) +{ + if ( top->next == find ) return top; + + if ( top->child != NULL ) { + SCBlock *t = sc_find_previous(top->child, find); + if ( t != NULL ) return t; + } + if ( top->next != NULL ) { + SCBlock *t = sc_find_previous(top->next, find); + if ( t != NULL ) return t; + } + return NULL; +} + + +/* Add a new block before "bl" */ +SCBlock *sc_block_prepend(SCBlock *bl, SCBlock *top) +{ + SCBlock *bln; + SCBlock *prev; + + prev = sc_find_previous(top, bl); + if ( prev == NULL ) { + fprintf(stderr, "Couldn't find previous\n"); + return NULL; + } + + bln = sc_block_new(); + if ( bln == NULL ) return NULL; + + prev->next = bln; + bln->next = bl; + return bln; +} + + /* Append "bln" after "bl" */ void sc_block_append_p(SCBlock *bl, SCBlock *bln) { diff --git a/src/sc_parse.h b/src/sc_parse.h index ff10638..9ebbc7c 100644 --- a/src/sc_parse.h +++ b/src/sc_parse.h @@ -50,6 +50,8 @@ extern SCBlock *sc_block_append(SCBlock *bl, extern SCBlock *sc_block_new_parent(SCBlock *bl, const char *name); +extern SCBlock *sc_block_prepend(SCBlock *bl, SCBlock *top); + extern void sc_block_append_p(SCBlock *bl, SCBlock *bln); extern void sc_block_append_block(SCBlock *bl, SCBlock *bln); -- cgit v1.2.3