Kanzi Framework  3.9.0
Kanzi Engine API
kanzi::FocusManager Class Reference

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

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

Classes

class  BringScopeToFrontMessageArguments
 Message arguments used by the BringScopeToFrontMessage. More...
 
class  FocusEnteredFocusScopeMessageArguments
 Message arguments used by FocusEnteredFocusScopeMessage. More...
 
class  FocusLeftFocusScopeMessageArguments
 Message arguments used by FocusLeftFocusScopeMessage. More...
 
class  MoveFocusMessageArguments
 Message arguments used by the focus move messages. More...
 
class  PostFocusMessageArguments
 
class  PreFocusMessageArguments
 Message arguments for the pre-focus messages. More...
 
class  ScopeBroughtToFrontMessageArguments
 Message arguments used by the ScopeBroughtToFrontMessage. More...
 
class  ScopeSentToBackMessageArguments
 Message arguments used by the ScopeSentToBackMessage. More...
 
struct  ScopeStack
 Stack of the registered popup-type focus scopes. More...
 
class  ScopeStateChangeMessageArguments
 Base message argument class for the focus scope state change message arguments. More...
 
class  SendScopeToBackMessageArguments
 Message arguments used by the SendScopeToBackMessage. More...
 

Public Types

enum  FocusChainDirection { PreviousFocusable, NextFocusable }
 Specifies the direction of the focus move. More...
 
enum  FocusReason {
  ForceFocusReason, FocusChainNavigationReason, HiddenFocusReason, UnhiddenFocusReason,
  OtherScopeInFront, ScopeDetached, ScopeNextInStack, OtherFocusReason
}
 Specifies the reason the node is focused. More...
 
enum  FocusScopeType : int {
  FocusScopeType::NoScope, FocusScopeType::Group, FocusScopeType::Fence, FocusScopeType::Modal,
  FocusScopeType::Popup
}
 Specifies the type of the focus scope. More...
 

Public Member Functions

bool bringScopeToFront (NodeSharedPtr node)
 Brings a popup-type or modal focus scope to the front of focus scopes. More...
 
bool bringScopeToFront (ModalScope &scope)
 Brings a modal focus scope to the front of focus scopes. More...
 
FocusScopePtr createFocusScopeInfo (Node &rootNode)
 Creates a focus scope info with the rootNode as the focus scope node. More...
 
NodeSharedPtr getFocus () const
 Returns the focus node of the application. More...
 
ModalScopegetForemostScope () const
 Returns the foremost popup-type focus scope. More...
 
NodeSharedPtr getForemostScopeNode () const
 Returns the root node of the foremost popup-type focus scope. More...
 
ModalScopegetPrecedingScope (const ModalScope &scope) const
 Returns the popup-type focus scope that precedes the focus scope that you pass as an argument. More...
 
bool sendScopeToBack (NodeSharedPtr node)
 Sends a popup-type or modal focus scope to the end of the stack of focus scopes. More...
 
bool sendScopeToBack (ModalScope &scope, FocusReason reason)
 Sends a focus scope to the end of the focus scope stack with a given reason value. More...
 
KZ_DEPRECATED NodeSharedPtr tryMoveActiveFocus (ModalScope &popupScope, FocusChainDirection direction)
 Tries to set the focus to a node relative to the current focus node of the popup-type or modal focus scope passed as an argument using the focus chain navigation. More...
 
KZ_DEPRECATED NodeSharedPtr tryMoveActiveFocus (FocusChainDirection direction)
 
NodeSharedPtr tryMoveFocus (ModalScope &popupScope, FocusChainDirection direction)
 Tries to set the focus to a node relative to the current focus node of the popup-type focus scope passed as an argument using the focus chain navigation. More...
 
NodeSharedPtr tryMoveFocus (FocusChainDirection direction)
 Tries to set the focus to a node relative to the current focus node of the application using the focus chain navigation. More...
 
NodeSharedPtr tryMoveFocusBackward ()
 The method is a specialization of the tryMoveFocus(FocusChainDirection) moving and moves the focus from the current focus node in the backward direction. More...
 
