refactor: state machine

This commit is contained in:
2025-08-08 04:17:15 +02:00
parent 490f924bcc
commit 7398e61f00
4 changed files with 133 additions and 39 deletions
+3 -2
View File
@@ -4,7 +4,8 @@
"~/Pictures/116327446_p0.jpg"
],
"dirs": [
"~/.config/backgrounds"
"~/.config/backgrounds",
"/run/media/kolkas/移硬1T/逆流茶会/"
],
"excludes": [
"~/.config/backgrounds/nao-stars-crop-adjust-flop.jpg",
@@ -21,7 +22,7 @@
"image_focus_width": 480,
"window_width": 750,
"window_height": 500,
"no_loading_screen": false
"no_loading_screen": true
},
"sort": {
"type": "name",
+1 -1
View File
@@ -1,7 +1,7 @@
/*
* @Author: Uyanide pywang0608@foxmail.com
* @Date: 2025-08-05 01:22:53
* @LastEditTime: 2025-08-08 02:34:24
* @LastEditTime: 2025-08-08 04:05:07
* @Description: Animated carousel widget for displaying and selecting images.
*/
#include "images_carousel.h"
+114 -30
View File
@@ -1,7 +1,7 @@
/*
* @Author: Uyanide pywang0608@foxmail.com
* @Date: 2025-08-05 00:37:58
* @LastEditTime: 2025-08-08 02:25:20
* @LastEditTime: 2025-08-08 04:04:17
* @Description: MainWindow implementation.
*/
#include "main_window.h"
@@ -44,13 +44,6 @@ void MainWindow::_setupUI() {
this,
&MainWindow::_onImageFocused);
connect(this, &MainWindow::stop, m_carousel, &ImagesCarousel::onStop);
connect(m_carousel, &ImagesCarousel::stopped, this,
// &MainWindow::close); // instead of closing, we just stop the loading
[this]() {
_onLoadingCompleted(m_carousel->getLoadedImagesCount());
m_carousel->focusCurrImage(); },
// ensure this is called in the main thread
Qt::QueuedConnection);
m_carouselIndex = ui->stackedWidget->addWidget(m_carousel);
// create loading indicator
@@ -76,11 +69,11 @@ void MainWindow::_setupUI() {
connect(ui->confirmButton,
&QPushButton::clicked,
this,
&MainWindow::onConfirm);
&MainWindow::_onConfirmPressed);
connect(ui->cancelButton,
&QPushButton::clicked,
this,
&MainWindow::onCancel);
&MainWindow::_onCancelPressed);
ui->confirmButton->setFocusPolicy(Qt::NoFocus);
ui->cancelButton->setFocusPolicy(Qt::NoFocus);
@@ -89,23 +82,123 @@ void MainWindow::_setupUI() {
void MainWindow::keyPressEvent(QKeyEvent *event) {
if (event->key() == Qt::Key_Escape) {
onCancel();
} else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
onConfirm();
_onCancelPressed();
return;
}
// if loadingScreen is enabled and loading is in progress, ignore other keys
else if (!m_config.getStyleConfig().noLoadingScreen && m_isLoading) {
event->ignore();
} else if (event->key() == Qt::Key_Space || event->key() == Qt::Key_Tab || event->key() == Qt::Key_Right) {
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
_onConfirmPressed();
return;
}
switch (m_state) {
case Init:
MainWindow::keyPressEvent(event);
break;
case Loading:
if (m_config.getStyleConfig().noLoadingScreen) {
switch (event->key()) {
case Qt::Key_Space:
case Qt::Key_Tab:
case Qt::Key_Right:
m_carousel->focusNextImage();
} else if (event->key() == Qt::Key_Left) {
break;
case Qt::Key_Left:
m_carousel->focusPrevImage();
} else {
break;
default:
QMainWindow::keyPressEvent(event);
}
} else {
event->ignore();
}
break;
case Ready:
switch (event->key()) {
case Qt::Key_Space:
case Qt::Key_Tab:
case Qt::Key_Right:
m_carousel->focusNextImage();
break;
case Qt::Key_Left:
m_carousel->focusPrevImage();
break;
default:
QMainWindow::keyPressEvent(event);
}
break;
default:
event->ignore();
break;
}
}
void MainWindow::_onCancelPressed() {
switch (m_state) {
case Loading:
// case loading screen is disabled, quit the app
if (m_config.getStyleConfig().noLoadingScreen) {
info("Stopping loading and quitting app.");
connect(
m_carousel,
&ImagesCarousel::stopped,
this,
&MainWindow::onCancel);
m_state = Stopping;
emit stop();
}
// otherwise, stop loading and display the loaded images
else {
info("Stopping loading.");
connect(
m_carousel,
&ImagesCarousel::stopped,
this,
[this]() {
_onLoadingCompleted(m_carousel->getLoadedImagesCount());
m_carousel->focusCurrImage();
});
m_state = Stopping;
emit stop();
}
break;
case Ready:
info("Quitting app.");
onCancel();
break;
default:
break;
}
}
void MainWindow::_onConfirmPressed() {
switch (m_state) {
case Loading:
// case loading screen is disabled, confirm the selection
if (m_config.getStyleConfig().noLoadingScreen) {
info("Stopping loading and confirming selection.");
connect(
m_carousel,
&ImagesCarousel::stopped,
this,
&MainWindow::onConfirm);
m_state = Stopping;
emit stop();
}
break;
case Ready:
info("Confirming selection.");
onConfirm();
break;
default:
break;
}
}
void MainWindow::wheelEvent(QWheelEvent *event) {
if (m_state != Ready && m_config.getStyleConfig().noLoadingScreen) {
event->ignore();
return;
}
if (event->angleDelta().y() > 0) {
m_carousel->focusPrevImage();
} else if (event->angleDelta().y() < 0) {
@@ -116,10 +209,6 @@ void MainWindow::wheelEvent(QWheelEvent *event) {
}
void MainWindow::onConfirm() {
if (m_isLoading) {
warn("Loading is still in progress, please wait until it finishes.");
return;
}
close();
const auto path = m_carousel->getCurrentImagePath();
if (path.isEmpty()) {
@@ -144,20 +233,15 @@ void MainWindow::onConfirm() {
}
void MainWindow::onCancel() {
if (m_isLoading) {
warn("Loading stopped by user, waiting all threads to finish...");
emit stop();
} else {
close();
}
}
void MainWindow::_onImageFocused(const QString &path, const int index, const int count) {
ui->topLabel->setText(QString("%1 (%2/%3)").arg(splitNameFromPath(path)).arg(index + 1).arg(count));
}
void MainWindow::_onLoadingStarted(const qsizetype amount) {
m_isLoading = true;
m_state = Loading;
if (m_config.getStyleConfig().noLoadingScreen) {
return;
}
@@ -168,5 +252,5 @@ void MainWindow::_onLoadingStarted(const qsizetype amount) {
void MainWindow::_onLoadingCompleted(const qsizetype amount) {
info(QString("Loading completed, loaded %1 images").arg(amount));
ui->stackedWidget->setCurrentIndex(m_carouselIndex);
m_isLoading = false;
m_state = Ready;
}
+11 -2
View File
@@ -1,7 +1,7 @@
/*
* @Author: Uyanide pywang0608@foxmail.com
* @Date: 2025-08-05 00:37:58
* @LastEditTime: 2025-08-08 02:11:57
* @LastEditTime: 2025-08-08 03:37:24
* @Description: MainWindow implementation.
*/
#ifndef MAINWINDOW_H
@@ -44,13 +44,22 @@ class MainWindow : public QMainWindow {
void _onLoadingStarted(const qsizetype amount);
void _onLoadingCompleted(const qsizetype amount);
void _onCancelPressed();
void _onConfirmPressed();
private:
enum _State {
Init,
Loading,
Stopping,
Ready,
} m_state = Init;
Ui::MainWindow *ui;
ImagesCarousel *m_carousel = nullptr;
LoadingIndicator *m_loadingIndicator = nullptr;
int m_carouselIndex, m_loadingIndicatorIndex;
const Config &m_config;
bool m_isLoading = false;
signals:
void stop();