Python-EFL: implemented decorators for edje.
Decorators implemented in a much more simple and generic way than before, we can use them in other place too. 3 deco implemented: @on_signal(emission, source) @message_handler @on_text_change I choosed the 'strange' on_* naming convention to not clash/confuse with normal callback functions, tell me if you don't like.
This commit is contained in:
parent
236d66caf8
commit
5913721de9
1
TODO
1
TODO
|
@ -54,7 +54,6 @@ STUFF LEFT OUT
|
|||
* python-evas/evas/decorators.py
|
||||
* python-evas/evas/debug.py
|
||||
* python-evas old hack to rotate objects
|
||||
* edje decorators callbacks
|
||||
|
||||
|
||||
CHANGES FROM 1.7 to 1.8
|
||||
|
|
|
@ -21,8 +21,9 @@ import warnings
|
|||
from cpython cimport PyMem_Malloc, PyMem_Free, PyUnicode_AsUTF8String
|
||||
cimport libc.stdlib
|
||||
|
||||
from efl.eo cimport _object_mapping_register, object_from_instance
|
||||
from efl.eo cimport _ctouni, _touni, convert_eina_list_strings_to_python_list
|
||||
from efl.eo cimport _object_mapping_register, object_from_instance, \
|
||||
_register_decorated_callbacks, _ctouni, _touni, \
|
||||
convert_eina_list_strings_to_python_list
|
||||
|
||||
|
||||
# Edje_Message_Type:
|
||||
|
@ -318,36 +319,6 @@ def module_load(name):
|
|||
return bool(edje_module_load(
|
||||
<const_char *>name if name is not None else NULL))
|
||||
|
||||
# class EdjeObjectMeta(evas.c_evas.EvasObjectMeta):
|
||||
# def __init__(cls, name, bases, dict_):
|
||||
# evas.c_evas.EvasObjectMeta.__init__(cls, name, bases, dict_)
|
||||
# cls._fetch_callbacks()
|
||||
#
|
||||
# def _fetch_callbacks(cls):
|
||||
# if "__edje_signal_callbacks__" in cls.__dict__:
|
||||
# return
|
||||
#
|
||||
# cls.__edje_signal_callbacks__ = []
|
||||
# cls.__edje_message_callbacks__ = []
|
||||
# cls.__edje_text_callbacks__ = []
|
||||
#
|
||||
# sig_append = cls.__edje_signal_callbacks__.append
|
||||
# msg_append = cls.__edje_message_callbacks__.append
|
||||
# txt_append = cls.__edje_text_callbacks__.append
|
||||
#
|
||||
# for name in dir(cls):
|
||||
# val = getattr(cls, name)
|
||||
# if not callable(val):
|
||||
# continue
|
||||
#
|
||||
# if hasattr(val, "edje_signal_callback"):
|
||||
# sig_data = getattr(val, "edje_signal_callback")
|
||||
# sig_append((name, sig_data))
|
||||
# elif hasattr(val, "edje_message_handler"):
|
||||
# msg_append(name)
|
||||
# elif hasattr(val, "edje_text_change_callback"):
|
||||
# txt_append(name)
|
||||
|
||||
|
||||
include "efl.edje_message.pxi"
|
||||
include "efl.edje_external.pxi"
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
# 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/>.
|
||||
|
||||
|
||||
cdef void text_change_cb(void *data,
|
||||
Evas_Object *obj,
|
||||
const_char *part) with gil:
|
||||
|
@ -127,6 +128,7 @@ cdef class Edje(Object):
|
|||
|
||||
def __init__(self, Canvas canvas not None, **kargs):
|
||||
self._set_obj(edje_object_add(canvas.obj))
|
||||
_register_decorated_callbacks(self)
|
||||
self._set_common_params(**kargs)
|
||||
|
||||
def __free_wrapper_resources(self, ed):
|
||||
|
@ -1206,4 +1208,26 @@ cdef class Edje(Object):
|
|||
<const_char *>source if source is not None else NULL)
|
||||
|
||||
|
||||
# decorators
|
||||
def on_signal(emission, source):
|
||||
def decorator(func):
|
||||
if not hasattr(func, "__decorated_callbacks__"):
|
||||
func.__decorated_callbacks__ = list()
|
||||
func.__decorated_callbacks__.append(("signal_callback_add", emission, source, func))
|
||||
return func
|
||||
return decorator
|
||||
|
||||
def message_handler(func):
|
||||
if not hasattr(func, "__decorated_callbacks__"):
|
||||
func.__decorated_callbacks__ = list()
|
||||
func.__decorated_callbacks__.append(("message_handler_set", func))
|
||||
return func
|
||||
|
||||
def on_text_change(func):
|
||||
if not hasattr(func, "__decorated_callbacks__"):
|
||||
func.__decorated_callbacks__ = list()
|
||||
func.__decorated_callbacks__.append(("text_change_cb_set", func))
|
||||
return func
|
||||
|
||||
|
||||
_object_mapping_register("edje", Edje)
|
||||
|
|
|
@ -233,6 +233,22 @@ cdef object object_from_instance(cEo *obj):
|
|||
return o
|
||||
|
||||
|
||||
cdef void _register_decorated_callbacks(object obj):
|
||||
""" Serach every attrib of the pyobj for a __decorated_callbacks__ object,
|
||||
a list actually. If found then exec the functions listed there, with their
|
||||
arguments. Must be called just after the _set_obj call.
|
||||
List items signature: ("function_name", *args)
|
||||
"""
|
||||
cdef object attr_name, attrib, func_name, func
|
||||
|
||||
for attr_name in dir(obj):
|
||||
attrib = getattr(obj, attr_name)
|
||||
if hasattr(attrib, "__decorated_callbacks__"):
|
||||
for (func_name, *args) in getattr(attrib, "__decorated_callbacks__"):
|
||||
func = getattr(obj, func_name)
|
||||
func(*args)
|
||||
|
||||
|
||||
######################################################################
|
||||
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
# along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from efl.c_eo cimport Eo as cEo
|
||||
from efl.c_eo cimport Eo_Class
|
||||
from efl cimport Eina_List, const_Eina_List
|
||||
from libc.string cimport const_char
|
||||
|
||||
|
@ -35,6 +34,8 @@ cdef object object_from_instance(cEo *obj)
|
|||
cdef void _object_mapping_register(char *name, object cls) except *
|
||||
cdef void _object_mapping_unregister(char *name)
|
||||
|
||||
cdef void _register_decorated_callbacks(object obj)
|
||||
|
||||
cdef unicode _touni(char* s)
|
||||
cdef unicode _ctouni(const_char *s)
|
||||
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from efl import evas
|
||||
from efl import ecore
|
||||
from efl import edje
|
||||
from efl.edje import Edje
|
||||
|
||||
import os, unittest
|
||||
|
||||
|
||||
theme_file = os.path.join(os.path.dirname(__file__), "theme.edj")
|
||||
|
||||
expected_signals = ["edje,state,ltr", "load", "edje,state,ltr", "resize",
|
||||
"cursor,changed", "changed", "zoom,stop", "emit,message",
|
||||
"emit,message"]
|
||||
expected_signals2 = ["load", "resize"]
|
||||
expected_messages = [33, 33]
|
||||
expected_text_parts = ["label", "label"]
|
||||
|
||||
|
||||
class MyEdje(Edje):
|
||||
def __init__(self, canvas):
|
||||
Edje.__init__(self, canvas, file=theme_file, group="main")
|
||||
|
||||
|
||||
@edje.on_signal("*", "*")
|
||||
def cb_signal_all(self, emission, source):
|
||||
expected_signals.remove(emission)
|
||||
|
||||
@edje.on_signal("load", "*")
|
||||
@edje.on_signal("resize", "*")
|
||||
def cb_signal_load_resize(self, emission, source):
|
||||
expected_signals2.remove(emission)
|
||||
|
||||
@edje.message_handler
|
||||
def message_handler(self, msg):
|
||||
expected_messages.remove(msg.val)
|
||||
|
||||
@edje.on_text_change
|
||||
def text_change(self, part):
|
||||
expected_text_parts.remove(part)
|
||||
|
||||
|
||||
class TestEdjeDecoratedCallbacks(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.canvas = evas.Canvas(method="buffer",
|
||||
size=(400, 500),
|
||||
viewport=(0, 0, 400, 500))
|
||||
self.canvas.engine_info_set(self.canvas.engine_info_get())
|
||||
|
||||
def tearDown(self):
|
||||
self.canvas.delete()
|
||||
|
||||
def testDecorators(self):
|
||||
o = MyEdje(self.canvas)
|
||||
self.assertIsInstance(o, Edje)
|
||||
|
||||
# this should trigger text_change, two times
|
||||
ecore.Timer(0.1, lambda: o.part_text_set("label", "asd"))
|
||||
ecore.Timer(0.1, lambda: o.part_text_set("label", "asd2"))
|
||||
|
||||
# ask the edje obj to send a messagge, two times
|
||||
ecore.Timer(0.1, lambda: o.signal_emit("emit,message", ""))
|
||||
ecore.Timer(0.1, lambda: o.signal_emit("emit,message", ""))
|
||||
|
||||
# and then quit the main loop
|
||||
ecore.Timer(0.2, lambda: ecore.main_loop_quit())
|
||||
|
||||
ecore.main_loop_begin()
|
||||
|
||||
self.assertEqual(expected_signals, [])
|
||||
self.assertEqual(expected_signals2, [])
|
||||
self.assertEqual(expected_messages, [])
|
||||
self.assertEqual(expected_text_parts, [])
|
||||
|
||||
o.delete()
|
||||
self.assertTrue(o.is_deleted())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(verbosity=2)
|
||||
edje.shutdown()
|
||||
ecore.shutdown()
|
||||
evas.shutdown()
|
|
@ -534,7 +534,7 @@ collections {
|
|||
program { name: "emit_back_message";
|
||||
signal: "emit,message";
|
||||
script {
|
||||
send_message(MSG_INT, 1, 1);
|
||||
send_message(MSG_INT, 1, 33);
|
||||
}
|
||||
}
|
||||
program { name: "prog1";
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue