python-efl: Fix documentation issues, use NotImplementedError for

abstract methods in evas smartobject.


SVN revision: 84398
This commit is contained in:
Kai Huuhko 2013-03-01 12:44:05 +00:00
parent 413059f163
commit bb65ae91cb
14 changed files with 440 additions and 303 deletions

View File

@ -1,4 +1,4 @@
:class:`efl.ecore.Animator` Class
==============================
=================================
.. autoclass:: efl.ecore.Animator

View File

@ -1,4 +1,4 @@
:class:`efl.ecore.FileDownload` Class
==============================
=====================================
.. autoclass:: efl.ecore.FileDownload

View File

@ -1,4 +1,4 @@
:class:`efl.ecore.IdleEnterer` Class
==============================
====================================
.. autoclass:: efl.ecore.IdleEnterer

View File

@ -1,4 +1,4 @@
:class:`efl.ecore.IdleExiter` Class
==============================
===================================
.. autoclass:: efl.ecore.IdleExiter

View File

@ -17,28 +17,32 @@
cdef class Animator(Eo):
"""Creates an animator to tick off at every animaton tick during main loop
execution.
This class represents an animator that will call the given ``func``
every N seconds where N is the frametime interval set by
animator_frametime_set(). The function will be passed any extra
parameters given to constructor.
"""
When the animator ``func`` is called, it must return a value of either
*True* or *False* (remember that Python returns *None* if no value is
explicitly returned and *None* evaluates to *False*). If it returns
*True*, it will be called again at the next tick, or if it returns
*False* it will be deleted automatically making any references/handles
for it invalid.
Creates an animator to tick off at every animaton tick during main loop
execution.
Animators should be stopped/deleted by means delete() or
returning *False* from ``func``, otherwise they'll continue alive, even
if the current python context delete it's reference to it.
This class represents an animator that will call the given ``func``
every N seconds where N is the frametime interval set by
animator_frametime_set(). The function will be passed any extra
parameters given to constructor.
:param func: function to call every frame.
Expected signature::
func(*args, **kargs): bool
When the animator ``func`` is called, it must return a value of either
*True* or *False* (remember that Python returns *None* if no value is
explicitly returned and *None* evaluates to *False*). If it returns
*True*, it will be called again at the next tick, or if it returns
*False* it will be deleted automatically making any references/handles
for it invalid.
Animators should be stopped/deleted by means delete() or
returning *False* from ``func``, otherwise they'll continue alive, even
if the current python context delete it's reference to it.
:param func:
function to call every frame. Expected signature::
func(*args, **kargs) -> bool
"""
def __init__(self, func, *args, **kargs):
@ -70,15 +74,18 @@ cdef class Animator(Eo):
def animator_add(func, *args, **kargs):
"""Animator factory, for C-api compatibility.
"""
func signature::
func(*args, **kargs): bool
Animator factory, for C-api compatibility.
:param func: function to call every frame.
func signature::
:return: a new Animator instance
:rtype: ``efl.ecore.Animator``
func(*args, **kargs): bool
:param func: function to call every frame.
:return: a new Animator instance
:rtype: ``efl.ecore.Animator``
"""
return Animator(func, *args, **kargs)

View File

