merge with master
[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 (*edge_left)(Evas_Object *obj,
265                         void *data);
266       void (*edge_right)(Evas_Object *obj,
267                          void *data);
268       void (*edge_top)(Evas_Object *obj,
269                        void *data);
270       void (*edge_bottom)(Evas_Object *obj,
271                           void *data);
272       void (*vbar_drag)(Evas_Object *obj,
273                           void *data);
274       void (*vbar_press)(Evas_Object *obj,
275                           void *data);
276       void (*vbar_unpress)(Evas_Object *obj,
277                           void *data);
278       void (*hbar_drag)(Evas_Object *obj,
279                           void *data);
280       void (*hbar_press)(Evas_Object *obj,
281                           void *data);
282       void (*hbar_unpress)(Evas_Object *obj,
283                           void *data);
284       void (*content_min_limit)(Evas_Object *obj,
285                                 Eina_Bool w,
286                                 Eina_Bool h);
287    } cb_func;
288
289    struct
290    {
291       struct
292       {
293          Evas_Coord      start, end;
294          double          t_start, t_end;
295          Ecore_Animator *animator;
296       } x, y;
297    } scrollto;
298
299    double     pagerel_h, pagerel_v;
300    Evas_Coord pagesize_h, pagesize_v;
301
302    Eina_Bool  momentum_animator_disabled : 1;
303    Eina_Bool  bounce_animator_disabled : 1;
304    Eina_Bool  one_direction_at_a_time : 1;
305    Eina_Bool  wheel_disabled : 1;
306    Eina_Bool  hbar_visible : 1;
307    Eina_Bool  vbar_visible : 1;
308    Eina_Bool  bounce_horiz : 1;
309    Eina_Bool  bounce_vert : 1;
310    Eina_Bool  is_mirrored : 1;
311    Eina_Bool  extern_pan : 1;
312    Eina_Bool  bouncemey : 1;
313    Eina_Bool  bouncemex : 1;
314    Eina_Bool  freeze : 1;
315    Eina_Bool  hold : 1;
316    Eina_Bool  min_w : 1;
317    Eina_Bool  min_h : 1;
318    Eina_Bool  go_left : 1;
319    Eina_Bool  go_right : 1;
320    Eina_Bool  go_up : 1;
321    Eina_Bool  go_down : 1;
322 };
323
324 typedef struct _Elm_Scrollable_Smart_Interface Elm_Scrollable_Smart_Interface;
325 struct _Elm_Scrollable_Smart_Interface
326 {
327    Evas_Smart_Interface base;
328
329    void       (*objects_set)(Evas_Object *obj,
330                              Evas_Object *edje_obj,
331                              Evas_Object *hit_rectangle);
332    void       (*content_set)(Evas_Object *obj,
333                              Evas_Object *content);
334
335    void       (*extern_pan_set)(Evas_Object *obj,
336                                 Evas_Object *pan);
337
338    void       (*drag_start_cb_set)(Evas_Object *obj,
339                                    void (*d_start_cb)(Evas_Object *obj,
340                                                          void *data));
341    void       (*drag_stop_cb_set)(Evas_Object *obj,
342                                   void (*d_stop_cb)(Evas_Object *obj,
343                                                        void *data));
344    void       (*animate_start_cb_set)(Evas_Object *obj,
345                                       void (*a_start_cb)(Evas_Object *obj,
346                                                                void *data));
347    void       (*animate_stop_cb_set)(Evas_Object *obj,
348                                      void (*a_stop_cb)(Evas_Object *obj,
349                                                              void *data));
350    void       (*scroll_cb_set)(Evas_Object *obj,
351                                void (*s_cb)(Evas_Object *obj,
352                                                  void *data));
353    void       (*edge_left_cb_set)(Evas_Object *obj,
354                                   void (*e_left_cb)(Evas_Object *obj,
355                                                        void *data));
356    void       (*edge_right_cb_set)(Evas_Object *obj,
357                                    void (*e_right_cb)(Evas_Object *obj,
358                                                          void *data));
359    void       (*edge_top_cb_set)(Evas_Object *obj,
360                                  void (*e_top_cb)(Evas_Object *obj,
361                                                      void *data));
362    void       (*edge_bottom_cb_set)(Evas_Object *obj,
363                                     void (*e_bottom_cb)(Evas_Object *obj,
364                                                            void *data));
365    void       (*vbar_drag_cb_set)(Evas_Object *obj,
366                                     void (*v_drag_cb)(Evas_Object *obj,
367                                                            void *data));
368    void       (*vbar_press_cb_set)(Evas_Object *obj,
369                                     void (*v_press_cb)(Evas_Object *obj,
370                                                            void *data));
371    void       (*vbar_unpress_cb_set)(Evas_Object *obj,
372                                     void (*v_unpress_cb)(Evas_Object *obj,
373                                                            void *data));
374    void       (*hbar_drag_cb_set)(Evas_Object *obj,
375                                     void (*h_drag_cb)(Evas_Object *obj,
376                                                            void *data));
377    void       (*hbar_press_cb_set)(Evas_Object *obj,
378                                     void (*h_press_cb)(Evas_Object *obj,
379                                                            void *data));
380    void       (*hbar_unpress_cb_set)(Evas_Object *obj,
381                                     void (*h_unpress_cb)(Evas_Object *obj,
382                                                            void *data));
383
384    void       (*content_min_limit_cb_set)(Evas_Object *obj,
385                                           void (*c_limit_cb)(Evas_Object *obj,
386                                                              Eina_Bool w,
387                                                              Eina_Bool h));
388
389    /* set the position of content object inside the scrolling region,
390     * immediately */
391    void       (*content_pos_set)(Evas_Object *obj,
392                                  Evas_Coord x,
393                                  Evas_Coord y,
394                                  Eina_Bool sig);
395    void       (*content_pos_get)(const Evas_Object *obj,
396                                  Evas_Coord *x,
397                                  Evas_Coord *y);
398
399    void       (*content_region_show)(Evas_Object *obj,
400                                      Evas_Coord x,
401                                      Evas_Coord y,
402                                      Evas_Coord w,
403                                      Evas_Coord h);
404    void       (*content_region_set)(Evas_Object *obj,
405                                     Evas_Coord x,
406                                     Evas_Coord y,
407                                     Evas_Coord w,
408                                     Evas_Coord h);
409
410    void       (*content_size_get)(const Evas_Object *obj,
411                                   Evas_Coord *w,
412                                   Evas_Coord *h);
413
414    /* get the size of the actual viewport area (swallowed into
415     * scroller Edje object) */
416    void       (*content_viewport_size_get)(const Evas_Object *obj,
417                                            Evas_Coord *w,
418                                            Evas_Coord *h);
419
420    /* this one issues the respective callback, only */
421    void       (*content_min_limit)(Evas_Object *obj,
422                                    Eina_Bool w,
423                                    Eina_Bool h);
424
425    void       (*step_size_set)(Evas_Object *obj,
426                                Evas_Coord x,
427                                Evas_Coord y);
428    void       (*step_size_get)(const Evas_Object *obj,
429                                Evas_Coord *x,
430                                Evas_Coord *y);
431    void       (*page_size_set)(Evas_Object *obj,
432                                Evas_Coord x,
433                                Evas_Coord y);
434    void       (*page_size_get)(const Evas_Object *obj,
435                                Evas_Coord *x,
436                                Evas_Coord *y);
437    void       (*policy_set)(Evas_Object *obj,
438                             Elm_Scroller_Policy hbar,
439                             Elm_Scroller_Policy vbar);
440    void       (*policy_get)(const Evas_Object *obj,
441                             Elm_Scroller_Policy *hbar,
442                             Elm_Scroller_Policy *vbar);
443
444    void       (*single_direction_set)(Evas_Object *obj,
445                                       Eina_Bool single_dir);
446    Eina_Bool  (*single_direction_get)(const Evas_Object *obj);
447
448    void       (*mirrored_set)(Evas_Object *obj,
449                               Eina_Bool mirrored);
450
451    void       (*hold_set)(Evas_Object *obj,
452                           Eina_Bool hold);
453    void       (*freeze_set)(Evas_Object *obj,
454                             Eina_Bool freeze);
455
456    void       (*bounce_allow_set)(Evas_Object *obj,
457                                   Eina_Bool horiz,
458                                   Eina_Bool vert);
459    void       (*bounce_allow_get)(const Evas_Object *obj,
460                                   Eina_Bool *horiz,
461                                   Eina_Bool *vert);
462
463    void       (*paging_set)(Evas_Object *obj,
464                             double pagerel_h,
465                             double pagerel_v,
466                             Evas_Coord pagesize_h,
467                             Evas_Coord pagesize_v);
468    void       (*paging_get)(const Evas_Object *obj,
469                             double *pagerel_h,
470                             double *pagerel_v,
471                             Evas_Coord *pagesize_h,
472                             Evas_Coord *pagesize_v);
473    void       (*current_page_get)(const Evas_Object *obj,
474                                   int *pagenumber_h,
475                                   int *pagenumber_v);
476    void       (*last_page_get)(const Evas_Object *obj,
477                                int *pagenumber_h,
478                                int *pagenumber_v);
479    void       (*page_show)(Evas_Object *obj,
480                            int pagenumber_h,
481                            int pagenumber_v);
482    void       (*page_bring_in)(Evas_Object *obj,
483                                int pagenumber_h,
484                                int pagenumber_v);
485
486    void       (*region_bring_in)(Evas_Object *obj,
487                                  Evas_Coord x,
488                                  Evas_Coord y,
489                                  Evas_Coord w,
490                                  Evas_Coord h);
491
492    void       (*gravity_set)(Evas_Object *obj,
493                              double x,
494                              double y);
495    void       (*gravity_get)(const Evas_Object *obj,
496                              double *x,
497                              double *y);
498
499    Eina_Bool  (*momentum_animator_disabled_get)(const Evas_Object *obj);
500    void       (*momentum_animator_disabled_set)(Evas_Object *obj,
501                                                 Eina_Bool disabled);
502
503    void       (*bounce_animator_disabled_set)(Evas_Object *obj,
504                                               Eina_Bool disabled);
505    Eina_Bool  (*bounce_animator_disabled_get)(const Evas_Object *obj);
506
507    Eina_Bool  (*wheel_disabled_get)(const Evas_Object *obj);
508    void       (*wheel_disabled_set)(Evas_Object *obj,
509                                     Eina_Bool disabled);
510 };
511
512 EAPI extern const char ELM_SCROLLABLE_IFACE_NAME[];
513 EAPI extern const Elm_Scrollable_Smart_Interface ELM_SCROLLABLE_IFACE;
514
515 EAPI const Elm_Pan_Smart_Class *elm_pan_smart_class_get(void);
516
517 #define ELM_SCROLLABLE_IFACE_GET(obj, iface)    \
518   const Elm_Scrollable_Smart_Interface * iface; \
519   iface = evas_object_smart_interface_get(obj, ELM_SCROLLABLE_IFACE_NAME);
520
521 #define ELM_SCROLLABLE_CHECK(obj, ...)                                       \
522   const Elm_Scrollable_Smart_Interface * s_iface =                           \
523     evas_object_smart_interface_get(obj, ELM_SCROLLABLE_IFACE_NAME);         \
524                                                                              \
525   if (!s_iface)                                                              \
526     {                                                                        \
527        ERR("Passing object (%p) of type '%s' in function %s, but it doesn't" \
528            " implement the Elementary scrollable interface.", obj,           \
529            elm_widget_type_get(obj), __func__);                              \
530        if (getenv("ELM_ERROR_ABORT")) abort();                               \
531        return __VA_ARGS__;                                                   \
532     }
533
534 /**
535  * @}
536  */
537
538 #endif