diff --git a/doc/ewe/ewe.rst b/doc/ewe/ewe.rst new file mode 100644 index 0000000..8a0e72e --- /dev/null +++ b/doc/ewe/ewe.rst @@ -0,0 +1,34 @@ +.. py:module:: efl.ewe + +:mod:`efl.ewe` Package +============================= + +.. automodule:: + efl.ewe.__init__ + +Reference +--------- + +Modules +^^^^^^^ + +.. toctree:: + :maxdepth: 4 + + module-combobox + module-entry + module-ruler + module-statusbar + module-tabs + +Inheritance diagram +------------------- + +.. inheritance-diagram:: + efl.ewe.__init__ + efl.ewe.combobox + efl.ewe.entry + efl.ewe.ruler + efl.ewe.statusbar + efl.ewe.tabs + :parts: 3 diff --git a/doc/ewe/module-combobox.rst b/doc/ewe/module-combobox.rst new file mode 100644 index 0000000..a8a4630 --- /dev/null +++ b/doc/ewe/module-combobox.rst @@ -0,0 +1,8 @@ +:mod:`combobox` Module +-------------------------- + +.. automodule:: efl.ewe.combobox + +.. inheritance-diagram:: + efl.ewe.combobox + :parts: 3 diff --git a/doc/ewe/module-entry.rst b/doc/ewe/module-entry.rst new file mode 100644 index 0000000..efa313f --- /dev/null +++ b/doc/ewe/module-entry.rst @@ -0,0 +1,8 @@ +:mod:`entry` Module +-------------------------- + +.. automodule:: efl.ewe.entry + +.. inheritance-diagram:: + efl.ewe.entry + :parts: 3 diff --git a/doc/ewe/module-ruler.rst b/doc/ewe/module-ruler.rst new file mode 100644 index 0000000..f471567 --- /dev/null +++ b/doc/ewe/module-ruler.rst @@ -0,0 +1,8 @@ +:mod:`ruler` Module +-------------------------- + +.. automodule:: efl.ewe.ruler + +.. inheritance-diagram:: + efl.ewe.ruler + :parts: 3 diff --git a/doc/ewe/module-statusbar.rst b/doc/ewe/module-statusbar.rst new file mode 100644 index 0000000..a904e58 --- /dev/null +++ b/doc/ewe/module-statusbar.rst @@ -0,0 +1,8 @@ +:mod:`statusbar` Module +-------------------------- + +.. automodule:: efl.ewe.statusbar + +.. inheritance-diagram:: + efl.ewe.statusbar + :parts: 3 diff --git a/doc/ewe/module-tabs.rst b/doc/ewe/module-tabs.rst new file mode 100644 index 0000000..945ab16 --- /dev/null +++ b/doc/ewe/module-tabs.rst @@ -0,0 +1,8 @@ +:mod:`tabs` Module +-------------------------- + +.. automodule:: efl.ewe.tabs + +.. inheritance-diagram:: + efl.ewe.tabs + :parts: 3 diff --git a/doc/index.rst b/doc/index.rst index ac42901..63377b8 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -79,6 +79,13 @@ Elementary :maxdepth: 4 +Ewe +---------- + +.. toctree:: ewe/ewe + :maxdepth: 4 + + DBus integration ---------------- diff --git a/efl/elementary/entry.pxd b/efl/elementary/entry.pxd index 0096f7d..4f9c4ef 100644 --- a/efl/elementary/entry.pxd +++ b/efl/elementary/entry.pxd @@ -5,6 +5,7 @@ from enums cimport Elm_Wrap_Type, Elm_Text_Format, Elm_Cnp_Mode, \ Elm_Input_Panel_Lang, Elm_Input_Panel_Return_Key_Type, \ Elm_Autocapital_Type, Elm_Icon_Type, Elm_Sel_Type, Elm_Sel_Format, \ Elm_Xdnd_Action +from efl.elementary.layout_class cimport LayoutClass cdef extern from "Elementary.h": ctypedef struct Elm_Entry_Anchor_Info: @@ -151,3 +152,6 @@ cdef extern from "Elementary.h": void elm_entry_context_menu_item_icon_get(const Elm_Entry_Context_Menu_Item *item, const char **icon_file, const char **icon_group, Elm_Icon_Type *icon_type) Eina_Bool elm_cnp_selection_get(const Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format, Elm_Drop_Cb datacb, void *udata) + +cdef class Entry(LayoutClass): + pass diff --git a/efl/ewe/__init__.pxd b/efl/ewe/__init__.pxd new file mode 100644 index 0000000..44c0f7f --- /dev/null +++ b/efl/ewe/__init__.pxd @@ -0,0 +1,3 @@ +cdef extern from "ewe.h": + int ewe_init(int argc, char **argv) + int ewe_shutdown() diff --git a/efl/ewe/__init__.py b/efl/ewe/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/efl/ewe/__init__.pyx b/efl/ewe/__init__.pyx new file mode 100644 index 0000000..6bea8c9 --- /dev/null +++ b/efl/ewe/__init__.pyx @@ -0,0 +1,45 @@ +from libc.string cimport memcpy +from cpython cimport PyMem_Malloc, PyUnicode_AsUTF8String + +import sys + +def init(): + """Initialize Elementary Widget Extensions library + + :return: The init counter value. + :rtype: int + + This function initializes Ewe and increments a counter of + the number of calls to it. It returns the new counter's value. + + """ + cdef: + int argc, i, arg_len + char **argv + char *arg + + argc = len(sys.argv) + argv = PyMem_Malloc(argc * sizeof(char *)) + for i in range(argc): + t = sys.argv[i] + if isinstance(t, unicode): t = PyUnicode_AsUTF8String(t) + arg = t + arg_len = len(arg) + argv[i] = PyMem_Malloc(arg_len + 1) + memcpy(argv[i], arg, arg_len + 1) + + return ewe_init(argc, argv) + +def shutdown(): + """Shut down Elementary Widget Extensions library + + :return: The init counter value. + :rtype: int + + This should be called at the end of your application, just + before it ceases to do any more processing. This will clean up + any permanent resources your application may have allocated via + Ewe that would otherwise persist. + + """ + return ewe_shutdown() diff --git a/efl/ewe/combobox.pxd b/efl/ewe/combobox.pxd new file mode 100644 index 0000000..8f7a458 --- /dev/null +++ b/efl/ewe/combobox.pxd @@ -0,0 +1,21 @@ +from efl.eina cimport Eina_Bool, Eina_Stringshare, Eina_List +from efl.evas cimport Evas_Object + +cdef extern from "ewe.h": + ctypedef struct Ewe_Combobox_Item: + Evas_Object *owner + Evas_Object *content + Eina_Stringshare *title + unsigned int index + + Evas_Object * ewe_combobox_add(Evas_Object *parent) + Eina_Bool ewe_combobox_expanded_get(Evas_Object *obj) + Ewe_Combobox_Item * ewe_combobox_item_add(Evas_Object *obj, Eina_Stringshare *title) + Eina_Bool ewe_combobox_item_del(Evas_Object *obj, Ewe_Combobox_Item *item) + Eina_Bool ewe_combobox_items_list_free(Evas_Object *obj, Eina_Bool empty) + const Eina_List * ewe_combobox_items_list_get(const Evas_Object *obj) + Eina_Bool ewe_combobox_item_title_set(Evas_Object *obj, int index, Eina_Stringshare *title) + Eina_Bool ewe_combobox_text_set(Evas_Object *obj, Eina_Stringshare *title) + Eina_Stringshare * ewe_combobox_item_title_get(Evas_Object *obj, const int index) + Ewe_Combobox_Item * ewe_combobox_select_item_get(Evas_Object *obj) + Eina_Bool ewe_combobox_select_item_set(Evas_Object *obj, const int index) diff --git a/efl/ewe/combobox.pyx b/efl/ewe/combobox.pyx new file mode 100644 index 0000000..ea6021c --- /dev/null +++ b/efl/ewe/combobox.pyx @@ -0,0 +1,166 @@ +from libc.stdint cimport uintptr_t +from cpython cimport PyUnicode_AsUTF8String + +from efl.utils.conversions cimport _ctouni +from efl.evas cimport Object as evasObject +from efl.elementary.object cimport Object + +def _cb_combobox_item_conv(uintptr_t addr): + cdef ComboboxItem it = ComboboxItem.__new__(ComboboxItem) + it.item = addr + return it + +cdef class ComboboxItem(object): + + cdef Ewe_Combobox_Item *item + + def __init__(self, evasObject parent not None, title): + """This adds an item to combobox object. + + :param parent: The combobox object + :param title: The combobox title + + """ + if isinstance(title, unicode): title = PyUnicode_AsUTF8String(title) + self.item = ewe_combobox_item_add(parent.obj, title) + + def delete(self): + """Delete combobox item. + + :param item: The combobox item + :return: EINA_TRUE on success, EINA_FALSE otherwise + + """ + return bool(ewe_combobox_item_del(self.item.owner, self.item)) + +cdef list eina_list_items_to_python_list(const Eina_List *lst): + cdef: + Ewe_Combobox_Item *item + list ret = [] + Eina_List *itr = lst + ComboboxItem it + while itr: + it = ComboboxItem.__new__(ComboboxItem) + it.item = itr.data + ret.append(it) + itr = itr.next + return ret + +cdef class Combobox(Object): + + def __init__(self, evasObject parent not None, **kwargs): + """Add a new combobox to the parent + + :param parent: The parent object + + """ + self._set_obj(ewe_combobox_add(parent.obj)) + self._set_properties_from_keyword_args(kwargs) + + property expanded: + """Returns whether the combobox is expanded. + + :type: bool + + """ + def __get__(self): + return bool(ewe_combobox_expanded_get(self.obj)) + + def items_list_free(self, bint empty): + """Combobox items list free. + + :param item: The combobox item + :return: True on success, False otherwise + + """ + return ewe_combobox_items_list_free(self.obj, empty) + + def items_list_get(self): + """Get internal items list. + + :return: list of items on success, None otherwise + + """ + return eina_list_items_to_python_list( + ewe_combobox_items_list_get(self.obj) + ) + + property text: + """This sets title for the combobox. + + :param title: Text to be set as title of the combobox + :raise RuntimeError: True on success, False otherwise + + """ + def __set__(self, title): + if isinstance(title, unicode): + title = PyUnicode_AsUTF8String(title) + if not ewe_combobox_text_set(self.obj, title): + raise RuntimeError("Setting title text failed") + + def selected_item_get(self): + """Gets the selected item from a combobox object. + + :return: The selected combobox item object or None if it cannot be created + + """ + cdef ComboboxItem it = ComboboxItem.__new__(ComboboxItem) + it.item = ewe_combobox_select_item_get(self.obj) + return it + + def selected_item_set(self, int index): + """Sets select combobox item. + + :param index: The combobox index + :return: True on success, False otherwise + + """ + return bool(ewe_combobox_select_item_set(self.obj, index)) + + def item_title_set(self, int index, title): + """This sets title of the combobox item. + + :param index: The combobox item index + :param title: Text to be setted as title of the combobox item + :rtype: bool + + """ + if isinstance(title, unicode): title = PyUnicode_AsUTF8String(title) + return ewe_combobox_item_title_set( + self.obj, + index, + title if title is not None else NULL + ) + def item_title_get(self, int index): + """This sets title of the combobox item. + + :param index: The combobox item index + :rtype: string + + """ + return _ctouni(ewe_combobox_item_title_get( + self.obj, + index + )) + + def callback_collapsed_add(self, func, *args, **kwargs): + """Called when the menu is collapsed.""" + self._callback_add("collapsed", func, *args, **kwargs) + + def callback_collapsed_del(self, func): + self._callback_del("collapsed", func) + + def callback_expanded_add(self, func, *args, **kwargs): + """Called when the menu is expanded.""" + self._callback_add("expanded", func, *args, **kwargs) + + def callback_expanded_del(self, func): + self._callback_del("expanded", func) + + def callback_selected_add(self, func, *args, **kwargs): + """Called when user selects an item.""" + self._callback_add_full("selected", _cb_combobox_item_conv, func, + *args, **kwargs) + + def callback_selected_del(self, func): + self._callback_del_full("selected", _cb_combobox_item_conv, func) diff --git a/efl/ewe/entry.pxd b/efl/ewe/entry.pxd new file mode 100644 index 0000000..738afdc --- /dev/null +++ b/efl/ewe/entry.pxd @@ -0,0 +1,15 @@ +from efl.eina cimport Eina_Bool +from efl.evas cimport Evas_Object + +cdef extern from "ewe.h": + Evas_Object *ewe_entry_add(Evas_Object *parent) + Eina_Bool ewe_entry_regex_set(Evas_Object *obj, const char *regex_str, int flags) + Eina_Bool ewe_entry_regex_unset(Evas_Object *obj) + Eina_Bool ewe_entry_regex_check(Evas_Object *obj) + Eina_Bool ewe_entry_regex_glow_set(Evas_Object *obj, Eina_Bool glow) + Eina_Bool ewe_entry_regex_glow_get(const Evas_Object *obj) + int ewe_entry_regex_error_get(const Evas_Object *obj) + const char * ewe_entry_regex_error_text_get(const Evas_Object *obj) + Eina_Bool ewe_entry_regex_autocheck_set(Evas_Object *obj, Eina_Bool autocheck) + Eina_Bool ewe_entry_regex_autocheck_get(const Evas_Object *obj) + void ewe_entry_entry_set(Evas_Object *obj, const char *text) diff --git a/efl/ewe/entry.pyx b/efl/ewe/entry.pyx new file mode 100644 index 0000000..d4b6d10 --- /dev/null +++ b/efl/ewe/entry.pyx @@ -0,0 +1,221 @@ +""" + +Enumerations +============ + +.. _Ewe_Entry_Regex_Toggles: + +Regex Flags +------------- + +.. data:: EWE_REG_EXTENDED + + Regex check option: Use Extended Regular Expressions. + +.. data:: EWE_REG_ICASE + + Regex check option: Ignore case in match. + + +.. _Ewe_Entry_Regex_Status: + +Regex Status +------------ + +.. data:: EWE_REG_NOERROR + + Regex Success: Regex maches to the Entrys text + +.. data:: EWE_REG_NOMATCH + + Regex Error: regexec() failed to match. + +.. data:: EWE_REG_BADPAT + + Regex Error: Invalid regular expression. + +.. data:: EWE_REG_ECOLLATE + + Regex Error: Invalid collating element referenced. + +.. data:: EWE_REG_ECTYPE + + Regex Error: Invalid character class type referenced. + +.. data:: EWE_REG_EESCAPE + + Regex Error: Trailing \ in pattern. + +.. data:: EWE_REG_ESUBREG + + Regex Error: Wrong back reference. + +.. data:: EWE_REG_EBRACK + + Regex Error: [ ] imbalance. + +.. data:: EWE_REG_EPAREN + + Regex Error: \( \) or ( ) imbalance. + +.. data:: EWE_REG_EBRACE + + Regex Error: \{ \} imbalance. + +.. data:: EWE_REG_BADBR + + Regex Error: Content of \{ \} invalid: not a number, number too large, more than two numbers, first larger than second. + +.. data:: EWE_REG_ERANGE + + Regex Error: Invalid endpoint in range expression. + +.. data:: EWE_REG_ESPACE + + Regex Error: Out of memory. + +.. data:: EWE_REG_BADRPT + + Regex Error: ?, * or + not preceded by valid regular expression. + +""" + +from efl.elementary.entry cimport Entry as elmEntry +from cpython cimport PyUnicode_AsUTF8String +from efl.utils.conversions cimport _ctouni +from efl.evas cimport Object as evasObject + +cimport enums + +EWE_REG_EXTENDED = enums.EWE_REG_EXTENDED +EWE_REG_ICASE = enums.EWE_REG_ICASE + +EWE_REG_NOERROR = enums.EWE_REG_NOERROR +EWE_REG_NOMATCH = enums.EWE_REG_NOMATCH +EWE_REG_BADPAT = enums.EWE_REG_BADPAT +EWE_REG_ECOLLATE = enums.EWE_REG_ECOLLATE +EWE_REG_ECTYPE = enums.EWE_REG_ECTYPE +EWE_REG_EESCAPE = enums.EWE_REG_EESCAPE +EWE_REG_ESUBREG = enums.EWE_REG_ESUBREG +EWE_REG_EBRACK = enums.EWE_REG_EBRACK +EWE_REG_EPAREN = enums.EWE_REG_EPAREN +EWE_REG_EBRACE = enums.EWE_REG_EBRACE +EWE_REG_BADBR = enums.EWE_REG_BADBR +EWE_REG_ERANGE = enums.EWE_REG_ERANGE +EWE_REG_ESPACE = enums.EWE_REG_ESPACE +EWE_REG_BADRPT = enums.EWE_REG_BADRPT + +cdef class Entry(elmEntry): + + def __init__(self, evasObject parent not None, **kwargs): + """This adds an entry to @p parent object. + + By default, entries are: + + - not scrolled + - multi-line + - word wrapped + - autosave is enabled + + :param parent: The parent object + + """ + self._set_obj(ewe_entry_add(parent.obj)) + self._set_properties_from_keyword_args(kwargs) + + def regex_set(self, regex_str not None, int flags): + """Set regular expresion to be compiled and used. + + :param regex_str: The text of regular expresion + :param flags: Compile flags for regex + :type flags: int value from or'ed :ref:`Ewe_Entry_Regex_Toggles` + :return: True on success, otherwise returns False. + + """ + if isinstance(regex_str, unicode): + regex_str = PyUnicode_AsUTF8String(regex_str) + return bool(ewe_entry_regex_set( + self.obj, + regex_str, + flags + )) + + def regex_unset(self): + """Unset previoustly set regular expresion. + + :return: True on success, otherwise returns False. + + """ + return bool(ewe_entry_regex_unset(self.obj)) + + def regex_check(self): + """Check current text of Entry with previoustly set regular expresion. + + :return: True on success, otherwise returns False. + + """ + return bool(ewe_entry_regex_check(self.obj)) + + property regex_glow: + """Set if regex error signals for EDJE should be emitted. + + :type: bool + + """ + def __set__(self, bint glow): + if not ewe_entry_regex_glow_set(self.obj, glow): + raise RuntimeError("glow could not be set") + + def __get__(self): + return bool(ewe_entry_regex_glow_get(self.obj)) + + def regex_error_get(self): + """Returns last regex error + + :return: The last regex error. + + """ + return ewe_entry_regex_error_get(self.obj) + + def regex_error_text_get(self): + """Returns the string that contains last regex error. + This message updates on each regex setting and checking. + The string is deleted on Entry object deleteon. + + :return: The last regex error. If regex is not set yet None would be returned. + + """ + return _ctouni(ewe_entry_regex_error_text_get(self.obj)) + + property regex_autocheck: + """Automatic regex check on "entry,changed". + + Signals will be processed only for focused entry. + + :type: bool + + """ + def __set__(self, bint autocheck): + if not ewe_entry_regex_autocheck_set(self.obj, autocheck): + raise RuntimeError("could not enable autocheck") + + def __get__(self): + return bool(ewe_entry_regex_autocheck_get(self.obj)) + + property entry: + """This sets the text displayed within the entry to @p entry. + + :param entry: The text to be displayed + + .. note:: Using this function bypasses text filters + + """ + def __get__(self): + return elmEntry.entry.__get__(self) + + def __set__(self, text): + if isinstance(text, unicode): text = PyUnicode_AsUTF8String(text) + ewe_entry_entry_set( + self.obj, + text if text is not None else NULL + ) diff --git a/efl/ewe/enums.pxd b/efl/ewe/enums.pxd new file mode 100644 index 0000000..24eef4c --- /dev/null +++ b/efl/ewe/enums.pxd @@ -0,0 +1,35 @@ +cdef extern from "ewe.h": + enum: + EWE_REG_EXTENDED + EWE_REG_ICASE + + enum: + EWE_REG_NOERROR + EWE_REG_NOMATCH + EWE_REG_BADPAT + EWE_REG_ECOLLATE + EWE_REG_ECTYPE + EWE_REG_EESCAPE + EWE_REG_ESUBREG + EWE_REG_EBRACK + EWE_REG_EPAREN + EWE_REG_EBRACE + EWE_REG_BADBR + EWE_REG_ERANGE + EWE_REG_ESPACE + EWE_REG_BADRPT + + ctypedef enum Ewe_Ruler_Orient: + EWE_RULER_ORIENT_WRONG # returned from get func if some error occured + EWE_RULER_ORIENT_HORIZONTAL # Ruler (dis)appears in horizontal mode + EWE_RULER_ORIENT_VERTICAL # Ruler (dis)appears in vertical mode + + ctypedef enum Ewe_Statusbar_Items_Align: + EWE_STATUSBAR_ITEMS_ALIGN_RIGHT + EWE_STATUSBAR_ITEMS_ALIGN_CENTER + EWE_STATUSBAR_ITEMS_ALIGN_LEFT + EWE_STATUSBAR_ITEMS_ALIGN_LAST + + ctypedef enum Ewe_Statusbar_Items_Type: + EWE_STATUSBAR_ITEM_TYPE_OBJECT # item with content + EWE_STATUSBAR_ITEM_TYPE_SEPARATOR # separate item diff --git a/efl/ewe/object_item.pxd b/efl/ewe/object_item.pxd new file mode 100644 index 0000000..f0b5938 --- /dev/null +++ b/efl/ewe/object_item.pxd @@ -0,0 +1,2 @@ +cdef class _ObjectItem(object): + cdef int _set_properties_from_keyword_args(self, dict kwargs) except 0 diff --git a/efl/ewe/object_item.pyx b/efl/ewe/object_item.pyx new file mode 100644 index 0000000..0b0cb5d --- /dev/null +++ b/efl/ewe/object_item.pyx @@ -0,0 +1,9 @@ +cdef class _ObjectItem(object): + cdef int _set_properties_from_keyword_args(self, dict kwargs) except 0: + if not kwargs: + return 1 + cdef list cls_list = dir(self) + for k, v in kwargs.items(): + assert k in cls_list, "%s has no attribute with the name %s." % (self, k) + setattr(self, k, v) + return 1 diff --git a/efl/ewe/ruler.pxd b/efl/ewe/ruler.pxd new file mode 100644 index 0000000..67a91f4 --- /dev/null +++ b/efl/ewe/ruler.pxd @@ -0,0 +1,13 @@ +from efl.c_eo cimport Eo +from efl.eina cimport Eina_Bool +from efl.evas cimport Evas_Object +from enums cimport Ewe_Ruler_Orient + +cdef extern from "ewe.h": + Evas_Object * ewe_ruler_add(Evas_Object *parent) + Eina_Bool ewe_ruler_orient_set(Evas_Object *obj, Ewe_Ruler_Orient orient) + Ewe_Ruler_Orient ewe_ruler_orient_get(const Eo *obj) + Eina_Bool ewe_ruler_step_set(Evas_Object *obj, unsigned int step) + unsigned int ewe_ruler_step_get(const Eo *obj) + Eina_Bool ewe_ruler_zero_offset_set(Evas_Object *obj, int pos) + int ewe_ruler_zero_offset_get(const Eo *obj) diff --git a/efl/ewe/ruler.pyx b/efl/ewe/ruler.pyx new file mode 100644 index 0000000..d630d84 --- /dev/null +++ b/efl/ewe/ruler.pyx @@ -0,0 +1,84 @@ +""" +Enumerations +============ + +.. _Ewe_Ruler_Orient: + +Orientation +----------- + +.. data:: EWE_RULER_ORIENT_WRONG + + returned from get func if some error occured + +.. data:: EWE_RULER_ORIENT_HORIZONTAL + + Ruler (dis)appears in horizontal mode + +.. data:: EWE_RULER_ORIENT_VERTICAL + + Ruler (dis)appears in vertical mode + +""" + +from cpython cimport PyUnicode_AsUTF8String +from efl.utils.conversions cimport _ctouni +from efl.evas cimport Object as evasObject +from efl.elementary.object cimport Object +cimport enums + +EWE_RULER_ORIENT_WRONG = enums.EWE_RULER_ORIENT_WRONG +EWE_RULER_ORIENT_HORIZONTAL = enums.EWE_RULER_ORIENT_HORIZONTAL +EWE_RULER_ORIENT_VERTICAL = enums.EWE_RULER_ORIENT_VERTICAL + + +cdef class Ruler(Object): + def __init__(self, evasObject parent not None, **kwargs): + """Add new ruler to the given parent object + + :param parent: The parent object. + + """ + self._set_obj(ewe_ruler_add(parent.obj)) + self._set_properties_from_keyword_args(kwargs) + + property orient: + """Ruler orientation + + :type: :ref:`Ewe_Ruler_Orient` + + """ + def __set__(self, Ewe_Ruler_Orient orient): + if not ewe_ruler_orient_set(self.obj, orient): + raise RuntimeError("Could not set ruler orientation") + + def __get__(self): + return ewe_ruler_orient_get(self.obj) + + property step: + """Step between marks of the ruler. If step is setting to 0, it would be + setting to 1. + + :type: int + + """ + def __set__(self, unsigned int step): + if not ewe_ruler_step_set(self.obj, step): + raise RuntimeError("Could not set ruler step") + + def __get__(self): + return ewe_ruler_step_get(self.obj) + + property zero_offset: + """Change the ruler's "zero pointer" mark position in pixels relative to + start parent's layout + + :type: int + + """ + def __set__(self, int pos): + if not ewe_ruler_zero_offset_set(self.obj, pos): + raise RuntimeError("Could not set ruler offset") + + def __get__(self): + return ewe_ruler_zero_offset_get(self.obj) diff --git a/efl/ewe/statusbar.pxd b/efl/ewe/statusbar.pxd new file mode 100644 index 0000000..f258166 --- /dev/null +++ b/efl/ewe/statusbar.pxd @@ -0,0 +1,47 @@ +from efl.eina cimport Eina_Bool, Eina_List +from efl.evas cimport Evas_Object, Evas_Smart_Cb +from enums cimport Ewe_Statusbar_Items_Type, Ewe_Statusbar_Items_Align + +cdef extern from "ewe.h": + + ctypedef struct Ewe_Statusbar_Item: + Evas_Object *parent # the pointer to parent statusbar object + Evas_Object *content # the object, which added into item + Evas_Object *markup # the object which load markup from edj file + + Ewe_Statusbar_Items_Type type # item type: separator or item witch content + + Evas_Smart_Cb func # callback function, which call when item clicked + void *cb_data # data, which will be sended into item callback + + + Eina_Bool disabled # the item disabled status: EINA_TRUE - enabled + int id # the item identificator + int width # the item width, if less that 0, then ulimited width will set + + + int ewe_statusbar_item_id_get(Ewe_Statusbar_Item *item) + int ewe_statusbar_item_width_get(Ewe_Statusbar_Item *item) + Eina_Bool ewe_statusbar_item_width_set(Ewe_Statusbar_Item *item, int width) + char * ewe_statusbar_item_label_get(Ewe_Statusbar_Item *item) + Eina_Bool ewe_statusbar_item_label_set(Ewe_Statusbar_Item *item, const char *label) + Evas_Object * ewe_statusbar_item_content_get(Ewe_Statusbar_Item *item) + Eina_Bool ewe_statusbar_item_content_set(Ewe_Statusbar_Item *item, Evas_Object *content) + Evas_Object * ewe_statusbar_item_content_unset(Ewe_Statusbar_Item *item) + Evas_Object * ewe_statusbar_item_statusbar_get(Ewe_Statusbar_Item *item) + + + Evas_Object * ewe_statusbar_add(Evas_Object *parent) + Eina_Bool ewe_statusbar_clear(Evas_Object *obj) + Ewe_Statusbar_Item * ewe_statusbar_item_append(Evas_Object *obj, Evas_Object *content, Ewe_Statusbar_Items_Type type, Evas_Smart_Cb func, void *func_data) + Ewe_Statusbar_Item * ewe_statusbar_item_prepend(Evas_Object *obj, Evas_Object *content, Ewe_Statusbar_Items_Type type, Evas_Smart_Cb func, void *func_data) + Eina_Bool ewe_statusbar_item_insert_before(Evas_Object *obj, Ewe_Statusbar_Item *item, Ewe_Statusbar_Item *before) + Eina_Bool ewe_statusbar_item_insert_after(Evas_Object *obj, Ewe_Statusbar_Item *item, Ewe_Statusbar_Item *after) + Eina_Bool ewe_statusbar_items_swap(Evas_Object *obj, Ewe_Statusbar_Item *item_first, Ewe_Statusbar_Item *item_second) + const Eina_List * ewe_statusbar_items_list_get(Evas_Object *obj) + void ewe_statusbar_items_padding_set(Evas_Object *obj, int padding) + int ewe_statusbar_items_padding_get(const Evas_Object *obj) + void ewe_statusbar_items_align_set(Evas_Object *obj, Ewe_Statusbar_Items_Align align) + Ewe_Statusbar_Items_Align ewe_statusbar_items_align_get(const Evas_Object *obj) + Eina_Bool ewe_statusbar_item_remove(Evas_Object *obj, Ewe_Statusbar_Item *item) + diff --git a/efl/ewe/statusbar.pyx b/efl/ewe/statusbar.pyx new file mode 100644 index 0000000..c0d0a21 --- /dev/null +++ b/efl/ewe/statusbar.pyx @@ -0,0 +1,394 @@ + +""" + +Enumerations +============ + + +.. _Ewe_Statusbar_Items_Align: + +Item alignment +-------------- + +Defines items align into statusbar + +.. data:: EWE_STATUSBAR_ITEMS_ALIGN_RIGHT +.. data:: EWE_STATUSBAR_ITEMS_ALIGN_CENTER +.. data:: EWE_STATUSBAR_ITEMS_ALIGN_LEFT + + +.. _Ewe_Statusbar_Items_Type: + +Item types +---------- + +Defines statusbar item types. + +.. data:: EWE_STATUSBAR_ITEM_TYPE_OBJECT + + item with content + +.. data:: EWE_STATUSBAR_ITEM_TYPE_SEPARATOR + + separator item + +""" + +from cpython cimport PyUnicode_AsUTF8String, Py_INCREF, Py_DECREF + +from efl.eo cimport object_from_instance +from efl.utils.conversions cimport _touni +from efl.evas cimport Object as evasObject +from efl.elementary.object cimport Object +from efl.ewe.object_item cimport _ObjectItem +cimport enums + +import traceback + +EWE_STATUSBAR_ITEMS_ALIGN_RIGHT = enums.EWE_STATUSBAR_ITEMS_ALIGN_RIGHT +EWE_STATUSBAR_ITEMS_ALIGN_CENTER = enums.EWE_STATUSBAR_ITEMS_ALIGN_CENTER +EWE_STATUSBAR_ITEMS_ALIGN_LEFT = enums.EWE_STATUSBAR_ITEMS_ALIGN_LEFT +EWE_STATUSBAR_ITEMS_ALIGN_LAST = enums.EWE_STATUSBAR_ITEMS_ALIGN_LAST + +EWE_STATUSBAR_ITEM_TYPE_OBJECT = enums.EWE_STATUSBAR_ITEM_TYPE_OBJECT +EWE_STATUSBAR_ITEM_TYPE_SEPARATOR = enums.EWE_STATUSBAR_ITEM_TYPE_SEPARATOR + +cdef void _py_ewe_statusbar_item_cb(void *data, Evas_Object *obj, void *event_info) with gil: + cdef StatusbarItem item = data + try: + o = object_from_instance(obj) + item.cb(o, item, item.cb_data) + except Exception: + traceback.print_exc() + +cdef _statusbar_item_to_python(Ewe_Statusbar_Item *it): + cdef: + void *data + StatusbarItem item + + if it == NULL: + return None + + data = it.cb_data + + if data == NULL: + # Create a dummy statusbar item. + item = StatusbarItem.__new__(StatusbarItem) + item._set_obj(it) + else: + item = data + + return item + +cdef _statusbar_item_list_to_python(const Eina_List *lst): + cdef Ewe_Statusbar_Item *it + ret = [] + while lst: + it = lst.data + lst = lst.next + o = _statusbar_item_to_python(it) + if o is not None: + ret.append(o) + return ret + +cdef class StatusbarItem(_ObjectItem): + + cdef: + object cb + object cb_data + Ewe_Statusbar_Item *item + + cdef int _set_obj(self, Ewe_Statusbar_Item *item) except 0: + assert self.item == NULL, "Object must be clean" + self.item = item + Py_INCREF(self) + return 1 + + cdef int _unset_obj(self) except 0: + assert self.item != NULL, "Object already deleted" + self.item = NULL + Py_DECREF(self) + return 1 + + def __init__(self, *args, **kwargs): + self.append(*args, **kwargs) + + @classmethod + def append(cls, + Statusbar statusbar not None, evasObject content=None, + Ewe_Statusbar_Items_Type type=enums.EWE_STATUSBAR_ITEM_TYPE_OBJECT, + cb=None, cb_data=None, **kwargs): + """Append a new item in a given statusbar widget. + + :param content: The object, which will be set into statusbar item as + content. Can be None, if planned set content with + :py:attr:`StatusbarItem.content`. + :param type: Item type. + :param func: Convenience function called when the item is clicked. + :param func_data: Data passed to func above. + + :return: A handle to the item added or NULL if not possible + + This adds the new item to the end of the list childrens in statusbar widget. + + """ + cdef: + void *func_data + StatusbarItem self + + self = cls.__new__(cls) + + if cb: + if not callable(cb): + raise TypeError("cb must be callable") + else: + self.cb = cb + self.cb_data = cb_data + + self._set_obj(ewe_statusbar_item_append( + statusbar.obj, content.obj, type, + _py_ewe_statusbar_item_cb if cb is not None else NULL, + self + )) + + self._set_properties_from_keyword_args(kwargs) + + return self + + @classmethod + def prepend(cls, + Statusbar statusbar not None, evasObject content=None, + Ewe_Statusbar_Items_Type type=enums.EWE_STATUSBAR_ITEM_TYPE_OBJECT, + cb=None, cb_data=None, **kwargs): + """Prepend a new item in a given statusbar widget. + + :param content: The object, which will be set into statusbar item as + content. Can be None, if planned set content with + :py:attr:`StatusbarItem.content`. + :param type: Item type. + :param func: Convenience function called when the item is clicked. + :param func_data: Data passed to func above. + + :return: A handle to the item added or None if not possible + + This adds the new item to the beginnig of the list childrens in statusbar widget. + + """ + cdef: + void *func_data + StatusbarItem self + + self = cls.__new__(cls) + + if cb: + if not callable(cb): + raise TypeError("cb must be callable") + else: + self.cb = cb + self.cb_data = cb_data + + self._set_properties_from_keyword_args(kwargs) + + self._set_obj(ewe_statusbar_item_prepend( + statusbar.obj, content.obj, type, + _py_ewe_statusbar_item_cb if cb is not None else NULL, + self + )) + + return self + + def insert_before(self, StatusbarItem before not None): + """Insert this item before another in a given statusbar widget. + + :param before: The item to place this one before. + + :return: True if item inserted sucessful, or Flase in otherwise. + + """ + return bool(ewe_statusbar_item_insert_before( + ewe_statusbar_item_statusbar_get(self.item), + before.item, + self.item + )) + + def insert_after(self, StatusbarItem after not None): + """Insert a existent item after another in a given statusbar widget. + + :param after: The item to place this one before. + + :return: True if item inserted sucessful, or False in otherwise. + + """ + return bool(ewe_statusbar_item_insert_after( + ewe_statusbar_item_statusbar_get(self.item), + after.item, + self.item + )) + + def items_swap(self, StatusbarItem item_second not None): + """Swap statusbar items positions into statusbar widgets. + + :param item_first: The item, which will be swapped. + :param item_second: The item, which will be swapped. + + :return: True if swap is sucessful, or False in otherwise. + + """ + return bool(ewe_statusbar_items_swap( + ewe_statusbar_item_statusbar_get(self.item), + self.item, + item_second.item + )) + + property index: + """Get the index of the statusbar item. + + :type: int + + """ + def __get__(self): + return ewe_statusbar_item_id_get(self.item) + + property width: + """The width of the statusbar item. + + A width, which will be set as fixed for statusbar item. If + param equal -1, then width of statusbar item will be unlimited. + + :type: int + + """ + def __get__(self): + return ewe_statusbar_item_width_get(self.item) + + def __set__(self, int width): + if not ewe_statusbar_item_width_set(self.item, width): + raise RuntimeError("Width could not be set") + + property label: + """Item label. + + :type: string + + """ + def __get__(self): + return _touni(ewe_statusbar_item_label_get(self.item)) + + def __set__(self, label): + if isinstance(label, unicode): + label = PyUnicode_AsUTF8String(label) + + if not ewe_statusbar_item_label_set( + self.item, + label if label is not None else NULL + ): + raise RuntimeError("Could not set item label") + + property content: + """Get the object, which stored into statusbar item. + + :type: :py:class:`efl.evas.Object` + + """ + def __get__(self): + return object_from_instance( + ewe_statusbar_item_content_get(self.item) + ) + + def __set__(self, evasObject content): + if not ewe_statusbar_item_content_set(self.item, content.obj): + raise RuntimeError("Content could not be set") + + def __del__(self): + ewe_statusbar_item_content_unset(self.item) + + property statusbar: + """Get the statusbar object from statusbar item. + + :type: :py:class:`Statusbar` + + """ + def __get__(self): + return object_from_instance( + ewe_statusbar_item_statusbar_get(self.item) + ) + + def delete(self): + """Remove item from statusbar widget. + + :return: True if item removed sucessful, or False in otherwise. + + """ + cdef bint ret + ret = ewe_statusbar_item_remove( + ewe_statusbar_item_statusbar_get(self.item), + self.item + ) + self._unset_obj() + return ret + + +cdef class Statusbar(Object): + def __init__(self, evasObject parent not None, **kwargs): + """Add a new statusbar widget to the given parent object. + + :param parent: The parent object + + """ + self._set_obj(ewe_statusbar_add(parent.obj)) + self._set_properties_from_keyword_args(kwargs) + + def clear(self): + """Remove all items from a given statusbar widget. + + :return: True if items clear sucessful, or False in otherwise. + + This removes (and deletes) all items in given statusbar, leaving it + empty. + + """ + return bool(ewe_statusbar_clear(self.obj)) + + property items: + """Retrieve a list of the items, which exist into the statusbar. + + :return: a new Eina_List with a pointer to Ewe_Statusbar_Item in its + nodes, or None on errors. + + """ + def __get__(self): + return _statusbar_item_list_to_python( + ewe_statusbar_items_list_get(self.obj) + ) + + property padding: + """Set the padding between the statusbar items. + + :type: int + + Extra space in pixels that will be added between a statusbar items. + This padding is set for all items in the statusbar widget. + + """ + def __set__(self, int padding): + ewe_statusbar_items_padding_set(self.obj, padding) + + def __get__(self): + return ewe_statusbar_items_padding_get(self.obj) + + property align: + """Alignment of the whole bounding statusbar of items. + + :type: :ref:`Ewe_Statusbar_Items_Align` + + How the bounding box containing all the items of the statusbar, after + their sizes and position has been calculated, will be aligned within + the space given for the whole statusbar widget. + + """ + def __set__(self, Ewe_Statusbar_Items_Align align): + ewe_statusbar_items_align_set(self.obj, align) + + def __get__(self): + return ewe_statusbar_items_align_get(self.obj) + diff --git a/efl/ewe/tabs.pxd b/efl/ewe/tabs.pxd new file mode 100644 index 0000000..47455ac --- /dev/null +++ b/efl/ewe/tabs.pxd @@ -0,0 +1,32 @@ +from efl.eina cimport Eina_Bool, Eina_List, Eina_Stringshare +from efl.evas cimport Evas_Object, Evas_Smart_Cb +from enums cimport Ewe_Statusbar_Items_Type, Ewe_Statusbar_Items_Align + + +cdef extern from "ewe.h": + ctypedef struct Ewe_Tabs_Item: + Evas_Object *owner + Evas_Object *head + Evas_Object *content + Eina_Stringshare *title + Eina_Stringshare *style + Eina_Bool disabled + + Evas_Object * ewe_tabs_add(Evas_Object *parent) + Ewe_Tabs_Item * ewe_tabs_item_append(Evas_Object *obj, Ewe_Tabs_Item *item, Eina_Stringshare *title, Eina_Stringshare *style) + Ewe_Tabs_Item * ewe_tabs_item_prepend(Evas_Object *obj, Ewe_Tabs_Item *item, Eina_Stringshare *title, Eina_Stringshare *style) + Eina_Bool ewe_tabs_item_del(Evas_Object *obj, Ewe_Tabs_Item *item) + const Eina_List * ewe_tabs_items_list_get(const Evas_Object *obj) + Eina_Bool ewe_tabs_item_content_set(Evas_Object *obj, Ewe_Tabs_Item *item, Evas_Object *content) + Evas_Object * ewe_tabs_item_content_unset(Evas_Object *obj, Ewe_Tabs_Item *item) + const Evas_Object * ewe_tabs_item_content_get(Evas_Object *obj, Ewe_Tabs_Item *item) + Eina_Bool ewe_tabs_item_icon_set(Evas_Object *obj, Ewe_Tabs_Item *item, Evas_Object *icon) + Evas_Object * ewe_tabs_item_icon_unset(Evas_Object *obj, Ewe_Tabs_Item *item) + Eina_Bool ewe_tabs_item_button_set(Evas_Object *obj, Ewe_Tabs_Item *item, Evas_Object *button) + Evas_Object * ewe_tabs_item_button_unset(Evas_Object *obj, Ewe_Tabs_Item *item) + Eina_Bool ewe_tabs_active_item_set(Evas_Object *obj, Ewe_Tabs_Item *item) + Ewe_Tabs_Item * ewe_tabs_active_item_get(const Evas_Object *obj) + Eina_Bool ewe_tabs_item_title_set(Evas_Object *obj, Ewe_Tabs_Item *item, Eina_Stringshare *title) + Eina_Stringshare * ewe_tabs_item_title_get(const Evas_Object *obj, Ewe_Tabs_Item *item) + Eina_Bool ewe_tabs_item_disabled_set(Evas_Object *obj, Ewe_Tabs_Item *item, Eina_Bool disabled) + Eina_Bool ewe_tabs_item_disabled_get(const Evas_Object *obj, Ewe_Tabs_Item *item) diff --git a/efl/ewe/tabs.pyx b/efl/ewe/tabs.pyx new file mode 100644 index 0000000..207f77a --- /dev/null +++ b/efl/ewe/tabs.pyx @@ -0,0 +1,278 @@ +from libc.stdint cimport uintptr_t +from cpython cimport PyUnicode_AsUTF8String, Py_INCREF, Py_DECREF + +from efl.eo cimport object_from_instance +from efl.utils.conversions cimport _ctouni +from efl.evas cimport Object as evasObject +from efl.elementary.object cimport Object +from efl.ewe.object_item cimport _ObjectItem +cimport enums + +import traceback + + +def _cb_tabs_item_conv(uintptr_t addr): + cdef TabsItem it = TabsItem.__new__(TabsItem) + it.item = addr + return it + +cdef _tabs_item_to_python(Ewe_Tabs_Item *it): + cdef: + TabsItem item + + if it == NULL: + return None + + # Create a dummy tabs item. + item = TabsItem.__new__(TabsItem) + item._set_obj(it) + + return item + +cdef _tabs_item_list_to_python(const Eina_List *lst): + cdef Ewe_Tabs_Item *it + ret = [] + while lst: + it = lst.data + lst = lst.next + o = _tabs_item_to_python(it) + if o is not None: + ret.append(o) + return ret + + +cdef class TabsItem(_ObjectItem): + cdef: + Ewe_Tabs_Item *item + + cdef int _set_obj(self, Ewe_Tabs_Item *item) except 0: + assert self.item == NULL, "Object must be clean" + self.item = item + Py_INCREF(self) + return 1 + + def __richcmp__(TabsItem self, TabsItem y, op): + if op == 2: + return self.item == y.item + elif op == 3: + return self.item != y.item + else: + return NotImplemented + + def __init__(self, *args, **kwargs): + self.append(*args, **kwargs) + + @classmethod + def append(cls, + Tabs tabs not None, TabsItem after=None, + title=None, style=None, **kwargs + ): + """This adds an item after specified item. + If no item specified adds as last. + + :param item: The tabs item + :param title: The tabs title + :param style: The tabs style + :return: The new tabs item object or NULL if it cannot be created + + """ + cdef: + void *func_data + TabsItem self + + self = cls.__new__(cls) + + if isinstance(title, unicode): title = PyUnicode_AsUTF8String(title) + if isinstance(style, unicode): style = PyUnicode_AsUTF8String(style) + + self._set_obj(ewe_tabs_item_append( + tabs.obj, + after.item if after is not None else NULL, + title if title is not None else NULL, + style if style is not None else NULL + )) + + self._set_properties_from_keyword_args(kwargs) + + return self + + @classmethod + def prepend(cls, + Tabs tabs not None, TabsItem before=None, + title=None, style=None, **kwargs + ): + """This adds an item before specified item. + If no item specified adds as first. + + :param item: The tabs item + :param title: The tabs title + :param style: The tabs style + :return: The new tabs item object or NULL if it cannot be created + + """ + cdef: + void *func_data + TabsItem self + + self = cls.__new__(cls) + + if isinstance(title, unicode): title = PyUnicode_AsUTF8String(title) + if isinstance(style, unicode): style = PyUnicode_AsUTF8String(style) + + self._set_obj(ewe_tabs_item_prepend( + tabs.obj, + before.item if before is not None else NULL, + title if title is not None else NULL, + style if style is not None else NULL + )) + + self._set_properties_from_keyword_args(kwargs) + + return self + + def delete(self): + """Delete tabs item. + + :param item: The tabs item + :return: EINA_TRUE on success, EINA_FALSE otherwise + + """ + return bool(ewe_tabs_item_del(self.item.owner, self.item)) + + property content: + """Content of tabs item + + :type: :py:class:`efl.evas.Object` + + """ + def __set__(self, evasObject content): + if not ewe_tabs_item_content_set( + self.item.owner, self.item, content.obj + ): + raise RuntimeError + + def __del__(self): + ewe_tabs_item_content_unset(self.item.owner, self.item) + + def __get__(self): + return object_from_instance(ewe_tabs_item_content_get( + self.item.owner, self.item + )) + + + property icon: + """Icon of tabs item + + :type: :py:class:`efl.evas.Object` + + """ + def __set__(self, evasObject icon not None): + if not ewe_tabs_item_icon_set(self.item.owner, self.item, icon.obj): + raise RuntimeError + + def __del__(self): + ewe_tabs_item_icon_unset(self.item.owner, self.item) + + property button: + """Button of tabs item. + + :type: :py:class:`efl.evas.Object` + + """ + def __set__(self, evasObject button not None): + if not ewe_tabs_item_button_set(self.item.owner, self.item, button.obj): + raise RuntimeError + + def __del__(self): + ewe_tabs_item_button_unset(self.item.owner, self.item) + + def activate(self): + """This activates tabs item. + + :param item: The tabs item + :return: EINA_TRUE on success, EINA_FALSE otherwise + + """ + return bool(ewe_tabs_active_item_set(self.item.owner, self.item)) + + property title: + """Title of the tabs item. + + :type: string + + """ + def __set__(self, title): + if isinstance(title, unicode): + title = PyUnicode_AsUTF8String(title) + if not ewe_tabs_item_title_set( + self.item.owner, self.item, title + ): + raise RuntimeError + + def __get__(self): + return _ctouni(ewe_tabs_item_title_get(self.item.owner, self.item)) + + property disabled: + """This enables or disables tabs item. + + Notes: user cannot switch to disabled tabs item. + If it is active allready or is activated from code + items content will be also rendered disabled. + + :param item: The tabs item + :param disabled: EINA_TRUE to disable, EINA_FALSE to enable tabs item + :return: EINA_TRUE on success, EINA_FALSE otherwise + + """ + def __set__(self, bint disabled): + if not ewe_tabs_item_disabled_set(self.item.owner, self.item, disabled): + raise RuntimeError + + def __get__(self): + return bool(ewe_tabs_item_disabled_get(self.item.owner, self.item)) + +cdef class Tabs(Object): + def __init__(self, evasObject parent not None, **kwargs): + """This adds tabs to @p parent object. + + :param parent: The parent object + :return: The new object or NULL if it cannot be created + + """ + self._set_obj(ewe_tabs_add(parent.obj)) + self._set_properties_from_keyword_args(kwargs) + + property items: + """Get internal items list. + + :param obj: The tabs object + :return: list of items on success, NULL otherwise + + """ + def __get__(self): + return _tabs_item_list_to_python(ewe_tabs_items_list_get(self.obj)) + + property active_item: + """Get active item item. + + :return: Ewe_Tabs_Item* on success, NULL otherwise + + """ + def __get__(self): + return _tabs_item_to_python(ewe_tabs_active_item_get(self.obj)) + + def callback_item_activated_add(self, func, *args, **kwargs): + self._callback_add_full("ewe,tabs,item,activated", _cb_tabs_item_conv, + func, *args, **kwargs) + + def callback_item_activated_del(self, func): + self._callback_del_full("ewe,tabs,item,activated", _cb_tabs_item_conv, + func) + + def callback_item_deactivated_add(self, func, *args, **kwargs): + self._callback_add_full("ewe,tabs,item,deactivated", _cb_tabs_item_conv, + func, *args, **kwargs) + + def callback_item_deactivated_del(self, func): + self._callback_del_full("ewe,tabs,item,deactivated", _cb_tabs_item_conv, + func) diff --git a/examples/ewe/ruler_example.edc b/examples/ewe/ruler_example.edc new file mode 100644 index 0000000..02df06d --- /dev/null +++ b/examples/ewe/ruler_example.edc @@ -0,0 +1,26 @@ +collections { + group { name: "view"; + parts { + part { name: "ruler_hor"; + type: SWALLOW; + description { + state: "default 0.0"; + align: 0.5 0.0; + max: -1 60; + rel1.offset: 80 20; + rel2.offset: -20 -20; + } + } + part { name: "ruler_ver"; + type: SWALLOW; + description { + state: "default 0.0"; + align: 0.0 0.5; + max: 60 -1; + rel1.offset: 20 80; + rel2.offset: 20 -20; + } + } + } + } +} diff --git a/examples/ewe/ruler_example.edj b/examples/ewe/ruler_example.edj new file mode 100644 index 0000000..bd0f7de Binary files /dev/null and b/examples/ewe/ruler_example.edj differ diff --git a/examples/ewe/statusbar.edc b/examples/ewe/statusbar.edc new file mode 100644 index 0000000..b39ed54 --- /dev/null +++ b/examples/ewe/statusbar.edc @@ -0,0 +1,53 @@ +collections { + group { name: "window"; + parts { + part { name: "background"; + type: RECT; + description { state: "default" 0.0; + color: 64 64 64 255; + } + } + part { name: "ewe.swallow.content"; + type: SWALLOW; + description { state: "default" 0.0; + rel2 { + relative: 1 0; + offset: -1 -2; + to: "ewe.swallow.statusbar"; + } + } + } + part { name: "ewe.swallow.statusbar"; + type: SWALLOW; + description { state: "default" 0.0; + align: 0 1; + min: 0 29; + max: -1 29; + rel2 { + offset: 0 0; + } + } + } + part { name: "bevel"; + type: RECT; + description { state: "default" 0.0; + align: 0.5 1; + min: 0 2; + max: -1 2; + fixed: 1 1; + color: 255 90 0 255; + rel1 { + to_y: "ewe.swallow.statusbar"; + } + rel2 { + relative: 1 0; + offset: 0 0; + to_y: "ewe.swallow.statusbar"; + } + } + } + } + } +} + + diff --git a/examples/ewe/statusbar.edj b/examples/ewe/statusbar.edj new file mode 100644 index 0000000..747d81e Binary files /dev/null and b/examples/ewe/statusbar.edj differ diff --git a/examples/ewe/test.py b/examples/ewe/test.py new file mode 100755 index 0000000..3284c14 --- /dev/null +++ b/examples/ewe/test.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python +# encoding: utf-8 + +import logging +elog = logging.getLogger("efl") +elog.setLevel(logging.INFO) + +elog_form = logging.Formatter( + "[%(name)s] %(levelname)s in %(funcName)s:%(lineno)d - %(message)s" + ) +elog_hdlr = logging.StreamHandler() +elog_hdlr.setFormatter(elog_form) + +elog.addHandler(elog_hdlr) + +eolog = logging.getLogger("efl.eo") +eolog.setLevel(logging.INFO) + +evaslog = logging.getLogger("efl.evas") +evaslog.setLevel(logging.INFO) + +from efl.evas import EVAS_HINT_EXPAND, EVAS_HINT_FILL +from efl import elementary +from efl.elementary.window import StandardWindow +from efl.elementary.box import Box, ELM_BOX_LAYOUT_FLOW_HORIZONTAL +from efl.elementary.button import Button +from efl.elementary.frame import Frame +from efl.elementary.label import Label +from efl.elementary.check import Check +from efl.elementary.entry import Entry +from efl.elementary.scroller import Scroller + +from efl.elementary.configuration import Configuration +elm_conf = Configuration() + +elog.setLevel(logging.DEBUG) + +EXPAND_BOTH = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND +FILL_BOTH = EVAS_HINT_FILL, EVAS_HINT_FILL + +items = [ + ("Combobox", [ + ("Combobox", "test_combobox", "combobox_clicked"), + ]), + ("Entry", [ + ("Entry", "test_entry", "entry_clicked"), + ]), + ("Ruler", [ + ("Ruler", "test_ruler", "ruler_clicked"), + ]), + ("Statusbar", [ + ("Statusbar", "test_statusbar", "statusbar_clicked"), + ]), + ("Tabs", [ + ("Tabs", "test_tabs", "tabs_clicked"), + ]) + ] + + +def selected_cb(o, mod, func): + exec("from {0} import {1}; {1}(o)".format(mod, func)) + + +def menu_create(search, win): + tbx.clear() + for category in items: + frame = Frame(win, size_hint_weight=EXPAND_BOTH, + size_hint_align=FILL_BOTH, text=category[0]) + frame.show() + tbx.pack_end(frame) + + tbx2 = Box(win, layout=ELM_BOX_LAYOUT_FLOW_HORIZONTAL, + size_hint_weight=(EVAS_HINT_EXPAND, 0.0), + size_hint_align=(EVAS_HINT_FILL, 0.0)) + frame.content_set(tbx2) + tbx2.show() + + cnt = 0 + for test in category[1]: + if search is None or test[0].lower().find(search.lower()) > -1: + bt = Button(win, text=test[0]) + bt.callback_clicked_add(selected_cb, test[1], test[2]) + bt.show() + tbx2.pack_end(bt) + cnt += 1 + + if cnt < 1: + frame.delete() + + +def destroy(obj, str1, str2, str3, str4): + elementary.exit() + + +def cb_mirroring(toggle): + elm_conf.mirrored = toggle.state + + +def cb_filter(en, win): + menu_create(en.text_get(), win) + +if __name__ == "__main__": + elementary.init() + win = StandardWindow("test", "Python EFL test application") + win.callback_delete_request_add(destroy, "test1", "test2", + str3="test3", str4="test4") + + box0 = Box(win, size_hint_weight=EXPAND_BOTH) + win.resize_object_add(box0) + box0.show() + + lb = Label(win) + lb.text = ("Please select a test from the list below by clicking
" + "the test button to show the test window.") + lb.show() + + fr = Frame(win, text="Information", content=lb) + box0.pack_end(fr) + fr.show() + + tg = Check(win, style="toggle", text="UI-Mirroring:") + tg.callback_changed_add(cb_mirroring) + box0.pack_end(tg) + tg.show() + + bx1 = Box(win, size_hint_weight=(EVAS_HINT_EXPAND, 0.0), + size_hint_align=(EVAS_HINT_FILL, 0.0), horizontal=True) + box0.pack_end(bx1) + bx1.show() + + lb = Label(win, text="Filter:") + bx1.pack_end(lb) + lb.show() + + en = Entry(win, single_line=True, scrollable=True, + size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) + en.part_text_set("guide", "Type widget name here to search.") + en.callback_changed_add(cb_filter, win) + bx1.pack_end(en) + en.show() + en.focus_set(True) + + sc = Scroller(win, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH, + bounce=(False, True)) + sc.show() + box0.pack_end(sc) + + tbx = Box(win, size_hint_weight=(EVAS_HINT_EXPAND, 0.0), + size_hint_align=(EVAS_HINT_FILL, 0.0)) + sc.content_set(tbx) + tbx.show() + + menu_create(None, win) + + win.resize(480, 480) + win.show() + elementary.run() + elementary.shutdown() diff --git a/examples/ewe/test_combobox.py b/examples/ewe/test_combobox.py new file mode 100644 index 0000000..ed11132 --- /dev/null +++ b/examples/ewe/test_combobox.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# encoding: utf-8 + +from efl.evas import EVAS_HINT_EXPAND, EVAS_HINT_FILL +from efl import elementary +from efl import ewe +from efl.ewe.combobox import Combobox, ComboboxItem +from efl.elementary.box import Box +from efl.elementary.window import StandardWindow + +EXPAND_BOTH = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND +EXPAND_HORIZ = EVAS_HINT_EXPAND, 0.0 +FILL_BOTH = EVAS_HINT_FILL, EVAS_HINT_FILL +FILL_HORIZ = EVAS_HINT_FILL, 0.5 + + +def collapsed(obj): + print("collapsed") + + +def expanded(obj): + print("expanded") + + +def selected(obj, item): + print(item) + + +def combobox_clicked(obj): + win = StandardWindow( + "combobox", "Combobox", autodel=True, + size=(320, 200) + ) + if obj is None: + win.callback_delete_request_add(lambda o: elementary.exit()) + + bx = Box(win, size_hint_weight=EXPAND_BOTH) + win.resize_object_add(bx) + bx.show() + + cb = Combobox( + win, size_hint_weight=EXPAND_BOTH, + size_hint_align=FILL_BOTH, + ) + + cb.callback_collapsed_add(collapsed) + cb.callback_expanded_add(expanded) + cb.callback_selected_add(selected) + + for i in range(5): + ComboboxItem(cb, str(i)) + + bx.pack_end(cb) + cb.show() + + win.show() + +if __name__ == "__main__": + ewe.init() + + combobox_clicked(None) + + elementary.run() + ewe.shutdown() diff --git a/examples/ewe/test_entry.py b/examples/ewe/test_entry.py new file mode 100644 index 0000000..70bec1e --- /dev/null +++ b/examples/ewe/test_entry.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# encoding: utf-8 + +from efl.evas import EVAS_HINT_EXPAND, EVAS_HINT_FILL +from efl import elementary +from efl import ewe +from efl.elementary.box import Box +from efl.elementary.label import Label +from efl.elementary.window import StandardWindow +from efl.ewe.entry import Entry + +EXPAND_BOTH = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND +EXPAND_HORIZ = EVAS_HINT_EXPAND, 0.0 +FILL_BOTH = EVAS_HINT_FILL, EVAS_HINT_FILL +FILL_HORIZ = EVAS_HINT_FILL, 0.5 + + +def on_changed(obj, entry2, entry3): + entry = entry2.entry + if entry and entry2.regex_set(entry, 0): + entry3.regex_set(entry, 0) + entry3.editable = True + entry3.regex_autocheck = True + entry3.regex_check() + entry3.regex_glow = True + else: + print("Error Message: %s" % entry2.regex_error_text_get()) + entry3.regex_unset() + entry3.editable = False + entry3.regex_autocheck = False + entry3.entry = "" + entry3.regex_glow = False + + +def entry_clicked(obj): + win = StandardWindow( + "entry", "Entry", autodel=True, + size=(400, 400) + ) + if obj is None: + win.callback_delete_request_add(lambda o: elementary.exit()) + + box = Box(win, size_hint_weight=EXPAND_BOTH) + win.resize_object_add(box) + + # Entry to enter regex + ebox = Box(box, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) + + entry2 = Entry( + box, scrollable=True, single_line=True, + size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH + ) + + entry2.show() + + label = Label(box, text="Enter regex:") + label.show() + + ebox.pack_end(label) + ebox.pack_end(entry2) + ebox.show() + box.pack_end(ebox) + + # Entry to check regex + ebox = Box(box, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) + + entry3 = Entry( + ebox, scrollable=True, single_line=True, editable=False, + size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH + ) + entry3.show() + + label = Label(box, text="Check regex:") + label.show() + + ebox.pack_end(label) + ebox.pack_end(entry3) + + ebox.show() + box.pack_end(ebox) + + entry2.callback_changed_add(on_changed, entry2, entry3) + + box.show() + win.show() + + +if __name__ == "__main__": + ewe.init() + + entry_clicked(None) + + elementary.run() + ewe.shutdown() diff --git a/examples/ewe/test_ruler.py b/examples/ewe/test_ruler.py new file mode 100644 index 0000000..7d29f57 --- /dev/null +++ b/examples/ewe/test_ruler.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# encoding: utf-8 + +from efl.evas import EVAS_HINT_EXPAND, EVAS_HINT_FILL +from efl import elementary +from efl import ewe +from efl.ewe.ruler import Ruler, EWE_RULER_ORIENT_VERTICAL +from efl.elementary.layout import Layout +from efl.elementary.spinner import Spinner +from efl.elementary.window import StandardWindow + +EXPAND_BOTH = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND +EXPAND_HORIZ = EVAS_HINT_EXPAND, 0.0 +FILL_BOTH = EVAS_HINT_FILL, EVAS_HINT_FILL +FILL_HORIZ = EVAS_HINT_FILL, 0.5 + + +RULER_HOR = "ruler_hor" +RULER_VER = "ruler_ver" + + +def offset_cb(obj): + val = obj.value + obj.data[RULER_HOR].zero_offset = val + obj.data[RULER_VER].zero_offset = val + print("Zero offset changed to %d" % val) + + +def step_cb(obj): + val = obj.value + obj.data[RULER_HOR].step = val + obj.data[RULER_VER].step = val + print("Step between marks of the ruler has changed to %d" % val) + + +def ruler_clicked(obj): + win = StandardWindow( + "ruler", "Ruler", autodel=True, + size=(740, 740) + ) + if obj is None: + win.callback_delete_request_add(lambda o: elementary.exit()) + + step = 100 + + layout = Layout(win, size_hint_weight=EXPAND_BOTH) + win.resize_object_add(layout) + layout.file_set("ruler_example.edj", "view") + layout.show() + + ruler_hor = Ruler(win) + layout.content_set("ruler_hor", ruler_hor) + ruler_hor.step = step + ruler_hor.show() + + layout = Layout(win, size_hint_weight=EXPAND_BOTH) + win.resize_object_add(layout) + layout.file_set("ruler_example.edj", "view") + layout.show() + + ruler_ver = Ruler(win) + layout.content_set("ruler_ver", ruler_ver) + ruler_ver.orient = EWE_RULER_ORIENT_VERTICAL + ruler_ver.step = step + ruler_ver.show() + + spinner1 = Spinner( + win, step=10, min_max=(-10000.0, 10000.0), editable=True, + size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_HORIZ, + geometry=(350, 350, 210, 25) + ) + spinner1.label_format = "Zero offset is %1.0f" + spinner1.show() + spinner1.data[RULER_HOR] = ruler_hor + spinner1.data[RULER_VER] = ruler_ver + spinner1.callback_changed_add(offset_cb) + + spinner2 = Spinner( + win, step=5, min_max=(0, 1000.0), value=100, editable=True, + size_hint_align=FILL_HORIZ, size_hint_weight=EXPAND_BOTH, + geometry=(350, 390, 210, 25) + ) + spinner2.label_format = "Step between marks is %1.0f" + spinner2.show() + spinner2.data[RULER_HOR] = ruler_hor + spinner2.data[RULER_VER] = ruler_ver + spinner2.callback_changed_add(step_cb) + + win.show() + +if __name__ == "__main__": + ewe.init() + + ruler_clicked(None) + + elementary.run() + ewe.shutdown() diff --git a/examples/ewe/test_statusbar.py b/examples/ewe/test_statusbar.py new file mode 100644 index 0000000..c315e2d --- /dev/null +++ b/examples/ewe/test_statusbar.py @@ -0,0 +1,184 @@ +#!/usr/bin/env python +# encoding: utf-8 + +from efl.evas import EVAS_HINT_EXPAND, EVAS_HINT_FILL +from efl import elementary +from efl import ewe +from efl.ewe.statusbar import Statusbar, StatusbarItem, \ + EWE_STATUSBAR_ITEM_TYPE_OBJECT, EWE_STATUSBAR_ITEM_TYPE_SEPARATOR +from efl.elementary.entry import Entry +from efl.elementary.window import Window, ELM_WIN_BASIC +from efl.elementary.background import Background +from efl.elementary.label import Label +from efl.elementary.button import Button +from efl.elementary.layout import Layout +from efl.elementary.progressbar import Progressbar +from efl.elementary.clock import Clock + +EXPAND_BOTH = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND +EXPAND_HORIZ = EVAS_HINT_EXPAND, 0.0 +FILL_BOTH = EVAS_HINT_FILL, EVAS_HINT_FILL +FILL_HORIZ = EVAS_HINT_FILL, 0.5 + +checked = False + + +def item_cb(obj, item, data): + progressbar = data + if progressbar.value >= 1: + progressbar.value += 0.1 + else: + progressbar.value += 0.1 + + +def item_del_cb(obj, item, data): + label = data + print("item deleted: " + str(item.delete())) + count = len(obj.items) + label.text = str(count) + + +def unswallow_cb(obj, data): + item = data + + content = item.content + del item.content + + if not content: + print("Unset object is None") + try: + item.content = obj + except RuntimeError: + pass + else: + obj.text = "UnSet me" + item.label = "Unset" + item.width = 220 + return + + if content is not obj: + print("Unsetted object not equal to button") + return + + obj.text = "Set me" + item.label = "Unset" + item.width = 120 + content.move(50, 50) + + +def reorder_cb(obj, data): + item = obj.data["tst"] + before = obj.data["tst2"] + after = data + #it_index = item.index + global checked + + if checked: + item.insert_after(after) + else: + item.insert_before(before) + + checked = not checked + + +def statusbar_clicked(obj): + win = Window( + "statusbar", ELM_WIN_BASIC, title="Statusbar", autodel=True, + size=(1200, 300) + ) + if obj is None: + win.callback_delete_request_add(lambda o: elementary.exit()) + + bg = Background( + win, size_hint_weight=EXPAND_BOTH, color=(90, 255, 255) + ) + bg.show() + + markup = Layout(win, size_hint_weight=EXPAND_BOTH) + win.resize_object_add(markup) + + try: + markup.file = ("statusbar.edj", "window") + except RuntimeError: + print("Something wrong with layout file st") + + statusbar = Statusbar(markup) + statusbar.show() + + markup.content_set("ewe.swallow.statusbar", statusbar) + markup.content_set("ewe.swallow.content", bg) + markup.show() + + progressbar = Progressbar(markup) + progressbar.show() + reorder_button = Button(statusbar) + + obj = Entry(statusbar, single_line=True, entry="Testing") + + item = StatusbarItem.append( + statusbar, progressbar, EWE_STATUSBAR_ITEM_TYPE_OBJECT, label="PB: " + ) + + item = StatusbarItem.append( + statusbar, reorder_button, EWE_STATUSBAR_ITEM_TYPE_OBJECT, + item_cb, progressbar, label="Reorder: " + ) + reorder_button.data["tst"] = item + + button = Button(statusbar) + item = StatusbarItem.append( + statusbar, button, EWE_STATUSBAR_ITEM_TYPE_OBJECT, label="Unset" + ) + button.callback_clicked_add(unswallow_cb, item) + reorder_button.callback_clicked_add(reorder_cb, item) + + StatusbarItem.append(statusbar, button, EWE_STATUSBAR_ITEM_TYPE_SEPARATOR) + StatusbarItem.append( + statusbar, obj, EWE_STATUSBAR_ITEM_TYPE_OBJECT, label="Entry: " + ) + + StatusbarItem.append( + statusbar, type=EWE_STATUSBAR_ITEM_TYPE_OBJECT, label="None: " + ) + + label = Label(statusbar) + + button = Button(statusbar) + item = StatusbarItem.append( + statusbar, button, EWE_STATUSBAR_ITEM_TYPE_OBJECT, item_del_cb, label, + label="Delete me " + ) + + StatusbarItem.append(statusbar, button, EWE_STATUSBAR_ITEM_TYPE_SEPARATOR) + + obj = Clock(statusbar) + item = StatusbarItem.append( + statusbar, obj, EWE_STATUSBAR_ITEM_TYPE_OBJECT + ) + item.label = " " + + item = StatusbarItem.append( + statusbar, label, EWE_STATUSBAR_ITEM_TYPE_OBJECT, width=100, + label="Count" + ) + reorder_button.data["tst2"] = item + + item = StatusbarItem.append( + statusbar, button, EWE_STATUSBAR_ITEM_TYPE_SEPARATOR + ) + items = statusbar.items + count = len(items) + label.text = str(count) + + print("Items count %d" % count) + + win.show() + + +if __name__ == "__main__": + ewe.init() + + statusbar_clicked(None) + + elementary.run() + ewe.shutdown() diff --git a/examples/ewe/test_tabs.py b/examples/ewe/test_tabs.py new file mode 100644 index 0000000..4542715 --- /dev/null +++ b/examples/ewe/test_tabs.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# encoding: utf-8 + +from efl.evas import EVAS_HINT_EXPAND, EVAS_HINT_FILL +from efl import elementary +from efl import ewe +from efl.ewe.tabs import Tabs, TabsItem +from efl.elementary.label import Label +from efl.elementary.button import Button +from efl.elementary.window import StandardWindow + +EXPAND_BOTH = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND +EXPAND_HORIZ = EVAS_HINT_EXPAND, 0.0 +FILL_BOTH = EVAS_HINT_FILL, EVAS_HINT_FILL +FILL_HORIZ = EVAS_HINT_FILL, 0.5 + + +def on_click(obj, data): + it = data + it.delete() + + +def on_activate(obj, it): + print("Activated item: [%s]" % it.title) + + +def on_deactivate(obj, it): + print("Deactivated item: [%s]" % it.title) + + +def tabs_clicked(obj): + win = StandardWindow( + "tabs", "Tabs", autodel=True, size=(1000, 600) + ) + if obj is None: + win.callback_delete_request_add(lambda o: elementary.exit()) + + tabs = Tabs(win) + tabs.callback_item_activated_add(on_activate) + tabs.callback_item_deactivated_add(on_deactivate) + + lbl = Label(win, text="TEXT 1") + lbl2 = Label(win, text="TEXT 2") + lbl3 = Label(win, text="TEXT 3") + + it = TabsItem.append(tabs, title="test_tabs") + it.content = lbl + it = TabsItem.append(tabs, title="test_tabs") + it.disabled = True + it_cannot_del = TabsItem.append(tabs, title="Can't delete me :P") + btn = Button(tabs) + btn.callback_clicked_add(on_click, it_cannot_del) + it_cannot_del.icon = btn + it = TabsItem.append(tabs, title="test_tabs") + it = TabsItem.append(tabs, None, "test_tabs2 with long text", "red") + it = TabsItem.prepend(tabs, it, "test_tabs2 with long text", "green") + it.title = "tabs item 2 with resetted title" + it.content = lbl2 + + del it.content + + it = TabsItem.append(tabs, style="blue") + it.title = "tabs item 3 :)" + it.content = lbl3 + + items = tabs.items + for it in items: + if it == it_cannot_del: + continue + btn = Button(tabs) + btn.callback_clicked_add(on_click, it) + it.button = btn + + win.resize_object_add(tabs) + lbl3.show() + + tabs.show() + + win.show() + +if __name__ == "__main__": + ewe.init() + + tabs_clicked(None) + + elementary.run() + ewe.shutdown() diff --git a/setup.py b/setup.py index dee9e17..e88e3a1 100755 --- a/setup.py +++ b/setup.py @@ -29,6 +29,7 @@ if RELEASE.split(".")[2] == "99": CYTHON_MIN_VERSION = "0.19" EFL_MIN_VERSION = "1.10.99" ELM_MIN_VERSION = "1.10.99" +EWE_MIN_VERSION = "0.1.0" # XXX: Force default visibility. See phab T504 @@ -415,6 +416,35 @@ if set(("build", "build_ext", "install", "bdist", "sdist")) & set(sys.argv): packages.append("efl.elementary") + # === Ewe === + try: + ewe_cflags, ewe_libs = pkg_config( + 'Ewe', 'ewe', EWE_MIN_VERSION + ) + except SystemExit: + pass + else: + ewe_mods = ( + "__init__", + "object_item", + "combobox", + "entry", + "ruler", + "statusbar", + "tabs" + ) + + for m in ewe_mods: + e = Extension( + "ewe." + m, + ["efl/ewe/" + m + module_suffix], + include_dirs=["include/"], + extra_compile_args=ewe_cflags, + extra_link_args=ewe_libs + eina_libs + evas_libs, + ) + modules.append(e) + + packages.append("efl.ewe") setup( name="python-efl",