summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Hirt <hirt.danny@gmail.com>2017-09-07 13:47:35 +0300
committerDaniel Hirt <hirt.danny@gmail.com>2017-09-10 20:08:42 +0300
commitf03cb8bfd2d7a05af32c6fa9e7771a9a37fe277b (patch)
tree3ab191a252da1c3bdb4c616b22a3ece678b7320f
parentbc0a84496f0f3773888a29d5445272b683483a32 (diff)
downloadefl-devs/herdsman/text_async.tar.gz
Ui text: use async layoutdevs/herdsman/text_async
Adds "Efl.Ui.Text_Async" object. This new widget uses the "async_layout" functionality of the underlying Efl.Canvas.Text_Async object. Since this object is attached (composition), the two objects negotiate over the operations on the object, so that operations that may get "rejected" (due to the text object being busy with asynchronous layout work) could be deferred by this widget to be later applied when the layout is complete. Currently, if "editable" mode is enabled, there is no asynchronous layout, as interactive operations (e.g. typing) should get processed immediately. Thus, only "non-editable" instructs the text object to do asynchronous layout. elementary_test "efl ui text" was modified to use this new widget. @feature
-rw-r--r--src/Makefile_Elementary.am1
-rw-r--r--src/bin/elementary/test_efl_ui_text.c20
-rw-r--r--src/lib/elementary/Elementary.h1
-rw-r--r--src/lib/elementary/efl_ui_internal_text_interactive.eo2
-rw-r--r--src/lib/elementary/efl_ui_text.c201
-rw-r--r--src/lib/elementary/efl_ui_text_async.eo8
6 files changed, 184 insertions, 49 deletions
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index ad50ab466b..8684aa343e 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -123,6 +123,7 @@ elm_public_eolian_files = \
lib/elementary/efl_ui_text_interactive.eo \
lib/elementary/efl_ui_text.eo \
lib/elementary/efl_ui_text_editable.eo \
+ lib/elementary/efl_ui_text_async.eo \
lib/elementary/efl_config_global.eo \
lib/elementary/efl_ui_clock.eo \
lib/elementary/efl_ui_cursor.eo \
diff --git a/src/bin/elementary/test_efl_ui_text.c b/src/bin/elementary/test_efl_ui_text.c
index 862c832e16..fdc24ebeb5 100644
--- a/src/bin/elementary/test_efl_ui_text.c
+++ b/src/bin/elementary/test_efl_ui_text.c
@@ -98,6 +98,12 @@ typedef struct
} Test_Data;
static void
+my_efl_ui_text_bt_1(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ efl_ui_text_interactive_editable_set(data, !efl_ui_text_interactive_editable_get(data));
+}
+
+static void
my_efl_ui_text_bt_3(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Efl_Text_Cursor_Cursor *sel_start, *sel_end;
@@ -168,8 +174,9 @@ test_efl_ui_text(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
elm_win_resize_object_add(win, bx);
evas_object_show(bx);
- en = efl_add(EFL_UI_TEXT_CLASS, win,
- efl_text_multiline_set(efl_added, EINA_TRUE));
+ en = efl_add(EFL_UI_TEXT_ASYNC_CLASS, win);
+
+ efl_text_multiline_set(en, EINA_TRUE);
printf("Added Efl.Ui.Text object\n");
efl_key_data_set(en, "wrap_idx", 0);
@@ -207,6 +214,15 @@ test_efl_ui_text(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL);
bt = elm_button_add(win);
+ elm_object_text_set(bt, "Edit");
+ evas_object_smart_callback_add(bt, "clicked", my_efl_ui_text_bt_1, en);
+ evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+ elm_box_pack_end(bx2, bt);
+ elm_object_focus_allow_set(bt, EINA_FALSE);
+ evas_object_show(bt);
+
+ bt = elm_button_add(win);
elm_object_text_set(bt, "Sel");
evas_object_smart_callback_add(bt, "clicked", my_efl_ui_text_bt_3, en);
evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index f73df08558..b4abf3899a 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -276,6 +276,7 @@ EAPI extern Elm_Version *elm_version;
# include <efl_ui_text_interactive.eo.h>
# include <efl_ui_text.eo.h>
# include <efl_ui_text_editable.eo.h>
+# include <efl_ui_text_async.eo.h>
# include <efl_ui_clock.eo.h>
# include <efl_ui_image_factory.eo.h>
#endif
diff --git a/src/lib/elementary/efl_ui_internal_text_interactive.eo b/src/lib/elementary/efl_ui_internal_text_interactive.eo
index 034576f019..71add674c0 100644
--- a/src/lib/elementary/efl_ui_internal_text_interactive.eo
+++ b/src/lib/elementary/efl_ui_internal_text_interactive.eo
@@ -1,4 +1,4 @@
-class Efl.Ui.Internal.Text.Interactive (Efl.Canvas.Text, Efl.Ui.Text.Interactive)
+class Efl.Ui.Internal.Text.Interactive (Efl.Canvas.Text_Async, Efl.Ui.Text.Interactive)
{
[[An internal object that is in charge of the interactive aspect of the text widget
diff --git a/src/lib/elementary/efl_ui_text.c b/src/lib/elementary/efl_ui_text.c
index fccb5c877c..f66779f667 100644
--- a/src/lib/elementary/efl_ui_text.c
+++ b/src/lib/elementary/efl_ui_text.c
@@ -92,6 +92,11 @@ struct _Efl_Ui_Text_Data
Elm_Cnp_Mode cnp_mode;
Elm_Sel_Format drop_format;
+ struct {
+ char *text;
+ Eina_Bool enabled;
+ } async;
+
Eina_Bool input_panel_return_key_disabled : 1;
Eina_Bool drag_selection_asked : 1;
Eina_Bool sel_handler_disabled : 1;
@@ -127,7 +132,7 @@ struct _Efl_Ui_Text_Data
Eina_Bool scroll : 1;
Eina_Bool input_panel_show_on_demand : 1;
Eina_Bool anchors_updated : 1;
- Eina_Bool test_bit : 1;
+ Eina_Bool async_busy : 1;
};
struct _Anchor
@@ -916,7 +921,7 @@ _efl_ui_text_elm_widget_theme_apply(Eo *obj, Efl_Ui_Text_Data *sd)
theme_apply = elm_obj_widget_theme_apply(efl_cast(obj, ELM_WIDGET_CLASS));
if (!theme_apply) return EFL_UI_THEME_APPLY_FAILED;
- evas_event_freeze(evas_object_evas_get(obj));
+ efl_event_freeze(obj);
edje_object_mirrored_set
(wd->resize_obj, efl_ui_mirrored_get(obj));
@@ -1017,12 +1022,10 @@ _efl_ui_text_elm_widget_theme_apply(Eo *obj, Efl_Ui_Text_Data *sd)
}
sd->changed = EINA_TRUE;
- elm_layout_sizing_eval(obj);
sd->has_text = !sd->has_text;
_efl_ui_text_guide_update(obj, !sd->has_text);
- evas_event_thaw(evas_object_evas_get(obj));
- evas_event_thaw_eval(evas_object_evas_get(obj));
+ efl_event_thaw(obj);
efl_event_callback_legacy_call(obj, EFL_UI_LAYOUT_EVENT_THEME_CHANGED, NULL);
@@ -1067,38 +1070,23 @@ _cursor_geometry_recalc(Evas_Object *obj)
elm_widget_show_region_set(obj, sr, EINA_FALSE);
}
-EOLIAN static void
-_efl_ui_text_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Text_Data *sd)
+static void
+_layout_text_sizing_eval(Eo *obj, Evas_Coord tw, Evas_Coord th)
{
- Evas_Coord minw, minh, resw, resh;
- Evas_Coord fw, fh;
Eo *sw;
- Eina_Bool wrap;
+ Evas_Coord minw, minh;
- evas_object_geometry_get(obj, NULL, NULL, &resw, &resh);
-
- sw = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
- if (!sw) return;
-
- wrap = efl_text_wrap_get(sw);
-
- if (!sd->changed && (resw == sd->ent_w) && (resh == sd->ent_h)) return;
-
- sd->changed = EINA_FALSE;
- sd->ent_w = resw;
- sd->ent_h = resh;
+ efl_event_freeze(obj);
+ EFL_UI_TEXT_DATA_GET(obj, sd);
- evas_event_freeze(evas_object_evas_get(obj));
+ sw = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
if (sd->scroll)
{
Evas_Coord vw, vh;
- Evas_Coord tw, th;
+
elm_interface_scrollable_content_viewport_geometry_get(obj, NULL, NULL, &vw, &vh);
- efl_gfx_size_set(sd->entry_edje, vw, vh);
- efl_gfx_size_get(sw, &tw, &th);
- efl_canvas_text_size_formatted_get(sw, &fw, &fh);
- evas_object_size_hint_min_set(sw, fw, fh);
+ evas_object_size_hint_min_set(sw, tw, th);
edje_object_size_min_calc(sd->entry_edje, &minw, &minh);
evas_object_size_hint_min_set(sw, -1, -1);
@@ -1112,8 +1100,10 @@ _efl_ui_text_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Text_Data *sd)
}
else
{
- efl_canvas_text_size_formatted_get(sw, &fw, &fh);
- evas_object_size_hint_min_set(sw, fw, fh);
+ Eina_Bool wrap;
+
+ wrap = efl_text_wrap_get(sw);
+ evas_object_size_hint_min_set(sw, tw, th);
edje_object_size_min_calc(sd->entry_edje, &minw, &minh);
evas_object_size_hint_min_set(sw, -1, -1);
if (wrap == EFL_TEXT_FORMAT_WRAP_NONE)
@@ -1121,13 +1111,57 @@ _efl_ui_text_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Text_Data *sd)
evas_object_size_hint_min_set(obj, minw, minh);
}
}
- evas_event_thaw(evas_object_evas_get(obj));
- evas_event_thaw_eval(evas_object_evas_get(obj));
+ efl_event_thaw(obj);
+ _decoration_defer_all(obj);
+}
- if (!sd->deferred_decoration_cursor)
+EOLIAN static void
+_efl_ui_text_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Text_Data *sd)
+{
+ Evas_Coord resw, resh;
+ Eo *sw;
+ Eina_Bool can_async;
+
+ evas_object_geometry_get(obj, NULL, NULL, &resw, &resh);
+
+ sw = edje_object_part_swallow_get(sd->entry_edje, "elm.text");
+ if (!sw) return;
+
+ if (!sd->changed && (resw == sd->ent_w) && (resh == sd->ent_h)) return;
+
+ sd->changed = EINA_FALSE;
+ sd->ent_w = resw;
+ sd->ent_h = resh;
+
+
+ can_async = !sd->editable && sd->async.enabled;
+
+ efl_event_freeze(obj);
+ if (sd->scroll)
{
- sd->deferred_decoration_cursor = EINA_TRUE;
- _decoration_defer(obj);
+ Evas_Coord vw, vh;
+ elm_interface_scrollable_content_viewport_geometry_get(obj, NULL, NULL, &vw, &vh);
+ efl_gfx_size_set(sd->entry_edje, vw, vh);
+ }
+ if (can_async)
+ {
+ efl_event_thaw(obj);
+ sd->async_busy = EINA_TRUE;
+ efl_canvas_text_async_layout(sw);
+ }
+ else
+ {
+ /* Don't defer - complete the sizing evaluation now */
+ Evas_Coord fw, fh;
+ efl_canvas_text_size_formatted_get(obj, &fw, &fh);
+ efl_event_thaw(obj);
+ _layout_text_sizing_eval(obj, fw, fh);
+
+ if (!sd->deferred_decoration_cursor)
+ {
+ sd->deferred_decoration_cursor = EINA_TRUE;
+ _decoration_defer(obj);
+ }
}
}
@@ -2088,7 +2122,7 @@ _entry_changed_handle(void *data,
single_line = !efl_text_multiline_get(obj);
- evas_event_freeze(evas_object_evas_get(data));
+ efl_event_freeze(obj);
sd->changed = EINA_TRUE;
/* Reset the size hints which are no more relevant. Keep the
* height, this is a hack, but doesn't really matter cause we'll
@@ -2105,8 +2139,7 @@ _entry_changed_handle(void *data,
elm_layout_sizing_eval(data);
ELM_SAFE_FREE(sd->text, eina_stringshare_del);
ELM_SAFE_FREE(sd->delay_write, ecore_timer_del);
- evas_event_thaw(evas_object_evas_get(data));
- evas_event_thaw_eval(evas_object_evas_get(data));
+ efl_event_thaw(obj);
if ((sd->auto_save) && (sd->file))
sd->delay_write = ecore_timer_add(EFL_UI_TEXT_DELAY_WRITE_TIME,
_delay_write, data);
@@ -2952,6 +2985,37 @@ _end_handler_mouse_move_cb(void *data,
_magnifier_move(data);
}
+static void
+_on_layout_complete(void *data, const Efl_Event *event)
+{
+ EFL_UI_TEXT_DATA_GET(data, sd);
+ Efl_Canvas_Text_Async_Layout_Event_Info *ev = event->info;
+ _layout_text_sizing_eval(data, ev->w, ev->h);
+
+ if (sd->async.text)
+ {
+ efl_text_set(sd->text_obj, sd->async.text);
+ free(sd->async.text);
+ sd->async.text = NULL;
+ }
+}
+
+static void
+_on_text_set_reject(void *data, const Efl_Event *event)
+{
+ Efl_Canvas_Text_Async_Text_Set_Info *ev = event->info;
+ EFL_UI_TEXT_DATA_GET(data, sd);
+ if (sd->async_busy)
+ {
+ char *tmp = strdup(ev->text);
+ if (sd->async.text)
+ {
+ free(sd->async.text);
+ }
+ sd->async.text = tmp;
+ }
+}
+
EOLIAN static void
_efl_ui_text_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Text_Data *priv)
{
@@ -2962,8 +3026,18 @@ _efl_ui_text_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Text_Data *priv)
/* XXX: needs to be before efl_canvas_group_add, since the latter will
* trigger a layout_sizing_eval call and requires the canvas text object to
* be instantiated. */
- text_obj = efl_add(EFL_UI_INTERNAL_TEXT_INTERACTIVE_CLASS, obj);
+ if (priv->async.enabled)
+ {
+ text_obj = efl_add(EFL_UI_INTERNAL_TEXT_INTERACTIVE_CLASS, obj,
+ efl_canvas_text_async_set(efl_added, EINA_TRUE));
+ }
+ else
+ {
+ text_obj = efl_add(EFL_UI_INTERNAL_TEXT_INTERACTIVE_CLASS, obj);
+ }
+
efl_composite_attach(obj, text_obj);
+ priv->text_obj = text_obj;
// FIXME: use the theme, when a proper theming option is available
// (possibly, text_classes).
@@ -2974,7 +3048,6 @@ _efl_ui_text_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Text_Data *priv)
efl_canvas_group_add(efl_super(obj, MY_CLASS));
elm_widget_sub_object_parent_add(obj);
- priv->test_bit = EINA_TRUE;
priv->entry_edje = wd->resize_obj;
priv->cnp_mode = ELM_CNP_MODE_PLAINTEXT;
@@ -3012,6 +3085,16 @@ _efl_ui_text_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Text_Data *priv)
evas_object_event_callback_add(priv->entry_edje, EVAS_CALLBACK_MOVE,
_efl_ui_text_move_cb, obj);
+ /* Async layout */
+ if (priv->async.enabled)
+ {
+ efl_event_callback_add(text_obj,
+ EFL_CANVAS_TEXT_EVENT_ASYNC_LAYOUT_COMPLETE,
+ _on_layout_complete, obj);
+ efl_event_callback_add(text_obj,
+ EFL_CANVAS_TEXT_EVENT_ASYNC_TEXT_SET,
+ _on_text_set_reject, obj);
+ }
priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
evas_object_data_set(priv->hit_rect, "_elm_leaveme", obj);
@@ -3106,7 +3189,7 @@ _efl_ui_text_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Text_Data *priv)
edje_object_part_text_select_allow_set
(priv->entry_edje, "elm.text", EINA_TRUE);
- elm_layout_sizing_eval(obj);
+ //elm_layout_sizing_eval(obj);
efl_ui_text_input_panel_layout_set(obj, ELM_INPUT_PANEL_LAYOUT_NORMAL);
efl_ui_text_input_panel_enabled_set(obj, EINA_TRUE);
@@ -3189,7 +3272,7 @@ _efl_ui_text_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Text_Data *sd)
_efl_ui_text_anchor_hover_end(obj, sd);
_efl_ui_text_anchor_hover_parent_set(obj, sd, NULL);
- evas_event_freeze(evas_object_evas_get(obj));
+ efl_event_freeze(obj);
eina_stringshare_del(sd->file);
@@ -3232,8 +3315,7 @@ _efl_ui_text_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Text_Data *sd)
free(sd->input_panel_imdata);
eina_stringshare_del(sd->anchor_hover.hover_style);
- evas_event_thaw(evas_object_evas_get(obj));
- evas_event_thaw_eval(evas_object_evas_get(obj));
+ efl_event_thaw(obj);
if (sd->start_handler)
{
@@ -3333,7 +3415,7 @@ _cb_deleted(void *data EINA_UNUSED, const Efl_Event *ev)
}
EOLIAN static Eo *
-_efl_ui_text_efl_object_constructor(Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED)
+_efl_ui_text_efl_object_constructor(Eo *obj, Efl_Ui_Text_Data *pd EINA_UNUSED)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
@@ -5358,13 +5440,40 @@ ELM_LAYOUT_CONTENT_ALIASES_IMPLEMENT(MY_CLASS_PFX)
#define EFL_UI_TEXT_EXTRA_OPS \
EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_text), \
ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_text), \
- ELM_LAYOUT_CONTENT_ALIASES_OPS(MY_CLASS_PFX)
+ ELM_LAYOUT_CONTENT_ALIASES_OPS(MY_CLASS_PFX), \
#include "efl_ui_text.eo.c"
+EOLIAN static Eo *
+_efl_ui_text_async_efl_object_constructor(Eo *obj, void *_pd EINA_UNUSED)
+{
+ obj = efl_constructor(efl_super(obj, EFL_UI_TEXT_ASYNC_CLASS));
+ return obj;
+}
+
+EOLIAN static void
+_efl_ui_text_async_efl_canvas_group_group_add(Eo *obj, void *_pd EINA_UNUSED)
+{
+ EFL_UI_TEXT_DATA_GET(obj, sd);
+ sd->async.enabled = EINA_TRUE;
+ efl_canvas_group_add(efl_super(obj, EFL_UI_TEXT_ASYNC_CLASS));
+}
+
+EOLIAN static void
+_efl_ui_text_async_efl_canvas_group_group_del(Eo *obj, void *_pd EINA_UNUSED)
+{
+ efl_canvas_group_del(efl_super(obj, EFL_UI_TEXT_ASYNC_CLASS));
+}
+
+#define EFL_UI_TEXT_ASYNC_EXTRA_OPS \
+ EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_text_async)
+
+#include "efl_ui_text_async.eo.c"
+
#undef MY_CLASS
#define MY_CLASS EFL_UI_TEXT_EDITABLE_CLASS
+
EOLIAN static Eo *
_efl_ui_text_editable_efl_object_constructor(Eo *obj, void *_pd EINA_UNUSED)
{
diff --git a/src/lib/elementary/efl_ui_text_async.eo b/src/lib/elementary/efl_ui_text_async.eo
new file mode 100644
index 0000000000..4c3c32bd50
--- /dev/null
+++ b/src/lib/elementary/efl_ui_text_async.eo
@@ -0,0 +1,8 @@
+class Efl.Ui.Text_Async (Efl.Ui.Text)
+{
+ [[Efl UI text async class]]
+ data: null;
+ implements {
+ Efl.Object.constructor;
+ }
+}