--- a/src/gui.cpp Mon Jul 15 14:43:29 2013 +0300 +++ b/src/gui.cpp Mon Jul 15 19:30:16 2013 +0300 @@ -47,9 +47,7 @@ #include "addObjectDialog.h" #include "messagelog.h" #include "config.h" - -actionmeta g_actionMeta[MAX_ACTIONS]; -static ushort g_metacursor = 0; +#include "ui_ldforge.h" static bool g_bSelectionLocked = false; @@ -71,255 +69,96 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -ForgeWindow::ForgeWindow () { +ForgeWindow::ForgeWindow() { g_win = this; m_renderer = new GLRenderer; - m_objList = new ObjectList; - m_objList->setSelectionMode (QListWidget::ExtendedSelection); - m_objList->setAlternatingRowColors (true); - connect (m_objList, SIGNAL (itemSelectionChanged ()), this, SLOT (slot_selectionChanged ())); - connect (m_objList, SIGNAL (itemDoubleClicked (QListWidgetItem*)), this, SLOT (slot_editObject (QListWidgetItem*))); + ui = new Ui_LDForgeUI; + ui->setupUi (this); - m_msglog = new MessageManager; - m_msglog->setRenderer( R() ); - m_renderer->setMessageLog( m_msglog ); + // Stuff the renderer into its frame + QVBoxLayout* rendererLayout = new QVBoxLayout (ui->rendererFrame); + rendererLayout->addWidget (R()); - m_splitter = new QSplitter; - m_splitter->addWidget (m_renderer); - m_splitter->addWidget (m_objList); - setCentralWidget (m_splitter); - - m_colorMeta = parseQuickColorMeta (); + connect (ui->objectList, SIGNAL (itemSelectionChanged()), this, SLOT (slot_selectionChanged())); + connect (ui->objectList, SIGNAL (itemDoubleClicked (QListWidgetItem*)), this, SLOT (slot_editObject (QListWidgetItem*))); - createMenuActions (); - createMenus (); - createToolbars (); - - slot_selectionChanged (); - + // Init message log manager + m_msglog = new MessageManager; + m_msglog->setRenderer (R()); + m_renderer->setMessageLog (m_msglog); + m_colorMeta = parseQuickColorMeta(); + slot_selectionChanged(); setStatusBar (new QStatusBar); + // Init primitive loader task stuff m_primLoaderBar = new QProgressBar; m_primLoaderWidget = new QWidget; QHBoxLayout* primLoaderLayout = new QHBoxLayout (m_primLoaderWidget); primLoaderLayout->addWidget (new QLabel ("Loading primitives:")); primLoaderLayout->addWidget (m_primLoaderBar); - statusBar ()->addPermanentWidget (m_primLoaderWidget); - m_primLoaderWidget->hide (); + statusBar()->addPermanentWidget (m_primLoaderWidget); + m_primLoaderWidget->hide(); - setWindowIcon (getIcon ("ldforge")); - updateTitle (); - setMinimumSize (320, 200); - resize (800, 600); + // Make certain actions checkable + ui->actionAxes->setChecked (gl_axes); + ui->actionWireframe->setChecked (gl_wireframe); + ui->actionBFCView->setChecked (gl_colorbfc); + updateGridToolBar(); + updateEditModeActions(); + updateRecentFilesMenu(); + updateToolBars(); + updateTitle(); - connect (qApp, SIGNAL (aboutToQuit ()), this, SLOT (slot_lastSecondCleanup ())); + setMinimumSize (300, 200); + + connect (qApp, SIGNAL (aboutToQuit()), this, SLOT (slot_lastSecondCleanup())); + + // Connect all actions +#define act(N) \ + connect (ui->action##N, SIGNAL (triggered()), this, SLOT (slot_action())); +#include "actions.h" } -// ============================================================================= -void ForgeWindow::slot_lastSecondCleanup () { - delete m_renderer; +void ForgeWindow::slot_action() { + // Find out which action triggered this +#define act(N) if (sender() == ui->action##N) invokeAction (ui->action##N, &actiondef_##N); +#include "actions.h" +} + +void ForgeWindow::invokeAction (QAction* act, void (*func) ()) { + // Open the history so we can record the edits done during this action. + if (act != ACTION (Undo) && act != ACTION (Redo) && act != ACTION (Open)) + currentFile()->openHistory(); + + // Invoke the function + (*func) (); + + // Close the history now. + currentFile()->closeHistory(); } // ============================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// ============================================================================= -void ForgeWindow::createMenuActions () { - // Create the actions based on stored meta. - for (actionmeta meta : g_actionMeta) { - if (meta.qAct == null) - break; - - QAction*& act = *meta.qAct; - act = new QAction (getIcon (meta.sIconName), meta.sDisplayName, this); - act->setStatusTip (meta.sDescription); - act->setShortcut (*meta.conf); - - connect (act, SIGNAL (triggered ()), this, SLOT (slot_action ())); - } - - // Make certain actions checkable - findAction ("gridCoarse")->setCheckable (true); - findAction ("gridMedium")->setCheckable (true); - findAction ("gridFine")->setCheckable (true); - - findAction ("axes")->setCheckable (true); - findAction ("axes")->setChecked (gl_axes); - - findAction ("wireframe")->setCheckable (true); - findAction ("wireframe")->setChecked (gl_wireframe); - - findAction ("colorbfc")->setCheckable (true); - findAction ("colorbfc")->setChecked (gl_colorbfc); - - updateEditModeActions (); - - // things not implemented yet - findAction ("help")->setEnabled (false); +void ForgeWindow::slot_lastSecondCleanup() { + delete m_renderer; + delete ui; } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -QMenu* g_CurrentMenu; - -QMenu* ForgeWindow::initMenu (const char* name) { - return g_CurrentMenu = menuBar ()->addMenu (tr (name)); -} - -void ForgeWindow::addMenuAction (const char* name) { - g_CurrentMenu->addAction (findAction (name)); -} - - -// ============================================================================= -void ForgeWindow::createMenus () { - m_recentFilesMenu = new QMenu (tr ("Open &Recent")); - m_recentFilesMenu->setIcon (getIcon ("open-recent")); - updateRecentFilesMenu (); - - QMenu*& menu = g_CurrentMenu; - - // File menu - initMenu ("&File"); - addMenuAction ("newFile"); - addMenuAction ("open"); - menu->addMenu (m_recentFilesMenu); - addMenuAction ("save"); - addMenuAction ("saveAs"); - menu->addSeparator (); - addMenuAction ("insertFrom"); - addMenuAction ("exportTo"); - menu->addSeparator (); - addMenuAction ("settings"); - addMenuAction ("setLDrawPath"); - menu->addSeparator (); -#ifndef RELEASE - addMenuAction ("testpic"); -#endif - addMenuAction ("reloadPrimitives"); - menu->addSeparator (); - addMenuAction ("exit"); - - // View menu - initMenu ("&View"); - addMenuAction ("resetView"); - addMenuAction ("axes"); - addMenuAction ("wireframe"); - addMenuAction ("colorbfc"); - menu->addSeparator (); - addMenuAction ("setOverlay"); - addMenuAction ("clearOverlay"); - menu->addSeparator (); - addMenuAction ("screencap"); - - // Insert menu - initMenu ("&Insert"); - addMenuAction ("insertRaw"); - menu->addSeparator (); - addMenuAction ("newSubfile"); - addMenuAction ("newLine"); - addMenuAction ("newTriangle"); - addMenuAction ("newQuad"); - addMenuAction ("newCondLine"); - addMenuAction ("newComment"); - addMenuAction ("newBFC"); - addMenuAction ("newVertex"); - - // Edit menu - initMenu ("&Edit"); - addMenuAction ("undo"); - addMenuAction ("redo"); - menu->addSeparator (); - addMenuAction ("cut"); - addMenuAction ("copy"); - addMenuAction ("paste"); - addMenuAction ("del"); - menu->addSeparator (); - addMenuAction ("selectAll"); - addMenuAction ("selectByColor"); - addMenuAction ("selectByType"); - menu->addSeparator (); - addMenuAction ("modeSelect"); - addMenuAction ("modeDraw"); - menu->addSeparator (); - addMenuAction ("setDrawDepth"); - - // Move menu - initMenu ("&Move"); - addMenuAction ("moveUp"); - addMenuAction ("moveDown"); - menu->addSeparator (); - addMenuAction ("gridCoarse"); - addMenuAction ("gridMedium"); - addMenuAction ("gridFine"); - menu->addSeparator (); - addMenuAction ("moveXPos"); - addMenuAction ("moveXNeg"); - addMenuAction ("moveYPos"); - addMenuAction ("moveYNeg"); - addMenuAction ("moveZPos"); - addMenuAction ("moveZNeg"); - menu->addSeparator (); - addMenuAction ("rotateXPos"); - addMenuAction ("rotateXNeg"); - addMenuAction ("rotateYPos"); - addMenuAction ("rotateYNeg"); - addMenuAction ("rotateZPos"); - addMenuAction ("rotateZNeg"); - addMenuAction ("rotpoint"); - - initMenu ("&Tools"); - addMenuAction ("setColor"); - addMenuAction ("autoColor"); - addMenuAction ("uncolorize"); - menu->addSeparator (); - addMenuAction ("invert"); - addMenuAction ("inlineContents"); - addMenuAction ("deepInline"); - addMenuAction ("makePrimitive"); - menu->addSeparator (); - addMenuAction ("splitQuads"); - addMenuAction ("setContents"); - addMenuAction ("makeBorders"); - addMenuAction ("makeCornerVerts"); - addMenuAction ("roundCoords"); - addMenuAction ("visibility"); - addMenuAction ("replaceCoords"); - addMenuAction ("flip"); - addMenuAction ("demote"); - - initMenu ("E&xternal Programs"); - addMenuAction ("ytruder"); - addMenuAction ("rectifier"); - addMenuAction ("intersector"); - addMenuAction ("isecalc"); - addMenuAction ("coverer"); - addMenuAction ("edger2"); - - // Help menu - initMenu ("&Help"); - addMenuAction ("help"); - menu->addSeparator (); - addMenuAction ("about"); - addMenuAction ("aboutQt"); -} - -// ============================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// ============================================================================= -void ForgeWindow::updateRecentFilesMenu () { +void ForgeWindow::updateRecentFilesMenu() { // First, clear any items in the recent files menu for (QAction* recent : m_recentFiles) delete recent; - m_recentFiles.clear (); + m_recentFiles.clear(); vector<str> files = container_cast<QStringList, vector<str>> (io_recentfiles.value.split ("@")); for (str file : c_rev<str> (files)) { QAction* recent = new QAction (getIcon ("open-recent"), file, this); - connect (recent, SIGNAL (triggered ()), this, SLOT (slot_recentFile ())); - m_recentFilesMenu->addAction (recent); + connect (recent, SIGNAL (triggered()), this, SLOT (slot_recentFile())); + ui->menuOpenRecent->addAction (recent); m_recentFiles << recent; } } @@ -327,105 +166,14 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -static QToolBar* g_CurrentToolBar; -static Qt::ToolBarArea g_ToolBarArea = Qt::TopToolBarArea; - -void ForgeWindow::initSingleToolBar (const char* name) { - QToolBar* toolbar = new QToolBar (name); - addToolBar (g_ToolBarArea, toolbar); - m_toolBars << toolbar; - - g_CurrentToolBar = toolbar; -} - -// ============================================================================= -void ForgeWindow::addToolBarAction (const char* name) { - g_CurrentToolBar->addAction (findAction (name)); -} - -// ============================================================================= -void ForgeWindow::createToolbars () { - initSingleToolBar ("File"); - addToolBarAction ("newFile"); - addToolBarAction ("open"); - addToolBarAction ("save"); - addToolBarAction ("saveAs"); - - // ========================================== - initSingleToolBar ("Insert"); - addToolBarAction ("newSubfile"); - addToolBarAction ("newLine"); - addToolBarAction ("newTriangle"); - addToolBarAction ("newQuad"); - addToolBarAction ("newCondLine"); - addToolBarAction ("newComment"); - addToolBarAction ("newBFC"); - addToolBarAction ("newVertex"); - - // ========================================== - initSingleToolBar ("Edit"); - addToolBarAction ("undo"); - addToolBarAction ("redo"); - addToolBarAction ("cut"); - addToolBarAction ("copy"); - addToolBarAction ("paste"); - addToolBarAction ("del"); - addToolBarBreak (Qt::TopToolBarArea); - - // ========================================== - initSingleToolBar ("Select"); - addToolBarAction ("selectAll"); - addToolBarAction ("selectByColor"); - addToolBarAction ("selectByType"); - - // ========================================== - initSingleToolBar ("Grids"); - addToolBarAction ("gridCoarse"); - addToolBarAction ("gridMedium"); - addToolBarAction ("gridFine"); - - // ========================================== - initSingleToolBar ("View"); - addToolBarAction ("axes"); - addToolBarAction ("wireframe"); - addToolBarAction ("colorbfc"); - - // ========================================== - // Color toolbar - m_colorToolBar = new QToolBar ("Quick Colors"); - addToolBar (Qt::RightToolBarArea, m_colorToolBar); - - // ========================================== - initSingleToolBar ("Tools"); - addToolBarAction ("setColor"); - addToolBarAction ("autoColor"); - addToolBarAction ("splitQuads"); - addToolBarAction ("setContents"); - addToolBarAction ("makeBorders"); - addToolBarAction ("replaceCoords"); - addToolBarAction ("roundCoords"); - addToolBarAction ("visibility"); - - // ========================================== - g_ToolBarArea = Qt::LeftToolBarArea; - initSingleToolBar ("Modes"); - addToolBarAction ("modeSelect"); - addToolBarAction ("modeDraw"); - - updateToolBars (); -} - -// ============================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// ============================================================================= -vector<quickColor> parseQuickColorMeta () { +vector<quickColor> parseQuickColorMeta() { vector<quickColor> meta; for (str colorname : gui_colortoolbar.value.split (":")) { if (colorname == "|") { meta << quickColor ({null, null, true}); } else { - LDColor* col = getColor (colorname.toLong ()); + LDColor* col = getColor (colorname.toLong()); assert (col != null); meta << quickColor ({col, null, false}); } @@ -437,73 +185,68 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void ForgeWindow::updateToolBars () { - const QSize iconsize (gui_toolbar_iconsize, gui_toolbar_iconsize); - - for (QToolBar* bar : m_toolBars) - bar->setIconSize (iconsize); - +void ForgeWindow::updateToolBars() { // Update the quick color toolbar. for (QToolButton* btn : m_colorButtons) delete btn; - m_colorButtons.clear (); + m_colorButtons.clear(); - // Clear the toolbar to remove separators - m_colorToolBar->clear (); + // Clear the toolbar - we deleted the buttons but there's still separators + ui->colorToolbar->clear(); for (quickColor& entry : m_colorMeta) { if (entry.isSeparator) - m_colorToolBar->addSeparator (); + ui->colorToolbar->addSeparator(); else { QToolButton* colorButton = new QToolButton; colorButton->setIcon (makeColorIcon (entry.col, gui_toolbar_iconsize)); - colorButton->setIconSize (iconsize); + colorButton->setIconSize (QSize (22, 22)); colorButton->setToolTip (entry.col->name); - connect (colorButton, SIGNAL (clicked ()), this, SLOT (slot_quickColor ())); - m_colorToolBar->addWidget (colorButton); + connect (colorButton, SIGNAL (clicked()), this, SLOT (slot_quickColor())); + ui->colorToolbar->addWidget (colorButton); m_colorButtons << colorButton; entry.btn = colorButton; } } - updateGridToolBar (); + updateGridToolBar(); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void ForgeWindow::updateGridToolBar () { +void ForgeWindow::updateGridToolBar() { // Ensure that the current grid - and only the current grid - is selected. - findAction ("gridCoarse")->setChecked (grid == Grid::Coarse); - findAction ("gridMedium")->setChecked (grid == Grid::Medium); - findAction ("gridFine")->setChecked (grid == Grid::Fine); + ui->actionGridCoarse->setChecked (grid == Grid::Coarse); + ui->actionGridMedium->setChecked (grid == Grid::Medium); + ui->actionGridFine->setChecked (grid == Grid::Fine); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void ForgeWindow::updateTitle () { +void ForgeWindow::updateTitle() { str title = fmt (APPNAME " %1", fullVersionString()); // Append our current file if we have one if (currentFile()) { - if (currentFile()->name ().length () > 0) - title += fmt (": %1", basename (currentFile()->name ())); + if (currentFile()->name().length() > 0) + title += fmt (": %1", basename (currentFile()->name())); else title += fmt (": <anonymous>"); - if (currentFile()->numObjs () > 0 && - currentFile()->obj (0)->getType () == LDObject::Comment) + if (currentFile()->numObjs() > 0 && + currentFile()->obj (0)->getType() == LDObject::Comment) { // Append title LDCommentObject* comm = static_cast<LDCommentObject*> (currentFile()->obj (0)); title += fmt (": %1", comm->text); } - if (currentFile()->history ().pos () != currentFile()->savePos ()) + if (currentFile()->history().pos() != currentFile()->savePos()) title += '*'; } @@ -513,44 +256,6 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -EXTERN_ACTION( undo ); -EXTERN_ACTION( redo ); -EXTERN_ACTION( open ); -void ForgeWindow::slot_action () { - // Open the history so we can record the edits done during this action. - if( sender() != ACTION( undo ) && sender() != ACTION( redo ) && sender() != ACTION( open )) - currentFile()->openHistory (); - - // Get the action that triggered this slot. - QAction* qAct = static_cast<QAction*> (sender ()); - - // Find the meta for the action. - actionmeta* meta = null; - - for (actionmeta& it : g_actionMeta) { - if (it.qAct == null) - break; - - if (*it.qAct == qAct) { - meta = ⁢ - break; - } - } - - if (!meta) { - log ("Warning: unknown signal sender %p!\n", qAct); - return; - } - - // We have the meta, now call the handler. - (*meta->handler) (); - - currentFile()->closeHistory (); -} - -// ============================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// ============================================================================= int ForgeWindow::deleteSelection() { if( m_sel.size() == 0 ) @@ -560,9 +265,8 @@ int num = 0; // Delete the objects that were being selected - for( LDObject * obj : selCopy ) - { - currentFile()->forgetObject( obj ); + for (LDObject* obj : selCopy) { + currentFile()->forgetObject (obj); ++num; delete obj; } @@ -574,7 +278,7 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void ForgeWindow::buildObjList () { +void ForgeWindow::buildObjList() { if (!currentFile()) return; @@ -583,15 +287,15 @@ // while this is done. g_bSelectionLocked = true; - for (int i = 0; i < m_objList->count (); ++i) - delete m_objList->item (i); + for (int i = 0; i < ui->objectList->count(); ++i) + delete ui->objectList->item (i); - m_objList->clear (); + ui->objectList->clear(); - for (LDObject* obj : currentFile()->objs ()) { + for (LDObject* obj : currentFile()->objs()) { str descr; - switch (obj->getType ()) { + switch (obj->getType()) { case LDObject::Comment: descr = static_cast<LDCommentObject*> (obj)->text; @@ -607,7 +311,7 @@ case LDObject::Triangle: case LDObject::Quad: case LDObject::CondLine: - for (short i = 0; i < obj->vertices (); ++i) { + for (short i = 0; i < obj->vertices(); ++i) { if (i != 0) descr += ", "; @@ -627,11 +331,11 @@ { LDSubfileObject* ref = static_cast<LDSubfileObject*> (obj); - descr = fmt ("%1 %2, (", ref->fileInfo ()->name (), - ref->position ().stringRep (true)); + descr = fmt ("%1 %2, (", ref->fileInfo()->name(), + ref->position().stringRep (true)); for (short i = 0; i < 9; ++i) - descr += fmt ("%1%2", ftoa (ref->transform ()[i]), + descr += fmt ("%1%2", ftoa (ref->transform()[i]), (i != 8) ? " " : ""); descr += ')'; @@ -656,7 +360,7 @@ } // Put it into brackets if it's hidden - if (obj->hidden ()) { + if (obj->hidden()) { descr = fmt ("[[ %1 ]]", descr); } @@ -667,64 +371,56 @@ if (obj->getType() == LDObject::Error) { item->setBackground (QColor ("#AA0000")); item->setForeground (QColor ("#FFAA00")); - } elif (lv_colorize && obj->isColored () && - obj->color () != maincolor && obj->color () != edgecolor) + } elif (lv_colorize && obj->isColored() && + obj->color() != maincolor && obj->color() != edgecolor) { // If the object isn't in the main or edge color, draw this // list entry in said color. - LDColor* col = getColor (obj->color ()); + LDColor* col = getColor (obj->color()); if (col) item->setForeground (col->faceColor); } obj->qObjListEntry = item; - m_objList->insertItem (m_objList->count (), item); + ui->objectList->insertItem (ui->objectList->count(), item); } g_bSelectionLocked = false; - updateSelection (); - scrollToSelection (); + updateSelection(); + scrollToSelection(); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void ForgeWindow::scrollToSelection () { +void ForgeWindow::scrollToSelection() { if (m_sel.size() == 0) return; - LDObject* obj = m_sel[m_sel.size () - 1]; - m_objList->scrollToItem (obj->qObjListEntry); + LDObject* obj = m_sel[m_sel.size() - 1]; + ui->objectList->scrollToItem (obj->qObjListEntry); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void ForgeWindow::slot_selectionChanged () { +void ForgeWindow::slot_selectionChanged() { if (g_bSelectionLocked == true || currentFile() == null) return; - /* - // If the selection isn't 1 exact, disable setting contents - findAction ("setContents")->setEnabled (qObjList->selectedItems().size() == 1); - - // If we have no selection, disable splitting quads - findAction ("splitQuads")->setEnabled (qObjList->selectedItems().size() > 0); - */ - // Update the shared selection array, though don't do this if this was // called during GL picking, in which case the GL renderer takes care // of the selection. - if (m_renderer->picking ()) + if (m_renderer->picking()) return; vector<LDObject*> priorSelection = m_sel; // Get the objects from the object list selection - m_sel.clear (); - const QList<QListWidgetItem*> items = m_objList->selectedItems (); + m_sel.clear(); + const QList<QListWidgetItem*> items = ui->objectList->selectedItems(); - for (LDObject* obj : currentFile()->objs ()) + for (LDObject* obj : currentFile()->objs()) for (QListWidgetItem* item : items) { if (item == obj->qObjListEntry) { m_sel << obj; @@ -743,21 +439,21 @@ m_renderer->compileObject (obj); } - m_renderer->update (); + m_renderer->update(); } // ============================================================================= -void ForgeWindow::slot_recentFile () { - QAction* qAct = static_cast<QAction*> (sender ()); - openMainFile (qAct->text ()); +void ForgeWindow::slot_recentFile() { + QAction* qAct = static_cast<QAction*> (sender()); + openMainFile (qAct->text()); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void ForgeWindow::slot_quickColor () { - currentFile()->openHistory (); - QToolButton* button = static_cast<QToolButton*> (sender ()); +void ForgeWindow::slot_quickColor() { + currentFile()->openHistory(); + QToolButton* button = static_cast<QToolButton*> (sender()); LDColor* col = null; for (quickColor entry : m_colorMeta) { @@ -773,52 +469,52 @@ short newColor = col->index; for (LDObject* obj : m_sel) { - if (obj->isColored () == false) + if (obj->isColored() == false) continue; // uncolored object obj->setColor (newColor); } - fullRefresh (); - currentFile()->closeHistory (); + fullRefresh(); + currentFile()->closeHistory(); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -ulong ForgeWindow::getInsertionPoint () { - if (m_sel.size () > 0) { +ulong ForgeWindow::getInsertionPoint() { + if (m_sel.size() > 0) { // If we have a selection, put the item after it. return (m_sel[m_sel.size() - 1]->getIndex (currentFile())) + 1; } // Otherwise place the object at the end. - return currentFile()->numObjs (); + return currentFile()->numObjs(); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void ForgeWindow::fullRefresh () { - buildObjList (); - m_renderer->hardRefresh (); +void ForgeWindow::fullRefresh() { + buildObjList(); + m_renderer->hardRefresh(); } -void ForgeWindow::refresh () { - buildObjList (); - m_renderer->update (); +void ForgeWindow::refresh() { + buildObjList(); + m_renderer->update(); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void ForgeWindow::updateSelection () { +void ForgeWindow::updateSelection() { g_bSelectionLocked = true; - for (LDObject* obj : currentFile()->objs ()) + for (LDObject* obj : currentFile()->objs()) obj->setSelected (false); - m_objList->clearSelection (); + ui->objectList->clearSelection(); for (LDObject* obj : m_sel) { if( obj->qObjListEntry == null ) continue; @@ -828,14 +524,14 @@ } g_bSelectionLocked = false; - slot_selectionChanged (); + slot_selectionChanged(); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= bool ForgeWindow::isSelected (LDObject* obj) { - LDObject* needle = obj->topLevelParent (); + LDObject* needle = obj->topLevelParent(); for (LDObject* hay : m_sel) if (hay == needle) @@ -844,18 +540,18 @@ return false; } -short ForgeWindow::getSelectedColor () { +short ForgeWindow::getSelectedColor() { short result = -1; for (LDObject* obj : m_sel) { - if (obj->isColored () == false) + if (obj->isColored() == false) continue; // doesn't use color - if (result != -1 && obj->color () != result) + if (result != -1 && obj->color() != result) return -1; // No consensus in object color if (result == -1) - result = obj->color (); + result = obj->color(); } return result; @@ -864,15 +560,15 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -LDObject::Type ForgeWindow::uniformSelectedType () { +LDObject::Type ForgeWindow::uniformSelectedType() { LDObject::Type result = LDObject::Unidentified; for (LDObject* obj : m_sel) { - if (result != LDObject::Unidentified && obj->color () != result) + if (result != LDObject::Unidentified && obj->color() != result) return LDObject::Unidentified; if (result == LDObject::Unidentified) - result = obj->getType (); + result = obj->getType(); } return result; @@ -883,52 +579,51 @@ // ============================================================================= void ForgeWindow::closeEvent (QCloseEvent* ev) { // Check whether it's safe to close all files. - if (!safeToCloseAll ()) { - ev->ignore (); + if (!safeToCloseAll()) { + ev->ignore(); return; } // Save the configuration before leaving so that, for instance, grid choice // is preserved across instances. - config::save (); + config::save(); - ev->accept (); + ev->accept(); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= void ForgeWindow::spawnContextMenu (const QPoint pos) { - const bool single = (g_win->sel ().size () == 1); - LDObject* singleObj = (single) ? g_win->sel ()[0] : null; + const bool single = (g_win->sel().size() == 1); + LDObject* singleObj = (single) ? g_win->sel()[0] : null; QMenu* contextMenu = new QMenu; - if (single && singleObj->getType () != LDObject::Empty) { - contextMenu->addAction (findAction ("editObject")); - contextMenu->addSeparator (); + if (single && singleObj->getType() != LDObject::Empty) { + contextMenu->addAction (ACTION (Edit)); + contextMenu->addSeparator(); } - contextMenu->addAction (findAction ("cut")); - contextMenu->addAction (findAction ("copy")); - contextMenu->addAction (findAction ("paste")); - contextMenu->addAction (findAction ("del")); - contextMenu->addSeparator (); - contextMenu->addAction (findAction ("setColor")); + contextMenu->addAction (ACTION (Cut)); + contextMenu->addAction (ACTION (Copy)); + contextMenu->addAction (ACTION (Paste)); + contextMenu->addAction (ACTION (Delete)); + contextMenu->addSeparator(); + contextMenu->addAction (ACTION (SetColor)); if (single) - contextMenu->addAction (findAction ("setContents")); - - contextMenu->addAction (findAction ("makeBorders")); - contextMenu->addAction (findAction ("setOverlay")); - contextMenu->addAction (findAction ("clearOverlay")); + contextMenu->addAction (ACTION (EditRaw)); - for (const char* mode : g_modeActionNames) - contextMenu->addAction (findAction (mode)); + contextMenu->addAction (ACTION (Borders)); + contextMenu->addAction (ACTION (SetOverlay)); + contextMenu->addAction (ACTION (ClearOverlay)); + contextMenu->addAction (ACTION (ModeSelect)); + contextMenu->addAction (ACTION (ModeDraw)); - if (R ()->camera () != GL::Free) { - contextMenu->addSeparator (); - contextMenu->addAction (findAction ("setDrawDepth")); + if (R()->camera() != GL::Free) { + contextMenu->addSeparator(); + contextMenu->addAction (ACTION (SetDrawDepth)); } contextMenu->exec (pos); @@ -945,8 +640,8 @@ // ============================================================================= void ForgeWindow::deleteByColor (const short colnum) { vector<LDObject*> objs; - for (LDObject* obj : currentFile()->objs ()) { - if (!obj->isColored () || obj->color () != colnum) + for (LDObject* obj : currentFile()->objs()) { + if (!obj->isColored() || obj->color() != colnum) continue; objs << obj; @@ -956,20 +651,10 @@ } // ============================================================================= -void ForgeWindow::updateEditModeActions () { - const EditMode mode = R ()->editMode (); - const size_t numModeActions = (sizeof g_modeActionNames / sizeof *g_modeActionNames); - assert ((size_t) mode < numModeActions); - - for (size_t i = 0; i < numModeActions; ++i) { - QAction* act = findAction (g_modeActionNames[i]); - - act->setCheckable (true); - act->setChecked (i == (size_t) mode); - - if (i != Select) - act->setEnabled (R ()->camera () != GL::Free); - } +void ForgeWindow::updateEditModeActions() { + const EditMode mode = R()->editMode(); + ACTION (ModeSelect)->setChecked (mode == Select); + ACTION (ModeDraw)->setChecked (mode == Draw); } void ForgeWindow::slot_editObject (QListWidgetItem* listitem) { @@ -981,11 +666,11 @@ } } - AddObjectDialog::staticDialog (obj->getType (), obj); + AddObjectDialog::staticDialog (obj->getType(), obj); } void ForgeWindow::primitiveLoaderStart (ulong max) { - m_primLoaderWidget->show (); + m_primLoaderWidget->show(); m_primLoaderBar->setRange (0, max); m_primLoaderBar->setValue (0); m_primLoaderBar->setFormat ("%p%"); @@ -995,26 +680,26 @@ m_primLoaderBar->setValue (prog); } -void ForgeWindow::primitiveLoaderEnd () { +void ForgeWindow::primitiveLoaderEnd() { QTimer* hidetimer = new QTimer; - connect (hidetimer, SIGNAL (timeout ()), m_primLoaderWidget, SLOT (hide ())); + connect (hidetimer, SIGNAL (timeout()), m_primLoaderWidget, SLOT (hide())); hidetimer->setSingleShot (true); hidetimer->start (1500); m_primLoaderBar->setFormat( tr( "Done" )); - log( tr( "Primitives scanned: %1 primitives listed" ), m_primLoaderBar->value() ); + log (tr ("Primitives scanned: %1 primitives listed"), m_primLoaderBar->value()); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= void ForgeWindow::save (LDOpenFile* f, bool saveAs) { - str path = f->name (); + str path = f->name(); - if (path.length () == 0 || saveAs) { + if (path.length() == 0 || saveAs) { path = QFileDialog::getSaveFileName (g_win, tr ("Save As"), - currentFile()->name (), tr ("LDraw files (*.dat *.ldr)")); + currentFile()->name(), tr ("LDraw files (*.dat *.ldr)")); - if (path.length () == 0) { + if (path.length() == 0) { // User didn't give a file name. This happens if the user cancelled // saving in the save file dialog. Abort. return; @@ -1025,20 +710,17 @@ f->setName (path); if (f == currentFile()) - g_win->updateTitle (); + g_win->updateTitle(); log ("Saved to %1.", path); // Add it to recent files addRecentFile (path); } else { - setlocale (LC_ALL, "C"); - str message = fmt (tr ("Failed to save to %1: %2"), path, strerror (errno)); // Tell the user the save failed, and give the option for saving as with it. - QMessageBox dlg (QMessageBox::Critical, tr ("Save Failure"), message, - QMessageBox::Close, g_win); + QMessageBox dlg (QMessageBox::Critical, tr ("Save Failure"), message, QMessageBox::Close, g_win); // Add a save-as button QPushButton* saveAsBtn = new QPushButton (tr ("Save As")); @@ -1047,19 +729,18 @@ dlg.setDefaultButton (QMessageBox::Close); dlg.exec(); - if (dlg.clickedButton () == saveAsBtn) + if (dlg.clickedButton() == saveAsBtn) save (f, true); // yay recursion! } } -void ForgeWindow::addMessage( str msg ) -{ - m_msglog->addLine( msg ); +void ForgeWindow::addMessage (str msg) { + m_msglog->addLine (msg); } // ============================================================================ void ObjectList::contextMenuEvent (QContextMenuEvent* ev) { - g_win->spawnContextMenu (ev->globalPos ()); + g_win->spawnContextMenu (ev->globalPos()); } // ============================================================================= @@ -1071,7 +752,7 @@ // ============================================================================= bool confirm (str msg) { - return confirm ("Confirm", msg); + return confirm (ForgeWindow::tr ("Confirm"), msg); } bool confirm (str title, str msg) { @@ -1081,26 +762,11 @@ // ============================================================================= void critical (str msg) { - QMessageBox::critical (g_win, QObject::tr( "Error" ), msg, + QMessageBox::critical (g_win, ForgeWindow::tr("Error"), msg, (QMessageBox::Close), QMessageBox::Close); } // ============================================================================= -QAction* findAction (str name) { - for (actionmeta& meta : g_actionMeta) { - if (meta.qAct == null) - break; - - if (name == meta.name) - return *meta.qAct; - } - - fatal (fmt ("Couldn't find action named `%2'!", name)); - abort (); - return null; -} - -// ============================================================================= QIcon makeColorIcon (LDColor* colinfo, const ushort size) { // Create an image object and link a painter to it. QImage img (size, size, QImage::Format_ARGB32); @@ -1110,11 +776,11 @@ if (colinfo->index == maincolor) { // Use the user preferences for main color here col = gl_maincolor.value; - col.setAlpha (gl_maincolor_alpha * 255.0f); + col.setAlphaF (gl_maincolor_alpha); } // Paint the icon - paint.fillRect (QRect (0, 0, size, size), Qt::black); + paint.fillRect (QRect (0, 0, size, size), colinfo->edgeColor); paint.drawPixmap (QRect (1, 1, size - 2, size - 2), getIcon ("checkerboard"), QRect (0, 0, 8, 8)); paint.fillRect (QRect (1, 1, size - 2, size - 2), col); return QIcon (QPixmap::fromImage (img)); @@ -1124,17 +790,17 @@ void makeColorSelector (QComboBox* box) { std::map<short, ulong> counts; - for (LDObject* obj : currentFile()->objs ()) { - if (!obj->isColored ()) + for (LDObject* obj : currentFile()->objs()) { + if (!obj->isColored()) continue; - if (counts.find (obj->color ()) == counts.end ()) - counts[obj->color ()] = 1; + if (counts.find (obj->color()) == counts.end()) + counts[obj->color()] = 1; else - counts[obj->color ()]++; + counts[obj->color()]++; } - box->clear (); + box->clear(); ulong row = 0; for (const auto& pair : counts) { LDColor* col = getColor (pair.first); @@ -1152,12 +818,12 @@ // ============================================================================= QDialogButtonBox* makeButtonBox (QDialog& dlg) { QDialogButtonBox* bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - QWidget::connect (bbx_buttons, SIGNAL (accepted ()), &dlg, SLOT (accept ())); - QWidget::connect (bbx_buttons, SIGNAL (rejected ()), &dlg, SLOT (reject ())); + QWidget::connect (bbx_buttons, SIGNAL (accepted()), &dlg, SLOT (accept())); + QWidget::connect (bbx_buttons, SIGNAL (rejected()), &dlg, SLOT (reject())); return bbx_buttons; } -CheckBoxGroup* makeAxesBox () { +CheckBoxGroup* makeAxesBox() { CheckBoxGroup* cbg_axes = new CheckBoxGroup ("Axes", Qt::Horizontal); cbg_axes->addCheckBox ("X", X); cbg_axes->addCheckBox ("Y", Y); @@ -1166,23 +832,21 @@ } void ForgeWindow::setStatusBarText (str text) { - statusBar ()->showMessage (text); + statusBar()->showMessage (text); } -void ForgeWindow::addActionMeta (actionmeta& meta) { - if (g_metacursor == 0) - memset (g_actionMeta, 0, sizeof g_actionMeta); - - assert (g_metacursor < MAX_ACTIONS); - g_actionMeta[g_metacursor++] = meta; -} - -void ForgeWindow::clearSelection() -{ +void ForgeWindow::clearSelection() { m_sel.clear(); } +Ui_LDForgeUI* ForgeWindow::interface() const { + return ui; +} + +#define act(N) QAction* ForgeWindow::action##N() { return ui->action##N; } +#include "actions.h" + QImage imageFromScreencap (uchar* data, ushort w, ushort h) { // GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well. - return QImage (data, w, h, QImage::Format_ARGB32).rgbSwapped ().mirrored (); + return QImage (data, w, h, QImage::Format_ARGB32).rgbSwapped().mirrored(); } \ No newline at end of file