Begin work on Bézier curve support. They can be drawn but don't render in 3D and they load as comments.

Sun, 04 Oct 2015 04:26:11 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sun, 04 Oct 2015 04:26:11 +0300
changeset 1000
c064cc048f14
parent 999
213a7c7a3ce4
child 1001
024cbc902e75

Begin work on Bézier curve support. They can be drawn but don't render in 3D and they load as comments.

CMakeLists.txt file | annotate | diff | comparison | revisions
ldforge.qrc file | annotate | diff | comparison | revisions
src/editmodes/abstractEditMode.cpp file | annotate | diff | comparison | revisions
src/editmodes/abstractEditMode.h file | annotate | diff | comparison | revisions
src/editmodes/curvemode.cpp file | annotate | diff | comparison | revisions
src/editmodes/curvemode.h file | annotate | diff | comparison | revisions
src/editmodes/drawMode.cpp file | annotate | diff | comparison | revisions
src/editmodes/drawMode.h file | annotate | diff | comparison | revisions
src/editmodes/linePathMode.h file | annotate | diff | comparison | revisions
src/glRenderer.cpp file | annotate | diff | comparison | revisions
src/glRenderer.h file | annotate | diff | comparison | revisions
src/ldObject.cpp file | annotate | diff | comparison | revisions
src/ldObject.h file | annotate | diff | comparison | revisions
src/ldpaths.cpp file | annotate | diff | comparison | revisions
src/mainwindow.ui file | annotate | diff | comparison | revisions
src/toolsets/basictoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/basictoolset.h file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Sun Oct 04 02:59:38 2015 +0300
+++ b/CMakeLists.txt	Sun Oct 04 04:26:11 2015 +0300
@@ -66,6 +66,7 @@
 	src/dialogs/openprogressdialog.cpp
 	src/editmodes/abstractEditMode.cpp
 	src/editmodes/circleMode.cpp
+	src/editmodes/curvemode.cpp
 	src/editmodes/drawMode.cpp
     src/editmodes/linePathMode.cpp
 	src/editmodes/magicWandMode.cpp
@@ -117,6 +118,7 @@
 	src/dialogs/openprogressdialog.h
 	src/editmodes/abstractEditMode.h
 	src/editmodes/circleMode.h
+	src/editmodes/curvemode.h
 	src/editmodes/drawMode.h
 	src/editmodes/linePathMode.h
 	src/editmodes/magicWandMode.h
--- a/ldforge.qrc	Sun Oct 04 02:59:38 2015 +0300
+++ b/ldforge.qrc	Sun Oct 04 04:26:11 2015 +0300
@@ -1,6 +1,7 @@
 <!DOCTYPE RCC>
 <RCC version="1.0">
 <qresource>
+	<file>./icons/add-beziercurve.png</file>
 	<file>./icons/add-bfc.png</file>
 	<file>./icons/add-comment.png</file>
 	<file>./icons/add-condline.png</file>
@@ -15,6 +16,7 @@
 	<file>./icons/arrow-up.png</file>
 	<file>./icons/autocolor.png</file>
 	<file>./icons/axes.png</file>
+	<file>./icons/beziercurve.png</file>
 	<file>./icons/bfc.png</file>
 	<file>./icons/bfc-view.png</file>
 	<file>./icons/brick-new.png</file>
--- a/src/editmodes/abstractEditMode.cpp	Sun Oct 04 02:59:38 2015 +0300
+++ b/src/editmodes/abstractEditMode.cpp	Sun Oct 04 04:26:11 2015 +0300
@@ -25,8 +25,10 @@
 #include "circleMode.h"
 #include "magicWandMode.h"
 #include "linePathMode.h"
+#include "curvemode.h"
 #include "../mainwindow.h"
 #include "../glRenderer.h"
+#include "../miscallenous.h"
 
 ConfigOption (bool DrawLineLengths = true)
 ConfigOption (bool DrawAngles = false)
@@ -48,6 +50,7 @@
 	case EditModeType::Circle: return new CircleMode (renderer);
 	case EditModeType::MagicWand: return new MagicWandMode (renderer);
 	case EditModeType::LinePath: return new LinePathMode (renderer);
+	case EditModeType::Curve: return new CurveMode (renderer);
 	}
 
 	throw std::logic_error ("bad type given to AbstractEditMode::createByType");
