feat: sorting
This commit is contained in:
@@ -21,5 +21,9 @@
|
|||||||
"image_focus_width": 480,
|
"image_focus_width": 480,
|
||||||
"window_width": 750,
|
"window_width": 750,
|
||||||
"window_height": 500
|
"window_height": 500
|
||||||
|
},
|
||||||
|
"sort": {
|
||||||
|
"type": "size",
|
||||||
|
"reverse": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+25
-1
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: Uyanide pywang0608@foxmail.com
|
* @Author: Uyanide pywang0608@foxmail.com
|
||||||
* @Date: 2025-08-05 01:34:52
|
* @Date: 2025-08-05 01:34:52
|
||||||
* @LastEditTime: 2025-08-05 20:11:11
|
* @LastEditTime: 2025-08-06 00:23:54
|
||||||
* @Description: Configuration manager.
|
* @Description: Configuration manager.
|
||||||
*/
|
*/
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -99,6 +99,29 @@ void Config::_loadConfig(const QString &configPath) {
|
|||||||
info(QString("Window height: %1").arg(m_configItems.styleWindowHeight));
|
info(QString("Window height: %1").arg(m_configItems.styleWindowHeight));
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
|
{"sort.type", "type", [this](const QJsonValue &val) {
|
||||||
|
if (val.isString()) {
|
||||||
|
QString type = val.toString().toLower();
|
||||||
|
if (type == "none") {
|
||||||
|
m_configItems.sortType = SortType::None;
|
||||||
|
} else if (type == "name") {
|
||||||
|
m_configItems.sortType = SortType::Name;
|
||||||
|
} else if (type == "date") {
|
||||||
|
m_configItems.sortType = SortType::Date;
|
||||||
|
} else if (type == "size") {
|
||||||
|
m_configItems.sortType = SortType::Size;
|
||||||
|
} else {
|
||||||
|
warn(QString("Unknown sort type: %1").arg(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info(QString("Sort type: %1").arg(static_cast<int>(m_configItems.sortType)));
|
||||||
|
}},
|
||||||
|
{"sort.reverse", "reverse", [this](const QJsonValue &val) {
|
||||||
|
if (val.isBool()) {
|
||||||
|
m_configItems.sortReverse = val.toBool();
|
||||||
|
info(QString("Sort reverse: %1").arg(m_configItems.sortReverse));
|
||||||
|
}
|
||||||
|
}},
|
||||||
};
|
};
|
||||||
|
|
||||||
// 统一解析
|
// 统一解析
|
||||||
@@ -180,6 +203,7 @@ void Config::_loadWallpapers() {
|
|||||||
m_wallpapers.append(path);
|
m_wallpapers.append(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info(QString("Found %1 wallpapers").arg(paths.size()));
|
info(QString("Found %1 wallpapers").arg(paths.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-3
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: Uyanide pywang0608@foxmail.com
|
* @Author: Uyanide pywang0608@foxmail.com
|
||||||
* @Date: 2025-08-05 01:34:52
|
* @Date: 2025-08-05 01:34:52
|
||||||
* @LastEditTime: 2025-08-05 20:12:47
|
* @LastEditTime: 2025-08-06 00:23:45
|
||||||
* @Description: Configuration manager.
|
* @Description: Configuration manager.
|
||||||
*/
|
*/
|
||||||
#ifndef CONFIG_H
|
#ifndef CONFIG_H
|
||||||
@@ -15,6 +15,13 @@ class Config : public QObject {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum class SortType : int {
|
||||||
|
None = 0,
|
||||||
|
Name,
|
||||||
|
Date,
|
||||||
|
Size,
|
||||||
|
};
|
||||||
|
|
||||||
Config(const QString& configDir, const QStringList& searchDirs = {}, QObject* parent = nullptr);
|
Config(const QString& configDir, const QStringList& searchDirs = {}, QObject* parent = nullptr);
|
||||||
|
|
||||||
~Config();
|
~Config();
|
||||||
@@ -37,6 +44,10 @@ class Config : public QObject {
|
|||||||
|
|
||||||
[[nodiscard]] int getStyleWindowHeight() const { return m_configItems.styleWindowHeight; }
|
[[nodiscard]] int getStyleWindowHeight() const { return m_configItems.styleWindowHeight; }
|
||||||
|
|
||||||
|
[[nodiscard]] SortType getSortType() const { return m_configItems.sortType; }
|
||||||
|
|
||||||
|
[[nodiscard]] bool isSortReverse() const { return m_configItems.sortReverse; }
|
||||||
|
|
||||||
static const QString s_DefaultConfigFileName;
|
static const QString s_DefaultConfigFileName;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -53,8 +64,10 @@ class Config : public QObject {
|
|||||||
double styleAspectRatio = 1.6;
|
double styleAspectRatio = 1.6;
|
||||||
int styleImageWidth = 320;
|
int styleImageWidth = 320;
|
||||||
int styleImageFocusWidth = 480;
|
int styleImageFocusWidth = 480;
|
||||||
int styleWindowWidth = 800;
|
int styleWindowWidth = 720;
|
||||||
int styleWindowHeight = 600;
|
int styleWindowHeight = 500;
|
||||||
|
SortType sortType = SortType::None;
|
||||||
|
bool sortReverse = false;
|
||||||
} m_configItems;
|
} m_configItems;
|
||||||
|
|
||||||
QStringList m_wallpapers;
|
QStringList m_wallpapers;
|
||||||
|
|||||||
@@ -36,6 +36,38 @@
|
|||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QVBoxLayout" name="mainLayout">
|
<layout class="QVBoxLayout" name="mainLayout">
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="topLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="actions" native="true">
|
<widget class="QWidget" name="actions" native="true">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
|
|||||||
+64
-17
@@ -1,20 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: Uyanide pywang0608@foxmail.com
|
* @Author: Uyanide pywang0608@foxmail.com
|
||||||
* @Date: 2025-08-05 01:22:53
|
* @Date: 2025-08-05 01:22:53
|
||||||
* @LastEditTime: 2025-08-05 20:06:23
|
* @LastEditTime: 2025-08-06 00:47:21
|
||||||
* @Description: Animated carousel widget for displaying and selecting images.
|
* @Description: Animated carousel widget for displaying and selecting images.
|
||||||
*/
|
*/
|
||||||
#include "images_carousel.h"
|
#include "images_carousel.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <qevent.h>
|
#include <qboxlayout.h>
|
||||||
#include <qpropertyanimation.h>
|
|
||||||
#include <qvariantanimation.h>
|
|
||||||
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QMetaObject>
|
#include <QMetaObject>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
|
#include <QVector>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "ui_images_carousel.h"
|
#include "ui_images_carousel.h"
|
||||||
@@ -24,6 +24,8 @@ using namespace GeneralLogger;
|
|||||||
ImagesCarousel::ImagesCarousel(const double itemAspectRatio,
|
ImagesCarousel::ImagesCarousel(const double itemAspectRatio,
|
||||||
const int itemWidth,
|
const int itemWidth,
|
||||||
const int itemFocusWidth,
|
const int itemFocusWidth,
|
||||||
|
const Config::SortType sortType,
|
||||||
|
const bool sortReverse,
|
||||||
QWidget* parent)
|
QWidget* parent)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
ui(new Ui::ImagesCarousel),
|
ui(new Ui::ImagesCarousel),
|
||||||
@@ -32,11 +34,18 @@ ImagesCarousel::ImagesCarousel(const double itemAspectRatio,
|
|||||||
m_itemWidth(itemWidth),
|
m_itemWidth(itemWidth),
|
||||||
m_itemHeight(static_cast<int>(itemWidth / itemAspectRatio)),
|
m_itemHeight(static_cast<int>(itemWidth / itemAspectRatio)),
|
||||||
m_itemFocusWidth(itemFocusWidth),
|
m_itemFocusWidth(itemFocusWidth),
|
||||||
m_itemFocusHeight(static_cast<int>(itemFocusWidth / itemAspectRatio)) {
|
m_itemFocusHeight(static_cast<int>(itemFocusWidth / itemAspectRatio)),
|
||||||
|
m_sortType(sortType),
|
||||||
|
m_sortReverse(sortReverse) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
m_imagesLayout = dynamic_cast<QHBoxLayout*>(ui->scrollAreaWidgetContents->layout());
|
||||||
connect(m_updateTimer, &QTimer::timeout, this, &ImagesCarousel::_updateImages);
|
connect(m_updateTimer, &QTimer::timeout, this, &ImagesCarousel::_updateImages);
|
||||||
m_updateTimer->start(100);
|
m_updateTimer->start(100);
|
||||||
|
|
||||||
|
connect(this, &ImagesCarousel::imagesLoaded, this, [this]() {
|
||||||
|
_focusCurrImage();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagesCarousel::~ImagesCarousel() {
|
ImagesCarousel::~ImagesCarousel() {
|
||||||
@@ -44,15 +53,23 @@ ImagesCarousel::~ImagesCarousel() {
|
|||||||
for (auto item : std::as_const(m_imageQueue)) {
|
for (auto item : std::as_const(m_imageQueue)) {
|
||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
|
// memory of items in m_loadedImages managed by Qt parent-child system
|
||||||
|
// ...
|
||||||
if (m_scrollAnimation) {
|
if (m_scrollAnimation) {
|
||||||
m_scrollAnimation->stop();
|
m_scrollAnimation->stop();
|
||||||
delete m_scrollAnimation;
|
delete m_scrollAnimation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImagesCarousel::appendImage(const QString& path) {
|
void ImagesCarousel::appendImages(const QStringList& paths) {
|
||||||
ImageLoader* loader = new ImageLoader(path, this);
|
{
|
||||||
QThreadPool::globalInstance()->start(loader);
|
QMutexLocker locker(&m_imageCountMutex);
|
||||||
|
m_imageCount += paths.size();
|
||||||
|
}
|
||||||
|
for (const QString& path : paths) {
|
||||||
|
ImageLoader* loader = new ImageLoader(path, this);
|
||||||
|
QThreadPool::globalInstance()->start(loader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageLoader::ImageLoader(const QString& path, ImagesCarousel* carousel)
|
ImageLoader::ImageLoader(const QString& path, ImagesCarousel* carousel)
|
||||||
@@ -78,19 +95,45 @@ void ImagesCarousel::_addImageToQueue(const ImageData* data) {
|
|||||||
void ImagesCarousel::_updateImages() {
|
void ImagesCarousel::_updateImages() {
|
||||||
QMutexLocker locker(&m_queueMutex);
|
QMutexLocker locker(&m_queueMutex);
|
||||||
|
|
||||||
|
static const QVector<std::function<bool(const ImageItem*, const ImageItem*)>> cmpFuncs = {
|
||||||
|
[](auto, auto) {
|
||||||
|
return false;
|
||||||
|
}, // None
|
||||||
|
[](auto a, auto b) {
|
||||||
|
return a->getFileName() < b->getFileName();
|
||||||
|
},
|
||||||
|
[](auto a, auto b) {
|
||||||
|
return a->getFileDate() < b->getFileDate();
|
||||||
|
},
|
||||||
|
[](auto a, auto b) {
|
||||||
|
return a->getFileSize() < b->getFileSize();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
int processCount = 0;
|
int processCount = 0;
|
||||||
while (!m_imageQueue.isEmpty() && processCount < 5) {
|
while (!m_imageQueue.isEmpty() && processCount < 5) {
|
||||||
ImageItem* item = m_imageQueue.dequeue();
|
ImageItem* item = m_imageQueue.dequeue();
|
||||||
ui->scrollAreaWidgetContents->layout()->addWidget(item);
|
|
||||||
m_loadedImages.append(item);
|
// insert into correct position based on sort type and direction
|
||||||
// focus first image
|
// currently O(n^2), but better as O(n * (n + log(n))) with vector and binary search
|
||||||
if (m_loadedImages.size() == 1) {
|
qint64 inserPos = m_loadedImages.size();
|
||||||
item->setFocus(true);
|
if (m_sortType != Config::SortType::None) {
|
||||||
} else {
|
for (auto it = m_loadedImages.rbegin();
|
||||||
item->setFocus(false);
|
it != m_loadedImages.rend() &&
|
||||||
|
cmpFuncs[static_cast<int>(m_sortType)](*it, item) == m_sortReverse;
|
||||||
|
++it, --inserPos);
|
||||||
}
|
}
|
||||||
|
m_loadedImages.insert(inserPos, item);
|
||||||
|
m_imagesLayout->insertWidget(inserPos, item);
|
||||||
processCount++;
|
processCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QMutexLocker countLocker(&m_imageCountMutex);
|
||||||
|
if (m_loadedImages.size() >= m_imageCount) {
|
||||||
|
emit imagesLoaded();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageLoader::run() {
|
void ImageLoader::run() {
|
||||||
@@ -101,8 +144,7 @@ void ImageLoader::run() {
|
|||||||
Q_ARG(const ImageData*, data));
|
Q_ARG(const ImageData*, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageData::ImageData(const QString& p, const int initWidth, const int initHeight) : path(p) {
|
ImageData::ImageData(const QString& p, const int initWidth, const int initHeight) : file(p) {
|
||||||
path = p;
|
|
||||||
if (!pixmap.load(p)) {
|
if (!pixmap.load(p)) {
|
||||||
warn(QString("Failed to load image from path: %1").arg(p));
|
warn(QString("Failed to load image from path: %1").arg(p));
|
||||||
}
|
}
|
||||||
@@ -137,11 +179,16 @@ void ImagesCarousel::focusPrevImage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ImagesCarousel::_unfocusCurrImage() {
|
void ImagesCarousel::_unfocusCurrImage() {
|
||||||
|
// bound check was (or should) done by caller
|
||||||
m_loadedImages[m_currentIndex]->setFocus(false);
|
m_loadedImages[m_currentIndex]->setFocus(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImagesCarousel::_focusCurrImage() {
|
void ImagesCarousel::_focusCurrImage() {
|
||||||
|
// bound check was (or should) done by caller
|
||||||
m_loadedImages[m_currentIndex]->setFocus(true);
|
m_loadedImages[m_currentIndex]->setFocus(true);
|
||||||
|
emit imageFocused(m_loadedImages[m_currentIndex]->getFileFullPath(),
|
||||||
|
m_currentIndex,
|
||||||
|
m_loadedImages.size());
|
||||||
auto hScrollBar = ui->scrollArea->horizontalScrollBar();
|
auto hScrollBar = ui->scrollArea->horizontalScrollBar();
|
||||||
int spacing = ui->scrollAreaWidgetContents->layout()->spacing();
|
int spacing = ui->scrollAreaWidgetContents->layout()->spacing();
|
||||||
int centerOffset = (m_itemWidth + spacing) * m_currentIndex + m_itemFocusWidth / 2 - spacing;
|
int centerOffset = (m_itemWidth + spacing) * m_currentIndex + m_itemFocusWidth / 2 - spacing;
|
||||||
|
|||||||
+30
-11
@@ -1,14 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: Uyanide pywang0608@foxmail.com
|
* @Author: Uyanide pywang0608@foxmail.com
|
||||||
* @Date: 2025-08-05 01:22:53
|
* @Date: 2025-08-05 01:22:53
|
||||||
* @LastEditTime: 2025-08-05 19:47:43
|
* @LastEditTime: 2025-08-06 00:47:12
|
||||||
* @Description: Animated carousel widget for displaying and selecting images.
|
* @Description: Animated carousel widget for displaying and selecting images.
|
||||||
*/
|
*/
|
||||||
#ifndef IMAGES_CAROUSEL_H
|
#ifndef IMAGES_CAROUSEL_H
|
||||||
#define IMAGES_CAROUSEL_H
|
#define IMAGES_CAROUSEL_H
|
||||||
|
|
||||||
#include <qtmetamacros.h>
|
#include <QFileInfo>
|
||||||
|
#include <QHBoxLayout>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
@@ -22,6 +22,8 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
class ImagesCarousel;
|
class ImagesCarousel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,7 +31,7 @@ class ImagesCarousel;
|
|||||||
* and can be safely created and passed between threads.
|
* and can be safely created and passed between threads.
|
||||||
*/
|
*/
|
||||||
struct ImageData {
|
struct ImageData {
|
||||||
QString path;
|
QFileInfo file;
|
||||||
QPixmap pixmap;
|
QPixmap pixmap;
|
||||||
|
|
||||||
explicit ImageData(const QString& p, const int initWidth, const int initHeight);
|
explicit ImageData(const QString& p, const int initWidth, const int initHeight);
|
||||||
@@ -51,10 +53,16 @@ class ImageItem : public QLabel {
|
|||||||
|
|
||||||
~ImageItem() override;
|
~ImageItem() override;
|
||||||
|
|
||||||
[[nodiscard]] const QString& getPath() const { return m_data->path; }
|
[[nodiscard]] QString getFileFullPath() const { return m_data->file.absoluteFilePath(); }
|
||||||
|
|
||||||
|
[[nodiscard]] QString getFileName() const { return m_data->file.fileName(); }
|
||||||
|
|
||||||
|
[[nodiscard]] QDateTime getFileDate() const { return m_data->file.lastModified(); }
|
||||||
|
|
||||||
[[nodiscard]] const QPixmap& getPixmap() const { return m_data->pixmap; }
|
[[nodiscard]] const QPixmap& getPixmap() const { return m_data->pixmap; }
|
||||||
|
|
||||||
|
[[nodiscard]] qint64 getFileSize() const { return m_data->file.size(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setFocus(bool focus = true);
|
void setFocus(bool focus = true);
|
||||||
|
|
||||||
@@ -90,6 +98,8 @@ class ImagesCarousel : public QWidget {
|
|||||||
explicit ImagesCarousel(const double itemAspectRatio,
|
explicit ImagesCarousel(const double itemAspectRatio,
|
||||||
const int itemWidth,
|
const int itemWidth,
|
||||||
const int itemFocusWidth,
|
const int itemFocusWidth,
|
||||||
|
const Config::SortType sortType,
|
||||||
|
const bool sortReverse,
|
||||||
QWidget* parent = nullptr);
|
QWidget* parent = nullptr);
|
||||||
~ImagesCarousel();
|
~ImagesCarousel();
|
||||||
|
|
||||||
@@ -99,13 +109,15 @@ class ImagesCarousel : public QWidget {
|
|||||||
if (m_currentIndex < 0 || m_currentIndex >= m_loadedImages.size()) {
|
if (m_currentIndex < 0 || m_currentIndex >= m_loadedImages.size()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return m_loadedImages[m_currentIndex]->getPath();
|
return m_loadedImages[m_currentIndex]->getFileFullPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
const int m_itemWidth = 320;
|
const int m_itemWidth = 320;
|
||||||
const int m_itemHeight = 180;
|
const int m_itemHeight = 180;
|
||||||
const int m_itemFocusWidth = 480;
|
const int m_itemFocusWidth = 480;
|
||||||
const int m_itemFocusHeight = 270;
|
const int m_itemFocusHeight = 270;
|
||||||
|
const Config::SortType m_sortType = Config::SortType::None;
|
||||||
|
const bool m_sortReverse = false;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void focusNextImage();
|
void focusNextImage();
|
||||||
@@ -115,7 +127,7 @@ class ImagesCarousel : public QWidget {
|
|||||||
void _unfocusCurrImage();
|
void _unfocusCurrImage();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void appendImage(const QString& path);
|
void appendImages(const QStringList& paths);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_INVOKABLE void _addImageToQueue(const ImageData* data);
|
Q_INVOKABLE void _addImageToQueue(const ImageData* data);
|
||||||
@@ -130,6 +142,13 @@ class ImagesCarousel : public QWidget {
|
|||||||
QTimer* m_updateTimer;
|
QTimer* m_updateTimer;
|
||||||
int m_currentIndex = 0;
|
int m_currentIndex = 0;
|
||||||
QPropertyAnimation* m_scrollAnimation;
|
QPropertyAnimation* m_scrollAnimation;
|
||||||
|
QHBoxLayout* m_imagesLayout = nullptr;
|
||||||
|
QMutex m_imageCountMutex;
|
||||||
|
int m_imageCount = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void imageFocused(const QString& path, const int index, const int count);
|
||||||
|
void imagesLoaded();
|
||||||
};
|
};
|
||||||
|
|
||||||
class ImagesCarouselScrollArea : public QScrollArea {
|
class ImagesCarouselScrollArea : public QScrollArea {
|
||||||
|
|||||||
+15
-5
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: Uyanide pywang0608@foxmail.com
|
* @Author: Uyanide pywang0608@foxmail.com
|
||||||
* @Date: 2025-08-05 00:37:58
|
* @Date: 2025-08-05 00:37:58
|
||||||
* @LastEditTime: 2025-08-05 20:12:40
|
* @LastEditTime: 2025-08-06 00:48:11
|
||||||
* @Description: MainWindow implementation.
|
* @Description: MainWindow implementation.
|
||||||
*/
|
*/
|
||||||
#include "main_window.h"
|
#include "main_window.h"
|
||||||
@@ -17,6 +17,11 @@
|
|||||||
|
|
||||||
using namespace GeneralLogger;
|
using namespace GeneralLogger;
|
||||||
|
|
||||||
|
static QString splitNameFromPath(const QString &path) {
|
||||||
|
QFileInfo fileInfo(path);
|
||||||
|
return fileInfo.fileName();
|
||||||
|
}
|
||||||
|
|
||||||
MainWindow::MainWindow(const Config &config, QWidget *parent)
|
MainWindow::MainWindow(const Config &config, QWidget *parent)
|
||||||
: QMainWindow(parent), ui(new Ui::MainWindow), m_config(config) {
|
: QMainWindow(parent), ui(new Ui::MainWindow), m_config(config) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
@@ -33,8 +38,11 @@ void MainWindow::_setupUI() {
|
|||||||
m_config.getStyleAspectRatio(),
|
m_config.getStyleAspectRatio(),
|
||||||
m_config.getStyleImageWidth(),
|
m_config.getStyleImageWidth(),
|
||||||
m_config.getStyleImageFocusWidth(),
|
m_config.getStyleImageFocusWidth(),
|
||||||
|
m_config.getSortType(),
|
||||||
|
m_config.isSortReverse(),
|
||||||
this);
|
this);
|
||||||
ui->mainLayout->insertWidget(0, m_carousel);
|
ui->mainLayout->insertWidget(2, m_carousel);
|
||||||
|
connect(m_carousel, &ImagesCarousel::imageFocused, this, &MainWindow::_onImageFocused);
|
||||||
|
|
||||||
// set window size
|
// set window size
|
||||||
setMinimumSize(m_config.getStyleWindowWidth(), m_config.getStyleWindowHeight());
|
setMinimumSize(m_config.getStyleWindowWidth(), m_config.getStyleWindowHeight());
|
||||||
@@ -45,9 +53,7 @@ void MainWindow::_setupUI() {
|
|||||||
ui->confirmButton->setFocusPolicy(Qt::NoFocus);
|
ui->confirmButton->setFocusPolicy(Qt::NoFocus);
|
||||||
ui->cancelButton->setFocusPolicy(Qt::NoFocus);
|
ui->cancelButton->setFocusPolicy(Qt::NoFocus);
|
||||||
|
|
||||||
for (const auto &image : m_config.getWallpapers()) {
|
m_carousel->appendImages(m_config.getWallpapers());
|
||||||
m_carousel->appendImage(image);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::keyPressEvent(QKeyEvent *event) {
|
void MainWindow::keyPressEvent(QKeyEvent *event) {
|
||||||
@@ -91,3 +97,7 @@ void MainWindow::onConfirm() {
|
|||||||
void MainWindow::onCancel() {
|
void MainWindow::onCancel() {
|
||||||
close();
|
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));
|
||||||
|
}
|
||||||
+4
-1
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: Uyanide pywang0608@foxmail.com
|
* @Author: Uyanide pywang0608@foxmail.com
|
||||||
* @Date: 2025-08-05 00:37:58
|
* @Date: 2025-08-05 00:37:58
|
||||||
* @LastEditTime: 2025-08-05 19:53:51
|
* @LastEditTime: 2025-08-06 00:47:04
|
||||||
* @Description: MainWindow implementation.
|
* @Description: MainWindow implementation.
|
||||||
*/
|
*/
|
||||||
#ifndef MAINWINDOW_H
|
#ifndef MAINWINDOW_H
|
||||||
@@ -37,6 +37,9 @@ class MainWindow : public QMainWindow {
|
|||||||
private:
|
private:
|
||||||
void _setupUI();
|
void _setupUI();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void _onImageFocused(const QString &path, const int index, const int count);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
ImagesCarousel *m_carousel = nullptr;
|
ImagesCarousel *m_carousel = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user