diff --git a/source/tycho/CMakeLists.txt b/source/tycho/CMakeLists.txt index bb99487..3eb2249 100644 --- a/source/tycho/CMakeLists.txt +++ b/source/tycho/CMakeLists.txt @@ -29,7 +29,7 @@ add_library( cc_source/main.cc cc_source/mapprops.cc cc_source/menu.cc - cc_source/projectview.cc + cc_source/project.cc resources/resources.qrc ui/about.ui ui/license.ui @@ -37,7 +37,7 @@ add_library( ui/mapview.ui ui/menu.ui ui/points.ui - ui/projectview.ui + ui/project.ui ) set_target_properties( diff --git a/source/tycho/bindings.json b/source/tycho/bindings.json index fa1faa3..8983c88 100644 --- a/source/tycho/bindings.json +++ b/source/tycho/bindings.json @@ -6,21 +6,29 @@ "implementationModule": "qimpl" }, "objects": { - "ProjectModel": { - "type": "List", + "MapModel": { + "type": "Tree", "functions": { "open": { "return": "bool", "mut": true, "arguments": [{ - "name": "fname", + "name": "path", "type": "QString" }] }, "save": { - "return": "void", + "return": "bool", "mut": false }, + "saveAs": { + "return": "bool", + "mut": false, + "arguments": [{ + "name": "path", + "type": "QString" + }] + }, "isDirty": { "return": "bool", "mut": false diff --git a/source/tycho/cc_headers/mapprops.h b/source/tycho/cc_headers/mapprops.h index 2bc0bbf..196c6ca 100644 --- a/source/tycho/cc_headers/mapprops.h +++ b/source/tycho/cc_headers/mapprops.h @@ -4,19 +4,18 @@ #include "../ui/ui_mapprops.h" -class ProjectModel; +class MapModel; class MapProps : public QDialog, private Ui::MapProps { Q_OBJECT public: - explicit MapProps(QSharedPointer proj, - QWidget *parent = nullptr); + explicit MapProps(MapModel *mapModel, QWidget *parent = nullptr); ~MapProps(); private: - QSharedPointer proj; + MapModel *mapModel; }; // EOF diff --git a/source/tycho/cc_headers/menu.h b/source/tycho/cc_headers/menu.h index 00e7ebb..e6d7c55 100644 --- a/source/tycho/cc_headers/menu.h +++ b/source/tycho/cc_headers/menu.h @@ -5,7 +5,7 @@ #include "../ui/ui_menu.h" -class ProjectView; +class Project; class Menu : public QMainWindow, private Ui::Menu { @@ -27,9 +27,9 @@ protected: void openLicense(QWidget *parent); private: - ProjectView *activeProject() const; + Project *activeProject() const; QMdiSubWindow *activeSubWindow() const; - void addProject(ProjectView *view); + void addProject(Project *proj); }; // EOF diff --git a/source/tycho/cc_headers/project.h b/source/tycho/cc_headers/project.h index b112cfa..7eed791 100644 --- a/source/tycho/cc_headers/project.h +++ b/source/tycho/cc_headers/project.h @@ -2,24 +2,50 @@ #include -#include "bindings.h" -#include "../ui/ui_projectview.h" +#include "../ui/ui_project.h" -class ProjectView : public QMdiSubWindow, private Ui::ProjectView +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 ProjectView(QWidget *parent = nullptr); - ~ProjectView(); + explicit Project(ProjectModel &&model, QWidget *parent = nullptr); + ~Project(); - QSharedPointer model(); + ProjectModel model; protected: void closeEvent(QCloseEvent *event) override; - -private: - QSharedPointer proj; }; // EOF diff --git a/source/tycho/cc_headers/tycho.h b/source/tycho/cc_headers/tycho.h index 9349140..ff4ae65 100644 --- a/source/tycho/cc_headers/tycho.h +++ b/source/tycho/cc_headers/tycho.h @@ -4,6 +4,8 @@ #include #include +#include "bindings.h" + #ifdef TYCHO_DEBUG_PRINT #define dbgPrint(...) qDebug(__VA_ARGS__) #else diff --git a/source/tycho/cc_source/mapprops.cc b/source/tycho/cc_source/mapprops.cc index 28237e1..0bddc54 100644 --- a/source/tycho/cc_source/mapprops.cc +++ b/source/tycho/cc_source/mapprops.cc @@ -3,9 +3,9 @@ #include -MapProps::MapProps(QSharedPointer _proj, QWidget *parent) : +MapProps::MapProps(MapModel *_mapModel, QWidget *parent) : QDialog(parent), - proj(_proj) + mapModel(_mapModel) { setupUi(this); diff --git a/source/tycho/cc_source/menu.cc b/source/tycho/cc_source/menu.cc index 3f3ef16..4611dba 100644 --- a/source/tycho/cc_source/menu.cc +++ b/source/tycho/cc_source/menu.cc @@ -32,9 +32,9 @@ Menu::~Menu() void Menu::mapNew() { - QScopedPointer view{new ProjectView}; + QScopedPointer proj{new Project(new MapModel)}; - addProject(view.take()); + addProject(proj.take()); } void Menu::mapOpen() @@ -46,10 +46,10 @@ void Menu::mapOpen() QString(), tr("Marathon Map files (*.scen *.sceA Map)")); - QScopedPointer view{new ProjectView}; + QScopedPointer proj{new Project(new MapModel)}; - if(view->model()->open(fname)) { - addProject(view.take()); + if(proj->model.open(fname)) { + addProject(proj.take()); } } @@ -96,18 +96,18 @@ void Menu::openLicense(QWidget *parent) void Menu::openMapProperties() { - auto view = activeProject(); + auto proj = activeProject(); - if(view) { - MapProps props{view->model(), view}; + if(proj && proj->model.type() == ProjectModel::Map) { + MapProps props{proj->model.getMap(), proj}; props.exec(); } } void Menu::updateActions() { - auto view = activeProject(); - bool active = view != nullptr; + auto proj = activeProject(); + bool active = proj != nullptr; actionClose->setEnabled(active); actionMapProps->setEnabled(active); @@ -127,9 +127,9 @@ void Menu::closeEvent(QCloseEvent *event) event->accept(); } -ProjectView *Menu::activeProject() const +Project *Menu::activeProject() const { - return qobject_cast(activeSubWindow()); + return qobject_cast(activeSubWindow()); } QMdiSubWindow *Menu::activeSubWindow() const @@ -137,9 +137,9 @@ QMdiSubWindow *Menu::activeSubWindow() const return mdiArea->activeSubWindow(); } -void Menu::addProject(ProjectView *view) +void Menu::addProject(Project *proj) { - auto win = mdiArea->addSubWindow(view); + auto win = mdiArea->addSubWindow(proj); win->showMaximized(); } diff --git a/source/tycho/cc_source/project.cc b/source/tycho/cc_source/project.cc new file mode 100644 index 0000000..c08c9cf --- /dev/null +++ b/source/tycho/cc_source/project.cc @@ -0,0 +1,128 @@ +#include "tycho.h" +#include "project.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; + } +} + +ProjectModel::Type ProjectModel::type() const +{ + return modelType; +} + +QAbstractItemModel *ProjectModel::getAbstract() const +{ + switch(modelType) { + case Map: return modelMap; + } + Q_UNREACHABLE(); +} + +MapModel *ProjectModel::getMap() const +{ + return modelType == Map ? modelMap : nullptr; +} + +bool ProjectModel::isDirty() const +{ + switch(modelType) { + case Map: return modelMap->isDirty(); + } + Q_UNREACHABLE(); +} + +bool ProjectModel::open(QString const &path) +{ + switch(modelType) { + case Map: return modelMap->open(path); + } + Q_UNREACHABLE(); +} + +bool ProjectModel::saveAs(QString const &path) const +{ + switch(modelType) { + case Map: return modelMap->saveAs(path); + } + Q_UNREACHABLE(); +} + +bool ProjectModel::save() const +{ + switch(modelType) { + case Map: return modelMap->save(); + } + 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); + + treeView->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: + assert(true); + break; + } + } + + event->accept(); +} + +// EOF diff --git a/source/tycho/cc_source/projectview.cc b/source/tycho/cc_source/projectview.cc deleted file mode 100644 index bb89962..0000000 --- a/source/tycho/cc_source/projectview.cc +++ /dev/null @@ -1,62 +0,0 @@ -#include "tycho.h" -#include "project.h" - -#include -#include - -ProjectView::ProjectView(QWidget *parent) : - QMdiSubWindow(parent), - proj(new ProjectModel) -{ - auto widget = new QWidget(this); - - setupUi(widget); - - setWidget(widget); - setAttribute(Qt::WA_DeleteOnClose); - - listView->setModel(proj.data()); - - dbgPrintFunc(); -} - -ProjectView::~ProjectView() -{ - dbgPrintFunc(); -} - -QSharedPointer ProjectView::model() -{ - return proj; -} - -void ProjectView::closeEvent(QCloseEvent *event) -{ - if(proj->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: - proj->save(); - break; - case QMessageBox::Discard: - break; - case QMessageBox::Cancel: - event->ignore(); - return; - default: - assert(true); - break; - } - } - - event->accept(); -} - -// EOF diff --git a/source/tycho/source/qimpl.rs b/source/tycho/source/qimpl.rs index 42fb7f5..c649578 100644 --- a/source/tycho/source/qimpl.rs +++ b/source/tycho/source/qimpl.rs @@ -1,7 +1,7 @@ //! Qt implementation. -mod project; +mod map; -pub use self::project::*; +pub use self::map::*; // EOF diff --git a/source/tycho/source/qimpl/map.rs b/source/tycho/source/qimpl/map.rs new file mode 100644 index 0000000..66cdb0d --- /dev/null +++ b/source/tycho/source/qimpl/map.rs @@ -0,0 +1,138 @@ +//! Map model. + +use crate::qintr::*; +//use memmap::Mmap; +use maraiah::map; + +pub struct MapModel +{ + emit: MapModelEmitter, + model: MapModelTree, +} + +impl Drop for MapModel +{ + fn drop(&mut self) + { + if cfg!(debug_assertions) { + eprintln!("drop MapModel"); + } + } +} + +impl MapModelTrait for MapModel +{ + /// Returns a new `MapModel` instance. + fn new(emit: MapModelEmitter, model: MapModelTree) -> MapModel + { + if cfg!(debug_assertions) { + eprintln!("new MapModel"); + } + + MapModel{emit, model} + } + + /// Returns the emitter of `self`. + fn emit(&mut self) -> &mut MapModelEmitter + { + &mut self.emit + } + + /// Checks if `row` exists in the leaf `index`. + fn check_row(&self, index: usize, _row: usize) -> Option + { + None + } + + /// Returns the row `index` is in. + fn row(&self, index: usize) -> usize + { + index + } + + /// Returns the number of rows in `index`. + fn row_count(&self, index: Option) -> usize + { + match index { + Some(_) => 0, + None => 7, + } + } + + /// Returns the leaf index of `row` in the leaf `index`. + fn index(&self, index: Option, row: usize) -> usize + { + match index { + Some(_) => unreachable!(), + None => row, + } + } + + /// Returns the parent index of the leaf `index`, if any. + fn parent(&self, _index: usize) -> Option + { + // no parents! + None + } + + fn row_name(&self, row: usize) -> u64 + { + row as u64 + 1 + } + + fn some_number(&self, row: usize) -> u64 + { + 69420 + } + + /// Opens the map file at `path`. + fn open(&mut self, path: String) -> bool + { + if cfg!(debug_assertions) { + eprintln!("opening project: {}", &path); + } + + /* + let fp = std::fs::File::open(path); + let fp = if let Ok(fp) = fp {fp} else {return false;}; + + let mm = unsafe {Mmap::map(&fp)}; + let mm = if let Ok(mm) = mm {mm} else {return false;}; + + if let Ok(wad) = map::read(&mm) { + self.wad.replace(Some(wad)); + return true; + } + */ + + false + } + + /// Saves the project into the original file. + fn save(&self) -> bool + { + if cfg!(debug_assertions) { + eprintln!("saving project"); + } + + false + } + + /// Saves the project into `path`. + fn save_as(&self, path: String) -> bool + { + if cfg!(debug_assertions) { + eprintln!("saving project as {}", path); + } + + false + } + + /// Returns `true` if the file has been modified from its original state. + fn is_dirty(&self) -> bool + { + false + } +} + +// EOF diff --git a/source/tycho/source/qimpl/project.rs b/source/tycho/source/qimpl/project.rs deleted file mode 100644 index 83b6780..0000000 --- a/source/tycho/source/qimpl/project.rs +++ /dev/null @@ -1,88 +0,0 @@ -//! Project management. - -use crate::qintr::*; -//use memmap::Mmap; -use maraiah::map; - -pub struct ProjectModel -{ - emit: ProjectModelEmitter, -} - -impl Drop for ProjectModel -{ - fn drop(&mut self) - { - if cfg!(debug_assertions) { - eprintln!("drop ProjectModel"); - } - } -} - -impl ProjectModelTrait for ProjectModel -{ - fn new(emit: ProjectModelEmitter, _: ProjectModelList) -> ProjectModel - { - if cfg!(debug_assertions) { - eprintln!("new ProjectModel"); - } - - ProjectModel{emit} - } - - fn emit(&mut self) -> &mut ProjectModelEmitter - { - &mut self.emit - } - - fn row_count(&self) -> usize - { - 7 - } - - fn row_name(&self, row: usize) -> u64 - { - row as u64 + 1 - } - - fn some_number(&self, row: usize) -> u64 - { - 69420 - } - - fn open(&mut self, path: String) -> bool - { - if cfg!(debug_assertions) { - eprintln!("opening project: {}", &path); - } - - /* - let fp = std::fs::File::open(path); - let fp = if let Ok(fp) = fp {fp} else {return false;}; - - let mm = unsafe {Mmap::map(&fp)}; - let mm = if let Ok(mm) = mm {mm} else {return false;}; - - if let Ok(wad) = map::read(&mm) { - self.wad.replace(Some(wad)); - return true; - } - */ - - false - } - - fn save(&self) - { - if cfg!(debug_assertions) { - eprintln!("saving project"); - } - } - - fn is_dirty(&self) -> bool - { - false - } -} - -// EOF diff --git a/source/tycho/ui/projectview.ui b/source/tycho/ui/project.ui similarity index 63% rename from source/tycho/ui/projectview.ui rename to source/tycho/ui/project.ui index 8cb0849..d2ec69d 100644 --- a/source/tycho/ui/projectview.ui +++ b/source/tycho/ui/project.ui @@ -1,7 +1,7 @@ - ProjectView - + Project + 0 @@ -15,7 +15,16 @@ - + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + Qt::ScrollBarAlwaysOn