- now compiles

Sat, 05 Jul 2014 01:17:48 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sat, 05 Jul 2014 01:17:48 +0300
changeset 827
82469b40567e
parent 826
d7a21e4a4ec3
child 828
7dd8f19159f7

- now compiles

src/actions.cc file | annotate | diff | comparison | revisions
src/editmodes/abstracteditmode.cc file | annotate | diff | comparison | revisions
src/editmodes/abstracteditmode.h file | annotate | diff | comparison | revisions
src/editmodes/circlemode.cc file | annotate | diff | comparison | revisions
src/editmodes/drawmode.cc file | annotate | diff | comparison | revisions
src/editmodes/drawmode.h file | annotate | diff | comparison | revisions
src/editmodes/magicwandmode.cc file | annotate | diff | comparison | revisions
src/editmodes/selectmode.cc file | annotate | diff | comparison | revisions
src/editmodes/selectmode.h file | annotate | diff | comparison | revisions
src/glRenderer.cc file | annotate | diff | comparison | revisions
src/glRenderer.h file | annotate | diff | comparison | revisions
--- a/src/actions.cc	Fri Jul 04 23:44:44 2014 +0300
+++ b/src/actions.cc	Sat Jul 05 01:17:48 2014 +0300
@@ -37,6 +37,7 @@
 #include "colors.h"
 #include "glCompiler.h"
 #include "ui_newpart.h"
+#include "editmodes/abstracteditmode.h"
 
 EXTERN_CFGENTRY (Bool,		drawWireframe);
 EXTERN_CFGENTRY (Bool,		bfcRedGreenView);
@@ -587,28 +588,28 @@
 //
 void MainWindow::slot_actionModeSelect()
 {
-	R()->setEditMode (ESelectMode);
+	R()->setEditMode (EditModeType::Select);
 }
 
 // =============================================================================
 //
 void MainWindow::slot_actionModeDraw()
 {
-	R()->setEditMode (EDrawMode);
+	R()->setEditMode (EditModeType::Draw);
 }
 
 // =============================================================================
 //
 void MainWindow::slot_actionModeCircle()
 {
-	R()->setEditMode (ECircleMode);
+	R()->setEditMode (EditModeType::Circle);
 }
 
 // =============================================================================
 //
 void MainWindow::slot_actionModeMagicWand()
 {
- 	R()->setEditMode (EMagicWandMode);
+ 	R()->setEditMode (EditModeType::MagicWand);
 }
 
 // =============================================================================
--- a/src/editmodes/abstracteditmode.cc	Fri Jul 04 23:44:44 2014 +0300
+++ b/src/editmodes/abstracteditmode.cc	Sat Jul 05 01:17:48 2014 +0300
@@ -1,3 +1,4 @@
+#include <QMouseEvent>
 #include <stdexcept>
 #include "abstracteditmode.h"
 #include "selectmode.h"
@@ -5,10 +6,13 @@
 #include "circlemode.h"
 #include "magicwandmode.h"
 #include "../mainWindow.h"
+#include "../glRenderer.h"
 
 AbstractEditMode::AbstractEditMode (GLRenderer* renderer) :
 	_renderer (renderer) {}
 
+AbstractEditMode::~AbstractEditMode() {}
+
 AbstractEditMode* AbstractEditMode::createByType (GLRenderer* renderer, EditModeType type)
 {
 	switch (type)
--- a/src/editmodes/abstracteditmode.h	Fri Jul 04 23:44:44 2014 +0300
+++ b/src/editmodes/abstracteditmode.h	Sat Jul 05 01:17:48 2014 +0300
@@ -1,9 +1,9 @@
 #pragma once
 #include "../main.h"
-#include "../glRenderer.h"
 
 class QPainter;
 class GLRenderer;
+class QMouseEvent;
 
 enum class EditModeType
 {
@@ -16,7 +16,6 @@
 class AbstractEditMode
 {
 	GLRenderer* _renderer;
-	QBrush		_polybrush;
 
 public:
 	struct MouseEventData
@@ -28,16 +27,16 @@
 	};
 
 	AbstractEditMode (GLRenderer* renderer);
+	virtual ~AbstractEditMode();
 
 	virtual bool			allowFreeCamera() const = 0;
-	virtual void			render (QPainter& painter) const {};
+	virtual void			render (QPainter&) const {};
 	GLRenderer*				renderer() const;
 	virtual EditModeType	type() const = 0;
 	virtual bool			mousePressed (QMouseEvent*) { return false; }
 	virtual bool			mouseReleased (MouseEventData const&) { return false; }
 	virtual bool			mouseDoubleClicked (QMouseEvent*) { return false; }
 	virtual bool			mouseMoved (QMouseEvent*) { return false; }
-	void					finishDraw (LDObjectList& objs);
 
 	static AbstractEditMode* createByType (GLRenderer* renderer, EditModeType type);
 };
@@ -47,10 +46,12 @@
 //
 class AbstractDrawMode : public AbstractEditMode
 {
+	DEFINE_CLASS (AbstractDrawMode, AbstractEditMode)
+
+protected:
 	QList<Vertex>			_drawedVerts;
-	Vertex					m_rectverts[4];
-
-	DEFINE_CLASS (AbstractDrawMode, AbstractEditMode)
+	Vertex					_rectverts[4];
+	QBrush					_polybrush;
 
 public:
 	AbstractDrawMode (GLRenderer* renderer);
@@ -62,6 +63,7 @@
 
 	bool mouseReleased (const AbstractEditMode::MouseEventData& data) override;
 	void addDrawnVertex (const Vertex& pos);
+	void finishDraw (LDObjectList& objs);
 
 	virtual bool preAddVertex (Vertex const&)
 	{
--- a/src/editmodes/circlemode.cc	Fri Jul 04 23:44:44 2014 +0300
+++ b/src/editmodes/circlemode.cc	Sat Jul 05 01:17:48 2014 +0300
@@ -5,10 +5,16 @@
 #include "../ldDocument.h"
 #include "../misc/ringFinder.h"
 #include "../primitives.h"
+#include "../glRenderer.h"
 
 CircleMode::CircleMode (GLRenderer* renderer) :
 	Super (renderer) {}
 
+EditModeType CircleMode::type() const
+{
+	return EditModeType::Circle;
+}
+
 double CircleMode::getCircleDrawDist (int pos) const
 {
 	assert (_drawedVerts.size() >= pos + 1);
@@ -150,7 +156,7 @@
 
 void CircleMode::render (QPainter& painter) const
 {
-	QFontMetrics const metrics (QFont());
+	QFontMetrics metrics = QFontMetrics (QFont());
 
 	// If we have not specified the center point of the circle yet, preview it on the screen.
 	if (_drawedVerts.isEmpty())
@@ -223,14 +229,14 @@
 
 		// Draw the circles
 		painter.setBrush (Qt::NoBrush);
-		painter.setPen (renderer()->getLinePen());
+		painter.setPen (renderer()->linePen());
 		painter.drawPolygon (QPolygon (circlepoints));
 		painter.drawPolygon (QPolygon (circle2points));
 
 		// Draw the current radius in the middle of the circle.
 		QPoint origin = renderer()->coordconv3_2 (_drawedVerts[0]);
 		QString label = QString::number (dist0);
-		painter.setPen (renderer()->getTextPen());
+		painter.setPen (renderer()->textPen());
 		painter.drawText (origin.x() - (metrics.width (label) / 2), origin.y(), label);
 
 		if (_drawedVerts.size() >= 2)
@@ -246,11 +252,15 @@
 	if (Super::mouseReleased (data))
 		return true;
 
-	if (_drawedVerts.size() < 3)
+	if (data.releasedButtons & Qt::LeftButton)
 	{
-		addDrawnVertex (renderer()->position3D());
-		return;
+		if (_drawedVerts.size() < 3)
+			addDrawnVertex (renderer()->position3D());
+		else
+			buildCircle();
+
+		return true;
 	}
 
-	buildCircle();
+	return false;
 }
--- a/src/editmodes/drawmode.cc	Fri Jul 04 23:44:44 2014 +0300
+++ b/src/editmodes/drawmode.cc	Sat Jul 05 01:17:48 2014 +0300
@@ -1,9 +1,11 @@
 #include <QPainter>
+#include <QMouseEvent>
 #include "drawmode.h"
 #include "../ldObject.h"
+#include "../glRenderer.h"
 
-CFGENTRY (Bool,		drawLineLengths,			true)
-CFGENTRY (Bool,		drawAngles,					false)
+CFGENTRY (Bool, drawLineLengths, true)
+CFGENTRY (Bool, drawAngles, false)
 
 DrawMode::DrawMode (GLRenderer* renderer) :
 	Super (renderer),
@@ -19,7 +21,7 @@
 	QPoint poly[4];
 	Vertex poly3d[4];
 	int numverts = 4;
-	QFontMetrics metrics (QFont());
+	QFontMetrics metrics = QFontMetrics (QFont());
 
 	// Calculate polygon data
 	if (not _rectdraw)
@@ -27,7 +29,7 @@
 		numverts = _drawedVerts.size() + 1;
 		int i = 0;
 
-		for (Vertex& vert : _drawedVerts)
+		for (Vertex const& vert : _drawedVerts)
 			poly3d[i++] = vert;
 
 		// Draw the cursor vertex as the last one in the list.
@@ -41,7 +43,7 @@
 		// Get vertex information from m_rectverts
 		if (_drawedVerts.size() > 0)
 			for (int i = 0; i < numverts; ++i)
-				poly3d[i] = m_rectverts[i];
+				poly3d[i] = _rectverts[i];
 		else
 			poly3d[0] = renderer()->position3D();
 	}
@@ -114,7 +116,7 @@
 	{
 		if (vert == pos)
 		{
-			endDraw (true);
+			endDraw();
 			return true;
 		}
 	}
@@ -127,32 +129,37 @@
 	if (Super::mouseReleased (data))
 		return true;
 
-	if (_rectdraw)
+	if (data.releasedButtons & Qt::LeftButton)
 	{
-		if (_drawedVerts.size() == 2)
+		if (_rectdraw)
 		{
-			endDraw (true);
-			return true;
+			if (_drawedVerts.size() == 2)
+			{
+				endDraw();
+				return true;
+			}
 		}
-	}
-	else
-	{
-		// If we have 4 verts, stop drawing.
-		if (_drawedVerts.size() >= 4)
+		else
 		{
-			endDraw (true);
-			return;
+			// If we have 4 verts, stop drawing.
+			if (_drawedVerts.size() >= 4)
+			{
+				endDraw();
+				return true;
+			}
+
+			if (_drawedVerts.isEmpty())
+			{
+				_rectdraw = (data.ev->modifiers() & Qt::ShiftModifier);
+				updateRectVerts();
+			}
 		}
 
-		if (_drawedVerts.isEmpty())
-		{
-			_rectdraw = (ev->modifiers() & Qt::ShiftModifier);
-			updateRectVerts();
-		}
+		addDrawnVertex (renderer()->position3D());
+		return true;
 	}
 
-	addDrawnVertex (renderer()->position3D());
-	return true;
+	return false;
 }
 
 //
@@ -161,6 +168,7 @@
 bool DrawMode::mouseMoved (QMouseEvent*)
 {
 	updateRectVerts();
+	return false;
 }
 
 void DrawMode::updateRectVerts()
@@ -171,7 +179,7 @@
 	if (_drawedVerts.isEmpty())
 	{
 		for (int i = 0; i < 4; ++i)
-			m_rectverts[i] = renderer()->position3D();
+			_rectverts[i] = renderer()->position3D();
 
 		return;
 	}
@@ -184,16 +192,16 @@
 			   localz = (Axis) (3 - localx - localy);
 
 	for (int i = 0; i < 4; ++i)
-		m_rectverts[i].setCoordinate (localz, renderer()->getDepthValue());
+		_rectverts[i].setCoordinate (localz, renderer()->getDepthValue());
 
-	m_rectverts[0].setCoordinate (localx, v0[localx]);
-	m_rectverts[0].setCoordinate (localy, v0[localy]);
-	m_rectverts[1].setCoordinate (localx, v1[localx]);
-	m_rectverts[1].setCoordinate (localy, v0[localy]);
-	m_rectverts[2].setCoordinate (localx, v1[localx]);
-	m_rectverts[2].setCoordinate (localy, v1[localy]);
-	m_rectverts[3].setCoordinate (localx, v0[localx]);
-	m_rectverts[3].setCoordinate (localy, v1[localy]);
+	_rectverts[0].setCoordinate (localx, v0[localx]);
+	_rectverts[0].setCoordinate (localy, v0[localy]);
+	_rectverts[1].setCoordinate (localx, v1[localx]);
+	_rectverts[1].setCoordinate (localy, v0[localy]);
+	_rectverts[2].setCoordinate (localx, v1[localx]);
+	_rectverts[2].setCoordinate (localy, v1[localy]);
+	_rectverts[3].setCoordinate (localx, v0[localx]);
+	_rectverts[3].setCoordinate (localy, v1[localy]);
 }
 
 void DrawMode::endDraw()
@@ -209,7 +217,7 @@
 		updateRectVerts();
 
 		for (int i = 0; i < quad->numVertices(); ++i)
-			quad->setVertex (i, m_rectverts[i]);
+			quad->setVertex (i, _rectverts[i]);
 
 		quad->setColor (maincolor());
 		objs << quad;
--- a/src/editmodes/drawmode.h	Fri Jul 04 23:44:44 2014 +0300
+++ b/src/editmodes/drawmode.h	Sat Jul 05 01:17:48 2014 +0300
@@ -15,5 +15,6 @@
 	virtual bool mouseMoved (QMouseEvent*) override;
 
 private:
+	void endDraw();
 	void updateRectVerts();
 };
