Sun, 12 Jun 2022 20:47:04 +0300
begin refactor of gl side
CMakeLists.txt | file | annotate | diff | comparison | revisions | |
src/basics.h | file | annotate | diff | comparison | revisions | |
src/document.cpp | file | annotate | diff | comparison | revisions | |
src/document.h | file | annotate | diff | comparison | revisions | |
src/document.ui | file | annotate | diff | comparison | revisions | |
src/documentmanager.cpp | file | annotate | diff | comparison | revisions | |
src/documentmanager.h | file | annotate | diff | comparison | revisions | |
src/gl/vertexprogram.cpp | file | annotate | diff | comparison | revisions | |
src/gl/vertexprogram.h | file | annotate | diff | comparison | revisions | |
src/main.cpp | file | annotate | diff | comparison | revisions | |
src/ui/canvas.cpp | file | annotate | diff | comparison | revisions | |
src/ui/canvas.h | file | annotate | diff | comparison | revisions | |
src/widgets/colorindexinput.cpp | file | annotate | diff | comparison | revisions | |
src/widgets/colorindexinput.h | file | annotate | diff | comparison | revisions |
--- a/CMakeLists.txt Sat Jun 11 15:20:24 2022 +0300 +++ b/CMakeLists.txt Sun Jun 12 20:47:04 2022 +0300 @@ -95,7 +95,6 @@ src/widgets/vec3editor.h ) set (LDFORGE_FORMS - src/document.ui src/mainwindow.ui src/settingseditor/librarieseditor.ui src/settingseditor/settingseditor.ui
--- a/src/basics.h Sat Jun 11 15:20:24 2022 +0300 +++ b/src/basics.h Sun Jun 12 20:47:04 2022 +0300 @@ -308,8 +308,8 @@ return qHash(key.x) ^ rotl10(qHash(key.y)) ^ rotl20(qHash(key.z)); } -template<typename K, typename V, typename Fn> -void forValueInMap(const std::map<K, V>& map, Fn&& fn) +template<typename T, typename Fn> +void forValueInMap(T&& map, Fn&& fn) { for (const auto& it : map) { fn(it.second);
--- a/src/document.cpp Sat Jun 11 15:20:24 2022 +0300 +++ b/src/document.cpp Sun Jun 12 20:47:04 2022 +0300 @@ -23,41 +23,38 @@ #include "model.h" #include "ui/objecteditor.h" -EditorTabWidget::EditorTabWidget( +EditTools::EditTools( Model* model, - DocumentManager* documents, const ColorTable& colorTable, - QWidget* parent) : - QWidget{parent}, + QObject* parent) : + QObject{parent}, colorTable{colorTable}, - canvas{new Canvas{model, this, documents, colorTable, this}}, model{model}, vertexMap{model} { - this->setMouseTracking(true); - connect(this->canvas, &Canvas::mouseClick, this, &EditorTabWidget::canvasMouseClick); - connect(this->canvas, &Canvas::mouseMove, this, &EditorTabWidget::canvasMouseMove); - connect(this->canvas, &Canvas::newStatusText, this, &EditorTabWidget::newStatusText); +#if 0 + connect(this->canvas, &Canvas::mouseClick, this, &EditTools::canvasMouseClick); + connect(this->canvas, &Canvas::mouseMove, this, &EditTools::canvasMouseMove); + connect(this->canvas, &Canvas::newStatusText, this, &EditTools::newStatusText); connect(this->model, &Model::dataChanged, this->canvas, qOverload<>(&Canvas::update)); connect(&this->vertexMap, &VertexMap::verticesChanged, [&]() { - this->canvas->rebuildVertices(this); + this->canvas->rebuildVertices(&this->vertexMap); }); this->canvas->drawState = &this->drawState; - QVBoxLayout* layout = new QVBoxLayout{this}; - layout->addWidget(this->canvas); +#endif } -EditorTabWidget::~EditorTabWidget() +EditTools::~EditTools() { } -void EditorTabWidget::applyToVertices(VertexMap::ApplyFunction fn) const +void EditTools::applyToVertices(VertexMap::ApplyFunction fn) const { this->vertexMap.apply(fn); } -void EditorTabWidget::setEditMode(EditingMode mode) +void EditTools::setEditMode(EditingMode mode) { this->drawState.mode = mode; } @@ -87,8 +84,9 @@ return any(points, std::bind(isclose, std::placeholders::_1, pos)); } -void EditorTabWidget::canvasMouseClick(QMouseEvent *event) +void EditTools::canvasMouseClick(QMouseEvent*) { +#if 0 switch(this->drawState.mode) { case SelectMode: @@ -104,15 +102,11 @@ } break; case DrawMode: - if (event->button() == Qt::LeftButton and this->canvas->worldPosition.has_value()) - { - const glm::vec3& pos = this->canvas->worldPosition.value(); - if (isCloseToExistingPoints(this->drawState.polygon, pos)) - { + if (event->button() == Qt::LeftButton) { + if (isCloseToExistingPoints(this->drawState.polygon, worldPosition)) { this->closeShape(); } - else - { + else { this->drawState.polygon.push_back(pos); updatePreviewPolygon(&this->drawState); } @@ -128,10 +122,11 @@ } break; } +#endif } - -void EditorTabWidget::canvasMouseMove(QMouseEvent *event) +void EditTools::canvasMouseMove(QMouseEvent*) { +#if 0 switch(this->drawState.mode) { case SelectMode: @@ -146,7 +141,9 @@ event->accept(); break; } +#endif } +#if 0 /* void EditorTabWidget::select(const QSet<ModelId> &selected) @@ -165,17 +162,17 @@ selectionModel->select(itemSelection, QItemSelectionModel::ClearAndSelect); } */ -const QSet<ModelId> EditorTabWidget::selectedObjects() const +const QSet<ModelId> EditTools::selectedObjects() const { return this->canvas->selectedObjects(); } - -EditingMode EditorTabWidget::currentEditingMode() const +#endif +EditingMode EditTools::currentEditingMode() const { return this->drawState.mode; } - -void EditorTabWidget::closeShape() +#if 0 +void EditTools::closeShape() { if (this->drawState.polygon.size() >= 2 and this->drawState.polygon.size() <= 4) { @@ -222,3 +219,5 @@ this->drawState.polygon.clear(); updatePreviewPolygon(&this->drawState); } + +#endif
--- a/src/document.h Sat Jun 11 15:20:24 2022 +0300 +++ b/src/document.h Sun Jun 12 20:47:04 2022 +0300 @@ -38,20 +38,18 @@ Q_DECLARE_METATYPE(ModelAction) -class EditorTabWidget : public QWidget +class EditTools : public QObject { Q_OBJECT public: - explicit EditorTabWidget( + explicit EditTools( Model* model, - DocumentManager* documents, const ColorTable& colorTable, - QWidget *parent = nullptr); - ~EditorTabWidget() override; + QObject *parent = nullptr); + ~EditTools() override; void applyToVertices(VertexMap::ApplyFunction fn) const; const QSet<ModelId> selectedObjects() const; const ColorTable& colorTable; - Canvas* const canvas; Model* const model; EditingMode currentEditingMode() const; Q_SLOT void setEditMode(EditingMode mode); @@ -61,6 +59,7 @@ void newStatusText(const QString& newStatusText); void splitterChanged(); void modelAction(const ModelAction& action); + void drawStateChanged(const DrawState& drawState); private: void closeShape(); DrawState drawState;
--- a/src/document.ui Sat Jun 11 15:20:24 2022 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>Document</class> - <widget class="QWidget" name="Document"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>957</width> - <height>540</height> - </rect> - </property> - <property name="windowTitle"> - <string>Form</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QSplitter" name="viewportListSplitter"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <widget class="QFrame" name="viewportFrame"> - <property name="frameShape"> - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Raised</enum> - </property> - </widget> - <widget class="QListView" name="listView"> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> - </property> - <property name="selectionBehavior"> - <enum>QAbstractItemView::SelectRows</enum> - </property> - </widget> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui>
--- a/src/documentmanager.cpp Sat Jun 11 15:20:24 2022 +0300 +++ b/src/documentmanager.cpp Sun Jun 12 20:47:04 2022 +0300 @@ -24,7 +24,8 @@ #include "documentmanager.h" #include "parser.h" -DocumentManager::DocumentManager() +DocumentManager::DocumentManager(QObject *parent) : + QObject{parent} { } @@ -35,8 +36,10 @@ ModelId DocumentManager::newModel() { const ModelId modelId{++this->modelIdCounter}; - this->openModels[modelId].id = modelId; - this->openModels[modelId].opentype = OpenType::ManuallyOpened; + this->openModels.emplace(std::make_pair(modelId, ModelInfo{ + .id = modelId, + .opentype = OpenType::ManuallyOpened, + })); this->makePolygonCacheForModel(modelId); return modelId; } @@ -122,13 +125,13 @@ if (file.error() == QFile::NoError) { const ModelId modelId{++this->modelIdCounter}; - this->openModels[modelId] = { + this->openModels.emplace(std::make_pair(modelId, ModelInfo{ .model = std::move(newModel), .id = modelId, .path = path, .opentype = openType, .polygonCache = {}, - }; + })); this->makePolygonCacheForModel(modelId); result = modelId; } @@ -241,11 +244,20 @@ } } -const DocumentManager::ModelInfo *DocumentManager::infoForModel(ModelId modelId) const +const DocumentManager::ModelInfo *DocumentManager::find(ModelId modelId) const { return findInMap(this->openModels, modelId); } +void DocumentManager::setModelPayload(ModelId modelId, QObject *object) +{ + ModelInfo* info = findInMap(this->openModels, modelId); + if (info != nullptr) { + info->payload = object; + object->setParent(this); + } +} + QString errorStringFromMissingDependencies(const DocumentManager::MissingDependencies& missing) { QString missingString;
--- a/src/documentmanager.h Sat Jun 11 15:20:24 2022 +0300 +++ b/src/documentmanager.h Sun Jun 12 20:47:04 2022 +0300 @@ -29,8 +29,9 @@ AutomaticallyOpened, }; -class DocumentManager +class DocumentManager : public QObject { + Q_OBJECT public: struct ModelInfo { @@ -39,10 +40,13 @@ QString path; OpenType opentype; std::map<QString, ModelId> dependencies = {}; - PolygonCache polygonCache; + PolygonCache polygonCache = {}; + QObject* payload; }; using MissingDependencies = std::map<QString, QString>; - DocumentManager(); + DocumentManager(QObject* parent = nullptr); + auto begin() const { return this->openModels.begin(); } + auto end() const { return this->openModels.end(); } ModelId newModel(); Model* findDependencyByName(const ModelId modelId, const QString& name); Model* getModelById(ModelId modelId); @@ -58,7 +62,14 @@ bool saveModel(const ModelId modelId, QTextStream& errors); std::optional<ModelId> findIdForModel(const Model* model) const; PolygonCache* getPolygonCacheForModel(ModelId modelId); - const ModelInfo* infoForModel(ModelId modelId) const; + const ModelInfo* find(ModelId modelId) const; + void setModelPayload(ModelId modelId, QObject* object); + template<typename T> + T* findPayload(ModelId modelId) const + { + const ModelInfo* info = this->find(modelId); + return info ? qobject_cast<T*>(info->payload) : nullptr; + } private: int modelIdCounter = 0; std::map<ModelId, ModelInfo> openModels;
--- a/src/gl/vertexprogram.cpp Sat Jun 11 15:20:24 2022 +0300 +++ b/src/gl/vertexprogram.cpp Sun Jun 12 20:47:04 2022 +0300 @@ -120,12 +120,12 @@ this->fragmentStyle = newFragmentStyle; } -void VertexProgram::build(const EditorTabWidget *document) +void VertexProgram::build(const VertexMap* vertexMap) { constexpr glm::vec3 color = {0.0, 1.0, 1.0}; this->data.clear(); const std::vector<glm::vec3> sphere = ::sphere(8 / 2); - document->applyToVertices([&](const glm::vec3&, const VertexMap::VertexInfo& info) + vertexMap->apply([&](const glm::vec3&, const VertexMap::VertexInfo& info) { reserveMore(this->data, sphere.size()); for (const glm::vec3& point : sphere)
--- a/src/gl/vertexprogram.h Sat Jun 11 15:20:24 2022 +0300 +++ b/src/gl/vertexprogram.h Sun Jun 12 20:47:04 2022 +0300 @@ -1,7 +1,7 @@ #ifndef VERTEXPROGRAM_H #define VERTEXPROGRAM_H #include "basicshaderprogram.h" -class EditorTabWidget; +class VertexMap; class VertexProgram : public AbstractBasicShaderProgram { @@ -17,7 +17,7 @@ glm::vec3 color; }; VertexProgram(QObject* parent = nullptr); - void build(const EditorTabWidget* document); + void build(const VertexMap* document); protected: const char* vertexShaderSource() const override; const char* fragmentShaderSource() const override;
--- a/src/main.cpp Sat Jun 11 15:20:24 2022 +0300 +++ b/src/main.cpp Sun Jun 12 20:47:04 2022 +0300 @@ -3,15 +3,34 @@ #include <QMessageBox> #include <QMdiSubWindow> #include <QStackedWidget> +#include <QCloseEvent> #include "mainwindow.h" #include "ui_mainwindow.h" #include "version.h" +#include "ui/canvas.h" #include "document.h" #include "settingseditor/settingseditor.h" #include "widgets/colorselectdialog.h" static const QDir LOCALE_DIR {":/locale"}; +class ModelSubWindow : public QMdiSubWindow +{ + Q_OBJECT +public: + const ModelId modelId; + ModelSubWindow(ModelId modelId, QWidget* widget) : + QMdiSubWindow{widget}, + modelId{modelId} + { + } +protected: + void closeEvent(QCloseEvent* event) override + { + event->ignore(); + } +}; + static void doQtRegistrations() { QCoreApplication::setApplicationName(::appName); @@ -32,6 +51,18 @@ } }; +class ModelData : public QObject +{ + Q_OBJECT +public: + ModelData(QObject* parent) : QObject {parent} {} + std::unique_ptr<Canvas> canvas; + std::unique_ptr<QItemSelectionModel> itemSelectionModel; + std::unique_ptr<EditTools> tools; + Model* model; +}; +#include "main.moc" + static constexpr MemberData<Ui_MainWindow, QAction*, gl::RenderStyle> renderStyleButtons[] = { { offsetof(Ui_MainWindow, actionRenderStyleNormal), gl::RenderStyle::Normal }, { offsetof(Ui_MainWindow, actionRenderStyleBfc), gl::RenderStyle::BfcRedGreen }, @@ -107,52 +138,41 @@ } } -/* -void MainWindow::handleDocumentSplitterChange() +ModelData* findModelData(DocumentManager* documents, ModelId modelId) +{ + return documents->findPayload<ModelData>(modelId); +} + +static ModelSubWindow* currentModelSubWindow(Ui_MainWindow* ui) { - EditorTabWidget* currentDocument = this->currentDocument(); - if (currentDocument != nullptr) - { - this->documentSplitterState = currentDocument->saveSplitterState(); - for (int i = 0; i < this->ui->tabs->count(); i += 1) - { - EditorTabWidget* document = qobject_cast<EditorTabWidget*>(this->ui->tabs->widget(i)); - if (document != nullptr and document != currentDocument) - { - document->restoreSplitterState(this->documentSplitterState); - } - } - this->settings.setMainSplitterState(this->documentSplitterState); - } + return qobject_cast<ModelSubWindow*>(ui->mdiArea->activeSubWindow()); } -*/ -static EditorTabWidget* currentTabWidget(Ui_MainWindow* ui) +static ModelData* currentModelData(Ui_MainWindow* ui, DocumentManager* documents) { - QMdiSubWindow* activeSubWindow = ui->mdiArea->activeSubWindow(); - if (activeSubWindow == nullptr) { - return nullptr; + if (auto* const activeSubWindow = currentModelSubWindow(ui)) { + return findModelData(documents, activeSubWindow->modelId); } else { - return qobject_cast<EditorTabWidget*>(activeSubWindow->widget()); - } -}; - - -static void closeDocument(DocumentManager* documents, EditorTabWidget *document) -{ - std::optional<ModelId> modelId = documents->findIdForModel(document->model); - if (modelId.has_value()) { - documents->closeDocument(modelId.value()); - delete document; + return nullptr; } } -static std::optional<ModelId> findCurrentModelId(Ui_MainWindow* ui, DocumentManager* documents) +static Model* currentModelBody(Ui_MainWindow* ui, DocumentManager* documents) { - const EditorTabWidget* tab = currentTabWidget(ui); - if (tab != nullptr) { - return documents->findIdForModel(tab->model); + if (auto* const activeSubWindow = currentModelSubWindow(ui)) { + return documents->getModelById(activeSubWindow->modelId); + } + else { + return nullptr; + } +} + +static std::optional<ModelId> findCurrentModelId(Ui_MainWindow* ui) +{ + ModelSubWindow* activeSubWindow = qobject_cast<ModelSubWindow*>(ui->mdiArea->activeSubWindow()); + if (activeSubWindow != nullptr) { + return activeSubWindow->modelId; } else { return {}; @@ -196,16 +216,28 @@ } } +template<typename Fn> +static void forModel(const DocumentManager* documents, Fn&& fn) +{ + forValueInMap(*documents, [&fn](const DocumentManager::ModelInfo& info) + { + ModelData* modelSpecificData = qobject_cast<ModelData*>(info.payload); + if (modelSpecificData != nullptr) { + fn(&info, modelSpecificData); + } + }); +} + static void updateRenderPreferences( Ui_MainWindow* ui, - const gl::RenderPreferences* renderPreferences) + const gl::RenderPreferences* renderPreferences, + const DocumentManager* documents) { - for (QMdiSubWindow* subWindow : ui->mdiArea->subWindowList()) { - EditorTabWidget* tab = qobject_cast<EditorTabWidget*>(subWindow->widget()); - if (tab != nullptr) { - tab->canvas->setRenderPreferences(*renderPreferences); + forModel(documents, [&renderPreferences](const void*, const ModelData* data){ + if (data->canvas != nullptr) { + data->canvas->setRenderPreferences(*renderPreferences); } - } + }); for (auto data : ::renderStyleButtons) { QAction* action = data.memberInstance(ui); action->setChecked(renderPreferences->style == data.payload); @@ -295,7 +327,6 @@ QStringList recentlyOpenedFiles; ColorTable colorTable; gl::RenderPreferences renderPreferences; - QMap<Model*, QItemSelectionModel*> itemSelectionModels; ui.setupUi(&mainWindow); const uiutilities::KeySequenceMap defaultKeyboardShortcuts = uiutilities::makeKeySequenceMap(uiutilities::collectActions(&mainWindow)); @@ -340,7 +371,7 @@ libraries.restoreFromSettings(&settings); updateRecentlyOpenedDocumentsMenu(); colorTable = loadColors(&libraries); - updateRenderPreferences(&ui, &renderPreferences); + updateRenderPreferences(&ui, &renderPreferences, &documents); ui.mdiArea->setViewMode(static_cast<QMdiArea::ViewMode>(settings.viewMode())); ui.retranslateUi(&mainWindow); }; @@ -357,36 +388,45 @@ }; const auto openModelForEditing = [&](const ModelId modelId){ Model* model = documents.getModelById(modelId); - EditorTabWidget* document = new EditorTabWidget{model, &documents, colorTable}; - QObject::connect( - document, - &EditorTabWidget::modelAction, - std::bind(executeAction, model, std::placeholders::_1)); - QItemSelectionModel* selectionModel = new QItemSelectionModel{model}; - itemSelectionModels[model] = selectionModel; - QObject::connect(selectionModel, &QItemSelectionModel::selectionChanged, - [model, document](const QItemSelection& selected, const QItemSelection& deselected) - { - auto resolveIndex = [&model](const QModelIndex& index){ - return model->idAt(index.row()); - }; - auto resolve = [&resolveIndex](const QItemSelection& selection) + if (model != nullptr) { + ModelData* data = new ModelData(&documents); + data->tools = std::make_unique<EditTools>(model, colorTable); + data->canvas = std::make_unique<Canvas>(model, data->tools.get(), &documents, colorTable); + data->itemSelectionModel = std::make_unique<QItemSelectionModel>(model); + data->model = model; + QObject::connect( + data->tools.get(), + &EditTools::modelAction, + std::bind(executeAction, model, std::placeholders::_1)); + QObject::connect(data->itemSelectionModel.get(), &QItemSelectionModel::selectionChanged, + [modelId, &documents]( + const QItemSelection& selected, + const QItemSelection& deselected) { - return fn::map<QSet<ModelId>>(selection.indexes(), resolveIndex); - }; - document->canvas->handleSelectionChange(resolve(selected), resolve(deselected)); - }); - document->canvas->setRenderPreferences(renderPreferences); - QObject::connect( - document, - &EditorTabWidget::newStatusText, - [&](const QString& newStatusText) { - mainWindow.statusBar()->showMessage(newStatusText); + ModelData* data = findModelData(&documents, modelId); + if (data != nullptr) { + auto resolveIndex = [&data](const QModelIndex& index){ + return data->model->idAt(index.row()); + }; + auto resolve = [&resolveIndex](const QItemSelection& selection) + { + return fn::map<QSet<ModelId>>(selection.indexes(), resolveIndex); + }; + data->canvas->handleSelectionChange(resolve(selected), resolve(deselected)); + } }); - const QFileInfo fileInfo{*documents.modelPath(modelId)}; - QMdiSubWindow* subWindow = ui.mdiArea->addSubWindow(document); - subWindow->setWindowTitle(tabName(fileInfo)); - subWindow->show(); + data->canvas->setRenderPreferences(renderPreferences); + QObject::connect( + data->tools.get(), + &EditTools::newStatusText, + [&](const QString& newStatusText) { + mainWindow.statusBar()->showMessage(newStatusText); + }); + const QFileInfo fileInfo{*documents.modelPath(modelId)}; + QMdiSubWindow* subWindow = ui.mdiArea->addSubWindow(data->canvas.get()); + subWindow->setWindowTitle(tabName(fileInfo)); + subWindow->show(); + } }; QObject::connect(ui.actionNew, &QAction::triggered, [&]{ openModelForEditing(documents.newModel()); @@ -411,18 +451,14 @@ } }); QObject::connect(ui.actionQuit, &QAction::triggered, &mainWindow, &QMainWindow::close); - QObject::connect(ui.actionAdjustGridToView, &QAction::triggered, [&ui]{ - EditorTabWidget* tab = currentTabWidget(&ui); - if (tab != nullptr) - { - adjustGridToView(tab->canvas); + QObject::connect(ui.actionAdjustGridToView, &QAction::triggered, [&]{ + if (ModelData* data = currentModelData(&ui, &documents)) { + adjustGridToView(data->canvas.get()); } }); QObject::connect(ui.actionClose, &QAction::triggered, [&ui, &documents]{ - EditorTabWidget* tab = currentTabWidget(&ui); - if (tab != nullptr) - { - closeDocument(&documents, tab); + if (ModelData* data = currentModelData(&ui, &documents)) { + // TODO } }); const auto save = [&](ModelId modelId){ @@ -442,7 +478,7 @@ } }; const auto actionSaveAs = [&]{ - const std::optional<ModelId> modelId = findCurrentModelId(&ui, &documents); + const std::optional<ModelId> modelId = findCurrentModelId(&ui); if (modelId.has_value()) { const QString* pathPtr = documents.modelPath(*modelId); @@ -467,40 +503,37 @@ }; QObject::connect(ui.actionSaveAs, &QAction::triggered, actionSaveAs); QObject::connect(ui.actionSave, &QAction::triggered, [&]{ - if (currentTabWidget(&ui) != nullptr) { - const std::optional<ModelId> modelId = findCurrentModelId(&ui, &documents); - if (modelId.has_value()) { - const QString* path = documents.modelPath(*modelId); - if (path == nullptr or path->isEmpty()) { - actionSaveAs(); - } - else { - save(*modelId); - } + const std::optional<ModelId> modelId = findCurrentModelId(&ui); + if (modelId.has_value()) { + const QString* path = documents.modelPath(*modelId); + if (path == nullptr or path->isEmpty()) { + actionSaveAs(); + } + else { + save(*modelId); } } }); QObject::connect(ui.actionDelete, &QAction::triggered, [&]{ - EditorTabWidget* tab = currentTabWidget(&ui); - if (tab != nullptr) { + if (Model* model = currentModelBody(&ui, &documents)) { std::vector<int> selectedRows = rows(ui.modelListView->selectionModel()->selectedRows()); std::sort(selectedRows.begin(), selectedRows.end(), std::greater<int>{}); for (int row : selectedRows) { - executeAction(tab->model, DeleteFromModel{.position = row}); + executeAction(model, DeleteFromModel{.position = row}); } } }); QObject::connect(ui.actionDrawAxes, &QAction::triggered, [&](bool drawAxes){ renderPreferences.drawAxes = drawAxes; saveSettings(); - updateRenderPreferences(&ui, &renderPreferences); + updateRenderPreferences(&ui, &renderPreferences, &documents); }); for (auto data : ::renderStyleButtons) { QAction* action = data.memberInstance(&ui); QObject::connect(action, &QAction::triggered, [&, data]{ renderPreferences.style = data.payload; saveSettings(); - updateRenderPreferences(&ui, &renderPreferences); + updateRenderPreferences(&ui, &renderPreferences, &documents); }); } const auto checkEditingModeAction = [&ui](EditingMode mode) { @@ -511,24 +544,22 @@ initializeTools(&ui, &mainWindow); for (QAction* action : ui.editingModesToolBar->actions()) { QObject::connect(action, &QAction::triggered, [&, action]{ - EditorTabWidget* tab = currentTabWidget(&ui); - if (tab != nullptr) { + if (ModelData* data = currentModelData(&ui, &documents)) { const EditingMode mode = action->data().value<EditingMode>(); - tab->setEditMode(mode); + data->tools->setEditMode(mode); checkEditingModeAction(mode); } }); } QObject::connect(ui.mdiArea, &QMdiArea::subWindowActivated, [&](QMdiSubWindow* subWindow) { - if (subWindow != nullptr) { - EditorTabWidget* tab = qobject_cast<EditorTabWidget*>(subWindow->widget()); - if (tab != nullptr) { - checkEditingModeAction(tab->currentEditingMode()); - QItemSelectionModel* selectionModel = itemSelectionModels.value(tab->model); - if (selectionModel != nullptr) { - ui.modelListView->setModel(tab->model); - ui.modelListView->setSelectionModel(selectionModel); + ModelSubWindow* modelSubWindow = qobject_cast<ModelSubWindow*>(subWindow); + if (modelSubWindow != nullptr) { + if (ModelData* data = documents.findPayload<ModelData>(modelSubWindow->modelId)) { + checkEditingModeAction(data->tools->currentEditingMode()); + if (data->itemSelectionModel != nullptr) { + ui.modelListView->setModel(data->model); + ui.modelListView->setSelectionModel(data->itemSelectionModel.get()); } } } @@ -536,7 +567,7 @@ mainWindow.setWindowTitle(title()); mainWindow.restoreGeometry(settings.mainWindowGeometry()); restoreSettings(); - updateRenderPreferences(&ui, &renderPreferences); + updateRenderPreferences(&ui, &renderPreferences, &documents); mainWindow.show(); const int result = app.exec(); saveSettings();
--- a/src/ui/canvas.cpp Sat Jun 11 15:20:24 2022 +0300 +++ b/src/ui/canvas.cpp Sun Jun 12 20:47:04 2022 +0300 @@ -5,7 +5,7 @@ Canvas::Canvas( Model* model, - EditorTabWidget *document, + EditTools *document, DocumentManager* documents, const ColorTable& colorTable, QWidget* parent) : @@ -33,11 +33,11 @@ * @brief Updates vertex rendering * @param document Document to get vertices from */ -void Canvas::rebuildVertices(EditorTabWidget* document) +void Canvas::rebuildVertices(VertexMap* vertexMap) { if (this->vertexProgram.has_value()) { - this->vertexProgram->build(document); + this->vertexProgram->build(vertexMap); this->update(); } }
--- a/src/ui/canvas.h Sat Jun 11 15:20:24 2022 +0300 +++ b/src/ui/canvas.h Sun Jun 12 20:47:04 2022 +0300 @@ -7,6 +7,8 @@ #include "gl/axesprogram.h" #include "gl/vertexprogram.h" +class EditTools; + enum EditingMode { SelectMode, @@ -30,7 +32,7 @@ using OverpaintCallback = std::function<void(Canvas*, QPainter*)>; Canvas( Model* model, - EditorTabWidget* document, + EditTools* document, DocumentManager* documents, const ColorTable& colorTable, QWidget* parent = nullptr); @@ -48,7 +50,7 @@ DrawState* drawState = nullptr; public Q_SLOTS: void handleSelectionChange(const QSet<ModelId>& selectedIds, const QSet<ModelId>& deselectedIds); - void rebuildVertices(EditorTabWidget *document); + void rebuildVertices(VertexMap* vertexMap); void setGridMatrix(const glm::mat4 &newMatrix); protected: void mouseMoveEvent(QMouseEvent* event) override; @@ -74,7 +76,7 @@ bool isDark = true; QSet<ModelId> selection; OverpaintCallback overpaintCallback = nullptr; - EditorTabWidget* document; + EditTools* document; }; void adjustGridToView(Canvas* canvas);
--- a/src/widgets/colorindexinput.cpp Sat Jun 11 15:20:24 2022 +0300 +++ b/src/widgets/colorindexinput.cpp Sun Jun 12 20:47:04 2022 +0300 @@ -3,15 +3,15 @@ #include "colorselectdialog.h" #include "uiutilities.h" -ColorIndexInput::ColorIndexInput(EditorTabWidget *document, ColorIndex color, QWidget *parent) : +ColorIndexInput::ColorIndexInput(ColorTable *colorTable, ColorIndex color, QWidget *parent) : QWidget{parent}, - document{document}, + colorTable{colorTable}, ui{*new Ui_ColorIndexInput} { this->ui.setupUi(this); connect(this->ui.button, &QPushButton::clicked, [this]() { - ColorSelectDialog dialog{this->document->colorTable, this->document}; + ColorSelectDialog dialog{*this->colorTable, this}; const int result = dialog.exec(); if (result == QDialog::Accepted) { @@ -20,8 +20,9 @@ }); connect(this->ui.index, qOverload<int>(&QSpinBox::valueChanged), [this](int value) { - this->ui.button->setText(colorDisplayName({value}, this->document->colorTable).value_or("???")); - const opt<QColor> face = colorFace({value}, this->document->colorTable); + const opt<QString> displayName = colorDisplayName({value}, *this->colorTable); + const opt<QColor> face = colorFace({value}, *this->colorTable); + this->ui.button->setText(displayName.value_or(tr("???"))); if (face.has_value()) { uiutilities::colorizeWidget(this->ui.button, *face); }
--- a/src/widgets/colorindexinput.h Sat Jun 11 15:20:24 2022 +0300 +++ b/src/widgets/colorindexinput.h Sun Jun 12 20:47:04 2022 +0300 @@ -5,13 +5,13 @@ { Q_OBJECT public: - ColorIndexInput(EditorTabWidget *document, ColorIndex color = MAIN_COLOR, QWidget *parent = nullptr); + ColorIndexInput(ColorTable *colorTable, ColorIndex color = MAIN_COLOR, QWidget *parent = nullptr); ~ColorIndexInput(); ldraw::Color selectedColor() const; void setSelectedColor(ldraw::Color color); Q_SIGNALS: void colorChanged(ldraw::Color color); private: - EditorTabWidget* const document; + ColorTable* const colorTable; class Ui_ColorIndexInput& ui; };