summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Hirt <daniel.hirt@samsung.com>2016-06-13 10:59:59 +0000
committerDaniel Hirt <daniel.hirt@samsung.com>2016-06-13 14:47:47 +0000
commit6a33d922fbfe9db1b4a3c6198c0f0da706b63270 (patch)
tree90da7160da31ba07647089884d9bc30d08b44112
parent38d1f9e140f5c042b2d76dc02bee821e8cd36a2f (diff)
downloadefl-6a33d922fbfe9db1b4a3c6198c0f0da706b63270.tar.gz
Efl.Ui.Text: implement selection logic (WIP)
-rw-r--r--src/lib/elementary/efl_ui_text.c247
1 files changed, 180 insertions, 67 deletions
diff --git a/src/lib/elementary/efl_ui_text.c b/src/lib/elementary/efl_ui_text.c
index 2bbefb6309..d6914c6ccc 100644
--- a/src/lib/elementary/efl_ui_text.c
+++ b/src/lib/elementary/efl_ui_text.c
@@ -21,10 +21,12 @@
#include "elm_widget_entry.h"
#include "efl_ui_text.eo.h"
+typedef struct _Efl_Ui_Text_Data Efl_Ui_Text_Data;
+typedef struct _Efl_Ui_Text_Rectangle Efl_Ui_Text_Rectangle;
+
/**
* Base widget smart data extended with entry instance data.
*/
-typedef struct _Efl_Ui_Text_Data Efl_Ui_Text_Data;
struct _Efl_Ui_Text_Data
{
Evas_Object *hit_rect, *entry_edje, *scr_edje;
@@ -66,7 +68,8 @@ struct _Efl_Ui_Text_Data
Elm_Input_Panel_Lang input_panel_lang;
Elm_Input_Panel_Return_Key_Type input_panel_return_key_type;
Elm_Input_Hints input_hints;
- Edje_Cursor sel_handler_cursor;
+ Eo *sel_handler_cursor;
+ Eina_List *rects;
void *input_panel_imdata;
int input_panel_imdata_len;
int input_panel_layout_variation;
@@ -140,6 +143,12 @@ struct _Efl_Ui_Text_Data
if (EINA_UNLIKELY(!eo_isa((obj), EFL_UI_TEXT_CLASS))) \
return
+struct _Efl_Ui_Text_Rectangle
+{
+ Eina_Rectangle rect;
+ Evas_Object *obj_bg, *obj;
+};
+
#define MY_CLASS EFL_UI_TEXT_CLASS
#define MY_CLASS_NAME "Efl_Ui_Text"
@@ -218,10 +227,11 @@ struct _Mod_Api
static void _create_selection_handlers(Evas_Object *obj, Efl_Ui_Text_Data *sd);
static void _magnifier_move(void *data);
-static void _update_decorations(Efl_Ui_Text_Data *sd);
+static void _update_decorations(Eo *obj, Eo *text_obj);
static void _create_text_cursors(Eo *obj, Efl_Ui_Text_Data *sd);
static Eina_Bool _efl_ui_text_changed_cb(void *data EINA_UNUSED, const Eo_Event *event);
-static Eina_Bool _text_cursor_changed_cb(void *data EINA_UNUSED, const Eo_Event *event);
+static Eina_Bool _efl_ui_text_selection_changed_cb(void *data EINA_UNUSED, const Eo_Event *event);
+static Eina_Bool _efl_ui_text_cursor_changed_cb(void *data EINA_UNUSED, const Eo_Event *event);
static Mod_Api *
_module_find(Evas_Object *obj EINA_UNUSED)
@@ -1211,7 +1221,7 @@ _deferred_recalc_job(void *data)
elm_widget_show_region_set(data, cx, cy, cw, ch, EINA_FALSE);
}
}
- _update_decorations(sd);
+ _update_decorations(data, sw);
}
EOLIAN static void
@@ -3612,28 +3622,32 @@ _start_handler_mouse_down_cb(void *data,
EFL_UI_TEXT_DATA_GET(data, sd);
Evas_Event_Mouse_Down *ev = event_info;
- int start_pos, end_pos, main_pos, pos;
+ int start_pos, end_pos, pos;
+ Efl_Canvas_Text_Cursor *sel_start, *sel_end;
+ Efl_Canvas_Text_Cursor *main_cur;
+
+ Eo *text_obj = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
sd->start_handler_down = EINA_TRUE;
- start_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
- EDJE_CURSOR_SELECTION_BEGIN);
- end_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
- EDJE_CURSOR_SELECTION_END);
- main_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
- EDJE_CURSOR_MAIN);
+
+ /* Get the cursors */
+ efl_ui_text_interactive_selection_cursors_get(text_obj, &sel_start, &sel_end);
+ main_cur = efl_canvas_text_cursor_get(text_obj);
+
+ start_pos = efl_canvas_text_cursor_position_get(sel_start);
+ end_pos = efl_canvas_text_cursor_position_get(sel_end);
+
if (start_pos <= end_pos)
{
pos = start_pos;
- sd->sel_handler_cursor = EDJE_CURSOR_SELECTION_BEGIN;
+ sd->sel_handler_cursor = sel_start;
}
else
{
pos = end_pos;
- sd->sel_handler_cursor = EDJE_CURSOR_SELECTION_END;
+ sd->sel_handler_cursor = sel_end;
}
- if (pos != main_pos)
- edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
- EDJE_CURSOR_MAIN, pos);
+ efl_canvas_text_cursor_position_set(main_cur, pos);
_selection_handlers_offset_calc(data, sd->start_handler, ev->canvas.x, ev->canvas.y);
}
@@ -3667,19 +3681,23 @@ _start_handler_mouse_move_cb(void *data,
Evas_Event_Mouse_Move *ev = event_info;
Evas_Coord ex, ey;
Evas_Coord cx, cy;
+ Efl_Canvas_Text_Cursor *main_cur;
int pos;
+ Eo *text_obj = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+ main_cur = efl_canvas_text_cursor_get(text_obj);
+
evas_object_geometry_get(sd->entry_edje, &ex, &ey, NULL, NULL);
cx = ev->cur.canvas.x - sd->ox - ex;
cy = ev->cur.canvas.y - sd->oy - ey;
if (cx <= 0) cx = 1;
- edje_object_part_text_cursor_coord_set(sd->entry_edje, "elm.text",
- sd->sel_handler_cursor, cx, cy);
- pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
- sd->sel_handler_cursor);
- edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
- EDJE_CURSOR_MAIN, pos);
+ efl_canvas_text_cursor_coord_set(sd->sel_handler_cursor, cx, cy);
+ pos = efl_canvas_text_cursor_position_get(sd->sel_handler_cursor);
+
+ /* Set the main cursor. */
+ efl_canvas_text_cursor_position_set(main_cur, pos);
+
ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
sd->long_pressed = EINA_FALSE;
if (_elm_config->magnifier_enable)
@@ -3695,28 +3713,32 @@ _end_handler_mouse_down_cb(void *data,
EFL_UI_TEXT_DATA_GET(data, sd);
Evas_Event_Mouse_Down *ev = event_info;
- int pos, start_pos, end_pos, main_pos;
+ Efl_Canvas_Text_Cursor *sel_start, *sel_end;
+ Efl_Canvas_Text_Cursor *main_cur;
+ int pos, start_pos, end_pos;
sd->end_handler_down = EINA_TRUE;
- start_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
- EDJE_CURSOR_SELECTION_BEGIN);
- end_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
- EDJE_CURSOR_SELECTION_END);
+
+ Eo *text_obj = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+
+ efl_ui_text_interactive_selection_cursors_get(text_obj, &sel_start, &sel_end);
+ main_cur = efl_canvas_text_cursor_get(text_obj);
+
+ start_pos = efl_canvas_text_cursor_position_get(sel_start);
+ end_pos = efl_canvas_text_cursor_position_get(sel_end);
+
if (start_pos < end_pos)
{
pos = end_pos;
- sd->sel_handler_cursor = EDJE_CURSOR_SELECTION_END;
+ sd->sel_handler_cursor = sel_start;
}
else
{
pos = start_pos;
- sd->sel_handler_cursor = EDJE_CURSOR_SELECTION_BEGIN;
+ sd->sel_handler_cursor = sel_end;
}
- main_pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
- EDJE_CURSOR_MAIN);
- if (pos != main_pos)
- edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
- EDJE_CURSOR_MAIN, pos);
+
+ efl_canvas_text_cursor_position_set(main_cur, pos);
_selection_handlers_offset_calc(data, sd->end_handler, ev->canvas.x, ev->canvas.y);
}
@@ -3757,12 +3779,12 @@ _end_handler_mouse_move_cb(void *data,
cy = ev->cur.canvas.y - sd->oy - ey;
if (cx <= 0) cx = 1;
- edje_object_part_text_cursor_coord_set(sd->entry_edje, "elm.text",
- sd->sel_handler_cursor, cx, cy);
- pos = edje_object_part_text_cursor_pos_get(sd->entry_edje, "elm.text",
- sd->sel_handler_cursor);
- edje_object_part_text_cursor_pos_set(sd->entry_edje, "elm.text",
- EDJE_CURSOR_MAIN, pos);
+ efl_canvas_text_cursor_coord_set(sd->sel_handler_cursor, cx, cy);
+ pos = efl_canvas_text_cursor_position_get(sd->sel_handler_cursor);
+ /* Set the main cursor. */
+ efl_canvas_text_cursor_position_set(
+ edje_object_part_swallow_get(sd->entry_edje, "elm.text"),
+ pos);
ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del);
sd->long_pressed = EINA_FALSE;
if (_elm_config->magnifier_enable)
@@ -3772,7 +3794,7 @@ _end_handler_mouse_move_cb(void *data,
EOLIAN static void
_efl_ui_text_evas_object_smart_add(Eo *obj, Efl_Ui_Text_Data *priv)
{
- Eo *ui_text;
+ Eo *text_obj;
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
@@ -3798,14 +3820,16 @@ _efl_ui_text_evas_object_smart_add(Eo *obj, Efl_Ui_Text_Data *priv)
if (!elm_layout_theme_set(obj, "efl_ui_text", "base", elm_widget_style_get(obj)))
CRI("Failed to set layout!");
- ui_text = eo_add(EFL_UI_INTERNAL_TEXT_INTERACTIVE_CLASS, obj);
- eo_composite_attach(obj, ui_text);
- edje_object_part_swallow(priv->entry_edje, "elm.text", ui_text);
- efl_canvas_text_style_set(ui_text, "font=Sans font_size=14 color=#fff wrap=word");
- eo_event_callback_add(ui_text, EFL_UI_TEXT_INTERACTIVE_EVENT_CHANGED_USER,
- _efl_ui_text_changed_cb, priv);
- eo_event_callback_add(efl_canvas_text_cursor_get(ui_text), EFL_CANVAS_TEXT_CURSOR_EVENT_CHANGED,
- _text_cursor_changed_cb, priv);
+ text_obj = eo_add(EFL_UI_INTERNAL_TEXT_INTERACTIVE_CLASS, obj);
+ eo_composite_attach(obj, text_obj);
+ edje_object_part_swallow(priv->entry_edje, "elm.text", text_obj);
+ efl_canvas_text_style_set(text_obj, "font=Sans font_size=14 color=#fff wrap=word");
+ eo_event_callback_add(text_obj, EFL_UI_TEXT_INTERACTIVE_EVENT_CHANGED_USER,
+ _efl_ui_text_changed_cb, obj);
+ eo_event_callback_add(text_obj, EFL_UI_TEXT_INTERACTIVE_EVENT_SELECTION_CHANGED,
+ _efl_ui_text_selection_changed_cb, obj);
+ eo_event_callback_add(efl_canvas_text_cursor_get(text_obj), EFL_CANVAS_TEXT_CURSOR_EVENT_CHANGED,
+ _efl_ui_text_cursor_changed_cb, obj);
priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
@@ -5832,12 +5856,20 @@ _efl_ui_text_elm_interface_atspi_accessible_name_get(Eo *obj, Efl_Ui_Text_Data *
}
static inline Eo *
-_cursor_create(Eo *obj, Efl_Ui_Text_Data *sd, const char *file, const char *source)
+_decoration_create(Eo *obj, Efl_Ui_Text_Data *sd, const char *file,
+ const char *source, Eina_Bool above)
{
Eo *ret = eo_add(EDJE_OBJECT_CLASS, obj);
edje_object_file_set(ret, file, source);
evas_object_smart_member_add(ret, obj);
- evas_object_stack_above(ret, sd->entry_edje);
+ if (above)
+ {
+ evas_object_stack_above(ret, sd->entry_edje);
+ }
+ else
+ {
+ evas_object_stack_below(ret, sd->entry_edje);
+ }
evas_object_clip_set(ret, evas_object_clip_get(obj));
evas_object_pass_events_set(ret, EINA_TRUE);
return ret;
@@ -5851,29 +5883,27 @@ _create_text_cursors(Eo *obj, Efl_Ui_Text_Data *sd)
{
const char *file;
efl_file_get(sd->entry_edje, &file, NULL);
- sd->cursor = _cursor_create(obj, sd, file, "elm/entry/cursor/default");
- sd->cursor_bidi = _cursor_create(obj, sd, file, "elm/entry/cursor/default");
+ sd->cursor = _decoration_create(obj, sd, file, "elm/entry/cursor/default", EINA_TRUE);
+ sd->cursor_bidi = _decoration_create(obj, sd, file, "elm/entry/cursor/default", EINA_TRUE);
evas_object_show(sd->cursor);
evas_object_show(sd->cursor_bidi);
edje_object_signal_emit(sd->cursor, "elm,action,focus", "elm");
edje_object_signal_emit(sd->cursor_bidi, "elm,action,focus", "elm");
}
-/**
- * General function to be called whenever decorations are requried to be
- * updated. Example cases are resizes, key events, change events etc.
- */
static void
-_update_text_cursors(Efl_Ui_Text_Data *sd)
+_update_text_cursors(Eo *obj)
{
Evas_Coord x, y, w, h, xx, yy, ww, hh;
Evas_Coord xx2, yy2;
- Eo *text_obj;
Eina_Bool bidi_cursor;
+ EFL_UI_TEXT_DATA_GET(obj, sd);
+
+ Eo *text_obj = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+
x = y = w = h = -1;
xx = yy = ww = hh = -1;
- text_obj = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
evas_object_geometry_get(text_obj, &x, &y, &w, &h);
//FIXME; HACKKK!!!
x = 0; y = 0;
@@ -5906,22 +5936,105 @@ _update_text_cursors(Efl_Ui_Text_Data *sd)
}
static void
-_update_decorations(Efl_Ui_Text_Data *sd)
+_update_text_selection(Eo *obj, Eo *text_obj)
+{
+ Evas_Coord x, y;
+ Efl_Canvas_Text_Cursor *sel_start, *sel_end;
+
+ Eina_List *l;
+ Eina_Iterator *range;
+ Efl_Ui_Text_Rectangle *rect;
+ Eina_Rectangle *r;
+ const char *file;
+
+ EFL_UI_TEXT_DATA_GET(obj, sd);
+
+ evas_object_geometry_get(text_obj, &x, &y, NULL, NULL);
+
+ efl_file_get(sd->entry_edje, &file, NULL);
+
+ efl_ui_text_interactive_selection_cursors_get(text_obj, &sel_start, &sel_end);
+
+#if 1
+ {
+ int pos_start, pos_end;
+
+ pos_start = efl_canvas_text_cursor_position_get(sel_start);
+ pos_end = efl_canvas_text_cursor_position_get(sel_end);
+
+ printf("start=%d, end=%d\n", pos_start, pos_end);
+ }
+#endif
+
+ range = efl_canvas_text_range_geometry_get(text_obj,
+ sel_start, sel_end);
+
+ l = sd->rects;
+ EINA_ITERATOR_FOREACH(range, r)
+ {
+ /* Create if there isn't a rectangle to populate. */
+ if (!l)
+ {
+ rect = calloc(1, sizeof(Efl_Ui_Text_Rectangle));
+ sd->rects = eina_list_append(sd->rects, rect);
+
+ rect->obj_bg = _decoration_create(obj, sd, file, "elm/entry/selection/default", EINA_FALSE);
+ }
+ else
+ {
+ rect = eina_list_data_get(l);
+ l = l->next;
+ }
+ rect->rect = *r;
+
+ if (rect->obj_bg)
+ {
+ evas_object_move(rect->obj_bg, x + r->x, y + r->y);
+ evas_object_resize(rect->obj_bg, r->w, r->h);
+ }
+ }
+ eina_iterator_free(range);
+
+ /* delete redundant rectection rects */
+ while (l)
+ {
+ Eina_List *temp = l->next;
+ rect = eina_list_data_get(l);
+ if (rect)
+ {
+ if (rect->obj_bg) eo_del(rect->obj_bg);
+ free(rect);
+ }
+ sd->rects = eina_list_remove_list(sd->rects, l);
+ l = temp;
+ }
+}
+
+static void
+_update_decorations(Eo *en_obj, Eo *text_obj)
{
- _update_text_cursors(sd);
+ _update_text_cursors(en_obj);
+ _update_text_selection(en_obj, text_obj);
+}
+
+static Eina_Bool
+_efl_ui_text_changed_cb(void *data, const Eo_Event *event EINA_UNUSED)
+{
+ _update_decorations(data, event->object);
+ return EINA_TRUE;
}
static Eina_Bool
-_efl_ui_text_changed_cb(void *data EINA_UNUSED, const Eo_Event *event EINA_UNUSED)
+_efl_ui_text_cursor_changed_cb(void *data, const Eo_Event *event EINA_UNUSED)
{
- _update_decorations(data);
+ _update_text_cursors(data);
return EINA_TRUE;
}
static Eina_Bool
-_text_cursor_changed_cb(void *data EINA_UNUSED, const Eo_Event *event EINA_UNUSED)
+_efl_ui_text_selection_changed_cb(void *data, const Eo_Event *event EINA_UNUSED)
{
- _update_decorations(data);
+ _update_text_selection(data, event->object);
return EINA_TRUE;
}