summaryrefslogtreecommitdiff
path: root/src/lib/elementary/efl_ui_panel.c
diff options
context:
space:
mode:
authorWoochanlee <wc0917.lee@samsung.com>2018-12-20 11:32:28 +0900
committerJaehyun Cho <jae_hyun.cho@samsung.com>2018-12-20 11:32:28 +0900
commitd9a222ecf59622ec9cf80a908b0a987d18f87b0f (patch)
tree0308b4cb7934e65a51c9cdda7b436ade745b527c /src/lib/elementary/efl_ui_panel.c
parent2e2c2250937a7ea333f5ef927655dce0ba1478ff (diff)
Intruduce Efl.Ui.Panel (Create Efl Ui Widget from elm widget(elm_panel))
Summary: Create Efl Ui Widget from elm widget(elm_panel) Test Plan: elementary_test -> efl_ui_panel Reviewers: woohyun, Jaehyun_Cho, segfaultxavi Reviewed By: Jaehyun_Cho, segfaultxavi Subscribers: segfaultxavi, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D7238
Diffstat (limited to 'src/lib/elementary/efl_ui_panel.c')
-rw-r--r--src/lib/elementary/efl_ui_panel.c1386
1 files changed, 1386 insertions, 0 deletions
diff --git a/src/lib/elementary/efl_ui_panel.c b/src/lib/elementary/efl_ui_panel.c
new file mode 100644
index 0000000..06d3323
--- /dev/null
+++ b/src/lib/elementary/efl_ui_panel.c
@@ -0,0 +1,1386 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_ACCESS_OBJECT_PROTECTED
6#define EFL_ACCESS_WIDGET_ACTION_PROTECTED
7#define EFL_UI_FOCUS_LAYER_PROTECTED
8#define EFL_PART_PROTECTED
9
10#include <Elementary.h>
11
12#include "elm_priv.h"
13#include "efl_ui_panel_private.h"
14
15#include "els_box.h"
16
17#include "elm_part_helper.h"
18
19#define MY_CLASS EFL_UI_PANEL_CLASS
20
21#define MY_CLASS_NAME "Efl.Ui.Panel"
22
23static const char ACCESS_OUTLINE_PART[] = "access.outline";
24static const char SIG_TOGGLED[] = "toggled";
25static const char SIG_SCROLL[] = "scroll";
26
27static const Evas_Smart_Cb_Description _smart_callbacks[] = {
28 {SIG_TOGGLED, ""},
29 {SIG_SCROLL, ""},
30 {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
31 {SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
32 {NULL, NULL}
33};
34static void _panel_toggle(void *, Evas_Object *, const char *,const char *);
35static Eina_Bool _key_action_toggle(Evas_Object *obj, const char *params);
36static void _drawer_open(Evas_Object *, Evas_Coord , Evas_Coord , Eina_Bool );
37static void _drawer_close(Evas_Object *, Evas_Coord , Evas_Coord , Eina_Bool);
38
39static const Elm_Action key_actions[] = {
40 {"toggle", _key_action_toggle},
41 {NULL, NULL}
42};
43
44static void
45_mirrored_set(Evas_Object *obj,
46 Eina_Bool rtl)
47{
48 EFL_UI_PANEL_DATA_GET(obj, sd);
49
50 if ((sd->content) && (efl_isa(sd->content, EFL_UI_WIDGET_CLASS)))
51 efl_ui_mirrored_set(sd->content, rtl);
52 efl_ui_panel_orient_set(obj, efl_ui_panel_orient_get(obj));
53}
54
55EOLIAN static void
56_efl_ui_panel_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Panel_Data *sd)
57{
58 Evas_Coord mw = 0, mh = 0;
59
60 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
61
62 if (sd->delete_me) return;
63
64 if (sd->scrollable)
65 {
66 if (sd->hidden) _drawer_close(obj, wd->w, wd->h, EINA_FALSE);
67 else _drawer_open(obj, wd->w, wd->h, EINA_FALSE);
68 }
69
70 evas_object_smart_calculate(sd->bx);
71 edje_object_size_min_calc(wd->resize_obj, &mw, &mh);
72 evas_object_size_hint_min_set(obj, mw, mh);
73 evas_object_size_hint_max_set(obj, -1, -1);
74}
75
76static char *
77_access_state_cb(void *data, Evas_Object *obj EINA_UNUSED)
78{
79 EFL_UI_PANEL_DATA_GET(data, sd);
80
81 if (!sd->hidden) return strdup(E_("state: opened"));
82 else return strdup(E_("state: closed"));
83
84 return NULL;
85}
86
87static Evas_Object *
88_access_object_get(const Evas_Object *obj, const char *part)
89{
90 Evas_Object *po, *ao, *o;
91 EFL_UI_PANEL_DATA_GET(obj, sd);
92
93 o = elm_layout_edje_get(sd->scr_ly);
94 edje_object_freeze(o);
95 po = (Evas_Object *)edje_object_part_object_get(o, part);
96 edje_object_thaw(o);
97 ao = evas_object_data_get(po, "_part_access_obj");
98
99 return ao;
100}
101
102static void
103_access_activate_cb(void *data,
104 Evas_Object *part_obj EINA_UNUSED,
105 Elm_Object_Item *item EINA_UNUSED)
106{
107 efl_ui_panel_hidden_set(data, EINA_TRUE);
108}
109
110static void
111_access_obj_process(Evas_Object *obj, Eina_Bool is_access)
112{
113 Evas_Object *ao;
114 EFL_UI_PANEL_DATA_GET(obj, sd);
115
116 if (is_access)
117 {
118 ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
119 if (!ao)
120 {
121 ao = _elm_access_edje_object_part_object_register
122 (obj, elm_layout_edje_get(sd->scr_ly), ACCESS_OUTLINE_PART);
123 _elm_access_text_set(_elm_access_info_get(ao),
124 ELM_ACCESS_TYPE, E_("A panel is open"));
125 _elm_access_text_set(_elm_access_info_get(ao),
126 ELM_ACCESS_CONTEXT_INFO, E_("Double tap to close panel menu"));
127 _elm_access_activate_callback_set
128 (_elm_access_info_get(ao), _access_activate_cb, obj);
129 }
130 }
131 else
132 {
133 _elm_access_edje_object_part_object_unregister
134 (obj, elm_layout_edje_get(sd->scr_ly), ACCESS_OUTLINE_PART);
135 }
136}
137
138static void
139_orient_set_do(Evas_Object *obj)
140{
141 EFL_UI_PANEL_DATA_GET(obj, sd);
142 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
143
144 switch (sd->orient)
145 {
146 case EFL_UI_PANEL_ORIENT_TOP:
147 elm_widget_theme_element_set(obj, "top");
148 break;
149 case EFL_UI_PANEL_ORIENT_BOTTOM:
150 elm_widget_theme_element_set(obj, "bottom");
151 break;
152 case EFL_UI_PANEL_ORIENT_LEFT:
153 elm_widget_theme_element_set(obj, "left");
154 break;
155 case EFL_UI_PANEL_ORIENT_RIGHT:
156 elm_widget_theme_element_set(obj, "right");
157 break;
158 }
159
160 efl_ui_widget_theme_apply(obj);
161
162 /* access */
163 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
164 {
165 Evas_Object *ao;
166 ao = _elm_access_edje_object_part_object_register
167 (obj, wd->resize_obj, "btn_icon");
168 _elm_access_text_set(_elm_access_info_get(ao),
169 ELM_ACCESS_TYPE, E_("panel button"));
170 _elm_access_callback_set
171 (_elm_access_info_get(ao), ELM_ACCESS_STATE, _access_state_cb, obj);
172 }
173}
174
175static void
176_scrollable_layout_theme_set(Eo *obj, Efl_Ui_Panel_Data *sd)
177{
178 switch (sd->orient)
179 {
180 case EFL_UI_PANEL_ORIENT_TOP:
181 elm_widget_theme_element_set(sd->scr_ly, "scrollable/top");
182 break;
183 case EFL_UI_PANEL_ORIENT_BOTTOM:
184 elm_widget_theme_element_set(sd->scr_ly, "scrollable/bottom");
185 break;
186 case EFL_UI_PANEL_ORIENT_LEFT:
187 elm_widget_theme_element_set(sd->scr_ly, "scrollable/left");
188 break;
189 case EFL_UI_PANEL_ORIENT_RIGHT:
190 elm_widget_theme_element_set(sd->scr_ly, "scrollable/right");
191 break;
192 }
193
194 efl_ui_widget_theme_apply(sd->scr_ly);
195
196 /* access */
197 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
198 _access_obj_process(obj, EINA_TRUE);
199}
200
201EOLIAN static Efl_Ui_Theme_Apply_Result
202_efl_ui_panel_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Panel_Data *sd)
203{
204 const char *str;
205 Evas_Coord minw = 0, minh = 0;
206
207 Efl_Ui_Theme_Apply_Result int_ret = EFL_UI_THEME_APPLY_RESULT_FAIL;
208
209 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_UI_THEME_APPLY_RESULT_FAIL);
210
211 int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
212 if (!int_ret) return EFL_UI_THEME_APPLY_RESULT_FAIL;
213
214 _mirrored_set(obj, efl_ui_mirrored_get(obj));
215
216 if (sd->scrollable)
217 {
218 const char *handler_size;
219 elm_widget_theme_object_set(obj, sd->scr_edje, "panel", NULL,
220 elm_widget_style_get(obj));
221 handler_size = edje_object_data_get(sd->scr_edje, "handler_size");
222 if (handler_size)
223 sd->handler_size = (int) (elm_object_scale_get(obj)) * (atoi(handler_size));
224 }
225 else
226 {
227 str = edje_object_data_get
228 (wd->resize_obj, "focus_highlight");
229 if ((str) && (!strcmp(str, "on")))
230 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
231 else
232 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
233
234 evas_object_hide(sd->event);
235 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
236 evas_object_size_hint_min_set(sd->event, minw, minh);
237
238 if (edje_object_part_exists(wd->resize_obj, "efl.swallow.event"))
239 efl_content_set(efl_part(efl_super(obj, MY_CLASS), "efl.swallow.event"), sd->event);
240 }
241
242 if (efl_finalized_get(obj))
243 elm_layout_sizing_eval(obj);
244
245 return int_ret;
246}
247
248static void
249_box_layout_cb(Evas_Object *o,
250 Evas_Object_Box_Data *_pd,
251 void *data EINA_UNUSED)
252{
253 _els_box_layout(o, _pd, EINA_TRUE, EINA_FALSE, EINA_FALSE);
254}
255
256static void
257_handler_open(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
258{
259 EFL_UI_PANEL_DATA_GET(obj, sd);
260
261 if (sd->handler_size == 0) return;
262
263 switch (sd->orient)
264 {
265 case EFL_UI_PANEL_ORIENT_TOP:
266 elm_interface_scrollable_region_bring_in
267 (obj, 0, (h * sd->content_size_ratio) - sd->handler_size, w, h);
268 break;
269 case EFL_UI_PANEL_ORIENT_BOTTOM:
270 elm_interface_scrollable_region_bring_in
271 (obj, 0, sd->handler_size, w, h);
272 break;
273 case EFL_UI_PANEL_ORIENT_LEFT:
274 elm_interface_scrollable_region_bring_in
275 (obj, (w * sd->content_size_ratio) - sd->handler_size, 0, w, h);
276 break;
277 case EFL_UI_PANEL_ORIENT_RIGHT:
278 elm_interface_scrollable_region_bring_in
279 (obj, sd->handler_size, 0, w, h);
280 break;
281 }
282}
283
284static void
285_drawer_open(Evas_Object *obj, Evas_Coord w, Evas_Coord h, Eina_Bool anim)
286{
287 EFL_UI_PANEL_DATA_GET(obj, sd);
288 int x = 0, y = 0;
289
290 if (sd->freeze)
291 {
292 elm_interface_scrollable_movement_block_set
293 (obj, EFL_UI_SCROLL_BLOCK_NONE);
294 sd->freeze = EINA_FALSE;
295 elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
296 }
297
298 switch (sd->orient)
299 {
300 case EFL_UI_PANEL_ORIENT_TOP:
301 break;
302 case EFL_UI_PANEL_ORIENT_LEFT:
303 if (efl_ui_mirrored_get(obj))
304 x = w * sd->content_size_ratio;
305 break;
306
307 case EFL_UI_PANEL_ORIENT_BOTTOM:
308 y = h * sd->content_size_ratio;
309 break;
310
311 case EFL_UI_PANEL_ORIENT_RIGHT:
312 if (!efl_ui_mirrored_get(obj))
313 x = w * sd->content_size_ratio;
314 break;
315 }
316
317 if (anim)
318 elm_interface_scrollable_region_bring_in
319 (obj, x, y, w, h);
320 else
321 elm_interface_scrollable_content_region_show
322 (obj, x, y, w, h);
323}
324
325static void
326_drawer_close(Evas_Object *obj, Evas_Coord w, Evas_Coord h, Eina_Bool anim)
327{
328 EFL_UI_PANEL_DATA_GET(obj, sd);
329 int x = 0, y = 0, cx, cy;
330 Eina_Bool horizontal = EINA_FALSE;
331
332 elm_widget_tree_unfocusable_set(obj, EINA_TRUE);
333 switch (sd->orient)
334 {
335 case EFL_UI_PANEL_ORIENT_TOP:
336 y = h * sd->content_size_ratio;
337 break;
338
339 case EFL_UI_PANEL_ORIENT_LEFT:
340 if (!efl_ui_mirrored_get(obj))
341 x = w * sd->content_size_ratio;
342 horizontal = EINA_TRUE;
343 break;
344
345 case EFL_UI_PANEL_ORIENT_BOTTOM:
346 break;
347
348 case EFL_UI_PANEL_ORIENT_RIGHT:
349 if (efl_ui_mirrored_get(obj))
350 x = w * sd->content_size_ratio;
351 horizontal = EINA_TRUE;
352 break;
353 }
354
355 elm_interface_scrollable_content_pos_get(obj, &cx, &cy);
356
357 if ((x == cx) && (y == cy))
358 {
359 if (!sd->freeze)
360 {
361 if (horizontal)
362 elm_interface_scrollable_movement_block_set
363 (obj, EFL_UI_SCROLL_BLOCK_HORIZONTAL);
364 else
365 elm_interface_scrollable_movement_block_set
366 (obj, EFL_UI_SCROLL_BLOCK_VERTICAL);
367 sd->freeze = EINA_TRUE;
368 elm_layout_signal_emit(sd->scr_ly, "efl,state,content,hidden", "efl");
369 }
370
371 return;
372 }
373
374 if (anim)
375 {
376 if (sd->freeze)
377 {
378 elm_interface_scrollable_movement_block_set
379 (obj, EFL_UI_SCROLL_BLOCK_NONE);
380 sd->freeze = EINA_FALSE;
381 elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
382 }
383 elm_interface_scrollable_region_bring_in(obj, x, y, w, h);
384 }
385 else
386 {
387 elm_interface_scrollable_content_region_show(obj, x, y, w, h);
388 if (!sd->freeze)
389 {
390 if (horizontal)
391 elm_interface_scrollable_movement_block_set
392 (obj, EFL_UI_SCROLL_BLOCK_HORIZONTAL);
393 else
394 elm_interface_scrollable_movement_block_set
395 (obj, EFL_UI_SCROLL_BLOCK_VERTICAL);
396 sd->freeze = EINA_TRUE;
397 elm_layout_signal_emit(sd->scr_ly, "efl,state,content,hidden", "efl");
398 }
399 }
400}
401
402static void
403_panel_toggle(void *data EINA_UNUSED,
404 Evas_Object *obj,
405 const char *emission EINA_UNUSED,
406 const char *source EINA_UNUSED)
407{
408 EFL_UI_PANEL_DATA_GET(obj, sd);
409 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
410 int w, h;
411
412 if (sd->scrollable)
413 {
414 if (elm_widget_disabled_get(obj)) return;
415
416 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
417 if (sd->hidden)
418 {
419 sd->hidden = EINA_FALSE;
420 _drawer_open(obj, w, h, EINA_TRUE);
421 }
422 else
423 {
424 sd->hidden = EINA_TRUE;
425 _drawer_close(obj, w, h, EINA_TRUE);
426 }
427 }
428 else
429 {
430 if (sd->hidden)
431 {
432 elm_layout_signal_emit(obj, "efl,action,show", "efl");
433 sd->hidden = EINA_FALSE;
434 evas_object_repeat_events_set(obj, EINA_FALSE);
435 }
436 else
437 {
438 elm_layout_signal_emit(obj, "efl,action,hide", "efl");
439 sd->hidden = EINA_TRUE;
440 evas_object_repeat_events_set(obj, EINA_TRUE);
441 }
442
443 //if the panel is hidden, make this thing unfocusable
444 elm_widget_tree_unfocusable_set(obj, sd->hidden);
445 edje_object_message_signal_process(wd->resize_obj);
446 }
447
448 efl_ui_focus_layer_enable_set(obj, !sd->hidden);
449 efl_event_callback_call(obj, EFL_UI_PANEL_EVENT_TOGGLED, NULL);
450}
451
452static Eina_Bool
453_state_sync(Evas_Object *obj)
454{
455 EFL_UI_PANEL_DATA_GET(obj, sd);
456 Evas_Coord pos, panel_size, w, h, threshold;
457 Eina_Bool horizontal = EINA_FALSE, reverse = EINA_FALSE;
458
459 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
460
461 if (!evas_object_visible_get(sd->bx)) return EINA_TRUE;
462
463 switch (sd->orient)
464 {
465 case EFL_UI_PANEL_ORIENT_BOTTOM:
466 reverse = EINA_TRUE;
467 case EFL_UI_PANEL_ORIENT_TOP:
468 break;
469
470 case EFL_UI_PANEL_ORIENT_RIGHT:
471 reverse = EINA_TRUE;
472 EINA_FALLTHROUGH;
473 case EFL_UI_PANEL_ORIENT_LEFT:
474 horizontal = EINA_TRUE;
475 break;
476 }
477
478 if (horizontal)
479 {
480 if (w <= 0) return EINA_TRUE;
481
482 panel_size = w * sd->content_size_ratio;
483 elm_interface_scrollable_content_pos_get(obj, &pos, NULL);
484 reverse ^= efl_ui_mirrored_get(obj);
485 }
486 else
487 {
488 if (h <= 0) return EINA_TRUE;
489
490 panel_size = h * sd->content_size_ratio;
491 elm_interface_scrollable_content_pos_get(obj, NULL, &pos);
492 }
493 threshold = (sd->hidden) ? panel_size - (panel_size / 4) : (panel_size / 4);
494
495 if (reverse)
496 {
497 if (pos > panel_size - threshold) sd->hidden = EINA_FALSE;
498 else sd->hidden = EINA_TRUE;
499 }
500 else
501 {
502 if (pos < threshold) sd->hidden = EINA_FALSE;
503 else sd->hidden = EINA_TRUE;
504 }
505
506 return EINA_FALSE;
507}
508
509static Eina_Bool
510_timer_cb(void *data)
511{
512 EFL_UI_PANEL_DATA_GET(data, sd);
513 Evas_Object *obj = data;
514 Evas_Coord w, h;
515
516 sd->timer = NULL;
517
518 if (sd->freeze)
519 {
520 elm_interface_scrollable_movement_block_set
521 (obj, EFL_UI_SCROLL_BLOCK_NONE);
522 sd->freeze = EINA_FALSE;
523 elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
524 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
525 _handler_open(obj, w, h);
526 }
527
528 return ECORE_CALLBACK_CANCEL;
529}
530
531static void
532_event_mouse_up(void *data,
533 Evas *e EINA_UNUSED,
534 Evas_Object *obj EINA_UNUSED,
535 void *event_info)
536{
537 EFL_UI_PANEL_DATA_GET(data, sd);
538 Evas_Event_Mouse_Up *ev = event_info;
539 Evas_Coord x, y, up_x, up_y, minw = 0, minh = 0;
540 evas_object_geometry_get(data, &x, &y, NULL, NULL);
541
542 up_x = ev->canvas.x - x;
543 up_y = ev->canvas.y - y;
544
545 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
546
547 if ((!sd->hidden) && (up_x == sd->down_x) && (up_y == sd->down_y))
548 efl_ui_panel_hidden_set(data, EINA_TRUE);
549}
550
551static void
552_on_mouse_down(void *data,
553 Evas *e EINA_UNUSED,
554 Evas_Object *obj,
555 void *event_info)
556{
557 Efl_Ui_Panel_Data *sd = data;
558 Evas_Event_Mouse_Down *ev = event_info;
559 Evas_Coord finger_size = elm_config_finger_size_get();
560 Evas_Coord x, y, w, h;
561 evas_object_geometry_get(obj, &x, &y, &w, &h);
562 Eina_Bool is_mirrored = efl_ui_mirrored_get(obj);
563
564 sd->down_x = ev->canvas.x - x;
565 sd->down_y = ev->canvas.y - y;
566
567 // if freeze state & mouse down on the edge
568 // then set timer for un-freeze
569 switch (sd->orient)
570 {
571 case EFL_UI_PANEL_ORIENT_TOP:
572 if ((sd->freeze) && (sd->down_y >= 0) && (sd->down_y < finger_size))
573 {
574 ecore_timer_del(sd->timer);
575 sd->timer = ecore_timer_add(0.2, _timer_cb, obj);
576 }
577 break;
578 case EFL_UI_PANEL_ORIENT_BOTTOM:
579 if ((sd->freeze) && (sd->down_y <= h) && (sd->down_y > (h - finger_size)))
580 {
581 ecore_timer_del(sd->timer);
582 sd->timer = ecore_timer_add(0.2, _timer_cb, obj);
583 }
584 break;
585 case EFL_UI_PANEL_ORIENT_LEFT:
586 if ((!is_mirrored && (sd->freeze) && (sd->down_x >= 0) && (sd->down_x < finger_size)) ||
587 ((is_mirrored && (sd->freeze) && (sd->down_x <= w) && (sd->down_x > (w - finger_size)))))
588 {
589 ecore_timer_del(sd->timer);
590 sd->timer = ecore_timer_add(0.2, _timer_cb, obj);
591 }
592 break;
593 case EFL_UI_PANEL_ORIENT_RIGHT:
594 if ((is_mirrored && (sd->freeze) && (sd->down_x >= 0) && (sd->down_x < finger_size)) ||
595 (!is_mirrored && (sd->freeze) && (sd->down_x <= w) && (sd->down_x > (w - finger_size))))
596 {
597 ecore_timer_del(sd->timer);
598 sd->timer = ecore_timer_add(0.2, _timer_cb, obj);
599 }
600 break;
601 }
602}
603
604static void
605_on_mouse_move(void *data,
606 Evas *e EINA_UNUSED,
607 Evas_Object *obj,
608 void *event_info)
609{
610 Efl_Ui_Panel_Data *sd = data;
611 Evas_Event_Mouse_Move *ev = event_info;
612 Evas_Coord x, y, w, h, cur_x, cur_y, finger_size;
613 evas_object_geometry_get(obj, &x, &y, &w, &h);
614 finger_size = elm_config_finger_size_get();
615 Eina_Bool is_mirrored = efl_ui_mirrored_get(obj);
616
617 cur_x = ev->cur.canvas.x - x;
618 cur_y = ev->cur.canvas.y - y;
619
620 // if mouse down on the edge (it means sd->timer is not null)
621 // and move more than finger size
622 // then un-freeze
623 switch (sd->orient)
624 {
625 case EFL_UI_PANEL_ORIENT_TOP:
626 if (sd->timer && ((cur_y - sd->down_y) > finger_size))
627 {
628 elm_interface_scrollable_movement_block_set
629 (obj, EFL_UI_SCROLL_BLOCK_NONE);
630 sd->freeze = EINA_FALSE;
631 elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
632 }
633 break;
634 case EFL_UI_PANEL_ORIENT_BOTTOM:
635 if (sd->timer && ((sd->down_y - cur_y) > finger_size))
636 {
637 elm_interface_scrollable_movement_block_set
638 (obj, EFL_UI_SCROLL_BLOCK_NONE);
639 sd->freeze = EINA_FALSE;
640 elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
641 }
642 break;
643 case EFL_UI_PANEL_ORIENT_LEFT:
644 if ((!is_mirrored && (sd->timer) && ((cur_x - sd->down_x) > finger_size)) ||
645 ((is_mirrored) && (sd->timer) && ((sd->down_x - cur_x) > finger_size)))
646 {
647 elm_interface_scrollable_movement_block_set
648 (obj, EFL_UI_SCROLL_BLOCK_NONE);
649 sd->freeze = EINA_FALSE;
650 elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
651 }
652 break;
653 case EFL_UI_PANEL_ORIENT_RIGHT:
654 if ((is_mirrored && (sd->timer) && ((cur_x - sd->down_x) > finger_size)) ||
655 (!is_mirrored && (sd->timer) && ((sd->down_x - cur_x) > finger_size)))
656 {
657 elm_interface_scrollable_movement_block_set
658 (obj, EFL_UI_SCROLL_BLOCK_NONE);
659 sd->freeze = EINA_FALSE;
660 elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
661 }
662 break;
663 }
664
665 if (!sd->freeze && sd->hidden)
666 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
667}
668
669static void
670_on_mouse_up(void *data,
671 Evas *e EINA_UNUSED,
672 Evas_Object *obj,
673 void *event_info)
674{
675 Efl_Ui_Panel_Data *sd = data;
676 Evas_Event_Mouse_Up *ev = event_info;
677 Evas_Coord w, h;
678 Eina_Bool hidden;
679
680 hidden = sd->hidden;
681 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
682
683 ELM_SAFE_FREE(sd->timer, ecore_timer_del);
684
685 if (_state_sync(obj)) return;
686
687 if (sd->hidden) _drawer_close(obj, w, h, EINA_TRUE);
688 else _drawer_open(obj, w, h, EINA_TRUE);
689
690 if (sd->hidden != hidden)
691 efl_event_callback_legacy_call(obj, EFL_UI_PANEL_EVENT_TOGGLED, NULL);
692
693 if (!sd->freeze && sd->hidden)
694 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
695}
696
697static Eina_Bool
698_key_action_toggle(Evas_Object *obj, const char *params EINA_UNUSED)
699{
700 _panel_toggle(NULL, obj, NULL, NULL);
701 return EINA_TRUE;
702}
703
704// _panel_elm_widget_widget_event
705ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(panel, Efl_Ui_Panel_Data)
706
707EOLIAN static Eina_Bool
708_efl_ui_panel_efl_ui_widget_widget_event(Eo *obj, Efl_Ui_Panel_Data *pd, const Efl_Event *eo_event, Evas_Object *src)
709{
710 if (src != obj) return EINA_FALSE;
711 return _panel_efl_ui_widget_widget_event(obj, pd, eo_event, src);
712}
713
714static Eina_Bool
715_efl_ui_panel_efl_content_content_set(Eo *obj, Efl_Ui_Panel_Data *sd, Efl_Gfx_Entity *content)
716{
717 if (sd->content == content) return EINA_TRUE;
718 if (sd->content)
719 evas_object_box_remove_all(sd->bx, EINA_TRUE);
720 sd->content = content;
721 if (content)
722 {
723 evas_object_box_append(sd->bx, sd->content);
724 evas_object_show(sd->content);
725 if (sd->scrollable)
726 elm_widget_sub_object_add(sd->scr_ly, sd->content);
727 else
728 elm_widget_sub_object_add(obj, sd->content);
729 }
730
731 if (efl_finalized_get(obj))
732 elm_layout_sizing_eval(obj);
733
734 return EINA_TRUE;
735}
736
737static Efl_Gfx_Entity*
738_efl_ui_panel_efl_content_content_get(const Eo *obj EINA_UNUSED, Efl_Ui_Panel_Data *sd)
739{
740 return sd->content;
741}
742
743static Efl_Gfx_Entity*
744_efl_ui_panel_efl_content_content_unset(Eo *obj EINA_UNUSED, Efl_Ui_Panel_Data *sd)
745{
746 Efl_Gfx_Entity *ret = NULL;
747
748 if (!sd->content) return NULL;
749 ret = sd->content;
750
751 evas_object_box_remove_all(sd->bx, EINA_FALSE);
752 if (sd->scrollable)
753 _elm_widget_sub_object_redirect_to_top(sd->scr_ly, sd->content);
754 sd->content = NULL;
755
756 return ret;
757}
758
759EOLIAN static void
760_efl_ui_panel_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Position2D pos)
761{
762 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, pos.x, pos.y))
763 return;
764
765 efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
766 efl_gfx_entity_position_set(sd->hit_rect, pos);
767}
768
769static void
770_scrollable_layout_resize(Eo *obj, Efl_Ui_Panel_Data *sd, Evas_Coord w, Evas_Coord h)
771{
772 switch (sd->orient)
773 {
774 case EFL_UI_PANEL_ORIENT_TOP:
775 case EFL_UI_PANEL_ORIENT_BOTTOM:
776 // vertical
777 evas_object_resize(sd->scr_ly, w, (1 + sd->content_size_ratio) * h);
778 evas_object_size_hint_min_set(sd->scr_panel, w, (sd->content_size_ratio * h));
779 evas_object_size_hint_min_set(sd->scr_event, w, h);
780 break;
781 case EFL_UI_PANEL_ORIENT_LEFT:
782 case EFL_UI_PANEL_ORIENT_RIGHT:
783 // horizontal
784 evas_object_resize(sd->scr_ly, (1 + sd->content_size_ratio) * w, h);
785 evas_object_size_hint_min_set(sd->scr_panel, (sd->content_size_ratio * w), h);
786 evas_object_size_hint_min_set(sd->scr_event, w, h);
787 break;
788 }
789 if (efl_finalized_get(obj))
790 elm_layout_sizing_eval(obj);
791}
792
793EOLIAN static void
794_efl_ui_panel_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Size2D sz)
795{
796 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, sz.w, sz.h))
797 return;
798
799 efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz);
800
801 if (!sd->scrollable) return;
802
803 efl_gfx_entity_size_set(sd->hit_rect, sz);
804 _scrollable_layout_resize(obj, sd, sz.w, sz.h);
805}
806
807EOLIAN static void
808_efl_ui_panel_efl_canvas_group_group_member_add(Eo *obj, Efl_Ui_Panel_Data *sd, Evas_Object *member)
809{
810 efl_canvas_group_member_add(efl_super(obj, MY_CLASS), member);
811
812 if (sd->hit_rect) evas_object_raise(sd->hit_rect);
813}
814
815EOLIAN static void
816_efl_ui_panel_efl_ui_widget_on_access_update(Eo *obj, Efl_Ui_Panel_Data *_pd, Eina_Bool is_access)
817{
818 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
819 Efl_Ui_Panel_Data *sd = _pd;
820
821 if (sd->scrollable)
822 {
823 _access_obj_process(obj, is_access);
824 return;
825 }
826
827 if (is_access)
828 _elm_access_edje_object_part_object_register
829 (obj, wd->resize_obj, "btn_icon");
830 else
831 _elm_access_edje_object_part_object_unregister
832 (obj, wd->resize_obj, "btn_icon");
833}
834
835EOLIAN static Eo *
836_efl_ui_panel_efl_object_constructor(Eo *obj, Efl_Ui_Panel_Data *_pd)
837{
838 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
839
840 obj = efl_constructor(efl_super(obj, MY_CLASS));
841 elm_widget_sub_object_parent_add(obj);
842 elm_widget_can_focus_set(obj, EINA_TRUE);
843
844 _pd->panel_edje = wd->resize_obj;
845
846 efl_ui_widget_theme_apply(obj);
847
848 _pd->bx = evas_object_box_add(evas_object_evas_get(obj));
849 evas_object_box_layout_set(_pd->bx, _box_layout_cb, _pd, NULL);
850 evas_object_show(_pd->bx);
851
852 elm_layout_signal_callback_add
853 (obj, "efl,action,panel,toggle", "*", _panel_toggle, obj);
854
855 _mirrored_set(obj, efl_ui_mirrored_get(obj));
856
857 _pd->event = evas_object_rectangle_add(evas_object_evas_get(obj));
858 evas_object_color_set(_pd->event, 0, 0, 0, 0);
859 evas_object_pass_events_set(_pd->event, EINA_TRUE);
860 elm_widget_sub_object_add(obj, _pd->event);
861
862 /* just to bootstrap and have theme hook to work */
863 if (!elm_layout_theme_set(obj, "panel", "top", elm_widget_style_get(obj)))
864 CRI("Failed to set layout!");
865 else
866 {
867 elm_layout_content_set(obj, "efl.content", _pd->bx);
868
869 if (edje_object_part_exists
870 (wd->resize_obj, "efl.swallow.event"))
871 {
872 Evas_Coord minw = 0, minh = 0;
873
874 elm_coords_finger_size_adjust(1, &minw, 1, &minh);
875 evas_object_size_hint_min_set(_pd->event, minw, minh);
876 efl_content_set(efl_part(efl_super(obj, MY_CLASS), "efl.swallow.event"), _pd->event);
877 }
878 }
879
880 evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
881 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_PANEL);
882
883 efl_ui_focus_layer_behaviour_set(obj, EINA_FALSE, EINA_FALSE);
884
885 return obj;
886}
887
888EOLIAN static void
889_efl_ui_panel_efl_object_destructor(Eo *obj, Efl_Ui_Panel_Data *sd)
890{
891 Evas_Object *child;
892 Eina_List *l;
893
894 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
895
896 sd->delete_me = EINA_TRUE;
897
898 ELM_SAFE_FREE(sd->timer, ecore_timer_del);
899
900 /* let's make our panel object the *last* to be processed, since it
901 * may (smart) parent other sub objects here */
902 EINA_LIST_FOREACH(wd->subobjs, l, child)
903 {
904 if (child == sd->bx)
905 {
906 wd->subobjs =
907 eina_list_demote_list(wd->subobjs, l);
908 break;
909 }
910 }
911
912 efl_destructor(efl_super(obj, MY_CLASS));
913}
914
915EOLIAN static void
916_efl_ui_panel_orient_set(Eo *obj, Efl_Ui_Panel_Data *sd, Efl_Ui_Panel_Orient orient)
917{
918 if (sd->orient == orient) return;
919 sd->orient = orient;
920
921 if (sd->scrollable)
922 {
923 _scrollable_layout_theme_set(obj, sd);
924
925 if (!sd->freeze)
926 {
927 switch (sd->orient)
928 {
929 case EFL_UI_PANEL_ORIENT_TOP:
930 case EFL_UI_PANEL_ORIENT_BOTTOM:
931 elm_interface_scrollable_movement_block_set
932 (obj, EFL_UI_SCROLL_BLOCK_VERTICAL);
933 break;
934 case EFL_UI_PANEL_ORIENT_LEFT:
935 case EFL_UI_PANEL_ORIENT_RIGHT:
936 elm_interface_scrollable_movement_block_set
937 (obj, EFL_UI_SCROLL_BLOCK_HORIZONTAL);
938 break;
939 }
940
941 sd->freeze = EINA_TRUE;
942 elm_layout_signal_emit(sd->scr_ly, "efl,state,content,hidden", "efl");
943 }
944
945 efl_ui_panel_scrollable_content_size_set(obj, sd->content_size_ratio);
946 }
947 else
948 _orient_set_do(obj);
949
950 if (efl_finalized_get(obj))
951 elm_layout_sizing_eval(obj);
952}
953
954EOLIAN static Efl_Ui_Panel_Orient
955_efl_ui_panel_orient_get(const Eo *obj EINA_UNUSED, Efl_Ui_Panel_Data *sd)
956{
957 return sd->orient;
958}
959
960EOLIAN static void
961_efl_ui_panel_hidden_set(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Bool hidden)
962{
963 if (sd->hidden == !!hidden)
964 {
965 if (sd->scrollable && sd->hidden && !sd->freeze)
966 {
967 Evas_Coord w, h;
968 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
969 _drawer_close(obj, w, h, EINA_TRUE);
970 }
971 return;
972 }
973
974 _panel_toggle(NULL, obj, NULL, NULL);
975}
976
977EOLIAN static Eina_Bool
978_efl_ui_panel_hidden_get(const Eo *obj EINA_UNUSED, Efl_Ui_Panel_Data *sd)
979{
980 return sd->hidden;
981}
982
983EOLIAN static void
984_efl_ui_panel_toggle(Eo *obj, Efl_Ui_Panel_Data *_pd EINA_UNUSED)
985{
986 _panel_toggle(NULL, obj, NULL, NULL);
987}
988
989EOLIAN static Eina_Rect
990_efl_ui_panel_efl_ui_widget_interest_region_get(const Eo *obj, Efl_Ui_Panel_Data *sd)
991{
992 Eina_Rect r = {};
993
994 elm_interface_scrollable_content_pos_get(obj, &r.x, &r.y);
995 evas_object_geometry_get(obj, NULL, NULL, &r.w, &r.h);
996 switch (sd->orient)
997 {
998 case EFL_UI_PANEL_ORIENT_TOP:
999 case EFL_UI_PANEL_ORIENT_BOTTOM:
1000 r.h *= sd->content_size_ratio;
1001 break;
1002 case EFL_UI_PANEL_ORIENT_LEFT:
1003 case EFL_UI_PANEL_ORIENT_RIGHT:
1004 r.w *= sd->content_size_ratio;
1005 break;
1006 }
1007 if (r.w < 1) r.w = 1;
1008 if (r.h < 1) r.h = 1;
1009
1010 return r;
1011}
1012
1013static void
1014_anim_stop_cb(Evas_Object *obj, void *data EINA_UNUSED)
1015{
1016 EFL_UI_PANEL_DATA_GET(obj, sd);
1017 Evas_Object *ao;
1018 Evas_Coord pos, w, h, panel_size = 0;
1019 Eina_Bool open = EINA_FALSE, horizontal = EINA_FALSE, reverse = EINA_FALSE;
1020
1021 if (elm_widget_disabled_get(obj)) return;
1022
1023 switch (sd->orient)
1024 {
1025 case EFL_UI_PANEL_ORIENT_BOTTOM:
1026 reverse = EINA_TRUE;
1027 case EFL_UI_PANEL_ORIENT_TOP:
1028 break;
1029
1030 case EFL_UI_PANEL_ORIENT_RIGHT:
1031 reverse = EINA_TRUE;
1032 EINA_FALLTHROUGH;
1033 case EFL_UI_PANEL_ORIENT_LEFT:
1034 horizontal = EINA_TRUE;
1035 break;
1036 }
1037
1038 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1039 if (horizontal)
1040 {
1041 if (w <= 0) return;
1042
1043 panel_size = w * sd->content_size_ratio;
1044 elm_interface_scrollable_content_pos_get(obj, &pos, NULL);
1045 reverse ^= efl_ui_mirrored_get(obj);
1046 }
1047 else
1048 {
1049 if (h <= 0) return;
1050
1051 panel_size = h * sd->content_size_ratio;
1052 elm_interface_scrollable_content_pos_get(obj, NULL, &pos);
1053 }
1054
1055 if (pos == 0) open = !reverse;
1056 else if (pos == panel_size) open = reverse;
1057 else return;
1058
1059 if (open)
1060 {
1061 elm_interface_scrollable_single_direction_set
1062 (obj, ELM_SCROLLER_SINGLE_DIRECTION_HARD);
1063
1064 //focus & access
1065 elm_object_tree_focus_allow_set(obj, EINA_TRUE);
1066 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
1067 {
1068 ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
1069 evas_object_show(ao);
1070 _elm_access_highlight_set(ao);
1071 }
1072 else
1073 elm_object_focus_set(obj, EINA_TRUE);
1074 }
1075 else
1076 {
1077 if (horizontal)
1078 elm_interface_scrollable_movement_block_set
1079 (obj, EFL_UI_SCROLL_BLOCK_HORIZONTAL);
1080 else
1081 elm_interface_scrollable_movement_block_set
1082 (obj, EFL_UI_SCROLL_BLOCK_VERTICAL);
1083 sd->freeze = EINA_TRUE;
1084 elm_layout_signal_emit(sd->scr_ly, "efl,state,content,hidden", "efl");
1085
1086 elm_interface_scrollable_single_direction_set
1087 (obj, ELM_SCROLLER_SINGLE_DIRECTION_NONE);
1088
1089 //focus & access
1090 elm_object_tree_focus_allow_set(obj, EINA_FALSE);
1091 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
1092 {
1093 ao = _access_object_get(obj, ACCESS_OUTLINE_PART);
1094 evas_object_hide(ao);
1095 }
1096 }
1097}
1098
1099static void
1100_scroll_cb(Evas_Object *obj, void *data EINA_UNUSED)
1101{
1102 EFL_UI_PANEL_DATA_GET(obj, sd);
1103 Efl_Ui_Panel_Scroll_Info event;
1104 Evas_Coord x, y, w, h;
1105
1106 if (elm_widget_disabled_get(obj)) return;
1107 // in the case of
1108 // freeze_set(FALSE) -> mouse_up -> freeze_set(TRUE) -> scroll
1109 if (sd->freeze)
1110 {
1111 elm_interface_scrollable_movement_block_set
1112 (obj, EFL_UI_SCROLL_BLOCK_NONE);
1113 sd->freeze = EINA_FALSE;
1114 elm_layout_signal_emit(sd->scr_ly, "efl,state,content,visible", "efl");
1115 }
1116
1117 elm_interface_scrollable_content_pos_get(obj, &x, &y);
1118 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1119
1120 switch (sd->orient)
1121 {
1122 case EFL_UI_PANEL_ORIENT_TOP:
1123 event.rel_x = 1;
1124 event.rel_y = 1 - ((double) y / (double) ((sd->content_size_ratio) * h));
1125 break;
1126 case EFL_UI_PANEL_ORIENT_BOTTOM:
1127 event.rel_x = 1;
1128 event.rel_y = (double) y / (double) ((sd->content_size_ratio) * h);
1129 break;
1130 case EFL_UI_PANEL_ORIENT_LEFT:
1131 if (!efl_ui_mirrored_get(obj))
1132 {
1133 event.rel_x = 1 - ((double) x / (double) ((sd->content_size_ratio) * w));
1134 event.rel_y = 1;
1135 }
1136 else
1137 {
1138 event.rel_x = (double) x / (double) ((sd->content_size_ratio) * w);
1139 event.rel_y = 1;
1140 }
1141 break;
1142 case EFL_UI_PANEL_ORIENT_RIGHT:
1143 if (efl_ui_mirrored_get(obj))
1144 {
1145 event.rel_x = 1 - ((double) x / (double) ((sd->content_size_ratio) * w));
1146 event.rel_y = 1;
1147 }
1148 else
1149 {
1150 event.rel_x = (double) x / (double) ((sd->content_size_ratio) * w);
1151 event.rel_y = 1;
1152 }
1153 break;
1154 }
1155 efl_event_callback_legacy_call
1156 (obj, EFL_UI_EVENT_SCROLL, (void *) &event);
1157}
1158
1159EOLIAN static Eina_Bool
1160_efl_ui_panel_efl_ui_widget_on_disabled_update(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Bool disabled)
1161{
1162 if (!efl_ui_widget_on_disabled_update(efl_super(obj, MY_CLASS), disabled))
1163 return EINA_FALSE;
1164
1165 if (sd->scrollable)
1166 {
1167 if (disabled && sd->callback_added)
1168 {
1169 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_DOWN,
1170 _on_mouse_down);
1171 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_MOVE,
1172 _on_mouse_move);
1173 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_UP,
1174 _on_mouse_up);
1175 evas_object_event_callback_del(sd->scr_event, EVAS_CALLBACK_MOUSE_UP,
1176 _event_mouse_up);
1177
1178 sd->callback_added = EINA_FALSE;
1179 }
1180 else if (!disabled && !sd->callback_added)
1181 {
1182 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
1183 _on_mouse_down, sd);
1184 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE,
1185 _on_mouse_move, sd);
1186 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
1187 _on_mouse_up, sd);
1188 evas_object_event_callback_add(sd->scr_event, EVAS_CALLBACK_MOUSE_UP,
1189 _event_mouse_up, obj);
1190
1191 sd->callback_added = EINA_TRUE;
1192 }
1193 }
1194
1195 return EINA_TRUE;
1196}
1197
1198EOLIAN static double
1199_efl_ui_panel_scrollable_content_size_get(const Eo *obj EINA_UNUSED, Efl_Ui_Panel_Data *sd)
1200{
1201 return sd->content_size_ratio;
1202}
1203
1204EOLIAN static void
1205_efl_ui_panel_scrollable_content_size_set(Eo *obj, Efl_Ui_Panel_Data *sd, double ratio)
1206{
1207 if (ratio < 0) ratio = 0;
1208 else if (ratio > 1.0) ratio = 1.0;
1209
1210 sd->content_size_ratio = ratio;
1211
1212 if (sd->scrollable)
1213 {
1214 Evas_Coord w, h;
1215 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1216
1217 _scrollable_layout_resize(obj, sd, w, h);
1218 }
1219}
1220
1221EOLIAN static Eina_Bool
1222_efl_ui_panel_scrollable_get(const Eo *obj EINA_UNUSED, Efl_Ui_Panel_Data *sd)
1223{
1224 return sd->scrollable;
1225}
1226
1227EOLIAN static void
1228_efl_ui_panel_scrollable_set(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Bool scrollable)
1229{
1230 scrollable = !!scrollable;
1231 if (sd->scrollable == scrollable) return;
1232 sd->scrollable = scrollable;
1233
1234 if (scrollable)
1235 {
1236 elm_layout_content_unset(obj, "efl.content");
1237
1238 elm_widget_resize_object_set(obj, NULL);
1239 elm_widget_sub_object_add(obj, sd->panel_edje);
1240
1241 if (!sd->scr_edje)
1242 {
1243 const char *handler_size;
1244
1245 sd->scr_edje = edje_object_add(evas_object_evas_get(obj));
1246 elm_widget_theme_object_set(obj, sd->scr_edje, "panel", NULL,
1247 elm_widget_style_get(obj));
1248 evas_object_size_hint_weight_set
1249 (sd->scr_edje, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1250 evas_object_size_hint_align_set
1251 (sd->scr_edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
1252
1253 handler_size = edje_object_data_get(sd->scr_edje, "handler_size");
1254 if (handler_size)
1255 sd->handler_size = (int) (elm_object_scale_get(obj)) * (atoi(handler_size));
1256 }
1257
1258 elm_widget_resize_object_set(obj, sd->scr_edje);
1259
1260 if (!sd->hit_rect)
1261 {
1262 sd->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj));
1263 evas_object_smart_member_add(sd->hit_rect, obj);
1264 elm_widget_sub_object_add(obj, sd->hit_rect);
1265 evas_object_color_set(sd->hit_rect, 0, 0, 0, 0);
1266 evas_object_show(sd->hit_rect);
1267 evas_object_repeat_events_set(sd->hit_rect, EINA_TRUE);
1268
1269 elm_interface_scrollable_objects_set(obj, sd->scr_edje, sd->hit_rect);
1270 elm_interface_scrollable_animate_stop_cb_set(obj, _anim_stop_cb);
1271 elm_interface_scrollable_scroll_cb_set(obj, _scroll_cb);
1272 }
1273
1274 if (!sd->scr_ly)
1275 {
1276 sd->scr_ly = efl_add(EFL_UI_LAYOUT_CLASS, obj,
1277 elm_layout_theme_set(efl_added,
1278 "panel",
1279 "scrollable/left",
1280 elm_widget_style_get(obj)));
1281
1282 evas_object_smart_member_add(sd->scr_ly, obj);
1283 elm_widget_sub_object_add(obj, sd->scr_ly);
1284 _scrollable_layout_theme_set(obj, sd);
1285
1286 sd->scr_panel = evas_object_rectangle_add(evas_object_evas_get(obj));
1287 evas_object_color_set(sd->scr_panel, 0, 0, 0, 0);
1288 elm_widget_sub_object_add(obj, sd->scr_panel);
1289 if (!elm_layout_content_set(sd->scr_ly, "efl.panel_area", sd->scr_panel))
1290 elm_layout_content_set(sd->scr_ly, "panel_area", sd->scr_panel);
1291
1292 sd->scr_event = evas_object_rectangle_add(evas_object_evas_get(obj));
1293 evas_object_color_set(sd->scr_event, 0, 0, 0, 0);
1294 elm_widget_sub_object_add(obj, sd->scr_event);
1295 if (!elm_layout_content_set(sd->scr_ly, "efl.event_area", sd->scr_event))
1296 elm_layout_content_set(sd->scr_ly, "event_area", sd->scr_event);
1297 }
1298
1299 elm_interface_scrollable_content_set(obj, sd->scr_ly);
1300 sd->freeze = EINA_TRUE;
1301 efl_content_set(efl_part(sd->scr_ly, "efl.content"), sd->bx);
1302 if (sd->content) elm_widget_sub_object_add(sd->scr_ly, sd->content);
1303
1304 switch (sd->orient)
1305 {
1306 case EFL_UI_PANEL_ORIENT_TOP:
1307 case EFL_UI_PANEL_ORIENT_BOTTOM:
1308 elm_interface_scrollable_movement_block_set
1309 (obj, EFL_UI_SCROLL_BLOCK_VERTICAL);
1310 break;
1311 case EFL_UI_PANEL_ORIENT_LEFT:
1312 case EFL_UI_PANEL_ORIENT_RIGHT:
1313 elm_interface_scrollable_movement_block_set
1314 (obj, EFL_UI_SCROLL_BLOCK_HORIZONTAL);
1315 break;
1316 }
1317
1318 elm_interface_scrollable_single_direction_set
1319 (obj, ELM_SCROLLER_SINGLE_DIRECTION_NONE);
1320
1321 if (!elm_widget_disabled_get(obj) && !sd->callback_added)
1322 {
1323 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
1324 _on_mouse_down, sd);
1325 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE,
1326 _on_mouse_move, sd);
1327 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
1328 _on_mouse_up, sd);
1329 evas_object_event_callback_add(sd->scr_event, EVAS_CALLBACK_MOUSE_UP,
1330 _event_mouse_up, obj);
1331
1332 sd->callback_added = EINA_TRUE;
1333 }
1334
1335 }
1336 else
1337 {
1338 elm_interface_scrollable_content_set(obj, NULL);
1339
1340 if (sd->callback_added)
1341 {
1342 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_DOWN, _on_mouse_down);
1343 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_MOVE, _on_mouse_move);
1344 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_UP, _on_mouse_up);
1345 evas_object_event_callback_del(sd->scr_event, EVAS_CALLBACK_MOUSE_UP,
1346 _event_mouse_up);
1347
1348 sd->callback_added = EINA_FALSE;
1349 }
1350
1351 elm_widget_resize_object_set(obj, NULL);
1352 elm_widget_sub_object_add(obj, sd->scr_edje);
1353
1354 elm_widget_resize_object_set(obj, sd->panel_edje);
1355
1356 elm_layout_content_unset(sd->scr_ly, "efl.content");
1357 elm_layout_content_set(obj, "efl.content", sd->bx);
1358 if (sd->content) elm_widget_sub_object_add(obj, sd->content);
1359 }
1360}
1361
1362EOLIAN static void
1363_efl_ui_panel_efl_ui_base_mirrored_set(Eo *obj, Efl_Ui_Panel_Data *sd, Eina_Bool mirrored)
1364{
1365 if (sd->scrollable)
1366 efl_ui_mirrored_set(efl_cast(obj, ELM_INTERFACE_SCROLLABLE_MIXIN), mirrored);
1367 else
1368 efl_ui_mirrored_set(efl_cast(obj, EFL_UI_WIDGET_CLASS), mirrored);
1369}
1370
1371EOLIAN const Efl_Access_Action_Data *
1372_efl_ui_panel_efl_access_widget_action_elm_actions_get(const Eo *obj EINA_UNUSED, Efl_Ui_Panel_Data *pd EINA_UNUSED)
1373{
1374 static Efl_Access_Action_Data atspi_actions[] = {
1375 { "toggle", "toggle", NULL, _key_action_toggle},
1376 { NULL, NULL, NULL, NULL }
1377 };
1378 return &atspi_actions[0];
1379}
1380
1381/* Internal EO APIs and hidden overrides */
1382
1383#define EFL_UI_PANEL_EXTRA_OPS \
1384 ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_panel)
1385
1386#include "efl_ui_panel.eo.c"