Huge cleanups and added open gl window
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
#include "addeventdialog.h"
|
||||
#include "ui_addeventdialog.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
AddEventDialog::AddEventDialog(QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::AddEventDialog>()}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
#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"});
|
||||
|
||||
connect(m_ui->pushButtonCreate, &QAbstractButton::clicked,
|
||||
this, [this](){ m_eventType = Object::EventType::Create; accept(); });
|
||||
connect(m_ui->pushButtonDestroy, &QAbstractButton::clicked,
|
||||
this, [this](){ m_eventType = Object::EventType::Destroy; accept(); });
|
||||
connect(m_ui->pushButtonDraw, &QAbstractButton::clicked,
|
||||
this, [this](){ m_eventType = Object::EventType::Draw; accept(); });
|
||||
connect(m_ui->pushButtonStep, &QAbstractButton::clicked,
|
||||
this, [this](){ m_eventType = Object::EventType::Step; accept(); });
|
||||
}
|
||||
|
||||
AddEventDialog::~AddEventDialog() = default;
|
||||
|
||||
void AddEventDialog::accept()
|
||||
{
|
||||
if (!m_eventType)
|
||||
{
|
||||
QMessageBox::warning(this, tr("No Event selected!"), tr("No Event selected!"));
|
||||
return;
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void AddEventDialog::reject()
|
||||
{
|
||||
m_eventType = std::nullopt;
|
||||
|
||||
QDialog::reject();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
|
||||
namespace Ui { class AddEventDialog; }
|
||||
|
||||
class AddEventDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AddEventDialog(QWidget *parent = nullptr);
|
||||
~AddEventDialog();
|
||||
|
||||
Object::EventType eventType() const { return *m_eventType; }
|
||||
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Ui::AddEventDialog> m_ui;
|
||||
|
||||
std::optional<Object::EventType> m_eventType;
|
||||
};
|
||||
@@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AddEventDialog</class>
|
||||
<widget class="QDialog" name="AddEventDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>265</width>
|
||||
<height>221</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Choose the Event to Add</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="pushButtonDraw">
|
||||
<property name="text">
|
||||
<string>Dra&w</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/event-draw.png</normaloff>:/qtgameengine/icons/event-draw.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pushButtonMouse">
|
||||
<property name="text">
|
||||
<string>&Mouse</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QPushButton" name="pushButtonKeyRelease">
|
||||
<property name="text">
|
||||
<string>Ke&y Release</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="pushButtonAlarm">
|
||||
<property name="text">
|
||||
<string>&Alarm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QPushButton" name="pushButtonStep">
|
||||
<property name="text">
|
||||
<string>&Step</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/event-step.png</normaloff>:/qtgameengine/icons/event-step.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="pushButtonCreate">
|
||||
<property name="text">
|
||||
<string>C&reate</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/event-create.png</normaloff>:/qtgameengine/icons/event-create.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="pushButtonOther">
|
||||
<property name="text">
|
||||
<string>O&ther</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QPushButton" name="pushButtonCollision">
|
||||
<property name="text">
|
||||
<string>C&ollision</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pushButtonDestroy">
|
||||
<property name="text">
|
||||
<string>&Destroy</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/event-destroy.png</normaloff>:/qtgameengine/icons/event-destroy.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QPushButton" name="pushButtonKeyPress">
|
||||
<property name="text">
|
||||
<string>Key &Press</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QPushButton" name="pushButtonKeyboard">
|
||||
<property name="text">
|
||||
<string>&Keyboard</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QPushButton" name="pushButtonTrigger">
|
||||
<property name="text">
|
||||
<string>&Trigger</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel</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>AddEventDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>132</x>
|
||||
<y>196</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>132</x>
|
||||
<y>108</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>AddEventDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>132</x>
|
||||
<y>196</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>132</x>
|
||||
<y>108</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,205 @@
|
||||
#include "backgroundpropertiesdialog.h"
|
||||
#include "ui_backgroundpropertiesdialog.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
#include "models/projecttreemodel.h"
|
||||
#include "imageeditordialog.h"
|
||||
|
||||
BackgroundPropertiesDialog::BackgroundPropertiesDialog(Background &background, ProjectTreeModel &projectModel, QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::BackgroundPropertiesDialog>()},
|
||||
m_background{background},
|
||||
m_projectModel{projectModel},
|
||||
m_pixmap{m_background.pixmap}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
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"});
|
||||
|
||||
m_ui->lineEditName->setText(m_background.name);
|
||||
updateSpriteInfo();
|
||||
m_ui->checkBoxTileset->setChecked(m_background.tileset);
|
||||
|
||||
connect(&m_projectModel, &ProjectTreeModel::backgroundNameChanged,
|
||||
this, &BackgroundPropertiesDialog::backgroundNameChanged);
|
||||
|
||||
connect(m_ui->pushButtonLoad, &QAbstractButton::clicked,
|
||||
this, &BackgroundPropertiesDialog::loadBackground);
|
||||
connect(m_ui->pushButtonSave, &QAbstractButton::clicked,
|
||||
this, &BackgroundPropertiesDialog::saveBackground);
|
||||
connect(m_ui->pushButtonEdit, &QAbstractButton::clicked,
|
||||
this, &BackgroundPropertiesDialog::editBackground);
|
||||
|
||||
connect(m_ui->lineEditName, &QLineEdit::textChanged,
|
||||
this, &BackgroundPropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxTileset, &QCheckBox::stateChanged,
|
||||
this, &BackgroundPropertiesDialog::changed);
|
||||
}
|
||||
|
||||
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()))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Renaming Background failed!"), tr("Renaming Background failed!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_projectModel.setBackgroundPixmap(m_background, std::move(m_pixmap)))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Setting Background pixmap failed!"), tr("Setting Background pixmap failed!"));
|
||||
return;
|
||||
}
|
||||
|
||||
m_background.tileset = m_ui->checkBoxTileset->isChecked();
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void BackgroundPropertiesDialog::reject()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto result = QMessageBox::warning(
|
||||
this,
|
||||
tr("The Background 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 BackgroundPropertiesDialog::loadBackground()
|
||||
{
|
||||
const auto path = QFileDialog::getOpenFileName(this, tr("Open a Background Image..."), {},
|
||||
QStringLiteral("%0 (*.png);;%1 (*.bmp);;%2 (*.tiff);;%3 (*.jpg *.jpeg);;%4 (*)")
|
||||
.arg(tr("PNG Files"))
|
||||
.arg(tr("BMP Files"))
|
||||
.arg(tr("TIFF Files"))
|
||||
.arg(tr("JPEG Files"))
|
||||
.arg(tr("All Files"))
|
||||
);
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
QPixmap pixmap;
|
||||
if (!pixmap.load(path))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Could not load sprite!"), tr("Could not load sprite!"));
|
||||
return;
|
||||
}
|
||||
|
||||
m_pixmap = std::move(pixmap);
|
||||
changed();
|
||||
updateSpriteInfo();
|
||||
}
|
||||
|
||||
void BackgroundPropertiesDialog::saveBackground()
|
||||
{
|
||||
if (m_pixmap.isNull())
|
||||
{
|
||||
QMessageBox::warning(this, tr("No background available to save!"), tr("No background available to save!"));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto path = QFileDialog::getSaveFileName(this, tr("Save a Background Image..."), m_background.name + ".png",
|
||||
QStringLiteral("%0 (*.png);;%1 (*.bmp);;%2 (*.tiff);;%3 (*.jpg *.jpeg);;%4 (*)")
|
||||
.arg(tr("PNG Files"))
|
||||
.arg(tr("BMP Files"))
|
||||
.arg(tr("TIFF Files"))
|
||||
.arg(tr("JPEG Files"))
|
||||
.arg(tr("All Files"))
|
||||
);
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
if (!m_pixmap.save(path))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Could not save Background!"), tr("Could not save Background!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void BackgroundPropertiesDialog::editBackground()
|
||||
{
|
||||
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()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
m_unsavedChanges = true;
|
||||
updateTitle();
|
||||
}
|
||||
}
|
||||
|
||||
void BackgroundPropertiesDialog::backgroundNameChanged(const Background &background)
|
||||
{
|
||||
if (&background != &m_background)
|
||||
return;
|
||||
|
||||
{
|
||||
QSignalBlocker blocker{m_ui->lineEditName};
|
||||
m_ui->lineEditName->setText(background.name);
|
||||
}
|
||||
|
||||
updateTitle();
|
||||
}
|
||||
|
||||
void BackgroundPropertiesDialog::updateTitle()
|
||||
{
|
||||
setWindowTitle(tr("Background Properties: %0%1")
|
||||
.arg(m_background.name)
|
||||
.arg(m_unsavedChanges ? tr("*") : QString{})
|
||||
);
|
||||
}
|
||||
|
||||
void BackgroundPropertiesDialog::updateSpriteInfo()
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class BackgroundPropertiesDialog; }
|
||||
struct Background;
|
||||
class ProjectTreeModel;
|
||||
|
||||
class BackgroundPropertiesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BackgroundPropertiesDialog(Background &background, ProjectTreeModel &projectModel, QWidget *parent = nullptr);
|
||||
~BackgroundPropertiesDialog();
|
||||
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
|
||||
private slots:
|
||||
void loadBackground();
|
||||
void saveBackground();
|
||||
void editBackground();
|
||||
|
||||
void changed();
|
||||
|
||||
void backgroundNameChanged(const Background &background);
|
||||
|
||||
private:
|
||||
void updateTitle();
|
||||
void updateSpriteInfo();
|
||||
|
||||
const std::unique_ptr<Ui::BackgroundPropertiesDialog> m_ui;
|
||||
|
||||
Background &m_background;
|
||||
ProjectTreeModel &m_projectModel;
|
||||
|
||||
bool m_unsavedChanges{};
|
||||
|
||||
QPixmap m_pixmap;
|
||||
};
|
||||
@@ -0,0 +1,217 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BackgroundPropertiesDialog</class>
|
||||
<widget class="QDialog" name="BackgroundPropertiesDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>597</width>
|
||||
<height>295</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/background-file.png</normaloff>:/qtgameengine/icons/background-file.png</iconset>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelName">
|
||||
<property name="text">
|
||||
<string>&Name:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditName</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEditName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The name of the background</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonLoad">
|
||||
<property name="toolTip">
|
||||
<string>Load the background from a file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Load Background</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/open.png</normaloff>:/qtgameengine/icons/open.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonSave">
|
||||
<property name="toolTip">
|
||||
<string>Save the background to a file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Save Background</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/save.png</normaloff>:/qtgameengine/icons/save.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonEdit">
|
||||
<property name="toolTip">
|
||||
<string>Edit the background image</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Edit Background</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/edit.png</normaloff>:/qtgameengine/icons/edit.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelWidth">
|
||||
<property name="text">
|
||||
<string>Width:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelHeight">
|
||||
<property name="text">
|
||||
<string>Height:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</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>&Use as tile set</string>
|
||||
</property>
|
||||
</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>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QLabel" name="labelPreview">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>396</width>
|
||||
<height>275</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>BackgroundPropertiesDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>96</x>
|
||||
<y>272</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>298</x>
|
||||
<y>147</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>BackgroundPropertiesDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>96</x>
|
||||
<y>272</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>298</x>
|
||||
<y>147</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,63 @@
|
||||
#include "codeactiondialog.h"
|
||||
|
||||
#include <QRadioButton>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
|
||||
CodeActionDialog::CodeActionDialog(Action &action, QWidget *parent) :
|
||||
CodeEditorDialog{tr("Execute Code"), parent},
|
||||
m_action{action},
|
||||
m_radioButtonSelf{new QRadioButton{tr("Self"), this}},
|
||||
m_radioButtonOther{new QRadioButton{tr("Other"), this}},
|
||||
m_radioButtonObject{new QRadioButton{tr("Object"), this}}
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
setWindowFlags((windowFlags() & ~Qt::Dialog) | Qt::Window);
|
||||
#endif
|
||||
setWindowFlag(Qt::WindowCloseButtonHint);
|
||||
|
||||
addToolbarWidget(new QLabel{tr("Applies to:"), this});
|
||||
addToolbarWidget(m_radioButtonSelf);
|
||||
addToolbarWidget(m_radioButtonOther);
|
||||
addToolbarWidget(m_radioButtonObject);
|
||||
|
||||
m_radioButtonSelf->setChecked(m_action.appliesTo == Action::AppliesTo::Self);
|
||||
m_radioButtonOther->setChecked(m_action.appliesTo == Action::AppliesTo::Other);
|
||||
m_radioButtonObject->setChecked(m_action.appliesTo == Action::AppliesTo::Object);
|
||||
|
||||
setScript(m_action.script);
|
||||
|
||||
connect(m_radioButtonSelf, &QRadioButton::toggled,
|
||||
this, &CodeActionDialog::changed);
|
||||
connect(m_radioButtonOther, &QRadioButton::toggled,
|
||||
this, &CodeActionDialog::changed);
|
||||
connect(m_radioButtonObject, &QRadioButton::toggled,
|
||||
this, &CodeActionDialog::changed);
|
||||
}
|
||||
|
||||
void CodeActionDialog::accept()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_radioButtonSelf->isChecked())
|
||||
m_action.appliesTo = Action::AppliesTo::Self;
|
||||
else if (m_radioButtonOther->isChecked())
|
||||
m_action.appliesTo = Action::AppliesTo::Other;
|
||||
else if (m_radioButtonObject->isChecked())
|
||||
m_action.appliesTo = Action::AppliesTo::Object;
|
||||
else
|
||||
{
|
||||
QMessageBox::warning(this, tr("No Applies To selected!"), tr("No Applies To selected!"));
|
||||
return;
|
||||
}
|
||||
|
||||
m_action.script = script();
|
||||
|
||||
CodeEditorDialog::accept();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "codeeditordialog.h"
|
||||
|
||||
class QRadioButton;
|
||||
struct Action;
|
||||
|
||||
class CodeActionDialog : public CodeEditorDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CodeActionDialog(Action &action, QWidget *parent = nullptr);
|
||||
|
||||
void accept() override;
|
||||
|
||||
private:
|
||||
Action &m_action;
|
||||
|
||||
QRadioButton * const m_radioButtonSelf;
|
||||
QRadioButton * const m_radioButtonOther;
|
||||
QRadioButton * const m_radioButtonObject;
|
||||
};
|
||||
@@ -0,0 +1,195 @@
|
||||
#include "codeeditordialog.h"
|
||||
#include "ui_codeeditordialog.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFont>
|
||||
#include <QLabel>
|
||||
#include <QTextBlock>
|
||||
#include <QMessageBox>
|
||||
#include <QSignalBlocker>
|
||||
#include <QFileDialog>
|
||||
#include <QFile>
|
||||
|
||||
#include "jshighlighter.h"
|
||||
|
||||
CodeEditorDialog::CodeEditorDialog(const QString &title, QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::CodeEditorDialog>()},
|
||||
m_title{title},
|
||||
m_labelPosition{new QLabel{this}}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
updateTitle();
|
||||
|
||||
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::loadCode);
|
||||
connect(m_ui->actionSave, &QAction::triggered,
|
||||
this, &CodeEditorDialog::saveCode);
|
||||
connect(m_ui->actionPrint, &QAction::triggered,
|
||||
this, &CodeEditorDialog::printCode);
|
||||
|
||||
connect(m_ui->codeEdit, &QPlainTextEdit::textChanged,
|
||||
this, &CodeEditorDialog::changed);
|
||||
connect(m_ui->codeEdit, &QPlainTextEdit::textChanged,
|
||||
this, &CodeEditorDialog::updatePosition);
|
||||
connect(m_ui->codeEdit, &QPlainTextEdit::cursorPositionChanged,
|
||||
this, &CodeEditorDialog::updatePosition);
|
||||
}
|
||||
|
||||
CodeEditorDialog::~CodeEditorDialog() = default;
|
||||
|
||||
void CodeEditorDialog::accept()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void CodeEditorDialog::reject()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto result = QMessageBox::warning(
|
||||
this,
|
||||
tr("The Script 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;
|
||||
}
|
||||
}
|
||||
|
||||
QString CodeEditorDialog::script() const
|
||||
{
|
||||
return m_ui->codeEdit->toPlainText();
|
||||
}
|
||||
|
||||
void CodeEditorDialog::setScript(const QString &script)
|
||||
{
|
||||
QSignalBlocker blocker{m_ui->codeEdit};
|
||||
m_ui->codeEdit->setPlainText(script);
|
||||
}
|
||||
|
||||
void CodeEditorDialog::changed()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
m_unsavedChanges = true;
|
||||
updateTitle();
|
||||
}
|
||||
}
|
||||
|
||||
void CodeEditorDialog::addToolbarWidget(QWidget *widget)
|
||||
{
|
||||
m_ui->toolBar->addWidget(widget);
|
||||
}
|
||||
|
||||
void CodeEditorDialog::loadCode()
|
||||
{
|
||||
const auto path = QFileDialog::getOpenFileName(this, tr("Load Code from a Text File..."));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
QFile file{path};
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Could not open file!"), tr("Could not open file!") + "\n\n" + file.errorString());
|
||||
return;
|
||||
}
|
||||
|
||||
m_ui->codeEdit->setPlainText(QString::fromUtf8(file.readAll()));
|
||||
}
|
||||
|
||||
void CodeEditorDialog::saveCode()
|
||||
{
|
||||
const auto path = QFileDialog::getSaveFileName(this, tr("Save Code to a Text File..."));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
QFile file{path};
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Could not open file!"), tr("Could not open file!") + "\n\n" + file.errorString());
|
||||
return;
|
||||
}
|
||||
|
||||
auto asUtf8 = script().toUtf8();
|
||||
const auto size = asUtf8.size();
|
||||
if (const auto written = file.write(std::move(asUtf8)); written != size)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Could not write file!"), tr("Could not write file!") + "\n\n" + tr("written(%0) != size(%1)") + "\n\n" + file.errorString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CodeEditorDialog::printCode()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
void CodeEditorDialog::updateTitle()
|
||||
{
|
||||
setWindowTitle(tr("%0%1")
|
||||
.arg(m_title)
|
||||
.arg(m_unsavedChanges ? tr("*") : QString{})
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class QLabel;
|
||||
namespace Ui { class CodeEditorDialog; }
|
||||
|
||||
class CodeEditorDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CodeEditorDialog(const QString &title, QWidget *parent = nullptr);
|
||||
~CodeEditorDialog();
|
||||
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
|
||||
const QString &title() const { return m_title; }
|
||||
void setTitle(const QString &title) { if (m_title == title) return; m_title = title; updateTitle(); }
|
||||
|
||||
QString script() const;
|
||||
void setScript(const QString &script);
|
||||
|
||||
protected slots:
|
||||
void changed();
|
||||
|
||||
protected:
|
||||
bool m_unsavedChanges{};
|
||||
|
||||
void addToolbarWidget(QWidget *widget);
|
||||
|
||||
private slots:
|
||||
void loadCode();
|
||||
void saveCode();
|
||||
void printCode();
|
||||
|
||||
void updatePosition();
|
||||
|
||||
private:
|
||||
void updateTitle();
|
||||
|
||||
const std::unique_ptr<Ui::CodeEditorDialog> m_ui;
|
||||
|
||||
QString m_title;
|
||||
|
||||
QLabel * const m_labelPosition;
|
||||
};
|
||||
@@ -0,0 +1,571 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CodeEditorDialog</class>
|
||||
<widget class="QDialog" name="CodeEditorDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>540</width>
|
||||
<height>497</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Code Editor</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/script-file.png</normaloff>:/qtgameengine/icons/script-file.png</iconset>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<property name="movable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<addaction name="actionOk"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionLoad"/>
|
||||
<addaction name="actionSave"/>
|
||||
<addaction name="actionPrint"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionUndo"/>
|
||||
<addaction name="actionRedo"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCut"/>
|
||||
<addaction name="actionCopy"/>
|
||||
<addaction name="actionPaste"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionFind"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCheck"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
|
||||
<item>
|
||||
<layout class="QVBoxLayout">
|
||||
<item>
|
||||
<widget class="CodeEditorWidget" name="codeEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QStatusBar" name="statusbar">
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetSearch" native="true">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0,0">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxFind">
|
||||
<property name="title">
|
||||
<string>Find</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBoxFind">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxCaseSensitive">
|
||||
<property name="text">
|
||||
<string>Case Sensitive</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxWholeWord">
|
||||
<property name="text">
|
||||
<string>Whole word only</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pushButtonFindFirst">
|
||||
<property name="text">
|
||||
<string>First</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="pushButtonFindPrev">
|
||||
<property name="text">
|
||||
<string>Previous</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pushButtonFindNext">
|
||||
<property name="text">
|
||||
<string>Next</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="pushButtonFindLast">
|
||||
<property name="text">
|
||||
<string>Last</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxReplace">
|
||||
<property name="title">
|
||||
<string>Replace</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBoxReplace">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pushButtonReplaceFirst">
|
||||
<property name="text">
|
||||
<string>First</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="pushButtonReplacePrevious">
|
||||
<property name="text">
|
||||
<string>Previous</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pushButtonReplaceNext">
|
||||
<property name="text">
|
||||
<string>Next</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="pushButtonReplaceLast">
|
||||
<property name="text">
|
||||
<string>Last</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonReplaceAll">
|
||||
<property name="text">
|
||||
<string>Replace All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionOk">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/ok.png</normaloff>:/qtgameengine/icons/ok.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>OK</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>OK, Save Changes</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionLoad">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/open.png</normaloff>:/qtgameengine/icons/open.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Load the code from a text file</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/save.png</normaloff>:/qtgameengine/icons/save.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the code to a text file</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPrint">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/print.png</normaloff>:/qtgameengine/icons/print.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Print</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Print the code</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUndo">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/undo.png</normaloff>:/qtgameengine/icons/undo.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Undo</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Undo the last change</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRedo">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/redo.png</normaloff>:/qtgameengine/icons/redo.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Redo</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Redo the last undo</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCut">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/cut.png</normaloff>:/qtgameengine/icons/cut.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cut</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Cut the selected text into clipboard</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCopy">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/copy.png</normaloff>:/qtgameengine/icons/copy.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Copy</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Copy the selected text to the clipboard</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPaste">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/paste.png</normaloff>:/qtgameengine/icons/paste.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Paste</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Paste the text from the clipboard</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionFind">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/find.png</normaloff>:/qtgameengine/icons/find.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Find</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Show the find and replace panel</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCheck">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/check.png</normaloff>:/qtgameengine/icons/check.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Check</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Check the script for syntax errors</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>CodeEditorWidget</class>
|
||||
<extends>QPlainTextEdit</extends>
|
||||
<header>widgets/codeeditorwidget.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>actionOk</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>CodeEditorDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>269</x>
|
||||
<y>248</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionUndo</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>codeEdit</receiver>
|
||||
<slot>undo()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>269</x>
|
||||
<y>263</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionRedo</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>codeEdit</receiver>
|
||||
<slot>redo()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>269</x>
|
||||
<y>263</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>codeEdit</sender>
|
||||
<signal>undoAvailable(bool)</signal>
|
||||
<receiver>actionUndo</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>269</x>
|
||||
<y>263</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>codeEdit</sender>
|
||||
<signal>redoAvailable(bool)</signal>
|
||||
<receiver>actionRedo</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>269</x>
|
||||
<y>263</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionCut</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>codeEdit</receiver>
|
||||
<slot>cut()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>269</x>
|
||||
<y>263</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionCopy</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>codeEdit</receiver>
|
||||
<slot>copy()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>269</x>
|
||||
<y>263</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionPaste</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>codeEdit</receiver>
|
||||
<slot>paste()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>269</x>
|
||||
<y>263</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>codeEdit</sender>
|
||||
<signal>copyAvailable(bool)</signal>
|
||||
<receiver>actionCut</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>269</x>
|
||||
<y>263</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>codeEdit</sender>
|
||||
<signal>copyAvailable(bool)</signal>
|
||||
<receiver>actionCopy</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>269</x>
|
||||
<y>263</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionFind</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>widgetSearch</receiver>
|
||||
<slot>setVisible(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>499</x>
|
||||
<y>263</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "createspritedialog.h"
|
||||
#include "ui_createspritedialog.h"
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
CreateSpriteDialog::CreateSpriteDialog(QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::CreateSpriteDialog>()}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
#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"});
|
||||
}
|
||||
|
||||
CreateSpriteDialog::CreateSpriteDialog(const QSize &size, QWidget *parent) :
|
||||
CreateSpriteDialog{parent}
|
||||
{
|
||||
m_ui->spinBoxWidth->setValue(size.width());
|
||||
m_ui->spinBoxHeight->setValue(size.height());
|
||||
}
|
||||
|
||||
CreateSpriteDialog::~CreateSpriteDialog() = default;
|
||||
|
||||
QSize CreateSpriteDialog::spriteSize() const
|
||||
{
|
||||
return QSize{m_ui->spinBoxWidth->value(), m_ui->spinBoxHeight->value()};
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class CreateSpriteDialog; }
|
||||
|
||||
class CreateSpriteDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CreateSpriteDialog(QWidget *parent = nullptr);
|
||||
explicit CreateSpriteDialog(const QSize &size, QWidget *parent = nullptr);
|
||||
~CreateSpriteDialog();
|
||||
|
||||
QSize spriteSize() const;
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Ui::CreateSpriteDialog> m_ui;
|
||||
};
|
||||
@@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CreateSpriteDialog</class>
|
||||
<widget class="QDialog" name="CreateSpriteDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>283</width>
|
||||
<height>142</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Create a new sprite</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1">
|
||||
<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>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelWidth">
|
||||
<property name="text">
|
||||
<string>Width:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxWidth</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelHeight">
|
||||
<property name="text">
|
||||
<string>Height:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxHeight</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxWidth">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>16384</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>32</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxHeight">
|
||||
<property name="maximum">
|
||||
<number>16384</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>32</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>CreateSpriteDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>CreateSpriteDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,44 @@
|
||||
#include "deletemomentsdialog.h"
|
||||
#include "ui_deletemomentsdialog.h"
|
||||
|
||||
DeleteMomentsDialog::DeleteMomentsDialog(QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::DeleteMomentsDialog>()}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
}
|
||||
|
||||
DeleteMomentsDialog::DeleteMomentsDialog(int fromMoment, int tillMoment, QWidget *parent) :
|
||||
DeleteMomentsDialog{parent}
|
||||
{
|
||||
setFromMoment(fromMoment);
|
||||
setTillMoment(tillMoment);
|
||||
}
|
||||
|
||||
DeleteMomentsDialog::~DeleteMomentsDialog() = default;
|
||||
|
||||
int DeleteMomentsDialog::fromMoment() const
|
||||
{
|
||||
return m_ui->spinBoxFromMoment->value();
|
||||
}
|
||||
|
||||
void DeleteMomentsDialog::setFromMoment(int fromMoment)
|
||||
{
|
||||
m_ui->spinBoxFromMoment->setValue(fromMoment);
|
||||
}
|
||||
|
||||
int DeleteMomentsDialog::tillMoment() const
|
||||
{
|
||||
return m_ui->spinBoxTillMoment->value();
|
||||
}
|
||||
|
||||
void DeleteMomentsDialog::setTillMoment(int tillMoment)
|
||||
{
|
||||
m_ui->spinBoxTillMoment->setValue(tillMoment);
|
||||
}
|
||||
|
||||
void DeleteMomentsDialog::setFromTillMoment(int fromMoment, int tillMoment)
|
||||
{
|
||||
setFromMoment(fromMoment);
|
||||
setTillMoment(tillMoment);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class DeleteMomentsDialog; }
|
||||
|
||||
class DeleteMomentsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DeleteMomentsDialog(QWidget *parent = nullptr);
|
||||
explicit DeleteMomentsDialog(int fromMoment, int tillMoment, QWidget *parent = nullptr);
|
||||
~DeleteMomentsDialog();
|
||||
|
||||
int fromMoment() const;
|
||||
void setFromMoment(int fromMoment);
|
||||
|
||||
int tillMoment() const;
|
||||
void setTillMoment(int tillMoment);
|
||||
|
||||
void setFromTillMoment(int fromMoment, int tillMoment);
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Ui::DeleteMomentsDialog> m_ui;
|
||||
};
|
||||
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DeleteMomentsDialog</class>
|
||||
<widget class="QDialog" name="DeleteMomentsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>218</width>
|
||||
<height>139</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Deleting Moments</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelFromMoment">
|
||||
<property name="text">
|
||||
<string>From moment:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxFromMoment</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelTillMoment">
|
||||
<property name="text">
|
||||
<string>Till moment:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxTillMoment</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxFromMoment">
|
||||
<property name="maximum">
|
||||
<number>2147483647</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxTillMoment">
|
||||
<property name="maximum">
|
||||
<number>2147483647</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>DeleteMomentsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>DeleteMomentsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "editspritedialog.h"
|
||||
#include "ui_editspritedialog.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
#include "models/spritesmodel.h"
|
||||
#include "createspritedialog.h"
|
||||
#include "imageeditordialog.h"
|
||||
|
||||
EditSpriteDialog::EditSpriteDialog(const std::vector<QPixmap> &pixmaps, const QString &spriteName, QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::EditSpriteDialog>()},
|
||||
m_pixmaps{pixmaps},
|
||||
m_spriteName{spriteName},
|
||||
m_model{std::make_unique<SpritesModel>(m_pixmaps, this)}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
setWindowFlags((windowFlags() & ~Qt::Dialog) | Qt::Window);
|
||||
#endif
|
||||
setWindowFlag(Qt::WindowMinimizeButtonHint);
|
||||
setWindowFlag(Qt::WindowMaximizeButtonHint);
|
||||
setWindowFlag(Qt::WindowCloseButtonHint);
|
||||
|
||||
updateTitle();
|
||||
|
||||
m_ui->actionNew->setShortcut(QKeySequence::New);
|
||||
m_ui->actionCreateFromFile->setShortcut(QKeySequence::Open);
|
||||
m_ui->actionSaveAsPngFile->setShortcut(QKeySequence::Save);
|
||||
|
||||
m_ui->listView->setModel(m_model.get());
|
||||
|
||||
connect(m_ui->actionNew, &QAction::triggered, this, &EditSpriteDialog::newSprite);
|
||||
|
||||
connect(m_ui->listView, &QListView::doubleClicked, this, &EditSpriteDialog::doubleClicked);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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{})
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QPixmap>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace Ui { class EditSpriteDialog; }
|
||||
struct Sprite;
|
||||
class SpritesModel;
|
||||
|
||||
class EditSpriteDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
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;
|
||||
|
||||
std::vector<QPixmap> m_pixmaps;
|
||||
const QString m_spriteName;
|
||||
|
||||
bool m_unsavedChanges{};
|
||||
|
||||
const std::unique_ptr<SpritesModel> m_model;
|
||||
};
|
||||
@@ -0,0 +1,255 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EditSpriteDialog</class>
|
||||
<widget class="QDialog" name="EditSpriteDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>590</width>
|
||||
<height>510</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Sprite Editor</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1,0">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
<string>&File</string>
|
||||
</property>
|
||||
<addaction name="actionNew"/>
|
||||
<addaction name="actionCreateFromFile"/>
|
||||
<addaction name="actionAddFromFile"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSaveAsPngFile"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCreateFromStrip"/>
|
||||
<addaction name="actionAddFromStrip"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCloseSavingChanges"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuEdit">
|
||||
<property name="title">
|
||||
<string>&Edit</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuTransform">
|
||||
<property name="title">
|
||||
<string>&Transform</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuImages">
|
||||
<property name="title">
|
||||
<string>&Images</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuAnimation">
|
||||
<property name="title">
|
||||
<string>&Animation</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuEdit"/>
|
||||
<addaction name="menuTransform"/>
|
||||
<addaction name="menuImages"/>
|
||||
<addaction name="menuAnimation"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="movable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="floatable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<addaction name="actionCloseSavingChanges"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionNew"/>
|
||||
<addaction name="actionCreateFromFile"/>
|
||||
<addaction name="actionAddFromFile"/>
|
||||
<addaction name="actionSaveAsPngFile"/>
|
||||
<addaction name="separator"/>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayoutWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxShowPreview">
|
||||
<property name="text">
|
||||
<string>Show Preview</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QListView" name="listView">
|
||||
<property name="spacing">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="viewMode">
|
||||
<enum>QListView::IconMode</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionNew">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/new.png</normaloff>:/qtgameengine/icons/new.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&New...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateFromFile">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/open.png</normaloff>:/qtgameengine/icons/open.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Create from file...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAddFromFile">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/create-group.png</normaloff>:/qtgameengine/icons/create-group.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Add from file...</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+A</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveAsPngFile">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/save.png</normaloff>:/qtgameengine/icons/save.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Save as PNG File...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateFromStrip">
|
||||
<property name="text">
|
||||
<string>Create from Strip...</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+I</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAddFromStrip">
|
||||
<property name="text">
|
||||
<string>Add from Stri&p...</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+P</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCloseSavingChanges">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/ok.png</normaloff>:/qtgameengine/icons/ok.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Close Saving Changes</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>actionCloseSavingChanges</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>EditSpriteDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>245</x>
|
||||
<y>249</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "extensionpackagesdialog.h"
|
||||
#include "ui_extensionpackagesdialog.h"
|
||||
|
||||
#include "installextensiondialog.h"
|
||||
|
||||
ExtensionPackagesDialog::ExtensionPackagesDialog(QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::ExtensionPackagesDialog>()}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
#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"});
|
||||
|
||||
if (auto button = m_ui->buttonBox->addButton(tr("Install"), QDialogButtonBox::ActionRole))
|
||||
{
|
||||
button->setIcon(QIcon{":/qtgameengine/icons/extension-packages-file.png"});
|
||||
connect(button, &QAbstractButton::clicked,
|
||||
this, &ExtensionPackagesDialog::install);
|
||||
}
|
||||
}
|
||||
|
||||
ExtensionPackagesDialog::~ExtensionPackagesDialog() = default;
|
||||
|
||||
void ExtensionPackagesDialog::install()
|
||||
{
|
||||
InstallExtensionDialog dialog{this};
|
||||
dialog.exec();
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class ExtensionPackagesDialog; }
|
||||
|
||||
class ExtensionPackagesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ExtensionPackagesDialog(QWidget *parent = nullptr);
|
||||
~ExtensionPackagesDialog();
|
||||
|
||||
private slots:
|
||||
void install();
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Ui::ExtensionPackagesDialog> m_ui;
|
||||
};
|
||||
@@ -0,0 +1,212 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ExtensionPackagesDialog</class>
|
||||
<widget class="QDialog" name="ExtensionPackagesDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>461</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Extension Packages</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,1,0">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout" columnminimumwidth="1,0,1">
|
||||
<item row="1" column="0">
|
||||
<widget class="QListView" name="listViewUsedPackages"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonLeft">
|
||||
<property name="text">
|
||||
<string>⬅️</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonRight">
|
||||
<property name="text">
|
||||
<string>➡️</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelUsedPackages">
|
||||
<property name="text">
|
||||
<string>Used Packages:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QListView" name="listViewAvailablePackages"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="labelAvailablePackages">
|
||||
<property name="text">
|
||||
<string>Available Packages:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxInformation">
|
||||
<property name="title">
|
||||
<string>Information</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelAuthor">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Author:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelVersion">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Version:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelDate">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Date:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelLicense">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>License:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelDescription">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Description:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>ExtensionPackagesDialog</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>ExtensionPackagesDialog</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>
|
||||
@@ -0,0 +1,184 @@
|
||||
#include "fontpropertiesdialog.h"
|
||||
#include "ui_fontpropertiesdialog.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
#include "models/projecttreemodel.h"
|
||||
|
||||
FontPropertiesDialog::FontPropertiesDialog(Font &font, ProjectTreeModel &projectModel, QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::FontPropertiesDialog>()},
|
||||
m_font{font},
|
||||
m_projectModel{projectModel}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
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"});
|
||||
|
||||
m_ui->lineEditName->setText(m_font.name);
|
||||
m_ui->fontComboBox->setCurrentFont(m_font.font);
|
||||
m_ui->spinBoxSize->setValue(m_font.font.pointSize());
|
||||
m_ui->checkBoxBold->setChecked(m_font.font.bold());
|
||||
m_ui->checkBoxItalic->setChecked(m_font.font.italic());
|
||||
m_ui->spinBoxCharRangeFrom->setValue(m_font.range.from);
|
||||
m_ui->spinBoxCharRangeTo->setValue(m_font.range.to);
|
||||
|
||||
m_ui->labelPreview->setFont(currentFont());
|
||||
|
||||
connect(&m_projectModel, &ProjectTreeModel::fontNameChanged,
|
||||
this, &FontPropertiesDialog::fontNameChanged);
|
||||
|
||||
connect(m_ui->pushButtonNormal, &QAbstractButton::clicked,
|
||||
this, &FontPropertiesDialog::normalRange);
|
||||
connect(m_ui->pushButtonDigits, &QAbstractButton::clicked,
|
||||
this, &FontPropertiesDialog::digitsRange);
|
||||
connect(m_ui->pushButtonAll, &QAbstractButton::clicked,
|
||||
this, &FontPropertiesDialog::allRange);
|
||||
connect(m_ui->pushButtonLetters, &QAbstractButton::clicked,
|
||||
this, &FontPropertiesDialog::lettersRange);
|
||||
|
||||
connect(m_ui->lineEditName, &QLineEdit::textChanged,
|
||||
this, &FontPropertiesDialog::changed);
|
||||
connect(m_ui->fontComboBox, &QFontComboBox::currentFontChanged,
|
||||
this, &FontPropertiesDialog::changed);
|
||||
connect(m_ui->spinBoxSize, &QSpinBox::valueChanged,
|
||||
this, &FontPropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxBold, &QCheckBox::toggled,
|
||||
this, &FontPropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxItalic, &QCheckBox::toggled,
|
||||
this, &FontPropertiesDialog::changed);
|
||||
connect(m_ui->spinBoxCharRangeFrom, &QSpinBox::valueChanged,
|
||||
this, &FontPropertiesDialog::changed);
|
||||
connect(m_ui->spinBoxCharRangeTo, &QSpinBox::valueChanged,
|
||||
this, &FontPropertiesDialog::changed);
|
||||
}
|
||||
|
||||
FontPropertiesDialog::~FontPropertiesDialog() = default;
|
||||
|
||||
void FontPropertiesDialog::accept()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_font.name != m_ui->lineEditName->text())
|
||||
{
|
||||
if (!m_projectModel.rename<Font>(m_font, m_ui->lineEditName->text()))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Renaming Font failed!"), tr("Renaming Font failed!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_font.font = currentFont();
|
||||
m_font.range = {
|
||||
.from = m_ui->spinBoxCharRangeFrom->value(),
|
||||
.to = m_ui->spinBoxCharRangeTo->value(),
|
||||
};
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void FontPropertiesDialog::reject()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto result = QMessageBox::warning(
|
||||
this,
|
||||
tr("The Font 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 FontPropertiesDialog::normalRange()
|
||||
{
|
||||
m_ui->spinBoxCharRangeFrom->setValue(32);
|
||||
m_ui->spinBoxCharRangeFrom->setValue(127);
|
||||
}
|
||||
|
||||
void FontPropertiesDialog::digitsRange()
|
||||
{
|
||||
m_ui->spinBoxCharRangeFrom->setValue(48);
|
||||
m_ui->spinBoxCharRangeFrom->setValue(57);
|
||||
}
|
||||
|
||||
void FontPropertiesDialog::allRange()
|
||||
{
|
||||
m_ui->spinBoxCharRangeFrom->setValue(0);
|
||||
m_ui->spinBoxCharRangeFrom->setValue(255);
|
||||
}
|
||||
|
||||
void FontPropertiesDialog::lettersRange()
|
||||
{
|
||||
m_ui->spinBoxCharRangeFrom->setValue(65);
|
||||
m_ui->spinBoxCharRangeFrom->setValue(122);
|
||||
}
|
||||
|
||||
void FontPropertiesDialog::changed()
|
||||
{
|
||||
m_ui->labelPreview->setFont(currentFont());
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
m_unsavedChanges = true;
|
||||
updateTitle();
|
||||
}
|
||||
}
|
||||
|
||||
void FontPropertiesDialog::fontNameChanged(const Font &font)
|
||||
{
|
||||
if (&font != &m_font)
|
||||
return;
|
||||
|
||||
{
|
||||
QSignalBlocker blocker{m_ui->lineEditName};
|
||||
m_ui->lineEditName->setText(font.name);
|
||||
}
|
||||
|
||||
updateTitle();
|
||||
}
|
||||
|
||||
void FontPropertiesDialog::updateTitle()
|
||||
{
|
||||
setWindowTitle(tr("Font Properties: %0%1")
|
||||
.arg(m_font.name)
|
||||
.arg(m_unsavedChanges ? tr("*") : QString{})
|
||||
);
|
||||
}
|
||||
|
||||
QFont FontPropertiesDialog::currentFont() const
|
||||
{
|
||||
QFont font;
|
||||
font.setFamily(m_ui->fontComboBox->currentFont().family());
|
||||
font.setPointSize(m_ui->spinBoxSize->value());
|
||||
font.setBold(m_ui->checkBoxBold->isChecked());
|
||||
font.setItalic(m_ui->checkBoxItalic->isChecked());
|
||||
return font;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class FontPropertiesDialog; }
|
||||
struct Font;
|
||||
class ProjectTreeModel;
|
||||
|
||||
class FontPropertiesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FontPropertiesDialog(Font &font, ProjectTreeModel &projectModel, QWidget *parent = nullptr);
|
||||
~FontPropertiesDialog();
|
||||
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
|
||||
private slots:
|
||||
void normalRange();
|
||||
void digitsRange();
|
||||
void allRange();
|
||||
void lettersRange();
|
||||
|
||||
void changed();
|
||||
|
||||
void fontNameChanged(const Font &font);
|
||||
|
||||
private:
|
||||
void updateTitle();
|
||||
QFont currentFont() const;
|
||||
|
||||
const std::unique_ptr<Ui::FontPropertiesDialog> m_ui;
|
||||
|
||||
Font &m_font;
|
||||
ProjectTreeModel &m_projectModel;
|
||||
|
||||
bool m_unsavedChanges{};
|
||||
};
|
||||
@@ -0,0 +1,259 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FontPropertiesDialog</class>
|
||||
<widget class="QDialog" name="FontPropertiesDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>338</width>
|
||||
<height>451</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Font Properties</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/font-file.png</normaloff>:/qtgameengine/icons/font-file.png</iconset>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelName">
|
||||
<property name="text">
|
||||
<string>&Name:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditName</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<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">
|
||||
<property name="text">
|
||||
<string>Font:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>fontComboBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelSize">
|
||||
<property name="text">
|
||||
<string>Size:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxSize</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QFontComboBox" name="fontComboBox"/>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxSize"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxBold">
|
||||
<property name="text">
|
||||
<string>Bold</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxItalic">
|
||||
<property name="text">
|
||||
<string>Italic</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxCharacterRange">
|
||||
<property name="title">
|
||||
<string>Character Range</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="labelTill">
|
||||
<property name="text">
|
||||
<string>till</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QSpinBox" name="spinBoxCharRangeFrom">
|
||||
<property name="maximum">
|
||||
<number>255</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>32</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QSpinBox" name="spinBoxCharRangeTo">
|
||||
<property name="maximum">
|
||||
<number>255</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>127</number>
|
||||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
</widget>
|
||||
</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>
|
||||
</widget>
|
||||
</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>
|
||||
</widget>
|
||||
</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>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelPreview">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>AaBbCcDd</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</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>FontPropertiesDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>168</x>
|
||||
<y>429</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>168</x>
|
||||
<y>225</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>FontPropertiesDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>168</x>
|
||||
<y>429</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>168</x>
|
||||
<y>225</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "gameinformationdialog.h"
|
||||
#include "ui_gameinformationdialog.h"
|
||||
|
||||
GameInformationDialog::GameInformationDialog(QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::GameInformationDialog>()}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
setWindowFlags((windowFlags() & ~Qt::Dialog) | Qt::Window);
|
||||
#endif
|
||||
setWindowFlag(Qt::WindowMinimizeButtonHint);
|
||||
setWindowFlag(Qt::WindowMaximizeButtonHint);
|
||||
setWindowFlag(Qt::WindowCloseButtonHint);
|
||||
}
|
||||
|
||||
GameInformationDialog::~GameInformationDialog() = default;
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class GameInformationDialog; }
|
||||
|
||||
class GameInformationDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GameInformationDialog(QWidget *parent = nullptr);
|
||||
~GameInformationDialog();
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Ui::GameInformationDialog> m_ui;
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GameInformationDialog</class>
|
||||
<widget class="QDialog" name="GameInformationDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<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/>
|
||||
</ui>
|
||||
@@ -0,0 +1,111 @@
|
||||
#include "globalgamesettingsdialog.h"
|
||||
#include "ui_globalgamesettingsdialog.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QMessageBox>
|
||||
|
||||
GlobalGameSettingsDialog::GlobalGameSettingsDialog(QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::GlobalGameSettingsDialog>()}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
#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{})
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class GlobalGameSettingsDialog; }
|
||||
|
||||
class GlobalGameSettingsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
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{};
|
||||
};
|
||||
@@ -0,0 +1,475 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GlobalGameSettingsDialog</class>
|
||||
<widget class="QDialog" name="GlobalGameSettingsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>426</width>
|
||||
<height>556</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Global Game Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidgetResolution">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabGraphics">
|
||||
<attribute name="title">
|
||||
<string>Graphics</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxFullscreen">
|
||||
<property name="text">
|
||||
<string>Start in full-screen mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,1">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxScaling">
|
||||
<property name="title">
|
||||
<string>Scaling</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonFixedScale">
|
||||
<property name="text">
|
||||
<string>Fixed scale (in %)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBox">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonKeepAspectRatio">
|
||||
<property name="text">
|
||||
<string>Keep aspect ratio</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonFullScale">
|
||||
<property name="text">
|
||||
<string>Full scale</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxInterpolateColors">
|
||||
<property name="text">
|
||||
<string>Interpolate colors between pixels</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelColorOutsideRoom">
|
||||
<property name="text">
|
||||
<string>Color outside the room region:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>toolButtonColorOutside</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButtonColorOutside">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxAllowResize">
|
||||
<property name="text">
|
||||
<string>Allow the player to resize the game window</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxAlwaysOntop">
|
||||
<property name="text">
|
||||
<string>Let the game window always stay on top</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxNoBorder">
|
||||
<property name="text">
|
||||
<string>Don't draw a border in windowed mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxNoWindowButtons">
|
||||
<property name="text">
|
||||
<string>Don't show the buttons in the window caption</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxDisplayCursor">
|
||||
<property name="text">
|
||||
<string>Display the cursor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxFreezeOnFocusLost">
|
||||
<property name="text">
|
||||
<string>Freeze the game when the form loses focus</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxDisableScreensavers">
|
||||
<property name="text">
|
||||
<string>Disable screensavers and power saving actions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabResolution">
|
||||
<attribute name="title">
|
||||
<string>Resolution</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabOther">
|
||||
<attribute name="title">
|
||||
<string>Other</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxDefaultKeys">
|
||||
<property name="title">
|
||||
<string>Default Keys</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxEscEndGame">
|
||||
<property name="text">
|
||||
<string>Let <Esc> end the game</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxTreatCloseAsEsc">
|
||||
<property name="text">
|
||||
<string>Treat the close button as <Esc> key</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxF1ShowGameInfo">
|
||||
<property name="text">
|
||||
<string>Let <F1> show the game information</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxF4SwitchScreenMode">
|
||||
<property name="text">
|
||||
<string>Let <F4> switch between screen modes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxEnableSavestates">
|
||||
<property name="text">
|
||||
<string>Let <F5> save the game and <F6> load a game</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxF9Screenshot">
|
||||
<property name="text">
|
||||
<string>Let <F9> take a screenshot of the game</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxGameProcessPriority">
|
||||
<property name="title">
|
||||
<string>Game Process Priority</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonPriorityNormal">
|
||||
<property name="text">
|
||||
<string>Normal</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonPriorityHigh">
|
||||
<property name="text">
|
||||
<string>High</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonPriorityHighest">
|
||||
<property name="text">
|
||||
<string>Highest</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxVersionInformation">
|
||||
<property name="title">
|
||||
<string>Version Information</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelMajor">
|
||||
<property name="text">
|
||||
<string>Major</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxMajor</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBoxMajor"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelMinor">
|
||||
<property name="text">
|
||||
<string>Minor</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxMinor</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBoxMinor"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelRelease">
|
||||
<property name="text">
|
||||
<string>Release</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxRelease</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBoxRelease"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelBuild">
|
||||
<property name="text">
|
||||
<string>Build</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxBuild</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBoxBuild"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelCompany">
|
||||
<property name="text">
|
||||
<string>Company</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditCompany</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEditCompany"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelProduct">
|
||||
<property name="text">
|
||||
<string>Product</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditProduct</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineEditProduct"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelCopyright">
|
||||
<property name="text">
|
||||
<string>Copyright</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditCopyright</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineEditCopyright"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelDescription">
|
||||
<property name="text">
|
||||
<string>Description</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditDescription</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="lineEditDescription"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabLoading">
|
||||
<attribute name="title">
|
||||
<string>Loading</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabErrors">
|
||||
<attribute name="title">
|
||||
<string>Errors</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabInfo">
|
||||
<attribute name="title">
|
||||
<string>Info</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>GlobalGameSettingsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>184</x>
|
||||
<y>506</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>184</x>
|
||||
<y>263</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>GlobalGameSettingsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>184</x>
|
||||
<y>506</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>184</x>
|
||||
<y>263</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,88 @@
|
||||
#include "imageeditordialog.h"
|
||||
#include "ui_imageeditordialog.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
ImageEditorDialog::ImageEditorDialog(const QPixmap &pixmap, const QString &title, QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::ImageEditorDialog>()},
|
||||
m_pixmap{pixmap},
|
||||
m_title{title}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
#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{})
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QPixmap>
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class ImageEditorDialog; }
|
||||
|
||||
class ImageEditorDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
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{};
|
||||
};
|
||||
@@ -0,0 +1,328 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ImageEditorDialog</class>
|
||||
<widget class="QDialog" name="ImageEditorDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>572</width>
|
||||
<height>454</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Image Editor</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1,0">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
<string>&File</string>
|
||||
</property>
|
||||
<addaction name="actionNew"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSaveAsPngFile"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionPreviousImage"/>
|
||||
<addaction name="actionNextImage"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCloseSavingChanges"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuEdit">
|
||||
<property name="title">
|
||||
<string>&Edit</string>
|
||||
</property>
|
||||
<addaction name="actionUndo"/>
|
||||
<addaction name="actionRedo"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionEraseToLeftColor"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionDelete"/>
|
||||
<addaction name="actionCut"/>
|
||||
<addaction name="actionCopy"/>
|
||||
<addaction name="actionPaste"/>
|
||||
<addaction name="actionPasteFromFile"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSelectAll"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
<string>&View</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuTransform">
|
||||
<property name="title">
|
||||
<string>&Transform</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuImage">
|
||||
<property name="title">
|
||||
<string>&Image</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuEdit"/>
|
||||
<addaction name="menuView"/>
|
||||
<addaction name="menuTransform"/>
|
||||
<addaction name="menuImage"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="movable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<addaction name="actionCloseSavingChanges"/>
|
||||
<addaction name="actionPreviousImage"/>
|
||||
<addaction name="actionNextImage"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionNew"/>
|
||||
<addaction name="actionLoad"/>
|
||||
<addaction name="actionSaveAsPngFile"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionUndo"/>
|
||||
<addaction name="actionRedo"/>
|
||||
<addaction name="separator"/>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<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"/>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionNew">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/new.png</normaloff>:/qtgameengine/icons/new.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&New...</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Create a new, empty image</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveAsPngFile">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/save.png</normaloff>:/qtgameengine/icons/save.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Save as PNG file...</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the image as a PNG file</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPreviousImage">
|
||||
<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>&Previous image...</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Edit the previous subimage of the sprite</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionNextImage">
|
||||
<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>N&ext image...</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Edit the next subimage of the sprite</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCloseSavingChanges">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/ok.png</normaloff>:/qtgameengine/icons/ok.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Close Saving Changes</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Close the image editor, saving the changes made</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionLoad">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/open.png</normaloff>:/qtgameengine/icons/open.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUndo">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/undo.png</normaloff>:/qtgameengine/icons/undo.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Undo</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRedo">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/redo.png</normaloff>:/qtgameengine/icons/redo.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Redo</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEraseToLeftColor">
|
||||
<property name="text">
|
||||
<string>&Erase to left color</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDelete">
|
||||
<property name="text">
|
||||
<string>&Delete</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCut">
|
||||
<property name="text">
|
||||
<string>Cu&t</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCopy">
|
||||
<property name="text">
|
||||
<string>&Copy</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPaste">
|
||||
<property name="text">
|
||||
<string>&Paste</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPasteFromFile">
|
||||
<property name="text">
|
||||
<string>Paste from F&ile</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSelectAll">
|
||||
<property name="text">
|
||||
<string>Select &All</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>DrawingCanvasWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>widgets/drawingcanvaswidget.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<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>
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "includedfilesdialog.h"
|
||||
#include "ui_includedfilesdialog.h"
|
||||
|
||||
#include "projectcontainer.h"
|
||||
#include "models/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;
|
||||
@@ -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;
|
||||
};
|
||||
@@ -0,0 +1,146 @@
|
||||
<?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">
|
||||
<property name="toolTip">
|
||||
<string>This is the list of files to be included when creating a stand-alone game.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonAdd">
|
||||
<property name="toolTip">
|
||||
<string>Add a file to be included</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Add</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/add.png</normaloff>:/qtgameengine/icons/add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonChange">
|
||||
<property name="toolTip">
|
||||
<string>Change the properties of the included file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Change</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/replace.png</normaloff>:/qtgameengine/icons/replace.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonDelete">
|
||||
<property name="toolTip">
|
||||
<string>Delete the indicated included file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Delete</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/delete.png</normaloff>:/qtgameengine/icons/delete.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonClear">
|
||||
<property name="toolTip">
|
||||
<string>Clear the list of included files</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Clear</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/new.png</normaloff>:/qtgameengine/icons/new.png</iconset>
|
||||
</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>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>
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "installextensiondialog.h"
|
||||
#include "ui_installextensiondialog.h"
|
||||
|
||||
InstallExtensionDialog::InstallExtensionDialog(QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::InstallExtensionDialog>()}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
setWindowFlags((windowFlags() & ~Qt::Dialog) | Qt::Window);
|
||||
#endif
|
||||
setWindowFlag(Qt::WindowCloseButtonHint);
|
||||
}
|
||||
|
||||
InstallExtensionDialog::~InstallExtensionDialog() = default;
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class InstallExtensionDialog; }
|
||||
|
||||
class InstallExtensionDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InstallExtensionDialog(QWidget *parent = nullptr);
|
||||
~InstallExtensionDialog();
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Ui::InstallExtensionDialog> m_ui;
|
||||
};
|
||||
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>InstallExtensionDialog</class>
|
||||
<widget class="QDialog" name="InstallExtensionDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Installing Extension Packages</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelInstalledPackages">
|
||||
<property name="text">
|
||||
<string>Installed Packages:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListView" name="listView"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>InstallExtensionDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>350</x>
|
||||
<y>149</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>199</x>
|
||||
<y>149</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>InstallExtensionDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>350</x>
|
||||
<y>149</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>199</x>
|
||||
<y>149</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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>
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "objectinformationdialog.h"
|
||||
#include "ui_objectinformationdialog.h"
|
||||
|
||||
ObjectInformationDialog::ObjectInformationDialog(ProjectContainer &project, QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::ObjectInformationDialog>()},
|
||||
m_project{project}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
}
|
||||
|
||||
ObjectInformationDialog::~ObjectInformationDialog() = default;
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class ObjectInformationDialog; }
|
||||
struct ProjectContainer;
|
||||
|
||||
class ObjectInformationDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ObjectInformationDialog(ProjectContainer &project, QWidget *parent = nullptr);
|
||||
~ObjectInformationDialog();
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Ui::ObjectInformationDialog> m_ui;
|
||||
|
||||
ProjectContainer &m_project;
|
||||
};
|
||||
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ObjectInformationDialog</class>
|
||||
<widget class="QDialog" name="ObjectInformationDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Information about all Objects</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/object-file.png</normaloff>:/qtgameengine/icons/object-file.png</iconset>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<addaction name="actionOk"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSave"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionPrint"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="plainTextEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionOk">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/ok.png</normaloff>:/qtgameengine/icons/ok.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ok</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Close the form</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/save.png</normaloff>:/qtgameengine/icons/save.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the object information to a file</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPrint">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/print.png</normaloff>:/qtgameengine/icons/print.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Print</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Print the object information</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<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>
|
||||
@@ -0,0 +1,373 @@
|
||||
#include "objectpropertiesdialog.h"
|
||||
#include "ui_objectpropertiesdialog.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "models/projecttreemodel.h"
|
||||
#include "models/objecteventsmodel.h"
|
||||
#include "addeventdialog.h"
|
||||
|
||||
ObjectPropertiesDialog::ObjectPropertiesDialog(Object &object, ProjectTreeModel &projectModel, QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::ObjectPropertiesDialog>()},
|
||||
m_object{object},
|
||||
m_projectModel{projectModel},
|
||||
m_events{m_object.events},
|
||||
m_eventsModel{std::make_unique<ObjectEventsModel>(m_events)},
|
||||
m_spritesMenu{new QMenu{m_ui->toolButtonSprite}},
|
||||
m_spriteName{object.spriteName}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
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"});
|
||||
|
||||
m_ui->lineEditName->setText(m_object.name);
|
||||
m_ui->lineEditSprite->setText(m_spriteName.isEmpty() ? tr("<no sprite>") : m_spriteName);
|
||||
updateSpritePreview();
|
||||
m_ui->toolButtonSprite->setMenu(m_spritesMenu);
|
||||
m_ui->checkBoxVisible->setChecked(m_object.visible);
|
||||
m_ui->checkBoxSolid->setChecked(m_object.solid);
|
||||
m_ui->spinBoxDepth->setValue(m_object.depth);
|
||||
m_ui->checkBoxPersistent->setChecked(m_object.persistent);
|
||||
|
||||
m_ui->listViewEvents->setModel(m_eventsModel.get());
|
||||
|
||||
connect(&m_projectModel, &ProjectTreeModel::objectNameChanged,
|
||||
this, &ObjectPropertiesDialog::objectNameChanged);
|
||||
connect(&m_projectModel, &ProjectTreeModel::spriteNameChanged,
|
||||
this, &ObjectPropertiesDialog::spriteNameChanged);
|
||||
connect(&m_projectModel, &ProjectTreeModel::spriteAboutToBeRemoved,
|
||||
this, &ObjectPropertiesDialog::spriteAboutToBeRemoved);
|
||||
connect(&m_projectModel, &ProjectTreeModel::spritePixmapsChanged,
|
||||
this, &ObjectPropertiesDialog::spritePixmapsChanged);
|
||||
|
||||
connect(m_eventsModel.get(), &QAbstractItemModel::modelReset,
|
||||
this, &ObjectPropertiesDialog::changed);
|
||||
connect(m_eventsModel.get(), &QAbstractItemModel::rowsInserted,
|
||||
this, &ObjectPropertiesDialog::changed);
|
||||
connect(m_eventsModel.get(), &QAbstractItemModel::dataChanged,
|
||||
this, &ObjectPropertiesDialog::changed);
|
||||
connect(m_eventsModel.get(), &QAbstractItemModel::rowsRemoved,
|
||||
this, &ObjectPropertiesDialog::changed);
|
||||
|
||||
connect(m_ui->pushButtonNewSprite, &QAbstractButton::clicked,
|
||||
this, &ObjectPropertiesDialog::newSprite);
|
||||
connect(m_ui->pushButtonEditSprite, &QAbstractButton::clicked,
|
||||
this, &ObjectPropertiesDialog::editSprite);
|
||||
connect(m_ui->pushButtonShowInformation, &QAbstractButton::clicked,
|
||||
this, &ObjectPropertiesDialog::showInformation);
|
||||
connect(m_ui->pushButtonAddEvent, &QAbstractButton::clicked,
|
||||
this, &ObjectPropertiesDialog::addEvent);
|
||||
connect(m_ui->pushButtonDeleteEvent, &QAbstractButton::clicked,
|
||||
this, &ObjectPropertiesDialog::deleteEvent);
|
||||
connect(m_ui->pushButtonChangeEvent, &QAbstractButton::clicked,
|
||||
this, &ObjectPropertiesDialog::replaceEvent);
|
||||
|
||||
connect(m_ui->lineEditName, &QLineEdit::textChanged,
|
||||
this, &ObjectPropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxVisible, &QCheckBox::toggled,
|
||||
this, &ObjectPropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxSolid, &QCheckBox::toggled,
|
||||
this, &ObjectPropertiesDialog::changed);
|
||||
connect(m_ui->spinBoxDepth, &QSpinBox::valueChanged,
|
||||
this, &ObjectPropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxPersistent, &QCheckBox::toggled,
|
||||
this, &ObjectPropertiesDialog::changed);
|
||||
|
||||
connect(m_spritesMenu, &QMenu::aboutToShow,
|
||||
this, &ObjectPropertiesDialog::spritesMenuAboutToShow);
|
||||
|
||||
connect(m_ui->listViewEvents->selectionModel(), &QItemSelectionModel::currentChanged,
|
||||
this, &ObjectPropertiesDialog::currentEventChanged);
|
||||
|
||||
connect(m_ui->listViewEvents, &QListView::customContextMenuRequested,
|
||||
this, &ObjectPropertiesDialog::eventsContextMenuRequested);
|
||||
|
||||
connect(m_ui->actionsWidget, &ActionsContainerWidget::changed,
|
||||
this, &ObjectPropertiesDialog::changed);
|
||||
}
|
||||
|
||||
ObjectPropertiesDialog::~ObjectPropertiesDialog() = default;
|
||||
|
||||
void ObjectPropertiesDialog::accept()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_object.name != m_ui->lineEditName->text())
|
||||
{
|
||||
if (!m_projectModel.rename<Object>(m_object, m_ui->lineEditName->text()))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Renaming Object failed!"), tr("Renaming Object failed!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_object.spriteName = m_spriteName;
|
||||
m_object.visible = m_ui->checkBoxVisible->isChecked();
|
||||
m_object.solid = m_ui->checkBoxSolid->isChecked();
|
||||
m_object.depth = m_ui->spinBoxDepth->value();
|
||||
m_object.persistent = m_ui->checkBoxPersistent->isChecked();
|
||||
m_object.events = std::move(m_events);
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::reject()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto result = QMessageBox::warning(
|
||||
this,
|
||||
tr("The Object 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 ObjectPropertiesDialog::newSprite()
|
||||
{
|
||||
auto sprite = m_projectModel.create<Sprite>();
|
||||
if (!sprite)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Creating Sprite failed"), tr("Creating Sprite failed"));
|
||||
return;
|
||||
}
|
||||
setSprite(*sprite);
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::editSprite()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::showInformation()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::addEvent()
|
||||
{
|
||||
AddEventDialog dialog{this};
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
if (!m_eventsModel->addEvent(dialog.eventType()))
|
||||
QMessageBox::warning(this, tr("Could not add Event!"), tr("Could not add Event!"));
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::deleteEvent()
|
||||
{
|
||||
const auto index = m_ui->listViewEvents->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
if (QMessageBox::question(this, tr("Confirm"), tr("Are you sure, that you really want to remove the event with all its actions?")) != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
if (!m_eventsModel->removeRow(index.row()))
|
||||
QMessageBox::warning(this, tr("Could not delete Event!"), tr("Could not delete Event!"));
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::replaceEvent()
|
||||
{
|
||||
const auto index = m_ui->listViewEvents->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
const auto event = m_eventsModel->getEvent(index);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
AddEventDialog dialog{this};
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
if (!m_eventsModel->changeEvent(event->first, dialog.eventType()))
|
||||
QMessageBox::warning(this, tr("Could not change Event!"), tr("Could not change Event!"));
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::duplicateEvent()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::changed()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
m_unsavedChanges = true;
|
||||
updateTitle();
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::objectNameChanged(const Object &object)
|
||||
{
|
||||
if (&object != &m_object)
|
||||
return;
|
||||
|
||||
{
|
||||
QSignalBlocker blocker{m_ui->lineEditName};
|
||||
m_ui->lineEditName->setText(object.name);
|
||||
}
|
||||
|
||||
updateTitle();
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::spriteNameChanged(const Sprite &sprite, const QString &oldName)
|
||||
{
|
||||
if (m_spriteName.isEmpty())
|
||||
return;
|
||||
|
||||
if (m_spriteName != oldName)
|
||||
return;
|
||||
|
||||
m_spriteName = sprite.name;
|
||||
{
|
||||
QSignalBlocker blocker{m_ui->lineEditSprite};
|
||||
m_ui->lineEditSprite->setText(sprite.name);
|
||||
}
|
||||
updateSpritePreview();
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::spriteAboutToBeRemoved(const Sprite &sprite)
|
||||
{
|
||||
if (m_spriteName.isEmpty())
|
||||
return;
|
||||
|
||||
if (m_spriteName != sprite.name)
|
||||
return;
|
||||
|
||||
m_spriteName.clear();
|
||||
{
|
||||
QSignalBlocker blocker{m_ui->lineEditSprite};
|
||||
m_ui->lineEditSprite->setText(tr("<no sprite>"));
|
||||
}
|
||||
m_ui->labelSpritePreview->setPixmap(QPixmap{});
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::spritePixmapsChanged(const Sprite &sprite)
|
||||
{
|
||||
if (m_spriteName.isEmpty())
|
||||
return;
|
||||
|
||||
if (m_spriteName != sprite.name)
|
||||
return;
|
||||
|
||||
updateSpritePreview(sprite.pixmaps);
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::spritesMenuAboutToShow()
|
||||
{
|
||||
m_spritesMenu->clear();
|
||||
m_spritesMenu->addAction(tr("<no sprite>"), this, &ObjectPropertiesDialog::clearSprite);
|
||||
for (const auto &sprite : m_projectModel.project()->sprites)
|
||||
m_spritesMenu->addAction(sprite.pixmaps.empty() ? QPixmap{} : sprite.pixmaps.front(),
|
||||
sprite.name,
|
||||
this,
|
||||
[&sprite,this](){ setSprite(sprite); });
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::currentEventChanged(const QModelIndex &index)
|
||||
{
|
||||
if (index.isValid())
|
||||
{
|
||||
if (auto event = m_eventsModel->getEvent(index))
|
||||
m_ui->actionsWidget->setActionsContainer(&event->second);
|
||||
else
|
||||
goto none;
|
||||
}
|
||||
else
|
||||
{
|
||||
none:
|
||||
m_ui->actionsWidget->setActionsContainer(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::eventsContextMenuRequested(const QPoint &pos)
|
||||
{
|
||||
const auto index = m_ui->listViewEvents->indexAt(pos);
|
||||
auto event = index.isValid() ? m_eventsModel->getEvent(index) : nullptr;
|
||||
|
||||
QMenu menu{this};
|
||||
menu.addAction(tr("&Add Event"), this, &ObjectPropertiesDialog::addEvent);
|
||||
menu.addAction(tr("&Change Event"), this, &ObjectPropertiesDialog::replaceEvent)->setEnabled(event);
|
||||
menu.addAction(tr("&Duplicate Event"), this, &ObjectPropertiesDialog::duplicateEvent)->setEnabled(event);
|
||||
menu.addAction(tr("D&elete Event"), this, &ObjectPropertiesDialog::deleteEvent)->setEnabled(event);
|
||||
menu.exec(m_ui->listViewEvents->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::clearSprite()
|
||||
{
|
||||
m_spriteName.clear();
|
||||
m_ui->labelSpritePreview->setPixmap(QPixmap{});
|
||||
m_ui->lineEditSprite->setText(tr("<no sprite>"));
|
||||
changed();
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::setSprite(const Sprite &sprite)
|
||||
{
|
||||
m_spriteName = sprite.name;
|
||||
updateSpritePreview(sprite.pixmaps);
|
||||
m_ui->lineEditSprite->setText(sprite.name);
|
||||
changed();
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::updateTitle()
|
||||
{
|
||||
setWindowTitle(tr("Object Properties: %0%1")
|
||||
.arg(m_object.name)
|
||||
.arg(m_unsavedChanges ? tr("*") : QString{})
|
||||
);
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::updateSpritePreview()
|
||||
{
|
||||
if (m_spriteName.isEmpty())
|
||||
m_ui->labelSpritePreview->setPixmap(QPixmap{});
|
||||
else
|
||||
{
|
||||
const auto &sprites = m_projectModel.project()->sprites;
|
||||
const auto iter = std::find_if(std::cbegin(sprites), std::cend(sprites),
|
||||
[&](const Sprite &sprite){ return sprite.name == m_spriteName; });
|
||||
if (iter == std::cend(sprites))
|
||||
qWarning() << "sprite" << m_spriteName << "not found";
|
||||
else
|
||||
updateSpritePreview(iter->pixmaps);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPropertiesDialog::updateSpritePreview(const std::vector<QPixmap> &pixmaps)
|
||||
{
|
||||
m_ui->labelSpritePreview->setPixmap(pixmaps.empty() ? QPixmap{} : pixmaps.front().scaled(32, m_ui->labelSpritePreview->height(), Qt::KeepAspectRatio));
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
|
||||
class QMenu;
|
||||
namespace Ui { class ObjectPropertiesDialog; }
|
||||
class ProjectTreeModel;
|
||||
class ObjectEventsModel;
|
||||
|
||||
class ObjectPropertiesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ObjectPropertiesDialog(Object &object, ProjectTreeModel &projectModel, QWidget *parent = nullptr);
|
||||
~ObjectPropertiesDialog();
|
||||
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
|
||||
private slots:
|
||||
void newSprite();
|
||||
void editSprite();
|
||||
void showInformation();
|
||||
void addEvent();
|
||||
void deleteEvent();
|
||||
void replaceEvent();
|
||||
void duplicateEvent();
|
||||
|
||||
void changed();
|
||||
|
||||
void objectNameChanged(const Object &object);
|
||||
void spriteNameChanged(const Sprite &sprite, const QString &oldName);
|
||||
void spriteAboutToBeRemoved(const Sprite &sprite);
|
||||
void spritePixmapsChanged(const Sprite &sprite);
|
||||
|
||||
void spritesMenuAboutToShow();
|
||||
void currentEventChanged(const QModelIndex &index);
|
||||
void eventsContextMenuRequested(const QPoint &pos);
|
||||
|
||||
void clearSprite();
|
||||
void setSprite(const Sprite &sprite);
|
||||
|
||||
private:
|
||||
void updateTitle();
|
||||
void updateSpritePreview();
|
||||
void updateSpritePreview(const std::vector<QPixmap> &pixmaps);
|
||||
|
||||
const std::unique_ptr<Ui::ObjectPropertiesDialog> m_ui;
|
||||
|
||||
Object &m_object;
|
||||
ProjectTreeModel &m_projectModel;
|
||||
|
||||
Object::events_container_t m_events;
|
||||
|
||||
const std::unique_ptr<ObjectEventsModel> m_eventsModel;
|
||||
|
||||
QMenu * const m_spritesMenu;
|
||||
|
||||
QString m_spriteName;
|
||||
|
||||
bool m_unsavedChanges{};
|
||||
};
|
||||
@@ -0,0 +1,455 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ObjectPropertiesDialog</class>
|
||||
<widget class="QDialog" name="ObjectPropertiesDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>894</width>
|
||||
<height>496</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Object Properties</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/object-file.png</normaloff>:/qtgameengine/icons/object-file.png</iconset>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4" stretch="0,0,1">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelName">
|
||||
<property name="text">
|
||||
<string>&Name:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditName</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEditName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The name of the object</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxSprite">
|
||||
<property name="title">
|
||||
<string>Sprite</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelSpritePreview">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditSprite">
|
||||
<property name="toolTip">
|
||||
<string>The sprite used to represent the object</string>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButtonSprite">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::InstantPopup</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonNewSprite">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Create a new sprite for this object</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>New</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonEditSprite">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Edit the sprite for this object</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Edit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxVisible">
|
||||
<property name="toolTip">
|
||||
<string>Whether the object is visible</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Visible</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxSolid">
|
||||
<property name="toolTip">
|
||||
<string>Whether the object is solid</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Solid</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelDepth">
|
||||
<property name="text">
|
||||
<string>Depth:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxDepth</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxDepth">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The depth at which the object is drawn</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkBoxPersistent">
|
||||
<property name="toolTip">
|
||||
<string>Wheter the object is persistent between rooms</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Persistent</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelParent">
|
||||
<property name="text">
|
||||
<string>Parent:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditParent</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditParent">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The parent from which events and actions are</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><no parent></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButtonParent">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditMask">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The image used as a collision mask for the object</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><same as sprite></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButtonMask">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelMask">
|
||||
<property name="text">
|
||||
<string>Mask:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditMask</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonShowInformation">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Show the information about the object</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show Information</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/info.png</normaloff>:/qtgameengine/icons/info.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</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>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelEvents">
|
||||
<property name="text">
|
||||
<string>Events:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>listViewEvents</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListView" name="listViewEvents">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonAddEvent">
|
||||
<property name="toolTip">
|
||||
<string>Click here to add another event</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add Event</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonDeleteEvent">
|
||||
<property name="toolTip">
|
||||
<string>Delete the currently selected event</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonChangeEvent">
|
||||
<property name="toolTip">
|
||||
<string>Change which event has this behaviour</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Change</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ActionsContainerWidget" name="actionsWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ActionsContainerWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>widgets/actionscontainerwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>ObjectPropertiesDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>138</x>
|
||||
<y>511</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>423</x>
|
||||
<y>266</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>ObjectPropertiesDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>138</x>
|
||||
<y>511</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>423</x>
|
||||
<y>266</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,365 @@
|
||||
#include "pathpropertiesdialog.h"
|
||||
#include "ui_pathpropertiesdialog.h"
|
||||
|
||||
#include <QSpinBox>
|
||||
#include <QLabel>
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
#include <QSignalBlocker>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
#include "models/projecttreemodel.h"
|
||||
#include "models/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);
|
||||
m_ui->statusbar->addWidget(m_labelY, 1);
|
||||
m_labelArea->setFrameStyle(QFrame::Sunken);
|
||||
m_ui->statusbar->addWidget(m_labelArea, 4);
|
||||
|
||||
{
|
||||
auto frame = new QFrame{this};
|
||||
frame->setFrameStyle(QFrame::Sunken);
|
||||
m_ui->statusbar->addPermanentWidget(frame, 2);
|
||||
}
|
||||
|
||||
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->spinBoxX, &QSpinBox::valueChanged,
|
||||
this, &PathPropertiesDialog::pointFieldsChanged);
|
||||
connect(m_ui->spinBoxY, &QSpinBox::valueChanged,
|
||||
this, &PathPropertiesDialog::pointFieldsChanged);
|
||||
connect(m_ui->spinBoxSp, &QSpinBox::valueChanged,
|
||||
this, &PathPropertiesDialog::pointFieldsChanged);
|
||||
|
||||
connect(m_ui->pushButtonAdd, &QAbstractButton::clicked,
|
||||
this, &PathPropertiesDialog::addPoint);
|
||||
connect(m_ui->pushButtonInsert, &QAbstractButton::clicked,
|
||||
this, &PathPropertiesDialog::insertPoint);
|
||||
connect(m_ui->pushButtonDelete, &QAbstractButton::clicked,
|
||||
this, &PathPropertiesDialog::deletePoint);
|
||||
|
||||
connect(m_ui->lineEditName, &QLineEdit::textChanged,
|
||||
this, &PathPropertiesDialog::changed);
|
||||
|
||||
connect(m_pointsModel.get(), &QAbstractTableModel::rowsInserted,
|
||||
this, &PathPropertiesDialog::changed);
|
||||
connect(m_pointsModel.get(), &QAbstractTableModel::rowsInserted,
|
||||
m_ui->widget, qOverload<>(&PathPointsWidget::update));
|
||||
connect(m_pointsModel.get(), &QAbstractTableModel::rowsRemoved,
|
||||
this, &PathPropertiesDialog::changed);
|
||||
connect(m_pointsModel.get(), &QAbstractTableModel::rowsRemoved,
|
||||
m_ui->widget, qOverload<>(&PathPointsWidget::update));
|
||||
connect(m_pointsModel.get(), &QAbstractTableModel::dataChanged,
|
||||
this, &PathPropertiesDialog::dataChanged);
|
||||
connect(m_pointsModel.get(), &QAbstractTableModel::dataChanged,
|
||||
this, &PathPropertiesDialog::changed);
|
||||
connect(m_pointsModel.get(), &QAbstractTableModel::dataChanged,
|
||||
m_ui->widget, qOverload<>(&PathPointsWidget::update));
|
||||
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()))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Renaming Path failed!"), tr("Renaming Path failed!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void PathPropertiesDialog::reject()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto result = QMessageBox::warning(
|
||||
this,
|
||||
tr("The Path 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 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::addPoint()
|
||||
{
|
||||
if (!m_pointsModel->insertPoint(m_points.size(), getPointFromFields()))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Could not add Point!"), tr("Could not add Point!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PathPropertiesDialog::insertPoint()
|
||||
{
|
||||
const auto index = m_ui->treeView->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
if (!m_pointsModel->insertPoint(index.row() + 1, getPointFromFields()))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Could not insert Point!"), tr("Could not insert Point!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PathPropertiesDialog::deletePoint()
|
||||
{
|
||||
const auto index = m_ui->treeView->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
if (!m_pointsModel->removeRows(index.row(), 1))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Could not remove Point!"), tr("Could not remove Point!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PathPropertiesDialog::pointFieldsChanged()
|
||||
{
|
||||
const auto index = m_ui->treeView->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
if (!m_pointsModel->updatePoint(index.row(), getPointFromFields()))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Could not update Point!"), tr("Could not update Point!"));
|
||||
return;
|
||||
}
|
||||
|
||||
changed();
|
||||
}
|
||||
|
||||
void PathPropertiesDialog::changed()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
m_unsavedChanges = true;
|
||||
updateTitle();
|
||||
}
|
||||
}
|
||||
|
||||
void PathPropertiesDialog::pathNameChanged(const Path &path)
|
||||
{
|
||||
if (&path != &m_path)
|
||||
return;
|
||||
|
||||
{
|
||||
QSignalBlocker blocker{m_ui->lineEditName};
|
||||
m_ui->lineEditName->setText(path.name);
|
||||
}
|
||||
|
||||
updateTitle();
|
||||
}
|
||||
|
||||
void PathPropertiesDialog::updateTitle()
|
||||
{
|
||||
setWindowTitle(tr("Path Properties: %0%1")
|
||||
.arg(m_path.name)
|
||||
.arg(m_unsavedChanges ? tr("*") : QString{})
|
||||
);
|
||||
}
|
||||
|
||||
void PathPropertiesDialog::updatePointFields()
|
||||
{
|
||||
const auto index = m_ui->treeView->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
const auto point = m_pointsModel->getPoint(index);
|
||||
if (!point)
|
||||
return;
|
||||
|
||||
{
|
||||
QSignalBlocker blocker{m_ui->spinBoxX};
|
||||
m_ui->spinBoxX->setValue(point->point.x());
|
||||
}
|
||||
{
|
||||
QSignalBlocker blocker{m_ui->spinBoxY};
|
||||
m_ui->spinBoxY->setValue(point->point.y());
|
||||
}
|
||||
{
|
||||
QSignalBlocker blocker{m_ui->spinBoxSp};
|
||||
m_ui->spinBoxSp->setValue(point->sp);
|
||||
}
|
||||
}
|
||||
|
||||
Path::Point PathPropertiesDialog::getPointFromFields() const
|
||||
{
|
||||
return Path::Point{
|
||||
.point{
|
||||
m_ui->spinBoxX->value(),
|
||||
m_ui->spinBoxY->value()
|
||||
},
|
||||
.sp = m_ui->spinBoxSp->value()
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
|
||||
class QSpinBox;
|
||||
class QLabel;
|
||||
namespace Ui { class PathPropertiesDialog; }
|
||||
class ProjectTreeModel;
|
||||
class PathPointsModel;
|
||||
|
||||
class PathPropertiesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PathPropertiesDialog(Path &path, ProjectTreeModel &projectModel, QWidget *parent = nullptr);
|
||||
~PathPropertiesDialog();
|
||||
|
||||
void accept() override;
|
||||
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 addPoint();
|
||||
void insertPoint();
|
||||
void deletePoint();
|
||||
|
||||
void pointFieldsChanged();
|
||||
void changed();
|
||||
|
||||
void pathNameChanged(const Path &path);
|
||||
|
||||
private:
|
||||
void updateTitle();
|
||||
void updatePointFields();
|
||||
|
||||
Path::Point getPointFromFields() const;
|
||||
|
||||
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;
|
||||
};
|
||||
@@ -0,0 +1,639 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PathPropertiesDialog</class>
|
||||
<widget class="QDialog" name="PathPropertiesDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>921</width>
|
||||
<height>576</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Path Properties</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/path-file.png</normaloff>:/qtgameengine/icons/path-file.png</iconset>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<property name="movable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<addaction name="actionOk"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionUndo"/>
|
||||
<addaction name="separator"/>
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelName">
|
||||
<property name="text">
|
||||
<string>&Name:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditName</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEditName">
|
||||
<property name="toolTip">
|
||||
<string>The name of the path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="treeView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelX">
|
||||
<property name="text">
|
||||
<string>&X:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxX</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<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">
|
||||
<property name="text">
|
||||
<string>&Y:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxY</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<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">
|
||||
<property name="text">
|
||||
<string>s&p:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxSp</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<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>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<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>
|
||||
</widget>
|
||||
</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>
|
||||
</widget>
|
||||
</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>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<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>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonStraight">
|
||||
<property name="text">
|
||||
<string>&Straight lines</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonSmooth">
|
||||
<property name="text">
|
||||
<string>S&mooth curves</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelPrecision">
|
||||
<property name="text">
|
||||
<string>P&recision:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxPrecision</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxPrecision">
|
||||
<property name="toolTip">
|
||||
<string>Precision with which to create smooth curves</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxClosed">
|
||||
<property name="text">
|
||||
<string>Closed</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7" stretch="1,0">
|
||||
<item>
|
||||
<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"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionOk">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/ok.png</normaloff>:/qtgameengine/icons/ok.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>OK</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Close the form, saving the changes</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUndo">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/undo.png</normaloff>:/qtgameengine/icons/undo.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Undo</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Undo the last changes in the path</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionClear">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/new.png</normaloff>:/qtgameengine/icons/new.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Clear the path</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionReverse">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/rotate.png</normaloff>:/qtgameengine/icons/rotate.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reverse</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Reverse the path</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShift">
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/move.png</normaloff>:/qtgameengine/icons/move.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Shift</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<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>widgets/pathpointswidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>actionOk</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>PathPropertiesDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>363</x>
|
||||
<y>224</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +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);
|
||||
|
||||
#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;
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class PreferencesDialog; }
|
||||
|
||||
class PreferencesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PreferencesDialog(QWidget *parent = nullptr);
|
||||
~PreferencesDialog();
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Ui::PreferencesDialog> m_ui;
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PreferencesDialog</class>
|
||||
<widget class="QDialog" name="PreferencesDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Preferences</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<widget class="QWidget" name="tabGeneral">
|
||||
<attribute name="title">
|
||||
<string>General</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabForms">
|
||||
<attribute name="title">
|
||||
<string>Forms</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabScriptsAndCode">
|
||||
<attribute name="title">
|
||||
<string>Scripts and Code</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabEditors">
|
||||
<attribute name="title">
|
||||
<string>Editors</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>PreferencesDialog</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>PreferencesDialog</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>
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "roompropertiesdialog.h"
|
||||
#include "ui_roompropertiesdialog.h"
|
||||
|
||||
RoomPropertiesDialog::RoomPropertiesDialog(Room &room, ProjectTreeModel &projectModel, QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::RoomPropertiesDialog>()}
|
||||
{
|
||||
Q_UNUSED(room)
|
||||
Q_UNUSED(projectModel)
|
||||
|
||||
m_ui->setupUi(this);
|
||||
}
|
||||
|
||||
RoomPropertiesDialog::~RoomPropertiesDialog() = default;
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class RoomPropertiesDialog; }
|
||||
struct Room;
|
||||
class ProjectTreeModel;
|
||||
|
||||
class RoomPropertiesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RoomPropertiesDialog(Room &room, ProjectTreeModel &projectModel, QWidget *parent = nullptr);
|
||||
~RoomPropertiesDialog();
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Ui::RoomPropertiesDialog> m_ui;
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RoomPropertiesDialog</class>
|
||||
<widget class="QDialog" name="RoomPropertiesDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Room Properties</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/room-file.png</normaloff>:/qtgameengine/icons/room-file.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,70 @@
|
||||
#include "scriptpropertiesdialog.h"
|
||||
#include "ui_codeeditordialog.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
#include "models/projecttreemodel.h"
|
||||
|
||||
ScriptPropertiesDialog::ScriptPropertiesDialog(Script &script, ProjectTreeModel &projectModel, QWidget *parent) :
|
||||
CodeEditorDialog{tr("Script Properties: %0").arg(script.name), parent},
|
||||
m_script{script},
|
||||
m_projectModel{projectModel},
|
||||
m_lineEditName{new QLineEdit{this}}
|
||||
{
|
||||
{
|
||||
auto label = new QLabel{tr("&Name:"), this};
|
||||
label->setBuddy(m_lineEditName);
|
||||
addToolbarWidget(label);
|
||||
}
|
||||
m_lineEditName->setMaximumWidth(100);
|
||||
addToolbarWidget(m_lineEditName);
|
||||
|
||||
|
||||
m_lineEditName->setText(m_script.name);
|
||||
setScript(m_script.script);
|
||||
|
||||
connect(&m_projectModel, &ProjectTreeModel::scriptNameChanged,
|
||||
this, &ScriptPropertiesDialog::scriptNameChanged);
|
||||
|
||||
connect(m_lineEditName, &QLineEdit::textChanged,
|
||||
this, &ScriptPropertiesDialog::changed);
|
||||
}
|
||||
|
||||
void ScriptPropertiesDialog::accept()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_script.name != m_lineEditName->text())
|
||||
{
|
||||
if (!m_projectModel.rename<Script>(m_script, m_lineEditName->text()))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Renaming Script failed!"), tr("Renaming Script failed!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_script.script = script();
|
||||
|
||||
CodeEditorDialog::accept();
|
||||
}
|
||||
|
||||
void ScriptPropertiesDialog::scriptNameChanged(const Script &script)
|
||||
{
|
||||
if (&script != &m_script)
|
||||
return;
|
||||
|
||||
setTitle(tr("Script Properties: %0").arg(script.name));
|
||||
|
||||
{
|
||||
QSignalBlocker blocker{m_lineEditName};
|
||||
m_lineEditName->setText(script.name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "codeeditordialog.h"
|
||||
|
||||
class QLineEdit;
|
||||
struct Script;
|
||||
class ProjectTreeModel;
|
||||
|
||||
class ScriptPropertiesDialog : public CodeEditorDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScriptPropertiesDialog(Script &script, ProjectTreeModel &projectModel, QWidget *parent = nullptr);
|
||||
|
||||
void accept() override;
|
||||
|
||||
private slots:
|
||||
void scriptNameChanged(const Script &script);
|
||||
|
||||
private:
|
||||
Script &m_script;
|
||||
ProjectTreeModel &m_projectModel;
|
||||
|
||||
QLineEdit * const m_lineEditName;
|
||||
};
|
||||
@@ -0,0 +1,248 @@
|
||||
#include "soundpropertiesdialog.h"
|
||||
#include "ui_soundpropertiesdialog.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
#include "models/projecttreemodel.h"
|
||||
|
||||
SoundPropertiesDialog::SoundPropertiesDialog(Sound &sound, ProjectTreeModel &projectModel, QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::SoundPropertiesDialog>()},
|
||||
m_sound{sound},
|
||||
m_projectModel{projectModel},
|
||||
m_path{m_sound.path}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
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"});
|
||||
|
||||
m_ui->lineEditName->setText(m_sound.name);
|
||||
if (!m_sound.path.isEmpty())
|
||||
{
|
||||
m_ui->labelFilename->setText(tr("Filename: %0").arg(QFileInfo{m_sound.path}.fileName()));
|
||||
m_soundEffect.setSource(QUrl::fromLocalFile(m_sound.path));
|
||||
}
|
||||
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);
|
||||
m_ui->checkBoxEcho->setChecked(m_sound.effects.echo);
|
||||
m_ui->checkBoxReverb->setChecked(m_sound.effects.reverb);
|
||||
m_ui->horizontalSliderVolume->setValue(m_sound.volume);
|
||||
m_ui->horizontalSliderPan->setValue(m_sound.pan);
|
||||
m_ui->checkBoxPreload->setChecked(m_sound.preload);
|
||||
|
||||
connect(&m_projectModel, &ProjectTreeModel::soundNameChanged,
|
||||
this, &SoundPropertiesDialog::soundNameChanged);
|
||||
|
||||
connect(m_ui->pushButtonLoad, &QAbstractButton::clicked,
|
||||
this, &SoundPropertiesDialog::loadSound);
|
||||
connect(m_ui->pushButtonPlay, &QAbstractButton::clicked,
|
||||
this, &SoundPropertiesDialog::playSound);
|
||||
connect(m_ui->pushButtonStop, &QAbstractButton::clicked,
|
||||
this, &SoundPropertiesDialog::stopSound);
|
||||
connect(m_ui->pushButtonSave, &QAbstractButton::clicked,
|
||||
this, &SoundPropertiesDialog::saveSound);
|
||||
connect(m_ui->pushButtonEdit, &QAbstractButton::clicked,
|
||||
this, &SoundPropertiesDialog::editSound);
|
||||
|
||||
connect(m_ui->lineEditName, &QLineEdit::textChanged,
|
||||
this, &SoundPropertiesDialog::changed);
|
||||
connect(m_ui->radioButtonNormal, &QRadioButton::toggled,
|
||||
this, &SoundPropertiesDialog::changed);
|
||||
connect(m_ui->radioButtonMusic, &QRadioButton::toggled,
|
||||
this, &SoundPropertiesDialog::changed);
|
||||
connect(m_ui->radioButton3D, &QRadioButton::toggled,
|
||||
this, &SoundPropertiesDialog::changed);
|
||||
connect(m_ui->radioButtonMultimedia, &QRadioButton::toggled,
|
||||
this, &SoundPropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxChorus, &QCheckBox::stateChanged,
|
||||
this, &SoundPropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxFlanger, &QCheckBox::stateChanged,
|
||||
this, &SoundPropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxGargle, &QCheckBox::stateChanged,
|
||||
this, &SoundPropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxEcho, &QCheckBox::stateChanged,
|
||||
this, &SoundPropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxReverb, &QCheckBox::stateChanged,
|
||||
this, &SoundPropertiesDialog::changed);
|
||||
connect(m_ui->horizontalSliderVolume, &QSlider::valueChanged,
|
||||
this, &SoundPropertiesDialog::changed);
|
||||
connect(m_ui->horizontalSliderPan, &QSlider::valueChanged,
|
||||
this, &SoundPropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxPreload, &QCheckBox::stateChanged,
|
||||
this, &SoundPropertiesDialog::changed);
|
||||
}
|
||||
|
||||
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()))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Renaming Sound failed!"), tr("Renaming Sound failed!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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 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();
|
||||
m_sound.effects.gargle = m_ui->checkBoxGargle->isChecked();
|
||||
m_sound.effects.echo = m_ui->checkBoxEcho->isChecked();
|
||||
m_sound.effects.reverb = m_ui->checkBoxReverb->isChecked();
|
||||
m_sound.volume = m_ui->horizontalSliderVolume->value();
|
||||
m_sound.pan = m_ui->horizontalSliderPan->value();
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void SoundPropertiesDialog::reject()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto result = QMessageBox::warning(
|
||||
this,
|
||||
tr("The Sound 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 SoundPropertiesDialog::loadSound()
|
||||
{
|
||||
auto path = QFileDialog::getOpenFileName(this, tr("Open a Sound File..."));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
if (QFile file{path}; !file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Could not load Sound!"), tr("Could not load Sound!") + "\n\n" + file.errorString());
|
||||
return;
|
||||
}
|
||||
|
||||
m_path = std::move(path);
|
||||
changed();
|
||||
m_ui->labelFilename->setText(tr("Filename: %0").arg(QFileInfo{m_path}.fileName()));
|
||||
m_soundEffect.setSource(QUrl::fromLocalFile(m_path));
|
||||
}
|
||||
|
||||
void SoundPropertiesDialog::saveSound()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
const auto savePath = QFileDialog::getSaveFileName(this, tr("Save a Sound File..."), m_sound.name + ".wav", tr("WAV Files (*.wav)"));
|
||||
if (savePath.isEmpty())
|
||||
return;
|
||||
|
||||
if (!QFile::copy(m_path, savePath))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Could not save Sound!"), tr("Could not save Sound!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundPropertiesDialog::playSound()
|
||||
{
|
||||
m_soundEffect.play();
|
||||
}
|
||||
|
||||
void SoundPropertiesDialog::stopSound()
|
||||
{
|
||||
m_soundEffect.stop();
|
||||
}
|
||||
|
||||
void SoundPropertiesDialog::editSound()
|
||||
{
|
||||
QMessageBox::critical(this, tr("Setup not complete"), tr("No valid external editor has been indicated for this type of sound. You can specify this editor in the Preferences."));
|
||||
}
|
||||
|
||||
void SoundPropertiesDialog::changed()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
m_unsavedChanges = true;
|
||||
updateTitle();
|
||||
}
|
||||
}
|
||||
|
||||
void SoundPropertiesDialog::soundNameChanged(const Sound &sound)
|
||||
{
|
||||
if (&sound != &m_sound)
|
||||
return;
|
||||
|
||||
{
|
||||
QSignalBlocker blocker{m_ui->lineEditName};
|
||||
m_ui->lineEditName->setText(sound.name);
|
||||
}
|
||||
|
||||
updateTitle();
|
||||
}
|
||||
|
||||
void SoundPropertiesDialog::updateTitle()
|
||||
{
|
||||
setWindowTitle(tr("Sound Properties: %0%1")
|
||||
.arg(m_sound.name)
|
||||
.arg(m_unsavedChanges ? tr("*") : QString{})
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QString>
|
||||
#include <QSoundEffect>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class SoundPropertiesDialog; }
|
||||
struct Sound;
|
||||
class ProjectTreeModel;
|
||||
|
||||
class SoundPropertiesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SoundPropertiesDialog(Sound &sound, ProjectTreeModel &projectModel, QWidget *parent = nullptr);
|
||||
~SoundPropertiesDialog();
|
||||
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
|
||||
private slots:
|
||||
void loadSound();
|
||||
void saveSound();
|
||||
void playSound();
|
||||
void stopSound();
|
||||
void editSound();
|
||||
|
||||
void changed();
|
||||
|
||||
void soundNameChanged(const Sound &sound);
|
||||
|
||||
private:
|
||||
void updateTitle();
|
||||
|
||||
const std::unique_ptr<Ui::SoundPropertiesDialog> m_ui;
|
||||
|
||||
Sound &m_sound;
|
||||
ProjectTreeModel &m_projectModel;
|
||||
|
||||
bool m_unsavedChanges{};
|
||||
|
||||
QString m_path;
|
||||
|
||||
QSoundEffect m_soundEffect;
|
||||
};
|
||||
@@ -0,0 +1,364 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SoundPropertiesDialog</class>
|
||||
<widget class="QDialog" name="SoundPropertiesDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>239</width>
|
||||
<height>534</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Sound Properties</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/sound-file.png</normaloff>:/qtgameengine/icons/sound-file.png</iconset>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelName">
|
||||
<property name="text">
|
||||
<string>&Name:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditName</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEditName">
|
||||
<property name="toolTip">
|
||||
<string>The name of the sound</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<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>&Load Sound</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/open.png</normaloff>:/qtgameengine/icons/open.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonPlay">
|
||||
<property name="toolTip">
|
||||
<string>Play the sound</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/run.png</normaloff>:/qtgameengine/icons/run.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonStop">
|
||||
<property name="toolTip">
|
||||
<string>Stop the sound</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/exit.png</normaloff>:/qtgameengine/icons/exit.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonSave">
|
||||
<property name="toolTip">
|
||||
<string>Save the sound to a file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Sa&ve Sound</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/save.png</normaloff>:/qtgameengine/icons/save.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFilename">
|
||||
<property name="text">
|
||||
<string>Filename:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonNormal">
|
||||
<property name="text">
|
||||
<string>Normal Sound</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonMusic">
|
||||
<property name="text">
|
||||
<string>Background Music</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButton3D">
|
||||
<property name="text">
|
||||
<string>3D Sound</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonMultimedia">
|
||||
<property name="text">
|
||||
<string>Use multimedia player</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</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>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBoxFlanger">
|
||||
<property name="text">
|
||||
<string>Flanger</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkBoxChorus">
|
||||
<property name="text">
|
||||
<string>Chorus</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="checkBoxGargle">
|
||||
<property name="text">
|
||||
<string>Gargle</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="checkBoxEcho">
|
||||
<property name="text">
|
||||
<string>Echo</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkBoxReverb">
|
||||
<property name="text">
|
||||
<string>Reverb</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelVolume">
|
||||
<property name="text">
|
||||
<string>Volume:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>horizontalSliderVolume</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelPan">
|
||||
<property name="text">
|
||||
<string>Pan:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>horizontalSliderPan</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</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>&Preload</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</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="pushButtonEdit">
|
||||
<property name="toolTip">
|
||||
<string>Edit the sound using an external sound editor</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Edit Sound</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/sound.png</normaloff>:/qtgameengine/icons/sound.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</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>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>SoundPropertiesDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>119</x>
|
||||
<y>480</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>119</x>
|
||||
<y>266</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>SoundPropertiesDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>119</x>
|
||||
<y>512</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>119</x>
|
||||
<y>266</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,244 @@
|
||||
#include "spritepropertiesdialog.h"
|
||||
#include "ui_spritepropertiesdialog.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
#include <QSignalBlocker>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
#include "models/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_pixmaps{m_sprite.pixmaps}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
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"});
|
||||
|
||||
m_ui->lineEditName->setText(m_sprite.name);
|
||||
updateSpriteInfo();
|
||||
m_ui->spinBoxOriginX->setValue(m_sprite.origin.x);
|
||||
m_ui->spinBoxOriginY->setValue(m_sprite.origin.y);
|
||||
m_ui->checkBoxPreciseCollisionChecking->setChecked(m_sprite.preciseCollisionChecking);
|
||||
m_ui->checkBoxSeparateCollisionMasks->setChecked(m_sprite.separateCollisionMasks);
|
||||
|
||||
connect(&m_projectModel, &ProjectTreeModel::spriteNameChanged,
|
||||
this, &SpritePropertiesDialog::spriteNameChanged);
|
||||
|
||||
connect(m_ui->pushButtonLoad, &QAbstractButton::clicked,
|
||||
this, &SpritePropertiesDialog::loadSprite);
|
||||
connect(m_ui->pushButtonSave, &QAbstractButton::clicked,
|
||||
this, &SpritePropertiesDialog::saveSprite);
|
||||
connect(m_ui->pushButtonEdit, &QAbstractButton::clicked,
|
||||
this, &SpritePropertiesDialog::editSprite);
|
||||
connect(m_ui->pushButtonCenterOrigin, &QAbstractButton::clicked,
|
||||
this, &SpritePropertiesDialog::centerOrigin);
|
||||
connect(m_ui->pushButtonModifyCollisionmask, &QAbstractButton::clicked,
|
||||
this, &SpritePropertiesDialog::modifyMask);
|
||||
|
||||
connect(m_ui->lineEditName, &QLineEdit::textChanged,
|
||||
this, &SpritePropertiesDialog::changed);
|
||||
connect(m_ui->spinBoxOriginX, &QSpinBox::valueChanged,
|
||||
this, &SpritePropertiesDialog::changed);
|
||||
connect(m_ui->spinBoxOriginY, &QSpinBox::valueChanged,
|
||||
this, &SpritePropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxPreciseCollisionChecking, &QCheckBox::stateChanged,
|
||||
this, &SpritePropertiesDialog::changed);
|
||||
connect(m_ui->checkBoxSeparateCollisionMasks, &QCheckBox::stateChanged,
|
||||
this, &SpritePropertiesDialog::changed);
|
||||
}
|
||||
|
||||
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()))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Renaming Sprite failed!"), tr("Renaming Sprite failed!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_projectModel.setSpritePixmaps(m_sprite, std::move(m_pixmaps)))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Setting Sprite pixmaps failed!"), tr("Setting Sprite pixmaps failed!"));
|
||||
return;
|
||||
}
|
||||
|
||||
m_sprite.origin.x = m_ui->spinBoxOriginX->value();
|
||||
m_sprite.origin.y = m_ui->spinBoxOriginY->value();
|
||||
m_sprite.preciseCollisionChecking = m_ui->checkBoxPreciseCollisionChecking->isChecked();
|
||||
m_sprite.separateCollisionMasks = m_ui->checkBoxSeparateCollisionMasks->isChecked();
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void SpritePropertiesDialog::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 SpritePropertiesDialog::loadSprite()
|
||||
{
|
||||
const auto path = QFileDialog::getOpenFileName(this, tr("Open a Sprite Image..."), {},
|
||||
QStringLiteral("%0 (*.png);;%1 (*.bmp);;%2 (*.tiff);;%3 (*.jpg *.jpeg);;%4 (*)")
|
||||
.arg(tr("PNG Files"))
|
||||
.arg(tr("BMP Files"))
|
||||
.arg(tr("TIFF Files"))
|
||||
.arg(tr("JPEG Files"))
|
||||
.arg(tr("All Files"))
|
||||
);
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
QPixmap pixmap;
|
||||
if (!pixmap.load(path))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Could not load sprite!"), tr("Could not load sprite!"));
|
||||
return;
|
||||
}
|
||||
|
||||
m_pixmaps = std::vector<QPixmap>{ std::move(pixmap) };
|
||||
changed();
|
||||
updateSpriteInfo();
|
||||
}
|
||||
|
||||
void SpritePropertiesDialog::saveSprite()
|
||||
{
|
||||
if (m_pixmaps.empty() || m_pixmaps.front().isNull())
|
||||
{
|
||||
QMessageBox::warning(this, tr("No sprites available to save!"), tr("No sprites available to save!"));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto path = QFileDialog::getSaveFileName(this, tr("Save a Sprite Image..."), m_sprite.name + ".png",
|
||||
QStringLiteral("%0 (*.png);;%1 (*.bmp);;%2 (*.tiff);;%3 (*.jpg *.jpeg);;%4 (*)")
|
||||
.arg(tr("PNG Files"))
|
||||
.arg(tr("BMP Files"))
|
||||
.arg(tr("TIFF Files"))
|
||||
.arg(tr("JPEG Files"))
|
||||
.arg(tr("All Files"))
|
||||
);
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
if (!m_pixmaps.front().save(path))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Could not save Sprite!"), tr("Could not save Sprite!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SpritePropertiesDialog::editSprite()
|
||||
{
|
||||
EditSpriteDialog dialog{m_pixmaps, m_sprite.name, this};
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
m_pixmaps = dialog.pixmaps();
|
||||
changed();
|
||||
updateSpriteInfo();
|
||||
}
|
||||
}
|
||||
|
||||
void SpritePropertiesDialog::centerOrigin()
|
||||
{
|
||||
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(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()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
m_unsavedChanges = true;
|
||||
updateTitle();
|
||||
}
|
||||
}
|
||||
|
||||
void SpritePropertiesDialog::spriteNameChanged(const Sprite &sprite)
|
||||
{
|
||||
if (&sprite != &m_sprite)
|
||||
return;
|
||||
|
||||
{
|
||||
QSignalBlocker blocker{m_ui->lineEditName};
|
||||
m_ui->lineEditName->setText(sprite.name);
|
||||
}
|
||||
|
||||
updateTitle();
|
||||
}
|
||||
|
||||
void SpritePropertiesDialog::updateTitle()
|
||||
{
|
||||
setWindowTitle(tr("Sprite Properties: %0%1")
|
||||
.arg(m_sprite.name)
|
||||
.arg(m_unsavedChanges ? tr("*") : QString{})
|
||||
);
|
||||
}
|
||||
|
||||
void SpritePropertiesDialog::updateSpriteInfo()
|
||||
{
|
||||
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()));
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ui { class SpritePropertiesDialog; }
|
||||
struct Sprite;
|
||||
class ProjectTreeModel;
|
||||
|
||||
class SpritePropertiesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SpritePropertiesDialog(Sprite &sprite, ProjectTreeModel &projectModel, QWidget *parent = nullptr);
|
||||
~SpritePropertiesDialog();
|
||||
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
|
||||
private slots:
|
||||
void loadSprite();
|
||||
void saveSprite();
|
||||
void editSprite();
|
||||
void centerOrigin();
|
||||
void modifyMask();
|
||||
|
||||
void changed();
|
||||
|
||||
void spriteNameChanged(const Sprite &sprite);
|
||||
|
||||
private:
|
||||
void updateTitle();
|
||||
void updateSpriteInfo();
|
||||
|
||||
const std::unique_ptr<Ui::SpritePropertiesDialog> m_ui;
|
||||
|
||||
Sprite &m_sprite;
|
||||
ProjectTreeModel &m_projectModel;
|
||||
|
||||
bool m_unsavedChanges{};
|
||||
|
||||
std::vector<QPixmap> m_pixmaps;
|
||||
};
|
||||
@@ -0,0 +1,378 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SpritePropertiesDialog</class>
|
||||
<widget class="QDialog" name="SpritePropertiesDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>560</width>
|
||||
<height>344</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Sprite Properties</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/sprite-file.png</normaloff>:/qtgameengine/icons/sprite-file.png</iconset>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,1">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelName">
|
||||
<property name="text">
|
||||
<string>&Name:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditName</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEditName">
|
||||
<property name="toolTip">
|
||||
<string>The name of the sprite</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<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>
|
||||
<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>&Load Sprite</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/open.png</normaloff>:/qtgameengine/icons/open.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonSave">
|
||||
<property name="toolTip">
|
||||
<string>Save the sprite to a file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Save Sprite</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/save.png</normaloff>:/qtgameengine/icons/save.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonEdit">
|
||||
<property name="toolTip">
|
||||
<string>Edit the sprite</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Edit Sprite</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/edit.png</normaloff>:/qtgameengine/icons/edit.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelHeight">
|
||||
<property name="text">
|
||||
<string>Height:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelWidth">
|
||||
<property name="text">
|
||||
<string>Width:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelSubimages">
|
||||
<property name="text">
|
||||
<string>Number of subimages:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxOrigin">
|
||||
<property name="title">
|
||||
<string>Origin</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelOriginX">
|
||||
<property name="text">
|
||||
<string>&X:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxOriginX</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<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">
|
||||
<property name="text">
|
||||
<string>&Y:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBoxOriginY</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<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>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<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="pushButtonCenterOrigin">
|
||||
<property name="toolTip">
|
||||
<string>Put the origin in the center of the image</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Center</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</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>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBoxCollisionChecking">
|
||||
<property name="title">
|
||||
<string>Collision Checking</string>
|
||||
</property>
|
||||
<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>&Precise collision checking</string>
|
||||
</property>
|
||||
</widget>
|
||||
</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&te Collision Masks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonModifyCollisionmask">
|
||||
<property name="toolTip">
|
||||
<string>Modify additional options for the collision mask</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Modify Mask</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QLabel" name="labelPreview">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>124</width>
|
||||
<height>324</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>SpritePropertiesDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>108</x>
|
||||
<y>321</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>279</x>
|
||||
<y>171</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>SpritePropertiesDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>108</x>
|
||||
<y>321</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>279</x>
|
||||
<y>171</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,293 @@
|
||||
#include "timelinepropertiesdialog.h"
|
||||
#include "ui_timelinepropertiesdialog.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
#include <QInputDialog>
|
||||
#include <QMenu>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "models/projecttreemodel.h"
|
||||
#include "models/timelinemomentsmodel.h"
|
||||
#include "dialogs/deletemomentsdialog.h"
|
||||
|
||||
TimeLinePropertiesDialog::TimeLinePropertiesDialog(TimeLine &timeLine, ProjectTreeModel &projectModel, QWidget *parent) :
|
||||
QDialog{parent},
|
||||
m_ui{std::make_unique<Ui::TimeLinePropertiesDialog>()},
|
||||
m_timeLine{timeLine},
|
||||
m_projectModel{projectModel},
|
||||
m_moments{timeLine.moments},
|
||||
m_momentsModel{std::make_unique<TimelineMomentsModel>(m_moments, this)}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
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"});
|
||||
|
||||
m_ui->lineEditName->setText(m_timeLine.name);
|
||||
|
||||
m_ui->listViewMoments->setModel(m_momentsModel.get());
|
||||
|
||||
connect(&m_projectModel, &ProjectTreeModel::timeLineNameChanged,
|
||||
this, &TimeLinePropertiesDialog::timeLineNameChanged);
|
||||
|
||||
connect(m_momentsModel.get(), &QAbstractItemModel::modelReset,
|
||||
this, &TimeLinePropertiesDialog::changed);
|
||||
connect(m_momentsModel.get(), &QAbstractItemModel::rowsInserted,
|
||||
this, &TimeLinePropertiesDialog::changed);
|
||||
connect(m_momentsModel.get(), &QAbstractItemModel::dataChanged,
|
||||
this, &TimeLinePropertiesDialog::changed);
|
||||
connect(m_momentsModel.get(), &QAbstractItemModel::rowsRemoved,
|
||||
this, &TimeLinePropertiesDialog::changed);
|
||||
|
||||
connect(m_ui->lineEditName, &QLineEdit::textChanged,
|
||||
this, &TimeLinePropertiesDialog::changed);
|
||||
|
||||
connect(m_ui->pushButtonAdd, &QAbstractButton::clicked,
|
||||
this, &TimeLinePropertiesDialog::addMoment);
|
||||
connect(m_ui->pushButtonChange, &QAbstractButton::clicked,
|
||||
this, &TimeLinePropertiesDialog::changeMoment);
|
||||
connect(m_ui->pushButtonDelete, &QAbstractButton::clicked,
|
||||
this, &TimeLinePropertiesDialog::deleteMoments);
|
||||
connect(m_ui->pushButtonClear, &QAbstractButton::clicked,
|
||||
this, &TimeLinePropertiesDialog::clearMoments);
|
||||
connect(m_ui->pushButtonShift, &QAbstractButton::clicked,
|
||||
this, &TimeLinePropertiesDialog::shiftMoments);
|
||||
connect(m_ui->pushButtonDuplicate, &QAbstractButton::clicked,
|
||||
this, &TimeLinePropertiesDialog::duplicateMoments);
|
||||
connect(m_ui->pushButtonSpread, &QAbstractButton::clicked,
|
||||
this, &TimeLinePropertiesDialog::spreadMoments);
|
||||
connect(m_ui->pushButtonMerge, &QAbstractButton::clicked,
|
||||
this, &TimeLinePropertiesDialog::mergeMoments);
|
||||
connect(m_ui->pushButtonShowInformation, &QAbstractButton::clicked,
|
||||
this, &TimeLinePropertiesDialog::showInformation);
|
||||
|
||||
connect(m_ui->listViewMoments->selectionModel(), &QItemSelectionModel::currentChanged,
|
||||
this, &TimeLinePropertiesDialog::currentMomentChanged);
|
||||
connect(m_momentsModel.get(), &QAbstractItemModel::modelAboutToBeReset,
|
||||
m_ui->listViewMoments, [listView=m_ui->listViewMoments](){
|
||||
listView->setCurrentIndex(QModelIndex{});
|
||||
});
|
||||
connect(m_ui->listViewMoments, &QListView::customContextMenuRequested,
|
||||
this, &TimeLinePropertiesDialog::momentsContextMenuRequested);
|
||||
|
||||
connect(m_ui->actionsWidget, &ActionsContainerWidget::changed,
|
||||
this, &TimeLinePropertiesDialog::changed);
|
||||
}
|
||||
|
||||
TimeLinePropertiesDialog::~TimeLinePropertiesDialog() = default;
|
||||
|
||||
void TimeLinePropertiesDialog::accept()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_timeLine.name != m_ui->lineEditName->text())
|
||||
{
|
||||
if (!m_projectModel.rename<TimeLine>(m_timeLine, m_ui->lineEditName->text()))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Renaming Time Line failed!"), tr("Renaming Time Line failed!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_timeLine.moments = m_moments;
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::reject()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto result = QMessageBox::warning(
|
||||
this,
|
||||
tr("The Time Line 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 TimeLinePropertiesDialog::changed()
|
||||
{
|
||||
if (!m_unsavedChanges)
|
||||
{
|
||||
m_unsavedChanges = true;
|
||||
updateTitle();
|
||||
}
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::timeLineNameChanged(const TimeLine &timeLine)
|
||||
{
|
||||
if (&timeLine != &m_timeLine)
|
||||
return;
|
||||
|
||||
{
|
||||
QSignalBlocker blocker{m_ui->lineEditName};
|
||||
m_ui->lineEditName->setText(timeLine.name);
|
||||
}
|
||||
|
||||
updateTitle();
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::addMoment()
|
||||
{
|
||||
TimeLine::moment_key_t newMoment{};
|
||||
for (const auto &moment : m_moments)
|
||||
if (moment.first >= newMoment)
|
||||
newMoment = moment.first + 1;
|
||||
|
||||
bool ok;
|
||||
const auto moment = QInputDialog::getInt(this, tr("Adding a Moment"), tr("Indicate the moment:"), newMoment, 0, std::numeric_limits<TimeLine::moment_key_t>::max(), 1, &ok);
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
if (!m_momentsModel->addMoment(moment))
|
||||
QMessageBox::warning(this, tr("Could not add Moment!"), tr("Could not add Moment!"));
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::changeMoment()
|
||||
{
|
||||
const auto index = m_ui->listViewMoments->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
const auto moment = m_momentsModel->getMoment(index);
|
||||
if (!moment)
|
||||
return;
|
||||
|
||||
bool ok;
|
||||
const auto newMoment = QInputDialog::getInt(this, tr("Changing a Moment"), tr("Indicate the moment:"), moment->first, 0, std::numeric_limits<TimeLine::moment_key_t>::max(), 1, &ok);
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
if (!m_momentsModel->changeMoment(moment->first, newMoment))
|
||||
QMessageBox::warning(this, tr("Could not change Moment!"), tr("Could not change Moment!"));
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::deleteMoments()
|
||||
{
|
||||
if (m_moments.empty())
|
||||
return;
|
||||
|
||||
std::optional<TimeLine::moment_key_t> momentKey;
|
||||
|
||||
if (const auto index = m_ui->listViewMoments->currentIndex(); index.isValid())
|
||||
if (const auto moment = m_momentsModel->getMoment(index); moment)
|
||||
momentKey = moment->first;
|
||||
|
||||
DeleteMomentsDialog dialog = momentKey ? DeleteMomentsDialog{*momentKey, *momentKey, this} : DeleteMomentsDialog{this};
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
if (dialog.fromMoment() > dialog.tillMoment())
|
||||
{
|
||||
QMessageBox::warning(this, tr("Invalid input!"), tr("Invalid input!") + "\n\n" + tr("From moment cannot be greater than Till moment!"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_momentsModel->removeRows(dialog.fromMoment(), dialog.tillMoment() - dialog.fromMoment() + 1))
|
||||
QMessageBox::warning(this, tr("Could not remove Moments!"), tr("Could not remove Moments!"));
|
||||
}
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::clearMoments()
|
||||
{
|
||||
if (m_moments.empty())
|
||||
return;
|
||||
if (QMessageBox::question(this, tr("Confirm"), tr("Are you sure, that you really want to remove all Moments?")) != QMessageBox::Yes)
|
||||
return;
|
||||
if (!m_momentsModel->clearMoments())
|
||||
QMessageBox::warning(this, tr("Could not clear Moments!"), tr("Could not clear Moments!"));
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::shiftMoments()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::duplicateMoments()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::spreadMoments()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::mergeMoments()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::showInformation()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::currentMomentChanged(const QModelIndex &index)
|
||||
{
|
||||
qDebug() << index.isValid() << index.row();
|
||||
|
||||
if (index.isValid())
|
||||
{
|
||||
if (auto moment = m_momentsModel->getMoment(index))
|
||||
m_ui->actionsWidget->setActionsContainer(&moment->second);
|
||||
else
|
||||
goto none;
|
||||
}
|
||||
else
|
||||
{
|
||||
none:
|
||||
m_ui->actionsWidget->setActionsContainer(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::momentsContextMenuRequested(const QPoint &pos)
|
||||
{
|
||||
const auto index = m_ui->listViewMoments->indexAt(pos);
|
||||
auto moment = index.isValid() ? m_momentsModel->getMoment(index) : nullptr;
|
||||
|
||||
QMenu menu{this};
|
||||
menu.addAction(tr("&Add Moment"), this, &TimeLinePropertiesDialog::addMoment);
|
||||
menu.addAction(tr("&Change Moment"), this, &TimeLinePropertiesDialog::changeMoment)->setEnabled(moment);
|
||||
menu.addAction(tr("&Delete Moment"), this, &TimeLinePropertiesDialog::deleteMoments)->setEnabled(moment);
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("&Shift Moments"), this, &TimeLinePropertiesDialog::shiftMoments)->setEnabled(moment);
|
||||
menu.addAction(tr("&Merge Moments"), this, &TimeLinePropertiesDialog::mergeMoments)->setEnabled(moment);
|
||||
menu.exec(m_ui->listViewMoments->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void TimeLinePropertiesDialog::updateTitle()
|
||||
{
|
||||
setWindowTitle(tr("Time Line Properties: %0%1")
|
||||
.arg(m_timeLine.name)
|
||||
.arg(m_unsavedChanges ? tr("*") : QString{})
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
|
||||
namespace Ui { class TimeLinePropertiesDialog; }
|
||||
class ProjectTreeModel;
|
||||
class TimelineMomentsModel;
|
||||
|
||||
class TimeLinePropertiesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TimeLinePropertiesDialog(TimeLine &timeLine, ProjectTreeModel &projectModel, QWidget *parent = nullptr);
|
||||
~TimeLinePropertiesDialog();
|
||||
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
|
||||
private slots:
|
||||
void changed();
|
||||
|
||||
void timeLineNameChanged(const TimeLine &timeLine);
|
||||
|
||||
void addMoment();
|
||||
void changeMoment();
|
||||
void deleteMoments();
|
||||
void clearMoments();
|
||||
void shiftMoments();
|
||||
void duplicateMoments();
|
||||
void spreadMoments();
|
||||
void mergeMoments();
|
||||
void showInformation();
|
||||
|
||||
void currentMomentChanged(const QModelIndex &index);
|
||||
void momentsContextMenuRequested(const QPoint &pos);
|
||||
|
||||
private:
|
||||
void updateTitle();
|
||||
|
||||
const std::unique_ptr<Ui::TimeLinePropertiesDialog> m_ui;
|
||||
|
||||
TimeLine &m_timeLine;
|
||||
ProjectTreeModel &m_projectModel;
|
||||
|
||||
TimeLine::moments_container_t m_moments;
|
||||
|
||||
const std::unique_ptr<TimelineMomentsModel> m_momentsModel;
|
||||
|
||||
bool m_unsavedChanges{};
|
||||
};
|
||||
@@ -0,0 +1,317 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TimeLinePropertiesDialog</class>
|
||||
<widget class="QDialog" name="TimeLinePropertiesDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>838</width>
|
||||
<height>533</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Time Line Properties</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/timeline-file.png</normaloff>:/qtgameengine/icons/timeline-file.png</iconset>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,1">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelName">
|
||||
<property name="text">
|
||||
<string>&Name:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditName</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditName">
|
||||
<property name="toolTip">
|
||||
<string>The name of the time line</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="pushButtonAdd">
|
||||
<property name="toolTip">
|
||||
<string>Click here to add another moment</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Add</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/add.png</normaloff>:/qtgameengine/icons/add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pushButtonChange">
|
||||
<property name="toolTip">
|
||||
<string>Change the moment</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Change</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/replace.png</normaloff>:/qtgameengine/icons/replace.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pushButtonDelete">
|
||||
<property name="toolTip">
|
||||
<string>Delete moments</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Delete</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/delete.png</normaloff>:/qtgameengine/icons/delete.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QPushButton" name="pushButtonShift">
|
||||
<property name="toolTip">
|
||||
<string>Shift moments by an amount</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Shift</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/arrow-right.png</normaloff>:/qtgameengine/icons/arrow-right.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="pushButtonClear">
|
||||
<property name="toolTip">
|
||||
<string>Clear all moments</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>C&lear</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/new.png</normaloff>:/qtgameengine/icons/new.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QPushButton" name="pushButtonDuplicate">
|
||||
<property name="toolTip">
|
||||
<string>Duplicate moments</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>D&uplicate</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/copy.png</normaloff>:/qtgameengine/icons/copy.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QPushButton" name="pushButtonSpread">
|
||||
<property name="toolTip">
|
||||
<string>Spread out the moments adding additional time between them</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>S&pread</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/scale.png</normaloff>:/qtgameengine/icons/scale.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QPushButton" name="pushButtonMerge">
|
||||
<property name="toolTip">
|
||||
<string>Merge a number of moments into one</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Merge</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/merge.png</normaloff>:/qtgameengine/icons/merge.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonShowInformation">
|
||||
<property name="toolTip">
|
||||
<string>Show information about the time line</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show &Information</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/info.png</normaloff>:/qtgameengine/icons/info.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</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>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelMoments">
|
||||
<property name="text">
|
||||
<string>Moments:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>listViewMoments</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListView" name="listViewMoments">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ActionsContainerWidget" name="actionsWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ActionsContainerWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>widgets/actionscontainerwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>TimeLinePropertiesDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>150</x>
|
||||
<y>277</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>256</x>
|
||||
<y>239</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>TimeLinePropertiesDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>150</x>
|
||||
<y>277</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>256</x>
|
||||
<y>239</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "triggerconditiondialog.h"
|
||||
|
||||
TriggerConditionDialog::TriggerConditionDialog(QWidget *parent) :
|
||||
CodeEditorDialog{tr("Trigger condition"), parent}
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
setWindowFlags((windowFlags() & ~Qt::Dialog) | Qt::Window);
|
||||
#endif
|
||||
setWindowFlag(Qt::WindowMinimizeButtonHint);
|
||||
setWindowFlag(Qt::WindowMaximizeButtonHint);
|
||||
setWindowFlag(Qt::WindowCloseButtonHint);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "codeeditordialog.h"
|
||||
|
||||
class TriggerConditionDialog : public CodeEditorDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TriggerConditionDialog(QWidget *parent = nullptr);
|
||||
};
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "triggersdialog.h"
|
||||
#include "ui_triggersdialog.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
#include "models/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->pushButtonAdd, &QAbstractButton::clicked,
|
||||
this, &TriggersDialog::addTrigger);
|
||||
connect(m_ui->pushButtonDelete, &QAbstractButton::clicked,
|
||||
this, &TriggersDialog::deleteTrigger);
|
||||
connect(m_ui->pushButtonLoad, &QAbstractButton::clicked,
|
||||
this, &TriggersDialog::loadTrigger);
|
||||
connect(m_ui->pushButtonSave, &QAbstractButton::clicked,
|
||||
this, &TriggersDialog::saveTrigger);
|
||||
connect(m_ui->pushButtonClear, &QAbstractButton::clicked,
|
||||
this, &TriggersDialog::clearTriggers);
|
||||
connect(m_ui->pushButtonUseCodeEditor, &QAbstractButton::clicked,
|
||||
this, &TriggersDialog::openCodeEditor);
|
||||
}
|
||||
|
||||
void TriggersDialog::addTrigger()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void TriggersDialog::deleteTrigger()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void TriggersDialog::loadTrigger()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void TriggersDialog::saveTrigger()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void TriggersDialog::clearTriggers()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
TriggersDialog::~TriggersDialog() = default;
|
||||
|
||||
void TriggersDialog::openCodeEditor()
|
||||
{
|
||||
TriggerConditionDialog dialog{this};
|
||||
dialog.setScript(m_ui->plainTextEdit->toPlainText());
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
m_ui->plainTextEdit->setPlainText(dialog.script());
|
||||
// changed();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#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 addTrigger();
|
||||
void deleteTrigger();
|
||||
void loadTrigger();
|
||||
void saveTrigger();
|
||||
void clearTriggers();
|
||||
|
||||
void openCodeEditor();
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Ui::TriggersDialog> m_ui;
|
||||
|
||||
ProjectContainer &m_project;
|
||||
|
||||
const std::unique_ptr<TriggersModel> m_model;
|
||||
};
|
||||
@@ -0,0 +1,285 @@
|
||||
<?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>
|
||||
<property name="toolTip">
|
||||
<string>List of all defined triggers. Click on a trigger to change it</string>
|
||||
</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>&Load</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/open.png</normaloff>:/qtgameengine/icons/open.png</iconset>
|
||||
</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>&Delete</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/delete.png</normaloff>:/qtgameengine/icons/delete.png</iconset>
|
||||
</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>&Add</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/add.png</normaloff>:/qtgameengine/icons/add.png</iconset>
|
||||
</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>&Clear</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/new.png</normaloff>:/qtgameengine/icons/new.png</iconset>
|
||||
</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>&Save</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/save.png</normaloff>:/qtgameengine/icons/save.png</iconset>
|
||||
</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>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditName</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditName">
|
||||
<property name="toolTip">
|
||||
<string>Type here a name for the trigger</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelCondition">
|
||||
<property name="text">
|
||||
<string>Condition:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>plainTextEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="plainTextEdit">
|
||||
<property name="toolTip">
|
||||
<string>Type here the condition for the trigger</string>
|
||||
</property>
|
||||
</widget>
|
||||
</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="toolTip">
|
||||
<string>Use the code editor to edit the condition</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&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="toolTip">
|
||||
<string>Event will be checked at the beginning of each step</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Begin of step</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonMiddle">
|
||||
<property name="toolTip">
|
||||
<string>Event will be checked in the middle of each step (just before the step event)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Middle of step</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonEnd">
|
||||
<property name="toolTip">
|
||||
<string>Event will be checked at the end of each step</string>
|
||||
</property>
|
||||
<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>
|
||||
<property name="buddy">
|
||||
<cstring>lineEditConstantName</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditConstantName">
|
||||
<property name="toolTip">
|
||||
<string>When required you can provide a constant name that you can use in code to call the event</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources.qrc"/>
|
||||
</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>
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "userdefinedconstantsdialog.h"
|
||||
#include "ui_userdefinedconstantsdialog.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
#include "models/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());
|
||||
|
||||
connect(m_ui->pushButtonInsert, &QAbstractButton::clicked,
|
||||
this, &UserDefinedConstantsDialog::insertConstant);
|
||||
connect(m_ui->pushButtonAdd, &QAbstractButton::clicked,
|
||||
this, &UserDefinedConstantsDialog::addConstant);
|
||||
connect(m_ui->pushButtonDelete, &QAbstractButton::clicked,
|
||||
this, &UserDefinedConstantsDialog::deleteConstant);
|
||||
connect(m_ui->pushButtonClear, &QAbstractButton::clicked,
|
||||
this, &UserDefinedConstantsDialog::clearConstants);
|
||||
connect(m_ui->pushButtonUp, &QAbstractButton::clicked,
|
||||
this, &UserDefinedConstantsDialog::moveConstantUp);
|
||||
connect(m_ui->pushButtonDown, &QAbstractButton::clicked,
|
||||
this, &UserDefinedConstantsDialog::moveConstantDown);
|
||||
connect(m_ui->pushButtonSort, &QAbstractButton::clicked,
|
||||
this, &UserDefinedConstantsDialog::sortConstants);
|
||||
connect(m_ui->pushButtonLoad, &QAbstractButton::clicked,
|
||||
this, &UserDefinedConstantsDialog::loadConstant);
|
||||
connect(m_ui->pushButtonSave, &QAbstractButton::clicked,
|
||||
this, &UserDefinedConstantsDialog::saveConstant);
|
||||
}
|
||||
|
||||
UserDefinedConstantsDialog::~UserDefinedConstantsDialog() = default;
|
||||
|
||||
void UserDefinedConstantsDialog::insertConstant()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void UserDefinedConstantsDialog::addConstant()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void UserDefinedConstantsDialog::deleteConstant()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void UserDefinedConstantsDialog::clearConstants()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void UserDefinedConstantsDialog::moveConstantUp()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void UserDefinedConstantsDialog::moveConstantDown()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void UserDefinedConstantsDialog::sortConstants()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void UserDefinedConstantsDialog::loadConstant()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
|
||||
void UserDefinedConstantsDialog::saveConstant()
|
||||
{
|
||||
QMessageBox::warning(this, tr("Not yet implemented"), tr("Not yet implemented"));
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#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 slots:
|
||||
void insertConstant();
|
||||
void addConstant();
|
||||
void deleteConstant();
|
||||
void clearConstants();
|
||||
void moveConstantUp();
|
||||
void moveConstantDown();
|
||||
void sortConstants();
|
||||
void loadConstant();
|
||||
void saveConstant();
|
||||
|
||||
private:
|
||||
const std::unique_ptr<Ui::UserDefinedConstantsDialog> m_ui;
|
||||
|
||||
ProjectContainer &m_project;
|
||||
|
||||
const std::unique_ptr<ConstantsModel> m_model;
|
||||
};
|
||||
@@ -0,0 +1,213 @@
|
||||
<?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="toolTip">
|
||||
<string>Insert a constant before the current one</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Insert</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/add.png</normaloff>:/qtgameengine/icons/add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="pushButtonSort">
|
||||
<property name="toolTip">
|
||||
<string>Sort the constants</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Sort</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/sort.png</normaloff>:/qtgameengine/icons/sort.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pushButtonDelete">
|
||||
<property name="toolTip">
|
||||
<string>Delete the current constant</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Delete</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/delete.png</normaloff>:/qtgameengine/icons/delete.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QPushButton" name="pushButtonLoad">
|
||||
<property name="toolTip">
|
||||
<string>Load the constants from a text file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Load</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/open.png</normaloff>:/qtgameengine/icons/open.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="pushButtonUp">
|
||||
<property name="toolTip">
|
||||
<string>Moves the constant up</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Up</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/arrow-up.png</normaloff>:/qtgameengine/icons/arrow-up.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pushButtonAdd">
|
||||
<property name="toolTip">
|
||||
<string>Append a constant at the end of the list</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Add</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/add.png</normaloff>:/qtgameengine/icons/add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="pushButtonClear">
|
||||
<property name="toolTip">
|
||||
<string>Clear all the constants</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Clear</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/new.png</normaloff>:/qtgameengine/icons/new.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="pushButtonDown">
|
||||
<property name="toolTip">
|
||||
<string>Moves the constant down</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Do&wn</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/arrow-down.png</normaloff>:/qtgameengine/icons/arrow-down.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QPushButton" name="pushButtonSave">
|
||||
<property name="toolTip">
|
||||
<string>Save the constants to a text file</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Sa&ve</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/save.png</normaloff>:/qtgameengine/icons/save.png</iconset>
|
||||
</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>
|
||||
@@ -0,0 +1,449 @@
|
||||
#include "jshighlighter.h"
|
||||
|
||||
class JSBlockData : public QTextBlockUserData
|
||||
{
|
||||
public:
|
||||
QList<int> bracketPositions;
|
||||
};
|
||||
|
||||
JSHighlighter::JSHighlighter(QTextDocument *parent) :
|
||||
QSyntaxHighlighter{parent},
|
||||
m_colors {
|
||||
// default color scheme
|
||||
{ Normal, QColor("#000000") },
|
||||
{ Comment, QColor("#808080") },
|
||||
{ Number, QColor("#008000") },
|
||||
{ String, QColor("#800000") },
|
||||
{ Operator, QColor("#808000") },
|
||||
{ Identifier, QColor("#000020") },
|
||||
{ Keyword, QColor("#000080") },
|
||||
{ BuiltIn, QColor("#008080") },
|
||||
{ Marker, QColor("#ffff00") },
|
||||
},
|
||||
m_keywords {
|
||||
// https://developer.mozilla.org/en/JavaScript/Reference/Reserved_Words
|
||||
"break",
|
||||
"case",
|
||||
"catch",
|
||||
"continue",
|
||||
"default",
|
||||
"delete",
|
||||
"do",
|
||||
"else",
|
||||
"finally",
|
||||
"for",
|
||||
"function",
|
||||
"if",
|
||||
"in",
|
||||
"instanceof",
|
||||
"new",
|
||||
"return",
|
||||
"switch",
|
||||
"this",
|
||||
"throw",
|
||||
"try",
|
||||
"typeof",
|
||||
"var",
|
||||
"void",
|
||||
"while",
|
||||
"with",
|
||||
|
||||
"true",
|
||||
"false",
|
||||
"null",
|
||||
},
|
||||
m_knownIds {
|
||||
// built-in and other popular objects + properties
|
||||
"Object",
|
||||
"prototype",
|
||||
"create",
|
||||
"defineProperty",
|
||||
"defineProperties",
|
||||
"getOwnPropertyDescriptor",
|
||||
"keys",
|
||||
"getOwnPropertyNames",
|
||||
"constructor",
|
||||
"__parent__",
|
||||
"__proto__",
|
||||
"__defineGetter__",
|
||||
"__defineSetter__",
|
||||
"eval",
|
||||
"hasOwnProperty",
|
||||
"isPrototypeOf",
|
||||
"__lookupGetter__",
|
||||
"__lookupSetter__",
|
||||
"__noSuchMethod__",
|
||||
"propertyIsEnumerable",
|
||||
"toSource",
|
||||
"toLocaleString",
|
||||
"toString",
|
||||
"unwatch",
|
||||
"valueOf",
|
||||
"watch",
|
||||
|
||||
"Function",
|
||||
"arguments",
|
||||
"arity",
|
||||
"caller",
|
||||
"constructor",
|
||||
"length",
|
||||
"name",
|
||||
"apply",
|
||||
"bind",
|
||||
"call",
|
||||
|
||||
"String",
|
||||
"fromCharCode",
|
||||
"length",
|
||||
"charAt",
|
||||
"charCodeAt",
|
||||
"concat",
|
||||
"indexOf",
|
||||
"lastIndexOf",
|
||||
"localCompare",
|
||||
"match",
|
||||
"quote",
|
||||
"replace",
|
||||
"search",
|
||||
"slice",
|
||||
"split",
|
||||
"substr",
|
||||
"substring",
|
||||
"toLocaleLowerCase",
|
||||
"toLocaleUpperCase",
|
||||
"toLowerCase",
|
||||
"toUpperCase",
|
||||
"trim",
|
||||
"trimLeft",
|
||||
"trimRight",
|
||||
|
||||
"Array",
|
||||
"isArray",
|
||||
"index",
|
||||
"input",
|
||||
"pop",
|
||||
"push",
|
||||
"reverse",
|
||||
"shift",
|
||||
"sort",
|
||||
"splice",
|
||||
"unshift",
|
||||
"concat",
|
||||
"join",
|
||||
"filter",
|
||||
"forEach",
|
||||
"every",
|
||||
"map",
|
||||
"some",
|
||||
"reduce",
|
||||
"reduceRight",
|
||||
|
||||
"RegExp",
|
||||
"global",
|
||||
"ignoreCase",
|
||||
"lastIndex",
|
||||
"multiline",
|
||||
"source",
|
||||
"exec",
|
||||
"test",
|
||||
|
||||
"JSON",
|
||||
"parse",
|
||||
"stringify",
|
||||
|
||||
"decodeURI",
|
||||
"decodeURIComponent",
|
||||
"encodeURI",
|
||||
"encodeURIComponent",
|
||||
"eval",
|
||||
"isFinite",
|
||||
"isNaN",
|
||||
"parseFloat",
|
||||
"parseInt",
|
||||
"Infinity",
|
||||
"NaN",
|
||||
"undefined",
|
||||
|
||||
"Math",
|
||||
"E",
|
||||
"LN2",
|
||||
"LN10",
|
||||
"LOG2E",
|
||||
"LOG10E",
|
||||
"PI",
|
||||
"SQRT1_2",
|
||||
"SQRT2",
|
||||
"abs",
|
||||
"acos",
|
||||
"asin",
|
||||
"atan",
|
||||
"atan2",
|
||||
"ceil",
|
||||
"cos",
|
||||
"exp",
|
||||
"floor",
|
||||
"log",
|
||||
"max",
|
||||
"min",
|
||||
"pow",
|
||||
"random",
|
||||
"round",
|
||||
"sin",
|
||||
"sqrt",
|
||||
"tan",
|
||||
|
||||
"document",
|
||||
"window",
|
||||
"navigator",
|
||||
"userAgent",
|
||||
},
|
||||
m_markCaseSensitivity{Qt::CaseInsensitive}
|
||||
{
|
||||
}
|
||||
|
||||
void JSHighlighter::setColor(ColorComponent component, const QColor &color)
|
||||
{
|
||||
m_colors[component] = color;
|
||||
rehighlight();
|
||||
}
|
||||
|
||||
void JSHighlighter::highlightBlock(const QString &text)
|
||||
{
|
||||
// parsing state
|
||||
enum {
|
||||
Start = 0,
|
||||
Number = 1,
|
||||
Identifier = 2,
|
||||
String = 3,
|
||||
Comment = 4,
|
||||
Regex = 5
|
||||
};
|
||||
|
||||
QList<int> bracketPositions;
|
||||
|
||||
int blockState = previousBlockState();
|
||||
int bracketLevel = blockState >> 4;
|
||||
int state = blockState & 15;
|
||||
if (blockState < 0)
|
||||
{
|
||||
bracketLevel = 0;
|
||||
state = Start;
|
||||
}
|
||||
|
||||
int start = 0;
|
||||
int i = 0;
|
||||
while (i <= text.length())
|
||||
{
|
||||
QChar ch = (i < text.length()) ? text.at(i) : QChar();
|
||||
QChar next = (i < text.length() - 1) ? text.at(i + 1) : QChar();
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case Start:
|
||||
start = i;
|
||||
if (ch.isSpace())
|
||||
{
|
||||
++i;
|
||||
}
|
||||
else if (ch.isDigit())
|
||||
{
|
||||
++i;
|
||||
state = Number;
|
||||
}
|
||||
else if (ch.isLetter() || ch == '_')
|
||||
{
|
||||
++i;
|
||||
state = Identifier;
|
||||
}
|
||||
else if (ch == '\'' || ch == '\"')
|
||||
{
|
||||
++i;
|
||||
state = String;
|
||||
}
|
||||
else if (ch == '/' && next == '*')
|
||||
{
|
||||
++i;
|
||||
++i;
|
||||
state = Comment;
|
||||
}
|
||||
else if (ch == '/' && next == '/')
|
||||
{
|
||||
i = text.length();
|
||||
setFormat(start, text.length(), m_colors[ColorComponent::Comment]);
|
||||
}
|
||||
else if (ch == '/' && next != '*')
|
||||
{
|
||||
++i;
|
||||
state = Regex;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!QString("(){}[]").contains(ch))
|
||||
setFormat(start, 1, m_colors[Operator]);
|
||||
if (ch =='{' || ch == '}')
|
||||
{
|
||||
bracketPositions += i;
|
||||
if (ch == '{')
|
||||
bracketLevel++;
|
||||
else
|
||||
bracketLevel--;
|
||||
}
|
||||
++i;
|
||||
state = Start;
|
||||
}
|
||||
break;
|
||||
|
||||
case Number:
|
||||
if (ch.isSpace() || !ch.isDigit())
|
||||
{
|
||||
setFormat(start, i - start, m_colors[ColorComponent::Number]);
|
||||
state = Start;
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
break;
|
||||
|
||||
case Identifier:
|
||||
if (ch.isSpace() || !(ch.isDigit() || ch.isLetter() || ch == '_'))
|
||||
{
|
||||
QString token = text.mid(start, i - start).trimmed();
|
||||
if (m_keywords.contains(token))
|
||||
setFormat(start, i - start, m_colors[Keyword]);
|
||||
else if (m_knownIds.contains(token))
|
||||
setFormat(start, i - start, m_colors[BuiltIn]);
|
||||
state = Start;
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
break;
|
||||
|
||||
case String:
|
||||
if (ch == text.at(start)) {
|
||||
QChar prev = (i > 0) ? text.at(i - 1) : QChar();
|
||||
if (prev != '\\') {
|
||||
++i;
|
||||
setFormat(start, i - start, m_colors[ColorComponent::String]);
|
||||
state = Start;
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
break;
|
||||
|
||||
case Comment:
|
||||
if (ch == '*' && next == '/')
|
||||
{
|
||||
++i;
|
||||
++i;
|
||||
setFormat(start, i - start, m_colors[ColorComponent::Comment]);
|
||||
state = Start;
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
break;
|
||||
|
||||
case Regex:
|
||||
if (ch == '/')
|
||||
{
|
||||
QChar prev = (i > 0) ? text.at(i - 1) : QChar();
|
||||
if (prev != '\\')
|
||||
{
|
||||
++i;
|
||||
setFormat(start, i - start, m_colors[ColorComponent::String]);
|
||||
state = Start;
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
state = Start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (state == Comment)
|
||||
setFormat(start, text.length(), m_colors[ColorComponent::Comment]);
|
||||
else
|
||||
state = Start;
|
||||
|
||||
if (!m_markString.isEmpty())
|
||||
{
|
||||
int pos = 0;
|
||||
int len = m_markString.length();
|
||||
QTextCharFormat markerFormat;
|
||||
markerFormat.setBackground(m_colors[Marker]);
|
||||
markerFormat.setForeground(m_colors[Normal]);
|
||||
for (;;)
|
||||
{
|
||||
pos = text.indexOf(m_markString, pos, m_markCaseSensitivity);
|
||||
if (pos < 0)
|
||||
break;
|
||||
setFormat(pos, len, markerFormat);
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bracketPositions.isEmpty())
|
||||
{
|
||||
JSBlockData *blockData = reinterpret_cast<JSBlockData*>(currentBlock().userData());
|
||||
if (!blockData)
|
||||
{
|
||||
blockData = new JSBlockData;
|
||||
currentBlock().setUserData(blockData);
|
||||
}
|
||||
blockData->bracketPositions = bracketPositions;
|
||||
}
|
||||
|
||||
blockState = (state & 15) | (bracketLevel << 4);
|
||||
setCurrentBlockState(blockState);
|
||||
}
|
||||
|
||||
void JSHighlighter::mark(const QString &str, Qt::CaseSensitivity caseSensitivity)
|
||||
{
|
||||
m_markString = str;
|
||||
m_markCaseSensitivity = caseSensitivity;
|
||||
rehighlight();
|
||||
}
|
||||
|
||||
QStringList JSHighlighter::keywords() const
|
||||
{
|
||||
return QStringList{std::begin(m_keywords), std::end(m_keywords)};
|
||||
}
|
||||
|
||||
void JSHighlighter::setKeywords(std::set<QString> &&keywords)
|
||||
{
|
||||
m_keywords = std::move(keywords);
|
||||
rehighlight();
|
||||
}
|
||||
|
||||
void JSHighlighter::setKeywords(const std::set<QString> &keywords)
|
||||
{
|
||||
m_keywords = keywords;
|
||||
rehighlight();
|
||||
}
|
||||
|
||||
struct BlockInfo
|
||||
{
|
||||
int position;
|
||||
int number;
|
||||
bool foldable: 1;
|
||||
bool folded : 1;
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(BlockInfo, Q_PRIMITIVE_TYPE);
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <QSyntaxHighlighter>
|
||||
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
enum ColorComponent {
|
||||
Background,
|
||||
Normal,
|
||||
Comment,
|
||||
Number,
|
||||
String,
|
||||
Operator,
|
||||
Identifier,
|
||||
Keyword,
|
||||
BuiltIn,
|
||||
Sidebar,
|
||||
LineNumber,
|
||||
Cursor,
|
||||
Marker,
|
||||
BracketMatch,
|
||||
BracketError,
|
||||
FoldIndicator
|
||||
};
|
||||
|
||||
class JSHighlighter : public QSyntaxHighlighter
|
||||
{
|
||||
public:
|
||||
JSHighlighter(QTextDocument *parent = 0);
|
||||
void setColor(ColorComponent component, const QColor &color);
|
||||
void mark(const QString &str, Qt::CaseSensitivity caseSensitivity);
|
||||
|
||||
QStringList keywords() const;
|
||||
void setKeywords(std::set<QString> &&keywords);
|
||||
void setKeywords(const std::set<QString> &keywords);
|
||||
|
||||
protected:
|
||||
void highlightBlock(const QString &text);
|
||||
|
||||
private:
|
||||
std::unordered_map<ColorComponent, QColor> m_colors;
|
||||
std::set<QString> m_keywords;
|
||||
std::set<QString> m_knownIds;
|
||||
|
||||
QString m_markString;
|
||||
Qt::CaseSensitivity m_markCaseSensitivity;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,116 @@
|
||||
#pragma once
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
|
||||
class QMdiSubWindow;
|
||||
class QActionGroup;
|
||||
namespace Ui { class MainWindow; }
|
||||
class ProjectTreeModel;
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(const QString &filePath, QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void contextMenuRequested(const QPoint &pos);
|
||||
void doubleClicked(const QModelIndex &index);
|
||||
void selectionChanged(const QModelIndex &index);
|
||||
void modelErrorOccured(const QString &message);
|
||||
void changed();
|
||||
|
||||
void newFile();
|
||||
void openFile();
|
||||
void saveFile();
|
||||
void saveFileAs();
|
||||
void createExecutable();
|
||||
void publishGame();
|
||||
void importResources();
|
||||
void exportResources();
|
||||
void preferences();
|
||||
void create();
|
||||
void duplicate();
|
||||
void createGroup();
|
||||
void sortByName();
|
||||
void delete_();
|
||||
void rename();
|
||||
void showProperties();
|
||||
void findResource();
|
||||
void showObjectInformation();
|
||||
private:
|
||||
template<typename T>
|
||||
void createFor();
|
||||
private slots:
|
||||
void showGameInformation();
|
||||
void showGlobalGameSettings();
|
||||
void showExtensionPackages();
|
||||
void showDefineConstants();
|
||||
void showDefineTriggers();
|
||||
void showIncludedFiles();
|
||||
void runGame();
|
||||
void debugGame();
|
||||
void about();
|
||||
|
||||
void rowsInserted(const QModelIndex &parent, int first, int last);
|
||||
void rowsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
|
||||
void modelAboutToBeReset();
|
||||
|
||||
private:
|
||||
void setupStylesMenu();
|
||||
void loadFile(const QString &path);
|
||||
void updateTitle();
|
||||
|
||||
template<typename T, typename ...Targs>
|
||||
void openOrActivateWindow(QMdiSubWindow * &ptr, Targs &&...args);
|
||||
|
||||
template<typename T>
|
||||
std::map<T*, QMdiSubWindow*> &propertyWindowsFor();
|
||||
|
||||
template<typename T>
|
||||
bool doubleClickedFor(const QModelIndex &index);
|
||||
|
||||
template<typename T>
|
||||
bool rowsAboutToBeRemovedFor(const QModelIndex &parent, int first, int last);
|
||||
|
||||
template<typename T>
|
||||
void modelAboutToBeResetFor();
|
||||
|
||||
const std::unique_ptr<Ui::MainWindow> m_ui;
|
||||
|
||||
ProjectContainer m_project;
|
||||
|
||||
QString m_filePath;
|
||||
bool m_unsavedChanges{};
|
||||
|
||||
const std::unique_ptr<ProjectTreeModel> m_projectTreeModel;
|
||||
|
||||
std::map<Sprite*, QMdiSubWindow*> m_spritePropertiesWindows;
|
||||
std::map<Sound*, QMdiSubWindow*> m_soundPropertiesWindows;
|
||||
std::map<Background*, QMdiSubWindow*> m_backgroundPropertiesWindows;
|
||||
std::map<Path*, QMdiSubWindow*> m_pathPropertiesWindows;
|
||||
std::map<Script*, QMdiSubWindow*> m_scriptPropertiesWindows;
|
||||
std::map<Font*, QMdiSubWindow*> m_fontPropertiesWindows;
|
||||
std::map<TimeLine*, QMdiSubWindow*> m_timeLinePropertiesWindows;
|
||||
std::map<Object*, QMdiSubWindow*> m_objectPropertiesWindows;
|
||||
std::map<Room*, QMdiSubWindow*> m_roomPropertiesWindows;
|
||||
|
||||
QMdiSubWindow *m_objectInformationWindow{};
|
||||
QMdiSubWindow *m_userDefinedConstantsWindow{};
|
||||
QMdiSubWindow *m_triggersWindow{};
|
||||
QMdiSubWindow *m_includedFilesWindow{};
|
||||
|
||||
QActionGroup *m_actionGroupViewMode{};
|
||||
QActionGroup *m_actionGroupStyles{};
|
||||
QActionGroup *m_actionGroupWindows{};
|
||||
};
|
||||
@@ -0,0 +1,978 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1366</width>
|
||||
<height>768</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Qt Gamemaker 1.0 Ultimate</string>
|
||||
</property>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QTreeView" name="treeView">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::EditKeyPressed</set>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="animated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="headerHidden">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMdiArea" name="mdiArea">
|
||||
<property name="background">
|
||||
<brush brushstyle="CrossPattern">
|
||||
<color alpha="255">
|
||||
<red>159</red>
|
||||
<green>159</green>
|
||||
<blue>159</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1366</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
<string>&File</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuRecentFiles">
|
||||
<property name="title">
|
||||
<string>&Recent Files</string>
|
||||
</property>
|
||||
<addaction name="actionNone"/>
|
||||
</widget>
|
||||
<addaction name="actionNew"/>
|
||||
<addaction name="actionOpen"/>
|
||||
<addaction name="menuRecentFiles"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSave"/>
|
||||
<addaction name="actionSaveAs"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCreateExecutable"/>
|
||||
<addaction name="actionPublishGame"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionImportResources"/>
|
||||
<addaction name="actionExportResources"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionAdvancedMode"/>
|
||||
<addaction name="actionPreferences"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionExit"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuEdit">
|
||||
<property name="title">
|
||||
<string>&Edit</string>
|
||||
</property>
|
||||
<addaction name="actionCreate"/>
|
||||
<addaction name="actionDuplicate"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCreateGroup"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionDelete"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionRename"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionProperties"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionFindResource"/>
|
||||
<addaction name="actionExpandResourceTree"/>
|
||||
<addaction name="actionCollapseResourceTree"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionShowObjectInformation"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuResources">
|
||||
<property name="title">
|
||||
<string>&Resources</string>
|
||||
</property>
|
||||
<addaction name="actionCreateSprite"/>
|
||||
<addaction name="actionCreateSound"/>
|
||||
<addaction name="actionCreateBackground"/>
|
||||
<addaction name="actionCreatePath"/>
|
||||
<addaction name="actionCreateScript"/>
|
||||
<addaction name="actionCreateFont"/>
|
||||
<addaction name="actionCreateTimeLine"/>
|
||||
<addaction name="actionCreateObject"/>
|
||||
<addaction name="actionCreateRoom"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionGameInformation"/>
|
||||
<addaction name="actionGlobalGameSettings"/>
|
||||
<addaction name="actionExtensionPackages"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionDefineConstants"/>
|
||||
<addaction name="actionDefineTriggers"/>
|
||||
<addaction name="actionIncludedFiles"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuScripts">
|
||||
<property name="title">
|
||||
<string>&Scripts</string>
|
||||
</property>
|
||||
<addaction name="actionImportScripts"/>
|
||||
<addaction name="actionExportAllScripts"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionShowBuiltInVariables"/>
|
||||
<addaction name="actionShowBuildInFunctions"/>
|
||||
<addaction name="actionShowExtensionFunctions"/>
|
||||
<addaction name="actionShowConstants"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionShowResourceNames"/>
|
||||
<addaction name="actionSearchInScripts"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCheckResourceNames"/>
|
||||
<addaction name="actionCheckAllScripts"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuRun">
|
||||
<property name="title">
|
||||
<string>R&un</string>
|
||||
</property>
|
||||
<addaction name="actionRunNormally"/>
|
||||
<addaction name="actionRunInDebugMode"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuWindow">
|
||||
<property name="title">
|
||||
<string>&Window</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuStyle">
|
||||
<property name="title">
|
||||
<string>Style</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="actionClose"/>
|
||||
<addaction name="actionCloseAll"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionTile"/>
|
||||
<addaction name="actionCascade"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionNext"/>
|
||||
<addaction name="actionPrevious"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSubWindowedView"/>
|
||||
<addaction name="actionTabbedView"/>
|
||||
<addaction name="menuStyle"/>
|
||||
<addaction name="separator"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuHelp">
|
||||
<property name="title">
|
||||
<string>&Help</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuTutorials">
|
||||
<property name="title">
|
||||
<string>&Tutorials</string>
|
||||
</property>
|
||||
<addaction name="actionNone"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuExtensionPackages">
|
||||
<property name="title">
|
||||
<string>&Extension Packages</string>
|
||||
</property>
|
||||
<addaction name="actionNone"/>
|
||||
</widget>
|
||||
<addaction name="actionContents"/>
|
||||
<addaction name="menuTutorials"/>
|
||||
<addaction name="menuExtensionPackages"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionNews"/>
|
||||
<addaction name="actionBook"/>
|
||||
<addaction name="actionMoreTutorials"/>
|
||||
<addaction name="actionWebsite"/>
|
||||
<addaction name="actionForum"/>
|
||||
<addaction name="actionWiki"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionAbout"/>
|
||||
<addaction name="actionAboutQt"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuEdit"/>
|
||||
<addaction name="menuResources"/>
|
||||
<addaction name="menuScripts"/>
|
||||
<addaction name="menuRun"/>
|
||||
<addaction name="menuWindow"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<property name="movable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<addaction name="actionNew"/>
|
||||
<addaction name="actionOpen"/>
|
||||
<addaction name="actionSave"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCreateExecutable"/>
|
||||
<addaction name="actionPublishGame"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionRunNormally"/>
|
||||
<addaction name="actionRunInDebugMode"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCreateSprite"/>
|
||||
<addaction name="actionCreateSound"/>
|
||||
<addaction name="actionCreateBackground"/>
|
||||
<addaction name="actionCreatePath"/>
|
||||
<addaction name="actionCreateScript"/>
|
||||
<addaction name="actionCreateFont"/>
|
||||
<addaction name="actionCreateTimeLine"/>
|
||||
<addaction name="actionCreateObject"/>
|
||||
<addaction name="actionCreateRoom"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionGameInformation"/>
|
||||
<addaction name="actionGlobalGameSettings"/>
|
||||
<addaction name="actionExtensionPackages"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionContents"/>
|
||||
</widget>
|
||||
<action name="actionNew">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/new.png</normaloff>:/qtgameengine/icons/new.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&New</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionOpen">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/open.png</normaloff>:/qtgameengine/icons/open.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Open</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/save.png</normaloff>:/qtgameengine/icons/save.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Save</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveAs">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/save-as.png</normaloff>:/qtgameengine/icons/save-as.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save &As...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateExecutable">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/create-executable.png</normaloff>:/qtgameengine/icons/create-executable.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Create Executable...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPublishGame">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/publish-game.png</normaloff>:/qtgameengine/icons/publish-game.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>P&ublish your Game...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionImportResources">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/import-resources.png</normaloff>:/qtgameengine/icons/import-resources.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Import Resources...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExportResources">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/export-resources.png</normaloff>:/qtgameengine/icons/export-resources.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Export Resources...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAdvancedMode">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ad&vanced Mode</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPreferences">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/preferences.png</normaloff>:/qtgameengine/icons/preferences.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Preferences...</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::PreferencesRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExit">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/exit.png</normaloff>:/qtgameengine/icons/exit.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>E&xit</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::QuitRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionNone">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>(none)</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreate">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/create.png</normaloff>:/qtgameengine/icons/create.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Create</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDuplicate">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/duplicate.png</normaloff>:/qtgameengine/icons/duplicate.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>D&uplicate</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Alt+Ins</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateGroup">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/create-group.png</normaloff>:/qtgameengine/icons/create-group.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cr&eate Group</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSortByName">
|
||||
<property name="text">
|
||||
<string>&Sort by Name</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDelete">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/delete.png</normaloff>:/qtgameengine/icons/delete.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Delete</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRename">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/rename.png</normaloff>:/qtgameengine/icons/rename.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Rename</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionProperties">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/properties.png</normaloff>:/qtgameengine/icons/properties.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Properties</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Alt+Return</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionFindResource">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/find.png</normaloff>:/qtgameengine/icons/find.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Find Resource</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExpandResourceTree">
|
||||
<property name="text">
|
||||
<string>E&xpand Resource Tree</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCollapseResourceTree">
|
||||
<property name="text">
|
||||
<string>C&ollapse Resource Tree</string>
|
||||
</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>&Show Object Information</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateSprite">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/sprite.png</normaloff>:/qtgameengine/icons/sprite.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create &Sprite</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+S</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateSound">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/sound.png</normaloff>:/qtgameengine/icons/sound.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create So&und</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+U</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateBackground">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/background.png</normaloff>:/qtgameengine/icons/background.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create &Background</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+B</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreatePath">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/path.png</normaloff>:/qtgameengine/icons/path.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create &Path</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+P</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateScript">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/script.png</normaloff>:/qtgameengine/icons/script.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create S&cript</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+C</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateFont">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/font.png</normaloff>:/qtgameengine/icons/font.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create &Font</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+F</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateTimeLine">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/timeline.png</normaloff>:/qtgameengine/icons/timeline.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create &Time Line</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+T</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateObject">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/object.png</normaloff>:/qtgameengine/icons/object.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create &Object</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+O</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreateRoom">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/room.png</normaloff>:/qtgameengine/icons/room.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create &Room</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+R</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGameInformation">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/game-information.png</normaloff>:/qtgameengine/icons/game-information.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Change Game &Information</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+I</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGlobalGameSettings">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/global-game-settings.png</normaloff>:/qtgameengine/icons/global-game-settings.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Change &Global Game Settings</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+G</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExtensionPackages">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/extension-packages.png</normaloff>:/qtgameengine/icons/extension-packages.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select &Extension Packages</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+E</string>
|
||||
</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&nstants...</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+N</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDefineTriggers">
|
||||
<property name="text">
|
||||
<string>&Define Triggers...</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+D</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionIncludedFiles">
|
||||
<property name="text">
|
||||
<string>Inc&luded Files...</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+L</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRunNormally">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/run.png</normaloff>:/qtgameengine/icons/run.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Run normally</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>F5</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRunInDebugMode">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/debug.png</normaloff>:/qtgameengine/icons/debug.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Run in &Debug mode</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>F6</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionImportScripts">
|
||||
<property name="text">
|
||||
<string>&Import Scripts...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionContents">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/help.png</normaloff>:/qtgameengine/icons/help.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Contents</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionNews">
|
||||
<property name="text">
|
||||
<string>&News...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionBook">
|
||||
<property name="text">
|
||||
<string>&Book...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionMoreTutorials">
|
||||
<property name="text">
|
||||
<string>&More Tutorials...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionWebsite">
|
||||
<property name="text">
|
||||
<string>&Website...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionForum">
|
||||
<property name="text">
|
||||
<string>&Forum...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionWiki">
|
||||
<property name="text">
|
||||
<string>W&iki...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAbout">
|
||||
<property name="text">
|
||||
<string>&About Game Maker...</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::AboutRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAboutQt">
|
||||
<property name="text">
|
||||
<string>About &Qt...</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::AboutQtRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExportAllScripts">
|
||||
<property name="text">
|
||||
<string>&Export All Scripts...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShowBuiltInVariables">
|
||||
<property name="text">
|
||||
<string>Show Built-in &Variables</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShowBuildInFunctions">
|
||||
<property name="text">
|
||||
<string>Show Build-in &Functions</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShowExtensionFunctions">
|
||||
<property name="text">
|
||||
<string>S&how Extension Functions</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShowConstants">
|
||||
<property name="text">
|
||||
<string>Show &Constants</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionShowResourceNames">
|
||||
<property name="text">
|
||||
<string>&Show Resource Names</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSearchInScripts">
|
||||
<property name="text">
|
||||
<string>Search i&n Scripts...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCheckResourceNames">
|
||||
<property name="text">
|
||||
<string>Check &Resource Names</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCheckAllScripts">
|
||||
<property name="text">
|
||||
<string>Check &All Scripts</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionClose">
|
||||
<property name="text">
|
||||
<string>Cl&ose</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCloseAll">
|
||||
<property name="text">
|
||||
<string>Close &All</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionTile">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/tile.png</normaloff>:/qtgameengine/icons/tile.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Tile</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCascade">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/qtgameengine/icons/cascade.png</normaloff>:/qtgameengine/icons/cascade.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Cascade</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionNext">
|
||||
<property name="text">
|
||||
<string>Ne&xt</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPrevious">
|
||||
<property name="text">
|
||||
<string>Pre&vious</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSubWindowedView">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Sub-Windowed view</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionTabbedView">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ta&bbed view</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>actionExit</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>close()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>399</x>
|
||||
<y>299</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionExpandResourceTree</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>treeView</receiver>
|
||||
<slot>expandAll()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>66</x>
|
||||
<y>314</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionCollapseResourceTree</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>treeView</receiver>
|
||||
<slot>collapseAll()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>66</x>
|
||||
<y>314</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionClose</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>mdiArea</receiver>
|
||||
<slot>closeActiveSubWindow()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>468</x>
|
||||
<y>314</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionCloseAll</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>mdiArea</receiver>
|
||||
<slot>closeAllSubWindows()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>468</x>
|
||||
<y>314</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionTile</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>mdiArea</receiver>
|
||||
<slot>tileSubWindows()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>468</x>
|
||||
<y>314</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionCascade</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>mdiArea</receiver>
|
||||
<slot>cascadeSubWindows()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>468</x>
|
||||
<y>314</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionPrevious</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>mdiArea</receiver>
|
||||
<slot>activatePreviousSubWindow()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>468</x>
|
||||
<y>314</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionNext</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>mdiArea</receiver>
|
||||
<slot>activateNextSubWindow()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>468</x>
|
||||
<y>314</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,114 @@
|
||||
#include "actionscontainermodel.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QIcon>
|
||||
|
||||
ActionsContainerModel::ActionsContainerModel(QObject *parent) :
|
||||
QAbstractListModel{parent}
|
||||
{
|
||||
}
|
||||
|
||||
int ActionsContainerModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_actionsContainer ? m_actionsContainer->size() : 0;
|
||||
}
|
||||
|
||||
QVariant ActionsContainerModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!m_actionsContainer)
|
||||
{
|
||||
qWarning() << "no currentEvent";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!index.isValid())
|
||||
{
|
||||
qWarning() << "unexpected invalid index";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (index.row() < 0 || std::size_t(index.row()) >= m_actionsContainer->size())
|
||||
{
|
||||
qWarning() << "unexpected row" << index.row();
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto &action = m_actionsContainer->at(index.row());
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole:
|
||||
return tr("Execute a piece of code");
|
||||
case Qt::DecorationRole:
|
||||
return QIcon{":/qtgameengine/icons/code-action.png"};
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void ActionsContainerModel::setActionsContainer(ActionsContainer *actionsContainer)
|
||||
{
|
||||
beginResetModel();
|
||||
m_actionsContainer = actionsContainer;
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
Action *ActionsContainerModel::getAction(const QModelIndex &index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
{
|
||||
qWarning() << "unexpected invalid index";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return getAction(index.row());
|
||||
}
|
||||
|
||||
const Action *ActionsContainerModel::getAction(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
{
|
||||
qWarning() << "unexpected invalid index";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return getAction(index.row());
|
||||
}
|
||||
|
||||
Action *ActionsContainerModel::getAction(int row)
|
||||
{
|
||||
if (!m_actionsContainer)
|
||||
{
|
||||
qWarning() << "invalid actions container";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (row < 0 || std::size_t(row) >= m_actionsContainer->size())
|
||||
{
|
||||
qWarning() << "unexpected row" << row;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &*std::next(std::begin(*m_actionsContainer), row);
|
||||
}
|
||||
|
||||
const Action *ActionsContainerModel::getAction(int row) const
|
||||
{
|
||||
if (!m_actionsContainer)
|
||||
{
|
||||
qWarning() << "invalid actions container";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (row < 0 || std::size_t(row) >= m_actionsContainer->size())
|
||||
{
|
||||
qWarning() << "unexpected row" << row;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &*std::next(std::cbegin(*m_actionsContainer), row);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
|
||||
class ActionsContainerModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ActionsContainerModel(QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
ActionsContainer *actionsContainer() const { return m_actionsContainer; }
|
||||
void setActionsContainer(ActionsContainer *actionsContainer);
|
||||
|
||||
Action *getAction(const QModelIndex &index);
|
||||
const Action *getAction(const QModelIndex &index) const;
|
||||
Action *getAction(int row);
|
||||
const Action *getAction(int row) const;
|
||||
|
||||
private:
|
||||
ActionsContainer *m_actionsContainer{};
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
#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
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ConstantsModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return NumberOfColumns;
|
||||
}
|
||||
|
||||
QVariant ConstantsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
Q_UNUSED(role)
|
||||
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 {};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "includedfilesmodel.h"
|
||||
|
||||
#include "projectcontainer.h"
|
||||
|
||||
IncludedFilesModel::IncludedFilesModel(ProjectContainer &project, QObject *parent) :
|
||||
QAbstractListModel{parent},
|
||||
m_project{project}
|
||||
{
|
||||
}
|
||||
|
||||
int IncludedFilesModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
QVariant IncludedFilesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
Q_UNUSED(role)
|
||||
return {};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -0,0 +1,178 @@
|
||||
#include "objecteventsmodel.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QIcon>
|
||||
|
||||
#include "futurecpp.h"
|
||||
|
||||
ObjectEventsModel::ObjectEventsModel(Object::events_container_t &events, QObject *parent) :
|
||||
QAbstractListModel{parent},
|
||||
m_events{events}
|
||||
{
|
||||
}
|
||||
|
||||
int ObjectEventsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_events.size();
|
||||
}
|
||||
|
||||
QVariant ObjectEventsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
|
||||
if (index.row() < 0 || std::size_t(index.row()) >= m_events.size())
|
||||
{
|
||||
qWarning() << "row out of bounds" << index.row();
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto &pair = *std::next(std::cbegin(m_events), index.row());
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole:
|
||||
switch (pair.first)
|
||||
{
|
||||
case Object::EventType::Create: return tr("Create");
|
||||
case Object::EventType::Destroy: return tr("Destroy");
|
||||
case Object::EventType::Step: return tr("Step");
|
||||
case Object::EventType::Draw: return tr("Draw");
|
||||
default:
|
||||
qWarning() << "unknown event type" << std::to_underlying(pair.first);
|
||||
return QString::number(std::to_underlying(pair.first));
|
||||
}
|
||||
case Qt::DecorationRole:
|
||||
switch (pair.first)
|
||||
{
|
||||
case Object::EventType::Create: return QIcon{":/qtgameengine/icons/event-create.png"};
|
||||
case Object::EventType::Destroy: return QIcon{":/qtgameengine/icons/event-destroy.png"};
|
||||
case Object::EventType::Step: return QIcon{":/qtgameengine/icons/event-step.png"};
|
||||
case Object::EventType::Draw: return QIcon{":/qtgameengine/icons/event-draw.png"};
|
||||
default:
|
||||
qWarning() << "unknown event type" << std::to_underlying(pair.first);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ObjectEventsModel::removeRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
|
||||
if (row < 0 || std::size_t(row) >= m_events.size())
|
||||
{
|
||||
qWarning() << "unexpected row" << row;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count < 0 || std::size_t(count) > m_events.size() - row)
|
||||
{
|
||||
qWarning() << "unexpected row+count" << count << row;
|
||||
return false;
|
||||
}
|
||||
|
||||
beginRemoveRows({}, row, row + count - 1);
|
||||
auto begin = std::next(std::begin(m_events), row);
|
||||
auto end = std::next(begin, count);
|
||||
m_events.erase(begin, end);
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectEventsModel::addEvent(Object::EventType eventType)
|
||||
{
|
||||
if (m_events.contains(eventType))
|
||||
{
|
||||
qWarning() << std::to_underlying(eventType) << "duplicate";
|
||||
return false;
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
m_events[eventType];
|
||||
endResetModel();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectEventsModel::changeEvent(Object::EventType eventType, Object::EventType newEventType)
|
||||
{
|
||||
const auto iter = m_events.find(eventType);
|
||||
if (iter == std::cend(m_events))
|
||||
{
|
||||
qWarning() << std::to_underlying(eventType) << "not found";
|
||||
return false;
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
auto value = std::move(iter->second);
|
||||
m_events.erase(iter);
|
||||
m_events[newEventType] = std::move(value);
|
||||
endResetModel();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectEventsModel::removeEvent(Object::EventType eventType)
|
||||
{
|
||||
const auto iter = m_events.find(eventType);
|
||||
if (iter == std::cend(m_events))
|
||||
{
|
||||
qWarning() << std::to_underlying(eventType) << "not found";
|
||||
return false;
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
m_events.erase(iter);
|
||||
endResetModel();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::pair<const Object::EventType, ActionsContainer> *ObjectEventsModel::getEvent(const QModelIndex &index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
{
|
||||
qWarning() << "unexpected invalid index";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return getEvent(index.row());
|
||||
}
|
||||
|
||||
const std::pair<const Object::EventType, ActionsContainer> *ObjectEventsModel::getEvent(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
{
|
||||
qWarning() << "unexpected invalid index";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return getEvent(index.row());
|
||||
}
|
||||
|
||||
std::pair<const Object::EventType, ActionsContainer> *ObjectEventsModel::getEvent(int row)
|
||||
{
|
||||
if (row < 0 || std::size_t(row) >= m_events.size())
|
||||
{
|
||||
qWarning() << "unexpected row" << row;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &*std::next(std::begin(m_events), row);
|
||||
}
|
||||
|
||||
const std::pair<const Object::EventType, ActionsContainer> *ObjectEventsModel::getEvent(int row) const
|
||||
{
|
||||
if (row < 0 || std::size_t(row) >= m_events.size())
|
||||
{
|
||||
qWarning() << "unexpected row" << row;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &*std::next(std::cbegin(m_events), row);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
|
||||
class ObjectEventsModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ObjectEventsModel(Object::events_container_t &events, QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex{}) override;
|
||||
|
||||
bool addEvent(Object::EventType eventType);
|
||||
bool changeEvent(Object::EventType eventType, Object::EventType newEventType);
|
||||
bool removeEvent(Object::EventType eventType);
|
||||
|
||||
std::pair<const Object::EventType, ActionsContainer> *getEvent(const QModelIndex &index);
|
||||
const std::pair<const Object::EventType, ActionsContainer> *getEvent(const QModelIndex &index) const;
|
||||
std::pair<const Object::EventType, ActionsContainer> *getEvent(int row);
|
||||
const std::pair<const Object::EventType, ActionsContainer> *getEvent(int row) const;
|
||||
|
||||
private:
|
||||
Object::events_container_t &m_events;
|
||||
};
|
||||
@@ -0,0 +1,196 @@
|
||||
#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
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_points.size();
|
||||
}
|
||||
|
||||
int PathPointsModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return NumberOfColumns;
|
||||
}
|
||||
|
||||
QVariant PathPointsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (index.row() < 0 || std::size_t(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 {};
|
||||
}
|
||||
|
||||
bool PathPointsModel::insertRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
|
||||
if (row < 0 || std::size_t(row) > m_points.size())
|
||||
{
|
||||
qWarning() << "unexpected row" << row;
|
||||
return false;
|
||||
}
|
||||
|
||||
beginInsertRows({}, row, row + count - 1);
|
||||
for (size_t i = 0; i < std::size_t(count); i++)
|
||||
m_points.emplace(std::next(std::begin(m_points), row + i));
|
||||
endInsertRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PathPointsModel::removeRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
|
||||
if (row < 0 || std::size_t(row) >= m_points.size())
|
||||
{
|
||||
qWarning() << "unexpected row" << row;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count < 0 || std::size_t(count) > m_points.size() - row)
|
||||
{
|
||||
qWarning() << "unexpected row+count" << count << row;
|
||||
return false;
|
||||
}
|
||||
|
||||
beginRemoveRows({}, row, row + count - 1);
|
||||
auto begin = std::next(std::begin(m_points), row);
|
||||
auto end = std::next(begin, count);
|
||||
m_points.erase(begin, end);
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<Path::Point> PathPointsModel::getPoint(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
{
|
||||
qWarning() << "unexpected invalid index" << index;
|
||||
return {};
|
||||
}
|
||||
|
||||
return getPoint(index.row());
|
||||
}
|
||||
|
||||
std::optional<Path::Point> PathPointsModel::getPoint(int row) const
|
||||
{
|
||||
if (row < 0 || std::size_t(row) >= m_points.size())
|
||||
{
|
||||
qWarning() << "unexpected row" << row;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return m_points.at(row);
|
||||
}
|
||||
|
||||
bool PathPointsModel::insertPoint(std::size_t index, Path::Point point)
|
||||
{
|
||||
if (index > m_points.size())
|
||||
{
|
||||
qWarning() << "unexpected index" << index;
|
||||
return false;
|
||||
}
|
||||
|
||||
beginInsertRows({}, index, index);
|
||||
m_points.emplace(std::next(std::begin(m_points), index), point);
|
||||
endInsertRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PathPointsModel::updatePoint(std::size_t index, Path::Point point)
|
||||
{
|
||||
if (index >= m_points.size())
|
||||
{
|
||||
qWarning() << "unexpected index" << index;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_points.at(index) = point;
|
||||
const auto modelIndex = this->index(index, 0);
|
||||
emit dataChanged(modelIndex, modelIndex, { Qt::DisplayRole, Qt::EditRole });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PathPointsModel::removePoint(std::size_t index)
|
||||
{
|
||||
if (index >= m_points.size())
|
||||
{
|
||||
qWarning() << "unexpected index" << index;
|
||||
return false;
|
||||
}
|
||||
|
||||
beginRemoveRows({}, index, index);
|
||||
m_points.erase(std::next(std::begin(m_points), index));
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PathPointsModel::pointInserted(std::size_t index)
|
||||
{
|
||||
beginInsertRows({}, index, index);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void PathPointsModel::pointMoved(std::size_t index)
|
||||
{
|
||||
const auto modelIndex = this->index(index, 0);
|
||||
emit dataChanged(modelIndex, modelIndex, {Qt::DisplayRole, Qt::EditRole});
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#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 = QModelIndex{}) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex{}) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex{}) override;
|
||||
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex{}) override;
|
||||
|
||||
std::optional<Path::Point> getPoint(const QModelIndex &index) const;
|
||||
std::optional<Path::Point> getPoint(int row) const;
|
||||
|
||||
bool insertPoint(std::size_t index, Path::Point point);
|
||||
bool updatePoint(std::size_t index, Path::Point point);
|
||||
bool removePoint(std::size_t index);
|
||||
|
||||
public slots:
|
||||
void pointInserted(std::size_t index);
|
||||
void pointMoved(std::size_t index);
|
||||
|
||||
private:
|
||||
std::vector<Path::Point> &m_points;
|
||||
};
|
||||
@@ -0,0 +1,999 @@
|
||||
#include "projecttreemodel.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QPixmap>
|
||||
#include <QIcon>
|
||||
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
|
||||
#include "futurecpp.h"
|
||||
#include "projectcontainer.h"
|
||||
|
||||
namespace {
|
||||
enum {
|
||||
RowSprites,
|
||||
RowSounds,
|
||||
RowBackgrounds,
|
||||
RowPaths,
|
||||
RowScripts,
|
||||
RowFonts,
|
||||
RowTimeLines,
|
||||
RowObjects,
|
||||
RowRooms,
|
||||
RowGameInformation,
|
||||
RowGlobalGameSettings,
|
||||
RowExtensionPackages,
|
||||
NumberOfRows
|
||||
};
|
||||
}
|
||||
|
||||
ProjectTreeModel::ProjectTreeModel(QObject *parent) :
|
||||
QAbstractItemModel{parent}
|
||||
{
|
||||
}
|
||||
|
||||
ProjectTreeModel::ProjectTreeModel(ProjectContainer &project, QObject *parent) :
|
||||
QAbstractItemModel{parent},
|
||||
m_project{&project}
|
||||
{
|
||||
}
|
||||
|
||||
QModelIndex ProjectTreeModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
return createIndex(row, column, std::to_underlying(NodeType::Root));
|
||||
else if (!parent.parent().isValid())
|
||||
{
|
||||
switch (nodeType(parent))
|
||||
{
|
||||
case NodeType::Root:
|
||||
switch (parent.row())
|
||||
{
|
||||
case RowSprites: return createIndex(row, column, std::to_underlying(NodeType::Sprite));
|
||||
case RowSounds: return createIndex(row, column, std::to_underlying(NodeType::Sound));
|
||||
case RowBackgrounds: return createIndex(row, column, std::to_underlying(NodeType::Background));
|
||||
case RowPaths: return createIndex(row, column, std::to_underlying(NodeType::Path));
|
||||
case RowScripts: return createIndex(row, column, std::to_underlying(NodeType::Script));
|
||||
case RowFonts: return createIndex(row, column, std::to_underlying(NodeType::Font));
|
||||
case RowTimeLines: return createIndex(row, column, std::to_underlying(NodeType::TimeLine));
|
||||
case RowObjects: return createIndex(row, column, std::to_underlying(NodeType::Object));
|
||||
case RowRooms: return createIndex(row, column, std::to_underlying(NodeType::Room));
|
||||
default:
|
||||
qWarning() << "unexpected parent row" << parent.row();
|
||||
return {};
|
||||
}
|
||||
default:
|
||||
qWarning() << "unexpected parent type" << parent.internalId();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << "unexpected parent";
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex ProjectTreeModel::parent(const QModelIndex &child) const
|
||||
{
|
||||
switch (nodeType(child))
|
||||
{
|
||||
case NodeType::Root: return {};
|
||||
case NodeType::Sprite: return rootFor<Sprite>();
|
||||
case NodeType::Sound: return rootFor<Sound>();
|
||||
case NodeType::Background: return rootFor<Background>();
|
||||
case NodeType::Path: return rootFor<Path>();
|
||||
case NodeType::Script: return rootFor<Script>();
|
||||
case NodeType::Font: return rootFor<Font>();
|
||||
case NodeType::TimeLine: return rootFor<TimeLine>();
|
||||
case NodeType::Object: return rootFor<Object>();
|
||||
case NodeType::Room: return rootFor<Room>();
|
||||
default:
|
||||
qWarning() << "unexpected child type" << child.internalId();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
int ProjectTreeModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
return m_project ? NumberOfRows : 0;
|
||||
|
||||
switch (nodeType(parent))
|
||||
{
|
||||
case NodeType::Root:
|
||||
switch (parent.row())
|
||||
{
|
||||
case RowSprites: return m_project ? m_project->containerFor<Sprite>().size() : 0;
|
||||
case RowSounds: return m_project ? m_project->containerFor<Sound>().size() : 0;
|
||||
case RowBackgrounds: return m_project ? m_project->containerFor<Background>().size() : 0;
|
||||
case RowPaths: return m_project ? m_project->containerFor<Path>().size() : 0;
|
||||
case RowScripts: return m_project ? m_project->containerFor<Script>().size() : 0;
|
||||
case RowFonts: return m_project ? m_project->containerFor<Font>().size() : 0;
|
||||
case RowTimeLines: return m_project ? m_project->containerFor<TimeLine>().size() : 0;
|
||||
case RowObjects: return m_project ? m_project->containerFor<Object>().size() : 0;
|
||||
case RowRooms: return m_project ? m_project->containerFor<Room>().size() : 0;
|
||||
case RowGameInformation:
|
||||
case RowGlobalGameSettings:
|
||||
case RowExtensionPackages:
|
||||
return 0;
|
||||
default:
|
||||
qWarning() << "unexpected parent row" << parent.row();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return {};
|
||||
case NodeType::Sprite:
|
||||
case NodeType::Sound:
|
||||
case NodeType::Background:
|
||||
case NodeType::Path:
|
||||
case NodeType::Script:
|
||||
case NodeType::Font:
|
||||
case NodeType::TimeLine:
|
||||
case NodeType::Object:
|
||||
case NodeType::Room:
|
||||
return 0;
|
||||
default:
|
||||
qWarning() << "unexpected parent child type" << parent.internalId();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int ProjectTreeModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
return 1;
|
||||
|
||||
switch (nodeType(parent))
|
||||
{
|
||||
case NodeType::Root:
|
||||
switch (parent.row())
|
||||
{
|
||||
case RowSprites:
|
||||
case RowSounds:
|
||||
case RowBackgrounds:
|
||||
case RowPaths:
|
||||
case RowScripts:
|
||||
case RowFonts:
|
||||
case RowTimeLines:
|
||||
case RowObjects:
|
||||
case RowRooms:
|
||||
case RowGameInformation:
|
||||
case RowGlobalGameSettings:
|
||||
case RowExtensionPackages:
|
||||
return 1;
|
||||
default:
|
||||
qWarning() << "unexpected parent row" << parent.row();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return {};
|
||||
case NodeType::Sprite:
|
||||
case NodeType::Sound:
|
||||
case NodeType::Background:
|
||||
case NodeType::Path:
|
||||
case NodeType::Script:
|
||||
case NodeType::Font:
|
||||
case NodeType::TimeLine:
|
||||
case NodeType::Object:
|
||||
case NodeType::Room:
|
||||
return 1;
|
||||
default:
|
||||
qWarning() << "unexpected parent child type" << parent.internalId();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
QVariant ProjectTreeModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
{
|
||||
qWarning() << "invalid index";
|
||||
return {};
|
||||
}
|
||||
|
||||
switch (nodeType(index))
|
||||
{
|
||||
case NodeType::Root:
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole:
|
||||
switch (index.row())
|
||||
{
|
||||
case RowSprites: return tr("Sprites");
|
||||
case RowSounds: return tr("Sounds");
|
||||
case RowBackgrounds: return tr("Backgrounds");
|
||||
case RowPaths: return tr("Paths");
|
||||
case RowScripts: return tr("Scripts");
|
||||
case RowFonts: return tr("Fonts");
|
||||
case RowTimeLines: return tr("Time Lines");
|
||||
case RowObjects: return tr("Objects");
|
||||
case RowRooms: return tr("Rooms");
|
||||
case RowGameInformation: return tr("Game Information");
|
||||
case RowGlobalGameSettings: return tr("Global Game Settings");
|
||||
case RowExtensionPackages: return tr("Extension Packages");
|
||||
default:
|
||||
qWarning() << "unexpected root row" << index.row();
|
||||
return {};
|
||||
}
|
||||
case Qt::DecorationRole:
|
||||
switch (index.row())
|
||||
{
|
||||
case RowSprites:
|
||||
case RowSounds:
|
||||
case RowBackgrounds:
|
||||
case RowPaths:
|
||||
case RowScripts:
|
||||
case RowFonts:
|
||||
case RowTimeLines:
|
||||
case RowObjects:
|
||||
case RowRooms: return QIcon{":/qtgameengine/icons/folder.png"};
|
||||
case RowGameInformation: return QIcon{":/qtgameengine/icons/game-information-file.png"};
|
||||
case RowGlobalGameSettings: return QIcon{":/qtgameengine/icons/global-game-settings-file.png"};
|
||||
case RowExtensionPackages: return QIcon{":/qtgameengine/icons/extension-packages-file.png"};
|
||||
default:
|
||||
qWarning() << "unexpected root row" << index.row();
|
||||
return {};
|
||||
}
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
case NodeType::Sprite: return dataFor<Sprite>(index, role);
|
||||
case NodeType::Sound: return dataFor<Sound>(index, role);
|
||||
case NodeType::Background: return dataFor<Background>(index, role);
|
||||
case NodeType::Path: return dataFor<Path>(index, role);
|
||||
case NodeType::Script: return dataFor<Script>(index, role);
|
||||
case NodeType::Font: return dataFor<Font>(index, role);
|
||||
case NodeType::TimeLine: return dataFor<TimeLine>(index, role);
|
||||
case NodeType::Object: return dataFor<Object>(index, role);
|
||||
case NodeType::Room: return dataFor<Room>(index, role);
|
||||
default:
|
||||
qWarning() << "unexpected index type" << index.internalId();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Qt::ItemFlags ProjectTreeModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
auto flags = QAbstractItemModel::flags(index);
|
||||
|
||||
switch (nodeType(index))
|
||||
{
|
||||
case NodeType::Root:
|
||||
break;
|
||||
case NodeType::Sprite:
|
||||
case NodeType::Sound:
|
||||
case NodeType::Background:
|
||||
case NodeType::Path:
|
||||
case NodeType::Script:
|
||||
case NodeType::Font:
|
||||
case NodeType::TimeLine:
|
||||
case NodeType::Object:
|
||||
case NodeType::Room:
|
||||
flags |= Qt::ItemIsEditable;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
bool ProjectTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
switch (const auto nodeType = this->nodeType(index))
|
||||
{
|
||||
case NodeType::Sprite: return setDataFor<Sprite>(index, value, role);
|
||||
case NodeType::Sound: return setDataFor<Sound>(index, value, role);
|
||||
case NodeType::Background: return setDataFor<Background>(index, value, role);
|
||||
case NodeType::Path: return setDataFor<Path>(index, value, role);
|
||||
case NodeType::Script: return setDataFor<Script>(index, value, role);
|
||||
case NodeType::Font: return setDataFor<Font>(index, value, role);
|
||||
case NodeType::TimeLine: return setDataFor<TimeLine>(index, value, role);
|
||||
case NodeType::Object: return setDataFor<Object>(index, value, role);
|
||||
case NodeType::Room: return setDataFor<Room>(index, value, role);
|
||||
default:
|
||||
qWarning() << "unexpected nodeType" << std::to_underlying(nodeType);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ProjectTreeModel::insertRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
if (auto result = insertRowsFor<Sprite>(row, count, parent)) return *result;
|
||||
if (auto result = insertRowsFor<Sound>(row, count, parent)) return *result;
|
||||
if (auto result = insertRowsFor<Background>(row, count, parent)) return *result;
|
||||
if (auto result = insertRowsFor<Path>(row, count, parent)) return *result;
|
||||
if (auto result = insertRowsFor<Script>(row, count, parent)) return *result;
|
||||
if (auto result = insertRowsFor<Font>(row, count, parent)) return *result;
|
||||
if (auto result = insertRowsFor<TimeLine>(row, count, parent)) return *result;
|
||||
if (auto result = insertRowsFor<Object>(row, count, parent)) return *result;
|
||||
if (auto result = insertRowsFor<Room>(row, count, parent)) return *result;
|
||||
|
||||
qWarning() << "unexpected parent" << parent;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProjectTreeModel::removeRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
if (auto result = removeRowsFor<Sprite>(row, count, parent)) return *result;
|
||||
if (auto result = removeRowsFor<Sound>(row, count, parent)) return *result;
|
||||
if (auto result = removeRowsFor<Background>(row, count, parent)) return *result;
|
||||
if (auto result = removeRowsFor<Path>(row, count, parent)) return *result;
|
||||
if (auto result = removeRowsFor<Script>(row, count, parent)) return *result;
|
||||
if (auto result = removeRowsFor<Font>(row, count, parent)) return *result;
|
||||
if (auto result = removeRowsFor<TimeLine>(row, count, parent)) return *result;
|
||||
if (auto result = removeRowsFor<Object>(row, count, parent)) return *result;
|
||||
if (auto result = removeRowsFor<Room>(row, count, parent)) return *result;
|
||||
|
||||
qWarning() << "unexpected parent" << parent;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ProjectTreeModel::setProject(ProjectContainer *project)
|
||||
{
|
||||
beginResetModel();
|
||||
m_project = project;
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
ProjectTreeModel::NodeType ProjectTreeModel::nodeType(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
qWarning() << "invalid index";
|
||||
|
||||
return NodeType(index.internalId());
|
||||
}
|
||||
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Sprite>() const
|
||||
{
|
||||
return createIndex(RowSprites, 0, std::to_underlying(NodeType::Root));
|
||||
}
|
||||
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Sound>() const
|
||||
{
|
||||
return createIndex(RowSounds, 0, std::to_underlying(NodeType::Root));
|
||||
}
|
||||
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Background>() const
|
||||
{
|
||||
return createIndex(RowBackgrounds, 0, std::to_underlying(NodeType::Root));
|
||||
}
|
||||
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Path>() const
|
||||
{
|
||||
return createIndex(RowPaths, 0, std::to_underlying(NodeType::Root));
|
||||
}
|
||||
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Script>() const
|
||||
{
|
||||
return createIndex(RowScripts, 0, std::to_underlying(NodeType::Root));
|
||||
}
|
||||
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Font>() const
|
||||
{
|
||||
return createIndex(RowFonts, 0, std::to_underlying(NodeType::Root));
|
||||
}
|
||||
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<TimeLine>() const
|
||||
{
|
||||
return createIndex(RowTimeLines, 0, std::to_underlying(NodeType::Root));
|
||||
}
|
||||
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Object>() const
|
||||
{
|
||||
return createIndex(RowObjects, 0, std::to_underlying(NodeType::Root));
|
||||
}
|
||||
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Room>() const
|
||||
{
|
||||
return createIndex(RowRooms, 0, std::to_underlying(NodeType::Root));
|
||||
}
|
||||
|
||||
QModelIndex ProjectTreeModel::gameInformationRoot() const
|
||||
{
|
||||
return createIndex(RowGameInformation, 0, std::to_underlying(NodeType::Root));
|
||||
}
|
||||
|
||||
QModelIndex ProjectTreeModel::globalGameSettingsRoot() const
|
||||
{
|
||||
return createIndex(RowGlobalGameSettings, 0, std::to_underlying(NodeType::Root));
|
||||
}
|
||||
|
||||
QModelIndex ProjectTreeModel::extensionPackagesRoot() const
|
||||
{
|
||||
return createIndex(RowExtensionPackages, 0, std::to_underlying(NodeType::Root));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *ProjectTreeModel::get(const QModelIndex &index)
|
||||
{
|
||||
if (!m_project)
|
||||
{
|
||||
qWarning() << "unexpected null project";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (const auto nodeType = this->nodeType(index); nodeType != nodeTypeFor<T>())
|
||||
{
|
||||
qWarning() << "unexpected index type" << std::to_underlying(nodeType);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto &container = m_project->containerFor<T>();
|
||||
if (index.row() < 0 || std::size_t(index.row()) >= container.size())
|
||||
{
|
||||
qWarning() << "invalid row" << index.row();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &*std::next(std::begin(container), index.row());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T *ProjectTreeModel::get(const QModelIndex &index) const
|
||||
{
|
||||
if (!m_project)
|
||||
{
|
||||
qWarning() << "unexpected null project";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (const auto nodeType = this->nodeType(index); nodeType != nodeTypeFor<T>())
|
||||
{
|
||||
qWarning() << "unexpected index type" << std::to_underlying(nodeType);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto &container = m_project->containerFor<T>();
|
||||
if (index.row() < 0 || std::size_t(index.row()) >= container.size())
|
||||
{
|
||||
qWarning() << "invalid row" << index.row();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &*std::next(std::cbegin(container), index.row());
|
||||
}
|
||||
|
||||
template Sprite *ProjectTreeModel::get<Sprite>(const QModelIndex &index);
|
||||
template const Sprite *ProjectTreeModel::get<Sprite>(const QModelIndex &index) const;
|
||||
template Sound *ProjectTreeModel::get<Sound>(const QModelIndex &index);
|
||||
template const Sound *ProjectTreeModel::get<Sound>(const QModelIndex &index) const;
|
||||
template Background *ProjectTreeModel::get<Background>(const QModelIndex &index);
|
||||
template const Background *ProjectTreeModel::get<Background>(const QModelIndex &index) const;
|
||||
template Path *ProjectTreeModel::get<Path>(const QModelIndex &index);
|
||||
template const Path *ProjectTreeModel::get<Path>(const QModelIndex &index) const;
|
||||
template Script *ProjectTreeModel::get<Script>(const QModelIndex &index);
|
||||
template const Script *ProjectTreeModel::get<Script>(const QModelIndex &index) const;
|
||||
template Font *ProjectTreeModel::get<Font>(const QModelIndex &index);
|
||||
template const Font *ProjectTreeModel::get<Font>(const QModelIndex &index) const;
|
||||
template TimeLine *ProjectTreeModel::get<TimeLine>(const QModelIndex &index);
|
||||
template const TimeLine *ProjectTreeModel::get<TimeLine>(const QModelIndex &index) const;
|
||||
template Object *ProjectTreeModel::get<Object>(const QModelIndex &index);
|
||||
template const Object *ProjectTreeModel::get<Object>(const QModelIndex &index) const;
|
||||
template Room *ProjectTreeModel::get<Room>(const QModelIndex &index);
|
||||
template const Room *ProjectTreeModel::get<Room>(const QModelIndex &index) const;
|
||||
|
||||
template<typename T>
|
||||
T *ProjectTreeModel::create()
|
||||
{
|
||||
if (!m_project)
|
||||
{
|
||||
qWarning() << "unexpected null project";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto &container = m_project->containerFor<T>();
|
||||
|
||||
beginInsertRows(rootFor<T>(), container.size(), container.size());
|
||||
container.emplace_back(T { .name = getFreeNameFor<T>(container) });
|
||||
endInsertRows();
|
||||
|
||||
return &container.back();
|
||||
}
|
||||
|
||||
template Sprite *ProjectTreeModel::create<Sprite>();
|
||||
template Sound *ProjectTreeModel::create<Sound>();
|
||||
template Background *ProjectTreeModel::create<Background>();
|
||||
template Path *ProjectTreeModel::create<Path>();
|
||||
template Script *ProjectTreeModel::create<Script>();
|
||||
template Font *ProjectTreeModel::create<Font>();
|
||||
template TimeLine *ProjectTreeModel::create<TimeLine>();
|
||||
template Object *ProjectTreeModel::create<Object>();
|
||||
template Room *ProjectTreeModel::create<Room>();
|
||||
|
||||
template<typename T>
|
||||
bool ProjectTreeModel::remove(const T &entry)
|
||||
{
|
||||
if (!m_project)
|
||||
{
|
||||
qWarning() << "unexpected null project";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto &container = m_project->containerFor<T>();
|
||||
const auto iter = std::find_if(std::begin(container), std::end(container),
|
||||
[&entry](const auto &otherEntry){ return &entry == &otherEntry; });
|
||||
if (iter == std::cend(container))
|
||||
{
|
||||
qWarning() << "entry not from this project!";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto row = std::distance(std::begin(container), iter);
|
||||
|
||||
onBeforeRemove<T>(*iter);
|
||||
|
||||
emitAboutToBeRemoved<T>(*iter);
|
||||
|
||||
beginRemoveRows(rootFor<T>(), row, row);
|
||||
container.erase(iter);
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template bool ProjectTreeModel::remove<Sprite>(const Sprite &entry);
|
||||
template bool ProjectTreeModel::remove<Sound>(const Sound &entry);
|
||||
template bool ProjectTreeModel::remove<Background>(const Background &entry);
|
||||
template bool ProjectTreeModel::remove<Path>(const Path &entry);
|
||||
template bool ProjectTreeModel::remove<Script>(const Script &entry);
|
||||
template bool ProjectTreeModel::remove<Font>(const Font &entry);
|
||||
template bool ProjectTreeModel::remove<TimeLine>(const TimeLine &entry);
|
||||
template bool ProjectTreeModel::remove<Object>(const Object &entry);
|
||||
template bool ProjectTreeModel::remove<Room>(const Room &entry);
|
||||
|
||||
template<typename T>
|
||||
bool ProjectTreeModel::rename(const T &entry, const QString &newName)
|
||||
{
|
||||
if (!m_project)
|
||||
{
|
||||
qWarning() << "unexpected null project";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto &container = m_project->containerFor<T>();
|
||||
const auto iter = std::find_if(std::begin(container), std::end(container),
|
||||
[&entry](const auto &otherEntry){ return &entry == &otherEntry; });
|
||||
if (iter == std::cend(container))
|
||||
{
|
||||
qWarning() << "entry not from this project!";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iter->name == newName)
|
||||
return true;
|
||||
|
||||
if (std::any_of(std::cbegin(container), std::cend(container),
|
||||
[&newName](const auto &entry){ return entry.name == newName; }))
|
||||
{
|
||||
qWarning() << "duplicate name" << newName;
|
||||
return false;
|
||||
}
|
||||
|
||||
onBeforeRename<T>(*iter, newName);
|
||||
|
||||
auto oldName = std::move(iter->name);
|
||||
iter->name = std::move(newName);
|
||||
|
||||
emitNameChanged<T>(*iter, oldName);
|
||||
const auto index = this->index(std::distance(std::begin(container), iter), 0, rootFor<T>());
|
||||
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
|
||||
|
||||
onAfterRename<T>(*iter, std::move(oldName));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template bool ProjectTreeModel::rename<Sprite>(const Sprite &entry, const QString &newName);
|
||||
template bool ProjectTreeModel::rename<Sound>(const Sound &entry, const QString &newName);
|
||||
template bool ProjectTreeModel::rename<Background>(const Background &entry, const QString &newName);
|
||||
template bool ProjectTreeModel::rename<Path>(const Path &entry, const QString &newName);
|
||||
template bool ProjectTreeModel::rename<Script>(const Script &entry, const QString &newName);
|
||||
template bool ProjectTreeModel::rename<Font>(const Font &entry, const QString &newName);
|
||||
template bool ProjectTreeModel::rename<TimeLine>(const TimeLine &entry, const QString &newName);
|
||||
template bool ProjectTreeModel::rename<Object>(const Object &entry, const QString &newName);
|
||||
template bool ProjectTreeModel::rename<Room>(const Room &entry, const QString &newName);
|
||||
|
||||
bool ProjectTreeModel::setSpritePixmaps(const Sprite &sprite, std::vector<QPixmap> &&pixmaps)
|
||||
{
|
||||
if (!m_project)
|
||||
{
|
||||
qWarning() << "unexpected null project";
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
auto &container = m_project->sprites;
|
||||
const auto iter = std::find_if(std::begin(container), std::end(container),
|
||||
[&sprite](const auto &otherEntry){ return &sprite == &otherEntry; });
|
||||
if (iter == std::cend(container))
|
||||
{
|
||||
qWarning() << "sprite not from this project!";
|
||||
return false;
|
||||
}
|
||||
|
||||
iter->pixmaps = std::move(pixmaps);
|
||||
|
||||
const auto index = this->index(std::distance(std::begin(container), iter), 0, rootFor<Sprite>());
|
||||
emit dataChanged(index, index, { Qt::DecorationRole });
|
||||
|
||||
emit spritePixmapsChanged(*iter);
|
||||
}
|
||||
|
||||
for (auto iter = std::cbegin(m_project->objects); iter != std::cend(m_project->objects); iter++)
|
||||
{
|
||||
if (iter->spriteName != sprite.name)
|
||||
continue;
|
||||
|
||||
const auto index = this->index(std::distance(std::cbegin(m_project->objects), iter), 0, rootFor<Object>());
|
||||
emit dataChanged(index, index, {Qt::DecorationRole});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProjectTreeModel::setBackgroundPixmap(const Background &background, QPixmap &&pixmap)
|
||||
{
|
||||
if (!m_project)
|
||||
{
|
||||
qWarning() << "unexpected null project";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto &container = m_project->backgrounds;
|
||||
const auto iter = std::find_if(std::begin(container), std::end(container),
|
||||
[&background](const auto &otherEntry){ return &background == &otherEntry; });
|
||||
if (iter == std::cend(container))
|
||||
{
|
||||
qWarning() << "background not from this project!";
|
||||
return false;
|
||||
}
|
||||
|
||||
iter->pixmap = std::move(pixmap);
|
||||
|
||||
const auto index = this->index(std::distance(std::begin(container), iter), 0, rootFor<Background>());
|
||||
emit dataChanged(index, index, { Qt::DecorationRole });
|
||||
|
||||
emit backgroundPixmapChanged(*iter);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
QVariant ProjectTreeModel::dataFor(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!m_project)
|
||||
{
|
||||
qWarning() << "unexpected null project";
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto &container = m_project->containerFor<T>();
|
||||
if (std::size_t(index.row()) >= container.size())
|
||||
{
|
||||
qWarning() << "index out of bounds" << index.row();
|
||||
return {};
|
||||
}
|
||||
|
||||
auto iter = std::next(std::cbegin(container), index.row());
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole:
|
||||
return iter->name;
|
||||
case Qt::DecorationRole:
|
||||
return iconFor<T>(*iter);
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
QVariant ProjectTreeModel::iconFor<Sprite>(const Sprite &entry) const
|
||||
{
|
||||
if (entry.pixmaps.empty() || entry.pixmaps.front().isNull())
|
||||
{
|
||||
QPixmap pixmap{16, 16};
|
||||
pixmap.fill(Qt::white);
|
||||
return pixmap;
|
||||
}
|
||||
return QIcon{entry.pixmaps.front()};
|
||||
}
|
||||
|
||||
template<>
|
||||
QVariant ProjectTreeModel::iconFor<Sound>(const Sound &entry) const
|
||||
{
|
||||
switch (entry.type)
|
||||
{
|
||||
case Sound::Type::Sound:
|
||||
return QIcon{":/qtgameengine/icons/sound-file.png"};
|
||||
case Sound::Type::Music:
|
||||
return QIcon{":/qtgameengine/icons/music-file.png"};
|
||||
default:
|
||||
qWarning() << "unexpected sound type" << std::to_underlying(entry.type);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
QVariant ProjectTreeModel::iconFor<Background>(const Background &entry) const
|
||||
{
|
||||
if (entry.pixmap.isNull())
|
||||
{
|
||||
QPixmap pixmap{64, 64};
|
||||
pixmap.fill(Qt::white);
|
||||
return QIcon{pixmap};
|
||||
}
|
||||
return QIcon{entry.pixmap};
|
||||
}
|
||||
|
||||
template<>
|
||||
QVariant ProjectTreeModel::iconFor<Path>(const Path &entry) const
|
||||
{
|
||||
Q_UNUSED(entry)
|
||||
return QIcon{":/qtgameengine/icons/path-file.png"};
|
||||
}
|
||||
|
||||
template<>
|
||||
QVariant ProjectTreeModel::iconFor<Script>(const Script &entry) const
|
||||
{
|
||||
Q_UNUSED(entry)
|
||||
return QIcon{":/qtgameengine/icons/script-file.png"};
|
||||
}
|
||||
|
||||
template<>
|
||||
QVariant ProjectTreeModel::iconFor<Font>(const Font &entry) const
|
||||
{
|
||||
Q_UNUSED(entry)
|
||||
return QIcon{":/qtgameengine/icons/font-file.png"};
|
||||
}
|
||||
|
||||
template<>
|
||||
QVariant ProjectTreeModel::iconFor<TimeLine>(const TimeLine &entry) const
|
||||
{
|
||||
Q_UNUSED(entry)
|
||||
return QIcon{":/qtgameengine/icons/timeline-file.png"};
|
||||
}
|
||||
|
||||
template<>
|
||||
QVariant ProjectTreeModel::iconFor<Object>(const Object &entry) const
|
||||
{
|
||||
if (m_project && !entry.spriteName.isEmpty())
|
||||
{
|
||||
const auto iter = std::find_if(std::cbegin(m_project->sprites), std::cend(m_project->sprites),
|
||||
[&](const Sprite &sprite){ return sprite.name == entry.spriteName; });
|
||||
if (iter == std::cend(m_project->sprites))
|
||||
qWarning() << "sprite" << entry.spriteName << "not found";
|
||||
else if (!iter->pixmaps.empty() && !iter->pixmaps.front().isNull())
|
||||
return QIcon{iter->pixmaps.front()};
|
||||
}
|
||||
|
||||
QPixmap pixmap{64, 64};
|
||||
pixmap.fill(Qt::white);
|
||||
return QIcon{pixmap};
|
||||
}
|
||||
|
||||
template<>
|
||||
QVariant ProjectTreeModel::iconFor<Room>(const Room &entry) const
|
||||
{
|
||||
Q_UNUSED(entry)
|
||||
return QIcon{":/qtgameengine/icons/room-file.png"};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool ProjectTreeModel::setDataFor(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (!m_project)
|
||||
{
|
||||
qWarning() << "unexpected null project";
|
||||
return {};
|
||||
}
|
||||
|
||||
auto &container = m_project->containerFor<T>();
|
||||
if (index.row() < 0 || std::size_t(index.row()) >= container.size())
|
||||
{
|
||||
qWarning() << "unexpected row" << index.row();
|
||||
return false;
|
||||
}
|
||||
auto iter = std::next(std::begin(container), index.row());
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole:
|
||||
if (auto name = value.toString(); name != iter->name)
|
||||
{
|
||||
if (std::any_of(std::cbegin(container), std::cend(container),
|
||||
[&name](const auto &entry){ return entry.name == name; }))
|
||||
{
|
||||
qWarning() << "duplicate name" << name;
|
||||
emit errorOccured(tr("A Sprite with the name \"%0\" is already existing").arg(name));
|
||||
return false;
|
||||
}
|
||||
onBeforeRename<T>(*iter, name);
|
||||
auto oldName = std::move(iter->name);
|
||||
iter->name = std::move(name);
|
||||
emitNameChanged<T>(*iter, oldName);
|
||||
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
|
||||
onAfterRename<T>(*iter, std::move(oldName));
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
qWarning() << "unexpected role" << role;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::optional<bool> ProjectTreeModel::insertRowsFor(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
if (parent != rootFor<T>())
|
||||
return std::nullopt;
|
||||
|
||||
if (!m_project)
|
||||
{
|
||||
qWarning() << "unexpected null project";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto &container = m_project->containerFor<T>();
|
||||
if (row < 0 || std::size_t(row) > container.size())
|
||||
{
|
||||
qWarning() << "unexpected row" << row;
|
||||
return false;
|
||||
}
|
||||
|
||||
beginInsertRows(parent, row, row + count - 1);
|
||||
for (size_t i = 0; i < std::size_t(count); i++)
|
||||
container.emplace(std::next(std::begin(container), row + i), T { .name = getFreeNameFor<T>(container) });
|
||||
endInsertRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::optional<bool> ProjectTreeModel::removeRowsFor(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
if (parent != rootFor<T>())
|
||||
return std::nullopt;
|
||||
|
||||
if (!m_project)
|
||||
{
|
||||
qWarning() << "unexpected null project";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto &container = m_project->containerFor<T>();
|
||||
|
||||
if (row < 0 || std::size_t(row) >= container.size())
|
||||
{
|
||||
qWarning() << "unexpected row" << row;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count < 0 || std::size_t(count) > container.size() - row)
|
||||
{
|
||||
qWarning() << "unexpected row+count" << count << row;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto begin = std::next(std::begin(container), row);
|
||||
auto end = std::next(begin, count);
|
||||
|
||||
for (auto iter = begin; iter != end; iter++)
|
||||
onBeforeRemove<T>(*iter);
|
||||
|
||||
for (auto iter = begin; iter != end; iter++)
|
||||
emitAboutToBeRemoved(*iter);
|
||||
|
||||
beginRemoveRows(parent, row, row + count - 1);
|
||||
container.erase(begin, end);
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T> void ProjectTreeModel::onBeforeRemove(const T &entry)
|
||||
{
|
||||
Q_UNUSED(entry)
|
||||
}
|
||||
|
||||
template<> void ProjectTreeModel::onBeforeRemove<Sprite>(const Sprite &sprite)
|
||||
{
|
||||
for (auto iter = std::begin(m_project->objects); iter != std::end(m_project->objects); iter++)
|
||||
{
|
||||
if (iter->spriteName != sprite.name)
|
||||
continue;
|
||||
|
||||
auto oldSpriteName = std::move(iter->spriteName);
|
||||
iter->spriteName.clear();
|
||||
|
||||
const auto index = this->index(std::distance(std::begin(m_project->objects), iter), 0, rootFor<Object>());
|
||||
emit dataChanged(index, index, {Qt::DecorationRole});
|
||||
|
||||
emit objectSpriteNameChanged(*iter, std::move(oldSpriteName));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> void ProjectTreeModel::onBeforeRename(const T &entry, const QString &newName)
|
||||
{
|
||||
Q_UNUSED(entry)
|
||||
Q_UNUSED(newName)
|
||||
}
|
||||
|
||||
template<typename T> void ProjectTreeModel::onAfterRename(const T &entry, const QString &oldName)
|
||||
{
|
||||
Q_UNUSED(entry)
|
||||
Q_UNUSED(oldName)
|
||||
}
|
||||
|
||||
template<> void ProjectTreeModel::onAfterRename<Sprite>(const Sprite &sprite, const QString &oldName)
|
||||
{
|
||||
for (auto iter = std::begin(m_project->objects); iter != std::end(m_project->objects); iter++)
|
||||
{
|
||||
if (iter->spriteName != oldName)
|
||||
continue;
|
||||
|
||||
auto oldSpriteName = std::move(iter->spriteName);
|
||||
|
||||
iter->spriteName = sprite.name;
|
||||
|
||||
// const auto index = this->index(std::distance(std::begin(m_project->objects), iter), 0, rootFor<Object>());
|
||||
// emit dataChanged(index, index, {Qt::DecorationRole});
|
||||
|
||||
emit objectSpriteNameChanged(*iter, std::move(oldSpriteName));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
QString ProjectTreeModel::getFreeNameFor(const std::list<T> &container)
|
||||
{
|
||||
QString name;
|
||||
for (int i = 0; ; i++)
|
||||
{
|
||||
name = nameTempateFor<T>().arg(i);
|
||||
if (std::none_of(std::cbegin(container), std::cend(container),
|
||||
[&name](const T &entry){ return entry.name == name; }))
|
||||
break;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
template<> void ProjectTreeModel::emitCreated<Sprite>(const Sprite &entry) { emit spriteCreated(entry); }
|
||||
template<> void ProjectTreeModel::emitCreated<Sound>(const Sound &entry) { emit soundCreated(entry); }
|
||||
template<> void ProjectTreeModel::emitCreated<Background>(const Background &entry) { emit backgroundCreated(entry); }
|
||||
template<> void ProjectTreeModel::emitCreated<Path>(const Path &entry) { emit pathCreated(entry); }
|
||||
template<> void ProjectTreeModel::emitCreated<Script>(const Script &entry) { emit scriptCreated(entry); }
|
||||
template<> void ProjectTreeModel::emitCreated<Font>(const Font &entry) { emit fontCreated(entry); }
|
||||
template<> void ProjectTreeModel::emitCreated<TimeLine>(const TimeLine &entry) { emit timeLineCreated(entry); }
|
||||
template<> void ProjectTreeModel::emitCreated<Object>(const Object &entry) { emit objectCreated(entry); }
|
||||
template<> void ProjectTreeModel::emitCreated<Room>(const Room &entry) { emit roomCreated(entry); }
|
||||
template<> void ProjectTreeModel::emitAboutToBeRemoved<Sprite>(const Sprite &entry) { emit spriteAboutToBeRemoved(entry); }
|
||||
template<> void ProjectTreeModel::emitAboutToBeRemoved<Sound>(const Sound &entry) { emit soundAboutToBeRemoved(entry); }
|
||||
template<> void ProjectTreeModel::emitAboutToBeRemoved<Background>(const Background &entry) { emit backgroundAboutToBeRemoved(entry); }
|
||||
template<> void ProjectTreeModel::emitAboutToBeRemoved<Path>(const Path &entry) { emit pathAboutToBeRemoved(entry); }
|
||||
template<> void ProjectTreeModel::emitAboutToBeRemoved<Script>(const Script &entry) { emit scriptAboutToBeRemoved(entry); }
|
||||
template<> void ProjectTreeModel::emitAboutToBeRemoved<Font>(const Font &entry) { emit fontAboutToBeRemoved(entry); }
|
||||
template<> void ProjectTreeModel::emitAboutToBeRemoved<TimeLine>(const TimeLine &entry) { emit timeLineAboutToBeRemoved(entry); }
|
||||
template<> void ProjectTreeModel::emitAboutToBeRemoved<Object>(const Object &entry) { emit objectAboutToBeRemoved(entry); }
|
||||
template<> void ProjectTreeModel::emitAboutToBeRemoved<Room>(const Room &entry) { emit roomAboutToBeRemoved(entry); }
|
||||
template<> void ProjectTreeModel::emitNameChanged<Sprite>(const Sprite &entry, const QString &oldName) { emit spriteNameChanged(entry, oldName); }
|
||||
template<> void ProjectTreeModel::emitNameChanged<Sound>(const Sound &entry, const QString &oldName) { emit soundNameChanged(entry, oldName); }
|
||||
template<> void ProjectTreeModel::emitNameChanged<Background>(const Background &entry, const QString &oldName) { emit backgroundNameChanged(entry, oldName); }
|
||||
template<> void ProjectTreeModel::emitNameChanged<Path>(const Path &entry, const QString &oldName) { emit pathNameChanged(entry, oldName); }
|
||||
template<> void ProjectTreeModel::emitNameChanged<Script>(const Script &entry, const QString &oldName) { emit scriptNameChanged(entry, oldName); }
|
||||
template<> void ProjectTreeModel::emitNameChanged<Font>(const Font &entry, const QString &oldName) { emit fontNameChanged(entry, oldName); }
|
||||
template<> void ProjectTreeModel::emitNameChanged<TimeLine>(const TimeLine &entry, const QString &oldName) { emit timeLineNameChanged(entry, oldName); }
|
||||
template<> void ProjectTreeModel::emitNameChanged<Object>(const Object &entry, const QString &oldName) { emit objectNameChanged(entry, oldName); }
|
||||
template<> void ProjectTreeModel::emitNameChanged<Room>(const Room &entry, const QString &oldName) { emit roomNameChanged(entry, oldName); }
|
||||
template<> QString ProjectTreeModel::nameTempateFor<Sprite>() { return QStringLiteral("sprite%0"); }
|
||||
template<> QString ProjectTreeModel::nameTempateFor<Sound>() { return QStringLiteral("sound%0"); }
|
||||
template<> QString ProjectTreeModel::nameTempateFor<Background>() { return QStringLiteral("background%0"); }
|
||||
template<> QString ProjectTreeModel::nameTempateFor<Path>() { return QStringLiteral("path%0"); }
|
||||
template<> QString ProjectTreeModel::nameTempateFor<Script>() { return QStringLiteral("script%0"); }
|
||||
template<> QString ProjectTreeModel::nameTempateFor<Font>() { return QStringLiteral("font%0"); }
|
||||
template<> QString ProjectTreeModel::nameTempateFor<TimeLine>() { return QStringLiteral("timeline%0"); }
|
||||
template<> QString ProjectTreeModel::nameTempateFor<Object>() { return QStringLiteral("object%0"); }
|
||||
template<> QString ProjectTreeModel::nameTempateFor<Room>() { return QStringLiteral("room%0"); }
|
||||
@@ -0,0 +1,152 @@
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include <optional>
|
||||
|
||||
struct ProjectContainer;
|
||||
struct Sprite;
|
||||
struct Sound;
|
||||
struct Background;
|
||||
struct Path;
|
||||
struct Script;
|
||||
struct Font;
|
||||
struct TimeLine;
|
||||
struct Object;
|
||||
struct Room;
|
||||
|
||||
class ProjectTreeModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class NodeType {
|
||||
Root = 12,
|
||||
Sprite,
|
||||
Sound,
|
||||
Background,
|
||||
Path,
|
||||
Script,
|
||||
Font,
|
||||
TimeLine,
|
||||
Object,
|
||||
Room,
|
||||
};
|
||||
|
||||
explicit ProjectTreeModel(QObject *parent = nullptr);
|
||||
explicit ProjectTreeModel(ProjectContainer &project, QObject *parent = nullptr);
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
|
||||
QModelIndex parent(const QModelIndex &child) const override;
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
bool insertRows(int row, int count, const QModelIndex &parent) override;
|
||||
bool removeRows(int row, int count, const QModelIndex &parent) override;
|
||||
|
||||
ProjectContainer *project() { return m_project; }
|
||||
const ProjectContainer *project() const { return m_project; }
|
||||
void setProject(ProjectContainer *project);
|
||||
|
||||
NodeType nodeType(const QModelIndex &index) const;
|
||||
|
||||
template<typename T> QModelIndex rootFor() const;
|
||||
|
||||
QModelIndex gameInformationRoot() const;
|
||||
QModelIndex globalGameSettingsRoot() const;
|
||||
QModelIndex extensionPackagesRoot() const;
|
||||
|
||||
template<typename T> T *get(const QModelIndex &index);
|
||||
template<typename T> const T *get(const QModelIndex &index) const;
|
||||
|
||||
template<typename T> T *create();
|
||||
|
||||
template<typename T> bool remove(const T &entry);
|
||||
|
||||
template<typename T> bool rename(const T &entry, const QString &newName);
|
||||
|
||||
template<typename T> static constexpr ProjectTreeModel::NodeType nodeTypeFor() = delete;
|
||||
|
||||
bool setSpritePixmaps(const Sprite &sprite, std::vector<QPixmap> &&pixmaps);
|
||||
|
||||
bool setBackgroundPixmap(const Background &background, QPixmap &&pixmap);
|
||||
|
||||
signals:
|
||||
void errorOccured(const QString &message);
|
||||
|
||||
void spriteCreated(const Sprite &sprite);
|
||||
void soundCreated(const Sound &sound);
|
||||
void backgroundCreated(const Background &background);
|
||||
void pathCreated(const Path &path);
|
||||
void scriptCreated(const Script &script);
|
||||
void fontCreated(const Font &font);
|
||||
void timeLineCreated(const TimeLine &font);
|
||||
void objectCreated(const Object &font);
|
||||
void roomCreated(const Room &font);
|
||||
|
||||
void spriteAboutToBeRemoved(const Sprite &sprite);
|
||||
void soundAboutToBeRemoved(const Sound &sound);
|
||||
void backgroundAboutToBeRemoved(const Background &background);
|
||||
void pathAboutToBeRemoved(const Path &path);
|
||||
void scriptAboutToBeRemoved(const Script &script);
|
||||
void fontAboutToBeRemoved(const Font &font);
|
||||
void timeLineAboutToBeRemoved(const TimeLine &font);
|
||||
void objectAboutToBeRemoved(const Object &font);
|
||||
void roomAboutToBeRemoved(const Room &font);
|
||||
|
||||
void spriteNameChanged(const Sprite &sprite, const QString &oldName);
|
||||
void soundNameChanged(const Sound &sound, const QString &oldName);
|
||||
void backgroundNameChanged(const Background &background, const QString &oldName);
|
||||
void pathNameChanged(const Path &path, const QString &oldName);
|
||||
void scriptNameChanged(const Script &script, const QString &oldName);
|
||||
void fontNameChanged(const Font &font, const QString &oldName);
|
||||
void timeLineNameChanged(const TimeLine &font, const QString &oldName);
|
||||
void objectNameChanged(const Object &font, const QString &oldName);
|
||||
void roomNameChanged(const Room &font, const QString &oldName);
|
||||
|
||||
void spritePixmapsChanged(const Sprite &sprite);
|
||||
|
||||
void backgroundPixmapChanged(const Background &background);
|
||||
|
||||
void objectSpriteNameChanged(const Object &object, const QString &oldSpriteName);
|
||||
|
||||
private:
|
||||
template<typename T> QVariant dataFor(const QModelIndex &index, int role) const;
|
||||
template<typename T> QVariant iconFor(const T &entry) const;
|
||||
template<typename T> bool setDataFor(const QModelIndex &index, const QVariant &value, int role);
|
||||
template<typename T> std::optional<bool> insertRowsFor(int row, int count, const QModelIndex &parent);
|
||||
template<typename T> std::optional<bool> removeRowsFor(int row, int count, const QModelIndex &parent);
|
||||
template<typename T> static QString getFreeNameFor(const std::list<T> &container);
|
||||
|
||||
template<typename T> void emitCreated(const T &entry);
|
||||
template<typename T> void onBeforeRemove(const T &entry);
|
||||
template<typename T> void emitAboutToBeRemoved(const T &entry);
|
||||
template<typename T> void onBeforeRename(const T &entry, const QString &newName);
|
||||
template<typename T> void onAfterRename(const T &entry, const QString &oldName);
|
||||
template<typename T> void emitNameChanged(const T &entry, const QString &oldName);
|
||||
template<typename T> static QString nameTempateFor();
|
||||
|
||||
ProjectContainer *m_project{};
|
||||
};
|
||||
|
||||
template<> constexpr ProjectTreeModel::NodeType ProjectTreeModel::nodeTypeFor<Sprite>() { return ProjectTreeModel::NodeType::Sprite; }
|
||||
template<> constexpr ProjectTreeModel::NodeType ProjectTreeModel::nodeTypeFor<Sound>() { return ProjectTreeModel::NodeType::Sound; }
|
||||
template<> constexpr ProjectTreeModel::NodeType ProjectTreeModel::nodeTypeFor<Background>() { return ProjectTreeModel::NodeType::Background; }
|
||||
template<> constexpr ProjectTreeModel::NodeType ProjectTreeModel::nodeTypeFor<Path>() { return ProjectTreeModel::NodeType::Path; }
|
||||
template<> constexpr ProjectTreeModel::NodeType ProjectTreeModel::nodeTypeFor<Script>() { return ProjectTreeModel::NodeType::Script; }
|
||||
template<> constexpr ProjectTreeModel::NodeType ProjectTreeModel::nodeTypeFor<Font>() { return ProjectTreeModel::NodeType::Font; }
|
||||
template<> constexpr ProjectTreeModel::NodeType ProjectTreeModel::nodeTypeFor<TimeLine>() { return ProjectTreeModel::NodeType::TimeLine; }
|
||||
template<> constexpr ProjectTreeModel::NodeType ProjectTreeModel::nodeTypeFor<Object>() { return ProjectTreeModel::NodeType::Object; }
|
||||
template<> constexpr ProjectTreeModel::NodeType ProjectTreeModel::nodeTypeFor<Room>() { return ProjectTreeModel::NodeType::Room; }
|
||||
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Sprite>() const;
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Sound>() const;
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Background>() const;
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Path>() const;
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Script>() const;
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Font>() const;
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<TimeLine>() const;
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Object>() const;
|
||||
template<> QModelIndex ProjectTreeModel::rootFor<Room>() const;
|
||||
@@ -0,0 +1,54 @@
|
||||
#include "spritesmodel.h"
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QDebug>
|
||||
|
||||
SpritesModel::SpritesModel(const std::vector<QPixmap> &pixmaps, QObject *parent) :
|
||||
QAbstractListModel{parent},
|
||||
m_pixmaps{pixmaps}
|
||||
{
|
||||
}
|
||||
|
||||
int SpritesModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
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:
|
||||
if (index.row() < 0 || std::size_t(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 || std::size_t(index.row()) >= m_pixmaps.size())
|
||||
qFatal("index out of range");
|
||||
|
||||
return m_pixmaps.at(index.row());
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QPixmap>
|
||||
|
||||
#include <vector>
|
||||
|
||||
class SpritesModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
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;
|
||||
};
|
||||
@@ -0,0 +1,232 @@
|
||||
#include "timelinemomentsmodel.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
TimelineMomentsModel::TimelineMomentsModel(TimeLine::moments_container_t &moments, QObject *parent) :
|
||||
QAbstractListModel{parent},
|
||||
m_moments{moments}
|
||||
{
|
||||
}
|
||||
|
||||
int TimelineMomentsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_moments.size();
|
||||
}
|
||||
|
||||
QVariant TimelineMomentsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
|
||||
if (index.row() < 0 || std::size_t(index.row()) >= m_moments.size())
|
||||
{
|
||||
qWarning() << "row out of bounds" << index.row();
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto &pair = *std::next(std::cbegin(m_moments), index.row());
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole:
|
||||
return tr("Step %0").arg(pair.first);
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool TimelineMomentsModel::removeRows(int row, int count, const QModelIndex &parent)
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
|
||||
if (row < 0 || std::size_t(row) >= m_moments.size())
|
||||
{
|
||||
qWarning() << "unexpected row" << row;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count < 0 || std::size_t(count) > m_moments.size() - row)
|
||||
{
|
||||
qWarning() << "unexpected row+count" << count << row;
|
||||
return false;
|
||||
}
|
||||
|
||||
beginRemoveRows({}, row, row + count - 1);
|
||||
auto begin = std::next(std::begin(m_moments), row);
|
||||
auto end = std::next(begin, count);
|
||||
m_moments.erase(begin, end);
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TimelineMomentsModel::addMoment(TimeLine::moment_key_t moment)
|
||||
{
|
||||
if (m_moments.contains(moment))
|
||||
{
|
||||
qWarning() << moment << "duplicate";
|
||||
return false;
|
||||
}
|
||||
|
||||
// temporary copy to find row before inserting, as its needed for beginInsertRows()
|
||||
auto tempMoments = m_moments;
|
||||
|
||||
const auto &tempInsertResult = tempMoments.insert(std::make_pair(moment, ActionsContainer{}));
|
||||
if (!tempInsertResult.second)
|
||||
{
|
||||
qWarning() << "temp inserting failed!";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto tempNewRow = std::distance(std::begin(tempMoments), tempInsertResult.first);
|
||||
|
||||
|
||||
beginInsertRows({}, tempNewRow, tempNewRow);
|
||||
|
||||
const auto &insertResult = m_moments.insert(std::make_pair(moment, ActionsContainer{}));
|
||||
if (!insertResult.second)
|
||||
{
|
||||
qWarning() << "inserting failed!";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto newRow = std::distance(std::begin(m_moments), insertResult.first);
|
||||
Q_ASSERT(tempNewRow == newRow);
|
||||
|
||||
endInsertRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TimelineMomentsModel::changeMoment(TimeLine::moment_key_t moment, TimeLine::moment_key_t newMoment)
|
||||
{
|
||||
const auto iter = m_moments.find(moment);
|
||||
if (iter == std::cend(m_moments))
|
||||
{
|
||||
qWarning() << moment << "not found";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (moment == newMoment)
|
||||
{
|
||||
qWarning() << "same moment again";
|
||||
return true;
|
||||
}
|
||||
|
||||
auto container = std::move(iter->second);
|
||||
|
||||
const auto oldRow = std::distance(std::begin(m_moments), iter);
|
||||
|
||||
beginRemoveRows({}, oldRow, oldRow);
|
||||
m_moments.erase(iter);
|
||||
endRemoveRows();
|
||||
|
||||
// temporary copy to find row before inserting, as its needed for beginInsertRows()
|
||||
auto tempMoments = m_moments;
|
||||
|
||||
const auto &tempInsertResult = tempMoments.insert(std::make_pair(newMoment, ActionsContainer{}));
|
||||
if (!tempInsertResult.second)
|
||||
{
|
||||
qWarning() << "temp inserting failed!";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto tempNewRow = std::distance(std::begin(tempMoments), tempInsertResult.first);
|
||||
|
||||
|
||||
beginInsertRows({}, tempNewRow, tempNewRow);
|
||||
|
||||
const auto &insertResult = m_moments.insert(std::make_pair(newMoment, std::move(container)));
|
||||
if (!insertResult.second)
|
||||
{
|
||||
qWarning() << "inserting failed!";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto newRow = std::distance(std::begin(m_moments), insertResult.first);
|
||||
Q_ASSERT(tempNewRow == newRow);
|
||||
|
||||
endInsertRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TimelineMomentsModel::removeMoment(TimeLine::moment_key_t moment)
|
||||
{
|
||||
const auto iter = m_moments.find(moment);
|
||||
if (iter == std::cend(m_moments))
|
||||
{
|
||||
qWarning() << moment << "not found";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto row = std::distance(std::begin(m_moments), iter);
|
||||
|
||||
beginRemoveRows({}, row, row);
|
||||
m_moments.erase(iter);
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TimelineMomentsModel::clearMoments()
|
||||
{
|
||||
if (m_moments.empty())
|
||||
{
|
||||
qWarning() << "moments already empty";
|
||||
return true;
|
||||
}
|
||||
|
||||
beginRemoveRows({}, 0, m_moments.size() - 1);
|
||||
m_moments.clear();
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::pair<const TimeLine::moment_key_t, ActionsContainer> *TimelineMomentsModel::getMoment(const QModelIndex &index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
{
|
||||
qWarning() << "unexpected invalid index";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return getMoment(index.row());
|
||||
}
|
||||
|
||||
const std::pair<const TimeLine::moment_key_t, ActionsContainer> *TimelineMomentsModel::getMoment(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
{
|
||||
qWarning() << "unexpected invalid index";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return getMoment(index.row());
|
||||
}
|
||||
|
||||
std::pair<const TimeLine::moment_key_t, ActionsContainer> *TimelineMomentsModel::getMoment(int row)
|
||||
{
|
||||
if (row < 0 || std::size_t(row) >= m_moments.size())
|
||||
{
|
||||
qWarning() << "unexpected row" << row;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &*std::next(std::begin(m_moments), row);
|
||||
}
|
||||
|
||||
const std::pair<const TimeLine::moment_key_t, ActionsContainer> *TimelineMomentsModel::getMoment(int row) const
|
||||
{
|
||||
if (row < 0 || std::size_t(row) >= m_moments.size())
|
||||
{
|
||||
qWarning() << "unexpected row" << row;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &*std::next(std::cbegin(m_moments), row);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
#include "projectcontainer.h"
|
||||
|
||||
class TimelineMomentsModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TimelineMomentsModel(TimeLine::moments_container_t &moments, QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex{}) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex{}) override;
|
||||
|
||||
bool addMoment(TimeLine::moment_key_t moment);
|
||||
bool changeMoment(TimeLine::moment_key_t moment, TimeLine::moment_key_t newMoment);
|
||||
bool removeMoment(TimeLine::moment_key_t moment);
|
||||
bool clearMoments();
|
||||
|
||||
std::pair<const TimeLine::moment_key_t, ActionsContainer> *getMoment(const QModelIndex &index);
|
||||
const std::pair<const TimeLine::moment_key_t, ActionsContainer> *getMoment(const QModelIndex &index) const;
|
||||
std::pair<const TimeLine::moment_key_t, ActionsContainer> *getMoment(int row);
|
||||
const std::pair<const TimeLine::moment_key_t, ActionsContainer> *getMoment(int row) const;
|
||||
|
||||
private:
|
||||
TimeLine::moments_container_t &m_moments;
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "triggersmodel.h"
|
||||
|
||||
#include "projectcontainer.h"
|
||||
|
||||
TriggersModel::TriggersModel(ProjectContainer &project, QObject *parent) :
|
||||
QAbstractListModel{parent},
|
||||
m_project{project}
|
||||
{
|
||||
}
|
||||
|
||||
int TriggersModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
QVariant TriggersModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
Q_UNUSED(role)
|
||||
return {};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user