From b30b3fd522b8ec4c31fb14a3e28d98c1f15d9a48 Mon Sep 17 00:00:00 2001 From: letsfindaway Date: Thu, 4 Feb 2021 18:14:59 +0100 Subject: [PATCH] add cpp tool to draw a coordinate system --- resources/OpenBoard.qrc | 2 + resources/images/numbersTool.svg | 63 +++ resources/images/toolPalette/axesTool.png | Bin 0 -> 8134 bytes src/adaptors/UBSvgSubsetAdaptor.cpp | 91 ++++ src/adaptors/UBSvgSubsetAdaptor.h | 4 + src/board/UBBoardController.cpp | 5 + src/board/UBBoardView.cpp | 3 + src/core/UB.h | 1 + src/domain/UBGraphicsScene.cpp | 16 + src/domain/UBGraphicsScene.h | 1 + src/tools/UBGraphicsAxes.cpp | 580 ++++++++++++++++++++++ src/tools/UBGraphicsAxes.h | 142 ++++++ src/tools/UBToolsManager.cpp | 8 + src/tools/UBToolsManager.h | 1 + src/tools/tools.pri | 2 + 15 files changed, 919 insertions(+) create mode 100644 resources/images/numbersTool.svg create mode 100644 resources/images/toolPalette/axesTool.png create mode 100644 src/tools/UBGraphicsAxes.cpp create mode 100644 src/tools/UBGraphicsAxes.h diff --git a/resources/OpenBoard.qrc b/resources/OpenBoard.qrc index 3e41418a..480269c1 100644 --- a/resources/OpenBoard.qrc +++ b/resources/OpenBoard.qrc @@ -364,5 +364,7 @@ images/expand-all.png images/asc.png images/desc.png + images/toolPalette/axesTool.png + images/numbersTool.svg diff --git a/resources/images/numbersTool.svg b/resources/images/numbersTool.svg new file mode 100644 index 00000000..862270de --- /dev/null +++ b/resources/images/numbersTool.svg @@ -0,0 +1,63 @@ + + + +image/svg+xml1 + \ No newline at end of file diff --git a/resources/images/toolPalette/axesTool.png b/resources/images/toolPalette/axesTool.png new file mode 100644 index 0000000000000000000000000000000000000000..05008c8cba7f605baf16a85869ae30817d341e22 GIT binary patch literal 8134 zcmV;%A35NOP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3;wlG{p*tpC?4W(oCvET^6kvxB?*`B0=JO3iM& zeXcufsVS<60uqS?NUQn({&%VW;ZF)VDj!mgB}UC3UwpBZH(4Klj#s1o{&)Y0=STeh zc3eF_upDx{y7LS3Jil^0yuOh9dAz+JSE--t~zNI{jWW)l<< zr|WJU_{uH^UC&WQLd)z>z}Lt*2rtkV|Ueq zqvGSasmE6KJ5I!<-tDhNeiDBJ@6-M%{A68qCu)POHl-WC6l3xDGTsbR%`$VpcGEG@ z+i4T8)^_|Z$FfVd*zP0*UVhB7Nx9;N%fzD-Imco9w8iY}7P%f5%UpRF&a{Tbi1GW6 z`aJNjKW_`ICB8LA=cli*%L=|QLn0^tauxwG>-1^Z{x#}&(Vu@Lu#O0Z?dHq|t8T{< zEtnU!+>W!;L2;_rN4}Ue&INE0*A5s1qP@}4xL~5u$=YNLe$2$DV!3tRHX>kx3U*+n z_0C0tldW8v?9=C5TzXEHS`~y*c0!w@M?cpXrLPI!rqOWH^3AVaYK!8a5$4Q&4CQ?p zxinweDskc0Sb`*U_o-LC8fJ``M`C^7S4u>y+tIztqbE1<b-uhJZ)VsNNwvV04% zyVWMEj%aNeVWklINEmG0+qwSDK!rCKP{F>oVr|XT?u6^LMV8^+M7 zg@A8U1vDxozral}S&DXYJq^}dZ|hVEL=V&U>3g(#4B2sWxyRT5g2oGKE_M*W5V&f8 zv?Zp)7=uTEmJ2i2zRyt?gIDasF9F4}vAU6cYxw)`Hmp8(+?)x+wODfmA}Ml-w%k~b z)k3NuGEX3)V-0P1Z>F4)C*`OmQ`RI0KH`@GsnBW*q(J~Iu?-W-r`gZ%sQo4L-Om4d z<3ULwB^9t=s!(eL03^GST_$mpJF&)RROMDv9*R8;$TJao_^^_*oK828SEerXFtiJ~)XAD$ zt0iZUdwoIiZsJi}YJ`rgQK8O+r+uIZv2AL@VK6fBd}SX9K}~6!MP4hcyND^&)%HjG z1GV;Xg#GbJtfP^j&ehb;B^v_owRo?sAIrAAJOz3!Qd#lMNGc_9Gj1A5KbDQ6Cf#1N zkOghWDB4JEly}lS9Iw&N7S!S&0*1C3Vox(ER9PzES7=i{h7}r=OMHc+gI;<1V-eJD zJtM5XgqXOQZTu%Dl8?46Fx_FIj>y^ppUDN;xT<-^QX-|kcQ)>UCul&0$Wk2wvYq6J z1P7tJCdF_%G{9VzH`{hk?Q2z09tG2Bz+s$J$U8jhk;~fTNl{oL0gF)c6y3 zDRaKz)fDOh4xz3PJqiVRHn~Rg(%nuE zi5B#Wxui2W(EZY4dupn46~qeGwm2JoW>_7SMZKK*gdOxGZ))xdHG7gYGn}Gls(r&kf1&UM$UIpfJmS&O*FtJ#DI+|3Fb7hG<1`M_|j`bjZz;2KTslY{)$25#x z6i7sI=*`E7zl4yi<`Qg!f9X4hiqmMwUd$$0nrVA6T>}Lxqi`wE6z7bDqxVb2cSI)Q zimnkP;nRph8zn>)h1}68)njm<)Ez^K8xnLMA3S`%;#L6>T!r}q{Z2gsHT$r-9*0`? zC!3N}LD$QP|Q#I|A;J@Nhok@_2&`2cd10SACR`5j0W5F6bzkf}EGqF>0(Vu?yiBi4qlMtmLF%Mm7SXWZ=SAg(&qL#) zHsIhwBxq{lbO=t`jT*v{gVx0`nkv26#KMq6^T#^pDpD^{#Agb;X8>FFQ&+l5Xilsg z%1RS}h$wllzd0g_i5Tc^?TZKuyZ2zJy0P?z$D?waR6o9eX>si1X5lIDh~UZ8Lpq=} z$wu!AdZ;7W(eOAiS|#I%Wzu=Nh~Lb zioo;mhe_Ki4W|>CsRu2RMO_tP!qm3qA9lh`C;psTJM_RWc0dx2?aSuv47_vZFMX## z)a%RUaNNK6OQjZQI~o3$V*3E!h8_zE`fjB5uZ6Y> z_d@%(GJC2+X5;V;#5bw^E1|vHENbvzXO(_*F1b&FO!-Eow9(IaBl2It#z&8MQ-3Am z;&vkL1#0QT6;GE0vIeVb%anf-L9Znhmu! z8nVBnPgtr0m-ny?;-N&XLSE;r&C#N!wqx4kpMeEqmEU;loCm7=Sc&7l0ftW? z2gahQYcbP4jjc%3*G{z$>Cz$FSOcXGpktU#y;0$!jNZtdFg|To7o&%*12@t@So(Bt zYd4mb|AoMBZDd>O*q5|)bH6@tm>xI`YwzGOSo<#X)E^?1SCuMF3Ztv^9&6qeiqh0) z&OB0Piz322$vWd`C}l+1kb?Hj!31-{9+M*q1PvduON@!h~{9jFsn*;n~EYFM}SC623y^R!`|R((q#y3@{W$ zVo0+%VZIE{ZfDN8c^0{h_e22XNzpc%$~R-GB}Jc2^l`Un(d8PKlEw|lEZR+R5R6!8 zotxbL_Ov%KWF#ESnxxGq?a{i8UE>fL7Kim1e5$vx82l=?Ot!EJc6v{}IwsOdw&sj42RUKn26Zd3S0vQ?(L0>_+kmC0#_X zkpDTG8|d@*N!Yg&v6tF>eV{J0vVWO~JqKb3XK!iChDF@|b|!X)Nv+>a#7=)_Q_Fj! zq5jKlo^#8Ur6B*m<(-w>A>@hmTc~jj!B)>`?^uhl8{^#(cLVr${URTzo6-Dr0{?dd zc&JAGIDdZ|zf*cc9)PZoQmmIW|(-;D(5Pv(Qvd9I%JMx&X^UH< z*k_aH0TI4}Y&W=RHJLxj)Q_afl`2h>G~}i=Iqc;we4*=!*>)N*D6i734P+;+c^)z( z$H7h7+z>?tNiVYDj2M#{Zd>rqwuXuVVNRLHzP{_Oy@Olys=O{Ow{rO;sjec)sQ<)K$$hOUDtcq*M*8Zm9dB>3z{tx)oGR$U1~w9mPbJhiqKFnMb0LuX>X79CXFG`(o>C=azQK> zs2px8(RpBm7B|#E4JFbDw!9fg#v^-T`*hvKaf+o+znxwapB!#GoF-p_7w z1_g7sRL7=w#J*(H;f;wHZI1NKBKVsei_yWSpaNoY4q;|@e@4S$A4?%@jCdYG*v!?C z7@HwG4N(cM)G3ciWb}-&KV6-c_lqyphcms*HL9Re;5LTb2uHm0u`xT+ch(%kIxn5a z?=AQ=K>e!)UG$o7&x}ytq=ej(*x|HCb1e6N!r2~6os!#?GVH9!tsq_1VT_o2HD_nG z%qBE_rJ@Tb&Wwl9De_^Udx1+ zhDZibaU@i%cQn{E_l_twbk{1i`W3oDz8Jc_5>U*(4J-2pksDRBxI79$A+W-a^g}7q z=|oY$2nVw|I|G~YfSgTm&9s7KGqlN_Z(5?V@Na7|~0VgaL>i(>{l69Pj0 zO*1UjftDW&z!EYmEDTGgSOglUM}it<0!9SRC%>j-z3Y14m zWKgQ9JiW&~#`t`&=1(G8-KyxXkJWttP|ew9t6$&RTlaubpELE_n|qHI?r7j{@9L@F zKSOu_2%Y-V%md}$HlU~Ui$Ml z2bB^}b$<)j$%9?}gJ9?YKRR&2Vma#ht9B!PIk5k0!8fELW=Kn}rP_}7hvig60bN2r zUQ6Cx;`*D(Qk5i(jDye`VIwF#@CnP~bGe4hLuudxM5BS-y^|Byq3qLGI$P%1$+ znP2?E7cW=%b(n7!UP!1~Bb^<(Bgvha^4h?@Gb1zpeP^bMrcOg2WeVK!IRzAMHsXV! zvSjPGUvSTB$bGJ2kKXKXRIHE`B!*_psS*A}w~dG)zQKPtr}EeH39XPb;>~ z;^$7^_vvWv7y z8!f9nV0uOA&Do06y*x8c*D5ktn*qs{)Ry(RLq?)TWRHnd^|MNK8}9YUZVmLbsQs#F zABLr$sQBWzWx4}+h7Vre0lb9o4I(>qy~%^#1h1rxg#QKv^+Li1!UdgQzL0;gc&INB z#f=nB-?EIwJnBinB=@n}YErIS%yb{}Uuj53FP=<%xKu{RQ07hCProI9kgS!Pebo2a z5gv1j5~FJ@0vc3>`af?U+>~P%m3V;qfgCS3StULv9y95J#E)E8 zJbvR`bXnk;Q8SaCCyo+}#ST_Fn3YV8c#1ftYC7c$S&voDTb#8@jkWH{Ul`8oE6ZG` zIgBJ0u>=Vs6x2{g1vcWe>ZDjm(|*FoKjiu)aw+60gOOtaRcMf1KlmT~?$#y{D4^000SaNLh0L04^f{04^f|c%?sf00007bV*G` z2jv143KSAY+V__L00&A*L_t(|+U=d&Zxq)Z$3JIwW<52FZ@aP6B41<-A++(L+O9-v z#UW}7i12`48e|Faoc+XBDoY0ZDqg@CUReU*4NE;3ob)dCtggc8=mWk;dAQW&h{ia7*Xbp$-Tl_FD$-BAwZeU_2j^i1Wh4gtUGH1YJ zC<`UE0=PSDQk3IT8q!x-rlJP%BrE)Fl0l7he+FhYY}qA^f2KQO*LAsgp_S`bFNoJ) zP{wM&;NT!bLqh-z4GmFJQX<~ZWDU4|`}WdyM@NTvK9c}qu^4C0oLSmGfBrm)L_)lu zDF6>1Jiu|BrTy{oar*oF#rv58(AL(rdYpahmUurC0H&v>xpe8$s^e$Ro+TQM3V?Jc z(ACwo_B#-zxPSk?07!QNEiEnUp1XSWssKo*@!{cNy1TpAJ%8iI4aUdE1wguV_wL>A zyr#3WQvjqxj^li5^Ye{bTU+sThqD9#3=9k~Iy$!n_rYCv<2nI$K(8Yar;;A#|ed=>nT-p2CZFwKKbCe z)}VaTzq6<=cC-fNzxc{xY*w-NCvoWmq!Shi00AHp00KY&hy;KD5D5SQAQAuqKqLSJ zfJguc0FeL?0HRDt-Rqn3{?==yJ)!8#7#C0e27rA>&XJw_&Rg&Nk1G9HC8_V_3IZ;s&w%2BwIcr(MY*oFSrK+}IgL&EE}@{F*#?n01BRibK<`oopAVT7 zZgeRL>YEi2nKO9qu)?PF0n!Nz0FeL?03rb(07L>n0Eh&D01ycP0U#0p|6giqYNEZp zow>O=t#(au?aOJ)mMt7VejI=U2M$nMTg%q1Td^!l0Axaym6cRiS99mi9h#e)X>M*N z7z|QhUr$X<&G%jhRhpnz(4IYeR_sqsPIBthDHP+{4YlY%gV~uy}YNVhn}7u0Cw-*Opp5XO=$apK_n94 z$dMxeoIH7wU@)k~?$n&YXT25&tMo2aaG}djcvEu4goUxOF^(NO_EICJ{rmT`W5*5( z3k#QyueDUcx_yApv?vIM2x*!X;kwIqg25o6P)LubY=aHCenO#`Rsb9GvM4BU2)(dY z#NgoIy4ME+0qX1P*|~EkrKP19#><~g5&!}~BmmwXnE*-me?HV+j4UNxg`?>+S;t)tS2;=a*ibmx@Bh3_(pBu<^)qcYr=yC03|Q1x#!3cd>*;Br?vS32>3m0OYc7} gb8L_K_{tmoFXh60Rz#y+M*si-07*qoM6N<$f=w8!C;$Ke literal 0 HcmV?d00001 diff --git a/src/adaptors/UBSvgSubsetAdaptor.cpp b/src/adaptors/UBSvgSubsetAdaptor.cpp index 052ea10b..ad209b1b 100644 --- a/src/adaptors/UBSvgSubsetAdaptor.cpp +++ b/src/adaptors/UBSvgSubsetAdaptor.cpp @@ -51,6 +51,7 @@ #include "domain/UBItem.h" #include "tools/UBGraphicsRuler.h" +#include "tools/UBGraphicsAxes.h" #include "tools/UBGraphicsCompass.h" #include "tools/UBGraphicsProtractor.h" #include "tools/UBGraphicsCurtainItem.h" @@ -754,6 +755,17 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene(UBDocumentProx mScene->registerTool(ruler); } + } + else if (mXmlReader.name() == "axes") + { + + UBGraphicsAxes *axes = axesFromSvg(); + if (axes) + { + mScene->addItem(axes); + mScene->registerTool(axes); + } + } else if (mXmlReader.name() == "compass") { @@ -1353,6 +1365,14 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(UBDocumentProxy* proxy, continue; } + // Is the item a axes? + UBGraphicsAxes *axes = qgraphicsitem_cast (item); + if (axes && axes->isVisible()) + { + axesToSvg(axes); + continue; + } + // Is the item a cache? UBGraphicsCache* cache = qgraphicsitem_cast(item); if(cache && cache->isVisible()) @@ -2859,6 +2879,40 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::rulerToSvg(UBGraphicsRuler* item) mXmlWriter.writeEndElement(); } +void UBSvgSubsetAdaptor::UBSvgSubsetWriter::axesToSvg(UBGraphicsAxes *item) +{ + + /** + * + * sample + * + + + */ + + mXmlWriter.writeStartElement(UBSettings::uniboardDocumentNamespaceUri, "axes"); + mXmlWriter.writeAttribute("x", QString("%1").arg(item->pos().x())); + mXmlWriter.writeAttribute("y", QString("%1").arg(item->pos().y())); + mXmlWriter.writeAttribute("left", QString("%1").arg(item->bounds().left())); + mXmlWriter.writeAttribute("top", QString("%1").arg(item->bounds().top())); + mXmlWriter.writeAttribute("width", QString("%1").arg(item->bounds().width())); + mXmlWriter.writeAttribute("height", QString("%1").arg(item->bounds().height())); + mXmlWriter.writeAttribute("numbers", QString("%1").arg(item->showNumbes())); + + QString zs; + zs.setNum(item->zValue(), 'f'); // 'f' keeps precision + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "z-value", zs); + + UBItem* ubItem = dynamic_cast(item); + + if (ubItem) + { + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "uuid", UBStringUtils::toCanonicalUuid(ubItem->uuid())); + } + + mXmlWriter.writeEndElement(); +} + UBGraphicsRuler* UBSvgSubsetAdaptor::UBSvgSubsetReader::rulerFromSvg() { @@ -2883,6 +2937,43 @@ UBGraphicsRuler* UBSvgSubsetAdaptor::UBSvgSubsetReader::rulerFromSvg() return ruler; } +UBGraphicsAxes *UBSvgSubsetAdaptor::UBSvgSubsetReader::axesFromSvg() +{ + UBGraphicsAxes* axes = new UBGraphicsAxes(); + + graphicsItemFromSvg(axes); + + axes->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Tool)); + + QStringRef svgX = mXmlReader.attributes().value("x"); + QStringRef svgY = mXmlReader.attributes().value("y"); + QStringRef svgLeft = mXmlReader.attributes().value("left"); + QStringRef svgTop = mXmlReader.attributes().value("top"); + QStringRef svgWidth = mXmlReader.attributes().value("width"); + QStringRef svgHeight = mXmlReader.attributes().value("height"); + QStringRef svgNumbers = mXmlReader.attributes().value("numbers"); + + if (!svgX.isNull() && !svgY.isNull()) + { + axes->setPos(svgX.toString().toFloat(), svgY.toString().toFloat()); + } + + if (!svgWidth.isNull() && !svgHeight.isNull() && !svgLeft.isNull() && !svgTop.isNull()) + { + axes->setRect(svgLeft.toString().toFloat(), svgTop.toString().toFloat(), + svgWidth.toString().toFloat(), svgHeight.toString().toFloat()); + } + + if (!svgNumbers.isNull()) + { + axes->setShowNumbers(svgNumbers.toInt()); + } + + axes->setVisible(true); + + return axes; +} + void UBSvgSubsetAdaptor::UBSvgSubsetWriter::compassToSvg(UBGraphicsCompass* item) { diff --git a/src/adaptors/UBSvgSubsetAdaptor.h b/src/adaptors/UBSvgSubsetAdaptor.h index c66c8198..ea263969 100644 --- a/src/adaptors/UBSvgSubsetAdaptor.h +++ b/src/adaptors/UBSvgSubsetAdaptor.h @@ -49,6 +49,7 @@ class UBGraphicsW3CWidgetItem; class UBGraphicsTextItem; class UBGraphicsCurtainItem; class UBGraphicsRuler; +class UBGraphicsAxes; class UBGraphicsCompass; class UBGraphicsProtractor; class UBGraphicsScene; @@ -144,6 +145,8 @@ class UBSvgSubsetAdaptor UBGraphicsRuler* rulerFromSvg(); + UBGraphicsAxes* axesFromSvg(); + UBGraphicsCompass* compassFromSvg(); UBGraphicsProtractor* protractorFromSvg(); @@ -247,6 +250,7 @@ class UBSvgSubsetAdaptor void textItemToSvg(UBGraphicsTextItem *item); void curtainItemToSvg(UBGraphicsCurtainItem *item); void rulerToSvg(UBGraphicsRuler *item); + void axesToSvg(UBGraphicsAxes *item); void compassToSvg(UBGraphicsCompass *item); void protractorToSvg(UBGraphicsProtractor *item); void cacheToSvg(UBGraphicsCache* item); diff --git a/src/board/UBBoardController.cpp b/src/board/UBBoardController.cpp index 749b73e4..0ee35ae5 100644 --- a/src/board/UBBoardController.cpp +++ b/src/board/UBBoardController.cpp @@ -1441,6 +1441,11 @@ UBItem *UBBoardController::downloadFinished(bool pSuccess, QUrl sourceUrl, QUrl mActiveScene->addRuler(pPos); UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); } + else if (sourceUrl.toString() == UBToolsManager::manager()->axes.id) + { + mActiveScene->addAxes(pPos); + UBDrawingController::drawingController()->setStylusTool(UBStylusTool::Selector); + } else if (sourceUrl.toString() == UBToolsManager::manager()->protractor.id) { mActiveScene->addProtractor(pPos); diff --git a/src/board/UBBoardView.cpp b/src/board/UBBoardView.cpp index 78ba7ba2..4accb0f6 100644 --- a/src/board/UBBoardView.cpp +++ b/src/board/UBBoardView.cpp @@ -77,6 +77,7 @@ #include "document/UBDocumentProxy.h" #include "tools/UBGraphicsRuler.h" +#include "tools/UBGraphicsAxes.h" #include "tools/UBGraphicsCurtainItem.h" #include "tools/UBGraphicsCompass.h" #include "tools/UBGraphicsCache.h" @@ -467,6 +468,7 @@ bool UBBoardView::isCppTool(QGraphicsItem *item) { return (item->type() == UBGraphicsItemType::CompassItemType || item->type() == UBGraphicsItemType::RulerItemType + || item->type() == UBGraphicsItemType::AxesItemType || item->type() == UBGraphicsItemType::ProtractorItemType || item->type() == UBGraphicsItemType::TriangleItemType || item->type() == UBGraphicsItemType::CurtainItemType); @@ -537,6 +539,7 @@ Here we determines cases when items should to get mouse press event at pressing { case UBGraphicsProtractor::Type: case UBGraphicsRuler::Type: + case UBGraphicsAxes::Type: case UBGraphicsTriangle::Type: case UBGraphicsCompass::Type: case UBGraphicsCache::Type: diff --git a/src/core/UB.h b/src/core/UB.h index 86f9691a..0811b035 100644 --- a/src/core/UB.h +++ b/src/core/UB.h @@ -172,6 +172,7 @@ struct UBGraphicsItemType ToolWidgetItemType, //65555 GraphicsWidgetItemType, //65556 UserTypesCount, //65557 + AxesItemType, //65558 SelectionFrameType // this line must be the last line in this enum because it is types counter. }; }; diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index 44b14418..4e91018e 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -50,6 +50,7 @@ #include "gui/UBResources.h" #include "tools/UBGraphicsRuler.h" +#include "tools/UBGraphicsAxes.h" #include "tools/UBGraphicsProtractor.h" #include "tools/UBGraphicsCompass.h" #include "tools/UBGraphicsTriangle.h" @@ -2191,6 +2192,21 @@ void UBGraphicsScene::addRuler(QPointF center) ruler->setVisible(true); } +void UBGraphicsScene::addAxes(QPointF center) +{ + UBGraphicsAxes* axes = new UBGraphicsAxes(); // mem : owned and destroyed by the scene + mTools << axes; + + axes->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Tool)); + + addItem(axes); + + QPointF itemSceneCenter = axes->sceneBoundingRect().center(); + axes->moveBy(center.x() - itemSceneCenter.x(), center.y() - itemSceneCenter.y()); + + axes->setVisible(true); +} + void UBGraphicsScene::addProtractor(QPointF center) { // Protractor diff --git a/src/domain/UBGraphicsScene.h b/src/domain/UBGraphicsScene.h index 4040af7e..3b898685 100644 --- a/src/domain/UBGraphicsScene.h +++ b/src/domain/UBGraphicsScene.h @@ -236,6 +236,7 @@ class UBGraphicsScene: public UBCoreGraphicsScene, public UBItem } void addRuler(QPointF center); + void addAxes(QPointF center); void addProtractor(QPointF center); void addCompass(QPointF center); void addTriangle(QPointF center); diff --git a/src/tools/UBGraphicsAxes.cpp b/src/tools/UBGraphicsAxes.cpp new file mode 100644 index 00000000..566e4b15 --- /dev/null +++ b/src/tools/UBGraphicsAxes.cpp @@ -0,0 +1,580 @@ +/* + * Copyright (C) 2015-2018 Département de l'Instruction Publique (DIP-SEM) + * + * Copyright (C) 2013 Open Education Foundation + * + * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour + * l'Education Numérique en Afrique (GIP ENA) + * + * This file is part of OpenBoard. + * + * OpenBoard 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, version 3 of the License, + * with a specific linking exception for the OpenSSL project's + * "OpenSSL" library (or with modified versions of it that use the + * same license as the "OpenSSL" library). + * + * OpenBoard 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 OpenBoard. If not, see . + */ + + + + +#include + +#include "tools/UBGraphicsAxes.h" +#include "domain/UBGraphicsScene.h" +#include "frameworks/UBGeometryUtils.h" +#include "core/UBApplication.h" +#include "gui/UBResources.h" +#include "board/UBBoardController.h" // TODO UB 4.x clean that dependency +#include "board/UBDrawingController.h" + +#include "core/memcheck.h" + +const QRect UBGraphicsAxes::sDefaultRect = QRect(-200, -200, 400, 400); + +const QColor UBGraphicsAxes::sLightBackgroundDrawColor = QColor(0x33, 0x33, 0x33, sDrawTransparency); +const QColor UBGraphicsAxes::sDarkBackgroundDrawColor = QColor(0xff, 0xff, 0xff, sDrawTransparency); + + +UBGraphicsAxes::UBGraphicsAxes() + : QGraphicsPolygonItem() + , mResizing(false) +{ + setRect(sDefaultRect); + + setFlag(QGraphicsItem::ItemIsMovable, true); + setFlag(QGraphicsItem::ItemIsSelectable, true); + setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); + + setAcceptHoverEvents(true); + + mCloseSvgItem = new QGraphicsSvgItem(":/images/closeTool.svg", this); + mCloseSvgItem->setVisible(false); + mCloseSvgItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control)); + + mNumbersSvgItem = new QGraphicsSvgItem(":/images/numbersTool.svg", this); + mNumbersSvgItem->setVisible(false); + mNumbersSvgItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control)); + + mShowNumbers = true; + + setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::CppTool)); //Necessary to set if we want z value to be assigned correctly + + setFlag(QGraphicsItem::ItemIsSelectable, false); + updateResizeCursor(); + + connect(UBApplication::boardController, &UBBoardController::zoomChanged, [this](qreal){ + // recalculate shape when zoom factor changes + setRect(mBounds); + }); +} + +UBGraphicsAxes::~UBGraphicsAxes() +{ + // NOOP +} + +UBItem* UBGraphicsAxes::deepCopy() const +{ + UBGraphicsAxes* copy = new UBGraphicsAxes(); + + copyItemParameters(copy); + + // TODO UB 4.7 ... complete all members ? + + return copy; +} + +void UBGraphicsAxes::copyItemParameters(UBItem *copy) const +{ + UBGraphicsAxes *cp = dynamic_cast(copy); + if (cp) + { + cp->setPos(this->pos()); + cp->setRect(this->mBounds); + cp->setTransform(this->transform()); + } +} + +void UBGraphicsAxes::setRect(qreal x, qreal y, qreal w, qreal h) +{ + // Save the bounds rect + mBounds.setX(x); mBounds.setY(y); mBounds.setWidth(w); mBounds.setHeight(h); + + mAntiScaleRatio = 1 / (UBApplication::boardController->systemScaleFactor() * UBApplication::boardController->currentZoom()); + qreal range = sItemWidth * mAntiScaleRatio; + QPolygonF polygon; + polygon << QPointF(-range, -range) + << QPointF(-range, mBounds.top()) + << QPointF(range, mBounds.top()) + << QPointF(range, -range) + << QPointF(mBounds.right(), -range) + << QPointF(mBounds.right(), range) + << QPointF(range, range) + << QPointF(range, mBounds.bottom()) + << QPointF(-range, mBounds.bottom()) + << QPointF(-range, range) + << QPointF(mBounds.left(), range) + << QPointF(mBounds.left(), -range); + setPolygon(polygon); +} + +QRectF UBGraphicsAxes::bounds() const +{ + return mBounds; +} + +void UBGraphicsAxes::setShowNumbers(bool showNumbers) +{ + mShowNumbers = showNumbers; +} + +bool UBGraphicsAxes::showNumbes() const +{ + return mShowNumbers; +} + +void UBGraphicsAxes::paint(QPainter *painter, const QStyleOptionGraphicsItem *styleOption, QWidget *widget) +{ + Q_UNUSED(styleOption); + Q_UNUSED(widget); + + mAntiScaleRatio = 1 / (UBApplication::boardController->systemScaleFactor() * UBApplication::boardController->currentZoom()); + QTransform antiScaleTransform; + antiScaleTransform.scale(mAntiScaleRatio, mAntiScaleRatio); + + mCloseSvgItem->setTransform(antiScaleTransform); + mCloseSvgItem->setPos(closeButtonRect().topLeft()); + + mNumbersSvgItem->setTransform(antiScaleTransform); + mNumbersSvgItem->setPos(numbersButtonRect().topLeft()); + + QTransform antiScaleTransform2; + qreal ratio = mAntiScaleRatio > 1.0 ? mAntiScaleRatio : 1.0; + antiScaleTransform2.scale(ratio, 1.0); + + QPen pen(drawColor()); + pen.setWidthF(2); + painter->setPen(pen); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->drawLine(xAxis()); + painter->drawLine(yAxis()); + + // draw arrows at end + QPointF tip = xAxis().p1(); + painter->drawLine(tip.x(), tip.y(), tip.x() + sArrowLength, tip.y() + sArrowWidth); + painter->drawLine(tip.x(), tip.y(), tip.x() + sArrowLength, tip.y() - sArrowWidth); + + tip = xAxis().p2(); + painter->drawLine(tip.x(), tip.y(), tip.x() - sArrowLength, tip.y() + sArrowWidth); + painter->drawLine(tip.x(), tip.y(), tip.x() - sArrowLength, tip.y() - sArrowWidth); + + tip = yAxis().p1(); + painter->drawLine(tip.x(), tip.y(), tip.x() + sArrowWidth, tip.y() - sArrowLength); + painter->drawLine(tip.x(), tip.y(), tip.x() - sArrowWidth, tip.y() - sArrowLength); + + tip = yAxis().p2(); + painter->drawLine(tip.x(), tip.y(), tip.x() + sArrowWidth, tip.y() + sArrowLength); + painter->drawLine(tip.x(), tip.y(), tip.x() - sArrowWidth, tip.y() + sArrowLength); + + pen.setWidthF(1); + painter->setPen(pen); + paintGraduations(painter); +} + + +QVariant UBGraphicsAxes::itemChange(GraphicsItemChange change, const QVariant &value) +{ + if (change == QGraphicsItem::ItemVisibleHasChanged) + { + mCloseSvgItem->setParentItem(this); + mNumbersSvgItem->setParentItem(this); + } + + return QGraphicsPolygonItem::itemChange(change, value); +} + +void UBGraphicsAxes::paintGraduations(QPainter *painter) +{ + painter->save(); + painter->setFont(font()); + QFontMetricsF fontMetrics(painter->font()); + + // Update the width of one "centimeter" to correspond to the width of the background grid (whether it is displayed or not) + sPixelsPerCentimeter = UBApplication::boardController->activeScene()->backgroundGridSize(); + + // When a "centimeter" is too narrow, we only display every 5th number + double numbersWidth = fontMetrics.boundingRect("-00").width(); + bool shouldDisplayAllNumbers = (numbersWidth <= (sPixelsPerCentimeter - 5)); + + // draw numbers on x axis + int fromX = (xAxis().x1() + sMargin) / sPixelsPerCentimeter; + int toX = (xAxis().x2() - sMargin) / sPixelsPerCentimeter; + + for (int centimeters(fromX); centimeters <= toX; centimeters++) + { + bool isImportant = abs(centimeters) == 1 || abs(centimeters) % 5 == 0; + double graduationX = sPixelsPerCentimeter * centimeters; + double graduationHeight = UBGeometryUtils::millimeterGraduationHeight; + + painter->drawLine(QLineF(graduationX, graduationHeight, graduationX, -graduationHeight)); + + if (mShowNumbers && (shouldDisplayAllNumbers || isImportant) && centimeters != 0) + { + QString text = QString("%1").arg(centimeters); + + if (graduationX + fontMetrics.width(text) / 2 < xAxis().x2()) + { + qreal textWidth = fontMetrics.width(text); + qreal textHeight = fontMetrics.tightBoundingRect(text).height(); + painter->drawText( + QRectF(graduationX - textWidth / 2, textHeight - 5, textWidth, textHeight), + Qt::AlignVCenter, text); + } + } + } + + // draw numbers on y axis + int fromY = (-yAxis().y1() + sMargin) / sPixelsPerCentimeter; + int toY = (-yAxis().y2() - sMargin) / sPixelsPerCentimeter; + + for (int centimeters(fromY); centimeters <= toY; centimeters++) + { + bool isImportant = abs(centimeters) == 1 || abs(centimeters) % 5 == 0; + double graduationY = - sPixelsPerCentimeter * centimeters; + double graduationHeight = UBGeometryUtils::millimeterGraduationHeight; + + painter->drawLine(QLineF(graduationHeight, graduationY, - graduationHeight, graduationY)); + + if (mShowNumbers && (shouldDisplayAllNumbers || isImportant) && centimeters != 0) + { + QString text = QString("%1").arg(centimeters); + + qreal textWidth = fontMetrics.width(text); + qreal textHeight = fontMetrics.tightBoundingRect(text).height(); + painter->drawText( + QRectF(- textWidth - 10, graduationY - textHeight / 2, textWidth, textHeight), + Qt::AlignVCenter, text); + } + } + + painter->restore(); +} + +void UBGraphicsAxes::setRect(const QRectF &rect) +{ + setRect(rect.x(), rect.y(), rect.width(), rect.height()); +} + +void UBGraphicsAxes::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (resizeLeftRect().contains(event->pos())) + { + mResizeDirection = Left; + mResizing = true; + event->accept(); + } + else if (resizeRightRect().contains(event->pos())) + { + mResizeDirection = Right; + mResizing = true; + event->accept(); + } + else if (resizeTopRect().contains(event->pos())) + { + mResizeDirection = Top; + mResizing = true; + event->accept(); + } + else if (resizeBottomRect().contains(event->pos())) + { + mResizeDirection = Bottom; + mResizing = true; + event->accept(); + } + else + { + mResizing = false; + QGraphicsItem::mousePressEvent(event); + } + mCloseSvgItem->setVisible(false); + mNumbersSvgItem->setVisible(false); +} + +void UBGraphicsAxes::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if (!mResizing) + { + QGraphicsItem::mouseMoveEvent(event); + } + else + { + QPointF delta = event->pos() - event->lastPos(); + prepareGeometryChange(); + + switch (mResizeDirection) + { + case Left: + delta.setY(0); + if (delta.x() > -mBounds.left() - sMinLength) + delta.setX(-mBounds.left() - sMinLength); + setRect(mBounds.x() + delta.x(), mBounds.y(), mBounds.width() - delta.x(), mBounds.height()); + break; + + case Right: + if (-delta.x() > mBounds.right() - sMinLength) + delta.setX(sMinLength - mBounds.right()); + setRect(mBounds.x(), mBounds.y(), mBounds.width() + delta.x(), mBounds.height()); + break; + + case Top: + delta.setX(0); + if (delta.y() > -mBounds.top() - sMinLength) + delta.setY(-mBounds.top() - sMinLength); + setRect(mBounds.x(), mBounds.y() + delta.y(), mBounds.width(), mBounds.height() - delta.y()); + break; + + case Bottom: + if (-delta.y() > mBounds.bottom() - sMinLength) + delta.setY(sMinLength - mBounds.bottom()); + setRect(mBounds.x(), mBounds.y(), mBounds.width(), mBounds.height() + delta.y()); + break; + } + + event->accept(); + } +} + +void UBGraphicsAxes::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if (mResizing) + { + mResizing = false; + event->accept(); + } + else if (closeButtonRect().contains(event->pos())) + { + hide(); + event->accept(); + } + else if (numbersButtonRect().contains(event->pos())) + { + mShowNumbers = !mShowNumbers; + update(boundingRect()); + event->accept(); + } + else + { + // snap to grid + if (true) { + QPointF delta = pos(); + qreal gridSize = scene()->backgroundGridSize(); + qreal deltaX = delta.x() - round(delta.x() / gridSize) * gridSize; + qreal deltaY = delta.y() - round(delta.y() / gridSize) * gridSize; + setPos(pos() - QPointF(deltaX, deltaY)); + } + + QGraphicsItem::mouseReleaseEvent(event); + } + + if (scene()) + scene()->setModified(true); +} + +void UBGraphicsAxes::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); + + if (currentTool == UBStylusTool::Selector || + currentTool == UBStylusTool::Play) + { + mCloseSvgItem->setParentItem(this); + mNumbersSvgItem->setParentItem(this); + + mShowButtons = true; + mCloseSvgItem->setVisible(mShowButtons); + mNumbersSvgItem->setVisible(mShowButtons); + selectCursor(event); + event->accept(); + update(); + } +} + +void UBGraphicsAxes::hoverMoveEvent(QGraphicsSceneHoverEvent *event) +{ + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); + + if (currentTool == UBStylusTool::Selector || currentTool == UBStylusTool::Play) + { + mCloseSvgItem->setVisible(mShowButtons); + mNumbersSvgItem->setVisible(mShowButtons); + selectCursor(event); + event->accept(); + } +} + +void UBGraphicsAxes::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + mShowButtons = false; + setCursor(Qt::ArrowCursor); + mCloseSvgItem->setVisible(mShowButtons); + mNumbersSvgItem->setVisible(mShowButtons); + UBDrawingController::drawingController()->mActiveRuler = NULL; + event->accept(); + update(); +} + +void UBGraphicsAxes::updateResizeCursor() +{ + QPixmap pix(":/images/cursors/resize.png"); + QTransform tr; + tr.rotate(-90); + mResizeCursorH = QCursor(pix, pix.width() / 2, pix.height() / 2); + mResizeCursorV = QCursor(pix.transformed(tr, Qt::SmoothTransformation), pix.width() / 2, pix.height() / 2); +} + +QCursor UBGraphicsAxes::resizeCursor() const +{ + switch (mResizeDirection) + { + case Left: + case Right: + return mResizeCursorH; + + default: + break; + } + + return mResizeCursorV; +} + +QCursor UBGraphicsAxes::closeCursor() const +{ + return Qt::ArrowCursor; +} + +QCursor UBGraphicsAxes::moveCursor() const +{ + return Qt::SizeAllCursor; +} + +void UBGraphicsAxes::selectCursor(QGraphicsSceneHoverEvent *event) +{ + if (resizeLeftRect().contains(event->pos())) + { + mResizeDirection = Left; + setCursor(resizeCursor()); + } + else if (resizeRightRect().contains(event->pos())) + { + mResizeDirection = Right; + setCursor(resizeCursor()); + } + else if (resizeTopRect().contains(event->pos())) + { + mResizeDirection = Top; + setCursor(resizeCursor()); + } + else if (resizeBottomRect().contains(event->pos())) + { + mResizeDirection = Bottom; + setCursor(resizeCursor()); + } else if (closeButtonRect().contains(event->pos())) + setCursor(closeCursor()); + else if (numbersButtonRect().contains(event->pos())) { + setCursor(closeCursor()); + } else { + setCursor(moveCursor()); + } +} + +QRectF UBGraphicsAxes::resizeLeftRect() const +{ + qreal range = sItemWidth * mAntiScaleRatio; + return QRectF(xAxis().x1(), xAxis().y1() - range, sArrowLength, 2 * range); +} + +QRectF UBGraphicsAxes::resizeRightRect() const +{ + qreal range = sItemWidth * mAntiScaleRatio; + return QRectF(xAxis().x2() - sArrowLength, xAxis().y2() - range, sArrowLength, 2 * range); +} + +QRectF UBGraphicsAxes::resizeBottomRect() const +{ + qreal range = sItemWidth * mAntiScaleRatio; + return QRectF(yAxis().x1() - range, yAxis().y1() - sArrowLength, 2 * range, sArrowLength); +} + +QRectF UBGraphicsAxes::resizeTopRect() const +{ + qreal range = sItemWidth * mAntiScaleRatio; + return QRectF(yAxis().x2() - range, yAxis().y2(), 2 * range, sArrowLength); +} + +QRectF UBGraphicsAxes::closeButtonRect() const +{ + QPixmap closePixmap(":/images/closeTool.svg"); + + QSizeF closeRectSize( + closePixmap.width() * mAntiScaleRatio, + closePixmap.height() * mAntiScaleRatio); + + QPointF closeRectTopLeft( + -sItemWidth * mAntiScaleRatio, + -sItemWidth * mAntiScaleRatio); + + return QRectF(closeRectTopLeft, closeRectSize); +} + +QRectF UBGraphicsAxes::numbersButtonRect() const +{ + QPixmap numbersPixmap(":/images/numbersTool.svg"); + + QSizeF numbersRectSize( + numbersPixmap.width() * mAntiScaleRatio, + numbersPixmap.height() * mAntiScaleRatio); + + QPointF numbersRectTopLeft( + sItemWidth * mAntiScaleRatio - numbersRectSize.width(), + sItemWidth * mAntiScaleRatio - numbersRectSize.height()); + + return QRectF(numbersRectTopLeft, numbersRectSize); +} + +QLineF UBGraphicsAxes::xAxis() const +{ + return QLineF(mBounds.left(), 0, mBounds.right(), 0); +} + +QLineF UBGraphicsAxes::yAxis() const +{ + return QLineF(0, mBounds.bottom(), 0, mBounds.top()); +} + +UBGraphicsScene* UBGraphicsAxes::scene() const +{ + return static_cast(QGraphicsPolygonItem::scene()); +} + +QColor UBGraphicsAxes::drawColor() const +{ + return scene()->isDarkBackground() ? sDarkBackgroundDrawColor : sLightBackgroundDrawColor; +} + +QFont UBGraphicsAxes::font() const +{ + QFont font("Arial"); + font.setPixelSize(16); + font.setBold(true); + return font; +} diff --git a/src/tools/UBGraphicsAxes.h b/src/tools/UBGraphicsAxes.h new file mode 100644 index 00000000..c478800f --- /dev/null +++ b/src/tools/UBGraphicsAxes.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2015-2018 Département de l'Instruction Publique (DIP-SEM) + * + * Copyright (C) 2013 Open Education Foundation + * + * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour + * l'Education Numérique en Afrique (GIP ENA) + * + * This file is part of OpenBoard. + * + * OpenBoard 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, version 3 of the License, + * with a specific linking exception for the OpenSSL project's + * "OpenSSL" library (or with modified versions of it that use the + * same license as the "OpenSSL" library). + * + * OpenBoard 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 OpenBoard. If not, see . + */ + + + + +#ifndef UBGRAPHICSAXES_H +#define UBGRAPHICSAXES_H + + +#include +#include + +#include "core/UB.h" +#include "domain/UBItem.h" + +class UBGraphicsScene; + +class UBGraphicsAxes : public QObject, public QGraphicsPolygonItem, public UBItem +{ + Q_OBJECT + + public: + UBGraphicsAxes(); + virtual ~UBGraphicsAxes(); + + enum { Type = UBGraphicsItemType::AxesItemType }; + + virtual int type() const + { + return Type; + } + + virtual UBItem* deepCopy() const; + virtual void copyItemParameters(UBItem *copy) const; + + void setRect(qreal x, qreal y, qreal w, qreal h); + QRectF bounds() const; + void setShowNumbers(bool showNumbers); + bool showNumbes() const; + + enum UBGraphicsAxesDirection + { + Left = 0, + Right, + Bottom, + Top + }; + + protected: + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *styleOption, QWidget *widget); + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + void paintGraduations(QPainter *painter); + void setRect(const QRectF &rect); + + // Events + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + + private: + // Helpers + void updateResizeCursor(); + QCursor resizeCursor() const; + QCursor closeCursor() const; + QCursor moveCursor() const; + void selectCursor(QGraphicsSceneHoverEvent *event); + + virtual QRectF resizeLeftRect() const; + virtual QRectF resizeRightRect() const; + virtual QRectF resizeBottomRect() const; + virtual QRectF resizeTopRect() const; + virtual QRectF closeButtonRect() const; + virtual QRectF numbersButtonRect() const; + virtual QLineF xAxis() const; + virtual QLineF yAxis() const; + virtual UBGraphicsScene* scene() const; + + QColor drawColor() const; + QFont font() const; + + QGraphicsSvgItem* mCloseSvgItem; + QGraphicsSvgItem* mNumbersSvgItem; + + bool mResizing; + UBGraphicsAxesDirection mResizeDirection; + bool mShowButtons; + bool mShowNumbers; + + + QCursor mResizeCursorH; + QCursor mResizeCursorV; + + int drawLineDirection; + + // Constants + static const QRect sDefaultRect; + + static const int sMinLength = 50; // 1sm + static const int sMaxLength = 35000; // 700sm + static const int sArrowLength = 12; + static const int sArrowWidth = 5; + static const int sMargin = 5; + static const int sItemWidth = 30; + static const int sDrawTransparency = 255; + static const QColor sLightBackgroundDrawColor; + static const QColor sDarkBackgroundDrawColor; + + qreal mStrokeWidth; + qreal mAntiScaleRatio; + qreal sPixelsPerCentimeter; + QRectF mBounds; +}; + +#endif // UBGRAPHICSAXES_H diff --git a/src/tools/UBToolsManager.cpp b/src/tools/UBToolsManager.cpp index 210f74f0..d041a0b4 100644 --- a/src/tools/UBToolsManager.cpp +++ b/src/tools/UBToolsManager.cpp @@ -68,6 +68,14 @@ UBToolsManager::UBToolsManager(QObject *parent) mDescriptors << ruler; + axes.id = "openboardtool://axes"; + axes.icon = QPixmap(":/images/toolPalette/axesTool.png"); + axes.label = tr("Axes"); + axes.version = "1.0"; + mToolsIcon.insert(axes.id, ":/images/toolPalette/axesTool.png"); + mDescriptors << axes; + + compass.id = "openboardtool://compass"; compass.icon = QPixmap(":/images/toolPalette/compassTool.png"); compass.label = tr("Compass"); diff --git a/src/tools/UBToolsManager.h b/src/tools/UBToolsManager.h index beec45cf..5783080b 100644 --- a/src/tools/UBToolsManager.h +++ b/src/tools/UBToolsManager.h @@ -84,6 +84,7 @@ class UBToolsManager : public QObject } UBToolDescriptor ruler; + UBToolDescriptor axes; UBToolDescriptor protractor; UBToolDescriptor compass; UBToolDescriptor mask; diff --git a/src/tools/tools.pri b/src/tools/tools.pri index 1f2d00af..e43955af 100644 --- a/src/tools/tools.pri +++ b/src/tools/tools.pri @@ -1,4 +1,5 @@ HEADERS += src/tools/UBGraphicsRuler.h \ + src/tools/UBGraphicsAxes.h \ src/tools/UBGraphicsTriangle.h \ src/tools/UBGraphicsProtractor.h \ src/tools/UBGraphicsCompass.h \ @@ -9,6 +10,7 @@ HEADERS += src/tools/UBGraphicsRuler.h \ src/tools/UBGraphicsCache.h SOURCES += src/tools/UBGraphicsRuler.cpp \ + src/tools/UBGraphicsAxes.cpp \ src/tools/UBGraphicsTriangle.cpp \ src/tools/UBGraphicsProtractor.cpp \ src/tools/UBGraphicsCompass.cpp \