Merge branch 'feature/manual-layout' into 'feature/manual-layout'

Feature/manual layout

See merge request smart-pattern/valentina!11
This commit is contained in:
Roman Telezhynskyi 2020-11-22 12:10:25 +00:00
commit e81d1167a3
38 changed files with 2989 additions and 201 deletions

View file

@ -12,6 +12,7 @@ SOURCES += \
$$PWD/vpcommands.cpp \
$$PWD/vpgraphicspiece.cpp \
$$PWD/vpgraphicssheet.cpp \
$$PWD/vpgraphicstilegrid.cpp \
$$PWD/vplayout.cpp \
$$PWD/vpmaingraphicsview.cpp \
$$PWD/vpmainwindow.cpp \
@ -20,6 +21,7 @@ SOURCES += \
$$PWD/vppiecelist.cpp \
$$PWD/vpsettings.cpp \
$$PWD/vpsheet.cpp \
$$PWD/vptilefactory.cpp \
$$PWD/xml/vplayoutfilereader.cpp \
$$PWD/xml/vplayoutfilewriter.cpp \
$$PWD/xml/vplayoutliterals.cpp
@ -36,6 +38,7 @@ HEADERS += \
$$PWD/vpcommands.h \
$$PWD/vpgraphicspiece.h \
$$PWD/vpgraphicssheet.h \
$$PWD/vpgraphicstilegrid.h \
$$PWD/vplayout.h \
$$PWD/vpmaingraphicsview.h \
$$PWD/vpmainwindow.h \
@ -45,6 +48,7 @@ HEADERS += \
$$PWD/vpsettings.h \
$$PWD/vpsheet.h \
$$PWD/vpstable.h \
$$PWD/vptilefactory.h \
$$PWD/xml/vplayoutfilereader.h \
$$PWD/xml/vplayoutfilewriter.h \
$$PWD/xml/vplayoutliterals.h

View file

@ -7,7 +7,7 @@
# File with common stuff for whole project
include(../../../common.pri)
QT += core gui widgets network xml xmlpatterns printsupport concurrent
QT += core gui widgets network xml svg xmlpatterns printsupport concurrent
# Name of binary file
TARGET = puzzle

View file

@ -9,6 +9,12 @@
<file>puzzleicon/64x64/iconPortrait.png</file>
<file>puzzleicon/64x64/iconGrainlineVertical.png</file>
<file>puzzleicon/64x64/iconGrainlineHorizontal.png</file>
<file alias="cursor_rotate">puzzleicon/64x64/cursorRotate.png</file>
<file>puzzleicon/64x64/iconProperties.png</file>
<file>puzzleicon/svg/icon_scissors.svg</file>
<file>puzzleicon/svg/icon_scissors_vertical.svg</file>
<file>puzzleicon/svg/icon_scissors_horizontal.svg</file>
<file>puzzleicon/16x16/roll.png</file>
<file>puzzleicon/16x16/template.png</file>
<file>puzzleicon/svg/cursor_rotate.svg</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View file

@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
@ -9,39 +7,18 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg893"
width="128"
height="128"
viewBox="0 0 33.866666 33.866668"
version="1.1"
id="svg8"
sodipodi:docname="icon_rotate.svg"
inkscape:export-filename="/home/ronan/Desktop/iconRotate.png"
inkscape:export-xdpi="48"
inkscape:export-ydpi="48"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4142136"
inkscape:cx="-73.50406"
inkscape:cy="-5.7476577"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="1487"
inkscape:window-height="906"
inkscape:window-x="648"
inkscape:window-y="365"
inkscape:window-maximized="0" />
viewBox="0 0 128 128"
sodipodi:docname="cursor_rotate.svg"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
inkscape:export-filename="/home/ronan/Workspace_cpp/valentina/src/app/puzzle/share/resources/puzzleicon/64x64/cursorRotate@2x.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<metadata
id="metadata5">
id="metadata899">
<rdf:RDF>
<cc:Work
rdf:about="">
@ -52,16 +29,38 @@
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs897" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1943"
inkscape:window-height="957"
id="namedview895"
showgrid="false"
inkscape:zoom="3.8141593"
inkscape:cx="-9.2984942"
inkscape:cy="78.770819"
inkscape:window-x="-163"
inkscape:window-y="86"
inkscape:window-maximized="0"
inkscape:current-layer="g901"
showguides="false"
inkscape:lockguides="false" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-263.13332)">
inkscape:label="Image"
id="g901">
<path
style="fill:#000000;fill-opacity:0.99622641;stroke:#000000;stroke-width:0.56587124;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 7.0186194,287.41283 -6.32117702,-9.61886 4.59283552,0.0718 c 0.2260142,-13.99266 14.6277861,-19.32352 24.6168741,-9.04316 8.326613,8.56942 1.645094,23.6663 -11.704329,23.56294 l -0.02016,4.07882 -9.3161816,-5.90315 9.3649386,-5.23047 -0.0097,3.75053 c 12.855101,-0.23223 15.657569,-13.03558 9.321879,-19.01152 -6.380838,-6.01853 -18.7084318,-6.45152 -19.0255146,7.87916 l 4.6551916,0.099 z"
id="path873"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccscccccsccc" />
id="path1502"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:16.112;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
d="M 67.494019,3 C 45.635979,3 26.4721,14.832798 15.842825,32.458789 L 0,20.886257 10.290418,67.03627 50.234036,44.059307 30.104959,39.845618 c 7.88695,-12.507886 21.673605,-20.733626 37.38906,-20.733626 24.548563,0 44.393991,20.068893 44.393991,45.180711 0,25.111817 -19.845428,45.178617 -44.393991,45.178617 -18.793455,0 -34.829896,-11.76047 -41.31635,-28.542147 -12.799702,5.691961 -3.295568,1.770075 -14.669238,6.556583 C 20.55829,109.77568 42.229103,125.58331 67.494019,125.58331 100.88055,125.58331 128,97.98361 128,64.292703 128,30.601797 100.88055,3 67.494019,3 Z"
sodipodi:nodetypes="scccccsssccsss" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View file

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128"
height="128"
viewBox="0 0 33.866666 33.866668"
version="1.1"
id="svg8"
sodipodi:docname="icon_properties.svg"
inkscape:export-filename="/home/ronan/Desktop/icon_properties@2x.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8"
inkscape:cx="-11.795691"
inkscape:cy="86.412865"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="1513"
inkscape:window-height="752"
inkscape:window-x="374"
inkscape:window-y="117"
inkscape:window-maximized="0"
inkscape:document-rotation="0"
inkscape:snap-global="false" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-263.13332)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.05013126;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect815"
width="25.9415"
height="32.816536"
x="3.9646497"
y="263.65839" />
<path
style="fill:none;stroke:#000000;stroke-width:1.17405;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 7.5406885,268.48285 18.5207075,0.002"
id="path860"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.17405;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 7.5406885,272.18701 18.5207075,0.002"
id="path860-3"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.17405;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 7.5406885,275.89118 18.5207075,0.002"
id="path860-3-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.17405;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 7.5406885,279.59535 18.5207075,0.002"
id="path860-3-6-7"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1.17217;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 7.5406884,283.29857 9.5248736,0.004"
id="path860-3-6-7-3"
sodipodi:nodetypes="cc" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Ebene 2">
<rect
style="fill:#ffb000;fill-opacity:1;stroke:#000000;stroke-width:0.0239823;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1541"
width="11.755722"
height="4.0580931"
x="-3.0312908"
y="33.013405"
transform="matrix(0.7043678,-0.70983519,0.65609625,0.75467723,0,0)" />
<rect
style="fill:#ff6ac5;fill-opacity:1;stroke:#000000;stroke-width:0.0246373;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1558"
width="4.095542"
height="2.2526591"
x="32.814873"
y="-5.8033538"
transform="matrix(0.769894,0.63817178,-0.72322028,0.69061743,0,0)" />
<path
sodipodi:type="star"
style="fill:#ecb05c;fill-opacity:0.585054;stroke:#000000;stroke-width:0.0256646;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1560"
sodipodi:sides="3"
sodipodi:cx="20.110312"
sodipodi:cy="29.040583"
sodipodi:r1="2.4221137"
sodipodi:r2="1.2110568"
sodipodi:arg1="0.14292279"
sodipodi:arg2="1.1901203"
inkscape:flatsided="true"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 22.507729,29.385581 -3.894903,1.558727 0.597554,-4.152449 z"
inkscape:transform-center-x="-0.30927552"
inkscape:transform-center-y="-0.31760931"
transform="rotate(7.0152373,14.907215,26.753104)" />
<path
d="m 32.521685,18.700663 -1.915051,-1.950856 c -0.255301,-0.259946 -0.59531,-0.403311 -0.95729,-0.403442 -2.56e-4,0 -3.42e-4,0 -5.98e-4,0 -0.361979,0 -0.701754,0.143149 -0.95682,0.402964 l -9.764404,9.946229 c -0.08,0.08341 -0.112911,0.202146 -0.136638,0.276461 l -1.255006,4.474487 c -0.045,0.160609 -0.001,0.333424 0.114791,0.451418 0.08588,0.08748 0.201256,0.13476 0.319213,0.13476 0.04147,0 0.08319,-0.006 0.124067,-0.01771 l 4.390169,-1.277678 c 0.01304,-0.0036 0.207012,-0.0718 0.273863,-0.139906 l 9.764295,-9.946361 c 0.255302,-0.259934 0.3957,-0.60627 0.395582,-0.975236 -8.4e-5,-0.368726 -0.140868,-0.715075 -0.396169,-0.975129 z m -13.894462,12.202626 0.842858,-3.004847 2.107026,2.146289 z m 3.81154,-1.281375 -2.553598,-2.601189 7.848656,-7.994895 2.553599,2.601177 z m 9.445081,-9.621087 -0.957994,0.975978 -2.553716,-2.601308 0.958113,-0.975847 c 0.0846,-0.08616 0.197733,-0.133564 0.318508,-0.133564 h 2.57e-4 c 0.121012,0 0.234388,0.04763 0.319214,0.134042 l 1.91517,1.950856 c 0.175995,0.179278 0.176231,0.470805 5.11e-4,0.649843 z m 0,0"
id="path953"
style="fill:#000000;fill-opacity:1;stroke-width:0.0304305;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

View file

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="100"
height="56"
id="svg2"
sodipodi:docname="Scissors_icon_black.svg"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
<metadata
id="metadata11">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1825"
inkscape:window-height="947"
id="namedview9"
showgrid="false"
inkscape:zoom="4"
inkscape:cx="88.508712"
inkscape:cy="66.691968"
inkscape:window-x="408"
inkscape:window-y="42"
inkscape:window-maximized="0"
inkscape:current-layer="g4593" />
<defs
id="defs4">
<marker
refX="0"
refY="0"
orient="auto"
id="Scissors"
style="overflow:visible">
<path
d="M 9.0898857,-3.6061018 C 8.1198849,-4.7769976 6.3697607,-4.7358294 5.0623558,-4.2327734 l -8.2124046,3.0779029 c -2.3882933,-1.3067135 -4.7482873,-0.9325372 -4.7482873,-1.5687873 0,-0.4973164 0.4566662,-0.3883222 0.3883068,-1.6831941 -0.065635,-1.2432767 -1.3635771,-2.1630796 -2.5903987,-2.0816435 -1.227271,-0.00735 -2.499439,0.9331613 -2.510341,2.2300611 -0.09143,1.3063864 1.007209,2.5196896 2.306764,2.6052316 1.5223406,0.2266616 4.218258,-0.6955566 5.482945,1.57086006 -0.9422847,1.73825774 -2.6140244,1.74307674 -4.1255107,1.65607034 -1.2548743,-0.072235 -2.7620933,0.2873979 -3.3606483,1.5208605 -0.578367,1.1820862 -0.0112,2.8646022 1.316749,3.226412 1.3401912,0.4918277 3.1806689,-0.129711 3.4993722,-1.6707242 0.2456585,-1.187823 -0.5953659,-1.7459574 -0.2725074,-2.1771537 0.2436135,-0.32536 1.7907806,-0.1368452 4.5471053,-1.3748244 L 5.6763468,4.2330688 C 6.8000164,4.5467672 8.1730685,4.5362646 9.1684433,3.4313614 l -9.22008423,-3.48508362 z m -18.3078016,-1.900504 c 1.294559,0.7227998 1.1888392,2.6835702 -0.1564272,3.0632889 -1.2165179,0.423661 -2.7710269,-0.7589694 -2.3831779,-2.0774648 0.227148,-1.0818519 1.653387,-1.480632 2.5396051,-0.9858241 z m 0.056264,8.0173649 c 1.3508301,0.4988648 1.1214429,2.7844356 -0.2522207,3.091609 -0.9110594,0.3163391 -2.2135494,-0.1387976 -2.3056964,-1.2121394 -0.177609,-1.305055 1.356085,-2.4841482 2.5579171,-1.8794696 z"
id="schere"
style="marker-start:none" />
</marker>
</defs>
<g
transform="matrix(0.88916115,0.40113698,-0.40113698,0.88916115,416.60041,-888.00877)"
id="layer1">
<g
transform="matrix(4.2610846,-1.2351263,1.2351263,4.2610846,-1337.7659,-2994.9736)"
id="g4593">
<path
d="m 59.731665,956.40057 c -0.609784,-1.39286 -2.303491,-1.83556 -3.698902,-1.71226 l -8.742604,0.69566 c -1.935736,-1.91425 -4.307466,-2.2049 -4.132136,-2.81651 0.137044,-0.47806 0.545993,-0.24745 0.837105,-1.51102 0.279511,-1.21323 -0.714709,-2.45509 -1.916471,-2.71488 -1.177727,-0.34526 -2.659814,0.20827 -3.027677,1.45195 -0.447882,1.23061 0.273869,2.69969 1.499535,3.14003 1.400938,0.6374 4.246607,0.49379 4.837778,3.02096 -1.384807,1.41129 -2.993148,0.95525 -4.422137,0.4551 -1.186382,-0.41524 -2.734347,-0.48487 -3.649629,0.53589 -0.881717,0.97694 -0.800158,2.7506 0.376675,3.46434 1.15277,0.8421 3.093263,0.7518 3.824279,-0.64172 0.563472,-1.07414 -0.09119,-1.84242 0.337995,-2.16796 0.32384,-0.24563 1.759155,0.36194 4.749906,-0.0686 l 3.518754,2.50293 c 0.830495,-0.11244 2.357866,-0.33884 2.949854,-0.42081 l -3.108827,-2.3174 9.766502,-0.89574 z m -17.075242,-6.87194 c 1.045256,1.05155 0.403306,2.90727 -0.994512,2.90157 -1.286163,0.072 -2.454591,-1.49318 -1.718425,-2.65375 0.516476,-0.97737 1.997384,-0.96769 2.712937,-0.24782 z m -2.155235,7.72245 c 1.161058,0.85179 0.310724,2.98566 -1.0944,2.9024 -0.962958,0.053 -2.089598,-0.7434 -1.882399,-1.80058 0.188897,-1.30347 1.988129,-2.01427 2.976799,-1.10182 z"
id="path4599"
style="marker-start:none"
sodipodi:nodetypes="cccscccccccccccccccccccccccc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View file

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="10mm"
height="5.5999999mm"
id="svg2"
sodipodi:docname="icon_scissors_horizontal.svg"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
<metadata
id="metadata11">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1510"
inkscape:window-height="773"
id="namedview9"
showgrid="false"
inkscape:zoom="4"
inkscape:cx="-13.069473"
inkscape:cy="57.804097"
inkscape:window-x="285"
inkscape:window-y="105"
inkscape:window-maximized="0"
inkscape:current-layer="g4593"
inkscape:document-rotation="0"
units="mm" />
<defs
id="defs4">
<marker
refX="0"
refY="0"
orient="auto"
id="Scissors"
style="overflow:visible">
<path
d="M 9.0898857,-3.6061018 C 8.1198849,-4.7769976 6.3697607,-4.7358294 5.0623558,-4.2327734 l -8.2124046,3.0779029 c -2.3882933,-1.3067135 -4.7482873,-0.9325372 -4.7482873,-1.5687873 0,-0.4973164 0.4566662,-0.3883222 0.3883068,-1.6831941 -0.065635,-1.2432767 -1.3635771,-2.1630796 -2.5903987,-2.0816435 -1.227271,-0.00735 -2.499439,0.9331613 -2.510341,2.2300611 -0.09143,1.3063864 1.007209,2.5196896 2.306764,2.6052316 1.5223406,0.2266616 4.218258,-0.6955566 5.482945,1.57086006 -0.9422847,1.73825774 -2.6140244,1.74307674 -4.1255107,1.65607034 -1.2548743,-0.072235 -2.7620933,0.2873979 -3.3606483,1.5208605 -0.578367,1.1820862 -0.0112,2.8646022 1.316749,3.226412 1.3401912,0.4918277 3.1806689,-0.129711 3.4993722,-1.6707242 0.2456585,-1.187823 -0.5953659,-1.7459574 -0.2725074,-2.1771537 0.2436135,-0.32536 1.7907806,-0.1368452 4.5471053,-1.3748244 L 5.6763468,4.2330688 C 6.8000164,4.5467672 8.1730685,4.5362646 9.1684433,3.4313614 l -9.22008423,-3.48508362 z m -18.3078016,-1.900504 c 1.294559,0.7227998 1.1888392,2.6835702 -0.1564272,3.0632889 -1.2165179,0.423661 -2.7710269,-0.7589694 -2.3831779,-2.0774648 0.227148,-1.0818519 1.653387,-1.480632 2.5396051,-0.9858241 z m 0.056264,8.0173649 c 1.3508301,0.4988648 1.1214429,2.7844356 -0.2522207,3.091609 -0.9110594,0.3163391 -2.2135494,-0.1387976 -2.3056964,-1.2121394 -0.177609,-1.305055 1.356085,-2.4841482 2.5579171,-1.8794696 z"
id="schere"
style="marker-start:none" />
</marker>
</defs>
<g
transform="matrix(0.88916115,0.40113698,-0.40113698,0.88916115,416.60041,-888.00877)"
id="layer1">
<g
transform="matrix(4.2610846,-1.2351263,1.2351263,4.2610846,-1337.7659,-2994.9736)"
id="g4593">
<path
d="m 35.464624,949.91014 c 0.230465,0.52643 0.870608,0.69376 1.398007,0.64716 l 3.304293,-0.26293 c 0.731614,0.72349 1.628019,0.83334 1.561751,1.06451 -0.0518,0.18068 -0.206363,0.0935 -0.316383,0.57109 -0.105643,0.45854 0.270125,0.92791 0.724333,1.02609 0.445128,0.1305 1.005282,-0.0787 1.144322,-0.54876 0.169277,-0.46512 -0.103509,-1.02036 -0.566757,-1.18679 -0.529488,-0.2409 -1.605018,-0.18663 -1.828451,-1.14178 0.523391,-0.5334 1.131267,-0.36105 1.671359,-0.172 0.448397,0.15694 1.033456,0.18325 1.379387,-0.20254 0.333251,-0.36924 0.302424,-1.0396 -0.142367,-1.30936 -0.435692,-0.31827 -1.169106,-0.28414 -1.445396,0.24254 -0.212966,0.40597 0.03447,0.69635 -0.127746,0.81938 -0.122393,0.0928 -0.664876,-0.13679 -1.795242,0.0259 l -1.329919,-0.94598 c -0.313891,0.0425 -0.891164,0.12806 -1.114904,0.15904 l 1.174988,0.87587 -3.691276,0.33854 z m 6.453633,2.59727 c -0.395055,-0.39744 -0.15243,-1.09881 0.375877,-1.09666 0.486113,-0.0272 0.927723,0.56435 0.649487,1.00299 -0.195206,0.3694 -0.754918,0.36575 -1.025364,0.0937 z m 0.814577,-2.91872 c -0.438826,-0.32194 -0.11744,-1.12844 0.413631,-1.09697 0.363954,-0.02 0.789772,0.28097 0.711461,0.68053 -0.0714,0.49265 -0.751419,0.7613 -1.125092,0.41644 z"
id="path4599"
style="fill:#b4b4b4;fill-opacity:1;stroke-width:0.377953;marker-start:none"
sodipodi:nodetypes="cccscccccccccccccccccccccccc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

