初始化提交

This commit is contained in:
王立帮
2024-07-20 22:09:06 +08:00
commit c247dd07a6
6876 changed files with 2743096 additions and 0 deletions

View File

@@ -0,0 +1,197 @@
#include <M5Core2.h>
#include "Goals.h"
extern Button A;
extern Button B;
Goal::Goal() { name = ""; success = false; }
bool Goal::passed() { return success; }
const char* Goal::getName(){ return name.c_str(); }
bool Goal::test() {
M5.Lcd.fillRect(0, TEXT_TOP, 320, TEXT_HEIGHT, NAVY);
M5.Lcd.drawCentreString(name, TEXT_CENTER, TEXT_TOP, TEXT_FONT);
start_time = millis();
while(start_time + TEST_DURRATION > millis()) {
M5.update();
delay(1);
if(success) {
return true;
}
}
return false;
}
// Tap the A button
//
TapAGoal::TapAGoal() { name = "Tap the A Button"; }
// Set success to true if all the conditions of the goal are met
void TapAGoal::event_handler(Event& e) {
if((E_TAP == e) && (0 == strcmp("A", e.button->getName()))) success = true;
}
// Tap the B button
//
TapBGoal::TapBGoal() { name = "Tap the B Button"; }
void TapBGoal::event_handler(Event& e) {
if((E_TAP == e) && (0 == strcmp("B", e.button->getName()))) success = true;
}
// Long Press (LONG_PRESS_TIME mS) on the A Button
//
LongPressAGoal::LongPressAGoal() { name = "Long Press the A Button"; }
void LongPressAGoal::event_handler(Event& e) {
if((E_LONGPRESSED == e) && (0 == strcmp("A", e.button->getName()))) success = true;
}
// Long Press (LONG_PRESS_TIME mS) on the B Button
//
LongPressBGoal::LongPressBGoal() { name = "Long Press the B Button"; }
void LongPressBGoal::event_handler(Event& e) {
if((E_LONGPRESSED == e) && (0 == strcmp("B", e.button->getName()))) success = true;
}
// Long Press (LONG_PRESS_TIME mS) on the Background
//
LongPressBackgroundGoal::LongPressBackgroundGoal() { name = "Long Press the Background"; }
void LongPressBackgroundGoal::event_handler(Event& e) {
if((E_LONGPRESSED == e) && (0 == strcmp("background", e.button->getName()))) success = true;
}
// Double Tap the A button
//
DoubleTapAGoal::DoubleTapAGoal() { name = "Double Tap the A Button"; }
// Set success to true if all the conditions of the goal are met
void DoubleTapAGoal::event_handler(Event& e) {
if((E_DBLTAP == e) && (0 == strcmp("A", e.button->getName()))) success = true;
}
// Double Tap the B button
//
DoubleTapBGoal::DoubleTapBGoal() { name = "Double Tap the B Button"; }
void DoubleTapBGoal::event_handler(Event& e) {
if((E_DBLTAP == e) && (0 == strcmp("B", e.button->getName()))) success = true;
}
// Tap the Background
//
TapBackgroundGoal::TapBackgroundGoal() { name = "Tap the Background"; }
// Set success to true if all the conditions of the goal are met
void TapBackgroundGoal::event_handler(Event& e) {
if((E_TAP == e) && (0 == strcmp("background", e.button->getName()))) success = true;
}
// Double Tap the Background
//
DoubleTapBackgroundGoal::DoubleTapBackgroundGoal() { name = "Double Tap the Background"; }
void DoubleTapBackgroundGoal::event_handler(Event& e) {
if((E_DBLTAP == e) && (0 == strcmp("background", e.button->getName()))) success = true;
}
// Drag from A to B
//
DragFromAtoBGoal::DragFromAtoBGoal() { name = "Drag From A to B"; }
// 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)
// Button never reflects another object; get position and test location.
void DragFromAtoBGoal::event_handler(Event& e) {
if(E_DRAGGED == e) {
if(A.contains(e.from) && B.contains(e.to)) success = true;
}
}
// Drag from B to A
//
DragFromBtoAGoal::DragFromBtoAGoal() { name = "Drag From B to A"; }
void DragFromBtoAGoal::event_handler(Event& e) {
if(E_DRAGGED == e) {
if(B.contains(e.from) && A.contains(e.to)) success = true;
}
}
// Drag from A to Background
//
DragFromAtoBackgroundGoal::DragFromAtoBackgroundGoal() { name = "Drag From A to Background"; }
void DragFromAtoBackgroundGoal::event_handler(Event& e) {
if(E_DRAGGED == e) {
if(A.contains(e.from) && M5.background.contains(e.to) && !A.contains(e.to) && !B.contains(e.to)) success = true;
}
}
// Drag from B to Background
//
DragFromBtoBackgroundGoal::DragFromBtoBackgroundGoal() { name = "Drag From B to Background"; }
void DragFromBtoBackgroundGoal::event_handler(Event& e) {
if(E_DRAGGED == e) {
if(B.contains(e.from) && M5.background.contains(e.to) && !A.contains(e.to) && !B.contains(e.to)) success = true;
}
}
// Drag from Background to A
//
DragFromBackgroundtoAGoal::DragFromBackgroundtoAGoal() {
name = "Drag From Background to A";
can_succeed = true;
}
// You don't get an E_DRAGGED event if you start in the background, so return an error if one comes in.
void DragFromBackgroundtoAGoal::event_handler(Event& e) {
if(E_DRAGGED == e) can_succeed = false;
if(E_RELEASE == e) {
if(M5.background.contains(e.from) && !A.contains(e.from) && !B.contains(e.from) && A.contains(e.to)) success = can_succeed;
}
}
// Drag from Background to B
//
DragFromBackgroundtoBGoal::DragFromBackgroundtoBGoal() {
name = "Drag From Background to B";
can_succeed = true;
}
// You don't get an E_DRAGGED event if you start in the background, so return an error if one comes in.
void DragFromBackgroundtoBGoal::event_handler(Event& e) {
if(E_DRAGGED == e) can_succeed = false;
if(E_RELEASE == e) {
if(M5.background.contains(e.from) && !A.contains(e.from) && !B.contains(e.from) && B.contains(e.to)) success = can_succeed;
}
}
// Swipe up detection
//
SwipeUpGoal::SwipeUpGoal() { name = "Swipe Up"; }
void SwipeUpGoal::event_handler(Event& e) {
if((E_GESTURE == e) && (0 == strcmp("swipe up", e.gesture->getName()))) success = true;
}
// Swipe down detection
//
SwipeDownGoal::SwipeDownGoal() { name = "Swipe Down"; }
void SwipeDownGoal::event_handler(Event& e) {
if((E_GESTURE == e) && (0 == strcmp("swipe down", e.gesture->getName()))) success = true;
}
// Swipe left detection
//
SwipeLeftGoal::SwipeLeftGoal() { name = "Swipe Left"; }
void SwipeLeftGoal::event_handler(Event& e) {
if((E_GESTURE == e) && (0 == strcmp("swipe left", e.gesture->getName()))) success = true;
}
// Swipe right detection
//
SwipeRightGoal::SwipeRightGoal() { name = "Swipe Right"; }
void SwipeRightGoal::event_handler(Event& e) {
if((E_GESTURE == e) && (0 == strcmp("swipe right", e.gesture->getName()))) success = true;
}

View File

@@ -0,0 +1,41 @@
#pragma once
#define TEXT_TOP 25
#define TEXT_CENTER 160
#define TEXT_HEIGHT 32
#define TEXT_FONT 4
#define TEST_DURRATION 8000
class Goal {
public:
Goal();
bool test();
bool passed();
const char* getName();
virtual void event_handler(Event& evt) = 0;
protected:
String name;
uint32_t start_time;
bool success;
};
class TapAGoal : public Goal { public: TapAGoal(); void event_handler(Event& e); };
class TapBGoal : public Goal { public: TapBGoal(); void event_handler(Event& e); };
class LongPressAGoal : public Goal { public: LongPressAGoal(); void event_handler(Event& e); };
class LongPressBGoal : public Goal { public: LongPressBGoal(); void event_handler(Event& e); };
class LongPressBackgroundGoal : public Goal { public: LongPressBackgroundGoal(); void event_handler(Event& e); };
class DoubleTapAGoal : public Goal { public: DoubleTapAGoal(); void event_handler(Event& e); };
class DoubleTapBGoal : public Goal { public: DoubleTapBGoal(); void event_handler(Event& e); };
class TapBackgroundGoal : public Goal { public: TapBackgroundGoal(); void event_handler(Event& e); };
class DoubleTapBackgroundGoal : public Goal { public: DoubleTapBackgroundGoal(); void event_handler(Event& e); };
class DragFromAtoBGoal : public Goal { public: DragFromAtoBGoal(); void event_handler(Event& e); };
class DragFromBtoAGoal : public Goal { public: DragFromBtoAGoal(); void event_handler(Event& e); };
class DragFromAtoBackgroundGoal : public Goal { public: DragFromAtoBackgroundGoal(); void event_handler(Event& e); };
class DragFromBtoBackgroundGoal : public Goal { public: DragFromBtoBackgroundGoal(); void event_handler(Event& e); };
class DragFromBackgroundtoAGoal : public Goal { public: DragFromBackgroundtoAGoal(); void event_handler(Event& e); private: bool can_succeed; };
class DragFromBackgroundtoBGoal : public Goal { public: DragFromBackgroundtoBGoal(); void event_handler(Event& e); private: bool can_succeed; };
class SwipeUpGoal : public Goal { public: SwipeUpGoal(); void event_handler(Event& e); };
class SwipeDownGoal : public Goal { public: SwipeDownGoal(); void event_handler(Event& e); };
class SwipeLeftGoal : public Goal { public: SwipeLeftGoal(); void event_handler(Event& e); };
class SwipeRightGoal : public Goal { public: SwipeRightGoal(); void event_handler(Event& e); };

