Moved over the rotation menu to new system
Had to change how the values where stored in RAM from singed to unsigned to be able to use the generic menu features. Also had to add the MenuEntrySub as a parameter to the menu callback functions to be able fo display and store the correct values. Did some major cleanup now that the special case of rotator menu is gone together with all uses of the old version of the sub menu struct.
This commit is contained in:
parent
6c721e8b65
commit
bddbffd51d
4 changed files with 189 additions and 287 deletions
|
@ -81,8 +81,8 @@ 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
|
||||
|
||||
|
@ -335,11 +335,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);
|
||||
|
@ -639,10 +639,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
|
||||
|
@ -676,8 +676,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
|
||||
|
@ -725,8 +725,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
|
||||
|
@ -750,10 +750,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) {
|
||||
|
|
|
@ -37,8 +37,8 @@ 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 uint16_t rotations[4];
|
||||
extern uint16_t parallel; // semitones
|
||||
|
||||
extern int touch_Thr;
|
||||
|
||||
|
|
401
NuEVI/menu.cpp
401
NuEVI/menu.cpp
|
@ -37,7 +37,6 @@ static byte activeSub[CursorIdx::NUM_CURSORS];
|
|||
|
||||
byte cursorNow;
|
||||
|
||||
static byte forceRedraw = 0;
|
||||
static byte FPD = 0;
|
||||
|
||||
|
||||
|
@ -216,20 +215,15 @@ static void plotSubOption(const char* label, int color) {
|
|||
|
||||
static bool drawSubMenu(const MenuPage &page, int color) {
|
||||
int index = cursors[page.cursor];
|
||||
// TODO: Handle MenuEntrySubRotator case
|
||||
// TODO: Null check subMenuFunc
|
||||
const MenuEntry* subEntry = page.entries[index];
|
||||
switch(subEntry->type) {
|
||||
case MenuType::ESub:
|
||||
((const MenuEntrySub*)subEntry)->subMenuFunc(color);
|
||||
break;
|
||||
|
||||
case MenuType::ESubNew:
|
||||
{
|
||||
char buffer[12];
|
||||
const char* labelPtr = nullptr;
|
||||
const MenuEntrySubNew* sub = (const MenuEntrySubNew*)subEntry;
|
||||
sub->getSubTextFunc(buffer, &labelPtr);
|
||||
const MenuEntrySub* sub = (const MenuEntrySub*)subEntry;
|
||||
sub->getSubTextFunc(*sub, buffer, &labelPtr);
|
||||
|
||||
// If ECustom flag is set, we assume that the getSubTextFunc
|
||||
// rendered by it self.
|
||||
|
@ -354,7 +348,6 @@ static void drawPatchView(){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void drawSubBox(const char* label)
|
||||
{
|
||||
display.fillRect(63,11,64,52,BLACK);
|
||||
|
@ -372,20 +365,6 @@ void drawMenuCursor(byte itemNo, byte color){
|
|||
display.drawTriangle(57, ymid,61, ymid+2,61, ymid-2, color);
|
||||
}
|
||||
|
||||
static void plotRotator(int color,int value){
|
||||
char buff[12];
|
||||
numToString(value, buff, true);
|
||||
plotSubOption(buff, color);
|
||||
}
|
||||
|
||||
static void plotPriority(int color){
|
||||
if (priority){
|
||||
plotSubOption("ROT", color);
|
||||
} else {
|
||||
plotSubOption("MEL", color);
|
||||
}
|
||||
}
|
||||
|
||||
static void plotMIDI(int color) {
|
||||
char buff[7];
|
||||
numToString(MIDIchannel, buff);
|
||||
|
@ -400,13 +379,6 @@ static void plotMIDI(int color) {
|
|||
display.print("S");
|
||||
}
|
||||
|
||||
static void drawSubRotator(int __unused color){
|
||||
// HACKY HACK ROTATOR MENU
|
||||
// drawSubBox("SEMITONES");
|
||||
//plotRotator(WHITE,value);
|
||||
forceRedraw = 1;
|
||||
}
|
||||
|
||||
//***********************************************************
|
||||
|
||||
// TODO: Move these to a settings.cpp maybe?
|
||||
|
@ -455,30 +427,30 @@ static void clearFPS(int trills) {
|
|||
|
||||
//***********************************************************
|
||||
// Main menu
|
||||
const MenuEntrySubNew transposeMenu = {
|
||||
MenuType::ESubNew, "TRANSPOSE", "TRANSPOSE", &transpose, 0, 24, MenuEntryFlags::ENone,
|
||||
[](char* out, const char** __unused unit) {
|
||||
const MenuEntrySub transposeMenu = {
|
||||
MenuType::ESub, "TRANSPOSE", "TRANSPOSE", &transpose, 0, 24, MenuEntryFlags::ENone,
|
||||
[](SubMenuRef __unused, char* out, const char** __unused unit) {
|
||||
numToString(transpose - 12, out, true);
|
||||
},
|
||||
[]() { writeSetting(TRANSP_ADDR,transpose); }
|
||||
[](const MenuEntrySub &sub) { writeSetting(TRANSP_ADDR,*sub.valuePtr); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew octaveMenu = {
|
||||
MenuType::ESubNew, "OCTAVE", "OCTAVE", &octave, 0, 6, MenuEntryFlags::ENone,
|
||||
[](char* out, const char** __unused unit) {
|
||||
const MenuEntrySub octaveMenu = {
|
||||
MenuType::ESub, "OCTAVE", "OCTAVE", &octave, 0, 6, MenuEntryFlags::ENone,
|
||||
[](SubMenuRef __unused, char* out, const char** __unused unit) {
|
||||
numToString(octave-3, out, true);
|
||||
},
|
||||
[]() { writeSetting(OCTAVE_ADDR,octave); }
|
||||
[](SubMenuRef __unused) { writeSetting(OCTAVE_ADDR,octave); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew midiMenu = {
|
||||
MenuType::ESubNew, "MIDI CH", "MIDI CHNL", &MIDIchannel, 1, 16, MenuEntryFlags::ECustom | MenuEntryFlags::EEnterHandler,
|
||||
[](char* __unused out, const char** __unused unit) {
|
||||
const MenuEntrySub midiMenu = {
|
||||
MenuType::ESub, "MIDI CH", "MIDI CHNL", &MIDIchannel, 1, 16, MenuEntryFlags::ECustom | MenuEntryFlags::EEnterHandler,
|
||||
[](SubMenuRef __unused, char* __unused out, const char** __unused unit) {
|
||||
plotMIDI(WHITE);
|
||||
},
|
||||
[]() { writeSetting(MIDI_ADDR, MIDIchannel); },
|
||||
[](const MenuEntrySub & __unused sub) { writeSetting(MIDI_ADDR, MIDIchannel); },
|
||||
[]() -> bool { // On enter handler
|
||||
readSwitches();
|
||||
if (pinkyKey){
|
||||
|
@ -513,13 +485,80 @@ const MenuPage mainMenuPage = {
|
|||
ARR_LEN(mainMenuEntries), mainMenuEntries
|
||||
};
|
||||
|
||||
|
||||
//***********************************************************
|
||||
// Rotator menu
|
||||
const MenuEntrySub rotatorParaMenu = { MenuType::ESub, "PARALLEL", "SEMITONES", &subParallel, drawSubRotator };
|
||||
const MenuEntrySubRotator rotator1Menu = { MenuType::ESubRotator, "ROTATE 1", "SEMITONES", 1, &subRotator, drawSubRotator };
|
||||
const MenuEntrySubRotator rotator2Menu = { MenuType::ESubRotator, "ROTATE 2", "SEMITONES", 2, &subRotator, drawSubRotator };
|
||||
const MenuEntrySubRotator rotator3Menu = { MenuType::ESubRotator, "ROTATE 3", "SEMITONES", 3, &subRotator, drawSubRotator };
|
||||
const MenuEntrySubRotator rotator4Menu = { MenuType::ESubRotator, "ROTATE 4", "SEMITONES", 4, &subRotator, drawSubRotator };
|
||||
const MenuEntrySub rotatorPrioMenu = { MenuType::ESub, "PRIORITY", "MONO PRIO", &subPriority, plotPriority };
|
||||
|
||||
static void rotatorSave(const MenuEntrySub& __unused sub) {
|
||||
int16_t stored;
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
stored = readSetting(ROTN1_ADDR+2*i);
|
||||
if(stored != rotations[i])
|
||||
writeSetting(ROTN1_ADDR+2*i,(rotations[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static void rotatorOptionGet(SubMenuRef sub, char *out, const char** __unused unit) {
|
||||
numToString((*sub.valuePtr) - 24, out, true);
|
||||
}
|
||||
|
||||
static void parallelOptionGet(SubMenuRef __unused, char *out, const char** __unused unit) {
|
||||
numToString(parallel-24, out, true);
|
||||
}
|
||||
|
||||
static void parallelSave(SubMenuRef __unused) {
|
||||
writeSetting(PARAL_ADDR, parallel);
|
||||
}
|
||||
|
||||
const MenuEntrySub rotatorParaMenu = {
|
||||
MenuType::ESub, "PARALLEL", "SEMITONES", ¶llel, 0, 48, MenuEntryFlags::ENone,
|
||||
parallelOptionGet,
|
||||
parallelSave,
|
||||
nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySub rotator1Menu = {
|
||||
MenuType::ESub, "ROTATE 1", "SEMITONES", &rotations[0], 0, 48, MenuEntryFlags::ENone,
|
||||
rotatorOptionGet,
|
||||
rotatorSave,
|
||||
nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySub rotator2Menu = {
|
||||
MenuType::ESub, "ROTATE 2", "SEMITONES", &rotations[1], 0, 48, MenuEntryFlags::ENone,
|
||||
rotatorOptionGet,
|
||||
rotatorSave,
|
||||
nullptr
|
||||
};
|
||||
const MenuEntrySub rotator3Menu = {
|
||||
MenuType::ESub, "ROTATE 3", "SEMITONES", &rotations[2], 0, 48, MenuEntryFlags::ENone,
|
||||
rotatorOptionGet,
|
||||
rotatorSave,
|
||||
nullptr
|
||||
};
|
||||
const MenuEntrySub rotator4Menu = {
|
||||
MenuType::ESub, "ROTATE 4", "SEMITONES", &rotations[3], 0, 48, MenuEntryFlags::ENone,
|
||||
rotatorOptionGet,
|
||||
rotatorSave,
|
||||
nullptr
|
||||
};
|
||||
|
||||
static void rotatorPrioOptionGet(SubMenuRef __unused, char* out, const char** __unused) {
|
||||
if (priority) strncpy(out, "ROT", 4);
|
||||
else strncpy(out, "MEL", 4);
|
||||
}
|
||||
|
||||
static void rotatorPrioSave(SubMenuRef __unused) {
|
||||
writeSetting(PRIO_ADDR,priority);
|
||||
}
|
||||
|
||||
const MenuEntrySub rotatorPrioMenu = {
|
||||
MenuType::ESub, "PRIORITY", "MONO PRIO", &priority, 0,1, MenuEntryFlags::EWrap,
|
||||
rotatorPrioOptionGet,
|
||||
rotatorPrioSave,
|
||||
nullptr,
|
||||
};
|
||||
|
||||
|
||||
const MenuEntry* rotatorMenuEntries[] = {
|
||||
(MenuEntry*)&rotatorParaMenu,
|
||||
|
@ -539,14 +578,14 @@ const MenuPage rotatorMenuPage = {
|
|||
|
||||
//***********************************************************
|
||||
// Breath menu
|
||||
const MenuEntrySubNew breathCCMenu = {
|
||||
MenuType::ESubNew, "BREATH CC", "BREATH CC", &breathCC, 0, 10, MenuEntryFlags::EWrap,
|
||||
[](char* out, const char** __unused unit) {
|
||||
const MenuEntrySub breathCCMenu = {
|
||||
MenuType::ESub, "BREATH CC", "BREATH CC", &breathCC, 0, 10, MenuEntryFlags::EWrap,
|
||||
[](SubMenuRef __unused, char* out, const char** __unused unit) {
|
||||
const char* breathCCMenuLabels[] = { "OFF", "MW", "BR", "VL", "EX", "MW+",
|
||||
"BR+", "VL+", "EX+", "CF", "20" };
|
||||
strncpy(out, breathCCMenuLabels[breathCC], 4);
|
||||
},
|
||||
[](){
|
||||
[](const MenuEntrySub & __unused sub){
|
||||
if (readSetting(BREATH_CC_ADDR) != breathCC) {
|
||||
writeSetting(BREATH_CC_ADDR,breathCC);
|
||||
midiReset();
|
||||
|
@ -555,11 +594,11 @@ const MenuEntrySubNew breathCCMenu = {
|
|||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew breathATMenu = {
|
||||
MenuType::ESubNew, "BREATH AT", "BREATH AT", &breathAT, 0, 1, MenuEntryFlags::EWrap,
|
||||
[](char* out, const char ** __unused unit) {
|
||||
const MenuEntrySub breathATMenu = {
|
||||
MenuType::ESub, "BREATH AT", "BREATH AT", &breathAT, 0, 1, MenuEntryFlags::EWrap,
|
||||
[](SubMenuRef __unused, char* out, const char ** __unused unit) {
|
||||
strncpy(out, breathAT?"ON":"OFF", 4);
|
||||
}, []() {
|
||||
}, [](const MenuEntrySub & __unused sub) {
|
||||
if (readSetting(BREATH_AT_ADDR) != breathAT) {
|
||||
writeSetting(BREATH_AT_ADDR, breathAT);
|
||||
midiReset();
|
||||
|
@ -568,46 +607,46 @@ const MenuEntrySubNew breathATMenu = {
|
|||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew velocityMenu = {
|
||||
MenuType::ESubNew, "VELOCITY", "VELOCITY", &velocity, 0, 127, MenuEntryFlags::EWrap,
|
||||
[](char* out, const char** __unused unit) {
|
||||
const MenuEntrySub velocityMenu = {
|
||||
MenuType::ESub, "VELOCITY", "VELOCITY", &velocity, 0, 127, MenuEntryFlags::EWrap,
|
||||
[](SubMenuRef __unused, char* out, const char** __unused unit) {
|
||||
if(velocity) numToString(velocity, out);
|
||||
else strncpy(out, "DYN", 4);
|
||||
},
|
||||
[]() { writeSetting(VELOCITY_ADDR,velocity); }
|
||||
[](const MenuEntrySub & __unused sub) { writeSetting(VELOCITY_ADDR,velocity); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew curveMenu = {
|
||||
MenuType::ESubNew, "CURVE", "CURVE", &curve, 0, 12, MenuEntryFlags::EWrap,
|
||||
[](char* out, const char** __unused unit) {
|
||||
const MenuEntrySub curveMenu = {
|
||||
MenuType::ESub, "CURVE", "CURVE", &curve, 0, 12, MenuEntryFlags::EWrap,
|
||||
[](SubMenuRef __unused, char* out, const char** __unused unit) {
|
||||
const char* curveMenuLabels[] = {"-4", "-3", "-2", "-1", "LIN", "+1", "+2",
|
||||
"+3", "+4", "S1", "S2", "Z1", "Z2" };
|
||||
strncpy(out, curveMenuLabels[curve], 4);
|
||||
},
|
||||
[](){ writeSetting(BREATHCURVE_ADDR,curve); }
|
||||
[](const MenuEntrySub & __unused sub){ writeSetting(BREATHCURVE_ADDR,curve); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew velSmpDlMenu = {
|
||||
MenuType::ESubNew, "VEL DELAY", "VEL DELAY", &velSmpDl, 0, 30, MenuEntryFlags::EWrap,
|
||||
[](char *out, const char** label) {
|
||||
const MenuEntrySub velSmpDlMenu = {
|
||||
MenuType::ESub, "VEL DELAY", "VEL DELAY", &velSmpDl, 0, 30, MenuEntryFlags::EWrap,
|
||||
[](SubMenuRef __unused, char *out, const char** label) {
|
||||
if (velSmpDl) {
|
||||
numToString(velSmpDl, out);
|
||||
*label = "ms";
|
||||
} else strncpy(out, "OFF", 4);
|
||||
},
|
||||
[]() { writeSetting(VEL_SMP_DL_ADDR,velSmpDl); }
|
||||
[](const MenuEntrySub & __unused sub) { writeSetting(VEL_SMP_DL_ADDR,velSmpDl); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew velBiasMenu = {
|
||||
MenuType::ESubNew, "VEL BIAS", "VEL BIAS", &velBias, 0, 9, MenuEntryFlags::EWrap,
|
||||
[](char* out, const char** __unused unit) {
|
||||
const MenuEntrySub velBiasMenu = {
|
||||
MenuType::ESub, "VEL BIAS", "VEL BIAS", &velBias, 0, 9, MenuEntryFlags::EWrap,
|
||||
[](SubMenuRef __unused, char* out, const char** __unused unit) {
|
||||
if (velBias) numToString(velBias, out);
|
||||
else strncpy(out, "OFF", 4);
|
||||
},
|
||||
[](){ writeSetting(VEL_BIAS_ADDR,velBias); }
|
||||
[](SubMenuRef __unused){ writeSetting(VEL_BIAS_ADDR,velBias); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
|
@ -629,63 +668,63 @@ const MenuPage breathMenuPage = {
|
|||
|
||||
//***********************************************************
|
||||
// Control menu
|
||||
const MenuEntrySubNew portMenu = {
|
||||
MenuType::ESubNew, "PORT/GLD", "PORT/GLD", &portamento, 0, 2, MenuEntryFlags::EWrap,
|
||||
[](char* out, const char ** __unused unit) {
|
||||
const MenuEntrySub portMenu = {
|
||||
MenuType::ESub, "PORT/GLD", "PORT/GLD", &portamento, 0, 2, MenuEntryFlags::EWrap,
|
||||
[](SubMenuRef __unused,char* out, const char ** __unused unit) {
|
||||
const char* labs[] = { "OFF", "ON", "SW" };
|
||||
strncpy(out, labs[portamento], 4);
|
||||
},
|
||||
[]() { writeSetting(PORTAM_ADDR,portamento); }
|
||||
[](SubMenuRef __unused sub) { writeSetting(PORTAM_ADDR,portamento); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew pitchBendMenu = {
|
||||
MenuType::ESubNew, "PITCHBEND", "PITCHBEND", &PBdepth, 0, 12, MenuEntryFlags::ENone,
|
||||
[](char* out, const char** __unused unit) {
|
||||
const MenuEntrySub pitchBendMenu = {
|
||||
MenuType::ESub, "PITCHBEND", "PITCHBEND", &PBdepth, 0, 12, MenuEntryFlags::ENone,
|
||||
[](SubMenuRef __unused, char* out, const char** __unused unit) {
|
||||
if(PBdepth) {
|
||||
memcpy(out, "1/", 2);
|
||||
numToString(PBdepth, &out[2]);
|
||||
}
|
||||
else strncpy(out, "OFF", 4);
|
||||
},
|
||||
[](){ writeSetting(PB_ADDR,PBdepth); }
|
||||
[](SubMenuRef __unused){ writeSetting(PB_ADDR,PBdepth); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew extraMenu = {
|
||||
MenuType::ESubNew, "EXTRA CTR", "EXTRA CTR", &extraCT, 0,4, MenuEntryFlags::EWrap,
|
||||
[](char* out, const char** __unused unit) {
|
||||
const MenuEntrySub extraMenu = {
|
||||
MenuType::ESub, "EXTRA CTR", "EXTRA CTR", &extraCT, 0,4, MenuEntryFlags::EWrap,
|
||||
[](SubMenuRef __unused,char* out, const char** __unused unit) {
|
||||
const char* extraMenuLabels[] = { "OFF", "MW", "FP", "CF", "SP" };
|
||||
strncpy(out, extraMenuLabels[extraCT], 12);
|
||||
},
|
||||
[]() { writeSetting(EXTRA_ADDR,extraCT); }
|
||||
[](const MenuEntrySub & __unused sub) { writeSetting(EXTRA_ADDR,extraCT); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntryStateCh vibratoSubMenu = { MenuType::EStateChange, "VIBRATO", VIBRATO_MENU };
|
||||
|
||||
const MenuEntrySubNew deglitchMenu = {
|
||||
MenuType::ESubNew, "DEGLITCH", "DEGLITCH", °litch, 0, 70, MenuEntryFlags::ENone,
|
||||
[](char* textBuffer, const char** label) {
|
||||
const MenuEntrySub deglitchMenu = {
|
||||
MenuType::ESub, "DEGLITCH", "DEGLITCH", °litch, 0, 70, MenuEntryFlags::ENone,
|
||||
[](SubMenuRef __unused,char* textBuffer, const char** label) {
|
||||
if(deglitch) {
|
||||
numToString(deglitch, textBuffer);
|
||||
*label = "ms";
|
||||
} else
|
||||
strncpy(textBuffer, "OFF", 4);
|
||||
},
|
||||
[]() { writeSetting(DEGLITCH_ADDR,deglitch); }
|
||||
[](const MenuEntrySub & __unused sub) { writeSetting(DEGLITCH_ADDR,deglitch); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew pinkyMenu = {
|
||||
MenuType::ESubNew, "PINKY KEY", "PINKY KEY", &pinkySetting, 0, 24, MenuEntryFlags::ENone,
|
||||
[](char* textBuffer, const char** __unused unit) {
|
||||
const MenuEntrySub pinkyMenu = {
|
||||
MenuType::ESub, "PINKY KEY", "PINKY KEY", &pinkySetting, 0, 24, MenuEntryFlags::ENone,
|
||||
[](SubMenuRef __unused,char* textBuffer, const char** __unused unit) {
|
||||
if (pinkySetting == PBD)
|
||||
strncpy(textBuffer, "PBD", 4);
|
||||
else
|
||||
numToString(pinkySetting-12, textBuffer, true);
|
||||
},
|
||||
[]() { writeSetting(PINKY_KEY_ADDR,pinkySetting); }
|
||||
[](const MenuEntrySub & __unused sub) { writeSetting(PINKY_KEY_ADDR,pinkySetting); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
|
@ -709,60 +748,60 @@ const MenuPage controlMenuPage = {
|
|||
//***********************************************************
|
||||
// Vibrato menu
|
||||
|
||||
static void vibGetStr(char* textBuffer, const char** __unused unit) {
|
||||
static void vibGetStr(SubMenuRef __unused, char* textBuffer, const char** __unused unit) {
|
||||
if(vibrato)
|
||||
numToString(vibrato, textBuffer);
|
||||
else
|
||||
strncpy(textBuffer, "OFF", 4);
|
||||
}
|
||||
|
||||
static void vibStore() {
|
||||
static void vibStore(const MenuEntrySub & __unused sub) {
|
||||
writeSetting(VIBRATO_ADDR,vibrato);
|
||||
}
|
||||
|
||||
const MenuEntrySubNew vibDepthMenu = {
|
||||
MenuType::ESubNew, "DEPTH", "LEVEL", &vibrato, 0, 9, MenuEntryFlags::ENone,
|
||||
const MenuEntrySub vibDepthMenu = {
|
||||
MenuType::ESub, "DEPTH", "LEVEL", &vibrato, 0, 9, MenuEntryFlags::ENone,
|
||||
vibGetStr,
|
||||
vibStore,
|
||||
nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew vibSenseMenu = {
|
||||
MenuType::ESubNew, "SENSE", "LEVEL", &vibSens, 1, 12, MenuEntryFlags::ENone,
|
||||
[](char* textBuffer, const char** __unused unit) {
|
||||
const MenuEntrySub vibSenseMenu = {
|
||||
MenuType::ESub, "SENSE", "LEVEL", &vibSens, 1, 12, MenuEntryFlags::ENone,
|
||||
[](SubMenuRef __unused,char* textBuffer, const char** __unused unit) {
|
||||
numToString(vibSens, textBuffer);
|
||||
},
|
||||
[]() { writeSetting(VIB_SENS_ADDR,vibSens); }
|
||||
[](const MenuEntrySub & __unused sub) { writeSetting(VIB_SENS_ADDR,vibSens); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew vibRetnMenu = {
|
||||
MenuType::ESubNew, "RETURN", "LEVEL", &vibRetn, 0, 4, MenuEntryFlags::ENone,
|
||||
[](char* textBuffer, const char** __unused unit) {
|
||||
const MenuEntrySub vibRetnMenu = {
|
||||
MenuType::ESub, "RETURN", "LEVEL", &vibRetn, 0, 4, MenuEntryFlags::ENone,
|
||||
[](SubMenuRef __unused, char* textBuffer, const char** __unused unit) {
|
||||
numToString(vibRetn, textBuffer);
|
||||
},
|
||||
[]() { writeSetting(VIB_RETN_ADDR,vibRetn); }
|
||||
[](const MenuEntrySub & __unused sub) { writeSetting(VIB_RETN_ADDR,vibRetn); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew vibSquelchMenu = {
|
||||
MenuType::ESubNew, "SQUELCH", "LEVEL", &vibSquelch, 1, 30, MenuEntryFlags::ENone,
|
||||
[](char* textBuffer, const char** __unused unit) {
|
||||
const MenuEntrySub vibSquelchMenu = {
|
||||
MenuType::ESub, "SQUELCH", "LEVEL", &vibSquelch, 1, 30, MenuEntryFlags::ENone,
|
||||
[](SubMenuRef __unused, char* textBuffer, const char** __unused unit) {
|
||||
numToString(vibSquelch, textBuffer);
|
||||
},
|
||||
[]() { writeSetting(VIB_SQUELCH_ADDR,vibSquelch); }
|
||||
[](const MenuEntrySub & __unused sub) { writeSetting(VIB_SQUELCH_ADDR,vibSquelch); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
const MenuEntrySubNew vibDirMenu = {
|
||||
MenuType::ESubNew, "DIRECTION", "DIRECTION", &vibDirection , 0, 1, MenuEntryFlags::EWrap,
|
||||
[](char* out, const char** __unused unit) {
|
||||
const MenuEntrySub vibDirMenu = {
|
||||
MenuType::ESub, "DIRECTION", "DIRECTION", &vibDirection , 0, 1, MenuEntryFlags::EWrap,
|
||||
[](SubMenuRef __unused, char* out, const char** __unused unit) {
|
||||
if (DNWD == vibDirection)
|
||||
strncpy(out, "NRM", 4);
|
||||
else
|
||||
strncpy(out, "REV", 4);
|
||||
},
|
||||
[]() { writeSetting(VIB_DIRECTION_ADDR,vibDirection); }
|
||||
[](const MenuEntrySub & __unused sub) { writeSetting(VIB_DIRECTION_ADDR,vibDirection); }
|
||||
, nullptr
|
||||
};
|
||||
|
||||
|
@ -784,25 +823,16 @@ const MenuPage vibratoMenuPage = {
|
|||
|
||||
//***********************************************************
|
||||
|
||||
static bool ExecuteMenuSelection(const MenuPage &page) //int cursorPosition, const struct MenuEntry *menuEntry)
|
||||
{
|
||||
static bool selectMenuOption(const MenuPage &page) {
|
||||
int cursorPosition = cursors[page.cursor];
|
||||
const MenuEntry* menuEntry = page.entries[cursorPosition];
|
||||
cursorBlinkTime = millis();
|
||||
|
||||
switch(menuEntry->type) {
|
||||
case MenuType::ESub:
|
||||
*((const MenuEntrySub*)menuEntry)->flag = 1;
|
||||
activeSub[page.cursor] = cursorPosition+1;
|
||||
drawMenuCursor(cursorPosition, WHITE);
|
||||
drawSubBox( ((const MenuEntrySub*)menuEntry)->subTitle);
|
||||
((const MenuEntrySub*)menuEntry)->subMenuFunc(WHITE);
|
||||
return true;
|
||||
|
||||
case MenuType::ESubNew:
|
||||
activeSub[page.cursor] = cursorPosition+1;
|
||||
drawMenuCursor(cursorPosition, WHITE);
|
||||
drawSubBox( ((const MenuEntrySubNew*)menuEntry)->subTitle);
|
||||
drawSubMenu(page, WHITE);
|
||||
return true;
|
||||
|
||||
|
@ -810,24 +840,11 @@ static bool ExecuteMenuSelection(const MenuPage &page) //int cursorPosition, con
|
|||
state = ((const MenuEntryStateCh*)menuEntry)->state;
|
||||
stateFirstRun = 1;
|
||||
break;
|
||||
|
||||
case MenuType::ESubRotator:
|
||||
activeSub[page.cursor] = cursorPosition+1;
|
||||
*((const MenuEntrySubRotator*)menuEntry)->flag = ((const MenuEntrySubRotator*)menuEntry)->flagValue;
|
||||
drawMenuCursor(cursorPosition, WHITE);
|
||||
((const MenuEntrySubRotator*)menuEntry)->subMenuFunc(WHITE);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//***********************************************************
|
||||
|
||||
static bool selectMenuOption(const MenuPage &page){
|
||||
// const MenuEntry* entry = menuEntries[cursorPosition];
|
||||
return ExecuteMenuSelection( page );
|
||||
}
|
||||
|
||||
//***********************************************************
|
||||
|
||||
|
@ -843,7 +860,7 @@ static bool updateSubMenu(const MenuPage &page, uint32_t timeNow) {
|
|||
if( current_sub < 0)
|
||||
return false;
|
||||
|
||||
auto sub = (const MenuEntrySubNew*)page.entries[current_sub];
|
||||
auto sub = (const MenuEntrySub*)page.entries[current_sub];
|
||||
uint16_t currentVal = *sub->valuePtr;
|
||||
|
||||
switch (deumButtonState){
|
||||
|
@ -871,13 +888,13 @@ static bool updateSubMenu(const MenuPage &page, uint32_t timeNow) {
|
|||
}
|
||||
} else {
|
||||
activeSub[page.cursor] = 0;
|
||||
sub->applyFunc();
|
||||
sub->applyFunc(*sub);
|
||||
}
|
||||
break;
|
||||
|
||||
case BTN_MENU:
|
||||
activeSub[page.cursor] = 0;
|
||||
sub->applyFunc();
|
||||
sub->applyFunc(*sub);
|
||||
break;
|
||||
}
|
||||
*sub->valuePtr = currentVal;
|
||||
|
@ -1009,7 +1026,6 @@ void menu() {
|
|||
unsigned long timeNow = millis();
|
||||
const MenuPage *currentPage = nullptr;
|
||||
|
||||
bool redrawSubValue = false;
|
||||
bool redraw = stateFirstRun;
|
||||
// read the state of the switches
|
||||
uint8_t deumButtons = 0x0f ^(digitalRead(dPin) | (digitalRead(ePin) << 1) | (digitalRead(uPin) << 2) | (digitalRead(mPin)<<3));
|
||||
|
@ -1225,109 +1241,21 @@ void menu() {
|
|||
redraw |= updateSubMenu(*currentPage, timeNow);
|
||||
} else {
|
||||
bool hadButtons = buttonPressedAndNotUsed;
|
||||
redraw |= updateMenuPage( *currentPage, timeNow );
|
||||
redraw |= updateMenuPage(*currentPage, timeNow);
|
||||
if (hadButtons)
|
||||
checkForPatchView(deumButtonState);
|
||||
}
|
||||
} else if (state == ROTATOR_MENU) { // ROTATOR MENU HERE <<<<<<<<<<<<<<<
|
||||
currentPage = &rotatorMenuPage;
|
||||
if (stateFirstRun) {
|
||||
drawMenu(rotatorMenuPage);
|
||||
drawMenu(*currentPage);
|
||||
stateFirstRun = 0;
|
||||
}
|
||||
currentPage = &rotatorMenuPage;
|
||||
if (subParallel){
|
||||
if (((timeNow - cursorBlinkTime) > cursorBlinkInterval) || forceRedraw) {
|
||||
if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE;
|
||||
if (forceRedraw){
|
||||
forceRedraw = 0;
|
||||
cursorNow = WHITE;
|
||||
}
|
||||
plotRotator(cursorNow,parallel);
|
||||
redraw = true;
|
||||
cursorBlinkTime = timeNow;
|
||||
}
|
||||
if (buttonPressedAndNotUsed){
|
||||
buttonPressedAndNotUsed = 0;
|
||||
switch (deumButtonState){
|
||||
case BTN_DOWN:
|
||||
if (parallel > -24)
|
||||
parallel--;
|
||||
break;
|
||||
|
||||
case BTN_UP:
|
||||
if (parallel < 24)
|
||||
parallel++;
|
||||
break;
|
||||
|
||||
case BTN_ENTER: // fallthrough
|
||||
case BTN_MENU:
|
||||
subParallel = 0;
|
||||
writeSetting(PARAL_ADDR,(parallel + 24));
|
||||
break;
|
||||
}
|
||||
clearSubValue();
|
||||
plotRotator(WHITE,parallel);
|
||||
cursorNow = BLACK;
|
||||
redraw = true;
|
||||
cursorBlinkTime = timeNow;
|
||||
}
|
||||
} else if (subRotator){
|
||||
if (((timeNow - cursorBlinkTime) > cursorBlinkInterval) || forceRedraw) {
|
||||
if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE;
|
||||
if (forceRedraw){
|
||||
forceRedraw = 0;
|
||||
cursorNow = WHITE;
|
||||
}
|
||||
plotRotator(cursorNow,rotations[subRotator-1]);
|
||||
redraw = true;
|
||||
cursorBlinkTime = timeNow;
|
||||
}
|
||||
if (buttonPressedAndNotUsed){
|
||||
buttonPressedAndNotUsed = 0;
|
||||
switch (deumButtonState){
|
||||
case BTN_DOWN:
|
||||
if (rotations[subRotator-1] > -24)
|
||||
rotations[subRotator-1]--;
|
||||
break;
|
||||
|
||||
case BTN_UP:
|
||||
if (rotations[subRotator-1] < 24)
|
||||
rotations[subRotator-1]++;
|
||||
break;
|
||||
|
||||
case BTN_ENTER: // fallthrough
|
||||
case BTN_MENU:
|
||||
writeSetting(ROTN1_ADDR+2*(subRotator-1),(rotations[subRotator-1]+24));
|
||||
subRotator = 0;
|
||||
break;
|
||||
}
|
||||
clearSubValue();
|
||||
plotRotator(WHITE,rotations[subRotator-1]);
|
||||
cursorNow = BLACK;
|
||||
redraw = true;
|
||||
cursorBlinkTime = timeNow;
|
||||
}
|
||||
} else if (subPriority){
|
||||
updateSubMenuCursor( *currentPage, timeNow );
|
||||
if (buttonPressedAndNotUsed) {
|
||||
buttonPressedAndNotUsed = 0;
|
||||
switch (deumButtonState){
|
||||
case BTN_DOWN: // fallthrough
|
||||
case BTN_UP:
|
||||
priority = !priority;
|
||||
break;
|
||||
|
||||
case BTN_ENTER: // fallthrough
|
||||
case BTN_MENU:
|
||||
subPriority = 0;
|
||||
writeSetting(PRIO_ADDR,priority);
|
||||
break;
|
||||
}
|
||||
redrawSubValue = true;
|
||||
}
|
||||
if(activeSub[currentPage->cursor]) {
|
||||
redraw |= updateSubMenu(*currentPage, timeNow);
|
||||
} else {
|
||||
bool hadButtons = buttonPressedAndNotUsed;
|
||||
redraw |= updateMenuPage(*currentPage, timeNow );
|
||||
redraw |= updateMenuPage(*currentPage, timeNow);
|
||||
if (hadButtons)
|
||||
checkForPatchView(deumButtonState);
|
||||
}
|
||||
|
@ -1359,13 +1287,6 @@ void menu() {
|
|||
redraw |= updatePage(vibratoMenuPage, timeNow);
|
||||
}
|
||||
|
||||
if(redrawSubValue && currentPage) {
|
||||
clearSubValue();
|
||||
redraw |= drawSubMenu(*currentPage, WHITE);
|
||||
cursorNow = BLACK;
|
||||
cursorBlinkTime = timeNow;
|
||||
}
|
||||
|
||||
if(redraw) {
|
||||
display.display();
|
||||
}
|
||||
|
|
|
@ -5,24 +5,9 @@
|
|||
|
||||
enum MenuType {
|
||||
ESub,
|
||||
ESubNew,
|
||||
ESubRotator,
|
||||
EStateChange,
|
||||
};
|
||||
|
||||
struct MenuEntry {
|
||||
enum MenuType type;
|
||||
const char* title;
|
||||
};
|
||||
|
||||
struct MenuEntrySub {
|
||||
enum MenuType type;
|
||||
const char* title;
|
||||
const char* subTitle;
|
||||
byte* flag;
|
||||
void (*subMenuFunc)(int color);
|
||||
};
|
||||
|
||||
enum MenuEntryFlags {
|
||||
ENone = 0,
|
||||
EWrap = (1<<0),
|
||||
|
@ -30,7 +15,15 @@ enum MenuEntryFlags {
|
|||
EEnterHandler = (1<<2),
|
||||
};
|
||||
|
||||
struct MenuEntrySubNew {
|
||||
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;
|
||||
|
@ -38,21 +31,11 @@ struct MenuEntrySubNew {
|
|||
uint16_t min;
|
||||
uint16_t max;
|
||||
uint16_t flags;
|
||||
void (*getSubTextFunc)(char*textBuffer, const char**label);
|
||||
void (*applyFunc)(void);
|
||||
void (*getSubTextFunc)(SubMenuRef, char*textBuffer, const char**label);
|
||||
void (*applyFunc)(SubMenuRef);
|
||||
bool (*onEnterFunc)(void);
|
||||
};
|
||||
|
||||
|
||||
struct MenuEntrySubRotator {
|
||||
enum MenuType type;
|
||||
const char* title;
|
||||
const char* subTitle;
|
||||
byte flagValue;
|
||||
byte* flag;
|
||||
void (*subMenuFunc)(int color);
|
||||
};
|
||||
|
||||
struct MenuEntryStateCh {
|
||||
enum MenuType type;
|
||||
const char* title;
|
||||
|
@ -70,8 +53,6 @@ struct MenuPage {
|
|||
|
||||
//***********************************************************
|
||||
|
||||
|
||||
|
||||
struct AdjustValue {
|
||||
uint16_t *value;
|
||||
uint16_t limitLow;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue