Merge pull request #1549 from MarcelP102/codex/graphic-attributes-cleanup

[UX] Introducing graphic attributes panel

# Conflicts:
#	locales/ar-SA/opencadstudio.ftl
#	locales/bg-BG/opencadstudio.ftl
#	locales/cs-CZ/opencadstudio.ftl
#	locales/de-DE/opencadstudio.ftl
#	locales/el-GR/opencadstudio.ftl
#	locales/en-US/opencadstudio.ftl
#	locales/es-ES/opencadstudio.ftl
#	locales/fi-FI/opencadstudio.ftl
#	locales/fr-FR/opencadstudio.ftl
#	locales/hi-IN/opencadstudio.ftl
#	locales/hu-HU/opencadstudio.ftl
#	locales/it-IT/opencadstudio.ftl
#	locales/ja-JP/opencadstudio.ftl
#	locales/ko-KR/opencadstudio.ftl
#	locales/lo-LA/opencadstudio.ftl
#	locales/nl-NL/opencadstudio.ftl
#	locales/pl-PL/opencadstudio.ftl
#	locales/pt-BR/opencadstudio.ftl
#	locales/ru-RU/opencadstudio.ftl
#	locales/tr-TR/opencadstudio.ftl
#	locales/zh-CN/opencadstudio.ftl
#	locales/zh-TW/opencadstudio.ftl
#	src/app/mod.rs
#	src/app/update/dialog.rs
#	src/app/view/mod.rs
#	src/locale_catalog.rs
#	src/ui/dock.rs
This commit is contained in:
Hakan Seven committed 2026-10-12 00:49:27 +03:00
commit 1333efcad2
68 files changed
+6178 -173

No files matched your search

+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="#B4B6B9"
stroke-width="1.8"
stroke-linecap="round"
stroke-linejoin="round"
version="1.1"
id="svg3"
sodipodi:docname="lineweight.svg"
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs3" />
<sodipodi:namedview
id="namedview3"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="6.0364583"
inkscape:cx="-23.606557"
inkscape:cy="-24.434858"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3" />
<path
d="M 0,0.75 H 24.000001"
stroke-width="1.1"
id="path1"
style="stroke-width:1.5;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none" />
<path
d="M 0,5 H 24.000002"
stroke-width="2.4"
id="path2-6-6"
style="stroke-width:3;stroke-linecap:butt;stroke-dasharray:none" />
<path
d="m 2e-6,11.75 h 24"
stroke-width="2.4"
id="path2-6-2-1"
style="stroke-width:5.5;stroke-linecap:butt;stroke-miterlimit:0;stroke-dasharray:none" />
<path
d="M 0,20.5 H 24"
stroke-width="2.4"
id="path2-6-2-1-6"
style="stroke-width:7;stroke-linecap:butt;stroke-miterlimit:0;stroke-dasharray:none" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

+50
View File
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="#B4B6B9"
stroke-width="1.8"
stroke-linecap="round"
stroke-linejoin="round"
version="1.1"
id="svg1"
sodipodi:docname="transparency.svg"
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="34.147365"
inkscape:cx="13.368528"
inkscape:cy="10.527899"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<rect
x="0.89999998"
y="0.89999998"
width="22.200001"
height="22.200001"
id="rect1"
style="stroke-width:1.8;stroke-dasharray:none" />
<path
d="M 0.89999998,0.89999998 H 12 V 12 H 0.89999998 Z M 12,12 H 23.1 V 23.1 H 12 Z"
fill="#b4b6b9"
stroke="none"
id="path1"
style="stroke-width:1.8" />
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

+135
View File
@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
width="64"
height="64"
version="1.1"
id="svg3"
sodipodi:docname="gradient_curved.svg"
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3"
pagecolor="#B4B6B9"
bordercolor="#B4B6B9"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#B4B6B9"
inkscape:zoom="1.9394531"
inkscape:cx="49.240685"
inkscape:cy="-85.333334"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3" />
<defs
id="defs2">
<linearGradient
id="g"
x1="4"
y1="4"
x2="20"
y2="4"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(22.421511,-1.7454447)"
inkscape:label="0">
<stop
offset="0"
stop-color="#6DB7ED"
stop-opacity="0.9"
id="stop1"
style="stop-color:#B4B6B9;stop-opacity:1;" />
<stop
offset="1"
stop-color="#6DB7ED"
stop-opacity="0.0"
id="stop2"
style="stop-color:#B4B6B9;stop-opacity:0;" />
</linearGradient>
<radialGradient
id="domeColor"
cx="425.3569"
cy="810.08398"
r="487.05515"
fx="425.3569"
fy="810.08398"
gradientTransform="matrix(0.63134428,7.5044275e-5,-0.00132862,0.0415918,-254.82322,-32.945166)"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
stop-color="#B4B6B9"
id="stop1-3"
style="stop-color:#6DB7ED;stop-opacity:1;" />
<stop
offset="1"
stop-color="#B4B6B9"
id="stop6"
style="stop-color:#B4B6B9;stop-opacity:1;" />
</radialGradient>
<radialGradient
id="domeColor-6"
cx="425.3569"
cy="810.08398"
r="487.05515"
fx="425.3569"
fy="810.08398"
gradientTransform="matrix(0.04040603,7.8734977e-5,-8.5031467e-5,0.0436373,5.7983172,-63.225256)"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
stop-color="#B4B6B9"
id="stop1-7"
style="stop-color:#B4B6B9;stop-opacity:0.29402253;" />
<stop
offset="1"
stop-color="#B4B6B9"
id="stop6-5"
style="stop-color:#B4B6B9;stop-opacity:1;" />
</radialGradient>
<radialGradient
id="domeColor-5"
cx="425.3569"
cy="810.08398"
r="487.05515"
fx="425.3569"
fy="810.08398"
gradientTransform="matrix(0.038512,7.5044275e-5,-8.1045617e-5,0.0415918,-4.2762155,-8.9451656)"
gradientUnits="userSpaceOnUse">
<stop
offset="0.2"
stop-color="#B4B6B9"
id="stop1-3-6"
style="stop-color:#B4B6B9;stop-opacity:1;" />
<stop
offset="1"
stop-color="#B4B6B9"
id="stop6-2"
style="stop-color:#B4B6B9;stop-opacity:1;" />
</radialGradient>
</defs>
<rect
x="-175.5"
y="-23.4375"
width="375"
height="22.875"
fill="url(#domeColor)"
id="rect15"
style="fill:url(#domeColor);stroke:none;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
transform="rotate(90)" />
<rect
x="0.5625"
y="-23.4375"
width="22.875"
height="22.875"
fill="url(#domeColor)"
id="rect15-1"
style="fill:none;stroke:#b4b6b9;stroke-width:1.125;stroke-dasharray:none;stroke-opacity:1"
transform="rotate(90)" />
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

@@ -0,0 +1,155 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
width="64"
height="64"
version="1.1"
id="svg3"
sodipodi:docname="gradient_curved_inverted.svg"
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3"
pagecolor="#B4B6B9"
bordercolor="#B4B6B9"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#B4B6B9"
inkscape:zoom="0.68570022"
inkscape:cx="-67.813891"
inkscape:cy="-212.19185"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3" />
<defs
id="defs2">
<linearGradient
id="g"
x1="4"
y1="4"
x2="20"
y2="4"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(22.421511,-1.7454447)"
inkscape:label="0">
<stop
offset="0"
stop-color="#6DB7ED"
stop-opacity="0.9"
id="stop1"
style="stop-color:#B4B6B9;stop-opacity:1;" />
<stop
offset="1"
stop-color="#6DB7ED"
stop-opacity="0.0"
id="stop2"
style="stop-color:#B4B6B9;stop-opacity:0;" />
</linearGradient>
<radialGradient
id="domeColor"
cx="425.3569"
cy="810.08398"
r="487.05515"
fx="425.3569"
fy="810.08398"
gradientTransform="matrix(0.63134428,7.5044275e-5,-0.00132862,0.0415918,-254.82322,-8.9451655)"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
stop-color="#B4B6B9"
id="stop1-3"
style="stop-color:#B4B6B9;stop-opacity:0.29402253;" />
<stop
offset="1"
stop-color="#B4B6B9"
id="stop6"
style="stop-color:#B4B6B9;stop-opacity:1;" />
</radialGradient>
<radialGradient
id="domeColor-6"
cx="425.3569"
cy="810.08398"
r="487.05515"
fx="425.3569"
fy="810.08398"
gradientTransform="matrix(0.04040603,7.8734977e-5,-8.5031467e-5,0.0436373,5.7983172,-63.225256)"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
stop-color="#B4B6B9"
id="stop1-7"
style="stop-color:#B4B6B9;stop-opacity:0.29402253;" />
<stop
offset="1"
stop-color="#B4B6B9"
id="stop6-5"
style="stop-color:#B4B6B9;stop-opacity:1;" />
</radialGradient>
<radialGradient
id="domeColor-5"
cx="425.3569"
cy="810.08398"
r="487.05515"
fx="425.3569"
fy="810.08398"
gradientTransform="matrix(0.038512,7.5044275e-5,-8.1045617e-5,0.0415918,-4.2762155,-8.9451656)"
gradientUnits="userSpaceOnUse">
<stop
offset="0.2"
stop-color="#B4B6B9"
id="stop1-3-6"
style="stop-color:#B4B6B9;stop-opacity:1;" />
<stop
offset="1"
stop-color="#B4B6B9"
id="stop6-2"
style="stop-color:#B4B6B9;stop-opacity:1;" />
</radialGradient>
<radialGradient
id="domeColor-2"
cx="425.3569"
cy="810.08398"
r="487.05515"
fx="425.3569"
fy="810.08398"
gradientTransform="matrix(0.63134425,7.5044275e-5,-0.00132862,0.0415918,-254.8232,-32.945166)"
gradientUnits="userSpaceOnUse">
<stop
offset="0.2"
stop-color="#B4B6B9"
id="stop1-3-7"
style="stop-color:#B4B6B9;stop-opacity:1;" />
<stop
offset="1"
stop-color="#B4B6B9"
id="stop6-0"
style="stop-color:#6DB7ED;stop-opacity:1;" />
</radialGradient>
</defs>
<rect
x="-175.5"
y="-23.4375"
width="375"
height="22.875"
fill="url(#domeColor)"
id="rect15"
style="fill:url(#domeColor-2);stroke:none;stroke-width:1.125;stroke-dasharray:none;stroke-opacity:1"
transform="rotate(90)" />
<rect
x="0.5625"
y="-23.4375"
width="22.875"
height="22.875"
fill="url(#domeColor)"
id="rect15-1"
style="fill:none;stroke:#b4b6b9;stroke-width:1.125;stroke-dasharray:none;stroke-opacity:1"
transform="rotate(90)" />
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
width="64"
height="64"
version="1.1"
id="svg3"
sodipodi:docname="gradient_cylindrical_inverted.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3"
pagecolor="#B4B6B9"
bordercolor="#B4B6B9"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#B4B6B9"
inkscape:zoom="4.5273438"
inkscape:cx="-35.451251"
inkscape:cy="6.2950819"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3" />
<defs
id="defs2">
<linearGradient
id="linearGradient15"
inkscape:collect="always">
<stop
style="stop-color:#6DB7ED;stop-opacity:1;"
offset="0"
id="stop15" />
<stop
style="stop-color:#B4B6B9;stop-opacity:1;"
offset="0.47"
id="stop17" />
<stop
style="stop-color:#B4B6B9;stop-opacity:1;"
offset="0.52999997"
id="stop18" />
<stop
style="stop-color:#6DB7ED;stop-opacity:1;"
offset="1"
id="stop16" />
</linearGradient>
<linearGradient
id="g"
x1="4"
y1="4"
x2="20"
y2="4"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(22.421511,-1.7454447)"
inkscape:label="0">
<stop
offset="0"
stop-color="#6DB7ED"
stop-opacity="0.9"
id="stop1"
style="stop-color:#B4B6B9;stop-opacity:1;" />
<stop
offset="1"
stop-color="#6DB7ED"
stop-opacity="0.0"
id="stop2"
style="stop-color:#B4B6B9;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient15"
id="linearGradient16"
x1="0"
y1="12"
x2="24"
y2="12"
gradientUnits="userSpaceOnUse" />
</defs>
<rect
x="0.5625"
y="0.5625"
width="22.875"
height="22.875"
stroke="#B4B6B9"
stroke-width="1.5"
fill="none"
id="rect3"
style="fill:url(#linearGradient16);stroke-width:1.125;stroke-dasharray:none;stroke:#B4B6B9;stroke-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
width="64"
height="64"
version="1.1"
id="svg3"
sodipodi:docname="gradient_cylindrical.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3"
pagecolor="#B4B6B9"
bordercolor="#B4B6B9"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#B4B6B9"
inkscape:zoom="4.5273438"
inkscape:cx="-35.451251"
inkscape:cy="6.2950819"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3" />
<defs
id="defs2">
<linearGradient
id="linearGradient15"
inkscape:collect="always">
<stop
style="stop-color:#B4B6B9;stop-opacity:1;"
offset="0"
id="stop15" />
<stop
style="stop-color:#6DB7ED;stop-opacity:1;"
offset="0.47"
id="stop17" />
<stop
style="stop-color:#6DB7ED;stop-opacity:1;"
offset="0.52999997"
id="stop18" />
<stop
style="stop-color:#B4B6B9;stop-opacity:1;"
offset="0.99787325"
id="stop16" />
</linearGradient>
<linearGradient
id="g"
x1="4"
y1="4"
x2="20"
y2="4"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(22.421511,-1.7454447)"
inkscape:label="0">
<stop
offset="0"
stop-color="#6DB7ED"
stop-opacity="0.9"
id="stop1"
style="stop-color:#B4B6B9;stop-opacity:1;" />
<stop
offset="1"
stop-color="#6DB7ED"
stop-opacity="0.0"
id="stop2"
style="stop-color:#B4B6B9;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient15"
id="linearGradient16"
x1="0"
y1="12"
x2="24"
y2="12"
gradientUnits="userSpaceOnUse" />
</defs>
<rect
x="0.5625"
y="0.5625"
width="22.875"
height="22.875"
stroke="#B4B6B9"
stroke-width="1.5"
fill="none"
id="rect3"
style="fill:url(#linearGradient16);stroke-width:1.125;stroke-dasharray:none;stroke:#B4B6B9;stroke-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
width="64"
height="64"
version="1.1"
id="svg3"
sodipodi:docname="gradient_hemispherical.svg"
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3"
pagecolor="#B4B6B9"
bordercolor="#B4B6B9"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#B4B6B9"
inkscape:zoom="6.4026309"
inkscape:cx="14.759558"
inkscape:cy="17.25853"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3" />
<defs
id="defs2">
<linearGradient
id="linearGradient4"
inkscape:collect="always">
<stop
style="stop-color:#B4B6B9;stop-opacity:1;"
offset="0"
id="stop4" />
<stop
style="stop-color:#6DB7ED;stop-opacity:1;"
offset="0.69999999"
id="stop5" />
</linearGradient>
<linearGradient
id="g"
x1="4"
y1="4"
x2="20"
y2="4"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(22.421511,-1.7454447)"
inkscape:label="0">
<stop
offset="0"
stop-color="#6DB7ED"
stop-opacity="0.9"
id="stop1"
style="stop-color:#B4B6B9;stop-opacity:1;" />
<stop
offset="1"
stop-color="#6DB7ED"
stop-opacity="0.0"
id="stop2"
style="stop-color:#B4B6B9;stop-opacity:0;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4"
id="radialGradient7"
cx="12"
cy="12"
fx="12"
fy="12"
r="12"
gradientUnits="userSpaceOnUse" />
</defs>
<rect
x="0.5625"
y="0.5625"
width="22.875"
height="22.875"
stroke="#B4B6B9"
stroke-width="1.5"
fill="none"
id="rect3"
style="fill:url(#radialGradient7);stroke-width:1.125;stroke-dasharray:none;fill-opacity:1;stroke:#B4B6B9;stroke-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
width="64"
height="64"
version="1.1"
id="svg3"
sodipodi:docname="gradient_hemispherical_inverted.svg"
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3"
pagecolor="#B4B6B9"
bordercolor="#B4B6B9"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#B4B6B9"
inkscape:zoom="6.4026309"
inkscape:cx="14.759558"
inkscape:cy="17.25853"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3" />
<defs
id="defs2">
<linearGradient
id="linearGradient4"
inkscape:collect="always">
<stop
style="stop-color:#6db7ed;stop-opacity:1;"
offset="0"
id="stop5" />
<stop
style="stop-color:#b4b6b9;stop-opacity:0.25348836;"
offset="0.51998693"
id="stop4" />
</linearGradient>
<linearGradient
id="g"
x1="4"
y1="4"
x2="20"
y2="4"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(22.421511,-1.7454447)"
inkscape:label="0">
<stop
offset="0"
stop-color="#6DB7ED"
stop-opacity="0.9"
id="stop1"
style="stop-color:#B4B6B9;stop-opacity:1;" />
<stop
offset="1"
stop-color="#6DB7ED"
stop-opacity="0.0"
id="stop2"
style="stop-color:#B4B6B9;stop-opacity:0;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4"
id="radialGradient7"
cx="12"
cy="12"
fx="12"
fy="12"
r="12"
gradientUnits="userSpaceOnUse" />
</defs>
<rect
x="0.5625"
y="0.5625"
width="22.875"
height="22.875"
stroke="#B4B6B9"
stroke-width="1.5"
fill="none"
id="rect3-3"
style="fill:#b4b6b9;fill-opacity:1;stroke:#b4b6b9;stroke-width:1.125;stroke-dasharray:none;stroke-opacity:1" />
<rect
x="0.5625"
y="0.5625"
width="22.875"
height="22.875"
stroke="#B4B6B9"
stroke-width="1.5"
fill="none"
id="rect3"
style="fill:url(#radialGradient7);stroke-width:1.125;stroke-dasharray:none;fill-opacity:1;stroke:#B4B6B9;stroke-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

