From ce0a8a6444d1df004c2786bdc465c2ef9a34bc0f Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Tue, 5 Jun 2018 16:24:13 +0200 Subject: [PATCH] ui: Use flow layout in source group selection window --- bin/app/data/gui/window/window.css | 2 +- src/lib_gui/CMakeLists.txt | 2 + src/lib_gui/qt/utility/QtFlowLayout.cpp | 183 ++++++++++++++++++ src/lib_gui/qt/utility/QtFlowLayout.h | 47 +++++ src/lib_gui/qt/window/QtWindow.cpp | 1 - .../project_wizzard/QtProjectWizzard.cpp | 3 +- .../QtProjectWizzardContentSelect.cpp | 24 ++- 7 files changed, 250 insertions(+), 12 deletions(-) create mode 100644 src/lib_gui/qt/utility/QtFlowLayout.cpp create mode 100644 src/lib_gui/qt/utility/QtFlowLayout.h diff --git a/bin/app/data/gui/window/window.css b/bin/app/data/gui/window/window.css index ee46efeb..62aa65d3 100644 --- a/bin/app/data/gui/window/window.css +++ b/bin/app/data/gui/window/window.css @@ -164,7 +164,7 @@ QCheckBox:disabled { font-size: 12px; width: 7em; height: 8em; - margin-top: 10px; + margin: 5px; } #sourceGroupButton:hover, #sourceGroupButton:checked { diff --git a/src/lib_gui/CMakeLists.txt b/src/lib_gui/CMakeLists.txt index 93604118..d4d78841 100644 --- a/src/lib_gui/CMakeLists.txt +++ b/src/lib_gui/CMakeLists.txt @@ -108,6 +108,8 @@ add_files( qt/utility/QtFileDialog.h qt/utility/QtFilesAndDirectoriesDialog.cpp qt/utility/QtFilesAndDirectoriesDialog.h + qt/utility/QtFlowLayout.cpp + qt/utility/QtFlowLayout.h qt/utility/QtHighlighter.cpp qt/utility/QtHighlighter.h qt/utility/QtScrollSpeedChangeListener.cpp diff --git a/src/lib_gui/qt/utility/QtFlowLayout.cpp b/src/lib_gui/qt/utility/QtFlowLayout.cpp new file mode 100644 index 00000000..fa525b4b --- /dev/null +++ b/src/lib_gui/qt/utility/QtFlowLayout.cpp @@ -0,0 +1,183 @@ +// from: http://doc.qt.io/qt-5/qtwidgets-layouts-flowlayout-flowlayout-cpp.html + +#include "qt/utility/QtFlowLayout.h" + +#include + +QtFlowLayout::QtFlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) + : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) +{ + setContentsMargins(margin, margin, margin, margin); +} + +QtFlowLayout::QtFlowLayout(int margin, int hSpacing, int vSpacing) + : m_hSpace(hSpacing), m_vSpace(vSpacing) +{ + setContentsMargins(margin, margin, margin, margin); +} + +QtFlowLayout::~QtFlowLayout() +{ + QLayoutItem *item; + while ((item = takeAt(0))) + { + delete item; + } +} + +void QtFlowLayout::addItem(QLayoutItem *item) +{ + itemList.append(item); +} + +int QtFlowLayout::horizontalSpacing() const +{ + if (m_hSpace >= 0) + { + return m_hSpace; + } + else + { + return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); + } +} + +int QtFlowLayout::verticalSpacing() const +{ + if (m_vSpace >= 0) + { + return m_vSpace; + } + else + { + return smartSpacing(QStyle::PM_LayoutVerticalSpacing); + } +} + +int QtFlowLayout::count() const +{ + return itemList.size(); +} + +QLayoutItem *QtFlowLayout::itemAt(int index) const +{ + return itemList.value(index); +} + +QLayoutItem *QtFlowLayout::takeAt(int index) +{ + if (index >= 0 && index < itemList.size()) + { + return itemList.takeAt(index); + } + + return 0; +} + +Qt::Orientations QtFlowLayout::expandingDirections() const +{ + return 0; +} + +bool QtFlowLayout::hasHeightForWidth() const +{ + return true; +} + +int QtFlowLayout::heightForWidth(int width) const +{ + int height = doLayout(QRect(0, 0, width, 0), true); + return height; +} + +void QtFlowLayout::setGeometry(const QRect &rect) +{ + QLayout::setGeometry(rect); + doLayout(rect, false); +} + +QSize QtFlowLayout::sizeHint() const +{ + return minimumSize(); +} + +QSize QtFlowLayout::minimumSize() const +{ + QSize size; + QLayoutItem *item; + foreach (item, itemList) + { + size = size.expandedTo(item->minimumSize()); + } + + size += QSize(2*margin(), 2*margin()); + return size; +} + +int QtFlowLayout::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; + + QLayoutItem *item; + foreach (item, itemList) + { + 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 QtFlowLayout::smartSpacing(QStyle::PixelMetric pm) const +{ + QObject *parent = this->parent(); + if (!parent) + { + return -1; + } + else if (parent->isWidgetType()) + { + QWidget *pw = static_cast(parent); + return pw->style()->pixelMetric(pm, 0, pw); + } + else + { + return static_cast(parent)->spacing(); + } +} diff --git a/src/lib_gui/qt/utility/QtFlowLayout.h b/src/lib_gui/qt/utility/QtFlowLayout.h new file mode 100644 index 00000000..e9e1d01a --- /dev/null +++ b/src/lib_gui/qt/utility/QtFlowLayout.h @@ -0,0 +1,47 @@ +// from: http://doc.qt.io/qt-5/qtwidgets-layouts-flowlayout-flowlayout-h.html + +#ifndef QT_FLOW_LAYOUT_H +#define QT_FLOW_LAYOUT_H + +#include +#include +#include + +class QtFlowLayout + : public QLayout +{ +public: + explicit QtFlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); + explicit QtFlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1); + ~QtFlowLayout(); + + int horizontalSpacing() const; + int verticalSpacing() const; + + Qt::Orientations expandingDirections() const override; + + QSize minimumSize() const override; + void setGeometry(const QRect &rect) override; + QSize sizeHint() const override; + + bool hasHeightForWidth() const override; + int heightForWidth(int) const override; + + + void addItem(QLayoutItem *item) override; + QLayoutItem *itemAt(int index) const override; + QLayoutItem *takeAt(int index) override; + + int count() const override; + +private: + int doLayout(const QRect &rect, bool testOnly) const; + int smartSpacing(QStyle::PixelMetric pm) const; + + QList itemList; + + int m_hSpace; + int m_vSpace; +}; + +#endif // QT_FLOW_LAYOUT_H diff --git a/src/lib_gui/qt/window/QtWindow.cpp b/src/lib_gui/qt/window/QtWindow.cpp index f13d2db2..ebe08473 100644 --- a/src/lib_gui/qt/window/QtWindow.cpp +++ b/src/lib_gui/qt/window/QtWindow.cpp @@ -197,7 +197,6 @@ void QtWindow::moveToCenter() else { move( - parentWidget()->pos().x() + parentWidget()->width() / 2 - sizeHint().width() / 2, parentWidget()->pos().y() + parentWidget()->height() / 2 - sizeHint().height() / 2 ); diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp index 74e81f06..0ec3e35f 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp @@ -676,10 +676,11 @@ void QtProjectWizzard::newSourceGroup() QtProjectWizzardWindow* window = createWindowWithContent( [](QtProjectWizzardWindow* window) { - window->setPreferredSize(QSize(570, 380)); + window->setPreferredSize(QSize(680, 400)); return new QtProjectWizzardContentSelect(window); } ); + window->resize(QSize(680, 400)); connect(dynamic_cast(window->content()), &QtProjectWizzardContentSelect::selected, diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSelect.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSelect.cpp index 187e36b7..83825b29 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSelect.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSelect.cpp @@ -6,6 +6,7 @@ #include #include "qt/window/project_wizzard/QtProjectWizzardWindow.h" +#include "qt/utility/QtFlowLayout.h" #include "settings/LanguageType.h" #include "utility/ResourcePaths.h" #include "utility/utilityString.h" @@ -112,7 +113,7 @@ void QtProjectWizzardContentSelect::populate(QGridLayout* layout, int& row) } ); - QHBoxLayout* hlayout = new QHBoxLayout(); + QtFlowLayout* flayout = new QtFlowLayout(10, 0, 0); for (auto& languageIt: sourceGroupInfos) { @@ -126,7 +127,7 @@ void QtProjectWizzardContentSelect::populate(QGridLayout* layout, int& row) ); b->setProperty("source_group_type", int(sourceGroupIt.type)); sourceGroupButtons->addButton(b); - hlayout->addWidget(b); + flayout->addWidget(b); } m_buttons[languageIt.first] = sourceGroupButtons; @@ -152,19 +153,25 @@ void QtProjectWizzardContentSelect::populate(QGridLayout* layout, int& row) ); } - QFrame* container = new QFrame(); - container->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - container->setObjectName("sourceGroupContainer"); - container->setLayout(hlayout); + QWidget* container = new QWidget(); + QVBoxLayout* containerLayout = new QVBoxLayout(); + containerLayout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(container, 0, QtProjectWizzardWindow::BACK_COL); + QFrame* groupContainer = new QFrame(); + groupContainer->setObjectName("sourceGroupContainer"); + groupContainer->setLayout(flayout); + containerLayout->addWidget(groupContainer, 0); m_description = new QLabel(" \n \n"); m_description->setWordWrap(true); m_description->setOpenExternalLinks(true); m_description->setObjectName("sourceGroupDescription"); m_description->setTextInteractionFlags(Qt::TextSelectableByMouse); - layout->addWidget(m_description, 1, QtProjectWizzardWindow::BACK_COL); + m_description->setMinimumHeight(80); + containerLayout->addWidget(m_description, 0); + + container->setLayout(containerLayout); + layout->addWidget(container, 0, QtProjectWizzardWindow::BACK_COL); m_title = new QLabel("Source Group Types"); m_title->setObjectName("sourceGroupTitle"); @@ -172,7 +179,6 @@ void QtProjectWizzardContentSelect::populate(QGridLayout* layout, int& row) layout->addWidget(m_title, 0, QtProjectWizzardWindow::BACK_COL, Qt::AlignLeft | Qt::AlignTop); layout->setRowStretch(0, 0); - layout->setRowStretch(1, 1); layout->setColumnStretch(QtProjectWizzardWindow::FRONT_COL, 0); layout->setColumnStretch(QtProjectWizzardWindow::BACK_COL, 1); layout->setHorizontalSpacing(0);