Kanzi 3.9.10
kanzi::FocusManager Class Reference

Focus Manager enables you to set and change the key focus between attached nodes. More...

#include <kanzi/core.ui/input/focus_manager.hpp>

Classes

class  FocusEnteredFocusScopeMessageArguments
 Message arguments used by the FocusEnteredFocusScopeMessage. More...
 
class  FocusLeftFocusScopeMessageArguments
 Message arguments used by the FocusLeftFocusScopeMessage. More...
 
class  InputOutsideOverlayMessageArguments
 Message arguments used by the InputOutsideOverlayMessage. More...
 
class  MoveFocusMessageArguments
 Message arguments used by the focus move messages. More...
 
class  OverlayBroughtToFrontMessageArguments
 Message arguments used by the OverlayBroughtToFrontMessage. More...
 
class  OverlayGainedFocusMessageArguments
 Message arguments used by the OverlayGainedFocusMessage. More...
 
class  OverlayLostFocusMessageArguments
 Message arguments used by the OverlayLostFocusMessage. More...
 
class  OverlaySentToBackMessageArguments
 Message arguments used by the OverlaySentToBackMessage. More...
 
class  PostFocusMessageArguments
 
class  PreFocusMessageArguments
 Message arguments for the pre-focus messages. More...
 
class  ScopeStateChangeMessageArguments
 Base message argument class for the focus scope state change message arguments. More...
 

Public Types

using FocusChainDirection
 Specifies the direction of the focus move.
 
using FocusReason
 Specifies the reason the node is focused.
 
using FocusScopeType
 Specifies the type of the focus scope.
 

Public Member Functions

void attach (Screen &screen)
 Attaches a screen node to a focus manager.
 
KZ_DEPRECATED FocusScopePtr createFocusScopeInfo (Node &rootNode)
 Creates a focus scope info with the rootNode as the focus scope node.
 
void detach (Screen &screen)
 Detaches a screen node from an focus manager.
 
 FocusManager ()
 Creates a FocusManager instance.
 
NodeSharedPtr getFocus () const
 Returns the key focus node of the application.
 
OverlayScopegetFocusedOverlay () const
 Returns the focused overlay focus scope.
 
OverlayScopegetForemostOverlay () const
 Returns the foremost overlay focus scope.
 
NodeSharedPtr getForemostOverlayNode () const
 Returns the root node of the foremost overlay focus scope.
 
OverlayScopegetOverlayBelow (const OverlayScope &scope) const
 Returns the overlay focus scope that precedes in the overlay scope stack the overlay focus scope that you pass as an argument.
 
void removeFocus ()
 Removes key focus from the application by removing the focused status from the focused node.
 
KZ_DEPRECATED NodeSharedPtr tryMoveActiveFocus (kanzi::FocusChainDirection direction)
 
KZ_DEPRECATED NodeSharedPtr tryMoveActiveFocus (ModalScope &popupScope, kanzi::FocusChainDirection direction)
 Tries to set the focus to a node relative to the current key focus node of the overlay focus scope passed as an argument using the focus chain navigation.
 
NodeSharedPtr tryMoveFocus (kanzi::FocusChainDirection direction)
 Tries to set the focus to a node relative to the current key focus node of the application using the focus chain navigation.
 
NodeSharedPtr tryMoveFocus (OverlayScope &overlayScope, kanzi::FocusChainDirection direction)
 Tries to set the focus to a node relative to the current key focus node of the overlay focus scope passed as an argument using the focus chain navigation.
 
NodeSharedPtr tryMoveFocusBackward ()
 The method is a specialization of the tryMoveFocus(FocusChainDirection) moving and moves the focus from the current key focus node in the backward direction.
 
NodeSharedPtr tryMoveFocusForward ()
 The method is a specialization of the tryMoveFocus(FocusChainDirection) method and moves the focus from the current key focus node in the forward direction.
 
NodeSharedPtr tryMoveFocusInScope (FocusScope &scope, kanzi::FocusChainDirection direction)
 Tries to set the focus to a node relative to the current key focus node of the focus scope using the focus navigation.
 
KZ_DEPRECATED NodeSharedPtr trySetActiveFocus (ModalScope &popupScope, NodeSharedPtr newFocusNode, kanzi::FocusReason reason)
 Tries to set the focus on an overlay focus scope.
 
KZ_DEPRECATED NodeSharedPtr trySetActiveFocus (NodeSharedPtr newFocusNode)
 An overload of trySetActiveFocus() using FocusReason::Force to move the focus.
 
KZ_DEPRECATED NodeSharedPtr trySetActiveFocus (NodeSharedPtr newFocusNode, kanzi::FocusReason reason)
 Tries to set the focus node of the foremost overlay focus scope to the newFocusNode and specifies the reason for moving the focus.
 
NodeSharedPtr trySetFocus (NodeSharedPtr newFocusNode)
 Tries to set the focus to the newFocusNode.
 
NodeSharedPtr trySetFocus (NodeSharedPtr newFocusNode, FocusFallback fallbackOption)
 Tries to set the focus to the newFocusNode using trySetFocus() but with a fallback behavior in case the node does not gain focus.
 

Static Public Member Functions

static PropertyTypeEditorInfoSharedPtr makeEditorInfo ()
 Creates the property editor info for the FocusManager.
 

Friends

class Node
 
class OverlayScope
 

Messages

Message arguments for post-focus messages.

Contains the reason the focus move is initiated.

Since
Kanzi 3.7.0
using ScopeBroughtToFrontMessageArguments
 
using ScopeSentToBackMessageArguments
 
static MessageType< PreFocusMessageArgumentsAboutToLoseFocusMessage
 The message dispatched to the key focus node and its ascendants before losing focus.
 
static MessageType< PreFocusMessageArgumentsAboutToGainFocusMessage
 The message dispatched to the next focusable node.
 
static MessageType< PostFocusMessageArgumentsFocusLostMessage
 Informs the old key focus node about losing the focus.
 
static MessageType< PostFocusMessageArgumentsFocusGainedMessage
 Informs the new key focus node about getting the focus.
 
static MessageType< OverlayBroughtToFrontMessageArgumentsOverlayBroughtToFrontMessage
 Kanzi dispatches this message when an overlay scope becomes the foremost overlay scope.
 
static MessageType< ScopeBroughtToFrontMessageArgumentsScopeBroughtToFrontMessage
 Kanzi dispatches this message when an overlay scope becomes the foremost overlay scope.
 
static MessageType< OverlaySentToBackMessageArgumentsOverlaySentToBackMessage
 Kanzi dispatches this message when an overlay scope is no longer the foremost overlay scope.
 
static MessageType< ScopeSentToBackMessageArgumentsScopeSentToBackMessage
 Kanzi dispatches this message when an overlay scope is no longer the foremost overlay scope.
 
static MessageType< FocusEnteredFocusScopeMessageArgumentsFocusEnteredFocusScopeMessage
 When focus enters a focus scope, Kanzi sends this message to the focus scope node that contains the node which gains focus.
 
static MessageType< FocusLeftFocusScopeMessageArgumentsFocusLeftFocusScopeMessage
 When focus leaves a focus scope, Kanzi sends this message to the focus scope node that contains the node which loses focus.
 
static MessageType< OverlayGainedFocusMessageArgumentsOverlayGainedFocusMessage
 When an overlay scope gains focus, Kanzi sends this message to the overlay scope node that contains the node which gains focus.
 
static MessageType< OverlayLostFocusMessageArgumentsOverlayLostFocusMessage
 When an overlay scope loses focus, Kanzi sends this message to the overlay scope node that contains the node which loses focus.
 
static MessageType< MoveFocusMessageArgumentsMoveScopeFocusForwardMessage
 A focus scope node handles this message to move the focus to the next focusable node of the focus scope in forward direction.
 
