Wed, 10 Apr 2013 01:51:35 +0300
Split some stuff out of the edit tool bar into move and object tool bars. The object tool bar is now located on the left side of the screen as the top one is running out of space.
/* * LDForge: LDraw parts authoring CAD * Copyright (C) 2013 Santeri `arezey` Piippo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <QtGui> #include "common.h" #include "gldraw.h" #include "gui.h" #include "file.h" #include "config.h" #include "misc.h" #include "colors.h" #include "config.h" EXTERN_ACTION (newFile) EXTERN_ACTION (open) EXTERN_ACTION (save) EXTERN_ACTION (saveAs) EXTERN_ACTION (settings) EXTERN_ACTION (exit) EXTERN_ACTION (cut) EXTERN_ACTION (copy) EXTERN_ACTION (paste) EXTERN_ACTION (del) EXTERN_ACTION (setColor) EXTERN_ACTION (inlineContents) EXTERN_ACTION (deepInline) EXTERN_ACTION (splitQuads) EXTERN_ACTION (setContents) EXTERN_ACTION (makeBorders) EXTERN_ACTION (moveUp) EXTERN_ACTION (moveDown) EXTERN_ACTION (newSubfile) EXTERN_ACTION (newLine) EXTERN_ACTION (newCondLine) EXTERN_ACTION (newTriangle) EXTERN_ACTION (newQuad) EXTERN_ACTION (newVertex) EXTERN_ACTION (newComment) EXTERN_ACTION (help) EXTERN_ACTION (about) EXTERN_ACTION (aboutQt) EXTERN_ACTION (undo) EXTERN_ACTION (redo) vector<actionmeta> g_ActionMeta; cfg (bool, lv_colorize, true); // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= ForgeWindow::ForgeWindow () { R = new renderer; qObjList = new QTreeWidget; qObjList->setHeaderHidden (true); qObjList->setMaximumWidth (256); qObjList->setSelectionMode (QTreeWidget::MultiSelection); connect (qObjList, SIGNAL (itemSelectionChanged ()), this, SLOT (slot_selectionChanged ())); qMessageLog = new QTextEdit; qMessageLog->setReadOnly (true); qMessageLog->setMaximumHeight (96); QWidget* w = new QWidget; QGridLayout* layout = new QGridLayout; layout->setColumnMinimumWidth (0, 192); layout->setColumnStretch (0, 1); layout->addWidget (R, 0, 0); layout->addWidget (qObjList, 0, 1); layout->addWidget (qMessageLog, 1, 0, 1, 2); w->setLayout (layout); setCentralWidget (w); createMenuActions (); createMenus (); createToolbars (); slot_selectionChanged (); setWindowIcon (QIcon ("icons/ldforge.png")); setTitle (); setMinimumSize (320, 200); resize (800, 600); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= void ForgeWindow::createMenuActions () { // Create the actions based on stored meta. for (actionmeta meta : g_ActionMeta) { QAction*& qAct = *meta.qAct; qAct = new QAction (getIcon (meta.sIconName), meta.sDisplayName, this); qAct->setStatusTip (meta.sDescription); qAct->setShortcut (*meta.conf); connect (qAct, SIGNAL (triggered ()), this, SLOT (slot_action ())); } // things not implemented yet QAction* const qaDisabledActions[] = { ACTION_NAME (newSubfile), ACTION_NAME (about), ACTION_NAME (help), }; for (QAction* act : qaDisabledActions) act->setEnabled (false); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= #define ADD_MENU_ITEM(MENU, ACT) q##MENU##Menu->addAction (ACTION_NAME (ACT)); void ForgeWindow::createMenus () { // File menu qFileMenu = menuBar ()->addMenu (tr ("&File")); ADD_MENU_ITEM (File, newFile) // New ADD_MENU_ITEM (File, open) // Open ADD_MENU_ITEM (File, save) // Save ADD_MENU_ITEM (File, saveAs) // Save As qFileMenu->addSeparator (); // ------- ADD_MENU_ITEM (File, settings) // Settings qFileMenu->addSeparator (); // ------- ADD_MENU_ITEM (File, exit) // Exit // Insert menu qInsertMenu = menuBar ()->addMenu (tr ("&Insert")); ADD_MENU_ITEM (Insert, newSubfile) // New Subfile ADD_MENU_ITEM (Insert, newLine) // New Line ADD_MENU_ITEM (Insert, newTriangle) // New Triangle ADD_MENU_ITEM (Insert, newQuad) // New Quad ADD_MENU_ITEM (Insert, newCondLine) // New Conditional Line ADD_MENU_ITEM (Insert, newComment) // New Comment ADD_MENU_ITEM (Insert, newVertex) // New Vertex // Edit menu qEditMenu = menuBar ()->addMenu (tr ("&Edit")); ADD_MENU_ITEM (Edit, undo) // Undo ADD_MENU_ITEM (Edit, redo) // Redo qEditMenu->addSeparator (); // ----- ADD_MENU_ITEM (Edit, cut) // Cut ADD_MENU_ITEM (Edit, copy) // Copy ADD_MENU_ITEM (Edit, paste) // Paste ADD_MENU_ITEM (Edit, del) // Delete qEditMenu->addSeparator (); // ----- ADD_MENU_ITEM (Edit, moveUp) // Move Up ADD_MENU_ITEM (Edit, moveDown) // Move Down qEditMenu->addSeparator (); // ----- ADD_MENU_ITEM (Edit, setColor) // Set Color qEditMenu->addSeparator (); // ----- ADD_MENU_ITEM (Edit, inlineContents) // Inline ADD_MENU_ITEM (Edit, deepInline) // Deep Inline ADD_MENU_ITEM (Edit, splitQuads) // Split Quads ADD_MENU_ITEM (Edit, setContents) // Set Contents ADD_MENU_ITEM (Edit, makeBorders) // Make Borders // Help menu qHelpMenu = menuBar ()->addMenu (tr ("&Help")); ADD_MENU_ITEM (Help, help) // Help qHelpMenu->addSeparator (); // ----- ADD_MENU_ITEM (Help, about) // About ADD_MENU_ITEM (Help, aboutQt) // About Qt } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= #define ADD_TOOLBAR_ITEM(ACT) (*g_CurrentToolBar)->addAction (ACTION_NAME (ACT)); static QToolBar** g_CurrentToolBar; static Qt::ToolBarArea g_ToolBarArea = Qt::TopToolBarArea; void ForgeWindow::initSingleToolBar (QToolBar*& qBar, const char* sName) { qBar = new QToolBar (sName); qBar->setIconSize (QSize (24, 24)); addToolBar (g_ToolBarArea, qBar); g_CurrentToolBar = &qBar; } void ForgeWindow::createToolbars () { initSingleToolBar (qFileToolBar, "File"); ADD_TOOLBAR_ITEM (newFile) ADD_TOOLBAR_ITEM (open) ADD_TOOLBAR_ITEM (save) ADD_TOOLBAR_ITEM (saveAs) initSingleToolBar (qInsertToolBar, "Insert"); ADD_TOOLBAR_ITEM (newSubfile) ADD_TOOLBAR_ITEM (newLine) ADD_TOOLBAR_ITEM (newTriangle) ADD_TOOLBAR_ITEM (newQuad) ADD_TOOLBAR_ITEM (newCondLine) ADD_TOOLBAR_ITEM (newComment) ADD_TOOLBAR_ITEM (newVertex) initSingleToolBar (qEditToolBar, "Edit"); ADD_TOOLBAR_ITEM (undo) ADD_TOOLBAR_ITEM (redo) ADD_TOOLBAR_ITEM (cut) ADD_TOOLBAR_ITEM (copy) ADD_TOOLBAR_ITEM (paste) ADD_TOOLBAR_ITEM (del) addToolBar (qEditToolBar); initSingleToolBar (qMoveToolBar, "Move"); ADD_TOOLBAR_ITEM (moveUp) ADD_TOOLBAR_ITEM (moveDown) // ========================================== // Left area toolbars g_ToolBarArea = Qt::LeftToolBarArea; initSingleToolBar (qInsertToolBar, "Objects"); ADD_TOOLBAR_ITEM (setColor) ADD_TOOLBAR_ITEM (inlineContents) ADD_TOOLBAR_ITEM (splitQuads) ADD_TOOLBAR_ITEM (setContents) ADD_TOOLBAR_ITEM (makeBorders) } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= void ForgeWindow::setTitle () { str zTitle = APPNAME_DISPLAY " v" VERSION_STRING; // Append our current file if we have one if (g_CurrentFile) { zTitle.appendformat (": %s", basename (g_CurrentFile->zFileName.chars())); if (g_CurrentFile->objects.size() > 0 && g_CurrentFile->objects[0]->getType() == OBJ_Comment) { // Append title LDComment* comm = static_cast<LDComment*> (g_CurrentFile->objects[0]); zTitle.appendformat (":%s", comm->zText.chars()); } } setWindowTitle (zTitle.chars()); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= void ForgeWindow::slot_action () { // Get the action that triggered this slot. QAction* qAct = static_cast<QAction*> (sender ()); // Find the meta for the action. actionmeta* pMeta = nullptr; for (actionmeta meta : g_ActionMeta) { if (*meta.qAct == qAct) { pMeta = &meta; break; } } if (!pMeta) { fprintf (stderr, "unknown signal sender %p!\n", qAct); return; } // We have the meta, now call the handler. (*pMeta->handler) (); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= void ForgeWindow::deleteSelection () { vector<LDObject*> objs = getSelectedObjects (); // Delete the objects that were being selected for (LDObject* obj : objs) { g_CurrentFile->forgetObject (obj); delete obj; } if (objs.size() > 0) refresh (); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= void ForgeWindow::buildObjList () { if (!g_CurrentFile) return; QList<QTreeWidgetItem*> qaItems; qObjList->clear (); for (LDObject* obj : g_CurrentFile->objects) { str zText; switch (obj->getType ()) { case OBJ_Comment: zText = static_cast<LDComment*> (obj)->zText.chars(); // Remove leading whitespace while (~zText && zText[0] == ' ') zText -= -1; break; case OBJ_Empty: break; // leave it empty case OBJ_Line: { LDLine* line = static_cast<LDLine*> (obj); zText.format ("%s, %s", line->vaCoords[0].getStringRep (true).chars(), line->vaCoords[1].getStringRep (true).chars()); } break; case OBJ_Triangle: { LDTriangle* triangle = static_cast<LDTriangle*> (obj); zText.format ("%s, %s, %s", triangle->vaCoords[0].getStringRep (true).chars(), triangle->vaCoords[1].getStringRep (true).chars(), triangle->vaCoords[2].getStringRep (true).chars()); } break; case OBJ_Quad: { LDQuad* quad = static_cast<LDQuad*> (obj); zText.format ("%s, %s, %s, %s", quad->vaCoords[0].getStringRep (true).chars(), quad->vaCoords[1].getStringRep (true).chars(), quad->vaCoords[2].getStringRep (true).chars(), quad->vaCoords[3].getStringRep (true).chars()); } break; case OBJ_CondLine: { LDCondLine* line = static_cast<LDCondLine*> (obj); zText.format ("%s, %s, %s, %s", line->vaCoords[0].getStringRep (true).chars(), line->vaCoords[1].getStringRep (true).chars(), line->vaCoords[2].getStringRep (true).chars(), line->vaCoords[3].getStringRep (true).chars()); } break; case OBJ_Gibberish: zText.format ("ERROR: %s", static_cast<LDGibberish*> (obj)->zContents.chars()); break; case OBJ_Vertex: zText.format ("%s", static_cast<LDVertex*> (obj)->vPosition.getStringRep (true).chars()); break; case OBJ_Subfile: { LDSubfile* ref = static_cast<LDSubfile*> (obj); zText.format ("%s %s, (", ref->zFileName.chars(), ref->vPosition.getStringRep (true).chars()); for (short i = 0; i < 9; ++i) zText.appendformat ("%s%s", ftoa (ref->mMatrix[i]).chars(), (i != 8) ? " " : ""); zText += ')'; } break; case OBJ_BFC: { LDBFC* bfc = static_cast<LDBFC*> (obj); zText = LDBFC::saStatements[bfc->dStatement]; } break; default: zText = g_saObjTypeNames[obj->getType ()]; break; } QTreeWidgetItem* item = new QTreeWidgetItem ((QTreeWidget*) (nullptr), QStringList (zText.chars()), 0); item->setIcon (0, QIcon (str::mkfmt ("icons/%s.png", g_saObjTypeIcons[obj->getType ()]).chars())); // Color gibberish red if (obj->getType() == OBJ_Gibberish) { item->setBackground (0, QColor ("#AA0000")); item->setForeground (0, QColor ("#FFAA00")); } else if (lv_colorize && obj->dColor != -1 && obj->dColor != dMainColor && obj->dColor != dEdgeColor) { // If the object isn't in the main or edge color, draw this // list entry in said color. color* col = getColor (obj->dColor); if (col) item->setForeground (0, col->qColor); } obj->qObjListEntry = item; qaItems.append (item); } qObjList->insertTopLevelItems (0, qaItems); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= void ForgeWindow::slot_selectionChanged () { /* // If the selection isn't 1 exact, disable setting contents ACTION (setContents)->setEnabled (qObjList->selectedItems().size() == 1); // If we have no selection, disable splitting quads ACTION (splitQuads)->setEnabled (qObjList->selectedItems().size() > 0); */ } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= ulong ForgeWindow::getInsertionPoint () { ulong ulIndex; if (qObjList->selectedItems().size() == 1) { // If we have a selection, put the item after it. for (ulIndex = 0; ulIndex < g_CurrentFile->objects.size(); ++ulIndex) if (g_CurrentFile->objects[ulIndex]->qObjListEntry == qObjList->selectedItems()[0]) break; if (ulIndex >= g_CurrentFile->objects.size()) return ulIndex + 1; } // Otherwise place the object at the end. return g_CurrentFile->objects.size(); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= void ForgeWindow::refresh () { buildObjList (); R->hardRefresh (); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= std::vector<LDObject*> ForgeWindow::getSelectedObjects () { std::vector<LDObject*> objs; QList<QTreeWidgetItem*> const qaItems = qObjList->selectedItems(); for (LDObject* obj : g_CurrentFile->objects) for (QTreeWidgetItem* qItem : qaItems) { if (qItem == obj->qObjListEntry) { objs.push_back (obj); break; } } return objs; } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= QIcon getIcon (const char* sIconName) { return (QIcon (str::mkfmt ("./icons/%s.png", sIconName))); }