@ -167,7 +167,7 @@ cdef void _ecore_exe_pre_free_cb(void *data, const_Ecore_Exe *exe) with gil:
cdef class Exe(object):
"""Spawns a child process with its stdin/out available for communication.
This function forks and runs the given command using C{/bin/sh}.
This function forks and runs the given command using ``/bin/sh``.
Note that the process handle is only valid until a child process
terminated event is received. After all handlers for the child
@ -180,10 +180,10 @@ cdef class Exe(object):
*flags*, that will make Ecore monitor process' stdout and stderr,
emitting events on main loop.
To write use ``send()``. To read listen to ``ECORE_EXE_EVENT_DATA``
To write use :py:func:`send`. To read listen to ``ECORE_EXE_EVENT_DATA``
or ``ECORE_EXE_EVENT_ERROR`` events (see below). Ecore may
buffer read and error data until a newline character if asked for
with the `*flags*. All data will be included in the events
with the *flags*. All data will be included in the events
(newlines will be replaced with NULLS if line is buffered).
``ECORE_EXE_EVENT_DATA`` events will only happen if the process is
@ -191,21 +191,20 @@ cdef class Exe(object):
with the error version. Writing will only be allowed with
``ECORE_EXE_PIPE_WRITE`` enabled in the *flags*.
Instance Event Handling
=======================
.. rubric:: Instance Event Handling
To make use easier, there are methods that automatically filter
events for this instance and deletes them when the ``Exe`` is
deleted:
- on_add_event_add()
- on_add_event_del()
- on_del_event_add()
- on_del_event_del()
- on_data_event_add()
- on_data_event_del()
- on_error_event_add()
- on_error_event_del()
- on_add_event_add()
- on_add_event_del()
- on_del_event_add()
- on_del_event_del()
- on_data_event_add()
- on_data_event_del()
- on_error_event_add()
- on_error_event_del()
The callback signatures are::
@ -221,8 +220,7 @@ cdef class Exe(object):
However, there are C-api conformat functions as well.
Event Handling (C-api conformant)
=================================
.. rubric:: Event Handling (C-api conformant)
Getting data from executed processed is done by means of event
handling, which is also used to notify whenever this process
@ -230,29 +228,31 @@ cdef class Exe(object):
One should listen to events in the main loop, such as:
- ``EventExeAdd`` listen with ``on_exe_add_event_add()`` to know
when sub processes were started and ready to be used.
EventExeAdd
listen with ``on_exe_add_event_add()`` to know when sub processes
were started and ready to be used.
- ``EventExeDel`` listen with ``on_exe_del_event_add()`` to know
when sub processes died.
EventExeDel
listen with ``on_exe_del_event_add()`` to know when sub processes died.
- ``EventExeData`` listen with ``on_exe_data_event_add()`` to know
when sub processes output data to their stdout.
EventExeData
listen with ``on_exe_data_event_add()`` to know when sub processes
output data to their stdout.
- ``EventExeError`` listen with ``on_exe_error_event_add()`` to
know when sub processes output data to their stderr.
EventExeError
listen with ``on_exe_error_event_add()`` to know when sub processes
output data to their stderr.
Events will have the following signature, as explained in
``EventHandler``::
func(event, *args, **kargs): bool
That mean once registered, your callback ``func`` will be called
for all known ``Exe`` instances (that were created from
Python!). You can query which instance created such event with
``event.exe`` property. Thus you often need to filter if the event
you got is from the instance you need! (This is designed to match
C-api).
That mean once registered, your callback ``func`` will be called for all
known ``Exe`` instances (that were created from Python!). You can query
which instance created such event with ``event.exe`` property. Thus you
often need to filter if the event you got is from the instance you need!
(This is designed to match C-api).
Once your function returns evaluates to *False* (note: not returning
means returning *None*, that evaluates to *False*!), your callback
@ -264,20 +264,37 @@ cdef class Exe(object):
:param exe_cmd: command to execute as subprocess.
:type exe_cmd: str
:param flags: if given (!= 0), should be bitwise OR of
- ECORE_EXE_PIPE_READ: Exe Pipe Read mask
- ECORE_EXE_PIPE_WRITE: Exe Pipe Write mask
- ECORE_EXE_PIPE_ERROR: Exe Pipe error mask
- ECORE_EXE_PIPE_READ_LINE_BUFFERED: Reads are buffered until
a newline and delivered 1 event per line.
- ECORE_EXE_PIPE_ERROR_LINE_BUFFERED: Errors are buffered
until a newline and delivered 1 event per line
- ECORE_EXE_PIPE_AUTO: stdout and stderr are buffered automatically
- ECORE_EXE_RESPAWN: Exe is restarted if it dies
- ECORE_EXE_USE_SH: Use /bin/sh to run the command.
- ECORE_EXE_NOT_LEADER Do not use setsid() to have the
executed process be its own session leader
:param flags:
if given (!= 0), should be bitwise OR of
ECORE_EXE_PIPE_READ
Exe Pipe Read mask
ECORE_EXE_PIPE_WRITE
Exe Pipe Write mask
ECORE_EXE_PIPE_ERROR
Exe Pipe error mask
ECORE_EXE_PIPE_READ_LINE_BUFFERED
Reads are buffered until a newline and delivered 1 event per line.
ECORE_EXE_PIPE_ERROR_LINE_BUFFERED
Errors are buffered until a newline and delivered 1 event per line.
ECORE_EXE_PIPE_AUTO
stdout and stderr are buffered automatically
ECORE_EXE_RESPAWN
Exe is restarted if it dies
ECORE_EXE_USE_SH
Use /bin/sh to run the command.
ECORE_EXE_NOT_LEADER
Do not use setsid() to have the executed process be its own
session leader
:type flags: int
:param data: extra data to be associated and available with ``data_get()``
@ -407,7 +424,7 @@ cdef class Exe(object):
ret = bool(ecore_exe_send(self.exe, <const_void *>buf_view.buf, buf_view.len))
PyBuffer_Release(&buf_view)
return ret
def close_stdin(self):
"""Close executed process' stdin.

View File

