aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2014-03-11 23:15:34 +0100
committerThomas White <taw@bitwiz.org.uk>2014-03-11 23:15:34 +0100
commitcd5b7c2b8905619e2c66959178c92fc41a712eb7 (patch)
tree34dc48dd9dbc560342693b2b93b6e4fdacbfaec3
parente16371560338dc7596aeed75c0ea2fd6288c7088 (diff)
New way of doing cursor position
-rw-r--r--src/frame.h2
-rw-r--r--src/mainwindow.c54
-rw-r--r--src/presentation.h5
-rw-r--r--src/render.c9
-rw-r--r--src/shape.c1
-rw-r--r--src/wrap.c98
-rw-r--r--src/wrap.h7
7 files changed, 87 insertions, 89 deletions
diff --git a/src/frame.h b/src/frame.h
index e1cfccd..beb8187 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -53,8 +53,6 @@ struct frame
int max_lines;
struct wrap_line *lines;
- size_t pos;
-
/* The rectangle allocated to this frame, determined by the renderer */
double x;
double y;
diff --git a/src/mainwindow.c b/src/mainwindow.c
index ab75cdc..7c850cd 100644
--- a/src/mainwindow.c
+++ b/src/mainwindow.c
@@ -905,19 +905,33 @@ static void draw_editing_box(cairo_t *cr, struct frame *fr)
}
-static void draw_caret(cairo_t *cr, struct frame *fr, int pos)
+static void draw_caret(cairo_t *cr, struct frame *fr,
+ int cursor_line, int cursor_box, int cursor_pos)
{
double xposd, yposd, line_height;
double cx, clow, chigh;
const double t = 1.8;
+ struct wrap_box *box;
+ int i;
+
+ if ( fr == NULL ) return;
+ if ( fr->n_lines == 0 ) return;
+ printf("Cursor at frame %p, line %i, box %i, pos %i\n",
+ fr, cursor_line, cursor_box, cursor_pos);
+
+ /* Locate the cursor in a "logical" and "geographical" sense */
+ box = &fr->lines[cursor_line].boxes[cursor_box];
+ get_cursor_pos(box, cursor_pos, &xposd, &yposd, &line_height);
- /* Fix up cursor position if necessary */
- if ( (fr->n_lines > 0) && (fr->pos < fr->lines[0].sc_offset) ) {
- fr->pos = fr->lines[0].sc_offset;
- pos = fr->pos;
+ for ( i=0; i<cursor_line; i++ ) {
+ yposd += pango_units_to_double(fr->lines[i].height);
}
- get_cursor_pos(fr, pos, &xposd, &yposd, &line_height);
+ for ( i=0; i<cursor_box; i++ ) {
+ int w = fr->lines[cursor_line].boxes[i].width;
+ w += fr->lines[cursor_line].boxes[i].sp;
+ xposd += pango_units_to_double(w);
+ }
cx = fr->x + xposd;
clow = fr->y + yposd;
@@ -976,7 +990,8 @@ static void draw_overlay(cairo_t *cr, struct presentation *p)
/* If only one frame is selected, draw the caret */
if ( p->n_selection == 1 ) {
- draw_caret(cr, p->selection[0], p->cursor_pos);
+ draw_caret(cr, p->cursor_frame, p->cursor_line, p->cursor_box,
+ p->cursor_pos);
}
if ( (p->drag_status == DRAG_STATUS_DRAGGING)
@@ -1381,9 +1396,10 @@ static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event,
} else {
- clicked->pos = find_cursor_pos(clicked,
- x-fr->x, y-fr->y);
- p->cursor_pos = clicked->pos;
+ p->cursor_frame = clicked;
+ find_cursor(clicked, x-fr->x, y-fr->y,
+ &p->cursor_line, &p->cursor_box,
+ &p->cursor_pos);
p->start_corner_x = event->x - p->border_offs_x;
p->start_corner_y = event->y - p->border_offs_y;
@@ -1583,22 +1599,20 @@ static gboolean button_release_sig(GtkWidget *da, GdkEventButton *event,
static void move_cursor(struct presentation *p, signed int x, signed int y)
{
-#warning Re-implement move_cursor() please
-#if 0
- ssize_t pos = p->cursor_pos;
+ struct wrap_line *line = &p->cursor_frame->lines[p->cursor_line];
+ struct wrap_box *box = &line->boxes[p->cursor_box];
/* FIXME: Advance past images etc */
- pos += x;
- if ( pos < 0 ) pos = 0;
+ p->cursor_pos += x;
- if ( pos > strlen(p->selection[0]->sc) ) {
- pos = strlen(p->selection[0]->sc);
+ if ( p->cursor_pos < 0 ) {
+ p->cursor_pos = 0;
}
- p->selection[0]->pos = pos;
- p->cursor_pos = pos;
-#endif
+ if ( p->cursor_pos > g_utf8_strlen(box->text, -1) ) {
+ p->cursor_pos = 0;
+ }
}
diff --git a/src/presentation.h b/src/presentation.h
index 09c6878..d66692e 100644
--- a/src/presentation.h
+++ b/src/presentation.h
@@ -139,6 +139,11 @@ struct presentation
struct frame **selection;
int n_selection;
int max_selection;
+
+ /* Location of the cursor */
+ struct frame *cursor_frame;
+ int cursor_line;
+ int cursor_box;
size_t cursor_pos;
/* This is the "native" size of the slide. It only exists to give
diff --git a/src/render.c b/src/render.c
index 49ff5c3..2d45261 100644
--- a/src/render.c
+++ b/src/render.c
@@ -110,7 +110,6 @@ static void render_image_box(cairo_t *cr, struct wrap_box *box, ImageStore *is,
static void draw_outline(cairo_t *cr, struct wrap_box *box)
{
- char tmp[32];
double asc, desc;
if ( box->type == WRAP_BOX_SENTINEL ) return;
@@ -128,14 +127,6 @@ static void draw_outline(cairo_t *cr, struct wrap_box *box)
pango_units_to_double(box->sp), asc + desc);
cairo_set_source_rgb(cr, 0.7, 0.4, 0.7);
cairo_fill(cr);
-
- snprintf(tmp, 31, "%lli", (long long int)box->sc_offset);
- cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_ITALIC,
- CAIRO_FONT_WEIGHT_NORMAL);
- cairo_set_font_size(cr, 10.0);
- cairo_move_to(cr, 0.0, desc);
- cairo_set_source_rgb(cr, 0.0, 0.0, 0.7);
- cairo_show_text(cr, tmp);
}
diff --git a/src/shape.c b/src/shape.c
index e54de09..4edd57b 100644
--- a/src/shape.c
+++ b/src/shape.c
@@ -79,7 +79,6 @@ static int add_wrap_box(struct wrap_line *line, char *text, size_t offset,
box = &line->boxes[line->n_boxes];
if ( !editable ) offset = 0;
- box->sc_offset = offset;
box->type = WRAP_BOX_PANGO;
box->text = text;
box->space = space;
diff --git a/src/wrap.c b/src/wrap.c
index a929ad0..d419a1b 100644
--- a/src/wrap.c
+++ b/src/wrap.c
@@ -83,7 +83,7 @@ void initialise_line(struct wrap_line *l)
}
-
+#if 0
static struct wrap_line *get_cursor_line(struct frame *fr, size_t pos,
double *yposd)
{
@@ -117,56 +117,32 @@ static struct wrap_line *get_cursor_line(struct frame *fr, size_t pos,
return &fr->lines[line];
}
+#endif
-
-void get_cursor_pos(struct frame *fr, size_t pos,
+void get_cursor_pos(struct wrap_box *box, size_t pos,
double *xposd, double *yposd, double *line_height)
{
- signed int i;
- struct wrap_line *l;
- struct wrap_box *b;
int p;
- int box;
*xposd = 0.0;
*yposd = 0.0;
*line_height = 20.0;
- if ( fr->n_lines == 0 ) return;
-
- l = get_cursor_line(fr, pos, yposd);
- if ( l == NULL ) return;
-
- *line_height = pango_units_to_double(l->height);
-
- for ( box=1; box<l->n_boxes; box++ ) {
- /* Was the cursor in the previous box? */
- if ( !l->boxes[box].editable ) continue;
- if ( l->boxes[box].type == WRAP_BOX_SENTINEL ) break;
- if ( l->boxes[box].sc_offset > pos ) break;
- }
- box--;
-
- *xposd = fr->pad_l;
- for ( i=0; i<box; i++ ) {
- *xposd += pango_units_to_double(l->boxes[i].width);
- *xposd += pango_units_to_double(l->boxes[i].sp);
- }
+ if ( box == NULL ) return;
- b = &l->boxes[box];
+ *line_height = pango_units_to_double(box->height);
- if ( !b->editable ) {
- *xposd += pango_units_to_double(b->width);
+ if ( !box->editable ) {
+ *xposd += pango_units_to_double(box->width);
return;
}
- switch ( b->type ) {
+ switch ( box->type ) {
case WRAP_BOX_PANGO :
- pango_glyph_string_index_to_x(b->glyphs, b->text,
- strlen(b->text),
- &b->item->analysis,
- pos - b->sc_offset,
+ pango_glyph_string_index_to_x(box->glyphs, box->text,
+ strlen(box->text),
+ &box->item->analysis, pos,
FALSE, &p);
*xposd += pango_units_to_double(p);
break;
@@ -178,8 +154,7 @@ void get_cursor_pos(struct frame *fr, size_t pos,
}
-static struct wrap_line *find_cursor_line(struct frame *fr, double yposd,
- int *end)
+static int find_cursor_line(struct frame *fr, double yposd, int *end)
{
int i;
double y = fr->pad_t;
@@ -189,18 +164,18 @@ static struct wrap_line *find_cursor_line(struct frame *fr, double yposd,
for ( i=0; i<fr->n_lines; i++ ) {
double height = pango_units_to_double(fr->lines[i].height);
if ( yposd < y + height ) {
- return &fr->lines[i];
+ return i;
}
y += height;
}
*end = 1;
- return &fr->lines[fr->n_lines-1];
+ return fr->n_lines-1;
}
-static struct wrap_box *find_cursor_box(struct frame *fr, struct wrap_line *l,
- double xposd, double *x_pos, int *end)
+static int find_cursor_box(struct frame *fr, struct wrap_line *l,
+ double xposd, double *x_pos, int *end)
{
int i;
double x = fr->pad_l;
@@ -212,18 +187,19 @@ static struct wrap_box *find_cursor_box(struct frame *fr, struct wrap_line *l,
width += pango_units_to_double(l->boxes[i].sp);
if ( xposd < x + width ) {
*x_pos = xposd - x;
- return &l->boxes[i];
+ return i;
}
x += width;
}
*end = 1;
*x_pos = xposd - x;
- return &l->boxes[l->n_boxes-1];
+ return l->n_boxes-1;
}
-size_t find_cursor_pos(struct frame *fr, double xposd, double yposd)
+void find_cursor(struct frame *fr, double xposd, double yposd,
+ int *line, int *box, size_t *pos)
{
struct wrap_line *l;
struct wrap_box *b;
@@ -231,19 +207,31 @@ size_t find_cursor_pos(struct frame *fr, double xposd, double yposd)
double x_pos = 0.0;
int idx, trail;
int x_pos_i;
+ size_t offs;
+ int ln, bn;
- if ( fr->n_lines == 0 ) return 0;
+ if ( fr->n_lines == 0 ) {
+ *line = 0;
+ *box = 0;
+ *pos = 0;
+ return;
+ }
- l = find_cursor_line(fr, yposd, &end);
+ ln = find_cursor_line(fr, yposd, &end);
+ l = &fr->lines[ln];
+ *line = ln;
if ( end ) {
- b = &l->boxes[l->n_boxes - 1];
+ bn = l->n_boxes-1;
} else {
- b = find_cursor_box(fr, l, xposd, &x_pos, &end);
+ bn = find_cursor_box(fr, l, xposd, &x_pos, &end);
}
+ b = &l->boxes[bn];
+ *box = bn;
if ( !b->editable ) {
- return 0;
+ *pos = 0;
+ return;
}
switch ( b->type ) {
@@ -259,14 +247,19 @@ size_t find_cursor_pos(struct frame *fr, double xposd, double yposd)
&b->item->analysis,
x_pos_i, &idx, &trail);
/* FIXME: Assumes 1 byte char */
- return b->sc_offset + idx + trail;
+ offs = idx + trail;
case WRAP_BOX_SENTINEL :
- return l->boxes[l->n_boxes-2].sc_offset;
+ offs = 0;
+ break;
+
+ default :
+ offs = 0;
+ break;
}
- return b->sc_offset;
+ *pos = offs;
}
@@ -458,7 +451,6 @@ static void output_line(int q, int s, struct frame *fr, struct wrap_line *boxes)
l->max_boxes = s-q;
alloc_boxes(l);
- l->sc_offset = boxes->boxes[q].sc_offset;
for ( j=q; j<s; j++ ) {
l->boxes[l->n_boxes++] = boxes->boxes[j];
}
diff --git a/src/wrap.h b/src/wrap.h
index 8fc057a..a4064e6 100644
--- a/src/wrap.h
+++ b/src/wrap.h
@@ -59,7 +59,6 @@ enum wrap_box_space
struct wrap_box
{
enum wrap_box_type type;
- size_t sc_offset; /* How far into the SC for this frame */
int editable;
/* Pango units */
@@ -95,16 +94,16 @@ struct wrap_line
int overfull;
int underfull;
int last_line;
- size_t sc_offset;
};
extern int wrap_contents(struct frame *fr);
-extern void get_cursor_pos(struct frame *fr, size_t pos,
+extern void get_cursor_pos(struct wrap_box *box, size_t pos,
double *xposd, double *yposd, double *line_height);
-extern size_t find_cursor_pos(struct frame *fr, double xposd, double yposd);
+extern void find_cursor(struct frame *fr, double xposd, double yposd,
+ int *line, int *box, size_t *pos);
extern void alloc_boxes(struct wrap_line *l);
extern void initialise_line(struct wrap_line *l);