初始化提交
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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); };
|
||||
@@ -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); }
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user