@@ -112,8 +115,7 @@
 
 		for (const Vertex& vrt : vertices)
 		{
-			// If the vertex in 2d space is very close to the cursor then we use
-			// it regardless of depth.
+			// If the vertex in 2d space is very close to the cursor then we use it regardless of depth.
 			QPoint vect2d = renderer()->convert3dTo2d (vrt) - cursorPosition2D;
 			const double distance2DSquared = std::pow (vect2d.x(), 2) + std::pow (vect2d.y(), 2);
 			if (distance2DSquared < 16.0 * 16.0)
@@ -147,7 +149,18 @@
 	{
 		// Remove the last vertex
 		m_drawedVerts.removeLast();
+		return true;
+	}
 
+	if (data.releasedButtons & Qt::LeftButton)
+	{
+		if (m_drawedVerts.size() >= maxVertices())
+		{
+			endDraw();
+			return true;
+		}
+
+		addDrawnVertex (getCursorVertex());
 		return true;
 	}
 
@@ -256,3 +269,36 @@
 
 	return false;
 }
+
+template<typename T>
+T intervalClamp (T a, T interval)
+{
+	T remainder = a % interval;
+
+	if (remainder >= float (interval / 2))
+		a += interval;
+
+	a -= remainder;
+	return a;
+}
+
+Vertex AbstractDrawMode::getCursorVertex() const
+{
+	Vertex result = renderer()->position3D();
+
+	if (renderer()->keyboardModifiers() & Qt::ControlModifier
+		and not m_drawedVerts.isEmpty())
+	{
+		Vertex const& v0 = m_drawedVerts.last();
+		Vertex const& v1 = result;
+		Axis relX, relY;
+
+		renderer()->getRelativeAxes (relX, relY);
+		QLineF ln (v0[relX], v0[relY], v1[relX], v1[relY]);
+		ln.setAngle (intervalClamp<int> (ln.angle(), 45));
+		result.setCoordinate (relX, Grid::Snap (ln.x2(), Grid::Coordinate));
+		result.setCoordinate (relY, Grid::Snap (ln.y2(), Grid::Coordinate));
+	}
+
+	return result;
+}
\ No newline at end of file
--- a/src/editmodes/abstractEditMode.h	Sun Oct 04 02:59:38 2015 +0300
+++ b/src/editmodes/abstractEditMode.h	Sun Oct 04 04:26:11 2015 +0300
@@ -32,6 +32,7 @@
 	Circle,
 	MagicWand,
 	LinePath,
+	Curve,
 };
 
 class AbstractEditMode : public QObject, public HierarchyElement
@@ -80,24 +81,19 @@
 public:
 	AbstractDrawMode (GLRenderer* renderer);
 
-	virtual bool allowFreeCamera() const override
-	{
-		return false;
-	}
-
-	bool mouseReleased (const AbstractEditMode::MouseEventData& data) override;
 	void addDrawnVertex (const Vertex& pos);
+	virtual bool allowFreeCamera() const override final { return false; }
+	virtual void endDraw() {}
+	void drawLength (QPainter& painter,
+		const Vertex& v0, const Vertex& v1,
+		const QPointF& v0p, const QPointF& v1p) const;
 	void finishDraw (const LDObjectList& objs);
-	void renderPolygon (QPainter& painter, const QVector<Vertex>& poly3d,
-		bool withlengths, bool withangles) const;
-	void drawLength (QPainter& painter, Vertex const& v0, Vertex const& v1,
-		const QPointF& v0p, const QPointF& v1p) const;
+	Vertex getCursorVertex() const;
 	bool keyReleased (QKeyEvent* ev) override;