+89
View File
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
width="64"
height="64"
version="1.1"
id="svg3"
sodipodi:docname="gradient_linear.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3"
pagecolor="#B4B6B9"
bordercolor="#B4B6B9"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#B4B6B9"
inkscape:zoom="6.4026309"
inkscape:cx="14.759558"
inkscape:cy="17.25853"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3" />
<defs
id="defs2">
<linearGradient
id="linearGradient4"
inkscape:collect="always">
<stop
style="stop-color:#6DB7ED;stop-opacity:1;"
offset="0"
id="stop5" />
<stop
style="stop-color:#B4B6B9;stop-opacity:1;"
offset="0.85000002"
id="stop4" />
</linearGradient>
<linearGradient
id="g"
x1="4"
y1="4"
x2="20"
y2="4"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(22.421511,-1.7454447)"
inkscape:label="0">
<stop
offset="0"
stop-color="#6DB7ED"
stop-opacity="0.9"
id="stop1"
style="stop-color:#B4B6B9;stop-opacity:1;" />
<stop
offset="1"
stop-color="#6DB7ED"
stop-opacity="0.0"
id="stop2"
style="stop-color:#B4B6B9;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4"
id="linearGradient7"
x1="0"
y1="12"
x2="24"
y2="12"
gradientUnits="userSpaceOnUse" />
</defs>
<rect
x="0.5625"
y="0.5625"
width="22.875"
height="22.875"
stroke="#B4B6B9"
stroke-width="1.5"
fill="none"
id="rect3"
style="fill:url(#linearGradient7);stroke-width:1.125;stroke-dasharray:none;fill-opacity:1;stroke:#B4B6B9;stroke-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
width="64"
height="64"
version="1.1"
id="svg3"
sodipodi:docname="gradient_spherical.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3"
pagecolor="#B4B6B9"
bordercolor="#B4B6B9"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#B4B6B9"
inkscape:zoom="6.4026309"
inkscape:cx="14.759558"
inkscape:cy="17.25853"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3" />
<defs
id="defs2">
<linearGradient
id="linearGradient4"
inkscape:collect="always">
<stop
style="stop-color:#B4B6B9;stop-opacity:1;"
offset="0.30000001"
id="stop4" />
<stop
style="stop-color:#6DB7ED;stop-opacity:1;"
offset="0.94999999"
id="stop5" />
</linearGradient>
<linearGradient
id="g"
x1="4"
y1="4"
x2="20"
y2="4"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(22.421511,-1.7454447)"
inkscape:label="0">
<stop
offset="0"
stop-color="#6DB7ED"
stop-opacity="0.9"
id="stop1"
style="stop-color:#B4B6B9;stop-opacity:1;" />
<stop
offset="1"
stop-color="#6DB7ED"
stop-opacity="0.0"
id="stop2"
style="stop-color:#B4B6B9;stop-opacity:0;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4"
id="radialGradient7"
cx="12"
cy="12"
fx="12"
fy="12"
r="12"
gradientUnits="userSpaceOnUse" />
</defs>
<rect
x="0.5625"
y="0.5625"
width="22.875"
height="22.875"
stroke="#B4B6B9"
stroke-width="1.5"
fill="none"
id="rect3"
style="fill:url(#radialGradient7);stroke-width:1.125;stroke-dasharray:none;fill-opacity:1;stroke:#B4B6B9;stroke-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
width="64"
height="64"
version="1.1"
id="svg3"
sodipodi:docname="gradient_spherical_inverted.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3"
pagecolor="#B4B6B9"
bordercolor="#B4B6B9"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#B4B6B9"
inkscape:zoom="6.4026309"
inkscape:cx="14.759558"
inkscape:cy="17.25853"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3" />
<defs
id="defs2">
<linearGradient
id="linearGradient4"
inkscape:collect="always">
<stop
style="stop-color:#6DB7ED;stop-opacity:1;"
offset="0.29615885"
id="stop5" />
<stop
style="stop-color:#B4B6B9;stop-opacity:1;"
offset="0.95343965"
id="stop4" />
</linearGradient>
<linearGradient
id="g"
x1="4"
y1="4"
x2="20"
y2="4"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(22.421511,-1.7454447)"
inkscape:label="0">
<stop
offset="0"
stop-color="#6DB7ED"
stop-opacity="0.9"
id="stop1"
style="stop-color:#B4B6B9;stop-opacity:1;" />
<stop
offset="1"
stop-color="#6DB7ED"
stop-opacity="0.0"
id="stop2"
style="stop-color:#B4B6B9;stop-opacity:0;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4"
id="radialGradient7"
cx="12"
cy="12"
fx="12"
fy="12"
r="12"
gradientUnits="userSpaceOnUse" />
</defs>
<rect
x="0.5625"
y="0.5625"
width="22.875"
height="22.875"
stroke="#B4B6B9"
stroke-width="1.5"
fill="none"
id="rect3"
style="fill:url(#radialGradient7);stroke-width:1.125;stroke-dasharray:none;fill-opacity:1;stroke:#B4B6B9;stroke-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

+6
View File
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-label="Graphic Attributes">
<rect x="4.25" y="3.75" width="15.5" height="16.5" rx="1.75" fill="none" stroke="#B4B6B9" stroke-width="1.5"/>
<path d="M7 8h10M7 12h4" fill="none" stroke="#B4B6B9" stroke-width="1.5" stroke-linecap="round"/>
<rect x="7" y="15" width="10" height="2.5" rx="0.75" fill="#6DB7ED"/>
<path d="M13 11.25h4v1.5h-4z" fill="#6DB7ED"/>
</svg>

After

Width:  |  Height:  |  Size: 445 B

+84 -7
View File
@@ -1,10 +1,87 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="64" height="64">
<defs>
<linearGradient id="g" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#6DB7ED" stop-opacity="0.9"/>
<stop offset="100%" stop-color="#6DB7ED" stop-opacity="0.0"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
width="64"
height="64"
version="1.1"
id="svg3"
sodipodi:docname="hatch_gradient.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3"
pagecolor="#B4B6B9"
bordercolor="#B4B6B9"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#B4B6B9"
inkscape:zoom="15.601563"
inkscape:cx="22.401602"
inkscape:cy="32.849273"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3" />
<defs
id="defs2">
<linearGradient
id="g"
x1="4"
y1="4"
x2="20"
y2="4"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(22.421511,-1.7454447)">
<stop
offset="0%"
stop-color="#6DB7ED"
stop-opacity="0.9"
id="stop1" />
<stop
offset="100%"
stop-color="#6DB7ED"
stop-opacity="0.0"
id="stop2" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3"
id="linearGradient4"
x1="0"
y1="12"
x2="24"
y2="12"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.98333334,0,0,0.98333334,0.19999999,0.19999999)" />
<linearGradient
id="linearGradient3"
inkscape:collect="always">
<stop
style="stop-color:#6DB7ED;stop-opacity:0.89999998;"
offset="0"
id="stop3" />
<stop
style="stop-color:#6DB7ED;stop-opacity:0;"
offset="1"
id="stop4" />
</linearGradient>
</defs>
<rect x="4" y="4" width="16" height="16" fill="url(#g)"/>
<rect x="4" y="4" width="16" height="16" stroke="#B4B6B9" stroke-width="1.5" fill="none"/>
<rect
x="0.9375"
y="0.9375"
width="22.125"
height="22.125"
stroke="#B4B6B9"
stroke-width="1.5"
fill="none"
id="rect3"
style="fill:url(#linearGradient4);stroke-width:1.875;stroke-dasharray:none" />
</svg>

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 2.3 KiB

+29 -22
View File
@@ -6,7 +6,7 @@
version="1.1"
id="svg6"
sodipodi:docname="hatch_lines.svg"
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
@@ -20,15 +20,15 @@
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="6.3152247"
inkscape:cx="34.044711"
inkscape:cy="32.698757"
inkscape:window-width="1920"
inkscape:window-height="939"
inkscape:zoom="8.9310764"
inkscape:cx="26.032696"
inkscape:cy="34.878215"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
inkscape:current-layer="g6" />
<defs
id="defs1">
<clipPath
@@ -53,40 +53,47 @@
y2="-2"
stroke="#6db7ed"
stroke-width="1.2"
id="line1" />
id="line1"
style="stroke-width:1.25222463;stroke-dasharray:none" />
<line
x1="2"
y1="26"
y1="25.5"
x2="26"
y2="2"
y2="1.5"
stroke="#6db7ed"
stroke-width="1.2"
id="line2" />
id="line2"
style="stroke-width:1.25222;stroke-dasharray:none" />
<line
x1="-6"
y1="18"
y1="19"
x2="18"
y2="-6"
y2="-5"
stroke="#6db7ed"
stroke-width="1.2"
id="line3" />
id="line3"
inkscape:transform-center-x="1.4695877"
inkscape:transform-center-y="-1.4695877"
style="stroke-width:1.25222;stroke-dasharray:none" />
<line
x1="6"
y1="30"
y1="29"
x2="30"
y2="6"
y2="5"
stroke="#6db7ed"
stroke-width="1.2"
id="line5" />
id="line5"
style="stroke-width:1.25222;stroke-dasharray:none" />
</g>
<!-- Square boundary -->
<rect
x="0.87927544"
y="0.87927294"
width="22.241451"
height="22.241451"
x="0.9375"
y="0.9375"
width="22.125"
height="22.125"
stroke="#b4b6b9"
stroke-width="1.75855"
fill="none"
id="rect6" />
id="rect6"
style="stroke-width:1.875;stroke-dasharray:none" />
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

+50
View File
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
width="64"
height="64"
version="1.1"
id="svg2"
sodipodi:docname="hatch_none.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs2" />
<sodipodi:namedview
id="namedview2"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="12.805262"
inkscape:cx="31.66667"
inkscape:cy="32.75997"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<!-- Solid fill -->
<path
style="fill:none;stroke:#ff0000;stroke-width:1.875;stroke-dasharray:none;stroke-opacity:1"
d="M 0,24 24,0"
id="path1"
sodipodi:nodetypes="cc" />
<rect
x="0.9375"
y="0.9375"
width="22.125"
height="22.125116"
stroke="#b4b6b9"
stroke-width="2.05714"
fill="none"
id="rect2"
style="fill:none;fill-opacity:1;stroke-width:1.875;stroke-dasharray:none" />
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

+43 -3
View File
@@ -1,5 +1,45 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="64" height="64">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 24 24"
width="64"
height="64"
version="1.1"
id="svg2"
sodipodi:docname="hatch_solid.svg"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs2" />
<sodipodi:namedview
id="namedview2"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="18.109375"
inkscape:cx="32"
inkscape:cy="32"
inkscape:window-width="2560"
inkscape:window-height="1368"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<!-- Solid fill -->
<rect x="4" y="4" width="16" height="16" fill="#6DB7ED" opacity="0.6"/>
<rect x="4" y="4" width="16" height="16" stroke="#B4B6B9" stroke-width="1.5" fill="none"/>
<rect
x="0.9375"
y="0.9375"
width="22.125"
height="22.125116"
stroke="#b4b6b9"
stroke-width="2.05714"
fill="none"
id="rect2"
style="fill:#6db7ed;fill-opacity:1;stroke-width:1.875;stroke-dasharray:none" />
</svg>

Before

Width:  |  Height:  |  Size: 280 B

After

Width:  |  Height:  |  Size: 1.3 KiB