NodeSharedPtr tryMoveFocusForward ()
 The method is a specialization of the tryMoveFocus(FocusChainDirection) method and moves the focus from the current focus node in the forward direction. More...
 
NodeSharedPtr tryMoveFocusInScope (FocusScope &scope, FocusChainDirection direction)
 Tries to set the focus to a node relative to the current focus node of the focus scope using the focus navigation. More...
 
KZ_DEPRECATED NodeSharedPtr trySetActiveFocus (ModalScope &popupScope, NodeSharedPtr newFocusNode, FocusReason reason)
 Tries to set the focus on a popup-type focus scope. More...
 
KZ_DEPRECATED NodeSharedPtr trySetActiveFocus (NodeSharedPtr newFocusNode, FocusReason reason)
 Tries to set the focus node of the foremost popup-type focus scope to the newFocusNode and specifies the reason for moving the focus. More...
 
KZ_DEPRECATED NodeSharedPtr trySetActiveFocus (NodeSharedPtr newFocusNode)
 An overload of trySetFocus() using ForceFocusReason to move the focus. More...
 
NodeSharedPtr trySetFocus (ModalScope &popupScope, NodeSharedPtr newFocusNode, FocusReason reason)
 Tries to set the focus on a popup-type focus scope. More...
 
NodeSharedPtr trySetFocus (NodeSharedPtr newFocusNode, FocusReason reason)
 Tries to set the focus to the newFocusNode and specifies the reason for moving the focus. More...
 
NodeSharedPtr trySetFocus (NodeSharedPtr newFocusNode)
 An overload of trySetFocus() using ForceFocusReason to set the focus. More...
 

Static Public Member Functions

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

Static Public Attributes

Messages

Message arguments for post-focus messages.

Contains the reason the focus move is initiated.

Since
Kanzi 3.7.0
static MessageType< PreFocusMessageArgumentsAboutToLoseFocusMessage
 The message dispatched to the focus node and its ascendants before losing focus. More...
 
static MessageType< PreFocusMessageArgumentsAboutToGainFocusMessage
 The message dispatched to the next focusable node. More...
 
static MessageType< PostFocusMessageArgumentsFocusLostMessage
 Informs the old focus node about losing the focus. More...
 
static MessageType< PostFocusMessageArgumentsFocusGainedMessage
 Informs the new focus node about getting the focus. More...
 
static MessageType< ScopeBroughtToFrontMessageArgumentsScopeBroughtToFrontMessage
 A popup-type focus scope node dispatches this message to notify about the focus scope activation. More...
 
static MessageType< BringScopeToFrontMessageArgumentsBringScopeToFrontMessage
 A popup-type focus scope node handles this message to activate the scope. More...
 
static MessageType< ScopeSentToBackMessageArgumentsScopeSentToBackMessage
 A popup-type focus scope node dispatches this message to notify about the focus scope deactivation. More...
 
static MessageType< SendScopeToBackMessageArgumentsSendScopeToBackMessage
 A popup-type focus scope node handles this message to deactivate the scope. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 

Friends

class Domain
 
class Node
 

Properties

static PropertyType< int > FocusOrderProperty
 Sets the focus chain order of the node to which the property is attached. More...
 
static PropertyType< bool > CyclicFocusNavigationProperty
 Sets whether the focus chain navigation is cyclic in a focus scope. More...
 
static PropertyType< FocusScopeTypeFocusScopeTypeProperty
 Sets the focus scope type of the node to which this property is attached. More...
 
static size_t getFocusOrder (const Node &node)
 Returns the value of the FocusOrderProperty. More...
 
static void setFocusOrder (Node &node, size_t index)
 Sets the value of the FocusOrderProperty. More...
 
static void clearFocusOrder (Node &node)
 Clears the local value of the FocusOrderProperty. More...
 
static bool getCyclicFocusNavigation (const Node &node)
 Returns the value of the CyclicFocusNavigationProperty. More...
 
