Canvas layout: support more Efl.Text.* with efl_part
authorDaniel Hirt <hirt.danny@gmail.com>
Tue, 6 Nov 2018 14:52:53 +0000 (16:52 +0200)
committerYeongjong Lee <yj34.lee@samsung.com>
Thu, 8 Nov 2018 06:50:39 +0000 (15:50 +0900)
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

13 files changed:
src/Makefile_Edje.am
src/examples/elementary.mk
src/examples/elementary/efl_canvas_layout_text.c [new file with mode: 0644]
src/examples/elementary/efl_canvas_layout_text.edc [new file with mode: 0644]
src/lib/edje/edje_load.c
src/lib/edje/edje_part_text.c
src/lib/edje/edje_private.h
src/lib/edje/edje_textblock.c
src/lib/edje/edje_util.c
src/lib/edje/efl_canvas_layout_part_text.eo
src/tests/edje/data/test_text.edc [new file with mode: 0644]
src/tests/edje/edje_suite.c
src/tests/edje/edje_test_text.c

index b96e991..fecd37b 100644 (file)
@@ -318,6 +318,7 @@ 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_textblock.edc \
+tests/edje/data/test_text.edc \
 tests/edje/data/filter.lua
 
 
@@ -368,6 +369,7 @@ EDJE_TEST_FILES = tests/edje/data/test_layout.edj \
                      tests/edje/data/test_signal_callback_del_full.edj \
                      tests/edje/data/test_text_cursor.edj \
                      tests/edje/data/test_textblock.edj \
+                     tests/edje/data/test_text.edj \
                      $(NULL)
 
 CLEANFILES += $(EDJE_TEST_FILES)
index 0d0fa00..e928d9d 100644 (file)
@@ -122,7 +122,8 @@ elementary/efl_thread_6.c \
 elementary/efl_ui_list_example_1.c \
 elementary/efl_ui_list_view_example_1.c \
 elementary/efl_ui_list_view_example_2.c \
-elementary/efl_ui_list_view_example_3.c
+elementary/efl_ui_list_view_example_3.c \
+elementary/efl_canvas_layout_text.c
 
 ELM_SRCS += \
 elementary/bg_cxx_example_01.cc \
@@ -154,7 +155,8 @@ elementary/theme_example.edc \
 elementary/layout_example.edc \
 elementary/codegen_example.edc \
 elementary/efl_ui_list_view_example.edc \
-elementary/prefs_example_03.edc
+elementary/prefs_example_03.edc \
+elementary/efl_canvas_layout_text.edc
 
 ELM_EPCS = \
 elementary/prefs_example_01.epc \
@@ -336,7 +338,8 @@ elementary/efl_thread_6 \
 elementary/efl_ui_list_example_1 \
 elementary/efl_ui_list_view_example_1 \
 elementary/efl_ui_list_view_example_2 \
-elementary/efl_ui_list_view_example_3
+elementary/efl_ui_list_view_example_3 \
+elementary/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 (file)
index 0000000..8e89403
--- /dev/null
@@ -0,0 +1,158 @@
+// 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 'g' to cycle group examples.\n"
+          "Press 'e' to cycle ellipsis modes.\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 (file)
index 0000000..401ad0c
--- /dev/null
@@ -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;
+                }
+            }
+        }
+    }
+}
index 998088f..2b4de71 100644 (file)
@@ -1700,6 +1700,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);
                     }
@@ -1895,10 +1914,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;
           }
      }
index b11dd3b..c9b6981 100644 (file)
@@ -205,5 +205,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"
 
index ba26f37..cb51c47 100644 (file)
@@ -2111,6 +2111,7 @@ struct _Edje_Real_Part_Text
     * END *
     *******/
 
+   Efl_Canvas_Layout_Part_Text_Expand expand;
    struct {
       unsigned char       fit_x, fit_y; // 2
       short               in_size; // 2
@@ -2410,6 +2411,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,
@@ -2419,7 +2472,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;
@@ -2454,6 +2509,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;
 };
 
@@ -3187,9 +3249,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;
index 894eef4..e3e77de 100644 (file)
@@ -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 */
@@ -125,14 +158,14 @@ _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;
 
              /*
               * TIZEN_ONLY(20171211): fix calculation for vertically expandable textblock without max height
               *
-             if (chosen_desc->text.max_y)
+             if (dmaxy)
                {
                   // text.min: 0 1
                    * text.max: X 1 //
@@ -232,7 +265,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
@@ -245,7 +278,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
@@ -281,7 +314,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
@@ -293,23 +326,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
@@ -355,7 +388,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
@@ -369,7 +402,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 */
@@ -383,7 +416,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
@@ -441,12 +474,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;
index f2c31f9..32cf002 100644 (file)
@@ -175,6 +175,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:
@@ -2143,6 +2153,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)
 {
index b59f470..4ea5d32 100644 (file)
@@ -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/tests/edje/data/test_text.edc b/src/tests/edje/data/test_text.edc
new file mode 100644 (file)
index 0000000..9395a2d
--- /dev/null
@@ -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;
+               }
+           }
+       }
+   }
+}
index e8f39cf..8193003 100644 (file)
@@ -13,6 +13,7 @@ static const Efl_Test_Case etc[] = {
   { "Signal", edje_test_signal },
   { "Swallow", edje_test_swallow },
   { "Text", edje_test_text },
+  { "Edje Text", edje_test_text },
   { NULL, NULL }
 };
 
index 0e975f3..c4ac3c8 100644 (file)
@@ -12,7 +12,6 @@
 
 #define EVAS_DATA_DIR TESTS_SRC_DIR "/../../lib/evas"
 
-
 EFL_START_TEST(edje_test_text_cursor)
 {
    Evas *evas;
@@ -115,8 +114,227 @@ EFL_START_TEST(edje_test_textblock)
 }
 EFL_END_TEST
 
+START_TEST(edje_test_text_ellipsis)
+{
+   Eo *evas;
+   Eo *layout;
+
+   evas = _setup_evas();
+
+   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);
+
+   evas_free(evas);
+}
+END_TEST
+
+START_TEST(edje_test_text_wrap)
+{
+   Eo *evas;
+   Eo *layout;
+
+   evas = _setup_evas();
+
+   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);
+
+   evas_free(evas);
+}
+END_TEST
+
+START_TEST(edje_test_text_font)
+{
+   Eo *evas;
+   Eo *layout;
+
+   evas = _setup_evas();
+
+   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);
+
+   evas_free(evas);
+}
+END_TEST
+
+START_TEST(edje_test_text_color)
+{
+   Eo *evas;
+   Eo *layout;
+
+   evas = _setup_evas();
+
+   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);
+
+   evas_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;
+   Eo *layout;
+
+   evas = _setup_evas();
+
+   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);
+
+   evas_free(evas);
+}
+END_TEST
+
 void edje_test_text(TCase *tc)
 {
    tcase_add_test(tc, edje_test_text_cursor);
    tcase_add_test(tc, edje_test_textblock);
+   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);
 }