functui.nav¶
Tools to make layouts responsive to keyboard and mouse input
- functui.nav.DEFAULT_NAV_BINDINGS = {' ': NavAction.SELECT_VIA_KEYBOARD, 'ctrl+d': NavAction.PAGE_DOWN, 'ctrl+u': NavAction.PAGE_UP, 'down': NavAction.NAV_DOWN, 'enter': NavAction.SELECT_VIA_KEYBOARD, 'h': NavAction.NAV_LEFT, 'j': NavAction.NAV_DOWN, 'k': NavAction.NAV_UP, 'l': NavAction.NAV_RIGHT, 'left': NavAction.NAV_LEFT, 'left mouse': NavAction.SELECT_VIA_MOUSE_START, 'left mouse released': NavAction.SELECT_VIA_MOUSE_END, 'mouse wheel down': NavAction.SCROLL_DOWN, 'mouse wheel up': NavAction.SCROLL_UP, 'page down': NavAction.PAGE_DOWN, 'page up': NavAction.PAGE_UP, 'right': NavAction.NAV_RIGHT, 'up': NavAction.NAV_UP}¶
A dictinary that maps the string representation of keycodes to a
NavAction
- class functui.nav.Direction(*values)[source]¶
Used to specify navigation direction for a container defined by a
InteractibleID.- VERTICAL¶
- HORIZONTAL¶
- class functui.nav.InteractibleID(data: tuple[InteractibleIDPart, ...])[source]¶
Used to create keyboard navigable tree. May be used either as a container or an item.
If an id is created with the
InteractibleID.childmethod (which is the preffered way of creating new InteractibleID’s), the parent will be saved in the child as anInteractibleIDPartpart.- child(local_id: int, direction: None | Direction = None, persistent: bool = False) → Self[source]¶
Create a new InteractibleID with specified attributes.
The newly created child will remeber this ID as its parent. (as well as all of this ID’s ancestors if there are any)
- Parameters:
local_id – Child’s local id relative to its parent (the InteractibleID on which this method is being called on). Used to distinguish this child from other children of same parent.
direction – If child is used as a container, navigate it’s children by specified direction. If no direction is provided, it will be inherited from child’s parent. (the InteractibleID on which this method is being called on).
persistent – If child is used as a container, remember which child was active and make it active insted of just the first elemnt if this container becomes active again.
- data: tuple[InteractibleIDPart, ...]¶
Every intercatible id stores its own part at the end of the data tuple, and its ancestors parts before it.
- mutual_ancestor(b: Self) → Self[source]¶
Get the closest ID to which both self, and a are descendants.
- property parent¶
may error
- class functui.nav.InteractibleIDPart(direction: functui.nav.Direction, local_id: int, persistent: bool, first_child_default: bool)[source]¶
- class functui.nav.NavAction(*values)[source]¶
An action that is meant to be sent to
NavData.update.- SELECT_VIA_KEYBOARD¶
- SELECT_VIA_MOUSE_START¶
For example, if user presses down left click.
- SELECT_VIA_MOUSE_END¶
For example, if user releases left click.
- PAGE_DOWN¶
- PAGE_UP¶
- SCROLL_UP¶
- SCROLL_DOWN¶
- NAV_UP¶
- NAV_RIGHT¶
- NAV_DOWN¶
- NAV_LEFT¶
- class functui.nav.NavState(mouse_position: Coordinate = (-1, -1), last_mouse_position: Coordinate = (-1, -1), action: NavAction | None = None, last_action: NavAction | None = None, areas: MappingProxyType = mappingproxy({}), _active_id: InteractibleID = InteractibleID(data=()), _hovered_data: _HoveredData = (InteractibleID(data=()), False), _held_down: InteractibleID = InteractibleID(data=()), _held_down_is_being_dragged: bool = False, _just_held_down: InteractibleID = InteractibleID(data=()), _last_active_or_hovered_id: InteractibleID = InteractibleID(data=()), _persistent_state: MappingProxyType = mappingproxy({}), _persistent_selected_id: MappingProxyType = mappingproxy({}))[source]¶
A data structure storing and managing keyboard navigation and mouse data.
- property active_id¶
The interactible that is active through keyboard navigation.
- Returns:
EMPTY_INTERACTIBLEif no interactible is active
- areas: MappingProxyType = mappingproxy({})¶
All areas that were marked by an
interaction_areawrapper node.
- is_active(key: InteractibleID) → bool[source]¶
Whether an interactible or one of its descendants is active via keyboard navigation
- is_held_down(key: InteractibleID) → bool[source]¶
Whether
SELECT_VIA_MOUSE_STARTwas triggered while hovering over interactive or its descendant, but beforeSELECT_VIA_MOUSE_ENDis triggered.
- is_hover(key: InteractibleID) → bool[source]¶
Whether the mouse is hovering above an interactible or one of its descendants.
Note
Only one interactible at a time can be hovered, so if there is an overlap between interactible areas, only one of them will return true.
- is_selected(key: InteractibleID) → bool[source]¶
Whether an interactible was selected by keyboard or mouse.
This condition if often triggered by pressing enter while an interactible is active through keyboard navigation, or by releasing left click on an interactible with a mouse.
More specifically, this returns whether an interactible is active and
SELECT_VIA_KEYBOARDwas triggered OR an interactible is hovered andSELECT_VIA_MOUSE_ENDwas triggered
- update(res: Result | None = None, action: NavAction | None = None, nav_tree: list[InteractibleID] | None = None, mouse_position: Coordinate | None = None)[source]¶
Create a new NavState based on data and user input.
- Parameters:
res – Result created from a
Layoutbeing renedered.action – User input parsed as an action.
nav_data – The keyboard navigation tree that is used to perform keyboard navigation based on the action. InteractibleID’s must be defined in order.
mouse_position – Mouse position.
- Returns:
A new NavState with keyboard navigation and mouse interactivity performed.
- functui.nav.ROOT_HORIZONTAL = InteractibleID(data=(InteractibleIDPart(direction=<Direction.HORIZONTAL: 2>, local_id=0, persistent=False, first_child_default=False),))¶
A Root for a keyboard navigation tree who’s children are navigated horizontaly.
- functui.nav.ROOT_VERTICAL = InteractibleID(data=(InteractibleIDPart(direction=<Direction.VERTICAL: 1>, local_id=0, persistent=False, first_child_default=False),))¶
A Root for a keyboard navigation tree who’s children are navigated vertically.
- functui.nav.interaction_area(interactible_id: InteractibleID, dragable=False)[source]¶
A wrapper node that marks its child layout as interactive.
Meant to be used along with
NavState.This wrapper node also retrieves at which size and position child layout was rendered at. This allows mouse hover detection, and in a scrollable container, automatically scrolling to a child that became active through keyboard navigation.
- functui.nav.v_scroll(container_id: InteractibleID, nav: NavState)[source]¶
Allow vertical scrolling if child does not fit into available space.