-
-	virtual bool preAddVertex (Vertex const&)
-	{
-		return false;
-	}
+	virtual int maxVertices() const { return 0; }
+	bool mouseReleased (const AbstractEditMode::MouseEventData& data) override;
+	virtual bool preAddVertex (Vertex const&) { return false; }
+	void renderPolygon (QPainter& painter, const QVector<Vertex>& poly3d, bool withlengths, bool withangles) const;
 };
 
 //
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/editmodes/curvemode.cpp	Sun Oct 04 04:26:11 2015 +0300
@@ -0,0 +1,86 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2015 Teemu Piippo
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "curvemode.h"
+#include "../ldObject.h"
+#include "../glRenderer.h"
+
+CurveMode::CurveMode (GLRenderer* renderer) :
+	Super (renderer) {}
+
+void CurveMode::render (QPainter& painter) const
+{
+	if (m_drawedVerts.size() >= 1)
+	{
+		Vertex curve[4];
+		QPoint curve2d[4];
+
+		for (int i = 0; i < qMin (countof(curve), m_drawedVerts.size()); ++i)
+			curve[i] = m_drawedVerts[i];
+
+		// Factor the cursor into the preview
+		if (m_drawedVerts.size() < 4)
+			curve[m_drawedVerts.size()] = getCursorVertex();
+
+		// Default the control points to their vertex positions
+		if (m_drawedVerts.size() < 2)
+			curve[2] = curve[0];
+
+		if (m_drawedVerts.size() < 3)
+			curve[3] = curve[1];
+
+		for (int i = 0; i < countof(curve); ++i)
+			curve2d[i] = renderer()->convert3dTo2d (curve[i]);
+
+		painter.setPen (renderer()->linePen());
+
+		for (int i = 0; i < qMin (countof(curve), m_drawedVerts.size() + 1); ++i)
+		{
+			if (i < 2)
+				renderer()->drawBlip (painter, curve2d[i]);
+			else
+				// Give control points a different color
+				renderer()->drawBlip (painter, curve2d[i], QColor (0, 96, 96));
+		}
+
+		QPainterPath path (curve2d[0]);
+		path.cubicTo (curve2d[2], curve2d[3], curve2d[1]);
+		painter.strokePath (path, renderer()->linePen());
+	}
+	else
+	{
+		// Even if we have nothing, still draw the vertex at the cursor
+		painter.setPen (renderer()->linePen());
+		renderer()->drawBlip (painter, renderer()->convert3dTo2d (getCursorVertex()));
+	}
+}
+
+EditModeType CurveMode::type() const
+{
+	return EditModeType::Curve;
+}
+
+void CurveMode::endDraw()
+{
+	if (m_drawedVerts.size() == 4)
+	{
+		LDObjectList objs;
+		objs << new LDBezierCurve (m_drawedVerts[0], m_drawedVerts[1], m_drawedVerts[2], m_drawedVerts[3]);
+		finishDraw (objs);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/editmodes/curvemode.h	Sun Oct 04 04:26:11 2015 +0300
@@ -0,0 +1,32 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2015 Teemu Piippo
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#include "abstractEditMode.h"
+
+class CurveMode : public AbstractDrawMode
+{
+	DEFINE_CLASS (CurveMode, AbstractDrawMode)
+
+public:
+	CurveMode (GLRenderer* renderer);
+	void endDraw() override;
+	void render (QPainter& painter) const override;
+	EditModeType type() const override;
+	int maxVertices() const override { return 4; }
+};
--- a/src/editmodes/drawMode.cpp	Sun Oct 04 02:59:38 2015 +0300
+++ b/src/editmodes/drawMode.cpp	Sun Oct 04 04:26:11 2015 +0300
@@ -21,7 +21,6 @@
 #include "drawMode.h"
 #include "../ldObject.h"
 #include "../glRenderer.h"
-#include "../miscallenous.h"
 
 DrawMode::DrawMode (GLRenderer* renderer) :
 	Super (renderer) {}
@@ -34,7 +33,6 @@
 void DrawMode::render (QPainter& painter) const
 {
 	QVector<Vertex> poly;
-	QFontMetrics metrics = QFontMetrics (QFont());
 
 	for (Vertex const& vert : m_drawedVerts)
 		poly << vert;
@@ -63,27 +61,6 @@
 	return false;
 }
 
-bool DrawMode::mouseReleased (MouseEventData const& data)
-{
-	if (Super::mouseReleased (data))
-		return true;
-
-	if (data.releasedButtons & Qt::LeftButton)
-	{
-		// If we have 4 verts, stop drawing.
-		if (m_drawedVerts.size() >= 4)
-		{
-			endDraw();
-			return true;
-		}
-
-		addDrawnVertex (getCursorVertex());
-		return true;
-	}
-
-	return false;
-}
-
 void DrawMode::endDraw()
 {
 	// Clean the selection and create the object
@@ -120,36 +97,3 @@
 
 	finishDraw (objs);
 }
-
-template<typename T>
-T IntervalClamp (T a, T interval)
-{
-	T remainder = a % interval;
-
-	if (remainder >= float (interval / 2))
-		a += interval;
-
-	a -= remainder;
-	return a;
-}
-
-Vertex DrawMode::getCursorVertex() const
-{
-	Vertex result = renderer()->position3D();
-
-	if (renderer()->keyboardModifiers() & Qt::ControlModifier
-		and not m_drawedVerts.isEmpty())
-	{
-		Vertex const& v0 = m_drawedVerts.last();
-		Vertex const& v1 = result;
-		Axis relX, relY;
-
-		renderer()->getRelativeAxes (relX, relY);
-		QLineF ln (v0[relX], v0[relY], v1[relX], v1[relY]);
-		ln.setAngle (IntervalClamp<int> (ln.angle(), 45));
-		result.setCoordinate (relX, Grid::Snap (ln.x2(), Grid::Coordinate));
-		result.setCoordinate (relY, Grid::Snap (ln.y2(), Grid::Coordinate));
-	}
-
-	return result;
-}
--- a/src/editmodes/drawMode.h	Sun Oct 04 02:59:38 2015 +0300
+++ b/src/editmodes/drawMode.h	Sun Oct 04 04:26:11 2015 +0300
@@ -28,9 +28,8 @@
 	DrawMode (GLRenderer* renderer);
 
 	void render (QPainter& painter) const override;
+	int maxVertices() const override { return 4; }
 	EditModeType type() const override;
-	bool mouseReleased (MouseEventData const& data) override;
-	void endDraw();
+	void endDraw() override;
 	bool preAddVertex (Vertex const&) override;
-	Vertex getCursorVertex() const;
 };
--- a/src/editmodes/linePathMode.h	Sun Oct 04 02:59:38 2015 +0300
+++ b/src/editmodes/linePathMode.h	Sun Oct 04 04:26:11 2015 +0300
@@ -13,6 +13,6 @@
 	bool mouseReleased (MouseEventData const& data) override;
 	bool preAddVertex (Vertex const& pos) override;
 	bool keyReleased (QKeyEvent*) override;
-	void endDraw();
+	void endDraw() override;
 };
 
