From b01980d2fbc9b67076ea9c43ddf3159cd7485dab Mon Sep 17 00:00:00 2001 From: regulus79 <117475203+regulus79@users.noreply.github.com> Date: Sun, 30 Nov 2025 15:11:57 -0500 Subject: [PATCH] Add Setting for Default Autoscroll State (#7851) Previously, the autoscroll state of the song editor and piano roll (continuous, stepped, none) was not saved. This can be an issue for users who want to permanently set their autoscroll settings, without having to change them every time they start up LMMS. This PR adds an option in the settings window to change the default autoscroll state. --- include/SetupDialog.h | 2 ++ include/TimeLineWidget.h | 19 +++++++++++++------ src/gui/editors/TimeLineWidget.cpp | 12 ++++++++++++ src/gui/modals/SetupDialog.cpp | 14 ++++++++++++++ 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/include/SetupDialog.h b/include/SetupDialog.h index c314ff42d..a382df917 100644 --- a/include/SetupDialog.h +++ b/include/SetupDialog.h @@ -149,6 +149,8 @@ private: bool m_openLastProject; QString m_loopMarkerMode; QComboBox* m_loopMarkerComboBox; + QString m_autoScroll; + QComboBox* m_autoScrollComboBox; QString m_lang; QStringList m_languages; diff --git a/include/TimeLineWidget.h b/include/TimeLineWidget.h index b1861f67c..2f40077ff 100644 --- a/include/TimeLineWidget.h +++ b/include/TimeLineWidget.h @@ -48,6 +48,8 @@ namespace lmms::gui class TextFloat; + + class TimeLineWidget : public QWidget { Q_OBJECT @@ -67,6 +69,10 @@ public: Q_PROPERTY(QSize mouseHotspotSelLeft READ mouseHotspotSelLeft WRITE setMouseHotspotSelLeft) Q_PROPERTY(QSize mouseHotspotSelRight READ mouseHotspotSelRight WRITE setMouseHotspotSelRight) + static constexpr const char* AutoScrollDisabledString = "disabled"; + static constexpr const char* AutoScrollSteppedString = "stepped"; + static constexpr const char* AutoScrollContinuousString = "continuous"; + enum class AutoScrollState { Stepped, @@ -132,10 +138,8 @@ public: return( m_pos ); } - AutoScrollState autoScroll() const - { - return m_autoScroll; - } + AutoScrollState autoScroll() const { return m_autoScroll; } + void setAutoScroll(AutoScrollState state) { m_autoScroll = state; } inline void setPixelsPerBar( float ppb ) { @@ -153,6 +157,8 @@ public: m_ppb / TimePos::ticksPerBar() ); } + static AutoScrollState defaultAutoScrollState(); + signals: void positionChanged(const lmms::TimePos& postion); void regionSelectedFromPixels( int, int ); @@ -209,8 +215,6 @@ private: QCursor m_cursorSelectLeft = QCursor{embed::getIconPixmap("cursor_select_left"), 0, 16}; QCursor m_cursorSelectRight = QCursor{embed::getIconPixmap("cursor_select_right"), 32, 16}; - AutoScrollState m_autoScroll = AutoScrollState::Stepped; - // Width of the unused region on the widget's left (above track labels or piano) int m_xOffset; float m_ppb; @@ -220,6 +224,9 @@ private: // Leftmost position visible in parent editor const TimePos & m_begin; const Song::PlayMode m_mode; + + AutoScrollState m_autoScroll = defaultAutoScrollState(); + // When in MoveLoop mode we need the initial positions. Storing only the latest // position allows for unquantized drag but fails when toggling quantization. std::array m_oldLoopPos; diff --git a/src/gui/editors/TimeLineWidget.cpp b/src/gui/editors/TimeLineWidget.cpp index a10d2dc07..0e74ff445 100644 --- a/src/gui/editors/TimeLineWidget.cpp +++ b/src/gui/editors/TimeLineWidget.cpp @@ -90,6 +90,7 @@ void TimeLineWidget::addToolButtons( QToolBar * _tool_bar ) autoScroll->addState(embed::getIconPixmap("autoscroll_stepped_on"), tr("Stepped auto scrolling")); autoScroll->addState(embed::getIconPixmap("autoscroll_continuous_on"), tr("Continuous auto scrolling")); autoScroll->addState(embed::getIconPixmap("autoscroll_off"), tr("Auto scrolling disabled")); + autoScroll->changeState(static_cast(m_autoScroll)); connect( autoScroll, SIGNAL(changedState(int)), this, SLOT(toggleAutoScroll(int))); @@ -459,4 +460,15 @@ void TimeLineWidget::contextMenuEvent(QContextMenuEvent* event) menu.exec(event->globalPos()); } + +TimeLineWidget::AutoScrollState TimeLineWidget::defaultAutoScrollState() +{ + QString autoScrollState = ConfigManager::inst()->value("ui", "autoscroll"); + if (autoScrollState == AutoScrollSteppedString) { return AutoScrollState::Stepped; } + else if (autoScrollState == AutoScrollContinuousString) { return AutoScrollState::Continuous; } + else if (autoScrollState == AutoScrollDisabledString) { return AutoScrollState::Disabled; } + else { return AutoScrollState::Stepped; } +} + + } // namespace lmms::gui diff --git a/src/gui/modals/SetupDialog.cpp b/src/gui/modals/SetupDialog.cpp index d7e3dcf93..d31657ab8 100644 --- a/src/gui/modals/SetupDialog.cpp +++ b/src/gui/modals/SetupDialog.cpp @@ -42,6 +42,7 @@ #include "SetupDialog.h" #include "TabBar.h" #include "TabButton.h" +#include "TimeLineWidget.h" // Platform-specific audio-interface classes. @@ -119,6 +120,7 @@ SetupDialog::SetupDialog(ConfigTab tab_to_open) : m_openLastProject(ConfigManager::inst()->value( "app", "openlastproject").toInt()), m_loopMarkerMode{ConfigManager::inst()->value("app", "loopmarkermode", "dual")}, + m_autoScroll(ConfigManager::inst()->value("ui", "autoscroll", "stepped")), m_lang(ConfigManager::inst()->value( "app", "language")), m_saveInterval( ConfigManager::inst()->value( @@ -268,6 +270,17 @@ SetupDialog::SetupDialog(ConfigTab tab_to_open) : guiGroupLayout->addWidget(new QLabel{tr("Loop edit mode"), guiGroupBox}); guiGroupLayout->addWidget(m_loopMarkerComboBox); + m_autoScrollComboBox = new QComboBox{guiGroupBox}; + m_autoScrollComboBox->addItem(tr("Disabled"), TimeLineWidget::AutoScrollDisabledString); + m_autoScrollComboBox->addItem(tr("Stepped (Scroll once the playhead goes out of view)"), TimeLineWidget::AutoScrollSteppedString); + m_autoScrollComboBox->addItem(tr("Continuous (Scroll constantly to keep the playhead in the center)"), TimeLineWidget::AutoScrollContinuousString); + m_autoScrollComboBox->setCurrentIndex(m_autoScrollComboBox->findData(m_autoScroll)); + connect(m_autoScrollComboBox, qOverload(&QComboBox::currentIndexChanged), + this, [this](){ m_autoScroll = m_autoScrollComboBox->currentData().toString(); }); + + guiGroupLayout->addWidget(new QLabel{tr("Default Autoscroll Mode"), guiGroupBox}); + guiGroupLayout->addWidget(m_autoScrollComboBox); + generalControlsLayout->addWidget(guiGroupBox); generalControlsLayout->addSpacing(10); @@ -980,6 +993,7 @@ void SetupDialog::accept() QString::number(m_openLastProject)); ConfigManager::inst()->setValue("app", "loopmarkermode", m_loopMarkerMode); ConfigManager::inst()->setValue("app", "language", m_lang); + ConfigManager::inst()->setValue("ui", "autoscroll", m_autoScroll); ConfigManager::inst()->setValue("ui", "saveinterval", QString::number(m_saveInterval)); ConfigManager::inst()->setValue("ui", "enableautosave",