193 for (LDQuickColor & entry : m_quickColors) |
193 for (LDQuickColor & entry : m_quickColors) |
194 { if (entry.isSeparator()) |
194 { if (entry.isSeparator()) |
195 ui->colorToolbar->addSeparator(); |
195 ui->colorToolbar->addSeparator(); |
196 else |
196 else |
197 { QToolButton* colorButton = new QToolButton; |
197 { QToolButton* colorButton = new QToolButton; |
198 colorButton->setIcon (makeColorIcon (entry.color(), 22)); |
198 colorButton->setIcon (makeColorIcon (entry.getColor(), 22)); |
199 colorButton->setIconSize (QSize (22, 22)); |
199 colorButton->setIconSize (QSize (22, 22)); |
200 colorButton->setToolTip (entry.color()->name); |
200 colorButton->setToolTip (entry.getColor()->name); |
201 |
201 |
202 connect (colorButton, SIGNAL (clicked()), this, SLOT (slot_quickColor())); |
202 connect (colorButton, SIGNAL (clicked()), this, SLOT (slot_quickColor())); |
203 ui->colorToolbar->addWidget (colorButton); |
203 ui->colorToolbar->addWidget (colorButton); |
204 m_colorButtons << colorButton; |
204 m_colorButtons << colorButton; |
205 |
205 |
224 void ForgeWindow::updateTitle() |
224 void ForgeWindow::updateTitle() |
225 { str title = fmt (APPNAME " %1", fullVersionString()); |
225 { str title = fmt (APPNAME " %1", fullVersionString()); |
226 |
226 |
227 // Append our current file if we have one |
227 // Append our current file if we have one |
228 if (LDFile::current()) |
228 if (LDFile::current()) |
229 { if (LDFile::current()->name().length() > 0) |
229 { if (LDFile::current()->getName().length() > 0) |
230 title += fmt (": %1", basename (LDFile::current()->name())); |
230 title += fmt (": %1", basename (LDFile::current()->getName())); |
231 else |
231 else |
232 title += fmt (": <anonymous>"); |
232 title += fmt (": <anonymous>"); |
233 |
233 |
234 if (LDFile::current()->getObjectCount() > 0 && |
234 if (LDFile::current()->getObjectCount() > 0 && |
235 LDFile::current()->getObject (0)->getType() == LDObject::Comment) |
235 LDFile::current()->getObject (0)->getType() == LDObject::Comment) |
236 { // Append title |
236 { // Append title |
237 LDComment* comm = static_cast<LDComment*> (LDFile::current()->getObject (0)); |
237 LDComment* comm = static_cast<LDComment*> (LDFile::current()->getObject (0)); |
238 title += fmt (": %1", comm->text); |
238 title += fmt (": %1", comm->text); |
239 } |
239 } |
240 |
240 |
241 if (LDFile::current()->history().pos() != LDFile::current()->savePos()) |
241 if (LDFile::current()->getHistory()->getPosition() != LDFile::current()->getSavePosition()) |
242 title += '*'; |
242 title += '*'; |
243 } |
243 } |
244 |
244 |
245 #ifdef DEBUG |
245 #ifdef DEBUG |
246 title += " [debug build]"; |
246 title += " [debug build]"; |
281 for (int i = 0; i < ui->objectList->count(); ++i) |
281 for (int i = 0; i < ui->objectList->count(); ++i) |
282 delete ui->objectList->item (i); |
282 delete ui->objectList->item (i); |
283 |
283 |
284 ui->objectList->clear(); |
284 ui->objectList->clear(); |
285 |
285 |
286 for (LDObject* obj : LDFile::current()->objects()) |
286 for (LDObject* obj : LDFile::current()->getObjects()) |
287 { str descr; |
287 { str descr; |
288 |
288 |
289 switch (obj->getType()) |
289 switch (obj->getType()) |
290 { case LDObject::Comment: |
290 { case LDObject::Comment: |
291 { descr = static_cast<LDComment*> (obj)->text; |
291 { descr = static_cast<LDComment*> (obj)->text; |
319 } break; |
319 } break; |
320 |
320 |
321 case LDObject::Subfile: |
321 case LDObject::Subfile: |
322 { LDSubfile* ref = static_cast<LDSubfile*> (obj); |
322 { LDSubfile* ref = static_cast<LDSubfile*> (obj); |
323 |
323 |
324 descr = fmt ("%1 %2, (", ref->fileInfo()->name(), ref->position().stringRep (true)); |
324 descr = fmt ("%1 %2, (", ref->getFileInfo()->getName(), ref->position().stringRep (true)); |
325 |
325 |
326 for (int i = 0; i < 9; ++i) |
326 for (int i = 0; i < 9; ++i) |
327 descr += fmt ("%1%2", ref->transform()[i], (i != 8) ? " " : ""); |
327 descr += fmt ("%1%2", ref->getTransform()[i], (i != 8) ? " " : ""); |
328 |
328 |
329 descr += ')'; |
329 descr += ')'; |
330 } break; |
330 } break; |
331 |
331 |
332 case LDObject::BFC: |
332 case LDObject::BFC: |
333 { descr = LDBFC::statements[static_cast<LDBFC*> (obj)->type]; |
333 { descr = LDBFC::statements[static_cast<LDBFC*> (obj)->type]; |
334 } break; |
334 } break; |
335 |
335 |
336 case LDObject::Overlay: |
336 case LDObject::Overlay: |
337 { LDOverlay* ovl = static_cast<LDOverlay*> (obj); |
337 { LDOverlay* ovl = static_cast<LDOverlay*> (obj); |
338 descr = fmt ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->camera()], |
338 descr = fmt ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->getCamera()], |
339 basename (ovl->filename()), ovl->x(), ovl->y(), ovl->width(), ovl->height()); |
339 basename (ovl->getFileName()), ovl->getX(), ovl->getY(), |
|
340 ovl->getWidth(), ovl->getHeight()); |
340 } |
341 } |
341 break; |
342 break; |
342 |
343 |
343 default: |
344 default: |
344 { descr = obj->getTypeName(); |
345 { descr = obj->getTypeName(); |
347 |
348 |
348 QListWidgetItem* item = new QListWidgetItem (descr); |
349 QListWidgetItem* item = new QListWidgetItem (descr); |
349 item->setIcon (getIcon (obj->getTypeName())); |
350 item->setIcon (getIcon (obj->getTypeName())); |
350 |
351 |
351 // Use italic font if hidden |
352 // Use italic font if hidden |
352 if (obj->hidden()) |
353 if (obj->isHidden()) |
353 { QFont font = item->font(); |
354 { QFont font = item->font(); |
354 font.setItalic (true); |
355 font.setItalic (true); |
355 item->setFont (font); |
356 item->setFont (font); |
356 } |
357 } |
357 |
358 |
358 // Color gibberish orange on red so it stands out. |
359 // Color gibberish orange on red so it stands out. |
359 if (obj->getType() == LDObject::Error) |
360 if (obj->getType() == LDObject::Error) |
360 { item->setBackground (QColor ("#AA0000")); |
361 { item->setBackground (QColor ("#AA0000")); |
361 item->setForeground (QColor ("#FFAA00")); |
362 item->setForeground (QColor ("#FFAA00")); |
362 } |
363 } |
363 elif (lv_colorize && obj->isColored() && obj->color() != maincolor && obj->color() != edgecolor) |
364 elif (lv_colorize && obj->isColored() && obj->getColor() != maincolor && obj->getColor() != edgecolor) |
364 { // If the object isn't in the main or edge color, draw this |
365 { // If the object isn't in the main or edge color, draw this |
365 // list entry in said color. |
366 // list entry in said color. |
366 LDColor* col = getColor (obj->color()); |
367 LDColor* col = getColor (obj->getColor()); |
367 |
368 |
368 if (col) |
369 if (col) |
369 item->setForeground (col->faceColor); |
370 item->setForeground (col->faceColor); |
370 } |
371 } |
371 |
372 |
395 return; |
396 return; |
396 |
397 |
397 // Update the shared selection array, though don't do this if this was |
398 // Update the shared selection array, though don't do this if this was |
398 // called during GL picking, in which case the GL renderer takes care |
399 // called during GL picking, in which case the GL renderer takes care |
399 // of the selection. |
400 // of the selection. |
400 if (m_renderer->picking()) |
401 if (m_renderer->isPicking()) |
401 return; |
402 return; |
402 |
403 |
403 QList<LDObject*> priorSelection = selection(); |
404 QList<LDObject*> priorSelection = selection(); |
404 |
405 |
405 // Get the objects from the object list selection |
406 // Get the objects from the object list selection |
406 LDFile::current()->clearSelection(); |
407 LDFile::current()->clearSelection(); |
407 const QList<QListWidgetItem*> items = ui->objectList->selectedItems(); |
408 const QList<QListWidgetItem*> items = ui->objectList->selectedItems(); |
408 |
409 |
409 for (LDObject* obj : LDFile::current()->objects()) |
410 for (LDObject* obj : LDFile::current()->getObjects()) |
410 { for (QListWidgetItem* item : items) |
411 { for (QListWidgetItem* item : items) |
411 { if (item == obj->qObjListEntry) |
412 { if (item == obj->qObjListEntry) |
412 { obj->select(); |
413 { obj->select(); |
413 break; |
414 break; |
414 } |
415 } |
491 // ============================================================================= |
492 // ============================================================================= |
492 // ----------------------------------------------------------------------------- |
493 // ----------------------------------------------------------------------------- |
493 void ForgeWindow::updateSelection() |
494 void ForgeWindow::updateSelection() |
494 { g_isSelectionLocked = true; |
495 { g_isSelectionLocked = true; |
495 |
496 |
496 for (LDObject* obj : LDFile::current()->objects()) |
497 for (LDObject* obj : LDFile::current()->getObjects()) |
497 obj->setSelected (false); |
498 obj->setSelected (false); |
498 |
499 |
499 ui->objectList->clearSelection(); |
500 ui->objectList->clearSelection(); |
500 |
501 |
501 for (LDObject* obj : selection()) |
502 for (LDObject* obj : selection()) |
517 |
518 |
518 for (LDObject* obj : selection()) |
519 for (LDObject* obj : selection()) |
519 { if (obj->isColored() == false) |
520 { if (obj->isColored() == false) |
520 continue; // doesn't use color |
521 continue; // doesn't use color |
521 |
522 |
522 if (result != -1 && obj->color() != result) |
523 if (result != -1 && obj->getColor() != result) |
523 return -1; // No consensus in object color |
524 return -1; // No consensus in object color |
524 |
525 |
525 if (result == -1) |
526 if (result == -1) |
526 result = obj->color(); |
527 result = obj->getColor(); |
527 } |
528 } |
528 |
529 |
529 return result; |
530 return result; |
530 } |
531 } |
531 |
532 |
533 // ----------------------------------------------------------------------------- |
534 // ----------------------------------------------------------------------------- |
534 LDObject::Type ForgeWindow::getUniformSelectedType() |
535 LDObject::Type ForgeWindow::getUniformSelectedType() |
535 { LDObject::Type result = LDObject::Unidentified; |
536 { LDObject::Type result = LDObject::Unidentified; |
536 |
537 |
537 for (LDObject * obj : selection()) |
538 for (LDObject * obj : selection()) |
538 { if (result != LDObject::Unidentified && obj->color() != result) |
539 { if (result != LDObject::Unidentified && obj->getColor() != result) |
539 return LDObject::Unidentified; |
540 return LDObject::Unidentified; |
540 |
541 |
541 if (result == LDObject::Unidentified) |
542 if (result == LDObject::Unidentified) |
542 result = obj->getType(); |
543 result = obj->getType(); |
543 } |
544 } |
611 // ============================================================================= |
612 // ============================================================================= |
612 // ----------------------------------------------------------------------------- |
613 // ----------------------------------------------------------------------------- |
613 void ForgeWindow::deleteByColor (const int colnum) |
614 void ForgeWindow::deleteByColor (const int colnum) |
614 { QList<LDObject*> objs; |
615 { QList<LDObject*> objs; |
615 |
616 |
616 for (LDObject * obj : LDFile::current()->objects()) |
617 for (LDObject* obj : LDFile::current()->getObjects()) |
617 { if (!obj->isColored() || obj->color() != colnum) |
618 { if (!obj->isColored() || obj->getColor() != colnum) |
618 continue; |
619 continue; |
619 |
620 |
620 objs << obj; |
621 objs << obj; |
621 } |
622 } |
622 |
623 |
624 } |
625 } |
625 |
626 |
626 // ============================================================================= |
627 // ============================================================================= |
627 // ----------------------------------------------------------------------------- |
628 // ----------------------------------------------------------------------------- |
628 void ForgeWindow::updateEditModeActions() |
629 void ForgeWindow::updateEditModeActions() |
629 { const EditMode mode = R()->editMode(); |
630 { const EditMode mode = R()->getEditMode(); |
630 ACTION (ModeSelect)->setChecked (mode == Select); |
631 ACTION (ModeSelect)->setChecked (mode == Select); |
631 ACTION (ModeDraw)->setChecked (mode == Draw); |
632 ACTION (ModeDraw)->setChecked (mode == Draw); |
632 ACTION (ModeCircle)->setChecked (mode == CircleMode); |
633 ACTION (ModeCircle)->setChecked (mode == CircleMode); |
633 } |
634 } |
634 |
635 |
635 // ============================================================================= |
636 // ============================================================================= |
636 // ----------------------------------------------------------------------------- |
637 // ----------------------------------------------------------------------------- |
637 void ForgeWindow::slot_editObject (QListWidgetItem* listitem) |
638 void ForgeWindow::slot_editObject (QListWidgetItem* listitem) |
638 { LDObject* obj = null; |
639 { LDObject* obj = null; |
639 |
640 |
640 for (LDObject* it : LDFile::current()->objects()) |
641 for (LDObject* it : LDFile::current()->getObjects()) |
641 { if (it->qObjListEntry == listitem) |
642 { if (it->qObjListEntry == listitem) |
642 { obj = it; |
643 { obj = it; |
643 break; |
644 break; |
644 } |
645 } |
645 } |
646 } |
674 } |
675 } |
675 |
676 |
676 // ============================================================================= |
677 // ============================================================================= |
677 // ----------------------------------------------------------------------------- |
678 // ----------------------------------------------------------------------------- |
678 void ForgeWindow::save (LDFile* f, bool saveAs) |
679 void ForgeWindow::save (LDFile* f, bool saveAs) |
679 { str path = f->name(); |
680 { str path = f->getName(); |
680 |
681 |
681 if (saveAs || path.isEmpty()) |
682 if (saveAs || path.isEmpty()) |
682 { path = QFileDialog::getSaveFileName (g_win, tr ("Save As"), |
683 { path = QFileDialog::getSaveFileName (g_win, tr ("Save As"), |
683 (f->name().isEmpty()) ? f->name() : f->defaultName(), tr ("LDraw files (*.dat *.ldr)")); |
684 (f->getName().isEmpty()) ? f->getName() : f->getDefaultName(), |
|
685 tr ("LDraw files (*.dat *.ldr)")); |
684 |
686 |
685 if (path.isEmpty()) |
687 if (path.isEmpty()) |
686 { // User didn't give a file name, abort. |
688 { // User didn't give a file name, abort. |
687 return; |
689 return; |
688 } |
690 } |
768 paint.fillRect (QRect (1, 1, size - 2, size - 2), col); |
770 paint.fillRect (QRect (1, 1, size - 2, size - 2), col); |
769 return QIcon (QPixmap::fromImage (img)); |
771 return QIcon (QPixmap::fromImage (img)); |
770 } |
772 } |
771 |
773 |
772 // ============================================================================= |
774 // ============================================================================= |
773 void makeColorSelector (QComboBox* box) |
775 void makeColorComboBox (QComboBox* box) |
774 { std::map<int, int> counts; |
776 { std::map<int, int> counts; |
775 |
777 |
776 for (LDObject * obj : LDFile::current()->objects()) |
778 for (LDObject * obj : LDFile::current()->getObjects()) |
777 { if (!obj->isColored()) |
779 { if (!obj->isColored()) |
778 continue; |
780 continue; |
779 |
781 |
780 if (counts.find (obj->color()) == counts.end()) |
782 if (counts.find (obj->getColor()) == counts.end()) |
781 counts[obj->color()] = 1; |
783 counts[obj->getColor()] = 1; |
782 else |
784 else |
783 counts[obj->color()]++; |
785 counts[obj->getColor()]++; |
784 } |
786 } |
785 |
787 |
786 box->clear(); |
788 box->clear(); |
787 int row = 0; |
789 int row = 0; |
788 |
790 |
790 { LDColor* col = getColor (pair.first); |
792 { LDColor* col = getColor (pair.first); |
791 assert (col != null); |
793 assert (col != null); |
792 |
794 |
793 QIcon ico = makeColorIcon (col, 16); |
795 QIcon ico = makeColorIcon (col, 16); |
794 box->addItem (ico, fmt ("[%1] %2 (%3 object%4)", |
796 box->addItem (ico, fmt ("[%1] %2 (%3 object%4)", |
795 pair.first, col->name, pair.second, plural (pair.second))); |
797 pair.first, col->name, pair.second, plural (pair.second))); |
796 box->setItemData (row, pair.first); |
798 box->setItemData (row, pair.first); |
797 |
799 |
798 ++row; |
800 ++row; |
799 } |
801 } |
800 } |
802 } |
813 void ForgeWindow::updateFileList() |
815 void ForgeWindow::updateFileList() |
814 { ui->fileList->clear(); |
816 { ui->fileList->clear(); |
815 |
817 |
816 for (LDFile* f : g_loadedFiles) |
818 for (LDFile* f : g_loadedFiles) |
817 { // Don't list implicit files unless explicitly desired. |
819 { // Don't list implicit files unless explicitly desired. |
818 if (f->implicit() && !gui_implicitfiles) |
820 if (f->isImplicit() && !gui_implicitfiles) |
819 continue; |
821 continue; |
820 |
822 |
821 // Add an item to the list for this file and store a pointer to it in |
823 // Add an item to the list for this file and store a pointer to it in |
822 // the file, so we can find files by the list item. |
824 // the file, so we can find files by the list item. |
823 ui->fileList->addItem (""); |
825 ui->fileList->addItem (""); |
827 updateFileListItem (f); |
829 updateFileListItem (f); |
828 } |
830 } |
829 } |
831 } |
830 |
832 |
831 void ForgeWindow::updateFileListItem (LDFile* f) |
833 void ForgeWindow::updateFileListItem (LDFile* f) |
832 { if (f->listItem() == null) |
834 { if (f->getListItem() == null) |
833 { // We don't have a list item for this file, so the list either doesn't |
835 { // We don't have a list item for this file, so the list either doesn't |
834 // exist yet or is out of date. Build the list now. |
836 // exist yet or is out of date. Build the list now. |
835 updateFileList(); |
837 updateFileList(); |
836 return; |
838 return; |
837 } |
839 } |
838 |
840 |
839 // If this is the current file, it also needs to be the selected item on |
841 // If this is the current file, it also needs to be the selected item on |
840 // the list. |
842 // the list. |
841 if (f == LDFile::current()) |
843 if (f == LDFile::current()) |
842 ui->fileList->setCurrentItem (f->listItem()); |
844 ui->fileList->setCurrentItem (f->getListItem()); |
843 |
845 |
844 // If we list implicit files, draw them with a shade of gray to make them |
846 // If we list implicit files, draw them with a shade of gray to make them |
845 // distinct. |
847 // distinct. |
846 if (f->implicit()) |
848 if (f->isImplicit()) |
847 f->listItem()->setForeground (QColor (96, 96, 96)); |
849 f->getListItem()->setForeground (QColor (96, 96, 96)); |
848 |
850 |
849 f->listItem()->setText (f->getShortName()); |
851 f->getListItem()->setText (f->getShortName()); |
850 |
852 |
851 // If the file has unsaved changes, draw a little icon next to it to mark that. |
853 // If the file has unsaved changes, draw a little icon next to it to mark that. |
852 f->listItem()->setIcon (f->hasUnsavedChanges() ? getIcon ("file-save") : QIcon()); |
854 f->getListItem()->setIcon (f->hasUnsavedChanges() ? getIcon ("file-save") : QIcon()); |
853 } |
855 } |
854 |
856 |
855 void ForgeWindow::beginAction (QAction* act) |
857 void ForgeWindow::beginAction (QAction* act) |
856 { // Open the history so we can record the edits done during this action. |
858 { // Open the history so we can record the edits done during this action. |
857 if (act != ACTION (Undo) && act != ACTION (Redo) && act != ACTION (Open)) |
859 if (act == ACTION (Undo) || act == ACTION (Redo) || act == ACTION (Open)) |
858 LDFile::current()->openHistory(); |
860 LDFile::current()->getHistory()->setIgnoring (true); |
859 } |
861 } |
860 |
862 |
861 void ForgeWindow::endAction() |
863 void ForgeWindow::endAction() |
862 { // Close the history now. |
864 { // Close the history now. |
863 LDFile::current()->closeHistory(); |
865 LDFile::current()->addHistoryStep(); |
864 |
866 |
865 // Update the list item of the current file - we may need to draw an icon |
867 // Update the list item of the current file - we may need to draw an icon |
866 // now that marks it as having unsaved changes. |
868 // now that marks it as having unsaved changes. |
867 updateFileListItem (LDFile::current()); |
869 updateFileListItem (LDFile::current()); |
868 } |
870 } |
910 } |
912 } |
911 |
913 |
912 // ============================================================================= |
914 // ============================================================================= |
913 // ----------------------------------------------------------------------------- |
915 // ----------------------------------------------------------------------------- |
914 LDQuickColor::LDQuickColor (LDColor* color, QToolButton* toolButton) : |
916 LDQuickColor::LDQuickColor (LDColor* color, QToolButton* toolButton) : |
915 m_color (color), |
917 m_Color (color), |
916 m_toolButton (toolButton) {} |
918 m_ToolButton (toolButton) {} |
917 |
919 |
918 LDQuickColor LDQuickColor::getSeparator() |
920 LDQuickColor LDQuickColor::getSeparator() |
919 { return LDQuickColor (null, null); |
921 { return LDQuickColor (null, null); |
920 } |
922 } |
921 |
923 |
922 bool LDQuickColor::isSeparator() const |
924 bool LDQuickColor::isSeparator() const |
923 { return color() == null; |
925 { return getColor() == null; |
924 } |
926 } |