@ -69,15 +69,18 @@ cdef class FdHandler(object):
references/handles for it invalid.
FdHandler use includes:
- handle multiple socket connections using a single process;
- thread wake-up and synchronization;
- non-blocking file description operations.
- handle multiple socket connections using a single process;
- thread wake-up and synchronization;
- non-blocking file description operations.
:param fd: file descriptor or object with fileno() method.
:param flags: bitwise OR of ECORE_FD_READ, ECORE_FD_WRITE...
:param func: function to call when file descriptor state changes.
Expected signature::
func(fd_handler, *args, **kargs): bool
:param func:
function to call when file descriptor state changes.
Expected signature::
func(fd_handler, *args, **kargs): bool
"""
def __init__(self, fd, int flags, func, *args, **kargs):
@ -171,8 +174,13 @@ cdef class FdHandler(object):
def active_set(self, int flags):
"""Set what active streams the given FdHandler should be monitoring.
:param flags: one of ECORE_FD_NONE - ECORE_FD_READ - ECORE_FD_WRITE
- ECORE_FD_ERROR - ECORE_FD_ALL
:param flags:
one of
- ECORE_FD_NONE
- ECORE_FD_READ
- ECORE_FD_WRITE
- ECORE_FD_ERROR
- ECORE_FD_ALL
"""
cdef Ecore_Fd_Handler_Flags v = <Ecore_Fd_Handler_Flags>flags
@ -191,9 +199,11 @@ cdef class FdHandler(object):
return bool(ecore_main_fd_handler_active_get(self.obj, ECORE_FD_ERROR))
def prepare_callback_set(self, func, *args, **kargs):
"""Set a function to call becore doing the select() on the fd.
"""
Set a function to call becore doing the select() on the fd.
Expected signature::
Expected signature::
function(object, *args, **kargs)
"""
@ -210,15 +220,18 @@ cdef class FdHandler(object):
def fd_handler_add(fd, int flags, func, *args, **kargs):
"""L{FdHandler} factory, for C-api compatibility.
"""
:py:class:`FdHandler` factory, for C-api compatibility.
``func`` signature::
func(fd_handler, *args, **kargs): bool
``func`` signature::
:param fd: file descriptor or object with C{fileno()} method.
:param flags: bitwise OR of ECORE_FD_READ, ECORE_FD_WRITE...
:param func: function to call when file descriptor state changes.
func(fd_handler, *args, **kargs): bool
:param fd: file descriptor or object with C{fileno()} method.
:param flags: bitwise OR of ECORE_FD_READ, ECORE_FD_WRITE...
:param func: function to call when file descriptor state changes.
:rtype: `efl.ecore.FdHandler`
:rtype: `efl.ecore.FdHandler`
"""
return FdHandler(fd, flags, func, *args, **kargs)

View File

@ -26,8 +26,8 @@ cdef class Idler(Eo):
When the idler ``func`` is called, it must return a value of either
True or False (remember that Python returns None if no value is
explicitly returned and None evaluates to False). If it returns
B{True}, it will be called again when system become idle, or if it
returns B{False} it will be deleted automatically making any
**True**, it will be called again when system become idle, or if it
returns **False** it will be deleted automatically making any
references/handles for it invalid.
Idlers should be stopped/deleted by means of delete()or
@ -36,9 +36,11 @@ cdef class Idler(Eo):
Idlers are useful for progressively prossessing data without blocking.
:param func: function to call when system is idle.
Expected signature::
func(*args, **kargs): bool
:param func:
Function to call when system is idle.
Expected signature::
func(*args, **kargs): bool
"""
def __init__(self, func, *args, **kargs):
@ -89,11 +91,12 @@ cdef class IdleEnterer(Idler):
Idle enterer are useful for post-work jobs, like garbage collection.
:param func:
Function to call when system enters idle.
Expected signature::
func(*args, **kargs): bool
:param func: function to call when system enters idle.
Expected signature::
func(*args, **kargs): bool
"""
def __init__(self, func, *args, **kargs):
if not callable(func):
@ -126,9 +129,11 @@ cdef class IdleExiter(Idler):
returning *False* from ``func``, otherwise they'll continue alive, even
if the current python context delete it's reference to it.
:param func: function to call when system exits idle.
Expected signature::
func(*args, **kargs): bool
:param func:
Function to call when system exits idle.
Expected signature::
func(*args, **kargs): bool
"""
def __init__(self, func, *args, **kargs):
@ -160,9 +165,11 @@ def idler_add(func, *args, **kargs):
def idle_enterer_add(func, *args, **kargs):
"""efl.ecore.IdleEnterer factory, for C-api compatibility.
:param func: function to call when system enters idle.
Expected signature::
func(*args, **kargs): bool
:param func:
Function to call when system enters idle.
Expected signature::
func(*args, **kargs): bool
:return: a new IdleEnterer instance
:rtype: efl.ecore.IdleEnterer
@ -173,9 +180,11 @@ def idle_enterer_add(func, *args, **kargs):
def idle_exiter_add(func, *args, **kargs):
"""efl.ecore.IdleExiter factory, for C-api compatibility.
:param func: function to call when system exits idle.
Expected signature::
func(*args, **kargs): bool
:param func:
Function to call when system exits idle.
Expected signature::
func(*args, **kargs): bool
:return: a new IdleExiter instance
:rtype: efl.ecore.IdleExiter

View File

@ -38,9 +38,11 @@ cdef class Timer(Eo):
:param interval: interval in seconds.
:type interval: float
:param func: function to callback when timer expires.
The function signature is::
func(*args, **kargs): bool
:param func:
function to callback when timer expires.
The function signature is::
func(*args, **kargs): bool
"""
def __init__(self, double interval, func, *args, **kargs):
@ -66,7 +68,7 @@ cdef class Timer(Eo):
def delete(self):
"Stop callback emission and free internal resources."
ecore_timer_del(self.obj)
def stop(self):
"Alias for ``delete()``"
self.delete()
@ -84,7 +86,7 @@ cdef class Timer(Eo):
:param add: seconds to add to the timer
:type add: double
"""
ecore_timer_delay(self.obj, add)

