2424namespace InputActions
2525{
2626
27- /* *
28- * Angle tolerance for left, up, right and down directions. Remaining space is used for diagonals.
29- */
30- static const qreal ANGLE_TOLERANCE = 20 ;
31- // clang-format off
32- static const std::unordered_map<SwipeTriggerDirection, std::tuple<qreal, qreal, bool >> ANGLES {
33- // direction // min angle // max angle // bidirectional
34- {SwipeTriggerDirection::Left, {180 - ANGLE_TOLERANCE , 180 + ANGLE_TOLERANCE , false }},
35- {SwipeTriggerDirection::Right, {360 - ANGLE_TOLERANCE , ANGLE_TOLERANCE , false }},
36- {SwipeTriggerDirection::Up, {90 - ANGLE_TOLERANCE , 90 + ANGLE_TOLERANCE , false }},
37- {SwipeTriggerDirection::Down, {270 - ANGLE_TOLERANCE , 270 + ANGLE_TOLERANCE , false }},
38-
39- {SwipeTriggerDirection::LeftUp, {90 + ANGLE_TOLERANCE , 180 - ANGLE_TOLERANCE , false }},
40- {SwipeTriggerDirection::LeftDown, {180 + ANGLE_TOLERANCE , 270 - ANGLE_TOLERANCE , false }},
41- {SwipeTriggerDirection::RightUp, {ANGLE_TOLERANCE , 90 - ANGLE_TOLERANCE , false }},
42- {SwipeTriggerDirection::RightDown, {270 + ANGLE_TOLERANCE , 360 - ANGLE_TOLERANCE , false }},
43-
44- {SwipeTriggerDirection::LeftRight, {360 - ANGLE_TOLERANCE , ANGLE_TOLERANCE , true }},
45- {SwipeTriggerDirection::UpDown, {270 - ANGLE_TOLERANCE , 270 + ANGLE_TOLERANCE , true }},
46-
47- {SwipeTriggerDirection::LeftUpRightDown, {270 + ANGLE_TOLERANCE , 360 - ANGLE_TOLERANCE , true }},
48- {SwipeTriggerDirection::LeftDownRightUp, {ANGLE_TOLERANCE , 90 - ANGLE_TOLERANCE , true }},
49-
50- {SwipeTriggerDirection::Any, {0 , 360 , false }},
51- };
52- // clang-format on
53-
5427SwipeTrigger::SwipeTrigger (qreal minAngle, qreal maxAngle)
5528 : MotionTrigger(TriggerType::Swipe)
5629 , m_minAngle(minAngle)
@@ -60,11 +33,16 @@ SwipeTrigger::SwipeTrigger(qreal minAngle, qreal maxAngle)
6033
6134SwipeTrigger::SwipeTrigger (SwipeTriggerDirection direction)
6235 : MotionTrigger(TriggerType::Swipe)
36+ , m_direction(direction)
6337{
64- const auto &angles = ANGLES .at (direction);
65- m_minAngle = std::get<0 >(angles);
66- m_maxAngle = std::get<1 >(angles);
67- m_bidirectional = std::get<2 >(angles);
38+ switch (direction) {
39+ case SwipeTriggerDirection::LeftRight:
40+ case SwipeTriggerDirection::UpDown:
41+ case SwipeTriggerDirection::LeftUpRightDown:
42+ case SwipeTriggerDirection::LeftDownRightUp:
43+ m_bidirectional = true ;
44+ break ;
45+ }
6846}
6947
7048bool SwipeTrigger::canUpdate (const TriggerUpdateEvent &event) const
@@ -75,7 +53,9 @@ bool SwipeTrigger::canUpdate(const TriggerUpdateEvent &event) const
7553
7654 const auto &castedEvent = dynamic_cast <const SwipeTriggerUpdateEvent &>(event);
7755 const auto angle = castedEvent.averageAngle (); // Use the average so that the trigger is not cancelled on jitter
78- return matchesAngleRange (angle) || (m_bidirectional && matchesOppositeAngleRange (angle));
56+
57+ const auto range = angleRange (castedEvent.sender ());
58+ return matchesAngleRange (angle, range.min , range.max ) || (m_bidirectional && matchesOppositeAngleRange (angle, range.min , range.max ));
7959}
8060
8161void SwipeTrigger::updateActions (const TriggerUpdateEvent &event)
@@ -85,7 +65,8 @@ void SwipeTrigger::updateActions(const TriggerUpdateEvent &event)
8565
8666 // Ensure delta is always positive for normal angle range, and negative for opposite. Normal range takes priority over the opposite one in case of
8767 // overlapping.
88- if (!matchesAngleRange (angle) && matchesOppositeAngleRange (angle)) {
68+ const auto range = angleRange (newEvent.sender ());
69+ if (!matchesAngleRange (angle, range.min , range.max ) && matchesOppositeAngleRange (angle, range.min , range.max )) {
8970 auto delta = event.delta ();
9071 delta = {delta.accelerated () * -1 , delta.unaccelerated () * -1 };
9172 newEvent.setDelta (delta);
@@ -94,22 +75,66 @@ void SwipeTrigger::updateActions(const TriggerUpdateEvent &event)
9475 MotionTrigger::updateActions (newEvent);
9576}
9677
97- bool SwipeTrigger::matchesAngleRange (qreal angle ) const
78+ SwipeTrigger::AngleRange SwipeTrigger::angleRange ( const InputDevice *device ) const
9879{
99- if (m_minAngle <= m_maxAngle) {
100- return angle >= m_minAngle && angle <= m_maxAngle;
80+ if (!m_direction) {
81+ return {m_minAngle, m_maxAngle};
82+ }
83+
84+ const auto tolerance = device ? device->properties ().swipeAngleTolerance () : DEFAULT_SWIPE_ANGLE_TOLERANGE ;
85+ switch (m_direction.value ()) {
86+ case SwipeTriggerDirection::Left:
87+ return {180 - tolerance, 180 + tolerance};
88+ case SwipeTriggerDirection::Right:
89+ return {360 - tolerance, tolerance};
90+ case SwipeTriggerDirection::Up:
91+ return {90 - tolerance, 90 + tolerance};
92+ case SwipeTriggerDirection::Down:
93+ return {270 - tolerance, 270 + tolerance};
94+
95+ case SwipeTriggerDirection::LeftUp:
96+ return {90 + tolerance, 180 - tolerance};
97+ case SwipeTriggerDirection::LeftDown:
98+ return {180 + tolerance, 270 - tolerance};
99+ case SwipeTriggerDirection::RightUp:
100+ return {tolerance, 90 - tolerance};
101+ case SwipeTriggerDirection::RightDown:
102+ return {270 + tolerance, 360 - tolerance};
103+
104+ case SwipeTriggerDirection::LeftRight:
105+ return {360 - tolerance, tolerance};
106+ case SwipeTriggerDirection::UpDown:
107+ return {270 - tolerance, 270 + tolerance};
108+
109+ case SwipeTriggerDirection::LeftUpRightDown:
110+ return {270 + tolerance, 360 - tolerance};
111+ case SwipeTriggerDirection::LeftDownRightUp:
112+ return {tolerance, 90 - tolerance};
113+
114+ case SwipeTriggerDirection::Any:
115+ return {0 , 360 };
116+
117+ default :
118+ return {0 , 0 };
101119 }
102- return angle >= m_minAngle || angle <= m_maxAngle;
103120}
104121
105- bool SwipeTrigger::matchesOppositeAngleRange (qreal angle) const
122+ bool SwipeTrigger::matchesAngleRange (qreal angle, qreal min, qreal max)
106123{
107- auto min = m_minAngle - 180 ;
124+ if (min <= max) {
125+ return angle >= min && angle <= max;
126+ }
127+ return angle >= min || angle <= max;
128+ }
129+
130+ bool SwipeTrigger::matchesOppositeAngleRange (qreal angle, qreal min, qreal max)
131+ {
132+ min -= 180 ;
108133 if (min < 0 ) {
109134 min += 360 ;
110135 }
111136
112- auto max = m_maxAngle - 180 ;
137+ max -= 180 ;
113138 if (max < 0 ) {
114139 max += 360 ;
115140 }
@@ -120,4 +145,10 @@ bool SwipeTrigger::matchesOppositeAngleRange(qreal angle) const
120145 return angle >= min || angle <= max;
121146}
122147
148+ SwipeTrigger::AngleRange::AngleRange (qreal min, qreal max)
149+ : min(min)
150+ , max(max)
151+ {
152+ }
153+
123154}
0 commit comments