bunch of stuff. very basic drag/drop now working
This commit is contained in:
75
.gitignore
vendored
Normal file
75
.gitignore
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
# This file is used to ignore files which are generated
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
*~
|
||||
*.autosave
|
||||
*.a
|
||||
*.core
|
||||
*.moc
|
||||
*.o
|
||||
*.obj
|
||||
*.orig
|
||||
*.rej
|
||||
*.so
|
||||
*.so.*
|
||||
*_pch.h.cpp
|
||||
*_resource.rc
|
||||
*.qm
|
||||
.#*
|
||||
*.*#
|
||||
core
|
||||
!core/
|
||||
tags
|
||||
.DS_Store
|
||||
.directory
|
||||
*.debug
|
||||
Makefile*
|
||||
*.prl
|
||||
*.app
|
||||
moc_*.cpp
|
||||
ui_*.h
|
||||
qrc_*.cpp
|
||||
Thumbs.db
|
||||
*.res
|
||||
*.rc
|
||||
/.qmake.cache
|
||||
/.qmake.stash
|
||||
|
||||
# qtcreator generated files
|
||||
*.pro.user*
|
||||
CMakeLists.txt.user*
|
||||
|
||||
# xemacs temporary files
|
||||
*.flc
|
||||
|
||||
# Vim temporary files
|
||||
.*.swp
|
||||
|
||||
# Visual Studio generated files
|
||||
*.ib_pdb_index
|
||||
*.idb
|
||||
*.ilk
|
||||
*.pdb
|
||||
*.sln
|
||||
*.suo
|
||||
*.vcproj
|
||||
*vcproj.*.*.user
|
||||
*.ncb
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.vcxproj
|
||||
*vcxproj.*
|
||||
|
||||
# MinGW generated files
|
||||
*.Debug
|
||||
*.Release
|
||||
|
||||
# Python byte code
|
||||
*.pyc
|
||||
|
||||
# Binaries
|
||||
# --------
|
||||
*.dll
|
||||
*.exe
|
||||
|
||||
build
|
||||
84
CMakeLists.txt
Normal file
84
CMakeLists.txt
Normal file
@@ -0,0 +1,84 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(qt-app VERSION 0.1 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
|
||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
|
||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Network)
|
||||
|
||||
set(PROJECT_SOURCES
|
||||
main.cpp
|
||||
mainwindow.cpp
|
||||
mainwindow.h
|
||||
mainwindow.ui
|
||||
)
|
||||
|
||||
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||
qt_add_executable(qt-app
|
||||
MANUAL_FINALIZATION
|
||||
${PROJECT_SOURCES}
|
||||
tiercard.hpp tiercard.cpp
|
||||
flowlayout.cpp flowlayout.h flowlayout.pro
|
||||
tiercardlayout.hpp tiercardlayout.cpp
|
||||
aspectratiopixmaplabel.hpp aspectratiopixmaplabel.cpp
|
||||
fullsizelayout.hpp fullsizelayout.cpp
|
||||
tierrow.hpp tierrow.cpp
|
||||
tierrowtitlecard.hpp tierrowtitlecard.cpp
|
||||
myflowlayout.hpp myflowlayout.cpp
|
||||
utils.hpp
|
||||
rowholder.hpp rowholder.cpp
|
||||
settings.hpp settings.cpp
|
||||
|
||||
)
|
||||
# Define target properties for Android with Qt 6 as:
|
||||
# set_property(TARGET qt-app APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
|
||||
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
|
||||
else()
|
||||
if(ANDROID)
|
||||
add_library(qt-app SHARED
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
# Define properties for Android with Qt 5 after find_package() calls as:
|
||||
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
|
||||
else()
|
||||
add_executable(qt-app
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(qt-app PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
target_link_libraries(qt-app PRIVATE Qt${QT_VERISON_MAJOR}::Network)
|
||||
|
||||
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
|
||||
# If you are developing for iOS or macOS you should consider setting an
|
||||
# explicit, fixed bundle identifier manually though.
|
||||
if(${QT_VERSION} VERSION_LESS 6.1.0)
|
||||
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.qt-app)
|
||||
endif()
|
||||
set_target_properties(qt-app PROPERTIES
|
||||
${BUNDLE_ID_OPTION}
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
|
||||
MACOSX_BUNDLE TRUE
|
||||
WIN32_EXECUTABLE TRUE
|
||||
)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS qt-app
|
||||
BUNDLE DESTINATION .
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
if(QT_VERSION_MAJOR EQUAL 6)
|
||||
qt_finalize_executable(qt-app)
|
||||
endif()
|
||||
36
aspectratiopixmaplabel.cpp
Normal file
36
aspectratiopixmaplabel.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "aspectratiopixmaplabel.hpp"
|
||||
|
||||
AspectRatioPixmapLabel::AspectRatioPixmapLabel(QWidget *parent) :
|
||||
QLabel(parent)
|
||||
{
|
||||
this->setMinimumSize(1,1);
|
||||
setScaledContents(false);
|
||||
}
|
||||
|
||||
void AspectRatioPixmapLabel::setPixmap ( const QPixmap & p)
|
||||
{
|
||||
pix = p;
|
||||
QLabel::setPixmap(scaledPixmap());
|
||||
}
|
||||
|
||||
int AspectRatioPixmapLabel::heightForWidth( int width ) const
|
||||
{
|
||||
return pix.isNull() ? this->height() : ((qreal)pix.height()*width)/pix.width();
|
||||
}
|
||||
|
||||
QSize AspectRatioPixmapLabel::sizeHint() const
|
||||
{
|
||||
int w = this->width();
|
||||
return QSize( w, heightForWidth(w) );
|
||||
}
|
||||
|
||||
QPixmap AspectRatioPixmapLabel::scaledPixmap() const
|
||||
{
|
||||
return pix.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
void AspectRatioPixmapLabel::resizeEvent(QResizeEvent * e)
|
||||
{
|
||||
if(!pix.isNull())
|
||||
QLabel::setPixmap(scaledPixmap());
|
||||
}
|
||||
23
aspectratiopixmaplabel.hpp
Normal file
23
aspectratiopixmaplabel.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef ASPECTRATIOPIXMAPLABEL_HPP
|
||||
#define ASPECTRATIOPIXMAPLABEL_HPP
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPixmap>
|
||||
#include <QResizeEvent>
|
||||
|
||||
class AspectRatioPixmapLabel : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AspectRatioPixmapLabel(QWidget *parent = 0);
|
||||
virtual int heightForWidth( int width ) const;
|
||||
virtual QSize sizeHint() const;
|
||||
QPixmap scaledPixmap() const;
|
||||
public slots:
|
||||
void setPixmap ( const QPixmap & );
|
||||
void resizeEvent(QResizeEvent *);
|
||||
private:
|
||||
QPixmap pix;
|
||||
};
|
||||
|
||||
#endif // ASPECTRATIOPIXMAPLABEL_HPP
|
||||
154
flowlayout.cpp
Normal file
154
flowlayout.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "flowlayout.h"
|
||||
//! [1]
|
||||
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()
|
||||
{
|
||||
for (auto& child : itemList)
|
||||
{
|
||||
delete child;
|
||||
child = nullptr;
|
||||
}
|
||||
itemList.clear();
|
||||
}
|
||||
|
||||
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 : std::as_const(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 : std::as_const(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
flowlayout.h
Normal file
41
flowlayout.h
Normal file
@@ -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>
|
||||
//! [0]
|
||||
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;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif // FLOWLAYOUT_H
|
||||
11
flowlayout.pro
Normal file
11
flowlayout.pro
Normal file
@@ -0,0 +1,11 @@
|
||||
QT += widgets
|
||||
|
||||
HEADERS = flowlayout.h \
|
||||
window.h
|
||||
SOURCES = flowlayout.cpp \
|
||||
main.cpp \
|
||||
window.cpp
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/layouts/flowlayout
|
||||
INSTALLS += target
|
||||
91
fullsizelayout.cpp
Normal file
91
fullsizelayout.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#include "fullsizelayout.hpp"
|
||||
#include "qdebug.h"
|
||||
#include "qwidget.h"
|
||||
#include <algorithm>
|
||||
|
||||
FullSizeLayout::FullSizeLayout() {}
|
||||
|
||||
FullSizeLayout::~FullSizeLayout()
|
||||
{
|
||||
for (auto& child : itemList)
|
||||
{
|
||||
delete child;
|
||||
child = nullptr;
|
||||
}
|
||||
itemList.clear();
|
||||
}
|
||||
void FullSizeLayout::addItem(QLayoutItem* item)
|
||||
{
|
||||
itemList.append(item);
|
||||
}
|
||||
int FullSizeLayout::horizontalSpacing() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int FullSizeLayout::verticalSpacing() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Qt::Orientations FullSizeLayout::expandingDirections() const
|
||||
{
|
||||
return Qt::Vertical | Qt::Horizontal;
|
||||
}
|
||||
bool FullSizeLayout::hasHeightForWidth() const
|
||||
{
|
||||
for (auto child : itemList)
|
||||
{
|
||||
if (child->hasHeightForWidth())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int FullSizeLayout::heightForWidth(int width) const
|
||||
{
|
||||
int h = -1;
|
||||
for (auto child : itemList)
|
||||
{
|
||||
h = std::max(h, child->heightForWidth(width));
|
||||
}
|
||||
return h;
|
||||
}
|
||||
int FullSizeLayout::count() const
|
||||
{
|
||||
return static_cast<int>(itemList.count());
|
||||
}
|
||||
QLayoutItem* FullSizeLayout::itemAt(int index) const
|
||||
{
|
||||
return itemList.value(index);
|
||||
}
|
||||
QSize FullSizeLayout::minimumSize() const
|
||||
{
|
||||
QSize size;
|
||||
for (auto child : itemList)
|
||||
{
|
||||
// auto wid = child->widget();
|
||||
if (std::max(child->minimumSize().height(), child->minimumSize().width()) >= 200)
|
||||
child->minimumSize();
|
||||
// if (wid)
|
||||
size = size.expandedTo(child->minimumSize());
|
||||
}
|
||||
return size;
|
||||
}
|
||||
void FullSizeLayout::setGeometry(const QRect &rect)
|
||||
{
|
||||
for (auto child : itemList)
|
||||
{
|
||||
child->setGeometry(rect);
|
||||
}
|
||||
}
|
||||
QSize FullSizeLayout::sizeHint() const
|
||||
{
|
||||
QSize size(1,1);
|
||||
for (auto child : itemList)
|
||||
{
|
||||
size = size.expandedTo(child->sizeHint());
|
||||
}
|
||||
return size;
|
||||
}
|
||||
QLayoutItem* FullSizeLayout::takeAt(int index)
|
||||
{
|
||||
return itemList.takeAt(index);
|
||||
}
|
||||
28
fullsizelayout.hpp
Normal file
28
fullsizelayout.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef FULLSIZELAYOUT_HPP
|
||||
#define FULLSIZELAYOUT_HPP
|
||||
|
||||
#include <QLayout>
|
||||
|
||||
class FullSizeLayout : public QLayout
|
||||
{
|
||||
public:
|
||||
FullSizeLayout();
|
||||
~FullSizeLayout();
|
||||
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:
|
||||
QList<QLayoutItem*> itemList;
|
||||
};
|
||||
|
||||
#endif // FULLSIZELAYOUT_HPP
|
||||
141
main.cpp
Normal file
141
main.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
#include "mainwindow.h"
|
||||
#include "tiercard.hpp"
|
||||
#include "tierrow.hpp"
|
||||
#include "tiercardlayout.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "rowholder.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QImageReader>
|
||||
#include <QTimer>
|
||||
#include <QDockWidget>
|
||||
#include <QScrollArea>
|
||||
|
||||
// int main(int argc, char *argv[])
|
||||
// {
|
||||
// QApplication a(argc, argv);
|
||||
// // MainWindow w;
|
||||
// // w.show();
|
||||
// TierCard card;
|
||||
// // card.setGeometry(0, 0, 200, 200);
|
||||
// card.setFixedSize(200, 200);
|
||||
// card.set_text("SOME TEXT");
|
||||
// card.set_bg_color(QColor(255, 255, 255));
|
||||
// card.show();
|
||||
|
||||
// QNetworkAccessManager qnam;
|
||||
// QNetworkRequest req(QUrl("https://upload.wikimedia.org/wikipedia/en/4/4d/Shrek_%28character%29.png"));
|
||||
// auto resp = qnam.get(req);
|
||||
// QObject::connect(resp, &QNetworkReply::finished, [&card, resp]()
|
||||
// {
|
||||
// QImageReader reader(resp);
|
||||
// reader.setAutoDetectImageFormat(true);
|
||||
// QPixmap image = QPixmap::fromImageReader(&reader);
|
||||
// card.set_image(image);
|
||||
// });
|
||||
|
||||
// int fontSize = 10;
|
||||
// QColor bg_switcher(255, 128, 128);
|
||||
// QTimer bg_changer;
|
||||
// bg_changer.setTimerType(Qt::PreciseTimer);
|
||||
// bg_changer.setSingleShot(false);
|
||||
// bg_changer.setInterval(1000);
|
||||
// QObject::connect(&bg_changer, &QTimer::timeout, [&card, &bg_switcher, &fontSize, &a]()
|
||||
// {
|
||||
// card.set_bg_color(bg_switcher);
|
||||
// a.setStyleSheet(QString("*[cssClass=\"tierCardText\"]{font-size: %1pt}").arg(fontSize));
|
||||
// bg_switcher = QColor(bg_switcher.green(), bg_switcher.blue(), bg_switcher.red());
|
||||
// fontSize+=3;
|
||||
// });
|
||||
// bg_changer.start();
|
||||
|
||||
// return a.exec();
|
||||
// }
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
// QDockWidget dock;
|
||||
QScrollArea scroll;
|
||||
TierRow* row = TierRow::create();
|
||||
row->setColor(QColor(255, 128, 64));
|
||||
row->setText("Row Title");
|
||||
TierCard* card1 = TierCard::create();
|
||||
row->setStyleSheet(makeBgColorString(QColor(35,35,35)));
|
||||
card1->setText("CARD1");
|
||||
card1->setBgColor(QColor(64,255,64));
|
||||
card1->setFixedSize(150,150);
|
||||
TierCard* card2 = TierCard::create();
|
||||
card2->setText("CARD2");
|
||||
card2->setBgColor(QColor(64,64,255));
|
||||
card2->setFixedSize(150,150);
|
||||
row->addCard(card1);
|
||||
row->addCard(card2);
|
||||
|
||||
TierRow* row2 = TierRow::create();
|
||||
row2->setColor(QColor(128, 128, 255));
|
||||
row2->setText("Row Title");
|
||||
TierCard* card3 = TierCard::create();
|
||||
card3->setText("CARD1");
|
||||
card3->setBgColor(QColor(64,12,164));
|
||||
card3->setFixedSize(150,150);
|
||||
TierCard* card4 = TierCard::create();
|
||||
card4->setText("CARD2");
|
||||
card4->setBgColor(QColor(164,64,155));
|
||||
card4->setFixedSize(150,150);
|
||||
auto card5 = TierCard::clone(card4);
|
||||
card5->setFixedSize(150,150);
|
||||
row->addCard(card5);
|
||||
row2->addCard(card3);
|
||||
row2->addCard(card4);
|
||||
// row.show();
|
||||
|
||||
RowHolder holder;
|
||||
holder.setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
|
||||
// auto holderLayout = new QVBoxLayout();
|
||||
holder.addRow(row);
|
||||
holder.addRow(row2);
|
||||
|
||||
scroll.setWidget(&holder);
|
||||
scroll.setWidgetResizable(true);
|
||||
// dock.setWidget(&scroll);
|
||||
// w.dockWidgetArea(&dock);
|
||||
w.setCentralWidget(&scroll);
|
||||
w.show();
|
||||
|
||||
w.setStyleSheet(a.styleSheet()
|
||||
.append("#tierCardText {"
|
||||
" font-style: bold;"
|
||||
" font-size: 52; }")
|
||||
.append("#tierCardId {"
|
||||
" font-size: 24; }"));
|
||||
// a.setFont()
|
||||
// QTimer bg_changer;
|
||||
// bg_changer.setTimerType(Qt::PreciseTimer);
|
||||
// bg_changer.setSingleShot(false);
|
||||
// bg_changer.setInterval(1000);
|
||||
// QObject::connect(&bg_changer, &QTimer::timeout, [&row]()
|
||||
// {
|
||||
// row.updateGeometry();
|
||||
// });
|
||||
// bg_changer.start();
|
||||
// w.show();
|
||||
|
||||
// callOnMeAndChildren<TierRow>(&row, [](TierRow* obj)
|
||||
// {
|
||||
// auto wid = dynamic_cast<QWidget*>(obj);
|
||||
// if (wid)
|
||||
// {
|
||||
// auto size = wid->minimumSize();
|
||||
// if (std::max(size.height(), size.width()) >= 200)
|
||||
// {
|
||||
// qDebug() << wid->objectName() << ": " << size;
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// qDebug() << row.minimumSize() << row.layout()->minimumSize();
|
||||
return a.exec();
|
||||
}
|
||||
15
mainwindow.cpp
Normal file
15
mainwindow.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "mainwindow.h"
|
||||
#include "./ui_mainwindow.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
ui = nullptr;
|
||||
}
|
||||
23
mainwindow.h
Normal file
23
mainwindow.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
};
|
||||
#endif // MAINWINDOW_H
|
||||
31
mainwindow.ui
Normal file
31
mainwindow.ui
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget"/>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
109
myflowlayout.cpp
Normal file
109
myflowlayout.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
// #include "myflowlayout.hpp"
|
||||
// #include "qexception.h"
|
||||
// #include "qwidget.h"
|
||||
|
||||
// MyFlowLayout::MyFlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
|
||||
// : QLayout(parent), hSpace(hSpacing), vSpace(vSpacing)
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
// MyFlowLayout::MyFlowLayout(int margin, int hSpacing, int vSpacing)
|
||||
// : hSpace(hSpacing), vSpace(vSpacing)
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
// MyFlowLayout::~MyFlowLayout()
|
||||
// {
|
||||
// for (auto child : itemList)
|
||||
// {
|
||||
// delete child;
|
||||
// }
|
||||
// }
|
||||
|
||||
// void MyFlowLayout::addItem(QLayoutItem* item)
|
||||
// {
|
||||
// itemList.append(item);
|
||||
// }
|
||||
|
||||
// int MyFlowLayout::horizontalSpacing() const
|
||||
// {
|
||||
// return hSpace;
|
||||
// }
|
||||
|
||||
// int MyFlowLayout::verticalSpacing() const
|
||||
// {
|
||||
// return vSpace;
|
||||
// }
|
||||
|
||||
// Qt::Orientations MyFlowLayout::expandingDirections() const
|
||||
// {
|
||||
// return { };
|
||||
// }
|
||||
|
||||
// bool MyFlowLayout::hasHeightForWidth() const
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// int MyFlowLayout::heightForWidth(int width) const
|
||||
// {
|
||||
// QRect rect(0, 0, width, 0);
|
||||
// return doLayout(rect, false);
|
||||
// }
|
||||
|
||||
// QSize MyFlowLayout::minimumSize() const
|
||||
// {
|
||||
// QSize size(1,1);
|
||||
// for (auto child : itemList)
|
||||
// {
|
||||
// size = size.expandedTo(child->minimumSize());
|
||||
// }
|
||||
// return size;
|
||||
// }
|
||||
|
||||
// QLayoutItem* MyFlowLayout::itemAt(int index) const
|
||||
// {
|
||||
// return itemList.at(index);
|
||||
// }
|
||||
|
||||
// QLayoutItem* MyFlowLayout::takeAt(int index)
|
||||
// {
|
||||
// return itemList.takeAt(index);
|
||||
// }
|
||||
|
||||
// int MyFlowLayout::doLayout(const QRect &rect, bool apply) 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 : std::as_const(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 (apply)
|
||||
// item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
|
||||
|
||||
// x = nextX;
|
||||
// lineHeight = qMax(lineHeight, item->sizeHint().height());
|
||||
// }
|
||||
// return y + lineHeight - rect.y() + bottom;
|
||||
// }
|
||||
36
myflowlayout.hpp
Normal file
36
myflowlayout.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// #ifndef MYFLOWLAYOUT_HPP
|
||||
// #define MYFLOWLAYOUT_HPP
|
||||
|
||||
// #include <QLayout>
|
||||
// #include <QStyle>
|
||||
|
||||
// class MyFlowLayout : public QLayout
|
||||
// {
|
||||
// public:
|
||||
// explicit MyFlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
// explicit MyFlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
// ~MyFlowLayout();
|
||||
|
||||
// void addItem(QLayoutItem *item) override;
|
||||
// int horizontalSpacing() const;
|
||||
// int verticalSpacing() const;
|
||||
// Qt::Orientations expandingDirections() const override;
|
||||
// bool hasHeightForWidth() const override;
|
||||
// int heightForWidth(int width) 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 apply=true) const;
|
||||
// int smartSpacing(QStyle::PixelMetric pm) const;
|
||||
|
||||
// QList<QLayoutItem *> itemList;
|
||||
// int hSpace;
|
||||
// int vSpace;
|
||||
// };
|
||||
|
||||
// #endif // MYFLOWLAYOUT_HPP
|
||||
19
rowholder.cpp
Normal file
19
rowholder.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "rowholder.hpp"
|
||||
|
||||
RowHolder::RowHolder()
|
||||
{
|
||||
_layout = new QVBoxLayout();
|
||||
_layout->setAlignment(Qt::AlignTop);
|
||||
setLayout(_layout);
|
||||
}
|
||||
|
||||
void RowHolder::addRow(TierRow* row)
|
||||
{
|
||||
row->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
|
||||
_layout->addWidget(row, 0, Qt::AlignTop);
|
||||
}
|
||||
|
||||
RowHolder::~RowHolder()
|
||||
{
|
||||
|
||||
}
|
||||
25
rowholder.hpp
Normal file
25
rowholder.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef ROWHOLDER_HPP
|
||||
#define ROWHOLDER_HPP
|
||||
|
||||
#include "tierrow.hpp"
|
||||
|
||||
#include <QFrame>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
class RowHolder : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using IdType = uint32_t;
|
||||
RowHolder();
|
||||
~RowHolder();
|
||||
void addRow(TierRow* row);
|
||||
|
||||
|
||||
private:
|
||||
QVBoxLayout* _layout;
|
||||
};
|
||||
|
||||
#endif // ROWHOLDER_HPP
|
||||
5
settings.cpp
Normal file
5
settings.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
#include "settings.hpp"
|
||||
|
||||
Settings::Settings(QObject *parent)
|
||||
: QObject{parent}
|
||||
{}
|
||||
15
settings.hpp
Normal file
15
settings.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef SETTINGS_HPP
|
||||
#define SETTINGS_HPP
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class Settings : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Settings(QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
};
|
||||
|
||||
#endif // SETTINGS_HPP
|
||||
185
tiercard.cpp
Normal file
185
tiercard.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
#include "tiercard.hpp"
|
||||
#include "fullsizelayout.hpp"
|
||||
#include "qmimedata.h"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
// TierCard::TierCard(QWidget *parent)
|
||||
// : QWidget{parent}
|
||||
// {
|
||||
// auto bg_layout= new QVBoxLayout(this);
|
||||
// bg_layout->setSpacing(0);
|
||||
// bg_layout->setContentsMargins(0, 0, 0, 0);
|
||||
// background = new QWidget();
|
||||
// bg_layout->addWidget(background);
|
||||
// auto img_layout = new QVBoxLayout(background);
|
||||
// img_layout->setSpacing(0);
|
||||
// img_layout->setContentsMargins(0, 0, 0, 0);
|
||||
// image = new AspectRatioPixmapLabel();
|
||||
// img_layout->addWidget(image, 0, Qt::AlignCenter);
|
||||
// image->setAttribute(Qt::WA_TranslucentBackground);
|
||||
// image->setAlignment(Qt::AlignCenter);
|
||||
// auto txt_layout = new QVBoxLayout(image);
|
||||
// txt_layout->setSpacing(0);
|
||||
// txt_layout->setContentsMargins(0, 0, 0, 0);
|
||||
// text_label = new QLabel();
|
||||
// id_label = new QLabel("4");
|
||||
// text_label->setWordWrap(true);
|
||||
// // text_label->setTextFormat(Qt::RichText);
|
||||
// text_label->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
|
||||
// id_label->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
|
||||
// text_label->setAttribute(Qt::WA_TranslucentBackground);
|
||||
// id_label->setAttribute(Qt::WA_TranslucentBackground);
|
||||
// txt_layout->addWidget(text_label, Qt::AlignTop | Qt::AlignHCenter);
|
||||
// txt_layout->addWidget(id_label, Qt::AlignBottom, Qt::AlignLeft);
|
||||
// text_label->setProperty("cssClass", "tierCardText");
|
||||
// id_label->setProperty("cssClass", "tierCardId");
|
||||
// }
|
||||
|
||||
TierCard::IdType TierCard::getAvailableId()
|
||||
{
|
||||
for (IdType id = 1;; id++)
|
||||
{
|
||||
if (idMap.find(id) == idMap.end())
|
||||
{
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TierCard::releaseId(IdType id)
|
||||
{
|
||||
if (idMap.erase(id) == 0)
|
||||
{
|
||||
qDebug() << "Card id not found during destructor";
|
||||
}
|
||||
}
|
||||
|
||||
TierCard* TierCard::create(QWidget* parent)
|
||||
{
|
||||
TierCard* card;
|
||||
auto id = getAvailableId();
|
||||
card = new TierCard(id, parent);
|
||||
idMap[id] = card;
|
||||
return card;
|
||||
}
|
||||
|
||||
TierCard* TierCard::clone(TierCard *other, QWidget* parent)
|
||||
{
|
||||
TierCard* card;
|
||||
auto id = getAvailableId();
|
||||
card = new TierCard(id, parent);
|
||||
card->setText(other->getText());
|
||||
auto img = other->getImage();
|
||||
card->setImage(img);
|
||||
card->setBgColor(other->getBgColor());
|
||||
idMap[id] = card;
|
||||
return card;
|
||||
}
|
||||
|
||||
TierCard::TierCard(IdType id, QWidget* parent)
|
||||
: QWidget{parent}
|
||||
{
|
||||
background = new QWidget();
|
||||
image = new AspectRatioPixmapLabel();
|
||||
image->setAttribute(Qt::WA_TranslucentBackground);
|
||||
image->setAlignment(Qt::AlignCenter);
|
||||
textLabel = new QLabel();
|
||||
idLabel = new QLabel();
|
||||
textLabel->setWordWrap(true);
|
||||
// text_label->setTextFormat(Qt::RichText);
|
||||
textLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
|
||||
idLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
|
||||
textLabel->setAttribute(Qt::WA_TranslucentBackground);
|
||||
idLabel->setAttribute(Qt::WA_TranslucentBackground);
|
||||
textLabel->setObjectName("tierCardText");
|
||||
idLabel->setObjectName("tierCardId");
|
||||
idLabel->setText(QString::number(id));
|
||||
auto layout = new FullSizeLayout();
|
||||
layout->addWidget(background);
|
||||
layout->addWidget(image);
|
||||
layout->addWidget(textLabel);
|
||||
layout->addWidget(idLabel);
|
||||
this->setLayout(layout);
|
||||
}
|
||||
|
||||
TierCard::~TierCard()
|
||||
{
|
||||
releaseId(getId());
|
||||
// delete text_label;
|
||||
// text_label = nullptr;
|
||||
// delete id_label;
|
||||
// id_label = nullptr;
|
||||
}
|
||||
|
||||
void TierCard::setText(QString str)
|
||||
{
|
||||
textLabel->setText(str);
|
||||
}
|
||||
|
||||
QString TierCard::getText() const
|
||||
{
|
||||
return textLabel->text();
|
||||
}
|
||||
|
||||
uint32_t TierCard::getId() const
|
||||
{
|
||||
return static_cast<uint32_t>(idLabel->text().toUInt());
|
||||
}
|
||||
|
||||
void TierCard::setBgColor(QColor color)
|
||||
{
|
||||
bgColor = color;
|
||||
auto str = makeBgColorString(color);
|
||||
background->setStyleSheet(str);
|
||||
}
|
||||
|
||||
QColor TierCard::getBgColor()
|
||||
{
|
||||
return bgColor;
|
||||
}
|
||||
|
||||
void TierCard::setImage(const QPixmap img)
|
||||
{
|
||||
// QMetaObject::invokeMethod()
|
||||
image->setPixmap(img);
|
||||
}
|
||||
|
||||
QPixmap TierCard::getImage() const
|
||||
{
|
||||
return image->pixmap();
|
||||
}
|
||||
|
||||
void TierCard::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
qDebug() << "mouse press event";
|
||||
QPixmap pix(size());
|
||||
render(&pix);
|
||||
QDrag drag(this);
|
||||
drag.setPixmap(pix);
|
||||
QByteArray itemData;
|
||||
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
|
||||
auto _id = getId();
|
||||
dataStream.writeRawData(reinterpret_cast<char*>(&_id), sizeof(_id));
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData(MimeType, itemData);
|
||||
drag.setMimeData(mimeData);
|
||||
hide();
|
||||
if (drag.exec() == Qt::MoveAction)
|
||||
{
|
||||
show();
|
||||
}
|
||||
else
|
||||
{
|
||||
show();
|
||||
}
|
||||
}
|
||||
|
||||
TierCard* TierCard::getFromId(IdType id)
|
||||
{
|
||||
auto iter = idMap.find(id);
|
||||
if (iter == idMap.end())
|
||||
return nullptr;
|
||||
return &(*iter->second);
|
||||
}
|
||||
49
tiercard.hpp
Normal file
49
tiercard.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef TIERCARD_H
|
||||
#define TIERCARD_H
|
||||
|
||||
#include "aspectratiopixmaplabel.hpp"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QColor>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
class TierCard : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using IdType = uint32_t;
|
||||
inline static const char* MimeType = "application/x-tiercard";
|
||||
TierCard(TierCard const&) = delete;
|
||||
~TierCard();
|
||||
static TierCard* create(QWidget *parent = nullptr);
|
||||
static TierCard* clone(TierCard *other, QWidget* parent = nullptr);
|
||||
static TierCard* getFromId(IdType id);
|
||||
void setText(QString str);
|
||||
QString getText() const;
|
||||
void setImage(const QPixmap img);
|
||||
QPixmap getImage() const;
|
||||
IdType getId() const;
|
||||
void setBgColor(QColor color);
|
||||
QColor getBgColor();
|
||||
// QColor bg_color() const;
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
|
||||
private:
|
||||
explicit TierCard(IdType id, QWidget *parent = nullptr);
|
||||
QWidget* background;
|
||||
AspectRatioPixmapLabel* image;
|
||||
QLabel* textLabel;
|
||||
QLabel* idLabel;
|
||||
QColor bgColor;
|
||||
static IdType getAvailableId();
|
||||
static void releaseId(IdType id);
|
||||
inline static std::unordered_map<IdType, TierCard*> idMap;
|
||||
|
||||
signals:
|
||||
};
|
||||
|
||||
#endif // TIERCARD_H
|
||||
30
tiercardlayout.cpp
Normal file
30
tiercardlayout.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// #include "tiercardlayout.hpp"
|
||||
// #include <QException>
|
||||
|
||||
// TierCardLayout::TierCardLayout()
|
||||
// {
|
||||
// // itemList.append(nullptr);
|
||||
// // itemList.append(nullptr);
|
||||
// // itemList.append(nullptr);
|
||||
// }
|
||||
|
||||
// TierCardLayout::~TierCardLayout()
|
||||
// {
|
||||
// // QLayoutItem *item;
|
||||
// // while ((item = takeAt(0)))
|
||||
// // delete item;
|
||||
// delete image;
|
||||
// delete text;
|
||||
// delete id;
|
||||
// }
|
||||
|
||||
// void TierCardLayout::addItem(QLayoutItem *item)
|
||||
// {
|
||||
// // itemList.append(item);
|
||||
// throw new QException();
|
||||
// }
|
||||
|
||||
// QLayoutItem* TierCardLayout::itemAt(int index) const
|
||||
// {
|
||||
// throw new QException();
|
||||
// }
|
||||
31
tiercardlayout.hpp
Normal file
31
tiercardlayout.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
// #ifndef TIERCARDLAYOUT_HPP
|
||||
// #define TIERCARDLAYOUT_HPP
|
||||
|
||||
// #include <QLayout>
|
||||
// #include <QLabel>
|
||||
|
||||
// class TierCardLayout : public QLayout
|
||||
// {
|
||||
// public:
|
||||
// TierCardLayout();
|
||||
// ~TierCardLayout();
|
||||
// void addItem(QLayoutItem *item) override;
|
||||
// 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;
|
||||
// public
|
||||
|
||||
// private:
|
||||
// QList<QLayoutItem *> itemList;
|
||||
// QLabel* image;
|
||||
// QLabel* text;
|
||||
// QLabel* id;
|
||||
// };
|
||||
|
||||
// #endif // TIERCARDLAYOUT_HPP
|
||||
198
tierrow.cpp
Normal file
198
tierrow.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
#include "tierrow.hpp"
|
||||
#include "fullsizelayout.hpp"
|
||||
#include "qmimedata.h"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
||||
TierRow::TierRow(IdType id, QWidget *parent)
|
||||
: QWidget{parent}
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
auto fadeLayout = new FullSizeLayout();
|
||||
fadeLayout->setSizeConstraint(QLayout::SetMinimumSize);
|
||||
fadeLayout->setContentsMargins(0, 0, 0, 0);
|
||||
fadeLayout->setSpacing(0);
|
||||
bgFadeContainer = new QWidget();
|
||||
bgFadeContainer->setStyleSheet(makeBgColorString(QColor(255,255,255,100)));
|
||||
bgFadeContainer->setMinimumSize(0, 0);
|
||||
fadeLayout->addWidget(bgFadeContainer);
|
||||
this->setLayout(fadeLayout);
|
||||
auto splitLayout = new QHBoxLayout();
|
||||
splitLayout->setSizeConstraint(QLayout::SetMinimumSize);
|
||||
splitLayout->setContentsMargins(0, 0, 0, 0);
|
||||
splitLayout->setSpacing(0);
|
||||
titleCard = new TierRowTitleCard(id);
|
||||
cardContainer = new QWidget();
|
||||
cardContainer->setMinimumSize(0, 0);
|
||||
titleCard->setFixedSize(150, 150);
|
||||
cardContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
splitLayout->addWidget(titleCard, 0, Qt::AlignLeft | Qt::AlignTop);
|
||||
splitLayout->addWidget(cardContainer, 1, Qt::AlignTop);
|
||||
|
||||
cardContainer->setStyleSheet(makeBgColorString(QColor(60,60,60,100)));
|
||||
|
||||
bgFadeContainer->setLayout(splitLayout);
|
||||
cardLayout = new FlowLayout();
|
||||
cardLayout->setSizeConstraint(QLayout::SetMinimumSize);
|
||||
cardLayout->setContentsMargins(0, 0, 0, 0);
|
||||
cardLayout->setSpacing(0);
|
||||
cardContainer->setLayout(cardLayout);
|
||||
// setMinimumSize(0, 0);
|
||||
}
|
||||
|
||||
TierRow::~TierRow()
|
||||
{
|
||||
qDebug() << "Row destructor called " << id();
|
||||
if (idMap.erase(id()) == 0)
|
||||
{
|
||||
qDebug() << "Row id not found during destructor";
|
||||
}
|
||||
}
|
||||
|
||||
void TierRow::addCard(TierCard* card)
|
||||
{
|
||||
cardContainer->layout()->addWidget(card);
|
||||
}
|
||||
// TierCard* TierRow::takeCard(uint32_t id)
|
||||
// {
|
||||
// for (auto i : cardContainer->children())
|
||||
// }
|
||||
void TierRow::setColor(QColor color)
|
||||
{
|
||||
_color = color;
|
||||
titleCard->setColor(color);
|
||||
auto str = makeBgColorString(color);
|
||||
setStyleSheet(str);
|
||||
}
|
||||
QColor TierRow::color()
|
||||
{
|
||||
return _color;
|
||||
}
|
||||
void TierRow::setText(QString text)
|
||||
{
|
||||
titleCard->setText(text);
|
||||
}
|
||||
QString TierRow::text()
|
||||
{
|
||||
return titleCard->text();
|
||||
}
|
||||
uint32_t TierRow::id()
|
||||
{
|
||||
return titleCard->id();
|
||||
}
|
||||
|
||||
void TierRow::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
this->QWidget::resizeEvent(event);
|
||||
recalcMaxHeight();
|
||||
}
|
||||
|
||||
void TierRow::recalcMaxHeight()
|
||||
{
|
||||
setMaximumHeight(cardLayout->totalMinimumHeightForWidth(cardContainer->width()));
|
||||
}
|
||||
|
||||
TierRow* TierRow::create(QWidget* parent)
|
||||
{
|
||||
TierRow* row;
|
||||
for (IdType id = 1;; id++)
|
||||
{
|
||||
if (idMap.find(id) == idMap.end())
|
||||
{
|
||||
row = new TierRow(id, parent);
|
||||
idMap[id] = row;
|
||||
return row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TierRow* TierRow::getFromId(IdType id)
|
||||
{
|
||||
auto iter = idMap.find(id);
|
||||
if (iter == idMap.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
void TierRow::dropEvent(QDropEvent *event)
|
||||
{
|
||||
qDebug() << "drop event";
|
||||
//card dragged to this row
|
||||
if (event->mimeData()->hasFormat(TierCard::MimeType))
|
||||
{
|
||||
if (event->proposedAction() == Qt::MoveAction)
|
||||
{
|
||||
auto data = event->mimeData()->data(TierCard::MimeType);
|
||||
QDataStream stream(&data, QIODevice::ReadOnly);
|
||||
TierCard::IdType cardId;
|
||||
uint dataLen = 0;
|
||||
stream.readRawData(reinterpret_cast<char*>(&cardId), dataLen);
|
||||
auto card = TierCard::getFromId(cardId);
|
||||
addCard(card);
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
else
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
//image(s) dragged to make new card(s)
|
||||
else if (event->mimeData()->hasImage())
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void TierRow::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
qDebug() << "drag enter event";
|
||||
if (event->mimeData()->hasFormat(TierCard::MimeType))
|
||||
{
|
||||
if (event->proposedAction() == Qt::MoveAction)
|
||||
{
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept(cardContainer->rect());
|
||||
}
|
||||
else
|
||||
{
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept(cardContainer->geometry());
|
||||
}
|
||||
}
|
||||
else if (event->mimeData()->hasImage())
|
||||
{
|
||||
event->setDropAction(Qt::CopyAction);
|
||||
event->accept();
|
||||
}
|
||||
else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void TierRow::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
qDebug() << "drag move event";
|
||||
if (event->mimeData()->hasFormat(TierCard::MimeType))
|
||||
{
|
||||
if (event->proposedAction() == Qt::MoveAction)
|
||||
{
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
else
|
||||
{
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept(cardContainer->geometry());
|
||||
}
|
||||
}
|
||||
else if (event->mimeData()->hasImage())
|
||||
{
|
||||
event->setDropAction(Qt::CopyAction);
|
||||
event->accept();
|
||||
}
|
||||
else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
51
tierrow.hpp
Normal file
51
tierrow.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef TIERROW_HPP
|
||||
#define TIERROW_HPP
|
||||
|
||||
#include "tiercard.hpp"
|
||||
#include "tierrowtitlecard.hpp"
|
||||
#include "flowlayout.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDrag>
|
||||
|
||||
class TierRow : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using IdType = TierRowTitleCard::IdType;
|
||||
static TierRow* create(QWidget* parent = nullptr);
|
||||
static TierRow* getFromId(IdType id);
|
||||
~TierRow();
|
||||
void addCard(TierCard* card);
|
||||
TierCard* takeCard(uint32_t id);
|
||||
void setColor(QColor color);
|
||||
QColor color();
|
||||
void setText(QString text);
|
||||
QString text();
|
||||
uint32_t id();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
// void mousePressEvent(QMouseEvent* event) override;
|
||||
void dropEvent(QDropEvent *event) override;
|
||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||
void dragMoveEvent(QDragMoveEvent *event) override;
|
||||
|
||||
private:
|
||||
explicit TierRow(IdType id, QWidget* parent = nullptr);
|
||||
TierRowTitleCard* titleCard;
|
||||
QWidget* bgFadeContainer;
|
||||
QWidget* cardContainer;
|
||||
QLayout* cardLayout;
|
||||
QColor _color;
|
||||
void recalcMaxHeight();
|
||||
inline static std::unordered_map<IdType, TierRow*> idMap;
|
||||
|
||||
public slots:
|
||||
void cardResize(QRect newSize);
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
#endif // TIERROW_HPP
|
||||
42
tierrowtitlecard.cpp
Normal file
42
tierrowtitlecard.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "tierrowtitlecard.hpp"
|
||||
#include "fullsizelayout.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <QFrame>
|
||||
|
||||
TierRowTitleCard::TierRowTitleCard(IdType id, QWidget *parent)
|
||||
: QFrame{parent}
|
||||
{
|
||||
this->setFrameStyle(QFrame::Box | QFrame::Plain);
|
||||
auto layout = new FullSizeLayout();
|
||||
titleLabel = new QLabel();
|
||||
idLabel = new QLabel();
|
||||
layout->addWidget(titleLabel);
|
||||
layout->addWidget(idLabel);
|
||||
setLayout(layout);
|
||||
}
|
||||
QString TierRowTitleCard::text() const
|
||||
{
|
||||
return titleLabel->text();
|
||||
}
|
||||
|
||||
QColor TierRowTitleCard::color() const
|
||||
{
|
||||
return _color;
|
||||
}
|
||||
|
||||
void TierRowTitleCard::setText(QString& str)
|
||||
{
|
||||
titleLabel->setText(str);
|
||||
}
|
||||
|
||||
void TierRowTitleCard::setColor(QColor color)
|
||||
{
|
||||
_color = color;
|
||||
setStyleSheet(makeBgColorString(color));
|
||||
}
|
||||
|
||||
uint32_t TierRowTitleCard::id() const
|
||||
{
|
||||
return static_cast<uint32_t>(idLabel->text().toUInt());
|
||||
}
|
||||
27
tierrowtitlecard.hpp
Normal file
27
tierrowtitlecard.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef TIERROWTITLECARD_HPP
|
||||
#define TIERROWTITLECARD_HPP
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
|
||||
class TierRowTitleCard : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using IdType = uint32_t;
|
||||
explicit TierRowTitleCard(IdType id, QWidget *parent = nullptr);
|
||||
void setColor(QColor color);
|
||||
QColor color() const;
|
||||
void setText(QString& text);
|
||||
QString text() const;
|
||||
uint32_t id() const;
|
||||
|
||||
private:
|
||||
QColor _color;
|
||||
QLabel* titleLabel;
|
||||
QLabel* idLabel;
|
||||
|
||||
signals:
|
||||
};
|
||||
|
||||
#endif // TIERROWTITLECARD_HPP
|
||||
56
utils.hpp
Normal file
56
utils.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef UTILS_HPP
|
||||
#define UTILS_HPP
|
||||
|
||||
#include "tierrow.hpp"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QString>
|
||||
|
||||
//change this stupid name
|
||||
inline void callOnMeAndChildren(QObject* obj, void (*func)(QObject*))
|
||||
{
|
||||
func(obj);
|
||||
for (auto w : obj->children())
|
||||
{
|
||||
callOnMeAndChildren(w, func);
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
void callOnMeAndChildren(QObject* obj, void (*func)(T*))
|
||||
{
|
||||
if (auto casted = dynamic_cast<T*>(obj))
|
||||
{
|
||||
func(casted);
|
||||
}
|
||||
for (auto w : obj->children())
|
||||
{
|
||||
callOnMeAndChildren(w, func);
|
||||
}
|
||||
}
|
||||
|
||||
inline QString makeBgColorString(QColor color)
|
||||
{
|
||||
return QString("background-color: rgba(%1,%2,%3,%4)")
|
||||
.arg(QString::number(color.red()),
|
||||
QString::number(color.green()),
|
||||
QString::number(color.blue()),
|
||||
QString::number(color.alphaF()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* findParentOfType(QObject* obj)
|
||||
{
|
||||
auto parent = obj->parent();
|
||||
if (!parent)
|
||||
return nullptr;
|
||||
else if (auto asT = dynamic_cast<T*>(parent))
|
||||
{
|
||||
return asT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return findParentOfType<T>(parent);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // UTILS_HPP
|
||||
Reference in New Issue
Block a user