View File

@@ -0,0 +1,100 @@
#include <M5Core2.h>
#include "Goals.h"
// This program provides goal-oriented tested for M5Buttons
#define SCORE_TOP 200
#define SCORE_HEIGHT 32
#define SCORE_FONT 4
#define LONG_PRESS_TIME 500
// Defines gestures
Gesture swipeRight("swipe right", 80, DIR_RIGHT, 30, true);
Gesture swipeDown ("swipe down", 60, DIR_DOWN, 30, true);
Gesture swipeLeft ("swipe left", 80, DIR_LEFT, 30, true);
Gesture swipeUp ("swipe up", 60, DIR_UP, 30, true);
ButtonColors on_clrs = {BLACK, WHITE, WHITE};
ButtonColors off_clrs = {BLACK, WHITE, WHITE};
Button A(40, 80, 80, 80, false ,"A", off_clrs, on_clrs, MC_DATUM);
Button B(200, 80, 80, 80, false ,"B", off_clrs, on_clrs, MC_DATUM);
Goal* current_goal = nullptr;
Goal* goals[] = { new TapAGoal(), new TapBGoal(), new DoubleTapAGoal(), new DoubleTapBGoal(),
new LongPressAGoal(), new LongPressBackgroundGoal(), new LongPressBGoal(),
new TapBackgroundGoal(), new DoubleTapBackgroundGoal(), new DragFromAtoBGoal(),
new DragFromBtoAGoal(), new DragFromAtoBackgroundGoal(), new DragFromBtoBackgroundGoal(),
new DragFromBackgroundtoAGoal(), new DragFromBackgroundtoBGoal(), new SwipeUpGoal(),
new SwipeDownGoal(), new SwipeLeftGoal(), new SwipeRightGoal()
};
void eventHandler(Event& e) {
if(current_goal) current_goal->event_handler(e);
}
void show_score(int successes, int failures) {
M5.Lcd.fillRect(0, SCORE_TOP, 320, SCORE_HEIGHT, NAVY);
uint8_t datum = M5.Lcd.getTextDatum();
M5.Lcd.setTextDatum(TL_DATUM);
String str = "Pass: ";
str += String(successes);
M5.Lcd.drawString(str, 20, SCORE_TOP, SCORE_FONT);
str = "Fail: ";
str += String(failures);
M5.Lcd.setTextDatum(TR_DATUM);
M5.Lcd.drawString(str, 300, SCORE_TOP, SCORE_FONT);
M5.Lcd.setTextDatum(datum);
}
void setup() {
M5.begin();
A.longPressTime = B.longPressTime = M5.background.longPressTime = LONG_PRESS_TIME;
M5.Lcd.fillScreen(NAVY);
M5.Lcd.setTextSize(1);
M5.Lcd.setTextColor(WHITE, NAVY);
M5.Lcd.drawCentreString("Goal Oriented Testing", TEXT_CENTER, TEXT_TOP, TEXT_FONT);
M5.Buttons.addHandler(eventHandler, E_ALL);
M5.Buttons.draw();
}
void loop() {
int successes = 0;
int failures = 0;
int len = sizeof(goals) / sizeof(Goal*);
// Shuffle the goals
for (int i=0; i < len; i++) {
int n = random(0, len); // Integer from 0 to len-1
Goal* temp = goals[n];
goals[n] = goals[i];
goals[i] = temp;
}
for(int i = 0; i < len; i++) {
delay(500);
current_goal = goals[i];
if(current_goal->test()) {
successes++;
}
else {
failures++;
}
current_goal = nullptr;
M5.Lcd.fillRect(0, TEXT_TOP, 320, TEXT_HEIGHT, NAVY);
show_score(successes, failures);
}
M5.Lcd.drawCentreString("Test Complete", TEXT_CENTER, TEXT_TOP, TEXT_FONT);
if(failures) {
M5.Lcd.fillRect(0, TEXT_TOP+TEXT_HEIGHT, 320, 240, NAVY);
M5.Lcd.setCursor(20, TEXT_TOP + 50, TEXT_FONT);
M5.Lcd.println("Failures:");
for(uint8_t i = 0; i < len; i++) {
if(!goals[i]->passed()) {
M5.Lcd.print(" ");
M5.Lcd.println(goals[i]->getName());
}
}
}
while(true) { delay(1000); }
}