View file

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="5.5999999mm"
height="10mm"
id="svg2"
sodipodi:docname="icon_scissors_vertical.svg"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
<metadata
id="metadata11">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1845"
inkscape:window-height="1016"
id="namedview9"
showgrid="false"
inkscape:zoom="4"
inkscape:cx="-13.069473"
inkscape:cy="50.393713"
inkscape:window-x="75"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g4593"
inkscape:document-rotation="0"
units="mm" />
<defs
id="defs4">
<marker
refX="0"
refY="0"
orient="auto"
id="Scissors"
style="overflow:visible">
<path
d="M 9.0898857,-3.6061018 C 8.1198849,-4.7769976 6.3697607,-4.7358294 5.0623558,-4.2327734 l -8.2124046,3.0779029 c -2.3882933,-1.3067135 -4.7482873,-0.9325372 -4.7482873,-1.5687873 0,-0.4973164 0.4566662,-0.3883222 0.3883068,-1.6831941 -0.065635,-1.2432767 -1.3635771,-2.1630796 -2.5903987,-2.0816435 -1.227271,-0.00735 -2.499439,0.9331613 -2.510341,2.2300611 -0.09143,1.3063864 1.007209,2.5196896 2.306764,2.6052316 1.5223406,0.2266616 4.218258,-0.6955566 5.482945,1.57086006 -0.9422847,1.73825774 -2.6140244,1.74307674 -4.1255107,1.65607034 -1.2548743,-0.072235 -2.7620933,0.2873979 -3.3606483,1.5208605 -0.578367,1.1820862 -0.0112,2.8646022 1.316749,3.226412 1.3401912,0.4918277 3.1806689,-0.129711 3.4993722,-1.6707242 0.2456585,-1.187823 -0.5953659,-1.7459574 -0.2725074,-2.1771537 0.2436135,-0.32536 1.7907806,-0.1368452 4.5471053,-1.3748244 L 5.6763468,4.2330688 C 6.8000164,4.5467672 8.1730685,4.5362646 9.1684433,3.4313614 l -9.22008423,-3.48508362 z m -18.3078016,-1.900504 c 1.294559,0.7227998 1.1888392,2.6835702 -0.1564272,3.0632889 -1.2165179,0.423661 -2.7710269,-0.7589694 -2.3831779,-2.0774648 0.227148,-1.0818519 1.653387,-1.480632 2.5396051,-0.9858241 z m 0.056264,8.0173649 c 1.3508301,0.4988648 1.1214429,2.7844356 -0.2522207,3.091609 -0.9110594,0.3163391 -2.2135494,-0.1387976 -2.3056964,-1.2121394 -0.177609,-1.305055 1.356085,-2.4841482 2.5579171,-1.8794696 z"
id="schere"
style="marker-start:none" />
</marker>
</defs>
<g
transform="matrix(0.88916115,0.40113698,-0.40113698,0.88916115,416.60041,-888.00877)"
id="layer1">
<g
transform="matrix(4.2610846,-1.2351263,1.2351263,4.2610846,-1337.7659,-2994.9736)"
id="g4593">
<path
d="m 36.184207,948.95114 c 0.569876,0.0741 0.909488,0.64195 1.012188,1.16134 l 0.671333,3.24604 c 0.899184,0.50018 1.255261,1.33013 1.458678,1.20188 0.158999,-0.10024 0.0321,-0.22428 0.459871,-0.46343 0.410725,-0.22962 0.966427,-6e-5 1.187683,0.40859 0.249732,0.3909 0.205467,0.9872 -0.206972,1.25211 -0.399242,0.29256 -1.008607,0.18588 -1.297908,-0.21237 -0.379329,-0.44103 -0.627899,-1.48884 -1.60743,-1.43634 -0.365808,0.65165 -0.03037,1.1871 0.302112,1.65281 0.276041,0.38663 0.464872,0.94101 0.191168,1.381 -0.261348,0.42319 -0.913595,0.58101 -1.296949,0.22937 -0.427389,-0.32934 -0.599659,-1.04305 -0.171218,-1.45557 0.330248,-0.31797 0.678218,-0.16158 0.751001,-0.35173 0.05492,-0.14347 -0.317221,-0.60012 -0.476999,-1.7309 l -1.280073,-1.01242 c -0.04695,-0.31326 -0.126182,-0.89144 -0.158987,-1.11492 l 1.169432,0.88327 -0.706915,-3.63873 z m 4.297937,5.47019 c -0.492034,-0.26819 -1.097611,0.16084 -0.947845,0.66748 0.109774,0.47433 0.80121,0.73295 1.144574,0.34318 0.300097,-0.29069 0.140107,-0.82706 -0.196729,-1.01066 z m -2.57461,1.59808 c -0.431781,-0.33133 -1.116275,0.20272 -0.937591,0.70381 0.08252,0.35505 0.490562,0.67973 0.8523,0.49284 0.453046,-0.20628 0.52087,-0.93429 0.08529,-1.19665 z"
id="path4599"
style="fill:#b4b4b4;fill-opacity:1;stroke-width:0.377954;marker-start:none"
sodipodi:nodetypes="cccscccccccccccccccccccccccc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

View file

@ -363,6 +363,7 @@ VPMainWindow *VPApplication::NewMainWindow(const VPCommandLinePtr &cmd)
{
puzzle->show();
}
puzzle->InitZoom();
return puzzle;
}

View file

@ -83,6 +83,15 @@ void VPCarrousel::Refresh()
RefreshOrientation();
}
//---------------------------------------------------------------------------------------------------------------------
void VPCarrousel::RefreshFocusedSheetName()
{
// FIXME : This implementation will need a refactoring when we have multiple sheets, now it's not very nice!!
ui->comboBoxPieceList->setItemText(1, tr("Pieces of ") + m_layout->GetFocusedSheet()->GetName());
}
//---------------------------------------------------------------------------------------------------------------------
void VPCarrousel::Clear()
{

View file

@ -65,6 +65,11 @@ public:
*/
void Refresh();
/**
* @brief RefreshFocusedSheetName refreshes the name of the focused sheet
*/
void RefreshFocusedSheetName();
/**
* @brief Clear Clears the carrousel (removes everything)
*/

View file

@ -74,7 +74,7 @@ void VPCarrouselPiece::RefreshSelection()
}
//---------------------------------------------------------------------------------------------------------------------
QIcon VPCarrouselPiece::CreatePieceIcon(const QSize &size) const
QIcon VPCarrouselPiece::CreatePieceIcon(const QSize &size, bool isDragIcon) const
{
QVector<QPointF> points = m_piece->GetMappedContourPoints(); // seamline
if(points.isEmpty())
@ -92,31 +92,66 @@ QIcon VPCarrouselPiece::CreatePieceIcon(const QSize &size) const
qreal dx = canvas.center().x() - boundingRect.center().x();
qreal dy = canvas.center().y() - boundingRect.center().y();
QPixmap pixmap(size);
pixmap.fill(QColor("white"));
QVector<QIcon::Mode> iconModes;
iconModes.append(QIcon::Normal);
QPainter painter;
painter.begin(&pixmap);
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
int spacing = 2;
painter.translate(spacing, spacing);
qreal scaleFactorX = canvasSize * 100 / (size.width() - spacing*2) / 100;
qreal scaleFactorY = canvasSize * 100 / (size.height() - spacing*2) / 100;
painter.scale(1./scaleFactorX, 1./scaleFactorY);
painter.setPen(QPen(Qt::black, 0.8*qMax(scaleFactorX, scaleFactorY)));
painter.translate(dx, dy);
painter.drawPolygon(shape);
painter.end();
if(not isDragIcon)
{
iconModes.append(QIcon::Selected);
}
QIcon icon;
icon.addPixmap(pixmap,QIcon::Normal);
icon.addPixmap(pixmap,QIcon::Selected);
for(auto iconMode : iconModes)
{
QPixmap pixmap(size);
if(not isDragIcon)
{
pixmap.fill(QColor(Qt::white));
}
else
{
pixmap.fill(QColor(Qt::transparent));
}
QPainter painter;
painter.begin(&pixmap);
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
int spacing = 2;
painter.translate(spacing, spacing);
qreal scaleFactorX = canvasSize * 100 / (size.width() - spacing*2) / 100;
qreal scaleFactorY = canvasSize * 100 / (size.height() - spacing*2) / 100;
painter.scale(1./scaleFactorX, 1./scaleFactorY);
painter.setPen(QPen(Qt::black, 0.8*qMax(scaleFactorX, scaleFactorY)));
if(not isDragIcon)
{
painter.translate(dx, dy);
}
else
{
painter.translate(-boundingRect.topLeft().x()+spacing, -boundingRect.topLeft().y()+spacing);
}
if(iconMode == QIcon::Selected)
{
painter.setBrush(QBrush(QColor(255,160,160,60)));
}
else
{
painter.setBrush(QBrush(Qt::white));
}
painter.drawPolygon(shape);
painter.end();
icon.addPixmap(pixmap,iconMode);
}
return icon;
}

View file

@ -56,7 +56,7 @@ public:
* @param size of the icon
* @return the created icon
*/
QIcon CreatePieceIcon(const QSize &size) const;
QIcon CreatePieceIcon(const QSize &size, bool isDragIcon = false) const;
private:

View file

