aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2013-08-15 23:51:42 +0200
committerThomas White <taw@bitwiz.org.uk>2013-08-15 23:51:42 +0200
commit8d341bdb00df96e549f0cadc64c25cfa4f09294a (patch)
treec7c72ee9431a33831c34c2e782456c5378da6152
parent4fd6e38211b569b81045528ea8794de790ad9da9 (diff)
Click to set cursor position (needs debugging)
-rw-r--r--src/mainwindow.c3
-rw-r--r--src/wrap.c106
-rw-r--r--src/wrap.h1
3 files changed, 60 insertions, 50 deletions
diff --git a/src/mainwindow.c b/src/mainwindow.c
index 2ec5771..54792ce 100644
--- a/src/mainwindow.c
+++ b/src/mainwindow.c
@@ -1184,6 +1184,9 @@ static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event,
p->drag_status = DRAG_STATUS_NONE;
p->drag_reason = DRAG_REASON_NONE;
set_selection(p, clicked);
+ clicked->pos = find_cursor_pos(clicked,
+ x-clicked->x, y-clicked->y);
+ p->cursor_pos = clicked->pos;
}
diff --git a/src/wrap.c b/src/wrap.c
index 5cff2e0..76780b4 100644
--- a/src/wrap.c
+++ b/src/wrap.c
@@ -166,72 +166,78 @@ void get_cursor_pos(struct frame *fr, size_t pos,
}
-#if 0
-size_t find_cursor_pos(struct frame *fr, double xposd, double yposd)
+static struct wrap_line *find_cursor_line(struct frame *fr, double yposd,
+ int *end)
{
- int line, box;
- signed int i;
- struct wrap_line *l;
- struct wrap_box *b;
- int p;
- int found = 0;
+ int i;
+ double y = fr->lop.pad_t;
- *xposd = 0;
- *yposd = 0;
+ *end = 0;
- line = 0;
for ( i=0; i<fr->n_lines; i++ ) {
- if ( fr->lines[i].sc_offset > pos ) {
- line = i-1;
- found = 1;
- break;
+ double height = pango_units_to_double(fr->lines[i].height);
+ if ( yposd < y + height ) {
+ return &fr->lines[i];
}
- }
- if ( !found ) {
- /* Cursor is on the last line */
- line = fr->n_lines-1;
- }
- assert(line >= 0);
- for ( i=0; i<line; i++ ) {
- *yposd += fr->lines[i].height;
+ y += height;
}
- *line_height = pango_units_to_double(fr->lines[line].height);
- *yposd /= PANGO_SCALE;
- *yposd += fr->lop.pad_t;
+ *end = 1;
+ return &fr->lines[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)
+{
+ int i;
+ double x = fr->lop.pad_l;
- l = &fr->lines[line];
- box = 0;
- for ( i=0; i<l->n_boxes-1; i++ ) {
- box = i;
- if ( l->boxes[i+1].type == WRAP_BOX_SENTINEL ) break;
- if ( l->boxes[i+1].sc_offset > pos ) break;
- *xposd += l->boxes[i].width;
- if ( i < l->n_boxes-2 ) {
- *xposd += l->boxes[i].sp;
+ *end = 0;
+
+ for ( i=0; i<l->n_boxes; i++ ) {
+ double width = pango_units_to_double(l->boxes[i].width);
+ width += pango_units_to_double(l->boxes[i].sp);
+ if ( xposd < x + width ) {
+ *x_pos = xposd - x;
+ return &l->boxes[i];
}
+ x += width;
}
- b = &l->boxes[box];
- if ( b->type == WRAP_BOX_PANGO ) {
- pango_glyph_string_index_to_x(b->glyphs, b->text,
- strlen(b->text),
- &b->item->analysis,
- pos - b->sc_offset,
- FALSE, &p);
- //printf("offset %i in '%s' -> %i\n",
- // (int)pos-(int)b->sc_offset, b->text, p);
+ *end = 1;
+ *x_pos = xposd - x;
+ return &l->boxes[i];
+}
- *xposd += p;
- *xposd /= PANGO_SCALE;
- *xposd += fr->lop.pad_l;
- //printf("%i -> line %i, box %i -> %f, %f\n",
- // (int)pos, line, box, *xposd, *yposd);
+size_t find_cursor_pos(struct frame *fr, double xposd, double yposd)
+{
+ struct wrap_line *l;
+ struct wrap_box *b;
+ int end;
+ double x_pos;
+
+ l = find_cursor_line(fr, yposd, &end);
+
+ if ( end ) {
+ b = &l->boxes[l->n_boxes - 1];
} else {
+ b = find_cursor_box(fr, l, xposd, &x_pos, &end);
+ }
+
+ if ( b->type == WRAP_BOX_PANGO ) {
+ int idx, trail;
+ int x_pos_i = pango_units_from_double(x_pos);
+ pango_glyph_string_x_to_index(b->glyphs, b->text,
+ strlen(b->text),
+ &b->item->analysis,
+ x_pos_i, &idx, &trail);
+ return b->sc_offset + idx + trail; /* FIXME: Assumes 1 byte char */
}
+
+ return b->sc_offset;
}
-#endif
static void shape_and_measure(gpointer data, gpointer user_data)
diff --git a/src/wrap.h b/src/wrap.h
index 603d2e6..6f03fd9 100644
--- a/src/wrap.h
+++ b/src/wrap.h
@@ -102,6 +102,7 @@ extern int wrap_contents(struct frame *fr, PangoContext *pc);
extern void get_cursor_pos(struct frame *fr, 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 wrap_line_free(struct wrap_line *l);
extern void show_boxes(struct wrap_line *boxes);