Added three configurable grid layouts, coarse, medium and fine grids, like those of MLCad. The grids are considerably finer by default simply because part editing works at a lower scale than model editing.

Mon, 22 Apr 2013 03:53:21 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Mon, 22 Apr 2013 03:53:21 +0300
changeset 124
7962744759ad
parent 123
a54d9d5c0c1f
child 125
7ee7aa5e28be

Added three configurable grid layouts, coarse, medium and fine grids, like those of MLCad. The grids are considerably finer by default simply because part editing works at a lower scale than model editing.

gui.cpp file | annotate | diff | comparison | revisions
gui.h file | annotate | diff | comparison | revisions
gui_actions.cpp file | annotate | diff | comparison | revisions
gui_editactions.cpp file | annotate | diff | comparison | revisions
misc.cpp file | annotate | diff | comparison | revisions
misc.h file | annotate | diff | comparison | revisions
zz_configDialog.cpp file | annotate | diff | comparison | revisions
zz_configDialog.h file | annotate | diff | comparison | revisions
--- a/gui.cpp	Sun Apr 21 19:03:53 2013 +0300
+++ b/gui.cpp	Mon Apr 22 03:53:21 2013 +0300
@@ -297,6 +297,7 @@
 	ADD_TOOLBAR_ITEM (save)
 	ADD_TOOLBAR_ITEM (saveAs)
 	
+	// ==========================================
 	initSingleToolBar ("Insert");
 	ADD_TOOLBAR_ITEM (newSubfile)
 	ADD_TOOLBAR_ITEM (newLine)
@@ -307,6 +308,7 @@
 	ADD_TOOLBAR_ITEM (newVertex)
 	ADD_TOOLBAR_ITEM (newRadial)
 	
+	// ==========================================
 	initSingleToolBar ("Edit");
 	ADD_TOOLBAR_ITEM (undo)
 	ADD_TOOLBAR_ITEM (redo)
@@ -315,12 +317,14 @@
 	ADD_TOOLBAR_ITEM (paste)
 	ADD_TOOLBAR_ITEM (del)
 	
+	// ==========================================
 	initSingleToolBar ("Select");
 	ADD_TOOLBAR_ITEM (selectByColor)
 	ADD_TOOLBAR_ITEM (selectByType)
 	
 	addToolBarBreak (Qt::TopToolBarArea);
 	
+	// ==========================================
 	initSingleToolBar ("Move");
 	ADD_TOOLBAR_ITEM (moveUp)
 	ADD_TOOLBAR_ITEM (moveDown)
@@ -331,6 +335,7 @@
 	ADD_TOOLBAR_ITEM (moveZPos)
 	ADD_TOOLBAR_ITEM (moveZNeg)
 	
+	// ==========================================
 	initSingleToolBar ("Rotate");
 	ADD_TOOLBAR_ITEM (rotateXPos)
 	ADD_TOOLBAR_ITEM (rotateXNeg)
@@ -340,6 +345,21 @@
 	ADD_TOOLBAR_ITEM (rotateZNeg)
 	
 	// ==========================================
+	// Grid toolbar
+	qGridToolBar = new QToolBar ("Grids");
+	addToolBar (Qt::TopToolBarArea, qGridToolBar);
+	
+	for (int i = 0; i < g_NumGrids; ++i) {
+		QIcon icon = getIcon (format ("grid-%s", str (g_GridInfo[i].name).tolower ().chars ()));
+		gridActions[i] = new QAction (icon, "", this);
+		gridActions[i]->setCheckable (true);
+		
+		qGridToolBar->addAction (gridActions[i]);
+		
+		connect (gridActions[i], SIGNAL (triggered ()), this, SLOT (slot_setGrid ()));
+	}
+	
+	// ==========================================
 	// Color toolbar
 	qColorToolBar = new QToolBar ("Quick Colors");
 	addToolBar (Qt::RightToolBarArea, qColorToolBar);
@@ -411,6 +431,9 @@
 			entry.btn = qColorButton;
 		}
 	}
+	
+	for (short i = 0; i < g_NumGrids; ++i)
+		gridActions[i]->setChecked (i == grid);
 }
 
 // ========================================================================= //