@ -47,7 +47,7 @@ VPCarrouselPieceList::VPCarrouselPieceList(QWidget* parent) :
QListWidget(parent),
m_dragStart(QPoint())
{
setStyleSheet("QListWidget::item{border: 2px solid transparent; color: black;} QListWidget::item:selected {border: 2px solid red;}");
setStyleSheet("QListWidget::item{border: 2px solid transparent; color: black;} QListWidget::item:selected {border: 2px solid rgb(255,160,160);}");
setContextMenuPolicy(Qt::DefaultContextMenu);
setSelectionMode(QAbstractItemView::MultiSelection);
setViewMode(QListView::IconMode);
@ -163,7 +163,7 @@ void VPCarrouselPieceList::startDrag(Qt::DropActions supportedActions)
mimeData->SetPiecePtr(piece);
mimeData->setObjectName("piecePointer");
QPixmap pixmap = pieceItem->CreatePieceIcon(QSize(120,120)).pixmap(QSize(120,120));
QPixmap pixmap = pieceItem->CreatePieceIcon(QSize(120,120), true).pixmap(QSize(120,120));
drag->setPixmap(pixmap);
drag->setMimeData(mimeData);
@ -187,33 +187,42 @@ void VPCarrouselPieceList::dragMoveEvent(QDragMoveEvent* e)
void VPCarrouselPieceList::contextMenuEvent(QContextMenuEvent *event)
{
QListWidgetItem* _item = currentItem();
if(_item->type() == 1001)
if(_item != nullptr)
{
VPCarrouselPiece *pieceItem = static_cast<VPCarrouselPiece *> (_item);
QMenu contextMenu;
if(m_pieceList->GetSheet() == nullptr)
if(_item->type() == 1001)
{
VPPieceList* sheetPieces = pieceItem->GetPiece()->GetPieceList()->GetLayout()->GetFocusedSheet()->GetPieceList();
QAction *moveAction = contextMenu.addAction(tr("Move to Sheet"));
QVariant data = QVariant::fromValue(sheetPieces);
moveAction->setData(data);
VPCarrouselPiece *pieceItem = static_cast<VPCarrouselPiece *> (_item);
connect(moveAction, &QAction::triggered, this, &VPCarrouselPieceList::on_ActionPieceMovedToPieceList);
QMenu contextMenu;
if(m_pieceList->GetSheet() == nullptr)
{
VPPieceList* sheetPieces = pieceItem->GetPiece()->GetPieceList()->GetLayout()->GetFocusedSheet()->GetPieceList();
QAction *moveAction = contextMenu.addAction(tr("Move to Sheet"));
QVariant moveData = QVariant::fromValue(sheetPieces);
moveAction->setData(moveData);
VPPieceList* trashPieceList = pieceItem->GetPiece()->GetPieceList()->GetLayout()->GetTrashPieceList();
QAction *deleteAction = contextMenu.addAction(tr("Delete"));
QVariant deleteData = QVariant::fromValue(trashPieceList);
deleteAction->setData(deleteData);
connect(moveAction, &QAction::triggered, this, &VPCarrouselPieceList::on_ActionPieceMovedToPieceList);
connect(deleteAction, &QAction::triggered, this, &VPCarrouselPieceList::on_ActionPieceMovedToPieceList);
}
// remove from piece list action
if(m_pieceList->GetSheet() != nullptr)
{
VPPieceList* unplacedPieces = pieceItem->GetPiece()->GetPieceList()->GetLayout()->GetUnplacedPieceList();
QAction *removeAction = contextMenu.addAction(tr("Remove from Sheet"));
QVariant data = QVariant::fromValue(unplacedPieces);
removeAction->setData(data);
connect(removeAction, &QAction::triggered, this, &VPCarrouselPieceList::on_ActionPieceMovedToPieceList);
}
contextMenu.exec(event->globalPos());
}
// remove from piece list action
if(m_pieceList->GetSheet() != nullptr)
{
VPPieceList* unplacedPieces = pieceItem->GetPiece()->GetPieceList()->GetLayout()->GetUnplacedPieceList();
QAction *removeAction = contextMenu.addAction(tr("Remove from Sheet"));
QVariant data = QVariant::fromValue(unplacedPieces);
removeAction->setData(data);
connect(removeAction, &QAction::triggered, this, &VPCarrouselPieceList::on_ActionPieceMovedToPieceList);
}
contextMenu.exec(event->globalPos());
}
}
@ -235,8 +244,6 @@ void VPCarrouselPieceList::on_ActionPieceMovedToPieceList()
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPCarrouselPieceList::on_PieceAdded(VPPiece* piece)
{

View file

@ -108,7 +108,6 @@ private slots:
* @brief on_ActionPieceMovedToPieceList when a piece is moved to another piece list via a context menu
*/
void on_ActionPieceMovedToPieceList();
};
#endif // VPCARROUSELPIECELIST_H

View file

@ -31,19 +31,22 @@
#include <QPen>
#include <QBrush>
#include <QPainter>
#include <QCursor>
#include <QGraphicsSceneMouseEvent>
#include <QStyleOptionGraphicsItem>
#include <QGraphicsSceneContextMenuEvent>
#include <QMenu>
#include <QtMath>
#include <QGraphicsScene>
#include <QApplication>
#include "vppiece.h"
#include "vppiecelist.h"
#include "vplayout.h"
#include "vpsheet.h"
#include "vlayoutpiecepath.h"
#include "vplacelabelitem.h"
#include <QLoggingCategory>
Q_LOGGING_CATEGORY(pGraphicsPiece, "p.graphicsPiece")
@ -54,8 +57,17 @@ VPGraphicsPiece::VPGraphicsPiece(VPPiece *piece, QGraphicsItem *parent) :
m_cuttingLine(QPainterPath()),
m_seamLine(QPainterPath()),
m_grainline(QPainterPath()),
m_rotationStartPoint(QPointF())
m_passmarks(QPainterPath()),
m_internalPaths(QVector<QPainterPath>()),
m_internalPathsPenStyle(QVector<Qt::PenStyle>()),
m_placeLabels(QVector<QPainterPath>()),
m_rotationStartPoint(QPointF()),
m_rotateCursor(QCursor())
{
QPixmap cursor_pixmap = QIcon("://puzzleicon/svg/cursor_rotate.svg").pixmap(QSize(32,32));
m_rotateCursor= QCursor(cursor_pixmap, 16, 16);
Init();
}
@ -78,7 +90,7 @@ void VPGraphicsPiece::Init()
if(!seamLinePoints.isEmpty())
{
m_seamLine.moveTo(seamLinePoints.first());
for (int i = 1; i < seamLinePoints.size(); ++i)
for (int i = 0; i < seamLinePoints.size(); i++)
m_seamLine.lineTo(seamLinePoints.at(i));
}
@ -87,7 +99,7 @@ void VPGraphicsPiece::Init()
if(!cuttingLinepoints.isEmpty())
{
m_cuttingLine.moveTo(cuttingLinepoints.first());
for (int i = 1; i < cuttingLinepoints.size(); ++i)
for (int i = 0; i < cuttingLinepoints.size(); i++)
m_cuttingLine.lineTo(cuttingLinepoints.at(i));
}
@ -98,17 +110,49 @@ void VPGraphicsPiece::Init()
if(!grainLinepoints.isEmpty())
{
m_grainline.moveTo(grainLinepoints.first());
for (int i = 1; i < grainLinepoints.size(); ++i)
for (int i = 0; i < grainLinepoints.size(); i++)
m_grainline.lineTo(grainLinepoints.at(i));
}
}
// TODO : initialises the other elements labels, passmarks etc.
// initialises the internal paths
QVector<VLayoutPiecePath> internalPaths = m_piece->GetInternalPaths();
for (int i = 0; i < internalPaths.size(); i++)
{
VLayoutPiecePath piecePath = internalPaths.at(i);
QPainterPath path = m_piece->GetMatrix().map(piecePath.GetPainterPath());
m_internalPaths.append(path);
m_internalPathsPenStyle.append(piecePath.PenStyle());
}
// initialises the passmarks
QVector<VLayoutPassmark> passmarks = m_piece->GetPassmarks();
for(auto &passmark : passmarks)
{
for (auto &line : passmark.lines)
{
m_passmarks.moveTo(line.p1());
m_passmarks.lineTo(line.p2());
}
}
// initialises the place labels (buttons etc)
QVector<VLayoutPlaceLabel> placeLabels = m_piece->GetPlaceLabels();
for(auto &placeLabel : placeLabels)
{
QPainterPath path = VPlaceLabelItem::LabelShapePath(placeLabel.shape);
m_placeLabels.append(path);
}
// TODO : initialises the text labels
// Initialises the connectors
connect(m_piece, &VPPiece::SelectionChanged, this, &VPGraphicsPiece::on_PieceSelectionChanged);
connect(m_piece, &VPPiece::PositionChanged, this, &VPGraphicsPiece::on_PiecePositionChanged);
connect(m_piece, &VPPiece::RotationChanged, this, &VPGraphicsPiece::on_PieceRotationChanged);
connect(m_piece, &VPPiece::PropertiesChanged, this, &VPGraphicsPiece::on_PiecePropertiesChanged);
}
//---------------------------------------------------------------------------------------------------------------------
@ -148,9 +192,11 @@ void VPGraphicsPiece::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
QPen pen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
QBrush noBrush(Qt::NoBrush);
QBrush selectionBrush(QColor(255,160,160,60));
QBrush blackBrush(Qt::black);
painter->setPen(pen);
// selection
if(isSelected())
{
painter->setBrush(selectionBrush);
@ -168,7 +214,7 @@ void VPGraphicsPiece::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
}
// paint the seam line
if(!m_seamLine.isEmpty())
if(!m_seamLine.isEmpty() && m_piece->GetShowSeamLine())
{
painter->drawPath(m_seamLine);
}
@ -178,8 +224,54 @@ void VPGraphicsPiece::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
// paint the grainline
if(!m_grainline.isEmpty())
{
// here to fill the grainlines arrow. Not wanted for mvp
// later maybe if it's configurable
// painter->setBrush(blackBrush);
painter->drawPath(m_grainline);
}
// paint the internal paths
painter->setBrush(noBrush);
if(!m_internalPaths.isEmpty())
{
Qt::PenStyle penStyleTmp = pen.style();
for (int i = 0; i < m_internalPaths.size(); i++)
{
painter->setPen(m_internalPathsPenStyle.at(i));
painter->drawPath(m_internalPaths.at(i));
}
painter->setPen(penStyleTmp);
}
// paint the passmarks
if(!m_passmarks.isEmpty())
{
painter->drawPath(m_passmarks);
}
// paint the place labels (buttons etc)
if(!m_placeLabels.isEmpty())
{
for(auto &placeLabel : m_placeLabels)
{
painter->drawPath(placeLabel);
}
}
// TODO Detail & Piece Label
// QPointF position = m_piece->GetPatternTextPosition();
// QStringList texts = m_piece->GetPatternText();
// painter->drawText();
// when using m_piece->GetItem(), the results were quite bad
}
//---------------------------------------------------------------------------------------------------------------------
@ -189,11 +281,24 @@ void VPGraphicsPiece::mousePressEvent(QGraphicsSceneMouseEvent *event)
//perform the default behaviour
QGraphicsItem::mousePressEvent(event);
// change the cursor when clicking left button
// change the cursor when clicking the left button
if((event->button() == Qt::LeftButton))
{
if(event->modifiers() & Qt::AltModifier)
{
setCursor(m_rotateCursor);
}
else
{
setCursor(Qt::ClosedHandCursor);
}
}
// change the selected state when clicking left button
if (event->button() == Qt::LeftButton)
{
setSelected(true);
setCursor(Qt::ClosedHandCursor);
if (event->modifiers() & Qt::ControlModifier)
{
@ -208,12 +313,6 @@ void VPGraphicsPiece::mousePressEvent(QGraphicsSceneMouseEvent *event)
if((event->button() == Qt::LeftButton) && (event->modifiers() & Qt::AltModifier))
{
m_rotationStartPoint = event->scenePos();
QPixmap cursor_pixmap = QPixmap(":/cursor_rotate");
cursor_pixmap = cursor_pixmap.scaledToWidth(32);
QCursor cursor_rotate = QCursor(cursor_pixmap, 16, 16);
setCursor(cursor_rotate);
}
}
@ -222,6 +321,8 @@ void VPGraphicsPiece::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
{
if((event->buttons() == Qt::LeftButton) && (event->modifiers() & Qt::AltModifier))
{
//FIXME: it flickers between the arrow cursor and the rotate cursor
setCursor(m_rotateCursor);
QPointF rotationNewPoint = event->scenePos();
QPointF rotationCenter = sceneBoundingRect().center();
@ -278,20 +379,14 @@ void VPGraphicsPiece::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
if(event->modifiers() & Qt::AltModifier)
{
// TODO FIXME: find a more efficient way
QPixmap cursor_pixmap = QPixmap(":/cursor_rotate");
cursor_pixmap = cursor_pixmap.scaledToWidth(32);
QCursor cursor_rotate = QCursor(cursor_pixmap, 16, 16);
setCursor(cursor_rotate);
//FIXME: it flickers between the arrow cursor and the rotate cursor
setCursor(m_rotateCursor);
}
else
{
setCursor(QCursor(Qt::OpenHandCursor));
setCursor(Qt::OpenHandCursor);
}
}
@ -370,6 +465,15 @@ void VPGraphicsPiece::on_PieceRotationChanged()
setRotation(-m_piece->GetRotation());
}
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::on_PiecePropertiesChanged()
{
if(scene())
{
scene()->update();
}
}
//---------------------------------------------------------------------------------------------------------------------
QVariant VPGraphicsPiece::itemChange(GraphicsItemChange change, const QVariant &value)
{

View file

@ -30,6 +30,7 @@
#define VPGRAPHICSPIECE_H
#include <QGraphicsItem>
#include <QCursor>
class VPPiece;
@ -63,6 +64,11 @@ public slots:
*/
void on_PieceRotationChanged();
/**
* @brief on_PiecePropertiesChanged Slot called when the showSeamline / mirrored was changed
*/
void on_PiecePropertiesChanged();
protected:
QRectF boundingRect() const override;
QPainterPath shape() const override;
@ -92,9 +98,16 @@ private:
QPainterPath m_cuttingLine;
QPainterPath m_seamLine;
QPainterPath m_grainline;
QPainterPath m_passmarks;
QVector<QPainterPath> m_internalPaths;
QVector<Qt::PenStyle> m_internalPathsPenStyle;
QVector<QPainterPath> m_placeLabels;
QPointF m_rotationStartPoint;
QCursor m_rotateCursor;
};
#endif // VPGRAPHICSPIECE_H

View file

@ -27,6 +27,8 @@
*************************************************************************/
#include "vpgraphicssheet.h"
#include "vplayout.h"
#include <QtMath>
//---------------------------------------------------------------------------------------------------------------------
VPGraphicsSheet::VPGraphicsSheet(VPSheet *sheet, QGraphicsItem *parent):
@ -55,12 +57,18 @@ void VPGraphicsSheet::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
painter->setPen(pen);
painter->setBrush(noBrush);
painter->drawRect(GetMarginsRect());
if(m_showMargin)
{
painter->drawRect(GetMarginsRect());
}
pen.setColor(Qt::black);
if(m_showBorder)
{
pen.setColor(Qt::black);
painter->setPen(pen);
painter->drawRect(GetSheetRect());
painter->setPen(pen);
painter->drawRect(GetSheetRect());
}
m_boundingRect = GetSheetRect();
}
@ -96,6 +104,18 @@ QRectF VPGraphicsSheet::GetMarginsRect() const
return rect;
}
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsSheet::SetShowMargin(bool value)
{
m_showMargin = value;
}
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsSheet::SetShowBorder(bool value)
{
m_showBorder = value;
}
//---------------------------------------------------------------------------------------------------------------------
QRectF VPGraphicsSheet::boundingRect() const

View file

@ -47,12 +47,28 @@ public:
QRectF GetSheetRect() const;
QRectF GetMarginsRect() const;
/**
* @brief ShowMargin Sets Wether we see the margin
* @param value true to show the margin
*/
void SetShowMargin(bool value);
/**
* @brief ShowBorder Sets whether we see the border of the sheet
* @param value true to show the border
*/
void SetShowBorder(bool value);
private:
Q_DISABLE_COPY(VPGraphicsSheet)
VPSheet *m_sheet{nullptr};
QRectF m_boundingRect;
bool m_showMargin{true};
bool m_showBorder{true};
};
#endif // VPGRAPHICSSHEET_H

View file

@ -0,0 +1,78 @@
#include "vpgraphicstilegrid.h"
#include "vptilefactory.h"
#include "vplayout.h"
//---------------------------------------------------------------------------------------------------------------------
VPGraphicsTileGrid::VPGraphicsTileGrid(VPLayout *layout, VPTileFactory *tileFactory,QGraphicsItem *parent):
QGraphicsItem(parent),
m_tileFactory(tileFactory),
m_layout(layout)
{
}
//---------------------------------------------------------------------------------------------------------------------
VPGraphicsTileGrid::~VPGraphicsTileGrid()
{
}
//---------------------------------------------------------------------------------------------------------------------
QRectF VPGraphicsTileGrid::boundingRect() const
{
if(m_layout->GetShowTiles())
{
return QRectF(0,
0,
m_tileFactory->getColNb()* m_tileFactory->getDrawingAreaWidth(),
m_tileFactory->getRowNb()* m_tileFactory->getDrawingAreaHeight()
);
}
else
{
return QRectF(0,0,0,0);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsTileGrid::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(widget);
Q_UNUSED(option);
if(m_layout->GetShowTiles())
{
QPen pen(QColor(255,0,0,127), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
pen.setCosmetic(true);
pen.setStyle(Qt::DashLine);
QBrush noBrush(Qt::NoBrush);
painter->setPen(pen);
painter->setBrush(noBrush);
for(int i=0;i<=m_tileFactory->getColNb();i++)
{
painter->drawLine(QPointF(
i*m_tileFactory->getDrawingAreaWidth(),
0),
QPointF(
i*m_tileFactory->getDrawingAreaWidth(),
m_tileFactory->getRowNb()*m_tileFactory->getDrawingAreaHeight()
)
);
}
for(int j=0;j<=m_tileFactory->getRowNb();j++)
{
painter->drawLine(QPointF(
0,
j*m_tileFactory->getDrawingAreaHeight()
),
QPointF(
m_tileFactory->getColNb()*m_tileFactory->getDrawingAreaWidth(),
j*m_tileFactory->getDrawingAreaHeight()
)
);
}
}
}

View file

@ -0,0 +1,57 @@
/************************************************************************
**
** @file vpgraphicstilegrid.h
** @author Ronan Le Tiec
** @date 19 11, 2020
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2020 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina 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 Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VPGRAPHICSTILEGRID_H
#define VPGRAPHICSTILEGRID_H
#include <QGraphicsItem>
#include <QPainter>
#include "../vmisc/def.h"
class VPTileFactory;
class VPLayout;
class VPGraphicsTileGrid : public QGraphicsItem
{
public:
explicit VPGraphicsTileGrid(VPLayout* layout, VPTileFactory *tileFactory, QGraphicsItem *parent = nullptr);
~VPGraphicsTileGrid();
QRectF boundingRect() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
private:
Q_DISABLE_COPY(VPGraphicsTileGrid)
VPTileFactory *m_tileFactory{nullptr};
VPLayout *m_layout{nullptr};
};
#endif // VPGRAPHICSTILEGRID_H

View file

@ -38,6 +38,7 @@ Q_LOGGING_CATEGORY(pLayout, "p.layout")
//---------------------------------------------------------------------------------------------------------------------
VPLayout::VPLayout() :
m_unplacedPieceList(new VPPieceList(this)),
m_trashPieceList(new VPPieceList(this)),
m_sheets(QList<VPSheet*>())
{
m_unplacedPieceList->SetName(QObject::tr("Unplaced pieces"));
@ -48,6 +49,7 @@ VPLayout::~VPLayout()
{
qDeleteAll(m_sheets);
delete m_unplacedPieceList;
delete m_trashPieceList;
}
//---------------------------------------------------------------------------------------------------------------------
@ -56,6 +58,12 @@ VPPieceList* VPLayout::GetUnplacedPieceList()
return m_unplacedPieceList;
}
//---------------------------------------------------------------------------------------------------------------------
VPPieceList* VPLayout::GetTrashPieceList()
{
return m_trashPieceList;
}
//---------------------------------------------------------------------------------------------------------------------
VPSheet* VPLayout::AddSheet()
{
@ -141,6 +149,31 @@ bool VPLayout::GetWarningPiecesOutOfBound() const
return m_warningPiecesOutOfBound;
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetTitle(QString title)
{
m_title = title;
}
//---------------------------------------------------------------------------------------------------------------------
QString VPLayout::GetTitle() const
{
return m_title;
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetDescription(QString description)
{
m_description = description;
}
//---------------------------------------------------------------------------------------------------------------------
QString VPLayout::GetDescription() const
{
return m_description;
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::ClearSelection()
{
@ -183,7 +216,7 @@ void VPLayout::MovePieceToPieceList(VPPiece* piece, VPPieceList* pieceList)
pieceList->AddPiece(piece);
// signal, that a piece was moved
emit PieceMovedToPieceList(piece, pieceListBefore,pieceList);
emit PieceMovedToPieceList(piece, pieceListBefore, pieceList);
}
@ -205,3 +238,132 @@ VPSheet* VPLayout::GetFocusedSheet()
{
return m_focusedSheet;
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetTilesSize(qreal width, qreal height)
{
m_tilesSize.setWidth(width);
m_tilesSize.setHeight(height);
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetTilesSizeConverted(qreal width, qreal height)
{
m_tilesSize.setWidth(UnitConvertor(width, GetUnit(), Unit::Px));
m_tilesSize.setHeight(UnitConvertor(height, GetUnit(), Unit::Px));
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetTilesSize(const QSizeF &size)
{
m_tilesSize = size;
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetTilesSizeConverted(const QSizeF &size)
{
m_tilesSize = QSizeF(
UnitConvertor(size.width(), GetUnit(), Unit::Px),
UnitConvertor(size.height(), GetUnit(), Unit::Px)
);
}
//---------------------------------------------------------------------------------------------------------------------
QSizeF VPLayout::GetTilesSize() const
{
return m_tilesSize;
}
//---------------------------------------------------------------------------------------------------------------------
QSizeF VPLayout::GetTilesSize(Unit unit) const
{
QSizeF convertedSize = QSizeF(
UnitConvertor(m_tilesSize.width(), Unit::Px, unit),
UnitConvertor(m_tilesSize.height(), Unit::Px, unit)
);
return convertedSize;
}
//---------------------------------------------------------------------------------------------------------------------
QSizeF VPLayout::GetTilesSizeConverted() const
{
return GetTilesSize(GetUnit());
}
//---------------------------------------------------------------------------------------------------------------------
PageOrientation VPLayout::GetTilesOrientation()
{
return m_tilesOrientation;
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetTilesOrientation(PageOrientation orientation)
{
if(orientation != m_tilesOrientation)
{
m_tilesOrientation = orientation;
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetTilesMargins(qreal left, qreal top, qreal right, qreal bottom)
{
m_tilesMargins.setLeft(left);
m_tilesMargins.setTop(top);
m_tilesMargins.setRight(right);
m_tilesMargins.setBottom(bottom);
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetTilesMarginsConverted(qreal left, qreal top, qreal right, qreal bottom)
{
m_tilesMargins.setLeft(UnitConvertor(left, GetUnit(), Unit::Px));
m_tilesMargins.setTop(UnitConvertor(top, GetUnit(), Unit::Px));
m_tilesMargins.setRight(UnitConvertor(right, GetUnit(), Unit::Px));
m_tilesMargins.setBottom(UnitConvertor(bottom, GetUnit(), Unit::Px));
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetTilesMargins(const QMarginsF &margins)
{
m_tilesMargins = margins;
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetTilesMarginsConverted(const QMarginsF &margins)
{
m_tilesMargins = UnitConvertor(margins, GetUnit(), Unit::Px);
}
//---------------------------------------------------------------------------------------------------------------------
QMarginsF VPLayout::GetTilesMargins() const
{
return m_tilesMargins;
}
//---------------------------------------------------------------------------------------------------------------------
QMarginsF VPLayout::GetTilesMargins(Unit unit) const
{
return UnitConvertor(m_tilesMargins, Unit::Px, unit);
}
//---------------------------------------------------------------------------------------------------------------------
QMarginsF VPLayout::GetTilesMarginsConverted() const
{
return UnitConvertor(m_tilesMargins, Unit::Px, GetUnit());
}
//---------------------------------------------------------------------------------------------------------------------
bool VPLayout::GetShowTiles()
{
return m_showTiles;
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayout::SetShowTiles(bool value)
{
m_showTiles = value;
}

View file

@ -50,6 +50,12 @@ public:
*/
VPPieceList* GetUnplacedPieceList();
/**
* @brief GetTrashPieceList Returns the piece list of the trash
* @return the pieces list of trashed pieces.
*/
VPPieceList* GetTrashPieceList();
VPSheet* AddSheet();
VPSheet* AddSheet(VPSheet *sheet);
QList<VPSheet *> GetSheets();
@ -78,6 +84,30 @@ public:
void SetWarningPiecesOutOfBound(bool state);
bool GetWarningPiecesOutOfBound() const;
/**
* @brief SetTitle Sets the title of the layout to the given value
* @param title the title of the layout
*/
void SetTitle(QString title);
/**
* @brief GetTitle Returns the title of the layout
* @return
*/
QString GetTitle() const;
/**
* @brief SetDescription Sets the description of the layout to the given value
* @param description the description of the layout
*/
void SetDescription(QString description);
/**
* @brief GetDescription Returns the description of the layout.
* @return
*/
QString GetDescription() const;
/**
* @brief ClearSelection goes through the unplaced pieces and through the sheets and calls
* SetIsSelected(false) for the pieces that were selected.
@ -114,6 +144,124 @@ public:
VPSheet* GetFocusedSheet();
/**
* @brief SetTilesSize sets the size of the tiles, the values have to be in Unit::Px
* @param width tiles width
* @param height tiles height
*/
void SetTilesSize(qreal width, qreal height);
/**
* @brief SetTilesSizeConverted sets the size of the sheet, the values have to be in the layout's unit
* @param width tiles width
* @param height tiles height
*/
void SetTilesSizeConverted(qreal width, qreal height);
/**
* @brief SetTilesSize sets the size of the tiles, the values have to be in Unit::Px
* @param size tiles size
*/
void SetTilesSize(const QSizeF &size);
/**
* @brief SetTilesSizeConverted sets the size of the tiles, the values have to be in the layout's unit
* @param size tiles size
*/
void SetTilesSizeConverted(const QSizeF &size);
/**
* @brief GetTilesSize Returns the size of the tiles in Unit::Px
* @return tiles size in Unit::Px
*/
QSizeF GetTilesSize() const;
/**
* @brief GetTilesSize Returns the size of the tiles in given Unit
* @return tiles size
*/
QSizeF GetTilesSize(Unit unit) const;
/**
* @brief GetTilesSizeConverted Returns the size of the tiles in the layout's unit
* @return the size in the layout's unit
*/
QSizeF GetTilesSizeConverted() const;
/**
* @brief GetOrientation Returns the orientation of the tiles
* @return orientation of the tiles
*/
PageOrientation GetTilesOrientation();
/**
* @brief SetOrientation Sets the orientation of the tiles to the given value
* @param orientation the new tiles orientation
*/
void SetTilesOrientation(PageOrientation orientation);
/**
* @brief SetTilesMargins, set the margins of the tiles, the values have to be in Unit::Px
* @param left in Unit::Px
* @param top in Unit::Px
* @param right in Unit::Px
* @param bottom in Unit::Px
*/
void SetTilesMargins(qreal left, qreal top, qreal right, qreal bottom);
/**
* @brief SetSheetMargins, set the margins of the tiles, the values have to be in the unit of the layout
* @param left in Unit::Px
* @param top in Unit::Px
* @param right in Unit::Px
* @param bottom in Unit::Px
*/
void SetTilesMarginsConverted(qreal left, qreal top, qreal right, qreal bottom);
/**
* @brief SetTilesMargins set the margins of the tiles, the values have to be in Unit::Px
* @param margins tiles margins
*/
void SetTilesMargins(const QMarginsF &margins);
/**
* @brief SetTilesMarginsConverted set the margins of the tiles, the values have to be in the unit of the layout
* @param margins tiles margins
*/
void SetTilesMarginsConverted(const QMarginsF &margins);
/**
* @brief GetTilesMargins Returns margins of the tiles in Unit::Px
* @return the margins in Unit::Px
*/
QMarginsF GetTilesMargins() const;
/**
* @brief GetTilesMargins Returns margins of the tiles in the given unit
* @param unit the unit in which we want the margins
* @return the margins in the given unit
*/
QMarginsF GetTilesMargins(Unit unit) const;
/**
* @brief GetTilesMarginsConverted Returns the margins of the tiles in the layout's unit
* @return the margins in the tiles's unit
*/
QMarginsF GetTilesMarginsConverted() const;
/**
* @brief GetShowTiles Returns true if the tiles has to be shown on the current sheet
* @return
*/
bool GetShowTiles();
/**
* @brief SetShowTiles Sets wether to show the tiles on the current sheet or not
* @param value true to show the tiles
*/
void SetShowTiles(bool value);
signals:
void PieceMovedToPieceList(VPPiece *piece, VPPieceList *pieceListBefore, VPPieceList *pieceListAfter);
@ -123,16 +271,12 @@ private:
VPPieceList *m_unplacedPieceList;
QList<VPSheet*> m_sheets;
/**
TODO : To be replaced by m_focusedSheet
* @brief m_focusedPieceList pointer the the focused piece list, to which pieces will be
* added via drag and drop, or if no piece list is defined.
* @brief m_trashPieceList Holds the pieces that were deleted
*/
VPPieceList *m_focusedPieceList{nullptr};
VPPieceList *m_trashPieceList;
QList<VPSheet*> m_sheets;
VPSheet *m_focusedSheet{nullptr};
// format
@ -141,7 +285,27 @@ private:
bool m_warningSuperpositionOfPieces{false};
bool m_warningPiecesOutOfBound{false};
QString m_title{};
QString m_description{};
/**
* @brief m_size the Size of the tiles in Unit::Px
*/
QSizeF m_tilesSize{};
/**
* @brief holds the orientation of the tiles
*/
PageOrientation m_tilesOrientation {PageOrientation::Portrait};
// margins
/**
* @brief m_margins the margins of the tiles in Unit::Px
*/
QMarginsF m_tilesMargins{};
bool m_showTiles{false};
};
#endif // VPLAYOUT_H

View file

@ -37,6 +37,7 @@
#include "vplayout.h"
#include "vpsheet.h"
#include "../vwidgets/vmaingraphicsscene.h"
#include "vptilefactory.h"
#include <QLoggingCategory>
@ -44,7 +45,7 @@ Q_LOGGING_CATEGORY(pMainGraphicsView, "p.mainGraphicsView")
//---------------------------------------------------------------------------------------------------------------------
VPMainGraphicsView::VPMainGraphicsView(VPLayout *layout, QWidget *parent) :
VPMainGraphicsView::VPMainGraphicsView(VPLayout *layout, VPTileFactory *tileFactory, QWidget *parent) :
VMainGraphicsView(parent),
m_layout(layout)
{
@ -58,6 +59,9 @@ VPMainGraphicsView::VPMainGraphicsView(VPLayout *layout, QWidget *parent) :
setAcceptDrops(true);
m_graphicsTileGrid = new VPGraphicsTileGrid(layout, tileFactory);
m_scene->addItem(m_graphicsTileGrid);
// add the connections
connect(m_layout, &VPLayout::PieceMovedToPieceList, this, &VPMainGraphicsView::on_PieceMovedToPieceList);
connect(m_scene, &VMainGraphicsScene::selectionChanged, this,
@ -71,9 +75,44 @@ void VPMainGraphicsView::RefreshLayout()
m_graphicsSheet->update();
m_graphicsTileGrid->update();
m_scene->update();
}
//---------------------------------------------------------------------------------------------------------------------
VMainGraphicsScene* VPMainGraphicsView::GetScene()
{
return m_scene;
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::PrepareForExport()
{
m_layout->ClearSelection();
m_graphicsSheet->SetShowBorder(false);
m_graphicsSheet->SetShowMargin(false);
m_showTilesTmp = m_layout->GetShowTiles();
m_layout->SetShowTiles(false);
RefreshLayout();
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::CleanAfterExport()
{
m_graphicsSheet->SetShowBorder(true);
m_graphicsSheet->SetShowMargin(true);
m_layout->SetShowTiles(m_showTilesTmp);
RefreshLayout();
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::dragEnterEvent(QDragEnterEvent *event)
{
@ -174,7 +213,7 @@ void VPMainGraphicsView::on_PieceMovedToPieceList(VPPiece *piece, VPPieceList *p
scene()->removeItem(_graphicsPiece);
m_graphicsPieces.removeAll(_graphicsPiece);
}
else if(pieceListAfter != m_layout->GetUnplacedPieceList())
else if(pieceListAfter != m_layout->GetUnplacedPieceList() && pieceListAfter != m_layout->GetTrashPieceList())
{
if(_graphicsPiece == nullptr)
{
@ -193,9 +232,22 @@ void VPMainGraphicsView::on_PieceMovedToPieceList(VPPiece *piece, VPPieceList *p
//---------------------------------------------------------------------------------------------------------------------
void VPMainGraphicsView::on_SceneSelectionChanged()
{
// most of the selection behaviour taks place automatically
// most of the selection behaviour takes place automatically
// but we need to make sure that the unplaced pieces are unselected when the scene selection has changed
// because as they are not part of the scene, they are not updated
m_layout->GetUnplacedPieceList()->ClearSelection();
// make sure, that the selected items are on top
// FIXME: maybe there is a more proper way to do it
for(auto graphicPiece : m_graphicsPieces)
{
if(!graphicPiece->GetPiece()->GetIsSelected())
{
if(!m_scene->selectedItems().isEmpty())
{
graphicPiece->stackBefore(m_scene->selectedItems().first());
}
}
}
}

View file

@ -31,16 +31,19 @@
#include "vpgraphicssheet.h"
#include "vpgraphicspiece.h"
#include "vptilefactory.h"
#include "vpgraphicstilegrid.h"
#include "../vwidgets/vmaingraphicsview.h"
class VMainGraphicsScene;
class VPTileFactory;
class VPMainGraphicsView : public VMainGraphicsView
{
Q_OBJECT
public:
VPMainGraphicsView(VPLayout *layout, QWidget *parent);
VPMainGraphicsView(VPLayout *layout, VPTileFactory *tileFactory, QWidget *parent);
~VPMainGraphicsView() = default;
/**
@ -48,6 +51,24 @@ public:
*/
void RefreshLayout();
/**
* @brief GetScene Returns the scene of the view
* @return
*/
VMainGraphicsScene* GetScene();
/**
* @brief PrepareForExport prepares the graphic for an export (i.e hide margin etc)
*/
void PrepareForExport();
/**
* @brief CleanAfterExport cleans the graphic for an export (i.e show margin etc)
*/
void CleanAfterExport();
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
@ -56,6 +77,8 @@ protected:
void keyPressEvent(QKeyEvent *event) override;
void drawTilesLine();
private slots:
/**
* @brief on_PieceMovedToPieceList The slot is called when the given piece was moved from the given piece list to the other
@ -77,10 +100,18 @@ private:
VMainGraphicsScene *m_scene{nullptr};
VPGraphicsSheet *m_graphicsSheet{nullptr};
VPGraphicsTileGrid *m_graphicsTileGrid{nullptr};
VPLayout *m_layout{nullptr};
QList<VPGraphicsPiece*> m_graphicsPieces{};
/**
* variable to hold temporarly hte value of the show tiles
*/
bool m_showTilesTmp{false};
};
#endif // VPMAINGRAPHICSVIEW_H

View file

@ -29,6 +29,8 @@
#include <QFileDialog>
#include <QCloseEvent>
#include <QtMath>
#include <QSvgGenerator>
#include "ui_vpmainwindow.h"
#include "dialogs/vpdialogabout.h"
@ -40,6 +42,7 @@
#include "../vmisc/projectversion.h"
#include "../ifc/xml/vlayoutconverter.h"
#include "../ifc/exception/vexception.h"
#include "../vwidgets/vmaingraphicsscene.h"
#include "vpsheet.h"
#include <QLoggingCategory>
@ -73,19 +76,35 @@ VPMainWindow::VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent) :
m_layout->SetUnit(Unit::Cm);
m_layout->SetWarningSuperpositionOfPieces(true);
m_layout->SetTitle(QString("My Test Layout"));
m_layout->SetDescription(QString("Description of my Layout"));
m_layout->SetTilesSizeConverted(21,29.7);
m_layout->SetTilesOrientation(PageOrientation::Portrait);
m_layout->SetTilesMarginsConverted(1,1,1,1);
m_layout->SetShowTiles(true);
// --------------------------------------------------------
ui->setupUi(this);
// init the tile factory
m_tileFactory = new VPTileFactory(m_layout, qApp->Settings());
m_tileFactory->refreshTileInfos();
InitMenuBar();
InitProperties();
InitCarrousel();
InitMainGraphics();
InitZoomToolBar();
SetPropertiesData();
ReadSettings();
}
//---------------------------------------------------------------------------------------------------------------------
@ -183,6 +202,12 @@ void VPMainWindow::ImportRawLayouts(const QStringList &rawLayouts)
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::InitZoom()
{
m_graphicsView->ZoomFitBest();
}
//---------------------------------------------------------------------------------------------------------------------
VPPiece* VPMainWindow::CreatePiece(const VLayoutPiece &rawPiece)
{
@ -231,6 +256,7 @@ void VPMainWindow::InitMenuBar()
void VPMainWindow::InitProperties()
{
InitPropertyTabCurrentPiece();
InitPropertyTabCurrentSheet();
InitPropertyTabLayout();
InitPropertyTabTiles();
}
@ -238,6 +264,10 @@ void VPMainWindow::InitProperties()
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::InitPropertyTabCurrentPiece()
{
// FIXME ---- For MVP we hide a few things. To be displayed when functions there
ui->groupBoxLayoutControl->hide();
ui->groupBoxCurrentPieceGeometry->hide();
// ------------------------------ placement -----------------------------------
connect(ui->doubleSpinBoxCurrentPieceBoxPositionX, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
@ -246,21 +276,12 @@ void VPMainWindow::InitPropertyTabCurrentPiece()
&VPMainWindow::on_CurrentPiecePositionEdited);
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::InitPropertyTabLayout()
void VPMainWindow::InitPropertyTabCurrentSheet()
{
// -------------------- init the unit combobox ---------------------
ui->comboBoxLayoutUnit->addItem(tr("Centimeters"), QVariant(UnitsToStr(Unit::Cm)));
ui->comboBoxLayoutUnit->addItem(tr("Millimiters"), QVariant(UnitsToStr(Unit::Mm)));
ui->comboBoxLayoutUnit->addItem(tr("Inches"), QVariant(UnitsToStr(Unit::Inch)));
// set default unit - TODO when we have the setting for the unit
// const qint32 indexUnit = -1;//ui->comboBoxLayoutUnit->findData(qApp->ValentinaSettings()->GetUnit());
// if (indexUnit != -1)
// {
// ui->comboBoxLayoutUnit->setCurrentIndex(indexUnit);
// }
// FIXME ---- For MVP we hide a few things. To be displayed when functions there
ui->pushButtonSheetRemoveUnusedLength->hide();
ui->groupBoxSheetControl->hide();
// some of the UI Elements are connected to the slots via auto-connect
// see https://doc.qt.io/qt-5/designer-using-a-ui-file.html#widgets-and-dialogs-with-auto-connect
@ -293,18 +314,96 @@ void VPMainWindow::InitPropertyTabLayout()
connect(ui->radioButtonSheetFollowGrainlineHorizontal, QOverload<bool>::of(&QRadioButton::clicked), this,
&VPMainWindow::on_SheetFollowGrainlineChanged);
// -------------------- export ---------------------------
// -------------------- sheet template ---------------------------
// TODO init the file format export combobox
// FIXME: find a nicer way to initiliase it
QVector<PaperSizeTemplate> sheetTemplates = QVector<PaperSizeTemplate>();
sheetTemplates.append(PaperSizeTemplate::A0);
sheetTemplates.append(PaperSizeTemplate::A1);
sheetTemplates.append(PaperSizeTemplate::A2);
sheetTemplates.append(PaperSizeTemplate::A3);
sheetTemplates.append(PaperSizeTemplate::A4);
sheetTemplates.append(PaperSizeTemplate::Letter);
sheetTemplates.append(PaperSizeTemplate::Legal);
sheetTemplates.append(PaperSizeTemplate::Tabloid);
sheetTemplates.append(PaperSizeTemplate::Roll24in);
sheetTemplates.append(PaperSizeTemplate::Roll30in);
sheetTemplates.append(PaperSizeTemplate::Roll36in);
sheetTemplates.append(PaperSizeTemplate::Roll42in);
sheetTemplates.append(PaperSizeTemplate::Roll44in);
sheetTemplates.append(PaperSizeTemplate::Roll48in);
sheetTemplates.append(PaperSizeTemplate::Roll62in);
sheetTemplates.append(PaperSizeTemplate::Roll72in);
sheetTemplates.append(PaperSizeTemplate::Custom);
ui->comboBoxSheetTemplate->blockSignals(true);
VPSheet::PopulateComboBox(&sheetTemplates, ui->comboBoxSheetTemplate);
ui->comboBoxSheetTemplate->blockSignals(false);
ui->comboBoxSheetTemplate->setCurrentIndex(0);
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::InitPropertyTabTiles()
{
// for the MVP we don't want the tiles tab.
// we remove it. As soon as we need it, update this code
ui->tabWidgetProperties->removeTab(2); // remove tiles
// -------------------- layout width, length, orientation ------------------------
connect(ui->doubleSpinBoxTilesWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
&VPMainWindow::on_TilesSizeChanged);
connect(ui->doubleSpinBoxTilesLength, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
&VPMainWindow::on_TilesSizeChanged);
connect(ui->radioButtonTilesPortrait, QOverload<bool>::of(&QRadioButton::clicked), this,
&VPMainWindow::on_TilesOrientationChanged);
connect(ui->radioButtonTilesLandscape, QOverload<bool>::of(&QRadioButton::clicked), this,
&VPMainWindow::on_TilesOrientationChanged);
// -------------------- tiles template
QVector<PaperSizeTemplate> tilesTemplates = QVector<PaperSizeTemplate>();
tilesTemplates.append(PaperSizeTemplate::A0);
tilesTemplates.append(PaperSizeTemplate::A1);
tilesTemplates.append(PaperSizeTemplate::A2);
tilesTemplates.append(PaperSizeTemplate::A3);
tilesTemplates.append(PaperSizeTemplate::A4);
tilesTemplates.append(PaperSizeTemplate::Letter);
tilesTemplates.append(PaperSizeTemplate::Legal);
tilesTemplates.append(PaperSizeTemplate::Custom);
ui->comboBoxTilesTemplate->blockSignals(true);
VPSheet::PopulateComboBox(&tilesTemplates, ui->comboBoxTilesTemplate);
ui->comboBoxTilesTemplate->blockSignals(false);
ui->comboBoxTilesTemplate->setCurrentIndex(4); //A4
// -------------------- margins ------------------------
connect(ui->doubleSpinBoxTilesMarginTop, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
&VPMainWindow::on_TilesMarginChanged);
connect(ui->doubleSpinBoxTilesMarginRight, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
&VPMainWindow::on_TilesMarginChanged);
connect(ui->doubleSpinBoxTilesMarginBottom, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
&VPMainWindow::on_TilesMarginChanged);
connect(ui->doubleSpinBoxTilesMarginLeft, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
&VPMainWindow::on_TilesMarginChanged);
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::InitPropertyTabLayout()
{
// FIXME ---- For MVP we hide a few things. To be displayed when functions there
ui->groupBoxLayoutControl->hide();
// -------------------- init the unit combobox ---------------------
ui->comboBoxLayoutUnit->addItem(tr("Centimeters"), QVariant(UnitsToStr(Unit::Cm)));
ui->comboBoxLayoutUnit->addItem(tr("Millimiters"), QVariant(UnitsToStr(Unit::Mm)));
ui->comboBoxLayoutUnit->addItem(tr("Inches"), QVariant(UnitsToStr(Unit::Inch)));
// set default unit - TODO when we have the setting for the unit
// const qint32 indexUnit = -1;//ui->comboBoxLayoutUnit->findData(qApp->ValentinaSettings()->GetUnit());
// if (indexUnit != -1)
// {
// ui->comboBoxLayoutUnit->setCurrentIndex(indexUnit);
// }
}
//---------------------------------------------------------------------------------------------------------------------
@ -356,6 +455,7 @@ void VPMainWindow::SetPropertyTabCurrentPieceData()
// set the value to the current piece
ui->lineEditCurrentPieceName->setText(selectedPiece->GetName());
ui->plainTextEditCurrentPieceUUID->setPlainText(selectedPiece->GetUUID().toString());
ui->checkBoxCurrentPieceShowSeamline->setChecked(selectedPiece->GetShowSeamLine());
ui->checkBoxCurrentPieceMirrorPiece->setChecked(selectedPiece->GetPieceMirrored());
@ -393,7 +493,7 @@ void VPMainWindow::SetPropertyTabSheetData()
SetDoubleSpinBoxValue(ui->doubleSpinBoxSheetLength, size.height());
// Set Orientation
if(size.width() <= size.height())
if(m_layout->GetFocusedSheet()->GetOrientation() == PageOrientation::Portrait)
{
ui->radioButtonSheetPortrait->setChecked(true);
}
@ -416,10 +516,42 @@ void VPMainWindow::SetPropertyTabSheetData()
SetCheckBoxValue(ui->checkBoxSheetStickyEdges, m_layout->GetFocusedSheet()->GetStickyEdges());
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::SetPropertyTabTilesData()
{
// set Width / Length
QSizeF size = m_layout->GetTilesSizeConverted();
SetDoubleSpinBoxValue(ui->doubleSpinBoxTilesWidth, size.width());
SetDoubleSpinBoxValue(ui->doubleSpinBoxTilesLength, size.height());
// Set Orientation
if(m_layout->GetTilesOrientation() == PageOrientation::Portrait)
{
ui->radioButtonSheetPortrait->setChecked(true);
}
else
{
ui->radioButtonSheetLandscape->setChecked(true);
}
// set margins
QMarginsF margins = m_layout->GetTilesMarginsConverted();
SetDoubleSpinBoxValue(ui->doubleSpinBoxTilesMarginLeft, margins.left());
SetDoubleSpinBoxValue(ui->doubleSpinBoxTilesMarginTop, margins.top());
SetDoubleSpinBoxValue(ui->doubleSpinBoxTilesMarginRight, margins.right());
SetDoubleSpinBoxValue(ui->doubleSpinBoxTilesMarginBottom, margins.bottom());
// set "show tiles" checkbox
SetCheckBoxValue(ui->checkBoxTilesShowTiles, m_layout->GetShowTiles());
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::SetPropertyTabLayoutData()
{
// TODO FIXME : Set name and description
// set the title and description
ui->lineEditLayoutName->setText(m_layout->GetTitle());
ui->plainTextEditLayoutDescription->setPlainText(m_layout->GetDescription());
// set Unit
int index = ui->comboBoxLayoutUnit->findData(QVariant(UnitsToStr(m_layout->GetUnit())));
@ -435,21 +567,78 @@ void VPMainWindow::SetPropertyTabLayoutData()
SetCheckBoxValue(ui->checkBoxLayoutWarningPiecesSuperposition, m_layout->GetWarningSuperpositionOfPieces());
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::SetPropertyTabTilesData()
{
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::InitMainGraphics()
{
m_graphicsView = new VPMainGraphicsView(m_layout, this);
m_graphicsView = new VPMainGraphicsView(m_layout, m_tileFactory, this);
ui->centralWidget->layout()->addWidget(m_graphicsView);
m_graphicsView->RefreshLayout();
connect(m_graphicsView, &VPMainGraphicsView::ScaleChanged, this, &VPMainWindow::on_ScaleChanged);
connect(m_graphicsView->GetScene(), &VMainGraphicsScene::mouseMove, this, &VPMainWindow::on_MouseMoved);
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::InitZoomToolBar()
{
if (not m_doubleSpinBoxScale.isNull())
{
delete m_doubleSpinBoxScale;
}
if (m_mouseCoordinate != nullptr)
{
delete m_mouseCoordinate;
}
// connect the zoom buttons and shortcuts to the slots
QList<QKeySequence> zoomInShortcuts;
zoomInShortcuts.append(QKeySequence(QKeySequence::ZoomIn));
zoomInShortcuts.append(QKeySequence(Qt::ControlModifier + Qt::Key_Plus + Qt::KeypadModifier));
ui->actionZoomIn->setShortcuts(zoomInShortcuts);
connect(ui->actionZoomIn, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomIn);
QList<QKeySequence> zoomOutShortcuts;
zoomOutShortcuts.append(QKeySequence(QKeySequence::ZoomOut));
zoomOutShortcuts.append(QKeySequence(Qt::ControlModifier + Qt::Key_Minus + Qt::KeypadModifier));
ui->actionZoomOut->setShortcuts(zoomOutShortcuts);
connect(ui->actionZoomOut, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomOut);
QList<QKeySequence> zoomOriginalShortcuts;
zoomOriginalShortcuts.append(QKeySequence(Qt::ControlModifier + Qt::Key_0));
zoomOriginalShortcuts.append(QKeySequence(Qt::ControlModifier + Qt::Key_0 + Qt::KeypadModifier));
ui->actionZoomOriginal->setShortcuts(zoomOriginalShortcuts);
connect(ui->actionZoomOriginal, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomOriginal);
QList<QKeySequence> zoomFitBestShortcuts;
zoomFitBestShortcuts.append(QKeySequence(Qt::ControlModifier + Qt::Key_Equal));
ui->actionZoomFitBest->setShortcuts(zoomFitBestShortcuts);
connect(ui->actionZoomFitBest, &QAction::triggered, m_graphicsView, &VPMainGraphicsView::ZoomFitBest);
// defined the scale
ui->toolBarZoom->addSeparator();
QLabel* zoomScale = new QLabel(tr("Scale:"), this);
ui->toolBarZoom->addWidget(zoomScale);
m_doubleSpinBoxScale = new QDoubleSpinBox(this);
m_doubleSpinBoxScale->setDecimals(1);
m_doubleSpinBoxScale->setSuffix("%");
on_ScaleChanged(m_graphicsView->transform().m11());
connect(m_doubleSpinBoxScale.data(), QOverload<double>::of(&QDoubleSpinBox::valueChanged),
this, [this](double d){m_graphicsView->Zoom(d/100.0);});
ui->toolBarZoom->addWidget(m_doubleSpinBoxScale);
// define the mouse position
ui->toolBarZoom->addSeparator();
m_mouseCoordinate = new QLabel(QString("0, 0 (%1)").arg(UnitsToStr(m_layout->GetUnit(), true)));
ui->toolBarZoom->addWidget(m_mouseCoordinate);
ui->toolBarZoom->addSeparator();
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::SetDoubleSpinBoxValue(QDoubleSpinBox *spinBox, qreal value)
@ -560,6 +749,81 @@ bool VPMainWindow::MaybeSave()
return true;
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::generateTiledPdf(QString fileName)
{
if(not fileName.isEmpty())
{
m_graphicsView->PrepareForExport();
m_tileFactory->refreshTileInfos();
PageOrientation tilesOrientation = m_layout->GetTilesOrientation();
// ------------- Set up the printer
QPrinter* printer = new QPrinter();
printer->setCreator(QGuiApplication::applicationDisplayName()+QChar(QChar::Space)+
QCoreApplication::applicationVersion());
printer->setOrientation(QPrinter::Portrait); // in the pdf file the pages should always be in portrait
// here we might need to so some rounding for the size.
printer->setPageSize(QPageSize(m_layout->GetTilesSize(Unit::Mm),
QPageSize::Millimeter));
printer->setFullPage(true);
#ifdef Q_OS_MAC
printer->setOutputFormat(QPrinter::NativeFormat);
#else
printer->setOutputFormat(QPrinter::PdfFormat);
#endif
printer->setOutputFileName(fileName);
printer->setResolution(static_cast<int>(PrintDPI));
printer->setDocName("Test"); // FIXME
// ------------- Set up the painter
QPainter painter;
if (not painter.begin(printer))
{ // failed to open file
qCritical() << tr("Failed to open file, is it writable?");
return;
}
painter.setFont( QFont( QStringLiteral("Arial"), 8, QFont::Normal ) );
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setBrush ( QBrush ( Qt::NoBrush ) );
if(tilesOrientation == PageOrientation::Landscape)
{
// The landscape tiles have to be rotated, because the pages
// stay portrait in the pdf
painter.rotate(90);
painter.translate(0, -ToPixel(printer->pageRect(QPrinter::Millimeter).width(), Unit::Mm));
}
for(int row=0;row<m_tileFactory->getRowNb();row++) // for each row of the tiling grid
{
for(int col=0;col<m_tileFactory->getColNb();col++) // for each column of tiling grid
{
if(not (row == 0 && col == 0))
{
if (not printer->newPage())
{
qWarning("failed in flushing page to disk, disk full?");
return;
}
}
m_tileFactory->drawTile(&painter, m_graphicsView, row, col);
}
}
painter.end();
m_graphicsView->CleanAfterExport();
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_actionNew_triggered()
{
@ -669,7 +933,8 @@ void VPMainWindow::on_actionSave_triggered()
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_actionSaveAs_triggered()
{
// TODO / FIXME : See valentina how the save is done over there. we need to add the extension .vlt, check for empty file names etc.
// TODO / FIXME : See valentina how the save is done over there. we need to add the
// extension .vlt, check for empty file names etc.
//Get list last open files
QStringList recentFiles = qApp->PuzzleSettings()->GetRecentFileList();
@ -771,29 +1036,66 @@ void VPMainWindow::on_comboBoxLayoutUnit_currentIndexChanged(int index)
m_layout->SetUnit(Unit::Inch);
}
SetPropertyTabSheetData();
SetPropertyTabCurrentPieceData();
SetPropertyTabSheetData();
SetPropertyTabTilesData();
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_lineEditSheetName_textChanged(const QString &text)
{
m_layout->GetFocusedSheet()->SetName(text);
if(m_carrousel != nullptr)
{
m_carrousel->RefreshFocusedSheetName();
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_comboBoxSheetTemplate_currentIndexChanged(int index)
{
// just for test purpuses, to be removed:
QMessageBox msgBox;
msgBox.setText("TODO VPMainWindow::SheetTemplateChanged");
int ret = msgBox.exec();
PaperSizeTemplate tmpl = static_cast<PaperSizeTemplate>(
ui->comboBoxSheetTemplate->itemData(index).toInt()
);
Q_UNUSED(index);
Q_UNUSED(ret);
QSizeF tmplSize = VPSheet::GetTemplateSize(tmpl);
if(!tmplSize.isEmpty())
{
ui->doubleSpinBoxSheetWidth->blockSignals(true);
ui->doubleSpinBoxSheetLength->blockSignals(true);
ui->doubleSpinBoxSheetWidth->setValue(UnitConvertor(tmplSize.width(), Unit::Px, m_layout->GetUnit()));
ui->doubleSpinBoxSheetLength->setValue(UnitConvertor(tmplSize.height(), Unit::Px, m_layout->GetUnit()));
// TODO
on_SheetSizeChanged(false);
ui->doubleSpinBoxSheetWidth->blockSignals(false);
ui->doubleSpinBoxSheetLength->blockSignals(false);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_SheetSizeChanged()
void VPMainWindow::on_SheetSizeChanged(bool changedViaSizeCombobox)
{
m_layout->GetFocusedSheet()->SetSheetSizeConverted(ui->doubleSpinBoxSheetWidth->value(), ui->doubleSpinBoxSheetLength->value());
m_layout->GetFocusedSheet()->SetSheetSizeConverted(
ui->doubleSpinBoxSheetWidth->value(),
ui->doubleSpinBoxSheetLength->value()
);
if(changedViaSizeCombobox)
{
ui->comboBoxSheetTemplate->blockSignals(true);
// we don't try to get the right size, because it doesn't work well because of mm / inch conversion
int index = ui->comboBoxSheetTemplate->findData(
QVariant(static_cast<int>(PaperSizeTemplate::Custom)));
ui->comboBoxSheetTemplate->setCurrentIndex(index);
ui->comboBoxSheetTemplate->blockSignals(false);
}
m_tileFactory->refreshTileInfos();
// TODO Undo / Redo
@ -812,6 +1114,7 @@ void VPMainWindow::on_SheetOrientationChanged()
{
m_layout->GetFocusedSheet()->SetOrientation(PageOrientation::Landscape);
}
m_tileFactory->refreshTileInfos();
// TODO Undo / Redo
@ -847,6 +1150,120 @@ void VPMainWindow::on_SheetMarginChanged()
m_graphicsView->RefreshLayout();
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_comboBoxTilesTemplate_currentIndexChanged(int index)
{
PaperSizeTemplate tmpl = static_cast<PaperSizeTemplate>(
ui->comboBoxTilesTemplate->itemData(index).toInt()
);
QSizeF tmplSize = VPSheet::GetTemplateSize(tmpl);
if(!tmplSize.isEmpty())
{
ui->doubleSpinBoxTilesWidth->blockSignals(true);
ui->doubleSpinBoxTilesLength->blockSignals(true);
ui->doubleSpinBoxTilesWidth->setValue(UnitConvertor(tmplSize.width(), Unit::Px, m_layout->GetUnit()));
ui->doubleSpinBoxTilesLength->setValue(UnitConvertor(tmplSize.height(), Unit::Px, m_layout->GetUnit()));
on_TilesSizeChanged(false);
ui->doubleSpinBoxTilesWidth->blockSignals(false);
ui->doubleSpinBoxTilesLength->blockSignals(false);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_TilesSizeChanged(bool changedViaSizeCombobox)
{
m_layout->SetTilesSizeConverted(ui->doubleSpinBoxTilesWidth->value(), ui->doubleSpinBoxTilesLength->value());
m_tileFactory->refreshTileInfos();
if(changedViaSizeCombobox)
{
ui->comboBoxTilesTemplate->blockSignals(true);
// we don't try to get the right size, because it doesn't work well because of mm / inch conversion
int index = ui->comboBoxTilesTemplate->findData(
QVariant(static_cast<int>(PaperSizeTemplate::Custom)));
ui->comboBoxTilesTemplate->setCurrentIndex(index);
ui->comboBoxTilesTemplate->blockSignals(false);
}
// TODO Undo / Redo
if(m_graphicsView != nullptr)
{
m_graphicsView->RefreshLayout();
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_TilesOrientationChanged()
{
// Updates the orientation
if(ui->radioButtonTilesPortrait->isChecked())
{
m_layout->SetTilesOrientation(PageOrientation::Portrait);
}
else
{
m_layout->SetTilesOrientation(PageOrientation::Landscape);
}
m_tileFactory->refreshTileInfos();
// TODO Undo / Redo
m_graphicsView->RefreshLayout();
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_TilesMarginChanged()
{
m_layout->SetTilesMarginsConverted(
ui->doubleSpinBoxTilesMarginLeft->value(),
ui->doubleSpinBoxTilesMarginTop->value(),
ui->doubleSpinBoxTilesMarginRight->value(),
ui->doubleSpinBoxTilesMarginBottom->value()
);
m_tileFactory->refreshTileInfos();
// TODO Undo / Redo
m_graphicsView->RefreshLayout();
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_checkBoxTilesShowTiles_toggled(bool checked)
{
m_layout->SetShowTiles(checked);
// TODO Undo / Redo
m_graphicsView->RefreshLayout();
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_pushButtonTilesExport_clicked()
{
// svg export to do some test for the first test
QString dir = QDir::homePath();
QString filters(tr("PDF Files") + QLatin1String("(*.pdf)"));
QString fileName = QFileDialog::getSaveFileName(this, tr("Save as"),
dir + QLatin1String("/") + tr("Layout") + QLatin1String(".pdf"),
filters, nullptr
#ifdef Q_OS_LINUX
, QFileDialog::DontUseNativeDialog
#endif
);
generateTiledPdf(fileName);
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_SheetFollowGrainlineChanged()
@ -901,14 +1318,43 @@ void VPMainWindow::on_checkBoxSheetStickyEdges_toggled(bool checked)
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_pushButtonSheetExport_clicked()
{
// just for test purpuses, to be removed:
QMessageBox msgBox;
msgBox.setText("TODO VPMainWindow::on_pushButtonSheetExport_clicked");
int ret = msgBox.exec();
// svg export to do some test for the first test
Q_UNUSED(ret);
QString dir = QDir::homePath();
QString filters(tr("SVG Files") + QLatin1String("(*.svg)"));
QString fileName = QFileDialog::getSaveFileName(this, tr("Save as"),
dir + QLatin1String("/") + tr("Layout") + QLatin1String(".svg"),
filters, nullptr
#ifdef Q_OS_LINUX
, QFileDialog::DontUseNativeDialog
#endif
);
// TODO
if(not fileName.isEmpty())
{
m_graphicsView->PrepareForExport();
const QSizeF s = m_layout->GetFocusedSheet()->GetSheetSize();
const QRectF r = QRectF(0, 0, s.width(), s.height());
QSvgGenerator generator;
generator.setFileName(fileName);
generator.setSize(QSize(qFloor(s.width()),qFloor(s.height())));
generator.setViewBox(r);
generator.setTitle(tr("Pattern"));
generator.setDescription(m_layout->GetDescription().toHtmlEscaped());
generator.setResolution(static_cast<int>(PrintDPI));
QPainter painter;
painter.begin(&generator);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(Qt::black, qApp->Settings()->WidthHairLine(), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
painter.setBrush ( QBrush ( Qt::NoBrush ) );
m_graphicsView->GetScene()->render(&painter, r, r, Qt::IgnoreAspectRatio);
painter.end();
m_graphicsView->CleanAfterExport();
}
}
@ -1002,3 +1448,30 @@ void VPMainWindow::on_PieceRotationChanged()
SetDoubleSpinBoxValue(ui->doubleSpinBoxCurrentPieceAngle, angle);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_ScaleChanged(qreal scale)
{
if (not m_doubleSpinBoxScale.isNull())
{
m_doubleSpinBoxScale->blockSignals(true);
m_doubleSpinBoxScale->setMaximum(qFloor(VPMainGraphicsView::MaxScale()*1000)/10.0);
m_doubleSpinBoxScale->setMinimum(qFloor(VPMainGraphicsView::MinScale()*1000)/10.0);
m_doubleSpinBoxScale->setValue(qFloor(scale*1000)/10.0);
m_doubleSpinBoxScale->setSingleStep(1);
m_doubleSpinBoxScale->blockSignals(false);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_MouseMoved(const QPointF &scenePos)
{
if (m_mouseCoordinate != nullptr)
{
m_mouseCoordinate->setText(QStringLiteral("%1, %2 (%3)")
.arg(static_cast<qint32>(FromPixel(scenePos.x(), m_layout->GetUnit())))
.arg(static_cast<qint32>(FromPixel(scenePos.y(), m_layout->GetUnit())))
.arg(UnitsToStr(m_layout->GetUnit(), true)));
}
}

View file

@ -31,6 +31,7 @@
#include <QMainWindow>
#include <QMessageBox>
#include <QDoubleSpinBox>
#include <QPointer>
#include "../vmisc/def.h"
#include "vpcarrousel.h"
@ -38,7 +39,9 @@
#include "vplayout.h"
#include "vppiece.h"
#include "../vlayout/vlayoutpiece.h"
#include "vptilefactory.h"
#include "vpcommandline.h"
#include "../vlayout/vlayoutdef.h"
namespace Ui
{
@ -74,6 +77,11 @@ public:
*/
void ImportRawLayouts(const QStringList &rawLayouts);
/**
* @brief InitZoom Initialises the zoom to fit best
*/
void InitZoom();
public slots:
/**
* @brief on_actionNew_triggered When the menu action File > New
@ -98,6 +106,18 @@ private:
VPLayout *m_layout{nullptr};
QList<VPPiece *>m_selectedPieces{QList<VPPiece *>()};
VPTileFactory *m_tileFactory{nullptr};
/**
* @brief spin box with the scale factor of the graphic view
*/
QPointer<QDoubleSpinBox> m_doubleSpinBoxScale{nullptr};
/**
* @brief mouseCoordinate pointer to label who show mouse coordinate.
*/
QLabel* m_mouseCoordinate{nullptr};
/**
* @brief CreatePiece creates a piece from the given VLayoutPiece data
* @param rawPiece the raw piece data
@ -119,6 +139,11 @@ private:
*/
void InitPropertyTabCurrentPiece();
/**
* @brief InitPropertyTabCurrentSheet Inits the current sheet tab in the properties;
*/
void InitPropertyTabCurrentSheet();
/**
* @brief InitPropertyTabLayout Inits the layout tab in the properties
*/
@ -139,6 +164,11 @@ private:
*/
void InitMainGraphics();
/**
* @brief InitToolBar Initialises the tool bar
*/
void InitZoomToolBar();
/**
* @brief SetPropertiesData Sets the values of UI elements
* in all the property tabs to the values saved in m_layout
@ -190,6 +220,13 @@ private:
bool MaybeSave();
/**
* @brief generateTiledPdf Generates the tiled Pdf in the given filename
* @param filename
*/
void generateTiledPdf(QString fileName);
private slots:
/**
* @brief on_actionOpen_triggered When the menu action File > Open is
@ -248,42 +285,50 @@ private slots:
*/
void on_comboBoxLayoutUnit_currentIndexChanged(int index);
/**
* @brief on_lineEditSheetName_textChanged When the name of the sheet is changed
* in the sheet layout tab
* @param text
*/
void on_lineEditSheetName_textChanged(const QString &text);
/**
* @brief on_comboBoxLayoutTemplate_currentIndexChanged When the template is
* changed in the layout property tab.
* changed in the sheet property tab.
* The slot is automatically connected through name convention.
* @param index the index of the selected templated
*/
void on_comboBoxSheetTemplate_currentIndexChanged(int index);
/**
* @brief LayoutSizeChanged When the width or the length has been changed in
* the layout property tab
* @brief on_SheetSizeChanged When the width or the length has been changed in
* the sheet property tab
* @param changedViaSizeCombobox true if the change happened through the combobox
*/
void on_SheetSizeChanged();
void on_SheetSizeChanged(bool changedViaSizeCombobox = true);
/**
* @brief LayoutOrientationChanged When one of the radio boxes for the layout
* @brief on_SheetOrientationChanged When one of the radio boxes for the sheet
* orientation has been clicked
*/
void on_SheetOrientationChanged();
/**
* @brief on_pushButtonLayoutRemoveUnusedLength_clicked When the button
* "Remove unused length" in the layout property tab is clicked.
* "Remove unused length" in the sheet property tab is clicked.
* The slot is automatically connected through name convention.
*/
void on_pushButtonSheetRemoveUnusedLength_clicked();
/**
* @brief on_LayoutMarginChanged When one of the margin values has been changed
* in the layout property tab.
* @brief on_SheetMarginChanged When one of the margin values has been changed
* in the sheet property tab.
*/
void on_SheetMarginChanged();
/**
* @brief LayoutFollowGrainlineChanged When one of the radio boxes for the
* "Follow grainline" has been clicked in the layout property tab.
* "Follow grainline" has been clicked in the sheet property tab.
*/
void on_SheetFollowGrainlineChanged();
@ -295,6 +340,45 @@ private slots:
*/
void on_doubleSpinBoxSheetPiecesGap_valueChanged(double value);
/**
* @brief on_comboBoxTilesTemplate_currentIndexChanged When the template is
* changed in the tiles property tab.
* The slot is automatically connected through name convention.
* @param index the index of the selected templated
*/
void on_comboBoxTilesTemplate_currentIndexChanged(int index);
/**
* @brief on_TilesSizeChanged When the width or the length has been changed in
* the tiles property tab
* @param changedViaSizeCombobox true if the change happened through the combobox
*/
void on_TilesSizeChanged(bool changedViaSizeCombobox = true);
/**
* @brief on_TilesOrientationChanged When one of the radio boxes for the tiles
* orientation has been clicked
*/
void on_TilesOrientationChanged();
/**
* @brief on_TilesMarginChanged When one of the margin values has been changed
* in the tiles property tab.
*/
void on_TilesMarginChanged();
/**
* @brief on_checkBoxTilesShowTiles_toggled When the checkbox "show tiles" is
* clicked
* @param checked´
*/
void on_checkBoxTilesShowTiles_toggled(bool checked);
/**
* @brief on_pushButtonTilesExport_clicked When the export tiles button is clicked
*/
void on_pushButtonTilesExport_clicked();
/**
* @brief on_checkBoxLayoutWarningPiecesSuperposition_toggled When the
* "Warning when pieces superposition" checkbox value in the layout
@ -380,6 +464,16 @@ private slots:
*/
void on_PieceRotationChanged();
/**
* @brief on_ScaleChanged When the scale of the graphic view is changed
*/
void on_ScaleChanged(qreal scale);
/**
* @brief mouseMove save mouse position and show user.
* @param scenePos position mouse.
*/
void on_MouseMoved(const QPointF &scenePos);
};
#endif // VPMAINWINDOW_H

View file

@ -36,7 +36,7 @@
<x>0</x>
<y>0</y>
<width>1427</width>
<height>21</height>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@ -176,7 +176,7 @@
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<property name="iconSize">
<size>
@ -234,7 +234,7 @@
<x>0</x>
<y>0</y>
<width>342</width>
<height>1252</height>
<height>1318</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@ -275,6 +275,13 @@
<string>Infos</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="1" column="0">
<widget class="QLabel" name="labelCurrentPieceName">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEditCurrentPieceName">
<property name="text">
@ -285,10 +292,26 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelCurrentPieceName">
<item row="2" column="0">
<widget class="QLabel" name="labelCurrentPieceUUID">
<property name="text">
<string>Name:</string>
<string>UUID:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPlainTextEdit" name="plainTextEditCurrentPieceUUID">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>48</height>
</size>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="plainText">
<string>{7b2ce4ae-96f5-4905-bb34-405cb40ca208}</string>
</property>
</widget>
</item>
@ -507,7 +530,7 @@
<string/>
</attribute>
<attribute name="toolTip">
<string>Layout properties</string>
<string>Sheet properties</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayoutSheetProperty">
<property name="leftMargin">
@ -541,8 +564,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>356</width>
<height>761</height>
<width>342</width>
<height>731</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
@ -609,6 +632,9 @@
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBoxSheetWidth">
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>100000.000000000000000</double>
</property>
@ -623,6 +649,9 @@
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBoxSheetLength">
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>100000.000000000000000</double>
</property>
@ -958,7 +987,7 @@
<x>0</x>
<y>0</y>
<width>356</width>
<height>761</height>
<height>717</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
@ -968,13 +997,221 @@
<string notr="true">font-weight: bold;</string>
</property>
<property name="text">
<string>Tiles of current sheet</string>
<string>Tiled Pdf Export</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxTilesFormat">
<property name="title">
<string>Format</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_18">
<item>
<layout class="QFormLayout" name="formLayoutTilesFormat">
<item row="1" column="0">
<widget class="QLabel" name="labelTilesWidth">
<property name="text">
<string>Width</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBoxTilesWidth">
<property name="maximum">
<double>100000.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelTilesLength">
<property name="text">
<string>Length</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBoxTilesLength">
<property name="maximum">
<double>100000.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelTilesOrientation">
<property name="text">
<string>Orientation</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayoutTilesOrientation">
<item>
<widget class="QRadioButton" name="radioButtonTilesPortrait">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="share/resources/puzzleicon.qrc">
<normaloff>:/puzzleicon/64x64/iconPortrait.png</normaloff>:/puzzleicon/64x64/iconPortrait.png</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonTilesLandscape">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="share/resources/puzzleicon.qrc">
<normaloff>:/puzzleicon/64x64/iconLandscape.png</normaloff>:/puzzleicon/64x64/iconLandscape.png</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelTilesTemplate">
<property name="text">
<string>Template</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBoxTilesTemplate"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxTilesMargin">
<property name="title">
<string>Margins</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="3">
<widget class="QLabel" name="labelTilesMarginRight">
<property name="text">
<string>Right:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="labelTilesMarginLeft">
<property name="text">
<string>Left:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QDoubleSpinBox" name="doubleSpinBoxTilesMarginRight">
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QDoubleSpinBox" name="doubleSpinBoxTilesMarginLeft">
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="labelTilesMarginTop">
<property name="text">
<string>Top:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QDoubleSpinBox" name="doubleSpinBoxTilesMarginTop">
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="labelTilesMarginBottom">
<property name="text">
<string>Bottom:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QDoubleSpinBox" name="doubleSpinBoxTilesMarginBottom">
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxTilesControl">
<property name="title">
<string>Control</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_19">
<item>
<widget class="QCheckBox" name="checkBoxTilesShowTiles">
<property name="text">
<string>Show Tiles on sheet</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxTilesExport">
<property name="title">
<string>Export</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_20">
<item>
<widget class="QPushButton" name="pushButtonTilesExport">
<property name="text">
<string>Export Tiled Pdf</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacerTiles">
<property name="orientation">
@ -995,8 +1232,15 @@
</layout>
</widget>
<widget class="QWidget" name="tabLayoutProperty">
<attribute name="icon">
<iconset resource="share/resources/puzzleicon.qrc">
<normaloff>:/puzzleicon/64x64/iconProperties.png</normaloff>:/puzzleicon/64x64/iconProperties.png</iconset>
</attribute>
<attribute name="title">
<string>Prop.</string>
<string/>
</attribute>
<attribute name="toolTip">
<string>Layout properties</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayoutLayoutProperty">
<property name="leftMargin">
@ -1031,7 +1275,7 @@
<x>0</x>
<y>0</y>
<width>356</width>
<height>761</height>
<height>717</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
@ -1066,7 +1310,7 @@
<item row="0" column="1">
<widget class="QLineEdit" name="lineEditLayoutName">
<property name="text">
<string>My layout</string>
<string/>
</property>
</widget>
</item>
@ -1155,6 +1399,24 @@
</layout>
</widget>
</widget>
<widget class="QToolBar" name="toolBarZoom">
<property name="windowTitle">
<string>toolBar</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionZoomIn"/>
<addaction name="actionZoomOut"/>
<addaction name="actionZoomOriginal"/>
<addaction name="actionZoomFitBest"/>
</widget>
<action name="actionOpen">
<property name="text">
<string>&amp;Open</string>
@ -1233,15 +1495,93 @@
<string>Properties</string>
</property>
</action>
<action name="actionZoomIn">
<property name="icon">
<iconset theme="zoom-in">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Zoom in</string>
</property>
</action>
<action name="actionZoomOut">
<property name="icon">
<iconset theme="zoom-out">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Zoom out</string>
</property>
</action>
<action name="actionZoomOriginal">
<property name="icon">
<iconset theme="zoom-original">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Zoom 1:1</string>
</property>
</action>
<action name="actionZoomFitBest">
<property name="icon">
<iconset theme="zoom-fit-best">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Zoom fit best</string>
</property>
<property name="toolTip">
<string>Zoom sheet</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<tabstops>
<tabstop>tabWidgetProperties</tabstop>
<tabstop>scrollAreaCurrentPiece</tabstop>
<tabstop>scrollAreaSheet</tabstop>
<tabstop>scrollAreaTiles</tabstop>
<tabstop>scrollAreaLayout</tabstop>
<tabstop>lineEditCurrentPieceName</tabstop>
<tabstop>plainTextEditCurrentPieceUUID</tabstop>
<tabstop>checkBoxCurrentPieceShowSeamline</tabstop>
<tabstop>checkBoxCurrentPieceMirrorPiece</tabstop>
<tabstop>doubleSpinBoxCurrentPieceAngle</tabstop>
<tabstop>doubleSpinBoxCurrentPieceBoxPositionX</tabstop>
<tabstop>doubleSpinBoxCurrentPieceBoxPositionY</tabstop>
<tabstop>lineEditSheetName</tabstop>
<tabstop>comboBoxSheetTemplate</tabstop>
<tabstop>doubleSpinBoxSheetWidth</tabstop>
<tabstop>doubleSpinBoxSheetLength</tabstop>
<tabstop>radioButtonSheetPortrait</tabstop>
<tabstop>radioButtonSheetLandscape</tabstop>
<tabstop>pushButtonSheetRemoveUnusedLength</tabstop>
<tabstop>doubleSpinBoxSheetMarginTop</tabstop>
<tabstop>doubleSpinBoxSheetMarginLeft</tabstop>
<tabstop>doubleSpinBoxSheetMarginRight</tabstop>
<tabstop>doubleSpinBoxSheetMarginBottom</tabstop>
<tabstop>scrollAreaTiles</tabstop>
<tabstop>radioButtonSheetFollowGrainlineNo</tabstop>
<tabstop>radioButtonSheetFollowGrainlineVertical</tabstop>
<tabstop>radioButtonSheetFollowGrainlineHorizontal</tabstop>
<tabstop>doubleSpinBoxSheetPiecesGap</tabstop>
<tabstop>checkBoxSheetStickyEdges</tabstop>
<tabstop>comboBoxSheetExportFormat</tabstop>
<tabstop>pushButtonSheetExport</tabstop>
<tabstop>doubleSpinBoxTilesWidth</tabstop>
<tabstop>doubleSpinBoxTilesLength</tabstop>
<tabstop>radioButtonTilesPortrait</tabstop>
<tabstop>radioButtonTilesLandscape</tabstop>
<tabstop>doubleSpinBoxTilesMarginTop</tabstop>
<tabstop>doubleSpinBoxTilesMarginLeft</tabstop>
<tabstop>doubleSpinBoxTilesMarginRight</tabstop>
<tabstop>doubleSpinBoxTilesMarginBottom</tabstop>
<tabstop>checkBoxTilesShowTiles</tabstop>
<tabstop>pushButtonTilesExport</tabstop>
<tabstop>lineEditLayoutName</tabstop>
<tabstop>plainTextEditLayoutDescription</tabstop>
<tabstop>comboBoxLayoutUnit</tabstop>
<tabstop>checkBoxLayoutWarningPiecesSuperposition</tabstop>
<tabstop>checkBoxLayoutWarningPiecesOutOfBound</tabstop>
</tabstops>
<resources>
<include location="share/resources/puzzleicon.qrc"/>

View file

@ -43,6 +43,255 @@ VPSheet::~VPSheet()
delete m_pieceList;
}
//---------------------------------------------------------------------------------------------------------------------
QSizeF VPSheet::GetTemplateSize(PaperSizeTemplate tmpl)
{
qreal height = 0;
qreal width = 0;
switch (tmpl)
{
case PaperSizeTemplate::A0:
width = UnitConvertor(841, Unit::Mm, Unit::Px);
height = UnitConvertor(1189, Unit::Mm, Unit::Px);
break;
case PaperSizeTemplate::A1:
width = UnitConvertor(594, Unit::Mm, Unit::Px);
height = UnitConvertor(841, Unit::Mm, Unit::Px);
break;
case PaperSizeTemplate::A2:
width = UnitConvertor(420, Unit::Mm, Unit::Px);
height = UnitConvertor(594, Unit::Mm, Unit::Px);
break;
case PaperSizeTemplate::A3:
width = UnitConvertor(297, Unit::Mm, Unit::Px);
height = UnitConvertor(420, Unit::Mm, Unit::Px);
break;
case PaperSizeTemplate::A4:
width = UnitConvertor(210, Unit::Mm, Unit::Px);
height = UnitConvertor(297, Unit::Mm, Unit::Px);
break;
case PaperSizeTemplate::Letter:
width = UnitConvertor(8.5, Unit::Inch, Unit::Px);
height = UnitConvertor(11, Unit::Inch, Unit::Px);
break;
case PaperSizeTemplate::Legal:
width = UnitConvertor(8.5, Unit::Inch, Unit::Px);
height = UnitConvertor(14, Unit::Inch, Unit::Px);
break;
case PaperSizeTemplate::Tabloid:
width = UnitConvertor(11, Unit::Inch, Unit::Px);
height = UnitConvertor(17, Unit::Inch, Unit::Px);
break;
case PaperSizeTemplate::Roll24in:
width = UnitConvertor(24, Unit::Inch, Unit::Px);
height = UnitConvertor(48, Unit::Inch, Unit::Px);
break;
case PaperSizeTemplate::Roll30in:
width = UnitConvertor(30, Unit::Inch, Unit::Px);
height = UnitConvertor(60, Unit::Inch, Unit::Px);
break;
case PaperSizeTemplate::Roll36in:
width = UnitConvertor(36, Unit::Inch, Unit::Px);
height = UnitConvertor(72, Unit::Inch, Unit::Px);
break;
case PaperSizeTemplate::Roll42in:
width = UnitConvertor(42, Unit::Inch, Unit::Px);
height = UnitConvertor(84, Unit::Inch, Unit::Px);
break;
case PaperSizeTemplate::Roll44in:
width = UnitConvertor(44, Unit::Inch, Unit::Px);
height = UnitConvertor(88, Unit::Inch, Unit::Px);
break;
case PaperSizeTemplate::Roll48in:
width = UnitConvertor(48, Unit::Inch, Unit::Px);
height = UnitConvertor(96, Unit::Inch, Unit::Px);
break;
case PaperSizeTemplate::Roll62in:
width = UnitConvertor(62, Unit::Inch, Unit::Px);
height = UnitConvertor(124, Unit::Inch, Unit::Px);
break;
case PaperSizeTemplate::Roll72in:
width = UnitConvertor(72, Unit::Inch, Unit::Px);
height = UnitConvertor(144, Unit::Inch, Unit::Px);
break;
default:
break;
}
return QSizeF(width, height);
}
//---------------------------------------------------------------------------------------------------------------------
QString VPSheet::GetTemplateName(PaperSizeTemplate tmpl)
{
QString tmplName;
switch (tmpl)
{
case PaperSizeTemplate::A0:
tmplName = QString("A0");
break;
case PaperSizeTemplate::A1:
tmplName = QString("A1");
break;
case PaperSizeTemplate::A2:
tmplName = QString("A2");
break;
case PaperSizeTemplate::A3:
tmplName = QString("A3");
break;
case PaperSizeTemplate::A4:
tmplName = QString("A4");
break;
case PaperSizeTemplate::Letter:
tmplName = tr("Letter");
break;
case PaperSizeTemplate::Legal:
tmplName = tr("Legal");
break;
case PaperSizeTemplate::Tabloid:
tmplName = tr("Tabloid");
break;
case PaperSizeTemplate::Roll24in:
tmplName = tr("Roll 24in");
break;
case PaperSizeTemplate::Roll30in:
tmplName = tr("Roll 30in");
break;
case PaperSizeTemplate::Roll36in:
tmplName = tr("Roll 36in");
break;
case PaperSizeTemplate::Roll42in:
tmplName = tr("Roll 42in");
break;
case PaperSizeTemplate::Roll44in:
tmplName = tr("Roll 44in");
break;
case PaperSizeTemplate::Roll48in:
tmplName = tr("Roll 48in");
break;
case PaperSizeTemplate::Roll62in:
tmplName = tr("Roll 62in");
break;
case PaperSizeTemplate::Roll72in:
tmplName = tr("Roll 72in");
break;
case PaperSizeTemplate::Custom:
tmplName = tr("Custom");
break;
default:
break;
}
if(not tmplName.isEmpty())
{
tmplName += " " + QStringLiteral("(%1ppi)").arg(PrintDPI);
}
return tmplName;
}
//---------------------------------------------------------------------------------------------------------------------
PaperSizeTemplate VPSheet::GetTemplate(QSizeF size)
{
Q_UNUSED(size);
// TODO, float comparision not safe and problems with
// inch / cm
// const int max = static_cast<int>(PaperSizeTemplate::Custom);
// for (int i=0; i < max; i++)
// {
// PaperSizeTemplate tmpl = static_cast<PaperSizeTemplate>(i);
// const QSizeF tmplSize = GetTemplateSize(tmpl);
// if(size.width() == tmplSize.width())
// {
// if(isRollTemplate(tmpl))
// {
// return tmpl;
// }
// else if(size.height() == tmplSize.height())
// {
// return tmpl;
// }
// }
// }
return PaperSizeTemplate::Custom;
}
//---------------------------------------------------------------------------------------------------------------------
bool VPSheet::isRollTemplate(PaperSizeTemplate tmpl)
{
switch (tmpl) {
case PaperSizeTemplate::Roll24in:
case PaperSizeTemplate::Roll30in:
case PaperSizeTemplate::Roll36in:
case PaperSizeTemplate::Roll42in:
case PaperSizeTemplate::Roll44in:
case PaperSizeTemplate::Roll48in:
case PaperSizeTemplate::Roll62in:
case PaperSizeTemplate::Roll72in:
return true;
default:
return false;
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPSheet::PopulateComboBox(QVector<PaperSizeTemplate> *tmpls, QComboBox* comboBox)
{
const QIcon icoPaper("://puzzleicon/16x16/template.png");
const QIcon icoRoll("://puzzleicon/16x16/roll.png");
QIcon icon;
for (auto tmpl : *tmpls)
{
icon = (isRollTemplate(tmpl))? icoRoll : icoPaper;
comboBox->addItem(icon, GetTemplateName(tmpl), QVariant(static_cast<int>(tmpl)));
}
}
//---------------------------------------------------------------------------------------------------------------------
VPLayout* VPSheet::GetLayout()
{
return m_layout;
}
//---------------------------------------------------------------------------------------------------------------------
VPPieceList* VPSheet::GetPieceList()
{

View file

@ -32,11 +32,36 @@
#include <QSizeF>
#include <QMarginsF>
#include <QList>
#include <QComboBox>
#include "def.h"
// is this the right place for the definition?
enum class FollowGrainline : qint8 { No = 0, Follow90 = 1, Follow180 = 2};
enum class FollowGrainline : qint8 {
No = 0,
Follow90 = 1,
Follow180 = 2
};
enum class PaperSizeTemplate : qint8 {
A0 = 0,
A1,
A2,
A3,
A4,
Letter,
Legal,
Tabloid,
Roll24in,
Roll30in,
Roll36in,
Roll42in,
Roll44in,
Roll48in,
Roll62in,
Roll72in,
Custom
};
class VPLayout;
class VPPieceList;
@ -45,10 +70,53 @@ class VPSheet : public QObject
{
Q_OBJECT
public:
explicit VPSheet(VPLayout* layout);
~VPSheet();
/**
* @brief GetTemplateSize Returns the size in Px of the given template
* @param tmpl
* @return the size in Px
*/
static QSizeF GetTemplateSize(PaperSizeTemplate tmpl);
/**
* @brief GetTemplateName Returns the name of the given template
* @param tmpl
* @return
*/
static QString GetTemplateName(PaperSizeTemplate tmpl);
/**
* @brief GetTemplate GetTemplate Returns the template that corresponds to the given size
* @param size the Size in Px
* @return
*/
static PaperSizeTemplate GetTemplate(QSizeF size);
/**
* @brief PopulateComboBox Populates the given combo with the given templates
* @param tmpls
* @param comboBox
*/
static void PopulateComboBox(QVector<PaperSizeTemplate> *tmpls, QComboBox* comboBox);
/**
* @brief isRollTemplate Returns wether the given template is a roll or not.
* @param tmpl
* @return
*/
static bool isRollTemplate(PaperSizeTemplate tmpl);
/**
* @brief GetLayout Returns the Layout of the sheet
* @return
*/
VPLayout* GetLayout();
/**
* @brief GetPieceList returns the piece list of the sheet
* @return piece list
@ -203,6 +271,7 @@ public:
void SetStickyEdges(bool state);
bool GetStickyEdges() const;
private:
Q_DISABLE_COPY(VPSheet)

View file

@ -0,0 +1,315 @@
#include "vptilefactory.h"
#include <QtSvg>
#include "../vwidgets/vmaingraphicsscene.h"
#include "vpsheet.h"
#include "vpmaingraphicsview.h"
//---------------------------------------------------------------------------------------------------------------------
VPTileFactory::VPTileFactory(VPLayout *layout, VCommonSettings *commonSettings):
m_layout(layout),
m_commonSettings(commonSettings)
{
m_infoStripeWidth = UnitConvertor(1, Unit::Cm, Unit::Px);
}
//---------------------------------------------------------------------------------------------------------------------
VPTileFactory::~VPTileFactory()
{
}
//---------------------------------------------------------------------------------------------------------------------
void VPTileFactory::refreshTileInfos()
{
if(m_layout != nullptr)
{
PageOrientation tilesOrientation = m_layout->GetTilesOrientation();
QSizeF tilesSize = m_layout->GetTilesSize();
QMarginsF tilesMargins = m_layout->GetTilesMargins();
// sets the drawing height
m_drawingAreaHeight = (tilesOrientation == PageOrientation::Portrait)?
tilesSize.height() : tilesSize.width();
m_drawingAreaHeight -=
tilesMargins.top() + tilesMargins.bottom() + m_infoStripeWidth;
// sets the drawing width
m_drawingAreaWidth = (tilesOrientation == PageOrientation::Portrait)?
tilesSize.width() : tilesSize.height();
m_drawingAreaWidth -=
tilesMargins.left() + tilesMargins.right() + m_infoStripeWidth;
QSizeF sheetSize = m_layout->GetFocusedSheet()->GetSheetSize();
qreal totalDrawingWidth = 0;
qreal totaldrawingHeight = 0;
if(m_layout->GetFocusedSheet()->GetOrientation() == PageOrientation::Portrait)
{
totalDrawingWidth = sheetSize.width();
totaldrawingHeight = sheetSize.height();
}
else
{
totalDrawingWidth = sheetSize.height();
totaldrawingHeight = sheetSize.width();
}
m_nbCol = qCeil(totalDrawingWidth/m_drawingAreaWidth);
m_nbRow = qCeil(totaldrawingHeight/m_drawingAreaHeight);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPTileFactory::drawTile(QPainter *painter, VPMainGraphicsView *graphicsView, int row, int col)
{
QMarginsF tilesMargins = m_layout->GetTilesMargins();
QPen penTileInfos = QPen(QColor(180,180,180), m_commonSettings->WidthHairLine(), Qt::DashLine, Qt::RoundCap, Qt::RoundJoin);
QPen penTileDrawing = QPen(Qt::black, m_commonSettings->WidthMainLine(), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
QSvgRenderer* svgRenderer = new QSvgRenderer();
// ------------- prepare triangles for position marks
QRectF rectBasic = QRectF(-UnitConvertor(0.5, Unit::Cm, Unit::Px),
0,
UnitConvertor(1, Unit::Cm, Unit::Px),
UnitConvertor(0.5, Unit::Cm, Unit::Px)
);
QPainterPath triangleBasic;
triangleBasic.moveTo(rectBasic.topLeft());
triangleBasic.lineTo(rectBasic.topRight());
triangleBasic.lineTo(rectBasic.left() + (rectBasic.width() / 2), rectBasic.bottom());
triangleBasic.lineTo(rectBasic.topLeft());
QBrush triangleBush = QBrush(QColor(200,200,200));
// add the tiles decorations (cutting and gluing lines, scissors, infos etc.)
painter->setPen(penTileInfos);
if(row > 0)
{
// add top triangle
QPainterPath triangleTop =
QTransform()
.translate(tilesMargins.left()+m_drawingAreaWidth/2, tilesMargins.top())
.map(triangleBasic);
painter->fillPath(triangleTop, triangleBush);
// scissors along the top line
svgRenderer->load(QStringLiteral("://puzzleicon/svg/icon_scissors_horizontal.svg"));
svgRenderer->render(painter, QRectF(tilesMargins.left() + m_drawingAreaWidth,
tilesMargins.top(),
UnitConvertor(1, Unit::Cm, Unit::Px),
UnitConvertor(0.56, Unit::Cm, Unit::Px)
));
// dashed top line (for cutting)
penTileInfos.setStyle(Qt::DashLine);
painter->setPen(penTileInfos);
painter->drawLine(QPointF(tilesMargins.left(),
tilesMargins.top()),
QPointF(tilesMargins.left() + m_drawingAreaWidth + m_infoStripeWidth,
tilesMargins.top())
);
}
else
{
// solid top line stopping at the edge
penTileInfos.setStyle(Qt::SolidLine);
painter->setPen(penTileInfos);
painter->drawLine(QPointF(tilesMargins.left(),
tilesMargins.top()),
QPointF(tilesMargins.left() + m_drawingAreaWidth + ((col < m_nbCol-1)? m_infoStripeWidth : 0),
tilesMargins.top())
);
}
if(col > 0)
{
// add left triangle
QPainterPath triangleLeft =
QTransform()
.translate(tilesMargins.left(), tilesMargins.top()+ m_drawingAreaHeight/2)
.rotate(-90)
.map(triangleBasic);
painter->fillPath(triangleLeft, triangleBush);
// scissors along the left line
svgRenderer->load(QStringLiteral("://puzzleicon/svg/icon_scissors_vertical.svg"));
svgRenderer->render(painter, QRectF(tilesMargins.left(),
tilesMargins.top()+m_drawingAreaHeight,
UnitConvertor(0.56, Unit::Cm, Unit::Px),
UnitConvertor(1, Unit::Cm, Unit::Px)
));
// dashed left line (for cutting)
penTileInfos.setStyle(Qt::DashLine);
painter->setPen(penTileInfos);
painter->drawLine(QPointF(tilesMargins.left(),
tilesMargins.top()),
QPointF(tilesMargins.left(),
tilesMargins.top() + m_drawingAreaHeight + m_infoStripeWidth)
);
}
else
{
// solid left line at the edge
penTileInfos.setStyle(Qt::SolidLine);
painter->setPen(penTileInfos);
painter->drawLine(QPointF(tilesMargins.left(),
tilesMargins.top()),
QPointF(tilesMargins.left(),
tilesMargins.top() + m_drawingAreaHeight + ((row < m_nbRow-1)? m_infoStripeWidth : 0))
);
}
if(row < m_nbRow-1)
{
// add bottom triangle
QPainterPath triangleBottom =
QTransform()
.translate(tilesMargins.left()+ m_drawingAreaWidth/2, tilesMargins.top()+ m_drawingAreaHeight)
.rotate(180)
.map(triangleBasic);
painter->fillPath(triangleBottom, triangleBush);
// dotted bottom line (for glueing)
penTileInfos.setStyle(Qt::DotLine);
painter->setPen(penTileInfos);
painter->drawLine(QPointF(tilesMargins.left(),
tilesMargins.top() + m_drawingAreaHeight),
QPointF(tilesMargins.left() + m_drawingAreaWidth + m_infoStripeWidth,
tilesMargins.top() + m_drawingAreaHeight)
);
} else
{
// solid bottom line at the edge
penTileInfos.setStyle(Qt::SolidLine);
painter->setPen(penTileInfos);
painter->drawLine(QPointF(tilesMargins.left(),
tilesMargins.top() + m_drawingAreaHeight),
QPointF(tilesMargins.left() + m_drawingAreaWidth + ((col < m_nbCol-1)? m_infoStripeWidth : 0),
tilesMargins.top() + m_drawingAreaHeight)
);
}
if(col < m_nbCol-1)
{
// add right triangle
QPainterPath triangleRight =
QTransform()
.translate(tilesMargins.left()+ m_drawingAreaWidth, tilesMargins.top()+ m_drawingAreaHeight/2)
.rotate(90)
.map(triangleBasic);
painter->fillPath(triangleRight, triangleBush);
// dotted right line (for glueing)
penTileInfos.setStyle(Qt::DotLine);
painter->setPen(penTileInfos);
painter->drawLine(QPointF(tilesMargins.left() + m_drawingAreaWidth,
tilesMargins.top()),
QPointF(tilesMargins.left() + m_drawingAreaWidth,
tilesMargins.top()+ m_drawingAreaHeight + m_infoStripeWidth)
);
}
else
{
// solid right line at the edge
penTileInfos.setStyle(Qt::SolidLine);
painter->setPen(penTileInfos);
painter->drawLine(QPointF(tilesMargins.left() + m_drawingAreaWidth,
tilesMargins.top()),
QPointF(tilesMargins.left() + m_drawingAreaWidth,
tilesMargins.top()+ m_drawingAreaHeight + ((row < m_nbRow-1) ? m_infoStripeWidth : 0))
);
}
// paint the content of the page
QRectF source = QRectF(col*m_drawingAreaWidth,
row*m_drawingAreaHeight,
m_drawingAreaWidth + m_infoStripeWidth,
m_drawingAreaHeight + m_infoStripeWidth
);
QRectF target = QRectF(tilesMargins.left(),
tilesMargins.top(),
source.width(),
source.height()
);
painter->setPen(penTileDrawing);
graphicsView->GetScene()->render(painter, target, source, Qt::IgnoreAspectRatio);
// prepare the painting for the text information
QTextDocument td;
td.setPageSize(QSizeF(
m_drawingAreaWidth - UnitConvertor(2, Unit::Cm, Unit::Px),
m_drawingAreaHeight
));
// paint the grid information
const QString grid = tr("Grid ( %1 , %2 )").arg(row+1).arg(col+1);
td.setHtml(QString("<table width='100%' style='color:rgb(180,180,180);'>"
"<tr>"
"<td align='center'>%1</td>"
"</tr>"
"</table>")
.arg(grid));
painter->setPen(penTileInfos);
painter->save();
painter->translate(QPointF(tilesMargins.left()+ UnitConvertor(1, Unit::Cm, Unit::Px),
m_drawingAreaHeight + tilesMargins.top()
));
td.drawContents(painter);
painter->restore();
// paint the page information
const QString page = tr("Page %1 of %2").arg(row*m_nbCol+col+1).arg(m_nbCol*m_nbRow);
td.setPageSize(QSizeF(m_drawingAreaHeight - UnitConvertor(2, Unit::Cm, Unit::Px), m_drawingAreaWidth));
td.setHtml(QString("<table width='100%' style='color:rgb(180,180,180);'>"
"<tr>"
"<td align='center'>%1 - %2</td>"
"</tr>"
"</table>")
.arg(page).arg(m_layout->GetFocusedSheet()->GetName()));
painter->save();
painter->rotate(-90);
painter->translate(QPointF(-(m_drawingAreaHeight+tilesMargins.top()) + UnitConvertor(1, Unit::Cm, Unit::Px),
m_drawingAreaWidth + tilesMargins.left()
));
td.drawContents(painter);
painter->restore();
}
//---------------------------------------------------------------------------------------------------------------------
int VPTileFactory::getRowNb()
{
return m_nbRow;
}
//---------------------------------------------------------------------------------------------------------------------
int VPTileFactory::getColNb()
{
return m_nbCol;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VPTileFactory::getDrawingAreaHeight()
{
return m_drawingAreaHeight;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VPTileFactory::getDrawingAreaWidth()
{
return m_drawingAreaWidth;
}

View file

@ -0,0 +1,121 @@
/************************************************************************
**
** @file vptilefactory.h
** @author Ronan Le Tiec
** @date 19 11, 2020
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2020 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina 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 Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VPTILEFACTORY_H
#define VPTILEFACTORY_H
#include <QtMath>
#include <QObject>
#include "vplayout.h"
#include "../vmisc/def.h"
#include "vcommonsettings.h"
class VPMainGraphicsView;
class VPTileFactory : QObject
{
Q_OBJECT
public:
VPTileFactory(VPLayout *layout, VCommonSettings *settings);
~VPTileFactory();
/**
* @brief drawTile draws the tile of given coordinate (row, col) from the
* current sheet of the layout with the given painter
* @param painter
* @param row
* @param col
*/
void drawTile(QPainter *painter, VPMainGraphicsView *graphicsView, int row, int col);
/**
* @brief refreshTileInfos Resfreshes the tile infos (m_nbCol, m_nbRow, m_drawingAreaHeight, m_drawingAreaWidth)
*/
void refreshTileInfos();
/**
* @brief getRowNb Returns the number of row pages
* @return
*/
int getRowNb();
/**
* @brief getColNb Returns the number of col pages
* @return
*/
int getColNb();
/**
* @brief getDrawingAreaHeight Returns the usable height of the tile in Px
* @return
*/
qreal getDrawingAreaHeight();
/**
* @brief getDrawingAreaWidth Returns the usable width of the tile in Px
* @return
*/
qreal getDrawingAreaWidth();
private:
Q_DISABLE_COPY(VPTileFactory)
VPLayout *m_layout{nullptr};
VCommonSettings *m_commonSettings{nullptr};
/**
* @brief m_nbCol the number of column-pages for the current sheet of the layout
*/
int m_nbCol{0};
/**
* @brief m_nbRow the number of row-pages for the current sheet of the layout
*/
int m_nbRow{0};
/**
* @brief m_drawingAreaHeight the height of the drawing area
*/
qreal m_drawingAreaHeight{0};
/**
* @brief m_drawingAreaWidth the width of the drawing area
*/
qreal m_drawingAreaWidth{0};
/**
* @brief m_infoStripeWidth the width of the info / glueing stripe in Px
*/
qreal m_infoStripeWidth{0};
};
#endif // VPTILEFACTORY_H