From e8b69b97004ce2e6cf798c80e75a8a83bafd346a Mon Sep 17 00:00:00 2001 From: Premik Date: Thu, 10 May 2018 00:45:45 +0200 Subject: [PATCH] Zooming with mouse wheel center (#3835) * Horizontal mouse-wheel zooming. Ensure zoom center is always on the current mouse position. * Horizontal zoom using mouse wheel center on the mouse position. For the SongEditor too. * Wheel center on the Automation editor too. --- include/SongEditor.h | 1 + src/gui/editors/AutomationEditor.cpp | 11 +++++++++++ src/gui/editors/PianoRoll.cpp | 8 ++++++++ src/gui/editors/SongEditor.cpp | 14 ++++++++++++-- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/include/SongEditor.h b/include/SongEditor.h index d6e904acecf..e31d0f862d8 100644 --- a/include/SongEditor.h +++ b/include/SongEditor.h @@ -135,6 +135,7 @@ private slots: bool m_scrollBack; bool m_smoothScroll; + int m_widgetWidthTotal; EditMode m_mode; EditMode m_ctrlMode; // mode they were in before they hit ctrl diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 2e0c68cd56d..6743a7ca01e 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -1680,6 +1680,17 @@ void AutomationEditor::wheelEvent(QWheelEvent * we ) x--; } x = qBound( 0, x, m_zoomingXModel.size() - 1 ); + + int mouseX = (we->x() - VALUES_WIDTH)* MidiTime::ticksPerTact(); + // ticks based on the mouse x-position where the scroll wheel was used + int ticks = mouseX / m_ppt; + // what would be the ticks in the new zoom level on the very same mouse x + int newTicks = mouseX / (DEFAULT_PPT * m_zoomXLevels[x]); + + // scroll so the tick "selected" by the mouse x doesn't move on the screen + m_leftRightScroll->setValue(m_leftRightScroll->value() + ticks - newTicks); + + m_zoomingXModel.setValue( x ); } else if( we->modifiers() & Qt::ShiftModifier diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 17fc7bd2e78..983d2eb7b5f 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -3296,6 +3296,14 @@ void PianoRoll::wheelEvent(QWheelEvent * we ) z--; } z = qBound( 0, z, m_zoomingModel.size() - 1 ); + + int x = (we->x() - WHITE_KEY_WIDTH)* MidiTime::ticksPerTact(); + // ticks based on the mouse x-position where the scroll wheel was used + int ticks = x / m_ppt; + // what would be the ticks in the new zoom level on the very same mouse x + int newTicks = x / (DEFAULT_PR_PPT * m_zoomLevels[z]); + // scroll so the tick "selected" by the mouse x doesn't move on the screen + m_leftRightScroll->setValue(m_leftRightScroll->value() + ticks - newTicks); // update combobox with zooming-factor m_zoomingModel.setValue( z ); } diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index 320003178f7..52e91a26061 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -82,11 +82,11 @@ SongEditor::SongEditor( Song * song ) : { m_zoomingModel->setParent(this); // create time-line - int widgetTotal = ConfigManager::inst()->value( "ui", + m_widgetWidthTotal = ConfigManager::inst()->value( "ui", "compacttrackbuttons" ).toInt()==1 ? DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT : DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH; - m_timeLine = new TimeLineWidget( widgetTotal, 32, + m_timeLine = new TimeLineWidget( m_widgetWidthTotal, 32, pixelsPerTact(), m_song->m_playPos[Song::Mode_PlaySong], m_currentPosition, @@ -385,6 +385,16 @@ void SongEditor::wheelEvent( QWheelEvent * we ) z--; } z = qBound( 0, z, m_zoomingModel->size() - 1 ); + + + int x = (we->x() - m_widgetWidthTotal); + // tact based on the mouse x-position where the scroll wheel was used + int tact= x / pixelsPerTact(); + // what would be the tact in the new zoom level on the very same mouse x + int newTact = x / DEFAULT_PIXELS_PER_TACT / m_zoomLevels[z]; + // scroll so the tact "selected" by the mouse x doesn't move on the screen + m_leftRightScroll->setValue(m_leftRightScroll->value() + tact - newTact); + // update combobox with zooming-factor m_zoomingModel->setValue( z );