Plane drawing is functional at last!!!11 Also added meta function findAction to find an action by name so I don't have to extern all of them manually in gui.cpp

Sun, 05 May 2013 17:04:42 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sun, 05 May 2013 17:04:42 +0300
changeset 163
46955613626d
parent 162
b7d65e89861a
child 164
8c93d8e38494

Plane drawing is functional at last!!!11 Also added meta function findAction to find an action by name so I don't have to extern all of them manually in gui.cpp

gldraw.cpp file | annotate | diff | comparison | revisions
gldraw.h file | annotate | diff | comparison | revisions
gui.cpp file | annotate | diff | comparison | revisions
gui.h file | annotate | diff | comparison | revisions
gui_actions.cpp file | annotate | diff | comparison | revisions
types.cpp file | annotate | diff | comparison | revisions
types.h file | annotate | diff | comparison | revisions
--- a/gldraw.cpp	Sun May 05 00:53:13 2013 +0300
+++ b/gldraw.cpp	Sun May 05 17:04:42 2013 +0300
@@ -27,6 +27,7 @@
 #include "colors.h"
 #include "gui.h"
 #include "misc.h"
+#include "history.h"
 
 static double g_objOffset[3];
 static double g_storedBBoxSize;
@@ -78,6 +79,15 @@
 	GLRenderer::Right,
 	GLRenderer::Free
 };
+
+const struct GLAxis {
+	const QColor col;
+	const vertex vert;
+} g_GLAxes[3] = {
+	{ QColor (255, 0, 0), vertex (10000, 0, 0) },
+	{ QColor (128, 192, 0), vertex (0, 10000, 0) },
+	{ QColor (0, 160, 192), vertex (0, 0, 10000) },
+};
 	
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -342,15 +352,6 @@
 	glMatrixMode (GL_MODELVIEW);
 }
 
-const struct GLAxis {
-	const QColor col;
-	const vertex vert;
-} g_GLAxes[3] = {
-	{ QColor (255, 0, 0), vertex (10000, 0, 0) },
-	{ QColor (128, 192, 0), vertex (0, 10000, 0) },
-	{ QColor (0, 160, 192), vertex (0, 0, 10000) },
-};
-
 void GLRenderer::drawGLScene () const {
 	if (g_curfile == null)
 		return;
@@ -396,6 +397,7 @@
 	glMatrixMode (GL_MODELVIEW);
 }
 
+// =============================================================================
 vertex GLRenderer::coord_2to3 (const QPoint& pos2d, const bool snap) const {
 	vertex pos3d;
 	const staticCameraMeta* cam = &g_staticCameras[m_camera];
@@ -405,8 +407,10 @@
 		negYFac = cam->negY ? -1 : 1;
 	
 	// Calculate cx and cy - these are the LDraw unit coords the cursor is at.
-	double cx = (-m_virtWidth + ((2 * pos2d.x () * m_virtWidth) / m_width) - m_panX) * g_storedBBoxSize - (negXFac * g_objOffset[axisX]);
-	double cy = (m_virtHeight - ((2 * pos2d.y () * m_virtHeight) / m_height) - m_panY) * g_storedBBoxSize - (negYFac * g_objOffset[axisY]);
+	double cx = (-m_virtWidth + ((2 * pos2d.x () * m_virtWidth) / m_width) - m_panX) *
+		g_storedBBoxSize - (negXFac * g_objOffset[axisX]);
+	double cy = (m_virtHeight - ((2 * pos2d.y () * m_virtHeight) / m_height) - m_panY) *
+		g_storedBBoxSize - (negYFac * g_objOffset[axisY]);
 	
 	if (snap) {
 		cx = Grid::snap (cx, (Grid::Config) axisX);
@@ -422,16 +426,37 @@
 	return pos3d;
 }
 
+// =============================================================================
 QPoint GLRenderer::coord_3to2 (const vertex& pos3d) const {
-	QPoint pos2d (0, 0);
-	GLdouble glmatr[16];
-	glGetDoublev (GL_MODELVIEW, glmatr);
+	/*
+	cx = (-m_virtWidth + ((2 * pos2d.x () * m_virtWidth) / m_width) - m_panX) * g_storedBBoxSize - (negXFac * g_objOffset[axisX]);
+	
+	                                                 cx = (-vw + ((2 * x * vw) / w) - panx) * size - (neg * ofs)
+	                                  cx + (neg * ofs) = (-vw + ((2 * x * vw) / w) - panx) * size
+	                         (cx + (neg * ofs)) / size = ((2 * x * vw) / w) - vw - panx
+	           ((cx + (neg * ofs)) / size) + vw + panx = (2 * x * vw) / w
+	     (((cx + (neg * ofs)) / size) + vw + panx) * w = 2 * vw * x
+	
+	x = ((((cx + (neg * ofs)) / size) + vw + panx) * w) / (2 * vw)
+	*/
 	
-	matrix<4> matr (glmatr);
+	QPoint pos2d;
+	const staticCameraMeta* cam = &g_staticCameras[m_camera];
+	const Axis axisX = cam->axisX;
+	const Axis axisY = cam->axisY;
+	const short negXFac = cam->negX ? -1 : 1,
+		negYFac = cam->negY ? -1 : 1;
 	
-	vertex copy = pos3d;
-	copy.transform (matrix<3> (matr), g_origin);
-	return QPoint (copy[X], copy[Y]);
+	short x1 = ((((pos3d[axisX] + (negXFac * g_objOffset[axisX])) / g_storedBBoxSize) +
+		m_virtWidth + m_panX) * m_width) / (2 * m_virtWidth);
+	short y1 = -((((pos3d[axisY] + (negYFac * g_objOffset[axisY])) / g_storedBBoxSize) -
+		m_virtHeight + m_panY) * m_height) / (2 * m_virtHeight);
+	
+	x1 *= negXFac;
+	y1 *= negYFac;
+	
+	pos2d = QPoint (x1, y1);
+	return pos2d;
 }
 
 // =============================================================================
@@ -465,7 +490,42 @@
 			textSize.height (), Qt::AlignCenter, text);
 		
 		// If we're plane drawing, draw the vertices onto the screen.
