diff options
author | Thomas White <taw@bitwiz.org.uk> | 2016-03-28 22:28:21 +0200 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2016-03-28 22:51:11 +0200 |
commit | d4de5d06c2ac66b15aa01da3f29dbb33ea270249 (patch) | |
tree | f8d1735975c4e0df11fc57304e94053958ea8c85 | |
parent | 4def920737575625a8336a41a4310cc52052ce01 (diff) |
Cursor stuff
-rw-r--r-- | src/frame.c | 118 | ||||
-rw-r--r-- | src/frame.h | 14 | ||||
-rw-r--r-- | src/sc_editor.c | 74 | ||||
-rw-r--r-- | src/sc_editor.h | 1 |
4 files changed, 155 insertions, 52 deletions
diff --git a/src/frame.c b/src/frame.c index a541999..591dafd 100644 --- a/src/frame.c +++ b/src/frame.c @@ -523,3 +523,121 @@ void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is, } } + + +size_t end_offset_of_para(struct frame *fr, int pn) +{ + int i; + size_t total = 0; + for ( i=0; i<fr->paras[pn]->n_runs; i++ ) { + total += fr->paras[pn]->runs[i].len_bytes; + } + return total; +} + + +/* Local x,y in paragraph -> text offset */ +static int text_para_pos(Paragraph *para, double x, double y, int *ptrail) +{ + int idx; + pango_layout_xy_to_index(para->layout, pango_units_from_double(x), + pango_units_from_double(y), &idx, ptrail); + return idx; +} + + +int find_cursor(struct frame *fr, double x, double y, + int *ppara, int *ppos, int *ptrail) +{ + double pos = fr->pad_t; + int i; + + for ( i=0; i<fr->n_paras; i++ ) { + double npos = pos + fr->paras[i]->height; + if ( npos > y ) { + *ppara = i; + if ( fr->paras[i]->type == PARA_TYPE_TEXT ) { + *ppos = text_para_pos(fr->paras[i], x-fr->pad_l, + y-pos, ptrail); + } else { + *ppos = 0; + } + return 0; + } + pos = npos; + } + + /* Pretend it's in the last paragraph */ + pos -= fr->paras[fr->n_paras-1]->height; + *ppara = fr->n_paras - 1; + *ppos = text_para_pos(fr->paras[i], x - fr->pad_l, y - pos, ptrail); + return 0; +} + + +int get_cursor_pos(struct frame *fr, int cursor_para, int cursor_pos, + double *cx, double *cy, double *ch) +{ + Paragraph *para; + PangoRectangle rect; + int i; + double py = 0.0; + + if ( cursor_para > fr->n_paras ) { + fprintf(stderr, "Cursor paragraph number is too high!\n"); + return 1; + } + + para = fr->paras[cursor_para]; + + if ( para->type != PARA_TYPE_TEXT ) return 1; + + pango_layout_get_cursor_pos(para->layout, cursor_pos, &rect, NULL); + + for ( i=0; i<cursor_para; i++ ) { + py += fr->paras[i]->height; + } + *cx = pango_units_to_double(rect.x) + fr->pad_l; + *cy = pango_units_to_double(rect.y) + fr->pad_t + py; + *ch = pango_units_to_double(rect.height); + return 0; +} + + +void cursor_moveh(struct frame *fr, int *cpara, int *cpos, int *ctrail, + signed int dir) +{ + Paragraph *para = fr->paras[*cpara]; + + if ( (*cpos+*ctrail == end_offset_of_para(fr, *cpara)) && (dir > 0) ) { + if ( *cpara < fr->n_paras-1 ) { + (*cpara)++; + *cpos = 0; + *ctrail = 0; + return; + } else { + /* Can't move any further */ + return; + } + } + + if ( (*cpos+*ctrail == 0) && (dir < 0) ) { + if ( *cpara > 0 ) { + (*cpara)--; + *cpos = end_offset_of_para(fr, *cpara) - 1; + *ctrail = 1; + return; + } else { + /* Can't move any further */ + return; + } + } + pango_layout_move_cursor_visually(para->layout, 1, *cpos, *ctrail, + dir, cpos, ctrail); +} + + +void cursor_movev(struct frame *fr, int *cpara, int *cpos, int *ctrail, + signed int dir) +{ +} diff --git a/src/frame.h b/src/frame.h index b300c8d..39fe13f 100644 --- a/src/frame.h +++ b/src/frame.h @@ -125,4 +125,18 @@ extern void add_image_para(struct frame *fr, const char *filename, extern void wrap_paragraph(Paragraph *para, PangoContext *pc, double w); +extern size_t end_offset_of_para(struct frame *fr, int pn); + +extern int find_cursor(struct frame *fr, double x, double y, + int *ppara, int *ppos, int *ptrail); + +extern int get_cursor_pos(struct frame *fr, int cursor_para, int cursor_pos, + double *cx, double *cy, double *ch); + +extern void cursor_moveh(struct frame *fr, int *cpara, int *cpos, int *ctrail, + signed int dir); + +extern void cursor_movev(struct frame *fr, int *cpara, int *cpos, int *ctrail, + signed int dir); + #endif /* FRAME_H */ diff --git a/src/sc_editor.c b/src/sc_editor.c index 1658122..c61c51a 100644 --- a/src/sc_editor.c +++ b/src/sc_editor.c @@ -362,27 +362,6 @@ void sc_editor_delete_selected_frame(SCEditor *e) } -static int find_cursor(struct frame *fr, double x, double y, - int *ppara, int *ppos) -{ - *ppara = 0; - *ppos = 0; - return 0; -} - - -static void move_cursor_back(SCEditor *e) -{ - /* FIXME */ -} - - -void advance_cursor(SCEditor *e) -{ - /* FIXME */ -} - - static gint destroy_sig(GtkWidget *window, SCEditor *e) { return 0; @@ -420,23 +399,19 @@ static void draw_editing_box(cairo_t *cr, struct frame *fr) } -static void draw_caret(cairo_t *cr, struct frame *fr) +static void draw_caret(cairo_t *cr, struct frame *fr, int cursor_para, + size_t cursor_pos, int cursor_trail) { -#if 0 - double xposd, yposd, cx; - double clow, chigh; - PangoRectangle pos; + double cx, clow, chigh, h; const double t = 1.8; - pango_layout_get_cursor_pos(o->layout, - o->insertion_point+o->insertion_trail, - &pos, NULL); + if ( get_cursor_pos(fr, cursor_para, cursor_pos+cursor_trail, + &cx, &clow, &h) ) + { + return; + } - xposd = pos.x/PANGO_SCALE; - cx = o->base.x - o->offs_x + xposd; - yposd = pos.y/PANGO_SCALE; - clow = o->base.y - o->offs_y + yposd; - chigh = clow + (pos.height/PANGO_SCALE); + chigh = clow + h; cairo_move_to(cr, cx, clow); cairo_line_to(cr, cx, chigh); @@ -454,7 +429,6 @@ static void draw_caret(cairo_t *cr, struct frame *fr) cairo_set_source_rgb(cr, 0.86, 0.0, 0.0); cairo_set_line_width(cr, 1.0); cairo_stroke(cr); -#endif } @@ -488,7 +462,8 @@ static void draw_overlay(cairo_t *cr, SCEditor *e) draw_resize_handle(cr, x+w-20.0, y+h-20.0); } - draw_caret(cr, e->cursor_frame); + draw_caret(cr, e->cursor_frame, e->cursor_para, e->cursor_pos, + e->cursor_trail); } @@ -561,16 +536,6 @@ static gboolean draw_sig(GtkWidget *da, cairo_t *cr, SCEditor *e) } -static void move_cursor(SCEditor *e, signed int x, signed int y) -{ - if ( x > 0 ) { - advance_cursor(e); - } else { - move_cursor_back(e); - } -} - - void insert_scblock(SCBlock *scblock, SCEditor *e) { #if 0 @@ -881,7 +846,8 @@ static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event, e->cursor_frame = clicked; find_cursor(clicked, x-fr->x, y-fr->y, - &e->cursor_para, &e->cursor_pos); + &e->cursor_para, &e->cursor_pos, + &e->cursor_trail); e->start_corner_x = event->x - e->border_offs_x; e->start_corner_y = event->y - e->border_offs_y; @@ -914,7 +880,7 @@ static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event, e->selection = clicked; e->cursor_frame = clicked; find_cursor(clicked, x-clicked->x, y-clicked->y, - &e->cursor_para, &e->cursor_pos); + &e->cursor_para, &e->cursor_pos, &e->cursor_trail); } @@ -1122,7 +1088,8 @@ static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, case GDK_KEY_Left : if ( e->selection != NULL ) { - move_cursor(e, -1, 0); + cursor_moveh(e->cursor_frame, &e->cursor_para, + &e->cursor_pos, &e->cursor_trail, -1); sc_editor_redraw(e); } claim = 1; @@ -1130,7 +1097,8 @@ static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, case GDK_KEY_Right : if ( e->selection != NULL ) { - move_cursor(e, +1, 0); + cursor_moveh(e->cursor_frame, &e->cursor_para, + &e->cursor_pos, &e->cursor_trail, +1); sc_editor_redraw(e); } claim = 1; @@ -1138,7 +1106,8 @@ static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, case GDK_KEY_Up : if ( e->selection != NULL ) { - move_cursor(e, 0, -1); + cursor_movev(e->cursor_frame, &e->cursor_para, + &e->cursor_pos, &e->cursor_trail, -1); sc_editor_redraw(e); } claim = 1; @@ -1146,7 +1115,8 @@ static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, case GDK_KEY_Down : if ( e->selection != NULL ) { - move_cursor(e, 0, +1); + cursor_movev(e->cursor_frame, &e->cursor_para, + &e->cursor_pos, &e->cursor_trail, +1); sc_editor_redraw(e); } claim = 1; diff --git a/src/sc_editor.h b/src/sc_editor.h index 99afa50..eaa7f41 100644 --- a/src/sc_editor.h +++ b/src/sc_editor.h @@ -119,6 +119,7 @@ struct _sceditor struct frame *cursor_frame; int cursor_para; /* paragraph index */ int cursor_pos; /* character offset into paragraph */ + int cursor_trail; /* Border surrounding actual slide within drawingarea */ double border_offs_x; |