Added a few more dialogs and models

This commit is contained in:
2022-01-10 21:49:06 +01:00
parent 2a21ffb8c7
commit b8c62a923e
79 changed files with 2748 additions and 326 deletions

View File

@ -7,18 +7,29 @@ DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000
HEADERS += \
codeeditorwidget.h \
constantsmodel.h \
dialogs/codeeditordialog.h \
dialogs/createspritedialog.h \
dialogs/fontpropertiesdialog.h \
dialogs/imageeditordialog.h \
dialogs/includedfilesdialog.h \
dialogs/maskpropertiesdialog.h \
dialogs/objectinformationdialog.h \
dialogs/objectpropertiesdialog.h \
dialogs/pathpropertiesdialog.h \
dialogs/roompropertiesdialog.h \
dialogs/scriptpropertiesdialog.h \
dialogs/timelinepropertiesdialog.h \
dialogs/triggerconditiondialog.h \
dialogs/triggersdialog.h \
dialogs/userdefinedconstantsdialog.h \
drawingcanvaswidget.h \
futurecpp.h \
includedfilesmodel.h \
jshighlighter.h \
mainwindow.h \
pathpointsmodel.h \
pathpointswidget.h \
projectcontainer.h \
projecttreemodel.h \
dialogs/backgroundpropertiesdialog.h \
@ -29,21 +40,33 @@ HEADERS += \
dialogs/preferencesdialog.h \
dialogs/soundpropertiesdialog.h \
dialogs/spritepropertiesdialog.h \
spritesmodel.h
spritesmodel.h \
triggersmodel.h
SOURCES += main.cpp \
codeeditorwidget.cpp \
constantsmodel.cpp \
dialogs/codeeditordialog.cpp \
dialogs/createspritedialog.cpp \
dialogs/fontpropertiesdialog.cpp \
dialogs/imageeditordialog.cpp \
dialogs/includedfilesdialog.cpp \
dialogs/maskpropertiesdialog.cpp \
dialogs/objectinformationdialog.cpp \
dialogs/objectpropertiesdialog.cpp \
dialogs/pathpropertiesdialog.cpp \
dialogs/roompropertiesdialog.cpp \
dialogs/scriptpropertiesdialog.cpp \
dialogs/timelinepropertiesdialog.cpp \
dialogs/triggerconditiondialog.cpp \
dialogs/triggersdialog.cpp \
dialogs/userdefinedconstantsdialog.cpp \
drawingcanvaswidget.cpp \
includedfilesmodel.cpp \
jshighlighter.cpp \
mainwindow.cpp \
pathpointsmodel.cpp \
pathpointswidget.cpp \
projectcontainer.cpp \
projecttreemodel.cpp \
dialogs/backgroundpropertiesdialog.cpp \
@ -54,18 +77,23 @@ SOURCES += main.cpp \
dialogs/preferencesdialog.cpp \
dialogs/soundpropertiesdialog.cpp \
dialogs/spritepropertiesdialog.cpp \
spritesmodel.cpp
spritesmodel.cpp \
triggersmodel.cpp
FORMS += \
dialogs/codeeditordialog.ui \
dialogs/createspritedialog.ui \
dialogs/fontpropertiesdialog.ui \
dialogs/imageeditordialog.ui \
dialogs/includedfilesdialog.ui \
dialogs/maskpropertiesdialog.ui \
dialogs/objectinformationdialog.ui \
dialogs/objectpropertiesdialog.ui \
dialogs/pathpropertiesdialog.ui \
dialogs/roompropertiesdialog.ui \
dialogs/scriptpropertiesdialog.ui \
dialogs/timelinepropertiesdialog.ui \
dialogs/triggersdialog.ui \
dialogs/userdefinedconstantsdialog.ui \
mainwindow.ui \
dialogs/backgroundpropertiesdialog.ui \
dialogs/editspritedialog.ui \

View File

@ -3,8 +3,8 @@
#include <QPainter>
#include <QTextBlock>
CodeEditorWidget::CodeEditorWidget(QWidget *parent)
: QPlainTextEdit{parent}
CodeEditorWidget::CodeEditorWidget(QWidget *parent) :
QPlainTextEdit{parent}
{
lineNumberArea = new LineNumberArea(this);
@ -105,7 +105,9 @@ void CodeEditorWidget::lineNumberAreaPaintEvent(QPaintEvent *event)
}
}
LineNumberArea::LineNumberArea(CodeEditorWidget *editor) : QWidget(editor), codeEditor(editor)
LineNumberArea::LineNumberArea(CodeEditorWidget *editor) :
QWidget{editor},
codeEditor{editor}
{
}

46
constantsmodel.cpp Normal file
View File

@ -0,0 +1,46 @@
#include "constantsmodel.h"
#include "projectcontainer.h"
namespace {
enum {
ColumnName,
ColumnValue,
NumberOfColumns
};
}
ConstantsModel::ConstantsModel(ProjectContainer &project, QObject *parent) :
QAbstractTableModel{parent},
m_project{project}
{
}
int ConstantsModel::rowCount(const QModelIndex &parent) const
{
return 0;
}
int ConstantsModel::columnCount(const QModelIndex &parent) const
{
return NumberOfColumns;
}
QVariant ConstantsModel::data(const QModelIndex &index, int role) const
{
return {};
}
QVariant ConstantsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation != Qt::Horizontal || (role != Qt::DisplayRole && role != Qt::EditRole))
return {};
switch (section)
{
case ColumnName: return tr("Name");
case ColumnValue: return tr("Value");
}
return {};
}

21
constantsmodel.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
#include <QAbstractTableModel>
struct ProjectContainer;
class ConstantsModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit ConstantsModel(ProjectContainer &project, QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
private:
ProjectContainer &m_project;
};

View File