-		
+		if (m_planeDraw) {
+			ushort numverts = m_planeDrawVerts.size () + 1;
+			const short blipsize = 8;
+			
+			if (numverts > 0) {
+				QPoint* poly = new QPoint[numverts];
+				
+				uchar i = 0;
+				for (vertex& vert : m_planeDrawVerts) {
+					poly[i] = coord_3to2 (vert);
+					++i;
+				}
+				
+				// Draw the cursor vertex as the last one in the list.
+				if (numverts < 5)
+					poly[i] = coord_3to2 (m_hoverpos);
+				else
+					numverts = 4;
+				
+				paint.setPen (m_thinBorderPen);
+				paint.setBrush (QColor (128, 192, 0));
+				
+				// Draw vertex blips
+				for (ushort i = 0; i < numverts; ++i) {
+					QPoint& blip = poly[i];
+					paint.drawEllipse (blip.x () - blipsize / 2, blip.y () - blipsize / 2,
+						blipsize, blipsize);
+				}
+				
+				paint.setPen (m_thickBorderPen);
+				paint.setBrush (QColor (128, 192, 0, 128));
+				paint.drawPolygon (poly, numverts);
+				
+				delete[] poly;
+			}
+		}
 	}
 	
 	// Camera icons
@@ -719,9 +779,29 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 void GLRenderer::mouseReleaseEvent (QMouseEvent* ev) {
-	if ((m_lastButtons & Qt::LeftButton) && !(ev->buttons() & Qt::LeftButton)) {
+	const bool wasLeft = (m_lastButtons & Qt::LeftButton) && !(ev->buttons() & Qt::LeftButton);
+	const bool wasRight = (m_lastButtons & Qt::RightButton) && !(ev->buttons() & Qt::RightButton);
+	
+	if (wasLeft) {
 		if (m_planeDraw) {
-			m_planeDrawVerts.push_back ({m_hoverpos, m_pos});
+			printf ("vert: %s\n", m_hoverpos.stringRep (true).chars ());
+			
+			// If we picked an already-existing vertex, stop drawing
+			for (vertex& vert : m_planeDrawVerts) {
+				if (vert == m_hoverpos) {
+					endPlaneDraw (true);
+					return;
+				}
+			}
+			
+			// Also, if have 4 verts, also stop drawing.
+			if (m_planeDrawVerts.size () >= 4)
+				endPlaneDraw (true);
+			
+			m_planeDrawVerts.push_back (m_hoverpos);
+			
+			update ();
+			return;
 		} else {
 			if (!m_rangepick)
 				m_addpick = (m_keymods & Qt::ControlModifier);
@@ -732,6 +812,19 @@
 		
 		m_rangepick = false;
 		m_totalmove = 0;
+		return;
+	}
+	
+	if (wasRight && m_planeDraw) {
+		if (m_planeDrawVerts.size () > 0) {
+			// Remove the last vertex
+			m_planeDrawVerts.erase (m_planeDrawVerts.end () - 1);
+		} else {
+			endPlaneDraw (false);
+			return;
+		}
+		
+		update ();
 	}
 }
 
@@ -854,11 +947,11 @@
 	
 	// Clear the selection if we do not wish to add to it.
 	if (!m_addpick) {
-		std::vector<LDObject*> paOldSelection = g_win->sel ();
+		std::vector<LDObject*> oldsel = g_win->sel ();
 		g_win->sel ().clear ();
 		
 		// Recompile the prior selection to remove the highlight color
-		for (LDObject* obj : paOldSelection)
+		for (LDObject* obj : oldsel)
 			recompileObject (obj);
 	}
 	
@@ -974,17 +1067,94 @@
 	update ();
 }
 
+// =============================================================================
 void GLRenderer::beginPlaneDraw () {
 	if (m_camera == Free)
-		return;
+		return; // Cannot draw with the free camera
 	
 	m_planeDraw = true;
+	
+	// Disable the context menu - we need the right mouse button
+	// for removing vertices.
+	setContextMenuPolicy (Qt::NoContextMenu);
+	
+	// Use the crosshair cursor when plane drawing.
+	setCursor (Qt::CrossCursor);
+	
+	// Clear the selection when beginning to draw onto a plane.
+	// FIXME: make the selection clearing stuff in ::pick a method and use it
+	// here! This code doesn't update the GL lists.
+	g_win->sel ().clear ();
+	g_win->updateSelection ();
 	update ();
 }
 
-// ========================================================================= //
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// ========================================================================= //
+// =============================================================================
+void GLRenderer::endPlaneDraw (bool accept) {
+	// If we accepted, clean the selection and create the object
+	if (accept) {
+		vector<vertex>& verts = m_planeDrawVerts;
+		printf ("accepted (%lu verts)\n", verts.size ());
+		
+		LDObject* obj = null;
+		
+		switch (verts.size ()) {
+		case 1:
+			{
+				// 1 vertex - add a vertex object
+				obj = new LDVertex;
+				static_cast<LDVertex*> (obj)->vPosition = verts[0];
+				obj->dColor = maincolor;
+			}
+			break;
+		
+		case 2:
+			{
+				// 2 verts - make a line
+				obj = new LDLine;
+				obj->dColor = edgecolor;
+				for (ushort i = 0; i < 2; ++i)
+					obj->vaCoords[i] = verts[i];
+			}
+			break;
+			
+		case 3:
+		case 4:
+			{
+				obj = (verts.size () == 3) ?
+					static_cast<LDObject*> (new LDTriangle) :
+					static_cast<LDObject*> (new LDQuad);
+				
+				obj->dColor = maincolor;
+				for (ushort i = 0; i < obj->vertices (); ++i)
+					obj->vaCoords[i] = verts[i];
+			}
+			break;
+		}
+		
+		if (obj) {
+			g_curfile->addObject (obj);
+			recompileObject (obj);
+			g_win->refresh ();
+			
+			History::addEntry (new AddHistory ({(ulong) obj->getIndex (g_curfile)}, {obj->clone ()}));
+		}
+	}
+	
+	m_planeDraw = false;
+	m_planeDrawVerts.clear ();
+	
+	unsetCursor ();
+	
+	// Restore the context menu
+	setContextMenuPolicy (Qt::DefaultContextMenu);
+	
+	update ();
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 void GLRenderer::recompileObject (LDObject* obj) {
 	// Replace the old list with the new one.
 	GLuint uList = glGenLists (1);
--- a/gldraw.h	Sun May 05 00:53:13 2013 +0300
+++ b/gldraw.h	Sun May 05 17:04:42 2013 +0300
@@ -24,11 +24,6 @@
 #include "common.h"
 #include "ldtypes.h"
 
-typedef struct {
-	vertex pos3d;
-	QPoint pos2d;
-} GLPlaneDrawVertex;
-
 // =============================================================================
 // GLRenderer
 // 
@@ -63,9 +58,11 @@
 	void updateSelFlash ();
 	void resetAngles ();
 	uchar* screencap (ushort& w, ushort& h);
+	void setCamera (const GLRenderer::Camera cam);
 	void beginPlaneDraw ();
+	void endPlaneDraw (bool accept);
+	
 	GLRenderer::Camera camera () { return m_camera; }
-	void setCamera (const GLRenderer::Camera cam);
 	bool picking () { return m_picking; }
 
 protected:
@@ -95,7 +92,7 @@
 	Camera m_camera, m_toolTipCamera;
 	uint m_axeslist;
 	ushort m_width, m_height;
-	std::vector<GLPlaneDrawVertex> m_planeDrawVerts;
+	std::vector<vertex> m_planeDrawVerts;
 	
 	void compileOneObject (LDObject* obj);
 	void compileSubObject (LDObject* obj, const GLenum gltype);
--- a/gui.cpp	Sun May 05 00:53:13 2013 +0300
+++ b/gui.cpp	Sun May 05 17:04:42 2013 +0300
@@ -34,73 +34,6 @@
 #include "history.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 (makeCornerVerts)
-EXTERN_ACTION (moveUp)
-EXTERN_ACTION (moveDown)
-EXTERN_ACTION (newSubfile)
-EXTERN_ACTION (newLine)
-EXTERN_ACTION (newCondLine)
-EXTERN_ACTION (newTriangle)
-EXTERN_ACTION (newQuad)
-EXTERN_ACTION (newComment)
-EXTERN_ACTION (newBFC)
-EXTERN_ACTION (newVertex)
-EXTERN_ACTION (newRadial)
-EXTERN_ACTION (help)
-EXTERN_ACTION (about)
-EXTERN_ACTION (aboutQt)
-EXTERN_ACTION (undo)
-EXTERN_ACTION (redo)
-EXTERN_ACTION (showHistory)
-EXTERN_ACTION (selectAll)
-EXTERN_ACTION (selectByColor)
-EXTERN_ACTION (selectByType)
-EXTERN_ACTION (moveXNeg)
-EXTERN_ACTION (moveYNeg)
-EXTERN_ACTION (moveZNeg)
-EXTERN_ACTION (moveXPos)
-EXTERN_ACTION (moveYPos)
-EXTERN_ACTION (moveZPos)
-EXTERN_ACTION (invert)
-EXTERN_ACTION (rotateXNeg)
-EXTERN_ACTION (rotateYNeg)
-EXTERN_ACTION (rotateZNeg)
-EXTERN_ACTION (rotateXPos)
-EXTERN_ACTION (rotateYPos)
-EXTERN_ACTION (rotateZPos)
-EXTERN_ACTION (roundCoords)
-EXTERN_ACTION (gridCoarse)
-EXTERN_ACTION (gridMedium)
-EXTERN_ACTION (gridFine)
-EXTERN_ACTION (resetView)
-EXTERN_ACTION (insertFrom)
-EXTERN_ACTION (insertRaw)
-EXTERN_ACTION (screencap)
-EXTERN_ACTION (editObject)
-EXTERN_ACTION (uncolorize)
-EXTERN_ACTION (axes)
-
-#ifndef RELEASE
-EXTERN_ACTION (addTestQuad)
-EXTERN_ACTION (addTestRadial)
-#endif // RELEASE
-
 vector<actionmeta> g_ActionMeta;
 
 static bool g_bSelectionLocked = false;
@@ -175,20 +108,15 @@
 	}
 	
 	// Grid actions and axes are checkable
-	ACTION (gridCoarse)->setCheckable (true);
-	ACTION (gridMedium)->setCheckable (true);
-	ACTION (gridFine)->setCheckable (true);
+	findAction ("gridCoarse")->setCheckable (true);
+	findAction ("gridMedium")->setCheckable (true);
+	findAction ("gridFine")->setCheckable (true);
 	
-	ACTION (axes)->setCheckable (true);
-	ACTION (axes)->setChecked (gl_axes);
+	findAction ("axes")->setCheckable (true);
+	findAction ("axes")->setChecked (gl_axes);
 	
 	// things not implemented yet
-	QAction* const qaDisabledActions[] = {
-		ACTION (help),
-	};
-	
-	for (QAction* act : qaDisabledActions)
-		act->setEnabled (false);
+	findAction ("help")->setEnabled (false);
 	
 	History::updateActions ();
 }
@@ -196,109 +124,126 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
+QMenu* g_CurrentMenu;
+
+void ForgeWindow::initMenu (const char* name) {
+	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
-	QMenu* qFileMenu = menuBar ()->addMenu (tr ("&File"));
-	qFileMenu->addAction (ACTION (newFile));				// New
-	qFileMenu->addAction (ACTION (open));				// Open
-	qFileMenu->addMenu (m_recentFilesMenu);				// Open Recent
-	qFileMenu->addAction (ACTION (save));					// Save
-	qFileMenu->addAction (ACTION (saveAs));				// Save As
-	qFileMenu->addSeparator ();							// -------
-	qFileMenu->addAction (ACTION (settings));				// Settings
-	qFileMenu->addSeparator ();							// -------
-	qFileMenu->addAction (ACTION (exit));					// Exit
+	initMenu ("&File");
+	addMenuAction ("newFile");				// New
+	addMenuAction ("open");				// Open
+	menu->addMenu (m_recentFilesMenu);	// Open Recent
+	addMenuAction ("save");				// Save
+	addMenuAction ("saveAs");				// Save As
+	menu->addSeparator ();					// -------
+	addMenuAction ("settings");			// Settings
+	menu->addSeparator ();					// -------
+	addMenuAction ("exit");				// Exit
 	
 	// View menu
-	QMenu* qViewMenu = menuBar ()->addMenu (tr ("&View"));
-	qViewMenu->addAction (ACTION (resetView));			// Reset View
-	qViewMenu->addAction (ACTION (axes));					// Draw Axes
-	qViewMenu->addSeparator ();							// -----
-	qViewMenu->addAction (ACTION (screencap));			// Screencap Part
-	qViewMenu->addAction (ACTION (showHistory));			// Edit History
+	initMenu ("&View");
+	addMenuAction ("resetView");			// Reset View
+	addMenuAction ("axes");				// Draw Axes
+	menu->addSeparator ();					// -----
+	addMenuAction ("screencap");			// Screencap Part
+	addMenuAction ("showHistory");		// Edit History
 	
 	// Insert menu
-	QMenu* qInsertMenu = menuBar ()->addMenu (tr ("&Insert"));
-	qInsertMenu->addAction (ACTION (insertFrom));		// Insert from File
-	qInsertMenu->addAction (ACTION (insertRaw));			// Insert Raw
-	qInsertMenu->addSeparator ();							// -------
-	qInsertMenu->addAction (ACTION (newSubfile));		// New Subfile
-	qInsertMenu->addAction (ACTION (newLine));			// New Line
-	qInsertMenu->addAction (ACTION (newTriangle));		// New Triangle
-	qInsertMenu->addAction (ACTION (newQuad));			// New Quad
-	qInsertMenu->addAction (ACTION (newCondLine));		// New Conditional Line
-	qInsertMenu->addAction (ACTION (newComment));		// New Comment
-	qInsertMenu->addAction (ACTION (newBFC));			// New BFC Statment
-	qInsertMenu->addAction (ACTION (newVertex));			// New Vertex
-	qInsertMenu->addAction (ACTION (newRadial));			// New Radial
+	initMenu ("&Insert");
+	addMenuAction ("insertFrom");			// Insert from File
+	addMenuAction ("insertRaw");			// Insert Raw
+	menu->addSeparator ();					// -------
+	addMenuAction ("newSubfile");			// New Subfile
+	addMenuAction ("newLine");			// New Line
+	addMenuAction ("newTriangle");		// New Triangle
+	addMenuAction ("newQuad");				// New Quad
+	addMenuAction ("newCondLine");		// New Conditional Line
+	addMenuAction ("newComment");			// New Comment
+	addMenuAction ("newBFC");				// New BFC Statment
+	addMenuAction ("newVertex");			// New Vertex
+	addMenuAction ("newRadial");			// New Radial
+	menu->addSeparator ();					// -----
+	addMenuAction ("beginDraw");			// Begin Drawing
+	addMenuAction ("doneDraw");			// Cancel Drawing
+	addMenuAction ("cancelDraw");			// Done Drawing
 	
 	// Edit menu
-	QMenu* qEditMenu = menuBar ()->addMenu (tr ("&Edit"));
-	qEditMenu->addAction (ACTION (undo));					// Undo
-	qEditMenu->addAction (ACTION (redo));				// Redo
-	qEditMenu->addSeparator ();							// -----
-	qEditMenu->addAction (ACTION (cut));					// Cut
-	qEditMenu->addAction (ACTION (copy));					// Copy
-	qEditMenu->addAction (ACTION (paste));				// Paste
-	qEditMenu->addAction (ACTION (del));					// Delete
-	qEditMenu->addSeparator ();							// -----
-	qEditMenu->addAction (ACTION (selectAll));			// Select All
-	qEditMenu->addAction (ACTION (selectByColor));		// Select by Color
-	qEditMenu->addAction (ACTION (selectByType));		// Select by Type
-	qEditMenu->addSeparator ();							// -----
+	initMenu ("&Edit");
+	addMenuAction ("undo");				// Undo
+	addMenuAction ("redo");				// Redo
+	menu->addSeparator ();					// -----
+	addMenuAction ("cut");					// Cut
+	addMenuAction ("copy");				// Copy
+	addMenuAction ("paste");				// Paste
+	addMenuAction ("del");					// Delete
+	menu->addSeparator ();					// -----
+	addMenuAction ("selectAll");			// Select All
+	addMenuAction ("selectByColor");		// Select by Color
+	addMenuAction ("selectByType");		// Select by Type
 	
-	QMenu* toolsMenu = menuBar ()->addMenu (tr ("&Tools"));
-	toolsMenu->addAction (ACTION (setColor));			// Set Color
-	toolsMenu->addAction (ACTION (invert));				// Invert
-	toolsMenu->addAction (ACTION (inlineContents));		// Inline
-	toolsMenu->addAction (ACTION (deepInline));			// Deep Inline
-	toolsMenu->addAction (ACTION (splitQuads));			// Split Quads
-	toolsMenu->addAction (ACTION (setContents));			// Set Contents
-	toolsMenu->addAction (ACTION (makeBorders));			// Make Borders
-	toolsMenu->addAction (ACTION (makeCornerVerts));		// Make Corner Vertices
-	toolsMenu->addAction (ACTION (roundCoords));			// Round Coordinates
-	toolsMenu->addAction (ACTION (uncolorize));			// Uncolorize
+	initMenu ("&Tools");
+	addMenuAction ("setColor");			// Set Color
+	addMenuAction ("invert");				// Invert
+	addMenuAction ("inlineContents");		// Inline
+	addMenuAction ("deepInline");			// Deep Inline
+	addMenuAction ("splitQuads");			// Split Quads
+	addMenuAction ("setContents");		// Set Contents
+	addMenuAction ("makeBorders");		// Make Borders
+	addMenuAction ("makeCornerVerts");	// Make Corner Vertices
+	addMenuAction ("roundCoords");		// Round Coordinates
+	addMenuAction ("uncolorize");			// Uncolorize
 	
 	// Move menu
-	QMenu* qMoveMenu = menuBar ()->addMenu (tr ("&Move"));
-	qMoveMenu->addAction (ACTION (moveUp));				// Move Up
-	qMoveMenu->addAction (ACTION (moveDown));			// Move Down
-	qMoveMenu->addSeparator ();							// -----
-	qMoveMenu->addAction (ACTION (gridCoarse));			// Coarse Grid
-	qMoveMenu->addAction (ACTION (gridMedium));			// Medium Grid
-	qMoveMenu->addAction (ACTION (gridFine));			// Fine Grid
-	qMoveMenu->addSeparator ();							// -----
-	qMoveMenu->addAction (ACTION (moveXPos));			// Move +X
-	qMoveMenu->addAction (ACTION (moveXNeg));			// Move -X
-	qMoveMenu->addAction (ACTION (moveYPos));			// Move +Y
-	qMoveMenu->addAction (ACTION (moveYNeg));			// Move -Y
-	qMoveMenu->addAction (ACTION (moveZPos));			// Move +Z
-	qMoveMenu->addAction (ACTION (moveZNeg));			// Move -Z
-	qMoveMenu->addSeparator ();							// -----
-	qMoveMenu->addAction (ACTION (rotateXPos));			// Rotate +X
-	qMoveMenu->addAction (ACTION (rotateXNeg));			// Rotate -X
-	qMoveMenu->addAction (ACTION (rotateYPos));			// Rotate +Y
-	qMoveMenu->addAction (ACTION (rotateYNeg));			// Rotate -Y
-	qMoveMenu->addAction (ACTION (rotateZPos));			// Rotate +Z
-	qMoveMenu->addAction (ACTION (rotateZNeg));			// Rotate -Z
+	initMenu ("&Move");
+	addMenuAction ("moveUp");				// Move Up
+	addMenuAction ("moveDown");			// Move Down
+	menu->addSeparator ();					// -----
+	addMenuAction ("gridCoarse");			// Coarse Grid
+	addMenuAction ("gridMedium");			// Medium Grid
+	addMenuAction ("gridFine");			// Fine Grid
+	menu->addSeparator ();					// -----
+	addMenuAction ("moveXPos");			// Move +X
+	addMenuAction ("moveXNeg");			// Move -X
+	addMenuAction ("moveYPos");			// Move +Y
+	addMenuAction ("moveYNeg");			// Move -Y
+	addMenuAction ("moveZPos");			// Move +Z
+	addMenuAction ("moveZNeg");			// Move -Z
+	menu->addSeparator ();					// -----
+	addMenuAction ("rotateXPos");			// Rotate +X
+	addMenuAction ("rotateXNeg");			// Rotate -X
+	addMenuAction ("rotateYPos");			// Rotate +Y
+	addMenuAction ("rotateYNeg");			// Rotate -Y
+	addMenuAction ("rotateZPos");			// Rotate +Z
+	addMenuAction ("rotateZNeg");			// Rotate -Z
 	
 #ifndef RELEASE
 	// Debug menu
-	QMenu* qDebugMenu = menuBar ()->addMenu (tr ("&Debug"));
-	qDebugMenu->addAction (ACTION (addTestQuad));		// Add Test Quad
-	qDebugMenu->addAction (ACTION (addTestRadial));		// Add Test Radial
+	initMenu ("&Debug");
+	addMenuAction ("addTestQuad");		// Add Test Quad
+	addMenuAction ("addTestRadial");		// Add Test Radial
 #endif // RELEASE
 	
 	// Help menu
-	QMenu* qHelpMenu = menuBar ()->addMenu (tr ("&Help"));
-	qHelpMenu->addAction (ACTION (help));				// Help
-	qHelpMenu->addSeparator ();							// -----
-	qHelpMenu->addAction (ACTION (about));				// About
-	qHelpMenu->addAction (ACTION (aboutQt));				// About Qt
+	initMenu ("&Help");
+	addMenuAction ("help");				// Help
+	menu->addSeparator ();					// -----
+	addMenuAction ("about");				// About
+	addMenuAction ("aboutQt");				// About Qt
 }
 
 // =============================================================================
@@ -306,19 +251,19 @@
 // =============================================================================
 void ForgeWindow::updateRecentFilesMenu () {
 	// First, clear any items in the recent files menu
-	for (QAction* qRecent : m_recentFiles)
-		delete qRecent;
+	for (QAction* recent : m_recentFiles)
+		delete recent;
 	m_recentFiles.clear ();
 	
-	std::vector<str> zaFiles = io_recentfiles.value / "@";
-	for (long i = zaFiles.size() - 1; i >= 0; --i) {
-		str zFile = zaFiles[i];
+	std::vector<str> files = io_recentfiles.value / "@";
+	for (long i = files.size() - 1; i >= 0; --i) {
+		str file = files[i];
 		
-		QAction* qRecent = new QAction (getIcon ("open-recent"), zFile, this);
+		QAction* recent = new QAction (getIcon ("open-recent"), file, this);
 		
-		connect (qRecent, SIGNAL (triggered ()), this, SLOT (slot_recentFile ()));
-		m_recentFilesMenu->addAction (qRecent);
-		m_recentFiles.push_back (qRecent);
+		connect (recent, SIGNAL (triggered ()), this, SLOT (slot_recentFile ()));
+		m_recentFilesMenu->addAction (recent);
+		m_recentFiles.push_back (recent);
 	}
 }
 
@@ -328,81 +273,87 @@
 static QToolBar* g_CurrentToolBar;
 static Qt::ToolBarArea g_ToolBarArea = Qt::TopToolBarArea;
 
-void ForgeWindow::initSingleToolBar (const char* sName) {
-	QToolBar* toolbar = new QToolBar (sName);
+void ForgeWindow::initSingleToolBar (const char* name) {
+	QToolBar* toolbar = new QToolBar (name);
 	addToolBar (g_ToolBarArea, toolbar);
 	m_toolBars.push_back (toolbar);
 	
 	g_CurrentToolBar = toolbar;
 }
 
+// =============================================================================
+void ForgeWindow::addToolBarAction (const char* name) {
+	g_CurrentToolBar->addAction (findAction (name));
+}
+
+// =============================================================================
 void ForgeWindow::createToolbars () {
 	initSingleToolBar ("File");
-	g_CurrentToolBar->addAction (ACTION (newFile));
-	g_CurrentToolBar->addAction (ACTION (open));
-	g_CurrentToolBar->addAction (ACTION (save));
-	g_CurrentToolBar->addAction (ACTION (saveAs));
+	addToolBarAction ("newFile");
+	addToolBarAction ("open");
+	addToolBarAction ("save");
+	addToolBarAction ("saveAs");
 	
 	// ==========================================
 	initSingleToolBar ("Insert");
-	g_CurrentToolBar->addAction (ACTION (newSubfile));
-	g_CurrentToolBar->addAction (ACTION (newLine));
-	g_CurrentToolBar->addAction (ACTION (newTriangle));
-	g_CurrentToolBar->addAction (ACTION (newQuad));
-	g_CurrentToolBar->addAction (ACTION (newCondLine));
-	g_CurrentToolBar->addAction (ACTION (newComment));
-	g_CurrentToolBar->addAction (ACTION (newBFC));
-	g_CurrentToolBar->addAction (ACTION (newVertex));
-	g_CurrentToolBar->addAction (ACTION (newRadial));
+	addToolBarAction ("newSubfile");
+	addToolBarAction ("newLine");
+	addToolBarAction ("newTriangle");
+	addToolBarAction ("newQuad");
+	addToolBarAction ("newCondLine");
+	addToolBarAction ("newComment");
+	addToolBarAction ("newBFC");
+	addToolBarAction ("newVertex");
+	addToolBarAction ("newRadial");
 	
 	// ==========================================
 	initSingleToolBar ("Edit");
-	g_CurrentToolBar->addAction (ACTION (undo));
-	g_CurrentToolBar->addAction (ACTION (redo));
-	g_CurrentToolBar->addAction (ACTION (cut));
-	g_CurrentToolBar->addAction (ACTION (copy));
-	g_CurrentToolBar->addAction (ACTION (paste));
-	g_CurrentToolBar->addAction (ACTION (del));
+	addToolBarAction ("undo");
+	addToolBarAction ("redo");
+	addToolBarAction ("cut");
+	addToolBarAction ("copy");
+	addToolBarAction ("paste");
+	addToolBarAction ("del");
 	
 	// ==========================================
 	initSingleToolBar ("Select");
-	g_CurrentToolBar->addAction (ACTION (selectAll));
-	g_CurrentToolBar->addAction (ACTION (selectByColor));
-	g_CurrentToolBar->addAction (ACTION (selectByType));
+	addToolBarAction ("selectAll");
+	addToolBarAction ("selectByColor");
+	addToolBarAction ("selectByType");
 	
 	addToolBarBreak (Qt::TopToolBarArea);
 	
 	// ==========================================
 	initSingleToolBar ("Move");
-	g_CurrentToolBar->addAction (ACTION (moveUp));
-	g_CurrentToolBar->addAction (ACTION (moveDown));
-	g_CurrentToolBar->addAction (ACTION (moveXPos));
-	g_CurrentToolBar->addAction (ACTION (moveXNeg));
-	g_CurrentToolBar->addAction (ACTION (moveYPos));
-	g_CurrentToolBar->addAction (ACTION (moveYNeg));
-	g_CurrentToolBar->addAction (ACTION (moveZPos));
-	g_CurrentToolBar->addAction (ACTION (moveZNeg));
+	addToolBarAction ("moveUp");
+	addToolBarAction ("moveDown");
+	addToolBarAction ("moveXPos");
+	addToolBarAction ("moveXNeg");
+	addToolBarAction ("moveYPos");
+	addToolBarAction ("moveYNeg");
+	addToolBarAction ("moveZPos");
+	addToolBarAction ("moveZNeg");
 	
 	// ==========================================
 	initSingleToolBar ("Rotate");
-	g_CurrentToolBar->addAction (ACTION (rotateXPos));
-	g_CurrentToolBar->addAction (ACTION (rotateXNeg));
-	g_CurrentToolBar->addAction (ACTION (rotateYPos));
-	g_CurrentToolBar->addAction (ACTION (rotateYNeg));
-	g_CurrentToolBar->addAction (ACTION (rotateZPos));
-	g_CurrentToolBar->addAction (ACTION (rotateZNeg));
+	addToolBarAction ("rotateXPos");
+	addToolBarAction ("rotateXNeg");
+	addToolBarAction ("rotateYPos");
+	addToolBarAction ("rotateYNeg");
+	addToolBarAction ("rotateZPos");
+	addToolBarAction ("rotateZNeg");
 	
 	// ==========================================
 	// Grid toolbar
 	initSingleToolBar ("Grids");
-	g_CurrentToolBar->addAction (ACTION (gridCoarse));
-	g_CurrentToolBar->addAction (ACTION (gridMedium));
-	g_CurrentToolBar->addAction (ACTION (gridFine));
+	addToolBarAction ("gridCoarse");
+	addToolBarAction ("gridMedium");
+	addToolBarAction ("gridFine");
 	addToolBarBreak (Qt::TopToolBarArea);
 	
 	// ==========================================
 	initSingleToolBar ("View");
-	g_CurrentToolBar->addAction (ACTION (axes));
+	addToolBarAction ("axes");
 	
 	// ==========================================
 	// Color toolbar
@@ -413,17 +364,17 @@
 	// Left area toolbars
 	//g_ToolBarArea = Qt::LeftToolBarArea;
 	initSingleToolBar ("Tools");
-	g_CurrentToolBar->addAction (ACTION (setColor));
-	g_CurrentToolBar->addAction (ACTION (invert));
-	g_CurrentToolBar->addAction (ACTION (inlineContents));
-	g_CurrentToolBar->addAction (ACTION (deepInline));
-	g_CurrentToolBar->addAction (ACTION (splitQuads));
-	g_CurrentToolBar->addAction (ACTION (setContents));
-	g_CurrentToolBar->addAction (ACTION (makeBorders));
-	g_CurrentToolBar->addAction (ACTION (makeCornerVerts));
-	g_CurrentToolBar->addAction (ACTION (roundCoords));
-	g_CurrentToolBar->addAction (ACTION (screencap));
-	g_CurrentToolBar->addAction (ACTION (uncolorize));
+	addToolBarAction ("setColor");
+	addToolBarAction ("invert");
+	addToolBarAction ("inlineContents");
+	addToolBarAction ("deepInline");
+	addToolBarAction ("splitQuads");
+	addToolBarAction ("setContents");
+	addToolBarAction ("makeBorders");
+	addToolBarAction ("makeCornerVerts");
+	addToolBarAction ("roundCoords");
+	addToolBarAction ("screencap");
+	addToolBarAction ("uncolorize");
 	
 	
 	updateToolBars ();
@@ -488,9 +439,9 @@
 // =============================================================================
 void ForgeWindow::updateGridToolBar () {
 	// Ensure that the current grid - and only the current grid - is selected.
-	ACTION (gridCoarse)->setChecked (grid == Grid::Coarse);
-	ACTION (gridMedium)->setChecked (grid == Grid::Medium);
-	ACTION (gridFine)->setChecked (grid == Grid::Fine);
+	findAction ("gridCoarse")->setChecked (grid == Grid::Coarse);
+	findAction ("gridMedium")->setChecked (grid == Grid::Medium);
+	findAction ("gridFine")->setChecked (grid == Grid::Fine);
 }
 
 // =============================================================================
@@ -731,10 +682,10 @@
 	
 	/*
 	// If the selection isn't 1 exact, disable setting contents
-	ACTION (setContents)->setEnabled (qObjList->selectedItems().size() == 1);
+	findAction ("setContents")->setEnabled (qObjList->selectedItems().size() == 1);
 	
 	// If we have no selection, disable splitting quads
-	ACTION (splitQuads)->setEnabled (qObjList->selectedItems().size() > 0);
+	findAction ("splitQuads")->setEnabled (qObjList->selectedItems().size() > 0);
 	*/
 	
 	// Update the shared selection array, though don't do this if this was
@@ -922,19 +873,19 @@
 	QMenu* contextMenu = new QMenu;
 	
 	if (single) {
-		contextMenu->addAction (ACTION (editObject));
+		contextMenu->addAction (findAction ("editObject"));
 		contextMenu->addSeparator ();
 	}
 	
-	contextMenu->addAction (ACTION (cut));
-	contextMenu->addAction (ACTION (copy));
-	contextMenu->addAction (ACTION (paste));
-	contextMenu->addAction (ACTION (del));
+	contextMenu->addAction (findAction ("cut"));
+	contextMenu->addAction (findAction ("copy"));
+	contextMenu->addAction (findAction ("paste"));
+	contextMenu->addAction (findAction ("del"));
 	contextMenu->addSeparator ();
-	contextMenu->addAction (ACTION (setColor));
+	contextMenu->addAction (findAction ("setColor"));
 	if (single)
-		contextMenu->addAction (ACTION (setContents));
-	contextMenu->addAction (ACTION (makeBorders));
+		contextMenu->addAction (findAction ("setContents"));
+	contextMenu->addAction (findAction ("makeBorders"));
 	
 	contextMenu->exec (pos);
 }
@@ -1022,4 +973,13 @@
 	}
 	
 	m_msglog->setHtml (log);
+}
+
+// =============================================================================
+QAction* const& findAction (str name) {
+	for (actionmeta& meta : g_ActionMeta)
+		if (name == meta.name)
+			return *meta.qAct;
+	
+	return null;
 }
\ No newline at end of file
--- a/gui.h	Sun May 05 00:53:13 2013 +0300
+++ b/gui.h	Sun May 05 17:04:42 2013 +0300
@@ -45,7 +45,7 @@
 typedef struct {
 	QAction** const qAct;
 	keyseqconfig* const conf;
-	const char* const sDisplayName, *sIconName, *sDescription;
+	const char* const name, *sDisplayName, *sIconName, *sDescription;
 	void (*const handler) ();
 } actionmeta;
 
@@ -59,7 +59,7 @@
 	cfg (keyseq, key_##NAME, DEFSHORTCUT); \
 	static void actionHandler_##NAME (); \
 	static ActionAdder ActionAdderInstance_##NAME (&ACTION(NAME), DISPLAYNAME, \
-		ICONNAME, DESCR, &key_##NAME, actionHandler_##NAME); \
+		ICONNAME, DESCR, &key_##NAME, actionHandler_##NAME, #NAME); \
 	static void actionHandler_##NAME ()
 
 #define EXTERN_ACTION(NAME) extern QAction* ACTION (NAME);
@@ -88,9 +88,10 @@
 class ActionAdder {
 public:
 	ActionAdder (QAction** qAct, const char* sDisplayName, const char* sIconName,
-		const char* sDescription, keyseqconfig* conf, void (*const handler) ())
+		const char* sDescription, keyseqconfig* conf, void (*const handler) (),
+		const char* name)
 	{
-		actionmeta meta = {qAct, conf, sDisplayName, sIconName, sDescription, handler};
+		actionmeta meta = {qAct, conf, name, sDisplayName, sIconName, sDescription, handler};
 		g_ActionMeta.push_back (meta);
 	}
 };
@@ -168,7 +169,11 @@
 	void createMenuActions ();
 	void createMenus ();
 	void createToolbars ();
-	void initSingleToolBar (const char* sName);
+	void initSingleToolBar (const char* name);
+	void addToolBarAction (const char* name);
+	
+	void initMenu (const char* name);
+	void addMenuAction (const char* name);
 
 private slots:
 	void slot_selectionChanged ();
@@ -185,6 +190,7 @@
 bool confirm (str title, str msg);
 bool confirm (str msg);
 void critical (str msg);
+QAction* const& findAction (str name);
 
 // -----------------------------------------------------------------------------
 // Pointer to the instance of ForgeWindow.
--- a/gui_actions.cpp	Sun May 05 00:53:13 2013 +0300
+++ b/gui_actions.cpp	Sun May 05 17:04:42 2013 +0300
@@ -390,10 +390,18 @@
 }
 
 // =============================================================================
