refactored the segments/divisions editor in MainWindow to a new widget

Thu, 21 Jun 2018 18:46:03 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Thu, 21 Jun 2018 18:46:03 +0300
changeset 1417
ed39bfca7a67
parent 1416
ba63c7286767
child 1418
503d4e7e27c9

refactored the segments/divisions editor in MainWindow to a new widget

CMakeLists.txt file | annotate | diff | comparison | revisions
src/basics.h file | annotate | diff | comparison | revisions
src/editmodes/circleMode.cpp file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/mainwindow.h file | annotate | diff | comparison | revisions
src/mainwindow.ui file | annotate | diff | comparison | revisions
src/widgets/circularsectioneditor.cpp file | annotate | diff | comparison | revisions
src/widgets/circularsectioneditor.h file | annotate | diff | comparison | revisions
src/widgets/circularsectioneditor.ui file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Thu Jun 21 17:02:58 2018 +0300
+++ b/CMakeLists.txt	Thu Jun 21 18:46:03 2018 +0300
@@ -95,6 +95,7 @@
 	src/toolsets/viewtoolset.cpp
 	src/types/boundingbox.cpp
 	src/types/vertex.cpp
+	src/widgets/circularsectioneditor.cpp
 	src/widgets/colorbutton.cpp
 	src/widgets/doublespinbox.cpp
 	src/widgets/headeredit.cpp
@@ -176,6 +177,7 @@
 	src/types/boundingbox.h
 	src/types/library.h
 	src/types/vertex.h
+	src/widgets/circularsectioneditor.h
 	src/widgets/colorbutton.h
 	src/widgets/doublespinbox.h
 	src/widgets/headeredit.h
@@ -206,6 +208,7 @@
 	src/toolsets/fixroundingerrors.ui
 	src/mainwindow.ui
 	src/partdownloader.ui
+	src/widgets/circularsectioneditor.ui
 	src/widgets/vertexobjecteditor.ui
 	src/widgets/headeredit.ui
 	src/widgets/matrixeditor.ui
--- a/src/basics.h	Thu Jun 21 17:02:58 2018 +0300
+++ b/src/basics.h	Thu Jun 21 18:46:03 2018 +0300
@@ -59,6 +59,12 @@
 	Clockwise,
 };
 