static MessageType< MoveFocusMessageArgumentsMoveScopeFocusBackwardMessage
 A focus scope node handles this message to move the focus to the next focusable node of the focus scope in backward direction.
 
static MessageType< InputOutsideOverlayMessageArgumentsInputOutsideOverlayMessage
 Kanzi dispatches this message when an input event occurs outside of an overlay scope node area.
 

Properties

static PropertyType< FocusOnPressFocusOnPressProperty
 Sets where to set the focus when the user presses a node that has this property.
 
static PropertyType< intFocusOrderProperty
 Sets the focus chain order of the node to which the property is attached.
 
static PropertyType< boolCyclicFocusNavigationProperty
 Sets whether the focus chain navigation is cyclic in a focus scope.
 
static PropertyType< FocusScopeTypeFocusScopeTypeProperty
 Sets the focus scope type of the node to which this property is attached.
 
static FocusOnPress getFocusOnPress (const Node &node)
 Gets the value of FocusOnPressProperty.
 
static void setFocusOnPress (Node &node, FocusOnPress focusOnPress)
 Set the value of the FocusOnPressProperty.
 
static size_t getFocusOrder (const Node &node)
 Returns the value of the FocusOrderProperty.
 
static void setFocusOrder (Node &node, size_t index)
 Sets the value of the FocusOrderProperty.
 
static void clearFocusOrder (Node &node)
 Clears the local value of the FocusOrderProperty.
 
static bool getCyclicFocusNavigation (const Node &node)
 Returns the value of the CyclicFocusNavigationProperty.
 
static void setCyclicFocusNavigation (Node &node, bool cyclic)
 Sets the value of the CyclicFocusNavigationProperty.
 
static void clearCyclicFocusNavigation (Node &node)
 Clears the local value of the CyclicFocusNavigationProperty.
 
static FocusScopeType getFocusScopeType (const Node &node)
 Returns the value of the FocusScopeTypeProperty.
 
static void setFocusScopeType (Node &node, FocusScopeType type)
 Sets the value of the FocusScopeTypeProperty.
 
static KZ_DEPRECATED bool isFocusScope (const Node &node)
 If a node has the FocusScopeTypeProperty attached, returns whether that node is a focus scope.
 
static KZ_DEPRECATED void setFocusScope (Node &node, bool isScope)
 Sets the value of the FocusScopeTypeProperty property for a node to set that node to either become or not become a focus scope.
 
static KZ_DEPRECATED bool isFocusFence (const Node &node)
 If a node has the FocusScopeTypeProperty attached, returns whether that node is a focus fence.
 
static KZ_DEPRECATED void setFocusFence (Node &node, bool isFence)
 Sets the value of the FocusScopeTypeProperty property for a node to set that node to either become or not become a focus fence.
 

Detailed Description

Focus Manager enables you to set and change the key focus between attached nodes.

Each domain can have only one instance of a Focus Manager.

Focusable node

A focusable node is a node that is attached to the scene graph and has the Node::FocusableProperty set to true. Kanzi can set focus only to focusable nodes. When a node has the Node::FocusableProperty set to false, Kanzi excludes that node from the focus management. This is the default setting.

Key focus node

The key focus node of an application is the node that receives all the key input, and has the read-only Node::FocusedProperty set to true. Kanzi controls the value of the Node::FocusedProperty internally. Changing the value of the property does not set the key focus node. To set the key focus node, use trySetFocus() or tryMoveFocus() or one of its variants.

Focus chain and focus order

A focus chain is the sequence of nodes that defines the order in which Kanzi applies focus to nodes when the application user moves the focus in a focus scope using the focus chain navigation methods. Each focus scope node has its own focus chain.

To set the order of a node in a focus chain, use the FocusOrderProperty. When you do not set the value of the FocusOrderProperty, the node tree order determines the order of the node in a focus chain.

Focus scopes

Kanzi organizes nodes in focus scopes. Focus scopes are nodes which assist in focus chain navigation handling. Focus scopes group their child nodes and drive the focus navigation within that group. They also act like a focus proxy, forwarding the focus to one of their focusable child nodes.

When a focus scope receives focus, Kanzi tries to move the focus to the last-focused node of the focus scope. If focus has not yet visited the focus scope, Kanzi tries to focus:

  • The first focusable node of the focus chain, if the reason the focus scope receives the focus is not backward focus chain navigation.

    The first focusable node is either the node with the smallest value of the FocusOrderProperty, or the first node in the node tree of the focus scope.

  • The last focusable node of the focus chain, if the focus scope receives the focus because of backward focus chain navigation.

    The last focusable node is either the node with the largest value of the FocusOrderProperty, or the last node in the node tree of the focus scope.

When you move the focus away from a focus scope, that scope remembers its last-focused child node.

For more details on focus navigation with scopes, see Setting focus to focus scope nodes and focus navigation in focus scopes.

Focus scope types

Kanzi defines these focus scope types:

  • Focus group groups focusable nodes. This is the simplest type of focus scope. You can move the focus to the focus group and out of the focus group.

    To make a node a focus group, in that node set the FocusScopeTypeProperty to FocusScopeType::Group.

  • Focus fence keeps the focus navigation inside the scope and does not allow the focus navigation to enter or leave that scope.

    To make a node a focus fence, in that node set the FocusScopeTypeProperty to FocusScopeType::Fence.

  • Overlay focus scope types:

    • Modal overlay blocks the key and touch input that originates from outside its boundaries and keeps the focus navigation within the overlay boundaries, just like a focus fence. Every Kanzi application has at least one modal overlay: the Screen node.

      To make a node a modal overlay, in that node set the FocusScopeTypeProperty to FocusScopeType::Modal.

    • Modeless overlay propagates the key and touch input that originates from outside its boundaries, but keeps the focus navigation within the focus scope boundaries, just like a modal overlay.

      To make a node a modeless overlay, in that node set the FocusScopeTypeProperty to FocusScopeType::Modeless.

    • Auto-closing modal overlay is similar to modal overlay, except that when the overlay is an Activity in a Parallel Activity Host, the Parallel Activity Host deactivates that Activity when user input originates from outside the boundaries of that Activity.

      To make a node an auto-closing modal overlay, in that node set the FocusScopeTypeProperty to FocusScopeType::AutoClosingModal.

    • Auto-closing modeless overlay is similar to modeless overlay, except that when the overlay is an Activity in a Parallel Activity Host, the Parallel Activity Host deactivates that Activity when:

      • User input originates from outside the boundaries of that Activity.
      • Focus moves to an overlay that is behind that Activity.

      To make a node an auto-closing modal overlay, in that node set the FocusScopeTypeProperty to FocusScopeType::AutoClosingModeless.

    One overlay at a time can be the focused overlay. The focus node of the focused overlay is the key focus node of the application and receives key input.

    The focus node of an overlay that is currently not the focused overlay is the logical focus node of that overlay. This node was the key focus node before the overlay lost focus. Once the overlay regains focus, the logical focus node becomes the key focus node of the application.

    When user input originates from a node that is outside the node tree of an overlay focus scope, that overlay focus scope sends the InputOutsideOverlayMessage message. A Parallel Activity Host automatically handles the InputOutsideOverlayMessage message sent by an Activity which is an auto-closing overlay. For an overlay focus scope node that is not an Activity you can handle the InputOutsideOverlayMessage message manually. For example, you can make a modeless overlay invisible when user input originates from outside its boundaries.

    An overlay focus scope has no parent focus scope.

Nesting focus scopes

Kanzi organizes nodes in a tree of nodes and organizes focus scopes in the same tree. This enables you to create focus scopes inside focus scopes, that is, nested focus scopes. A nested focus scope behaves the same way as any other focus scope: it forwards and remembers the focus of its child node the same way, regardless of its nested state. When the last-focused node of a focus scope is a nested focus scope, if the nested focus scope is a focus group or a focus fence, Kanzi forwards the focus to the last-focused node of that focus group or focus fence.

