Tue, 15 Jul 2014 02:54:23 +0300
- split the rectangle ability out of the draw mode into its own edit mode
--- a/CMakeLists.txt Sun Jul 13 20:40:24 2014 +0300 +++ b/CMakeLists.txt Tue Jul 15 02:54:23 2014 +0300 @@ -51,6 +51,7 @@ src/editmodes/circleMode.cc src/editmodes/drawMode.cc src/editmodes/magicWandMode.cc + src/editmodes/rectangleMode.cc src/editmodes/selectMode.cc ) @@ -84,6 +85,7 @@ src/editmodes/circleMode.h src/editmodes/drawMode.h src/editmodes/magicWandMode.h + src/editmodes/rectangleMode.h src/editmodes/selectMode.h )
--- a/ldforge.qrc Sun Jul 13 20:40:24 2014 +0300 +++ b/ldforge.qrc Tue Jul 15 02:54:23 2014 +0300 @@ -71,6 +71,7 @@ <file>./icons/mode-circle.png</file> <file>./icons/mode-draw.png</file> <file>./icons/mode-magicwand.png</file> + <file>./icons/mode-rectangle.png</file> <file>./icons/mode-select.png</file> <file>./icons/move-x-neg.png</file> <file>./icons/move-x-pos.png</file>
--- a/src/actions.cc Sun Jul 13 20:40:24 2014 +0300 +++ b/src/actions.cc Tue Jul 15 02:54:23 2014 +0300 @@ -600,6 +600,13 @@ // ============================================================================= // +void MainWindow::slot_actionModeRectangle() +{ + R()->setEditMode (EditModeType::Rectangle); +} + +// ============================================================================= +// void MainWindow::slot_actionModeCircle() { R()->setEditMode (EditModeType::Circle);
--- a/src/editmodes/abstractEditMode.cc Sun Jul 13 20:40:24 2014 +0300 +++ b/src/editmodes/abstractEditMode.cc Tue Jul 15 02:54:23 2014 +0300 @@ -21,11 +21,15 @@ #include "abstractEditMode.h" #include "selectMode.h" #include "drawMode.h" +#include "rectangleMode.h" #include "circleMode.h" #include "magicWandMode.h" #include "../mainWindow.h" #include "../glRenderer.h" +CFGENTRY (Bool, drawLineLengths, true) +CFGENTRY (Bool, drawAngles, false) + AbstractEditMode::AbstractEditMode (GLRenderer* renderer) : _renderer (renderer) {} @@ -37,6 +41,7 @@ { case EditModeType::Select: return new SelectMode (renderer); case EditModeType::Draw: return new DrawMode (renderer); + case EditModeType::Rectangle: return new RectangleMode (renderer); case EditModeType::Circle: return new CircleMode (renderer); case EditModeType::MagicWand: return new MagicWandMode (renderer); } @@ -152,7 +157,7 @@ return false; } -void AbstractDrawMode::finishDraw (LDObjectList& objs) +void AbstractDrawMode::finishDraw (LDObjectList const& objs) { if (objs.size() > 0) { @@ -168,3 +173,65 @@ _drawedVerts.clear(); } + +void AbstractDrawMode::renderPolygon (QPainter& painter, const QVector<Vertex>& poly3d, bool withangles) const +{ + QVector<QPoint> poly (poly3d.size()); + QFontMetrics metrics = QFontMetrics (QFont()); + + // Convert to 2D + for (int i = 0; i < poly3d.size(); ++i) + poly[i] = renderer()->coordconv3_2 (poly3d[i]); + + // Draw the polygon-to-be + painter.setBrush (_polybrush); + painter.drawPolygon (QPolygonF (poly)); + + // Draw vertex blips + for (int i = 0; i < poly3d.size(); ++i) + { + QPoint& blip = poly[i]; + painter.setPen (renderer()->linePen()); + renderer()->drawBlip (painter, blip); + + // Draw their coordinates + painter.setPen (renderer()->textPen()); + painter.drawText (blip.x(), blip.y() - 8, poly3d[i].toString (true)); + } + + // Draw line lenghts and angle info if appropriate + if (poly3d.size() >= 2) + { + painter.setPen (renderer()->textPen()); + + for (int i = 0; i < poly3d.size(); ++i) + { + const int j = (i + 1) % poly3d.size(); + const int h = (i - 1 >= 0) ? (i - 1) : (poly3d.size() - 1); + + if (cfg::drawLineLengths) + { + const QString label = QString::number ((poly3d[j] - poly3d[i]).length()); + QPoint origin = QLineF (poly[i], poly[j]).pointAt (0.5).toPoint(); + painter.drawText (origin, label); + } + + if (withangles and cfg::drawAngles) + { + QLineF l0 (poly[h], poly[i]), + l1 (poly[i], poly[j]); + + double angle = 180 - l0.angleTo (l1); + + if (angle < 0) + angle = 180 - l1.angleTo (l0); + + QString label = QString::number (angle) + QString::fromUtf8 (QByteArray ("\302\260")); + QPoint pos = poly[i]; + pos.setY (pos.y() + metrics.height()); + + painter.drawText (pos, label); + } + } + } +}
--- a/src/editmodes/abstractEditMode.h Sun Jul 13 20:40:24 2014 +0300 +++ b/src/editmodes/abstractEditMode.h Tue Jul 15 02:54:23 2014 +0300 @@ -27,6 +27,7 @@ { Select, Draw, + Rectangle, Circle, MagicWand, }; @@ -68,7 +69,6 @@ protected: QList<Vertex> _drawedVerts; - Vertex _rectverts[4]; QBrush _polybrush; public: @@ -81,7 +81,8 @@ bool mouseReleased (const AbstractEditMode::MouseEventData& data) override; void addDrawnVertex (const Vertex& pos); - void finishDraw (LDObjectList& objs); + void finishDraw (const LDObjectList& objs); + void renderPolygon (QPainter& painter, const QVector<Vertex>& poly3d, bool withangles) const; virtual bool preAddVertex (Vertex const&) {
--- a/src/editmodes/drawMode.cc Sun Jul 13 20:40:24 2014 +0300 +++ b/src/editmodes/drawMode.cc Tue Jul 15 02:54:23 2014 +0300 @@ -22,12 +22,8 @@ #include "../ldObject.h" #include "../glRenderer.h" -CFGENTRY (Bool, drawLineLengths, true) -CFGENTRY (Bool, drawAngles, false) - DrawMode::DrawMode (GLRenderer* renderer) : - Super (renderer), - _rectdraw (false) {} + Super (renderer) {} EditModeType DrawMode::type() const { @@ -36,95 +32,17 @@ void DrawMode::render (QPainter& painter) const { - QPoint poly[4]; - Vertex poly3d[4]; - int numverts = 4; + QVector<Vertex> poly; QFontMetrics metrics = QFontMetrics (QFont()); - // Calculate polygon data - if (not _rectdraw) - { - numverts = _drawedVerts.size() + 1; - int i = 0; - - for (Vertex const& vert : _drawedVerts) - poly3d[i++] = vert; - - // Draw the cursor vertex as the last one in the list. - if (numverts <= 4) - poly3d[i] = renderer()->position3D(); - else - numverts = 4; - } - else - { - // Get vertex information from m_rectverts - if (_drawedVerts.size() > 0) - for (int i = 0; i < numverts; ++i) - poly3d[i] = _rectverts[i]; - else - poly3d[0] = renderer()->position3D(); - } - - // Convert to 2D - for (int i = 0; i < numverts; ++i) - poly[i] = renderer()->coordconv3_2 (poly3d[i]); - - if (numverts > 0) - { - // Draw the polygon-to-be - painter.setBrush (_polybrush); - painter.drawPolygon (poly, numverts); - - // Draw vertex blips - for (int i = 0; i < numverts; ++i) - { - QPoint& blip = poly[i]; - painter.setPen (renderer()->linePen()); - renderer()->drawBlip (painter, blip); + for (Vertex const& vert : _drawedVerts) + poly << vert; - // Draw their coordinates - painter.setPen (renderer()->textPen()); - painter.drawText (blip.x(), blip.y() - 8, poly3d[i].toString (true)); - } - - // Draw line lenghts and angle info if appropriate - if (numverts >= 2) - { - int numlines = (_drawedVerts.size() == 1) ? 1 : _drawedVerts.size() + 1; - painter.setPen (renderer()->textPen()); - - for (int i = 0; i < numlines; ++i) - { - const int j = (i + 1 < numverts) ? i + 1 : 0; - const int h = (i - 1 >= 0) ? i - 1 : numverts - 1; + // Draw the cursor vertex as the last one in the list. + if (poly.size() < 4) + poly << renderer()->position3D(); - if (cfg::drawLineLengths) - { - const QString label = QString::number ((poly3d[j] - poly3d[i]).length()); - QPoint origin = QLineF (poly[i], poly[j]).pointAt (0.5).toPoint(); - painter.drawText (origin, label); - } - - if (cfg::drawAngles) - { - QLineF l0 (poly[h], poly[i]), - l1 (poly[i], poly[j]); - - double angle = 180 - l0.angleTo (l1); - - if (angle < 0) - angle = 180 - l1.angleTo (l0); - - QString label = QString::number (angle) + QString::fromUtf8 (QByteArray ("\302\260")); - QPoint pos = poly[i]; - pos.setY (pos.y() + metrics.height()); - - painter.drawText (pos, label); - } - } - } - } + renderPolygon (painter, poly, true); } bool DrawMode::preAddVertex (Vertex const& pos) @@ -149,28 +67,11 @@ if (data.releasedButtons & Qt::LeftButton) { - if (_rectdraw) - { - if (_drawedVerts.size() == 2) - { - endDraw(); - return true; - } - } - else + // If we have 4 verts, stop drawing. + if (_drawedVerts.size() >= 4) { - // If we have 4 verts, stop drawing. - if (_drawedVerts.size() >= 4) - { - endDraw(); - return true; - } - - if (_drawedVerts.isEmpty()) - { - _rectdraw = (data.ev->modifiers() & Qt::ShiftModifier); - updateRectVerts(); - } + endDraw(); + return true; } addDrawnVertex (renderer()->position3D()); @@ -180,107 +81,49 @@ return false; } -// -// Update rect vertices when the mouse moves since the 3d position likely has changed -// -bool DrawMode::mouseMoved (QMouseEvent*) -{ - updateRectVerts(); - return false; -} - -void DrawMode::updateRectVerts() -{ - if (not _rectdraw) - return; - - if (_drawedVerts.isEmpty()) - { - for (int i = 0; i < 4; ++i) - _rectverts[i] = renderer()->position3D(); - - return; - } - - Vertex v0 = _drawedVerts[0], - v1 = (_drawedVerts.size() >= 2) ? _drawedVerts[1] : renderer()->position3D(); - - const Axis localx = renderer()->getCameraAxis (false), - localy = renderer()->getCameraAxis (true), - localz = (Axis) (3 - localx - localy); - - for (int i = 0; i < 4; ++i) - _rectverts[i].setCoordinate (localz, renderer()->getDepthValue()); - - _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() { // Clean the selection and create the object QList<Vertex>& verts = _drawedVerts; LDObjectList objs; - if (_rectdraw) + switch (verts.size()) { - LDQuadPtr quad (spawn<LDQuad>()); - - updateRectVerts(); + case 1: + { + // 1 vertex - add a vertex object + LDVertexPtr obj = spawn<LDVertex>(); + obj->pos = verts[0]; + obj->setColor (maincolor()); + objs << obj; + break; + } - for (int i = 0; i < quad->numVertices(); ++i) - quad->setVertex (i, _rectverts[i]); - - quad->setColor (maincolor()); - objs << quad; - } - else - { - switch (verts.size()) + case 2: { - case 1: - { - // 1 vertex - add a vertex object - LDVertexPtr obj = spawn<LDVertex>(); - obj->pos = verts[0]; - obj->setColor (maincolor()); - objs << obj; - break; - } + // 2 verts - make a line + LDLinePtr obj = spawn<LDLine> (verts[0], verts[1]); + obj->setColor (edgecolor()); + objs << obj; + break; + } - case 2: - { - // 2 verts - make a line - LDLinePtr obj = spawn<LDLine> (verts[0], verts[1]); - obj->setColor (edgecolor()); - objs << obj; - break; - } + case 3: + case 4: + { + LDObjectPtr obj = (verts.size() == 3) ? + static_cast<LDObjectPtr> (spawn<LDTriangle>()) : + static_cast<LDObjectPtr> (spawn<LDQuad>()); - case 3: - case 4: - { - LDObjectPtr obj = (verts.size() == 3) ? - static_cast<LDObjectPtr> (spawn<LDTriangle>()) : - static_cast<LDObjectPtr> (spawn<LDQuad>()); + obj->setColor (maincolor()); - obj->setColor (maincolor()); + for (int i = 0; i < verts.size(); ++i) + obj->setVertex (i, verts[i]); - for (int i = 0; i < verts.size(); ++i) - obj->setVertex (i, verts[i]); - - objs << obj; - break; - } + objs << obj; + break; } } finishDraw (objs); - _rectdraw = false; }
--- a/src/editmodes/drawMode.h Sun Jul 13 20:40:24 2014 +0300 +++ b/src/editmodes/drawMode.h Tue Jul 15 02:54:23 2014 +0300 @@ -31,9 +31,7 @@ virtual EditModeType type() const override; virtual bool preAddVertex (Vertex const& pos) override; virtual bool mouseReleased (MouseEventData const& data) override; - virtual bool mouseMoved (QMouseEvent*) override; private: void endDraw(); - void updateRectVerts(); };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/editmodes/rectangleMode.cc Tue Jul 15 02:54:23 2014 +0300 @@ -0,0 +1,104 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013, 2014 Santeri 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 <QPainter> +#include <QMouseEvent> +#include "rectangleMode.h" +#include "../ldObject.h" +#include "../glRenderer.h" + +RectangleMode::RectangleMode (GLRenderer* renderer) : + Super (renderer), + _rectangleVerts (QVector<Vertex>(4)) {} + +EditModeType RectangleMode::type() const +{ + return EditModeType::Rectangle; +} + +void RectangleMode::render (QPainter& painter) const +{ + renderPolygon (painter, (_drawedVerts.size() > 0) ? _rectangleVerts : + QVector<Vertex> ({renderer()->position3D()}), false); +} + +bool RectangleMode::mouseReleased (MouseEventData const& data) +{ + if (Super::mouseReleased (data)) + return true; + + if (data.releasedButtons & Qt::LeftButton) + { + if (_drawedVerts.size() == 2) + { + LDQuadPtr quad (spawn<LDQuad>()); + updateRectVerts(); + + for (int i = 0; i < quad->numVertices(); ++i) + quad->setVertex (i, _rectangleVerts[i]); + + quad->setColor (maincolor()); + finishDraw (LDObjectList ({quad})); + return true; + } + + addDrawnVertex (renderer()->position3D()); + return true; + } + + return false; +} + +// +// Update rect vertices when the mouse moves since the 3d position likely has changed +// +bool RectangleMode::mouseMoved (QMouseEvent*) +{ + updateRectVerts(); + return false; +} + +void RectangleMode::updateRectVerts() +{ + if (_drawedVerts.isEmpty()) + { + for (int i = 0; i < 4; ++i) + _rectangleVerts[i] = renderer()->position3D(); + + return; + } + + Vertex v0 = _drawedVerts[0], + v1 = (_drawedVerts.size() >= 2) ? _drawedVerts[1] : renderer()->position3D(); + + const Axis localx = renderer()->getCameraAxis (false), + localy = renderer()->getCameraAxis (true), + localz = (Axis) (3 - localx - localy); + + for (int i = 0; i < 4; ++i) + _rectangleVerts[i].setCoordinate (localz, renderer()->getDepthValue()); + + _rectangleVerts[0].setCoordinate (localx, v0[localx]); + _rectangleVerts[0].setCoordinate (localy, v0[localy]); + _rectangleVerts[1].setCoordinate (localx, v1[localx]); + _rectangleVerts[1].setCoordinate (localy, v0[localy]); + _rectangleVerts[2].setCoordinate (localx, v1[localx]); + _rectangleVerts[2].setCoordinate (localy, v1[localy]); + _rectangleVerts[3].setCoordinate (localx, v0[localx]); + _rectangleVerts[3].setCoordinate (localy, v1[localy]); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/editmodes/rectangleMode.h Tue Jul 15 02:54:23 2014 +0300 @@ -0,0 +1,37 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013, 2014 Santeri 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 RectangleMode : public AbstractDrawMode +{ + DEFINE_CLASS (RectangleMode, AbstractDrawMode) + QVector<Vertex> _rectangleVerts; + +public: + RectangleMode (GLRenderer* renderer); + + virtual void render (QPainter& painter) const override; + virtual EditModeType type() const override; + virtual bool mouseReleased (MouseEventData const& data) override; + virtual bool mouseMoved (QMouseEvent*) override; + +private: + void updateRectVerts(); +};
--- a/src/mainWindow.cc Sun Jul 13 20:40:24 2014 +0300 +++ b/src/mainWindow.cc Tue Jul 15 02:54:23 2014 +0300 @@ -694,6 +694,7 @@ const EditModeType mode = R()->currentEditModeType(); ui->actionModeSelect->setChecked (mode == EditModeType::Select); ui->actionModeDraw->setChecked (mode == EditModeType::Draw); + ui->actionModeRectangle->setChecked (mode == EditModeType::Rectangle); ui->actionModeCircle->setChecked (mode == EditModeType::Circle); ui->actionModeMagicWand->setChecked (mode == EditModeType::MagicWand); }
--- a/src/mainWindow.h Sun Jul 13 20:40:24 2014 +0300 +++ b/src/mainWindow.h Tue Jul 15 02:54:23 2014 +0300 @@ -218,6 +218,7 @@ void slot_actionSelectByType(); void slot_actionModeDraw(); void slot_actionModeSelect(); + void slot_actionModeRectangle(); void slot_actionModeCircle(); void slot_actionModeMagicWand(); void slot_actionSetDrawDepth();
--- a/ui/ldforge.ui Sun Jul 13 20:40:24 2014 +0300 +++ b/ui/ldforge.ui Tue Jul 15 02:54:23 2014 +0300 @@ -48,7 +48,7 @@ <x>0</x> <y>0</y> <width>233</width> - <height>418</height> + <height>426</height> </rect> </property> <attribute name="label"> @@ -75,8 +75,8 @@ <rect> <x>0</x> <y>0</y> - <width>98</width> - <height>95</height> + <width>99</width> + <height>99</height> </rect> </property> <attribute name="label"> @@ -112,7 +112,7 @@ <x>0</x> <y>0</y> <width>1010</width> - <height>30</height> + <height>28</height> </rect> </property> <widget class="QMenu" name="menuFile"> @@ -450,6 +450,7 @@ </attribute> <addaction name="actionModeSelect"/> <addaction name="actionModeDraw"/> + <addaction name="actionModeRectangle"/> <addaction name="actionModeCircle"/> <addaction name="actionModeMagicWand"/> </widget> @@ -1478,7 +1479,7 @@ <string>Circle Mode</string> </property> <property name="shortcut"> - <string>Ctrl+3</string> + <string>Ctrl+4</string> </property> </action> <action name="actionVisibilityHide"> @@ -1598,7 +1599,22 @@ <string>Magic wand</string> </property> <property name="shortcut"> - <string>Ctrl+4</string> + <string>Ctrl+5</string> + </property> + </action> + <action name="actionModeRectangle"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="icon"> + <iconset resource="../ldforge.qrc"> + <normaloff>:/icons/mode-rectangle.png</normaloff>:/icons/mode-rectangle.png</iconset> + </property> + <property name="text"> + <string>Rectangle Mode</string> + </property> + <property name="shortcut"> + <string>Ctrl+3</string> </property> </action> </widget>