# HG changeset patch # User Teemu Piippo # Date 1654626929 -10800 # Node ID 1909a0123c72da07ecbcba2096f6887cca712f3e # Parent b05af0bab735909849419c77e2c315ad96308dd3 Move editing modes tool bar, tool options widget stack and model list view into the main window diff -r b05af0bab735 -r 1909a0123c72 src/document.cpp --- a/src/document.cpp Tue Jun 07 20:44:19 2022 +0300 +++ b/src/document.cpp Tue Jun 07 21:35:29 2022 +0300 @@ -18,8 +18,8 @@ #include #include +#include #include "document.h" -#include "ui_document.h" #include "model.h" #include "ui/objecteditor.h" @@ -33,56 +33,24 @@ canvas{new Canvas{model, this, documents, colorTable, this}}, model{model}, documents{documents}, - vertexMap{model}, - ui{*new Ui_Document}, - toolsBar{new QToolBar{this}} + vertexMap{model} { - this->ui.setupUi(this); - const int listWidth = static_cast(this->width() / 3); - this->ui.viewportListSplitter->setSizes({listWidth * 2, listWidth}); - this->ui.toolsBarContainer->setLayout(new QVBoxLayout{this->ui.toolsBarContainer}); - 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->canvas); - this->toolsBar->setOrientation(Qt::Vertical); this->setMouseTracking(true); - connect(this->ui.viewportListSplitter, &QSplitter::splitterMoved, this, &EditorTabWidget::splitterChanged); connect(this->canvas, &Canvas::mouseClick, this, &EditorTabWidget::canvasMouseClick); connect(this->canvas, &Canvas::mouseMove, this, &EditorTabWidget::canvasMouseMove); connect(this->canvas, &Canvas::newStatusText, this, &EditorTabWidget::newStatusText); - connect(this->ui.listView->selectionModel(), &QItemSelectionModel::selectionChanged, - [&](const QItemSelection& selected, const QItemSelection& deselected) - { - auto resolveIndex = [this](const QModelIndex& index){ return this->model->idAt(index.row()); }; - auto resolve = [resolveIndex](const QItemSelection& selection) - { - return fn::map>(selection.indexes(), resolveIndex); - }; - this->canvas->handleSelectionChange(resolve(selected), resolve(deselected)); - }); connect(this->model, &Model::dataChanged, this->canvas, qOverload<>(&Canvas::update)); connect(&this->vertexMap, &VertexMap::verticesChanged, [&]() { this->canvas->rebuildVertices(this); }); this->canvas->drawState = &this->drawState; - this->initializeTools(); + QVBoxLayout* layout = new QVBoxLayout{this}; + layout->addWidget(this->canvas); } EditorTabWidget::~EditorTabWidget() { - delete &this->ui; -} - -QByteArray EditorTabWidget::saveSplitterState() const -{ - return this->ui.viewportListSplitter->saveState(); -} - -void EditorTabWidget::restoreSplitterState(const QByteArray& state) -{ - this->ui.viewportListSplitter->restoreState(state); } void EditorTabWidget::applyToVertices(VertexMap::ApplyFunction fn) const @@ -90,61 +58,9 @@ this->vertexMap.apply(fn); } -const char INDEX_PROPERTY[] = "_editing_mode_index"; - -void EditorTabWidget::initializeTools() +void EditorTabWidget::setEditMode(EditingMode mode) { - const struct - { - 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); - action->setChecked(i == 0); - action->setToolTip(editingModeInfo.tooltip); - action->setIcon(QPixmap{editingModeInfo.icon}); - action->setProperty(INDEX_PROPERTY, i); - this->toolsBar->addAction(action); - QWidget* widget = editingModeInfo.widget; - if (widget == nullptr) { - widget = new QWidget{this}; - } - this->ui.toolWidgetStack->addWidget(widget); - this->toolActions.push_back(action); - connect(action, &QAction::triggered, this, &EditorTabWidget::editingModeTriggered); - } - this->ui.listView->selectAll(); -} - -void EditorTabWidget::editingModeTriggered() -{ - QAction* triggeredAction = qobject_cast(this->sender()); - if (triggeredAction != nullptr) - { - const int index = triggeredAction->property(INDEX_PROPERTY).toInt(); - this->drawState.mode = static_cast(index); - this->ui.toolWidgetStack->setCurrentIndex(index); - for (QAction* action : this->toolActions) { - action->setChecked(action == triggeredAction); - } - } + this->drawState.mode = mode; } void updatePreviewPolygon(DrawState* drawState) @@ -184,7 +100,7 @@ if (highlighted != ModelId{0}) { selected.insert(highlighted); } - this->select(selected); + //this->select(selected); event->accept(); } break; @@ -232,6 +148,7 @@ break; } } +/* void EditorTabWidget::select(const QSet &selected) { @@ -248,12 +165,17 @@ } selectionModel->select(itemSelection, QItemSelectionModel::ClearAndSelect); } - +*/ const QSet EditorTabWidget::selectedObjects() const { return this->canvas->selectedObjects(); } +EditingMode EditorTabWidget::currentEditingMode() const +{ + return this->drawState.mode; +} + void EditorTabWidget::closeShape() { if (this->drawState.polygon.size() >= 2 and this->drawState.polygon.size() <= 4) diff -r b05af0bab735 -r 1909a0123c72 src/document.h --- a/src/document.h Tue Jun 07 20:44:19 2022 +0300 +++ b/src/document.h Tue Jun 07 21:35:29 2022 +0300 @@ -34,27 +34,21 @@ const ldraw::ColorTable& colorTable, QWidget *parent = nullptr); ~EditorTabWidget() override; - QByteArray saveSplitterState() const; - void restoreSplitterState(const QByteArray& state); void applyToVertices(VertexMap::ApplyFunction fn) const; const QSet selectedObjects() const; const ldraw::ColorTable& colorTable; Canvas* const canvas; Model* const model; - Q_SLOT void editingModeTriggered(); + EditingMode currentEditingMode() const; + Q_SLOT void setEditMode(EditingMode mode); Q_SLOT void canvasMouseClick(QMouseEvent* event); Q_SLOT void canvasMouseMove(QMouseEvent* event); - void select(const QSet &selected); Q_SIGNALS: void newStatusText(const QString& newStatusText); void splitterChanged(); private: - void initializeTools(); void closeShape(); DrawState drawState; DocumentManager* const documents; VertexMap vertexMap; - class Ui_Document& ui; - QToolBar* toolsBar; - std::vector toolActions; }; diff -r b05af0bab735 -r 1909a0123c72 src/document.ui --- a/src/document.ui Tue Jun 07 20:44:19 2022 +0300 +++ b/src/document.ui Tue Jun 07 21:35:29 2022 +0300 @@ -13,65 +13,30 @@ Form - - - - + - + - Qt::Vertical + Qt::Horizontal - - - Qt::Horizontal + + + QFrame::StyledPanel - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - true - - - QAbstractItemView::ExtendedSelection - - - QAbstractItemView::SelectRows - - + + QFrame::Raised + - - + + true - - - - 0 - 0 - 921 - 73 - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows + diff -r b05af0bab735 -r 1909a0123c72 src/main.cpp --- a/src/main.cpp Tue Jun 07 20:44:19 2022 +0300 +++ b/src/main.cpp Tue Jun 07 21:35:29 2022 +0300 @@ -2,6 +2,7 @@ #include #include #include +#include #include "mainwindow.h" #include "ui_mainwindow.h" #include "version.h" @@ -146,18 +147,6 @@ } } -static void handleTabCloseButton(Ui_MainWindow* ui, DocumentManager* documents, int tabIndex) -{ - /* - if (tabIndex >= 0 and tabIndex < ui->tabs->count()) { - EditorTabWidget* tab = qobject_cast(ui->tabs->widget(tabIndex)); - if (tab != nullptr) { - closeDocument(documents, tab); - } - } - */ -} - static std::optional findCurrentModelId(Ui_MainWindow* ui, DocumentManager* documents) { const EditorTabWidget* tab = currentTabWidget(ui); @@ -236,6 +225,44 @@ }; } +void initializeTools(Ui_MainWindow* ui, QWidget* parent) +{ + const struct + { + QString name, tooltip; + QPixmap icon; + QWidget* widget; + } editingModesInfo[] = { + { + .name = QObject::tr("Select"), + .tooltip = QObject::tr("Select elements from the model."), + .icon = {":/icons/navigate-outline.png"}, + //.widget = this->objectEditor, + }, + { + .name = QObject::tr("Draw"), + .tooltip = QObject::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, parent}; + action->setCheckable(true); + action->setChecked(i == 0); + action->setData(static_cast(i)); + action->setToolTip(editingModeInfo.tooltip); + action->setIcon(QPixmap{editingModeInfo.icon}); + ui->editingModesToolBar->addAction(action); + QWidget* widget = editingModeInfo.widget; + if (widget == nullptr) { + widget = new QWidget{parent}; + } + ui->toolWidgetStack->addWidget(widget); + } +} + int main(int argc, char *argv[]) { doQtRegistrations(); @@ -251,6 +278,7 @@ QStringList recentlyOpenedFiles; ldraw::ColorTable colorTable; gl::RenderPreferences renderPreferences; + QMap itemSelectionModels; ui.setupUi(&mainWindow); const uiutilities::KeySequenceMap defaultKeyboardShortcuts = uiutilities::makeKeySequenceMap(uiutilities::collectActions(&mainWindow)); @@ -299,11 +327,22 @@ updateRecentlyOpenedDocumentsMenu(); }; const auto openModelForEditing = [&](const ModelId modelId){ - EditorTabWidget* document = new EditorTabWidget{ - documents.getModelById(modelId), - &documents, - colorTable, - }; + Model* model = documents.getModelById(modelId); + EditorTabWidget* document = new EditorTabWidget{model, &documents, colorTable}; + 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) + { + return fn::map>(selection.indexes(), resolveIndex); + }; + document->canvas->handleSelectionChange(resolve(selected), resolve(deselected)); + }); document->canvas->setRenderPreferences(renderPreferences); QObject::connect( document, @@ -315,7 +354,6 @@ QMdiSubWindow* subWindow = ui.mdiArea->addSubWindow(document); subWindow->setWindowTitle(tabName(fileInfo)); subWindow->show(); - document->restoreSplitterState(documentSplitterState); }; QObject::connect(ui.actionNew, &QAction::triggered, [&]{ openModelForEditing(documents.newModel()); @@ -409,11 +447,6 @@ } } }); - /* - QObject::connect(ui.mdiArea, &QTabWidget::tabCloseRequested, [&](int index){ - handleTabCloseButton(&ui, &documents, index); - }); - */ QObject::connect(ui.actionDrawAxes, &QAction::triggered, [&](bool drawAxes){ renderPreferences.drawAxes = drawAxes; saveSettings(); @@ -427,6 +460,34 @@ updateRenderPreferences(&ui, &renderPreferences); }); } + const auto checkEditingModeAction = [&ui](EditingMode mode) { + for (QAction* action : ui.editingModesToolBar->actions()) { + action->setChecked(action->data().value() == mode); + } + }; + initializeTools(&ui, &mainWindow); + for (QAction* action : ui.editingModesToolBar->actions()) { + QObject::connect(action, &QAction::triggered, [&, action]{ + EditorTabWidget* tab = currentTabWidget(&ui); + if (tab != nullptr) { + const EditingMode mode = action->data().value(); + tab->setEditMode(mode); + checkEditingModeAction(mode); + } + }); + } + QObject::connect(ui.mdiArea, &QMdiArea::subWindowActivated, + [&](QMdiSubWindow* subWindow){ + EditorTabWidget* tab = qobject_cast(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); + } + } + }); mainWindow.setWindowTitle(title()); mainWindow.restoreGeometry(settings.mainWindowGeometry()); restoreSettings(); diff -r b05af0bab735 -r 1909a0123c72 src/mainwindow.ui --- a/src/mainwindow.ui Tue Jun 07 20:44:19 2022 +0300 +++ b/src/mainwindow.ui Tue Jun 07 21:35:29 2022 +0300 @@ -14,7 +14,7 @@ LDForge - + @@ -136,6 +136,47 @@ + + + toolBar_2 + + + LeftToolBarArea + + + false + + + + + Tool options + + + 8 + + + + + + + + + + + + Model body + + + 2 + + + + + + + + + diff -r b05af0bab735 -r 1909a0123c72 src/ui/canvas.h --- a/src/ui/canvas.h Tue Jun 07 20:44:19 2022 +0300 +++ b/src/ui/canvas.h Tue Jun 07 21:35:29 2022 +0300 @@ -13,6 +13,8 @@ DrawMode }; +Q_DECLARE_METATYPE(EditingMode); + struct DrawState { std::vector polygon;