diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/elementary/src/lib/elm_panes.c | 470 |
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 | |||
11 | typedef struct _Widget_Data Widget_Data; | ||
12 | |||
13 | struct _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 | |||
35 | static const char *widtype = NULL; | ||
36 | static void _del_hook(Evas_Object *obj); | ||
37 | static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); | ||
38 | static void _theme_hook(Evas_Object *obj); | ||
39 | static void _sizing_eval(Evas_Object *obj); | ||
40 | static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info); | ||
41 | |||
42 | static const char SIG_CLICKED[] = "clicked"; | ||
43 | static const char SIG_PRESS[] = "press"; | ||
44 | static const char SIG_UNPRESS[] = "unpress"; | ||
45 | static const char SIG_CLICKED_DOUBLE[] = "clicked,double"; | ||
46 | |||
47 | static const Evas_Smart_Cb_Description _signals[] = { | ||
48 | {SIG_CLICKED, ""}, | ||
49 | {SIG_PRESS, ""}, | ||
50 | {SIG_UNPRESS, ""}, | ||
51 | {SIG_CLICKED_DOUBLE, ""}, | ||
52 | {NULL, NULL} | ||
53 | }; | ||
54 | |||
55 | static 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 | |||
63 | static 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 | |||
71 | static 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 | |||
101 | static 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 | |||
145 | static void | ||
146 | _sizing_eval(Evas_Object *obj) | ||
147 | { | ||
148 | Widget_Data *wd = elm_widget_data_get(obj); | ||
149 | if (!wd) return; | ||
150 | } | ||
151 | |||
152 | static 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 | |||
158 | static 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 | |||
183 | static 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 | |||
189 | static 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 | |||
197 | static 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 | |||
203 | static 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 | |||
216 | static 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 | |||
231 | static 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 | |||
246 | static 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 | |||
256 | static 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 | |||
266 | static 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 | |||
279 | static 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 | |||
293 | static 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 | |||
307 | EAPI Evas_Object * | ||
308 | elm_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 | |||
355 | EINA_DEPRECATED EAPI void | ||
356 | elm_panes_content_left_set(Evas_Object *obj, Evas_Object *content) | ||
357 | { | ||
358 | _content_set_hook(obj, "left", content); | ||
359 | } | ||
360 | |||
361 | EINA_DEPRECATED EAPI void | ||
362 | elm_panes_content_right_set(Evas_Object *obj, Evas_Object *content) | ||
363 | { | ||
364 | _content_set_hook(obj, "right", content); | ||
365 | } | ||
366 | |||
367 | EINA_DEPRECATED EAPI Evas_Object * | ||
368 | elm_panes_content_left_get(const Evas_Object *obj) | ||
369 | { | ||
370 | return _content_get_hook(obj, "left"); | ||
371 | } | ||
372 | |||
373 | EINA_DEPRECATED EAPI Evas_Object * | ||
374 | elm_panes_content_right_get(const Evas_Object *obj) | ||
375 | { | ||
376 | return _content_get_hook(obj, "right"); | ||
377 | } | ||
378 | |||
379 | EINA_DEPRECATED EAPI Evas_Object * | ||
380 | elm_panes_content_left_unset(Evas_Object *obj) | ||
381 | { | ||
382 | return _content_unset_hook(obj, "left"); | ||
383 | } | ||
384 | |||
385 | EINA_DEPRECATED EAPI Evas_Object * | ||
386 | elm_panes_content_right_unset(Evas_Object *obj) | ||
387 | { | ||
388 | return _content_unset_hook(obj, "right"); | ||
389 | } | ||
390 | |||
391 | EAPI double | ||
392 | elm_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 | |||
404 | EAPI void | ||
405 | elm_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 | |||
418 | EAPI double | ||
419 | elm_panes_content_right_size_get(const Evas_Object *obj) | ||
420 | { | ||
421 | return (1.0 - elm_panes_content_left_size_get(obj)); | ||
422 | } | ||
423 | |||
424 | EAPI void | ||
425 | elm_panes_content_right_size_set(Evas_Object *obj, double size) | ||
426 | { | ||
427 | elm_panes_content_left_size_set(obj, (1.0 - size)); | ||
428 | } | ||
429 | |||
430 | EAPI void | ||
431 | elm_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 | |||
441 | EAPI Eina_Bool | ||
442 | elm_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 | |||
450 | EAPI void | ||
451 | elm_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 | |||
463 | EAPI Eina_Bool | ||
464 | elm_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 | } | ||