--- a/src/editmodes/magicwandmode.cc	Fri Jul 04 23:44:44 2014 +0300
+++ b/src/editmodes/magicwandmode.cc	Sat Jul 05 01:17:48 2014 +0300
@@ -20,6 +20,7 @@
 #include "magicwandmode.h"
 #include "../ldDocument.h"
 #include "../mainWindow.h"
+#include "../glRenderer.h"
 
 MagicWandMode::MagicWandMode (GLRenderer* renderer) :
 	Super (renderer)
@@ -39,11 +40,6 @@
 	return EditModeType::MagicWand;
 }
 
-bool MagicWandMode::allowFreeCamera() const
-{
-	return true;
-}
-
 void MagicWandMode::fillBoundaries (LDObjectPtr obj, QVector<BoundaryType>& boundaries, QVector<LDObjectPtr>& candidates)
 {
 	// All boundaries obviously share vertices with the object, therefore they're all in the list
@@ -202,13 +198,18 @@
 	if (Super::mouseReleased (data))
 		return true;
 
-	MagicType wandtype = MagicWandMode::Set;
+	if (data.releasedButtons & Qt::LeftButton)
+	{
+		MagicType wandtype = MagicWandMode::Set;
 
-	if (data.keymods & Qt::ShiftModifier)
-		wandtype = MagicWandMode::Additive;
-	elif (data.keymods & Qt::ControlModifier)
-		wandtype = MagicWandMode::Subtractive;
-	
-	doMagic (renderer()->pickOneObject (data.ev->x(), data.ev->y()), wandtype);
-	return true;
+		if (data.keymods & Qt::ShiftModifier)
+			wandtype = MagicWandMode::Additive;
+		elif (data.keymods & Qt::ControlModifier)
+			wandtype = MagicWandMode::Subtractive;
+
+		doMagic (renderer()->pickOneObject (data.ev->x(), data.ev->y()), wandtype);
+		return true;
+	}
+
+	return false;
 }
