From eb0b0f527789b28b9d76ba2b187f905926a9524f Mon Sep 17 00:00:00 2001 From: Spekular Date: Mon, 22 Dec 2014 20:00:47 +0100 Subject: [PATCH 1/3] Adds automation flipping. --- include/AutomationEditor.h | 6 +++ include/AutomationPattern.h | 2 + include/AutomationPatternView.h | 2 + src/core/AutomationPattern.cpp | 81 +++++++++++++++++++++++++++++++ src/gui/AutomationEditor.cpp | 53 +++++++++++++++++++- src/gui/AutomationPatternView.cpp | 26 ++++++++++ 6 files changed, 168 insertions(+), 2 deletions(-) diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index 83b0a022bd2..fe46c9af081 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -130,6 +130,8 @@ protected slots: void eraseButtonToggled(); void selectButtonToggled(); void moveButtonToggled(); + void flipYButtonPressed(); + void flipXButtonPressed(); void discreteButtonToggled(); void linearButtonToggled(); @@ -187,6 +189,8 @@ protected slots: static QPixmap * s_toolErase; static QPixmap * s_toolSelect; static QPixmap * s_toolMove; + static QPixmap * s_toolYFlip; + static QPixmap * s_toolXFlip; QWidget * m_toolBar; @@ -198,6 +202,8 @@ protected slots: ToolButton * m_eraseButton; ToolButton * m_selectButton; ToolButton * m_moveButton; + ToolButton * m_flipYButton; + ToolButton * m_flipXButton; ToolButton * m_discreteButton; ToolButton * m_linearButton; diff --git a/include/AutomationPattern.h b/include/AutomationPattern.h index b6259b3c53a..9035491b30b 100644 --- a/include/AutomationPattern.h +++ b/include/AutomationPattern.h @@ -170,6 +170,8 @@ public slots: void clear(); void openInAutomationEditor(); void objectDestroyed( jo_id_t ); + void flipY( int min, int max ); + void flipX( bool visible ); private: void cleanObjects(); diff --git a/include/AutomationPatternView.h b/include/AutomationPatternView.h index 2c2a6c96b93..76b2e1a4720 100644 --- a/include/AutomationPatternView.h +++ b/include/AutomationPatternView.h @@ -51,6 +51,8 @@ protected slots: void changeName(); void disconnectObject( QAction * _a ); void toggleRecording(); + void flipY(); + void flipX(); protected: virtual void constructContextMenu( QMenu * ); diff --git a/src/core/AutomationPattern.cpp b/src/core/AutomationPattern.cpp index 9164e733dfa..a71030dff1b 100644 --- a/src/core/AutomationPattern.cpp +++ b/src/core/AutomationPattern.cpp @@ -384,6 +384,87 @@ float *AutomationPattern::valuesAfter( const MidiTime & _time ) const +void AutomationPattern::flipY( int min, int max ) +{ + timeMap tempMap = m_timeMap; + timeMap::ConstIterator iterate = m_timeMap.lowerBound(0); + float tempValue = 0; + + int numPoints = 0; + + //(iterate+1).key() - iterate.key(); gets the number of values until the next point + + for( int i = 0; (iterate + i + 1) != m_timeMap.end() && (iterate + i ) != m_timeMap.end() ; i++) + { + numPoints++; + } + + for( int i = 0; i <= numPoints; i++ ) + { + + if (min < 0) + { + tempValue = valueAt((iterate + i).key()) * -1; + //removeValue((iterate + i).key(), false); + putValue( MidiTime((iterate + i).key()) , tempValue, false); + } + else + { + tempValue = max - valueAt((iterate + i).key()); + //removeValue((iterate).key(), false); + putValue( MidiTime((iterate + i).key()) , tempValue, false); + } + } + + generateTangents(); + Engine::automationEditor()->update(); + emit dataChanged(); + +} + + + + +void AutomationPattern::flipX(bool visible) +{ + timeMap tempMap; + + timeMap::ConstIterator iterate = m_timeMap.lowerBound(0); + float tempValue = 0; + int numPoints = 0; + + //(iterate+1).key() - iterate.key(); gets the number of values until the next point + + for( int i = 0; (iterate + i + 1) != m_timeMap.end() && (iterate + i ) != m_timeMap.end() ; i++) + { + numPoints++; + } + + float realLength = (iterate + numPoints).key(); + + for( int i = 0; i <= numPoints; i++ ) + { + tempValue = valueAt((iterate + i).key()); + + cleanObjects(); + + MidiTime newTime = MidiTime( realLength - (iterate + i).key() ); + + tempMap[newTime] = tempValue; + } + + m_timeMap.clear(); + + m_timeMap = tempMap; + + generateTangents(); + Engine::automationEditor()->update(); + emit dataChanged(); +} + + + + void AutomationPattern::saveSettings( QDomDocument & _doc, QDomElement & _this ) { _this.setAttribute( "pos", startPosition() ); diff --git a/src/gui/AutomationEditor.cpp b/src/gui/AutomationEditor.cpp index cb90253b46e..a05d378b326 100644 --- a/src/gui/AutomationEditor.cpp +++ b/src/gui/AutomationEditor.cpp @@ -69,6 +69,8 @@ QPixmap * AutomationEditor::s_toolDraw = NULL; QPixmap * AutomationEditor::s_toolErase = NULL; QPixmap * AutomationEditor::s_toolSelect = NULL; QPixmap * AutomationEditor::s_toolMove = NULL; +QPixmap * AutomationEditor::s_toolYFlip = NULL; +QPixmap * AutomationEditor::s_toolXFlip = NULL; @@ -128,6 +130,16 @@ AutomationEditor::AutomationEditor() : s_toolMove = new QPixmap( embed::getIconPixmap( "edit_move" ) ); } + if( s_toolYFlip == NULL ) + { + s_toolYFlip = new QPixmap( embed::getIconPixmap( + "flip_y" ) ); + } + if( s_toolXFlip == NULL ) + { + s_toolXFlip = new QPixmap( embed::getIconPixmap( + "flip_x" ) ); + } setAttribute( Qt::WA_OpaquePaintEvent, true ); @@ -206,15 +218,25 @@ AutomationEditor::AutomationEditor() : m_toolBar ); m_eraseButton->setCheckable( true ); + m_flipYButton = new ToolButton( embed::getIconPixmap( "flip_y" ), + tr( "Flip Vertically" ), + this, SLOT( flipYButtonPressed() ), + m_toolBar ); + + m_flipXButton = new ToolButton( embed::getIconPixmap( "flip_x" ), + tr( "Flip Horizontally" ), + this, SLOT( flipXButtonPressed() ), + m_toolBar ); + //TODO: m_selectButton and m_moveButton are broken. - /*m_selectButton = new toolButton( embed::getIconPixmap( + /*m_selectButton = new ToolButton( embed::getIconPixmap( "edit_select" ), tr( "Select mode (Shift+S)" ), this, SLOT( selectButtonToggled() ), m_toolBar ); m_selectButton->setCheckable( true ); - m_moveButton = new toolButton( embed::getIconPixmap( "edit_move" ), + m_moveButton = new ToolButton( embed::getIconPixmap( "edit_move" ), tr( "Move selection mode (Shift+M)" ), this, SLOT( moveButtonToggled() ), m_toolBar ); @@ -223,6 +245,8 @@ AutomationEditor::AutomationEditor() : QButtonGroup * tool_button_group = new QButtonGroup( this ); tool_button_group->addButton( m_drawButton ); tool_button_group->addButton( m_eraseButton ); + tool_button_group->addButton( m_flipYButton ); + tool_button_group->addButton( m_flipXButton ); //tool_button_group->addButton( m_selectButton ); //tool_button_group->addButton( m_moveButton ); tool_button_group->setExclusive( true ); @@ -237,6 +261,12 @@ AutomationEditor::AutomationEditor() : tr( "Click here and erase-mode will be activated. In this " "mode you can erase single values. You can also press " "'Shift+E' on your keyboard to activate this mode." ) ); + m_flipYButton->setWhatsThis( + tr( "Click here and the pattern will be inverted." + "The points are flipped in the y direction. " ) ); + m_flipXButton->setWhatsThis( + tr( "Click here and the pattern will be reversed. " + "The points are flipped in the x direction." ) ); /*m_selectButton->setWhatsThis( tr( "Click here and select-mode will be activated. In this " "mode you can select values. This is necessary " @@ -394,6 +424,9 @@ AutomationEditor::AutomationEditor() : tb_layout->addSpacing( 10 ); tb_layout->addWidget( m_drawButton ); tb_layout->addWidget( m_eraseButton ); + tb_layout->addSpacing( 10 ); + tb_layout->addWidget( m_flipYButton ); + tb_layout->addWidget( m_flipXButton ); //tb_layout->addWidget( m_selectButton ); //tb_layout->addWidget( m_moveButton ); tb_layout->addSpacing( 10 ); @@ -2029,6 +2062,22 @@ void AutomationEditor::eraseButtonToggled() +void AutomationEditor::flipYButtonPressed() +{ + m_pattern->flipY(m_minLevel, m_maxLevel); +} + + + + +void AutomationEditor::flipXButtonPressed() +{ + m_pattern->flipX( false ); +} + + + + void AutomationEditor::selectButtonToggled() { m_editMode = SELECT; diff --git a/src/gui/AutomationPatternView.cpp b/src/gui/AutomationPatternView.cpp index 17fbb559f7c..a65fd1a08f7 100644 --- a/src/gui/AutomationPatternView.cpp +++ b/src/gui/AutomationPatternView.cpp @@ -145,6 +145,26 @@ void AutomationPatternView::toggleRecording() } + + +void AutomationPatternView::flipY() +{ + m_pat->flipY(m_pat->getMin(), m_pat->getMax()); + update(); +} + + + + +void AutomationPatternView::flipX() +{ + m_pat->flipX( true ); + update(); +} + + + + void AutomationPatternView::constructContextMenu( QMenu * _cm ) { QAction * a = new QAction( embed::getIconPixmap( "automation" ), @@ -168,6 +188,12 @@ void AutomationPatternView::constructContextMenu( QMenu * _cm ) _cm->addAction( embed::getIconPixmap( "record" ), tr( "Set/clear record" ), this, SLOT( toggleRecording() ) ); + _cm->addAction( embed::getIconPixmap( "flip_y" ), + tr( "Flip Y" ), + this, SLOT( flipY() ) ); + _cm->addAction( embed::getIconPixmap( "flip_x" ), + tr( "Flip X" ), + this, SLOT( flipX() ) ); if( !m_pat->m_objects.isEmpty() ) { _cm->addSeparator(); From bfeced71409f52e10e0689d5b58774a20e934148 Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 23 Dec 2014 10:26:54 +0100 Subject: [PATCH 2/3] Code Cleanup --- src/core/AutomationPattern.cpp | 28 ++++++++++++---------------- src/gui/AutomationEditor.cpp | 2 +- src/gui/AutomationPatternView.cpp | 2 +- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/core/AutomationPattern.cpp b/src/core/AutomationPattern.cpp index a71030dff1b..7571ddfbe08 100644 --- a/src/core/AutomationPattern.cpp +++ b/src/core/AutomationPattern.cpp @@ -392,9 +392,7 @@ void AutomationPattern::flipY( int min, int max ) int numPoints = 0; - //(iterate+1).key() - iterate.key(); gets the number of values until the next point - - for( int i = 0; (iterate + i + 1) != m_timeMap.end() && (iterate + i ) != m_timeMap.end() ; i++) + for( int i = 0; ( iterate + i + 1 ) != m_timeMap.end() && ( iterate + i ) != m_timeMap.end() ; i++) { numPoints++; } @@ -402,17 +400,15 @@ void AutomationPattern::flipY( int min, int max ) for( int i = 0; i <= numPoints; i++ ) { - if (min < 0) + if ( min < 0 ) { - tempValue = valueAt((iterate + i).key()) * -1; - //removeValue((iterate + i).key(), false); - putValue( MidiTime((iterate + i).key()) , tempValue, false); + tempValue = valueAt( ( iterate + i ).key() ) * -1; + putValue( MidiTime( (iterate + i).key() ) , tempValue, false); } else { - tempValue = max - valueAt((iterate + i).key()); - //removeValue((iterate).key(), false); - putValue( MidiTime((iterate + i).key()) , tempValue, false); + tempValue = max - valueAt( ( iterate + i ).key() ); + putValue( MidiTime( (iterate + i).key() ) , tempValue, false); } } @@ -425,7 +421,7 @@ void AutomationPattern::flipY( int min, int max ) -void AutomationPattern::flipX(bool visible) +void AutomationPattern::flipX( bool visible ) { timeMap tempMap; @@ -433,22 +429,22 @@ void AutomationPattern::flipX(bool visible) float tempValue = 0; int numPoints = 0; - //(iterate+1).key() - iterate.key(); gets the number of values until the next point + //(iterate+1).key() - iterate.key(); gets the "distance" to the next point - for( int i = 0; (iterate + i + 1) != m_timeMap.end() && (iterate + i ) != m_timeMap.end() ; i++) + for( int i = 0; ( iterate + i + 1 ) != m_timeMap.end() && ( iterate + i ) != m_timeMap.end() ; i++) { numPoints++; } - float realLength = (iterate + numPoints).key(); + float realLength = ( iterate + numPoints ).key(); for( int i = 0; i <= numPoints; i++ ) { - tempValue = valueAt((iterate + i).key()); + tempValue = valueAt( ( iterate + i ).key() ); cleanObjects(); - MidiTime newTime = MidiTime( realLength - (iterate + i).key() ); + MidiTime newTime = MidiTime( realLength - ( iterate + i ).key() ); tempMap[newTime] = tempValue; } diff --git a/src/gui/AutomationEditor.cpp b/src/gui/AutomationEditor.cpp index a05d378b326..3468299b8a6 100644 --- a/src/gui/AutomationEditor.cpp +++ b/src/gui/AutomationEditor.cpp @@ -2064,7 +2064,7 @@ void AutomationEditor::eraseButtonToggled() void AutomationEditor::flipYButtonPressed() { - m_pattern->flipY(m_minLevel, m_maxLevel); + m_pattern->flipY( m_minLevel, m_maxLevel ); } diff --git a/src/gui/AutomationPatternView.cpp b/src/gui/AutomationPatternView.cpp index a65fd1a08f7..869c1ef820f 100644 --- a/src/gui/AutomationPatternView.cpp +++ b/src/gui/AutomationPatternView.cpp @@ -149,7 +149,7 @@ void AutomationPatternView::toggleRecording() void AutomationPatternView::flipY() { - m_pat->flipY(m_pat->getMin(), m_pat->getMax()); + m_pat->flipY( m_pat->getMin(), m_pat->getMax() ); update(); } From ddbf9cd26448ac4b779cf39aaeaf6c9ac650a52b Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 23 Dec 2014 19:23:35 +0100 Subject: [PATCH 3/3] Fixes flipping visiblesegment horizontally --- include/AutomationPattern.h | 2 +- src/core/AutomationPattern.cpp | 63 +++++++++++++++++++++++++------ src/gui/AutomationEditor.cpp | 2 +- src/gui/AutomationPatternView.cpp | 7 ++-- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/include/AutomationPattern.h b/include/AutomationPattern.h index 9035491b30b..d95b6f3d268 100644 --- a/include/AutomationPattern.h +++ b/include/AutomationPattern.h @@ -171,7 +171,7 @@ public slots: void openInAutomationEditor(); void objectDestroyed( jo_id_t ); void flipY( int min, int max ); - void flipX( bool visible ); + void flipX( int length = -1 ); private: void cleanObjects(); diff --git a/src/core/AutomationPattern.cpp b/src/core/AutomationPattern.cpp index 7571ddfbe08..7ab4b597720 100644 --- a/src/core/AutomationPattern.cpp +++ b/src/core/AutomationPattern.cpp @@ -421,7 +421,7 @@ void AutomationPattern::flipY( int min, int max ) -void AutomationPattern::flipX( bool visible ) +void AutomationPattern::flipX( int length ) { timeMap tempMap; @@ -429,26 +429,65 @@ void AutomationPattern::flipX( bool visible ) float tempValue = 0; int numPoints = 0; - //(iterate+1).key() - iterate.key(); gets the "distance" to the next point - for( int i = 0; ( iterate + i + 1 ) != m_timeMap.end() && ( iterate + i ) != m_timeMap.end() ; i++) { numPoints++; } float realLength = ( iterate + numPoints ).key(); - - for( int i = 0; i <= numPoints; i++ ) - { - tempValue = valueAt( ( iterate + i ).key() ); - cleanObjects(); - - MidiTime newTime = MidiTime( realLength - ( iterate + i ).key() ); + if ( length != -1 && length != realLength) + { + if ( realLength < length ) + { + tempValue = valueAt( ( iterate + numPoints ).key() ); + putValue( MidiTime( length ) , tempValue, false); + numPoints++; + for( int i = 0; i <= numPoints; i++ ) + { + tempValue = valueAt( ( iterate + i ).key() ); + cleanObjects(); + MidiTime newTime = MidiTime( length - ( iterate + i ).key() ); + tempMap[newTime] = tempValue; + } + } + else + { + //for ( int i = 0; ( iterate + i ).key() < length ; i++ ) + //{ + // tempValue = valueAt( ( iterate + i ).key() ); + //} + //putValue( MidiTime( length ) , tempValue, false); + //numPoints++; + for( int i = 0; i <= numPoints; i++ ) + { + tempValue = valueAt( ( iterate + i ).key() ); + cleanObjects(); + MidiTime newTime; - tempMap[newTime] = tempValue; + if ( ( iterate + i ).key() <= length ) + { + newTime = MidiTime( length - ( iterate + i ).key() ); + } + else + { + newTime = MidiTime( ( iterate + i ).key() ); + } + tempMap[newTime] = tempValue; + } + } } - + else + { + for( int i = 0; i <= numPoints; i++ ) + { + tempValue = valueAt( ( iterate + i ).key() ); + cleanObjects(); + MidiTime newTime = MidiTime( realLength - ( iterate + i ).key() ); + tempMap[newTime] = tempValue; + } + } + m_timeMap.clear(); m_timeMap = tempMap; diff --git a/src/gui/AutomationEditor.cpp b/src/gui/AutomationEditor.cpp index 3468299b8a6..2d28bd8f19a 100644 --- a/src/gui/AutomationEditor.cpp +++ b/src/gui/AutomationEditor.cpp @@ -2072,7 +2072,7 @@ void AutomationEditor::flipYButtonPressed() void AutomationEditor::flipXButtonPressed() { - m_pattern->flipX( false ); + m_pattern->flipX(); } diff --git a/src/gui/AutomationPatternView.cpp b/src/gui/AutomationPatternView.cpp index 869c1ef820f..1c404e6ef6f 100644 --- a/src/gui/AutomationPatternView.cpp +++ b/src/gui/AutomationPatternView.cpp @@ -158,7 +158,8 @@ void AutomationPatternView::flipY() void AutomationPatternView::flipX() { - m_pat->flipX( true ); + //m_pat->flipX( m_pat->length() ); + m_pat->flipX( m_pat->TrackContentObject::length() ); update(); } @@ -189,10 +190,10 @@ void AutomationPatternView::constructContextMenu( QMenu * _cm ) tr( "Set/clear record" ), this, SLOT( toggleRecording() ) ); _cm->addAction( embed::getIconPixmap( "flip_y" ), - tr( "Flip Y" ), + tr( "Flip Vertically (Visible)" ), this, SLOT( flipY() ) ); _cm->addAction( embed::getIconPixmap( "flip_x" ), - tr( "Flip X" ), + tr( "Flip Horizontally (Visible)" ), this, SLOT( flipX() ) ); if( !m_pat->m_objects.isEmpty() ) {