init
This commit is contained in:
256
actions/lc_actiondrawcircle2pr.cpp
Normal file
256
actions/lc_actiondrawcircle2pr.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
This file is part of the LibreCAD project, a 2D CAD program
|
||||
|
||||
Copyright (C) 2014-2015 Dongxu Li (dongxuli2011 at gmail.com)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
#include<cmath>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "lc_actiondrawcircle2pr.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_point.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
|
||||
|
||||
struct LC_ActionDrawCircle2PR::Points
|
||||
{
|
||||
RS_Vector point1;
|
||||
RS_Vector point2;
|
||||
};
|
||||
|
||||
LC_ActionDrawCircle2PR::LC_ActionDrawCircle2PR(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_ActionDrawCircleCR(container, graphicView)
|
||||
,pPoints(new Points{})
|
||||
{
|
||||
actionType=RS2::ActionDrawCircle2PR;
|
||||
reset();
|
||||
}
|
||||
|
||||
LC_ActionDrawCircle2PR::~LC_ActionDrawCircle2PR() = default;
|
||||
|
||||
void LC_ActionDrawCircle2PR::reset() {
|
||||
deletePreview();
|
||||
*data = {};
|
||||
pPoints->point1 = {};
|
||||
pPoints->point2 = {};
|
||||
}
|
||||
|
||||
void LC_ActionDrawCircle2PR::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
void LC_ActionDrawCircle2PR::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
RS_Circle* circle = new RS_Circle(container,
|
||||
*data);
|
||||
circle->setLayerToActive();
|
||||
circle->setPenToActive();
|
||||
container->addEntity(circle);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(circle);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
RS_Vector rz = graphicView->getRelativeZero();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(rz);
|
||||
drawSnapper();
|
||||
|
||||
setStatus(SetPoint1);
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
bool LC_ActionDrawCircle2PR::preparePreview(const RS_Vector& mouse) {
|
||||
const RS_Vector vp=(pPoints->point1 + pPoints->point2)*0.5;
|
||||
double const angle=pPoints->point1.angleTo(pPoints->point2) + 0.5*M_PI;
|
||||
double const& r0=data->radius;
|
||||
double const r=sqrt(r0*r0-0.25*pPoints->point1.squaredTo(pPoints->point2));
|
||||
|
||||
const RS_Vector dvp=RS_Vector(angle)*r;
|
||||
const RS_Vector& center1= vp + dvp;
|
||||
const RS_Vector& center2= vp - dvp;
|
||||
|
||||
if( center1.squaredTo(center2) < RS_TOLERANCE ) {
|
||||
//no need to select center, as only one solution possible
|
||||
data->center=vp;
|
||||
return false;
|
||||
}
|
||||
|
||||
const double ds=mouse.squaredTo(center1) - mouse.squaredTo(center2);
|
||||
if (ds < 0. ){
|
||||
data->center=center1;
|
||||
return true;
|
||||
}
|
||||
if (ds > 0. ){
|
||||
data->center=center2;
|
||||
return true;
|
||||
}
|
||||
data->center.valid=false;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LC_ActionDrawCircle2PR::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
pPoints->point1 = mouse;
|
||||
break;
|
||||
|
||||
case SetPoint2:
|
||||
if(mouse.distanceTo(pPoints->point1) <= 2.*data->radius) pPoints->point2 = mouse;
|
||||
break;
|
||||
|
||||
case SelectCenter: {
|
||||
if(preparePreview(mouse)){
|
||||
bool existing=false;
|
||||
for(auto p: *preview){
|
||||
if(p->rtti() == RS2::EntityCircle){
|
||||
if( static_cast<RS_Circle*>(p)->getData() == *data)
|
||||
existing=true;
|
||||
}
|
||||
}
|
||||
if(!existing){
|
||||
deletePreview();
|
||||
preview->addEntity(new RS_Point(preview.get(), RS_PointData(data->center)));
|
||||
RS_Circle* circle = new RS_Circle(preview.get(), *data);
|
||||
preview->addEntity(circle);
|
||||
drawPreview();
|
||||
}
|
||||
}else{
|
||||
if(data->isValid()) trigger();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LC_ActionDrawCircle2PR::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LC_ActionDrawCircle2PR::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e) return;
|
||||
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
pPoints->point1 = mouse;
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
setStatus(SetPoint2);
|
||||
break;
|
||||
|
||||
case SetPoint2:
|
||||
if(mouse.distanceTo(pPoints->point1) <= 2.*data->radius){
|
||||
pPoints->point2 = mouse;
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
setStatus(SelectCenter);
|
||||
}else{
|
||||
RS_DIALOGFACTORY->commandMessage(tr("radius=%1 is too small for points selected\ndistance between points=%2 is larger than diameter=%3").
|
||||
arg(data->radius).arg(pPoints->point1.distanceTo(pPoints->point2)).arg(2.*data->radius));
|
||||
}
|
||||
break;
|
||||
|
||||
case SelectCenter: {
|
||||
bool showPreview=preparePreview(mouse);
|
||||
if(showPreview || data->isValid())
|
||||
trigger();
|
||||
else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Select from two possible circle centers"));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LC_ActionDrawCircle2PR::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList LC_ActionDrawCircle2PR::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LC_ActionDrawCircle2PR::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetPoint2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify second point"),
|
||||
tr("Back"));
|
||||
break;
|
||||
case SelectCenter:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Select circle center"),
|
||||
tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LC_ActionDrawCircle2PR::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
||||
72
actions/lc_actiondrawcircle2pr.h
Normal file
72
actions/lc_actiondrawcircle2pr.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw circle, given its radius and two points on circle
|
||||
|
||||
Copyright (C) 2014-2015 Dongxu Li (dongxuli2011 at gmail.com)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
#ifndef LC_ACTIONDRAWCIRCLE2PR_H
|
||||
#define LC_ACTIONDRAWCIRCLE2PR_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
#include "rs_actiondrawcirclecr.h"
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw a
|
||||
* circle with radius and two points on the circle
|
||||
*
|
||||
* @author Dongxu Li
|
||||
*/
|
||||
class LC_ActionDrawCircle2PR : public RS_ActionDrawCircleCR {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetPoint1, /**< Setting the 1st point. */
|
||||
SetPoint2, /**< Setting the 2nd point. */
|
||||
SelectCenter /**< select center out of two possibilities. */
|
||||
};
|
||||
|
||||
public:
|
||||
LC_ActionDrawCircle2PR(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~LC_ActionDrawCircle2PR() override;
|
||||
|
||||
void reset();
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
bool preparePreview(const RS_Vector& mouse);
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
protected:
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
};
|
||||
|
||||
#endif
|
||||
234
actions/lc_actiondrawlinepolygon3.cpp
Normal file
234
actions/lc_actiondrawlinepolygon3.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2017 A. Stebich (librecad@mail.lordofbikes.de)
|
||||
** Copyright (C) 2017 taoxumuye (tfy.hi@163.com)
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include "lc_actiondrawlinepolygon3.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_creation.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct LC_ActionDrawLinePolygonCenTan::Points {
|
||||
/** Center of polygon */
|
||||
RS_Vector center;
|
||||
/** Edge */
|
||||
RS_Vector corner;
|
||||
};
|
||||
|
||||
LC_ActionDrawLinePolygonCenTan::LC_ActionDrawLinePolygonCenTan(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw Polygons (Center,Corner)", container, graphicView)
|
||||
, pPoints(new Points{})
|
||||
,number(3)
|
||||
,lastStatus(SetCenter)
|
||||
{
|
||||
actionType=RS2::ActionDrawLinePolygonCenCor;
|
||||
}
|
||||
|
||||
LC_ActionDrawLinePolygonCenTan::~LC_ActionDrawLinePolygonCenTan() = default;
|
||||
|
||||
void LC_ActionDrawLinePolygonCenTan::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
deletePreview();
|
||||
|
||||
RS_Creation creation(container, graphicView);
|
||||
bool ok = creation.createPolygon3(pPoints->center, pPoints->corner, number);
|
||||
|
||||
if (!ok) {
|
||||
RS_DEBUG->print("RS_ActionDrawLinePolygon::trigger:"
|
||||
" No polygon added\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LC_ActionDrawLinePolygonCenTan::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawLinePolygon::mouseMoveEvent begin");
|
||||
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
break;
|
||||
|
||||
case SetTangent:
|
||||
if (pPoints->center.valid) {
|
||||
pPoints->corner = mouse;
|
||||
deletePreview();
|
||||
|
||||
RS_Creation creation(preview.get(), nullptr, false);
|
||||
creation.createPolygon3(pPoints->center, pPoints->corner, number);
|
||||
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LC_ActionDrawLinePolygonCenTan::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
void LC_ActionDrawLinePolygonCenTan::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e) return;
|
||||
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
pPoints->center = mouse;
|
||||
setStatus(SetTangent);
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
break;
|
||||
|
||||
case SetTangent:
|
||||
pPoints->corner = mouse;
|
||||
trigger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LC_ActionDrawLinePolygonCenTan::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify center"),
|
||||
"");
|
||||
break;
|
||||
|
||||
case SetTangent:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify a tangent"), "");
|
||||
break;
|
||||
|
||||
case SetNumber:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter number:"), "");
|
||||
break;
|
||||
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LC_ActionDrawLinePolygonCenTan::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
}
|
||||
|
||||
void LC_ActionDrawLinePolygonCenTan::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
void LC_ActionDrawLinePolygonCenTan::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
case SetTangent:
|
||||
if (checkCommand("number", c)) {
|
||||
deletePreview();
|
||||
lastStatus = (Status)getStatus();
|
||||
setStatus(SetNumber);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetNumber: {
|
||||
bool ok;
|
||||
int n = c.toInt(&ok);
|
||||
if (ok) {
|
||||
e->accept();
|
||||
if (n>0 && n<10000) {
|
||||
number = n;
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid number. "
|
||||
"Try 1..9999"));
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList LC_ActionDrawLinePolygonCenTan::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
case SetTangent:
|
||||
cmd += command("number");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LC_ActionDrawLinePolygonCenTan::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
85
actions/lc_actiondrawlinepolygon3.h
Normal file
85
actions/lc_actiondrawlinepolygon3.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2017 A. Stebich (librecad@mail.lordofbikes.de)
|
||||
** Copyright (C) 2017 taoxumuye (tfy.hi@163.com)
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef LC_ACTIONDRAWLINEPOLYGON3_H
|
||||
#define LC_ACTIONDRAWLINEPOLYGON3_H
|
||||
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw polygons.
|
||||
*
|
||||
*/
|
||||
class LC_ActionDrawLinePolygonCenTan : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
enum Status {
|
||||
SetCenter, /**< Setting center. */
|
||||
SetTangent, /**< Setting tangent. */
|
||||
SetNumber /**< Setting number in the command line. */
|
||||
};
|
||||
|
||||
public:
|
||||
LC_ActionDrawLinePolygonCenTan(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~LC_ActionDrawLinePolygonCenTan() override;
|
||||
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
void updateMouseButtonHints() override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseCursor() override;
|
||||
|
||||
int getNumber() const{
|
||||
return number;
|
||||
}
|
||||
|
||||
void setNumber(int n) {
|
||||
number = n;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
/** Number of edges. */
|
||||
int number;
|
||||
/** Last status before entering text. */
|
||||
Status lastStatus;
|
||||
};
|
||||
|
||||
#endif // LC_ACTIONDRAWLINEPOLYGON3_H
|
||||
400
actions/lc_actiondrawsplinepoints.cpp
Normal file
400
actions/lc_actiondrawsplinepoints.cpp
Normal file
@@ -0,0 +1,400 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2014 Dongxu Li (dongxuli2011@gmail.com)
|
||||
** Copyright (C) 2014 Pavel Krejcir (pavel@pamsoft.cz)
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "lc_actiondrawsplinepoints.h"
|
||||
|
||||
#include "lc_splinepoints.h"
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commands.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_point.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct LC_ActionDrawSplinePoints::Points {
|
||||
/**
|
||||
* Spline data defined so far.
|
||||
*/
|
||||
LC_SplinePointsData data;
|
||||
|
||||
/**
|
||||
* Spline used.
|
||||
*/
|
||||
std::unique_ptr<LC_SplinePoints> spline;
|
||||
|
||||
/**
|
||||
* Point history (for undo)
|
||||
*/
|
||||
std::vector<RS_Vector> undoBuffer;
|
||||
};
|
||||
|
||||
LC_ActionDrawSplinePoints::LC_ActionDrawSplinePoints(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView):
|
||||
RS_ActionDrawSpline( container, graphicView)
|
||||
, pPoints(new Points{})
|
||||
{
|
||||
actionType=RS2::ActionDrawSplinePoints;
|
||||
setName("DrawSplinePoints");
|
||||
}
|
||||
|
||||
LC_ActionDrawSplinePoints::~LC_ActionDrawSplinePoints() = default;
|
||||
|
||||
void LC_ActionDrawSplinePoints::reset() {
|
||||
pPoints->spline.reset();
|
||||
pPoints->undoBuffer.clear();
|
||||
}
|
||||
|
||||
void LC_ActionDrawSplinePoints::init(int status)
|
||||
{
|
||||
RS_PreviewActionInterface::init(status);
|
||||
reset();
|
||||
}
|
||||
|
||||
void LC_ActionDrawSplinePoints::trigger()
|
||||
{
|
||||
if(!pPoints->spline.get()) return;
|
||||
|
||||
pPoints->spline->setLayerToActive();
|
||||
pPoints->spline->setPenToActive();
|
||||
pPoints->spline->update();
|
||||
RS_Entity* s=pPoints->spline->clone();
|
||||
container->addEntity(s);
|
||||
|
||||
// upd. undo list:
|
||||
if (document)
|
||||
{
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(s);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
// upd view
|
||||
RS_Vector r = graphicView->getRelativeZero();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(r);
|
||||
RS_DEBUG->print("RS_ActionDrawSplinePoints::trigger(): spline added: %d",
|
||||
s->getId());
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
void LC_ActionDrawSplinePoints::mouseMoveEvent(QMouseEvent* e)
|
||||
{
|
||||
RS_DEBUG->print("RS_ActionDrawSplinePoints::mouseMoveEvent begin");
|
||||
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
|
||||
if(getStatus() == SetNextPoint)
|
||||
{
|
||||
LC_SplinePoints* sp = static_cast<LC_SplinePoints*>(pPoints->spline->clone());
|
||||
sp->addPoint(mouse);
|
||||
deletePreview();
|
||||
preview->addEntity(sp);
|
||||
|
||||
for(auto const& v: sp->getPoints())
|
||||
{
|
||||
preview->addEntity(new RS_Point(preview.get(), RS_PointData(v)));
|
||||
}
|
||||
drawPreview();
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawSplinePoints::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
void LC_ActionDrawSplinePoints::mouseReleaseEvent(QMouseEvent* e)
|
||||
{
|
||||
if(e->button() == Qt::LeftButton)
|
||||
{
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
}
|
||||
else if(e->button() == Qt::RightButton)
|
||||
{
|
||||
if(getStatus() == SetNextPoint && pPoints->spline.get())
|
||||
{
|
||||
trigger();
|
||||
}
|
||||
init(getStatus() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void LC_ActionDrawSplinePoints::coordinateEvent(RS_CoordinateEvent* e)
|
||||
{
|
||||
if(e == nullptr) return;
|
||||
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus())
|
||||
{
|
||||
case SetStartPoint:
|
||||
pPoints->undoBuffer.clear();
|
||||
if(!pPoints->spline.get())
|
||||
{
|
||||
pPoints->spline.reset(new LC_SplinePoints(container, pPoints->data));
|
||||
pPoints->spline->addPoint(mouse);
|
||||
preview->addEntity(new RS_Point(preview.get(), RS_PointData(mouse)));
|
||||
}
|
||||
setStatus(SetNextPoint);
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
updateMouseButtonHints();
|
||||
break;
|
||||
case SetNextPoint:
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
if(pPoints->spline.get())
|
||||
{
|
||||
pPoints->spline->addPoint(mouse);
|
||||
drawPreview();
|
||||
drawSnapper();
|
||||
}
|
||||
updateMouseButtonHints();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LC_ActionDrawSplinePoints::commandEvent(RS_CommandEvent* e)
|
||||
{
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
switch (getStatus())
|
||||
{
|
||||
case SetStartPoint:
|
||||
if(checkCommand("help", c))
|
||||
{
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case SetNextPoint:
|
||||
if (checkCommand("undo", c))
|
||||
{
|
||||
undo();
|
||||
updateMouseButtonHints();
|
||||
return;
|
||||
}
|
||||
if (checkCommand("redo", c))
|
||||
{
|
||||
redo();
|
||||
updateMouseButtonHints();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QStringList LC_ActionDrawSplinePoints::getAvailableCommands()
|
||||
{
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus())
|
||||
{
|
||||
case SetStartPoint:
|
||||
break;
|
||||
case SetNextPoint:
|
||||
if(pPoints->data.splinePoints.size() > 0)
|
||||
{
|
||||
cmd += command("undo");
|
||||
}
|
||||
if(pPoints->undoBuffer.size() > 0)
|
||||
{
|
||||
cmd += command("redo");
|
||||
}
|
||||
if(pPoints->data.splinePoints.size() > 2)
|
||||
{
|
||||
cmd += command("close");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void LC_ActionDrawSplinePoints::updateMouseButtonHints()
|
||||
{
|
||||
switch (getStatus())
|
||||
{
|
||||
case SetStartPoint:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first control point"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetNextPoint:
|
||||
{
|
||||
QString msg = "";
|
||||
|
||||
if(pPoints->data.splinePoints.size() > 2)
|
||||
{
|
||||
msg += RS_COMMANDS->command("close");
|
||||
msg += "/";
|
||||
}
|
||||
if(pPoints->data.splinePoints.size() > 0)
|
||||
{
|
||||
msg += RS_COMMANDS->command("undo");
|
||||
}
|
||||
if(pPoints->undoBuffer.size() > 0)
|
||||
{
|
||||
msg += RS_COMMANDS->command("redo");
|
||||
}
|
||||
|
||||
if(pPoints->data.splinePoints.size() > 0)
|
||||
{
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify next control point or [%1]").arg(msg),
|
||||
tr("Back"));
|
||||
}
|
||||
else
|
||||
{
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify next control point"),
|
||||
tr("Back"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LC_ActionDrawSplinePoints::showOptions()
|
||||
{
|
||||
RS_ActionInterface::showOptions();
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
}
|
||||
|
||||
void LC_ActionDrawSplinePoints::hideOptions()
|
||||
{
|
||||
RS_ActionInterface::hideOptions();
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
void LC_ActionDrawSplinePoints::updateMouseCursor()
|
||||
{
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
/*
|
||||
void RS_ActionDrawSplinePoints::close() {
|
||||
if (history.size()>2 && start.valid) {
|
||||
//data.endpoint = start;
|
||||
//trigger();
|
||||
if (spline) {
|
||||
RS_CoordinateEvent e(spline->getStartpoint());
|
||||
coordinateEvent(&e);
|
||||
}
|
||||
trigger();
|
||||
setStatus(SetStartpoint);
|
||||
graphicView->moveRelativeZero(start);
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(
|
||||
tr("Cannot close sequence of lines: "
|
||||
"Not enough entities defined yet."));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void LC_ActionDrawSplinePoints::undo()
|
||||
{
|
||||
if(!pPoints->spline.get())
|
||||
{
|
||||
RS_DIALOGFACTORY->commandMessage(
|
||||
tr("Cannot undo: Not enough entities defined yet."));
|
||||
return;
|
||||
}
|
||||
|
||||
auto& splinePts = pPoints->spline->getData().splinePoints;
|
||||
|
||||
size_t nPoints = splinePts.size();
|
||||
if(nPoints > 1)
|
||||
{
|
||||
RS_Vector v = splinePts.back();
|
||||
pPoints->undoBuffer.push_back(v);
|
||||
pPoints->spline->removeLastPoint();
|
||||
|
||||
if(!splinePts.size()) setStatus(SetStartPoint);
|
||||
else
|
||||
{
|
||||
v = splinePts.back();
|
||||
graphicView->moveRelativeZero(v);
|
||||
}
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
drawPreview();
|
||||
}
|
||||
else
|
||||
{
|
||||
RS_DIALOGFACTORY->commandMessage(
|
||||
tr("Cannot undo: Not enough entities defined yet."));
|
||||
}
|
||||
}
|
||||
|
||||
void LC_ActionDrawSplinePoints::redo()
|
||||
{
|
||||
int iBufLen = pPoints->undoBuffer.size();
|
||||
if(iBufLen > 1)
|
||||
{
|
||||
RS_Vector v = pPoints->undoBuffer.back();
|
||||
pPoints->spline->addPoint(v);
|
||||
pPoints->undoBuffer.pop_back();
|
||||
|
||||
setStatus(SetNextPoint);
|
||||
v = pPoints->data.splinePoints.back();
|
||||
graphicView->moveRelativeZero(v);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
}
|
||||
else
|
||||
{
|
||||
RS_DIALOGFACTORY->commandMessage(
|
||||
tr("Cannot undo: Nothing could be redone."));
|
||||
}
|
||||
}
|
||||
|
||||
void LC_ActionDrawSplinePoints::setClosed(bool c)
|
||||
{
|
||||
pPoints->data.closed = c;
|
||||
if(pPoints->spline.get())
|
||||
{
|
||||
pPoints->spline->setClosed(c);
|
||||
}
|
||||
}
|
||||
|
||||
bool LC_ActionDrawSplinePoints::isClosed()
|
||||
{
|
||||
return pPoints->data.closed;
|
||||
return false;
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
||||
85
actions/lc_actiondrawsplinepoints.h
Normal file
85
actions/lc_actiondrawsplinepoints.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2014 Dongxu Li (dongxuli2011@gmail.com)
|
||||
** Copyright (C) 2014 Pavel Krejcir (pavel@pamsoft.cz)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef LC_ACTIONDRAWSPLINEPOINTS_H
|
||||
#define LC_ACTIONDRAWSPLINEPOINTS_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
#include "rs_actiondrawspline.h"
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw splines through points.
|
||||
*
|
||||
* @author Pavel Krejcir
|
||||
*/
|
||||
class LC_ActionDrawSplinePoints : public RS_ActionDrawSpline
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status
|
||||
{
|
||||
SetStartPoint, /**< Setting the startpoint. */
|
||||
SetNextPoint /**< Setting the next point. */
|
||||
};
|
||||
|
||||
LC_ActionDrawSplinePoints(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~LC_ActionDrawSplinePoints() override;
|
||||
|
||||
void reset();
|
||||
|
||||
void init(int status = 0) override;
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void showOptions() override;
|
||||
void hideOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
void setClosed(bool c) override;
|
||||
bool isClosed() override;
|
||||
void undo() override;
|
||||
//using degree=2 only
|
||||
void setDegree(int /*deg*/) override{}
|
||||
|
||||
private:
|
||||
void redo();
|
||||
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
92
actions/lc_actionfileexportmakercam.cpp
Normal file
92
actions/lc_actionfileexportmakercam.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2014 Christian Luginbühl (dinkel@pimprecords.com)
|
||||
** Copyright (C) 2018 Andrey Yaromenok (ayaromenok@gmail.com)
|
||||
**
|
||||
**
|
||||
** 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 2 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, write to the Free Software Foundation, Inc.,
|
||||
** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include "lc_actionfileexportmakercam.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <QAction>
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphic.h"
|
||||
#include "lc_makercamsvg.h"
|
||||
#include "rs_settings.h"
|
||||
#include "lc_xmlwriterqxmlstreamwriter.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
LC_ActionFileExportMakerCam::LC_ActionFileExportMakerCam(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
: RS_ActionInterface("Export as CAM/plain SVG...", container, graphicView) {}
|
||||
|
||||
|
||||
void LC_ActionFileExportMakerCam::init(int status) {
|
||||
|
||||
RS_ActionInterface::init(status);
|
||||
trigger();
|
||||
}
|
||||
|
||||
void LC_ActionFileExportMakerCam::trigger() {
|
||||
|
||||
RS_DEBUG->print("LC_ActionFileExportMakerCam::trigger()");
|
||||
|
||||
if (graphic != NULL) {
|
||||
|
||||
bool accepted = RS_DIALOGFACTORY->requestOptionsMakerCamDialog();
|
||||
|
||||
if (accepted) {
|
||||
|
||||
QString filename = RS_DIALOGFACTORY->requestFileSaveAsDialog(tr("Export as"),
|
||||
"",
|
||||
"Scalable Vector Graphics (*.svg)");
|
||||
|
||||
if (!filename.isEmpty()) {
|
||||
|
||||
RS_SETTINGS->beginGroup("/ExportMakerCam");
|
||||
|
||||
std::unique_ptr<LC_MakerCamSVG> generator(new LC_MakerCamSVG(new LC_XMLWriterQXmlStreamWriter(),
|
||||
(bool)RS_SETTINGS->readNumEntry("/ExportInvisibleLayers"),
|
||||
(bool)RS_SETTINGS->readNumEntry("/ExportConstructionLayers"),
|
||||
(bool)RS_SETTINGS->readNumEntry("/WriteBlocksInline"),
|
||||
(bool)RS_SETTINGS->readNumEntry("/ConvertEllipsesToBeziers"),
|
||||
(bool)RS_SETTINGS->readNumEntry("/ExportImages"),
|
||||
(bool)RS_SETTINGS->readNumEntry("/BakeDashDotLines"),
|
||||
(double)RS_SETTINGS->readEntry("/DefaultElementWidth").toDouble(),
|
||||
(double)RS_SETTINGS->readEntry("/DefaultDashLinePatternLength").toDouble())
|
||||
);
|
||||
|
||||
RS_SETTINGS->endGroup();
|
||||
|
||||
if (generator->generate(graphic)) {
|
||||
|
||||
std::ofstream file;
|
||||
file.open(filename.toStdString());
|
||||
file << generator->resultAsString();
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finish(false);
|
||||
}
|
||||
39
actions/lc_actionfileexportmakercam.h
Normal file
39
actions/lc_actionfileexportmakercam.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2014 Christian Luginbühl (dinkel@pimprecords.com)
|
||||
**
|
||||
**
|
||||
** 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 2 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, write to the Free Software Foundation, Inc.,
|
||||
** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef LC_ACTIONFILEEXPORTMAKERCAM_H
|
||||
#define LC_ACTIONFILEEXPORTMAKERCAM_H
|
||||
|
||||
#include "rs_actioninterface.h"
|
||||
|
||||
class LC_ActionFileExportMakerCam : public RS_ActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
LC_ActionFileExportMakerCam(RS_EntityContainer& container, RS_GraphicView& graphicView);
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
101
actions/lc_actionlayerstoggleconstruction.cpp
Normal file
101
actions/lc_actionlayerstoggleconstruction.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Toggle whether a layer is a construction layer
|
||||
* Construction layer doesn't appear on printout
|
||||
* and have straight lines of infinite length
|
||||
|
||||
Copyright (C) 2015 A. Stebich (librecad@mail.lordofbikes.de)
|
||||
Copyright (C) 2011 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#include "lc_actionlayerstoggleconstruction.h"
|
||||
|
||||
#include <QAction>
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_graphic.h"
|
||||
#include "rs_layer.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
/**
|
||||
* whether a layer is a construction layer or not
|
||||
* construction layers doesn't appear on printout,
|
||||
* and have straight lines of infinite length
|
||||
*
|
||||
* @author Armin Stebich
|
||||
*/
|
||||
LC_ActionLayersToggleConstruction::LC_ActionLayersToggleConstruction(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView,
|
||||
RS_Layer* layer)
|
||||
: RS_ActionInterface("Toggle Construction Layer", container, graphicView)
|
||||
, a_layer(layer)
|
||||
{}
|
||||
|
||||
|
||||
void LC_ActionLayersToggleConstruction::trigger() {
|
||||
RS_DEBUG->print("toggle layer construction");
|
||||
if (graphic) {
|
||||
RS_LayerList* ll = graphic->getLayerList();
|
||||
unsigned cnt = 0;
|
||||
// toggle selected layers
|
||||
for (auto layer: *ll) {
|
||||
if (!layer) continue;
|
||||
if (!layer->isVisibleInLayerList()) continue;
|
||||
if (!layer->isSelectedInLayerList()) continue;
|
||||
graphic->toggleLayerConstruction(layer);
|
||||
deselectEntities(layer);
|
||||
cnt++;
|
||||
}
|
||||
// if there wasn't selected layers, toggle active layer
|
||||
if (!cnt) {
|
||||
graphic->toggleLayerConstruction(a_layer);
|
||||
deselectEntities(a_layer);
|
||||
}
|
||||
}
|
||||
finish(false);
|
||||
}
|
||||
|
||||
|
||||
void LC_ActionLayersToggleConstruction::init(int status) {
|
||||
RS_ActionInterface::init(status);
|
||||
trigger();
|
||||
}
|
||||
|
||||
|
||||
void LC_ActionLayersToggleConstruction::deselectEntities(RS_Layer* layer)
|
||||
{
|
||||
if (!layer) return;
|
||||
|
||||
for(auto e: *container){
|
||||
if (e && e->isVisible() && e->getLayer() == layer) {
|
||||
|
||||
if (graphicView) {
|
||||
graphicView->deleteEntity(e);
|
||||
}
|
||||
|
||||
if (graphicView) {
|
||||
graphicView->drawEntity(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// EOF
|
||||
58
actions/lc_actionlayerstoggleconstruction.h
Normal file
58
actions/lc_actionlayerstoggleconstruction.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Toggle whether a layer is a construction layer
|
||||
* Construction layer doesn't appear on printout
|
||||
* and have straight lines of infinite length
|
||||
|
||||
Copyright (C) 2015 A. Stebich (librecad@mail.lordofbikes.de)
|
||||
Copyright (C) 2011 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#ifndef LC_ACTIONLAYERSTOGGLECONSTRUCTION_H
|
||||
#define LC_ACTIONLAYERSTOGGLECONSTRUCTION_H
|
||||
|
||||
#include "rs_actioninterface.h"
|
||||
|
||||
class RS_Layer;
|
||||
|
||||
/**
|
||||
* whether a layer is a construction layer or not
|
||||
* construction layers doesn't appear on printout,
|
||||
* and have straight lines of infinite length
|
||||
*
|
||||
* @author Armin Stebich
|
||||
*/
|
||||
class LC_ActionLayersToggleConstruction : public RS_ActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
LC_ActionLayersToggleConstruction(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView,
|
||||
RS_Layer* layer);
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
|
||||
protected:
|
||||
RS_Layer* a_layer;
|
||||
|
||||
private:
|
||||
void deselectEntities(RS_Layer* layer);
|
||||
};
|
||||
|
||||
#endif
|
||||
70
actions/rs_actionblocksadd.cpp
Normal file
70
actions/rs_actionblocksadd.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include "rs_actionblocksadd.h"
|
||||
|
||||
#include <QAction>
|
||||
#include "rs_graphic.h"
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
|
||||
RS_ActionBlocksAdd::RS_ActionBlocksAdd(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_ActionInterface("Add Block", container, graphicView) {
|
||||
actionType = RS2::ActionBlocksAdd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksAdd::trigger() {
|
||||
RS_DEBUG->print("adding block");
|
||||
if (graphic) {
|
||||
RS_BlockList* blockList = graphic->getBlockList();
|
||||
if (blockList) {
|
||||
RS_BlockData d =
|
||||
RS_DIALOGFACTORY->requestNewBlockDialog(blockList);
|
||||
if (d.isValid()) {
|
||||
// Block cannot contain blocks.
|
||||
if (container->rtti() == RS2::EntityBlock) {
|
||||
graphic->addBlock(new RS_Block(container->getParent(), d));
|
||||
} else {
|
||||
graphic->addBlock(new RS_Block(container, d));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finish(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksAdd::init(int status) {
|
||||
RS_ActionInterface::init(status);
|
||||
trigger();
|
||||
}
|
||||
|
||||
// EOF
|
||||
48
actions/rs_actionblocksadd.h
Normal file
48
actions/rs_actionblocksadd.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONBLOCKSADD_H
|
||||
#define RS_ACTIONBLOCKSADD_H
|
||||
|
||||
#include "rs_actioninterface.h"
|
||||
|
||||
/**
|
||||
* This action class can handle user events to edit blocks.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionBlocksAdd : public RS_ActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RS_ActionBlocksAdd(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
92
actions/rs_actionblocksattributes.cpp
Normal file
92
actions/rs_actionblocksattributes.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include "rs_actionblocksattributes.h"
|
||||
|
||||
#include <QAction>
|
||||
#include "qc_applicationwindow.h"
|
||||
#include "qc_mdiwindow.h"
|
||||
#include "rs_graphic.h"
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
|
||||
RS_ActionBlocksAttributes::RS_ActionBlocksAttributes(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_ActionInterface("Edit Block Attributes", container, graphicView) {}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksAttributes::trigger() {
|
||||
RS_DEBUG->print("editing block attributes");
|
||||
|
||||
if (graphic) {
|
||||
RS_Block* block = graphic->getActiveBlock();
|
||||
RS_BlockList* blockList = graphic->getBlockList();
|
||||
if (blockList && block) {
|
||||
QString oldName = block->getName();
|
||||
|
||||
RS_BlockData d;
|
||||
d = RS_DIALOGFACTORY->requestBlockAttributesDialog(
|
||||
blockList);
|
||||
|
||||
if (d.isValid()) {
|
||||
|
||||
QString newName = d.name;
|
||||
|
||||
// update window title of opened block
|
||||
QC_ApplicationWindow* appWindow = QC_ApplicationWindow::getAppWindow();
|
||||
QC_MDIWindow* blockWindow = appWindow->getWindowWithDoc(block);
|
||||
if (blockWindow) {
|
||||
QString title = blockWindow->windowTitle();
|
||||
title = title.replace(
|
||||
"'" + oldName + "'",
|
||||
"'" + newName + "'");
|
||||
blockWindow->setWindowTitle(title);
|
||||
}
|
||||
|
||||
blockList->rename(block, newName);
|
||||
|
||||
// update the name of all inserts:
|
||||
graphic->renameInserts(oldName, newName);
|
||||
|
||||
graphic->addBlockNotification();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
finish(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksAttributes::init(int status) {
|
||||
RS_ActionInterface::init(status);
|
||||
trigger();
|
||||
}
|
||||
|
||||
// EOF
|
||||
48
actions/rs_actionblocksattributes.h
Normal file
48
actions/rs_actionblocksattributes.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONBLOCKSATTRIBUTES_H
|
||||
#define RS_ACTIONBLOCKSATTRIBUTES_H
|
||||
|
||||
#include "rs_actioninterface.h"
|
||||
|
||||
/**
|
||||
* This action class can handle user events to edit block attributes.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionBlocksAttributes : public RS_ActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RS_ActionBlocksAttributes(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
163
actions/rs_actionblockscreate.cpp
Normal file
163
actions/rs_actionblockscreate.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actionblockscreate.h"
|
||||
|
||||
#include "rs_creation.h"
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_graphic.h"
|
||||
#include "rs_insert.h"
|
||||
#include "rs_modification.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
RS_ActionBlocksCreate::RS_ActionBlocksCreate(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Blocks Create",
|
||||
container, graphicView)
|
||||
,referencePoint(new RS_Vector{})
|
||||
{
|
||||
actionType=RS2::ActionBlocksCreate;
|
||||
}
|
||||
|
||||
RS_ActionBlocksCreate::~RS_ActionBlocksCreate() = default;
|
||||
|
||||
|
||||
void RS_ActionBlocksCreate::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksCreate::trigger() {
|
||||
if (graphic) {
|
||||
RS_BlockList* blockList = graphic->getBlockList();
|
||||
if (blockList) {
|
||||
RS_BlockData d =
|
||||
RS_DIALOGFACTORY->requestNewBlockDialog(blockList);
|
||||
|
||||
if (!d.name.isEmpty()) {
|
||||
RS_Creation creation(container, graphicView);
|
||||
creation.createBlock(&d, *referencePoint, true);
|
||||
|
||||
RS_InsertData id(
|
||||
d.name,
|
||||
*referencePoint,
|
||||
RS_Vector(1.0,1.0),
|
||||
0.0,
|
||||
1, 1, RS_Vector(0.0,0.0)
|
||||
);
|
||||
creation.createInsert(&id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
|
||||
setStatus(getStatus()+1); // clear mouse button hints
|
||||
updateMouseButtonHints();
|
||||
graphicView->killSelectActions();
|
||||
finish(false);
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionBlocksCreate::mouseMoveEvent(QMouseEvent* e) {
|
||||
snapPoint(e);
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetReferencePoint:
|
||||
//data.insertionPoint = snapPoint(e);
|
||||
|
||||
/*if (block) {
|
||||
deletePreview();
|
||||
//preview->addAllFrom(*block);
|
||||
//preview->move(data.insertionPoint);
|
||||
RS_Creation creation(preview, nullptr, false);
|
||||
creation.createInsert(data);
|
||||
drawPreview();
|
||||
}*/
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksCreate::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksCreate::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetReferencePoint:
|
||||
*referencePoint = e->getCoordinate();
|
||||
trigger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksCreate::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetReferencePoint:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify reference point"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionBlocksCreate::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
75
actions/rs_actionblockscreate.h
Normal file
75
actions/rs_actionblockscreate.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONBLOCKSCREATE_H
|
||||
#define RS_ACTIONBLOCKSCREATE_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
/**
|
||||
* This action class can handle user events for creating blocks from
|
||||
* existing entities.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionBlocksCreate : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetReferencePoint, /**< Setting the reference point. */
|
||||
ShowDialog /**< Showing dialog for name. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionBlocksCreate(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionBlocksCreate() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
//void commandEvent(RS_CommandEvent* e) override;
|
||||
//QStringList getAvailableCommands() override;
|
||||
|
||||
//void showOptions() override;
|
||||
//void hideOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<RS_Vector> referencePoint;
|
||||
};
|
||||
|
||||
#endif
|
||||
69
actions/rs_actionblocksedit.cpp
Normal file
69
actions/rs_actionblocksedit.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include "rs_actionblocksedit.h"
|
||||
|
||||
#include <QAction>
|
||||
#include "rs_graphic.h"
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
|
||||
|
||||
RS_ActionBlocksEdit::RS_ActionBlocksEdit(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_ActionInterface("Edit Block", container, graphicView) {}
|
||||
|
||||
void RS_ActionBlocksEdit::trigger() {
|
||||
|
||||
RS_DEBUG->print(RS_Debug::D_DEBUGGING, "RS_ActionBlocksEdit::trigger(): edit block");
|
||||
|
||||
if (!graphic) {
|
||||
RS_DEBUG->print(RS_Debug::D_ERROR, "RS_ActionBlocksEdit::trigger(): nullptr graphic");
|
||||
return;
|
||||
}
|
||||
|
||||
RS_BlockList *bl = graphic->getBlockList();
|
||||
|
||||
if (!bl) {
|
||||
RS_DEBUG->print(RS_Debug::D_ERROR, "RS_ActionBlocksEdit::trigger(): nullptr block list in graphic");
|
||||
return;
|
||||
}
|
||||
|
||||
// std::cout<<__func__<<" : "<<__LINE__<<" : graphic->getBlockList()->count()="<<graphic->getBlockList()->count()<<std::endl;
|
||||
RS_DIALOGFACTORY->requestEditBlockWindow(bl);
|
||||
|
||||
finish(false);
|
||||
RS_DEBUG->print(RS_Debug::D_DEBUGGING, "RS_ActionBlocksEdit::trigger(): OK");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksEdit::init(int status) {
|
||||
RS_ActionInterface::init(status);
|
||||
trigger();
|
||||
}
|
||||
|
||||
48
actions/rs_actionblocksedit.h
Normal file
48
actions/rs_actionblocksedit.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONBLOCKSEDIT_H
|
||||
#define RS_ACTIONBLOCKSEDIT_H
|
||||
|
||||
#include "rs_actioninterface.h"
|
||||
|
||||
/**
|
||||
* This action class can handle user events to edit blocks.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionBlocksEdit : public RS_ActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RS_ActionBlocksEdit(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
57
actions/rs_actionblocksexplode.cpp
Normal file
57
actions/rs_actionblocksexplode.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include "rs_actionblocksexplode.h"
|
||||
|
||||
#include <QAction>
|
||||
#include "rs_modification.h"
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
RS_ActionBlocksExplode::RS_ActionBlocksExplode(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Blocks Explode",
|
||||
container, graphicView) {
|
||||
actionType=RS2::ActionBlocksExplode;
|
||||
}
|
||||
|
||||
void RS_ActionBlocksExplode::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
trigger();
|
||||
finish(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksExplode::trigger() {
|
||||
RS_Modification m(*container, graphicView);
|
||||
m.explode();
|
||||
}
|
||||
|
||||
|
||||
// EOF
|
||||
49
actions/rs_actionblocksexplode.h
Normal file
49
actions/rs_actionblocksexplode.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONBLOCKSEXPLODE_H
|
||||
#define RS_ACTIONBLOCKSEXPLODE_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
/**
|
||||
* This action class can handle user events for exploding blocks and
|
||||
* other entity containers into single entities.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionBlocksExplode : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RS_ActionBlocksExplode(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
63
actions/rs_actionblocksfreezeall.cpp
Normal file
63
actions/rs_actionblocksfreezeall.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include "rs_actionblocksfreezeall.h"
|
||||
|
||||
#include <QAction>
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_graphic.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
|
||||
|
||||
RS_ActionBlocksFreezeAll::RS_ActionBlocksFreezeAll(bool freeze,
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_ActionInterface("Freeze all Blocks",
|
||||
container, graphicView) {
|
||||
|
||||
this->freeze = freeze;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionBlocksFreezeAll::trigger() {
|
||||
RS_DEBUG->print("RS_ActionBlocksFreezeAll::trigger");
|
||||
if (graphic) {
|
||||
graphic->freezeAllBlocks(freeze);
|
||||
}
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
|
||||
finish(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksFreezeAll::init(int status) {
|
||||
RS_ActionInterface::init(status);
|
||||
trigger();
|
||||
}
|
||||
|
||||
// EOF
|
||||
52
actions/rs_actionblocksfreezeall.h
Normal file
52
actions/rs_actionblocksfreezeall.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONBLOCKSFREEZEALL_H
|
||||
#define RS_ACTIONBLOCKSFREEZEALL_H
|
||||
|
||||
#include "rs_actioninterface.h"
|
||||
|
||||
|
||||
/**
|
||||
* This action class can handle user events to edit layers.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionBlocksFreezeAll : public RS_ActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RS_ActionBlocksFreezeAll(bool freeze,
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
|
||||
private:
|
||||
bool freeze;
|
||||
};
|
||||
|
||||
#endif
|
||||
420
actions/rs_actionblocksinsert.cpp
Normal file
420
actions/rs_actionblocksinsert.cpp
Normal file
@@ -0,0 +1,420 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actionblocksinsert.h"
|
||||
#include "rs_insert.h"
|
||||
#include "rs_block.h"
|
||||
|
||||
#include "rs_graphic.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_creation.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
RS_ActionBlocksInsert::RS_ActionBlocksInsert(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Blocks Insert",
|
||||
container, graphicView)
|
||||
,block(nullptr)
|
||||
,lastStatus(SetUndefined)
|
||||
{
|
||||
actionType = RS2::ActionBlocksInsert;
|
||||
reset(); // init data Member
|
||||
}
|
||||
|
||||
|
||||
|
||||
RS_ActionBlocksInsert::~RS_ActionBlocksInsert() = default;
|
||||
|
||||
|
||||
void RS_ActionBlocksInsert::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
reset();
|
||||
|
||||
if (graphic) {
|
||||
block = graphic->getActiveBlock();
|
||||
if (block) {
|
||||
QString blockName = block->getName();
|
||||
data->name = blockName;
|
||||
if (document->rtti() == RS2::EntityBlock) {
|
||||
QString parentBlockName = ((RS_Block*)(document))->getName();
|
||||
if (parentBlockName == blockName) {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Block cannot contain an insert of itself."));
|
||||
finish(false);
|
||||
} else {
|
||||
QStringList bnChain = block->findNestedInsert(parentBlockName);
|
||||
if (!bnChain.empty()) {
|
||||
RS_DIALOGFACTORY->commandMessage(blockName
|
||||
+ tr(" has nested insert of current block in:\n")
|
||||
+ bnChain.join("->")
|
||||
+ tr("\nThis block cannot be inserted."));
|
||||
finish(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
finish(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksInsert::reset() {
|
||||
data.reset(new RS_InsertData("",
|
||||
RS_Vector(0.0,0.0),
|
||||
RS_Vector(1.0,1.0),
|
||||
0.0,
|
||||
1, 1,
|
||||
RS_Vector(1.0,1.0),
|
||||
NULL,
|
||||
RS2::Update));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksInsert::trigger() {
|
||||
deletePreview();
|
||||
|
||||
//RS_Modification m(*container, graphicView);
|
||||
//m.paste(img->insertionPoint);
|
||||
//std::cout << *RS_Clipboard::instance();
|
||||
|
||||
if (block) {
|
||||
RS_Creation creation(container, graphicView);
|
||||
data->updateMode = RS2::Update;
|
||||
creation.createInsert(data.get());
|
||||
}
|
||||
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
|
||||
//finish();
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionBlocksInsert::mouseMoveEvent(QMouseEvent* e) {
|
||||
switch (getStatus()) {
|
||||
case SetTargetPoint:
|
||||
data->insertionPoint = snapPoint(e);
|
||||
|
||||
if (block) {
|
||||
deletePreview();
|
||||
//preview->addAllFrom(*block);
|
||||
//preview->move(data->insertionPoint);
|
||||
RS_Creation creation(preview.get(), nullptr, false);
|
||||
// Create insert as preview only
|
||||
data->updateMode = RS2::PreviewUpdate;
|
||||
creation.createInsert(data.get());
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksInsert::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksInsert::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (e==NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
data->insertionPoint = e->getCoordinate();
|
||||
trigger();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksInsert::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetTargetPoint:
|
||||
if (checkCommand("angle", c)) {
|
||||
deletePreview();
|
||||
lastStatus = (Status)getStatus();
|
||||
setStatus(SetAngle);
|
||||
} else if (checkCommand("factor", c)) {
|
||||
deletePreview();
|
||||
lastStatus = (Status)getStatus();
|
||||
setStatus(SetFactor);
|
||||
} else if (checkCommand("columns", c)) {
|
||||
deletePreview();
|
||||
lastStatus = (Status)getStatus();
|
||||
setStatus(SetColumns);
|
||||
} else if (checkCommand("rows", c)) {
|
||||
deletePreview();
|
||||
lastStatus = (Status)getStatus();
|
||||
setStatus(SetRows);
|
||||
} else if (checkCommand("columnspacing", c)) {
|
||||
deletePreview();
|
||||
lastStatus = (Status)getStatus();
|
||||
setStatus(SetColumnSpacing);
|
||||
} else if (checkCommand("rowspacing", c)) {
|
||||
deletePreview();
|
||||
lastStatus = (Status)getStatus();
|
||||
setStatus(SetRowSpacing);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
data->angle = RS_Math::deg2rad(a);
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetFactor: {
|
||||
bool ok;
|
||||
double f = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
setFactor(f);
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetColumns: {
|
||||
bool ok;
|
||||
int cols = (int)RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
data->cols = cols;
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetRows: {
|
||||
bool ok;
|
||||
int rows = (int)RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
data->rows = rows;
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetColumnSpacing: {
|
||||
bool ok;
|
||||
double cs = (int)RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
data->spacing.x = cs;
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetRowSpacing: {
|
||||
bool ok;
|
||||
int rs = (int)RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
data->spacing.y = rs;
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double RS_ActionBlocksInsert::getAngle() const {
|
||||
return data->angle;
|
||||
}
|
||||
|
||||
void RS_ActionBlocksInsert::setAngle(double a) {
|
||||
data->angle = a;
|
||||
}
|
||||
|
||||
double RS_ActionBlocksInsert::getFactor() const {
|
||||
return data->scaleFactor.x;
|
||||
}
|
||||
|
||||
void RS_ActionBlocksInsert::setFactor(double f) {
|
||||
data->scaleFactor = RS_Vector(f, f);
|
||||
}
|
||||
|
||||
int RS_ActionBlocksInsert::getColumns() const {
|
||||
return data->cols;
|
||||
}
|
||||
|
||||
void RS_ActionBlocksInsert::setColumns(int c) {
|
||||
data->cols = c;
|
||||
}
|
||||
|
||||
int RS_ActionBlocksInsert::getRows() const {
|
||||
return data->rows;
|
||||
}
|
||||
|
||||
void RS_ActionBlocksInsert::setRows(int r) {
|
||||
data->rows = r;
|
||||
}
|
||||
|
||||
double RS_ActionBlocksInsert::getColumnSpacing() const {
|
||||
return data->spacing.x;
|
||||
}
|
||||
|
||||
void RS_ActionBlocksInsert::setColumnSpacing(double cs) {
|
||||
data->spacing.x = cs;
|
||||
}
|
||||
|
||||
double RS_ActionBlocksInsert::getRowSpacing() const {
|
||||
return data->spacing.y;
|
||||
}
|
||||
|
||||
void RS_ActionBlocksInsert::setRowSpacing(double rs) {
|
||||
data->spacing.y = rs;
|
||||
}
|
||||
|
||||
QStringList RS_ActionBlocksInsert::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetTargetPoint:
|
||||
cmd += command("angle");
|
||||
cmd += command("factor");
|
||||
;
|
||||
cmd += command("columns");
|
||||
cmd += command("rows");
|
||||
cmd += command("columnspacing");
|
||||
cmd += command("rowspacing");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionBlocksInsert::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksInsert::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionBlocksInsert::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetTargetPoint:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify reference point"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetAngle:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter angle:"),
|
||||
"");
|
||||
break;
|
||||
case SetFactor:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter factor:"),
|
||||
"");
|
||||
break;
|
||||
case SetColumns:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter columns:"),
|
||||
"");
|
||||
break;
|
||||
case SetRows:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter rows:"),
|
||||
"");
|
||||
break;
|
||||
case SetColumnSpacing:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter column spacing:"),
|
||||
"");
|
||||
break;
|
||||
case SetRowSpacing:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter row spacing:"),
|
||||
"");
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksInsert::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
115
actions/rs_actionblocksinsert.h
Normal file
115
actions/rs_actionblocksinsert.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONBLOCKSINSERT_H
|
||||
#define RS_ACTIONBLOCKSINSERT_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
#include "rs_insert.h"
|
||||
|
||||
class RS_Block;
|
||||
struct RS_InsertData;
|
||||
|
||||
/**
|
||||
* This action class can handle user events for inserting blocks into the
|
||||
* current drawing.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionBlocksInsert : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetUndefined = -1, /**< Setting undefined for initialisation. */
|
||||
SetTargetPoint = 0,/**< Setting the reference point. */
|
||||
SetAngle, /**< Setting angle in the command line. */
|
||||
SetFactor, /**< Setting factor in the command line. */
|
||||
SetColumns, /**< Setting columns in the command line. */
|
||||
SetRows, /**< Setting rows in the command line. */
|
||||
SetColumnSpacing, /**< Setting column spacing in the command line. */
|
||||
SetRowSpacing /**< Setting row spacing in the command line. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionBlocksInsert(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionBlocksInsert() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void reset();
|
||||
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void showOptions() override;
|
||||
void hideOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
double getAngle() const;
|
||||
|
||||
void setAngle(double a);
|
||||
|
||||
double getFactor() const;
|
||||
|
||||
void setFactor(double f);
|
||||
|
||||
int getColumns() const;
|
||||
|
||||
void setColumns(int c);
|
||||
|
||||
int getRows() const;
|
||||
|
||||
void setRows(int r);
|
||||
|
||||
double getColumnSpacing() const;
|
||||
|
||||
void setColumnSpacing(double cs);
|
||||
|
||||
double getRowSpacing() const;
|
||||
|
||||
void setRowSpacing(double rs);
|
||||
|
||||
protected:
|
||||
RS_Block* block;
|
||||
std::unique_ptr<RS_InsertData> data;
|
||||
|
||||
/** Last status before entering option. */
|
||||
Status lastStatus;
|
||||
};
|
||||
|
||||
#endif
|
||||
122
actions/rs_actionblocksremove.cpp
Normal file
122
actions/rs_actionblocksremove.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include "rs_actionblocksremove.h"
|
||||
|
||||
#include <QAction>
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_graphic.h"
|
||||
#include "rs_insert.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
|
||||
RS_ActionBlocksRemove::RS_ActionBlocksRemove(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_ActionInterface("Remove Block", container, graphicView) {}
|
||||
|
||||
void RS_ActionBlocksRemove::trigger() {
|
||||
RS_DEBUG->print("RS_ActionBlocksRemove::trigger");
|
||||
|
||||
if (!(graphic && document)) {
|
||||
finish(false);
|
||||
return;
|
||||
}
|
||||
|
||||
RS_BlockList* bl = graphic->getBlockList();
|
||||
QList<RS_Block*> blocks =
|
||||
RS_DIALOGFACTORY->requestSelectedBlocksRemovalDialog(bl);
|
||||
|
||||
if (blocks.isEmpty()) {
|
||||
finish(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// list of containers that might refer to the block via inserts:
|
||||
std::vector<RS_EntityContainer*> containerList;
|
||||
containerList.push_back(graphic);
|
||||
for (int bi = 0; bi < bl->count(); bi++) {
|
||||
containerList.push_back(bl->at(bi));
|
||||
}
|
||||
|
||||
document->startUndoCycle();
|
||||
|
||||
for (auto block: blocks) {
|
||||
if (nullptr == block) {
|
||||
continue;
|
||||
}
|
||||
for(auto cont: containerList){
|
||||
// remove all inserts from the graphic:
|
||||
bool done;
|
||||
do {
|
||||
done = true;
|
||||
for(auto e: *cont){
|
||||
|
||||
if (e->rtti()==RS2::EntityInsert) {
|
||||
RS_Insert* ins = (RS_Insert*)e;
|
||||
if (ins->getName()==block->getName() && !ins->isUndone()) {
|
||||
document->addUndoable(ins);
|
||||
ins->setUndoState(true);
|
||||
done = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!done);
|
||||
}
|
||||
|
||||
// clear selection and active state
|
||||
block->selectedInBlockList(false);
|
||||
if (block == bl->getActive()) {
|
||||
bl->activate(nullptr);
|
||||
}
|
||||
|
||||
// close all windows that are editing this block:
|
||||
RS_DIALOGFACTORY->closeEditBlockWindow(block);
|
||||
|
||||
// Now remove block from the block list, but do not delete:
|
||||
block->setUndoState(true);
|
||||
document->addUndoable(block);
|
||||
}
|
||||
document->endUndoCycle();
|
||||
|
||||
graphic->addBlockNotification();
|
||||
graphic->updateInserts();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
bl->activate(nullptr);
|
||||
|
||||
finish(false);
|
||||
RS_DIALOGFACTORY->updateSelectionWidget(container->countSelected(),container->totalSelectedLength());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksRemove::init(int status) {
|
||||
RS_ActionInterface::init(status);
|
||||
trigger();
|
||||
}
|
||||
|
||||
// EOF
|
||||
48
actions/rs_actionblocksremove.h
Normal file
48
actions/rs_actionblocksremove.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONBLOCKSREMOVE_H
|
||||
#define RS_ACTIONBLOCKSREMOVE_H
|
||||
|
||||
#include "rs_actioninterface.h"
|
||||
|
||||
|
||||
/**
|
||||
* This action class can handle user events to remove blocks.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionBlocksRemove : public RS_ActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RS_ActionBlocksRemove(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
109
actions/rs_actionblockssave.cpp
Normal file
109
actions/rs_actionblockssave.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
This file is part of the LibreCAD project, a 2D CAD program
|
||||
|
||||
** Copyright (C) 2012 Dongxu Li (dongxuli2011@gmail.com)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
#include "rs_actionblockssave.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include "qg_blockwidget.h"
|
||||
#include "qg_filedialog.h"
|
||||
#include "qc_applicationwindow.h"
|
||||
#include "rs_graphic.h"
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_insert.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "qc_mdiwindow.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
|
||||
|
||||
RS_ActionBlocksSave::RS_ActionBlocksSave(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_ActionInterface("Edit Block", container, graphicView) {}
|
||||
|
||||
/*recursive add blocks in graphic*/
|
||||
void RS_ActionBlocksSave::addBlock(RS_Insert* in, RS_Graphic* g) {
|
||||
|
||||
for(auto e: *in){
|
||||
|
||||
if (e->rtti() == RS2::EntityInsert) {
|
||||
RS_Insert * in=static_cast<RS_Insert *>(e);
|
||||
addBlock(in,g);
|
||||
g->addBlock(in->getBlockForInsert());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionBlocksSave::trigger() {
|
||||
RS_DEBUG->print("save block to file");
|
||||
QC_ApplicationWindow* appWindow = QC_ApplicationWindow::getAppWindow();
|
||||
if(!appWindow) {
|
||||
finish(false);
|
||||
return;
|
||||
}
|
||||
RS_BlockList* bList = appWindow->getBlockWidget() -> getBlockList();
|
||||
if (bList) {
|
||||
auto b=bList->getActive();
|
||||
if(b) {
|
||||
RS_Graphic g(nullptr);
|
||||
g.setOwner(false);
|
||||
g.getBlockList()->setOwner(false);
|
||||
|
||||
g.clearLayers();
|
||||
// g.addLayer(b->getLayer());
|
||||
for (RS_Entity* e=b->firstEntity(RS2::ResolveNone);
|
||||
e;
|
||||
e = b->nextEntity(RS2::ResolveNone)) {
|
||||
g.addEntity(e);
|
||||
if (e->rtti() == RS2::EntityInsert) {
|
||||
RS_Insert *in = static_cast<RS_Insert *>(e);
|
||||
g.addBlock(in->getBlockForInsert());
|
||||
addBlock(in,&g);
|
||||
}
|
||||
// std::cout<<__FILE__<<" : "<<__func__<<" : line: "<<__LINE__<<" : "<<e->rtti()<<std::endl;
|
||||
// g.addLayer(e->getLayer());
|
||||
// std::cout<<__FILE__<<" : "<<__func__<<" : line: "<<__LINE__<<" : "<<e->rtti()<<std::endl;
|
||||
}
|
||||
// std::cout<<__FILE__<<" : "<<__func__<<" : line: "<<__LINE__<<std::endl;
|
||||
// std::cout<<"add layer name="<<qPrintable(b->getLayer()->getName())<<std::endl;
|
||||
|
||||
RS2::FormatType t = RS2::FormatDXFRW;
|
||||
|
||||
QG_FileDialog dlg(appWindow->getMDIWindow(),0, QG_FileDialog::BlockFile);
|
||||
QString const& fn = dlg.getSaveFile(&t);
|
||||
QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
|
||||
// g.setModified(true);
|
||||
g.saveAs(fn, t);
|
||||
QApplication::restoreOverrideCursor();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("No block activated to save"));
|
||||
} else {
|
||||
RS_DEBUG->print(RS_Debug::D_WARNING,
|
||||
"RS_ActionBlocksSave::trigger(): blockList is NULL");
|
||||
}
|
||||
finish(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksSave::init(int status) {
|
||||
RS_ActionInterface::init(status);
|
||||
trigger();
|
||||
}
|
||||
|
||||
46
actions/rs_actionblockssave.h
Normal file
46
actions/rs_actionblockssave.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/****************************************************************************
|
||||
This file is part of the LibreCAD project, a 2D CAD program
|
||||
|
||||
** Copyright (C) 2012 Dongxu Li (dongxuli2011@gmail.com)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONBLOCKSSAVE_H
|
||||
#define RS_ACTIONBLOCKSSAVE_H
|
||||
|
||||
#include "rs_actioninterface.h"
|
||||
|
||||
class RS_Insert;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to save the active block to a file.
|
||||
*
|
||||
* @author Dongxu Li
|
||||
*/
|
||||
class RS_ActionBlocksSave : public RS_ActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RS_ActionBlocksSave(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
|
||||
private:
|
||||
void addBlock(RS_Insert* in, RS_Graphic* g);
|
||||
};
|
||||
|
||||
#endif
|
||||
74
actions/rs_actionblockstoggleview.cpp
Normal file
74
actions/rs_actionblockstoggleview.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include "rs_actionblockstoggleview.h"
|
||||
|
||||
#include <QAction>
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_graphic.h"
|
||||
#include "rs_block.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
|
||||
|
||||
RS_ActionBlocksToggleView::RS_ActionBlocksToggleView(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_ActionInterface("Toggle Block Visibility",
|
||||
container, graphicView) {}
|
||||
|
||||
|
||||
void RS_ActionBlocksToggleView::trigger() {
|
||||
RS_DEBUG->print("toggle block");
|
||||
if (graphic) {
|
||||
RS_BlockList* bl = graphic->getBlockList();
|
||||
unsigned cnt = 0;
|
||||
// toggle selected blocks
|
||||
for (auto block: *bl) {
|
||||
if (!block) continue;
|
||||
if (!block->isVisibleInBlockList()) continue;
|
||||
if (!block->isSelectedInBlockList()) continue;
|
||||
graphic->toggleBlock(block);
|
||||
cnt++;
|
||||
}
|
||||
// if there wasn't selected blocks, toggle active block
|
||||
if (!cnt) {
|
||||
graphic->toggleBlock(graphic->getActiveBlock());
|
||||
}
|
||||
}
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
|
||||
finish(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionBlocksToggleView::init(int status) {
|
||||
RS_ActionInterface::init(status);
|
||||
trigger();
|
||||
}
|
||||
|
||||
// EOF
|
||||
49
actions/rs_actionblockstoggleview.h
Normal file
49
actions/rs_actionblockstoggleview.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONBLOCKSTOGGLEVIEW_H
|
||||
#define RS_ACTIONBLOCKSTOGGLEVIEW_H
|
||||
|
||||
#include "rs_actioninterface.h"
|
||||
|
||||
|
||||
/**
|
||||
* This action class can handle user events to edit layers.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionBlocksToggleView : public RS_ActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RS_ActionBlocksToggleView(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
424
actions/rs_actiondefault.cpp
Normal file
424
actions/rs_actiondefault.cpp
Normal file
@@ -0,0 +1,424 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
#include<QMouseEvent>
|
||||
#include "rs_actiondefault.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_modification.h"
|
||||
#include "rs_selection.h"
|
||||
#include "rs_overlaybox.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
struct RS_ActionDefault::Points {
|
||||
RS_Vector v1;
|
||||
RS_Vector v2;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
RS_ActionDefault::RS_ActionDefault(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
: RS_PreviewActionInterface("Default",
|
||||
container, graphicView)
|
||||
, pPoints(new Points{})
|
||||
, restrBak(RS2::RestrictNothing)
|
||||
{
|
||||
|
||||
RS_DEBUG->print("RS_ActionDefault::RS_ActionDefault");
|
||||
actionType=RS2::ActionDefault;
|
||||
RS_DEBUG->print("RS_ActionDefault::RS_ActionDefault: OK");
|
||||
}
|
||||
|
||||
RS_ActionDefault::~RS_ActionDefault() = default;
|
||||
|
||||
|
||||
void RS_ActionDefault::init(int status) {
|
||||
RS_DEBUG->print("RS_ActionDefault::init");
|
||||
if(status==Neutral){
|
||||
deletePreview();
|
||||
deleteSnapper();
|
||||
}
|
||||
RS_PreviewActionInterface::init(status);
|
||||
pPoints->v1 = pPoints->v2 = {};
|
||||
// snapMode.clear();
|
||||
// snapMode.restriction = RS2::RestrictNothing;
|
||||
// restrBak = RS2::RestrictNothing;
|
||||
// RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarMain);
|
||||
|
||||
RS_DEBUG->print("RS_ActionDefault::init: OK");
|
||||
}
|
||||
|
||||
void RS_ActionDefault::keyPressEvent(QKeyEvent* e) {
|
||||
// std::cout<<"RS_ActionDefault::keyPressEvent(): begin"<<std::endl;
|
||||
switch(e->key()){
|
||||
case Qt::Key_Shift:
|
||||
restrBak = snapMode.restriction;
|
||||
setSnapRestriction(RS2::RestrictOrthogonal);
|
||||
e->accept();
|
||||
break; //avoid clearing command line at shift key
|
||||
//cleanup default action, issue#285
|
||||
case Qt::Key_Escape:
|
||||
// std::cout<<"RS_ActionDefault::keyPressEvent(): Qt::Key_Escape"<<std::endl;
|
||||
deletePreview();
|
||||
deleteSnapper();
|
||||
setStatus(Neutral);
|
||||
e->accept();
|
||||
break;
|
||||
default:
|
||||
e->ignore();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RS_ActionDefault::keyReleaseEvent(QKeyEvent* e) {
|
||||
if (e->key()==Qt::Key_Shift) {
|
||||
setSnapRestriction(restrBak);
|
||||
e->accept();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDefault::mouseMoveEvent(QMouseEvent* e) {
|
||||
|
||||
RS_Vector mouse = graphicView->toGraph(e->x(), e->y());
|
||||
RS_Vector relMouse = mouse - graphicView->getRelativeZero();
|
||||
|
||||
RS_DIALOGFACTORY->updateCoordinateWidget(mouse, relMouse);
|
||||
|
||||
switch (getStatus()) {
|
||||
case Neutral:
|
||||
deleteSnapper();
|
||||
break;
|
||||
case Dragging:
|
||||
//v2 = graphicView->toGraph(e->x(), e->y());
|
||||
pPoints->v2 = mouse;
|
||||
|
||||
if (graphicView->toGuiDX(pPoints->v1.distanceTo(pPoints->v2))>10) {
|
||||
// look for reference points to drag:
|
||||
double dist;
|
||||
RS_Vector ref = container->getNearestSelectedRef(pPoints->v1, &dist);
|
||||
if (ref.valid==true && graphicView->toGuiDX(dist)<8) {
|
||||
RS_DEBUG->print("RS_ActionDefault::mouseMoveEvent: "
|
||||
"moving reference point");
|
||||
setStatus(MovingRef);
|
||||
pPoints->v1 = ref;
|
||||
graphicView->moveRelativeZero(pPoints->v1);
|
||||
}
|
||||
else {
|
||||
// test for an entity to drag:
|
||||
RS_Entity* en = catchEntity(pPoints->v1);
|
||||
if (en && en->isSelected()) {
|
||||
RS_DEBUG->print("RS_ActionDefault::mouseMoveEvent: "
|
||||
"moving entity");
|
||||
setStatus(Moving);
|
||||
RS_Vector vp= en->getNearestRef(pPoints->v1);
|
||||
if(vp.valid) pPoints->v1=vp;
|
||||
|
||||
//graphicView->moveRelativeZero(v1);
|
||||
}
|
||||
|
||||
// no entity found. start area selection:
|
||||
else {
|
||||
setStatus(SetCorner2);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MovingRef:
|
||||
pPoints->v2 = snapPoint(e);
|
||||
RS_DIALOGFACTORY->updateCoordinateWidget(pPoints->v2, pPoints->v2 - graphicView->getRelativeZero());
|
||||
|
||||
if (e->modifiers() & Qt::ShiftModifier) {
|
||||
mouse = snapToAngle(mouse, pPoints->v1, 15.);
|
||||
pPoints->v2 = mouse;
|
||||
}
|
||||
|
||||
deletePreview();
|
||||
preview->addSelectionFrom(*container);
|
||||
preview->moveRef(pPoints->v1, pPoints->v2 - pPoints->v1);
|
||||
|
||||
if (e->modifiers() & Qt::ShiftModifier) {
|
||||
RS_Line *line = new RS_Line(pPoints->v1, mouse);
|
||||
preview->addEntity(line);
|
||||
line->setSelected(true);
|
||||
}
|
||||
|
||||
drawPreview();
|
||||
break;
|
||||
|
||||
case Moving:
|
||||
pPoints->v2 = snapPoint(e);
|
||||
RS_DIALOGFACTORY->updateCoordinateWidget(pPoints->v2, pPoints->v2 - graphicView->getRelativeZero());
|
||||
|
||||
if (e->modifiers() & Qt::ShiftModifier) {
|
||||
mouse = snapToAngle(mouse, pPoints->v1, 15.);
|
||||
pPoints->v2 = mouse;
|
||||
}
|
||||
|
||||
deletePreview();
|
||||
preview->addSelectionFrom(*container);
|
||||
preview->move(pPoints->v2 - pPoints->v1);
|
||||
|
||||
if (e->modifiers() & Qt::ShiftModifier) {
|
||||
RS_Line *line = new RS_Line(pPoints->v1, mouse);
|
||||
preview->addEntity(line);
|
||||
line->setSelected(true);
|
||||
}
|
||||
|
||||
drawPreview();
|
||||
break;
|
||||
|
||||
case SetCorner2:
|
||||
if (pPoints->v1.valid) {
|
||||
pPoints->v2 = mouse;
|
||||
|
||||
deletePreview();
|
||||
|
||||
RS_OverlayBox* ob=new RS_OverlayBox(preview.get(),
|
||||
RS_OverlayBoxData(pPoints->v1, pPoints->v2));
|
||||
preview->addEntity(ob);
|
||||
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
case Panning:
|
||||
{
|
||||
RS_Vector const vTarget(e->x(), e->y());
|
||||
RS_Vector const v01=vTarget - pPoints->v1;
|
||||
if(v01.squared()>=64.){
|
||||
graphicView->zoomPan((int) v01.x, (int) v01.y);
|
||||
pPoints->v1=vTarget;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDefault::mousePressEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
switch (getStatus()) {
|
||||
case Neutral:
|
||||
{
|
||||
auto const m=e->modifiers();
|
||||
if(m & (Qt::ControlModifier|Qt::MetaModifier)){
|
||||
pPoints->v1 = RS_Vector(e->x(), e->y());
|
||||
setStatus(Panning);
|
||||
} else {
|
||||
pPoints->v1 = graphicView->toGraph(e->x(), e->y());
|
||||
setStatus(Dragging);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Moving: {
|
||||
pPoints->v2 = snapPoint(e);
|
||||
if (e->modifiers() & Qt::ShiftModifier) {
|
||||
pPoints->v2 = snapToAngle(pPoints->v2, pPoints->v1, 15.);
|
||||
}
|
||||
deletePreview();
|
||||
RS_Modification m(*container, graphicView);
|
||||
RS_MoveData data;
|
||||
data.number = 0;
|
||||
data.useCurrentLayer = false;
|
||||
data.useCurrentAttributes = false;
|
||||
data.offset = pPoints->v2 - pPoints->v1;
|
||||
m.move(data);
|
||||
setStatus(Neutral);
|
||||
RS_DIALOGFACTORY->updateSelectionWidget(
|
||||
container->countSelected(),container->totalSelectedLength());
|
||||
deleteSnapper();
|
||||
}
|
||||
break;
|
||||
|
||||
case MovingRef: {
|
||||
pPoints->v2 = snapPoint(e);
|
||||
if (e->modifiers() & Qt::ShiftModifier) {
|
||||
pPoints->v2 = snapToAngle(pPoints->v2, pPoints->v1, 15.);
|
||||
}
|
||||
deletePreview();
|
||||
RS_Modification m(*container, graphicView);
|
||||
RS_MoveRefData data;
|
||||
data.ref = pPoints->v1;
|
||||
data.offset = pPoints->v2 - pPoints->v1;
|
||||
m.moveRef(data);
|
||||
//container->moveSelectedRef(v1, v2-v2);
|
||||
setStatus(Neutral);
|
||||
RS_DIALOGFACTORY->updateSelectionWidget(
|
||||
container->countSelected(),container->totalSelectedLength());
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
//cleanup
|
||||
setStatus(Neutral);
|
||||
e->accept();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDefault::mouseReleaseEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDefault::mouseReleaseEvent()");
|
||||
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
pPoints->v2 = graphicView->toGraph(e->x(), e->y());
|
||||
switch (getStatus()) {
|
||||
case Dragging: {
|
||||
// select single entity:
|
||||
RS_Entity* en = catchEntity(e);
|
||||
|
||||
if (en) {
|
||||
deletePreview();
|
||||
|
||||
RS_Selection s(*container, graphicView);
|
||||
s.selectSingle(en);
|
||||
|
||||
RS_DIALOGFACTORY->updateSelectionWidget(
|
||||
container->countSelected(),container->totalSelectedLength());
|
||||
|
||||
e->accept();
|
||||
|
||||
setStatus(Neutral);
|
||||
} else {
|
||||
setStatus(SetCorner2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SetCorner2: {
|
||||
//v2 = snapPoint(e);
|
||||
pPoints->v2 = graphicView->toGraph(e->x(), e->y());
|
||||
|
||||
// select window:
|
||||
//if (graphicView->toGuiDX(v1.distanceTo(v2))>20) {
|
||||
deletePreview();
|
||||
|
||||
bool cross = (pPoints->v1.x > pPoints->v2.x);
|
||||
RS_Selection s(*container, graphicView);
|
||||
bool select = (e->modifiers() & Qt::ShiftModifier) ? false : true;
|
||||
s.selectWindow(pPoints->v1, pPoints->v2, select, cross);
|
||||
|
||||
RS_DIALOGFACTORY->updateSelectionWidget(
|
||||
container->countSelected(),container->totalSelectedLength());
|
||||
|
||||
setStatus(Neutral);
|
||||
e->accept();
|
||||
//}
|
||||
}
|
||||
break;
|
||||
|
||||
case Panning:
|
||||
setStatus(Neutral);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
//cleanup
|
||||
setStatus(Neutral);
|
||||
e->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDefault::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
// if the current action can't deal with the command,
|
||||
// it might be intended to launch a new command
|
||||
//if (!e.isAccepted()) {
|
||||
// command for new action:
|
||||
//RS2::ActionType type = RS_COMMANDS->cmdToAction(c);
|
||||
//if (type!=RS2::ActionNone) {
|
||||
//graphicView->setCurrentAction(type);
|
||||
//return true;
|
||||
//}
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDefault::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
//cmd += "line";
|
||||
//cmd += "rectangle";
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDefault::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case Neutral:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
case SetCorner2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Choose second edge"),
|
||||
tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDefault::updateMouseCursor() {
|
||||
switch (getStatus()) {
|
||||
case Neutral:
|
||||
graphicView->setMouseCursor(RS2::ArrowCursor);
|
||||
break;
|
||||
case Moving:
|
||||
case MovingRef:
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
break;
|
||||
case Panning:
|
||||
graphicView->setMouseCursor(RS2::ClosedHandCursor);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// EOF
|
||||
85
actions/rs_actiondefault.h
Normal file
85
actions/rs_actiondefault.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONSELECTWINDOW_H
|
||||
#define RS_ACTIONSELECTWINDOW_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
|
||||
/**
|
||||
* This action class can handle user events to select all entities.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDefault : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
Neutral, /**< we don't know what we do yet. */
|
||||
Dragging, /**< dragging (either an entity or the
|
||||
first part of a selection window) */
|
||||
SetCorner2, /**< Setting the 2nd corner of a selection window. */
|
||||
Moving, /**< Moving entities (drag'n'drop) */
|
||||
MovingRef, /**< Moving a reference point of one or more selected
|
||||
entities */
|
||||
Panning /**< view panning triggered by Ctl- mouse dragging */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDefault(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDefault() override;
|
||||
|
||||
void finish(bool /*updateTB*/ = true ) override{}
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void keyPressEvent(QKeyEvent* e) override;
|
||||
void keyReleaseEvent(QKeyEvent* e) override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mousePressEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
// void resume() override;
|
||||
|
||||
protected:
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
RS2::SnapRestriction restrBak;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
290
actions/rs_actiondimaligned.cpp
Normal file
290
actions/rs_actiondimaligned.cpp
Normal file
@@ -0,0 +1,290 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
#include<cmath>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondimaligned.h"
|
||||
#include "rs_dimaligned.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_constructionline.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
RS_ActionDimAligned::RS_ActionDimAligned(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_ActionDimension("Draw aligned dimensions",
|
||||
container, graphicView) {
|
||||
actionType=RS2::ActionDimAligned;
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
RS_ActionDimAligned::~RS_ActionDimAligned() = default;
|
||||
|
||||
void RS_ActionDimAligned::reset() {
|
||||
RS_ActionDimension::reset();
|
||||
|
||||
edata.reset(new RS_DimAlignedData(RS_Vector(false),
|
||||
RS_Vector(false))
|
||||
);
|
||||
lastStatus = SetExtPoint1;
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimAligned::trigger() {
|
||||
RS_ActionDimension::trigger();
|
||||
|
||||
preparePreview();
|
||||
graphicView->moveRelativeZero(data->definitionPoint);
|
||||
|
||||
//data->text = getText();
|
||||
RS_DimAligned* dim =
|
||||
new RS_DimAligned(container, *data, *edata);
|
||||
dim->setLayerToActive();
|
||||
dim->setPenToActive();
|
||||
dim->update();
|
||||
container->addEntity(dim);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(dim);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
RS_Vector rz = graphicView->getRelativeZero();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(rz);
|
||||
|
||||
RS_DEBUG->print("RS_ActionDimAligned::trigger():"
|
||||
" dim added: %d", dim->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimAligned::preparePreview() {
|
||||
RS_Vector dirV = RS_Vector::polar(100.,
|
||||
edata->extensionPoint1.angleTo(
|
||||
edata->extensionPoint2)
|
||||
+M_PI_2);
|
||||
RS_ConstructionLine cl(nullptr,
|
||||
RS_ConstructionLineData(
|
||||
edata->extensionPoint2,
|
||||
edata->extensionPoint2+dirV));
|
||||
|
||||
data->definitionPoint =
|
||||
cl.getNearestPointOnEntity(data->definitionPoint);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimAligned::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDimAligned::mouseMoveEvent begin");
|
||||
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetExtPoint1:
|
||||
break;
|
||||
|
||||
case SetExtPoint2:
|
||||
if (edata->extensionPoint1.valid) {
|
||||
deletePreview();
|
||||
preview->addEntity(
|
||||
new RS_Line{preview.get(),edata->extensionPoint1, mouse}
|
||||
);
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
case SetDefPoint:
|
||||
if (edata->extensionPoint1.valid && edata->extensionPoint2.valid) {
|
||||
deletePreview();
|
||||
data->definitionPoint = mouse;
|
||||
|
||||
preparePreview();
|
||||
|
||||
//data->text = getText();
|
||||
RS_DimAligned* dim = new RS_DimAligned(preview.get(), *data, *edata);
|
||||
preview->addEntity(dim);
|
||||
dim->update();
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDimAligned::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimAligned::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimAligned::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e) return;
|
||||
|
||||
RS_Vector pos = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetExtPoint1:
|
||||
edata->extensionPoint1 = pos;
|
||||
graphicView->moveRelativeZero(pos);
|
||||
setStatus(SetExtPoint2);
|
||||
break;
|
||||
|
||||
case SetExtPoint2:
|
||||
edata->extensionPoint2 = pos;
|
||||
graphicView->moveRelativeZero(pos);
|
||||
setStatus(SetDefPoint);
|
||||
break;
|
||||
|
||||
case SetDefPoint:
|
||||
data->definitionPoint = pos;
|
||||
trigger();
|
||||
reset();
|
||||
setStatus(SetExtPoint1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimAligned::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetText: {
|
||||
setText(c);
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
graphicView->enableCoordinateInput();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (checkCommand("text", c)) {
|
||||
lastStatus = (Status)getStatus();
|
||||
graphicView->disableCoordinateInput();
|
||||
setStatus(SetText);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDimAligned::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetExtPoint1:
|
||||
case SetExtPoint2:
|
||||
case SetDefPoint:
|
||||
cmd += command("text");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimAligned::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetExtPoint1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify first extension line origin"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetExtPoint2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify second extension line origin"),
|
||||
tr("Back"));
|
||||
break;
|
||||
case SetDefPoint:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify dimension line location"),
|
||||
tr("Back"));
|
||||
break;
|
||||
case SetText:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter dimension text:"), "");
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimAligned::hideOptions() {
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
|
||||
RS_ActionDimension::hideOptions();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimAligned::showOptions() {
|
||||
RS_ActionDimension::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
}
|
||||
|
||||
// EOF
|
||||
86
actions/rs_actiondimaligned.h
Normal file
86
actions/rs_actiondimaligned.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDIMALIGNED_H
|
||||
#define RS_ACTIONDIMALIGNED_H
|
||||
|
||||
#include "rs_actiondimension.h"
|
||||
|
||||
struct RS_DimAlignedData;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw
|
||||
* aligned dimensions.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDimAligned : public RS_ActionDimension {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetExtPoint1, /**< Setting the 1st ext point. */
|
||||
SetExtPoint2, /**< Setting the 2nd ext point. */
|
||||
SetDefPoint, /**< Setting the common def point */
|
||||
SetText /**< Setting the text label in command line */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDimAligned(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDimAligned() override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
void trigger() override;
|
||||
void preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Aligned dimension data.
|
||||
*/
|
||||
std::unique_ptr<RS_DimAlignedData> edata;
|
||||
|
||||
/** Last status before entering text. */
|
||||
Status lastStatus;
|
||||
}
|
||||
;
|
||||
|
||||
#endif
|
||||
431
actions/rs_actiondimangular.cpp
Normal file
431
actions/rs_actiondimangular.cpp
Normal file
@@ -0,0 +1,431 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2018 A. Stebich (librecad@mail.lordofbikes.de)
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <cmath>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondimangular.h"
|
||||
#include "rs_dimangular.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_information.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
#include "rs_math.h"
|
||||
|
||||
RS_ActionDimAngular::RS_ActionDimAngular(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView) :
|
||||
RS_ActionDimension( "Draw Angular Dimensions", container, graphicView)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
RS_ActionDimAngular::~RS_ActionDimAngular() = default;
|
||||
|
||||
void RS_ActionDimAngular::reset()
|
||||
{
|
||||
RS_ActionDimension::reset();
|
||||
|
||||
actionType = RS2::ActionDimAngular;
|
||||
edata.reset( new RS_DimAngularData( RS_Vector( false),
|
||||
RS_Vector( false),
|
||||
RS_Vector( false),
|
||||
RS_Vector( false)) );
|
||||
RS_DIALOGFACTORY->requestOptions( this, true, true);
|
||||
}
|
||||
|
||||
void RS_ActionDimAngular::trigger()
|
||||
{
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
if (line1.getStartpoint().valid && line2.getStartpoint().valid) {
|
||||
RS_DimAngular* newEntity {new RS_DimAngular( container,
|
||||
*data,
|
||||
*edata)};
|
||||
|
||||
newEntity->setLayerToActive();
|
||||
newEntity->setPenToActive();
|
||||
newEntity->update();
|
||||
container->addEntity(newEntity);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(newEntity);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
RS_Vector rz {graphicView->getRelativeZero()};
|
||||
setStatus( SetLine1);
|
||||
graphicView->redraw( RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero( rz);
|
||||
RS_Snapper::finish();
|
||||
}
|
||||
else {
|
||||
RS_DEBUG->print( "RS_ActionDimAngular::trigger: Entity is nullptr\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDimAngular::mouseMoveEvent(QMouseEvent* e)
|
||||
{
|
||||
RS_DEBUG->print( "RS_ActionDimAngular::mouseMoveEvent begin");
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPos:
|
||||
if( setData( snapPoint(e))) {
|
||||
RS_DimAngular *d {new RS_DimAngular( preview.get(), *data, *edata)};
|
||||
|
||||
deletePreview();
|
||||
preview->addEntity(d);
|
||||
d->update();
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDimAngular::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
void RS_ActionDimAngular::mouseReleaseEvent(QMouseEvent* e)
|
||||
{
|
||||
if (Qt::LeftButton == e->button()) {
|
||||
switch (getStatus()) {
|
||||
case SetLine1: {
|
||||
RS_Entity *en {catchEntity( e, RS2::ResolveAll)};
|
||||
if (en && RS2::EntityLine == en->rtti()) {
|
||||
line1 = *dynamic_cast<RS_Line*>(en);
|
||||
click1 = line1.getNearestPointOnEntity( graphicView->toGraph( e->x(), e->y()));
|
||||
setStatus(SetLine2);
|
||||
}
|
||||
break; }
|
||||
|
||||
case SetLine2: {
|
||||
RS_Entity *en{catchEntity(e, RS2::ResolveAll)};
|
||||
if (en && en->rtti()==RS2::EntityLine) {
|
||||
line2 = *dynamic_cast<RS_Line*>(en);
|
||||
click2 = line2.getNearestPointOnEntity( graphicView->toGraph( e->x(), e->y()));
|
||||
if( setData( click2, true)) {
|
||||
graphicView->moveRelativeZero( center);
|
||||
setStatus(SetPos);
|
||||
}
|
||||
}
|
||||
break; }
|
||||
|
||||
case SetPos: {
|
||||
RS_CoordinateEvent ce( snapPoint( e));
|
||||
coordinateEvent( &ce);
|
||||
break; }
|
||||
}
|
||||
}
|
||||
else if (Qt::RightButton == e->button()) {
|
||||
deletePreview();
|
||||
init( getStatus() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDimAngular::coordinateEvent(RS_CoordinateEvent* e)
|
||||
{
|
||||
if ( ! e) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPos:
|
||||
if( setData( e->getCoordinate())) {
|
||||
trigger();
|
||||
reset();
|
||||
setStatus( SetLine1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDimAngular::commandEvent(RS_CommandEvent* e)
|
||||
{
|
||||
QString c( e->getCommand().toLower());
|
||||
|
||||
if (checkCommand( QStringLiteral( "help"), c)) {
|
||||
RS_DIALOGFACTORY->commandMessage( msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
// setting new text label:
|
||||
if (SetText == getStatus()) {
|
||||
setText( c);
|
||||
RS_DIALOGFACTORY->requestOptions( this, true, true);
|
||||
graphicView->enableCoordinateInput();
|
||||
setStatus( lastStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
// command: text
|
||||
if (checkCommand( QStringLiteral( "text"), c)) {
|
||||
lastStatus = static_cast<Status>(getStatus());
|
||||
graphicView->disableCoordinateInput();
|
||||
setStatus( SetText);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList RS_ActionDimAngular::getAvailableCommands()
|
||||
{
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetLine1:
|
||||
case SetLine2:
|
||||
case SetPos:
|
||||
cmd += command( QStringLiteral( "text"));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void RS_ActionDimAngular::showOptions()
|
||||
{
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions( this, true);
|
||||
}
|
||||
|
||||
void RS_ActionDimAngular::hideOptions()
|
||||
{
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions( this, false);
|
||||
}
|
||||
|
||||
void RS_ActionDimAngular::updateMouseButtonHints()
|
||||
{
|
||||
switch (getStatus()) {
|
||||
case SetLine1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget( tr("Select first line"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetLine2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget( tr("Select second line"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetPos:
|
||||
RS_DIALOGFACTORY->updateMouseWidget( tr("Specify dimension arc line location"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetText:
|
||||
RS_DIALOGFACTORY->updateMouseWidget( tr("Enter dimension text:"), "");
|
||||
break;
|
||||
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Justify one of the angle lines to ensure that the starting point
|
||||
* of the line has the same angle from the intersection point as the
|
||||
* selection click point and it is further away than the line end point
|
||||
*
|
||||
* @param line A selected line for the dimension
|
||||
* @param click The click pos which selected the line
|
||||
* @param center The intersection of the 2 lines to dimension
|
||||
*/
|
||||
void RS_ActionDimAngular::justify(RS_Line &line, const RS_Vector &click)
|
||||
{
|
||||
RS_Vector vStartPoint( line.getStartpoint());
|
||||
|
||||
if( ! RS_Math::equal( vStartPoint.angleTo(center), click.angleTo( center))
|
||||
|| vStartPoint.distanceTo( center) < click.distanceTo( center)) {
|
||||
line.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a sorted array with angles from the lines intersection point
|
||||
* to the starting points and their revers angles.
|
||||
* Ensure, that line1 and line2 are in CCW order.
|
||||
* Compute an offset for quadrant() method.
|
||||
*
|
||||
* @param line A selected line for the dimension
|
||||
* @param click The click pos which selected the line
|
||||
* @param center The intersection of the 2 lines to dimension
|
||||
*/
|
||||
void RS_ActionDimAngular::lineOrder(const RS_Vector &dimPos)
|
||||
{
|
||||
if( ! center.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
// starting point angles and selection point angle from intersection point
|
||||
double a0 {(dimPos - center).angle()};
|
||||
double a1 {(line1.getStartpoint() - center).angle()};
|
||||
double a2 {(line2.getStartpoint() - center).angle()};
|
||||
|
||||
// swap lines if necessary to ensure CCW order
|
||||
if( RS_Math::correctAngle2( a1 - a0) > RS_Math::correctAngle2( a2 - a0)) {
|
||||
RS_Line swapLines( line1);
|
||||
line1 = line2;
|
||||
line2 = swapLines;
|
||||
double swapAngle {a1};
|
||||
a1 = a2;
|
||||
a2 = swapAngle;
|
||||
}
|
||||
|
||||
// sorted array with starting point and reverse angles
|
||||
angles.clear();
|
||||
angles.push_back( a1);
|
||||
angles.push_back( RS_Math::correctAngle( a1 + M_PI));
|
||||
angles.push_back( a2);
|
||||
angles.push_back( RS_Math::correctAngle( a2 + M_PI));
|
||||
std::sort( angles.begin(), angles.end());
|
||||
|
||||
// find starting quadrant and compute the offset for quadrant() method
|
||||
int startQuadrant = 0;
|
||||
for( auto angle : angles) {
|
||||
if( RS_Math::equal( a1, angle)) {
|
||||
break;
|
||||
}
|
||||
++startQuadrant;
|
||||
}
|
||||
quadrantOffset = 0x03 & (4 - startQuadrant);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the quadrant of \p angle relative to 1st quadrant.
|
||||
* When the angle lines are selected, the starting quadrant
|
||||
* is shifted to become 0 by \p quadrantOffset.
|
||||
* This is the criterion how the angles dimension is drawn.
|
||||
*
|
||||
* @param angle The angle, e.g. mouse or coordinate position
|
||||
* @return The quadrant of \p angle, relative to the 1st selection quadrant
|
||||
*/
|
||||
int RS_ActionDimAngular::quadrant(const double angle)
|
||||
{
|
||||
if( 1 > angles.size()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double a1 {RS_Math::correctAngle2( angles.at(0) - angle)};
|
||||
double a2 {RS_Math::correctAngle2( angles.at(1) - angle)};
|
||||
|
||||
int angleQuadrant {0};
|
||||
if( 0.0 < a1 && 0.0 < a2) {
|
||||
angleQuadrant = 3;
|
||||
}
|
||||
else if( 0.0 >= a1 && 0.0 >= a2) {
|
||||
angleQuadrant = 1;
|
||||
}
|
||||
else if( 0.0 < a1 && 0.0 >= a2) {
|
||||
angleQuadrant = 2;
|
||||
}
|
||||
|
||||
return (0x03 & (angleQuadrant + quadrantOffset));
|
||||
}
|
||||
|
||||
/**
|
||||
* On \p mouseMoveEvent, \p mouseReleaseEvent and \p coordinateEvent
|
||||
* this method sets the dimension data appropriate to the mouse
|
||||
* cursor/coordinate in \p dimPos.
|
||||
* When \p calcCenter is true, the intersection point and other static
|
||||
* values are computed. This is only necessary, when line selection changes,
|
||||
* e.g. on \p mouseReleaseEvent. For \p mouseMoveEvent calcCenter is false.
|
||||
*
|
||||
* @param dimPos The mouse/coordinate position
|
||||
* @param calcCenter If true, the center and corresponding values are calculated
|
||||
* @return true If the dimension data were set, false is a parameter is invalid
|
||||
*/
|
||||
bool RS_ActionDimAngular::setData(const RS_Vector &dimPos, const bool calcCenter /*= false*/)
|
||||
{
|
||||
if( ! line1.getStartpoint().valid || ! line2.getStartpoint().valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! center.valid || calcCenter) {
|
||||
RS_VectorSolutions sol = RS_Information::getIntersectionLineLine( &line1, &line2);
|
||||
center = sol.get(0);
|
||||
}
|
||||
if ( ! center.valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( calcCenter) {
|
||||
justify( line1, click1);
|
||||
justify( line2, click2);
|
||||
lineOrder( dimPos);
|
||||
}
|
||||
|
||||
edata->definitionPoint4 = dimPos;
|
||||
switch( quadrant( (dimPos - center).angle())) {
|
||||
default:
|
||||
case 0:
|
||||
edata->definitionPoint1 = line1.getEndpoint();
|
||||
edata->definitionPoint2 = line1.getStartpoint();
|
||||
edata->definitionPoint3 = line2.getEndpoint();
|
||||
data->definitionPoint = line2.getStartpoint();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
edata->definitionPoint1 = line2.getEndpoint();
|
||||
edata->definitionPoint2 = line2.getStartpoint();
|
||||
edata->definitionPoint3 = line1.getStartpoint();
|
||||
data->definitionPoint = line1.getEndpoint();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
edata->definitionPoint1 = line2.getEndpoint();
|
||||
edata->definitionPoint2 = line2.getStartpoint();
|
||||
edata->definitionPoint3 = line1.getEndpoint();
|
||||
data->definitionPoint = line1.getStartpoint();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
edata->definitionPoint1 = line2.getStartpoint();
|
||||
edata->definitionPoint2 = line2.getEndpoint();
|
||||
edata->definitionPoint3 = line1.getEndpoint();
|
||||
data->definitionPoint = line1.getStartpoint();
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// EOF
|
||||
91
actions/rs_actiondimangular.h
Normal file
91
actions/rs_actiondimangular.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2018 A. Stebich (librecad@mail.lordofbikes.de)
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDIMANGULAR_H
|
||||
#define RS_ACTIONDIMANGULAR_H
|
||||
|
||||
#include "rs_actiondimension.h"
|
||||
#include "rs_line.h"
|
||||
|
||||
struct RS_DimAngularData;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw angular dimensions.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDimAngular : public RS_ActionDimension
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
enum Status {
|
||||
SetLine1, ///< Choose 1st line
|
||||
SetLine2, ///< Choose 2nd line
|
||||
SetPos, ///< Choose position
|
||||
SetText ///< Setting text label in consle
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDimAngular(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDimAngular() override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
|
||||
private:
|
||||
RS_Line line1; ///< 1st chosen line
|
||||
RS_Line line2; ///< 2nd chosen line
|
||||
RS_Vector click1; ///< 1st click pos
|
||||
RS_Vector click2; ///< 2nd click pos
|
||||
RS_Vector center; ///< Center of arc
|
||||
std::unique_ptr<RS_DimAngularData> edata; ///< Data of new dimension
|
||||
Status lastStatus; ///< Last status before entering text
|
||||
std::vector<double> angles; ///< Array to sort line angles
|
||||
int quadrantOffset {0}; ///< Offset on starting quadrant
|
||||
|
||||
void justify( RS_Line &line, const RS_Vector &click);
|
||||
void lineOrder(const RS_Vector &dimPos);
|
||||
int quadrant(const double angle);
|
||||
bool setData(const RS_Vector& dimPos, const bool calcCenter = false);
|
||||
};
|
||||
|
||||
#endif
|
||||
321
actions/rs_actiondimdiametric.cpp
Normal file
321
actions/rs_actiondimdiametric.cpp
Normal file
@@ -0,0 +1,321 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
#include<cmath>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondimdiametric.h"
|
||||
#include "rs_dimdiametric.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_arc.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
|
||||
RS_ActionDimDiametric::RS_ActionDimDiametric(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_ActionDimension("Draw Diametric Dimensions",
|
||||
container, graphicView)
|
||||
, pos(new RS_Vector{})
|
||||
{
|
||||
actionType=RS2::ActionDimDiametric;
|
||||
reset();
|
||||
}
|
||||
|
||||
RS_ActionDimDiametric::~RS_ActionDimDiametric() = default;
|
||||
|
||||
void RS_ActionDimDiametric::reset() {
|
||||
RS_ActionDimension::reset();
|
||||
|
||||
edata.reset(new RS_DimDiametricData(RS_Vector{false},
|
||||
0.0)
|
||||
);
|
||||
entity = nullptr;
|
||||
*pos = {};
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimDiametric::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
preparePreview();
|
||||
if (entity) {
|
||||
RS_DimDiametric* newEntity = nullptr;
|
||||
|
||||
newEntity = new RS_DimDiametric(container,
|
||||
*data,
|
||||
*edata);
|
||||
|
||||
newEntity->setLayerToActive();
|
||||
newEntity->setPenToActive();
|
||||
newEntity->update();
|
||||
container->addEntity(newEntity);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(newEntity);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
RS_Vector rz = graphicView->getRelativeZero();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(rz);
|
||||
RS_Snapper::finish();
|
||||
|
||||
} else {
|
||||
RS_DEBUG->print("RS_ActionDimDiametric::trigger:"
|
||||
" Entity is nullptr\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimDiametric::preparePreview() {
|
||||
if (entity) {
|
||||
double radius{0.};
|
||||
RS_Vector center{false};
|
||||
if (entity->rtti()==RS2::EntityArc) {
|
||||
RS_Arc* p = static_cast<RS_Arc*>(entity);
|
||||
radius = p->getRadius();
|
||||
center = p->getCenter();
|
||||
} else if (entity->rtti()==RS2::EntityCircle) {
|
||||
RS_Circle* p = static_cast<RS_Circle*>(entity);
|
||||
radius = p->getRadius();
|
||||
center = p->getCenter();
|
||||
}
|
||||
double angle = center.angleTo(*pos);
|
||||
|
||||
data->definitionPoint.setPolar(radius, angle + M_PI);
|
||||
data->definitionPoint += center;
|
||||
|
||||
edata->definitionPoint.setPolar(radius, angle);
|
||||
edata->definitionPoint += center;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimDiametric::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDimDiametric::mouseMoveEvent begin");
|
||||
|
||||
switch (getStatus()) {
|
||||
|
||||
case SetPos:
|
||||
if (entity) {
|
||||
*pos = snapPoint(e);
|
||||
|
||||
preparePreview();
|
||||
RS_DimDiametric* d = new RS_DimDiametric(preview.get(), *data, *edata);
|
||||
|
||||
deletePreview();
|
||||
preview->addEntity(d);
|
||||
d->update();
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDimDiametric::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimDiametric::mouseReleaseEvent(QMouseEvent* e) {
|
||||
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
switch (getStatus()) {
|
||||
case SetEntity: {
|
||||
RS_Entity* en = catchEntity(e, RS2::ResolveAll);
|
||||
if (en) {
|
||||
if (en->rtti()==RS2::EntityArc ||
|
||||
en->rtti()==RS2::EntityCircle) {
|
||||
|
||||
entity = en;
|
||||
RS_Vector center;
|
||||
if (entity->rtti()==RS2::EntityArc) {
|
||||
center =
|
||||
static_cast<RS_Arc*>(entity)->getCenter();
|
||||
} else {
|
||||
center =
|
||||
static_cast<RS_Circle*>(entity)->getCenter();
|
||||
}
|
||||
graphicView->moveRelativeZero(center);
|
||||
setStatus(SetPos);
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a circle "
|
||||
"or arc entity"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SetPos: {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimDiametric::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e) return;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPos:
|
||||
*pos = e->getCoordinate();
|
||||
trigger();
|
||||
reset();
|
||||
setStatus(SetEntity);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimDiametric::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
// setting new text label:
|
||||
if (getStatus()==SetText) {
|
||||
setText(c);
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
graphicView->enableCoordinateInput();
|
||||
setStatus(lastStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
// command: text
|
||||
if (checkCommand("text", c)) {
|
||||
lastStatus = (Status)getStatus();
|
||||
graphicView->disableCoordinateInput();
|
||||
setStatus(SetText);
|
||||
}
|
||||
|
||||
// setting angle
|
||||
if (getStatus()==SetPos) {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
pos->setPolar(1.0, RS_Math::deg2rad(a));
|
||||
*pos += data->definitionPoint;
|
||||
trigger();
|
||||
reset();
|
||||
setStatus(SetEntity);
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDimDiametric::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetEntity:
|
||||
case SetPos:
|
||||
cmd += command("text");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDimDiametric::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetEntity:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Select arc or circle entity"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetPos:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify dimension line location"), tr("Cancel"));
|
||||
break;
|
||||
case SetText:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter dimension text:"), "");
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimDiametric::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimDiametric::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
//RS_DIALOGFACTORY->requestDimDiametricOptions(edata, false);
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// EOF
|
||||
81
actions/rs_actiondimdiametric.h
Normal file
81
actions/rs_actiondimdiametric.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDIMDIAMETRIC_H
|
||||
#define RS_ACTIONDIMDIAMETRIC_H
|
||||
|
||||
#include "rs_actiondimension.h"
|
||||
|
||||
struct RS_DimDiametricData;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw diametric dimensions.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDimDiametric : public RS_ActionDimension {
|
||||
Q_OBJECT
|
||||
private:
|
||||
enum Status {
|
||||
SetEntity, /**< Choose entity. */
|
||||
SetPos, /**< Choose point. */
|
||||
SetText /**< Setting text label in the command line. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDimDiametric(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDimDiametric() override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
void trigger() override;
|
||||
void preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
|
||||
private:
|
||||
/** Chosen entity (arc / circle) */
|
||||
RS_Entity* entity;
|
||||
/** Chosen position */
|
||||
std::unique_ptr<RS_Vector> pos;
|
||||
/** Data of new dimension */
|
||||
std::unique_ptr<RS_DimDiametricData> edata;
|
||||
/** Last status before entering text. */
|
||||
Status lastStatus;
|
||||
};
|
||||
|
||||
#endif
|
||||
163
actions/rs_actiondimension.cpp
Normal file
163
actions/rs_actiondimension.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include "rs_actiondimaligned.h"
|
||||
|
||||
#include "rs_dimension.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
|
||||
|
||||
RS_ActionDimension::RS_ActionDimension(const char* name,
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface(name,
|
||||
container, graphicView) {
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
RS_ActionDimension::~RS_ActionDimension() = default;
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimension::reset() {
|
||||
data.reset(new RS_DimensionData(RS_Vector(false),
|
||||
RS_Vector(false),
|
||||
RS_MTextData::VAMiddle,
|
||||
RS_MTextData::HACenter,
|
||||
RS_MTextData::Exact,
|
||||
1.0,
|
||||
"",
|
||||
"Standard",
|
||||
0.0)
|
||||
);
|
||||
diameter = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimension::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
//reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimension::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimension::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimension::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
}
|
||||
|
||||
bool RS_ActionDimension::isDimensionAction(RS2::ActionType type) {
|
||||
switch(type){
|
||||
case RS2::ActionDimAligned:
|
||||
case RS2::ActionDimLinear:
|
||||
case RS2::ActionDimLinearVer:
|
||||
case RS2::ActionDimLinearHor:
|
||||
case RS2::ActionDimAngular:
|
||||
case RS2::ActionDimDiametric:
|
||||
case RS2::ActionDimRadial:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString RS_ActionDimension::getText() const {
|
||||
if (!data->text.isEmpty()) {
|
||||
return data->text;
|
||||
}
|
||||
|
||||
QString l = label;
|
||||
|
||||
if (l.isEmpty() &&
|
||||
(diameter==true || !tol1.isEmpty() || !tol2.isEmpty())) {
|
||||
l = "<>";
|
||||
}
|
||||
|
||||
if (diameter==true) {
|
||||
l = QChar(0x2205) + l;
|
||||
}
|
||||
|
||||
if (!tol1.isEmpty() || !tol2.isEmpty()) {
|
||||
l += QString("\\S%1\\%2;").arg(tol1).arg(tol2);
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void RS_ActionDimension::setText(const QString& t) {
|
||||
data->text = t;
|
||||
}
|
||||
|
||||
const QString& RS_ActionDimension::getLabel() const{
|
||||
return label;
|
||||
}
|
||||
|
||||
void RS_ActionDimension::setLabel(const QString& t) {
|
||||
//data->text = t;
|
||||
label = t;
|
||||
}
|
||||
const QString& RS_ActionDimension::getTol1() const{
|
||||
return tol1;
|
||||
}
|
||||
void RS_ActionDimension::setTol1(const QString& t) {
|
||||
tol1 = t;
|
||||
}
|
||||
const QString& RS_ActionDimension::getTol2() const{
|
||||
return tol2;
|
||||
}
|
||||
void RS_ActionDimension::setTol2(const QString& t) {
|
||||
tol2 = t;
|
||||
}
|
||||
bool RS_ActionDimension::getDiameter() const {
|
||||
return diameter;
|
||||
}
|
||||
void RS_ActionDimension::setDiameter(bool d) {
|
||||
diameter = d;
|
||||
}
|
||||
|
||||
// EOF
|
||||
92
actions/rs_actiondimension.h
Normal file
92
actions/rs_actiondimension.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDIMENSION_H
|
||||
#define RS_ACTIONDIMENSION_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
struct RS_DimensionData;
|
||||
|
||||
/**
|
||||
* Base class for dimension actions.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDimension : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RS_ActionDimension(const char* name,
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDimension() override;
|
||||
|
||||
virtual void reset();
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseCursor() override;
|
||||
// void updateToolBar() override;
|
||||
|
||||
QString getText() const;
|
||||
|
||||
void setText(const QString& t);
|
||||
|
||||
const QString& getLabel() const;
|
||||
void setLabel(const QString& t);
|
||||
const QString& getTol1() const;
|
||||
void setTol1(const QString& t);
|
||||
const QString& getTol2() const;
|
||||
void setTol2(const QString& t);
|
||||
bool getDiameter() const;
|
||||
void setDiameter(bool d);
|
||||
|
||||
static bool isDimensionAction(RS2::ActionType type);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Generic dimension data.
|
||||
*/
|
||||
std::unique_ptr<RS_DimensionData> data;
|
||||
|
||||
QString label;
|
||||
QString tol1;
|
||||
QString tol2;
|
||||
bool diameter;
|
||||
|
||||
/**
|
||||
* Commands.
|
||||
*/
|
||||
/*
|
||||
QString cmdText;
|
||||
QString cmdText2;
|
||||
*/
|
||||
};
|
||||
|
||||
#endif
|
||||
241
actions/rs_actiondimleader.cpp
Normal file
241
actions/rs_actiondimleader.cpp
Normal file
@@ -0,0 +1,241 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
#include<vector>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondimleader.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_leader.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDimLeader::Points {
|
||||
std::vector<RS_Vector> points;
|
||||
};
|
||||
|
||||
RS_ActionDimLeader::RS_ActionDimLeader(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw leaders",
|
||||
container, graphicView)
|
||||
, pPoints(new Points{})
|
||||
{
|
||||
actionType=RS2::ActionDimLeader;
|
||||
reset();
|
||||
}
|
||||
|
||||
RS_ActionDimLeader::~RS_ActionDimLeader() = default;
|
||||
|
||||
void RS_ActionDimLeader::reset() {
|
||||
//data = RS_LineData(RS_Vector(false), RS_Vector(false));
|
||||
//start = RS_Vector(false);
|
||||
//history.clear();
|
||||
pPoints->points.clear();
|
||||
}
|
||||
|
||||
void RS_ActionDimLeader::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimLeader::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
if (pPoints->points.size()){
|
||||
|
||||
RS_Leader* leader = new RS_Leader(container, RS_LeaderData(true));
|
||||
leader->setLayerToActive();
|
||||
leader->setPenToActive();
|
||||
|
||||
for(const auto& vp: pPoints->points){
|
||||
leader->addVertex(vp);
|
||||
}
|
||||
|
||||
container->addEntity(leader);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(leader);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
deletePreview();
|
||||
RS_Vector rz = graphicView->getRelativeZero();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(rz);
|
||||
//drawSnapper();
|
||||
|
||||
RS_DEBUG->print("RS_ActionDimLeader::trigger(): leader added: %d",
|
||||
leader->getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimLeader::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDimLeader::mouseMoveEvent begin");
|
||||
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
if (getStatus()==SetEndpoint && pPoints->points.size()) {
|
||||
deletePreview();
|
||||
|
||||
// fill in lines that were already set:
|
||||
RS_Vector last(false);
|
||||
for(const auto& v: pPoints->points){
|
||||
if (last.valid) {
|
||||
preview->addEntity(new RS_Line{preview.get(), last, v});
|
||||
}
|
||||
last = v;
|
||||
}
|
||||
|
||||
if (pPoints->points.size() ) {
|
||||
RS_Vector const& p = pPoints->points.back();
|
||||
preview->addEntity(new RS_Line{preview.get(), p, mouse});
|
||||
}
|
||||
drawPreview();
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDimLeader::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimLeader::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
if (getStatus()==SetEndpoint) {
|
||||
trigger();
|
||||
reset();
|
||||
setStatus(SetStartpoint);
|
||||
} else {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimLeader::keyPressEvent(QKeyEvent* e) {
|
||||
if (getStatus()==SetEndpoint && e->key()==Qt::Key_Enter) {
|
||||
trigger();
|
||||
reset();
|
||||
setStatus(SetStartpoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimLeader::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetStartpoint:
|
||||
//data.startpoint = mouse;
|
||||
pPoints->points.clear();
|
||||
pPoints->points.push_back(mouse);
|
||||
//start = data.startpoint;
|
||||
setStatus(SetEndpoint);
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
break;
|
||||
|
||||
case SetEndpoint:
|
||||
//data.endpoint = mouse;
|
||||
pPoints->points.push_back(mouse);
|
||||
//trigger();
|
||||
//data.startpoint = data.endpoint;
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimLeader::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
// enter to finish
|
||||
if (c=="") {
|
||||
trigger();
|
||||
reset();
|
||||
setStatus(SetStartpoint);
|
||||
//finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDimLeader::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void RS_ActionDimLeader::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetStartpoint:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify target point"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetEndpoint:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify next point"),
|
||||
tr("Finish"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDimLeader::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
84
actions/rs_actiondimleader.h
Normal file
84
actions/rs_actiondimleader.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDIMLEADER_H
|
||||
#define RS_ACTIONDIMLEADER_H
|
||||
|
||||
#include<memory>
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
class RS_Leader;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw
|
||||
* leaders (arrows).
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDimLeader : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetStartpoint, /**< Setting the startpoint. */
|
||||
SetEndpoint /**< Setting the endpoint. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDimLeader(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDimLeader() override;
|
||||
|
||||
void reset();
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
void keyPressEvent(QKeyEvent*) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Leader entity.
|
||||
*/
|
||||
RS_Leader* leader;
|
||||
/**
|
||||
* Points set so far.
|
||||
*/
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
};
|
||||
|
||||
#endif
|
||||
332
actions/rs_actiondimlinear.cpp
Normal file
332
actions/rs_actiondimlinear.cpp
Normal file
@@ -0,0 +1,332 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
#include<cmath>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondimlinear.h"
|
||||
#include "rs_dimlinear.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_constructionline.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param angle Initial angle in rad.
|
||||
* @param fixedAngle true: The user can't change the angle.
|
||||
* false: The user can change the angle in a option widget.
|
||||
*/
|
||||
RS_ActionDimLinear::RS_ActionDimLinear(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView,
|
||||
double angle,
|
||||
bool _fixedAngle, RS2::ActionType /*type*/)
|
||||
:RS_ActionDimension("Draw linear dimensions",
|
||||
container, graphicView)
|
||||
,edata(new RS_DimLinearData(RS_Vector(0., 0.), RS_Vector(0., 0.), angle, 0.))
|
||||
,fixedAngle(_fixedAngle)
|
||||
,lastStatus(SetExtPoint1)
|
||||
{
|
||||
//TODO: fix dim linear type logic: whether it's for linear only, or should cover horizontal/vertical dim types
|
||||
actionType=RS2::ActionDimLinear;
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
RS_ActionDimLinear::~RS_ActionDimLinear() = default;
|
||||
|
||||
void RS_ActionDimLinear::reset() {
|
||||
RS_ActionDimension::reset();
|
||||
|
||||
edata.reset(new RS_DimLinearData(RS_Vector(false),
|
||||
RS_Vector(false),
|
||||
(fixedAngle ? edata->angle : 0.0), 0.0)
|
||||
);
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimLinear::trigger() {
|
||||
RS_ActionDimension::trigger();
|
||||
|
||||
preparePreview();
|
||||
RS_DimLinear* dim = new RS_DimLinear(container, *data, *edata);
|
||||
dim->setLayerToActive();
|
||||
dim->setPenToActive();
|
||||
dim->update();
|
||||
container->addEntity(dim);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(dim);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
RS_Vector rz = graphicView->getRelativeZero();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(rz);
|
||||
|
||||
RS_DEBUG->print("RS_ActionDimLinear::trigger():"
|
||||
" dim added: %d", dim->getId());
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDimLinear::preparePreview() {
|
||||
RS_Vector dirV = RS_Vector::polar(100., edata->angle+M_PI_2);
|
||||
|
||||
RS_ConstructionLine cl(
|
||||
NULL,
|
||||
RS_ConstructionLineData(
|
||||
edata->extensionPoint2,
|
||||
edata->extensionPoint2+dirV));
|
||||
|
||||
data->definitionPoint =
|
||||
cl.getNearestPointOnEntity(data->definitionPoint);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimLinear::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDimLinear::mouseMoveEvent begin");
|
||||
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetExtPoint1:
|
||||
break;
|
||||
|
||||
case SetExtPoint2:
|
||||
if (edata->extensionPoint1.valid) {
|
||||
deletePreview();
|
||||
preview->addEntity(new RS_Line{preview.get(),
|
||||
edata->extensionPoint1, mouse});
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
case SetDefPoint:
|
||||
if (edata->extensionPoint1.valid && edata->extensionPoint2.valid) {
|
||||
deletePreview();
|
||||
data->definitionPoint = mouse;
|
||||
|
||||
preparePreview();
|
||||
|
||||
RS_DimLinear* dim = new RS_DimLinear(preview.get(), *data, *edata);
|
||||
preview->addEntity(dim);
|
||||
dim->update();
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDimLinear::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimLinear::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimLinear::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (e==NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
RS_Vector pos = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetExtPoint1:
|
||||
edata->extensionPoint1 = pos;
|
||||
graphicView->moveRelativeZero(pos);
|
||||
setStatus(SetExtPoint2);
|
||||
break;
|
||||
|
||||
case SetExtPoint2:
|
||||
edata->extensionPoint2 = pos;
|
||||
graphicView->moveRelativeZero(pos);
|
||||
setStatus(SetDefPoint);
|
||||
break;
|
||||
|
||||
case SetDefPoint:
|
||||
data->definitionPoint = pos;
|
||||
trigger();
|
||||
reset();
|
||||
setStatus(SetExtPoint1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double RS_ActionDimLinear::getAngle() const{
|
||||
return edata->angle;
|
||||
}
|
||||
|
||||
void RS_ActionDimLinear::setAngle(double a) {
|
||||
edata->angle = a;
|
||||
}
|
||||
|
||||
bool RS_ActionDimLinear::hasFixedAngle() const{
|
||||
return fixedAngle;
|
||||
}
|
||||
|
||||
void RS_ActionDimLinear::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetText:
|
||||
setText(c);
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
graphicView->enableCoordinateInput();
|
||||
setStatus(lastStatus);
|
||||
break;
|
||||
|
||||
case SetAngle: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
setAngle(RS_Math::deg2rad(a));
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
lastStatus = (Status)getStatus();
|
||||
deletePreview();
|
||||
if (checkCommand("text", c)) {
|
||||
graphicView->disableCoordinateInput();
|
||||
setStatus(SetText);
|
||||
return;
|
||||
} else if (!fixedAngle && (checkCommand("angle", c))) {
|
||||
setStatus(SetAngle);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDimLinear::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetExtPoint1:
|
||||
case SetExtPoint2:
|
||||
case SetDefPoint:
|
||||
cmd += command("text");
|
||||
if (!fixedAngle) {
|
||||
cmd += command("angle");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDimLinear::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetExtPoint1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify first extension line origin"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetExtPoint2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify second extension line origin"),
|
||||
tr("Back"));
|
||||
break;
|
||||
case SetDefPoint:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify dimension line location"),
|
||||
tr("Back"));
|
||||
break;
|
||||
case SetText:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter dimension text:"), "");
|
||||
break;
|
||||
case SetAngle:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Enter dimension line angle:"), "");
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimLinear::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimLinear::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// EOF
|
||||
107
actions/rs_actiondimlinear.h
Normal file
107
actions/rs_actiondimlinear.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDIMLINEAR_H
|
||||
#define RS_ACTIONDIMLINEAR_H
|
||||
|
||||
#include "rs_actiondimension.h"
|
||||
|
||||
struct RS_DimLinearData;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw
|
||||
* aligned dimensions.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDimLinear : public RS_ActionDimension {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Varitions of this action.
|
||||
*/
|
||||
enum Variation {
|
||||
AnyAngle,
|
||||
Horizontal,
|
||||
Vertical
|
||||
};
|
||||
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetExtPoint1, /**< Setting the 1st ext point. */
|
||||
SetExtPoint2, /**< Setting the 2nd ext point. */
|
||||
SetDefPoint, /**< Setting the common def point. */
|
||||
SetText, /**< Setting the text label in the command line. */
|
||||
SetAngle /**< Setting the angle in the command line. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDimLinear(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView,
|
||||
double angle=0.0, bool fixedAngle=false,
|
||||
RS2::ActionType type = RS2::ActionDimLinear);
|
||||
~RS_ActionDimLinear() override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
void trigger() override;
|
||||
void preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
|
||||
double getAngle() const;
|
||||
|
||||
void setAngle(double a);
|
||||
|
||||
bool hasFixedAngle() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Aligned dimension data.
|
||||
*/
|
||||
std::unique_ptr<RS_DimLinearData> edata;
|
||||
/**
|
||||
* Is the angle fixed?
|
||||
*/
|
||||
bool fixedAngle;
|
||||
|
||||
/** Last status before entering text or angle. */
|
||||
Status lastStatus;
|
||||
};
|
||||
|
||||
#endif
|
||||
317
actions/rs_actiondimradial.cpp
Normal file
317
actions/rs_actiondimradial.cpp
Normal file
@@ -0,0 +1,317 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondimradial.h"
|
||||
|
||||
#include "rs_dimradial.h"
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_arc.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
|
||||
RS_ActionDimRadial::RS_ActionDimRadial(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_ActionDimension("Draw Radial Dimensions",
|
||||
container, graphicView)
|
||||
,entity(nullptr)
|
||||
,pos(new RS_Vector{})
|
||||
,lastStatus(SetEntity)
|
||||
{
|
||||
actionType=RS2::ActionDimRadial;
|
||||
reset();
|
||||
}
|
||||
|
||||
RS_ActionDimRadial::~RS_ActionDimRadial() = default;
|
||||
|
||||
void RS_ActionDimRadial::reset() {
|
||||
RS_ActionDimension::reset();
|
||||
|
||||
edata.reset(new RS_DimRadialData{{}, 0.0});
|
||||
entity = nullptr;
|
||||
*pos = {};
|
||||
lastStatus = SetEntity;
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimRadial::trigger() {
|
||||
RS_ActionDimension::trigger();
|
||||
|
||||
preparePreview();
|
||||
if (entity) {
|
||||
RS_DimRadial* newEntity = nullptr;
|
||||
|
||||
newEntity = new RS_DimRadial(container,
|
||||
*data,
|
||||
*edata);
|
||||
|
||||
newEntity->setLayerToActive();
|
||||
newEntity->setPenToActive();
|
||||
newEntity->update();
|
||||
container->addEntity(newEntity);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(newEntity);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
RS_Vector rz = graphicView->getRelativeZero();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(rz);
|
||||
RS_Snapper::finish();
|
||||
|
||||
}
|
||||
else {
|
||||
RS_DEBUG->print("RS_ActionDimRadial::trigger:"
|
||||
" Entity is nullptr\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDimRadial::preparePreview() {
|
||||
if (entity) {
|
||||
double angle = data->definitionPoint.angleTo(*pos);
|
||||
double radius=0.0;
|
||||
if (entity->rtti()==RS2::EntityArc) {
|
||||
radius = ((RS_Arc*)entity)->getRadius();
|
||||
} else if (entity->rtti()==RS2::EntityCircle) {
|
||||
radius = ((RS_Circle*)entity)->getRadius();
|
||||
}
|
||||
|
||||
edata->definitionPoint.setPolar(radius, angle);
|
||||
edata->definitionPoint += data->definitionPoint;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimRadial::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDimRadial::mouseMoveEvent begin");
|
||||
|
||||
//RS_Vector mouse(graphicView->toGraphX(e->x()),
|
||||
// graphicView->toGraphY(e->y()));
|
||||
|
||||
switch (getStatus()) {
|
||||
|
||||
case SetPos:
|
||||
if (entity) {
|
||||
*pos = snapPoint(e);
|
||||
|
||||
preparePreview();
|
||||
|
||||
RS_DimRadial* d = new RS_DimRadial(preview.get(), *data, *edata);
|
||||
|
||||
deletePreview();
|
||||
preview->addEntity(d);
|
||||
d->update();
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDimRadial::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimRadial::mouseReleaseEvent(QMouseEvent* e) {
|
||||
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
switch (getStatus()) {
|
||||
case SetEntity: {
|
||||
RS_Entity* en = catchEntity(e, RS2::ResolveAll);
|
||||
if (en) {
|
||||
if (en->rtti()==RS2::EntityArc ||
|
||||
en->rtti()==RS2::EntityCircle) {
|
||||
entity = en;
|
||||
if (entity->rtti()==RS2::EntityArc) {
|
||||
data->definitionPoint =
|
||||
static_cast<RS_Arc*>(entity)->getCenter();
|
||||
} else if (entity->rtti()==RS2::EntityCircle) {
|
||||
data->definitionPoint =
|
||||
static_cast<RS_Circle*>(entity)->getCenter();
|
||||
}
|
||||
graphicView->moveRelativeZero(data->definitionPoint);
|
||||
setStatus(SetPos);
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a circle "
|
||||
"or arc entity"));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SetPos: {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimRadial::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e) return;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPos:
|
||||
*pos = e->getCoordinate();
|
||||
trigger();
|
||||
reset();
|
||||
setStatus(SetEntity);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimRadial::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
// setting new text label:
|
||||
if (getStatus()==SetText) {
|
||||
setText(c);
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
graphicView->enableCoordinateInput();
|
||||
setStatus(lastStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
// command: text
|
||||
if (checkCommand("text", c)) {
|
||||
lastStatus = (Status)getStatus();
|
||||
graphicView->disableCoordinateInput();
|
||||
setStatus(SetText);
|
||||
}
|
||||
|
||||
// setting angle
|
||||
if (getStatus()==SetPos) {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
pos->setPolar(1.0, RS_Math::deg2rad(a));
|
||||
*pos += data->definitionPoint;
|
||||
trigger();
|
||||
reset();
|
||||
setStatus(SetEntity);
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDimRadial::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetEntity:
|
||||
case SetPos:
|
||||
cmd += command("text");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDimRadial::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetEntity:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Select arc or circle entity"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetPos:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify dimension line position or enter angle:"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetText:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter dimension text:"), "");
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimRadial::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
//RS_DIALOGFACTORY->requestDimRadialOptions(edata, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDimRadial::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
//RS_DIALOGFACTORY->requestDimRadialOptions(edata, false);
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// EOF
|
||||
83
actions/rs_actiondimradial.h
Normal file
83
actions/rs_actiondimradial.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDIMRADIAL_H
|
||||
#define RS_ACTIONDIMRADIAL_H
|
||||
|
||||
#include "rs_actiondimension.h"
|
||||
|
||||
struct RS_DimRadialData;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw radial dimensions.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDimRadial : public RS_ActionDimension {
|
||||
Q_OBJECT
|
||||
private:
|
||||
enum Status {
|
||||
SetEntity, /**< Choose entity. */
|
||||
SetPos, /**< Choose point. */
|
||||
SetText /**< Setting text label in the command line. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDimRadial(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDimRadial() override;
|
||||
|
||||
|
||||
void reset() override;
|
||||
|
||||
void trigger() override;
|
||||
void preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
|
||||
|
||||
private:
|
||||
/** Chosen entity (arc / circle) */
|
||||
RS_Entity* entity;
|
||||
/** Chosen position */
|
||||
std::unique_ptr<RS_Vector> pos;
|
||||
/** Data of new dimension */
|
||||
std::unique_ptr<RS_DimRadialData> edata;
|
||||
/** Last status before entering text. */
|
||||
Status lastStatus;
|
||||
};
|
||||
|
||||
#endif
|
||||
405
actions/rs_actiondrawarc.cpp
Normal file
405
actions/rs_actiondrawarc.cpp
Normal file
@@ -0,0 +1,405 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
#include<cmath>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawarc.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commands.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_arc.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
RS_ActionDrawArc::RS_ActionDrawArc(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw arcs",
|
||||
container, graphicView)
|
||||
,data(new RS_ArcData())
|
||||
{
|
||||
actionType= RS2::ActionDrawArc;
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
RS_ActionDrawArc::~RS_ActionDrawArc() = default;
|
||||
|
||||
void RS_ActionDrawArc::reset() {
|
||||
|
||||
if (data->reversed) {
|
||||
data.reset(new RS_ArcData(RS_Vector(false),
|
||||
0.0,
|
||||
2.*M_PI, 0.0,
|
||||
true));
|
||||
} else {
|
||||
data.reset(new RS_ArcData(RS_Vector(false),
|
||||
0.0,
|
||||
0.0, 2.*M_PI,
|
||||
false));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
RS_Arc* arc = new RS_Arc(container,
|
||||
*data);
|
||||
arc->setLayerToActive();
|
||||
arc->setPenToActive();
|
||||
container->addEntity(arc);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(arc);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(arc->getCenter());
|
||||
|
||||
setStatus(SetCenter);
|
||||
reset();
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawArc::trigger(): arc added: %d",
|
||||
arc->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawArc::mouseMoveEvent begin");
|
||||
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
data->center = mouse;
|
||||
break;
|
||||
|
||||
case SetRadius:
|
||||
if (data->center.valid) {
|
||||
data->radius = data->center.distanceTo(mouse);
|
||||
deletePreview();
|
||||
preview->addEntity(new RS_Circle(preview.get(),
|
||||
{data->center, data->radius}));
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle1:
|
||||
data->angle1 = data->center.angleTo(mouse);
|
||||
if (data->reversed) {
|
||||
data->angle2 = RS_Math::correctAngle(data->angle1-M_PI/3);
|
||||
} else {
|
||||
data->angle2 = RS_Math::correctAngle(data->angle1+M_PI/3);
|
||||
}
|
||||
deletePreview();
|
||||
preview->addEntity(new RS_Arc(preview.get(),
|
||||
*data));
|
||||
drawPreview();
|
||||
break;
|
||||
|
||||
case SetAngle2:
|
||||
data->angle2 = data->center.angleTo(mouse);
|
||||
deletePreview();
|
||||
preview->addEntity(new RS_Arc(preview.get(),
|
||||
*data));
|
||||
drawPreview();
|
||||
break;
|
||||
|
||||
case SetIncAngle:
|
||||
data->angle2 = data->angle1 + data->center.angleTo(mouse);
|
||||
deletePreview();
|
||||
preview->addEntity(new RS_Arc(preview.get(),
|
||||
*data));
|
||||
drawPreview();
|
||||
break;
|
||||
|
||||
case SetChordLength: {
|
||||
double x = data->center.distanceTo(mouse);
|
||||
if (fabs(x/(2*data->radius))<=1.0) {
|
||||
data->angle2 = data->angle1 + asin(x/(2*data->radius)) * 2;
|
||||
deletePreview();
|
||||
preview->addEntity(new RS_Arc(preview.get(),
|
||||
*data));
|
||||
drawPreview();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawArc::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e) return;
|
||||
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
data->center = mouse;
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
setStatus(SetRadius);
|
||||
break;
|
||||
|
||||
case SetRadius:
|
||||
if (data->center.valid) {
|
||||
data->radius = data->center.distanceTo(mouse);
|
||||
}
|
||||
setStatus(SetAngle1);
|
||||
break;
|
||||
|
||||
case SetAngle1:
|
||||
data->angle1 = data->center.angleTo(mouse);
|
||||
setStatus(SetAngle2);
|
||||
break;
|
||||
|
||||
case SetAngle2:
|
||||
data->angle2 = data->center.angleTo(mouse);
|
||||
trigger();
|
||||
break;
|
||||
|
||||
case SetIncAngle:
|
||||
data->angle2 = data->angle1 + data->center.angleTo(mouse);
|
||||
trigger();
|
||||
break;
|
||||
|
||||
case SetChordLength: {
|
||||
double x = data->center.distanceTo(mouse);
|
||||
if (fabs(x/(2*data->radius))<=1.0) {
|
||||
data->angle2 = data->angle1 + asin(x/(2*data->radius)) * 2;
|
||||
trigger();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (RS_COMMANDS->checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
if (RS_COMMANDS->checkCommand("reversed", c)) {
|
||||
e->accept();
|
||||
setReversed(!isReversed());
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
|
||||
case SetRadius: {
|
||||
bool ok;
|
||||
double r = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
data->radius = r;
|
||||
setStatus(SetAngle1);
|
||||
e->accept();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle1: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
data->angle1 = RS_Math::deg2rad(a);
|
||||
e->accept();
|
||||
setStatus(SetAngle2);
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle2: {
|
||||
if (RS_COMMANDS->checkCommand("angle", c)) {
|
||||
setStatus(SetIncAngle);
|
||||
} else if (RS_COMMANDS->checkCommand("chord length", c)) {
|
||||
setStatus(SetChordLength);
|
||||
} else {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
data->angle2 = RS_Math::deg2rad(a);
|
||||
e->accept();
|
||||
trigger();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SetIncAngle: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
data->angle2 = data->angle1 + RS_Math::deg2rad(a);
|
||||
e->accept();
|
||||
trigger();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetChordLength: {
|
||||
bool ok;
|
||||
double l = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
if (fabs(l/(2*data->radius))<=1.0) {
|
||||
data->angle2 = data->angle1 + asin(l/(2*data->radius)) * 2;
|
||||
trigger();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid chord length"));
|
||||
e->accept();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDrawArc::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
cmd += RS_COMMANDS->command("reversed");
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawArc::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify center"), tr("Cancel"));
|
||||
break;
|
||||
case SetRadius:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify radius"), tr("Back"));
|
||||
break;
|
||||
case SetAngle1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify start angle:"), tr("Back"));
|
||||
break;
|
||||
case SetAngle2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify end angle or [angle/chord length]"),
|
||||
tr("Back"));
|
||||
break;
|
||||
case SetIncAngle:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify included angle:"),
|
||||
tr("Back"));
|
||||
break;
|
||||
case SetChordLength:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify chord length:"),
|
||||
tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
|
||||
bool RS_ActionDrawArc::isReversed() const{
|
||||
return data->reversed;
|
||||
}
|
||||
|
||||
void RS_ActionDrawArc::setReversed(bool r) const{
|
||||
data->reversed = r;
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
||||
96
actions/rs_actiondrawarc.h
Normal file
96
actions/rs_actiondrawarc.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWARC_H
|
||||
#define RS_ACTIONDRAWARC_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
struct RS_ArcData;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw
|
||||
* simple arcs with the center, radius, start- and endangle given.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawArc : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetCenter, /**< Setting the center point. */
|
||||
SetRadius, /**< Setting the radius. */
|
||||
SetAngle1, /**< Setting the startpoint. */
|
||||
SetAngle2, /**< Setting the endpoint. */
|
||||
SetIncAngle, /**< Setting the included angle. */
|
||||
SetChordLength /**< Setting carc chord length. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawArc(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawArc() override;
|
||||
|
||||
void reset();
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
bool isReversed() const;
|
||||
|
||||
void setReversed(bool r) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Arc data defined so far.
|
||||
*/
|
||||
std::unique_ptr<RS_ArcData> data;
|
||||
/**
|
||||
* Commands
|
||||
*/
|
||||
/*QString cmdReversed;
|
||||
QString cmdReversed2;
|
||||
QString cmdReversed3;
|
||||
*/
|
||||
};
|
||||
|
||||
#endif
|
||||
262
actions/rs_actiondrawarc3p.cpp
Normal file
262
actions/rs_actiondrawarc3p.cpp
Normal file
@@ -0,0 +1,262 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawarc3p.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_actiondrawarc.h"
|
||||
#include "rs_commands.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_arc.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
|
||||
struct RS_ActionDrawArc3P::Points {
|
||||
RS_ArcData data;
|
||||
/**
|
||||
* 1st point.
|
||||
*/
|
||||
RS_Vector point1;
|
||||
/**
|
||||
* 2nd point.
|
||||
*/
|
||||
RS_Vector point2;
|
||||
/**
|
||||
* 3rd point.
|
||||
*/
|
||||
RS_Vector point3;
|
||||
};
|
||||
|
||||
RS_ActionDrawArc3P::RS_ActionDrawArc3P(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw arcs 3P",
|
||||
container, graphicView)
|
||||
, pPoints(new Points())
|
||||
{
|
||||
actionType=RS2::ActionDrawArc3P;
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
RS_ActionDrawArc3P::~RS_ActionDrawArc3P() = default;
|
||||
|
||||
|
||||
void RS_ActionDrawArc3P::reset() {
|
||||
pPoints.reset(new Points{});
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc3P::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
//reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc3P::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
preparePreview();
|
||||
if (pPoints->data.isValid()) {
|
||||
RS_Arc* arc = new RS_Arc{container, pPoints->data};
|
||||
arc->setLayerToActive();
|
||||
arc->setPenToActive();
|
||||
container->addEntity(arc);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(arc);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(arc->getEndpoint());
|
||||
|
||||
setStatus(SetPoint1);
|
||||
reset();
|
||||
} else {
|
||||
//RS_DIALOGFACTORY->requestWarningDialog(tr("Invalid arc data."));
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Invalid arc data."));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc3P::preparePreview() {
|
||||
pPoints->data = {};
|
||||
if (pPoints->point1.valid && pPoints->point2.valid && pPoints->point3.valid) {
|
||||
RS_Arc arc(NULL, pPoints->data);
|
||||
bool suc = arc.createFrom3P(pPoints->point1, pPoints->point2, pPoints->point3);
|
||||
if (suc) {
|
||||
pPoints->data = arc.getData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawArc3P::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
pPoints->point1 = mouse;
|
||||
break;
|
||||
|
||||
case SetPoint2:
|
||||
pPoints->point2 = mouse;
|
||||
if (pPoints->point1.valid) {
|
||||
RS_Line* line = new RS_Line{preview.get(), pPoints->point1, pPoints->point2};
|
||||
|
||||
deletePreview();
|
||||
preview->addEntity(line);
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
case SetPoint3:
|
||||
pPoints->point3 = mouse;
|
||||
preparePreview();
|
||||
if (pPoints->data.isValid()) {
|
||||
RS_Arc* arc = new RS_Arc(preview.get(), pPoints->data);
|
||||
|
||||
deletePreview();
|
||||
preview->addEntity(arc);
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc3P::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc3P::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (e==NULL) {
|
||||
return;
|
||||
}
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
pPoints->point1 = mouse;
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
setStatus(SetPoint2);
|
||||
break;
|
||||
|
||||
case SetPoint2:
|
||||
pPoints->point2 = mouse;
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
setStatus(SetPoint3);
|
||||
break;
|
||||
|
||||
case SetPoint3:
|
||||
pPoints->point3 = mouse;
|
||||
trigger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc3P::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
if (RS_COMMANDS->checkCommand("center", c, rtti())) {
|
||||
finish(false);
|
||||
graphicView->setCurrentAction(
|
||||
new RS_ActionDrawArc(*container, *graphicView));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDrawArc3P::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc3P::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify startpoint or [center]"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetPoint2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify second point"), tr("Back"));
|
||||
break;
|
||||
case SetPoint3:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify endpoint"), tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArc3P::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
||||
82
actions/rs_actiondrawarc3p.h
Normal file
82
actions/rs_actiondrawarc3p.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWARC3P_H
|
||||
#define RS_ACTIONDRAWARC3P_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
struct RS_ArcData;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw
|
||||
* arcs with three points given.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawArc3P : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetPoint1, /**< Setting the 1st point. */
|
||||
SetPoint2, /**< Setting the 2nd point. */
|
||||
SetPoint3 /**< Setting the 3rd point. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawArc3P(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawArc3P() override;
|
||||
|
||||
void reset();
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
void preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Arc data defined so far.
|
||||
*/
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
};
|
||||
|
||||
#endif
|
||||
286
actions/rs_actiondrawarctangential.cpp
Normal file
286
actions/rs_actiondrawarctangential.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
#include<cmath>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawarctangential.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_arc.h"
|
||||
#include "ui_qg_arctangentialoptions.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
|
||||
RS_ActionDrawArcTangential::RS_ActionDrawArcTangential(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw arcs tangential",
|
||||
container, graphicView)
|
||||
, point(new RS_Vector{})
|
||||
, data(new RS_ArcData{})
|
||||
{
|
||||
actionType=RS2::ActionDrawArcTangential;
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
RS_ActionDrawArcTangential::~RS_ActionDrawArcTangential() = default;
|
||||
|
||||
void RS_ActionDrawArcTangential::reset() {
|
||||
baseEntity = nullptr;
|
||||
isStartPoint = false;
|
||||
*point = {};
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArcTangential::setByRadius(bool status) {
|
||||
byRadius=status;
|
||||
}
|
||||
|
||||
void RS_ActionDrawArcTangential::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
//reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArcTangential::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
if (!(point->valid && baseEntity)) {
|
||||
RS_DEBUG->print("RS_ActionDrawArcTangential::trigger: "
|
||||
"conditions not met");
|
||||
return;
|
||||
}
|
||||
|
||||
preparePreview();
|
||||
RS_Arc* arc = new RS_Arc(container, *data);
|
||||
arc->setLayerToActive();
|
||||
arc->setPenToActive();
|
||||
container->addEntity(arc);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(arc);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(arc->getCenter());
|
||||
|
||||
setStatus(SetBaseEntity);
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArcTangential::preparePreview() {
|
||||
if (baseEntity && point->valid) {
|
||||
RS_Vector startPoint;
|
||||
double direction;
|
||||
if (isStartPoint) {
|
||||
startPoint = baseEntity->getStartpoint();
|
||||
direction = RS_Math::correctAngle(baseEntity->getDirection1()+M_PI);
|
||||
} else {
|
||||
startPoint = baseEntity->getEndpoint();
|
||||
direction = RS_Math::correctAngle(baseEntity->getDirection2()+M_PI);
|
||||
}
|
||||
|
||||
RS_Arc arc(nullptr, RS_ArcData());
|
||||
bool suc;
|
||||
if (byRadius) {
|
||||
suc = arc.createFrom2PDirectionRadius(startPoint, *point, direction, data->radius);
|
||||
} else {
|
||||
suc = arc.createFrom2PDirectionAngle(startPoint, *point, direction, angleLength);
|
||||
}
|
||||
if (suc) {
|
||||
data.reset(new RS_ArcData(arc.getData()));
|
||||
if (byRadius)
|
||||
RS_DIALOGFACTORY->updateArcTangentialOptions(arc.getAngleLength()*180./M_PI,true);
|
||||
else
|
||||
RS_DIALOGFACTORY->updateArcTangentialOptions(arc.getRadius(),false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawArcTangential::mouseMoveEvent(QMouseEvent* e) {
|
||||
if(getStatus() == SetEndAngle) {
|
||||
*point = snapPoint(e);
|
||||
preparePreview();
|
||||
if (data->isValid()) {
|
||||
RS_Arc* arc = new RS_Arc(preview.get(), *data);
|
||||
deletePreview();
|
||||
preview->addEntity(arc);
|
||||
drawPreview();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArcTangential::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
switch (getStatus()) {
|
||||
|
||||
// set base entity:
|
||||
case SetBaseEntity: {
|
||||
RS_Vector coord = graphicView->toGraph(e->x(), e->y());
|
||||
RS_Entity* entity = catchEntity(coord, RS2::ResolveAll);
|
||||
if (entity) {
|
||||
if (entity->isAtomic()) {
|
||||
baseEntity = static_cast<RS_AtomicEntity*>(entity);
|
||||
if (baseEntity->getStartpoint().distanceTo(coord) <
|
||||
baseEntity->getEndpoint().distanceTo(coord)) {
|
||||
isStartPoint = true;
|
||||
} else {
|
||||
isStartPoint = false;
|
||||
}
|
||||
setStatus(SetEndAngle);
|
||||
updateMouseButtonHints();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// set angle (point that defines the angle)
|
||||
case SetEndAngle: {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArcTangential::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (e==nullptr) {
|
||||
return;
|
||||
}
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetBaseEntity:
|
||||
break;
|
||||
|
||||
case SetEndAngle:
|
||||
*point = mouse;
|
||||
trigger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArcTangential::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDrawArcTangential::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawArcTangential::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
updateMouseButtonHints();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArcTangential::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArcTangential::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetBaseEntity:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify base entity"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetEndAngle:
|
||||
if(byRadius) {
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify end angle"), tr("Back"));
|
||||
} else {
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify end point"), tr("Back"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawArcTangential::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawArcTangential::setRadius(double r){
|
||||
data->radius = r;
|
||||
}
|
||||
|
||||
double RS_ActionDrawArcTangential::getRadius() const {
|
||||
return data->radius;
|
||||
}
|
||||
|
||||
// EOF
|
||||
114
actions/rs_actiondrawarctangential.h
Normal file
114
actions/rs_actiondrawarctangential.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWARCTANGENTIAL_H
|
||||
#define RS_ACTIONDRAWARCTANGENTIAL_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
class RS_AtomicEntity;
|
||||
struct RS_ArcData;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw
|
||||
* arcs with three points given.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawArcTangential : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetBaseEntity, /**< Setting base entity. */
|
||||
SetEndAngle /**< Setting end angle. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawArcTangential(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawArcTangential() override;
|
||||
|
||||
void reset();
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
void preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
void setRadius(double r);
|
||||
|
||||
double getRadius() const;
|
||||
void setAngle(double r) {
|
||||
angleLength= r;
|
||||
}
|
||||
|
||||
double getAngle() const {
|
||||
return angleLength;
|
||||
}
|
||||
void setByRadius(bool status=true);
|
||||
bool getByRadius() const{
|
||||
return byRadius;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Base entity.
|
||||
*/
|
||||
RS_AtomicEntity* baseEntity;
|
||||
/**
|
||||
* Start point of base entity clicked?
|
||||
*/
|
||||
bool isStartPoint;
|
||||
/**
|
||||
* Point that determines end angle.
|
||||
*/
|
||||
std::unique_ptr<RS_Vector> point;
|
||||
/**
|
||||
* Arc data calculated.
|
||||
*/
|
||||
std::unique_ptr<RS_ArcData> data;
|
||||
private:
|
||||
double angleLength;
|
||||
bool byRadius;
|
||||
};
|
||||
|
||||
#endif
|
||||
231
actions/rs_actiondrawcircle.cpp
Normal file
231
actions/rs_actiondrawcircle.cpp
Normal file
@@ -0,0 +1,231 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawcircle.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
RS_ActionDrawCircle::RS_ActionDrawCircle(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw circles",
|
||||
container, graphicView)
|
||||
,data(new RS_CircleData())
|
||||
{
|
||||
actionType=RS2::ActionDrawCircle;
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
RS_ActionDrawCircle::~RS_ActionDrawCircle() = default;
|
||||
|
||||
void RS_ActionDrawCircle::reset() {
|
||||
data.reset(new RS_CircleData{});
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
RS_Circle* circle = new RS_Circle(container,
|
||||
*data);
|
||||
circle->setLayerToActive();
|
||||
circle->setPenToActive();
|
||||
container->addEntity(circle);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(circle);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(circle->getCenter());
|
||||
|
||||
setStatus(SetCenter);
|
||||
reset();
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawCircle::trigger(): circle added: %d",
|
||||
circle->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawCircle::mouseMoveEvent begin");
|
||||
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
data->center = mouse;
|
||||
break;
|
||||
|
||||
case SetRadius:
|
||||
if (data->center.valid) {
|
||||
data->radius = data->center.distanceTo(mouse);
|
||||
deletePreview();
|
||||
preview->addEntity(new RS_Circle(preview.get(),
|
||||
*data));
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawCircle::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e){
|
||||
return;
|
||||
}
|
||||
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
data->center = mouse;
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
setStatus(SetRadius);
|
||||
break;
|
||||
|
||||
case SetRadius:
|
||||
if (data->center.valid) {
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
data->radius = data->center.distanceTo(mouse);
|
||||
trigger();
|
||||
}
|
||||
//setStatus(SetCenter);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
|
||||
case SetRadius: {
|
||||
bool ok;
|
||||
double r = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
data->radius = r;
|
||||
e->accept();
|
||||
trigger();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
//setStatus(SetCenter);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDrawCircle::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircle::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify center"), tr("Cancel"));
|
||||
break;
|
||||
case SetRadius:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify point on circle"), tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
||||
82
actions/rs_actiondrawcircle.h
Normal file
82
actions/rs_actiondrawcircle.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWCIRCLE_H
|
||||
#define RS_ACTIONDRAWCIRCLE_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
struct RS_CircleData;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw
|
||||
* circles with a given center and a point on the circle line.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawCircle : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetCenter, /**< Setting the center point. */
|
||||
SetRadius /**< Setting the radius. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawCircle(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawCircle() override;
|
||||
|
||||
void reset();
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Circle data defined so far.
|
||||
*/
|
||||
std::unique_ptr<RS_CircleData> data;
|
||||
};
|
||||
|
||||
#endif
|
||||
227
actions/rs_actiondrawcircle2p.cpp
Normal file
227
actions/rs_actiondrawcircle2p.cpp
Normal file
@@ -0,0 +1,227 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawcircle2p.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
|
||||
struct RS_ActionDrawCircle2P::Points {
|
||||
/**
|
||||
* 1st point.
|
||||
*/
|
||||
RS_Vector point1;
|
||||
/**
|
||||
* 2nd point.
|
||||
*/
|
||||
RS_Vector point2;
|
||||
};
|
||||
|
||||
RS_ActionDrawCircle2P::RS_ActionDrawCircle2P(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw circles",
|
||||
container, graphicView)
|
||||
, data(new RS_CircleData())
|
||||
, pPoints(new Points{})
|
||||
{
|
||||
actionType=RS2::ActionDrawCircle2P;
|
||||
reset();
|
||||
}
|
||||
|
||||
RS_ActionDrawCircle2P::~RS_ActionDrawCircle2P() = default;
|
||||
|
||||
void RS_ActionDrawCircle2P::reset() {
|
||||
data.reset(new RS_CircleData{});
|
||||
pPoints->point1 = {};
|
||||
pPoints->point2 = {};
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle2P::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle2P::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
preparePreview();
|
||||
if (data->isValid()) {
|
||||
RS_Circle* circle = new RS_Circle(container,
|
||||
*data);
|
||||
circle->setLayerToActive();
|
||||
circle->setPenToActive();
|
||||
container->addEntity(circle);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(circle);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
RS_Vector rz = graphicView->getRelativeZero();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(rz);
|
||||
|
||||
setStatus(SetPoint1);
|
||||
reset();
|
||||
} else
|
||||
RS_DIALOGFACTORY->requestWarningDialog(tr("Invalid Circle data."));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle2P::preparePreview() {
|
||||
data.reset(new RS_CircleData{});
|
||||
if (pPoints->point1.valid && pPoints->point2.valid) {
|
||||
RS_Circle circle(nullptr, *data);
|
||||
bool suc = circle.createFrom2P(pPoints->point1, pPoints->point2);
|
||||
if (suc) {
|
||||
data.reset(new RS_CircleData(circle.getData()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircle2P::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
pPoints->point1 = mouse;
|
||||
break;
|
||||
|
||||
case SetPoint2:
|
||||
pPoints->point2 = mouse;
|
||||
preparePreview();
|
||||
if (data->isValid()) {
|
||||
RS_Circle* circle = new RS_Circle(preview.get(), *data);
|
||||
deletePreview();
|
||||
preview->addEntity(circle);
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle2P::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle2P::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (e==NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
pPoints->point1 = mouse;
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
setStatus(SetPoint2);
|
||||
break;
|
||||
|
||||
case SetPoint2:
|
||||
pPoints->point2 = mouse;
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
trigger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle2P::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDrawCircle2P::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle2P::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify first point"), tr("Cancel"));
|
||||
break;
|
||||
case SetPoint2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify second point"), tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle2P::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
||||
82
actions/rs_actiondrawcircle2p.h
Normal file
82
actions/rs_actiondrawcircle2p.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWCIRCLE2P_H
|
||||
#define RS_ACTIONDRAWCIRCLE2P_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
struct RS_CircleData;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw
|
||||
* simple arcs with the center, radius, start- and endangle given.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawCircle2P : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetPoint1, /**< Setting the 1st point. */
|
||||
SetPoint2 /**< Setting the 2nd point. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawCircle2P(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawCircle2P() override;
|
||||
|
||||
void reset();
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
void preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Circle data defined so far.
|
||||
*/
|
||||
std::unique_ptr<RS_CircleData> data;
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
};
|
||||
|
||||
#endif
|
||||
232
actions/rs_actiondrawcircle3p.cpp
Normal file
232
actions/rs_actiondrawcircle3p.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawcircle3p.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
|
||||
struct RS_ActionDrawCircle3P::Points {
|
||||
RS_CircleData data;
|
||||
/**
|
||||
* 1st point.
|
||||
*/
|
||||
RS_Vector point1;
|
||||
/**
|
||||
* 2nd point.
|
||||
*/
|
||||
RS_Vector point2;
|
||||
/**
|
||||
* 3rd point.
|
||||
*/
|
||||
RS_Vector point3;
|
||||
};
|
||||
|
||||
|
||||
RS_ActionDrawCircle3P::RS_ActionDrawCircle3P(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw circles",
|
||||
container, graphicView)
|
||||
,pPoints(new Points{})
|
||||
{
|
||||
actionType=RS2::ActionDrawCircle3P;
|
||||
}
|
||||
|
||||
RS_ActionDrawCircle3P::~RS_ActionDrawCircle3P() = default;
|
||||
|
||||
void RS_ActionDrawCircle3P::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
pPoints.reset(new Points{});
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle3P::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
preparePreview();
|
||||
if (pPoints->data.isValid()) {
|
||||
RS_Circle* circle = new RS_Circle{container, pPoints->data};
|
||||
circle->setLayerToActive();
|
||||
circle->setPenToActive();
|
||||
container->addEntity(circle);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(circle);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
RS_Vector rz = graphicView->getRelativeZero();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(rz);
|
||||
drawSnapper();
|
||||
|
||||
setStatus(SetPoint1);
|
||||
pPoints.reset(new Points{});
|
||||
} else
|
||||
RS_DIALOGFACTORY->requestWarningDialog(tr("Invalid circle data."));
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircle3P::preparePreview() {
|
||||
pPoints->data = RS_CircleData{};
|
||||
if (pPoints->point1.valid && pPoints->point2.valid && pPoints->point3.valid) {
|
||||
RS_Circle circle{nullptr, pPoints->data};
|
||||
bool suc = circle.createFrom3P(pPoints->point1,
|
||||
pPoints->point2,
|
||||
pPoints->point3);
|
||||
if (suc) {
|
||||
pPoints->data = circle.getData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle3P::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
pPoints->point1 = mouse;
|
||||
break;
|
||||
|
||||
case SetPoint2:
|
||||
pPoints->point2 = mouse;
|
||||
break;
|
||||
|
||||
case SetPoint3:
|
||||
pPoints->point3 = mouse;
|
||||
preparePreview();
|
||||
if (pPoints->data.isValid()) {
|
||||
RS_Circle* circle = new RS_Circle{preview.get(), pPoints->data};
|
||||
|
||||
deletePreview();
|
||||
preview->addEntity(circle);
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle3P::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle3P::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (e==nullptr) {
|
||||
return;
|
||||
}
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
pPoints->point1 = mouse;
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
setStatus(SetPoint2);
|
||||
break;
|
||||
|
||||
case SetPoint2:
|
||||
pPoints->point2 = mouse;
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
setStatus(SetPoint3);
|
||||
break;
|
||||
|
||||
case SetPoint3:
|
||||
pPoints->point3 = mouse;
|
||||
trigger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle3P::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDrawCircle3P::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircle3P::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetPoint2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify second point"),
|
||||
tr("Back"));
|
||||
break;
|
||||
case SetPoint3:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify third point"),
|
||||
tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircle3P::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
||||
81
actions/rs_actiondrawcircle3p.h
Normal file
81
actions/rs_actiondrawcircle3p.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWCIRCLE3P_H
|
||||
#define RS_ACTIONDRAWCIRCLE3P_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
struct RS_CircleData;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw
|
||||
* circles with three points given.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawCircle3P : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetPoint1, /**< Setting the 1st point. */
|
||||
SetPoint2, /**< Setting the 2nd point. */
|
||||
SetPoint3 /**< Setting the 3rd point. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawCircle3P(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawCircle3P() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
void preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Circle data defined so far.
|
||||
*/
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
258
actions/rs_actiondrawcirclecr.cpp
Normal file
258
actions/rs_actiondrawcirclecr.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawcirclecr.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
RS_ActionDrawCircleCR::RS_ActionDrawCircleCR(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw circles CR",
|
||||
container, graphicView)
|
||||
,data(new RS_CircleData())
|
||||
{
|
||||
actionType=RS2::ActionDrawCircleCR;
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
RS_ActionDrawCircleCR::~RS_ActionDrawCircleCR() = default;
|
||||
|
||||
|
||||
void RS_ActionDrawCircleCR::reset() {
|
||||
data.reset(new RS_CircleData{RS_Vector{false}, 0.0});
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleCR::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleCR::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
RS_Circle* circle = new RS_Circle(container,
|
||||
*data);
|
||||
circle->setLayerToActive();
|
||||
circle->setPenToActive();
|
||||
|
||||
switch(getStatus()) {
|
||||
case SetCenter:
|
||||
container->addEntity(circle);
|
||||
graphicView->moveRelativeZero(circle->getCenter());
|
||||
break;
|
||||
case SetRadius:
|
||||
break;
|
||||
}
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(circle);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
|
||||
setStatus(SetCenter);
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawCircleCR::trigger(): circle added: %d",
|
||||
circle->getId());
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleCR::setRadius(double r)
|
||||
{
|
||||
if(r>RS_TOLERANCE){
|
||||
data->radius=r;
|
||||
}else{
|
||||
RS_DIALOGFACTORY->commandMessage(tr("radius=%1 is invalid").arg(r));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircleCR::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawCircleCR::mouseMoveEvent begin");
|
||||
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
data->center = mouse;
|
||||
deletePreview();
|
||||
preview->addEntity(new RS_Circle(preview.get(),
|
||||
*data));
|
||||
drawPreview();
|
||||
break;
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawCircleCR::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleCR::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleCR::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (e==NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
data->center = mouse;
|
||||
trigger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleCR::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
if (checkCommand("radius", c)) {
|
||||
deletePreview();
|
||||
setStatus(SetRadius);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetRadius: {
|
||||
bool ok;
|
||||
double r = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
data->radius = r;
|
||||
e->accept();
|
||||
trigger();
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDrawCircleCR::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
cmd += command("radius");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleCR::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify circle center"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetRadius:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify circle radius"),
|
||||
tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleCR::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleCR::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleCR::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
|
||||
double RS_ActionDrawCircleCR::getRadius() const{
|
||||
return data->radius;
|
||||
}
|
||||
// EOF
|
||||
|
||||
87
actions/rs_actiondrawcirclecr.h
Normal file
87
actions/rs_actiondrawcirclecr.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWCIRCLECR_H
|
||||
#define RS_ACTIONDRAWCIRCLECR_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
struct RS_CircleData;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw
|
||||
* simple arcs with the center, radius, start- and endangle given.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawCircleCR : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetCenter, /**< Setting the center point. */
|
||||
SetRadius /**< Setting radius in command line. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawCircleCR(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawCircleCR() override;
|
||||
|
||||
void reset();
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
double getRadius() const;
|
||||
|
||||
void setRadius(double r);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Circle data defined so far.
|
||||
*/
|
||||
std::unique_ptr<RS_CircleData> data;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
303
actions/rs_actiondrawcircleinscribe.cpp
Normal file
303
actions/rs_actiondrawcircleinscribe.cpp
Normal file
@@ -0,0 +1,303 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw circle by foci and a point on circle
|
||||
|
||||
Copyright (C) 2011 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
#include<vector>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawcircleinscribe.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawCircleInscribe::Points {
|
||||
RS_CircleData cData;
|
||||
RS_Vector coord;
|
||||
std::vector<RS_Line*> lines;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
RS_ActionDrawCircleInscribe::RS_ActionDrawCircleInscribe(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw circle inscribed",
|
||||
container, graphicView)
|
||||
, pPoints(new Points{})
|
||||
, valid(false)
|
||||
{
|
||||
actionType=RS2::ActionDrawCircleInscribe;
|
||||
}
|
||||
|
||||
RS_ActionDrawCircleInscribe::~RS_ActionDrawCircleInscribe() = default;
|
||||
|
||||
void RS_ActionDrawCircleInscribe::clearLines(bool checkStatus)
|
||||
{
|
||||
while(pPoints->lines.size() ){
|
||||
if(checkStatus && (int) pPoints->lines.size()<=getStatus() )
|
||||
break;
|
||||
pPoints->lines.back()->setHighlighted(false);
|
||||
graphicView->drawEntity(pPoints->lines.back());
|
||||
pPoints->lines.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircleInscribe::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
if(status>=0) {
|
||||
RS_Snapper::suspend();
|
||||
}
|
||||
clearLines(true);
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleInscribe::finish(bool updateTB){
|
||||
clearLines();
|
||||
RS_PreviewActionInterface::finish(updateTB);
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircleInscribe::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
|
||||
RS_Circle* circle=new RS_Circle(container, pPoints->cData);
|
||||
|
||||
deletePreview();
|
||||
container->addEntity(circle);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(circle);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
clearLines(false);
|
||||
|
||||
setStatus(SetLine1);
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawCircle4Line::trigger():"
|
||||
" entity added: %d", circle->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleInscribe::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawCircle4Line::mouseMoveEvent begin");
|
||||
|
||||
if(getStatus() == SetLine3) {
|
||||
RS_Entity* en = catchEntity(e, RS2::EntityLine, RS2::ResolveAll);
|
||||
if(!en) return;
|
||||
if(!(en->isVisible() && en->rtti()== RS2::EntityLine)) return;
|
||||
for(int i=0;i<getStatus();i++) {
|
||||
if(en->getId() == pPoints->lines[i]->getId()) return; //do not pull in the same line again
|
||||
}
|
||||
if(en->getParent() && en->getParent()->ignoredOnModification())
|
||||
return;
|
||||
pPoints->coord= graphicView->toGraph(e->x(), e->y());
|
||||
deletePreview();
|
||||
while(pPoints->lines.size()==3){
|
||||
pPoints->lines.back()->setHighlighted(false);
|
||||
graphicView->drawEntity(pPoints->lines.back());
|
||||
pPoints->lines.pop_back();
|
||||
}
|
||||
en->setHighlighted(true);
|
||||
pPoints->lines.push_back(static_cast<RS_Line*>(en));
|
||||
graphicView->drawEntity(pPoints->lines.back());
|
||||
if(preparePreview()) {
|
||||
RS_Circle* e=new RS_Circle(preview.get(), pPoints->cData);
|
||||
preview->addEntity(e);
|
||||
drawPreview();
|
||||
}
|
||||
|
||||
}
|
||||
RS_DEBUG->print("RS_ActionDrawCircle4Line::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
bool RS_ActionDrawCircleInscribe::preparePreview(){
|
||||
valid=false;
|
||||
if(getStatus() == SetLine3) {
|
||||
RS_Circle c(preview.get(), pPoints->cData);
|
||||
valid= c.createInscribe(pPoints->coord, pPoints->lines);
|
||||
if(valid){
|
||||
pPoints->cData = c.getData();
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleInscribe::mouseReleaseEvent(QMouseEvent* e) {
|
||||
// Proceed to next status
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
RS_Entity* en = catchEntity(e, RS2::EntityLine, RS2::ResolveAll);
|
||||
if(!en) return;
|
||||
if(!(en->isVisible() && en->rtti()== RS2::EntityLine)) return;
|
||||
for(int i=0;i<getStatus();i++) {
|
||||
if(en->getId() == pPoints->lines[i]->getId()) return; //do not pull in the same line again
|
||||
}
|
||||
if(en->getParent()) {
|
||||
if ( en->getParent()->ignoredOnModification()) return;
|
||||
}
|
||||
while((int) pPoints->lines.size()>getStatus()){
|
||||
pPoints->lines.back()->setHighlighted(false);
|
||||
graphicView->drawEntity(pPoints->lines.back());
|
||||
pPoints->lines.pop_back();
|
||||
}
|
||||
pPoints->lines.push_back(static_cast<RS_Line*>(en));
|
||||
pPoints->coord= graphicView->toGraph(e->x(), e->y());
|
||||
switch (getStatus()) {
|
||||
case SetLine1:
|
||||
case SetLine2:
|
||||
en->setHighlighted(true);
|
||||
setStatus(getStatus()+1);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
break;
|
||||
case SetLine3:
|
||||
if( preparePreview()) {
|
||||
trigger();
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
// Return to last status:
|
||||
if(getStatus()>0){
|
||||
clearLines(true);
|
||||
pPoints->lines.back()->setHighlighted(false);
|
||||
pPoints->lines.pop_back();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
deletePreview();
|
||||
}
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//void RS_ActionDrawCircleInscribe::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
|
||||
//}
|
||||
|
||||
//fixme, support command line
|
||||
|
||||
/*
|
||||
void RS_ActionDrawCircle4Line::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetFocus1: {
|
||||
bool ok;
|
||||
double m = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
ratio = m / major.magnitude();
|
||||
if (!isArc) {
|
||||
trigger();
|
||||
} else {
|
||||
setStatus(SetAngle1);
|
||||
}
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle1: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle1 = RS_Math::deg2rad(a);
|
||||
setStatus(SetAngle2);
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle2: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle2 = RS_Math::deg2rad(a);
|
||||
trigger();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
QStringList RS_ActionDrawCircleInscribe::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleInscribe::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetLine1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the first line"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetLine2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the second line"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetLine3:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the third line"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleInscribe::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
79
actions/rs_actiondrawcircleinscribe.h
Normal file
79
actions/rs_actiondrawcircleinscribe.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
|
||||
Copyright (C) 2011 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWCIRCLEINSCRIBE_H
|
||||
#define RS_ACTIONDRAWCIRCLEINSCRIBE_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
class RS_Line;
|
||||
struct RS_CircleData;
|
||||
|
||||
/**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
*
|
||||
* @author Dongxu Li
|
||||
*/
|
||||
class RS_ActionDrawCircleInscribe : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetLine1, // Setting the First Line. */
|
||||
SetLine2, // Setting the Second Line. */
|
||||
SetLine3 // Setting the Third Line. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawCircleInscribe(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawCircleInscribe() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
bool preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
// void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
// void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
void finish(bool updateTB=true) override;
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief clearLines unset highlighten lines, and clear the vector "lines"
|
||||
* @param checkStatus keep lines members according to getStatus()
|
||||
*/
|
||||
void clearLines(bool checkStatus=false);
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
#endif
|
||||
474
actions/rs_actiondrawcircletan1_2p.cpp
Normal file
474
actions/rs_actiondrawcircletan1_2p.cpp
Normal file
@@ -0,0 +1,474 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw circle by foci and a point on circle
|
||||
|
||||
Copyright (C) 2012 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawcircletan1_2p.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_arc.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_point.h"
|
||||
#include "lc_quadratic.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawCircleTan1_2P::Points {
|
||||
std::vector<RS_Vector> points;
|
||||
RS_CircleData cData;
|
||||
RS_Vector coord;
|
||||
double radius = 0.;
|
||||
bool valid = false;
|
||||
//keep a list of centers found
|
||||
RS_VectorSolutions centers;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
RS_ActionDrawCircleTan1_2P::RS_ActionDrawCircleTan1_2P(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw tangent circle 2P",
|
||||
container, graphicView)
|
||||
,circle(nullptr)
|
||||
,pPoints(new Points{})
|
||||
{
|
||||
actionType = RS2::ActionDrawCircleTan1_2P;
|
||||
}
|
||||
|
||||
RS_ActionDrawCircleTan1_2P::~RS_ActionDrawCircleTan1_2P() = default;
|
||||
|
||||
void RS_ActionDrawCircleTan1_2P::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
if(status>=0) {
|
||||
RS_Snapper::suspend();
|
||||
}
|
||||
|
||||
if (status<=SetCircle1) {
|
||||
if(circle) {
|
||||
if(circle->isHighlighted()){
|
||||
circle->setHighlighted(false);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
}
|
||||
}
|
||||
pPoints->points.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan1_2P::finish(bool updateTB){
|
||||
if (circle) {
|
||||
circle->setHighlighted(false);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
}
|
||||
RS_PreviewActionInterface::finish(updateTB);
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleTan1_2P::trigger() {
|
||||
// std::cout<<__FILE__<<" : "<<__func__<<" : line "<<__LINE__<<std::endl;
|
||||
// std::cout<<"begin"<<std::endl;
|
||||
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
|
||||
RS_Circle* c=new RS_Circle(container, pPoints->cData);
|
||||
|
||||
container->addEntity(c);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(c);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
|
||||
circle->setHighlighted(false);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
// drawSnapper();
|
||||
|
||||
setStatus(SetCircle1);
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan1_2P::trigger():"
|
||||
" entity added: %d", c->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan1_2P::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan1_2P::mouseMoveEvent begin");
|
||||
|
||||
switch(getStatus() ){
|
||||
case SetPoint1:
|
||||
{
|
||||
RS_Vector&& mouse=snapPoint(e);
|
||||
pPoints->points.clear();
|
||||
pPoints->points.push_back(mouse);
|
||||
switch(circle->rtti()){
|
||||
case RS2::EntityArc:
|
||||
case RS2::EntityCircle:
|
||||
{
|
||||
RS_Vector const& dvp=mouse - circle->getCenter();
|
||||
double rvp=dvp.magnitude();
|
||||
if(rvp<RS_TOLERANCE2) break;
|
||||
pPoints->cData.radius=(circle->getRadius()+rvp)*0.5;
|
||||
pPoints->cData.center=circle->getCenter()+dvp*(pPoints->cData.radius/rvp);
|
||||
pPoints->cData.radius=fabs(circle->getRadius()-pPoints->cData.radius);
|
||||
}
|
||||
break;
|
||||
case RS2::EntityLine:
|
||||
{
|
||||
RS_Line* line=static_cast<RS_Line*>(circle);
|
||||
RS_Vector&& vp=line->getNearestPointOnEntity(pPoints->points[0],false);
|
||||
if(vp.valid){
|
||||
pPoints->cData.center=(vp+pPoints->points[0])*0.5;
|
||||
pPoints->cData.radius=vp.distanceTo(pPoints->cData.center);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
deletePreview();
|
||||
RS_Circle* e=new RS_Circle(preview.get(), pPoints->cData);
|
||||
preview->addEntity(e);
|
||||
drawPreview();
|
||||
break;
|
||||
}
|
||||
case SetPoint2: {
|
||||
RS_Vector const& mouse=snapPoint(e);
|
||||
pPoints->points.resize(1);
|
||||
pPoints->points.push_back(mouse);
|
||||
deletePreview();
|
||||
pPoints->coord=mouse;
|
||||
if (!getCenters()) return;
|
||||
if (preparePreview()) {
|
||||
RS_Circle* e=new RS_Circle(preview.get(), pPoints->cData);
|
||||
preview->addEntity(e);
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SetCenter: {
|
||||
|
||||
// RS_Entity* en = catchEntity(e, enTypeList, RS2::ResolveAll);
|
||||
pPoints->coord= graphicView->toGraph(e->x(), e->y());
|
||||
// circles[getStatus()]=static_cast<RS_Line*>(en);
|
||||
if(preparePreview()) {
|
||||
deletePreview();
|
||||
RS_Circle* e=new RS_Circle(preview.get(), pPoints->cData);
|
||||
for(size_t i=0; i<pPoints->centers.size(); ++i)
|
||||
preview->addEntity(new RS_Point(preview.get(), RS_PointData(pPoints->centers.at(i))));
|
||||
preview->addEntity(e);
|
||||
// double r0=cData.radius*0.1;
|
||||
// if(centers.size()>1)
|
||||
// for(unsigned i=0; i< centers.size(); ++i){
|
||||
// RS_DEBUG->print(RS_Debug::D_ERROR, "center %d: (%g, %g)\n",i,centers.at(i).x,centers.at(i).y);
|
||||
// preview->addEntity(new RS_Circle(preview, RS_CircleData(centers.at(i), r0)));
|
||||
// }
|
||||
drawPreview();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan1_2P::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
//void RS_ActionDrawCircleTan1_2P::setRadius(const double& r)
|
||||
//{
|
||||
// cData.radius=r;
|
||||
// if(getStatus() == SetPoint2){
|
||||
// RS_Circle c(nullptr,cData);
|
||||
// centers=c.createTan1_2P(circle,cData.radius);
|
||||
// }
|
||||
//}
|
||||
|
||||
bool RS_ActionDrawCircleTan1_2P::getCenters(){
|
||||
pPoints->centers.clear();
|
||||
if(getStatus() < SetPoint2) return false;
|
||||
|
||||
LC_Quadratic lc0(circle, pPoints->points[0]);
|
||||
// LC_Quadratic lc1(circle, points[1]);
|
||||
LC_Quadratic lc1(pPoints->points[1], pPoints->points[0]);
|
||||
auto list=LC_Quadratic::getIntersection(lc0,lc1);
|
||||
// DEBUG_HEADER
|
||||
// std::cout<<"intersections : "<<list<<std::endl;
|
||||
|
||||
for(const RS_Vector& vp: list){
|
||||
//when taking the path of center of tangent circle passing a given point,
|
||||
// the center is never closer to the circle center than the point, for internal and external tangent circles
|
||||
double ds0=vp.distanceTo(pPoints->points[0]);
|
||||
// double ds1=vp.distanceTo(points[1]);
|
||||
// if( fabs(ds0 - ds1)> RS_TOLERANCE) continue;
|
||||
if(circle->rtti()==RS2::EntityCircle||circle->rtti()==RS2::EntityArc){
|
||||
double ds=vp.distanceTo(circle->getCenter());
|
||||
//condition for tangential to the given circle
|
||||
if( fabs(ds - (ds0 + circle->getRadius())) > RS_TOLERANCE && fabs(ds - fabs(ds0 - circle->getRadius())) > RS_TOLERANCE ) continue;
|
||||
}else{
|
||||
double ds=0.;
|
||||
circle->getNearestPointOnEntity(vp, false,&ds);
|
||||
//condition for tangential to the given straight line
|
||||
if( fabs(ds - ds0)>RS_TOLERANCE) continue;
|
||||
}
|
||||
|
||||
//avoid counting the same center
|
||||
bool existing=false;
|
||||
for(auto const& vq: pPoints->centers){
|
||||
if(vq.squaredTo(vp) < RS_TOLERANCE15 ){
|
||||
existing=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(existing) continue;
|
||||
pPoints->centers.push_back(vp);
|
||||
}
|
||||
// DEBUG_HEADER
|
||||
// std::cout<<"points: "<<points[0]<<" , "<<points[1]<<std::endl;
|
||||
// std::cout<<"centers.size()="<<centers.size()<<std::endl;
|
||||
// std::cout<<"centers: "<<centers<<std::endl;
|
||||
pPoints->valid= (pPoints->centers.size()>0);
|
||||
return pPoints->valid;
|
||||
}
|
||||
|
||||
bool RS_ActionDrawCircleTan1_2P::preparePreview(){
|
||||
if (!pPoints->centers.size()) getCenters();
|
||||
if (!pPoints->centers.size()) return false;
|
||||
pPoints->cData.center=pPoints->centers.getClosest(pPoints->coord);
|
||||
pPoints->cData.radius=pPoints->points[0].distanceTo(pPoints->cData.center);
|
||||
return true;
|
||||
}
|
||||
|
||||
RS_Entity* RS_ActionDrawCircleTan1_2P::catchCircle(QMouseEvent* e) {
|
||||
RS_Entity* ret=nullptr;
|
||||
RS_Entity* en = catchEntity(e,enTypeList, RS2::ResolveAll);
|
||||
if (!en) return ret;
|
||||
if (!en->isVisible()) return ret;
|
||||
if (en->getParent()) {
|
||||
if ( en->getParent()->ignoredOnModification()){
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return en;
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleTan1_2P::mouseReleaseEvent(QMouseEvent* e) {
|
||||
// Proceed to next status
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCircle1:
|
||||
{
|
||||
RS_Entity* en = catchCircle(e);
|
||||
if (!en) return;
|
||||
circle = static_cast<RS_AtomicEntity*>(en);
|
||||
circle->setHighlighted(true);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
setStatus(getStatus()+1);
|
||||
}
|
||||
break;
|
||||
case SetPoint1:
|
||||
case SetPoint2:
|
||||
{
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
}
|
||||
break;
|
||||
case SetCenter:
|
||||
pPoints->coord=graphicView->toGraph(e->x(),e->y());
|
||||
if(preparePreview()) trigger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
// Return to last status:
|
||||
if(getStatus()>0){
|
||||
deletePreview();
|
||||
}
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan1_2P::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
pPoints->coord=mouse;
|
||||
switch(getStatus()){
|
||||
|
||||
case SetPoint1:
|
||||
pPoints->points.clear();
|
||||
pPoints->points.push_back(mouse);
|
||||
setStatus(getStatus()+1);
|
||||
break;
|
||||
|
||||
case SetPoint2:
|
||||
// pPoints->points.reserve(1);
|
||||
pPoints->points.push_back(mouse);
|
||||
if(getCenters()) {
|
||||
if(pPoints->centers.size()==1) trigger();
|
||||
else setStatus(getStatus()+1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//fixme, support command line
|
||||
|
||||
/*
|
||||
void RS_ActionDrawCircleTan1_2P::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetFocus1: {
|
||||
bool ok;
|
||||
double m = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
ratio = m / major.magnitude();
|
||||
if (!isArc) {
|
||||
trigger();
|
||||
} else {
|
||||
setStatus(SetAngle1);
|
||||
}
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle1: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle1 = RS_Math::deg2rad(a);
|
||||
setStatus(SetAngle2);
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle2: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle2 = RS_Math::deg2rad(a);
|
||||
trigger();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//void RS_ActionDrawCircleTan1_2P::showOptions() {
|
||||
// RS_DEBUG->print("RS_ActionDrawCircleTan1_2P::showOptions");
|
||||
// RS_ActionInterface::showOptions();
|
||||
|
||||
// RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
// RS_DEBUG->print("RS_ActionDrawCircleTan1_2P::showOptions: OK");
|
||||
//}
|
||||
|
||||
|
||||
|
||||
//void RS_ActionDrawCircleTan1_2P::hideOptions() {
|
||||
// RS_ActionInterface::hideOptions();
|
||||
|
||||
// RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
//}
|
||||
|
||||
|
||||
QStringList RS_ActionDrawCircleTan1_2P::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan1_2P::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetCircle1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify a line/arc/circle"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetPoint1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the first point on the tangent circle"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetPoint2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the second point on the tangent circle"),
|
||||
tr("Back"));
|
||||
break;
|
||||
case SetCenter:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Select the center of the tangent circle"),
|
||||
tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan1_2P::updateMouseCursor()
|
||||
{
|
||||
switch (getStatus())
|
||||
{
|
||||
case SetCircle1:
|
||||
case SetCenter:
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
break;
|
||||
case SetPoint1:
|
||||
case SetPoint2:
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double RS_ActionDrawCircleTan1_2P::getRadius() const{
|
||||
return pPoints->cData.radius;
|
||||
}
|
||||
|
||||
// EOF
|
||||
87
actions/rs_actiondrawcircletan1_2p.h
Normal file
87
actions/rs_actiondrawcircletan1_2p.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
|
||||
Copyright (C) 2012 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWCIRCLETAN1_2P_H
|
||||
#define RS_ACTIONDRAWCIRCLETAN1_2P_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
class RS_AtomicEntity;
|
||||
struct RS_CircleData;
|
||||
|
||||
/**
|
||||
* Draw tangential circle passing 2 points
|
||||
*
|
||||
* @author Dongxu Li
|
||||
*/
|
||||
class RS_ActionDrawCircleTan1_2P : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetCircle1=0, // Setting the First Circle. */
|
||||
SetPoint1=1, // Setting the First Point. */
|
||||
SetPoint2=2, // Setting the Second Point. */
|
||||
SetCenter // Setting the internal or external tangent circle's center. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawCircleTan1_2P(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawCircleTan1_2P() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
bool getCenters();
|
||||
bool preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
// void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
void finish(bool updateTB=true) override;
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
// void showOptions() override;
|
||||
// void hideOptions() override;
|
||||
// void setRadius(const double& r);
|
||||
double getRadius() const;
|
||||
|
||||
|
||||
protected:
|
||||
RS_Entity* catchCircle(QMouseEvent* e);
|
||||
RS_AtomicEntity* circle;
|
||||
|
||||
private:
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
|
||||
//list of entity types supported by current action
|
||||
const EntityTypeList enTypeList = EntityTypeList {RS2::EntityLine, RS2::EntityArc, RS2::EntityCircle};
|
||||
};
|
||||
|
||||
#endif
|
||||
334
actions/rs_actiondrawcircletan2.cpp
Normal file
334
actions/rs_actiondrawcircletan2.cpp
Normal file
@@ -0,0 +1,334 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw circle by foci and a point on circle
|
||||
|
||||
Copyright (C) 2012 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#include<vector>
|
||||
#include<QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawcircletan2.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_point.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawCircleTan2::Points {
|
||||
RS_CircleData cData;
|
||||
RS_Vector coord;
|
||||
double radius{0.};
|
||||
bool valid{false};
|
||||
RS_VectorSolutions centers;
|
||||
std::vector<RS_AtomicEntity*> circles;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
RS_ActionDrawCircleTan2::RS_ActionDrawCircleTan2(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw circle inscribed",
|
||||
container, graphicView)
|
||||
, pPoints(new Points{})
|
||||
{
|
||||
actionType=RS2::ActionDrawCircleTan2;
|
||||
}
|
||||
|
||||
RS_ActionDrawCircleTan2::~RS_ActionDrawCircleTan2() = default;
|
||||
|
||||
void RS_ActionDrawCircleTan2::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
if(status>=0) {
|
||||
RS_Snapper::suspend();
|
||||
}
|
||||
|
||||
if (status==SetCircle1) {
|
||||
pPoints->circles.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan2::finish(bool updateTB){
|
||||
if(pPoints->circles.size()>0){
|
||||
for(auto p: pPoints->circles){
|
||||
if(p) p->setHighlighted(false);
|
||||
}
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
pPoints->circles.clear();
|
||||
}
|
||||
RS_PreviewActionInterface::finish(updateTB);
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan2::trigger() {
|
||||
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
|
||||
RS_Circle* circle=new RS_Circle(container, pPoints->cData);
|
||||
|
||||
container->addEntity(circle);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(circle);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
for(auto p: pPoints->circles)
|
||||
p->setHighlighted(false);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
// drawSnapper();
|
||||
|
||||
pPoints->circles.clear();
|
||||
setStatus(SetCircle1);
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan2::trigger():"
|
||||
" entity added: %d", circle->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan2::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan2::mouseMoveEvent begin");
|
||||
|
||||
switch(getStatus() ){
|
||||
case SetCenter: {
|
||||
// RS_Entity* en = catchEntity(e, enTypeList, RS2::ResolveAll);
|
||||
pPoints->coord= graphicView->toGraph(e->x(), e->y());
|
||||
// circles[getStatus()]=static_cast<RS_Line*>(en);
|
||||
if(preparePreview()) {
|
||||
deletePreview();
|
||||
RS_Circle* e=new RS_Circle(preview.get(), pPoints->cData);
|
||||
preview->addEntity(e);
|
||||
for(size_t i=0; i< pPoints->centers.size(); ++i){
|
||||
preview->addEntity(new RS_Point(preview.get(), RS_PointData(pPoints->centers.at(i))));
|
||||
}
|
||||
drawPreview();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan2::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleTan2::setRadius(const double& r)
|
||||
{
|
||||
pPoints->cData.radius=r;
|
||||
if(getStatus() == SetCenter){
|
||||
pPoints->centers=RS_Circle::createTan2(pPoints->circles,
|
||||
pPoints->cData.radius);
|
||||
}
|
||||
}
|
||||
|
||||
bool RS_ActionDrawCircleTan2::getCenters(){
|
||||
if(getStatus() != SetCircle2) return false;
|
||||
pPoints->centers=RS_Circle::createTan2(pPoints->circles,
|
||||
pPoints->cData.radius);
|
||||
pPoints->valid= (pPoints->centers.size()>0);
|
||||
return pPoints->valid;
|
||||
}
|
||||
|
||||
bool RS_ActionDrawCircleTan2::preparePreview(){
|
||||
if (pPoints->valid) {
|
||||
pPoints->cData.center=pPoints->centers.getClosest(pPoints->coord);
|
||||
}
|
||||
return pPoints->valid;
|
||||
}
|
||||
|
||||
RS_Entity* RS_ActionDrawCircleTan2::catchCircle(QMouseEvent* e) {
|
||||
RS_Entity* en = catchEntity(e,enTypeList, RS2::ResolveAll);
|
||||
if (!en) return nullptr;
|
||||
if (!en->isVisible()) return nullptr;
|
||||
for (int i=0;i<getStatus();i++) {
|
||||
if(en->getId() == pPoints->circles[i]->getId()) return nullptr; //do not pull in the same line again
|
||||
}
|
||||
if(en->getParent()) {
|
||||
if ( en->getParent()->ignoredOnModification()){
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return en;
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleTan2::mouseReleaseEvent(QMouseEvent* e) {
|
||||
// Proceed to next status
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCircle1:
|
||||
case SetCircle2: {
|
||||
RS_Entity* en = catchCircle(e);
|
||||
if (!en) return;
|
||||
pPoints->circles.resize(getStatus());
|
||||
pPoints->circles.push_back(static_cast<RS_AtomicEntity*>(en));
|
||||
if(getStatus()==SetCircle1 || getCenters()){
|
||||
pPoints->circles.at(pPoints->circles.size()-1)->setHighlighted(true);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
setStatus(getStatus()+1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SetCenter:
|
||||
pPoints->coord= graphicView->toGraph(e->x(), e->y());
|
||||
if( preparePreview()) trigger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
// Return to last status:
|
||||
if(getStatus()>0){
|
||||
pPoints->circles[getStatus()-1]->setHighlighted(false);
|
||||
pPoints->circles.pop_back();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
deletePreview();
|
||||
}
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//void RS_ActionDrawCircleTan2::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
|
||||
//}
|
||||
|
||||
//fixme, support command line
|
||||
|
||||
/*
|
||||
void RS_ActionDrawCircleTan2::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetFocus1: {
|
||||
bool ok;
|
||||
double m = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
ratio = m / major.magnitude();
|
||||
if (!isArc) {
|
||||
trigger();
|
||||
} else {
|
||||
setStatus(SetAngle1);
|
||||
}
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle1: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle1 = RS_Math::deg2rad(a);
|
||||
setStatus(SetAngle2);
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle2: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle2 = RS_Math::deg2rad(a);
|
||||
trigger();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan2::showOptions() {
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan2::showOptions");
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan2::showOptions: OK");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan2::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
|
||||
QStringList RS_ActionDrawCircleTan2::getAvailableCommands() {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan2::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetCircle1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the first line/arc/circle"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetCircle2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the second line/arc/circle"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetCenter:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Select the center of the tangent circle"),
|
||||
tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan2::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
}
|
||||
|
||||
double RS_ActionDrawCircleTan2::getRadius() const{
|
||||
return pPoints->cData.radius;
|
||||
}
|
||||
|
||||
// EOF
|
||||
85
actions/rs_actiondrawcircletan2.h
Normal file
85
actions/rs_actiondrawcircletan2.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw a tangential circle of two given circles, with given radius
|
||||
|
||||
Copyright (C) 2012-2015 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWCIRCLETAN2_H
|
||||
#define RS_ACTIONDRAWCIRCLETAN2_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
class RS_AtomicEntity;
|
||||
struct RS_CircleData;
|
||||
|
||||
/**
|
||||
* Draw a circle tangential to two give circles and with radius
|
||||
*
|
||||
* @author Dongxu Li
|
||||
*/
|
||||
class RS_ActionDrawCircleTan2 : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetCircle1, // Setting the First Circle. */
|
||||
SetCircle2, // Setting the Second Circle. */
|
||||
SetCenter // select the closest tangential Circle. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawCircleTan2(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawCircleTan2() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
bool getCenters();
|
||||
bool preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
// void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
// void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
void finish(bool updateTB=true) override;
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
void showOptions() override;
|
||||
void hideOptions() override;
|
||||
void setRadius(const double& r);
|
||||
double getRadius() const;
|
||||
|
||||
|
||||
protected:
|
||||
RS_Entity* catchCircle(QMouseEvent* e);
|
||||
private:
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
|
||||
//list of entity types supported by current action
|
||||
const EntityTypeList enTypeList = EntityTypeList{RS2::EntityLine, RS2::EntityArc, RS2::EntityCircle};
|
||||
};
|
||||
|
||||
#endif
|
||||
361
actions/rs_actiondrawcircletan2_1p.cpp
Normal file
361
actions/rs_actiondrawcircletan2_1p.cpp
Normal file
@@ -0,0 +1,361 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw circle by foci and a point on circle
|
||||
|
||||
Copyright (C) 2012 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
#include<vector>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawcircletan2_1p.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_arc.h"
|
||||
#include "rs_circle.h"
|
||||
#include "lc_quadratic.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_point.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawCircleTan2_1P::Points {
|
||||
RS_Vector point;
|
||||
RS_CircleData cData;
|
||||
RS_Vector coord;
|
||||
double radius = 0.;
|
||||
bool valid = false;
|
||||
//keep a list of centers found
|
||||
RS_VectorSolutions centers;
|
||||
std::vector<RS_AtomicEntity*> circles;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
RS_ActionDrawCircleTan2_1P::RS_ActionDrawCircleTan2_1P(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw tangent circle 2P",
|
||||
container, graphicView)
|
||||
, pPoints(new Points{})
|
||||
{
|
||||
actionType=RS2::ActionDrawCircleTan2_1P;
|
||||
}
|
||||
|
||||
RS_ActionDrawCircleTan2_1P::~RS_ActionDrawCircleTan2_1P() = default;
|
||||
|
||||
void RS_ActionDrawCircleTan2_1P::init(int status) {
|
||||
if(status>=0) {
|
||||
RS_Snapper::suspend();
|
||||
}
|
||||
if(status>(int) pPoints->circles.size()) status=(int) pPoints->circles.size();
|
||||
RS_PreviewActionInterface::init(status);
|
||||
for(int i=0; i<status; ++i){
|
||||
if(!pPoints->circles[i]) {
|
||||
status=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool updateNeeded(false);
|
||||
for(size_t i=status>=0?status:0; i<pPoints->circles.size(); ++i){
|
||||
if(pPoints->circles[i])
|
||||
if(pPoints->circles[i]->isHighlighted()){
|
||||
pPoints->circles[i]->setHighlighted(false);
|
||||
updateNeeded=true;
|
||||
}
|
||||
}
|
||||
if(updateNeeded) graphicView->redraw(RS2::RedrawDrawing);
|
||||
pPoints->circles.resize(status>=0?status:0);
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan2_1P::finish(bool updateTB){
|
||||
if( pPoints->circles.size() >0) {
|
||||
for(RS_AtomicEntity*const circle: pPoints->circles)
|
||||
circle->setHighlighted(false);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
}
|
||||
RS_PreviewActionInterface::finish(updateTB);
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleTan2_1P::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
RS_Circle* c=new RS_Circle(container, pPoints->cData);
|
||||
|
||||
container->addEntity(c);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(c);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
|
||||
for(RS_AtomicEntity*const circle: pPoints->circles)
|
||||
circle->setHighlighted(false);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
pPoints->circles.clear();
|
||||
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan2_1P::trigger():"
|
||||
" entity added: %d", c->getId());
|
||||
init(SetCircle1);
|
||||
}
|
||||
|
||||
|
||||
bool RS_ActionDrawCircleTan2_1P::getCenters()
|
||||
{
|
||||
if(pPoints->circles.size()<2) return false;
|
||||
LC_Quadratic lc0(pPoints->circles[0], pPoints->point);
|
||||
LC_Quadratic lc1(pPoints->circles[1], pPoints->point);
|
||||
|
||||
auto const& list=LC_Quadratic::getIntersection(lc0,lc1);
|
||||
pPoints->centers.clear();
|
||||
for(const RS_Vector& vp: list){
|
||||
auto ds=vp.distanceTo(pPoints->point)-RS_TOLERANCE;
|
||||
bool validBranch(true);
|
||||
for(int j=0;j<2;j++){
|
||||
if(pPoints->circles[j]->rtti()==RS2::EntityCircle||pPoints->circles[j]->rtti()==RS2::EntityArc){
|
||||
if( vp.distanceTo(pPoints->circles[j]->getCenter()) <= ds) {
|
||||
validBranch=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(validBranch) pPoints->centers.push_back(vp);
|
||||
}
|
||||
return pPoints->centers.size()>0;
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleTan2_1P::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan2_1P::mouseMoveEvent begin");
|
||||
|
||||
switch( getStatus()){
|
||||
case SetPoint:
|
||||
pPoints->coord=snapPoint(e);
|
||||
pPoints->point=pPoints->coord;
|
||||
break;
|
||||
case SetCenter:
|
||||
pPoints->coord=graphicView->toGraph(e->x(),e->y());
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
deletePreview();
|
||||
if(preparePreview()){
|
||||
RS_Circle* e=new RS_Circle(preview.get(), pPoints->cData);
|
||||
for (auto const& vp: pPoints->centers)
|
||||
preview->addEntity(new RS_Point(preview.get(), vp));
|
||||
preview->addEntity(e);
|
||||
drawPreview();
|
||||
}
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan2_1P::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
bool RS_ActionDrawCircleTan2_1P::preparePreview(){
|
||||
if (!getCenters()) return false;
|
||||
pPoints->cData.center=pPoints->centers.getClosest(pPoints->coord);
|
||||
pPoints->cData.radius=pPoints->point.distanceTo(pPoints->cData.center);
|
||||
return true;
|
||||
}
|
||||
|
||||
RS_Entity* RS_ActionDrawCircleTan2_1P::catchCircle(QMouseEvent* e) {
|
||||
RS_Entity* ret=nullptr;
|
||||
RS_Entity* en = catchEntity(e,enTypeList, RS2::ResolveAll);
|
||||
if (!en) return ret;
|
||||
if (!en->isVisible()) return ret;
|
||||
for(auto p: pPoints->circles){
|
||||
if(p && en->getId() == p->getId()) return ret; //do not pull in the same line again
|
||||
}
|
||||
if(en->getParent() && en->getParent()->ignoredOnModification()){
|
||||
return nullptr;
|
||||
}
|
||||
return en;
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleTan2_1P::mouseReleaseEvent(QMouseEvent* e) {
|
||||
// Proceed to next status
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCircle1:
|
||||
case SetCircle2:
|
||||
{
|
||||
pPoints->circles.resize(getStatus());
|
||||
RS_AtomicEntity* en = static_cast<RS_AtomicEntity*>(catchCircle(e));
|
||||
if (!en) return;
|
||||
// circle = static_cast<RS_AtomicEntity*>(en);
|
||||
en->setHighlighted(true);
|
||||
pPoints->circles.push_back(en);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
setStatus(getStatus()+1);
|
||||
}
|
||||
break;
|
||||
case SetPoint:
|
||||
{
|
||||
RS_Vector snapped = snapPoint(e);
|
||||
RS_CoordinateEvent ce(snapped);
|
||||
coordinateEvent(&ce);
|
||||
}
|
||||
break;
|
||||
case SetCenter:
|
||||
pPoints->coord=graphicView->toGraph(e->x(),e->y());
|
||||
if(preparePreview()) trigger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
// Return to last status:
|
||||
if(getStatus()>0){
|
||||
deletePreview();
|
||||
}
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan2_1P::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
switch(getStatus()){
|
||||
|
||||
case SetPoint:
|
||||
pPoints->point=mouse;
|
||||
pPoints->coord=mouse;
|
||||
if(getCenters()) {
|
||||
if(pPoints->centers.size()==1) trigger();
|
||||
else setStatus(getStatus()+1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
// case SetCenter:
|
||||
// coord=mouse;
|
||||
// trigger();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//fixme, support command line
|
||||
|
||||
/*
|
||||
void RS_ActionDrawCircleTan2_1P::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetFocus1: {
|
||||
bool ok;
|
||||
double m = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
ratio = m / major.magnitude();
|
||||
if (!isArc) {
|
||||
trigger();
|
||||
} else {
|
||||
setStatus(SetAngle1);
|
||||
}
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle1: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle1 = RS_Math::deg2rad(a);
|
||||
setStatus(SetAngle2);
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle2: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle2 = RS_Math::deg2rad(a);
|
||||
trigger();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
QStringList RS_ActionDrawCircleTan2_1P::getAvailableCommands() {
|
||||
return {};
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleTan2_1P::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetCircle1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify a line/arc/circle"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetCircle2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the another arc/circle"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetPoint:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify a point on the tangent circle"),
|
||||
tr("Back"));
|
||||
break;
|
||||
case SetCenter:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Select the center of the tangent circle"),
|
||||
tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleTan2_1P::updateMouseCursor()
|
||||
{
|
||||
switch (getStatus())
|
||||
{
|
||||
case SetCircle1:
|
||||
case SetCircle2:
|
||||
case SetCenter:
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
break;
|
||||
case SetPoint:
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// EOF
|
||||
81
actions/rs_actiondrawcircletan2_1p.h
Normal file
81
actions/rs_actiondrawcircletan2_1p.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
|
||||
Copyright (C) 2012 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWCIRCLETAN2_1P_H
|
||||
#define RS_ACTIONDRAWCIRCLETAN2_1P_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
class RS_AtomicEntity;
|
||||
struct RS_CircleData;
|
||||
|
||||
/**
|
||||
* Given two circles and a point, draw a common tangent circle passing the point
|
||||
*
|
||||
* @author Dongxu Li
|
||||
*/
|
||||
class RS_ActionDrawCircleTan2_1P : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetCircle1=0, // Setting the first circle. */
|
||||
SetCircle2=1, // Setting the second circle. */
|
||||
SetPoint=2, // Setting point on the desired circle. */
|
||||
SetCenter
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawCircleTan2_1P(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawCircleTan2_1P() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
bool getCenters();
|
||||
bool preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
// void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
void finish(bool updateTB=true) override;
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
|
||||
protected:
|
||||
RS_Entity* catchCircle(QMouseEvent* e);
|
||||
private:
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
|
||||
//list of entity types supported by current action
|
||||
const EntityTypeList enTypeList = EntityTypeList {RS2::EntityLine, RS2::EntityArc, RS2::EntityCircle};
|
||||
};
|
||||
|
||||
#endif
|
||||
476
actions/rs_actiondrawcircletan3.cpp
Normal file
476
actions/rs_actiondrawcircletan3.cpp
Normal file
@@ -0,0 +1,476 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw circle by foci and a point on circle
|
||||
|
||||
Copyright (C) 2012 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#include "rs_actiondrawcircletan3.h"
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_point.h"
|
||||
#include "lc_quadratic.h"
|
||||
#include "rs_information.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawCircleTan3::Points {
|
||||
std::vector<RS_AtomicEntity*> circles;
|
||||
std::shared_ptr<RS_CircleData> cData{std::make_shared<RS_CircleData>()};
|
||||
RS_Vector coord;
|
||||
bool valid{false};
|
||||
//keep a list of centers found
|
||||
std::vector<std::shared_ptr<RS_CircleData> > candidates;
|
||||
RS_VectorSolutions centers;
|
||||
};
|
||||
|
||||
RS_ActionDrawCircleTan3::~RS_ActionDrawCircleTan3() = default;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
RS_ActionDrawCircleTan3::RS_ActionDrawCircleTan3(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw circle inscribed",
|
||||
container, graphicView)
|
||||
, pPoints(new Points{})
|
||||
{
|
||||
actionType=RS2::ActionDrawCircleTan3;
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleTan3::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
if(status>=0) {
|
||||
RS_Snapper::suspend();
|
||||
}
|
||||
|
||||
if (status==SetCircle1) {
|
||||
pPoints->circles.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan3::finish(bool updateTB){
|
||||
if(pPoints->circles.size()>0){
|
||||
for(RS_AtomicEntity* const pc: pPoints->circles)
|
||||
if(pc) pc->setHighlighted(false);
|
||||
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
pPoints->circles.clear();
|
||||
}
|
||||
RS_PreviewActionInterface::finish(updateTB);
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan3::trigger() {
|
||||
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
|
||||
RS_Circle* circle=new RS_Circle(container, *pPoints->cData);
|
||||
|
||||
container->addEntity(circle);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(circle);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
for(RS_AtomicEntity* const pc: pPoints->circles)
|
||||
if(pc) pc->setHighlighted(false);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
// drawSnapper();
|
||||
|
||||
pPoints->circles.clear();
|
||||
setStatus(SetCircle1);
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan3::trigger():"
|
||||
" entity added: %d", circle->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawCircleTan3::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan3::mouseMoveEvent begin");
|
||||
|
||||
switch(getStatus() ){
|
||||
case SetCenter: {
|
||||
// RS_Entity* en = catchEntity(e, enTypeList, RS2::ResolveAll);
|
||||
pPoints->coord= graphicView->toGraph(e->x(), e->y());
|
||||
// circles[getStatus()]=static_cast<RS_Line*>(en);
|
||||
deletePreview();
|
||||
if(preparePreview()) {
|
||||
RS_Circle* e=new RS_Circle(preview.get(), *pPoints->cData);
|
||||
preview->addEntity(e);
|
||||
for(auto& c: pPoints->candidates){
|
||||
preview->addEntity(new RS_Point(nullptr, RS_PointData(c->center)));
|
||||
}
|
||||
drawPreview();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RS_DEBUG->print("RS_ActionDrawCircleTan3::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
bool RS_ActionDrawCircleTan3::getData(){
|
||||
if(getStatus() != SetCircle3) return false;
|
||||
//find the nearest circle
|
||||
size_t i=0;
|
||||
size_t const countLines=std::count_if(pPoints->circles.begin(), pPoints->circles.end(), [](RS_AtomicEntity* e)->bool
|
||||
{
|
||||
return e->rtti()==RS2::EntityLine;
|
||||
});
|
||||
|
||||
for(;i<pPoints->circles.size();++i)
|
||||
if(pPoints->circles[i]->rtti() == RS2::EntityLine) break;
|
||||
pPoints->candidates.clear();
|
||||
size_t i1=(i+1)%3;
|
||||
size_t i2=(i+2)%3;
|
||||
if(i<pPoints->circles.size() && pPoints->circles[i]->rtti() == RS2::EntityLine){
|
||||
//one or more lines
|
||||
|
||||
LC_Quadratic lc0(pPoints->circles[i],pPoints->circles[i1],false);
|
||||
LC_Quadratic lc1;
|
||||
RS_VectorSolutions sol;
|
||||
//detect degenerate case two circles with the same radius
|
||||
switch(countLines){
|
||||
default:
|
||||
case 0:
|
||||
//this should not happen
|
||||
assert(false);
|
||||
case 1:
|
||||
//1 line, two circles
|
||||
{
|
||||
for(unsigned k=0; k<4; ++k){
|
||||
//loop through all mirroring cases
|
||||
lc1=LC_Quadratic(pPoints->circles[i],pPoints->circles[i1], k & 1u);
|
||||
LC_Quadratic lc2=LC_Quadratic(pPoints->circles[i],pPoints->circles[i2], k & 2u);
|
||||
sol.push_back(LC_Quadratic::getIntersection(lc1,lc2));
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
//2 lines, one circle
|
||||
{
|
||||
if(pPoints->circles[i2]->rtti()==RS2::EntityLine){
|
||||
std::swap(i1, i2);
|
||||
}
|
||||
//i2 is circle
|
||||
|
||||
for(unsigned k=0; k<4; ++k){
|
||||
//loop through all mirroring cases
|
||||
lc1=LC_Quadratic(pPoints->circles[i2],pPoints->circles[i], k & 1u);
|
||||
LC_Quadratic lc2=LC_Quadratic(pPoints->circles[i2],pPoints->circles[i1], k & 2u);
|
||||
sol.push_back(LC_Quadratic::getIntersection(lc1,lc2));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
//3 lines
|
||||
{
|
||||
lc0=pPoints->circles[i]->getQuadratic();
|
||||
lc1=pPoints->circles[i1]->getQuadratic();
|
||||
auto lc2=pPoints->circles[i2]->getQuadratic();
|
||||
//attempt to have intersections (lc0, lc1), (lc0, lc2)
|
||||
auto sol1=LC_Quadratic::getIntersection(lc0,lc1);
|
||||
if(sol1.size()<1) {
|
||||
std::swap(lc0, lc2);
|
||||
std::swap(i, i2);
|
||||
}
|
||||
sol1=LC_Quadratic::getIntersection(lc0,lc2);
|
||||
if(sol1.size()<1) {
|
||||
std::swap(lc0, lc1);
|
||||
std::swap(i, i1);
|
||||
}
|
||||
|
||||
RS_Line* line0=static_cast<RS_Line*>(pPoints->circles[i]);
|
||||
RS_Line* line1=static_cast<RS_Line*>(pPoints->circles[i1]);
|
||||
RS_Line* line2=static_cast<RS_Line*>(pPoints->circles[i2]);
|
||||
lc0=line0->getQuadratic();
|
||||
lc1=line1->getQuadratic();
|
||||
lc2=line2->getQuadratic();
|
||||
//intersection 0, 1
|
||||
sol1=LC_Quadratic::getIntersection(lc0,lc1);
|
||||
if(!sol1.size()) {
|
||||
return false;
|
||||
}
|
||||
RS_Vector const v1=sol1.at(0);
|
||||
double angle1=0.5*(line0->getAngle1()+line1->getAngle1());
|
||||
|
||||
//intersection 0, 2
|
||||
sol1=LC_Quadratic::getIntersection(lc0,lc2);
|
||||
double angle2;
|
||||
if(sol1.size()<1) {
|
||||
return false;
|
||||
}
|
||||
angle2=0.5*(line0->getAngle1()+line2->getAngle1());
|
||||
RS_Vector const& v2=sol1.at(0);
|
||||
//two bisector lines per intersection
|
||||
for(unsigned j=0; j<2; ++j){
|
||||
RS_Line l1{v1, v1+RS_Vector{angle1}};
|
||||
for(unsigned j1=0; j1<2; ++j1){
|
||||
RS_Line l2{v2, v2+RS_Vector{angle2}};
|
||||
sol.push_back(RS_Information::getIntersectionLineLine(&l1, &l2));
|
||||
angle2 += M_PI_2;
|
||||
}
|
||||
angle1 += M_PI_2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double d;
|
||||
|
||||
//line passes circle center, need a second parabola as the image of the line
|
||||
for(int j=1;j<=2;j++){
|
||||
if(pPoints->circles[(i+j)%3]->rtti() == RS2::EntityCircle){
|
||||
pPoints->circles[i]->getNearestPointOnEntity(pPoints->circles[(i+j)%3]->getCenter(),
|
||||
false,&d);
|
||||
if(d<RS_TOLERANCE) {
|
||||
LC_Quadratic lc2(pPoints->circles[i],pPoints->circles[(i+j)%3], true);
|
||||
sol.push_back(LC_Quadratic::getIntersection(lc2,lc1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//clean up duplicate and invalid
|
||||
RS_VectorSolutions sol1;
|
||||
for(const RS_Vector& vp: sol){
|
||||
if(vp.magnitude()>RS_MAXDOUBLE) continue;
|
||||
if(sol1.size() && sol1.getClosestDistance(vp)<RS_TOLERANCE) continue;
|
||||
sol1.push_back(vp);
|
||||
}
|
||||
|
||||
for(auto const& v: sol1){
|
||||
pPoints->circles[i]->getNearestPointOnEntity(v,false,&d);
|
||||
auto data = std::make_shared<RS_CircleData>(v,d);
|
||||
if(pPoints->circles[(i+1)%3]->isTangent(*data)==false) continue;
|
||||
if(pPoints->circles[(i+2)%3]->isTangent(*data)==false) continue;
|
||||
pPoints->candidates.push_back(data);
|
||||
}
|
||||
|
||||
} else {
|
||||
RS_Circle c{nullptr, *pPoints->cData};
|
||||
auto solutions=c.createTan3(pPoints->circles);
|
||||
pPoints->candidates.clear();
|
||||
for(const RS_Circle& s: solutions){
|
||||
pPoints->candidates.push_back(std::make_shared<RS_CircleData>(s.getData()));
|
||||
}
|
||||
}
|
||||
pPoints->valid = ( pPoints->candidates.size() >0);
|
||||
return pPoints->valid;
|
||||
}
|
||||
|
||||
bool RS_ActionDrawCircleTan3::preparePreview(){
|
||||
if(getStatus() != SetCenter || pPoints->valid==false) {
|
||||
pPoints->valid=false;
|
||||
return false;
|
||||
}
|
||||
//find the nearest circle
|
||||
size_t index=pPoints->candidates.size();
|
||||
double dist=RS_MAXDOUBLE*RS_MAXDOUBLE;
|
||||
for(size_t i=0;i<pPoints->candidates.size();++i){
|
||||
|
||||
preview->addEntity(new RS_Point(preview.get(), RS_PointData(pPoints->candidates.at(i)->center)));
|
||||
double d;
|
||||
RS_Circle(nullptr, *pPoints->candidates.at(i)).getNearestPointOnEntity(pPoints->coord,false,&d);
|
||||
double dCenter=pPoints->coord.distanceTo(pPoints->candidates.at(i)->center);
|
||||
d=std::min(d,dCenter);
|
||||
if(d<dist){
|
||||
dist=d;
|
||||
index=i;
|
||||
}
|
||||
}
|
||||
if( index<pPoints->candidates.size()){
|
||||
pPoints->cData=pPoints->candidates.at(index);
|
||||
pPoints->valid=true;
|
||||
}else{
|
||||
pPoints->valid=false;
|
||||
}
|
||||
return pPoints->valid;
|
||||
}
|
||||
|
||||
RS_Entity* RS_ActionDrawCircleTan3::catchCircle(QMouseEvent* e) {
|
||||
RS_Entity* ret=nullptr;
|
||||
RS_Entity* en = catchEntity(e,enTypeList, RS2::ResolveAll);
|
||||
if (!en) return ret;
|
||||
if (!en->isVisible()) return ret;
|
||||
for(int i=0;i<getStatus();++i) {
|
||||
if(en->getId() == pPoints->circles[i]->getId()) return ret; //do not pull in the same line again
|
||||
}
|
||||
if(en->getParent()) {
|
||||
if ( en->getParent()->ignoredOnModification()){
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return en;
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleTan3::mouseReleaseEvent(QMouseEvent* e) {
|
||||
// Proceed to next status
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCircle1:
|
||||
case SetCircle2:
|
||||
case SetCircle3: {
|
||||
RS_Entity* en = catchCircle(e);
|
||||
if (!en) return;
|
||||
pPoints->circles.resize(getStatus());
|
||||
for(const RS_AtomicEntity* const pc: pPoints->circles)
|
||||
if(pc == en) continue;
|
||||
pPoints->circles.push_back(static_cast<RS_AtomicEntity*>(en));
|
||||
if(getStatus()<=SetCircle2 || (getStatus()==SetCircle3 && getData())){
|
||||
pPoints->circles.at(pPoints->circles.size()-1)->setHighlighted(true);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
setStatus(getStatus()+1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SetCenter:
|
||||
pPoints->coord= graphicView->toGraph(e->x(), e->y());
|
||||
if( preparePreview()) trigger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
// Return to last status:
|
||||
if(getStatus()>0){
|
||||
pPoints->circles[getStatus()-1]->setHighlighted(false);
|
||||
pPoints->circles.pop_back();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
deletePreview();
|
||||
}
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//void RS_ActionDrawCircleTan3::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
|
||||
//}
|
||||
|
||||
//fixme, support command line
|
||||
|
||||
/*
|
||||
void RS_ActionDrawCircleTan3::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetFocus1: {
|
||||
bool ok;
|
||||
double m = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
ratio = m / major.magnitude();
|
||||
if (!isArc) {
|
||||
trigger();
|
||||
} else {
|
||||
setStatus(SetAngle1);
|
||||
}
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle1: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle1 = RS_Math::deg2rad(a);
|
||||
setStatus(SetAngle2);
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle2: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle2 = RS_Math::deg2rad(a);
|
||||
trigger();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
QStringList RS_ActionDrawCircleTan3::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleTan3::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetCircle1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the first line/arc/circle"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetCircle2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the second line/arc/circle"),
|
||||
tr("Back"));
|
||||
break;
|
||||
case SetCircle3:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the third line/arc/circle"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetCenter:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Select the center of the tangent circle"),
|
||||
tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawCircleTan3::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
85
actions/rs_actiondrawcircletan3.h
Normal file
85
actions/rs_actiondrawcircletan3.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw a common tangent circle of 3 existing circles
|
||||
* Problem of Appollonius
|
||||
|
||||
Copyright (C) 2012 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWCIRCLETAN3_H
|
||||
#define RS_ACTIONDRAWCIRCLETAN3_H
|
||||
|
||||
#include<vector>
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
struct RS_CircleData;
|
||||
class RS_AtomicEntity;
|
||||
|
||||
/**
|
||||
* Draw Common tangential circle of 3 given circles, i.e. Appollonius's problem
|
||||
*
|
||||
* @author Dongxu Li
|
||||
*/
|
||||
class RS_ActionDrawCircleTan3 : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetCircle1, // Setting the First Circle. */
|
||||
SetCircle2, // Setting the Second Circle. */
|
||||
SetCircle3, // Setting the Third Circle. */
|
||||
SetCenter // select the closest tangential Circle. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawCircleTan3(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawCircleTan3() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
bool getData();
|
||||
bool preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
// void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
// void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
void finish(bool updateTB=true) override;
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
//protected:
|
||||
private:
|
||||
std::vector<double> verifyCenter(const RS_Vector& center) const;
|
||||
std::vector<double> getRadii(RS_AtomicEntity* entity, const RS_Vector& center) const;
|
||||
RS_Entity* catchCircle(QMouseEvent* e);
|
||||
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
|
||||
//list of entity types supported by current action
|
||||
const EntityTypeList enTypeList = EntityTypeList {RS2::EntityArc, RS2::EntityCircle, RS2::EntityLine, RS2::EntityPoint};
|
||||
};
|
||||
|
||||
#endif
|
||||
319
actions/rs_actiondrawellipse4points.cpp
Normal file
319
actions/rs_actiondrawellipse4points.cpp
Normal file
@@ -0,0 +1,319 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
|
||||
Copyright (C) 2011 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawellipse4points.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_ellipse.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawEllipse4Points::Points {
|
||||
RS_VectorSolutions points;
|
||||
RS_CircleData cData;
|
||||
RS_EllipseData eData;
|
||||
bool valid,evalid;
|
||||
bool m_bUniqueEllipse{false}; //a message of non-unique ellipse is shown
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
RS_ActionDrawEllipse4Points::RS_ActionDrawEllipse4Points(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw ellipse from 4 points", container,
|
||||
graphicView)
|
||||
, pPoints(new Points{})
|
||||
{
|
||||
actionType=RS2::ActionDrawEllipse4Points;
|
||||
}
|
||||
|
||||
RS_ActionDrawEllipse4Points::~RS_ActionDrawEllipse4Points() = default;
|
||||
|
||||
void RS_ActionDrawEllipse4Points::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
if(getStatus() == SetPoint1) pPoints->points.clear();
|
||||
}
|
||||
|
||||
void RS_ActionDrawEllipse4Points::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
RS_Entity* en;
|
||||
if(getStatus()==SetPoint4 && pPoints->evalid){
|
||||
en=new RS_Ellipse(container, pPoints->eData);
|
||||
}else{
|
||||
en=new RS_Circle(container, pPoints->cData);
|
||||
}
|
||||
|
||||
// update undo list:
|
||||
deletePreview();
|
||||
container->addEntity(en);
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(en);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
RS_Vector rz = graphicView->getRelativeZero();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(rz);
|
||||
drawSnapper();
|
||||
setStatus(SetPoint1);
|
||||
// RS_DEBUG->print("RS_ActionDrawEllipse4Point::trigger():" " entity added: %d", ellipse->getId());
|
||||
|
||||
// RS_DEBUG->print("RS_ActionDrawEllipse4Point::trigger():" " entity added: %d", ellipse->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipse4Points::mouseMoveEvent(QMouseEvent* e) {
|
||||
// RS_DEBUG->print("RS_ActionDrawEllipse4Point::mouseMoveEvent begin");
|
||||
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
pPoints->points.set(getStatus(),mouse);
|
||||
if(preparePreview()) {
|
||||
switch(getStatus()) {
|
||||
case SetPoint2:
|
||||
case SetPoint3:
|
||||
if(pPoints->valid){
|
||||
RS_Circle* circle=new RS_Circle(preview.get(), pPoints->cData);
|
||||
deletePreview();
|
||||
preview->addEntity(circle);
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
case SetPoint4:
|
||||
if(pPoints->evalid){
|
||||
deletePreview();
|
||||
RS_Ellipse* e=new RS_Ellipse(preview.get(), pPoints->eData);
|
||||
preview->addEntity(e);
|
||||
drawPreview();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
// RS_DEBUG->print("RS_ActionDrawEllipse4Point::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
bool RS_ActionDrawEllipse4Points::preparePreview(){
|
||||
pPoints->valid=false;
|
||||
switch(getStatus()) {
|
||||
case SetPoint2:
|
||||
case SetPoint3:
|
||||
{
|
||||
RS_Circle c(preview.get(), pPoints->cData);
|
||||
pPoints->valid= c.createFrom3P(pPoints->points);
|
||||
if(pPoints->valid){
|
||||
pPoints->cData = c.getData();
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case SetPoint4:
|
||||
{
|
||||
int j=SetPoint4;
|
||||
pPoints->evalid=false;
|
||||
if ((pPoints->points.get(j) - pPoints->points.get(j-1)).squared() <RS_TOLERANCE15){
|
||||
RS_Circle c(preview.get(), pPoints->cData);
|
||||
pPoints->valid= c.createFrom3P(pPoints->points);
|
||||
if (pPoints->valid) {
|
||||
pPoints->cData = c.getData();
|
||||
}
|
||||
} else {
|
||||
RS_Ellipse e{preview.get(), pPoints->eData};
|
||||
pPoints->valid= e.createFrom4P(pPoints->points);
|
||||
if (pPoints->valid) {
|
||||
pPoints->evalid=pPoints->valid;
|
||||
pPoints->eData = e.getData();
|
||||
pPoints->m_bUniqueEllipse=false;
|
||||
} else {
|
||||
pPoints->evalid=false;
|
||||
if (pPoints->m_bUniqueEllipse==false) {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Can not determine uniquely an ellipse"));
|
||||
pPoints->m_bUniqueEllipse=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return pPoints->valid;
|
||||
}
|
||||
|
||||
void RS_ActionDrawEllipse4Points::mouseReleaseEvent(QMouseEvent* e) {
|
||||
// Proceed to next status
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
}
|
||||
|
||||
// Return to last status:
|
||||
else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawEllipse4Points::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
pPoints->points.alloc(getStatus()+1);
|
||||
pPoints->points.set(getStatus(),mouse);
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
setStatus(SetPoint2);
|
||||
break;
|
||||
case SetPoint2:
|
||||
case SetPoint3:
|
||||
case SetPoint4:
|
||||
|
||||
if( preparePreview()) {
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
if(getStatus() == SetPoint4 ||
|
||||
(pPoints->points.get(getStatus()) - pPoints->points.get(getStatus()-1)).squared() <RS_TOLERANCE15) {
|
||||
//also draw the entity, if clicked on the same point twice
|
||||
trigger();
|
||||
}else{
|
||||
setStatus(getStatus()+1);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//fixme, support command line
|
||||
|
||||
/*
|
||||
void RS_ActionDrawEllipse4Point::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetFocus1: {
|
||||
bool ok;
|
||||
double m = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
ratio = m / major.magnitude();
|
||||
if (!isArc) {
|
||||
trigger();
|
||||
} else {
|
||||
setStatus(SetAngle1);
|
||||
}
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle1: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle1 = RS_Math::deg2rad(a);
|
||||
setStatus(SetAngle2);
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle2: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle2 = RS_Math::deg2rad(a);
|
||||
trigger();
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
QStringList RS_ActionDrawEllipse4Points::getAvailableCommands() {
|
||||
return {};
|
||||
}
|
||||
|
||||
void RS_ActionDrawEllipse4Points::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetPoint1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the first point on ellipse"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetPoint2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the second point on ellipse"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetPoint3:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the third point on ellipse"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetPoint4:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the fourth point on ellipse"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipse4Points::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
75
actions/rs_actiondrawellipse4points.h
Normal file
75
actions/rs_actiondrawellipse4points.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
|
||||
Copyright (C) 2011 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWELLIPSE4POINTS_H
|
||||
#define RS_ACTIONDRAWELLIPSE4POINTS_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
struct RS_CircleData;
|
||||
struct RS_EllipseData;
|
||||
|
||||
/**
|
||||
* Draw ellipse in XY direction by 4 points on ellipse
|
||||
*
|
||||
* @author Dongxu Li
|
||||
*/
|
||||
class RS_ActionDrawEllipse4Points : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetPoint1, // Setting the First Point. */
|
||||
SetPoint2, // Setting the Second Point. */
|
||||
SetPoint3, // Setting the Third Point. */
|
||||
SetPoint4 // Setting the Last Point. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawEllipse4Points(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawEllipse4Points() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
bool preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
// void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
protected:
|
||||
// 4 points on ellipse
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
};
|
||||
|
||||
#endif
|
||||
393
actions/rs_actiondrawellipseaxis.cpp
Normal file
393
actions/rs_actiondrawellipseaxis.cpp
Normal file
@@ -0,0 +1,393 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
#include<cmath>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawellipseaxis.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_ellipse.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawEllipseAxis::Points {
|
||||
/** Center of ellipse */
|
||||
RS_Vector center;
|
||||
/** Endpoint of major axis */
|
||||
RS_Vector m_vMajorP;
|
||||
/** Ratio major / minor */
|
||||
double ratio;
|
||||
/** Start angle */
|
||||
double angle1;
|
||||
/** End angle */
|
||||
double angle2;
|
||||
/** Do we produce an arc (true) or full ellipse (false) */
|
||||
bool isArc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param isArc true if this action will produce an ellipse arc.
|
||||
* false if it will produce a full ellipse.
|
||||
*/
|
||||
RS_ActionDrawEllipseAxis::RS_ActionDrawEllipseAxis(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView,
|
||||
bool isArc)
|
||||
:RS_PreviewActionInterface("Draw ellipse with axis",
|
||||
container, graphicView)
|
||||
,pPoints(new Points{{}, {}, 0.5, 0., isArc?2.*M_PI:0., isArc})
|
||||
{
|
||||
actionType=isArc?RS2::ActionDrawEllipseArcAxis:RS2::ActionDrawEllipseAxis;
|
||||
}
|
||||
|
||||
RS_ActionDrawEllipseAxis::~RS_ActionDrawEllipseAxis() = default;
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseAxis::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
if (status==SetCenter) {
|
||||
pPoints->center = {};
|
||||
}
|
||||
if (status<=SetMajor) {
|
||||
pPoints->m_vMajorP = {};
|
||||
}
|
||||
if (status<=SetMinor) {
|
||||
pPoints->ratio = 0.5;
|
||||
}
|
||||
if (status<=SetAngle1) {
|
||||
pPoints->angle1 = 0.0;
|
||||
}
|
||||
if (status<=SetAngle2) {
|
||||
pPoints->angle2 = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseAxis::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
RS_Ellipse* ellipse = new RS_Ellipse{container,
|
||||
{pPoints->center, pPoints->m_vMajorP, pPoints->ratio,
|
||||
pPoints->angle1, pPoints->angle2, false}
|
||||
};
|
||||
if (pPoints->ratio > 1.){
|
||||
ellipse->switchMajorMinor();
|
||||
}
|
||||
ellipse->setLayerToActive();
|
||||
ellipse->setPenToActive();
|
||||
|
||||
container->addEntity(ellipse);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(ellipse);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
RS_Vector rz = graphicView->getRelativeZero();
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(rz);
|
||||
drawSnapper();
|
||||
|
||||
setStatus(SetCenter);
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawEllipseAxis::trigger():"
|
||||
" entity added: %d", ellipse->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseAxis::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawEllipseAxis::mouseMoveEvent begin");
|
||||
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
|
||||
switch (getStatus()) {
|
||||
// case SetCenter:
|
||||
// break;
|
||||
|
||||
case SetMajor:
|
||||
if (pPoints->center.valid) {
|
||||
deletePreview();
|
||||
preview->addEntity(new RS_Ellipse{preview.get(),
|
||||
{pPoints->center, mouse-pPoints->center, 0.5, 0.0,
|
||||
pPoints->isArc?2.*M_PI:0.
|
||||
, false}});
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
case SetMinor:
|
||||
if (pPoints->center.valid && pPoints->m_vMajorP.valid) {
|
||||
deletePreview();
|
||||
RS_Line line{pPoints->center-pPoints->m_vMajorP, pPoints->center+pPoints->m_vMajorP};
|
||||
double d = line.getDistanceToPoint(mouse);
|
||||
pPoints->ratio = d/(line.getLength()/2);
|
||||
preview->addEntity(new RS_Ellipse{preview.get(),
|
||||
{pPoints->center, pPoints->m_vMajorP, pPoints->ratio, 0., pPoints->isArc?2.*M_PI:0.
|
||||
, false}});
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle1:
|
||||
if (pPoints->center.valid && pPoints->m_vMajorP.valid) {
|
||||
deletePreview();
|
||||
|
||||
//angle1 = center.angleTo(mouse);
|
||||
|
||||
RS_Vector m = mouse;
|
||||
m.rotate(pPoints->center, -pPoints->m_vMajorP.angle());
|
||||
RS_Vector v = m-pPoints->center;
|
||||
v.y /= pPoints->ratio;
|
||||
pPoints->angle1 = v.angle(); // + m_vMajorP.angle();
|
||||
|
||||
preview->addEntity(new RS_Line{preview.get(), pPoints->center, mouse});
|
||||
|
||||
preview->addEntity(new RS_Ellipse{preview.get(),
|
||||
{pPoints->center, pPoints->m_vMajorP, pPoints->ratio, pPoints->angle1, pPoints->angle1+1.0
|
||||
, false}});
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle2:
|
||||
if (pPoints->center.valid && pPoints->m_vMajorP.valid) {
|
||||
deletePreview();
|
||||
//angle2 = center.angleTo(mouse);
|
||||
|
||||
RS_Vector m = mouse;
|
||||
m.rotate(pPoints->center, -pPoints->m_vMajorP.angle());
|
||||
RS_Vector v = m-pPoints->center;
|
||||
v.y /= pPoints->ratio;
|
||||
pPoints->angle2 = v.angle(); // + m_vMajorP.angle();
|
||||
|
||||
preview->addEntity(new RS_Line{preview.get(), pPoints->center, mouse});
|
||||
|
||||
preview->addEntity(new RS_Ellipse{preview.get(),
|
||||
{pPoints->center, pPoints->m_vMajorP,
|
||||
pPoints->ratio,
|
||||
pPoints->angle1, pPoints->angle2
|
||||
, false}});
|
||||
drawPreview();
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawEllipseAxis::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseAxis::mouseReleaseEvent(QMouseEvent* e) {
|
||||
// Proceed to next status
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
}
|
||||
|
||||
// Return to last status:
|
||||
else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseAxis::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e) return;
|
||||
RS_Vector const& mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
pPoints->center = mouse;
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
setStatus(SetMajor);
|
||||
break;
|
||||
|
||||
case SetMajor:
|
||||
pPoints->m_vMajorP = mouse- pPoints->center;
|
||||
setStatus(SetMinor);
|
||||
break;
|
||||
|
||||
case SetMinor: {
|
||||
RS_Line line{pPoints->center-pPoints->m_vMajorP, pPoints->center+pPoints->m_vMajorP};
|
||||
double d = line.getDistanceToPoint(mouse);
|
||||
pPoints->ratio = d/(line.getLength()/2);
|
||||
if (!pPoints->isArc) {
|
||||
trigger();
|
||||
setStatus(SetCenter);
|
||||
} else {
|
||||
setStatus(SetAngle1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle1: {
|
||||
//angle1 = center.angleTo(mouse);
|
||||
RS_Vector m = mouse;
|
||||
m.rotate(pPoints->center, -pPoints->m_vMajorP.angle());
|
||||
RS_Vector v = m-pPoints->center;
|
||||
v.y /= pPoints->ratio;
|
||||
pPoints->angle1 = v.angle();
|
||||
setStatus(SetAngle2);
|
||||
} break;
|
||||
|
||||
case SetAngle2: {
|
||||
//angle2 = center.angleTo(mouse);
|
||||
RS_Vector m = mouse;
|
||||
m.rotate(pPoints->center, -pPoints->m_vMajorP.angle());
|
||||
RS_Vector v = m-pPoints->center;
|
||||
v.y /= pPoints->ratio;
|
||||
pPoints->angle2 = v.angle();
|
||||
trigger();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseAxis::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetMinor: {
|
||||
bool ok;
|
||||
double m = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
e->accept();
|
||||
pPoints->ratio = m / pPoints->m_vMajorP.magnitude();
|
||||
if (!pPoints->isArc) {
|
||||
trigger();
|
||||
} else {
|
||||
setStatus(SetAngle1);
|
||||
}
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle1: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
e->accept();
|
||||
pPoints->angle1 = RS_Math::deg2rad(a);
|
||||
setStatus(SetAngle2);
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle2: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
e->accept();
|
||||
pPoints->angle2 = RS_Math::deg2rad(a);
|
||||
trigger();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDrawEllipseAxis::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseAxis::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify ellipse center"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetMajor:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify endpoint of major axis"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetMinor:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify endpoint or length of minor axis:"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetAngle1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify start angle"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetAngle2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify end angle"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseAxis::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
77
actions/rs_actiondrawellipseaxis.h
Normal file
77
actions/rs_actiondrawellipseaxis.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWELLIPSEAXIS_H
|
||||
#define RS_ACTIONDRAWELLIPSEAXIS_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw ellipses
|
||||
* with a center point and the endpoints of minor and major axis.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawEllipseAxis : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetCenter, /**< Setting the center. */
|
||||
SetMajor, /**< Setting endpoint of major axis. */
|
||||
SetMinor, /**< Setting minor/major ratio. */
|
||||
SetAngle1, /**< Setting start angle. */
|
||||
SetAngle2 /**< Setting end angle. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawEllipseAxis(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView,
|
||||
bool isArc);
|
||||
~RS_ActionDrawEllipseAxis() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
protected:
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
};
|
||||
|
||||
#endif
|
||||
311
actions/rs_actiondrawellipsecenter3points.cpp
Normal file
311
actions/rs_actiondrawellipsecenter3points.cpp
Normal file
@@ -0,0 +1,311 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
|
||||
Copyright (C) 2011-2015 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawellipsecenter3points.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_circle.h"
|
||||
#include "rs_ellipse.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawEllipseCenter3Points::Points {
|
||||
RS_VectorSolutions points;
|
||||
RS_CircleData cData;
|
||||
RS_EllipseData eData;
|
||||
bool valid{false};
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
RS_ActionDrawEllipseCenter3Points::RS_ActionDrawEllipseCenter3Points(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw ellipse by center and 3 points",
|
||||
container, graphicView)
|
||||
, pPoints(new Points{})
|
||||
{
|
||||
actionType=RS2::ActionDrawEllipseCenter3Points;
|
||||
}
|
||||
|
||||
RS_ActionDrawEllipseCenter3Points::~RS_ActionDrawEllipseCenter3Points() = default;
|
||||
|
||||
void RS_ActionDrawEllipseCenter3Points::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
if (status==SetCenter) {
|
||||
pPoints->points.clear();
|
||||
}
|
||||
drawSnapper();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseCenter3Points::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
|
||||
RS_Ellipse* ellipse=new RS_Ellipse(container, pPoints->eData);
|
||||
|
||||
deletePreview();
|
||||
container->addEntity(ellipse);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(ellipse);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
graphicView->moveRelativeZero(ellipse->getCenter());
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
drawSnapper();
|
||||
|
||||
setStatus(SetCenter);
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawEllipseCenter3Points::trigger():"
|
||||
" entity added: %d", ellipse->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseCenter3Points::mouseMoveEvent(QMouseEvent* e) {
|
||||
// RS_DEBUG->print("RS_ActionDrawEllipseCenter3Points::mouseMoveEvent begin");
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
if(getStatus() == SetCenter) return;
|
||||
pPoints->points.resize(getStatus());
|
||||
pPoints->points.push_back(mouse);
|
||||
if(preparePreview()) {
|
||||
switch(getStatus()) {
|
||||
|
||||
case SetPoint1:
|
||||
{
|
||||
RS_Circle* circle=new RS_Circle(preview.get(), pPoints->cData);
|
||||
deletePreview();
|
||||
preview->addEntity(circle);
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
case SetPoint2:
|
||||
case SetPoint3:
|
||||
{
|
||||
deletePreview();
|
||||
RS_Ellipse* e=new RS_Ellipse(preview.get(), pPoints->eData);
|
||||
preview->addEntity(e);
|
||||
drawPreview();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
RS_DEBUG->print("RS_ActionDrawEllipseCenter3Points::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
bool RS_ActionDrawEllipseCenter3Points::preparePreview(){
|
||||
pPoints->valid=false;
|
||||
switch(getStatus()) {
|
||||
case SetPoint1:
|
||||
{
|
||||
RS_Circle c(preview.get(), pPoints->cData);
|
||||
pPoints->valid= c.createFromCR(pPoints->points.at(0),
|
||||
pPoints->points.get(0).distanceTo(pPoints->points.get(1)));
|
||||
|
||||
if (pPoints->valid){
|
||||
pPoints->cData = c.getData();
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case SetPoint2:
|
||||
case SetPoint3:
|
||||
{
|
||||
RS_Ellipse e(preview.get(), pPoints->eData);
|
||||
pPoints->valid= e.createFromCenter3Points(pPoints->points);
|
||||
if (pPoints->valid){
|
||||
pPoints->eData = e.getData();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return pPoints->valid;
|
||||
}
|
||||
|
||||
void RS_ActionDrawEllipseCenter3Points::mouseReleaseEvent(QMouseEvent* e) {
|
||||
// Proceed to next status
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
}
|
||||
|
||||
// Return to last status:
|
||||
else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseCenter3Points::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e) return;
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
pPoints->points.alloc(getStatus()+1);
|
||||
pPoints->points.set(getStatus(), mouse);
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
setStatus(SetPoint1);
|
||||
break;
|
||||
case SetPoint1:
|
||||
case SetPoint2:
|
||||
for(int i=0;i<getStatus()-1;i++) {
|
||||
if( (mouse-pPoints->points.get(i)).squared() < RS_TOLERANCE15) {
|
||||
return;//refuse to accept points already chosen
|
||||
}
|
||||
}
|
||||
// setStatus(getStatus()+1);
|
||||
// break;
|
||||
// fall-through
|
||||
case SetPoint3:
|
||||
if( preparePreview()) {
|
||||
if(getStatus() == SetPoint3) {
|
||||
trigger();
|
||||
}else{
|
||||
setStatus(getStatus()+1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//fixme, support command line
|
||||
|
||||
/*
|
||||
void RS_ActionDrawEllipseCenter3Points::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetFocus1: {
|
||||
bool ok;
|
||||
double m = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
ratio = m / major.magnitude();
|
||||
if (!isArc) {
|
||||
trigger();
|
||||
} else {
|
||||
setStatus(SetAngle1);
|
||||
}
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle1: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle1 = RS_Math::deg2rad(a);
|
||||
setStatus(SetAngle2);
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle2: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle2 = RS_Math::deg2rad(a);
|
||||
trigger();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
QStringList RS_ActionDrawEllipseCenter3Points::getAvailableCommands() {
|
||||
return {};
|
||||
}
|
||||
|
||||
void RS_ActionDrawEllipseCenter3Points::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetCenter:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the center of ellipse"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetPoint1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the first point on ellipse"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetPoint2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the second point on ellipse"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetPoint3:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the third point on ellipse"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawEllipseCenter3Points::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
71
actions/rs_actiondrawellipsecenter3points.h
Normal file
71
actions/rs_actiondrawellipsecenter3points.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
|
||||
Copyright (C) 2011-2015 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWELLIPSECENTER3POINTS_H
|
||||
#define RS_ACTIONDRAWELLIPSECENTER3POINTS_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
/**
|
||||
* Draw ellipse by center and 3 points on ellipse
|
||||
*
|
||||
* @author Dongxu Li
|
||||
*/
|
||||
class RS_ActionDrawEllipseCenter3Points : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetCenter=0, // Setting the Center. */
|
||||
SetPoint1=1, // Setting the First Point. */
|
||||
SetPoint2=2, // Setting the Second Point. */
|
||||
SetPoint3=3 // Setting the Third Point. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawEllipseCenter3Points(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawEllipseCenter3Points() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
bool preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
// void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
private:
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
};
|
||||
|
||||
#endif
|
||||
261
actions/rs_actiondrawellipsefocipoint.cpp
Normal file
261
actions/rs_actiondrawellipsefocipoint.cpp
Normal file
@@ -0,0 +1,261 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
|
||||
Copyright (C) 2011 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#include "rs_actiondrawellipsefocipoint.h"
|
||||
#include<cmath>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_ellipse.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawEllipseFociPoint::Points {
|
||||
// Foci of ellipse
|
||||
RS_Vector focus1,focus2;
|
||||
// A point on ellipse
|
||||
RS_Vector point;
|
||||
RS_Vector center,major;
|
||||
double c; //hold half of distance between foci
|
||||
double d; //hold half of distance
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
RS_ActionDrawEllipseFociPoint::RS_ActionDrawEllipseFociPoint(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw ellipse by foci and a point",
|
||||
container, graphicView)
|
||||
, pPoints(new Points{})
|
||||
{
|
||||
actionType=RS2::ActionDrawEllipseFociPoint;
|
||||
}
|
||||
|
||||
RS_ActionDrawEllipseFociPoint::~RS_ActionDrawEllipseFociPoint() = default;
|
||||
|
||||
void RS_ActionDrawEllipseFociPoint::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
if (status==SetFocus1) {
|
||||
pPoints->focus1.valid=false;
|
||||
}
|
||||
}
|
||||
|
||||
double RS_ActionDrawEllipseFociPoint::findRatio() const
|
||||
{
|
||||
return sqrt(pPoints->d*pPoints->d-pPoints->c*pPoints->c)/pPoints->d;
|
||||
|
||||
}
|
||||
|
||||
void RS_ActionDrawEllipseFociPoint::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
RS_Ellipse* ellipse = new RS_Ellipse{container,
|
||||
{pPoints->center,
|
||||
pPoints->major*pPoints->d,
|
||||
findRatio(),
|
||||
0., 0.,false}
|
||||
};
|
||||
ellipse->setLayerToActive();
|
||||
ellipse->setPenToActive();
|
||||
|
||||
container->addEntity(ellipse);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(ellipse);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
// RS_Vector rz = graphicView->getRelativeZero();
|
||||
graphicView->moveRelativeZero(ellipse->getCenter());
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
drawSnapper();
|
||||
|
||||
setStatus(SetFocus1);
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawEllipseFociPoint::trigger():"
|
||||
" entity added: %d", ellipse->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseFociPoint::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawEllipseFociPoint::mouseMoveEvent begin");
|
||||
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
|
||||
switch (getStatus()) {
|
||||
|
||||
|
||||
case SetPoint:
|
||||
pPoints->point=mouse;
|
||||
pPoints->d=0.5*(pPoints->focus1.distanceTo(pPoints->point) +
|
||||
pPoints->focus2.distanceTo(pPoints->point));
|
||||
if (pPoints->d > pPoints->c+ RS_TOLERANCE) {
|
||||
deletePreview();
|
||||
preview->addEntity(new RS_Ellipse{preview.get(),
|
||||
{pPoints->center,
|
||||
pPoints->major*pPoints->d,
|
||||
findRatio(),
|
||||
0., 0.,false}});
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawEllipseFociPoint::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseFociPoint::mouseReleaseEvent(QMouseEvent* e) {
|
||||
// Proceed to next status
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
}
|
||||
|
||||
// Return to last status:
|
||||
else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseFociPoint::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (e==NULL) {
|
||||
return;
|
||||
}
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetFocus1:
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
pPoints->focus1=mouse;
|
||||
setStatus(SetFocus2);
|
||||
break;
|
||||
|
||||
case SetFocus2:
|
||||
pPoints->c = 0.5*pPoints->focus1.distanceTo(mouse);
|
||||
if(pPoints->c > RS_TOLERANCE){
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
pPoints->focus2=mouse;
|
||||
pPoints->center=(pPoints->focus1+pPoints->focus2)*0.5;
|
||||
pPoints->major=pPoints->focus1-pPoints->center;
|
||||
pPoints->major /= pPoints->c ;
|
||||
setStatus(SetPoint);
|
||||
}
|
||||
break;
|
||||
case SetPoint:
|
||||
pPoints->point=mouse;
|
||||
pPoints->d=0.5*(pPoints->focus1.distanceTo(pPoints->point)+pPoints->focus2.distanceTo(pPoints->point));
|
||||
if (pPoints->d > pPoints->c+ RS_TOLERANCE) {
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
trigger();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawEllipseFociPoint::commandEvent(RS_CommandEvent* e) {
|
||||
QString cmd = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", cmd)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(": ")+
|
||||
tr("specify a point on ellipse, or total distance to foci")
|
||||
);
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
if(getStatus()==SetPoint){
|
||||
bool ok;
|
||||
double a = RS_Math::eval(cmd, &ok);
|
||||
if (ok) {
|
||||
pPoints->d=0.5*fabs(a);
|
||||
if (pPoints->d > pPoints->c + RS_TOLERANCE) {
|
||||
trigger();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Total distance %1 is smaller than distance between foci").arg(fabs(a)));
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QStringList RS_ActionDrawEllipseFociPoint::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseFociPoint::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetFocus1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first focus of ellipse"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetFocus2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify second focus of ellipse"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetPoint:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify a point on ellipse or total distance to foci"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawEllipseFociPoint::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
71
actions/rs_actiondrawellipsefocipoint.h
Normal file
71
actions/rs_actiondrawellipsefocipoint.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
|
||||
Copyright (C) 2011 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWELLIPSEFOCIPOINT_H
|
||||
#define RS_ACTIONDRAWELLIPSEFOCIPOINT_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
/**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
*
|
||||
* @author Dongxu Li
|
||||
*/
|
||||
class RS_ActionDrawEllipseFociPoint : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetFocus1, // Setting the first focus. */
|
||||
SetFocus2, // Setting the second focus. */
|
||||
SetPoint // Setting a point on ellipse
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawEllipseFociPoint(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawEllipseFociPoint() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
protected:
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
private:
|
||||
double findRatio() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
306
actions/rs_actiondrawellipseinscribe.cpp
Normal file
306
actions/rs_actiondrawellipseinscribe.cpp
Normal file
@@ -0,0 +1,306 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
|
||||
Copyright (C) 2011 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawellipseinscribe.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_ellipse.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawEllipseInscribe::Points {
|
||||
std::vector<RS_Line*> lines;
|
||||
RS_EllipseData eData;
|
||||
bool valid{false};
|
||||
};
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
RS_ActionDrawEllipseInscribe::RS_ActionDrawEllipseInscribe(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw ellipse inscribed",
|
||||
container, graphicView)
|
||||
, pPoints(new Points{})
|
||||
{
|
||||
actionType=RS2::ActionDrawEllipseInscribe;
|
||||
}
|
||||
|
||||
RS_ActionDrawEllipseInscribe::~RS_ActionDrawEllipseInscribe() = default;
|
||||
|
||||
void RS_ActionDrawEllipseInscribe::clearLines(bool checkStatus)
|
||||
{
|
||||
while(pPoints->lines.size() ){
|
||||
if(checkStatus && (int) pPoints->lines.size()<=getStatus() )
|
||||
break;
|
||||
pPoints->lines.back()->setHighlighted(false);
|
||||
graphicView->drawEntity(pPoints->lines.back());
|
||||
pPoints->lines.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawEllipseInscribe::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
if(status>=0) {
|
||||
RS_Snapper::suspend();
|
||||
}
|
||||
clearLines(true);
|
||||
}
|
||||
|
||||
void RS_ActionDrawEllipseInscribe::finish(bool updateTB){
|
||||
clearLines(false);
|
||||
RS_PreviewActionInterface::finish(updateTB);
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseInscribe::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
|
||||
RS_Ellipse* ellipse=new RS_Ellipse(container, pPoints->eData);
|
||||
|
||||
deletePreview();
|
||||
container->addEntity(ellipse);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(ellipse);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
for(RS_Line*const p: pPoints->lines) {
|
||||
if(!p) continue;
|
||||
p->setHighlighted(false);
|
||||
graphicView->drawEntity(p);
|
||||
|
||||
}
|
||||
drawSnapper();
|
||||
|
||||
clearLines(false);
|
||||
setStatus(SetLine1);
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawEllipse4Line::trigger():"
|
||||
" entity added: %d", ellipse->getId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseInscribe::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawEllipse4Line::mouseMoveEvent begin");
|
||||
|
||||
if(getStatus() == SetLine4) {
|
||||
RS_Entity* en = catchEntity(e, RS2::EntityLine, RS2::ResolveAll);
|
||||
if(!en) return;
|
||||
if(!(en->isVisible() && en->rtti()== RS2::EntityLine)) return;
|
||||
for(auto p: pPoints->lines){
|
||||
if(en == p) return; //do not pull in the same line again
|
||||
}
|
||||
|
||||
if(en->getParent() && en->getParent()->ignoredOnModification()){
|
||||
return;
|
||||
}
|
||||
|
||||
deletePreview();
|
||||
|
||||
clearLines(true);
|
||||
pPoints->lines.push_back(static_cast<RS_Line*>(en));
|
||||
if(preparePreview()) {
|
||||
pPoints->lines.back()->setHighlighted(true);
|
||||
graphicView->drawEntity(pPoints->lines.back());
|
||||
RS_Ellipse* e=new RS_Ellipse(preview.get(), pPoints->eData);
|
||||
preview->addEntity(e);
|
||||
drawPreview();
|
||||
}
|
||||
|
||||
}
|
||||
RS_DEBUG->print("RS_ActionDrawEllipse4Line::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
bool RS_ActionDrawEllipseInscribe::preparePreview(){
|
||||
pPoints->valid=false;
|
||||
if(getStatus() == SetLine4) {
|
||||
RS_Ellipse e{preview.get(), RS_EllipseData()};
|
||||
pPoints->valid= e.createInscribeQuadrilateral(pPoints->lines);
|
||||
if (pPoints->valid){
|
||||
pPoints->eData = e.getData();
|
||||
} else if ( RS_DIALOGFACTORY){
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Can not determine uniquely an ellipse"));
|
||||
}
|
||||
}
|
||||
return pPoints->valid;
|
||||
}
|
||||
|
||||
void RS_ActionDrawEllipseInscribe::mouseReleaseEvent(QMouseEvent* e) {
|
||||
// Proceed to next status
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
if (!e) return;
|
||||
RS_Entity* en = catchEntity(e, RS2::EntityLine, RS2::ResolveAll);
|
||||
if(!en) return;
|
||||
if(!(en->isVisible() && en->rtti()== RS2::EntityLine)) return;
|
||||
for(int i=0; i<getStatus(); ++i) {
|
||||
if(en->getId() == pPoints->lines[i]->getId()) return; //do not pull in the same line again
|
||||
}
|
||||
if(en->getParent()) {
|
||||
if ( en->getParent()->ignoredOnModification()) return;
|
||||
}
|
||||
clearLines(true);
|
||||
pPoints->lines.push_back(static_cast<RS_Line*>(en));
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetLine1:
|
||||
case SetLine2:
|
||||
case SetLine3:
|
||||
en->setHighlighted(true);
|
||||
graphicView->drawEntity(en);
|
||||
setStatus(getStatus()+1);
|
||||
break;
|
||||
case SetLine4:
|
||||
if( preparePreview()) {
|
||||
trigger();
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
// Return to last status:
|
||||
if(getStatus()>0){
|
||||
clearLines(true);
|
||||
pPoints->lines.back()->setHighlighted(false);
|
||||
graphicView->drawEntity(pPoints->lines.back());
|
||||
pPoints->lines.pop_back();
|
||||
deletePreview();
|
||||
}
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//void RS_ActionDrawEllipseInscribe::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
|
||||
//}
|
||||
|
||||
//fixme, support command line
|
||||
|
||||
/*
|
||||
void RS_ActionDrawEllipse4Line::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetFocus1: {
|
||||
bool ok;
|
||||
double m = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
ratio = m / major.magnitude();
|
||||
if (!isArc) {
|
||||
trigger();
|
||||
} else {
|
||||
setStatus(SetAngle1);
|
||||
}
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle1: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle1 = RS_Math::deg2rad(a);
|
||||
setStatus(SetAngle2);
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle2: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
angle2 = RS_Math::deg2rad(a);
|
||||
trigger();
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
QStringList RS_ActionDrawEllipseInscribe::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawEllipseInscribe::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetLine1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the first line"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetLine2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the second line"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetLine3:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the third line"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetLine4:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the fourth line"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawEllipseInscribe::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
74
actions/rs_actiondrawellipseinscribe.h
Normal file
74
actions/rs_actiondrawellipseinscribe.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
|
||||
Copyright (C) 2011 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWELLIPSEINSCRIBE_H
|
||||
#define RS_ACTIONDRAWELLIPSEINSCRIBE_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
/**
|
||||
* Draw ellipse by foci and a point on ellipse
|
||||
*
|
||||
* @author Dongxu Li
|
||||
*/
|
||||
class RS_ActionDrawEllipseInscribe : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetLine1, // Setting the First Line. */
|
||||
SetLine2, // Setting the Second Line. */
|
||||
SetLine3, // Setting the Third Line. */
|
||||
SetLine4 // Setting the Last Line. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawEllipseInscribe(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawEllipseInscribe() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
bool preparePreview();
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
// void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
// void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
void finish(bool updateTB=true) override;
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
protected:
|
||||
// 4 points on ellipse
|
||||
private:
|
||||
void clearLines(bool checkStatus=false);
|
||||
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
};
|
||||
|
||||
#endif
|
||||
238
actions/rs_actiondrawhatch.cpp
Normal file
238
actions/rs_actiondrawhatch.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
#include <iostream>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawhatch.h"
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_information.h"
|
||||
#include "rs_hatch.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
RS_ActionDrawHatch::RS_ActionDrawHatch(RS_EntityContainer& container, RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw Hatch", container, graphicView)
|
||||
, data{new RS_HatchData{}}
|
||||
{
|
||||
actionType = RS2::ActionDrawHatch;
|
||||
}
|
||||
|
||||
RS_ActionDrawHatch::~RS_ActionDrawHatch() = default;
|
||||
|
||||
void RS_ActionDrawHatch::setShowArea(bool s){
|
||||
m_bShowArea=s;
|
||||
}
|
||||
|
||||
void RS_ActionDrawHatch::init(int status) {
|
||||
RS_ActionInterface::init(status);
|
||||
|
||||
RS_Hatch tmp(container, *data);
|
||||
tmp.setLayerToActive();
|
||||
tmp.setPenToActive();
|
||||
if (RS_DIALOGFACTORY->requestHatchDialog(&tmp)) {
|
||||
*data = tmp.getData();
|
||||
trigger();
|
||||
finish(false);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
|
||||
} else {
|
||||
finish(false);
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawHatch::trigger() {
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawHatch::trigger()");
|
||||
|
||||
//if (pos.valid) {
|
||||
//deletePreview();
|
||||
RS_Entity* e;
|
||||
|
||||
// deselect unhatchable entities:
|
||||
for(auto e: *container){
|
||||
if (e->isSelected() &&
|
||||
(e->rtti()==RS2::EntityHatch ||
|
||||
/* e->rtti()==RS2::EntityEllipse ||*/ e->rtti()==RS2::EntityPoint ||
|
||||
e->rtti()==RS2::EntityMText || e->rtti()==RS2::EntityText ||
|
||||
RS_Information::isDimension(e->rtti()))) {
|
||||
e->setSelected(false);
|
||||
}
|
||||
}
|
||||
for (e=container->firstEntity(RS2::ResolveAll); e;
|
||||
e=container->nextEntity(RS2::ResolveAll)) {
|
||||
if (e->isSelected() &&
|
||||
(e->rtti()==RS2::EntityHatch ||
|
||||
/* e->rtti()==RS2::EntityEllipse ||*/ e->rtti()==RS2::EntityPoint ||
|
||||
e->rtti()==RS2::EntityMText || e->rtti()==RS2::EntityText ||
|
||||
RS_Information::isDimension(e->rtti()))) {
|
||||
e->setSelected(false);
|
||||
}
|
||||
}
|
||||
|
||||
// look for selected contours:
|
||||
bool haveContour = false;
|
||||
for (e=container->firstEntity(RS2::ResolveAll); e;
|
||||
e=container->nextEntity(RS2::ResolveAll)) {
|
||||
if (e->isSelected()) {
|
||||
haveContour = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!haveContour) {
|
||||
std::cerr << "no contour selected\n";
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<RS_Hatch> hatch{new RS_Hatch{container, *data}};
|
||||
hatch->setLayerToActive();
|
||||
hatch->setPenToActive();
|
||||
RS_EntityContainer* loop = new RS_EntityContainer(hatch.get());
|
||||
loop->setPen(RS_Pen(RS2::FlagInvalid));
|
||||
|
||||
// add selected contour:
|
||||
for (RS_Entity* e=container->firstEntity(RS2::ResolveAll); e;
|
||||
e=container->nextEntity(RS2::ResolveAll)) {
|
||||
|
||||
if (e->isSelected()) {
|
||||
e->setSelected(false);
|
||||
// entity is part of a complex entity (spline, polyline, ..):
|
||||
if (e->getParent() &&
|
||||
// RVT - Don't de-delect the parent EntityPolyline, this is messing up the getFirst and getNext iterators
|
||||
// (e->getParent()->rtti()==RS2::EntitySpline ||
|
||||
// e->getParent()->rtti()==RS2::EntityPolyline)) {
|
||||
(e->getParent()->rtti()==RS2::EntitySpline)) {
|
||||
e->getParent()->setSelected(false);
|
||||
}
|
||||
RS_Entity* cp = e->clone();
|
||||
cp->setPen(RS_Pen(RS2::FlagInvalid));
|
||||
cp->reparent(loop);
|
||||
loop->addEntity(cp);
|
||||
}
|
||||
}
|
||||
|
||||
hatch->addEntity(loop);
|
||||
if (hatch->validate()) {
|
||||
container->addEntity(hatch.get());
|
||||
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(hatch.get());
|
||||
document->endUndoCycle();
|
||||
}
|
||||
hatch->update();
|
||||
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
|
||||
bool printArea = true;
|
||||
switch( hatch->getUpdateError()) {
|
||||
case RS_Hatch::HATCH_OK :
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Hatch created successfully."));
|
||||
break;
|
||||
case RS_Hatch::HATCH_INVALID_CONTOUR :
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Hatch Error: Invalid contour found!"));
|
||||
printArea = false;
|
||||
break;
|
||||
case RS_Hatch::HATCH_PATTERN_NOT_FOUND :
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Hatch Error: Pattern not found!"));
|
||||
break;
|
||||
case RS_Hatch::HATCH_TOO_SMALL :
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Hatch Error: Contour or pattern too small!"));
|
||||
break;
|
||||
case RS_Hatch::HATCH_AREA_TOO_BIG :
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Hatch Error: Contour too big!"));
|
||||
break;
|
||||
default :
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Hatch Error: Undefined Error!"));
|
||||
printArea = false;
|
||||
break;
|
||||
}
|
||||
if(m_bShowArea && printArea){
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Total hatch area = %1").
|
||||
arg(hatch->getTotalArea(),10,'g',8));
|
||||
}
|
||||
|
||||
hatch.release();
|
||||
|
||||
} else {
|
||||
hatch.reset();
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Invalid hatch area. Please check that "
|
||||
"the entities chosen form one or more closed contours."));
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawHatch::mouseMoveEvent(QMouseEvent*) {
|
||||
RS_DEBUG->print("RS_ActionDrawHatch::mouseMoveEvent begin");
|
||||
|
||||
/*if (getStatus()==SetPos) {
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
pos = mouse;
|
||||
|
||||
|
||||
deletePreview();
|
||||
if (hatch && !hatch->isVisible()) {
|
||||
hatch->setVisible(true);
|
||||
}
|
||||
offset = RS_Vector(graphicView->toGuiDX(pos.x),
|
||||
-graphicView->toGuiDY(pos.y));
|
||||
drawPreview();
|
||||
}*/
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawHatch::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawHatch::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
snapPoint(e);
|
||||
|
||||
switch (getStatus()) {
|
||||
case ShowDialog:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
//deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawHatch::updateMouseButtonHints() {
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
}
|
||||
|
||||
void RS_ActionDrawHatch::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
68
actions/rs_actiondrawhatch.h
Normal file
68
actions/rs_actiondrawhatch.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWHATCH_H
|
||||
#define RS_ACTIONDRAWHATCH_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
struct RS_HatchData;
|
||||
class RS_Hatch;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw hatches.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawHatch : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
ShowDialog /**< Showing the hatch dialog. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawHatch(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawHatch();
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
void setShowArea(bool s);
|
||||
|
||||
private:
|
||||
std::unique_ptr<RS_HatchData> data;
|
||||
bool m_bShowArea{true};
|
||||
};
|
||||
|
||||
#endif
|
||||
332
actions/rs_actiondrawimage.cpp
Normal file
332
actions/rs_actiondrawimage.cpp
Normal file
@@ -0,0 +1,332 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
#include<cmath>
|
||||
#include <QAction>
|
||||
#include <QImage>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_image.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_units.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_creation.h"
|
||||
#include "rs_actiondrawimage.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
|
||||
struct RS_ActionDrawImage::ImageData {
|
||||
RS_ImageData data;
|
||||
QImage img;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
RS_ActionDrawImage::RS_ActionDrawImage(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Image",
|
||||
container, graphicView)
|
||||
, pImg(new ImageData{})
|
||||
, lastStatus(ShowDialog)
|
||||
{
|
||||
actionType=RS2::ActionDrawImage;
|
||||
}
|
||||
|
||||
RS_ActionDrawImage::~RS_ActionDrawImage() = default;
|
||||
|
||||
|
||||
void RS_ActionDrawImage::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
reset();
|
||||
|
||||
pImg->data.file = RS_DIALOGFACTORY->requestImageOpenDialog();
|
||||
// RVT_PORT should we really redarw here?? graphicView->redraw();
|
||||
|
||||
if (!pImg->data.file.isEmpty()) {
|
||||
//std::cout << "file: " << pImg->data.file << "\n";
|
||||
//qDebug() << "file: " << pImg->data.file;
|
||||
|
||||
pImg->img = QImage(pImg->data.file);
|
||||
|
||||
setStatus(SetTargetPoint);
|
||||
} else {
|
||||
setFinished();
|
||||
//RS_DIALOGFACTORY->requestToolBar(RS2::ToolBarMain);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawImage::reset() {
|
||||
pImg->data = {
|
||||
0,
|
||||
{0.0,0.0},
|
||||
{1.0,0.0},
|
||||
{0.0,1.0},
|
||||
{1.0,1.0},
|
||||
"",
|
||||
50, 50, 0
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawImage::trigger() {
|
||||
deletePreview();
|
||||
|
||||
if (!pImg->data.file.isEmpty()) {
|
||||
RS_Creation creation(container, graphicView);
|
||||
creation.createImage(& pImg->data);
|
||||
}
|
||||
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->zoomAuto();
|
||||
finish(false);
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawImage::mouseMoveEvent(QMouseEvent* e) {
|
||||
if (getStatus() == SetTargetPoint) {
|
||||
pImg->data.insertionPoint = snapPoint(e);
|
||||
|
||||
deletePreview();
|
||||
//RS_Creation creation(preview, nullptr, false);
|
||||
//creation.createInsert(data);
|
||||
double const w=pImg->img.width();
|
||||
double const h=pImg->img.height();
|
||||
RS_Line* line = new RS_Line{preview.get(), {0., 0.}, {w, 0.}};
|
||||
preview->addEntity(line);
|
||||
line = new RS_Line{preview.get(), {w, 0.}, {w, h}};
|
||||
preview->addEntity(line);
|
||||
line = new RS_Line{preview.get(), {w, h}, {0., h}};
|
||||
preview->addEntity(line);
|
||||
line = new RS_Line{preview.get(), {0., h}, {0., 0.}};
|
||||
preview->addEntity(line);
|
||||
preview->scale({0., 0.},
|
||||
{pImg->data.uVector.magnitude(), pImg->data.uVector.magnitude()});
|
||||
preview->rotate({0.,0.}, pImg->data.uVector.angle());
|
||||
preview->move(pImg->data.insertionPoint);
|
||||
drawPreview();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawImage::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
//init(getStatus()-1);
|
||||
finish(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawImage::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (e==nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
pImg->data.insertionPoint = e->getCoordinate();
|
||||
trigger();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawImage::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetTargetPoint:
|
||||
if (checkCommand("angle", c)) {
|
||||
deletePreview();
|
||||
lastStatus = (Status)getStatus();
|
||||
setStatus(SetAngle);
|
||||
} else if (checkCommand("factor", c)) {
|
||||
deletePreview();
|
||||
lastStatus = (Status)getStatus();
|
||||
setStatus(SetFactor);
|
||||
} else if (checkCommand("dpi",c)) {
|
||||
deletePreview();
|
||||
lastStatus =(Status)getStatus();
|
||||
setStatus(SetDPI);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
setAngle(RS_Math::deg2rad(a));
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetFactor: {
|
||||
bool ok;
|
||||
double f = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
setFactor(f);
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetDPI : {
|
||||
bool ok;
|
||||
double dpi = RS_Math::eval(c, &ok);
|
||||
|
||||
if(ok) {
|
||||
setFactor(RS_Units::dpiToScale(dpi, document->getGraphicUnit()));
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double RS_ActionDrawImage::getAngle() const {
|
||||
return pImg->data.uVector.angle();
|
||||
}
|
||||
|
||||
void RS_ActionDrawImage::setAngle(double a) const{
|
||||
double l = pImg->data.uVector.magnitude();
|
||||
pImg->data.uVector.setPolar(l, a);
|
||||
pImg->data.vVector.setPolar(l, a+M_PI_2);
|
||||
}
|
||||
|
||||
double RS_ActionDrawImage::getFactor() const {
|
||||
return pImg->data.uVector.magnitude();
|
||||
}
|
||||
|
||||
void RS_ActionDrawImage::setFactor(double f) const {
|
||||
double a = pImg->data.uVector.angle();
|
||||
pImg->data.uVector.setPolar(f, a);
|
||||
pImg->data.vVector.setPolar(f, a+M_PI_2);
|
||||
}
|
||||
|
||||
double RS_ActionDrawImage::dpiToScale(double dpi) const {
|
||||
return RS_Units::dpiToScale(dpi, document->getGraphicUnit());
|
||||
}
|
||||
|
||||
|
||||
|
||||
double RS_ActionDrawImage::scaleToDpi(double scale) const {
|
||||
return RS_Units::scaleToDpi(scale, document->getGraphicUnit());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawImage::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
QStringList RS_ActionDrawImage::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetTargetPoint:
|
||||
cmd += command("angle");
|
||||
cmd += command("factor");
|
||||
cmd += command("dpi");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawImage::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawImage::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawImage::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetTargetPoint:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify reference point"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetAngle:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter angle:"),
|
||||
"");
|
||||
break;
|
||||
case SetFactor:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter factor:"),
|
||||
"");
|
||||
break;
|
||||
case SetDPI:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter dpi:"),
|
||||
"");
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// EOF
|
||||
104
actions/rs_actiondrawimage.h
Normal file
104
actions/rs_actiondrawimage.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWIMAGE_H
|
||||
#define RS_ACTIONDRAWIMAGE_H
|
||||
#include<memory>
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
struct RS_ImageData;
|
||||
class QImage;
|
||||
|
||||
/**
|
||||
* This action class can handle user events for inserting bitmaps into the
|
||||
* current drawing.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawImage : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
ShowDialog, /**< Dialog. */
|
||||
SetTargetPoint, /**< Setting the reference point. */
|
||||
SetAngle, /**< Setting angle in the command line. */
|
||||
SetFactor, /**< Setting factor in the command line. */
|
||||
SetDPI /**< Setting dpi in the command line. */
|
||||
//SetColumns, /**< Setting columns in the command line. */
|
||||
//SetRows, /**< Setting rows in the command line. */
|
||||
//SetColumnSpacing, /**< Setting column spacing in the command line. */
|
||||
//SetRowSpacing /**< Setting row spacing in the command line. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawImage(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawImage() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void reset();
|
||||
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void showOptions() override;
|
||||
void hideOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
// void updateToolBar() override;
|
||||
|
||||
double getAngle() const;
|
||||
|
||||
void setAngle(double a) const;
|
||||
|
||||
double getFactor() const;
|
||||
|
||||
void setFactor(double f) const;
|
||||
|
||||
double dpiToScale(double dpi) const;
|
||||
|
||||
double scaleToDpi(double scale) const;
|
||||
|
||||
|
||||
protected:
|
||||
struct ImageData;
|
||||
std::unique_ptr<ImageData> pImg;
|
||||
|
||||
/** Last status before entering option. */
|
||||
Status lastStatus;
|
||||
};
|
||||
|
||||
#endif
|
||||
481
actions/rs_actiondrawline.cpp
Normal file
481
actions/rs_actiondrawline.cpp
Normal file
@@ -0,0 +1,481 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2019 A. Stebich (librecad@mail.lordofbikes.de)
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "rs_actiondrawline.h"
|
||||
#include "rs_actioneditundo.h"
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commands.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawLine::History
|
||||
{
|
||||
explicit History(RS_ActionDrawLine::HistoryAction a,
|
||||
const RS_Vector& p,
|
||||
const RS_Vector& c,
|
||||
const int s) :
|
||||
histAct( a),
|
||||
prevPt( p),
|
||||
currPt( c),
|
||||
startOffset( s) {}
|
||||
|
||||
explicit History(const History& h) :
|
||||
histAct( h.histAct),
|
||||
prevPt( h.prevPt),
|
||||
currPt( h.currPt),
|
||||
startOffset( h.startOffset) {}
|
||||
|
||||
History& operator=(const History& rho) {
|
||||
histAct = rho.histAct;
|
||||
prevPt = rho.prevPt;
|
||||
currPt = rho.currPt;
|
||||
startOffset = rho.startOffset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
RS_ActionDrawLine::HistoryAction histAct; ///< action to undo/redo
|
||||
RS_Vector prevPt; ///< previous coordinate
|
||||
RS_Vector currPt; ///< current coordinate
|
||||
int startOffset;///< offset to start point for close method
|
||||
};
|
||||
|
||||
struct RS_ActionDrawLine::Points
|
||||
{
|
||||
/// Line data defined so far
|
||||
RS_LineData data;
|
||||
/// Point history (undo/redo pointer)
|
||||
int historyIndex {-1};
|
||||
/// start point offset for close method
|
||||
int startOffset {0};
|
||||
|
||||
/// Point history (undo/redo buffer)
|
||||
std::vector<History> history;
|
||||
|
||||
/// wrapper for historyIndex to avoid 'signedness' warnings where std::vector-methods expect size_t
|
||||
/// also, offset helps in close method to find starting point
|
||||
size_t index(const int offset = 0);
|
||||
};
|
||||
|
||||
size_t RS_ActionDrawLine::Points::index(const int offset /*= 0*/)
|
||||
{
|
||||
return static_cast<size_t>( std::max( 0, historyIndex + offset));
|
||||
}
|
||||
|
||||
RS_ActionDrawLine::RS_ActionDrawLine(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView) :
|
||||
RS_PreviewActionInterface( "Draw lines", container, graphicView),
|
||||
pPoints( new Points{})
|
||||
{
|
||||
RS_DEBUG->print("RS_ActionDrawLine::RS_ActionDrawLine");
|
||||
actionType=RS2::ActionDrawLine;
|
||||
}
|
||||
|
||||
RS_ActionDrawLine::~RS_ActionDrawLine() = default;
|
||||
|
||||
void RS_ActionDrawLine::reset()
|
||||
{
|
||||
RS_DEBUG->print("RS_ActionDrawLine::reset");
|
||||
pPoints.reset(new Points{});
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::init(int status)
|
||||
{
|
||||
RS_DEBUG->print("RS_ActionDrawLine::init");
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
reset();
|
||||
drawSnapper();
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::trigger()
|
||||
{
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
RS_Line* line = new RS_Line(container, pPoints->data);
|
||||
line->setLayerToActive();
|
||||
line->setPenToActive();
|
||||
container->addEntity(line);
|
||||
|
||||
// update undo list
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(line);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(pPoints->history.at(pPoints->index()).currPt);
|
||||
RS_DEBUG->print("RS_ActionDrawLine::trigger(): line added: %d",
|
||||
line->getId());
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::mouseMoveEvent(QMouseEvent* e)
|
||||
{
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
if (getStatus() == SetEndpoint && pPoints->data.startpoint.valid) {
|
||||
// Snapping to angle(15*) if shift key is pressed
|
||||
if (e->modifiers() & Qt::ShiftModifier) {
|
||||
mouse = snapToAngle(mouse, pPoints->data.startpoint, 15.);
|
||||
}
|
||||
|
||||
deletePreview();
|
||||
RS_Line *line = new RS_Line(pPoints->data.startpoint, mouse);
|
||||
preview->addEntity(line);
|
||||
line->setLayerToActive();
|
||||
line->setPenToActive();
|
||||
drawPreview();
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::mouseReleaseEvent(QMouseEvent* e)
|
||||
{
|
||||
if (e->button() == Qt::LeftButton) {
|
||||
RS_Vector snapped = snapPoint(e);
|
||||
|
||||
// Snapping to angle(15*) if shift key is pressed
|
||||
if ((e->modifiers() & Qt::ShiftModifier)
|
||||
&& getStatus() == SetEndpoint ) {
|
||||
snapped = snapToAngle(snapped, pPoints->data.startpoint, 15.);
|
||||
}
|
||||
|
||||
RS_CoordinateEvent ce(snapped);
|
||||
coordinateEvent(&ce);
|
||||
}
|
||||
else if (e->button() == Qt::RightButton) {
|
||||
deletePreview();
|
||||
switch (getStatus()) {
|
||||
default:
|
||||
case SetStartpoint:
|
||||
init( getStatus() - 1);
|
||||
break;
|
||||
|
||||
case SetEndpoint:
|
||||
next();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::coordinateEvent(RS_CoordinateEvent* e)
|
||||
{
|
||||
RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent");
|
||||
|
||||
if (nullptr == e) {
|
||||
RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: event was nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
if (pPoints->data.startpoint.valid == false
|
||||
&& getStatus() == SetEndpoint) {
|
||||
setStatus(SetStartpoint);
|
||||
pPoints->startOffset = 0;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetStartpoint:
|
||||
pPoints->data.startpoint = mouse;
|
||||
pPoints->startOffset = 0;
|
||||
addHistory( HA_SetStartpoint, graphicView->getRelativeZero(), mouse, pPoints->startOffset);
|
||||
setStatus(SetEndpoint);
|
||||
graphicView->moveRelativeZero(mouse);
|
||||
updateMouseButtonHints();
|
||||
break;
|
||||
|
||||
case SetEndpoint:
|
||||
if ((mouse-pPoints->data.startpoint).squared() > RS_TOLERANCE2) {
|
||||
// refuse zero length lines
|
||||
pPoints->data.endpoint = mouse;
|
||||
++pPoints->startOffset;
|
||||
addHistory( HA_SetEndpoint, pPoints->data.startpoint, mouse, pPoints->startOffset);
|
||||
trigger();
|
||||
pPoints->data.startpoint = pPoints->data.endpoint;
|
||||
if (pPoints->history.size() >= 2) {
|
||||
updateMouseButtonHints();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawLine::coordinateEvent: OK");
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::commandEvent(RS_CommandEvent* e)
|
||||
{
|
||||
RS_DEBUG->print("RS_ActionDrawLine::commandEvent");
|
||||
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetStartpoint:
|
||||
if (checkCommand( "help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case SetEndpoint:
|
||||
if (checkCommand( "close", c)) {
|
||||
close();
|
||||
e->accept();
|
||||
updateMouseButtonHints();
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkCommand( "undo", c)) {
|
||||
undo();
|
||||
e->accept();
|
||||
updateMouseButtonHints();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkCommand( "redo", c)) {
|
||||
redo();
|
||||
e->accept();
|
||||
updateMouseButtonHints();
|
||||
}
|
||||
RS_DEBUG->print("RS_ActionDrawLine::commandEvent: OK");
|
||||
}
|
||||
|
||||
QStringList RS_ActionDrawLine::getAvailableCommands()
|
||||
{
|
||||
QStringList cmd;
|
||||
if (pPoints->index() + 1 < pPoints->history.size()) {
|
||||
cmd += command("redo");
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetStartpoint:
|
||||
break;
|
||||
case SetEndpoint:
|
||||
if (pPoints->historyIndex >= 1) {
|
||||
cmd += command("undo");
|
||||
}
|
||||
if (pPoints->startOffset >= 2) {
|
||||
cmd += command("close");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::updateMouseButtonHints()
|
||||
{
|
||||
switch (getStatus()) {
|
||||
case SetStartpoint:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetEndpoint: {
|
||||
QString msg = "";
|
||||
|
||||
if (pPoints->startOffset >= 2) {
|
||||
msg += RS_COMMANDS->command("close");
|
||||
}
|
||||
if (pPoints->index() + 1 < pPoints->history.size()) {
|
||||
if (msg.size() > 0) {
|
||||
msg += "/";
|
||||
}
|
||||
msg += RS_COMMANDS->command("redo");
|
||||
}
|
||||
if (pPoints->historyIndex >= 1) {
|
||||
if (msg.size() > 0) {
|
||||
msg += "/";
|
||||
}
|
||||
msg += RS_COMMANDS->command("undo");
|
||||
}
|
||||
|
||||
if (pPoints->historyIndex >= 1) {
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify next point or [%1]").arg(msg),
|
||||
tr("Back"));
|
||||
} else {
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify next point"),
|
||||
tr("Back"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::showOptions()
|
||||
{
|
||||
RS_DEBUG->print("RS_ActionDrawLine::showOptions");
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::hideOptions()
|
||||
{
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawLine::updateMouseCursor()
|
||||
{
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::close()
|
||||
{
|
||||
if (SetEndpoint != getStatus()) {
|
||||
return;
|
||||
}
|
||||
if (1 < pPoints->startOffset
|
||||
&& 0 <= pPoints->historyIndex - pPoints->startOffset) {
|
||||
History h(pPoints->history.at( pPoints->index( -pPoints->startOffset)));
|
||||
if ((pPoints->data.startpoint - h.currPt).squared() > RS_TOLERANCE2) {
|
||||
pPoints->data.endpoint = h.currPt;
|
||||
addHistory( HA_Close, pPoints->data.startpoint, pPoints->data.endpoint, pPoints->startOffset);
|
||||
trigger();
|
||||
setStatus(SetStartpoint);
|
||||
}
|
||||
}
|
||||
else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Cannot close sequence of lines: "
|
||||
"Not enough entities defined yet, or already closed."));
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::next()
|
||||
{
|
||||
addHistory( HA_Next, pPoints->data.startpoint, pPoints->data.endpoint, pPoints->startOffset);
|
||||
setStatus(SetStartpoint);
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::addHistory(RS_ActionDrawLine::HistoryAction a, const RS_Vector& p, const RS_Vector& c, const int s)
|
||||
{
|
||||
if (pPoints->historyIndex < -1) {
|
||||
pPoints->historyIndex = -1;
|
||||
}
|
||||
|
||||
pPoints->history.erase(pPoints->history.begin() + pPoints->historyIndex + 1, pPoints->history.end());
|
||||
pPoints->history.push_back( History( a, p, c, s));
|
||||
pPoints->historyIndex = static_cast<int>(pPoints->history.size() - 1);
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::undo()
|
||||
{
|
||||
if (0 <= pPoints->historyIndex) {
|
||||
History h( pPoints->history.at( pPoints->index()));
|
||||
|
||||
--pPoints->historyIndex;
|
||||
deletePreview();
|
||||
graphicView->moveRelativeZero(h.prevPt);
|
||||
|
||||
switch (h.histAct) {
|
||||
case HA_SetStartpoint:
|
||||
setStatus(SetStartpoint);
|
||||
break;
|
||||
|
||||
case HA_SetEndpoint:
|
||||
case HA_Close:
|
||||
graphicView->setCurrentAction( new RS_ActionEditUndo(true, *container, *graphicView));
|
||||
pPoints->data.startpoint = h.prevPt;
|
||||
setStatus(SetEndpoint);
|
||||
break;
|
||||
|
||||
case HA_Next:
|
||||
pPoints->data.startpoint = h.prevPt;
|
||||
setStatus(SetEndpoint);
|
||||
break;
|
||||
}
|
||||
|
||||
// get index for close from new current history
|
||||
h = pPoints->history.at( pPoints->index());
|
||||
pPoints->startOffset = h.startOffset;
|
||||
}
|
||||
else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Cannot undo: "
|
||||
"Begin of history reached"));
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLine::redo()
|
||||
{
|
||||
if (pPoints->history.size() > (pPoints->index() + 1)) {
|
||||
++pPoints->historyIndex;
|
||||
History h( pPoints->history.at( pPoints->index()));
|
||||
deletePreview();
|
||||
graphicView->moveRelativeZero(h.currPt);
|
||||
pPoints->data.startpoint = h.currPt;
|
||||
pPoints->startOffset = h.startOffset;
|
||||
switch (h.histAct) {
|
||||
case HA_SetStartpoint:
|
||||
setStatus(SetEndpoint);
|
||||
break;
|
||||
|
||||
case HA_SetEndpoint:
|
||||
graphicView->setCurrentAction( new RS_ActionEditUndo(false, *container, *graphicView));
|
||||
setStatus(SetEndpoint);
|
||||
break;
|
||||
|
||||
case HA_Close:
|
||||
graphicView->setCurrentAction( new RS_ActionEditUndo(false, *container, *graphicView));
|
||||
setStatus(SetStartpoint);
|
||||
break;
|
||||
|
||||
case HA_Next:
|
||||
setStatus(SetStartpoint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
RS_DIALOGFACTORY->commandMessage( tr("Cannot redo: "
|
||||
"End of history reached"));
|
||||
}
|
||||
}
|
||||
93
actions/rs_actiondrawline.h
Normal file
93
actions/rs_actiondrawline.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2019 A. Stebich (librecad@mail.lordofbikes.de)
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWLINE_H
|
||||
#define RS_ACTIONDRAWLINE_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw
|
||||
* simple lines with the start- and endpoint given.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawLine : public RS_PreviewActionInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Action States
|
||||
enum Status {
|
||||
SetStartpoint, ///< Setting the startpoint
|
||||
SetEndpoint ///< Setting the endpoint
|
||||
};
|
||||
|
||||
/// History Actions
|
||||
enum HistoryAction {
|
||||
HA_SetStartpoint, ///< Setting the startpoint
|
||||
HA_SetEndpoint, ///< Setting the endpoint
|
||||
HA_Close, ///< Close group of lines
|
||||
HA_Next ///< Start new group of lines
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawLine(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawLine() override;
|
||||
|
||||
void reset();
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void showOptions() override;
|
||||
void hideOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
void addHistory(RS_ActionDrawLine::HistoryAction a, const RS_Vector& p, const RS_Vector& c, const int s);
|
||||
|
||||
void close();
|
||||
void next();
|
||||
void undo();
|
||||
void redo();
|
||||
|
||||
protected:
|
||||
struct History;
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
};
|
||||
|
||||
#endif
|
||||
333
actions/rs_actiondrawlineangle.cpp
Normal file
333
actions/rs_actiondrawlineangle.cpp
Normal file
@@ -0,0 +1,333 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
#include<cmath>
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawlineangle.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_settings.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawLineAngle::Points {
|
||||
/**
|
||||
* Line data defined so far.
|
||||
*/
|
||||
RS_LineData data;
|
||||
/**
|
||||
* Position.
|
||||
*/
|
||||
RS_Vector pos;
|
||||
/**
|
||||
* Line angle.
|
||||
*/
|
||||
double angle;
|
||||
/**
|
||||
* Line length.
|
||||
*/
|
||||
double length{1.};
|
||||
/**
|
||||
* Is the angle fixed?
|
||||
*/
|
||||
bool fixedAngle;
|
||||
/**
|
||||
* Snap point (start, middle, end).
|
||||
*/
|
||||
int snpPoint{0};
|
||||
};
|
||||
|
||||
RS_ActionDrawLineAngle::RS_ActionDrawLineAngle(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView,
|
||||
double angle,
|
||||
bool fixedAngle, RS2::ActionType actionType)
|
||||
:RS_PreviewActionInterface("Draw lines with given angle",
|
||||
container, graphicView)
|
||||
, pPoints(new Points{})
|
||||
{
|
||||
|
||||
this->actionType=actionType;
|
||||
pPoints->angle = angle;
|
||||
pPoints->fixedAngle = fixedAngle;
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true,false);
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
RS_ActionDrawLineAngle::~RS_ActionDrawLineAngle() {
|
||||
RS_SETTINGS->beginGroup("/Draw");
|
||||
if (!hasFixedAngle()) {
|
||||
RS_SETTINGS->writeEntry("/LineAngleAngle", RS_Math::rad2deg(getAngle()));
|
||||
}
|
||||
RS_SETTINGS->writeEntry("/LineAngleLength", getLength());
|
||||
RS_SETTINGS->writeEntry("/LineAngleSnapPoint", getSnapPoint());
|
||||
RS_SETTINGS->endGroup();
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawLineAngle::reset() {
|
||||
pPoints->data = {{}, {}};
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineAngle::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineAngle::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
preparePreview();
|
||||
RS_Line* line = new RS_Line{container, pPoints->data};
|
||||
line->setLayerToActive();
|
||||
line->setPenToActive();
|
||||
container->addEntity(line);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(line);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
graphicView->moveRelativeZero(pPoints->data.startpoint);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
RS_DEBUG->print("RS_ActionDrawLineAngle::trigger(): line added: %d",
|
||||
line->getId());
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineAngle::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawLineAngle::mouseMoveEvent begin");
|
||||
|
||||
if (getStatus()==SetPos) {
|
||||
pPoints->pos = snapPoint(e);
|
||||
deletePreview();
|
||||
preparePreview();
|
||||
preview->addEntity(new RS_Line(preview.get(),
|
||||
pPoints->data));
|
||||
drawPreview();
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawLineAngle::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineAngle::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
if (getStatus()==SetPos) {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawLineAngle::preparePreview() {
|
||||
RS_Vector p1, p2;
|
||||
// End:
|
||||
if (pPoints->snpPoint == 2) {
|
||||
p2.setPolar(-pPoints->length, pPoints->angle);
|
||||
} else {
|
||||
p2.setPolar(pPoints->length, pPoints->angle);
|
||||
}
|
||||
|
||||
// Middle:
|
||||
if (pPoints->snpPoint == 1) {
|
||||
p1 = pPoints->pos - (p2 / 2);
|
||||
} else {
|
||||
p1 = pPoints->pos;
|
||||
}
|
||||
|
||||
p2 += p1;
|
||||
pPoints->data = {p1, p2};
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineAngle::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e) return;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPos:
|
||||
pPoints->pos = e->getCoordinate();
|
||||
trigger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineAngle::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPos:
|
||||
if (!pPoints->fixedAngle && checkCommand("angle", c)) {
|
||||
deletePreview();
|
||||
setStatus(SetAngle);
|
||||
} else if (checkCommand("length", c)) {
|
||||
deletePreview();
|
||||
setStatus(SetLength);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetAngle: {
|
||||
bool ok;
|
||||
double a = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
e->accept();
|
||||
pPoints->angle = RS_Math::deg2rad(a);
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(SetPos);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetLength: {
|
||||
bool ok;
|
||||
double l = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
e->accept();
|
||||
pPoints->length = l;
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(SetPos);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineAngle::setSnapPoint(int sp) {
|
||||
pPoints->snpPoint = sp;
|
||||
}
|
||||
|
||||
int RS_ActionDrawLineAngle::getSnapPoint() const{
|
||||
return pPoints->snpPoint;
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineAngle::setAngle(double a) {
|
||||
pPoints->angle = a;
|
||||
}
|
||||
|
||||
double RS_ActionDrawLineAngle::getAngle() const{
|
||||
return pPoints->angle;
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineAngle::setLength(double l) {
|
||||
pPoints->length = l;
|
||||
}
|
||||
|
||||
double RS_ActionDrawLineAngle::getLength() const{
|
||||
return pPoints->length;
|
||||
}
|
||||
|
||||
bool RS_ActionDrawLineAngle::hasFixedAngle() const{
|
||||
switch(rtti()){
|
||||
case RS2::ActionDrawLineHorizontal:
|
||||
case RS2::ActionDrawLineVertical:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QStringList RS_ActionDrawLineAngle::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPos:
|
||||
if (!pPoints->fixedAngle) {
|
||||
cmd += command("angle");
|
||||
}
|
||||
cmd += command("length");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawLineAngle::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetPos:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify position"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetAngle:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter angle:"), tr("Back"));
|
||||
break;
|
||||
|
||||
case SetLength:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter length:"), tr("Back"));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineAngle::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true,true);
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineAngle::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineAngle::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
97
actions/rs_actiondrawlineangle.h
Normal file
97
actions/rs_actiondrawlineangle.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWLINEANGLE_H
|
||||
#define RS_ACTIONDRAWLINEANGLE_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw
|
||||
* simple lines at a gien angle.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawLineAngle : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetPos, /**< Setting the position. */
|
||||
SetAngle, /**< Setting angle in the command line. */
|
||||
SetLength /**< Setting length in the command line. */
|
||||
};
|
||||
|
||||
RS_ActionDrawLineAngle(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView,
|
||||
double angle=0.0,
|
||||
bool fixedAngle=false,
|
||||
RS2::ActionType actionType=RS2::ActionDrawLineAngle);
|
||||
~RS_ActionDrawLineAngle() override;
|
||||
|
||||
void reset();
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
void preparePreview();
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
void setSnapPoint(int sp);
|
||||
|
||||
int getSnapPoint() const;
|
||||
|
||||
void setAngle(double a);
|
||||
|
||||
double getAngle() const;
|
||||
|
||||
void setLength(double l);
|
||||
|
||||
double getLength() const;
|
||||
|
||||
bool hasFixedAngle() const;
|
||||
|
||||
protected:
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
331
actions/rs_actiondrawlinebisector.cpp
Normal file
331
actions/rs_actiondrawlinebisector.cpp
Normal file
@@ -0,0 +1,331 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawlinebisector.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_creation.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawLineBisector::Points {
|
||||
/** Mouse pos when choosing the 1st line */
|
||||
RS_Vector coord1;
|
||||
/** Mouse pos when choosing the 2nd line */
|
||||
RS_Vector coord2;
|
||||
};
|
||||
|
||||
RS_ActionDrawLineBisector::RS_ActionDrawLineBisector(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw Bisectors", container, graphicView)
|
||||
,bisector(nullptr)
|
||||
,line1(nullptr)
|
||||
,line2(nullptr)
|
||||
,length(10.)
|
||||
,number(1)
|
||||
, pPoints(new Points{})
|
||||
,lastStatus(SetLine1)
|
||||
{
|
||||
actionType=RS2::ActionDrawLineBisector;
|
||||
}
|
||||
|
||||
RS_ActionDrawLineBisector::~RS_ActionDrawLineBisector() = default;
|
||||
|
||||
|
||||
void RS_ActionDrawLineBisector::setLength(double l) {
|
||||
length = l;
|
||||
}
|
||||
|
||||
double RS_ActionDrawLineBisector::getLength() const{
|
||||
return length;
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineBisector::setNumber(int n) {
|
||||
number = n;
|
||||
}
|
||||
|
||||
int RS_ActionDrawLineBisector::getNumber() const {
|
||||
return number;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawLineBisector::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
if(status>=0) {
|
||||
RS_Snapper::suspend();
|
||||
}
|
||||
|
||||
if (status<SetLine2) {
|
||||
if(line2 && line2->isHighlighted()){
|
||||
line2->setHighlighted(false);
|
||||
}
|
||||
if(status<0 && line1 && line1->isHighlighted()){
|
||||
line1->setHighlighted(false);
|
||||
}
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineBisector::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
for(auto p: {line1, line2}){
|
||||
if(p && p->isHighlighted()){
|
||||
p->setHighlighted(false);
|
||||
}
|
||||
}
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
|
||||
RS_Creation creation(container, graphicView);
|
||||
creation.createBisector(pPoints->coord1,
|
||||
pPoints->coord2,
|
||||
length,
|
||||
number,
|
||||
line1,
|
||||
line2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineBisector::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawLineBisector::mouseMoveEvent begin");
|
||||
|
||||
RS_Vector mouse = RS_Vector(graphicView->toGraphX(e->x()),
|
||||
graphicView->toGraphY(e->y()));
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetLine1:
|
||||
break;
|
||||
|
||||
case SetLine2: {
|
||||
pPoints->coord2 = mouse;
|
||||
RS_Entity* en = catchEntity(e, RS2::ResolveAll);
|
||||
if(en==line1) break;
|
||||
if (en && en->rtti()==RS2::EntityLine) {
|
||||
if(line2 && line2->isHighlighted()){
|
||||
line2->setHighlighted(false);
|
||||
}
|
||||
line2 = static_cast<RS_Line*>(en);
|
||||
line2->setHighlighted(true);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
|
||||
deletePreview();
|
||||
|
||||
RS_Creation creation(preview.get(), nullptr, false);
|
||||
creation.createBisector(pPoints->coord1,
|
||||
pPoints->coord2,
|
||||
length,
|
||||
number,
|
||||
line1,
|
||||
line2);
|
||||
drawPreview();
|
||||
}else{
|
||||
if(line2 && line2->isHighlighted()){
|
||||
line2->setHighlighted(false);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
}
|
||||
line2=nullptr;
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawLineBisector::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineBisector::mouseReleaseEvent(QMouseEvent* e) {
|
||||
|
||||
if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
} else {
|
||||
|
||||
RS_Vector mouse = RS_Vector(graphicView->toGraphX(e->x()),
|
||||
graphicView->toGraphY(e->y()));
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetLine1: {
|
||||
pPoints->coord1 = mouse;
|
||||
RS_Entity* en = catchEntity(e, RS2::ResolveAll);
|
||||
if (en && en->rtti()==RS2::EntityLine) {
|
||||
line1 = static_cast<RS_Line*>(en);
|
||||
line1->setHighlighted(true);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
line2=nullptr;
|
||||
setStatus(SetLine2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SetLine2:
|
||||
pPoints->coord2 = mouse;
|
||||
trigger();
|
||||
setStatus(SetLine1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawLineBisector::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetLine1:
|
||||
case SetLine2:
|
||||
lastStatus = (Status)getStatus();
|
||||
if (checkCommand("length", c)) {
|
||||
deletePreview();
|
||||
setStatus(SetLength);
|
||||
} else if (checkCommand("number", c)) {
|
||||
deletePreview();
|
||||
setStatus(SetNumber);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetLength: {
|
||||
bool ok;
|
||||
double l = RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
e->accept();
|
||||
length = l;
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
case SetNumber: {
|
||||
bool ok;
|
||||
int n = (int)RS_Math::eval(c, &ok);
|
||||
if (ok) {
|
||||
e->accept();
|
||||
if(n>0 && n<=200)
|
||||
number = n;
|
||||
else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Number sector lines not in range: ", "number of bisector to create must be in [1, 200]")+QString::number(n));
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDrawLineBisector::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetLine1:
|
||||
case SetLine2:
|
||||
cmd += command("length");
|
||||
cmd += command("number");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawLineBisector::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetLine1:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Select first line"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetLine2:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Select second line"),
|
||||
tr("Back"));
|
||||
break;
|
||||
case SetLength:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter bisector length:"),
|
||||
tr("Back"));
|
||||
break;
|
||||
case SetNumber:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter number of bisectors:"),
|
||||
tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineBisector::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineBisector::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineBisector::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
94
actions/rs_actiondrawlinebisector.h
Normal file
94
actions/rs_actiondrawlinebisector.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWLINEBISECTOR_H
|
||||
#define RS_ACTIONDRAWLINEBISECTOR_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
class RS_Line;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw bisectors.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawLineBisector : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
private:
|
||||
enum Status {
|
||||
SetLine1, /**< Choose the 1st line. */
|
||||
SetLine2, /**< Choose the 2nd line. */
|
||||
SetLength, /**< Set length in command line. */
|
||||
SetNumber /**< Set number in command line. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawLineBisector(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawLineBisector() override;
|
||||
|
||||
void init(int status=0) override;
|
||||
|
||||
void trigger() override;
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
void setLength(double l);
|
||||
|
||||
double getLength() const;
|
||||
|
||||
void setNumber(int n);
|
||||
|
||||
int getNumber() const;
|
||||
|
||||
private:
|
||||
/** Closest bisector. */
|
||||
RS_Line* bisector;
|
||||
/** First chosen entity */
|
||||
RS_Line* line1;
|
||||
/** Second chosen entity */
|
||||
RS_Line* line2;
|
||||
/** Length of the bisector. */
|
||||
double length;
|
||||
/** Number of bisectors to create. */
|
||||
int number;
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
/** Last status before entering length or number. */
|
||||
Status lastStatus;
|
||||
};
|
||||
|
||||
#endif
|
||||
153
actions/rs_actiondrawlinefree.cpp
Normal file
153
actions/rs_actiondrawlinefree.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawlinefree.h"
|
||||
#include "rs_polyline.h"
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
RS_ActionDrawLineFree::RS_ActionDrawLineFree(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw freehand lines",
|
||||
container, graphicView)
|
||||
,vertex(new RS_Vector{})
|
||||
{
|
||||
preview->setOwner(false);
|
||||
actionType=RS2::ActionDrawLineFree;
|
||||
}
|
||||
|
||||
RS_ActionDrawLineFree::~RS_ActionDrawLineFree() = default;
|
||||
|
||||
void RS_ActionDrawLineFree::trigger() {
|
||||
deleteSnapper();
|
||||
if (polyline.get()) {
|
||||
deletePreview();
|
||||
|
||||
polyline->endPolyline();
|
||||
RS_VectorSolutions sol=polyline->getRefPoints();
|
||||
if(sol.getNumber() > 2 ) {
|
||||
RS_Entity* ent=polyline->clone();
|
||||
container->addEntity(ent);
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(ent);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
RS_DEBUG->print("RS_ActionDrawLineFree::trigger():"
|
||||
" polyline added: %d", ent->getId());
|
||||
}
|
||||
polyline.reset();
|
||||
}
|
||||
setStatus(SetStartpoint);
|
||||
}
|
||||
|
||||
/*
|
||||
* 11 Aug 2011, Dongxu Li
|
||||
*/
|
||||
|
||||
void RS_ActionDrawLineFree::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_Vector v = snapPoint(e);
|
||||
drawSnapper();
|
||||
if (getStatus()==Dragging && polyline.get()) {
|
||||
if( (graphicView->toGui(v) - graphicView->toGui(*vertex)).squared()< 1. ){
|
||||
//do not add the same mouse position
|
||||
return;
|
||||
}
|
||||
auto ent = static_cast<RS_Polyline*>(polyline->addVertex(v));
|
||||
if (ent->count()){
|
||||
preview->addCloneOf(ent);
|
||||
drawPreview();
|
||||
}
|
||||
|
||||
*vertex = v;
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawLineFree::%s:"
|
||||
" line added: %d", __func__, ent->getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineFree::mousePressEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
switch(getStatus()){
|
||||
case SetStartpoint:
|
||||
setStatus(Dragging);
|
||||
// fall-through
|
||||
case Dragging:
|
||||
*vertex = snapPoint(e);
|
||||
polyline.reset(new RS_Polyline(container,
|
||||
RS_PolylineData(*vertex, *vertex, 0))
|
||||
);
|
||||
polyline->setLayerToActive();
|
||||
polyline->setPenToActive();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
//else if (RS2::qtToRsButtonState(e->button())==RS2::RightButton && !vertex.valid) {
|
||||
//}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineFree::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
if(getStatus()==Dragging){
|
||||
*vertex = {};
|
||||
trigger();
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
if (polyline.get()) {
|
||||
polyline.reset();
|
||||
}
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineFree::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetStartpoint:
|
||||
case Dragging:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Click and drag to draw a line"), tr("Cancel"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineFree::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
66
actions/rs_actiondrawlinefree.h
Normal file
66
actions/rs_actiondrawlinefree.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2011 Dongxu Li (dongxuli2011@gmail.com)
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWLINEFREE_H
|
||||
#define RS_ACTIONDRAWLINEFREE_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
class RS_Polyline;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw freehand lines.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawLineFree : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetStartpoint, /**< Setting the startpoint. */
|
||||
Dragging /**< Setting the endpoint. */
|
||||
};
|
||||
RS_ActionDrawLineFree(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawLineFree() override;
|
||||
|
||||
void trigger() override;
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mousePressEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<RS_Vector> vertex;
|
||||
std::unique_ptr<RS_Polyline> polyline;
|
||||
};
|
||||
|
||||
#endif
|
||||
175
actions/rs_actiondrawlinehorvert.cpp
Normal file
175
actions/rs_actiondrawlinehorvert.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawlinehorvert.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
struct RS_ActionDrawLineHorVert::Points {
|
||||
/**
|
||||
* Line data.
|
||||
*/
|
||||
RS_LineData data;
|
||||
/**
|
||||
* 2 points
|
||||
*/
|
||||
RS_Vector p1;
|
||||
RS_Vector p2;
|
||||
};
|
||||
|
||||
|
||||
|
||||
RS_ActionDrawLineHorVert::RS_ActionDrawLineHorVert(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw horizontal/vertical lines",
|
||||
container, graphicView)
|
||||
, pPoints(new Points{})
|
||||
{
|
||||
reset();
|
||||
RS_DEBUG->print("RS_ActionDrawLineHorVert::constructor");
|
||||
}
|
||||
|
||||
|
||||
|
||||
RS_ActionDrawLineHorVert::~RS_ActionDrawLineHorVert() = default;
|
||||
|
||||
void RS_ActionDrawLineHorVert::reset() {
|
||||
pPoints->data = {{}, {}};
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineHorVert::init(int status) {
|
||||
RS_PreviewActionInterface::init(status);
|
||||
|
||||
reset();
|
||||
RS_DEBUG->print("RS_ActionDrawLineHorVert::init");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineHorVert::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
RS_Line* line = new RS_Line(container, pPoints->data);
|
||||
line->setLayerToActive();
|
||||
line->setPenToActive();
|
||||
container->addEntity(line);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(line);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
graphicView->moveRelativeZero(line->getMiddlePoint());
|
||||
RS_DEBUG->print("RS_ActionDrawLineHorVert::trigger():"
|
||||
" line added: %d", line->getId());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineHorVert::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawLineHorVert::mouseMoveEvent begin");
|
||||
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
if (getStatus()==SetEndpoint && pPoints->p1.valid) {
|
||||
RS_Vector p2x = RS_Vector(mouse.x, pPoints->p1.y);
|
||||
RS_Vector p2y = RS_Vector(pPoints->p1.x, mouse.y);
|
||||
if (mouse.distanceTo(p2y) > mouse.distanceTo(p2x))
|
||||
pPoints->p2 = p2x;
|
||||
else
|
||||
pPoints->p2 = p2y;
|
||||
deletePreview();
|
||||
pPoints->data = {pPoints->p1, pPoints->p2};
|
||||
preview->addEntity(new RS_Line{preview.get(), pPoints->data});
|
||||
drawPreview();
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawLineHorVert::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineHorVert::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
RS_Vector mouse = snapPoint(e);
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetStartpoint:
|
||||
pPoints->p1 = mouse;
|
||||
setStatus(SetEndpoint);
|
||||
break;
|
||||
|
||||
case SetEndpoint:
|
||||
pPoints->p2 = mouse;
|
||||
trigger();
|
||||
setStatus(SetStartpoint);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineHorVert::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetStartpoint:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify first point"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetEndpoint:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify second point"),
|
||||
tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawLineHorVert::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
70
actions/rs_actiondrawlinehorvert.h
Normal file
70
actions/rs_actiondrawlinehorvert.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWLINEHORVERT_H
|
||||
#define RS_ACTIONDRAWLINEHORVERT_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw
|
||||
* horizontal/vertical lines from a given startpoint
|
||||
* to an endpoint closest to a second given point.
|
||||
* OBSOLETE
|
||||
*
|
||||
* @author Ulf Lehnert
|
||||
*/
|
||||
class RS_ActionDrawLineHorVert : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Action States.
|
||||
*/
|
||||
enum Status {
|
||||
SetStartpoint, /**< Setting the 1st point. */
|
||||
SetEndpoint /**< Setting the 2nd point. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawLineHorVert(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawLineHorVert() override;
|
||||
|
||||
void reset();
|
||||
|
||||
void init(int status=0) override;
|
||||
void trigger() override;
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
protected:
|
||||
struct Points;
|
||||
std::unique_ptr<Points> pPoints;
|
||||
};
|
||||
|
||||
#endif
|
||||
208
actions/rs_actiondrawlineorthtan.cpp
Normal file
208
actions/rs_actiondrawlineorthtan.cpp
Normal file
@@ -0,0 +1,208 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
* This action class can handle user events to draw tangents normal to lines
|
||||
|
||||
Copyright (C) 2011-2012 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#include<QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawlineorthtan.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_creation.h"
|
||||
#include "rs_selection.h"
|
||||
#include "rs_line.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
namespace{
|
||||
auto circleList={RS2::EntityArc, RS2::EntityCircle, RS2::EntityEllipse}; //this holds a list of entity types which supports tangent
|
||||
}
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw tangents normal to lines
|
||||
*
|
||||
* @author Dongxu Li
|
||||
*/
|
||||
RS_ActionDrawLineOrthTan::RS_ActionDrawLineOrthTan(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw Tangent Orthogonal", container, graphicView)
|
||||
,normal(nullptr)
|
||||
,tangent(nullptr)
|
||||
,circle(nullptr)
|
||||
{
|
||||
actionType=RS2::ActionDrawLineOrthTan;
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawLineOrthTan::finish(bool updateTB){
|
||||
clearLines();
|
||||
RS_PreviewActionInterface::finish(updateTB);
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineOrthTan::trigger() {
|
||||
if(!tangent) return;
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
deletePreview();
|
||||
if(circle)
|
||||
circle->setHighlighted(false);
|
||||
circle=nullptr;
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
RS_Entity* newEntity = new RS_Line(container,
|
||||
tangent->getData());
|
||||
newEntity->setLayerToActive();
|
||||
newEntity->setPenToActive();
|
||||
container->addEntity(newEntity);
|
||||
|
||||
// upd. undo list:
|
||||
if (document) {
|
||||
document->startUndoCycle();
|
||||
document->addUndoable(newEntity);
|
||||
document->endUndoCycle();
|
||||
}
|
||||
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
|
||||
setStatus(SetCircle);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineOrthTan::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawLineOrthTan::mouseMoveEvent begin");
|
||||
e->accept();
|
||||
RS_Vector mouse(graphicView->toGraphX(e->x()),
|
||||
graphicView->toGraphY(e->y()));
|
||||
|
||||
switch(getStatus()){
|
||||
case SetLine:
|
||||
return;
|
||||
case SetCircle:{
|
||||
|
||||
RS_Entity* en = catchEntity(e, circleList, RS2::ResolveAll);
|
||||
if(!en) return;
|
||||
deletePreview();
|
||||
if(circle)
|
||||
circle->setHighlighted(false);
|
||||
circle = en;
|
||||
circle->setHighlighted(true);
|
||||
graphicView->redraw(RS2::RedrawDrawing);
|
||||
deletePreview();
|
||||
RS_Creation creation(preview.get(), graphicView, false);
|
||||
tangent = creation.createLineOrthTan(mouse,
|
||||
normal,
|
||||
circle);
|
||||
preview->addEntity(tangent);
|
||||
drawPreview();
|
||||
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RS_DEBUG->print("RS_ActionDrawLineOrthTan::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
void RS_ActionDrawLineOrthTan::clearLines()
|
||||
{
|
||||
for(RS_Entity* p: {(RS_Entity*) normal, circle}){
|
||||
if(p){
|
||||
p->setHighlighted(false);
|
||||
graphicView->drawEntity(p);
|
||||
}
|
||||
}
|
||||
if(circle) circle=nullptr;
|
||||
deletePreview();
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineOrthTan::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::RightButton) {
|
||||
clearLines();
|
||||
if (getStatus() == SetLine) {
|
||||
finish(true);
|
||||
}else{
|
||||
init(getStatus()-1);
|
||||
}
|
||||
} else {
|
||||
switch (getStatus()) {
|
||||
case SetLine: {
|
||||
RS_Entity* en=catchEntity(e,RS2::EntityLine);
|
||||
if(en){
|
||||
if (en->getLength() < RS_TOLERANCE) {
|
||||
//ignore lines not long enough
|
||||
break;
|
||||
}
|
||||
if(normal) {
|
||||
normal->setHighlighted(false);
|
||||
graphicView->drawEntity(normal);
|
||||
}
|
||||
normal=static_cast<RS_Line*>(en);
|
||||
normal->setHighlighted(true);
|
||||
graphicView->drawEntity(normal);
|
||||
setStatus(SetCircle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SetCircle:
|
||||
if(tangent){
|
||||
trigger();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineOrthTan::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetLine:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Select a line"),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
case SetCircle:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Select circle, arc or ellipse"),
|
||||
tr("Back"));
|
||||
break;
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineOrthTan::updateMouseCursor() {
|
||||
if(isFinished()) {
|
||||
graphicView->setMouseCursor(RS2::ArrowCursor);
|
||||
}else{
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
}
|
||||
}
|
||||
|
||||
// EOF
|
||||
67
actions/rs_actiondrawlineorthtan.h
Normal file
67
actions/rs_actiondrawlineorthtan.h
Normal file
@@ -0,0 +1,67 @@
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
* This action class can handle user events to draw tangents normal to lines
|
||||
|
||||
Copyright (C) 2011 Dongxu Li (dongxuli2011@gmail.com)
|
||||
Copyright (C) 2011 R. van Twisk (librecad@rvt.dds.nl)
|
||||
|
||||
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 2
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWLINEORTHTAN_H
|
||||
#define RS_ACTIONDRAWLINEORTHTAN_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
class RS_Line;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw tangents normal to lines
|
||||
*
|
||||
* @author Dongxu Li
|
||||
*/
|
||||
class RS_ActionDrawLineOrthTan : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
private:
|
||||
enum Status {
|
||||
SetLine, /**< Choose the line orthogonal to the tangent line */
|
||||
SetCircle /**< Choose the arc/circle/ellipse to create its tangent line*/
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawLineOrthTan(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
|
||||
void trigger() override;
|
||||
void finish(bool updateTB = true) override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
void updateMouseButtonHints() override;
|
||||
void updateMouseCursor() override;
|
||||
|
||||
private:
|
||||
void clearLines();
|
||||
/** normal to tangent. */
|
||||
RS_Line* normal; // the select normal line
|
||||
/** tangent. */
|
||||
RS_Line* tangent; //holds the tangent line for preview
|
||||
/** arc/circle/ellipse to generate tangent */
|
||||
RS_Entity* circle;
|
||||
};
|
||||
|
||||
#endif
|
||||
228
actions/rs_actiondrawlineparallel.cpp
Normal file
228
actions/rs_actiondrawlineparallel.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawlineparallel.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_creation.h"
|
||||
#include "rs_commands.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_actiondrawlineparallelthrough.h"
|
||||
#include "rs_math.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
RS_ActionDrawLineParallel::RS_ActionDrawLineParallel(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw Parallels", container, graphicView)
|
||||
,parallel(nullptr)
|
||||
,distance(1.0)
|
||||
,number(1)
|
||||
, coord(new RS_Vector{})
|
||||
,entity(nullptr)
|
||||
{
|
||||
actionType=RS2::ActionDrawLineParallel;
|
||||
}
|
||||
|
||||
RS_ActionDrawLineParallel::~RS_ActionDrawLineParallel() = default;
|
||||
|
||||
double RS_ActionDrawLineParallel::getDistance() const{
|
||||
return distance;
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineParallel::setDistance(double d) {
|
||||
distance = d;
|
||||
}
|
||||
|
||||
int RS_ActionDrawLineParallel::getNumber() const{
|
||||
return number;
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineParallel::setNumber(int n) {
|
||||
number = n;
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineParallel::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
RS_Creation creation(container, graphicView);
|
||||
RS_Entity* e = creation.createParallel(*coord,
|
||||
distance, number,
|
||||
entity);
|
||||
|
||||
if (!e) {
|
||||
RS_DEBUG->print("RS_ActionDrawLineParallel::trigger:"
|
||||
" No parallels added\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineParallel::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawLineParallel::mouseMoveEvent begin");
|
||||
|
||||
*coord = {graphicView->toGraphX(e->x()), graphicView->toGraphY(e->y())};
|
||||
|
||||
entity = catchEntity(e, RS2::ResolveAll);
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetEntity: {
|
||||
deletePreview();
|
||||
|
||||
RS_Creation creation(preview.get(), nullptr, false);
|
||||
creation.createParallel(*coord,
|
||||
distance, number,
|
||||
entity);
|
||||
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawLineParallel::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineParallel::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::RightButton) {
|
||||
init(getStatus()-1);
|
||||
} else {
|
||||
trigger();
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineParallel::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetEntity:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(
|
||||
tr("Specify Distance <%1> or select entity or [%2]")
|
||||
.arg(distance).arg(RS_COMMANDS->command("through")),
|
||||
tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetNumber:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Enter number:"), "");
|
||||
break;
|
||||
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineParallel::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
updateMouseButtonHints();
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineParallel::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineParallel::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetEntity: {
|
||||
if (checkCommand("through", c)) {
|
||||
finish(false);
|
||||
graphicView->setCurrentAction(
|
||||
new RS_ActionDrawLineParallelThrough(*container,
|
||||
*graphicView));
|
||||
} else if (checkCommand("number", c)) {
|
||||
deletePreview();
|
||||
setStatus(SetNumber);
|
||||
} else {
|
||||
bool ok;
|
||||
double d = RS_Math::eval(c, &ok);
|
||||
if(ok) e->accept();
|
||||
if (ok && d>1.0e-10) {
|
||||
distance = d;
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
updateMouseButtonHints();
|
||||
//setStatus(SetEntity);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SetNumber: {
|
||||
bool ok;
|
||||
int n = c.toInt(&ok);
|
||||
if (ok) {
|
||||
e->accept();
|
||||
if (n>0 && n<100) {
|
||||
number = n;
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid number. "
|
||||
"Try 1..99"));
|
||||
} else
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(SetEntity);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QStringList RS_ActionDrawLineParallel::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetEntity:
|
||||
cmd += command("number");
|
||||
cmd += command("through");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineParallel::updateMouseCursor() {
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
}
|
||||
|
||||
// EOF
|
||||
103
actions/rs_actiondrawlineparallel.h
Normal file
103
actions/rs_actiondrawlineparallel.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWLINEPARALLEL_H
|
||||
#define RS_ACTIONDRAWLINEPARALLEL_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
class RS_Vector;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw parallel
|
||||
* lines, arcs and circles.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawLineParallel : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
private:
|
||||
enum Status {
|
||||
SetEntity, /**< Choose original entity. */
|
||||
//SetDistance, /**< Setting distance in the command line. */
|
||||
SetNumber /**< Setting number in the command line. */
|
||||
//SetThrough /**< Setting a point for the parallel to go through. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawLineParallel(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawLineParallel() override;
|
||||
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
void updateMouseButtonHints() override;
|
||||
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
|
||||
void updateMouseCursor() override;
|
||||
// void updateToolBar() override;
|
||||
|
||||
double getDistance() const;
|
||||
|
||||
void setDistance(double d);
|
||||
|
||||
int getNumber() const;
|
||||
|
||||
void setNumber(int n);
|
||||
|
||||
private:
|
||||
/** Closest parallel. */
|
||||
RS_Entity* parallel;
|
||||
/** Distance of the parallel. */
|
||||
double distance;
|
||||
/** Number of parallels. */
|
||||
int number;
|
||||
/** Coordinate of the mouse. */
|
||||
std::unique_ptr<RS_Vector> coord;
|
||||
/** Original entity. */
|
||||
RS_Entity* entity;
|
||||
/**
|
||||
* Commands
|
||||
*/
|
||||
/*
|
||||
QString cmdDistance;
|
||||
QString cmdDistance2;
|
||||
QString cmdDistance3;
|
||||
|
||||
QString cmdNumber;
|
||||
QString cmdNumber2;
|
||||
QString cmdNumber3;
|
||||
*/
|
||||
};
|
||||
|
||||
#endif
|
||||
298
actions/rs_actiondrawlineparallelthrough.cpp
Normal file
298
actions/rs_actiondrawlineparallelthrough.cpp
Normal file
@@ -0,0 +1,298 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QMouseEvent>
|
||||
#include "rs_actiondrawlineparallelthrough.h"
|
||||
|
||||
#include "rs_dialogfactory.h"
|
||||
#include "rs_graphicview.h"
|
||||
#include "rs_creation.h"
|
||||
#include "rs_commandevent.h"
|
||||
#include "rs_coordinateevent.h"
|
||||
#include "rs_preview.h"
|
||||
#include "rs_debug.h"
|
||||
|
||||
RS_ActionDrawLineParallelThrough::RS_ActionDrawLineParallelThrough(
|
||||
RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView)
|
||||
:RS_PreviewActionInterface("Draw Parallels", container, graphicView)
|
||||
,coord(new RS_Vector{})
|
||||
,lastStatus(SetEntity)
|
||||
{
|
||||
actionType=RS2::ActionDrawLineParallelThrough;
|
||||
m_SnapDistance=1.;
|
||||
}
|
||||
|
||||
RS_ActionDrawLineParallelThrough::~RS_ActionDrawLineParallelThrough() = default;
|
||||
|
||||
void RS_ActionDrawLineParallelThrough::finish(bool updateTB){
|
||||
if(entity){
|
||||
entity->setHighlighted(false);
|
||||
graphicView->drawEntity(entity);
|
||||
entity=nullptr;
|
||||
}
|
||||
RS_PreviewActionInterface::finish(updateTB);
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineParallelThrough::trigger() {
|
||||
RS_PreviewActionInterface::trigger();
|
||||
|
||||
if (entity) {
|
||||
RS_Creation creation(container, graphicView);
|
||||
RS_Entity* e = creation.createParallelThrough(*coord,
|
||||
number,
|
||||
entity);
|
||||
|
||||
if (!e) {
|
||||
RS_DEBUG->print("RS_ActionDrawLineParallelThrough::trigger:"
|
||||
" No parallels added\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineParallelThrough::mouseMoveEvent(QMouseEvent* e) {
|
||||
RS_DEBUG->print("RS_ActionDrawLineParallelThrough::mouseMoveEvent begin");
|
||||
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetEntity: {
|
||||
entity = catchEntity(e, RS2::ResolveAll);
|
||||
/*deletePreview();
|
||||
|
||||
RS_Creation creation(preview, nullptr, false);
|
||||
creation.createParallelThrough(*coord,
|
||||
number,
|
||||
entity);
|
||||
|
||||
drawPreview();*/
|
||||
}
|
||||
break;
|
||||
|
||||
case SetPos: {
|
||||
*coord = snapPoint(e);
|
||||
//RS_Vector(graphicView->toGraphX(e->x()),
|
||||
// graphicView->toGraphY(e->y()));
|
||||
deletePreview();
|
||||
|
||||
RS_Creation creation(preview.get(), nullptr, false);
|
||||
creation.createParallelThrough(*coord,
|
||||
number,
|
||||
entity);
|
||||
|
||||
drawPreview();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RS_DEBUG->print("RS_ActionDrawLineParallelThrough::mouseMoveEvent end");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineParallelThrough::mouseReleaseEvent(QMouseEvent* e) {
|
||||
if (e->button()==Qt::LeftButton) {
|
||||
switch (getStatus()) {
|
||||
case SetEntity:
|
||||
entity = catchEntity(e, RS2::ResolveAll);
|
||||
if (entity) {
|
||||
entity->setHighlighted(true);
|
||||
graphicView->drawEntity(entity);
|
||||
setStatus(SetPos);
|
||||
}
|
||||
break;
|
||||
case SetPos: {
|
||||
RS_CoordinateEvent ce(snapPoint(e));
|
||||
coordinateEvent(&ce);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (e->button()==Qt::RightButton) {
|
||||
deletePreview();
|
||||
if (entity) {
|
||||
entity->setHighlighted(false);
|
||||
graphicView->drawEntity(entity);
|
||||
entity=nullptr;
|
||||
}
|
||||
init(getStatus()-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineParallelThrough::coordinateEvent(RS_CoordinateEvent* e) {
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
|
||||
RS_Vector mouse = e->getCoordinate();
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetPos:
|
||||
*coord = mouse;
|
||||
trigger();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineParallelThrough::updateMouseButtonHints() {
|
||||
switch (getStatus()) {
|
||||
case SetEntity:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Select entity"), tr("Cancel"));
|
||||
break;
|
||||
|
||||
case SetPos:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Specify through point"),
|
||||
tr("Back"));
|
||||
break;
|
||||
|
||||
case SetNumber:
|
||||
RS_DIALOGFACTORY->updateMouseWidget(tr("Number:"), tr("Back"));
|
||||
break;
|
||||
|
||||
default:
|
||||
RS_DIALOGFACTORY->updateMouseWidget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineParallelThrough::showOptions() {
|
||||
RS_ActionInterface::showOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, true);
|
||||
updateMouseButtonHints();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineParallelThrough::hideOptions() {
|
||||
RS_ActionInterface::hideOptions();
|
||||
|
||||
RS_DIALOGFACTORY->requestOptions(this, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineParallelThrough::commandEvent(RS_CommandEvent* e) {
|
||||
QString c = e->getCommand().toLower();
|
||||
|
||||
if (checkCommand("help", c)) {
|
||||
RS_DIALOGFACTORY->commandMessage(msgAvailableCommands()
|
||||
+ getAvailableCommands().join(", "));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetEntity:
|
||||
case SetPos: {
|
||||
if (checkCommand("number", c)) {
|
||||
deletePreview();
|
||||
lastStatus = (Status)getStatus();
|
||||
setStatus(SetNumber);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SetNumber: {
|
||||
bool ok;
|
||||
int n = c.toInt(&ok);
|
||||
if (ok) {
|
||||
e->accept();
|
||||
if (n>0 && n<100) {
|
||||
number = n;
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid number. "
|
||||
"Try 1..99"));
|
||||
}
|
||||
} else {
|
||||
RS_DIALOGFACTORY->commandMessage(tr("Not a valid expression"));
|
||||
}
|
||||
RS_DIALOGFACTORY->requestOptions(this, true, true);
|
||||
setStatus(lastStatus);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QStringList RS_ActionDrawLineParallelThrough::getAvailableCommands() {
|
||||
QStringList cmd;
|
||||
|
||||
switch (getStatus()) {
|
||||
case SetEntity:
|
||||
cmd += command("number");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RS_ActionDrawLineParallelThrough::updateMouseCursor()
|
||||
{
|
||||
switch (getStatus())
|
||||
{
|
||||
case SetEntity:
|
||||
graphicView->setMouseCursor(RS2::SelectCursor);
|
||||
break;
|
||||
case SetNumber:
|
||||
case SetPos:
|
||||
graphicView->setMouseCursor(RS2::CadCursor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int RS_ActionDrawLineParallelThrough::getNumber() const{
|
||||
return number;
|
||||
}
|
||||
|
||||
void RS_ActionDrawLineParallelThrough::setNumber(int n) {
|
||||
number = n;
|
||||
}
|
||||
|
||||
// EOF
|
||||
86
actions/rs_actiondrawlineparallelthrough.h
Normal file
86
actions/rs_actiondrawlineparallelthrough.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of the LibreCAD project, a 2D CAD program
|
||||
**
|
||||
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
|
||||
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
|
||||
**
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU General Public License version 2 as published by the Free Software
|
||||
** Foundation and appearing in the file gpl-2.0.txt included in the
|
||||
** packaging of this file.
|
||||
**
|
||||
** 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, write to the Free Software
|
||||
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
**
|
||||
** This copyright notice MUST APPEAR in all copies of the script!
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RS_ACTIONDRAWLINEPARALLELTHROUGH_H
|
||||
#define RS_ACTIONDRAWLINEPARALLELTHROUGH_H
|
||||
|
||||
#include "rs_previewactioninterface.h"
|
||||
|
||||
class RS_Vector;
|
||||
|
||||
/**
|
||||
* This action class can handle user events to draw parallel
|
||||
* lines, arcs and circles.
|
||||
*
|
||||
* @author Andrew Mustun
|
||||
*/
|
||||
class RS_ActionDrawLineParallelThrough : public RS_PreviewActionInterface {
|
||||
Q_OBJECT
|
||||
enum Status {
|
||||
SetEntity, /**< Choose original entity. */
|
||||
SetPos, /**< Setting point for this parallel to go through. */
|
||||
SetNumber /**< Setting number in the command line. */
|
||||
};
|
||||
|
||||
public:
|
||||
RS_ActionDrawLineParallelThrough(RS_EntityContainer& container,
|
||||
RS_GraphicView& graphicView);
|
||||
~RS_ActionDrawLineParallelThrough() override;
|
||||
|
||||
void trigger() override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
void updateMouseButtonHints() override;
|
||||
|
||||
void coordinateEvent(RS_CoordinateEvent* e) override;
|
||||
void commandEvent(RS_CommandEvent* e) override;
|
||||
QStringList getAvailableCommands() override;
|
||||
|
||||
void hideOptions() override;
|
||||
void showOptions() override;
|
||||
void finish(bool updateTB=true) override;
|
||||
|
||||
void updateMouseCursor() override;
|
||||
|
||||
int getNumber() const;
|
||||
|
||||
void setNumber(int n);
|
||||
|
||||
private:
|
||||
/** Closest parallel. */
|
||||
RS_Entity* parallel=nullptr;
|
||||
/** Number of parallels. */
|
||||
int number=1;
|
||||
/** Coordinate of the mouse. */
|
||||
std::unique_ptr<RS_Vector> coord;
|
||||
/** Original entity. */
|
||||
RS_Entity* entity=nullptr;
|
||||
/** Last status before entering length or number. */
|
||||
Status lastStatus;
|
||||
};
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user