From ae2c9a745e43a1156405ba84ebf646882a744d71 Mon Sep 17 00:00:00 2001 From: Dmugetsu <168934208+diegolix29@users.noreply.github.com> Date: Wed, 26 Mar 2025 15:50:52 -0600 Subject: [PATCH] Gui: Adding Pause button working, full screen button and labels to buttons on main window gui (#2634) * Adding names to gui buttoms and adjusting spacing. * moving refresh button to last slot. * Changing the implementation to tooltips for hover over them - qstring to detect background color. * Fixing some themes with inverted tooltip base * Suggestions / Fixes - Pause and FullScreen Buttons * Update REUSE.toml * cleaning up * Icons stuff * clang * Buttons toggle - Cleaning code - Fixing Icons * cleaning boolean * Toggle pause and play icons and label to "Resume" when paused. * Simplifying the toggles. * New icons and final Push to review * Reuse * Icon rename, adding f9 press for pause game when no gui is on without needed of debug menu * clang + reuse * clang dosent work on this part * again Clang * Last fix for review. Light theme white resume icon fix. * Proper fix for Resume icon * New Rebase * Fixed Orientation with docking issues and cleaning boxlayout code * Adding spacer to separate actions, sizeslider on top of search bar. And adding margins * Fixed Background not showing on OLED Theme * Fixing check marks * Adding all Daniel Suggestions and fixed F9 not working with debug menu open. * Clang * reverting all OLED theme changes * Final suggestions --- REUSE.toml | 4 +- src/common/config.cpp | 12 +++ src/common/config.h | 2 + src/core/devtools/layer.cpp | 43 +++++--- src/core/devtools/layer.h | 1 + src/images/controller_icon.png | Bin 9102 -> 4142 bytes src/images/fullscreen_icon.png | Bin 0 -> 2590 bytes src/images/pause_icon.png | Bin 965 -> 1972 bytes src/images/play_icon.png | Bin 1150 -> 2875 bytes src/images/refresh_icon.png | Bin 3381 -> 0 bytes src/images/refreshlist_icon.png | Bin 0 -> 3247 bytes src/images/restart_game_icon.png | Bin 0 -> 3935 bytes src/images/settings_icon.png | Bin 2219 -> 4543 bytes src/images/stop_icon.png | Bin 658 -> 1601 bytes src/qt_gui/main_window.cpp | 168 ++++++++++++++++++++++++++++-- src/qt_gui/main_window.h | 12 +++ src/qt_gui/main_window_themes.cpp | 45 ++++---- src/qt_gui/main_window_ui.h | 32 ++++-- src/sdl_window.cpp | 20 ++++ src/sdl_window.h | 2 + src/shadps4.qrc | 74 ++++++------- 21 files changed, 324 insertions(+), 91 deletions(-) create mode 100644 src/images/fullscreen_icon.png delete mode 100644 src/images/refresh_icon.png create mode 100644 src/images/refreshlist_icon.png create mode 100644 src/images/restart_game_icon.png diff --git a/REUSE.toml b/REUSE.toml index 793990bd8..ad2bc3678 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -49,8 +49,10 @@ path = [ "src/images/pause_icon.png", "src/images/play_icon.png", "src/images/ps4_controller.png", - "src/images/refresh_icon.png", + "src/images/restart_game_icon.png", + "src/images/refreshlist_icon.png", "src/images/settings_icon.png", + "src/images/fullscreen_icon.png", "src/images/stop_icon.png", "src/images/utils_icon.png", "src/images/shadPS4.icns", diff --git a/src/common/config.cpp b/src/common/config.cpp index 16d9e5724..09236f30c 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -107,6 +107,7 @@ static bool showBackgroundImage = true; static bool isFullscreen = false; static std::string fullscreenMode = "Windowed"; static bool isHDRAllowed = false; +static bool showLabelsUnderIcons = true; // Language u32 m_language = 1; // english @@ -176,6 +177,14 @@ bool getIsFullscreen() { return isFullscreen; } +bool getShowLabelsUnderIcons() { + return showLabelsUnderIcons; +} + +bool setShowLabelsUnderIcons() { + return false; +} + std::string getFullscreenMode() { return fullscreenMode; } @@ -427,6 +436,9 @@ void setVblankDiv(u32 value) { void setIsFullscreen(bool enable) { isFullscreen = enable; } +static void setShowLabelsUnderIcons(bool enable) { + showLabelsUnderIcons = enable; +} void setFullscreenMode(std::string mode) { fullscreenMode = mode; diff --git a/src/common/config.h b/src/common/config.h index 1025e9956..3a0bf252c 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -26,6 +26,8 @@ bool GetLoadGameSizeEnabled(); std::filesystem::path GetSaveDataPath(); void setLoadGameSizeEnabled(bool enable); bool getIsFullscreen(); +bool getShowLabelsUnderIcons(); +bool setShowLabelsUnderIcons(); std::string getFullscreenMode(); bool isNeoModeConsole(); bool isDevKitConsole(); diff --git a/src/core/devtools/layer.cpp b/src/core/devtools/layer.cpp index 87fd9ffb3..94b39e801 100644 --- a/src/core/devtools/layer.cpp +++ b/src/core/devtools/layer.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "SDL3/SDL_log.h" #include "layer.h" #include @@ -117,22 +118,6 @@ void L::DrawMenuBar() { EndMainMenuBar(); } - - if (IsKeyPressed(ImGuiKey_F9, false)) { - if (io.KeyCtrl && io.KeyAlt) { - if (!DebugState.ShouldPauseInSubmit()) { - DebugState.RequestFrameDump(dump_frame_count); - } - } - if (!io.KeyCtrl && !io.KeyAlt) { - if (isSystemPaused) { - DebugState.ResumeGuestThreads(); - } else { - DebugState.PauseGuestThreads(); - } - } - } - if (open_popup_options) { OpenPopup("GPU Tools Options"); just_opened_options = true; @@ -381,6 +366,32 @@ void L::Draw() { visibility_toggled = true; } + if (IsKeyPressed(ImGuiKey_F9, false)) { + if (io.KeyCtrl && io.KeyAlt) { + if (!DebugState.ShouldPauseInSubmit()) { + DebugState.RequestFrameDump(dump_frame_count); + } + } else { + if (DebugState.IsGuestThreadsPaused()) { + DebugState.ResumeGuestThreads(); + SDL_Log("Game resumed from Keyboard"); + show_pause_status = false; + } else { + DebugState.PauseGuestThreads(); + SDL_Log("Game paused from Keyboard"); + show_pause_status = true; + } + visibility_toggled = true; + } + } + + if (show_pause_status) { + ImVec2 pos = ImVec2(10, 10); + ImU32 color = IM_COL32(255, 255, 255, 255); + + ImGui::GetForegroundDrawList()->AddText(pos, color, "Game Paused Press F9 to Resume"); + } + if (show_simple_fps) { if (Begin("Video Info", nullptr, ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoDecoration | diff --git a/src/core/devtools/layer.h b/src/core/devtools/layer.h index 5bb53fbdb..9e949c8e9 100644 --- a/src/core/devtools/layer.h +++ b/src/core/devtools/layer.h @@ -19,6 +19,7 @@ public: static void SetupSettings(); void Draw() override; + bool show_pause_status = false; }; } // namespace Core::Devtools diff --git a/src/images/controller_icon.png b/src/images/controller_icon.png index 40c92a89bc53a9447d223c3c45286afe3b3d1673..0d5556329e55f8b1854821536a58a1ecd4d4528b 100644 GIT binary patch literal 4142 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 UN}CF^{5$l5tgc(4fqtp~1!=YDDgXcg literal 9102 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 DoToWu diff --git a/src/images/fullscreen_icon.png b/src/images/fullscreen_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..719ffe4a19b842f711a4cd6be61fcbfb668b6ef1 GIT binary patch literal 2590 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 literal 0 HcmV?d00001 diff --git a/src/images/pause_icon.png b/src/images/pause_icon.png index 5375689b7880bb46d843eca0f8494e66bee69f19..86bbc6acbd15eecfa96376cfe90511a7be46387d 100644 GIT binary patch literal 1972 zcmdT_i!arfy{iVAzJ9Gbo`tMNHA#@h>IfA7M$xv8To!iOS+ z!uBEnXs6+WaHM18#mo5Cow10st?dRo|D_QOsqwN!1e@q@-_j~Y7?#6qD};vME15Pv z(U|W@K^UBosebu>(?`bl49=V?w=HGt;NW_cMJ+i6_crQ@-wqeGY$TqDRFw)lCtBX~ zR-ZQ$3+PYG-}J4~cs!d7sm0td?I($U?R3sshp$b6G-u9=L8@n!P(%_Efm0xNq)8;9 z_0IAofiHTs*LrT1*0mYCWnVZ`yvE;**s2@xP!YWk?bvKgN$F=d;Injx$1aq9I4gy6}J(8 z`xSOLdBty+xCTAIoUyF!u!C>d9+=0XtmEBHmFI_5va!dr5~Ou&QD2$PHv`eNZ-Y~p zpN+C9f?{8XLsHZBT~8;tC?AD1r2R^D?pK5*=7aeIIO>5Q7sbptUeEq1)1hT7& z=Vs?@I3x*M(H%G^piVk5>zdC|P&cw)C4EsE;hq;k+1?pcTcp(MKJvibGsk#UOi4-K z<5}xToD55I8~B|(bm{%^S8!R|@%G9Ho#*cHCSP)cUnTK8UJ$aHkOz|`>}6d|re9jK zMM;A2deITR(nQqlwk9vWK8pZVq+hk_W$q7fsgpfFy_C^7vLGT?wQrv3EKgWB}q zfZe=4&c!kRNcK7U>s#y}VkWuEW<_-h!n)rTamnb7&fiPE_8Qew&AfBatE@0%^-l#x z$)mZ)MYJbzKF!p7;f#zO+C`?YSiiwI0=K7O27$sz}M(aUznWS^rI^g z_$#AppVG~K)b8S3u~YeH^giqUpj<>3 z@$5z$_g&Pal_hb%gx)0zYj}B8#V*#ISWIN`u0X|af*hF-1^vOkz<)vOBa7kLV`-Jf zIYBrpeCZ0u^A}AnJsbB%F$Vi;n;H)FJF`0SPUe&J`V_vJnN#7N3mzG>Fx4&w%N2_u z3t1Z!hnG&X(_-8tdIPFh_oppJMZ`)yl=h5kC@36hV1_DuB4cMs^0gSyz2;jiiY2W?XKr*L~&n`rOg yq4X_mcVRF$pQf;`3y&P1L&}yT-L$My4=tU-d1msLTBv`w>9f#KDkjb=i$8av~#YX{;OV|SJ{5L_TAEltb!0QbM7;y zxd$W{u}{pdTEZO}P* z=XB%hfAdnG|Kpj%CUzky_kag0|CjGy1vAzczRNw3!CSna!R(UK>%aW#0xy4Eyi7cG zy8Z5TJMDkOUs>|(>X&mFe;&`>wCK>zaK`yUXKd&EDt_wH)SmU@by{ojeJ_jehC)@r z1}9hyICxAdZ5fVnpPS7zEzF?!o9n~ygSE&0>YP1iYjIY*DO_dK)`Skl`K=M%jn%Br zZkAFq2JMXPm#^KX2PV@1u2pis@n4=i3V-r0m>{- zIU2ml$!l8Uq|^sf)>L?fd7Lx~*u*nulBoYlF3m_bpiJW z`Re&gZ|-bg7FqdaQcIsWPte!W#fNrQ3!kf;YA{&@cD64BQY zxBmzo-6i+Rdc)?nowu{&bS$6Qzlcs^{;;L3y^22vnA~Llv4?-Xqg=?&+KN6{`R67{1=U l`|swmAL-)I{E#;Lew559d%-E~fxvvp;OXk;vd$@?2>?c3y|VxS diff --git a/src/images/play_icon.png b/src/images/play_icon.png index 2815be39d8594b213fad22e68c7e8ac16872d639..d50d404b79bc4b5f5e7122e2f30cb5663ad3c4ad 100644 GIT binary patch delta 2848 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 LNkvXXu0mjf_p(8M diff --git a/src/images/refreshlist_icon.png b/src/images/refreshlist_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7de6685b27e195b1517d5058f11e48b079f4ee08 GIT binary patch literal 3247 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 literal 0 HcmV?d00001 diff --git a/src/images/restart_game_icon.png b/src/images/restart_game_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1e549e10192135af9d1ba30522c3a405521a2259 GIT binary patch literal 3935 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 literal 0 HcmV?d00001 diff --git a/src/images/settings_icon.png b/src/images/settings_icon.png index c88cd7a6f16cbc54bbb44730d3dac206f3affe2b..81127bfa3e7856ac86bb645a79a905c4324d42b3 100644 GIT binary patch literal 4543 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 r0w|%4^SL>bXBXW&WwtaSTv9Aq5DDXYMx@8o?^} delta 2190 zcmV;92yyqnBdZaRB#}WBe+XSkL_t(|ob8=iY*s}S$N&8*%3j290Dc3|W|=7O4ghZe7#K#!ju8O z9tID6bEfxd6Zb zq?{Q5&gL}uJa0#DG0cBGfCfe9H3R5pArqC^B5a-e8PH;3xIb3Ob0NTU;SJ>j>Fk+olx`@8bA&P9ZeTc^A_|7fJ^+pfATu91i;;VQcnunf7af^&Jo|TEZG4#!m>W2IR8AQ z>4R|zwgaCFf_#d?VY|=|JChPZvN4<~FvHJ40DlYpL2tZwz7hm@9)-sXLVtYWyYjn) z%8vr*jAZBmU@F^9-s7`S75_|jjwuNq(mD(JH%b$HR=!%O_(`7?11JVClh>$AhC8EL z0Of-If6Nuq0#CLbFLV{=OWJ#P@_Yb2Y`8^L**-|E?~6{tne3D!O@pzWo6>7OD#U+| z3Y%jLMEkUf4~9N?U8vWK{eFj{GSZ?B_E6toR*kngP6t^#?V2HiM%l*ntmTZ*NK)Dj zbvzi29tI ziykiLEH-TDGTsr{vRPApGwX`RD0WX7w%}C?rrT^H{gf?Naa&FLd|$muI3r6~&sZ?JmnHrbJ^CKWOpr zf4pMQ{wD6LMCikZE=eFdybX&`=1k3-5of+H(Yz^9)cqq24yLt^4QocwYxo?13xZ%Z z4m=E-BTiE)ZWX3m>OfPZ2k`>;Ns=an|8cLd%bczDg`x*iSBEtaMn1@ zeUS?02u}^|&U8!_@{e&S=QyFB`(v&he~%+&s18PSgVxsDy~(j+FeCVnks4jcE=69l zHl~gjg;TMP6$x71b}8ywZje{CyQBvyb*Nl|$iG*|21VYr9^_Q5BXq9NabA)4AzVfS zLJrBc15%lww@jP?p|+=vFlD8TeTt`t)b=_m6nT%QY*F8-$V(fVRPjVi70MJLfB#sA za*mI=?S0wtWg;(37HlOgh6ls$f@kAehqA60PT1WH?H;Ow;Ti6Wyy04PQY#Fq=?yH2 zQG)6uikzRMQFUUXT%;%d<_Kk$3uV0dDrtw2 zo0h~h;chZ$WF;#KRVLi=ynyQ-9`bgyrI@|u^Jc;|adL36_3O!2Jd=i=VBJ*K$$_S| z-wpHDJGu~*Hzx<38xU;?T`@@GFB>;CIKDNT7dN1~gdODu8O;ASsov8Sf9Av;6r(*%}<{ zL)B=Cg5Z-3dxz8-ULd`|C-4~wTt`@#kLw7!>ue1PUfAi*%D@V?^ljj@oVB+18S187 z&_&~iOj~fTd?{3JqQbt?e^?~+2WbfMdL_CLFMXaC`h%_jCc+*;h;S_$#@;s0n4nou zJ6hl=P}sA)&^F|#HBPa$aTzP)d@sPcP+gO_?tM8|_F7oR8kV_V#DzTZzyZ)G*K$K^ zjOMe%#Ryx}@&x2BkFb?)A6nx!O=u0e9Gf`T8U&x&YuMn9(w3Mue-ITVF$4YUg3mPO zEBFl9AF0h_I$#-RQAPg<0cUKJO<+x@m|R?mllHNeATHfF>YGnleK_`69nyR^^aGE< znO#0ONgYOw_T#3PEf4c|qRM!OGoROsW+6{2$KA4JtU(aWEgX$v63g~>#2}ahF1IkT zyLo<9ZEHtrI)D~pe_LuihlzE0Wx{J9<#Vi%9FfvM%12`cQvN5+ft0h{0AL=ZRH{0STY0$P*Qc0il??Q8}O}s}M~E z*343LB7MFnD%nV*?bD+kt3LiUK(dU>D80m@ya|b3SmN zI<4&GOmF_00R=98m7Nn-a#+C4{PQyY+XDVy$`c3#0)apv5C{YU0d&m2p@aE8r}ynE Q00000NkvXX1g=70f&tk8-T(jq diff --git a/src/images/stop_icon.png b/src/images/stop_icon.png index 74c615f65a54bd8380a3e67f689d86038019edc6..55b6b01c7c4c20ce586a0145ccbbfe7db38cfc43 100644 GIT binary patch literal 1601 zcmeAS@N?(olHy`uVBq!ia0vp^DImQL70(Y)*K0-phSslL`iUdT1k0gQ7S_~VrE{6o}X)of~lUN zo@wfhX`(y)37&w3&Rt70XRt82O%L|C5p=^+AG#Ht|;!HrcAtMum0FaIX z;>>myuy_`b4FaB$j0`WB5j2{m3_z&~>vp@3Xlx~Oh9v) zz$$|*Er2YjE<*zYknFd0hqp*vSLz3b#0O6o$B>G+w{yK$gr-Wgm4|PheXBJNS zg{G8*|NsAAllt+s$544k!o%~PJALkHT|a61 zNyzf;`(OJD{QfDQKQXz;@1Lf6(j+CJLt&N6_xRpZSU*AgiR+~=RsT=!f3p75mN`@B zpEx{eeg9Hlh47PSi@NWqy`RLAc+A=0_|w~;oPWMNbbVRc(i)F_`jL~$s_suVo;1tv z=+RHCKc}9lZI~OA^>fdXZINEp_L_FO@)ONJvToK{GtK;T_ESSoVFR&qJlj_4r|PBd zE_tqc`})+PhC2)E`fCF1CcHc5oc(?KljdEweudS4_g1}|A#D*{c6#y4yvB!2pH9n7 z)?d2YXiI_p$@eP1AD#acfAgt>h4{K@IiA-~hE8&C3bfJuesY(poZf@7pF8&G-+lV< z@ck+Jr}}Pblq*a^)#z1|HQ95I}0BA-%zNO4QeuO z&VAKgl77o!x!2hhv7A|cZ-vh~Tsw98_w-1M1D3{7U(cyIem|)_`TgZsxj5&Klguvi zw6ssXlx*wWm)FI7$A`^yaoJMy{a60X`u8+JK_%2`MP}yoFF|V_2Uus#Xr6VQzvHY! zMQ>16tYyuM4QEP1`q?a3RQ}~!E$Q)+U2E6BIU7ZeU0t`X)>uH8fnA7asG*)Tg|+|L z>x~W9s{5NTOPW7Ev^ulu*x9s|>f)x|e`f2Pot|WNf05zBWu{lwnM{~5>-y#HS&e@b z{=bOVYucE{qp9a-Y33Rs3zVERb=LnI`(=2ZO!>37e&*AvlPunCYO~4$R_jg*T%&qp z=DxS_d~8PQ{@?XC8{D2+xadrk>DwKyLB?6(O|yc3yBG^hJNJB(NpG*??lWbz5k?0u zX)op3dQ(NRd7tyNHWA~hsk5#te{EyGWBm4qn`M^h9ev4`6B}H%Svt9%6R(R8Uz_D1 z@%_~DCwi7${ZFEc%$vlIy9a8|m_x5Hj%{^aAA?sB}CnXb}Y`cq-|pL5>l z#Fnk*J8;jO=XATlkF;s`vofdkuYdabljzPDhRWg`1#$%s3Qky0dD{H>Tjts>q)s;Pb7n*6h+re$$!H6bLNxZl}X=?J*+FvB`m+GA3yobV*S1I zynHT+UObdLwfw|w)ybbM(>-K3yX!e)TdY1Eo7N{>DSJrRg1=VYyKKg;t+GeAzDXp00i_>zopr E0K^za>cWLdxmJqeaYUez~9^NjLra`DY8Sp;&0&QkN;qmtC9m^~iQ58_A_Neb2c6`26F&neh9wX8V@~tzW;(G}W2c zV$IJF8*WT}W%zvk+R3x{_4QmgG&`1`Hd{(ZYX zo~-abb2xIc_?6j@PP7%qypfAClUr`HE-8-JdPYH@YJY9&fr;+FOpnE$JACjEW5gWi zrSB!eE%{l08wvAA&-oIU`?=!$*IBc+T$q1+es!qgW6giFvT7LrzZTvs^#5YJ`tvQR mi{; #include #include @@ -132,23 +134,160 @@ void MainWindow::CreateActions() { m_theme_act_group->addAction(ui->setThemeOled); } +void MainWindow::PauseGame() { + SDL_Event event; + SDL_memset(&event, 0, sizeof(event)); + event.type = SDL_EVENT_TOGGLE_PAUSE; + is_paused = !is_paused; + UpdateToolbarButtons(); + SDL_PushEvent(&event); +} + +void MainWindow::toggleLabelsUnderIcons() { + bool showLabels = ui->toggleLabelsAct->isChecked(); + Config::setShowLabelsUnderIcons(); + UpdateToolbarLabels(); + if (isGameRunning) { + UpdateToolbarButtons(); + } +} + +void MainWindow::toggleFullscreen() { + SDL_Event event; + SDL_memset(&event, 0, sizeof(event)); + event.type = SDL_EVENT_TOGGLE_FULLSCREEN; + SDL_PushEvent(&event); +} + +QWidget* MainWindow::createButtonWithLabel(QPushButton* button, const QString& labelText, + bool showLabel) { + QWidget* container = new QWidget(this); + QVBoxLayout* layout = new QVBoxLayout(container); + layout->setAlignment(Qt::AlignCenter | Qt::AlignBottom); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(button); + + QLabel* label = nullptr; + if (showLabel && ui->toggleLabelsAct->isChecked()) { + label = new QLabel(labelText, this); + label->setAlignment(Qt::AlignCenter | Qt::AlignBottom); + layout->addWidget(label); + button->setToolTip(""); + } else { + button->setToolTip(labelText); + } + + container->setLayout(layout); + container->setProperty("buttonLabel", QVariant::fromValue(label)); + return container; +} + +QWidget* createSpacer(QWidget* parent) { + QWidget* spacer = new QWidget(parent); + spacer->setFixedWidth(15); + spacer->setFixedHeight(15); + return spacer; +} + void MainWindow::AddUiWidgets() { // add toolbar widgets QApplication::setStyle("Fusion"); - ui->toolBar->setObjectName("mw_toolbar"); - ui->toolBar->addWidget(ui->playButton); - ui->toolBar->addWidget(ui->pauseButton); - ui->toolBar->addWidget(ui->stopButton); - ui->toolBar->addWidget(ui->refreshButton); - ui->toolBar->addWidget(ui->settingsButton); - ui->toolBar->addWidget(ui->controllerButton); - ui->toolBar->addWidget(ui->keyboardButton); + + bool showLabels = ui->toggleLabelsAct->isChecked(); + ui->toolBar->clear(); + + ui->toolBar->addWidget(createSpacer(this)); + ui->toolBar->addWidget(createButtonWithLabel(ui->playButton, tr("Play"), showLabels)); + ui->toolBar->addWidget(createButtonWithLabel(ui->pauseButton, tr("Pause"), showLabels)); + ui->toolBar->addWidget(createButtonWithLabel(ui->stopButton, tr("Stop"), showLabels)); + ui->toolBar->addWidget(createButtonWithLabel(ui->restartButton, tr("Restart"), showLabels)); + ui->toolBar->addWidget(createSpacer(this)); + ui->toolBar->addWidget(createButtonWithLabel(ui->settingsButton, tr("Settings"), showLabels)); + ui->toolBar->addWidget( + createButtonWithLabel(ui->fullscreenButton, tr("Full Screen"), showLabels)); + ui->toolBar->addWidget(createSpacer(this)); + ui->toolBar->addWidget( + createButtonWithLabel(ui->controllerButton, tr("Controllers"), showLabels)); + ui->toolBar->addWidget(createButtonWithLabel(ui->keyboardButton, tr("Keyboard"), showLabels)); + ui->toolBar->addWidget(createSpacer(this)); QFrame* line = new QFrame(this); - line->setFrameShape(QFrame::StyledPanel); + line->setFrameShape(QFrame::VLine); line->setFrameShadow(QFrame::Sunken); + line->setMinimumWidth(2); ui->toolBar->addWidget(line); - ui->toolBar->addWidget(ui->sizeSliderContainer); - ui->toolBar->addWidget(ui->mw_searchbar); + ui->toolBar->addWidget(createSpacer(this)); + if (showLabels) { + QLabel* pauseButtonLabel = ui->pauseButton->parentWidget()->findChild(); + if (pauseButtonLabel) { + pauseButtonLabel->setVisible(false); + } + } + ui->toolBar->addWidget( + createButtonWithLabel(ui->refreshButton, tr("Refresh List"), showLabels)); + ui->toolBar->addWidget(createSpacer(this)); + + QBoxLayout* toolbarLayout = new QBoxLayout(QBoxLayout::TopToBottom); + toolbarLayout->setSpacing(2); + toolbarLayout->setContentsMargins(2, 2, 2, 2); + ui->sizeSliderContainer->setFixedWidth(150); + + QWidget* searchSliderContainer = new QWidget(this); + QBoxLayout* searchSliderLayout = new QBoxLayout(QBoxLayout::TopToBottom); + searchSliderLayout->setContentsMargins(0, 0, 6, 6); + searchSliderLayout->setSpacing(2); + ui->mw_searchbar->setFixedWidth(150); + + searchSliderLayout->addWidget(ui->sizeSliderContainer); + searchSliderLayout->addWidget(ui->mw_searchbar); + + searchSliderContainer->setLayout(searchSliderLayout); + + ui->toolBar->addWidget(searchSliderContainer); + + if (!showLabels) { + toolbarLayout->addWidget(searchSliderContainer); + } + + ui->playButton->setVisible(true); + ui->pauseButton->setVisible(false); +} + +void MainWindow::UpdateToolbarButtons() { + // add toolbar widgets when game is running + bool showLabels = ui->toggleLabelsAct->isChecked(); + + ui->playButton->setVisible(false); + ui->pauseButton->setVisible(true); + + if (showLabels) { + QLabel* playButtonLabel = ui->playButton->parentWidget()->findChild(); + if (playButtonLabel) + playButtonLabel->setVisible(false); + } + + if (is_paused) { + ui->pauseButton->setIcon(ui->playButton->icon()); + ui->pauseButton->setToolTip(tr("Resume")); + } else { + if (isIconBlack) { + ui->pauseButton->setIcon(QIcon(":images/pause_icon.png")); + } else { + ui->pauseButton->setIcon(RecolorIcon(QIcon(":images/pause_icon.png"), isWhite)); + } + ui->pauseButton->setToolTip(tr("Pause")); + } + + if (showLabels) { + QLabel* pauseButtonLabel = ui->pauseButton->parentWidget()->findChild(); + if (pauseButtonLabel) { + pauseButtonLabel->setText(is_paused ? tr("Resume") : tr("Pause")); + pauseButtonLabel->setVisible(true); + } + } +} + +void MainWindow::UpdateToolbarLabels() { + AddUiWidgets(); } void MainWindow::CreateDockWindows() { @@ -253,6 +392,8 @@ void MainWindow::CreateConnects() { connect(ui->refreshButton, &QPushButton::clicked, this, &MainWindow::RefreshGameTable); connect(ui->showGameListAct, &QAction::triggered, this, &MainWindow::ShowGameList); connect(this, &MainWindow::ExtractionFinished, this, &MainWindow::RefreshGameTable); + connect(ui->toggleLabelsAct, &QAction::toggled, this, &MainWindow::toggleLabelsUnderIcons); + connect(ui->fullscreenButton, &QPushButton::clicked, this, &MainWindow::toggleFullscreen); connect(ui->sizeSlider, &QSlider::valueChanged, this, [this](int value) { if (isTableList) { @@ -276,6 +417,7 @@ void MainWindow::CreateConnects() { }); connect(ui->playButton, &QPushButton::clicked, this, &MainWindow::StartGame); + connect(ui->pauseButton, &QPushButton::clicked, this, &MainWindow::PauseGame); connect(m_game_grid_frame.get(), &QTableWidget::cellDoubleClicked, this, &MainWindow::StartGame); connect(m_game_list_frame.get(), &QTableWidget::cellDoubleClicked, this, @@ -743,6 +885,8 @@ void MainWindow::StartGame() { return; } StartEmulator(path); + + UpdateToolbarButtons(); } } @@ -1217,7 +1361,9 @@ void MainWindow::SetUiIcons(bool isWhite) { ui->pauseButton->setIcon(RecolorIcon(ui->pauseButton->icon(), isWhite)); ui->stopButton->setIcon(RecolorIcon(ui->stopButton->icon(), isWhite)); ui->refreshButton->setIcon(RecolorIcon(ui->refreshButton->icon(), isWhite)); + ui->restartButton->setIcon(RecolorIcon(ui->restartButton->icon(), isWhite)); ui->settingsButton->setIcon(RecolorIcon(ui->settingsButton->icon(), isWhite)); + ui->fullscreenButton->setIcon(RecolorIcon(ui->fullscreenButton->icon(), isWhite)); ui->controllerButton->setIcon(RecolorIcon(ui->controllerButton->icon(), isWhite)); ui->keyboardButton->setIcon(RecolorIcon(ui->keyboardButton->icon(), isWhite)); ui->refreshGameListAct->setIcon(RecolorIcon(ui->refreshGameListAct->icon(), isWhite)); diff --git a/src/qt_gui/main_window.h b/src/qt_gui/main_window.h index 5ac56e44c..bcd5e53ba 100644 --- a/src/qt_gui/main_window.h +++ b/src/qt_gui/main_window.h @@ -5,6 +5,7 @@ #include #include +#include #include #include "background_music_player.h" @@ -38,6 +39,8 @@ public: void InstallDragDropPkg(std::filesystem::path file, int pkgNum, int nPkg); void InstallDirectory(); void StartGame(); + void PauseGame(); + bool showLabels; private Q_SLOTS: void ConfigureGuiFromSettings(); @@ -47,15 +50,21 @@ private Q_SLOTS: void RefreshGameTable(); void HandleResize(QResizeEvent* event); void OnLanguageChanged(const std::string& locale); + void toggleLabelsUnderIcons(); private: Ui_MainWindow* ui; void AddUiWidgets(); + void UpdateToolbarLabels(); + void UpdateToolbarButtons(); + QWidget* createButtonWithLabel(QPushButton* button, const QString& labelText, bool showLabel); void CreateActions(); + void toggleFullscreen(); void CreateRecentGameActions(); void CreateDockWindows(); void GetPhysicalDevices(); void LoadGameLists(); + #ifdef ENABLE_UPDATER void CheckUpdateMain(bool checkSave); #endif @@ -73,6 +82,9 @@ private: bool isIconBlack = false; bool isTableList = true; bool isGameRunning = false; + bool isWhite = false; + bool is_paused = false; + QActionGroup* m_icon_size_act_group = nullptr; QActionGroup* m_list_mode_act_group = nullptr; QActionGroup* m_theme_act_group = nullptr; diff --git a/src/qt_gui/main_window_themes.cpp b/src/qt_gui/main_window_themes.cpp index c5574fca9..624673cba 100644 --- a/src/qt_gui/main_window_themes.cpp +++ b/src/qt_gui/main_window_themes.cpp @@ -19,7 +19,7 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) { themePalette.setColor(QPalette::WindowText, Qt::white); themePalette.setColor(QPalette::Base, QColor(20, 20, 20)); themePalette.setColor(QPalette::AlternateBase, QColor(53, 53, 53)); - themePalette.setColor(QPalette::ToolTipBase, Qt::white); + themePalette.setColor(QPalette::ToolTipBase, QColor(20, 20, 20)); themePalette.setColor(QPalette::ToolTipText, Qt::white); themePalette.setColor(QPalette::Text, Qt::white); themePalette.setColor(QPalette::Button, QColor(53, 53, 53)); @@ -37,18 +37,18 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) { "border-radius: 4px; padding: 5px; }" "QLineEdit:focus {" "border: 1px solid #2A82DA; }"); - themePalette.setColor(QPalette::Window, QColor(240, 240, 240)); // Light gray - themePalette.setColor(QPalette::WindowText, Qt::black); // Black - themePalette.setColor(QPalette::Base, QColor(230, 230, 230, 80)); // Grayish - themePalette.setColor(QPalette::ToolTipBase, Qt::black); // Black - themePalette.setColor(QPalette::ToolTipText, Qt::black); // Black - themePalette.setColor(QPalette::Text, Qt::black); // Black - themePalette.setColor(QPalette::Button, QColor(240, 240, 240)); // Light gray - themePalette.setColor(QPalette::ButtonText, Qt::black); // Black - themePalette.setColor(QPalette::BrightText, Qt::red); // Red - themePalette.setColor(QPalette::Link, QColor(42, 130, 218)); // Blue - themePalette.setColor(QPalette::Highlight, QColor(42, 130, 218)); // Blue - themePalette.setColor(QPalette::HighlightedText, Qt::white); // White + themePalette.setColor(QPalette::Window, QColor(240, 240, 240)); // Light gray + themePalette.setColor(QPalette::WindowText, Qt::black); // Black + themePalette.setColor(QPalette::Base, QColor(230, 230, 230, 80)); // Grayish + themePalette.setColor(QPalette::ToolTipBase, QColor(230, 230, 230, 80)); // Grayish + themePalette.setColor(QPalette::ToolTipText, Qt::black); // Black + themePalette.setColor(QPalette::Text, Qt::black); // Black + themePalette.setColor(QPalette::Button, QColor(240, 240, 240)); // Light gray + themePalette.setColor(QPalette::ButtonText, Qt::black); // Black + themePalette.setColor(QPalette::BrightText, Qt::red); // Red + themePalette.setColor(QPalette::Link, QColor(42, 130, 218)); // Blue + themePalette.setColor(QPalette::Highlight, QColor(42, 130, 218)); // Blue + themePalette.setColor(QPalette::HighlightedText, Qt::white); // White qApp->setPalette(themePalette); break; case Theme::Green: @@ -62,8 +62,9 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) { themePalette.setColor(QPalette::WindowText, Qt::white); // White text themePalette.setColor(QPalette::Base, QColor(25, 40, 25)); // Darker green base themePalette.setColor(QPalette::AlternateBase, - QColor(53, 69, 53)); // Dark green alternate base - themePalette.setColor(QPalette::ToolTipBase, Qt::white); // White tooltip background + QColor(53, 69, 53)); // Dark green alternate base + themePalette.setColor(QPalette::ToolTipBase, + QColor(25, 40, 25)); // White tooltip background themePalette.setColor(QPalette::ToolTipText, Qt::white); // White tooltip text themePalette.setColor(QPalette::Text, Qt::white); // White text themePalette.setColor(QPalette::Button, QColor(53, 69, 53)); // Dark green button @@ -85,8 +86,9 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) { themePalette.setColor(QPalette::WindowText, Qt::white); // White text themePalette.setColor(QPalette::Base, QColor(20, 40, 60)); // Darker blue base themePalette.setColor(QPalette::AlternateBase, - QColor(40, 60, 90)); // Dark blue alternate base - themePalette.setColor(QPalette::ToolTipBase, Qt::white); // White tooltip background + QColor(40, 60, 90)); // Dark blue alternate base + themePalette.setColor(QPalette::ToolTipBase, + QColor(20, 40, 60)); // White tooltip background themePalette.setColor(QPalette::ToolTipText, Qt::white); // White tooltip text themePalette.setColor(QPalette::Text, Qt::white); // White text themePalette.setColor(QPalette::Button, QColor(40, 60, 90)); // Dark blue button @@ -109,8 +111,9 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) { themePalette.setColor(QPalette::WindowText, Qt::white); // White text themePalette.setColor(QPalette::Base, QColor(80, 30, 90)); // Darker violet base themePalette.setColor(QPalette::AlternateBase, - QColor(100, 50, 120)); // Violet alternate base - themePalette.setColor(QPalette::ToolTipBase, Qt::white); // White tooltip background + QColor(100, 50, 120)); // Violet alternate base + themePalette.setColor(QPalette::ToolTipBase, + QColor(80, 30, 90)); // White tooltip background themePalette.setColor(QPalette::ToolTipText, Qt::white); // White tooltip text themePalette.setColor(QPalette::Text, Qt::white); // White text themePalette.setColor(QPalette::Button, QColor(100, 50, 120)); // Violet button @@ -133,7 +136,7 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) { themePalette.setColor(QPalette::WindowText, QColor(249, 245, 215)); themePalette.setColor(QPalette::Base, QColor(29, 32, 33)); themePalette.setColor(QPalette::AlternateBase, QColor(50, 48, 47)); - themePalette.setColor(QPalette::ToolTipBase, QColor(249, 245, 215)); + themePalette.setColor(QPalette::ToolTipBase, QColor(29, 32, 33)); themePalette.setColor(QPalette::ToolTipText, QColor(249, 245, 215)); themePalette.setColor(QPalette::Text, QColor(249, 245, 215)); themePalette.setColor(QPalette::Button, QColor(40, 40, 40)); @@ -155,7 +158,7 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) { themePalette.setColor(QPalette::WindowText, QColor(192, 202, 245)); themePalette.setColor(QPalette::Base, QColor(25, 28, 39)); themePalette.setColor(QPalette::AlternateBase, QColor(36, 40, 59)); - themePalette.setColor(QPalette::ToolTipBase, QColor(192, 202, 245)); + themePalette.setColor(QPalette::ToolTipBase, QColor(25, 28, 39)); themePalette.setColor(QPalette::ToolTipText, QColor(192, 202, 245)); themePalette.setColor(QPalette::Text, QColor(192, 202, 245)); themePalette.setColor(QPalette::Button, QColor(30, 30, 41)); diff --git a/src/qt_gui/main_window_ui.h b/src/qt_gui/main_window_ui.h index 246c2afd6..c4f47b636 100644 --- a/src/qt_gui/main_window_ui.h +++ b/src/qt_gui/main_window_ui.h @@ -20,6 +20,7 @@ public: QAction* setIconSizeSmallAct; QAction* setIconSizeMediumAct; QAction* setIconSizeLargeAct; + QAction* toggleLabelsAct; QAction* setlistModeListAct; QAction* setlistModeGridAct; QAction* setlistElfAct; @@ -50,6 +51,8 @@ public: QPushButton* settingsButton; QPushButton* controllerButton; QPushButton* keyboardButton; + QPushButton* fullscreenButton; + QPushButton* restartButton; QWidget* sizeSliderContainer; QHBoxLayout* sizeSliderContainer_layout; @@ -104,7 +107,15 @@ public: showGameListAct->setCheckable(true); refreshGameListAct = new QAction(MainWindow); refreshGameListAct->setObjectName("refreshGameListAct"); - refreshGameListAct->setIcon(QIcon(":images/refresh_icon.png")); + refreshGameListAct->setIcon(QIcon(":images/refreshlist_icon.png")); + + toggleLabelsAct = new QAction(MainWindow); + toggleLabelsAct->setObjectName("toggleLabelsAct"); + toggleLabelsAct->setText( + QCoreApplication::translate("MainWindow", "Show Labels Under Icons")); + toggleLabelsAct->setCheckable(true); + toggleLabelsAct->setChecked(Config::getShowLabelsUnderIcons()); + setIconSizeTinyAct = new QAction(MainWindow); setIconSizeTinyAct->setObjectName("setIconSizeTinyAct"); setIconSizeTinyAct->setCheckable(true); @@ -210,20 +221,28 @@ public: stopButton->setIconSize(QSize(40, 40)); refreshButton = new QPushButton(centralWidget); refreshButton->setFlat(true); - refreshButton->setIcon(QIcon(":images/refresh_icon.png")); - refreshButton->setIconSize(QSize(32, 32)); + refreshButton->setIcon(QIcon(":images/refreshlist_icon.png")); + refreshButton->setIconSize(QSize(40, 40)); + fullscreenButton = new QPushButton(centralWidget); + fullscreenButton->setFlat(true); + fullscreenButton->setIcon(QIcon(":images/fullscreen_icon.png")); + fullscreenButton->setIconSize(QSize(38, 38)); settingsButton = new QPushButton(centralWidget); settingsButton->setFlat(true); settingsButton->setIcon(QIcon(":images/settings_icon.png")); - settingsButton->setIconSize(QSize(44, 44)); + settingsButton->setIconSize(QSize(40, 40)); controllerButton = new QPushButton(centralWidget); controllerButton->setFlat(true); controllerButton->setIcon(QIcon(":images/controller_icon.png")); - controllerButton->setIconSize(QSize(40, 40)); + controllerButton->setIconSize(QSize(55, 48)); keyboardButton = new QPushButton(centralWidget); keyboardButton->setFlat(true); keyboardButton->setIcon(QIcon(":images/keyboard_icon.png")); - keyboardButton->setIconSize(QSize(48, 44)); + keyboardButton->setIconSize(QSize(50, 50)); + restartButton = new QPushButton(centralWidget); + restartButton->setFlat(true); + restartButton->setIcon(QIcon(":images/restart_game_icon.png")); + restartButton->setIconSize(QSize(40, 40)); sizeSliderContainer = new QWidget(centralWidget); sizeSliderContainer->setObjectName("sizeSliderContainer"); @@ -304,6 +323,7 @@ public: menuView->addAction(refreshGameListAct); menuView->addAction(menuGame_List_Mode->menuAction()); menuView->addAction(menuGame_List_Icons->menuAction()); + menuView->addAction(toggleLabelsAct); menuView->addAction(menuThemes->menuAction()); menuThemes->addAction(setThemeDark); menuThemes->addAction(setThemeLight); diff --git a/src/sdl_window.cpp b/src/sdl_window.cpp index 80d196147..fcdde7240 100644 --- a/src/sdl_window.cpp +++ b/src/sdl_window.cpp @@ -11,6 +11,7 @@ #include "common/config.h" #include "common/elf_info.h" #include "common/version.h" +#include "core/debug_state.h" #include "core/libraries/kernel/time.h" #include "core/libraries/pad/pad.h" #include "imgui/renderer/imgui_core.h" @@ -396,6 +397,25 @@ void WindowSDL::WaitEvent() { case SDL_EVENT_QUIT: is_open = false; break; + case SDL_EVENT_TOGGLE_FULLSCREEN: { + if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) { + SDL_SetWindowFullscreen(window, 0); + } else { + SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN); + } + break; + } + case SDL_EVENT_TOGGLE_PAUSE: + SDL_Log("Received SDL_EVENT_TOGGLE_PAUSE"); + + if (DebugState.IsGuestThreadsPaused()) { + SDL_Log("Game Resumed"); + DebugState.ResumeGuestThreads(); + } else { + SDL_Log("Game Paused"); + DebugState.PauseGuestThreads(); + } + break; default: break; } diff --git a/src/sdl_window.h b/src/sdl_window.h index 03ba0797b..48a9be58c 100644 --- a/src/sdl_window.h +++ b/src/sdl_window.h @@ -7,6 +7,8 @@ #include "core/libraries/pad/pad.h" #include "input/controller.h" #include "string" +#define SDL_EVENT_TOGGLE_FULLSCREEN (SDL_EVENT_USER + 1) +#define SDL_EVENT_TOGGLE_PAUSE (SDL_EVENT_USER + 2) struct SDL_Window; struct SDL_Gamepad; diff --git a/src/shadps4.qrc b/src/shadps4.qrc index 340756f5c..83dea01c4 100644 --- a/src/shadps4.qrc +++ b/src/shadps4.qrc @@ -1,38 +1,40 @@ - - images/shadps4.ico - images/about_icon.png - images/dump_icon.png - images/play_icon.png - images/pause_icon.png - images/stop_icon.png - images/utils_icon.png - images/file_icon.png - images/trophy_icon.png - images/folder_icon.png - images/themes_icon.png - images/iconsize_icon.png - images/list_icon.png - images/grid_icon.png - images/exit_icon.png - images/settings_icon.png - images/controller_icon.png - images/refresh_icon.png - images/update_icon.png - images/list_mode_icon.png - images/flag_jp.png - images/flag_eu.png - images/flag_unk.png - images/flag_us.png - images/flag_world.png - images/flag_china.png - images/github.png - images/discord.png - images/ko-fi.png - images/youtube.png - images/website.png - images/ps4_controller.png - images/keyboard_icon.png - images/KBM.png - + + images/shadps4.ico + images/about_icon.png + images/dump_icon.png + images/play_icon.png + images/pause_icon.png + images/stop_icon.png + images/utils_icon.png + images/file_icon.png + images/folder_icon.png + images/themes_icon.png + images/iconsize_icon.png + images/list_icon.png + images/grid_icon.png + images/exit_icon.png + images/settings_icon.png + images/controller_icon.png + images/restart_game_icon.png + images/update_icon.png + images/list_mode_icon.png + images/flag_jp.png + images/flag_eu.png + images/flag_unk.png + images/flag_us.png + images/flag_world.png + images/flag_china.png + images/github.png + images/discord.png + images/ko-fi.png + images/youtube.png + images/website.png + images/ps4_controller.png + images/keyboard_icon.png + images/KBM.png + images/fullscreen_icon.png + images/refreshlist_icon.png + images/trophy_icon.png +