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