Ui text scroller: add scroller for internal usage
authorDaniel Hirt <hirt.danny@gmail.com>
Fri, 7 Sep 2018 09:37:18 +0000 (12:37 +0300)
committerYeongjong Lee <yj34.lee@samsung.com>
Thu, 8 Nov 2018 06:40:50 +0000 (15:40 +0900)
This class inherits Efl.Ui.Scroller and has its own sizing_eval logic to
handle the text content sizing as needed.

It's kept internal as it only serves Efl.Ui.Text in a scrollable mode.

src/Makefile_Elementary.am
src/lib/elementary/Elementary.h
src/lib/elementary/efl_ui_internal_text_scroller.c [new file with mode: 0644]
src/lib/elementary/efl_ui_internal_text_scroller.eo [new file with mode: 0644]

index 70ccdaf..03b7b00 100644 (file)
@@ -158,6 +158,7 @@ elm_public_eolian_files += \
 # Private classes (not exposed or shipped)
 elm_private_eolian_files = \
        lib/elementary/efl_ui_internal_text_interactive.eo \
+       lib/elementary/efl_ui_internal_text_scroller.eo \
        lib/elementary/efl_ui_focus_composition_adapter.eo \
        lib/elementary/efl_ui_win_part.eo \
        lib/elementary/efl_ui_focus_parent_provider.eo \
@@ -736,6 +737,8 @@ lib_elementary_libelementary_la_SOURCES = \
        lib/elementary/efl_ui_flip.c \
        lib/elementary/efl_ui_internal_text_interactive.c \
        lib/elementary/efl_ui_internal_text_interactive.h \
+       lib/elementary/efl_ui_internal_text_scroller.c \
+       lib/elementary/efl_ui_internal_text_scroller.h \
        lib/elementary/elm_flipselector.c \
        lib/elementary/elm_font.c \
        lib/elementary/efl_ui_frame.c \
index 50e2935..8160cf4 100644 (file)
@@ -352,6 +352,7 @@ typedef Eo Efl_Ui_Focus_Manager;
 # include <efl_ui_list_view.eo.h>
 # include <efl_ui_list_view_pan.eo.h>
 # include <efl_ui_pan.eo.h>
+# include <efl_ui_internal_text_scroller.eo.h>
 # include <efl_ui_scroll_manager.eo.h>
 # include <efl_ui_scroller.eo.h>
 # include <efl_ui_dnd_types.eot.h>
