src/gui.cpp

changeset 493
16766ac1bbd9
parent 492
e964085e6913
child 497
c51941e590b6
equal deleted inserted replaced
492:e964085e6913 493:16766ac1bbd9
46 #include "widgets.h" 46 #include "widgets.h"
47 #include "addObjectDialog.h" 47 #include "addObjectDialog.h"
48 #include "messagelog.h" 48 #include "messagelog.h"
49 #include "config.h" 49 #include "config.h"
50 #include "ui_ldforge.h" 50 #include "ui_ldforge.h"
51 #include "moc_gui.cpp"
51 52
52 static bool g_bSelectionLocked = false; 53 static bool g_bSelectionLocked = false;
53 54
54 cfg (Bool, lv_colorize, true); 55 cfg (Bool, lv_colorize, true);
55 cfg (String, gui_colortoolbar, "16:24:|:1:2:4:14:0:15:|:33:34:36:46"); 56 cfg (String, gui_colortoolbar, "16:24:|:1:2:4:14:0:15:|:33:34:36:46");
64 #define act(N) extern_cfg (KeySequence, key_##N); 65 #define act(N) extern_cfg (KeySequence, key_##N);
65 #include "actions.h" 66 #include "actions.h"
66 67
67 // ============================================================================= 68 // =============================================================================
68 // ----------------------------------------------------------------------------- 69 // -----------------------------------------------------------------------------
69 ForgeWindow::ForgeWindow() { 70 ForgeWindow::ForgeWindow()
70 g_win = this; 71 { g_win = this;
71 m_renderer = new GLRenderer; 72 m_renderer = new GLRenderer;
72 73
73 ui = new Ui_LDForgeUI; 74 ui = new Ui_LDForgeUI;
74 ui->setupUi (this); 75 ui->setupUi (this);
75 76
76 // Stuff the renderer into its frame 77 // Stuff the renderer into its frame
77 QVBoxLayout* rendererLayout = new QVBoxLayout (ui->rendererFrame); 78 QVBoxLayout* rendererLayout = new QVBoxLayout (ui->rendererFrame);
78 rendererLayout->addWidget (R()); 79 rendererLayout->addWidget (R());
79 80
80 connect (ui->objectList, SIGNAL (itemSelectionChanged()), this, SLOT (slot_selectionChanged())); 81 connect (ui->objectList, SIGNAL (itemSelectionChanged()), this, SLOT (slot_selectionChanged()));
81 connect (ui->objectList, SIGNAL (itemDoubleClicked (QListWidgetItem*)), this, SLOT (slot_editObject (QListWidgetItem*))); 82 connect (ui->objectList, SIGNAL (itemDoubleClicked (QListWidgetItem*)), this, SLOT (slot_editObject (QListWidgetItem*)));
82 connect (ui->fileList, SIGNAL (currentItemChanged (QListWidgetItem*, QListWidgetItem*)), this, SLOT (changeCurrentFile())); 83 connect (ui->fileList, SIGNAL (currentItemChanged (QListWidgetItem*, QListWidgetItem*)), this, SLOT (changeCurrentFile()));
83 84
84 // Init message log manager 85 // Init message log manager
85 m_msglog = new MessageManager; 86 m_msglog = new MessageManager;
86 m_msglog->setRenderer (R()); 87 m_msglog->setRenderer (R());
87 m_renderer->setMessageLog (m_msglog); 88 m_renderer->setMessageLog (m_msglog);
88 m_quickColors = quickColorsFromConfig(); 89 m_quickColors = quickColorsFromConfig();
89 slot_selectionChanged(); 90 slot_selectionChanged();
90 setStatusBar (new QStatusBar); 91 setStatusBar (new QStatusBar);
91 92
92 // Init primitive loader task stuff 93 // Init primitive loader task stuff
93 m_primLoaderBar = new QProgressBar; 94 m_primLoaderBar = new QProgressBar;
94 m_primLoaderWidget = new QWidget; 95 m_primLoaderWidget = new QWidget;
95 QHBoxLayout* primLoaderLayout = new QHBoxLayout (m_primLoaderWidget); 96 QHBoxLayout* primLoaderLayout = new QHBoxLayout (m_primLoaderWidget);
96 primLoaderLayout->addWidget (new QLabel ("Loading primitives:")); 97 primLoaderLayout->addWidget (new QLabel ("Loading primitives:"));
97 primLoaderLayout->addWidget (m_primLoaderBar); 98 primLoaderLayout->addWidget (m_primLoaderBar);
98 statusBar()->addPermanentWidget (m_primLoaderWidget); 99 statusBar()->addPermanentWidget (m_primLoaderWidget);
99 m_primLoaderWidget->hide(); 100 m_primLoaderWidget->hide();
100 101
101 // Make certain actions checkable 102 // Make certain actions checkable
102 ui->actionAxes->setChecked (gl_axes); 103 ui->actionAxes->setChecked (gl_axes);
103 ui->actionWireframe->setChecked (gl_wireframe); 104 ui->actionWireframe->setChecked (gl_wireframe);
104 ui->actionBFCView->setChecked (gl_colorbfc); 105 ui->actionBFCView->setChecked (gl_colorbfc);
105 updateGridToolBar(); 106 updateGridToolBar();
106 updateEditModeActions(); 107 updateEditModeActions();
107 updateRecentFilesMenu(); 108 updateRecentFilesMenu();
108 updateToolBars(); 109 updateToolBars();
109 updateTitle(); 110 updateTitle();
110 111
111 setMinimumSize (300, 200); 112 setMinimumSize (300, 200);
112 113
113 connect (qApp, SIGNAL (aboutToQuit()), this, SLOT (slot_lastSecondCleanup())); 114 connect (qApp, SIGNAL (aboutToQuit()), this, SLOT (slot_lastSecondCleanup()));
114 115
115 // Connect all actions and set shortcuts 116 // Connect all actions and set shortcuts
116 #define act(N) \ 117 #define act(N) \
117 connect (ui->action##N, SIGNAL (triggered()), this, SLOT (slot_action())); \ 118 connect (ui->action##N, SIGNAL (triggered()), this, SLOT (slot_action())); \
118 ui->action##N->setShortcut (key_##N); 119 ui->action##N->setShortcut (key_##N);
119 #include "actions.h" 120 #include "actions.h"
120 } 121 }
121 122
122 // ============================================================================= 123 // =============================================================================
123 // ----------------------------------------------------------------------------- 124 // -----------------------------------------------------------------------------
124 void ForgeWindow::slot_action() { 125 void ForgeWindow::slot_action()
125 // Find out which action triggered this 126 { // Find out which action triggered this
126 #define act(N) if (sender() == ui->action##N) invokeAction (ui->action##N, &actiondef_##N); 127 #define act(N) if (sender() == ui->action##N) invokeAction (ui->action##N, &actiondef_##N);
127 #include "actions.h" 128 #include "actions.h"
128 } 129 }
129 130
130 // ============================================================================= 131 // =============================================================================
131 // ----------------------------------------------------------------------------- 132 // -----------------------------------------------------------------------------
132 void ForgeWindow::invokeAction (QAction* act, void (*func)()) { 133 void ForgeWindow::invokeAction (QAction* act, void (*func) ())
133 beginAction (act); 134 { beginAction (act);
134 (*func)(); 135 (*func) ();
135 endAction(); 136 endAction();
136 } 137 }
137 138
138 // ============================================================================= 139 // =============================================================================
139 // ----------------------------------------------------------------------------- 140 // -----------------------------------------------------------------------------
140 void ForgeWindow::slot_lastSecondCleanup() { 141 void ForgeWindow::slot_lastSecondCleanup()
141 delete m_renderer; 142 { delete m_renderer;
142 delete ui; 143 delete ui;
143 } 144 }
144 145
145 // ============================================================================= 146 // =============================================================================
146 // ----------------------------------------------------------------------------- 147 // -----------------------------------------------------------------------------
147 void ForgeWindow::updateRecentFilesMenu() { 148 void ForgeWindow::updateRecentFilesMenu()
148 // First, clear any items in the recent files menu 149 { // First, clear any items in the recent files menu
149 for (QAction* recent : m_recentFiles) 150 for (QAction * recent : m_recentFiles)
150 delete recent; 151 delete recent;
152
151 m_recentFiles.clear(); 153 m_recentFiles.clear();
152 154
153 QAction* first = null; 155 QAction* first = null;
154 156
155 for (const QVariant& it : io_recentfiles) { 157 for (const QVariant & it : io_recentfiles)
156 str file = it.toString(); 158 { str file = it.toString();
157 QAction* recent = new QAction (getIcon ("open-recent"), file, this); 159 QAction* recent = new QAction (getIcon ("open-recent"), file, this);
158 160
159 connect (recent, SIGNAL (triggered()), this, SLOT (slot_recentFile())); 161 connect (recent, SIGNAL (triggered()), this, SLOT (slot_recentFile()));
160 ui->menuOpenRecent->insertAction (first, recent); 162 ui->menuOpenRecent->insertAction (first, recent);
161 m_recentFiles << recent; 163 m_recentFiles << recent;
162 first = recent; 164 first = recent;
163 } 165 }
164 } 166 }
165 167
166 // ============================================================================= 168 // =============================================================================
167 // ----------------------------------------------------------------------------- 169 // -----------------------------------------------------------------------------
168 List<LDQuickColor> quickColorsFromConfig() { 170 List<LDQuickColor> quickColorsFromConfig()
169 List<LDQuickColor> colors; 171 { List<LDQuickColor> colors;
170 172
171 for (str colorname : gui_colortoolbar.value.split (":")) { 173 for (str colorname : gui_colortoolbar.value.split (":"))
172 if (colorname == "|") 174 { if (colorname == "|")
173 colors << LDQuickColor::getSeparator(); 175 colors << LDQuickColor::getSeparator();
174 else { 176 else
175 LDColor* col = getColor (colorname.toLong()); 177 { LDColor* col = getColor (colorname.toLong());
176 178
177 if (col != null) 179 if (col != null)
178 colors << LDQuickColor (col, null); 180 colors << LDQuickColor (col, null);
179 } 181 }
180 } 182 }
181 183
182 return colors; 184 return colors;
183 } 185 }
184 186
185 // ============================================================================= 187 // =============================================================================
186 // ----------------------------------------------------------------------------- 188 // -----------------------------------------------------------------------------
187 void ForgeWindow::updateToolBars() { 189 void ForgeWindow::updateToolBars()
188 m_colorButtons.clear(); 190 { m_colorButtons.clear();
189 ui->colorToolbar->clear(); 191 ui->colorToolbar->clear();
190 192
191 for (LDQuickColor& entry : m_quickColors) { 193 for (LDQuickColor & entry : m_quickColors)
192 if (entry.isSeparator()) 194 { if (entry.isSeparator())
193 ui->colorToolbar->addSeparator(); 195 ui->colorToolbar->addSeparator();
194 else { 196 else
195 QToolButton* colorButton = new QToolButton; 197 { QToolButton* colorButton = new QToolButton;
196 colorButton->setIcon (makeColorIcon (entry.color(), 22)); 198 colorButton->setIcon (makeColorIcon (entry.color(), 22));
197 colorButton->setIconSize (QSize (22, 22)); 199 colorButton->setIconSize (QSize (22, 22));
198 colorButton->setToolTip (entry.color()->name); 200 colorButton->setToolTip (entry.color()->name);
199 201
200 connect (colorButton, SIGNAL (clicked()), this, SLOT (slot_quickColor())); 202 connect (colorButton, SIGNAL (clicked()), this, SLOT (slot_quickColor()));
201 ui->colorToolbar->addWidget (colorButton); 203 ui->colorToolbar->addWidget (colorButton);
202 m_colorButtons << colorButton; 204 m_colorButtons << colorButton;
203 205
204 entry.setToolButton (colorButton); 206 entry.setToolButton (colorButton);
205 } 207 }
206 } 208 }
207 209
208 updateGridToolBar(); 210 updateGridToolBar();
209 } 211 }
210 212
211 // ============================================================================= 213 // =============================================================================
212 // ----------------------------------------------------------------------------- 214 // -----------------------------------------------------------------------------
213 void ForgeWindow::updateGridToolBar() { 215 void ForgeWindow::updateGridToolBar()
214 // Ensure that the current grid - and only the current grid - is selected. 216 { // Ensure that the current grid - and only the current grid - is selected.
215 ui->actionGridCoarse->setChecked (grid == Grid::Coarse); 217 ui->actionGridCoarse->setChecked (grid == Grid::Coarse);
216 ui->actionGridMedium->setChecked (grid == Grid::Medium); 218 ui->actionGridMedium->setChecked (grid == Grid::Medium);
217 ui->actionGridFine->setChecked (grid == Grid::Fine); 219 ui->actionGridFine->setChecked (grid == Grid::Fine);
218 } 220 }
219 221
220 // ============================================================================= 222 // =============================================================================
221 // ----------------------------------------------------------------------------- 223 // -----------------------------------------------------------------------------
222 void ForgeWindow::updateTitle() { 224 void ForgeWindow::updateTitle()
223 str title = fmt (APPNAME " %1", fullVersionString()); 225 { str title = fmt (APPNAME " %1", fullVersionString());
224 226
225 // Append our current file if we have one 227 // Append our current file if we have one
226 if (LDFile::current()) { 228 if (LDFile::current())
227 if (LDFile::current()->name().length() > 0) 229 { if (LDFile::current()->name().length() > 0)
228 title += fmt (": %1", basename (LDFile::current()->name())); 230 title += fmt (": %1", basename (LDFile::current()->name()));
229 else 231 else
230 title += fmt (": <anonymous>"); 232 title += fmt (": <anonymous>");
231 233
232 if (LDFile::current()->numObjs() > 0 && 234 if (LDFile::current()->numObjs() > 0 &&
233 LDFile::current()->obj (0)->getType() == LDObject::Comment) 235 LDFile::current()->obj (0)->getType() == LDObject::Comment)
234 { 236 { // Append title
235 // Append title
236 LDComment* comm = static_cast<LDComment*> (LDFile::current()->obj (0)); 237 LDComment* comm = static_cast<LDComment*> (LDFile::current()->obj (0));
237 title += fmt (": %1", comm->text); 238 title += fmt (": %1", comm->text);
238 } 239 }
239 240
240 if (LDFile::current()->history().pos() != LDFile::current()->savePos()) 241 if (LDFile::current()->history().pos() != LDFile::current()->savePos())
241 title += '*'; 242 title += '*';
242 } 243 }
243 244
244 setWindowTitle (title); 245 setWindowTitle (title);
245 } 246 }
246 247
247 // ============================================================================= 248 // =============================================================================
248 // ----------------------------------------------------------------------------- 249 // -----------------------------------------------------------------------------
249 int ForgeWindow::deleteSelection() { 250 int ForgeWindow::deleteSelection()
250 if (m_sel.size() == 0) 251 { if (m_sel.size() == 0)
251 return 0; 252 return 0;
252 253
253 List<LDObject*> selCopy = m_sel; 254 List<LDObject*> selCopy = m_sel;
254 int num = 0; 255 int num = 0;
255 256
256 // Delete the objects that were being selected 257 // Delete the objects that were being selected
257 for (LDObject* obj : selCopy) { 258 for (LDObject * obj : selCopy)
258 LDFile::current()->forgetObject (obj); 259 { LDFile::current()->forgetObject (obj);
259 ++num; 260 ++num;
260 delete obj; 261 delete obj;
261 } 262 }
262 263
263 refresh(); 264 refresh();
264 return num; 265 return num;
265 } 266 }
266 267
267 // ============================================================================= 268 // =============================================================================
268 // ----------------------------------------------------------------------------- 269 // -----------------------------------------------------------------------------
269 void ForgeWindow::buildObjList() { 270 void ForgeWindow::buildObjList()
270 if (!LDFile::current()) 271 { if (!LDFile::current())
271 return; 272 return;
272 273
273 // Lock the selection while we do this so that refreshing the object list 274 // Lock the selection while we do this so that refreshing the object list
274 // doesn't trigger selection updating so that the selection doesn't get lost 275 // doesn't trigger selection updating so that the selection doesn't get lost
275 // while this is done. 276 // while this is done.
276 g_bSelectionLocked = true; 277 g_bSelectionLocked = true;
277 278
278 for (int i = 0; i < ui->objectList->count(); ++i) 279 for (int i = 0; i < ui->objectList->count(); ++i)
279 delete ui->objectList->item (i); 280 delete ui->objectList->item (i);
280 281
281 ui->objectList->clear(); 282 ui->objectList->clear();
282 283
283 for (LDObject* obj : LDFile::current()->objects()) { 284 for (LDObject * obj : LDFile::current()->objects())
284 str descr; 285 { str descr;
285 286
286 switch (obj->getType()) { 287 switch (obj->getType())
287 case LDObject::Comment: 288 { case LDObject::Comment:
288 descr = static_cast<LDComment*> (obj)->text; 289 descr = static_cast<LDComment*> (obj)->text;
289 290
290 // Remove leading whitespace 291 // Remove leading whitespace
291 while (descr[0] == ' ') 292 while (descr[0] == ' ')
292 descr.remove (0, 1); 293 descr.remove (0, 1);
293 break; 294
294 295 break;
295 case LDObject::Empty: 296
296 break; // leave it empty 297 case LDObject::Empty:
297 298 break; // leave it empty
298 case LDObject::Line: 299
299 case LDObject::Triangle: 300 case LDObject::Line:
300 case LDObject::Quad: 301 case LDObject::Triangle:
301 case LDObject::CndLine: 302 case LDObject::Quad:
302 for (short i = 0; i < obj->vertices(); ++i) { 303 case LDObject::CndLine:
303 if (i != 0) 304
304 descr += ", "; 305 for (short i = 0; i < obj->vertices(); ++i)
305 306 { if (i != 0)
306 descr += obj->getVertex (i).stringRep (true); 307 descr += ", ";
307 } 308
308 break; 309 descr += obj->getVertex (i).stringRep (true);
309 310 }
310 case LDObject::Error: 311
311 descr = fmt ("ERROR: %1", obj->raw()); 312 break;
312 break; 313
313 314 case LDObject::Error:
314 case LDObject::Vertex: 315 descr = fmt ("ERROR: %1", obj->raw());
315 descr = static_cast<LDVertex*> (obj)->pos.stringRep (true); 316 break;
316 break; 317
317 318 case LDObject::Vertex:
318 case LDObject::Subfile: 319 descr = static_cast<LDVertex*> (obj)->pos.stringRep (true);
319 { 320 break;
320 LDSubfile* ref = static_cast<LDSubfile*> (obj); 321
321 322 case LDObject::Subfile:
323 { LDSubfile* ref = static_cast<LDSubfile*> (obj);
324
322 descr = fmt ("%1 %2, (", ref->fileInfo()->name(), 325 descr = fmt ("%1 %2, (", ref->fileInfo()->name(),
323 ref->position().stringRep (true)); 326 ref->position().stringRep (true));
324 327
325 for (short i = 0; i < 9; ++i) 328 for (short i = 0; i < 9; ++i)
326 descr += fmt ("%1%2", ftoa (ref->transform()[i]), 329 descr += fmt ("%1%2", ftoa (ref->transform() [i]),
327 (i != 8) ? " " : ""); 330 (i != 8) ? " " : "");
328 331
329 descr += ')'; 332 descr += ')';
330 } 333 }
331 break; 334 break;
332 335
333 case LDObject::BFC: 336 case LDObject::BFC:
334 descr = LDBFC::statements[static_cast<LDBFC*> (obj)->type]; 337 descr = LDBFC::statements[static_cast<LDBFC*> (obj)->type];
335 break; 338 break;
336 339
337 case LDObject::Overlay: 340 case LDObject::Overlay:
338 { 341 { LDOverlay* ovl = static_cast<LDOverlay*> (obj);
339 LDOverlay* ovl = static_cast<LDOverlay*> (obj);
340 descr = fmt ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->camera()], 342 descr = fmt ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->camera()],
341 basename (ovl->filename()), ovl->x(), ovl->y(), ovl->width(), ovl->height()); 343 basename (ovl->filename()), ovl->x(), ovl->y(), ovl->width(), ovl->height());
342 } 344 }
343 break; 345 break;
344 346
345 default: 347 default:
346 descr = obj->typeName(); 348 descr = obj->typeName();
347 break; 349 break;
348 } 350 }
349 351
350 // Put it into brackets if it's hidden 352 // Put it into brackets if it's hidden
351 if (obj->hidden()) 353 if (obj->hidden())
352 descr = fmt ("[[ %1 ]]", descr); 354 descr = fmt ("[[ %1 ]]", descr);
353 355
354 QListWidgetItem* item = new QListWidgetItem (descr); 356 QListWidgetItem* item = new QListWidgetItem (descr);
355 item->setIcon (getIcon (obj->typeName())); 357 item->setIcon (getIcon (obj->typeName()));
356 358
357 // Color gibberish orange on red so it stands out. 359 // Color gibberish orange on red so it stands out.
358 if (obj->getType() == LDObject::Error) { 360 if (obj->getType() == LDObject::Error)
359 item->setBackground (QColor ("#AA0000")); 361 { item->setBackground (QColor ("#AA0000"));
360 item->setForeground (QColor ("#FFAA00")); 362 item->setForeground (QColor ("#FFAA00"));
361 } elif (lv_colorize && obj->isColored() && 363 } elif (lv_colorize && obj->isColored() &&
362 obj->color() != maincolor && obj->color() != edgecolor) 364
363 { 365 obj->color() != maincolor && obj->color() != edgecolor)
364 // If the object isn't in the main or edge color, draw this 366 { // If the object isn't in the main or edge color, draw this
365 // list entry in said color. 367 // list entry in said color.
366 LDColor* col = getColor (obj->color()); 368 LDColor* col = getColor (obj->color());
369
367 if (col) 370 if (col)
368 item->setForeground (col->faceColor); 371 item->setForeground (col->faceColor);
369 } 372 }
370 373
371 obj->qObjListEntry = item; 374 obj->qObjListEntry = item;
372 ui->objectList->insertItem (ui->objectList->count(), item); 375 ui->objectList->insertItem (ui->objectList->count(), item);
373 } 376 }
374 377
375 g_bSelectionLocked = false; 378 g_bSelectionLocked = false;
376 updateSelection(); 379 updateSelection();
377 scrollToSelection(); 380 scrollToSelection();
378 } 381 }
379 382
380 // ============================================================================= 383 // =============================================================================
381 // ----------------------------------------------------------------------------- 384 // -----------------------------------------------------------------------------
382 void ForgeWindow::scrollToSelection() { 385 void ForgeWindow::scrollToSelection()
383 if (m_sel.size() == 0) 386 { if (m_sel.size() == 0)
384 return; 387 return;
385 388
386 LDObject* obj = m_sel[m_sel.size() - 1]; 389 LDObject* obj = m_sel[m_sel.size() - 1];
387 ui->objectList->scrollToItem (obj->qObjListEntry); 390 ui->objectList->scrollToItem (obj->qObjListEntry);
388 } 391 }
389 392
390 // ============================================================================= 393 // =============================================================================
391 // ----------------------------------------------------------------------------- 394 // -----------------------------------------------------------------------------
392 void ForgeWindow::slot_selectionChanged() { 395 void ForgeWindow::slot_selectionChanged()
393 if (g_bSelectionLocked == true || LDFile::current() == null) 396 { if (g_bSelectionLocked == true || LDFile::current() == null)
394 return; 397 return;
395 398
396 // Update the shared selection array, though don't do this if this was 399 // Update the shared selection array, though don't do this if this was
397 // called during GL picking, in which case the GL renderer takes care 400 // called during GL picking, in which case the GL renderer takes care
398 // of the selection. 401 // of the selection.
399 if (m_renderer->picking()) 402 if (m_renderer->picking())
400 return; 403 return;
401 404
402 List<LDObject*> priorSelection = m_sel; 405 List<LDObject*> priorSelection = m_sel;
403 406
404 // Get the objects from the object list selection 407 // Get the objects from the object list selection
405 m_sel.clear(); 408 m_sel.clear();
406 const QList<QListWidgetItem*> items = ui->objectList->selectedItems(); 409 const QList<QListWidgetItem*> items = ui->objectList->selectedItems();
407 410
408 for (LDObject* obj : LDFile::current()->objects()) 411 for (LDObject * obj : LDFile::current()->objects())
409 for (QListWidgetItem* item : items) { 412 for (QListWidgetItem * item : items)
410 if (item == obj->qObjListEntry) { 413 { if (item == obj->qObjListEntry)
411 m_sel << obj; 414 { m_sel << obj;
415 break;
416 }
417 }
418
419 // Update the GL renderer
420 for (LDObject * obj : priorSelection)
421 { obj->setSelected (false);
422 m_renderer->compileObject (obj);
423 }
424
425 for (LDObject * obj : m_sel)
426 { obj->setSelected (true);
427 m_renderer->compileObject (obj);
428 }
429
430 m_renderer->update();
431 }
432
433 // =============================================================================
434 // -----------------------------------------------------------------------------
435 void ForgeWindow::slot_recentFile()
436 { QAction* qAct = static_cast<QAction*> (sender());
437 openMainFile (qAct->text());
438 }
439
440 // =============================================================================
441 // -----------------------------------------------------------------------------
442 void ForgeWindow::slot_quickColor()
443 { beginAction (null);
444 QToolButton* button = static_cast<QToolButton*> (sender());
445 LDColor* col = null;
446
447 for (const LDQuickColor & entry : m_quickColors)
448 { if (entry.toolButton() == button)
449 { col = entry.color();
412 break; 450 break;
413 } 451 }
414 } 452 }
415 453
416 // Update the GL renderer
417 for (LDObject* obj : priorSelection) {
418 obj->setSelected (false);
419 m_renderer->compileObject (obj);
420 }
421
422 for (LDObject* obj : m_sel) {
423 obj->setSelected (true);
424 m_renderer->compileObject (obj);
425 }
426
427 m_renderer->update();
428 }
429
430 // =============================================================================
431 // -----------------------------------------------------------------------------
432 void ForgeWindow::slot_recentFile() {
433 QAction* qAct = static_cast<QAction*> (sender());
434 openMainFile (qAct->text());
435 }
436
437 // =============================================================================
438 // -----------------------------------------------------------------------------
439 void ForgeWindow::slot_quickColor() {
440 beginAction (null);
441 QToolButton* button = static_cast<QToolButton*> (sender());
442 LDColor* col = null;
443
444 for (const LDQuickColor& entry : m_quickColors) {
445 if (entry.toolButton() == button) {
446 col = entry.color();
447 break;
448 }
449 }
450
451 if (col == null) 454 if (col == null)
452 return; 455 return;
453 456
454 short newColor = col->index; 457 short newColor = col->index;
455 458
456 for (LDObject* obj : m_sel) { 459 for (LDObject * obj : m_sel)
457 if (obj->isColored() == false) 460 { if (obj->isColored() == false)
458 continue; // uncolored object 461 continue; // uncolored object
459 462
460 obj->setColor (newColor); 463 obj->setColor (newColor);
461 R()->compileObject (obj); 464 R()->compileObject (obj);
462 } 465 }
463 466
464 refresh(); 467 refresh();
465 endAction(); 468 endAction();
466 } 469 }
467 470
468 // ============================================================================= 471 // =============================================================================
469 // ----------------------------------------------------------------------------- 472 // -----------------------------------------------------------------------------
470 ulong ForgeWindow::getInsertionPoint() { 473 ulong ForgeWindow::getInsertionPoint()
471 if (m_sel.size() > 0) { 474 { if (m_sel.size() > 0)
472 // If we have a selection, put the item after it. 475 { // If we have a selection, put the item after it.
473 return (m_sel[m_sel.size() - 1]->getIndex()) + 1; 476 return (m_sel[m_sel.size() - 1]->getIndex()) + 1;
474 } 477 }
475 478
476 // Otherwise place the object at the end. 479 // Otherwise place the object at the end.
477 return LDFile::current()->numObjs(); 480 return LDFile::current()->numObjs();
478 } 481 }
479 482
480 // ============================================================================= 483 // =============================================================================
481 // ----------------------------------------------------------------------------- 484 // -----------------------------------------------------------------------------
482 void ForgeWindow::fullRefresh() { 485 void ForgeWindow::fullRefresh()
483 buildObjList(); 486 { buildObjList();
484 m_renderer->hardRefresh(); 487 m_renderer->hardRefresh();
485 } 488 }
486 489
487 // ============================================================================= 490 // =============================================================================
488 // ----------------------------------------------------------------------------- 491 // -----------------------------------------------------------------------------
489 void ForgeWindow::refresh() { 492 void ForgeWindow::refresh()
490 buildObjList(); 493 { buildObjList();
491 m_renderer->update(); 494 m_renderer->update();
492 } 495 }
493 496
494 // ============================================================================= 497 // =============================================================================
495 // ----------------------------------------------------------------------------- 498 // -----------------------------------------------------------------------------
496 void ForgeWindow::updateSelection() { 499 void ForgeWindow::updateSelection()
497 g_bSelectionLocked = true; 500 { g_bSelectionLocked = true;
498 501
499 for (LDObject* obj : LDFile::current()->objects()) 502 for (LDObject * obj : LDFile::current()->objects())
500 obj->setSelected (false); 503 obj->setSelected (false);
501 504
502 ui->objectList->clearSelection(); 505 ui->objectList->clearSelection();
503 for (LDObject* obj : m_sel) { 506
504 if (obj->qObjListEntry == null) 507 for (LDObject * obj : m_sel)
508 { if (obj->qObjListEntry == null)
505 continue; 509 continue;
506 510
507 obj->qObjListEntry->setSelected (true); 511 obj->qObjListEntry->setSelected (true);
508 obj->setSelected (true); 512 obj->setSelected (true);
509 } 513 }
510 514
511 g_bSelectionLocked = false; 515 g_bSelectionLocked = false;
512 slot_selectionChanged(); 516 slot_selectionChanged();
513 } 517 }
514 518
515 // ============================================================================= 519 // =============================================================================
516 // ----------------------------------------------------------------------------- 520 // -----------------------------------------------------------------------------
517 bool ForgeWindow::isSelected (LDObject* obj) { 521 bool ForgeWindow::isSelected (LDObject* obj)
518 LDObject* needle = obj->topLevelParent(); 522 { LDObject* needle = obj->topLevelParent();
519 523
520 for (LDObject* hay : m_sel) 524 for (LDObject * hay : m_sel)
521 if (hay == needle) 525 if (hay == needle)
522 return true; 526 return true;
523 527
524 return false; 528 return false;
525 } 529 }
526 530
527 short ForgeWindow::getSelectedColor() { 531 short ForgeWindow::getSelectedColor()
528 short result = -1; 532 { short result = -1;
529 533
530 for (LDObject* obj : m_sel) { 534 for (LDObject * obj : m_sel)
531 if (obj->isColored() == false) 535 { if (obj->isColored() == false)
532 continue; // doesn't use color 536 continue; // doesn't use color
533 537
534 if (result != -1 && obj->color() != result) 538 if (result != -1 && obj->color() != result)
535 return -1; // No consensus in object color 539 return -1; // No consensus in object color
536 540
537 if (result == -1) 541 if (result == -1)
538 result = obj->color(); 542 result = obj->color();
539 } 543 }
540 544
541 return result; 545 return result;
542 } 546 }
543 547
544 // ============================================================================= 548 // =============================================================================
545 // ----------------------------------------------------------------------------- 549 // -----------------------------------------------------------------------------
546 LDObject::Type ForgeWindow::uniformSelectedType() { 550 LDObject::Type ForgeWindow::uniformSelectedType()
547 LDObject::Type result = LDObject::Unidentified; 551 { LDObject::Type result = LDObject::Unidentified;
548 552
549 for (LDObject* obj : m_sel) { 553 for (LDObject * obj : m_sel)
550 if (result != LDObject::Unidentified && obj->color() != result) 554 { if (result != LDObject::Unidentified && obj->color() != result)
551 return LDObject::Unidentified; 555 return LDObject::Unidentified;
552 556
553 if (result == LDObject::Unidentified) 557 if (result == LDObject::Unidentified)
554 result = obj->getType(); 558 result = obj->getType();
555 } 559 }
556 560
557 return result; 561 return result;
558 } 562 }
559 563
560 // ============================================================================= 564 // =============================================================================
561 // ----------------------------------------------------------------------------- 565 // -----------------------------------------------------------------------------
562 void ForgeWindow::closeEvent (QCloseEvent* ev) { 566 void ForgeWindow::closeEvent (QCloseEvent* ev)
563 // Check whether it's safe to close all files. 567 { // Check whether it's safe to close all files.
564 if (!safeToCloseAll()) { 568 if (!safeToCloseAll())
565 ev->ignore(); 569 { ev->ignore();
566 return; 570 return;
567 } 571 }
568 572
569 // Save the configuration before leaving so that, for instance, grid choice 573 // Save the configuration before leaving so that, for instance, grid choice
570 // is preserved across instances. 574 // is preserved across instances.
571 Config::save(); 575 Config::save();
572 576
573 ev->accept(); 577 ev->accept();
574 } 578 }
575 579
576 // ============================================================================= 580 // =============================================================================
577 // ----------------------------------------------------------------------------- 581 // -----------------------------------------------------------------------------
578 void ForgeWindow::spawnContextMenu (const QPoint pos) { 582 void ForgeWindow::spawnContextMenu (const QPoint pos)
579 const bool single = (g_win->sel().size() == 1); 583 { const bool single = (g_win->sel().size() == 1);
580 LDObject* singleObj = (single) ? g_win->sel()[0] : null; 584 LDObject* singleObj = (single) ? g_win->sel() [0] : null;
581 585
582 QMenu* contextMenu = new QMenu; 586 QMenu* contextMenu = new QMenu;
583 587
584 if (single && singleObj->getType() != LDObject::Empty) { 588 if (single && singleObj->getType() != LDObject::Empty)
585 contextMenu->addAction (ACTION (Edit)); 589 { contextMenu->addAction (ACTION (Edit));
586 contextMenu->addSeparator(); 590 contextMenu->addSeparator();
587 } 591 }
588 592
589 contextMenu->addAction (ACTION (Cut)); 593 contextMenu->addAction (ACTION (Cut));
590 contextMenu->addAction (ACTION (Copy)); 594 contextMenu->addAction (ACTION (Copy));
591 contextMenu->addAction (ACTION (Paste)); 595 contextMenu->addAction (ACTION (Paste));
592 contextMenu->addAction (ACTION (Delete)); 596 contextMenu->addAction (ACTION (Delete));
593 contextMenu->addSeparator(); 597 contextMenu->addSeparator();
594 contextMenu->addAction (ACTION (SetColor)); 598 contextMenu->addAction (ACTION (SetColor));
595 599
596 if (single) 600 if (single)
597 contextMenu->addAction (ACTION (EditRaw)); 601 contextMenu->addAction (ACTION (EditRaw));
598 602
599 contextMenu->addAction (ACTION (Borders)); 603 contextMenu->addAction (ACTION (Borders));
600 contextMenu->addAction (ACTION (SetOverlay)); 604 contextMenu->addAction (ACTION (SetOverlay));
601 contextMenu->addAction (ACTION (ClearOverlay)); 605 contextMenu->addAction (ACTION (ClearOverlay));
602 contextMenu->addAction (ACTION (ModeSelect)); 606 contextMenu->addAction (ACTION (ModeSelect));
603 contextMenu->addAction (ACTION (ModeDraw)); 607 contextMenu->addAction (ACTION (ModeDraw));
604 contextMenu->addAction (ACTION (ModeCircle)); 608 contextMenu->addAction (ACTION (ModeCircle));
605 609
606 if (R()->camera() != GL::Free) { 610 if (R()->camera() != GL::Free)
607 contextMenu->addSeparator(); 611 { contextMenu->addSeparator();
608 contextMenu->addAction (ACTION (SetDrawDepth)); 612 contextMenu->addAction (ACTION (SetDrawDepth));
609 } 613 }
610 614
611 contextMenu->exec (pos); 615 contextMenu->exec (pos);
612 } 616 }
613 617
614 // ============================================================================= 618 // =============================================================================
615 // ----------------------------------------------------------------------------- 619 // -----------------------------------------------------------------------------
616 void ForgeWindow::deleteObjVector (List<LDObject*> objs) { 620 void ForgeWindow::deleteObjVector (List<LDObject*> objs)
617 for (LDObject* obj : objs) { 621 { for (LDObject * obj : objs)
618 LDFile::current()->forgetObject (obj); 622 { LDFile::current()->forgetObject (obj);
619 delete obj; 623 delete obj;
620 } 624 }
621 } 625 }
622 626
623 // ============================================================================= 627 // =============================================================================
624 // ----------------------------------------------------------------------------- 628 // -----------------------------------------------------------------------------
625 void ForgeWindow::deleteByColor (const short colnum) { 629 void ForgeWindow::deleteByColor (const short colnum)
626 List<LDObject*> objs; 630 { List<LDObject*> objs;
627 for (LDObject* obj : LDFile::current()->objects()) { 631
628 if (!obj->isColored() || obj->color() != colnum) 632 for (LDObject * obj : LDFile::current()->objects())
633 { if (!obj->isColored() || obj->color() != colnum)
629 continue; 634 continue;
630 635
631 objs << obj; 636 objs << obj;
632 } 637 }
633 638
634 deleteObjVector (objs); 639 deleteObjVector (objs);
635 } 640 }
636 641
637 // ============================================================================= 642 // =============================================================================
638 // ----------------------------------------------------------------------------- 643 // -----------------------------------------------------------------------------
639 void ForgeWindow::updateEditModeActions() { 644 void ForgeWindow::updateEditModeActions()
640 const EditMode mode = R()->editMode(); 645 { const EditMode mode = R()->editMode();
641 ACTION (ModeSelect)->setChecked (mode == Select); 646 ACTION (ModeSelect)->setChecked (mode == Select);
642 ACTION (ModeDraw)->setChecked (mode == Draw); 647 ACTION (ModeDraw)->setChecked (mode == Draw);
643 ACTION (ModeCircle)->setChecked (mode == CircleMode); 648 ACTION (ModeCircle)->setChecked (mode == CircleMode);
644 } 649 }
645 650
646 // ============================================================================= 651 // =============================================================================
647 // ----------------------------------------------------------------------------- 652 // -----------------------------------------------------------------------------
648 void ForgeWindow::slot_editObject (QListWidgetItem* listitem) { 653 void ForgeWindow::slot_editObject (QListWidgetItem* listitem)
649 LDObject* obj = null; 654 { LDObject* obj = null;
650 for (LDObject* it : LDFile::current()->objects()) { 655
651 if (it->qObjListEntry == listitem) { 656 for (LDObject * it : LDFile::current()->objects())
652 obj = it; 657 { if (it->qObjListEntry == listitem)
658 { obj = it;
653 break; 659 break;
654 } 660 }
655 } 661 }
656 662
657 AddObjectDialog::staticDialog (obj->getType(), obj); 663 AddObjectDialog::staticDialog (obj->getType(), obj);
658 } 664 }
659 665
660 // ============================================================================= 666 // =============================================================================
661 // ----------------------------------------------------------------------------- 667 // -----------------------------------------------------------------------------
662 void ForgeWindow::primitiveLoaderStart (ulong max) { 668 void ForgeWindow::primitiveLoaderStart (ulong max)
663 m_primLoaderWidget->show(); 669 { m_primLoaderWidget->show();
664 m_primLoaderBar->setRange (0, max); 670 m_primLoaderBar->setRange (0, max);
665 m_primLoaderBar->setValue (0); 671 m_primLoaderBar->setValue (0);
666 m_primLoaderBar->setFormat ("%p%"); 672 m_primLoaderBar->setFormat ("%p%");
667 } 673 }
668 674
669 // ============================================================================= 675 // =============================================================================
670 // ----------------------------------------------------------------------------- 676 // -----------------------------------------------------------------------------
671 void ForgeWindow::primitiveLoaderUpdate (ulong prog) { 677 void ForgeWindow::primitiveLoaderUpdate (ulong prog)
672 m_primLoaderBar->setValue (prog); 678 { m_primLoaderBar->setValue (prog);
673 } 679 }
674 680
675 // ============================================================================= 681 // =============================================================================
676 // ----------------------------------------------------------------------------- 682 // -----------------------------------------------------------------------------
677 void ForgeWindow::primitiveLoaderEnd() { 683 void ForgeWindow::primitiveLoaderEnd()
678 QTimer* hidetimer = new QTimer; 684 { QTimer* hidetimer = new QTimer;
679 connect (hidetimer, SIGNAL (timeout()), m_primLoaderWidget, SLOT (hide())); 685 connect (hidetimer, SIGNAL (timeout()), m_primLoaderWidget, SLOT (hide()));
680 hidetimer->setSingleShot (true); 686 hidetimer->setSingleShot (true);
681 hidetimer->start (1500); 687 hidetimer->start (1500);
682 m_primLoaderBar->setFormat (tr ("Done")); 688 m_primLoaderBar->setFormat (tr ("Done"));
683 log (tr ("Primitives scanned: %1 primitives listed"), m_primLoaderBar->value()); 689 log (tr ("Primitives scanned: %1 primitives listed"), m_primLoaderBar->value());
684 } 690 }
685 691
686 // ============================================================================= 692 // =============================================================================
687 // ----------------------------------------------------------------------------- 693 // -----------------------------------------------------------------------------
688 void ForgeWindow::save (LDFile* f, bool saveAs) { 694 void ForgeWindow::save (LDFile* f, bool saveAs)
689 str path = f->name(); 695 { str path = f->name();
690 696
691 if (path.length() == 0 || saveAs) { 697 if (path.length() == 0 || saveAs)
692 path = QFileDialog::getSaveFileName (g_win, tr ("Save As"), 698 { path = QFileDialog::getSaveFileName (g_win, tr ("Save As"),
693 LDFile::current()->name(), tr ("LDraw files (*.dat *.ldr)")); 699 LDFile::current()->name(), tr ("LDraw files (*.dat *.ldr)"));
694 700
695 if (path.length() == 0) { 701 if (path.length() == 0)
696 // User didn't give a file name. This happens if the user cancelled 702 { // User didn't give a file name. This happens if the user cancelled
697 // saving in the save file dialog. Abort. 703 // saving in the save file dialog. Abort.
698 return; 704 return;
699 } 705 }
700 } 706 }
701 707
702 if (f->save (path)) { 708 if (f->save (path))
703 f->setName (path); 709 { f->setName (path);
704 710
705 if (f == LDFile::current()) 711 if (f == LDFile::current())
706 g_win->updateTitle(); 712 g_win->updateTitle();
707 713
708 log ("Saved to %1.", path); 714 log ("Saved to %1.", path);
709 715
710 // Add it to recent files 716 // Add it to recent files
711 addRecentFile (path); 717 addRecentFile (path);
712 } else { 718 }
713 str message = fmt (tr ("Failed to save to %1: %2"), path, strerror (errno)); 719 else
714 720 { str message = fmt (tr ("Failed to save to %1: %2"), path, strerror (errno));
721
715 // Tell the user the save failed, and give the option for saving as with it. 722 // Tell the user the save failed, and give the option for saving as with it.
716 QMessageBox dlg (QMessageBox::Critical, tr ("Save Failure"), message, QMessageBox::Close, g_win); 723 QMessageBox dlg (QMessageBox::Critical, tr ("Save Failure"), message, QMessageBox::Close, g_win);
717 724
718 // Add a save-as button 725 // Add a save-as button
719 QPushButton* saveAsBtn = new QPushButton (tr ("Save As")); 726 QPushButton* saveAsBtn = new QPushButton (tr ("Save As"));
720 saveAsBtn->setIcon (getIcon ("file-save-as")); 727 saveAsBtn->setIcon (getIcon ("file-save-as"));
721 dlg.addButton (saveAsBtn, QMessageBox::ActionRole); 728 dlg.addButton (saveAsBtn, QMessageBox::ActionRole);
722 dlg.setDefaultButton (QMessageBox::Close); 729 dlg.setDefaultButton (QMessageBox::Close);
723 dlg.exec(); 730 dlg.exec();
724 731
725 if (dlg.clickedButton() == saveAsBtn) 732 if (dlg.clickedButton() == saveAsBtn)
726 save (f, true); // yay recursion! 733 save (f, true); // yay recursion!
727 } 734 }
728 } 735 }
729 736
730 void ForgeWindow::addMessage (str msg) { 737 void ForgeWindow::addMessage (str msg)
731 m_msglog->addLine (msg); 738 { m_msglog->addLine (msg);
732 } 739 }
733 740
734 // ============================================================================ 741 // ============================================================================
735 void ObjectList::contextMenuEvent (QContextMenuEvent* ev) { 742 void ObjectList::contextMenuEvent (QContextMenuEvent* ev)
736 g_win->spawnContextMenu (ev->globalPos()); 743 { g_win->spawnContextMenu (ev->globalPos());
737 } 744 }
738 745
739 // ============================================================================= 746 // =============================================================================
740 // ----------------------------------------------------------------------------- 747 // -----------------------------------------------------------------------------
741 QPixmap getIcon (str iconName) { 748 QPixmap getIcon (str iconName)
742 return (QPixmap (fmt (":/icons/%1.png", iconName))); 749 { return (QPixmap (fmt (":/icons/%1.png", iconName)));
743 } 750 }
744 751
745 // ============================================================================= 752 // =============================================================================
746 bool confirm (str msg) { 753 bool confirm (str msg)
747 return confirm (ForgeWindow::tr ("Confirm"), msg); 754 { return confirm (ForgeWindow::tr ("Confirm"), msg);
748 } 755 }
749 756
750 bool confirm (str title, str msg) { 757 bool confirm (str title, str msg)
751 return QMessageBox::question (g_win, title, msg, 758 { return QMessageBox::question (g_win, title, msg,
752 (QMessageBox::Yes | QMessageBox::No), QMessageBox::No) == QMessageBox::Yes; 759 (QMessageBox::Yes | QMessageBox::No), QMessageBox::No) == QMessageBox::Yes;
753 } 760 }
754 761
755 // ============================================================================= 762 // =============================================================================
756 void critical (str msg) { 763 void critical (str msg)
757 QMessageBox::critical (g_win, ForgeWindow::tr("Error"), msg, 764 { QMessageBox::critical (g_win, ForgeWindow::tr ("Error"), msg,
758 (QMessageBox::Close), QMessageBox::Close); 765 (QMessageBox::Close), QMessageBox::Close);
759 } 766 }
760 767
761 // ============================================================================= 768 // =============================================================================
762 QIcon makeColorIcon (LDColor* colinfo, const ushort size) { 769 QIcon makeColorIcon (LDColor* colinfo, const ushort size)
763 // Create an image object and link a painter to it. 770 { // Create an image object and link a painter to it.
764 QImage img (size, size, QImage::Format_ARGB32); 771 QImage img (size, size, QImage::Format_ARGB32);
765 QPainter paint (&img); 772 QPainter paint (&img);
766 773
767 QColor col = colinfo->faceColor; 774 QColor col = colinfo->faceColor;
768 if (colinfo->index == maincolor) { 775
769 // Use the user preferences for main color here 776 if (colinfo->index == maincolor)
777 { // Use the user preferences for main color here
770 col = gl_maincolor.value; 778 col = gl_maincolor.value;
771 col.setAlphaF (gl_maincolor_alpha); 779 col.setAlphaF (gl_maincolor_alpha);
772 } 780 }
773 781
774 // Paint the icon 782 // Paint the icon
775 paint.fillRect (QRect (0, 0, size, size), colinfo->edgeColor); 783 paint.fillRect (QRect (0, 0, size, size), colinfo->edgeColor);
776 paint.drawPixmap (QRect (1, 1, size - 2, size - 2), getIcon ("checkerboard"), QRect (0, 0, 8, 8)); 784 paint.drawPixmap (QRect (1, 1, size - 2, size - 2), getIcon ("checkerboard"), QRect (0, 0, 8, 8));
777 paint.fillRect (QRect (1, 1, size - 2, size - 2), col); 785 paint.fillRect (QRect (1, 1, size - 2, size - 2), col);
778 return QIcon (QPixmap::fromImage (img)); 786 return QIcon (QPixmap::fromImage (img));
779 } 787 }
780 788
781 // ============================================================================= 789 // =============================================================================
782 void makeColorSelector (QComboBox* box) { 790 void makeColorSelector (QComboBox* box)
783 std::map<short, ulong> counts; 791 { std::map<short, ulong> counts;
784 792
785 for (LDObject* obj : LDFile::current()->objects()) { 793 for (LDObject * obj : LDFile::current()->objects())
786 if (!obj->isColored()) 794 { if (!obj->isColored())
787 continue; 795 continue;
788 796
789 if (counts.find (obj->color()) == counts.end()) 797 if (counts.find (obj->color()) == counts.end())
790 counts[obj->color()] = 1; 798 counts[obj->color()] = 1;
791 else 799 else
792 counts[obj->color()]++; 800 counts[obj->color()]++;
793 } 801 }
794 802
795 box->clear(); 803 box->clear();
796 ulong row = 0; 804 ulong row = 0;
797 for (const auto& pair : counts) { 805
798 LDColor* col = getColor (pair.first); 806 for (const auto & pair : counts)
807 { LDColor* col = getColor (pair.first);
799 assert (col != null); 808 assert (col != null);
800 809
801 QIcon ico = makeColorIcon (col, 16); 810 QIcon ico = makeColorIcon (col, 16);
802 box->addItem (ico, fmt ("[%1] %2 (%3 object%4)", 811 box->addItem (ico, fmt ("[%1] %2 (%3 object%4)",
803 pair.first, col->name, pair.second, plural (pair.second))); 812 pair.first, col->name, pair.second, plural (pair.second)));
804 box->setItemData (row, pair.first); 813 box->setItemData (row, pair.first);
805 814
806 ++row; 815 ++row;
807 } 816 }
808 } 817 }
809 818
810 void ForgeWindow::setStatusBarText (str text) { 819 void ForgeWindow::setStatusBarText (str text)
811 statusBar()->showMessage (text); 820 { statusBar()->showMessage (text);
812 } 821 }
813 822
814 void ForgeWindow::clearSelection() { 823 void ForgeWindow::clearSelection()
815 m_sel.clear(); 824 { m_sel.clear();
816 } 825 }
817 826
818 Ui_LDForgeUI* ForgeWindow::interface() const { 827 Ui_LDForgeUI* ForgeWindow::interface() const
819 return ui; 828 { return ui;
820 } 829 }
821 830
822 #define act(N) QAction* ForgeWindow::action##N() { return ui->action##N; } 831 #define act(N) QAction* ForgeWindow::action##N() { return ui->action##N; }
823 #include "actions.h" 832 #include "actions.h"
824 833
825 void ForgeWindow::updateFileList() { 834 void ForgeWindow::updateFileList()
826 ui->fileList->clear(); 835 { ui->fileList->clear();
827 836
828 for (LDFile* f : g_loadedFiles) { 837 for (LDFile * f : g_loadedFiles)
829 // Don't list implicit files unless explicitly desired. 838 { // Don't list implicit files unless explicitly desired.
830 if (f->implicit() && !gui_implicitfiles) 839 if (f->implicit() && !gui_implicitfiles)
831 continue; 840 continue;
832 841
833 // Add an item to the list for this file and store a pointer to it in 842 // Add an item to the list for this file and store a pointer to it in
834 // the file, so we can find files by the list item. 843 // the file, so we can find files by the list item.
835 ui->fileList->addItem (""); 844 ui->fileList->addItem ("");
836 QListWidgetItem* item = ui->fileList->item (ui->fileList->count() - 1); 845 QListWidgetItem* item = ui->fileList->item (ui->fileList->count() - 1);
837 f->setListItem (item); 846 f->setListItem (item);
838 847
839 updateFileListItem (f); 848 updateFileListItem (f);
840 } 849 }
841 } 850 }
842 851
843 void ForgeWindow::updateFileListItem (LDFile* f) { 852 void ForgeWindow::updateFileListItem (LDFile* f)
844 if (f->listItem() == null) { 853 { if (f->listItem() == null)
845 // We don't have a list item for this file, so the list either doesn't 854 { // We don't have a list item for this file, so the list either doesn't
846 // exist yet or is out of date. Build the list now. 855 // exist yet or is out of date. Build the list now.
847 updateFileList(); 856 updateFileList();
848 return; 857 return;
849 } 858 }
850 859
851 // If this is the current file, it also needs to be the selected item on 860 // If this is the current file, it also needs to be the selected item on
852 // the list. 861 // the list.
853 if (f == LDFile::current()) 862 if (f == LDFile::current())
854 ui->fileList->setCurrentItem (f->listItem()); 863 ui->fileList->setCurrentItem (f->listItem());
855 864
856 // If we list implicit files, draw them with a shade of gray to make them 865 // If we list implicit files, draw them with a shade of gray to make them
857 // distinct. 866 // distinct.
858 if (f->implicit()) 867 if (f->implicit())
859 f->listItem()->setForeground (QColor (96, 96, 96)); 868 f->listItem()->setForeground (QColor (96, 96, 96));
860 869
861 f->listItem()->setText (f->getShortName()); 870 f->listItem()->setText (f->getShortName());
862 871
863 // If the file has unsaved changes, draw a little icon next to it to mark that. 872 // If the file has unsaved changes, draw a little icon next to it to mark that.
864 f->listItem()->setIcon (f->hasUnsavedChanges() ? getIcon ("file-save") : QIcon()); 873 f->listItem()->setIcon (f->hasUnsavedChanges() ? getIcon ("file-save") : QIcon());
865 } 874 }
866 875
867 void ForgeWindow::beginAction (QAction* act) { 876 void ForgeWindow::beginAction (QAction* act)
868 // Open the history so we can record the edits done during this action. 877 { // Open the history so we can record the edits done during this action.
869 if (act != ACTION (Undo) && act != ACTION (Redo) && act != ACTION (Open)) 878 if (act != ACTION (Undo) && act != ACTION (Redo) && act != ACTION (Open))
870 LDFile::current()->openHistory(); 879 LDFile::current()->openHistory();
871 } 880 }
872 881
873 void ForgeWindow::endAction() { 882 void ForgeWindow::endAction()
874 // Close the history now. 883 { // Close the history now.
875 LDFile::current()->closeHistory(); 884 LDFile::current()->closeHistory();
876 885
877 // Update the list item of the current file - we may need to draw an icon 886 // Update the list item of the current file - we may need to draw an icon
878 // now that marks it as having unsaved changes. 887 // now that marks it as having unsaved changes.
879 updateFileListItem (LDFile::current()); 888 updateFileListItem (LDFile::current());
880 } 889 }
881 890
882 // ============================================================================= 891 // =============================================================================
883 // A file is selected from the list of files on the left of the screen. Find out 892 // A file is selected from the list of files on the left of the screen. Find out
884 // which file was picked and change to it. 893 // which file was picked and change to it.
885 void ForgeWindow::changeCurrentFile() { 894 void ForgeWindow::changeCurrentFile()
886 LDFile* f = null; 895 { LDFile* f = null;
887 QListWidgetItem* item = ui->fileList->currentItem(); 896 QListWidgetItem* item = ui->fileList->currentItem();
888 897
889 // Find the file pointer of the item that was selected. 898 // Find the file pointer of the item that was selected.
890 for (LDFile* it : g_loadedFiles) { 899 for (LDFile * it : g_loadedFiles)
891 if (it->listItem() == item) { 900 { if (it->listItem() == item)
892 f = it; 901 { f = it;
893 break; 902 break;
894 } 903 }
895 } 904 }
896 905
897 // If we picked the same file we're currently on, we don't need to do 906 // If we picked the same file we're currently on, we don't need to do
898 // anything. 907 // anything.
899 if (!f || f == LDFile::current()) 908 if (!f || f == LDFile::current())
900 return; 909 return;
901 910
902 LDFile::setCurrent (f); 911 LDFile::setCurrent (f);
903 } 912 }
904 913
905 void ForgeWindow::refreshObjectList() { 914 void ForgeWindow::refreshObjectList()
915 {
906 #if 0 916 #if 0
907 ui->objectList->clear(); 917 ui->objectList->clear();
908 LDFile* f = LDFile::current(); 918 LDFile* f = LDFile::current();
909 919
910 for (LDObject* obj : *f) 920 for (LDObject * obj : *f)
911 ui->objectList->addItem (obj->qObjListEntry); 921 ui->objectList->addItem (obj->qObjListEntry);
922
912 #endif 923 #endif
913 924
914 buildObjList(); 925 buildObjList();
915 } 926 }
916 927
917 QImage imageFromScreencap (uchar* data, ushort w, ushort h) { 928 QImage imageFromScreencap (uchar* data, ushort w, ushort h)
918 // GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well. 929 { // GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well.
919 return QImage (data, w, h, QImage::Format_ARGB32).rgbSwapped().mirrored(); 930 return QImage (data, w, h, QImage::Format_ARGB32).rgbSwapped().mirrored();
920 } 931 }
921 932
922 // ============================================================================= 933 // =============================================================================
923 // ----------------------------------------------------------------------------- 934 // -----------------------------------------------------------------------------
924 LDQuickColor::LDQuickColor (LDColor* color, QToolButton* toolButton) : 935 LDQuickColor::LDQuickColor (LDColor* color, QToolButton* toolButton) :
925 m_color (color), 936 m_color (color),
926 m_toolButton (toolButton) {} 937 m_toolButton (toolButton) {}
927 938
928 LDQuickColor LDQuickColor::getSeparator() { 939 LDQuickColor LDQuickColor::getSeparator()
929 return LDQuickColor (null, null); 940 { return LDQuickColor (null, null);
930 } 941 }
931 942
932 bool LDQuickColor::isSeparator() const { 943 bool LDQuickColor::isSeparator() const
933 return color() == null; 944 { return color() == null;
934 } 945 }
935 #include "moc_gui.cpp"

mercurial