Split PrimitivePrompt into its new source files, renamed it to GeneratePrimitivePrompt

Tue, 16 Feb 2016 01:39:06 +0200

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Tue, 16 Feb 2016 01:39:06 +0200
changeset 1019
a2e4286adb0d
parent 1018
49358df9495b
child 1020
815a040d4039

Split PrimitivePrompt into its new source files, renamed it to GeneratePrimitivePrompt
Added PrimitiveSpec structure and used it to pass primitive specifications instead of 4 separate variables

CMakeLists.txt file | annotate | diff | comparison | revisions
src/dialogs/generateprimitivedialog.cpp file | annotate | diff | comparison | revisions
src/dialogs/generateprimitivedialog.h file | annotate | diff | comparison | revisions
src/dialogs/generateprimitivedialog.ui file | annotate | diff | comparison | revisions
src/editmodes/circleMode.cpp file | annotate | diff | comparison | revisions
src/primitives.cpp file | annotate | diff | comparison | revisions
src/primitives.h file | annotate | diff | comparison | revisions
src/toolsets/filetoolset.cpp file | annotate | diff | comparison | revisions
ui/makeprim.ui file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Tue Feb 16 00:59:50 2016 +0200
+++ b/CMakeLists.txt	Tue Feb 16 01:39:06 2016 +0200
@@ -61,6 +61,7 @@
 	src/version.cpp
 	src/dialogs/colorselector.cpp
 	src/dialogs/configdialog.cpp
+	src/dialogs/generateprimitivedialog.cpp
 	src/dialogs/ldrawpathdialog.cpp
 	src/dialogs/newpartdialog.cpp
 	src/dialogs/openprogressdialog.cpp
@@ -68,7 +69,7 @@
 	src/editmodes/circleMode.cpp
 	src/editmodes/curvemode.cpp
 	src/editmodes/drawMode.cpp
-    src/editmodes/linePathMode.cpp
+	src/editmodes/linePathMode.cpp
 	src/editmodes/magicWandMode.cpp
 	src/editmodes/rectangleMode.cpp
 	src/editmodes/selectMode.cpp
@@ -115,6 +116,7 @@
 	src/transform.h
 	src/dialogs/colorselector.h
 	src/dialogs/configdialog.h
+	src/dialogs/generateprimitivedialog.h
 	src/dialogs/ldrawpathdialog.h
 	src/dialogs/newpartdialog.h
 	src/dialogs/openprogressdialog.h
@@ -145,7 +147,6 @@
 	ui/flip.ui
 	ui/intersector.ui
 	ui/isecalc.ui
-	ui/makeprim.ui
 	ui/overlay.ui
 	ui/rectifier.ui
 	ui/replcoords.ui
@@ -155,6 +156,7 @@
 	src/partdownloader.ui
 	src/dialogs/colorselector.ui
 	src/dialogs/configdialog.ui