+struct CircularSection
+{
+	int segments = 16;
+	int divisions = 16;
+};
+
 /*
  * Special operator definition that implements the XOR operator for windings.
  * However, if either winding is NoWinding, then this function returns NoWinding.
--- a/src/editmodes/circleMode.cpp	Thu Jun 21 17:02:58 2018 +0300
+++ b/src/editmodes/circleMode.cpp	Thu Jun 21 18:46:03 2018 +0300
@@ -89,8 +89,7 @@
 void CircleMode::endDraw()
 {
 	Model model {m_documents};
-	int segments = m_window->ringToolSegments();
-	int divisions = m_window->ringToolDivisions();
+	CircularSection section = m_window->circleToolSection();
 	double dist0 = getCircleDrawDist(0);
 	double dist1 = getCircleDrawDist(1);
 	QVector3D translation = m_drawedVerts.first().toVector();
@@ -105,7 +104,7 @@
 		QMatrix4x4 transform = renderer()->currentCamera().transformationMatrix(1);
 		transform.scale(dist0);
 		transform.translate(translation);
-		model.emplace<LDCircularPrimitive>(PrimitiveModel::Circle, segments, divisions, transform);
+		model.emplace<LDCircularPrimitive>(PrimitiveModel::Circle, section.segments, section.divisions, transform);
 		finishDraw(model);
 		return;
 	}
@@ -116,7 +115,7 @@
 		QMatrix4x4 transform = renderer()->currentCamera().transformationMatrix(1);
 		transform.scale(max(dist0, dist1));
 		transform.translate(translation);
-		model.emplace<LDCircularPrimitive>(PrimitiveModel::Disc, segments, divisions, transform);
+		model.emplace<LDCircularPrimitive>(PrimitiveModel::Disc, section.segments, section.divisions, transform);
 		finishDraw(model);
 		return;
 	}
@@ -124,8 +123,9 @@
 	{
 		// The ring finder found a solution, use that. Add the component rings to the file.
 		PrimitiveModel primitiveModel;
-		primitiveModel.segments = m_window->ringToolSegments();
-		primitiveModel.divisions = m_window->ringToolDivisions();
+		CircularSection section = m_window->circleToolSection();
+		primitiveModel.segments = section.segments;
+		primitiveModel.divisions = section.divisions;
 		primitiveModel.type = PrimitiveModel::Ring;
 
 		for (const RingFinder::Component& component : g_RingFinder.bestSolution()->getComponents())
@@ -151,10 +151,10 @@
 		templ.setCoordinate(localy, y0);
 
 		// Calculate circle coords
-		QVector<QLineF> c0 = makeCircle(segments, divisions, dist0);
-		QVector<QLineF> c1 = makeCircle(segments, divisions, dist1);
+		QVector<QLineF> c0 = makeCircle(section.segments, section.divisions, dist0);
+		QVector<QLineF> c1 = makeCircle(section.segments, section.divisions, dist1);
 
-		for (int i = 0; i < segments; ++i)
+		for (int i = 0; i < section.segments; ++i)
 		{
 			Vertex v0, v1, v2, v3;
 			v0 = v1 = v2 = v3 = templ;
@@ -191,7 +191,7 @@
 {
 	if (not m_drawedVerts.isEmpty())
 	{
-		int divisions = m_window->ringToolDivisions();
+		int divisions = m_window->circleToolSection().divisions;
 		QPointF originSpot = renderer()->currentCamera().convert3dTo2d(m_drawedVerts.first());
 		// Line from the origin of the circle to current mouse position
 		QLineF hand1 = {originSpot, renderer()->mousePositionF()};
@@ -227,15 +227,14 @@
 	QVector<QPointF> innerverts2d, outerverts2d;
 	double innerdistance = getCircleDrawDist(0);
 	double outerdistance = countof(m_drawedVerts) >= 2 ? getCircleDrawDist (1) : -1;
-	int divisions = m_window->ringToolDivisions();
-	int segments = m_window->ringToolSegments();
-	double angleUnit = 2 * pi / divisions;
+	CircularSection section = m_window->circleToolSection();
+	double angleUnit = 2 * pi / section.divisions;
 	Axis relX, relY;
 	renderer()->getRelativeAxes(relX, relY);
 	double angleoffset = (countof(m_drawedVerts) < 3 ? orientation() : m_angleOffset);
 
 	// Calculate the preview positions of vertices
-	for (int i = 0; i < segments + 1; ++i)
+	for (int i = 0; i < section.segments + 1; ++i)
 	{
 		const double sinangle = ldrawsin(angleoffset + i * angleUnit);
 		const double cosangle = ldrawcos(angleoffset + i * angleUnit);
@@ -260,10 +259,10 @@
 	{
 		painter.setBrush(m_polybrush);
 		painter.setPen(Qt::NoPen);
-		lines.reserve(segments * 2);
+		lines.reserve(section.segments * 2);
 
 		// Compile polygons
-		for (int i = 0; i < segments; ++i)
+		for (int i = 0; i < section.segments; ++i)
 		{
 			QVector<QPointF> points;
 			points << innerverts2d[i]
@@ -276,7 +275,7 @@
 		}
 
 		// Add bordering edges for unclosed rings/discs
-		if (segments != divisions)
+		if (section.segments != section.divisions)
 		{
 			lines.append({innerverts2d.first(), outerverts2d.first()});
 			lines.append({innerverts2d.last(), outerverts2d.last()});
@@ -284,9 +283,9 @@
 	}
 	else
 	{
-		lines.reserve(segments);
+		lines.reserve(section.segments);
 
-		for (int i = 0; i < segments; ++i)
+		for (int i = 0; i < section.segments; ++i)
 			lines.append({innerverts2d[i], innerverts2d[i + 1]});
 	}
 
--- a/src/mainwindow.cpp	Thu Jun 21 17:02:58 2018 +0300
+++ b/src/mainwindow.cpp	Thu Jun 21 18:46:03 2018 +0300
@@ -111,9 +111,7 @@
 	updateTitle();
 	loadShortcuts();
 	setMinimumSize (300, 200);
-	connect(ui.ringToolDivisions, SIGNAL(currentTextChanged(QString)), this, SLOT(ringToolDivisionsChanged()));
-	connect(ui.ringToolSegments, SIGNAL(valueChanged(int)), this, SLOT(circleToolSegmentsChanged()));
-	circleToolSegmentsChanged(); // invoke it manually for initial label text
+	connect(ui.circleToolSection, &CircularSectionEditor::sectionChanged, [&](){this->renderer()->update();});
 
 	// Examine the toolsets and make a dictionary of tools
 	m_toolsets = Toolset::createToolsets (this);
@@ -796,41 +794,9 @@
 	return m_defaultShortcuts[act];
 }
 
-int MainWindow::ringToolDivisions() const
-{
-	return ui.ringToolDivisions->currentText().toInt();
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-//
-int MainWindow::ringToolSegments() const
-{
-	return ui.ringToolSegments->value();
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-//
-void MainWindow::ringToolDivisionsChanged()
+CircularSection MainWindow::circleToolSection() const
 {
-	// Scale the segments value to fit.
-	int divisions = this->ringToolDivisions();
-	int newSegments = static_cast<int>(round(
-		this->ringToolSegments() * double(divisions) / this->previousDivisions
-	));
-	this->ui.ringToolSegments->setMaximum(divisions);
-	this->ui.ringToolSegments->setValue(newSegments);
-	this->previousDivisions = divisions;
-	this->renderer()->update();
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-//
-void MainWindow::circleToolSegmentsChanged()
-{
-	int numerator = this->ringToolSegments();
-	int denominator = this->ringToolDivisions();
-	simplify (numerator, denominator);
-	ui.ringToolSegmentsLabel->setText(fractionRep(numerator, denominator));
+	return ui.circleToolSection->section();
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
--- a/src/mainwindow.h	Thu Jun 21 17:02:58 2018 +0300
+++ b/src/mainwindow.h	Thu Jun 21 18:46:03 2018 +0300
@@ -83,8 +83,7 @@
 	Canvas* renderer();
 	void refresh();
 	void replaceSelection(const QItemSelection& selection);
-	int ringToolDivisions() const;
-	int ringToolSegments() const;
+	CircularSection circleToolSection() const;
 	bool save (LDDocument* doc, bool saveAs);
 	void saveShortcuts();
 	void select(const QModelIndex& objectIndex);
@@ -108,10 +107,8 @@
 
 public slots:
 	void actionTriggered();
-	void circleToolSegmentsChanged();
 	void closeTab (int tabindex);
 	void historyTraversed();
-	void ringToolDivisionsChanged();
 	void tabSelected();
 	void documentClosed(LDDocument* document);
 	void updateTitle();
--- a/src/mainwindow.ui	Thu Jun 21 17:02:58 2018 +0300
+++ b/src/mainwindow.ui	Thu Jun 21 18:46:03 2018 +0300
@@ -40,15 +40,15 @@
       </widget>
       <widget class="QToolBox" name="toolBox">
        <property name="currentIndex">
-        <number>1</number>
+        <number>2</number>
        </property>
        <widget class="QWidget" name="page">
         <property name="geometry">
          <rect>
           <x>0</x>
           <y>0</y>
-          <width>926</width>
-          <height>336</height>
+          <width>100</width>
+          <height>30</height>
          </rect>
         </property>
         <attribute name="label">
@@ -71,7 +71,7 @@
           <x>0</x>
           <y>0</y>
           <width>926</width>
-          <height>336</height>
+          <height>366</height>
          </rect>
         </property>
         <attribute name="label">
@@ -102,7 +102,7 @@
           <x>0</x>
           <y>0</y>
           <width>926</width>
-          <height>336</height>
+          <height>366</height>
          </rect>
         </property>
         <attribute name="label">
@@ -114,78 +114,13 @@
            <property name="title">
             <string>Circle Tool Options</string>
            </property>
-           <layout class="QVBoxLayout" name="verticalLayout_5">
-            <item>
-             <layout class="QFormLayout" name="formLayout">
-              <item row="0" column="0">
-               <widget class="QLabel" name="label_2">
-                <property name="text">
-                 <string>Divisions:</string>
-                </property>
-               </widget>
-              </item>
-              <item row="1" column="0">
-               <widget class="QLabel" name="label">
-                <property name="text">
-                 <string>Segments:</string>
-                </property>
-               </widget>
-              </item>
-              <item row="1" column="1">
-               <layout class="QHBoxLayout" name="horizontalLayout_2">
-                <item>
-                 <widget class="QSpinBox" name="ringToolSegments">
-                  <property name="enabled">
-                   <bool>true</bool>
-                  </property>
-                  <property name="minimum">
-                   <number>1</number>
-                  </property>
-                  <property name="maximum">
-                   <number>16</number>
-                  </property>
-                  <property name="value">
-                   <number>16</number>
-                  </property>
-                 </widget>
-                </item>
-                <item>
-                 <widget class="QLabel" name="ringToolSegmentsLabel">
-                  <property name="text">
-                   <string>a / b</string>
-                  </property>
-                 </widget>
-                </item>
-               </layout>
-              </item>
-              <item row="0" column="1">
-               <widget class="QComboBox" name="ringToolDivisions">
-                <property name="currentIndex">
-                 <number>1</number>
-                </property>
-                <item>
-                 <property name="text">
-                  <string>8</string>
-                 </property>
-                </item>
-                <item>
-                 <property name="text">
-                  <string>16</string>
-                 </property>
-                </item>
-                <item>
-                 <property name="text">
-                  <string>48</string>
-                 </property>
-                </item>
-               </widget>
-              </item>
-             </layout>
-            </item>
-           </layout>
+           <layout class="QVBoxLayout" name="verticalLayout_5"/>
           </widget>
          </item>
          <item>
+          <widget class="CircularSectionEditor" name="circleToolSection" native="true"/>
+         </item>
+         <item>
           <spacer name="verticalSpacer">
            <property name="orientation">
             <enum>Qt::Vertical</enum>
@@ -205,8 +140,8 @@
          <rect>
           <x>0</x>
           <y>0</y>
-          <width>926</width>
-          <height>336</height>
+          <width>93</width>
+          <height>93</height>
          </rect>
         </property>
         <attribute name="label">
@@ -239,7 +174,7 @@
      <x>0</x>
      <y>0</y>
      <width>1010</width>
-     <height>31</height>
+     <height>26</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">
@@ -1789,10 +1724,15 @@
    <header>widgets/headeredit.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>CircularSectionEditor</class>
+   <extends>QWidget</extends>
+   <header>widgets/circularsectioneditor.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <resources>
   <include location="../ldforge.qrc"/>
-  <include location="../ldforge.qrc"/>
  </resources>
  <connections/>
 </ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/widgets/circularsectioneditor.cpp	Thu Jun 21 18:46:03 2018 +0300
@@ -0,0 +1,68 @@
+#include "circularsectioneditor.h"
+#include "ui_circularsectioneditor.h"
+#include "../primitives.h"
+
+CircularSectionEditor::CircularSectionEditor(QWidget* parent) :
+    QWidget {parent},
+    ui {*new Ui_CircularSectionEditor}
+{
+	ui.setupUi(this);
+	ui.divisions->setValidator(new QIntValidator {1, INT_MAX});
+	connect(ui.segments, qOverload<int>(&QSpinBox::valueChanged), this, &CircularSectionEditor::segmentsChanged);
+	connect(ui.divisions, qOverload<const QString&>(&QComboBox::activated), this, &CircularSectionEditor::divisionsChanged);
+	previousDivisions = ui.divisions->currentText().toInt();
+	updateFractionLabel();
+}
+
+CircularSectionEditor::~CircularSectionEditor()
+{
+	delete &ui;
+}
+
+CircularSection CircularSectionEditor::section()
+{
+	return {ui.segments->value(), ui.divisions->currentText().toInt()};
+}
+
+void CircularSectionEditor::setSection(const CircularSection& newSection)
+{
+	ui.divisions->setCurrentText(QString::number(newSection.divisions));
+	ui.segments->setValue(newSection.segments);
+}
+
+void CircularSectionEditor::updateFractionLabel()
+{
+	CircularSection section = this->section();
+	int numerator = section.segments;
+	int denominator = section.divisions;
+	simplify(numerator, denominator);
+	ui.fraction->setText(fractionRep(numerator, denominator));
+}
+
+void CircularSectionEditor::divisionsChanged()
+{
+	// Scale the segments value to fit.
+	int divisions = ui.divisions->currentText().toInt();
+
+	if (divisions <= 0)
+	{
+		ui.divisions->setCurrentText(QString::number(1));
+	}
+	else
+	{
+		int newSegments = static_cast<int>(round(
+			ui.segments->value() * double(divisions) / this->previousDivisions
+		));
+		ui.segments->setMaximum(divisions);
+		ui.segments->setValue(newSegments);
+		previousDivisions = divisions;
+	}
+
+	emit sectionChanged(section());
+}
+
+void CircularSectionEditor::segmentsChanged()
+{
+	updateFractionLabel();
+	emit sectionChanged(section());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/widgets/circularsectioneditor.h	Thu Jun 21 18:46:03 2018 +0300
@@ -0,0 +1,26 @@
+#pragma once
+#include <QWidget>
+#include "../basics.h"
+
+class CircularSectionEditor : public QWidget
+{
+	Q_OBJECT
+
+public:
+	explicit CircularSectionEditor(QWidget *parent = 0);
+	~CircularSectionEditor();
+
+	CircularSection section();
+	void setSection(const CircularSection& newSection);
+
+signals:
+	void sectionChanged(CircularSection);
+
+private:
+	class Ui_CircularSectionEditor& ui;
+	int previousDivisions;
+
+	Q_SLOT void updateFractionLabel();
+	Q_SLOT void segmentsChanged();
+	Q_SLOT void divisionsChanged();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/widgets/circularsectioneditor.ui	Thu Jun 21 18:46:03 2018 +0300
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CircularSectionEditor</class>
+ <widget class="QWidget" name="CircularSectionEditor">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>207</width>
+    <height>86</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QFormLayout" name="formLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Segments:</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="0">
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string>Divisions:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QComboBox" name="divisions">
+       <property name="editable">
+        <bool>true</bool>
+       </property>
+       <property name="currentIndex">
+        <number>1</number>
+       </property>
+       <item>
+        <property name="text">
+         <string>8</string>
+        </property>
+       </item>
+       <item>
+        <property name="text">
+         <string>16</string>
+        </property>
+       </item>
+       <item>
+        <property name="text">
+         <string>48</string>
+        </property>
+       </item>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="fraction">
+       <property name="text">
+        <string>1 / 1</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

mercurial