[
[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_child_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
127 {
128    API_ENTRY return;
129    if (w) *w = sd->child_w;
130    if (h) *h = sd->child_h;
131 }
132
133 /* local subsystem functions */
134 static void
135 _smart_child_del_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
136 {
137    Smart_Data *sd;
138
139    sd = data;
140    sd->child_obj = NULL;
141    evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
142 }
143
144 static void
145 _smart_child_resize_hook(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
146 {
147    Smart_Data *sd;
148    Evas_Coord w, h;
149
150    sd = data;
151    evas_object_geometry_get(sd->child_obj, NULL, NULL, &w, &h);
152    if ((w != sd->child_w) || (h != sd->child_h))
153      {
154         sd->child_w = w;
155         sd->child_h = h;
156         _smart_reconfigure(sd);
157      }
158    evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
159 }
160
161 static void
162 _smart_reconfigure(Smart_Data *sd)
163 {
164    evas_object_move(sd->child_obj, sd->x - sd->px, sd->y - sd->py);
165 }
166
167 static void
168 _smart_add(Evas_Object *obj)
169 {
170    Smart_Data *sd;
171
172    sd = calloc(1, sizeof(Smart_Data));
173    if (!sd) return;
174    sd->smart_obj = obj;
175    sd->x = 0;
176    sd->y = 0;
177    sd->w = 0;
178    sd->h = 0;
179    evas_object_smart_data_set(obj, sd);
180 }
181
182 static void
183 _smart_del(Evas_Object *obj)
184 {
185    INTERNAL_ENTRY;
186    _elm_smart_pan_child_set(obj, NULL);
187    free(sd);
188 }
189
190 static void
191 _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
192 {
193    INTERNAL_ENTRY;
194    sd->x = x;
195    sd->y = y;
196    _smart_reconfigure(sd);
197 }
198
199 static void
200 _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
201 {
202    INTERNAL_ENTRY;
203    sd->w = w;
204    sd->h = h;
205    _smart_reconfigure(sd);
206    evas_object_smart_callback_call(sd->smart_obj, "changed", NULL);
207 }
208
209 static void
210 _smart_show(Evas_Object *obj)
211 {
212    INTERNAL_ENTRY;
213    evas_object_show(sd->child_obj);
214 }
215
216 static void
217 _smart_hide(Evas_Object *obj)
218 {
219    INTERNAL_ENTRY;
220    evas_object_hide(sd->child_obj);
221 }
222
223 static void
224 _smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
225 {
226    INTERNAL_ENTRY;
227    evas_object_color_set(sd->child_obj, r, g, b, a);
228 }
229
230 static void
231 _smart_clip_set(Evas_Object *obj, Evas_Object *clip)
232 {
233    INTERNAL_ENTRY;
234    evas_object_clip_set(sd->child_obj, clip);
235 }
236
237 static void
238 _smart_clip_unset(Evas_Object *obj)
239 {
240    INTERNAL_ENTRY;
241    evas_object_clip_unset(sd->child_obj);
242 }
243
244 /* never need to touch this */
245
246 static void
247 _smart_init(void)
248 {
249    if (_smart) return;
250      {
251         static const Evas_Smart_Class sc =
252           {
253              SMART_NAME,
254                EVAS_SMART_CLASS_VERSION,
255                _smart_add,
256                _smart_del,
257                _smart_move,
258                _smart_resize,
259                _smart_show,
260                _smart_hide,
261                _smart_color_set,
262                _smart_clip_set,
263                _smart_clip_unset,
264                NULL,
265                NULL,
266                NULL,
267                NULL,
268                NULL,
269                NULL,
270                NULL
271           };
272         _smart = evas_smart_class_new(&sc);
273      }
274 }
275