summaryrefslogtreecommitdiff
path: root/efl/elementary/slideshow.pyx
blob: e1f9597339145ac6b61074c18480581ded71c867 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
# Copyright (C) 2007-2015 various contributors (see AUTHORS)
#
# This file is part of Python-EFL.
#
# Python-EFL is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3 of the License, or (at your option) any later version.
#
# Python-EFL is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this Python-EFL.  If not, see <http://www.gnu.org/licenses/>.
#

"""

:mod:`slideshow` Module
#######################

.. image:: /images/slideshow-preview.png


Widget description
==================

This widget, as the name indicates, is a pre-made image
slideshow panel, with API functions acting on (child) image
items presentation. Between those actions, are:

- advance to next/previous image
- select the style of image transition animation
- set the exhibition time for each image
- start/stop the slideshow

The transition animations are defined in the widget's theme,
consequently new animations can be added without having to
update the widget's code.

Slideshow items
===============

For slideshow items, just like for :py:class:`~efl.elementary.genlist.Genlist`
ones, the user defines a **classes**, specifying functions that will be called
on the item's creation and deletion times.

The :py:class:`SlideshowItemClass` class contains the following
members:

- ``get`` - When an item is displayed, this function is
  called, and it's where one should create the item object, de
  facto. For example, the object can be a pure Evas image object
  or a :py:class:`~efl.elementary.photocam.Photocam` widget.

- ``delete`` - When an item is no more displayed, this function
  is called, where the user must delete any data associated to
  the item.

Slideshow caching
=================

The slideshow provides facilities to have items adjacent to the
one being displayed **already "realized"** (i.e. loaded) for
you, so that the system does not have to decode image data
anymore at the time it has to actually switch images on its
viewport. The user is able to set the numbers of items to be
cached **before** and **after** the current item, in the widget's
item list.


Emitted signals
===============

- ``changed`` - when the slideshow switches its view to a new item.
  event_info parameter in callback contains the current visible item
- ``transition,end`` - when a slide transition ends. event_info
  parameter in callback contains the current visible item
- ``focused`` - When the slideshow has received focus. (since 1.8)
- ``unfocused`` - When the slideshow has lost focus. (since 1.8)


Inheritance diagram
===================

.. inheritance-diagram:: efl.elementary.slideshow
    :parts: 2

"""

from cpython cimport PyUnicode_AsUTF8String, Py_INCREF
from libc.stdint cimport uintptr_t

from efl.eo cimport _object_mapping_register, object_from_instance, PY_REFCOUNT
from efl.utils.conversions cimport _ctouni
from efl.evas cimport Object as evasObject
from efl.utils.conversions cimport eina_list_strings_to_python_list

from layout_class cimport LayoutClass

import traceback
from object_item cimport _object_item_to_python, _object_item_list_to_python, \
    ObjectItem


cdef object _cb_object_item_conv(void *addr):
    return _object_item_to_python(<Elm_Object_Item *>addr)


cdef Evas_Object *_py_elm_slideshow_item_get(void *data, Evas_Object *obj) with gil:
    cdef:
        SlideshowItem item = <SlideshowItem>data
        SlideshowItemClass itc = item.item_class
        evasObject icon

    func = itc._get_func
    if func is None:
        return NULL

    try:
        o = object_from_instance(obj)
        icon = func(o, item.item_data)
    except Exception:
        traceback.print_exc()
        return NULL

    if icon is not None:
        return icon.obj
    else:
        return NULL


cdef void _py_elm_slideshow_item_del(void *data, Evas_Object *obj) with gil:
    cdef:
        SlideshowItem item = <SlideshowItem>data
        SlideshowItemClass itc = item.item_class

    func = itc._del_func
    if func is not None:
        try:
            o = object_from_instance(obj)
            func(o, item.item_data)
        except Exception:
            traceback.print_exc()

    # XXX: SlideShow item handling is weird
    # item._unset_obj()
    #Py_DECREF(item)

cdef int _py_elm_slideshow_compare_func(const void *data1, const void *data2) with gil:
    cdef:
        SlideshowItem item1 = <SlideshowItem>data1
        SlideshowItem item2 = <SlideshowItem>data2
        object func = item1.compare_func

    if func is None:
        return 0

    ret = func(item1, item2)
    if ret is not None:
        try:
            return ret
        except Exception:
            traceback.print_exc()
            return 0
    else:
        return 0

