Skip to content

Commit

Permalink
added image grid visualization.
Browse files Browse the repository at this point in the history
  • Loading branch information
ponchio committed Jan 31, 2024
1 parent 3ceddd6 commit 85f2d9b
Show file tree
Hide file tree
Showing 10 changed files with 293 additions and 9 deletions.
136 changes: 136 additions & 0 deletions relightlab/flowlayout.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

#include <QtWidgets>

#include "flowlayout.h"

FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
: QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) {
setContentsMargins(margin, margin, margin, margin);
}

FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
: m_hSpace(hSpacing), m_vSpace(vSpacing) {
setContentsMargins(margin, margin, margin, margin);
}

FlowLayout::~FlowLayout() {
QLayoutItem *item;
while ((item = takeAt(0)))
delete item;
}

void FlowLayout::addItem(QLayoutItem *item) {
itemList.append(item);
}

int FlowLayout::horizontalSpacing() const {
if (m_hSpace >= 0) {
return m_hSpace;
} else {
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
}
}

int FlowLayout::verticalSpacing() const {
if (m_vSpace >= 0) {
return m_vSpace;
} else {
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
}
}

int FlowLayout::count() const {
return itemList.size();
}

QLayoutItem *FlowLayout::itemAt(int index) const {
return itemList.value(index);
}

QLayoutItem *FlowLayout::takeAt(int index) {
if (index >= 0 && index < itemList.size())
return itemList.takeAt(index);
return nullptr;
}

Qt::Orientations FlowLayout::expandingDirections() const {
return { };
}

bool FlowLayout::hasHeightForWidth() const {
return true;
}

int FlowLayout::heightForWidth(int width) const {
int height = doLayout(QRect(0, 0, width, 0), true);
return height;
}

void FlowLayout::setGeometry(const QRect &rect) {
QLayout::setGeometry(rect);
doLayout(rect, false);
}

QSize FlowLayout::sizeHint() const {
return minimumSize();
}

QSize FlowLayout::minimumSize() const {
QSize size;
for (const QLayoutItem *item : itemList)
size = size.expandedTo(item->minimumSize());

const QMargins margins = contentsMargins();
size += QSize(margins.left() + margins.right(), margins.top() + margins.bottom());
return size;
}

int FlowLayout::doLayout(const QRect &rect, bool testOnly) const {
int left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
int x = effectiveRect.x();
int y = effectiveRect.y();
int lineHeight = 0;

for (QLayoutItem *item : itemList) {
const QWidget *wid = item->widget();
int spaceX = horizontalSpacing();
if (spaceX == -1)
spaceX = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
int spaceY = verticalSpacing();
if (spaceY == -1)
spaceY = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);

int nextX = x + item->sizeHint().width() + spaceX;
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
x = effectiveRect.x();
y = y + lineHeight + spaceY;
nextX = x + item->sizeHint().width() + spaceX;
lineHeight = 0;
}

if (!testOnly)
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));

x = nextX;
lineHeight = qMax(lineHeight, item->sizeHint().height());
}
return y + lineHeight - rect.y() + bottom;
}

int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const {
QObject *parent = this->parent();
if (!parent) {
return -1;
} else if (parent->isWidgetType()) {
QWidget *pw = static_cast<QWidget *>(parent);
return pw->style()->pixelMetric(pm, nullptr, pw);
} else {
return static_cast<QLayout *>(parent)->spacing();
}
}
41 changes: 41 additions & 0 deletions relightlab/flowlayout.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

#ifndef FLOWLAYOUT_H
#define FLOWLAYOUT_H

#include <QLayout>
#include <QRect>
#include <QStyle>

class FlowLayout : public QLayout
{
public:
explicit FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
~FlowLayout();

void addItem(QLayoutItem *item) override;
int horizontalSpacing() const;
int verticalSpacing() const;
Qt::Orientations expandingDirections() const override;
bool hasHeightForWidth() const override;
int heightForWidth(int) const override;
int count() const override;
QLayoutItem *itemAt(int index) const override;
QSize minimumSize() const override;
void setGeometry(const QRect &rect) override;
QSize sizeHint() const override;
QLayoutItem *takeAt(int index) override;

private:
int doLayout(const QRect &rect, bool testOnly) const;
int smartSpacing(QStyle::PixelMetric pm) const;

QList<QLayoutItem *> itemList;
int m_hSpace;
int m_vSpace;
};


#endif // FLOWLAYOUT_H
33 changes: 30 additions & 3 deletions relightlab/imageframe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "imageframe.h"
#include "canvas.h"
#include "imagelist.h"
#include "imagegrid.h"

