1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #include <Elementary.h>
6
7 #include "elm_priv.h"
8 #include "efl_ui_item_private.h"
9
10 #define MY_CLASS EFL_UI_ITEM_CLASS
11 #define MY_CLASS_PFX efl_ui_item
12
13 #define MY_CLASS_NAME "Efl.Ui.Item"
14
15 static Eina_Bool _key_action_select(Evas_Object *obj, const char *params EINA_UNUSED);
16
17 static const Elm_Action key_actions[] = {
18 {"select", _key_action_select},
19 {NULL, NULL}
20 };
21
22 static Eina_Bool
_key_action_select(Evas_Object * obj,const char * params EINA_UNUSED)23 _key_action_select(Evas_Object *obj, const char *params EINA_UNUSED)
24 {
25 efl_ui_selectable_selected_set(obj, EINA_TRUE);
26 return EINA_FALSE;
27 }
28
29 static Efl_Ui_Select_Mode
_fetch_state(Eo * obj)30 _fetch_state(Eo *obj)
31 {
32 if (efl_isa(obj, EFL_UI_MULTI_SELECTABLE_INTERFACE))
33 return efl_ui_multi_selectable_select_mode_get(obj);
34 if (efl_isa(obj, EFL_UI_SINGLE_SELECTABLE_INTERFACE))
35 return EFL_UI_SELECT_MODE_SINGLE;
36 ERR("Uncaught state %s", efl_debug_name_get(obj));
37 return EFL_UI_SELECT_MODE_NONE;
38 }
39
40 static void
_item_select(Eo * obj,Efl_Ui_Item_Data * pd)41 _item_select(Eo *obj, Efl_Ui_Item_Data *pd)
42 {
43 Efl_Ui_Select_Mode m;
44
45 if (pd->container)
46 {
47 m = _fetch_state(pd->container);
48 if (m == EFL_UI_SELECT_MODE_NONE)
49 return;
50 }
51 else
52 {
53 if (pd->selected)
54 return;
55 }
56
57 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
58
59 Eina_Bool tmp = pd->selected = EINA_TRUE;
60 edje_object_signal_emit(wd->resize_obj, "efl,state,selected", "efl");
61 efl_event_callback_call(obj, EFL_UI_EVENT_SELECTED_CHANGED, &tmp);
62 }
63
64 static void
_item_unselect(Eo * obj,Efl_Ui_Item_Data * pd)65 _item_unselect(Eo *obj, Efl_Ui_Item_Data *pd)
66 {
67 if (!pd->selected) return;
68 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
69
70 Eina_Bool tmp = pd->selected =EINA_FALSE;
71 edje_object_signal_emit(wd->resize_obj, "efl,state,unselected", "efl");
72 efl_event_callback_call(obj, EFL_UI_EVENT_SELECTED_CHANGED, &tmp);
73 }
74
75 /* Mouse Controls */
76 static void
_item_pressed(void * data,const Efl_Event * ev EINA_UNUSED)77 _item_pressed(void *data, const Efl_Event *ev EINA_UNUSED)
78 {
79 Efl_Ui_Item *obj = data;
80 if (efl_ui_widget_disabled_get(obj)) return;
81
82 efl_layout_signal_emit(obj, "efl,state,pressed", "efl");
83 }
84
85 static void
_item_unpressed(void * data,const Efl_Event * ev EINA_UNUSED)86 _item_unpressed(void *data, const Efl_Event *ev EINA_UNUSED)
87 {
88 Efl_Ui_Item *obj = data;
89 Efl_Ui_Select_Mode m;
90 EFL_UI_ITEM_DATA_GET_OR_RETURN(obj, pd);
91
92 if (efl_ui_widget_disabled_get(obj)) return;
93 if (!efl_ui_item_container_get(obj)) return;
94
95 efl_layout_signal_emit(obj, "efl,state,unpressed", "efl");
96 m = _fetch_state(pd->container);
97
98 if (pd->selected)
99 {
100 if (efl_ui_selectable_allow_manual_deselection_get(pd->container))
101 efl_ui_selectable_selected_set(obj, EINA_FALSE);
102 }
103 else if (m != EFL_UI_SELECT_MODE_NONE)
104 efl_ui_selectable_selected_set(obj, EINA_TRUE);
105 }
106
107 EFL_CALLBACKS_ARRAY_DEFINE(self_listening,
108 {EFL_INPUT_EVENT_PRESSED, _item_pressed},
109 {EFL_INPUT_EVENT_UNPRESSED, _item_unpressed},
110 )
111
112 /* Mouse Controls ends */
113
114 EOLIAN static Eo *
_efl_ui_item_efl_object_constructor(Eo * obj,Efl_Ui_Item_Data * pd EINA_UNUSED)115 _efl_ui_item_efl_object_constructor(Eo *obj, Efl_Ui_Item_Data *pd EINA_UNUSED)
116 {
117 obj = efl_constructor(efl_super(obj, MY_CLASS));
118 efl_ui_layout_finger_size_multiplier_set(obj, 0, 0);
119
120 efl_event_callback_array_add(obj, self_listening(), obj);
121
122 return obj;
123 }
124
125 EOLIAN static Efl_Object *
_efl_ui_item_efl_object_finalize(Eo * obj,Efl_Ui_Item_Data * pd EINA_UNUSED)126 _efl_ui_item_efl_object_finalize(Eo *obj, Efl_Ui_Item_Data *pd EINA_UNUSED)
127 {
128 Eo *eo;
129 eo = efl_finalize(efl_super(obj, MY_CLASS));
130 ELM_WIDGET_DATA_GET_OR_RETURN(eo, wd, eo);
131
132 /* Support Item Focus Feature */
133 elm_widget_can_focus_set(obj, EINA_TRUE);
134
135 if (efl_ui_layout_theme_version_get(obj) == 123)
136 efl_ui_action_connector_bind_clickable_to_object(wd->resize_obj, obj);
137 else
138 efl_ui_action_connector_bind_clickable_to_theme(wd->resize_obj, obj);
139 return eo;
140 }
141
142 EOLIAN static void
_efl_ui_item_efl_object_destructor(Eo * obj,Efl_Ui_Item_Data * pd EINA_UNUSED)143 _efl_ui_item_efl_object_destructor(Eo *obj, Efl_Ui_Item_Data *pd EINA_UNUSED)
144 {
145 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
146
147 efl_destructor(efl_super(obj, MY_CLASS));
148 }
149
150 EOLIAN static int
_efl_ui_item_index_get(const Eo * obj,Efl_Ui_Item_Data * pd)151 _efl_ui_item_index_get(const Eo *obj, Efl_Ui_Item_Data *pd)
152 {
153 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->container, -1);
154 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(pd->container, EFL_PACK_LINEAR_INTERFACE), -1);
155 return efl_pack_index_get(pd->container, obj);
156 }
157
158 EOLIAN static void
_efl_ui_item_efl_ui_selectable_selected_set(Eo * obj,Efl_Ui_Item_Data * pd,Eina_Bool select)159 _efl_ui_item_efl_ui_selectable_selected_set(Eo *obj, Efl_Ui_Item_Data *pd, Eina_Bool select)
160 {
161 Eina_Bool selected = !!select;
162 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
163 if (wd->disabled) return;
164
165 if (selected) _item_select(obj, pd);
166 else _item_unselect(obj, pd);
167 }
168
169 EOLIAN static Eina_Bool
_efl_ui_item_efl_ui_selectable_selected_get(const Eo * obj EINA_UNUSED,Efl_Ui_Item_Data * pd)170 _efl_ui_item_efl_ui_selectable_selected_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
171 {
172 return pd->selected;
173 }
174
175 EOLIAN static void
_efl_ui_item_container_set(Eo * obj EINA_UNUSED,Efl_Ui_Item_Data * pd,Efl_Ui_Widget * container)176 _efl_ui_item_container_set(Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd, Efl_Ui_Widget *container)
177 {
178 pd->container = container;
179 if (!pd->container)
180 {
181 pd->parent = NULL;
182 }
183 }
184
185 EOLIAN static Efl_Ui_Widget*
_efl_ui_item_container_get(const Eo * obj EINA_UNUSED,Efl_Ui_Item_Data * pd)186 _efl_ui_item_container_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
187 {
188 return pd->container;
189 }
190
191 EOLIAN static void
_efl_ui_item_item_parent_set(Eo * obj,Efl_Ui_Item_Data * pd,Efl_Ui_Item * parent)192 _efl_ui_item_item_parent_set(Eo *obj, Efl_Ui_Item_Data *pd, Efl_Ui_Item *parent)
193 {
194 if (pd->parent)
195 {
196 ERR("Parent is already set on object %p", obj);
197 return;
198 }
199 if (efl_invalidated_get(obj) || efl_invalidating_get(obj))
200 {
201 ERR("Parent cannot be set during invalidate");
202 return;
203 }
204 if (pd->container)
205 {
206 ERR("Parent must be set before adding the object to the container");
207 return;
208 }
209 pd->parent = parent;
210 }
211
212
213 EOLIAN static Efl_Ui_Item*
_efl_ui_item_item_parent_get(const Eo * obj EINA_UNUSED,Efl_Ui_Item_Data * pd)214 _efl_ui_item_item_parent_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
215 {
216 return pd->parent;
217 }
218
219 EOLIAN static void
_efl_ui_item_calc_locked_set(Eo * obj EINA_UNUSED,Efl_Ui_Item_Data * pd,Eina_Bool locked)220 _efl_ui_item_calc_locked_set(Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd, Eina_Bool locked)
221 {
222 pd->locked = !!locked;
223 }
224
225 EOLIAN static Eina_Bool
_efl_ui_item_calc_locked_get(const Eo * obj EINA_UNUSED,Efl_Ui_Item_Data * pd)226 _efl_ui_item_calc_locked_get(const Eo *obj EINA_UNUSED, Efl_Ui_Item_Data *pd)
227 {
228 return pd->locked;
229 }
230
231 EOLIAN static void
_efl_ui_item_efl_canvas_group_group_need_recalculate_set(Eo * obj,Efl_Ui_Item_Data * pd EINA_UNUSED,Eina_Bool value)232 _efl_ui_item_efl_canvas_group_group_need_recalculate_set(Eo *obj, Efl_Ui_Item_Data *pd EINA_UNUSED, Eina_Bool value)
233 {
234 // Prevent recalc when the item are stored in the cache
235 // As due to async behavior, we can still have text updated from future that just finished after
236 // we have left the releasing stage of factories. This is the simplest way to prevent those later
237 // update.
238 if (pd->locked) return;
239 efl_canvas_group_need_recalculate_set(efl_super(obj, EFL_UI_ITEM_CLASS), value);
240 }
241
242 ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_item, Efl_Ui_Item_Data)
243
244 #include "efl_ui_item.eo.c"
245 #include "efl_ui_selectable.eo.c"
246 #include "efl_ui_multi_selectable.eo.c"
247 #include "efl_ui_multi_selectable_object_range.eo.c"
248 #include "efl_ui_single_selectable.eo.c"
249 #include "efl_ui_item_clickable.eo.c"
250
251