Thu, 21 Jun 2018 18:46:03 +0300
refactored the segments/divisions editor in MainWindow to a new widget
--- 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>