Kanzi does not include the nested overlay focus scopes from the focus chain, and does not remember these overlay scope nodes as last-focused nodes. To learn how Kanzi handles these scope types, see Overlay focus scope stack and input delivery.

Setting focus

To set focus to a node:

  1. In the node set these properties:
  2. Attach the node to the node tree of a focus scope that is either the foremost modal overlay in your application or a modeless overlay on top of the foremost modal overlay.

    For example, attach the node to the Screen or a Viewport2D node.

    Kanzi can set focus to a node that is in the process of being attached to the node tree, but not to a node that is not attached to the node tree.

  3. Use one of the trySetFocus() methods to set focus to the node.

To set focus to a node:

auto node = EmptyNode2D::create(getDomain(), "empty");
node->setFocusable(true);
// Attach the node you created to the root node.
rootNode->addChild(node);
// Set the focus to the node you attached to the root node.
getTestScreen()->getFocusManager()->trySetFocus(node);

Getting focus

To retrieve the node that has the key focus, use the getFocus() method.

Kanzi uses these properties to indicate if a node is the focus node of an overlay or if a focus scope contains the focus node of an overlay:

  • Node::FocusedProperty reports whether a node has the key focus and receives key input. Only one node in an application can have this property set to true at a time.
  • Node::FocusStateProperty when set to FocusState::LogicalFocus indicates that the node is the logical focus node of an overlay that is currently not the focused overlay. The logical focus node gets the key focus when the overlay, to which the node belongs, regains the focus.
  • Node::FocusStateProperty in a focus scope node can have these values:
    • FocusState::NoFocus indicates that none of the nodes in that scope have focus.
    • FocusState::LogicalFocus indicates that one of the nodes in that scope is the logical focus node of the overlay to which the scope belongs.
    • FocusState::KeyFocus indicates that one of the nodes in that scope is the key focus node of the overlay to which the scope belongs.

For example, you can use the Node::FocusedProperty or Node::FocusStateProperty in a binding or as a controller property in a state manager to change the look and behavior of the node that has the key focus or is the logical focus of an overlay.

The impact of the Node::VisibleProperty on the focused node

When you hide a node that has focus, by setting the Node::VisibleProperty to false:

  1. The Focus Manager dispatches the FocusLostMessage with FocusReason::Hidden and the application loses the focus.
  2. Kanzi clears the last-focused node information of all ascendant focus scopes of the node that you hid.

You cannot set the focus to a hidden node.

// Create a Button2D node, and attach it to the root node. Buttons are focusable by default.
auto button = Button2D::create(getDomain(), "first button");
rootNode->addChild(button);
button->trySetFocus();
// Handle Focus Lost message.
auto onFocusLost = [](auto& args)
{
if (args.getFocusReason() == FocusReason::Hidden)
{
// ...
}
};
button->addMessageHandler(FocusManager::FocusLostMessage, onFocusLost);
// Hide the button. This triggers Focus Lost message with FocusReason::Hidden.
button->setVisible(false);

The impact of the Node::EnabledProperty on the focused node

When you disable a node that has focus, by setting the Node::EnabledProperty to false, the Focus Manager keeps the focus on that node and continues to deliver input events to its attached Input Manipulators. UI nodes are responsible for checking their enabled state when receiving input events, and deciding whether to handle those events. You cannot set focus to a disabled node.

Focus chain navigation

Unless you want to override the default behavior, or you want to provide other triggers to move the focus across the nodes, you do not need to care about the default key navigation. You can override the default key navigation by customizing the FocusNavigationManipulator installed on the focus scope, or setting your own focus navigation manipulator to the focus scope. Other means of focus chain navigation you can use are actions that are triggered by property changes, state changes on nodes, and so on.

The default chain navigation keys are the Tab and BackTab keys. The forward direction navigates the focus from the node with smaller value of the attached FocusOrderProperty to the nodes with higher value of the attached FocusOrderProperty, while backwards direction navigates the focus in the opposite direction.

Kanzi restricts the focus chain navigation to within a specific overlay focus scope and, when performing focus chain navigation, skips the nested focus fences, the focus groups with empty focus chain, and overlay focus scopes.

Kanzi automatically includes in the focus chain all nodes in a focus scope that have the Node::FocusableProperty, Node::EnabledProperty, and Node::VisibleProperty set to true. To move the focus to the next node in the focus chain, call the tryMoveFocus() method or one of its overrides.

When Tab and BackTab keys are functional keys of a node, that node consumes the keys used by the focus chain navigation. When such node receives focus, the Focus Manager is no longer able to move the focus from that node through the key input events. To use keys to move focus from such node, you must install a FocusNavigationManipulator to that node, and set custom keys to move the focus from the node.

To move focus in focus chain from a node that consumes the Tab and BackTab keys:

class TabConsumerNode;
typedef shared_ptr<TabConsumerNode> TabConsumerNodeSharedPtr;
// This example contains a node to which the user can set focus using the Tab and BackTab keys.
// However, the normal use of this node consumes the Tab and BackTab keys, so the user cannot
// use these same keys to move the focus to another node. This example shows how to set the
// Ctrl+Tab and Ctrl+BackTab keys to move the focus forward and backward in the focus chain.
class TabConsumerNode : public Node2D
{
public:
// Create the node.
static TabConsumerNodeSharedPtr create(Domain* domain, string_view name)
{
TabConsumerNodeSharedPtr node(new TabConsumerNode(domain, name));
node->initialize();
return node;
}
protected:
explicit TabConsumerNode(Domain* domain, string_view name) :
Node2D(domain, name),
// The node is focusable by default.
m_focusable(*this, FocusableProperty, true)
{
}
void onAttached() override
{
Node2D::onAttached();
// The focus navigation manipulator to use different keys to move the focus. Use Ctrl+Tab to move
// forward and Ctrl+BackTab to move backward.
auto focusManipulator = FocusNavigationManipulator::create(getDomain());
focusManipulator->setFocusNavigationKey(FocusChainDirection::Next, LogicalKey::Tab, KeyModifier::Control);
focusManipulator->setFocusNavigationKey(FocusChainDirection::Previous, LogicalKey::BackTab, KeyModifier::Control);
addInputManipulator(focusManipulator);
// The key manipulators and message handler to capture Tab and BackTab key sequences.
auto backtabManipulator = KeyManipulator::create(getDomain());
backtabManipulator->setKey(LogicalKey::BackTab);
addInputManipulator(backtabManipulator);
auto tabManipulator = KeyManipulator::create(getDomain());
tabManipulator->setKey(LogicalKey::Tab);
addInputManipulator(tabManipulator);
(void)addMessageHandler(KeyManipulator::KeyPressedMessage, this, &TabConsumerNode::handleKeyPressedMessages);
}
// Handle the Tab and Shift+Tab keys.
void handleKeyPressedMessages(KeyManipulator::KeyPressedMessageArguments& /*arguments*/)
{
// Consume the Tab and Shift + Tab keys and mark the message handled.
}
private:
ClassPropertyDefaultValue<bool> m_focusable;
};

Setting focus to focus scope nodes and focus navigation in focus scopes

When you set the focus to a focus scope node, Kanzi tries to restore the focus on the last-focused node of the focus scope.

When you set the focus to a focus scope node using the tryMoveFocusBackward() method, and the focus scope has no last-focused node remembered, Kanzi tries to move the focus to the last focusable node of the focus chain of the focus scope.

When you set the focus to a focus scope node using trySetFocus() or any other variant of the tryMoveFocus() methods, and the focus scope has no last-focused node remembered, Kanzi tries to move the focus to the first focusable node of the focus chain of the focus scope.