@@ -636,9 +659,9 @@
 	updateSelection ();
 }
 
-// ========================================================================= //
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// ========================================================================= //
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 void ForgeWindow::slot_selectionChanged () {
 	if (g_bSelectionLocked == true)
 		return;
@@ -669,17 +692,15 @@
 	}
 }
 
-// ========================================================================= //
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// ========================================================================= //
+// =============================================================================
 void ForgeWindow::slot_recentFile () {
 	QAction* qAct = static_cast<QAction*> (sender ());
 	openMainFile (qAct->text ());
 }
 
-// ========================================================================= //
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// ========================================================================= //
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 void ForgeWindow::slot_quickColor () {
 	QPushButton* qBtn = static_cast<QPushButton*> (sender ());
 	color* col = null;
@@ -712,9 +733,27 @@
 	refresh ();
 }
 
-// ========================================================================= //
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// ========================================================================= //
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void ForgeWindow::slot_setGrid () {
+	short idx;
+	for (idx = 0; idx < g_NumGrids; ++idx)
+		if (sender () == gridActions[idx])
+			break;
+	
+	assert (idx < g_NumGrids);
+	
+	grid = idx;
+	
+	for (short i = 0; i < g_NumGrids; ++i)
+		if (i != idx)
+			gridActions[i]->setChecked (false);
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 ulong ForgeWindow::getInsertionPoint () {
 	ulong ulIndex;
 	
@@ -732,17 +771,17 @@
 	return g_CurrentFile->objects.size();
 }
 
-// ========================================================================= //
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// ========================================================================= //
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 void ForgeWindow::refresh () {
 	buildObjList ();
 	R->hardRefresh ();
 }
 
-// ========================================================================= //
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// ========================================================================= //
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 std::vector<LDObject*> ForgeWindow::getSelectedObjects () {
 	std::vector<LDObject*> objs;
 	
@@ -762,9 +801,9 @@
 	return objs;
 }
 
-// ========================================================================= //
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// ========================================================================= //
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 void ForgeWindow::updateSelection () {
 	g_bSelectionLocked = true;
 	
@@ -775,9 +814,9 @@
 	slot_selectionChanged ();
 }
 
-// ========================================================================= //
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// ========================================================================= //
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 bool ForgeWindow::isSelected (LDObject* obj) {
 	LDObject* pNeedle = obj->topLevelParent ();
 	
@@ -807,9 +846,9 @@
 	return dResult;
 }
 
-// ========================================================================= //
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// ========================================================================= //
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 LDObjectType_e ForgeWindow::getSelectedType () {
 	LDObjectType_e eResult = OBJ_Unidentified;
 	
@@ -824,21 +863,21 @@
 	return eResult;
 }
 
-// ========================================================================= //
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// ========================================================================= //
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 std::vector<LDObject*>& ForgeWindow::selection () {
 	return paSelection;
 }
 
-// ========================================================================= //
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-// ========================================================================= //
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 QIcon getIcon (const char* sIconName) {
 	return (QIcon (format ("./icons/%s.png", sIconName)));
 }
 
-// ========================================================================= //
+// =============================================================================
 bool confirm (str zMessage) {
 	return QMessageBox::question (g_ForgeWindow, "Confirm", zMessage,
 		(QMessageBox::Yes | QMessageBox::No), QMessageBox::No) == QMessageBox::Yes;
--- a/gui.h	Sun Apr 21 19:03:53 2013 +0300
+++ b/gui.h	Mon Apr 22 03:53:21 2013 +0300
@@ -123,6 +123,10 @@
 	QToolBar* qColorToolBar;
 	std::vector<quickColorMetaEntry> quickColorMeta;
 	
+	// Grid buttons
+	QAction* gridActions[3];
+	QToolBar* qGridToolBar;
+	
 	// Selected objects
 	std::vector<LDObject*> paSelection;
 	
@@ -154,6 +158,7 @@
 	void slot_action ();
 	void slot_recentFile ();
 	void slot_quickColor ();
+	void slot_setGrid ();
 };
 
 // -----------------------------------------------------------------------------
--- a/gui_actions.cpp	Sun Apr 21 19:03:53 2013 +0300
+++ b/gui_actions.cpp	Mon Apr 22 03:53:21 2013 +0300
@@ -16,10 +16,8 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <errno.h>
 #include <qfiledialog.h>
 #include <qmessagebox.h>
-#include <qboxlayout.h>
 #include "gui.h"
 #include "file.h"
 #include "history.h"
--- a/gui_editactions.cpp	Sun Apr 21 19:03:53 2013 +0300
+++ b/gui_editactions.cpp	Mon Apr 22 03:53:21 2013 +0300
@@ -403,9 +403,14 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-void doMoveObjects (const vertex vVector) {
+void doMoveObjects (vertex vVector) {
 	vector<ulong> ulaIndices;
 	
+	// Apply the grid values
+	vVector.x *= currentGrid ().confs[Grid::X]->value;
+	vVector.y *= currentGrid ().confs[Grid::Y]->value;
+	vVector.z *= currentGrid ().confs[Grid::Z]->value;
+	
 	for (LDObject* obj : g_ForgeWindow->selection ()) {
 		ulaIndices.push_back (obj->getIndex (g_CurrentFile));
 		obj->move (vVector);
@@ -572,9 +577,7 @@
 	bbox box;
 	vertex origin;
 	std::vector<vertex*> queue;
-	
-	// TODO: generalize the angle
-	const double angle = (pi * 22.5f) / 360;
+	const double angle = (pi * currentGrid ().confs[Grid::Angle]->value) / 360;
 	
 	// ref: http://en.wikipedia.org/wiki/Transformation_matrix#Rotation_2
 	matrix transform (
--- a/misc.cpp	Sun Apr 21 19:03:53 2013 +0300
+++ b/misc.cpp	Mon Apr 22 03:53:21 2013 +0300
@@ -78,6 +78,31 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
+// Grid stuff
+cfg (int, grid, Grid::Medium);
+
+cfg (float, grid_coarse_x,		5.0f);
+cfg (float, grid_coarse_y,		5.0f);
+cfg (float, grid_coarse_z,		5.0f);
+cfg (float, grid_coarse_angle,	45.0f);
+cfg (float, grid_medium_x,		1.0f);
+cfg (float, grid_medium_y,		1.0f);
+cfg (float, grid_medium_z,		1.0f);
+cfg (float, grid_medium_angle,	22.5f);
+cfg (float, grid_fine_x,		0.1f);
+cfg (float, grid_fine_y,		0.1f);
+cfg (float, grid_fine_z,		0.1f);
+cfg (float, grid_fine_angle,	7.5f);
+
+const gridinfo g_GridInfo[3] = {
+	{ "Coarse",	{ &grid_coarse_x,	&grid_coarse_y,	&grid_coarse_z,	&grid_coarse_angle	} },
+	{ "Medium",	{ &grid_medium_x,	&grid_medium_y,	&grid_medium_z,	&grid_medium_angle	} },
+	{ "Fine",	{ &grid_fine_x,		&grid_fine_y,	&grid_fine_z,	&grid_fine_angle	} }
+};
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 str ftoa (double fCoord) {
 	// Disable the locale first so that the decimal point will not
 	// turn into anything weird (like commas)
--- a/misc.h	Sun Apr 21 19:03:53 2013 +0300
+++ b/misc.h	Mon Apr 22 03:53:21 2013 +0300
@@ -36,6 +36,35 @@
 // Simplifies the given fraction.
 void simplify (short& dNum, short& dDenom);
 
+// Grid stuff
+typedef struct {
+	const char* const name;
+	floatconfig* const confs[4];
+} gridinfo;
+
+namespace Grid {
+	enum Type {
+		Coarse,
+		Medium,
+		Fine
+	};
+	
+	enum Config {
+		X,
+		Y,
+		Z,
+		Angle
+	};
+};
+
+extern_cfg (int, grid);
+static const short g_NumGrids = 3;
+extern const gridinfo g_GridInfo[3];
+
+inline const gridinfo& currentGrid () {
+	return g_GridInfo[grid];
+}
+
 // =============================================================================
 // StringParser
 //
--- a/zz_configDialog.cpp	Sun Apr 21 19:03:53 2013 +0300
+++ b/zz_configDialog.cpp	Mon Apr 22 03:53:21 2013 +0300
@@ -58,6 +58,7 @@
 	initMainTab ();
 	initShortcutsTab ();
 	initQuickColorTab ();
+	initGridTab ();
 	
 	IMPLEMENT_DIALOG_BUTTONS
 	
@@ -248,6 +249,53 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
+void ConfigDialog::initGridTab () {
+	QWidget* tab = new QWidget;
+	QGridLayout* layout = new QGridLayout;
+	QVBoxLayout* l2 = new QVBoxLayout;
+	
+	QLabel* xlabel = new QLabel ("X"),
+		*ylabel = new QLabel ("Y"),
+		*zlabel = new QLabel ("Z"),
+		*anglabel = new QLabel ("Angle");
+	
+	short i = 1;
+	for (QLabel* label : std::initializer_list<QLabel*> ({xlabel, ylabel, zlabel, anglabel})) {
+		label->setAlignment (Qt::AlignCenter);
+		layout->addWidget (label, 0, i++);
+	}
+	
+	for (int i = 0; i < g_NumGrids; ++i) {
+		// Icon
+		gridIcons[i] = new QLabel;
+		gridIcons[i]->setPixmap (QPixmap (format ("icons/grid-%s", str (g_GridInfo[i].name).tolower ().chars ())));
+		
+		// Text label
+		gridLabels[i] = new QLabel (format ("%s:", g_GridInfo[i].name));
+		
+		QHBoxLayout* labellayout = new QHBoxLayout;
+		labellayout->addWidget (gridIcons[i]);
+		labellayout->addWidget (gridLabels[i]);
+		layout->addLayout (labellayout, i + 1, 0);
+		
+		// Add the widgets
+		for (int j = 0; j < 4; ++j) {
+			gridData[i][j] = new QDoubleSpinBox;
+			gridData[i][j]->setValue (g_GridInfo[i].confs[j]->value);
+			layout->addWidget (gridData[i][j], i + 1, j + 1);
+		}
+	}
+	
+	l2->addLayout (layout);
+	l2->addStretch (1);
+	
+	tab->setLayout (l2);
+	qTabs->addTab (tab, "Grids");
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 void ConfigDialog::updateQuickColorList (quickColorMetaEntry* pSel) {
 	for (QListWidgetItem* qItem : qaQuickColorItems)
 		delete qItem;
@@ -564,6 +612,11 @@
 		g_ForgeWindow->quickColorMeta = dlg.quickColorMeta;
 		gui_colortoolbar = dlg.makeColorToolBarString ();
 		
+		// Set the grid settings
+		for (int i = 0; i < g_NumGrids; ++i)
+			for (int j = 0; j < 4; ++j)
+				g_GridInfo[i].confs[j]->value = dlg.gridData[i][j]->value ();
+		
 		// Save the config
 		config::save ();
 		
--- a/zz_configDialog.h	Sun Apr 21 19:03:53 2013 +0300
+++ b/zz_configDialog.h	Mon Apr 22 03:53:21 2013 +0300
@@ -24,6 +24,7 @@
 #include <qpushbutton.h>
 #include <qcheckbox.h>
 #include <qlistwidget.h>
+#include <qspinbox.h>
 
 class ConfigDialog : public QDialog {
 	Q_OBJECT
@@ -58,6 +59,12 @@
 	std::vector<quickColorMetaEntry> quickColorMeta;
 	
 	// =========================================================================
+	// Grid tab
+	QLabel* gridLabels[3];
+	QLabel* gridIcons[3];
+	QDoubleSpinBox* gridData[3][4];
+	
+	// =========================================================================
 	QDialogButtonBox* qButtons;
 	
 	ConfigDialog (ForgeWindow* parent);
@@ -68,6 +75,7 @@
 	void initMainTab ();
 	void initShortcutsTab ();
 	void initQuickColorTab ();
+	void initGridTab ();
 	
 	void makeSlider (QSlider*& qSlider, short int dMin, short int dMax, short int dDefault);
 	void setButtonBackground (QPushButton* qButton, str zValue);

mercurial