[Scroller] Fix the calculation double type number. Round off to the nearest whole...
[framework/uifw/elementary.git] / src / lib / elm_interface_scrollable.h
1 #ifndef ELM_INTEFARCE_SCROLLER_H
2 #define ELM_INTEFARCE_SCROLLER_H
3
4 /**
5  * @addtogroup Widget
6  * @{
7  *
8  * @section elm-scrollable-interface The Elementary Scrollable Interface
9  *
10  * This is a common interface for widgets having @b scrollable views.
11  * Widgets using/implementing this must use the
12  * @c EVAS_SMART_SUBCLASS_IFACE_NEW macro (instead of the
13  * @c EVAS_SMART_SUBCLASS_NEW one) when declaring its smart class,
14  * so an interface is also declared.
15  *
16  * The scrollable interface comes built with Elementary and is exposed
17  * as #ELM_SCROLLABLE_IFACE.
18  *
19  * The interface API is explained in details at
20  * #Elm_Scrollable_Smart_Interface.
21  *
22  * An Elementary scrollable interface will handle an internal @b
23  * panning object. It has the function of clipping and moving the
24  * actual scrollable content around, by the command of the scrollable
25  * interface calls. Though it's not the common case, one might
26  * want/have to change some aspects of the internal panning object
27  * behavior.  For that, we have it also exposed here --
28  * #Elm_Pan_Smart_Class. Use elm_pan_smart_class_get() to build your
29  * custom panning object, when creating a scrollable widget (again,
30  * only if you need a custom panning object) and set it with
31  * Elm_Scrollable_Smart_Interface::extern_pan_set.
32  */
33
34 /**
35  * @def ELM_PAN_CLASS
36  *
37  * Use this macro to cast whichever subclass of
38  * #Elm_Pan_Smart_Class into it, so to access its fields.
39  *
40  * @ingroup Widget
41  */
42  #define ELM_PAN_CLASS(x) ((Elm_Pan_Smart_Class *)x)
43
44 /**
45  * @def ELM_PAN_SMART_CLASS_VERSION
46  *
47  * Current version for Elementary pan @b base smart class, a value
48  * which goes to _Elm_Pan_Smart_Class::version.
49  *
50  * @ingroup Widget
51  */
52 #define ELM_PAN_SMART_CLASS_VERSION 1
53
54 /**
55  * @def ELM_PAN_SMART_CLASS_INIT
56  *
57  * Initializer for a whole #Elm_Pan_Smart_Class structure, with
58  * @c NULL values on its specific fields.
59  *
60  * @param smart_class_init initializer to use for the "base" field
61  * (#Evas_Smart_Class).
62  *
63  * @see EVAS_SMART_CLASS_INIT_NULL
64  * @see EVAS_SMART_CLASS_INIT_NAME_VERSION
65  * @see ELM_PAN_SMART_CLASS_INIT_NULL
66  * @see ELM_PAN_SMART_CLASS_INIT_NAME_VERSION
67  *
68  * @ingroup Widget
69  */
70 #define ELM_PAN_SMART_CLASS_INIT(smart_class_init)                        \
71   {smart_class_init, ELM_PAN_SMART_CLASS_VERSION, NULL, NULL, NULL, NULL, \
72    NULL, NULL, NULL}
73
74 /**
75  * @def ELM_PAN_SMART_CLASS_INIT_NULL
76  *
77  * Initializer to zero out a whole #Elm_Pan_Smart_Class structure.
78  *
79  * @see ELM_PAN_SMART_CLASS_INIT_NAME_VERSION
80  * @see ELM_PAN_SMART_CLASS_INIT
81  *
82  * @ingroup Widget
83  */
84 #define ELM_PAN_SMART_CLASS_INIT_NULL \
85   ELM_PAN_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NULL)
86
87 /**
88  * @def ELM_PAN_SMART_CLASS_INIT_NAME_VERSION
89  *
90  * Initializer to zero out a whole #Elm_Pan_Smart_Class structure and
91  * set its name and version.
92  *
93  * This is similar to #ELM_PAN_SMART_CLASS_INIT_NULL, but it will
94  * also set the version field of #Elm_Pan_Smart_Class (base field)
95  * to the latest #ELM_PAN_SMART_CLASS_VERSION and name it to the
96  * specific value.
97  *
98  * It will keep a reference to the name field as a <c>"const char *"</c>,
99  * i.e., the name must be available while the structure is
100  * used (hint: static or global variable!) and must not be modified.
101  *
102  * @see ELM_PAN_SMART_CLASS_INIT_NULL
103  * @see ELM_PAN_SMART_CLASS_INIT
104  *
105  * @ingroup Widget
106  */
107 #define ELM_PAN_SMART_CLASS_INIT_NAME_VERSION(name) \
108   ELM_PAN_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NAME_VERSION(name))
109
110 /**
111  * Elementary scroller panning base smart class. This inherits
112  * directly from the Evas smart clipped class (an object clipping
113  * children to its viewport/size). It is exposed here only to build
114  * widgets needing a custom panning behavior.
115  */
116 typedef struct _Elm_Pan_Smart_Class Elm_Pan_Smart_Class;
117 struct _Elm_Pan_Smart_Class
118 {
119    Evas_Smart_Class base; /* it's a clipped smart object */
120
121    int              version; /**< Version of this smart class definition */
122
123    void             (*pos_set)(Evas_Object *obj,
124                                Evas_Coord x,
125                                Evas_Coord y);
126    void             (*pos_get)(const Evas_Object *obj,
127                                Evas_Coord *x,
128                                Evas_Coord *y);
129    void             (*pos_max_get)(const Evas_Object *obj,
130                                    Evas_Coord *x,
131                                    Evas_Coord *y);
132    void             (*pos_min_get)(const Evas_Object *obj,
133                                    Evas_Coord *x,
134                                    Evas_Coord *y);
135    void             (*content_size_get)(const Evas_Object *obj,
136                                         Evas_Coord *x,
137                                         Evas_Coord *y);
138    void             (*gravity_set)(Evas_Object *obj,
139                                    double x,
140                                    double y);
141    void             (*gravity_get)(const Evas_Object *obj,
142                                    double *x,
143                                    double *y);
144 };
145
146 /**
147  * Elementary scroller panning base smart data.
148  */
149 typedef struct _Elm_Pan_Smart_Data Elm_Pan_Smart_Data;
150 struct _Elm_Pan_Smart_Data
151 {
152    Evas_Object_Smart_Clipped_Data base;
153
154    const Elm_Pan_Smart_Class     *api; /**< This is the pointer to the object's class, from where we can reach/call its class functions */
155
156    Evas_Object                   *self;
157    Evas_Object                   *content;
158    Evas_Coord                     x, y, w, h;
159    Evas_Coord                     content_w, content_h, px, py;
160    double                         gravity_x, gravity_y;
161    Evas_Coord                     prev_cw, prev_ch, delta_posx, delta_posy;
162 };
163
164 /**
165  * Elementary scrollable interface base data.
166  */
167 typedef struct _Elm_Scrollable_Smart_Interface_Data
168   Elm_Scrollable_Smart_Interface_Data;
169 struct _Elm_Scrollable_Smart_Interface_Data
170 {
171    Evas_Coord                    x, y, w, h;
172    Evas_Coord                    wx, wy, ww, wh; /**< Last "wanted" geometry */
173
174    Evas_Object                  *obj;
175    Evas_Object                  *content;
176    Evas_Object                  *pan_obj;
177    Evas_Object                  *edje_obj;
178    Evas_Object                  *event_rect;
179
180    Evas_Object                  *parent_widget;
181
182    Elm_Scroller_Policy           hbar_flags, vbar_flags;
183    Elm_Scroller_Single_Direction one_direction_at_a_time;
184
185    struct
186    {
187       Evas_Coord x, y;
188       Evas_Coord sx, sy;
189       Evas_Coord dx, dy;
190       Evas_Coord pdx, pdy;
191       Evas_Coord bx, by;
192       Evas_Coord ax, ay;
193       Evas_Coord bx0, by0;
194       Evas_Coord b0x, b0y;
195       Evas_Coord b2x, b2y;
196
197       struct
198       {
199          Evas_Coord x, y;
200          double     timestamp, localtimestamp;
201       } history[60];
202
203       struct
204       {
205          double tadd, dxsum, dysum;
206          double est_timestamp_diff;
207       } hist;
208
209       double          anim_start;
210       double          anim_start2;
211       double          anim_start3;
212       double          onhold_vx, onhold_vy, onhold_tlast,
213                       onhold_vxe, onhold_vye;
214       double          extra_time;
215
216       Evas_Coord      hold_x, hold_y;
217       Evas_Coord      locked_x, locked_y;
218       int             hdir, vdir;
219
220       Ecore_Animator *hold_animator;
221       Ecore_Animator *onhold_animator;
222       Ecore_Animator *momentum_animator;
223       Ecore_Animator *bounce_x_animator;
224       Ecore_Animator *bounce_y_animator;
225
226       Eina_Bool       bounce_x_hold : 1;
227       Eina_Bool       bounce_y_hold : 1;
228       Eina_Bool       dragged_began : 1;
229       Eina_Bool       want_dragged : 1;
230       Eina_Bool       hold_parent : 1;
231       Eina_Bool       want_reset : 1;
232       Eina_Bool       cancelled : 1;
233       Eina_Bool       dragged : 1;
234       Eina_Bool       locked : 1;
235       Eina_Bool       scroll : 1;
236       Eina_Bool       dir_x : 1;
237       Eina_Bool       dir_y : 1;
238       Eina_Bool       hold : 1;
239       Eina_Bool       now : 1;
240    } down;
241
242    struct
243    {
244       Evas_Coord w, h;
245       Eina_Bool  resized : 1;
246    } content_info;
247
248    struct
249    {
250       Evas_Coord x, y;
251    } step, page;
252
253    struct
254    {
255       void (*drag_start)(Evas_Object *obj,
256                          void *data);
257       void (*drag_stop)(Evas_Object *obj,
258                         void *data);
259       void (*animate_start)(Evas_Object *obj,
260                             void *data);
261       void (*animate_stop)(Evas_Object *obj,
262                            void *data);
263       void (*scroll)(Evas_Object *obj,
264                      void *data);
265       void (*scroll_left)(Evas_Object *obj,
266                      void *data);
267       void (*scroll_right)(Evas_Object *obj,
268                      void *data);
269       void (*scroll_up)(Evas_Object *obj,
270                      void *data);
271       void (*scroll_down)(Evas_Object *obj,
272                      void *data);
273       void (*edge_left)(Evas_Object *obj,
274                         void *data);
275       void (*edge_right)(Evas_Object *obj,
276                          void *data);
277       void (*edge_top)(Evas_Object *obj,
278                        void *data);
279       void (*edge_bottom)(Evas_Object *obj,
280                           void *data);
281       void (*vbar_drag)(Evas_Object *obj,
282                           void *data);
283       void (*vbar_press)(Evas_Object *obj,
284                           void *data);
285       void (*vbar_unpress)(Evas_Object *obj,
286                           void *data);
287       void (*hbar_drag)(Evas_Object *obj,
288                           void *data);
289       void (*hbar_press)(Evas_Object *obj,
290                           void *data);
291       void (*hbar_unpress)(Evas_Object *obj,
292                           void *data);
293       void (*content_min_limit)(Evas_Object *obj,
294                                 Eina_Bool w,
295                                 Eina_Bool h);
296    } cb_func;
297
298    struct
299    {
300       struct
301       {
302          Evas_Coord      start, end;
303          double          t_start, t_end;
304          Ecore_Animator *animator;
305       } x, y;
306    } scrollto;
307
308    double     pagerel_h, pagerel_v;
309    Evas_Coord pagesize_h, pagesize_v;
310    int        page_limit_h, page_limit_v;
311
312    Eina_Bool  momentum_animator_disabled : 1;
313    Eina_Bool  bounce_animator_disabled : 1;
314    Eina_Bool  wheel_disabled : 1;
315    Eina_Bool  hbar_visible : 1;
316    Eina_Bool  vbar_visible : 1;
317    Eina_Bool  bounce_horiz : 1;
318    Eina_Bool  bounce_vert : 1;
319    Eina_Bool  is_mirrored : 1;
320    Eina_Bool  extern_pan : 1;
321    Eina_Bool  bouncemey : 1;
322    Eina_Bool  bouncemex : 1;
323    Eina_Bool  freeze : 1;
324    Eina_Bool  hold : 1;
325    Eina_Bool  min_w : 1;
326    Eina_Bool  min_h : 1;
327    Eina_Bool  go_left : 1;
328    Eina_Bool  go_right : 1;
329    Eina_Bool  go_up : 1;
330    Eina_Bool  go_down : 1;
331 };
332
333 typedef struct _Elm_Scrollable_Smart_Interface Elm_Scrollable_Smart_Interface;
334 struct _Elm_Scrollable_Smart_Interface
335 {
336    Evas_Smart_Interface base;
337
338    void       (*objects_set)(Evas_Object *obj,
339                              Evas_Object *edje_obj,
340                              Evas_Object *hit_rectangle);
341    void       (*content_set)(Evas_Object *obj,
342                              Evas_Object *content);
343
344    void       (*extern_pan_set)(Evas_Object *obj,
345                                 Evas_Object *pan);
346
347    void       (*drag_start_cb_set)(Evas_Object *obj,
348                                    void (*d_start_cb)(Evas_Object *obj,
349                                                          void *data));
350    void       (*drag_stop_cb_set)(Evas_Object *obj,
351                                   void (*d_stop_cb)(Evas_Object *obj,
352                                                        void *data));
353    void       (*animate_start_cb_set)(Evas_Object *obj,
354                                       void (*a_start_cb)(Evas_Object *obj,
355                                                                void *data));
356    void       (*animate_stop_cb_set)(Evas_Object *obj,
357                                      void (*a_stop_cb)(Evas_Object *obj,
358                                                              void *data));
359    void       (*scroll_cb_set)(Evas_Object *obj,
360                                void (*s_cb)(Evas_Object *obj,
361                                                  void *data));
362    void       (*scroll_left_cb_set)(Evas_Object *obj,
363                                void (*s_left_cb)(Evas_Object *obj,
364                                                  void *data));
365    void       (*scroll_right_cb_set)(Evas_Object *obj,
366                                void (*s_right_cb)(Evas_Object *obj,
367                                                  void *data));
368    void       (*scroll_up_cb_set)(Evas_Object *obj,
369                                void (*s_up_cb)(Evas_Object *obj,
370                                                  void *data));
371    void       (*scroll_down_cb_set)(Evas_Object *obj,
372                                void (*s_down_cb)(Evas_Object *obj,
373                                                  void *data));
374    void       (*edge_left_cb_set)(Evas_Object *obj,
375                                   void (*e_left_cb)(Evas_Object *obj,
376                                                        void *data));
377    void       (*edge_right_cb_set)(Evas_Object *obj,
378                                    void (*e_right_cb)(Evas_Object *obj,
379                                                          void *data));
380    void       (*edge_top_cb_set)(Evas_Object *obj,
381                                  void (*e_top_cb)(Evas_Object *obj,
382                                                      void *data));
383    void       (*edge_bottom_cb_set)(Evas_Object *obj,
384                                     void (*e_bottom_cb)(Evas_Object *obj,
385                                                            void *data));
386    void       (*vbar_drag_cb_set)(Evas_Object *obj,
387                                     void (*v_drag_cb)(Evas_Object *obj,
388                                                            void *data));
389    void       (*vbar_press_cb_set)(Evas_Object *obj,
390                                     void (*v_press_cb)(Evas_Object *obj,
391                                                            void *data));
392    void       (*vbar_unpress_cb_set)(Evas_Object *obj,
393                                     void (*v_unpress_cb)(Evas_Object *obj,
394                                                            void *data));
395    void       (*hbar_drag_cb_set)(Evas_Object *obj,
396                                     void (*h_drag_cb)(Evas_Object *obj,
397                                                            void *data));
398    void       (*hbar_press_cb_set)(Evas_Object *obj,
399                                     void (*h_press_cb)(Evas_Object *obj,
400                                                            void *data));
401    void       (*hbar_unpress_cb_set)(Evas_Object *obj,
402                                     void (*h_unpress_cb)(Evas_Object *obj,
403                                                            void *data));
404
405    void       (*content_min_limit_cb_set)(Evas_Object *obj,
406                                           void (*c_limit_cb)(Evas_Object *obj,
407                                                              Eina_Bool w,
408                                                              Eina_Bool h));
409
410    /* set the position of content object inside the scrolling region,
411     * immediately */
412    void       (*content_pos_set)(Evas_Object *obj,
413                                  Evas_Coord x,
414                                  Evas_Coord y,
415                                  Eina_Bool sig);
416    void       (*content_pos_get)(const Evas_Object *obj,
417                                  Evas_Coord *x,
418                                  Evas_Coord *y);
419
420    void       (*content_region_show)(Evas_Object *obj,
421                                      Evas_Coord x,
422                                      Evas_Coord y,
423                                      Evas_Coord w,
424                                      Evas_Coord h);
425    void       (*content_region_set)(Evas_Object *obj,
426                                     Evas_Coord x,
427                                     Evas_Coord y,
428                                     Evas_Coord w,
429                                     Evas_Coord h);
430
431    void       (*content_size_get)(const Evas_Object *obj,
432                                   Evas_Coord *w,
433                                   Evas_Coord *h);
434
435    /* get the size of the actual viewport area (swallowed into
436     * scroller Edje object) */
437    void       (*content_viewport_size_get)(const Evas_Object *obj,
438                                            Evas_Coord *w,
439                                            Evas_Coord *h);
440
441    /* this one issues the respective callback, only */
442    void       (*content_min_limit)(Evas_Object *obj,
443                                    Eina_Bool w,
444                                    Eina_Bool h);
445
446    void       (*step_size_set)(Evas_Object *obj,
447                                Evas_Coord x,
448                                Evas_Coord y);
449    void       (*step_size_get)(const Evas_Object *obj,
450                                Evas_Coord *x,
451                                Evas_Coord *y);
452    void       (*page_size_set)(Evas_Object *obj,
453                                Evas_Coord x,
454                                Evas_Coord y);
455    void       (*page_size_get)(const Evas_Object *obj,
456                                Evas_Coord *x,
457                                Evas_Coord *y);
458    void       (*policy_set)(Evas_Object *obj,
459                             Elm_Scroller_Policy hbar,
460                             Elm_Scroller_Policy vbar);
461    void       (*policy_get)(const Evas_Object *obj,
462                             Elm_Scroller_Policy *hbar,
463                             Elm_Scroller_Policy *vbar);
464
465    void       (*single_direction_set)(Evas_Object *obj,
466                                       Elm_Scroller_Single_Direction single_dir);
467    Elm_Scroller_Single_Direction (*single_direction_get)(const Evas_Object *obj);
468
469    void       (*repeat_events_set)(Evas_Object *obj,
470                                       Eina_Bool repeat_events);
471    Eina_Bool  (*repeat_events_get)(const Evas_Object *obj);
472
473    void       (*mirrored_set)(Evas_Object *obj,
474                               Eina_Bool mirrored);
475
476    void       (*hold_set)(Evas_Object *obj,
477                           Eina_Bool hold);
478    void       (*freeze_set)(Evas_Object *obj,
479                             Eina_Bool freeze);
480
481    void       (*bounce_allow_set)(Evas_Object *obj,
482                                   Eina_Bool horiz,
483                                   Eina_Bool vert);
484    void       (*bounce_allow_get)(const Evas_Object *obj,
485                                   Eina_Bool *horiz,
486                                   Eina_Bool *vert);
487
488    void       (*paging_set)(Evas_Object *obj,
489                             double pagerel_h,
490                             double pagerel_v,
491                             Evas_Coord pagesize_h,
492                             Evas_Coord pagesize_v);
493    void       (*paging_get)(const Evas_Object *obj,
494                             double *pagerel_h,
495                             double *pagerel_v,
496                             Evas_Coord *pagesize_h,
497                             Evas_Coord *pagesize_v);
498    void       (*page_scroll_limit_set)(const Evas_Object *obj,
499                                   int page_limit_h,
500                                   int page_limit_v);
501    void       (*page_scroll_limit_get)(const Evas_Object *obj,
502                                   int *page_limit_h,
503                                   int *page_limit_v);
504    void       (*current_page_get)(const Evas_Object *obj,
505                                   int *pagenumber_h,
506                                   int *pagenumber_v);
507    void       (*last_page_get)(const Evas_Object *obj,
508                                int *pagenumber_h,
509                                int *pagenumber_v);
510    void       (*page_show)(Evas_Object *obj,
511                            int pagenumber_h,
512                            int pagenumber_v);
513    void       (*page_bring_in)(Evas_Object *obj,
514                                int pagenumber_h,
515                                int pagenumber_v);
516
517    void       (*region_bring_in)(Evas_Object *obj,
518                                  Evas_Coord x,
519                                  Evas_Coord y,
520                                  Evas_Coord w,
521                                  Evas_Coord h);
522
523    void       (*gravity_set)(Evas_Object *obj,
524                              double x,
525                              double y);
526    void       (*gravity_get)(const Evas_Object *obj,
527                              double *x,
528                              double *y);
529
530    Eina_Bool  (*momentum_animator_disabled_get)(const Evas_Object *obj);
531    void       (*momentum_animator_disabled_set)(Evas_Object *obj,
532                                                 Eina_Bool disabled);
533
534    void       (*bounce_animator_disabled_set)(Evas_Object *obj,
535                                               Eina_Bool disabled);
536    Eina_Bool  (*bounce_animator_disabled_get)(const Evas_Object *obj);
537
538    Eina_Bool  (*wheel_disabled_get)(const Evas_Object *obj);
539    void       (*wheel_disabled_set)(Evas_Object *obj,
540                                     Eina_Bool disabled);
541 };
542
543 EAPI extern const char ELM_SCROLLABLE_IFACE_NAME[];
544 EAPI extern const Elm_Scrollable_Smart_Interface ELM_SCROLLABLE_IFACE;
545
546 EAPI const Elm_Pan_Smart_Class *elm_pan_smart_class_get(void);
547
548 #define ELM_SCROLLABLE_IFACE_GET(obj, iface)    \
549   const Elm_Scrollable_Smart_Interface * iface; \
550   iface = evas_object_smart_interface_get(obj, ELM_SCROLLABLE_IFACE_NAME);
551
552 #define ELM_SCROLLABLE_CHECK(obj, ...)                                       \
553   const Elm_Scrollable_Smart_Interface * s_iface =                           \
554     evas_object_smart_interface_get(obj, ELM_SCROLLABLE_IFACE_NAME);         \
555                                                                              \
556   if (!s_iface)                                                              \
557     {                                                                        \
558        ERR("Passing object (%p) of type '%s' in function %s, but it doesn't" \
559            " implement the Elementary scrollable interface.", obj,           \
560            elm_widget_type_get(obj), __func__);                              \
561        if (getenv("ELM_ERROR_ABORT")) abort();                               \
562        return __VA_ARGS__;                                                   \
563     }
564
565 /**
566  * @}
567  */
568
569 #endif