Merge pull request #17 from Trasselfrisyr/numenu

Full Menu Refactoring
This commit is contained in:
John Stäck 2019-06-25 13:06:02 +02:00 committed by GitHub
commit 34a3dd0613
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 1586 additions and 3668 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.vscode/ipch
*.o

View file

@ -89,33 +89,13 @@ unsigned short fastPatch[7] = {0,0,0,0,0,0,0};
byte rotatorOn = 0;
byte currentRotation = 0;
int rotations[4] = { -5, -10, -7, -14 }; // semitones { -5, -10, -7, -14 };
int parallel = 7; // semitones
uint16_t rotations[4]; // semitones { -5, -10, -7, -14 };
uint16_t parallel; // = 7; // semitones
byte gateOpen = 0; // setting for gate always open, note on sent for every time fingering changes, no matter the breath status
int breathLoLimit = 0;
int breathHiLimit = 4095;
int portamLoLimit = 700;
int portamHiLimit = 4700;
int pitchbLoLimit = 500;
int pitchbHiLimit = 4000;
int extracLoLimit = 500;
int extracHiLimit = 4000;
int ctouchLoLimit = 50;
int ctouchHiLimit = 350;
int ttouchLoLimit = 50;
int ttouchHiLimit = 1900;
int touch_Thr = 1300;
int breathStep;
int portamStep;
int pitchbStep;
int extracStep;
int ctouchStep;
byte ccList[11] = {0,1,2,7,11,1,2,7,11,74,20}; // OFF, Modulation, Breath, Volume, Expression (then same sent in hires), CC74 (cutoff/brightness), CC20
int pbDepthList[13] = {8192,8192,4096,2731,2048,1638,1365,1170,1024,910,819,744,683};
@ -363,11 +343,11 @@ void setup() {
fastPatch[5] = readSetting(FP6_ADDR);
fastPatch[6] = readSetting(FP7_ADDR);
dipSwBits = readSetting(DIPSW_BITS_ADDR);
parallel = readSetting(PARAL_ADDR)-24;
rotations[0] = readSetting(ROTN1_ADDR)-24;
rotations[1] = readSetting(ROTN2_ADDR)-24;
rotations[2] = readSetting(ROTN3_ADDR)-24;
rotations[3] = readSetting(ROTN4_ADDR)-24;
parallel = readSetting(PARAL_ADDR);
rotations[0] = readSetting(ROTN1_ADDR);
rotations[1] = readSetting(ROTN2_ADDR);
rotations[2] = readSetting(ROTN3_ADDR);
rotations[3] = readSetting(ROTN4_ADDR);
priority = readSetting(PRIO_ADDR);
vibSens = readSetting(VIB_SENS_ADDR);
vibRetn = readSetting(VIB_RETN_ADDR);
@ -379,12 +359,6 @@ void setup() {
slowMidi = dipSwBits & (1<<3);
activePatch = patch;
breathStep = (breathHiLimit - breathLoLimit)/92; // 92 is the number of pixels in the settings bar
portamStep = (portamHiLimit - portamLoLimit)/92;
pitchbStep = (pitchbHiLimit - pitchbLoLimit)/92;
extracStep = (extracHiLimit - extracLoLimit)/92;
ctouchStep = (ctouchHiLimit - ctouchLoLimit)/92;
touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit);
if (!touchSensor.begin(0x5A)) {
@ -673,10 +647,10 @@ void loop() {
}
}
if (rotatorOn) {
midiSendNoteOn(noteValueCheck(fingeredNote + parallel), velocitySend); // send Note On message for new note
midiSendNoteOn(noteValueCheck(fingeredNote + parallel-24), velocitySend); // send Note On message for new note
if (currentRotation < 3) currentRotation++;
else currentRotation = 0;
midiSendNoteOn(noteValueCheck(fingeredNote + rotations[currentRotation]), velocitySend); // send Note On message for new note
midiSendNoteOn(noteValueCheck(fingeredNote + rotations[currentRotation]-24), velocitySend); // send Note On message for new note
}
if (!priority) { // mono prio to base note
midiSendNoteOn(fingeredNote, velocitySend); // send Note On message for new note
@ -710,8 +684,8 @@ void loop() {
}
}
if (rotatorOn) {
midiSendNoteOff(noteValueCheck(activeNote + parallel)); // send Note Off message for old note
midiSendNoteOff(noteValueCheck(activeNote + rotations[currentRotation])); // send Note Off message for old note
midiSendNoteOff(noteValueCheck(activeNote + parallel-24 )); // send Note Off message for old note
midiSendNoteOff(noteValueCheck(activeNote + rotations[currentRotation]-24)); // send Note Off message for old note
}
if (!priority) {
midiSendNoteOff(activeNote); // send Note Off message
@ -759,8 +733,8 @@ void loop() {
}
}
if (rotatorOn) {
midiSendNoteOff(noteValueCheck(activeNote + parallel)); // send Note Off message for old note
midiSendNoteOff(noteValueCheck(activeNote + rotations[currentRotation])); // send Note Off message for old note
midiSendNoteOff(noteValueCheck(activeNote + parallel-24)); // send Note Off message for old note
midiSendNoteOff(noteValueCheck(activeNote + rotations[currentRotation]-24)); // send Note Off message for old note
}
if ((parallelChord || subOctaveDouble || rotatorOn) && !priority) { // poly playing, send old note off before new note on
midiSendNoteOff(activeNote); // send Note Off message for old note
@ -784,10 +758,10 @@ void loop() {
}
}
if (rotatorOn) {
midiSendNoteOn(noteValueCheck(fingeredNote + parallel), velocitySend); // send Note On message for new note
midiSendNoteOn(noteValueCheck(fingeredNote + parallel-24), velocitySend); // send Note On message for new note
if (currentRotation < 3) currentRotation++;
else currentRotation = 0;
midiSendNoteOn(noteValueCheck(fingeredNote + rotations[currentRotation]), velocitySend); // send Note On message for new note
midiSendNoteOn(noteValueCheck(fingeredNote + rotations[currentRotation]-24), velocitySend); // send Note On message for new note
}
if (!priority) {
@ -1233,9 +1207,9 @@ void extraController() {
void portamento_() {
// Portamento is controlled with the bite sensor (variable capacitor) in the mouthpiece
if (biteJumper){ //PBITE (if pulled low with jumper, use pressure sensor on A7)
biteSensor=analogRead(A7); // alternative kind bite sensor (air pressure tube and sensor) PBITE
biteSensor = analogRead(A7); // alternative kind bite sensor (air pressure tube and sensor) PBITE
} else {
biteSensor=touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right)
biteSensor = touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right)
}
if (portamento && (biteSensor >= portamThrVal)) { // if we are enabled and over the threshold, send portamento
if (!portIsOn) {

374
NuEVI/adjustmenu.cpp Normal file
View file

@ -0,0 +1,374 @@
#include <Arduino.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_MPR121.h>
#include "menu.h"
#include "numenu.h"
#include "globals.h"
#include "config.h"
#include "hardware.h"
#include "settings.h"
//***********************************************************
extern Adafruit_SSD1306 display;
extern Adafruit_MPR121 touchSensor;
extern byte cursorNow;
//***********************************************************
// Variables used for the adjust menu
static byte forcePix;
static uint16_t pos1;
static uint16_t pos2;
static int16_t adjustOption;
static int16_t adjustCurrent;
static int16_t sensorPixelPos1 = -1;
static int16_t sensorPixelPos2 = -1;
static bool refreshScreen;
//***********************************************************
static void breathSave(const AdjustMenuEntry& e) {
writeSetting(BREATH_THR_ADDR, *e.entries[0].value);
writeSetting(BREATH_MAX_ADDR, *e.entries[1].value);
}
const AdjustMenuEntry breathAdjustMenu = {
"BREATH",
{
{ &breathThrVal, breathLoLimit, breathHiLimit },
{ &breathMaxVal, breathLoLimit, breathHiLimit }
},
breathSave
};
static void portamentoSave(const AdjustMenuEntry& e) {
writeSetting(PORTAM_THR_ADDR, *e.entries[0].value);
writeSetting(PORTAM_MAX_ADDR, *e.entries[1].value);
}
const AdjustMenuEntry portamentoAdjustMenu = {
"PORTAMENTO",
{
{ &portamThrVal, portamLoLimit, portamHiLimit },
{ &portamMaxVal, portamLoLimit, portamHiLimit }
},
portamentoSave
};
static void pbSave(const AdjustMenuEntry& e) {
writeSetting(PITCHB_THR_ADDR, *e.entries[0].value);
writeSetting(PITCHB_MAX_ADDR, *e.entries[1].value);
}
const AdjustMenuEntry pitchBendAdjustMenu = {
"PITCH BEND",
{
{ &pitchbThrVal, pitchbLoLimit, pitchbHiLimit },
{ &pitchbMaxVal, pitchbLoLimit, pitchbHiLimit }
},
pbSave
};
static void extracSave(const AdjustMenuEntry& e) {
writeSetting(EXTRAC_THR_ADDR, *e.entries[0].value);
writeSetting(EXTRAC_MAX_ADDR, *e.entries[1].value);
}
const AdjustMenuEntry extraSensorAdjustMenu = {
"EXTRA CONTROLLER",
{
{ &extracThrVal, extracLoLimit, extracHiLimit },
{ &extracMaxVal, extracLoLimit, extracHiLimit }
},
extracSave
};
static void ctouchThrSave(const AdjustMenuEntry& e) {
writeSetting(CTOUCH_THR_ADDR, *e.entries[0].value);
}
const AdjustMenuEntry ctouchAdjustMenu = {
"TOUCH SENSE",
{
{ &ctouchThrVal, ctouchLoLimit, ctouchHiLimit },
{ nullptr, 0, 0 }
},
ctouchThrSave
};
const AdjustMenuEntry* adjustMenuEntries[] = {
&breathAdjustMenu,
&portamentoAdjustMenu,
&pitchBendAdjustMenu,
&extraSensorAdjustMenu,
&ctouchAdjustMenu,
};
static const int numAdjustEntries = ARR_LEN(adjustMenuEntries);
//***********************************************************
static void drawAdjCursor(byte color) {
display.drawTriangle(16,4,20,4,18,1,color);
display.drawTriangle(16,6,20,6,18,9,color);
}
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 drawAdjustBase(const char* title, bool all) {
display.clearDisplay();
drawAdjustFrame(17);
// sensor marker lines.
display.drawLine(25,36,25,40,WHITE);
display.drawLine(120,36,120,40,WHITE);
display.setTextSize(1);
display.setCursor(25,2);
display.println(title);
display.setCursor(0,20);
display.println("THR");
display.setCursor(0,35);
display.println("SNS");
if(all) {
drawAdjustFrame(47);
display.setCursor(0,50);
display.println("MAX");
}
cursorNow = WHITE;
drawAdjCursor(WHITE);
}
static void drawLineCursor(uint16_t hPos, uint16_t vPos, int color) {
display.drawLine(hPos, vPos,hPos, vPos+6, color);
}
static bool updateAdjustLineCursor(uint32_t timeNow, uint16_t hPos, uint16_t vPos ) {
if ((timeNow - cursorBlinkTime) > cursorBlinkInterval) {
if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE;
drawLineCursor(hPos, vPos, cursorNow);
cursorBlinkTime = timeNow;
return true;
}
return false;
}
static void drawAdjustMenu(const AdjustMenuEntry *menu) {
bool haveSecondValue = menu->entries[1].value != nullptr;
drawAdjustBase( menu->title, haveSecondValue );
pos1 = map( *menu->entries[0].value, menu->entries[0].limitLow, menu->entries[0].limitHigh, 27, 119);
display.drawLine( pos1, 20, pos1, 26, WHITE );
if(haveSecondValue) {
pos2 = map( *menu->entries[1].value, menu->entries[1].limitLow, menu->entries[1].limitHigh, 27, 119);
display.drawLine( pos2, 50, pos2, 56, WHITE );
}
}
//***********************************************************
static bool updateSensorPixel(int pos, int pos2) {
bool update = pos != sensorPixelPos1 || pos2 != sensorPixelPos2;
if(update) {
display.drawFastHLine(28, 38, 119-28, BLACK); // Clear old line
display.drawPixel(pos, 38, WHITE);
if( pos2 >= 0) display.drawPixel(pos2, 38, WHITE);
sensorPixelPos1 = pos;
sensorPixelPos2 = pos2;
}
return update;
}
void plotSensorPixels(){
int redraw = 0;
if(forcePix)
sensorPixelPos1 = -1;
// This is hacky. It depends on the order of items in the adjust menu list.
if(adjustOption == 0) {
int pos = map(constrain(pressureSensor, breathLoLimit, breathHiLimit), breathLoLimit, breathHiLimit, 28, 118);
redraw = updateSensorPixel(pos, -1);
}
else if(adjustOption == 1) {
int pos = map(constrain(biteSensor,portamLoLimit,portamHiLimit), portamLoLimit, portamHiLimit, 28, 118);
redraw = updateSensorPixel(pos, -1);
}
else if(adjustOption == 2) {
int pos = map(constrain(pbUp, pitchbLoLimit, pitchbHiLimit), pitchbLoLimit, pitchbHiLimit, 28, 118);
int pos2 = map(constrain(pbDn, pitchbLoLimit, pitchbHiLimit), pitchbLoLimit, pitchbHiLimit, 28, 118);
redraw = updateSensorPixel(pos, pos2);
}
else if(adjustOption == 3) {
int pos = map(constrain(exSensor, extracLoLimit, extracHiLimit), extracLoLimit, extracHiLimit, 28, 118);
redraw = updateSensorPixel(pos, -1);
}
else if(adjustOption == 4) {
display.drawLine(28,38,118,38,BLACK);
for (byte i=0; i<12; i++){
int pos = map(constrain(touchSensor.filteredData(i), ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118);
display.drawPixel(pos, 38, WHITE);
}
int posRead = map(touchRead(halfPitchBendKeyPin),ttouchLoLimit,ttouchHiLimit,ctouchHiLimit,ctouchLoLimit);
int pos = map(constrain(posRead, ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118);
posRead = map(touchRead(specialKeyPin),ttouchLoLimit,ttouchHiLimit,ctouchHiLimit,ctouchLoLimit);
int pos2 = map(constrain(posRead, ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118);
updateSensorPixel(pos, pos2);
redraw = 1;
}
if (redraw){
display.display();
}
forcePix = 0;
}
//***********************************************************
static bool drawAdjustBar(uint16_t buttons, int row, const AdjustValue* entry, uint16_t *pos) {
bool updated = false;
uint16_t step = (entry->limitHigh-entry->limitLow)/92;
int val = *entry->value;
switch(buttons) {
case BTN_UP:
val += step;
updated = true;
break;
case BTN_DOWN:
val -= step;
updated = true;
break;
}
if(updated) {
*entry->value = constrain(val, entry->limitLow, entry->limitHigh);
auto p = *pos;
display.drawLine(p, row, p, row+6, BLACK);
*pos = p = map(*entry->value, entry->limitLow, entry->limitHigh, 27, 119);
display.drawLine(p, row, p, row+6, WHITE);
cursorNow = BLACK;
}
return updated;
}
static bool updateAdjustCursor(uint32_t timeNow) {
if ((timeNow - cursorBlinkTime) > cursorBlinkInterval) {
if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE;
drawAdjCursor(cursorNow);
cursorBlinkTime = timeNow;
return true;
}
return false;
}
static bool handleInput(const AdjustMenuEntry *currentMenu, uint32_t timeNow, uint8_t buttons, uint16_t *xpos, int ypos, int index) {
if (buttons) {
drawAdjustBar( buttons, ypos, &currentMenu->entries[index], xpos );
int last = adjustCurrent;
if(buttons == BTN_ENTER) adjustCurrent += 1;
else if( buttons == BTN_MENU) adjustCurrent = 0;
if(last != adjustCurrent) drawLineCursor(*xpos, ypos, WHITE);
return true;
} else {
return updateAdjustLineCursor(timeNow, *xpos, ypos);
}
}
int updateAdjustMenu(uint32_t timeNow, KeyState &input, bool firstRun, bool drawSensor) {
bool redraw = false;
int result = 0;
const AdjustMenuEntry *currentMenu = adjustMenuEntries[adjustOption];
uint8_t buttons = input.changed ? input.current : 0;
if(firstRun || refreshScreen) {
adjustCurrent = 0;
refreshScreen = false;
drawAdjustMenu(currentMenu);
// the sensor pixel stuff should be refactored (to work again)
forcePix = 1;
sensorPixelPos1 = -1; // Force draw of sensor pixels
}
if(adjustCurrent == 0) {
// Currently selecting what option to modify
redraw |= updateAdjustCursor(timeNow);
bool save = false;
if( buttons == BTN_DOWN ) {
adjustOption += 1;
refreshScreen = 1;
save = true;
}
else if ( buttons == BTN_UP ) {
adjustOption -= 1;
refreshScreen = 1;
save = true;
}
else if ( buttons == BTN_ENTER ) {
adjustCurrent = 1;
}
else if (buttons == BTN_MENU ) {
adjustCurrent = 0;
result = -1;
save = true;
}
if(save && currentMenu->saveFunc)
currentMenu->saveFunc(*currentMenu);
} else if( adjustCurrent == 1) {
handleInput(currentMenu, timeNow, buttons, &pos1, 20, 0);
} else {
handleInput(currentMenu, timeNow, buttons, &pos2, 50, 1);
}
// Keep adjustCurrent in range
if( (adjustCurrent > 2) || ((adjustCurrent == 2) && (currentMenu->entries[1].value == nullptr)))
adjustCurrent = 0;
// Keep adjust option in range.
if(adjustOption < 0)
adjustOption = numAdjustEntries-1;
else if (adjustOption >= numAdjustEntries)
adjustOption = 0;
if(drawSensor) {
plotSensorPixels();
}
if(result >= 0)
result = redraw;
return result;
}

View file

@ -21,4 +21,19 @@
#define CC_INTERVAL 2
// MAybe move these to config.h (as defines?)
#define breathLoLimit 0
#define breathHiLimit 4095
#define portamLoLimit 700
#define portamHiLimit 4700
#define pitchbLoLimit 500
#define pitchbHiLimit 4000
#define extracLoLimit 500
#define extracHiLimit 4000
#define ctouchLoLimit 50
#define ctouchHiLimit 350
#define ttouchLoLimit 50
#define ttouchHiLimit 1900
#endif

View file

@ -37,28 +37,10 @@ extern unsigned short vibDirection; //direction of first vibrato wave UPWD or DN
extern unsigned short fastPatch[7];
extern byte rotatorOn;
extern byte currentRotation;
extern int rotations[4];
extern int parallel; // semitones
extern int breathLoLimit;
extern int breathHiLimit;
extern int portamLoLimit;
extern int portamHiLimit;
extern int pitchbLoLimit;
extern int pitchbHiLimit;
extern int extracLoLimit;
extern int extracHiLimit;
extern int ctouchLoLimit;
extern int ctouchHiLimit;
extern int ttouchLoLimit;
extern int ttouchHiLimit;
extern uint16_t rotations[4];
extern uint16_t parallel; // semitones
extern int touch_Thr;
extern int breathStep;
extern int portamStep;
extern int pitchbStep;
extern int extracStep;
extern int ctouchStep;
extern unsigned long cursorBlinkTime; // the last time the cursor was toggled

File diff suppressed because it is too large Load diff

View file

@ -2,38 +2,38 @@
#define __MENU_H
#include "Wiring.h"
#include "numenu.h"
#define MENU_ROW_HEIGHT 9
#define MENU_HEADER_OFFSET 3
#define MENU_HEADER_OFFSET 12
#define MENU_NUM_ROWS 6
//display states
#define DISPLAYOFF_IDL 0
#define MAIN_MENU 1
#define PATCH_VIEW 2
#define BREATH_ADJ_IDL 10
#define BREATH_ADJ_THR 11
#define BREATH_ADJ_MAX 12
#define PORTAM_ADJ_IDL 20
#define PORTAM_ADJ_THR 21
#define PORTAM_ADJ_MAX 22
#define PITCHB_ADJ_IDL 30
#define PITCHB_ADJ_THR 31
#define PITCHB_ADJ_MAX 32
#define EXTRAC_ADJ_IDL 40
#define EXTRAC_ADJ_THR 41
#define EXTRAC_ADJ_MAX 42
#define VIBRAT_ADJ_IDL 50
#define VIBRAT_ADJ_THR 51
#define VIBRAT_ADJ_DPT 52
#define CTOUCH_ADJ_IDL 60
#define CTOUCH_ADJ_THR 61
#define SETUP_BR_MENU 80
#define SETUP_CT_MENU 90
#define ROTATOR_MENU 100
#define VIBRATO_MENU 110
#define ADJUST_MENU 3
#define SETUP_BR_MENU 4
#define SETUP_CT_MENU 5
#define ROTATOR_MENU 6
#define VIBRATO_MENU 7
extern byte subVibSquelch;
#define ARR_LEN(a) (sizeof (a) / sizeof (a[0]))
#define BTN_DOWN 1
#define BTN_ENTER 2
#define BTN_UP 4
#define BTN_MENU 8
extern const unsigned long debounceDelay; // the debounce time; increase if the output flickers
extern const unsigned long buttonRepeatInterval;
extern const unsigned long buttonRepeatDelay;
extern const unsigned long cursorBlinkInterval; // the cursor blink toggle interval time
extern const unsigned long patchViewTimeUp; // ms until patch view shuts off
extern const unsigned long menuTimeUp; // menu shuts off after one minute of button inactivity
extern byte subVibSquelch; // TODO: This is broken <- subVibSquelch is never set, we need another way to expose what menu is open.
void initDisplay();
void showVersion();
@ -42,4 +42,7 @@ void drawSensorPixels();
unsigned short readSetting(byte address);
void writeSetting(byte address, unsigned short value);
int updateAdjustMenu(uint32_t timeNow, KeyState &input, bool firstRun, bool drawSensor);
bool adjustPageUpdate(KeyState &input, uint32_t timeNow);
#endif

37
NuEVI/numenu.cpp Normal file
View file

@ -0,0 +1,37 @@
/*
Notes on the original menu implementation
# Menus
## Main Menu
### Transpose
Sub menu with values -12 to 12.
### Octave
Sub menu with values -3 to +3
### MIDI CH
Sub menu with values 0 to 16. Should be 1 to 16, but there might be a bug
either in my simulation code, my changes to the menu or a bug in the original
menu.
### Adjust
This is a special option where the Adjust menu mode is entered. It take over
the display and draw horizontal indicators for threshold and such. More on
this in a later section.
### SETUP BR
Breath setup. Opens a new menu with breath specific stuff.
### SETUP CTL
Controls setup. Opens a new menu.
*/

90
NuEVI/numenu.h Normal file
View file

@ -0,0 +1,90 @@
#ifndef __NUMENU_H
#define __NUMENU_H
#include <stdint.h>
//***********************************************************
struct KeyState {
uint8_t current;
uint8_t changed;
};
//***********************************************************
enum MenuType {
ESub,
EStateChange,
};
enum MenuEntryFlags {
ENone = 0,
EMenuEntryWrap = (1u<<0),
EMenuEntryCustom = (1u<<1),
EMenuEntryEnterHandler = (1u<<2),
};
enum MenuPageFlags {
EMenuPageCustom = (1u<<0),
EMenuPageRoot = (1u<<1),
EMenuCustomTitle = (1u << 2),
};
struct MenuEntry {
enum MenuType type;
const char* title;
};
struct MenuEntrySub;
typedef const MenuEntrySub& SubMenuRef;
struct MenuEntrySub {
enum MenuType type;
const char* title;
const char* subTitle;
uint16_t* valuePtr;
uint16_t min;
uint16_t max;
uint16_t flags;
void (*getSubTextFunc)(SubMenuRef, char*textBuffer, const char**label);
void (*applyFunc)(SubMenuRef);
bool (*onEnterFunc)(void);
};
struct MenuEntryStateCh {
enum MenuType type;
const char* title;
uint8_t state;
};
struct MenuPage {
const char* title;
uint16_t flags;
uint8_t cursor;
uint8_t parentPage;
uint8_t numEntries;
const MenuEntry** entries;
};
struct MenuPageCustom {
const char* title;
uint16_t flags;
bool (*menuUpdateFunc)(KeyState &input, uint32_t timeNow);
};
//***********************************************************
struct AdjustValue {
uint16_t *value;
uint16_t limitLow;
uint16_t limitHigh;
};
struct AdjustMenuEntry {
const char* title;
AdjustValue entries[2];
void (*saveFunc)(const AdjustMenuEntry&);
};
#endif

View file

@ -27,6 +27,7 @@ INCDIRS += $(addprefix -I,$(INCS))
TARGET=nuevisim
CXXFILES= ../NuEVI/menu.cpp \
../NuEVI/adjustmenu.cpp \
src/nuevisim.cpp \
src/simeeprom.cpp \
src/Print.cpp \