1 #include "e.h"
2
3 #define SMART_NAME "e_scrollframe"
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_Coord x, y, w, h;
11
12 Evas_Object *smart_obj;
13 Evas_Object *child_obj;
14 Evas_Object *pan_obj;
15 Evas_Object *edje_obj;
16 Evas_Object *event_obj;
17
18 E_Scrollframe_Policy hbar_flags, vbar_flags;
19
20 struct
21 {
22 Evas_Coord x, y;
23 Evas_Coord sx, sy;
24 Evas_Coord dx, dy;
25 struct
26 {
27 Evas_Coord x, y;
28 double timestamp;
29 } history[20];
30 double anim_start;
31 Ecore_Animator *momentum_animator;
32 Evas_Coord locked_x, locked_y;
33 unsigned char now E_BITFIELD;
34 unsigned char dragged E_BITFIELD;
35 unsigned char dir_x E_BITFIELD;
36 unsigned char dir_y E_BITFIELD;
37 unsigned char locked E_BITFIELD;
38 } down;
39
40 struct
41 {
42 Evas_Coord w, h;
43 } child;
44 struct
45 {
46 Evas_Coord x, y;
47 } step, page;
48
49 struct
50 {
51 void (*set)(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
52 void (*get)(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
53 void (*max_get)(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
54 void (*child_size_get)(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y);
55 } pan_func;
56 struct
57 {
58 Eina_Bool forced E_BITFIELD;
59 } thumbscroll;
60
61 unsigned char hbar_visible E_BITFIELD;
62 unsigned char vbar_visible E_BITFIELD;
63 unsigned char extern_pan E_BITFIELD;
64 unsigned char one_dir_at_a_time E_BITFIELD;
65 Eina_Bool key_nav E_BITFIELD;
66 };
67
68 /* local subsystem functions */
69 static void _e_smart_child_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
70 static void _e_smart_pan_changed_hook(void *data, Evas_Object *obj, void *event_info);
71 static void _e_smart_pan_pan_changed_hook(void *data, Evas_Object *obj, void *event_info);
72 static void _e_smart_event_wheel(void *data, Evas *e, Evas_Object *obj, void *event_info);
73 static void _e_smart_event_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
74 static Eina_Bool _e_smart_momentum_animator(void *data);
75 static void _e_smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info);
76 static void _e_smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj, void *event_info);
77 static void _e_smart_event_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
78 static void _e_smart_edje_drag_v(void *data, Evas_Object *obj, const char *emission, const char *source);
79 static void _e_smart_edje_drag_h(void *data, Evas_Object *obj, const char *emission, const char *source);
80 static void _e_smart_scrollbar_read(E_Smart_Data *sd);
81 static void _e_smart_scrollbar_reset(E_Smart_Data *sd);
82 static int _e_smart_scrollbar_bar_h_visibility_adjust(E_Smart_Data *sd);
83 static int _e_smart_scrollbar_bar_v_visibility_adjust(E_Smart_Data *sd);
84 static void _e_smart_scrollbar_bar_visibility_adjust(E_Smart_Data *sd);
85 static void _e_smart_scrollbar_size_adjust(E_Smart_Data *sd);
86 static void _e_smart_reconfigure(E_Smart_Data *sd);
87 static void _e_smart_add(Evas_Object *obj);
88 static void _e_smart_del(Evas_Object *obj);
89 static void _e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
90 static void _e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
91 static void _e_smart_show(Evas_Object *obj);
92 static void _e_smart_hide(Evas_Object *obj);
93 static void _e_smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
94 static void _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
95 static void _e_smart_clip_unset(Evas_Object *obj);
96 static void _e_smart_init(void);
97
98 /* local subsystem globals */
99 static Evas_Smart *_e_smart = NULL;
100
101 /* externally accessible functions */
102 E_API Evas_Object *
e_scrollframe_add(Evas * evas)103 e_scrollframe_add(Evas *evas)
104 {
105 _e_smart_init();
106 return evas_object_smart_add(evas, _e_smart);
107 }
108
109 E_API void
e_scrollframe_child_set(Evas_Object * obj,Evas_Object * child)110 e_scrollframe_child_set(Evas_Object *obj, Evas_Object *child)
111 {
112 Evas_Object *o;
113
114 API_ENTRY return;
115 if (sd->child_obj)
116 {
117 if (sd->pan_obj)
118 {
119 e_pan_child_set(sd->pan_obj, NULL);
120 evas_object_event_callback_del(sd->child_obj, EVAS_CALLBACK_FREE,
121 _e_smart_child_del_hook);
122 }
123 }
124
125 sd->child_obj = child;
126 if (!child) return;
127
128 if (!sd->pan_obj)
129 {
130 o = e_pan_add(evas_object_evas_get(obj));
131 sd->pan_obj = o;
132 evas_object_smart_callback_add(o, "changed",
133 _e_smart_pan_changed_hook, sd);
134 evas_object_smart_callback_add(o, "pan_changed",
135 _e_smart_pan_pan_changed_hook, sd);
136 evas_object_show(o);
137 edje_object_part_swallow(sd->edje_obj, "e.swallow.content", o);
138 }
139
140 sd->pan_func.set = e_pan_set;
141 sd->pan_func.get = e_pan_get;
142 sd->pan_func.max_get = e_pan_max_get;
143 sd->pan_func.child_size_get = e_pan_child_size_get;
144
145 evas_object_event_callback_add(child, EVAS_CALLBACK_FREE,
146 _e_smart_child_del_hook, sd);
147 e_pan_child_set(sd->pan_obj, sd->child_obj);
148 sd->pan_func.child_size_get(sd->pan_obj, &sd->child.w, &sd->child.h);
149 _e_smart_scrollbar_size_adjust(sd);
150 _e_smart_scrollbar_reset(sd);
151 }
152
153 E_API void
e_scrollframe_extern_pan_set(Evas_Object * obj,Evas_Object * pan,void (* pan_set)(Evas_Object * obj,Evas_Coord x,Evas_Coord y),void (* pan_get)(Evas_Object * obj,Evas_Coord * x,Evas_Coord * y),void (* pan_max_get)(Evas_Object * obj,Evas_Coord * x,Evas_Coord * y),void (* pan_child_size_get)(Evas_Object * obj,Evas_Coord * x,Evas_Coord * y))154 e_scrollframe_extern_pan_set(Evas_Object *obj, Evas_Object *pan,
155 void (*pan_set)(Evas_Object *obj, Evas_Coord x, Evas_Coord y),
156 void (*pan_get)(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y),
157 void (*pan_max_get)(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y),
158 void (*pan_child_size_get)(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y))
159 {
160 API_ENTRY return;
161
162 e_scrollframe_child_set(obj, NULL);
163 if (sd->extern_pan)
164 {
165 if (sd->pan_obj)
166 {
167 edje_object_part_unswallow(sd->edje_obj, sd->pan_obj);
168 sd->pan_obj = NULL;
169 }
170 }
171 else
172 {
173 if (sd->pan_obj)
174 {
175 evas_object_del(sd->pan_obj);
176 sd->pan_obj = NULL;
177 }
178 }
179 if (!pan)
180 {
181 sd->extern_pan = 0;
182 return;
183 }
184
185 sd->pan_obj = pan;
186 sd->pan_func.set = pan_set;
187 sd->pan_func.get = pan_get;
188 sd->pan_func.max_get = pan_max_get;
189 sd->pan_func.child_size_get = pan_child_size_get;
190 sd->extern_pan = 1;
191 evas_object_smart_callback_add(sd->pan_obj, "changed",
192 _e_smart_pan_changed_hook, sd);
193 evas_object_smart_callback_add(sd->pan_obj, "pan_changed",
194 _e_smart_pan_pan_changed_hook, sd);
195 edje_object_part_swallow(sd->edje_obj, "e.swallow.content", sd->pan_obj);
196 evas_object_show(sd->pan_obj);
197 }
198
199 E_API int
e_scrollframe_custom_theme_set(Evas_Object * obj,const char * custom_category,const char * custom_group)200 e_scrollframe_custom_theme_set(Evas_Object *obj, const char *custom_category, const char *custom_group)
201 {
202 API_ENTRY return 0;
203
204 if (!e_theme_edje_object_set(sd->edje_obj, custom_category, custom_group))
205 return 0;
206 if (sd->pan_obj)
207 edje_object_part_swallow(sd->edje_obj, "e.swallow.content", sd->pan_obj);
208 sd->vbar_visible = !sd->vbar_visible;
209 sd->hbar_visible = !sd->hbar_visible;
210 _e_smart_scrollbar_bar_visibility_adjust(sd);
211 return 1;
212 }
213
214 E_API int
e_scrollframe_custom_edje_file_set(Evas_Object * obj,const char * file,const char * group)215 e_scrollframe_custom_edje_file_set(Evas_Object *obj, const char *file, const char *group)
216 {
217 API_ENTRY return 0;
218
219 if (!edje_object_file_set(sd->edje_obj, file, group)) return 0;
220 if (sd->pan_obj)
221 edje_object_part_swallow(sd->edje_obj, "e.swallow.content", sd->pan_obj);
222 sd->vbar_visible = !sd->vbar_visible;
223 sd->hbar_visible = !sd->hbar_visible;
224 _e_smart_scrollbar_bar_visibility_adjust(sd);
225 return 1;
226 }
227
228 E_API void
e_scrollframe_child_pos_set(Evas_Object * obj,Evas_Coord x,Evas_Coord y)229 e_scrollframe_child_pos_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
230 {
231 Evas_Coord mx = 0, my = 0;
232 double vx, vy;
233
234 API_ENTRY return;
235 if (!sd->pan_obj) return;
236 sd->pan_func.max_get(sd->pan_obj, &mx, &my);
237 if (mx > 0) vx = (double)x / (double)mx;
238 else vx = 0.0;
239 if (vx < 0.0) vx = 0.0;
240 else if (vx > 1.0)
241 vx = 1.0;
242 if (my > 0) vy = (double)y / (double)my;
243 else vy = 0.0;
244 if (vy < 0.0) vy = 0.0;
245 else if (vy > 1.0)
246 vy = 1.0;
247 edje_object_part_drag_value_set(sd->edje_obj, "e.dragable.vbar", 0.0, vy);
248 edje_object_part_drag_value_set(sd->edje_obj, "e.dragable.hbar", vx, 0.0);
249 sd->pan_func.set(sd->pan_obj, x, y);
250 }
251
252 E_API void
e_scrollframe_child_pos_get(Evas_Object * obj,Evas_Coord * x,Evas_Coord * y)253 e_scrollframe_child_pos_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
254 {
255 API_ENTRY return;
256 if (sd->pan_obj)
257 sd->pan_func.get(sd->pan_obj, x, y);
258 else
259 {
260 *x = 0;
261 *y = 0;
262 }
263 }
264
265 E_API void
e_scrollframe_child_region_show(Evas_Object * obj,Evas_Coord x,Evas_Coord y,Evas_Coord w,Evas_Coord h)266 e_scrollframe_child_region_show(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
267 {
268 Evas_Coord mx = 0, my = 0, cw = 0, ch = 0, px = 0, py = 0, nx, ny, vw, vh;
269
270 API_ENTRY return;
271 if (!sd->pan_obj) return;
272 sd->pan_func.max_get(sd->pan_obj, &mx, &my);
273 sd->pan_func.child_size_get(sd->pan_obj, &cw, &ch);
274 sd->pan_func.get(sd->pan_obj, &px, &py);
275 e_scrollframe_child_viewport_size_get(obj, &vw, &vh);
276
277 /* Abort if the request region is already shown */
278 if ((px <= x) && (py <= y) && (x + w <= px + vw) && (y + h <= py + vh))
279 return;
280
281 nx = px;
282 if (x < px) nx = x;
283 else if ((x + w) > (px + (cw - mx)))
284 {
285 nx = x + w - (cw - mx);
286 if (nx > x) nx = x;
287 }
288 ny = py;
289 if (y < py) ny = y;
290 else if ((y + h) > (py + (ch - my)))
291 {
292 ny = y + h - (ch - my);
293 if (ny > y) ny = y;
294 }
295 if ((nx == px) && (ny == py)) return;
296 e_scrollframe_child_pos_set(obj, nx, ny);
297 }
298
299 E_API void
e_scrollframe_child_viewport_size_get(Evas_Object * obj,Evas_Coord * w,Evas_Coord * h)300 e_scrollframe_child_viewport_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
301 {
302 API_ENTRY return;
303 edje_object_calc_force(sd->edje_obj);
304 edje_object_part_geometry_get(sd->edje_obj,
305 "e.swallow.content", NULL, NULL, w, h);
306 }
307
308 E_API void
e_scrollframe_step_size_set(Evas_Object * obj,Evas_Coord x,Evas_Coord y)309 e_scrollframe_step_size_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
310 {
311 API_ENTRY return;
312 if (x < 1) x = 1;
313 if (y < 1) y = 1;
314 sd->step.x = x;
315 sd->step.y = y;
316 _e_smart_scrollbar_size_adjust(sd);
317 }
318
319 E_API void
e_scrollframe_step_size_get(Evas_Object * obj,Evas_Coord * x,Evas_Coord * y)320 e_scrollframe_step_size_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
321 {
322 API_ENTRY return;
323 if (x) *x = sd->step.x;
324 if (y) *y = sd->step.y;
325 }
326
327 E_API void
e_scrollframe_page_size_set(Evas_Object * obj,Evas_Coord x,Evas_Coord y)328 e_scrollframe_page_size_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
329 {
330 API_ENTRY return;
331 sd->page.x = x;
332 sd->page.y = y;
333 _e_smart_scrollbar_size_adjust(sd);
334 }
335
336 E_API void
e_scrollframe_page_size_get(Evas_Object * obj,Evas_Coord * x,Evas_Coord * y)337 e_scrollframe_page_size_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y)
338 {
339 API_ENTRY return;
340 if (x) *x = sd->page.x;
341 if (y) *y = sd->page.y;
342 }
343
344 E_API void
e_scrollframe_policy_set(Evas_Object * obj,E_Scrollframe_Policy hbar,E_Scrollframe_Policy vbar)345 e_scrollframe_policy_set(Evas_Object *obj, E_Scrollframe_Policy hbar, E_Scrollframe_Policy vbar)
346 {
347 API_ENTRY return;
348 if ((sd->hbar_flags == hbar) && (sd->vbar_flags == vbar)) return;
349 sd->hbar_flags = hbar;
350 sd->vbar_flags = vbar;
351 sd->vbar_visible = !sd->vbar_visible;
352 sd->hbar_visible = !sd->hbar_visible;
353 _e_smart_scrollbar_size_adjust(sd);
354 }
355
356 E_API void
e_scrollframe_policy_get(Evas_Object * obj,E_Scrollframe_Policy * hbar,E_Scrollframe_Policy * vbar)357 e_scrollframe_policy_get(Evas_Object *obj, E_Scrollframe_Policy *hbar, E_Scrollframe_Policy *vbar)
358 {
359 API_ENTRY return;
360 if (hbar) *hbar = sd->hbar_flags;
361 if (vbar) *vbar = sd->vbar_flags;
362 }
363
364 E_API Evas_Object *
e_scrollframe_edje_object_get(Evas_Object * obj)365 e_scrollframe_edje_object_get(Evas_Object *obj)
366 {
367 API_ENTRY return NULL;
368 return sd->edje_obj;
369 }
370
371 E_API void
e_scrollframe_single_dir_set(Evas_Object * obj,Eina_Bool single_dir)372 e_scrollframe_single_dir_set(Evas_Object *obj, Eina_Bool single_dir)
373 {
374 API_ENTRY return;
375 sd->one_dir_at_a_time = single_dir;
376 }
377
378 E_API Eina_Bool
e_scrollframe_single_dir_get(Evas_Object * obj)379 e_scrollframe_single_dir_get(Evas_Object *obj)
380 {
381 API_ENTRY return EINA_FALSE;
382 return sd->one_dir_at_a_time;
383 }
384
385 E_API void
e_scrollframe_thumbscroll_force(Evas_Object * obj,Eina_Bool forced)386 e_scrollframe_thumbscroll_force(Evas_Object *obj, Eina_Bool forced)
387 {
388 API_ENTRY return;
389 sd->thumbscroll.forced = forced;
390 }
391
392 E_API void
e_scrollframe_key_navigation_set(Evas_Object * obj,Eina_Bool enabled)393 e_scrollframe_key_navigation_set(Evas_Object *obj, Eina_Bool enabled)
394 {
395 API_ENTRY return;
396 if (enabled == sd->key_nav)
397 return;
398
399 sd->key_nav = enabled;
400 if (sd->key_nav)
401 evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN,
402 _e_smart_event_key_down, sd);
403 else
404 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_KEY_DOWN,
405 _e_smart_event_key_down, sd);
406 }
407
408 /* local subsystem functions */
409 static void
_e_smart_edje_drag_v(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)410 _e_smart_edje_drag_v(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
411 {
412 E_Smart_Data *sd;
413
414 sd = data;
415 _e_smart_scrollbar_read(sd);
416 }
417
418 static void
_e_smart_edje_drag_h(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)419 _e_smart_edje_drag_h(void *data, Evas_Object *obj EINA_UNUSED, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
420 {
421 E_Smart_Data *sd;
422
423 sd = data;
424 _e_smart_scrollbar_read(sd);
425 }
426
427 static void
_e_smart_child_del_hook(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)428 _e_smart_child_del_hook(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
429 {
430 E_Smart_Data *sd;
431
432 sd = data;
433 sd->child_obj = NULL;
434 _e_smart_scrollbar_size_adjust(sd);
435 _e_smart_scrollbar_reset(sd);
436 }
437
438 static void
_e_smart_pan_changed_hook(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)439 _e_smart_pan_changed_hook(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
440 {
441 Evas_Coord w, h;
442 E_Smart_Data *sd;
443
444 sd = data;
445 if (!sd->pan_obj) return;
446 sd->pan_func.child_size_get(sd->pan_obj, &w, &h);
447 if ((w != sd->child.w) || (h != sd->child.h))
448 {
449 sd->child.w = w;
450 sd->child.h = h;
451 _e_smart_scrollbar_size_adjust(sd);
452 }
453 }
454
455 static void
_e_smart_pan_pan_changed_hook(void * data,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)456 _e_smart_pan_pan_changed_hook(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
457 {
458 Evas_Coord x, y;
459 E_Smart_Data *sd;
460
461 sd = data;
462 if (!sd->pan_obj) return;
463 sd->pan_func.get(sd->pan_obj, &x, &y);
464 e_scrollframe_child_pos_set(sd->smart_obj, x, y);
465 }
466
467 static void
_e_smart_event_wheel(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)468 _e_smart_event_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
469 {
470 Evas_Event_Mouse_Wheel *ev;
471 E_Smart_Data *sd;
472 Evas_Coord x = 0, y = 0;
473
474 sd = data;
475 ev = event_info;
476 e_scrollframe_child_pos_get(sd->smart_obj, &x, &y);
477
478 if ((sd->vbar_visible) && ((ev->direction % 2 == 0) || (!sd->hbar_visible)))
479 y += ev->z * sd->step.y;
480 else if ((sd->hbar_visible) &&
481 ((ev->direction % 2 == 1) || (!sd->vbar_visible)))
482 x += ev->z * sd->step.x;
483
484 e_scrollframe_child_pos_set(sd->smart_obj, x, y);
485 }
486
487 static void
_e_smart_event_mouse_down(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)488 _e_smart_event_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
489 {
490 Evas_Event_Mouse_Down *ev;
491 E_Smart_Data *sd;
492
493 sd = data;
494 ev = event_info;
495 if ((e_config->thumbscroll_enable) || (sd->thumbscroll.forced))
496 {
497 if (sd->down.momentum_animator)
498 {
499 ecore_animator_del(sd->down.momentum_animator);
500 sd->down.momentum_animator = NULL;
501 }
502 if (ev->button == 1)
503 {
504 sd->down.now = 1;
505 sd->down.dragged = 0;
506 sd->down.dir_x = 0;
507 sd->down.dir_y = 0;
508 sd->down.x = ev->canvas.x;
509 sd->down.y = ev->canvas.y;
510 e_scrollframe_child_pos_get(sd->smart_obj,
511 &sd->down.sx, &sd->down.sy);
512 sd->down.locked = 0;
513 memset(&(sd->down.history[0]), 0, sizeof(sd->down.history[0]) * 20);
514 sd->down.history[0].timestamp = ecore_loop_time_get();
515 sd->down.history[0].x = ev->canvas.x;
516 sd->down.history[0].y = ev->canvas.y;
517 }
518 }
519 }
520
521 static Eina_Bool
_e_smart_momentum_animator(void * data)522 _e_smart_momentum_animator(void *data)
523 {
524 E_Smart_Data *sd;
525 double t, dt, p;
526 Evas_Coord x, y, dx, dy;
527
528 sd = data;
529 t = ecore_loop_time_get();
530 dt = t - sd->down.anim_start;
531 if (dt >= 0.0)
532 {
533 dt = dt / e_config->thumbscroll_friction;
534 if (dt > 1.0) dt = 1.0;
535 p = 1.0 - ((1.0 - dt) * (1.0 - dt) * (1.0 - dt));
536 dx = (sd->down.dx * e_config->thumbscroll_friction * p);
537 dy = (sd->down.dy * e_config->thumbscroll_friction * p);
538 x = sd->down.sx - dx;
539 y = sd->down.sy - dy;
540 e_scrollframe_child_pos_set(sd->smart_obj, x, y);
541 if (dt >= 1.0)
542 {
543 sd->down.momentum_animator = NULL;
544 return ECORE_CALLBACK_CANCEL;
545 }
546 }
547 return ECORE_CALLBACK_RENEW;
548 }
549
550 static void
_e_smart_event_mouse_up(void * data,Evas * e,Evas_Object * obj EINA_UNUSED,void * event_info)551 _e_smart_event_mouse_up(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info)
552 {
553 Evas_Event_Mouse_Down *ev;
554 E_Smart_Data *sd;
555 Evas_Coord x = 0, y = 0;
556
557 sd = data;
558 ev = event_info;
559 if ((e_config->thumbscroll_enable) || (sd->thumbscroll.forced))
560 {
561 if (ev->button == 1)
562 {
563 x = ev->canvas.x - sd->down.x;
564 y = ev->canvas.y - sd->down.y;
565 if (sd->down.dragged)
566 {
567 double t, at, dt;
568 int i;
569 Evas_Coord ax, ay, dx, dy, vel;
570
571 t = ecore_loop_time_get();
572 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
573 ax = ev->canvas.x;
574 ay = ev->canvas.y;
575 at = 0.0;
576 for (i = 0; i < 20; i++)
577 {
578 dt = t - sd->down.history[i].timestamp;
579 if (dt > 0.2) break;
580 at += dt;
581 ax += sd->down.history[i].x;
582 ay += sd->down.history[i].y;
583 }
584 ax /= (i + 1);
585 ay /= (i + 1);
586 at /= (i + 1);
587 at *= 4.0;
588 dx = ev->canvas.x - ax;
589 dy = ev->canvas.y - ay;
590 if (at > 0)
591 {
592 vel = sqrt((dx * dx) + (dy * dy)) / at;
593 if ((e_config->thumbscroll_friction > 0.0) &&
594 (vel > e_config->thumbscroll_momentum_threshhold))
595 {
596 if (!sd->down.momentum_animator)
597 sd->down.momentum_animator =
598 ecore_animator_add(_e_smart_momentum_animator, sd);
599 sd->down.dx = ((double)dx / at);
600 sd->down.dy = ((double)dy / at);
601 sd->down.anim_start = t;
602 e_scrollframe_child_pos_get(sd->smart_obj, &x, &y);
603 sd->down.sx = x;
604 sd->down.sy = y;
605 }
606 }
607 evas_event_feed_hold(e, 0, ev->timestamp, ev->data);
608 }
609 sd->down.dragged = 0;
610 sd->down.now = 0;
611 }
612 }
613 }
614
615 static void
_e_smart_event_mouse_move(void * data,Evas * e,Evas_Object * obj EINA_UNUSED,void * event_info)616 _e_smart_event_mouse_move(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info)
617 {
618 Evas_Event_Mouse_Move *ev;
619 E_Smart_Data *sd;
620 Evas_Coord x = 0, y = 0;
621
622 sd = data;
623 ev = event_info;
624 if ((e_config->thumbscroll_enable) || (sd->thumbscroll.forced))
625 {
626 if (sd->down.now)
627 {
628 memmove(&(sd->down.history[1]), &(sd->down.history[0]),
629 sizeof(sd->down.history[0]) * 19);
630 sd->down.history[0].timestamp = ecore_loop_time_get();
631 sd->down.history[0].x = ev->cur.canvas.x;
632 sd->down.history[0].y = ev->cur.canvas.y;
633
634 x = ev->cur.canvas.x - sd->down.x;
635 if (x < 0) x = -x;
636 y = ev->cur.canvas.y - sd->down.y;
637 if (y < 0) y = -y;
638 if ((sd->one_dir_at_a_time) &&
639 (!sd->down.dir_x) && (!sd->down.dir_y))
640 {
641 if (x > y)
642 {
643 if (x > e_config->thumbscroll_threshhold)
644 {
645 sd->down.dir_x = 1;
646 sd->down.dir_y = 0;
647 }
648 }
649 else
650 {
651 if (y > e_config->thumbscroll_threshhold)
652 {
653 sd->down.dir_x = 0;
654 sd->down.dir_y = 1;
655 }
656 }
657 }
658 if ((sd->down.dragged) ||
659 (((x * x) + (y * y)) >
660 (e_config->thumbscroll_threshhold *
661 e_config->thumbscroll_threshhold)))
662 {
663 if ((e_config->thumbscroll_enable) ||
664 (sd->thumbscroll.forced))
665 {
666 if (!sd->down.dragged)
667 evas_event_feed_hold(e, 1, ev->timestamp, ev->data);
668 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
669 sd->down.dragged = 1;
670 x = sd->down.sx - (ev->cur.canvas.x - sd->down.x);
671 y = sd->down.sy - (ev->cur.canvas.y - sd->down.y);
672 if ((sd->down.dir_x) || (sd->down.dir_y))
673 {
674 if (!sd->down.locked)
675 {
676 sd->down.locked_x = x;
677 sd->down.locked_y = y;
678 sd->down.locked = 1;
679 }
680 if (sd->down.dir_x) y = sd->down.locked_y;
681 else x = sd->down.locked_x;
682 }
683 e_scrollframe_child_pos_set(sd->smart_obj, x, y);
684 }
685 }
686 }
687 }
688 }
689
690 static void
_e_smart_event_key_down(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)691 _e_smart_event_key_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
692 {
693 Evas_Event_Key_Down *ev;
694 E_Smart_Data *sd;
695 Evas_Coord x = 0, y = 0, vw = 0, vh = 0, mx = 0, my = 0;
696
697 sd = data;
698 ev = event_info;
699 e_scrollframe_child_pos_get(sd->smart_obj, &x, &y);
700 if (!sd->pan_obj) return;
701 sd->pan_func.max_get(sd->pan_obj, &mx, &my);
702 edje_object_part_geometry_get(sd->edje_obj, "e.swallow.content", NULL, NULL, &vw, &vh);
703 if (!strcmp(ev->key, "Left"))
704 x -= sd->step.x;
705 else if (!strcmp(ev->key, "Right"))
706 x += sd->step.x;
707 else if (!strcmp(ev->key, "Up"))
708 y -= sd->step.y;
709 else if (!strcmp(ev->key, "Home"))
710 y = 0;
711 else if (!strcmp(ev->key, "End"))
712 y = my;
713 else if (!strcmp(ev->key, "Down"))
714 y += sd->step.y;
715 else if (!strcmp(ev->key, "Prior"))
716 {
717 if (sd->page.y < 0)
718 y -= -(sd->page.y * vh) / 100;
719 else
720 y -= sd->page.y;
721 }
722 else if (!strcmp(ev->key, "Next"))
723 {
724 if (sd->page.y < 0)
725 y += -(sd->page.y * vh) / 100;
726 else
727 y += sd->page.y;
728 }
729 e_scrollframe_child_pos_set(sd->smart_obj, x, y);
730 }
731
732 static void
_e_smart_scrollbar_read(E_Smart_Data * sd)733 _e_smart_scrollbar_read(E_Smart_Data *sd)
734 {
735 Evas_Coord x, y, mx = 0, my = 0;
736 double vx = 0.0, vy = 0.0;
737
738 edje_object_part_drag_value_get(sd->edje_obj, "e.dragable.vbar", NULL, &vy);
739 edje_object_part_drag_value_get(sd->edje_obj, "e.dragable.hbar", &vx, NULL);
740 if (!sd->pan_obj) return;
741 sd->pan_func.max_get(sd->pan_obj, &mx, &my);
742 x = vx * (double)mx;
743 y = vy * (double)my;
744 if (sd->pan_obj)
745 sd->pan_func.set(sd->pan_obj, x, y);
746 if (((e_config->thumbscroll_enable) || (sd->thumbscroll.forced))
747 && (sd->down.now) && (!sd->down.dragged))
748 sd->down.now = 0;
749 }
750
751 static void
_e_smart_scrollbar_reset(E_Smart_Data * sd)752 _e_smart_scrollbar_reset(E_Smart_Data *sd)
753 {
754 edje_object_part_drag_value_set(sd->edje_obj, "e.dragable.vbar", 0.0, 0.0);
755 edje_object_part_drag_value_set(sd->edje_obj, "e.dragable.hbar", 0.0, 0.0);
756 if ((!sd->child_obj) && (!sd->extern_pan))
757 {
758 edje_object_part_drag_size_set(sd->edje_obj, "e.dragable.vbar", 1.0, 1.0);
759 edje_object_part_drag_size_set(sd->edje_obj, "e.dragable.hbar", 1.0, 1.0);
760 }
761 if (sd->pan_obj)
762 sd->pan_func.set(sd->pan_obj, 0, 0);
763 }
764
765 static int
_e_smart_scrollbar_bar_v_visibility_adjust(E_Smart_Data * sd)766 _e_smart_scrollbar_bar_v_visibility_adjust(E_Smart_Data *sd)
767 {
768 int scroll_v_vis_change = 0;
769 Evas_Coord h, vh;
770
771 h = sd->child.h;
772 edje_object_part_geometry_get(sd->edje_obj, "e.swallow.content",
773 NULL, NULL, NULL, &vh);
774 if (sd->vbar_visible)
775 {
776 if (sd->vbar_flags == E_SCROLLFRAME_POLICY_AUTO)
777 {
778 if ((sd->child_obj) || (sd->extern_pan))
779 {
780 if (h <= vh)
781 {
782 scroll_v_vis_change = 1;
783 sd->vbar_visible = 0;
784 }
785 }
786 else
787 {
788 scroll_v_vis_change = 1;
789 sd->vbar_visible = 0;
790 }
791 }
792 else if (sd->vbar_flags == E_SCROLLFRAME_POLICY_OFF)
793 {
794 scroll_v_vis_change = 1;
795 sd->vbar_visible = 0;
796 }
797 }
798 else
799 {
800 if (sd->vbar_flags == E_SCROLLFRAME_POLICY_AUTO)
801 {
802 if ((sd->child_obj) || (sd->extern_pan))
803 {
804 if (h > vh)
805 {
806 scroll_v_vis_change = 1;
807 sd->vbar_visible = 1;
808 }
809 }
810 }
811 else if (sd->vbar_flags == E_SCROLLFRAME_POLICY_ON)
812 {
813 scroll_v_vis_change = 1;
814 sd->vbar_visible = 1;
815 }
816 }
817 if (scroll_v_vis_change)
818 {
819 if (sd->vbar_visible)
820 edje_object_signal_emit(sd->edje_obj, "e,action,show,vbar", "e");
821 else
822 edje_object_signal_emit(sd->edje_obj, "e,action,hide,vbar", "e");
823 edje_object_message_signal_process(sd->edje_obj);
824 _e_smart_scrollbar_size_adjust(sd);
825 }
826 return scroll_v_vis_change;
827 }
828
829 static int
_e_smart_scrollbar_bar_h_visibility_adjust(E_Smart_Data * sd)830 _e_smart_scrollbar_bar_h_visibility_adjust(E_Smart_Data *sd)
831 {
832 int scroll_h_vis_change = 0;
833 Evas_Coord w, vw;
834
835 w = sd->child.w;
836 edje_object_part_geometry_get(sd->edje_obj, "e.swallow.content",
837 NULL, NULL, &vw, NULL);
838 if (sd->hbar_visible)
839 {
840 if (sd->hbar_flags == E_SCROLLFRAME_POLICY_AUTO)
841 {
842 if ((sd->child_obj) || (sd->extern_pan))
843 {
844 if (w <= vw)
845 {
846 scroll_h_vis_change = 1;
847 sd->hbar_visible = 0;
848 }
849 }
850 else
851 {
852 scroll_h_vis_change = 1;
853 sd->hbar_visible = 0;
854 }
855 }
856 else if (sd->hbar_flags == E_SCROLLFRAME_POLICY_OFF)
857 {
858 scroll_h_vis_change = 1;
859 sd->hbar_visible = 0;
860 }
861 }
862 else
863 {
864 if (sd->hbar_flags == E_SCROLLFRAME_POLICY_AUTO)
865 {
866 if ((sd->child_obj) || (sd->extern_pan))
867 {
868 if (w > vw)
869 {
870 scroll_h_vis_change = 1;
871 sd->hbar_visible = 1;
872 }
873 }
874 }
875 else if (sd->hbar_flags == E_SCROLLFRAME_POLICY_ON)
876 {
877 scroll_h_vis_change = 1;
878 sd->hbar_visible = 1;
879 }
880 }
881 if (scroll_h_vis_change)
882 {
883 if (sd->hbar_visible)
884 edje_object_signal_emit(sd->edje_obj, "e,action,show,hbar", "e");
885 else
886 edje_object_signal_emit(sd->edje_obj, "e,action,hide,hbar", "e");
887 edje_object_message_signal_process(sd->edje_obj);
888 _e_smart_scrollbar_size_adjust(sd);
889 }
890 return scroll_h_vis_change;
891 }
892
893 static void
_e_smart_scrollbar_bar_visibility_adjust(E_Smart_Data * sd)894 _e_smart_scrollbar_bar_visibility_adjust(E_Smart_Data *sd)
895 {
896 int changed = 0;
897
898 changed |= _e_smart_scrollbar_bar_h_visibility_adjust(sd);
899 changed |= _e_smart_scrollbar_bar_v_visibility_adjust(sd);
900 if (changed)
901 {
902 changed |= _e_smart_scrollbar_bar_h_visibility_adjust(sd);
903 changed |= _e_smart_scrollbar_bar_v_visibility_adjust(sd);
904 }
905 if (changed)
906 {
907 _e_smart_scrollbar_bar_h_visibility_adjust(sd);
908 _e_smart_scrollbar_bar_v_visibility_adjust(sd);
909 }
910 }
911
912 static void
_e_smart_scrollbar_size_adjust(E_Smart_Data * sd)913 _e_smart_scrollbar_size_adjust(E_Smart_Data *sd)
914 {
915 if ((sd->child_obj) || (sd->extern_pan))
916 {
917 Evas_Coord x = 0, y = 0, w = 0, h = 0, mx = 0, my = 0, vw = 0, vh = 0;
918 double vx = 0.0, vy = 0.0, size = 0.0;
919
920 edje_object_calc_force(sd->edje_obj);
921 edje_object_part_geometry_get(sd->edje_obj, "e.swallow.content",
922 NULL, NULL, &vw, &vh);
923 w = sd->child.w;
924 if (w < 1) w = 1;
925 size = (double)vw / (double)w;
926 if (size > 1.0)
927 {
928 size = 1.0;
929 edje_object_part_drag_value_set(sd->edje_obj, "e.dragable.hbar",
930 0.0, 0.0);
931 }
932 edje_object_part_drag_size_set(sd->edje_obj, "e.dragable.hbar",
933 size, 1.0);
934
935 h = sd->child.h;
936 if (h < 1) h = 1;
937 size = (double)vh / (double)h;
938 if (size > 1.0)
939 {
940 size = 1.0;
941 edje_object_part_drag_value_set(sd->edje_obj, "e.dragable.vbar",
942 0.0, 0.0);
943 }
944 edje_object_part_drag_size_set(sd->edje_obj, "e.dragable.vbar",
945 1.0, size);
946
947 edje_object_part_drag_value_get(sd->edje_obj, "e.dragable.hbar",
948 &vx, NULL);
949 edje_object_part_drag_value_get(sd->edje_obj, "e.dragable.vbar",
950 NULL, &vy);
951 if (sd->pan_obj)
952 {
953 sd->pan_func.max_get(sd->pan_obj, &mx, &my);
954 x = vx * mx;
955 y = vy * my;
956 }
957
958 edje_object_part_drag_step_set(sd->edje_obj, "e.dragable.hbar",
959 (double)sd->step.x / (double)w, 0.0);
960 edje_object_part_drag_step_set(sd->edje_obj, "e.dragable.vbar",
961 0.0, (double)sd->step.y / (double)h);
962 if (sd->page.x > 0)
963 edje_object_part_drag_page_set(sd->edje_obj, "e.dragable.hbar",
964 (double)sd->page.x / (double)w, 0.0);
965 else
966 edje_object_part_drag_page_set(sd->edje_obj, "e.dragable.hbar",
967 -((double)sd->page.x * ((double)vw / (double)w)) / 100.0, 0.0);
968 if (sd->page.y > 0)
969 edje_object_part_drag_page_set(sd->edje_obj, "e.dragable.vbar",
970 0.0, (double)sd->page.y / (double)h);
971 else
972 edje_object_part_drag_page_set(sd->edje_obj, "e.dragable.vbar",
973 0.0, -((double)sd->page.y * ((double)vh / (double)h)) / 100.0);
974
975 if (sd->pan_obj)
976 sd->pan_func.set(sd->pan_obj, x, y);
977 }
978 else
979 {
980 edje_object_part_drag_size_set(sd->edje_obj, "e.dragable.vbar",
981 1.0, 1.0);
982 edje_object_part_drag_size_set(sd->edje_obj, "e.dragable.hbar",
983 1.0, 1.0);
984 if (sd->pan_obj)
985 sd->pan_func.set(sd->pan_obj, 0, 0);
986 }
987 _e_smart_scrollbar_bar_visibility_adjust(sd);
988 }
989
990 static void
_e_smart_reconfigure(E_Smart_Data * sd)991 _e_smart_reconfigure(E_Smart_Data *sd)
992 {
993 evas_object_move(sd->edje_obj, sd->x, sd->y);
994 evas_object_resize(sd->edje_obj, sd->w, sd->h);
995 evas_object_move(sd->event_obj, sd->x, sd->y);
996 evas_object_resize(sd->event_obj, sd->w, sd->h);
997 _e_smart_scrollbar_size_adjust(sd);
998 }
999
1000 static void
_e_smart_add(Evas_Object * obj)1001 _e_smart_add(Evas_Object *obj)
1002 {
1003 E_Smart_Data *sd;
1004 Evas_Object *o;
1005
1006 sd = E_NEW(E_Smart_Data, 1);
1007 if (!sd) return;
1008 evas_object_smart_data_set(obj, sd);
1009
1010 sd->smart_obj = obj;
1011 sd->x = 0;
1012 sd->y = 0;
1013 sd->w = 0;
1014 sd->h = 0;
1015 sd->step.x = 32;
1016 sd->step.y = 32;
1017 sd->page.x = -50;
1018 sd->page.y = -50;
1019 sd->hbar_flags = E_SCROLLFRAME_POLICY_AUTO;
1020 sd->vbar_flags = E_SCROLLFRAME_POLICY_AUTO;
1021 sd->key_nav = EINA_TRUE;
1022
1023 evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN,
1024 _e_smart_event_key_down, sd);
1025 evas_object_propagate_events_set(obj, 0);
1026
1027 o = edje_object_add(evas_object_evas_get(obj));
1028 sd->edje_obj = o;
1029 e_theme_edje_object_set(o, "base/theme/widgets",
1030 "e/widgets/scrollframe");
1031 edje_object_signal_callback_add(o, "drag*", "e.dragable.vbar",
1032 _e_smart_edje_drag_v, sd);
1033 edje_object_signal_callback_add(o, "drag*", "e.dragable.hbar",
1034 _e_smart_edje_drag_h, sd);
1035 evas_object_smart_member_add(o, obj);
1036
1037 o = evas_object_rectangle_add(evas_object_evas_get(obj));
1038 evas_object_smart_member_add(o, obj);
1039 sd->event_obj = o;
1040 evas_object_color_set(o, 0, 0, 0, 0);
1041 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL,
1042 _e_smart_event_wheel, sd);
1043 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
1044 _e_smart_event_mouse_down, sd);
1045 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP,
1046 _e_smart_event_mouse_up, sd);
1047 evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE,
1048 _e_smart_event_mouse_move, sd);
1049 evas_object_smart_member_add(o, obj);
1050 evas_object_repeat_events_set(o, 1);
1051
1052 sd->pan_func.set = e_pan_set;
1053 sd->pan_func.get = e_pan_get;
1054 sd->pan_func.max_get = e_pan_max_get;
1055 sd->pan_func.child_size_get = e_pan_child_size_get;
1056
1057 _e_smart_scrollbar_reset(sd);
1058 edje_object_signal_emit(sd->edje_obj, "e,action,hide,hbar", "e");
1059 edje_object_signal_emit(sd->edje_obj, "e,action,hide,vbar", "e");
1060 }
1061
1062 static void
_e_smart_del(Evas_Object * obj)1063 _e_smart_del(Evas_Object *obj)
1064 {
1065 INTERNAL_ENTRY;
1066 e_scrollframe_child_set(obj, NULL);
1067 if (sd->pan_obj)
1068 {
1069 if (!sd->extern_pan) evas_object_del(sd->pan_obj);
1070 }
1071 evas_object_del(sd->edje_obj);
1072 evas_object_del(sd->event_obj);
1073 if (sd->down.momentum_animator)
1074 ecore_animator_del(sd->down.momentum_animator);
1075 E_FREE(sd);
1076 }
1077
1078 static void
_e_smart_move(Evas_Object * obj,Evas_Coord x,Evas_Coord y)1079 _e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
1080 {
1081 INTERNAL_ENTRY;
1082 sd->x = x;
1083 sd->y = y;
1084 _e_smart_reconfigure(sd);
1085 }
1086
1087 static void
_e_smart_resize(Evas_Object * obj,Evas_Coord w,Evas_Coord h)1088 _e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
1089 {
1090 INTERNAL_ENTRY;
1091 sd->w = w;
1092 sd->h = h;
1093 _e_smart_reconfigure(sd);
1094 }
1095
1096 static void
_e_smart_show(Evas_Object * obj)1097 _e_smart_show(Evas_Object *obj)
1098 {
1099 INTERNAL_ENTRY;
1100 evas_object_show(sd->edje_obj);
1101 evas_object_show(sd->event_obj);
1102 }
1103
1104 static void
_e_smart_hide(Evas_Object * obj)1105 _e_smart_hide(Evas_Object *obj)
1106 {
1107 INTERNAL_ENTRY;
1108 evas_object_hide(sd->edje_obj);
1109 evas_object_hide(sd->event_obj);
1110 }
1111
1112 static void
_e_smart_color_set(Evas_Object * obj,int r,int g,int b,int a)1113 _e_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
1114 {
1115 INTERNAL_ENTRY;
1116 evas_object_color_set(sd->edje_obj, r, g, b, a);
1117 }
1118
1119 static void
_e_smart_clip_set(Evas_Object * obj,Evas_Object * clip)1120 _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
1121 {
1122 INTERNAL_ENTRY;
1123 evas_object_clip_set(sd->edje_obj, clip);
1124 evas_object_clip_set(sd->event_obj, clip);
1125 }
1126
1127 static void
_e_smart_clip_unset(Evas_Object * obj)1128 _e_smart_clip_unset(Evas_Object *obj)
1129 {
1130 INTERNAL_ENTRY;
1131 evas_object_clip_unset(sd->edje_obj);
1132 evas_object_clip_unset(sd->event_obj);
1133 }
1134
1135 /* never need to touch this */
1136
1137 static void
_e_smart_init(void)1138 _e_smart_init(void)
1139 {
1140 if (_e_smart) return;
1141 {
1142 static const Evas_Smart_Class sc =
1143 {
1144 SMART_NAME,
1145 EVAS_SMART_CLASS_VERSION,
1146 _e_smart_add,
1147 _e_smart_del,
1148 _e_smart_move,
1149 _e_smart_resize,
1150 _e_smart_show,
1151 _e_smart_hide,
1152 _e_smart_color_set,
1153 _e_smart_clip_set,
1154 _e_smart_clip_unset,
1155 NULL, NULL, NULL, NULL, NULL, NULL, NULL
1156 };
1157 _e_smart = evas_smart_class_new(&sc);
1158 }
1159 }
1160
1161