32 using Selection::Selection;
35 if (getCurrentUI() == &soundEditor && soundEditor.inNoteRowEditor() && !isUIModeActive(UI_MODE_AUDITIONING)) {
36 display->displayPopup(
"Select Row");
43 auto* clip =
static_cast<InstrumentClip*
>(modelStack->getTimelineCounter());
44 if (!clip->affectEntire && clip->output->type == OutputType::KIT) {
45 Kit* kit = getCurrentKit();
46 if (kit->selectedDrum !=
nullptr) {
47 return clip->getNoteRowForDrum(modelStack, kit->selectedDrum);
50 else if (clip->output->type != OutputType::KIT) {
51 if (soundEditor.selectedNoteRow) {
54 clip->getNoteRowOnScreen(instrumentClipView.lastAuditionedYDisplay, modelStack);
55 if (!modelStackWithNoteRow->getNoteRowAllowNull()) {
56 modelStackWithNoteRow = instrumentClipView.createNoteRowForYDisplay(
57 modelStack, instrumentClipView.lastAuditionedYDisplay);
59 return modelStackWithNoteRow;
62 return modelStack->addNoteRow(0,
nullptr);
66 char modelStackMemory[MODEL_STACK_MAX_SIZE];
70 if (modelStackWithNoteRow->getNoteRowAllowNull() !=
nullptr) {
71 this->setValue(modelStackWithNoteRow->getNoteRow()->sequenceDirectionMode);
74 this->setValue(getCurrentInstrumentClip()->sequenceDirectionMode);
78 void writeCurrentValue()
override {
79 auto current_value = this->getValue<SequenceDirection>();
80 char modelStackMemory[MODEL_STACK_MAX_SIZE];
83 if (modelStackWithNoteRow->getNoteRowAllowNull() !=
nullptr) {
84 modelStackWithNoteRow->getNoteRow()->setSequenceDirectionMode(modelStackWithNoteRow, current_value);
87 getCurrentInstrumentClip()->setSequenceDirectionMode(modelStackWithNoteRow->toWithTimelineCounter(),
92 deluge::vector<std::string_view> getOptions(OptType optType)
override {
94 deluge::vector<std::string_view> sequenceDirectionOptions = {
95 l10n::getView(l10n::String::STRING_FOR_FORWARD),
96 l10n::getView(l10n::String::STRING_FOR_REVERSED),
97 l10n::getView(l10n::String::STRING_FOR_PING_PONG),
100 char modelStackMemory[MODEL_STACK_MAX_SIZE];
103 if (modelStackWithNoteRow->getNoteRowAllowNull() !=
nullptr) {
104 sequenceDirectionOptions.push_back(l10n::getView(l10n::String::STRING_FOR_NONE));
107 return sequenceDirectionOptions;
110 MenuPermission checkPermissionToBeginSession(ModControllableAudio* modControllable, int32_t whichThing,
111 ::MultiRange** currentRange)
override {
112 OutputType outputType = getCurrentOutputType();
113 if (!getCurrentInstrumentClip()->affectEntire && outputType == OutputType::KIT
114 && (getCurrentKit()->selectedDrum ==
nullptr)) {
115 return MenuPermission::NO;
117 else if (outputType != OutputType::KIT) {
118 soundEditor.selectedNoteRow = isUIModeActive(UI_MODE_AUDITIONING);
120 return MenuPermission::YES;
123 void renderInHorizontalMenu(
const HorizontalMenuSlotParams& slot)
override {
124 using namespace deluge::hid::display;
125 oled_canvas::Canvas& image = OLED::main;
127 const auto current_value = this->getValue<SequenceDirection>();
128 if (current_value == SequenceDirection::OBEY_PARENT) {
129 return Selection::renderInHorizontalMenu(slot);
132 const uint8_t icon_y = slot.start_y + kHorizontalMenuSlotYOffset;
133 if (current_value == SequenceDirection::PINGPONG) {
134 image.drawIconCentered(OLED::directionIcon, slot.start_x + 2, slot.width, icon_y);
135 image.drawIconCentered(OLED::directionIcon, slot.start_x - 2, slot.width, icon_y,
true);
138 image.drawIconCentered(OLED::directionIcon, slot.start_x, slot.width, icon_y,
139 current_value == SequenceDirection::REVERSE);