feat: option to disable gallery looping

This change is sponsored by @superuser7777

Related: https://github.com/BLumia/pineapple-pictures/issues/153
This commit is contained in:
Gary Wang 2025-06-25 20:55:42 +08:00
parent 2bee79c064
commit b566096b1f
No known key found for this signature in database
GPG Key ID: 5D30A4F15EA78760
8 changed files with 62 additions and 12 deletions

View File

@ -139,10 +139,7 @@ MainWindow::MainWindow(QWidget *parent)
m_gv->setOpacity(0, false);
m_closeButton->setOpacity(0, false);
connect(m_pm, &PlaylistManager::totalCountChanged, this, [this](int galleryFileCount) {
m_prevButton->setVisible(galleryFileCount > 1);
m_nextButton->setVisible(galleryFileCount > 1);
});
connect(m_pm, &PlaylistManager::totalCountChanged, this, &MainWindow::updateGalleryButtonsVisibility);
connect(m_pm->model(), &PlaylistModel::modelReset, this, std::bind(&MainWindow::galleryCurrent, this, false, false));
connect(m_pm, &PlaylistManager::currentIndexChanged, this, std::bind(&MainWindow::galleryCurrent, this, true, false));
@ -279,6 +276,8 @@ void MainWindow::galleryCurrent(bool showLoadImageHintWhenEmpty, bool reloadImag
m_graphicsView->showText(QCoreApplication::translate("GraphicsScene", "Drag image here"));
}
updateGalleryButtonsVisibility();
if (shouldResetfileWatcher) updateFileWatcher();
}
@ -603,8 +602,7 @@ void MainWindow::toggleProtectedMode()
{
m_protectedMode = !m_protectedMode;
m_closeButton->setVisible(!m_protectedMode);
m_prevButton->setVisible(!m_protectedMode);
m_nextButton->setVisible(!m_protectedMode);
updateGalleryButtonsVisibility();
}
void MainWindow::toggleStayOnTop()
@ -927,3 +925,13 @@ bool MainWindow::updateFileWatcher(const QString &basePath)
if (!basePath.isEmpty()) return m_fileSystemWatcher->addPath(basePath);
return false;
}
void MainWindow::updateGalleryButtonsVisibility()
{
const int galleryFileCount = m_pm->totalCount();
const bool loopGallery = Settings::instance()->loopGallery();
m_prevButton->setVisible(!m_protectedMode && galleryFileCount > 1);
m_nextButton->setVisible(!m_protectedMode && galleryFileCount > 1);
m_prevButton->setEnabled(loopGallery || !m_pm->isFirstIndex());
m_nextButton->setEnabled(loopGallery || !m_pm->isLastIndex());
}

View File

@ -110,6 +110,7 @@ private slots:
private:
bool updateFileWatcher(const QString & basePath = QString());
void updateGalleryButtonsVisibility();
private:
ActionManager *m_am;

View File

@ -196,7 +196,7 @@ QModelIndex PlaylistManager::previousIndex() const
int count = totalCount();
if (count == 0) return {};
return m_model.index(m_currentIndex - 1 < 0 ? count - 1 : m_currentIndex - 1);
return m_model.index(isFirstIndex() ? count - 1 : m_currentIndex - 1);
}
QModelIndex PlaylistManager::nextIndex() const
@ -204,7 +204,7 @@ QModelIndex PlaylistManager::nextIndex() const
int count = totalCount();
if (count == 0) return {};
return m_model.index(m_currentIndex + 1 == count ? 0 : m_currentIndex + 1);
return m_model.index(isLastIndex() ? 0 : m_currentIndex + 1);
}
QModelIndex PlaylistManager::curIndex() const
@ -212,6 +212,16 @@ QModelIndex PlaylistManager::curIndex() const
return m_model.index(m_currentIndex);
}
bool PlaylistManager::isFirstIndex() const
{
return m_currentIndex == 0;
}
bool PlaylistManager::isLastIndex() const
{
return m_currentIndex + 1 == totalCount();
}
void PlaylistManager::setCurrentIndex(const QModelIndex &index)
{
if (index.isValid() && index.row() >= 0 && index.row() < totalCount()) {

View File

@ -62,10 +62,12 @@ public:
Q_INVOKABLE QModelIndex loadPlaylist(const QList<QUrl> & urls);
Q_INVOKABLE QModelIndex loadPlaylist(const QUrl & url);
int totalCount() const;
inline int totalCount() const;
QModelIndex previousIndex() const;
QModelIndex nextIndex() const;
QModelIndex curIndex() const;
inline bool isFirstIndex() const;
inline bool isLastIndex() const;
void setCurrentIndex(const QModelIndex & index);
QUrl urlByIndex(const QModelIndex & index);
QString localFileByIndex(const QModelIndex & index);

View File

@ -60,6 +60,11 @@ bool Settings::useLightCheckerboard() const
return m_qsettings->value("use_light_checkerboard", false).toBool();
}
bool Settings::loopGallery() const
{
return m_qsettings->value("loop_gallery", true).toBool();
}
Settings::DoubleClickBehavior Settings::doubleClickBehavior() const
{
QString result = m_qsettings->value("double_click_behavior", "Close").toString();
@ -106,6 +111,12 @@ void Settings::setUseLightCheckerboard(bool light)
m_qsettings->sync();
}
void Settings::setLoopGallery(bool on)
{
m_qsettings->setValue("loop_gallery", on);
m_qsettings->sync();
}
void Settings::setDoubleClickBehavior(DoubleClickBehavior dcb)
{
m_qsettings->setValue("double_click_behavior", QEnumHelper::toString(dcb));

View File

@ -37,6 +37,7 @@ public:
bool stayOnTop() const;
bool useBuiltInCloseAnimation() const;
bool useLightCheckerboard() const;
bool loopGallery() const;
DoubleClickBehavior doubleClickBehavior() const;
MouseWheelBehavior mouseWheelBehavior() const;
WindowSizeBehavior initWindowSizeBehavior() const;
@ -45,6 +46,7 @@ public:
void setStayOnTop(bool on);
void setUseBuiltInCloseAnimation(bool on);
void setUseLightCheckerboard(bool light);
void setLoopGallery(bool on);
void setDoubleClickBehavior(DoubleClickBehavior dcb);
void setMouseWheelBehavior(MouseWheelBehavior mwb);
void setInitWindowSizeBehavior(WindowSizeBehavior wsb);

View File

@ -22,6 +22,7 @@ SettingsDialog::SettingsDialog(QWidget *parent)
, m_stayOnTop(new QCheckBox)
, m_useBuiltInCloseAnimation(new QCheckBox)
, m_useLightCheckerboard(new QCheckBox)
, m_loopGallery(new QCheckBox)
, m_doubleClickBehavior(new QComboBox)
, m_mouseWheelBehavior(new QComboBox)
, m_initWindowSizeBehavior(new QComboBox)
@ -121,6 +122,7 @@ SettingsDialog::SettingsDialog(QWidget *parent)
settingsForm->addRow(tr("Stay on top when start-up"), m_stayOnTop);
settingsForm->addRow(tr("Use built-in close window animation"), m_useBuiltInCloseAnimation);
settingsForm->addRow(tr("Use light-color checkerboard"), m_useLightCheckerboard);
settingsForm->addRow(tr("Loop the loaded gallery"), m_loopGallery);
settingsForm->addRow(tr("Double-click behavior"), m_doubleClickBehavior);
settingsForm->addRow(tr("Mouse wheel behavior"), m_mouseWheelBehavior);
settingsForm->addRow(tr("Default window size"), m_initWindowSizeBehavior);
@ -129,6 +131,7 @@ SettingsDialog::SettingsDialog(QWidget *parent)
m_stayOnTop->setChecked(Settings::instance()->stayOnTop());
m_useBuiltInCloseAnimation->setChecked(Settings::instance()->useBuiltInCloseAnimation());
m_useLightCheckerboard->setChecked(Settings::instance()->useLightCheckerboard());
m_loopGallery->setChecked(Settings::instance()->loopGallery());
m_doubleClickBehavior->setModel(new QStringListModel(dcbDropDown));
Settings::DoubleClickBehavior dcb = Settings::instance()->doubleClickBehavior();
m_doubleClickBehavior->setCurrentIndex(static_cast<int>(dcb));
@ -147,18 +150,30 @@ SettingsDialog::SettingsDialog(QWidget *parent)
}
}
connect(m_stayOnTop, &QCheckBox::stateChanged, this, [ = ](int state){
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
# define QCHECKBOX_CHECKSTATECHANGED QCheckBox::checkStateChanged
# define QT_CHECKSTATE Qt::CheckState
#else
# define QCHECKBOX_CHECKSTATECHANGED QCheckBox::stateChanged
# define QT_CHECKSTATE int
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
connect(m_stayOnTop, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
Settings::instance()->setStayOnTop(state == Qt::Checked);
});
connect(m_useBuiltInCloseAnimation, &QCheckBox::stateChanged, this, [ = ](int state){
connect(m_useBuiltInCloseAnimation, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
Settings::instance()->setUseBuiltInCloseAnimation(state == Qt::Checked);
});
connect(m_useLightCheckerboard, &QCheckBox::stateChanged, this, [ = ](int state){
connect(m_useLightCheckerboard, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
Settings::instance()->setUseLightCheckerboard(state == Qt::Checked);
});
connect(m_loopGallery, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
Settings::instance()->setLoopGallery(state == Qt::Checked);
});
connect(m_doubleClickBehavior, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [ = ](int index){
Settings::instance()->setDoubleClickBehavior(_dc_options.at(index).first);
});

View File

@ -25,6 +25,7 @@ private:
QCheckBox * m_stayOnTop = nullptr;
QCheckBox * m_useBuiltInCloseAnimation = nullptr;
QCheckBox * m_useLightCheckerboard = nullptr;
QCheckBox * m_loopGallery = nullptr;
QComboBox * m_doubleClickBehavior = nullptr;
QComboBox * m_mouseWheelBehavior = nullptr;
QComboBox * m_initWindowSizeBehavior = nullptr;