Skip to content

Commit

Permalink
Generalize horizontal shift for clip types
Browse files Browse the repository at this point in the history
  • Loading branch information
topisani committed Jul 3, 2023
1 parent e43e383 commit fce0bd6
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 153 deletions.
60 changes: 0 additions & 60 deletions src/deluge/gui/views/audio_clip_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
#include "playback/mode/arrangement.h"
#include "gui/ui_timer_manager.h"
#include "model/consequence/consequence_clip_length.h"
#include "model/consequence/consequence_instrument_clip_horizontal_shift.h"
#include "hid/led/pad_leds.h"
#include "hid/led/indicator_leds.h"
#include "hid/buttons.h"
Expand All @@ -45,8 +44,6 @@
#include "model/model_stack.h"
#include "extern.h"
#include "model/clip/clip_minder.h"
#include "memory/general_memory_allocator.h"
#include <new>

extern "C" {
extern uint8_t currentlyAccessingCard;
Expand Down Expand Up @@ -576,63 +573,6 @@ int AudioClipView::verticalEncoderAction(int offset, bool inCardRoutine) {
return ACTION_RESULT_DEALT_WITH;
}

int AudioClipView::horizontalEncoderAction(int offset) {
if ((isNoUIModeActive() && Buttons::isButtonPressed(yEncButtonX, yEncButtonY))
|| (isUIModeActiveExclusively(UI_MODE_HOLDING_HORIZONTAL_ENCODER_BUTTON)
&& Buttons::isButtonPressed(clipViewButtonX, clipViewButtonY))) {
if (sdRoutineLock) return ACTION_RESULT_REMIND_ME_OUTSIDE_CARD_ROUTINE; // Just be safe - maybe not necessary
int squareSize = getPosFromSquare(1) - getPosFromSquare(0);
int shiftAmount = offset * squareSize;
AudioClip* clip = getClip();

char modelStackMemory[MODEL_STACK_MAX_SIZE];
ModelStackWithTimelineCounter* modelStack = currentSong->setupModelStackWithCurrentClip(modelStackMemory);

bool was_shifted = clip->shiftHorizontally(modelStack, shiftAmount);
if (!was_shifted) {
numericDriver.displayPopup(HAVE_OLED ? "Can't shift past start" : "CANT");
return ACTION_RESULT_DEALT_WITH;
}

uiNeedsRendering(this, 0xFFFFFFFF, 0);

// If possible, just modify a previous Action to add this new shift amount to it.
Action* action = actionLogger.firstAction[BEFORE];
if (action && action->type == ACTION_INSTRUMENT_CLIP_HORIZONTAL_SHIFT && action->openForAdditions
&& action->currentClip == clip) {

// If there's no Consequence in the Action, that's probably because we deleted it a previous time with the code just below.
// Or possibly because the Action was created but there wasn't enough RAM to create the Consequence. Anyway, just go add a consequence now.
if (!action->firstConsequence) goto addConsequenceToAction;

ConsequenceInstrumentClipHorizontalShift* consequence =
(ConsequenceInstrumentClipHorizontalShift*)action->firstConsequence;
consequence->amount += shiftAmount;
}

// Or if no previous Action, go create a new one now.
else {

action = actionLogger.getNewAction(ACTION_INSTRUMENT_CLIP_HORIZONTAL_SHIFT, ACTION_ADDITION_NOT_ALLOWED);
if (action) {
addConsequenceToAction:
void* consMemory = generalMemoryAllocator.alloc(sizeof(ConsequenceInstrumentClipHorizontalShift));

if (consMemory) {
ConsequenceInstrumentClipHorizontalShift* newConsequence =
new (consMemory) ConsequenceInstrumentClipHorizontalShift(shiftAmount);
action->addConsequence(newConsequence);
}
}
}
return ACTION_RESULT_DEALT_WITH;
}

// Or, let parent deal with it
else {
return ClipView::horizontalEncoderAction(offset);
}
}
bool AudioClipView::setupScroll(uint32_t oldScroll) {

if (!getClip()->currentlyScrollableAndZoomable()) return false;
Expand Down
1 change: 0 additions & 1 deletion src/deluge/gui/views/audio_clip_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ class AudioClipView final : public ClipView, public ClipMinder {
void sampleNeedsReRendering(Sample* sample);
void selectEncoderAction(int8_t offset);
int verticalEncoderAction(int offset, bool inCardRoutine);
int horizontalEncoderAction(int offset);
int timerCallback();
uint32_t getMaxLength();
unsigned int getMaxZoom();
Expand Down
100 changes: 81 additions & 19 deletions src/deluge/gui/views/clip_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,23 @@
#include "model/clip/clip_minder.h"
#include "gui/views/view.h"
#include "definitions.h"
#include "model/consequence/consequence_clip_horizontal_shift.h"
#include "memory/general_memory_allocator.h"
#include <new>

static Clip* getCurrentClip() {
return currentSong->currentClip;
}

ClipView::ClipView() {
}

unsigned int ClipView::getMaxZoom() {
return currentSong->currentClip->getMaxZoom();
return getCurrentClip()->getMaxZoom();
}

uint32_t ClipView::getMaxLength() {
return currentSong->currentClip->getMaxLength();
return getCurrentClip()->getMaxLength();
}

void ClipView::focusRegained() {
Expand All @@ -48,14 +55,14 @@ void ClipView::focusRegained() {
int ClipView::buttonAction(int x, int y, bool on, bool inCardRoutine) {

// Horizontal encoder button press-down - don't let it do its zoom level thing if zooming etc not currently accessible
if (x == xEncButtonX && y == xEncButtonY && on && !currentSong->currentClip->currentlyScrollableAndZoomable()) {}
if (x == xEncButtonX && y == xEncButtonY && on && !getCurrentClip()->currentlyScrollableAndZoomable()) {}

#ifdef BUTTON_SEQUENCE_DIRECTION_X
else if (x == BUTTON_SEQUENCE_DIRECTION_X && y == BUTTON_SEQUENCE_DIRECTION_Y) {
if (on && isNoUIModeActive()) {
currentSong->currentClip->sequenceDirection++;
if (currentSong->currentClip->sequenceDirection == NUM_SEQUENCE_DIRECTION_OPTIONS) {
currentSong->currentClip->sequenceDirection = 0;
getCurrentClip()->sequenceDirection++;
if (getCurrentClip()->sequenceDirection == NUM_SEQUENCE_DIRECTION_OPTIONS) {
getCurrentClip()->sequenceDirection = 0;
}
view.setModLedStates();
}
Expand All @@ -76,7 +83,7 @@ Action* ClipView::lengthenClip(int32_t newLength) {
// If the last action was a shorten, undo it
bool undoing = (actionLogger.firstAction[BEFORE] && actionLogger.firstAction[BEFORE]->openForAdditions
&& actionLogger.firstAction[BEFORE]->type == ACTION_CLIP_LENGTH_DECREASE
&& actionLogger.firstAction[BEFORE]->currentClip == currentSong->currentClip);
&& actionLogger.firstAction[BEFORE]->currentClip == getCurrentClip());

if (undoing) {
allowResyncingDuringClipLengthChange =
Expand All @@ -86,16 +93,16 @@ Action* ClipView::lengthenClip(int32_t newLength) {
}

// Only if that didn't get us directly to the correct length, manually set length. This will do a resync if playback active
if (currentSong->currentClip->loopLength != newLength) {
int actionType = (newLength < currentSong->currentClip->loopLength) ? ACTION_CLIP_LENGTH_DECREASE
if (getCurrentClip()->loopLength != newLength) {
int actionType = (newLength < getCurrentClip()->loopLength) ? ACTION_CLIP_LENGTH_DECREASE
: ACTION_CLIP_LENGTH_INCREASE;

action = actionLogger.getNewAction(actionType, true);
if (action && action->currentClip != currentSong->currentClip) {
if (action && action->currentClip != getCurrentClip()) {
action = actionLogger.getNewAction(actionType, false);
}

currentSong->setClipLength(currentSong->currentClip, newLength, action);
currentSong->setClipLength(getCurrentClip(), newLength, action);
}

// Otherwise, do the resync that we missed out on doing
Expand All @@ -117,12 +124,12 @@ Action* ClipView::shortenClip(int32_t newLength) {
Action* action = NULL;

action = actionLogger.getNewAction(ACTION_CLIP_LENGTH_DECREASE, true);
if (action && action->currentClip != currentSong->currentClip) {
if (action && action->currentClip != getCurrentClip()) {
action = actionLogger.getNewAction(ACTION_CLIP_LENGTH_DECREASE, false);
}

currentSong->setClipLength(
currentSong->currentClip, newLength,
getCurrentClip(), newLength,
action); // Subsequently shortening by more squares won't cause additional Consequences to be added to the same
// Action - it checks, and only stores the data (snapshots and original length) once
return action;
Expand All @@ -135,12 +142,12 @@ int ClipView::horizontalEncoderAction(int offset) {
&& (Buttons::isShiftButtonPressed() || Buttons::isButtonPressed(clipViewButtonX, clipViewButtonY))) {

// If tempoless recording, don't allow
if (!currentSong->currentClip->currentlyScrollableAndZoomable()) {
if (!getCurrentClip()->currentlyScrollableAndZoomable()) {
numericDriver.displayPopup(HAVE_OLED ? "Can't edit length" : "CANT");
return ACTION_RESULT_DEALT_WITH;
}

uint32_t oldLength = currentSong->currentClip->loopLength;
uint32_t oldLength = getCurrentClip()->loopLength;

// If we're not scrolled all the way to the right, go there now
if (scrollRightToEndOfLengthIfNecessary(oldLength)) return ACTION_RESULT_DEALT_WITH;
Expand Down Expand Up @@ -206,11 +213,66 @@ int ClipView::horizontalEncoderAction(int offset) {
return ACTION_RESULT_DEALT_WITH;
}

// Or, maybe shift everything horizontally
else if ((isNoUIModeActive() && Buttons::isButtonPressed(yEncButtonX, yEncButtonY))
|| (isUIModeActiveExclusively(UI_MODE_HOLDING_HORIZONTAL_ENCODER_BUTTON)
&& Buttons::isButtonPressed(clipViewButtonX, clipViewButtonY))) {
if (sdRoutineLock) return ACTION_RESULT_REMIND_ME_OUTSIDE_CARD_ROUTINE; // Just be safe - maybe not necessary
int squareSize = getPosFromSquare(1) - getPosFromSquare(0);
int shiftAmount = offset * squareSize;
Clip* clip = getCurrentClip();

char modelStackMemory[MODEL_STACK_MAX_SIZE];
ModelStackWithTimelineCounter* modelStack = currentSong->setupModelStackWithCurrentClip(modelStackMemory);

bool wasShifted = clip->shiftHorizontally(modelStack, shiftAmount);
if (!wasShifted) {
numericDriver.displayPopup(HAVE_OLED ? "Can't shift past start" : "CANT");
return ACTION_RESULT_DEALT_WITH;
}

uiNeedsRendering(this, 0xFFFFFFFF, 0);

// If possible, just modify a previous Action to add this new shift amount to it.
Action* action = actionLogger.firstAction[BEFORE];
if (action && action->type == ACTION_CLIP_HORIZONTAL_SHIFT && action->openForAdditions
&& action->currentClip == clip) {

// If there's no Consequence in the Action, that's probably because we deleted it a previous time with the code just below.
// Or possibly because the Action was created but there wasn't enough RAM to create the Consequence. Anyway, just go add a consequence now.
if (!action->firstConsequence) goto addConsequenceToAction;

ConsequenceClipHorizontalShift* consequence =
(ConsequenceClipHorizontalShift*)action->firstConsequence;
consequence->amount += shiftAmount;

// It might look tempting that if we've completed one whole loop, we could delete the Consequence because everything would be back the same -
// but no! Remember different NoteRows might have different lengths.
}

// Or if no previous Action, go create a new one now.
else {

action = actionLogger.getNewAction(ACTION_CLIP_HORIZONTAL_SHIFT, ACTION_ADDITION_NOT_ALLOWED);
if (action) {
addConsequenceToAction:
void* consMemory = generalMemoryAllocator.alloc(sizeof(ConsequenceClipHorizontalShift));

if (consMemory) {
ConsequenceClipHorizontalShift* newConsequence =
new (consMemory) ConsequenceClipHorizontalShift(shiftAmount);
action->addConsequence(newConsequence);
}
}
}
return ACTION_RESULT_DEALT_WITH;
}

// Or, if shift button not pressed...
else {

// If tempoless recording, don't allow
if (!currentSong->currentClip->currentlyScrollableAndZoomable()) {
if (!getCurrentClip()->currentlyScrollableAndZoomable()) {
return ACTION_RESULT_DEALT_WITH;
}

Expand Down Expand Up @@ -258,14 +320,14 @@ int32_t ClipView::getLengthExtendAmount(int32_t square) {

int ClipView::getTickSquare() {

int newTickSquare = getSquareFromPos(currentSong->currentClip->getLivePos());
int newTickSquare = getSquareFromPos(getCurrentClip()->getLivePos());

// See if we maybe want to do an auto-scroll
if (currentSong->currentClip->getCurrentlyRecordingLinearly()) {
if (getCurrentClip()->getCurrentlyRecordingLinearly()) {

if (newTickSquare == displayWidth && (!currentUIMode || currentUIMode == UI_MODE_AUDITIONING)
&& getCurrentUI() == this && // currentPlaybackMode == &session &&
(!currentSong->currentClip->armState || xScrollBeforeFollowingAutoExtendingLinearRecording != -1)) {
(!getCurrentClip()->armState || xScrollBeforeFollowingAutoExtendingLinearRecording != -1)) {

if (xScrollBeforeFollowingAutoExtendingLinearRecording == -1)
xScrollBeforeFollowingAutoExtendingLinearRecording = currentSong->xScroll[NAVIGATION_CLIP];
Expand Down
51 changes: 0 additions & 51 deletions src/deluge/gui/views/instrument_clip_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
#include "gui/ui/rename/rename_drum_ui.h"
#include "model/song/song.h"
#include "model/clip/clip.h"
#include "model/consequence/consequence_instrument_clip_horizontal_shift.h"
#include "model/consequence/consequence_note_array_change.h"
#include "gui/menu_item/menu_item_colour.h"
#include "hid/led/pad_leds.h"
Expand Down Expand Up @@ -3877,56 +3876,6 @@ int InstrumentClipView::horizontalEncoderAction(int offset) {
return ACTION_RESULT_DEALT_WITH;
}

// Or, maybe shift everything horizontally
else if ((isNoUIModeActive() && Buttons::isButtonPressed(yEncButtonX, yEncButtonY))
|| (isUIModeActiveExclusively(UI_MODE_HOLDING_HORIZONTAL_ENCODER_BUTTON)
&& Buttons::isButtonPressed(clipViewButtonX, clipViewButtonY))) {
if (sdRoutineLock) return ACTION_RESULT_REMIND_ME_OUTSIDE_CARD_ROUTINE; // Just be safe - maybe not necessary
int squareSize = getPosFromSquare(1) - getPosFromSquare(0);
int shiftAmount = offset * squareSize;
InstrumentClip* clip = getCurrentClip();

char modelStackMemory[MODEL_STACK_MAX_SIZE];
ModelStackWithTimelineCounter* modelStack = currentSong->setupModelStackWithCurrentClip(modelStackMemory);

clip->shiftHorizontally(modelStack, shiftAmount);
uiNeedsRendering(this, 0xFFFFFFFF, 0);

// If possible, just modify a previous Action to add this new shift amount to it.
Action* action = actionLogger.firstAction[BEFORE];
if (action && action->type == ACTION_INSTRUMENT_CLIP_HORIZONTAL_SHIFT && action->openForAdditions
&& action->currentClip == clip) {

// If there's no Consequence in the Action, that's probably because we deleted it a previous time with the code just below.
// Or possibly because the Action was created but there wasn't enough RAM to create the Consequence. Anyway, just go add a consequence now.
if (!action->firstConsequence) goto addConsequenceToAction;

ConsequenceInstrumentClipHorizontalShift* consequence =
(ConsequenceInstrumentClipHorizontalShift*)action->firstConsequence;
consequence->amount += shiftAmount;

// It might look tempting that if we've completed one whole loop, we could delete the Consequence because everything would be back the same -
// but no! Remember different NoteRows might have different lengths.
}

// Or if no previous Action, go create a new one now.
else {

action = actionLogger.getNewAction(ACTION_INSTRUMENT_CLIP_HORIZONTAL_SHIFT, ACTION_ADDITION_NOT_ALLOWED);
if (action) {
addConsequenceToAction:
void* consMemory = generalMemoryAllocator.alloc(sizeof(ConsequenceInstrumentClipHorizontalShift));

if (consMemory) {
ConsequenceInstrumentClipHorizontalShift* newConsequence =
new (consMemory) ConsequenceInstrumentClipHorizontalShift(shiftAmount);
action->addConsequence(newConsequence);
}
}
}
return ACTION_RESULT_DEALT_WITH;
}

// Or, let parent deal with it
else {
return ClipView::horizontalEncoderAction(offset);
Expand Down
2 changes: 1 addition & 1 deletion src/deluge/model/action/action.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class ModelStack;
#define ACTION_ARRANGEMENT_TIME_CONTRACT 17
#define ACTION_ARRANGEMENT_CLEAR 18
#define ACTION_ARRANGEMENT_RECORD 19
#define ACTION_INSTRUMENT_CLIP_HORIZONTAL_SHIFT 20
#define ACTION_CLIP_HORIZONTAL_SHIFT 20
#define ACTION_NOTE_NUDGE 21
#define ACTION_NOTE_REPEAT_EDIT 22
#define ACTION_EUCLIDEAN_NUM_EVENTS_EDIT 23
Expand Down
2 changes: 2 additions & 0 deletions src/deluge/model/clip/clip.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ class Clip : public TimelineCounter {
void setSequenceDirectionMode(ModelStackWithTimelineCounter* modelStack, int newSequenceDirection);
bool possiblyCloneForArrangementRecording(ModelStackWithTimelineCounter* modelStack);
virtual void incrementPos(ModelStackWithTimelineCounter* modelStack, int32_t numTicks);
/// Return true if successfully shifted
virtual bool shiftHorizontally(ModelStackWithTimelineCounter* modelStack, int amount) = 0;

// ----- PlayPositionCounter implementation -------
int32_t getLoopLength();
Expand Down
3 changes: 2 additions & 1 deletion src/deluge/model/clip/instrument_clip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2941,7 +2941,7 @@ NoteRow* InstrumentClip::getNoteRowFromId(int id) {
}
}

void InstrumentClip::shiftHorizontally(ModelStackWithTimelineCounter* modelStack, int amount) {
bool InstrumentClip::shiftHorizontally(ModelStackWithTimelineCounter* modelStack, int amount) {

if (paramManager.containsAnyParamCollectionsIncludingExpression()) {
paramManager.shiftHorizontally(
Expand All @@ -2959,6 +2959,7 @@ void InstrumentClip::shiftHorizontally(ModelStackWithTimelineCounter* modelStack
expectEvent();
reGetParameterAutomation(modelStack); // Re-gets all NoteRow-level param automation too
}
return true;
}

void InstrumentClip::shiftOnlyOneNoteRowHorizontally(ModelStackWithNoteRow* modelStack, int shiftAmount) {
Expand Down
3 changes: 2 additions & 1 deletion src/deluge/model/clip/instrument_clip.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ class InstrumentClip final : public Clip {
void restoreBackedUpParamManagerMIDI(ModelStackWithModControllable* modelStack);
int getNoteRowId(NoteRow* noteRow, int noteRowIndex);
NoteRow* getNoteRowFromId(int id);
void shiftHorizontally(ModelStackWithTimelineCounter* modelStack, int amount);
/// Return true if successfully shifted. Instrument clips always succeed
bool shiftHorizontally(ModelStackWithTimelineCounter* modelStack, int amount);
bool containsAnyNotes();
ModelStackWithNoteRow* getNoteRowOnScreen(int yDisplay, ModelStackWithTimelineCounter* modelStack);
NoteRow* getNoteRowOnScreen(int yDisplay, Song* song, int* getIndex = NULL);
Expand Down

0 comments on commit fce0bd6

Please sign in to comment.