Deluge Firmware 1.3.0
Build date: 2026.02.12
Loading...
Searching...
No Matches
iterance_step_toggle.h
1/*
2 * Copyright (c) 2014-2023 Synthstrom Audible Limited
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#pragma once
18#include "definitions_cxx.hpp"
19#include "gui/menu_item/toggle.h"
20#include "gui/views/instrument_clip_view.h"
21#include "model/clip/instrument_clip.h"
22#include "model/note/note_row.h"
23
24namespace deluge::gui::menu_item::note_row {
25class IteranceStepToggle : public Toggle {
26public:
27 using Toggle::Toggle;
28
29 IteranceStepToggle(l10n::String newName, l10n::String title, uint8_t newIndex) : Toggle(newName, title) {
30 this->index = newIndex;
31 }
32
33 ModelStackWithNoteRow* getIndividualNoteRow(ModelStackWithTimelineCounter* modelStack) {
34 auto* clip = static_cast<InstrumentClip*>(modelStack->getTimelineCounter());
35 ModelStackWithNoteRow* modelStackWithNoteRow =
36 clip->getNoteRowOnScreen(instrumentClipView.lastAuditionedYDisplay,
37 modelStack); // don't create
38
39 bool isKit = clip->output->type == OutputType::KIT;
40
41 if (!isKit) {
42 if (!modelStackWithNoteRow->getNoteRowAllowNull()) { // if note row doesn't exist yet, create it
43 modelStackWithNoteRow =
44 instrumentClipView.createNoteRowForYDisplay(modelStack, instrumentClipView.lastAuditionedYDisplay);
45 }
46 }
47
48 return modelStackWithNoteRow;
49 }
50
51 void updateDisplay() {
52 if (display->haveOLED()) {
53 renderUIsForOled();
54 }
55 else {
56 drawValue();
57 }
58 }
59
60 void readCurrentValue() override {
61 char modelStackMemory[MODEL_STACK_MAX_SIZE];
62 ModelStackWithTimelineCounter* modelStack = currentSong->setupModelStackWithCurrentClip(modelStackMemory);
63 ModelStackWithNoteRow* modelStackWithNoteRow = getIndividualNoteRow(modelStack);
64
65 if (modelStackWithNoteRow->getNoteRowAllowNull() != nullptr) {
66 NoteRow* noteRow = modelStackWithNoteRow->getNoteRowAllowNull();
67 Iterance iterance = noteRow->iteranceValue;
68 if (iterance == kDefaultIteranceValue) {
69 // if we end up here in this menu, convert OFF to the default CUSTOM value 1of1
70 // so we can make edits from here
71 iterance = kCustomIteranceValue;
72 }
73 this->setValue(iterance.iteranceStep[index]);
74 updateDisplay();
75 }
76 }
77 void writeCurrentValue() override {
78 bool value = this->getValue();
79 char modelStackMemory[MODEL_STACK_MAX_SIZE];
80 ModelStackWithTimelineCounter* modelStack = currentSong->setupModelStackWithCurrentClip(modelStackMemory);
81 ModelStackWithNoteRow* modelStackWithNoteRow = getIndividualNoteRow(modelStack);
82
83 if (modelStackWithNoteRow->getNoteRowAllowNull() != nullptr) {
84 NoteRow* noteRow = modelStackWithNoteRow->getNoteRowAllowNull();
85 Iterance iterance = noteRow->iteranceValue;
86 if (iterance == kDefaultIteranceValue) {
87 // if we end up here in this menu, convert OFF to the default CUSTOM value 1of1
88 // so we can make edits from here
89 iterance = kCustomIteranceValue;
90 }
91 int32_t newIteranceSteps = iterance.toInt() & 0xFF;
92 if (value) {
93 newIteranceSteps |= (1 << index);
94 }
95 else {
96 newIteranceSteps &= ~(1 << index);
97 }
98 instrumentClipView.setNoteRowIteranceWithFinalValue(Iterance{iterance.divisor, newIteranceSteps});
99 }
100 }
101
102 uint8_t index;
103
104 bool isRelevant(ModControllableAudio* modControllable, int32_t whichThing) override {
105 char modelStackMemory[MODEL_STACK_MAX_SIZE];
106 ModelStackWithTimelineCounter* modelStack = currentSong->setupModelStackWithCurrentClip(modelStackMemory);
107 ModelStackWithNoteRow* modelStackWithNoteRow = getIndividualNoteRow(modelStack);
108
109 if (modelStackWithNoteRow->getNoteRowAllowNull() != nullptr) {
110 NoteRow* noteRow = modelStackWithNoteRow->getNoteRowAllowNull();
111 Iterance iterance = noteRow->iteranceValue;
112 // Only show this iteration step if its index is smaller than current divisor value
113 return (iterance == kDefaultIteranceValue && index == 0) || iterance.divisor > index;
114 }
115 return false;
116 }
117};
118} // 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:222
Definition mod_controllable_audio.h:47
Definition model_stack.h:189
Definition model_stack.h:129
Definition note_row.h:99
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:104
void readCurrentValue() override
Like readValueAgain, but does not redraw.
Definition iterance_step_toggle.h:60
Definition iterance.h:23