static void setCyclicFocusNavigation (Node &node, bool cyclic)
 Sets the value of the CyclicFocusNavigationProperty. More...
 
static void clearCyclicFocusNavigation (Node &node)
 Clears the local value of the CyclicFocusNavigationProperty. More...
 
static FocusScopeType getFocusScopeType (const Node &node)
 Returns the value of the FocusScopeTypeProperty. More...
 
static void setFocusScopeType (Node &node, FocusScopeType type)
 Sets the value of the FocusScopeTypeProperty. More...
 
static bool isFocusScope (const Node &node)
 If a node has the FocusScopeTypeProperty attached, returns whether that node is a focus scope. More...
 
static 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. More...
 
static bool isFocusFence (const Node &node)
 If a node has the FocusScopeTypeProperty attached, returns whether that node is a focus fence. More...
 
static 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. More...
 

Detailed Description

Focus Manager enables you to set and change the keyboard 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.

Focused node

A focused node is a node which receives all the keyboard 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 focused node. To set the focused 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. It 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, attach the FocusScopeTypeProperty to that node and set it 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, attach the FocusScopeTypeProperty to that node and set it to FocusScopeType::Fence.

  • Popup-type focus scopes:

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

      To make a node a modal scope, attach the FocusScopeTypeProperty to that node and set it to FocusScopeType::Modal.

    • Popup scope is similar to modal scope, except that when user input originates from a node that is outside of the node tree a popup scope, that popup scope loses focus.

      To make a node a popup scope, attach the FocusScopeTypeProperty to that node and set it to FocusScopeType::Popup.

    Modal and popup scopes have 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. A focus scope inside another focus scope is a nested focus scope. Nested focus scopes behave in the same way as any other focus scope: they forward and remember the focus of their child node in the same way, regardless of their 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 modal and popup focus scopes from the focus chain, and does not remember the scope nodes as last-focused nodes. To learn how Kanzi handles these scope types, see Popup-type focus scope stack and input delivery.

Setting and getting focus

To set focus on a node:

  1. Set the Node::FocusableProperty to true.
  2. Set the Node::EnabledProperty to true. This is the default value of the property.
  3. Set the Node::VisibleProperty to true. This is the default value of the property.
  4. Attach the node to a focus scope node. For example, the Screen or a Viewport2D node. Kanzi can set focus to the nodes that are in the process of being attached to the node tree, but not to the nodes that are not attached.
  5. Use one of the trySetFocus() methods to set the node as focus node. When setting the focus, use the appropriate FocusReason. If the reason is not known, use OtherFocusReason or call the variant which has only one argument.

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

To indicate which node has focus, Kanzi uses the Node::FocusedProperty. For example, you can use this property as a controller property in a State Manager to change the look and behavior of the node that has focus.

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.
getDomain()->getFocusManager()->trySetFocus(node);

Focus messages

When you call the trySetFocus() method, the Focus Manager sends the pre-focus and post-focus move messages. These messages are informative and you can use them to execute pre-focus move or post-focus move actions:

Kanzi dispatches these messages to the focus scope in this order:

  1. AboutToLoseFocusMessage to the focus node to inform that the node is about to lose the focus. Kanzi dispatches this message only if there is a current focus node.
  2. AboutToGainFocusMessage to the focus candidate node to inform that the node is about to get focus. Kanzi dispatches this message only if you pass a valid node to the trySetFocus() method.
  3. FocusGainedMessage. Kanzi dispatches this message to the new focus node handlers before the focus node is effectively set, and only if the new focus node is a valid node.
  4. FocusLostMessage. Kanzi dispatches this message to the previous focus node handlers right after the new focus node is set, and only if there was a previous node set.

