Documentation and reference implementation of command protocol v3, which adds mapping between trigger events and actions.
pip install -r requirements.txt
python main.py
Use the keys 1 and 2 to simulate button presses.
---
title: cmd protocol class diagram
---
classDiagram
TriggerType <|-- Button
TriggerType <|-- Pressure
TriggerType : +TriggerState state
TriggerType : +Action action
TriggerType : +TriggerType next
TriggerType: +process()
TriggerType "1" --> "0..1" TriggerType
class Button{
}
class Pressure{
}
Action <|-- MouseAction
Action <|-- IRAction
Action "1" --> "0..1" Action
class Action{
+execute()
}
class MouseAction{
}
class IRAction{
}
A button trigger type can be triggered by several modalities:
- single-click
- double-click
- triple-click
- long-press
- (combination of triggers 1-4 of the same button or another one.)
All triggers can have a timeout value, which resets the current state and starts evaluating a trigger type from the beginning.
A Trigger type is implemented as a class and maintains it's own state. The states can be one of the following:
- STARTED: Trigger object waits for key input to be evaluated
- CANCELLED: Input evaluation went into timeout
- FIRED: The Trigger object has had a valid combination of the required key inputs within the defined timeout time span.
- NEXT: The Trigger object has had a valid combination of the required key inputs and is cascaded with a subsequent Trigger object which does further processing of key inputs now.
a1 = Action(name="single-click action")
a2 = Action(name="double-click action")
a3 = Action(name="triple-click action")
a4 = Action(name="long press action")
a5 = Action(name="combined action")
# Button 1, single-click
b1=Button(name="b1",source=1,mode="pressed",count=1, timeout=400,action=a1)
# Button 1, double-click
b2 = Button(name="b2",source=1, mode="pressed", count=2, timeout=400, action=a2)
# Button 1, triple-click
b3 = Button(name="b3",source=1, mode="pressed", count=3, timeout=400, action=a3)
# Button 1, long press
b4 = Button(name="b4", source=1, mode="long_pressed", count=1, timeout=600, duration=100, action=a4)
# Button 1 single-click + Button 2 single-click
b5 = Button(name="b5", source=1, mode="pressed", count=1, timeout=200,
next_trigger=Button(name="b5a", source=2, mode="pressed", count=1, timeout=200, action=a5)
The trigger mappings must be grouped by trigger_type (e.g. button and source number) and then sorted by priority within that group.
- Button 1, long press
- Button 1, triple-click
- Button 1, single-click + Button 2, single-click
- Button 1, double-click
- Button 1, single-click
trigger_defs=[b4,b3,b5,b2,b1]
A button press is then propagated to all trigger mappings and the action is executed according to the following flowchart:
graph TD;
A[Start] -->B4{B4 Fired?};
B4 -- Yes --> A4[Execute Action A4]
B4 -- No --> B3{B3 Fired?};
B3 -- Yes --> A3{Execute Action A3}
B3 -- No --> B5{B5 Fired?}
B5 -- Yes --> A5{Execute Action A5}
B5 --> No --> B2{B2 Fired?}
B2 -- Yes --> A2[Execute Action A2]
B2 -- No --> A1[Execute Action A1]
-
Button 1 Press --> Immediate action
-
Button 1 Release --> Immediate action
-
Combined execute either A or B (internally pause normal mouse action):
- A: Strong Sip + Button 1 Press
- B: Button Press 1
-
Button 1 Long Press (after duration) --> action
-
Button 2 Press --> Immediate action
-
Detection with debouncing and tremor filters
-
Test cases with morse code logic