Kanzi Engine API
kanzi::KeyRepeatConceptImpl< TDerivedClass > Class Template Reference

This template class enables you to implement key-repeat gesture detection. More...

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

Inheritance diagram for kanzi::KeyRepeatConceptImpl< TDerivedClass >:
[legend]

Public Member Functions

void setKeyRepeatDetectionMode (DetectionMode mode)
 Sets the key-hold and key-repeat gesture detection mode. More...
 
 ~KeyRepeatConceptImpl () override
 Destructor. More...
 
- Public Member Functions inherited from kanzi::KeyRepeatConcept
chrono::milliseconds getKeyHoldTimeout () const
 Returns the time, in milliseconds, that Kanzi waits before it detects a key-hold gesture. More...
 
DetectionMode getKeyRepeatDetectionMode () const
 Returns the current key-hold and key-repeat gesture detection mode. More...
 
chrono::milliseconds getKeyRepeatInterval () const
 Returns the time, in milliseconds, between key-repeat gesture notifications that Kanzi sends repeatedly. More...
 
void setKeyHoldTimeout (chrono::milliseconds timeout)
 Sets the time that Kanzi waits to detect a key-hold gesture. More...
 
void setKeyRepeatInterval (chrono::milliseconds interval)
 Sets the time between the key-repeat gesture notifications that Kanzi sends repeatedly. More...
 
virtual ~KeyRepeatConcept ()=default
 Destructor. More...
 

Protected Member Functions

 KeyRepeatConceptImpl (Domain *domain)
 Constructor. More...
 
void startKeyRepeatDetection ()
 Starts the key-repeat gesture detection. More...
 
void stopKeyRepeatDetection ()
 Stops the gesture detection. More...
 
- Protected Member Functions inherited from kanzi::KeyRepeatConcept
 KeyRepeatConcept ()=default
 Constructor. More...
 

Additional Inherited Members

- Public Types inherited from kanzi::KeyRepeatConcept
enum  DetectionMode : uint8_t { DetectionMode::Disabled, DetectionMode::KeyHold, DetectionMode::KeyHoldAndRepeat }
 Specifies the key-hold and key-repeat gesture detection mode. More...
 
- Protected Attributes inherited from kanzi::KeyRepeatConcept
DetectionMode m_detectionMode
 Holds the key-repeat setting of the key gesture. More...
 
chrono::milliseconds m_keyHoldTimeout
 Key-hold timeout. More...
 
MainLoopTimerToken m_keyHoldTimerSubscription
 Timer handle for the initial key-hold and the key-repeat interval. More...
 
chrono::milliseconds m_keyRepeatInterval
 Key-repeat interval. More...
 

Detailed Description

template<typename TDerivedClass>
class kanzi::KeyRepeatConceptImpl< TDerivedClass >

This template class enables you to implement key-repeat gesture detection.

You can start the detection by calling startKeyRepeatDetection(), and stop the detection by calling stopKeyRepeatDetection(). It is recommended to use the template in combination with KeyInputConceptImpl template class, and start the key-repeat detection from the key-pressed gesture notification. To stop the detection, call the stopKeyRepeatDetection() method when the key-released gesture notification is received.

Your derived class must have the following methods:

  • void notifyKeyHoldGesture()
  • void notifyKeyRepeatGesture()
See also
KeyManipulator
Since
Kanzi 3.8.0

Example

To create a key manipulator with key-hold gesture recognition:

class SampleAccelerator;
using SampleAcceleratorSharedPtr = shared_ptr<SampleAccelerator>;
// This is a sample key manipulator that handles an accelerator composed of two key gestures: Ctrl+K, V.
// This example combines these key gestures into a single gesture and handles it as a single key gesture. You set the order in which Kanzi
// detects composing key gestures with the instantiation order of individual key gestures. The accelerator dispatches the
// AcceleratorActivated when the user presses Ctrl+K, V keys and holds for the key-hold timeout. The AcceleratorCompleted
// message is dispatched to the attached node of the manipulator when one of the composing key gestures detects the key-released
// gesture.
class SampleAccelerator : public InputManipulator, protected KeyRepeatConceptImpl<SampleAccelerator>
{
using ConceptClass = KeyRepeatConceptImpl<SampleAccelerator>;
public:
static MessageType<MessageArguments> AcceleratorActivatedMessage;
static MessageType<MessageArguments> AcceleratorCompletedMessage;
static MessageType<MessageArguments> AcceleratorCanceledMessage;
KZ_METACLASS_BEGIN(SampleAccelerator, InputManipulator, "Example.SampleAccelerator")
KZ_METACLASS_MESSAGE_TYPE(AcceleratorActivatedMessage)
KZ_METACLASS_MESSAGE_TYPE(AcceleratorCompletedMessage)
KZ_METACLASS_MESSAGE_TYPE(AcceleratorCanceledMessage)
static SampleAcceleratorSharedPtr create(Domain* domain, string_view = "")
{
return make_polymorphic_shared_ptr<InputManipulator>(new SampleAccelerator(domain));
}
protected:
// Inner class to handle a single key gesture of the accelerator.
class KeyGesture : public KeyInputConceptImpl<KeyGesture>
{
// Required to access ungrabGesture from the accelerator.
friend class SampleAccelerator;
SampleAccelerator& m_manipulator;
public:
explicit KeyGesture(SampleAccelerator& manipulator, LogicalKey key, KeyModifier modifiers = KeyModifier::Undefined) :
m_manipulator(manipulator)
{
setKey(key, modifiers);
}
// KeyInputConceptImpl calls this when the key event partially matches the key gesture composing elements.
void notifyPartialKeyPressGesture(KeyInputConcept&)
{
m_manipulator.setState(StatePossible);
}
// KeyInputConceptImpl calls this when the key gesture is fully detected.
void notifyKeyPressGesture(KeyInputConcept&)
{
if (!m_manipulator.isGestureGrabbed())
{
return;
}
// All the key gestures watched are detected, start the key hold and key repeat gesture detection.
m_manipulator.setState(StateBegin);
m_manipulator.startKeyRepeatDetection();
}
// KeyInputConceptImpl calls this when the key release gesture is detected on one of the key gestures
// composing the accelerator.
void notifyKeyReleaseGesture(KeyInputConcept&)
{
// Change the state of the manipulator only if the manipulator in an active state.
if (!m_manipulator.isActive())
{
return;
}
// Set the state of the manipulator.
m_manipulator.setState(StateEnd);
// Stop the gesture detection.
m_manipulator.stopKeyRepeatDetection();
// Dispatch the gesture completion message.
MessageArguments arguments;
m_manipulator.getAttachedNode()->dispatchMessage(AcceleratorCompletedMessage, arguments);
}
};
explicit SampleAccelerator(Domain* domain) :
InputManipulator(domain, ManipulatorType::KeyInputHandler),
ConceptClass(domain),
m_keyGestures({ { KeyGesture(*this, LogicalKey::K, KeyModifier::Control), KeyGesture(*this, LogicalKey::V) } })
{
}
// InputManager notifies the manipulator about an incoming key event. Returns true if the manipulator
// consumes the event.
bool notifyKeyInput(const KeyEvent& event) override
{
// The first key gesture must be grabbed first.
bool consumed = m_keyGestures[0].detectKeyGesture(event);
if (m_keyGestures[0].isGrabbed())
{
consumed = consumed | m_keyGestures[1].detectKeyGesture(event);
}
return consumed;
}
// If both key gestures are grabbed, returns true.
bool isGestureGrabbed()
{
return m_keyGestures[0].isGrabbed() && m_keyGestures[1].isGrabbed();
}
// KeyRepeatConceptImpl calls this method to notify the manipulator about the key-hold gesture detection.
void notifyKeyHoldGesture()
{
MessageArguments arguments;
getAttachedNode()->dispatchMessage(AcceleratorActivatedMessage, arguments);
}
void notifyKeyRepeatGesture()
{
// Do nothing, as the manipulator does not handle key repeats.
}
void onCancel() override
{
// Dispatch the cancel message first.
MessageArguments arguments;
getAttachedNode()->dispatchMessage(AcceleratorCanceledMessage, arguments);
// Reset the key gestures.
onReset();
}
void onReset() override
{
// Stop the key-hold detection first.
// Ungrab all grabbed keys.
for (auto& key : m_keyGestures)
{
key.ungrabGesture();
}
}
array<KeyGesture, 2> m_keyGestures;
KeyGesture* m_activeKey = nullptr;
friend class KeyRepeatConceptImpl<SampleAccelerator>;
};
MessageType<MessageArguments> SampleAccelerator::AcceleratorActivatedMessage(
kzMakeFixedString("SampleAccelerator.AcceleratorActivated"), MessageRoutingTunnelingBubbling,
metadata.displayName = "Accelerator Activated";
metadata.sendable = "False";
metadata.tooltip = "Accelerator activated.";
metadata.category = "Sample Accelerator";));
MessageType<MessageArguments> SampleAccelerator::AcceleratorCompletedMessage(
kzMakeFixedString("SampleAccelerator.AcceleratorCompleted"), MessageRoutingTunnelingBubbling,
metadata.displayName = "Accelerator Completed";
metadata.sendable = "False";
metadata.tooltip = "Accelerator completed.";
metadata.category = "Sample Accelerator";));
MessageType<MessageArguments> SampleAccelerator::AcceleratorCanceledMessage(
kzMakeFixedString("SampleAccelerator.AcceleratorCanceled"), MessageRoutingTunnelingBubbling,
metadata.displayName = "Accelerator Canceled";
metadata.sendable = "False";
metadata.tooltip = "Accelerator canceled.";
metadata.category = "Sample Accelerator";));

Constructor & Destructor Documentation

template<typename TDerivedClass >
kanzi::KeyRepeatConceptImpl< TDerivedClass >::~KeyRepeatConceptImpl ( )
override

Destructor.

template<typename TDerivedClass >
kanzi::KeyRepeatConceptImpl< TDerivedClass >::KeyRepeatConceptImpl ( Domain domain)
explicitprotected

Constructor.

Member Function Documentation

template<typename TDerivedClass >
void kanzi::KeyRepeatConceptImpl< TDerivedClass >::setKeyRepeatDetectionMode ( DetectionMode  mode)

Sets the key-hold and key-repeat gesture detection mode.

Parameters
modeThe new key-hold and repeat gesture detection mode.
template<typename TDerivedClass >
void kanzi::KeyRepeatConceptImpl< TDerivedClass >::startKeyRepeatDetection ( )
protected

Starts the key-repeat gesture detection.

template<typename TDerivedClass >
void kanzi::KeyRepeatConceptImpl< TDerivedClass >::stopKeyRepeatDetection ( )
protected

Stops the gesture detection.


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