diff --git a/src/lib/elementary/efl_ui_internal_text_scroller.c b/src/lib/elementary/efl_ui_internal_text_scroller.c
new file mode 100644 (file)
index 0000000..54b351e
--- /dev/null
@@ -0,0 +1,184 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#define ELM_LAYOUT_PROTECTED
+#define EFL_UI_SCROLL_MANAGER_PROTECTED
+#define EFL_UI_SCROLLBAR_PROTECTED
+#define EFL_UI_SCROLLBAR_BETA
+
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+
+#include "elm_priv.h"
+#include "elm_widget_layout.h"
+#include "efl_ui_widget_scroller.h"
+
+#define EFL_UI_SCROLLER_DATA_GET(o, sd) \
+  Efl_Ui_Scroller_Data * sd = efl_data_scope_safe_get(o, EFL_UI_SCROLLER_CLASS)
+
+#define MY_CLASS EFL_UI_INTERNAL_TEXT_SCROLLER_CLASS
+#define MY_CLASS_PFX efl_ui_internal_text_scroller
+
+#define MY_CLASS_NAME "Efl.Ui.Internal_Text_Scroller"
+
+typedef struct _Efl_Ui_Internal_Text_Scroller_Data
+{
+   Efl_Canvas_Text *content;
+   Eo *smanager;
+
+   Efl_Ui_Text_Scroller_Mode mode;
+
+   Eina_Bool  match_content_w: 1;
+   Eina_Bool  match_content_h: 1;
+} Efl_Ui_Internal_Text_Scroller_Data;
+
+#define EFL_UI_INTERNAL_TEXT_SCROLLER_DATA_GET(o, sd) \
+  Efl_Ui_Internal_Text_Scroller_Data * sd = efl_data_scope_safe_get(o, EFL_UI_INTERNAL_TEXT_SCROLLER_CLASS)
+
+#define EFL_UI_INTERNAL_TEXT_SCROLLER_DATA_GET_OR_RETURN(o, ptr, ...) \
+  EFL_UI_INTERNAL_TEXT_SCROLLER_DATA_GET(o, ptr);                         \
+  if (EINA_UNLIKELY(!ptr))                            \
+    {                                                 \
+       ERR("No widget data for object %p (%s)",       \
+           o, evas_object_type_get(o));               \
+       return __VA_ARGS__;                                    \
+    }
+
+EOLIAN static Eo *
+_efl_ui_internal_text_scroller_efl_object_constructor(Eo *obj,
+                                        Efl_Ui_Internal_Text_Scroller_Data *sd EINA_UNUSED)
+{
+   obj = efl_constructor(efl_super(obj, MY_CLASS));
+   //EFL_UI_SCROLLER_DATA_GET(obj, psd);
+   efl_ui_scrollbar_bar_mode_set(obj,
+         EFL_UI_SCROLLBAR_MODE_OFF, EFL_UI_SCROLLBAR_MODE_OFF);
+
+   return obj;
+}
+
+EOLIAN static void
+_efl_ui_internal_text_scroller_elm_layout_sizing_eval(Eo *obj,
+      Efl_Ui_Internal_Text_Scroller_Data *sd)
+{
+   Eina_Size2D size = {-1, -1};
+   Eina_Rect view = EINA_RECT(0, 0, 0, 0);
+   Evas_Coord vmw = 0, vmh = 0;
+   double xw = 0.0, yw = 0.0;
+
+   EFL_UI_SCROLLER_DATA_GET(obj, psd);
+
+   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+   if (sd->content)
+     {
+        efl_gfx_size_hint_weight_get(sd->content, &xw, &yw);
+     }
+
+   if (psd->smanager)
+     {
+        view = efl_ui_scrollable_viewport_geometry_get(psd->smanager);
+     }
+
+   edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
+
+   if (sd->content)
+     {
+        Eina_Size2D fsz = EINA_SIZE2D(0, 0);
+        Eina_Size2D sz = EINA_SIZE2D(0, 0);
+
+        sz = efl_gfx_entity_size_get(sd->content);
+        efl_event_freeze(sd->content);
+        efl_gfx_entity_size_set(sd->content, view.size);
+        efl_canvas_text_size_formatted_get(sd->content, &fsz.w, &fsz.h);
+        efl_gfx_entity_size_set(sd->content, sz);
+        efl_event_thaw(sd->content);
+
+
+        if (sd->mode == EFL_UI_TEXT_SCROLLER_MODE_SINGLELINE)
+          {
+             size.h = vmh + fsz.h;
+             if (fsz.w < view.w)
+               {
+                  fsz.w = view.w;
+               }
+          }
+        else
+          {
+             if (fsz.h < view.h)
+                fsz.h = view.h;
+
+             if (fsz.w < view.w)
+                fsz.w = view.w;
+          }
+
+        // FIXME: should be restricted_min?
+        efl_gfx_entity_size_set(sd->content, fsz);
+        efl_gfx_size_hint_min_set(obj, size);
+        efl_gfx_size_hint_max_set(obj, EINA_SIZE2D(-1, size.h));
+     }
+}
+
+EOLIAN static Eo *
+_efl_ui_internal_text_scroller_efl_object_finalize(Eo *obj,
+                                     Efl_Ui_Internal_Text_Scroller_Data *sd EINA_UNUSED)
+{
+   obj = efl_finalize(efl_super(obj, MY_CLASS));
+   efl_ui_scrollbar_bar_mode_set(obj,
+         EFL_UI_SCROLLBAR_MODE_OFF, EFL_UI_SCROLLBAR_MODE_OFF);
+
+   return obj;
+}
+
+EOLIAN static void
+_efl_ui_internal_text_scroller_efl_object_destructor(Eo *obj,
+                                       Efl_Ui_Internal_Text_Scroller_Data *sd EINA_UNUSED)
+{
+   efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static void
+_efl_ui_internal_text_scroller_text_object_set(Eo *obj,
+                                       Efl_Ui_Internal_Text_Scroller_Data *sd,
+                                       Efl_Canvas_Text *text_obj)
+{
+   sd->content = text_obj;
+   efl_content_set(obj, text_obj);
+}
+
+EOLIAN static void
+_efl_ui_internal_text_scroller_scroller_mode_set(Eo *obj,
+                                       Efl_Ui_Internal_Text_Scroller_Data *sd,
+                                       Efl_Ui_Text_Scroller_Mode mode)
+{
+   EFL_UI_SCROLLER_DATA_GET(obj, psd);
+   sd->mode = mode;
+   if (mode == EFL_UI_TEXT_SCROLLER_MODE_MULTILINE)
+     {
+        efl_ui_scrollbar_bar_mode_set(psd->smanager,
+              EFL_UI_SCROLLBAR_MODE_AUTO, EFL_UI_SCROLLBAR_MODE_AUTO);
+     }
+   else // default (single-line)
+     {
+        efl_ui_scrollbar_bar_mode_set(psd->smanager,
+              EFL_UI_SCROLLBAR_MODE_OFF, EFL_UI_SCROLLBAR_MODE_OFF);
+     }
+}
+
+EOLIAN static Eo *
+_efl_ui_internal_text_scroller_viewport_clip_get(const Eo *obj,
+      Efl_Ui_Internal_Text_Scroller_Data *sd EINA_UNUSED)
+{
+   EFL_UI_SCROLLER_DATA_GET(obj, psd);
+   return evas_object_clip_get(psd->pan_obj);
+}
+
+/* Internal EO APIs and hidden overrides */
+
+#define EFL_UI_INTERNAL_TEXT_SCROLLER_EXTRA_OPS \
+   ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_internal_text_scroller)
+
+#include "efl_ui_internal_text_scroller.eo.c"
diff --git a/src/lib/elementary/efl_ui_internal_text_scroller.eo b/src/lib/elementary/efl_ui_internal_text_scroller.eo
new file mode 100644 (file)
index 0000000..7058626
--- /dev/null
@@ -0,0 +1,45 @@
+enum Efl.Ui.Text_Scroller_Mode
+{
+   default = 0,
+   singleline = 0,
+   multiline = 1,
+}
+
+class Efl.Ui.Internal_Text_Scroller (Efl.Ui.Scroller)
+{
+   [[Efl ui text scroller class]]
+   methods {
+      @property text_object {
+         [[The Efl.Canvas.Text content of this scroller]]
+         set {
+            [[Sets the given text object as the content of this scroller]]
+         }
+         values {
+            text_obj: Efl.Canvas.Text @nullable;
+         }
+      }
+      @property scroller_mode {
+         [[Mode of operation for the scroller]]
+         set {
+            [[Sets mode to either default (singleline) or multiline]]
+         }
+         values {
+            mode: Efl.Ui.Text_Scroller_Mode;
+         }
+      }
+      @property viewport_clip {
+         [[The viewport's clip object]]
+         get {
+            [[Gets viewport's clip object]]
+         }
+         values {
+            clip: Efl.Object;
+         }
+      }
+   }
+   implements {
+      Efl.Object.constructor;
+      Efl.Object.finalize;
+      Efl.Object.destructor;
+   }
+}