Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add tension
  • Loading branch information
regulus79 committed May 22, 2025
commit 96225d10e852ad94d029b77db50bf290533374c5
23 changes: 15 additions & 8 deletions include/Clip.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,23 +151,28 @@ class LMMS_EXPORT Clip : public Model, public JournallingObject
TimePos startTimeOffset() const;
void setStartTimeOffset( const TimePos &startTimeOffset );

TimePos startCrossfadeLength() const
TimePos startCrossfadeLength() const { return m_startCrossfadeLength; }
void setStartCrossfadeLength(const TimePos& startCrossfadeLength)
{
return m_startCrossfadeLength;
m_startCrossfadeLength = std::max(TimePos{0}, startCrossfadeLength);
}
void setStartCrossfadeLength(const TimePos &startCrossfadeLength)
TimePos endCrossfadeLength() const { return m_endCrossfadeLength; }
void setEndCrossfadeLength(const TimePos &endCrossfadeLength)
{
m_startCrossfadeLength = std::max(TimePos{0}, startCrossfadeLength);
m_endCrossfadeLength = std::max(TimePos{0}, endCrossfadeLength);
}

TimePos endCrossfadeLength() const
float startCrossfadeTension() const { return m_startCrossfadeTension; }
void setStartCrossfadeTension(float startCrossfadeTension)
{
return m_endCrossfadeLength;
m_startCrossfadeTension = std::clamp(startCrossfadeTension, 0.0f, 1.0f);
}
void setEndCrossfadeLength(const TimePos &endCrossfadeLength)
float endCrossfadeTension() const { return m_endCrossfadeTension; }
void setEndCrossfadeTension(float endCrossfadeTension)
{
m_endCrossfadeLength = std::max(TimePos{0}, endCrossfadeLength);
m_endCrossfadeTension = std::clamp(endCrossfadeTension, 0.0f, 1.0f);
}

virtual bool isCrossfadeable() const { return false; }

// Will copy the state of a clip to another clip
Expand Down Expand Up @@ -202,6 +207,8 @@ public slots:

TimePos m_startCrossfadeLength;
TimePos m_endCrossfadeLength;
float m_startCrossfadeTension;
float m_endCrossfadeTension;

BoolModel m_mutedModel;
BoolModel m_soloModel;
Expand Down
5 changes: 5 additions & 0 deletions include/ClipView.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ protected slots:
ResizeLeft,
EditStartCrossfade,
EditEndCrossfade,
EditStartCrossfadeTension,
EditEndCrossfadeTension,
Split,
CopySelection,
ToggleSelected
Expand Down Expand Up @@ -234,8 +236,11 @@ protected slots:
QCursor m_cursorHand;
QCursor m_cursorKnife;
bool m_cursorSetYet;

bool m_mouseOverStartCrossfadeHandle;
bool m_mouseOverStartCrossfadeTensionHandle;
bool m_mouseOverEndCrossfadeHandle;
bool m_mouseOverEndCrossfadeTensionHandle;

