From: Jan Arne Petersen <jpeter...@openismus.com>

Make it possible to select text and render the selection to the editor
example.

Signed-off-by: Jan Arne Petersen <jpeter...@openismus.com>
---
 clients/editor.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 75 insertions(+), 1 deletion(-)

diff --git a/clients/editor.c b/clients/editor.c
index 295018a..3056bdc 100644
--- a/clients/editor.c
+++ b/clients/editor.c
@@ -50,6 +50,7 @@ struct text_entry {
        char *text;
        int active;
        uint32_t cursor;
+       uint32_t anchor;
        struct text_model *model;
        struct text_layout *layout;
 };
@@ -309,6 +310,7 @@ text_entry_create(struct editor *editor, const char *text)
        entry->text = strdup(text);
        entry->active = 0;
        entry->cursor = strlen(text);
+       entry->anchor = entry->cursor;
        entry->model = 
text_model_factory_create_text_model(editor->text_model_factory);
        text_model_add_listener(entry->model, &text_model_listener, entry);
 
@@ -418,6 +420,7 @@ text_entry_insert_at_cursor(struct text_entry *entry, const 
char *text)
        free(entry->text);
        entry->text = new_text;
        entry->cursor += strlen(text);
+       entry->anchor += strlen(text);
 
        text_layout_set_text(entry->layout, entry->text);
 }
@@ -432,6 +435,50 @@ text_entry_set_cursor_position(struct text_entry *entry,
 }
 
 static void
+text_entry_set_anchor_position(struct text_entry *entry,
+                              int32_t x, int32_t y)
+{
+       entry->anchor = text_layout_xy_to_index(entry->layout, x, y);
+
+       widget_schedule_redraw(entry->widget);
+}
+
+static void
+text_entry_draw_selection(struct text_entry *entry, cairo_t *cr)
+{
+       cairo_text_extents_t extents;
+       uint32_t start_index = entry->anchor < entry->cursor ? entry->anchor : 
entry->cursor;
+       uint32_t end_index = entry->anchor < entry->cursor ? entry->cursor : 
entry->anchor;
+       cairo_rectangle_t start;
+       cairo_rectangle_t end;
+
+       if (entry->anchor == entry->cursor)
+               return;
+
+       text_layout_extents(entry->layout, &extents);
+
+       text_layout_index_to_pos(entry->layout, start_index, &start);
+       text_layout_index_to_pos(entry->layout, end_index, &end);
+
+       cairo_save (cr);
+
+       cairo_set_source_rgba(cr, 0.0, 0.0, 1.0, 1.0);
+       cairo_rectangle(cr,
+                       start.x, extents.y_bearing + extents.height + 2,
+                       end.x - start.x, -extents.height - 4);
+       cairo_fill(cr);
+
+       cairo_rectangle(cr,
+                       start.x, extents.y_bearing + extents.height,
+                       end.x - start.x, -extents.height);
+       cairo_clip(cr);
+       cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
+       text_layout_draw(entry->layout, cr);
+
+       cairo_restore (cr);
+}
+
+static void
 text_entry_draw_cursor(struct text_entry *entry, cairo_t *cr)
 {
        cairo_text_extents_t extents;
@@ -484,6 +531,8 @@ text_entry_redraw_handler(struct widget *widget, void *data)
        cairo_translate(cr, 10, allocation.height / 2);
        text_layout_draw(entry->layout, cr);
 
+       text_entry_draw_selection(entry, cr);
+
        text_entry_draw_cursor(entry, cr);
 
        cairo_pop_group_to_source(cr);
@@ -493,6 +542,23 @@ text_entry_redraw_handler(struct widget *widget, void 
*data)
        cairo_surface_destroy(surface);
 }
 
+static int
+text_entry_motion_handler(struct widget *widget,
+                         struct input *input, uint32_t time,
+                         float x, float y, void *data)
+{
+       struct text_entry *entry = data;
+       struct rectangle allocation;
+
+       widget_get_allocation(entry->widget, &allocation);
+
+       text_entry_set_cursor_position(entry,
+                                      x - allocation.x,
+                                      y - allocation.y);
+
+       return CURSOR_IBEAM;
+}
+
 static void
 text_entry_button_handler(struct widget *widget,
                          struct input *input, uint32_t time,
@@ -510,7 +576,7 @@ text_entry_button_handler(struct widget *widget,
                return;
        }
 
-       text_entry_set_cursor_position(entry, 
+       text_entry_set_cursor_position(entry,
                                       x - allocation.x,
                                       y - allocation.y);
 
@@ -518,6 +584,14 @@ text_entry_button_handler(struct widget *widget,
                struct wl_seat *seat = input_get_seat(input);
 
                text_entry_activate(entry, seat);
+
+               text_entry_set_anchor_position(entry,
+                                              x - allocation.x,
+                                              y - allocation.y);
+
+               widget_set_motion_handler(entry->widget, 
text_entry_motion_handler);
+       } else {
+               widget_set_motion_handler(entry->widget, NULL);
        }
 }
 
-- 
1.7.11.4

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to