View File

@@ -0,0 +1,130 @@
#include <M5Core2.h>
// Display all the touch event on the M5Core2 screen.
// Press the A button to turn on/off E_MOVE event detection
// Press the B button to turn on/off long press (500mS) detection
// Press the C button to turn on/off key repeat (200mS)
TFT_eSprite disp(&M5.Lcd);
bool first_scroll = true;
bool show_move = false;
bool long_press = true;
bool key_repeat = false;
// Defines gestures
Gesture swipeRight("Swipe Right", 80, DIR_RIGHT, 30, true);
Gesture swipeDown( "Swipe Down", 60, DIR_DOWN, 30, true);
Gesture swipeLeft( "Swipe Left", 80, DIR_LEFT, 30, true);
Gesture swipeUp( "Swipe Up", 60, DIR_UP, 30, true);
// Use a scrollable sprite for output. Looks nice!
//
void setup_disp() {
disp.createSprite(320, 240);
disp.setScrollRect(0, 0, 320, 240);
disp.fillSprite(BLACK);
disp.setTextFont(2);
disp.setTextSize(1);
disp.setTextColor(WHITE, BLACK);
disp.setCursor(0, 0);
disp.pushSprite(0, 0);
}
// Lazy output routine. Just enough to do the job.
// str should fit on the screen (320 pixels) and not contain a \n
//
void output_info(const char* name, const char* info) {
Serial.printf("%-15s: %s\n", name, info);
if(disp.getCursorY() >= 220) {
disp.scroll(0, first_scroll ? -3 : -16);
first_scroll = false;
}
disp.printf("%s", name);
disp.setCursor(110, disp.getCursorY());
disp.printf("%s\n", info);
if(disp.getCursorY() >= 220) {
disp.setCursor(0, 220);
}
disp.pushSprite(0, 0);
}
// Let the user know what to do
//
void splash_screen() {
output_info("", "Welcome to TouchView");
output_info("Button A Sets", (show_move) ? "E_MOVE will be displayed" : "E_MOVE will be ignored");
output_info("Button B Sets", (long_press) ? "Long Presses will be detected" : "Long Presses will be ignored");
output_info("Button C Sets", (key_repeat) ? "Key Repeat Enabled" : "Key Repeat Disabled");
output_info("To Use", "Touch the Screen");
}
void eventHandler(Event& e) {
char buffer[32];
sprintf(buffer, "%3d,%3d/%3d,%3d %3d %3d %3d", e.from.x, e.from.y, e.to.x, e.to.y, e.distance(), e.direction(), e.duration);
output_info(e.typeName(), buffer);
}
void gestureHandler(Event& e) {
output_info(e.typeName(), e.gesture->getName());
}
// Remove/replace event handlers, since list of evetns could change.
//
void setup_events() {
M5.background.delHandlers();
uint16_t events = (show_move) ? E_ALL : (E_ALL - E_MOVE); // Show all events, or everything but E_MOVE? Controlled with A button.
M5.background.longPressTime = (long_press) ? 500 : 0; // Detect long presses (500mS) or not? Controlled with B button.
M5.background.repeatDelay = (key_repeat) ? 200 : 0; // Repeat press events every 200mS or not? Controlled with the C button.
M5.background.addHandler(eventHandler, events);
}
// Gestues only need to be set up once. I'll protect against multiple initializations.
//
void setupGestures() {
static bool done = false;
if(!done) {
done = true;
swipeRight.addHandler(gestureHandler, E_GESTURE);
swipeLeft.addHandler(gestureHandler, E_GESTURE);
swipeUp.addHandler(gestureHandler, E_GESTURE);
swipeDown.addHandler(gestureHandler, E_GESTURE);
}
}
void setup() {
M5.begin();
setup_disp();
splash_screen();
setup_events();
setupGestures();
}
void loop() {
M5.update();
if(M5.BtnA.wasPressed()) {
show_move = !show_move;
output_info("Button A", (show_move) ? "E_MOVE will be displayed" : "E_MOVE will be ignored");
setup_events();
}
if(M5.BtnB.wasPressed()) {
long_press = !long_press;
output_info("Button B", (long_press) ? "Long Presses will be detected" : "Long Presses will be ignored");
setup_events();
}
if(M5.BtnC.wasPressed()) {
key_repeat = !key_repeat;
output_info("Button C", (key_repeat) ? "Key Repeat Enabled" : "Key Repeat Disabled");
setup_events();
}
}

