gui_editactions.cpp

changeset 79
f8917e9d07f6
child 84
c9438ea54ed9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui_editactions.cpp	Tue Apr 09 17:41:19 2013 +0300
@@ -0,0 +1,253 @@
+/*
+ *  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 "gui.h"
+#include "common.h"
+#include "zz_setContentsDialog.h"
+#include "file.h"
+#include "zz_colorSelectDialog.h"
+
+vector<LDObject*> g_Clipboard;
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+static bool copyToClipboard () {
+	vector<LDObject*> objs = g_ForgeWindow->getSelectedObjects ();
+	
+	if (objs.size() == 0)
+		return false;
+	
+	// Clear the clipboard first.
+	for (LDObject* obj : g_Clipboard)
+		delete obj;
+	
+	g_Clipboard.clear ();
+	
+	// Now, copy the contents into the clipboard. The objects should be
+	// separate objects so that modifying the existing ones does not affect
+	// the clipboard. Thus, we add clones of the objects to the clipboard, not
+	// the objects themselves.
+	for (ulong i = 0; i < objs.size(); ++i)
+		g_Clipboard.push_back (objs[i]->clone ());
+	
+	return true;
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+ACTION (cut, "Cut", "cut", "Cut the current selection to clipboard.", CTRL (X)) {
+	if (!copyToClipboard ())
+		return;
+	
+	g_ForgeWindow->deleteSelection ();
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+ACTION (copy, "Copy", "copy", "Copy the current selection to clipboard.", CTRL (C)) {
+	copyToClipboard ();
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+ACTION (paste, "Paste", "paste", "Paste clipboard contents.", CTRL (V)) {
+	for (LDObject* obj : g_Clipboard)
+		g_CurrentFile->addObject (obj->clone ());
+	
+	g_ForgeWindow->refresh ();
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+ACTION (del, "Delete", "delete", "Delete the selection", KEY (Delete)) {
+	g_ForgeWindow->deleteSelection ();
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+static void doInline (bool bDeep) {
+	vector<LDObject*> sel = g_ForgeWindow->getSelectedObjects ();
+	
+	for (LDObject* obj : sel) {
+		// Obviously, only subfiles can be inlined.
+		if (obj->getType() != OBJ_Subfile)
+			continue;
+		
+		// Get the index of the subfile so we know where to insert the
+		// inlined contents.
+		long idx = obj->getIndex (g_CurrentFile);
+		if (idx == -1)
+			continue;
+		
+		LDSubfile* ref = static_cast<LDSubfile*> (obj);
+		
+		// Get the inlined objects. These are clones of the subfile's contents.
+		vector<LDObject*> objs = ref->inlineContents (bDeep, true);
+		
+		// Merge in the inlined objects
+		for (LDObject* inlineobj : objs)
+			g_CurrentFile->objects.insert (g_CurrentFile->objects.begin() + idx++, inlineobj);
+		
+		// Delete the subfile now as it's been inlined.
+		g_CurrentFile->forgetObject (ref);
+		delete ref;
+	}
+	
+	g_ForgeWindow->refresh ();
+}
+
+ACTION (inlineContents, "Inline", "inline", "Inline selected subfiles.", CTRL (I)) {
+	doInline (false);
+}
+
+ACTION (deepInline, "Deep Inline", "inline-deep", "Recursively inline selected subfiles "
+	"down to polygons only.", CTRL_SHIFT (I))
+{
+	doInline (true);
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+ACTION (splitQuads, "Split Quads", "quad-split", "Split quads into triangles.", (0)) {
+	vector<LDObject*> objs = g_ForgeWindow->getSelectedObjects ();
+	
+	for (LDObject* obj : objs) {
+		if (obj->getType() != OBJ_Quad)
+			continue;
+		
+		// Find the index of this quad
+		long lIndex = obj->getIndex (g_CurrentFile);
+		
+		if (lIndex == -1) {
+			// couldn't find it?
+			logf (LOG_Error, "Couldn't find quad %p in "
+				"current object list!!\n", obj);
+			return;
+		}
+		
+		std::vector<LDTriangle*> triangles = static_cast<LDQuad*> (obj)->splitToTriangles ();
+		
+		// Replace the quad with the first triangle and add the second triangle
+		// after the first one.
+		g_CurrentFile->objects[lIndex] = triangles[0];
+		g_CurrentFile->objects.insert (g_CurrentFile->objects.begin() + lIndex + 1, triangles[1]);
+		
+		// Delete this quad now, it has been split.
+		delete obj;
+	}
+	
+	g_ForgeWindow->refresh ();
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+ACTION (setContents, "Set Contents", "set-contents", "Set the raw code of this object.", KEY (F9)) {
+	if (g_ForgeWindow->qObjList->selectedItems().size() != 1)
+		return;
+	
+	LDObject* obj = g_ForgeWindow->getSelectedObjects ()[0];
+	SetContentsDialog::staticDialog (obj, g_ForgeWindow);
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+ACTION (setColor, "Set Color", "palette", "Set the color on given objects.", KEY (F10)) {
+	if (g_ForgeWindow->qObjList->selectedItems().size() <= 0)
+		return;
+	
+	short dColor;
+	short dDefault = -1;
+	
+	std::vector<LDObject*> objs = g_ForgeWindow->getSelectedObjects ();
+	
+	// If all selected objects have the same color, said color is our default
+	// value to the color selection dialog.
+	for (LDObject* obj : objs) {
+		if (obj->dColor == -1)
+			continue; // doesn't use color
+		
+		if (dDefault != -1 && obj->dColor != dDefault) {
+			// No consensus in object color, therefore we don't have a
+			// proper default value to use.
+			dDefault = -1;
+			break;
+		}
+		
+		if (dDefault == -1)
+			dDefault = obj->dColor;
+	}
+	
+	// Show the dialog to the user now and ask for a color.
+	if (ColorSelectDialog::staticDialog (dColor, dDefault, g_ForgeWindow)) {
+		for (LDObject* obj : objs)
+			if (obj->dColor != -1)
+				obj->dColor = dColor;
+		
+		g_ForgeWindow->refresh ();
+	}
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+ACTION (makeBorders, "Make Borders", "make-borders", "Add borders around given polygons.",
+	CTRL_SHIFT (B))
+{
+	vector<LDObject*> objs = g_ForgeWindow->getSelectedObjects ();
+	
+	for (LDObject* obj : objs) {
+		if (obj->getType() != OBJ_Quad && obj->getType() != OBJ_Triangle)
+			continue;
+		
+		short dNumLines;
+		LDLine* lines[4];
+		
+		if (obj->getType() == OBJ_Quad) {
+			dNumLines = 4;
+			
+			LDQuad* quad = static_cast<LDQuad*> (obj);
+			lines[0] = new LDLine (quad->vaCoords[0], quad->vaCoords[1]);
+			lines[1] = new LDLine (quad->vaCoords[1], quad->vaCoords[2]);
+			lines[2] = new LDLine (quad->vaCoords[2], quad->vaCoords[3]);
+			lines[3] = new LDLine (quad->vaCoords[3], quad->vaCoords[0]);
+		} else {
+			dNumLines = 3;
+			
+			LDTriangle* tri = static_cast<LDTriangle*> (obj);
+			lines[0] = new LDLine (tri->vaCoords[0], tri->vaCoords[1]);
+			lines[1] = new LDLine (tri->vaCoords[1], tri->vaCoords[2]);
+			lines[2] = new LDLine (tri->vaCoords[2], tri->vaCoords[0]); 
+		}
+		
+		for (short i = 0; i < dNumLines; ++i) {
+			lines[i]->dColor = dEdgeColor;
+			g_CurrentFile->addObject (lines[i]);
+		}
+	}
+	
+	g_ForgeWindow->refresh ();
+}

mercurial