The examples below show how to handle pre-focus messages.

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() != FocusManager::OtherFocusReason)
{
// 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() != FocusManager::FocusChainNavigationReason)
{
// 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.
getDomain()->getFocusManager()->trySetFocus(button, FocusManager::OtherFocusReason);

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, the Focus Manager dispatches the FocusLostMessage with HiddenFocusReason. You cannot set the focus to a hidden node. When you unhide that node by setting Node::VisibleProperty to true, and the focus remains on that node, the Focus Manager dispatches the FocusGainedMessage with UnhiddenFocusReason.

// 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() == FocusManager::HiddenFocusReason)
{
// ...
}
};
button->addMessageHandler(FocusManager::FocusLostMessage, onFocusLost);
// Handle Focus gained message.
auto onFocusGained = [](auto& args)
{
if (args.getFocusReason() == FocusManager::UnhiddenFocusReason)
{
// ...
}
};
button->addMessageHandler(FocusManager::FocusGainedMessage, onFocusGained);
// Hide the button. This triggers Focus Lost message with FocusManager::HiddenFocusReason.
button->setVisible(false);
// Unhide the button to set focus. This triggers Focus Gained message with FocusManager::UnhiddenFocusReason.
button->setVisible(true);

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 popup-type focus scope and, when performing focus chain navigation, skips the nested focus fences, the focus groups with empty focus chain and popup-type focus scopes.

Kanzi automatically includes in the focus chain all nodes of 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 which consumes the Tab and BackTab keys:

class TabConsumerNode;
typedef shared_ptr<TabConsumerNode> TabConsumerNodeSharedPtr;
// This example contains a node to which users can set focus using the Tab and BackTab keys.
// However, the normal use of this node consumes the Tab and BackTab keys, so users 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
{
// 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(FocusManager::NextFocusable, LogicalKey::Tab, KeyModifier::Control);
focusManipulator->setFocusNavigationKey(FocusManager::PreviousFocusable, 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 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.

When you mark a focus scope as non-focusable by setting the Node::FocusableProperty to false, you disable the focus scope functionality. As a result, Kanzi removes that node from the focus chain of its parent focus scope, and the nodes in its focus chain behave like normal non-focusable nodes.

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

// Create an Empty2DNode, make it a scope, and attach it to the root node.
auto scopeNode = EmptyNode2D::create(getDomain(), "Scope");
scopeNode->setFocusable(true);
FocusManager::setFocusScope(*scopeNode, true);
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 = getDomain()->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 on the focus scope using the trySetFocus() or the tryMoveFocus() methods, Kanzi restores the focus on this node, unless the last-focused node is detached from the UI scene.

To move the focus back on the last-focused node of a 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 = getDomain()->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 = getDomain()->getFocusManager()->trySetFocus(scopeNode);
if (focus == button2)
{
kzLogDebug(("button2 is the focus again."));
}
}

When you focus a scope using the focus chain navigation methods, such as tryMoveFocus() and its overrides, the scope forwards the focus to the 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 the nested focus scopes.

// Move the focus out from the scope.
focus = getDomain()->getFocusManager()->trySetFocus(outerButton);
if (focus != button2)
{
// Navigate on the focus chain in backward direction from the
// focus node.
getDomain()->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::setFocusScope(*rootNode, true);
// Create a scope.
auto scopeNode = EmptyNode2D::create(getDomain(), "Scope");
scopeNode->setFocusable(true);
FocusManager::setFocusScope(*scopeNode, true);
rootNode->addChild(scopeNode);
// Add a button to the first level of the scope.
auto button1 = Button2D::create(getDomain(), "first level button");
scopeNode->addChild(button1);
// Create a nested scope
auto nestedScopeNode = EmptyNode2D::create(getDomain(), "Nested scope");
nestedScopeNode->setFocusable(true);
FocusManager::setFocusScope(*nestedScopeNode, true);
scopeNode->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);
// Finally add a button to the same level as the outer scope is.
auto outerButton = Button2D::create(getDomain(), "non-scoped button");
rootNode->addChild(outerButton);
// Force focus on button2 from the nested scope.
auto focus = getDomain()->getFocusManager()->trySetFocus(button2);
// Both scopes have focus set.
if (scopeNode->isFocused() && nestedScopeNode->isFocused())
{
kzLogDebug(("scope and its nested scope has focus state set."));
}
// Move the focus onto outerButton.
getDomain()->getFocusManager()->trySetFocus(outerButton);
// Observe the focused state is lost in both the outer scope and the inner 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 they do not get focus as long as they have 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

You can move the focus from within a focus fence to a node outside of the focus fence, and the other way around, only by passing to the trySetFocus method any value, except the FocusChainNavigationReason.

Kanzi keeps the focus navigation inside a focus fence and skips the fences when the focus navigation happens outside of those focus fences. Kanzi also ignores the focus routing to the fences.

Use focus fences when you to keep the focus chain navigation within the boundaries of a focus scope.

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::setFocusFence(*fenceNode, true);
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::setFocusScope(*nestedScopeNode, true);
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 = getDomain()->getFocusManager()->trySetFocus(outerButton);
focus = getDomain()->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 = getDomain()->getFocusManager()->trySetFocus(button1);
}
if (focus == button1)
{
// Move forward. Observe the focus moves to button2 and button3.
getDomain()->getFocusManager()->tryMoveFocusForward();
kzLogDebug(("the focus is in the fence on node '{}'", getDomain()->getFocusManager()->getFocus()->getName()));
focus = getDomain()->getFocusManager()->tryMoveFocusForward();
kzLogDebug(("the focus is in the fence on node '{}'", getDomain()->getFocusManager()->getFocus()->getName()));
// The next move keeps the focus on button3 because it reached the fence boundaries.
focus = getDomain()->getFocusManager()->tryMoveFocusForward();
kzLogDebug(("the focus is in the fence on node '{}'", getDomain()->getFocusManager()->getFocus()->getName()));
}

Popup-type focus scope stack and input delivery

By default, Kanzi delivers the touch input to all nodes in a popup-type focus scope, including the nested focus scopes that are not popup-type focus scopes. Kanzi keeps track of the popup-type focus scopes of an application that are attached to the node tree, and organizes those in a form of a stack. Kanzi always delivers the touch input to the foremost focus scope nodes of the stack, excluding the nested popup-type focus scopes.

Modal focus scopes block the input that originates outside of its boundaries. You must bring to front, as well as send the focus scope to the back of the focus scope stack explicitly. Popup focus scopes send themselves to the back of the focus scope stack when the touch input originates outside of the popup focus scope node subtree boundaries. To get this functionality, you must set Node::HitTestableProperty to true on popup focus scopes, to let Kanzi detect the origin of the touch input.

Kanzi handles the key input in a similar way as touch input. Kanzi delivers the key input to the nodes of a focus scope subtree, except on popup focus scopes, where it delivers the key input also to the nodes that are outside of the focus scope of that subtree. The keys handled outside of the popup focus scope subtree dismisses the popup focus scope by sending it to the back to the focus scope stack.

You can bring a popup-type focus scope as foremost focus scope by calling the bringScopeToFront() method, and set the focus scope to the back of the stack of focus scopes by calling the sendScopeToBack() method. When you bring a popup-type focus scope to the front of the focus scope stack, that popup-type scope receives the ScopeBroughtToFrontMessage with the focus reason argument value set to ForceFocusReason, and the previous foremost focus scope receives the ScopeSentToBackMessage with the focus reason argument value set to OtherScopeInFront. When you send a popup-type focus scope to the back of the focus scope stack, that popup-type scope receives the ScopeSentToBackMessage with the focus reason argument value set to ForceFocusReason. The second foremost popup-type focus scope becomes the foremost focus scope, and receives the ScopeBroughtToFrontMessage with the focus reason value set to ScopeNextInStack.

Both ScopeBroughtToFrontMessage and ScopeSentToBackMessage enable you to control the visibility or other aspects of a focus scope node.

An example for a modal node:

class ModalNode;
typedef shared_ptr<ModalNode> ModalNodeSharedPtr;
// An 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_visibleDefaultValue(*this, Node::VisibleProperty, false),
m_focusableDefaultValue(*this, Node::FocusableProperty, true)
{
}
void onScopeInFront(FocusManager::ScopeBroughtToFrontMessageArguments&)
{
setVisible(true);
}
void onScopeToBack(FocusManager::ScopeSentToBackMessageArguments&)
{
setVisible(false);
}
void initialize()
{
addMessageHandler(FocusManager::ScopeBroughtToFrontMessage, this, &ModalNode::onScopeInFront);
addMessageHandler(FocusManager::ScopeSentToBackMessage, this, &ModalNode::onScopeToBack);
}
// The default overlay scope type of the Node.
ClassPropertyDefaultValue<FocusManager::FocusScopeType> m_focusScopeDefaultValue;
ClassPropertyDefaultValue<bool> m_visibleDefaultValue;
ClassPropertyDefaultValue<bool> m_focusableDefaultValue;
};