--- a/src/glRenderer.cpp	Sun Oct 04 02:59:38 2015 +0300
+++ b/src/glRenderer.cpp	Sun Oct 04 04:26:11 2015 +0300
@@ -721,13 +721,13 @@
 
 // =============================================================================
 //
-void GLRenderer::drawBlip (QPainter& paint, QPointF pos) const
+void GLRenderer::drawBlip (QPainter& paint, QPointF pos, QColor color) const
 {
 	QPen pen = m_thinBorderPen;
 	const int blipsize = 8;
 	pen.setWidth (1);
 	paint.setPen (pen);
-	paint.setBrush (QColor (64, 192, 0));
+	paint.setBrush (color);
 	paint.drawEllipse (pos.x() - blipsize / 2, pos.y() - blipsize / 2, blipsize, blipsize);
 }
 
--- a/src/glRenderer.h	Sun Oct 04 02:59:38 2015 +0300
+++ b/src/glRenderer.h	Sun Oct 04 04:26:11 2015 +0300
@@ -151,7 +151,7 @@
 	EditModeType currentEditModeType() const;
 	int depthNegateFactor() const;
 	LDDocument* document() const;
-	void drawBlip (QPainter& paint, QPointF pos) const;
+	void drawBlip (QPainter& paint, QPointF pos, QColor color = QColor (64, 192, 0)) const;
 	void drawGLScene();
 	void forgetObject (LDObject* obj);
 	Axis getCameraAxis (bool y, ECamera camid = (ECamera) -1);
--- a/src/ldObject.cpp	Sun Oct 04 02:59:38 2015 +0300
+++ b/src/ldObject.cpp	Sun Oct 04 04:26:11 2015 +0300
@@ -79,6 +79,7 @@
 LDOBJ_DEFAULT_CTOR (LDOverlay, LDObject)
 LDOBJ_DEFAULT_CTOR (LDBfc, LDObject)
 LDOBJ_DEFAULT_CTOR (LDComment, LDObject)
