aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/elementary/src/lib/elm_panes.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/elementary/src/lib/elm_panes.c470
1 files changed, 470 insertions, 0 deletions
diff --git a/libraries/elementary/src/lib/elm_panes.c b/libraries/elementary/src/lib/elm_panes.c
new file mode 100644
index 0000000..249f9e2
--- /dev/null
+++ b/libraries/elementary/src/lib/elm_panes.c
@@ -0,0 +1,470 @@
1#include <Elementary.h>
2#include "elm_priv.h"
3
4/**
5 * TODO
6 * Update the minimun height of the bar in the theme.
7 * No minimun should be set in the vertical theme
8 * Add events (move, start ...)
9 */
10
11typedef struct _Widget_Data Widget_Data;
12
13struct _Widget_Data
14{
15 Evas_Object *panes;
16
17 struct
18 {
19 Evas_Object *left;
20 Evas_Object *right;
21 } contents;
22
23 struct
24 {
25 int x_diff;
26 int y_diff;
27 Eina_Bool move;
28 } move;
29
30 Eina_Bool clicked_double;
31 Eina_Bool horizontal;
32 Eina_Bool fixed;
33};
34
35static const char *widtype = NULL;
36static void _del_hook(Evas_Object *obj);
37static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
38static void _theme_hook(Evas_Object *obj);
39static void _sizing_eval(Evas_Object *obj);
40static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
41
42static const char SIG_CLICKED[] = "clicked";
43static const char SIG_PRESS[] = "press";
44static const char SIG_UNPRESS[] = "unpress";
45static const char SIG_CLICKED_DOUBLE[] = "clicked,double";
46
47static const Evas_Smart_Cb_Description _signals[] = {
48 {SIG_CLICKED, ""},
49 {SIG_PRESS, ""},
50 {SIG_UNPRESS, ""},
51 {SIG_CLICKED_DOUBLE, ""},
52 {NULL, NULL}
53};
54
55static void
56_del_hook(Evas_Object *obj)
57{
58 Widget_Data *wd = elm_widget_data_get(obj);
59 if (!wd) return;
60 free(wd);
61}
62
63static void
64_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
65{
66 Widget_Data *wd = elm_widget_data_get(obj);
67 if (!wd) return;
68 edje_object_mirrored_set(wd->panes, rtl);
69}
70
71static void
72_theme_hook(Evas_Object *obj)
73{
74 Widget_Data *wd = elm_widget_data_get(obj);
75 const char *style = elm_widget_style_get(obj);
76 double size;
77
78 if (!wd) return;
79 _elm_widget_mirrored_reload(obj);
80 _mirrored_set(obj, elm_widget_mirrored_get(obj));
81 size = elm_panes_content_left_size_get(obj);
82
83 if (wd->horizontal)
84 _elm_theme_object_set(obj, wd->panes, "panes", "horizontal", style);
85 else
86 _elm_theme_object_set(obj, wd->panes, "panes", "vertical", style);
87
88 if (wd->contents.left)
89 edje_object_part_swallow(wd->panes, "elm.swallow.left", wd->contents.left);
90 if (wd->contents.right)
91 edje_object_part_swallow(wd->panes, "elm.swallow.right", wd->contents.right);
92 if (wd->fixed)
93 edje_object_signal_emit(wd->panes, "elm.panes.fixed", "elm");
94
95 edje_object_scale_set(wd->panes, elm_widget_scale_get(obj) *
96 _elm_config->scale);
97 _sizing_eval(obj);
98 elm_panes_content_left_size_set(obj, size);
99}
100
101static Eina_Bool
102_elm_panes_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
103{
104 Widget_Data *wd = elm_widget_data_get(obj);
105 if (!wd) return EINA_FALSE;
106
107 double w, h;
108 edje_object_part_drag_value_get(wd->panes, "elm.bar", &w, &h);
109 if (((wd->horizontal) && ( h == 0.0 )) || ((!wd->horizontal) && ( w == 0.0 )))
110 return elm_widget_focus_next_get(wd->contents.right, dir, next);
111
112 Evas_Object *chain[2];
113
114 /* Direction */
115 if (dir == ELM_FOCUS_PREVIOUS)
116 {
117 chain[0] = wd->contents.right;
118 chain[1] = wd->contents.left;
119 }
120 else if (dir == ELM_FOCUS_NEXT)
121 {
122 chain[0] = wd->contents.left;
123 chain[1] = wd->contents.right;
124 }
125 else
126 return EINA_FALSE;
127
128 unsigned char i = elm_widget_focus_get(chain[1]);
129
130 if (elm_widget_focus_next_get(chain[i], dir, next))
131 return EINA_TRUE;
132
133 i = !i;
134
135 Evas_Object *to_focus;
136 if (elm_widget_focus_next_get(chain[i], dir, &to_focus))
137 {
138 *next = to_focus;
139 return !!i;
140 }
141
142 return EINA_FALSE;
143}
144
145static void
146_sizing_eval(Evas_Object *obj)
147{
148 Widget_Data *wd = elm_widget_data_get(obj);
149 if (!wd) return;
150}
151
152static void
153_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
154{
155 _sizing_eval(data);
156}
157
158static void
159_sub_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
160{
161 Widget_Data *wd = elm_widget_data_get(obj);
162 Evas_Object *sub = event_info;
163
164 if (!wd) return;
165 if (sub == wd->contents.left)
166 {
167 evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
168 _changed_size_hints, obj);
169 edje_object_part_unswallow(wd->panes, sub);
170 wd->contents.left = NULL;
171 _sizing_eval(obj);
172 }
173 else if (sub == wd->contents.right)
174 {
175 evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
176 _changed_size_hints, obj);
177 edje_object_part_unswallow(wd->panes, sub);
178 wd->contents.right= NULL;
179 _sizing_eval(obj);
180 }
181}
182
183static void
184_clicked(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__)
185{
186 evas_object_smart_callback_call(data, SIG_CLICKED, NULL);
187}
188
189static void
190_clicked_double(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__)
191{
192 Widget_Data *wd = elm_widget_data_get(data);
193
194 wd->clicked_double = EINA_TRUE;
195}
196
197static void
198_press(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__)
199{
200 evas_object_smart_callback_call(data, SIG_PRESS, NULL);
201}
202
203static void
204_unpress(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__)
205{
206 Widget_Data *wd = elm_widget_data_get(data);
207 evas_object_smart_callback_call(data, SIG_UNPRESS, NULL);
208
209 if (wd->clicked_double)
210 {
211 evas_object_smart_callback_call(data, SIG_CLICKED_DOUBLE, NULL);
212 wd->clicked_double = EINA_FALSE;
213 }
214}
215
216static void
217_content_left_set(Evas_Object *obj, Evas_Object *content)
218{
219 Widget_Data *wd = elm_widget_data_get(obj);
220 if (wd->contents.left == content) return;
221 if (wd->contents.left)
222 evas_object_del(wd->contents.left);
223 wd->contents.left = content;
224 if (content)
225 {
226 elm_widget_sub_object_add(obj, content);
227 edje_object_part_swallow(wd->panes, "elm.swallow.left", content);
228 }
229}
230
231static void
232_content_right_set(Evas_Object *obj, Evas_Object *content)
233{
234 Widget_Data *wd = elm_widget_data_get(obj);
235 if (wd->contents.right == content) return;
236 if (wd->contents.right)
237 evas_object_del(wd->contents.right);
238 wd->contents.right = content;
239 if (content)
240 {
241 elm_widget_sub_object_add(obj, content);
242 edje_object_part_swallow(wd->panes, "elm.swallow.right", content);
243 }
244}
245
246static Evas_Object *
247_content_left_unset(Evas_Object *obj)
248{
249 Widget_Data *wd = elm_widget_data_get(obj);
250 if (!wd->contents.left) return NULL;
251 Evas_Object *content = wd->contents.left;
252 elm_widget_sub_object_del(obj, content);
253 return content;
254}
255
256static Evas_Object *
257_content_right_unset(Evas_Object *obj)
258{
259 Widget_Data *wd = elm_widget_data_get(obj);
260 if (!wd->contents.right) return NULL;
261 Evas_Object *content = wd->contents.right;
262 elm_widget_sub_object_del(obj, content);
263 return content;
264}
265
266static void
267_content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
268{
269 ELM_CHECK_WIDTYPE(obj, widtype);
270 Widget_Data *wd = elm_widget_data_get(obj);
271 if (!wd) return;
272 if (part && (!strncmp(part, "elm.swallow.", 12))) part += 12;
273 if (!part || !strcmp(part, "left"))
274 _content_left_set(obj, content);
275 else if (!strcmp(part, "right"))
276 _content_right_set(obj, content);
277}
278
279static Evas_Object *
280_content_get_hook(const Evas_Object *obj, const char *part)
281{
282 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
283 Widget_Data *wd = elm_widget_data_get(obj);
284 if (!wd) return NULL;
285 if (part && (!strncmp(part, "elm.swallow.", 12))) part += 12;
286 if (!part || !strcmp(part, "left"))
287 return wd->contents.left;
288 else if (!strcmp(part, "right"))
289 return wd->contents.right;
290 return NULL;
291}
292
293static Evas_Object *
294_content_unset_hook(Evas_Object *obj, const char *part)
295{
296 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
297 Widget_Data *wd = elm_widget_data_get(obj);
298 if (!wd) return NULL;
299 if (part && (!strncmp(part, "elm.swallow.", 12))) part += 12;
300 if (!part || !strcmp(part, "left"))
301 return _content_left_unset(obj);
302 else if (!strcmp(part, "right"))
303 return _content_right_unset(obj);
304 return NULL;
305}
306
307EAPI Evas_Object *
308elm_panes_add(Evas_Object *parent)
309{
310 Evas_Object *obj;
311 Evas *e;
312 Widget_Data *wd;
313
314 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
315
316 ELM_SET_WIDTYPE(widtype, "panes");
317 elm_widget_type_set(obj, "panes");
318 elm_widget_sub_object_add(parent, obj);
319 elm_widget_data_set(obj, wd);
320 elm_widget_del_hook_set(obj, _del_hook);
321 elm_widget_theme_hook_set(obj, _theme_hook);
322 elm_widget_focus_next_hook_set(obj, _elm_panes_focus_next_hook);
323 elm_widget_content_set_hook_set(obj, _content_set_hook);
324 elm_widget_content_get_hook_set(obj, _content_get_hook);
325 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
326 elm_widget_can_focus_set(obj, EINA_FALSE);
327
328 wd->panes = edje_object_add(e);
329 _elm_theme_object_set(obj, wd->panes, "panes", "vertical", "default");
330 elm_widget_resize_object_set(obj, wd->panes);
331 evas_object_show(wd->panes);
332
333 elm_panes_content_left_size_set(obj, 0.5);
334
335 edje_object_signal_callback_add(wd->panes, "elm,action,click", "",
336 _clicked, obj);
337 edje_object_signal_callback_add(wd->panes, "elm,action,click,double", "",
338 _clicked_double, obj);
339 edje_object_signal_callback_add(wd->panes, "elm,action,press", "",
340 _press, obj);
341 edje_object_signal_callback_add(wd->panes, "elm,action,unpress", "",
342 _unpress, obj);
343
344 evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
345 evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
346 _changed_size_hints, obj);
347
348 evas_object_smart_callbacks_descriptions_set(obj, _signals);
349
350 _mirrored_set(obj, elm_widget_mirrored_get(obj));
351 _sizing_eval(obj);
352 return obj;
353}
354
355EINA_DEPRECATED EAPI void
356elm_panes_content_left_set(Evas_Object *obj, Evas_Object *content)
357{
358 _content_set_hook(obj, "left", content);
359}
360
361EINA_DEPRECATED EAPI void
362elm_panes_content_right_set(Evas_Object *obj, Evas_Object *content)
363{
364 _content_set_hook(obj, "right", content);
365}
366
367EINA_DEPRECATED EAPI Evas_Object *
368elm_panes_content_left_get(const Evas_Object *obj)
369{
370 return _content_get_hook(obj, "left");
371}
372
373EINA_DEPRECATED EAPI Evas_Object *
374elm_panes_content_right_get(const Evas_Object *obj)
375{
376 return _content_get_hook(obj, "right");
377}
378
379EINA_DEPRECATED EAPI Evas_Object *
380elm_panes_content_left_unset(Evas_Object *obj)
381{
382 return _content_unset_hook(obj, "left");
383}
384
385EINA_DEPRECATED EAPI Evas_Object *
386elm_panes_content_right_unset(Evas_Object *obj)
387{
388 return _content_unset_hook(obj, "right");
389}
390
391EAPI double
392elm_panes_content_left_size_get(const Evas_Object *obj)
393{
394 ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
395 Widget_Data *wd = elm_widget_data_get(obj);
396 double w, h;
397
398 if (!wd) return 0;
399 edje_object_part_drag_value_get(wd->panes, "elm.bar", &w, &h);
400 if (wd->horizontal) return h;
401 else return w;
402}
403
404EAPI void
405elm_panes_content_left_size_set(Evas_Object *obj, double size)
406{
407 ELM_CHECK_WIDTYPE(obj, widtype);
408 Widget_Data *wd = elm_widget_data_get(obj);
409 if (!wd) return;
410 if (size < 0.0) size = 0.0;
411 else if (size > 1.0) size = 1.0;
412 if (wd->horizontal)
413 edje_object_part_drag_value_set(wd->panes, "elm.bar", 0.0, size);
414 else
415 edje_object_part_drag_value_set(wd->panes, "elm.bar", size, 0.0);
416}
417
418EAPI double
419elm_panes_content_right_size_get(const Evas_Object *obj)
420{
421 return (1.0 - elm_panes_content_left_size_get(obj));
422}
423
424EAPI void
425elm_panes_content_right_size_set(Evas_Object *obj, double size)
426{
427 elm_panes_content_left_size_set(obj, (1.0 - size));
428}
429
430EAPI void
431elm_panes_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
432{
433 ELM_CHECK_WIDTYPE(obj, widtype);
434 Widget_Data *wd = elm_widget_data_get(obj);
435 if (!wd) return;
436 wd->horizontal = horizontal;
437 _theme_hook(obj);
438 elm_panes_content_left_size_set(obj, 0.5);
439}
440
441EAPI Eina_Bool
442elm_panes_horizontal_get(const Evas_Object *obj)
443{
444 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
445 Widget_Data *wd = elm_widget_data_get(obj);
446 if (!wd) return EINA_FALSE;
447 return wd->horizontal;
448}
449
450EAPI void
451elm_panes_fixed_set(Evas_Object *obj, Eina_Bool fixed)
452{
453 ELM_CHECK_WIDTYPE(obj, widtype);
454 Widget_Data *wd = elm_widget_data_get(obj);
455 if (!wd) return;
456 wd->fixed = !!fixed;
457 if (wd->fixed == EINA_TRUE)
458 edje_object_signal_emit(wd->panes, "elm.panes.fixed", "elm");
459 else
460 edje_object_signal_emit(wd->panes, "elm.panes.unfixed", "elm");
461}
462
463EAPI Eina_Bool
464elm_panes_fixed_get(const Evas_Object *obj)
465{
466 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
467 Widget_Data *wd = elm_widget_data_get(obj);
468 if (!wd) return EINA_FALSE;
469 return wd->fixed;
470}