2018-09-07 02:37:18 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "elementary_config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define ELM_LAYOUT_PROTECTED
|
|
|
|
#define EFL_UI_SCROLL_MANAGER_PROTECTED
|
|
|
|
#define EFL_UI_SCROLLBAR_PROTECTED
|
|
|
|
|
|
|
|
#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"
|
2018-11-05 13:55:20 -08:00
|
|
|
|
|
|
|
#include "efl_ui_internal_text_scroller.h"
|
2018-09-07 02:37:18 -07:00
|
|
|
|
|
|
|
#define EFL_UI_SCROLLER_DATA_GET(o, sd) \
|
|
|
|
Efl_Ui_Scroller_Data * sd = efl_data_scope_safe_get(o, EFL_UI_SCROLLER_CLASS)
|
|
|
|
|
2019-10-25 06:42:33 -07:00
|
|
|
#define EFL_UI_SCROLLER_DATA_GET_OR_RETURN(o, ptr, ...) \
|
|
|
|
EFL_UI_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__; \
|
|
|
|
}
|
2018-09-07 02:37:18 -07:00
|
|
|
#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
|
|
|
|
{
|
2018-11-12 05:09:56 -08:00
|
|
|
Efl_Canvas_Text *text_obj;
|
|
|
|
Efl_Ui_Table *text_table;
|
2018-09-07 02:37:18 -07:00
|
|
|
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));
|
2019-10-25 06:42:33 -07:00
|
|
|
//EFL_UI_SCROLLER_DATA_GET_OR_RETURN(obj, psd, NULL);
|
2018-09-07 02:37:18 -07:00
|
|
|
efl_ui_scrollbar_bar_mode_set(obj,
|
|
|
|
EFL_UI_SCROLLBAR_MODE_OFF, EFL_UI_SCROLLBAR_MODE_OFF);
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
2019-07-30 10:11:48 -07:00
|
|
|
_efl_ui_internal_text_scroller_efl_canvas_group_group_calculate(Eo *obj,
|
2018-09-07 02:37:18 -07:00
|
|
|
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;
|
|
|
|
|
2019-07-30 10:11:48 -07:00
|
|
|
efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
|
2019-10-25 06:42:33 -07:00
|
|
|
EFL_UI_SCROLLER_DATA_GET_OR_RETURN(obj, psd);
|
2018-09-07 02:37:18 -07:00
|
|
|
|
|
|
|
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
|
|
|
|
|
|
|
|
|
|
|
if (psd->smanager)
|
|
|
|
{
|
|
|
|
view = efl_ui_scrollable_viewport_geometry_get(psd->smanager);
|
|
|
|
}
|
|
|
|
|
|
|
|
edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
|
|
|
|
|
2018-11-12 05:09:56 -08:00
|
|
|
if (sd->text_obj)
|
2018-09-07 02:37:18 -07:00
|
|
|
{
|
|
|
|
Eina_Size2D fsz = EINA_SIZE2D(0, 0);
|
|
|
|
Eina_Size2D sz = EINA_SIZE2D(0, 0);
|
|
|
|
|
2018-11-12 05:09:56 -08:00
|
|
|
sz = efl_gfx_entity_size_get(sd->text_table);
|
|
|
|
efl_event_freeze(sd->text_table);
|
|
|
|
efl_event_freeze(sd->text_obj);
|
|
|
|
efl_gfx_entity_size_set(sd->text_table, view.size);
|
|
|
|
efl_gfx_entity_size_set(sd->text_obj, view.size);
|
Efl.Text.Cursor
Summary:
Implementation of new cursor text object.
This Patch Contains :
1- Remove Efl.Text.Cursor & Efl.Text_Markup_Interactive interfaces and replace them with one Class Efl.Text.Cursor
=> there are some modifications on cursor methods
2- Update all related classes to use Efl.Text.Cursor object instead of the old interfaces
3- If class uses Efl.Text_Cursor_Cursor (handle), mainly annotation it will stay as it is until we update other annotations into attribute_factory
4- Add main cursor property into efl.text.interactive
5- Add cursor_new method in efl.ui.text (I think we may move it into efl.text.interactive interface)
There still some parts that need discussion: especially cursor movement functionality, I prefer to move function with Enum, instead of special function for each movement.
```
enum @beta Efl.Text.Cursor_Move_Type
{
[[Text cursor movement types]]
char_next, [[Advances to the next character]]
char_prev, [[Advances to the previous character]]
cluster_next, [[Advances to the next grapheme cluster]]
cluster_prev, [[Advances to the previous grapheme cluster]]
paragraph_start, [[Advances to the first character in this paragraph]]
paragraph_end, [[Advances to the last character in this paragraph]]
word_start, [[Advance to current word start]]
word_end, [[Advance to current word end]]
line_start, [[Advance to current line first character]]
line_end, [[Advance to current line last character]]
paragraph_first, [[Advance to current paragraph first character]]
paragraph_last, [[Advance to current paragraph last character]]
paragraph_next, [[Advances to the start of the next text node]]
paragraph_prev [[Advances to the end of the previous text node]]
}
move {
[[Move the cursor]]
params {
@in type: Efl.Text.Cursor_Move_Type; [[The type of movement]]
}
return: bool; [[True if actually moved]]
}
```
or old way:
```
char_next {
[[Advances to the next character]]
// FIXME: Make the number of characters we moved by? Useful for all the other functions
return: bool; [[True if actually moved]]
}
char_prev {
[[Advances to the previous character]]
return: bool; [[True if actually moved]]
}
char_delete {
[[Deletes a single character from position pointed by given cursor.]]
}
cluster_next {
[[Advances to the next grapheme cluster]]
return: bool; [[True if actually moved]]
}
cluster_prev {
[[Advances to the previous grapheme cluster]]
return: bool; [[True if actually moved]]
}
// FIXME: paragraph_end is inconsistent with word_end. The one goes to the last character and the other after the last character.
paragraph_start {
[[Advances to the first character in this paragraph]]
return: bool; [[True if actually moved]]
}
paragraph_end {
[[Advances to the last character in this paragraph]]
return: bool; [[True if actually moved]]
}
word_start {
[[Advance to current word start]]
return: bool; [[True if actually moved]]
}
word_end {
[[Advance to current word end]]
return: bool; [[True if actually moved]]
}
line_start {
[[Advance to current line first character]]
return: bool; [[True if actually moved]]
}
line_end {
[[Advance to current line last character]]
return: bool; [[True if actually moved]]
}
paragraph_first {
[[Advance to current paragraph first character]]
return: bool; [[True if actually moved]]
}
paragraph_last {
[[Advance to current paragraph last character]]
return: bool; [[True if actually moved]]
}
paragraph_next {
[[Advances to the start of the next text node]]
return: bool; [[True if actually moved]]
}
paragraph_prev {
[[Advances to the end of the previous text node]]
return: bool; [[True if actually moved]]
}
```
Reviewers: woohyun, tasn, segfaultxavi
Reviewed By: woohyun
Subscribers: a.srour, bu5hm4n, segfaultxavi, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D10542
2019-11-22 00:35:54 -08:00
|
|
|
fsz = efl_canvas_text_size_formatted_get(sd->text_obj);
|
2018-11-12 05:09:56 -08:00
|
|
|
efl_gfx_entity_size_set(sd->text_table, sz);
|
|
|
|
efl_gfx_entity_size_set(sd->text_obj, sz);
|
|
|
|
efl_event_thaw(sd->text_obj);
|
|
|
|
efl_event_thaw(sd->text_table);
|
2018-09-07 02:37:18 -07:00
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-11-12 05:09:56 -08:00
|
|
|
efl_gfx_entity_size_set(sd->text_table, fsz);
|
2019-07-30 10:12:07 -07:00
|
|
|
efl_gfx_hint_size_restricted_min_set(obj, size);
|
2018-09-07 02:37:18 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2018-11-12 05:09:56 -08:00
|
|
|
efl_content_set(obj, sd->text_table);
|
2018-09-07 02:37:18 -07:00
|
|
|
|
|
|
|
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
|
2018-11-12 05:09:56 -08:00
|
|
|
_efl_ui_internal_text_scroller_initialize(Eo *obj,
|
2018-09-07 02:37:18 -07:00
|
|
|
Efl_Ui_Internal_Text_Scroller_Data *sd,
|
2018-11-12 05:09:56 -08:00
|
|
|
Efl_Canvas_Text *text_obj,
|
|
|
|
Efl_Ui_Table *text_table)
|
2018-09-07 02:37:18 -07:00
|
|
|
{
|
2018-11-12 05:09:56 -08:00
|
|
|
if (efl_finalized_get(obj))
|
|
|
|
{
|
|
|
|
ERR("Can only be called on construction");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sd->text_obj = text_obj;
|
|
|
|
sd->text_table = text_table;
|
2018-09-07 02:37:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2019-10-25 06:42:33 -07:00
|
|
|
EFL_UI_SCROLLER_DATA_GET_OR_RETURN(obj, psd);
|
2018-09-07 02:37:18 -07:00
|
|
|
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)
|
|
|
|
{
|
2019-10-25 06:42:33 -07:00
|
|
|
EFL_UI_SCROLLER_DATA_GET_OR_RETURN(obj, psd, NULL);
|
2018-09-07 02:37:18 -07:00
|
|
|
return evas_object_clip_get(psd->pan_obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Internal EO APIs and hidden overrides */
|
|
|
|
|
|
|
|
#include "efl_ui_internal_text_scroller.eo.c"
|