cdef class SlideshowItemClass (object):
    """

    Defines the behavior of each slideshow item.

    This class should be created and handled to the Slideshow itself.

    It may be subclassed, in this case the methods :py:func:`get()` and ``delete()``
    will be used.

    It may also be instantiated directly, given getters to override as
    constructor parameters.

    :param get_func: if provided will override the behavior
        defined by :py:func:`get()` in this class. Its purpose is
        to return the icon object to be used (swallowed) by a
        given part and row. This function should have the
        signature:
        ``func(obj, item_data) -> obj``

    :param del_func: if provided will override the behavior
        defined by ``delete()`` in this class. Its purpose is to be
        called when item is deleted, thus finalizing resources
        and similar. This function should have the signature:
        ``func(obj, item_data)``

    .. note:: In all these signatures, 'obj' means Slideshow and
        'item_data' is the value given to Slideshow item add/sorted_insert
        methods, it should represent your item model as you want.

    """
    cdef Elm_Slideshow_Item_Class cls
    cdef readonly object _get_func
    cdef readonly object _del_func

    def __cinit__(self):
        self.cls.func.get = _py_elm_slideshow_item_get
        self.cls.func.del_ = _py_elm_slideshow_item_del

    def __init__(self, get_func=None, del_func=None):
        if get_func and not callable(get_func):
            raise TypeError("get_func is not callable!")
        elif get_func:
            self._get_func = get_func
        else:
            self._get_func = self.get

        if del_func and not callable(del_func):
            raise TypeError("del_func is not callable!")
        elif del_func:
            self._del_func = del_func
        else:
            try:
                self._del_func = self.delete
            except AttributeError:
                pass

    def __repr__(self):
        return ("<%s(%#x, refcount=%d, Elm_Slideshow_Item_Class=%#x, "
                "get_func=%s, del_func=%s)>") % \
               (type(self).__name__,
                <uintptr_t><void *>self,
                PY_REFCOUNT(self),
                <uintptr_t>&self.cls,
                self._get_func,
                self._del_func)

    def get(self, evasObject obj, item_data):
        """To be called by Slideshow for each item to get its icon.

        :param obj: the Slideshow instance
        :param item_data: the value given to slideshow item_add func.

        :return: icon object to be used and swallowed.
        :rtype: evas Object or None
        """
        return None

cdef class SlideshowItem(ObjectItem):
    """

    An item for the :class:`Slideshow` widget.

    """

    cdef:
        readonly SlideshowItemClass item_class
        object item_data, compare_func

    cdef int _set_obj(self, Elm_Object_Item *item) except 0:
        assert self.item == NULL, "Object must be clean"
        self.item = item
        Py_INCREF(self)
        return 1

    cdef void _unset_obj(self):
        assert self.item != NULL, "Object must wrap something"
        self.item = NULL

    def __init__(self, SlideshowItemClass item_class not None,
                 item_data=None, *args, **kwargs):
        self.item_class = item_class
        self.item_data = item_data
        self.args = args
        self.kwargs = kwargs

    def __repr__(self):
        return ("<%s(%#x, refcount=%d, Elm_Object_Item=%#x, "
                "item_class=%s, item_data=%r)>") % \
               (type(self).__name__,
                <uintptr_t><void*>self,
                PY_REFCOUNT(self),
                <uintptr_t>self.item,
                type(self.item_class).__name__,
                self.item_data)

    def add_to(self, Slideshow slideshow not None):
        """Add (append) a new item in a given slideshow widget.

        Add a new item to ``obj's`` internal list of items, appending it.
        The item's class must contain the function really fetching the
        image object to show for this item, which could be an Evas image
        object or an Elementary photo, for example. The ``data``
        parameter is going to be passed to both class functions of the
        item.

        .. seealso::
            :py:class:`SlideshowItemClass`
            :py:meth:`sorted_insert`
            :py:attr:`~efl.elementary.object_item.ObjectItem.data`

        :param item_class: The item class for the item
        :type item_class: :py:class:`SlideshowItemClass`

        :return: A handle to the item added or ``None``, on errors
        :rtype: :py:class:`SlideshowItem`

        """
        cdef Elm_Object_Item *item

        item = elm_slideshow_item_add(slideshow.obj, &self.item_class.cls,
                                      <void*>self)

        if item == NULL:
            raise RuntimeError("The item could not be added to the widget.")

        self._set_obj(item)
        self._set_properties_from_keyword_args(self.kwargs)
        return self

    def sorted_insert(self, Slideshow slideshow not None, func not None):
        """Insert a new item into the given slideshow widget, using the ``func``
        function to sort items (by item handles).

        Add a new item to ``obj``'s internal list of items, in a position
        determined by the ``func`` comparing function. The item's class
        must contain the function really fetching the image object to
        show for this item, which could be an Evas image object or an
        Elementary photo, for example. The ``data`` parameter is going to
        be passed to both class functions of the item.

        The compare function compares data1 and data2. If data1 is 'less'
        than data2, -1 must be returned, if it is 'greater', 1 must be
        returned, and if they are equal, 0 must be returned.

        .. seealso::
            :py:class:`SlideshowItemClass`
            :py:meth:`add_to`

        :param itc: The item class for the item
        :param func: The comparing function to be used to sort slideshow
            items **by SlideshowItemClass item handles**
        :return: Returns The slideshow item handle, on success, or
            ``None``, on errors

        """
        cdef Elm_Object_Item *item
        cdef Eina_Compare_Cb compare

        if not callable(func):
            raise TypeError("func is not None or callable")

        self.compare_func = func
        compare = _py_elm_slideshow_compare_func

        item = elm_slideshow_item_sorted_insert(slideshow.obj,
                                    &self.item_class.cls, <void*>self, compare)

        if item == NULL:
            raise RuntimeError("The item could not be added to the widget.")

        self._set_obj(item)
        self._set_properties_from_keyword_args(self.kwargs)
        return self

    property object:
        """Get the real Evas object created to implement the view of a given
        slideshow item.

        This returns the actual Evas object used to implement the specified
        slideshow item's view. This may be ``None``, as it may not have been
        created or may have been deleted, at any time, by the slideshow.
        **Do not modify this object** (move, resize, show, hide, etc.), as
        the slideshow is controlling it. This function is for querying,
        emitting custom signals or hooking lower level callbacks for events
        on that object. Do not delete this object under any circumstances.

        .. seealso:: :py:attr:`~efl.elementary.object_item.ObjectItem.data`

        :type: :py:class:`Slideshow`

        """
        def __get__(self):
            return object_from_instance(elm_slideshow_item_object_get(self.item))

    def show(self):
        """Display a given slideshow widget's item, programmatically.

        The change between the current item and this item will use the
        transition the slideshow object is set to use.

        .. seealso:: :py:attr:`Slideshow.transition`

        """
        elm_slideshow_item_show(self.item)

