1 #include <Elementary.h>
5 * @defgroup Panes panes
10 typedef struct _Widget_Data Widget_Data;
29 Eina_Bool clicked_double;
34 static const char *widtype = NULL;
35 static void _del_hook(Evas_Object *obj);
36 static void _theme_hook(Evas_Object *obj);
37 static void _sizing_eval(Evas_Object *obj);
38 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
41 _del_hook(Evas_Object *obj)
43 Widget_Data *wd = elm_widget_data_get(obj);
45 if (wd->panes) evas_object_del(wd->panes);
50 _theme_hook(Evas_Object *obj)
52 Widget_Data *wd = elm_widget_data_get(obj);
53 const char *style = elm_widget_style_get(obj);
57 size = elm_panes_content_left_size_get(obj);
60 _elm_theme_object_set(obj, wd->panes, "panes", "horizontal", style);
62 _elm_theme_object_set(obj, wd->panes, "panes", "vertical", style);
64 if (wd->contents.left)
65 edje_object_part_swallow(wd->panes, "elm.swallow.left", wd->contents.left);
66 if (wd->contents.right)
67 edje_object_part_swallow(wd->panes, "elm.swallow.right", wd->contents.right);
68 if(wd->contents.left && wd->contents.right)
69 edje_object_signal_emit(wd->panes, "elm.panes.pair", "elm");
71 edje_object_signal_emit(wd->panes, "elm.panes.fixed", "elm");
72 edje_object_scale_set(wd->panes, elm_widget_scale_get(obj) *
75 elm_panes_content_left_size_set(obj, size);
79 _elm_panes_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
81 Widget_Data *wd = elm_widget_data_get(obj);
87 edje_object_part_drag_value_get(wd->panes, "elm.bar", &w, &h);
88 if (((wd->horizontal) && ( h == 0.0 )) || ((!wd->horizontal) && ( w == 0.0 )))
89 return elm_widget_focus_next_get(wd->contents.right, dir, next);
91 Evas_Object *chain[2];
94 if (dir == ELM_FOCUS_PREVIOUS)
96 chain[0] = wd->contents.right;
97 chain[1] = wd->contents.left;
99 else if (dir == ELM_FOCUS_NEXT)
101 chain[0] = wd->contents.left;
102 chain[1] = wd->contents.right;
107 unsigned char i = elm_widget_focus_get(chain[1]);
109 if (elm_widget_focus_next_get(chain[i], dir, next))
114 Evas_Object *to_focus;
115 if (elm_widget_focus_next_get(chain[i], dir, &to_focus))
125 _sizing_eval(Evas_Object *obj)
127 Widget_Data *wd = elm_widget_data_get(obj);
132 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
138 _sub_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
140 Widget_Data *wd = elm_widget_data_get(obj);
141 Evas_Object *sub = event_info;
144 if (sub == wd->contents.left)
146 evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
147 _changed_size_hints, obj);
148 wd->contents.left = NULL;
151 else if (sub == wd->contents.right)
153 evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
154 _changed_size_hints, obj);
155 wd->contents.right= NULL;
161 _clicked(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__)
163 evas_object_smart_callback_call(data, "clicked", NULL);
167 _clicked_double(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__)
169 Widget_Data *wd = elm_widget_data_get(data);
171 wd->clicked_double = EINA_TRUE;
175 _press(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__)
177 evas_object_smart_callback_call(data, "press", NULL);
181 _unpress(void *data, Evas_Object *obj __UNUSED__ , const char *emission __UNUSED__, const char *source __UNUSED__)
183 Widget_Data *wd = elm_widget_data_get(data);
184 evas_object_smart_callback_call(data, "unpress", NULL);
186 if (wd->clicked_double)
188 evas_object_smart_callback_call(data, "clicked,double", NULL);
189 wd->clicked_double = EINA_FALSE;
194 * Add a new panes to the parent
196 * @param[in] parent The parent object
197 * @return The new object or NULL if it cannot be created
202 elm_panes_add(Evas_Object *parent)
208 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
210 wd = ELM_NEW(Widget_Data);
211 e = evas_object_evas_get(parent);
213 obj = elm_widget_add(e);
214 ELM_SET_WIDTYPE(widtype, "panes");
215 elm_widget_type_set(obj, "panes");
216 elm_widget_can_focus_set(obj, EINA_FALSE);
217 elm_widget_sub_object_add(parent, obj);
218 elm_widget_data_set(obj, wd);
219 elm_widget_del_hook_set(obj, _del_hook);
220 elm_widget_theme_hook_set(obj, _theme_hook);
221 elm_widget_focus_next_hook_set(obj, _elm_panes_focus_next_hook);
222 wd->contents.left = NULL;
223 wd->contents.right = NULL;
225 wd->panes = edje_object_add(e);
226 _elm_theme_object_set(obj, wd->panes, "panes", "vertical", "default");
227 elm_widget_resize_object_set(obj, wd->panes);
228 evas_object_show(wd->panes);
230 elm_panes_content_left_size_set(obj, 0.5);
232 edje_object_signal_callback_add(wd->panes, "elm,action,click", "",
234 edje_object_signal_callback_add(wd->panes, "elm,action,click,double", "",
235 _clicked_double, obj);
236 edje_object_signal_callback_add(wd->panes, "elm,action,press", "",
238 edje_object_signal_callback_add(wd->panes, "elm,action,unpress", "",
241 evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
242 evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
243 _changed_size_hints, obj);
250 * Set the left/top content of the panes widget
252 * Once the content object is set, a previously set one will be deleted.
253 * If you want to keep that old content object, use the
254 * elm_panes_content_left_unset() function.
256 * @param[in] obj The panes object
257 * @param[in] content The new left/top content object
262 elm_panes_content_left_set(Evas_Object *obj, Evas_Object *content)
264 ELM_CHECK_WIDTYPE(obj, widtype);
265 Widget_Data *wd = elm_widget_data_get(obj);
266 if (wd->contents.left)
268 evas_object_del(wd->contents.left);
269 wd->contents.left = NULL;
273 wd->contents.left = content;
274 elm_widget_sub_object_add(obj, content);
275 edje_object_part_swallow(wd->panes, "elm.swallow.left", content);
276 if (wd->contents.right)
277 edje_object_signal_emit(wd->panes, "elm.panes.pair", "elm");
280 edje_object_signal_emit(wd->panes, "elm.panes.unpair", "elm");
284 * Set the right/bottom content of the panes widget
286 * Once the content object is set, a previously set one will be deleted.
287 * If you want to keep that old content object, use the
288 * elm_panes_content_right_unset() function.
290 * @param[in] obj The panes object
291 * @param[in] content The new right/bottom content object
296 elm_panes_content_right_set(Evas_Object *obj, Evas_Object *content)
298 ELM_CHECK_WIDTYPE(obj, widtype);
299 Widget_Data *wd = elm_widget_data_get(obj);
300 if (wd->contents.right)
302 evas_object_del(wd->contents.right);
303 wd->contents.right = NULL;
307 wd->contents.right = content;
308 elm_widget_sub_object_add(obj, content);
309 edje_object_part_swallow(wd->panes, "elm.swallow.right", content);
310 if (wd->contents.left)
311 edje_object_signal_emit(wd->panes, "elm.panes.pair", "elm");
314 edje_object_signal_emit(wd->panes, "elm.panes.unpair", "elm");
318 * Get the left/top content used for the panes
320 * Return the left/top content object which is set for this widget.
322 * @param[in] obj The panes object
323 * @return The left/top content object that is being used
328 elm_panes_content_left_get(const Evas_Object *obj)
330 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
331 Widget_Data *wd = elm_widget_data_get(obj);
332 return wd->contents.left;
336 * Get the right/bottom content used for the panes
338 * Return the right/bottom content object which is set for this widget.
340 * @param[in] obj The panes object
341 * @return The right/bottom content object that is being used
346 elm_panes_content_right_get(const Evas_Object *obj)
348 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
349 Widget_Data *wd = elm_widget_data_get(obj);
350 return wd->contents.right;
354 * Unset the left/top content used for the panes
356 * Unparent and return the left content object which was set for this widget.
358 * @param[in] obj The panes object
359 * @return The left/top content object that was being used
364 elm_panes_content_left_unset(Evas_Object *obj)
366 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
367 Widget_Data *wd = elm_widget_data_get(obj);
368 if (!wd) return NULL;
369 if (!wd->contents.left) return NULL;
370 Evas_Object *content = wd->contents.left;
371 elm_widget_sub_object_del(obj, content);
372 edje_object_part_unswallow(wd->panes, content);
373 evas_object_hide(content);
374 wd->contents.left = NULL;
375 edje_object_signal_emit(wd->panes, "elm.panes.unpair", "elm");
380 * Unset the right/bottom content used for the panes
382 * Unparent and return the right content object which was set for this widget.
384 * @param[in] obj The panes object
385 * @return The right/bottom content object that was being used
390 elm_panes_content_right_unset(Evas_Object *obj)
392 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
393 Widget_Data *wd = elm_widget_data_get(obj);
394 if (!wd) return NULL;
395 if (!wd->contents.right) return NULL;
396 Evas_Object *content = wd->contents.right;
397 elm_widget_sub_object_del(obj, content);
398 edje_object_part_unswallow(wd->panes, content);
399 evas_object_hide(content);
400 wd->contents.right = NULL;
401 edje_object_signal_emit(wd->panes, "elm.panes.unpair", "elm");
406 * Get the relative normalized size of left/top content of the pane
408 * @param[in] obj The panes object
409 * @return The value of type double in the range [0.0,1.0]
414 elm_panes_content_left_size_get(const Evas_Object *obj)
416 ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
417 Widget_Data *wd = elm_widget_data_get(obj);
420 edje_object_part_drag_value_get(wd->panes, "elm.bar", &w, &h);
421 if (wd->horizontal) return h;
426 * Set a size of the left/top content with a relative normalized double value
428 * @param[in] obj The panes object
429 * @param[in] size The value of type double in the range [0.0,1.0]
434 elm_panes_content_left_size_set(Evas_Object *obj, double size)
436 ELM_CHECK_WIDTYPE(obj, widtype);
437 Widget_Data *wd = elm_widget_data_get(obj);
439 if (size < 0.0) size = 0.0;
440 else if (size > 1.0) size = 1.0;
442 edje_object_part_drag_value_set(wd->panes, "elm.bar", 0.0, size);
444 edje_object_part_drag_value_set(wd->panes, "elm.bar", size, 0.0);
448 * Set the type of an existing panes object to horizontal/vertical
450 * By default the panes is of vertical type
452 * @param[in] obj The panes object
453 * @param[in] horizontal Boolean value. If true, then the type is set to horizontal else vertical
458 elm_panes_horizontal_set(Evas_Object *obj, Eina_Bool horizontal)
460 ELM_CHECK_WIDTYPE(obj, widtype);
461 Widget_Data *wd = elm_widget_data_get(obj);
463 wd->horizontal = horizontal;
465 elm_panes_content_left_size_set(obj, 0.5);
469 * Indicate if the type of pane object is horizontal or not
471 * @param[in] obj The panes object
472 * @return true if it is of horizontal type else false
477 elm_panes_horizontal_get(const Evas_Object *obj)
479 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
480 Widget_Data *wd = elm_widget_data_get(obj);
481 return wd->horizontal;
485 * Set a handler of the pane object movable or non-movable
487 * @param[in] obj The panes object
488 * @param[in] fixed If set to true then the views size can't be changed using handler otherwise using handler they can be resized
493 elm_panes_fixed_set(Evas_Object *obj, Eina_Bool fixed)
495 ELM_CHECK_WIDTYPE(obj, widtype);
496 Widget_Data *wd = elm_widget_data_get(obj);
498 if (wd->fixed == EINA_TRUE)
499 edje_object_signal_emit(wd->panes, "elm.panes.fixed", "elm");
501 edje_object_signal_emit(wd->panes, "elm.panes.unfixed", "elm");
505 * Indicate if the handler of the panes object can be moved with user interaction
507 * @param[in] obj The panes object
508 * @return false if the views can be resized using handler else true
513 elm_panes_fixed_get(const Evas_Object *obj)
515 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
516 Widget_Data *wd = elm_widget_data_get(obj);