From 86a8f832ae2b622cd5489e5a01978d494997aaad Mon Sep 17 00:00:00 2001 From: Daniel Hirt Date: Fri, 7 Sep 2018 12:37:18 +0300 Subject: [PATCH] Ui text scroller: add scroller for internal usage 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 | 3 + src/lib/elementary/Elementary.h | 1 + .../efl_ui_internal_text_scroller.c | 184 ++++++++++++++++++ .../efl_ui_internal_text_scroller.eo | 45 +++++ 4 files changed, 233 insertions(+) create mode 100644 src/lib/elementary/efl_ui_internal_text_scroller.c create mode 100644 src/lib/elementary/efl_ui_internal_text_scroller.eo diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index 4298c46264..7c147f21fd 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -156,6 +156,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 \ @@ -718,6 +719,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 \ diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h index a504930681..bf56c5634f 100644 --- a/src/lib/elementary/Elementary.h +++ b/src/lib/elementary/Elementary.h @@ -342,6 +342,7 @@ typedef Eo Efl_Ui_Focus_Manager; # include # include # include +# include # include # include # include 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 index 0000000000..54b351eebd --- /dev/null +++ b/src/lib/elementary/efl_ui_internal_text_scroller.c @@ -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 + +#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 index 0000000000..70586260fa --- /dev/null +++ b/src/lib/elementary/efl_ui_internal_text_scroller.eo @@ -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; + } +}