+LDOBJ_DEFAULT_CTOR (LDBezierCurve, LDObject)
 
 LDObject::~LDObject()
 {
@@ -145,7 +146,7 @@
 QString LDCondLine::asText() const
 {
 	QString val = format ("5 %1", color());
-
+	
 	// Add the coordinates
 	for (int i = 0; i < 4; ++i)
 		val += format (" %1", vertex (i));
@@ -153,6 +154,17 @@
 	return val;
 }
 
+QString LDBezierCurve::asText() const
+{
+	QString result = format ("0 !LDFORGE BEZIER_CURVE %1", color());
+	
+	// Add the coordinates
+	for (int i = 0; i < 4; ++i)
+		result += format (" %1", vertex (i));
+
+	return result;
+}
+
 // =============================================================================
 //
 QString LDError::asText() const
@@ -265,6 +277,18 @@
 
 // =============================================================================
 //
+LDBezierCurve::LDBezierCurve(const Vertex& v0, const Vertex& v1, const Vertex& v2, const Vertex& v3,
+	LDDocument* document) :
+	LDObject (document)
+{
+	setVertex (0, v0);
+	setVertex (1, v1);
+	setVertex (2, v2);
+	setVertex (3, v3);
+}
+
+// =============================================================================
+//
 // Deletes this object
 //
 void LDObject::destroy()
@@ -600,17 +624,18 @@
 {
 	switch (type)
 	{
-		case OBJ_Comment:		return LDSpawn<LDComment>();
-		case OBJ_Bfc:			return LDSpawn<LDBfc>();
-		case OBJ_Line:			return LDSpawn<LDLine>();
-		case OBJ_CondLine:		return LDSpawn<LDCondLine>();
-		case OBJ_Subfile:		return LDSpawn<LDSubfile>();
-		case OBJ_Triangle:		return LDSpawn<LDTriangle>();
-		case OBJ_Quad:			return LDSpawn<LDQuad>();
-		case OBJ_Empty:			return LDSpawn<LDEmpty>();
-		case OBJ_Error:			return LDSpawn<LDError>();
-		case OBJ_Overlay:		return LDSpawn<LDOverlay>();
-		case OBJ_NumTypes:		break;
+	case OBJ_Comment:		return LDSpawn<LDComment>();
+	case OBJ_Bfc:			return LDSpawn<LDBfc>();
+	case OBJ_Line:			return LDSpawn<LDLine>();
+	case OBJ_CondLine:		return LDSpawn<LDCondLine>();
+	case OBJ_Subfile:		return LDSpawn<LDSubfile>();
+	case OBJ_Triangle:		return LDSpawn<LDTriangle>();
+	case OBJ_Quad:			return LDSpawn<LDQuad>();
+	case OBJ_Empty:			return LDSpawn<LDEmpty>();
+	case OBJ_Error:			return LDSpawn<LDError>();
+	case OBJ_Overlay:		return LDSpawn<LDOverlay>();
+	case OBJ_BezierCurve:	return LDSpawn<LDBezierCurve>();
+	case OBJ_NumTypes:		break;
 	}
 	return nullptr;
 }
@@ -739,6 +764,19 @@
 
 // =============================================================================
 //
+void LDBezierCurve::invert()
+{
+	// A Bézier curve's control points probably need to be, though.
+	Vertex tmp = vertex (1);
+	setVertex (1, vertex (0));
+	setVertex (0, tmp);
+	tmp = vertex (3);
+	setVertex (3, vertex (2));
+	setVertex (2, tmp);
+}
+
+// =============================================================================
+//
 LDLine* LDCondLine::toEdgeLine()
 {
 	LDLine* replacement = new LDLine;
--- a/src/ldObject.h	Sun Oct 04 02:59:38 2015 +0300
+++ b/src/ldObject.h	Sun Oct 04 04:26:11 2015 +0300
@@ -72,6 +72,7 @@
 	OBJ_Comment,		//	Object represents a	comment
 	OBJ_Error,			//	Object is the result of failed parsing
 	OBJ_Empty,			//	Object represents an empty line
+	OBJ_BezierCurve,	//	Object represents a Bézier curve
 
 	OBJ_NumTypes,       // Amount of object types
 	OBJ_FirstType = OBJ_Subfile
@@ -447,6 +448,22 @@
 	QString m_fileName;
 };
 
+class LDBezierCurve : public LDObject
+{
+	LDOBJ (BezierCurve)
+	LDOBJ_NAME (beziercurve)
+	LDOBJ_VERTICES (4)
+	LDOBJ_COLORED
+	LDOBJ_DEFAULTCOLOR (EdgeColor)
+	LDOBJ_SCEMANTIC
+	LDOBJ_NO_MATRIX
+
+public:
+	LDBezierCurve (const Vertex& v0, const Vertex& v1,
+		const Vertex& v2, const Vertex& v3, LDDocument* document = nullptr);
+	LDLine* toEdgeLine();
+};
+
 // Other common LDraw stuff
 static const QString CALicenseText ("!LICENSE Redistributable under CCAL version 2.0 : "
 	"see CAreadme.txt");
--- a/src/ldpaths.cpp	Sun Oct 04 02:59:38 2015 +0300
+++ b/src/ldpaths.cpp	Sun Oct 04 04:26:11 2015 +0300
@@ -26,7 +26,6 @@
 	}
 }
 
