Implemented basic grid rendering of task strips
This commit is contained in:
103
.gitignore
vendored
103
.gitignore
vendored
@@ -1,52 +1,73 @@
|
|||||||
# C++ objects and libs
|
# This file is used to ignore files which are generated
|
||||||
*.slo
|
# ----------------------------------------------------------------------------
|
||||||
*.lo
|
|
||||||
*.o
|
*~
|
||||||
|
*.autosave
|
||||||
*.a
|
*.a
|
||||||
*.la
|
*.core
|
||||||
*.lai
|
*.moc
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
*.so
|
*.so
|
||||||
*.so.*
|
*.so.*
|
||||||
*.dll
|
*_pch.h.cpp
|
||||||
*.dylib
|
*_resource.rc
|
||||||
|
*.qm
|
||||||
# Qt-es
|
.#*
|
||||||
object_script.*.Release
|
*.*#
|
||||||
object_script.*.Debug
|
core
|
||||||
*_plugin_import.cpp
|
!core/
|
||||||
|
tags
|
||||||
|
.DS_Store
|
||||||
|
.directory
|
||||||
|
*.debug
|
||||||
|
Makefile*
|
||||||
|
*.prl
|
||||||
|
*.app
|
||||||
|
moc_*.cpp
|
||||||
|
ui_*.h
|
||||||
|
qrc_*.cpp
|
||||||
|
Thumbs.db
|
||||||
|
*.res
|
||||||
|
*.rc
|
||||||
/.qmake.cache
|
/.qmake.cache
|
||||||
/.qmake.stash
|
/.qmake.stash
|
||||||
*.pro.user
|
|
||||||
*.pro.user.*
|
|
||||||
*.qbs.user
|
|
||||||
*.qbs.user.*
|
|
||||||
*.moc
|
|
||||||
moc_*.cpp
|
|
||||||
moc_*.h
|
|
||||||
qrc_*.cpp
|
|
||||||
ui_*.h
|
|
||||||
*.qmlc
|
|
||||||
*.jsc
|
|
||||||
Makefile*
|
|
||||||
*build-*
|
|
||||||
*.qm
|
|
||||||
*.prl
|
|
||||||
|
|
||||||
# Qt unit tests
|
# qtcreator generated files
|
||||||
target_wrapper.*
|
*.pro.user*
|
||||||
|
|
||||||
# QtCreator
|
# xemacs temporary files
|
||||||
*.autosave
|
*.flc
|
||||||
|
|
||||||
# QtCreator Qml
|
# Vim temporary files
|
||||||
*.qmlproject.user
|
.*.swp
|
||||||
*.qmlproject.user.*
|
|
||||||
|
|
||||||
# QtCreator CMake
|
# Visual Studio generated files
|
||||||
CMakeLists.txt.user*
|
*.ib_pdb_index
|
||||||
|
*.idb
|
||||||
|
*.ilk
|
||||||
|
*.pdb
|
||||||
|
*.sln
|
||||||
|
*.suo
|
||||||
|
*.vcproj
|
||||||
|
*vcproj.*.*.user
|
||||||
|
*.ncb
|
||||||
|
*.sdf
|
||||||
|
*.opensdf
|
||||||
|
*.vcxproj
|
||||||
|
*vcxproj.*
|
||||||
|
|
||||||
# QtCreator 4.8< compilation database
|
# MinGW generated files
|
||||||
compile_commands.json
|
*.Debug
|
||||||
|
*.Release
|
||||||
|
|
||||||
|
# Python byte code
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Binaries
|
||||||
|
# --------
|
||||||
|
*.dll
|
||||||
|
*.exe
|
||||||
|
|
||||||
# QtCreator local machine specific files for imported projects
|
|
||||||
*creator.user*
|
|
||||||
|
21
SprintPlanningTool.pro
Normal file
21
SprintPlanningTool.pro
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
QT = core gui widgets
|
||||||
|
|
||||||
|
CONFIG += c++17
|
||||||
|
|
||||||
|
DEFINES += QT_DEPRECATED_WARNINGS QT_DISABLE_DEPRECATED_BEFORE=0x060000
|
||||||
|
|
||||||
|
SOURCES += main.cpp \
|
||||||
|
flowlayout.cpp \
|
||||||
|
mainwindow.cpp \
|
||||||
|
stripsgrid.cpp \
|
||||||
|
stripwidget.cpp
|
||||||
|
|
||||||
|
FORMS += \
|
||||||
|
mainwindow.ui \
|
||||||
|
stripwidget.ui
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
flowlayout.h \
|
||||||
|
mainwindow.h \
|
||||||
|
stripsgrid.h \
|
||||||
|
stripwidget.h
|
150
flowlayout.cpp
Normal file
150
flowlayout.cpp
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
#include "flowlayout.h"
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
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 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 : qAsConst(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 : qAsConst(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();
|
||||||
|
}
|
||||||
|
}
|
34
flowlayout.h
Normal file
34
flowlayout.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#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;
|
||||||
|
};
|
14
main.cpp
Normal file
14
main.cpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "stripwidget.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
|
MainWindow mainWindow;
|
||||||
|
mainWindow.show();
|
||||||
|
|
||||||
|
return a.exec();
|
||||||
|
}
|
11
mainwindow.cpp
Normal file
11
mainwindow.cpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
QMainWindow{parent},
|
||||||
|
m_ui{std::make_unique<Ui::MainWindow>()}
|
||||||
|
{
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow() = default;
|
19
mainwindow.h
Normal file
19
mainwindow.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace Ui { class MainWindow; }
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget *parent = nullptr);
|
||||||
|
~MainWindow() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Ui::MainWindow> m_ui;
|
||||||
|
};
|
81
mainwindow.ui
Normal file
81
mainwindow.ui
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<?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="QScrollArea" name="scrollArea">
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="StripsGrid" name="stripsGrid">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>798</width>
|
||||||
|
<height>558</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>18</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menu_File">
|
||||||
|
<property name="title">
|
||||||
|
<string>&File</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="action_Quit"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menu_File"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
<action name="action_Quit">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Quit</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>StripsGrid</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>stripsgrid.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>action_Quit</sender>
|
||||||
|
<signal>triggered()</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>close()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>-1</x>
|
||||||
|
<y>-1</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>399</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
187
stripsgrid.cpp
Normal file
187
stripsgrid.cpp
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
#include "stripsgrid.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QGraphicsOpacityEffect>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QSpacerItem>
|
||||||
|
#include <QRandomGenerator>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
|
#include "stripwidget.h"
|
||||||
|
#include "flowlayout.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
QDebug &operator<<(QDebug &debug, const QMouseEvent &event)
|
||||||
|
{
|
||||||
|
return debug << "QMouseEvent(" << event.pos() << event.source() << event.flags() << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void call_n_times(int count, T func)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StripsGrid::StripsGrid(QWidget *parent) :
|
||||||
|
QWidget{parent}
|
||||||
|
{
|
||||||
|
m_layout = new QGridLayout{this};
|
||||||
|
|
||||||
|
QRandomGenerator random((qint32)(QDateTime::currentMSecsSinceEpoch()));
|
||||||
|
|
||||||
|
const auto stories = random.bounded(3, 10);
|
||||||
|
|
||||||
|
int row{0};
|
||||||
|
{
|
||||||
|
int column{0};
|
||||||
|
for (const auto text : {"Story", "To Do:", "In Progress:", "In Review:", "Done:"})
|
||||||
|
{
|
||||||
|
auto label = new QLabel{text};
|
||||||
|
{
|
||||||
|
auto font = label->font();
|
||||||
|
font.setPointSize(24);
|
||||||
|
label->setFont(font);
|
||||||
|
}
|
||||||
|
label->setFixedHeight(40);
|
||||||
|
m_layout->addWidget(label, row, column++);
|
||||||
|
|
||||||
|
{
|
||||||
|
auto line = new QFrame;
|
||||||
|
line->setFrameShape(QFrame::VLine);
|
||||||
|
line->setFrameShadow(QFrame::Sunken);
|
||||||
|
m_layout->addWidget(line, row, column++, (stories*2)+1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
row++;
|
||||||
|
|
||||||
|
call_n_times(stories, [&]()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
auto line = new QFrame;
|
||||||
|
line->setFrameShape(QFrame::HLine);
|
||||||
|
line->setFrameShadow(QFrame::Sunken);
|
||||||
|
m_layout->addWidget(line, row, 0, 1, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
row++;
|
||||||
|
|
||||||
|
int storyPoints{0};
|
||||||
|
|
||||||
|
auto storyWidget = new StripWidget;
|
||||||
|
storyWidget->setTitle(QString("ATC-%0").arg(random.bounded(1000, 5000)));
|
||||||
|
storyWidget->setStyleSheet("StripWidget { background-color: #AFA; }");
|
||||||
|
|
||||||
|
for (int column = 0; column < 5; column++)
|
||||||
|
{
|
||||||
|
if (column == 0)
|
||||||
|
{
|
||||||
|
auto layout = new QVBoxLayout;
|
||||||
|
layout->addSpacing(0);
|
||||||
|
layout->addWidget(storyWidget);
|
||||||
|
layout->addStretch(1);
|
||||||
|
m_layout->addLayout(layout, row, column*2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int count = random.bounded(0, 5);
|
||||||
|
if (!count)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto layout = new FlowLayout;
|
||||||
|
|
||||||
|
call_n_times(count, [&]()
|
||||||
|
{
|
||||||
|
auto widget = new StripWidget;
|
||||||
|
widget->setTitle(QString("ATC-%0").arg(random.bounded(1000, 5000)));
|
||||||
|
{
|
||||||
|
const auto points = std::array<int, 5>{1,3,5,8,13}[random.bounded(5)];
|
||||||
|
widget->setPoints(points);
|
||||||
|
storyPoints += points;
|
||||||
|
}
|
||||||
|
widget->setOwner(std::array<const char *, 5>{"DB", "KW", "BK", "MS", "AS"}[random.bounded(5)]);
|
||||||
|
widget->setStyleSheet("StripWidget { background-color: #FCC; }");
|
||||||
|
layout->addWidget(widget);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_layout->addLayout(layout, row, column*2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
storyWidget->setPoints(storyPoints);
|
||||||
|
|
||||||
|
row++;
|
||||||
|
});
|
||||||
|
|
||||||
|
m_layout->addItem(new QSpacerItem{0, 40, QSizePolicy::Minimum, QSizePolicy::Expanding}, ++row, 0, 1, 5);
|
||||||
|
|
||||||
|
m_widget = new StripWidget{this};
|
||||||
|
m_widget->setStyleSheet("StripWidget { background-color: #88FFFF; }");
|
||||||
|
m_widget->move(100, 100);
|
||||||
|
|
||||||
|
// auto widget = new QWidget;
|
||||||
|
// setCentralWidget(widget);
|
||||||
|
|
||||||
|
// m_layout = new QGridLayout{widget};
|
||||||
|
// const auto addColumn = [&](const QString &name)
|
||||||
|
// {
|
||||||
|
// auto label = new QLabel{name};
|
||||||
|
// {
|
||||||
|
// auto font = label->font();
|
||||||
|
// font.setPointSize(30);
|
||||||
|
// label->setFont(font);
|
||||||
|
// }
|
||||||
|
// m_layout->addWidget(label, 0, m_layout->columnCount());
|
||||||
|
// };
|
||||||
|
// addColumn("To Do");
|
||||||
|
// addColumn("In Progress");
|
||||||
|
// addColumn("In Review");
|
||||||
|
// addColumn("Done");
|
||||||
|
|
||||||
|
// m_layout->addWidget(new QWidget, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StripsGrid::mousePressEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
qDebug() << "mousePressEvent" << *event;
|
||||||
|
|
||||||
|
if (event->button() == Qt::LeftButton &&
|
||||||
|
!m_isDragging &&
|
||||||
|
m_widget->startDragging(event->pos() - m_widget->pos()))
|
||||||
|
{
|
||||||
|
m_widget->setGraphicsEffect(new QGraphicsOpacityEffect);
|
||||||
|
m_isDragging = true;
|
||||||
|
m_dragOffset = event->pos() - m_widget->pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget::mousePressEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StripsGrid::mouseReleaseEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
qDebug() << "mouseReleaseEvent" << *event;
|
||||||
|
|
||||||
|
if (event->button() == Qt::LeftButton &&
|
||||||
|
m_isDragging)
|
||||||
|
{
|
||||||
|
m_widget->setGraphicsEffect(nullptr);
|
||||||
|
m_isDragging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget::mouseReleaseEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StripsGrid::mouseMoveEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
qDebug() << "mouseMoveEvent" << *event;
|
||||||
|
|
||||||
|
if (m_isDragging)
|
||||||
|
m_widget->move(event->pos() - m_dragOffset);
|
||||||
|
|
||||||
|
QWidget::mouseMoveEvent(event);
|
||||||
|
}
|
27
stripsgrid.h
Normal file
27
stripsgrid.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class QGridLayout;
|
||||||
|
|
||||||
|
class StripWidget;
|
||||||
|
|
||||||
|
class StripsGrid : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit StripsGrid(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mousePressEvent(QMouseEvent *event) override;
|
||||||
|
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QGridLayout *m_layout;
|
||||||
|
|
||||||
|
bool m_isDragging{false};
|
||||||
|
QPoint m_dragOffset;
|
||||||
|
StripWidget *m_widget;
|
||||||
|
};
|
40
stripwidget.cpp
Normal file
40
stripwidget.cpp
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#include "stripwidget.h"
|
||||||
|
#include "ui_stripwidget.h"
|
||||||
|
|
||||||
|
StripWidget::StripWidget(QWidget *parent) :
|
||||||
|
QFrame{parent},
|
||||||
|
m_ui{std::make_unique<Ui::StripWidget>()}
|
||||||
|
{
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
|
setMinimumSize(size());
|
||||||
|
setMaximumSize(size());
|
||||||
|
setFixedSize(size());
|
||||||
|
}
|
||||||
|
|
||||||
|
StripWidget::~StripWidget() = default;
|
||||||
|
|
||||||
|
bool StripWidget::startDragging(const QPoint &pos) const
|
||||||
|
{
|
||||||
|
return m_ui->title->geometry().contains(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StripWidget::setTitle(const QString &title)
|
||||||
|
{
|
||||||
|
m_ui->title->setText(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StripWidget::setDescription(const QString &description)
|
||||||
|
{
|
||||||
|
m_ui->description->setText(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StripWidget::setPoints(int points)
|
||||||
|
{
|
||||||
|
m_ui->points->setText(QString::number(points));
|
||||||
|
}
|
||||||
|
|
||||||
|
void StripWidget::setOwner(const QString &owner)
|
||||||
|
{
|
||||||
|
m_ui->owner->setText(owner);
|
||||||
|
}
|
26
stripwidget.h
Normal file
26
stripwidget.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace Ui { class StripWidget; }
|
||||||
|
|
||||||
|
class StripWidget : public QFrame
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit StripWidget(QWidget *parent = nullptr);
|
||||||
|
~StripWidget() override;
|
||||||
|
|
||||||
|
bool startDragging(const QPoint &pos) const;
|
||||||
|
|
||||||
|
void setTitle(const QString &title);
|
||||||
|
void setDescription(const QString &description);
|
||||||
|
void setPoints(int points);
|
||||||
|
void setOwner(const QString &owner);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Ui::StripWidget> m_ui;
|
||||||
|
};
|
128
stripwidget.ui
Normal file
128
stripwidget.ui
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>StripWidget</class>
|
||||||
|
<widget class="QFrame" name="StripWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>195</width>
|
||||||
|
<height>105</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::Panel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="title">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>15</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::Panel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Sunken</enum>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">ATC-1234</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="description">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">Refactor once again everything</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="points">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::Panel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Sunken</enum>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="owner">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::Panel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Sunken</enum>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
Reference in New Issue
Block a user