diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0d3acfb..b63e572 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,6 +19,7 @@ set(libinputactions_SRCS libinputactions/config/parsers/qt.cpp libinputactions/config/parsers/separated-string.h libinputactions/config/parsers/std.cpp + libinputactions/config/parsers/triggers.cpp libinputactions/config/parsers/utils.h libinputactions/config/ConfigIssue.cpp libinputactions/config/ConfigIssueManager.cpp @@ -76,15 +77,41 @@ set(libinputactions_SRCS libinputactions/interfaces/SessionLock.h libinputactions/interfaces/Window.h libinputactions/interfaces/WindowProvider.cpp - libinputactions/triggers/DirectionalMotionTrigger.cpp - libinputactions/triggers/HoverTrigger.cpp - libinputactions/triggers/KeyboardShortcutTrigger.cpp - libinputactions/triggers/MotionTrigger.cpp - libinputactions/triggers/PressTrigger.cpp - libinputactions/triggers/StrokeTrigger.cpp - libinputactions/triggers/SwipeTrigger.cpp + libinputactions/triggers/core/DirectionalMotionTriggerCore.cpp + libinputactions/triggers/core/MotionTriggerCore.cpp + libinputactions/triggers/core/StrokeTriggerCore.cpp + libinputactions/triggers/core/SwipeTriggerCore.cpp + libinputactions/triggers/core/TimeTriggerCore.cpp + libinputactions/triggers/core/TriggerCore.cpp + libinputactions/triggers/keyboard/KeyboardShortcutTrigger.cpp + libinputactions/triggers/keyboard/KeyboardTrigger.cpp + libinputactions/triggers/mouse/MouseCircleTrigger.cpp + libinputactions/triggers/mouse/MouseMotionTrigger.cpp + libinputactions/triggers/mouse/MousePressTrigger.cpp + libinputactions/triggers/mouse/MouseStrokeTrigger.cpp + libinputactions/triggers/mouse/MouseSwipeTrigger.cpp + libinputactions/triggers/mouse/MouseTrigger.cpp + libinputactions/triggers/mouse/MouseWheelTrigger.cpp + libinputactions/triggers/pointer/PointerHoverTrigger.cpp + libinputactions/triggers/pointer/PointerTrigger.cpp + libinputactions/triggers/touchpad/TouchpadCircleTrigger.cpp + libinputactions/triggers/touchpad/TouchpadClickTrigger.cpp + libinputactions/triggers/touchpad/TouchpadHoldTrigger.cpp + libinputactions/triggers/touchpad/TouchpadPinchTrigger.cpp + libinputactions/triggers/touchpad/TouchpadRotateTrigger.cpp + libinputactions/triggers/touchpad/TouchpadStrokeTrigger.cpp + libinputactions/triggers/touchpad/TouchpadSwipeTrigger.cpp + libinputactions/triggers/touchpad/TouchpadTapTrigger.cpp + libinputactions/triggers/touchpad/TouchpadTrigger.cpp + libinputactions/triggers/touchscreen/TouchscreenCircleTrigger.cpp + libinputactions/triggers/touchscreen/TouchscreenHoldTrigger.cpp + libinputactions/triggers/touchscreen/TouchscreenPinchTrigger.cpp + libinputactions/triggers/touchscreen/TouchscreenRotateTrigger.cpp + libinputactions/triggers/touchscreen/TouchscreenStrokeTrigger.cpp + libinputactions/triggers/touchscreen/TouchscreenSwipeTrigger.cpp + libinputactions/triggers/touchscreen/TouchscreenTapTrigger.cpp + libinputactions/triggers/touchscreen/TouchscreenTrigger.cpp libinputactions/triggers/Trigger.cpp - libinputactions/triggers/WheelTrigger.cpp libinputactions/variables/LocalVariable.cpp libinputactions/variables/RemoteVariable.cpp libinputactions/variables/VariableManager.cpp diff --git a/src/libinputactions/actions/TriggerAction.cpp b/src/libinputactions/actions/TriggerAction.cpp index cb4181d..6003f71 100644 --- a/src/libinputactions/actions/TriggerAction.cpp +++ b/src/libinputactions/actions/TriggerAction.cpp @@ -19,7 +19,7 @@ #include "TriggerAction.h" #include "ActionExecutor.h" #include -#include +#include Q_LOGGING_CATEGORY(INPUTACTIONS_ACTION, "inputactions.action", QtWarningMsg) diff --git a/src/libinputactions/config/Node.cpp b/src/libinputactions/config/Node.cpp index ac2be43..d8d6d5d 100644 --- a/src/libinputactions/config/Node.cpp +++ b/src/libinputactions/config/Node.cpp @@ -204,10 +204,10 @@ std::map Node::mapItemsRawKeys() const return result; } -std::vector Node::sequenceItems() const +std::vector Node::sequenceItems(bool allowImplicitConversionToSequence) const { if (!isSequence()) { - if (m_allowImplicitConversionToSequence) { + if (m_allowImplicitConversionToSequence || allowImplicitConversionToSequence) { return {this}; } throw InvalidNodeTypeConfigException(this, NodeType::Sequence); diff --git a/src/libinputactions/config/Node.h b/src/libinputactions/config/Node.h index 3884128..7edee01 100644 --- a/src/libinputactions/config/Node.h +++ b/src/libinputactions/config/Node.h @@ -135,7 +135,7 @@ class Node : public std::enable_shared_from_this * @return Items of this sequence node. * @throws InvalidNodeTypeConfigException The node is not a sequence. */ - std::vector sequenceItems() const; + std::vector sequenceItems(bool allowImplicitConversionToSequence = false) const; /** * @return String keys and node values of this map node. Returned nodes are not marked as used. diff --git a/src/libinputactions/config/parsers/core.cpp b/src/libinputactions/config/parsers/core.cpp index d776fb1..45362dd 100644 --- a/src/libinputactions/config/parsers/core.cpp +++ b/src/libinputactions/config/parsers/core.cpp @@ -21,6 +21,7 @@ #include "flags.h" #include "globals.h" #include "separated-string.h" +#include "triggers.h" #include "utils.h" #include #include @@ -48,12 +49,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include @@ -575,180 +576,6 @@ struct NodeParser> }; template struct NodeParser>; -template<> -void NodeParser>::parse(const Node *node, std::unique_ptr &result) -{ - const auto *typeNode = node->at("type", true); - auto type = typeNode->as(); - - if (type == "circle") { - result = std::make_unique(TriggerType::Circle, - static_cast(node->at("direction", true)->as())); - } else if (type == "click") { - result = std::make_unique(TriggerType::Click); - } else if (type == "hold" || type == "press") { - auto pressTrigger = std::make_unique(); - loadSetter(pressTrigger.get(), &PressTrigger::setInstant, node->at("instant")); - result = std::move(pressTrigger); - } else if (type == "hover") { - result = std::make_unique(); - } else if (type == "pinch") { - result = std::make_unique(TriggerType::Pinch, - static_cast(node->at("direction", true)->as())); - } else if (type == "rotate") { - result = std::make_unique(TriggerType::Rotate, - static_cast(node->at("direction", true)->as())); - } else if (type == "shortcut") { - result = std::make_unique(node->at("shortcut", true)->as()); - } else if (type == "stroke") { - result = std::make_unique(node->at("strokes", true)->as>(true)); - } else if (type == "swipe") { - if (const auto *directionNode = node->at("direction")) { - result = std::make_unique(directionNode->as()); - } else { - const auto *angleNode = node->at("angle", true); - const auto angles = parseSeparatedString2(angleNode, '-'); - if (angles.first > 360 || angles.second > 360) { - throw InvalidValueConfigException(angleNode, "The angle may not be greater than 360."); - } - - auto swipeTrigger = std::make_unique(angles.first, angles.second); - loadSetter(swipeTrigger.get(), &SwipeTrigger::setBidirectional, node->at("bidirectional")); - result = std::move(swipeTrigger); - } - - } else if (type == "tap") { - result = std::make_unique(TriggerType::Tap); - } else if (type == "wheel") { - result = std::make_unique(static_cast(node->at("direction", true)->as())); - } else { - throw InvalidValueConfigException(typeNode, QString("Invalid trigger type '%1'.").arg(type)); - } - - loadSetter(result, &Trigger::setBlockEvents, node->at("block_events")); - loadSetter(result, &Trigger::setClearModifiers, node->at("clear_modifiers")); - loadSetter(result, &Trigger::setEndCondition, node->at("end_conditions")); - loadSetter(result, &Trigger::setId, node->at("id")); - loadSetter(result, &Trigger::setMouseButtonsExactOrder, node->at("mouse_buttons_exact_order")); - loadSetter(result, &Trigger::setResumeTimeout, node->at("resume_timeout")); - loadSetter(result, &Trigger::setSetLastTrigger, node->at("set_last_trigger")); - loadSetter(result, &Trigger::setThreshold, node->at("threshold")); - if (const auto *mouseButtonsNode = node->at("mouse_buttons")) { - mouseButtonsNode->as>(); // Ensure no duplicates, Trigger::setMouseButtons accepts a vector - loadSetter(result, &Trigger::setMouseButtons, mouseButtonsNode); - } - if (auto *motionTrigger = dynamic_cast(result.get())) { - loadSetter(motionTrigger, &MotionTrigger::setLockPointer, node->at("lock_pointer")); - loadSetter(motionTrigger, &MotionTrigger::setSpeed, node->at("speed")); - } - - auto conditionGroup = std::make_shared(); - if (const auto *fingersNode = node->at("fingers")) { - auto range = fingersNode->as>(); - if (!range.max()) { - conditionGroup->append(std::make_shared(BuiltinVariables::Fingers, - Value(range.min().value()), - ComparisonOperator::EqualTo)); - } else { - conditionGroup->append(std::make_shared(BuiltinVariables::Fingers, - std::vector>{ - Value(range.min().value()), Value(range.max().value())}, - ComparisonOperator::Between)); - } - } - if (const auto *modifiersNode = node->at("keyboard_modifiers")) { - g_configIssueManager->addIssue(DeprecatedFeatureConfigIssue(modifiersNode, DeprecatedFeature::TriggerKeyboardModifiers)); - - std::optional modifiers; - if (modifiersNode->isSequence()) { - modifiers = modifiersNode->as(); - } else { - const auto modifierMatchingMode = modifiersNode->as(); - if (modifierMatchingMode == "none") { - modifiers = Qt::KeyboardModifier::NoModifier; - } else if (modifierMatchingMode != "any") { - throw InvalidValueConfigException(modifiersNode, "Invalid keyboard modifier."); - } - } - - if (modifiers) { - conditionGroup->append(std::make_shared(BuiltinVariables::KeyboardModifiers, - Value(modifiers.value()), - ComparisonOperator::EqualTo)); - } - } - if (const auto *conditionsNode = node->at("conditions")) { - conditionGroup->append(conditionsNode->as>()); - } - - if (conditionGroup->conditions().size() == 1) { - result->setActivationCondition(conditionGroup->conditions()[0]); - } else if (conditionGroup->conditions().size()) { - result->setActivationCondition(conditionGroup); - } - - bool accelerated{}; - loadMember(accelerated, node->at("accelerated")); - - if (const auto *actionsNode = node->at("actions")) { - for (const auto *actionNode : actionsNode->sequenceItems()) { - auto action = actionNode->as>(); - if (dynamic_cast(result.get()) && action->on() != On::End && action->conflicting()) { - throw InvalidValueContextConfigException(actionNode, "Stroke triggers only support 'on: end' conflicting actions."); - } - - action->setAccelerated(accelerated); - result->addAction(std::move(action)); - } - } -} - -// Trigger list, handles triggers groups as well -template<> -void NodeParser>>::parse(const Node *node, std::vector> &result) -{ - for (const auto *triggerNode : node->sequenceItems()) { - if (const auto *subTriggersNode = triggerNode->at("gestures")) { - // Trigger group - for (const auto *subTriggerNode : subTriggersNode->sequenceItems()) { - const auto mergedNode = std::make_shared(*subTriggerNode); - - std::shared_ptr groupCondition; - for (const auto &[key, value] : triggerNode->mapItemsRawKeys()) { - const auto keyStr = key->as(); - if (keyStr == "conditions") { - groupCondition = triggerNode->at("conditions")->as>(); - } else if (keyStr != "gestures") { - mergedNode->addMapItem(key->shared_from_this(), value->shared_from_this()); - } - } - for (auto &trigger : mergedNode->as>>(true)) { - if (groupCondition) { - if (const auto triggerCondition = trigger->activationCondition()) { - if (const auto triggerConditionGroup = std::dynamic_pointer_cast(triggerCondition); - triggerConditionGroup && triggerConditionGroup->mode() == ConditionGroupMode::All) { - triggerConditionGroup->prepend(groupCondition); - } else { - auto conditionGroup = std::make_shared(); - conditionGroup->append(groupCondition); - conditionGroup->append(trigger->activationCondition()); - trigger->setActivationCondition(conditionGroup); - } - } else { - trigger->setActivationCondition(groupCondition); - } - } - - result.push_back(std::move(trigger)); - } - } - continue; - } - - result.push_back(triggerNode->as>()); - } -} - template<> void NodeParser>::parse(const Node *node, std::unique_ptr &result) { @@ -815,9 +642,6 @@ struct NodeParser> inline void parseTriggerHandler(const Node *node, TriggerHandler *handler) { - for (auto &trigger : node->at("gestures", true)->as>>()) { - handler->addTrigger(std::move(trigger)); - } loadSetter(handler, &TriggerHandler::setTimedTriggerUpdateDelta, node->at("__time_delta")); } @@ -854,6 +678,9 @@ inline void parseMultiTouchMotionTriggerHandler(const Node *node, MultiTouchMoti std::unique_ptr parseTouchpadTriggerHandler(const Node *node, InputDevice *device) { auto handler = std::make_unique(device); + for (auto &trigger : parseTriggerList(node->at("gestures", true))) { + handler->addTrigger(std::move(trigger)); + } parseMultiTouchMotionTriggerHandler(node, handler.get()); loadSetter(static_cast(handler.get()), &MotionTriggerHandler::setSwipeDeltaMultiplier, node->at("delta_multiplier")); return handler; @@ -862,6 +689,9 @@ std::unique_ptr parseTouchpadTriggerHandler(const Node * std::unique_ptr parseTouchscreenTriggerHandler(const Node *node, InputDevice *device) { auto handler = std::make_unique(device); + for (auto &trigger : parseTriggerList(node->at("gestures", true))) { + handler->addTrigger(std::move(trigger)); + } parseMultiTouchMotionTriggerHandler(node, handler.get()); return handler; } @@ -870,6 +700,9 @@ template<> void NodeParser>::parse(const Node *node, std::unique_ptr &result) { result = std::make_unique(); + for (auto &trigger : parseTriggerList(node->at("gestures", true))) { + result->addTrigger(std::move(trigger)); + } parseTriggerHandler(node, result.get()); } @@ -877,6 +710,9 @@ template<> void NodeParser>::parse(const Node *node, std::unique_ptr &result) { result = std::make_unique(); + for (auto &trigger : parseTriggerList(node->at("gestures", true))) { + result->addTrigger(std::move(trigger)); + } parseMotionTriggerHandler(node, node->mapAt("speed"), result.get()); } @@ -884,6 +720,9 @@ template<> void NodeParser>::parse(const Node *node, std::unique_ptr &result) { result = std::make_unique(); + for (auto &trigger : parseTriggerList(node->at("gestures", true))) { + result->addTrigger(std::move(trigger)); + } parseTriggerHandler(node, result.get()); } diff --git a/src/libinputactions/config/parsers/enums.cpp b/src/libinputactions/config/parsers/enums.cpp index ccdce75..7dca671 100644 --- a/src/libinputactions/config/parsers/enums.cpp +++ b/src/libinputactions/config/parsers/enums.cpp @@ -23,8 +23,8 @@ #include #include #include -#include -#include +#include +#include #include namespace InputActions @@ -72,32 +72,32 @@ NODEPARSER_ENUM(RotateDirection, "rotate direction", {"counterclockwise", RotateDirection::Counterclockwise}, {"any", RotateDirection::Any}, })) +NODEPARSER_ENUM(SimpleSwipeDirection, "swipe direction", + (std::unordered_map{ + {"left", SimpleSwipeDirection::Left}, + {"right", SimpleSwipeDirection::Right}, + {"up", SimpleSwipeDirection::Up}, + {"down", SimpleSwipeDirection::Down}, + {"up_down", SimpleSwipeDirection::UpDown}, + {"left_right", SimpleSwipeDirection::LeftRight}, + {"any", SimpleSwipeDirection::Any}, + })) NODEPARSER_ENUM(SwipeDirection, "swipe direction", (std::unordered_map{ {"left", SwipeDirection::Left}, {"right", SwipeDirection::Right}, {"up", SwipeDirection::Up}, {"down", SwipeDirection::Down}, + {"left_up", SwipeDirection::LeftUp}, + {"left_down", SwipeDirection::LeftDown}, + {"right_up", SwipeDirection::RightUp}, + {"right_down", SwipeDirection::RightDown}, {"up_down", SwipeDirection::UpDown}, {"left_right", SwipeDirection::LeftRight}, + {"left_up_right_down", SwipeDirection::LeftUpRightDown}, + {"left_down_right_up", SwipeDirection::LeftDownRightUp}, {"any", SwipeDirection::Any}, })) -NODEPARSER_ENUM(SwipeTriggerDirection, "swipe direction", - (std::unordered_map{ - {"left", SwipeTriggerDirection::Left}, - {"right", SwipeTriggerDirection::Right}, - {"up", SwipeTriggerDirection::Up}, - {"down", SwipeTriggerDirection::Down}, - {"left_up", SwipeTriggerDirection::LeftUp}, - {"left_down", SwipeTriggerDirection::LeftDown}, - {"right_up", SwipeTriggerDirection::RightUp}, - {"right_down", SwipeTriggerDirection::RightDown}, - {"up_down", SwipeTriggerDirection::UpDown}, - {"left_right", SwipeTriggerDirection::LeftRight}, - {"left_up_right_down", SwipeTriggerDirection::LeftUpRightDown}, - {"left_down_right_up", SwipeTriggerDirection::LeftDownRightUp}, - {"any", SwipeTriggerDirection::Any}, - })) NODEPARSER_ENUM(TriggerSpeed, "trigger speed", (std::unordered_map{ {"fast", TriggerSpeed::Fast}, diff --git a/src/libinputactions/config/parsers/triggers.cpp b/src/libinputactions/config/parsers/triggers.cpp new file mode 100644 index 0000000..9fb2ab2 --- /dev/null +++ b/src/libinputactions/config/parsers/triggers.cpp @@ -0,0 +1,303 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "triggers.h" +#include "NodeParser.h" +#include "containers.h" +#include "separated-string.h" +#include "utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace InputActions +{ + +template<> +void NodeParser>::parse(const Node *node, std::unique_ptr &result) +{ + result = std::make_unique(node->at("direction", true)->as()); +} + +template<> +void NodeParser>::parse(const Node *node, std::unique_ptr &result) +{ + result = std::make_unique(node->at("direction", true)->as()); +} + +template<> +void NodeParser>::parse(const Node *node, std::unique_ptr &result) +{ + result = std::make_unique(node->at("direction", true)->as()); +} + +template<> +void NodeParser>::parse(const Node *node, std::unique_ptr &result) +{ + result = std::make_unique(); +} + +template<> +void NodeParser>::parse(const Node *node, std::unique_ptr &result) +{ + result = std::make_unique(node->at("strokes", true)->as>(true)); +} + +template<> +void NodeParser>::parse(const Node *node, std::unique_ptr &result) +{ + if (const auto *directionNode = node->at("direction")) { + result = std::make_unique(directionNode->as()); + } else { + const auto *angleNode = node->at("angle", true); + const auto angles = parseSeparatedString2(angleNode, '-'); + if (angles.first > 360 || angles.second > 360) { + throw InvalidValueConfigException(angleNode, "The angle may not be greater than 360."); + } + + auto swipeTriggerCore = std::make_unique(angles.first, angles.second); + loadSetter(swipeTriggerCore.get(), &SwipeTriggerCore::setBidirectional, node->at("bidirectional")); + result = std::move(swipeTriggerCore); + } +} + +void finalizeTrigger(const Node *node, Trigger *trigger) +{ + loadSetter(trigger, &Trigger::setBlockEvents, node->at("block_events")); + loadSetter(trigger, &Trigger::setClearModifiers, node->at("clear_modifiers")); + loadSetter(trigger, &Trigger::setEndCondition, node->at("end_conditions")); + loadSetter(trigger, &Trigger::setId, node->at("id")); + loadSetter(trigger, &Trigger::setResumeTimeout, node->at("resume_timeout")); + loadSetter(trigger, &Trigger::setSetLastTrigger, node->at("set_last_trigger")); + loadSetter(trigger, &Trigger::setThreshold, node->at("threshold")); + if (auto *motionTriggerCore = dynamic_cast(&trigger->core())) { + loadSetter(motionTriggerCore, &MotionTriggerCore::setSpeed, node->at("speed")); + } + + auto conditionGroup = std::make_shared(); + if (const auto *fingersNode = node->at("fingers")) { + auto range = fingersNode->as>(); + if (!range.max()) { + conditionGroup->append(std::make_shared(BuiltinVariables::Fingers, + Value(range.min().value()), + ComparisonOperator::EqualTo)); + } else { + conditionGroup->append(std::make_shared(BuiltinVariables::Fingers, + std::vector>{ + Value(range.min().value()), Value(range.max().value())}, + ComparisonOperator::Between)); + } + } + if (const auto *modifiersNode = node->at("keyboard_modifiers")) { + g_configIssueManager->addIssue(DeprecatedFeatureConfigIssue(modifiersNode, DeprecatedFeature::TriggerKeyboardModifiers)); + + std::optional modifiers; + if (modifiersNode->isSequence()) { + modifiers = modifiersNode->as(); + } else { + const auto modifierMatchingMode = modifiersNode->as(); + if (modifierMatchingMode == "none") { + modifiers = Qt::KeyboardModifier::NoModifier; + } else if (modifierMatchingMode != "any") { + throw InvalidValueConfigException(modifiersNode, "Invalid keyboard modifier."); + } + } + + if (modifiers) { + conditionGroup->append(std::make_shared(BuiltinVariables::KeyboardModifiers, + Value(modifiers.value()), + ComparisonOperator::EqualTo)); + } + } + if (const auto *conditionsNode = node->at("conditions")) { + conditionGroup->append(conditionsNode->as>()); + } + + if (conditionGroup->conditions().size() == 1) { + trigger->setActivationCondition(conditionGroup->conditions()[0]); + } else if (conditionGroup->conditions().size()) { + trigger->setActivationCondition(conditionGroup); + } + + bool accelerated{}; + loadMember(accelerated, node->at("accelerated")); + + if (const auto *actionsNode = node->at("actions")) { + for (const auto *actionNode : actionsNode->sequenceItems()) { + auto action = actionNode->as>(); + if (dynamic_cast(&trigger->core()) && action->on() != On::End && action->conflicting()) { + throw InvalidValueContextConfigException(actionNode, "Stroke triggers only support 'on: end' conflicting actions."); + } + + action->setAccelerated(accelerated); + trigger->addAction(std::move(action)); + } + } +} + +template<> +void NodeParser>::parse(const Node *node, std::unique_ptr &result) +{ + const auto *typeNode = node->at("type", true); + auto type = typeNode->as(); + + if (type == "shortcut") { + result = std::make_unique(node->at("shortcut", true)->as(), node->as>()); + } else { + throw InvalidValueConfigException(typeNode, QString("Trigger '%1' does not exist for this device.").arg(type)); + } + + finalizeTrigger(node, result.get()); +} + +template<> +void NodeParser>::parse(const Node *node, std::unique_ptr &result) +{ + const auto *typeNode = node->at("type", true); + auto type = typeNode->as(); + + if (type == "circle") { + result = std::make_unique(node->as>()); + } else if (type == "press") { + auto pressTrigger = std::make_unique(node->as>()); + loadSetter(pressTrigger.get(), &MousePressTrigger::setInstant, node->at("instant")); + result = std::move(pressTrigger); + } else if (type == "stroke") { + result = std::make_unique(node->as>()); + } else if (type == "swipe") { + result = std::make_unique(node->as>()); + } else if (type == "wheel") { + result = std::make_unique(node->as>()); + } else { + throw InvalidValueConfigException(typeNode, QString("Trigger '%1' does not exist for this device.").arg(type)); + } + + loadSetter(result, &MouseTrigger::setMouseButtonsExactOrder, node->at("mouse_buttons_exact_order")); + if (const auto *mouseButtonsNode = node->at("mouse_buttons")) { + mouseButtonsNode->as>(); // Ensure no duplicates, MouseTrigger::setMouseButtons accepts a vector + loadSetter(result, &MouseTrigger::setMouseButtons, mouseButtonsNode); + } + + if (auto *motionTrigger = dynamic_cast(result.get())) { + loadSetter(motionTrigger, &MouseMotionTrigger::setLockPointer, node->at("lock_pointer")); + } + + finalizeTrigger(node, result.get()); +} + +template<> +void NodeParser>::parse(const Node *node, std::unique_ptr &result) +{ + const auto *typeNode = node->at("type", true); + auto type = typeNode->as(); + + if (type == "hover") { + result = std::make_unique(node->as>()); + } else { + throw InvalidValueConfigException(typeNode, QString("Trigger '%1' does not exist for this device.").arg(type)); + } + + finalizeTrigger(node, result.get()); +} + +template<> +void NodeParser>::parse(const Node *node, std::unique_ptr &result) +{ + const auto *typeNode = node->at("type", true); + auto type = typeNode->as(); + + if (type == "circle") { + result = std::make_unique(node->as>()); + } else if (type == "click") { + result = std::make_unique(node->as>()); + } else if (type == "hold" || type == "press") { + result = std::make_unique(node->as>()); + } else if (type == "pinch") { + result = std::make_unique(node->as>()); + } else if (type == "rotate") { + result = std::make_unique(node->as>()); + } else if (type == "stroke") { + result = std::make_unique(node->as>()); + } else if (type == "swipe") { + result = std::make_unique(node->as>()); + } else if (type == "tap") { + result = std::make_unique(node->as>()); + } else { + throw InvalidValueConfigException(typeNode, QString("Trigger '%1' does not exist for this device.").arg(type)); + } + + finalizeTrigger(node, result.get()); +} + +template<> +void NodeParser>::parse(const Node *node, std::unique_ptr &result) +{ + const auto *typeNode = node->at("type", true); + auto type = typeNode->as(); + + if (type == "circle") { + result = std::make_unique(node->as>()); + } else if (type == "hold" || type == "press") { + result = std::make_unique(node->as>()); + } else if (type == "pinch") { + result = std::make_unique(node->as>()); + } else if (type == "rotate") { + result = std::make_unique(node->as>()); + } else if (type == "stroke") { + result = std::make_unique(node->as>()); + } else if (type == "swipe") { + result = std::make_unique(node->as>()); + } else if (type == "tap") { + result = std::make_unique(node->as>()); + } else { + throw InvalidValueConfigException(typeNode, QString("Trigger '%1' does not exist for this device.").arg(type)); + } + + finalizeTrigger(node, result.get()); +} + +} \ No newline at end of file diff --git a/src/libinputactions/config/parsers/triggers.h b/src/libinputactions/config/parsers/triggers.h new file mode 100644 index 0000000..c2349d0 --- /dev/null +++ b/src/libinputactions/config/parsers/triggers.h @@ -0,0 +1,83 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace InputActions +{ + +class Trigger; + +// Trigger list, handles triggers groups as well +template +std::vector> parseTriggerList(const Node *node) +{ + std::vector> result; + for (const auto *triggerNode : node->sequenceItems(true)) { + if (const auto *subTriggersNode = triggerNode->at("gestures")) { + // Trigger group + for (const auto *subTriggerNode : subTriggersNode->sequenceItems()) { + const auto mergedNode = std::make_shared(*subTriggerNode); + + std::shared_ptr groupCondition; + for (const auto &[key, value] : triggerNode->mapItemsRawKeys()) { + const auto keyStr = key->as(); + if (keyStr == "conditions") { + groupCondition = triggerNode->at("conditions")->as>(); + } else if (keyStr != "gestures") { + mergedNode->addMapItem(key->shared_from_this(), value->shared_from_this()); + } + } + for (auto &trigger : parseTriggerList(mergedNode.get())) { + if (groupCondition) { + if (const auto triggerCondition = trigger->activationCondition()) { + if (const auto triggerConditionGroup = std::dynamic_pointer_cast(triggerCondition); + triggerConditionGroup && triggerConditionGroup->mode() == ConditionGroupMode::All) { + triggerConditionGroup->prepend(groupCondition); + } else { + auto conditionGroup = std::make_shared(); + conditionGroup->append(groupCondition); + conditionGroup->append(trigger->activationCondition()); + trigger->setActivationCondition(conditionGroup); + } + } else { + trigger->setActivationCondition(groupCondition); + } + } + + result.push_back(std::move(trigger)); + } + } + continue; + } + + result.push_back(triggerNode->as>()); + } + + return result; +} + +void finalizeTrigger(const Node *node, Trigger *trigger); + +} \ No newline at end of file diff --git a/src/libinputactions/dbus/DBusInterfaceBase.cpp b/src/libinputactions/dbus/DBusInterfaceBase.cpp index b158611..7aa7662 100644 --- a/src/libinputactions/dbus/DBusInterfaceBase.cpp +++ b/src/libinputactions/dbus/DBusInterfaceBase.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include namespace InputActions diff --git a/src/libinputactions/dbus/IntegratedDBusInterface.cpp b/src/libinputactions/dbus/IntegratedDBusInterface.cpp index f85f7ed..d7ef37a 100644 --- a/src/libinputactions/dbus/IntegratedDBusInterface.cpp +++ b/src/libinputactions/dbus/IntegratedDBusInterface.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include namespace InputActions diff --git a/src/libinputactions/handlers/KeyboardTriggerHandler.cpp b/src/libinputactions/handlers/KeyboardTriggerHandler.cpp index f4fa8f6..6780667 100644 --- a/src/libinputactions/handlers/KeyboardTriggerHandler.cpp +++ b/src/libinputactions/handlers/KeyboardTriggerHandler.cpp @@ -19,6 +19,7 @@ #include "KeyboardTriggerHandler.h" #include #include +#include namespace InputActions { @@ -28,6 +29,11 @@ KeyboardTriggerHandler::KeyboardTriggerHandler() setDeviceTypes(InputDeviceType::Keyboard); } +void KeyboardTriggerHandler::addTrigger(std::unique_ptr trigger) +{ + TriggerHandler::addTrigger(std::move(trigger)); +} + bool KeyboardTriggerHandler::keyboardKey(const KeyboardKeyEvent &event) { InputTriggerHandler::keyboardKey(event); diff --git a/src/libinputactions/handlers/KeyboardTriggerHandler.h b/src/libinputactions/handlers/KeyboardTriggerHandler.h index 367b162..75cc532 100644 --- a/src/libinputactions/handlers/KeyboardTriggerHandler.h +++ b/src/libinputactions/handlers/KeyboardTriggerHandler.h @@ -24,6 +24,8 @@ namespace InputActions { +class KeyboardTrigger; + /** * Can handle multiple devices simultaneously. A single instance is shared by all devices. */ @@ -32,6 +34,8 @@ class KeyboardTriggerHandler : public InputTriggerHandler public: KeyboardTriggerHandler(); + void addTrigger(std::unique_ptr trigger); + protected: bool keyboardKey(const KeyboardKeyEvent &event) override; diff --git a/src/libinputactions/handlers/MotionTriggerHandler.cpp b/src/libinputactions/handlers/MotionTriggerHandler.cpp index a011509..f154c61 100644 --- a/src/libinputactions/handlers/MotionTriggerHandler.cpp +++ b/src/libinputactions/handlers/MotionTriggerHandler.cpp @@ -27,8 +27,8 @@ #include #include #include -#include -#include +#include +#include Q_LOGGING_CATEGORY(INPUTACTIONS_HANDLER_MOTION, "inputactions.handler.motion", QtWarningMsg) @@ -290,8 +290,8 @@ void MotionTriggerHandler::onCircleCoastingTimerTick() void MotionTriggerHandler::onActivatingTrigger(const Trigger *trigger) { - if (const auto motionTrigger = dynamic_cast(trigger)) { - if (!m_isDeterminingSpeed && motionTrigger->hasSpeed()) { + if (const auto *motionTriggerCore = dynamic_cast(&trigger->core())) { + if (!m_isDeterminingSpeed && motionTriggerCore->hasSpeed()) { qCDebug(INPUTACTIONS_HANDLER_MOTION).noquote() << QString("Trigger has speed (id: %1)").arg(trigger->id()); m_isDeterminingSpeed = true; } @@ -315,7 +315,7 @@ void MotionTriggerHandler::onEndingTriggers(TriggerTypes types) continue; } - for (const auto &triggerStroke : dynamic_cast(trigger)->strokes()) { + for (const auto &triggerStroke : dynamic_cast(trigger->core()).strokes()) { const auto score = stroke.compare(triggerStroke); if (score > bestScore && score > Stroke::min_matching_score()) { best = trigger; diff --git a/src/libinputactions/handlers/MotionTriggerHandler.h b/src/libinputactions/handlers/MotionTriggerHandler.h index 961ac46..2390fec 100644 --- a/src/libinputactions/handlers/MotionTriggerHandler.h +++ b/src/libinputactions/handlers/MotionTriggerHandler.h @@ -19,7 +19,7 @@ #pragma once #include "InputTriggerHandler.h" -#include +#include Q_DECLARE_LOGGING_CATEGORY(INPUTACTIONS_HANDLER_MOTION) @@ -42,9 +42,6 @@ struct TriggerSpeedThreshold uint32_t directions; }; -/** - * Handles motion triggers: stroke, swipe. - */ class MotionTriggerHandler : public InputTriggerHandler { public: diff --git a/src/libinputactions/handlers/MouseTriggerHandler.cpp b/src/libinputactions/handlers/MouseTriggerHandler.cpp index 2ec0caf..7883123 100644 --- a/src/libinputactions/handlers/MouseTriggerHandler.cpp +++ b/src/libinputactions/handlers/MouseTriggerHandler.cpp @@ -20,8 +20,8 @@ #include #include #include -#include -#include +#include +#include #include Q_LOGGING_CATEGORY(INPUTACTIONS_HANDLER_MOUSE, "inputactions.handler.mouse", QtWarningMsg) @@ -42,6 +42,11 @@ MouseTriggerHandler::MouseTriggerHandler() m_motionTimeoutTimer.setSingleShot(true); } +void MouseTriggerHandler::addTrigger(std::unique_ptr trigger) +{ + TriggerHandler::addTrigger(std::move(trigger)); +} + bool MouseTriggerHandler::keyboardKey(const KeyboardKeyEvent &event) { MotionTriggerHandler::keyboardKey(event); @@ -63,13 +68,13 @@ bool MouseTriggerHandler::pointerAxis(const MotionEvent &event) return false; } - SwipeDirection direction = SwipeDirection::Left; + SimpleSwipeDirection direction = SimpleSwipeDirection::Left; if (delta.x() > 0) { - direction = SwipeDirection::Right; + direction = SimpleSwipeDirection::Right; } else if (delta.y() > 0) { - direction = SwipeDirection::Down; + direction = SimpleSwipeDirection::Down; } else if (delta.y() < 0) { - direction = SwipeDirection::Up; + direction = SimpleSwipeDirection::Up; } DirectionalMotionTriggerUpdateEvent updateEvent; updateEvent.setDelta(delta.x() != 0 ? delta.x() : delta.y()); @@ -78,7 +83,7 @@ bool MouseTriggerHandler::pointerAxis(const MotionEvent &event) const auto result = updateTriggers(TriggerType::Wheel, updateEvent); bool continuous = false; for (const auto &trigger : activeTriggers(TriggerType::Wheel)) { - if (static_cast(trigger)->continuous()) { + if (static_cast(trigger)->continuous()) { continuous = true; } } @@ -111,7 +116,7 @@ bool MouseTriggerHandler::pointerButton(const PointerButtonEvent &event) // This should be per-gesture instead of global, but it's good enough m_instantPress = false; for (const auto &trigger : triggers(TriggerType::Press, *m_activationEvent)) { - if (dynamic_cast(trigger)->instant()) { + if (dynamic_cast(trigger)->instant()) { qCDebug(INPUTACTIONS_HANDLER_MOUSE, "Press gesture is instant"); m_instantPress = true; break; @@ -228,7 +233,7 @@ bool MouseTriggerHandler::pointerMotion(const MotionEvent &event) pressBlockedMouseButtons(event.sender()); } const auto lockPointer = std::ranges::any_of(activeTriggers(TriggerType::SinglePointMotion), [](const auto *trigger) { - return dynamic_cast(trigger)->lockPointer(); + return dynamic_cast(trigger)->lockPointer(); }); return block && lockPointer; } @@ -251,10 +256,11 @@ bool MouseTriggerHandler::shouldBlockMouseButton(MouseButton button) // A partial match is required, not an exact one event->setMouseButtons({}); for (const auto &trigger : triggers(TriggerType::All, *event.get())) { - const auto buttons = trigger->mouseButtons(); + const auto *castedTrigger = dynamic_cast(trigger); + const auto buttons = castedTrigger->mouseButtons(); if (trigger->blockEvents() - && ((trigger->mouseButtonsExactOrder() && std::ranges::equal(m_buttons, buttons | std::views::take(m_buttons.size()))) - || (!trigger->mouseButtonsExactOrder() && std::ranges::contains(buttons, button)))) { + && ((castedTrigger->mouseButtonsExactOrder() && std::ranges::equal(m_buttons, buttons | std::views::take(m_buttons.size()))) + || (!castedTrigger->mouseButtonsExactOrder() && std::ranges::contains(buttons, button)))) { qCDebug(INPUTACTIONS_HANDLER_MOUSE).noquote().nospace() << "Mouse button blocked (button: " << button.scanCode() << ", trigger: " << trigger->id() << ")"; return true; diff --git a/src/libinputactions/handlers/MouseTriggerHandler.h b/src/libinputactions/handlers/MouseTriggerHandler.h index 15b6395..fad3167 100644 --- a/src/libinputactions/handlers/MouseTriggerHandler.h +++ b/src/libinputactions/handlers/MouseTriggerHandler.h @@ -25,15 +25,9 @@ Q_DECLARE_LOGGING_CATEGORY(INPUTACTIONS_HANDLER_MOUSE) namespace InputActions { +class MouseTrigger; + /** - * Handles mouse triggers: press, stroke, swipe, wheel. - * - * Press triggers activate after a small delay in order to allow for normal clicks and dragging. This behavior can be - * changed by making a press trigger instant, however any activated instant trigger will make all other activated - * triggers instant as well. - * @see setMotionTimeout - * @see PressTrigger::setInstant - * * Can handle multiple devices simultaneously. A single instance is shared by all devices. */ class MouseTriggerHandler : public MotionTriggerHandler @@ -41,6 +35,8 @@ class MouseTriggerHandler : public MotionTriggerHandler public: MouseTriggerHandler(); + void addTrigger(std::unique_ptr trigger); + protected: bool keyboardKey(const KeyboardKeyEvent &event) override; diff --git a/src/libinputactions/handlers/MultiTouchMotionTriggerHandler.h b/src/libinputactions/handlers/MultiTouchMotionTriggerHandler.h index a0bad22..f33b912 100644 --- a/src/libinputactions/handlers/MultiTouchMotionTriggerHandler.h +++ b/src/libinputactions/handlers/MultiTouchMotionTriggerHandler.h @@ -34,10 +34,6 @@ enum class PinchType Rotate }; -/** - * Handles multi-touch triggers: pinch, tap, rotate. - * In the future this will also be able to recognize triggers based on touch points. - */ class MultiTouchMotionTriggerHandler : public MotionTriggerHandler { protected: diff --git a/src/libinputactions/handlers/PointerTriggerHandler.cpp b/src/libinputactions/handlers/PointerTriggerHandler.cpp index cd6be35..d4bd9fd 100644 --- a/src/libinputactions/handlers/PointerTriggerHandler.cpp +++ b/src/libinputactions/handlers/PointerTriggerHandler.cpp @@ -17,10 +17,16 @@ */ #include "PointerTriggerHandler.h" +#include namespace InputActions { +void PointerTriggerHandler::addTrigger(std::unique_ptr trigger) +{ + TriggerHandler::addTrigger(std::move(trigger)); +} + bool PointerTriggerHandler::pointerMotion(const MotionEvent &event) { if (hasActiveTriggers(TriggerType::Hover)) { diff --git a/src/libinputactions/handlers/PointerTriggerHandler.h b/src/libinputactions/handlers/PointerTriggerHandler.h index e4a6c89..91211fb 100644 --- a/src/libinputactions/handlers/PointerTriggerHandler.h +++ b/src/libinputactions/handlers/PointerTriggerHandler.h @@ -23,6 +23,8 @@ namespace InputActions { +class PointerTrigger; + /** * Can handle multiple devices simultaneously. A single instance is shared by all devices. */ @@ -31,6 +33,8 @@ class PointerTriggerHandler : public InputTriggerHandler public: PointerTriggerHandler() = default; + void addTrigger(std::unique_ptr trigger); + protected: bool pointerMotion(const MotionEvent &event) override; diff --git a/src/libinputactions/handlers/TouchpadTriggerHandler.cpp b/src/libinputactions/handlers/TouchpadTriggerHandler.cpp index c46373b..40fc1db 100644 --- a/src/libinputactions/handlers/TouchpadTriggerHandler.cpp +++ b/src/libinputactions/handlers/TouchpadTriggerHandler.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,11 @@ TouchpadTriggerHandler::TouchpadTriggerHandler(InputDevice *device) connect(&m_libinputTapTimeoutTimer, &QTimer::timeout, this, &TouchpadTriggerHandler::onLibinputTapTimeout); } +void TouchpadTriggerHandler::addTrigger(std::unique_ptr trigger) +{ + TriggerHandler::addTrigger(std::move(trigger)); +} + bool TouchpadTriggerHandler::pointerAxis(const MotionEvent &event) { m_libinputFingers = 2; diff --git a/src/libinputactions/handlers/TouchpadTriggerHandler.h b/src/libinputactions/handlers/TouchpadTriggerHandler.h index 72e9523..a7b5a5d 100644 --- a/src/libinputactions/handlers/TouchpadTriggerHandler.h +++ b/src/libinputactions/handlers/TouchpadTriggerHandler.h @@ -24,9 +24,9 @@ namespace InputActions { +class TouchpadTrigger; + /** - * Handles touchpad triggers: click, pinch, press, rotate, stroke, swipe, tap. - * * Can handle one device. Each device has its own instance. */ class TouchpadTriggerHandler : public MultiTouchMotionTriggerHandler @@ -34,6 +34,8 @@ class TouchpadTriggerHandler : public MultiTouchMotionTriggerHandler public: TouchpadTriggerHandler(InputDevice *device); + void addTrigger(std::unique_ptr trigger); + protected: /** * Treated as two-finger motion. diff --git a/src/libinputactions/handlers/TouchscreenTriggerHandler.cpp b/src/libinputactions/handlers/TouchscreenTriggerHandler.cpp index fd5e3de..5c9a1d7 100644 --- a/src/libinputactions/handlers/TouchscreenTriggerHandler.cpp +++ b/src/libinputactions/handlers/TouchscreenTriggerHandler.cpp @@ -52,6 +52,7 @@ #include #include #include +#include namespace InputActions { @@ -79,6 +80,11 @@ TouchscreenTriggerHandler::TouchscreenTriggerHandler(InputDevice *device) connect(&m_touchUpTimer, &QTimer::timeout, this, &TouchscreenTriggerHandler::handleTouchUp); } +void TouchscreenTriggerHandler::addTrigger(std::unique_ptr trigger) +{ + TriggerHandler::addTrigger(std::move(trigger)); +} + bool TouchscreenTriggerHandler::evdevFrame(const EvdevFrameEvent &event) { // Block events that don't map to InputActions events (e.g. pressure change) diff --git a/src/libinputactions/handlers/TouchscreenTriggerHandler.h b/src/libinputactions/handlers/TouchscreenTriggerHandler.h index f47ac76..c042f59 100644 --- a/src/libinputactions/handlers/TouchscreenTriggerHandler.h +++ b/src/libinputactions/handlers/TouchscreenTriggerHandler.h @@ -24,6 +24,8 @@ namespace InputActions { +class TouchscreenTrigger; + struct PinchInfo { qreal angle; @@ -31,8 +33,6 @@ struct PinchInfo }; /** - * Handles touchscreen triggers: hold, pinch, rotate, single-point motion, tap. - * * Event filtering requires blocking events by default until a gesture is recognized. The device's virtual state is managed by this handler. The input backend * must not do anything else other than blocking individual events. * @@ -43,6 +43,8 @@ class TouchscreenTriggerHandler : public MultiTouchMotionTriggerHandler public: TouchscreenTriggerHandler(InputDevice *device); + void addTrigger(std::unique_ptr trigger); + protected: bool evdevFrame(const EvdevFrameEvent &event) override; bool touchCancel(const TouchCancelEvent &event) override; diff --git a/src/libinputactions/handlers/TriggerHandler.h b/src/libinputactions/handlers/TriggerHandler.h index cedfacf..eb917ed 100644 --- a/src/libinputactions/handlers/TriggerHandler.h +++ b/src/libinputactions/handlers/TriggerHandler.h @@ -46,8 +46,6 @@ class TriggerHandler : public QObject Q_OBJECT public: - void addTrigger(std::unique_ptr trigger); - /** * @param value The interval (in milliseconds) and delta used for updating time-based triggers. */ @@ -56,6 +54,8 @@ class TriggerHandler : public QObject protected: TriggerHandler(); + void addTrigger(std::unique_ptr trigger); + /** * Cancels all active triggers and activates triggers of the specified types eligible for activation. */ diff --git a/src/libinputactions/input/StrokeRecorder.cpp b/src/libinputactions/input/StrokeRecorder.cpp index 7f080e1..2ad7e1d 100644 --- a/src/libinputactions/input/StrokeRecorder.cpp +++ b/src/libinputactions/input/StrokeRecorder.cpp @@ -19,7 +19,7 @@ #include "StrokeRecorder.h" #include "events.h" #include -#include +#include namespace InputActions { diff --git a/src/libinputactions/input/devices/InputDeviceProperties.cpp b/src/libinputactions/input/devices/InputDeviceProperties.cpp index 09ecf15..84a8f6e 100644 --- a/src/libinputactions/input/devices/InputDeviceProperties.cpp +++ b/src/libinputactions/input/devices/InputDeviceProperties.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include namespace InputActions { diff --git a/src/libinputactions/triggers/Trigger.cpp b/src/libinputactions/triggers/Trigger.cpp index a8930df..eb5488c 100644 --- a/src/libinputactions/triggers/Trigger.cpp +++ b/src/libinputactions/triggers/Trigger.cpp @@ -17,6 +17,7 @@ */ #include "Trigger.h" +#include "core/TriggerCore.h" #include #include #include @@ -28,8 +29,9 @@ namespace InputActions static const std::chrono::milliseconds TICK_INTERVAL{5L}; -Trigger::Trigger(TriggerType type) +Trigger::Trigger(TriggerType type, std::unique_ptr core) : m_type(type) + , m_core(std::move(core)) { m_tickTimer.setTimerType(Qt::TimerType::PreciseTimer); connect(&m_tickTimer, &QTimer::timeout, this, &Trigger::onTick); @@ -39,6 +41,8 @@ Trigger::Trigger(TriggerType type) connect(&m_resumeTimeoutTimer, &QTimer::timeout, this, &Trigger::onResumeTimeoutTimerTimeout); } +Trigger::~Trigger() = default; + void Trigger::addAction(std::unique_ptr action) { actionAdded(action.get()); @@ -47,22 +51,12 @@ void Trigger::addAction(std::unique_ptr action) bool Trigger::canActivate(const TriggerActivationEvent &event) const { - if (!m_mouseButtons.empty() && event.mouseButtons().has_value()) { - if (m_mouseButtons.size() != event.mouseButtons()->size() - || (m_mouseButtonsExactOrder && !std::ranges::equal(m_mouseButtons, event.mouseButtons().value())) - || (!m_mouseButtonsExactOrder && !std::ranges::all_of(m_mouseButtons, [event](auto &button) { - return std::ranges::contains(event.mouseButtons().value(), button); - }))) { - return false; - } - } - return !m_activationCondition || m_activationCondition->satisfied(); } bool Trigger::canUpdate(const TriggerUpdateEvent &event) const { - return true; + return m_core->canUpdate(event); } bool Trigger::endIfCannotUpdate() const @@ -102,7 +96,7 @@ void Trigger::update(const TriggerUpdateEvent &event) } setLastTrigger(); - updateActions(event); + m_core->updateActions(m_actions, event); } bool Trigger::canEnd() const @@ -185,23 +179,6 @@ void Trigger::actionAdded(TriggerAction *action) } } -void Trigger::updateActions(const TriggerUpdateEvent &event) -{ - doUpdateActions(event); -} - -void Trigger::doUpdateActions(const TriggerUpdateEvent &event) -{ - for (const auto &action : m_actions) { - action->triggerUpdated(event); - } -} - -const TriggerType &Trigger::type() const -{ - return m_type; -} - void Trigger::onTick() { if (!m_withinThreshold) { @@ -239,4 +216,14 @@ void Trigger::reset() m_tickTimer.stop(); } +const TriggerCore &Trigger::core() const +{ + return *m_core; +} + +TriggerCore &Trigger::core() +{ + return *m_core; +} + } \ No newline at end of file diff --git a/src/libinputactions/triggers/Trigger.h b/src/libinputactions/triggers/Trigger.h index 9c51fa0..de37974 100644 --- a/src/libinputactions/triggers/Trigger.h +++ b/src/libinputactions/triggers/Trigger.h @@ -34,6 +34,8 @@ Q_DECLARE_LOGGING_CATEGORY(INPUTACTIONS_TRIGGER) namespace InputActions { +class TriggerCore; + /** * Unset optional fields are not checked by triggers. */ @@ -74,8 +76,8 @@ class Trigger : public QObject Q_OBJECT public: - Trigger(TriggerType type = TriggerType::None); - virtual ~Trigger() = default; + Trigger(TriggerType type, std::unique_ptr core); + ~Trigger() override; void addAction(std::unique_ptr action); /** @@ -169,29 +171,15 @@ class Trigger : public QObject */ void setThreshold(Range value) { m_threshold = std::move(value); } - /** - * Mouse buttons that must be pressed before and during the trigger. - * - * Only applies to mouse triggers. - */ - const std::vector &mouseButtons() const { return m_mouseButtons; } - void setMouseButtons(std::vector value) { m_mouseButtons = std::move(value); } - - /** - * Whether mouse buttons must be pressed in order as specified. - * - * Only applies to mouse triggers. - */ - bool mouseButtonsExactOrder() const { return m_mouseButtonsExactOrder; } - void setMouseButtonsExactOrder(bool value) { m_mouseButtonsExactOrder = value; } - /** * The amount of time after a trigger ends, during which the trigger can be performed again is if it never actually ended. Performing any action that does * not activate this trigger causes it to be cancelled immediately. */ void setResumeTimeout(std::chrono::milliseconds value) { m_resumeTimeout = std::move(value); } - const TriggerType &type() const; + const TriggerCore &core() const; + TriggerCore &core(); + TriggerType type() const { return m_type; } protected: /** @@ -199,21 +187,17 @@ class Trigger : public QObject */ virtual void actionAdded(TriggerAction *action); - /** - * Override to modify the event before passing it to actions. Must be called by the overriding method. - */ - virtual void updateActions(const TriggerUpdateEvent &event); - private slots: void onTick(); void onResumeTimeoutTimerTimeout(); private: - TEST_VIRTUAL void doUpdateActions(const TriggerUpdateEvent &event); void setLastTrigger(); void reset(); - TriggerType m_type{0}; + TriggerType m_type; + std::unique_ptr m_core; + std::vector> m_actions; bool m_started = false; QTimer m_tickTimer; @@ -230,8 +214,6 @@ private slots: QString m_id; bool m_setLastTrigger = true; std::optional> m_threshold; - std::vector m_mouseButtons; - bool m_mouseButtonsExactOrder{}; std::chrono::milliseconds m_resumeTimeout{}; friend class MockSwipeTrigger; diff --git a/src/libinputactions/triggers/DirectionalMotionTrigger.cpp b/src/libinputactions/triggers/core/DirectionalMotionTriggerCore.cpp similarity index 61% rename from src/libinputactions/triggers/DirectionalMotionTrigger.cpp rename to src/libinputactions/triggers/core/DirectionalMotionTriggerCore.cpp index 7370e1f..e0263f0 100644 --- a/src/libinputactions/triggers/DirectionalMotionTrigger.cpp +++ b/src/libinputactions/triggers/core/DirectionalMotionTriggerCore.cpp @@ -16,20 +16,19 @@ along with this program. If not, see . */ -#include "DirectionalMotionTrigger.h" +#include "DirectionalMotionTriggerCore.h" namespace InputActions { -DirectionalMotionTrigger::DirectionalMotionTrigger(TriggerType type, TriggerDirection direction) - : MotionTrigger(type) - , m_direction(direction) +DirectionalMotionTriggerCore::DirectionalMotionTriggerCore(TriggerDirection direction) + : m_direction(direction) { } -bool DirectionalMotionTrigger::canUpdate(const TriggerUpdateEvent &event) const +bool DirectionalMotionTriggerCore::canUpdate(const TriggerUpdateEvent &event) const { - if (!MotionTrigger::canUpdate(event)) { + if (!MotionTriggerCore::canUpdate(event)) { return false; } @@ -37,7 +36,7 @@ bool DirectionalMotionTrigger::canUpdate(const TriggerUpdateEvent &event) const return m_direction & castedEvent.direction(); } -void DirectionalMotionTrigger::updateActions(const TriggerUpdateEvent &event) +void DirectionalMotionTriggerCore::updateActions(const std::vector> &actions, const TriggerUpdateEvent &event) const { auto newEvent = dynamic_cast(event); @@ -45,8 +44,8 @@ void DirectionalMotionTrigger::updateActions(const TriggerUpdateEvent &event) static std::vector negativeDirections = { static_cast(PinchDirection::In), static_cast(RotateDirection::Counterclockwise), - static_cast(SwipeDirection::Left), - static_cast(SwipeDirection::Up), + static_cast(SimpleSwipeDirection::Left), + static_cast(SimpleSwipeDirection::Up), }; if ((m_direction & (m_direction - 1)) == 0 && std::find(negativeDirections.begin(), negativeDirections.end(), m_direction) != negativeDirections.end()) { auto delta = event.delta(); @@ -54,7 +53,22 @@ void DirectionalMotionTrigger::updateActions(const TriggerUpdateEvent &event) newEvent.setDelta(delta); } - MotionTrigger::updateActions(newEvent); + MotionTriggerCore::updateActions(actions, newEvent); +} + +PinchTriggerCore::PinchTriggerCore(PinchDirection direction) + : DirectionalMotionTriggerCore(static_cast(direction)) +{ +} + +RotateTriggerCore::RotateTriggerCore(RotateDirection direction) + : DirectionalMotionTriggerCore(static_cast(direction)) +{ +} + +SimpleSwipeTriggerCore::SimpleSwipeTriggerCore(SimpleSwipeDirection direction) + : DirectionalMotionTriggerCore(static_cast(direction)) +{ } } \ No newline at end of file diff --git a/src/libinputactions/triggers/DirectionalMotionTrigger.h b/src/libinputactions/triggers/core/DirectionalMotionTriggerCore.h similarity index 66% rename from src/libinputactions/triggers/DirectionalMotionTrigger.h rename to src/libinputactions/triggers/core/DirectionalMotionTriggerCore.h index b94425d..23a35fb 100644 --- a/src/libinputactions/triggers/DirectionalMotionTrigger.h +++ b/src/libinputactions/triggers/core/DirectionalMotionTriggerCore.h @@ -18,7 +18,7 @@ #pragma once -#include "MotionTrigger.h" +#include "MotionTriggerCore.h" namespace InputActions { @@ -36,7 +36,7 @@ enum class RotateDirection : TriggerDirection Counterclockwise = 1u << 3, Any = UINT32_MAX }; -enum class SwipeDirection : TriggerDirection +enum class SimpleSwipeDirection : TriggerDirection { Left = 1u << 4, Right = 1u << 5, @@ -62,22 +62,40 @@ class DirectionalMotionTriggerUpdateEvent : public MotionTriggerUpdateEvent /** * An input action that involves directional motion. */ -class DirectionalMotionTrigger : public MotionTrigger +class DirectionalMotionTriggerCore : public MotionTriggerCore { public: - DirectionalMotionTrigger(TriggerType type, TriggerDirection direction); - - /** - * @return Whether the direction matches. - * @see MotionTrigger::canUpdate - */ bool canUpdate(const TriggerUpdateEvent &event) const override; + void updateActions(const std::vector> &actions, const TriggerUpdateEvent &event) const override; protected: - void updateActions(const TriggerUpdateEvent &event) override; + DirectionalMotionTriggerCore(TriggerDirection direction); private: TriggerDirection m_direction; + + friend class TestDirectionalMotionTriggerCore; +}; + +class PinchTriggerCore : public DirectionalMotionTriggerCore +{ +public: + PinchTriggerCore(PinchDirection direction); +}; + +class RotateTriggerCore : public DirectionalMotionTriggerCore +{ +public: + RotateTriggerCore(RotateDirection direction); +}; + +/** + * Unlike SwipeTriggerCore, is not based on angles and does not support diagonal directions. + */ +class SimpleSwipeTriggerCore : public DirectionalMotionTriggerCore +{ +public: + SimpleSwipeTriggerCore(SimpleSwipeDirection direction); }; } \ No newline at end of file diff --git a/src/libinputactions/triggers/MotionTrigger.cpp b/src/libinputactions/triggers/core/MotionTriggerCore.cpp similarity index 82% rename from src/libinputactions/triggers/MotionTrigger.cpp rename to src/libinputactions/triggers/core/MotionTriggerCore.cpp index bad1e10..f692e2a 100644 --- a/src/libinputactions/triggers/MotionTrigger.cpp +++ b/src/libinputactions/triggers/core/MotionTriggerCore.cpp @@ -16,23 +16,22 @@ along with this program. If not, see . */ -#include "MotionTrigger.h" +#include "MotionTriggerCore.h" namespace InputActions { -MotionTrigger::MotionTrigger(TriggerType type) - : Trigger(type) +bool MotionTriggerCore::canUpdate(const TriggerUpdateEvent &event) const { -} + if (!TriggerCore::canUpdate(event)) { + return false; + } -bool MotionTrigger::canUpdate(const TriggerUpdateEvent &event) const -{ const auto &castedEvent = dynamic_cast(event); return m_speed == TriggerSpeed::Any || m_speed == castedEvent.speed(); } -bool MotionTrigger::hasSpeed() const +bool MotionTriggerCore::hasSpeed() const { return m_speed != TriggerSpeed::Any; } diff --git a/src/libinputactions/triggers/MotionTrigger.h b/src/libinputactions/triggers/core/MotionTriggerCore.h similarity index 80% rename from src/libinputactions/triggers/MotionTrigger.h rename to src/libinputactions/triggers/core/MotionTriggerCore.h index 51a53b8..833e09b 100644 --- a/src/libinputactions/triggers/MotionTrigger.h +++ b/src/libinputactions/triggers/core/MotionTriggerCore.h @@ -18,7 +18,8 @@ #pragma once -#include "Trigger.h" +#include "TriggerCore.h" +#include namespace InputActions { @@ -47,29 +48,16 @@ class MotionTriggerUpdateEvent : public TriggerUpdateEvent /** * An input action that involves directionless motion. */ -class MotionTrigger : public Trigger +class MotionTriggerCore : public TriggerCore { public: - MotionTrigger(TriggerType type = TriggerType::None); - - /** - * @return Whether the speed matches. - * @see Trigger::canUpdate - */ - bool canUpdate(const TriggerUpdateEvent &event) const override; - bool hasSpeed() const; TriggerSpeed speed() const { return m_speed; } void setSpeed(TriggerSpeed value) { m_speed = value; } - /** - * Lock the pointer while this trigger is active. Only applies to mouse triggers. - */ - bool lockPointer() const { return m_lockPointer; } - void setLockPointer(bool value) { m_lockPointer = value; } + bool canUpdate(const TriggerUpdateEvent &event) const override; private: - bool m_lockPointer{}; TriggerSpeed m_speed = TriggerSpeed::Any; }; diff --git a/src/libinputactions/triggers/StrokeTrigger.cpp b/src/libinputactions/triggers/core/StrokeTriggerCore.cpp similarity index 97% rename from src/libinputactions/triggers/StrokeTrigger.cpp rename to src/libinputactions/triggers/core/StrokeTriggerCore.cpp index 5d44617..850eaff 100644 --- a/src/libinputactions/triggers/StrokeTrigger.cpp +++ b/src/libinputactions/triggers/core/StrokeTriggerCore.cpp @@ -33,7 +33,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "StrokeTrigger.h" +#include "StrokeTriggerCore.h" #include #include #include @@ -44,17 +44,11 @@ namespace InputActions static const qreal SHARP_TURN_ANGLE_THRESHOLD = 30 * M_PI / 180; -StrokeTrigger::StrokeTrigger(std::vector strokes) - : MotionTrigger(TriggerType::Stroke) - , m_strokes(std::move(strokes)) +StrokeTriggerCore::StrokeTriggerCore(std::vector strokes) + : m_strokes(std::move(strokes)) { } -const std::vector &StrokeTrigger::strokes() const -{ - return m_strokes; -} - constexpr double stroke_infinity = 0.2; #define EPS 0.000001 diff --git a/src/libinputactions/triggers/StrokeTrigger.h b/src/libinputactions/triggers/core/StrokeTriggerCore.h similarity index 91% rename from src/libinputactions/triggers/StrokeTrigger.h rename to src/libinputactions/triggers/core/StrokeTriggerCore.h index cf26cd7..524a4d7 100644 --- a/src/libinputactions/triggers/StrokeTrigger.h +++ b/src/libinputactions/triggers/core/StrokeTriggerCore.h @@ -34,7 +34,8 @@ #pragma once -#include "MotionTrigger.h" +#include "MotionTriggerCore.h" +#include namespace InputActions { @@ -83,14 +84,14 @@ class Stroke }; /** - * A motion input action where a shape is drawn. + * Draw a shape. */ -class StrokeTrigger : public MotionTrigger +class StrokeTriggerCore : public MotionTriggerCore { public: - StrokeTrigger(std::vector strokes); + StrokeTriggerCore(std::vector strokes); - const std::vector &strokes() const; + const std::vector &strokes() const { return m_strokes; } private: std::vector m_strokes; diff --git a/src/libinputactions/triggers/SwipeTrigger.cpp b/src/libinputactions/triggers/core/SwipeTriggerCore.cpp similarity index 68% rename from src/libinputactions/triggers/SwipeTrigger.cpp rename to src/libinputactions/triggers/core/SwipeTriggerCore.cpp index 8a1acb8..6238bff 100644 --- a/src/libinputactions/triggers/SwipeTrigger.cpp +++ b/src/libinputactions/triggers/core/SwipeTriggerCore.cpp @@ -16,7 +16,7 @@ along with this program. If not, see . */ -#include "SwipeTrigger.h" +#include "SwipeTriggerCore.h" #include #include #include @@ -24,30 +24,28 @@ namespace InputActions { -SwipeTrigger::SwipeTrigger(qreal minAngle, qreal maxAngle) - : MotionTrigger(TriggerType::Swipe) - , m_minAngle(minAngle) +SwipeTriggerCore::SwipeTriggerCore(qreal minAngle, qreal maxAngle) + : m_minAngle(minAngle) , m_maxAngle(maxAngle) { } -SwipeTrigger::SwipeTrigger(SwipeTriggerDirection direction) - : MotionTrigger(TriggerType::Swipe) - , m_direction(direction) +SwipeTriggerCore::SwipeTriggerCore(SwipeDirection direction) + : m_direction(direction) { switch (direction) { - case SwipeTriggerDirection::LeftRight: - case SwipeTriggerDirection::UpDown: - case SwipeTriggerDirection::LeftUpRightDown: - case SwipeTriggerDirection::LeftDownRightUp: + case SwipeDirection::LeftRight: + case SwipeDirection::UpDown: + case SwipeDirection::LeftUpRightDown: + case SwipeDirection::LeftDownRightUp: m_bidirectional = true; break; } } -bool SwipeTrigger::canUpdate(const TriggerUpdateEvent &event) const +bool SwipeTriggerCore::canUpdate(const TriggerUpdateEvent &event) const { - if (!MotionTrigger::canUpdate(event)) { + if (!MotionTriggerCore::canUpdate(event)) { return false; } @@ -58,7 +56,7 @@ bool SwipeTrigger::canUpdate(const TriggerUpdateEvent &event) const return matchesAngleRange(angle, range.min, range.max) || (m_bidirectional && matchesOppositeAngleRange(angle, range.min, range.max)); } -void SwipeTrigger::updateActions(const TriggerUpdateEvent &event) +void SwipeTriggerCore::updateActions(const std::vector> &actions, const TriggerUpdateEvent &event) const { auto newEvent = dynamic_cast(event); const auto angle = newEvent.angle(); @@ -72,10 +70,10 @@ void SwipeTrigger::updateActions(const TriggerUpdateEvent &event) newEvent.setDelta(delta); } - MotionTrigger::updateActions(newEvent); + MotionTriggerCore::updateActions(actions, newEvent); } -SwipeTrigger::AngleRange SwipeTrigger::angleRange(const InputDevice *device) const +SwipeTriggerCore::AngleRange SwipeTriggerCore::angleRange(const InputDevice *device) const { if (!m_direction) { return {m_minAngle, m_maxAngle}; @@ -83,35 +81,35 @@ SwipeTrigger::AngleRange SwipeTrigger::angleRange(const InputDevice *device) con const auto tolerance = device ? device->properties().swipeAngleTolerance() : DEFAULT_SWIPE_ANGLE_TOLERANGE; switch (m_direction.value()) { - case SwipeTriggerDirection::Left: + case SwipeDirection::Left: return {180 - tolerance, 180 + tolerance}; - case SwipeTriggerDirection::Right: + case SwipeDirection::Right: return {360 - tolerance, tolerance}; - case SwipeTriggerDirection::Up: + case SwipeDirection::Up: return {90 - tolerance, 90 + tolerance}; - case SwipeTriggerDirection::Down: + case SwipeDirection::Down: return {270 - tolerance, 270 + tolerance}; - case SwipeTriggerDirection::LeftUp: + case SwipeDirection::LeftUp: return {90 + tolerance, 180 - tolerance}; - case SwipeTriggerDirection::LeftDown: + case SwipeDirection::LeftDown: return {180 + tolerance, 270 - tolerance}; - case SwipeTriggerDirection::RightUp: + case SwipeDirection::RightUp: return {tolerance, 90 - tolerance}; - case SwipeTriggerDirection::RightDown: + case SwipeDirection::RightDown: return {270 + tolerance, 360 - tolerance}; - case SwipeTriggerDirection::LeftRight: + case SwipeDirection::LeftRight: return {360 - tolerance, tolerance}; - case SwipeTriggerDirection::UpDown: + case SwipeDirection::UpDown: return {270 - tolerance, 270 + tolerance}; - case SwipeTriggerDirection::LeftUpRightDown: + case SwipeDirection::LeftUpRightDown: return {270 + tolerance, 360 - tolerance}; - case SwipeTriggerDirection::LeftDownRightUp: + case SwipeDirection::LeftDownRightUp: return {tolerance, 90 - tolerance}; - case SwipeTriggerDirection::Any: + case SwipeDirection::Any: return {0, 360}; default: @@ -119,7 +117,7 @@ SwipeTrigger::AngleRange SwipeTrigger::angleRange(const InputDevice *device) con } } -bool SwipeTrigger::matchesAngleRange(qreal angle, qreal min, qreal max) +bool SwipeTriggerCore::matchesAngleRange(qreal angle, qreal min, qreal max) { if (min <= max) { return angle >= min && angle <= max; @@ -127,7 +125,7 @@ bool SwipeTrigger::matchesAngleRange(qreal angle, qreal min, qreal max) return angle >= min || angle <= max; } -bool SwipeTrigger::matchesOppositeAngleRange(qreal angle, qreal min, qreal max) +bool SwipeTriggerCore::matchesOppositeAngleRange(qreal angle, qreal min, qreal max) { min -= 180; if (min < 0) { @@ -145,7 +143,7 @@ bool SwipeTrigger::matchesOppositeAngleRange(qreal angle, qreal min, qreal max) return angle >= min || angle <= max; } -SwipeTrigger::AngleRange::AngleRange(qreal min, qreal max) +SwipeTriggerCore::AngleRange::AngleRange(qreal min, qreal max) : min(min) , max(max) { diff --git a/src/libinputactions/triggers/SwipeTrigger.h b/src/libinputactions/triggers/core/SwipeTriggerCore.h similarity index 89% rename from src/libinputactions/triggers/SwipeTrigger.h rename to src/libinputactions/triggers/core/SwipeTriggerCore.h index 4e406a7..2f99918 100644 --- a/src/libinputactions/triggers/SwipeTrigger.h +++ b/src/libinputactions/triggers/core/SwipeTriggerCore.h @@ -18,7 +18,7 @@ #pragma once -#include "MotionTrigger.h" +#include "MotionTriggerCore.h" namespace InputActions { @@ -62,7 +62,7 @@ class SwipeTriggerUpdateEvent : public MotionTriggerUpdateEvent /** * For bidirectional values, the first direction named in the enum will always have a negative delta, and the second direction will have a positive one. */ -enum class SwipeTriggerDirection +enum class SwipeDirection { Left, Right, @@ -95,15 +95,15 @@ enum class SwipeTriggerDirection * If swipe triggers are active and the motion angle changes, but none of the active triggers acccept it, they are cancelled and all swipe triggers are * activated again, allowing for chaining multiple triggers together. */ -class SwipeTrigger : public MotionTrigger +class SwipeTriggerCore : public MotionTriggerCore { public: /** * If minAngle < maxAngle, the range includes all values where x >= minAngle && x <= maxAngle. * If minAngle > maxAngle, the range includes all values where x >= minAngle || x <= maxAngle. */ - SwipeTrigger(qreal minAngle, qreal maxAngle); - SwipeTrigger(SwipeTriggerDirection direction); + SwipeTriggerCore(qreal minAngle, qreal maxAngle); + SwipeTriggerCore(SwipeDirection direction); qreal minAngle() const { return m_minAngle; } qreal maxAngle() const { return m_maxAngle; } @@ -112,12 +112,11 @@ class SwipeTrigger : public MotionTrigger * Whether motion in the opposite angle range is valid as well. Such motion will have a negative delta. In case of overlapping ranges, the normal one has * the higher priority. */ + bool bidirectional() const { return m_bidirectional; } void setBidirectional(bool value) { m_bidirectional = value; } bool canUpdate(const TriggerUpdateEvent &event) const override; - -protected: - void updateActions(const TriggerUpdateEvent &event) override; + void updateActions(const std::vector> &actions, const TriggerUpdateEvent &event) const override; private: struct AngleRange @@ -135,13 +134,13 @@ class SwipeTrigger : public MotionTrigger static bool matchesAngleRange(qreal angle, qreal min, qreal max); static bool matchesOppositeAngleRange(qreal angle, qreal min, qreal max); - std::optional m_direction; + std::optional m_direction; qreal m_minAngle{}; qreal m_maxAngle{}; bool m_bidirectional{}; - friend class TestSwipeTrigger; + friend class TestSwipeTriggerCore; }; } \ No newline at end of file diff --git a/src/libinputactions/triggers/core/TimeTriggerCore.cpp b/src/libinputactions/triggers/core/TimeTriggerCore.cpp new file mode 100644 index 0000000..eb6426d --- /dev/null +++ b/src/libinputactions/triggers/core/TimeTriggerCore.cpp @@ -0,0 +1,23 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TimeTriggerCore.h" + +namespace InputActions +{ +} \ No newline at end of file diff --git a/src/libinputactions/triggers/PressTrigger.cpp b/src/libinputactions/triggers/core/TimeTriggerCore.h similarity index 89% rename from src/libinputactions/triggers/PressTrigger.cpp rename to src/libinputactions/triggers/core/TimeTriggerCore.h index 007e42a..4d94724 100644 --- a/src/libinputactions/triggers/PressTrigger.cpp +++ b/src/libinputactions/triggers/core/TimeTriggerCore.h @@ -16,14 +16,15 @@ along with this program. If not, see . */ -#include "PressTrigger.h" +#pragma once + +#include "TriggerCore.h" namespace InputActions { -PressTrigger::PressTrigger() - : Trigger(TriggerType::Press) +class TimeTriggerCore : public TriggerCore { -} +}; } \ No newline at end of file diff --git a/src/libinputactions/triggers/core/TriggerCore.cpp b/src/libinputactions/triggers/core/TriggerCore.cpp new file mode 100644 index 0000000..ce3877e --- /dev/null +++ b/src/libinputactions/triggers/core/TriggerCore.cpp @@ -0,0 +1,43 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TriggerCore.h" +#include +#include + +namespace InputActions +{ + +bool TriggerCore::canUpdate(const TriggerUpdateEvent &event) const +{ + return true; +} + +void TriggerCore::updateActions(const std::vector> &actions, const TriggerUpdateEvent &event) const +{ + doUpdateActions(actions, event); +} + +void TriggerCore::doUpdateActions(const std::vector> &actions, const TriggerUpdateEvent &event) const +{ + for (const auto &action : actions) { + action->triggerUpdated(event); + } +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/core/TriggerCore.h b/src/libinputactions/triggers/core/TriggerCore.h new file mode 100644 index 0000000..d0f4a22 --- /dev/null +++ b/src/libinputactions/triggers/core/TriggerCore.h @@ -0,0 +1,51 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include +#include + +namespace InputActions +{ + +class TriggerAction; +class TriggerUpdateEvent; + +/** + * A set of trigger properties and behaviors that can be shared between triggers of the same type but for different devices. + */ +class TriggerCore +{ +public: + TriggerCore() = default; + virtual ~TriggerCore() = default; + + virtual bool canUpdate(const TriggerUpdateEvent &event) const; + /** + * Override to modify the event before passing it to actions. Must be called by the overriding method. + */ + virtual void updateActions(const std::vector> &actions, const TriggerUpdateEvent &event) const; + +private: + TEST_VIRTUAL void doUpdateActions(const std::vector> &actions, const TriggerUpdateEvent &event) const; + + friend class MockSwipeTriggerCore; +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/KeyboardShortcutTrigger.cpp b/src/libinputactions/triggers/keyboard/KeyboardShortcutTrigger.cpp similarity index 75% rename from src/libinputactions/triggers/KeyboardShortcutTrigger.cpp rename to src/libinputactions/triggers/keyboard/KeyboardShortcutTrigger.cpp index 0261d3f..b3fa0a3 100644 --- a/src/libinputactions/triggers/KeyboardShortcutTrigger.cpp +++ b/src/libinputactions/triggers/keyboard/KeyboardShortcutTrigger.cpp @@ -17,12 +17,19 @@ */ #include "KeyboardShortcutTrigger.h" +#include namespace InputActions { KeyboardShortcutTrigger::KeyboardShortcutTrigger(KeyboardShortcut shortcut) - : Trigger(TriggerType::KeyboardShortcut) + : KeyboardTrigger(TriggerType::KeyboardShortcut, std::make_unique()) + , m_shortcut(std::move(shortcut)) +{ +} + +KeyboardShortcutTrigger::KeyboardShortcutTrigger(KeyboardShortcut shortcut, std::unique_ptr core) + : KeyboardTrigger(TriggerType::KeyboardShortcut, std::move(core)) , m_shortcut(std::move(shortcut)) { } diff --git a/src/libinputactions/triggers/KeyboardShortcutTrigger.h b/src/libinputactions/triggers/keyboard/KeyboardShortcutTrigger.h similarity index 81% rename from src/libinputactions/triggers/KeyboardShortcutTrigger.h rename to src/libinputactions/triggers/keyboard/KeyboardShortcutTrigger.h index 2d3e7af..e8e8383 100644 --- a/src/libinputactions/triggers/KeyboardShortcutTrigger.h +++ b/src/libinputactions/triggers/keyboard/KeyboardShortcutTrigger.h @@ -18,11 +18,13 @@ #pragma once -#include "Trigger.h" +#include "KeyboardTrigger.h" namespace InputActions { +class TimeTriggerCore; + struct KeyboardShortcut { /** @@ -31,10 +33,13 @@ struct KeyboardShortcut std::set keys; }; -class KeyboardShortcutTrigger : public Trigger +class KeyboardShortcutTrigger : public KeyboardTrigger { public: KeyboardShortcutTrigger(KeyboardShortcut shortcut); + KeyboardShortcutTrigger(KeyboardShortcut shortcut, std::unique_ptr core); + + const KeyboardShortcut &shortcut() const { return m_shortcut; } bool canActivate(const TriggerActivationEvent &event) const override; diff --git a/src/libinputactions/triggers/HoverTrigger.cpp b/src/libinputactions/triggers/keyboard/KeyboardTrigger.cpp similarity index 70% rename from src/libinputactions/triggers/HoverTrigger.cpp rename to src/libinputactions/triggers/keyboard/KeyboardTrigger.cpp index 4a6fee6..f74f294 100644 --- a/src/libinputactions/triggers/HoverTrigger.cpp +++ b/src/libinputactions/triggers/keyboard/KeyboardTrigger.cpp @@ -16,24 +16,15 @@ along with this program. If not, see . */ -#include "HoverTrigger.h" +#include "KeyboardTrigger.h" +#include namespace InputActions { -HoverTrigger::HoverTrigger() - : Trigger(TriggerType::Hover) +KeyboardTrigger::KeyboardTrigger(TriggerType type, std::unique_ptr core) + : Trigger(type, std::move(core)) { } -bool HoverTrigger::canUpdate(const TriggerUpdateEvent &event) const -{ - return Trigger::canUpdate(event) && (!activationCondition() || activationCondition()->satisfied()); -} - -bool HoverTrigger::endIfCannotUpdate() const -{ - return true; -} - } \ No newline at end of file diff --git a/src/libinputactions/triggers/keyboard/KeyboardTrigger.h b/src/libinputactions/triggers/keyboard/KeyboardTrigger.h new file mode 100644 index 0000000..d106513 --- /dev/null +++ b/src/libinputactions/triggers/keyboard/KeyboardTrigger.h @@ -0,0 +1,32 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include + +namespace InputActions +{ + +class KeyboardTrigger : public Trigger +{ +protected: + KeyboardTrigger(TriggerType type, std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/mouse/MouseCircleTrigger.cpp b/src/libinputactions/triggers/mouse/MouseCircleTrigger.cpp new file mode 100644 index 0000000..03eb0f6 --- /dev/null +++ b/src/libinputactions/triggers/mouse/MouseCircleTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "MouseCircleTrigger.h" +#include + +namespace InputActions +{ + +MouseCircleTrigger::MouseCircleTrigger(std::unique_ptr core) + : MouseMotionTrigger(TriggerType::Circle, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/mouse/MouseCircleTrigger.h b/src/libinputactions/triggers/mouse/MouseCircleTrigger.h new file mode 100644 index 0000000..e8ab1fd --- /dev/null +++ b/src/libinputactions/triggers/mouse/MouseCircleTrigger.h @@ -0,0 +1,34 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "MouseMotionTrigger.h" + +namespace InputActions +{ + +class RotateTriggerCore; + +class MouseCircleTrigger : public MouseMotionTrigger +{ +public: + MouseCircleTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/mouse/MouseMotionTrigger.cpp b/src/libinputactions/triggers/mouse/MouseMotionTrigger.cpp new file mode 100644 index 0000000..e1d1741 --- /dev/null +++ b/src/libinputactions/triggers/mouse/MouseMotionTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "MouseMotionTrigger.h" +#include + +namespace InputActions +{ + +MouseMotionTrigger::MouseMotionTrigger(TriggerType type, std::unique_ptr core) + : MouseTrigger(type, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/mouse/MouseMotionTrigger.h b/src/libinputactions/triggers/mouse/MouseMotionTrigger.h new file mode 100644 index 0000000..0456b6f --- /dev/null +++ b/src/libinputactions/triggers/mouse/MouseMotionTrigger.h @@ -0,0 +1,44 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "MouseTrigger.h" + +namespace InputActions +{ + +class MotionTriggerCore; + +class MouseMotionTrigger : public MouseTrigger +{ +public: + /** + * Lock the mouse pointer while this trigger is active. + */ + bool lockPointer() const { return m_lockPointer; } + void setLockPointer(bool value) { m_lockPointer = value; } + +protected: + MouseMotionTrigger(TriggerType type, std::unique_ptr core); + +private: + bool m_lockPointer{}; +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/mouse/MousePressTrigger.cpp b/src/libinputactions/triggers/mouse/MousePressTrigger.cpp new file mode 100644 index 0000000..d5a9f82 --- /dev/null +++ b/src/libinputactions/triggers/mouse/MousePressTrigger.cpp @@ -0,0 +1,35 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "MousePressTrigger.h" +#include + +namespace InputActions +{ + +MousePressTrigger::MousePressTrigger() + : MouseTrigger(TriggerType::Press, std::make_unique()) +{ +} + +MousePressTrigger::MousePressTrigger(std::unique_ptr core) + : MouseTrigger(TriggerType::Press, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/PressTrigger.h b/src/libinputactions/triggers/mouse/MousePressTrigger.h similarity index 82% rename from src/libinputactions/triggers/PressTrigger.h rename to src/libinputactions/triggers/mouse/MousePressTrigger.h index 9aabc0f..e19cd7e 100644 --- a/src/libinputactions/triggers/PressTrigger.h +++ b/src/libinputactions/triggers/mouse/MousePressTrigger.h @@ -18,18 +18,21 @@ #pragma once -#include "Trigger.h" +#include "MouseTrigger.h" namespace InputActions { -class PressTrigger : public Trigger +class TimeTriggerCore; + +class MousePressTrigger : public MouseTrigger { public: - PressTrigger(); + MousePressTrigger(); + MousePressTrigger(std::unique_ptr core); /** - * Whether the trigger should be activated immediately, preventing normal clicks from being performed. Currently only applies to mouse gestures. + * Whether the trigger should be activated immediately, preventing normal clicks from being performed. */ bool instant() const { return m_instant; } void setInstant(bool value) { m_instant = value; } diff --git a/src/libinputactions/triggers/mouse/MouseStrokeTrigger.cpp b/src/libinputactions/triggers/mouse/MouseStrokeTrigger.cpp new file mode 100644 index 0000000..8e130ab --- /dev/null +++ b/src/libinputactions/triggers/mouse/MouseStrokeTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "MouseStrokeTrigger.h" +#include + +namespace InputActions +{ + +MouseStrokeTrigger::MouseStrokeTrigger(std::unique_ptr core) + : MouseMotionTrigger(TriggerType::Stroke, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/mouse/MouseStrokeTrigger.h b/src/libinputactions/triggers/mouse/MouseStrokeTrigger.h new file mode 100644 index 0000000..0b0940b --- /dev/null +++ b/src/libinputactions/triggers/mouse/MouseStrokeTrigger.h @@ -0,0 +1,34 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "MouseMotionTrigger.h" + +namespace InputActions +{ + +class StrokeTriggerCore; + +class MouseStrokeTrigger : public MouseMotionTrigger +{ +public: + MouseStrokeTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/mouse/MouseSwipeTrigger.cpp b/src/libinputactions/triggers/mouse/MouseSwipeTrigger.cpp new file mode 100644 index 0000000..6dd7e9c --- /dev/null +++ b/src/libinputactions/triggers/mouse/MouseSwipeTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "MouseSwipeTrigger.h" +#include + +namespace InputActions +{ + +MouseSwipeTrigger::MouseSwipeTrigger(std::unique_ptr core) + : MouseMotionTrigger(TriggerType::Swipe, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/mouse/MouseSwipeTrigger.h b/src/libinputactions/triggers/mouse/MouseSwipeTrigger.h new file mode 100644 index 0000000..5b94bb5 --- /dev/null +++ b/src/libinputactions/triggers/mouse/MouseSwipeTrigger.h @@ -0,0 +1,34 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "MouseMotionTrigger.h" + +namespace InputActions +{ + +class SwipeTriggerCore; + +class MouseSwipeTrigger : public MouseMotionTrigger +{ +public: + MouseSwipeTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/mouse/MouseTrigger.cpp b/src/libinputactions/triggers/mouse/MouseTrigger.cpp new file mode 100644 index 0000000..2e96ebd --- /dev/null +++ b/src/libinputactions/triggers/mouse/MouseTrigger.cpp @@ -0,0 +1,48 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "MouseTrigger.h" +#include +#include + +namespace InputActions +{ + +MouseTrigger::MouseTrigger(TriggerType type, std::unique_ptr core) + : Trigger(type, std::move(core)) +{ +} + +MouseTrigger::~MouseTrigger() = default; + +bool MouseTrigger::canActivate(const TriggerActivationEvent &event) const +{ + if (!m_mouseButtons.empty() && event.mouseButtons().has_value()) { + if (m_mouseButtons.size() != event.mouseButtons()->size() + || (m_mouseButtonsExactOrder && !std::ranges::equal(m_mouseButtons, event.mouseButtons().value())) + || (!m_mouseButtonsExactOrder && !std::ranges::all_of(m_mouseButtons, [event](auto &button) { + return std::ranges::contains(event.mouseButtons().value(), button); + }))) { + return false; + } + } + + return Trigger::canActivate(event); +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/mouse/MouseTrigger.h b/src/libinputactions/triggers/mouse/MouseTrigger.h new file mode 100644 index 0000000..dd1eb0f --- /dev/null +++ b/src/libinputactions/triggers/mouse/MouseTrigger.h @@ -0,0 +1,56 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include + +namespace InputActions +{ + +class MouseButton; +class TriggerCore; + +class MouseTrigger : public Trigger +{ +public: + ~MouseTrigger() override; + + /** + * Mouse buttons that must be pressed before and during the trigger. + */ + const std::vector &mouseButtons() const { return m_mouseButtons; } + void setMouseButtons(std::vector value) { m_mouseButtons = std::move(value); } + + /** + * Whether mouse buttons must be pressed in order as specified. + */ + bool mouseButtonsExactOrder() const { return m_mouseButtonsExactOrder; } + void setMouseButtonsExactOrder(bool value) { m_mouseButtonsExactOrder = value; } + + bool canActivate(const TriggerActivationEvent &event) const override; + +protected: + MouseTrigger(TriggerType type, std::unique_ptr core); + +private: + std::vector m_mouseButtons; + bool m_mouseButtonsExactOrder{}; +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/WheelTrigger.cpp b/src/libinputactions/triggers/mouse/MouseWheelTrigger.cpp similarity index 71% rename from src/libinputactions/triggers/WheelTrigger.cpp rename to src/libinputactions/triggers/mouse/MouseWheelTrigger.cpp index 836af05..3f86d59 100644 --- a/src/libinputactions/triggers/WheelTrigger.cpp +++ b/src/libinputactions/triggers/mouse/MouseWheelTrigger.cpp @@ -16,27 +16,23 @@ along with this program. If not, see . */ -#include "WheelTrigger.h" +#include "MouseWheelTrigger.h" +#include namespace InputActions { -WheelTrigger::WheelTrigger(TriggerDirection direction) - : DirectionalMotionTrigger(TriggerType::Wheel, direction) +MouseWheelTrigger::MouseWheelTrigger(std::unique_ptr core) + : MouseMotionTrigger(TriggerType::Wheel, std::move(core)) { } -void WheelTrigger::actionAdded(TriggerAction *action) +void MouseWheelTrigger::actionAdded(TriggerAction *action) { - DirectionalMotionTrigger::actionAdded(action); + MouseMotionTrigger::actionAdded(action); if (action->on() == On::Update) { m_continuous = true; } } -bool WheelTrigger::continuous() const -{ - return m_continuous; -} - } \ No newline at end of file diff --git a/src/libinputactions/triggers/WheelTrigger.h b/src/libinputactions/triggers/mouse/MouseWheelTrigger.h similarity index 83% rename from src/libinputactions/triggers/WheelTrigger.h rename to src/libinputactions/triggers/mouse/MouseWheelTrigger.h index 43d92e2..49a2dee 100644 --- a/src/libinputactions/triggers/WheelTrigger.h +++ b/src/libinputactions/triggers/mouse/MouseWheelTrigger.h @@ -18,21 +18,23 @@ #pragma once -#include "DirectionalMotionTrigger.h" +#include "MouseMotionTrigger.h" namespace InputActions { +class SimpleSwipeTriggerCore; + /** * Wheel triggers are continuous when an update action is present and a mouse button or a keyboard modifier is present. Continuous triggers begin on a scroll * event and end on modifier or button release. Non-continuous triggers begin and end on the same scroll event. */ -class WheelTrigger : public DirectionalMotionTrigger +class MouseWheelTrigger : public MouseMotionTrigger { public: - WheelTrigger(TriggerDirection direction); + MouseWheelTrigger(std::unique_ptr core); - bool continuous() const; + bool continuous() const { return m_continuous; } protected: void actionAdded(TriggerAction *action) override; diff --git a/src/libinputactions/triggers/pointer/PointerHoverTrigger.cpp b/src/libinputactions/triggers/pointer/PointerHoverTrigger.cpp new file mode 100644 index 0000000..4a9aff3 --- /dev/null +++ b/src/libinputactions/triggers/pointer/PointerHoverTrigger.cpp @@ -0,0 +1,45 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "PointerHoverTrigger.h" +#include + +namespace InputActions +{ + +PointerHoverTrigger::PointerHoverTrigger() + : PointerTrigger(TriggerType::Hover, std::make_unique()) +{ +} + +PointerHoverTrigger::PointerHoverTrigger(std::unique_ptr core) + : PointerTrigger(TriggerType::Hover, std::move(core)) +{ +} + +bool PointerHoverTrigger::canUpdate(const TriggerUpdateEvent &event) const +{ + return Trigger::canUpdate(event) && (!activationCondition() || activationCondition()->satisfied()); +} + +bool PointerHoverTrigger::endIfCannotUpdate() const +{ + return true; +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/HoverTrigger.h b/src/libinputactions/triggers/pointer/PointerHoverTrigger.h similarity index 83% rename from src/libinputactions/triggers/HoverTrigger.h rename to src/libinputactions/triggers/pointer/PointerHoverTrigger.h index c58cb68..69e78fd 100644 --- a/src/libinputactions/triggers/HoverTrigger.h +++ b/src/libinputactions/triggers/pointer/PointerHoverTrigger.h @@ -18,15 +18,18 @@ #pragma once -#include "Trigger.h" +#include "PointerTrigger.h" namespace InputActions { -class HoverTrigger : public Trigger +class TimeTriggerCore; + +class PointerHoverTrigger : public PointerTrigger { public: - HoverTrigger(); + PointerHoverTrigger(); + PointerHoverTrigger(std::unique_ptr core); bool canUpdate(const TriggerUpdateEvent &event) const override; bool endIfCannotUpdate() const override; diff --git a/src/libinputactions/triggers/pointer/PointerTrigger.cpp b/src/libinputactions/triggers/pointer/PointerTrigger.cpp new file mode 100644 index 0000000..b58ee47 --- /dev/null +++ b/src/libinputactions/triggers/pointer/PointerTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "PointerTrigger.h" +#include + +namespace InputActions +{ + +PointerTrigger::PointerTrigger(TriggerType type, std::unique_ptr core) + : Trigger(type, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/pointer/PointerTrigger.h b/src/libinputactions/triggers/pointer/PointerTrigger.h new file mode 100644 index 0000000..57a287a --- /dev/null +++ b/src/libinputactions/triggers/pointer/PointerTrigger.h @@ -0,0 +1,32 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include + +namespace InputActions +{ + +class PointerTrigger : public Trigger +{ +protected: + PointerTrigger(TriggerType type, std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadCircleTrigger.cpp b/src/libinputactions/triggers/touchpad/TouchpadCircleTrigger.cpp new file mode 100644 index 0000000..f8b049a --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadCircleTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchpadCircleTrigger.h" +#include + +namespace InputActions +{ + +TouchpadCircleTrigger::TouchpadCircleTrigger(std::unique_ptr core) + : TouchpadTrigger(TriggerType::Circle, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadCircleTrigger.h b/src/libinputactions/triggers/touchpad/TouchpadCircleTrigger.h new file mode 100644 index 0000000..a3c9a45 --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadCircleTrigger.h @@ -0,0 +1,34 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchpadTrigger.h" + +namespace InputActions +{ + +class RotateTriggerCore; + +class TouchpadCircleTrigger : public TouchpadTrigger +{ +public: + TouchpadCircleTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadClickTrigger.cpp b/src/libinputactions/triggers/touchpad/TouchpadClickTrigger.cpp new file mode 100644 index 0000000..cb31623 --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadClickTrigger.cpp @@ -0,0 +1,35 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchpadClickTrigger.h" +#include + +namespace InputActions +{ + +TouchpadClickTrigger::TouchpadClickTrigger() + : TouchpadTrigger(TriggerType::Click, std::make_unique()) +{ +} + +TouchpadClickTrigger::TouchpadClickTrigger(std::unique_ptr core) + : TouchpadTrigger(TriggerType::Click, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadClickTrigger.h b/src/libinputactions/triggers/touchpad/TouchpadClickTrigger.h new file mode 100644 index 0000000..39347f2 --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadClickTrigger.h @@ -0,0 +1,35 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchpadTrigger.h" + +namespace InputActions +{ + +class TimeTriggerCore; + +class TouchpadClickTrigger : public TouchpadTrigger +{ +public: + TouchpadClickTrigger(); + TouchpadClickTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadHoldTrigger.cpp b/src/libinputactions/triggers/touchpad/TouchpadHoldTrigger.cpp new file mode 100644 index 0000000..e0f069f --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadHoldTrigger.cpp @@ -0,0 +1,35 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchpadHoldTrigger.h" +#include + +namespace InputActions +{ + +TouchpadHoldTrigger::TouchpadHoldTrigger() + : TouchpadTrigger(TriggerType::Press, std::make_unique()) +{ +} + +TouchpadHoldTrigger::TouchpadHoldTrigger(std::unique_ptr core) + : TouchpadTrigger(TriggerType::Press, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadHoldTrigger.h b/src/libinputactions/triggers/touchpad/TouchpadHoldTrigger.h new file mode 100644 index 0000000..f7eda93 --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadHoldTrigger.h @@ -0,0 +1,35 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchpadTrigger.h" + +namespace InputActions +{ + +class TimeTriggerCore; + +class TouchpadHoldTrigger : public TouchpadTrigger +{ +public: + TouchpadHoldTrigger(); + TouchpadHoldTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadPinchTrigger.cpp b/src/libinputactions/triggers/touchpad/TouchpadPinchTrigger.cpp new file mode 100644 index 0000000..7284dbc --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadPinchTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchpadPinchTrigger.h" +#include + +namespace InputActions +{ + +TouchpadPinchTrigger::TouchpadPinchTrigger(std::unique_ptr core) + : TouchpadTrigger(TriggerType::Pinch, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadPinchTrigger.h b/src/libinputactions/triggers/touchpad/TouchpadPinchTrigger.h new file mode 100644 index 0000000..b19b5d6 --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadPinchTrigger.h @@ -0,0 +1,34 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchpadTrigger.h" + +namespace InputActions +{ + +class PinchTriggerCore; + +class TouchpadPinchTrigger : public TouchpadTrigger +{ +public: + TouchpadPinchTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadRotateTrigger.cpp b/src/libinputactions/triggers/touchpad/TouchpadRotateTrigger.cpp new file mode 100644 index 0000000..c129029 --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadRotateTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchpadRotateTrigger.h" +#include + +namespace InputActions +{ + +TouchpadRotateTrigger::TouchpadRotateTrigger(std::unique_ptr core) + : TouchpadTrigger(TriggerType::Rotate, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadRotateTrigger.h b/src/libinputactions/triggers/touchpad/TouchpadRotateTrigger.h new file mode 100644 index 0000000..b58f5ef --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadRotateTrigger.h @@ -0,0 +1,34 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchpadTrigger.h" + +namespace InputActions +{ + +class RotateTriggerCore; + +class TouchpadRotateTrigger : public TouchpadTrigger +{ +public: + TouchpadRotateTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadStrokeTrigger.cpp b/src/libinputactions/triggers/touchpad/TouchpadStrokeTrigger.cpp new file mode 100644 index 0000000..b1202ec --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadStrokeTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchpadStrokeTrigger.h" +#include + +namespace InputActions +{ + +TouchpadStrokeTrigger::TouchpadStrokeTrigger(std::unique_ptr core) + : TouchpadTrigger(TriggerType::Stroke, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadStrokeTrigger.h b/src/libinputactions/triggers/touchpad/TouchpadStrokeTrigger.h new file mode 100644 index 0000000..f5b6ffe --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadStrokeTrigger.h @@ -0,0 +1,34 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchpadTrigger.h" + +namespace InputActions +{ + +class StrokeTriggerCore; + +class TouchpadStrokeTrigger : public TouchpadTrigger +{ +public: + TouchpadStrokeTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadSwipeTrigger.cpp b/src/libinputactions/triggers/touchpad/TouchpadSwipeTrigger.cpp new file mode 100644 index 0000000..79d5296 --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadSwipeTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchpadSwipeTrigger.h" +#include + +namespace InputActions +{ + +TouchpadSwipeTrigger::TouchpadSwipeTrigger(std::unique_ptr core) + : TouchpadTrigger(TriggerType::Swipe, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadSwipeTrigger.h b/src/libinputactions/triggers/touchpad/TouchpadSwipeTrigger.h new file mode 100644 index 0000000..31f0872 --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadSwipeTrigger.h @@ -0,0 +1,34 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchpadTrigger.h" + +namespace InputActions +{ + +class SwipeTriggerCore; + +class TouchpadSwipeTrigger : public TouchpadTrigger +{ +public: + TouchpadSwipeTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadTapTrigger.cpp b/src/libinputactions/triggers/touchpad/TouchpadTapTrigger.cpp new file mode 100644 index 0000000..ab95c26 --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadTapTrigger.cpp @@ -0,0 +1,35 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchpadTapTrigger.h" +#include + +namespace InputActions +{ + +TouchpadTapTrigger::TouchpadTapTrigger() + : TouchpadTrigger(TriggerType::Tap, std::make_unique()) +{ +} + +TouchpadTapTrigger::TouchpadTapTrigger(std::unique_ptr core) + : TouchpadTrigger(TriggerType::Tap, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadTapTrigger.h b/src/libinputactions/triggers/touchpad/TouchpadTapTrigger.h new file mode 100644 index 0000000..9f51558 --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadTapTrigger.h @@ -0,0 +1,35 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchpadTrigger.h" + +namespace InputActions +{ + +class TimeTriggerCore; + +class TouchpadTapTrigger : public TouchpadTrigger +{ +public: + TouchpadTapTrigger(); + TouchpadTapTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadTrigger.cpp b/src/libinputactions/triggers/touchpad/TouchpadTrigger.cpp new file mode 100644 index 0000000..9c78242 --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchpadTrigger.h" +#include + +namespace InputActions +{ + +TouchpadTrigger::TouchpadTrigger(TriggerType type, std::unique_ptr core) + : Trigger(type, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchpad/TouchpadTrigger.h b/src/libinputactions/triggers/touchpad/TouchpadTrigger.h new file mode 100644 index 0000000..240d6ad --- /dev/null +++ b/src/libinputactions/triggers/touchpad/TouchpadTrigger.h @@ -0,0 +1,32 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include + +namespace InputActions +{ + +class TouchpadTrigger : public Trigger +{ +protected: + TouchpadTrigger(TriggerType type, std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenCircleTrigger.cpp b/src/libinputactions/triggers/touchscreen/TouchscreenCircleTrigger.cpp new file mode 100644 index 0000000..41a2899 --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenCircleTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchscreenCircleTrigger.h" +#include + +namespace InputActions +{ + +TouchscreenCircleTrigger::TouchscreenCircleTrigger(std::unique_ptr core) + : TouchscreenTrigger(TriggerType::Circle, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenCircleTrigger.h b/src/libinputactions/triggers/touchscreen/TouchscreenCircleTrigger.h new file mode 100644 index 0000000..99167f2 --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenCircleTrigger.h @@ -0,0 +1,34 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchscreenTrigger.h" + +namespace InputActions +{ + +class RotateTriggerCore; + +class TouchscreenCircleTrigger : public TouchscreenTrigger +{ +public: + TouchscreenCircleTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenHoldTrigger.cpp b/src/libinputactions/triggers/touchscreen/TouchscreenHoldTrigger.cpp new file mode 100644 index 0000000..1bf596a --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenHoldTrigger.cpp @@ -0,0 +1,35 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchscreenHoldTrigger.h" +#include + +namespace InputActions +{ + +TouchscreenHoldTrigger::TouchscreenHoldTrigger() + : TouchscreenTrigger(TriggerType::Press, std::make_unique()) +{ +} + +TouchscreenHoldTrigger::TouchscreenHoldTrigger(std::unique_ptr core) + : TouchscreenTrigger(TriggerType::Press, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenHoldTrigger.h b/src/libinputactions/triggers/touchscreen/TouchscreenHoldTrigger.h new file mode 100644 index 0000000..3d4d6b0 --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenHoldTrigger.h @@ -0,0 +1,35 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchscreenTrigger.h" + +namespace InputActions +{ + +class TimeTriggerCore; + +class TouchscreenHoldTrigger : public TouchscreenTrigger +{ +public: + TouchscreenHoldTrigger(); + TouchscreenHoldTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenPinchTrigger.cpp b/src/libinputactions/triggers/touchscreen/TouchscreenPinchTrigger.cpp new file mode 100644 index 0000000..1c87f3a --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenPinchTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchscreenPinchTrigger.h" +#include + +namespace InputActions +{ + +TouchscreenPinchTrigger::TouchscreenPinchTrigger(std::unique_ptr core) + : TouchscreenTrigger(TriggerType::Pinch, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenPinchTrigger.h b/src/libinputactions/triggers/touchscreen/TouchscreenPinchTrigger.h new file mode 100644 index 0000000..347aa26 --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenPinchTrigger.h @@ -0,0 +1,34 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchscreenTrigger.h" + +namespace InputActions +{ + +class PinchTriggerCore; + +class TouchscreenPinchTrigger : public TouchscreenTrigger +{ +public: + TouchscreenPinchTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenRotateTrigger.cpp b/src/libinputactions/triggers/touchscreen/TouchscreenRotateTrigger.cpp new file mode 100644 index 0000000..0f783cc --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenRotateTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchscreenRotateTrigger.h" +#include + +namespace InputActions +{ + +TouchscreenRotateTrigger::TouchscreenRotateTrigger(std::unique_ptr core) + : TouchscreenTrigger(TriggerType::Rotate, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenRotateTrigger.h b/src/libinputactions/triggers/touchscreen/TouchscreenRotateTrigger.h new file mode 100644 index 0000000..242e64e --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenRotateTrigger.h @@ -0,0 +1,34 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchscreenTrigger.h" + +namespace InputActions +{ + +class RotateTriggerCore; + +class TouchscreenRotateTrigger : public TouchscreenTrigger +{ +public: + TouchscreenRotateTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenStrokeTrigger.cpp b/src/libinputactions/triggers/touchscreen/TouchscreenStrokeTrigger.cpp new file mode 100644 index 0000000..195fa14 --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenStrokeTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchscreenStrokeTrigger.h" +#include + +namespace InputActions +{ + +TouchscreenStrokeTrigger::TouchscreenStrokeTrigger(std::unique_ptr core) + : TouchscreenTrigger(TriggerType::Stroke, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenStrokeTrigger.h b/src/libinputactions/triggers/touchscreen/TouchscreenStrokeTrigger.h new file mode 100644 index 0000000..8f77dc7 --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenStrokeTrigger.h @@ -0,0 +1,34 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchscreenTrigger.h" + +namespace InputActions +{ + +class StrokeTriggerCore; + +class TouchscreenStrokeTrigger : public TouchscreenTrigger +{ +public: + TouchscreenStrokeTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenSwipeTrigger.cpp b/src/libinputactions/triggers/touchscreen/TouchscreenSwipeTrigger.cpp new file mode 100644 index 0000000..2f55090 --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenSwipeTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchscreenSwipeTrigger.h" +#include + +namespace InputActions +{ + +TouchscreenSwipeTrigger::TouchscreenSwipeTrigger(std::unique_ptr core) + : TouchscreenTrigger(TriggerType::Swipe, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenSwipeTrigger.h b/src/libinputactions/triggers/touchscreen/TouchscreenSwipeTrigger.h new file mode 100644 index 0000000..6419bca --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenSwipeTrigger.h @@ -0,0 +1,34 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchscreenTrigger.h" + +namespace InputActions +{ + +class SwipeTriggerCore; + +class TouchscreenSwipeTrigger : public TouchscreenTrigger +{ +public: + TouchscreenSwipeTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenTapTrigger.cpp b/src/libinputactions/triggers/touchscreen/TouchscreenTapTrigger.cpp new file mode 100644 index 0000000..2ac5f0f --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenTapTrigger.cpp @@ -0,0 +1,35 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchscreenTapTrigger.h" +#include + +namespace InputActions +{ + +TouchscreenTapTrigger::TouchscreenTapTrigger() + : TouchscreenTrigger(TriggerType::Tap, std::make_unique()) +{ +} + +TouchscreenTapTrigger::TouchscreenTapTrigger(std::unique_ptr core) + : TouchscreenTrigger(TriggerType::Tap, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenTapTrigger.h b/src/libinputactions/triggers/touchscreen/TouchscreenTapTrigger.h new file mode 100644 index 0000000..005bb11 --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenTapTrigger.h @@ -0,0 +1,35 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include "TouchscreenTrigger.h" + +namespace InputActions +{ + +class TimeTriggerCore; + +class TouchscreenTapTrigger : public TouchscreenTrigger +{ +public: + TouchscreenTapTrigger(); + TouchscreenTapTrigger(std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenTrigger.cpp b/src/libinputactions/triggers/touchscreen/TouchscreenTrigger.cpp new file mode 100644 index 0000000..bd2ed0e --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenTrigger.cpp @@ -0,0 +1,30 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TouchscreenTrigger.h" +#include + +namespace InputActions +{ + +TouchscreenTrigger::TouchscreenTrigger(TriggerType type, std::unique_ptr core) + : Trigger(type, std::move(core)) +{ +} + +} \ No newline at end of file diff --git a/src/libinputactions/triggers/touchscreen/TouchscreenTrigger.h b/src/libinputactions/triggers/touchscreen/TouchscreenTrigger.h new file mode 100644 index 0000000..a73db14 --- /dev/null +++ b/src/libinputactions/triggers/touchscreen/TouchscreenTrigger.h @@ -0,0 +1,32 @@ +/* + Input Actions - Input handler that executes user-defined actions + Copyright (C) 2024-2026 Marcin Woźniak + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include + +namespace InputActions +{ + +class TouchscreenTrigger : public Trigger +{ +protected: + TouchscreenTrigger(TriggerType type, std::unique_ptr core); +}; + +} \ No newline at end of file diff --git a/tests/libinputactions/CMakeLists.txt b/tests/libinputactions/CMakeLists.txt index 30d290a..91c4f73 100644 --- a/tests/libinputactions/CMakeLists.txt +++ b/tests/libinputactions/CMakeLists.txt @@ -41,15 +41,19 @@ libinputactions_add_test(TestConditionGroup SOURCES conditions/TestConditionGrou libinputactions_add_test(TestConditionGroupNodeParser SOURCES config/parsers/conditions/TestConditionGroupNodeParser.cpp) libinputactions_add_test(TestConditionNodeParser SOURCES config/parsers/conditions/TestConditionNodeParser.cpp) libinputactions_add_test(TestDeviceRuleNodeParser SOURCES config/parsers/TestDeviceRuleNodeParser.cpp) -libinputactions_add_test(TestDirectionalMotionTrigger SOURCES triggers/TestDirectionalMotionTrigger.cpp) +libinputactions_add_test(TestDirectionalMotionTriggerCore SOURCES triggers/core/TestDirectionalMotionTriggerCore.cpp) libinputactions_add_test(TestEnumNodeParser SOURCES config/parsers/TestEnumNodeParser.cpp) libinputactions_add_test(TestFlagsNodeParser SOURCES config/parsers/TestFlagsNodeParser.cpp) libinputactions_add_test(TestInputActionNodeParser SOURCES config/parsers/actions/TestInputActionNodeParser.cpp) libinputactions_add_test(TestInputTriggerHandler SOURCES handlers/TestInputTriggerHandler.cpp) libinputactions_add_test(TestKeyboardTriggerHandler SOURCES handlers/TestKeyboardTriggerHandler.cpp) -libinputactions_add_test(TestMotionTrigger SOURCES triggers/TestMotionTrigger.cpp) +libinputactions_add_test(TestKeyboardTriggerNodeParser SOURCES config/parsers/triggers/TestKeyboardTriggerNodeParser.cpp) +libinputactions_add_test(TestMotionTriggerCore SOURCES triggers/core/TestMotionTriggerCore.cpp) libinputactions_add_test(TestMotionTriggerHandler SOURCES handlers/TestMotionTriggerHandler.cpp) +libinputactions_add_test(TestMouseTrigger SOURCES triggers/TestMouseTrigger.cpp) +libinputactions_add_test(TestMouseTriggerNodeParser SOURCES config/parsers/triggers/TestMouseTriggerNodeParser.cpp) libinputactions_add_test(TestPlasmaShortcutActionNodeParser SOURCES config/parsers/actions/TestPlasmaShortcutActionNodeParser.cpp) +libinputactions_add_test(TestPointerTriggerNodeParser SOURCES config/parsers/triggers/TestPointerTriggerNodeParser.cpp) libinputactions_add_test(TestQPointFNodeParser SOURCES config/parsers/qt/TestQPointFNodeParser.cpp) libinputactions_add_test(TestQRegularExpressionNodeParser SOURCES config/parsers/qt/TestQRegularExpressionNodeParser.cpp) libinputactions_add_test(TestQStringNodeParser SOURCES config/parsers/qt/TestQStringNodeParser.cpp) @@ -58,14 +62,18 @@ libinputactions_add_test(TestRange SOURCES TestRange.cpp) libinputactions_add_test(TestRangeNodeParser SOURCES config/parsers/TestRangeNodeParser.cpp) libinputactions_add_test(TestSeparatedStringNodeParser SOURCES config/parsers/TestSeparatedStringNodeParser.cpp) libinputactions_add_test(TestSetNodeParser SOURCES config/parsers/containers/TestSetNodeParser.cpp) -libinputactions_add_test(TestSwipeTrigger SOURCES triggers/TestSwipeTrigger.cpp) +libinputactions_add_test(TestStrokeTriggerCoreNodeParser SOURCES config/parsers/triggers/TestStrokeTriggerCoreNodeParser.cpp) +libinputactions_add_test(TestSwipeTriggerCoreNodeParser SOURCES config/parsers/triggers/TestSwipeTriggerCoreNodeParser.cpp) +libinputactions_add_test(TestSwipeTriggerCore SOURCES triggers/core/TestSwipeTriggerCore.cpp) libinputactions_add_test(TestTouchpadTriggerHandler SOURCES handlers/TestTouchpadTriggerHandler.cpp) +libinputactions_add_test(TestTouchpadTriggerNodeParser SOURCES config/parsers/triggers/TestTouchpadTriggerNodeParser.cpp) +libinputactions_add_test(TestTouchscreenTriggerNodeParser SOURCES config/parsers/triggers/TestTouchscreenTriggerNodeParser.cpp) libinputactions_add_test(TestTrigger SOURCES triggers/TestTrigger.cpp) libinputactions_add_test(TestTriggerAction SOURCES actions/TestTriggerAction.cpp) libinputactions_add_test(TestTriggerActionNodeParser SOURCES config/parsers/TestTriggerActionNodeParser.cpp) libinputactions_add_test(TestTriggerGroupNodeParser SOURCES config/parsers/TestTriggerGroupNodeParser.cpp) libinputactions_add_test(TestTriggerHandler SOURCES handlers/TestTriggerHandler.cpp) -libinputactions_add_test(TestTriggerNodeParser SOURCES config/parsers/TestTriggerNodeParser.cpp) +libinputactions_add_test(TestTriggerNodeParser SOURCES config/parsers/triggers/TestTriggerNodeParser.cpp) libinputactions_add_test(TestValue SOURCES TestValue.cpp) libinputactions_add_test(TestVariableConditionNodeParser SOURCES config/parsers/conditions/TestVariableConditionNodeParser.cpp) libinputactions_add_test(TestVectorNodeParser SOURCES config/parsers/containers/TestVectorNodeParser.cpp) \ No newline at end of file diff --git a/tests/libinputactions/Test.h b/tests/libinputactions/Test.h index 6bdbc95..c2b5316 100644 --- a/tests/libinputactions/Test.h +++ b/tests/libinputactions/Test.h @@ -33,6 +33,11 @@ namespace InputActions #define INPUTACTIONS_VERIFY_ADDS_CONFIG_ISSUE(action, issueType, line, column) \ INPUTACTIONS_VERIFY_ADDS_CONFIG_ISSUE_SAVE(action, issueType, line, column, issue_) +#define INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(action) \ + g_configIssueManager = std::make_shared(); \ + action; \ + QCOMPARE(g_configIssueManager->issues().size(), 0); + class Test : public QObject { Q_OBJECT diff --git a/tests/libinputactions/actions/TestTriggerAction.cpp b/tests/libinputactions/actions/TestTriggerAction.cpp index 401f83a..aca82c1 100644 --- a/tests/libinputactions/actions/TestTriggerAction.cpp +++ b/tests/libinputactions/actions/TestTriggerAction.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include namespace InputActions { diff --git a/tests/libinputactions/config/parsers/TestTriggerGroupNodeParser.cpp b/tests/libinputactions/config/parsers/TestTriggerGroupNodeParser.cpp index 47bbe5d..f88db7c 100644 --- a/tests/libinputactions/config/parsers/TestTriggerGroupNodeParser.cpp +++ b/tests/libinputactions/config/parsers/TestTriggerGroupNodeParser.cpp @@ -4,7 +4,8 @@ #include #include #include -#include +#include +#include #include namespace InputActions @@ -31,7 +32,7 @@ private slots: gestures: - type: press )"); - const auto triggers = node->as>>(); + const auto triggers = parseTriggerList(node.get()); QCOMPARE(triggers.size(), 1); QCOMPARE(triggers[0]->id(), "test"); @@ -45,7 +46,7 @@ private slots: - type: press - type: press )"); - const auto triggers = node->as>>(); + const auto triggers = parseTriggerList(node.get()); QCOMPARE(triggers.size(), 2); QCOMPARE(triggers[0]->id(), "test"); @@ -60,7 +61,7 @@ private slots: - gestures: - type: press )"); - const auto triggers = node->as>>(); + const auto triggers = parseTriggerList(node.get()); QCOMPARE(triggers.size(), 1); QCOMPARE(triggers[0]->id(), "test"); @@ -74,7 +75,7 @@ private slots: gestures: - type: press )"); - const auto triggers = node->as>>(); + const auto triggers = parseTriggerList(node.get()); QCOMPARE(triggers.size(), 1); QCOMPARE(triggers[0]->id(), "test"); @@ -87,7 +88,7 @@ private slots: gestures: - type: press )"); - const auto triggers = node->as>>(); + const auto triggers = parseTriggerList(node.get()); QCOMPARE(triggers.size(), 1); QVERIFY(dynamic_pointer_cast(triggers[0]->activationCondition())); @@ -101,7 +102,7 @@ private slots: - type: press conditions: $b )"); - const auto triggers = node->as>>(); + const auto triggers = parseTriggerList(node.get()); QCOMPARE(triggers.size(), 1); @@ -132,7 +133,7 @@ private slots: - type: press conditions: $c )"); - const auto triggers = node->as>>(); + const auto triggers = parseTriggerList(node.get()); QCOMPARE(triggers.size(), 1); @@ -167,7 +168,7 @@ private slots: - $b - $c )"); - const auto triggers = node->as>>(); + const auto triggers = parseTriggerList(node.get()); QCOMPARE(triggers.size(), 1); @@ -203,7 +204,7 @@ private slots: - $b - $c )"); - const auto triggers = node->as>>(); + const auto triggers = parseTriggerList(node.get()); QCOMPARE(triggers.size(), 1); @@ -244,7 +245,7 @@ private slots: - type: press )"); - INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(node->as>>(), InvalidValueConfigException, 1, 23); + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(parseTriggerList(node.get()), InvalidValueConfigException, 1, 23); } void unusedProperty__addsConfigIssueAtCorrectPosition() @@ -255,7 +256,7 @@ private slots: - type: press )"); - node->as>>(); + parseTriggerList(node.get()); INPUTACTIONS_VERIFY_ADDS_CONFIG_ISSUE_SAVE(node->addUnusedMapPropertyIssues(), UnusedPropertyConfigIssue, 1, 14, issue); QCOMPARE(issue->property(), "_"); } diff --git a/tests/libinputactions/config/parsers/triggers/TestKeyboardTriggerNodeParser.cpp b/tests/libinputactions/config/parsers/triggers/TestKeyboardTriggerNodeParser.cpp new file mode 100644 index 0000000..dbe9a58 --- /dev/null +++ b/tests/libinputactions/config/parsers/triggers/TestKeyboardTriggerNodeParser.cpp @@ -0,0 +1,52 @@ +#include "Test.h" +#include +#include +#include +#include + +namespace InputActions +{ + +class TestKeyboardTriggerNodeParser : public Test +{ + Q_OBJECT + +private slots: + void shortcut__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: shortcut + shortcut: [ leftmeta, x ] + id: _ + )"); + + const auto trigger = node->as>(); + const auto *shortcutTrigger = dynamic_cast(trigger.get()); + + QVERIFY(shortcutTrigger); + QCOMPARE(shortcutTrigger->shortcut().keys.size(), 2); + QCOMPARE(shortcutTrigger->shortcut().keys.contains(KEY_LEFTMETA), true); + QCOMPARE(shortcutTrigger->shortcut().keys.contains(KEY_X), true); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void noType__throwsMissingRequiredPropertyConfigException() + { + const auto node = Node::create("_: _"); + + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION_SAVE(node->as>(), MissingRequiredPropertyConfigException, 0, 0, e); + QCOMPARE(e->property(), "type"); + } + + void invalidType__throwsInvalidValueConfigException() + { + const auto node = Node::create("type: _"); + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(node->as>(), InvalidValueConfigException, 0, 6); + } +}; + +} + +QTEST_MAIN(InputActions::TestKeyboardTriggerNodeParser) +#include "TestKeyboardTriggerNodeParser.moc" \ No newline at end of file diff --git a/tests/libinputactions/config/parsers/triggers/TestMouseTriggerNodeParser.cpp b/tests/libinputactions/config/parsers/triggers/TestMouseTriggerNodeParser.cpp new file mode 100644 index 0000000..d95a22d --- /dev/null +++ b/tests/libinputactions/config/parsers/triggers/TestMouseTriggerNodeParser.cpp @@ -0,0 +1,163 @@ +#include "Test.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace InputActions +{ + +class TestMouseTriggerNodeParser : public Test +{ + Q_OBJECT + +private slots: + void circle__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: circle + direction: any + mouse_buttons: [ left ] + mouse_buttons_exact_order: true + lock_pointer: true + speed: fast + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void press__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: press + instant: true + mouse_buttons: [ left ] + mouse_buttons_exact_order: true + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void stroke__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: stroke + strokes: [ 'MgAAMjJkZAA=' ] + mouse_buttons: [ left ] + mouse_buttons_exact_order: true + speed: fast + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void swipe__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: swipe + direction: any + mouse_buttons: [ left ] + mouse_buttons_exact_order: true + lock_pointer: true + speed: fast + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void wheel__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: wheel + direction: any + mouse_buttons: [ left ] + mouse_buttons_exact_order: true + lock_pointer: true + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void noType__throwsMissingRequiredPropertyConfigException() + { + const auto node = Node::create("_: _"); + + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION_SAVE(node->as>(), MissingRequiredPropertyConfigException, 0, 0, e); + QCOMPARE(e->property(), "type"); + } + + void invalidType__throwsInvalidValueConfigException() + { + const auto node = Node::create("type: _"); + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(node->as>(), InvalidValueConfigException, 0, 6); + } + + void mouseButtons_duplicateItem__throwsDuplicateSetItemConfigException() + { + const auto node = Node::create(R"( + type: press + mouse_buttons: [ left, left ] + )"); + + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION_SAVE(node->as>(), DuplicateSetItemConfigException, 2, 35, e); + QCOMPARE(e->index(), 1); + } + + void mouseButtons__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: press + mouse_buttons: [ left, right ] + )"); + + const auto trigger = node->as>(); + QCOMPARE(trigger->mouseButtons().size(), 2); + QCOMPARE(trigger->mouseButtons()[0], BTN_LEFT); + QCOMPARE(trigger->mouseButtons()[1], BTN_RIGHT); + QCOMPARE(trigger->mouseButtonsExactOrder(), false); + } + + void mouseButtons_exactOrder__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: press + mouse_buttons: [ left, right ] + mouse_buttons_exact_order: true + )"); + + const auto trigger = node->as>(); + QCOMPARE(trigger->mouseButtons().size(), 2); + QCOMPARE(trigger->mouseButtons()[0], BTN_LEFT); + QCOMPARE(trigger->mouseButtons()[1], BTN_RIGHT); + QCOMPARE(trigger->mouseButtonsExactOrder(), true); + } +}; + +} + +QTEST_MAIN(InputActions::TestMouseTriggerNodeParser) +#include "TestMouseTriggerNodeParser.moc" \ No newline at end of file diff --git a/tests/libinputactions/config/parsers/triggers/TestPointerTriggerNodeParser.cpp b/tests/libinputactions/config/parsers/triggers/TestPointerTriggerNodeParser.cpp new file mode 100644 index 0000000..9f9312d --- /dev/null +++ b/tests/libinputactions/config/parsers/triggers/TestPointerTriggerNodeParser.cpp @@ -0,0 +1,46 @@ +#include "Test.h" +#include +#include +#include +#include + +namespace InputActions +{ + +class TestPointerTriggerNodeParser : public Test +{ + Q_OBJECT + +private slots: + void hover__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: hover + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void noType__throwsMissingRequiredPropertyConfigException() + { + const auto node = Node::create("_: _"); + + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION_SAVE(node->as>(), MissingRequiredPropertyConfigException, 0, 0, e); + QCOMPARE(e->property(), "type"); + } + + void invalidType__throwsInvalidValueConfigException() + { + const auto node = Node::create("type: _"); + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(node->as>(), InvalidValueConfigException, 0, 6); + } +}; + +} + +QTEST_MAIN(InputActions::TestPointerTriggerNodeParser) +#include "TestPointerTriggerNodeParser.moc" \ No newline at end of file diff --git a/tests/libinputactions/config/parsers/triggers/TestStrokeTriggerCoreNodeParser.cpp b/tests/libinputactions/config/parsers/triggers/TestStrokeTriggerCoreNodeParser.cpp new file mode 100644 index 0000000..1d1bf6c --- /dev/null +++ b/tests/libinputactions/config/parsers/triggers/TestStrokeTriggerCoreNodeParser.cpp @@ -0,0 +1,25 @@ +#include "Test.h" +#include +#include +#include + +namespace InputActions +{ + +class TestStrokeTriggerCoreNodeParser : public Test +{ + Q_OBJECT + +private slots: + void invalidStroke_throwsInvalidValueConfigException() + { + const auto node = Node::create("strokes: [ 'MgAAMjJkZA=' ]"); + + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(node->as>(), InvalidValueConfigException, 0, 11); + } +}; + +} + +QTEST_MAIN(InputActions::TestStrokeTriggerCoreNodeParser) +#include "TestStrokeTriggerCoreNodeParser.moc" \ No newline at end of file diff --git a/tests/libinputactions/config/parsers/triggers/TestSwipeTriggerCoreNodeParser.cpp b/tests/libinputactions/config/parsers/triggers/TestSwipeTriggerCoreNodeParser.cpp new file mode 100644 index 0000000..30579d6 --- /dev/null +++ b/tests/libinputactions/config/parsers/triggers/TestSwipeTriggerCoreNodeParser.cpp @@ -0,0 +1,55 @@ +#include "Test.h" +#include +#include +#include + +namespace InputActions +{ + +class TestSwipeTriggerCoreNodeParser : public Test +{ + Q_OBJECT + +private slots: + void angle__parsesNodeCorrectly() + { + const auto node = Node::create("angle: 30-60"); + + const auto core = node->as>(); + QCOMPARE(core->minAngle(), 30); + QCOMPARE(core->maxAngle(), 60); + QCOMPARE(core->bidirectional(), false); + } + + void angle_bidirectional__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + angle: 30-60 + bidirectional: true + )"); + + const auto core = node->as>(); + QCOMPARE(core->minAngle(), 30); + QCOMPARE(core->maxAngle(), 60); + QCOMPARE(core->bidirectional(), true); + } + + void direction__doesNotThrow() + { + const auto node = Node::create("direction: right"); + + QVERIFY_THROWS_NO_EXCEPTION(node->as>()); + } + + void invalidAngle__throwsInvalidValueConfigException() + { + const auto node = Node::create("angle: 1-361"); + + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(node->as>(), InvalidValueConfigException, 0, 7); + } +}; + +} + +QTEST_MAIN(InputActions::TestSwipeTriggerCoreNodeParser) +#include "TestSwipeTriggerCoreNodeParser.moc" \ No newline at end of file diff --git a/tests/libinputactions/config/parsers/triggers/TestTouchpadTriggerNodeParser.cpp b/tests/libinputactions/config/parsers/triggers/TestTouchpadTriggerNodeParser.cpp new file mode 100644 index 0000000..225a9f9 --- /dev/null +++ b/tests/libinputactions/config/parsers/triggers/TestTouchpadTriggerNodeParser.cpp @@ -0,0 +1,162 @@ +#include "Test.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace InputActions +{ + +class TestTouchpadTriggerNodeParser : public Test +{ + Q_OBJECT + +private slots: + void click__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: click + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void circle__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: circle + direction: any + speed: fast + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void hold__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: hold + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void hold_typePress__parsesNodeCorrectly() + { + const auto node = Node::create("type: press"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + } + + void pinch__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: pinch + direction: any + speed: fast + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void rotate__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: rotate + direction: any + speed: fast + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void stroke__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: stroke + strokes: [ 'MgAAMjJkZAA=' ] + speed: fast + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void swipe__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: swipe + direction: any + speed: fast + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void tap__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: tap + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void noType__throwsMissingRequiredPropertyConfigException() + { + const auto node = Node::create("_: _"); + + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION_SAVE(node->as>(), MissingRequiredPropertyConfigException, 0, 0, e); + QCOMPARE(e->property(), "type"); + } + + void invalidType__throwsInvalidValueConfigException() + { + const auto node = Node::create("type: _"); + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(node->as>(), InvalidValueConfigException, 0, 6); + } +}; + +} + +QTEST_MAIN(InputActions::TestTouchpadTriggerNodeParser) +#include "TestTouchpadTriggerNodeParser.moc" \ No newline at end of file diff --git a/tests/libinputactions/config/parsers/triggers/TestTouchscreenTriggerNodeParser.cpp b/tests/libinputactions/config/parsers/triggers/TestTouchscreenTriggerNodeParser.cpp new file mode 100644 index 0000000..0032993 --- /dev/null +++ b/tests/libinputactions/config/parsers/triggers/TestTouchscreenTriggerNodeParser.cpp @@ -0,0 +1,148 @@ +#include "Test.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace InputActions +{ + +class TestTouchscreenTriggerNodeParser : public Test +{ + Q_OBJECT + +private slots: + void circle__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: circle + direction: any + speed: fast + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void hold__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: hold + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void hold_typePress__parsesNodeCorrectly() + { + const auto node = Node::create("type: press"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + } + + void pinch__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: pinch + direction: any + speed: fast + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void rotate__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: rotate + direction: any + speed: fast + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void stroke__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: stroke + strokes: [ 'MgAAMjJkZAA=' ] + speed: fast + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void swipe__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: swipe + direction: any + speed: fast + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void tap__parsesNodeCorrectly() + { + const auto node = Node::create(R"( + type: tap + id: _ + )"); + + const auto trigger = node->as>(); + QVERIFY(dynamic_cast(trigger.get())); + + INPUTACTIONS_VERIFY_ADDS_NO_CONFIG_ISSUE(node->addUnusedMapPropertyIssues()); + } + + void noType__throwsMissingRequiredPropertyConfigException() + { + const auto node = Node::create("_: _"); + + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION_SAVE(node->as>(), MissingRequiredPropertyConfigException, 0, 0, e); + QCOMPARE(e->property(), "type"); + } + + void invalidType__throwsInvalidValueConfigException() + { + const auto node = Node::create("type: _"); + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(node->as>(), InvalidValueConfigException, 0, 6); + } +}; + +} + +QTEST_MAIN(InputActions::TestTouchscreenTriggerNodeParser) +#include "TestTouchscreenTriggerNodeParser.moc" \ No newline at end of file diff --git a/tests/libinputactions/config/parsers/TestTriggerNodeParser.cpp b/tests/libinputactions/config/parsers/triggers/TestTriggerNodeParser.cpp similarity index 52% rename from tests/libinputactions/config/parsers/TestTriggerNodeParser.cpp rename to tests/libinputactions/config/parsers/triggers/TestTriggerNodeParser.cpp index 90242ed..1de4085 100644 --- a/tests/libinputactions/config/parsers/TestTriggerNodeParser.cpp +++ b/tests/libinputactions/config/parsers/triggers/TestTriggerNodeParser.cpp @@ -4,8 +4,11 @@ #include #include #include -#include -#include +#include +#include +#include +#include +#include namespace InputActions { @@ -15,104 +18,48 @@ class TestTriggerNodeParser : public Test Q_OBJECT private slots: - void stroke_withConflictingBeginAction__throwsInvalidValueContextConfigException() + void finalizeTrigger_stroke_withConflictingBeginAction__throwsInvalidValueContextConfigException() { + const auto trigger = std::make_unique(std::make_unique(std::vector{})); const auto node = Node::create(R"( - type: stroke - strokes: [ 'MgAAMjJkZAA=' ] - actions: - on: begin command: _ )"); - INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(node->as>(), InvalidValueContextConfigException, 5, 16); + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(finalizeTrigger(node.get(), trigger.get()), InvalidValueContextConfigException, 2, 16); } - void stroke_withNonConflictingBeginAction__doesNotThrow() + void finalizeTrigger_stroke_withNonConflictingBeginAction__doesNotThrow() { + const auto trigger = std::make_unique(std::make_unique(std::vector{})); const auto node = Node::create(R"( - type: stroke - strokes: [ 'MgAAMjJkZAA=' ] - actions: - on: begin conflicting: false command: _ )"); - QVERIFY_THROWS_NO_EXCEPTION(node->as>()); - } - - void stroke_withEndAction__doesNotThrow() - { - const auto node = Node::create(R"( - type: stroke - strokes: [ 'MgAAMjJkZAA=' ] - - actions: - - on: end - command: _ - )"); - - QVERIFY_THROWS_NO_EXCEPTION(node->as>()); + QVERIFY_THROWS_NO_EXCEPTION(finalizeTrigger(node.get(), trigger.get())); } - void stroke_invalidStroke__throwsInvalidValueConfigException() + void finalizeTrigger_stroke_withEndAction__doesNotThrow() { + const auto trigger = std::make_unique(std::make_unique(std::vector{})); const auto node = Node::create(R"( - type: stroke - strokes: [ 'MgAAMjJkZA=' ] - actions: - on: end command: _ )"); - INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(node->as>(), InvalidValueConfigException, 2, 23); + QVERIFY_THROWS_NO_EXCEPTION(finalizeTrigger(node.get(), trigger.get())); } - void swipe_angle__parsesNodeCorrectly() + void finalizeTrigger_fingers__parsesNodeCorrectly() { - const auto node = Node::create(R"( - type: swipe - angle: 30-60 - )"); - const auto trigger = node->as>(); - - const auto *swipeTrigger = dynamic_cast(trigger.get()); - QVERIFY(swipeTrigger); - QCOMPARE(swipeTrigger->minAngle(), 30); - QCOMPARE(swipeTrigger->maxAngle(), 60); - } - - void swipe_direction__doesNotThrow() - { - const auto node = Node::create(R"( - type: swipe - direction: right - )"); - - QVERIFY_THROWS_NO_EXCEPTION(node->as>()); - } - - void swipe_invalidAngle__throwsInvalidValueConfigException() - { - const auto node = Node::create(R"( - type: swipe - angle: 1-361 - )"); - - INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(node->as>(), InvalidValueConfigException, 2, 19); - } - - void fingers__parsesNodeCorrectly() - { - const auto node = Node::create(R"( - type: press - fingers: 2 - )"); - const auto trigger = node->as>(); + const auto trigger = std::make_unique(); + const auto node = Node::create("fingers: 2"); + finalizeTrigger(node.get(), trigger.get()); const auto condition = std::dynamic_pointer_cast(trigger->activationCondition()); QVERIFY(condition); @@ -127,11 +74,9 @@ private slots: void fingers_range__parsesNodeCorrectly() { - const auto node = Node::create(R"( - type: press - fingers: 2-3 - )"); - const auto trigger = node->as>(); + const auto trigger = std::make_unique(); + const auto node = Node::create("fingers: 2-3"); + finalizeTrigger(node.get(), trigger.get()); const auto condition = std::dynamic_pointer_cast(trigger->activationCondition()); QVERIFY(condition); @@ -145,46 +90,29 @@ private slots: QCOMPARE(std::any_cast(values[1].get().value()), 3); } - void mouseButtons_duplicateItem__throwsDuplicateSetItemConfigException() - { - const auto node = Node::create(R"( - type: press - mouse_buttons: [ left, left ] - )"); - - INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION_SAVE(node->as>(), DuplicateSetItemConfigException, 2, 35, e); - QCOMPARE(e->index(), 1); - } - void keyboardModifiers__addsDeprecatedFeatureConfigIssue() { - const auto node = Node::create(R"( - type: press - keyboard_modifiers: none - )"); + const auto trigger = std::make_unique(); + const auto node = Node::create("keyboard_modifiers: none"); - INPUTACTIONS_VERIFY_ADDS_CONFIG_ISSUE_SAVE(node->as>(), DeprecatedFeatureConfigIssue, 2, 32, e); + INPUTACTIONS_VERIFY_ADDS_CONFIG_ISSUE_SAVE(finalizeTrigger(node.get(), trigger.get()), DeprecatedFeatureConfigIssue, 0, 20, e); QCOMPARE(e->feature(), DeprecatedFeature::TriggerKeyboardModifiers); } void keyboardModifiers_any__doesNotAddCondition() { - const auto node = Node::create(R"( - type: press - keyboard_modifiers: any - )"); - const auto trigger = node->as>(); + const auto trigger = std::make_unique(); + const auto node = Node::create("keyboard_modifiers: any"); + finalizeTrigger(node.get(), trigger.get()); QVERIFY(!trigger->activationCondition()); } void keyboardModifiers_metaAlt__parsesNodeCorrectly() { - const auto node = Node::create(R"( - type: press - keyboard_modifiers: [ meta, alt ] - )"); - const auto trigger = node->as>(); + const auto trigger = std::make_unique(); + const auto node = Node::create("keyboard_modifiers: [ meta, alt ]"); + finalizeTrigger(node.get(), trigger.get()); const auto condition = std::dynamic_pointer_cast(trigger->activationCondition()); QVERIFY(condition); @@ -199,11 +127,9 @@ private slots: void keyboardModifiers_none__parsesNodeCorrectly() { - const auto node = Node::create(R"( - type: press - keyboard_modifiers: none - )"); - const auto trigger = node->as>(); + const auto trigger = std::make_unique(); + const auto node = Node::create("keyboard_modifiers: none"); + finalizeTrigger(node.get(), trigger.get()); const auto condition = std::dynamic_pointer_cast(trigger->activationCondition()); QVERIFY(condition); @@ -218,23 +144,21 @@ private slots: void keyboardModifiers_invalid__throwsInvalidValueConfigException() { - const auto node = Node::create(R"( - type: press - keyboard_modifiers: e - )"); + const auto trigger = std::make_unique(); + const auto node = Node::create("keyboard_modifiers: e"); - INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(node->as>(), InvalidValueConfigException, 2, 32); + INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(finalizeTrigger(node.get(), trigger.get()), InvalidValueConfigException, 0, 20); } void fingers_keyboardModifiers_triggerCondition__mergedIntoAllGroup() { + const auto trigger = std::make_unique(); const auto node = Node::create(R"( - type: press fingers: 2-3 conditions: $window_maximized keyboard_modifiers: none )"); - const auto trigger = node->as>(); + finalizeTrigger(node.get(), trigger.get()); const auto condition = std::dynamic_pointer_cast(trigger->activationCondition()); QVERIFY(condition); @@ -257,20 +181,6 @@ private slots: QCOMPARE(windowMaximizedCondition->negate(), false); QCOMPARE(windowMaximizedCondition->variableName(), "window_maximized"); } - - void invalid_noType__throwsMissingRequiredPropertyConfigException() - { - const auto node = Node::create("_: _"); - - INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION_SAVE(node->as>(), MissingRequiredPropertyConfigException, 0, 0, e); - QCOMPARE(e->property(), "type"); - } - - void invalid_invalidType__throwsInvalidValueConfigException() - { - const auto node = Node::create("type: _"); - INPUTACTIONS_VERIFY_THROWS_CONFIG_EXCEPTION(node->as>(), InvalidValueConfigException, 0, 6); - } }; } diff --git a/tests/libinputactions/handlers/TestInputTriggerHandler.cpp b/tests/libinputactions/handlers/TestInputTriggerHandler.cpp index b36d093..9feee73 100644 --- a/tests/libinputactions/handlers/TestInputTriggerHandler.cpp +++ b/tests/libinputactions/handlers/TestInputTriggerHandler.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include namespace InputActions @@ -29,7 +30,7 @@ private slots: void keyboardKey__modifierReleased_pressedBeforeTriggerActivation__triggersEnded() { QSignalSpy spy(m_handler.get(), &TriggerHandler::endingTriggers); - m_handler->addTrigger(std::make_unique(TriggerType::Press)); + m_handler->addTrigger(std::make_unique()); g_inputBackend->handleEvent(KeyboardKeyEvent(m_keyboard.get(), KEY_LEFTCTRL, true)); m_handler->handleEvent(KeyboardKeyEvent(m_keyboard.get(), KEY_LEFTCTRL, true)); @@ -45,7 +46,7 @@ private slots: void keyboardKey__modifierReleased_pressedAfterTriggerActivation__triggersNotEnded() { QSignalSpy spy(m_handler.get(), &TriggerHandler::endingTriggers); - m_handler->addTrigger(std::make_unique(TriggerType::Press)); + m_handler->addTrigger(std::make_unique()); m_handler->activateTriggers(TriggerType::Press); diff --git a/tests/libinputactions/handlers/TestKeyboardTriggerHandler.cpp b/tests/libinputactions/handlers/TestKeyboardTriggerHandler.cpp index 84d84f6..c11eb14 100644 --- a/tests/libinputactions/handlers/TestKeyboardTriggerHandler.cpp +++ b/tests/libinputactions/handlers/TestKeyboardTriggerHandler.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include namespace InputActions diff --git a/tests/libinputactions/handlers/TestMotionTriggerHandler.cpp b/tests/libinputactions/handlers/TestMotionTriggerHandler.cpp index 5f43aaa..ea81cb5 100644 --- a/tests/libinputactions/handlers/TestMotionTriggerHandler.cpp +++ b/tests/libinputactions/handlers/TestMotionTriggerHandler.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include using namespace ::testing; diff --git a/tests/libinputactions/handlers/TestTouchpadTriggerHandler.cpp b/tests/libinputactions/handlers/TestTouchpadTriggerHandler.cpp index 54f9009..bf29067 100644 --- a/tests/libinputactions/handlers/TestTouchpadTriggerHandler.cpp +++ b/tests/libinputactions/handlers/TestTouchpadTriggerHandler.cpp @@ -9,6 +9,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include @@ -45,7 +50,7 @@ private slots: void click_withoutLibinputButton() { - m_handler->addTrigger(std::make_unique(TriggerType::Click)); + m_handler->addTrigger(std::make_unique()); g_inputBackend->handleEvent(TouchpadClickEvent(m_touchpad.get(), true)); QCOMPARE(m_activatingTriggersSpy->count(), 1); @@ -71,7 +76,7 @@ private slots: { QFETCH(int, button); - m_handler->addTrigger(std::make_unique(TriggerType::Click)); + m_handler->addTrigger(std::make_unique()); g_inputBackend->handleEvent(TouchpadClickEvent(m_touchpad.get(), true)); QCOMPARE(g_inputBackend->handleEvent(PointerButtonEvent(m_touchpad.get(), button, true)), true); @@ -88,7 +93,7 @@ private slots: void press1_notDelayedOrBlocked() { - m_handler->addTrigger(std::make_unique(TriggerType::Press)); + m_handler->addTrigger(std::make_unique()); QCOMPARE(g_inputBackend->handleEvent(TouchpadGestureLifecyclePhaseEvent(m_touchpad.get(), TouchpadGestureLifecyclePhase::Begin, TriggerType::Press, 1)), false); @@ -104,8 +109,8 @@ private slots: void press1_hasClickTrigger_delayed() { - m_handler->addTrigger(std::make_unique(TriggerType::Press)); - m_handler->addTrigger(std::make_unique(TriggerType::Click)); + m_handler->addTrigger(std::make_unique()); + m_handler->addTrigger(std::make_unique()); g_inputBackend->handleEvent(TouchpadGestureLifecyclePhaseEvent(m_touchpad.get(), TouchpadGestureLifecyclePhase::Begin, TriggerType::Press)); QCOMPARE(m_activatingTriggersSpy->count(), 0); @@ -120,8 +125,8 @@ private slots: void press1_hasTapTrigger_delayed() { - m_handler->addTrigger(std::make_unique(TriggerType::Press)); - m_handler->addTrigger(std::make_unique(TriggerType::Tap)); + m_handler->addTrigger(std::make_unique()); + m_handler->addTrigger(std::make_unique()); g_inputBackend->handleEvent(TouchpadGestureLifecyclePhaseEvent(m_touchpad.get(), TouchpadGestureLifecyclePhase::Begin, TriggerType::Press)); QCOMPARE(m_activatingTriggersSpy->count(), 0); @@ -136,8 +141,8 @@ private slots: void press1_clickedDuringPress_pressCancelledAndClickActivated() { - m_handler->addTrigger(std::make_unique(TriggerType::Press)); - m_handler->addTrigger(std::make_unique(TriggerType::Click)); + m_handler->addTrigger(std::make_unique()); + m_handler->addTrigger(std::make_unique()); g_inputBackend->handleEvent(TouchpadGestureLifecyclePhaseEvent(m_touchpad.get(), TouchpadGestureLifecyclePhase::Begin, TriggerType::Press)); QTest::qWait(500); @@ -160,7 +165,7 @@ private slots: void press2_notDelayedOrBlocked() { - m_handler->addTrigger(std::make_unique(TriggerType::Press)); + m_handler->addTrigger(std::make_unique()); QCOMPARE(g_inputBackend->handleEvent(TouchpadGestureLifecyclePhaseEvent(m_touchpad.get(), TouchpadGestureLifecyclePhase::Begin, TriggerType::Press, 2)), false); @@ -176,7 +181,7 @@ private slots: void press3_blocked() { - m_handler->addTrigger(std::make_unique(TriggerType::Press)); + m_handler->addTrigger(std::make_unique()); QCOMPARE(g_inputBackend->handleEvent(TouchpadGestureLifecyclePhaseEvent(m_touchpad.get(), TouchpadGestureLifecyclePhase::Begin, TriggerType::Press, 3)), true); @@ -188,7 +193,7 @@ private slots: void swipe1() { - auto trigger = std::make_unique(TriggerType::Swipe); + auto trigger = std::make_unique(std::make_unique(SwipeDirection::Any)); trigger->setActivationCondition(std::make_shared("fingers", InputActions::Value(1), ComparisonOperator::EqualTo)); m_handler->addTrigger(std::move(trigger)); @@ -206,7 +211,7 @@ private slots: void swipe2() { - auto trigger = std::make_unique(TriggerType::Swipe); + auto trigger = std::make_unique(std::make_unique(SwipeDirection::Any)); trigger->setActivationCondition(std::make_shared("fingers", InputActions::Value(2), ComparisonOperator::EqualTo)); m_handler->addTrigger(std::move(trigger)); @@ -226,7 +231,7 @@ private slots: void tap1() { - m_handler->addTrigger(std::make_unique(TriggerType::Tap)); + m_handler->addTrigger(std::make_unique()); addPoint(); removePoints(); @@ -250,7 +255,7 @@ private slots: void tap1_noPointerButtonEvent_stateReset() { - m_handler->addTrigger(std::make_unique(TriggerType::Tap)); + m_handler->addTrigger(std::make_unique()); addPoint(); removePoints(); @@ -262,7 +267,7 @@ private slots: void tap1_tappedAgainBeforeLibinputButtonReleased() { - m_handler->addTrigger(std::make_unique(TriggerType::Tap)); + m_handler->addTrigger(std::make_unique()); addPoint(); removePoints(); @@ -291,7 +296,7 @@ private slots: void tap2_variablesSetDuringActivation() { - m_handler->addTrigger(std::make_unique(TriggerType::Tap)); + m_handler->addTrigger(std::make_unique()); const QPointF first(10, 10); const QPointF second(20, 20); @@ -321,7 +326,7 @@ private slots: void tap4() { - m_handler->addTrigger(std::make_unique(TriggerType::Tap)); + m_handler->addTrigger(std::make_unique()); addPoints(4); removePoints(); @@ -336,7 +341,7 @@ private slots: void tap4_moved() { - m_handler->addTrigger(std::make_unique(TriggerType::Tap)); + m_handler->addTrigger(std::make_unique()); addPoints(4); movePoints({10, 10}); @@ -349,7 +354,7 @@ private slots: void tap4_slow() { - m_handler->addTrigger(std::make_unique(TriggerType::Tap)); + m_handler->addTrigger(std::make_unique()); addPoints(4); QTest::qWait(500); @@ -362,8 +367,8 @@ private slots: void tap4_clicked() { - m_handler->addTrigger(std::make_unique(TriggerType::Click)); - m_handler->addTrigger(std::make_unique(TriggerType::Tap)); + m_handler->addTrigger(std::make_unique()); + m_handler->addTrigger(std::make_unique()); addPoints(4); g_inputBackend->handleEvent(TouchpadClickEvent(m_touchpad.get(), true)); @@ -405,7 +410,7 @@ private slots: QFETCH(bool, lmrTapButtonMap); QFETCH(bool, activated); - auto trigger = std::make_unique(TriggerType::Tap); + auto trigger = std::make_unique(); trigger->setActivationCondition(std::make_shared("fingers", InputActions::Value(triggerFingers), ComparisonOperator::EqualTo)); diff --git a/tests/libinputactions/handlers/TestTriggerHandler.cpp b/tests/libinputactions/handlers/TestTriggerHandler.cpp index a9386fc..440d0b0 100644 --- a/tests/libinputactions/handlers/TestTriggerHandler.cpp +++ b/tests/libinputactions/handlers/TestTriggerHandler.cpp @@ -1,9 +1,9 @@ #include "Test.h" -#include "mocks/MockTrigger.h" #include +#include #include - -using namespace ::testing; +#include +#include namespace InputActions { @@ -21,11 +21,11 @@ private slots: QTest::addColumn>("triggers"); QTest::addColumn("size"); - QTest::newRow("not activatable") << TriggerType::Press << std::vector({makeTrigger(TriggerType::Press, false)}) << 0; - QTest::newRow("activatable") << TriggerType::Press << std::vector({makeTrigger(TriggerType::Press, true)}) << 1; - QTest::newRow("activatable, wrong type") << TriggerType::Swipe << std::vector({makeTrigger(TriggerType::Press, true)}) << 0; + QTest::newRow("not activatable") << TriggerType::Click << std::vector({makeTrigger(false)}) << 0; + QTest::newRow("activatable") << TriggerType::Click << std::vector({makeTrigger(true)}) << 1; + QTest::newRow("activatable, wrong type") << TriggerType::Press << std::vector({makeTrigger(true)}) << 0; QTest::newRow("activatable, all") << TriggerType::All - << std::vector({makeTrigger(TriggerType::Press, true), makeTrigger(TriggerType::Swipe, true)}) << 2; + << std::vector({makeTrigger(true), makeTrigger(true)}) << 2; } void triggers() @@ -48,10 +48,10 @@ private slots: { QSignalSpy spy(m_handler.get(), &TriggerHandler::cancellingTriggers); - m_handler->addTrigger(std::make_unique(TriggerType::Press)); - m_handler->activateTriggers(TriggerType::Swipe); + m_handler->addTrigger(std::make_unique()); + m_handler->activateTriggers(TriggerType::Press); QCOMPARE(spy.count(), 0); - m_handler->activateTriggers(TriggerType::Swipe | TriggerType::Press); + m_handler->activateTriggers(TriggerType::Press | TriggerType::Click); QCOMPARE(spy.count(), 0); m_handler->activateTriggers(TriggerType::All); QCOMPARE(spy.count(), 1); @@ -62,10 +62,13 @@ private slots: } private: - MockTrigger *makeTrigger(TriggerType type, bool activatable) + template + T *makeTrigger(bool activatable) { - auto *trigger = new MockTrigger(type); - ON_CALL(*trigger, canActivate(_)).WillByDefault(Return(activatable)); + auto *trigger = new T(); + trigger->setActivationCondition(std::make_unique([activatable](const auto &arguments) { + return activatable; + })); return trigger; } diff --git a/tests/libinputactions/mocks/MockMouseTrigger.h b/tests/libinputactions/mocks/MockMouseTrigger.h new file mode 100644 index 0000000..19f685e --- /dev/null +++ b/tests/libinputactions/mocks/MockMouseTrigger.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include +#include + +namespace InputActions +{ + +class MockMouseTrigger : public MouseTrigger +{ +public: + MockMouseTrigger() + : MouseTrigger(TriggerType::None, std::make_unique()) + { + } +}; + +} \ No newline at end of file diff --git a/tests/libinputactions/mocks/MockSwipeTrigger.h b/tests/libinputactions/mocks/MockSwipeTrigger.h deleted file mode 100644 index 98fc418..0000000 --- a/tests/libinputactions/mocks/MockSwipeTrigger.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include - -namespace InputActions -{ - -class MockSwipeTrigger : public SwipeTrigger -{ -public: - MockSwipeTrigger(qreal angleMin, qreal angleMax) - : SwipeTrigger(angleMin, angleMax) - { - ON_CALL(*this, doUpdateActions).WillByDefault([this](const auto &event) { - this->SwipeTrigger::doUpdateActions(event); - }); - } - - MOCK_METHOD(void, doUpdateActions, (const TriggerUpdateEvent &event), (override)); -}; - -} \ No newline at end of file diff --git a/tests/libinputactions/mocks/MockSwipeTriggerCore.h b/tests/libinputactions/mocks/MockSwipeTriggerCore.h new file mode 100644 index 0000000..b8d6d81 --- /dev/null +++ b/tests/libinputactions/mocks/MockSwipeTriggerCore.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +namespace InputActions +{ + +class MockSwipeTriggerCore : public SwipeTriggerCore +{ +public: + MockSwipeTriggerCore(qreal angleMin, qreal angleMax) + : SwipeTriggerCore(angleMin, angleMax) + { + ON_CALL(*this, doUpdateActions).WillByDefault([this](const auto &actions, const auto &event) { + this->SwipeTriggerCore::doUpdateActions(actions, event); + }); + } + + MOCK_METHOD(void, doUpdateActions, (const std::vector> &actions, const TriggerUpdateEvent &event), (const, override)); +}; + +} \ No newline at end of file diff --git a/tests/libinputactions/mocks/MockTrigger.h b/tests/libinputactions/mocks/MockTrigger.h index 6b81981..87ae99e 100644 --- a/tests/libinputactions/mocks/MockTrigger.h +++ b/tests/libinputactions/mocks/MockTrigger.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include namespace InputActions { @@ -9,12 +9,10 @@ namespace InputActions class MockTrigger : public Trigger { public: - MockTrigger(TriggerType type = TriggerType::None) - : Trigger(type) + MockTrigger() + : Trigger(TriggerType::None, std::make_unique()) { } - - MOCK_METHOD(bool, canActivate, (const TriggerActivationEvent &event), (const, override)); }; } \ No newline at end of file diff --git a/tests/libinputactions/triggers/TestMouseTrigger.cpp b/tests/libinputactions/triggers/TestMouseTrigger.cpp new file mode 100644 index 0000000..fcee0cd --- /dev/null +++ b/tests/libinputactions/triggers/TestMouseTrigger.cpp @@ -0,0 +1,73 @@ +#include "Test.h" +#include "mocks/MockMouseTrigger.h" + +namespace InputActions +{ + +class TestMouseTrigger : public Test +{ + Q_OBJECT + +private slots: + void canActivate_mouseButtons_data() + { + QTest::addColumn>>("triggerButtons"); + QTest::addColumn>>("eventButtons"); + QTest::addColumn("orderMatters"); + QTest::addColumn("result"); + + const auto unset = std::optional>(); + const auto none = std::optional>(std::vector()); + const auto left = std::optional>{{BTN_LEFT}}; + const auto right = std::optional>{{BTN_RIGHT}}; + const auto leftRight = std::optional>{{BTN_LEFT, BTN_RIGHT}}; + const auto rightLeft = std::optional>{{BTN_RIGHT, BTN_LEFT}}; + + QTest::newRow("1") << left << unset << false << true; + QTest::newRow("3") << left << left << false << true; + QTest::newRow("4") << right << left << false << false; + QTest::newRow("5") << left << right << false << false; + QTest::newRow("6") << leftRight << left << false << false; + QTest::newRow("7") << left << leftRight << false << false; + + QTest::newRow("8") << left << unset << true << true; + QTest::newRow("9") << left << left << true << true; + QTest::newRow("10") << right << left << true << false; + QTest::newRow("11") << left << right << true << false; + QTest::newRow("12") << leftRight << left << true << false; + QTest::newRow("13") << left << leftRight << true << false; + + QTest::newRow("14") << leftRight << leftRight << false << true; + QTest::newRow("15") << leftRight << rightLeft << false << true; + QTest::newRow("16") << rightLeft << leftRight << false << true; + + QTest::newRow("17") << leftRight << rightLeft << true << false; + QTest::newRow("18") << rightLeft << leftRight << true << false; + + QTest::newRow("19") << none << unset << false << true; + QTest::newRow("20") << none << left << false << true; + QTest::newRow("21") << none << unset << true << true; + QTest::newRow("22") << none << left << true << true; + } + + void canActivate_mouseButtons() + { + QFETCH(std::optional>, triggerButtons); + QFETCH(std::optional>, eventButtons); + QFETCH(bool, orderMatters); + QFETCH(bool, result); + + MockMouseTrigger trigger; + trigger.setMouseButtons(triggerButtons.value()); + trigger.setMouseButtonsExactOrder(orderMatters); + + TriggerActivationEvent event; + event.setMouseButtons(eventButtons); + QCOMPARE(trigger.canActivate(event), result); + } +}; + +} + +QTEST_MAIN(InputActions::TestMouseTrigger) +#include "TestMouseTrigger.moc" \ No newline at end of file diff --git a/tests/libinputactions/triggers/TestTrigger.cpp b/tests/libinputactions/triggers/TestTrigger.cpp index 306b983..19460eb 100644 --- a/tests/libinputactions/triggers/TestTrigger.cpp +++ b/tests/libinputactions/triggers/TestTrigger.cpp @@ -1,7 +1,7 @@ #include "Test.h" +#include "mocks/MockTrigger.h" #include #include -#include namespace InputActions { @@ -11,63 +11,6 @@ class TestTrigger : public Test Q_OBJECT private slots: - void init() { m_trigger = std::make_unique(); } - - void canActivate_mouseButtons_data() - { - QTest::addColumn>>("triggerButtons"); - QTest::addColumn>>("eventButtons"); - QTest::addColumn("orderMatters"); - QTest::addColumn("result"); - - const auto unset = std::optional>(); - const auto none = std::optional>(std::vector()); - const auto left = std::optional>{{BTN_LEFT}}; - const auto right = std::optional>{{BTN_RIGHT}}; - const auto leftRight = std::optional>{{BTN_LEFT, BTN_RIGHT}}; - const auto rightLeft = std::optional>{{BTN_RIGHT, BTN_LEFT}}; - - QTest::newRow("1") << left << unset << false << true; - QTest::newRow("3") << left << left << false << true; - QTest::newRow("4") << right << left << false << false; - QTest::newRow("5") << left << right << false << false; - QTest::newRow("6") << leftRight << left << false << false; - QTest::newRow("7") << left << leftRight << false << false; - - QTest::newRow("8") << left << unset << true << true; - QTest::newRow("9") << left << left << true << true; - QTest::newRow("10") << right << left << true << false; - QTest::newRow("11") << left << right << true << false; - QTest::newRow("12") << leftRight << left << true << false; - QTest::newRow("13") << left << leftRight << true << false; - - QTest::newRow("14") << leftRight << leftRight << false << true; - QTest::newRow("15") << leftRight << rightLeft << false << true; - QTest::newRow("16") << rightLeft << leftRight << false << true; - - QTest::newRow("17") << leftRight << rightLeft << true << false; - QTest::newRow("18") << rightLeft << leftRight << true << false; - - QTest::newRow("19") << none << unset << false << true; - QTest::newRow("20") << none << left << false << true; - QTest::newRow("21") << none << unset << true << true; - QTest::newRow("22") << none << left << true << true; - } - - void canActivate_mouseButtons() - { - QFETCH(std::optional>, triggerButtons); - QFETCH(std::optional>, eventButtons); - QFETCH(bool, orderMatters); - QFETCH(bool, result); - - TriggerActivationEvent event; - m_trigger->setMouseButtons(triggerButtons.value()); - m_trigger->setMouseButtonsExactOrder(orderMatters); - event.setMouseButtons(eventButtons); - QCOMPARE(m_trigger->canActivate(event), result); - } - void update_threshold_data() { QTest::addColumn>>("threshold"); @@ -88,24 +31,23 @@ private slots: QFETCH(std::vector, deltas); QFETCH(bool, actionExecuted); + MockTrigger trigger; + if (threshold) { + trigger.setThreshold(threshold.value()); + } + auto action = std::make_unique(); const auto *actionRaw = action.get(); action->setOn(On::Begin); - m_trigger->addAction(std::move(action)); - if (threshold) { - m_trigger->setThreshold(threshold.value()); - } + trigger.addAction(std::move(action)); TriggerUpdateEvent event; for (const auto &delta : deltas) { event.setDelta(delta); - m_trigger->update(event); + trigger.update(event); } QCOMPARE(actionRaw->action()->executions(), actionExecuted); } - -private: - std::unique_ptr m_trigger; }; } diff --git a/tests/libinputactions/triggers/TestDirectionalMotionTrigger.cpp b/tests/libinputactions/triggers/core/TestDirectionalMotionTriggerCore.cpp similarity index 63% rename from tests/libinputactions/triggers/TestDirectionalMotionTrigger.cpp rename to tests/libinputactions/triggers/core/TestDirectionalMotionTriggerCore.cpp index beb0dae..0cba757 100644 --- a/tests/libinputactions/triggers/TestDirectionalMotionTrigger.cpp +++ b/tests/libinputactions/triggers/core/TestDirectionalMotionTriggerCore.cpp @@ -1,10 +1,10 @@ #include "Test.h" -#include +#include namespace InputActions { -class TestDirectionalMotionTrigger : public Test +class TestDirectionalMotionTriggerCore : public Test { Q_OBJECT @@ -26,39 +26,39 @@ private slots: << std::vector({static_cast(PinchDirection::Out)}) << std::vector({static_cast(PinchDirection::In)}); // Rotate is same as pinch - QTest::addRow("swipe left") << static_cast(SwipeDirection::Left) - << std::vector({static_cast(SwipeDirection::Left)}) - << std::vector({static_cast(SwipeDirection::Right), - static_cast(SwipeDirection::Up), - static_cast(SwipeDirection::Down)}); - QTest::addRow("swipe right") << static_cast(SwipeDirection::Right) - << std::vector({static_cast(SwipeDirection::Right)}) - << std::vector({static_cast(SwipeDirection::Left), - static_cast(SwipeDirection::Up), - static_cast(SwipeDirection::Down)}); + QTest::addRow("swipe left") << static_cast(SimpleSwipeDirection::Left) + << std::vector({static_cast(SimpleSwipeDirection::Left)}) + << std::vector({static_cast(SimpleSwipeDirection::Right), + static_cast(SimpleSwipeDirection::Up), + static_cast(SimpleSwipeDirection::Down)}); + QTest::addRow("swipe right") << static_cast(SimpleSwipeDirection::Right) + << std::vector({static_cast(SimpleSwipeDirection::Right)}) + << std::vector({static_cast(SimpleSwipeDirection::Left), + static_cast(SimpleSwipeDirection::Up), + static_cast(SimpleSwipeDirection::Down)}); QTest::addRow("swipe left/right") - << static_cast(SwipeDirection::LeftRight) - << std::vector({static_cast(SwipeDirection::Left), static_cast(SwipeDirection::Right)}) - << std::vector({static_cast(SwipeDirection::Up), static_cast(SwipeDirection::Down)}); - QTest::addRow("swipe up") << static_cast(SwipeDirection::Up) - << std::vector({static_cast(SwipeDirection::Up)}) - << std::vector({static_cast(SwipeDirection::Right), - static_cast(SwipeDirection::Left), - static_cast(SwipeDirection::Down)}); - QTest::addRow("swipe down") << static_cast(SwipeDirection::Down) - << std::vector({static_cast(SwipeDirection::Down)}) - << std::vector({static_cast(SwipeDirection::Right), - static_cast(SwipeDirection::Up), - static_cast(SwipeDirection::Left)}); + << static_cast(SimpleSwipeDirection::LeftRight) + << std::vector({static_cast(SimpleSwipeDirection::Left), static_cast(SimpleSwipeDirection::Right)}) + << std::vector({static_cast(SimpleSwipeDirection::Up), static_cast(SimpleSwipeDirection::Down)}); + QTest::addRow("swipe up") << static_cast(SimpleSwipeDirection::Up) + << std::vector({static_cast(SimpleSwipeDirection::Up)}) + << std::vector({static_cast(SimpleSwipeDirection::Right), + static_cast(SimpleSwipeDirection::Left), + static_cast(SimpleSwipeDirection::Down)}); + QTest::addRow("swipe down") << static_cast(SimpleSwipeDirection::Down) + << std::vector({static_cast(SimpleSwipeDirection::Down)}) + << std::vector({static_cast(SimpleSwipeDirection::Right), + static_cast(SimpleSwipeDirection::Up), + static_cast(SimpleSwipeDirection::Left)}); QTest::addRow("swipe up/down") - << static_cast(SwipeDirection::UpDown) - << std::vector({static_cast(SwipeDirection::Up), static_cast(SwipeDirection::Down)}) - << std::vector({static_cast(SwipeDirection::Left), static_cast(SwipeDirection::Right)}); - QTest::addRow("swipe any") << static_cast(SwipeDirection::Any) - << std::vector({static_cast(SwipeDirection::Up), - static_cast(SwipeDirection::Down), - static_cast(SwipeDirection::Left), - static_cast(SwipeDirection::Right)}) + << static_cast(SimpleSwipeDirection::UpDown) + << std::vector({static_cast(SimpleSwipeDirection::Up), static_cast(SimpleSwipeDirection::Down)}) + << std::vector({static_cast(SimpleSwipeDirection::Left), static_cast(SimpleSwipeDirection::Right)}); + QTest::addRow("swipe any") << static_cast(SimpleSwipeDirection::Any) + << std::vector({static_cast(SimpleSwipeDirection::Up), + static_cast(SimpleSwipeDirection::Down), + static_cast(SimpleSwipeDirection::Left), + static_cast(SimpleSwipeDirection::Right)}) << std::vector({}); } @@ -68,21 +68,21 @@ private slots: QFETCH(std::vector, valid); QFETCH(std::vector, invalid); - auto trigger = std::make_unique(TriggerType::None, direction); + DirectionalMotionTriggerCore core(direction); for (const auto &validDirection : valid) { DirectionalMotionTriggerUpdateEvent event; event.setDirection(validDirection); - QVERIFY(trigger->canUpdate(event)); + QVERIFY(core.canUpdate(event)); } for (const auto &invalidDirection : invalid) { DirectionalMotionTriggerUpdateEvent event; event.setDirection(invalidDirection); - QVERIFY(!trigger->canUpdate(event)); + QVERIFY(!core.canUpdate(event)); } } }; } -QTEST_MAIN(InputActions::TestDirectionalMotionTrigger) -#include "TestDirectionalMotionTrigger.moc" \ No newline at end of file +QTEST_MAIN(InputActions::TestDirectionalMotionTriggerCore) +#include "TestDirectionalMotionTriggerCore.moc" \ No newline at end of file diff --git a/tests/libinputactions/triggers/TestMotionTrigger.cpp b/tests/libinputactions/triggers/core/TestMotionTriggerCore.cpp similarity index 80% rename from tests/libinputactions/triggers/TestMotionTrigger.cpp rename to tests/libinputactions/triggers/core/TestMotionTriggerCore.cpp index fda1696..6c5e70c 100644 --- a/tests/libinputactions/triggers/TestMotionTrigger.cpp +++ b/tests/libinputactions/triggers/core/TestMotionTriggerCore.cpp @@ -1,10 +1,10 @@ #include "Test.h" -#include +#include namespace InputActions { -class TestMotionTrigger : public Test +class TestMotionTriggerCore : public Test { Q_OBJECT @@ -32,16 +32,16 @@ private slots: QFETCH(TriggerSpeed, eventSpeed); QFETCH(bool, result); - auto trigger = std::make_unique(); - trigger->setSpeed(triggerSpeed); + MotionTriggerCore core; + core.setSpeed(triggerSpeed); MotionTriggerUpdateEvent event; event.setSpeed(eventSpeed); - QCOMPARE(trigger->canUpdate(event), result); + QCOMPARE(core.canUpdate(event), result); } }; } -QTEST_MAIN(InputActions::TestMotionTrigger) -#include "TestMotionTrigger.moc" \ No newline at end of file +QTEST_MAIN(InputActions::TestMotionTriggerCore) +#include "TestMotionTriggerCore.moc" \ No newline at end of file diff --git a/tests/libinputactions/triggers/TestSwipeTrigger.cpp b/tests/libinputactions/triggers/core/TestSwipeTriggerCore.cpp similarity index 79% rename from tests/libinputactions/triggers/TestSwipeTrigger.cpp rename to tests/libinputactions/triggers/core/TestSwipeTriggerCore.cpp index 27d0be7..a90e64b 100644 --- a/tests/libinputactions/triggers/TestSwipeTrigger.cpp +++ b/tests/libinputactions/triggers/core/TestSwipeTriggerCore.cpp @@ -1,36 +1,36 @@ #include "Test.h" -#include "mocks/MockSwipeTrigger.h" +#include "mocks/MockSwipeTriggerCore.h" using namespace ::testing; namespace InputActions { -class TestSwipeTrigger : public Test +class TestSwipeTriggerCore : public Test { Q_OBJECT private slots: void canUpdate_currentAngleDoesNotMatchRange_averageAngleMatchesRange__returnsTrue() { - SwipeTrigger trigger(30, 60); + SwipeTriggerCore core(30, 60); SwipeTriggerUpdateEvent event; event.setAngle(0); event.setAverageAngle(45); - QCOMPARE(trigger.canUpdate(event), true); + QCOMPARE(core.canUpdate(event), true); } void canUpdate_currentAngleMatchesRange_averageAngleDoesNotMatchRange__returnsFalse() { - SwipeTrigger trigger(30, 60); + SwipeTriggerCore core(30, 60); SwipeTriggerUpdateEvent event; event.setAngle(45); event.setAverageAngle(0); - QCOMPARE(trigger.canUpdate(event), false); + QCOMPARE(core.canUpdate(event), false); } void canUpdate_data() @@ -55,60 +55,60 @@ private slots: QFETCH(qreal, angle); QFETCH(bool, returnValue); - SwipeTrigger trigger(min, max); - trigger.setBidirectional(bidirectional); + SwipeTriggerCore core(min, max); + core.setBidirectional(bidirectional); SwipeTriggerUpdateEvent event; event.setAverageAngle(angle); - QCOMPARE(trigger.canUpdate(event), returnValue); + QCOMPARE(core.canUpdate(event), returnValue); } void updateActions_bidirectional_normalAngle__updatesActionsWithPositiveDelta() { - MockSwipeTrigger trigger(0, 0); - trigger.setBidirectional(true); - EXPECT_CALL(trigger, doUpdateActions(Property(&TriggerUpdateEvent::delta, Property(&Delta::unaccelerated, Eq(10))))).Times(1); + MockSwipeTriggerCore core(0, 0); + core.setBidirectional(true); + EXPECT_CALL(core, doUpdateActions(_, Property(&TriggerUpdateEvent::delta, Property(&Delta::unaccelerated, Eq(10))))).Times(1); SwipeTriggerUpdateEvent event; event.setAngle(0); event.setDelta(10); - trigger.updateActions(event); + core.updateActions({}, event); - QVERIFY(Mock::VerifyAndClearExpectations(&trigger)); + QVERIFY(Mock::VerifyAndClearExpectations(&core)); } void updateActions_bidirectional_oppositeAngle__updatesActionsWithNegativeDelta() { - MockSwipeTrigger trigger(0, 0); - trigger.setBidirectional(true); - EXPECT_CALL(trigger, doUpdateActions(Property(&TriggerUpdateEvent::delta, Property(&Delta::unaccelerated, Eq(-10))))).Times(1); + MockSwipeTriggerCore core(0, 0); + core.setBidirectional(true); + EXPECT_CALL(core, doUpdateActions(_, Property(&TriggerUpdateEvent::delta, Property(&Delta::unaccelerated, Eq(-10))))).Times(1); SwipeTriggerUpdateEvent event; event.setAngle(180); event.setDelta(10); - trigger.updateActions(event); + core.updateActions({}, event); - QVERIFY(Mock::VerifyAndClearExpectations(&trigger)); + QVERIFY(Mock::VerifyAndClearExpectations(&core)); } void updateActions_bidirectional_overlappingAngleRanges__normalRangeHasHigherPriority() { - MockSwipeTrigger trigger(0, 270); - trigger.setBidirectional(true); - EXPECT_CALL(trigger, doUpdateActions(Property(&TriggerUpdateEvent::delta, Property(&Delta::unaccelerated, Gt(-10))))).Times(2); + MockSwipeTriggerCore core(0, 270); + core.setBidirectional(true); + EXPECT_CALL(core, doUpdateActions(_, Property(&TriggerUpdateEvent::delta, Property(&Delta::unaccelerated, Gt(-10))))).Times(2); SwipeTriggerUpdateEvent event; event.setAngle(30); event.setDelta(10); - trigger.updateActions(event); + core.updateActions({}, event); event.setAngle(260); - trigger.updateActions(event); + core.updateActions({}, event); - QVERIFY(Mock::VerifyAndClearExpectations(&trigger)); + QVERIFY(Mock::VerifyAndClearExpectations(&core)); } void matchesAngleRange_data() @@ -143,7 +143,7 @@ private slots: QFETCH(qreal, angle); QFETCH(bool, result); - QCOMPARE(SwipeTrigger::matchesAngleRange(angle, a, b), result); + QCOMPARE(SwipeTriggerCore::matchesAngleRange(angle, a, b), result); } void matchesOppositeAngleRange_data() @@ -178,11 +178,11 @@ private slots: QFETCH(qreal, angle); QFETCH(bool, result); - QCOMPARE(SwipeTrigger::matchesOppositeAngleRange(angle, a, b), result); + QCOMPARE(SwipeTriggerCore::matchesOppositeAngleRange(angle, a, b), result); } }; } -QTEST_MAIN(InputActions::TestSwipeTrigger) -#include "TestSwipeTrigger.moc" \ No newline at end of file +QTEST_MAIN(InputActions::TestSwipeTriggerCore) +#include "TestSwipeTriggerCore.moc" \ No newline at end of file