To bring a popup-type focus scopes to front using the FocusManager::bringScopeToFront() method:

auto modalNode = ModalNode::create(getDomain(), "Modal node");
// You must attach the modalNode to the node tree before you can activate the overlay scope.
rootNode->addChild(modalNode);
// Activate the overlay scope.
getDomain()->getFocusManager()->bringScopeToFront(modalNode);

You can achieve the same result using messages:

auto modalNode = ModalNode::create(getDomain(), "Modal node");
// Attach the node to the root node.
rootNode->addChild(modalNode);
FocusManager::BringScopeToFrontMessageArguments activateArgs;
// Activate the overlay scope.
modalNode->dispatchMessage(FocusManager::BringScopeToFrontMessage, activateArgs);
getDomain()->getFocusManager()->bringScopeToFront(modalNode);

Kanzi removes a popup-type scope from the FocusManager when you detach a popup-type scope node from the node tree. When Kanzi removes a popup-type scope from the FocusManager, it marks that focus scope as detached. Detached popup-type scopes remember their focus node in the same way as the inactive popup-type scopes do. You cannot bring a detached popup-type scope to front.

When you attach a detached popup-type focus scope node to the node tree, you can activate the focus scope. The activation restores the focus of that popup-type 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 a popup-type 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.

Member Enumeration Documentation

