diff --git a/tycho/CMakeLists.txt b/tycho/CMakeLists.txt index 210bdd6..ee04853 100644 --- a/tycho/CMakeLists.txt +++ b/tycho/CMakeLists.txt @@ -23,17 +23,13 @@ add_library( SHARED $ENV{OUT_DIR}/bindings.cc $ENV{OUT_DIR}/bindings.h - cc_headers/mapmodel.h - cc_headers/mapprops.h - cc_headers/menu.h - cc_headers/project.h - cc_headers/tycho.h - cc_source/cc.cc - cc_source/main.cc - cc_source/mapmodel.cc - cc_source/mapprops.cc - cc_source/menu.cc - cc_source/project.cc + cc/main.cc + cc/mapmodel.cc + cc/mapprops.cc + cc/mapview.cc + cc/menu.cc + cc/project.cc + cc/tycho.h resources/resources.qrc ui/about.ui ui/license.ui @@ -54,7 +50,6 @@ set_target_properties( target_include_directories( maraiah-tycho-hermes PUBLIC - cc_headers $ENV{OUT_DIR} ) diff --git a/tycho/build.rs b/tycho/build.rs index 0071746..8ed3967 100644 --- a/tycho/build.rs +++ b/tycho/build.rs @@ -16,7 +16,7 @@ fn main() let mut config = cmake::Config::new("."); if cfg!(debug_assertions) { - config.cxxflag("-DTYCHO_DEBUG_PRINT"); + config.cxxflag("-DTYCHO_DEBUG_ASSERTIONS"); } let destination = config.build(); diff --git a/tycho/cc_source/main.cc b/tycho/cc/main.cc similarity index 64% rename from tycho/cc_source/main.cc rename to tycho/cc/main.cc index e6d72d5..d5c8f7d 100644 --- a/tycho/cc_source/main.cc +++ b/tycho/cc/main.cc @@ -1,8 +1,11 @@ #include "tycho.h" -#include "menu.h" -#include extern "C" { + void critical_msg(char const *title, char const *msg) + { + QMessageBox::critical(nullptr, QObject::tr(title), QObject::tr(msg)); + } + int main_cc(char *app_path) { dbgPrint("cc entry"); diff --git a/tycho/cc/mapmodel.cc b/tycho/cc/mapmodel.cc new file mode 100644 index 0000000..71c7f66 --- /dev/null +++ b/tycho/cc/mapmodel.cc @@ -0,0 +1,73 @@ +#include "tycho.h" + +MapModel::MapModel(QObject *parent) : + AbstractMapModel(parent), + ProjectModel() +{ + dbgPrintFunc(); +} + +MapModel::~MapModel() +{ + dbgPrintFunc(); +} + +ProjectModel::Type MapModel::type() const +{ + return ProjectModel::Map; +} + +QAbstractItemModel const *MapModel::getAbstract() const +{ + return this; +} + +QAbstractItemModel *MapModel::getAbstract() +{ + return this; +} + +MapModel const *MapModel::getMap() const +{ + return this; +} + +MapModel *MapModel::getMap() +{ + return this; +} + +bool MapModel::isDirty() const +{ + return AbstractMapModel::isDirty(); +} + +bool MapModel::open(QString const &path) +{ + return AbstractMapModel::open(path); +} + +bool MapModel::save() const +{ + return AbstractMapModel::save(); +} + +bool MapModel::saveAs(QString const &path) const +{ + return AbstractMapModel::saveAs(path); +} + +QVariant MapModel::data(const QModelIndex &index, int role) const +{ + switch(role) { + case Qt::DecorationRole: { + auto name = propIcon(index.row()); + auto icon = name.front() == ':' ? QIcon(name) : QIcon::fromTheme(name); + return QVariant::fromValue(icon); + } + default: + return AbstractMapModel::data(index, role); + } +} + +// EOF diff --git a/tycho/cc_source/mapprops.cc b/tycho/cc/mapprops.cc similarity index 91% rename from tycho/cc_source/mapprops.cc rename to tycho/cc/mapprops.cc index 0bddc54..d33d011 100644 --- a/tycho/cc_source/mapprops.cc +++ b/tycho/cc/mapprops.cc @@ -1,7 +1,4 @@ #include "tycho.h" -#include "mapprops.h" - -#include MapProps::MapProps(MapModel *_mapModel, QWidget *parent) : QDialog(parent), diff --git a/tycho/cc/mapview.cc b/tycho/cc/mapview.cc new file mode 100644 index 0000000..3d22db9 --- /dev/null +++ b/tycho/cc/mapview.cc @@ -0,0 +1,16 @@ +#include "tycho.h" + +MapView::MapView(MapModel *mapModel, QWidget *parent) : + QWidget(parent) +{ + setupUi(this); + + dbgPrintFunc(); +} + +MapView::~MapView() +{ + dbgPrintFunc(); +} + +// EOF diff --git a/tycho/cc_source/menu.cc b/tycho/cc/menu.cc similarity index 87% rename from tycho/cc_source/menu.cc rename to tycho/cc/menu.cc index c6be78e..ae82e2a 100644 --- a/tycho/cc_source/menu.cc +++ b/tycho/cc/menu.cc @@ -1,16 +1,4 @@ #include "tycho.h" -#include "mapprops.h" -#include "menu.h" -#include "project.h" -#include "mapmodel.h" -#include "../ui/ui_about.h" -#include "../ui/ui_license.h" - -#include -#include -#include -#include -#include Menu::Menu(QWidget *parent) : QMainWindow(parent) @@ -54,7 +42,7 @@ void Menu::mapOpen() if(!fname.isEmpty()) { QScopedPointer proj{new Project(new MapModel)}; - if(proj->model.open(fname)) { + if(proj->model->open(fname)) { addProject(proj.take()); } } @@ -110,8 +98,8 @@ void Menu::openMapProperties() { auto proj = activeProject(); - if(proj && proj->model.type() == ProjectModel::Map) { - MapProps props{proj->model.getMap(), proj}; + if(proj && proj->model->type() == ProjectModel::Map) { + MapProps props{proj->model->getMap(), proj}; props.exec(); } } diff --git a/tycho/cc/project.cc b/tycho/cc/project.cc new file mode 100644 index 0000000..06daab4 --- /dev/null +++ b/tycho/cc/project.cc @@ -0,0 +1,52 @@ +#include "tycho.h" + +Project::Project(ProjectModel *_model, QWidget *parent) : + QMdiSubWindow(parent), + model(_model) +{ + auto widget = new QWidget(this); + + setupUi(widget); + + setWidget(widget); + setAttribute(Qt::WA_DeleteOnClose); + + listView->setModel(model->getAbstract()); + + dbgPrintFunc(); +} + +Project::~Project() +{ + dbgPrintFunc(); +} + +void Project::closeEvent(QCloseEvent *event) +{ + if(model->isDirty()) { + QMessageBox msg; + msg.setText(tr("Do you want to save your changes to this project before closing it?")); + msg.setInformativeText(tr("Unsaved changes will be lost unless you save.")); + msg.setStandardButtons(QMessageBox::Save | + QMessageBox::Discard | + QMessageBox::Cancel); + msg.setDefaultButton(QMessageBox::Save); + + switch(msg.exec()) { + case QMessageBox::Save: + model->save(); + break; + case QMessageBox::Discard: + break; + case QMessageBox::Cancel: + event->ignore(); + return; + default: + Q_UNREACHABLE(); + } + } + + event->accept(); +} + +// EOF diff --git a/tycho/cc/tycho.h b/tycho/cc/tycho.h new file mode 100644 index 0000000..f0db16b --- /dev/null +++ b/tycho/cc/tycho.h @@ -0,0 +1,172 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../ui/ui_about.h" +#include "../ui/ui_license.h" +#include "../ui/ui_mapprops.h" +#include "../ui/ui_mapview.h" +#include "../ui/ui_menu.h" +#include "../ui/ui_project.h" + +#include "bindings.h" + +#ifdef TYCHO_DEBUG_ASSERTIONS +#define dbgPrint(...) qDebug(__VA_ARGS__) +#else +#define dbgPrint(...) +#endif + +#define dbgPrintFunc() dbgPrint("%s", __func__) + +// TODO: namespace Tycho { + +class MapModel; +class MapProps; +class MapView; +class Menu; +class Project; +class ProjectModel; + +class MapProps : public QDialog, private Ui::MapProps +{ + Q_OBJECT + +public: + explicit MapProps(MapModel *mapModel, QWidget *parent = nullptr); + ~MapProps(); + +private: + MapModel *mapModel; +}; + +class MapView : public QWidget, private Ui::MapView +{ + Q_OBJECT + +public: + explicit MapView(MapModel *mapModel, QWidget *parent = nullptr); + ~MapView(); +}; + +class Project : public QMdiSubWindow, private Ui::Project +{ + Q_OBJECT + +public: + explicit Project(ProjectModel *model, QWidget *parent = nullptr); + ~Project(); + + QSharedPointer model; + +protected: + void closeEvent(QCloseEvent *event) override; +}; + +class ProjectModel +{ +public: + enum Type + { + Invalid, + Map, + }; + + virtual ~ProjectModel() {} + + virtual Type type() const = 0; + + virtual QAbstractItemModel const *getAbstract() const = 0; + virtual QAbstractItemModel *getAbstract() = 0; + virtual MapModel const *getMap() const = 0; + virtual MapModel *getMap() = 0; + + virtual bool isDirty() const = 0; + virtual bool open(QString const &path) = 0; + virtual bool save() const = 0; + virtual bool saveAs(QString const &path) const = 0; +}; + +class MapModel final : private AbstractMapModel, public ProjectModel +{ + Q_OBJECT + +public: + explicit MapModel(QObject *parent = nullptr); + ~MapModel() override; + + ProjectModel::Type type() const override; + + QAbstractItemModel const *getAbstract() const override; + QAbstractItemModel *getAbstract() override; + MapModel const *getMap() const override; + MapModel *getMap() override; + + bool isDirty() const override; + bool open(QString const &path) override; + bool save() const override; + bool saveAs(QString const &path) const override; + +private: + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) + const override; +}; + +class Menu : public QMainWindow, private Ui::Menu +{ + Q_OBJECT + +public: + explicit Menu(QWidget *parent = nullptr); + ~Menu(); + +public slots: + void mapNew(); + void mapOpen(); + void openAbout(); + void openAboutQt(); + void openMapProperties(); + void updateActions(); + +protected: + void closeEvent(QCloseEvent *event) override; + void openLicense(QWidget *parent); + +private: + Project *activeProject() const; + QMdiSubWindow *activeSubWindow() const; + void addProject(Project *proj); +}; + +constexpr std::uint32_t fourCC(std::uint8_t a, + std::uint8_t b, + std::uint8_t c, + std::uint8_t d) +{ + return (a << 24) | (b << 16) | (c << 8) | d; +} + +extern "C" { + char const *tychoAuthors(); + char const *tychoHomepage(); + char const *tychoLicenseText(); + char const *tychoRepository(); + char const *tychoVersion(); +} + +// } + +// EOF diff --git a/tycho/cc_headers/mapmodel.h b/tycho/cc_headers/mapmodel.h deleted file mode 100644 index acb5a67..0000000 --- a/tycho/cc_headers/mapmodel.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "bindings.h" - -class MapModel : public AbstractMapModel -{ - Q_OBJECT - -public: - explicit MapModel(QObject *parent = nullptr); - ~MapModel(); - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) - const override; -}; - -// EOF diff --git a/tycho/cc_headers/mapprops.h b/tycho/cc_headers/mapprops.h deleted file mode 100644 index 196c6ca..0000000 --- a/tycho/cc_headers/mapprops.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#include "../ui/ui_mapprops.h" - -class MapModel; - -class MapProps : public QDialog, private Ui::MapProps -{ - Q_OBJECT - -public: - explicit MapProps(MapModel *mapModel, QWidget *parent = nullptr); - ~MapProps(); - -private: - MapModel *mapModel; -}; - -// EOF diff --git a/tycho/cc_headers/menu.h b/tycho/cc_headers/menu.h deleted file mode 100644 index e3cad69..0000000 --- a/tycho/cc_headers/menu.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include - -#include "../ui/ui_menu.h" - -class Project; - -class Menu : public QMainWindow, private Ui::Menu -{ - Q_OBJECT - -public: - explicit Menu(QWidget *parent = nullptr); - ~Menu(); - -public slots: - void mapNew(); - void mapOpen(); - void openAbout(); - void openAboutQt(); - void openMapProperties(); - void updateActions(); - -protected: - void closeEvent(QCloseEvent *event) override; - void openLicense(QWidget *parent); - -private: - Project *activeProject() const; - QMdiSubWindow *activeSubWindow() const; - void addProject(Project *proj); -}; - -// EOF diff --git a/tycho/cc_headers/project.h b/tycho/cc_headers/project.h deleted file mode 100644 index 6c3d97a..0000000 --- a/tycho/cc_headers/project.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include - -#include "../ui/ui_project.h" - -class MapModel; - -class ProjectModel -{ -public: - enum Type - { - Invalid, - Map, - }; - - ProjectModel(MapModel *ptr); - ProjectModel(ProjectModel &&o); - ProjectModel() = delete; - ProjectModel(ProjectModel &) = delete; - ~ProjectModel(); - - Type type() const; - - QAbstractItemModel *getAbstract() const; - MapModel *getMap() const; - - bool isDirty() const; - bool open(QString const &path); - bool saveAs(QString const &path) const; - bool save() const; - -private: - Type modelType; - MapModel *modelMap; -}; - -class Project : public QMdiSubWindow, private Ui::Project -{ - Q_OBJECT - -public: - explicit Project(ProjectModel &&model, QWidget *parent = nullptr); - ~Project(); - - ProjectModel model; - -protected: - void closeEvent(QCloseEvent *event) override; -}; - -// EOF diff --git a/tycho/cc_headers/tycho.h b/tycho/cc_headers/tycho.h deleted file mode 100644 index ff4ae65..0000000 --- a/tycho/cc_headers/tycho.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "bindings.h" - -#ifdef TYCHO_DEBUG_PRINT -#define dbgPrint(...) qDebug(__VA_ARGS__) -#else -#define dbgPrint(...) -#endif - -#define dbgPrintFunc() dbgPrint("%s", __func__) - -constexpr std::uint32_t fourCC(std::uint8_t a, - std::uint8_t b, - std::uint8_t c, - std::uint8_t d) -{ - return (a << 24) | (b << 16) | (c << 8) | d; -} - -extern "C" { - char const *tychoAuthors(); - char const *tychoHomepage(); - char const *tychoLicenseText(); - char const *tychoRepository(); - char const *tychoVersion(); -} - -// EOF diff --git a/tycho/cc_source/cc.cc b/tycho/cc_source/cc.cc deleted file mode 100644 index ec81f56..0000000 --- a/tycho/cc_source/cc.cc +++ /dev/null @@ -1,10 +0,0 @@ -#include "tycho.h" -#include - -extern "C" { - void critical_msg(char const *title, char const *msg) { - QMessageBox::critical(nullptr, QObject::tr(title), QObject::tr(msg)); - } -} - -// EOF diff --git a/tycho/cc_source/mapmodel.cc b/tycho/cc_source/mapmodel.cc deleted file mode 100644 index e944cd6..0000000 --- a/tycho/cc_source/mapmodel.cc +++ /dev/null @@ -1,28 +0,0 @@ -#include "tycho.h" -#include "mapmodel.h" - -#include - -MapModel::MapModel(QObject *parent) : - AbstractMapModel(parent) -{ -} - -MapModel::~MapModel() -{ -} - -QVariant MapModel::data(const QModelIndex &index, int role) const -{ - switch(role) { - case Qt::DecorationRole: { - auto name = propIcon(index.row()); - auto icon = name.front() == ':' ? QIcon(name) : QIcon::fromTheme(name); - return QVariant::fromValue(icon); - } - default: - return AbstractMapModel::data(index, role); - } -} - -// EOF diff --git a/tycho/cc_source/project.cc b/tycho/cc_source/project.cc deleted file mode 100644 index 2a86dd6..0000000 --- a/tycho/cc_source/project.cc +++ /dev/null @@ -1,133 +0,0 @@ -#include "tycho.h" -#include "project.h" -#include "mapmodel.h" - -#include -#include - -ProjectModel::ProjectModel(MapModel *ptr) : - modelType(Map), - modelMap(ptr) -{ - Q_ASSERT(modelMap != nullptr); -} - -ProjectModel::ProjectModel(ProjectModel &&o) : - modelType(o.modelType), - modelMap(o.modelMap) -{ - o.modelType = Invalid; -} - -ProjectModel::~ProjectModel() -{ - switch(modelType) { - case Map: delete modelMap; break; - case Invalid: break; - } -} - -ProjectModel::Type ProjectModel::type() const -{ - return modelType; -} - -QAbstractItemModel *ProjectModel::getAbstract() const -{ - switch(modelType) { - case Map: return modelMap; - case Invalid: Q_UNREACHABLE(); - } -} - -MapModel *ProjectModel::getMap() const -{ - return modelType == Map ? modelMap : nullptr; -} - -bool ProjectModel::isDirty() const -{ - switch(modelType) { - case Map: return modelMap->isDirty(); - case Invalid: Q_UNREACHABLE(); - } - Q_UNREACHABLE(); -} - -bool ProjectModel::open(QString const &path) -{ - switch(modelType) { - case Map: return modelMap->open(path); - case Invalid: Q_UNREACHABLE(); - } - Q_UNREACHABLE(); -} - -bool ProjectModel::saveAs(QString const &path) const -{ - switch(modelType) { - case Map: return modelMap->saveAs(path); - case Invalid: Q_UNREACHABLE(); - } - Q_UNREACHABLE(); -} - -bool ProjectModel::save() const -{ - switch(modelType) { - case Map: return modelMap->save(); - case Invalid: Q_UNREACHABLE(); - } - Q_UNREACHABLE(); -} - -Project::Project(ProjectModel &&_model, QWidget *parent) : - QMdiSubWindow(parent), - model(std::move(_model)) -{ - auto widget = new QWidget(this); - - setupUi(widget); - - setWidget(widget); - setAttribute(Qt::WA_DeleteOnClose); - - listView->setModel(model.getAbstract()); - - dbgPrintFunc(); -} - -Project::~Project() -{ - dbgPrintFunc(); -} - -void Project::closeEvent(QCloseEvent *event) -{ - if(model.isDirty()) { - QMessageBox msg; - msg.setText(tr("Do you want to save your changes to this project before closing it?")); - msg.setInformativeText(tr("Unsaved changes will be lost unless you save.")); - msg.setStandardButtons(QMessageBox::Save | - QMessageBox::Discard | - QMessageBox::Cancel); - msg.setDefaultButton(QMessageBox::Save); - - switch(msg.exec()) { - case QMessageBox::Save: - model.save(); - break; - case QMessageBox::Discard: - break; - case QMessageBox::Cancel: - event->ignore(); - return; - default: - Q_UNREACHABLE(); - } - } - - event->accept(); -} - -// EOF diff --git a/tycho/ui/project.ui b/tycho/ui/project.ui index d5a21d4..b882e3a 100644 --- a/tycho/ui/project.ui +++ b/tycho/ui/project.ui @@ -14,6 +14,9 @@ Project + + +