xevi/NuEVI/src/adjustmenu.cpp
Brian Hrebec 01d193c9b3 Refactored for teensy 4.0, xEvi hardware
- Switched to platformio, ino -> cpp
- MPRLS for pressure sensor
- Added basic ICM support
- Removed widi, battery, other features not supported in xEvi
- Removed legacy options/processing
- Added LED strip support
- Added encoder support
- Reworked menu code to use encoders/be more flexible
2023-08-27 11:52:08 -05:00

175 lines
5.8 KiB
C++

#include <array>
#include <Arduino.h>
#include <Adafruit_SSD1306.h>
#include "menu.h"
#include "globals.h"
#include "config.h"
#include "hardware.h"
#include "settings.h"
//***********************************************************
extern Adafruit_SSD1306 display;
extern Adafruit_MPR121 touchSensorUtil;
extern Adafruit_MPR121 touchSensorKeys;
extern Adafruit_MPRLS pressureSensorMain;
extern Adafruit_MPRLS pressureSensorAlt;
extern byte cursorNow;
int16_t ctouchVal = 0;
// Track pixels for faster redrawing
struct AdjustDrawing {
int row;
int thrX;
int maxX;
int valX;
};
struct AdjustValue {
const char *title;
const int16_t &value;
int16_t &thrVal;
int16_t &maxVal;
const int16_t limitLow;
const int16_t limitHigh;
// If not null, thr and max are relative to zeroPoint
const int16_t *zeroPoint;
};
template<size_t N>
class AdjustMenuScreen : public MenuScreen {
public:
AdjustMenuScreen(const char* title, std::array<AdjustValue, N> entries) : _title(title), _entries(entries) { }
void update(InputState input, bool redraw) {
bool redrawIndicators = false;
if (input.changed) {
if (input.knobMenu) {
_selectedEntry = _selectedEntry + input.knobMenu;
redraw = true;
}
AdjustValue value = _entries[_selectedEntry];
if (input.knobVal1) {
value.thrVal += input.knobVal1;
redrawIndicators = true;
}
if (input.knobVal2) {
value.maxVal += input.knobVal2;
redrawIndicators = true;
}
} else {
draw(redrawIndicators, redraw);
}
}
const char *title() {
return _title;
}
private:
void draw(bool redrawIndicators, bool redraw) {
for (size_t i = 0; i < N; i++) {
if (redraw) {
drawAdjustRow(_entries[i], _rowDrawings[i], i == _selectedEntry);
} else if (redrawIndicators && i == _selectedEntry) {
drawAdjustIndicators(_entries[i], _rowDrawings[i]);
} else {
drawAdjustValues(_entries[i], _rowDrawings[i]);
}
}
}
const char* _title;
size_t _selectedEntry = 0;
std::array<AdjustValue, N> _entries;
std::array<AdjustDrawing, N> _rowDrawings;
};
std::array<AdjustValue, 8> adjustValues = {{
{"BREATH", state.breathSignal, calibration.breathThrValOffset, calibration.breathMaxValOffset,
BREATH_LO_LIMIT, BREATH_HI_LIMIT, &state.breathZero},
{"BR ALT", state.breathAltSignal, calibration.breathAltThrValOffset, calibration.breathAltMaxValOffset,
BREATH_LO_LIMIT, BREATH_HI_LIMIT, &state.breathAltZero},
{"BITE",state.biteSignal, calibration.biteThrVal, calibration.biteMaxVal, BITE_LO_LIMIT, BITE_HI_LIMIT, NULL},
{"PB DOWN",state.pbDnSignal, calibration.pbDnThrVal, calibration.pbDnMaxVal, PITCHB_LO_LIMIT, PITCHB_HI_LIMIT, NULL},
{"PB UP", state.pbUpSignal, calibration.pbUpThrVal, calibration.pbUpMaxVal, PITCHB_LO_LIMIT, PITCHB_HI_LIMIT, NULL},
{"EXTRA", state.extraSignal, calibration.extraThrVal, calibration.extraMaxVal, EXTRA_LO_LIMIT, EXTRA_HI_LIMIT, NULL},
{"LEVER", state.leverSignal, calibration.leverThrVal, calibration.leverMaxVal, LEVER_LO_LIMIT, LEVER_HI_LIMIT, NULL},
{"TOUCH", ctouchVal, calibration.ctouchThrVal, calibration.ctouchThrVal, CTOUCH_LO_LIMIT, CTOUCH_HI_LIMIT, NULL},
}};
const MenuScreen adjustMenu = AdjustMenuScreen<8>("ADJUST", adjustValues);
void autoCalSelected() {
}
//***********************************************************
static void drawIndicator(int x, int row, int color) {
display.fillTriangle(x-2, row+1, x+2, row+1, x, row+3, color);
display.fillTriangle(x-2, row+10, x+2, row+10, x, row+7, color);
}
static void drawAdjustIndicators(const AdjustValue &value, AdjustDrawing &drawing) {
const int thrX = mapConstrain(value.thrVal, value.limitLow, value.limitHigh, 1, 127);
const int maxX = mapConstrain(value.maxVal, value.limitLow, value.limitHigh, 1, 127);
if (drawing.maxX != maxX) {
drawIndicator(drawing.thrX, drawing.row, BLACK);
drawIndicator(thrX, drawing.row, WHITE);
drawing.maxX = maxX;
}
if (drawing.thrX != thrX) {
drawIndicator(drawing.thrX, drawing.row, BLACK);
drawIndicator(thrX, drawing.row, WHITE);
drawing.thrX = thrX;
}
}
static void drawAdjustTitle(const AdjustValue &value, AdjustDrawing &drawing, bool highlight) {
display.setTextSize(1);
if (highlight) {
display.setTextColor(BLACK, WHITE);
} else {
display.setTextColor(WHITE, BLACK);
}
display.setCursor(0, drawing.row);
display.println(value.title);
}
static void drawAdjustValues(const AdjustValue &value, AdjustDrawing &drawing) {
char buffer[13];
snprintf(buffer, 13, "%d>%d<%d", value.thrVal, value.value, value.maxVal);
display.setTextSize(1);
display.setCursor(128 - 6 * strlen(buffer), drawing.row);
display.println(buffer);
const int valX = mapConstrain(value.value, value.limitLow, value.limitHigh, 1, 127);
if (drawing.valX != valX) {
display.drawFastVLine(drawing.valX, drawing.row+4, 4, BLACK);
display.drawFastVLine(valX, drawing.row+4, 4, WHITE);
drawing.valX = valX;
}
}
static void drawAdjustFrame(int line) {
display.drawLine(25,line,120,line,WHITE); // Top line
display.drawLine(25,line+12,120,line+12,WHITE); // Bottom line
display.drawLine(25,line+1,25,line+2,WHITE);
display.drawLine(120,line+1,120,line+2,WHITE);
display.drawLine(120,line+10,120,line+11,WHITE);
display.drawLine(25,line+10,25,line+11,WHITE);
}
static void drawAdjustRow(const AdjustValue &value, AdjustDrawing &drawing, bool highlight) {
display.fillRect(0, drawing.row, 128, 21, BLACK);
drawAdjustFrame(drawing.row);
drawAdjustTitle(value, drawing, highlight);
drawAdjustValues(value, drawing);
drawAdjustIndicators(value, drawing);
}