--- a/src/editmodes/selectmode.cc	Fri Jul 04 23:44:44 2014 +0300
+++ b/src/editmodes/selectmode.cc	Sat Jul 05 01:17:48 2014 +0300
@@ -1,6 +1,9 @@
 #include <QMouseEvent>
+#include "selectmode.h"
 #include "../glRenderer.h"
-#include "selectmode.h"
+#include "../addObjectDialog.h"
+#include "../mainWindow.h"
+#include "../glRenderer.h"
 
 SelectMode::SelectMode (GLRenderer* renderer) :
 	Super (renderer) {}
@@ -10,21 +13,58 @@
 	return EditModeType::Select;
 }
 
+
+void SelectMode::render (QPainter& painter) const
+{
+	// If we're range-picking, draw a rectangle encompassing the selection area.
+	if (_rangepick && not renderer()->mouseHasMoved())
+	{
+		int x0 = _rangeStart.x(),
+			y0 = _rangeStart.y(),
+			x1 = renderer()->mousePosition().x(),
+			y1 = renderer()->mousePosition().y();
+
+		QRect rect (x0, y0, x1 - x0, y1 - y0);
+		QColor fillColor = (_addpick ? "#40FF00" : "#00CCFF");
+		fillColor.setAlphaF (0.2f);
+		painter.setPen (QPen (QColor (0, 0, 0, 208), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
+		painter.setBrush (QBrush (fillColor));
+		painter.drawRect (rect);
+	}
+}
+
 bool SelectMode::mouseReleased (MouseEventData const& data)
 {
 	if (Super::mouseReleased (data))
 		return true;
 
-	if (not data.mouseMoved)
-		_rangepick = false;
+	if (data.releasedButtons & Qt::LeftButton)
+	{
+		if (not data.mouseMoved)
+			_rangepick = false;
+
+		if (not _rangepick)
+			_addpick = (data.keymods & Qt::ControlModifier);
+
+		if (not data.mouseMoved || _rangepick)
+		{
+			QRect area;
+			int const mx = data.ev->x();
+			int const my = data.ev->y();
 
-	if (not _rangepick)
-		_addpick = (data.keymods & Qt::ControlModifier);
+			if (not _rangepick)
+				area = QRect (mx, my, mx + 1, my + 1);
+			else
+				area = QRect (_rangeStart.x(), _rangeStart.y(), mx, my);
 
-	if (not data.mouseMoved || _rangepick)
-		renderer()->pick (data.ev->x(), data.ev->y());
+			renderer()->pick (area, _addpick);
+		}
 
-	_rangepick = false;
+		_rangepick = false;
+		return true;
+	}
+
+	return false;
 }
 
 bool SelectMode::mousePressed (QMouseEvent* ev)
@@ -64,3 +104,8 @@
 
 	return false;
 }
+
+bool SelectMode::mouseMoved (QMouseEvent*)
+{
+	return not _rangepick;
+}
--- a/src/editmodes/selectmode.h	Fri Jul 04 23:44:44 2014 +0300
+++ b/src/editmodes/selectmode.h	Sat Jul 05 01:17:48 2014 +0300
@@ -11,7 +11,10 @@
 public:
 	SelectMode (GLRenderer* renderer);
 
+	virtual void render (QPainter& painter) const override;
+	virtual bool mousePressed (QMouseEvent* ev);
 	virtual bool mouseReleased (MouseEventData const& data) override;
 	virtual bool mouseDoubleClicked (QMouseEvent* ev);
+	virtual bool mouseMoved (QMouseEvent*) override;
 	virtual EditModeType type() const override;
 };
