git repos / SagoImageBrowser

commit 61136b77

Poul Sander · 2026-02-20 22:45
61136b77cf0a204767b35e561be988975a71ec67 patch · browse files
parent cfe4a67bc73d106cd4b66f028b603d78d9bf5098

Now has a single image mode

Changed files

M CMakeLists.txt before
A imageviewwidget.cpp
A imageviewwidget.h
M mainwindow.cpp before
M mainwindow.h before
diff --git a/CMakeLists.txt b/CMakeLists.txt index 3eba63e..eb016dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -14,6 +14,8 @@ qt_add_executable(ImageBrowser
imagemodel.h
thumbnailworker.cpp
thumbnailworker.h
+ imageviewwidget.cpp
+ imageviewwidget.h
)
target_link_libraries(ImageBrowser PRIVATE Qt6::Widgets)
\ No newline at end of file
diff --git a/imageviewwidget.cpp b/imageviewwidget.cpp new file mode 100644 index 0000000..2ff637b --- /dev/null +++ b/imageviewwidget.cpp
@@ -0,0 +1,50 @@
+#include "imageviewwidget.h"
+
+#include <QPainter>
+#include <QKeyEvent>
+#include <QImageReader>
+
+ImageViewWidget::ImageViewWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ setFocusPolicy(Qt::StrongFocus);
+ setStyleSheet("background-color: black;");
+}
+
+void ImageViewWidget::setImage(const QString &path)
+{
+ QImageReader reader(path);
+ reader.setAutoTransform(true);
+ QImage image = reader.read();
+
+ if (!image.isNull())
+ m_pixmap = QPixmap::fromImage(image);
+ else
+ m_pixmap = QPixmap();
+
+ update();
+}
+
+void ImageViewWidget::paintEvent(QPaintEvent *)
+{
+ if (m_pixmap.isNull())
+ return;
+
+ QPainter painter(this);
+ QPixmap scaled = m_pixmap.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ int x = (width() - scaled.width()) / 2;
+ int y = (height() - scaled.height()) / 2;
+ painter.drawPixmap(x, y, scaled);
+}
+
+void ImageViewWidget::keyPressEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_Escape)
+ {
+ emit closeRequested();
+ event->accept();
+ return;
+ }
+
+ QWidget::keyPressEvent(event);
+}
diff --git a/imageviewwidget.h b/imageviewwidget.h new file mode 100644 index 0000000..f10cd29 --- /dev/null +++ b/imageviewwidget.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <QWidget>
+#include <QImage>
+#include <QPixmap>
+#include <QString>
+
+class ImageViewWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ImageViewWidget(QWidget *parent = nullptr);
+
+ void setImage(const QString &path);
+
+signals:
+ void closeRequested();
+
+protected:
+ void paintEvent(QPaintEvent *event) override;
+ void keyPressEvent(QKeyEvent *event) override;
+
+private:
+ QPixmap m_pixmap;
+};
diff --git a/mainwindow.cpp b/mainwindow.cpp index 2c297e3..504f0b0 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp
@@ -1,17 +1,20 @@
#include "mainwindow.h"
#include "imagemodel.h"
+#include "imageviewwidget.h"
#include <QFileSystemModel>
#include <QTreeView>
#include <QListView>
#include <QLabel>
#include <QSplitter>
+#include <QStackedWidget>
#include <QDir>
#include <QImageReader>
#include <QHeaderView>
#include <QScrollBar>
#include <QTimer>
#include <QEvent>
+#include <QKeyEvent>
#include <QItemSelectionModel>
#include <iostream>
@@ -68,7 +71,17 @@ void MainWindow::setupUi()
mainSplitter->addWidget(rightSplitter);
mainSplitter->setStretchFactor(1, 1);
- setCentralWidget(mainSplitter);
+ m_browserPage = mainSplitter;
+
+ // Single image view
+ m_imageView = new ImageViewWidget;
+
+ // Stack to switch between browser and single image
+ m_stack = new QStackedWidget;
+ m_stack->addWidget(m_browserPage);
+ m_stack->addWidget(m_imageView);
+
+ setCentralWidget(m_stack);
}
void MainWindow::setupConnections()
@@ -88,6 +101,12 @@ void MainWindow::setupConnections()
connect(m_listView->selectionModel(), &QItemSelectionModel::currentChanged,
this, [this](const QModelIndex &current) { showPreview(current); });
+ connect(m_listView, &QListView::doubleClicked, this,
+ [this](const QModelIndex &index) { enterSingleImageMode(index); });
+
+ connect(m_imageView, &ImageViewWidget::closeRequested,
+ this, &MainWindow::leaveSingleImageMode);
+
connect(m_listView->verticalScrollBar(), &QScrollBar::valueChanged,
this, [this]()
{ loadVisibleThumbnails(); });
@@ -139,3 +158,53 @@ void MainWindow::showPreview(const QModelIndex &index)
Qt::KeepAspectRatio,
Qt::SmoothTransformation));
}
+
+void MainWindow::enterSingleImageMode(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return;
+
+ QString path = m_imageModel->filePath(index);
+ m_imageView->setImage(path);
+ m_stack->setCurrentWidget(m_imageView);
+ m_imageView->setFocus();
+}
+
+void MainWindow::leaveSingleImageMode()
+{
+ if (isFullScreen())
+ {
+ if (m_wasFullScreen)
+ showFullScreen();
+ else
+ showNormal();
+ }
+ m_stack->setCurrentWidget(m_browserPage);
+ m_listView->setFocus();
+}
+
+void MainWindow::keyPressEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_F11 && m_stack->currentWidget() == m_imageView)
+ {
+ if (isFullScreen())
+ showNormal();
+ else
+ showFullScreen();
+ event->accept();
+ return;
+ }
+
+ if (event->key() == Qt::Key_Return && m_stack->currentWidget() == m_browserPage)
+ {
+ QModelIndex current = m_listView->currentIndex();
+ if (current.isValid())
+ {
+ enterSingleImageMode(current);
+ event->accept();
+ return;
+ }
+ }
+
+ QMainWindow::keyPressEvent(event);
+}
diff --git a/mainwindow.h b/mainwindow.h index 7b01b44..4072447 100644 --- a/mainwindow.h +++ b/mainwindow.h
@@ -5,8 +5,10 @@
class QTreeView;
class QListView;
class QLabel;
+class QStackedWidget;
class QFileSystemModel;
class ImageModel;
+class ImageViewWidget;
class MainWindow : public QMainWindow
{
@@ -20,7 +22,10 @@ private:
void setupConnections();
void loadVisibleThumbnails();
void showPreview(const QModelIndex &index);
+ void enterSingleImageMode(const QModelIndex &index);
+ void leaveSingleImageMode();
+ void keyPressEvent(QKeyEvent *event) override;
bool eventFilter(QObject *obj, QEvent *event) override;
QFileSystemModel *m_dirModel;
@@ -29,4 +34,9 @@ private:
QTreeView *m_treeView;
QListView *m_listView;
QLabel *m_previewLabel;
+
+ QStackedWidget *m_stack;
+ QWidget *m_browserPage;
+ ImageViewWidget *m_imageView;
+ bool m_wasFullScreen = false;
};