Implemented first drawing capabilities in image editor
This commit is contained in:
@@ -38,6 +38,7 @@ HEADERS += \
|
||||
src/editor/editorguiutils.h \
|
||||
src/editor/roomscene.h \
|
||||
src/editor/widgets/actiondragwidget.h \
|
||||
src/editor/widgets/colorwidget.h \
|
||||
src/editor/widgets/draggabletreeview.h \
|
||||
src/editor/widgets/objectparentselectorwidget.h \
|
||||
src/editor/widgets/objectselectorwidget.h \
|
||||
@@ -108,6 +109,7 @@ SOURCES += \
|
||||
src/editor/editorguiutils.cpp \
|
||||
src/editor/roomscene.cpp \
|
||||
src/editor/widgets/actiondragwidget.cpp \
|
||||
src/editor/widgets/colorwidget.cpp \
|
||||
src/editor/widgets/draggabletreeview.cpp \
|
||||
src/editor/widgets/objectparentselectorwidget.cpp \
|
||||
src/editor/widgets/objectselectorwidget.cpp \
|
||||
|
||||
@@ -89,7 +89,7 @@ void EditSpriteDialog::newSprite()
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
QPixmap pixmap{dialog.spriteSize()};
|
||||
pixmap.fill(Qt::white);
|
||||
pixmap.fill(Qt::transparent);
|
||||
|
||||
m_model->beginResetModel();
|
||||
m_pixmaps = std::vector<QPixmap> { std::move(pixmap) };
|
||||
@@ -110,8 +110,11 @@ void EditSpriteDialog::doubleClicked(const QModelIndex &index)
|
||||
ImageEditorDialog dialog{m_model->pixmap(index), tr("Image Editor: %0").arg(m_spriteName), this};
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
qDebug() << "apply pixmap?!";
|
||||
emit m_model->beginResetModel();
|
||||
m_pixmaps[index.row()] = dialog.pixmap();
|
||||
emit m_model->dataChanged(index, index, {Qt::DecorationRole});
|
||||
emit m_model->endResetModel();
|
||||
//emit m_model->dataChanged(index, index, {Qt::DecorationRole});
|
||||
changed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
#include <QButtonGroup>
|
||||
#include <QFontDialog>
|
||||
#include <QColorDialog>
|
||||
|
||||
ImageEditorDialog::ImageEditorDialog(const QPixmap &pixmap, const QString &title, QWidget *parent) :
|
||||
QDialog{parent},
|
||||
@@ -24,6 +26,21 @@ ImageEditorDialog::ImageEditorDialog(const QPixmap &pixmap, const QString &title
|
||||
|
||||
m_ui->scrollArea->setBackgroundRole(QPalette::Dark);
|
||||
|
||||
connect(m_ui->pushButtonSelectFont, &QAbstractButton::pressed,
|
||||
this, &ImageEditorDialog::selectFont);
|
||||
|
||||
connect(m_ui->pushButtonLeftButtonColor, &QAbstractButton::pressed,
|
||||
this, &ImageEditorDialog::selectLeftButtonColor);
|
||||
connect(m_ui->pushButtonRightButtonColor, &QAbstractButton::pressed,
|
||||
this, &ImageEditorDialog::selectRightButtonColor);
|
||||
|
||||
connect(m_ui->canvas, &DrawingCanvasWidget::changed,
|
||||
this, &ImageEditorDialog::changed);
|
||||
connect(m_ui->canvas, &DrawingCanvasWidget::leftButtonColorChanged,
|
||||
this, &ImageEditorDialog::updateLeftButtonColor);
|
||||
connect(m_ui->canvas, &DrawingCanvasWidget::rightButtonColorChanged,
|
||||
this, &ImageEditorDialog::updateRightButtonColor);
|
||||
|
||||
{
|
||||
auto group = new QButtonGroup{this};
|
||||
group->setExclusive(true);
|
||||
@@ -71,6 +88,9 @@ ImageEditorDialog::ImageEditorDialog(const QPixmap &pixmap, const QString &title
|
||||
|
||||
m_ui->toolButtonDraw->click();
|
||||
|
||||
updateLeftButtonColor(m_ui->canvas->leftButtonColor());
|
||||
updateRightButtonColor(m_ui->canvas->rightButtonColor());
|
||||
|
||||
m_ui->canvas->setPixmap(m_pixmap);
|
||||
}
|
||||
|
||||
@@ -78,12 +98,6 @@ ImageEditorDialog::~ImageEditorDialog() = default;
|
||||
|
||||
void ImageEditorDialog::accept()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
QDialog::accept();
|
||||
@@ -128,6 +142,45 @@ void ImageEditorDialog::changed()
|
||||
}
|
||||
}
|
||||
|
||||
void ImageEditorDialog::selectFont()
|
||||
{
|
||||
QFontDialog dialog{m_ui->pushButtonSelectFont->font(), this};
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
m_ui->pushButtonSelectFont->setFont(dialog.selectedFont());
|
||||
}
|
||||
|
||||
void ImageEditorDialog::selectLeftButtonColor()
|
||||
{
|
||||
QColorDialog dialog{m_ui->canvas->leftButtonColor(), this};
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
m_ui->canvas->setLeftButtonColor(dialog.selectedColor());
|
||||
}
|
||||
|
||||
void ImageEditorDialog::selectRightButtonColor()
|
||||
{
|
||||
QColorDialog dialog{m_ui->canvas->rightButtonColor(), this};
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
m_ui->canvas->setRightButtonColor(dialog.selectedColor());
|
||||
}
|
||||
|
||||
void ImageEditorDialog::updateLeftButtonColor(const QColor &leftButtonColor)
|
||||
{
|
||||
auto frame = m_ui->pushButtonLeftButtonColor;
|
||||
auto palette = frame->palette();
|
||||
auto role = frame->backgroundRole();
|
||||
palette.setBrush(role, leftButtonColor);
|
||||
frame->setPalette(palette);
|
||||
}
|
||||
|
||||
void ImageEditorDialog::updateRightButtonColor(const QColor &rightButtonColor)
|
||||
{
|
||||
auto frame = m_ui->pushButtonRightButtonColor;
|
||||
auto palette = frame->palette();
|
||||
auto role = frame->backgroundRole();
|
||||
palette.setBrush(role, rightButtonColor);
|
||||
frame->setPalette(palette);
|
||||
}
|
||||
|
||||
void ImageEditorDialog::updateTitle()
|
||||
{
|
||||
setWindowTitle(tr("%0%1")
|
||||
|
||||
@@ -23,6 +23,11 @@ public:
|
||||
|
||||
private slots:
|
||||
void changed();
|
||||
void selectFont();
|
||||
void selectLeftButtonColor();
|
||||
void selectRightButtonColor();
|
||||
void updateLeftButtonColor(const QColor &leftButtonColor);
|
||||
void updateRightButtonColor(const QColor &rightButtonColor);
|
||||
|
||||
private:
|
||||
void updateTitle();
|
||||
|
||||
@@ -631,6 +631,12 @@
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonSelectFont">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>64</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Aa</string>
|
||||
</property>
|
||||
@@ -704,7 +710,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>759</width>
|
||||
<width>741</width>
|
||||
<height>1042</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -731,19 +737,13 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frameLeft">
|
||||
<widget class="QPushButton" name="pushButtonLeftButtonColor">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -758,19 +758,13 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frameHeight">
|
||||
<widget class="QPushButton" name="pushButtonRightButtonColor">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -778,10 +772,10 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_4">
|
||||
<widget class="ColorWidget" name="frameColorCoarse">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<width>75</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -794,10 +788,10 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_5">
|
||||
<widget class="ColorWidget" name="frameColorFine">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<width>75</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -878,6 +872,9 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxPreview">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Preview</string>
|
||||
</property>
|
||||
@@ -1114,6 +1111,12 @@
|
||||
<extends>QWidget</extends>
|
||||
<header>widgets/drawingcanvaswidget.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ColorWidget</class>
|
||||
<extends>QFrame</extends>
|
||||
<header>widgets/colorwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../resources_editor.qrc"/>
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#include "colorwidget.h"
|
||||
|
||||
#include <QPaintEvent>
|
||||
#include <QResizeEvent>
|
||||
#include <QPainter>
|
||||
|
||||
ColorWidget::ColorWidget(QWidget *parent)
|
||||
: QFrame{parent}
|
||||
{
|
||||
setCol(150, 255);
|
||||
setAttribute(Qt::WA_NoSystemBackground);
|
||||
setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) );
|
||||
}
|
||||
|
||||
ColorWidget::~ColorWidget() = default;
|
||||
|
||||
void ColorWidget::setCol(int h, int s)
|
||||
{
|
||||
int nhue = qMin(qMax(0,h), 359);
|
||||
int nsat = qMin(qMax(0,s), 255);
|
||||
if (nhue == m_hue && nsat == m_sat)
|
||||
return;
|
||||
QRect r(colPt(), QSize(20,20));
|
||||
m_hue = nhue;
|
||||
m_sat = nsat;
|
||||
r = r.united(QRect(colPt(), QSize(20,20)));
|
||||
r.translate(contentsRect().x()-9, contentsRect().y()-9);
|
||||
// update(r);
|
||||
repaint(r);
|
||||
}
|
||||
|
||||
void ColorWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
QPainter p(this);
|
||||
drawFrame(&p);
|
||||
QRect r = contentsRect();
|
||||
p.drawPixmap(r.topLeft(), m_pixmap);
|
||||
}
|
||||
|
||||
void ColorWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
int w = width() - frameWidth() * 2;
|
||||
int h = height() - frameWidth() * 2;
|
||||
QImage img(w, h, QImage::Format_RGB32);
|
||||
int x, y;
|
||||
uint *pixel = (uint *) img.scanLine(0);
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
const uint *end = pixel + w;
|
||||
x = 0;
|
||||
while (pixel < end) {
|
||||
QPoint p(x, y);
|
||||
QColor c;
|
||||
c.setHsv(huePt(p), satPt(p), 200);
|
||||
*pixel = c.rgb();
|
||||
++pixel;
|
||||
++x;
|
||||
}
|
||||
}
|
||||
m_pixmap = QPixmap::fromImage(img);
|
||||
}
|
||||
|
||||
QPoint ColorWidget::colPt()
|
||||
{
|
||||
QRect r = contentsRect();
|
||||
return QPoint((360 - m_hue) * (r.width() - 1) / 360, (255 - m_sat) * (r.height() - 1) / 255);
|
||||
}
|
||||
|
||||
int ColorWidget::huePt(const QPoint &pt)
|
||||
{
|
||||
QRect r = contentsRect();
|
||||
return 360 - pt.x() * 360 / (r.width() - 1);
|
||||
}
|
||||
|
||||
int ColorWidget::satPt(const QPoint &pt)
|
||||
{
|
||||
QRect r = contentsRect();
|
||||
return 255 - pt.y() * 255 / (r.height() - 1);
|
||||
}
|
||||
|
||||
void ColorWidget::setCol(const QPoint &pt)
|
||||
{
|
||||
setCol(huePt(pt), satPt(pt));
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <QFrame>
|
||||
#include <QPixmap>
|
||||
|
||||
class ColorWidget : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ColorWidget(QWidget *parent = nullptr);
|
||||
~ColorWidget() override;
|
||||
|
||||
public slots:
|
||||
void setCol(int h, int s);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
QPoint colPt();
|
||||
int huePt(const QPoint &pt);
|
||||
int satPt(const QPoint &pt);
|
||||
void setCol(const QPoint &pt);
|
||||
|
||||
int m_hue{};
|
||||
int m_sat{};
|
||||
|
||||
QPixmap m_pixmap;
|
||||
};
|
||||
@@ -26,6 +26,20 @@ void DrawingCanvasWidget::setScale(float scale)
|
||||
update();
|
||||
}
|
||||
|
||||
void DrawingCanvasWidget::setLeftButtonColor(const QColor &leftButtonColor)
|
||||
{
|
||||
if (m_leftButtonColor == leftButtonColor)
|
||||
return;
|
||||
emit leftButtonColorChanged(m_leftButtonColor = leftButtonColor);
|
||||
}
|
||||
|
||||
void DrawingCanvasWidget::setRightButtonColor(const QColor &rightButtonColor)
|
||||
{
|
||||
if (m_rightButtonColor == rightButtonColor)
|
||||
return;
|
||||
emit rightButtonColorChanged(m_rightButtonColor = rightButtonColor);
|
||||
}
|
||||
|
||||
void DrawingCanvasWidget::paintEvent(QPaintEvent *ev)
|
||||
{
|
||||
if (!m_pixmap)
|
||||
@@ -63,9 +77,20 @@ void DrawingCanvasWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QWidget::mousePressEvent(event);
|
||||
|
||||
if (event->button() == Qt::LeftButton)
|
||||
switch (event->button())
|
||||
{
|
||||
case Qt::LeftButton:
|
||||
case Qt::RightButton:
|
||||
{
|
||||
m_currentlyDrawing = event->button() == Qt::LeftButton;
|
||||
|
||||
setMouseTracking(true);
|
||||
|
||||
setPixel(event->pos() / m_scale, event->button() == Qt::LeftButton);
|
||||
|
||||
break;
|
||||
}
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,13 +98,34 @@ void DrawingCanvasWidget::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
|
||||
if (event->button() == Qt::LeftButton)
|
||||
switch (event->button())
|
||||
{
|
||||
case Qt::LeftButton:
|
||||
case Qt::RightButton:
|
||||
{
|
||||
m_currentlyDrawing = std::nullopt;
|
||||
|
||||
setMouseTracking(false);
|
||||
|
||||
break;
|
||||
}
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawingCanvasWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
QWidget::mouseMoveEvent(event);
|
||||
|
||||
if (m_currentlyDrawing)
|
||||
setPixel(event->pos() / m_scale, *m_currentlyDrawing);
|
||||
}
|
||||
|
||||
void DrawingCanvasWidget::setPixel(QPoint pos, bool leftColor)
|
||||
{
|
||||
auto image = m_pixmap->toImage();
|
||||
image.setPixelColor(pos.x(), pos.y(), leftColor ? m_leftButtonColor : m_rightButtonColor);
|
||||
*m_pixmap = QPixmap::fromImage(image);
|
||||
repaint();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,11 @@ class DrawingCanvasWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(float scale READ scale WRITE setScale NOTIFY scaleChanged FINAL)
|
||||
|
||||
Q_PROPERTY(QColor leftButtonColor READ leftButtonColor WRITE setLeftButtonColor NOTIFY leftButtonColorChanged FINAL)
|
||||
Q_PROPERTY(QColor rightButtonColor READ rightButtonColor WRITE setRightButtonColor NOTIFY rightButtonColorChanged FINAL)
|
||||
|
||||
public:
|
||||
explicit DrawingCanvasWidget(QWidget *parent = nullptr);
|
||||
|
||||
@@ -18,8 +23,17 @@ public:
|
||||
float scale() const { return m_scale; }
|
||||
void setScale(float scale);
|
||||
|
||||
QColor leftButtonColor() const { return m_leftButtonColor; }
|
||||
void setLeftButtonColor(const QColor &LeftButtonColor);
|
||||
QColor rightButtonColor() const { return m_rightButtonColor; }
|
||||
void setRightButtonColor(const QColor &rightButtonColor);
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
void scaleChanged(float scale);
|
||||
void leftButtonColorChanged(const QColor &LeftButtonColor);
|
||||
void rightButtonColorChanged(const QColor &rightButtonColor);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *ev) override;
|
||||
@@ -28,7 +42,14 @@ protected:
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
void setPixel(QPoint pos, bool leftColor);
|
||||
|
||||
QPixmap *m_pixmap{};
|
||||
|
||||
float m_scale{4.f};
|
||||
|
||||
QColor m_leftButtonColor{Qt::white};
|
||||
QColor m_rightButtonColor{Qt::black};
|
||||
|
||||
std::optional<bool> m_currentlyDrawing;
|
||||
};
|
||||
|
||||
@@ -148,6 +148,7 @@ QDataStream &operator>>(QDataStream &ds, std::variant<T...> &variant)
|
||||
static constexpr func_t *funcs[] = {
|
||||
detail::variantUnpacker<T, T...>...
|
||||
};
|
||||
assert(index >= 0 && size_t(index) < std::size(funcs));
|
||||
variant = funcs[index](ds);
|
||||
|
||||
return ds;
|
||||
|
||||
Reference in New Issue
Block a user