diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index 83b0a022b..fe46c9af0 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 @@ private: 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 @@ private: 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 b6259b3c5..9035491b3 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 2c2a6c96b..76b2e1a47 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 9164e733d..a71030dff 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 cb90253b4..a05d378b3 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 17fbb559f..a65fd1a08 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();