285 lines
11 KiB
Plaintext
285 lines
11 KiB
Plaintext
.. currentmodule:: sdl2.ext
|
|
|
|
User interface elements
|
|
=======================
|
|
User interface elements within :mod:`sdl2.ext` are simple
|
|
:class:`Sprite` objects, which are enhanced by certain input hooks; as such,
|
|
they are not classes on their own, but implemented as mixins. The user input
|
|
itself is handled by an :class:`UIProcessor` object, which takes care of
|
|
delegating input events, such as mouse movements, clicks and keyboard input,
|
|
to the correct UI element.
|
|
|
|
Depending on the event type (e.g. pressing a mouse button), the UIProcessor
|
|
will execute its matching method (e.g. ``mousedown()``) with only those UI
|
|
elements, which support the event type.
|
|
|
|
.. image:: images/uiprocessing.png
|
|
|
|
.. _ui-elem-types:
|
|
|
|
UI element types
|
|
----------------
|
|
Every :class:`sdl2.ext` UI element is a simple :class:`Sprite` object, to
|
|
which additional attributes and methods are bound.
|
|
|
|
Every UI element features the following attributes
|
|
|
|
``element.uitype``
|
|
|
|
The ``uitype`` attribute can have one of the following values,
|
|
identifying the UI element:
|
|
|
|
* ``BUTTON`` - a UI element, which can react on mouse input
|
|
* ``CHECKBUTTON`` - as ``BUTTON``, but it retains its state on clicks
|
|
* ``TEXTENTRY`` - a UI element that reacts on keyboard input
|
|
|
|
``element.events``
|
|
|
|
A dictionary containing the SDL2 event mappings. Each supported SDL2 event
|
|
(e.g. ``SDL_MOUSEMOTION``) is associated with a bound
|
|
:class:`EventHandler` acting as callback for user code
|
|
(e.g. ``mousemotion()``).
|
|
|
|
Depending on the exact type of the element, it will feature additional methods
|
|
and attributes explained below.
|
|
|
|
Button elements
|
|
^^^^^^^^^^^^^^^
|
|
``BUTTON`` UI elements feature a ``state`` attribute, which can be one of the
|
|
following values.
|
|
|
|
======== =====================================================================
|
|
state Description
|
|
======== =====================================================================
|
|
RELEASED Indicates that the UI element is not pressed.
|
|
HOVERED Indicates that the mouse cursor is currently hovering the UI element.
|
|
PRESSED Indicates that a mouse button is pressed on the UI element.
|
|
======== =====================================================================
|
|
|
|
``BUTTON`` UI elements react with the following event handlers on events:
|
|
|
|
``button.motion(event : sdl2.events.SDL_Event)``
|
|
|
|
An :class:`EventHandler` that is invoked, if the mouse moves around while
|
|
being over the ``BUTTON``.
|
|
|
|
``button.pressed(event : sdl2.events.SDL_Event)``
|
|
|
|
An :class:`EventHandler` that is invoked, if a mouse button is pressed on
|
|
the ``BUTTON``.
|
|
|
|
``button.released(event : sdl2.events.SDL_Event)``
|
|
|
|
An :class:`EventHandler` that is invoked, if a mouse button is released on
|
|
the ``BUTTON``.
|
|
|
|
``button.click(event : sdl2.events.SDL_Event)``
|
|
|
|
An :class:`EventHandler` that is invoked, if a mouse button is pressed and
|
|
released on the ``BUTTON``.
|
|
|
|
Besides the ``BUTTON`` a special ``CHECKBUTTON`` UI element type exists,
|
|
which enhances the ``BUTTON`` bindings by an additional ``checked`` attribute.
|
|
The ``checked`` attribute switches its status (``False`` to ``True`` and
|
|
``True`` to ``False``) every time the UI element is clicked.
|
|
|
|
Text input elements
|
|
^^^^^^^^^^^^^^^^^^^
|
|
``TEXTENTRY`` elements react on text input, once they are activated. Text being
|
|
input, once a ``TEXTENTRY`` has been activated, is stored in its ``text``
|
|
attribute.
|
|
|
|
The ``TEXTENTRY`` reacts with the following event handlers on events:
|
|
|
|
``textentry.motion(event : sdl2.events.SDL_Event)``
|
|
|
|
An :class:`EventHandler` that is invoked, if the mouse moves around while
|
|
being over the ``TEXTENTRY``.
|
|
|
|
``textentry.pressed(event : sdl2.events.SDL_Event)``
|
|
|
|
An :class:`EventHandler` that is invoked, if a mouse button is pressed on
|
|
the ``TEXTENTRY``.
|
|
|
|
``textentry.released(event : sdl2.events.SDL_Event)``
|
|
|
|
An :class:`EventHandler` that is invoked, if a mouse button is released on
|
|
the ``TEXTENTRY``.
|
|
|
|
``textentry.keydown(event : sdl2.events.SDL_Event)``
|
|
|
|
An :class:`EventHandler` that is invoked on pressing a key.
|
|
|
|
``textentry.keyup(event : sdl2.events.SDL_Event)``
|
|
|
|
An :class:`EventHandler` that is invoked on releasing a key.
|
|
|
|
``textentry.input(event : sdl2.events.SDL_Event)``
|
|
|
|
An :class:`EventHandler` that is invoked on text input events.
|
|
Text input events are automatically created, once the :class:`UIProcessor`
|
|
activates a ``TEXTENTRY`` UI element.
|
|
|
|
``textentry.editing(event : sdl2.events.SDL_Event)``
|
|
|
|
An :class:`EventHandler` that is invoked on text editing events. Text
|
|
editing events are automatically created, once the :class:`UIProcessor`
|
|
activates a ``TEXTENTRY`` UI element.
|
|
|
|
Text editing events are however only raised, if an IME system is involved,
|
|
which combines glyphs and symbols to characters or word fragments.
|
|
|
|
API
|
|
---
|
|
|
|
.. class:: UIFactory(spritefactory : SpriteFactory[, **kwargs])
|
|
|
|
A factory class for creating UI elements. The :class:`UIFactory`
|
|
allows you to create UI elements based on the
|
|
:class:`Sprite` class. To do this, it requires a :class:`SpriteFactory`,
|
|
which will create the sprites, to which the :class:`UIFactory` then binds
|
|
the additional methods and attributes.
|
|
|
|
The additional *kwargs* are used as default arguments for creating
|
|
**sprites** within the factory methods.
|
|
|
|
.. attribute:: default_args
|
|
|
|
A dictionary containing the default arguments to be passed to the
|
|
sprite creation methods of the bound :class:`SpriteFactory`.
|
|
|
|
.. attribute:: spritefactory
|
|
|
|
The :class:`SpriteFactory` being used for creating new :class:`Sprite`
|
|
objects.
|
|
|
|
.. method:: create_button(**kwargs) -> Sprite
|
|
|
|
Creates a new button UI element.
|
|
|
|
*kwargs* are the arguments to be passed for the sprite
|
|
construction and can vary depending on the sprite type.
|
|
See :meth:`SpriteFactory.create_sprite()` for further details.
|
|
|
|
.. method:: create_check_button(**kwargs) -> Sprite
|
|
|
|
Creates a new checkbutton UI element.
|
|
|
|
*kwargs* are the arguments to be passed for the sprite
|
|
construction and can vary depending on the sprite type.
|
|
See :meth:`SpriteFactory.create_sprite()` for further details.
|
|
|
|
.. method:: create_text_entry(**kwargs) -> Sprite
|
|
|
|
Creates a new textentry UI element.
|
|
|
|
*kwargs* are the arguments to be passed for the sprite
|
|
construction and can vary depending on the sprite type.
|
|
See :meth:`SpriteFactory.create_sprite()` for further details.
|
|
|
|
.. method:: from_color(color : object , size) -> Sprite
|
|
|
|
Creates a UI element with a specific color.
|
|
|
|
*uitype* must be one of the supported :ref:`ui-elem-types` classifying
|
|
the type of UI element to be created.
|
|
|
|
.. method:: from_image(uitype : int, fname : str) -> Sprite
|
|
|
|
Creates a UI element from an image file. The image must be
|
|
loadable via :func:`load_image()`.
|
|
|
|
*uitype* must be one of the supported :ref:`ui-elem-types` classifying
|
|
the type of UI element to be created.
|
|
|
|
.. method:: from_object(uitype : int, obj: object) -> Sprite
|
|
|
|
Creates a UI element from an object. The object will be passed through
|
|
:func:`sdl2.rwops_from_object()` in order to try to load image data from
|
|
it.
|
|
|
|
*uitype* must be one of the supported :ref:`ui-elem-types` classifying
|
|
the type of UI element to be created.
|
|
|
|
.. method:: from_surface(uitype : int, surface : SDL_Surface[, free=False]) -> Sprite
|
|
|
|
Creates a UI element from the passed
|
|
:class:`sdl2.surface.SDL_Surface`. If *free* is set to
|
|
``True``, the passed *surface* will be freed automatically.
|
|
|
|
*uitype* must be one of the supported :ref:`ui-elem-types` classifying
|
|
the type of UI element to be created.
|
|
|
|
.. class:: UIProcessor()
|
|
|
|
A processing system for user interface elements and events.
|
|
|
|
.. attribute:: handlers
|
|
|
|
A dict containing the mapping of SDL2 events to the available
|
|
:class:`EventHandler` bindings of the :class:`UIProcessor`.
|
|
|
|
.. method:: activate(component : object) -> None
|
|
|
|
Activates a UI control to receive text input.
|
|
|
|
.. method:: deactivate(component : object) -> None
|
|
|
|
Deactivate the currently active UI control.
|
|
|
|
.. method:: passevent(component : object, event : SDL_Event) -> None
|
|
|
|
Passes the *event* to a *component* without any additional checks or
|
|
restrictions.
|
|
|
|
.. method:: mousemotion(component : object, event : SDL_Event) -> None
|
|
|
|
Checks, if the event's motion position is on the *component* and
|
|
executes the component's event handlers on demand. If the motion event
|
|
position is not within the area of the *component*, nothing will be
|
|
done. In case the component is a ``BUTTON``, its :attr:`state` will be
|
|
adjusted to reflect, if it is currently hovered or not.
|
|
|
|
.. method:: mousedown(component : object, event : SDL_Event) -> None
|
|
|
|
Checks, if the event's button press position is on the *component* and
|
|
executes the component's event handlers on demand. If the button press
|
|
position is not within the area of the component, nothing will be done.
|
|
|
|
In case the component is a ``BUTTON``, its :attr:`state`
|
|
will be adjusted to reflect, if it is currently pressed or not.
|
|
|
|
In case the component is a ``TEXTENTRY`` and the pressed button is
|
|
the primary mouse button, the component will be marked as the next
|
|
control to activate for text input.
|
|
|
|
.. method:: mouseup(self, component, event) -> None
|
|
|
|
Checks, if the event's button release position is on the *component* and
|
|
executes the component's event handlers on demand. If the button release
|
|
position is not within the area of the component, nothing will be done.
|
|
|
|
In case the component is a ``BUTTON``, its :attr:`state`
|
|
will be adjusted to reflect, whether it is hovered or not.
|
|
|
|
If the button release followed a button press on the same component and
|
|
if the button is the primary button, the ``click()`` event handler is
|
|
invoked, if the component is a ``BUTTON``.
|
|
|
|
.. method:: dispatch(obj : object, event : SDL_Event) -> None
|
|
|
|
Passes an event to the given object. If *obj* is a
|
|
:class:`World` object, UI relevant components will receive
|
|
the event, if they support the event type. If *obj* is a single object,
|
|
``obj.events`` **must** be a dict consisting of SDL event type
|
|
identifiers and :class:`EventHandler` instances bound
|
|
to the object. If *obj* is a iterable, such as a list or set, every
|
|
item within *obj* **must** feature an ``events`` attribute as
|
|
described above.
|
|
|
|
.. method:: process(world : World, components : iterable) -> None
|
|
|
|
The :class:`UIProcessor` class does not implement the `process()`
|
|
method by default. Instead it uses :meth:`dispatch()` to send events
|
|
around to components. :meth:`process()` does nothing.
|