Create a run when placing cursor in an empty paragraph
authorThomas White <taw@physics.org>
Sun, 18 Mar 2018 14:04:06 +0000 (15:04 +0100)
committerThomas White <taw@physics.org>
Sun, 18 Mar 2018 22:14:13 +0000 (23:14 +0100)
src/frame.c
src/frame.h
src/sc_editor.c
src/sc_parse.c
src/sc_parse.h

index a125ce6..62fe72c 100644 (file)
@@ -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;
index 8eae26a..36cdca1 100644 (file)
@@ -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,
index 36ea899..51b50a5 100644 (file)
@@ -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);
 
        }
 
index f4717f1..5a653cf 100644 (file)
@@ -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)
 {
index ff10638..9ebbc7c 100644 (file)
@@ -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);