FullscreenUI: Replace landing icons with colourable icons

This commit is contained in:
Stenzek 2025-03-15 13:56:29 +10:00
parent 4bac7cb79e
commit 2a86faa51e
No known key found for this signature in database
19 changed files with 331 additions and 33 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#ffffff" d="M12 2C17.52 2 22 6.48 22 12C22 17.52 17.52 22 12 22C6.48 22 2 17.52 2 12C2 6.48 6.48 2 12 2ZM12 20C16.42 20 20 16.42 20 12C20 7.58 16.42 4 12 4C7.58 4 4 7.58 4 12C4 16.42 7.58 20 12 20ZM12 11H16V13H12V16L8 12L12 8V11Z"></path></svg>

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#ffffff" d="M21 3C21.5523 3 22 3.44772 22 4V11H20V5H4V19H10V21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H21ZM21 13C21.5523 13 22 13.4477 22 14V20C22 20.5523 21.5523 21 21 21H13C12.4477 21 12 20.5523 12 20V14C12 13.4477 12.4477 13 13 13H21ZM11.5 7L9.45711 9.04311L11.7071 11.2929L10.2929 12.7071L8.04311 10.4571L6 12.5V7H11.5Z"></path></svg>

After

Width:  |  Height:  |  Size: 424 B

View File

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 512 512"
version="1.1"
id="svg1"
sodipodi:docname="exit.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
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="true"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="2.640625"
inkscape:cx="256"
inkscape:cy="256"
inkscape:window-width="2856"
inkscape:window-height="1651"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
<path
fill="#ffffff"
d="m 363.3838,123.77433 108.17663,108.17663 c 6.3426,6.3426 9.95436,15.06368 9.95436,24.04904 0,8.98535 -3.61176,17.70643 -9.95436,24.04904 L 363.3838,388.22566 c -5.63787,5.63787 -13.21376,8.72108 -21.14202,8.72108 -16.47315,0 -29.86309,-13.38994 -29.86309,-29.86309 V 312.37869 H 199.6213 c -15.59223,0 -28.18935,-12.59711 -28.18935,-28.18935 v -56.37869 c 0,-15.59223 12.59712,-28.18935 28.18935,-28.18935 h 112.75739 v -54.70496 c 0,-16.47315 13.38994,-29.86309 29.86309,-29.86309 7.92826,0 15.50415,3.1713 21.14202,8.72108 z m -191.95185,-8.72108 h -56.3787 c -15.59222,0 -28.189349,12.59712 -28.189349,28.18935 v 225.51479 c 0,15.59223 12.597119,28.18935 28.189349,28.18935 h 56.3787 c 15.59223,0 28.18935,12.59712 28.18935,28.18935 0,15.59223 -12.59712,28.18935 -28.18935,28.18935 h -56.3787 c -46.688603,0 -84.56804,-37.87944 -84.56804,-84.56805 V 143.2426 c 0,-46.688607 37.879437,-84.568041 84.56804,-84.568041 h 56.3787 c 15.59223,0 28.18935,12.597115 28.18935,28.189347 0,15.592224 -12.59712,28.189344 -28.18935,28.189344 z"
id="path1"
style="stroke-width:0.880917" />
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 640 640"
version="1.1"
id="svg1"
sodipodi:docname="game-list.svg"
width="640"
height="640"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
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="#000001"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="true"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="0.93429246"
inkscape:cx="436.69409"
inkscape:cy="330.73156"
inkscape:window-width="2844"
inkscape:window-height="1651"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
<path
fill="#ffffff"
d="m 264.14016,286.21023 c -46.25894,0 -83.78977,37.53084 -83.78977,83.78977 0,46.25893 37.53083,83.78978 83.78977,83.78978 h 111.71968 c 46.25894,0 83.78977,-37.53085 83.78977,-83.78978 0,-46.25894 -37.53083,-83.78977 -83.78977,-83.78977 z m 132.66713,45.38613 a 17.456203,17.456203 0 1 1 0,34.91239 17.456203,17.456203 0 1 1 0,-34.91239 z m -45.38612,59.35108 a 17.456203,17.456203 0 1 1 34.91239,0 17.456203,17.456203 0 1 1 -34.91239,0 z m -97.75473,-45.38612 c 0,-5.80419 4.66954,-10.47373 10.47372,-10.47373 5.80418,0 10.47371,4.66954 10.47371,10.47373 v 13.96496 h 13.96497 c 5.80417,0 10.47373,4.66953 10.47373,10.47372 0,5.80419 -4.66954,10.47372 -10.47373,10.47372 h -13.96497 v 13.96496 c 0,5.80419 -4.66953,10.47373 -10.47371,10.47373 -5.80419,0 -10.47372,-4.66954 -10.47372,-10.47373 v -13.96496 h -13.96496 c -5.8042,0 -10.47373,-4.66953 -10.47373,-10.47372 0,-5.8042 4.66953,-10.47373 10.47373,-10.47373 h 13.96496 z"
id="path1"
style="stroke-width:0.436405" />
<path
fill="#ffffff"
d="m 89.226718,138.67812 c -9.066093,0 -16.483806,7.41772 -16.483806,16.48381 v 329.67613 c 0,9.06609 7.417713,16.4838 16.483806,16.4838 H 550.77329 c 9.06608,0 16.4838,-7.41771 16.4838,-16.4838 V 155.16193 c 0,-9.06609 -7.41772,-16.48381 -16.4838,-16.48381 z m -65.935226,16.48381 c 0,-36.36739 29.567828,-65.935223 65.935226,-65.935223 H 550.77329 c 36.36739,0 65.93522,29.567833 65.93522,65.935223 v 329.67613 c 0,36.36739 -29.56783,65.93523 -65.93522,65.93523 H 89.226718 c -36.367398,0 -65.935226,-29.56784 -65.935226,-65.93523 z m 98.902838,65.93523 c 0,-18.20753 14.76011,-32.96759 32.96761,-32.96759 18.20751,0 32.96761,14.76006 32.96761,32.96759 0,18.20752 -14.7601,32.96759 -32.96761,32.96759 -18.2075,0 -32.96761,-14.76007 -32.96761,-32.96759 z m 107.14475,0 c 0,-13.70217 11.02352,-24.72572 24.72569,-24.72572 h 230.77329 c 13.70216,0 24.72571,11.02355 24.72571,24.72572 0,13.70217 -11.02355,24.72572 -24.72571,24.72572 H 254.06477 c -13.70217,0 -24.72569,-11.02355 -24.72569,-24.72572 z"
id="path1-5"
style="stroke-width:1.03024"
sodipodi:nodetypes="ssssssssssssssssssssssssssssss" />
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#ffffff" d="M2.13127 13.6308C1.9492 12.5349 1.95521 11.434 2.13216 10.3695C3.23337 10.3963 4.22374 9.86798 4.60865 8.93871C4.99357 8.00944 4.66685 6.93557 3.86926 6.17581C4.49685 5.29798 5.27105 4.51528 6.17471 3.86911C6.9345 4.66716 8.0087 4.99416 8.93822 4.60914C9.86774 4.22412 10.3961 3.23332 10.369 2.13176C11.4649 1.94969 12.5658 1.9557 13.6303 2.13265C13.6036 3.23385 14.1319 4.22422 15.0612 4.60914C15.9904 4.99406 17.0643 4.66733 17.8241 3.86975C18.7019 4.49734 19.4846 5.27153 20.1308 6.1752C19.3327 6.93499 19.0057 8.00919 19.3907 8.93871C19.7757 9.86823 20.7665 10.3966 21.8681 10.3695C22.0502 11.4654 22.0442 12.5663 21.8672 13.6308C20.766 13.6041 19.7756 14.1324 19.3907 15.0616C19.0058 15.9909 19.3325 17.0648 20.1301 17.8245C19.5025 18.7024 18.7283 19.4851 17.8247 20.1312C17.0649 19.3332 15.9907 19.0062 15.0612 19.3912C14.1316 19.7762 13.6033 20.767 13.6303 21.8686C12.5344 22.0507 11.4335 22.0447 10.3691 21.8677C10.3958 20.7665 9.86749 19.7761 8.93822 19.3912C8.00895 19.0063 6.93508 19.333 6.17532 20.1306C5.29749 19.503 4.51479 18.7288 3.86862 17.8252C4.66667 17.0654 4.99367 15.9912 4.60865 15.0616C4.22363 14.1321 3.23284 13.6038 2.13127 13.6308ZM11.9997 15.0002C13.6565 15.0002 14.9997 13.657 14.9997 12.0002C14.9997 10.3433 13.6565 9.00018 11.9997 9.00018C10.3428 9.00018 8.99969 10.3433 8.99969 12.0002C8.99969 13.657 10.3428 15.0002 11.9997 15.0002Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 512 512"
version="1.1"
id="svg1"
sodipodi:docname="start-bios.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
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="true"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="2.640625"
inkscape:cx="256"
inkscape:cy="256"
inkscape:window-width="2852"
inkscape:window-height="1651"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
<path
fill="#ffffff"
d="m 186.11835,53.343194 c 0,-11.617826 -9.34668,-20.964498 -20.9645,-20.964498 -11.61782,0 -20.9645,9.346672 -20.9645,20.964498 v 34.940832 c -30.83528,0 -55.905324,25.070044 -55.905324,55.905324 H 53.343194 c -11.617826,0 -20.964498,9.34668 -20.964498,20.9645 0,11.61782 9.346672,20.9645 20.964498,20.9645 H 88.284026 V 235.0355 H 53.343194 c -11.617826,0 -20.964498,9.34668 -20.964498,20.96449 0,11.61783 9.346672,20.96451 20.964498,20.96451 h 34.940832 v 48.91716 H 53.343194 c -11.617826,0 -20.964498,9.34666 -20.964498,20.96449 0,11.61783 9.346672,20.9645 20.964498,20.9645 h 34.940832 c 0,30.83528 25.070044,55.90533 55.905324,55.90533 v 34.94082 c 0,11.61783 9.34668,20.9645 20.9645,20.9645 11.61782,0 20.9645,-9.34667 20.9645,-20.9645 v -34.94082 h 48.91715 v 34.94082 c 0,11.61783 9.34668,20.9645 20.96449,20.9645 11.61783,0 20.96451,-9.34667 20.96451,-20.9645 v -34.94082 h 48.91716 v 34.94082 c 0,11.61783 9.34666,20.9645 20.96449,20.9645 11.61783,0 20.9645,-9.34667 20.9645,-20.9645 v -34.94082 c 30.83528,0 55.90533,-25.07005 55.90533,-55.90533 h 34.94082 c 11.61783,0 20.9645,-9.34667 20.9645,-20.9645 0,-11.61783 -9.34667,-20.96449 -20.9645,-20.96449 H 423.71598 V 276.9645 h 34.94082 c 11.61783,0 20.9645,-9.34668 20.9645,-20.96451 0,-11.61781 -9.34667,-20.96449 -20.9645,-20.96449 h -34.94082 v -48.91715 h 34.94082 c 11.61783,0 20.9645,-9.34668 20.9645,-20.9645 0,-11.61782 -9.34667,-20.9645 -20.9645,-20.9645 h -34.94082 c 0,-30.83528 -25.07005,-55.905324 -55.90533,-55.905324 V 53.343194 c 0,-11.617826 -9.34667,-20.964498 -20.9645,-20.964498 -11.61783,0 -20.96449,9.346672 -20.96449,20.964498 V 88.284026 H 276.9645 V 53.343194 c 0,-11.617826 -9.34668,-20.964498 -20.96451,-20.964498 -11.61781,0 -20.96449,9.346672 -20.96449,20.964498 v 34.940832 h -48.91715 z m -13.97634,90.846156 h 167.71598 c 15.46131,0 27.95266,12.49134 27.95266,27.95266 v 167.71598 c 0,15.46131 -12.49135,27.95266 -27.95266,27.95266 H 172.14201 c -15.46132,0 -27.95266,-12.49135 -27.95266,-27.95266 V 172.14201 c 0,-15.46132 12.49134,-27.95266 27.95266,-27.95266 z m 167.71598,27.95266 H 172.14201 v 167.71598 h 167.71598 z"
id="path1"
style="stroke-width:0.87352" />
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 512 512"
version="1.1"
id="svg1"
sodipodi:docname="start-disc.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
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="true"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="1.8685849"
inkscape:cx="269.72282"
inkscape:cy="294.60797"
inkscape:window-width="2856"
inkscape:window-height="1652"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
<path
fill="#ffffff"
d="m 49.005172,256 a 206.99483,206.99483 0 1 1 413.989658,0 206.99483,206.99483 0 1 1 -413.989658,0 z M 256,281.87436 a 25.874355,25.874355 0 1 1 0,-51.74871 25.874355,25.874355 0 1 1 0,51.74871 z M 178.37694,256 a 77.62306,77.62306 0 1 0 155.24612,0 77.62306,77.62306 0 1 0 -155.24612,0 z m -51.7487,-12.93717 c 0,-28.30008 14.15003,-57.48958 36.54752,-79.88707 22.39749,-22.39749 51.58699,-36.54752 79.88707,-36.54752 7.11544,0 12.93717,-5.82173 12.93717,-12.93718 0,-7.11545 -5.82173,-12.93718 -12.93717,-12.93718 -36.70924,0 -72.12476,18.03119 -98.24169,44.06726 -26.11692,26.03607 -44.06726,61.53245 -44.06726,98.24169 0,7.11544 5.82173,12.93717 12.93718,12.93717 7.11545,0 12.93718,-5.82173 12.93718,-12.93717 z"
id="path1"
style="stroke-width:0.808574" />
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 576 576"
version="1.1"
id="svg1"
sodipodi:docname="start-file.svg"
width="576"
height="576"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
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="true"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="2.640625"
inkscape:cx="287.81065"
inkscape:cy="225.70414"
inkscape:window-width="2852"
inkscape:window-height="1651"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
<path
fill="#ffffff"
d="m 375.58614,492.32782 h 43.78453 c 10.39883,0 19.97669,-5.47306 25.17611,-14.50363 L 546.71069,302.68606 c 5.29063,-9.03055 5.29063,-20.15913 0.0912,-29.2809 -5.19941,-9.12179 -14.77728,-14.59484 -25.26731,-14.59484 H 156.66347 c -10.39883,0 -19.9767,5.47306 -25.17611,14.50363 L 69.0944,380.22117 V 142.05155 c 0,-8.02715 6.567679,-14.59484 14.594844,-14.59484 H 190.87013 c 3.83116,0 7.57108,1.55071 10.30762,4.28724 l 24.17271,24.17271 c 19.15573,19.15573 45.15279,29.91943 72.24447,29.91943 h 107.1809 c 8.02716,0 14.59484,6.56767 14.59484,14.59484 v 29.1897 h 43.78454 v -29.1897 c 0,-32.19988 -26.17951,-58.37938 -58.37938,-58.37938 h -107.1809 c -15.50702,0 -30.37551,-6.11158 -41.32164,-17.05772 L 232.10058,100.72991 C 221.15444,89.783772 206.28594,83.672181 190.77892,83.672181 H 83.689244 c -32.199876,0 -58.379378,26.179509 -58.379378,58.379369 v 291.89689 c 0,32.19988 26.179502,58.37938 58.379378,58.37938 h 21.618616 z"
id="path1"
style="stroke-width:0.912178" />
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -80,6 +80,7 @@ using ImGuiFullscreen::ChoiceDialogOptions;
using ImGuiFullscreen::FocusResetType;
using ImGuiFullscreen::LAYOUT_FOOTER_HEIGHT;
using ImGuiFullscreen::LAYOUT_HORIZONTAL_MENU_ITEM_IMAGE_SIZE;
using ImGuiFullscreen::LAYOUT_LARGE_FONT_SIZE;
using ImGuiFullscreen::LAYOUT_MEDIUM_FONT_SIZE;
using ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT;
@ -249,6 +250,11 @@ static ChoiceDialogOptions GetBackgroundOptions(const TinyString& current_value)
//////////////////////////////////////////////////////////////////////////
static bool LoadResources();
static void DestroyResources();
static GPUTexture* GetUserThemeableTexture(
const std::string_view png_name, const std::string_view svg_name, bool* is_colorable = nullptr,
const ImVec2& svg_size = LayoutScale(LAYOUT_HORIZONTAL_MENU_ITEM_IMAGE_SIZE, LAYOUT_HORIZONTAL_MENU_ITEM_IMAGE_SIZE));
static bool UserThemeableHorizontalButton(const std::string_view png_name, const std::string_view svg_name,
const char* title, const char* description);
//////////////////////////////////////////////////////////////////////////
// Landing
@ -478,12 +484,13 @@ static constexpr const std::array s_ps_button_mapping{
std::make_pair(ICON_PF_RIGHT_TRIGGER_RT, ICON_PF_RIGHT_TRIGGER_R2),
};
static constexpr std::array s_theme_names = {FSUI_NSTR("Automatic"), FSUI_NSTR("Dark"), FSUI_NSTR("Light"),
FSUI_NSTR("AMOLED"), FSUI_NSTR("Cobalt Sky"), FSUI_NSTR("Grey Matter"),
FSUI_NSTR("Pinky Pals"), FSUI_NSTR("Dark Ruby"), FSUI_NSTR("Purple Rain")};
static constexpr std::array s_theme_names = {
FSUI_NSTR("Automatic"), FSUI_NSTR("Dark"), FSUI_NSTR("Light"),
FSUI_NSTR("AMOLED"), FSUI_NSTR("Cobalt Sky"), FSUI_NSTR("Grey Matter"),
FSUI_NSTR("Pinky Pals"), FSUI_NSTR("Dark Ruby"), FSUI_NSTR("Purple Rain")};
static constexpr std::array s_theme_values = {"", "Dark", "Light", "AMOLED",
"CobaltSky", "GreyMatter", "PinkyPals", "DarkRuby", "PurpleRain"};
static constexpr std::array s_theme_values = {"", "Dark", "Light", "AMOLED", "CobaltSky",
"GreyMatter", "PinkyPals", "DarkRuby", "PurpleRain"};
//////////////////////////////////////////////////////////////////////////
// State
@ -1121,9 +1128,9 @@ bool FullscreenUI::LoadResources()
{
s_state.app_icon_texture = LoadTexture("images/duck.png");
s_state.fallback_disc_texture = LoadTexture("fullscreenui/cdrom.png");
s_state.fallback_exe_texture = LoadTexture("fullscreenui/settings.png");
s_state.fallback_exe_texture = LoadTexture("fullscreenui/exe-file.png");
s_state.fallback_psf_texture = LoadTexture("fullscreenui/psf-file.png");
s_state.fallback_playlist_texture = LoadTexture("fullscreenui/game-list.png");
s_state.fallback_playlist_texture = LoadTexture("fullscreenui/playlist-file.png");
return true;
}
@ -1138,6 +1145,53 @@ void FullscreenUI::DestroyResources()
s_state.app_icon_texture.reset();
}
GPUTexture* FullscreenUI::GetUserThemeableTexture(const std::string_view png_name, const std::string_view svg_name,
bool* is_colorable, const ImVec2& svg_size)
{
GPUTexture* tex = ImGuiFullscreen::FindCachedTexture(png_name);
if (tex)
{
if (is_colorable)
*is_colorable = false;
return tex;
}
const u32 svg_width = static_cast<u32>(svg_size.x);
const u32 svg_height = static_cast<u32>(svg_size.y);
tex = ImGuiFullscreen::FindCachedTexture(svg_name, svg_width, svg_height);
if (tex)
return tex;
// slow path, check filesystem for override
if (EmuFolders::Resources != EmuFolders::UserResources &&
FileSystem::FileExists(Path::Combine(EmuFolders::UserResources, png_name).c_str()))
{
// use the user's png
if (is_colorable)
*is_colorable = false;
return ImGuiFullscreen::GetCachedTexture(png_name);
}
// otherwise use the system/user svg
if (is_colorable)
*is_colorable = true;
return ImGuiFullscreen::GetCachedTexture(svg_name, svg_width, svg_height);
}
bool FullscreenUI::UserThemeableHorizontalButton(const std::string_view png_name, const std::string_view svg_name,
const char* title, const char* description)
{
bool is_colorable;
GPUTexture* icon = GetUserThemeableTexture(
png_name, svg_name, &is_colorable,
LayoutScale(LAYOUT_HORIZONTAL_MENU_ITEM_IMAGE_SIZE, LAYOUT_HORIZONTAL_MENU_ITEM_IMAGE_SIZE));
return HorizontalMenuItem(icon, title, description,
is_colorable ? ImGui::GetColorU32(ImGuiCol_Text) : IM_COL32(255, 255, 255, 255));
}
//////////////////////////////////////////////////////////////////////////
// Utility
//////////////////////////////////////////////////////////////////////////
@ -1873,28 +1927,29 @@ void FullscreenUI::DrawLandingWindow()
{
ResetFocusHere();
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/game-list.png"), FSUI_CSTR("Game List"),
FSUI_CSTR("Launch a game from images scanned from your game directories.")))
if (UserThemeableHorizontalButton("fullscreenui/game-list.png", "fullscreenui/game-list.svg",
FSUI_CSTR("Game List"),
FSUI_CSTR("Launch a game from images scanned from your game directories.")))
{
SwitchToGameList();
}
if (HorizontalMenuItem(
GetCachedTexture("fullscreenui/cdrom.png"), FSUI_CSTR("Start Game"),
if (UserThemeableHorizontalButton(
"fullscreenui/cdrom.png", "fullscreenui/start-disc.svg", FSUI_CSTR("Start Game"),
FSUI_CSTR("Launch a game from a file, disc, or starts the console without any disc inserted.")))
{
s_state.current_main_window = MainWindowType::StartGame;
QueueResetFocus(FocusResetType::ViewChanged);
}
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/settings.png"), FSUI_CSTR("Settings"),
FSUI_CSTR("Changes settings for the application.")))
if (UserThemeableHorizontalButton("fullscreenui/settings.png", "fullscreenui/settings.svg", FSUI_CSTR("Settings"),
FSUI_CSTR("Changes settings for the application.")))
{
SwitchToSettings();
}
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/exit.png"), FSUI_CSTR("Exit"),
FSUI_CSTR("Return to desktop mode, or exit the application.")) ||
if (UserThemeableHorizontalButton("fullscreenui/exit.png", "fullscreenui/exit.svg", FSUI_CSTR("Exit"),
FSUI_CSTR("Return to desktop mode, or exit the application.")) ||
(!AreAnyDialogsOpen() && WantsToCloseMenu()))
{
s_state.current_main_window = MainWindowType::Exit;
@ -1949,27 +2004,26 @@ void FullscreenUI::DrawStartGameWindow()
{
ResetFocusHere();
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/start-file.png"), FSUI_CSTR("Start File"),
FSUI_CSTR("Launch a game by selecting a file/disc image.")))
if (HorizontalMenuItem(GetUserThemeableTexture("fullscreenui/start-file.png", "fullscreenui/start-file.svg"),
FSUI_CSTR("Start File"), FSUI_CSTR("Launch a game by selecting a file/disc image.")))
{
DoStartFile();
}
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/start-disc.png"), FSUI_CSTR("Start Disc"),
FSUI_CSTR("Start a game from a disc in your PC's DVD drive.")))
if (HorizontalMenuItem(GetUserThemeableTexture("fullscreenui/start-disc.png", "fullscreenui/start-disc.svg"),
FSUI_CSTR("Start Disc"), FSUI_CSTR("Start a game from a disc in your PC's DVD drive.")))
{
DoStartDisc();
}
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/start-bios.png"), FSUI_CSTR("Start BIOS"),
FSUI_CSTR("Start the console without any disc inserted.")))
if (HorizontalMenuItem(GetUserThemeableTexture("fullscreenui/start-bios.png", "fullscreenui/start-bios.svg"),
FSUI_CSTR("Start BIOS"), FSUI_CSTR("Start the console without any disc inserted.")))
{
DoStartBIOS();
}
// https://www.iconpacks.net/free-icon/arrow-back-3783.html
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/back-icon.png"), FSUI_CSTR("Back"),
FSUI_CSTR("Return to the previous menu.")) ||
if (HorizontalMenuItem(GetUserThemeableTexture("fullscreenui/back-icon.png", "fullscreenui/back-icon.svg"),
FSUI_CSTR("Back"), FSUI_CSTR("Return to the previous menu.")) ||
(!AreAnyDialogsOpen() && WantsToCloseMenu()))
{
s_state.current_main_window = MainWindowType::Landing;
@ -2016,22 +2070,23 @@ void FullscreenUI::DrawExitWindow()
{
ResetFocusHere();
// https://www.iconpacks.net/free-icon/arrow-back-3783.html
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/back-icon.png"), FSUI_CSTR("Back"),
FSUI_CSTR("Return to the previous menu.")) ||
if (HorizontalMenuItem(GetUserThemeableTexture("fullscreenui/back-icon.png", "fullscreenui/back-icon.svg"),
FSUI_CSTR("Back"), FSUI_CSTR("Return to the previous menu.")) ||
WantsToCloseMenu())
{
s_state.current_main_window = MainWindowType::Landing;
QueueResetFocus(FocusResetType::ViewChanged);
}
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/exit.png"), FSUI_CSTR("Exit DuckStation"),
if (HorizontalMenuItem(GetUserThemeableTexture("fullscreenui/exit.png", "fullscreenui/exit.svg"),
FSUI_CSTR("Exit DuckStation"),
FSUI_CSTR("Completely exits the application, returning you to your desktop.")))
{
DoRequestExit();
}
if (HorizontalMenuItem(GetCachedTexture("fullscreenui/desktop-mode.png"), FSUI_CSTR("Desktop Mode"),
if (HorizontalMenuItem(GetUserThemeableTexture("fullscreenui/desktop-mode.png", "fullscreenui/desktop-mode.svg"),
FSUI_CSTR("Desktop Mode"),
FSUI_CSTR("Exits Big Picture mode, returning to the desktop interface.")))
{
DoDesktopMode();

View File

@ -372,6 +372,26 @@ std::shared_ptr<GPUTexture> ImGuiFullscreen::LoadTexture(std::string_view path,
return s_state.placeholder_texture;
}
GPUTexture* ImGuiFullscreen::FindCachedTexture(std::string_view name)
{
std::shared_ptr<GPUTexture>* tex_ptr = s_state.texture_cache.Lookup(name);
return tex_ptr ? tex_ptr->get() : nullptr;
}
GPUTexture* ImGuiFullscreen::FindCachedTexture(std::string_view name, u32 svg_width, u32 svg_height)
{
// ignore size hints if it's not needed, don't duplicate
if (!TextureNeedsSVGDimensions(name))
return FindCachedTexture(name);
svg_width = static_cast<u32>(std::ceil(LayoutScale(static_cast<float>(svg_width))));
svg_height = static_cast<u32>(std::ceil(LayoutScale(static_cast<float>(svg_height))));
const SmallString wh_name = SmallString::from_format("{}#{}x{}", name, svg_width, svg_height);
std::shared_ptr<GPUTexture>* tex_ptr = s_state.texture_cache.Lookup(wh_name.view());
return tex_ptr ? tex_ptr->get() : nullptr;
}
GPUTexture* ImGuiFullscreen::GetCachedTexture(std::string_view name)
{
std::shared_ptr<GPUTexture>* tex_ptr = s_state.texture_cache.Lookup(name);
@ -561,6 +581,12 @@ ImRect ImGuiFullscreen::CenterImage(const ImVec2& fit_size, const ImVec2& image_
return ret;
}
ImRect ImGuiFullscreen::CenterImage(const ImVec2& fit_rect, const GPUTexture* texture)
{
const GSVector2 texture_size = GSVector2(texture->GetSizeVec());
return CenterImage(fit_rect, ImVec2(texture_size.x, texture_size.y));
}
ImRect ImGuiFullscreen::CenterImage(const ImRect& fit_rect, const ImVec2& image_size)
{
ImRect ret(CenterImage(fit_rect.Max - fit_rect.Min, image_size));
@ -568,6 +594,12 @@ ImRect ImGuiFullscreen::CenterImage(const ImRect& fit_rect, const ImVec2& image_
return ret;
}
ImRect ImGuiFullscreen::CenterImage(const ImRect& fit_rect, const GPUTexture* texture)
{
const GSVector2 texture_size = GSVector2(texture->GetSizeVec());
return CenterImage(fit_rect, ImVec2(texture_size.x, texture_size.y));
}
ImRect ImGuiFullscreen::FitImage(const ImVec2& fit_size, const ImVec2& image_size)
{
ImRect rect;
@ -2209,7 +2241,7 @@ void ImGuiFullscreen::EndHorizontalMenu()
EndFullscreenWindow();
}
bool ImGuiFullscreen::HorizontalMenuItem(GPUTexture* icon, const char* title, const char* description)
bool ImGuiFullscreen::HorizontalMenuItem(GPUTexture* icon, const char* title, const char* description, u32 color)
{
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
@ -2244,11 +2276,13 @@ bool ImGuiFullscreen::HorizontalMenuItem(GPUTexture* icon, const char* title, co
bb.Max -= style.FramePadding;
const float avail_width = bb.Max.x - bb.Min.x;
const float icon_size = LayoutScale(150.0f);
const float icon_size = LayoutScale(LAYOUT_HORIZONTAL_MENU_ITEM_IMAGE_SIZE);
const ImVec2 icon_pos = bb.Min + ImVec2((avail_width - icon_size) * 0.5f, 0.0f);
const ImRect icon_box = CenterImage(ImRect(icon_pos, icon_pos + ImVec2(icon_size, icon_size)), icon);
ImDrawList* dl = ImGui::GetWindowDrawList();
dl->AddImage(reinterpret_cast<ImTextureID>(icon), icon_pos, icon_pos + ImVec2(icon_size, icon_size));
dl->AddImage(reinterpret_cast<ImTextureID>(icon), icon_box.Min, icon_box.Max, ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f),
color);
ImFont* title_font = UIStyle.LargeFont;
const ImVec2 title_size =

View File

@ -42,6 +42,7 @@ static constexpr float LAYOUT_FOOTER_HEIGHT = LAYOUT_MEDIUM_FONT_SIZE + LAYOUT_F
static constexpr float LAYOUT_HORIZONTAL_MENU_HEIGHT = 320.0f;
static constexpr float LAYOUT_HORIZONTAL_MENU_PADDING = 30.0f;
static constexpr float LAYOUT_HORIZONTAL_MENU_ITEM_WIDTH = 250.0f;
static constexpr float LAYOUT_HORIZONTAL_MENU_ITEM_IMAGE_SIZE = 150.0f;
static constexpr float LAYOUT_SHADOW_OFFSET = 1.0f;
struct ALIGN_TO_CACHE_LINE UIStyles
@ -151,7 +152,9 @@ ALWAYS_INLINE static std::string_view RemoveHash(std::string_view s)
/// Centers an image within the specified bounds, scaling up or down as needed.
ImRect CenterImage(const ImVec2& fit_size, const ImVec2& image_size);
ImRect CenterImage(const ImVec2& fit_rect, const GPUTexture* texture);
ImRect CenterImage(const ImRect& fit_rect, const ImVec2& image_size);
ImRect CenterImage(const ImRect& fit_rect, const GPUTexture* texture);
/// Fits an image to the specified bounds, cropping if needed. Returns UV coordinates.
ImRect FitImage(const ImVec2& fit_size, const ImVec2& image_size);
@ -170,6 +173,8 @@ void Shutdown(bool clear_state);
/// Texture cache.
const std::shared_ptr<GPUTexture>& GetPlaceholderTexture();
std::shared_ptr<GPUTexture> LoadTexture(std::string_view path, u32 svg_width = 0, u32 svg_height = 0);
GPUTexture* FindCachedTexture(std::string_view name);
GPUTexture* FindCachedTexture(std::string_view name, u32 svg_width, u32 svg_height);
GPUTexture* GetCachedTexture(std::string_view name);
GPUTexture* GetCachedTexture(std::string_view name, u32 svg_width, u32 svg_height);
GPUTexture* GetCachedTextureAsync(std::string_view name);
@ -335,7 +340,8 @@ bool NavTab(const char* title, bool is_active, bool enabled, float width, float
bool BeginHorizontalMenu(const char* name, const ImVec2& position, const ImVec2& size, const ImVec4& bg_color,
u32 num_items);
void EndHorizontalMenu();
bool HorizontalMenuItem(GPUTexture* icon, const char* title, const char* description);
bool HorizontalMenuItem(GPUTexture* icon, const char* title, const char* description,
u32 color = IM_COL32(255, 255, 255, 255));
using FileSelectorCallback = std::function<void(std::string path)>;
using FileSelectorFilters = std::vector<std::string>;