bool m_needsUpdate;
inline void setInitialPos( QPoint pos )
Expand Down
10 changes: 8 additions & 2 deletions src/core/Clip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Clip::Clip( Track * track ) :
m_length(),
m_startCrossfadeLength(0),
m_endCrossfadeLength(0),
m_startCrossfadeTension(1.0f - std::numbers::sqrt2 / 2),
m_endCrossfadeTension(1.0f - std::numbers::sqrt2 / 2),
m_mutedModel( false, this, tr( "Mute" ) ),
m_selectViewOnCreate{false}
{
Expand Down Expand Up @@ -76,6 +78,10 @@ Clip::Clip(const Clip& other):
m_startPosition(other.m_startPosition),
m_length(other.m_length),
m_startTimeOffset(other.m_startTimeOffset),
m_startCrossfadeLength(other.m_startCrossfadeLength),
m_endCrossfadeLength(other.m_endCrossfadeLength),
m_startCrossfadeTension(other.m_startCrossfadeTension),
m_endCrossfadeTension(other.m_endCrossfadeTension),
m_mutedModel(other.m_mutedModel.value(), this, tr( "Mute" )),
m_resizable(other.m_resizable),
m_autoResize(other.m_autoResize),
Expand Down Expand Up @@ -139,8 +145,8 @@ void Clip::movePosition( const TimePos & pos )
void Clip::changeLength( const TimePos & length )
{
m_length = length;
m_startCrossfadeLength = std::min(m_startCrossfadeLength, m_length);
m_endCrossfadeLength = std::min(m_endCrossfadeLength, m_length);
setStartCrossfadeLength(std::min(m_startCrossfadeLength, m_length));
setEndCrossfadeLength(std::min(m_endCrossfadeLength, m_length));
Engine::getSong()->updateLength();
emit lengthChanged();
}
Expand Down
4 changes: 4 additions & 0 deletions src/core/SampleClip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,8 @@ void SampleClip::saveSettings( QDomDocument & _doc, QDomElement & _this )
_this.setAttribute("autoresize", QString::number(getAutoResize()));
_this.setAttribute("startfadelength", QString::number(startCrossfadeLength()));
_this.setAttribute("endfadelength", QString::number(endCrossfadeLength()));
_this.setAttribute("startfadetension", QString::number(startCrossfadeTension()));
_this.setAttribute("endfadetension", QString::number(endCrossfadeTension()));
if( sampleFile() == "" )
{
QString s;
Expand Down Expand Up @@ -361,6 +363,8 @@ void SampleClip::loadSettings( const QDomElement & _this )
setAutoResize(_this.attribute("autoresize", "1").toInt());
setStartCrossfadeLength(_this.attribute("startfadelength").toInt());
setEndCrossfadeLength(_this.attribute("endfadelength").toInt());
setStartCrossfadeTension(_this.attribute("startfadetension", QString::number(1.0f - std::numbers::sqrt2 / 2)).toFloat());
setEndCrossfadeTension(_this.attribute("endfadetension", QString::number(1.0f - std::numbers::sqrt2 / 2)).toFloat());

if (_this.hasAttribute("color"))
{
Expand Down
13 changes: 9 additions & 4 deletions src/core/SamplePlayHandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "AudioEngine.h"
#include "AudioBusHandle.h"
#include "Engine.h"
#include "lmms_math.h"
#include "MixHelpers.h"
#include "Note.h"
#include "PatternTrack.h"
Expand Down Expand Up @@ -87,76 +88,80 @@




void SamplePlayHandle::play( SampleFrame* buffer )
{
const fpp_t fpp = Engine::audioEngine()->framesPerPeriod();
//play( 0, _try_parallelizing );
if( framesDone() >= totalFrames() )
{
zeroSampleFrames(buffer, fpp);
return;
}

SampleFrame* workingBuffer = buffer;
f_cnt_t frames = fpp;

// apply offset for the first period
if( framesDone() == 0 )
{
zeroSampleFrames(buffer, offset());
workingBuffer += offset();
frames -= offset();
}

const f_cnt_t initialFrameIndex = m_state.frameIndex();

if( !( m_track && m_track->isMuted() )
&& !(m_patternTrack && m_patternTrack->isMuted()))
{
/* StereoVolumeVector v =
{ { m_volumeModel->value() / DefaultVolume,
m_volumeModel->value() / DefaultVolume } };*/
// SamplePlayHandle always plays the sample at its original pitch;
// it is used only for previews, SampleTracks and the metronome.
if (!m_sample->play(workingBuffer, &m_state, frames, DefaultBaseFreq))
{
zeroSampleFrames(workingBuffer, frames);
}

// Apply crossfade if this play handle is for a clip
if (m_clip && (m_clip->startCrossfadeLength() != 0 || m_clip->endCrossfadeLength() != 0))
{
const int framesPerTick = Engine::framesPerTick(Engine::audioEngine()->outputSampleRate());
const int startCrossfadeFrames = m_clip->startCrossfadeLength() * framesPerTick;
const int endCrossfadeFrames = m_clip->endCrossfadeLength() * framesPerTick;
const int startOffsetFrames = m_clip->startTimeOffset() * framesPerTick;
const int lengthFrames = m_clip->length() * framesPerTick;
const float startPower = std::log(1.0f - m_clip->startCrossfadeTension()) / -std::numbers::ln2;
const float endPower = std::log(1.0f - m_clip->endCrossfadeTension()) / -std::numbers::ln2;

for (f_cnt_t f = 0; f < frames; ++f)
{
const f_cnt_t frameIndex = initialFrameIndex + f;
const int framesRelativeToClipStart = frameIndex + startOffsetFrames;
const int framesRelativeToClipEnd = lengthFrames - framesRelativeToClipStart;
if (framesRelativeToClipStart < 0 || framesRelativeToClipEnd < 0) { workingBuffer[f] = SampleFrame(); continue; }

if (framesRelativeToClipStart < startCrossfadeFrames && framesRelativeToClipEnd < endCrossfadeFrames)
{
workingBuffer[f] *= std::sqrt(static_cast<float>(framesRelativeToClipStart) / static_cast<float>(startCrossfadeFrames))
* std::sqrt(static_cast<float>(framesRelativeToClipEnd) / static_cast<float>(endCrossfadeFrames));
workingBuffer[f] *=
fastPow(static_cast<float>(framesRelativeToClipStart) / static_cast<float>(startCrossfadeFrames), startPower)
* fastPow(static_cast<float>(framesRelativeToClipEnd) / static_cast<float>(endCrossfadeFrames), endPower);
}
else if (framesRelativeToClipStart < startCrossfadeFrames)
{
workingBuffer[f] *= std::sqrt(static_cast<float>(framesRelativeToClipStart) / static_cast<float>(startCrossfadeFrames));
workingBuffer[f] *= fastPow(static_cast<float>(framesRelativeToClipStart) / static_cast<float>(startCrossfadeFrames), startPower);
}
else if (framesRelativeToClipEnd < endCrossfadeFrames)
{
workingBuffer[f] *= std::sqrt(static_cast<float>(framesRelativeToClipEnd) / static_cast<float>(endCrossfadeFrames));
workingBuffer[f] *= fastPow(static_cast<float>(framesRelativeToClipEnd) / static_cast<float>(endCrossfadeFrames), endPower);
}
}
}
}

m_frame += frames;

Check notice on line 164 in src/core/SamplePlayHandle.cpp

View check run for this annotation

codefactor.io / CodeFactor

src/core/SamplePlayHandle.cpp#L91-L164

Complex Method
}


Expand Down
109 changes: 101 additions & 8 deletions src/gui/clips/ClipView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "InstrumentTrack.h"
#include "InstrumentTrackView.h"
#include "KeyboardShortcuts.h"
#include "lmms_math.h"
#include "MidiClip.h"
#include "MidiClipView.h"
#include "Note.h"
Expand Down Expand Up @@ -114,7 +115,9 @@
m_cursorKnife( QCursor( embed::getIconPixmap( "cursor_knife" ) ) ),
m_cursorSetYet( false ),
m_mouseOverStartCrossfadeHandle(false),
m_mouseOverStartCrossfadeTensionHandle(false),
m_mouseOverEndCrossfadeHandle(false),
m_mouseOverEndCrossfadeTensionHandle(false),
m_needsUpdate( true )
{
if( s_textFloat == nullptr )
Expand Down Expand Up @@ -616,69 +619,92 @@
painter.drawText( textLeft, finalTextTop, elidedClipName );
}

void ClipView::drawCrossfade(QPainter& painter, QRect rect)
{
float nom = Engine::getSong()->getTimeSigModel().getNumerator();
float den = Engine::getSong()->getTimeSigModel().getDenominator();
float ticksPerBar = DefaultTicksPerBar * nom / den;
int startCrossfadeLength = m_clip->startCrossfadeLength() / ticksPerBar * pixelsPerBar();
int endCrossfadeLength = m_clip->endCrossfadeLength() / ticksPerBar * pixelsPerBar();
float startCrossfadeTension = m_clip->startCrossfadeTension();
float endCrossfadeTension = m_clip->endCrossfadeTension();

if (m_clip->startCrossfadeLength() > 0)
{
QPainterPath startPath;
startPath.moveTo(QPoint(0,0));
startPath.lineTo(QPoint(0, rect.height()));
float lastValue = 0;
for (int i = 0; i < startCrossfadeLength; ++i)
{
float nextValue = std::sqrt(static_cast<float>(i) / static_cast<float>(startCrossfadeLength));
float nextValue = fastPow(static_cast<float>(i) / static_cast<float>(startCrossfadeLength), std::log(1.0f - startCrossfadeTension) / -std::numbers::ln2);
startPath.lineTo(QPoint(i + 1, (1.0f - nextValue) * rect.height()));
painter.drawLine(i, (1.0f - lastValue) * rect.height(), i + 1, (1.0f - nextValue) * rect.height());
lastValue = nextValue;
}
startPath.lineTo(QPoint(startCrossfadeLength, 0));
painter.fillPath(startPath, QColor(0,0,0,200));
}
if (m_mouseOverStartCrossfadeHandle || m_action == Action::EditStartCrossfade)
{
painter.drawEllipse(std::max(0, startCrossfadeLength - CROSSFADE_GRIP_ACTIVE_RADIUS), 0, CROSSFADE_GRIP_ACTIVE_RADIUS*2, CROSSFADE_GRIP_ACTIVE_RADIUS*2);
}
else if (m_clip->startCrossfadeLength() > 0)
{
painter.drawEllipse(std::max(0, startCrossfadeLength - CROSSFADE_GRIP_RADIUS), 0, CROSSFADE_GRIP_RADIUS*2, CROSSFADE_GRIP_RADIUS*2);
}

if ((m_mouseOverStartCrossfadeTensionHandle || m_action == Action::EditStartCrossfadeTension) && m_clip->startCrossfadeLength() > 0)
{
painter.drawEllipse(std::max(0, startCrossfadeLength / 2 - CROSSFADE_GRIP_ACTIVE_RADIUS), startCrossfadeTension * rect.height() - CROSSFADE_GRIP_ACTIVE_RADIUS, CROSSFADE_GRIP_ACTIVE_RADIUS*2, CROSSFADE_GRIP_ACTIVE_RADIUS*2);
}
else if (m_clip->startCrossfadeLength() > 0)
{
painter.drawEllipse(std::max(0, startCrossfadeLength / 2 - CROSSFADE_GRIP_RADIUS), startCrossfadeTension * rect.height() - CROSSFADE_GRIP_RADIUS, CROSSFADE_GRIP_RADIUS*2, CROSSFADE_GRIP_RADIUS*2);
}

if (m_clip->endCrossfadeLength() > 0)
{
QPainterPath endPath;
endPath.moveTo(QPoint(rect.width(),0));
endPath.lineTo(QPoint(rect.width(), rect.height()));
float lastValue = 0;
for (int i = 1; i < endCrossfadeLength; ++i)
{
float nextValue = std::sqrt(static_cast<float>(i) / static_cast<float>(endCrossfadeLength));
float nextValue = fastPow(static_cast<float>(i) / static_cast<float>(endCrossfadeLength), std::log(1.0f - endCrossfadeTension) / -std::numbers::ln2);
endPath.lineTo(QPoint(rect.width() - i - 1, (1.0f - nextValue) * rect.height()));
painter.drawLine(rect.width() - i, (1.0f - lastValue) * rect.height(), rect.width() - i - 1, (1.0f - nextValue) * rect.height());
lastValue = nextValue;
}
endPath.lineTo(QPoint(rect.width() - endCrossfadeLength, 0));
painter.fillPath(endPath, QColor(0,0,0,200));
}

if (m_mouseOverEndCrossfadeHandle || m_action == Action::EditEndCrossfade)
{
painter.drawEllipse(std::min(rect.width() - CROSSFADE_GRIP_ACTIVE_RADIUS * 2, rect.width() - endCrossfadeLength - CROSSFADE_GRIP_ACTIVE_RADIUS), 0, CROSSFADE_GRIP_ACTIVE_RADIUS*2, CROSSFADE_GRIP_ACTIVE_RADIUS*2);
}
else if (m_clip->endCrossfadeLength() > 0)
{
painter.drawEllipse(std::min(rect.width() - CROSSFADE_GRIP_RADIUS * 2, rect.width() - endCrossfadeLength - CROSSFADE_GRIP_RADIUS), 0, CROSSFADE_GRIP_RADIUS*2, CROSSFADE_GRIP_RADIUS*2);
}

if ((m_mouseOverEndCrossfadeTensionHandle || m_action == Action::EditEndCrossfadeTension) && m_clip->endCrossfadeLength() > 0)
{
painter.drawEllipse(std::min(rect.width() - CROSSFADE_GRIP_ACTIVE_RADIUS * 2, rect.width() - endCrossfadeLength / 2 - CROSSFADE_GRIP_ACTIVE_RADIUS), endCrossfadeTension * rect.height() - CROSSFADE_GRIP_ACTIVE_RADIUS, CROSSFADE_GRIP_ACTIVE_RADIUS*2, CROSSFADE_GRIP_ACTIVE_RADIUS*2);
}
else if (m_clip->endCrossfadeLength() > 0)
{
painter.drawEllipse(std::min(rect.width() - CROSSFADE_GRIP_RADIUS * 2, rect.width() - endCrossfadeLength / 2 - CROSSFADE_GRIP_RADIUS), endCrossfadeTension * rect.height() - CROSSFADE_GRIP_RADIUS, CROSSFADE_GRIP_RADIUS*2, CROSSFADE_GRIP_RADIUS*2);
}
}

Check notice on line 701 in src/gui/clips/ClipView.cpp

View check run for this annotation

codefactor.io / CodeFactor

src/gui/clips/ClipView.cpp#L622-L701

Complex Method
void ClipView::leaveEvent(QEvent* e)
{
m_mouseOverStartCrossfadeHandle = false;
m_mouseOverEndCrossfadeHandle = false;
m_mouseOverStartCrossfadeTensionHandle = false;
m_mouseOverEndCrossfadeTensionHandle = false;
update();
}

Expand All @@ -697,213 +723,236 @@
*
* \param me The QMouseEvent to handle.
*/
void ClipView::mousePressEvent( QMouseEvent * me )
{
// Right now, active is only used on right/mid clicks actions, so we use a ternary operator
// to avoid the overhead of calling getClickedClips when it's not used
auto active = me->button() == Qt::LeftButton
? QVector<ClipView *>()
: getClickedClips();

setInitialPos( me->pos() );
setInitialOffsets();
if( !fixedClips() && me->button() == Qt::LeftButton )
{
const bool knifeMode = m_trackView->trackContainerView()->knifeMode();

if (me->modifiers() & KBD_COPY_MODIFIER && !knifeMode)
{
if( isSelected() )
{
m_action = Action::CopySelection;
}
else
{
m_action = Action::ToggleSelected;
}
}
else
{
if( isSelected() )
{
for (auto clipv: getClickedClips()) { clipv->getClip()->addJournalCheckPoint(); }

if (m_mouseOverStartCrossfadeHandle && m_clip->isCrossfadeable())
{
m_action = Action::EditStartCrossfade;
setCursor(Qt::SizeHorCursor);
}
else if (m_mouseOverEndCrossfadeHandle && m_clip->isCrossfadeable())
{
m_action = Action::EditEndCrossfade;
setCursor(Qt::SizeHorCursor);
}
else if (m_mouseOverStartCrossfadeTensionHandle && m_clip->startCrossfadeLength() > 0 && m_clip->isCrossfadeable())
{
m_action = Action::EditStartCrossfadeTension;
setCursor(Qt::SizeVerCursor);
}
else if (m_mouseOverEndCrossfadeTensionHandle && m_clip->endCrossfadeLength() > 0 && m_clip->isCrossfadeable())
{
m_action = Action::EditEndCrossfadeTension;
setCursor(Qt::SizeVerCursor);
}
else
{
m_action = Action::MoveSelection;
}
}
else
{
getGUI()->songEditor()->m_editor->selectAllClips( false );
m_clip->addJournalCheckPoint();

setInitialPos( me->pos() );
setInitialOffsets();

if (!m_clip->getResizable() && !knifeMode)
{ // Always move clips that can't be manually resized
m_action = Action::Move;
setCursor( Qt::SizeAllCursor );
}
else if (m_mouseOverStartCrossfadeHandle && m_clip->isCrossfadeable())
{
m_action = Action::EditStartCrossfade;
setCursor(Qt::SizeHorCursor);
}
else if (m_mouseOverEndCrossfadeHandle && m_clip->isCrossfadeable())
{
m_action = Action::EditEndCrossfade;
setCursor(Qt::SizeHorCursor);
}
else if (m_mouseOverStartCrossfadeTensionHandle && m_clip->startCrossfadeLength() > 0 && m_clip->isCrossfadeable())
{
m_action = Action::EditStartCrossfadeTension;
setCursor(Qt::SizeVerCursor);
}
else if (m_mouseOverEndCrossfadeTensionHandle && m_clip->endCrossfadeLength() > 0 && m_clip->isCrossfadeable())
{
m_action = Action::EditEndCrossfadeTension;
setCursor(Qt::SizeVerCursor);
}
else if( me->x() >= width() - RESIZE_GRIP_WIDTH )
{
m_action = Action::Resize;
setCursor( Qt::SizeHorCursor );
}
else if (me->x() < RESIZE_GRIP_WIDTH)
{
m_action = Action::ResizeLeft;
setCursor( Qt::SizeHorCursor );
}
else if (knifeMode)
{
m_action = Action::Split;
setCursor( m_cursorKnife );
setMarkerPos( knifeMarkerPos( me ) );
setMarkerEnabled( true );
update();
}
else
{
m_action = Action::Move;
setCursor( Qt::SizeAllCursor );
}

if( m_action == Action::Move )
{
s_textFloat->setTitle( tr( "Current position" ) );
s_textFloat->setText( QString( "%1:%2" ).
arg( m_clip->startPosition().getBar() + 1 ).
arg( m_clip->startPosition().getTicks() %
TimePos::ticksPerBar() ) );
}
else if( m_action == Action::Resize || m_action == Action::ResizeLeft )
{
s_textFloat->setTitle( tr( "Current length" ) );
s_textFloat->setText( tr( "%1:%2 (%3:%4 to %5:%6)" ).
arg( m_clip->length().getBar() ).
arg( m_clip->length().getTicks() %
TimePos::ticksPerBar() ).
arg( m_clip->startPosition().getBar() + 1 ).
arg( m_clip->startPosition().getTicks() %
TimePos::ticksPerBar() ).
arg( m_clip->endPosition().getBar() + 1 ).
arg( m_clip->endPosition().getTicks() %
TimePos::ticksPerBar() ) );
}
else if (m_action == Action::EditStartCrossfade)
{
s_textFloat->setTitle(tr("Fade length"));
s_textFloat->setText(QString("%1:%2").
arg(m_clip->startCrossfadeLength().getBar() + 1).
arg(m_clip->startCrossfadeLength().getTicks() %
TimePos::ticksPerBar()));
}
else if (m_action == Action::EditEndCrossfade)
{
s_textFloat->setTitle(tr("Fade length"));
s_textFloat->setText(QString("%1:%2").
arg(m_clip->endCrossfadeLength().getBar() + 1).
arg(m_clip->endCrossfadeLength().getTicks() %
TimePos::ticksPerBar()));
}
// s_textFloat->reparent( this );
// setup text-float as if Clip was already moved/resized
s_textFloat->moveGlobal( this, QPoint( width() + 2, height() + 2) );
if ( m_action != Action::Split) { s_textFloat->show(); }
}

delete m_hint;
QString hint;
if (m_action == Action::Move || m_action == Action::MoveSelection)
{
hint = tr("Press <%1> and drag to make a copy.");
}
else if (m_action == Action::Split)
{
hint = dynamic_cast<MidiClipView*>(this)
? tr("Press <%1> or <Alt> for unquantized splitting.\nPress <Shift> for destructive splitting.")
: tr("Press <%1> or <Alt> for unquantized splitting.");
}
else if (m_action == Action::Resize || m_action == Action::ResizeLeft)
{
hint = tr("Press <%1> or <Alt> for unquantized resizing.");
}
else if (m_action == Action::EditStartCrossfade || m_action == Action::EditEndCrossfade)
{
hint = tr("Press <%1> or <Alt> for quantized fading.");
}
m_hint = TextFloat::displayMessage( tr( "Hint" ), hint.arg(UI_COPY_KEY),
embed::getIconPixmap( "hint" ), 0 );
if (hint != "")
{
m_hint = TextFloat::displayMessage(tr("Hint"), hint.arg(UI_COPY_KEY),
embed::getIconPixmap("hint"), 0);
}
}
}
else if( me->button() == Qt::RightButton )
{
if( me->modifiers() & Qt::ControlModifier )
{
toggleMute( active );
}
else if( me->modifiers() & Qt::ShiftModifier && !fixedClips() )
{
remove( active );
}
if (m_action == Action::Split)
{
m_action = Action::None;
setMarkerEnabled(false);
update();
}
}
else if( me->button() == Qt::MiddleButton )
{
if( me->modifiers() & Qt::ControlModifier )
{
toggleMute( active );
}
else if( !fixedClips() )
{
remove( active );
}
}
}




/*! \brief Handle a mouse movement (drag) on this ClipView.
*
* Handles the various ways in which a ClipView can be
* used with a mouse drag.
*
* * If in move mode, move ourselves in the track,
* * or if in move-selection mode, move the entire selection,
* * or if in resize mode, resize ourselves,
* * otherwise ???
*
* \param me The QMouseEvent to handle.
* \todo what does the final else case do here?
*/

Check warning on line 955 in src/gui/clips/ClipView.cpp

View check run for this annotation

codefactor.io / CodeFactor

src/gui/clips/ClipView.cpp#L726-L955

Very Complex Method
void ClipView::mouseMoveEvent( QMouseEvent * me )
{
if( m_action == Action::CopySelection || m_action == Action::ToggleSelected )
Expand Down Expand Up @@ -1148,7 +1197,7 @@
// If multiple clips are selected, also set their crossfades
for (auto clipv: getClickedClips())
{
if (clipv && clipv->getClip()->isCrossfadeable())
if (clipv->getClip()->isCrossfadeable())
{
if (m_action == Action::EditStartCrossfade)
{
Expand All @@ -1162,6 +1211,30 @@
}
}
}
else if (m_action == Action::EditStartCrossfadeTension || m_action == Action::EditEndCrossfadeTension)
{
float tension = static_cast<float>(me->y()) / height();
if (m_action == Action::EditStartCrossfadeTension) { m_clip->setStartCrossfadeTension(tension); }
if (m_action == Action::EditEndCrossfadeTension) { m_clip->setEndCrossfadeTension(tension); }
update();

// If multiple clips are selected, also set their tensions
for (auto clipv: getClickedClips())
{
if (clipv->getClip()->isCrossfadeable())
{
if (m_action == Action::EditStartCrossfadeTension)
{
clipv->getClip()->setStartCrossfadeTension(tension);
}
else if (m_action == Action::EditEndCrossfadeTension)
{
clipv->getClip()->setEndCrossfadeTension(tension);
}
clipv->update();
}
}
}
else if( m_action == Action::Split )
{
setCursor(m_cursorKnife);
Expand All @@ -1173,6 +1246,8 @@

bool oldStartState = m_mouseOverStartCrossfadeHandle;
bool oldEndState = m_mouseOverEndCrossfadeHandle;
bool oldStartTensionState = m_mouseOverStartCrossfadeTensionHandle;
bool oldEndTensionState = m_mouseOverEndCrossfadeTensionHandle;

m_mouseOverStartCrossfadeHandle =
// Is the x coordinate within the radius of the handle?
Expand All @@ -1184,15 +1259,30 @@
&& me->y() <= CROSSFADE_GRIP_ACTIVE_RADIUS * 2;

m_mouseOverEndCrossfadeHandle =
// Is the x coordinate within the radius of the handle?
// Is the x coordinate within the radius of the handle?
(std::abs(me->x() - (m_clip->length() - m_clip->endCrossfadeLength()) * ppb / TimePos::ticksPerBar()) <= CROSSFADE_GRIP_ACTIVE_RADIUS
// Or, if there is no current fade, is the x coordinate close to the clip end?
|| (m_clip->endCrossfadeLength() == 0
&& m_clip->length() * ppb / TimePos::ticksPerBar() - me->x() < CROSSFADE_GRIP_ACTIVE_RADIUS * 2))
// And, is the y coordinate up by the top of the clip?
&& me->y() <= CROSSFADE_GRIP_ACTIVE_RADIUS * 2;

if (oldStartState != m_mouseOverStartCrossfadeHandle || oldEndState != m_mouseOverEndCrossfadeHandle)
m_mouseOverStartCrossfadeTensionHandle =
// Is the x coordinate within the radius of the handle?
std::abs(me->x() - m_clip->startCrossfadeLength() / 2 * ppb / TimePos::ticksPerBar()) <= CROSSFADE_GRIP_ACTIVE_RADIUS
// And, is the y coordinate at the height of the tension?
&& std::abs(me->y() - m_clip->startCrossfadeTension() * height()) <= CROSSFADE_GRIP_ACTIVE_RADIUS * 2;

m_mouseOverEndCrossfadeTensionHandle =
// Is the x coordinate within the radius of the handle?
std::abs(me->x() - (m_clip->length() - m_clip->endCrossfadeLength() / 2) * ppb / TimePos::ticksPerBar()) <= CROSSFADE_GRIP_ACTIVE_RADIUS
// And, is the y coordinate at the height of the tension?
&& std::abs(me->y() - m_clip->endCrossfadeTension() * height()) <= CROSSFADE_GRIP_ACTIVE_RADIUS * 2;

if (oldStartState != m_mouseOverStartCrossfadeHandle
|| oldEndState != m_mouseOverEndCrossfadeHandle
|| oldStartTensionState != m_mouseOverStartCrossfadeTensionHandle
|| oldEndTensionState != m_mouseOverEndCrossfadeTensionHandle)
{
update();
}
Expand Down Expand Up @@ -1220,7 +1310,10 @@
setSelected( !isSelected() );
}

if (m_action == Action::EditStartCrossfade || m_action == Action::EditEndCrossfade)
if (m_action == Action::EditStartCrossfade
|| m_action == Action::EditEndCrossfade
|| m_action == Action::EditStartCrossfadeTension
|| m_action == Action::EditEndCrossfadeTension)
{
update();
}
Expand Down
Loading