35 using Selection::Selection;
36 void readCurrentValue()
override { this->setValue(soundEditor.currentArpSettings->preset); }
39 void writeCurrentValue()
override {
40 auto current_value = this->getValue<ArpPreset>();
43 if (currentUIMode == UI_MODE_HOLDING_AFFECT_ENTIRE_IN_SOUND_EDITOR && soundEditor.editingKitRow()) {
45 Kit* kit = getCurrentKit();
48 if (soundEditor.currentArpSettings->mode == ArpMode::OFF || current_value == ArpPreset::OFF) {
49 if (getCurrentClip()->isActiveOnOutput() && !soundEditor.editingKitAffectEntire()) {
54 for (
Drum* thisDrum = kit->firstDrum; thisDrum !=
nullptr; thisDrum = thisDrum->next) {
55 thisDrum->arpSettings.preset = current_value;
56 thisDrum->arpSettings.updateSettingsFromCurrentPreset();
57 thisDrum->arpSettings.flagForceArpRestart =
true;
63 if (soundEditor.currentArpSettings->mode == ArpMode::OFF || current_value == ArpPreset::OFF) {
64 if (getCurrentClip()->isActiveOnOutput() && !soundEditor.editingKitAffectEntire()) {
65 char modelStackMemory[MODEL_STACK_MAX_SIZE];
68 if (soundEditor.editingKit()) {
70 Drum* currentDrum = ((
Kit*)getCurrentClip()->output)->selectedDrum;
71 if (currentDrum !=
nullptr) {
72 currentDrum->killAllVoices();
75 else if (soundEditor.editingCVOrMIDIClip()) {
76 getCurrentInstrumentClip()->stopAllNotesForMIDIOrCV(modelStack->toWithTimelineCounter());
79 ModelStackWithSoundFlags* modelStackWithSoundFlags = modelStack->addSoundFlags();
80 soundEditor.currentSound->allNotesOff(
81 modelStackWithSoundFlags,
82 soundEditor.currentSound
84 soundEditor.currentSound->reassessRenderSkippingStatus(modelStackWithSoundFlags);
89 soundEditor.currentArpSettings->preset = current_value;
90 soundEditor.currentArpSettings->updateSettingsFromCurrentPreset();
91 soundEditor.currentArpSettings->flagForceArpRestart =
true;
95 deluge::vector<std::string_view> getOptions(OptType optType)
override {
97 using enum l10n::String;
99 l10n::getView(STRING_FOR_OFF),
100 l10n::getView(STRING_FOR_UP),
101 l10n::getView(STRING_FOR_DOWN),
102 l10n::getView(STRING_FOR_BOTH),
103 l10n::getView(STRING_FOR_RANDOM),
104 l10n::getView(STRING_FOR_WALK),
105 l10n::getView(STRING_FOR_CUSTOM),
110 auto current_value = this->getValue<ArpPreset>();
111 if (current_value == ArpPreset::CUSTOM) {
112 if (soundEditor.editingKitRow()) {
113 return &arpOctaveModeToNoteModeMenuForDrums;
115 return &arpOctaveModeToNoteModeMenu;
122 void getColumnLabel(
StringBuf& label)
override { label.append(l10n::get(l10n::String::STRING_FOR_MODE)); }
124 void renderInHorizontalMenu(int32_t startX, int32_t width, int32_t startY, int32_t height)
override {
125 using namespace deluge::hid::display;
128 if (this->getValue<ArpPreset>() == ArpPreset::OFF) {
129 const auto offString = l10n::get(l10n::String::STRING_FOR_OFF);
130 return image.drawStringCentered(offString, startX, startY + 8, kTextTitleSpacingX, kTextTitleSizeY, width);
133 const std::vector<std::reference_wrapper<const std::vector<uint8_t>>> bitmaps = [&] {
134 switch (this->getValue<ArpPreset>()) {
136 return std::vector{std::cref(OLED::arpModeIconUp)};
137 case ArpPreset::DOWN:
138 return std::vector{std::cref(OLED::arpModeIconDown)};
139 case ArpPreset::BOTH:
140 return std::vector{std::cref(OLED::arpModeIconUp), std::cref(OLED::arpModeIconDown)};
141 case ArpPreset::RANDOM:
142 return std::vector{std::cref(OLED::diceIcon)};
143 case ArpPreset::WALK:
144 return std::vector{std::cref(OLED::arpModeIconWalk)};
145 case ArpPreset::CUSTOM:
146 return std::vector{std::cref(OLED::arpModeIconCustom)};
148 return std::vector<std::reference_wrapper<const std::vector<uint8_t>>>{};
152 constexpr int32_t numBytesTall = 2;
153 const int32_t bitmapsWidth = std::accumulate(
154 bitmaps.begin(), bitmaps.end(), 0, [](int32_t acc,
auto v) { return acc + v.get().size() / numBytesTall; });
157 int32_t x = startX + (width - bitmapsWidth) / 2;
158 int32_t y = startY + (height - numBytesTall * 8) / 2;
161 for (
auto bitmap : bitmaps) {
162 image.drawGraphicMultiLine(bitmap.get().data(), x, y, bitmap.get().size() / numBytesTall, numBytesTall * 8,
164 x += bitmap.get().
size() / numBytesTall;