View File

@ -98,15 +98,21 @@ cdef class Edje(Object):
Edje also provides scripting through Embryo and communication can be
done using messages and signals.
.. warning:: although Edje provides part_object_get(), you should **NOT**
.. warning::
although Edje provides part_object_get(), you should **NOT**
mess with these objects states or you'll screw the given Edje. The
objects you get with this function should be handled as "read-only".
.. attention:: messages are one way only! If you emit a message from Python
.. attention::
messages are one way only! If you emit a message from Python
you will just get it from your Embryo script, if you emit from Embryo
you just get it in Python. If you want to emit events and capture
them on the same side, use signals.
.. note:: You can debug messages and signals by capturing all of them,
.. note::
You can debug messages and signals by capturing all of them,
example::
>>> def sig_dbg(obj, emission, source):
... print "%s: %s %s" % (obj, emission, source)
...
@ -193,7 +199,7 @@ cdef class Edje(Object):
:param file: the name of the file to load
:param group: the name of the group inside the edj to load
:raise EdjeLoadError: if error occurred during load.
"""
@ -206,7 +212,7 @@ cdef class Edje(Object):
:return: the tuple (file, group)
:rtype: tuple for str
"""
cdef const_char_ptr file, group
edje_object_file_get(self.obj, &file, &group)
@ -225,7 +231,7 @@ cdef class Edje(Object):
:param value: True to play or False to pause
:type value: int
"""
edje_object_play_set(self.obj, value)
@ -296,7 +302,7 @@ cdef class Edje(Object):
:param color_class: the name of the color class to query
:return: the tuple (r, g, b, a, r2, g2, b2, a2, r3, g3, b3, a3)
:rtype: tuple of int
"""
cdef int r, g, b, a
cdef int r2, g2, b2, a2
@ -361,12 +367,15 @@ cdef class Edje(Object):
return bool(edje_object_part_exists(self.obj, _cfruni(part)))
def part_object_get(self, part):
"""Get the efl.evas.Object that represents this part.
"""
Get the efl.evas.Object that represents this part.
.. warning::
You should never modify the state of the returned object
(with Edje.move() or Edje.hide() for example),
but you can safely query info about its current state
(with Edje.visible_get() or Edje.color_get() for example).
.. warning:: You should never modify the state of the returned object
(with Edje.move() or Edje.hide() for example),
but you can safely query info about its current state
(with Edje.visible_get() or Edje.color_get() for example).
"""
cdef Evas_Object *obj
obj = <Evas_Object*>edje_object_part_object_get(self.obj, _cfruni(part))
@ -393,9 +402,12 @@ cdef class Edje(Object):
def text_change_cb_set(self, func, *args, **kargs):
"""Set function to callback on text changes.
:param func: the function to call when text change
Expected signature::
function(object, part, *args, **kargs)
:param func:
The function to call when text change
Expected signature::
function(object, part, *args, **kargs)
"""
if func is None:
self._text_change_cb = None
@ -417,14 +429,14 @@ cdef class Edje(Object):
def part_text_get(self, part):
"""Get the text of a given part.
:return: the text of part
:rtype: str
"""
cdef const_char_ptr s
return _ctouni(edje_object_part_text_get(self.obj, _cfruni(part)))
def part_text_select_all(self, part):
"Select all the text of the given TEXT or TEXTBLOCK part"
@ -479,7 +491,7 @@ cdef class Edje(Object):
:type part: str
:param obj: the efl.evas.Object to swallow inside part
:type obj: efl.evas.Object
"""
edje_object_part_swallow(self.obj, _cfruni(part), obj.obj)
@ -968,10 +980,10 @@ cdef class Edje(Object):
Data should be pure-python types that will be converted to
the Message subclass that better fits it. Supported are:
- long, int, float, str
- list of long, int, float, str
- str and one of long, int, float
- str and a list of one of long, int, float
- long, int, float, str
- list of long, int, float, str
- str and one of long, int, float
- str and a list of one of long, int, float
Messages sent will **NOT** be available at Python-side (ie:
message_handler_set()), but just at Embryo-side.
@ -1003,9 +1015,11 @@ cdef class Edje(Object):
"""Set the handler of messages coming from Embryo.
Signature::
function(object, message, *args, **kargs)
.. note:: this just handle messages sent from Embryo.
:raise TypeError: if func is not callable or None.
"""
if func is None:
@ -1027,14 +1041,17 @@ cdef class Edje(Object):
"""Add callback to given signal (emission, source).
Signature::
function(object, emission, source, *args, **kargs)
:param emission: the emission to listen, may be or contain '*' to
match multiple.
:param source: the emission's source to listen, may be or contain
'*' to match multiple.
:param func: the callable to use. Will get any further arguments
you gave to signal_callback_add().
:param emission:
the emission to listen, may be or contain '*' to match multiple.
:param source:
the emission's source to listen, may be or contain '*' to match
multiple.
:param func:
the callable to use. Will get any further arguments you gave to
signal_callback_add().
:raise TypeError: if func is not callable.
"""

