Skip to content

Commit 4823c2e

Browse files
committed
Added @vkichline's TouchView and TouchGoal examples
1 parent 4d49de1 commit 4823c2e

File tree

5 files changed

+469
-0
lines changed

5 files changed

+469
-0
lines changed

examples/Touch/TouchGoal/Goals.cpp

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#include <M5Core2.h>
2+
#include "Goals.h"
3+
4+
extern Button A;
5+
extern Button B;
6+
7+
Goal::Goal() { name = ""; success = false; }
8+
bool Goal::passed() { return success; }
9+
const char* Goal::getName(){ return name.c_str(); }
10+
bool Goal::test() {
11+
M5.Lcd.fillRect(0, TEXT_TOP, 320, TEXT_HEIGHT, NAVY);
12+
M5.Lcd.drawCentreString(name, TEXT_CENTER, TEXT_TOP, TEXT_FONT);
13+
start_time = millis();
14+
while(start_time + TEST_DURRATION > millis()) {
15+
M5.update();
16+
delay(1);
17+
if(success) {
18+
return true;
19+
}
20+
}
21+
return false;
22+
}
23+
24+
25+
// Tap the A button
26+
//
27+
TapAGoal::TapAGoal() { name = "Tap the A Button"; }
28+
// Set success to true if all the conditions of the goal are met
29+
void TapAGoal::event_handler(Event& e) {
30+
if((E_TAP == e) && (0 == strcmp("A", e.button->name()))) success = true;
31+
}
32+
33+
34+
// Tap the B button
35+
//
36+
TapBGoal::TapBGoal() { name = "Tap the B Button"; }
37+
void TapBGoal::event_handler(Event& e) {
38+
if((E_TAP == e) && (0 == strcmp("B", e.button->name()))) success = true;
39+
}
40+
41+
// Long Press (LONG_PRESS_TIME mS) on the A Button
42+
//
43+
LongPressAGoal::LongPressAGoal() { name = "Long Press the A Button"; }
44+
void LongPressAGoal::event_handler(Event& e) {
45+
if((E_LONGPRESSED == e) && (0 == strcmp("A", e.button->name()))) success = true;
46+
}
47+
48+
49+
// Long Press (LONG_PRESS_TIME mS) on the B Button
50+
//
51+
LongPressBGoal::LongPressBGoal() { name = "Long Press the B Button"; }
52+
void LongPressBGoal::event_handler(Event& e) {
53+
if((E_LONGPRESSED == e) && (0 == strcmp("B", e.button->name()))) success = true;
54+
}
55+
56+
57+
// Long Press (LONG_PRESS_TIME mS) on the Background
58+
//
59+
LongPressBackgroundGoal::LongPressBackgroundGoal() { name = "Long Press the Background"; }
60+
void LongPressBackgroundGoal::event_handler(Event& e) {
61+
if((E_LONGPRESSED == e) && (0 == strcmp("background", e.button->name()))) success = true;
62+
}
63+
64+
65+
// Double Tap the A button
66+
//
67+
DoubleTapAGoal::DoubleTapAGoal() { name = "Double Tap the A Button"; }
68+
// Set success to true if all the conditions of the goal are met
69+
void DoubleTapAGoal::event_handler(Event& e) {
70+
if((E_DBLTAP == e) && (0 == strcmp("A", e.button->name()))) success = true;
71+
}
72+
73+
74+
// Double Tap the B button
75+
//
76+
DoubleTapBGoal::DoubleTapBGoal() { name = "Double Tap the B Button"; }
77+
void DoubleTapBGoal::event_handler(Event& e) {
78+
if((E_DBLTAP == e) && (0 == strcmp("B", e.button->name()))) success = true;
79+
}
80+
81+
82+
// Tap the Background
83+
//
84+
TapBackgroundGoal::TapBackgroundGoal() { name = "Tap the Background"; }
85+
// Set success to true if all the conditions of the goal are met
86+
void TapBackgroundGoal::event_handler(Event& e) {
87+
if((E_TAP == e) && (0 == strcmp("background", e.button->name()))) success = true;
88+
}
89+
90+
91+
// Double Tap the Background
92+
//
93+
DoubleTapBackgroundGoal::DoubleTapBackgroundGoal() { name = "Double Tap the Background"; }
94+
void DoubleTapBackgroundGoal::event_handler(Event& e) {
95+
if((E_DBLTAP == e) && (0 == strcmp("background", e.button->name()))) success = true;
96+
}
97+
98+
99+
// Drag from A to B
100+
//
101+
DragFromAtoBGoal::DragFromAtoBGoal() { name = "Drag From A to B"; }
102+
// The series of events I see is: E_TOUCH(A), E_MOVE(A)..., E_PRESSING(a), E_MOVE(A)..., E_RELEASE(A), E_DRAGGED(A)
103+
// Button never reflects another object; get position and test location.
104+
void DragFromAtoBGoal::event_handler(Event& e) {
105+
if(E_DRAGGED == e) {
106+
if(A.contains(e.from) && B.contains(e.to)) success = true;
107+
}
108+
}
109+
110+
111+
// Drag from B to A
112+
//
113+
DragFromBtoAGoal::DragFromBtoAGoal() { name = "Drag From B to A"; }
114+
void DragFromBtoAGoal::event_handler(Event& e) {
115+
if(E_DRAGGED == e) {
116+
if(B.contains(e.from) && A.contains(e.to)) success = true;
117+
}
118+
}
119+
120+
121+
// Drag from A to Background
122+
//
123+
DragFromAtoBackgroundGoal::DragFromAtoBackgroundGoal() { name = "Drag From A to Background"; }
124+
void DragFromAtoBackgroundGoal::event_handler(Event& e) {
125+
if(E_DRAGGED == e) {
126+
if(A.contains(e.from) && M5.background.contains(e.to) && !A.contains(e.to) && !B.contains(e.to)) success = true;
127+
}
128+
}
129+
130+
131+
// Drag from B to Background
132+
//
133+
DragFromBtoBackgroundGoal::DragFromBtoBackgroundGoal() { name = "Drag From B to Background"; }
134+
void DragFromBtoBackgroundGoal::event_handler(Event& e) {
135+
if(E_DRAGGED == e) {
136+
if(B.contains(e.from) && M5.background.contains(e.to) && !A.contains(e.to) && !B.contains(e.to)) success = true;
137+
}
138+
}
139+
140+
141+
// Drag from Background to A
142+
//
143+
DragFromBackgroundtoAGoal::DragFromBackgroundtoAGoal() {
144+
name = "Drag From Background to A";
145+
can_succeed = true;
146+
}
147+
// You don't get an E_DRAGGED event if you start in the background, so return an error if one comes in.
148+
void DragFromBackgroundtoAGoal::event_handler(Event& e) {
149+
if(E_DRAGGED == e) can_succeed = false;
150+
if(E_RELEASE == e) {
151+
if(M5.background.contains(e.from) && !A.contains(e.from) && !B.contains(e.from) && A.contains(e.to)) success = can_succeed;
152+
}
153+
}
154+
155+
156+
// Drag from Background to B
157+
//
158+
DragFromBackgroundtoBGoal::DragFromBackgroundtoBGoal() {
159+
name = "Drag From Background to B";
160+
can_succeed = true;
161+
}
162+
// You don't get an E_DRAGGED event if you start in the background, so return an error if one comes in.
163+
void DragFromBackgroundtoBGoal::event_handler(Event& e) {
164+
if(E_DRAGGED == e) can_succeed = false;
165+
if(E_RELEASE == e) {
166+
if(M5.background.contains(e.from) && !A.contains(e.from) && !B.contains(e.from) && B.contains(e.to)) success = can_succeed;
167+
}
168+
}
169+
170+
171+
// Swipe up detection
172+
//
173+
SwipeUpGoal::SwipeUpGoal() { name = "Swipe Up"; }
174+
void SwipeUpGoal::event_handler(Event& e) {
175+
if((E_GESTURE == e) && (0 == strcmp("swipe up", e.gesture->name()))) success = true;
176+
}
177+
178+
// Swipe down detection
179+
//
180+
SwipeDownGoal::SwipeDownGoal() { name = "Swipe Down"; }
181+
void SwipeDownGoal::event_handler(Event& e) {
182+
if((E_GESTURE == e) && (0 == strcmp("swipe down", e.gesture->name()))) success = true;
183+
}
184+
185+
// Swipe left detection
186+
//
187+
SwipeLeftGoal::SwipeLeftGoal() { name = "Swipe Left"; }
188+
void SwipeLeftGoal::event_handler(Event& e) {
189+
if((E_GESTURE == e) && (0 == strcmp("swipe left", e.gesture->name()))) success = true;
190+
}
191+
192+
// Swipe right detection
193+
//
194+
SwipeRightGoal::SwipeRightGoal() { name = "Swipe Right"; }
195+
void SwipeRightGoal::event_handler(Event& e) {
196+
if((E_GESTURE == e) && (0 == strcmp("swipe right", e.gesture->name()))) success = true;
197+
}