To set the focus on the last focusable child node of a scope:

// Create an EmptyNode2D node, make it a focus scope, and attach it to the root node.
auto scopeNode = EmptyNode2D::create(getDomain(), "Scope");
scopeNode->setFocusable(true);
FocusManager::setFocusScopeType(*scopeNode, FocusScopeType::Group);
rootNode->addChild(scopeNode);
// Add a few Button nodes as child nodes of the scope.
auto button1 = Button2D::create(getDomain(), "First button");
auto button2 = Button2D::create(getDomain(), "Second button");
auto button3 = Button2D::create(getDomain(), "Third button");
scopeNode->addChild(button1);
scopeNode->addChild(button2);
scopeNode->addChild(button3);
// Set the button2 node as the last-focused node of the scope.
setScopeFocusedNode(*scopeNode, *button2);
// When you force the focus on the scope, the focus manager forwards the focus
// to the button2 node.
auto focus = getTestScreen()->getFocusManager()->trySetFocus(scopeNode);
if (focus == button2)
{
kzLogDebug(("button2 is the focus."));
}

When you move the focus out from a focus scope, the focus scope remembers the focus state of its last-focused node. This way when you return the focus to the focus scope using the trySetFocus() or tryMoveFocus() method, Kanzi restores the focus on this node, unless the last-focused node is detached from the UI scene.

To move the focus back to the last-focused node of a focus scope:

// Following the previous code example, which shows how to set the focus on the last
// focusable child node of a scope, add a Button node outside of the scope node.
auto outerButton = Button2D::create(getDomain(), "Outer button");
rootNode->addChild(outerButton);
// Move the focus to the Button node you just created.
focus = getTestScreen()->getFocusManager()->trySetFocus(outerButton);
if (focus == outerButton)
{
kzLogDebug(("button2 is no longer the focus."));
// Move the focus back to the scope and observe that the focus manager forwards the
// focus to the button2 node.
focus = getTestScreen()->getFocusManager()->trySetFocus(scopeNode);
if (focus == button2)
{
kzLogDebug(("button2 is the focus again."));
}
}

When you set the focus to a focus scope using the focus chain navigation methods, such as tryMoveFocus() and its overrides, the focus scope forwards the focus to its last-focused child node. Further calls on the method move the focus in the direction specified, to the next or previous node in the focus chain, including nested focus scopes.

// Move the focus out from the scope.
focus = getTestScreen()->getFocusManager()->trySetFocus(outerButton);
if (focus != button2)
{
// Navigate on the focus chain in backward direction from the
// focus node.
getTestScreen()->getFocusManager()->tryMoveFocusBackward();
}

When a node gets focus, all its ascendant focus scopes get their focus state set to true. The focus scopes keep the focus state as long as the focus node remains in their scope. When you move the focus away from a node, all its ascendant focus scopes get their focus state set to false.

This example shows this scenario:

// Make root node a focus scope.
rootNode->setFocusable(true);
FocusManager::setFocusScopeType(*rootNode, FocusScopeType::Group);
// Create an EmptyNode2D node and make it a focus scope.
auto scopeNode = EmptyNode2D::create(getDomain(), "Scope");
scopeNode->setFocusable(true);
FocusManager::setFocusScopeType(*scopeNode, FocusScopeType::Group);
rootNode->addChild(scopeNode);
// Add a Button2D node to the first level of the focus scope.
auto button1 = Button2D::create(getDomain(), "first level button");
scopeNode->addChild(button1);
// Create a nested focus scope.
auto nestedScopeNode = EmptyNode2D::create(getDomain(), "Nested scope");
nestedScopeNode->setFocusable(true);
FocusManager::setFocusScopeType(*nestedScopeNode, FocusScopeType::Group);
scopeNode->addChild(nestedScopeNode);
// Add two buttons to the nested focus scope.
auto button2 = Button2D::create(getDomain(), "second level button1");
auto button3 = Button2D::create(getDomain(), "second level button2");
nestedScopeNode->addChild(button2);
nestedScopeNode->addChild(button3);
// Add a button to the root node.
auto outerButton = Button2D::create(getDomain(), "non-scoped button");
rootNode->addChild(outerButton);
// Force focus to button2 from the nested scope.
auto focus = getTestScreen()->getFocusManager()->trySetFocus(button2);
// Both scopes contain the key focus.
if (scopeNode->getFocusState() == FocusState::KeyFocus && nestedScopeNode->getFocusState() == FocusState::KeyFocus)
{
kzLogDebug(("scope and its nested scope contains focus."));
}
// Set focus to the button in the root node.
getTestScreen()->getFocusManager()->trySetFocus(outerButton);
// Observe the focused state is lost in both the outer and inner focus scope.
if (!scopeNode->isFocused() && !nestedScopeNode->isFocused() && nestedScopeNode->getFocusScopeInfo()->getLastFocused())
{
kzLogDebug(("nested scope preserved its last-focused node."));
}

Kanzi skips focus scopes in the focus chain navigation, because a focus scope does not get focus as long as it has child nodes that can get focus. The child nodes of a focus scope node that is hidden or disabled cannot get focus. You can exclude a focus scope node from the focus chain by setting either the Node::EnabledProperty or the Node::VisibleProperty to false.

You can route the default focus chain navigation in the same way as regular focus nodes. In that case, focus chain navigation follows the routed nodes and focuses the nodes or focus scopes routed when the focus navigation leaves the focus scope:

  • In the forward navigation after the last node of the focus chain is visited
  • In the backward navigation after the first node of the focus chain is visited

Use a focus fence (FocusScopeType::Fence) when you want to keep the focus chain navigation within the boundaries of a focus scope.

Kanzi keeps the focus chain navigation inside a focus fence and skips fences when the focus chain navigation happens outside of those focus fences. Kanzi also ignores the focus routing to focus fences. You can move the focus from within a focus fence to a node outside of the focus fence, and the other way around, only using the trySetFocus() method.

This example shows the focus fence behavior:

// Add a button to the top level.
auto outerButton = Button2D::create(getDomain(), "non-scoped button");
rootNode->addChild(outerButton);
// Create a scope with a nested scope. Make the outer scope a fence.
auto fenceNode = EmptyNode2D::create(getDomain(), "Scope");
FocusManager::setFocusScopeType(*fenceNode, FocusScopeType::Fence);
rootNode->addChild(fenceNode);
// Add a button to the first level of the scope.
auto button1 = Button2D::create(getDomain(), "first level button");
fenceNode->addChild(button1);
// Create a nested scope
auto nestedScopeNode = EmptyNode2D::create(getDomain(), "Nested scope");
FocusManager::setFocusScopeType(*nestedScopeNode, FocusScopeType::Group);
fenceNode->addChild(nestedScopeNode);
// Add two buttons to the nested scope.
auto button2 = Button2D::create(getDomain(), "second level button1");
auto button3 = Button2D::create(getDomain(), "second level button2");
nestedScopeNode->addChild(button2);
nestedScopeNode->addChild(button3);
// Force focus on outerButton and navigate forward to try to enter the scope.
auto focus = getTestScreen()->getFocusManager()->trySetFocus(outerButton);
focus = getTestScreen()->getFocusManager()->tryMoveFocusForward();
// Observe the focus stays on the button because the next node is a fence.
if (!focus)
{
// Move focus inside the fence. The focus is moved into the fence because
// the reason was not the focus chain navigation.
focus = getTestScreen()->getFocusManager()->trySetFocus(button1);
}
if (focus == button1)
{
// Move forward. Observe the focus moves to button2 and button3.
getTestScreen()->getFocusManager()->tryMoveFocusForward();
kzLogDebug(("the focus is in the fence on node '{}'", getTestScreen()->getFocusManager()->getFocus()->getName()));
focus = getTestScreen()->getFocusManager()->tryMoveFocusForward();
kzLogDebug(("the focus is in the fence on node '{}'", getTestScreen()->getFocusManager()->getFocus()->getName()));
// The next move keeps the focus on button3 because it reached the fence boundaries.
focus = getTestScreen()->getFocusManager()->tryMoveFocusForward();
kzLogDebug(("the focus is in the fence on node '{}'", getTestScreen()->getFocusManager()->getFocus()->getName()));
}