View File

@ -114,7 +114,7 @@ EVAS_COLORSPACE_RGB565_A5P = 3
EVAS_PIXEL_FORMAT_NONE = 0
EVAS_PIXEL_FORMAT_ARGB32 = 1
EVAS_PIXEL_FORMAT_YUV420P_601 = 2
EVAS_FONT_HINTING_NONE = 0
EVAS_FONT_HINTING_AUTO = 1
EVAS_FONT_HINTING_BYTECODE = 2
@ -171,10 +171,10 @@ def render_method_lookup(name):
Lookup render method and return its id (> 0 if found).
@param name: Render method
@type name: string
@return: ID
@rtype: int
:param name: Render method
:type name: string
:return: ID
:rtype: int
"""
return evas_render_method_lookup(_cfruni(name))
@ -185,7 +185,7 @@ def render_method_list():
Returns a list of render method names.
@rtype: list of str
:rtype: list of str
"""
cdef Eina_List *lst

View File

@ -21,8 +21,8 @@
# for i from 0 <= i < evas_canvas_event_callbacks_len:
# canvas._callbacks[i] = None
# return 1
#
#
#
#
cdef int _canvas_unregister_callbacks(Canvas canvas) except 0:
cdef Evas *e
cdef Evas_Event_Cb cb
@ -153,7 +153,7 @@ cdef class Canvas(Eo):
"""Set the engine information pointer.
Note that given value is a pointer, usually acquired with
:py:func:`engine_info_get() and is totally engine and platform
:py:func:`engine_info_get` and is totally engine and platform
dependent.
This call is very low level and is meant for extension to use,
@ -229,7 +229,7 @@ cdef class Canvas(Eo):
:param y:
:param w:
:param h:
The output viewport is the area of the evas that will be visible to
the viewer. The viewport will be stretched to fit the output target
of the evas when rendering is performed.
@ -559,8 +559,15 @@ cdef class Canvas(Eo):
<Evas_Font_Hinting_Flags>flags))
def font_hinting_set(self, int flags):
""":param flags: one of EVAS_FONT_HINTING_NONE,
EVAS_FONT_HINTING_AUTO or EVAS_FONT_HINTING_BYTECODE
"""
:param flags:
One of
* EVAS_FONT_HINTING_NONE
* EVAS_FONT_HINTING_AUTO
* EVAS_FONT_HINTING_BYTECODE
"""
evas_font_hinting_set(self.obj, <Evas_Font_Hinting_Flags>flags)

View File