examples/Touch/TouchGoal/Goals.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#pragma once
2+
3+
#define TEXT_TOP 25
4+
#define TEXT_CENTER 160
5+
#define TEXT_HEIGHT 32
6+
#define TEXT_FONT 4
7+
8+
#define TEST_DURRATION 8000
9+
10+
class Goal {
11+
public:
12+
Goal();
13+
bool test();
14+
bool passed();
15+
const char* getName();
16+
virtual void event_handler(Event& evt) = 0;
17+
protected:
18+
String name;
19+
uint32_t start_time;
20+
bool success;
21+
};
22+
23+
class TapAGoal : public Goal { public: TapAGoal(); void event_handler(Event& e); };
24+
class TapBGoal : public Goal { public: TapBGoal(); void event_handler(Event& e); };
25+
class LongPressAGoal : public Goal { public: LongPressAGoal(); void event_handler(Event& e); };
26+
class LongPressBGoal : public Goal { public: LongPressBGoal(); void event_handler(Event& e); };
27+
class LongPressBackgroundGoal : public Goal { public: LongPressBackgroundGoal(); void event_handler(Event& e); };
28+
class DoubleTapAGoal : public Goal { public: DoubleTapAGoal(); void event_handler(Event& e); };
29+
class DoubleTapBGoal : public Goal { public: DoubleTapBGoal(); void event_handler(Event& e); };
30+
class TapBackgroundGoal : public Goal { public: TapBackgroundGoal(); void event_handler(Event& e); };
31+
class DoubleTapBackgroundGoal : public Goal { public: DoubleTapBackgroundGoal(); void event_handler(Event& e); };
32+
class DragFromAtoBGoal : public Goal { public: DragFromAtoBGoal(); void event_handler(Event& e); };
33+
class DragFromBtoAGoal : public Goal { public: DragFromBtoAGoal(); void event_handler(Event& e); };
34+
class DragFromAtoBackgroundGoal : public Goal { public: DragFromAtoBackgroundGoal(); void event_handler(Event& e); };
35+
class DragFromBtoBackgroundGoal : public Goal { public: DragFromBtoBackgroundGoal(); void event_handler(Event& e); };
36+
class DragFromBackgroundtoAGoal : public Goal { public: DragFromBackgroundtoAGoal(); void event_handler(Event& e); private: bool can_succeed; };
37+
class DragFromBackgroundtoBGoal : public Goal { public: DragFromBackgroundtoBGoal(); void event_handler(Event& e); private: bool can_succeed; };
38+
class SwipeUpGoal : public Goal { public: SwipeUpGoal(); void event_handler(Event& e); };
39+
class SwipeDownGoal : public Goal { public: SwipeDownGoal(); void event_handler(Event& e); };
40+
class SwipeLeftGoal : public Goal { public: SwipeLeftGoal(); void event_handler(Event& e); };
41+
class SwipeRightGoal : public Goal { public: SwipeRightGoal(); void event_handler(Event& e); };
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include <M5Core2.h>
2+
#include "Goals.h"
3+
4+
// This program provides goal-oriented tested for M5Buttons
5+
6+
#define SCORE_TOP 200
7+
#define SCORE_HEIGHT 32
8+
#define SCORE_FONT 4
9+
#define LONG_PRESS_TIME 500
10+
11+
// Defines gestures
12+
Gesture swipeRight("swipe right", 80, DIR_RIGHT, 30, true);
13+
Gesture swipeDown ("swipe down", 60, DIR_DOWN, 30, true);
14+
Gesture swipeLeft ("swipe left", 80, DIR_LEFT, 30, true);
15+
Gesture swipeUp ("swipe up", 60, DIR_UP, 30, true);
16+
17+
ButtonColors on_clrs = {BLACK, WHITE, WHITE};
18+
ButtonColors off_clrs = {BLACK, WHITE, WHITE};
19+
20+
Button A(40, 80, 80, 80, false ,"A", off_clrs, on_clrs, MC_DATUM);
21+
Button B(200, 80, 80, 80, false ,"B", off_clrs, on_clrs, MC_DATUM);
22+
23+
24+
Goal* current_goal = nullptr;
25+
Goal* goals[] = { new TapAGoal(), new TapBGoal(), new DoubleTapAGoal(), new DoubleTapBGoal(),
26+
new LongPressAGoal(), new LongPressBackgroundGoal(), new LongPressBGoal(),
27+
new TapBackgroundGoal(), new DoubleTapBackgroundGoal(), new DragFromAtoBGoal(),
28+
new DragFromBtoAGoal(), new DragFromAtoBackgroundGoal(), new DragFromBtoBackgroundGoal(),
29+
new DragFromBackgroundtoAGoal(), new DragFromBackgroundtoBGoal(), new SwipeUpGoal(),
30+
new SwipeDownGoal(), new SwipeLeftGoal(), new SwipeRightGoal()
31+
};
32+
33+
void eventHandler(Event& e) {
34+
if(current_goal) current_goal->event_handler(e);
35+
}
36+
37+
void show_score(int successes, int failures) {
38+
M5.Lcd.fillRect(0, SCORE_TOP, 320, SCORE_HEIGHT, NAVY);
39+
uint8_t datum = M5.Lcd.getTextDatum();
40+
M5.Lcd.setTextDatum(TL_DATUM);
41+
String str = "Pass: ";
42+
str += String(successes);
43+
M5.Lcd.drawString(str, 20, SCORE_TOP, SCORE_FONT);
44+
str = "Fail: ";
45+
str += String(failures);
46+
M5.Lcd.setTextDatum(TR_DATUM);
47+
M5.Lcd.drawString(str, 300, SCORE_TOP, SCORE_FONT);
48+
M5.Lcd.setTextDatum(datum);
49+
}
50+
51+
void setup() {
52+
M5.begin();
53+
A.longPressTime = B.longPressTime = M5.background.longPressTime = LONG_PRESS_TIME;
54+
M5.Lcd.fillScreen(NAVY);
55+
M5.Lcd.setTextSize(1);
56+
M5.Lcd.setTextColor(WHITE, NAVY);
57+
M5.Lcd.drawCentreString("Goal Oriented Testing", TEXT_CENTER, TEXT_TOP, TEXT_FONT);
58+
M5.Buttons.addHandler(eventHandler, E_ALL);
59+
M5.Buttons.draw();
60+
}
61+
62+
void loop() {
63+
int successes = 0;
64+
int failures = 0;
65+
int len = sizeof(goals) / sizeof(Goal*);
66+
// Shuffle the goals
67+
for (int i=0; i < len; i++) {
68+
int n = random(0, len); // Integer from 0 to len-1
69+
Goal* temp = goals[n];
70+
goals[n] = goals[i];
71+
goals[i] = temp;
72+
}
73+
74+
for(int i = 0; i < len; i++) {
75+
delay(500);
76+
current_goal = goals[i];
77+
if(current_goal->test()) {
78+
successes++;
79+
}
80+
else {
81+
failures++;
82+
}
83+
current_goal = nullptr;
84+
M5.Lcd.fillRect(0, TEXT_TOP, 320, TEXT_HEIGHT, NAVY);
85+
show_score(successes, failures);
86+
}
87+
M5.Lcd.drawCentreString("Test Complete", TEXT_CENTER, TEXT_TOP, TEXT_FONT);
88+
if(failures) {
89+
M5.Lcd.fillRect(0, TEXT_TOP+TEXT_HEIGHT, 320, 240, NAVY);
90+
M5.Lcd.setCursor(20, TEXT_TOP + 50, TEXT_FONT);
91+
M5.Lcd.println("Failures:");
92+
for(uint8_t i = 0; i < len; i++) {
93+
if(!goals[i]->passed()) {
94+
M5.Lcd.print(" ");
95+
M5.Lcd.println(goals[i]->getName());
96+
}
97+
}
98+
}
99+
while(true) { delay(1000); }
100+
}

0 commit comments

Comments
 (0)