From 31dd33b097661175a86b6799df525972055099fb Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Fri, 14 Feb 2014 13:38:28 -0600 Subject: [PATCH] Added preliminary (i.e., non-functional) trim tool. Also: - Bugfix for incorrect mirrored point in Geomtry::Mirror() - Added miscellaneous missing icons - Added auto-connect to add lines tool - Fixed Dimension object to respond to where the dimension line actually is --- architektonas.pro | 2 + res/architektonas.qrc | 1 + res/block-import.png | Bin 0 -> 1158 bytes res/layer-add.png | Bin 0 -> 1884 bytes res/layer-delete.png | Bin 0 -> 1938 bytes res/layer-down.png | Bin 0 -> 1142 bytes res/layer-edit.png | Bin 0 -> 1200 bytes res/layer-up.png | Bin 0 -> 1139 bytes res/trim-tool.png | Bin 0 -> 966 bytes src/applicationwindow.cpp | 17 ++++ src/applicationwindow.h | 2 + src/circle.cpp | 1 - src/dimension.cpp | 32 +++++--- src/dimension.h | 2 +- src/drawlineaction.cpp | 12 ++- src/geometry.cpp | 10 +-- src/trimaction.cpp | 161 ++++++++++++++++++++++++++++++++++++++ src/trimaction.h | 32 ++++++++ 18 files changed, 251 insertions(+), 21 deletions(-) create mode 100644 res/block-import.png create mode 100644 res/layer-add.png create mode 100644 res/layer-delete.png create mode 100644 res/layer-down.png create mode 100644 res/layer-edit.png create mode 100644 res/layer-up.png create mode 100644 res/trim-tool.png create mode 100644 src/trimaction.cpp create mode 100644 src/trimaction.h diff --git a/architektonas.pro b/architektonas.pro index edea5ee..eea6798 100644 --- a/architektonas.pro +++ b/architektonas.pro @@ -78,6 +78,7 @@ HEADERS = \ src/rotateaction.h \ src/settingsdialog.h \ src/text.h \ + src/trimaction.h \ src/vector.h SOURCES = \ @@ -112,5 +113,6 @@ SOURCES = \ src/rotateaction.cpp \ src/settingsdialog.cpp \ src/text.cpp \ + src/trimaction.cpp \ src/vector.cpp diff --git a/res/architektonas.qrc b/res/architektonas.qrc index cf1593b..602ddae 100644 --- a/res/architektonas.qrc +++ b/res/architektonas.qrc @@ -15,6 +15,7 @@ rotate-tool.png snap-to-grid-tool.png splash.png + trim-tool.png quit.png zoom-in.png zoom-out.png diff --git a/res/block-import.png b/res/block-import.png new file mode 100644 index 0000000000000000000000000000000000000000..8648f4f1e8414b29a32b9b1e24e00d5954a29c7f GIT binary patch literal 1158 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 W*9zqZAJd=!0000r;z literal 0 HcmV?d00001 diff --git a/res/layer-delete.png b/res/layer-delete.png new file mode 100644 index 0000000000000000000000000000000000000000..43369c2f7b1c4817dbce517ae18ab78988c36591 GIT binary patch literal 1938 zcmV;D2W|L?P)WFU8GbZ8()Nlj2>E@cM*00#C+L_t(|+U1)~a8uVA zhM#kFtzTQRY{!(i(|RCDtH=p7Q+`sCrvIK~2Rjzbuwl!vggt9^>{*m$7xk)?PD|@) zY~)PGPH}9;u4%|n117O$$y`b3-qXd={nIr>#zH^NnelM%J<`2;zxVy#^LT&ncbd|AH-PWy>2cP2yXYyG%Ve|JhP%G5 zO@VMY>??5rN~IEui;KGk-;n{ZL0-OmnWd#AUvpzSzhM}hI(2H-;5#k_Z1CA^mXjw> zI!1Nt?p>Irz=xnVq${P(NQ!_!!%8V5LByG z*4EZIefqQycr%JPy_48KfBrm~Oa@KUoDx?`$<)*oXV0E(3gaDD3fK4cUUr2Ly%t<*Jsdo8GQf&NI)?D8jOT%mugo(U5C3{FcO7d52`0x0=_6f zF8@-^jm>&nJ)myGQt)09Mj|eFfW@K$f4C3Ehd>ur1Is?(Y!;cihK_v!Fv95$=) zumZ(uOFcy275G>Pj`l;ubL~+DKHX5q`yy~8>B$NKe|ZA;4RxB<;p1V5YEYFhvjGdO z4S=>Q<`2fC}`jc4##zAcsH&I_UAX^(6@mEK?ve2@;_ zu~=0rLt2M}i6D4@#}y|%TD?J|?}+`Q{SeVy^trqO4{$UMJz9|crKhkz0v``;|B$kT zrLDI05{<6{nFM4#xjkEe`I_T^H0VXC~hP4Ab3 z{?}R(rZ(L7`S0u={?~AW*e3S34M3pOeZODH*d7ZW#y(8@m0d--c`^iJ$>%?Hp{P=* zO~%*wD)5t}V%Z-5+Jw0R4D`U65x?n4;KpNB5WSuB2gV!JFH1@x9RNO{03ZAN!tkSn zznGb=t>@#fL67IPRSP~ZC^LIK8Vu|57Oa+3SNO2fcG)+!3Vbx^XVETZj;2%}V2`IJ z{PD43^mspH`oP|%lM;$1{QaAb-BZ*9?8icC2PYBov;U}~nxC;gzwB)}|1b(~*Hw8^ zz~8=psco;82EZr%Oad~!F2Ju!@Xwm-AL{kH{Y)OdthKi%(*8SFr7Dr1JnLBS!4w$l z^|!conL8ST4+i}0?Mxn44CNEY`yu3+t61>+|8+F;+XvuXk9(Ia1^!4P5Qct^9Qj4l8lTn4`?xgb8@RN&w7fR|FGLs)~*v$03B&m zSad^gZEa<4bN~PV002XBWnpw>WFU8GbZ8()Nlj2>E@cM*00Y`dL_t(|+U1*DYZE~f z$N#gt_F^TmEmW-{lGjueK~Pc9*M0;aeDG8B(}=$K8N?ThMWu}|5eoK2sI`hzO{nz&jP-l7*~IGVDppoju(q~__4ReVLO|3)N%BRX*J`y;uh(IkX8(Mn z(Z~z|qf9FVg<_0Rumecz!isA)n`pP&n3EKO zDNO9f_E>`CG5+|NmfpH-KeQ78JXw8q+0XChVSJsOQ(2LJR<}VxuZZd zu~m(w$jwGlb|05!#SL+hOi!a~{lpv)8QYnrIiM7eOAev$DK=Ev8ybU3g-;EE5^DgaQAp)e z05|-FN#OA%>C^Vo-7s!hoE!eiH1J?vcI_{**x&OP~3 zNI+ShnE1zw(2qV`1g1O-A34DDufWY3uv81%=93M~p91PJQ;9AC&vu1IgM_`w+;BJ<)4>`xeoje>V930NDHk*bY!L zf#n7NoI|eLZymZ`a&a>36%GNfJHYpU1HuJ_V0qt0$rBD`Y|?~1!0rOSPTbFT=6pa0 zz^k9Y=3n>tvmMS?T~9gNcE}POR!n@MF|C(23Jhp_+5l#)0Q?VN+Y67zY2bDp=o#{a zfR}rH%V!DZyL^EMVLI3~&07*qo IM6N<$f(2y%WB>pF literal 0 HcmV?d00001 diff --git a/res/layer-edit.png b/res/layer-edit.png new file mode 100644 index 0000000000000000000000000000000000000000..105cb5d7e926f94cdb0e492ed0b7300a70ca9089 GIT binary patch literal 1200 zcmV;h1W)^kP)WFU8GbZ8()Nlj2>E@cM*00b0CL_t(|+U=X&Z_{QJ z#(%G!rVS}c+h}E=2~ckkN>Q~*Ok<3WT}^`jV3+$V`qvSw|W3%=`Idr?48fE`gAc*o_Y1TCp#Hnf!_tOC+b zK&J{cMto>-tfQ1QPcrffus2b;QNx}oFAx=c&jh3}4=68t+_M7Go(uyM;AeDFLW1g< zfKJdUB%$lva$!5Zly!pAQx(Wszu!T~xDm1kcx1gmi-fTm8g&8&?gchBHdLij0YKMv zc6WDKUS9Uf;_)v9uNxu>R)TJ|x^MFk5v6r&b+gj)dg0T8T$EK3LM6cgks$qye&{M7 zA}RxFP(xJ(Tu8Pj;=TY^O11wdlmhzn{IAn-_9NnMkLrRcAfa;DPZGqh)cQUc$(Sn) zcTX^bmRQ`X$|!mPu_xS7HA8JRjP3B4fKgooLCnxt0U3|JF9BJ$z(E@!2=HWulaq>H zzfx(8zNZ)H=*5+%FF#vQ{8UM`0&>3K3p!kyF@Uzl{Wq}v*4V!?8$=^R8~yHX@aqzs zEm+474h-;f6L5VVCe+XZ?DR5TIZgA7{)s%CD_X}pb$EDS?En0Q6a44q&_&mN?3d8J z74T!lDepf_@ZXl9VB_sW1Ac!I%jDyJqdZ6@(~d;HweE|$Gy2az!BPnpk2@{J-F>Jv z;LMbYbMlFnL5K9u7vcQ0mHT(4Cv;$8@rKSVNc?_B5wkIIR#VZs;D>Nw}0Sb z2^LGveDJgel?f=jq>zTd&A%negu{{$g#c$K_*dNm@#w$+f58S`#85?Ea|eIegj+9L z&66?-R$(U_22j*xqBGz`#BqUVD&!(Jit!PX%iYIIVN}!A&!r+T2G?9w%A%>hYG+@ z!EDY3{uMkkm&d{}xKxH#a1I4-zck8Z3{f8rH&|=J2xvLeJ)Saa;rQq8+ zz{d$59oOdJ%e(>p?!HkbQwqK}0#4-NWFU8GbZ8()Nlj2>E@cM*00Y-aL_t(|+T~hHYZFlv z{?5$Uhn2)OP_>FkpsQ3AK~Pc9ZGVCb7ygR=8qtlvLEKm@YTLM}P_P@J)+$mptr{k^ zWR8nTW+s_O=HA?SB^L%do#f_x-}%nt-aEw1$a)Zw?|*68MQIZd1U77>VOy#M#01X( zNR|XqH5oYs?;}CAvb;k>eg+S?4+P!4YPA|xS68vJvVyg>HEe8bqwY7zrnHlK14rT@sq0wk0uYfS)g613m zghlKWB{~rWL>VDyAd7rPMrBdo(GrU1VZtFY)Koi6O9H%N@5_8Pxke~M0vr>D`oTWD zS@r?hFG6Gp$id=iCgcc`ZgmqyVR0K*j1o}begaoC-5bgL>_xQPNghmZy9?M|14M$EJp-e~^TLQ*j z0RyW*T4Q~E9hFK20I;~Yn0_dP)p13YAc-bHS&3ri=p7*c2|T`3NcsD6KnVEoab+5KP#NhY7+neO%~AmZBh>qVXG28T z``NAL!jT5QO&UpnQ6$fakk;AEjRfDLfSjs8J*#~LXnm3ypJQQf2=uJ|ZaOfJ4+{(4*9peTz{~T% z`3W2RyF)uCptvtgiW6{d!rlY;c3f!BhY}!Ki;MoM?0-=*vu`p`eMkTR002ovPDHLk FV1hiA>%IU0 literal 0 HcmV?d00001 diff --git a/res/trim-tool.png b/res/trim-tool.png new file mode 100644 index 0000000000000000000000000000000000000000..4f80fbd522611f62e14807dfd00a68f28a71ae6d GIT binary patch literal 966 zcmV;%13CPOP)`C3dO`pI03B&m zSad^gZEa<4bN~PV002XBWnpw>WFU8GbZ8()Nlj2>E@cM*00SyXL_t(|+U;B2iqk+C zJu?X_X(eSVtga|%!KL?dL_d z&1CbRW+s!Q1Ep-+O}}&IobPAaG9p6Ri!l~>OjTS=H34B@qn3);loF5yd|nc=s>#$0 zd|0GR7P$bxq0gcSU=#;>eRCWKgTVm(ejmf(5TnsZFAF5>5T&pJi@V- zkF5d{^FS%tKS~K44PRVy&oku&h|-rpf)=bsR)ID6i}#JNK-iE|vOScrZ|0ScNJ5pB zVv4}h08s>%m2QE$wZE|h)OGUHc^J}WBII=%bPDYR>ni^$CN<0WD#fv;l8ckA!ssj+WCnlB0-jyT3yyS9 z!gf{QcwbXzr`vr%I1wta_fM+;CJR^+mR#Qwt4dkS0^UbJ9S%S8s95Ev!&>$OW&r#n z8+c%QZvL_WUQdDf5_oYPFwZ$#5%BVBWs_fcBXo2bxNm!ZpG|>}f828SvrAt^M=P=;7$uz67Y5gSRA-( zi&p~9e!0ZtD}zk6#1nVKM}TFxpyw;VHh_}@FXR=uvQOT5stWj^1?EflW*NYft^gju ztDnH+u;Z~KFZs?QMr0X4K#5PmA?hX4Qo07*qoM6N<$g1(oPGynhq literal 0 HcmV?d00001 diff --git a/src/applicationwindow.cpp b/src/applicationwindow.cpp index 5261dd1..4f1be35 100644 --- a/src/applicationwindow.cpp +++ b/src/applicationwindow.cpp @@ -45,6 +45,7 @@ #include "painter.h" #include "rotateaction.h" #include "settingsdialog.h" +#include "trimaction.h" // Class variables @@ -267,6 +268,13 @@ void ApplicationWindow::MirrorTool(void) } +void ApplicationWindow::TrimTool(void) +{ + ClearUIToolStatesExcept(trimAct); + SetInternalToolStates(); +} + + void ApplicationWindow::AddLineTool(void) { ClearUIToolStatesExcept(addLineAct); @@ -397,6 +405,9 @@ void ApplicationWindow::ClearUIToolStatesExcept(QAction * exception) if (exception != mirrorAct) mirrorAct->setChecked(false); + + if (exception != trimAct) + trimAct->setChecked(false); } @@ -421,6 +432,7 @@ void ApplicationWindow::SetInternalToolStates(void) drawing->SetToolActive(addDimensionAct->isChecked() ? new DrawDimensionAction() : NULL); drawing->SetToolActive(mirrorAct->isChecked() ? new MirrorAction() : NULL); drawing->SetToolActive(rotateAct->isChecked() ? new RotateAction() : NULL); + drawing->SetToolActive(trimAct->isChecked() ? new TrimAction() : NULL); if (drawing->toolAction) Object::ignoreClicks = true; @@ -700,6 +712,9 @@ void ApplicationWindow::CreateActions(void) mirrorAct = CreateAction(tr("&Mirror"), tr("Mirror"), tr("Mirror selected objects around a line."), QIcon(":/res/mirror-tool.png"), QKeySequence("m,i"), true); connect(mirrorAct, SIGNAL(triggered()), this, SLOT(MirrorTool())); + trimAct = CreateAction(tr("&Trim"), tr("Trim"), tr("Trim extraneous lines from selected objects."), QIcon(":/res/trim-tool.png"), QKeySequence("t,r"), true); + connect(trimAct, SIGNAL(triggered()), this, SLOT(TrimTool())); + //Hm. I think we'll have to have separate logic to do the "Radio Group Toolbar" thing... // Yup, in order to turn them off, we'd have to have an "OFF" toolbar button. Ick. @@ -770,6 +785,7 @@ void ApplicationWindow::CreateMenus(void) menu->addAction(fixLengthAct); menu->addAction(rotateAct); menu->addAction(mirrorAct); + menu->addAction(trimAct); menu->addAction(connectAct); menu->addAction(disconnectAct); menu->addSeparator(); @@ -818,6 +834,7 @@ void ApplicationWindow::CreateToolbars(void) toolbar->addAction(fixLengthAct); toolbar->addAction(rotateAct); toolbar->addAction(mirrorAct); + toolbar->addAction(trimAct); toolbar->addAction(deleteAct); toolbar->addAction(connectAct); toolbar->addAction(disconnectAct); diff --git a/src/applicationwindow.h b/src/applicationwindow.h index cf25247..089ab8f 100644 --- a/src/applicationwindow.h +++ b/src/applicationwindow.h @@ -34,6 +34,7 @@ class ApplicationWindow: public QMainWindow void DimensionTool(void); void RotateTool(void); void MirrorTool(void); + void TrimTool(void); void AddLineTool(void); void AddCircleTool(void); void AddArcTool(void); @@ -94,6 +95,7 @@ class ApplicationWindow: public QMainWindow QAction * connectAct; QAction * disconnectAct; QAction * mirrorAct; + QAction * trimAct; // Class variables public: diff --git a/src/circle.cpp b/src/circle.cpp index d8a2e5d..88cdaa7 100644 --- a/src/circle.cpp +++ b/src/circle.cpp @@ -253,7 +253,6 @@ same reference number. /*virtual*/ void Circle::Mirror(Point p1, Point p2) { Point c1 = Geometry::MirrorPointAroundLine(position, p1, p2); -// return new Circle(c1, radius); position = c1; } diff --git a/src/dimension.cpp b/src/dimension.cpp index 7c4488d..01d7ec3 100644 --- a/src/dimension.cpp +++ b/src/dimension.cpp @@ -73,33 +73,33 @@ all objects move as a unified whole. double angle = v.Angle(); Vector orthogonal = Vector::Normal(position, endpoint); Vector unit = v.Unit(); + linePt1 = position, linePt2 = endpoint; // Horizontally aligned display #if 1 - Vector pos = position, endp = endpoint, ortho; - double y1, y2; + Vector /*pos = position, endp = endpoint,*/ ortho; + double y1; if ((angle < PI_OVER_2) || (angle > PI3_OVER_2)) { - y1 = (pos.y > endp.y ? pos.y : endp.y); - y2 = (pos.y > endp.y ? endp.y : pos.y); + y1 = (position.y > endpoint.y ? position.y : endpoint.y); ortho = Vector(0, 1.0); angle = 0; } else { - y1 = (pos.y > endp.y ? endp.y : pos.y); - y2 = (pos.y > endp.y ? pos.y : endp.y); + y1 = (position.y > endpoint.y ? endpoint.y : position.y); ortho = Vector(0, -1.0); angle = PI; } - pos.y = endp.y = y1; - unit = Vector(pos, endp).Unit(); - Point p1 = pos + (ortho * 10.0 * size); - Point p2 = endp + (ortho * 10.0 * size); - Point p3 = pos + (ortho * 16.0 * size); - Point p4 = endp + (ortho * 16.0 * size); +// pos.y = endp.y = y1; + linePt1.y = linePt2.y = y1; + unit = Vector(linePt1, linePt2).Unit(); + Point p1 = linePt1 + (ortho * 10.0 * size); + Point p2 = linePt2 + (ortho * 10.0 * size); + Point p3 = linePt1 + (ortho * 16.0 * size); + Point p4 = linePt2 + (ortho * 16.0 * size); Point p5 = position + (ortho * 4.0 * size); Point p6 = endpoint + (ortho * 4.0 * size); #endif @@ -124,7 +124,8 @@ I believe they are pixels. // Calculate whether or not the arrowheads are too crowded to put inside // the extension lines. 9.0 is the length of the arrowhead. // double t = Geometry::ParameterOfLineAndPoint(position, endpoint, endpoint - (unit * 9.0 * size)); - double t = Geometry::ParameterOfLineAndPoint(pos, endp, endp - (unit * 9.0 * size)); +// double t = Geometry::ParameterOfLineAndPoint(pos, endp, endp - (unit * 9.0 * size)); + double t = Geometry::ParameterOfLineAndPoint(linePt1, linePt2, linePt2 - (unit * 9.0 * size)); //printf("Dimension::Draw(): t = %lf\n", t); // On the screen, it's acting like this is actually 58%... @@ -326,8 +327,13 @@ about keeping track of old states... { Vector orthogonal = Vector::Normal(position, endpoint); // Get our line parallel to our points +#if 0 Point p1 = position + (orthogonal * 10.0 * size); Point p2 = endpoint + (orthogonal * 10.0 * size); +#else + Point p1 = linePt1 + (orthogonal * 10.0 * size); + Point p2 = linePt2 + (orthogonal * 10.0 * size); +#endif Point p3(p1, point); hitPoint1 = hitPoint2 = hitLine = hitFlipSwitch = false; diff --git a/src/dimension.h b/src/dimension.h index c3709b6..9a9b3d4 100644 --- a/src/dimension.h +++ b/src/dimension.h @@ -1,7 +1,6 @@ #ifndef __DIMENSION_H__ #define __DIMENSION_H__ -#include "connection.h" #include "object.h" class Line; @@ -38,6 +37,7 @@ class Dimension: public Object Vector endpoint; // Starting point is Object::position Vector oldPoint; // Used for dragging Point oldEndpoint; + Point linePt1, linePt2; // Used for testing dimension line hits private: bool dragging; diff --git a/src/drawlineaction.cpp b/src/drawlineaction.cpp index 27b9513..5490e98 100644 --- a/src/drawlineaction.cpp +++ b/src/drawlineaction.cpp @@ -80,12 +80,22 @@ DrawLineAction::~DrawLineAction() { p2 = p1; state = NEXT_POINT; + line = NULL; } else if (state == NEXT_POINT) { + Line * oldLine = line; // We create the new object here, and then pass it off to the // DrawingView which stuffs it into the document. line = new Line(p1, p2); + + // Connect Lines by default + if (oldLine) + { + oldLine->Connect(line, 0); + line->Connect(oldLine, 1.0); + } + // We don't need no stinkin' sentinels, when we have signals & slots! emit ObjectReady(line); @@ -103,7 +113,7 @@ DrawLineAction::~DrawLineAction() p1Save = p1; p1 = p2; state = FIRST_POINT; - emit(NeedRefresh()); + emit NeedRefresh(); } } diff --git a/src/geometry.cpp b/src/geometry.cpp index cfb0511..41928aa 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -62,15 +62,15 @@ double Geometry::ParameterOfLineAndPoint(Point tail, Point head, Point point) } -Point Geometry::MirrorPointAroundLine(Point point, Point p1, Point p2) +Point Geometry::MirrorPointAroundLine(Point point, Point tail, Point head) { // Get the vector of the intersection of the line and the normal on the // line to the point in question. - double t = ParameterOfLineAndPoint(p1, p2, point); - Vector v = Vector(p1, p2) * t; + double t = ParameterOfLineAndPoint(tail, head, point); + Vector v = Vector(tail, head) * t; - // Get the point normal to point to the line passed in (p2 is the tail) - Point normalOnLine = p2 + v; + // Get the point normal to point to the line passed in + Point normalOnLine = tail + v; // Make our mirrored vector (head - tail) Vector mirror = -(point - normalOnLine); diff --git a/src/trimaction.cpp b/src/trimaction.cpp new file mode 100644 index 0000000..ea8e9eb --- /dev/null +++ b/src/trimaction.cpp @@ -0,0 +1,161 @@ +// TrimAction.cpp: Action class for mirroring selected objects +// +// Part of the Architektonas Project +// (C) 2011 Underground Software +// See the README and GPLv3 files for licensing and warranty information +// +// JLH = James Hammons +// +// WHO WHEN WHAT +// --- ---------- ------------------------------------------------------------ +// JLH 08/27/2011 Created this file +// + +#include "trimaction.h" +#include "applicationwindow.h" +#include "container.h" +#include "drawingview.h" +#include "line.h" +#include "mathconstants.h" +#include "painter.h" + + +enum { FIRST_POINT, NEXT_POINT }; + + +TrimAction::TrimAction(): state(FIRST_POINT), line(NULL), + shiftWasPressedOnNextPoint(false), ctrlWasPressed(false), + mirror(new Container(Vector())) +{ + ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror); + mirror->Save(); +} + + +TrimAction::~TrimAction() +{ +} + + +/*virtual*/ void TrimAction::Draw(Painter * painter) +{ + painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine)); + + if (state == FIRST_POINT) + { + painter->DrawHandle(p1); + } + else + { + Vector reflectedP2 = -(p2 - p1); + Point newP2 = p1 + reflectedP2; + painter->DrawLine(newP2, p2); + painter->DrawHandle(p1); + + double absAngle = (Vector(p2 - p1).Angle()) * RADIANS_TO_DEGREES; + + // Keep the angle between 0 and 180 degrees + if (absAngle > 180.0) + absAngle -= 180.0; + + QString text = QChar(0x2221) + QObject::tr(": %1"); + text = text.arg(absAngle); + + if (ctrlWasPressed) + text += " (Copy)"; + + painter->DrawInformativeText(text); + + // Draw the mirror only if there's been a line to mirror around + if (p1 != p2) + mirror->Draw(painter); + } +} + + +/*virtual*/ void TrimAction::MouseDown(Vector point) +{ + // Clear our override... + shiftWasPressedOnNextPoint = false; + + if (state == FIRST_POINT) + p1 = point; + else + p2 = point; +} + + +/*virtual*/ void TrimAction::MouseMoved(Vector point) +{ + if (state == FIRST_POINT) + p1 = point; + else + { + p2 = point; + mirror->Restore(); + mirror->Mirror(p1, p2); + } +} + + +/*virtual*/ void TrimAction::MouseReleased(void) +{ + if (state == FIRST_POINT) + { + p2 = p1; + state = NEXT_POINT; + } + else if (state == NEXT_POINT) + { + if (!ctrlWasPressed) + { + state = FIRST_POINT; + ApplicationWindow::drawing->document.MirrorSelected(p1, p2); + + mirror->Clear(); + ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror); + mirror->Save(); + } + else + { + mirror->CopyContentsTo(&(ApplicationWindow::drawing->document)); + } + } +} + + +/*virtual*/ void TrimAction::KeyDown(int key) +{ + if ((key == Qt::Key_Shift) && (state == NEXT_POINT)) + { + shiftWasPressedOnNextPoint = true; + p1Save = p1; + p1 = p2; + state = FIRST_POINT; + emit NeedRefresh(); + } + else if (key == Qt::Key_Control) + { + ctrlWasPressed = true; + emit NeedRefresh(); + } +} + + +/*virtual*/ void TrimAction::KeyReleased(int key) +{ + if ((key == Qt::Key_Shift) && shiftWasPressedOnNextPoint) + { + shiftWasPressedOnNextPoint = false; + p2 = p1; + p1 = p1Save; + state = NEXT_POINT; + emit NeedRefresh(); + } + else if (key == Qt::Key_Control) + { + ctrlWasPressed = false; + emit NeedRefresh(); + } +} + diff --git a/src/trimaction.h b/src/trimaction.h new file mode 100644 index 0000000..02720de --- /dev/null +++ b/src/trimaction.h @@ -0,0 +1,32 @@ +#ifndef __TRIMACTION_H__ +#define __TRIMACTION_H__ + +#include "action.h" + +class Container; +class Line; + +class TrimAction: public Action +{ + public: + TrimAction(); + ~TrimAction(); + + virtual void Draw(Painter *); + virtual void MouseDown(Vector); + virtual void MouseMoved(Vector); + virtual void MouseReleased(void); + virtual void KeyDown(int); + virtual void KeyReleased(int); + + private: + int state; + Line * line; + Vector p1, p2, p1Save; + bool shiftWasPressedOnNextPoint; + bool ctrlWasPressed; + Container * mirror; +}; + +#endif // __TRIMACTION_H__ + -- 2.37.2