Merge branch 'master' of jae.hwan.kim@165.213.180.234:/git/slp2.0/slp2.0-pkgs/EFL...
[framework/uifw/elementary.git] / src / lib / elm_panel.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Panel Panel
6  * @ingroup Elementary
7  *
8  * A panel is a type of animated container that contains subobjects.  It
9  * can be expanded or contracted.
10  *
11  * Orientations are as follows:
12  * ELM_PANEL_ORIENT_TOP
13  * ELM_PANEL_ORIENT_BOTTOM
14  * ELM_PANEL_ORIENT_LEFT
15  * ELM_PANEL_ORIENT_RIGHT
16  * NOTE: Only LEFT and RIGHT orientations are implemented.
17  *
18  * THIS WIDGET IS UNDER CONSTRUCTION!
19  */
20
21 typedef struct _Widget_Data Widget_Data;
22 struct _Widget_Data 
23 {
24    Evas_Object *scr, *bx;
25    Elm_Panel_Orient orient;
26    Eina_Bool hidden : 1;
27 };
28
29 static const char *widtype = NULL;
30 static void _del_hook(Evas_Object *obj);
31 static void _theme_hook(Evas_Object *obj);
32 static void _sizing_eval(Evas_Object *obj);
33 static void _resize(void *data, Evas *evas, Evas_Object *obj, void *event);
34 static void _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data);
35 static void _toggle_panel(void *data, Evas_Object *obj, const char *emission, const char *source);
36
37 static void 
38 _del_hook(Evas_Object *obj) 
39 {
40    Widget_Data *wd = elm_widget_data_get(obj);
41    if (!wd) return;
42    free(wd);
43 }
44
45 static void 
46 _theme_hook(Evas_Object *obj) 
47 {
48    Widget_Data *wd = elm_widget_data_get(obj);
49    if (!wd) return;
50    elm_smart_scroller_object_theme_set(obj, wd->scr, "panel", "base", elm_widget_style_get(obj));
51 //   scale = (elm_widget_scale_get(obj) * _elm_config->scale);
52 //   edje_object_scale_set(wd->scr, scale);
53    _sizing_eval(obj);
54 }
55
56 static void 
57 _sizing_eval(Evas_Object *obj) 
58 {
59    Widget_Data *wd = elm_widget_data_get(obj);
60    Evas_Coord mw = -1, mh = -1;
61    Evas_Coord vw = 0, vh = 0;
62    Evas_Coord w, h;
63    if (!wd) return;
64    evas_object_smart_calculate(wd->bx);
65    edje_object_size_min_calc(elm_smart_scroller_edje_object_get(wd->scr), 
66                              &mw, &mh);
67    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
68    if (w < mw) w = mw;
69    if (h < mh) h = mh;
70    evas_object_resize(wd->scr, w, h);
71
72    evas_object_size_hint_min_get(wd->bx, &mw, &mh);
73    if (w > mw) mw = w;
74    if (h > mh) mh = h;
75    evas_object_resize(wd->bx, mw, mh);
76
77    elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
78    mw = mw + (w - vw);
79    mh = mh + (h - vh);
80    evas_object_size_hint_min_set(obj, mw, mh);
81    evas_object_size_hint_max_set(obj, -1, -1);
82 }
83
84 static void 
85 _resize(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
86 {
87    Widget_Data *wd = elm_widget_data_get(data);
88    Evas_Coord mw, mh, vw, vh, w, h;
89    if (!wd) return;
90    elm_smart_scroller_child_viewport_size_get(wd->scr, &vw, &vh);
91    evas_object_size_hint_min_get(wd->bx, &mw, &mh);
92    evas_object_geometry_get(wd->bx, NULL, NULL, &w, &h);
93    if ((vw >= mw) || (vh >= mh))
94      {
95         if ((w != vw) || (h != vh)) evas_object_resize(wd->bx, vw, vh);
96      }
97 }
98
99 static void 
100 _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) 
101 {
102    Widget_Data *wd = data;
103    if (!wd) return;
104    _els_box_layout(o, priv, EINA_TRUE, EINA_FALSE);
105 }
106
107 static void 
108 _toggle_panel(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) 
109 {
110    Widget_Data *wd = elm_widget_data_get(data);
111    if (!wd) return;
112    if (wd->hidden) 
113      {
114         edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), 
115                                 "elm,action,show", "elm");
116         wd->hidden = EINA_FALSE;
117      }
118    else
119      {
120         edje_object_signal_emit(elm_smart_scroller_edje_object_get(wd->scr), 
121                                 "elm,action,hide", "elm");
122         wd->hidden = EINA_TRUE;
123      }
124 }
125
126 /**
127  * Adds a panel object
128  *
129  * @param parent The parent object
130  *
131  * @return The panel object, or NULL on failure
132  *
133  * @ingroup Panel
134  */
135 EAPI Evas_Object *
136 elm_panel_add(Evas_Object *parent) 
137 {
138    Evas_Object *obj;
139    Evas *evas;
140    Widget_Data *wd;
141
142    wd = ELM_NEW(Widget_Data);
143    evas = evas_object_evas_get(parent);
144    obj = elm_widget_add(evas);
145    ELM_SET_WIDTYPE(widtype, "panel");
146    elm_widget_type_set(obj, "panel");
147    elm_widget_sub_object_add(parent, obj);
148    elm_widget_data_set(obj, wd);
149    elm_widget_del_hook_set(obj, _del_hook);
150    elm_widget_theme_hook_set(obj, _theme_hook);
151    elm_widget_can_focus_set(obj, 0);
152
153    wd->scr = elm_smart_scroller_add(evas);
154    elm_smart_scroller_widget_set(wd->scr, obj);
155    elm_smart_scroller_object_theme_set(obj, wd->scr, "panel", "base", "left");
156    elm_smart_scroller_bounce_allow_set(wd->scr, 0, 0);
157    elm_widget_resize_object_set(obj, wd->scr);
158    elm_smart_scroller_policy_set(wd->scr, ELM_SMART_SCROLLER_POLICY_OFF, 
159                                  ELM_SMART_SCROLLER_POLICY_OFF);
160
161    wd->hidden = EINA_FALSE;
162    wd->orient = ELM_PANEL_ORIENT_LEFT;
163
164    wd->bx = evas_object_box_add(evas);
165    evas_object_size_hint_align_set(wd->bx, 0.5, 0.5);
166    evas_object_box_layout_set(wd->bx, _layout, wd, NULL);
167    elm_widget_sub_object_add(obj, wd->bx);
168    elm_smart_scroller_child_set(wd->scr, wd->bx);
169    evas_object_show(wd->bx);
170
171    edje_object_signal_callback_add(elm_smart_scroller_edje_object_get(wd->scr), 
172                                    "elm,action,panel,toggle", "*", 
173                                    _toggle_panel, obj);
174
175    evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE, _resize, obj);
176
177    _sizing_eval(obj);
178    return obj;
179 }
180
181 /**
182  * Sets the orientation of the panel
183  *
184  * @param parent The parent object
185  * @param orient The panel orientation.  Can be one of the following:
186  * ELM_PANEL_ORIENT_TOP
187  * ELM_PANEL_ORIENT_BOTTOM
188  * ELM_PANEL_ORIENT_LEFT
189  * ELM_PANEL_ORIENT_RIGHT
190  *
191  * NOTE: Only LEFT and RIGHT orientations are implemented.
192  *
193  * @ingroup Panel
194  */
195 EAPI void 
196 elm_panel_orient_set(Evas_Object *obj, Elm_Panel_Orient orient) 
197 {
198    ELM_CHECK_WIDTYPE(obj, widtype);
199    Widget_Data *wd = elm_widget_data_get(obj);
200    if (!wd) return;
201    wd->orient = orient;
202    switch (orient) 
203      {
204      case ELM_PANEL_ORIENT_TOP:
205      case ELM_PANEL_ORIENT_BOTTOM:
206         break;
207      case ELM_PANEL_ORIENT_LEFT:
208         elm_smart_scroller_object_theme_set(obj, wd->scr, "panel", "base", "left");
209         break;
210      case ELM_PANEL_ORIENT_RIGHT:
211         elm_smart_scroller_object_theme_set(obj, wd->scr, "panel", "base", "right");
212         break;
213      default:
214         break;
215      }
216    _sizing_eval(obj);
217 }
218
219 /**
220  * Get the orientation of the panel.
221  *
222  * @param obj The panel object
223  * @return The Elm_Panel_Orient, or ELM_PANEL_ORIENT_LEFT on failure.
224  *
225  * @ingroup Panel
226  */
227 EAPI Elm_Panel_Orient
228 elm_panel_orient_get(Evas_Object *obj)
229 {
230    ELM_CHECK_WIDTYPE(obj, widtype) ELM_PANEL_ORIENT_LEFT;
231    Widget_Data *wd = elm_widget_data_get(obj);
232    if (!wd) return ELM_PANEL_ORIENT_LEFT;
233    return wd->orient;   
234 }
235
236 /**
237  * Set the content of the panel.
238  *
239  * @param obj The panel object
240  * @param content The panel content
241  *
242  * @ingroup Panel
243  */
244 EAPI void 
245 elm_panel_content_set(Evas_Object *obj, Evas_Object *content) 
246 {
247    ELM_CHECK_WIDTYPE(obj, widtype);
248    Widget_Data *wd = elm_widget_data_get(obj);
249    if (!wd) return;
250    evas_object_box_remove_all(wd->bx, EINA_TRUE);
251    if (!content) return;
252    evas_object_box_append(wd->bx, content);
253    evas_object_show(content);
254    _sizing_eval(obj);
255 }
256
257 /**
258  * Set the state of the panel.
259  *
260  * @param obj The panel object
261  * @param hidden If true, the panel will run the edje animation to contract
262  *
263  * @ingroup Panel
264  */
265 EAPI void
266 elm_panel_hidden_set(Evas_Object *obj, Eina_Bool hidden)
267 {
268    ELM_CHECK_WIDTYPE(obj, widtype);
269    Widget_Data *wd = elm_widget_data_get(obj);
270    if (!wd) return;
271    if (wd->hidden == hidden) return;
272    wd->hidden = hidden;
273    _toggle_panel(obj, NULL, "elm,action,panel,toggle", "*");
274 }
275
276 /**
277  * Get the state of the panel.
278  *
279  * @param obj The panel object
280  * @param hidden If true, the panel is in the "hide" state
281  *
282  * @ingroup Panel
283  */
284 EAPI Eina_Bool
285 elm_panel_hidden_get(Evas_Object *obj)
286 {
287    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
288    Widget_Data *wd = elm_widget_data_get(obj);
289    if (!wd) return EINA_FALSE;
290    return wd->hidden;
291 }
292
293 /**
294  * Toggle the state of the panel from code
295  *
296  * @param obj The panel object
297  *
298  * @ingroup Panel
299  */
300 EAPI void
301 elm_panel_toggle(Evas_Object *obj)
302 {
303    ELM_CHECK_WIDTYPE(obj, widtype);
304    Widget_Data *wd = elm_widget_data_get(obj);
305    if (!wd) return;
306    wd->hidden = !(wd->hidden);
307    _toggle_panel(obj, NULL, "elm,action,panel,toggle", "*");
308 }