Huge cleanups and added open gl window
This commit is contained in:
1 parent
a477581f6f
commit
ffd4c821ef
525 files changed
+1320
-35862
No files matched your search
@@ -0,0 +1,76 @@
|
||||
#include "actionscontainerwidget.h"
|
||||
#include "ui_actionscontainerwidget.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
#include <QMenu>
|
||||
|
||||
#include "models/actionscontainermodel.h"
|
||||
#include "dialogs/codeactiondialog.h"
|
||||
|
||||
ActionsContainerWidget::ActionsContainerWidget(QWidget *parent) :
|
||||
QWidget{parent},
|
||||
m_ui{std::make_unique<Ui::ActionsContainerWidget>()},
|
||||
m_actionsModel{std::make_unique<ActionsContainerModel>(this)}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_ui->listViewActions->setModel(m_actionsModel.get());
|
||||
|
||||
connect(m_ui->listViewActions, &QListView::customContextMenuRequested,
|
||||
this, &ActionsContainerWidget::actionsContextMenuRequested);
|
||||
|
||||
connect(m_ui->listViewActions, &QListView::doubleClicked,
|
||||
this, &ActionsContainerWidget::actionDoubleClicked);
|
||||
|
||||
connect(m_actionsModel.get(), &QAbstractItemModel::modelAboutToBeReset,
|
||||
m_ui->listViewActions, [listView=m_ui->listViewActions](){
|
||||
listView->setCurrentIndex(QModelIndex{});
|
||||
});
|
||||
}
|
||||
|
||||
ActionsContainerWidget::~ActionsContainerWidget() = default;
|
||||
|
||||
ActionsContainer *ActionsContainerWidget::actionsContainer() const
|
||||
{
|
||||
return m_actionsModel->actionsContainer();
|
||||
}
|
||||
|
||||
void ActionsContainerWidget::setActionsContainer(ActionsContainer *actionsContainer)
|
||||
{
|
||||
m_actionsModel->setActionsContainer(actionsContainer);
|
||||
}
|
||||
|
||||
void ActionsContainerWidget::actionDoubleClicked(const QModelIndex &index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
auto action = m_actionsModel->getAction(index);
|
||||
if (!action)
|
||||
return;
|
||||
|
||||
CodeActionDialog dialog{*action, this};
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void ActionsContainerWidget::actionsContextMenuRequested(const QPoint &pos)
|
||||
{
|
||||
const auto index = m_ui->listViewActions->indexAt(pos);
|
||||
auto action = index.isValid() ? m_actionsModel->getAction(index) : nullptr;
|
||||
|
||||
QMenu menu{this};
|
||||
menu.addAction(tr("&Edit Values"), this, [this,index](){ actionDoubleClicked(index); })->setEnabled(action);
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("C&ut"))->setEnabled(false);
|
||||
menu.addAction(tr("&Copy"))->setEnabled(false);
|
||||
menu.addAction(tr("&Paste"))->setEnabled(false);
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("&Delete"))->setEnabled(false);
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("Select &All"))->setEnabled(false);
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("C&lear"))->setEnabled(false);
|
||||
menu.exec(m_ui->listViewActions->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
|
||||
namespace Ui { class ActionsContainerWidget; }
|
||||
class ActionsContainerModel;
|
||||
|
||||
class ActionsContainerWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ActionsContainerWidget(QWidget *parent = nullptr);
|
||||
~ActionsContainerWidget();
|
||||
|
||||
ActionsContainer *actionsContainer() const;
|
||||
void setActionsContainer(ActionsContainer *actionsContainer);
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
private slots:
|
||||
void actionDoubleClicked(const QModelIndex &index);
|
||||
void actionsContextMenuRequested(const QPoint &pos);
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Ui::ActionsContainerWidget> m_ui;
|
||||
|
||||
const std::unique_ptr<ActionsContainerModel> m_actionsModel;
|
||||
};
|
||||
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ActionsContainerWidget</class>
|
||||
<widget class="QWidget" name="ActionsContainerWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelActions">
|
||||
<property name="text">
|
||||
<string>Actions:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>listViewActions</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListView" name="listViewActions">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolBox" name="toolBox">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>136</width>
|
||||
<height>242</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Page 1</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>136</width>
|
||||
<height>242</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Page 2</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,123 @@
|
||||
#include "codeeditorwidget.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QTextBlock>
|
||||
|
||||
CodeEditorWidget::CodeEditorWidget(QWidget *parent) :
|
||||
QPlainTextEdit{parent}
|
||||
{
|
||||
lineNumberArea = new LineNumberArea(this);
|
||||
|
||||
connect(this, &CodeEditorWidget::blockCountChanged,
|
||||
this, &CodeEditorWidget::updateLineNumberAreaWidth);
|
||||
connect(this, &CodeEditorWidget::updateRequest,
|
||||
this, &CodeEditorWidget::updateLineNumberArea);
|
||||
connect(this, &CodeEditorWidget::cursorPositionChanged,
|
||||
this, &CodeEditorWidget::highlightCurrentLine);
|
||||
|
||||
updateLineNumberAreaWidth(0);
|
||||
highlightCurrentLine();
|
||||
}
|
||||
|
||||
void CodeEditorWidget::updateLineNumberAreaWidth(int newBlockCount)
|
||||
{
|
||||
Q_UNUSED(newBlockCount)
|
||||
setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
|
||||
}
|
||||
|
||||
int CodeEditorWidget::lineNumberAreaWidth()
|
||||
{
|
||||
int digits = 1;
|
||||
int max = qMax(1, blockCount());
|
||||
while (max >= 10)
|
||||
{
|
||||
max /= 10;
|
||||
++digits;
|
||||
}
|
||||
|
||||
int space = 3 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits;
|
||||
|
||||
return std::max(space, 40);
|
||||
}
|
||||
|
||||
void CodeEditorWidget::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
QPlainTextEdit::resizeEvent(e);
|
||||
|
||||
QRect cr = contentsRect();
|
||||
lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
|
||||
}
|
||||
|
||||
void CodeEditorWidget::updateLineNumberArea(const QRect &rect, int dy)
|
||||
{
|
||||
if (dy)
|
||||
lineNumberArea->scroll(0, dy);
|
||||
else
|
||||
lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
|
||||
|
||||
if (rect.contains(viewport()->rect()))
|
||||
updateLineNumberAreaWidth(0);
|
||||
}
|
||||
|
||||
void CodeEditorWidget::highlightCurrentLine()
|
||||
{
|
||||
QList<QTextEdit::ExtraSelection> extraSelections;
|
||||
|
||||
if (!isReadOnly())
|
||||
{
|
||||
QTextEdit::ExtraSelection selection;
|
||||
|
||||
QColor lineColor = QColor(Qt::yellow).lighter(160);
|
||||
|
||||
selection.format.setBackground(lineColor);
|
||||
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
||||
selection.cursor = textCursor();
|
||||
selection.cursor.clearSelection();
|
||||
extraSelections.append(selection);
|
||||
}
|
||||
|
||||
setExtraSelections(extraSelections);
|
||||
}
|
||||
|
||||
void CodeEditorWidget::lineNumberAreaPaintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPainter painter(lineNumberArea);
|
||||
painter.fillRect(event->rect(), Qt::lightGray);
|
||||
|
||||
QTextBlock block = firstVisibleBlock();
|
||||
int blockNumber = block.blockNumber();
|
||||
int top = qRound(blockBoundingGeometry(block).translated(contentOffset()).top());
|
||||
int bottom = top + qRound(blockBoundingRect(block).height());
|
||||
|
||||
while (block.isValid() && top <= event->rect().bottom())
|
||||
{
|
||||
if (block.isVisible() && bottom >= event->rect().top())
|
||||
{
|
||||
QString number = QString::number(blockNumber + 1);
|
||||
painter.setPen(Qt::black);
|
||||
painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),
|
||||
Qt::AlignRight, number);
|
||||
}
|
||||
|
||||
block = block.next();
|
||||
top = bottom;
|
||||
bottom = top + qRound(blockBoundingRect(block).height());
|
||||
++blockNumber;
|
||||
}
|
||||
}
|
||||
|
||||
LineNumberArea::LineNumberArea(CodeEditorWidget *editor) :
|
||||
QWidget{editor},
|
||||
codeEditor{editor}
|
||||
{
|
||||
}
|
||||
|
||||
QSize LineNumberArea::sizeHint() const
|
||||
{
|
||||
return QSize(codeEditor->lineNumberAreaWidth(), 0);
|
||||
}
|
||||
|
||||
void LineNumberArea::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
codeEditor->lineNumberAreaPaintEvent(event);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
class CodeEditorWidget : public QPlainTextEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CodeEditorWidget(QWidget *parent = nullptr);
|
||||
|
||||
void lineNumberAreaPaintEvent(QPaintEvent *event);
|
||||
int lineNumberAreaWidth();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void updateLineNumberAreaWidth(int newBlockCount);
|
||||
void highlightCurrentLine();
|
||||
void updateLineNumberArea(const QRect &rect, int dy);
|
||||
|
||||
private:
|
||||
QWidget *lineNumberArea;
|
||||
};
|
||||
|
||||
class LineNumberArea : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LineNumberArea(CodeEditorWidget *editor);
|
||||
|
||||
QSize sizeHint() const override;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
CodeEditorWidget *codeEditor;
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "drawingcanvaswidget.h"
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QPainter>
|
||||
|
||||
DrawingCanvasWidget::DrawingCanvasWidget(QWidget *parent) :
|
||||
QWidget{parent}
|
||||
{
|
||||
}
|
||||
|
||||
void DrawingCanvasWidget::setPixmap(QPixmap &pixmap)
|
||||
{
|
||||
m_pixmap = &pixmap;
|
||||
setFixedSize(m_pixmap->size() * m_scale);
|
||||
update();
|
||||
}
|
||||
|
||||
void DrawingCanvasWidget::setScale(float scale)
|
||||
{
|
||||
if (m_scale == scale)
|
||||
return;
|
||||
emit scaleChanged(m_scale = scale);
|
||||
if (m_pixmap)
|
||||
setFixedSize(m_pixmap->size() * m_scale);
|
||||
update();
|
||||
}
|
||||
|
||||
void DrawingCanvasWidget::paintEvent(QPaintEvent *ev)
|
||||
{
|
||||
if (!m_pixmap)
|
||||
{
|
||||
QWidget::paintEvent(ev);
|
||||
return;
|
||||
}
|
||||
|
||||
QBrush brush;
|
||||
{
|
||||
QPixmap pixmap{32, 32};
|
||||
{
|
||||
QPainter painter{&pixmap};
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(Qt::gray);
|
||||
painter.drawRect(0, 0, 16, 16);
|
||||
painter.drawRect(16, 16, 16, 16);
|
||||
painter.setBrush(Qt::white);
|
||||
painter.drawRect(0, 16, 16, 16);
|
||||
painter.drawRect(16, 0, 16, 16);
|
||||
}
|
||||
brush.setTexture(std::move(pixmap));
|
||||
}
|
||||
|
||||
QPainter painter{this};
|
||||
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(std::move(brush));
|
||||
painter.drawRect(rect());
|
||||
|
||||
painter.drawPixmap(rect(), *m_pixmap);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QPixmap;
|
||||
|
||||
class DrawingCanvasWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DrawingCanvasWidget(QWidget *parent = nullptr);
|
||||
|
||||
QPixmap *pixmap() { return m_pixmap; }
|
||||
const QPixmap *pixmap() const { return m_pixmap; }
|
||||
void setPixmap(QPixmap &pixmap);
|
||||
|
||||
float scale() const { return m_scale; }
|
||||
void setScale(float scale);
|
||||
|
||||
signals:
|
||||
void scaleChanged(float scale);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *ev) override;
|
||||
|
||||
private:
|
||||
QPixmap *m_pixmap{};
|
||||
|
||||
float m_scale{4.f};
|
||||
};
|
||||
@@ -0,0 +1,225 @@
|
||||
#include "pathpointswidget.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
PathPointsWidget::PathPointsWidget(QWidget *parent) :
|
||||
QWidget{parent}
|
||||
{
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
PathPointsWidget::PathPointsWidget(std::vector<Path::Point> *points, QWidget *parent) :
|
||||
QWidget{parent},
|
||||
m_points{points}
|
||||
{
|
||||
}
|
||||
|
||||
void PathPointsWidget::setPoints(std::vector<Path::Point> *points)
|
||||
{
|
||||
m_points = points;
|
||||
update();
|
||||
}
|
||||
|
||||
void PathPointsWidget::setShowGrid(bool showGrid)
|
||||
{
|
||||
if (m_showGrid == showGrid)
|
||||
return;
|
||||
emit showGridChanged(m_showGrid = showGrid);
|
||||
update();
|
||||
}
|
||||
|
||||
void PathPointsWidget::setGridX(int gridX)
|
||||
{
|
||||
if (m_gridX == gridX)
|
||||
return;
|
||||
emit gridXChanged(m_gridX = gridX);
|
||||
update();
|
||||
}
|
||||
|
||||
void PathPointsWidget::setGridY(int gridY)
|
||||
{
|
||||
if (m_gridY == gridY)
|
||||
return;
|
||||
emit gridYChanged(m_gridY = gridY);
|
||||
update();
|
||||
}
|
||||
|
||||
void PathPointsWidget::setClosed(bool closed)
|
||||
{
|
||||
if (m_closed == closed)
|
||||
return;
|
||||
emit closedChanged(m_closed = closed);
|
||||
update();
|
||||
}
|
||||
|
||||
void PathPointsWidget::setSelectedIndex(const std::optional<std::size_t> &selectedIndex)
|
||||
{
|
||||
if (m_selectedIndex == selectedIndex)
|
||||
return;
|
||||
emit selectedIndexChanged(m_selectedIndex = selectedIndex);
|
||||
update();
|
||||
}
|
||||
|
||||
void PathPointsWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
if (m_showGrid)
|
||||
{
|
||||
if (!m_gridBrush || m_gridBrush->gridX != m_gridX || m_gridBrush->gridY != m_gridY)
|
||||
{
|
||||
QPixmap pixmap{m_gridX, m_gridY};
|
||||
|
||||
{
|
||||
QPainter painter{&pixmap};
|
||||
painter.setPen(palette().color(m_gridRole));
|
||||
painter.drawLine(0, 0, m_gridX, 0);
|
||||
painter.drawLine(0, 0, 0, m_gridY);
|
||||
|
||||
painter.fillRect(1, 1, m_gridX - 1, m_gridY - 1, palette().color(backgroundRole()));
|
||||
}
|
||||
|
||||
m_gridBrush = GridBrush {
|
||||
.gridX = m_gridX,
|
||||
.gridY = m_gridY,
|
||||
.brush = QBrush{std:: move(pixmap)}
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
m_gridBrush = std::nullopt;
|
||||
|
||||
QPainter painter{this};
|
||||
painter.fillRect(rect(), m_gridBrush ? m_gridBrush->brush : palette().color(backgroundRole()));
|
||||
|
||||
if (!m_points)
|
||||
return;
|
||||
|
||||
const auto drawLine = [&](const auto &point0, const auto &point1){
|
||||
painter.setPen(QPen{Qt::black, 2});
|
||||
painter.drawLine(point0.point, point1.point);
|
||||
painter.setPen(QPen{Qt::yellow, 1});
|
||||
painter.drawLine(point0.point, point1.point);
|
||||
};
|
||||
|
||||
std::adjacent_find(std::cbegin(*m_points), std::cend(*m_points),
|
||||
[&](const Path::Point &point0, const Path::Point &point1){
|
||||
drawLine(point0, point1);
|
||||
return false;
|
||||
});
|
||||
|
||||
if (m_closed && m_points->size() >= 2)
|
||||
drawLine(m_points->back(), m_points->front());
|
||||
|
||||
painter.setPen(Qt::black);
|
||||
std::size_t i{};
|
||||
for (const auto &point : *m_points)
|
||||
{
|
||||
if (i == m_selectedIndex)
|
||||
painter.setBrush(Qt::red);
|
||||
else if (i == 0)
|
||||
painter.setBrush(Qt::green);
|
||||
else
|
||||
painter.setBrush(Qt::blue);
|
||||
painter.drawEllipse(point.point, 2, 2);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void PathPointsWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QWidget::mousePressEvent(event);
|
||||
|
||||
switch (event->button())
|
||||
{
|
||||
case Qt::LeftButton:
|
||||
if (!m_points)
|
||||
return;
|
||||
|
||||
if (!m_points->empty())
|
||||
{
|
||||
auto points = *m_points;
|
||||
const auto distance = [&](const Path::Point &point){ return QLineF{point.point, event->pos()}.length(); };
|
||||
std::sort(std::begin(points), std::end(points), [&](const Path::Point &left, const Path::Point &right){
|
||||
return distance(left) < distance(right);
|
||||
});
|
||||
if (distance(points.front()) > 8)
|
||||
goto createNew;
|
||||
|
||||
const auto iter = std::find_if(std::cbegin(*m_points), std::cend(*m_points),
|
||||
[&minPoint=points.front().point](const Path::Point &point){ return point.point == minPoint; });
|
||||
if (iter == std::cend(*m_points))
|
||||
{
|
||||
qWarning() << "unexpected end";
|
||||
goto createNew;
|
||||
}
|
||||
|
||||
const auto index = std::distance(std::cbegin(*m_points), iter);
|
||||
emit pointInserted(index);
|
||||
emit selectedIndexChanged(m_selectedIndex = index);
|
||||
m_dragIndex = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
createNew:
|
||||
m_points->push_back(Path::Point{.point = snapPoint(event->pos()), .sp=100});
|
||||
const auto index = m_points->size() - 1;
|
||||
emit pointInserted(index);
|
||||
emit selectedIndexChanged(m_selectedIndex = index);
|
||||
m_dragIndex = index;
|
||||
}
|
||||
update();
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
void PathPointsWidget::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
|
||||
switch (event->button())
|
||||
{
|
||||
case Qt::LeftButton:
|
||||
m_dragIndex = std::nullopt;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
void PathPointsWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
QWidget::mouseMoveEvent(event);
|
||||
|
||||
emit cursorMoved(snapPoint(event->pos()));
|
||||
|
||||
if (m_dragIndex)
|
||||
{
|
||||
if (event->buttons().testFlag(Qt::LeftButton))
|
||||
{
|
||||
const auto point = snapPoint(event->pos());
|
||||
if ((*m_points)[*m_dragIndex].point != point)
|
||||
{
|
||||
(*m_points)[*m_dragIndex].point = point;
|
||||
emit pointMoved(*m_dragIndex);
|
||||
update();
|
||||
}
|
||||
}
|
||||
else
|
||||
m_dragIndex = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
QPoint PathPointsWidget::snapPoint(const QPoint &point) const
|
||||
{
|
||||
if (!m_showGrid)
|
||||
return point;
|
||||
return QPoint{
|
||||
(point.x() + (m_gridX / 2)) / m_gridX * m_gridX,
|
||||
(point.y() + (m_gridY / 2)) / m_gridY * m_gridY,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPalette>
|
||||
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
|
||||
class PathPointsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool showGrid READ showGrid WRITE setShowGrid NOTIFY showGridChanged)
|
||||
Q_PROPERTY(int gridX READ gridX WRITE setGridX NOTIFY gridXChanged)
|
||||
Q_PROPERTY(int gridY READ gridY WRITE setGridY NOTIFY gridYChanged)
|
||||
Q_PROPERTY(bool closed READ closed WRITE setClosed NOTIFY closedChanged)
|
||||
|
||||
public:
|
||||
explicit PathPointsWidget(QWidget *parent = nullptr);
|
||||
explicit PathPointsWidget(std::vector<Path::Point> *points, QWidget *parent = nullptr);
|
||||
|
||||
void setPoints(std::vector<Path::Point> *points);
|
||||
|
||||
bool showGrid() const { return m_showGrid; }
|
||||
void setShowGrid(bool showGrid);
|
||||
|
||||
int gridX() const { return m_gridX; }
|
||||
void setGridX(int gridX);
|
||||
|
||||
int gridY() const { return m_gridY; }
|
||||
void setGridY(int gridY);
|
||||
|
||||
bool closed() const { return m_closed; }
|
||||
void setClosed(bool closed);
|
||||
|
||||
const std::optional<std::size_t> &selectedIndex() const { return m_selectedIndex; }
|
||||
void setSelectedIndex(const std::optional<std::size_t> &selectedIndex);
|
||||
|
||||
QPalette::ColorRole gridRole() const { return m_gridRole; }
|
||||
void setGridRole(QPalette::ColorRole gridRole) { if (gridRole == m_gridRole) return; m_gridRole = gridRole; update(); }
|
||||
|
||||
signals:
|
||||
void showGridChanged(bool showGrid);
|
||||
void gridXChanged(int gridX);
|
||||
void gridYChanged(int gridY);
|
||||
void closedChanged(bool closed);
|
||||
void selectedIndexChanged(const std::optional<std::size_t> &selectedIndex);
|
||||
|
||||
void cursorMoved(const QPoint &point);
|
||||
|
||||
void pointInserted(std::size_t index);
|
||||
void pointMoved(std::size_t index);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
QPoint snapPoint(const QPoint &point) const;
|
||||
|
||||
std::vector<Path::Point> *m_points{};
|
||||
|
||||
bool m_showGrid{true};
|
||||
int m_gridX{16};
|
||||
int m_gridY{16};
|
||||
|
||||
bool m_closed{true};
|
||||
|
||||
std::optional<std::size_t> m_selectedIndex;
|
||||
std::optional<std::size_t> m_dragIndex;
|
||||
|
||||
struct GridBrush {
|
||||
int gridX;
|
||||
int gridY;
|
||||
QBrush brush;
|
||||
};
|
||||
|
||||
std::optional<GridBrush> m_gridBrush;
|
||||
|
||||
QPalette::ColorRole m_gridRole{QPalette::Dark};
|
||||
};
|
||||
Reference in new issue
Block a user