\ No newline at end of file
--- a/src/glRenderer.cc	Fri Jul 04 23:44:44 2014 +0300
+++ b/src/glRenderer.cc	Sat Jul 05 01:17:48 2014 +0300
@@ -40,8 +40,9 @@
 #include "addObjectDialog.h"
 #include "messageLog.h"
 #include "glCompiler.h"
+#include "primitives.h"
 
-static const LDFixedCameraInfo g_FixedCameras[6] =
+static const LDFixedCamera g_FixedCameras[6] =
 {
 	{{  1,  0, 0 }, X, Z, false, false, false }, // top
 	{{  0,  0, 0 }, X, Y, false,  true, false }, // front
@@ -104,7 +105,7 @@
 	m_isPicking = false;
 	m_camera = (ECamera) cfg::camera;
 	m_drawToolTip = false;
-	m_editmode = AbstractEditMode::createByType (EditModeType::Select);
+	m_editmode = AbstractEditMode::createByType (this, EditModeType::Select);
 	m_panning = false;
 	m_compiler = new GLCompiler (this);
 	setDrawOnly (false);
@@ -114,8 +115,7 @@
 	m_toolTipTimer = new QTimer (this);
 	m_toolTipTimer->setSingleShot (true);
 	m_isCameraMoving = false;
-	m_thickBorderPen = QPen (QColor (0, 0, 0, 208), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
-	m_thinBorderPen = m_thickBorderPen;
+	m_thinBorderPen = QPen (QColor (0, 0, 0, 208), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
 	m_thinBorderPen.setWidth (1);
 	setAcceptDrops (true);
 	connect (m_toolTipTimer, SIGNAL (timeout()), this, SLOT (slot_toolTipTimer()));
@@ -143,6 +143,7 @@
 		delete info.img;
 
 	delete m_compiler;
+	delete m_editmode;
 }
 
 // =============================================================================
@@ -693,23 +694,6 @@
 			y += metrics.height();
 		}
 	}
