feat(boards): add device detection and text scrolling support
This commit is contained in:
@@ -304,8 +304,10 @@ void DoorbellLogic::onSerialCommand(const String& cmd) {
|
||||
Serial.println();
|
||||
Serial.printf("[NET] %s RSSI:%d IP:%s\n", _state.wifiSsid.c_str(), _state.wifiRssi,
|
||||
_state.ipAddr.c_str());
|
||||
} else if(cmd == "board") {
|
||||
Serial.printf("[BOARD] %s\n", _board);
|
||||
} else
|
||||
Serial.println(F("[CMD] alert|silence|reboot|dashboard|off|status"));
|
||||
Serial.println(F("[CMD] alert|silence|reboot|dashboard|off|status|board"));
|
||||
}
|
||||
|
||||
void DoorbellLogic::setScreen(ScreenID s) {
|
||||
|
||||
@@ -23,6 +23,7 @@ public:
|
||||
void processSerial();
|
||||
|
||||
const ScreenState& getScreenState() const { return _state; }
|
||||
const char* getBoard() const { return _board; }
|
||||
|
||||
/// Externally trigger silence (e.g. hold-to-silence gesture).
|
||||
void silenceAlert();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <cstdint>
|
||||
|
||||
struct Layout {
|
||||
@@ -36,6 +37,89 @@ struct Layout {
|
||||
uint16_t y = row * (tileH + gap);
|
||||
return Layout(x, y, tileW, tileH);
|
||||
}
|
||||
|
||||
Layout clamp(uint16_t maxW, uint16_t maxH) const {
|
||||
return Layout(
|
||||
x < maxW ? x : maxW, y < maxH ? y : maxH, w <= maxW ? w : maxW, h <= maxH ? h : maxH);
|
||||
}
|
||||
|
||||
Layout padded(uint16_t padding) const {
|
||||
uint16_t newX = x + padding;
|
||||
uint16_t newY = y + padding;
|
||||
uint16_t newW = w > 2 * padding ? w - 2 * padding : 0;
|
||||
uint16_t newH = h > 2 * padding ? h - 2 * padding : 0;
|
||||
return Layout(newX, newY, newW, newH);
|
||||
}
|
||||
|
||||
bool contains(uint16_t px, uint16_t py) const {
|
||||
return px >= x && px < x + w && py >= y && py < y + h;
|
||||
}
|
||||
};
|
||||
|
||||
class TextScroller {
|
||||
public:
|
||||
TextScroller()
|
||||
: _text()
|
||||
, _scrollOffset(0)
|
||||
, _lastUpdateMs(0)
|
||||
, _scrollSpeed(50)
|
||||
, _pauseMs(2000) { }
|
||||
|
||||
void setText(const char* text) {
|
||||
if(text != _text.c_str()) {
|
||||
_text = text;
|
||||
_scrollOffset = 0;
|
||||
_lastUpdateMs = 0;
|
||||
_paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
void setScrollSpeed(uint16_t msPerPixel) { _scrollSpeed = msPerPixel; }
|
||||
void setPauseDuration(uint16_t ms) { _pauseMs = ms; }
|
||||
|
||||
template <typename DrawFn> void render(DrawFn draw, uint16_t maxWidth) {
|
||||
uint32_t now = millis();
|
||||
|
||||
if(_text.length() <= maxWidth / 8) {
|
||||
draw(0, _text.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if(!_paused && now - _lastUpdateMs > _scrollSpeed) {
|
||||
_scrollOffset++;
|
||||
_lastUpdateMs = now;
|
||||
|
||||
if(_scrollOffset > (int)_text.length() * 6) {
|
||||
_paused = true;
|
||||
_pauseStartMs = now;
|
||||
}
|
||||
}
|
||||
|
||||
if(_paused && now - _pauseStartMs > _pauseMs) {
|
||||
_paused = false;
|
||||
_scrollOffset = 0;
|
||||
_lastUpdateMs = now;
|
||||
}
|
||||
|
||||
int16_t x = -_scrollOffset;
|
||||
char buf[2] = { 0 };
|
||||
for(size_t i = 0; i < _text.length(); i++) {
|
||||
buf[0] = _text.charAt(i);
|
||||
if(x + 8 > 0 && x < (int)maxWidth) {
|
||||
draw(x, buf);
|
||||
}
|
||||
x += 6;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
String _text;
|
||||
int16_t _scrollOffset;
|
||||
uint32_t _lastUpdateMs;
|
||||
uint32_t _pauseStartMs;
|
||||
uint16_t _scrollSpeed;
|
||||
uint16_t _pauseMs;
|
||||
bool _paused;
|
||||
};
|
||||
|
||||
struct TileMetrics {
|
||||
|
||||
Reference in New Issue
Block a user