@ -13,7 +13,8 @@ BackgroundPropertiesDialog::BackgroundPropertiesDialog(Background &background, P
QDialog{parent},
m_ui{std::make_unique<Ui::BackgroundPropertiesDialog>()},
m_background{background},
m_projectModel{projectModel}
m_projectModel{projectModel},
m_pixmap{m_background.pixmap}
{
m_ui->setupUi(this);
@ -27,7 +28,6 @@ BackgroundPropertiesDialog::BackgroundPropertiesDialog(Background &background, P
m_ui->lineEditName->setText(m_background.name);
updateSpriteInfo();
m_ui->checkBoxTileset->setChecked(m_background.tileset);
m_ui->labelPreview->setPixmap(m_background.pixmap);
connect(&m_projectModel, &ProjectTreeModel::backgroundNameChanged,
this, &BackgroundPropertiesDialog::backgroundNameChanged);
@ -49,6 +49,12 @@ BackgroundPropertiesDialog::~BackgroundPropertiesDialog() = default;
void BackgroundPropertiesDialog::accept()
{
if (!m_unsavedChanges)
{
QDialog::reject();
return;
}
if (m_background.name != m_ui->lineEditName->text())
{
if (!m_projectModel.rename<Background>(m_background, m_ui->lineEditName->text()))
@ -58,8 +64,7 @@ void BackgroundPropertiesDialog::accept()
}
}
if (m_newPixmap)
m_background.pixmap = std::move(*m_newPixmap);
m_background.pixmap = std::move(m_pixmap);
m_background.tileset = m_ui->checkBoxTileset->isChecked();
QDialog::accept();
@ -108,20 +113,14 @@ void BackgroundPropertiesDialog::loadBackground()
return;
}
m_ui->labelPreview->setPixmap(pixmap);
m_newPixmap = std::move(pixmap);
m_unsavedChanges = true;
updateTitle();
m_pixmap = std::move(pixmap);
changed();
updateSpriteInfo();
}
void BackgroundPropertiesDialog::saveBackground()
{
const auto &pixmap = m_newPixmap ? *m_newPixmap : m_background.pixmap;
if (pixmap.isNull())
if (m_pixmap.isNull())
{
QMessageBox::warning(this, tr("No background available to save!"), tr("No background available to save!"));
return;
@ -131,7 +130,7 @@ void BackgroundPropertiesDialog::saveBackground()
if (path.isEmpty())
return;
if (!pixmap.save(path))
if (!m_pixmap.save(path))
{
QMessageBox::warning(this, tr("Could not save Background!"), tr("Could not save Background!"));
return;
@ -140,7 +139,13 @@ void BackgroundPropertiesDialog::saveBackground()
void BackgroundPropertiesDialog::editBackground()
{
ImageEditorDialog{this}.exec();
ImageEditorDialog dialog{m_pixmap, tr("Image Editor: %0").arg(m_background.name), this};
if (dialog.exec() == QDialog::Accepted)
{
m_pixmap = dialog.pixmap();
changed();
updateSpriteInfo();
}
}
void BackgroundPropertiesDialog::changed()
@ -175,7 +180,7 @@ void BackgroundPropertiesDialog::updateTitle()
void BackgroundPropertiesDialog::updateSpriteInfo()
{
const auto &pixmap = m_newPixmap ? *m_newPixmap : m_background.pixmap;
m_ui->labelWidth->setText(tr("Width: %0").arg(pixmap.width()));
m_ui->labelHeight->setText(tr("Height: %0").arg(pixmap.height()));
m_ui->labelWidth->setText(tr("Width: %0").arg(m_pixmap.width()));
m_ui->labelHeight->setText(tr("Height: %0").arg(m_pixmap.height()));
m_ui->labelPreview->setPixmap(m_pixmap);
}

View File

@ -41,5 +41,5 @@ private:
bool m_unsavedChanges{};
std::optional<QPixmap> m_newPixmap;
QPixmap m_pixmap;
};

View File

@ -40,6 +40,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>The name of the background</string>
</property>
</widget>
</item>
</layout>
@ -59,6 +62,9 @@
</item>
<item>
<widget class="QPushButton" name="pushButtonLoad">
<property name="toolTip">
<string>Load the background from a file</string>
</property>
<property name="text">
<string>&amp;Load Background</string>
</property>
@ -70,6 +76,9 @@
</item>
<item>
<widget class="QPushButton" name="pushButtonSave">
<property name="toolTip">
<string>Save the background to a file</string>
</property>
<property name="text">
<string>&amp;Save Background</string>
</property>
@ -81,6 +90,9 @@
</item>
<item>
<widget class="QPushButton" name="pushButtonEdit">
<property name="toolTip">
<string>Edit the background image</string>
</property>
<property name="text">
<string>&amp;Edit Background</string>
</property>
@ -123,6 +135,9 @@
</item>
<item>
<widget class="QCheckBox" name="checkBoxTileset">
<property name="toolTip">
<string>Indicate whether to use this background as a tile set</string>
</property>
<property name="text">
<string>&amp;Use as tile set</string>
</property>

View File

@ -0,0 +1,84 @@
#include "codeeditordialog.h"
#include "ui_codeeditordialog.h"
#include <QDebug>
#include <QFont>
#include <QLabel>
#include <QTextBlock>
#include "jshighlighter.h"
CodeEditorDialog::CodeEditorDialog(QWidget *parent) :
QDialog{parent},
m_ui{std::make_unique<Ui::CodeEditorDialog>()},
m_labelPosition{new QLabel{this}}
{
m_ui->setupUi(this);
m_labelPosition->setFrameStyle(QFrame::Sunken);
m_ui->statusbar->addWidget(m_labelPosition);
{
QFont font;
font.setFamily("Consolas");
font.setFixedPitch(true);
font.setPointSize(10);
m_ui->codeEdit->setFont(font);
}
new JSHighlighter{m_ui->codeEdit->document()};
updatePosition();
connect(m_ui->actionLoad, &QAction::triggered,
this, &CodeEditorDialog::load);
connect(m_ui->actionSave, &QAction::triggered,
this, &CodeEditorDialog::save);
connect(m_ui->actionPrint, &QAction::triggered,
this, &CodeEditorDialog::print);
connect(m_ui->codeEdit, &QPlainTextEdit::textChanged,
this, &CodeEditorDialog::updatePosition);
connect(m_ui->codeEdit, &QPlainTextEdit::cursorPositionChanged,
this, &CodeEditorDialog::updatePosition);
}
CodeEditorDialog::~CodeEditorDialog() = default;
void CodeEditorDialog::load()
{
}
void CodeEditorDialog::save()
{
}
void CodeEditorDialog::print()
{
}
void CodeEditorDialog::updatePosition()
{
auto cursor = m_ui->codeEdit->textCursor();
auto position = cursor.position();
cursor.movePosition(QTextCursor::StartOfLine);
position -= cursor.position() - 1;
int lines = 1;
while (cursor.positionInBlock() > 0)
{
cursor.movePosition(QTextCursor::Up);
//lines++;
}
QTextBlock block = cursor.block().previous();
while (block.isValid())
{
lines += 1; //block.lineCount();
block = block.previous();
}
m_labelPosition->setText(tr("%0/%1: %2").arg(lines).arg(m_ui->codeEdit->blockCount()).arg(position));
}

View File

@ -0,0 +1,30 @@
#pragma once
#include <QDialog>
#include <memory>
class QLabel;
namespace Ui { class CodeEditorDialog; }
class CodeEditorDialog : public QDialog
{
Q_OBJECT
public:
explicit CodeEditorDialog(QWidget *parent = nullptr);
~CodeEditorDialog();
private slots:
void load();
void save();
void print();
void updatePosition();
protected:
const std::unique_ptr<Ui::CodeEditorDialog> m_ui;
private:
QLabel * const m_labelPosition;
};

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ScriptPropertiesDialog</class>
<widget class="QDialog" name="ScriptPropertiesDialog">
<class>CodeEditorDialog</class>
<widget class="QDialog" name="CodeEditorDialog">
<property name="geometry">
<rect>
<x>0</x>
@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
<string>Script Properties</string>
<string>Code Editor</string>
</property>
<property name="windowIcon">
<iconset resource="../resources.qrc">
@ -231,6 +231,9 @@
<property name="text">
<string>OK</string>
</property>
<property name="toolTip">
<string>OK, Save Changes</string>
</property>
</action>
<action name="actionLoad">
<property name="icon">
@ -391,7 +394,7 @@
<connection>
<sender>actionOk</sender>
<signal>triggered()</signal>
<receiver>ScriptPropertiesDialog</receiver>
<receiver>CodeEditorDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">

View File

@ -9,10 +9,10 @@ CreateSpriteDialog::CreateSpriteDialog(QWidget *parent) :
{
m_ui->setupUi(this);
setWindowFlags(windowFlags()
& ~Qt::Dialog
| Qt::Window
| Qt::WindowCloseButtonHint);
#ifdef Q_OS_LINUX
setWindowFlags(windowFlags() & ~Qt::Dialog | Qt::Window);
#endif
setWindowFlag(Qt::WindowCloseButtonHint);
if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Ok))
button->setIcon(QIcon{":/qtgameengine/icons/ok.png"});
@ -29,7 +29,7 @@ CreateSpriteDialog::CreateSpriteDialog(const QSize &size, QWidget *parent) :
CreateSpriteDialog::~CreateSpriteDialog() = default;
QSize CreateSpriteDialog::size() const
QSize CreateSpriteDialog::spriteSize() const
{
return QSize{m_ui->spinBoxWidth->value(), m_ui->spinBoxHeight->value()};
}

View File

@ -15,7 +15,7 @@ public:
explicit CreateSpriteDialog(const QSize &size, QWidget *parent = nullptr);
~CreateSpriteDialog();
QSize size() const;
QSize spriteSize() const;
private:
const std::unique_ptr<Ui::CreateSpriteDialog> m_ui;

View File

@ -50,6 +50,9 @@
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>16384</number>
</property>
<property name="value">
<number>32</number>
</property>

View File

@ -1,27 +1,30 @@
#include "editspritedialog.h"
#include "ui_editspritedialog.h"
#include <QMessageBox>
#include "projectcontainer.h"
#include "spritesmodel.h"
#include "createspritedialog.h"
#include "imageeditordialog.h"
EditSpriteDialog::EditSpriteDialog(Sprite &sprite, QWidget *parent) :
EditSpriteDialog::EditSpriteDialog(const std::vector<QPixmap> &pixmaps, const QString &spriteName, QWidget *parent) :
QDialog{parent},
m_ui{std::make_unique<Ui::EditSpriteDialog>()},
m_sprite{sprite},
m_model{std::make_unique<SpritesModel>(this)}
m_pixmaps{pixmaps},
m_spriteName{spriteName},
m_model{std::make_unique<SpritesModel>(m_pixmaps, this)}
{
m_ui->setupUi(this);
setWindowFlags(windowFlags()
& ~Qt::Dialog
| Qt::Window
| Qt::WindowMinimizeButtonHint
| Qt::WindowMaximizeButtonHint
| Qt::WindowCloseButtonHint);
#ifdef Q_OS_LINUX
setWindowFlags(windowFlags() & ~Qt::Dialog | Qt::Window);
#endif
setWindowFlag(Qt::WindowMinimizeButtonHint);
setWindowFlag(Qt::WindowMaximizeButtonHint);
setWindowFlag(Qt::WindowCloseButtonHint);
setWindowTitle(tr("Sprite editor - %0").arg(m_sprite.name));
updateTitle();
m_ui->actionNew->setShortcut(QKeySequence::New);
m_ui->actionCreateFromFile->setShortcut(QKeySequence::Open);
@ -36,16 +39,95 @@ EditSpriteDialog::EditSpriteDialog(Sprite &sprite, QWidget *parent) :
EditSpriteDialog::~EditSpriteDialog() = default;
void EditSpriteDialog::accept()
{
if (!m_unsavedChanges)
{
QDialog::reject();
return;
}
// TODO
QDialog::accept();
}
void EditSpriteDialog::reject()
{
if (!m_unsavedChanges)
{
QDialog::reject();
return;
}
const auto result = QMessageBox::warning(
this,
tr("The Sprite has been modified."),
tr("Do you want to save your changes?"),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel,
QMessageBox::Save
);
switch (result)
{
case QMessageBox::Save:
accept();
return;
case QMessageBox::Discard:
QDialog::reject();
return;
case QMessageBox::Cancel:
return;
default:
qWarning() << "unexpected dialog result" << result;
}
}
void EditSpriteDialog::newSprite()
{
CreateSpriteDialog dialog{this};
if (dialog.exec() == QDialog::Accepted)
{
QPixmap pixmap{dialog.spriteSize()};
pixmap.fill(Qt::white);
m_model->beginResetModel();
m_pixmaps = std::vector<QPixmap> { std::move(pixmap) };
m_model->endResetModel();
qDebug() << m_model->rowCount({});
changed();
}
}
void EditSpriteDialog::doubleClicked(const QModelIndex &index)
{
ImageEditorDialog{this}.exec();
if (!index.isValid())
{
qWarning() << "unexpected invalid index";
return;
}
ImageEditorDialog dialog{m_model->pixmap(index), tr("Image Editor: %0").arg(m_spriteName), this};
if (dialog.exec() == QDialog::Accepted)
{
m_pixmaps[index.row()] = dialog.pixmap();
emit m_model->dataChanged(index, index, {Qt::DecorationRole});
changed();
}
}
void EditSpriteDialog::changed()
{
if (!m_unsavedChanges)
{
m_unsavedChanges = true;
updateTitle();
}
}
void EditSpriteDialog::updateTitle()
{
setWindowTitle(tr("Sprite editor - %0%1")
.arg(m_spriteName)
.arg(m_unsavedChanges ? tr("*") : QString{})
);
}

View File

@ -1,8 +1,10 @@
#pragma once
#include <QDialog>
#include <QPixmap>
#include <memory>
#include <vector>
namespace Ui { class EditSpriteDialog; }
struct Sprite;
@ -13,17 +15,29 @@ class EditSpriteDialog : public QDialog
Q_OBJECT
public:
explicit EditSpriteDialog(Sprite &sprite, QWidget *parent = nullptr);
explicit EditSpriteDialog(const std::vector<QPixmap> &pixmaps, const QString &spriteName, QWidget *parent = nullptr);
~EditSpriteDialog();
void accept() override;
void reject() override;
const std::vector<QPixmap> &pixmaps() const { return m_pixmaps; }
private slots:
void newSprite();
void doubleClicked(const QModelIndex &index);
void changed();
private:
void updateTitle();
const std::unique_ptr<Ui::EditSpriteDialog> m_ui;
Sprite &m_sprite;
std::vector<QPixmap> m_pixmaps;
const QString m_spriteName;
bool m_unsavedChanges{};
const std::unique_ptr<SpritesModel> m_model;
};

View File

@ -7,12 +7,10 @@ ExtensionPackagesDialog::ExtensionPackagesDialog(QWidget *parent) :
{
m_ui->setupUi(this);
setWindowFlags(windowFlags()
& ~Qt::Dialog
| Qt::Window
| Qt::WindowMinimizeButtonHint
| Qt::WindowMaximizeButtonHint
| Qt::WindowCloseButtonHint);
#ifdef Q_OS_LINUX
setWindowFlags(windowFlags() & ~Qt::Dialog | Qt::Window);
#endif
setWindowFlag(Qt::WindowCloseButtonHint);
if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Ok))
button->setIcon(QIcon{":/qtgameengine/icons/ok.png"});

View File

@ -31,7 +31,11 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEditName"/>
<widget class="QLineEdit" name="lineEditName">
<property name="toolTip">
<string>The name of the font</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelFont">
@ -130,6 +134,9 @@
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pushButtonNormal">
<property name="toolTip">
<string>Set the character range to the normal range (32 - 127)</string>
</property>
<property name="text">
<string>Normal</string>
</property>
@ -137,6 +144,9 @@
</item>
<item row="2" column="0">
<widget class="QPushButton" name="pushButtonDigits">
<property name="toolTip">
<string>Set the character range to the digits range (48 - 57)</string>
</property>
<property name="text">
<string>Digits</string>
</property>
@ -144,6 +154,9 @@
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pushButtonAll">
<property name="toolTip">
<string>Set the character range to the complete set (0 - 255)</string>
</property>
<property name="text">
<string>All</string>
</property>
@ -151,6 +164,9 @@
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pushButtonLetters">
<property name="toolTip">
<string>Set the character range to the letters range (65 - 122)</string>
</property>
<property name="text">
<string>Letters</string>
</property>

View File

@ -6,12 +6,13 @@ GameInformationDialog::GameInformationDialog(QWidget *parent) :
m_ui{std::make_unique<Ui::GameInformationDialog>()}
{
m_ui->setupUi(this);
setWindowFlags(windowFlags()
& ~Qt::Dialog
| Qt::Window
| Qt::WindowMinimizeButtonHint
| Qt::WindowMaximizeButtonHint
| Qt::WindowCloseButtonHint);
#ifdef Q_OS_LINUX
setWindowFlags(windowFlags() & ~Qt::Dialog | Qt::Window);
#endif
setWindowFlag(Qt::WindowMinimizeButtonHint);
setWindowFlag(Qt::WindowMaximizeButtonHint);
setWindowFlag(Qt::WindowCloseButtonHint);
}
GameInformationDialog::~GameInformationDialog() = default;

View File

@ -13,6 +13,19 @@
<property name="windowTitle">
<string>Game Information</string>
</property>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>50</x>
<y>50</y>
<width>201</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Not yet implemented</string>
</property>
</widget>
</widget>
<resources/>
<connections/>

View File

@ -2,6 +2,7 @@
#include "ui_globalgamesettingsdialog.h"
#include <QPushButton>
#include <QMessageBox>
GlobalGameSettingsDialog::GlobalGameSettingsDialog(QWidget *parent) :
QDialog{parent},
@ -9,17 +10,102 @@ GlobalGameSettingsDialog::GlobalGameSettingsDialog(QWidget *parent) :
{
m_ui->setupUi(this);
setWindowFlags(windowFlags()
& ~Qt::Dialog
| Qt::Window
| Qt::WindowMinimizeButtonHint
| Qt::WindowMaximizeButtonHint
| Qt::WindowCloseButtonHint);
#ifdef Q_OS_LINUX
setWindowFlags(windowFlags() & ~Qt::Dialog | Qt::Window);
#endif
setWindowFlag(Qt::WindowCloseButtonHint);
updateTitle();
if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Ok))
button->setIcon(QIcon{":/qtgameengine/icons/ok.png"});
if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Cancel))
button->setIcon(QIcon{":/qtgameengine/icons/delete.png"});
connect(m_ui->checkBoxFullscreen, &QCheckBox::toggled,
this, &GlobalGameSettingsDialog::changed);
connect(m_ui->radioButtonFixedScale, &QCheckBox::toggled,
this, &GlobalGameSettingsDialog::changed);
connect(m_ui->radioButtonKeepAspectRatio, &QRadioButton::toggled,
this, &GlobalGameSettingsDialog::changed);
connect(m_ui->radioButtonFullScale, &QRadioButton::toggled,
this, &GlobalGameSettingsDialog::changed);
connect(m_ui->checkBoxInterpolateColors, &QRadioButton::toggled,
this, &GlobalGameSettingsDialog::changed);
// TODO toolButtonColorOutside
connect(m_ui->checkBoxAllowResize, &QCheckBox::toggled,
this, &GlobalGameSettingsDialog::changed);
connect(m_ui->checkBoxAlwaysOntop, &QCheckBox::toggled,
this, &GlobalGameSettingsDialog::changed);
connect(m_ui->checkBoxNoBorder, &QCheckBox::toggled,
this, &GlobalGameSettingsDialog::changed);
connect(m_ui->checkBoxNoWindowButtons, &QCheckBox::toggled,
this, &GlobalGameSettingsDialog::changed);
connect(m_ui->checkBoxDisplayCursor, &QCheckBox::toggled,
this, &GlobalGameSettingsDialog::changed);
connect(m_ui->checkBoxFreezeOnFocusLost, &QCheckBox::toggled,
this, &GlobalGameSettingsDialog::changed);
connect(m_ui->checkBoxDisableScreensavers, &QCheckBox::toggled,
this, &GlobalGameSettingsDialog::changed);
}
GlobalGameSettingsDialog::~GlobalGameSettingsDialog() = default;
void GlobalGameSettingsDialog::accept()
{
if (!m_unsavedChanges)
{
QDialog::reject();
return;
}
// TODO
QDialog::accept();
}
void GlobalGameSettingsDialog::reject()
{
if (!m_unsavedChanges)
{
QDialog::reject();
return;
}
const auto result = QMessageBox::warning(
this,
tr("The Global Game Settings has been modified."),
tr("Do you want to save your changes?"),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel,
QMessageBox::Save
);
switch (result)
{
case QMessageBox::Save:
accept();
return;
case QMessageBox::Discard:
QDialog::reject();
return;
case QMessageBox::Cancel:
return;
default:
qWarning() << "unexpected dialog result" << result;
}
}
void GlobalGameSettingsDialog::changed()
{
if (!m_unsavedChanges)
{
m_unsavedChanges = true;
updateTitle();
}
}
void GlobalGameSettingsDialog::updateTitle()
{
setWindowTitle(tr("Global Game Settings%0")
.arg(m_unsavedChanges ? tr("*") : QString{})
);
}

