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