-#include <QDebug>
 bool LDPaths::isValid (const QDir& dir) const
 {
 	if (dir.exists())
--- a/src/mainwindow.ui	Sun Oct 04 02:59:38 2015 +0300
+++ b/src/mainwindow.ui	Sun Oct 04 04:26:11 2015 +0300
@@ -48,7 +48,7 @@
            <x>0</x>
            <y>0</y>
            <width>234</width>
-           <height>402</height>
+           <height>407</height>
           </rect>
          </property>
          <attribute name="label">
@@ -75,8 +75,8 @@
           <rect>
            <x>0</x>
            <y>0</y>
-           <width>234</width>
-           <height>402</height>
+           <width>264</width>
+           <height>121</height>
           </rect>
          </property>
          <attribute name="label">
@@ -157,8 +157,8 @@
           <rect>
            <x>0</x>
            <y>0</y>
-           <width>234</width>
-           <height>402</height>
+           <width>96</width>
+           <height>86</height>
           </rect>
          </property>
          <attribute name="label">
@@ -194,7 +194,7 @@
      <x>0</x>
      <y>0</y>
      <width>1010</width>
-     <height>30</height>
+     <height>29</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">
@@ -536,6 +536,7 @@
    <addaction name="actionModeRectangle"/>
    <addaction name="actionModeCircle"/>
    <addaction name="actionModeLinePath"/>
+   <addaction name="actionModeCurve"/>
   </widget>
   <widget class="QToolBar" name="toolBarColors">
    <property name="windowTitle">
@@ -1694,6 +1695,18 @@
     <string>P</string>
    </property>
   </action>
+  <action name="actionModeCurve">
+   <property name="icon">
+    <iconset resource="../ldforge.qrc">
+     <normaloff>:/icons/beziercurve.png</normaloff>:/icons/beziercurve.png</iconset>
+   </property>
+   <property name="text">
+    <string>Curve Mode</string>
+   </property>
+   <property name="shortcut">
+    <string>C</string>
+   </property>
+  </action>
  </widget>
  <resources>
   <include location="../ldforge.qrc"/>
--- a/src/toolsets/basictoolset.cpp	Sun Oct 04 02:59:38 2015 +0300
+++ b/src/toolsets/basictoolset.cpp	Sun Oct 04 04:26:11 2015 +0300
@@ -269,6 +269,11 @@
 	m_window->renderer()->setEditMode (EditModeType::Select);
 }
 
+void BasicToolset::modeCurve()
+{
+	m_window->renderer()->setEditMode (EditModeType::Curve);
+}
+
 void BasicToolset::modeDraw()
 {
 	m_window->renderer()->setEditMode (EditModeType::Draw);
--- a/src/toolsets/basictoolset.h	Sun Oct 04 02:59:38 2015 +0300
+++ b/src/toolsets/basictoolset.h	Sun Oct 04 04:26:11 2015 +0300
@@ -39,6 +39,7 @@
 	Q_INVOKABLE void modeMagicWand();
 	Q_INVOKABLE void modeRectangle();
 	Q_INVOKABLE void modeSelect();
+	Q_INVOKABLE void modeCurve();
 	Q_INVOKABLE void newBFC();
 	Q_INVOKABLE void newComment();
 	Q_INVOKABLE void newConditionalLine();

mercurial