allow adjusting mouse for each screen
40
wlx-overlay-s/src/assets/edit/flip180.svg
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="flip180.svg"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
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="32"
|
||||||
|
inkscape:cx="18.3125"
|
||||||
|
inkscape:cy="14.46875"
|
||||||
|
inkscape:window-width="2560"
|
||||||
|
inkscape:window-height="1402"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg1" />
|
||||||
|
<!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE -->
|
||||||
|
<path
|
||||||
|
fill="white"
|
||||||
|
d="M 12,22 C 10.616667,22 9.3166667,21.737333 8.1,21.212 6.8833333,20.686667 5.825,19.974333 4.925,19.075 4.025,18.175667 3.3126667,17.117333 2.788,15.9 2.2633333,14.682667 2.0006667,13.382667 2,12 1.9993333,10.617333 2.262,9.3173333 2.788,8.1 3.314,6.8826667 4.0263333,5.8243333 4.925,4.925 5.8236667,4.0256667 6.882,3.3133333 8.1,2.788 9.318,2.2626667 10.618,2 12,2 c 1.382,0 2.682,0.2626667 3.9,0.788 1.218,0.5253333 2.276333,1.2376667 3.175,2.137 0.898667,0.8993333 1.611333,1.9576667 2.138,3.175 0.526667,1.2173333 0.789,2.517333 0.787,3.9 -0.002,1.382667 -0.264667,2.682667 -0.788,3.9 -0.523333,1.217333 -1.235667,2.275667 -2.137,3.175 -0.901333,0.899333 -1.959667,1.612 -3.175,2.138 C 14.684667,21.739 13.384667,22.001333 12,22 m 0,-2 c 2.233333,0 4.125,-0.775 5.675,-2.325 C 19.225,16.125 20,14.233333 20,12 20,9.9778321 19.418096,8.0680972 17.675,6.325 15.931904,4.5819028 14.232703,3.7451172 12.00586,3.7451172 c 0,3.1215572 -0.0031,8.2546878 -0.0031,8.2546878 C 12.002734,11.999805 12,20 12,20"
|
||||||
|
id="path1"
|
||||||
|
sodipodi:nodetypes="csssssssssssssssccsszccc" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
40
wlx-overlay-s/src/assets/edit/flip270.svg
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="flip270.svg"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
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="32"
|
||||||
|
inkscape:cx="18.3125"
|
||||||
|
inkscape:cy="14.46875"
|
||||||
|
inkscape:window-width="2560"
|
||||||
|
inkscape:window-height="1402"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg1" />
|
||||||
|
<!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE -->
|
||||||
|
<path
|
||||||
|
fill="white"
|
||||||
|
d="M 12,22 C 10.616667,22 9.3166667,21.737333 8.1,21.212 6.8833333,20.686667 5.825,19.974333 4.925,19.075 4.025,18.175667 3.3126667,17.117333 2.788,15.9 2.2633333,14.682667 2.0006667,13.382667 2,12 1.9993333,10.617333 2.262,9.3173333 2.788,8.1 3.314,6.8826667 4.0263333,5.8243333 4.925,4.925 5.8236667,4.0256667 6.882,3.3133333 8.1,2.788 9.318,2.2626667 10.618,2 12,2 c 1.382,0 2.682,0.2626667 3.9,0.788 1.218,0.5253333 2.276333,1.2376667 3.175,2.137 0.898667,0.8993333 1.611333,1.9576667 2.138,3.175 0.526667,1.2173333 0.789,2.517333 0.787,3.9 -0.002,1.382667 -0.264667,2.682667 -0.788,3.9 -0.523333,1.217333 -1.235667,2.275667 -2.137,3.175 -0.901333,0.899333 -1.959667,1.612 -3.175,2.138 C 14.684667,21.739 13.384667,22.001333 12,22 m 0,-2 c 2.233333,0 4.125,-0.775 5.675,-2.325 C 19.225,16.125 20,14.233333 20,12 20,9.9778321 19.418096,8.0680972 17.675,6.325 15.931904,4.5819028 14.232703,3.7451172 12.00586,3.7451172 c 0,3.1215572 -0.0031,8.2546878 -0.0031,8.2546878 C 12.002734,11.999805 6.7304687,12 4,12 4,14.233333 4.775,16.125 6.325,17.675 7.875,19.225 9.7666667,20 12,20"
|
||||||
|
id="path1"
|
||||||
|
sodipodi:nodetypes="csssssssssssssssccsszcccsc" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
40
wlx-overlay-s/src/assets/edit/flip90.svg
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="flip90.svg"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
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="32"
|
||||||
|
inkscape:cx="18.3125"
|
||||||
|
inkscape:cy="14.46875"
|
||||||
|
inkscape:window-width="2560"
|
||||||
|
inkscape:window-height="1402"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg1" />
|
||||||
|
<!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE -->
|
||||||
|
<path
|
||||||
|
fill="white"
|
||||||
|
d="M 12,22 C 10.616667,22 9.3166667,21.737333 8.1,21.212 6.8833333,20.686667 5.825,19.974333 4.925,19.075 4.025,18.175667 3.3126667,17.117333 2.788,15.9 2.2633333,14.682667 2.0006667,13.382667 2,12 1.9993333,10.617333 2.262,9.3173333 2.788,8.1 3.314,6.8826667 4.0263333,5.8243333 4.925,4.925 5.8236667,4.0256667 6.882,3.3133333 8.1,2.788 9.318,2.2626667 10.618,2 12,2 c 1.382,0 2.682,0.2626667 3.9,0.788 1.218,0.5253333 2.276333,1.2376667 3.175,2.137 0.898667,0.8993333 1.611333,1.9576667 2.138,3.175 0.526667,1.2173333 0.789,2.517333 0.787,3.9 -0.002,1.382667 -0.264667,2.682667 -0.788,3.9 -0.523333,1.217333 -1.235667,2.275667 -2.137,3.175 -0.901333,0.899333 -1.959667,1.612 -3.175,2.138 C 14.684667,21.739 13.384667,22.001333 12,22 M 20,12 C 20,9.9778321 19.418096,8.0680972 17.675,6.325 15.931904,4.5819028 14.232703,3.7451172 12.00586,3.7451172 c 0,3.1215572 -0.0031,8.2546878 -0.0031,8.2546878"
|
||||||
|
id="path1"
|
||||||
|
sodipodi:nodetypes="cssssssssssssssscczcc" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.1 KiB |
40
wlx-overlay-s/src/assets/edit/flipped.svg
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="flipped.svg"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
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="32"
|
||||||
|
inkscape:cx="18.3125"
|
||||||
|
inkscape:cy="14.46875"
|
||||||
|
inkscape:window-width="2560"
|
||||||
|
inkscape:window-height="1402"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg1" />
|
||||||
|
<!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE -->
|
||||||
|
<path
|
||||||
|
fill="white"
|
||||||
|
d="M 12,22 C 10.616667,22 9.3166667,21.737333 8.1,21.212 6.8833333,20.686667 5.825,19.974333 4.925,19.075 4.025,18.175667 3.3126667,17.117333 2.788,15.9 2.2633333,14.682667 2.0006667,13.382667 2,12 1.9993333,10.617333 2.262,9.3173333 2.788,8.1 3.314,6.8826667 4.0263333,5.8243333 4.925,4.925 5.8236667,4.0256667 6.882,3.3133333 8.1,2.788 9.318,2.2626667 10.618,2 12,2 c 1.382,0 2.682,0.2626667 3.9,0.788 1.218,0.5253333 2.276333,1.2376667 3.175,2.137 0.898667,0.8993333 1.611333,1.9576667 2.138,3.175 0.526667,1.2173333 0.789,2.517333 0.787,3.9 -0.002,1.382667 -0.264667,2.682667 -0.788,3.9 -0.523333,1.217333 -1.235667,2.275667 -2.137,3.175 -0.901333,0.899333 -1.959667,1.612 -3.175,2.138 C 14.684667,21.739 13.384667,22.001333 12,22"
|
||||||
|
id="path1"
|
||||||
|
sodipodi:nodetypes="csssssssssssssssc" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE --><path fill="currentColor" d="m2.1 2.075l19.8 19.8l-1.425 1.425l-1.1-1.1q-.5.375-1.1.588T17 23h-6.95q-.75 0-1.4-.337T7.575 21.7L1.2 12.375l.6-.575q.475-.475 1.125-.55t1.175.3L7 13.575v-3.75L.675 3.5zM21 18.15l-6-5.975V3q0-.425.288-.712T16 2t.713.288T17 3v9.175h2V5q0-.425.288-.712T20 4t.713.288T21 5zm-8-8l-2-2V2q0-.425.288-.712T12 1t.713.288T13 2zm-4-4l-2-2V4q0-.425.288-.712T8 3t.713.288T9 4z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE --><path fill="white" d="m2.1 2.075l19.8 19.8l-1.425 1.425l-1.1-1.1q-.5.375-1.1.588T17 23h-6.95q-.75 0-1.4-.337T7.575 21.7L1.2 12.375l.6-.575q.475-.475 1.125-.55t1.175.3L7 13.575v-3.75L.675 3.5zM21 18.15l-6-5.975V3q0-.425.288-.712T16 2t.713.288T17 3v9.175h2V5q0-.425.288-.712T20 4t.713.288T21 5zm-8-8l-2-2V2q0-.425.288-.712T12 1t.713.288T13 2zm-4-4l-2-2V4q0-.425.288-.712T8 3t.713.288T9 4z"/></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 600 B After Width: | Height: | Size: 594 B |
40
wlx-overlay-s/src/assets/edit/normal.svg
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="normal.svg"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
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="32"
|
||||||
|
inkscape:cx="18.3125"
|
||||||
|
inkscape:cy="14.46875"
|
||||||
|
inkscape:window-width="2560"
|
||||||
|
inkscape:window-height="1402"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg1" />
|
||||||
|
<!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE -->
|
||||||
|
<path
|
||||||
|
fill="white"
|
||||||
|
d="M 12,22 C 10.616667,22 9.3166667,21.737333 8.1,21.212 6.8833333,20.686667 5.825,19.974333 4.925,19.075 4.025,18.175667 3.3126667,17.117333 2.788,15.9 2.2633333,14.682667 2.0006667,13.382667 2,12 1.9993333,10.617333 2.262,9.3173333 2.788,8.1 3.314,6.8826667 4.0263333,5.8243333 4.925,4.925 5.8236667,4.0256667 6.882,3.3133333 8.1,2.788 9.318,2.2626667 10.618,2 12,2 c 1.382,0 2.682,0.2626667 3.9,0.788 1.218,0.5253333 2.276333,1.2376667 3.175,2.137 0.898667,0.8993333 1.611333,1.9576667 2.138,3.175 0.526667,1.2173333 0.789,2.517333 0.787,3.9 -0.002,1.382667 -0.264667,2.682667 -0.788,3.9 -0.523333,1.217333 -1.235667,2.275667 -2.137,3.175 -0.901333,0.899333 -1.959667,1.612 -3.175,2.138 C 14.684667,21.739 13.384667,22.001333 12,22 m 0,-2 c 2.233333,0 4.125,-0.775 5.675,-2.325 C 19.225,16.125 20,14.233333 20,12 20,9.9778321 19.418096,8.0680972 17.675,6.325 15.931904,4.5819028 14.226843,4 12,4 9.7731573,4 7.875,4.775 6.325,6.325 4.775,7.875 4,9.7666667 4,12 4,14.233333 4.775,16.125 6.325,17.675 7.875,19.225 9.7666667,20 12,20"
|
||||||
|
id="path1"
|
||||||
|
sodipodi:nodetypes="csssssssssssssssccsszzzssc" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
40
wlx-overlay-s/src/assets/edit/rotate180.svg
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="rotate180.svg"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
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="32"
|
||||||
|
inkscape:cx="22.5"
|
||||||
|
inkscape:cy="19.09375"
|
||||||
|
inkscape:window-width="2560"
|
||||||
|
inkscape:window-height="1402"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg1" />
|
||||||
|
<!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE -->
|
||||||
|
<path
|
||||||
|
fill="white"
|
||||||
|
d="M 12,22 C 10.616667,22 9.3166667,21.737333 8.1,21.212 6.8833333,20.686667 5.825,19.974333 4.925,19.075 4.025,18.175667 3.3126667,17.117333 2.788,15.9 2.2633333,14.682667 2.0006667,13.382667 2,12 1.9993333,10.617333 2.262,9.3173333 2.788,8.1 3.314,6.8826667 4.0263333,5.8243333 4.925,4.925 5.8236667,4.0256667 6.882,3.3133333 8.1,2.788 9.318,2.2626667 10.618,2 12,2 c 1.382,0 2.682,0.2626667 3.9,0.788 1.218,0.5253333 2.276333,1.2376667 3.175,2.137 0.898667,0.8993333 1.611333,1.9576667 2.138,3.175 0.526667,1.2173333 0.789,2.517333 0.787,3.9 -0.002,1.382667 -0.264667,2.682667 -0.788,3.9 -0.523333,1.217333 -1.235667,2.275667 -2.137,3.175 -0.901333,0.899333 -1.959667,1.612 -3.175,2.138 C 14.684667,21.739 13.384667,22.001333 12,22 m 0,-2 c 0,-4.40625 0,-3.449573 0,-8 V 4 C 9.7666667,4 7.875,4.775 6.325,6.325 4.775,7.875 4,9.7666667 4,12 4,14.233333 4.775,16.125 6.325,17.675 7.875,19.225 9.7666667,20 12,20"
|
||||||
|
id="path1"
|
||||||
|
sodipodi:nodetypes="csssssssssssssssccccsssc" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.1 KiB |
40
wlx-overlay-s/src/assets/edit/rotate270.svg
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="rotate270.svg"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
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="32"
|
||||||
|
inkscape:cx="22.5"
|
||||||
|
inkscape:cy="19.09375"
|
||||||
|
inkscape:window-width="2560"
|
||||||
|
inkscape:window-height="1402"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg1" />
|
||||||
|
<!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE -->
|
||||||
|
<path
|
||||||
|
fill="white"
|
||||||
|
d="M 12,22 C 10.616667,22 9.3166667,21.737333 8.1,21.212 6.8833333,20.686667 5.825,19.974333 4.925,19.075 4.025,18.175667 3.3126667,17.117333 2.788,15.9 2.2633333,14.682667 2.0006667,13.382667 2,12 1.9993333,10.617333 2.262,9.3173333 2.788,8.1 3.314,6.8826667 4.0263333,5.8243333 4.925,4.925 5.8236667,4.0256667 6.882,3.3133333 8.1,2.788 9.318,2.2626667 10.618,2 12,2 c 1.382,0 2.682,0.2626667 3.9,0.788 1.218,0.5253333 2.276333,1.2376667 3.175,2.137 0.898667,0.8993333 1.611333,1.9576667 2.138,3.175 0.526667,1.2173333 0.789,2.517333 0.787,3.9 -0.002,1.382667 -0.264667,2.682667 -0.788,3.9 -0.523333,1.217333 -1.235667,2.275667 -2.137,3.175 -0.901333,0.899333 -1.959667,1.612 -3.175,2.138 C 14.684667,21.739 13.384667,22.001333 12,22 M 12,12 V 4 C 9.7666667,4 7.875,4.775 6.325,6.325 4.775,7.875 4,9.7666667 4,12"
|
||||||
|
id="path1"
|
||||||
|
sodipodi:nodetypes="cssssssssssssssscccsc" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
40
wlx-overlay-s/src/assets/edit/rotate90.svg
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="rotate90.svg"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
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="32"
|
||||||
|
inkscape:cx="22.5"
|
||||||
|
inkscape:cy="19.09375"
|
||||||
|
inkscape:window-width="2560"
|
||||||
|
inkscape:window-height="1402"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg1" />
|
||||||
|
<!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE -->
|
||||||
|
<path
|
||||||
|
fill="white"
|
||||||
|
d="M 12,22 C 10.616667,22 9.3166667,21.737333 8.1,21.212 6.8833333,20.686667 5.825,19.974333 4.925,19.075 4.025,18.175667 3.3126667,17.117333 2.788,15.9 2.2633333,14.682667 2.0006667,13.382667 2,12 1.9993333,10.617333 2.262,9.3173333 2.788,8.1 3.314,6.8826667 4.0263333,5.8243333 4.925,4.925 5.8236667,4.0256667 6.882,3.3133333 8.1,2.788 9.318,2.2626667 10.618,2 12,2 c 1.382,0 2.682,0.2626667 3.9,0.788 1.218,0.5253333 2.276333,1.2376667 3.175,2.137 0.898667,0.8993333 1.611333,1.9576667 2.138,3.175 0.526667,1.2173333 0.789,2.517333 0.787,3.9 -0.002,1.382667 -0.264667,2.682667 -0.788,3.9 -0.523333,1.217333 -1.235667,2.275667 -2.137,3.175 -0.901333,0.899333 -1.959667,1.612 -3.175,2.138 C 14.684667,21.739 13.384667,22.001333 12,22 m 0,-2 c 2.233333,0 4.125,-0.775 5.675,-2.325 C 19.225,16.125 20,14.233333 20,12 16.205587,12 14.579192,11.9944 12,12 V 4 C 9.7666667,4 7.875,4.775 6.325,6.325 4.775,7.875 4,9.7666667 4,12 4,14.233333 4.775,16.125 6.325,17.675 7.875,19.225 9.7666667,20 12,20"
|
||||||
|
id="path1"
|
||||||
|
sodipodi:nodetypes="csssssssssssssssccscccsssc" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -45,6 +45,7 @@
|
|||||||
<TopButton sticky="0" id="top_alpha" src="edit/fade.svg" tooltip="EDIT_MODE.OPACITY" press="::EditModeTab alpha" />
|
<TopButton sticky="0" id="top_alpha" src="edit/fade.svg" tooltip="EDIT_MODE.OPACITY" press="::EditModeTab alpha" />
|
||||||
<TopButton sticky="0" id="top_curve" src="edit/curve.svg" tooltip="EDIT_MODE.ADJUST_CURVATURE" press="::EditModeTab curve" />
|
<TopButton sticky="0" id="top_curve" src="edit/curve.svg" tooltip="EDIT_MODE.ADJUST_CURVATURE" press="::EditModeTab curve" />
|
||||||
<TopButton sticky="0" id="top_stereo" src="edit/3d.svg" tooltip="EDIT_MODE.STEREO_3D_MODE.TITLE" press="::EditModeTab stereo" />
|
<TopButton sticky="0" id="top_stereo" src="edit/3d.svg" tooltip="EDIT_MODE.STEREO_3D_MODE.TITLE" press="::EditModeTab stereo" />
|
||||||
|
<TopButton sticky="0" id="top_mouse" src="edit/normal.svg" tooltip="EDIT_MODE.MOUSE.TITLE" press="::EditModeTab mouse" />
|
||||||
<!-- TopButton sticky="0" id="top_move" src="edit/move-all.svg" tooltip="EDIT_MODE.MOVE_PRESS_AND_DRAG" / -->
|
<!-- TopButton sticky="0" id="top_move" src="edit/move-all.svg" tooltip="EDIT_MODE.MOVE_PRESS_AND_DRAG" / -->
|
||||||
<!-- TopButton sticky="0" id="top_resize" src="edit/resize.svg" tooltip="EDIT_MODE.RESIZE_PRESS_AND_DRAG" / -->
|
<!-- TopButton sticky="0" id="top_resize" src="edit/resize.svg" tooltip="EDIT_MODE.RESIZE_PRESS_AND_DRAG" / -->
|
||||||
<TopButtonDanger src="edit/delete.svg" tooltip="EDIT_MODE.DELETE" press="::EditModeDeletePress" release="::EditModeDeleteRelease" />
|
<TopButtonDanger src="edit/delete.svg" tooltip="EDIT_MODE.DELETE" press="::EditModeDeletePress" release="::EditModeDeleteRelease" />
|
||||||
@@ -77,6 +78,19 @@
|
|||||||
<PosButton id="stereo_bottomtop" src="edit/3d_bottomtop.svg" tooltip="EDIT_MODE.STEREO_3D_MODE.SPLIT_BOTTOM_TOP" press="::EditModeSetStereo bottomtop" />
|
<PosButton id="stereo_bottomtop" src="edit/3d_bottomtop.svg" tooltip="EDIT_MODE.STEREO_3D_MODE.SPLIT_BOTTOM_TOP" press="::EditModeSetStereo bottomtop" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="tab_mouse" display="none" height="100" flex_direction="column">
|
||||||
|
<div padding="8" gap="8" justify_content="center" align_items="center">
|
||||||
|
<PosButton id="mouse_default" src="edit/close.svg" tooltip="DEFAULT" press="::EditModeSetMouse default" />
|
||||||
|
<PosButton id="mouse_normal" src="edit/normal.svg" tooltip="EDIT_MODE.MOUSE.NORMAL" press="::EditModeSetMouse normal" />
|
||||||
|
<PosButton id="mouse_rotate90" src="edit/rotate90.svg" tooltip="EDIT_MODE.MOUSE.ROTATE90" press="::EditModeSetMouse rotate90" />
|
||||||
|
<PosButton id="mouse_rotate180" src="edit/rotate180.svg" tooltip="EDIT_MODE.MOUSE.ROTATE180" press="::EditModeSetMouse rotate180" />
|
||||||
|
<PosButton id="mouse_rotate270" src="edit/rotate270.svg" tooltip="EDIT_MODE.MOUSE.ROTATE270" press="::EditModeSetMouse rotate270" />
|
||||||
|
<PosButton id="mouse_flipped" src="edit/flipped.svg" tooltip="EDIT_MODE.MOUSE.FLIPPED" press="::EditModeSetMouse flipped" />
|
||||||
|
<PosButton id="mouse_flip90" src="edit/flip90.svg" tooltip="EDIT_MODE.MOUSE.FLIP90" press="::EditModeSetMouse flip90" />
|
||||||
|
<PosButton id="mouse_flip180" src="edit/flip180.svg" tooltip="EDIT_MODE.MOUSE.FLIP180" press="::EditModeSetMouse flip180" />
|
||||||
|
<PosButton id="mouse_flip270" src="edit/flip270.svg" tooltip="EDIT_MODE.MOUSE.FLIP270" press="::EditModeSetMouse flip270" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="tab_alpha" display="none" height="100" padding="8" gap="8" justify_content="center" align_items="center">
|
<div id="tab_alpha" display="none" height="100" padding="8" gap="8" justify_content="center" align_items="center">
|
||||||
<div width="100%" padding="8" gap="8" justify_content="center" align_items="center">
|
<div width="100%" padding="8" gap="8" justify_content="center" align_items="center">
|
||||||
<label translation="EDIT_MODE.OPACITY" />
|
<label translation="EDIT_MODE.OPACITY" />
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::{
|
use std::{
|
||||||
fs,
|
fs,
|
||||||
io::{BufRead, BufReader, Read},
|
io::{BufRead, BufReader},
|
||||||
process::Child,
|
process::Child,
|
||||||
sync::{
|
sync::{
|
||||||
Arc, LazyLock,
|
Arc, LazyLock,
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ pub struct GuiPanel<S> {
|
|||||||
context: WguiContext,
|
context: WguiContext,
|
||||||
timestep: Timestep,
|
timestep: Timestep,
|
||||||
has_focus: [bool; 2],
|
has_focus: [bool; 2],
|
||||||
|
last_content_size: Vec2,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type OnCustomIdFunc<S> = Box<
|
pub type OnCustomIdFunc<S> = Box<
|
||||||
@@ -175,6 +176,7 @@ impl<S: 'static> GuiPanel<S> {
|
|||||||
gui_scale: params.gui_scale,
|
gui_scale: params.gui_scale,
|
||||||
initialized: false,
|
initialized: false,
|
||||||
has_focus: [false, false],
|
has_focus: [false, false],
|
||||||
|
last_content_size: Vec2::ZERO,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,6 +208,7 @@ impl<S: 'static> GuiPanel<S> {
|
|||||||
gui_scale: params.gui_scale,
|
gui_scale: params.gui_scale,
|
||||||
initialized: false,
|
initialized: false,
|
||||||
has_focus: [false, false],
|
has_focus: [false, false],
|
||||||
|
last_content_size: Vec2::ZERO,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +241,6 @@ impl<S: 'static> OverlayBackend for GuiPanel<S> {
|
|||||||
if self.layout.content_size.x * self.layout.content_size.y != 0.0 {
|
if self.layout.content_size.x * self.layout.content_size.y != 0.0 {
|
||||||
self.update_layout()?;
|
self.update_layout()?;
|
||||||
self.interaction_transform = Some(ui_transform([
|
self.interaction_transform = Some(ui_transform([
|
||||||
//TODO: dynamic
|
|
||||||
self.layout.content_size.x as _,
|
self.layout.content_size.x as _,
|
||||||
self.layout.content_size.y as _,
|
self.layout.content_size.y as _,
|
||||||
]));
|
]));
|
||||||
@@ -275,6 +277,17 @@ impl<S: 'static> OverlayBackend for GuiPanel<S> {
|
|||||||
return Ok(ShouldRender::Unable);
|
return Ok(ShouldRender::Unable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !self
|
||||||
|
.last_content_size
|
||||||
|
.abs_diff_eq(self.layout.content_size, 0.1 /* pixels */)
|
||||||
|
{
|
||||||
|
self.interaction_transform = Some(ui_transform([
|
||||||
|
self.layout.content_size.x as _,
|
||||||
|
self.layout.content_size.y as _,
|
||||||
|
]));
|
||||||
|
self.last_content_size = self.layout.content_size;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(if self.layout.check_toggle_needs_redraw() {
|
Ok(if self.layout.check_toggle_needs_redraw() {
|
||||||
ShouldRender::Should
|
ShouldRender::Should
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use wgui::{
|
|||||||
parser::Fetchable,
|
parser::Fetchable,
|
||||||
widget::EventResult,
|
widget::EventResult,
|
||||||
};
|
};
|
||||||
|
use wlx_capture::frame::Transform;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
attrib_value,
|
attrib_value,
|
||||||
@@ -24,6 +25,7 @@ use crate::{
|
|||||||
gui::panel::{GuiPanel, NewGuiPanelParams, OnCustomAttribFunc, button::BUTTON_EVENTS},
|
gui::panel::{GuiPanel, NewGuiPanelParams, OnCustomAttribFunc, button::BUTTON_EVENTS},
|
||||||
overlays::edit::{
|
overlays::edit::{
|
||||||
lock::InteractLockHandler,
|
lock::InteractLockHandler,
|
||||||
|
mouse::new_mouse_tab_handler,
|
||||||
pos::{PosTabState, new_pos_tab_handler},
|
pos::{PosTabState, new_pos_tab_handler},
|
||||||
sprite_tab::SpriteTabHandler,
|
sprite_tab::SpriteTabHandler,
|
||||||
stereo::new_stereo_tab_handler,
|
stereo::new_stereo_tab_handler,
|
||||||
@@ -42,6 +44,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
mod lock;
|
mod lock;
|
||||||
|
mod mouse;
|
||||||
mod pos;
|
mod pos;
|
||||||
mod sprite_tab;
|
mod sprite_tab;
|
||||||
mod stereo;
|
mod stereo;
|
||||||
@@ -66,6 +69,7 @@ struct EditModeState {
|
|||||||
lock: InteractLockHandler,
|
lock: InteractLockHandler,
|
||||||
pos: SpriteTabHandler<PosTabState>,
|
pos: SpriteTabHandler<PosTabState>,
|
||||||
stereo: SpriteTabHandler<StereoMode>,
|
stereo: SpriteTabHandler<StereoMode>,
|
||||||
|
mouse: SpriteTabHandler<Transform>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type EditModeWrapPanel = GuiPanel<EditModeState>;
|
type EditModeWrapPanel = GuiPanel<EditModeState>;
|
||||||
@@ -264,6 +268,7 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
|
|||||||
lock: InteractLockHandler::default(),
|
lock: InteractLockHandler::default(),
|
||||||
pos: SpriteTabHandler::default(),
|
pos: SpriteTabHandler::default(),
|
||||||
stereo: SpriteTabHandler::default(),
|
stereo: SpriteTabHandler::default(),
|
||||||
|
mouse: SpriteTabHandler::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let on_custom_attrib: OnCustomAttribFunc = Box::new(move |layout, attribs, _app| {
|
let on_custom_attrib: OnCustomAttribFunc = Box::new(move |layout, attribs, _app| {
|
||||||
@@ -323,6 +328,16 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
|
|||||||
Ok(EventResult::Consumed)
|
Ok(EventResult::Consumed)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
"::EditModeSetMouse" => {
|
||||||
|
let key = args.next().unwrap().to_owned();
|
||||||
|
Box::new(move |common, _data, app, state| {
|
||||||
|
let sel = OverlaySelector::Id(*state.id.borrow());
|
||||||
|
let task = state.mouse.button_clicked(common, &key);
|
||||||
|
app.tasks
|
||||||
|
.enqueue(TaskType::Overlay(OverlayTask::Modify(sel, task)));
|
||||||
|
Ok(EventResult::Consumed)
|
||||||
|
})
|
||||||
|
}
|
||||||
"::EditModeDeletePress" => Box::new(move |_common, _data, _app, state| {
|
"::EditModeDeletePress" => Box::new(move |_common, _data, _app, state| {
|
||||||
state.delete.pressed = Instant::now();
|
state.delete.pressed = Instant::now();
|
||||||
// TODO: animate to light up button after 2s
|
// TODO: animate to light up button after 2s
|
||||||
@@ -361,9 +376,12 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
|
|||||||
|
|
||||||
panel.state.pos = new_pos_tab_handler(&mut panel)?;
|
panel.state.pos = new_pos_tab_handler(&mut panel)?;
|
||||||
panel.state.stereo = new_stereo_tab_handler(&mut panel)?;
|
panel.state.stereo = new_stereo_tab_handler(&mut panel)?;
|
||||||
|
panel.state.mouse = new_mouse_tab_handler(&mut panel)?;
|
||||||
panel.state.lock = InteractLockHandler::new(&mut panel)?;
|
panel.state.lock = InteractLockHandler::new(&mut panel)?;
|
||||||
panel.state.tabs =
|
panel.state.tabs = ButtonPaneTabSwitcher::new(
|
||||||
ButtonPaneTabSwitcher::new(&mut panel, &["none", "pos", "alpha", "curve", "stereo"])?;
|
&mut panel,
|
||||||
|
&["none", "pos", "alpha", "curve", "stereo", "mouse"],
|
||||||
|
)?;
|
||||||
|
|
||||||
set_up_checkbox(&mut panel, "additive_box", cb_assign_additive)?;
|
set_up_checkbox(&mut panel, "additive_box", cb_assign_additive)?;
|
||||||
set_up_slider(&mut panel, "lerp_slider", cb_assign_lerp)?;
|
set_up_slider(&mut panel, "lerp_slider", cb_assign_lerp)?;
|
||||||
@@ -435,6 +453,19 @@ fn reset_panel(
|
|||||||
.set_tab_visible(&mut common, "stereo", false);
|
.set_tab_visible(&mut common, "stereo", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(mouse) = attrib_value!(
|
||||||
|
owc.backend.get_attrib(BackendAttrib::MouseTransform),
|
||||||
|
BackendAttribValue::MouseTransform
|
||||||
|
) {
|
||||||
|
panel.state.tabs.set_tab_visible(&mut common, "mouse", true);
|
||||||
|
panel.state.mouse.reset(&mut common, &mouse);
|
||||||
|
} else {
|
||||||
|
panel
|
||||||
|
.state
|
||||||
|
.tabs
|
||||||
|
.set_tab_visible(&mut common, "mouse", false);
|
||||||
|
}
|
||||||
|
|
||||||
panel.layout.process_alterables(alterables)?;
|
panel.layout.process_alterables(alterables)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
72
wlx-overlay-s/src/overlays/edit/mouse.rs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
use wlx_capture::frame::Transform;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
overlays::edit::{
|
||||||
|
EditModeWrapPanel,
|
||||||
|
sprite_tab::{SpriteTabHandler, SpriteTabKey},
|
||||||
|
},
|
||||||
|
windowing::backend::BackendAttribValue,
|
||||||
|
};
|
||||||
|
|
||||||
|
static MOUSE_NAMES: [&str; 9] = [
|
||||||
|
"default",
|
||||||
|
"normal",
|
||||||
|
"rotate90",
|
||||||
|
"rotate180",
|
||||||
|
"rotate270",
|
||||||
|
"flipped",
|
||||||
|
"flip90",
|
||||||
|
"flip180",
|
||||||
|
"flip270",
|
||||||
|
];
|
||||||
|
|
||||||
|
pub fn new_mouse_tab_handler(
|
||||||
|
panel: &mut EditModeWrapPanel,
|
||||||
|
) -> anyhow::Result<SpriteTabHandler<Transform>> {
|
||||||
|
SpriteTabHandler::new(
|
||||||
|
panel,
|
||||||
|
"mouse",
|
||||||
|
&MOUSE_NAMES,
|
||||||
|
Box::new(|_common, state| {
|
||||||
|
let mouse_transform = state.clone();
|
||||||
|
Box::new(move |app, owc| {
|
||||||
|
owc.backend
|
||||||
|
.set_attrib(app, BackendAttribValue::MouseTransform(mouse_transform));
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpriteTabKey for Transform {
|
||||||
|
fn to_tab_key(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Transform::Undefined => "default",
|
||||||
|
Transform::Normal => "normal",
|
||||||
|
Transform::Rotated90 => "rotate90",
|
||||||
|
Transform::Rotated180 => "rotate180",
|
||||||
|
Transform::Rotated270 => "rotate270",
|
||||||
|
Transform::Flipped => "flipped",
|
||||||
|
Transform::Flipped90 => "flip90",
|
||||||
|
Transform::Flipped180 => "flip180",
|
||||||
|
Transform::Flipped270 => "flip270",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_tab_key(key: &str) -> Self {
|
||||||
|
match key {
|
||||||
|
"default" => Transform::Undefined,
|
||||||
|
"normal" => Transform::Normal,
|
||||||
|
"rotate90" => Transform::Rotated90,
|
||||||
|
"rotate180" => Transform::Rotated180,
|
||||||
|
"rotate270" => Transform::Rotated270,
|
||||||
|
"flipped" => Transform::Flipped,
|
||||||
|
"flip90" => Transform::Flipped90,
|
||||||
|
"flip180" => Transform::Flipped180,
|
||||||
|
"flip270" => Transform::Flipped270,
|
||||||
|
_ => {
|
||||||
|
panic!("cannot translate to mouse transform: {key}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,7 +45,7 @@ impl SpriteTabKey for StereoMode {
|
|||||||
"topbottom" => StereoMode::TopBottom,
|
"topbottom" => StereoMode::TopBottom,
|
||||||
"bottomtop" => StereoMode::BottomTop,
|
"bottomtop" => StereoMode::BottomTop,
|
||||||
_ => {
|
_ => {
|
||||||
panic!("cannot translate to positioning: {key}")
|
panic!("cannot translate to stereo mode: {key}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use crate::{
|
|||||||
subsystem::hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT, WheelDelta},
|
subsystem::hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT, WheelDelta},
|
||||||
windowing::backend::{
|
windowing::backend::{
|
||||||
BackendAttrib, BackendAttribValue, FrameMeta, OverlayBackend, OverlayEventData,
|
BackendAttrib, BackendAttribValue, FrameMeta, OverlayBackend, OverlayEventData,
|
||||||
RenderResources, ShouldRender, StereoMode,
|
RenderResources, ShouldRender, StereoMode, ui_transform,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,6 +47,10 @@ pub struct ScreenBackend {
|
|||||||
mouse_transform: Affine2,
|
mouse_transform: Affine2,
|
||||||
interaction_transform: Option<Affine2>,
|
interaction_transform: Option<Affine2>,
|
||||||
stereo: Option<StereoMode>,
|
stereo: Option<StereoMode>,
|
||||||
|
pub(super) logical_pos: Vec2,
|
||||||
|
pub(super) logical_size: Vec2,
|
||||||
|
pub(super) mouse_transform_original: Transform,
|
||||||
|
mouse_transform_override: Transform,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScreenBackend {
|
impl ScreenBackend {
|
||||||
@@ -63,49 +67,61 @@ impl ScreenBackend {
|
|||||||
mouse_transform: Affine2::ZERO,
|
mouse_transform: Affine2::ZERO,
|
||||||
interaction_transform: None,
|
interaction_transform: None,
|
||||||
stereo: None,
|
stereo: None,
|
||||||
|
logical_pos: Vec2::ZERO,
|
||||||
|
logical_size: Vec2::ZERO,
|
||||||
|
mouse_transform_original: Transform::Undefined,
|
||||||
|
mouse_transform_override: Transform::Undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn set_mouse_transform(&mut self, pos: Vec2, size: Vec2, transform: Transform) {
|
pub(super) fn apply_mouse_transform_with_override(&mut self, override_transform: Transform) {
|
||||||
|
let size = self.logical_size;
|
||||||
|
let pos = self.logical_pos;
|
||||||
|
|
||||||
|
let transform = match override_transform {
|
||||||
|
Transform::Undefined => self.mouse_transform_original,
|
||||||
|
other => other,
|
||||||
|
};
|
||||||
|
|
||||||
self.mouse_transform = match transform {
|
self.mouse_transform = match transform {
|
||||||
Transform::Rotated90 | Transform::Flipped90 => Affine2::from_cols(
|
Transform::Normal | Transform::Undefined => {
|
||||||
|
Affine2::from_cols(vec2(size.x, 0.), vec2(0., size.y), pos)
|
||||||
|
}
|
||||||
|
Transform::Rotated90 => Affine2::from_cols(
|
||||||
vec2(0., size.y),
|
vec2(0., size.y),
|
||||||
vec2(-size.x, 0.),
|
vec2(-size.x, 0.),
|
||||||
vec2(pos.x + size.x, pos.y),
|
vec2(pos.x + size.x, pos.y),
|
||||||
),
|
),
|
||||||
Transform::Rotated180 | Transform::Flipped180 => Affine2::from_cols(
|
Transform::Rotated180 => Affine2::from_cols(
|
||||||
vec2(-size.x, 0.),
|
vec2(-size.x, 0.),
|
||||||
vec2(0., -size.y),
|
vec2(0., -size.y),
|
||||||
vec2(pos.x + size.x, pos.y + size.y),
|
vec2(pos.x + size.x, pos.y + size.y),
|
||||||
),
|
),
|
||||||
Transform::Rotated270 | Transform::Flipped270 => Affine2::from_cols(
|
Transform::Rotated270 => Affine2::from_cols(
|
||||||
vec2(0., -size.y),
|
vec2(0., -size.y),
|
||||||
vec2(size.x, 0.),
|
vec2(size.x, 0.),
|
||||||
vec2(pos.x, pos.y + size.y),
|
vec2(pos.x, pos.y + size.y),
|
||||||
),
|
),
|
||||||
_ => Affine2::from_cols(vec2(size.x, 0.), vec2(0., size.y), pos),
|
Transform::Flipped => Affine2::from_cols(
|
||||||
|
vec2(-size.x, 0.),
|
||||||
|
vec2(0., size.y),
|
||||||
|
vec2(pos.x + size.x, pos.y),
|
||||||
|
),
|
||||||
|
Transform::Flipped90 => {
|
||||||
|
Affine2::from_cols(vec2(0., size.y), vec2(size.x, 0.), vec2(pos.x, pos.y))
|
||||||
|
}
|
||||||
|
Transform::Flipped180 => Affine2::from_cols(
|
||||||
|
vec2(size.x, 0.),
|
||||||
|
vec2(0., -size.y),
|
||||||
|
vec2(pos.x, pos.y + size.y),
|
||||||
|
),
|
||||||
|
Transform::Flipped270 => Affine2::from_cols(
|
||||||
|
vec2(0., -size.y),
|
||||||
|
vec2(-size.x, 0.),
|
||||||
|
vec2(pos.x + size.x, pos.y + size.y),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn set_interaction_transform(&mut self, res: Vec2, transform: Transform) {
|
|
||||||
let center = Vec2 { x: 0.5, y: 0.5 };
|
|
||||||
self.interaction_transform = Some(match transform {
|
|
||||||
Transform::Rotated90 | Transform::Flipped90 => {
|
|
||||||
Affine2::from_cols(Vec2::NEG_Y * (res.x / res.y), Vec2::NEG_X, center)
|
|
||||||
}
|
|
||||||
Transform::Rotated180 | Transform::Flipped180 => {
|
|
||||||
Affine2::from_cols(Vec2::NEG_X, Vec2::NEG_Y * (-res.x / res.y), center)
|
|
||||||
}
|
|
||||||
Transform::Rotated270 | Transform::Flipped270 => {
|
|
||||||
Affine2::from_cols(Vec2::Y * (res.x / res.y), Vec2::X, center)
|
|
||||||
}
|
|
||||||
_ if res.y > res.x => {
|
|
||||||
// Xorg upright screens
|
|
||||||
Affine2::from_cols(Vec2::X * (res.y / res.x), Vec2::NEG_Y, center)
|
|
||||||
}
|
|
||||||
_ => Affine2::from_cols(Vec2::X, Vec2::NEG_Y * (res.x / res.y), center),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OverlayBackend for ScreenBackend {
|
impl OverlayBackend for ScreenBackend {
|
||||||
@@ -175,17 +191,14 @@ impl OverlayBackend for ScreenBackend {
|
|||||||
.is_some_and(|old| old.extent[..2] != meta.extent[..2])
|
.is_some_and(|old| old.extent[..2] != meta.extent[..2])
|
||||||
{
|
{
|
||||||
pipeline.set_extent(app, [meta.extent[0] as _, meta.extent[1] as _])?;
|
pipeline.set_extent(app, [meta.extent[0] as _, meta.extent[1] as _])?;
|
||||||
self.set_interaction_transform(
|
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));
|
||||||
meta.extent.extent_vec2(),
|
|
||||||
frame.get_transform(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let pipeline =
|
let pipeline =
|
||||||
ScreenPipeline::new(&meta, app, self.stereo.unwrap_or(StereoMode::None))?;
|
ScreenPipeline::new(&meta, app, self.stereo.unwrap_or(StereoMode::None))?;
|
||||||
meta.extent[2] = pipeline.get_depth();
|
meta.extent[2] = pipeline.get_depth();
|
||||||
self.pipeline = Some(pipeline);
|
self.pipeline = Some(pipeline);
|
||||||
self.set_interaction_transform(meta.extent.extent_vec2(), frame.get_transform());
|
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.meta = Some(meta);
|
self.meta = Some(meta);
|
||||||
@@ -281,6 +294,9 @@ impl OverlayBackend for ScreenBackend {
|
|||||||
fn get_attrib(&self, attrib: BackendAttrib) -> Option<BackendAttribValue> {
|
fn get_attrib(&self, attrib: BackendAttrib) -> Option<BackendAttribValue> {
|
||||||
match attrib {
|
match attrib {
|
||||||
BackendAttrib::Stereo => self.stereo.map(|s| BackendAttribValue::Stereo(s)),
|
BackendAttrib::Stereo => self.stereo.map(|s| BackendAttribValue::Stereo(s)),
|
||||||
|
BackendAttrib::MouseTransform => Some(BackendAttribValue::MouseTransform(
|
||||||
|
self.mouse_transform_override,
|
||||||
|
)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,6 +315,11 @@ impl OverlayBackend for ScreenBackend {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BackendAttribValue::MouseTransform(new) => {
|
||||||
|
self.mouse_transform_override = new;
|
||||||
|
self.apply_mouse_transform_with_override(new);
|
||||||
|
true
|
||||||
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use glam::vec2;
|
use glam::vec2;
|
||||||
use wlx_capture::{
|
use wlx_capture::{
|
||||||
WlxCapture,
|
WlxCapture,
|
||||||
|
frame::Transform,
|
||||||
wayland::{WlxClient, WlxOutput},
|
wayland::{WlxClient, WlxOutput},
|
||||||
wlr_dmabuf::WlrDmabufCapture,
|
wlr_dmabuf::WlrDmabufCapture,
|
||||||
wlr_screencopy::WlrScreencopyCapture,
|
wlr_screencopy::WlrScreencopyCapture,
|
||||||
@@ -124,15 +125,14 @@ pub fn create_screens_wayland(wl: &mut WlxClient, app: &mut AppState) -> ScreenC
|
|||||||
&mut pw_tokens,
|
&mut pw_tokens,
|
||||||
app,
|
app,
|
||||||
) {
|
) {
|
||||||
let logical_pos = vec2(output.logical_pos.0 as f32, output.logical_pos.1 as f32);
|
backend.logical_pos = vec2(output.logical_pos.0 as f32, output.logical_pos.1 as f32);
|
||||||
let logical_size = vec2(output.logical_size.0 as f32, output.logical_size.1 as f32);
|
backend.logical_size = vec2(output.logical_size.0 as f32, output.logical_size.1 as f32);
|
||||||
let transform = output.transform;
|
backend.mouse_transform_original = output.transform;
|
||||||
|
backend.apply_mouse_transform_with_override(Transform::Undefined);
|
||||||
backend.set_mouse_transform(logical_pos, logical_size, transform);
|
|
||||||
|
|
||||||
let window_config = create_screen_from_backend(
|
let window_config = create_screen_from_backend(
|
||||||
output.name.clone(),
|
output.name.clone(),
|
||||||
transform,
|
output.transform,
|
||||||
&app.session,
|
&app.session,
|
||||||
Box::new(backend),
|
Box::new(backend),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -103,11 +103,9 @@ pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result<ScreenCreateDa
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
backend.set_mouse_transform(
|
backend.logical_pos = vec2(m.monitor.x() as f32, m.monitor.y() as f32);
|
||||||
vec2(m.monitor.x() as f32, m.monitor.y() as f32),
|
backend.logical_size = vec2(m.monitor.width() as f32, m.monitor.height() as f32);
|
||||||
vec2(m.monitor.width() as f32, m.monitor.height() as f32),
|
backend.apply_mouse_transform_with_override(Transform::Undefined);
|
||||||
Transform::Normal,
|
|
||||||
);
|
|
||||||
|
|
||||||
let window_data = create_screen_from_backend(
|
let window_data = create_screen_from_backend(
|
||||||
m.name.clone(),
|
m.name.clone(),
|
||||||
@@ -188,11 +186,9 @@ pub fn create_screens_xshm(app: &mut AppState) -> anyhow::Result<ScreenCreateDat
|
|||||||
pos,
|
pos,
|
||||||
);
|
);
|
||||||
|
|
||||||
backend.set_mouse_transform(
|
backend.logical_pos = vec2(s.monitor.x() as f32, s.monitor.y() as f32);
|
||||||
vec2(s.monitor.x() as f32, s.monitor.y() as f32),
|
backend.logical_size = vec2(size.0 as f32, size.1 as f32);
|
||||||
vec2(size.0 as f32, size.1 as f32),
|
backend.apply_mouse_transform_with_override(Transform::Undefined);
|
||||||
Transform::Normal,
|
|
||||||
);
|
|
||||||
|
|
||||||
let window_data = create_screen_from_backend(
|
let window_data = create_screen_from_backend(
|
||||||
s.name.clone(),
|
s.name.clone(),
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use wgui::gfx::{
|
|||||||
WGfx,
|
WGfx,
|
||||||
cmd::{GfxCommandBuffer, WGfxClearMode},
|
cmd::{GfxCommandBuffer, WGfxClearMode},
|
||||||
};
|
};
|
||||||
|
use wlx_capture::frame::Transform;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::input::{HoverResult, PointerHit},
|
backend::input::{HoverResult, PointerHit},
|
||||||
@@ -111,11 +112,13 @@ macro_rules! attrib_value {
|
|||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum BackendAttrib {
|
pub enum BackendAttrib {
|
||||||
Stereo,
|
Stereo,
|
||||||
|
MouseTransform,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum BackendAttribValue {
|
pub enum BackendAttribValue {
|
||||||
Stereo(StereoMode),
|
Stereo(StereoMode),
|
||||||
|
MouseTransform(Transform),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct OverlayMeta {
|
pub struct OverlayMeta {
|
||||||
|
|||||||