--- a/src/document.cpp Wed May 25 13:49:45 2022 +0300 +++ b/src/document.cpp Wed May 25 17:24:51 2022 +0300 @@ -22,12 +22,7 @@ #include "ui_document.h" #include "model.h" #include "modeleditor.h" -#include "tools/basetool.h" -#include "tools/drawtool.h" -#include "tools/pathtool.h" -#include "tools/selecttool.h" -#include "tools/transformtool.h" -#include "tools/circletool.h" +#include "ui/objecteditor.h" Document::Document( Model* model, @@ -36,12 +31,13 @@ QWidget* parent) : QWidget{parent}, colorTable{colorTable}, + canvas{new Canvas{model, this, documents, colorTable, this}}, model{model}, documents{documents}, vertexMap{model}, - renderer{new Canvas{model, documents, colorTable, this}}, - ui{*new Ui::Document}, - toolsBar{new QToolBar{this}} + ui{*new Ui_Document}, + toolsBar{new QToolBar{this}}, + objectEditor{new ObjectEditor{this}} { this->ui.setupUi(this); const int listWidth = static_cast<int>(this->width() / 3); @@ -50,16 +46,16 @@ this->ui.toolsBarContainer->layout()->addWidget(this->toolsBar); this->ui.listView->setModel(model); this->ui.viewportFrame->setLayout(new QVBoxLayout{this->ui.listView}); - this->ui.viewportFrame->layout()->addWidget(this->renderer); + this->ui.viewportFrame->layout()->addWidget(this->canvas); this->toolsBar->setOrientation(Qt::Vertical); this->setMouseTracking(true); connect(this->ui.viewportListSplitter, &QSplitter::splitterMoved, this, &Document::splitterChanged); - connect(this->renderer, &Canvas::newStatusText, this, &Document::newStatusText); - connect(this->renderer, &Canvas::selectionChanged, [&](const QSet<ldraw::id_t>& newSelection) + connect(this->canvas, &Canvas::newStatusText, this, &Document::newStatusText); + connect(this->canvas, &Canvas::selectionChanged, [&](const QSet<ldraw::id_t>& newSelection) { QItemSelectionModel* selectionModel = this->ui.listView->selectionModel(); QItemSelection selection; - for (ldraw::id_t id : newSelection) + for (const ldraw::id_t id : newSelection) { QModelIndex index = this->model->find(id); if (index != QModelIndex{}) @@ -69,7 +65,6 @@ } QSignalBlocker blocker{this}; selectionModel->select(selection, QItemSelectionModel::ClearAndSelect); - this->selectionChanged(newSelection); }); connect(this->ui.listView->selectionModel(), &QItemSelectionModel::selectionChanged, [&](const QItemSelection& selected, const QItemSelection& deselected) @@ -79,34 +74,12 @@ { return fn::map<QSet<ldraw::id_t>>(selection.indexes(), resolveIndex); }; - this->renderer->handleSelectionChange(resolve(selected), resolve(deselected)); - this->selectionChanged(resolve(this->ui.listView->selectionModel()->selection())); + this->canvas->handleSelectionChange(resolve(selected), resolve(deselected)); }); - connect(this->model, &Model::dataChanged, this->renderer, qOverload<>(&Canvas::update)); - connect(this->renderer, &Canvas::mouseClick, this, [this](Canvas* canvas, QMouseEvent* event) - { - if (this->selectedTool != nullptr) - { - this->selectedTool->mouseClick(canvas, event); - } - }); - connect(this->renderer, &Canvas::mouseMove, this, [this](Canvas* canvas, QMouseEvent* event) - { - if (this->selectedTool != nullptr) - { - this->selectedTool->mouseMove(this, canvas, event); - } - }); + connect(this->model, &Model::dataChanged, this->canvas, qOverload<>(&Canvas::update)); connect(&this->vertexMap, &VertexMap::verticesChanged, [&]() { - this->renderer->rebuildVertices(this); - }); - this->setCanvasOverpaintCallback([&](Canvas* canvas, QPainter* painter) - { - if (this->selectedTool != nullptr) - { - this->selectedTool->overpaint(canvas, painter); - } + this->canvas->rebuildVertices(this); }); this->initializeTools(); } @@ -126,16 +99,6 @@ this->ui.viewportListSplitter->restoreState(state); } -void Document::setRenderPreferences(const gl::RenderPreferences& newPreferences) -{ - this->renderer->setRenderPreferences(newPreferences); -} - -void Document::setCanvasOverpaintCallback(Canvas::OverpaintCallback fn) -{ - this->renderer->setOverpaintCallback(fn); -} - std::unique_ptr<ModelEditor> Document::editModel() { std::unique_ptr<ModelEditor> editorPointer = std::make_unique<ModelEditor>(*this->model); @@ -150,102 +113,62 @@ this->vertexMap.apply(fn); } -void Document::selectionChanged(const QSet<ldraw::id_t>& newSelection) -{ - for (BaseTool* tool : this->tools) - { - tool->selectionChanged(newSelection); - } -} +const char INDEX_PROPERTY[] = "_editing_mode_index"; void Document::initializeTools() { - this->tools.clear(); - this->tools.reserve(3); - this->tools.push_back(new SelectTool{this}); - this->tools.push_back(new DrawTool{this}); - this->tools.push_back(new CircleTool{this}); - this->tools.push_back(new PathTool{this}); - this->tools.push_back(new TransformTool{this}); - for (BaseTool* toolInstance : this->tools) + const struct { - QAction* action = new QAction{toolInstance->name(), this}; + QString name, tooltip; + QPixmap icon; + QWidget* widget; + } editingModesInfo[] = { + { + .name = tr("Select"), + .tooltip = tr("Select elements from the model."), + .icon = {":/icons/navigate-outline.png"}, + .widget = this->objectEditor, + }, + { + .name = tr("Draw"), + .tooltip = tr("Draw new elements into the model."), + .icon = {":/icons/pencil-outline.png"}, + .widget = nullptr, + }, + }; + for (int i = 0; i < countof(editingModesInfo); ++i) { + const auto& editingModeInfo = editingModesInfo[i]; + QAction* action = new QAction{editingModeInfo.name, this}; action->setCheckable(true); - this->toolActions[toolInstance] = action; - action->setToolTip(toolInstance->toolTip()); - action->setIcon(QPixmap{toolInstance->iconName()}); - connect(action, &QAction::triggered, this, &Document::toolActionTriggered); + action->setChecked(i == 0); + action->setToolTip(editingModeInfo.tooltip); + action->setIcon(QPixmap{editingModeInfo.icon}); + action->setProperty(INDEX_PROPERTY, i); this->toolsBar->addAction(action); - QWidget* const widget = toolInstance->toolWidget(); - if (widget) - { - this->ui.toolWidgetStack->addWidget(widget); + QWidget* widget = editingModeInfo.widget; + if (widget == nullptr) { + widget = new QWidget{this}; } - else - { - this->ui.toolWidgetStack->addWidget(new QWidget{this}); - } - connect(toolInstance, &BaseTool::desiredGridChange, this->renderer, &Canvas::setGridMatrix); - } - this->selectTool(this->tools[0]); -} - -void Document::toolActionTriggered() -{ - QAction* action = qobject_cast<QAction*>(sender()); - if (action != nullptr) - { - BaseTool* tool = nullptr; - for (auto&& pair : items(this->toolActions)) - { - if (pair.value == action) - { - tool = pair.key; - } - } - this->selectTool(tool); + this->ui.toolWidgetStack->addWidget(widget); + this->toolActions.push_back(action); + connect(action, &QAction::triggered, this, &Document::editingModeTriggered); } } -void Document::selectTool(BaseTool* tool) +void Document::editingModeTriggered() { - if (tool != nullptr && tool != this->selectedTool) + QAction* triggeredAction = qobject_cast<QAction*>(this->sender()); + if (triggeredAction != nullptr) { - if (this->selectedTool != nullptr) - { - this->selectedTool->reset(); - } - this->selectedTool = tool; - for (auto&& pair : items(this->toolActions)) - { - pair.value->setChecked(pair.key == tool); - } - const int index = this->tools.indexOf(tool); - if (index != -1) - { - this->ui.toolWidgetStack->setCurrentIndex(index); + const int index = triggeredAction->property(INDEX_PROPERTY).toInt(); + this->canvas->mode = static_cast<EditingMode>(index); + this->ui.toolWidgetStack->setCurrentIndex(index); + for (QAction* action : this->toolActions) { + action->setChecked(action == triggeredAction); } } } -void Document::handleKeyPress(QKeyEvent* event) -{ - if (this->selectedTool != nullptr) - { - this->selectedTool->keyReleased(this, this->renderer, event); - } -} - -void Document::adjustGridToView() -{ - this->renderer->adjustGridToView(); -} - -const glm::mat4 &Document::currentGrid() const -{ - return this->renderer->getGridMatrix(); -} - const Model &Document::getModel() const { return *this->model; @@ -253,5 +176,5 @@ const QSet<ldraw::id_t> Document::selectedObjects() const { - return this->renderer->selectedObjects(); + return this->canvas->selectedObjects(); }