◆ FocusReason

Specifies the reason the node is focused.

Enumerator
ForceFocusReason 

The focus is forced on the node.

Since
Kanzi 3.7.0
FocusChainNavigationReason 

The focus is moved as a result of navigation in the focus chain.

HiddenFocusReason 

The Node::VisibleProperty of the node with the focus was set to false.

The value is only used in post-focus messages.

UnhiddenFocusReason 

The Node::VisibleProperty of the node with the focus was set to true.

The value is only used in post-focus messages.

OtherScopeInFront 

The focus change occurred because Kanzi is activating another popup-type focus scope.

Since
Kanzi 3.7.0
ScopeDetached 

The focus change occurred because Kanzi is detaching the popup-type focus scope node.

Since
Kanzi 3.7.0
ScopeNextInStack 

The popup-type focus scope is activated because it is the first popup-type focus scope that follows the foremost focus scope that is sent to the back of the focus scope stack.

Since
Kanzi 3.7.0
OtherFocusReason 

The focus is moved by means other than Tab or BackTab keys, or tap or mouse button press.

◆ FocusChainDirection

Specifies the direction of the focus move.

Enumerator
PreviousFocusable 

Moves the focus to the previous focusable node.

NextFocusable 

Moves the focus to the next focusable node.

◆ FocusScopeType

Specifies the type of the focus scope.

Since
Kanzi 3.7.0
Enumerator
NoScope 

Removes a previously set focus scope data from a Node or focus scope info. Kanzi Engine uses this value internally.

Group 

Sets a node to be a generic focus navigation group.

Fence 

Sets a node to be a focus navigation fence.

Modal 

Sets a node to be a modal focus fence.

When the input occurs outside of the node boundaries, Kanzi suppresses that input.

Popup 

Sets a node to be a popup focus fence.

When the input occurs outside of the node boundaries, Kanzi deactivates that node.

Member Function Documentation

◆ 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 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.

◆ setFocusScope()

static 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).

◆ isFocusFence()

