-
-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added touch driver and improved buttons for M5Core2
- Loading branch information
Showing
6 changed files
with
871 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
#include "M5PointAndZone.h" | ||
|
||
// Point class | ||
|
||
Point::Point(int16_t x_ /* = INVALID_VALUE */, | ||
int16_t y_ /* = INVALID_VALUE */) { | ||
x = x_; | ||
y = y_; | ||
} | ||
|
||
bool Point::operator==(const Point& p) { return (Equals(p)); } | ||
|
||
bool Point::operator!=(const Point& p) { return (!Equals(p)); } | ||
|
||
Point::operator char*() { | ||
if (valid()) { | ||
sprintf(_text, "(%d, %d)", x, y); | ||
} else { | ||
strncpy(_text, "(invalid)", 12); | ||
} | ||
return _text; | ||
} | ||
|
||
Point::operator bool() { return !(x == INVALID_VALUE && y == INVALID_VALUE); } | ||
|
||
void Point::set(int16_t x_ /* = INVALID_VALUE */, | ||
int16_t y_ /* = INVALID_VALUE */) { | ||
x = x_; | ||
y = y_; | ||
} | ||
|
||
bool Point::Equals(const Point& p) { return (x == p.x && y == p.y); } | ||
|
||
bool Point::in(Zone& z) { return (z.contains(x, y)); } | ||
|
||
bool Point::valid() { return !(x == INVALID_VALUE && y == INVALID_VALUE); } | ||
|
||
uint16_t Point::distanceTo(const Point& p) { | ||
int16_t dx = x - p.x; | ||
int16_t dy = y - p.y; | ||
return sqrt(dx * dx + dy * dy) + 0.5; | ||
} | ||
|
||
uint16_t Point::directionTo(const Point& p, bool rot1 /* = false */) { | ||
// 57.29578 =~ 180/pi, see https://stackoverflow.com/a/62486304 | ||
uint16_t a = (uint16_t)(450.5 + (atan2(p.y - y, p.x - x) * 57.29578)); | ||
#ifdef TFT | ||
if (rot1) { | ||
if (TFT->rotation < 4) { | ||
a = (((TFT->rotation + 3) % 4) * 90) + a; | ||
} else { | ||
a = (((TFT->rotation + 1) % 4) * 90) - a; | ||
} | ||
} | ||
#endif /* TFT */ | ||
a = (360 + a) % 360; | ||
return a; | ||
} | ||
|
||
bool Point::isDirectionTo(const Point& p, int16_t wanted, | ||
uint8_t plusminus /* = PLUSMINUS */, | ||
bool rot1 /* = false */) { | ||
uint16_t a = directionTo(p, rot1); | ||
return (min(abs(wanted - a), 360 - abs(wanted - a)) <= plusminus); | ||
} | ||
|
||
void Point::rotate(uint8_t m) { | ||
if (m == 1 || !valid()) return; | ||
int16_t normal_x = x; | ||
int16_t normal_y = y; | ||
int16_t inv_x = HIGHEST_X - x; | ||
int16_t inv_y = HIGHEST_Y - y; | ||
// inv_y can be negative for area below screen of M5Core2 | ||
switch (m) { | ||
case 0: | ||
x = inv_y; | ||
y = normal_x; | ||
break; | ||
case 2: | ||
x = normal_y; | ||
y = inv_x; | ||
break; | ||
case 3: | ||
x = inv_x; | ||
y = inv_y; | ||
break; | ||
// rotations 4-7 are mirrored | ||
case 4: | ||
x = inv_y; | ||
y = inv_x; | ||
break; | ||
case 5: | ||
x = normal_x; | ||
y = inv_y; | ||
break; | ||
case 6: | ||
x = normal_y; | ||
y = normal_x; | ||
break; | ||
case 7: | ||
x = inv_x; | ||
y = normal_y; | ||
break; | ||
} | ||
} | ||
|
||
// Zone class | ||
|
||
Zone::Zone(int16_t x_ /* = INVALID_VALUE */, int16_t y_ /* = INVALID_VALUE */, | ||
int16_t w_ /* = 0 */, int16_t h_ /* = 0 */, bool rot1_ /* = false */ | ||
) { | ||
set(x_, y_, w_, h_, rot1_); | ||
} | ||
|
||
Zone::operator bool() { return !(x == INVALID_VALUE && y == INVALID_VALUE); } | ||
|
||
void Zone::set(int16_t x_ /* = INVALID_VALUE */, | ||
int16_t y_ /* = INVALID_VALUE */, int16_t w_ /* = 0 */, | ||
int16_t h_ /* = 0 */, bool rot1_ /* = false */) { | ||
x = x_; | ||
y = y_; | ||
w = w_; | ||
h = h_; | ||
rot1 = rot1_; | ||
} | ||
|
||
bool Zone::valid() { return !(x == INVALID_VALUE && y == INVALID_VALUE); } | ||
|
||
bool Zone::contains(const Point& p) { return contains(p.x, p.y); } | ||
|
||
bool Zone::contains(int16_t x_, int16_t y_) { | ||
#ifdef TFT | ||
if (rot1 && TFT->rotation != 1) { | ||
Zone t = *this; | ||
t.rotate(TFT->rotation); | ||
return (y_ >= t.y && y_ <= t.y + t.h && x_ >= t.x && x_ <= t.x + t.w); | ||
} | ||
#endif /* TFT */ | ||
|
||
return (y_ >= y && y_ <= y + h && x_ >= x && x_ <= x + w); | ||
} | ||
|
||
void Zone::rotate(uint8_t m) { | ||
if (m == 1) return; | ||
int16_t normal_x = x; | ||
int16_t normal_y = y; | ||
int16_t inv_x = TFT_WIDTH - 1 - x - w; | ||
int16_t inv_y = TFT_HEIGHT - 1 - y - h; // negative for area below screen | ||
switch (m) { | ||
case 0: | ||
x = inv_y; | ||
y = normal_x; | ||
break; | ||
case 2: | ||
x = normal_y; | ||
y = inv_x; | ||
break; | ||
case 3: | ||
x = inv_x; | ||
y = inv_y; | ||
break; | ||
// rotations 4-7 are mirrored | ||
case 4: | ||
x = inv_y; | ||
y = inv_x; | ||
break; | ||
case 5: | ||
x = normal_x; | ||
y = inv_y; | ||
break; | ||
case 6: | ||
x = normal_y; | ||
y = normal_x; | ||
break; | ||
case 7: | ||
x = inv_x; | ||
y = normal_y; | ||
break; | ||
} | ||
if (!(m % 2)) std::swap(w, h); | ||
} |
Oops, something went wrong.