src/gui.cc

changeset 603
47e7773c7841
parent 600
209e3f1f7b2c
child 604
01bdac75994a
equal deleted inserted replaced
602:ac1744536b33 603:47e7773c7841
65 extern_cfg (Bool, gl_drawangles); 65 extern_cfg (Bool, gl_drawangles);
66 66
67 // ============================================================================= 67 // =============================================================================
68 // ----------------------------------------------------------------------------- 68 // -----------------------------------------------------------------------------
69 ForgeWindow::ForgeWindow() 69 ForgeWindow::ForgeWindow()
70 { g_win = this; 70 {
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
120 } 121 }
121 122
122 // ============================================================================= 123 // =============================================================================
123 // ----------------------------------------------------------------------------- 124 // -----------------------------------------------------------------------------
124 KeySequenceConfig* ForgeWindow::shortcutForAction (QAction* act) 125 KeySequenceConfig* ForgeWindow::shortcutForAction (QAction* act)
125 { str keycfgname = fmt ("key_%1", act->objectName()); 126 {
127 str keycfgname = fmt ("key_%1", act->objectName());
126 return KeySequenceConfig::getByName (keycfgname); 128 return KeySequenceConfig::getByName (keycfgname);
127 } 129 }
128 130
129 // ============================================================================= 131 // =============================================================================
130 // ----------------------------------------------------------------------------- 132 // -----------------------------------------------------------------------------
131 void ForgeWindow::updateActionShortcuts() 133 void ForgeWindow::updateActionShortcuts()
132 { for (QAction* act : findChildren<QAction*>()) 134 {
133 { KeySequenceConfig* cfg = shortcutForAction (act); 135 for (QAction* act : findChildren<QAction*>())
136 {
137 KeySequenceConfig* cfg = shortcutForAction (act);
134 138
135 if (cfg) 139 if (cfg)
136 act->setShortcut (cfg->getValue()); 140 act->setShortcut (cfg->getValue());
137 } 141 }
138 } 142 }
139 143
140 // ============================================================================= 144 // =============================================================================
141 // ----------------------------------------------------------------------------- 145 // -----------------------------------------------------------------------------
142 void ForgeWindow::slot_action() 146 void ForgeWindow::slot_action()
143 { // Get the name of the sender object and use it to compose the slot name. 147 {
148 // Get the name of the sender object and use it to compose the slot name.
144 str methodName = fmt ("slot_%1", sender()->objectName()); 149 str methodName = fmt ("slot_%1", sender()->objectName());
145 150
146 #ifdef DEBUG 151 #ifdef DEBUG
147 log ("Action %1 triggered", sender()->objectName()); 152 log ("Action %1 triggered", sender()->objectName());
148 #endif 153 #endif
153 } 158 }
154 159
155 // ============================================================================= 160 // =============================================================================
156 // ----------------------------------------------------------------------------- 161 // -----------------------------------------------------------------------------
157 void ForgeWindow::endAction() 162 void ForgeWindow::endAction()
158 { // Add a step in the history now. 163 {
164 // Add a step in the history now.
159 getCurrentDocument()->addHistoryStep(); 165 getCurrentDocument()->addHistoryStep();
160 166
161 // Update the list item of the current file - we may need to draw an icon 167 // Update the list item of the current file - we may need to draw an icon
162 // now that marks it as having unsaved changes. 168 // now that marks it as having unsaved changes.
163 updateDocumentListItem (getCurrentDocument()); 169 updateDocumentListItem (getCurrentDocument());
164 } 170 }
165 171
166 // ============================================================================= 172 // =============================================================================
167 // ----------------------------------------------------------------------------- 173 // -----------------------------------------------------------------------------
168 void ForgeWindow::slot_lastSecondCleanup() 174 void ForgeWindow::slot_lastSecondCleanup()
169 { delete m_renderer; 175 {
176 delete m_renderer;
170 delete ui; 177 delete ui;
171 } 178 }
172 179
173 // ============================================================================= 180 // =============================================================================
174 // ----------------------------------------------------------------------------- 181 // -----------------------------------------------------------------------------
175 void ForgeWindow::updateRecentFilesMenu() 182 void ForgeWindow::updateRecentFilesMenu()
176 { // First, clear any items in the recent files menu 183 {
184 // First, clear any items in the recent files menu
177 for (QAction * recent : m_recentFiles) 185 for (QAction * recent : m_recentFiles)
178 delete recent; 186 delete recent;
179 187
180 m_recentFiles.clear(); 188 m_recentFiles.clear();
181 189
182 QAction* first = null; 190 QAction* first = null;
183 191
184 for (const QVariant& it : io_recentfiles) 192 for (const QVariant& it : io_recentfiles)
185 { str file = it.toString(); 193 {
194 str file = it.toString();
186 QAction* recent = new QAction (getIcon ("open-recent"), file, this); 195 QAction* recent = new QAction (getIcon ("open-recent"), file, this);
187 196
188 connect (recent, SIGNAL (triggered()), this, SLOT (slot_recentFile())); 197 connect (recent, SIGNAL (triggered()), this, SLOT (slot_recentFile()));
189 ui->menuOpenRecent->insertAction (first, recent); 198 ui->menuOpenRecent->insertAction (first, recent);
190 m_recentFiles << recent; 199 m_recentFiles << recent;
193 } 202 }
194 203
195 // ============================================================================= 204 // =============================================================================
196 // ----------------------------------------------------------------------------- 205 // -----------------------------------------------------------------------------
197 QList<LDQuickColor> quickColorsFromConfig() 206 QList<LDQuickColor> quickColorsFromConfig()
198 { QList<LDQuickColor> colors; 207 {
208 QList<LDQuickColor> colors;
199 209
200 for (str colorname : gui_colortoolbar.split (":")) 210 for (str colorname : gui_colortoolbar.split (":"))
201 { if (colorname == "|") 211 {
212 if (colorname == "|")
202 colors << LDQuickColor::getSeparator(); 213 colors << LDQuickColor::getSeparator();
203 else 214 else
204 { LDColor* col = getColor (colorname.toLong()); 215 {
216 LDColor* col = getColor (colorname.toLong());
205 217
206 if (col != null) 218 if (col != null)
207 colors << LDQuickColor (col, null); 219 colors << LDQuickColor (col, null);
208 } 220 }
209 } 221 }
212 } 224 }
213 225
214 // ============================================================================= 226 // =============================================================================
215 // ----------------------------------------------------------------------------- 227 // -----------------------------------------------------------------------------
216 void ForgeWindow::updateToolBars() 228 void ForgeWindow::updateToolBars()
217 { m_colorButtons.clear(); 229 {
230 m_colorButtons.clear();
218 ui->colorToolbar->clear(); 231 ui->colorToolbar->clear();
219 232
220 for (LDQuickColor& entry : m_quickColors) 233 for (LDQuickColor& entry : m_quickColors)
221 { if (entry.isSeparator()) 234 {
235 if (entry.isSeparator())
222 ui->colorToolbar->addSeparator(); 236 ui->colorToolbar->addSeparator();
223 else 237 else
224 { QToolButton* colorButton = new QToolButton; 238 {
239 QToolButton* colorButton = new QToolButton;
225 colorButton->setIcon (makeColorIcon (entry.getColor(), 22)); 240 colorButton->setIcon (makeColorIcon (entry.getColor(), 22));
226 colorButton->setIconSize (QSize (22, 22)); 241 colorButton->setIconSize (QSize (22, 22));
227 colorButton->setToolTip (entry.getColor()->name); 242 colorButton->setToolTip (entry.getColor()->name);
228 243
229 connect (colorButton, SIGNAL (clicked()), this, SLOT (slot_quickColor())); 244 connect (colorButton, SIGNAL (clicked()), this, SLOT (slot_quickColor()));
238 } 253 }
239 254
240 // ============================================================================= 255 // =============================================================================
241 // ----------------------------------------------------------------------------- 256 // -----------------------------------------------------------------------------
242 void ForgeWindow::updateGridToolBar() 257 void ForgeWindow::updateGridToolBar()
243 { // Ensure that the current grid - and only the current grid - is selected. 258 {
259 // Ensure that the current grid - and only the current grid - is selected.
244 ui->actionGridCoarse->setChecked (grid == Grid::Coarse); 260 ui->actionGridCoarse->setChecked (grid == Grid::Coarse);
245 ui->actionGridMedium->setChecked (grid == Grid::Medium); 261 ui->actionGridMedium->setChecked (grid == Grid::Medium);
246 ui->actionGridFine->setChecked (grid == Grid::Fine); 262 ui->actionGridFine->setChecked (grid == Grid::Fine);
247 } 263 }
248 264
249 // ============================================================================= 265 // =============================================================================
250 // ----------------------------------------------------------------------------- 266 // -----------------------------------------------------------------------------
251 void ForgeWindow::updateTitle() 267 void ForgeWindow::updateTitle()
252 { str title = fmt (APPNAME " %1", fullVersionString()); 268 {
269 str title = fmt (APPNAME " %1", fullVersionString());
253 270
254 // Append our current file if we have one 271 // Append our current file if we have one
255 if (getCurrentDocument()) 272 if (getCurrentDocument())
256 { if (getCurrentDocument()->getName().length() > 0) 273 {
274 if (getCurrentDocument()->getName().length() > 0)
257 title += fmt (": %1", basename (getCurrentDocument()->getName())); 275 title += fmt (": %1", basename (getCurrentDocument()->getName()));
258 else 276 else
259 title += fmt (": <anonymous>"); 277 title += fmt (": <anonymous>");
260 278
261 if (getCurrentDocument()->getObjectCount() > 0 && 279 if (getCurrentDocument()->getObjectCount() > 0 &&
262 getCurrentDocument()->getObject (0)->getType() == LDObject::Comment) 280 getCurrentDocument()->getObject (0)->getType() == LDObject::Comment)
263 { // Append title 281 {
282 // Append title
264 LDComment* comm = static_cast<LDComment*> (getCurrentDocument()->getObject (0)); 283 LDComment* comm = static_cast<LDComment*> (getCurrentDocument()->getObject (0));
265 title += fmt (": %1", comm->text); 284 title += fmt (": %1", comm->text);
266 } 285 }
267 286
268 if (getCurrentDocument()->getHistory()->getPosition() != getCurrentDocument()->getSavePosition()) 287 if (getCurrentDocument()->getHistory()->getPosition() != getCurrentDocument()->getSavePosition())
279 } 298 }
280 299
281 // ============================================================================= 300 // =============================================================================
282 // ----------------------------------------------------------------------------- 301 // -----------------------------------------------------------------------------
283 int ForgeWindow::deleteSelection() 302 int ForgeWindow::deleteSelection()
284 { if (selection().isEmpty()) 303 {
304 if (selection().isEmpty())
285 return 0; 305 return 0;
286 306
287 QList<LDObject*> selCopy = selection(); 307 QList<LDObject*> selCopy = selection();
288 308
289 // Delete the objects that were being selected 309 // Delete the objects that were being selected
295 } 315 }
296 316
297 // ============================================================================= 317 // =============================================================================
298 // ----------------------------------------------------------------------------- 318 // -----------------------------------------------------------------------------
299 void ForgeWindow::buildObjList() 319 void ForgeWindow::buildObjList()
300 { if (!getCurrentDocument()) 320 {
321 if (!getCurrentDocument())
301 return; 322 return;
302 323
303 // Lock the selection while we do this so that refreshing the object list 324 // Lock the selection while we do this so that refreshing the object list
304 // doesn't trigger selection updating so that the selection doesn't get lost 325 // doesn't trigger selection updating so that the selection doesn't get lost
305 // while this is done. 326 // while this is done.
309 delete ui->objectList->item (i); 330 delete ui->objectList->item (i);
310 331
311 ui->objectList->clear(); 332 ui->objectList->clear();
312 333
313 for (LDObject* obj : getCurrentDocument()->getObjects()) 334 for (LDObject* obj : getCurrentDocument()->getObjects())
314 { str descr; 335 {
336 str descr;
315 337
316 switch (obj->getType()) 338 switch (obj->getType())
317 { case LDObject::Comment: 339 {
318 { descr = static_cast<LDComment*> (obj)->text; 340 case LDObject::Comment:
341 {
342 descr = static_cast<LDComment*> (obj)->text;
319 343
320 // Remove leading whitespace 344 // Remove leading whitespace
321 while (descr[0] == ' ') 345 while (descr[0] == ' ')
322 descr.remove (0, 1); 346 descr.remove (0, 1);
323 } break; 347 } break;
327 351
328 case LDObject::Line: 352 case LDObject::Line:
329 case LDObject::Triangle: 353 case LDObject::Triangle:
330 case LDObject::Quad: 354 case LDObject::Quad:
331 case LDObject::CondLine: 355 case LDObject::CondLine:
332 { for (int i = 0; i < obj->vertices(); ++i) 356 {
333 { if (i != 0) 357 for (int i = 0; i < obj->vertices(); ++i)
358 {
359 if (i != 0)
334 descr += ", "; 360 descr += ", ";
335 361
336 descr += obj->getVertex (i).stringRep (true); 362 descr += obj->getVertex (i).stringRep (true);
337 } 363 }
338 } break; 364 } break;
339 365
340 case LDObject::Error: 366 case LDObject::Error:
341 { descr = fmt ("ERROR: %1", obj->raw()); 367 {
368 descr = fmt ("ERROR: %1", obj->raw());
342 } break; 369 } break;
343 370
344 case LDObject::Vertex: 371 case LDObject::Vertex:
345 { descr = static_cast<LDVertex*> (obj)->pos.stringRep (true); 372 {
373 descr = static_cast<LDVertex*> (obj)->pos.stringRep (true);
346 } break; 374 } break;
347 375
348 case LDObject::Subfile: 376 case LDObject::Subfile:
349 { LDSubfile* ref = static_cast<LDSubfile*> (obj); 377 {
378 LDSubfile* ref = static_cast<LDSubfile*> (obj);
350 379
351 descr = fmt ("%1 %2, (", ref->getFileInfo()->getDisplayName(), ref->getPosition().stringRep (true)); 380 descr = fmt ("%1 %2, (", ref->getFileInfo()->getDisplayName(), ref->getPosition().stringRep (true));
352 381
353 for (int i = 0; i < 9; ++i) 382 for (int i = 0; i < 9; ++i)
354 descr += fmt ("%1%2", ref->getTransform()[i], (i != 8) ? " " : ""); 383 descr += fmt ("%1%2", ref->getTransform()[i], (i != 8) ? " " : "");
355 384
356 descr += ')'; 385 descr += ')';
357 } break; 386 } break;
358 387
359 case LDObject::BFC: 388 case LDObject::BFC:
360 { descr = LDBFC::statements[static_cast<LDBFC*> (obj)->type]; 389 {
390 descr = LDBFC::statements[static_cast<LDBFC*> (obj)->type];
361 } break; 391 } break;
362 392
363 case LDObject::Overlay: 393 case LDObject::Overlay:
364 { LDOverlay* ovl = static_cast<LDOverlay*> (obj); 394 {
395 LDOverlay* ovl = static_cast<LDOverlay*> (obj);
365 descr = fmt ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->getCamera()], 396 descr = fmt ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->getCamera()],
366 basename (ovl->getFileName()), ovl->getX(), ovl->getY(), 397 basename (ovl->getFileName()), ovl->getX(), ovl->getY(),
367 ovl->getWidth(), ovl->getHeight()); 398 ovl->getWidth(), ovl->getHeight());
368 } 399 }
369 break; 400 break;
370 401
371 default: 402 default:
372 { descr = obj->getTypeName(); 403 {
404 descr = obj->getTypeName();
373 } break; 405 } break;
374 } 406 }
375 407
376 QListWidgetItem* item = new QListWidgetItem (descr); 408 QListWidgetItem* item = new QListWidgetItem (descr);
377 item->setIcon (getIcon (obj->getTypeName())); 409 item->setIcon (getIcon (obj->getTypeName()));
378 410
379 // Use italic font if hidden 411 // Use italic font if hidden
380 if (obj->isHidden()) 412 if (obj->isHidden())
381 { QFont font = item->font(); 413 {
414 QFont font = item->font();
382 font.setItalic (true); 415 font.setItalic (true);
383 item->setFont (font); 416 item->setFont (font);
384 } 417 }
385 418
386 // Color gibberish orange on red so it stands out. 419 // Color gibberish orange on red so it stands out.
387 if (obj->getType() == LDObject::Error) 420 if (obj->getType() == LDObject::Error)
388 { item->setBackground (QColor ("#AA0000")); 421 {
422 item->setBackground (QColor ("#AA0000"));
389 item->setForeground (QColor ("#FFAA00")); 423 item->setForeground (QColor ("#FFAA00"));
390 } 424 }
391 elif (lv_colorize && obj->isColored() && obj->getColor() != maincolor && obj->getColor() != edgecolor) 425 elif (lv_colorize && obj->isColored() && obj->getColor() != maincolor && obj->getColor() != edgecolor)
392 { // If the object isn't in the main or edge color, draw this 426 {
427 // If the object isn't in the main or edge color, draw this
393 // list entry in said color. 428 // list entry in said color.
394 LDColor* col = getColor (obj->getColor()); 429 LDColor* col = getColor (obj->getColor());
395 430
396 if (col) 431 if (col)
397 item->setForeground (col->faceColor); 432 item->setForeground (col->faceColor);
407 } 442 }
408 443
409 // ============================================================================= 444 // =============================================================================
410 // ----------------------------------------------------------------------------- 445 // -----------------------------------------------------------------------------
411 void ForgeWindow::scrollToSelection() 446 void ForgeWindow::scrollToSelection()
412 { if (selection().isEmpty()) 447 {
448 if (selection().isEmpty())
413 return; 449 return;
414 450
415 LDObject* obj = selection().last(); 451 LDObject* obj = selection().last();
416 ui->objectList->scrollToItem (obj->qObjListEntry); 452 ui->objectList->scrollToItem (obj->qObjListEntry);
417 } 453 }
418 454
419 // ============================================================================= 455 // =============================================================================
420 // ----------------------------------------------------------------------------- 456 // -----------------------------------------------------------------------------
421 void ForgeWindow::slot_selectionChanged() 457 void ForgeWindow::slot_selectionChanged()
422 { if (g_isSelectionLocked == true || getCurrentDocument() == null) 458 {
459 if (g_isSelectionLocked == true || getCurrentDocument() == null)
423 return; 460 return;
424 461
425 // Update the shared selection array, though don't do this if this was 462 // Update the shared selection array, though don't do this if this was
426 // called during GL picking, in which case the GL renderer takes care 463 // called during GL picking, in which case the GL renderer takes care
427 // of the selection. 464 // of the selection.
433 // Get the objects from the object list selection 470 // Get the objects from the object list selection
434 getCurrentDocument()->clearSelection(); 471 getCurrentDocument()->clearSelection();
435 const QList<QListWidgetItem*> items = ui->objectList->selectedItems(); 472 const QList<QListWidgetItem*> items = ui->objectList->selectedItems();
436 473
437 for (LDObject* obj : getCurrentDocument()->getObjects()) 474 for (LDObject* obj : getCurrentDocument()->getObjects())
438 { for (QListWidgetItem* item : items) 475 {
439 { if (item == obj->qObjListEntry) 476 for (QListWidgetItem* item : items)
440 { obj->select(); 477 {
478 if (item == obj->qObjListEntry)
479 {
480 obj->select();
441 break; 481 break;
442 } 482 }
443 } 483 }
444 } 484 }
445 485
454 } 494 }
455 495
456 // ============================================================================= 496 // =============================================================================
457 // ----------------------------------------------------------------------------- 497 // -----------------------------------------------------------------------------
458 void ForgeWindow::slot_recentFile() 498 void ForgeWindow::slot_recentFile()
459 { QAction* qAct = static_cast<QAction*> (sender()); 499 {
500 QAction* qAct = static_cast<QAction*> (sender());
460 openMainFile (qAct->text()); 501 openMainFile (qAct->text());
461 } 502 }
462 503
463 // ============================================================================= 504 // =============================================================================
464 // ----------------------------------------------------------------------------- 505 // -----------------------------------------------------------------------------
465 void ForgeWindow::slot_quickColor() 506 void ForgeWindow::slot_quickColor()
466 { QToolButton* button = static_cast<QToolButton*> (sender()); 507 {
508 QToolButton* button = static_cast<QToolButton*> (sender());
467 LDColor* col = null; 509 LDColor* col = null;
468 510
469 for (const LDQuickColor & entry : m_quickColors) 511 for (const LDQuickColor & entry : m_quickColors)
470 { if (entry.getToolButton() == button) 512 {
471 { col = entry.getColor(); 513 if (entry.getToolButton() == button)
514 {
515 col = entry.getColor();
472 break; 516 break;
473 } 517 }
474 } 518 }
475 519
476 if (col == null) 520 if (col == null)
477 return; 521 return;
478 522
479 int newColor = col->index; 523 int newColor = col->index;
480 524
481 for (LDObject* obj : selection()) 525 for (LDObject* obj : selection())
482 { if (obj->isColored() == false) 526 {
527 if (obj->isColored() == false)
483 continue; // uncolored object 528 continue; // uncolored object
484 529
485 obj->setColor (newColor); 530 obj->setColor (newColor);
486 R()->compileObject (obj); 531 R()->compileObject (obj);
487 } 532 }
491 } 536 }
492 537
493 // ============================================================================= 538 // =============================================================================
494 // ----------------------------------------------------------------------------- 539 // -----------------------------------------------------------------------------
495 int ForgeWindow::getInsertionPoint() 540 int ForgeWindow::getInsertionPoint()
496 { // If we have a selection, put the item after it. 541 {
542 // If we have a selection, put the item after it.
497 if (!selection().isEmpty()) 543 if (!selection().isEmpty())
498 return selection().last()->getIndex() + 1; 544 return selection().last()->getIndex() + 1;
499 545
500 // Otherwise place the object at the end. 546 // Otherwise place the object at the end.
501 return getCurrentDocument()->getObjectCount(); 547 return getCurrentDocument()->getObjectCount();
502 } 548 }
503 549
504 // ============================================================================= 550 // =============================================================================
505 // ----------------------------------------------------------------------------- 551 // -----------------------------------------------------------------------------
506 void ForgeWindow::doFullRefresh() 552 void ForgeWindow::doFullRefresh()
507 { buildObjList(); 553 {
554 buildObjList();
508 m_renderer->hardRefresh(); 555 m_renderer->hardRefresh();
509 } 556 }
510 557
511 // ============================================================================= 558 // =============================================================================
512 // ----------------------------------------------------------------------------- 559 // -----------------------------------------------------------------------------
513 void ForgeWindow::refresh() 560 void ForgeWindow::refresh()
514 { buildObjList(); 561 {
562 buildObjList();
515 m_renderer->update(); 563 m_renderer->update();
516 } 564 }
517 565
518 // ============================================================================= 566 // =============================================================================
519 // ----------------------------------------------------------------------------- 567 // -----------------------------------------------------------------------------
520 void ForgeWindow::updateSelection() 568 void ForgeWindow::updateSelection()
521 { g_isSelectionLocked = true; 569 {
570 g_isSelectionLocked = true;
522 571
523 for (LDObject* obj : getCurrentDocument()->getObjects()) 572 for (LDObject* obj : getCurrentDocument()->getObjects())
524 obj->setSelected (false); 573 obj->setSelected (false);
525 574
526 ui->objectList->clearSelection(); 575 ui->objectList->clearSelection();
527 576
528 for (LDObject* obj : selection()) 577 for (LDObject* obj : selection())
529 { if (obj->qObjListEntry == null) 578 {
579 if (obj->qObjListEntry == null)
530 continue; 580 continue;
531 581
532 obj->qObjListEntry->setSelected (true); 582 obj->qObjListEntry->setSelected (true);
533 obj->setSelected (true); 583 obj->setSelected (true);
534 } 584 }
538 } 588 }
539 589
540 // ============================================================================= 590 // =============================================================================
541 // ----------------------------------------------------------------------------- 591 // -----------------------------------------------------------------------------
542 int ForgeWindow::getSelectedColor() 592 int ForgeWindow::getSelectedColor()
543 { int result = -1; 593 {
594 int result = -1;
544 595
545 for (LDObject* obj : selection()) 596 for (LDObject* obj : selection())
546 { if (obj->isColored() == false) 597 {
598 if (obj->isColored() == false)
547 continue; // doesn't use color 599 continue; // doesn't use color
548 600
549 if (result != -1 && obj->getColor() != result) 601 if (result != -1 && obj->getColor() != result)
550 return -1; // No consensus in object color 602 return -1; // No consensus in object color
551 603
557 } 609 }
558 610
559 // ============================================================================= 611 // =============================================================================
560 // ----------------------------------------------------------------------------- 612 // -----------------------------------------------------------------------------
561 LDObject::Type ForgeWindow::getUniformSelectedType() 613 LDObject::Type ForgeWindow::getUniformSelectedType()
562 { LDObject::Type result = LDObject::Unidentified; 614 {
615 LDObject::Type result = LDObject::Unidentified;
563 616
564 for (LDObject* obj : selection()) 617 for (LDObject* obj : selection())
565 { if (result != LDObject::Unidentified && obj->getColor() != result) 618 {
619 if (result != LDObject::Unidentified && obj->getColor() != result)
566 return LDObject::Unidentified; 620 return LDObject::Unidentified;
567 621
568 if (result == LDObject::Unidentified) 622 if (result == LDObject::Unidentified)
569 result = obj->getType(); 623 result = obj->getType();
570 } 624 }
573 } 627 }
574 628
575 // ============================================================================= 629 // =============================================================================
576 // ----------------------------------------------------------------------------- 630 // -----------------------------------------------------------------------------
577 void ForgeWindow::closeEvent (QCloseEvent* ev) 631 void ForgeWindow::closeEvent (QCloseEvent* ev)
578 { // Check whether it's safe to close all files. 632 {
633 // Check whether it's safe to close all files.
579 if (!safeToCloseAll()) 634 if (!safeToCloseAll())
580 { ev->ignore(); 635 {
636 ev->ignore();
581 return; 637 return;
582 } 638 }
583 639
584 // Save the configuration before leaving so that, for instance, grid choice 640 // Save the configuration before leaving so that, for instance, grid choice
585 // is preserved across instances. 641 // is preserved across instances.
589 } 645 }
590 646
591 // ============================================================================= 647 // =============================================================================
592 // ----------------------------------------------------------------------------- 648 // -----------------------------------------------------------------------------
593 void ForgeWindow::spawnContextMenu (const QPoint pos) 649 void ForgeWindow::spawnContextMenu (const QPoint pos)
594 { const bool single = (selection().size() == 1); 650 {
651 const bool single = (selection().size() == 1);
595 LDObject* singleObj = (single) ? selection()[0] : null; 652 LDObject* singleObj = (single) ? selection()[0] : null;
596 653
597 QMenu* contextMenu = new QMenu; 654 QMenu* contextMenu = new QMenu;
598 655
599 if (single && singleObj->getType() != LDObject::Empty) 656 if (single && singleObj->getType() != LDObject::Empty)
600 { contextMenu->addAction (ui->actionEdit); 657 {
658 contextMenu->addAction (ui->actionEdit);
601 contextMenu->addSeparator(); 659 contextMenu->addSeparator();
602 } 660 }
603 661
604 contextMenu->addAction (ui->actionCut); 662 contextMenu->addAction (ui->actionCut);
605 contextMenu->addAction (ui->actionCopy); 663 contextMenu->addAction (ui->actionCopy);
617 contextMenu->addAction (ui->actionModeSelect); 675 contextMenu->addAction (ui->actionModeSelect);
618 contextMenu->addAction (ui->actionModeDraw); 676 contextMenu->addAction (ui->actionModeDraw);
619 contextMenu->addAction (ui->actionModeCircle); 677 contextMenu->addAction (ui->actionModeCircle);
620 678
621 if (selection().size() > 0) 679 if (selection().size() > 0)
622 { contextMenu->addSeparator(); 680 {
681 contextMenu->addSeparator();
623 contextMenu->addAction (ui->actionSubfileSelection); 682 contextMenu->addAction (ui->actionSubfileSelection);
624 } 683 }
625 684
626 if (R()->camera() != GL::EFreeCamera) 685 if (R()->camera() != GL::EFreeCamera)
627 { contextMenu->addSeparator(); 686 {
687 contextMenu->addSeparator();
628 contextMenu->addAction (ui->actionSetDrawDepth); 688 contextMenu->addAction (ui->actionSetDrawDepth);
629 } 689 }
630 690
631 contextMenu->exec (pos); 691 contextMenu->exec (pos);
632 } 692 }
633 693
634 // ============================================================================= 694 // =============================================================================
635 // TODO: what the heh? 695 // TODO: what the heh?
636 // ----------------------------------------------------------------------------- 696 // -----------------------------------------------------------------------------
637 void ForgeWindow::deleteObjects (QList<LDObject*> objs) 697 void ForgeWindow::deleteObjects (QList<LDObject*> objs)
638 { for (LDObject* obj : objs) 698 {
699 for (LDObject* obj : objs)
639 obj->deleteSelf(); 700 obj->deleteSelf();
640 } 701 }
641 702
642 // ============================================================================= 703 // =============================================================================
643 // ----------------------------------------------------------------------------- 704 // -----------------------------------------------------------------------------
644 void ForgeWindow::deleteByColor (const int colnum) 705 void ForgeWindow::deleteByColor (const int colnum)
645 { QList<LDObject*> objs; 706 {
707 QList<LDObject*> objs;
646 708
647 for (LDObject* obj : getCurrentDocument()->getObjects()) 709 for (LDObject* obj : getCurrentDocument()->getObjects())
648 { if (!obj->isColored() || obj->getColor() != colnum) 710 {
711 if (!obj->isColored() || obj->getColor() != colnum)
649 continue; 712 continue;
650 713
651 objs << obj; 714 objs << obj;
652 } 715 }
653 716
655 } 718 }
656 719
657 // ============================================================================= 720 // =============================================================================
658 // ----------------------------------------------------------------------------- 721 // -----------------------------------------------------------------------------
659 void ForgeWindow::updateEditModeActions() 722 void ForgeWindow::updateEditModeActions()
660 { const EditMode mode = R()->getEditMode(); 723 {
724 const EditMode mode = R()->getEditMode();
661 ui->actionModeSelect->setChecked (mode == ESelectMode); 725 ui->actionModeSelect->setChecked (mode == ESelectMode);
662 ui->actionModeDraw->setChecked (mode == EDrawMode); 726 ui->actionModeDraw->setChecked (mode == EDrawMode);
663 ui->actionModeCircle->setChecked (mode == ECircleMode); 727 ui->actionModeCircle->setChecked (mode == ECircleMode);
664 } 728 }
665 729
666 // ============================================================================= 730 // =============================================================================
667 // ----------------------------------------------------------------------------- 731 // -----------------------------------------------------------------------------
668 void ForgeWindow::slot_editObject (QListWidgetItem* listitem) 732 void ForgeWindow::slot_editObject (QListWidgetItem* listitem)
669 { LDObject* obj = null; 733 {
734 LDObject* obj = null;
670 735
671 for (LDObject* it : getCurrentDocument()->getObjects()) 736 for (LDObject* it : getCurrentDocument()->getObjects())
672 { if (it->qObjListEntry == listitem) 737 {
673 { obj = it; 738 if (it->qObjListEntry == listitem)
739 {
740 obj = it;
674 break; 741 break;
675 } 742 }
676 } 743 }
677 744
678 AddObjectDialog::staticDialog (obj->getType(), obj); 745 AddObjectDialog::staticDialog (obj->getType(), obj);
680 747
681 #if 0 748 #if 0
682 // ============================================================================= 749 // =============================================================================
683 // ----------------------------------------------------------------------------- 750 // -----------------------------------------------------------------------------
684 void ForgeWindow::primitiveLoaderStart (int max) 751 void ForgeWindow::primitiveLoaderStart (int max)
685 { m_primLoaderWidget->show(); 752 {
753 m_primLoaderWidget->show();
686 m_primLoaderBar->setRange (0, max); 754 m_primLoaderBar->setRange (0, max);
687 m_primLoaderBar->setValue (0); 755 m_primLoaderBar->setValue (0);
688 m_primLoaderBar->setFormat ("%p%"); 756 m_primLoaderBar->setFormat ("%p%");
689 } 757 }
690 758
691 // ============================================================================= 759 // =============================================================================
692 // ----------------------------------------------------------------------------- 760 // -----------------------------------------------------------------------------
693 void ForgeWindow::primitiveLoaderUpdate (int prog) 761 void ForgeWindow::primitiveLoaderUpdate (int prog)
694 { m_primLoaderBar->setValue (prog); 762 {
763 m_primLoaderBar->setValue (prog);
695 } 764 }
696 765
697 // ============================================================================= 766 // =============================================================================
698 // ----------------------------------------------------------------------------- 767 // -----------------------------------------------------------------------------
699 void ForgeWindow::primitiveLoaderEnd() 768 void ForgeWindow::primitiveLoaderEnd()
700 { QTimer* hidetimer = new QTimer; 769 {
770 QTimer* hidetimer = new QTimer;
701 connect (hidetimer, SIGNAL (timeout()), m_primLoaderWidget, SLOT (hide())); 771 connect (hidetimer, SIGNAL (timeout()), m_primLoaderWidget, SLOT (hide()));
702 hidetimer->setSingleShot (true); 772 hidetimer->setSingleShot (true);
703 hidetimer->start (1500); 773 hidetimer->start (1500);
704 m_primLoaderBar->setFormat (tr ("Done")); 774 m_primLoaderBar->setFormat (tr ("Done"));
705 log (tr ("Primitives scanned: %1 primitives listed"), m_primLoaderBar->value()); 775 log (tr ("Primitives scanned: %1 primitives listed"), m_primLoaderBar->value());
707 #endif 777 #endif
708 778
709 // ============================================================================= 779 // =============================================================================
710 // ----------------------------------------------------------------------------- 780 // -----------------------------------------------------------------------------
711 bool ForgeWindow::save (LDDocument* f, bool saveAs) 781 bool ForgeWindow::save (LDDocument* f, bool saveAs)
712 { str path = f->getFullPath(); 782 {
783 str path = f->getFullPath();
713 784
714 if (saveAs || path.isEmpty()) 785 if (saveAs || path.isEmpty())
715 { str name = f->getDefaultName(); 786 {
787 str name = f->getDefaultName();
716 788
717 if (!f->getFullPath().isEmpty()) 789 if (!f->getFullPath().isEmpty())
718 name = f->getFullPath(); 790 name = f->getFullPath();
719 elif (!f->getName().isEmpty()) 791 elif (!f->getName().isEmpty())
720 name = f->getName(); 792 name = f->getName();
722 name.replace ("\\", "/"); 794 name.replace ("\\", "/");
723 path = QFileDialog::getSaveFileName (g_win, tr ("Save As"), 795 path = QFileDialog::getSaveFileName (g_win, tr ("Save As"),
724 name, tr ("LDraw files (*.dat *.ldr)")); 796 name, tr ("LDraw files (*.dat *.ldr)"));
725 797
726 if (path.isEmpty()) 798 if (path.isEmpty())
727 { // User didn't give a file name, abort. 799 {
800 // User didn't give a file name, abort.
728 return false; 801 return false;
729 } 802 }
730 } 803 }
731 804
732 if (f->save (path)) 805 if (f->save (path))
733 { if (f == getCurrentDocument()) 806 {
807 if (f == getCurrentDocument())
734 updateTitle(); 808 updateTitle();
735 809
736 log ("Saved to %1.", path); 810 log ("Saved to %1.", path);
737 811
738 // Add it to recent files 812 // Add it to recent files
757 831
758 return false; 832 return false;
759 } 833 }
760 834
761 void ForgeWindow::addMessage (str msg) 835 void ForgeWindow::addMessage (str msg)
762 { m_msglog->addLine (msg); 836 {
837 m_msglog->addLine (msg);
763 } 838 }
764 839
765 // ============================================================================ 840 // ============================================================================
766 void ObjectList::contextMenuEvent (QContextMenuEvent* ev) 841 void ObjectList::contextMenuEvent (QContextMenuEvent* ev)
767 { g_win->spawnContextMenu (ev->globalPos()); 842 {
843 g_win->spawnContextMenu (ev->globalPos());
768 } 844 }
769 845
770 // ============================================================================= 846 // =============================================================================
771 // ----------------------------------------------------------------------------- 847 // -----------------------------------------------------------------------------
772 QPixmap getIcon (str iconName) 848 QPixmap getIcon (str iconName)
773 { return (QPixmap (fmt (":/icons/%1.png", iconName))); 849 {
850 return (QPixmap (fmt (":/icons/%1.png", iconName)));
774 } 851 }
775 852
776 // ============================================================================= 853 // =============================================================================
777 bool confirm (str msg) 854 bool confirm (str msg)
778 { return confirm (ForgeWindow::tr ("Confirm"), msg); 855 {
856 return confirm (ForgeWindow::tr ("Confirm"), msg);
779 } 857 }
780 858
781 bool confirm (str title, str msg) 859 bool confirm (str title, str msg)
782 { return QMessageBox::question (g_win, title, msg, 860 {
861 return QMessageBox::question (g_win, title, msg,
783 (QMessageBox::Yes | QMessageBox::No), QMessageBox::No) == QMessageBox::Yes; 862 (QMessageBox::Yes | QMessageBox::No), QMessageBox::No) == QMessageBox::Yes;
784 } 863 }
785 864
786 // ============================================================================= 865 // =============================================================================
787 void critical (str msg) 866 void critical (str msg)
788 { QMessageBox::critical (g_win, ForgeWindow::tr ("Error"), msg, 867 {
868 QMessageBox::critical (g_win, ForgeWindow::tr ("Error"), msg,
789 (QMessageBox::Close), QMessageBox::Close); 869 (QMessageBox::Close), QMessageBox::Close);
790 } 870 }
791 871
792 // ============================================================================= 872 // =============================================================================
793 QIcon makeColorIcon (LDColor* colinfo, const int size) 873 QIcon makeColorIcon (LDColor* colinfo, const int size)
794 { // Create an image object and link a painter to it. 874 {
875 // Create an image object and link a painter to it.
795 QImage img (size, size, QImage::Format_ARGB32); 876 QImage img (size, size, QImage::Format_ARGB32);
796 QPainter paint (&img); 877 QPainter paint (&img);
797 QColor col = colinfo->faceColor; 878 QColor col = colinfo->faceColor;
798 879
799 if (colinfo->index == maincolor) 880 if (colinfo->index == maincolor)
800 { // Use the user preferences for main color here 881 {
882 // Use the user preferences for main color here
801 col = gl_maincolor; 883 col = gl_maincolor;
802 col.setAlphaF (gl_maincolor_alpha); 884 col.setAlphaF (gl_maincolor_alpha);
803 } 885 }
804 886
805 // Paint the icon border 887 // Paint the icon border
813 return QIcon (QPixmap::fromImage (img)); 895 return QIcon (QPixmap::fromImage (img));
814 } 896 }
815 897
816 // ============================================================================= 898 // =============================================================================
817 void makeColorComboBox (QComboBox* box) 899 void makeColorComboBox (QComboBox* box)
818 { std::map<int, int> counts; 900 {
901 std::map<int, int> counts;
819 902
820 for (LDObject* obj : getCurrentDocument()->getObjects()) 903 for (LDObject* obj : getCurrentDocument()->getObjects())
821 { if (!obj->isColored()) 904 {
905 if (!obj->isColored())
822 continue; 906 continue;
823 907
824 if (counts.find (obj->getColor()) == counts.end()) 908 if (counts.find (obj->getColor()) == counts.end())
825 counts[obj->getColor()] = 1; 909 counts[obj->getColor()] = 1;
826 else 910 else
829 913
830 box->clear(); 914 box->clear();
831 int row = 0; 915 int row = 0;
832 916
833 for (const auto& pair : counts) 917 for (const auto& pair : counts)
834 { LDColor* col = getColor (pair.first); 918 {
919 LDColor* col = getColor (pair.first);
835 assert (col != null); 920 assert (col != null);
836 921
837 QIcon ico = makeColorIcon (col, 16); 922 QIcon ico = makeColorIcon (col, 16);
838 box->addItem (ico, fmt ("[%1] %2 (%3 object%4)", 923 box->addItem (ico, fmt ("[%1] %2 (%3 object%4)",
839 pair.first, col->name, pair.second, plural (pair.second))); 924 pair.first, col->name, pair.second, plural (pair.second)));
842 ++row; 927 ++row;
843 } 928 }
844 } 929 }
845 930
846 void ForgeWindow::setStatusBarText (str text) 931 void ForgeWindow::setStatusBarText (str text)
847 { statusBar()->showMessage (text); 932 {
933 statusBar()->showMessage (text);
848 } 934 }
849 935
850 Ui_LDForgeUI* ForgeWindow::getInterface() const 936 Ui_LDForgeUI* ForgeWindow::getInterface() const
851 { return ui; 937 {
938 return ui;
852 } 939 }
853 940
854 void ForgeWindow::updateDocumentList() 941 void ForgeWindow::updateDocumentList()
855 { ui->fileList->clear(); 942 {
943 ui->fileList->clear();
856 944
857 for (LDDocument* f : g_loadedFiles) 945 for (LDDocument* f : g_loadedFiles)
858 { // Don't list implicit files unless explicitly desired. 946 {
947 // Don't list implicit files unless explicitly desired.
859 if (f->isImplicit() && !gui_implicitfiles) 948 if (f->isImplicit() && !gui_implicitfiles)
860 continue; 949 continue;
861 950
862 // Add an item to the list for this file and store a pointer to it in 951 // Add an item to the list for this file and store a pointer to it in
863 // the file, so we can find files by the list item. 952 // the file, so we can find files by the list item.
867 updateDocumentListItem (f); 956 updateDocumentListItem (f);
868 } 957 }
869 } 958 }
870 959
871 void ForgeWindow::updateDocumentListItem (LDDocument* f) 960 void ForgeWindow::updateDocumentListItem (LDDocument* f)
872 { if (f->getListItem() == null) 961 {
873 { // We don't have a list item for this file, so the list either doesn't 962 if (f->getListItem() == null)
963 {
964 // We don't have a list item for this file, so the list either doesn't
874 // exist yet or is out of date. Build the list now. 965 // exist yet or is out of date. Build the list now.
875 updateDocumentList(); 966 updateDocumentList();
876 return; 967 return;
877 } 968 }
878 969
894 985
895 // ============================================================================= 986 // =============================================================================
896 // A file is selected from the list of files on the left of the screen. Find out 987 // A file is selected from the list of files on the left of the screen. Find out
897 // which file was picked and change to it. 988 // which file was picked and change to it.
898 void ForgeWindow::changeCurrentFile() 989 void ForgeWindow::changeCurrentFile()
899 { LDDocument* f = null; 990 {
991 LDDocument* f = null;
900 QListWidgetItem* item = ui->fileList->currentItem(); 992 QListWidgetItem* item = ui->fileList->currentItem();
901 993
902 // Find the file pointer of the item that was selected. 994 // Find the file pointer of the item that was selected.
903 for (LDDocument* it : g_loadedFiles) 995 for (LDDocument* it : g_loadedFiles)
904 { if (it->getListItem() == item) 996 {
905 { f = it; 997 if (it->getListItem() == item)
998 {
999 f = it;
906 break; 1000 break;
907 } 1001 }
908 } 1002 }
909 1003
910 // If we picked the same file we're currently on, we don't need to do 1004 // If we picked the same file we're currently on, we don't need to do
928 1022
929 buildObjList(); 1023 buildObjList();
930 } 1024 }
931 1025
932 void ForgeWindow::updateActions() 1026 void ForgeWindow::updateActions()
933 { History* his = getCurrentDocument()->getHistory(); 1027 {
1028 History* his = getCurrentDocument()->getHistory();
934 int pos = his->getPosition(); 1029 int pos = his->getPosition();
935 ui->actionUndo->setEnabled (pos != -1); 1030 ui->actionUndo->setEnabled (pos != -1);
936 ui->actionRedo->setEnabled (pos < (long) his->getSize() - 1); 1031 ui->actionRedo->setEnabled (pos < (long) his->getSize() - 1);
937 ui->actionAxes->setChecked (gl_axes); 1032 ui->actionAxes->setChecked (gl_axes);
938 ui->actionBFCView->setChecked (gl_colorbfc); 1033 ui->actionBFCView->setChecked (gl_colorbfc);
939 ui->actionDrawAngles->setChecked (gl_drawangles); 1034 ui->actionDrawAngles->setChecked (gl_drawangles);
940 } 1035 }
941 1036
942 QImage imageFromScreencap (uchar* data, int w, int h) 1037 QImage imageFromScreencap (uchar* data, int w, int h)
943 { // GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well. 1038 {
1039 // GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well.
944 return QImage (data, w, h, QImage::Format_ARGB32).rgbSwapped().mirrored(); 1040 return QImage (data, w, h, QImage::Format_ARGB32).rgbSwapped().mirrored();
945 } 1041 }
946 1042
947 // ============================================================================= 1043 // =============================================================================
948 // ----------------------------------------------------------------------------- 1044 // -----------------------------------------------------------------------------
949 LDQuickColor::LDQuickColor (LDColor* color, QToolButton* toolButton) : 1045 LDQuickColor::LDQuickColor (LDColor* color, QToolButton* toolButton) :
950 m_Color (color), 1046 m_Color (color),
951 m_ToolButton (toolButton) {} 1047 m_ToolButton (toolButton) {}
952 1048
953 LDQuickColor LDQuickColor::getSeparator() 1049 LDQuickColor LDQuickColor::getSeparator()
954 { return LDQuickColor (null, null); 1050 {
1051 return LDQuickColor (null, null);
955 } 1052 }
956 1053
957 bool LDQuickColor::isSeparator() const 1054 bool LDQuickColor::isSeparator() const
958 { return getColor() == null; 1055 {
959 } 1056 return getColor() == null;
1057 }

mercurial