c478f62c5fcda8d09d8f97c16e2abb2b24cc86ad
[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
184    struct
185    {
186       Evas_Coord x, y;
187       Evas_Coord sx, sy;
188       Evas_Coord dx, dy;
189       Evas_Coord pdx, pdy;
190       Evas_Coord bx, by;
191       Evas_Coord ax, ay;
192       Evas_Coord bx0, by0;
193       Evas_Coord b0x, b0y;
194       Evas_Coord b2x, b2y;
195
196       struct
197       {
198          Evas_Coord x, y;
199          double     timestamp, localtimestamp;
200       } history[60];
201
202       struct
203       {
204          double tadd, dxsum, dysum;
205          double est_timestamp_diff;
206       } hist;
207
208       double          anim_start;
209       double          anim_start2;
210       double          anim_start3;
211       double          onhold_vx, onhold_vy, onhold_tlast,
212                       onhold_vxe, onhold_vye;
213       double          extra_time;
214
215       Evas_Coord      hold_x, hold_y;
216       Evas_Coord      locked_x, locked_y;
217       int             hdir, vdir;
218
219       Ecore_Animator *hold_animator;
220       Ecore_Animator *onhold_animator;
221       Ecore_Animator *momentum_animator;
222       Ecore_Animator *bounce_x_animator;
223       Ecore_Animator *bounce_y_animator;
224
225       Eina_Bool       bounce_x_hold : 1;
226       Eina_Bool       bounce_y_hold : 1;
227       Eina_Bool       dragged_began : 1;
228       Eina_Bool       want_dragged : 1;
229       Eina_Bool       hold_parent : 1;
230       Eina_Bool       want_reset : 1;
231       Eina_Bool       cancelled : 1;
232       Eina_Bool       dragged : 1;
233       Eina_Bool       locked : 1;
234       Eina_Bool       scroll : 1;
235       Eina_Bool       dir_x : 1;
236       Eina_Bool       dir_y : 1;
237       Eina_Bool       hold : 1;
238       Eina_Bool       now : 1;
239    } down;
240
241    struct
242    {
243       Evas_Coord w, h;
244       Eina_Bool  resized : 1;
245    } content_info;
246
247    struct
248    {
249       Evas_Coord x, y;
250    } step, page;
251
252    struct
253    {
254       void (*drag_start)(Evas_Object *obj,
255                          void *data);
256       void (*drag_stop)(Evas_Object *obj,
257                         void *data);
258       void (*animate_start)(Evas_Object *obj,
259                             void *data);
260       void (*animate_stop)(Evas_Object *obj,
261                            void *data);
262       void (*scroll)(Evas_Object *obj,
263                      void *data);
264       void (*scroll_left)(Evas_Object *obj,
265                      void *data);
266       void (*scroll_right)(Evas_Object *obj,
267                      void *data);
268       void (*scroll_up)(Evas_Object *obj,
269                      void *data);
270       void (*scroll_down)(Evas_Object *obj,
271                      void *data);
272       void (*edge_left)(Evas_Object *obj,
273                         void *data);
274       void (*edge_right)(Evas_Object *obj,
275                          void *data);
276       void (*edge_top)(Evas_Object *obj,
277                        void *data);
278       void (*edge_bottom)(Evas_Object *obj,
279                           void *data);
280       void (*vbar_drag)(Evas_Object *obj,
281                           void *data);
282       void (*vbar_press)(Evas_Object *obj,
283                           void *data);
284       void (*vbar_unpress)(Evas_Object *obj,
285                           void *data);
286       void (*hbar_drag)(Evas_Object *obj,
287                           void *data);
288       void (*hbar_press)(Evas_Object *obj,
289                           void *data);
290       void (*hbar_unpress)(Evas_Object *obj,
291                           void *data);
292       void (*content_min_limit)(Evas_Object *obj,
293                                 Eina_Bool w,
294                                 Eina_Bool h);
295    } cb_func;
296
297    struct
298    {
299       struct
300       {
301          Evas_Coord      start, end;
302          double          t_start, t_end;
303          Ecore_Animator *animator;
304       } x, y;
305    } scrollto;
306
307    double     pagerel_h, pagerel_v;
308    Evas_Coord pagesize_h, pagesize_v;
309
310    Eina_Bool  momentum_animator_disabled : 1;
311    Eina_Bool  bounce_animator_disabled : 1;
312    Eina_Bool  one_direction_at_a_time : 1;
313    Eina_Bool  wheel_disabled : 1;
314    Eina_Bool  hbar_visible : 1;
315    Eina_Bool  vbar_visible : 1;
316    Eina_Bool  bounce_horiz : 1;
317    Eina_Bool  bounce_vert : 1;
318    Eina_Bool  is_mirrored : 1;
319    Eina_Bool  extern_pan : 1;
320    Eina_Bool  bouncemey : 1;
321    Eina_Bool  bouncemex : 1;
322    Eina_Bool  freeze : 1;
323    Eina_Bool  hold : 1;
324    Eina_Bool  min_w : 1;
325    Eina_Bool  min_h : 1;
326    Eina_Bool  go_left : 1;
327    Eina_Bool  go_right : 1;
328    Eina_Bool  go_up : 1;
329    Eina_Bool  go_down : 1;
330 };
331
332 typedef struct _Elm_Scrollable_Smart_Interface Elm_Scrollable_Smart_Interface;
333 struct _Elm_Scrollable_Smart_Interface
334 {
335    Evas_Smart_Interface base;
336
337    void       (*objects_set)(Evas_Object *obj,
338                              Evas_Object *edje_obj,
339                              Evas_Object *hit_rectangle);
340    void       (*content_set)(Evas_Object *obj,
341                              Evas_Object *content);
342
343    void       (*extern_pan_set)(Evas_Object *obj,
344                                 Evas_Object *pan);
345
346    void       (*drag_start_cb_set)(Evas_Object *obj,
347                                    void (*d_start_cb)(Evas_Object *obj,
348                                                          void *data));
349    void       (*drag_stop_cb_set)(Evas_Object *obj,
350                                   void (*d_stop_cb)(Evas_Object *obj,
351                                                        void *data));
352    void       (*animate_start_cb_set)(Evas_Object *obj,
353                                       void (*a_start_cb)(Evas_Object *obj,
354                                                                void *data));
355    void       (*animate_stop_cb_set)(Evas_Object *obj,
356                                      void (*a_stop_cb)(Evas_Object *obj,
357                                                              void *data));
358    void       (*scroll_cb_set)(Evas_Object *obj,
359                                void (*s_cb)(Evas_Object *obj,
360                                                  void *data));
361    void       (*scroll_left_cb_set)(Evas_Object *obj,
362                                void (*s_left_cb)(Evas_Object *obj,
363                                                  void *data));
364    void       (*scroll_right_cb_set)(Evas_Object *obj,
365                                void (*s_right_cb)(Evas_Object *obj,
366                                                  void *data));
367    void       (*scroll_up_cb_set)(Evas_Object *obj,
368                                void (*s_up_cb)(Evas_Object *obj,
369                                                  void *data));
370    void       (*scroll_down_cb_set)(Evas_Object *obj,
371                                void (*s_down_cb)(Evas_Object *obj,
372                                                  void *data));
373    void       (*edge_left_cb_set)(Evas_Object *obj,
374                                   void (*e_left_cb)(Evas_Object *obj,
375                                                        void *data));
376    void       (*edge_right_cb_set)(Evas_Object *obj,
377                                    void (*e_right_cb)(Evas_Object *obj,
378                                                          void *data));
379    void       (*edge_top_cb_set)(Evas_Object *obj,
380                                  void (*e_top_cb)(Evas_Object *obj,
381                                                      void *data));
382    void       (*edge_bottom_cb_set)(Evas_Object *obj,
383                                     void (*e_bottom_cb)(Evas_Object *obj,
384                                                            void *data));
385    void       (*vbar_drag_cb_set)(Evas_Object *obj,
386                                     void (*v_drag_cb)(Evas_Object *obj,
387                                                            void *data));
388    void       (*vbar_press_cb_set)(Evas_Object *obj,
389                                     void (*v_press_cb)(Evas_Object *obj,
390                                                            void *data));
391    void       (*vbar_unpress_cb_set)(Evas_Object *obj,
392                                     void (*v_unpress_cb)(Evas_Object *obj,
393                                                            void *data));
394    void       (*hbar_drag_cb_set)(Evas_Object *obj,
395                                     void (*h_drag_cb)(Evas_Object *obj,
396                                                            void *data));
397    void       (*hbar_press_cb_set)(Evas_Object *obj,
398                                     void (*h_press_cb)(Evas_Object *obj,
399                                                            void *data));
400    void       (*hbar_unpress_cb_set)(Evas_Object *obj,
401                                     void (*h_unpress_cb)(Evas_Object *obj,
402                                                            void *data));
403
404    void       (*content_min_limit_cb_set)(Evas_Object *obj,
405                                           void (*c_limit_cb)(Evas_Object *obj,
406                                                              Eina_Bool w,
407                                                              Eina_Bool h));
408
409    /* set the position of content object inside the scrolling region,
410     * immediately */
411    void       (*content_pos_set)(Evas_Object *obj,
412                                  Evas_Coord x,
413                                  Evas_Coord y,
414                                  Eina_Bool sig);
415    void       (*content_pos_get)(const Evas_Object *obj,
416                                  Evas_Coord *x,
417                                  Evas_Coord *y);
418
419    void       (*content_region_show)(Evas_Object *obj,
420                                      Evas_Coord x,
421                                      Evas_Coord y,
422                                      Evas_Coord w,
423                                      Evas_Coord h);
424    void       (*content_region_set)(Evas_Object *obj,
425                                     Evas_Coord x,
426                                     Evas_Coord y,
427                                     Evas_Coord w,
428                                     Evas_Coord h);
429
430    void       (*content_size_get)(const Evas_Object *obj,
431                                   Evas_Coord *w,
432                                   Evas_Coord *h);
433
434    /* get the size of the actual viewport area (swallowed into
435     * scroller Edje object) */
436    void       (*content_viewport_size_get)(const Evas_Object *obj,
437                                            Evas_Coord *w,
438                                            Evas_Coord *h);
439
440    /* this one issues the respective callback, only */
441    void       (*content_min_limit)(Evas_Object *obj,
442                                    Eina_Bool w,
443                                    Eina_Bool h);
444
445    void       (*step_size_set)(Evas_Object *obj,
446                                Evas_Coord x,
447                                Evas_Coord y);
448    void       (*step_size_get)(const Evas_Object *obj,
449                                Evas_Coord *x,
450                                Evas_Coord *y);
451    void       (*page_size_set)(Evas_Object *obj,
452                                Evas_Coord x,
453                                Evas_Coord y);
454    void       (*page_size_get)(const Evas_Object *obj,
455                                Evas_Coord *x,
456                                Evas_Coord *y);
457    void       (*policy_set)(Evas_Object *obj,
458                             Elm_Scroller_Policy hbar,
459                             Elm_Scroller_Policy vbar);
460    void       (*policy_get)(const Evas_Object *obj,
461                             Elm_Scroller_Policy *hbar,
462                             Elm_Scroller_Policy *vbar);
463
464    void       (*single_direction_set)(Evas_Object *obj,
465                                       Eina_Bool single_dir);
466    Eina_Bool  (*single_direction_get)(const Evas_Object *obj);
467
468    void       (*mirrored_set)(Evas_Object *obj,
469                               Eina_Bool mirrored);
470
471    void       (*hold_set)(Evas_Object *obj,
472                           Eina_Bool hold);
473    void       (*freeze_set)(Evas_Object *obj,
474                             Eina_Bool freeze);
475
476    void       (*bounce_allow_set)(Evas_Object *obj,
477                                   Eina_Bool horiz,
478                                   Eina_Bool vert);
479    void       (*bounce_allow_get)(const Evas_Object *obj,
480                                   Eina_Bool *horiz,
481                                   Eina_Bool *vert);
482
483    void       (*paging_set)(Evas_Object *obj,
484                             double pagerel_h,
485                             double pagerel_v,
486                             Evas_Coord pagesize_h,
487                             Evas_Coord pagesize_v);
488    void       (*paging_get)(const Evas_Object *obj,
489                             double *pagerel_h,
490                             double *pagerel_v,
491                             Evas_Coord *pagesize_h,
492                             Evas_Coord *pagesize_v);
493    void       (*current_page_get)(const Evas_Object *obj,
494                                   int *pagenumber_h,
495                                   int *pagenumber_v);
496    void       (*last_page_get)(const Evas_Object *obj,
497                                int *pagenumber_h,
498                                int *pagenumber_v);
499    void       (*page_show)(Evas_Object *obj,
500                            int pagenumber_h,
501                            int pagenumber_v);
502    void       (*page_bring_in)(Evas_Object *obj,
503                                int pagenumber_h,
504                                int pagenumber_v);
505
506    void       (*region_bring_in)(Evas_Object *obj,
507                                  Evas_Coord x,
508                                  Evas_Coord y,
509                                  Evas_Coord w,
510                                  Evas_Coord h);
511
512    void       (*gravity_set)(Evas_Object *obj,
513                              double x,
514                              double y);
515    void       (*gravity_get)(const Evas_Object *obj,
516                              double *x,
517                              double *y);
518
519    Eina_Bool  (*momentum_animator_disabled_get)(const Evas_Object *obj);
520    void       (*momentum_animator_disabled_set)(Evas_Object *obj,
521                                                 Eina_Bool disabled);
522
523    void       (*bounce_animator_disabled_set)(Evas_Object *obj,
524                                               Eina_Bool disabled);
525    Eina_Bool  (*bounce_animator_disabled_get)(const Evas_Object *obj);
526
527    Eina_Bool  (*wheel_disabled_get)(const Evas_Object *obj);
528    void       (*wheel_disabled_set)(Evas_Object *obj,
529                                     Eina_Bool disabled);
530 };
531
532 EAPI extern const char ELM_SCROLLABLE_IFACE_NAME[];
533 EAPI extern const Elm_Scrollable_Smart_Interface ELM_SCROLLABLE_IFACE;
534
535 EAPI const Elm_Pan_Smart_Class *elm_pan_smart_class_get(void);
536
537 #define ELM_SCROLLABLE_IFACE_GET(obj, iface)    \
538   const Elm_Scrollable_Smart_Interface * iface; \
539   iface = evas_object_smart_interface_get(obj, ELM_SCROLLABLE_IFACE_NAME);
540
541 #define ELM_SCROLLABLE_CHECK(obj, ...)                                       \
542   const Elm_Scrollable_Smart_Interface * s_iface =                           \
543     evas_object_smart_interface_get(obj, ELM_SCROLLABLE_IFACE_NAME);         \
544                                                                              \
545   if (!s_iface)                                                              \
546     {                                                                        \
547        ERR("Passing object (%p) of type '%s' in function %s, but it doesn't" \
548            " implement the Elementary scrollable interface.", obj,           \
549            elm_widget_type_get(obj), __func__);                              \
550        if (getenv("ELM_ERROR_ABORT")) abort();                               \
551        return __VA_ARGS__;                                                   \
552     }
553
554 /**
555  * @}
556  */
557
558 #endif