From 2afadb527b281e9befa36d24c037bc79f75b7b2c Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Thu, 19 Mar 2009 13:36:10 +0000 Subject: [PATCH] working on edje entry to allow more selection controls. not 100% done yet. SVN revision: 39578 --- legacy/edje/src/bin/edje_cc_handlers.c | 33 +++++++ legacy/edje/src/lib/Edje.h | 1 + legacy/edje/src/lib/edje_data.c | 1 + legacy/edje/src/lib/edje_entry.c | 132 +++++++++++++++++-------- legacy/edje/src/lib/edje_private.h | 7 +- legacy/edje/src/lib/edje_util.c | 18 ++++ 6 files changed, 148 insertions(+), 44 deletions(-) diff --git a/legacy/edje/src/bin/edje_cc_handlers.c b/legacy/edje/src/bin/edje_cc_handlers.c index a88c1c1920..97a4731b39 100644 --- a/legacy/edje/src/bin/edje_cc_handlers.c +++ b/legacy/edje/src/bin/edje_cc_handlers.c @@ -104,6 +104,7 @@ static void st_collections_group_parts_part_source4(void); static void st_collections_group_parts_part_source5(void); static void st_collections_group_parts_part_source6(void); static void st_collections_group_parts_part_entry_mode(void); +static void st_collections_group_parts_part_select_mode(void); static void st_collections_group_parts_part_multiline(void); static void st_collections_group_parts_part_dragable_x(void); static void st_collections_group_parts_part_dragable_y(void); @@ -283,6 +284,7 @@ New_Statement_Handler statement_handlers[] = {"collections.group.parts.part.dragable.confine", st_collections_group_parts_part_dragable_confine}, {"collections.group.parts.part.dragable.events", st_collections_group_parts_part_dragable_events}, {"collections.group.parts.part.entry_mode", st_collections_group_parts_part_entry_mode}, + {"collections.group.parts.part.select_mode", st_collections_group_parts_part_select_mode}, {"collections.group.parts.part.multiline", st_collections_group_parts_part_multiline}, {"collections.group.parts.part.image", st_images_image}, /* dup */ {"collections.group.parts.part.images.image", st_images_image}, /* dup */ @@ -2117,6 +2119,37 @@ st_collections_group_parts_part_entry_mode(void) NULL); } +/** + @page edcref + @property + select_mode + @parameters + Sets the selection mode for a textblock part to one of: + @li DEFAULT + @li EXPLICIT + @effect + DEFAULT selection mode is what you would expect on any desktop. Press + mouse, drag and release to end. EXPLICIT mode requires the application + controlling the edje object has to explicitly begin and end selection + modes, and the selection itself is dragable at both ends. + @endproperty +*/ +static void +st_collections_group_parts_part_select_mode(void) +{ + Edje_Part_Collection *pc; + Edje_Part *ep; + + check_arg_count(1); + + pc = eina_list_data_get(eina_list_last(edje_collections)); + ep = eina_list_data_get(eina_list_last(pc->parts)); + ep->select_mode = parse_enum(0, + "DEFAULT", EDJE_ENTRY_SELECTION_MODE_DEFAULT, + "EXPLICIT", EDJE_ENTRY_SELECTION_MODE_EXPLICIT, + NULL); +} + /** @page edcref @property diff --git a/legacy/edje/src/lib/Edje.h b/legacy/edje/src/lib/Edje.h index 717cc02063..2ca4e061f7 100644 --- a/legacy/edje/src/lib/Edje.h +++ b/legacy/edje/src/lib/Edje.h @@ -255,6 +255,7 @@ extern "C" { EAPI const Eina_List *edje_object_part_text_anchor_list_get(const Evas_Object *obj, const char *part); EAPI const Eina_List *edje_object_part_text_anchor_geometry_get(const Evas_Object *obj, const char *part, const char *anchor); EAPI void edje_object_part_text_cursor_geometry_get(const Evas_Object *obj, const char *part, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h); + EAPI void edje_object_part_text_select_allow_set(const Evas_Object *obj, const char *part, Evas_Bool allow); EAPI void edje_object_part_swallow (Evas_Object *obj, const char *part, Evas_Object *obj_swallow); EAPI void edje_object_part_unswallow (Evas_Object *obj, Evas_Object *obj_swallow); diff --git a/legacy/edje/src/lib/edje_data.c b/legacy/edje/src/lib/edje_data.c index 760cc63130..63ccb51390 100644 --- a/legacy/edje/src/lib/edje_data.c +++ b/legacy/edje/src/lib/edje_data.c @@ -434,6 +434,7 @@ _edje_edd_setup(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.counfine_id", dragable.confine_id, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.events_id", dragable.events_id, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "entry_mode", entry_mode, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "select_mode", select_mode, EET_T_UCHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "multiline", multiline, EET_T_UCHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "source", source, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "source2", source2, EET_T_STRING); diff --git a/legacy/edje/src/lib/edje_entry.c b/legacy/edje/src/lib/edje_entry.c index 9514d75634..64c1741644 100644 --- a/legacy/edje/src/lib/edje_entry.c +++ b/legacy/edje/src/lib/edje_entry.c @@ -45,6 +45,7 @@ struct _Entry char *selection; Evas_Bool selecting : 1; Evas_Bool have_selection : 1; + Evas_Bool select_allow : 1; }; struct _Sel @@ -1053,6 +1054,7 @@ _edje_part_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info Evas_Coord x, y, w, h; Evas_Bool multiline; Evas_Textblock_Cursor *tc; + Evas_Bool dosel = 0; if (!rp) return; en = rp->entry_data; if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) || @@ -1064,8 +1066,17 @@ _edje_part_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info return; } if (ev->button != 1) return; - // double click -> select word - // triple click -> select line + if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT) + dosel = 1; + else if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) + { + if (en->select_allow) dosel = 1; + } + if (dosel) + { + // double click -> select word + // triple click -> select line + } tc = evas_object_textblock_cursor_new(rp->object); evas_textblock_cursor_copy(en->cursor, tc); multiline = rp->part->multiline; @@ -1074,10 +1085,10 @@ _edje_part_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info en->cy = ev->canvas.y - y; if (!evas_textblock_cursor_char_coord_set(en->cursor, en->cx, en->cy)) { - Evas_Coord lx, ly, lw, lh; + Evas_Coord lx, ly, lw, lh; int line; - - line = evas_textblock_cursor_line_coord_set(en->cursor, en->cy); + + line = evas_textblock_cursor_line_coord_set(en->cursor, en->cy); if (line == -1) _curs_end(en->cursor, rp->object, en); else @@ -1089,9 +1100,20 @@ _edje_part_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info _curs_lin_end(en->cursor, rp->object, en); } } - en->selecting = 1; - _sel_clear(en->cursor, rp->object, en); - _sel_start(en->cursor, rp->object, en); + if (dosel) + { + if ((en->have_selection) && + (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT)) + { + printf("have selection.. do nothing\n"); + } + else + { + en->selecting = 1; + _sel_clear(en->cursor, rp->object, en); + _sel_start(en->cursor, rp->object, en); + } + } if (evas_textblock_cursor_compare(tc, en->cursor)) _edje_emit(rp->edje, "cursor,changed", rp->part->name); evas_textblock_cursor_free(tc); @@ -1107,6 +1129,7 @@ _edje_part_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) Evas_Coord x, y, w, h; Evas_Bool multiline; Evas_Textblock_Cursor *tc; + Evas_Bool dosel = 0; if (ev->button != 1) return; if (!rp) return; en = rp->entry_data; @@ -1121,16 +1144,22 @@ _edje_part_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) en->cy = ev->canvas.y - y; if (!evas_textblock_cursor_char_coord_set(en->cursor, en->cx, en->cy)) { - Evas_Coord lx, ly, lw, lh; - - evas_textblock_cursor_line_coord_set(en->cursor, en->cy); - evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh); - if (en->cx <= lx) - _curs_lin_start(en->cursor, rp->object, en); - else - _curs_lin_end(en->cursor, rp->object, en); + Evas_Coord lx, ly, lw, lh; + + evas_textblock_cursor_line_coord_set(en->cursor, en->cy); + evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh); + if (en->cx <= lx) + _curs_lin_start(en->cursor, rp->object, en); + else + _curs_lin_end(en->cursor, rp->object, en); } - evas_textblock_cursor_copy(en->cursor, en->sel_end); + if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) + { + if (en->select_allow) + evas_textblock_cursor_copy(en->cursor, en->sel_end); + } + else + evas_textblock_cursor_copy(en->cursor, en->sel_end); en->selecting = 0; if (evas_textblock_cursor_compare(tc, en->cursor)) _edje_emit(rp->edje, "cursor,changed", rp->part->name); @@ -1146,39 +1175,49 @@ _edje_part_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info Entry *en; Evas_Coord x, y, w, h; Evas_Textblock_Cursor *tc; - if (!rp) return; Evas_Bool multiline; + if (!rp) return; en = rp->entry_data; if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) || (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE)) return; - tc = evas_object_textblock_cursor_new(rp->object); - evas_textblock_cursor_copy(en->cursor, tc); - multiline = rp->part->multiline; - if (!en->selecting) return; - evas_object_geometry_get(rp->object, &x, &y, &w, &h); - en->cx = ev->cur.canvas.x - x; - en->cy = ev->cur.canvas.y - y; - if (!evas_textblock_cursor_char_coord_set(en->cursor, en->cx, en->cy)) + if (en->selecting) { - Evas_Coord lx, ly, lw, lh; - - evas_textblock_cursor_line_coord_set(en->cursor, en->cy); - evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh); - if (en->cx <= lx) - _curs_lin_start(en->cursor, rp->object, en); - else - _curs_lin_end(en->cursor, rp->object, en); + tc = evas_object_textblock_cursor_new(rp->object); + evas_textblock_cursor_copy(en->cursor, tc); + multiline = rp->part->multiline; + evas_object_geometry_get(rp->object, &x, &y, &w, &h); + en->cx = ev->cur.canvas.x - x; + en->cy = ev->cur.canvas.y - y; + if (!evas_textblock_cursor_char_coord_set(en->cursor, en->cx, en->cy)) + { + Evas_Coord lx, ly, lw, lh; + + evas_textblock_cursor_line_coord_set(en->cursor, en->cy); + evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh); + if (en->cx <= lx) + _curs_lin_start(en->cursor, rp->object, en); + else + _curs_lin_end(en->cursor, rp->object, en); + } + if ((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) && + (en->select_allow)) + { + _sel_extend(en->cursor, rp->object, en); + } + else + { + _sel_extend(en->cursor, rp->object, en); + } + if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) != 0) + _sel_enable(en->cursor, rp->object, en); + if (en->have_selection) + _sel_update(en->cursor, rp->object, en); + if (evas_textblock_cursor_compare(tc, en->cursor)) + _edje_emit(rp->edje, "cursor,changed", rp->part->name); + evas_textblock_cursor_free(tc); + _edje_entry_real_part_configure(rp); } - _sel_extend(en->cursor, rp->object, en); - if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) != 0) - _sel_enable(en->cursor, rp->object, en); - if (en->have_selection) - _sel_update(en->cursor, rp->object, en); - if (evas_textblock_cursor_compare(tc, en->cursor)) - _edje_emit(rp->edje, "cursor,changed", rp->part->name); - evas_textblock_cursor_free(tc); - _edje_entry_real_part_configure(rp); } /***************************************************************/ @@ -1436,3 +1475,10 @@ _edje_entry_cursor_geometry_get(Edje_Real_Part *rp, Evas_Coord *cx, Evas_Coord * if (cw) *cw = ww; if (ch) *ch = hh; } + +void +_edje_entry_select_allow_set(Edje_Real_Part *rp, Evas_Bool allow) +{ + Entry *en = rp->entry_data; + en->select_allow = allow; +} diff --git a/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index abc31a9af9..389341afa1 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/src/lib/edje_private.h @@ -235,6 +235,9 @@ typedef struct _Edje_Patterns Edje_Patterns; #define EDJE_ENTRY_EDIT_MODE_EDITABLE 2 #define EDJE_ENTRY_EDIT_MODE_PASSWORD 3 +#define EDJE_ENTRY_SELECTION_MODE_DEFAULT 0 +#define EDJE_ENTRY_SELECTION_MODE_EXPLICIT 1 + #define EDJE_PART_PATH_SEPARATOR ':' #define EDJE_PART_PATH_SEPARATOR_STRING ":" /*----------*/ @@ -483,6 +486,7 @@ struct _Edje_Part unsigned char use_alternate_font_metrics; unsigned char pointer_mode; unsigned char entry_mode; + unsigned char select_mode; unsigned char multiline; }; @@ -1302,5 +1306,6 @@ void _edje_entry_select_all(Edje_Real_Part *rp); const Eina_List *_edje_entry_anchor_geometry_get(Edje_Real_Part *rp, const char *anchor); const Eina_List *_edje_entry_anchors_list(Edje_Real_Part *rp); void _edje_entry_cursor_geometry_get(Edje_Real_Part *rp, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch); - +void _edje_entry_select_allow_set(Edje_Real_Part *rp, Evas_Bool allow); + #endif diff --git a/legacy/edje/src/lib/edje_util.c b/legacy/edje/src/lib/edje_util.c index 85ea21d05d..8de42de4a6 100644 --- a/legacy/edje/src/lib/edje_util.c +++ b/legacy/edje/src/lib/edje_util.c @@ -1101,6 +1101,24 @@ edje_object_part_text_cursor_geometry_get(const Evas_Object *obj, const char *pa return; } +/** XX + * @param obj A valid Evas_Object handle + * @param part The part name + */ +EAPI void +edje_object_part_text_select_allow_set(const Evas_Object *obj, const char *part, Evas_Bool allow) +{ + Edje *ed; + Edje_Real_Part *rp; + + ed = _edje_fetch(obj); + if ((!ed) || (!part)) return; + rp = _edje_real_part_recursive_get(ed, (char *)part); + if (!rp) return; + if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE) + _edje_entry_select_allow_set(rp, allow); +} + /** Swallows an object into the edje * @param obj A valid Evas_Object handle * @param part The part name