static 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.

◆ setFocusFence()

static 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).
Since
Kanzi 3.7.0

◆ makeEditorInfo()

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

Creates the property editor info for the FocusManager.

◆ trySetFocus() [1/3]

NodeSharedPtr kanzi::FocusManager::trySetFocus ( ModalScope popupScope,
NodeSharedPtr  newFocusNode,
FocusReason  reason 
)

Tries to set the focus on a popup-type focus scope.

Parameters
popupScopeThe popup-type focus scope where you want to set the focus node.
newFocusNodeThe node to which you want to move the focus.
reasonThe reason you move the focus. If the reason is not known, use OtherFocusReason.
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. If the method cannot set the focus to any node, or the node is not within the focus scope boundaries, or if it is nullptr, the method returns nullptr.
Since
Kanzi 3.9.0

◆ trySetActiveFocus() [1/3]

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

Tries to set the focus on a popup-type focus scope.

Deprecated:
In Kanzi 3.9.0. Use trySetFocus().

◆ trySetFocus() [2/3]

NodeSharedPtr kanzi::FocusManager::trySetFocus ( NodeSharedPtr  newFocusNode,
FocusReason  reason 
)

Tries to set the focus to the newFocusNode and specifies the reason for moving the focus.

Parameters
newFocusNodeThe node to which you want to move the focus.
reasonThe reason you move the focus. If the reason is not known, use OtherFocusReason.
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. If the method cannot set the focus to any node, or the node is not within the boundaries of the foremost focus scope, the method returns nullptr.
Since
Kanzi 3.9.0

◆ trySetActiveFocus() [2/3]

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

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

Deprecated:
In Kanzi 3.9.0. Use trySetFocus().

◆ trySetFocus() [3/3]

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

An overload of trySetFocus() using ForceFocusReason to set the focus.

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. If the method cannot set the focus to any node, or the node is not within the boundaries of the foremost focus scope, the method returns nullptr.
Since
Kanzi 3.9.0

◆ trySetActiveFocus() [3/3]

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

An overload of trySetFocus() using ForceFocusReason to move the focus.

Deprecated:
In Kanzi 3.9.0. Use trySetFocus().

◆ tryMoveFocus() [1/2]

NodeSharedPtr kanzi::FocusManager::tryMoveFocus ( ModalScope popupScope,
FocusChainDirection  direction 
)

Tries to set the focus to a node relative to the current focus node of the popup-type focus scope passed as an argument using the focus chain navigation.

The method takes the next focus candidate from the focus chain of the popup-type focus scope and its nested focus scopes in the given direction.

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

The method fails if the popup-type focus scope has no focusable descendant node.

Parameters
popupScopeThe popup-type focus scope where you want to set the 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,
FocusChainDirection  direction 
)

Tries to set the focus to a node relative to the current 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 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, or the focus is not in the focus scope.

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, the method returns nullptr.
Since
Kanzi 3.9.0

◆ tryMoveActiveFocus() [1/2]

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

Tries to set the focus to a node relative to the current focus node of the popup-type or modal 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 ( FocusChainDirection  direction)

Tries to set the focus to a node relative to the current 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.

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, the method returns nullptr.
Since
Kanzi 3.9.0

◆ tryMoveActiveFocus() [2/2]

