summaryrefslogtreecommitdiff
path: root/src/lib/elementary/efl_ui_widget_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/elementary/efl_ui_widget_common.c')
-rw-r--r--src/lib/elementary/efl_ui_widget_common.c174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/lib/elementary/efl_ui_widget_common.c b/src/lib/elementary/efl_ui_widget_common.c
new file mode 100644
index 0000000..519efe2
--- /dev/null
+++ b/src/lib/elementary/efl_ui_widget_common.c
@@ -0,0 +1,174 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_ACCESS_OBJECT_PROTECTED
6#define EFL_ACCESS_COMPONENT_PROTECTED
7#define ELM_WIDGET_PROTECTED
8#define ELM_WIDGET_ITEM_PROTECTED
9#define EFL_INPUT_EVENT_PROTECTED
10#define EFL_UI_L10N_PROTECTED
11#define EFL_UI_FOCUS_OBJECT_PROTECTED
12#define EFL_UI_WIDGET_PART_BG_PROTECTED
13#define EFL_PART_PROTECTED
14
15#include <Elementary.h>
16
17#include "elm_priv.h"
18#include "elm_widget_container.h"
19#include "elm_interface_scrollable.h"
20#include "elm_pan_eo.h"
21#include "elm_part_helper.h"
22#include "elm_widget_combobox.h"
23
24typedef struct {
25 Eina_Iterator iterator;
26 Efl_Ui_Widget *origin; //where we started
27 Efl_Ui_Widget *current; // the current widget where the iterator is
28} Widget_Iterator;
29
30static Widget_Iterator*
31iter_init(Efl_Ui_Widget *origin)
32{
33 Widget_Iterator *it;
34
35 it = calloc(1, sizeof(Widget_Iterator));
36
37 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
38
39 it->origin = origin;
40 it->iterator.version = EINA_ITERATOR_VERSION;
41 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(NULL);
42 it->iterator.free = FUNC_ITERATOR_FREE(free);
43
44 return it;
45}
46
47static Efl_Ui_Widget*
48_fetch_parent_widget(Efl_Gfx_Entity* o)
49{
50 Efl_Ui_Widget *parent;
51
52 if (efl_isa(o, EFL_UI_WIDGET_CLASS))
53 parent = efl_ui_widget_parent_get(o);
54 else
55 parent = evas_object_data_get(o, "elm-parent");
56
57 return parent;
58}
59
60static Efl_Ui_Widget*
61_next_widget(Efl_Gfx_Entity* o)
62{
63 Efl_Ui_Widget *parent;
64 Eina_List *rel;
65
66 parent = _fetch_parent_widget(o);
67 ELM_WIDGET_DATA_GET_OR_RETURN(parent, pd, NULL);
68 rel = eina_list_data_find_list(pd->subobjs, o);
69
70 return eina_list_data_get(eina_list_next(rel));
71}
72
73static Eina_Bool
74_widget_next(Widget_Iterator *it, void **data)
75{
76 Efl_Ui_Widget *runner;
77 Efl_Ui_Widget_Data *pd = NULL;
78
79 //Init case
80 if (!it->current)
81 {
82 it->current = it->origin;
83 goto deliver;
84 }
85
86 if (efl_isa(it->current, EFL_UI_WIDGET_CLASS))
87 {
88 pd = efl_data_scope_safe_get(it->current, EFL_UI_WIDGET_CLASS);
89 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EINA_FALSE);
90 }
91
92 //If there is a child, go there
93 if (pd && pd->subobjs)
94 {
95 it->current = eina_list_data_get(pd->subobjs);
96 goto deliver;
97 }
98
99 //If there is no child, then iterate up the parents until we find a widget with a next widget
100 runner = it->current;
101 do
102 {
103 Efl_Ui_Widget *tmp = _next_widget(runner);
104
105 if (tmp)
106 {
107 it->current = tmp;
108 goto deliver;
109 }
110
111 runner = _fetch_parent_widget(runner);
112 }
113 while(runner && runner != it->origin);
114
115 //Reaching this point here means that there is no widget left, as there is no more parent we can explore
116 it->current = NULL;
117
118deliver:
119 *data = (void*)it->current;
120 return !!it->current;
121}
122
123EAPI Eina_Iterator*
124efl_ui_widget_tree_iterator(Efl_Ui_Widget *obj)
125{
126 ELM_WIDGET_DATA_GET_OR_RETURN(obj, pd, NULL);
127 Widget_Iterator *it = iter_init(obj);
128 it->iterator.next = FUNC_ITERATOR_NEXT(_widget_next);
129
130 return &it->iterator;
131}
132
133static Eina_Bool
134_only_widget(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
135{
136 return efl_isa(data, EFL_UI_WIDGET_CLASS);
137}
138
139EAPI Eina_Iterator*
140efl_ui_widget_tree_widget_iterator(Efl_Ui_Widget *obj)
141{
142 Eina_Iterator *tree_iterator = efl_ui_widget_tree_iterator(obj);
143 ELM_WIDGET_DATA_GET_OR_RETURN(obj, pd, NULL);
144
145 return eina_iterator_filter_new(tree_iterator, _only_widget, NULL, NULL);
146}
147
148static Eina_Bool
149_parent_next(Widget_Iterator *it, void **data)
150{
151 if (!it->current)
152 {
153 *data = it->origin;
154 it->current = *data;
155 }
156 else
157 {
158 Efl_Ui_Widget *parent = efl_ui_widget_parent_get(it->current);
159
160 *data = parent;
161 it->current = parent;
162 }
163
164 return !!*data;
165}
166
167EAPI Eina_Iterator*
168efl_ui_widget_parent_iterator(Efl_Ui_Widget *obj)
169{
170 ELM_WIDGET_DATA_GET_OR_RETURN(obj, pd, NULL);
171 Widget_Iterator *it = iter_init(obj);
172 it->iterator.next = FUNC_ITERATOR_NEXT(_parent_next);
173 return &it->iterator;
174}