@ -59,7 +59,7 @@ cdef void obj_free_cb(void *data, Evas *e,
# cdef _object_register_decorated_callbacks(obj):
# if not hasattr(obj, "__evas_event_callbacks__"):
# return
#
#
# for attr_name, evt in obj.__evas_event_callbacks__:
# attr_value = getattr(obj, attr_name)
# obj.event_callback_add(evt, attr_value)
@ -125,9 +125,11 @@ cdef class Object(Eo):
(:py:attr:`clip`), usually done by use of
:py:class:`Rectangle <efl.evas.Rectangle>` as clipper. Clip objects will
affect the drawing behavior:
- Limiting visibility
- Limiting geometry
- Modulating color
- Limiting visibility
- Limiting geometry
- Modulating color
Clips respects the hierarchy: the minimum area and the composed color
will be used used at the end, if one object is not visible, othe lower
objects (clipped by it) will not be visible as well. Clipping is the
@ -137,10 +139,10 @@ cdef class Object(Eo):
work for :py:class:`Images <efl.evas.Image>`
As with every evas component, colors should be specified in
**pre-multiplied** format, see L{evas.color_parse()} and
L{evas.color_argb_premul()}.
**pre-multiplied** format, see :py:func:`color_parse` and
:py:func:`evas.color_argb_premul`.
Objects can be grouped by means of L{SmartObject}, a virtual class
Objects can be grouped by means of :py:class:`SmartObject`, a virtual class
that can have it's methods implemented in order to apply methods to
its children.
@ -220,9 +222,9 @@ cdef class Object(Eo):
property evas:
""" The evas Canvas that owns this object.
:type: :py:class:`efl.evas.Canvas`
"""
def __get__(self):
return object_from_instance(evas_object_evas_get(self.obj))
@ -233,19 +235,19 @@ cdef class Object(Eo):
# TODO move to Eo
# def type_get(self):
# """type_get()
#
#
# Get the Evas object's type
#
# @rtype: string
#
# :rtype: string
# """
# if self.obj:
# return _ctouni(evas_object_type_get(self.obj))
# property type:
# """Type name, ie: "rectangle".
#
# @type: string
#
#
# :type: string
#
# """
# def __get__(self):
# return self.type_get()
@ -1580,4 +1582,4 @@ cdef class Object(Eo):
# TODO dunno how to do this in a sane way
#return evas_object_map_get(self.obj)
return None

View File

@ -261,11 +261,11 @@ cdef long _smart_object_class_new(char *name) except 0:
# def __init__(cls, name, bases, dict_):
# EvasObjectMeta.__init__(cls, name, bases, dict_)
# cls._setup_smart_class()
#
#
# def _setup_smart_class(cls):
# if "__evas_smart_class__" in cls.__dict__:
# return
#
#
# cdef long addr
# addr = _smart_object_class_new(cls.__name__)
# cls.__evas_smart_class__ = addr
@ -297,79 +297,95 @@ cdef class SmartObject(Object):
multiple basic elements, associate an object with a clip and deal with
them as an unit. See evas documentation for more details.
Recommended use is to create an B{clipper} object and clip every other
Recommended use is to create an **clipper** object and clip every other
member to it, then you can have all your other members to be always
visible and implement L{hide()}, L{show()}, L{color_set()}, L{clip_set()}
and L{clip_unset()} to just affect the B{clipper}. See
L{ClippedSmartObject}.
visible and implement :py:func:`hide`, :py:func:`show`,
:py:func:`color_set`, :py:func:`clip_set` and :py:func:`clip_unset` to
just affect the **clipper**. See :py:class:`ClippedSmartObject`.
B{Pay attention that just creating an object within the SmartObject
doesn't make it a member!} You must do L{member_add()} or use one of
**Pay attention that just creating an object within the SmartObject
doesn't make it a member!** You must do :py:func:`member_add` or use one of
the provided factories to ensure that. Failing to do so will leave
created objects on different layer and no stacking will be done for you.
Behavior is defined by defining the following methods:
- L{delete()}: called in order to remove object from canvas and
deallocate its resources. Usually you delete object's children
here. I{Default implementation delete all registered children.}
- L{move()}: called in order to move object to given position.
Usually you move children here. I{Default implementation
calculates offset and move registered children by it.}
- L{resize()}: called in order to resize object. I{No default
implementation.}
- L{show()}: called in order to show the given element. Usually you
call the same function on children. I{No default implementation.}
- L{hide()}: called in order to hide the given element. Usually you
call the same function on children. I{No default implementation.}
- L{color_set()}: called in order to change object color. I{No default
implementation.}
- L{clip_set()}: called in order to limit object's visible area.
I{No default implementation.}
- L{clip_unset()}: called in order to unlimit object's visible area.
I{No default implementation.}
- L{calculate()}: called before object is used for rendering and it
is marked as dirty/changed with L{changed()}. I{Default
implementation does nothing.}
- L{member_add()}: called when children is added to object. I{Default
implementation does nothing.}
- L{member_del()}: called when children is removed from object.
I{Default implementation does nothing.}
@note: You should never instantiate the SmartObject base class directly,
:py:func:`delete`
called in order to remove object from canvas and deallocate its
resources. Usually you delete object's children here. *Default
implementation deletes all registered children.*
:py:func:`move`
called in order to move object to given position. Usually you move
children here. *Default implementation calculates offset and move
registered children by it.*
:py:func:`resize`
called in order to resize object. *No default implementation.*
:py:func:`show`
called in order to show the given element. Usually you call the same
function on children. *No default implementation.*
:py:func:`hide`
called in order to hide the given element. Usually you call the same
function on children. *No default implementation.*
:py:func:`color_set`
called in order to change object color. *No default implementation.*
:py:func:`clip_set`
called in order to limit object's visible area. *No default
implementation.*
:py:func:`clip_unset`
called in order to unlimit object's visible area. *No default
implementation.*
:py:func:`calculate`
called before object is used for rendering and it is marked as
dirty/changed with :py:func:`changed`. *Default implementation does
nothing.*
:py:func:`member_add`
called when children is added to object. *Default implementation
does nothing.*
:py:func:`member_del`
called when children is removed from object. *Default implementation
does nothing.*
.. note::
You should never instantiate the SmartObject base class directly,
but inherit and implement methods, then instantiate this new subclass.
@note: If you redefine object's __init__(), you MUST call your parent!
Failing to do so will result in objects that just work from
Python and not from C, for instance, adding your object to Edje
swallow that clips or set color it will not behave as expected.
@note: Do not call your parent on methods you want to replace the behavior
.. note::
If you redefine object's __init__(), you MUST call your parent!
Failing to do so will result in objects that just work from Python
and not from C, for instance, adding your object to Edje swallow
that clips or set color it will not behave as expected.
..note::
Do not call your parent on methods you want to replace the behavior
instead of extending it. For example, some methods have default
implementation, you may want to remove and replace it with something
else.
@group Children manipulation: member_add, member_del, members_get,
members
@group Factories: Rectangle, Line, Image, FilledImage,
Polygon, Text
@group Default implementations: delete, move, calculate, member_add,
member_del
@group Missing implementations: resize, show, hide, color_set,
clip_set, clip_unset
@group Event system: callback_add, callback_del, callback_call
@see: L{ClippedSmartObject}
:seealso: :py:class:`ClippedSmartObject`
@param canvas: Evas canvas for this object
@type canvas: Canvas
@keyword size: Width and height
@type size: tuple of ints
@keyword pos: X and Y
@type pos: tuple of ints
@keyword geometry: X, Y, width, height
@type geometry: tuple of ints
@keyword color: R, G, B, A
@type color: tuple of ints
@keyword name: Object name
@type name: string
:param canvas: Evas canvas for this object
:type canvas: Canvas
:keyword size: Width and height
:type size: tuple of ints
:keyword pos: X and Y
:type pos: tuple of ints
:keyword geometry: X, Y, width, height
:type geometry: tuple of ints
:keyword color: R, G, B, A
:type color: tuple of ints
:keyword name: Object name
:type name: string
"""
def __cinit__(self, *a, **ka):
@ -437,7 +453,7 @@ cdef class SmartObject(Object):
Non-member objects can not interleave a smart object's members.
@note: if B{child} is already member of another SmartObject, it
:note: if **child** is already member of another SmartObject, it
will be deleted from that membership and added to this object.
"""
evas_object_smart_member_add(child.obj, self.obj)
@ -445,14 +461,14 @@ cdef class SmartObject(Object):
def member_del(self, Object child):
"""Removes a member object from a smart object.
@attention: this will actually map to C API as
C{evas_object_smart_member_del(child)}, so the object will loose
it's parent B{event if the object is not part of this object}.
.. attention:: this will actually map to C API as
``evas_object_smart_member_del(child)``, so the object will loose
it's parent **event if the object is not part of this object**.
"""
evas_object_smart_member_del(child.obj)
def members_get(self):
"""@rtype: tuple of L{Object}"""
""":rtype: tuple of :py:class:`Object`"""
cdef Eina_List *lst, *itr
cdef Object o
ret = []
@ -472,13 +488,19 @@ cdef class SmartObject(Object):
def callback_add(self, char *event, func, *args, **kargs):
"""Add a callback for the smart event specified by event.
@param event: event name
@param func: what to callback. Should have the signature:
C{function(object, event_info, *args, **kargs)}
:param event: Event name
:param func:
What to callback.
Should have the signature::
function(object, event_info, *args, **kargs)
:raise TypeError: if **func** is not callable.
.. warning::
**event_info** will always be a python object, if the
signal is provided by a C-only class, it will crash.
@raise TypeError: if B{func} is not callable.
@warning: B{event_info} will always be a python object, if the
signal is provided by a C-only class, it will crash.
"""
if not callable(func):
raise TypeError("func must be callable")
@ -495,12 +517,12 @@ cdef class SmartObject(Object):
Removes a callback that was added by L{callback_add()}.
@param event: event name
@param func: what to callback, should have be previously registered.
@precond: B{event} and B{func} must be used as parameter for
L{callback_add()}.
:param event: event name
:param func: what to callback, should have be previously registered.
:precond: **event** and **func** must be used as parameter for
:py:func:`callback_add`.
@raise ValueError: if there was no B{func} connected with this event.
:raise ValueError: if there was no **func** connected with this event.
"""
try:
lst = self._smart_callbacks[event]
@ -525,20 +547,25 @@ cdef class SmartObject(Object):
def callback_call(self, char *event, event_info=None):
"""Call any smart callbacks for event.
@param event: the event name
@param event_info: an event specific info to pass to the callback.
:param event: the event name
:param event_info: an event specific info to pass to the callback.
This should be called internally in the smart object when some
specific event has occurred. The documentation for the smart object
should include a list of possible events and what type of B{event_info}
to expect.
should include a list of possible events and what type of
**event_info** to expect.
@attention: B{event_info} will always be a python object.
.. attention::
**event_info** will always be a python object.
"""
evas_object_smart_callback_call(self.obj, event, <void*>event_info)
def delete(self):
"""Default implementation to delete all children."""
"""delete()
Default implementation to delete all children.
"""
cdef Eina_List *lst, *itr
lst = evas_object_smart_members_get(self.obj)
itr = lst
@ -548,11 +575,19 @@ cdef class SmartObject(Object):
eina_list_free(lst)
def move_children_relative(self, int dx, int dy):
"""Move all children relatively."""
"""move_children_relative(int dx, int dy)
Move all children relatively.
"""
evas_object_smart_move_children_relative(self.obj, dx, dy)
def move(self, int x, int y):
"""Default implementation to move all children."""
"""move(int x, int y)
Default implementation to move all children.
"""
cdef int orig_x, orig_y, dx, dy
evas_object_geometry_get(self.obj, &orig_x, &orig_y, NULL, NULL)
dx = x - orig_x
@ -560,29 +595,59 @@ cdef class SmartObject(Object):
self.move_children_relative(dx, dy)
def resize(self, int w, int h):
"""Virtual method resize(w, h) of SmartObject"""
print "%s.resize(w, h) not implemented." % self.__class__.__name__
"""resize(int w, int h)
Abstract method.
"""
raise NotImplementedError
#print "%s.resize(w, h) not implemented." % self.__class__.__name__
def show(self):
"""Virtual method show() of SmartObject"""
print "%s.show() not implemented." % self.__class__.__name__
"""show()
Abstract method.
"""
raise NotImplementedError
#print "%s.show() not implemented." % self.__class__.__name__
def hide(self):
"""Virtual method hide() of SmartObject"""
print "%s.hide() not implemented." % self.__class__.__name__
"""hide()
Abstract method.
"""
raise NotImplementedError
#print "%s.hide() not implemented." % self.__class__.__name__
def color_set(self, int r, int g, int b, int a):
"""Virtual method color_set(r, g, b, a) of SmartObject"""
print "%s.color_set(r, g, b, a) not implemented." % \
self.__class__.__name__
"""color_set(int r, int g, int b, int a)
Abstract method.
"""
raise NotImplementedError
#print "%s.color_set(r, g, b, a) not implemented." % \
#self.__class__.__name__
def clip_set(self, Object clip):
"""Virtual method clip(object) of SmartObject"""
print "%s.clip_set(object) not implemented." % self.__class__.__name__
"""clip(Object clip)
Abstract method.
"""
raise NotImplementedError
#print "%s.clip_set(object) not implemented." % self.__class__.__name__
def clip_unset(self):
"""Virtual method clip_unset() of SmartObject"""
print "%s.clip_unset() not implemented." % self.__class__.__name__
"""clip_unset()
Abstract method.
"""
raise NotImplementedError
#print "%s.clip_unset() not implemented." % self.__class__.__name__
def calculate(self):
"""Request object to recalculate it's internal state."""
@ -612,10 +677,11 @@ cdef class SmartObject(Object):
If no calculate() is provided, this flag will be left unchanged.
@note: just setting this flag will not make scene dirty and
evas_render() will have no effect. To do that, use
evas_object_smart_changed(), that will automatically call this
function with 1 as parameter.
.. note::
Just setting this flag will not make scene dirty and
evas_render() will have no effect. To do that, use
evas_object_smart_changed(), that will automatically call this
function with 1 as parameter.
"""
evas_object_smart_need_recalculate_set(self.obj, value)
@ -623,10 +689,10 @@ cdef class SmartObject(Object):
def need_recalculate_get(self):
"""Get the current value of need_recalculate flag.
@note: this flag will be unset during the render phase, after
calculate() is called if one is provided. If no calculate()
is provided, then the flag will be left unchanged after render
phase.
.. note:: this flag will be unset during the render phase, after
calculate() is called if one is provided. If no calculate()
is provided, then the flag will be left unchanged after render
phase.
"""
return evas_object_smart_need_recalculate_get(self.obj)
@ -640,7 +706,7 @@ cdef class SmartObject(Object):
# Factory
def Rectangle(self, **kargs):
"""Factory of children L{evas.Rectangle}.
@rtype: L{Rectangle<evas.Rectangle>}
:rtype: L{Rectangle<evas.Rectangle>}
"""
obj = Rectangle(self.evas, **kargs)
self.member_add(obj)
@ -648,7 +714,7 @@ cdef class SmartObject(Object):
def Line(self, **kargs):
"""Factory of children L{evas.Line}.
@rtype: L{Line<evas.Line>}
:rtype: L{Line<evas.Line>}
"""
obj = Line(self.evas, **kargs)
self.member_add(obj)
@ -656,7 +722,7 @@ cdef class SmartObject(Object):
# def Image(self, **kargs):
# """Factory of children L{evas.Image}.
# @rtype: L{Image<evas.Image>}
# :rtype: L{Image<evas.Image>}
# """
# obj = Image(self.evas, **kargs)
# self.member_add(obj)
@ -664,31 +730,31 @@ cdef class SmartObject(Object):
# def FilledImage(self, **kargs):
# """Factory of L{evas.FilledImage} associated with this canvas.
# @rtype: L{FilledImage<evas.FilledImage>}
# :rtype: L{FilledImage<evas.FilledImage>}
# """
# obj = FilledImage(self.evas, **kargs)
# self.member_add(obj)
# return obj
#
#
# def Polygon(self, **kargs):
# """Factory of children L{evas.Polygon}.
# @rtype: L{Polygon<evas.Polygon>}
# :rtype: L{Polygon<evas.Polygon>}
# """
# obj = Polygon(self.evas, **kargs)
# self.member_add(obj)
# return obj
#
#
# def Text(self, **kargs):
# """Factory of children L{evas.Text}.
# @rtype: L{Text<evas.Text>}
# :rtype: L{Text<evas.Text>}
# """
# obj = Text(self.evas, **kargs)
# self.member_add(obj)
# return obj
#
#
# def Textblock(self, **kargs):
# """Factory of children L{evas.Textblock}.
# @rtype: L{Textblock<evas.Textblock>}
# :rtype: L{Textblock<evas.Textblock>}
# """
<