Overlay focus scope stack and input delivery

By default, Kanzi delivers touch input to all nodes in an overlay focus scope, including the nested focus scopes that are not overlay focus scopes. Kanzi keeps track of the overlay focus scopes of an application that are attached to the node tree, and organizes them in the form of a stack. If the foremost overlay focus scope is a modeless overlay, Kanzi delivers the touch input that occurs outside of the foremost overlay focus scope boundaries to the overlay focus scopes that precede the foremost overlay scope.

When Kanzi detects touch input that originates outside an overlay scope, it sends the InputOutsideOverlayMessage message. To enable Kanzi to detect the origin of the touch input, you must set the Node::HitTestableProperty to true on the overlay scopes.

Kanzi delivers the key input to the foremost overlay scope first. If the foremost overlay scope does not consume the key input, and that scope is a modeless overlay, Kanzi propagates the key input to the overlay scopes that precede the foremost overlay scope. If the key is handled in one of the propagated overlay scopes, and the scope is a modeless overlay, Kanzi sends the InputOutsideOverlayMessage message.

When you attach an overlay scope node to the UI scene, Kanzi inserts that overlay scope to the overlay scope stack according to the rendering order of the nodes in the UI scene. The overlay scope receives:

When you hide an overlay scope node by setting Node::VisibleProperty to false on that node, Kanzi removes the overlay focus scope from the focus scope stack. When the overlay scope node is made visible again, Kanzi adds the overlay focus scope back to the focus scope stack.

To create a modal overlay node:

class ModalNode;
typedef shared_ptr<ModalNode> ModalNodeSharedPtr;
// A modal overlay node, which shows itself when brought to front, and hides when sent to back.
class ModalNode : public EmptyNode2D
{
public:
// Create the node.
static ModalNodeSharedPtr create(Domain* domain, string_view name)
{
ModalNodeSharedPtr popup = make_polymorphic_shared_ptr<EmptyNode2D>(new ModalNode(domain, name));
popup->initialize();
return popup;
}
private:
// Construct the node. Define the scope type as modal.
explicit ModalNode(Domain* domain, string_view name) :
EmptyNode2D(domain, name),
m_focusScopeDefaultValue(*this, FocusManager::FocusScopeTypeProperty, FocusManager::FocusScopeType::Modal),
m_focusableDefaultValue(*this, Node::FocusableProperty, true)
{
}
void onScopeToBack(FocusManager::OverlaySentToBackMessageArguments&)
{
setVisible(false);
}
void initialize()
{
EmptyNode2D::initialize();
addMessageHandler(FocusManager::OverlaySentToBackMessage, this, &ModalNode::onScopeToBack);
}
// The default overlay scope type of the Node.
ClassPropertyDefaultValue<FocusManager::FocusScopeType> m_focusScopeDefaultValue;
ClassPropertyDefaultValue<bool> m_focusableDefaultValue;
};

To bring an overlay focus scope to front:

auto modalNode = ModalNode::create(getDomain(), "Modal node");
// Attach the modalNode to the node tree. This brings the overlay scope to front.
rootNode->addChild(modalNode);

To send an overlay focus scope back:

When you detach an overlay focus scope node from the node tree, Kanzi removes that overlay focus scope from the FocusManager. When Kanzi removes an overlay focus scope from the FocusManager, it marks that focus scope as detached. A detached overlay focus scope remembers its last-focused node.

When you attach a detached overlay focus scope node to the node tree, if that overlay scope becomes the foremost overlay scope, Kanzi restores the focus of that overlay scope.

Cyclic focus navigation

When you move the focus forward or backward in a focus scope, and the focus reaches the last or first focusable node of the focus scope, Kanzi looks for the sibling of the focus scope to continue the focus chain navigation. When Kanzi cannot find a focus candidate in an overlay focus scope in the navigation direction, Kanzi by default keeps the focus on the last focused node. To enable cyclic focus navigation, attach the CyclicFocusNavigationProperty to the focus scope node, and set the property value to true.

In cyclic focus navigation:

  • When during forward focus navigation the focus reaches the last focusable UI element of the focus scope, focus navigation moves from there to the first focusable UI element.
  • When during backward focus navigation the focus reaches the first focusable UI element of the focus scope, focus navigation moves from there to the last focusable UI element.

You can enable cyclic focus navigation for any focus scope node. When you enable cyclic focus navigation, the focus chain navigation never leaves the boundaries of the focus scope.

Focus change notifications

Kanzi uses focus change notification messages to inform UI nodes about changes in the application focus and focus scope type of nodes. The set of messages that Kanzi dispatches depends on which focus action caused the change.

Kanzi dispatches these messages to notify nodes about focus changes:

Each message contains an argument that specifies the reason of the focus change.

Kanzi dispatches different sets of messages depending on the type of change:

  • Focus scope related messages only when there is a change in the currently focused focus scope.
  • Overlay related messages only when there is a change in the currently focused overlay.
  • OverlayBroughtToFrontMessage and OverlaySentToBackMessage only when there is a change in the foremost overlay focus scope.

These examples show how to handle the messages that Kanzi dispatches before the focus moves.

The pre-focus message handlers are:

// Handle losing focus when Tab or BackTab navigation reason is received.
static void allowLosingFocusOnOtherReason(FocusManager::PreFocusMessageArguments& arguments)
{
if (arguments.getFocusReason() == FocusReason::FocusChainNavigation)
{
// Handle the message here.
arguments.setHandled(true);
}
}
// Handle getting focus when focus chain navigation reason is received.
static void allowGainingFocusOnFocusNavigation(FocusManager::PreFocusMessageArguments& arguments)
{
if (arguments.getFocusReason() == FocusReason::FocusChainNavigation)
{
// Handle the message here.
arguments.setHandled(true);
}
}

To move focus:

// Create a Button2D node, and attach it to the root node.
auto button = Button2D::create(getDomain(), "button");
rootNode->addChild(button);
// Set the handlers for the pre-focus move messages.
auto loseToken = button->addMessageHandler(FocusManager::AboutToLoseFocusMessage, &allowLosingFocusOnOtherReason);
auto gainToken = button->addMessageHandler(FocusManager::AboutToGainFocusMessage, &allowGainingFocusOnFocusNavigation);
// Trying to set the focus to button.
getTestScreen()->getFocusManager()->trySetFocus(button);

When focus is set to a node and the application has no focus:

When focus is removed from the application:

When focus moves to a node in the same focus scope:

When focus moves to a node in a different focus scope because of trySetFocus() or tryMoveFocus() call:

When focus moves from a node in an overlay to a node in another overlay because of trySetFocus() call or because the overlay is detached:

Kanzi dispatches the OverlayGainedFocusMessage, FocusEnteredFocusScopeMessage, FocusLeftFocusScopeMessage, and OverlayLostFocusMessage only if the focused overlay or the focus scope that contains the key focus changes because of a focus change.

When there is a change in the overlay scope stack because a node was detached or attached, or its visibility changed:

  • When an overlay focus scope node, which is behind the currently focused overlay and is invisible, is made visible, Kanzi does not dispatch any focus change notifications.
  • When an overlay focus scope node is attached to be the foremost overlay but there is no application focus, and the attached overlay node has no focusable nodes, Kanzi dispatches only the OverlayBroughtToFrontMessage and OverlaySentToBackMessage.
  • When an overlay focus scope node is attached to be the foremost overlay and there is an existing application focus, Kanzi dispatches all focus change notifications:
  • When the overlay focus scope node of the foremost overlay, which holds the application focus, is detached from the node tree, Kanzi dispatches all focus change notifications:

