summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2014-03-24 17:59:50 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2014-03-24 18:02:03 +0900
commitc336820fb032fc5efff93cf91e4ed0a6183b032a (patch)
tree5764619e8d2ad93f32a94ca3d14457fd96ff7582 /src/modules
parent54855a435e781f3f91c8c6dc3a76131e83cab52b (diff)
Revert "adding focus direction for gengrid"
This reverts commit 4fe82cc740eda0c6b50ee09aedcf173aac1e775d.
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/Makefile.am3
-rw-r--r--src/modules/gengrid_focus_hook/Makefile.am38
-rw-r--r--src/modules/gengrid_focus_hook/gengrid_focus_hook.c491
3 files changed, 1 insertions, 531 deletions
diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am
index 7b9697058..00fbcc05c 100644
--- a/src/modules/Makefile.am
+++ b/src/modules/Makefile.am
@@ -6,5 +6,4 @@ prefs \
6test_entry \ 6test_entry \
7test_map \ 7test_map \
8access_output \ 8access_output \
9datetime_input_ctxpopup \ 9datetime_input_ctxpopup
10gengrid_focus_hook
diff --git a/src/modules/gengrid_focus_hook/Makefile.am b/src/modules/gengrid_focus_hook/Makefile.am
deleted file mode 100644
index 54d5b48dd..000000000
--- a/src/modules/gengrid_focus_hook/Makefile.am
+++ /dev/null
@@ -1,38 +0,0 @@
1
2MAINTAINERCLEANFILES = Makefile.in
3
4AM_CPPFLAGS = \
5-DELM_INTERNAL_API_ARGESFSDFEFC=1 \
6-I. \
7-I$(top_builddir) \
8-I$(top_srcdir) \
9-I$(top_srcdir)/src/lib \
10-I$(top_builddir)/src/lib \
11-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
12-DPACKAGE_LIB_DIR=\"$(libdir)\" \
13@ELEMENTARY_CFLAGS@ \
14@ELEMENTARY_X_CFLAGS@ \
15@ELEMENTARY_FB_CFLAGS@ \
16@ELEMENTARY_SDL_CFLAGS@ \
17@ELEMENTARY_WIN32_CFLAGS@ \
18@ELEMENTARY_WINCE_CFLAGS@ \
19@ELEMENTARY_ELOCATION_CFLAGS@ \
20@ELEMENTARY_EWEATHER_CFLAGS@ \
21@ELEMENTARY_WEB_CFLAGS@ \
22@ELEMENTARY_EMAP_CFLAGS@ \
23@ELEMENTARY_WAYLAND_CFLAGS@ \
24@ELEMENTARY_EMAP_CFLAGS@ \
25@EVIL_CFLAGS@
26
27if ELEMENTARY_WINDOWS_BUILD
28AM_CPPFLAGS += -DELEMENTARY_BUILD
29endif
30
31pkgdir = $(libdir)/elementary/modules/gengrid_focus_hook/$(MODULE_ARCH)
32pkg_LTLIBRARIES = module.la
33
34module_la_SOURCES = gengrid_focus_hook.c
35
36module_la_LIBADD = @ELEMENTARY_LIBS@ $(top_builddir)/src/lib/libelementary.la
37module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
38module_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/src/modules/gengrid_focus_hook/gengrid_focus_hook.c b/src/modules/gengrid_focus_hook/gengrid_focus_hook.c
deleted file mode 100644
index 3c1d69270..000000000
--- a/src/modules/gengrid_focus_hook/gengrid_focus_hook.c
+++ /dev/null
@@ -1,491 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4#include <Elementary.h>
5#include <Elementary_Cursor.h>
6#include "elm_priv.h"
7#include "elm_widget_gengrid.h"
8
9#include <limits.h>
10
11#define GG_IT(_it) (_it->item)
12
13#define EINA_INLIST_REVERSE_FOREACH_INSIDE(list, it) \
14 for (it = NULL, it = (list ? _EINA_INLIST_CONTAINER(it, list) : NULL); it; \
15 it = (EINA_INLIST_GET(it)->prev \
16 ? _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(it)->prev) \
17 : NULL))
18
19#define EINA_LIST_REVERSE_FOREACH_INSIDE(list, l, data) \
20 for (l = list, data = eina_list_data_get(l); l; \
21 l = eina_list_prev(l), data = eina_list_data_get(l))
22
23#define WEIGHT_MAX ((double)INT_MAX / (double)1000000)
24
25/**
26 * Find the first parent of object.
27 * Parent must be type of elm_gengrid.
28 *
29 * @param base
30 *
31 * @return
32 */
33static const Evas_Object *
34_find_gengrid_parent_item(const Evas_Object *base)
35{
36 const Evas_Object *res = NULL;
37 if (base)
38 {
39 const Evas_Object *parent = NULL;
40 parent = elm_widget_parent_get(base);
41
42 while (parent)
43 {
44 if (evas_object_smart_type_check(parent, "elm_gengrid"))
45 {
46 res = parent;
47 break;
48 }
49 parent = elm_widget_parent_get(parent);
50 }
51 }
52 return res;
53}
54
55static Eina_Bool
56_can_focus(const Evas_Object *obj)
57{
58 if (obj && elm_object_focus_allow_get(obj) && elm_widget_can_focus_get(obj))
59 return EINA_TRUE;
60 return EINA_FALSE;
61}
62
63static Eina_List *
64_get_contents(const Evas_Object *obj)
65{
66 Eina_List *res = NULL;
67 if (!obj) return NULL;
68
69 if (evas_object_smart_type_check(obj, "elm_layout"))
70 {
71 Evas_Object *edje = elm_layout_edje_get(obj);
72
73 if (edje)
74 {
75 const Eina_List *l = NULL;
76 const char *key;
77 const Eina_List *contents =
78 elm_widget_stringlist_get(edje_object_data_get(edje, "contents"));
79
80 EINA_LIST_FOREACH(contents, l, key)
81 {
82 if (key)
83 {
84 const Evas_Object *child =
85 edje_object_part_swallow_get(edje, key);
86 if (child)
87 {
88 Eina_List *l1 = NULL;
89 res = eina_list_append(res, child);
90
91 l1 = _get_contents(child);
92 if (l1) res = eina_list_merge(res, l1);
93 }
94 }
95 }
96 }
97 }
98 return res;
99}
100
101static Eina_List *
102_gengrid_item_contents_get(const Elm_Gen_Item *it)
103{
104 Eina_List *res = NULL;
105 Eina_List *l = NULL;
106 Evas_Object *child = NULL;
107 EINA_LIST_FOREACH(it->content_objs, l, child)
108 {
109 if (child)
110 {
111 Eina_List *l1 = NULL;
112 res = eina_list_append(res, child);
113
114 l1 = _get_contents(child);
115 if (l1) res = eina_list_merge(res, l1);
116 }
117 }
118 return res;
119}
120
121static const Evas_Object *
122_find_focusable_object(const Elm_Gen_Item *it,
123 const Evas_Object *base,
124 Elm_Focus_Direction dir)
125{
126 const Evas_Object *obj = NULL;
127 Eina_List *l = NULL;
128 Eina_List *contents = NULL;
129
130 if (!it) return NULL;
131
132 contents = _gengrid_item_contents_get(it);
133 if (contents)
134 {
135 if (base)
136 {
137 l = eina_list_data_find_list(contents, base);
138 obj = base;
139 }
140
141 if ((dir == ELM_FOCUS_LEFT) || (dir == ELM_FOCUS_UP))
142 {
143 if (l) l = eina_list_prev(l);
144 else l = eina_list_last(contents);
145
146 while (l)
147 {
148 obj = eina_list_data_get(l);
149 if (_can_focus(obj)) break;
150 obj = NULL;
151 l = eina_list_prev(l);
152 }
153 }
154 else if ((dir == ELM_FOCUS_RIGHT) || (dir == ELM_FOCUS_DOWN))
155 {
156 if (l) l = eina_list_next(l);
157 else l = contents;
158 while (l)
159 {
160 obj = eina_list_data_get(l);
161 if (_can_focus(obj)) break;
162 obj = NULL;
163 l = eina_list_next(l);
164 }
165 }
166 eina_list_free(contents);
167 }
168 return obj;
169}
170
171
172
173static Eina_Bool
174_check_item_contains(Elm_Gen_Item *it, const Evas_Object *base)
175{
176 Eina_Bool res = EINA_FALSE;
177 Eina_List *contents = NULL;
178 contents = _gengrid_item_contents_get(it);
179
180 if (contents)
181 {
182 const Eina_List *l = NULL;
183 Evas_Object *content = NULL;
184
185 // loop contents (Evas_Object) of item
186 EINA_LIST_FOREACH(contents, l, content)
187 {
188 if (content == base)
189 {
190 res = EINA_TRUE;
191 break;
192 }
193 }
194 eina_list_free(contents);
195 }
196 return res;
197}
198
199static Elm_Gen_Item *
200_find_item_for_base(const Evas_Object *obj,
201 const Evas_Object *base)
202{
203 ELM_GENGRID_CHECK(obj) EINA_FALSE;
204 ELM_GENGRID_DATA_GET(obj, sd);
205 Elm_Gen_Item *res = NULL;
206 Elm_Gen_Item *it = (Elm_Gen_Item *)(sd->last_selected_item);
207
208 if (it && (_check_item_contains(it, base))) res = it;
209 else
210 { // try find in all
211 EINA_INLIST_FOREACH(sd->items, it)
212 {
213 if (it && _check_item_contains(it, base))
214 {
215 res = it;
216 break;
217 }
218 }
219 }
220 return res;
221}
222
223static Eina_Bool
224_gengrid_self_focus_item_get(const Evas_Object *obj, const Evas_Object *base,
225 // list of Elm_Gen_Items
226 const Eina_List *items,
227 void *(*list_data_get)(const Eina_List *l) EINA_UNUSED,
228 double degree, Evas_Object **direction,
229 double *weight)
230{
231 Evas_Coord ox, oy;
232 Evas_Coord vw, vh;
233 const Evas_Object *res_obj = NULL;
234 Elm_Focus_Direction dir = ELM_FOCUS_UP;
235 unsigned int items_count = 0;
236 unsigned int columns = 0, items_visible = 0;
237 unsigned int items_row = 0, items_col = 0, rows = 0;
238 int new_position = 0;
239 int cx = 0;
240 int cy = 0;
241 int focused_pos = 0;
242 Elm_Gen_Item *it = NULL;
243 Elm_Gen_Item *it_res = NULL;
244 Eina_List *list = NULL;
245 Eina_List *l = NULL;
246 Elm_Gen_Item *focused_item = NULL;
247 ELM_GENGRID_CHECK(obj) EINA_FALSE;
248 ELM_GENGRID_DATA_GET(obj, sd);
249
250 if ((!direction) || (!weight) || (!base) || (!items)) return EINA_FALSE;
251
252 evas_object_geometry_get(sd->pan_obj, &ox, &oy, &vw, &vh);
253
254 focused_item = _find_item_for_base(obj, base);
255 if (!focused_item) return EINA_FALSE;
256
257 if (degree == 0) dir = ELM_FOCUS_UP;
258 else if (degree == 90) dir = ELM_FOCUS_RIGHT;
259 else if (degree == 180) dir = ELM_FOCUS_DOWN;
260 else if (degree == 270) dir = ELM_FOCUS_LEFT;
261 else return EINA_FALSE;
262
263 res_obj = _find_focusable_object(focused_item, base, dir);
264 if (res_obj && (res_obj != base))
265 {
266 *direction = (Evas_Object *)res_obj;
267 *weight = WEIGHT_MAX;
268 return EINA_TRUE;
269 }
270
271 focused_pos = focused_item->position - 1;
272
273 items_count = sd->item_count -
274 eina_list_count(sd->group_items) + sd->items_lost;
275 if (sd->horizontal)
276 {
277 if (sd->item_height > 0) items_visible = vh / sd->item_height;
278 if (items_visible < 1) items_visible = 1;
279
280 columns = items_count / items_visible;
281 if (items_count % items_visible) columns++;
282
283 items_row = items_visible;
284 if (items_row > sd->item_count) items_row = sd->item_count;
285
286 cx = focused_pos / items_row;
287 cy = focused_pos % items_row;
288 }
289 else
290 {
291 if (sd->item_width > 0) items_visible = vw / sd->item_width;
292 if (items_visible < 1) items_visible = 1;
293
294 rows = items_count / items_visible;
295 if (items_count % items_visible) rows++;
296
297 items_col = items_visible;
298 if (items_col > sd->item_count) items_col = sd->item_count;
299
300 cy = focused_pos / items_col;
301 cx = focused_pos % items_col;
302 }
303
304
305 if (dir == ELM_FOCUS_UP) cy--;
306 else if (dir == ELM_FOCUS_RIGHT) cx++;
307 else if (dir == ELM_FOCUS_DOWN) cy++;
308 else if (dir == ELM_FOCUS_LEFT) cx--;
309
310 if (cx < 0 || cy < 0) return EINA_FALSE;
311
312 if (sd->horizontal)
313 {
314 if ((cy > (int)(items_row - 1)) ||
315 (cx > (int)(columns - 1))) return EINA_FALSE;
316 new_position = items_row * cx + cy;
317 }
318 else
319 {
320 if ((cx > (int)(items_col - 1)) ||
321 (cy > (int)(rows - 1))) return EINA_FALSE;
322 new_position = cx + items_col * cy;
323 }
324
325 if (new_position > (int)(items_count - 1)) return EINA_FALSE;
326
327 focused_pos++;
328 new_position++;
329
330 list = eina_list_data_find_list(items, focused_item);
331
332 if (!list) return EINA_FALSE;
333
334 if (new_position > focused_pos)
335 {
336 /// New position should be after focused
337 EINA_LIST_FOREACH(list, l, it)
338 {
339 if (it->position == new_position)
340 {
341 it_res = it;
342 break;
343 }
344 }
345 }
346 else if (new_position < focused_pos)
347 {
348 /// New position should be before focused
349 EINA_LIST_REVERSE_FOREACH_INSIDE(list, l, it)
350 {
351 if (it->position == new_position)
352 {
353 it_res = it;
354 break;
355 }
356 }
357 }
358 else return EINA_FALSE;
359
360 if (it_res)
361 {
362 res_obj = _find_focusable_object(it_res, base, dir);
363 *direction = (Evas_Object *)res_obj;
364 *weight = WEIGHT_MAX;
365 return EINA_TRUE;
366 }
367 return EINA_FALSE;
368}
369
370static Eina_Bool
371_gengrid_focus_list_direction_get(const Evas_Object *obj,
372 const Evas_Object *base,
373 // list of Elm_Gen_Items
374 const Eina_List *items,
375 void *(*list_data_get)(const Eina_List *l),
376 double degree, Evas_Object **direction,
377 double *weight)
378{
379 const Eina_List *l = NULL;
380 Evas_Object *current_best = NULL;
381 ELM_GENGRID_CHECK(obj) EINA_FALSE;
382
383 if ((!direction) || (!weight) || (!base) || (!items)) return EINA_FALSE;
384
385 l = items;
386 current_best = *direction;
387
388 // loop items Elm_Gen_Item
389 for (; l; l = eina_list_next(l))
390 {
391 Eina_List *contents = NULL;
392 Elm_Gen_Item *it = list_data_get(l);
393 contents = _gengrid_item_contents_get(it);
394 if (contents)
395 {
396 const Eina_List *l2 = NULL;
397 Evas_Object *content = NULL;
398
399 // loop contents (Evas_Object) of item
400 EINA_LIST_FOREACH(contents, l2, content)
401 {
402 // if better element than set new sd->focused and sd->selected
403 elm_widget_focus_direction_get(content, base, degree,
404 direction, weight);
405 }
406 eina_list_free(contents);
407 }
408 }
409 if (current_best != *direction) return EINA_TRUE;
410 return EINA_FALSE;
411}
412
413EAPI void
414gen_focus_direction(Eo *obj, void *_pd, va_list *list)
415{
416 Eina_List *items = NULL;
417 const Evas_Object *parent = NULL;
418 void *(*list_data_get)(const Eina_List * list);
419 Eina_List *(*list_free)(Eina_List * list);
420 Elm_Gengrid_Smart_Data *sd = _pd;
421 Eina_Bool (*list_direction_get)(const Evas_Object * obj, const Evas_Object * base,
422 const Eina_List * items, void * (*list_data_get)(const Eina_List * l),
423 double degree, Evas_Object * *direction, double * weight);
424
425 Evas_Object *base = va_arg(*list, Evas_Object *);
426 double degree = va_arg(*list, double);
427 Evas_Object **direction = va_arg(*list, Evas_Object **);
428 double *weight = va_arg(*list, double *);
429 Eina_Bool *ret = va_arg(*list, Eina_Bool *);
430
431 if (!sd)
432 {
433 *ret = EINA_FALSE;
434 return;
435 }
436
437 *ret = EINA_FALSE;
438 list_data_get = NULL;
439 list_direction_get = NULL;
440 list_free = NULL;
441 parent = _find_gengrid_parent_item(base);
442
443 /// If focused is subobject of this gengrid then we selected next
444 /// in direction
445 if (obj == parent)
446 {
447 items = elm_gengrid_realized_items_get(obj);
448 list_data_get = NULL;
449 list_direction_get = _gengrid_self_focus_item_get;
450 list_free = eina_list_free;
451 }
452
453 if (!items)
454 {
455 items = (Eina_List *)(elm_object_focus_custom_chain_get(obj));
456 list_data_get = eina_list_data_get;
457 list_direction_get = elm_widget_focus_list_direction_get;
458 list_free = NULL;
459 }
460
461 if (!items)
462 {
463 items = elm_gengrid_realized_items_get(obj);
464 list_data_get = eina_list_data_get;
465 list_direction_get = _gengrid_focus_list_direction_get;
466 list_free = eina_list_free;
467 }
468
469 if (!items)
470 {
471 *ret = EINA_FALSE;
472 return;
473 }
474
475 *ret = list_direction_get(obj, base, items, list_data_get, degree,
476 direction, weight);
477 if (list_free) list_free(items);
478}
479
480// module api funcs needed
481EAPI int
482elm_modapi_init(void *m EINA_UNUSED)
483{
484 return 1; // succeed always
485}
486
487EAPI int
488elm_modapi_shutdown(void *m EINA_UNUSED)
489{
490 return 1; // succeed always
491}