# Copyright (C) 2007-2014 various contributors (see AUTHORS) # # This file is part of Python-EFL. # # Python-EFL is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 3 of the License, or (at your option) any later version. # # Python-EFL is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this Python-EFL. If not, see . """ .. image:: /images/menu-preview.png Widget description ------------------ A menu is a list of items displayed above its parent. When the menu is showing its parent is darkened. Each item can have a sub-menu. The menu object can be used to display a menu on a right click event, in a toolbar, anywhere. Signals that you can add callbacks for are: - ``clicked`` - the user clicked the empty space in the menu to dismiss. - ``dismissed`` - the user clicked the empty space in the menu to dismiss (since 1.8) Default content parts of the menu items that you can use for are: - ``default`` - A main content of the menu item Default text parts of the menu items that you can use for are: - ``default`` - label in the menu item """ from cpython cimport PyUnicode_AsUTF8String from efl.eo cimport _object_mapping_register, object_from_instance from efl.utils.conversions cimport _ctouni from efl.evas cimport Object as evasObject from object_item cimport _object_item_callback, _object_item_list_to_python, \ _object_item_to_python, _object_item_callback2, ObjectItem cdef class MenuItem(ObjectItem): """An item for the :py:class:`Menu` widget.""" cdef: MenuItem parent bytes label, icon def __init__(self, MenuItem parent = None, label = None, icon = None, callback = None, cb_data = None, *args, **kargs): if callback is not None: if not callable(callback): raise TypeError("callback is not callable") if isinstance(icon, unicode): icon = PyUnicode_AsUTF8String(icon) if isinstance(label, unicode): label = PyUnicode_AsUTF8String(label) self.parent = parent self.label = label self.icon = icon self.cb_func = callback self.cb_data = cb_data self.args = args self.kwargs = kargs def add_to(self, Menu menu not None): # TODO: document this cdef: Elm_Object_Item *item Elm_Object_Item *parent_obj = NULL Evas_Smart_Cb cb = NULL if self.cb_func is not None: cb = _object_item_callback2 item = elm_menu_item_add(menu.obj, self.parent.item if self.parent is not None else NULL, self.icon if self.icon is not None else NULL, self.label if self.label is not None else NULL, cb, self) if item == NULL: raise RuntimeError("The item could not be added to the widget.") self._set_obj(item) self._set_properties_from_keyword_args(self.kwargs) return self property object: """Get the Evas_Object of an Elm_Object_Item .. warning:: Don't manipulate this object! :return: The edje object containing the swallowed content """ def __get__(self): return object_from_instance(elm_menu_item_object_get(self.item)) def object_get(self): return object_from_instance(elm_menu_item_object_get(self.item)) property icon_name: """The standard icon name of a menu item Once this icon is set, any previously set icon will be deleted. :type: string """ def __get__(self): return _ctouni(elm_menu_item_icon_name_get(self.item)) def __set__(self, icon): if isinstance(icon, unicode): icon = PyUnicode_AsUTF8String(icon) elm_menu_item_icon_name_set(self.item, icon if icon is not None else NULL) def icon_name_set(self, icon): if isinstance(icon, unicode): icon = PyUnicode_AsUTF8String(icon) elm_menu_item_icon_name_set(self.item, icon if icon is not None else NULL) def icon_name_get(self): return _ctouni(elm_menu_item_icon_name_get(self.item)) property selected: """The selected state of the item. :type: bool """ def __get__(self): return elm_menu_item_selected_get(self.item) def __set__(self, selected): elm_menu_item_selected_set(self.item, selected) def selected_set(self, selected): elm_menu_item_selected_set(self.item, selected) def selected_get(self): return elm_menu_item_selected_get(self.item) property is_separator: """Returns whether the item is a separator. .. seealso:: :py:func:`Menu.item_separator_add()` :type: bool """ def __get__(self): return False property subitems: """A list of item's subitems. :type: tuple of :py:class:`MenuItem` .. versionadded:: 1.8 Calling del on this property clears the subitems """ def __get__(self): return _object_item_list_to_python(elm_menu_item_subitems_get(self.item)) def __del__(self): elm_menu_item_subitems_clear(self.item) def subitems_get(self): return _object_item_list_to_python(elm_menu_item_subitems_get(self.item)) def subitems_clear(self): elm_menu_item_subitems_clear(self.item) property index: """Get the position of a menu item This function returns the index position of a menu item in a menu. For a sub-menu, this number is relative to the first item in the sub-menu. .. note:: Index values begin with 0 :type: int """ def __get__(self): return elm_menu_item_index_get(self.item) def index_get(self): return elm_menu_item_index_get(self.item) property next: """Get the next item in the menu. :type: :py:class:`MenuItem` """ def __get__(self): return _object_item_to_python(elm_menu_item_next_get(self.item)) def next_get(self): return _object_item_to_python(elm_menu_item_next_get(self.item)) property prev: """Get the previous item in the menu. :type: :py:class:`MenuItem` """ def __get__(self): return _object_item_to_python(elm_menu_item_prev_get(self.item)) def prev_get(self): return _object_item_to_python(elm_menu_item_prev_get(self.item)) cdef class MenuSeparatorItem(ObjectItem): """A separator type menu item.""" cdef MenuItem parent def __init__(self, MenuItem parent): self.parent = parent def add_to(self, Menu menu not None): # TODO: document this cdef Elm_Object_Item *item if self.cb_func is not None: cb = _object_item_callback item = elm_menu_item_separator_add(menu.obj, self.parent.item if self.parent is not None else NULL) if item == NULL: raise RuntimeError("The item could not be added to the widget.") self._set_obj(item) return self property is_separator: """Returns whether the item is a separator. :type: bool """ def __get__(self): return True def next_get(self): """Get the next item in the menu. :return: The item after it, or None :rtype: :py:class:`MenuItem` """ return _object_item_to_python(elm_menu_item_next_get(self.item)) property next: """Get the next item in the menu. :type: :py:class:`MenuItem` """ def __get__(self): return _object_item_to_python(elm_menu_item_next_get(self.item)) def prev_get(self): """Get the previous item in the menu. :return: The item before it, or None :rtype: :py:class:`MenuItem` """ return _object_item_to_python(elm_menu_item_prev_get(self.item)) property prev: """Get the previous item in the menu. :type: :py:class:`MenuItem` """ def __get__(self): return _object_item_to_python(elm_menu_item_prev_get(self.item)) cdef class Menu(Object): """This is the class that actually implements the widget.""" def __init__(self, evasObject parent, *args, **kwargs): self._set_obj(elm_menu_add(parent.obj)) self._set_properties_from_keyword_args(kwargs) property parent: """The parent for the given menu widget. :type: :py:class:`~efl.elementary.object.Object` """ def __get__(self): return object_from_instance(elm_menu_parent_get(self.obj)) def __set__(self, evasObject parent): elm_menu_parent_set(self.obj, parent.obj) def parent_get(self): return object_from_instance(elm_menu_parent_get(self.obj)) def move(self, x, y): """Move the menu to a new position Sets the top-left position of the menu to (``x``,``y``). .. note:: ``x`` and ``y`` coordinates are relative to parent. :param x: The new position. :type x: Evas_Coord (int) :param y: The new position. :type y: Evas_Coord (int) """ elm_menu_move(self.obj, x, y) def close(self): """Close a opened menu Hides the menu and all it's sub-menus. """ elm_menu_close(self.obj) property items: """Returns a list of ``item``'s. :type: tuple of :py:class:`MenuItem` """ def __get__(self): return _object_item_list_to_python(elm_menu_items_get(self.obj)) def items_get(self): return _object_item_list_to_python(elm_menu_items_get(self.obj)) def item_add(self, MenuItem parent = None, label = None, icon = None, callback = None, *args, **kwargs): """Add an item at the end of the given menu widget :param parent: The parent menu item (optional) :type parent: :py:class:`~efl.elementary.object.Object` :param string icon: An icon display on the item. The icon will be destroyed by the menu. :param string label: The label of the item. :type label: string :param callback: Function called when the user select the item. :type callback: function :return: Returns the new item. :rtype: :py:class:`MenuItem` """ cdef: Elm_Object_Item *item Evas_Smart_Cb cb = NULL MenuItem ret = MenuItem.__new__(MenuItem) if callback is not None and callable(callback): cb = _object_item_callback if isinstance(label, unicode): label = PyUnicode_AsUTF8String(label) if isinstance(icon, unicode): icon = PyUnicode_AsUTF8String(icon) item = elm_menu_item_add(self.obj, parent.item if parent is not None else NULL, icon if icon is not None else NULL, label if label is not None else NULL, cb, ret) if item != NULL: ret._set_obj(item) ret.cb_func = callback ret.args = args ret.kwargs = kwargs return ret else: return None def item_separator_add(self, parent = None): """Add a separator item to menu under ``parent``. This item is a :py:class:`~efl.elementary.separator.Separator`. :param parent: The item to add the separator under :type parent: :py:class:`~efl.elementary.object.Object` :return: The created item or None on failure :rtype: :py:class:`MenuSeparatorItem` """ return MenuSeparatorItem(parent).add_to(self) property selected_item: """The selected item in the menu .. seealso:: :py:attr:`MenuItem.selected` :type: :py:class:`MenuItem` """ def __get__(self): return _object_item_to_python(elm_menu_selected_item_get(self.obj)) def selected_item_get(self): return _object_item_to_python(elm_menu_selected_item_get(self.obj)) property last_item: """The last item in the menu :type: :py:class:`MenuItem` """ def __get__(self): return _object_item_to_python(elm_menu_last_item_get(self.obj)) def last_item_get(self): return _object_item_to_python(elm_menu_last_item_get(self.obj)) property first_item: """The first item in the menu :type: MenuItem """ def __get__(self): return _object_item_to_python(elm_menu_first_item_get(self.obj)) def first_item_get(self): return _object_item_to_python(elm_menu_first_item_get(self.obj)) def callback_clicked_add(self, func, *args, **kwargs): """The user clicked the empty space in the menu to dismiss.""" self._callback_add("clicked", func, *args, **kwargs) def callback_clicked_del(self, func): self._callback_del("clicked", func) def callback_dismissed_add(self, func, *args, **kwargs): """the user clicked the empty space in the menu to dismiss .. versionadded:: 1.8 """ self._callback_add("dismissed", func, *args, **kwargs) def callback_dismissed_del(self, func): self._callback_del("dismissed", func) _object_mapping_register("Elm_Menu", Menu)