-
-	// If we're range-picking, draw a rectangle encompassing the selection area.
-	if (m_rangepick && not isPicking() && m_totalmove >= 10)
-	{
-		int x0 = m_rangeStart.x(),
-			y0 = m_rangeStart.y(),
-			x1 = m_mousePosition.x(),
-			y1 = m_mousePosition.y();
-
-		QRect rect (x0, y0, x1 - x0, y1 - y0);
-		QColor fillColor = (m_addpick ? "#40FF00" : "#00CCFF");
-		fillColor.setAlphaF (0.2f);
-
-		paint.setPen (m_thickBorderPen);
-		paint.setBrush (QBrush (fillColor));
-		paint.drawRect (rect);
-	}
 }
 
 // =============================================================================
@@ -739,9 +723,7 @@
 //
 void GLRenderer::mouseReleaseEvent (QMouseEvent* ev)
 {
-	const bool wasLeft = (m_lastButtons & Qt::LeftButton) && not (ev->buttons() & Qt::LeftButton),
-	   wasRight = (m_lastButtons & Qt::RightButton) && not (ev->buttons() & Qt::RightButton),
-	   wasMid = (m_lastButtons & Qt::MidButton) && not (ev->buttons() & Qt::MidButton);
+	const bool wasLeft = (m_lastButtons & Qt::LeftButton) && not (ev->buttons() & Qt::LeftButton);
 
 	Qt::MouseButtons releasedbuttons = m_lastButtons & ~ev->buttons();
 
@@ -751,7 +733,7 @@
 	if (wasLeft)
 	{
 		// Check if we selected a camera icon
-		if (m_totalmove < 10)
+		if (not mouseHasMoved())
 		{
 			for (CameraIcon & info : m_cameraIcons)
 			{
@@ -762,18 +744,18 @@
 				}
 			}
 		}
+	}
 
