mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-09-09 21:35:37 +00:00
feat: complete Cascade Indicator companion support
Add native-resolution Indicator UI, touch navigation, SD-backed pixel and emoji fonts, LoRa radio support, dual-slot WiFi Companion provisioning, and mesh clock fallback. Harden radio recovery and build defaults, normalize ESP32 setup-AP protocols, and document/test the operator workflows.
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <helpers/ui/TouchInput.h>
|
||||
|
||||
using mesh::ui::TouchAction;
|
||||
using mesh::ui::TouchInput;
|
||||
|
||||
namespace {
|
||||
|
||||
TouchAction release(TouchInput& input, int width = 137, int height = 137) {
|
||||
EXPECT_EQ(input.update(false, -1, -1, width, height), TouchAction::None);
|
||||
return input.update(false, -1, -1, width, height);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(TouchInput, EmitsOnlyAfterRelease) {
|
||||
TouchInput input;
|
||||
EXPECT_EQ(input.update(true, 70, 50, 137, 137), TouchAction::None);
|
||||
EXPECT_EQ(input.update(true, 72, 51, 137, 137), TouchAction::None);
|
||||
EXPECT_EQ(release(input), TouchAction::Select);
|
||||
EXPECT_EQ(input.update(false, -1, -1, 137, 137), TouchAction::None);
|
||||
}
|
||||
|
||||
TEST(TouchInput, MapsTapZonesToAllActions) {
|
||||
TouchInput input;
|
||||
|
||||
input.update(true, 10, 60, 137, 137);
|
||||
input.update(true, 10, 60, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Previous);
|
||||
|
||||
input.update(true, 68, 60, 137, 137);
|
||||
input.update(true, 68, 60, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Select);
|
||||
|
||||
input.update(true, 125, 60, 137, 137);
|
||||
input.update(true, 125, 60, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Next);
|
||||
}
|
||||
|
||||
TEST(TouchInput, CanUseAWiderCenterTapZone) {
|
||||
TouchInput input(false, false, 70);
|
||||
|
||||
input.update(true, 25, 60, 137, 137);
|
||||
input.update(true, 25, 60, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Select);
|
||||
|
||||
input.update(true, 10, 60, 137, 137);
|
||||
input.update(true, 10, 60, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Previous);
|
||||
|
||||
input.update(true, 127, 60, 137, 137);
|
||||
input.update(true, 127, 60, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Next);
|
||||
}
|
||||
|
||||
TEST(TouchInput, MapsHorizontalSwipesToPageNavigation) {
|
||||
TouchInput input;
|
||||
|
||||
input.update(true, 110, 60, 137, 137);
|
||||
input.update(true, 40, 62, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Next);
|
||||
|
||||
input.update(true, 30, 60, 137, 137);
|
||||
input.update(true, 105, 58, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Previous);
|
||||
}
|
||||
|
||||
TEST(TouchInput, MapsVerticalSwipesToPageNavigation) {
|
||||
TouchInput input;
|
||||
|
||||
input.update(true, 60, 110, 137, 137);
|
||||
input.update(true, 62, 35, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Next);
|
||||
|
||||
input.update(true, 60, 25, 137, 137);
|
||||
input.update(true, 58, 105, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Previous);
|
||||
}
|
||||
|
||||
TEST(TouchInput, CanRouteVerticalSwipesToASeparateSelector) {
|
||||
TouchInput input(true, true);
|
||||
|
||||
input.update(true, 60, 110, 137, 137);
|
||||
input.update(true, 62, 35, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::VerticalPrevious);
|
||||
|
||||
input.update(true, 60, 25, 137, 137);
|
||||
input.update(true, 58, 105, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::VerticalNext);
|
||||
|
||||
input.update(true, 110, 60, 137, 137);
|
||||
input.update(true, 40, 62, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Previous);
|
||||
}
|
||||
|
||||
TEST(TouchInput, BottomSelectorHasLargeArrowTapTargets) {
|
||||
TouchInput input(true, true, 70);
|
||||
|
||||
input.update(true, 15, 125, 137, 137, true);
|
||||
input.update(true, 15, 125, 137, 137, true);
|
||||
EXPECT_EQ(input.update(false, -1, -1, 137, 137, true),
|
||||
TouchAction::None);
|
||||
EXPECT_EQ(input.update(false, -1, -1, 137, 137, true),
|
||||
TouchAction::VerticalPrevious);
|
||||
|
||||
input.update(true, 122, 125, 137, 137, true);
|
||||
input.update(true, 122, 125, 137, 137, true);
|
||||
EXPECT_EQ(input.update(false, -1, -1, 137, 137, true),
|
||||
TouchAction::None);
|
||||
EXPECT_EQ(input.update(false, -1, -1, 137, 137, true),
|
||||
TouchAction::VerticalNext);
|
||||
|
||||
input.update(true, 68, 125, 137, 137, true);
|
||||
input.update(true, 68, 125, 137, 137, true);
|
||||
EXPECT_EQ(input.update(false, -1, -1, 137, 137, true),
|
||||
TouchAction::None);
|
||||
EXPECT_EQ(input.update(false, -1, -1, 137, 137, true),
|
||||
TouchAction::None);
|
||||
}
|
||||
|
||||
TEST(TouchInput, CanReverseSwipesWithoutReversingTapZones) {
|
||||
TouchInput input(true);
|
||||
|
||||
input.update(true, 110, 60, 137, 137);
|
||||
input.update(true, 40, 62, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Previous);
|
||||
|
||||
input.update(true, 30, 60, 137, 137);
|
||||
input.update(true, 105, 58, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Next);
|
||||
|
||||
input.update(true, 10, 60, 137, 137);
|
||||
input.update(true, 10, 60, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Previous);
|
||||
|
||||
input.update(true, 125, 60, 137, 137);
|
||||
input.update(true, 125, 60, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Next);
|
||||
}
|
||||
|
||||
TEST(TouchInput, KeepsGestureAcrossOneMissingTouchSample) {
|
||||
TouchInput input;
|
||||
|
||||
input.update(true, 110, 60, 137, 137);
|
||||
input.update(true, 80, 61, 137, 137);
|
||||
EXPECT_EQ(input.update(false, -1, -1, 137, 137), TouchAction::None);
|
||||
input.update(true, 40, 62, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Next);
|
||||
}
|
||||
|
||||
TEST(TouchInput, IgnoresContactWithNoDirectionSample) {
|
||||
TouchInput input;
|
||||
|
||||
input.update(true, 120, 60, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::None);
|
||||
}
|
||||
|
||||
TEST(TouchInput, UsesStartZoneForShortAmbiguousMovement) {
|
||||
TouchInput input(true);
|
||||
|
||||
input.update(true, 40, 60, 137, 137);
|
||||
input.update(true, 52, 60, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Previous);
|
||||
}
|
||||
|
||||
TEST(TouchInput, RepeatedSwipesKeepTheSameDirection) {
|
||||
TouchInput input(true);
|
||||
|
||||
for (int attempt = 0; attempt < 10; ++attempt) {
|
||||
input.update(true, 110, 60, 137, 137);
|
||||
input.update(true, 72, 61, 137, 137);
|
||||
input.update(true, 35, 62, 137, 137);
|
||||
EXPECT_EQ(release(input), TouchAction::Previous);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Reference in New Issue
Block a user