Scale type submenu

This commit is contained in:
Dejvino
2026-03-06 22:45:03 +01:00
parent f979c2c5d7
commit 7da78f5fb9
7 changed files with 51 additions and 254 deletions
+12 -112
View File
@@ -75,111 +75,12 @@ void UIManager::draw(UIState currentState, int menuSelection,
drawEditScreen("SET ROOT NOTE", "", noteNames[currentRoot % 12]);
}
break;
case UI_EDIT_SCALE_TYPE:
display.println(F("ENABLED SCALES"));
display.drawLine(0, 8, 128, 8, SSD1306_WHITE);
display.setCursor(0, 20);
if (menuSelection < 10) {
const char* typeNames[] = {"Chrom", "Major", "Minor", "H.Min", "P.Maj", "P.Min", "ChdMaj", "ChdMin", "ChdDim", "Chd7"};
display.setTextSize(2);
display.print(typeNames[menuSelection]);
display.setTextSize(1);
display.setCursor(0, 45);
bool isEnabled = (enabledScaleTypes & (1 << menuSelection));
display.print(isEnabled ? F("[ENABLED]") : F("[DISABLED]"));
} else {
display.setTextSize(2);
display.print(F("Back"));
}
display.setTextSize(1);
display.setCursor(0, 55);
display.println(F(" (Press to toggle)"));
break;
case UI_EDIT_INTENSITY:
drawNumberEditor("SET INTENSITY", trackIntensities[randomizeTrack], 1, 10);
break;
case UI_RANDOMIZE_TRACK_EDIT:
drawEditScreen("SET TRACK", "TRK: ", randomizeTrack + 1);
break;
case UI_SCALE_EDIT:
case UI_SCALE_NOTE_EDIT:
case UI_SCALE_TRANSPOSE:
display.println(F("EDIT SCALE"));
display.drawLine(0, 8, 128, 8, SSD1306_WHITE);
int totalItems = numScaleNotes + 5; // Back + Randomize + Notes + Add + Remove + Transpose
int startIdx = 0;
if (menuSelection >= 4) startIdx = menuSelection - 3;
int y = 12;
for (int i = startIdx; i < totalItems; i++) {
if (y > 54) break;
if (i == menuSelection) {
display.fillRect(0, y, 75, 9, SSD1306_WHITE);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
} else {
display.setTextColor(SSD1306_WHITE);
}
display.setCursor(2, y + 1);
if (i == 0) {
display.print(F("Back"));
} else if (i == 1) {
display.print(F("Randomize"));
} else if (i <= numScaleNotes + 1) {
int noteIdx = i - 2;
const char* noteNames[] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
display.print(noteNames[scaleNotes[noteIdx]]);
if (currentState == UI_SCALE_NOTE_EDIT && i == menuSelection) {
display.print(F(" <"));
}
} else if (i == numScaleNotes + 2) {
display.print(F("Transpose"));
if (currentState == UI_SCALE_TRANSPOSE) {
display.print(F(" < >"));
}
} else if (i == numScaleNotes + 3) {
display.print(F("Add Note"));
} else if (i == numScaleNotes + 4) {
display.print(F("Remove Note"));
}
y += 9;
}
// Piano Roll Preview
int px = 82;
int py = 20;
int wk_w = 5;
int wk_h = 20;
int bk_w = 4;
int bk_h = 12;
// White keys: C, D, E, F, G, A, B
int whiteNotes[] = {0, 2, 4, 5, 7, 9, 11};
for (int k = 0; k < 7; k++) {
bool active = false;
for (int j = 0; j < numScaleNotes; j++) {
if (scaleNotes[j] == whiteNotes[k]) { active = true; break; }
}
if (active) display.fillRect(px + k*6, py, wk_w, wk_h, SSD1306_WHITE);
else display.drawRect(px + k*6, py, wk_w, wk_h, SSD1306_WHITE);
}
// Black keys: C#, D#, F#, G#, A#
int blackNotes[] = {1, 3, 6, 8, 10};
int blackOffsets[] = {3, 9, 21, 27, 33};
for (int k = 0; k < 5; k++) {
bool active = false;
for (int j = 0; j < numScaleNotes; j++) {
if (scaleNotes[j] == blackNotes[k]) { active = true; break; }
}
int bx = px + blackOffsets[k];
display.fillRect(bx - 1, py - 1, bk_w + 2, bk_h + 2, SSD1306_BLACK);
if (active) display.fillRect(bx, py, bk_w, bk_h, SSD1306_WHITE);
else display.drawRect(bx, py, bk_w, bk_h, SSD1306_WHITE);
}
break;
}
display.display();
}
@@ -268,6 +169,18 @@ void UIManager::drawMenu(int selection, UIState currentState, int midiChannel, i
}
display.print(menuItems[i].label);
// Render checkbox for scale types
if (menuItems[i].id >= MENU_ID_SCALE_TYPE_CHROMATIC && menuItems[i].id <= MENU_ID_SCALE_TYPE_CHORD_7) {
int typeIndex = menuItems[i].id - MENU_ID_SCALE_TYPE_CHROMATIC;
bool enabled = (enabledScaleTypes & (1 << typeIndex));
int boxX = x - 10;
display.drawRect(boxX, y + 1, 7, 7, (i == selection) ? SSD1306_BLACK : SSD1306_WHITE);
if (enabled) display.fillRect(boxX + 2, y + 3, 3, 3, (i == selection) ? SSD1306_BLACK : SSD1306_WHITE);
if (typeIndex == currentScaleType) {
display.print(F(" *"));
}
}
MenuItemID id = menuItems[i].id;
@@ -279,24 +192,11 @@ void UIManager::drawMenu(int selection, UIState currentState, int midiChannel, i
if (id == MENU_ID_PLAYBACK) { display.print(F(": ")); display.print(isPlaying ? F("ON") : F("OFF")); }
else if (id == MENU_ID_MELODY) {
display.print(F(": ")); display.print(melodySeed);
} else if (id == MENU_ID_SCALE) {
display.print(F(": "));
if (numScaleNotes > 0) {
const char* noteNames[] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
for (int j = 0; j < min(numScaleNotes, 6); j++) {
display.print(noteNames[scaleNotes[j]]);
if (j < min(numScaleNotes, 6) - 1) display.print(F(" "));
}
}
} else if (id == MENU_ID_TEMPO) { display.print(F(": ")); display.print(tempo); }
else if (id == MENU_ID_ROOT) {
const char* noteNames[] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
display.print(F(": ")); display.print(noteNames[currentRoot % 12]);
}
else if (id == MENU_ID_SCALE_TYPE) {
const char* typeNames[] = {"Chrom", "Major", "Minor", "H.Min", "P.Maj", "P.Min", "ChdMaj", "ChdMin", "ChdDim", "Chd7"};
display.print(F(": ")); if (currentScaleType >= 0 && currentScaleType < 10) display.print(typeNames[currentScaleType]);
}
else if (id == MENU_ID_STEPS) { display.print(F(": ")); display.print(currentTrackNumSteps); }
else if (id == MENU_ID_SONG_MODE) { display.print(F(": ")); display.print(songModeEnabled ? F("ON") : F("OFF")); }
else if (id == MENU_ID_TRACK_SELECT) { display.print(F(": ")); display.print(randomizeTrack + 1); }