This template class enables you to implement key-repeat gesture detection.
class SampleAccelerator;
using SampleAcceleratorSharedPtr = shared_ptr<SampleAccelerator>;
class SampleAccelerator :
public InputManipulator,
protected KeyRepeatConceptImpl<SampleAccelerator>
{
using ConceptClass = KeyRepeatConceptImpl<SampleAccelerator>;
public:
static MessageType<MessageArguments> AcceleratorActivatedMessage;
static MessageType<MessageArguments> AcceleratorCompletedMessage;
static MessageType<MessageArguments> AcceleratorCanceledMessage;
static SampleAcceleratorSharedPtr create(Domain* domain, string_view = "")
{
return make_polymorphic_shared_ptr<InputManipulator>(new SampleAccelerator(domain));
}
protected:
class KeyGesture : public KeyInputConceptImpl<KeyGesture>
{
friend class SampleAccelerator;
SampleAccelerator& m_manipulator;
public:
m_manipulator(manipulator)
{
setKey(key, modifiers);
}
void notifyPartialKeyPressGesture(KeyInputConcept&)
{
m_manipulator.setState(StatePossible);
}
void notifyKeyPressGesture(KeyInputConcept&)
{
if (!m_manipulator.isGestureGrabbed())
{
return;
}
m_manipulator.setState(StateBegin);
m_manipulator.startKeyRepeatDetection();
}
void notifyKeyReleaseGesture(KeyInputConcept&)
{
if (!m_manipulator.isActive())
{
return;
}
m_manipulator.setState(StateEnd);
m_manipulator.stopKeyRepeatDetection();
MessageArguments arguments;
m_manipulator.getAttachedNode()->dispatchMessage(AcceleratorCompletedMessage, arguments);
}
};
explicit SampleAccelerator(Domain* domain) :
InputManipulator(domain, ManipulatorType::KeyInputHandler),
ConceptClass(domain),
{
}
bool notifyKeyInput(const KeyEvent& event) override
{
bool consumed = m_keyGestures[0].detectKeyGesture(event);
if (m_keyGestures[0].isGrabbed())
{
consumed = consumed | m_keyGestures[1].detectKeyGesture(event);
}
return consumed;
}
bool isGestureGrabbed()
{
return m_keyGestures[0].isGrabbed() && m_keyGestures[1].isGrabbed();
}
void notifyKeyHoldGesture()
{
MessageArguments arguments;
getAttachedNode()->dispatchMessage(AcceleratorActivatedMessage, arguments);
}
void notifyKeyRepeatGesture()
{
}
void onCancel() override
{
MessageArguments arguments;
getAttachedNode()->dispatchMessage(AcceleratorCanceledMessage, arguments);
onReset();
}
void onReset() override
{
for (auto& key : m_keyGestures)
{
key.ungrabGesture();
}
}
array<KeyGesture, 2> m_keyGestures;
KeyGesture* m_activeKey = nullptr;
};
MessageType<MessageArguments> SampleAccelerator::AcceleratorActivatedMessage(
metadata.displayName = "Accelerator Activated";
metadata.sendable = "False";
metadata.tooltip = "Accelerator activated.";
metadata.category = "Sample Accelerator";));
MessageType<MessageArguments> SampleAccelerator::AcceleratorCompletedMessage(
metadata.displayName = "Accelerator Completed";
metadata.sendable = "False";
metadata.tooltip = "Accelerator completed.";
metadata.category = "Sample Accelerator";));
MessageType<MessageArguments> SampleAccelerator::AcceleratorCanceledMessage(
metadata.displayName = "Accelerator Canceled";
metadata.sendable = "False";
metadata.tooltip = "Accelerator canceled.";
metadata.category = "Sample Accelerator";));