cdef class Slideshow(LayoutClass):
    """

    This is the class that actually implements the widget.

    """

    def __init__(self, evasObject parent, *args, **kwargs):
        """Slideshow(...)

        :param parent: The parent object
        :type parent: :py:class:`efl.evas.Object`
        :param \**kwargs: All the remaining keyword arguments are interpreted
                          as properties of the instance

        """
        self._set_obj(elm_slideshow_add(parent.obj))
        self._set_properties_from_keyword_args(kwargs)

    def item_add(self, SlideshowItemClass item_class not None, item_data):
        """Add (append) a new item in a given slideshow widget.

        Add a new item to ``obj's`` internal list of items, appending it.
        The item's class must contain the function really fetching the
        image object to show for this item, which could be an Evas image
        object or an Elementary photo, for example. The ``data``
        parameter is going to be passed to both class functions of the
        item.

        .. seealso::
            :py:class:`SlideshowItemClass`
            :py:func:`item_sorted_insert()`
            :py:attr:`efl.elementary.object_item.ObjectItem.data`

        :param item_class: The item class for the item
        :type item_class: :py:class:`SlideshowItemClass`

        :param item_data: The data (model) associated with this item

        :return: A handle to the item added or ``None``, on errors
        :rtype: :py:class:`SlideshowItem`

        .. versionchanged:: 1.14
            use item_data param instead or args/kargs

        """
        return SlideshowItem(item_class, item_data).add_to(self)

    def item_sorted_insert(self, SlideshowItemClass item_class not None,
                            func not None, item_data):
        """Insert a new item into the given slideshow widget, using the ``func``
        function to sort items (by item handles).

        Add a new item to ``obj``'s internal list of items, in a position
        determined by the ``func`` comparing function. The item's class
        must contain the function really fetching the image object to
        show for this item, which could be an Evas image object or an
        Elementary photo, for example. The ``data`` parameter is going to
        be passed to both class functions of the item.

        The compare function compares data1 and data2. If data1 is 'less'
        than data2, -1 must be returned, if it is 'greater', 1 must be
        returned, and if they are equal, 0 must be returned.

        .. seealso::
            :py:class:`SlideshowItemClass`
            :py:func:`item_add()`

        :param itc: The item class for the item
        :param func: The comparing function to be used to sort slideshow
            items **by SlideshowItemClass item handles**

        :param item_data: The data (model) associated with this item

        :return: A handle to the item added or ``None``, on errors
        :rtype: :py:class:`SlideshowItem`

        .. versionchanged:: 1.14
            use item_data param instead or args/kargs


        """
        return SlideshowItem(item_class, item_data).sorted_insert(self, func)

    def next(self):
        """Slide to the **next** item, in a given slideshow widget

        The sliding animation the object is set to use will be the
        transition effect used, after this call is issued.

        .. note:: If the end of the slideshow's internal list of items is
            reached, it'll wrap around to the list's beginning, again.

        """
        elm_slideshow_next(self.obj)

    def previous(self):
        """Slide to the **previous** item, in a given slideshow widget

        The sliding animation the object is set to use will be the
        transition effect used, after this call is issued.

        .. note:: If the beginning of the slideshow's internal list of items
            is reached, it'll wrap around to the list's end, again.

        """
        elm_slideshow_previous(self.obj)

    property transitions:
        """Returns the list of sliding transition/effect names available,
        for a given slideshow widget.

        The transitions, which come from the objects theme, must be an EDC
        data item named ``"transitions"`` on the theme file, with (prefix)
        names of EDC programs actually implementing them.

        The available transitions for slideshows on the default theme are:
            - ``"fade"`` - the current item fades out, while the new one
              fades in to the slideshow's viewport.
            - ``"black_fade"`` - the current item fades to black, and just
              then, the new item will fade in.
            - ``"horizontal"`` - the current item slides horizontally, until
              it gets out of the slideshow's viewport, while the new item
              comes from the left to take its place.
            - ``"vertical"`` - the current item slides vertically, until it
              gets out of the slideshow's viewport, while the new item comes
              from the bottom to take its place.
            - ``"square"`` - the new item starts to appear from the middle of
              the current one, but with a tiny size, growing until its
              target (full) size and covering the old one.

        .. seealso:: :py:attr:`transition`

        :type: tuple of strings

        """
        def __get__(self):
            return tuple(eina_list_strings_to_python_list(elm_slideshow_transitions_get(self.obj)))

    property transition:
        """The slide transition/effect in use for a given slideshow widget

        If ``transition`` is implemented in ``obj's`` theme (i.e., is
        contained in the list returned by :py:attr:`transitions`), this new sliding
        effect will be used on the widget.

        :type: string

        """
        def __set__(self, transition):
            if isinstance(transition, unicode): transition = PyUnicode_AsUTF8String(transition)
            elm_slideshow_transition_set(self.obj,
                <const char *>transition if transition is not None else NULL)
        def __get__(self):
            return _ctouni(elm_slideshow_transition_get(self.obj))

    property timeout:
        """The interval between each image transition on a given
        slideshow widget, **and start the slideshow, itself**

        After setting this, the slideshow widget will start cycling its
        view, sequentially and automatically, with the images of the
        items it has. The time between each new image displayed is going
        to be ``timeout`` in **seconds**. If a different timeout was set
        previously and an slideshow was in progress, it will continue
        with the new time between transitions, after this call.

        .. note:: A value less than or equal to 0 on ``timeout`` will disable
            the widget's internal timer, thus halting any slideshow which
            could be happening on ``obj``.

        :type: float

        """
        def __set__(self, timeout):
            elm_slideshow_timeout_set(self.obj, timeout)
        def __get__(self):
            return elm_slideshow_timeout_get(self.obj)

    property loop:
        """If, after a slideshow is started, for a given slideshow
        widget, its items should be displayed cyclically or not.

        .. note:: The methods :py:func:`next()` and :py:func:`previous()`
            will **ignore** what is set by this property, i.e.,
            they'll **always** cycle through items. This affects only
            the "automatic" slideshow, as set by :py:attr:`timeout`.

        :type: bool

        """
        def __set__(self, loop):
            elm_slideshow_loop_set(self.obj, loop)
        def __get__(self):
            return bool(elm_slideshow_loop_get(self.obj))

    def clear(self):
        """Remove all items from a given slideshow widget.

        This removes (and deletes) all items in the object, leaving it empty.

        .. seealso::

            :py:meth:`~efl.elementary.object_item.ObjectItem.delete`, to remove
            just one item.

        """
        elm_slideshow_clear(self.obj)

    property items:
        """Get the internal list of items in a given slideshow widget.

        This list is **not** to be modified in any way and must not be freed.
        Use the list members with functions like
        :py:meth:`~efl.elementary.object_item.ObjectItem.delete`,
        :py:attr:`~efl.elementary.object_item.ObjectItem.data`.

        .. warning::

            This list is only valid until ``obj`` object's internal items list
            is changed. It should be fetched again with another call to this
            function when changes happen.

        :type: tuple of :py:class:`SlideshowItem`

        """
        def __get__(self):
            return tuple(_object_item_list_to_python(elm_slideshow_items_get(self.obj)))

    property current_item:
        """The currently displayed item, in a given slideshow widget

        :type: :py:class:`SlideshowItem`

        """
        def __get__(self):
            return _object_item_to_python(elm_slideshow_item_current_get(self.obj))

    def nth_item_get(self, nth):
        """Get the the item, in a given slideshow widget, placed at position
        ``nth`` in its internal items list.

        :param nth: The number of the item to grab a handle to (0 being the
            first)
        :type nth: int

        :return: The item stored in ``obj`` at position ``nth`` or ``None``,
            if there's no item with that index (and on errors)
        :rtype: :py:class:`SlideshowItem`

        """
        return _object_item_to_python(elm_slideshow_item_nth_get(self.obj, nth))

    property layout:
        """The current slide layout in use for a given slideshow widget

        If ``layout`` is implemented in ``obj's`` theme (i.e., is contained
        in the list returned by elm_slideshow_layouts_get()), this new
        images layout will be used on the widget.

        :type: string

        """
        def __set__(self, layout):
            if isinstance(layout, unicode): layout = PyUnicode_AsUTF8String(layout)
            elm_slideshow_layout_set(self.obj,
                <const char *>layout if layout is not None else NULL)
        def __get__(self):
            return _ctouni(elm_slideshow_layout_get(self.obj))

    property layouts:
        """Returns the list of **layout** names available, for a given
        slideshow widget.

        Slideshow layouts will change how the widget is to dispose each
        image item in its viewport, with regard to cropping, scaling,
        etc.

        The layouts, which come from the object theme, must be an EDC
        data item name ``"layouts"`` on the theme file, with (prefix)
        names of EDC programs actually implementing them.

        The available layouts for slideshows on the default theme are:
            - ``"fullscreen"`` - item images with original aspect, scaled to
              touch top and down slideshow borders or, if the image's height
              is not enough, left and right slideshow borders.
            - ``"not_fullscreen"`` - the same behavior as the ``"fullscreen"``
              one, but always leaving 10% of the slideshow's dimensions of
              distance between the item image's borders and the slideshow
              borders, for each axis.

        .. seealso:: :py:attr:`layout`

        :type: tuple of strings

        """
        def __get__(self):
            return tuple(eina_list_strings_to_python_list(elm_slideshow_layouts_get(self.obj)))

    property cache_before:
        """The number of items to cache, on a given slideshow widget,
        **before the current item**

        The default value for this property is ``2``.

        :type: int

        """
        def __set__(self, count):
            elm_slideshow_cache_before_set(self.obj, count)
        def __get__(self):
            return elm_slideshow_cache_before_get(self.obj)

    property cache_after:
        """The number of items to cache, on a given slideshow widget,
        **after the current item**

        The default value for this property is ``2``.

        :type: int

        """
        def __set__(self, count):
            elm_slideshow_cache_after_set(self.obj, count)
        def __get__(self):
            return elm_slideshow_cache_after_get(self.obj)

    property count:
        """Get the number of items stored in a given slideshow widget

        :type: int

        """
        def __get__(self):
            return elm_slideshow_count_get(self.obj)

    def callback_changed_add(self, func, *args, **kwargs):
        """When the slideshow switches its view to a new item. event_info
        parameter in callback contains the current visible item."""
        self._callback_add_full("changed", _cb_object_item_conv,
                                func, args, kwargs)

    def callback_changed_del(self, func):
        self._callback_del_full("changed", _cb_object_item_conv, func)

    def callback_transition_end_add(self, func, *args, **kwargs):
        """When a slide transition ends. event_info parameter in callback
        contains the current visible item."""
        self._callback_add_full("transition,end", _cb_object_item_conv,
                                func, args, kwargs)

    def callback_transition_end_del(self, func):
        self._callback_del_full("transition,end", _cb_object_item_conv, func)

    def callback_focused_add(self, func, *args, **kwargs):
        """When the slideshow has received focus.

        .. versionadded:: 1.8
        """
        self._callback_add("focused", func, args, kwargs)

    def callback_focused_del(self, func):
        self._callback_del("focused", func)

    def callback_unfocused_add(self, func, *args, **kwargs):
        """When the slideshow has lost focus.

        .. versionadded:: 1.8
        """
        self._callback_add("unfocused", func, args, kwargs)

    def callback_unfocused_del(self, func):
        self._callback_del("unfocused", func)

_object_mapping_register("Elm_Slideshow", Slideshow)