1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4 
5 #define EFL_PACK_LAYOUT_PROTECTED
6 
7 #include <Elementary.h>
8 #include "elm_priv.h"
9 
10 typedef struct {
11    Efl_Ui_Box *indicator;
12    Efl_Ui_Spotlight_Container *container;
13    Efl_Canvas_Layout *layout;
14    double last_position;
15    Eina_Size2D min, max;
16 } Efl_Ui_Spotlight_Icon_Indicator_Data;
17 
18 static void
_flush_state(Eo * item,double val)19 _flush_state(Eo *item, double val)
20 {
21    Eina_Value v = eina_value_double_init(val);
22 
23     efl_layout_signal_message_send(item, 1, v);
24 }
25 
26 static void
_add_item(Eo * obj EINA_UNUSED,Efl_Ui_Spotlight_Icon_Indicator_Data * pd)27 _add_item(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Icon_Indicator_Data *pd)
28 {
29    Efl_Canvas_Layout *item;
30 
31    item = efl_add(EFL_CANVAS_LAYOUT_CLASS, pd->indicator);
32    elm_widget_theme_object_set(pd->indicator, item,
33                                "spotlight", "indicator", "default");
34    efl_gfx_hint_align_set(item, 0.5, 0.5);
35    efl_gfx_hint_weight_set(item, 0, 0);
36    efl_gfx_hint_fill_set(item, 0, 0);
37    efl_gfx_hint_size_min_set(item,  efl_layout_calc_size_min(item, EINA_SIZE2D(0, 0)));
38    efl_pack_end(pd->indicator, item);
39    _flush_state(item, 0.0);
40 }
41 
42 static void
_flush_position(Eo * obj EINA_UNUSED,Efl_Ui_Spotlight_Icon_Indicator_Data * pd)43 _flush_position(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Icon_Indicator_Data *pd)
44 {
45    int next = -1, closer;
46    double closer_val;
47 
48    for (int i = 0; i < efl_content_count(pd->indicator); ++i)
49      {
50         _flush_state(efl_pack_content_get(pd->indicator, i), 0.0f);
51      }
52 
53    closer = MIN(MAX(round(pd->last_position), 0), efl_content_count(pd->container) - 1);
54    closer_val = fabs(1.0f - fabs(closer - pd->last_position));
55 
56    _flush_state(efl_pack_content_get(pd->indicator, closer), closer_val);
57 
58    if (pd->last_position > closer)
59      next = closer + 1;
60    else if (pd->last_position < closer)
61      next = closer - 1;
62    else
63      {
64         next = closer + 1;
65         if (next < efl_content_count(pd->container))
66           _flush_state(efl_pack_content_get(pd->indicator, next), fabs(1.0f - fabs((next - pd->last_position))));
67         next = closer - 1;
68         if (next >= 0)
69           _flush_state(efl_pack_content_get(pd->indicator, next), fabs(1.0f - fabs((next - pd->last_position))));
70      }
71 
72    if (next >= 0 && next < efl_content_count(pd->container))
73      _flush_state(efl_pack_content_get(pd->indicator, next), fabs(1.0f - fabs((next - pd->last_position))));
74 }
75 
76 static void
_resize_cb(void * data,const Efl_Event * ev)77 _resize_cb(void *data, const Efl_Event *ev)
78 {
79    efl_gfx_entity_size_set(data, efl_gfx_entity_size_get(ev->object));
80 }
81 
82 static void
_position_cb(void * data,const Efl_Event * ev EINA_UNUSED)83 _position_cb(void *data, const Efl_Event *ev EINA_UNUSED)
84 {
85    efl_gfx_entity_position_set(data, efl_gfx_entity_position_get(ev->object));
86 }
87 
88 EFL_CALLBACKS_ARRAY_DEFINE(spotlight_resized,
89   {EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _resize_cb},
90   {EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _position_cb},
91 )
92 
93 EOLIAN static void
_efl_ui_spotlight_icon_indicator_efl_ui_spotlight_indicator_bind(Eo * obj,Efl_Ui_Spotlight_Icon_Indicator_Data * pd,Efl_Ui_Spotlight_Container * spotlight)94 _efl_ui_spotlight_icon_indicator_efl_ui_spotlight_indicator_bind(Eo *obj, Efl_Ui_Spotlight_Icon_Indicator_Data *pd, Efl_Ui_Spotlight_Container *spotlight)
95 {
96    if (spotlight)
97      {
98         pd->container = spotlight;
99         pd->layout = efl_add(EFL_CANVAS_LAYOUT_CLASS, pd->container);
100         efl_event_callback_array_add(pd->container, spotlight_resized(), pd->layout);
101 
102         if (elm_widget_theme_object_set(pd->container, pd->layout,
103                                        "spotlight",
104                                        "indicator_holder",
105                                        elm_widget_theme_style_get(pd->container)) == EFL_UI_THEME_APPLY_ERROR_GENERIC)
106           CRI("Failed to set layout!");
107         efl_canvas_group_member_add(pd->container, pd->layout);
108         efl_gfx_entity_geometry_set(pd->layout, efl_gfx_entity_geometry_get(pd->container));
109 
110         pd->indicator = efl_add(EFL_UI_BOX_CLASS, pd->container);
111         efl_ui_widget_internal_set(pd->indicator, EINA_TRUE);
112         efl_ui_layout_orientation_set(pd->indicator, EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL);
113         efl_content_set(efl_part(pd->layout, "efl.indicator"), pd->indicator);
114 
115         for (int i = 0; i < efl_content_count(pd->container); ++i)
116           {
117              Eo *subobj = efl_pack_content_get(pd->container, i);
118              _add_item(obj, pd);
119              efl_gfx_stack_above(pd->layout, subobj);
120           }
121      }
122 }
123 
124 EOLIAN static void
_efl_ui_spotlight_icon_indicator_efl_ui_spotlight_indicator_content_add(Eo * obj,Efl_Ui_Spotlight_Icon_Indicator_Data * pd,Efl_Gfx_Entity * subobj EINA_UNUSED,int index EINA_UNUSED)125 _efl_ui_spotlight_icon_indicator_efl_ui_spotlight_indicator_content_add(Eo *obj, Efl_Ui_Spotlight_Icon_Indicator_Data *pd, Efl_Gfx_Entity *subobj EINA_UNUSED, int index EINA_UNUSED)
126 {
127    _add_item(obj, pd);
128    _flush_position(obj, pd);
129    efl_gfx_stack_above(pd->layout, subobj);
130 }
131 
132 EOLIAN static void
_efl_ui_spotlight_icon_indicator_efl_ui_spotlight_indicator_content_del(Eo * obj,Efl_Ui_Spotlight_Icon_Indicator_Data * pd,Efl_Gfx_Entity * subobj EINA_UNUSED,int index EINA_UNUSED)133 _efl_ui_spotlight_icon_indicator_efl_ui_spotlight_indicator_content_del(Eo *obj, Efl_Ui_Spotlight_Icon_Indicator_Data *pd, Efl_Gfx_Entity *subobj EINA_UNUSED, int index EINA_UNUSED)
134 {
135    efl_del(efl_pack_content_get(pd->indicator, 0));
136    _flush_position(obj, pd);
137 }
138 
139 EOLIAN static void
_efl_ui_spotlight_icon_indicator_efl_ui_spotlight_indicator_position_update(Eo * obj EINA_UNUSED,Efl_Ui_Spotlight_Icon_Indicator_Data * pd,double position)140 _efl_ui_spotlight_icon_indicator_efl_ui_spotlight_indicator_position_update(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Icon_Indicator_Data *pd, double position)
141 {
142    pd->last_position = position;
143    _flush_position(obj, pd);
144 }
145 
146 EOLIAN static void
_efl_ui_spotlight_icon_indicator_efl_object_destructor(Eo * obj EINA_UNUSED,Efl_Ui_Spotlight_Icon_Indicator_Data * pd)147 _efl_ui_spotlight_icon_indicator_efl_object_destructor(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Icon_Indicator_Data *pd)
148 {
149    if (pd->layout)
150      efl_del(pd->layout);
151    if (pd->indicator)
152      efl_del(pd->indicator);
153 
154    efl_destructor(efl_super(obj, EFL_UI_SPOTLIGHT_ICON_INDICATOR_CLASS));
155 }
156 
157 
158 #include "efl_ui_spotlight_icon_indicator.eo.c"
159