1 /* |
1 /* |
2 * LDForge: LDraw parts authoring CAD |
2 * LDForge: LDraw parts authoring CAD |
3 * Copyright (C) 2013 Santeri `arezey` Piippo |
3 * Copyright (C) 2013 Santeri Piippo |
4 * |
4 * |
5 * This program is free software: you can redistribute it and/or modify |
5 * This program is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License as published by |
6 * it under the terms of the GNU General Public License as published by |
7 * the Free Software Foundation, either version 3 of the License, or |
7 * the Free Software Foundation, either version 3 of the License, or |
8 * (at your option) any later version. |
8 * (at your option) any later version. |
77 cfg (bool, lv_colorize, true); |
77 cfg (bool, lv_colorize, true); |
78 cfg (int, gui_toolbar_iconsize, 24); |
78 cfg (int, gui_toolbar_iconsize, 24); |
79 cfg (str, gui_colortoolbar, "16:24:|:0:1:2:3:4:5:6:7"); |
79 cfg (str, gui_colortoolbar, "16:24:|:0:1:2:3:4:5:6:7"); |
80 extern_cfg (str, io_recentfiles); |
80 extern_cfg (str, io_recentfiles); |
81 |
81 |
82 // ============================================================================= |
82 // ========================================================================= // |
83 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
83 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
84 // ============================================================================= |
84 // ========================================================================= // |
85 ForgeWindow::ForgeWindow () { |
85 ForgeWindow::ForgeWindow () { |
86 R = new renderer; |
86 R = new renderer; |
87 |
87 |
88 qObjList = new QTreeWidget; |
88 qObjList = new QTreeWidget; |
89 qObjList->setHeaderHidden (true); |
89 qObjList->setHeaderHidden (true); |
118 setTitle (); |
118 setTitle (); |
119 setMinimumSize (320, 200); |
119 setMinimumSize (320, 200); |
120 resize (800, 600); |
120 resize (800, 600); |
121 } |
121 } |
122 |
122 |
123 // ============================================================================= |
123 // ========================================================================= // |
124 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
124 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
125 // ============================================================================= |
125 // ========================================================================= // |
126 void ForgeWindow::createMenuActions () { |
126 void ForgeWindow::createMenuActions () { |
127 // Create the actions based on stored meta. |
127 // Create the actions based on stored meta. |
128 for (actionmeta meta : g_ActionMeta) { |
128 for (actionmeta meta : g_ActionMeta) { |
129 QAction*& qAct = *meta.qAct; |
129 QAction*& qAct = *meta.qAct; |
130 qAct = new QAction (getIcon (meta.sIconName), meta.sDisplayName, this); |
130 qAct = new QAction (getIcon (meta.sIconName), meta.sDisplayName, this); |
145 act->setEnabled (false); |
145 act->setEnabled (false); |
146 |
146 |
147 History::updateActions (); |
147 History::updateActions (); |
148 } |
148 } |
149 |
149 |
150 // ============================================================================= |
150 // ========================================================================= // |
151 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
151 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
152 // ============================================================================= |
152 // ========================================================================= // |
153 void ForgeWindow::createMenus () { |
153 void ForgeWindow::createMenus () { |
154 qRecentFilesMenu = new QMenu (tr ("Open &Recent")); |
154 qRecentFilesMenu = new QMenu (tr ("Open &Recent")); |
155 qRecentFilesMenu->setIcon (getIcon ("open-recent")); |
155 qRecentFilesMenu->setIcon (getIcon ("open-recent")); |
156 updateRecentFilesMenu (); |
156 updateRecentFilesMenu (); |
157 |
157 |
223 qHelpMenu->addSeparator (); // ----- |
223 qHelpMenu->addSeparator (); // ----- |
224 qHelpMenu->addAction (ACTION_NAME (about)); // About |
224 qHelpMenu->addAction (ACTION_NAME (about)); // About |
225 qHelpMenu->addAction (ACTION_NAME (aboutQt)); // About Qt |
225 qHelpMenu->addAction (ACTION_NAME (aboutQt)); // About Qt |
226 } |
226 } |
227 |
227 |
228 // ============================================================================= |
228 // ========================================================================= // |
229 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
229 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
230 // ============================================================================= |
230 // ========================================================================= // |
231 void ForgeWindow::updateRecentFilesMenu () { |
231 void ForgeWindow::updateRecentFilesMenu () { |
232 // First, clear any items in the recent files menu |
232 // First, clear any items in the recent files menu |
233 for (QAction* qRecent : qaRecentFiles) |
233 for (QAction* qRecent : qaRecentFiles) |
234 delete qRecent; |
234 delete qRecent; |
235 qaRecentFiles.clear (); |
235 qaRecentFiles.clear (); |
244 qRecentFilesMenu->addAction (qRecent); |
244 qRecentFilesMenu->addAction (qRecent); |
245 qaRecentFiles.push_back (qRecent); |
245 qaRecentFiles.push_back (qRecent); |
246 } |
246 } |
247 } |
247 } |
248 |
248 |
249 // ============================================================================= |
249 // ========================================================================= // |
250 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
250 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
251 // ============================================================================= |
251 // ========================================================================= // |
252 #define ADD_TOOLBAR_ITEM(ACT) g_CurrentToolBar->addAction (ACTION_NAME (ACT)); |
252 #define ADD_TOOLBAR_ITEM(ACT) g_CurrentToolBar->addAction (ACTION_NAME (ACT)); |
253 static QToolBar* g_CurrentToolBar; |
253 static QToolBar* g_CurrentToolBar; |
254 static Qt::ToolBarArea g_ToolBarArea = Qt::TopToolBarArea; |
254 static Qt::ToolBarArea g_ToolBarArea = Qt::TopToolBarArea; |
255 |
255 |
256 void ForgeWindow::initSingleToolBar (const char* sName) { |
256 void ForgeWindow::initSingleToolBar (const char* sName) { |
313 ADD_TOOLBAR_ITEM (makeCornerVerts) |
313 ADD_TOOLBAR_ITEM (makeCornerVerts) |
314 |
314 |
315 updateToolBars (); |
315 updateToolBars (); |
316 } |
316 } |
317 |
317 |
318 // ============================================================================= |
318 // ========================================================================= // |
319 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
319 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
320 // ============================================================================= |
320 // ========================================================================= // |
321 std::vector<quickColorMetaEntry> parseQuickColorMeta () { |
321 std::vector<quickColorMetaEntry> parseQuickColorMeta () { |
322 std::vector<quickColorMetaEntry> meta; |
322 std::vector<quickColorMetaEntry> meta; |
323 |
323 |
324 for (str zColor : gui_colortoolbar.value / ":") { |
324 for (str zColor : gui_colortoolbar.value / ":") { |
325 if (zColor == "|") { |
325 if (zColor == "|") { |
326 meta.push_back ({nullptr, nullptr, true}); |
326 meta.push_back ({null, null, true}); |
327 } else { |
327 } else { |
328 color* col = getColor (atoi (zColor)); |
328 color* col = getColor (atoi (zColor)); |
329 meta.push_back ({col, nullptr, false}); |
329 meta.push_back ({col, null, false}); |
330 } |
330 } |
331 } |
331 } |
332 |
332 |
333 return meta; |
333 return meta; |
334 } |
334 } |
335 |
335 |
336 // ============================================================================= |
336 // ========================================================================= // |
337 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
337 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
338 // ============================================================================= |
338 // ========================================================================= // |
339 void ForgeWindow::updateToolBars () { |
339 void ForgeWindow::updateToolBars () { |
340 for (QToolBar* qBar : qaToolBars) |
340 for (QToolBar* qBar : qaToolBars) |
341 qBar->setIconSize (QSize (gui_toolbar_iconsize, gui_toolbar_iconsize)); |
341 qBar->setIconSize (QSize (gui_toolbar_iconsize, gui_toolbar_iconsize)); |
342 |
342 |
343 // Update the quick color toolbar. |
343 // Update the quick color toolbar. |
365 entry.btn = qColorButton; |
365 entry.btn = qColorButton; |
366 } |
366 } |
367 } |
367 } |
368 } |
368 } |
369 |
369 |
370 // ============================================================================= |
370 // ========================================================================= // |
371 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
371 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
372 // ============================================================================= |
372 // ========================================================================= // |
373 void ForgeWindow::setTitle () { |
373 void ForgeWindow::setTitle () { |
374 str zTitle = APPNAME_DISPLAY " v" VERSION_STRING; |
374 str zTitle = APPNAME_DISPLAY " v" VERSION_STRING; |
375 |
375 |
376 // Append our current file if we have one |
376 // Append our current file if we have one |
377 if (g_CurrentFile) { |
377 if (g_CurrentFile) { |
387 } |
387 } |
388 |
388 |
389 setWindowTitle (zTitle.chars()); |
389 setWindowTitle (zTitle.chars()); |
390 } |
390 } |
391 |
391 |
392 // ============================================================================= |
392 // ========================================================================= // |
393 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
393 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
394 // ============================================================================= |
394 // ========================================================================= // |
395 void ForgeWindow::slot_action () { |
395 void ForgeWindow::slot_action () { |
396 // Get the action that triggered this slot. |
396 // Get the action that triggered this slot. |
397 QAction* qAct = static_cast<QAction*> (sender ()); |
397 QAction* qAct = static_cast<QAction*> (sender ()); |
398 |
398 |
399 // Find the meta for the action. |
399 // Find the meta for the action. |
400 actionmeta* pMeta = nullptr; |
400 actionmeta* pMeta = null; |
401 |
401 |
402 for (actionmeta meta : g_ActionMeta) { |
402 for (actionmeta meta : g_ActionMeta) { |
403 if (*meta.qAct == qAct) { |
403 if (*meta.qAct == qAct) { |
404 pMeta = &meta; |
404 pMeta = &meta; |
405 break; |
405 break; |
413 |
413 |
414 // We have the meta, now call the handler. |
414 // We have the meta, now call the handler. |
415 (*pMeta->handler) (); |
415 (*pMeta->handler) (); |
416 } |
416 } |
417 |
417 |
418 // ============================================================================= |
418 // ========================================================================= // |
419 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
419 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
420 // ============================================================================= |
420 // ========================================================================= // |
421 void ForgeWindow::deleteSelection (vector<ulong>* ulapIndices, std::vector<LDObject*>* papObjects) { |
421 void ForgeWindow::deleteSelection (vector<ulong>* ulapIndices, std::vector<LDObject*>* papObjects) { |
422 vector<LDObject*> objs = getSelectedObjects (); |
422 vector<LDObject*> objs = getSelectedObjects (); |
423 |
423 |
424 // Delete the objects that were being selected |
424 // Delete the objects that were being selected |
425 for (LDObject* obj : objs) { |
425 for (LDObject* obj : objs) { |
537 default: |
537 default: |
538 zText = g_saObjTypeNames[obj->getType ()]; |
538 zText = g_saObjTypeNames[obj->getType ()]; |
539 break; |
539 break; |
540 } |
540 } |
541 |
541 |
542 QTreeWidgetItem* item = new QTreeWidgetItem ((QTreeWidget*) (nullptr), |
542 QTreeWidgetItem* item = new QTreeWidgetItem ((QTreeWidget*) (null), |
543 QStringList (zText.chars()), 0); |
543 QStringList (zText.chars()), 0); |
544 item->setIcon (0, QIcon (str::mkfmt ("icons/%s.png", g_saObjTypeIcons[obj->getType ()]).chars())); |
544 item->setIcon (0, QIcon (str::mkfmt ("icons/%s.png", g_saObjTypeIcons[obj->getType ()]).chars())); |
545 |
545 |
546 // Color gibberish red |
546 // Color gibberish red |
547 if (obj->getType() == OBJ_Gibberish) { |
547 if (obj->getType() == OBJ_Gibberish) { |
565 } |
565 } |
566 |
566 |
567 qObjList->insertTopLevelItems (0, qaItems); |
567 qObjList->insertTopLevelItems (0, qaItems); |
568 } |
568 } |
569 |
569 |
570 // ============================================================================= |
570 // ========================================================================= // |
571 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
571 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
572 // ============================================================================= |
572 // ========================================================================= // |
573 void ForgeWindow::slot_selectionChanged () { |
573 void ForgeWindow::slot_selectionChanged () { |
574 /* |
574 /* |
575 // If the selection isn't 1 exact, disable setting contents |
575 // If the selection isn't 1 exact, disable setting contents |
576 ACTION (setContents)->setEnabled (qObjList->selectedItems().size() == 1); |
576 ACTION (setContents)->setEnabled (qObjList->selectedItems().size() == 1); |
577 |
577 |
578 // If we have no selection, disable splitting quads |
578 // If we have no selection, disable splitting quads |
579 ACTION (splitQuads)->setEnabled (qObjList->selectedItems().size() > 0); |
579 ACTION (splitQuads)->setEnabled (qObjList->selectedItems().size() > 0); |
580 */ |
580 */ |
581 } |
581 } |
582 |
582 |
583 // ============================================================================= |
583 // ========================================================================= // |
584 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
584 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
585 // ============================================================================= |
585 // ========================================================================= // |
586 void ForgeWindow::slot_recentFile () { |
586 void ForgeWindow::slot_recentFile () { |
587 QAction* qAct = static_cast<QAction*> (sender ()); |
587 QAction* qAct = static_cast<QAction*> (sender ()); |
588 openMainFile (qAct->text ()); |
588 openMainFile (qAct->text ()); |
589 } |
589 } |
590 |
590 |
591 // ============================================================================= |
591 // ========================================================================= // |
592 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
592 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
593 // ============================================================================= |
593 // ========================================================================= // |
594 void ForgeWindow::slot_quickColor () { |
594 void ForgeWindow::slot_quickColor () { |
595 QPushButton* qBtn = static_cast<QPushButton*> (sender ()); |
595 QPushButton* qBtn = static_cast<QPushButton*> (sender ()); |
596 color* col = nullptr; |
596 color* col = null; |
597 |
597 |
598 for (quickColorMetaEntry entry : quickColorMeta) { |
598 for (quickColorMetaEntry entry : quickColorMeta) { |
599 if (entry.btn == qBtn) { |
599 if (entry.btn == qBtn) { |
600 col = entry.col; |
600 col = entry.col; |
601 break; |
601 break; |
602 } |
602 } |
603 } |
603 } |
604 |
604 |
605 if (col == nullptr) |
605 if (col == null) |
606 return; |
606 return; |
607 |
607 |
608 std::vector<ulong> ulaIndices; |
608 std::vector<ulong> ulaIndices; |
609 std::vector<short> daColors; |
609 std::vector<short> daColors; |
610 short dNewColor = col->index (); |
610 short dNewColor = col->index (); |
621 |
621 |
622 History::addEntry (new SetColorHistory (ulaIndices, daColors, dNewColor)); |
622 History::addEntry (new SetColorHistory (ulaIndices, daColors, dNewColor)); |
623 refresh (); |
623 refresh (); |
624 } |
624 } |
625 |
625 |
626 // ============================================================================= |
626 // ========================================================================= // |
627 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
627 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
628 // ============================================================================= |
628 // ========================================================================= // |
629 ulong ForgeWindow::getInsertionPoint () { |
629 ulong ForgeWindow::getInsertionPoint () { |
630 ulong ulIndex; |
630 ulong ulIndex; |
631 |
631 |
632 if (qObjList->selectedItems().size() == 1) { |
632 if (qObjList->selectedItems().size() == 1) { |
633 // If we have a selection, put the item after it. |
633 // If we have a selection, put the item after it. |
641 |
641 |
642 // Otherwise place the object at the end. |
642 // Otherwise place the object at the end. |
643 return g_CurrentFile->objects.size(); |
643 return g_CurrentFile->objects.size(); |
644 } |
644 } |
645 |
645 |
646 // ============================================================================= |
646 // ========================================================================= // |
647 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
647 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
648 // ============================================================================= |
648 // ========================================================================= // |
649 void ForgeWindow::refresh () { |
649 void ForgeWindow::refresh () { |
650 buildObjList (); |
650 buildObjList (); |
651 R->hardRefresh (); |
651 R->hardRefresh (); |
652 } |
652 } |
653 |
653 |
654 // ============================================================================= |
654 // ========================================================================= // |
655 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
655 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
656 // ============================================================================= |
656 // ========================================================================= // |
657 std::vector<LDObject*> ForgeWindow::getSelectedObjects () { |
657 std::vector<LDObject*> ForgeWindow::getSelectedObjects () { |
658 std::vector<LDObject*> objs; |
658 std::vector<LDObject*> objs; |
659 |
659 |
660 QList<QTreeWidgetItem*> const qaItems = qObjList->selectedItems(); |
660 QList<QTreeWidgetItem*> const qaItems = qObjList->selectedItems(); |
661 for (LDObject* obj : g_CurrentFile->objects) |
661 for (LDObject* obj : g_CurrentFile->objects) |
667 } |
667 } |
668 |
668 |
669 return objs; |
669 return objs; |
670 } |
670 } |
671 |
671 |
672 // ============================================================================= |
672 // ========================================================================= // |
673 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
673 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
674 // ============================================================================= |
674 // ========================================================================= // |
|
675 void ForgeWindow::updateSelection () { |
|
676 buildObjList (); |
|
677 |
|
678 for (LDObject* obj : paSelection) |
|
679 obj->qObjListEntry->setSelected (true); |
|
680 } |
|
681 |
|
682 // ========================================================================= // |
|
683 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // |
|
684 // ========================================================================= // |
675 QIcon getIcon (const char* sIconName) { |
685 QIcon getIcon (const char* sIconName) { |
676 return (QIcon (str::mkfmt ("./icons/%s.png", sIconName))); |
686 return (QIcon (str::mkfmt ("./icons/%s.png", sIconName))); |
677 } |
687 } |
678 |
688 |
679 // ============================================================================= |
689 // ========================================================================= // |
680 bool confirm (str zMessage) { |
690 bool confirm (str zMessage) { |
681 return QMessageBox::question (g_ForgeWindow, "Confirm", zMessage, |
691 return QMessageBox::question (g_ForgeWindow, "Confirm", zMessage, |
682 (QMessageBox::Yes | QMessageBox::No), QMessageBox::No) == QMessageBox::Yes; |
692 (QMessageBox::Yes | QMessageBox::No), QMessageBox::No) == QMessageBox::Yes; |
683 } |
693 } |