+35
View File
@@ -6185,3 +6185,38 @@ dock =
.new-group = مجموعة جديدة
.browser = المستعرض
.node-graph = مخطط العقد
graphic-attributes =
.title = سمات الرسم
.set-all-bylayer = تعيين كل السمات إلى ByLayer
.set-all-byblock = تعيين كل السمات إلى ByBlock
.remove-bylayer-byblock = إزالة ByLayer / ByBlock
.create-layer-active-settings = إنشاء طبقة بالإعدادات النشطة
.fills-on-current-layer = إنشاء التعبئات على الطبقة الحالية
.edit-hatch = تحرير التهشير
.edit-gradient = تحرير التدرج
.close-open-object = الكائن المحدد مفتوح. هل تريد إغلاقه قبل إنشاء التعبئة؟ [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ من الكائنات المحددة مفتوحة. هل تريد إغلاقها قبل إنشاء التعبئة؟ [Yes / No] <Yes>
.enter-new-layer-name = أدخل اسمًا للطبقة الجديدة:
.invalid-layer-name = سمات الرسم: أدخل اسم طبقة صالحًا بدون <>/\":;?*|,=`.
.layer-exists = سمات الرسم: الطبقة "__ocs_fmt_0__" موجودة بالفعل.
.layer-not-created = سمات الرسم: تعذر إنشاء الطبقة.
.layer-created = تم إنشاء الطبقة "__ocs_fmt_0__" بإعدادات سمات الرسم النشطة.
.gradient-fill-locked = تعبئة متدرجة: التعبئة على طبقة مقفلة.
.select-closed-objects = حدد كائنًا مغلقًا واحدًا أو أكثر أولاً.
.locked-objects-skipped = سمات الرسم: لم يتم تغيير __ocs_fmt_0__ من الكائنات على طبقة مقفلة.
.no-hatch-pattern = سمات الرسم: لا يتوفر نمط تهشير.
.associated-fill-locked = سمات الرسم: توجد تعبئة مرتبطة على طبقة مقفلة.
.one-unsupported = سمات الرسم: لم يتم تغيير كائن واحد غير مدعوم.
.unsupported-skipped = سمات الرسم: لم يتم تغيير __ocs_fmt_0__ من الكائنات غير المدعومة.
.fill-transparency = شفافية التعبئة
.fill-change = تغيير التعبئة
.line-transparency = شفافية الخطوط
.cylindrical-short = أسطواني
.spherical-short = كروي
.hemispherical-short = نصف كروي
.invert-gradient = عكس التدرج
.tone = الدرجة
.reset-angle = إعادة تعيين الزاوية
.one-color = لون واحد
.two-colors = لونان
+35
View File
@@ -6173,3 +6173,38 @@ dock =
.new-group = Нова група
.browser = Браузър
.node-graph = Граф на възлите
graphic-attributes =
.title = Графични атрибути
.set-all-bylayer = Задаване на всички атрибути на ByLayer
.set-all-byblock = Задаване на всички атрибути на ByBlock
.remove-bylayer-byblock = Премахване на ByLayer / ByBlock
.create-layer-active-settings = Създаване на слой с активните настройки
.fills-on-current-layer = Създаване на запълвания в текущия слой
.edit-hatch = Редактиране на щриховката
.edit-gradient = Редактиране на преливането
.close-open-object = Избраният обект е отворен. Да се затвори ли преди създаване на запълването? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ от избраните обекти са отворени. Да се затворят ли преди създаване на запълването? [Yes / No] <Yes>
.enter-new-layer-name = Въведете име за новия слой:
.invalid-layer-name = Графични атрибути: въведете валидно име на слой без <>/\":;?*|,=`.
.layer-exists = Графични атрибути: слоят "__ocs_fmt_0__" вече съществува.
.layer-not-created = Графични атрибути: слоят не можа да бъде създаден.
.layer-created = Създаден е слой "__ocs_fmt_0__" с активните настройки на графичните атрибути.
.gradient-fill-locked = Преливащо запълване: запълването е в заключен слой.
.select-closed-objects = Първо изберете един или повече затворени обекта.
.locked-objects-skipped = Графични атрибути: __ocs_fmt_0__ обекта в заключен слой не бяха променени.
.no-hatch-pattern = Графични атрибути: няма наличен шаблон за щриховка.
.associated-fill-locked = Графични атрибути: свързано запълване е в заключен слой.
.one-unsupported = Графични атрибути: 1 неподдържан обект не беше променен.
.unsupported-skipped = Графични атрибути: __ocs_fmt_0__ неподдържани обекта не бяха променени.
.fill-transparency = Прозрачност на запълването
.fill-change = Промяна на запълването
.line-transparency = Прозрачност на линиите
.cylindrical-short = Цил.
.spherical-short = Сфер.
.hemispherical-short = Полусф.
.invert-gradient = Обръщане на преливането
.tone = Тон
.reset-angle = Нулиране на ъгъла
.one-color = Един цвят
.two-colors = Два цвята
+35
View File
@@ -6170,3 +6170,38 @@ dock =
.new-group = Nová skupina
.browser = Prohlížeč
.node-graph = Graf uzlů
graphic-attributes =
.title = Grafické atributy
.set-all-bylayer = Nastavit všechny atributy na ByLayer
.set-all-byblock = Nastavit všechny atributy na ByBlock
.remove-bylayer-byblock = Odebrat ByLayer / ByBlock
.create-layer-active-settings = Vytvořit hladinu s aktivním nastavením
.fills-on-current-layer = Vytvářet výplně v aktuální hladině
.edit-hatch = Upravit šrafu
.edit-gradient = Upravit přechod
.close-open-object = Vybraný objekt je otevřený. Uzavřít jej před vytvořením výplně? [Yes / No] <Yes>
.close-open-objects = Vybrané objekty jsou otevřené (__ocs_fmt_0__). Uzavřít je před vytvořením výplně? [Yes / No] <Yes>
.enter-new-layer-name = Zadejte název nové hladiny:
.invalid-layer-name = Grafické atributy: zadejte platný název hladiny bez <>/\":;?*|,=`.
.layer-exists = Grafické atributy: hladina "__ocs_fmt_0__" již existuje.
.layer-not-created = Grafické atributy: hladinu nelze vytvořit.
.layer-created = Hladina "__ocs_fmt_0__" byla vytvořena s aktivním nastavením grafických atributů.
.gradient-fill-locked = Přechodová výplň: výplň je v zamčené hladině.
.select-closed-objects = Nejprve vyberte jeden nebo více uzavřených objektů.
.locked-objects-skipped = Grafické atributy: objekty v zamčené hladině (__ocs_fmt_0__) nebyly změněny.
.no-hatch-pattern = Grafické atributy: není k dispozici žádný vzor šraf.
.associated-fill-locked = Grafické atributy: přidružená výplň je v zamčené hladině.
.one-unsupported = Grafické atributy: 1 nepodporovaný objekt nebyl změněn.
.unsupported-skipped = Grafické atributy: nepodporované objekty (__ocs_fmt_0__) nebyly změněny.
.fill-transparency = Průhlednost výplně
.fill-change = Změna výplně
.line-transparency = Průhlednost čar
.cylindrical-short = Válc.
.spherical-short = Kul.
.hemispherical-short = Polokul.
.invert-gradient = Obrátit přechod
.tone = Tón
.reset-angle = Obnovit úhel
.one-color = Jedna barva
.two-colors = Dvě barvy
+35
View File
@@ -6171,3 +6171,38 @@ dock =
.new-group = Neue Gruppe
.browser = Browser
.node-graph = Knotengraph
graphic-attributes =
.title = Grafikattribute
.set-all-bylayer = Alle Attribute auf ByLayer setzen
.set-all-byblock = Alle Attribute auf ByBlock setzen
.remove-bylayer-byblock = ByLayer / ByBlock entfernen
.create-layer-active-settings = Layer mit aktiven Einstellungen erstellen
.fills-on-current-layer = Füllungen auf dem aktuellen Layer erstellen
.edit-hatch = Schraffur bearbeiten
.edit-gradient = Verlauf bearbeiten
.close-open-object = Das ausgewählte Objekt ist offen. Vor dem Erstellen der Füllung schließen? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ ausgewählte Objekte sind offen. Vor dem Erstellen der Füllung schließen? [Yes / No] <Yes>
.enter-new-layer-name = Namen für den neuen Layer eingeben:
.invalid-layer-name = Grafikattribute: gültigen Layernamen ohne <>/\":;?*|,=` eingeben.
.layer-exists = Grafikattribute: Layer "__ocs_fmt_0__" ist bereits vorhanden.
.layer-not-created = Grafikattribute: Der Layer konnte nicht erstellt werden.
.layer-created = Layer "__ocs_fmt_0__" mit den aktiven Grafikattributen erstellt.
.gradient-fill-locked = Verlaufsfüllung: Die Füllung liegt auf einem gesperrten Layer.
.select-closed-objects = Zuerst ein oder mehrere geschlossene Objekte auswählen.
.locked-objects-skipped = Grafikattribute: __ocs_fmt_0__ Objekt(e) auf einem gesperrten Layer wurden nicht geändert.
.no-hatch-pattern = Grafikattribute: Kein Schraffurmuster verfügbar.
.associated-fill-locked = Grafikattribute: Eine zugehörige Füllung liegt auf einem gesperrten Layer.
.one-unsupported = Grafikattribute: 1 nicht unterstütztes Objekt wurde nicht geändert.
.unsupported-skipped = Grafikattribute: __ocs_fmt_0__ nicht unterstützte Objekte wurden nicht geändert.
.fill-transparency = Füllungstransparenz
.fill-change = Füllung ändern
.line-transparency = Linientransparenz
.cylindrical-short = Zyl.
.spherical-short = Kugel
.hemispherical-short = Halbk.
.invert-gradient = Verlauf umkehren
.tone = Ton
.reset-angle = Winkel zurücksetzen
.one-color = Einfarbig
.two-colors = Zweifarbig
+35
View File
@@ -6173,3 +6173,38 @@ dock =
.new-group = Νέα ομάδα
.browser = Περιηγητής
.node-graph = Γράφος κόμβων
graphic-attributes =
.title = Γραφικά χαρακτηριστικά
.set-all-bylayer = Ορισμός όλων των χαρακτηριστικών σε ByLayer
.set-all-byblock = Ορισμός όλων των χαρακτηριστικών σε ByBlock
.remove-bylayer-byblock = Αφαίρεση ByLayer / ByBlock
.create-layer-active-settings = Δημιουργία επιπέδου με τις ενεργές ρυθμίσεις
.fills-on-current-layer = Δημιουργία γεμισμάτων στο τρέχον επίπεδο
.edit-hatch = Επεξεργασία διαγράμμισης
.edit-gradient = Επεξεργασία διαβάθμισης
.close-open-object = Το επιλεγμένο αντικείμενο είναι ανοιχτό. Να κλείσει πριν από τη δημιουργία του γεμίσματος; [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ επιλεγμένα αντικείμενα είναι ανοιχτά. Να κλείσουν πριν από τη δημιουργία του γεμίσματος; [Yes / No] <Yes>
.enter-new-layer-name = Εισαγάγετε όνομα για το νέο επίπεδο:
.invalid-layer-name = Γραφικά χαρακτηριστικά: εισαγάγετε έγκυρο όνομα επιπέδου χωρίς <>/\":;?*|,=`.
.layer-exists = Γραφικά χαρακτηριστικά: το επίπεδο "__ocs_fmt_0__" υπάρχει ήδη.
.layer-not-created = Γραφικά χαρακτηριστικά: δεν ήταν δυνατή η δημιουργία του επιπέδου.
.layer-created = Δημιουργήθηκε το επίπεδο "__ocs_fmt_0__" με τις ενεργές ρυθμίσεις γραφικών χαρακτηριστικών.
.gradient-fill-locked = Γέμισμα διαβάθμισης: το γέμισμα βρίσκεται σε κλειδωμένο επίπεδο.
.select-closed-objects = Επιλέξτε πρώτα ένα ή περισσότερα κλειστά αντικείμενα.
.locked-objects-skipped = Γραφικά χαρακτηριστικά: __ocs_fmt_0__ αντικείμενα σε κλειδωμένο επίπεδο δεν άλλαξαν.
.no-hatch-pattern = Γραφικά χαρακτηριστικά: δεν υπάρχει διαθέσιμο μοτίβο διαγράμμισης.
.associated-fill-locked = Γραφικά χαρακτηριστικά: ένα συσχετισμένο γέμισμα βρίσκεται σε κλειδωμένο επίπεδο.
.one-unsupported = Γραφικά χαρακτηριστικά: 1 μη υποστηριζόμενο αντικείμενο δεν άλλαξε.
.unsupported-skipped = Γραφικά χαρακτηριστικά: __ocs_fmt_0__ μη υποστηριζόμενα αντικείμενα δεν άλλαξαν.
.fill-transparency = Διαφάνεια γεμίσματος
.fill-change = Αλλαγή γεμίσματος
.line-transparency = Διαφάνεια γραμμών
.cylindrical-short = Κυλ.
.spherical-short = Σφαιρ.
.hemispherical-short = Ημισφ.
.invert-gradient = Αντιστροφή διαβάθμισης
.tone = Τόνος
.reset-angle = Επαναφορά γωνίας
.one-color = Ένα χρώμα
.two-colors = Δύο χρώματα
+35
View File
@@ -6174,3 +6174,38 @@ dock =
.new-group = New group
.browser = Browser
.node-graph = Node Graph
graphic-attributes =
.title = Graphic Attributes
.set-all-bylayer = Set all attributes ByLayer
.set-all-byblock = Set all attributes ByBlock
.remove-bylayer-byblock = Remove ByLayer / ByBlock
.create-layer-active-settings = Create Layer with active settings
.fills-on-current-layer = Create fills on the current layer
.edit-hatch = Edit hatch
.edit-gradient = Edit gradient
.close-open-object = The selected object is open. Close it before creating the fill? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ selected objects are open. Close them before creating the fill? [Yes / No] <Yes>
.enter-new-layer-name = Enter a name for the new layer:
.invalid-layer-name = Graphic Attributes: enter a valid layer name without <>/\":;?*|,=`.
.layer-exists = Graphic Attributes: layer "__ocs_fmt_0__" already exists.
.layer-not-created = Graphic Attributes: the layer could not be created.
.layer-created = Created layer "__ocs_fmt_0__" with the active Graphic Attributes settings.
.gradient-fill-locked = Gradient Fill: the fill is on a locked layer.
.select-closed-objects = Select one or more closed objects first.
.locked-objects-skipped = Graphic Attributes: __ocs_fmt_0__ object(s) on a locked layer were not changed.
.no-hatch-pattern = Graphic Attributes: no hatch pattern is available.
.associated-fill-locked = Graphic Attributes: an associated fill is on a locked layer.
.one-unsupported = Graphic Attributes: 1 unsupported object was not changed.
.unsupported-skipped = Graphic Attributes: __ocs_fmt_0__ unsupported objects were not changed.
.fill-transparency = Fill transparency
.fill-change = Fill change
.line-transparency = Line transparency
.cylindrical-short = Cyl.
.spherical-short = Spher.
.hemispherical-short = Hemi.
.invert-gradient = Invert gradient
.tone = Tone
.reset-angle = Reset angle
.one-color = One Color
.two-colors = Two Colors
+35
View File
@@ -6173,3 +6173,38 @@ dock =
.new-group = Nuevo grupo
.browser = Explorador
.node-graph = Grafo de nodos
graphic-attributes =
.title = Atributos gráficos
.set-all-bylayer = Establecer todos los atributos en ByLayer
.set-all-byblock = Establecer todos los atributos en ByBlock
.remove-bylayer-byblock = Quitar ByLayer / ByBlock
.create-layer-active-settings = Crear capa con la configuración activa
.fills-on-current-layer = Crear rellenos en la capa actual
.edit-hatch = Editar sombreado
.edit-gradient = Editar degradado
.close-open-object = El objeto seleccionado está abierto. ¿Cerrarlo antes de crear el relleno? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ objetos seleccionados están abiertos. ¿Cerrarlos antes de crear el relleno? [Yes / No] <Yes>
.enter-new-layer-name = Introduzca un nombre para la capa nueva:
.invalid-layer-name = Atributos gráficos: introduzca un nombre de capa válido sin <>/\":;?*|,=`.
.layer-exists = Atributos gráficos: la capa "__ocs_fmt_0__" ya existe.
.layer-not-created = Atributos gráficos: no se pudo crear la capa.
.layer-created = Se creó la capa "__ocs_fmt_0__" con la configuración activa de atributos gráficos.
.gradient-fill-locked = Relleno degradado: el relleno está en una capa bloqueada.
.select-closed-objects = Seleccione primero uno o varios objetos cerrados.
.locked-objects-skipped = Atributos gráficos: no se modificaron __ocs_fmt_0__ objeto(s) en una capa bloqueada.
.no-hatch-pattern = Atributos gráficos: no hay ningún patrón de sombreado disponible.
.associated-fill-locked = Atributos gráficos: un relleno asociado está en una capa bloqueada.
.one-unsupported = Atributos gráficos: no se modificó 1 objeto no admitido.
.unsupported-skipped = Atributos gráficos: no se modificaron __ocs_fmt_0__ objetos no admitidos.
.fill-transparency = Transparencia del relleno
.fill-change = Cambio de relleno
.line-transparency = Transparencia de línea
.cylindrical-short = Cil.
.spherical-short = Esfér.
.hemispherical-short = Semiesf.
.invert-gradient = Invertir degradado
.tone = Tono
.reset-angle = Restablecer ángulo
.one-color = Un color
.two-colors = Dos colores
+35
View File
@@ -6170,3 +6170,38 @@ dock =
.new-group = Uusi ryhmä
.browser = Selain
.node-graph = Solmukaavio
graphic-attributes =
.title = Grafiikkamääritteet
.set-all-bylayer = Aseta kaikki määritteet arvoon ByLayer
.set-all-byblock = Aseta kaikki määritteet arvoon ByBlock
.remove-bylayer-byblock = Poista ByLayer / ByBlock
.create-layer-active-settings = Luo taso aktiivisilla asetuksilla
.fills-on-current-layer = Luo täytöt nykyiselle tasolle
.edit-hatch = Muokkaa viivoitusta
.edit-gradient = Muokkaa liukuväriä
.close-open-object = Valittu objekti on avoin. Suljetaanko se ennen täytön luomista? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ valittua objektia on avoimia. Suljetaanko ne ennen täytön luomista? [Yes / No] <Yes>
.enter-new-layer-name = Anna uuden tason nimi:
.invalid-layer-name = Grafiikkamääritteet: anna kelvollinen tason nimi ilman merkkejä <>/\":;?*|,=`.
.layer-exists = Grafiikkamääritteet: taso "__ocs_fmt_0__" on jo olemassa.
.layer-not-created = Grafiikkamääritteet: tasoa ei voitu luoda.
.layer-created = Taso "__ocs_fmt_0__" luotiin aktiivisilla grafiikkamääritteillä.
.gradient-fill-locked = Liukuväritäyttö: täyttö on lukitulla tasolla.
.select-closed-objects = Valitse ensin yksi tai useampi suljettu objekti.
.locked-objects-skipped = Grafiikkamääritteet: __ocs_fmt_0__ lukitulla tasolla olevaa objektia jätettiin muuttamatta.
.no-hatch-pattern = Grafiikkamääritteet: viivoituskuviota ei ole saatavilla.
.associated-fill-locked = Grafiikkamääritteet: liitetty täyttö on lukitulla tasolla.
.one-unsupported = Grafiikkamääritteet: 1 tukematonta objektia ei muutettu.
.unsupported-skipped = Grafiikkamääritteet: __ocs_fmt_0__ tukematonta objektia jätettiin muuttamatta.
.fill-transparency = Täytön läpinäkyvyys
.fill-change = Täytön muutos
.line-transparency = Viivojen läpinäkyvyys
.cylindrical-short = Lieriö
.spherical-short = Pallo
.hemispherical-short = Puolip.
.invert-gradient = Käännä liukuväri
.tone = Sävy
.reset-angle = Palauta kulma
.one-color = Yksi väri
.two-colors = Kaksi väriä
+35
View File
@@ -6172,3 +6172,38 @@ dock =
.new-group = Nouveau groupe
.browser = Navigateur
.node-graph = Graphe de nœuds
graphic-attributes =
.title = Attributs graphiques
.set-all-bylayer = Définir tous les attributs sur ByLayer
.set-all-byblock = Définir tous les attributs sur ByBlock
.remove-bylayer-byblock = Supprimer ByLayer / ByBlock
.create-layer-active-settings = Créer un calque avec les paramètres actifs
.fills-on-current-layer = Créer les remplissages sur le calque courant
.edit-hatch = Modifier la hachure
.edit-gradient = Modifier le dégradé
.close-open-object = L'objet sélectionné est ouvert. Le fermer avant de créer le remplissage ? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ objets sélectionnés sont ouverts. Les fermer avant de créer le remplissage ? [Yes / No] <Yes>
.enter-new-layer-name = Entrez un nom pour le nouveau calque :
.invalid-layer-name = Attributs graphiques : entrez un nom de calque valide sans <>/\":;?*|,=`.
.layer-exists = Attributs graphiques : le calque "__ocs_fmt_0__" existe déjà.
.layer-not-created = Attributs graphiques : impossible de créer le calque.
.layer-created = Calque "__ocs_fmt_0__" créé avec les attributs graphiques actifs.
.gradient-fill-locked = Remplissage dégradé : le remplissage est sur un calque verrouillé.
.select-closed-objects = Sélectionnez d'abord un ou plusieurs objets fermés.
.locked-objects-skipped = Attributs graphiques : __ocs_fmt_0__ objet(s) sur un calque verrouillé n'ont pas été modifiés.
.no-hatch-pattern = Attributs graphiques : aucun motif de hachure n'est disponible.
.associated-fill-locked = Attributs graphiques : un remplissage associé est sur un calque verrouillé.
.one-unsupported = Attributs graphiques : 1 objet non pris en charge n'a pas été modifié.
.unsupported-skipped = Attributs graphiques : __ocs_fmt_0__ objets non pris en charge n'ont pas été modifiés.
.fill-transparency = Transparence du remplissage
.fill-change = Modification du remplissage
.line-transparency = Transparence des lignes
.cylindrical-short = Cyl.
.spherical-short = Sphér.
.hemispherical-short = Hémi.
.invert-gradient = Inverser le dégradé
.tone = Ton
.reset-angle = Réinitialiser l'angle
.one-color = Une couleur
.two-colors = Deux couleurs
+35
View File
@@ -6161,3 +6161,38 @@ dock =
.new-group = नया समूह
.browser = ब्राउज़र
.node-graph = नोड ग्राफ़
graphic-attributes =
.title = ग्राफ़िक गुण
.set-all-bylayer = सभी गुण ByLayer पर सेट करें
.set-all-byblock = सभी गुण ByBlock पर सेट करें
.remove-bylayer-byblock = ByLayer / ByBlock हटाएँ
.create-layer-active-settings = सक्रिय सेटिंग्स के साथ लेयर बनाएँ
.fills-on-current-layer = भराव वर्तमान लेयर पर बनाएँ
.edit-hatch = हैच संपादित करें
.edit-gradient = ग्रेडिएंट संपादित करें
.close-open-object = चयनित ऑब्जेक्ट खुला है। भराव बनाने से पहले इसे बंद करें? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ चयनित ऑब्जेक्ट खुले हैं। भराव बनाने से पहले इन्हें बंद करें? [Yes / No] <Yes>
.enter-new-layer-name = नई लेयर का नाम दर्ज करें:
.invalid-layer-name = ग्राफ़िक गुण: <>/\":;?*|,=` के बिना मान्य लेयर नाम दर्ज करें।
.layer-exists = ग्राफ़िक गुण: लेयर "__ocs_fmt_0__" पहले से मौजूद है।
.layer-not-created = ग्राफ़िक गुण: लेयर नहीं बनाई जा सकी।
.layer-created = सक्रिय ग्राफ़िक गुण सेटिंग्स के साथ लेयर "__ocs_fmt_0__" बनाई गई।
.gradient-fill-locked = ग्रेडिएंट भराव: भराव लॉक की गई लेयर पर है।
.select-closed-objects = पहले एक या अधिक बंद ऑब्जेक्ट चुनें।
.locked-objects-skipped = ग्राफ़िक गुण: लॉक की गई लेयर पर __ocs_fmt_0__ ऑब्जेक्ट नहीं बदले गए।
.no-hatch-pattern = ग्राफ़िक गुण: कोई हैच पैटर्न उपलब्ध नहीं है।
.associated-fill-locked = ग्राफ़िक गुण: एक संबद्ध भराव लॉक की गई लेयर पर है।
.one-unsupported = ग्राफ़िक गुण: 1 असमर्थित ऑब्जेक्ट नहीं बदला गया।
.unsupported-skipped = ग्राफ़िक गुण: __ocs_fmt_0__ असमर्थित ऑब्जेक्ट नहीं बदले गए।
.fill-transparency = भराव पारदर्शिता
.fill-change = भराव परिवर्तन
.line-transparency = रेखा पारदर्शिता
.cylindrical-short = बेलन.
.spherical-short = गोल.
.hemispherical-short = अर्धगोल.
.invert-gradient = ग्रेडिएंट उलटें
.tone = टोन
.reset-angle = कोण रीसेट करें
.one-color = एक रंग
.two-colors = दो रंग
+35
View File
@@ -6159,3 +6159,38 @@ dock =
.new-group = Új csoport
.browser = Böngésző
.node-graph = Csomópontgráf
graphic-attributes =
.title = Grafikus jellemzők
.set-all-bylayer = Minden jellemző ByLayer értékre
.set-all-byblock = Minden jellemző ByBlock értékre
.remove-bylayer-byblock = ByLayer / ByBlock eltávolítása
.create-layer-active-settings = Fólia létrehozása az aktív beállításokkal
.fills-on-current-layer = Kitöltések létrehozása az aktuális fólián
.edit-hatch = Sraffozás szerkesztése
.edit-gradient = Színátmenet szerkesztése
.close-open-object = A kijelölt objektum nyitott. Bezárja a kitöltés létrehozása előtt? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ kijelölt objektum nyitott. Bezárja őket a kitöltés létrehozása előtt? [Yes / No] <Yes>
.enter-new-layer-name = Adja meg az új fólia nevét:
.invalid-layer-name = Grafikus jellemzők: adjon meg érvényes fólianevet <>/\":;?*|,=` nélkül.
.layer-exists = Grafikus jellemzők: a(z) "__ocs_fmt_0__" fólia már létezik.
.layer-not-created = Grafikus jellemzők: a fóliát nem sikerült létrehozni.
.layer-created = A(z) "__ocs_fmt_0__" fólia létrejött az aktív grafikus jellemzőkkel.
.gradient-fill-locked = Színátmenetes kitöltés: a kitöltés zárolt fólián van.
.select-closed-objects = Először jelöljön ki egy vagy több zárt objektumot.
.locked-objects-skipped = Grafikus jellemzők: __ocs_fmt_0__ zárolt fólián lévő objektum nem változott.
.no-hatch-pattern = Grafikus jellemzők: nincs elérhető sraffozási minta.
.associated-fill-locked = Grafikus jellemzők: egy társított kitöltés zárolt fólián van.
.one-unsupported = Grafikus jellemzők: 1 nem támogatott objektum nem változott.
.unsupported-skipped = Grafikus jellemzők: __ocs_fmt_0__ nem támogatott objektum nem változott.
.fill-transparency = Kitöltés átlátszósága
.fill-change = Kitöltés módosítása
.line-transparency = Vonalak átlátszósága
.cylindrical-short = Henger
.spherical-short = Gömb
.hemispherical-short = Félgömb
.invert-gradient = Színátmenet megfordítása
.tone = Tónus
.reset-angle = Szög visszaállítása
.one-color = Egy szín
.two-colors = Két szín
+35
View File
@@ -6172,3 +6172,38 @@ dock =
.new-group = Nuovo gruppo
.browser = Browser
.node-graph = Grafo dei nodi
graphic-attributes =
.title = Attributi grafici
.set-all-bylayer = Imposta tutti gli attributi su ByLayer
.set-all-byblock = Imposta tutti gli attributi su ByBlock
.remove-bylayer-byblock = Rimuovi ByLayer / ByBlock
.create-layer-active-settings = Crea layer con le impostazioni attive
.fills-on-current-layer = Crea i riempimenti sul layer corrente
.edit-hatch = Modifica tratteggio
.edit-gradient = Modifica sfumatura
.close-open-object = L'oggetto selezionato è aperto. Chiuderlo prima di creare il riempimento? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ oggetti selezionati sono aperti. Chiuderli prima di creare il riempimento? [Yes / No] <Yes>
.enter-new-layer-name = Immettere un nome per il nuovo layer:
.invalid-layer-name = Attributi grafici: immettere un nome di layer valido senza <>/\":;?*|,=`.
.layer-exists = Attributi grafici: il layer "__ocs_fmt_0__" esiste già.
.layer-not-created = Attributi grafici: impossibile creare il layer.
.layer-created = Layer "__ocs_fmt_0__" creato con le impostazioni attive degli attributi grafici.
.gradient-fill-locked = Riempimento sfumato: il riempimento è su un layer bloccato.
.select-closed-objects = Selezionare prima uno o più oggetti chiusi.
.locked-objects-skipped = Attributi grafici: __ocs_fmt_0__ oggetto/i su un layer bloccato non sono stati modificati.
.no-hatch-pattern = Attributi grafici: nessun modello di tratteggio disponibile.
.associated-fill-locked = Attributi grafici: un riempimento associato è su un layer bloccato.
.one-unsupported = Attributi grafici: 1 oggetto non supportato non è stato modificato.
.unsupported-skipped = Attributi grafici: __ocs_fmt_0__ oggetti non supportati non sono stati modificati.
.fill-transparency = Trasparenza riempimento
.fill-change = Modifica riempimento
.line-transparency = Trasparenza linee
.cylindrical-short = Cil.
.spherical-short = Sfer.
.hemispherical-short = Emisf.
.invert-gradient = Inverti sfumatura
.tone = Tono
.reset-angle = Reimposta angolo
.one-color = Un colore
.two-colors = Due colori
+35
View File
@@ -6161,3 +6161,38 @@ dock =
.new-group = 新しいグループ
.browser = ブラウザー
.node-graph = ノードグラフ
graphic-attributes =
.title = グラフィック属性
.set-all-bylayer = すべての属性を ByLayer に設定
.set-all-byblock = すべての属性を ByBlock に設定
.remove-bylayer-byblock = ByLayer / ByBlock を解除
.create-layer-active-settings = 現在の設定で画層を作成
.fills-on-current-layer = 塗り潰しを現在の画層に作成
.edit-hatch = ハッチングを編集
.edit-gradient = グラデーションを編集
.close-open-object = 選択したオブジェクトは開いています。塗り潰しを作成する前に閉じますか? [Yes / No] <Yes>
.close-open-objects = 選択した __ocs_fmt_0__ 個のオブジェクトは開いています。塗り潰しを作成する前に閉じますか? [Yes / No] <Yes>
.enter-new-layer-name = 新しい画層の名前を入力:
.invalid-layer-name = グラフィック属性: <>/\":;?*|,=` を含まない有効な画層名を入力してください。
.layer-exists = グラフィック属性: 画層 "__ocs_fmt_0__" は既に存在します。
.layer-not-created = グラフィック属性: 画層を作成できませんでした。
.layer-created = 現在のグラフィック属性の設定で画層 "__ocs_fmt_0__" を作成しました。
.gradient-fill-locked = グラデーション塗り潰し: 塗り潰しはロックされた画層にあります。
.select-closed-objects = 先に 1 つ以上の閉じたオブジェクトを選択してください。
.locked-objects-skipped = グラフィック属性: ロックされた画層上の __ocs_fmt_0__ 個のオブジェクトは変更されませんでした。
.no-hatch-pattern = グラフィック属性: 使用できるハッチング パターンがありません。
.associated-fill-locked = グラフィック属性: 関連付けられた塗り潰しがロックされた画層にあります。
.one-unsupported = グラフィック属性: サポートされていないオブジェクト 1 個は変更されませんでした。
.unsupported-skipped = グラフィック属性: サポートされていないオブジェクト __ocs_fmt_0__ 個は変更されませんでした。
.fill-transparency = 塗り潰しの透過性
.fill-change = 塗り潰しの変更
.line-transparency = 線の透過性
.cylindrical-short = 円柱
.spherical-short = 球
.hemispherical-short = 半球
.invert-gradient = グラデーションを反転
.tone = 濃淡
.reset-angle = 角度をリセット
.one-color = 1 色
.two-colors = 2 色
+35
View File
@@ -6172,3 +6172,38 @@ dock =
.new-group = 새 그룹
.browser = 브라우저
.node-graph = 노드 그래프
graphic-attributes =
.title = 그래픽 속성
.set-all-bylayer = 모든 속성을 ByLayer로 설정
.set-all-byblock = 모든 속성을 ByBlock으로 설정
.remove-bylayer-byblock = ByLayer / ByBlock 제거
.create-layer-active-settings = 현재 설정으로 도면층 작성
.fills-on-current-layer = 현재 도면층에 채우기 작성
.edit-hatch = 해치 편집
.edit-gradient = 그라데이션 편집
.close-open-object = 선택한 객체가 열려 있습니다. 채우기를 작성하기 전에 닫겠습니까? [Yes / No] <Yes>
.close-open-objects = 선택한 객체 __ocs_fmt_0__개가 열려 있습니다. 채우기를 작성하기 전에 닫겠습니까? [Yes / No] <Yes>
.enter-new-layer-name = 새 도면층 이름 입력:
.invalid-layer-name = 그래픽 속성: <>/\":;?*|,=`이(가) 없는 올바른 도면층 이름을 입력하십시오.
.layer-exists = 그래픽 속성: 도면층 "__ocs_fmt_0__"이(가) 이미 있습니다.
.layer-not-created = 그래픽 속성: 도면층을 작성할 수 없습니다.
.layer-created = 현재 그래픽 속성 설정으로 도면층 "__ocs_fmt_0__"을(를) 작성했습니다.
.gradient-fill-locked = 그라데이션 채우기: 채우기가 잠긴 도면층에 있습니다.
.select-closed-objects = 먼저 닫힌 객체를 하나 이상 선택하십시오.
.locked-objects-skipped = 그래픽 속성: 잠긴 도면층의 객체 __ocs_fmt_0__개가 변경되지 않았습니다.
.no-hatch-pattern = 그래픽 속성: 사용 가능한 해치 패턴이 없습니다.
.associated-fill-locked = 그래픽 속성: 연관된 채우기가 잠긴 도면층에 있습니다.
.one-unsupported = 그래픽 속성: 지원되지 않는 객체 1개가 변경되지 않았습니다.
.unsupported-skipped = 그래픽 속성: 지원되지 않는 객체 __ocs_fmt_0__개가 변경되지 않았습니다.
.fill-transparency = 채우기 투명도
.fill-change = 채우기 변경
.line-transparency = 선 투명도
.cylindrical-short = 원통
.spherical-short = 구
.hemispherical-short = 반구
.invert-gradient = 그라데이션 반전
.tone = 색조
.reset-angle = 각도 재설정
.one-color = 단색
.two-colors = 두 색
+35
View File
@@ -6174,3 +6174,38 @@ dock =
.new-group = ກຸ່ມໃໝ່
.browser = ບຣາວເຊີ
.node-graph = ກຣາຟໂນດ
graphic-attributes =
.title = ຄຸນລັກສະນະກຣາຟິກ
.set-all-bylayer = ຕັ້ງຄຸນລັກສະນະທັງໝົດເປັນ ByLayer
.set-all-byblock = ຕັ້ງຄຸນລັກສະນະທັງໝົດເປັນ ByBlock
.remove-bylayer-byblock = ລຶບ ByLayer / ByBlock
.create-layer-active-settings = ສ້າງເລເຢີດ້ວຍການຕັ້ງຄ່າປັດຈຸບັນ
.fills-on-current-layer = ສ້າງການຕື່ມໃສ່ເລເຢີປັດຈຸບັນ
.edit-hatch = ແກ້ໄຂແຮັດ
.edit-gradient = ແກ້ໄຂການໄລ່ສີ
.close-open-object = ວັດຖຸທີ່ເລືອກເປັນແບບເປີດ. ປິດມັນກ່ອນສ້າງການຕື່ມບໍ່? [Yes / No] <Yes>
.close-open-objects = ວັດຖຸທີ່ເລືອກ __ocs_fmt_0__ ອັນເປັນແບບເປີດ. ປິດພວກມັນກ່ອນສ້າງການຕື່ມບໍ່? [Yes / No] <Yes>
.enter-new-layer-name = ປ້ອນຊື່ສຳລັບເລເຢີໃໝ່:
.invalid-layer-name = ຄຸນລັກສະນະກຣາຟິກ: ປ້ອນຊື່ເລເຢີທີ່ຖືກຕ້ອງ ໂດຍບໍ່ມີ <>/\":;?*|,=`.
.layer-exists = ຄຸນລັກສະນະກຣາຟິກ: ເລເຢີ "__ocs_fmt_0__" ມີຢູ່ແລ້ວ.
.layer-not-created = ຄຸນລັກສະນະກຣາຟິກ: ບໍ່ສາມາດສ້າງເລເຢີໄດ້.
.layer-created = ສ້າງເລເຢີ "__ocs_fmt_0__" ດ້ວຍການຕັ້ງຄ່າຄຸນລັກສະນະກຣາຟິກປັດຈຸບັນແລ້ວ.
.gradient-fill-locked = ການຕື່ມໄລ່ສີ: ການຕື່ມຢູ່ໃນເລເຢີທີ່ຖືກລັອກ.
.select-closed-objects = ເລືອກວັດຖຸປິດໜຶ່ງອັນ ຫຼື ຫຼາຍກວ່ານັ້ນກ່ອນ.
.locked-objects-skipped = ຄຸນລັກສະນະກຣາຟິກ: ວັດຖຸ __ocs_fmt_0__ ອັນໃນເລເຢີທີ່ຖືກລັອກບໍ່ໄດ້ຖືກປ່ຽນ.
.no-hatch-pattern = ຄຸນລັກສະນະກຣາຟິກ: ບໍ່ມີຮູບແບບແຮັດ.
.associated-fill-locked = ຄຸນລັກສະນະກຣາຟິກ: ການຕື່ມທີ່ກ່ຽວຂ້ອງຢູ່ໃນເລເຢີທີ່ຖືກລັອກ.
.one-unsupported = ຄຸນລັກສະນະກຣາຟິກ: ວັດຖຸທີ່ບໍ່ຮອງຮັບ 1 ອັນບໍ່ໄດ້ຖືກປ່ຽນ.
.unsupported-skipped = ຄຸນລັກສະນະກຣາຟິກ: ວັດຖຸທີ່ບໍ່ຮອງຮັບ __ocs_fmt_0__ ອັນບໍ່ໄດ້ຖືກປ່ຽນ.
.fill-transparency = ຄວາມໂປ່ງໃສຂອງການຕື່ມ
.fill-change = ປ່ຽນການຕື່ມ
.line-transparency = ຄວາມໂປ່ງໃສຂອງເສັ້ນ
.cylindrical-short = ທໍ່.
.spherical-short = ກົມ.
.hemispherical-short = ເຄິ່ງກົມ.
.invert-gradient = ກັບການໄລ່ສີ
.tone = ໂທນ
.reset-angle = ຣີເຊັດມຸມ
.one-color = ໜຶ່ງສີ
.two-colors = ສອງສີ
+35
View File
@@ -6171,3 +6171,38 @@ dock =
.new-group = Nieuwe groep
.browser = Browser
.node-graph = Knooppuntgrafiek
graphic-attributes =
.title = Grafische attributen
.set-all-bylayer = Alle attributen op ByLayer zetten
.set-all-byblock = Alle attributen op ByBlock zetten
.remove-bylayer-byblock = ByLayer / ByBlock verwijderen
.create-layer-active-settings = Laag maken met actieve instellingen
.fills-on-current-layer = Vullingen op de huidige laag maken
.edit-hatch = Arcering bewerken
.edit-gradient = Kleurverloop bewerken
.close-open-object = Het geselecteerde object is open. Sluiten voordat de vulling wordt gemaakt? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ geselecteerde objecten zijn open. Sluiten voordat de vulling wordt gemaakt? [Yes / No] <Yes>
.enter-new-layer-name = Voer een naam in voor de nieuwe laag:
.invalid-layer-name = Grafische attributen: voer een geldige laagnaam in zonder <>/\":;?*|,=`.
.layer-exists = Grafische attributen: laag "__ocs_fmt_0__" bestaat al.
.layer-not-created = Grafische attributen: de laag kon niet worden gemaakt.
.layer-created = Laag "__ocs_fmt_0__" gemaakt met de actieve instellingen van Grafische attributen.
.gradient-fill-locked = Verloopvulling: de vulling staat op een vergrendelde laag.
.select-closed-objects = Selecteer eerst een of meer gesloten objecten.
.locked-objects-skipped = Grafische attributen: __ocs_fmt_0__ object(en) op een vergrendelde laag zijn niet gewijzigd.
.no-hatch-pattern = Grafische attributen: er is geen arceerpatroon beschikbaar.
.associated-fill-locked = Grafische attributen: een gekoppelde vulling staat op een vergrendelde laag.
.one-unsupported = Grafische attributen: 1 niet-ondersteund object is niet gewijzigd.
.unsupported-skipped = Grafische attributen: __ocs_fmt_0__ niet-ondersteunde objecten zijn niet gewijzigd.
.fill-transparency = Transparantie vulling
.fill-change = Vulling wijzigen
.line-transparency = Transparantie lijnen
.cylindrical-short = Cil.
.spherical-short = Bol
.hemispherical-short = Halfbol
.invert-gradient = Kleurverloop omkeren
.tone = Toon
.reset-angle = Hoek herstellen
.one-color = Eén kleur
.two-colors = Twee kleuren
+35
View File
@@ -6172,3 +6172,38 @@ dock =
.new-group = Nowa grupa
.browser = Przeglądarka
.node-graph = Graf węzłów
graphic-attributes =
.title = Atrybuty graficzne
.set-all-bylayer = Ustaw wszystkie atrybuty na ByLayer
.set-all-byblock = Ustaw wszystkie atrybuty na ByBlock
.remove-bylayer-byblock = Usuń ByLayer / ByBlock
.create-layer-active-settings = Utwórz warstwę z aktywnymi ustawieniami
.fills-on-current-layer = Twórz wypełnienia na bieżącej warstwie
.edit-hatch = Edytuj kreskowanie
.edit-gradient = Edytuj gradient
.close-open-object = Wybrany obiekt jest otwarty. Zamknąć go przed utworzeniem wypełnienia? [Yes / No] <Yes>
.close-open-objects = Wybrane obiekty są otwarte (__ocs_fmt_0__). Zamknąć je przed utworzeniem wypełnienia? [Yes / No] <Yes>
.enter-new-layer-name = Podaj nazwę nowej warstwy:
.invalid-layer-name = Atrybuty graficzne: podaj prawidłową nazwę warstwy bez <>/\":;?*|,=`.
.layer-exists = Atrybuty graficzne: warstwa "__ocs_fmt_0__" już istnieje.
.layer-not-created = Atrybuty graficzne: nie można utworzyć warstwy.
.layer-created = Utworzono warstwę "__ocs_fmt_0__" z aktywnymi atrybutami graficznymi.
.gradient-fill-locked = Wypełnienie gradientowe: wypełnienie jest na zablokowanej warstwie.
.select-closed-objects = Najpierw wybierz jeden lub więcej zamkniętych obiektów.
.locked-objects-skipped = Atrybuty graficzne: obiekty na zablokowanej warstwie (__ocs_fmt_0__) nie zostały zmienione.
.no-hatch-pattern = Atrybuty graficzne: brak dostępnego wzoru kreskowania.
.associated-fill-locked = Atrybuty graficzne: skojarzone wypełnienie jest na zablokowanej warstwie.
.one-unsupported = Atrybuty graficzne: 1 nieobsługiwany obiekt nie został zmieniony.
.unsupported-skipped = Atrybuty graficzne: nieobsługiwane obiekty (__ocs_fmt_0__) nie zostały zmienione.
.fill-transparency = Przezroczystość wypełnienia
.fill-change = Zmiana wypełnienia
.line-transparency = Przezroczystość linii
.cylindrical-short = Walc.
.spherical-short = Sfer.
.hemispherical-short = Półsf.
.invert-gradient = Odwróć gradient
.tone = Ton
.reset-angle = Resetuj kąt
.one-color = Jeden kolor
.two-colors = Dwa kolory
+35
View File
@@ -6173,3 +6173,38 @@ dock =
.new-group = Novo grupo
.browser = Navegador
.node-graph = Grafo de nós
graphic-attributes =
.title = Atributos gráficos
.set-all-bylayer = Definir todos os atributos como ByLayer
.set-all-byblock = Definir todos os atributos como ByBlock
.remove-bylayer-byblock = Remover ByLayer / ByBlock
.create-layer-active-settings = Criar camada com as configurações ativas
.fills-on-current-layer = Criar preenchimentos na camada atual
.edit-hatch = Editar hachura
.edit-gradient = Editar gradiente
.close-open-object = O objeto selecionado está aberto. Fechá-lo antes de criar o preenchimento? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ objetos selecionados estão abertos. Fechá-los antes de criar o preenchimento? [Yes / No] <Yes>
.enter-new-layer-name = Digite um nome para a nova camada:
.invalid-layer-name = Atributos gráficos: digite um nome de camada válido sem <>/\":;?*|,=`.
.layer-exists = Atributos gráficos: a camada "__ocs_fmt_0__" já existe.
.layer-not-created = Atributos gráficos: não foi possível criar a camada.
.layer-created = Camada "__ocs_fmt_0__" criada com as configurações ativas de atributos gráficos.
.gradient-fill-locked = Preenchimento gradiente: o preenchimento está em uma camada bloqueada.
.select-closed-objects = Selecione primeiro um ou mais objetos fechados.
.locked-objects-skipped = Atributos gráficos: __ocs_fmt_0__ objeto(s) em uma camada bloqueada não foram alterados.
.no-hatch-pattern = Atributos gráficos: nenhum padrão de hachura disponível.
.associated-fill-locked = Atributos gráficos: um preenchimento associado está em uma camada bloqueada.
.one-unsupported = Atributos gráficos: 1 objeto não suportado não foi alterado.
.unsupported-skipped = Atributos gráficos: __ocs_fmt_0__ objetos não suportados não foram alterados.
.fill-transparency = Transparência do preenchimento
.fill-change = Alteração de preenchimento
.line-transparency = Transparência da linha
.cylindrical-short = Cil.
.spherical-short = Esfér.
.hemispherical-short = Hemisf.
.invert-gradient = Inverter gradiente
.tone = Tom
.reset-angle = Redefinir ângulo
.one-color = Uma cor
.two-colors = Duas cores
+35
View File
@@ -6174,3 +6174,38 @@ dock =
.new-group = Новая группа
.browser = Обозреватель
.node-graph = Граф узлов
graphic-attributes =
.title = Графические атрибуты
.set-all-bylayer = Задать всем атрибутам ByLayer
.set-all-byblock = Задать всем атрибутам ByBlock
.remove-bylayer-byblock = Убрать ByLayer / ByBlock
.create-layer-active-settings = Создать слой с текущими настройками
.fills-on-current-layer = Создавать заливки на текущем слое
.edit-hatch = Редактировать штриховку
.edit-gradient = Редактировать градиент
.close-open-object = Выбранный объект разомкнут. Замкнуть его перед созданием заливки? [Yes / No] <Yes>
.close-open-objects = Выбранные объекты разомкнуты (__ocs_fmt_0__). Замкнуть их перед созданием заливки? [Yes / No] <Yes>
.enter-new-layer-name = Введите имя нового слоя:
.invalid-layer-name = Графические атрибуты: введите допустимое имя слоя без <>/\":;?*|,=`.
.layer-exists = Графические атрибуты: слой "__ocs_fmt_0__" уже существует.
.layer-not-created = Графические атрибуты: не удалось создать слой.
.layer-created = Создан слой "__ocs_fmt_0__" с текущими графическими атрибутами.
.gradient-fill-locked = Градиентная заливка: заливка находится на заблокированном слое.
.select-closed-objects = Сначала выберите один или несколько замкнутых объектов.
.locked-objects-skipped = Графические атрибуты: объекты на заблокированном слое (__ocs_fmt_0__) не изменены.
.no-hatch-pattern = Графические атрибуты: нет доступного образца штриховки.
.associated-fill-locked = Графические атрибуты: связанная заливка находится на заблокированном слое.
.one-unsupported = Графические атрибуты: 1 неподдерживаемый объект не изменён.
.unsupported-skipped = Графические атрибуты: неподдерживаемые объекты (__ocs_fmt_0__) не изменены.
.fill-transparency = Прозрачность заливки
.fill-change = Изменение заливки
.line-transparency = Прозрачность линий
.cylindrical-short = Цил.
.spherical-short = Сфер.
.hemispherical-short = Полусф.
.invert-gradient = Инвертировать градиент
.tone = Тон
.reset-angle = Сбросить угол
.one-color = Один цвет
.two-colors = Два цвета
+35
View File
@@ -6096,3 +6096,38 @@ dock =
.new-group = Yeni grup
.browser = Tarayıcı
.node-graph = Düğüm Grafiği
graphic-attributes =
.title = Grafik öznitelikleri
.set-all-bylayer = Tüm öznitelikleri ByLayer yap
.set-all-byblock = Tüm öznitelikleri ByBlock yap
.remove-bylayer-byblock = ByLayer / ByBlock kaldır
.create-layer-active-settings = Etkin ayarlarla katman oluştur
.fills-on-current-layer = Dolguları geçerli katmanda oluştur
.edit-hatch = Taramayı düzenle
.edit-gradient = Gradyanı düzenle
.close-open-object = Seçili nesne açık. Dolgu oluşturmadan önce kapatılsın mı? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ seçili nesne açık. Dolgu oluşturmadan önce kapatılsın mı? [Yes / No] <Yes>
.enter-new-layer-name = Yeni katman için bir ad girin:
.invalid-layer-name = Grafik öznitelikleri: <>/\":;?*|,=` içermeyen geçerli bir katman adı girin.
.layer-exists = Grafik öznitelikleri: "__ocs_fmt_0__" katmanı zaten var.
.layer-not-created = Grafik öznitelikleri: katman oluşturulamadı.
.layer-created = "__ocs_fmt_0__" katmanı etkin grafik öznitelikleriyle oluşturuldu.
.gradient-fill-locked = Gradyan dolgu: dolgu kilitli bir katmanda.
.select-closed-objects = Önce bir veya daha fazla kapalı nesne seçin.
.locked-objects-skipped = Grafik öznitelikleri: kilitli katmandaki __ocs_fmt_0__ nesne değiştirilmedi.
.no-hatch-pattern = Grafik öznitelikleri: kullanılabilir tarama deseni yok.
.associated-fill-locked = Grafik öznitelikleri: ilişkili bir dolgu kilitli katmanda.
.one-unsupported = Grafik öznitelikleri: desteklenmeyen 1 nesne değiştirilmedi.
.unsupported-skipped = Grafik öznitelikleri: desteklenmeyen __ocs_fmt_0__ nesne değiştirilmedi.
.fill-transparency = Dolgu saydamlığı
.fill-change = Dolgu değişikliği
.line-transparency = Çizgi saydamlığı
.cylindrical-short = Sil.
.spherical-short = Küre
.hemispherical-short = Yarıküre
.invert-gradient = Gradyanı ters çevir
.tone = Ton
.reset-angle = Açıyı sıfırla
.one-color = Tek renk
.two-colors = İki renk
+35
View File
@@ -6156,3 +6156,38 @@ dock =
.new-group = 新建组
.browser = 浏览器
.node-graph = 节点图
graphic-attributes =
.title = 图形特性
.set-all-bylayer = 将所有特性设为 ByLayer
.set-all-byblock = 将所有特性设为 ByBlock
.remove-bylayer-byblock = 移除 ByLayer / ByBlock
.create-layer-active-settings = 用当前设置创建图层
.fills-on-current-layer = 在当前图层上创建填充
.edit-hatch = 编辑填充图案
.edit-gradient = 编辑渐变色
.close-open-object = 选定对象未闭合。创建填充前是否将其闭合? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ 个选定对象未闭合。创建填充前是否将其闭合? [Yes / No] <Yes>
.enter-new-layer-name = 输入新图层的名称:
.invalid-layer-name = 图形特性: 请输入不含 <>/\":;?*|,=` 的有效图层名称。
.layer-exists = 图形特性: 图层 "__ocs_fmt_0__" 已存在。
.layer-not-created = 图形特性: 无法创建图层。
.layer-created = 已用当前图形特性设置创建图层 "__ocs_fmt_0__"。
.gradient-fill-locked = 渐变填充: 填充位于锁定的图层上。
.select-closed-objects = 请先选择一个或多个闭合对象。
.locked-objects-skipped = 图形特性: 锁定图层上的 __ocs_fmt_0__ 个对象未更改。
.no-hatch-pattern = 图形特性: 没有可用的填充图案。
.associated-fill-locked = 图形特性: 关联的填充位于锁定的图层上。
.one-unsupported = 图形特性: 1 个不支持的对象未更改。
.unsupported-skipped = 图形特性: __ocs_fmt_0__ 个不支持的对象未更改。
.fill-transparency = 填充透明度
.fill-change = 更改填充
.line-transparency = 线的透明度
.cylindrical-short = 圆柱
.spherical-short = 球形
.hemispherical-short = 半球
.invert-gradient = 反转渐变
.tone = 明暗
.reset-angle = 重置角度
.one-color = 单色
.two-colors = 双色
+35
View File
@@ -6168,3 +6168,38 @@ dock =
.new-group = 新增群組
.browser = 瀏覽器
.node-graph = 節點圖
graphic-attributes =
.title = 圖形特性
.set-all-bylayer = 將所有特性設為 ByLayer
.set-all-byblock = 將所有特性設為 ByBlock
.remove-bylayer-byblock = 移除 ByLayer / ByBlock
.create-layer-active-settings = 以目前設定建立圖層
.fills-on-current-layer = 在目前圖層上建立填充
.edit-hatch = 編輯填充線
.edit-gradient = 編輯漸層
.close-open-object = 選取的物件未封閉。建立填充前是否將其封閉? [Yes / No] <Yes>
.close-open-objects = __ocs_fmt_0__ 個選取的物件未封閉。建立填充前是否將其封閉? [Yes / No] <Yes>
.enter-new-layer-name = 輸入新圖層的名稱:
.invalid-layer-name = 圖形特性: 請輸入不含 <>/\":;?*|,=` 的有效圖層名稱。
.layer-exists = 圖形特性: 圖層 "__ocs_fmt_0__" 已存在。
.layer-not-created = 圖形特性: 無法建立圖層。
.layer-created = 已以目前圖形特性設定建立圖層 "__ocs_fmt_0__"。
.gradient-fill-locked = 漸層填充: 填充位於鎖定的圖層上。
.select-closed-objects = 請先選取一個或多個封閉物件。
.locked-objects-skipped = 圖形特性: 鎖定圖層上的 __ocs_fmt_0__ 個物件未變更。
.no-hatch-pattern = 圖形特性: 沒有可用的填充線樣式。
.associated-fill-locked = 圖形特性: 關聯的填充位於鎖定的圖層上。
.one-unsupported = 圖形特性: 1 個不支援的物件未變更。
.unsupported-skipped = 圖形特性: __ocs_fmt_0__ 個不支援的物件未變更。
.fill-transparency = 填充透明度
.fill-change = 變更填充
.line-transparency = 線的透明度
.cylindrical-short = 圓柱
.spherical-short = 球形
.hemispherical-short = 半球
.invert-gradient = 反轉漸層
.tone = 明暗
.reset-angle = 重設角度
.one-color = 單色
.two-colors = 雙色
+5
View File
@@ -500,6 +500,11 @@ impl OpenCADStudio {
return Some(Task::done(Message::ToggleProperties));
}
// ── GRAPHICATTRIBUTES — toggle Graphic Attributes palette ───────────
"GRAPHICATTRIBUTES" => {
return Some(Task::done(Message::ToggleGraphicAttributes));
}
// ── FILETAB — toggle file/document tabs ──────────────────────────────
"FILETAB" => {
return Some(Task::done(Message::ToggleFileTabs));
+4
View File
@@ -3,6 +3,10 @@ use super::*;
impl OpenCADStudio {
pub(super) fn dispatch_layers(&mut self, cmd: &str, i: usize) -> Option<Task<Message>> {
match cmd {
cmd if cmd.starts_with("GRAPHICATTRIBUTELAYER ") => {
let name = cmd.trim_start_matches("GRAPHICATTRIBUTELAYER").trim();
return Some(self.create_graphic_attributes_layer(name));
}
// ── Layer object commands ──────────────────────────────────────
"LAYOFF" => {
let handles: Vec<_> = self.tabs[i]
+1
View File
@@ -468,6 +468,7 @@ inventory::submit!(crate::command::CommandRegistration {
"DSETTINGS",
"PARAMETERS",
"GRID",
"GRAPHICATTRIBUTES",
"ISODRAFT",
"ISOPLANE",
"OSNAP",
+19
View File
@@ -30,6 +30,11 @@ pub struct AppConfig {
/// General edge-stack dock layout (which panels are docked, side, order,
/// width and auto-collapse) for the Properties panel and block palette.
pub dock: crate::ui::dock::DockState,
/// Whether the optional Graphic Attributes palette is visible.
pub show_graphic_attributes: bool,
/// Graphic Attributes creates fills on the current layer instead of the
/// layer of the filled object.
pub graphic_fills_on_current_layer: bool,
/// Add a newly selected annotation scale to existing annotative objects.
pub annotation_auto_scale: i8,
/// Ribbon collapse density.
@@ -52,6 +57,8 @@ impl Default for AppConfig {
start: StartConfig::default(),
statusbar: StatusBarConfig::default(),
dock: crate::ui::dock::DockState::default(),
show_graphic_attributes: false,
graphic_fills_on_current_layer: false,
annotation_auto_scale: -4,
ribbon: RibbonConfig::default(),
plot: PlotDialogState::default(),
@@ -612,6 +619,18 @@ mod tests {
assert_eq!(deserialized.model_space.selection_window_color, 5);
}
#[test]
fn graphic_attributes_visibility_defaults_off_and_round_trips() {
let missing: AppConfig = serde_json::from_str("{}").expect("deserialize old config");
assert!(!missing.show_graphic_attributes);
let mut original = AppConfig::default();
original.show_graphic_attributes = true;
let serialized = serde_json::to_string(&original).expect("serialize config");
let restored: AppConfig = serde_json::from_str(&serialized).expect("deserialize config");
assert!(restored.show_graphic_attributes);
}
#[test]
fn test_parse_theme_name() {
assert_eq!(parse_theme_name("light"), Some(iced::Theme::Light));
+12
View File
@@ -442,6 +442,11 @@ impl OpenCADStudio {
self.show_properties = true;
self.ribbon.set_properties(true);
}
PanelId::GraphicAttributes => {
self.show_graphic_attributes = true;
self.ribbon.set_graphic_attributes(true);
self.save_config();
}
PanelId::BlockPalette => self.open_blocks_palette(None),
PanelId::ExternalReferences => {
self.show_external_references = true;
@@ -488,6 +493,12 @@ impl OpenCADStudio {
self.show_layers = false;
self.ribbon.deactivate_tool_if("LAYERS");
}
PanelId::GraphicAttributes => {
self.show_graphic_attributes = false;
self.ribbon.set_graphic_attributes(false);
self.graphic_attributes.close_popups();
self.save_config();
}
}
self.dock_unpeek(id);
// A closed pallet cannot stay held by the pointer.
@@ -555,6 +566,7 @@ impl OpenCADStudio {
PanelId::Count => self.count_palette.show,
PanelId::SheetSetManager => self.sheet_set.show,
PanelId::Layers => self.show_layers,
PanelId::GraphicAttributes => self.show_graphic_attributes,
}
}
+14
View File
@@ -381,6 +381,20 @@ impl OpenCADStudio {
};
match id {
crate::ui::dock::PanelId::Properties => tab.properties.view(width, chrome),
crate::ui::dock::PanelId::GraphicAttributes => crate::ui::window::graphic_attributes::view(
&self.graphic_attributes,
&tab.scene,
&tab.properties,
width,
chrome,
self.dock
.location(id)
.map_or(crate::app::config::DockSide::Right, |(side, _)| side),
matches!(
self.color_pick_target,
Some((crate::app::ColorPickTarget::Gradient(_), _))
),
),
crate::ui::dock::PanelId::BlockPalette => {
crate::ui::window::block_palette::view(&self.block_palette, width, chrome)
}
+11
View File
@@ -817,6 +817,9 @@ pub(super) struct OpenCADStudio {
show_properties: bool,
/// The Layer Manager pallet (LAYERS) is open.
pub(crate) show_layers: bool,
/// Whether the Graphic Attributes palette is shown (GRAPHICATTRIBUTES).
show_graphic_attributes: bool,
graphic_attributes: crate::ui::window::graphic_attributes::GraphicAttributesState,
/// Docked Insert Block panel visibility.
pub(crate) show_block_palette: bool,
/// Node graph overlay over the viewport.
@@ -1616,6 +1619,9 @@ pub enum ColorPickerTab {
/// Where a colour chosen in the standalone palette window should be applied.
#[derive(Debug, Clone)]
pub enum ColorPickTarget {
Gradient(u8),
GraphicAttributesLine,
GraphicAttributesSolid,
DimStyle(DsField),
MLeader(&'static str),
Table(u8, &'static str),
@@ -2155,6 +2161,7 @@ pub enum PasteFocus {
#[derive(Debug, Clone)]
pub enum Message {
GraphicAttributes(crate::ui::window::graphic_attributes::GraphicAttributesMsg),
SpaceMouseWake,
SpaceMouseFrame(iced::time::Instant),
SpaceMouseFocus(iced::window::Id, bool),
@@ -2892,6 +2899,8 @@ pub enum Message {
ToggleViewCube,
/// Toggle the Properties panel visibility (PROPERTIES).
ToggleProperties,
/// Toggle the Graphic Attributes panel visibility (GRAPHICATTRIBUTES).
ToggleGraphicAttributes,
/// Toggle the document file tabs at the top (FILETAB).
ToggleFileTabs,
/// Toggle the layout tabs at the bottom (LAYOUTTAB).
@@ -4309,6 +4318,8 @@ impl OpenCADStudio {
render_mode_preview: None,
show_properties: true,
show_layers: false,
show_graphic_attributes: false,
graphic_attributes: Default::default(),
show_block_palette: false,
show_node_graph: false,
property_target_override: None,
+51 -1
View File
@@ -394,6 +394,10 @@ impl OpenCADStudio {
// dropdown so the dispatched command's new prompt is
// immediately visible on the overlay.
self.command_line.close_history();
if self.awaiting_fill_close_answer() {
let input = std::mem::take(&mut self.command_line.input);
return self.on_graphic_fill_close_input(&input);
}
// A leading `>` was only a "literal spaces" typing hint (see
// CommandSpace) — drop it before the input is interpreted.
// Free-form text prompts keep it: there it is content, not a
@@ -1100,6 +1104,9 @@ impl OpenCADStudio {
if !self.command_line.input.trim().is_empty() {
return self.update(Message::CommandSubmit);
}
if self.awaiting_fill_close_answer() {
return self.on_graphic_fill_close_input("");
}
// A grip edit is not an active CAD command, but its Dynamic Input
// fields use the same keyboard path. Route Enter through CommandSubmit,
// whose grip branch resolves Distance / Angle and finalizes the edit.
@@ -1154,6 +1161,11 @@ impl OpenCADStudio {
if self.ribbon.escape_extension() {
return Task::none();
}
if self.awaiting_fill_close_answer() {
self.graphic_attributes.pending_fill_close = None;
self.command_line.push_info(crate::t!("*Cancel*").as_ref());
return Task::none();
}
// Esc drops an unconsumed one-shot snap override and closes
// its menu (#337). Falls through — Esc keeps its usual effect.
self.snap_override_popup = None;
@@ -2225,6 +2237,35 @@ impl OpenCADStudio {
Task::none()
}
pub(super) fn on_ribbon_lineweight_changed(
&mut self,
lw: codec::types::LineWeight,
) -> Task<Message> {
let i = self.active_tab;
self.ribbon.close_dropdown();
let handles = self.property_target_handles(i);
if handles.is_empty() {
if self.has_property_selection(i) {
return Task::none();
}
// Persist into the tab's header (CELWEIGHT). #21.
self.tabs[i].scene.document.header.current_line_weight = lw.value();
self.tabs[i].dirty = true;
self.ribbon.active_lineweight = lw;
} else {
// Lineweight is baked into the cached wire geometry —
// re-tessellate so the change shows immediately (issue #231
// class).
self.apply_property_op(i, "CHPROP", &handles, |app, handle| {
if let Some(entity) = app.tabs[i].scene.document.get_entity_mut(handle) {
crate::scene::view::dispatch::apply_line_weight(entity, lw);
}
});
self.ribbon.active_lineweight = lw;
}
Task::none()
}
pub(super) fn on_ribbon_linetype_changed(&mut self, lt: String) -> Task<Message> {
let i = self.active_tab;
self.ribbon.close_dropdown();
@@ -2331,11 +2372,20 @@ impl OpenCADStudio {
pub(super) fn on_prop_hatch_pattern_changed(&mut self, name: String) -> Task<Message> {
let i = self.active_tab;
let handles = self.property_target_handles(i);
self.apply_hatch_pattern(i, &handles, name)
}
pub(super) fn apply_hatch_pattern(
&mut self,
i: usize,
handles: &[codec::Handle],
name: String,
) -> Task<Message> {
if !handles.is_empty() {
use crate::scene::model::hatch_patterns;
if let Some(entry) = hatch_patterns::find(&name) {
self.push_undo_snapshot(i, "HATCHEDIT");
for &handle in &handles {
for &handle in handles {
if let Some(codec::EntityType::Hatch(dxf)) =
self.tabs[i].scene.document.get_entity_mut(handle)
{
+9
View File
@@ -1326,6 +1326,8 @@ impl OpenCADStudio {
dock.ensure_settings();
dock
},
show_graphic_attributes: self.show_graphic_attributes,
graphic_fills_on_current_layer: self.graphic_attributes.fill_on_current_layer,
annotation_auto_scale: self.annotation_auto_scale,
ribbon: crate::app::config::RibbonConfig {
collapse: self.ribbon.collapse_mode(),
@@ -1384,6 +1386,13 @@ impl OpenCADStudio {
let mut dock = cfg.dock;
dock.ensure_settings();
self.dock = dock;
self.show_graphic_attributes = cfg.show_graphic_attributes;
self.graphic_attributes.fill_on_current_layer = cfg.graphic_fills_on_current_layer;
if self.show_graphic_attributes {
self.dock.dock_below_properties(crate::ui::dock::PanelId::GraphicAttributes);
}
self.ribbon
.set_graphic_attributes(self.show_graphic_attributes);
self.annotation_auto_scale = cfg.annotation_auto_scale.clamp(-4, 4);
self.ribbon.set_collapse_mode(cfg.ribbon.collapse);
self.plot_dialog = cfg.plot;
File diff suppressed because it is too large. Load diff
+56 -27
View File
@@ -99,6 +99,7 @@ mod context_menu;
mod dialog;
mod dynamic;
mod file;
mod graphic_attributes;
pub(in crate::app) use file::background_task;
#[cfg(not(target_arch = "wasm32"))]
pub(in crate::app) use file::native_paths_match;
@@ -473,6 +474,10 @@ impl OpenCADStudio {
}
}
self.refresh_gpu_status();
if self.graphic_attributes.tracks_selection() {
let selected = self.tabs[self.active_tab].scene.selected_handles_in_order();
self.graphic_attributes.retain_selection(&selected);
}
self.show_next_startup_modal();
self.sync_open_command_history();
// Close the document-level first-touch transaction started by
@@ -486,6 +491,7 @@ impl OpenCADStudio {
.active_cmd
.as_ref()
.map(|c| c.prompt())
.or_else(|| self.graphic_attributes.fill_close_prompt())
.or_else(|| self.pending_pick_label());
self.command_line.set_step_prompt(prompt);
// Mirror the step's clickable options so they render as buttons (#304).
@@ -493,6 +499,14 @@ impl OpenCADStudio {
.active_cmd
.as_ref()
.map(|c| c.options())
.or_else(|| {
self.graphic_attributes.pending_fill_close.as_ref().map(|_| {
vec![
crate::command::CmdOption::new("Yes", "Y"),
crate::command::CmdOption::new("No", "N"),
]
})
})
.unwrap_or_default();
self.command_line.set_step_options(opts);
// Persist UI preferences whenever a toggle changes them (issue #68).
@@ -2535,6 +2549,9 @@ impl OpenCADStudio {
// finishes the step like Enter. (#304)
self.command_line.input.clear();
self.command_line.close_history();
if self.awaiting_fill_close_answer() {
return self.on_graphic_fill_close_input(&kw);
}
if kw.is_empty() {
return self.feed_command(crate::command::StepInput::Enter);
}
@@ -3877,6 +3894,7 @@ impl OpenCADStudio {
}
Message::ViewportLeftPress => {
self.graphic_attributes.open_menu = None;
let sweep = self.sync_active_field_if_any();
Task::batch(vec![sweep, self.on_viewport_left_press()])
}
@@ -3884,6 +3902,7 @@ impl OpenCADStudio {
Message::ViewportLeftRelease => self.on_viewport_left_release(),
Message::ViewportRightPress => {
self.graphic_attributes.open_menu = None;
let i = self.active_tab;
self.ribbon.close_dropdown();
// Shift+RMB: the one-shot snap override menu at the cursor —
@@ -3986,7 +4005,10 @@ impl OpenCADStudio {
self.unfocus_widgets()
}
Message::ViewportMiddlePress => self.on_viewport_middle_press(),
Message::ViewportMiddlePress => {
self.graphic_attributes.open_menu = None;
self.on_viewport_middle_press()
}
Message::ViewportMiddleRelease => {
let i = self.active_tab;
@@ -4318,6 +4340,14 @@ impl OpenCADStudio {
self.ribbon.set_properties(self.show_properties);
Task::none()
}
Message::ToggleGraphicAttributes => {
let id = crate::ui::dock::PanelId::GraphicAttributes;
let open = !self.show_graphic_attributes;
if open {
self.dock.dock_below_properties(id);
}
self.dock_set_open(id, open)
}
Message::ToggleFileTabs => {
self.show_file_tabs ^= true;
self.ribbon.set_file_tabs(self.show_file_tabs);
@@ -6697,31 +6727,7 @@ impl OpenCADStudio {
Task::none()
}
Message::RibbonLinetypeChanged(lt) => self.on_ribbon_linetype_changed(lt),
Message::RibbonLineweightChanged(lw) => {
let i = self.active_tab;
self.ribbon.close_dropdown();
let handles = self.property_target_handles(i);
if handles.is_empty() {
if self.has_property_selection(i) {
return Task::none();
}
// Persist into the tab's header (CELWEIGHT). #21.
self.tabs[i].scene.document.header.current_line_weight = lw.value();
self.tabs[i].dirty = true;
self.ribbon.active_lineweight = lw;
} else {
// Lineweight is baked into the cached wire geometry —
// re-tessellate so the change shows immediately (issue #231
// class).
self.apply_property_op(i, "CHPROP", &handles, |app, handle| {
if let Some(entity) = app.tabs[i].scene.document.get_entity_mut(handle) {
crate::scene::view::dispatch::apply_line_weight(entity, lw);
}
});
self.ribbon.active_lineweight = lw;
}
Task::none()
}
Message::RibbonLineweightChanged(lw) => self.on_ribbon_lineweight_changed(lw),
Message::RibbonStyleChanged { key, name } => self.on_ribbon_style_changed(key, name),
@@ -7132,13 +7138,28 @@ impl OpenCADStudio {
Message::PropAttrCommit(tag) => self.on_prop_attr_commit(tag),
Message::PropPointerPressed => {
if !self.dock_panel_visible(crate::ui::dock::PanelId::Properties) {
if !self.dock_panel_visible(crate::ui::dock::PanelId::Properties)
&& !self.dock_panel_visible(crate::ui::dock::PanelId::GraphicAttributes)
{
return Task::none();
}
crate::ui::properties::sync_active_field_task()
}
Message::PropSyncActive(focused) => {
// The Graphic Attributes linetype scale field behaves like a
// Properties field: the first click selects its value.
let scale_field = iced::widget::Id::new(
crate::ui::window::graphic_attributes::LINETYPE_SCALE_FIELD,
);
if focused.as_ref() == Some(&scale_field) {
if !std::mem::replace(&mut self.graphic_attributes.linetype_scale_focused, true) {
return iced::widget::operation::select_all(scale_field);
}
return Task::none();
}
self.graphic_attributes.linetype_scale_focused = false;
self.graphic_attributes.linetype_scale_input = None;
let panel = &mut self.tabs[self.active_tab].properties;
if let Some(id) = focused.as_ref() {
if let Some(key) = panel.prop_field_key_for_id(id) {
@@ -9853,6 +9874,7 @@ impl OpenCADStudio {
Message::PlotDialogOpen => self.on_plot_dialog_open(),
Message::PlotDlg(m) => self.on_plot_dlg(m),
Message::BlockPalette(m) => self.on_block_palette(m),
Message::GraphicAttributes(m) => self.on_graphic_attributes(m),
Message::Dock(m) => self.on_dock(m),
Message::PrintAllOpen => self.on_print_all_open(),
Message::PrintAllToggle(name) => {
@@ -11015,6 +11037,13 @@ impl OpenCADStudio {
Task::none()
}
Message::OpenColorWindow(target, color) => {
if matches!(
target,
crate::app::ColorPickTarget::GraphicAttributesLine
| crate::app::ColorPickTarget::GraphicAttributesSolid
) {
self.graphic_attributes.open_menu = None;
}
self.color_pick_target = Some((target, color));
// Always open the shared CAD colour picker on the indexed ACI page.
+12
View File
@@ -13,6 +13,7 @@ use crate::scene::pick::grip::{find_hit_grip, find_hit_grip_paper, find_hit_grip
use crate::scene::{
self, hover_id, CubeRegion, Scene, VIEWCUBE_DRAW_PX, VIEWCUBE_PAD, VIEWCUBE_PX,
};
use crate::ui::window::graphic_attributes::GraphicAttributesMsg;
use crate::ui::PropertiesPanel;
use codec::types::Color as AcadColor;
use codec::{EntityType as AcadEntityType, Handle};
@@ -1156,6 +1157,17 @@ impl OpenCADStudio {
}
let s = crate::ui::color_select::color_to_aci_string(color);
let edit = match self.color_pick_target.take().map(|(target, _)| target) {
Some(crate::app::ColorPickTarget::Gradient(index)) => {
Some(Message::GraphicAttributes(GraphicAttributesMsg::Gradient(
crate::ui::window::gradient_editor::GradientMsg::Color(index, color),
)))
}
Some(crate::app::ColorPickTarget::GraphicAttributesLine) => Some(
Message::GraphicAttributes(GraphicAttributesMsg::LineColor(color)),
),
Some(crate::app::ColorPickTarget::GraphicAttributesSolid) => Some(
Message::GraphicAttributes(GraphicAttributesMsg::FillColor(color)),
),
Some(crate::app::ColorPickTarget::DimStyle(f)) => Some(Message::DsEdit(f, s)),
Some(crate::app::ColorPickTarget::MLeader(f)) => {
Some(Message::MLeaderStyleEdit { field: f, value: s })
+40
View File
@@ -354,6 +354,46 @@ impl CadCommand for ValuePromptCommand {
}
}
/// One-value prompt that preserves spaces and letter casing. This is intended
/// for symbol names entered through the command line, where a space belongs to
/// the value instead of submitting the current token.
pub struct FreeTextValuePromptCommand {
name: &'static str,
prompt: &'static str,
}
impl FreeTextValuePromptCommand {
pub fn new(name: &'static str, prompt: &'static str) -> Self {
Self { name, prompt }
}
}
impl CadCommand for FreeTextValuePromptCommand {
fn name(&self) -> &'static str {
self.name
}
fn prompt(&self) -> String {
crate::t!(self.prompt).into_owned()
}
fn input_kind(&self) -> InputKind {
InputKind::FreeText
}
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
Some(CmdResult::Dispatch(format!("{} {}", self.name, text.trim())))
}
fn on_point(&mut self, _pt: DVec3) -> CmdResult {
CmdResult::NeedPoint
}
fn on_enter(&mut self) -> CmdResult {
CmdResult::Dispatch(format!("{} ", self.name))
}
}
/// Interactive pick for `UCS FACE` and `UCS OBJECT`.
///
/// Hands the picked entity to the inline `UCS FACE <handle> <x,y,z>` /
+33
View File
@@ -5772,6 +5772,39 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
"New group" => Some(("dock", "new-group")),
"Browser" => Some(("dock", "browser")),
"Node Graph" => Some(("dock", "node-graph")),
"Graphic Attributes" => Some(("graphic-attributes", "title")),
"Set all attributes ByLayer" => Some(("graphic-attributes", "set-all-bylayer")),
"Set all attributes ByBlock" => Some(("graphic-attributes", "set-all-byblock")),
"Remove ByLayer / ByBlock" => Some(("graphic-attributes", "remove-bylayer-byblock")),
"Create Layer with active settings" => Some(("graphic-attributes", "create-layer-active-settings")),
"Create fills on the current layer" => Some(("graphic-attributes", "fills-on-current-layer")),
"Edit hatch" => Some(("graphic-attributes", "edit-hatch")),
"Edit gradient" => Some(("graphic-attributes", "edit-gradient")),
"The selected object is open. Close it before creating the fill? [Yes / No] <Yes>" => Some(("graphic-attributes", "close-open-object")),
"{count} selected objects are open. Close them before creating the fill? [Yes / No] <Yes>" => Some(("graphic-attributes", "close-open-objects")),
"Enter a name for the new layer:" => Some(("graphic-attributes", "enter-new-layer-name")),
"Graphic Attributes: enter a valid layer name without <>/\\\":;?*|,=`." => Some(("graphic-attributes", "invalid-layer-name")),
"Graphic Attributes: layer \"{name}\" already exists." => Some(("graphic-attributes", "layer-exists")),
"Graphic Attributes: the layer could not be created." => Some(("graphic-attributes", "layer-not-created")),
"Created layer \"{name}\" with the active Graphic Attributes settings." => Some(("graphic-attributes", "layer-created")),
"Gradient Fill: the fill is on a locked layer." => Some(("graphic-attributes", "gradient-fill-locked")),
"Select one or more closed objects first." => Some(("graphic-attributes", "select-closed-objects")),
"Graphic Attributes: {} object(s) on a locked layer were not changed." => Some(("graphic-attributes", "locked-objects-skipped")),
"Graphic Attributes: no hatch pattern is available." => Some(("graphic-attributes", "no-hatch-pattern")),
"Graphic Attributes: an associated fill is on a locked layer." => Some(("graphic-attributes", "associated-fill-locked")),
"Graphic Attributes: 1 unsupported object was not changed." => Some(("graphic-attributes", "one-unsupported")),
"Graphic Attributes: {skipped} unsupported objects were not changed." => Some(("graphic-attributes", "unsupported-skipped")),
"Fill transparency" => Some(("graphic-attributes", "fill-transparency")),
"Fill change" => Some(("graphic-attributes", "fill-change")),
"Line transparency" => Some(("graphic-attributes", "line-transparency")),
"Cyl." => Some(("graphic-attributes", "cylindrical-short")),
"Spher." => Some(("graphic-attributes", "spherical-short")),
"Hemi." => Some(("graphic-attributes", "hemispherical-short")),
"Invert gradient" => Some(("graphic-attributes", "invert-gradient")),
"Tone" => Some(("graphic-attributes", "tone")),
"Reset angle" => Some(("graphic-attributes", "reset-angle")),
"One Color" => Some(("graphic-attributes", "one-color")),
"Two Colors" => Some(("graphic-attributes", "two-colors")),
_ => None,
}
}
+7
View File
@@ -253,6 +253,13 @@ impl HatchCommand {
self
}
pub fn with_pattern(mut self, name: impl Into<String>, pattern: HatchPattern) -> Self {
self.pattern_override = Some((name.into(), pattern));
self
}
pub fn finish_selected(mut self) -> CmdResult { self.on_enter() }
fn set_object_selection(&mut self, handles: Vec<Handle>) {
let mut segments = Vec::new();
for handle in &handles {
@@ -0,0 +1,14 @@
use crate::modules::{IconKind, ModuleEvent, ToolDef};
pub const ICON: IconKind = IconKind::Svg(include_bytes!(
"../../../assets/icons/graphic_attributes.svg"
));
pub fn tool() -> ToolDef {
ToolDef {
id: "GRAPHICATTRIBUTES",
label: "Graphic Attributes",
icon: ICON,
event: ModuleEvent::Command("GRAPHICATTRIBUTES".to_string()),
}
}
+2
View File
@@ -3,6 +3,7 @@
mod cascade;
mod count_palette;
mod file_tabs;
mod graphic_attributes_palette;
mod layout_tabs;
pub mod limits;
mod orbit;
@@ -123,6 +124,7 @@ impl CadModule for ViewModule {
RibbonItem::LargeTool(tool_palettes::tool()),
RibbonItem::LargeTool(properties_palette::tool()),
RibbonItem::LargeTool(count_palette::tool()),
RibbonItem::LargeTool(graphic_attributes_palette::tool()),
RibbonItem::LargeTool(sheetset::tool()),
],
},
+8 -6
View File
@@ -103,7 +103,7 @@ fn family_from_stored_line(
/// Preserve the selected hue while moving its HSL lightness towards the
/// persisted one-colour tint/shade target (0 = black, 1 = white).
fn gradient_tint_color(base: [f32; 4], target: f32) -> [f32; 4] {
pub(crate) fn gradient_tint_color(base: [f32; 4], target: f32) -> [f32; 4] {
let max = base[0].max(base[1]).max(base[2]);
let min = base[0].min(base[1]).min(base[2]);
let lightness = (max + min) * 0.5;
@@ -1394,10 +1394,12 @@ impl Scene {
style.0 = crate::scene::view::render::adapt_to_bg(style.0, hatch_bg);
m.aci = style.4;
m.line_weight_px = style.3;
// A gradient's colour is its first stop (already baked into
// the cached model); only solid / pattern fills take the
// entity's resolved colour.
if !matches!(m.pattern, model::hatch_model::HatchPattern::Gradient { .. }) {
// Gradient RGB comes from its own colour stops, while
// transparency remains an entity property shared by both
// stops. Solid/pattern fills take the complete style.
if matches!(m.pattern, model::hatch_model::HatchPattern::Gradient { .. }) {
m.set_alpha(style.0[3]);
} else {
m.color = style.0;
}
if let EntityType::Hatch(dxf) = e {
@@ -2213,7 +2215,7 @@ impl Scene {
.colors
.get(i)
.and_then(|e| e.color.rgb())
.map(|(r, g, b)| [r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0, 1.0])
.map(|(r, g, b)| [r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0, color[3]])
};
gradient_color1 = stop(0);
let color1 = gradient_color1.unwrap_or(color);
+37
View File
@@ -4,6 +4,43 @@ use codec::types::{Vector2, Vector3};
use kernel::geom2d::{refine_spline_boundary, triangulate_rings, Curve, NurbsCurve};
use kernel::tessellation::DEFAULT_ANGLE;
#[test]
fn gradient_stops_keep_entity_transparency() {
let mut hatch = Hatch::new();
hatch.is_solid = true;
hatch
.paths
.push(rectangle([0.0, 0.0], [10.0, 10.0], [0.0; 2]));
hatch.gradient_color.enabled = true;
hatch.gradient_color.name = "LINEAR".into();
hatch.gradient_color.colors = vec![
codec::entities::hatch::GradientColorEntry {
value: 0.0,
color: codec::types::Color::Rgb { r: 255, g: 0, b: 0 },
},
codec::entities::hatch::GradientColorEntry {
value: 1.0,
color: codec::types::Color::Rgb { r: 0, g: 0, b: 255 },
},
];
let mut model = Scene::hatch_model_from_dxf(&hatch, [0.2, 0.3, 0.4, 0.35]).unwrap();
assert!((model.color[3] - 0.35).abs() < f32::EPSILON);
let crate::scene::model::hatch_model::HatchPattern::Gradient { color2, .. } = &model.pattern
else {
panic!("gradient hatch must produce a gradient render pattern");
};
assert!((color2[3] - 0.35).abs() < f32::EPSILON);
model.set_alpha(0.6);
assert!((model.color[3] - 0.6).abs() < f32::EPSILON);
let crate::scene::model::hatch_model::HatchPattern::Gradient { color2, .. } = &model.pattern
else {
unreachable!();
};
assert!((color2[3] - 0.6).abs() < f32::EPSILON);
}
fn narrow(clearance: f64, offset: [f64; 2]) -> NurbsCurve {
let line = |a: [f64; 2], b: [f64; 2]| {
[
+1
View File
@@ -37,6 +37,7 @@ pub use page_setup::{apply_default_page_setup, document_page_setups, rotated_mar
mod dwg_native_constraints;
mod entity;
pub use camera_ops::named_view_center;
pub(crate) use entity::gradient_tint_color;
pub use entity::CreateBlockOptions;
mod group_layer;
#[cfg(test)]
+12
View File
@@ -272,6 +272,18 @@ pub struct HatchModel {
pub draw_depth: f32,
}
impl HatchModel {
/// Apply an entity's resolved opacity to every colour stop. Gradient stop
/// colours come from the HATCH payload, but transparency remains a common
/// entity property and must affect both ends equally.
pub(crate) fn set_alpha(&mut self, alpha: f32) {
self.color[3] = alpha;
if let HatchPattern::Gradient { color2, .. } = &mut self.pattern {
color2[3] = alpha;
}
}
}
impl HatchModel {
pub(crate) fn gradient_frame(
&self,
+10 -2
View File
@@ -475,7 +475,11 @@ impl Scene {
_ => model.clone(),
};
let style = self.render_style(entity);
m.color = style.0;
if matches!(m.pattern, model::hatch_model::HatchPattern::Gradient { .. }) {
m.set_alpha(style.0[3]);
} else {
m.color = style.0;
}
m.aci = style.4;
m.line_weight_px = style.3;
if let EntityType::Hatch(dxf) = entity {
@@ -600,7 +604,11 @@ impl Scene {
_ => model.clone(),
};
let style = self.render_style(entity);
hatch.color = style.0;
if matches!(hatch.pattern, model::hatch_model::HatchPattern::Gradient { .. }) {
hatch.set_alpha(style.0[3]);
} else {
hatch.color = style.0;
}
hatch.aci = style.4;
hatch.line_weight_px = style.3;
hatch.draw_depth = depth_map.get(&handle.value()).map_or(0.0, |depth| depth[0]);
+15 -13
View File
@@ -230,18 +230,7 @@ fn color_selector_with_indicator<'a>(
}
let popup = container(color_list(extras, on_select, on_more))
.style(|theme: &Theme| {
let palette = theme.palette();
container::Style {
background: Some(Background::Color(palette.background.weak.color)),
border: Border {
color: palette.background.neutral.color,
width: 1.0,
radius: 2.0.into(),
},
..Default::default()
}
})
.style(popup_panel_style)
.padding(2);
// `DropDown` keeps the popup outside the surrounding form layout and
@@ -255,7 +244,20 @@ fn color_selector_with_indicator<'a>(
.into()
}
fn list_row_style(theme: &Theme, status: button::Status) -> button::Style {
pub(crate) fn popup_panel_style(theme: &Theme) -> container::Style {
let palette = theme.palette();
container::Style {
background: Some(Background::Color(palette.background.weak.color)),
border: Border {
color: palette.background.neutral.color,
width: 1.0,
radius: 2.0.into(),
},
..Default::default()
}
}
pub(crate) fn list_row_style(theme: &Theme, status: button::Status) -> button::Style {
let palette = theme.palette();
let hovered = matches!(status, button::Status::Hovered);
let text_color = if hovered {
+45 -2
View File
@@ -104,6 +104,7 @@ pub const DOCK_HOVER_DELAY: std::time::Duration = std::time::Duration::from_mill
#[serde(rename_all = "snake_case")]
pub enum PanelId {
Properties,
GraphicAttributes,
BlockPalette,
ExternalReferences,
/// Outline of the drawing's origin planes, open sketch and solid bodies.
@@ -122,8 +123,9 @@ pub enum PanelId {
impl PanelId {
/// Every panel, in the order the pallet menu lists them.
pub const ALL: [PanelId; 9] = [
pub const ALL: [PanelId; 10] = [
PanelId::Properties,
PanelId::GraphicAttributes,
PanelId::BlockPalette,
PanelId::ExternalReferences,
PanelId::Browser,
@@ -138,6 +140,7 @@ impl PanelId {
pub fn title(self) -> &'static str {
match self {
PanelId::Properties => "Properties",
PanelId::GraphicAttributes => "Graphic Attributes",
PanelId::BlockPalette => "Block Palette",
PanelId::ExternalReferences => "External References",
PanelId::Browser => "Browser",
@@ -153,6 +156,7 @@ impl PanelId {
pub fn icon(self) -> &'static [u8] {
match self {
PanelId::Properties => include_bytes!("../../assets/icons/properties.svg"),
PanelId::GraphicAttributes => include_bytes!("../../assets/icons/graphic_attributes.svg"),
PanelId::BlockPalette => include_bytes!("../../assets/icons/blocks/insert.svg"),
PanelId::ExternalReferences => crate::ui::icons::FOLDER_OPEN,
PanelId::Browser => include_bytes!("../../assets/icons/content_browser.svg"),
@@ -168,6 +172,7 @@ impl PanelId {
fn default_width(self) -> f32 {
match self {
PanelId::Properties => 250.0,
PanelId::GraphicAttributes => 250.0,
PanelId::BlockPalette => 260.0,
PanelId::ExternalReferences => 460.0,
PanelId::Browser => 230.0,
@@ -518,6 +523,23 @@ impl DockState {
self.floating.iter_mut().for_each(FloatPanel::heal);
}
/// Stack `id` under Properties in its group (or dock it at the end of
/// the left edge) unless it already has a place, which is then kept.
pub fn dock_below_properties(&mut self, id: PanelId) {
if self.is_placed(id) {
return;
}
match self.location(PanelId::Properties) {
Some((side, group)) => {
let index = self.groups(side)[group].panels.len();
self.join_group(id, side, group, index);
}
None => {
self.dock(id, DockSide::Left, usize::MAX);
}
}
}
/// Where (if anywhere) a panel is docked: its side and group index.
pub fn location(&self, id: PanelId) -> Option<(DockSide, usize)> {
for side in [DockSide::Left, DockSide::Right] {
@@ -1054,8 +1076,25 @@ pub struct Chrome {
/// and close. Pressing the row starts re-docking the panel. A floating panel
/// gets nothing here: its frame draws a vertical title bar beside it.
pub fn title_bar<'a>(id: PanelId, title: String, chrome: Chrome) -> Element<'a, Message> {
title_bar_with(id, title, chrome, None)
}
/// [`title_bar`] with a pallet's own control (a menu button) before the pin
/// and close. A floating pallet has no title bar, so the control then sits
/// alone at the top right.
pub fn title_bar_with<'a>(
id: PanelId,
title: String,
chrome: Chrome,
extra: Option<Element<'a, Message>>,
) -> Element<'a, Message> {
if chrome.floating {
return Space::new().width(0).height(0).into();
return match extra {
Some(extra) => row![Space::new().width(Length::Fill), extra]
.padding([3, 6])
.into(),
None => Space::new().width(0).height(0).into(),
};
}
// The pin and close only show while the pointer is over the bar; the
// fixed height keeps the bar from jumping when they appear.
@@ -1063,6 +1102,9 @@ pub fn title_bar<'a>(id: PanelId, title: String, chrome: Chrome) -> Element<'a,
.spacing(3)
.height(Length::Fixed(TITLE_BUTTON_H))
.align_y(iced::Center);
if let Some(extra) = extra {
bar = bar.push(extra);
}
if chrome.title_hovered {
bar = bar
.push(pin_button(
@@ -1230,6 +1272,7 @@ mod tests {
let mut state = DockState::default();
state.ensure_settings();
assert_eq!(state.width(PanelId::Properties, 1600.0), 250.0);
assert_eq!(state.width(PanelId::GraphicAttributes, 1600.0), 250.0);
assert_eq!(state.width(PanelId::BlockPalette, 1600.0), 260.0);
assert!(!state.auto_collapse(PanelId::Properties));
}
+151 -90
View File
@@ -55,6 +55,9 @@ pub fn linetype_display_name(name: &str) -> String {
impl fmt::Display for LinetypeItem {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.name.is_empty() && !self.art.is_empty() {
return f.write_str(&self.art);
}
let name = linetype_display_name(&self.name);
if self.art.is_empty() {
write!(f, "{name}")
@@ -95,6 +98,7 @@ impl fmt::Display for SelectionGroup {
#[derive(Clone)]
struct HatchPatternPreview {
pattern: crate::scene::model::hatch_model::HatchPattern,
padding: f32,
}
impl canvas::Program<Message> for HatchPatternPreview {
@@ -112,7 +116,7 @@ impl canvas::Program<Message> for HatchPatternPreview {
let mut frame = canvas::Frame::new(renderer, bounds.size());
let palette = theme.palette();
let pad = 4.0;
let pad = self.padding;
let sample = canvas::Path::rectangle(
Point::new(pad, pad),
Size::new(
@@ -201,6 +205,31 @@ fn hatch_preview_scale(pattern: &crate::scene::model::hatch_model::HatchPattern)
}
}
fn hatch_pattern_preview(
pattern: crate::scene::model::hatch_model::HatchPattern,
height: f32,
) -> Element<'static, Message> {
canvas(HatchPatternPreview {
pattern,
padding: 4.0,
})
.width(Length::Fill)
.height(height)
.into()
}
pub(crate) fn compact_hatch_pattern_preview(
pattern: crate::scene::model::hatch_model::HatchPattern,
) -> Element<'static, Message> {
canvas(HatchPatternPreview {
pattern,
padding: 0.5,
})
.width(Length::Fill)
.height(ROW_H)
.into()
}
fn hatch_pattern_matches(
entry: &crate::scene::model::hatch_patterns::PatternEntry,
search: &str,
@@ -223,6 +252,113 @@ pub(crate) fn filtered_hatch_patterns(
.collect()
}
/// Messages of a hatch pattern picker; the Properties panel and the Graphic
/// Attributes palette each route them to their own state.
pub(crate) struct PatternPickerMessages {
pub search_id: &'static str,
pub on_search: fn(String) -> Message,
pub on_confirm: Message,
pub on_focus: fn(usize) -> Message,
pub on_changed: fn(String) -> Message,
}
pub(crate) fn hatch_pattern_picker_content<'a>(
search_value: &'a str,
focus: usize,
current: &'a str,
messages: PatternPickerMessages,
) -> Element<'a, Message> {
let PatternPickerMessages {
search_id,
on_search,
on_confirm,
on_focus,
on_changed,
} = messages;
let search = text_input(t!("Search patterns…").as_ref(), search_value)
.id(iced::widget::Id::new(search_id))
.on_input(on_search)
.on_submit(on_confirm)
.size(FONT_SZ)
.padding([5, 7])
.width(Length::Fill);
let mut grid = column![].spacing(6);
let visible = filtered_hatch_patterns(search_value);
for (row_index, pair) in visible.chunks(2).enumerate() {
let mut cards = row![].spacing(6);
for (column_index, entry) in pair.iter().enumerate() {
let index = row_index * 2 + column_index;
let selected = current.eq_ignore_ascii_case(&entry.name);
let focused = focus == index;
let name = entry.name.clone();
let preview = hatch_pattern_preview(entry.gpu.clone(), PATTERN_PREVIEW_H);
let card = button(
column![
preview,
container(text(crate::ui::text_util::elide(&entry.name, 20)).size(FONT_SZ))
.width(Length::Fill)
.align_x(iced::Center),
]
.spacing(3),
)
.on_press(on_changed(name))
.style(move |theme: &Theme, status| {
let palette = theme.palette();
let hovered = matches!(status, button::Status::Hovered | button::Status::Pressed);
let pair = if selected {
palette.primary.weak
} else if hovered || focused {
palette.background.strong
} else {
palette.background.weak
};
button::Style {
background: Some(Background::Color(pair.color)),
text_color: pair.text,
border: Border {
color: if selected || focused {
palette.primary.base.color
} else {
palette.background.neutral.color
},
width: if selected || focused { 2.0 } else { 1.0 },
radius: 4.0.into(),
},
..Default::default()
}
})
.padding(5)
.width(PATTERN_CARD_W);
cards = cards.push(mouse_area(card).on_enter(on_focus(index)));
}
grid = grid.push(cards);
}
let results: Element<'_, Message> = if visible.is_empty() {
container(
text(t!("No matching patterns"))
.size(FONT_SZ)
.style(hint_text_style),
)
.padding(12)
.width(Length::Fill)
.center_x(Length::Fill)
.into()
} else {
scrollable(grid)
.height(Length::Fill)
.width(Length::Fill)
.into()
};
container(column![search, results].spacing(7))
.style(container::bordered_box)
.padding(8)
.width(PATTERN_PICKER_W)
.height(Length::Fixed(PATTERN_PICKER_H))
.into()
}
/// All standard CAD lineweight options for the combobox.
pub fn lw_options() -> Vec<LwItem> {
[
@@ -1504,99 +1640,24 @@ impl PropertiesPanel {
return prop_row_widget(label, head.into());
}
let search = text_input(t!("Search patterns…").as_ref(), &self.hatch_pattern_search)
.id(iced::widget::Id::new("hatch-pattern-search"))
.on_input(Message::PropHatchPatternSearchChanged)
.on_submit(Message::PropHatchPatternConfirm)
.size(FONT_SZ)
.padding([5, 7])
.width(Length::Fill);
let mut grid = column![].spacing(6);
let visible = filtered_hatch_patterns(&self.hatch_pattern_search);
for (row_index, pair) in visible.chunks(2).enumerate() {
let mut cards = row![].spacing(6);
for (column_index, entry) in pair.iter().enumerate() {
let index = row_index * 2 + column_index;
let selected = current.eq_ignore_ascii_case(&entry.name);
let focused = self.hatch_pattern_focus == index;
let name = entry.name.clone();
let preview = canvas(HatchPatternPreview {
pattern: entry.gpu.clone(),
})
.width(Length::Fill)
.height(PATTERN_PREVIEW_H);
let card = button(
column![
preview,
container(text(crate::ui::text_util::elide(&entry.name, 20)).size(FONT_SZ))
.width(Length::Fill)
.align_x(iced::Center),
]
.spacing(3),
)
.on_press(Message::PropHatchPatternChanged(name))
.style(move |theme: &Theme, status| {
let palette = theme.palette();
let hovered =
matches!(status, button::Status::Hovered | button::Status::Pressed);
let pair = if selected {
palette.primary.weak
} else if hovered || focused {
palette.background.strong
} else {
palette.background.weak
};
button::Style {
background: Some(Background::Color(pair.color)),
text_color: pair.text,
border: Border {
color: if selected || focused {
palette.primary.base.color
} else {
palette.background.neutral.color
},
width: if selected || focused { 2.0 } else { 1.0 },
radius: 4.0.into(),
},
..Default::default()
}
})
.padding(5)
.width(PATTERN_CARD_W);
cards =
cards.push(mouse_area(card).on_enter(Message::PropHatchPatternFocus(index)));
}
grid = grid.push(cards);
}
let results: Element<'_, Message> = if visible.is_empty() {
container(
text(t!("No matching patterns"))
.size(FONT_SZ)
.style(hint_text_style),
)
.padding(12)
.width(Length::Fill)
.center_x(Length::Fill)
.into()
} else {
scrollable(grid)
.height(Length::Fill)
.width(Length::Fill)
.into()
};
let popup = container(column![search, results].spacing(7))
.style(container::bordered_box)
.padding(8)
.width(PATTERN_PICKER_W)
.height(Length::Fixed(PATTERN_PICKER_H));
let popup = hatch_pattern_picker_content(
&self.hatch_pattern_search,
self.hatch_pattern_focus,
current,
PatternPickerMessages {
search_id: "hatch-pattern-search",
on_search: Message::PropHatchPatternSearchChanged,
on_confirm: Message::PropHatchPatternConfirm,
on_focus: Message::PropHatchPatternFocus,
on_changed: Message::PropHatchPatternChanged,
},
);
prop_row_widget(
label,
crate::ui::color_select::drop_down_below(
head.into(),
popup.into(),
popup,
Some(Length::Fixed(PATTERN_PICKER_W)),
Length::Fixed(PATTERN_PICKER_H),
Message::PropHatchPatternPickerToggle(current.to_string()),
@@ -2158,7 +2219,7 @@ fn text_input_style(theme: &Theme, status: text_input::Status) -> text_input::St
}
}
fn combo_input_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
pub(crate) fn combo_input_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
text_input_style(theme, status)
}
+7
View File
@@ -62,6 +62,8 @@ pub struct Ribbon {
pub show_count_palette: bool,
/// Sheet Set Manager palette shown (SSMSTATE).
pub show_sheet_set: bool,
/// Graphic Attributes panel visibility — drives its ribbon button highlight.
pub show_graphic_attributes: bool,
/// File tabs (FILETAB) visibility — drives the File Tabs button highlight.
pub show_file_tabs: bool,
/// Layout tabs (LAYOUTTAB) visibility — drives the Layout Tabs button highlight.
@@ -181,6 +183,7 @@ impl Ribbon {
show_properties: true,
show_count_palette: false,
show_sheet_set: false,
show_graphic_attributes: false,
show_file_tabs: true,
show_layout_tabs: true,
open_dropdown: None,
@@ -346,6 +349,9 @@ impl Ribbon {
pub fn set_sheet_set(&mut self, on: bool) {
self.show_sheet_set = on;
}
pub fn set_graphic_attributes(&mut self, on: bool) {
self.show_graphic_attributes = on;
}
pub fn set_file_tabs(&mut self, on: bool) {
self.show_file_tabs = on;
}
@@ -364,6 +370,7 @@ impl Ribbon {
show_ucs_icon: self.show_ucs_icon,
show_properties: self.show_properties,
show_count_palette: self.show_count_palette,
show_graphic_attributes: self.show_graphic_attributes,
show_block_palette,
show_sheet_set: self.show_sheet_set,
show_file_tabs: self.show_file_tabs,
+2
View File
@@ -38,6 +38,7 @@ pub(super) struct ToggleState {
pub show_ucs_icon: bool,
pub show_properties: bool,
pub show_count_palette: bool,
pub show_graphic_attributes: bool,
pub show_block_palette: bool,
pub show_sheet_set: bool,
pub show_file_tabs: bool,
@@ -370,6 +371,7 @@ pub(super) fn is_active_tool(id: &str, active_tool: &Option<String>, state: &Tog
"UCSICON" => state.show_ucs_icon,
"PROPERTIES" => state.show_properties,
"COUNTLIST" => state.show_count_palette,
"GRAPHICATTRIBUTES" => state.show_graphic_attributes,
"BLOCKPALETTE" => state.show_block_palette,
"SHEETSET" => state.show_sheet_set,
"FILETAB" => state.show_file_tabs,
+498
View File
@@ -0,0 +1,498 @@
//! Gradient flyout of the Graphic Attributes palette.
use crate::app::Message;
use crate::scene::model::hatch_model::GradientKind;
use crate::ui::window::graphic_attributes::GraphicAttributesMsg;
use codec::types::Color as AcadColor;
use iced::widget::{
button, checkbox, column, container, image, mouse_area, row, slider, text, text_input, tooltip,
Space,
};
use iced::{Background, Border, Color, Element, Fill, Length, Theme};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GradientColorMode {
One,
Two,
}
#[derive(Debug, Clone)]
pub struct GradientEditorState {
pub handles: Vec<codec::Handle>,
pub color_mode: GradientColorMode,
pub color_1: AcadColor,
pub color_2: AcadColor,
pub shade_tint: f32,
pub kind: GradientKind,
pub inverted: bool,
pub angle: String,
pub centered: bool,
/// Large preview, rebuilt only when a setting it depends on changes.
preview: std::cell::RefCell<Option<(PreviewKey, Option<iced::widget::image::Handle>)>>,
}
type PreviewKey = (GradientColorMode, AcadColor, AcadColor, u32, GradientKind, bool, String, bool);
#[derive(Debug, Clone)]
pub enum GradientMsg {
Open,
Cancel,
Apply,
ColorMode(GradientColorMode),
/// Stop colour 1 or 2.
Color(u8, AcadColor),
ShadeTint(f32),
Kind(GradientKind),
InvertToggled,
Angle(String),
AngleReset,
Centered(bool),
}
fn msg(message: GradientMsg) -> Message {
Message::GraphicAttributes(GraphicAttributesMsg::Gradient(message))
}
impl GradientEditorState {
pub fn from_hatch(
handles: Vec<codec::Handle>,
hatch: &codec::entities::Hatch,
) -> Self {
let color = |index: usize| {
hatch
.gradient_color
.colors
.get(index)
.map(|entry| entry.color)
.unwrap_or(AcadColor::Index(7))
};
let (kind, inverted) = GradientKind::from_name(&hatch.gradient_color.name);
Self {
handles,
color_mode: if hatch.gradient_color.is_single_color {
GradientColorMode::One
} else {
GradientColorMode::Two
},
color_1: color(0),
color_2: color(1),
shade_tint: hatch.gradient_color.color_tint as f32,
kind,
inverted,
angle: format!("{:.1}°", hatch.gradient_color.angle.to_degrees()),
centered: hatch.gradient_color.shift.abs() < 1e-9,
preview: Default::default(),
}
}
pub fn update(&mut self, message: GradientMsg) {
match message {
GradientMsg::ColorMode(mode) => self.color_mode = mode,
GradientMsg::Color(1, color) => self.color_1 = color,
GradientMsg::Color(_, color) => self.color_2 = color,
GradientMsg::ShadeTint(value) => self.shade_tint = value.clamp(0.0, 1.0),
GradientMsg::Kind(kind) => {
self.kind = kind;
if kind == GradientKind::Linear {
self.inverted = false;
}
}
GradientMsg::InvertToggled => {
if self.kind != GradientKind::Linear {
self.inverted ^= true;
}
}
GradientMsg::Angle(value) => self.angle = value,
GradientMsg::AngleReset => self.angle = "0.0°".into(),
GradientMsg::Centered(value) => self.centered = value,
GradientMsg::Open | GradientMsg::Cancel | GradientMsg::Apply => {}
}
}
pub fn angle_radians(&self) -> f64 {
self.angle
.trim()
.trim_end_matches('°')
.replace(',', ".")
.parse::<f64>()
.unwrap_or(0.0)
.rem_euclid(360.0)
.to_radians()
}
}
fn rgb(color: &AcadColor) -> Color {
let (r, g, b) = match color {
AcadColor::Rgb { r, g, b } => (*r, *g, *b),
AcadColor::Index(i) => {
codec::types::aci_table::aci_to_rgb(*i).unwrap_or((128, 128, 128))
}
_ => (255, 255, 255),
};
Color::from_rgb8(r, g, b)
}
fn rgb_array(color: &AcadColor) -> [f32; 4] {
let c = rgb(color);
[c.r, c.g, c.b, 1.0]
}
fn mix_rgba(a: Color, b: Color, t: f32) -> [u8; 4] {
let channel = |a: f32, b: f32| ((a + (b - a) * t) * 255.0).round() as u8;
[channel(a.r, b.r), channel(a.g, b.g), channel(a.b, b.b), 255]
}
fn preview_sized(
state: &GradientEditorState,
width: u32,
height: u32,
) -> Option<iced::widget::image::Handle> {
let c1 = rgb(&state.color_1);
let c2 = if state.color_mode == GradientColorMode::One {
let c = crate::scene::gradient_tint_color(rgb_array(&state.color_1), state.shade_tint);
Color::from_rgb(c[0], c[1], c[2])
} else {
rgb(&state.color_2)
};
let angle = state.angle_radians();
let frame = kernel::geom2d::gradient_frame(
&[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]],
angle,
if state.centered { 0.0 } else { 1.0 },
kernel::geom2d::Tolerance::default(),
)?;
let (sin, cos) = angle.sin_cos();
let radial = state.kind.radial();
let mut pixels = Vec::with_capacity((width * height * 4) as usize);
for y in 0..height {
let py = y as f64 / (height - 1) as f64;
for x in 0..width {
let px = x as f64 / (width - 1) as f64;
let mut t = if radial {
((px - frame.center[0]).hypot(py - frame.center[1]) / frame.radius).clamp(0.0, 1.0)
as f32
} else {
(((px * cos + py * sin) - frame.projection_min) / frame.projection_span)
.clamp(0.0, 1.0) as f32
};
if state.kind == GradientKind::Cylinder {
t = 1.0 - (2.0 * t - 1.0).abs();
} else if state.kind == GradientKind::Curved {
t *= t;
} else if state.kind == GradientKind::Hemispherical {
t = t.sqrt();
}
if state.inverted {
t = 1.0 - t;
}
pixels.extend_from_slice(&if radial {
mix_rgba(c2, c1, t)
} else {
mix_rgba(c1, c2, t)
});
}
}
Some(iced::widget::image::Handle::from_rgba(width, height, pixels))
}
fn preview(state: &GradientEditorState) -> Element<'static, Message> {
let key: PreviewKey = (
state.color_mode,
state.color_1,
state.color_2,
state.shade_tint.to_bits(),
state.kind,
state.inverted,
state.angle.clone(),
state.centered,
);
let mut cache = state.preview.borrow_mut();
if cache.as_ref().is_none_or(|(cached, _)| *cached != key) {
*cache = Some((key, preview_sized(state, 370, 80)));
}
preview_image(cache.as_ref().and_then(|(_, handle)| handle.clone()))
}
pub(crate) fn compact_preview(
hatch: &codec::entities::Hatch,
) -> Option<iced::widget::image::Handle> {
preview_sized(&GradientEditorState::from_hatch(Vec::new(), hatch), 256, 26)
}
pub(crate) fn preview_image(handle: Option<iced::widget::image::Handle>) -> Element<'static, Message> {
match handle {
Some(handle) => image(handle)
.width(Fill)
.height(Fill)
.content_fit(iced::ContentFit::Fill)
.into(),
None => Space::new().width(Fill).height(Fill).into(),
}
}
fn icon(kind: GradientKind, inverted: bool) -> &'static [u8] {
match (kind, inverted) {
(GradientKind::Linear, _) => {
include_bytes!("../../../assets/icons/gradient/gradient_linear.svg")
}
(GradientKind::Cylinder, false) => {
include_bytes!("../../../assets/icons/gradient/gradient_cylindrical.svg")
}
(GradientKind::Cylinder, true) => {
include_bytes!("../../../assets/icons/gradient/gradient_cylindrical_inverted.svg")
}
(GradientKind::Spherical, false) => {
include_bytes!("../../../assets/icons/gradient/gradient_spherical.svg")
}
(GradientKind::Spherical, true) => {
include_bytes!("../../../assets/icons/gradient/gradient_spherical_inverted.svg")
}
(GradientKind::Hemispherical, false) => {
include_bytes!("../../../assets/icons/gradient/gradient_hemispherical.svg")
}
(GradientKind::Hemispherical, true) => {
include_bytes!("../../../assets/icons/gradient/gradient_hemispherical_inverted.svg")
}
(GradientKind::Curved, false) => {
include_bytes!("../../../assets/icons/gradient/gradient_curved.svg")
}
(GradientKind::Curved, true) => {
include_bytes!("../../../assets/icons/gradient/gradient_curved_inverted.svg")
}
}
}
pub fn view(state: &GradientEditorState, dimmed: bool) -> Element<'_, Message> {
let segment = |label, mode| {
let selected = state.color_mode == mode;
button(text(label).size(11))
.on_press(msg(GradientMsg::ColorMode(mode)))
.width(Fill)
.style(move |theme: &Theme, status| {
if selected {
button::primary(theme, status)
} else {
button::secondary(theme, status)
}
})
};
let color_field = |label: std::borrow::Cow<'static, str>, index, color: AcadColor| {
let (background, _) = crate::ui::properties::acad_color_display(color);
let value = crate::ui::color_select::color_display_name(color);
let picker = button(
row![
crate::ui::color_select::swatch(background),
text(value).size(10),
Space::new().width(Fill),
]
.spacing(5)
.align_y(iced::Center),
)
.on_press(Message::OpenColorWindow(
crate::app::ColorPickTarget::Gradient(index),
color,
))
.style(|theme: &Theme, status| {
let palette = theme.palette();
button::Style {
background: Some(Background::Color(
if matches!(status, button::Status::Hovered) {
palette.background.weak.color
} else {
palette.background.base.color
},
)),
text_color: palette.background.base.text,
border: Border {
color: palette.background.neutral.color,
width: 1.0,
radius: 2.0.into(),
},
..Default::default()
}
})
.height(crate::ui::ROW_H)
.padding([3, 6])
.width(Fill);
row![text(label).size(11).width(43), picker]
.spacing(4)
.align_y(iced::Center)
.width(Fill)
};
let kinds = [
(GradientKind::Linear, crate::t!("Linear")),
(GradientKind::Cylinder, crate::t!("Cyl.")),
(GradientKind::Spherical, crate::t!("Spher.")),
(GradientKind::Hemispherical, crate::t!("Hemi.")),
(GradientKind::Curved, crate::t!("Curved")),
];
let mut type_row = row![].spacing(3);
for (kind, label) in kinds {
let selected = state.kind == kind;
let b = button(
column![
crate::ui::icons::semantic(
icon(kind, state.inverted && kind != GradientKind::Linear),
25.0
),
text(label).size(9)
]
.align_x(iced::Center),
)
.on_press(msg(GradientMsg::Kind(kind)))
.width(48)
.height(48)
.style(move |theme: &Theme, status| {
let mut s = button::subtle(theme, status);
if selected {
s.border.color = theme.palette().primary.base.color;
s.border.width = 1.0;
}
s
});
type_row = type_row.push(tooltip(
b,
text(kind.choice_label(false)).size(10),
tooltip::Position::Bottom,
));
}
let invert_selected = state.inverted && state.kind != GradientKind::Linear;
let invert = button(column![text("⇄").size(18), text(crate::t!("Invert")).size(9)].align_x(iced::Center))
.on_press_maybe(
(state.kind != GradientKind::Linear).then(|| msg(GradientMsg::InvertToggled)),
)
.width(42)
.height(48)
.style(move |theme: &Theme, status| {
let mut style = button::secondary(theme, status);
if invert_selected {
style.border.color = theme.palette().primary.base.color;
style.border.width = 1.0;
}
style
});
let separator =
container(Space::new().width(1).height(36)).style(|theme: &Theme| container::Style {
background: Some(Background::Color(theme.palette().background.neutral.color)),
..Default::default()
});
type_row = type_row.push(separator).push(tooltip(
invert,
text(crate::t!("Invert gradient")).size(10),
tooltip::Position::Bottom,
));
let colors: Element<'_, Message> = if state.color_mode == GradientColorMode::Two {
row![
color_field(crate::t!("Color 1"), 1, state.color_1),
color_field(crate::t!("Color 2"), 2, state.color_2)
]
.spacing(6)
.into()
} else {
row![
color_field(crate::t!("Color 1"), 1, state.color_1),
row![
text(crate::t!("Tone")).size(11).width(43),
slider(0..=100, (state.shade_tint * 100.0) as i32, |v| {
msg(GradientMsg::ShadeTint(v as f32 / 100.0))
})
.width(Fill)
]
.spacing(4)
.align_y(iced::Center)
.height(crate::ui::ROW_H)
.width(Fill)
]
.spacing(6)
.align_y(iced::Center)
.into()
};
let angle = row![
text(crate::t!("Angle")).size(11).width(43),
text_input("0.0°", &state.angle)
.on_input(|value| msg(GradientMsg::Angle(value)))
.size(11)
.width(Length::Fixed(92.0)),
tooltip(
button(crate::ui::icons::themed_undo(11.0, true))
.on_press(msg(GradientMsg::AngleReset))
.style(button::subtle)
.padding(3)
.width(24)
.height(crate::ui::ROW_H),
text(crate::t!("Reset angle")).size(10),
tooltip::Position::Bottom,
),
Space::new().width(Fill),
checkbox(state.centered)
.label(crate::t!("Centered"))
.on_toggle(|value| msg(GradientMsg::Centered(value)))
.size(14)
.text_size(11)
]
.spacing(6)
.align_y(iced::Center);
let types = row![text(crate::t!("Type")).size(11).width(43), type_row]
.spacing(4)
.align_y(iced::Center);
let actions = container(
row![
button(text(crate::t!("Cancel")).size(11))
.on_press(msg(GradientMsg::Cancel))
.style(button::secondary)
.padding([5, 14]),
button(text(crate::t!("OK")).size(11))
.on_press(msg(GradientMsg::Apply))
.style(button::primary)
.padding([5, 18]),
]
.spacing(8),
)
.width(Fill)
.align_x(iced::alignment::Horizontal::Right);
let content = column![
container(preview(state)).width(Fill).height(80),
row![
segment(crate::t!("One Color"), GradientColorMode::One),
segment(crate::t!("Two Colors"), GradientColorMode::Two)
]
.spacing(2),
colors,
types,
angle,
actions
]
.spacing(8)
.padding(10);
let panel: Element<'_, Message> = container(content)
.width(Length::Fixed(390.0))
.style(|theme: &Theme| container::Style {
background: Some(Background::Color(theme.palette().background.base.color)),
border: Border {
color: theme.palette().primary.base.color,
width: 1.0,
radius: 3.0.into(),
},
..Default::default()
})
.into();
let panel: Element<'_, Message> = if dimmed {
let shield = container(Space::new())
.width(Fill)
.height(Fill)
.style(|theme: &Theme| container::Style {
background: Some(Background::Color(
theme.palette().background.strongest.color.scale_alpha(0.55),
)),
..Default::default()
});
iced::widget::stack![panel, iced::widget::opaque(shield)]
.width(Length::Fixed(390.0))
.into()
} else {
panel
};
mouse_area(panel)
.interaction(iced::mouse::Interaction::Pointer)
.into()
}
File diff suppressed because it is too large. Load diff
+2
View File
@@ -13,6 +13,8 @@ pub mod drawing_units;
pub mod field_dialog;
pub mod find_replace;
pub mod geometric_tolerance;
pub mod gradient_editor;
pub mod graphic_attributes;
pub mod layer_state_manager;
pub mod layer_translator;
pub mod layers;