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