summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Huuhko <kai.huuhko@gmail.com>2015-03-10 22:53:16 +0200
committerKai Huuhko <kai.huuhko@gmail.com>2015-03-10 22:53:16 +0200
commit4ab927809e08665b27ccb999d38d9ea03fae6906 (patch)
tree18f5d3d4d86bed405f54d210872674f91da91561
parenta11fadc82df6155c3cefde17effffe683ac72c59 (diff)
Move smart callback handling from elm Object to evas SO and inherit
-rw-r--r--efl/elementary/object.pxd11
-rw-r--r--efl/elementary/object.pyx167
-rw-r--r--efl/evas/efl.evas_object_smart.pxi283
-rw-r--r--include/efl.evas.pxd12
4 files changed, 187 insertions, 286 deletions
diff --git a/efl/elementary/object.pxd b/efl/elementary/object.pxd
index d503243..3804eb9 100644
--- a/efl/elementary/object.pxd
+++ b/efl/elementary/object.pxd
@@ -16,7 +16,8 @@
16# along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>. 16# along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>.
17 17
18from efl.evas cimport Eina_Bool, Eina_List, Evas_Object, Evas_Smart_Cb, \ 18from efl.evas cimport Eina_Bool, Eina_List, Evas_Object, Evas_Smart_Cb, \
19 Evas_Coord, Evas_Callback_Type, Object as evasObject, Canvas as evasCanvas 19 Evas_Coord, Evas_Callback_Type, Object as evasObject, SmartObject, \
20 Canvas as evasCanvas
20 21
21 22
22cdef extern from "Edje.h": 23cdef extern from "Edje.h":
@@ -79,7 +80,7 @@ cdef extern from "Elementary.h":
79 ctypedef enum Elm_Xdnd_Action: 80 ctypedef enum Elm_Xdnd_Action:
80 pass 81 pass
81 82
82 83
83 ctypedef struct Elm_Theme 84 ctypedef struct Elm_Theme
84 85
85 ctypedef struct Elm_Object_Item 86 ctypedef struct Elm_Object_Item
@@ -221,12 +222,8 @@ cdef extern from "Elementary.h":
221 #TODO: void elm_access_object_unregister(Evas_Object *obj) 222 #TODO: void elm_access_object_unregister(Evas_Object *obj)
222 223
223 224
224cdef class Canvas(evasCanvas): 225cdef class Object(SmartObject):
225 pass
226
227cdef class Object(evasObject):
228 cdef: 226 cdef:
229 dict _elmcallbacks
230 list _elm_event_cbs, _elm_signal_cbs 227 list _elm_event_cbs, _elm_signal_cbs
231 object cnp_drop_cb, cnp_drop_data 228 object cnp_drop_cb, cnp_drop_data
232 object cnp_selection_loss_cb, cnp_selection_loss_data 229 object cnp_selection_loss_cb, cnp_selection_loss_data
diff --git a/efl/elementary/object.pyx b/efl/elementary/object.pyx
index 464b390..80d3103 100644
--- a/efl/elementary/object.pyx
+++ b/efl/elementary/object.pyx
@@ -280,7 +280,7 @@ from libc.stdint cimport uintptr_t
280from efl.eo cimport _object_mapping_register 280from efl.eo cimport _object_mapping_register
281from efl.utils.conversions cimport _ctouni, eina_list_objects_to_python_list 281from efl.utils.conversions cimport _ctouni, eina_list_objects_to_python_list
282from efl.utils.deprecated cimport DEPRECATED 282from efl.utils.deprecated cimport DEPRECATED
283from efl.evas cimport Object as evasObject, \ 283from efl.evas cimport Object as evasObject, SmartObject, \
284 EventKeyDown, EventKeyUp, EventMouseWheel, \ 284 EventKeyDown, EventKeyUp, EventMouseWheel, \
285 evas_object_smart_callback_add, evas_object_smart_callback_del, \ 285 evas_object_smart_callback_add, evas_object_smart_callback_del, \
286 Evas_Callback_Type, EVAS_CALLBACK_KEY_DOWN, EVAS_CALLBACK_KEY_UP, \ 286 Evas_Callback_Type, EVAS_CALLBACK_KEY_DOWN, EVAS_CALLBACK_KEY_UP, \
@@ -296,27 +296,6 @@ log = logging.getLogger("elementary")
296import traceback 296import traceback
297 297
298 298
299cdef void _object_callback(void *data,
300 Evas_Object *o, void *event_info) with gil:
301 cdef:
302 Object obj
303 object event, ei, event_conv, func, args, kargs
304 tuple lst
305
306 obj = object_from_instance(o)
307 event = <object>data
308 # XXX: This is expensive code
309 lst = tuple(obj._elmcallbacks[event])
310 for event_conv, func, args, kargs in lst:
311 try:
312 if event_conv is None:
313 func(obj, *args, **kargs)
314 else:
315 ei = event_conv(<uintptr_t>event_info)
316 func(obj, ei, *args, **kargs)
317 except Exception:
318 traceback.print_exc()
319
320cdef bint _event_dispatcher(Object obj, Object src, Evas_Callback_Type t, 299cdef bint _event_dispatcher(Object obj, Object src, Evas_Callback_Type t,
321 event_info): 300 event_info):
322 cdef bint ret 301 cdef bint ret
@@ -371,19 +350,7 @@ cdef void signal_callback(void *data, Evas_Object *obj,
371 traceback.print_exc() 350 traceback.print_exc()
372 351
373 352
374# TODO: Is this handled in Eo now? 353cdef class Object(SmartObject):
375cdef void _event_data_del_cb(void *data, Evas_Object *o,
376 void *event_info) with gil:
377 pass
378# Py_DECREF(<object>data)
379
380
381# TODO: why the hell we redefine Canvas here??
382cdef class Canvas(evasCanvas):
383 def __init__(self):
384 pass
385
386cdef class Object(evasObject):
387 """ 354 """
388 355
389 An abstract class to manage object and callback handling. 356 An abstract class to manage object and callback handling.
@@ -1698,136 +1665,6 @@ cdef class Object(evasObject):
1698 def translatable_text_get(self): 1665 def translatable_text_get(self):
1699 return _ctouni(elm_object_translatable_text_get(self.obj)) 1666 return _ctouni(elm_object_translatable_text_get(self.obj))
1700 1667
1701 #
1702 # Callbacks
1703 # =========
1704 #
1705 # TODO: Should these be internal only? (cdef)
1706 # Or remove the individual widget callback_*_add/del methods and
1707 # use just these.
1708 #
1709
1710 def _callback_add_full(self, event, event_conv, func, *args, **kargs):
1711 """Add a callback for the smart event specified by event.
1712
1713 :param event: event name
1714 :type event: string
1715 :param event_conv: Conversion function to get the
1716 pointer (as a long) to the object to be given to the
1717 function as the second parameter. If None, then no
1718 parameter will be given to the callback.
1719 :type event_conv: function
1720 :param func: what to callback. Should have the signature::
1721
1722 function(object, event_info, *args, **kargs)
1723 function(object, *args, **kargs) (if no event_conv is provided)
1724
1725 :type func: function
1726
1727 :raise TypeError: if **func** is not callable.
1728 :raise TypeError: if **event_conv** is not callable or None.
1729
1730 """
1731 if not callable(func):
1732 raise TypeError("func must be callable")
1733 if event_conv is not None and not callable(event_conv):
1734 raise TypeError("event_conv must be None or callable")
1735
1736 if self._elmcallbacks is None:
1737 self._elmcallbacks = {}
1738
1739 e = intern(event)
1740 lst = self._elmcallbacks.setdefault(e, [])
1741 if isinstance(event, unicode): event = PyUnicode_AsUTF8String(event)
1742 if not lst:
1743 evas_object_smart_callback_add(self.obj,
1744 <const char *>event if event is not None else NULL,
1745 _object_callback, <void *>e)
1746 lst.append((event_conv, func, args, kargs))
1747
1748 def _callback_del_full(self, event, event_conv, func):
1749 """Remove a smart callback.
1750
1751 Removes a callback that was added by :py:func:`_callback_add_full()`.
1752
1753 :param event: event name
1754 :type event: string
1755 :param event_conv: same as registered with :py:func:`_callback_add_full()`
1756 :type event_conv: function
1757 :param func: what to callback, should have be previously registered.
1758 :type func: function
1759
1760 :precond: **event**, **event_conv** and **func** must be used as
1761 parameter for :py:func:`_callback_add_full()`.
1762
1763 :raise ValueError: if there was no **func** connected with this event.
1764
1765 """
1766 try:
1767 lst = self._elmcallbacks[event]
1768 except KeyError as e:
1769 raise ValueError("Unknown event %r" % event)
1770
1771 i = -1
1772 ec = None
1773 f = None
1774 for i, (ec, f, a, k) in enumerate(lst):
1775 if event_conv == ec and func == f:
1776 break
1777
1778 if f != func or ec != event_conv:
1779 raise ValueError("Callback %s was not registered with event %r" %
1780 (func, event))
1781
1782 lst.pop(i)
1783 if lst:
1784 return
1785 self._elmcallbacks.pop(event)
1786 if isinstance(event, unicode): event = PyUnicode_AsUTF8String(event)
1787 evas_object_smart_callback_del(self.obj,
1788 <const char *>event if event is not None else NULL,
1789 _object_callback)
1790
1791 def _callback_add(self, event, func, *args, **kargs):
1792 """Add a callback for the smart event specified by event.
1793
1794 :param event: event name
1795 :type event: string
1796 :param func: what to callback. Should have the signature:
1797 *function(object, *args, **kargs)*
1798 :type func: function
1799
1800 :raise TypeError: if **func** is not callable.
1801
1802 """
1803 return self._callback_add_full(event, None, func, *args, **kargs)
1804
1805 def _callback_del(self, event, func):
1806 """Remove a smart callback.
1807
1808 Removes a callback that was added by :py:func:`_callback_add()`.
1809
1810 :param event: event name
1811 :type event: string
1812 :param func: what to callback, should have be previously registered.
1813 :type func: function
1814
1815 :precond: **event** and **func** must be used as parameter for
1816 :py:func:`_callback_add()`.
1817
1818 :raise ValueError: if there was no **func** connected with this event.
1819
1820 """
1821 return self._callback_del_full(event, None, func)
1822
1823 # FIXME: Remove this?
1824 def _get_obj_addr(self):
1825 """Return the address of the internal save Evas_Object
1826
1827 :return: Address of saved Evas_Object
1828
1829 """
1830 return <uintptr_t>self.obj
1831 1668
1832 # 1669 #
1833 # Copy and Paste 1670 # Copy and Paste
diff --git a/efl/evas/efl.evas_object_smart.pxi b/efl/evas/efl.evas_object_smart.pxi
index 988dd09..b54137c 100644
--- a/efl/evas/efl.evas_object_smart.pxi
+++ b/efl/evas/efl.evas_object_smart.pxi
@@ -322,31 +322,27 @@ cdef void _smart_object_member_del(Evas_Object *o, Evas_Object *clip) with gil:
322cdef void _smart_callback(void *data, Evas_Object *o, void *event_info) with gil: 322cdef void _smart_callback(void *data, Evas_Object *o, void *event_info) with gil:
323 323
324 cdef: 324 cdef:
325 void *tmp 325 void *tmp = NULL
326 Smart cls 326 SmartObject obj
327 Eo obj
328 object event, ei 327 object event, ei
329 328
330 tmp = evas_smart_data_get(evas_object_smart_smart_get(o))
331 if tmp == NULL:
332 EINA_LOG_DOM_ERR(PY_EFL_EVAS_LOG_DOMAIN, "cls is NULL!", NULL)
333 return
334 cls = <Smart>tmp
335
336 eo_do_ret(o, tmp, eo_key_data_get("python-eo")) 329 eo_do_ret(o, tmp, eo_key_data_get("python-eo"))
337 if tmp == NULL: 330 if tmp == NULL:
338 EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL) 331 EINA_LOG_DOM_ERR(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL)
339 obj = None 332 return
340 else: 333 else:
341 obj = <Eo>tmp 334 obj = <SmartObject>tmp
342 335
343 event = <object>data 336 event = <object>data
344 ei = <object>event_info
345 lst = tuple(obj._smart_callbacks[event]) 337 lst = tuple(obj._smart_callbacks[event])
346 338
347 for func, args, kargs in lst: 339 for event_conv, func, args, kargs in lst:
348 try: 340 try:
349 func(obj, ei, *args, **kargs) 341 if event_conv is None:
342 func(obj, *args, **kargs)
343 else:
344 ei = event_conv(<uintptr_t>event_info)
345 func(obj, ei, *args, **kargs)
350 except Exception: 346 except Exception:
351 traceback.print_exc() 347 traceback.print_exc()
352 348
@@ -619,13 +615,6 @@ cdef class SmartObject(Object):
619 def __iter__(self): 615 def __iter__(self):
620 return EoIterator.create(evas_object_smart_iterator_new(self.obj)) 616 return EoIterator.create(evas_object_smart_iterator_new(self.obj))
621 617
622 # property parent:
623 # def __get__(self):
624 # return object_from_instance(evas_object_parent_get(self.obj))
625
626 # def parent_get(self):
627 # return object_from_instance(evas_object_parent_get(self.obj))
628
629 def member_add(self, Object child): 618 def member_add(self, Object child):
630 """Set an evas object as a member of this object. 619 """Set an evas object as a member of this object.
631 620
@@ -677,87 +666,6 @@ cdef class SmartObject(Object):
677 def smart_get(self): 666 def smart_get(self):
678 return <Smart>evas_smart_data_get(evas_object_smart_smart_get(self.obj)) 667 return <Smart>evas_smart_data_get(evas_object_smart_smart_get(self.obj))
679 668
680 def callback_add(self, name, func, *args, **kargs):
681 """Add a callback for the smart event specified by event.
682
683 :param name: Event name
684 :param func:
685 What to callback.
686 Should have the signature::
687
688 function(object, event_info, *args, **kargs)
689
690 :raise TypeError: if **func** is not callable.
691
692 .. warning::
693 **event_info** will always be a python object, if the
694 signal is provided by a C-only class, it will crash.
695
696 """
697 if not callable(func):
698 raise TypeError("func must be callable")
699
700 if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
701
702 lst = self._smart_callbacks.setdefault(name, [])
703 if not lst:
704 evas_object_smart_callback_add(self.obj, name, _smart_callback,
705 <void *>name)
706 lst.append((func, args, kargs))
707
708 def callback_del(self, name, func):
709 """Remove a smart callback.
710
711 Removes a callback that was added by :py:func:`callback_add()`.
712
713 :param name: event name
714 :param func: what to callback, should have be previously registered.
715 :precond: **event** and **func** must be used as parameter for
716 :py:func:`callback_add`.
717
718 :raise ValueError: if there was no **func** connected with this event.
719 """
720 if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
721
722 try:
723 lst = self._smart_callbacks[name]
724 except KeyError:
725 raise ValueError("Unknown event %r" % name)
726
727 cdef:
728 int i = -1
729 object f = None
730
731 for i, (f, a, k) in enumerate(lst):
732 if func == f:
733 break
734
735 if f != func:
736 raise ValueError("Callback %s was not registered with event %r" %
737 (func, name))
738 lst.pop(i)
739 if lst:
740 return
741 self._smart_callbacks.pop(name)
742 evas_object_smart_callback_del(self.obj, name, _smart_callback)
743
744 def callback_call(self, name, event_info=None):
745 """Call any smart callbacks for event.
746
747 :param name: the event name
748 :param event_info: an event specific info to pass to the callback.
749
750 This should be called internally in the smart object when some
751 specific event has occurred. The documentation for the smart object
752 should include a list of possible events and what type of
753 **event_info** to expect.
754
755 .. attention::
756 **event_info** will always be a python object.
757 """
758 if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
759 evas_object_smart_callback_call(self.obj, name, <void*>event_info)
760
761 def move_children_relative(self, int dx, int dy): 669 def move_children_relative(self, int dx, int dy):
762 """Move all children relatively.""" 670 """Move all children relatively."""
763 evas_object_smart_move_children_relative(self.obj, dx, dy) 671 evas_object_smart_move_children_relative(self.obj, dx, dy)
@@ -812,4 +720,173 @@ cdef class SmartObject(Object):
812 def calculate(self): 720 def calculate(self):
813 evas_object_smart_calculate(self.obj) 721 evas_object_smart_calculate(self.obj)
814 722
723 #
724 # Callbacks
725 # =========
726 #
727
728 def _callback_add_full(self, event, event_conv, func, *args, **kargs):
729 """Add a callback for the smart event specified by event.
730
731 :param event: event name
732 :type event: string
733 :param event_conv: Conversion function to get the
734 pointer (as a long) to the object to be given to the
735 function as the second parameter. If None, then no
736 parameter will be given to the callback.
737 :type event_conv: function
738 :param func: what to callback. Should have the signature::
739
740 function(object, event_info, *args, **kargs)
741 function(object, *args, **kargs) (if no event_conv is provided)
742
743 :type func: function
744
745 :raise TypeError: if **func** is not callable.
746 :raise TypeError: if **event_conv** is not callable or None.
747
748 """
749 if not callable(func):
750 raise TypeError("func must be callable")
751 if event_conv is not None and not callable(event_conv):
752 raise TypeError("event_conv must be None or callable")
753
754 if self._smart_callbacks is None:
755 self._smart_callbacks = {}
756
757 e = intern(event)
758 lst = self._smart_callbacks.setdefault(e, [])
759 if isinstance(event, unicode): event = PyUnicode_AsUTF8String(event)
760 if not lst:
761 evas_object_smart_callback_add(self.obj,
762 <const char *>event if event is not None else NULL,
763 _smart_callback, <void *>e)
764 lst.append((event_conv, func, args, kargs))
765
766 def _callback_del_full(self, event, event_conv, func):
767 """Remove a smart callback.
768
769 Removes a callback that was added by :py:func:`_callback_add_full()`.
770
771 :param event: event name
772 :type event: string
773 :param event_conv: same as registered with :py:func:`_callback_add_full()`
774 :type event_conv: function
775 :param func: what to callback, should have be previously registered.
776 :type func: function
777
778 :precond: **event**, **event_conv** and **func** must be used as
779 parameter for :py:func:`_callback_add_full()`.
780
781 :raise ValueError: if there was no **func** connected with this event.
782
783 """
784 try:
785 lst = self._smart_callbacks[event]
786 except KeyError as e:
787 raise ValueError("Unknown event %r" % event)
788
789 i = -1
790 ec = None
791 f = None
792 for i, (ec, f, a, k) in enumerate(lst):
793 if event_conv == ec and func == f:
794 break
795
796 if f != func or ec != event_conv:
797 raise ValueError("Callback %s was not registered with event %r" %
798 (func, event))
799
800 lst.pop(i)
801 if lst:
802 return
803 self._smart_callbacks.pop(event)
804 if isinstance(event, unicode): event = PyUnicode_AsUTF8String(event)
805 evas_object_smart_callback_del(self.obj,
806 <const char *>event if event is not None else NULL,
807 _smart_callback)
808
809 def _callback_add(self, event, func, *args, **kargs):
810 """Add a callback for the smart event specified by event.
811
812 :param event: event name
813 :type event: string
814 :param func: what to callback. Should have the signature:
815 *function(object, *args, **kargs)*
816 :type func: function
817
818 :raise TypeError: if **func** is not callable.
819
820 """
821 return self._callback_add_full(event, None, func, *args, **kargs)
822
823 def _callback_del(self, event, func):
824 """Remove a smart callback.
825
826 Removes a callback that was added by :py:func:`_callback_add()`.
827
828 :param event: event name
829 :type event: string
830 :param func: what to callback, should have be previously registered.
831 :type func: function
832
833 :precond: **event** and **func** must be used as parameter for
834 :py:func:`_callback_add()`.
835
836 :raise ValueError: if there was no **func** connected with this event.
837
838 """
839 return self._callback_del_full(event, None, func)
840
841 def callback_add(self, name, func, *args, **kargs):
842 """Add a callback for the smart event specified by event.
843
844 :param name: Event name
845 :param func:
846 What to callback.
847 Should have the signature::
848
849 function(object, event_info, *args, **kargs)
850
851 :raise TypeError: if **func** is not callable.
852
853 .. warning::
854 **event_info** will always be a python object, if the
855 signal is provided by a C-only class, it will crash.
856
857 """
858 self._callback_add(name, func, *args, **kargs)
859
860 def callback_del(self, name, func):
861 """Remove a smart callback.
862
863 Removes a callback that was added by :py:func:`callback_add()`.
864
865 :param name: event name
866 :param func: what to callback, should have be previously registered.
867 :precond: **event** and **func** must be used as parameter for
868 :py:func:`callback_add`.
869
870 :raise ValueError: if there was no **func** connected with this event.
871 """
872 self._callback_del(name, func)
873
874 def callback_call(self, name, event_info=None):
875 """Call any smart callbacks for event.
876
877 :param name: the event name
878 :param event_info: an event specific info to pass to the callback.
879
880 This should be called internally in the smart object when some
881 specific event has occurred. The documentation for the smart object
882 should include a list of possible events and what type of
883 **event_info** to expect.
884
885 .. attention::
886 **event_info** will always be a python object.
887 """
888 if isinstance(name, unicode): name = PyUnicode_AsUTF8String(name)
889 evas_object_smart_callback_call(self.obj, name, <void*>event_info)
890
891
815_object_mapping_register("Evas_Smart", SmartObject) 892_object_mapping_register("Evas_Smart", SmartObject)
diff --git a/include/efl.evas.pxd b/include/efl.evas.pxd
index b92591b..d0efb8f 100644
--- a/include/efl.evas.pxd
+++ b/include/efl.evas.pxd
@@ -1204,18 +1204,8 @@ cdef class Textblock(Object):
1204 pass 1204 pass
1205 1205
1206 1206
1207# SmartObject disabled atm
1208cdef class SmartObject(Object): 1207cdef class SmartObject(Object):
1209 cdef object _smart_callbacks 1208 cdef dict _smart_callbacks
1210 cdef object _m_delete
1211 cdef object _m_move
1212 cdef object _m_resize
1213 cdef object _m_show
1214 cdef object _m_hide
1215 cdef object _m_color_set
1216 cdef object _m_clip_set
1217 cdef object _m_clip_unset
1218 cdef object _m_calculate
1219 cdef int _set_obj(self, cEo *obj) except 0 1209 cdef int _set_obj(self, cEo *obj) except 0
1220 1210
1221 1211