Some automation pattern fixes (#3352)

* Fix deleting automation points out of quantization

* Triplets in Automation Editor + better remove action

* Let a quantized Automation point wipe clean the space it covers

* Improve sensitivity on erase with zoom < 100%

* Eigth note default quantization

* Tooltip and whatsthis text
This commit is contained in:
Oskar Wallgren
2017-03-04 19:04:42 +01:00
committed by GitHub
parent fd74ddfe15
commit f7d09c3c69
3 changed files with 90 additions and 41 deletions

View File

@@ -204,23 +204,34 @@ void AutomationPattern::updateLength()
MidiTime AutomationPattern::putValue( const MidiTime & _time,
const float _value,
const bool _quant_pos )
MidiTime AutomationPattern::putValue( const MidiTime & time,
const float value,
const bool quantPos,
const bool controlKey )
{
cleanObjects();
MidiTime newTime = _quant_pos ?
Note::quantized( _time, quantization() ) :
_time;
MidiTime newTime = quantPos ?
Note::quantized( time, quantization() ) :
time;
m_timeMap[newTime] = _value;
m_timeMap[ newTime ] = value;
timeMap::const_iterator it = m_timeMap.find( newTime );
// Remove control points that are covered by the new points
// quantization value. Control Key to override
if( ! controlKey )
{
for( int i = newTime + 1; i < newTime + quantization(); ++i )
{
AutomationPattern::removeValue( i );
}
}
if( it != m_timeMap.begin() )
{
--it;
}
generateTangents(it, 3);
generateTangents( it, 3 );
// we need to maximize our length in case we're part of a hidden
// automation track as the user can't resize this pattern
@@ -237,18 +248,13 @@ MidiTime AutomationPattern::putValue( const MidiTime & _time,
void AutomationPattern::removeValue( const MidiTime & _time,
const bool _quant_pos )
void AutomationPattern::removeValue( const MidiTime & time )
{
cleanObjects();
MidiTime newTime = _quant_pos ?
Note::quantized( _time, quantization() ) :
_time;
m_timeMap.remove( newTime );
m_tangents.remove( newTime );
timeMap::const_iterator it = m_timeMap.lowerBound( newTime );
m_timeMap.remove( time );
m_tangents.remove( time );
timeMap::const_iterator it = m_timeMap.lowerBound( time );
if( it != m_timeMap.begin() )
{
--it;
@@ -267,7 +273,7 @@ void AutomationPattern::removeValue( const MidiTime & _time,
/**
* @brief Set the position of the point that is being draged.
* @brief Set the position of the point that is being dragged.
* Calling this function will also automatically set m_dragging to true,
* which applyDragValue() have to be called to m_dragging.
* @param the time(x position) of the point being dragged
@@ -275,14 +281,16 @@ void AutomationPattern::removeValue( const MidiTime & _time,
* @param true to snip x position
* @return
*/
MidiTime AutomationPattern::setDragValue( const MidiTime & _time, const float _value,
const bool _quant_pos )
MidiTime AutomationPattern::setDragValue( const MidiTime & time,
const float value,
const bool quantPos,
const bool controlKey )
{
if( m_dragging == false )
{
MidiTime newTime = _quant_pos ?
Note::quantized( _time, quantization() ) :
_time;
MidiTime newTime = quantPos ?
Note::quantized( time, quantization() ) :
time;
this->removeValue( newTime );
m_oldTimeMap = m_timeMap;
m_dragging = true;
@@ -293,10 +301,10 @@ MidiTime AutomationPattern::setDragValue( const MidiTime & _time, const float _v
for( timeMap::const_iterator it = m_timeMap.begin(); it != m_timeMap.end(); ++it )
{
generateTangents(it, 3);
generateTangents( it, 3 );
}
return this->putValue( _time, _value, _quant_pos );
return this->putValue( time, value, quantPos, controlKey );
}
@@ -648,7 +656,7 @@ void AutomationPattern::processMidiTime( const MidiTime & time )
}
else if( valueAt( time ) != value )
{
removeValue( time, false );
removeValue( time );
}
}
}

View File

@@ -132,6 +132,17 @@ AutomationEditor::AutomationEditor() :
{
m_quantizeModel.addItem( "1/" + QString::number( 1 << i ) );
}
for( int i = 0; i < 5; ++i )
{
m_quantizeModel.addItem( "1/" +
QString::number( ( 1 << i ) * 3 ) );
}
m_quantizeModel.addItem( "1/192" );
connect( &m_quantizeModel, SIGNAL(dataChanged() ),
this, SLOT( setQuantization() ) );
m_quantizeModel.setValue( m_quantizeModel.findText( "1/8" ) );
if( s_toolYFlip == NULL )
{
s_toolYFlip = new QPixmap( embed::getIconPixmap(
@@ -143,9 +154,6 @@ AutomationEditor::AutomationEditor() :
"flip_x" ) );
}
connect(&m_quantizeModel, SIGNAL(dataChanged()), this, SLOT(setQuantization()));
m_quantizeModel.setValue( m_quantizeModel.findText( "1/16" ) );
// add time-line
m_timeLine = new TimeLineWidget( VALUES_WIDTH, 0, m_ppt,
Engine::getSong()->getPlayPos(
@@ -555,7 +563,9 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
MidiTime new_time =
m_pattern->setDragValue( value_pos,
level );
level, true,
mouseEvent->modifiers() &
Qt::ControlModifier );
// reset it so that it can be used for
// ops (move, resize) after this
@@ -695,7 +705,9 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
// moved properly according to new starting-
// time in the time map of pattern
m_pattern->setDragValue( MidiTime( pos_ticks ),
level );
level, true,
mouseEvent->modifiers() &
Qt::ControlModifier );
}
Engine::getSong()->setModified();
@@ -706,7 +718,14 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
( mouseEvent->buttons() & Qt::LeftButton &&
m_editMode == ERASE ) )
{
m_pattern->removeValue( MidiTime( pos_ticks ) );
// int resolution needed to improve the sensitivity of
// the erase manoeuvre with zoom levels < 100%
int zoom = m_zoomingXModel.value();
int resolution = 1 + zoom * zoom;
for( int i = -resolution; i < resolution; ++i )
{
m_pattern->removeValue( MidiTime( pos_ticks + i ) );
}
}
else if( mouseEvent->buttons() & Qt::NoButton && m_editMode == DRAW )
{
@@ -2015,8 +2034,22 @@ void AutomationEditor::zoomingYChanged()
void AutomationEditor::setQuantization()
{
int quantization = DefaultTicksPerTact / (1 << m_quantizeModel.value());;
AutomationPattern::setQuantization(quantization);
int quantization = m_quantizeModel.value();
if( quantization < 7 )
{
quantization = 1 << quantization;
}
else if( quantization < 12 )
{
quantization = 1 << ( quantization - 7 );
quantization *= 3;
}
else
{
quantization = DefaultTicksPerTact;
}
quantization = DefaultTicksPerTact / quantization;
AutomationPattern::setQuantization( quantization );
}
@@ -2325,7 +2358,12 @@ AutomationEditorWindow::AutomationEditorWindow() :
quantizationActionsToolBar->addWidget( quantize_lbl );
quantizationActionsToolBar->addWidget( m_quantizeComboBox );
m_quantizeComboBox->setToolTip( tr( "Quantization" ) );
m_quantizeComboBox->setWhatsThis( tr( "Quantization. Sets the smallest "
"step size for the Automation Point. By default "
"this also sets the length, clearing out other "
"points in the range. Press <Ctrl> to override "
"this behaviour." ) );
// Setup our actual window
setFocusPolicy( Qt::StrongFocus );