-		if (not isDrawOnly())
-		{
-			AbstractEditMode::MouseEventData data;
-			data.ev = ev;
-			data.mouseMoved = m_totalmove >= 10;
-			data.keymods = m_keymods;
-			data.releasedButtons = releasedbuttons;
+	if (not isDrawOnly())
+	{
+		AbstractEditMode::MouseEventData data;
+		data.ev = ev;
+		data.mouseMoved = mouseHasMoved();
+		data.keymods = m_keymods;
+		data.releasedButtons = releasedbuttons;
 
-			if (m_editmode->mouseReleased (data))
-				goto end;
-		}
+		if (m_editmode->mouseReleased (data))
+			goto end;
 	}
 
 end:
@@ -796,30 +778,33 @@
 //
 void GLRenderer::mouseMoveEvent (QMouseEvent* ev)
 {
-	int dx = ev->x() - m_mousePosition.x();
-	int dy = ev->y() - m_mousePosition.y();
-	m_totalmove += abs (dx) + abs (dy);
-	setCameraMoving (false);
-
-	const bool left = ev->buttons() & Qt::LeftButton,
-			   mid = ev->buttons() & Qt::MidButton,
-			   shift = ev->modifiers() & Qt::ShiftModifier;
-
-	if (mid || (left && shift))
+	if (not m_editmode->mouseMoved (ev))
 	{
-		pan (X) += 0.03f * dx * (zoom() / 7.5f);
-		pan (Y) -= 0.03f * dy * (zoom() / 7.5f);
-		m_panning = true;
-		setCameraMoving (true);
-	}
-	elif (left && not m_rangepick && camera() == EFreeCamera)
-	{
-		rot (X) = rot (X) + dy;
-		rot (Y) = rot (Y) + dx;
+		int dx = ev->x() - m_mousePosition.x();
+		int dy = ev->y() - m_mousePosition.y();
+		m_totalmove += abs (dx) + abs (dy);
+		setCameraMoving (false);
+
+		const bool left = ev->buttons() & Qt::LeftButton,
+				mid = ev->buttons() & Qt::MidButton,
+				shift = ev->modifiers() & Qt::ShiftModifier;
 
-		clampAngle (rot (X));
-		clampAngle (rot (Y));
-		setCameraMoving (true);
+		if (mid || (left && shift))
+		{
+			pan (X) += 0.03f * dx * (zoom() / 7.5f);
+			pan (Y) -= 0.03f * dy * (zoom() / 7.5f);
+			m_panning = true;
+			setCameraMoving (true);
+		}
+		elif (left && camera() == EFreeCamera)
+		{
+			rot (X) = rot (X) + dy;
+			rot (Y) = rot (Y) + dx;
+
+			clampAngle (rot (X));
+			clampAngle (rot (Y));
+			setCameraMoving (true);
+		}
 	}
 
 	// Start the tool tip timer
@@ -833,7 +818,6 @@
 	// Calculate 3d position of the cursor
 	m_position3D = (camera() != EFreeCamera) ? coordconv2_3 (m_mousePosition, true) : g_origin;
 
-	m_editmode->mouseMoved (ev);
 	highlightCursorObject();
 	update();
 	ev->accept();
@@ -898,12 +882,19 @@
 
 // =============================================================================
 //
-void GLRenderer::pick (int mouseX, int mouseY)
+void GLRenderer::pick (int mouseX, int mouseY, bool additive)
+{
+	pick (QRect (mouseX, mouseY, mouseX + 1, mouseY + 1), additive);
+}
+
+// =============================================================================
+//
+void GLRenderer::pick (QRect const& range, bool additive)
 {
 	makeCurrent();
 
 	// Clear the selection if we do not wish to add to it.
-	if (not m_addpick)
+	if (not additive)
 	{
 		LDObjectList oldsel = selection();
 		getCurrentDocument()->clearSelection();
@@ -916,29 +907,10 @@
 	setPicking (true);
 	drawGLScene();
 
-	int x0 = mouseX,
-		  y0 = mouseY;
-	int x1, y1;
-
-	// Determine how big an area to read - with range picking, we pick by
-	// the area given, with single pixel picking, we use an 1 x 1 area.
-	if (m_rangepick)
-	{
-		x1 = m_rangeStart.x();
-		y1 = m_rangeStart.y();
-	}
-	else
-	{
-		x1 = x0 + 1;
-		y1 = y0 + 1;
-	}
-
-	// x0 and y0 must be less than x1 and y1, respectively.
-	if (x0 > x1)
-		qSwap (x0, x1);
-
-	if (y0 > y1)
-		qSwap (y0, y1);
+	int x0 = range.left();
+	int y0 = range.top();
+	int x1 = range.right();
+	int y1 = range.bottom();
 
 	// Clamp the values to ensure they're within bounds
 	x0 = max (0, x0);
@@ -982,7 +954,7 @@
 
 		// If this is an additive single pick and the object is currently selected,
 		// we remove it from selection instead.
-		if (not m_rangepick && m_addpick)
+		if (range.isNull() && additive)
 		{
 			if (obj->isSelected())
 			{
@@ -1008,7 +980,6 @@
 		compileObject (removedObj);
 
 	setPicking (false);
-	m_rangepick = false;
 	repaint();
 }
 
@@ -1036,7 +1007,7 @@
 		return;
 
 	delete m_editmode;
-	m_editmode = AbstractEditMode::createByType (a);
+	m_editmode = AbstractEditMode::createByType (this, a);
 
 	// If we cannot use the free camera, use the top one instead.
 	if (camera() == EFreeCamera && not m_editmode->allowFreeCamera())
@@ -1625,7 +1596,17 @@
 	return m_position3D;
 }
 
-LDFixedCamera const& GLRenderer::getFixedCamera (ECamera cam)
+LDFixedCamera const& GLRenderer::getFixedCamera (ECamera cam) const
 {
 	return g_FixedCameras[cam];
 }
+
+bool GLRenderer::mouseHasMoved() const
+{
+	return m_totalmove < 10;
+}
+
+QPoint const& GLRenderer::mousePosition() const
+{
+	return m_mousePosition;
+}
--- a/src/glRenderer.h	Fri Jul 04 23:44:44 2014 +0300
+++ b/src/glRenderer.h	Sat Jul 05 01:17:48 2014 +0300
@@ -173,7 +173,12 @@
 	void					initGLData();
 	void					initOverlaysFromObjects();
 	QPen					linePen() const;
+	bool					mouseHasMoved() const;
+	QPoint const&			mousePosition() const;
 	void					needZoomToFit();
+	void					pick (int mouseX, int mouseY, bool additive);
+	void					pick (QRect const& range, bool additive);
+	LDObjectPtr				pickOneObject (int mouseX, int mouseY);
 	Vertex const&			position3D() const;
 	void					refresh();
 	void					resetAngles();
@@ -219,8 +224,7 @@
 							m_panning;
 	QPoint					m_mousePosition,
 							m_globalpos;
-	QPen					m_thickBorderPen,
-							m_thinBorderPen;
+	QPen					m_thinBorderPen;
 	ECamera					m_camera,
 							m_toolTipCamera;
 	GLuint					m_axeslist;
@@ -237,8 +241,6 @@
 	LDOverlayPtr			findOverlayObject (ECamera cam);
 	inline double&			pan (Axis ax);
 	inline const double&	pan (Axis ax) const;
-	void					pick (int mouseX, int mouseY);
-	LDObjectPtr				pickOneObject (int mouseX, int mouseY);
 	inline double&			rot (Axis ax);
 	inline double&			zoom();
 	void					zoomToFit();

mercurial