refactor(display): extract dashboard tile grid logic to DisplayManager

This commit is contained in:
2026-02-18 04:28:35 -08:00
parent 3b8e54c511
commit 67613120ad
10 changed files with 259 additions and 64 deletions

View File

@@ -1,6 +1,7 @@
#pragma once
#include "IDisplayDriver.h"
#include "ScreenState.h"
class DisplayManager {
public:
@@ -24,8 +25,6 @@ public:
TouchEvent readTouch() { return _drv ? _drv->readTouch() : TouchEvent {}; }
int dashboardTouch(int x, int y) { return _drv ? _drv->dashboardTouch(x, y) : -1; }
HoldState updateHold(unsigned long ms) { return _drv ? _drv->updateHold(ms) : HoldState {}; }
void updateHint(int x, int y, bool active) {
@@ -34,9 +33,114 @@ public:
}
int width() { return _drv ? _drv->width() : 0; }
int height() { return _drv ? _drv->height() : 0; }
/// Auto-calculate grid dimensions for dashboard tiles
/// Prefers landscape (more columns than rows) for wide displays
void getTileGrid(int tileCount, int* outRows, int* outCols) const {
if(tileCount <= 0) {
*outRows = *outCols = 0;
return;
}
// Calculate cols: try to make it wider than tall
int cols = (int)sqrt(tileCount);
if(cols * cols < tileCount) cols++;
// Make cols >= rows for landscape preference
while(cols * ((tileCount + cols - 1) / cols) < tileCount) {
cols++;
}
int rows = (tileCount + cols - 1) / cols;
// If display is wider, prefer more columns
if(_drv) {
int w = _drv->width();
int h = _drv->height();
if(w > h) {
// Landscape display - maximize columns
cols = tileCount;
rows = 1;
}
}
*outRows = rows;
*outCols = cols;
}
/// Render all dashboard tiles with auto-calculated grid
void renderDashboard(const ScreenState& st) {
if(!_drv) return;
int rows, cols;
getTileGrid(DASHBOARD_TILE_COUNT, &rows, &cols);
int dispW = _drv->width();
int dispH = _drv->height();
// Reserve space for header
int headerH = 30;
int contentH = dispH - headerH;
// Calculate tile sizes
int tileW = dispW / cols;
int tileH = contentH / rows;
int margin = 8;
for(int i = 0; i < DASHBOARD_TILE_COUNT; i++) {
int row = i / cols;
int col = i % cols;
int x = col * tileW + margin;
int y = headerH + row * tileH + margin;
int w = tileW - 2 * margin;
int h = tileH - 2 * margin;
_drv->drawTileAt(x, y, w, h, DASHBOARD_TILES[i].label, DASHBOARD_TILES[i].bgColor);
}
// Store grid for touch calculations
_gridRows = rows;
_gridCols = cols;
}
/// Handle dashboard touch - returns action for tapped tile, or NONE
TileAction handleDashboardTouch(int x, int y) const {
if(!_drv || _gridCols <= 0) return TileAction::NONE;
// Transform touch coordinates (handles rotated touch panels)
_drv->transformTouch(&x, &y);
int dispW = _drv->width();
int dispH = _drv->height();
int headerH = 30;
// Check if in header area
if(y < headerH) return TileAction::NONE;
// Calculate which tile was touched
int tileW = dispW / _gridCols;
int contentH = dispH - headerH;
int tileH = contentH / _gridRows;
int col = x / tileW;
int row = (y - headerH) / tileH;
// Bounds check
if(col < 0 || col >= _gridCols || row < 0 || row >= _gridRows) {
return TileAction::NONE;
}
int index = row * _gridCols + col;
if(index < 0 || index >= DASHBOARD_TILE_COUNT) {
return TileAction::NONE;
}
return DASHBOARD_TILES[index].action;
}
private:
IDisplayDriver* _drv;
mutable int _gridRows = 0;
mutable int _gridCols = 0;
};