kuuko pushed a commit to branch master. http://git.enlightenment.org/bindings/python/python-efl.git/commit/?id=d3357619f7d32f53a5df9683409ed67038466a7e
commit d3357619f7d32f53a5df9683409ed67038466a7e Author: Kai Huuhko <kai.huu...@gmail.com> Date: Thu Mar 5 20:21:45 2015 +0200 Evas: Bring back SmartObject Possible TODO: support per-child delete cb like in C --- doc/evas/class-smart.rst | 11 ++++ doc/evas/module-evas.rst | 26 +++++++- efl/evas/efl.evas.pyx | 95 ++++++++++----------------- efl/evas/efl.evas_object_smart.pxi | 20 +++++- examples/elementary/test_core_evas_smart.py | 40 ++++++----- include/efl.evas.pxd | 31 ++++----- setup.py | 6 +- tests/evas/test_06_object_smart.py | 41 ++++++------ tests/evas/test_12_object_smart_as_factory.py | 5 +- 9 files changed, 157 insertions(+), 118 deletions(-) diff --git a/doc/evas/class-smart.rst b/doc/evas/class-smart.rst new file mode 100644 index 0000000..0163e0a --- /dev/null +++ b/doc/evas/class-smart.rst @@ -0,0 +1,11 @@ +.. currentmodule:: efl.evas + +:class:`efl.evas.SmartObject` Class +=================================== + +.. autoclass:: efl.evas.SmartObject + +:class:`efl.evas.ClippedSmartObject` Class +========================================== + +.. autoclass:: efl.evas.ClippedSmartObject diff --git a/doc/evas/module-evas.rst b/doc/evas/module-evas.rst index 7f98583..d45a78b 100644 --- a/doc/evas/module-evas.rst +++ b/doc/evas/module-evas.rst @@ -1,5 +1,29 @@ +:mod:`efl.evas` Module +###################### + +Classes +======= + +.. toctree:: + + class-canvas.rst + class-object.rst + class-image.rst + class-rectangle.rst + class-line.rst + class-polygon.rst + class-text.rst + class-textblock.rst + class-textgrid.rst + class-box.rst + class-table.rst + class-grid.rst + class-map.rst + class-rect.rst + class-smart.rst + .. automodule:: efl.evas :exclude-members: Box, Canvas, FilledImage, Grid, Image, Line, Map, Object, Polygon, Rect, Rectangle, Table, Text, Textblock, - Textgrid, TextgridCell + Textgrid, TextgridCell, SmartObject, ClippedSmartObject diff --git a/efl/evas/efl.evas.pyx b/efl/evas/efl.evas.pyx index 103db64..4b32c4e 100644 --- a/efl/evas/efl.evas.pyx +++ b/efl/evas/efl.evas.pyx @@ -17,31 +17,6 @@ """ -:mod:`efl.evas` Module -###################### - - -Classes -======= - -.. toctree:: - - class-canvas.rst - class-object.rst - class-image.rst - class-rectangle.rst - class-line.rst - class-polygon.rst - class-text.rst - class-textblock.rst - class-textgrid.rst - class-box.rst - class-table.rst - class-grid.rst - class-map.rst - class-rect.rst - - Enumerations ============ @@ -67,31 +42,31 @@ Helper values to be used as :ref:`evas-size-hints` for objects. .. data:: EXPAND_HORIZ = EVAS_HINT_EXPAND, 0.0 Expand horizontally - + .. versionadded:: 1.13 .. data:: EXPAND_VERT = 0.0, EVAS_HINT_EXPAND Expand vertically - + .. versionadded:: 1.13 .. data:: FILL_BOTH = EVAS_HINT_FILL, EVAS_HINT_FILL Fill both direction - + .. versionadded:: 1.13 .. data:: FILL_HORIZ = EVAS_HINT_FILL, 0.5 Fill horizontally - + .. versionadded:: 1.13 .. data:: FILL_VERT = 0.5, EVAS_HINT_FILL Fill vertically - + .. versionadded:: 1.13 @@ -294,7 +269,7 @@ Evas_Event_Flags .. data:: EVAS_EVENT_FLAG_NONE - No fancy flags set. + No fancy flags set. .. data:: EVAS_EVENT_FLAG_ON_HOLD @@ -455,11 +430,11 @@ Evas_Display_Mode .. data:: EVAS_DISPLAY_MODE_EXPAND - Use this mode when you want to give expand display mode hint to an object. + Use this mode when you want to give expand display mode hint to an object. .. data:: EVAS_DISPLAY_MODE_DONT_CHANGE - Use this mode when an object should not change its display mode. + Use this mode when an object should not change its display mode. .. _Evas_Load_Error: @@ -503,15 +478,15 @@ Evas_Alloc_Error .. data:: EVAS_ALLOC_ERROR_NONE - No allocation error. + No allocation error. .. data:: EVAS_ALLOC_ERROR_FATAL - Allocation failed despite attempts to free up memory. + Allocation failed despite attempts to free up memory. .. data:: EVAS_ALLOC_ERROR_RECOVERED - Allocation succeeded, but extra memory had to be found by freeing up speculative resources. + Allocation succeeded, but extra memory had to be found by freeing up speculative resources. .. _Evas_Fill_Spread: @@ -521,27 +496,27 @@ XXX .. data:: EVAS_TEXTURE_REFLECT - Image fill tiling mode - tiling reflects + Image fill tiling mode - tiling reflects .. data:: EVAS_TEXTURE_REPEAT - Image fill tiling mode - tiling reflects + Image fill tiling mode - tiling reflects .. data:: EVAS_TEXTURE_RESTRICT - Tiling clamps - range offset ignored + Tiling clamps - range offset ignored .. data:: EVAS_TEXTURE_RESTRICT_REFLECT - Tiling clamps and any range offset reflects + Tiling clamps and any range offset reflects .. data:: EVAS_TEXTURE_RESTRICT_REPEAT - Tiling clamps and any range offset repeats + Tiling clamps and any range offset repeats .. data:: EVAS_TEXTURE_PAD - Tiling extends with end values + Tiling extends with end values .. _Evas_Pixel_Import_Pixel_Format: @@ -551,11 +526,11 @@ Evas_Pixel_Import_Pixel_Format .. data:: EVAS_PIXEL_FORMAT_NONE - No pixel format. + No pixel format. .. data:: EVAS_PIXEL_FORMAT_ARGB32 - ARGB 32bit pixel format with A in the high byte per 32bit pixel word. + ARGB 32bit pixel format with A in the high byte per 32bit pixel word. .. data:: EVAS_PIXEL_FORMAT_YUV420P_601 @@ -592,19 +567,19 @@ Evas_Render_Op .. data:: EVAS_RENDER_BLEND - default op: d = d*(1-sa) + s + default op: d = d*(1-sa) + s .. data:: EVAS_RENDER_BLEND_REL - d = d*(1 - sa) + s*da + d = d*(1 - sa) + s*da .. data:: EVAS_RENDER_COPY - d = s + d = s .. data:: EVAS_RENDER_COPY_REL - d = s*da + d = s*da .. data:: EVAS_RENDER_ADD @@ -612,11 +587,11 @@ Evas_Render_Op .. data:: EVAS_RENDER_ADD_REL - d = d + s*da + d = d + s*da .. data:: EVAS_RENDER_SUB - d = d - s + d = d - s .. data:: EVAS_RENDER_SUB_REL @@ -624,19 +599,19 @@ Evas_Render_Op .. data:: EVAS_RENDER_TINT - d = d*s + d*(1 - sa) + s*(1 - da) + d = d*s + d*(1 - sa) + s*(1 - da) .. data:: EVAS_RENDER_TINT_REL - d = d*(1 - sa + s) + d = d*(1 - sa + s) .. data:: EVAS_RENDER_MASK - d = d*sa + d = d*sa .. data:: EVAS_RENDER_MUL - d = d*s + d = d*s .. _Evas_Border_Fill_Mode: @@ -714,15 +689,15 @@ Evas_Image_Content_Hint .. data:: EVAS_IMAGE_CONTENT_HINT_NONE - No hint at all. + No hint at all. .. data:: EVAS_IMAGE_CONTENT_HINT_DYNAMIC - The contents will change over time. + The contents will change over time. .. data:: EVAS_IMAGE_CONTENT_HINT_STATIC - The contents won't change over time. + The contents won't change over time. .. _Evas_Device_Class: @@ -770,11 +745,11 @@ Evas_Object_Pointer_Mode .. data:: EVAS_OBJECT_POINTER_MODE_AUTOGRAB - default, X11-like + default, X11-like .. data:: EVAS_OBJECT_POINTER_MODE_NOGRAB - pointer always bound to the object right below it + pointer always bound to the object right below it .. data:: EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN @@ -1155,7 +1130,7 @@ include "efl.evas_object_callbacks.pxi" include "efl.evas_object.pxi" # Disable evas smart object for the moment, because PyMethod_New is broken # in recent Cython versions, at least in Cython 0.21.1/2 using py3. -# include "efl.evas_object_smart.pxi" +include "efl.evas_object_smart.pxi" include "efl.evas_object_image.pxi" include "efl.evas_object_line.pxi" include "efl.evas_object_rectangle.pxi" diff --git a/efl/evas/efl.evas_object_smart.pxi b/efl/evas/efl.evas_object_smart.pxi index 2ef79ed..c61b7d7 100644 --- a/efl/evas/efl.evas_object_smart.pxi +++ b/efl/evas/efl.evas_object_smart.pxi @@ -16,8 +16,9 @@ # along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>. from efl.utils.conversions cimport eina_list_objects_to_python_list +from efl.c_eo cimport eo_do, eo_key_data_del, eo_key_data_set -from cpython cimport PyMethod_New +from cpython cimport PyMethod_New, Py_INCREF, Py_DECREF import types #cdef object _smart_classes @@ -113,6 +114,11 @@ cdef void _smart_object_delete(Evas_Object *o) with gil: obj._m_member_add = None obj._m_member_del = None + # eo_do(self.obj, + # eo_event_callback_del(EO_EV_DEL, _eo_event_del_cb, <const void *>self)) + eo_do(o, eo_key_data_del("python-eo")) + obj.obj = NULL + Py_DECREF(obj) cdef void _smart_object_move(Evas_Object *o, Evas_Coord x, Evas_Coord y) with gil: @@ -478,6 +484,18 @@ cdef class SmartObject(Object): self._set_properties_from_keyword_args(kwargs) + cdef int _set_obj(self, cEo *obj) except 0: + assert self.obj == NULL, "Object must be clean" + assert obj != NULL, "Cannot set a NULL object" + + self.obj = obj + eo_do(self.obj, eo_key_data_set("python-eo", <void *>self, NULL)) + # eo_do(self.obj, + # eo_event_callback_add(EO_EV_DEL, _eo_event_del_cb, <const void *>self)) + Py_INCREF(self) + + return 1 + def member_add(self, Object child): """member_add(Object child) diff --git a/examples/elementary/test_core_evas_smart.py b/examples/elementary/test_core_evas_smart.py index 5c733c9..597ad22 100644 --- a/examples/elementary/test_core_evas_smart.py +++ b/examples/elementary/test_core_evas_smart.py @@ -4,8 +4,7 @@ import os from random import randint -from efl.evas import SmartObject, EVAS_HINT_EXPAND, EVAS_HINT_FILL, \ - EXPAND_BOTH, FILL_BOTH +from efl.evas import SmartObject, EXPAND_BOTH, FILL_BOTH from efl import elementary from efl.elementary.window import StandardWindow from efl.elementary.box import Box @@ -18,32 +17,34 @@ objects = [] def random_color(): - return (randint(0,255), randint(0,255), randint(0,255), 255) + return (randint(0, 255), randint(0, 255), randint(0, 255), 255) + class MySmartObj(SmartObject): + def __init__(self, canvas): SmartObject.__init__(self, canvas) # gray background - self.bg = self.Rectangle(color=(128,128,128,128)) + self.bg = self.Rectangle(color=(128, 128, 128, 128)) # green dragbar to move the obj - self.dragpos = self.Rectangle(color=(0,128,0,128)) + self.dragpos = self.Rectangle(color=(0, 128, 0, 128)) self.dragpos.on_mouse_down_add(self.start_drag_move) self.dragpos.on_mouse_up_add(self.stop_drag_move) # blue rect to resize the obj - self.dragsize = self.Rectangle(color=(0,0,128,128)) + self.dragsize = self.Rectangle(color=(0, 0, 128, 128)) self.dragsize.on_mouse_down_add(self.start_drag_resize) self.dragsize.on_mouse_up_add(self.stop_drag_resize) # testing factories - self.obj_rect = self.Rectangle(size=(15,15), color=random_color()) - self.obj_rect.on_mouse_down_add(lambda o,e: self.hide()) + self.obj_rect = self.Rectangle(size=(15, 15), color=random_color()) + self.obj_rect.on_mouse_down_add(lambda o, e: self.hide()) self.obj_line = self.Line(color=random_color()) - self.obj_image = self.FilledImage(file=ic_file, size=(20,20)) + self.obj_image = self.FilledImage(file=ic_file, size=(20, 20)) self.obj_poly = self.Polygon(color=random_color()) - self.obj_text = self.Text(color=(0,0,0,255), font="Sans", + self.obj_text = self.Text(color=(0, 0, 0, 255), font="Sans", pass_events=True, text="Drag me") def resize(self, w, h): @@ -57,7 +58,7 @@ class MySmartObj(SmartObject): def move(self, x, y): print("MOVE", x, y) self.bg.pos = x, y - self.obj_text.pos = x,y + self.obj_text.pos = x, y self.dragpos.pos = x, y self.dragsize.pos = x + self.bg.size[0] - 15, y + self.bg.size[1] - 15 self.obj_rect.pos = x + 5, y + 20 @@ -110,6 +111,7 @@ class MySmartObj(SmartObject): x, y = event.position.canvas self.size = x - self.bg.pos[0], y - self.bg.pos[1] + def btn_add_cb(b): sm = MySmartObj(b.evas) sm.size = 100, 100 @@ -117,17 +119,21 @@ def btn_add_cb(b): sm.show() objects.append(sm) + def btn_del_cb(b): objects.pop().delete() + def btn_hide_cb(b): for o in objects: o.hide() + def btn_show_cb(b): for o in objects: o.show() + def core_evas_smart_clicked(obj, item=None): win = StandardWindow("evassmart", "Evas Smart Object Test", autodel=True) if obj is None: @@ -138,22 +144,22 @@ def core_evas_smart_clicked(obj, item=None): box.show() win.resize_object_add(box) - b = Button(win, text="Add one", size_hint_align=(0.0,0.0)) + b = Button(win, text="Add one", size_hint_align=(0.0, 0.0)) b.callback_clicked_add(btn_add_cb) box.pack_end(b) b.show() - b = Button(win, text="Del last", size_hint_align=(0.0,0.0)) + b = Button(win, text="Del last", size_hint_align=(0.0, 0.0)) b.callback_clicked_add(btn_del_cb) box.pack_end(b) b.show() - b = Button(win, text="Hide all", size_hint_align=(0.0,0.0)) + b = Button(win, text="Hide all", size_hint_align=(0.0, 0.0)) b.callback_clicked_add(btn_hide_cb) box.pack_end(b) b.show() - b = Button(win, text="Show all", size_hint_align=(0.0,0.0)) + b = Button(win, text="Show all", size_hint_align=(0.0, 0.0)) b.callback_clicked_add(btn_show_cb) box.pack_end(b) b.show() @@ -163,8 +169,10 @@ def core_evas_smart_clicked(obj, item=None): if __name__ == "__main__": + import logging + efl_log = logging.getLogger("efl") + efl_log.addHandler(logging.StreamHandler()) elementary.init() core_evas_smart_clicked(None) elementary.run() elementary.shutdown() - diff --git a/include/efl.evas.pxd b/include/efl.evas.pxd index b876a06..9bdc576 100644 --- a/include/efl.evas.pxd +++ b/include/efl.evas.pxd @@ -1203,21 +1203,22 @@ cdef class Textblock(Object): # SmartObject disabled atm -# cdef class SmartObject(Object): -# cdef object _smart_callbacks -# cdef object _m_delete -# cdef object _m_move -# cdef object _m_resize -# cdef object _m_show -# cdef object _m_hide -# cdef object _m_color_set -# cdef object _m_clip_set -# cdef object _m_clip_unset -# cdef object _m_calculate - - -# cdef class ClippedSmartObject(SmartObject): -# cdef readonly Rectangle clipper +cdef class SmartObject(Object): + cdef object _smart_callbacks + cdef object _m_delete + cdef object _m_move + cdef object _m_resize + cdef object _m_show + cdef object _m_hide + cdef object _m_color_set + cdef object _m_clip_set + cdef object _m_clip_unset + cdef object _m_calculate + cdef int _set_obj(self, cEo *obj) except 0 + + +cdef class ClippedSmartObject(SmartObject): + cdef readonly Rectangle clipper cdef class EventPoint: diff --git a/setup.py b/setup.py index be653ca..fa9e67d 100755 --- a/setup.py +++ b/setup.py @@ -283,9 +283,13 @@ if set(("build", "build_ext", "install", "bdist", "sdist")) & set(sys.argv): # === Evas === evas_cflags, evas_libs = pkg_config('Evas', 'evas', EFL_MIN_VER) evas_ext = Extension("evas", ["efl/evas/efl.evas" + module_suffix], + define_macros=[ + ('EFL_BETA_API_SUPPORT', 1), + ('EFL_EO_API_SUPPORT', 1) + ], include_dirs=['include/'], extra_compile_args=evas_cflags, - extra_link_args=evas_libs + eina_libs) + extra_link_args=evas_libs + eina_libs + eo_libs) ext_modules.append(evas_ext) # === Ecore === diff --git a/tests/evas/test_06_object_smart.py b/tests/evas/test_06_object_smart.py index b42508b..b8e4d95 100644 --- a/tests/evas/test_06_object_smart.py +++ b/tests/evas/test_06_object_smart.py @@ -4,27 +4,26 @@ from efl import evas import unittest -#class MyObject(evas.SmartObject): -# def __init__(self, canvas, *args, **kargs): -# evas.SmartObject.__init__(self, canvas, *args, **kargs) -# w, h = self.size -# w2 = w / 2 -# h2 = h / 2 -# self.r1 = evas.Rectangle(canvas, geometry=(0, 0, w2, h2), -# color="#ff0000") -# self.member_add(self.r1) -# -# self.r2 = evas.Rectangle(canvas, geometry=(w2, h2, w2, h2), -# color="#00ff00") -# self.member_add(self.r2) -# -# def resize(self, w, h): -# w2 = w / 2 -# h2 = h / 2 -# self.r1.geometry = (0, 0, w2, h2) -# self.r2.geometry = (w2, h2, w2, h2) - -@unittest.skip("SmartObject disabled") +class MyObject(evas.SmartObject): + def __init__(self, canvas, *args, **kargs): + evas.SmartObject.__init__(self, canvas, *args, **kargs) + w, h = self.size + w2 = w / 2 + h2 = h / 2 + self.r1 = evas.Rectangle(canvas, geometry=(0, 0, w2, h2), + color="#ff0000") + self.member_add(self.r1) + + self.r2 = evas.Rectangle(canvas, geometry=(w2, h2, w2, h2), + color="#00ff00") + self.member_add(self.r2) + + def resize(self, w, h): + w2 = w / 2 + h2 = h / 2 + self.r1.geometry = (0, 0, w2, h2) + self.r2.geometry = (w2, h2, w2, h2) + class SmartObjectTest(unittest.TestCase): def setUp(self): self.canvas = evas.Canvas(method="buffer", diff --git a/tests/evas/test_12_object_smart_as_factory.py b/tests/evas/test_12_object_smart_as_factory.py index 377de8c..7b24fe5 100644 --- a/tests/evas/test_12_object_smart_as_factory.py +++ b/tests/evas/test_12_object_smart_as_factory.py @@ -4,10 +4,9 @@ from efl import evas import unittest -# class MyObject(evas.SmartObject): - # pass +class MyObject(evas.SmartObject): + pass -@unittest.skip("SmartObject disabled") class CanvasFactory(unittest.TestCase): def setUp(self): self.canvas = evas.Canvas(method="buffer", --