tycho: see? I told you it was magic
parent
1ac6b2df9d
commit
c2339138a8
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<ProjectModel> proj,
|
||||
QWidget *parent = nullptr);
|
||||
explicit MapProps(MapModel *mapModel, QWidget *parent = nullptr);
|
||||
~MapProps();
|
||||
|
||||
private:
|
||||
QSharedPointer<ProjectModel> proj;
|
||||
MapModel *mapModel;
|
||||
};
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -2,24 +2,50 @@
|
|||
|
||||
#include <QMdiSubWindow>
|
||||
|
||||
#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<ProjectModel> model();
|
||||
ProjectModel model;
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private:
|
||||
QSharedPointer<ProjectModel> proj;
|
||||
};
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
#include "bindings.h"
|
||||
|
||||
#ifdef TYCHO_DEBUG_PRINT
|
||||
#define dbgPrint(...) qDebug(__VA_ARGS__)
|
||||
#else
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
#include <QDialogButtonBox>
|
||||
|
||||
MapProps::MapProps(QSharedPointer<ProjectModel> _proj, QWidget *parent) :
|
||||
MapProps::MapProps(MapModel *_mapModel, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
proj(_proj)
|
||||
mapModel(_mapModel)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
|
|
|
@ -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<ProjectView *>(activeSubWindow());
|
||||
return qobject_cast<Project *>(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();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
#include "tycho.h"
|
||||
#include "project.h"
|
||||
|
||||
#include <QCloseEvent>
|
||||
#include <QMessageBox>
|
||||
|
||||
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
|
|
@ -1,62 +0,0 @@
|
|||
#include "tycho.h"
|
||||
#include "project.h"
|
||||
|
||||
#include <QCloseEvent>
|
||||
#include <QMessageBox>
|
||||
|
||||
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<ProjectModel> 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
|
|
@ -1,7 +1,7 @@
|
|||
//! Qt implementation.
|
||||
|
||||
mod project;
|
||||
mod map;
|
||||
|
||||
pub use self::project::*;
|
||||
pub use self::map::*;
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -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<usize>
|
||||
{
|
||||
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>) -> usize
|
||||
{
|
||||
match index {
|
||||
Some(_) => 0,
|
||||
None => 7,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the leaf index of `row` in the leaf `index`.
|
||||
fn index(&self, index: Option<usize>, 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<usize>
|
||||
{
|
||||
// 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
|
|
@ -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
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ProjectView</class>
|
||||
<widget class="QWidget" name="ProjectView">
|
||||
<class>Project</class>
|
||||
<widget class="QWidget" name="Project">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
@ -15,7 +15,16 @@
|
|||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QListView" name="listView">
|
||||
<widget class="QTreeView" name="treeView">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
Loading…
Reference in New Issue