When the Focus Scope Type of a node changes, Kanzi:

  1. Removes the application focus.
  2. Applies the scope type change.
  3. Tries to restore the focus to the previously focused node if the scope type change itself does not cause Kanzi to restore focus to a node.

The focus scope type change concerns also the case where a new focus scope type is assigned to a node. The focus scope type of a node is expected to change only while using the Kanzi Studio Preview. There should be no need to change the focus scope type of a node dynamically at runtime.

The focus scope type change determines which messages Kanzi dispatches and their order:

  • When there is no application focus and a node, which is eligible to gain focus, is set to be an overlay focus scope:
  • When the application has focus and a node which is set to be an overlay focus scope becomes the foremost overlay:
  • When the focus scope type of the focus scope that contains the focus changes from group to fence:
  • When there is no application focus and focus scope type changes from group to fence, Kanzi does not dispatch any message.
  • When there is no application focus, and focus scope type changes from one overlay type to another, Kanzi does not dispatch any message.
  • When the application focus is in an overlay whose focus scope type changes to an other overlay type:

Member Typedef Documentation

◆ FocusReason

Specifies the reason the node is focused.

◆ FocusChainDirection

Specifies the direction of the focus move.

◆ FocusScopeType

Specifies the type of the focus scope.

Since
Kanzi 3.7.0

◆ ScopeBroughtToFrontMessageArguments

◆ ScopeSentToBackMessageArguments

Constructor & Destructor Documentation

◆ FocusManager()

kanzi::FocusManager::FocusManager ( )
explicit

Creates a FocusManager instance.

Member Function Documentation

◆ attach()

void kanzi::FocusManager::attach ( Screen & screen)

Attaches a screen node to a focus manager.

Kanzi calls this method when you associate a focus manager with a Screen node.

Parameters
screenThe Screen node to attach to the focus manager.
Since
Kanzi 3.9.6

◆ detach()

void kanzi::FocusManager::detach ( Screen & screen)

Detaches a screen node from an focus manager.

Kanzi calls this method when you disassociate a focus manager from a Screen node.

Parameters
screenThe Screen node to detach from the focus manager.
Since
Kanzi 3.9.6

◆ getFocusOnPress()

static FocusOnPress kanzi::FocusManager::getFocusOnPress ( const Node & node)
static

Gets the value of FocusOnPressProperty.

Parameters
nodeA node that has the FocusOnPressProperty attached.
Returns
The value of the FocusOnPressProperty. If the node has no FocusOnPressProperty value set, returns FocusOnPress::None.
Since
Kanzi 3.9.4

◆ setFocusOnPress()

static void kanzi::FocusManager::setFocusOnPress ( Node & node,
FocusOnPress focusOnPress )
static

Set the value of the FocusOnPressProperty.

Parameters
nodeA node that has the FocusOnPressProperty attached.
focusOnPressThe value that you want to set on the FocusOnPressProperty.
Since
Kanzi 3.9.4

◆ getFocusOrder()

static size_t kanzi::FocusManager::getFocusOrder ( const Node & node)
static

Returns the value of the FocusOrderProperty.

Parameters
nodeA node that has the FocusOrderProperty attached.
Returns
The value of the FocusOrderProperty. If the node has no FocusOrderProperty value set, returns numeric_limits<size_t>::max().
Since
Kanzi 3.9.0

◆ setFocusOrder()

static void kanzi::FocusManager::setFocusOrder ( Node & node,
size_t index )
static

Sets the value of the FocusOrderProperty.

Parameters
nodeA node that has the FocusOrderProperty attached, and for which you want to set the value.
indexThe value of the FocusOrderProperty that you want to set. To remove the local value of the FocusOrderProperty from the node, use numeric_limits<size_t>::max().
Since
Kanzi 3.9.0

◆ clearFocusOrder()

static void kanzi::FocusManager::clearFocusOrder ( Node & node)
static

Clears the local value of the FocusOrderProperty.

Parameters
nodeA node that has the FocusOrderProperty attached, and for which you want to clear the local value.
Since
Kanzi 3.9.0

◆ getCyclicFocusNavigation()

static bool kanzi::FocusManager::getCyclicFocusNavigation ( const Node & node)
static

Returns the value of the CyclicFocusNavigationProperty.

Parameters
nodeA node that has the CyclicFocusNavigationProperty attached.
Returns
The value of the CyclicFocusNavigationProperty. If the node has no CyclicFocusNavigationProperty value set, returns false.
Since
Kanzi 3.9.0

◆ setCyclicFocusNavigation()

static void kanzi::FocusManager::setCyclicFocusNavigation ( Node & node,
bool cyclic )
static

Sets the value of the CyclicFocusNavigationProperty.

Parameters
nodeA node that has the CyclicFocusNavigationProperty attached, and for which you want to set the value.
cyclicThe value of the CyclicFocusNavigationProperty that you want to set.
Since
Kanzi 3.9.0

◆ clearCyclicFocusNavigation()

static void kanzi::FocusManager::clearCyclicFocusNavigation ( Node & node)
static

Clears the local value of the CyclicFocusNavigationProperty.

Parameters
nodeA node that has the CyclicFocusNavigationProperty attached, and for which you want to clear the local value.
Since
Kanzi 3.9.0

◆ getFocusScopeType()

static FocusScopeType kanzi::FocusManager::getFocusScopeType ( const Node & node)
static

Returns the value of the FocusScopeTypeProperty.

Parameters
nodeA node that has the FocusScopeTypeProperty attached.
Returns
The value of the FocusScopeTypeProperty. If the node has no FocusScopeTypeProperty value set, returns FocusScopeType::NoScope.
Since
Kanzi 3.7.0

◆ setFocusScopeType()

static void kanzi::FocusManager::setFocusScopeType ( Node & node,
FocusScopeType type )
static

Sets the value of the FocusScopeTypeProperty.

Parameters
nodeA node that has the FocusScopeTypeProperty attached and for which you want to set the value.
typeThe value of the FocusScopeTypeProperty that you want to set. To remove the local value of the FocusScopeTypeProperty from the node, use FocusScopeType::NoScope.
Since
Kanzi 3.7.0

◆ isFocusScope()

static KZ_DEPRECATED bool kanzi::FocusManager::isFocusScope ( const Node & node)
static

If a node has the FocusScopeTypeProperty attached, returns whether that node is a focus scope.

Parameters
nodeA node that has the FocusScopeTypeProperty property attached.
Returns
If the FocusScopeTypeProperty is set to FocusScopeType::Group, true, otherwise false.
Deprecated
In Kanzi 3.9.4. Use getFocusScopeType() instead.

◆ setFocusScope()

static KZ_DEPRECATED void kanzi::FocusManager::setFocusScope ( Node & node,
bool isScope )
static

Sets the value of the FocusScopeTypeProperty property for a node to set that node to either become or not become a focus scope.

Parameters
nodeA node to which you want to attach the FocusScopeTypeProperty.
isScopeTo set the node to become a focus scope, set to true (FocusScopeType::Group), otherwise set to false (FocusScopeType::NoScope).
Deprecated
In Kanzi 3.9.4. Use setFocusScopeType() instead.

◆ isFocusFence()

static KZ_DEPRECATED bool kanzi::FocusManager::isFocusFence ( const Node & node)
static

If a node has the FocusScopeTypeProperty attached, returns whether that node is a focus fence.

Parameters
nodeA node for which you want to check whether it is a focus fence.
Returns
If the node is a focus fence, true, otherwise false.
Deprecated
In Kanzi 3.9.4. Use getFocusScopeType() instead.

◆ setFocusFence()

static KZ_DEPRECATED void kanzi::FocusManager::setFocusFence ( Node & node,
bool isFence )
static

Sets the value of the FocusScopeTypeProperty property for a node to set that node to either become or not become a focus fence.

Parameters
nodeA node to which you want to attach the FocusScopeTypeProperty.
isFenceTo set the node to become a focus fence, set to true (FocusScopeType::Fence), otherwise set to false (FocusScopeType::NoScope).
Deprecated
In Kanzi 3.9.4. Use setFocusScopeType() instead.

◆ makeEditorInfo()

static PropertyTypeEditorInfoSharedPtr kanzi::FocusManager::makeEditorInfo ( )
static

Creates the property editor info for the FocusManager.

◆ trySetActiveFocus() [1/3]

KZ_DEPRECATED NodeSharedPtr kanzi::FocusManager::trySetActiveFocus ( ModalScope & popupScope,
NodeSharedPtr newFocusNode,
kanzi::FocusReason reason )

Tries to set the focus on an overlay focus scope.

Deprecated
In Kanzi 3.9.0. Use trySetFocus().

◆ trySetFocus() [1/2]

NodeSharedPtr kanzi::FocusManager::trySetFocus ( NodeSharedPtr newFocusNode)

Tries to set the focus to the newFocusNode.

Parameters
newFocusNodeThe node to which you want to move the focus.
Returns
The node that has focus. This can be either the node to which you set the focus, or if that node is a focus scope node, one of its child nodes. The method returns nullptr
  • if the newFocusNode is a focus scope node and it is effectively invisible, or
  • if the newFocusNode is not focusable or is hidden, or
  • if the newFocusNode is not in the foremost modal overlay or in the modeless overlay scopes above it, or
  • if the newFocusNode is nullptr.
Since
Kanzi 3.9.0

◆ trySetFocus() [2/2]

NodeSharedPtr kanzi::FocusManager::trySetFocus ( NodeSharedPtr newFocusNode,
FocusFallback fallbackOption )

Tries to set the focus to the newFocusNode using trySetFocus() but with a fallback behavior in case the node does not gain focus.

Parameters
newFocusNodeThe node to which you want to move the focus.
fallbackOptionThe fallback behavior:
Returns
The node that has focus.
Since
Kanzi 3.9.3

◆ trySetActiveFocus() [2/3]

KZ_DEPRECATED NodeSharedPtr kanzi::FocusManager::trySetActiveFocus ( NodeSharedPtr newFocusNode,
kanzi::FocusReason reason )

Tries to set the focus node of the foremost overlay focus scope to the newFocusNode and specifies the reason for moving the focus.

Deprecated
In Kanzi 3.9.0. Use trySetFocus().

◆ trySetActiveFocus() [3/3]

KZ_DEPRECATED NodeSharedPtr kanzi::FocusManager::trySetActiveFocus ( NodeSharedPtr newFocusNode)

An overload of trySetActiveFocus() using FocusReason::Force to move the focus.

Deprecated
In Kanzi 3.9.0. Use trySetFocus().

◆ tryMoveFocus() [1/2]

NodeSharedPtr kanzi::FocusManager::tryMoveFocus ( OverlayScope & overlayScope,
kanzi::FocusChainDirection direction )

Tries to set the focus to a node relative to the current key focus node of the overlay focus scope passed as an argument using the focus chain navigation.

The method takes the next focus candidate from the focus chain of the overlay focus scope and its nested focus group or fence focus scopes in the given direction.

If the focus scope has no key focus node set, the method sets the focus to:

The method fails if the overlay focus scope has no focusable descendant node.

Parameters
overlayScopeThe overlay focus scope where you want to set the key focus node.
directionThe direction in which to query for the next focusable node.
Returns
The node that has focus. If the scope has no focusable node in the requested direction, the method returns nullptr.
Since
Kanzi 3.9.0

◆ tryMoveFocusInScope()

NodeSharedPtr kanzi::FocusManager::tryMoveFocusInScope ( FocusScope & scope,
kanzi::FocusChainDirection direction )

Tries to set the focus to a node relative to the current key focus node of the focus scope using the focus navigation.

The method takes from the focus chain of the focus scope the next focus candidate in the given direction. The method does not move the focus to nodes in nested focus scopes.

If the focus scope has no key focus node set, the method sets the focus to:

  • The first focusable node of the focus scope, if the direction is NextFocusable.
  • The last focusable node of the focus scope, if the direction is PreviousFocusable.

The method fails if:

  • The focus scope has no focusable descendant node.
  • The focus is not in the focus scope.
  • The application has no focus at all.
Parameters
scopeThe focus scope in which to move the focus.
directionThe direction in which to query for the next focusable node.
Returns
The node that has focus. If the scope has no focusable node in the requested direction, or the focus is not in the focus scope, or the application has no focus, the method returns nullptr.
Since
Kanzi 3.9.0

◆ tryMoveActiveFocus() [1/2]

KZ_DEPRECATED NodeSharedPtr kanzi::FocusManager::tryMoveActiveFocus ( ModalScope & popupScope,
kanzi::FocusChainDirection direction )

Tries to set the focus to a node relative to the current key focus node of the overlay focus scope passed as an argument using the focus chain navigation.

The method takes the next focus candidate from the focus chain in the given direction.

Deprecated
In Kanzi 3.9.0. Use tryMoveFocus().

◆ tryMoveFocus() [2/2]

NodeSharedPtr kanzi::FocusManager::tryMoveFocus ( kanzi::FocusChainDirection direction)

Tries to set the focus to a node relative to the current key focus node of the application using the focus chain navigation.

The method takes the next focus candidate from the focus chain in the given direction.

The action fails if there is no focusable node in the focus chain of the application or if there is no existing application focus.

Parameters
directionThe direction in which to query for the next focusable node.
Returns
The node that has focus. If the scope has no focusable node in the requested direction, or the application has no focus, the method returns nullptr.
Since
Kanzi 3.9.0

◆ tryMoveActiveFocus() [2/2]

KZ_DEPRECATED NodeSharedPtr kanzi::FocusManager::tryMoveActiveFocus ( kanzi::FocusChainDirection direction)
Deprecated
In Kanzi 3.9.0. Use tryMoveFocus().

◆ tryMoveFocusForward()

NodeSharedPtr kanzi::FocusManager::tryMoveFocusForward ( )

The method is a specialization of the tryMoveFocus(FocusChainDirection) method and moves the focus from the current key focus node in the forward direction.

Returns
The node that has focus. If the scope has no focusable node in the forward direction, or the application has no focus, the method returns nullptr.

◆ tryMoveFocusBackward()

NodeSharedPtr kanzi::FocusManager::tryMoveFocusBackward ( )

The method is a specialization of the tryMoveFocus(FocusChainDirection) moving and moves the focus from the current key focus node in the backward direction.

Returns
The node that has focus. If the scope has no focusable node in the backward direction, or the application has no focus, the method returns nullptr.

◆ getFocus()

NodeSharedPtr kanzi::FocusManager::getFocus ( ) const

Returns the key focus node of the application.

Returns
The key focus node of the application. If the application has no key focus node, or the last key focus node is disabled or invisible, returns nullptr.
Since
Kanzi 3.9.0

◆ removeFocus()

void kanzi::FocusManager::removeFocus ( )

Removes key focus from the application by removing the focused status from the focused node.

This method does not clear the last-focused nodes of focus scopes. Focus navigation works only when the application has focus.

After you call removeFocus(), all nodes in the application have Node::FocusedProperty set to false.

If there is no application focus, the method does not do anything.

To set the application focus again, call trySetFocus().

Since
Kanzi 3.9.2

◆ createFocusScopeInfo()

KZ_DEPRECATED FocusScopePtr kanzi::FocusManager::createFocusScopeInfo ( Node & rootNode)

