| 31 QWidget{parent}, |
31 QWidget{parent}, |
| 32 colorTable{colorTable}, |
32 colorTable{colorTable}, |
| 33 canvas{new Canvas{model, this, documents, colorTable, this}}, |
33 canvas{new Canvas{model, this, documents, colorTable, this}}, |
| 34 model{model}, |
34 model{model}, |
| 35 documents{documents}, |
35 documents{documents}, |
| 36 vertexMap{model}, |
36 vertexMap{model} |
| 37 ui{*new Ui_Document}, |
37 { |
| 38 toolsBar{new QToolBar{this}} |
|
| 39 { |
|
| 40 this->ui.setupUi(this); |
|
| 41 const int listWidth = static_cast<int>(this->width() / 3); |
|
| 42 this->ui.viewportListSplitter->setSizes({listWidth * 2, listWidth}); |
|
| 43 this->ui.toolsBarContainer->setLayout(new QVBoxLayout{this->ui.toolsBarContainer}); |
|
| 44 this->ui.toolsBarContainer->layout()->addWidget(this->toolsBar); |
|
| 45 this->ui.listView->setModel(model); |
|
| 46 this->ui.viewportFrame->setLayout(new QVBoxLayout{this->ui.listView}); |
|
| 47 this->ui.viewportFrame->layout()->addWidget(this->canvas); |
|
| 48 this->toolsBar->setOrientation(Qt::Vertical); |
|
| 49 this->setMouseTracking(true); |
38 this->setMouseTracking(true); |
| 50 connect(this->ui.viewportListSplitter, &QSplitter::splitterMoved, this, &EditorTabWidget::splitterChanged); |
|
| 51 connect(this->canvas, &Canvas::mouseClick, this, &EditorTabWidget::canvasMouseClick); |
39 connect(this->canvas, &Canvas::mouseClick, this, &EditorTabWidget::canvasMouseClick); |
| 52 connect(this->canvas, &Canvas::mouseMove, this, &EditorTabWidget::canvasMouseMove); |
40 connect(this->canvas, &Canvas::mouseMove, this, &EditorTabWidget::canvasMouseMove); |
| 53 connect(this->canvas, &Canvas::newStatusText, this, &EditorTabWidget::newStatusText); |
41 connect(this->canvas, &Canvas::newStatusText, this, &EditorTabWidget::newStatusText); |
| 54 connect(this->ui.listView->selectionModel(), &QItemSelectionModel::selectionChanged, |
|
| 55 [&](const QItemSelection& selected, const QItemSelection& deselected) |
|
| 56 { |
|
| 57 auto resolveIndex = [this](const QModelIndex& index){ return this->model->idAt(index.row()); }; |
|
| 58 auto resolve = [resolveIndex](const QItemSelection& selection) |
|
| 59 { |
|
| 60 return fn::map<QSet<ModelId>>(selection.indexes(), resolveIndex); |
|
| 61 }; |
|
| 62 this->canvas->handleSelectionChange(resolve(selected), resolve(deselected)); |
|
| 63 }); |
|
| 64 connect(this->model, &Model::dataChanged, this->canvas, qOverload<>(&Canvas::update)); |
42 connect(this->model, &Model::dataChanged, this->canvas, qOverload<>(&Canvas::update)); |
| 65 connect(&this->vertexMap, &VertexMap::verticesChanged, [&]() |
43 connect(&this->vertexMap, &VertexMap::verticesChanged, [&]() |
| 66 { |
44 { |
| 67 this->canvas->rebuildVertices(this); |
45 this->canvas->rebuildVertices(this); |
| 68 }); |
46 }); |
| 69 this->canvas->drawState = &this->drawState; |
47 this->canvas->drawState = &this->drawState; |
| 70 this->initializeTools(); |
48 QVBoxLayout* layout = new QVBoxLayout{this}; |
| |
49 layout->addWidget(this->canvas); |
| 71 } |
50 } |
| 72 |
51 |
| 73 EditorTabWidget::~EditorTabWidget() |
52 EditorTabWidget::~EditorTabWidget() |
| 74 { |
53 { |
| 75 delete &this->ui; |
|
| 76 } |
|
| 77 |
|
| 78 QByteArray EditorTabWidget::saveSplitterState() const |
|
| 79 { |
|
| 80 return this->ui.viewportListSplitter->saveState(); |
|
| 81 } |
|
| 82 |
|
| 83 void EditorTabWidget::restoreSplitterState(const QByteArray& state) |
|
| 84 { |
|
| 85 this->ui.viewportListSplitter->restoreState(state); |
|
| 86 } |
54 } |
| 87 |
55 |
| 88 void EditorTabWidget::applyToVertices(VertexMap::ApplyFunction fn) const |
56 void EditorTabWidget::applyToVertices(VertexMap::ApplyFunction fn) const |
| 89 { |
57 { |
| 90 this->vertexMap.apply(fn); |
58 this->vertexMap.apply(fn); |
| 91 } |
59 } |
| 92 |
60 |
| 93 const char INDEX_PROPERTY[] = "_editing_mode_index"; |
61 void EditorTabWidget::setEditMode(EditingMode mode) |
| 94 |
62 { |
| 95 void EditorTabWidget::initializeTools() |
63 this->drawState.mode = mode; |
| 96 { |
|
| 97 const struct |
|
| 98 { |
|
| 99 QString name, tooltip; |
|
| 100 QPixmap icon; |
|
| 101 QWidget* widget; |
|
| 102 } editingModesInfo[] = { |
|
| 103 { |
|
| 104 .name = tr("Select"), |
|
| 105 .tooltip = tr("Select elements from the model."), |
|
| 106 .icon = {":/icons/navigate-outline.png"}, |
|
| 107 //.widget = this->objectEditor, |
|
| 108 }, |
|
| 109 { |
|
| 110 .name = tr("Draw"), |
|
| 111 .tooltip = tr("Draw new elements into the model."), |
|
| 112 .icon = {":/icons/pencil-outline.png"}, |
|
| 113 .widget = nullptr, |
|
| 114 }, |
|
| 115 }; |
|
| 116 for (int i = 0; i < countof(editingModesInfo); ++i) { |
|
| 117 const auto& editingModeInfo = editingModesInfo[i]; |
|
| 118 QAction* action = new QAction{editingModeInfo.name, this}; |
|
| 119 action->setCheckable(true); |
|
| 120 action->setChecked(i == 0); |
|
| 121 action->setToolTip(editingModeInfo.tooltip); |
|
| 122 action->setIcon(QPixmap{editingModeInfo.icon}); |
|
| 123 action->setProperty(INDEX_PROPERTY, i); |
|
| 124 this->toolsBar->addAction(action); |
|
| 125 QWidget* widget = editingModeInfo.widget; |
|
| 126 if (widget == nullptr) { |
|
| 127 widget = new QWidget{this}; |
|
| 128 } |
|
| 129 this->ui.toolWidgetStack->addWidget(widget); |
|
| 130 this->toolActions.push_back(action); |
|
| 131 connect(action, &QAction::triggered, this, &EditorTabWidget::editingModeTriggered); |
|
| 132 } |
|
| 133 this->ui.listView->selectAll(); |
|
| 134 } |
|
| 135 |
|
| 136 void EditorTabWidget::editingModeTriggered() |
|
| 137 { |
|
| 138 QAction* triggeredAction = qobject_cast<QAction*>(this->sender()); |
|
| 139 if (triggeredAction != nullptr) |
|
| 140 { |
|
| 141 const int index = triggeredAction->property(INDEX_PROPERTY).toInt(); |
|
| 142 this->drawState.mode = static_cast<EditingMode>(index); |
|
| 143 this->ui.toolWidgetStack->setCurrentIndex(index); |
|
| 144 for (QAction* action : this->toolActions) { |
|
| 145 action->setChecked(action == triggeredAction); |
|
| 146 } |
|
| 147 } |
|
| 148 } |
64 } |
| 149 |
65 |
| 150 void updatePreviewPolygon(DrawState* drawState) |
66 void updatePreviewPolygon(DrawState* drawState) |
| 151 { |
67 { |
| 152 drawState->previewPolygon = drawState->polygon; |
68 drawState->previewPolygon = drawState->polygon; |