diff options
author | Daniel Hirt <hirt.danny@gmail.com> | 2018-06-05 21:02:43 +0300 |
---|---|---|
committer | Daniel Hirt <hirt.danny@gmail.com> | 2018-06-20 15:18:00 +0300 |
commit | 88e16b338823dcfbc21cbe88056dc31895036bd1 (patch) | |
tree | 653cb584dc730655832858f52387d5513c291913 | |
parent | 151b7616f671edc25f2a88fa1d728ea4ac71964b (diff) | |
download | efl-88e16b338823dcfbc21cbe88056dc31895036bd1.tar.gz |
Canvas layout: support more Efl.Text.* with efl_partdevs/herdsman/edje_part_next
This adds many Efl.Text.* that are useful for manipulating the
underlying TEXTBLOCK object's propeties using efl_part.
This has been implemented as part of the "user-defined" properties of
the layout part, so that the changes on the part persist across load of
different groups.
Note that text styles have precedence over the TEXTBLOCK (Canvas.Text)
object's properties. if an edc provides a style, the properties it
manipulates as part of the "base:" string would not be affected by this
API.
In general, this helps reducing the amount of styles for objects (or
modes of the same objects) that share the same setup, but are different
in some properties (e.g. ellipsis, wrap etc).
@feature
Canvas layout: add text part "expand" property
This adds "expansion modes", which are essentially the same as min/max
hints in the edje part's 'description.text' fields.
The user can then customize his widget to different modes without being
forced to create a new edje group in the theme.
Note that there is an added check in case one of the min/max text flags
are provided from the theme. In such case, all flags from this new API
will be ignored.
This fortifies misuse where the flags are set both in theme and the API.
@feature
-rw-r--r-- | src/Makefile_Edje.am | 3 | ||||
-rw-r--r-- | src/examples/elementary/Makefile.am | 6 | ||||
-rw-r--r-- | src/examples/elementary/efl_canvas_layout_text.c | 156 | ||||
-rw-r--r-- | src/examples/elementary/efl_canvas_layout_text.edc | 48 | ||||
-rw-r--r-- | src/lib/edje/edje_load.c | 24 | ||||
-rw-r--r-- | src/lib/edje/edje_part_text.c | 528 | ||||
-rw-r--r-- | src/lib/edje/edje_private.h | 70 | ||||
-rw-r--r-- | src/lib/edje/edje_textblock.c | 83 | ||||
-rw-r--r-- | src/lib/edje/edje_util.c | 75 | ||||
-rw-r--r-- | src/lib/edje/efl_canvas_layout_part_text.eo | 50 | ||||
-rw-r--r-- | src/lib/efl/interfaces/efl_text_style.eo | 9 | ||||
-rw-r--r-- | src/lib/evas/canvas/efl_canvas_text.eo | 1 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_object_textblock.c | 30 | ||||
-rw-r--r-- | src/tests/edje/data/test_text.edc | 41 | ||||
-rw-r--r-- | src/tests/edje/edje_suite.c | 1 | ||||
-rw-r--r-- | src/tests/edje/edje_suite.h | 1 | ||||
-rw-r--r-- | src/tests/edje/edje_test_text.c | 239 |
17 files changed, 1312 insertions, 53 deletions
diff --git a/src/Makefile_Edje.am b/src/Makefile_Edje.am index 87d67b5e89..051aeca202 100644 --- a/src/Makefile_Edje.am +++ b/src/Makefile_Edje.am @@ -300,6 +300,7 @@ tests/edje/data/test_messages.edc \ tests/edje/data/test_signals.edc \ tests/edje/data/test_signal_callback_del_full.edc \ tests/edje/data/test_text_cursor.edc \ +tests/edje/data/test_text.edc \ tests/edje/data/filter.lua @@ -318,6 +319,7 @@ TESTS += tests/edje/edje_suite tests_edje_edje_suite_SOURCES = \ tests/edje/edje_suite.c \ tests/edje/edje_test_edje.c \ +tests/edje/edje_test_text.c \ tests/edje/edje_suite.h tests/edje/data/%.edj: tests/edje/data/%.edc bin/edje/edje_cc${EXEEXT} @@ -344,6 +346,7 @@ EDJE_TEST_FILES = tests/edje/data/test_layout.edj \ tests/edje/data/test_signals.edj \ tests/edje/data/test_signal_callback_del_full.edj \ tests/edje/data/test_text_cursor.edj \ + tests/edje/data/test_text.edj \ $(NULL) CLEANFILES += $(EDJE_TEST_FILES) diff --git a/src/examples/elementary/Makefile.am b/src/examples/elementary/Makefile.am index 546c270a50..85d9e01aff 100644 --- a/src/examples/elementary/Makefile.am +++ b/src/examples/elementary/Makefile.am @@ -181,7 +181,8 @@ efl_thread_6.c \ efl_ui_list_example_1.c \ efl_ui_view_list_example_1.c \ efl_ui_view_list_example_2.c \ -efl_ui_view_list_example_3.c +efl_ui_view_list_example_3.c \ +efl_canvas_layout_text.c SRCS += \ bg_cxx_example_01.cc \ @@ -398,7 +399,8 @@ efl_thread_6 \ efl_ui_list_example_1 \ efl_ui_view_list_example_1 \ efl_ui_view_list_example_2 \ -efl_ui_view_list_example_3 +efl_ui_view_list_example_3 \ +efl_canvas_layout_text #benchmark3d #sphere-hunter diff --git a/src/examples/elementary/efl_canvas_layout_text.c b/src/examples/elementary/efl_canvas_layout_text.c new file mode 100644 index 0000000000..8dea0f8b87 --- /dev/null +++ b/src/examples/elementary/efl_canvas_layout_text.c @@ -0,0 +1,156 @@ +// gcc -o efl_canvas_layout_text efl_canvas_layout_text.c `pkg-config --cflags --libs elementary` +// edje_cc efl_canvas_layout.edc +// ./efl_canvas_layout_text + +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#else +# define EFL_BETA_API_SUPPORT 1 +# define EFL_EO_API_SUPPORT 1 +#endif + +#include <Efl.h> +#include <Elementary.h> +#include <string.h> + +static void +_on_win_delete(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED) +{ + efl_exit(0); +} + +static const char* groups[] = { "test", "test2" }; +static size_t group_itr = 0; + +static double ellipsis[] = { -1.0, 1.0 }; +static size_t ellipsis_itr = 0; + +static struct +{ + Efl_Text_Format_Wrap wrap; + const char *desc; +} wraps[] = +{ + { EFL_TEXT_FORMAT_WRAP_NONE, "none" }, + { EFL_TEXT_FORMAT_WRAP_WORD, "word" }, + { EFL_TEXT_FORMAT_WRAP_CHAR, "char" }, + { EFL_TEXT_FORMAT_WRAP_MIXED, "mixed" } +}; + +static struct +{ + Efl_Text_Format_Wrap wrap; + const char *desc; +} group[] = +{ + { EFL_TEXT_FORMAT_WRAP_NONE, "none" }, + { EFL_TEXT_FORMAT_WRAP_WORD, "word" }, + { EFL_TEXT_FORMAT_WRAP_CHAR, "char" }, + { EFL_TEXT_FORMAT_WRAP_MIXED, "mixed" } +}; +static struct +{ + Efl_Canvas_Layout_Part_Text_Expand expand; + const char *desc; +} expands[] = +{ + { EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_NONE, "none" }, + { EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MIN_X, "min_x" }, + { EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MIN_Y, "min_y" }, + { EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MAX_X, "max_x" }, + { EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MAX_Y, "max_y" }, + { EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MIN_X | EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MIN_Y , "min_x AND min_y"} +}; + +static size_t wrap_itr = 0; +static size_t expand_itr = 0; + +static void +_help(void) +{ + printf("Press 'w' to cycle wrap modes.\n" + "Press 's' to cycle expand hints and print min_size result.\n" + "Press 'h' to display this help.\n"); +} + +static const char *edjefile = "efl_canvas_layout_text.edj"; + +static void +_on_key_down(void *data, const Efl_Event *event) +{ + Efl_Input_Key *ev = event->info; + Eo *layout = data; + const char *key = efl_input_key_name_get(ev); + + if (!strcmp(key, "g")) + { + // edje group + group_itr = (group_itr + 1) % 2; + efl_file_set(layout, edjefile, groups[group_itr]); + printf("Changed layout group to: %s\n", groups[group_itr]); + } + else if (!strcmp(key, "w")) + { + // wrap mode + wrap_itr = (wrap_itr + 1) % 4; + efl_text_wrap_set(efl_part(layout, "text"), wraps[wrap_itr].wrap); + printf("Changed wrap to %s\n", wraps[wrap_itr].desc); + } + else if (!strcmp(key, "e")) + { + // ellipsis value + ellipsis_itr = (ellipsis_itr + 1) % 2; + efl_text_ellipsis_set(efl_part(layout, "text"), ellipsis[ellipsis_itr]); + printf("Changed ellipsis to %f\n", ellipsis[ellipsis_itr]); + } + else if (!strcmp(key, "s")) + { + Eina_Size2D sz; + // expand mode + expand_itr = (expand_itr + 1) % 6; + efl_canvas_layout_part_text_expand_set(efl_part(layout, "text"), + expands[expand_itr].expand); + printf("Changed expand mode to: %s\n", expands[expand_itr].desc); + + sz = efl_layout_calc_size_min(layout, EINA_SIZE2D(10, 10)); + printf("new expand_min: %dx%d\n", sz.w, sz.h); + } + else if (!strcmp(key, "h")) + { + _help(); + } +} + +EAPI_MAIN void +efl_main(void *data EINA_UNUSED, + const Efl_Event *ev) +{ + + Eo *layout; + Eo *win; + + win = efl_add(EFL_UI_WIN_CLASS, NULL, + efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC), + efl_text_set(efl_added, "Efl Canvas_Layout"), + efl_ui_win_autodel_set(efl_added, EINA_TRUE), + efl_event_callback_add(efl_added, EFL_UI_WIN_EVENT_DELETE_REQUEST, _on_win_delete, NULL)); + + + layout = efl_add(EFL_CANVAS_LAYOUT_CLASS, win); + efl_file_set(layout, edjefile, groups[group_itr]); + + efl_content_set(win, layout); + efl_gfx_entity_size_set(win, EINA_SIZE2D(110, 100)); + + efl_text_markup_set(efl_part(layout, "text"), "This is an example text. This is a layout text part."); + efl_text_wrap_set(efl_part(layout, "text"), wraps[wrap_itr].wrap); + efl_text_normal_color_set(efl_part(layout, "text"), 255, 255, 0, 255); + efl_text_font_set(efl_part(layout, "text"), "Serif", 12); + + efl_canvas_layout_part_text_expand_set(efl_part(layout, "text"), + expands[expand_itr].expand); + + efl_event_callback_add(win, EFL_EVENT_KEY_DOWN, _on_key_down, layout); + +} +EFL_MAIN() diff --git a/src/examples/elementary/efl_canvas_layout_text.edc b/src/examples/elementary/efl_canvas_layout_text.edc new file mode 100644 index 0000000000..401ad0c255 --- /dev/null +++ b/src/examples/elementary/efl_canvas_layout_text.edc @@ -0,0 +1,48 @@ +efl_version: 1 21; +collections { + styles { + style { name: "tbstyle"; + base: ""; + } + } + group { name: "test"; + parts { + textblock { "text"; nomouse; + desc { "default"; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + text { + style: "tbstyle"; + font: FN; size: 10; + align: 0.5 0.5; + } + visible: 1; + } + } + } + } + group { name: "test2"; + parts { + rect { "rect"; nomouse; repeat; precise; + desc { "default"; + color: 255 0 0 255; + rel1.relative: 0.0 0.0; + rel2.relative: 0.5 1; + } + } + textblock { "text"; nomouse; + desc { "default"; + rel1.relative: 0.5 0.0; + rel2.relative: 1.0 1.0; + //fixed: 1 1; + text { + style: "tbstyle"; + font: FN; size: 10; + align: 0.5 0.5; + } + visible: 1; + } + } + } + } +} diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index c0d0ac25a3..94f7c2a67b 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -1644,6 +1644,25 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch } eina_stringshare_del(eud->u.string.text); break; + + case EDJE_USER_TEXT_STYLE: + { + Edje_Part_Text_Prop *prop; + EINA_LIST_FREE(eud->u.text_style.props, prop) + { + _canvas_layout_user_text_apply(eud, obj, + prop); + free(prop); + } + } + break; + case EDJE_USER_TEXT_EXPAND: + { + efl_canvas_layout_part_text_expand_set( + efl_part(obj, eud->part), + eud->u.text_expand.expand); + } + break; } if (eud) _edje_user_definition_remove(eud, child); } @@ -1839,10 +1858,15 @@ _edje_object_collect(Edje *ed) edje_object_part_unswallow(NULL, eud->u.swallow.child); break; + case EDJE_USER_TEXT_STYLE: + _canvas_layout_user_text_collect(ed, eud); + break; + case EDJE_USER_DRAG_STEP: case EDJE_USER_DRAG_PAGE: case EDJE_USER_DRAG_VALUE: case EDJE_USER_DRAG_SIZE: + case EDJE_USER_TEXT_EXPAND: break; } } diff --git a/src/lib/edje/edje_part_text.c b/src/lib/edje/edje_part_text.c index 6e8e231ae2..31678a3697 100644 --- a/src/lib/edje/edje_part_text.c +++ b/src/lib/edje/edje_part_text.c @@ -197,5 +197,533 @@ _efl_canvas_layout_part_text_efl_text_markup_cursor_markup_insert(Eo *obj, // FIXME: entry should report the length of inserted text (after filtering) } +/* More Efl.Text.* API (@since 1.22) */ + +EOLIAN static void +_efl_canvas_layout_part_text_efl_text_style_backing_type_set(Eo *obj, + void *_pd EINA_UNUSED, + Efl_Text_Style_Backing_Type type) +{ + Edje_User_Defined *eud; + + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; + + eud = _edje_user_text_style_definition_fetch(pd->ed, pd->part); + + eud->u.text_style.types |= EDJE_PART_TEXT_PROP_NONE; + efl_text_backing_type_set(pd->rp->object, type); +} + +EOLIAN static Efl_Text_Style_Backing_Type +_efl_canvas_layout_part_text_efl_text_style_backing_type_get(const Eo *obj, + void *_pd EINA_UNUSED) +{ + + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) + return EFL_TEXT_STYLE_BACKING_TYPE_DISABLED; + + return efl_text_backing_type_get(pd->rp->object); +} + +#define TEXT_COLOR_IMPL(x, X) \ +EOLIAN static void \ +_efl_canvas_layout_part_text_efl_text_style_ ##x ##_color_set(Eo *obj, \ + void *_pd EINA_UNUSED, \ + unsigned char r, unsigned char g, unsigned char b, unsigned char a) \ +{ \ + Edje_User_Defined *eud; \ + \ + PROXY_DATA_GET(obj, pd); \ + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; \ + \ + eud = _edje_user_text_style_definition_fetch(pd->ed, pd->part); \ + \ + eud->u.text_style.types |= EDJE_PART_TEXT_PROP_COLOR_ ##X; \ + efl_text_ ##x ##_color_set(pd->rp->object, r, g, b, a); \ +} \ +\ +EOLIAN static void \ +_efl_canvas_layout_part_text_efl_text_style_ ##x ##_color_get(const Eo *obj, \ + void *_pd EINA_UNUSED, \ + unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) \ +{ \ + PROXY_DATA_GET(obj, pd); \ + *r = *g = *b = *a = 0; \ + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; \ + efl_text_ ##x ##_color_get(pd->rp->object, r, g, b, a); \ +} + +TEXT_COLOR_IMPL(backing, BACKING) +TEXT_COLOR_IMPL(glow, GLOW) +TEXT_COLOR_IMPL(glow2, GLOW2) +TEXT_COLOR_IMPL(normal, NORMAL) +TEXT_COLOR_IMPL(outline, OUTLINE) +TEXT_COLOR_IMPL(shadow, SHADOW) +TEXT_COLOR_IMPL(strikethrough, STRIKETHROUGH) +TEXT_COLOR_IMPL(underline, UNDERLINE) +TEXT_COLOR_IMPL(underline2, UNDERLINE2) +TEXT_COLOR_IMPL(underline_dashed, UNDERLINE_DASHED) + +EOLIAN static void +_efl_canvas_layout_part_text_efl_text_style_effect_type_set(Eo *obj, + void *_pd EINA_UNUSED, + Efl_Text_Style_Effect_Type type) +{ + Edje_User_Defined *eud; + + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; + + eud = _edje_user_text_style_definition_fetch(pd->ed, pd->part); + + eud->u.text_style.types |= EDJE_PART_TEXT_PROP_EFFECT_TYPE; + efl_text_effect_type_set(pd->rp->object, type); +} + +EOLIAN static void +_efl_canvas_layout_part_text_efl_text_format_ellipsis_set(Eo *obj, + void *_pd EINA_UNUSED, double value) +{ + Edje_User_Defined *eud; + + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; + + eud = _edje_user_text_style_definition_fetch(pd->ed, pd->part); + + eud->u.text_style.types |= EDJE_PART_TEXT_PROP_ELLIPSIS; + efl_text_ellipsis_set(pd->rp->object, value); +} + +EOLIAN static double +_efl_canvas_layout_part_text_efl_text_format_ellipsis_get(const Eo *obj, + void *_pd EINA_UNUSED) +{ + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return 0.0; + + return efl_text_ellipsis_get(pd->rp->object); +} + +EOLIAN static void +_efl_canvas_layout_part_text_efl_text_font_font_set(Eo *obj, + void *_pd EINA_UNUSED, const char *font, Efl_Font_Size size) +{ + Edje_User_Defined *eud; + + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; + + + eud = _edje_user_text_style_definition_fetch(pd->ed, pd->part); + + eud->u.text_style.types |= EDJE_PART_TEXT_PROP_FONT; + efl_text_font_set(pd->rp->object, font, size); +} + +EOLIAN static void +_efl_canvas_layout_part_text_efl_text_font_font_get(const Eo *obj, + void *_pd EINA_UNUSED, const char **font, Efl_Font_Size *size) +{ + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; + + efl_text_font_get(pd->rp->object, font, size); +} + +EOLIAN static void +_efl_canvas_layout_part_text_efl_text_style_shadow_direction_set(Eo *obj, + void *_pd EINA_UNUSED, + Efl_Text_Style_Shadow_Direction type) +{ + Edje_User_Defined *eud; + + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; + + eud = _edje_user_text_style_definition_fetch(pd->ed, pd->part); + + eud->u.text_style.types |= EDJE_PART_TEXT_PROP_SHADOW_DIRECTION; + efl_text_shadow_direction_set(pd->rp->object, type); +} + +EOLIAN static void +_efl_canvas_layout_part_text_efl_text_style_strikethrough_type_set(Eo *obj, + void *_pd EINA_UNUSED, + Efl_Text_Style_Strikethrough_Type type) +{ + Edje_User_Defined *eud; + + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; + + eud = _edje_user_text_style_definition_fetch(pd->ed, pd->part); + + eud->u.text_style.types |= EDJE_PART_TEXT_PROP_STRIKETHROUGH_TYPE; + efl_text_strikethrough_type_set(pd->rp->object, type); +} + +EOLIAN static void +_efl_canvas_layout_part_text_efl_text_style_underline_type_set(Eo *obj, + void *_pd EINA_UNUSED, + Efl_Text_Style_Underline_Type type) +{ + Edje_User_Defined *eud; + + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; + + + eud = _edje_user_text_style_definition_fetch(pd->ed, pd->part); + + eud->u.text_style.types = EDJE_PART_TEXT_PROP_UNDERLINE_TYPE; + efl_text_underline_type_set(pd->rp->object, type); +} + +EOLIAN static void +_efl_canvas_layout_part_text_efl_text_style_underline_height_set(Eo *obj, + void *_pd EINA_UNUSED, + double value) +{ + Edje_User_Defined *eud; + + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; + + eud = _edje_user_text_style_definition_fetch(pd->ed, pd->part); + + eud->u.text_style.types |= EDJE_PART_TEXT_PROP_UNDERLINE_HEIGHT; + efl_text_underline_height_set(pd->rp->object, value); +} + +EOLIAN static void +_efl_canvas_layout_part_text_efl_text_style_underline_dashed_width_set(Eo *obj, + void *_pd EINA_UNUSED, + int value) +{ + Edje_User_Defined *eud; + + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; + + eud = _edje_user_text_style_definition_fetch(pd->ed, pd->part); + + eud->u.text_style.types |= EDJE_PART_TEXT_PROP_UNDERLINE_DASHED_WIDTH; + efl_text_underline_dashed_width_set(pd->rp->object, value); +} + +EOLIAN static void +_efl_canvas_layout_part_text_efl_text_style_underline_dashed_gap_set(Eo *obj, + void *_pd EINA_UNUSED, + int value) +{ + Edje_User_Defined *eud; + + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; + + eud = _edje_user_text_style_definition_fetch(pd->ed, pd->part); + + eud->u.text_style.types |= EDJE_PART_TEXT_PROP_UNDERLINE_DASHED_GAP; + efl_text_underline_dashed_gap_set(pd->rp->object, value); +} + +EOLIAN static void +_efl_canvas_layout_part_text_efl_text_format_wrap_set(Eo *obj, + void *_pd EINA_UNUSED, Efl_Text_Format_Wrap wrap) +{ + Edje_User_Defined *eud; + + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; + + eud = _edje_user_text_style_definition_fetch(pd->ed, pd->part); + + eud->u.text_style.types |= EDJE_PART_TEXT_PROP_WRAP; + efl_text_wrap_set(pd->rp->object, wrap); +} + +EOLIAN static Efl_Text_Format_Wrap +_efl_canvas_layout_part_text_efl_text_format_wrap_get(const Eo *obj, + void *_pd EINA_UNUSED) +{ + PROXY_DATA_GET(obj, pd); + + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) + return EFL_TEXT_FORMAT_WRAP_NONE; + + return efl_text_wrap_get(pd->rp->object); +} + +static Edje_Part_Text_Prop * +_prop_new(Eina_List **props, Edje_Part_Text_Prop_Type type) +{ + Edje_Part_Text_Prop *prop; + + prop = malloc(sizeof(*prop)); + prop->type = type; + + *props = eina_list_append(*props, prop); + + return prop; +} + +void +_canvas_layout_user_text_collect(Edje *ed, Edje_User_Defined *eud) +{ + Edje_Real_Part *rp; + Eina_List **props = &eud->u.text_style.props; + + rp = _edje_real_part_recursive_get(&ed, eud->part); + if (eud->u.text_style.types == EDJE_PART_TEXT_PROP_NONE) return; + + if (eud->u.text_style.types & EDJE_PART_TEXT_PROP_BACKING_TYPE) + { + Edje_Part_Text_Prop *prop; + + prop = _prop_new(props, EDJE_PART_TEXT_PROP_BACKING_TYPE); + prop->val.backing = efl_text_backing_type_get(rp->object); + } +#define STYLE_COLOR_COLLECT(x, X) \ + if (eud->u.text_style.types & EDJE_PART_TEXT_PROP_COLOR_ ##X) \ + { \ + Edje_Part_Text_Prop *prop; \ + prop = _prop_new(props, EDJE_PART_TEXT_PROP_COLOR_ ##X); \ + efl_text_ ##x ##_color_get(rp->object, \ + &prop->val.color.r, &prop->val.color.g, \ + &prop->val.color.b, &prop->val.color.a); \ + } \ + + STYLE_COLOR_COLLECT(backing, BACKING) + STYLE_COLOR_COLLECT(glow, GLOW) + STYLE_COLOR_COLLECT(glow2, GLOW2) + STYLE_COLOR_COLLECT(normal, NORMAL) + STYLE_COLOR_COLLECT(outline, OUTLINE) + STYLE_COLOR_COLLECT(shadow, SHADOW) + STYLE_COLOR_COLLECT(strikethrough, STRIKETHROUGH) + STYLE_COLOR_COLLECT(underline, UNDERLINE) + STYLE_COLOR_COLLECT(underline2, UNDERLINE2) + STYLE_COLOR_COLLECT(underline_dashed, UNDERLINE_DASHED) +#undef STYLE_COLOR_COLLECT + + if (eud->u.text_style.types & EDJE_PART_TEXT_PROP_EFFECT_TYPE) + { + Edje_Part_Text_Prop *prop; + + prop = _prop_new(props, EDJE_PART_TEXT_PROP_EFFECT_TYPE); + prop->val.effect = efl_text_effect_type_get(rp->object); + } + + if (eud->u.text_style.types & EDJE_PART_TEXT_PROP_ELLIPSIS) + { + Edje_Part_Text_Prop *prop; + + prop = _prop_new(props, EDJE_PART_TEXT_PROP_ELLIPSIS); + prop->val.nd = efl_text_ellipsis_get(rp->object); + } + + if (eud->u.text_style.types & EDJE_PART_TEXT_PROP_FONT) + { + Edje_Part_Text_Prop *prop; + + prop = _prop_new(props, EDJE_PART_TEXT_PROP_FONT); + efl_text_font_get(rp->object, &prop->val.font.font, + &prop->val.font.size); + } + + if (eud->u.text_style.types & EDJE_PART_TEXT_PROP_SHADOW_DIRECTION) + { + Edje_Part_Text_Prop *prop; + + prop = _prop_new(props, EDJE_PART_TEXT_PROP_SHADOW_DIRECTION); + prop->val.shadow = efl_text_shadow_direction_get(rp->object); + } + + if (eud->u.text_style.types & EDJE_PART_TEXT_PROP_STRIKETHROUGH_TYPE) + { + Edje_Part_Text_Prop *prop; + + prop = _prop_new(props, EDJE_PART_TEXT_PROP_STRIKETHROUGH_TYPE); + prop->val.strikethrough_type = efl_text_strikethrough_type_get(rp->object); + } + + if (eud->u.text_style.types & EDJE_PART_TEXT_PROP_UNDERLINE_DASHED_GAP) + { + Edje_Part_Text_Prop *prop; + + prop = _prop_new(props, EDJE_PART_TEXT_PROP_UNDERLINE_DASHED_GAP); + prop->val.ni = efl_text_underline_dashed_gap_get(rp->object); + } + + if (eud->u.text_style.types & EDJE_PART_TEXT_PROP_UNDERLINE_DASHED_WIDTH) + { + Edje_Part_Text_Prop *prop; + + prop = _prop_new(props, EDJE_PART_TEXT_PROP_UNDERLINE_DASHED_WIDTH); + prop->val.ni = efl_text_underline_dashed_width_get(rp->object); + } + + if (eud->u.text_style.types & EDJE_PART_TEXT_PROP_UNDERLINE_TYPE) + { + Edje_Part_Text_Prop *prop; + + prop = _prop_new(props, EDJE_PART_TEXT_PROP_UNDERLINE_TYPE); + prop->val.ni = efl_text_underline_type_get(rp->object); + } + + if (eud->u.text_style.types & EDJE_PART_TEXT_PROP_UNDERLINE_HEIGHT) + { + Edje_Part_Text_Prop *prop; + + prop = _prop_new(props, EDJE_PART_TEXT_PROP_UNDERLINE_HEIGHT); + prop->val.ni = efl_text_underline_height_get(rp->object); + } + + if (eud->u.text_style.types & EDJE_PART_TEXT_PROP_WRAP) + { + Edje_Part_Text_Prop *prop; + + prop = _prop_new(props, EDJE_PART_TEXT_PROP_WRAP); + prop->val.wrap = efl_text_wrap_get(rp->object); + + } +} + +void +_canvas_layout_user_text_apply(Edje_User_Defined *eud, Eo *obj, + Edje_Part_Text_Prop *prop) +{ + switch (prop->type) + { + + case EDJE_PART_TEXT_PROP_BACKING_TYPE: + efl_text_backing_type_set( + efl_part(obj, + eud->part), + prop->val.backing); + break; + +#define STYLE_COLOR_CASE(x, X) \ + case EDJE_PART_TEXT_PROP_COLOR_##X : \ + efl_text_##x ##_color_set(efl_part(obj, \ + eud->part), \ + prop->val.color.r, \ + prop->val.color.g, \ + prop->val.color.b, \ + prop->val.color.a); \ + break; + + STYLE_COLOR_CASE(backing, BACKING) + STYLE_COLOR_CASE(glow, GLOW) + STYLE_COLOR_CASE(glow2, GLOW2) + STYLE_COLOR_CASE(normal, NORMAL) + STYLE_COLOR_CASE(outline, OUTLINE) + STYLE_COLOR_CASE(shadow, SHADOW) + STYLE_COLOR_CASE(strikethrough, STRIKETHROUGH) + STYLE_COLOR_CASE(underline, UNDERLINE) + STYLE_COLOR_CASE(underline2, UNDERLINE2) + STYLE_COLOR_CASE(underline_dashed, UNDERLINE_DASHED) +#undef STYLE_COLOR_CASE + + case EDJE_PART_TEXT_PROP_EFFECT_TYPE: + efl_text_effect_type_set( + efl_part(obj, + eud->part), + prop->val.effect); + break; + + case EDJE_PART_TEXT_PROP_ELLIPSIS: + efl_text_ellipsis_set(efl_part(obj, + eud->part), + prop->val.nd); + break; + + case EDJE_PART_TEXT_PROP_FONT: + efl_text_font_set(efl_part(obj, + eud->part), + prop->val.font.font, + prop->val.font.size); + break; + + case EDJE_PART_TEXT_PROP_SHADOW_DIRECTION: + efl_text_shadow_direction_set( + efl_part(obj, + eud->part), + prop->val.shadow); + break; + + case EDJE_PART_TEXT_PROP_STRIKETHROUGH_TYPE: + efl_text_strikethrough_type_set( + efl_part(obj, + eud->part), + prop->val.strikethrough_type); + break; + + case EDJE_PART_TEXT_PROP_UNDERLINE_DASHED_WIDTH: + efl_text_underline_dashed_width_set( + efl_part(obj, + eud->part), + prop->val.ni); + break; + + case EDJE_PART_TEXT_PROP_UNDERLINE_DASHED_GAP: + efl_text_underline_dashed_gap_set( + efl_part(obj, + eud->part), + prop->val.ni); + break; + + case EDJE_PART_TEXT_PROP_UNDERLINE_TYPE: + efl_text_underline_type_set( + efl_part(obj, + eud->part), + prop->val.underline_type); + break; + + case EDJE_PART_TEXT_PROP_UNDERLINE_HEIGHT: + efl_text_underline_height_set( + efl_part(obj, + eud->part), + prop->val.nd); + break; + + case EDJE_PART_TEXT_PROP_WRAP: + efl_text_wrap_set(efl_part(obj, + eud->part), + prop->val.wrap); + break; + + default: + break; + } +} + + +EOLIAN static void +_efl_canvas_layout_part_text_text_expand_set(Eo *obj, + void *_pd EINA_UNUSED, + Efl_Canvas_Layout_Part_Text_Expand type) +{ + Edje_User_Defined *eud; + + PROXY_DATA_GET(obj, pd); + if (pd->rp->part->type == EDJE_PART_TYPE_TEXT) return; + + eud = _edje_user_text_expand_definition_fetch(pd->ed, pd->part); + eud->u.text_expand.expand = type; + pd->rp->typedata.text->expand = type; + +} + +EOLIAN static Efl_Canvas_Layout_Part_Text_Expand +_efl_canvas_layout_part_text_text_expand_get(const Eo *obj, + void *_pd EINA_UNUSED) +{ + PROXY_DATA_GET(obj, pd); + return pd->rp->typedata.text->expand; +} + #include "efl_canvas_layout_part_text.eo.c" diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index 2c12ea6a51..2b0d538ebb 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -1974,6 +1974,7 @@ struct _Edje_Real_Part_Text const char *style; // 4 Edje_Position offset; // 8 short size; // 2 + Efl_Canvas_Layout_Part_Text_Expand expand; struct { unsigned char fit_x, fit_y; // 2 short in_size; // 2 @@ -2252,6 +2253,58 @@ struct _Edje_Patterns unsigned int finals[]; }; +typedef enum +{ + EDJE_PART_TEXT_PROP_NONE = 0, // never used + EDJE_PART_TEXT_PROP_BACKING_TYPE = 1, + EDJE_PART_TEXT_PROP_COLOR_BACKING = 1 << 2, + EDJE_PART_TEXT_PROP_COLOR_GLOW = 1 << 3, + EDJE_PART_TEXT_PROP_COLOR_GLOW2 = 1 << 4, + EDJE_PART_TEXT_PROP_COLOR_NORMAL = 1 << 5, + EDJE_PART_TEXT_PROP_COLOR_OUTLINE = 1 << 6, + EDJE_PART_TEXT_PROP_COLOR_SHADOW = 1 << 7, + EDJE_PART_TEXT_PROP_COLOR_STRIKETHROUGH = 1 << 8, + EDJE_PART_TEXT_PROP_COLOR_UNDERLINE = 1 << 9, + EDJE_PART_TEXT_PROP_COLOR_UNDERLINE2 = 1 << 10, + EDJE_PART_TEXT_PROP_COLOR_UNDERLINE_DASHED = 1 << 11, + EDJE_PART_TEXT_PROP_EFFECT_TYPE = 1 << 12, + EDJE_PART_TEXT_PROP_ELLIPSIS = 1 << 13, + EDJE_PART_TEXT_PROP_FONT = 1 << 14, + EDJE_PART_TEXT_PROP_SHADOW_DIRECTION = 1 << 15, + EDJE_PART_TEXT_PROP_STRIKETHROUGH_TYPE = 1 << 16, + EDJE_PART_TEXT_PROP_UNDERLINE_DASHED_GAP = 1 << 17, + EDJE_PART_TEXT_PROP_UNDERLINE_DASHED_WIDTH = 1 << 18, + EDJE_PART_TEXT_PROP_UNDERLINE_TYPE = 1 << 19, + EDJE_PART_TEXT_PROP_UNDERLINE_HEIGHT = 1 << 20, + EDJE_PART_TEXT_PROP_WRAP = 1 << 21 +} Edje_Part_Text_Prop_Type; + +typedef struct +{ + Edje_Part_Text_Prop_Type type; + union + { + int ni; // number integer + int nd; // number double + Efl_Text_Format_Wrap wrap; + Efl_Text_Style_Backing_Type backing; + Efl_Text_Style_Underline_Type underline; + struct + { + unsigned char r, g, b, a; + } color; + struct + { + const char *font; + Efl_Font_Size size; + } font; + Efl_Text_Style_Effect_Type effect; + Efl_Text_Style_Shadow_Direction shadow; + Efl_Text_Style_Strikethrough_Type strikethrough_type; + Efl_Text_Style_Underline_Type underline_type; + } val; +} Edje_Part_Text_Prop; + typedef enum _Edje_User_Defined_Type { EDJE_USER_SWALLOW, @@ -2261,7 +2314,9 @@ typedef enum _Edje_User_Defined_Type EDJE_USER_DRAG_STEP, EDJE_USER_DRAG_PAGE, EDJE_USER_DRAG_VALUE, - EDJE_USER_DRAG_SIZE + EDJE_USER_DRAG_SIZE, + EDJE_USER_TEXT_STYLE, + EDJE_USER_TEXT_EXPAND, } Edje_User_Defined_Type; typedef struct _Edje_User_Defined Edje_User_Defined; @@ -2296,6 +2351,13 @@ struct _Edje_User_Defined struct { double w, h; } drag_size; + struct { + Eina_List *props; + Edje_Part_Text_Prop_Type types; + } text_style; + struct { + Efl_Canvas_Layout_Part_Text_Expand expand; + } text_expand; } u; }; @@ -2973,9 +3035,15 @@ Eina_Bool _edje_multisense_internal_vibration_sample_play(Edje *ed, const char * void _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *state); +Edje_User_Defined * _edje_user_definition_fetch(Edje *ed, const char *part, Edje_User_Defined_Type type); +Edje_User_Defined * _edje_user_text_style_definition_fetch(Edje *ed, const char *part); +Edje_User_Defined * _edje_user_text_expand_definition_fetch(Edje *ed, const char *part); void _edje_user_definition_remove(Edje_User_Defined *eud, Evas_Object *child); void _edje_user_definition_free(Edje_User_Defined *eud); +void _canvas_layout_user_text_apply(Edje_User_Defined *eud, Eo *obj, Edje_Part_Text_Prop *prop); +void _canvas_layout_user_text_collect(Edje *ed, Edje_User_Defined *eud); + extern Efl_Observable *_edje_color_class_member; extern Efl_Observable *_edje_text_class_member; extern Efl_Observable *_edje_size_class_member; diff --git a/src/lib/edje/edje_textblock.c b/src/lib/edje/edje_textblock.c index 9b9f17cc25..800a86636f 100644 --- a/src/lib/edje/edje_textblock.c +++ b/src/lib/edje/edje_textblock.c @@ -35,14 +35,30 @@ _edje_part_recalc_single_textblock_min_max_calc_legacy(Edje_Real_Part *ep, int *maxw, int *maxh) { Evas_Coord tw, th, ins_l, ins_r, ins_t, ins_b; + unsigned char minx2 = 0, miny2 = 0, maxx2 = 0, maxy2 = 0; + + minx2 = chosen_desc->text.min_x; + miny2 = chosen_desc->text.min_y; + maxx2 = chosen_desc->text.max_x; + maxy2 = chosen_desc->text.max_y; + + // Do not use size from new api if min/max are non-zero in the theme + if (!chosen_desc->text.min_x && !chosen_desc->text.min_y && + !chosen_desc->text.max_x && !chosen_desc->text.max_y) + { + minx2 = ep->typedata.text->expand & EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MIN_X; + miny2 = ep->typedata.text->expand & EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MIN_Y; + maxx2 = ep->typedata.text->expand & EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MAX_X; + maxy2 = ep->typedata.text->expand & EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MAX_Y; + } /* Legacy code for Textblock min/max calculation */ - if ((chosen_desc->text.min_x) || (chosen_desc->text.min_y)) + if (minx2 || miny2) { int mw = 0, mh = 0; tw = th = 0; - if (!chosen_desc->text.min_x) + if (!minx2) { efl_gfx_entity_size_set(ep->object, EINA_SIZE2D(TO_INT(params->eval.w), TO_INT(params->eval.h))); efl_canvas_text_size_formatted_get(ep->object, &tw, &th); @@ -53,22 +69,22 @@ _edje_part_recalc_single_textblock_min_max_calc_legacy(Edje_Real_Part *ep, &ins_r, &ins_t, &ins_b); mw = ins_l + tw + ins_r; mh = ins_t + th + ins_b; - if (minw && chosen_desc->text.min_x) + if (minw && minx2) { if (mw > *minw) *minw = mw; } - if (minh && chosen_desc->text.min_y) + if (minh && miny2) { if (mh > *minh) *minh = mh; } } - if ((chosen_desc->text.max_x) || (chosen_desc->text.max_y)) + if ((maxx2) || (maxy2)) { int mw = 0, mh = 0; tw = th = 0; - if (!chosen_desc->text.max_x) + if (!maxx2) { efl_gfx_entity_size_set(ep->object, EINA_SIZE2D(TO_INT(params->eval.w), TO_INT(params->eval.h))); efl_canvas_text_size_formatted_get(ep->object, &tw, &th); @@ -79,12 +95,12 @@ _edje_part_recalc_single_textblock_min_max_calc_legacy(Edje_Real_Part *ep, &ins_t, &ins_b); mw = ins_l + tw + ins_r; mh = ins_t + th + ins_b; - if (maxw && chosen_desc->text.max_x) + if (maxw && maxx2) { if (mw > *maxw) *maxw = mw; if (minw && (*maxw < *minw)) *maxw = *minw; } - if (maxh && chosen_desc->text.max_y) + if (maxh && maxy2) { if (mh > *maxh) *maxh = mh; if (minh && (*maxh < *minh)) *maxh = *minh; @@ -102,18 +118,35 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep, Evas_Coord tw, th, ins_l, ins_r, ins_t, ins_b; Evas_Coord min_calc_w = 0, min_calc_h = 0; + unsigned char dminx, dminy, dmaxx, dmaxy; + + dminx = chosen_desc->text.min_x; + dminy = chosen_desc->text.min_y; + dmaxx = chosen_desc->text.max_x; + dmaxy = chosen_desc->text.max_y; + + // Do not use size from new api if min/max are non-zero in the theme + if (!chosen_desc->text.min_x && !chosen_desc->text.min_y && + !chosen_desc->text.max_x && !chosen_desc->text.max_y) + { + dminx = ep->typedata.text->expand & EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MIN_X; + dminy = ep->typedata.text->expand & EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MIN_Y; + dmaxx = ep->typedata.text->expand & EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MAX_X; + dmaxy = ep->typedata.text->expand & EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_MAX_Y; + } + /* min_calc_* values need to save calculated minumum size * for maximum size calculation */ if (minw) min_calc_w = *minw; if (minh) min_calc_h = *minh; - if ((chosen_desc->text.min_x) || (chosen_desc->text.min_y)) + if (dminx || dminy) { evas_object_textblock_style_insets_get(ep->object, &ins_l, &ins_r, &ins_t, &ins_b); tw = th = 0; - if (!chosen_desc->text.min_x) + if (!dminx) { /* text.min: 0 1 * text.max: X X */ @@ -122,11 +155,11 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep, if (min_calc_w > temp_w) temp_w = min_calc_w; - if ((!chosen_desc->text.max_x) && + if ((!dmaxx) && maxw && (*maxw > -1) && (*maxw < temp_w)) temp_w = *maxw; - if (chosen_desc->text.max_y) + if (dmaxy) { /* text.min: 0 1 * text.max: X 1 */ @@ -161,7 +194,7 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep, { /* text.min: 1 X * text.max: X X */ - if (chosen_desc->text.min_y && (!chosen_desc->text.max_x) && + if (dminy && (!dmaxx) && maxw && (*maxw > -1)) { /* text.min: 1 1 @@ -174,7 +207,7 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep, if (min_calc_w > temp_w) temp_w = min_calc_w; - if ((!chosen_desc->text.max_y) && maxh && (*maxh > -1)) + if ((!dmaxy) && maxh && (*maxh > -1)) { /* text.min: 1 1 * text.max: 0 0 @@ -210,7 +243,7 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep, tw += ins_l + ins_r; th += ins_t + ins_b; - if (!chosen_desc->text.max_x && + if (!dmaxx && (maxw && (*maxw > -1) && (*maxw < tw))) { /* text.min: 1 0 @@ -222,23 +255,23 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep, if (tw > min_calc_w) min_calc_w = tw; if (th > min_calc_h) min_calc_h = th; - if (chosen_desc->text.min_x && minw) *minw = min_calc_w; - if (chosen_desc->text.min_y && minh) *minh = min_calc_h; + if (dminx && minw) *minw = min_calc_w; + if (dminy && minh) *minh = min_calc_h; } - if ((chosen_desc->text.max_x) || (chosen_desc->text.max_y)) + if ((dmaxx) || (dmaxy)) { evas_object_textblock_style_insets_get(ep->object, &ins_l, &ins_r, &ins_t, &ins_b); tw = th = 0; - if (!chosen_desc->text.max_x) + if (!dmaxx) { /* text.min: X X * text.max: 0 1 */ int temp_w, temp_h; - if (chosen_desc->text.min_y) + if (dminy) { /* text.min: X 1 * text.max: 0 1 @@ -284,7 +317,7 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep, else { /* text.max: 1 X */ - if (chosen_desc->text.min_x) + if (dminx) { /* text.min: 1 X * text.max: 1 X @@ -298,7 +331,7 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep, { /* text.min: 0 X * text.max: 1 X */ - if (chosen_desc->text.max_y) + if (dmaxy) { /* text.min: 0 X * text.max: 1 1 */ @@ -312,7 +345,7 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep, if (min_calc_h > temp_h) temp_h = min_calc_h; - if (chosen_desc->text.min_y) + if (dminy) { /* text.min: 0 1 * text.max: 1 1 @@ -370,12 +403,12 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep, } } - if (maxw && chosen_desc->text.max_x) + if (maxw && dmaxx) { if (tw > *maxw) *maxw = tw; if (minw && (*maxw < *minw)) *maxw = *minw; } - if (maxh && chosen_desc->text.max_y) + if (maxh && dmaxy) { if (th > *maxh) *maxh = th; if (minh && (*maxh < *minh)) *maxh = *minh; diff --git a/src/lib/edje/edje_util.c b/src/lib/edje/edje_util.c index 7ab54bb4bd..8c5af161a6 100644 --- a/src/lib/edje/edje_util.c +++ b/src/lib/edje/edje_util.c @@ -136,6 +136,16 @@ _edje_user_definition_free(Edje_User_Defined *eud) if (rp) _edje_child_remove(eud->ed, rp, child); break; + case EDJE_USER_TEXT_STYLE: + { + Edje_Part_Text_Prop *prop; + EINA_LIST_FREE(eud->u.text_style.props, prop) + { + free(prop); + } + break; + } + case EDJE_USER_STRING: case EDJE_USER_DRAG_STEP: case EDJE_USER_DRAG_PAGE: @@ -1993,6 +2003,71 @@ _edje_object_part_text_raw_set(Edje *ed, Evas_Object *obj, Edje_Real_Part *rp, c EINA_FALSE, EINA_TRUE); } +Edje_User_Defined * +_edje_user_definition_fetch(Edje *ed, + const char *part, Edje_User_Defined_Type type) +{ + Edje_User_Defined *eud; + Eina_List *l; + + EINA_LIST_FOREACH(ed->user_defined, l, eud) + { + if (eud->type == type && !strcmp(eud->part, part)) + { + return eud; + } + } + eud = _edje_user_definition_new(type, part, ed); + return eud; +} + +Edje_User_Defined * +_edje_user_text_style_definition_fetch(Edje *ed, const char *part) +{ + Edje_User_Defined *eud; + Eina_List *l; + + EINA_LIST_FOREACH(ed->user_defined, l, eud) + { + if (eud->type == EDJE_USER_TEXT_STYLE && !strcmp(eud->part, part)) + { + break; + } + } + + if (!eud) + { + eud = _edje_user_definition_new(EDJE_USER_TEXT_STYLE, part, ed); + eud->u.text_style.types = EDJE_PART_TEXT_PROP_NONE; + eud->u.text_style.props = NULL; + } + + return eud; +} + +Edje_User_Defined * +_edje_user_text_expand_definition_fetch(Edje *ed, const char *part) +{ + Edje_User_Defined *eud; + Eina_List *l; + + EINA_LIST_FOREACH(ed->user_defined, l, eud) + { + if (eud->type == EDJE_USER_TEXT_EXPAND && !strcmp(eud->part, part)) + { + break; + } + } + + if (!eud) + { + eud = _edje_user_definition_new(EDJE_USER_TEXT_EXPAND, part, ed); + eud->u.text_expand.expand = EFL_CANVAS_LAYOUT_PART_TEXT_EXPAND_NONE; + } + + return eud; +} + void _edje_user_define_string(Edje *ed, const char *part, const char *raw_text, Edje_Text_Type type) { diff --git a/src/lib/edje/efl_canvas_layout_part_text.eo b/src/lib/edje/efl_canvas_layout_part_text.eo index b59f470a5b..4ea5d32349 100644 --- a/src/lib/edje/efl_canvas_layout_part_text.eo +++ b/src/lib/edje/efl_canvas_layout_part_text.eo @@ -1,11 +1,38 @@ +enum Efl.Canvas.Layout_Part_Text_Expand +{ + [[Text layout policy to enforce. If none is set, min/max descriptions + are taken in considerations solely. + ]] + none = 0, [[No policy. Use default description parameters.]] + min_x = 1, + min_y = 1 << 1, + max_x = 1 << 2, + max_y = 1 << 3, +} + class Efl.Canvas.Layout_Part_Text (Efl.Canvas.Layout_Part, Efl.Text, -Efl.Text_Markup, Efl.Text_Cursor) +Efl.Text_Markup, Efl.Text_Cursor, Efl.Text_Format, Efl.Text_Font, +Efl.Text_Style) { [[Represents a TEXT part of a layout Its lifetime is limited to one function call only, unless an extra reference is explicitly held. ]] + methods { + @property text_expand { + [[Sizing policy for text parts. + + This will determine whether to consider height or width + constraints, if text-specific behaviors occur (such as ellipsis, + line-wrapping etc. + ]] + values { + type: Efl.Canvas.Layout_Part_Text_Expand; + } + } + + } data: null; implements { Efl.Text.text { set; get; } @@ -24,5 +51,26 @@ Efl.Text_Markup, Efl.Text_Cursor) Efl.Text_Cursor.cursor_content { get; } Efl.Text_Cursor.cursor_geometry { get; } Efl.Text_Markup.cursor_markup_insert; + Efl.Text_Format.ellipsis { set; get; } + Efl.Text_Format.wrap { set; get; } + Efl.Text_Font.font { set; get; } + Efl.Text_Style.normal_color { set; get; } + Efl.Text_Style.backing_type { set; get; } + Efl.Text_Style.backing_color { set; get;} + Efl.Text_Style.underline_type { set; } + Efl.Text_Style.underline_color { set; get; } + Efl.Text_Style.underline2_color { set; get; } + Efl.Text_Style.underline_dashed_color { set; get; } + Efl.Text_Style.underline_height { set; } + Efl.Text_Style.underline_dashed_width { set; } + Efl.Text_Style.underline_dashed_gap { set; } + Efl.Text_Style.strikethrough_type { set; } + Efl.Text_Style.strikethrough_color { set; get; } + Efl.Text_Style.effect_type { set; } + Efl.Text_Style.shadow_direction { set; } + Efl.Text_Style.outline_color { set; get; } + Efl.Text_Style.shadow_color { set; get; } + Efl.Text_Style.glow_color { set; get; } + Efl.Text_Style.glow2_color { set; get; } } } diff --git a/src/lib/efl/interfaces/efl_text_style.eo b/src/lib/efl/interfaces/efl_text_style.eo index 395609626c..99552ac036 100644 --- a/src/lib/efl/interfaces/efl_text_style.eo +++ b/src/lib/efl/interfaces/efl_text_style.eo @@ -153,15 +153,6 @@ interface Efl.Text_Style { } } - @property underline2_type - { - [[Type of underline2 style]] - values - { - type: Efl.Text_Style_Underline_Type; [[Underline type]] - } - } - @property underline2_color { [[Color of underline2 style]] diff --git a/src/lib/evas/canvas/efl_canvas_text.eo b/src/lib/evas/canvas/efl_canvas_text.eo index b24139e34a..488e38f835 100644 --- a/src/lib/evas/canvas/efl_canvas_text.eo +++ b/src/lib/evas/canvas/efl_canvas_text.eo @@ -294,7 +294,6 @@ class Efl.Canvas.Text (Efl.Canvas.Object, Efl.Text, Efl.Text_Style.underline_dashed_color { get; set; } Efl.Text_Style.underline_dashed_width { get; set; } Efl.Text_Style.underline_dashed_gap { get; set; } - Efl.Text_Style.underline2_type { get; set; } Efl.Text_Style.underline2_color { get; set; } Efl.Text_Style.strikethrough_type { get; set; } Efl.Text_Style.strikethrough_color { get; set; } diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c index 89397d2bf6..3636c42875 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c @@ -15561,11 +15561,26 @@ _efl_canvas_text_efl_text_style_backing_color_get(const Eo *obj EINA_UNUSED, Efl _FMT_COLOR_RET(backing); } +static struct +{ + Eina_Bool underline_single : 1; + Eina_Bool underline_double : 1; + Eina_Bool underline_dashed : 1; +} _style_underline_map[] = { + { 0, 0, 0 }, + { 1, 0, 0 }, + { 1, 1, 0 }, + { 0, 0, 1 } +}; + static void _efl_canvas_text_efl_text_style_underline_type_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Style_Underline_Type type EINA_UNUSED) { ASYNC_BLOCK; - _FMT_SET(underline, type); + _FMT_SET(underline, _style_underline_map[type].underline_single); + _FMT_SET(underline2, _style_underline_map[type].underline_double); + _FMT_SET(underline_dash, _style_underline_map[type].underline_dashed); + } static Efl_Text_Style_Underline_Type @@ -15640,19 +15655,6 @@ _efl_canvas_text_efl_text_style_underline_dashed_gap_get(const Eo *obj EINA_UNUS } static void -_efl_canvas_text_efl_text_style_underline2_type_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Style_Underline_Type type EINA_UNUSED) -{ - ASYNC_BLOCK; - _FMT_SET(underline2, type); -} - -static Efl_Text_Style_Underline_Type -_efl_canvas_text_efl_text_style_underline2_type_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED) -{ - return _FMT(underline2); -} - -static void _efl_canvas_text_efl_text_style_underline2_color_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, unsigned char r EINA_UNUSED, unsigned char g EINA_UNUSED, unsigned char b EINA_UNUSED, unsigned char a EINA_UNUSED) { ASYNC_BLOCK; diff --git a/src/tests/edje/data/test_text.edc b/src/tests/edje/data/test_text.edc new file mode 100644 index 0000000000..9395a2d4de --- /dev/null +++ b/src/tests/edje/data/test_text.edc @@ -0,0 +1,41 @@ +collections { + styles { + style { name: "tbstyle"; + base: ""; + } + } + group { name: "test"; + parts { + textblock { "text"; nomouse; + desc { "default"; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + text { + style: "tbstyle"; + font: FN; size: 10; + align: 0.5 0.5; + min: 0 0; + } + visible: 1; + } + } + } + } + group { name: "test2"; + parts { + textblock { "text"; nomouse; + desc { "default"; + rel1.relative: 0.0 0.0; + rel2.relative: 1.0 1.0; + text { + style: "tbstyle"; + font: FN; size: 10; + align: 0.5 0.5; + min: 0 0; + } + visible: 1; + } + } + } + } +} diff --git a/src/tests/edje/edje_suite.c b/src/tests/edje/edje_suite.c index 80cb84a8f6..cac6982874 100644 --- a/src/tests/edje/edje_suite.c +++ b/src/tests/edje/edje_suite.c @@ -8,6 +8,7 @@ static const Efl_Test_Case etc[] = { { "Edje", edje_test_edje }, + { "Edje Text", edje_test_text }, { NULL, NULL } }; diff --git a/src/tests/edje/edje_suite.h b/src/tests/edje/edje_suite.h index a6f1354fec..85574ed928 100644 --- a/src/tests/edje/edje_suite.h +++ b/src/tests/edje/edje_suite.h @@ -4,6 +4,7 @@ #include <check.h> #include "../efl_check.h" void edje_test_edje(TCase *tc); +void edje_test_text(TCase *tc); #endif /* _EDJE_SUITE_H */ diff --git a/src/tests/edje/edje_test_text.c b/src/tests/edje/edje_test_text.c new file mode 100644 index 0000000000..7d878a6153 --- /dev/null +++ b/src/tests/edje/edje_test_text.c @@ -0,0 +1,239 @@ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <unistd.h> +#include <stdio.h> + +#define EFL_GFX_FILTER_BETA +#define EFL_CANVAS_LAYOUT_BETA + +#include <Eina.h> +#include <Edje.h> + +#include "edje_suite.h" +#include "edje_tests_helpers.h" + +#define EVAS_DATA_DIR TESTS_SRC_DIR "/../../lib/evas" + +static const char * +test_layout_get(const char *name) +{ + static char filename[PATH_MAX]; + + snprintf(filename, PATH_MAX, TESTS_BUILD_DIR"/data/%s", name); + + return filename; +} + +START_TEST(edje_test_text_ellipsis) +{ + Eo *evas = EDJE_TEST_INIT_EVAS(); + Eo *layout; + + layout = efl_add(EFL_CANVAS_LAYOUT_CLASS, evas, + efl_gfx_size_hint_min_set(efl_added, EINA_SIZE2D(160, 40))); + efl_file_set(layout, test_layout_get("test_text.edj"), "test"); + fail_if(efl_file_load_error_get(layout)); + + efl_text_ellipsis_set(efl_part(layout, "text"), 1.0); + + EDJE_TEST_FREE_EVAS(); +} +END_TEST + +START_TEST(edje_test_text_wrap) +{ + Eo *evas = EDJE_TEST_INIT_EVAS(); + Eo *layout; + + layout = efl_add(EFL_CANVAS_LAYOUT_CLASS, evas, + efl_gfx_size_hint_min_set(efl_added, EINA_SIZE2D(160, 40))); + efl_file_set(layout, test_layout_get("test_text.edj"), "test"); + fail_if(efl_file_load_error_get(layout)); + + efl_text_wrap_set(efl_part(layout, "text"), EFL_TEXT_FORMAT_WRAP_WORD); + + EDJE_TEST_FREE_EVAS(); +} +END_TEST + +START_TEST(edje_test_text_font) +{ + Eo *evas = EDJE_TEST_INIT_EVAS(); + Eo *layout; + + layout = efl_add(EFL_CANVAS_LAYOUT_CLASS, evas, + efl_gfx_size_hint_min_set(efl_added, EINA_SIZE2D(160, 40))); + efl_file_set(layout, test_layout_get("test_text.edj"), "test"); + fail_if(efl_file_load_error_get(layout)); + + efl_text_font_set(efl_part(layout, "text"), "Sans", 14); + + EDJE_TEST_FREE_EVAS(); +} +END_TEST + +START_TEST(edje_test_text_color) +{ + Eo *evas = EDJE_TEST_INIT_EVAS(); + Eo *layout; + + layout = efl_add(EFL_CANVAS_LAYOUT_CLASS, evas, + efl_gfx_size_hint_min_set(efl_added, EINA_SIZE2D(160, 40))); + efl_file_set(layout, test_layout_get("test_text.edj"), "test"); + fail_if(efl_file_load_error_get(layout)); + + efl_text_normal_color_set(efl_part(layout, "text"), 255, 255, 255, 255); + + EDJE_TEST_FREE_EVAS(); +} +END_TEST + +static void +_basic_check(Eo *layout, Eina_Bool set) +{ + // Colors + { + unsigned char r, g, b, a; + + // Just normal_color is enough + if (set) + { + efl_text_normal_color_set(efl_part(layout, "text"), + 255, 255, 255, 255); + efl_text_backing_color_set(efl_part(layout, "text"), + 255, 255, 255, 255); + efl_text_glow_color_set(efl_part(layout, "text"), + 255, 255, 255, 255); + efl_text_glow2_color_set(efl_part(layout, "text"), + 255, 255, 255, 255); + efl_text_outline_color_set(efl_part(layout, "text"), + 255, 255, 255, 255); + efl_text_shadow_color_set(efl_part(layout, "text"), + 255, 255, 255, 255); + efl_text_strikethrough_color_set(efl_part(layout, "text"), + 255, 255, 255, 255); + efl_text_underline_color_set(efl_part(layout, "text"), + 255, 255, 255, 255); + efl_text_underline2_color_set(efl_part(layout, "text"), + 255, 255, 255, 255); + efl_text_underline_dashed_color_set(efl_part(layout, "text"), + 255, 255, 255, 255); + } + + efl_text_normal_color_get(efl_part(layout, "text"), &r, &g, &b, &a); + ck_assert_int_eq(r, 255); + ck_assert_int_eq(g, 255); + ck_assert_int_eq(b, 255); + ck_assert_int_eq(a, 255); + + efl_text_backing_color_get(efl_part(layout, "text"), &r, &g, &b, &a); + ck_assert_int_eq(r, 255); + ck_assert_int_eq(g, 255); + ck_assert_int_eq(b, 255); + ck_assert_int_eq(a, 255); + + efl_text_glow_color_get(efl_part(layout, "text"), &r, &g, &b, &a); + ck_assert_int_eq(r, 255); + ck_assert_int_eq(g, 255); + ck_assert_int_eq(b, 255); + ck_assert_int_eq(a, 255); + + efl_text_glow2_color_get(efl_part(layout, "text"), &r, &g, &b, &a); + ck_assert_int_eq(r, 255); + ck_assert_int_eq(g, 255); + ck_assert_int_eq(b, 255); + ck_assert_int_eq(a, 255); + + efl_text_outline_color_get(efl_part(layout, "text"), &r, &g, &b, &a); + ck_assert_int_eq(r, 255); + ck_assert_int_eq(g, 255); + ck_assert_int_eq(b, 255); + ck_assert_int_eq(a, 255); + + efl_text_shadow_color_get(efl_part(layout, "text"), &r, &g, &b, &a); + ck_assert_int_eq(r, 255); + ck_assert_int_eq(g, 255); + ck_assert_int_eq(b, 255); + ck_assert_int_eq(a, 255); + + efl_text_strikethrough_color_get(efl_part(layout, "text"), &r, &g, &b, &a); + ck_assert_int_eq(r, 255); + ck_assert_int_eq(g, 255); + ck_assert_int_eq(b, 255); + ck_assert_int_eq(a, 255); + + efl_text_underline_color_get(efl_part(layout, "text"), &r, &g, &b, &a); + ck_assert_int_eq(r, 255); + ck_assert_int_eq(g, 255); + ck_assert_int_eq(b, 255); + ck_assert_int_eq(a, 255); + + efl_text_underline2_color_get(efl_part(layout, "text"), &r, &g, &b, &a); + ck_assert_int_eq(r, 255); + ck_assert_int_eq(g, 255); + ck_assert_int_eq(b, 255); + ck_assert_int_eq(a, 255); + + efl_text_underline_dashed_color_get(efl_part(layout, "text"), &r, &g, &b, &a); + ck_assert_int_eq(r, 255); + ck_assert_int_eq(g, 255); + ck_assert_int_eq(b, 255); + ck_assert_int_eq(a, 255); + } + + // Rest of api + { + Efl_Text_Format_Wrap wrap; + double ellipsis; + const char *font; + Efl_Font_Size size; + + if (set) + { + efl_text_wrap_set(efl_part(layout, "text"), EFL_TEXT_FORMAT_WRAP_WORD); + efl_text_ellipsis_set(efl_part(layout, "text"), 1.0); + efl_text_font_set(efl_part(layout, "text"), "Sans", 12); + } + + wrap = efl_text_wrap_get(efl_part(layout, "text")); + ck_assert_int_eq(wrap, EFL_TEXT_FORMAT_WRAP_WORD); + + ellipsis = efl_text_ellipsis_get(efl_part(layout, "text")); + ck_assert(EINA_DBL_EQ(ellipsis, 1.0)); + + efl_text_font_get(efl_part(layout, "text"), &font, &size); + ck_assert_str_eq(font, "Sans"); + ck_assert_int_eq(size, 12); + } +} + +START_TEST(edje_test_text_part) +{ + Eo *evas = EDJE_TEST_INIT_EVAS(); + Eo *layout; + + layout = efl_add(EFL_CANVAS_LAYOUT_CLASS, evas, + efl_gfx_size_hint_min_set(efl_added, EINA_SIZE2D(160, 40))); + + efl_file_set(layout, test_layout_get("test_text.edj"), "test"); + fail_if(efl_file_load_error_get(layout)); + _basic_check(layout, EINA_TRUE); + + // Load again and check persistance + efl_file_set(layout, test_layout_get("test_text.edj"), "test2"); + fail_if(efl_file_load_error_get(layout)); + _basic_check(layout, EINA_FALSE); + + EDJE_TEST_FREE_EVAS(); +} +END_TEST +void edje_test_text(TCase *tc) +{ + tcase_add_test(tc, edje_test_text_ellipsis); + tcase_add_test(tc, edje_test_text_wrap); + tcase_add_test(tc, edje_test_text_font); + tcase_add_test(tc, edje_test_text_color); + tcase_add_test(tc, edje_test_text_part); +} |