From 95187f37f40795bd5ca0857e4553067a45222f1c Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Thu, 16 Apr 2026 23:39:16 -0500 Subject: [PATCH] Added support for round avatars, added nine slice images, added rounded corners to a lot of stuff, tweaked theme. --- lib/gui_ext.rb | 10 +++++++ lib/theme.rb | 40 ++++++++++++++++++++++++--- lib/window.rb | 43 +++++++++++++++--------------- media/ui/circle.png | Bin 0 -> 2167 bytes media/ui/circle_small.png | Bin 0 -> 582 bytes media/ui/rounded.png | Bin 0 -> 430 bytes media/ui/rounded_bottom.png | Bin 0 -> 341 bytes media/ui/rounded_left.png | Bin 0 -> 350 bytes media/ui/rounded_left_bottom.png | Bin 0 -> 295 bytes media/ui/rounded_left_top.png | Bin 0 -> 304 bytes media/ui/rounded_right.png | Bin 0 -> 357 bytes media/ui/rounded_right_bottom.png | Bin 0 -> 292 bytes media/ui/rounded_right_top.png | Bin 0 -> 299 bytes media/ui/rounded_top.png | Bin 0 -> 361 bytes media/ui/square.png | Bin 0 -> 239 bytes 15 files changed, 68 insertions(+), 25 deletions(-) create mode 100644 media/ui/circle.png create mode 100644 media/ui/circle_small.png create mode 100644 media/ui/rounded.png create mode 100644 media/ui/rounded_bottom.png create mode 100644 media/ui/rounded_left.png create mode 100644 media/ui/rounded_left_bottom.png create mode 100644 media/ui/rounded_left_top.png create mode 100644 media/ui/rounded_right.png create mode 100644 media/ui/rounded_right_bottom.png create mode 100644 media/ui/rounded_right_top.png create mode 100644 media/ui/rounded_top.png create mode 100644 media/ui/square.png diff --git a/lib/gui_ext.rb b/lib/gui_ext.rb index 4ac8685..1643875 100644 --- a/lib/gui_ext.rb +++ b/lib/gui_ext.rb @@ -11,5 +11,15 @@ module W3DHubLauncher WHITE_IMAGE end + + def rounded_avatar(image) + circle = get_image("./media/ui/circle.png") + scale = [(circle.width.to_f / image.width).abs, (circle.width.to_f / image.height).abs].min + + Gosu.render(circle.width, circle.height) do + image.draw_rot(circle.width / 2, circle.height / 2, 0, 0, 0.5, 0.5, scale, scale) + circle.draw(0, 0, 1, 1, 1, 0xff_ffffff, :multiply) + end + end end end diff --git a/lib/theme.rb b/lib/theme.rb index 62e2667..b1c818a 100644 --- a/lib/theme.rb +++ b/lib/theme.rb @@ -11,8 +11,16 @@ module W3DHubLauncher FONT_MONO = "./media/fonts/NotoSansMono-Regular.ttf" + NINE_SLICE_EDGE = 8 + NINE_SLICE_ROUNDED = "./media/ui/rounded.png" + NINE_SLICE_ROUNDED_LEFT = "./media/ui/rounded_left.png" + NINE_SLICE_ROUNDED_RIGHT = "./media/ui/rounded_right.png" + NINE_SLICE_ROUNDED_TOP = "./media/ui/rounded_top.png" + NINE_SLICE_ROUNDED_BOTTOM = "./media/ui/rounded_bottom.png" + NINE_SLICE_SQUARE = "./media/ui/square.png" + CTA_BUTTON_THEME = { - background: 0xff_1a5fb4 + background_nine_slice_color: 0xff_1a5fb4 } THEME = { @@ -35,9 +43,23 @@ module W3DHubLauncher Button: { font: FONT_BOLD, text_shadow: false, - background: 0x88_5e5c64, - border_thickness: 1, - border_color: 0xff_000000 + color: 0xff_ffffff, + background: 0,#x88_5e5c64, + background_nine_slice: NINE_SLICE_ROUNDED, + background_nine_slice_from_edge: NINE_SLICE_EDGE, + background_nine_slice_mode: :stretched, + background_nine_slice_color: 0x88_5e5c64, + border_thickness: 0, + hover: { + color: 0xcc_ffffff, + background: 0, + background_nine_slice_color: 0xff_5e5c64 + }, + active: { + color: 0x88_ffffff, + background: 0, + background_nine_slice_color: 0xaa_5e5c64 + } }, EditLine: { font: FONT_REGULAR @@ -63,6 +85,7 @@ module W3DHubLauncher text_size: 24, text_align: :left, font: FONT_REGULAR, + background_nine_slice: NINE_SLICE_SQUARE, background: 0xee_000000, border_color: 0xaa_000000, hover: { @@ -71,6 +94,15 @@ module W3DHubLauncher active: { background: 0xee_444444 } + }, + ToolTip: { + text_size: 24, + background: 0,#x88_5e5c64, + background_nine_slice: NINE_SLICE_ROUNDED, + background_nine_slice_from_edge: NINE_SLICE_EDGE, + background_nine_slice_mode: :stretched, + background_nine_slice_color: 0xdd_5e5c64, + border_thickness: 0 } } end diff --git a/lib/window.rb b/lib/window.rb index 7e87144..29454c6 100644 --- a/lib/window.rb +++ b/lib/window.rb @@ -17,7 +17,7 @@ module W3DHubLauncher # root container - background image stack(width: 1.0, height: 1.0, background_image: safe_get_image("/run/media/cyberarm/Storage/W3DHub/Launcher/package-cache/games/apb/background.png.package"), background_image_mode: :fill) do # root container - background image tint - flow(width: 1.0, height: 1.0, background: ALPHA_BLACK) do + flow(width: 1.0, height: 1.0, background: 0xaa_000000) do # content container stack(fill: true, height: 1.0, margin: PADDING, margin_right: LARGE_PADDING) do # header bar container @@ -50,18 +50,18 @@ module W3DHubLauncher stack(width: 1.0, fill: true) do # game bar container flow(width: 1.0, height: 60) do - flow(width: 220, height: 1.0, background: ALPHA_BLACK) do + flow(width: 220, height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: ALPHA_BLACK) do flow(width: 1.0, height: 40, margin_left: PADDING, v_align: :center, h_align: :center) do image safe_get_image("./media/icons/menuGrid.png"), height: 40, color: 0xff_bbbbbb link "ALL GAMES", text_size: 24, font: FONT_BLACK, height: 1.0, text_v_align: :center end end - flow(fill: true, height: 1.0, background: ALPHA_BLACK, margin_left: PADDING) do - image safe_get_image("./data/cache/apb.png"), height: 1.0, padding: HALF_PADDING, background:0x88_5e5c64, border_thickness_bottom: 3, border_color_bottom: 0xff_3584e4, tip: "Red Alert: A Path Beyond" - image safe_get_image("./data/cache/ren.png"), height: 1.0, padding: HALF_PADDING, tip: "Command & Conquer: Renegade" - image safe_get_image("./data/cache/tsr.png"), height: 1.0, padding: HALF_PADDING, tip: "Tiberian Sun: Reborn" - image safe_get_image("./data/cache/woa.png"), height: 1.0, padding: HALF_PADDING, tip: "Battle for Dune: War of Assassins" + flow(fill: true, height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: ALPHA_BLACK, margin_left: PADDING) do + image safe_get_image("./data/cache/apb.png"), height: 1.0, padding: HALF_PADDING, background_nine_slice: NINE_SLICE_ROUNDED_TOP, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: 0x88_5e5c64, border_thickness_bottom: 3, border_color_bottom: 0xff_3584e4, tip: "Red Alert: A Path Beyond" + image safe_get_image("./data/cache/ren.png"), height: 1.0, padding: HALF_PADDING, background_nine_slice: NINE_SLICE_ROUNDED_TOP, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: 0, tip: "Command & Conquer: Renegade" + image safe_get_image("./data/cache/tsr.png"), height: 1.0, padding: HALF_PADDING, background_nine_slice: NINE_SLICE_ROUNDED_TOP, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: 0, tip: "Tiberian Sun: Reborn" + image safe_get_image("./data/cache/woa.png"), height: 1.0, padding: HALF_PADDING, background_nine_slice: NINE_SLICE_ROUNDED_TOP, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: 0, tip: "Battle for Dune: War of Assassins" end end @@ -83,16 +83,16 @@ module W3DHubLauncher caption "Game Version" list_box items: [ "Release", "Open Testing" ], width: 1.0, margin_bottom: PADDING flow(width: 1.0, height: 60) do - button "PLAY", fill: true, height: 1.0, **CTA_BUTTON_THEME - button safe_get_image("./media/icons/singleplayer.png"), image_height: 1.0, **CTA_BUTTON_THEME - button safe_get_image("./media/icons/gear.png"), image_height: 1.0, **CTA_BUTTON_THEME + button "PLAY", fill: true, height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_LEFT, **CTA_BUTTON_THEME + button safe_get_image("./media/icons/singleplayer.png"), image_height: 1.0, background_nine_slice: NINE_SLICE_SQUARE, **CTA_BUTTON_THEME + button safe_get_image("./media/icons/gear.png"), image_height: 1.0, background_nine_slice: NINE_SLICE_ROUNDED_RIGHT, **CTA_BUTTON_THEME end inscription "Version: 3.9.2.15", margin_top: PADDING end # game events and news container stack(fill: true, height: 1.0, margin_left: LARGE_PADDING, scroll: true) do - flow(width: 1.0, height: 1.0, max_height: 380, background: ALPHA_BLACK, border_thickness: 1, border_color: Gosu::Color::BLACK) do + flow(width: 1.0, height: 1.0, max_height: 380, background_nine_slice: NINE_SLICE_ROUNDED, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: ALPHA_BLACK) do image safe_get_image("./media/background.png"), fill: true, aspect_ratio: 16.0 / 9.0 stack(fill: true, height: 1.0, margin_left: PADDING) do @@ -109,8 +109,9 @@ module W3DHubLauncher # news container flow(width: 1.0, margin_top: PADDING) do 9.times do - stack(width: 1.0 / 3, height: 345, aspect_ratio: 1, margin_left: HALF_PADDING, margin_right: HALF_PADDING, margin_bottom: PADDING, background: ALPHA_BLACK, background_image: safe_get_image("./media/background.png"), background_image_mode: :fill, border_thickness: 1, border_color: Gosu::Color::BLACK) do - stack(width: 1.0, height: 1.0 / 3, padding: PADDING, v_align: :bottom, background: 0xdd_000000, border_thickness_top: 1, border_color_top: Gosu::Color::BLACK) do + stack(width: 1.0 / 3, height: 345, aspect_ratio: 1, margin_left: HALF_PADDING, margin_right: HALF_PADDING, margin_bottom: PADDING) do + stack(width: 1.0, fill: true, background_image: safe_get_image("./media/background.png"), background_image_mode: :fill) + stack(width: 1.0, height: 1.0 / 3, padding: PADDING, v_align: :bottom, background_nine_slice: NINE_SLICE_ROUNDED_BOTTOM, background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: ALPHA_BLACK, border_thickness_top: 1, border_color_top: Gosu::Color::BLACK) do caption "NEWS", color: 0x88_ffffff, font: FONT_BOLD tagline "A News Item Post A News Item Post", font: FONT_BOLD end @@ -127,9 +128,9 @@ module W3DHubLauncher # self account container flow(width: 1.0, height: 80) do # self avatar container - stack(width: 80, height: 1.0, background_image: safe_get_image("./media/default.png")) do + stack(width: 80, height: 1.0, background_image: rounded_avatar(safe_get_image("./media/default.png"))) do # self online state container - stack(width: 20, height: 20, v_align: :bottom, h_align: :right, background_image: safe_get_image("./media/icons/contrast.png"), background_image_color: 0xff_26a269) + stack(width: 20, height: 20, v_align: :bottom, h_align: :right, background_image: safe_get_image("./media/ui/circle_small.png"), background_image_color: 0xff_26a269) end stack(fill: true, height: 1.0, margin_left: HALF_PADDING) do @@ -152,7 +153,7 @@ module W3DHubLauncher # friend management container flow(width: 1.0, height: 60, margin_top: PADDING) do - flow(width: 1.0) do # FIXME: , v_align: :center + flow(width: 1.0, v_align: :center) do button safe_get_image("./media/icons/singleplayer.png"), image_height: 1.0 button safe_get_image("./media/icons/gear.png"), image_height: 1.0, margin_left: HALF_PADDING edit_line "", margin_left: HALF_PADDING, fill: true, height: 1.0 @@ -160,13 +161,13 @@ module W3DHubLauncher end # friends/clanmates list container - stack(width: 1.0, fill: true, margin_top: PADDING, scroll: true) do + stack(width: 1.0, fill: true, margin_top: LARGE_PADDING, scroll: true) do 50.times do |i| # friend container - flow(width: 1.0, height: 48, margin_bottom: HALF_PADDING, hover: { background: 0x44_000000 }) do + flow(width: 1.0, height: 48, padding_top: HALF_PADDING, padding_bottom: HALF_PADDING, background_nine_slice: NINE_SLICE_ROUNDED, background_nine_slice_color: 0, hover: { background_nine_slice_from_edge: NINE_SLICE_EDGE, background_nine_slice_color: 0x44_000000 }) do # friend avatar container - stack(width: 48, height: 1.0, background_image: safe_get_image("./media/default.png")) do - stack(width: 12, height: 12, v_align: :bottom, h_align: :right, background_image: safe_get_image("./media/icons/contrast.png"), background_image_color: 0xff_26a269) + stack(width: 48, height: 1.0, margin_left: HALF_PADDING, background_image: rounded_avatar(safe_get_image("./media/default.png"))) do + stack(width: 12, height: 12, v_align: :bottom, h_align: :right, background_image: safe_get_image("./media/ui/circle_small.png"), background_image_color: 0xff_26a269) end # friend name and status container stack(fill: true, height: 1.0, margin_left: HALF_PADDING, margin_right: HALF_PADDING) do @@ -176,7 +177,7 @@ module W3DHubLauncher end end # friend active application container - stack(width: 48, height: 1.0, background_image: safe_get_image("./media/logo.png")) + stack(width: 48, height: 1.0, margin_right: HALF_PADDING, background_image: safe_get_image("./media/logo.png")) end end end diff --git a/media/ui/circle.png b/media/ui/circle.png new file mode 100644 index 0000000000000000000000000000000000000000..88e3fa6900a551a55a0461032c81c35330131d31 GIT binary patch literal 2167 zcmV--2#EKIP)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H12n0z) zK~#90?VWqDRbv#ufA`SqrbJ5es3?sJJrK&H>GmGvj~E#;GSkpMnf_oJ(~ub=#hCF& zj2S~xp-3Y|CAsOzsIG?IN~I}ON)H^fnsu7vbRXxj_x|={{bu&mz1_3Vx~+BA_wDtq zM_D?ZCT5fY?SM}DXItPhpasxeuZBQKVkHCE3GvG_$I1wT$ z1|aUbKX4Cl7toY&auE0!m<22ZP7-p$ZU7yCk-$U1g+z;AftkSTKoub+tOn2r|9tw;Hx)M*m1ttJyj{4J!Gsrz%{^hpmPv!76aA;_XQC@2*Lx%FS6W}Ul3R8dBX@IYyf8g zFY6~ibLwW~k8BFx0$%b{Pkt={61#s#WA{es%mIe$adqeo;2hvXJ-jizV~Ive4~5wP z zZ&(ShH@ra}4WA2o6DUE6cZ+>f!*fK5cWXkb?*<@i&o@DySQ&XC#Vp;ln8mjxprNk& zru^_B6;JO2_53t|NqSOcgp;0{Tj|RZP@%;RaY)mSGiiM~Sn8z#h|6E60SF`f{Gh4z zC%sw%#I2a}qk~jNkMYU_Tm^hz=;p$3&QUdl9i@7JDW?2LQm)xVC3%2BdcJQ&7umco zD#ie0x4%-GE*Q~exi-%zcnOdgvnfCN+zi}Oj0gBG##OpWV<9l05Dy^hhABTj^smXA z*JJ=={guaXz_@&ufDYRD$U?sHBCWcWe8O5iz$2#oSRxo7g^?(F zWgCE<`zMbZGJAlO4myzDK1Om7ou8M|uAQd*%MN5sq+ri6a1jL)U(?qKq7|~v10yZ!rUZhpGTeH7eU17*(iwVS% zdAZ6LYN`yH?7uulz)UK1Y}{I)yRRY{L7x2GSlvI=RvS3MKY5IRnNaNP;FXzo3v8{4 zKKV3=khs7r-pOSI#MAj?dFA5)ghs$R^#(@x5s%$1H|$#-`L>Ap3m8?~X2J*!{{oNZ zqkN%|9zn91c(r)BjDVO3EX((Y^IZb6vxX!#aBWed8Gf@uX9DK+=`Y3rgwARNjSCjf z@RR+z?iV!uEmh4cUj3nRW(fy2?k^keqUMOGivRk-x8@ow^5r%(mUj}{e z@al$Mw~Idj^wT^7!}|@NeDe2sc~d{;1<0o4PJKKvysPIM0vy6){2CZ>LZ3}vw1{Cz z$PWE^U>I-=AMolapf)OiX9w3|BfYfGUaV25iDkc;HAjf?T| z@+x)rzCPMT*#I&~(&<=Wcnrqcrh!GeyO-RFP!U!G$Z)9|!DHIoC`#s7hFirOsZC>lU6 ztu#BPmo~HL;$yqpgBq||tr<|2UL|I@A`S*n9c{HVx}E-A_75$A=6aRuveHC^K5v|v)2Fs002ovPDHLkV1lOr@QnZf literal 0 HcmV?d00001 diff --git a/media/ui/circle_small.png b/media/ui/circle_small.png new file mode 100644 index 0000000000000000000000000000000000000000..92a1cee4ffb03bc4aaeadac165fd338f3a8537fb GIT binary patch literal 582 zcmV-M0=fN(P)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10nWKKG>2FyoM0dZPO!N|Bww}$5qN7aHUk#nPJwR1as>=HA6`R?8xMh(&d2tw zm~er1el04t2Yvy485uY?1680iBLmfVAj$*>{LN7Rj~O`3(7=K7WmHz|IA6nM#hRUh zqR-D3nL>x+lJl8qiSR6%c9f3GJ{>;@Bz_HyM4Qmq2WAMzw29xo#R|lNuU^yUtE7Cb zqO=5j2Og#L&rg6Cz;X1!B|6w?nDW(YyEy_TYu<_h{A12%TQp*Q=OjI8G=6du*25yE)sN%AGhirjJ-4K`1#AGTKEO5PAM04< UVfi$j&j0`b07*qoM6N<$f|E!9^#A|> literal 0 HcmV?d00001 diff --git a/media/ui/rounded.png b/media/ui/rounded.png new file mode 100644 index 0000000000000000000000000000000000000000..7916722a34089f80a6e2e08f71c946caef964f8a GIT binary patch literal 430 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5he4R}c>anMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&3=E9co-U3d6?2~6_V!{96mh*c zw>dfB^2NX(jO_~rul&@kE09u?bQ7r$-mu`wsqQIeZzHR}a;+*pzx&GSb2Goxo_A;v ze!z2s-K>%K-*&zV_Gt%H3)pM;Z6#SYaNl97?ulkKWDYybkoCiIL+@ekf(XScr*28Px-~GG6?mwrOn}>y4_W#+y Pux9Xd^>bP0l+XkKcVMgx literal 0 HcmV?d00001 diff --git a/media/ui/rounded_bottom.png b/media/ui/rounded_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..0df06fd37917d20d206c4800f1fd892c98555735 GIT binary patch literal 341 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5he4R}c>anMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Kt+!{T^vIy<~+T6*0aS?fbHR} zLo!FY6IUci%<~DzpWU`P@x{UU5@K#r-;9|YH_W?zKxWzfmox9J-71zSq+UpERIuc= z1!K*{uZE0!E_}6Nw7KwgM|8F?hyMXl-Qdq}Sq!?pA27sR_`ny#oPS%QhBfb*?}z`g z+a57)anMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Kt-=TT^vIy<~+T<+n2>q#OQXo`n;0qhHS!()ejhAn9~oO z>RWsHpO6Jpc*~m0PvaZ7lkQyGSn+e`v*7#x@)`PDBJ2K6PVM=)^?TU&c!uT*&Ly66 zj!=#`YlQh9Os-(aKf+w0lp~ou$Eo68T5B;&T?6}r<^t&&_PoaMCe;HqZ11*x{3-pQ d=Dl(2{<-P$yU#x3Vg`Df!PC{xWt~$(696PCk@5fl literal 0 HcmV?d00001 diff --git a/media/ui/rounded_left_bottom.png b/media/ui/rounded_left_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..20d0891e73396239fc103adfdbebc081f36e4002 GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5he4R}c>anMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Kt)?TT^vIy<~+T+(UUbm!1dry z@#+o2Tloz)I7SQV9(LKl_OWv&Z^yxzIh&sz*fhQPoS<2uusM~{;pG(#{2v+CKVqEM z5_`_lUT|Kaa>kEC%=cRFKahU+L8*eN?);A9%6WyotN%y8e_zXd^q}z5Pj9|U1KrQy M>FVdQ&MBb@08EHwsQ>@~ literal 0 HcmV?d00001 diff --git a/media/ui/rounded_left_top.png b/media/ui/rounded_left_top.png new file mode 100644 index 0000000000000000000000000000000000000000..86134e2444ac71c7194edb4f00c62d9e21233742 GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5he4R}c>anMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Kt+2!T^vIy<~+S>$i?Ky<8X2R zeB0(5m0Y%+y%jF{kLK#Qv2-6iR+RX^+2NF@k>Y8I=FS76I~c_uFsylV!|JK}1I9U= zk;@;=KQK{Z|3?im`}Z}kZvQuX;5Xyx%X*#Up6mDg@9t;gd89o-tx!mvnkesY!`i)! YIu8VbgpUS)0D6SM)78&qol`;+0JpqmwEzGB literal 0 HcmV?d00001 diff --git a/media/ui/rounded_right.png b/media/ui/rounded_right.png new file mode 100644 index 0000000000000000000000000000000000000000..579b2e0250dd7f06cc4e329455dc83ece986c519 GIT binary patch literal 357 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5he4R}c>anMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Kt-QCT^vIy<~+T9+S4UafZ^h- zLvsZsI-3f4(pD%KwLMhl5&g3!md`Fzg58jT_4S*3@9sXjRDN}JYNXh|?YbY>?l3<; zAiBZ+vzEYv<(wPY(8^_r@wRlFK{d>=z9iFS3j3^P6anMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Kt&rpT^vIy<~+TanMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Kt($|T^vIy<~+T6kdrBphvDMQ zmxugvQlh^oG}T75aWt9g)cj=sp1|DnS<9o%VVdEw2m5mmaPMGLf57y{TECIuep-j< zj&Nol{|6Sz9+w#{&NHuwJ8(RTzhEtU#TDk9uM8pk5BNP&p(^_Gm0|xkHm?j_ma=<7 Rtw298c)I$ztaD0e0syanMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Ktezj%WQp2zN-dbu=lycrm%{xItd5hM(+<+WWg$?{;U-%Hi}Y>`Q)=__99w zu_*tJL$YSh`rDW+j_CHi*(P{|tN%7*&%^f{*B|EgbK_Y2X{Pyoqdx@=vjZD0HWImVjb99uez0`*S0?$i)}x+rE!H}yEv>T4V0 hKXvl&Ih+2NyF5VmX#KZydx0Uq;OXk;vd$@?2>^fGm6iYi literal 0 HcmV?d00001 diff --git a/media/ui/square.png b/media/ui/square.png new file mode 100644 index 0000000000000000000000000000000000000000..de4149fc427355eff46731d3788d793d409de4aa GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5he4R}c>anMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Kt(m4E{-7;bDo}aWMnYlX)$Q4 sKW{EsE5KTL+ik`X&pEV1*Bi6tL#mdKI;Vst0J3#n*8l(j literal 0 HcmV?d00001