View File

@ -14,6 +14,16 @@ public:
explicit GlobalGameSettingsDialog(QWidget *parent = nullptr);
~GlobalGameSettingsDialog();
void accept() override;
void reject() override;
private slots:
void changed();
private:
void updateTitle();
const std::unique_ptr<Ui::GlobalGameSettingsDialog> m_ui;
bool m_unsavedChanges{};
};

View File

@ -109,7 +109,7 @@
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton">
<widget class="QToolButton" name="toolButtonColorOutside">
<property name="text">
<string>...</string>
</property>

View File

@ -1,18 +1,88 @@
#include "imageeditordialog.h"
#include "ui_imageeditordialog.h"
ImageEditorDialog::ImageEditorDialog(QWidget *parent) :
#include <QMessageBox>
ImageEditorDialog::ImageEditorDialog(const QPixmap &pixmap, const QString &title, QWidget *parent) :
QDialog{parent},
m_ui{std::make_unique<Ui::ImageEditorDialog>()}
m_ui{std::make_unique<Ui::ImageEditorDialog>()},
m_pixmap{pixmap},
m_title{title}
{
m_ui->setupUi(this);
setWindowFlags(windowFlags()
& ~Qt::Dialog
| Qt::Window
| Qt::WindowMinimizeButtonHint
| Qt::WindowMaximizeButtonHint
| Qt::WindowCloseButtonHint);
#ifdef Q_OS_LINUX
setWindowFlags(windowFlags() & ~Qt::Dialog | Qt::Window);
#endif
setWindowFlag(Qt::WindowMinimizeButtonHint);
setWindowFlag(Qt::WindowMaximizeButtonHint);
setWindowFlag(Qt::WindowCloseButtonHint);
updateTitle();
m_ui->scrollArea->setBackgroundRole(QPalette::Dark);
m_ui->canvas->setPixmap(m_pixmap);
}
ImageEditorDialog::~ImageEditorDialog() = default;
void ImageEditorDialog::accept()
{
if (!m_unsavedChanges)
{
QDialog::reject();
return;
}
// TODO
QDialog::accept();
}
void ImageEditorDialog::reject()
{
if (!m_unsavedChanges)
{
QDialog::reject();
return;
}
const auto result = QMessageBox::warning(
this,
tr("The Image has been modified."),
tr("Do you want to save your changes?"),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel,
QMessageBox::Save
);
switch (result)
{
case QMessageBox::Save:
accept();
return;
case QMessageBox::Discard:
QDialog::reject();
return;
case QMessageBox::Cancel:
return;
default:
qWarning() << "unexpected dialog result" << result;
}
}
void ImageEditorDialog::changed()
{
if (!m_unsavedChanges)
{
m_unsavedChanges = true;
updateTitle();
}
}
void ImageEditorDialog::updateTitle()
{
setWindowTitle(tr("%0%1")
.arg(m_title)
.arg(m_unsavedChanges ? tr("*") : QString{})
);
}

View File

@ -1,6 +1,8 @@
#pragma once
#include <QDialog>
#include <QPixmap>
#include <QString>
#include <memory>
@ -11,9 +13,24 @@ class ImageEditorDialog : public QDialog
Q_OBJECT
public:
explicit ImageEditorDialog(QWidget *parent = nullptr);
explicit ImageEditorDialog(const QPixmap &pixmap, const QString &title, QWidget *parent = nullptr);
~ImageEditorDialog();
const QPixmap &pixmap() const { return m_pixmap; }
void accept() override;
void reject() override;
private slots:
void changed();
private:
void updateTitle();
const std::unique_ptr<Ui::ImageEditorDialog> m_ui;
QPixmap m_pixmap;
const QString m_title;
bool m_unsavedChanges{};
};

View File

@ -31,7 +31,7 @@
</property>
<item>
<widget class="QMenuBar" name="menuBar">
<widget class="QMenu" name="menu_File">
<widget class="QMenu" name="menuFile">
<property name="title">
<string>&amp;File</string>
</property>
@ -44,7 +44,7 @@
<addaction name="separator"/>
<addaction name="actionCloseSavingChanges"/>
</widget>
<widget class="QMenu" name="menu_Edit">
<widget class="QMenu" name="menuEdit">
<property name="title">
<string>&amp;Edit</string>
</property>
@ -61,26 +61,26 @@
<addaction name="separator"/>
<addaction name="actionSelectAll"/>
</widget>
<widget class="QMenu" name="menu_View">
<widget class="QMenu" name="menuView">
<property name="title">
<string>&amp;View</string>
</property>
</widget>
<widget class="QMenu" name="menu_Transform">
<widget class="QMenu" name="menuTransform">
<property name="title">
<string>&amp;Transform</string>
</property>
</widget>
<widget class="QMenu" name="menu_Image">
<widget class="QMenu" name="menuImage">
<property name="title">
<string>&amp;Image</string>
</property>
</widget>
<addaction name="menu_File"/>
<addaction name="menu_Edit"/>
<addaction name="menu_View"/>
<addaction name="menu_Transform"/>
<addaction name="menu_Image"/>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
<addaction name="menuView"/>
<addaction name="menuTransform"/>
<addaction name="menuImage"/>
</widget>
</item>
<item>
@ -135,7 +135,40 @@
</widget>
</item>
<item>
<widget class="QGraphicsView" name="graphicsView"/>
<layout class="QHBoxLayout">
<item>
<widget class="QWidget">
<layout class="QVBoxLayout">
<item>
<widget class="QPushButton" />
</item>
</layout>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<widget class="DrawingCanvasWidget" name="canvas">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>0</width>
<height>0</height>
</rect>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QWidget">
<layout class="QVBoxLayout">
<item>
<widget class="QPushButton" />
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QStatusBar" name="statusBar"/>
@ -264,8 +297,32 @@
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>DrawingCanvasWidget</class>
<extends>QWidget</extends>
<header>drawingcanvaswidget.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../resources.qrc"/>
</resources>
<connections/>
<connections>
<connection>
<sender>actionCloseSavingChanges</sender>
<signal>triggered()</signal>
<receiver>ImageEditorDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>285</x>
<y>226</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,23 @@
#include "includedfilesdialog.h"
#include "ui_includedfilesdialog.h"
#include "projectcontainer.h"
#include "includedfilesmodel.h"
IncludedFilesDialog::IncludedFilesDialog(ProjectContainer &project, QWidget *parent) :
QDialog{parent},
m_ui{std::make_unique<Ui::IncludedFilesDialog>()},
m_project{project},
m_model{std::make_unique<IncludedFilesModel>(m_project, this)}
{
m_ui->setupUi(this);
if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Ok))
button->setIcon(QIcon{":/qtgameengine/icons/ok.png"});
if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Cancel))
button->setIcon(QIcon{":/qtgameengine/icons/delete.png"});
m_ui->listView->setModel(m_model.get());
}
IncludedFilesDialog::~IncludedFilesDialog() = default;

View File

@ -0,0 +1,25 @@
#pragma once
#include <QDialog>
#include <memory>
namespace Ui { class IncludedFilesDialog; }
struct ProjectContainer;
class IncludedFilesModel;
class IncludedFilesDialog : public QDialog
{
Q_OBJECT
public:
explicit IncludedFilesDialog(ProjectContainer &project, QWidget *parent = nullptr);
~IncludedFilesDialog();
private:
const std::unique_ptr<Ui::IncludedFilesDialog> m_ui;
ProjectContainer &m_project;
const std::unique_ptr<IncludedFilesModel> m_model;
};

View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>IncludedFilesDialog</class>
<widget class="QDialog" name="IncludedFilesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Included Files</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
<item>
<widget class="QGroupBox" name="groupBox">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Files to include in the stand alone executable:</string>
</property>
</widget>
</item>
<item>
<widget class="QListView" name="listView"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButtonAdd">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonChange">
<property name="text">
<string>Change</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonDelete">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonClear">
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
<property name="centerButtons">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>IncludedFilesDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>199</x>
<y>278</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>149</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>IncludedFilesDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>199</x>
<y>278</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>149</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,16 @@
#include "maskpropertiesdialog.h"
#include "ui_maskpropertiesdialog.h"
MaskPropertiesDialog::MaskPropertiesDialog(QWidget *parent) :
QDialog{parent},
m_ui{std::make_unique<Ui::MaskPropertiesDialog>()}
{
m_ui->setupUi(this);
#ifdef Q_OS_LINUX
setWindowFlags(windowFlags() & ~Qt::Dialog | Qt::Window);
#endif
setWindowFlag(Qt::WindowCloseButtonHint);
}
MaskPropertiesDialog::~MaskPropertiesDialog() = default;

View File

@ -0,0 +1,19 @@
#pragma once
#include <QDialog>
#include <memory>
namespace Ui { class MaskPropertiesDialog; }
class MaskPropertiesDialog : public QDialog
{
Q_OBJECT
public:
explicit MaskPropertiesDialog(QWidget *parent = nullptr);
~MaskPropertiesDialog();
private:
const std::unique_ptr<Ui::MaskPropertiesDialog> m_ui;
};

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MaskPropertiesDialog</class>
<widget class="QDialog" name="MaskPropertiesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Mask Properties</string>
</property>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,9 +1,10 @@
#include "objectinformationdialog.h"
#include "ui_objectinformationdialog.h"
ObjectInformationDialog::ObjectInformationDialog(QWidget *parent) :
ObjectInformationDialog::ObjectInformationDialog(ProjectContainer &project, QWidget *parent) :
QDialog{parent},
m_ui{std::make_unique<Ui::ObjectInformationDialog>()}
m_ui{std::make_unique<Ui::ObjectInformationDialog>()},
m_project{project}
{
m_ui->setupUi(this);
}

View File

@ -5,15 +5,18 @@
#include <memory>
namespace Ui { class ObjectInformationDialog; }
struct ProjectContainer;
class ObjectInformationDialog : public QDialog
{
Q_OBJECT
public:
explicit ObjectInformationDialog(QWidget *parent = nullptr);
explicit ObjectInformationDialog(ProjectContainer &project, QWidget *parent = nullptr);
~ObjectInformationDialog();
private:
const std::unique_ptr<Ui::ObjectInformationDialog> m_ui;
ProjectContainer &m_project;
};

View File

@ -96,5 +96,22 @@
<resources>
<include location="../resources.qrc"/>
</resources>
<connections/>
<connections>
<connection>
<sender>actionOk</sender>
<signal>triggered()</signal>
<receiver>ObjectInformationDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>149</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,25 +1,63 @@
#include "pathpropertiesdialog.h"
#include "ui_pathpropertiesdialog.h"
#include <QSpinBox>
#include <QLabel>
#include <QDebug>
#include <QMessageBox>
#include "projectcontainer.h"
#include "projecttreemodel.h"
#include "pathpointsmodel.h"
PathPropertiesDialog::PathPropertiesDialog(Path &path, ProjectTreeModel &projectModel, QWidget *parent) :
QDialog{parent},
m_ui{std::make_unique<Ui::PathPropertiesDialog>()},
m_path{path},
m_projectModel{projectModel},
m_points{path.points},
m_pointsModel{std::make_unique<PathPointsModel>(m_points, this)},
m_spinBoxSnapX{new QSpinBox{this}},
m_spinBoxSnapY{new QSpinBox{this}},
m_labelX{new QLabel{tr("x: %0").arg(0)}},
m_labelY{new QLabel{tr("y: %0").arg(0)}},
m_labelArea{new QLabel{tr("Area: (%0,%1)->(%2,%3)").arg(0).arg(0).arg(0).arg(0)}}
{
m_ui->setupUi(this);
m_ui->widget->setPoints(&m_points);
updateTitle();
{
auto label = new QLabel{tr("Snap X:"), this};
label->setBuddy(m_spinBoxSnapX);
m_ui->toolBar->insertWidget(m_ui->toolBar->actions().at(18), label);
}
m_spinBoxSnapX->setValue(m_ui->widget->gridX());
m_spinBoxSnapX->setMaximumWidth(50);
m_ui->toolBar->insertWidget(m_ui->toolBar->actions().at(19), m_spinBoxSnapX);
{
auto label = new QLabel{tr("Snap Y:"), this};
label->setBuddy(m_spinBoxSnapY);
m_ui->toolBar->insertWidget(m_ui->toolBar->actions().at(20), label);
}
m_spinBoxSnapY->setValue(m_ui->widget->gridY());
m_spinBoxSnapY->setMaximumWidth(50);
m_ui->toolBar->insertWidget(m_ui->toolBar->actions().at(21), m_spinBoxSnapY);
m_ui->actionGrid->setChecked(m_ui->widget->showGrid());
m_ui->treeView->setModel(m_pointsModel.get());
m_ui->radioButtonStraight->setChecked(m_path.type == Path::Type::Straight);
m_ui->radioButtonSmooth->setChecked(m_path.type == Path::Type::Smooth);
m_ui->checkBoxClosed->setChecked(m_path.closed);
m_ui->spinBoxPrecision->setValue(m_path.precision);
m_ui->widget->setClosed(m_path.closed);
m_labelX->setFrameStyle(QFrame::Sunken);
m_ui->statusbar->addWidget(m_labelX, 1);
m_labelY->setFrameStyle(QFrame::Sunken);
@ -35,9 +73,41 @@ PathPropertiesDialog::PathPropertiesDialog(Path &path, ProjectTreeModel &project
m_ui->lineEditName->setText(m_path.name);
m_ui->treeView->setColumnWidth(1, 75);
connect(m_ui->widget, &PathPointsWidget::pointInserted,
m_pointsModel.get(), &PathPointsModel::pointInserted);
connect(m_ui->widget, &PathPointsWidget::pointMoved,
m_pointsModel.get(), &PathPointsModel::pointMoved);
connect(&m_projectModel, &ProjectTreeModel::pathNameChanged,
this, &PathPropertiesDialog::pathNameChanged);
connect(m_ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged,
this, &PathPropertiesDialog::selectionChanged);
connect(m_ui->widget, &PathPointsWidget::gridXChanged,
m_spinBoxSnapX, &QSpinBox::setValue);
connect(m_ui->widget, &PathPointsWidget::gridYChanged,
m_spinBoxSnapY, &QSpinBox::setValue);
connect(m_ui->widget, &PathPointsWidget::showGridChanged,
m_ui->actionGrid, &QAction::setChecked);
connect(m_ui->widget, &PathPointsWidget::closedChanged,
m_ui->checkBoxClosed, &QCheckBox::setChecked);
connect(m_ui->widget, &PathPointsWidget::cursorMoved,
this, &PathPropertiesDialog::cursorMoved);
connect(m_ui->widget, &PathPointsWidget::selectedIndexChanged,
this, &PathPropertiesDialog::selectedPointChanged);
connect(m_spinBoxSnapX, &QSpinBox::valueChanged,
m_ui->widget, &PathPointsWidget::setGridX);
connect(m_spinBoxSnapY, &QSpinBox::valueChanged,
m_ui->widget, &PathPointsWidget::setGridY);
connect(m_ui->actionGrid, &QAction::toggled,
m_ui->widget, &PathPointsWidget::setShowGrid);
connect(m_ui->checkBoxClosed, &QCheckBox::toggled,
m_ui->widget, &PathPointsWidget::setClosed);
connect(m_ui->pushButtonAdd, &QAbstractButton::pressed,
this, &PathPropertiesDialog::add);
connect(m_ui->pushButtonInsert, &QAbstractButton::pressed,
@ -47,12 +117,35 @@ PathPropertiesDialog::PathPropertiesDialog(Path &path, ProjectTreeModel &project
connect(m_ui->lineEditName, &QLineEdit::textChanged,
this, &PathPropertiesDialog::changed);
connect(m_pointsModel.get(), &QAbstractTableModel::rowsInserted,
this, &PathPropertiesDialog::changed);
connect(m_pointsModel.get(), &QAbstractTableModel::rowsRemoved,
this, &PathPropertiesDialog::changed);
connect(m_pointsModel.get(), &QAbstractTableModel::dataChanged,
this, &PathPropertiesDialog::dataChanged);
connect(m_pointsModel.get(), &QAbstractTableModel::dataChanged,
this, &PathPropertiesDialog::changed);
connect(m_ui->radioButtonStraight, &QRadioButton::toggled,
this, &PathPropertiesDialog::changed);
connect(m_ui->radioButtonSmooth, &QRadioButton::toggled,
this, &PathPropertiesDialog::changed);
connect(m_ui->checkBoxClosed, &QCheckBox::toggled,
this, &PathPropertiesDialog::changed);
connect(m_ui->spinBoxPrecision, &QSpinBox::valueChanged,
this, &PathPropertiesDialog::changed);
}
PathPropertiesDialog::~PathPropertiesDialog() = default;
void PathPropertiesDialog::accept()
{
if (!m_unsavedChanges)
{
QDialog::reject();
return;
}
if (m_path.name != m_ui->lineEditName->text())
{
if (!m_projectModel.rename<Path>(m_path, m_ui->lineEditName->text()))
@ -62,7 +155,22 @@ void PathPropertiesDialog::accept()
}
}
// TODO
m_path.points = m_points;
if (m_ui->radioButtonStraight->isChecked())
m_path.type = Path::Type::Straight;
else if (m_ui->radioButtonSmooth->isChecked())
m_path.type = Path::Type::Smooth;
else
{
QMessageBox::critical(this, tr("No kind selected!"), tr("No kind selected!"));
return;
}
m_path.closed = m_ui->checkBoxClosed->isChecked();
m_path.precision = m_ui->spinBoxPrecision->value();
// TODO update points
QDialog::accept();
}
@ -97,6 +205,36 @@ void PathPropertiesDialog::reject()
}
}
void PathPropertiesDialog::selectionChanged(const QModelIndex &index)
{
if (!index.isValid())
{
m_ui->widget->setSelectedIndex(std::nullopt);
return;
}
m_ui->widget->setSelectedIndex(index.row());
updatePointFields();
}
void PathPropertiesDialog::selectedPointChanged(const std::optional<std::size_t> &index)
{
m_ui->treeView->setCurrentIndex(index ? m_pointsModel->index(*index, 0, {}) : QModelIndex{});
}
void PathPropertiesDialog::dataChanged(const QModelIndex &index)
{
if (index == m_ui->treeView->currentIndex())
updatePointFields();
}
void PathPropertiesDialog::cursorMoved(const QPoint &point)
{
m_labelX->setText(tr("X: %0").arg(point.x()));
m_labelY->setText(tr("Y: %0").arg(point.y()));
}
void PathPropertiesDialog::add()
{
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
@ -141,3 +279,11 @@ void PathPropertiesDialog::updateTitle()
.arg(m_unsavedChanges ? tr("*") : QString{})
);
}
void PathPropertiesDialog::updatePointFields()
{
const auto point = m_pointsModel->getPoint(m_ui->treeView->currentIndex());
m_ui->spinBoxX->setValue(point.point.x());
m_ui->spinBoxY->setValue(point.point.y());
m_ui->spinBoxSp->setValue(point.sp);
}

View File

@ -3,11 +3,15 @@
#include <QDialog>
#include <memory>
#include <optional>
#include "projectcontainer.h"
class QSpinBox;
class QLabel;
namespace Ui { class PathPropertiesDialog; }
struct Path;
class ProjectTreeModel;
class PathPointsModel;
class PathPropertiesDialog : public QDialog
{
@ -21,6 +25,11 @@ public:
void reject() override;
private slots:
void selectionChanged(const QModelIndex &index);
void selectedPointChanged(const std::optional<std::size_t> &index);
void dataChanged(const QModelIndex &index);
void cursorMoved(const QPoint &point);
void add();
void insert();
void delete_();
@ -31,14 +40,22 @@ private slots:
private:
void updateTitle();
void updatePointFields();
const std::unique_ptr<Ui::PathPropertiesDialog> m_ui;
Path &m_path;
ProjectTreeModel &m_projectModel;
std::vector<Path::Point> m_points;
const std::unique_ptr<PathPointsModel> m_pointsModel;
bool m_unsavedChanges{};
QSpinBox * const m_spinBoxSnapX;
QSpinBox * const m_spinBoxSnapY;
QLabel * const m_labelX;
QLabel * const m_labelY;
QLabel * const m_labelArea;

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>728</width>
<height>449</height>
<width>921</width>
<height>576</height>
</rect>
</property>
<property name="windowTitle">
@ -78,6 +78,20 @@
<addaction name="actionClear"/>
<addaction name="actionReverse"/>
<addaction name="actionShift"/>
<addaction name="actionMirrorHorizontally"/>
<addaction name="actionFlipVertically"/>
<addaction name="actionRotate"/>
<addaction name="actionScale"/>
<addaction name="separator"/>
<addaction name="actionShiftLeft"/>
<addaction name="actionShiftRight"/>
<addaction name="actionShiftTop"/>
<addaction name="actionShift_bottom"/>
<addaction name="actionCenterView"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="actionGrid"/>
<addaction name="actionRoom"/>
</widget>
</item>
</layout>
@ -112,7 +126,11 @@
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditName"/>
<widget class="QLineEdit" name="lineEditName">
<property name="toolTip">
<string>The name of the path</string>
</property>
</widget>
</item>
</layout>
</item>
@ -133,13 +151,19 @@
</spacer>
</item>
<item>
<widget class="QListView" name="listView">
<widget class="QTreeView" name="treeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
</widget>
</item>
<item>
@ -170,7 +194,14 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBoxX"/>
<widget class="QSpinBox" name="spinBoxX">
<property name="toolTip">
<string>X-coordinate of the point</string>
</property>
<property name="maximum">
<number>16384</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelY">
@ -180,7 +211,14 @@
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBoxY"/>
<widget class="QSpinBox" name="spinBoxY">
<property name="toolTip">
<string>Y-coordinate of the point</string>
</property>
<property name="maximum">
<number>16384</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelSp">
@ -190,7 +228,14 @@
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_3"/>
<widget class="QSpinBox" name="spinBoxSp">
<property name="toolTip">
<string>Relative speed at this point (100 = default)</string>
</property>
<property name="maximum">
<number>16384</number>
</property>
</widget>
</item>
</layout>
</item>
@ -211,6 +256,9 @@
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QPushButton" name="pushButtonAdd">
<property name="toolTip">
<string>Add the point to the path</string>
</property>
<property name="text">
<string>Add</string>
</property>
@ -218,6 +266,9 @@
</item>
<item>
<widget class="QPushButton" name="pushButtonInsert">
<property name="toolTip">
<string>Insert the point before the current one</string>
</property>
<property name="text">
<string>Insert</string>
</property>
@ -225,6 +276,9 @@
</item>
<item>
<widget class="QPushButton" name="pushButtonDelete">
<property name="toolTip">
<string>Delete the point from the path</string>
</property>
<property name="text">
<string>Delete</string>
</property>
@ -256,6 +310,9 @@
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QGroupBox" name="groupBoxConnectionKind">
<property name="toolTip">
<string>Indicate the type of connections between the points</string>
</property>
<property name="title">
<string>connection kind</string>
</property>
@ -287,7 +344,11 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBoxPrecision"/>
<widget class="QSpinBox" name="spinBoxPrecision">
<property name="toolTip">
<string>Precision with which to create smooth curves</string>
</property>
</widget>
</item>
</layout>
</item>
@ -324,7 +385,14 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout_7" stretch="1,0">
<item>
<widget class="QWidget" name="widget" native="true"/>
<widget class="PathPointsWidget" name="widget" native="true">
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QStatusBar" name="statusbar"/>
@ -394,7 +462,153 @@
<string>Shift the path</string>
</property>
</action>
<action name="actionMirrorHorizontally">
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/qtgameengine/icons/flip-horizontal.png</normaloff>:/qtgameengine/icons/flip-horizontal.png</iconset>
</property>
<property name="text">
<string>Mirror horizontally</string>
</property>
<property name="toolTip">
<string>Mirror the path horizontally</string>
</property>
</action>
<action name="actionFlipVertically">
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/qtgameengine/icons/flip-vertical.png</normaloff>:/qtgameengine/icons/flip-vertical.png</iconset>
</property>
<property name="text">
<string>Flip vertically</string>
</property>
<property name="toolTip">
<string>Flip the path vertically</string>
</property>
</action>
<action name="actionRotate">
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/qtgameengine/icons/rotate.png</normaloff>:/qtgameengine/icons/rotate.png</iconset>
</property>
<property name="text">
<string>Rotate</string>
</property>
<property name="toolTip">
<string>Rotate the path</string>
</property>
</action>
<action name="actionScale">
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/qtgameengine/icons/scale.png</normaloff>:/qtgameengine/icons/scale.png</iconset>
</property>
<property name="text">
<string>Scale</string>
</property>
<property name="toolTip">
<string>Scale the path</string>
</property>
</action>
<action name="actionShiftLeft">
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/qtgameengine/icons/arrow-left.png</normaloff>:/qtgameengine/icons/arrow-left.png</iconset>
</property>
<property name="text">
<string>Shift Left</string>
</property>
<property name="toolTip">
<string>Shift the view to the left</string>
</property>
</action>
<action name="actionShiftRight">
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/qtgameengine/icons/arrow-right.png</normaloff>:/qtgameengine/icons/arrow-right.png</iconset>
</property>
<property name="text">
<string>Shift right</string>
</property>
<property name="toolTip">
<string>Shift the view to the right</string>
</property>
</action>
<action name="actionShiftTop">
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/qtgameengine/icons/arrow-up.png</normaloff>:/qtgameengine/icons/arrow-up.png</iconset>
</property>
<property name="text">
<string>Shift top</string>
</property>
<property name="toolTip">
<string>Shift the view to the top</string>
</property>
</action>
<action name="actionShift_bottom">
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/qtgameengine/icons/arrow-down.png</normaloff>:/qtgameengine/icons/arrow-down.png</iconset>
</property>
<property name="text">
<string>Shift bottom</string>
</property>
<property name="toolTip">
<string>Shift the view to the bottom</string>
</property>
</action>
<action name="actionCenterView">
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/qtgameengine/icons/center.png</normaloff>:/qtgameengine/icons/center.png</iconset>
</property>
<property name="text">
<string>Center view</string>
</property>
<property name="toolTip">
<string>Center view around the path</string>
</property>
</action>
<action name="actionGrid">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/qtgameengine/icons/grid.png</normaloff>:/qtgameengine/icons/grid.png</iconset>
</property>
<property name="text">
<string>Grid</string>
</property>
<property name="toolTip">
<string>Toggle the showing of the grid</string>
</property>
</action>
<action name="actionRoom">
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/qtgameengine/icons/room.png</normaloff>:/qtgameengine/icons/room.png</iconset>
</property>
<property name="text">
<string>Room</string>
</property>
<property name="toolTip">
<string>Indicate the room to show as background</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>PathPointsWidget</class>
<extends>QWidget</extends>
<header>pathpointswidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../resources.qrc"/>
</resources>

View File

@ -1,17 +1,23 @@
#include "preferencesdialog.h"
#include "ui_preferencesdialog.h"
#include <QPushButton>
PreferencesDialog::PreferencesDialog(QWidget *parent) :
QDialog{parent},
m_ui{std::make_unique<Ui::PreferencesDialog>()}
{
m_ui->setupUi(this);
setWindowFlags(windowFlags()
& ~Qt::Dialog
| Qt::Window
| Qt::WindowMinimizeButtonHint
| Qt::WindowMaximizeButtonHint
| Qt::WindowCloseButtonHint);
#ifdef Q_OS_LINUX
setWindowFlags(windowFlags() & ~Qt::Dialog | Qt::Window);
#endif
setWindowFlag(Qt::WindowCloseButtonHint);
if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Ok))
button->setIcon(QIcon{":/qtgameengine/icons/ok.png"});
if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Cancel))
button->setIcon(QIcon{":/qtgameengine/icons/delete.png"});
}
PreferencesDialog::~PreferencesDialog() = default;

View File

@ -1,27 +1,20 @@
#include "scriptpropertiesdialog.h"
#include "ui_scriptpropertiesdialog.h"
#include "ui_codeeditordialog.h"
#include <QDebug>
#include <QFont>
#include <QLineEdit>
#include <QLabel>
#include <QTextBlock>
#include <QLineEdit>
#include <QMessageBox>
#include <QDebug>
#include "projectcontainer.h"
#include "projecttreemodel.h"
#include "jshighlighter.h"
ScriptPropertiesDialog::ScriptPropertiesDialog(Script &script, ProjectTreeModel &projectModel, QWidget *parent) :
QDialog{parent},
m_ui{std::make_unique<Ui::ScriptPropertiesDialog>()},
CodeEditorDialog{parent},
m_script{script},
m_projectModel{projectModel},
m_lineEditName{new QLineEdit{this}},
m_labelPosition{new QLabel{this}}
m_lineEditName{new QLineEdit{this}}
{
m_ui->setupUi(this);
updateTitle();
{
@ -32,46 +25,19 @@ ScriptPropertiesDialog::ScriptPropertiesDialog(Script &script, ProjectTreeModel
m_lineEditName->setMaximumWidth(100);
m_ui->toolBar->addWidget(m_lineEditName);
m_labelPosition->setFrameStyle(QFrame::Sunken);
m_ui->statusbar->addWidget(m_labelPosition);
{
QFont font;
font.setFamily("Consolas");
font.setFixedPitch(true);
font.setPointSize(10);
m_ui->codeEdit->setFont(font);
}
new JSHighlighter{m_ui->codeEdit->document()};
m_lineEditName->setText(m_script.name);
m_ui->codeEdit->setPlainText(m_script.script);
updatePosition();
connect(&m_projectModel, &ProjectTreeModel::scriptNameChanged,
this, &ScriptPropertiesDialog::scriptNameChanged);
connect(m_ui->actionLoad, &QAction::triggered,
this, &ScriptPropertiesDialog::load);
connect(m_ui->actionSave, &QAction::triggered,
this, &ScriptPropertiesDialog::save);
connect(m_ui->actionPrint, &QAction::triggered,
this, &ScriptPropertiesDialog::print);
connect(m_lineEditName, &QLineEdit::textChanged,
this, &ScriptPropertiesDialog::changed);
connect(m_ui->codeEdit, &QPlainTextEdit::textChanged,
this, &ScriptPropertiesDialog::changed);
connect(m_ui->codeEdit, &QPlainTextEdit::textChanged,
this, &ScriptPropertiesDialog::updatePosition);
connect(m_ui->codeEdit, &QPlainTextEdit::cursorPositionChanged,
this, &ScriptPropertiesDialog::updatePosition);
}
ScriptPropertiesDialog::~ScriptPropertiesDialog() = default;
void ScriptPropertiesDialog::accept()
{
if (m_script.name != m_lineEditName->text())
@ -85,14 +51,14 @@ void ScriptPropertiesDialog::accept()
m_script.script = m_ui->codeEdit->toPlainText();
QDialog::accept();
CodeEditorDialog::accept();
}
void ScriptPropertiesDialog::reject()
{
if (!m_unsavedChanges)
{
QDialog::reject();
CodeEditorDialog::reject();
return;
}
@ -109,7 +75,7 @@ void ScriptPropertiesDialog::reject()
accept();
return;
case QMessageBox::Discard:
QDialog::reject();
CodeEditorDialog::reject();
return;
case QMessageBox::Cancel:
return;
@ -127,44 +93,6 @@ void ScriptPropertiesDialog::changed()
}
}
void ScriptPropertiesDialog::load()
{
}
void ScriptPropertiesDialog::save()
{
}
void ScriptPropertiesDialog::print()
{
}
void ScriptPropertiesDialog::updatePosition()
{
auto cursor = m_ui->codeEdit->textCursor();
auto position = cursor.position();
cursor.movePosition(QTextCursor::StartOfLine);
position -= cursor.position() - 1;
int lines = 1;
while (cursor.positionInBlock() > 0)
{
cursor.movePosition(QTextCursor::Up);
//lines++;
}
QTextBlock block = cursor.block().previous();
while (block.isValid())
{
lines += 1; //block.lineCount();
block = block.previous();
}
m_labelPosition->setText(tr("%0/%1: %2").arg(lines).arg(m_ui->codeEdit->blockCount()).arg(position));
}
void ScriptPropertiesDialog::scriptNameChanged(const Script &script)
{
if (&script != &m_script)
@ -185,3 +113,4 @@ void ScriptPropertiesDialog::updateTitle()
.arg(m_unsavedChanges ? tr("*") : QString{})
);
}

View File

@ -1,22 +1,15 @@
#pragma once
#include <QDialog>
#include <memory>
#include "codeeditordialog.h"
class QLineEdit;
class QLabel;
namespace Ui { class ScriptPropertiesDialog; }
struct Script;
class ProjectTreeModel;
class ScriptPropertiesDialog : public QDialog
class ScriptPropertiesDialog : public CodeEditorDialog
{
Q_OBJECT
public:
explicit ScriptPropertiesDialog(Script &script, ProjectTreeModel &projectModel, QWidget *parent = nullptr);
~ScriptPropertiesDialog();
ScriptPropertiesDialog(Script &script, ProjectTreeModel &projectModel, QWidget *parent = nullptr);
void accept() override;
void reject() override;
@ -24,25 +17,15 @@ public:
private slots:
void changed();
void load();
void save();
void print();
void updatePosition();
void scriptNameChanged(const Script &script);
private:
void updateTitle();
const std::unique_ptr<Ui::ScriptPropertiesDialog> m_ui;
Script &m_script;
ProjectTreeModel &m_projectModel;
bool m_unsavedChanges{};
QLineEdit * const m_lineEditName;
QLabel * const m_labelPosition;
};

View File

@ -14,7 +14,8 @@ SoundPropertiesDialog::SoundPropertiesDialog(Sound &sound, ProjectTreeModel &pro
QDialog{parent},
m_ui{std::make_unique<Ui::SoundPropertiesDialog>()},
m_sound{sound},
m_projectModel{projectModel}
m_projectModel{projectModel},
m_path{m_sound.path}
{
m_ui->setupUi(this);
@ -33,6 +34,8 @@ SoundPropertiesDialog::SoundPropertiesDialog(Sound &sound, ProjectTreeModel &pro
}
m_ui->radioButtonNormal->setChecked(m_sound.type == Sound::Type::Sound);
m_ui->radioButtonMusic->setChecked(m_sound.type == Sound::Type::Music);
m_ui->radioButton3D->setChecked(false);
m_ui->radioButtonMultimedia->setChecked(false);
m_ui->checkBoxChorus->setChecked(m_sound.effects.chorus);
m_ui->checkBoxFlanger->setChecked(m_sound.effects.flanger);
m_ui->checkBoxGargle->setChecked(m_sound.effects.gargle);
@ -88,6 +91,12 @@ SoundPropertiesDialog::~SoundPropertiesDialog() = default;
void SoundPropertiesDialog::accept()
{
if (!m_unsavedChanges)
{
QDialog::reject();
return;
}
if (m_sound.name != m_ui->lineEditName->text())
{
if (!m_projectModel.rename<Sound>(m_sound, m_ui->lineEditName->text()))
@ -97,18 +106,23 @@ void SoundPropertiesDialog::accept()
}
}
if (m_newPath)
m_sound.path = std::move(*m_newPath);
m_sound.path = std::move(m_path);
if (m_ui->radioButtonNormal->isChecked())
m_sound.type = Sound::Type::Sound;
else if (m_ui->radioButtonMusic->isChecked())
m_sound.type = Sound::Type::Music;
else
else if (m_ui->radioButton3D->isChecked() ||
m_ui->radioButtonMultimedia->isChecked())
{
QMessageBox::critical(this, tr("Not implemented"), tr("This kind of sound is not yet supported!"));
return;
}
else
{
QMessageBox::critical(this, tr("No kind selected!"), tr("No kind selected!"));
return;
}
m_sound.effects.chorus = m_ui->checkBoxChorus->isChecked();
m_sound.effects.flanger = m_ui->checkBoxFlanger->isChecked();
@ -153,7 +167,7 @@ void SoundPropertiesDialog::reject()
void SoundPropertiesDialog::loadSound()
{
const auto path = QFileDialog::getOpenFileName(this, tr("Open a Sound File..."));
auto path = QFileDialog::getOpenFileName(this, tr("Open a Sound File..."));
if (path.isEmpty())
return;
@ -163,16 +177,15 @@ void SoundPropertiesDialog::loadSound()
return;
}
m_newPath = path;
m_path = std::move(path);
changed();
m_ui->labelFilename->setText(tr("Filename: %0").arg(QFileInfo{path}.fileName()));
m_soundEffect.setSource(QUrl::fromLocalFile(path));
m_ui->labelFilename->setText(tr("Filename: %0").arg(QFileInfo{m_path}.fileName()));
m_soundEffect.setSource(QUrl::fromLocalFile(m_path));
}
void SoundPropertiesDialog::saveSound()
{
const auto &path = m_newPath ? *m_newPath : m_sound.path;
if (path.isEmpty())
if (m_path.isEmpty())
{
QMessageBox::warning(this, tr("Could not save Sound!"), tr("Could not save Sound!") + "\n\n" + tr("No sound has been selected yet."));
return;
@ -182,7 +195,7 @@ void SoundPropertiesDialog::saveSound()
if (savePath.isEmpty())
return;
if (!QFile::copy(path, savePath))
if (!QFile::copy(m_path, savePath))
{
QMessageBox::warning(this, tr("Could not save Sound!"), tr("Could not save Sound!"));
return;

View File

@ -43,7 +43,7 @@ private:
bool m_unsavedChanges{};
std::optional<QString> m_newPath;
QString m_path;
QSoundEffect m_soundEffect;
};

View File

@ -31,7 +31,11 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEditName"/>
<widget class="QLineEdit" name="lineEditName">
<property name="toolTip">
<string>The name of the sound</string>
</property>
</widget>
</item>
</layout>
</item>
@ -39,6 +43,9 @@
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0,0">
<item>
<widget class="QPushButton" name="pushButtonLoad">
<property name="toolTip">
<string>Load the sound from a file</string>
</property>
<property name="text">
<string>&amp;Load Sound</string>
</property>
@ -80,6 +87,9 @@
</item>
<item>
<widget class="QPushButton" name="pushButtonSave">
<property name="toolTip">
<string>Save the sound to a file</string>
</property>
<property name="text">
<string>Sa&amp;ve Sound</string>
</property>
@ -98,6 +108,9 @@
</item>
<item>
<widget class="QGroupBox" name="groupBoxKind">
<property name="toolTip">
<string>Set the kind of this sound</string>
</property>
<property name="title">
<string>Kind</string>
</property>
@ -107,9 +120,6 @@
<property name="text">
<string>Normal Sound</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
@ -138,6 +148,9 @@
</item>
<item>
<widget class="QGroupBox" name="groupBoxEffects">
<property name="toolTip">
<string>Set the effects to apply for the sound</string>
</property>
<property name="title">
<string>Effects</string>
</property>
@ -194,6 +207,9 @@
</item>
<item row="0" column="1">
<widget class="QSlider" name="horizontalSliderVolume">
<property name="toolTip">
<string>Indicates the default volume for the sound</string>
</property>
<property name="maximum">
<number>100</number>
</property>
@ -217,6 +233,9 @@
</item>
<item row="1" column="1">
<widget class="QSlider" name="horizontalSliderPan">
<property name="toolTip">
<string>Indicates the default pan for the sound</string>
</property>
<property name="minimum">
<number>-100</number>
</property>
@ -238,6 +257,9 @@
</item>
<item>
<widget class="QCheckBox" name="checkBoxPreload">
<property name="toolTip">
<string>Indicates whether to preload the sound when the game starts</string>
</property>
<property name="text">
<string>&amp;Preload</string>
</property>
@ -263,6 +285,9 @@
</item>
<item>
<widget class="QPushButton" name="pushButtonEdit">
<property name="toolTip">
<string>Edit the sound using an external sound editor</string>
</property>
<property name="text">
<string>&amp;Edit Sound</string>
</property>

View File

@ -9,12 +9,14 @@
#include "projectcontainer.h"
#include "projecttreemodel.h"
#include "editspritedialog.h"
#include "maskpropertiesdialog.h"
SpritePropertiesDialog::SpritePropertiesDialog(Sprite &sprite, ProjectTreeModel &projectModel, QWidget *parent) :
QDialog{parent},
m_ui{std::make_unique<Ui::SpritePropertiesDialog>()},
m_sprite{sprite},
m_projectModel{projectModel}
m_projectModel{projectModel},
m_pixmaps{m_sprite.pixmaps}
{
m_ui->setupUi(this);
@ -31,7 +33,6 @@ SpritePropertiesDialog::SpritePropertiesDialog(Sprite &sprite, ProjectTreeModel
m_ui->spinBoxOriginY->setValue(m_sprite.origin.y);
m_ui->checkBoxPreciseCollisionChecking->setChecked(m_sprite.preciseCollisionChecking);
m_ui->checkBoxSeparateCollisionMasks->setChecked(m_sprite.separateCollisionMasks);
m_ui->labelPreview->setPixmap(m_sprite.pixmaps.empty() ? QPixmap{} : m_sprite.pixmaps.front());
connect(&m_projectModel, &ProjectTreeModel::spriteNameChanged,
this, &SpritePropertiesDialog::spriteNameChanged);
@ -44,6 +45,8 @@ SpritePropertiesDialog::SpritePropertiesDialog(Sprite &sprite, ProjectTreeModel
this, &SpritePropertiesDialog::editSprite);
connect(m_ui->pushButtonCenterOrigin, &QAbstractButton::pressed,
this, &SpritePropertiesDialog::centerOrigin);
connect(m_ui->pushButtonModifyCollisionmask, &QAbstractButton::pressed,
this, &SpritePropertiesDialog::modifyMask);
connect(m_ui->lineEditName, &QLineEdit::textChanged,
this, &SpritePropertiesDialog::changed);
@ -61,6 +64,12 @@ SpritePropertiesDialog::~SpritePropertiesDialog() = default;
void SpritePropertiesDialog::accept()
{
if (!m_unsavedChanges)
{
QDialog::reject();
return;
}
if (m_sprite.name != m_ui->lineEditName->text())
{
if (!m_projectModel.rename<Sprite>(m_sprite, m_ui->lineEditName->text()))
@ -70,8 +79,7 @@ void SpritePropertiesDialog::accept()
}
}
if (m_newPixmaps)
m_sprite.pixmaps = std::move(*m_newPixmaps);
m_sprite.pixmaps = std::move(m_pixmaps);
m_sprite.origin.x = m_ui->spinBoxOriginX->value();
m_sprite.origin.y = m_ui->spinBoxOriginY->value();
m_sprite.preciseCollisionChecking = m_ui->checkBoxPreciseCollisionChecking->isChecked();
@ -123,20 +131,14 @@ void SpritePropertiesDialog::loadSprite()
return;
}
m_ui->labelPreview->setPixmap(pixmap);
m_newPixmaps = std::vector<QPixmap>{ std::move(pixmap) };
m_unsavedChanges = true;
updateTitle();
m_pixmaps = std::vector<QPixmap>{ std::move(pixmap) };
changed();
updateSpriteInfo();
}
void SpritePropertiesDialog::saveSprite()
{
const auto &pixmaps = m_newPixmaps ? *m_newPixmaps : m_sprite.pixmaps;
if (pixmaps.empty() || pixmaps.front().isNull())
if (m_pixmaps.empty() || m_pixmaps.front().isNull())
{
QMessageBox::warning(this, tr("No sprites available to save!"), tr("No sprites available to save!"));
return;
@ -146,7 +148,7 @@ void SpritePropertiesDialog::saveSprite()
if (path.isEmpty())
return;
if (!pixmaps.front().save(path))
if (!m_pixmaps.front().save(path))
{
QMessageBox::warning(this, tr("Could not save Sprite!"), tr("Could not save Sprite!"));
return;
@ -155,20 +157,33 @@ void SpritePropertiesDialog::saveSprite()
void SpritePropertiesDialog::editSprite()
{
EditSpriteDialog{m_sprite}.exec();
EditSpriteDialog dialog{m_pixmaps, m_sprite.name, this};
if (dialog.exec() == QDialog::Accepted)
{
m_pixmaps = dialog.pixmaps();
changed();
updateSpriteInfo();
}
}
void SpritePropertiesDialog::centerOrigin()
{
const auto &pixmaps = m_newPixmaps ? *m_newPixmaps : m_sprite.pixmaps;
if (pixmaps.empty() || pixmaps.front().isNull())
if (m_pixmaps.empty() || m_pixmaps.front().isNull())
{
qDebug() << "unexpected empty pixmaps";
m_ui->spinBoxOriginX->setValue(0);
m_ui->spinBoxOriginY->setValue(0);
return;
}
m_ui->spinBoxOriginX->setValue(pixmaps.front().width() / 2);
m_ui->spinBoxOriginY->setValue(pixmaps.front().height() / 2);
m_ui->spinBoxOriginX->setValue(m_pixmaps.front().width() / 2);
m_ui->spinBoxOriginY->setValue(m_pixmaps.front().height() / 2);
}
void SpritePropertiesDialog::modifyMask()
{
MaskPropertiesDialog dialog{this};
dialog.exec();
}
void SpritePropertiesDialog::changed()
@ -203,8 +218,8 @@ void SpritePropertiesDialog::updateTitle()
void SpritePropertiesDialog::updateSpriteInfo()
{
const auto &pixmaps = m_newPixmaps ? *m_newPixmaps : m_sprite.pixmaps;
m_ui->labelWidth->setText(tr("Width: %0").arg(pixmaps.empty() ? tr("n/a") : QString::number(pixmaps.front().width())));
m_ui->labelHeight->setText(tr("Height: %0").arg(pixmaps.empty() ? tr("n/a") : QString::number(pixmaps.front().height())));
m_ui->labelSubimages->setText(tr("Number of subimages: %0").arg(pixmaps.size()));
m_ui->labelPreview->setPixmap(m_pixmaps.empty() ? QPixmap{} : m_pixmaps.front());
m_ui->labelWidth->setText(tr("Width: %0").arg(m_pixmaps.empty() ? tr("n/a") : QString::number(m_pixmaps.front().width())));
m_ui->labelHeight->setText(tr("Height: %0").arg(m_pixmaps.empty() ? tr("n/a") : QString::number(m_pixmaps.front().height())));
m_ui->labelSubimages->setText(tr("Number of subimages: %0").arg(m_pixmaps.size()));
}

View File

@ -26,6 +26,7 @@ private slots:
void saveSprite();
void editSprite();
void centerOrigin();
void modifyMask();
void changed();
@ -42,5 +43,5 @@ private:
bool m_unsavedChanges{};
std::optional<std::vector<QPixmap>> m_newPixmaps;
std::vector<QPixmap> m_pixmaps;
};

View File

@ -33,7 +33,11 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEditName"/>
<widget class="QLineEdit" name="lineEditName">
<property name="toolTip">
<string>The name of the sprite</string>
</property>
</widget>
</item>
</layout>
</item>
@ -56,6 +60,9 @@
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QPushButton" name="pushButtonLoad">
<property name="toolTip">
<string>Load the sprite from a file</string>
</property>
<property name="text">
<string>&amp;Load Sprite</string>
</property>
@ -67,6 +74,9 @@
</item>
<item>
<widget class="QPushButton" name="pushButtonSave">
<property name="toolTip">
<string>Save the sprite to a file</string>
</property>
<property name="text">
<string>&amp;Save Sprite</string>
</property>
@ -78,6 +88,9 @@
</item>
<item>
<widget class="QPushButton" name="pushButtonEdit">
<property name="toolTip">
<string>Edit the sprite</string>
</property>
<property name="text">
<string>&amp;Edit Sprite</string>
</property>
@ -151,7 +164,11 @@
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBoxOriginX"/>
<widget class="QSpinBox" name="spinBoxOriginX">
<property name="toolTip">
<string>The x-coordinate in the sprite that is used for the origin</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelOriginY">
@ -167,7 +184,11 @@
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBoxOriginY"/>
<widget class="QSpinBox" name="spinBoxOriginY">
<property name="toolTip">
<string>The y-coordinate in the sprite that is used for the origin</string>
</property>
</widget>
</item>
</layout>
</item>
@ -188,6 +209,9 @@
</item>
<item>
<widget class="QPushButton" name="pushButtonCenterOrigin">
<property name="toolTip">
<string>Put the origin in the center of the image</string>
</property>
<property name="text">
<string>&amp;Center</string>
</property>
@ -246,6 +270,9 @@
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QCheckBox" name="checkBoxPreciseCollisionChecking">
<property name="toolTip">
<string>Perform pixel precise colliion checking</string>
</property>
<property name="text">
<string>&amp;Precise collision checking</string>
</property>
@ -253,6 +280,9 @@
</item>
<item>
<widget class="QCheckBox" name="checkBoxSeparateCollisionMasks">
<property name="toolTip">
<string>Have separate collision masks for the subimages</string>
</property>
<property name="text">
<string>Separa&amp;te Collision Masks</string>
</property>
@ -260,6 +290,9 @@
</item>
<item>
<widget class="QPushButton" name="pushButtonModifyCollisionmask">
<property name="toolTip">
<string>Modify additional options for the collision mask</string>
</property>
<property name="text">
<string>&amp;Modify Mask</string>
</property>

View File

@ -0,0 +1,12 @@
#include "triggerconditiondialog.h"
TriggerConditionDialog::TriggerConditionDialog(QWidget *parent) :
CodeEditorDialog{parent}
{
#ifdef Q_OS_LINUX
setWindowFlags(windowFlags() & ~Qt::Dialog | Qt::Window);
#endif
setWindowFlag(Qt::WindowMinimizeButtonHint);
setWindowFlag(Qt::WindowMaximizeButtonHint);
setWindowFlag(Qt::WindowCloseButtonHint);
}

View File

@ -0,0 +1,11 @@
#pragma once
#include "codeeditordialog.h"
class TriggerConditionDialog : public CodeEditorDialog
{
Q_OBJECT
public:
explicit TriggerConditionDialog(QWidget *parent = nullptr);
};

View File

@ -0,0 +1,33 @@
#include "triggersdialog.h"
#include "ui_triggersdialog.h"
#include "projectcontainer.h"
#include "triggersmodel.h"
#include "triggerconditiondialog.h"
TriggersDialog::TriggersDialog(ProjectContainer &project, QWidget *parent) :
QDialog{parent},
m_ui{std::make_unique<Ui::TriggersDialog>()},
m_project{project},
m_model{std::make_unique<TriggersModel>(project, this)}
{
m_ui->setupUi(this);
if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Ok))
button->setIcon(QIcon{":/qtgameengine/icons/ok.png"});
if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Cancel))
button->setIcon(QIcon{":/qtgameengine/icons/delete.png"});
m_ui->listView->setModel(m_model.get());
connect(m_ui->pushButtonUseCodeEditor, &QAbstractButton::pressed,
this, &TriggersDialog::openCodeEditor);
}
TriggersDialog::~TriggersDialog() = default;
void TriggersDialog::openCodeEditor()
{
TriggerConditionDialog dialog{this};
dialog.exec();
}

28
dialogs/triggersdialog.h Normal file
View File

@ -0,0 +1,28 @@
#pragma once
#include <QDialog>
#include <memory>
namespace Ui { class TriggersDialog; }
struct ProjectContainer;
class TriggersModel;
class TriggersDialog : public QDialog
{
Q_OBJECT
public:
explicit TriggersDialog(ProjectContainer &project, QWidget *parent = nullptr);
~TriggersDialog();
private slots:
void openCodeEditor();
private:
const std::unique_ptr<Ui::TriggersDialog> m_ui;
ProjectContainer &m_project;
const std::unique_ptr<TriggersModel> m_model;
};

227
dialogs/triggersdialog.ui Normal file
View File

@ -0,0 +1,227 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TriggersDialog</class>
<widget class="QDialog" name="TriggersDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>622</width>
<height>515</height>
</rect>
</property>
<property name="windowTitle">
<string>Triggers</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListView" name="listView">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QPushButton" name="pushButtonLoad">
<property name="toolTip">
<string>Load the collection of triggers from a file.</string>
</property>
<property name="text">
<string>&amp;Load</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pushButtonDelete">
<property name="toolTip">
<string>Delete the selected trigger. Make sure no object uses it!</string>
</property>
<property name="text">
<string>&amp;Delete</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="pushButtonAdd">
<property name="toolTip">
<string>Add a trigger to the list</string>
</property>
<property name="text">
<string>&amp;Add</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="pushButtonClear">
<property name="toolTip">
<string>Clear the complete list of triggers</string>
</property>
<property name="text">
<string>&amp;Clear</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pushButtonSave">
<property name="toolTip">
<string>Save the collection of triggers to a file</string>
</property>
<property name="text">
<string>&amp;Save</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
<property name="centerButtons">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="enabled">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="labelName">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditName"/>
</item>
<item>
<widget class="QLabel" name="labelCondition">
<property name="text">
<string>Condition:</string>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="plainTextEdit"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<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>
<item>
<widget class="QPushButton" name="pushButtonUseCodeEditor">
<property name="text">
<string>&amp;Use code editor</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="labelMomentOfChecking">
<property name="text">
<string>Moment of checking:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QRadioButton" name="radioButtonBegin">
<property name="text">
<string>Begin of step</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonMiddle">
<property name="text">
<string>Middle of step</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonEnd">
<property name="text">
<string>End of step</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="labelConstantName">
<property name="text">
<string>Constant name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditConstantName"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>TriggersDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>93</x>
<y>492</y>
</hint>
<hint type="destinationlabel">
<x>310</x>
<y>257</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>TriggersDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>93</x>
<y>492</y>
</hint>
<hint type="destinationlabel">
<x>310</x>
<y>257</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,23 @@
#include "userdefinedconstantsdialog.h"
#include "ui_userdefinedconstantsdialog.h"
#include "projectcontainer.h"
#include "constantsmodel.h"
UserDefinedConstantsDialog::UserDefinedConstantsDialog(ProjectContainer &project, QWidget *parent) :
QDialog{parent},
m_ui{std::make_unique<Ui::UserDefinedConstantsDialog>()},
m_project{project},
m_model{std::make_unique<ConstantsModel>(m_project, this)}
{
m_ui->setupUi(this);
if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Ok))
button->setIcon(QIcon{":/qtgameengine/icons/ok.png"});
if (auto button = m_ui->buttonBox->button(QDialogButtonBox::Cancel))
button->setIcon(QIcon{":/qtgameengine/icons/delete.png"});
m_ui->treeView->setModel(m_model.get());
}
UserDefinedConstantsDialog::~UserDefinedConstantsDialog() = default;

View File

@ -0,0 +1,25 @@
#pragma once
#include <QDialog>
#include <memory>
namespace Ui { class UserDefinedConstantsDialog; }
struct ProjectContainer;
class ConstantsModel;
class UserDefinedConstantsDialog : public QDialog
{
Q_OBJECT
public:
explicit UserDefinedConstantsDialog(ProjectContainer &project, QWidget *parent = nullptr);
~UserDefinedConstantsDialog();
private:
const std::unique_ptr<Ui::UserDefinedConstantsDialog> m_ui;
ProjectContainer &m_project;
const std::unique_ptr<ConstantsModel> m_model;
};

View File

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UserDefinedConstantsDialog</class>
<widget class="QDialog" name="UserDefinedConstantsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>479</width>
<height>461</height>
</rect>
</property>
<property name="windowTitle">
<string>User-Defined Constants</string>
</property>
<property name="windowIcon">
<iconset resource="../resources.qrc">
<normaloff>:/qtgameengine/icons/constants.png</normaloff>:/qtgameengine/icons/constants.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,0">
<item>
<widget class="QGroupBox" name="groupBox">
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
<item>
<widget class="QTreeView" name="treeView">
<property name="rootIsDecorated">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QPushButton" name="pushButtonInsert">
<property name="text">
<string>&amp;Insert</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="pushButtonSort">
<property name="text">
<string>&amp;Sort</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pushButtonDelete">
<property name="text">
<string>&amp;Delete</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QPushButton" name="pushButtonLoad">
<property name="text">
<string>&amp;Load</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pushButtonUp">
<property name="text">
<string>&amp;Up</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pushButtonAdd">
<property name="text">
<string>&amp;Add</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pushButtonClear">
<property name="text">
<string>&amp;Clear</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pushButtonDown">
<property name="text">
<string>Do&amp;wn</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QPushButton" name="pushButtonSave">
<property name="text">
<string>Sa&amp;ve</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
<property name="centerButtons">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../resources.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>UserDefinedConstantsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>239</x>
<y>439</y>
</hint>
<hint type="destinationlabel">
<x>239</x>
<y>230</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>UserDefinedConstantsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>239</x>
<y>439</y>
</hint>
<hint type="destinationlabel">
<x>239</x>
<y>230</y>
</hint>
</hints>
</connection>
</connections>
</ui>

37
drawingcanvaswidget.cpp Normal file
View File

@ -0,0 +1,37 @@
#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)
{
QWidget::paintEvent(ev);
if (!m_pixmap)
return;
QPainter painter{this};
painter.drawPixmap(QRect{QPoint{}, m_pixmap->size() * m_scale}, *m_pixmap);
}

31
drawingcanvaswidget.h Normal file
View File

@ -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};
};

BIN
icons/center.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
icons/constants.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
icons/flip-horizontal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
icons/flip-vertical.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
icons/grid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
icons/scale.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

19
includedfilesmodel.cpp Normal file
View File

@ -0,0 +1,19 @@
#include "includedfilesmodel.h"
#include "projectcontainer.h"
IncludedFilesModel::IncludedFilesModel(ProjectContainer &project, QObject *parent) :
QAbstractListModel{parent},
m_project{project}
{
}
int IncludedFilesModel::rowCount(const QModelIndex &parent) const
{
return 0;
}
QVariant IncludedFilesModel::data(const QModelIndex &index, int role) const
{
return {};
}

19
includedfilesmodel.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include <QAbstractListModel>
struct ProjectContainer;
class IncludedFilesModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit IncludedFilesModel(ProjectContainer &project, QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
private:
ProjectContainer &m_project;
};

View File

@ -6,8 +6,10 @@
#include <QCloseEvent>
#include <QFileDialog>
#include <QInputDialog>
#include <QDebug>
#include "projecttreemodel.h"
#include "dialogs/preferencesdialog.h"
#include "dialogs/spritepropertiesdialog.h"
#include "dialogs/soundpropertiesdialog.h"
#include "dialogs/backgroundpropertiesdialog.h"
@ -17,11 +19,13 @@
#include "dialogs/timelinepropertiesdialog.h"
#include "dialogs/objectpropertiesdialog.h"
#include "dialogs/roompropertiesdialog.h"
#include "dialogs/preferencesdialog.h"
#include "dialogs/objectinformationdialog.h"
#include "dialogs/gameinformationdialog.h"
#include "dialogs/globalgamesettingsdialog.h"
#include "dialogs/extensionpackagesdialog.h"
#include "dialogs/objectinformationdialog.h"
#include "dialogs/userdefinedconstantsdialog.h"
#include "dialogs/triggersdialog.h"
#include "dialogs/includedfilesdialog.h"
namespace {
template<typename T> struct PropertiesDialogForDetail;
@ -107,6 +111,9 @@ MainWindow::MainWindow(QWidget *parent) :
connect(m_ui->actionGameInformation, &QAction::triggered, this, &MainWindow::showGameInformation);
connect(m_ui->actionGlobalGameSettings, &QAction::triggered, this, &MainWindow::showGlobalGameSettings);
connect(m_ui->actionExtensionPackages, &QAction::triggered, this, &MainWindow::showExtensionPackages);
connect(m_ui->actionDefineConstants, &QAction::triggered, this, &MainWindow::showDefineConstants);
connect(m_ui->actionDefineTriggers, &QAction::triggered, this, &MainWindow::showDefineTriggers);
connect(m_ui->actionIncludedFiles, &QAction::triggered, this, &MainWindow::showIncludedFiles);
connect(m_ui->actionAbout, &QAction::triggered, this, &MainWindow::about);
connect(m_ui->actionAboutQt, &QAction::triggered, qApp, &QApplication::aboutQt);
@ -126,10 +133,16 @@ MainWindow::MainWindow(QWidget *parent) :
connect(m_projectTreeModel.get(), &ProjectTreeModel::rowsInserted,
this, &MainWindow::rowsInserted);
connect(m_projectTreeModel.get(), &QAbstractTableModel::rowsInserted,
this, &MainWindow::changed);
connect(m_projectTreeModel.get(), &ProjectTreeModel::rowsAboutToBeRemoved,
this, &MainWindow::rowsAboutToBeRemoved);
connect(m_projectTreeModel.get(), &QAbstractTableModel::rowsRemoved,
this, &MainWindow::changed);
connect(m_projectTreeModel.get(), &ProjectTreeModel::modelAboutToBeReset,
this, &MainWindow::modelAboutToBeReset);
connect(m_projectTreeModel.get(), &QAbstractTableModel::dataChanged,
this, &MainWindow::changed);
updateTitle();
}
@ -318,6 +331,15 @@ void MainWindow::modelErrorOccured(const QString &message)
QMessageBox::warning(this, tr("Error occured!"), tr("Error occured!") + "\n\n" + message);
}
void MainWindow::changed()
{
if (!m_unsavedChanges)
{
m_unsavedChanges = true;
updateTitle();
}
}
void MainWindow::newFile()
{
m_ui->mdiArea->closeAllSubWindows();
@ -354,7 +376,7 @@ void MainWindow::newFile()
m_project = {};
m_projectTreeModel->setProject(&m_project);
m_filePath = {};
m_filePath = QString{};
m_unsavedChanges = false;
updateTitle();
@ -492,7 +514,8 @@ void MainWindow::exportResources()
void MainWindow::preferences()
{
PreferencesDialog{this}.exec();
PreferencesDialog dialog{this};
dialog.exec();
}
void MainWindow::create()
@ -501,7 +524,7 @@ void MainWindow::create()
if (!index.isValid())
return;
if (index == m_projectTreeModel->rootFor<Sprite>()) createFor<Sprite>();
if (index == m_projectTreeModel->rootFor<Sprite>()) createFor<Sprite>();
else if (index == m_projectTreeModel->rootFor<Sound>()) createFor<Sound>();
else if (index == m_projectTreeModel->rootFor<Background>()) createFor<Background>();
else if (index == m_projectTreeModel->rootFor<Path>()) createFor<Path>();
@ -583,35 +606,7 @@ void MainWindow::findResource()
void MainWindow::showObjectInformation()
{
if (m_objectInformationWindow)
m_ui->mdiArea->setActiveSubWindow(m_objectInformationWindow);
else
{
auto dialog = new ObjectInformationDialog;
auto subwindow = m_ui->mdiArea->addSubWindow(dialog);
auto action = m_ui->menuWindow->addAction(dialog->windowTitle());
action->setCheckable(true);
connect(action, &QAction::triggered,
m_ui->mdiArea, [mdiArea=m_ui->mdiArea,subwindow,action](){
mdiArea->setActiveSubWindow(subwindow);
action->setChecked(subwindow->windowState().testFlag(Qt::WindowActive));
});
connect(subwindow, &QMdiSubWindow::windowStateChanged,
action, [action](Qt::WindowStates oldState, Qt::WindowStates newState){
action->setChecked(newState.testFlag(Qt::WindowActive));
});
connect(dialog, &QWidget::windowTitleChanged, action, &QAction::setText);
connect(dialog, &QDialog::finished,
this, [&objectInformationWindow=m_objectInformationWindow](){
objectInformationWindow = nullptr;
});
connect(dialog, &QDialog::finished,
subwindow, &QObject::deleteLater);
connect(dialog, &QDialog::finished,
action, &QObject::deleteLater);
m_objectInformationWindow = subwindow;
dialog->show();
}
openOrActivateWindow<ObjectInformationDialog>(m_objectInformationWindow, m_project);
}
template<typename T>
@ -633,17 +628,37 @@ template void MainWindow::createFor<Room>();
void MainWindow::showGameInformation()
{
GameInformationDialog{this}.exec();
GameInformationDialog dialog{this};
if (dialog.exec() == QDialog::Accepted)
changed();
}
void MainWindow::showGlobalGameSettings()
{
GlobalGameSettingsDialog{this}.exec();
GlobalGameSettingsDialog dialog{this};
if (dialog.exec() == QDialog::Accepted)
changed();
}
void MainWindow::showExtensionPackages()
{
ExtensionPackagesDialog{this}.exec();
ExtensionPackagesDialog dialog{this};
dialog.exec();
}
void MainWindow::showDefineConstants()
{
openOrActivateWindow<UserDefinedConstantsDialog>(m_userDefinedConstantsWindow, m_project);
}
void MainWindow::showDefineTriggers()
{
openOrActivateWindow<TriggersDialog>(m_triggersWindow, m_project);
}
void MainWindow::showIncludedFiles()
{
openOrActivateWindow<IncludedFilesDialog>(m_includedFilesWindow, m_project);
}
void MainWindow::about()
@ -688,11 +703,45 @@ void MainWindow::modelAboutToBeReset()
void MainWindow::updateTitle()
{
setWindowTitle(tr("%0 - Qt Gamemaker 1.0 Ultimate%1")
setWindowTitle(tr("%0%1 - Qt Gamemaker 1.0 Ultimate")
.arg(m_filePath.isEmpty() ? "<new-game>" : QFileInfo{m_filePath}.fileName())
.arg(m_unsavedChanges ? tr("*") : QString{}));
}
template<typename T, typename ...Targs>
void MainWindow::openOrActivateWindow(QMdiSubWindow * &ptr, Targs &&...args)
{
if (ptr)
m_ui->mdiArea->setActiveSubWindow(ptr);
else
{
auto dialog = new T{std::forward<Targs>(args)...};
auto subwindow = m_ui->mdiArea->addSubWindow(dialog);
auto action = m_ui->menuWindow->addAction(dialog->windowTitle());
action->setCheckable(true);
connect(action, &QAction::triggered,
m_ui->mdiArea, [mdiArea=m_ui->mdiArea,subwindow,action](){
mdiArea->setActiveSubWindow(subwindow);
action->setChecked(subwindow->windowState().testFlag(Qt::WindowActive));
});
connect(subwindow, &QMdiSubWindow::windowStateChanged,
action, [action](Qt::WindowStates oldState, Qt::WindowStates newState){
action->setChecked(newState.testFlag(Qt::WindowActive));
});
connect(dialog, &QWidget::windowTitleChanged, action, &QAction::setText);
connect(dialog, &QDialog::finished,
this, [&ptr](){
ptr = nullptr;
});
connect(dialog, &QDialog::finished,
subwindow, &QObject::deleteLater);
connect(dialog, &QDialog::finished,
action, &QObject::deleteLater);
ptr = subwindow;
dialog->show();
}
}
template<typename T>
bool MainWindow::doubleClickedFor(const QModelIndex &index)
{
@ -725,7 +774,9 @@ bool MainWindow::doubleClickedFor(const QModelIndex &index)
});
connect(dialog, &QWidget::windowTitleChanged, action, &QAction::setText);
connect(dialog, &QDialog::finished,
this, [&propertyWindows,subwindow](){
this, [this,&propertyWindows,subwindow](int result){
if (result == QDialog::Accepted)
changed();
for (auto iter = std::begin(propertyWindows); iter != std::end(propertyWindows); )
{
if (iter->second == subwindow)

View File

@ -27,6 +27,7 @@ private slots:
void doubleClicked(const QModelIndex &index);
void selectionChanged(const QModelIndex &index);
void modelErrorOccured(const QString &message);
void changed();
void newFile();
void openFile();
@ -50,18 +51,12 @@ private:
template<typename T>
void createFor();
private slots:
// void createSprite();
// void createSound();
// void createBackground();
// void createPath();
// void createScript();
// void createFont();
// void createTimeLine();
// void createObject();
// void createRoom();
void showGameInformation();
void showGlobalGameSettings();
void showExtensionPackages();
void showDefineConstants();
void showDefineTriggers();
void showIncludedFiles();
void about();
void rowsInserted(const QModelIndex &parent, int first, int last);
@ -71,6 +66,9 @@ private slots:
private:
void updateTitle();
template<typename T, typename ...Targs>
void openOrActivateWindow(QMdiSubWindow * &ptr, Targs &&...args);
template<typename T>
std::map<T*, QMdiSubWindow*> &propertyWindowsFor();
@ -103,4 +101,7 @@ private:
std::map<Room*, QMdiSubWindow*> m_roomPropertiesWindows;
QMdiSubWindow *m_objectInformationWindow{};
QMdiSubWindow *m_userDefinedConstantsWindow{};
QMdiSubWindow *m_triggersWindow{};
QMdiSubWindow *m_includedFilesWindow{};
};

View File

@ -459,6 +459,10 @@
</property>
</action>
<action name="actionShowObjectInformation">
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/qtgameengine/icons/object-file.png</normaloff>:/qtgameengine/icons/object-file.png</iconset>
</property>
<property name="text">
<string>&amp;Show Object Information</string>
</property>
@ -608,6 +612,10 @@
</property>
</action>
<action name="actionDefineConstants">
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/qtgameengine/icons/constants.png</normaloff>:/qtgameengine/icons/constants.png</iconset>
</property>
<property name="text">
<string>Define Co&amp;nstants...</string>
</property>

100
pathpointsmodel.cpp Normal file
View File

@ -0,0 +1,100 @@
#include "pathpointsmodel.h"
#include <QDebug>
namespace {
enum {
ColumnPoint,
ColumnSp,
NumberOfColumns
};
}
PathPointsModel::PathPointsModel(std::vector<Path::Point> &points, QObject *parent) :
QAbstractTableModel{parent},
m_points{points}
{
}
int PathPointsModel::rowCount(const QModelIndex &parent) const
{
return m_points.size();
}
int PathPointsModel::columnCount(const QModelIndex &parent) const
{
return NumberOfColumns;
}
QVariant PathPointsModel::data(const QModelIndex &index, int role) const
{
if (index.row() < 0 || index.row() >= m_points.size())
{
qWarning() << "invalid row" << index.row();
return {};
}
const auto &point = m_points.at(index.row());
switch (index.column())
{
case ColumnPoint:
switch (role)
{
case Qt::DisplayRole: return tr("(%0,%1)").arg(point.point.x()).arg(point.point.y());
case Qt::EditRole: return point.point;
default: return {};
}
case ColumnSp:
switch (role)
{
case Qt::DisplayRole:
case Qt::EditRole: return point.sp;
default: return {};
}
}
return {};
}
QVariant PathPointsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation != Qt::Horizontal || (role != Qt::DisplayRole && role != Qt::EditRole))
return {};
switch (section)
{
case ColumnPoint: return tr("point");
case ColumnSp: return tr("sp");
}
return {};
}
Path::Point PathPointsModel::getPoint(const QModelIndex &index) const
{
if (!index.isValid())
{
qWarning() << "unexpected invalid index" << index;
return {};
}
if (index.row() < 0 || index.row() >= m_points.size())
{
qWarning() << "unexpected row" << index.row();
return {};
}
return m_points.at(index.row());
}
void PathPointsModel::pointInserted(std::size_t index)
{
emit beginInsertRows({}, index, index);
emit endInsertRows();
}
void PathPointsModel::pointMoved(std::size_t index)
{
emit dataChanged(this->index(index, 0), this->index(index, 0), {Qt::DisplayRole, Qt::EditRole});
}

29
pathpointsmodel.h Normal file
View File

@ -0,0 +1,29 @@
#pragma once
#include <QAbstractTableModel>
#include <vector>
#include "projectcontainer.h"
class PathPointsModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit PathPointsModel(std::vector<Path::Point> &points, QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
Path::Point getPoint(const QModelIndex &index) const;
public slots:
void pointInserted(std::size_t index);
void pointMoved(std::size_t index);
private:
std::vector<Path::Point> &m_points;
};

223
pathpointswidget.cpp Normal file
View File

@ -0,0 +1,223 @@
#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)
{
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()));
}
qDebug() << "setup brush" << pixmap.width() << pixmap.height();
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;
}
}
void PathPointsWidget::mouseReleaseEvent(QMouseEvent *event)
{
QWidget::mouseReleaseEvent(event);
switch (event->button())
{
case Qt::LeftButton:
m_dragIndex = std::nullopt;
break;
}
}
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,
};
}

84
pathpointswidget.h Normal file
View File

@ -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};
};

View File

@ -143,15 +143,37 @@ QDataStream &operator>>(QDataStream &ds, Background &background)
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Path::Point &point)
{
ds << point.point;
ds << point.sp;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Path::Point &point)
{
ds >> point.point;
ds >> point.sp;
return ds;
}
QDataStream &operator<<(QDataStream &ds, const Path &path)
{
ds << path.name;
ds << path.points;
ds << path.type;
ds << path.closed;
ds << path.precision;
return ds;
}
QDataStream &operator>>(QDataStream &ds, Path &path)
{
ds >> path.name;
ds >> path.points;
ds >> path.type;
ds >> path.closed;
ds >> path.precision;
return ds;
}

View File

@ -7,6 +7,7 @@
#include <QPixmap>
#include <QFont>
#include <QDataStream>
#include <QPoint>
struct Sprite
{
@ -49,6 +50,15 @@ struct Background
struct Path
{
QString name;
struct Point {
QPoint point;
int sp{100};
};
std::vector<Point> points;
enum class Type { Straight, Smooth };
Type type{Type::Straight};
bool closed{true};
int precision{4};
};
struct Script
@ -98,23 +108,5 @@ struct ProjectContainer
template<typename T> const std::list<T> &containerFor() const;
};
QDataStream &operator<<(QDataStream &ds, const Sprite &sprite);
QDataStream &operator>>(QDataStream &ds, Sprite &sprite);
QDataStream &operator<<(QDataStream &ds, const Sound &sound);
QDataStream &operator>>(QDataStream &ds, Sound &sound);
QDataStream &operator<<(QDataStream &ds, const Background &background);
QDataStream &operator>>(QDataStream &ds, Background &background);
QDataStream &operator<<(QDataStream &ds, const Path &path);
QDataStream &operator>>(QDataStream &ds, Path &path);
QDataStream &operator<<(QDataStream &ds, const Script &script);
QDataStream &operator>>(QDataStream &ds, Script &script);
QDataStream &operator<<(QDataStream &ds, const Font &font);
QDataStream &operator>>(QDataStream &ds, Font &font);
QDataStream &operator<<(QDataStream &ds, const TimeLine &timeLine);
QDataStream &operator>>(QDataStream &ds, TimeLine &timeLine);
QDataStream &operator<<(QDataStream &ds, const Object &object);
QDataStream &operator>>(QDataStream &ds, Object &object);
QDataStream &operator<<(QDataStream &ds, const Room &room);
QDataStream &operator>>(QDataStream &ds, Room &room);
QDataStream &operator<<(QDataStream &ds, const ProjectContainer &project);
QDataStream &operator>>(QDataStream &ds, ProjectContainer &project);

View File

@ -6,7 +6,7 @@
#include <utility>
#include <algorithm>
#include "futurecpp.h"
//#include "futurecpp.h"
#include "projectcontainer.h"
namespace {

View File

@ -65,5 +65,11 @@
<file>icons/object-file.png</file>
<file>icons/room-file.png</file>
<file>icons/timeline-file.png</file>
<file>icons/flip-horizontal.png</file>
<file>icons/flip-vertical.png</file>
<file>icons/scale.png</file>
<file>icons/center.png</file>
<file>icons/grid.png</file>
<file>icons/constants.png</file>
</qresource>
</RCC>

View File

@ -1,29 +1,53 @@
#include "spritesmodel.h"
#include <QPixmap>
#include <QDebug>
SpritesModel::SpritesModel(QObject *parent)
: QAbstractListModel{parent}
SpritesModel::SpritesModel(const std::vector<QPixmap> &pixmaps, QObject *parent) :
QAbstractListModel{parent},
m_pixmaps{pixmaps}
{
}
int SpritesModel::rowCount(const QModelIndex &parent) const
{
return 100;
return m_pixmaps.size();
}
QVariant SpritesModel::data(const QModelIndex &index, int role) const
{
if (index.column() != 0)
return {};
switch (role)
{
case Qt::DisplayRole:
case Qt::EditRole:
return tr("image %0").arg(index.row());
case Qt::DecorationRole:
QPixmap pixmap{64, 64};
pixmap.fill(Qt::black);
if (index.row() < 0 || index.row() >= m_pixmaps.size())
{
qWarning() << "invalid row" << index.row();
return {};
}
const auto &pixmap = m_pixmaps.at(index.row());
if (pixmap.isNull())
{
QPixmap pixmap{32, 32};
pixmap.fill(Qt::white);
return pixmap;
}
return pixmap;
}
return {};
}
const QPixmap &SpritesModel::pixmap(const QModelIndex &index) const
{
if (index.row() < 0 || index.row() >= m_pixmaps.size())
qFatal("index out of range");
return m_pixmaps.at(index.row());
}

View File

@ -1,14 +1,25 @@
#pragma once
#include <QAbstractListModel>
#include <QPixmap>
#include <vector>
class SpritesModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit SpritesModel(QObject *parent = nullptr);
explicit SpritesModel(const std::vector<QPixmap> &pixmaps, QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
const QPixmap &pixmap(const QModelIndex &index) const;
using QAbstractListModel::beginResetModel;
using QAbstractListModel::endResetModel;
private:
const std::vector<QPixmap> &m_pixmaps;
};

19
triggersmodel.cpp Normal file
View File

@ -0,0 +1,19 @@
#include "triggersmodel.h"
#include "projectcontainer.h"
TriggersModel::TriggersModel(ProjectContainer &project, QObject *parent) :
QAbstractListModel{parent},
m_project{project}
{
}
int TriggersModel::rowCount(const QModelIndex &parent) const
{
return 0;
}
QVariant TriggersModel::data(const QModelIndex &index, int role) const
{
return {};
}

19
triggersmodel.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include <QAbstractListModel>
struct ProjectContainer;
class TriggersModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit TriggersModel(ProjectContainer &project, QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
private:
ProjectContainer &m_project;
};