Creates a focus scope info with the rootNode as the focus scope node.

Parameters
rootNodeThe root node of the focus scope.
Returns
The unique pointer to the focus scope info.
Since
Kanzi 3.7.0
Deprecated
In Kanzi 3.9.2. Use FocusScope::create().

◆ getForemostOverlay()

OverlayScope * kanzi::FocusManager::getForemostOverlay ( ) const

Returns the foremost overlay focus scope.

Returns
The foremost overlay focus scope.
Since
Kanzi 3.9.2 the method returns OverlayScope.

◆ getFocusedOverlay()

OverlayScope * kanzi::FocusManager::getFocusedOverlay ( ) const

Returns the focused overlay focus scope.

Returns
The overlay focus scope that contains the application focus, or if there is no application focus, nullptr.
Since
Kanzi 3.9.2

◆ getForemostOverlayNode()

NodeSharedPtr kanzi::FocusManager::getForemostOverlayNode ( ) const

Returns the root node of the foremost overlay focus scope.

Returns
The root node of the foremost overlay focus scope.
Since
Kanzi 3.9.2

◆ getOverlayBelow()

OverlayScope * kanzi::FocusManager::getOverlayBelow ( const OverlayScope & scope) const

Returns the overlay focus scope that precedes in the overlay scope stack the overlay focus scope that you pass as an argument.

Parameters
scopeThe overlay focus scope for which you want to request the preceding overlay focus scope.
Returns
The overlay focus scope that precedes the overlay focus scope. If the overlay focus scope that you pass to this method is the only overlay focus scope in this application, returns nullptr.
Since
Kanzi 3.9.2 the argument and the return type of the method changed to OverlayScope.

Friends And Related Symbol Documentation

◆ Node

friend class Node
friend

◆ OverlayScope

Member Data Documentation

◆ FocusOnPressProperty

PropertyType<FocusOnPress> kanzi::FocusManager::FocusOnPressProperty
static

Sets where to set the focus when the user presses a node that has this property.

See also
getFocusOnPress(), setFocusOnPress()
Since
Kanzi 3.9.4

◆ FocusOrderProperty

PropertyType<int> kanzi::FocusManager::FocusOrderProperty
static

Sets the focus chain order of the node to which the property is attached.

Since
Kanzi 3.9.0

◆ CyclicFocusNavigationProperty

PropertyType<bool> kanzi::FocusManager::CyclicFocusNavigationProperty
static

Sets whether the focus chain navigation is cyclic in a focus scope.

Since
Kanzi 3.9.0

◆ FocusScopeTypeProperty

PropertyType<FocusScopeType> kanzi::FocusManager::FocusScopeTypeProperty
static

Sets the focus scope type of the node to which this property is attached.

Since
Kanzi 3.7.0

◆ AboutToLoseFocusMessage

MessageType<PreFocusMessageArguments> kanzi::FocusManager::AboutToLoseFocusMessage
static

The message dispatched to the key focus node and its ascendants before losing focus.

This is the first message that Kanzi dispatches when you move the focus from the key focus node to the next focusable node during the trySetFocus() call.

◆ AboutToGainFocusMessage

MessageType<PreFocusMessageArguments> kanzi::FocusManager::AboutToGainFocusMessage
static

The message dispatched to the next focusable node.

◆ FocusLostMessage

MessageType<PostFocusMessageArguments> kanzi::FocusManager::FocusLostMessage
static

Informs the old key focus node about losing the focus.

The message handlers can use this message to perform the required tasks after a node loses the focus.

◆ FocusGainedMessage

MessageType<PostFocusMessageArguments> kanzi::FocusManager::FocusGainedMessage
static

Informs the new key focus node about getting the focus.

The message handlers can use this message to perform the required tasks after a node gets the focus.

◆ OverlayBroughtToFrontMessage

MessageType<OverlayBroughtToFrontMessageArguments> kanzi::FocusManager::OverlayBroughtToFrontMessage
static

Kanzi dispatches this message when an overlay scope becomes the foremost overlay scope.

The message arguments contain the reason the overlay became the foremost overlay scope.

Since
Kanzi 3.9.2

◆ ScopeBroughtToFrontMessage

MessageType<ScopeBroughtToFrontMessageArguments> kanzi::FocusManager::ScopeBroughtToFrontMessage
static

Kanzi dispatches this message when an overlay scope becomes the foremost overlay scope.

The message arguments contain the reason the overlay became the foremost overlay scope.

Since
Kanzi 3.7.0
Deprecated
In Kanzi 3.9.2. Use OverlayBroughtToFrontMessage instead.

◆ OverlaySentToBackMessage

MessageType<OverlaySentToBackMessageArguments> kanzi::FocusManager::OverlaySentToBackMessage
static

Kanzi dispatches this message when an overlay scope is no longer the foremost overlay scope.

The message arguments contain the reason the overlay is no longer the foremost overlay scope.

Since
Kanzi 3.9.2

◆ ScopeSentToBackMessage

MessageType<ScopeSentToBackMessageArguments> kanzi::FocusManager::ScopeSentToBackMessage
static

Kanzi dispatches this message when an overlay scope is no longer the foremost overlay scope.

The message arguments contain the reason the overlay is no longer the foremost overlay scope.

Since
Kanzi 3.7.0
Deprecated
In Kanzi 3.9.2. Use OverlaySentToBackMessage instead.

◆ FocusEnteredFocusScopeMessage

MessageType<FocusEnteredFocusScopeMessageArguments> kanzi::FocusManager::FocusEnteredFocusScopeMessage
static

When focus enters a focus scope, Kanzi sends this message to the focus scope node that contains the node which gains focus.

Since
Kanzi 3.8.0

◆ FocusLeftFocusScopeMessage

MessageType<FocusLeftFocusScopeMessageArguments> kanzi::FocusManager::FocusLeftFocusScopeMessage
static

When focus leaves a focus scope, Kanzi sends this message to the focus scope node that contains the node which loses focus.

Since
Kanzi 3.8.0

◆ OverlayGainedFocusMessage

MessageType<OverlayGainedFocusMessageArguments> kanzi::FocusManager::OverlayGainedFocusMessage
static

When an overlay scope gains focus, Kanzi sends this message to the overlay scope node that contains the node which gains focus.

Since
Kanzi 3.9.2

◆ OverlayLostFocusMessage

MessageType<OverlayLostFocusMessageArguments> kanzi::FocusManager::OverlayLostFocusMessage
static

When an overlay scope loses focus, Kanzi sends this message to the overlay scope node that contains the node which loses focus.

Since
Kanzi 3.9.2

◆ MoveScopeFocusForwardMessage

MessageType<MoveFocusMessageArguments> kanzi::FocusManager::MoveScopeFocusForwardMessage
static

A focus scope node handles this message to move the focus to the next focusable node of the focus scope in forward direction.

See also
FocusNavigationManipulator
Since
Kanzi 3.9.0

◆ MoveScopeFocusBackwardMessage

MessageType<MoveFocusMessageArguments> kanzi::FocusManager::MoveScopeFocusBackwardMessage
static

A focus scope node handles this message to move the focus to the next focusable node of the focus scope in backward direction.

See also
FocusNavigationManipulator
Since
Kanzi 3.9.0

◆ InputOutsideOverlayMessage

MessageType<InputOutsideOverlayMessageArguments> kanzi::FocusManager::InputOutsideOverlayMessage
static

Kanzi dispatches this message when an input event occurs outside of an overlay scope node area.

When an auto-closing overlay Activity in a Parallel Activity Host sends this message, the Parallel Activity host handles the message automatically by deactivating the Activity. For an overlay focus scope node that is not an Activity you can handle this message manually.

Since
Kanzi 3.9.2

The documentation for this class was generated from the following file: