mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
story run icon, save/load resources
This commit is contained in:
parent
5ac03b8e8d
commit
ca36d4ac32
14 changed files with 290 additions and 68 deletions
|
|
@ -1,5 +1,7 @@
|
||||||
## Arduino MKR Zero (SAMD21G18A)
|
## Arduino MKR Zero (SAMD21G18A)
|
||||||
|
|
||||||
|
Current status: ON DEVELOPMENT
|
||||||
|
|
||||||
| Category | Maker | Name | Rounded Price |
|
| Category | Maker | Name | Rounded Price |
|
||||||
| ------------------ | ------------------------------ | --------------------- | ------------- |
|
| ------------------ | ------------------------------ | --------------------- | ------------- |
|
||||||
| Main CPU board | Arduino | MKR Zero | 30€ |
|
| Main CPU board | Arduino | MKR Zero | 30€ |
|
||||||
|
|
|
||||||
BIN
story-editor/assets/play-circle-green.png
Normal file
BIN
story-editor/assets/play-circle-green.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
41
story-editor/assets/play-circle-green.svg
Normal file
41
story-editor/assets/play-circle-green.svg
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="play-circle-green.svg"
|
||||||
|
inkscape:export-filename="play-circle-green.png"
|
||||||
|
inkscape:export-xdpi="599.172"
|
||||||
|
inkscape:export-ydpi="599.172"
|
||||||
|
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="38.514415"
|
||||||
|
inkscape:cx="8.0619166"
|
||||||
|
inkscape:cy="14.708779"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1136"
|
||||||
|
inkscape:window-x="3840"
|
||||||
|
inkscape:window-y="40"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:deskcolor="#d1d1d1" />
|
||||||
|
<path
|
||||||
|
d="M10,16.5V7.5L16,12M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z"
|
||||||
|
id="path2"
|
||||||
|
style="fill:#4e9a06" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -135,10 +135,13 @@ MainWindow::MainWindow()
|
||||||
{
|
{
|
||||||
// Take first
|
// Take first
|
||||||
QModelIndex index = selection.at(0);
|
QModelIndex index = selection.at(0);
|
||||||
QString fn = m_resourcesDock->getModel().GetFileName(index.row());
|
Resource res;
|
||||||
QJsonObject obj;
|
if (m_project.GetResourceAt(index.row(), res))
|
||||||
obj["image"] = fn;
|
{
|
||||||
m_model.setNodeData(id, NodeRole::InternalData, obj.toVariantMap());
|
QJsonObject obj;
|
||||||
|
obj["image"] = res.file.c_str();
|
||||||
|
m_model.setNodeData(id, NodeRole::InternalData, obj.toVariantMap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -268,7 +271,7 @@ void MainWindow::DisplayNode(StoryNode *m_tree, QtNodes::NodeId parentId)
|
||||||
|
|
||||||
if (m_tree->image >= 0)
|
if (m_tree->image >= 0)
|
||||||
{
|
{
|
||||||
std::string imageFile = m_project.GetWorkingDir() + "/rf/" + m_project.m_images[m_tree->image].file + ".bmp";
|
std::string imageFile = ""; // FIXME m_project.GetWorkingDir() + "/rf/" + m_project.m_images[m_tree->image].file + ".bmp";
|
||||||
std::cout << "Node image: " << imageFile << std::endl;
|
std::cout << "Node image: " << imageFile << std::endl;
|
||||||
nodeInternalData["image"] = imageFile.c_str();
|
nodeInternalData["image"] = imageFile.c_str();
|
||||||
}
|
}
|
||||||
|
|
@ -575,6 +578,20 @@ void MainWindow::OpenProject(const QString &filePath)
|
||||||
m_project.SetName(projectData["name"].toString().toStdString());
|
m_project.SetName(projectData["name"].toString().toStdString());
|
||||||
m_project.SetUuid(projectData["uuid"].toString().toStdString());
|
m_project.SetUuid(projectData["uuid"].toString().toStdString());
|
||||||
|
|
||||||
|
QJsonArray resourcesData = projectData["resources"].toArray();
|
||||||
|
|
||||||
|
for (const auto &r : resourcesData)
|
||||||
|
{
|
||||||
|
Resource rData;
|
||||||
|
QJsonObject obj = r.toObject();
|
||||||
|
rData.type = obj["type"].toString().toStdString();
|
||||||
|
rData.format = obj["format"].toString().toStdString();
|
||||||
|
rData.description = obj["description"].toString().toStdString();
|
||||||
|
rData.file = obj["file"].toString().toStdString();
|
||||||
|
m_resourcesDock->Append(rData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (projectRoot.contains("nodegraph"))
|
if (projectRoot.contains("nodegraph"))
|
||||||
{
|
{
|
||||||
QJsonObject nodeData = projectRoot["nodegraph"].toObject();
|
QJsonObject nodeData = projectRoot["nodegraph"].toObject();
|
||||||
|
|
@ -622,6 +639,21 @@ void MainWindow::SaveProject()
|
||||||
projectData["name"] = m_project.GetName().c_str();
|
projectData["name"] = m_project.GetName().c_str();
|
||||||
projectData["uuid"] = m_project.GetUuid().c_str();
|
projectData["uuid"] = m_project.GetUuid().c_str();
|
||||||
|
|
||||||
|
QJsonArray resourcesData;
|
||||||
|
|
||||||
|
for (std::vector<Resource>::const_iterator it = m_project.Begin(); it != m_project.End(); ++it)
|
||||||
|
{
|
||||||
|
auto &r = *it;
|
||||||
|
QJsonObject obj;
|
||||||
|
obj["type"] = r.type.c_str();
|
||||||
|
obj["format"] = r.format.c_str();
|
||||||
|
obj["description"] = r.description.c_str();
|
||||||
|
obj["file"] = r.file.c_str();
|
||||||
|
|
||||||
|
resourcesData.append(obj);
|
||||||
|
}
|
||||||
|
projectData["resources"] = resourcesData;
|
||||||
|
|
||||||
QJsonObject saveData;
|
QJsonObject saveData;
|
||||||
saveData["project"] = projectData;
|
saveData["project"] = projectData;
|
||||||
saveData["nodegraph"] = jsonModel;
|
saveData["nodegraph"] = jsonModel;
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ MediaNodeModel::MediaNodeModel(StoryGraphModel &model)
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_ui.selectImageButton, &QPushButton::clicked, [&](bool enable) {
|
connect(m_ui.selectImageButton, &QPushButton::clicked, [&](bool enable) {
|
||||||
//m_contextMenu->exec(m_widget->mapFromGlobal(QCursor::pos()));
|
|
||||||
emit m_model.sigChooseFile(getNodeId());
|
emit m_model.sigChooseFile(getNodeId());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,6 @@
|
||||||
<file>../assets/close-outline.svg</file>
|
<file>../assets/close-outline.svg</file>
|
||||||
<file>../assets/folder-open-outline.svg</file>
|
<file>../assets/folder-open-outline.svg</file>
|
||||||
<file>../assets/welcome.png</file>
|
<file>../assets/welcome.png</file>
|
||||||
|
<file>../assets/play-circle-green.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,37 @@
|
||||||
#include "resource_model.h"
|
#include "resource_model.h"
|
||||||
|
|
||||||
|
|
||||||
|
ResourceModel::ResourceModel(StoryProject &project, QObject *parent)
|
||||||
|
: QAbstractTableModel{parent}
|
||||||
|
, m_project(project)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int ResourceModel::rowCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return m_project.ResourcesSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ResourceModel::columnCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
QVariant ResourceModel::data(const QModelIndex &index, int role) const {
|
QVariant ResourceModel::data(const QModelIndex &index, int role) const {
|
||||||
if (role != Qt::DisplayRole && role != Qt::EditRole) return {};
|
if (role != Qt::DisplayRole && role != Qt::EditRole) return {};
|
||||||
const auto & res = m_data[index.row()];
|
Resource res;
|
||||||
switch (index.column()) {
|
if (m_project.GetResourceAt(index.row(), res))
|
||||||
case 0: return res.file.c_str();
|
{
|
||||||
case 1: return res.format.c_str();
|
switch (index.column()) {
|
||||||
case 2: return res.description.c_str();
|
case 0: return res.file.c_str();
|
||||||
default: return {};
|
case 1: return res.format.c_str();
|
||||||
};
|
case 2: return res.description.c_str();
|
||||||
|
case 3: return res.type.c_str();
|
||||||
|
default: ;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant ResourceModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
QVariant ResourceModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
||||||
|
|
@ -18,30 +40,76 @@ QVariant ResourceModel::headerData(int section, Qt::Orientation orientation, int
|
||||||
case 0: return "File";
|
case 0: return "File";
|
||||||
case 1: return "Format";
|
case 1: return "Format";
|
||||||
case 2: return "Description";
|
case 2: return "Description";
|
||||||
|
case 3: return "Type";
|
||||||
default: return {};
|
default: return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceModel::append(const Resource &res) {
|
void ResourceModel::append(const Resource &res) {
|
||||||
beginInsertRows({}, m_data.count(), m_data.count());
|
beginInsertRows({}, m_project.ResourcesSize(), m_project.ResourcesSize());
|
||||||
m_data.append(res);
|
m_project.AppendResource(res);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceModel::Clear()
|
void ResourceModel::Clear()
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_data.clear();
|
m_project.ClearResources();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ResourceModel::GetFileName(int row) {
|
|
||||||
QString n;
|
|
||||||
|
|
||||||
if (row < m_data.size())
|
// ------------------------------- PROXY MODEL -------------------------------
|
||||||
{
|
|
||||||
n = m_data.at(row).file.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
|
ResourceFilterProxyModel::ResourceFilterProxyModel(QObject *parent)
|
||||||
|
: QSortFilterProxyModel(parent)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourceFilterProxyModel::setFilterType(const QString & type)
|
||||||
|
{
|
||||||
|
m_typeFilter = type;
|
||||||
|
invalidateFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ResourceFilterProxyModel::filterAcceptsRow(int sourceRow,
|
||||||
|
const QModelIndex &sourceParent) const
|
||||||
|
{
|
||||||
|
QModelIndex indexType = sourceModel()->index(sourceRow, 3, sourceParent);
|
||||||
|
|
||||||
|
return (sourceModel()->data(indexType).toString() == m_typeFilter);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
bool ResourceFilterProxyModel::lessThan(const QModelIndex &left,
|
||||||
|
const QModelIndex &right) const
|
||||||
|
{
|
||||||
|
QVariant leftData = sourceModel()->data(left);
|
||||||
|
QVariant rightData = sourceModel()->data(right);
|
||||||
|
|
||||||
|
if (leftData.userType() == QMetaType::QDateTime) {
|
||||||
|
return leftData.toDateTime() < rightData.toDateTime();
|
||||||
|
} else {
|
||||||
|
static const QRegularExpression emailPattern("[\\w\\.]*@[\\w\\.]*");
|
||||||
|
|
||||||
|
QString leftString = leftData.toString();
|
||||||
|
if (left.column() == 1) {
|
||||||
|
const QRegularExpressionMatch match = emailPattern.match(leftString);
|
||||||
|
if (match.hasMatch())
|
||||||
|
leftString = match.captured(0);
|
||||||
|
}
|
||||||
|
QString rightString = rightData.toString();
|
||||||
|
if (right.column() == 1) {
|
||||||
|
const QRegularExpressionMatch match = emailPattern.match(rightString);
|
||||||
|
if (match.hasMatch())
|
||||||
|
rightString = match.captured(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString::localeAwareCompare(leftString, rightString) < 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,22 +10,36 @@ class ResourceModel : public QAbstractTableModel
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ResourceModel(QObject * parent = {}) : QAbstractTableModel{parent} {}
|
ResourceModel(StoryProject &project, QObject * parent = {});
|
||||||
|
|
||||||
int rowCount(const QModelIndex &) const override { return m_data.count(); }
|
int rowCount(const QModelIndex &) const override;
|
||||||
int columnCount(const QModelIndex &) const override { return 3; }
|
int columnCount(const QModelIndex &) const override;
|
||||||
QVariant data(const QModelIndex &index, int role) const override;
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||||
void append(const Resource & res);
|
void append(const Resource & res);
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
QString GetFileName(int row);
|
private:
|
||||||
|
StoryProject &m_project;
|
||||||
|
};
|
||||||
|
|
||||||
QList<Resource> GetData() const { return m_data; }
|
class ResourceFilterProxyModel : public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ResourceFilterProxyModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
|
||||||
|
void setFilterType(const QString &type);
|
||||||
|
protected:
|
||||||
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||||
|
// bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<Resource> m_data;
|
|
||||||
|
QString m_typeFilter;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RESOURCE_MODEL_H
|
#endif // RESOURCE_MODEL_H
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
ResourcesDock::ResourcesDock(StoryProject &project)
|
ResourcesDock::ResourcesDock(StoryProject &project)
|
||||||
: m_project(project)
|
: m_project(project)
|
||||||
|
, m_resourcesModel(project)
|
||||||
, DockWidgetBase(tr("Resources"), true)
|
, DockWidgetBase(tr("Resources"), true)
|
||||||
{
|
{
|
||||||
setObjectName("ResourcesDock"); // used to save the state
|
setObjectName("ResourcesDock"); // used to save the state
|
||||||
|
|
@ -11,37 +12,46 @@ ResourcesDock::ResourcesDock(StoryProject &project)
|
||||||
m_uiOstResources.setupUi(this);
|
m_uiOstResources.setupUi(this);
|
||||||
m_uiOstResources.resourcesView->setModel(&m_resourcesModel);
|
m_uiOstResources.resourcesView->setModel(&m_resourcesModel);
|
||||||
|
|
||||||
|
m_proxyModel.setSourceModel(&m_resourcesModel);
|
||||||
|
|
||||||
connect(m_uiOstResources.addImageButton, &QPushButton::clicked, [=](bool checked) {
|
connect(m_uiOstResources.addImageButton, &QPushButton::clicked, [=](bool checked) {
|
||||||
|
|
||||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
|
||||||
".",
|
".",
|
||||||
tr("Images (*.bmp)"));
|
tr("Images (*.bmp)"));
|
||||||
|
|
||||||
std::filesystem::path p(fileName.toStdString());
|
if (std::filesystem::exists(fileName.toStdString()))
|
||||||
std::filesystem::path p2 = m_project.ImagesPath() / p.filename().generic_string();
|
{
|
||||||
std::filesystem::copy(p, p2);
|
std::filesystem::path p(fileName.toStdString());
|
||||||
|
std::filesystem::path p2 = m_project.ImagesPath() / p.filename().generic_string();
|
||||||
Resource res;
|
std::filesystem::copy(p, p2, std::filesystem::copy_options::overwrite_existing);
|
||||||
res.format = "BMP";
|
|
||||||
res.file = p.filename();
|
|
||||||
m_resourcesModel.append(res);
|
|
||||||
|
|
||||||
|
Resource res;
|
||||||
|
res.format = "BMP";
|
||||||
|
res.type = "image";
|
||||||
|
res.file = p.filename();
|
||||||
|
m_resourcesModel.append(res);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_uiOstResources.addSoundButton, &QPushButton::clicked, [=](bool checked) {
|
connect(m_uiOstResources.addSoundButton, &QPushButton::clicked, [=](bool checked) {
|
||||||
|
|
||||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
|
||||||
".",
|
".",
|
||||||
tr("Sounds (*.wav)"));
|
tr("Sound files (*.wav, *.mp3, *.m4a)"));
|
||||||
|
|
||||||
std::filesystem::path p(fileName.toStdString());
|
if (std::filesystem::exists(fileName.toStdString()))
|
||||||
std::filesystem::path p2 = m_project.SoundsPath() / p.filename().generic_string();
|
{
|
||||||
std::filesystem::copy(p, p2);
|
std::filesystem::path p(fileName.toStdString());
|
||||||
|
std::filesystem::path p2 = m_project.SoundsPath() / p.filename().generic_string();
|
||||||
|
std::filesystem::copy(p, p2, std::filesystem::copy_options::overwrite_existing);
|
||||||
|
|
||||||
Resource res;
|
Resource res;
|
||||||
res.format = "WAV";
|
res.format = "WAV";
|
||||||
res.file = p.filename();
|
res.type = "sound";
|
||||||
m_resourcesModel.append(res);
|
res.file = p.filename();
|
||||||
|
m_resourcesModel.append(res);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,16 +60,21 @@ void ResourcesDock::Initialize()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourcesDock::Append(const Resource &res)
|
||||||
|
{
|
||||||
|
m_resourcesModel.append(res);
|
||||||
|
}
|
||||||
|
|
||||||
void ResourcesDock::SaveToProject()
|
void ResourcesDock::SaveToProject()
|
||||||
{
|
{
|
||||||
m_project.Clear();
|
m_project.Clear();
|
||||||
for (auto & r : m_resourcesModel.GetData())
|
// for (auto & r : m_resourcesModel.GetData())
|
||||||
{
|
// {
|
||||||
m_project.m_images.push_back(r);
|
// m_project.m_images.push_back(r);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourcesDock::slotClear()
|
void ResourcesDock::Clear()
|
||||||
{
|
{
|
||||||
m_resourcesModel.Clear();
|
m_resourcesModel.Clear();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,18 +14,21 @@ public:
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
|
||||||
QList<Resource> GetResources() const { return m_resourcesModel.GetData(); }
|
|
||||||
ResourceModel &getModel() { return m_resourcesModel; }
|
ResourceModel &getModel() { return m_resourcesModel; }
|
||||||
|
ResourceFilterProxyModel &getFilteredModel() { return m_proxyModel; }
|
||||||
|
|
||||||
|
void SetFilterType(const QString &type) { m_proxyModel.setFilterType(type); }
|
||||||
|
|
||||||
|
void Append(const Resource &res);
|
||||||
|
|
||||||
void SaveToProject();
|
void SaveToProject();
|
||||||
|
void Clear();
|
||||||
public slots:
|
|
||||||
void slotClear();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StoryProject &m_project;
|
StoryProject &m_project;
|
||||||
Ui::ostResources m_uiOstResources;
|
Ui::ostResources m_uiOstResources;
|
||||||
ResourceModel m_resourcesModel;
|
ResourceModel m_resourcesModel;
|
||||||
|
ResourceFilterProxyModel m_proxyModel;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RESOURCESDOCK_H
|
#endif // RESOURCESDOCK_H
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,10 @@ void StoryProject::Initialize(const std::string &file_path)
|
||||||
|
|
||||||
bool StoryProject::Load(const std::string &file_path)
|
bool StoryProject::Load(const std::string &file_path)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::ifstream f(file_path);
|
std::ifstream f(file_path);
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
/*
|
||||||
std::filesystem::path p(file_path);
|
std::filesystem::path p(file_path);
|
||||||
m_working_dir= p.parent_path();
|
m_working_dir= p.parent_path();
|
||||||
|
|
||||||
|
|
@ -116,7 +117,7 @@ bool StoryProject::Load(const std::string &file_path)
|
||||||
{
|
{
|
||||||
CreateTree();
|
CreateTree();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,6 +192,27 @@ void StoryProject::ReplaceCharacter(std::string &theString, const std::string &t
|
||||||
while (found != std::string::npos);
|
while (found != std::string::npos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StoryProject::AppendResource(const Resource &res)
|
||||||
|
{
|
||||||
|
m_resources.push_back(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoryProject::GetResourceAt(int index, Resource &resOut)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
if ((index >= 0) && (index < m_resources.size()))
|
||||||
|
{
|
||||||
|
resOut = m_resources[index];
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoryProject::ClearResources()
|
||||||
|
{
|
||||||
|
m_resources.clear();
|
||||||
|
}
|
||||||
|
|
||||||
std::string StoryProject::GetFileExtension(const std::string &fileName)
|
std::string StoryProject::GetFileExtension(const std::string &fileName)
|
||||||
{
|
{
|
||||||
if(fileName.find_last_of(".") != std::string::npos)
|
if(fileName.find_last_of(".") != std::string::npos)
|
||||||
|
|
@ -204,7 +226,7 @@ std::string StoryProject::Compile()
|
||||||
|
|
||||||
chip32 << "\tjump .entry\r\n";
|
chip32 << "\tjump .entry\r\n";
|
||||||
|
|
||||||
for (auto & r : m_images)
|
for (auto & r : m_resources)
|
||||||
{
|
{
|
||||||
std::string fileName = GetFileName(r.file);
|
std::string fileName = GetFileName(r.file);
|
||||||
std::string ext = GetFileExtension(fileName);
|
std::string ext = GetFileExtension(fileName);
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ struct Resource
|
||||||
std::string file;
|
std::string file;
|
||||||
std::string description;
|
std::string description;
|
||||||
std::string format;
|
std::string format;
|
||||||
|
std::string type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StoryProject
|
struct StoryProject
|
||||||
|
|
@ -52,20 +53,14 @@ struct StoryProject
|
||||||
std::string m_type;
|
std::string m_type;
|
||||||
std::string m_code;
|
std::string m_code;
|
||||||
|
|
||||||
std::vector<Resource> m_images;
|
|
||||||
std::vector<Resource> m_sounds;
|
|
||||||
|
|
||||||
StoryNode *m_tree;
|
StoryNode *m_tree;
|
||||||
|
|
||||||
|
|
||||||
bool Load(const std::string &file_path);
|
bool Load(const std::string &file_path);
|
||||||
void CreateTree();
|
void CreateTree();
|
||||||
void Clear() {
|
void Clear() {
|
||||||
m_uuid = "";
|
m_uuid = "";
|
||||||
m_working_dir = "";
|
m_working_dir = "";
|
||||||
m_images.clear();
|
m_resources.clear();
|
||||||
m_sounds.clear();
|
|
||||||
|
|
||||||
m_initialized = false;
|
m_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,6 +83,17 @@ struct StoryProject
|
||||||
static std::string GetFileName(const std::string &path);
|
static std::string GetFileName(const std::string &path);
|
||||||
static void ReplaceCharacter(std::string &theString, const std::string &toFind, const std::string &toReplace);
|
static void ReplaceCharacter(std::string &theString, const std::string &toFind, const std::string &toReplace);
|
||||||
|
|
||||||
|
|
||||||
|
// ------------- Resources Management
|
||||||
|
void AppendResource(const Resource &res);
|
||||||
|
bool GetResourceAt(int index, Resource &resOut);
|
||||||
|
void ClearResources();
|
||||||
|
int ResourcesSize() const { return m_resources.size(); }
|
||||||
|
|
||||||
|
std::vector<Resource>::const_iterator Begin() const { return m_resources.begin(); }
|
||||||
|
std::vector<Resource>::const_iterator End() const { return m_resources.end(); }
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Initialize with an existing project
|
// Initialize with an existing project
|
||||||
void Initialize(const std::string &file_path);
|
void Initialize(const std::string &file_path);
|
||||||
|
|
@ -104,6 +110,7 @@ private:
|
||||||
std::filesystem::path m_soundsPath;
|
std::filesystem::path m_soundsPath;
|
||||||
bool m_initialized{false};
|
bool m_initialized{false};
|
||||||
|
|
||||||
|
std::vector<Resource> m_resources;
|
||||||
std::string m_working_dir; /// Temporary folder based on the uuid, where the archive is unzipped
|
std::string m_working_dir; /// Temporary folder based on the uuid, where the archive is unzipped
|
||||||
std::string m_project_path; /// JSON project file
|
std::string m_project_path; /// JSON project file
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,21 @@ void ToolBar::createActions(QMenuBar *menuBar)
|
||||||
|
|
||||||
menuBar->addSeparator();
|
menuBar->addSeparator();
|
||||||
|
|
||||||
|
// -------------------------------- DEBUG STORY
|
||||||
|
|
||||||
|
QMenu *storyMenu = menuBar->addMenu(tr("&Story"));
|
||||||
|
// ------------ Run
|
||||||
|
{
|
||||||
|
QIcon icon(":/assets/play-circle-green.png");
|
||||||
|
m_runAction = new QAction(icon, tr("&Close project"), this);
|
||||||
|
m_runAction->setStatusTip(tr("Build and run current project"));
|
||||||
|
connect(m_runAction, &QAction::triggered, this, &ToolBar::sigRun);
|
||||||
|
storyMenu->addAction(m_runAction);
|
||||||
|
addSeparator();
|
||||||
|
addAction(m_runAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------- WINDOWS MENU
|
||||||
m_windowsMenu = menuBar->addMenu(tr("&Windows"));
|
m_windowsMenu = menuBar->addMenu(tr("&Windows"));
|
||||||
|
|
||||||
auto act = m_windowsMenu->addAction(tr("Reset docks position"));
|
auto act = m_windowsMenu->addAction(tr("Reset docks position"));
|
||||||
|
|
@ -102,6 +117,7 @@ void ToolBar::SetActionsActive(bool enable)
|
||||||
m_windowsMenu->setEnabled(enable);
|
m_windowsMenu->setEnabled(enable);
|
||||||
m_closeProjectAction->setEnabled(enable);
|
m_closeProjectAction->setEnabled(enable);
|
||||||
m_saveProjectAction->setEnabled(enable);
|
m_saveProjectAction->setEnabled(enable);
|
||||||
|
m_runAction->setEnabled(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,15 +23,17 @@ signals:
|
||||||
void sigExit();
|
void sigExit();
|
||||||
void sigDefaultDocksPosition();
|
void sigDefaultDocksPosition();
|
||||||
void sigOpenRecent(const QString &project);
|
void sigOpenRecent(const QString &project);
|
||||||
|
void sigRun();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotAbout();
|
void slotAbout();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMenu *m_windowsMenu;
|
QMenu *m_windowsMenu{nullptr};
|
||||||
QMenu *m_recentProjectsMenu;
|
QMenu *m_recentProjectsMenu{nullptr};
|
||||||
QAction *m_saveProjectAction;
|
QAction *m_saveProjectAction{nullptr};
|
||||||
QAction *m_closeProjectAction;
|
QAction *m_closeProjectAction{nullptr};
|
||||||
|
QAction *m_runAction{nullptr};
|
||||||
QList<QAction *> m_actionDockList;
|
QList<QAction *> m_actionDockList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue