Deluge Firmware 1.3.0
Build date: 2025.04.16
Loading...
Searching...
No Matches
iterance_step_toggle.h
1/*
2 * Copyright (c) 2024 Sean Ditny / Raúl Muñoz
3 *
4 * This file is part of The Synthstrom Audible Deluge Firmware.
5 *
6 * The Synthstrom Audible Deluge Firmware is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software Foundation,
8 * either version 3 of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with this program.
15 * If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#pragma once
19#include "definitions_cxx.hpp"
20#include "gui/menu_item/toggle.h"
21#include "gui/views/instrument_clip_view.h"
22#include "model/clip/instrument_clip.h"
23#include "model/note/note_row.h"
24
25namespace deluge::gui::menu_item::note_row {
26class IteranceStepToggle : public Toggle {
27public:
28 using Toggle::Toggle;
29
30 IteranceStepToggle(l10n::String newName, l10n::String title, uint8_t newIndex) : Toggle(newName, title) {
31 this->index = newIndex;
32 }
33
34 ModelStackWithNoteRow* getIndividualNoteRow(ModelStackWithTimelineCounter* modelStack) {
35 auto* clip = static_cast<InstrumentClip*>(modelStack->getTimelineCounter());
36 ModelStackWithNoteRow* modelStackWithNoteRow =
37 clip->getNoteRowOnScreen(instrumentClipView.lastAuditionedYDisplay,
38 modelStack); // don't create
39
40 bool isKit = clip->output->type == OutputType::KIT;
41
42 if (!isKit) {
43 if (!modelStackWithNoteRow->getNoteRowAllowNull()) { // if note row doesn't exist yet, create it
44 modelStackWithNoteRow =
45 instrumentClipView.createNoteRowForYDisplay(modelStack, instrumentClipView.lastAuditionedYDisplay);
46 }
47 }
48
49 return modelStackWithNoteRow;
50 }
51
52 void updateDisplay() {
53 if (display->haveOLED()) {
54 renderUIsForOled();
55 }
56 else {
57 drawValue();
58 }
59 }
60
61 void readCurrentValue() override {
62 char modelStackMemory[MODEL_STACK_MAX_SIZE];
63 ModelStackWithTimelineCounter* modelStack = currentSong->setupModelStackWithCurrentClip(modelStackMemory);
64 ModelStackWithNoteRow* modelStackWithNoteRow = getIndividualNoteRow(modelStack);
65
66 if (modelStackWithNoteRow->getNoteRowAllowNull() != nullptr) {
67 NoteRow* noteRow = modelStackWithNoteRow->getNoteRowAllowNull();
68 Iterance iterance = noteRow->iteranceValue;
69 if (iterance == kDefaultIteranceValue) {
70 // if we end up here in this menu, convert OFF to the default CUSTOM value 1of1
71 // so we can make edits from here
72 iterance = kCustomIteranceValue;
73 }
74 this->setValue(iterance.iteranceStep[index]);
75 updateDisplay();
76 }
77 }
78 void writeCurrentValue() override {
79 bool value = this->getValue();
80 char modelStackMemory[MODEL_STACK_MAX_SIZE];
81 ModelStackWithTimelineCounter* modelStack = currentSong->setupModelStackWithCurrentClip(modelStackMemory);
82 ModelStackWithNoteRow* modelStackWithNoteRow = getIndividualNoteRow(modelStack);
83
84 if (modelStackWithNoteRow->getNoteRowAllowNull() != nullptr) {
85 NoteRow* noteRow = modelStackWithNoteRow->getNoteRowAllowNull();
86 Iterance iterance = noteRow->iteranceValue;
87 if (iterance == kDefaultIteranceValue) {
88 // if we end up here in this menu, convert OFF to the default CUSTOM value 1of1
89 // so we can make edits from here
90 iterance = kCustomIteranceValue;
91 }
92 int32_t newIteranceSteps = iterance.toInt() & 0xFF;
93 if (value) {
94 newIteranceSteps |= (1 << index);
95 }
96 else {
97 newIteranceSteps &= ~(1 << index);
98 }
99 instrumentClipView.setNoteRowIteranceWithFinalValue(Iterance{iterance.divisor, newIteranceSteps});
100 }
101 }
102
103 uint8_t index;
104
105 bool isRelevant(ModControllableAudio* modControllable, int32_t whichThing) override {
106 char modelStackMemory[MODEL_STACK_MAX_SIZE];
107 ModelStackWithTimelineCounter* modelStack = currentSong->setupModelStackWithCurrentClip(modelStackMemory);
108 ModelStackWithNoteRow* modelStackWithNoteRow = getIndividualNoteRow(modelStack);
109
110 if (modelStackWithNoteRow->getNoteRowAllowNull() != nullptr) {
111 NoteRow* noteRow = modelStackWithNoteRow->getNoteRowAllowNull();
112 Iterance iterance = noteRow->iteranceValue;
113 // Only show this iteration step if its index is smaller than current divisor value
114 return (iterance == kDefaultIteranceValue && index == 0) || iterance.divisor > index;
115 }
116 return false;
117 }
118};
119} // namespace deluge::gui::menu_item::note_row
Definition instrument_clip.h:48
deluge::l10n::String title
Can get overridden by getTitle(). Actual max num chars for OLED display is 14.
Definition menu_item.h:208
Definition mod_controllable_audio.h:47
Definition model_stack.h:189
Definition model_stack.h:129
Definition note_row.h:98
Definition toggle.h:8
bool isRelevant(ModControllableAudio *modControllable, int32_t whichThing) override
Check if this MenuItem should show up in a containing deluge::gui::menu_item::Submenu.
Definition iterance_step_toggle.h:105
void readCurrentValue() override
Like readValueAgain, but does not redraw.
Definition iterance_step_toggle.h:61
Definition iterance.h:23