KZ_DEPRECATED NodeSharedPtr kanzi::FocusManager::tryMoveActiveFocus ( 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 focus node in the forward direction.

Returns
The node that has focus. If the scope has no focusable node in the forward direction, 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 focus node in the backward direction.

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

◆ getFocus()

NodeSharedPtr kanzi::FocusManager::getFocus ( ) const

Returns the focus node of the application.

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

◆ createFocusScopeInfo()

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

◆ bringScopeToFront() [1/2]

bool kanzi::FocusManager::bringScopeToFront ( NodeSharedPtr  node)

Brings a popup-type or modal focus scope to the front of focus scopes.

Kanzi automatically deactivates the previous foremost focus scope.

Parameters
nodeThe scope node or a node from the popup-type or modal focus scope to bring to front.
Returns
If the activation succeeds, true, otherwise false.
See also
FocusScope::isAttached()
Since
Kanzi 3.7.0

◆ bringScopeToFront() [2/2]

bool kanzi::FocusManager::bringScopeToFront ( ModalScope scope)

Brings a modal focus scope to the front of focus scopes.

Kanzi automatically deactivates the previous foremost focus scope.

Parameters
scopeThe modal focus scope to bring to front.
Returns
If the activation succeeds, true, otherwise false.
See also
FocusScope::isAttached(), ModalScope, PopupScope
Since
Kanzi 3.7.0

◆ sendScopeToBack() [1/2]

bool kanzi::FocusManager::sendScopeToBack ( NodeSharedPtr  node)

Sends a popup-type or modal focus scope to the end of the stack of focus scopes.

If the focus scope that owns the focus scope node is the foremost focus scope, the second foremost focus scope becomes the foremost focus scope.

Parameters
nodeThe focus scope node or a node from the focus scope to send to back.
Returns
If the focus scope is successfully sent to back, true, otherwise false.
Since
Kanzi 3.7.0

◆ sendScopeToBack() [2/2]

bool kanzi::FocusManager::sendScopeToBack ( ModalScope scope,
FocusReason  reason 
)

Sends a focus scope to the end of the focus scope stack with a given reason value.

If the focus scope is the foremost focus scope, the second foremost focus scope becomes the foremost focus scope.

Parameters
scopeThe focus scope to send to back.
reasonThe reason the scope is sent to back.
Returns
If the focus scope is successfully sent to back, true, otherwise false.
Since
Kanzi 3.7.0

◆ getForemostScope()

ModalScope& kanzi::FocusManager::getForemostScope ( ) const

Returns the foremost popup-type focus scope.

Returns
The foremost popup-type focus scope.
Since
Kanzi 3.7.0

◆ getForemostScopeNode()

NodeSharedPtr kanzi::FocusManager::getForemostScopeNode ( ) const

Returns the root node of the foremost popup-type focus scope.

Returns
The root node of the foremost popup-type focus scope.
Since
Kanzi 3.7.0

◆ getPrecedingScope()

ModalScope* kanzi::FocusManager::getPrecedingScope ( const ModalScope scope) const

Returns the popup-type focus scope that precedes the focus scope that you pass as an argument.

Parameters
scopeThe focus scope for which you want to request the preceding focus scope.
Returns
The popup or modal focus scope that was the foremost focus scope before the foremost focus scope. If the focus scope that you pass to this method is the only popup-type focus scope in this application, returns nullptr.
Since
Kanzi 3.7.0

Friends And Related Function Documentation

◆ Node

friend class Node
friend

◆ Domain

friend class Domain
friend

Member Data Documentation

◆ 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 focus node and its ascendants before losing focus.

This is the first message that Kanzi dispatches when you move the focus from the 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 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 focus node about getting the focus.

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

◆ ScopeBroughtToFrontMessage

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

A popup-type focus scope node dispatches this message to notify about the focus scope activation.

The activation reason value is specified in the FocusManager::ScopeBroughtToFrontMessageArguments.

Since
Kanzi 3.7.0

◆ BringScopeToFrontMessage

MessageType<BringScopeToFrontMessageArguments> kanzi::FocusManager::BringScopeToFrontMessage
static

A popup-type focus scope node handles this message to activate the scope.

If the scope is not attached, the scope activation fails.

Since
Kanzi 3.7.0

◆ ScopeSentToBackMessage

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

A popup-type focus scope node dispatches this message to notify about the focus scope deactivation.

The deactivation reason value is specified in the FocusManager::ScopeSentToBackMessageArguments.

Since
Kanzi 3.7.0

◆ SendScopeToBackMessage

MessageType<SendScopeToBackMessageArguments> kanzi::FocusManager::SendScopeToBackMessage
static

A popup-type focus scope node handles this message to deactivate the scope.

Since
Kanzi 3.7.0

◆ 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

◆ 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

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