src/document.cpp

changeset 203
1909a0123c72
parent 201
5d201ee4a9c3
child 204
52e10e8d88cc
equal deleted inserted replaced
202:b05af0bab735 203:1909a0123c72
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19 #include <QMouseEvent> 19 #include <QMouseEvent>
20 #include <QMessageBox> 20 #include <QMessageBox>
21 #include <QVBoxLayout>
21 #include "document.h" 22 #include "document.h"
22 #include "ui_document.h"
23 #include "model.h" 23 #include "model.h"
24 #include "ui/objecteditor.h" 24 #include "ui/objecteditor.h"
25 25
26 EditorTabWidget::EditorTabWidget( 26 EditorTabWidget::EditorTabWidget(
27 Model* model, 27 Model* model,
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;
182 const ModelId highlighted = this->canvas->getHighlightedObject(); 98 const ModelId highlighted = this->canvas->getHighlightedObject();
183 QSet<ModelId> selected; 99 QSet<ModelId> selected;
184 if (highlighted != ModelId{0}) { 100 if (highlighted != ModelId{0}) {
185 selected.insert(highlighted); 101 selected.insert(highlighted);
186 } 102 }
187 this->select(selected); 103 //this->select(selected);
188 event->accept(); 104 event->accept();
189 } 105 }
190 break; 106 break;
191 case DrawMode: 107 case DrawMode:
192 if (event->button() == Qt::LeftButton and this->canvas->worldPosition.has_value()) 108 if (event->button() == Qt::LeftButton and this->canvas->worldPosition.has_value())
230 } 146 }
231 event->accept(); 147 event->accept();
232 break; 148 break;
233 } 149 }
234 } 150 }
151 /*
235 152
236 void EditorTabWidget::select(const QSet<ModelId> &selected) 153 void EditorTabWidget::select(const QSet<ModelId> &selected)
237 { 154 {
238 QItemSelectionModel* selectionModel = this->ui.listView->selectionModel(); 155 QItemSelectionModel* selectionModel = this->ui.listView->selectionModel();
239 QItemSelection itemSelection; 156 QItemSelection itemSelection;
246 itemSelection.select(qindex, qindex); 163 itemSelection.select(qindex, qindex);
247 } 164 }
248 } 165 }
249 selectionModel->select(itemSelection, QItemSelectionModel::ClearAndSelect); 166 selectionModel->select(itemSelection, QItemSelectionModel::ClearAndSelect);
250 } 167 }
251 168 */
252 const QSet<ModelId> EditorTabWidget::selectedObjects() const 169 const QSet<ModelId> EditorTabWidget::selectedObjects() const
253 { 170 {
254 return this->canvas->selectedObjects(); 171 return this->canvas->selectedObjects();
172 }
173
174 EditingMode EditorTabWidget::currentEditingMode() const
175 {
176 return this->drawState.mode;
255 } 177 }
256 178
257 void EditorTabWidget::closeShape() 179 void EditorTabWidget::closeShape()
258 { 180 {
259 if (this->drawState.polygon.size() >= 2 and this->drawState.polygon.size() <= 4) 181 if (this->drawState.polygon.size() >= 2 and this->drawState.polygon.size() <= 4)

mercurial