#include <iostream>
using namespace std;
Expand Down Expand Up @@ -51,6 +52,9 @@ ImageFrame::ImageFrame() {
image_list = new ImageList();
content->addWidget(image_list, 0);

image_grid = new ImageGrid();
content->addWidget(image_grid, 1);

canvas = new Canvas();
content->addWidget(canvas, 1);

Expand All @@ -68,6 +72,10 @@ ImageFrame::ImageFrame() {

connect(image_list, SIGNAL(itemPressed(QListWidgetItem*)), this, SLOT(showImageItem(QListWidgetItem*)));

connect(qRelightApp->action("show_image"), SIGNAL(triggered(bool)), this, SLOT(imageMode()));
connect(qRelightApp->action("show_list"), SIGNAL(triggered(bool)), this, SLOT(listMode()));
connect(qRelightApp->action("show_grid"), SIGNAL(triggered(bool)), this, SLOT(gridMode()));

container->addLayout(content);

status = new QStatusBar();
Expand All @@ -76,17 +84,18 @@ ImageFrame::ImageFrame() {

void ImageFrame::init() {
image_list->init();
image_grid->init();
showImage(0);
fit();
showImage(0);
listMode(); //TODO actually use last used mode used by the user
}

void ImageFrame::showImage(int id) {
Project &project = qRelightApp->project();

image_list->setCurrentRow(id);
qRelightApp->action("previous_image")->setEnabled(id != 0);
qRelightApp->action("next_image")->setEnabled(id != project.images.size()-1);
qRelightApp->action("next_image")->setEnabled(id != (int)project.images.size()-1);

QString filename = project.images[id].filename;

Expand Down Expand Up @@ -137,7 +146,7 @@ void ImageFrame::previousImage() {

void ImageFrame::nextImage() {
int current = image_list->currentRow();
if(current++ == qRelightApp->project().images.size()-1)
if(current++ == (int)qRelightApp->project().images.size()-1)
return;
image_list->setCurrentRow(current);
showImage(current);
Expand All @@ -148,3 +157,21 @@ void ImageFrame::showImageItem(QListWidgetItem *item) {
int id =item->listWidget()->currentRow();
showImage(id);
}

void ImageFrame::imageMode() {
canvas->show();
image_list->hide();
image_grid->hide();
}
void ImageFrame::listMode() {
canvas->show();
image_list->show();
image_grid->hide();

}
void ImageFrame::gridMode() {
canvas->hide();
image_list->hide();
image_grid->show();
}

6 changes: 6 additions & 0 deletions relightlab/imageframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

class Canvas;
class ImageList;
class ImageGrid;

class QStatusBar;
class QGraphicsPixmapItem;
Expand All @@ -17,6 +18,7 @@ class ImageFrame: public QFrame {
public:
enum Mode { SINGLE, LIST, THUMBNAILS };
ImageList *image_list = nullptr;
ImageGrid *image_grid = nullptr;
Canvas *canvas = nullptr;
QStatusBar *status = nullptr;
ImageFrame();
Expand All @@ -31,6 +33,10 @@ public slots:
void nextImage();
void showImageItem(QListWidgetItem *item);

void imageMode();
void listMode();
void gridMode();

private:
QGraphicsPixmapItem *imagePixmap = nullptr;
QGraphicsScene *scene = nullptr;
Expand Down
47 changes: 47 additions & 0 deletions relightlab/imagegrid.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "imagegrid.h"
#include "relightapp.h"
#include "flowlayout.h"

#include <QLabel>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QCheckBox>


ImageThumb::ImageThumb(const QString& imagePath, const QString& text, QWidget* parent): QWidget(parent) {

QVBoxLayout* layout = new QVBoxLayout(this);

QLabel* thumb = new QLabel;
QImage img(imagePath);
img = img.scaledToHeight(256);
thumb->setPixmap(QPixmap::fromImage(img));
layout->addWidget(thumb);

QCheckBox *checkbox = new QCheckBox(text);
layout->addWidget(checkbox);

layout->setSpacing(5);
layout->setContentsMargins(5, 5, 5, 5);
}

ImageGrid::ImageGrid(QWidget *parent): QScrollArea(parent) {

flowlayout = new FlowLayout();
setWidgetResizable(true);
setWidget(new QWidget);
widget()->setLayout(flowlayout);
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
}

void ImageGrid::init() {
Project &project = qRelightApp->project();

for(Image &img: project.images) {
QFileInfo info(img.filename);
ImageThumb *thumb = new ImageThumb(img.filename, info.fileName());
flowlayout->addWidget(thumb);
}
}

26 changes: 26 additions & 0 deletions relightlab/imagegrid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef IMAGEGRID_H
#define IMAGEGRID_H

#include<QScrollArea>
#include <QWidget>


class FlowLayout;


class ImageThumb : public QWidget {
public:
ImageThumb(const QString& imagePath, const QString& text, QWidget* parent = nullptr);
};


class ImageGrid: public QScrollArea {
public:
ImageGrid(QWidget *parent = nullptr);

void init();
private:
FlowLayout *flowlayout = nullptr;
};

#endif // IMAGEGRID_H
1 change: 0 additions & 1 deletion relightlab/imagelist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,5 @@ void ImageList::init() {
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
item->setCheckState(Qt::Unchecked);
addItem(item);

}
}
2 changes: 0 additions & 2 deletions relightlab/relightapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ RelightApp::RelightApp(int &argc, char **argv): QApplication(argc, argv) {
addAction("show_list", "Show list", "", "");
addAction("show_grid", "Show grid", "", "");
}
RelightApp::~RelightApp() {
}

void RelightApp::run() {
mainwindow = new MainWindow;
Expand Down
2 changes: 1 addition & 1 deletion relightlab/relightapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class RelightApp: public QApplication {
MainWindow *mainwindow = nullptr;

RelightApp(int &argc, char **argv);
~RelightApp();
virtual ~RelightApp() {}
void run();

public slots:
Expand Down
Loading

0 comments on commit 85f2d9b

Please sign in to comment.