+	src/dialogs/generateprimitivedialog.ui
 	src/dialogs/ldrawpathdialog.ui
 	src/dialogs/newpartdialog.ui
 	src/dialogs/openprogressdialog.ui
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dialogs/generateprimitivedialog.cpp	Tue Feb 16 01:39:06 2016 +0200
@@ -0,0 +1,45 @@
+#include "../ldObject.h"
+#include "generateprimitivedialog.h"
+#include "ui_generateprimitivedialog.h"
+
+GeneratePrimitiveDialog::GeneratePrimitiveDialog (QWidget* parent, Qt::WindowFlags f) :
+	QDialog (parent, f),
+	ui(*new Ui_GeneratePrimitiveDialog)
+{
+	ui.setupUi (this);
+	connect (ui.highResolution, &QCheckBox::toggled, this, &GeneratePrimitiveDialog::highResolutionToggled);
+}
+
+
+GeneratePrimitiveDialog::~GeneratePrimitiveDialog()
+{
+	delete &ui;
+}
+
+
+void GeneratePrimitiveDialog::highResolutionToggled (bool on)
+{
+	ui.segments->setMaximum (on ? HighResolution : LowResolution);
+
+	// If the current value is 16 and we switch to hi-res, default the
+	// spinbox to 48. (should we scale this?)
+	if (on and ui.segments->value() == LowResolution)
+		ui.segments->setValue(HighResolution);
+}
+
+
+PrimitiveSpec GeneratePrimitiveDialog::spec() const
+{
+	PrimitiveSpec result;
+	result.type =
+		ui.typeCircle->isChecked()       ? Circle :
+		ui.typeCylinder->isChecked()     ? Cylinder :
+		ui.typeDisc->isChecked()         ? Disc :
+		ui.typeDiscNegative->isChecked() ? DiscNegative :
+		ui.typeRing->isChecked()         ? Ring :
+										   Cone;
+	result.divisions = ui.highResolution->isChecked() ? HighResolution : LowResolution;
+	result.segments = ui.segments->value();
+	result.ringNumber = ui.ringNumber->value();
+	return result;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dialogs/generateprimitivedialog.h	Tue Feb 16 01:39:06 2016 +0200
@@ -0,0 +1,21 @@
+#pragma once
+#include <QDialog>
+#include "../primitives.h"
+
+class Ui_GeneratePrimitiveDialog;
+
+class GeneratePrimitiveDialog : public QDialog
+{
+	Q_OBJECT
+
+public:
+	GeneratePrimitiveDialog(QWidget* parent = nullptr, Qt::WindowFlags f = 0);
+	virtual ~GeneratePrimitiveDialog();
+	PrimitiveSpec spec() const;
+
+public slots:
+	void highResolutionToggled (bool on);
+
+private:
+	Ui_GeneratePrimitiveDialog& ui;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dialogs/generateprimitivedialog.ui	Tue Feb 16 01:39:06 2016 +0200
@@ -0,0 +1,309 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>GeneratePrimitiveDialog</class>
+ <widget class="QDialog" name="GeneratePrimitiveDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>413</width>
+    <height>169</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Generate Primitive</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
+     <item>
+      <layout class="QVBoxLayout" name="verticalLayout_6">
+       <item>
+        <widget class="QGroupBox" name="groupbox">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="title">
+          <string>Type</string>
+         </property>
+         <layout class="QGridLayout" name="gridLayout_3">
+          <item row="1" column="0">
+           <widget class="QRadioButton" name="typeCircle">
+            <property name="text">
+             <string>Circle</string>
+            </property>
+            <property name="checked">
+             <bool>true</bool>
+            </property>
+            <property name="autoRepeat">
+             <bool>false</bool>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QRadioButton" name="typeCylinder">
+            <property name="text">
+             <string>Cylinder</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="0">
+           <widget class="QRadioButton" name="typeDisc">
+            <property name="text">
+             <string>Disc</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QRadioButton" name="typeDiscNegative">
+            <property name="text">
+             <string>Disc Negative</string>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="0">
+           <widget class="QRadioButton" name="typeRing">
+            <property name="text">
+             <string>Ring</string>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="1">
+           <widget class="QRadioButton" name="typeCone">
+            <property name="text">
+             <string>Cone</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <layout class="QVBoxLayout" name="verticalLayout_2">
+       <item>
+        <spacer name="verticalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QCheckBox" name="highResolution">
+         <property name="text">
+          <string>High resolution (48)</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <layout class="QGridLayout" name="gridLayout_2">
+         <item row="0" column="0">
+          <widget class="QLabel" name="label">
+           <property name="text">
+            <string>Segments:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="label_2">
+           <property name="text">
+            <string>Ring number:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1">
+          <widget class="QSpinBox" name="segments">
+           <property name="minimum">
+            <number>1</number>
+           </property>
+           <property name="maximum">
+            <number>16</number>
+           </property>
+           <property name="value">
+            <number>16</number>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QSpinBox" name="ringNumber">
+           <property name="enabled">
+            <bool>false</bool>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>GeneratePrimitiveDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>254</x>
+     <y>140</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>146</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>GeneratePrimitiveDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>322</x>
+     <y>140</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>146</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>typeCircle</sender>
+   <signal>clicked(bool)</signal>
+   <receiver>ringNumber</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>45</x>
+     <y>41</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>305</x>
+     <y>86</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>typeCylinder</sender>
+   <signal>clicked(bool)</signal>
+   <receiver>ringNumber</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>109</x>
+     <y>42</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>287</x>
+     <y>86</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>typeDisc</sender>
+   <signal>clicked(bool)</signal>
+   <receiver>ringNumber</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>49</x>
+     <y>66</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>287</x>
+     <y>87</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>typeDiscNegative</sender>
+   <signal>clicked(bool)</signal>
+   <receiver>ringNumber</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>121</x>
+     <y>58</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>288</x>
+     <y>83</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>typeRing</sender>
+   <signal>clicked(bool)</signal>
+   <receiver>ringNumber</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>45</x>
+     <y>90</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>301</x>
+     <y>86</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>typeCone</sender>
+   <signal>clicked(bool)</signal>
+   <receiver>ringNumber</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>111</x>
+     <y>89</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>302</x>
+     <y>85</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+ <slots>
+  <slot>enableRingNumber()</slot>
+ </slots>
+</ui>
--- a/src/editmodes/circleMode.cpp	Tue Feb 16 00:59:50 2016 +0200
+++ b/src/editmodes/circleMode.cpp	Tue Feb 16 01:39:06 2016 +0200
@@ -77,8 +77,10 @@
 void CircleMode::buildCircle()
 {
 	LDObjectList objs;
-	const int segments (m_window->ringToolSegments());
-	const int divisions (m_window->ringToolHiRes() ? HighResolution : LowResolution);
+	PrimitiveSpec spec;
+	spec.segments = m_window->ringToolSegments();
+	spec.divisions = m_window->ringToolHiRes() ? HighResolution : LowResolution;
+	spec.ringNumber = 0;
 	double dist0 (getCircleDrawDist (0));
 	double dist1 (getCircleDrawDist (1));
 	LDDocument* refFile;
@@ -91,23 +93,28 @@
 	if (dist0 == dist1)
 	{
 		// If the radii are the same, there's no ring space to fill. Use a circle.
-		refFile = primitives()->getPrimitive(::Circle, segments, divisions, 0);
+		spec.type = ::Circle;
+		refFile = primitives()->getPrimitive(spec);
 		transform = getCircleDrawMatrix (dist0);
 		circleOrDisc = true;
 	}
 	else if (dist0 == 0 or dist1 == 0)
 	{
 		// If either radii is 0, use a disc.
-		refFile = primitives()->getPrimitive(::Disc, segments, divisions, 0);
+		spec.type = ::Disc;
+		refFile = primitives()->getPrimitive(spec);
 		transform = getCircleDrawMatrix ((dist0 != 0) ? dist0 : dist1);
 		circleOrDisc = true;
 	}
 	else if (g_RingFinder.findRings (dist0, dist1))
 	{
 		// The ring finder found a solution, use that. Add the component rings to the file.
+		spec.type = ::Ring;
+
 		for (const RingFinder::Component& cmp : g_RingFinder.bestSolution()->getComponents())
 		{
-			refFile = primitives()->getPrimitive(::Ring, segments, divisions, cmp.num);
+			spec.ringNumber = cmp.num;
+			refFile = primitives()->getPrimitive(spec);
 			LDSubfileReference* ref = LDSpawn<LDSubfileReference>();
 			ref->setFileInfo (refFile);
 			ref->setTransform (getCircleDrawMatrix (cmp.scale));
@@ -132,10 +139,10 @@
 		templ.setCoordinate (localz, renderer()->getDepthValue());
 
 		// Calculate circle coords
-		primitives()->makeCircle(segments, divisions, dist0, c0);
-		primitives()->makeCircle(segments, divisions, dist1, c1);
+		primitives()->makeCircle(spec.segments, spec.divisions, dist0, c0);
+		primitives()->makeCircle(spec.segments, spec.divisions, dist1, c1);
 
-		for (int i = 0; i < segments; ++i)
+		for (int i = 0; i < spec.segments; ++i)
 		{
 			Vertex v0, v1, v2, v3;
 			v0 = v1 = v2 = v3 = templ;
--- a/src/primitives.cpp	Tue Feb 16 00:59:50 2016 +0200
+++ b/src/primitives.cpp	Tue Feb 16 01:39:06 2016 +0200
@@ -28,18 +28,6 @@
 #include "ldpaths.h"
 #include "documentmanager.h"
 
-QList<PrimitiveCategory*> m_categories;
-
-static const QStringList g_radialNameRoots =
-{
-	"edge",
-	"cyli",
-	"disc",
-	"ndis",
-	"ring",
-	"con"
-};
-
 PrimitiveScanner* PrimitiveManager::activeScanner()
 {
 	return m_activeScanner;
@@ -409,22 +397,22 @@
 
 // =============================================================================
 //
-LDObjectList PrimitiveManager::makePrimitiveBody (PrimitiveType type, int segs, int divs, int num)
+LDObjectList PrimitiveManager::makePrimitiveBody(const PrimitiveSpec& spec)
 {
 	LDObjectList objs;
 	QList<int> conditionalLineSegments;
 	QList<QLineF> circle;
 
-	makeCircle (segs, divs, 1, circle);
+	makeCircle (spec.segments, spec.divisions, 1, circle);
 
-	for (int i = 0; i < segs; ++i)
+	for (int i = 0; i < spec.segments; ++i)
 	{
 		double x0 = circle[i].x1();
 		double x1 = circle[i].x2();
 		double z0 = circle[i].y1();
 		double z1 = circle[i].y2();
 
-		switch (type)
+		switch (spec.type)
 		{
 		case Circle:
 			{
@@ -446,7 +434,7 @@
 				double x2, x3, z2, z3;
 				double y0, y1, y2, y3;
 
-				if (type == Cylinder)
+				if (spec.type == Cylinder)
 				{
 					x2 = x1;
 					x3 = x0;
@@ -458,17 +446,17 @@
 				}
 				else
 				{
-					x2 = x1 * (num + 1);
-					x3 = x0 * (num + 1);
-					z2 = z1 * (num + 1);
-					z3 = z0 * (num + 1);
+					x2 = x1 * (spec.ringNumber + 1);
+					x3 = x0 * (spec.ringNumber + 1);
+					z2 = z1 * (spec.ringNumber + 1);
+					z3 = z0 * (spec.ringNumber + 1);
 
-					x0 *= num;
-					x1 *= num;
-					z0 *= num;
-					z1 *= num;
+					x0 *= spec.ringNumber;
+					x1 *= spec.ringNumber;
+					z0 *= spec.ringNumber;
+					z1 *= spec.ringNumber;
 
-					if (type == Ring)
+					if (spec.type == Ring)
 						y0 = y1 = y2 = y3 = 0.0f;
 					else
 					{
@@ -485,12 +473,12 @@
 				LDQuad* quad (LDSpawn<LDQuad> (v0, v1, v2, v3));
 				quad->setColor (MainColor);
 
-				if (type == Cylinder)
+				if (spec.type == Cylinder)
 					quad->invert();
 
 				objs << quad;
 
-				if (type == Cylinder or type == Cone)
+				if (spec.type == Cylinder or spec.type == Cone)
 					conditionalLineSegments << i;
 			}
 			break;
@@ -500,7 +488,7 @@
 			{
 				double x2, z2;
 
-				if (type == Disc)
+				if (spec.type == Disc)
 					x2 = z2 = 0.0f;
 				else
 				{
@@ -516,9 +504,9 @@
 				// they'll end up upside-down.
 				LDTriangle* seg (LDSpawn<LDTriangle>());
 				seg->setColor (MainColor);
-				seg->setVertex (type == Disc ? 0 : 2, v0);
+				seg->setVertex (spec.type == Disc ? 0 : 2, v0);
 				seg->setVertex (1, v1);
-				seg->setVertex (type == Disc ? 2 : 0, v2);
+				seg->setVertex (spec.type == Disc ? 2 : 0, v2);
 				objs << seg;
 			}
 			break;
@@ -527,26 +515,26 @@
 
 	// If this is not a full circle, we need a conditional line at the other
 	// end, too.
-	if (segs < divs and not conditionalLineSegments.isEmpty())
-		conditionalLineSegments << segs;
+	if (spec.segments < spec.divisions and not conditionalLineSegments.isEmpty())
+		conditionalLineSegments << spec.segments;
 
 	for (int i : conditionalLineSegments)
 	{
-		Vertex v0 (getRadialPoint (i, divs, cos), 0.0f, getRadialPoint (i, divs, sin));
+		Vertex v0 (getRadialPoint (i, spec.divisions, cos), 0.0f, getRadialPoint (i, spec.divisions, sin));
 		Vertex v1;
-		Vertex v2 (getRadialPoint (i + 1, divs, cos), 0.0f, getRadialPoint (i + 1, divs, sin));
-		Vertex v3 (getRadialPoint (i - 1, divs, cos), 0.0f, getRadialPoint (i - 1, divs, sin));
+		Vertex v2 (getRadialPoint (i + 1, spec.divisions, cos), 0.0f, getRadialPoint (i + 1, spec.divisions, sin));
+		Vertex v3 (getRadialPoint (i - 1, spec.divisions, cos), 0.0f, getRadialPoint (i - 1, spec.divisions, sin));
 
-		if (type == Cylinder)
+		if (spec.type == Cylinder)
 		{
 			v1 = Vertex (v0[X], 1.0f, v0[Z]);
 		}
-		else if (type == Cone)
+		else if (spec.type == Cone)
 		{
-			v1 = Vertex (v0[X] * (num + 1), 0.0f, v0[Z] * (num + 1));
-			v0.setX (v0.x() * num);
+			v1 = Vertex (v0[X] * (spec.ringNumber + 1), 0.0f, v0[Z] * (spec.ringNumber + 1));
+			v0.setX (v0.x() * spec.ringNumber);
 			v0.setY (1.0);
-			v0.setZ (v0.z() * num);
+			v0.setZ (v0.z() * spec.ringNumber);
 		}
 
 		LDCondLine* line = (LDSpawn<LDCondLine>());
@@ -576,10 +564,10 @@
 
 // =============================================================================
 //
-QString PrimitiveManager::makeRadialFileName (PrimitiveType type, int segs, int divs, int num)
+QString PrimitiveManager::makeRadialFileName(const PrimitiveSpec& spec)
 {
-	int numerator = segs;
-	int denominator = divs;
+	int numerator = spec.segments;
+	int denominator = spec.divisions;
 
 	// Simplify the fractional part, but the denominator must be at least 4.
 	simplify (numerator, denominator);
@@ -592,10 +580,11 @@
 	}
 
 	// Compose some general information: prefix, fraction, root, ring number
-	QString prefix = (divs == LowResolution) ? "" : format ("%1/", divs);
+	QString prefix = (spec.divisions == LowResolution) ? "" : format ("%1/", spec.divisions);
 	QString frac = format ("%1-%2", numerator, denominator);
-	QString root = g_radialNameRoots[type];
-	QString numstr = (type == Ring or type == Cone) ? format ("%1", num) : "";
+	static const char* roots[] = { "edge", "cyli", "disc", "ndis", "ring", "con" };
+	QString root = roots[spec.type];
+	QString numstr = (spec.type == Ring or spec.type == Cone) ? format ("%1", spec.ringNumber) : "";
 
 	// Truncate the root if necessary (7-16rin4.dat for instance).
 	// However, always keep the root at least 2 characters.
@@ -608,30 +597,30 @@
 
 // =============================================================================
 //
-LDDocument* PrimitiveManager::generatePrimitive (PrimitiveType type, int segments, int divisions, int number)
+LDDocument* PrimitiveManager::generatePrimitive(const PrimitiveSpec& spec)
 {
 	// Make the description
-	QString fraction = QString::number ((float) segments / divisions);
-	QString name = makeRadialFileName (type, segments, divisions, number);
+	QString fraction = QString::number ((float) spec.segments / spec.divisions);
+	QString name = makeRadialFileName(spec);
 	QString description;
 
 	// Ensure that there's decimals, even if they're 0.
 	if (fraction.indexOf (".") == -1)
 		fraction += ".0";
 
-	if (type == Ring or type == Cone)
+	if (spec.type == Ring or spec.type == Cone)
 	{
 		QString spacing =
-			(number < 10) ? "  " :
-			(number < 100) ? " "  : "";
+			(spec.ringNumber < 10) ? "  " :
+			(spec.ringNumber < 100) ? " "  : "";
 
-		description = format ("%1 %2%3 x %4", primitiveTypeName (type), spacing, number, fraction);
+		description = format ("%1 %2%3 x %4", primitiveTypeName (spec.type), spacing, spec.ringNumber, fraction);
 	}
 	else
-		description = format ("%1 %2", primitiveTypeName (type), fraction);
+		description = format ("%1 %2", primitiveTypeName (spec.type), fraction);
 
 	// Prepend "Hi-Res" if 48/ primitive.
-	if (divisions == HighResolution)
+	if (spec.divisions == HighResolution)
 		description.insert (0, "Hi-Res ");
 
 	LDDocument* document = m_window->newDocument();
@@ -639,6 +628,7 @@
 
 	QString author = APPNAME;
 	QString license = "";
+	bool hires = (spec.divisions == HighResolution);
 
 	if (not m_config->defaultName().isEmpty())
 	{
@@ -651,7 +641,7 @@
 	objs << LDSpawn<LDComment> (description)
 		 << LDSpawn<LDComment> (format ("Name: %1", name))
 		 << LDSpawn<LDComment> (format ("Author: %1", author))
-		 << LDSpawn<LDComment> (format ("!LDRAW_ORG Unofficial_%1Primitive", divisions == HighResolution ?  "48_" : ""))
+		 << LDSpawn<LDComment> (format ("!LDRAW_ORG Unofficial_%1Primitive", hires ?  "48_" : ""))
 		 << LDSpawn<LDComment> (license)
 		 << LDSpawn<LDEmpty>()
 		 << LDSpawn<LDBfc> (BfcStatement::CertifyCCW)
@@ -660,7 +650,7 @@
 	document->openForEditing();
 	document->history()->setIgnoring (false);
 	document->addObjects (objs);
-	document->addObjects (makePrimitiveBody (type, segments, divisions, number));
+	document->addObjects (makePrimitiveBody(spec));
 	document->addHistoryStep();
 	return document;
 }
@@ -670,44 +660,15 @@
 // Gets a primitive by the given specs. If the primitive cannot be found, it will
 // be automatically generated.
 //
-LDDocument* PrimitiveManager::getPrimitive (PrimitiveType type, int segs, int divs, int num)
+LDDocument* PrimitiveManager::getPrimitive(const PrimitiveSpec& spec)
 {
-	QString name = makeRadialFileName (type, segs, divs, num);
+	QString name = makeRadialFileName(spec);
 	LDDocument* document = m_window->documents()->getDocumentByName (name);
 
 	if (document)
 		return document;
 
-	return generatePrimitive (type, segs, divs, num);
-}
-
-// =============================================================================
-//
-PrimitivePrompt::PrimitivePrompt (QWidget* parent, Qt::WindowFlags f) :
-	QDialog (parent, f)
-{
-	ui = new Ui_MakePrimUI;
-	ui->setupUi (this);
-	connect (ui->cb_hires, SIGNAL (toggled (bool)), this, SLOT (hiResToggled (bool)));
-}
-
-// =============================================================================
-//
-PrimitivePrompt::~PrimitivePrompt()
-{
-	delete ui;
-}
-
-// =============================================================================
-//
-void PrimitivePrompt::hiResToggled (bool on)
-{
-	ui->sb_segs->setMaximum (on ? HighResolution : LowResolution);
-
-	// If the current value is 16 and we switch to hi-res, default the
-	// spinbox to 48.
-	if (on and ui->sb_segs->value() == LowResolution)
-		ui->sb_segs->setValue (HighResolution);
+	return generatePrimitive(spec);
 }
 
 // =============================================================================
--- a/src/primitives.h	Tue Feb 16 00:59:50 2016 +0200
+++ b/src/primitives.h	Tue Feb 16 01:39:06 2016 +0200
@@ -23,8 +23,9 @@
 #include "main.h"
 
 class LDDocument;
-class Ui_MakePrimUI;
+class Ui_GeneratePrimitiveDialog;
 class PrimitiveCategory;
+class PrimitiveScanner;
 
 struct Primitive
 {
@@ -33,6 +34,24 @@
 	PrimitiveCategory* category;
 };
 
+enum PrimitiveType
+{
+	Circle,
+	Cylinder,
+	Disc,
+	DiscNegative,
+	Ring,
+	Cone,
+};
+
+struct PrimitiveSpec
+{
+	PrimitiveType type;
+	int segments;
+	int divisions;
+	int ringNumber;
+};
+
 class PrimitiveCategory : public QObject
 {
 	Q_OBJECT
@@ -61,9 +80,39 @@
 	QString m_name;
 };
 
+class PrimitiveManager : public QObject, HierarchyElement
+{
+	Q_OBJECT
+
+public:
+	PrimitiveManager(QObject* parent);
+
+	PrimitiveScanner* activeScanner();
+	LDDocument* generatePrimitive(const PrimitiveSpec &spec);
+	LDDocument* getPrimitive(const PrimitiveSpec &spec);
+	QString getPrimitivesCfgPath() const;
+	void loadPrimitives();
+	void makeCircle(int segs, int divs, double radius, QList<QLineF>& lines);
+	QString makeRadialFileName(const PrimitiveSpec &spec);
+	void populateTreeWidget(QTreeWidget* tree, const QString& selectByDefault = QString());
+	QString primitiveTypeName(PrimitiveType type);
+	Q_SLOT void scanDone();
+	void startScan();
+
+private:
+	QList<PrimitiveCategory*> m_categories;
+	PrimitiveScanner* m_activeScanner;
+	QList<Primitive> m_primitives;
+	PrimitiveCategory* m_unmatched;
+
+	LDObjectList makePrimitiveBody(const PrimitiveSpec &spec);
+	void loadCategories();
+	void populateCategories();
+	void clearCategories();
+};
+
 //
-// Worker object that scans the primitives folder for primitives and
-// builds an index of them.
+// Worker object that scans the primitives folder for primitives and builds an index of them.
 //
 class PrimitiveScanner : public QObject, HierarchyElement
 {
@@ -89,62 +138,6 @@
 	int m_baselen;
 };
 
-extern QList<PrimitiveCategory*> m_categories;
-
-enum PrimitiveType
-{
-	Circle,
-	Cylinder,
-	Disc,
-	DiscNegative,
-	Ring,
-	Cone,
-};
-
-class PrimitivePrompt : public QDialog
-{
-	Q_OBJECT
-
-public:
-	explicit PrimitivePrompt (QWidget* parent = nullptr, Qt::WindowFlags f = 0);
-	virtual ~PrimitivePrompt();
-	Ui_MakePrimUI* ui;
-
-public slots:
-	void hiResToggled (bool on);
-};
-
-class PrimitiveManager : public QObject, HierarchyElement
-{
-	Q_OBJECT
-
-public:
-	PrimitiveManager(QObject* parent);
-
-	PrimitiveScanner* activeScanner();
-	LDDocument* generatePrimitive(PrimitiveType type, int segs, int divs, int num);
-	LDDocument* getPrimitive(PrimitiveType type, int segs, int divs, int num);
-	QString getPrimitivesCfgPath() const;
-	void loadPrimitives();
-	void makeCircle(int segs, int divs, double radius, QList<QLineF>& lines);
-	QString makeRadialFileName(PrimitiveType type, int segs, int divs, int num);
-	void populateTreeWidget(QTreeWidget* tree, const QString& selectByDefault = QString());
-	QString primitiveTypeName(PrimitiveType type);
-	Q_SLOT void scanDone();
-	void startScan();
-
-private:
-	QList<PrimitiveCategory*> m_categories;
-	PrimitiveScanner* m_activeScanner;
-	QList<Primitive> m_primitives;
-	PrimitiveCategory* m_unmatched;
-
-	LDObjectList makePrimitiveBody (PrimitiveType type, int segs, int divs, int num);
-	void loadCategories();
-	void populateCategories();
-	void clearCategories();
-};
-
 class PrimitiveTreeItem : public QTreeWidgetItem
 {
 public:
--- a/src/toolsets/filetoolset.cpp	Tue Feb 16 00:59:50 2016 +0200
+++ b/src/toolsets/filetoolset.cpp	Tue Feb 16 01:39:06 2016 +0200
@@ -27,6 +27,7 @@
 #include "../dialogs/configdialog.h"
 #include "../dialogs/ldrawpathdialog.h"
 #include "../dialogs/newpartdialog.h"
+#include "../dialogs/generateprimitivedialog.h"
 #include "../documentmanager.h"
 #include "filetoolset.h"
 #include "ui_makeprim.h"
@@ -200,23 +201,12 @@
 
 void FileToolset::makePrimitive()
 {
-	PrimitivePrompt* dialog = new PrimitivePrompt (m_window);
+	GeneratePrimitiveDialog* dialog = new GeneratePrimitiveDialog(m_window);
 
 	if (not dialog->exec())
 		return;
 
-	int segs = dialog->ui->sb_segs->value();
-	int divs = dialog->ui->cb_hires->isChecked() ? HighResolution : LowResolution;
-	int num = dialog->ui->sb_ringnum->value();
-
-	PrimitiveType type =
-		dialog->ui->rb_circle->isChecked()   ? Circle :
-		dialog->ui->rb_cylinder->isChecked() ? Cylinder :
-		dialog->ui->rb_disc->isChecked()     ? Disc :
-		dialog->ui->rb_ndisc->isChecked()    ? DiscNegative :
-		dialog->ui->rb_ring->isChecked()     ? Ring : Cone;
-
-	LDDocument* primitive = primitives()->generatePrimitive(type, segs, divs, num);
+	LDDocument* primitive = primitives()->generatePrimitive(dialog->spec());
 	primitive->openForEditing();
 	m_window->save(primitive, false);
 }
--- a/ui/makeprim.ui	Tue Feb 16 00:59:50 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,309 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>MakePrimUI</class>
- <widget class="QDialog" name="MakePrimUI">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>336</width>
-    <height>147</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Generate a Primitive</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
-     <item>
-      <layout class="QVBoxLayout" name="verticalLayout_6">
-       <item>
-        <widget class="QGroupBox" name="gb_type">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="title">
-          <string>Type</string>
-         </property>
-         <layout class="QGridLayout" name="gridLayout_3">
-          <item row="1" column="0">
-           <widget class="QRadioButton" name="rb_circle">
-            <property name="text">
-             <string>Circle</string>
-            </property>
-            <property name="checked">
-             <bool>true</bool>
-            </property>
-            <property name="autoRepeat">
-             <bool>false</bool>
-            </property>
-           </widget>
-          </item>
-          <item row="1" column="1">
-           <widget class="QRadioButton" name="rb_cylinder">
-            <property name="text">
-             <string>Cylinder</string>
-            </property>
-           </widget>
-          </item>
-          <item row="2" column="0">
-           <widget class="QRadioButton" name="rb_disc">
-            <property name="text">
-             <string>Disc</string>
-            </property>
-           </widget>
-          </item>
-          <item row="2" column="1">
-           <widget class="QRadioButton" name="rb_ndisc">
-            <property name="text">
-             <string>Disc Negative</string>
-            </property>
-           </widget>
-          </item>
-          <item row="3" column="0">
-           <widget class="QRadioButton" name="rb_ring">
-            <property name="text">
-             <string>Ring</string>
-            </property>
-           </widget>
-          </item>
-          <item row="3" column="1">
-           <widget class="QRadioButton" name="rb_cone">
-            <property name="text">
-             <string>Cone</string>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </widget>
-       </item>
-      </layout>
-     </item>
-     <item>
-      <layout class="QVBoxLayout" name="verticalLayout_2">
-       <item>
-        <spacer name="verticalSpacer_2">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>20</width>
-           <height>40</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-       <item>
-        <widget class="QCheckBox" name="cb_hires">
-         <property name="text">
-          <string>Hi-res</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <layout class="QGridLayout" name="gridLayout_2">
-         <item row="0" column="0">
-          <widget class="QLabel" name="label">
-           <property name="text">
-            <string>Segments:</string>
-           </property>
-          </widget>
-         </item>
-         <item row="1" column="0">
-          <widget class="QLabel" name="label_2">
-           <property name="text">
-            <string>Ring number:</string>
-           </property>
-          </widget>
-         </item>
-         <item row="0" column="1">
-          <widget class="QSpinBox" name="sb_segs">
-           <property name="minimum">
-            <number>1</number>
-           </property>
-           <property name="maximum">
-            <number>16</number>
-           </property>
-           <property name="value">
-            <number>16</number>
-           </property>
-          </widget>
-         </item>
-         <item row="1" column="1">
-          <widget class="QSpinBox" name="sb_ringnum">
-           <property name="enabled">
-            <bool>false</bool>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <spacer name="verticalSpacer">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>20</width>
-           <height>40</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-      </layout>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-     </property>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
-   <receiver>MakePrimUI</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>254</x>
-     <y>140</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>157</x>
-     <y>146</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>rejected()</signal>
-   <receiver>MakePrimUI</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>322</x>
-     <y>140</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>286</x>
-     <y>146</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>rb_circle</sender>
-   <signal>clicked(bool)</signal>
-   <receiver>sb_ringnum</receiver>
-   <slot>setDisabled(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>45</x>
-     <y>41</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>305</x>
-     <y>86</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>rb_cylinder</sender>
-   <signal>clicked(bool)</signal>
-   <receiver>sb_ringnum</receiver>
-   <slot>setDisabled(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>109</x>
-     <y>42</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>287</x>
-     <y>86</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>rb_disc</sender>
-   <signal>clicked(bool)</signal>
-   <receiver>sb_ringnum</receiver>
-   <slot>setDisabled(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>49</x>
-     <y>66</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>287</x>
-     <y>87</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>rb_ndisc</sender>
-   <signal>clicked(bool)</signal>
-   <receiver>sb_ringnum</receiver>
-   <slot>setDisabled(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>121</x>
-     <y>58</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>288</x>
-     <y>83</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>rb_ring</sender>
-   <signal>clicked(bool)</signal>
-   <receiver>sb_ringnum</receiver>
-   <slot>setEnabled(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>45</x>
-     <y>90</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>301</x>
-     <y>86</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>rb_cone</sender>
-   <signal>clicked(bool)</signal>
-   <receiver>sb_ringnum</receiver>
-   <slot>setEnabled(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>111</x>
-     <y>89</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>302</x>
-     <y>85</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
- <slots>
-  <slot>enableRingNumber()</slot>
- </slots>
-</ui>

mercurial