================================================================
[framework/uifw/elementary.git] / src / lib / els_pan.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 #define SMART_NAME "elm_pan"
5 #define API_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if ((!obj) || (!sd) || (evas_object_type_get(obj) && strcmp(evas_object_type_get(obj), SMART_NAME)))
6 #define INTERNAL_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return;
7 typedef struct _Smart_Data Smart_Data;
8
9 struct _Smart_Data
10 {
11    Evas_Object *smart_obj;
12    Evas_Object *child_obj;
13    Evas_Coord   x, y, w, h;
14    Evas_Coord   child_w, child_h, px, py;
15 };
16
17 /* local subsystem functions */
18 static void _smart_child_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
19 static void _smart_child_resize_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
20
21 static void _smart_reconfigure(Smart_Data *sd);
22 static void _smart_add(Evas_Object *obj);
23 static void _smart_del(Evas_Object *obj);
24 static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
25 static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
26 static void _smart_show(Evas_Object *obj);
27 static void _smart_hide(Evas_Object *obj);
28 static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
29 static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
30 static void _smart_clip_unset(Evas_Object *obj);
31 static void _smart_init(void);
32
33 /* local subsystem globals */
34 static Evas_Smart *_smart = NULL;
35
36 /* externally accessible functions */
37 Evas_Object *
38 _elm_smart_pan_add(Evas *evas)
39 {
40    _smart_init();
41    return evas_object_smart_add(evas, _smart);
42 }
43
44 void
45 _elm_smart_pan_child_set(Evas_Object *obj, Evas_Object *child)
46 {
47    API_ENTRY return;
48    if (child == sd->child_obj) return;
49    if (sd->child_obj)
50      {
51         evas_object_clip_unset(sd->child_obj);
52         evas_object_smart_member_del(sd->child_obj);
53         evas_object_event_callback_del_full(sd->child_obj, EVAS_CALLBACK_FREE, _smart_child_del_hook, sd);
54         evas_object_event_callback_del_full(sd->child_obj, EVAS_CALLBACK_RESIZE, _smart_child_resize_hook, sd);
55         sd->child_obj = NULL;
56      }
57    if (child)
58      {
59         Evas_Coord w, h;
60         int r, g, b, a;
61
62         sd->child_obj = child;
63         evas_object_smart_member_add(sd->child_obj, sd->smart_obj);
64         evas_object_geometry_get(sd->child_obj, NULL, NULL, &w, &h);
65         sd->child_w = w;
66         sd->child_h = h;
67         evas_object_event_callback_add(child, EVAS_CALLBACK_FREE, _smart_child_del_hook, sd);
68         evas_object_event_callback_add(child, EVAS_CALLBACK_RESIZE, _smart_child_resize_hook, sd);
69         evas_object_color_get(sd->smart_obj, &r, &g, &b, &a);
70         evas_object_color_set(sd->child_obj, r, g, b, a);
71         evas_object_clip_set(sd->child_obj, evas_object_clip_get(sd->smart_obj));
72         if (evas_object_visible_get(sd->smart_obj)) evas_object_show(sd->child_obj);
73         else evas_object_hide(sd->child_obj);
74         _smart_reconfigure(sd);
75      }
76    evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
77 }
78
79 Evas_Object *
80 _elm_smart_pan_child_get(Evas_Object *obj)
81 {
82    API_ENTRY return NULL;
83    return sd->child_obj;
84 }
85
86 void
87 _elm_smart_pan_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
88 {
89    API_ENTRY return;
90 //   if (x > (sd->child_w - sd->w)) x = sd->child_w - sd->w;
91 //   if (y > (sd->child_h - sd->h)) y = sd->child_h - sd->h;
92 //   if (x < 0) x = 0;
93 //   if (y < 0) y = 0;
94    if ((x == sd->px) && (y == sd->py)) return;
95    sd->px = x;
96    sd->py = y;
97    _smart_reconfigure(sd);
98    evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
99 }
100
101 void
102 _elm_smart_pan_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
103 {
104    API_ENTRY return;
105    if (x) *x = sd->px;
106    if (y) *y = sd->py;
107 }
108
109 void
110 _elm_smart_pan_max_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
111 {
112    API_ENTRY return;
113    if (x)
114      {
115         if (sd->w < sd->child_w) *x = sd->child_w - sd->w;
116         else *x = 0;
117      }
118    if (y)
119      {
120         if (sd->h < sd->child_h) *y = sd->child_h - sd->h;
121         else *y = 0;
122      }
123 }
124
125 void
126 _elm_smart_pan_min_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
127 {
128    API_ENTRY return;
129    if (x)
130       *x = 0;
131    if (y)
132       *y = 0;
133 }
134
135 void
136 _elm_smart_pan_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
137 {
138    API_ENTRY return;
139    if (w) *w = sd->child_w;
140    if (h) *h = sd->child_h;
141 }
142
143 /* local subsystem functions */
144 static void
145 _smart_child_del_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
146 {
147    Smart_Data *sd;
148
149    sd = data;
150    sd->child_obj = NULL;
151    evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
152 }
153
154 static void
155 _smart_child_resize_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
156 {
157    Smart_Data *sd;
158    Evas_Coord w, h;
159
160    sd = data;
161    evas_object_geometry_get(sd->child_obj, NULL, NULL, &w, &h);
162    if ((w != sd->child_w) || (h != sd->child_h))
163      {
164         sd->child_w = w;
165         sd->child_h = h;
166         _smart_reconfigure(sd);
167      }
168    evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
169 }
170
171 static void
172 _smart_reconfigure(Smart_Data *sd)
173 {
174    evas_object_move(sd->child_obj, sd->x - sd->px, sd->y - sd->py);
175 }
176
177 static void
178 _smart_add(Evas_Object *obj)
179 {
180    Smart_Data *sd;
181
182    sd = calloc(1, sizeof(Smart_Data));
183    if (!sd) return;
184    sd->smart_obj = obj;
185    sd->x = 0;
186    sd->y = 0;
187    sd->w = 0;
188    sd->h = 0;
189    evas_object_smart_data_set(obj, sd);
190 }
191
192 static void
193 _smart_del(Evas_Object *obj)
194 {
195    INTERNAL_ENTRY;
196    _elm_smart_pan_child_set(obj, NULL);
197    free(sd);
198 }
199
200 static void
201 _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
202 {
203    INTERNAL_ENTRY;
204    sd->x = x;
205    sd->y = y;
206    _smart_reconfigure(sd);
207 }
208
209 static void
210 _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
211 {
212    INTERNAL_ENTRY;
213    sd->w = w;
214    sd->h = h;
215    _smart_reconfigure(sd);
216    evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
217 }
218
219 static void
220 _smart_show(Evas_Object *obj)
221 {
222    INTERNAL_ENTRY;
223    evas_object_show(sd->child_obj);
224 }
225
226 static void
227 _smart_hide(Evas_Object *obj)
228 {
229    INTERNAL_ENTRY;
230    evas_object_hide(sd->child_obj);
231 }
232
233 static void
234 _smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
235 {
236    INTERNAL_ENTRY;
237    evas_object_color_set(sd->child_obj, r, g, b, a);
238 }
239
240 static void
241 _smart_clip_set(Evas_Object *obj, Evas_Object *clip)
242 {
243    INTERNAL_ENTRY;
244    evas_object_clip_set(sd->child_obj, clip);
245 }
246
247 static void
248 _smart_clip_unset(Evas_Object *obj)
249 {
250    INTERNAL_ENTRY;
251    evas_object_clip_unset(sd->child_obj);
252 }
253
254 /* never need to touch this */
255
256 static void
257 _smart_init(void)
258 {
259    if (_smart) return;
260      {
261         static const Evas_Smart_Class sc =
262           {
263              SMART_NAME,
264                EVAS_SMART_CLASS_VERSION,
265                _smart_add,
266                _smart_del,
267                _smart_move,
268                _smart_resize,
269                _smart_show,
270                _smart_hide,
271                _smart_color_set,
272                _smart_clip_set,
273                _smart_clip_unset,
274                NULL,
275                NULL,
276                NULL,
277                NULL,
278                NULL,
279                NULL,
280                NULL
281           };
282         _smart = evas_smart_class_new(&sc);
283      }
284 }
285