View File

@@ -0,0 +1,18 @@
#include <M5Core2.h>
void setup() {
M5.begin();
M5.Lcd.fillScreen(WHITE);
}
void loop() {
M5.update();
Event& e = M5.Buttons.event;
if (e & (E_MOVE | E_RELEASE)) circle(e & E_MOVE ? e.from : e.to, WHITE);
if (e & (E_TOUCH | E_MOVE)) circle(e.to, e.finger ? BLUE : RED);
}
void circle(Point p, uint16_t c) {
M5.Lcd.drawCircle(p.x, p.y, 50, c);
M5.Lcd.drawCircle(p.x, p.y, 52, c);
}

View File

@@ -0,0 +1,86 @@
#include <M5Core2.h>
// Defines gestures
Gesture swipeRight("swipe right", 160, DIR_RIGHT, 30, true);
Gesture swipeDown("swipe down", 120, DIR_DOWN, 30, true);
Gesture swipeLeft("swipe left", 160, DIR_LEFT, 30, true);
Gesture swipeUp("swipe up", 120, DIR_UP, 30, true);
// Defines the buttons. Colors in format {bg, text, outline}
ButtonColors on_clrs = {RED, WHITE, WHITE};
ButtonColors off_clrs = {BLACK, WHITE, WHITE};
Button tl(0, 0, 0, 0, false ,"top-left", off_clrs, on_clrs, TL_DATUM);
Button bl(0, 0, 0, 0, false, "bottom-left", off_clrs, on_clrs, BL_DATUM);
Button tr(0, 0, 0, 0, false, "top-right", off_clrs, on_clrs, TR_DATUM);
Button br(0, 0, 0, 0, false, "bottom-right", off_clrs, on_clrs, BR_DATUM);
// For performance measurement (Single tap on bottom-right button)
uint32_t startTime;
uint32_t times = 0;
void setup() {
M5.begin();
M5.Buttons.addHandler(doRotation, E_GESTURE);
M5.Buttons.addHandler(toggleColor, E_DBLTAP);
M5.Buttons.addHandler(eventDisplay, E_ALL - E_MOVE);
br.addHandler(showPerformance, E_TAP);
br.repeatDelay = 1000;
doButtons();
startTime = millis();
}
void loop() {
M5.update();
times++;
}
// Positions the buttons and draws them. (Only because height and width
// change. If we were only switching between normal and upside-down we
// would only need the Buttons.draw() here.)
void doButtons() {
int16_t hw = M5.Lcd.width() / 2;
int16_t hh = M5.Lcd.height() / 2;
tl.set(0, 0, hw - 5, hh - 5);
bl.set(0, hh + 5, hw - 5, hh - 5);
tr.set(hw + 5, 0, hw - 5, hh - 5);
br.set(hw + 5, hh + 5, hw - 5, hh - 5);
M5.Buttons.draw();
}
void doRotation(Event& e) {
// Gestures and Buttons have an instanceIndex() that starts at zero
// so by defining the gestures in the right order I can use that as
// the input for M5.Lcd.setRotation.
uint8_t new_rotation = e.gesture->instanceIndex();
if (new_rotation != M5.Lcd.rotation) {
M5.Lcd.clearDisplay();
M5.Lcd.setRotation(new_rotation);
doButtons();
}
}
void toggleColor(Event& e) {
// Just so we can type "b." instead of "e.button->"
Button& b = *e.button;
if (b != M5.background) {
// Toggles the button color between black and blue
b.off.bg = (b.off.bg == BLACK) ? BLUE : BLACK;
b.draw();
}
}
void showPerformance(Event& e) {
Serial.printf("%d in %d ms, average M5.update() took %.2f microseconds\n",
times, millis() - startTime, (float)((millis() - startTime) * 1000) / times);
startTime = millis();
times = 0;
}
void eventDisplay(Event& e) {
Serial.printf("%-12s finger%d %-18s (%3d, %3d) --> (%3d, %3d) ",
e.typeName(), e.finger, e.objName(), e.from.x, e.from.y,
e.to.x, e.to.y);
Serial.printf("( dir %d deg, dist %d, %d ms )\n", e.direction(),
e.distance(), e.duration);
}