-MAKE_ACTION (beginPlaneDraw, "Begin drawing", "draw", "Begin drawing geometry", KEY (Space)) {
+MAKE_ACTION (beginDraw, "Begin Drawing", "draw", "Begin drawing geometry", KEY (Insert)) {
 	g_win->R ()->beginPlaneDraw ();
 }
 
+MAKE_ACTION (cancelDraw, "Cancel Drawing", "draw-cancel", "Cancel drawing geometry", KEY (Escape)) {
+	g_win->R ()->endPlaneDraw (false);
+}
+
+MAKE_ACTION (doneDraw, "Done Drawing", "draw-done", "Done drawing geometry", KEY (Enter)) {
+	g_win->R ()->endPlaneDraw (true);
+}
+
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
--- a/types.cpp	Sun May 05 00:53:13 2013 +0300
+++ b/types.cpp	Sun May 05 17:04:42 2013 +0300
@@ -29,12 +29,25 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 void vertex::transform (matrix<3> matr, vertex pos) {
-	double x2, y2, z2;
-	x2 = (matr[0] * coord (X)) + (matr[1] * coord (Y)) + (matr[2] * coord (Z)) + pos[X];
-	y2 = (matr[3] * coord (X)) + (matr[4] * coord (Y)) + (matr[5] * coord (Z)) + pos[Y];
-	z2 = (matr[6] * coord (X)) + (matr[7] * coord (Y)) + (matr[8] * coord (Z)) + pos[Z];
+	double x2 = (matr[0] * x ()) + (matr[1] * y ()) + (matr[2] * z ()) + pos[X];
+	double y2 = (matr[3] * x ()) + (matr[4] * y ()) + (matr[5] * z ()) + pos[Y];
+	double z2 = (matr[6] * x ()) + (matr[7] * y ()) + (matr[8] * z ()) + pos[Z];
 	
-	coord (X) = x2;
-	coord (Y) = y2;
-	coord (Z) = z2;
+	x () = x2;
+	y () = y2;
+	z () = z2;
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void vertex::transform (matrix<4> matr) {
+	double x2 = (matr[0] * x ()) + (matr[4] + y ()) + (matr[8] + z ()) + matr[12];
+	double y2 = (matr[1] * x ()) + (matr[5] + y ()) + (matr[9] + z ()) + matr[13];
+	double z2 = (matr[2] * x ()) + (matr[6] + y ()) + (matr[10] + z ()) + matr[14];
+	double w2 = (matr[3] * x ()) + (matr[7] + y ()) + (matr[11] + z ()) + matr[15];
+	
+	x () = x2 / w2;
+	y () = y2 / w2;
+	z () = z2 / w2;
 }
\ No newline at end of file
--- a/types.h	Sun May 05 00:53:13 2013 +0300
+++ b/types.h	Sun May 05 17:04:42 2013 +0300
@@ -114,7 +114,7 @@
 	void puts () const {
 		for (short i = 0; i < N; ++i) {
 			for (short j = 0; j < N; ++j)
-				printf ("%*f\t", 10, m_vals[(i * 3) + j]);
+				printf ("%*f\t", 10, m_vals[(i * N) + j]);
 			
 			printf ("\n");
 		}
@@ -176,6 +176,16 @@
 		return *this;
 	}
 	
+	bool operator== (const vertex& other) const {
+		return coord (X) == other[X] &&
+			coord (Y) == other[Y] &&
+			coord (Z) == other[Z];
+	}
+	
+	bool operator!= (const vertex& other) const {
+		return !operator== (other);
+	}
+	
 	vertex operator- () const {
 		return vertex (-m_coords[X], -m_coords[Y], -m_coords[Z]);
 	}
@@ -196,9 +206,17 @@
 		return coord ((ushort) ax);
 	}
 	
+	double& x () { return m_coords[X]; }
+	double& y () { return m_coords[Y]; }
+	double& z () { return m_coords[Z]; }
+	const double& x () const { return m_coords[X]; }
+	const double& y () const { return m_coords[Y]; }
+	const double& z () const { return m_coords[Z]; }
+	
 	vertex midpoint (vertex& other);
 	str stringRep (const bool mangled);
 	void transform (matrix<3> matr, vertex pos);
+	void transform (matrix<4> matr);
 };
 
 #endif // TYPES_H
\ No newline at end of file

mercurial