UI: Upgrade to wxWidgets 3.3.1 and add dark mode support for Windows (#1647)

This commit is contained in:
Crementif 2025-07-23 11:07:24 +02:00 committed by GitHub
parent 4efa40c51c
commit 08609591ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
77 changed files with 1224 additions and 1645 deletions

View file

@ -37,11 +37,11 @@ if (ENABLE_VCPKG)
endif() endif()
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_linux") set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_linux;${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports")
elseif(APPLE) elseif(APPLE)
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_mac") set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_mac;${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports")
else() else()
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports") set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_win;${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports")
endif() endif()
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/vcpkg/scripts/buildsystems/vcpkg.cmake" set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/vcpkg/scripts/buildsystems/vcpkg.cmake"
CACHE STRING "Vcpkg toolchain file") CACHE STRING "Vcpkg toolchain file")
@ -199,7 +199,7 @@ if(UNIX AND NOT APPLE)
endif() endif()
if (ENABLE_WXWIDGETS) if (ENABLE_WXWIDGETS)
find_package(wxWidgets 3.2 REQUIRED COMPONENTS base core gl propgrid xrc) find_package(wxWidgets 3.3 REQUIRED COMPONENTS base core gl propgrid xrc)
endif() endif()
if (ENABLE_CUBEB) if (ENABLE_CUBEB)

2
dependencies/vcpkg vendored

@ -1 +1 @@
Subproject commit 533a5fda5c0646d1771345fb572e759283444d5f Subproject commit f0fb3ddba5135b80982668de39dbaa139c00d281

View file

@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.7)
project(wxwidgets-example)
add_executable(main WIN32 popup.cpp)
find_package(wxWidgets REQUIRED)
target_compile_definitions(main PRIVATE ${wxWidgets_DEFINITIONS} "$<$<CONFIG:DEBUG>:${wxWidgets_DEFINITIONS_DEBUG}>")
target_include_directories(main PRIVATE ${wxWidgets_INCLUDE_DIRS})
target_link_libraries(main PRIVATE ${wxWidgets_LIBRARIES})
add_executable(main2 WIN32 popup.cpp)
find_package(wxWidgets CONFIG REQUIRED)
target_link_libraries(main2 PRIVATE wx::core wx::base)
option(USE_WXRC "Use the wxrc resource compiler" ON)
if(USE_WXRC)
execute_process(
COMMAND "${wxWidgets_wxrc_EXECUTABLE}" --help
RESULTS_VARIABLE error_result
)
if(error_result)
message(FATAL_ERROR "Failed to run wxWidgets_wxrc_EXECUTABLE (${wxWidgets_wxrc_EXECUTABLE})")
endif()
endif()
set(PRINT_VARS "" CACHE STRING "Variables to print at the end of configuration")
foreach(var IN LISTS PRINT_VARS)
message(STATUS "${var}:=${${var}}")
endforeach()

View file

@ -0,0 +1,25 @@
diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp
index 2b9e0d7f7e..7eab8b37df 100644
--- a/src/msw/listctrl.cpp
+++ b/src/msw/listctrl.cpp
@@ -3110,6 +3110,11 @@ bool HandleSubItemPrepaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD, HFONT h
if ( it.iImage != -1 )
{
+ if ( !listctrl->HasCheckBoxes() )
+ {
+ rc.left -= 6;
+ }
+
const int yImage = rc.top + ((rc.bottom - rc.top) / 2 - hImage / 2);
ImageList_Draw(himl, it.iImage, hdc, rc.left, yImage,
nmcd.uItemState & CDIS_SELECTED ? ILD_SELECTED
@@ -3235,7 +3240,7 @@ void HandleItemPaint(wxListCtrl* listctrl, LPNMLVCUSTOMDRAW pLVCD, HFONT hfont)
// do not draw item background colour under the checkbox/image
RECT rcIcon;
wxGetListCtrlItemRect(nmcd.hdr.hwndFrom, nmcd.dwItemSpec, LVIR_ICON, rcIcon);
- if ( !::IsRectEmpty(&rcIcon) )
+ if ( !::IsRectEmpty(&rcIcon) && listctrl->HasCheckBoxes() )
rc.left = rcIcon.right + listctrl->FromDIP(GAP_BETWEEN_CHECKBOX_AND_TEXT);
}

View file

@ -0,0 +1,21 @@
diff --git a/build/cmake/config.cmake b/build/cmake/config.cmake
index b359560..7504458 100644
--- a/build/cmake/config.cmake
+++ b/build/cmake/config.cmake
@@ -39,8 +39,14 @@ macro(wx_get_dependencies var lib)
else()
# For the value like $<$<CONFIG:DEBUG>:LIB_PATH>
# Or $<$<NOT:$<CONFIG:DEBUG>>:LIB_PATH>
- string(REGEX REPLACE "^.+>:(.+)>$" "\\1" dep_name ${dep})
- if (NOT dep_name)
+ if(dep MATCHES "^(.+>):(.+)>$")
+ if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND CMAKE_MATCH_1 STREQUAL [[$<$<NOT:$<CONFIG:DEBUG>>]])
+ continue()
+ elseif(CMAKE_BUILD_TYPE STREQUAL "Release" AND CMAKE_MATCH_1 STREQUAL [[$<$<CONFIG:DEBUG>]])
+ continue()
+ endif()
+ set(dep_name "${CMAKE_MATCH_2}")
+ else()
set(dep_name ${dep})
endif()
endif()

View file

@ -0,0 +1,23 @@
diff --git a/build/cmake/modules/FindPCRE2.cmake b/build/cmake/modules/FindPCRE2.cmake
index a27693a..455675a 100644
--- a/build/cmake/modules/FindPCRE2.cmake
+++ b/build/cmake/modules/FindPCRE2.cmake
@@ -24,7 +24,10 @@ set(PCRE2_CODE_UNIT_WIDTH_USED "${PCRE2_CODE_UNIT_WIDTH}" CACHE INTERNAL "")
find_package(PkgConfig QUIET)
pkg_check_modules(PC_PCRE2 QUIET libpcre2-${PCRE2_CODE_UNIT_WIDTH})
+set(PCRE2_LIBRARIES ${PC_PCRE2_LINK_LIBRARIES})
+set(PCRE2_INCLUDE_DIRS ${PC_PCRE2_INCLUDE_DIRS})
+if (0)
find_path(PCRE2_INCLUDE_DIRS
NAMES pcre2.h
HINTS ${PC_PCRE2_INCLUDEDIR}
@@ -36,6 +39,7 @@ find_library(PCRE2_LIBRARIES
HINTS ${PC_PCRE2_LIBDIR}
${PC_PCRE2_LIBRARY_DIRS}
)
+endif()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE2 REQUIRED_VARS PCRE2_LIBRARIES PCRE2_INCLUDE_DIRS VERSION_VAR PC_PCRE2_VERSION)

View file

@ -0,0 +1,17 @@
diff --git a/build/cmake/modules/FindGTK3.cmake b/build/cmake/modules/FindGTK3.cmake
index d2939a1..daf33fe 100644
--- a/build/cmake/modules/FindGTK3.cmake
+++ b/build/cmake/modules/FindGTK3.cmake
@@ -47,6 +47,12 @@ include(CheckSymbolExists)
set(CMAKE_REQUIRED_INCLUDES ${GTK3_INCLUDE_DIRS})
check_symbol_exists(GDK_WINDOWING_WAYLAND "gdk/gdk.h" wxHAVE_GDK_WAYLAND)
check_symbol_exists(GDK_WINDOWING_X11 "gdk/gdk.h" wxHAVE_GDK_X11)
+# With Lerc support in TIFF, Gtk3 may carry C++ compiler libs which break FindWxWidgets.cmake.
+# WxWidgets is C++, so we can remove them here using the inverse pattern.
+set(cxx_libs "${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES}")
+list(REMOVE_ITEM cxx_libs ${CMAKE_C_IMPLICIT_LINK_LIBRARIES})
+list(REMOVE_ITEM GTK3_LINK_LIBRARIES ${cxx_libs})
+set(GTK3_LIBRARIES "${GTK3_LINK_LIBRARIES}" CACHE INTERNAL "")
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK3 DEFAULT_MSG GTK3_INCLUDE_DIRS GTK3_LIBRARIES VERSION_OK)

View file

@ -0,0 +1,39 @@
diff --git a/build/cmake/init.cmake b/build/cmake/init.cmake
index f044d22d4d..48fc5ad072 100644
--- a/build/cmake/init.cmake
+++ b/build/cmake/init.cmake
@@ -198,7 +198,7 @@ if(WIN32)
endif()
endif()
-if(WIN32_MSVC_NAMING)
+if(0)
if(wxBUILD_SHARED)
set(lib_suffix "_dll")
else()
diff --git a/build/cmake/install.cmake b/build/cmake/install.cmake
index a373983043..2e1ace7bf9 100644
--- a/build/cmake/install.cmake
+++ b/build/cmake/install.cmake
@@ -63,7 +63,7 @@ else()
install(DIRECTORY DESTINATION "bin")
install(CODE "execute_process( \
- COMMAND ${CMAKE_COMMAND} -E create_symlink \
+ COMMAND ${CMAKE_COMMAND} -E copy \
\"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/wx/config/${wxBUILD_FILE_ID}\" \
\"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/wx-config\" \
)"
diff --git a/build/cmake/utils/CMakeLists.txt b/build/cmake/utils/CMakeLists.txt
index 15f4339ef9..f93849e025 100644
--- a/build/cmake/utils/CMakeLists.txt
+++ b/build/cmake/utils/CMakeLists.txt
@@ -39,7 +39,7 @@ if(wxUSE_XRC)
# Don't use wx_install() here to preserve escaping.
install(CODE "execute_process( \
- COMMAND ${CMAKE_COMMAND} -E create_symlink \
+ COMMAND ${CMAKE_COMMAND} -E copy \
\"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/${wxrc_output_name}${EXE_SUFFIX}\" \
\"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/wxrc${EXE_SUFFIX}\" \
)"

View file

@ -0,0 +1,13 @@
diff --git a/build/cmake/wxWidgetsConfig.cmake.in b/build/cmake/wxWidgetsConfig.cmake.in
index b251109..60cf762 100644
--- a/build/cmake/wxWidgetsConfig.cmake.in
+++ b/build/cmake/wxWidgetsConfig.cmake.in
@@ -1,5 +1,8 @@
@PACKAGE_INIT@
+include(CMakeFindDependencyMacro)
+find_dependency(NanoSVG CONFIG)
+
cmake_policy(PUSH)
# Set policies to prevent warnings
if(POLICY CMP0057)

View file

@ -0,0 +1,211 @@
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO wxWidgets/wxWidgets
REF "v${VERSION}"
SHA512 8ad17582c4ba721ffe76ada4bb8bd7bc4b050491220aca335fd0506a51354fb789d5bc3d965f0f459dc81784d6427c88272e2acc2099cddf73730231b5a16f62
HEAD_REF master
PATCHES
install-layout.patch
relocatable-wx-config.patch
nanosvg-ext-depend.patch
fix-libs-export.patch
fix-pcre2.patch
gtk3-link-libraries.patch
sdl2.patch
fix-dark-mode-offset.patch
)
vcpkg_check_features(
OUT_FEATURE_OPTIONS FEATURE_OPTIONS
FEATURES
fonts wxUSE_PRIVATE_FONTS
media wxUSE_MEDIACTRL
secretstore wxUSE_SECRETSTORE
sound wxUSE_SOUND
webview wxUSE_WEBVIEW
webview wxUSE_WEBVIEW_EDGE
)
set(OPTIONS_RELEASE "")
if(NOT "debug-support" IN_LIST FEATURES)
list(APPEND OPTIONS_RELEASE "-DwxBUILD_DEBUG_LEVEL=0")
endif()
set(OPTIONS "")
if(VCPKG_TARGET_IS_WINDOWS AND (VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64" OR VCPKG_TARGET_ARCHITECTURE STREQUAL "arm"))
list(APPEND OPTIONS
-DwxUSE_STACKWALKER=OFF
)
endif()
if(VCPKG_TARGET_IS_WINDOWS OR VCPKG_TARGET_IS_OSX)
list(APPEND OPTIONS -DwxUSE_WEBREQUEST_CURL=OFF)
else()
list(APPEND OPTIONS -DwxUSE_WEBREQUEST_CURL=ON)
endif()
if(VCPKG_TARGET_IS_WINDOWS)
if(VCPKG_CRT_LINKAGE STREQUAL "dynamic")
list(APPEND OPTIONS -DwxBUILD_USE_STATIC_RUNTIME=OFF)
else()
list(APPEND OPTIONS -DwxBUILD_USE_STATIC_RUNTIME=ON)
endif()
endif()
vcpkg_find_acquire_program(PKGCONFIG)
# This may be set to ON by users in a custom triplet.
# The use of 'wxUSE_STL' and 'WXWIDGETS_USE_STD_CONTAINERS' (ON or OFF) are not API compatible
# which is why they must be set in a custom triplet rather than a port feature.
if(NOT DEFINED WXWIDGETS_USE_STL)
set(WXWIDGETS_USE_STL OFF)
set(WXWIDGETS_USE_STD_STRING_CONV_IN_WXSTRING OFF)
endif()
if(NOT DEFINED WXWIDGETS_USE_STD_CONTAINERS)
set(WXWIDGETS_USE_STD_CONTAINERS OFF)
endif()
vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
${FEATURE_OPTIONS}
-DwxUSE_STC=OFF
-DwxUSE_REGEX=sys
-DwxUSE_ZLIB=sys
-DwxUSE_EXPAT=sys
-DwxUSE_LIBJPEG=sys
-DwxUSE_LIBPNG=sys
-DwxUSE_LIBTIFF=sys
-DwxUSE_LIBWEBP=sys
-DwxUSE_NANOSVG=sys
-DwxUSE_GLCANVAS=ON
-DwxUSE_LIBGNOMEVFS=OFF
-DwxUSE_LIBNOTIFY=OFF
-DwxUSE_STD_STRING_CONV_IN_WXSTRING=${WXWIDGETS_USE_STD_STRING_CONV_IN_WXSTRING}
-DwxUSE_STD_CONTAINERS=${WXWIDGETS_USE_STD_CONTAINERS}
-DwxUSE_UIACTIONSIMULATOR=OFF
-DCMAKE_DISABLE_FIND_PACKAGE_GSPELL=ON
-DCMAKE_DISABLE_FIND_PACKAGE_MSPACK=ON
-DwxBUILD_INSTALL_RUNTIME_DIR:PATH=bin
${OPTIONS}
"-DPKG_CONFIG_EXECUTABLE=${PKGCONFIG}"
# The minimum cmake version requirement for Cotire is 2.8.12.
# however, we need to declare that the minimum cmake version requirement is at least 3.1 to use CMAKE_PREFIX_PATH as the path to find .pc.
-DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=ON
OPTIONS_RELEASE
${OPTIONS_RELEASE}
MAYBE_UNUSED_VARIABLES
CMAKE_DISABLE_FIND_PACKAGE_GSPELL
CMAKE_DISABLE_FIND_PACKAGE_MSPACK
)
vcpkg_cmake_install()
vcpkg_cmake_config_fixup(CONFIG_PATH lib/cmake/wxWidgets)
# The CMake export is not ready for use: It lacks a config file.
file(REMOVE_RECURSE
${CURRENT_PACKAGES_DIR}/lib/cmake
${CURRENT_PACKAGES_DIR}/debug/lib/cmake
)
set(tools wxrc)
if(NOT VCPKG_TARGET_IS_WINDOWS)
list(APPEND tools wxrc-3.3)
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/tools/${PORT}")
file(RENAME "${CURRENT_PACKAGES_DIR}/bin/wx-config" "${CURRENT_PACKAGES_DIR}/tools/${PORT}/wx-config")
if(NOT VCPKG_BUILD_TYPE)
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/tools/${PORT}/debug")
file(RENAME "${CURRENT_PACKAGES_DIR}/debug/bin/wx-config" "${CURRENT_PACKAGES_DIR}/tools/${PORT}/debug/wx-config")
endif()
endif()
vcpkg_copy_tools(TOOL_NAMES ${tools} AUTO_CLEAN)
# do the copy pdbs now after the dlls got moved to the expected /bin folder above
vcpkg_copy_pdbs()
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/include/msvc")
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")
file(GLOB_RECURSE INCLUDES "${CURRENT_PACKAGES_DIR}/include/*.h")
if(EXISTS "${CURRENT_PACKAGES_DIR}/lib/mswu/wx/setup.h")
list(APPEND INCLUDES "${CURRENT_PACKAGES_DIR}/lib/mswu/wx/setup.h")
endif()
if(EXISTS "${CURRENT_PACKAGES_DIR}/debug/lib/mswud/wx/setup.h")
list(APPEND INCLUDES "${CURRENT_PACKAGES_DIR}/debug/lib/mswud/wx/setup.h")
endif()
foreach(INC IN LISTS INCLUDES)
file(READ "${INC}" _contents)
if(VCPKG_LIBRARY_LINKAGE STREQUAL "static")
string(REPLACE "defined(WXUSINGDLL)" "0" _contents "${_contents}")
else()
string(REPLACE "defined(WXUSINGDLL)" "1" _contents "${_contents}")
endif()
# Remove install prefix from setup.h to ensure package is relocatable
string(REGEX REPLACE "\n#define wxINSTALL_PREFIX [^\n]*" "\n#define wxINSTALL_PREFIX \"\"" _contents "${_contents}")
file(WRITE "${INC}" "${_contents}")
endforeach()
if(NOT EXISTS "${CURRENT_PACKAGES_DIR}/include/wx/setup.h")
file(GLOB_RECURSE WX_SETUP_H_FILES_DBG "${CURRENT_PACKAGES_DIR}/debug/lib/*.h")
file(GLOB_RECURSE WX_SETUP_H_FILES_REL "${CURRENT_PACKAGES_DIR}/lib/*.h")
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
vcpkg_replace_string("${WX_SETUP_H_FILES_REL}" "${CURRENT_PACKAGES_DIR}" "" IGNORE_UNCHANGED)
string(REPLACE "${CURRENT_PACKAGES_DIR}/lib/" "" WX_SETUP_H_FILES_REL "${WX_SETUP_H_FILES_REL}")
string(REPLACE "/setup.h" "" WX_SETUP_H_REL_RELATIVE "${WX_SETUP_H_FILES_REL}")
endif()
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
vcpkg_replace_string("${WX_SETUP_H_FILES_DBG}" "${CURRENT_PACKAGES_DIR}" "" IGNORE_UNCHANGED)
string(REPLACE "${CURRENT_PACKAGES_DIR}/debug/lib/" "" WX_SETUP_H_FILES_DBG "${WX_SETUP_H_FILES_DBG}")
string(REPLACE "/setup.h" "" WX_SETUP_H_DBG_RELATIVE "${WX_SETUP_H_FILES_DBG}")
endif()
configure_file("${CMAKE_CURRENT_LIST_DIR}/setup.h.in" "${CURRENT_PACKAGES_DIR}/include/wx/setup.h" @ONLY)
endif()
file(GLOB configs LIST_DIRECTORIES false "${CURRENT_PACKAGES_DIR}/lib/wx/config/*" "${CURRENT_PACKAGES_DIR}/tools/${PORT}/wx-config")
foreach(config IN LISTS configs)
vcpkg_replace_string("${config}" "${CURRENT_INSTALLED_DIR}" [[${prefix}]])
endforeach()
file(GLOB configs LIST_DIRECTORIES false "${CURRENT_PACKAGES_DIR}/debug/lib/wx/config/*" "${CURRENT_PACKAGES_DIR}/tools/${PORT}/debug/wx-config")
foreach(config IN LISTS configs)
vcpkg_replace_string("${config}" "${CURRENT_INSTALLED_DIR}/debug" [[${prefix}]])
endforeach()
# For CMake multi-config in connection with wrapper
if(EXISTS "${CURRENT_PACKAGES_DIR}/debug/lib/mswud/wx/setup.h")
file(INSTALL "${CURRENT_PACKAGES_DIR}/debug/lib/mswud/wx/setup.h"
DESTINATION "${CURRENT_PACKAGES_DIR}/lib/mswud/wx"
)
endif()
if(NOT "debug-support" IN_LIST FEATURES)
if(VCPKG_TARGET_IS_WINDOWS)
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/include/wx/debug.h" "#define wxDEBUG_LEVEL 1" "#define wxDEBUG_LEVEL 0")
else()
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/include/wx-3.3/wx/debug.h" "#define wxDEBUG_LEVEL 1" "#define wxDEBUG_LEVEL 0")
endif()
endif()
if("example" IN_LIST FEATURES)
file(INSTALL
"${CMAKE_CURRENT_LIST_DIR}/example/CMakeLists.txt"
"${SOURCE_PATH}/samples/popup/popup.cpp"
"${SOURCE_PATH}/samples/sample.xpm"
DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}/example"
)
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/share/${PORT}/example/popup.cpp" "../sample.xpm" "sample.xpm")
endif()
configure_file("${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake" "${CURRENT_PACKAGES_DIR}/share/${PORT}/vcpkg-cmake-wrapper.cmake" @ONLY)
file(REMOVE "${CURRENT_PACKAGES_DIR}/wxwidgets.props")
file(REMOVE "${CURRENT_PACKAGES_DIR}/debug/wxwidgets.props")
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/build")
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/build")
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share")
file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/docs/licence.txt")

View file

@ -0,0 +1,40 @@
diff --git a/wx-config.in b/wx-config.in
index 4df8571..a90db3d 100644
--- a/wx-config.in
+++ b/wx-config.in
@@ -398,8 +398,23 @@ is_cross() { [ "x@cross_compiling@" = "xyes" ]; }
# Determine the base directories we require.
-prefix=${input_option_prefix-${this_prefix:-@prefix@}}
-exec_prefix=${input_option_exec_prefix-${input_option_prefix-${this_exec_prefix:-@exec_prefix@}}}
+vcpkg_prefix=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)
+case "$vcpkg_prefix" in
+ */lib/wx/config)
+ vcpkg_prefix=${vcpkg_prefix%/*/*/*}
+ ;;
+ */tools/wxwidgets/debug)
+ vcpkg_prefix=${vcpkg_prefix%/*/*/*}/debug
+ ;;
+ */tools/wxwidgets)
+ vcpkg_prefix=${vcpkg_prefix%/*/*}
+ ;;
+esac
+if [ -n "@MINGW@" -a -n "@CMAKE_HOST_WIN32@" ]; then
+ vcpkg_prefix=$(cygpath -m "$vcpkg_prefix")
+fi
+prefix=${input_option_prefix-${this_prefix:-$vcpkg_prefix}}
+exec_prefix=${input_option_exec_prefix-${input_option_prefix-${this_exec_prefix:-$prefix}}}
wxconfdir="@libdir@/wx/config"
installed_configs=`cd "$wxconfdir" 2> /dev/null && ls | grep -v "^inplace-"`
@@ -936,6 +951,9 @@ prefix=${this_prefix-$prefix}
exec_prefix=${this_exec_prefix-$exec_prefix}
includedir="@includedir@"
+if [ "@CMAKE_BUILD_TYPE@" = "Debug" ] ; then
+ includedir="${includedir%/debug/include}/include"
+fi
libdir="@libdir@"
bindir="@bindir@"

View file

@ -0,0 +1,29 @@
diff --git a/build/cmake/init.cmake b/build/cmake/init.cmake
index 5447d33..f5440b4 100644
--- a/build/cmake/init.cmake
+++ b/build/cmake/init.cmake
@@ -530,7 +530,9 @@ if(wxUSE_GUI)
endif()
if(wxUSE_SOUND AND wxUSE_LIBSDL AND UNIX AND NOT APPLE)
- find_package(SDL2)
+ find_package(SDL2 CONFIG REQUIRED)
+ set(SDL2_INCLUDE_DIR "" CACHE INTERNAL "")
+ set(SDL2_LIBRARY SDL2::SDL2 CACHE INTERNAL "")
if(NOT SDL2_FOUND)
find_package(SDL)
endif()
diff --git a/build/cmake/wxWidgetsConfig.cmake.in b/build/cmake/wxWidgetsConfig.cmake.in
index 60cf762..202a8c3 100644
--- a/build/cmake/wxWidgetsConfig.cmake.in
+++ b/build/cmake/wxWidgetsConfig.cmake.in
@@ -2,6 +2,9 @@
include(CMakeFindDependencyMacro)
find_dependency(NanoSVG CONFIG)
+if("@wxUSE_LIBSDL@")
+ find_dependency(SDL2 CONFIG)
+endif()
cmake_policy(PUSH)
# Set policies to prevent warnings

View file

@ -0,0 +1,5 @@
#ifdef _DEBUG
#include "../../debug/lib/@WX_SETUP_H_DBG_RELATIVE@/setup.h"
#else
#include "../../lib/@WX_SETUP_H_REL_RELATIVE@/setup.h"
#endif

View file

@ -0,0 +1,4 @@
The package wxwidgets provides CMake targets:
find_package(wxWidgets CONFIG REQUIRED)
target_link_libraries(main PRIVATE wx::core wx::base)

View file

@ -0,0 +1,87 @@
cmake_policy(PUSH)
cmake_policy(SET CMP0012 NEW)
cmake_policy(SET CMP0054 NEW)
cmake_policy(SET CMP0057 NEW)
get_filename_component(_vcpkg_wx_root "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
set(wxWidgets_ROOT_DIR "${_vcpkg_wx_root}" CACHE INTERNAL "")
set(WX_ROOT_DIR "${_vcpkg_wx_root}" CACHE INTERNAL "")
unset(_vcpkg_wx_root)
if(WIN32)
# Find all libs with "32" infix which is unknown to FindwxWidgets.cmake
function(z_vcpkg_wxwidgets_find_base_library BASENAME)
find_library(WX_${BASENAME}d wx${BASENAME}33ud NAMES wx${BASENAME}d PATHS "${wxWidgets_ROOT_DIR}/debug/lib" NO_DEFAULT_PATH)
find_library(WX_${BASENAME} wx${BASENAME}33u NAMES wx${BASENAME} PATHS "${wxWidgets_ROOT_DIR}/lib" NO_DEFAULT_PATH REQUIRED)
endfunction()
function(z_vcpkg_wxwidgets_find_suffix_library BASENAME)
foreach(lib IN LISTS ARGN)
find_library(WX_${lib}d NAMES wx${BASENAME}33ud_${lib} PATHS "${wxWidgets_ROOT_DIR}/debug/lib" NO_DEFAULT_PATH)
find_library(WX_${lib} NAMES wx${BASENAME}33u_${lib} PATHS "${wxWidgets_ROOT_DIR}/lib" NO_DEFAULT_PATH)
endforeach()
endfunction()
z_vcpkg_wxwidgets_find_base_library(base)
z_vcpkg_wxwidgets_find_suffix_library(base net odbc xml)
z_vcpkg_wxwidgets_find_suffix_library(msw core adv aui html media xrc dbgrid gl qa richtext stc ribbon propgrid webview)
if(WX_stc AND "@VCPKG_LIBRARY_LINKAGE@" STREQUAL "static")
z_vcpkg_wxwidgets_find_base_library(scintilla)
endif()
# Force FindwxWidgets.cmake win32 mode for all windows targets built on windows
set(_vcpkg_wxwidgets_backup_crosscompiling "${CMAKE_CROSSCOMPILING}")
set(CMAKE_CROSSCOMPILING 0)
set(wxWidgets_LIB_DIR "${wxWidgets_ROOT_DIR}/lib" CACHE INTERNAL "")
else()
# FindwxWidgets.cmake unix mode, single-config
set(_vcpkg_wxconfig "")
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR "Debug" IN_LIST MAP_IMPORTED_CONFIG_${CMAKE_BUILD_TYPE})
# Debug
set(wxWidgets_LIB_DIR "${wxWidgets_ROOT_DIR}/debug/lib" CACHE INTERNAL "")
file(GLOB _vcpkg_wxconfig LIST_DIRECTORIES false "${wxWidgets_LIB_DIR}/wx/config/*")
endif()
if(NOT _vcpkg_wxconfig)
# Release or fallback
set(wxWidgets_LIB_DIR "${wxWidgets_ROOT_DIR}/lib" CACHE INTERNAL "")
file(GLOB _vcpkg_wxconfig LIST_DIRECTORIES false "${wxWidgets_LIB_DIR}/wx/config/*")
endif()
set(wxWidgets_CONFIG_EXECUTABLE "${_vcpkg_wxconfig}" CACHE INTERNAL "")
unset(_vcpkg_wxconfig)
endif()
set(WX_LIB_DIR "${wxWidgets_LIB_DIR}" CACHE INTERNAL "")
# https://gitlab.kitware.com/cmake/cmake/-/issues/26718
# Instead of special-casing the `atomic` library, we skip the checks entirely.
set(_wx_lib_found TRUE)
_find_package(${ARGS})
unset(_wx_lib_found)
if(DEFINED _vcpkg_wxwidgets_backup_crosscompiling)
set(CMAKE_CROSSCOMPILING "${_vcpkg_wxwidgets_backup_crosscompiling}")
unset(_vcpkg_wxwidgets_backup_crosscompiling)
endif()
if("@VCPKG_LIBRARY_LINKAGE@" STREQUAL "static" AND NOT "wx::core" IN_LIST wxWidgets_LIBRARIES)
find_package(NanoSVG CONFIG QUIET)
list(APPEND wxWidgets_LIBRARIES
NanoSVG::nanosvg NanoSVG::nanosvgrast
)
endif()
if(WIN32 AND "@VCPKG_LIBRARY_LINKAGE@" STREQUAL "static" AND NOT "wx::core" IN_LIST wxWidgets_LIBRARIES)
find_package(EXPAT QUIET)
find_package(JPEG QUIET)
find_package(PNG QUIET)
find_package(TIFF QUIET)
find_package(ZLIB QUIET)
list(APPEND wxWidgets_LIBRARIES
${EXPAT_LIBRARIES}
${JPEG_LIBRARIES}
${PNG_LIBRARIES}
${TIFF_LIBRARIES}
${ZLIB_LIBRARIES}
)
endif()
cmake_policy(POP)

View file

@ -0,0 +1,109 @@
{
"name": "wxwidgets",
"version": "3.3.1",
"description": [
"Widget toolkit and tools library for creating graphical user interfaces (GUIs) for cross-platform applications. ",
"Set WXWIDGETS_USE_STL in a custom triplet to build with the wxUSE_STL build option.",
"Set WXWIDGETS_USE_STD_CONTAINERS in a custom triplet to build with the wxUSE_STD_CONTAINERS build option."
],
"homepage": "https://github.com/wxWidgets/wxWidgets",
"license": "LGPL-2.0-or-later WITH WxWindows-exception-3.1",
"supports": "!uwp & !xbox",
"dependencies": [
{
"name": "cairo",
"default-features": false,
"platform": "!windows & !osx & !ios"
},
{
"name": "curl",
"default-features": false,
"platform": "!windows & !osx"
},
"expat",
{
"name": "gtk3",
"platform": "!windows & !osx & !ios"
},
{
"name": "libiconv",
"platform": "!windows"
},
"libjpeg-turbo",
"libpng",
"libwebp",
"nanosvg",
"opengl",
{
"name": "pcre2",
"default-features": false
},
{
"name": "tiff",
"default-features": false
},
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
},
"zlib"
],
"default-features": [
"debug-support",
"sound"
],
"features": {
"debug-support": {
"description": "Enable wxWidgets debugging support hooks even for release builds (wxDEBUG_LEVEL 1)"
},
"example": {
"description": "Example source code and CMake project"
},
"fonts": {
"description": "Enable to use the font functionality of wxWidgets",
"dependencies": [
{
"name": "fontconfig",
"platform": "!windows & !osx"
},
{
"name": "pango",
"platform": "!windows & !osx"
}
]
},
"media": {
"description": "Build wxMediaCtrl support",
"dependencies": [
{
"name": "gstreamer",
"default-features": false,
"platform": "!windows & !osx & !ios"
}
]
},
"secretstore": {
"description": "Use wxSecretStore class"
},
"sound": {
"description": "Build wxSound support",
"dependencies": [
{
"name": "sdl2",
"default-features": false,
"platform": "!windows & !osx & !ios"
}
]
},
"webview": {
"description": "The Edge backend uses Microsoft's Edge WebView2",
"dependencies": [
"webview2"
]
}
}
}

View file

View file

@ -34,8 +34,6 @@ add_library(CemuWxGui
debugger/DumpWindow.h debugger/DumpWindow.h
debugger/ModuleWindow.cpp debugger/ModuleWindow.cpp
debugger/ModuleWindow.h debugger/ModuleWindow.h
debugger/RegisterCtrl.cpp
debugger/RegisterCtrl.h
debugger/RegisterWindow.cpp debugger/RegisterWindow.cpp
debugger/RegisterWindow.h debugger/RegisterWindow.h
debugger/SymbolCtrl.cpp debugger/SymbolCtrl.cpp
@ -114,22 +112,8 @@ add_library(CemuWxGui
windows/TextureRelationViewer windows/TextureRelationViewer
windows/TextureRelationViewer/TextureRelationWindow.cpp windows/TextureRelationViewer/TextureRelationWindow.cpp
windows/TextureRelationViewer/TextureRelationWindow.h windows/TextureRelationViewer/TextureRelationWindow.h
wxcomponents/checked2.xpm
wxcomponents/checked_dis.xpm
wxcomponents/checked_d.xpm
wxcomponents/checked_ld.xpm
wxcomponents/checkedlistctrl.cpp
wxcomponents/checkedlistctrl.h
wxcomponents/checked_mo.xpm
wxcomponents/checked.xpm
wxcomponents/checktree.cpp wxcomponents/checktree.cpp
wxcomponents/checktree.h wxcomponents/checktree.h
wxcomponents/unchecked2.xpm
wxcomponents/unchecked_dis.xpm
wxcomponents/unchecked_d.xpm
wxcomponents/unchecked_ld.xpm
wxcomponents/unchecked_mo.xpm
wxcomponents/unchecked.xpm
wxgui.h wxgui.h
wxHelper.h wxHelper.h
) )

View file

@ -285,6 +285,17 @@ bool CemuApp::OnInit()
} }
SetTranslationCallback(TranslationCallback); SetTranslationCallback(TranslationCallback);
#if __WXMSW__
auto& wxGuiConfig = GetWxGUIConfig();
if (wxGuiConfig.msw_theme.GetValue() == static_cast<int>(MSWThemeOption::kAuto))
{
MSWEnableDarkMode(DarkMode_Auto);
}
else if (wxGuiConfig.msw_theme.GetValue() == static_cast<int>(MSWThemeOption::kDark))
{
MSWEnableDarkMode(DarkMode_Always);
}
#endif
for (auto&& path : failedWriteAccess) for (auto&& path : failedWriteAccess)
{ {

View file

@ -137,18 +137,40 @@ wxPanel* GeneralSettings2::AddGeneralPage(wxNotebook* notebook)
box_sizer->Add(first_row, 1, wxEXPAND, 5); box_sizer->Add(first_row, 1, wxEXPAND, 5);
} }
#if BOOST_OS_WINDOWS
{ {
auto* second_row = new wxFlexGridSizer(0, 3, 0, 0); auto* second_row = new wxFlexGridSizer(0, 2, 0, 0);
second_row->SetFlexibleDirection(wxBOTH); second_row->SetFlexibleDirection(wxBOTH);
second_row->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); second_row->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
second_row->Add(new wxStaticText(box, wxID_ANY, _("Theme"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
m_msw_theme = new wxChoice(box, wxID_ANY, wxDefaultPosition, wxDefaultSize);
m_msw_theme->SetToolTip(_("Changes the Windows theme used by Cemu\nThis only works on Windows 10 and later\nA restart will be required for any changes to take effect"));
m_msw_theme->AppendString(_("Follow Windows theme"));
m_msw_theme->AppendString(_("Light Theme"));
m_msw_theme->AppendString(_("Dark Theme"));
m_msw_theme->SetSelection(0);
second_row->Add(m_msw_theme, 0, wxALL, 5);
box_sizer->Add(second_row, 0, wxEXPAND, 5);
}
#endif
{
auto* third_row = new wxFlexGridSizer(0, 3, 0, 0);
third_row->SetFlexibleDirection(wxBOTH);
third_row->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
sint32 checkboxCount = 0; sint32 checkboxCount = 0;
auto CountRowElement = [&]() auto CountRowElement = [&]()
{ {
checkboxCount++; checkboxCount++;
if(checkboxCount != 2) if(checkboxCount != 2)
return; return;
second_row->AddSpacer(10); third_row->AddSpacer(10);
checkboxCount = 0; checkboxCount = 0;
}; };
@ -156,51 +178,51 @@ wxPanel* GeneralSettings2::AddGeneralPage(wxNotebook* notebook)
{ {
while(checkboxCount != 0) while(checkboxCount != 0)
CountRowElement(); CountRowElement();
second_row->AddSpacer(10); third_row->AddSpacer(10);
second_row->AddSpacer(10); third_row->AddSpacer(10);
second_row->AddSpacer(10); third_row->AddSpacer(10);
}; };
const int topflag = wxALIGN_CENTER_VERTICAL | wxALL; const int topflag = wxALIGN_CENTER_VERTICAL | wxALL;
m_save_window_position_size = new wxCheckBox(box, wxID_ANY, _("Remember main window position")); m_save_window_position_size = new wxCheckBox(box, wxID_ANY, _("Remember main window position"));
m_save_window_position_size->SetToolTip(_("Restores the last known window position and size when starting Cemu")); m_save_window_position_size->SetToolTip(_("Restores the last known window position and size when starting Cemu"));
second_row->Add(m_save_window_position_size, 0, topflag, 5); third_row->Add(m_save_window_position_size, 0, topflag, 5);
CountRowElement(); CountRowElement();
//second_row->AddSpacer(10); //third_row->AddSpacer(10);
m_save_padwindow_position_size = new wxCheckBox(box, wxID_ANY, _("Remember pad window position")); m_save_padwindow_position_size = new wxCheckBox(box, wxID_ANY, _("Remember pad window position"));
m_save_padwindow_position_size->SetToolTip(_("Restores the last known pad window position and size when opening it")); m_save_padwindow_position_size->SetToolTip(_("Restores the last known pad window position and size when opening it"));
second_row->Add(m_save_padwindow_position_size, 0, topflag, 5); third_row->Add(m_save_padwindow_position_size, 0, topflag, 5);
CountRowElement(); CountRowElement();
const int botflag = wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM; const int botflag = wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM;
m_discord_presence = new wxCheckBox(box, wxID_ANY, _("Discord Presence")); m_discord_presence = new wxCheckBox(box, wxID_ANY, _("Discord Presence"));
m_discord_presence->SetToolTip(_("Enables the Discord Rich Presence feature\nYou will also need to enable it in the Discord settings itself!")); m_discord_presence->SetToolTip(_("Enables the Discord Rich Presence feature\nYou will also need to enable it in the Discord settings itself!"));
second_row->Add(m_discord_presence, 0, botflag, 5); third_row->Add(m_discord_presence, 0, botflag, 5);
CountRowElement(); CountRowElement();
#ifndef ENABLE_DISCORD_RPC #ifndef ENABLE_DISCORD_RPC
m_discord_presence->Disable(); m_discord_presence->Disable();
#endif #endif
//second_row->AddSpacer(10); //third_row->AddSpacer(10);
m_fullscreen_menubar = new wxCheckBox(box, wxID_ANY, _("Fullscreen menu bar")); m_fullscreen_menubar = new wxCheckBox(box, wxID_ANY, _("Fullscreen menu bar"));
m_fullscreen_menubar->SetToolTip(_("Displays the menu bar when Cemu is running in fullscreen mode and the mouse cursor is moved to the top")); m_fullscreen_menubar->SetToolTip(_("Displays the menu bar when Cemu is running in fullscreen mode and the mouse cursor is moved to the top"));
second_row->Add(m_fullscreen_menubar, 0, botflag, 5); third_row->Add(m_fullscreen_menubar, 0, botflag, 5);
CountRowElement(); CountRowElement();
m_save_screenshot = new wxCheckBox(box, wxID_ANY, _("Save screenshot")); m_save_screenshot = new wxCheckBox(box, wxID_ANY, _("Save screenshot"));
m_save_screenshot->SetToolTip(_("Pressing the screenshot key (F12) will save a screenshot directly to the screenshots folder")); m_save_screenshot->SetToolTip(_("Pressing the screenshot key (F12) will save a screenshot directly to the screenshots folder"));
second_row->Add(m_save_screenshot, 0, botflag, 5); third_row->Add(m_save_screenshot, 0, botflag, 5);
CountRowElement(); CountRowElement();
m_disable_screensaver = new wxCheckBox(box, wxID_ANY, _("Disable screen saver")); m_disable_screensaver = new wxCheckBox(box, wxID_ANY, _("Disable screen saver"));
m_disable_screensaver->SetToolTip(_("Prevents the system from activating the screen saver or going to sleep while running a game.")); m_disable_screensaver->SetToolTip(_("Prevents the system from activating the screen saver or going to sleep while running a game."));
second_row->Add(m_disable_screensaver, 0, botflag, 5); third_row->Add(m_disable_screensaver, 0, botflag, 5);
CountRowElement(); CountRowElement();
// Enable/disable feral interactive gamemode // Enable/disable feral interactive gamemode
#if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE) #if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE)
m_feral_gamemode = new wxCheckBox(box, wxID_ANY, _("Enable Feral GameMode")); m_feral_gamemode = new wxCheckBox(box, wxID_ANY, _("Enable Feral GameMode"));
m_feral_gamemode->SetToolTip(_("Use FeralInteractive GameMode if installed.")); m_feral_gamemode->SetToolTip(_("Use FeralInteractive GameMode if installed."));
second_row->Add(m_feral_gamemode, 0, botflag, 5); third_row->Add(m_feral_gamemode, 0, botflag, 5);
CountRowElement(); CountRowElement();
#endif #endif
@ -210,17 +232,17 @@ wxPanel* GeneralSettings2::AddGeneralPage(wxNotebook* notebook)
#endif #endif
m_play_boot_sound = new wxCheckBox(box, wxID_ANY, _("Enable intro sound")); m_play_boot_sound = new wxCheckBox(box, wxID_ANY, _("Enable intro sound"));
m_play_boot_sound->SetToolTip(_("Play bootSound file while compiling shaders/pipelines.")); m_play_boot_sound->SetToolTip(_("Play bootSound file while compiling shaders/pipelines."));
second_row->Add(m_play_boot_sound, 0, botflag, 5); third_row->Add(m_play_boot_sound, 0, botflag, 5);
CountRowElement(); CountRowElement();
m_auto_update = new wxCheckBox(box, wxID_ANY, _("Automatically check for updates")); m_auto_update = new wxCheckBox(box, wxID_ANY, _("Automatically check for updates"));
m_auto_update->SetToolTip(_("Automatically checks for new cemu versions on startup")); m_auto_update->SetToolTip(_("Automatically checks for new cemu versions on startup"));
second_row->Add(m_auto_update, 0, botflag, 5); third_row->Add(m_auto_update, 0, botflag, 5);
CountRowElement(); CountRowElement();
m_receive_untested_releases = new wxCheckBox(box, wxID_ANY, _("Receive untested updates")); m_receive_untested_releases = new wxCheckBox(box, wxID_ANY, _("Receive untested updates"));
m_receive_untested_releases->SetToolTip(_("When checking for updates, include brand new and untested releases. These may contain bugs!")); m_receive_untested_releases->SetToolTip(_("When checking for updates, include brand new and untested releases. These may contain bugs!"));
second_row->Add(m_receive_untested_releases, 0, botflag, 5); third_row->Add(m_receive_untested_releases, 0, botflag, 5);
#if BOOST_OS_LINUX #if BOOST_OS_LINUX
if (!std::getenv("APPIMAGE")) { if (!std::getenv("APPIMAGE")) {
m_auto_update->Disable(); m_auto_update->Disable();
@ -229,7 +251,7 @@ wxPanel* GeneralSettings2::AddGeneralPage(wxNotebook* notebook)
m_auto_update->Disable(); m_auto_update->Disable();
#endif #endif
box_sizer->Add(second_row, 0, wxEXPAND, 5); box_sizer->Add(third_row, 0, wxEXPAND, 5);
} }
general_panel_sizer->Add(box_sizer, 0, wxEXPAND | wxALL, 5); general_panel_sizer->Add(box_sizer, 0, wxEXPAND | wxALL, 5);
@ -270,7 +292,7 @@ wxPanel* GeneralSettings2::AddGeneralPage(wxNotebook* notebook)
auto* general_gamepath_sizer = new wxStaticBoxSizer(general_gamepath_box, wxVERTICAL); auto* general_gamepath_sizer = new wxStaticBoxSizer(general_gamepath_box, wxVERTICAL);
m_game_paths = new wxListBox(general_gamepath_box, wxID_ANY); m_game_paths = new wxListBox(general_gamepath_box, wxID_ANY);
m_game_paths->SetMinSize(wxSize(150, 100)); m_game_paths->SetMinSize(wxSize(150, 70));
m_game_paths->SetToolTip(_("Add the root directory of your game(s). It will scan all directories in it for games")); m_game_paths->SetToolTip(_("Add the root directory of your game(s). It will scan all directories in it for games"));
general_gamepath_sizer->Add(m_game_paths, 1, wxALL | wxEXPAND, 5); general_gamepath_sizer->Add(m_game_paths, 1, wxALL | wxEXPAND, 5);
@ -816,9 +838,6 @@ wxPanel* GeneralSettings2::AddAccountPage(wxNotebook* notebook)
{ {
m_account_information = new wxCollapsiblePane(online_panel, wxID_ANY, _("Account information")); m_account_information = new wxCollapsiblePane(online_panel, wxID_ANY, _("Account information"));
#if BOOST_OS_WINDOWS
m_account_information->GetControlWidget()->SetBackgroundColour(*wxWHITE);
#endif
auto win = m_account_information->GetPane(); auto win = m_account_information->GetPane();
auto content = new wxBoxSizer(wxVERTICAL); auto content = new wxBoxSizer(wxVERTICAL);
@ -971,6 +990,9 @@ void GeneralSettings2::StoreConfig()
wxGuiConfig.receive_untested_updates = m_receive_untested_releases->IsChecked(); wxGuiConfig.receive_untested_updates = m_receive_untested_releases->IsChecked();
#if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE) #if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE)
wxGuiConfig.feral_gamemode = m_feral_gamemode->IsChecked(); wxGuiConfig.feral_gamemode = m_feral_gamemode->IsChecked();
#endif
#if BOOST_OS_WINDOWS
wxGuiConfig.msw_theme = m_msw_theme->GetSelection();
#endif #endif
config.play_boot_sound = m_play_boot_sound->IsChecked(); config.play_boot_sound = m_play_boot_sound->IsChecked();
config.disable_screensaver = m_disable_screensaver->IsChecked(); config.disable_screensaver = m_disable_screensaver->IsChecked();
@ -1146,7 +1168,6 @@ void GeneralSettings2::ValidateConfig()
void GeneralSettings2::DisableSettings(bool game_launched) void GeneralSettings2::DisableSettings(bool game_launched)
{ {
} }
void GeneralSettings2::OnAudioLatencyChanged(wxCommandEvent& event) void GeneralSettings2::OnAudioLatencyChanged(wxCommandEvent& event)
@ -1634,6 +1655,9 @@ void GeneralSettings2::ApplyConfig()
m_disable_screensaver->SetValue(config.disable_screensaver); m_disable_screensaver->SetValue(config.disable_screensaver);
m_play_boot_sound->SetValue(config.play_boot_sound); m_play_boot_sound->SetValue(config.play_boot_sound);
#if BOOST_OS_WINDOWS
m_msw_theme->SetSelection(wxGUIconfig.msw_theme);
#endif
#if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE) #if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE)
m_feral_gamemode->SetValue(wxGUIconfig.feral_gamemode); m_feral_gamemode->SetValue(wxGUIconfig.feral_gamemode);
#endif #endif

View file

@ -44,6 +44,9 @@ private:
wxCheckBox* m_auto_update, *m_receive_untested_releases, *m_save_screenshot; wxCheckBox* m_auto_update, *m_receive_untested_releases, *m_save_screenshot;
wxCheckBox* m_disable_screensaver; wxCheckBox* m_disable_screensaver;
wxCheckBox* m_play_boot_sound; wxCheckBox* m_play_boot_sound;
#if BOOST_OS_WINDOWS
wxChoice* m_msw_theme;
#endif
#if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE) #if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE)
wxCheckBox* m_feral_gamemode; wxCheckBox* m_feral_gamemode;
#endif #endif

View file

@ -12,7 +12,7 @@ wxDEFINE_EVENT(EVT_LOG, wxLogEvent);
LoggingWindow::LoggingWindow(wxFrame* parent) LoggingWindow::LoggingWindow(wxFrame* parent)
: wxFrame(parent, wxID_ANY, _("Logging window"), wxDefaultPosition, wxSize(800, 600), wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL) : wxFrame(parent, wxID_ANY, _("Logging window"), wxDefaultPosition, wxSize(800, 600), wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL)
{ {
auto* sizer = new wxBoxSizer( wxVERTICAL ); auto* sizer = new wxBoxSizer( wxVERTICAL );
{ {
auto filter_row = new wxBoxSizer( wxHORIZONTAL ); auto filter_row = new wxBoxSizer( wxHORIZONTAL );
@ -31,7 +31,7 @@ LoggingWindow::LoggingWindow(wxFrame* parent)
sizer->Add( filter_row, 0, wxEXPAND, 5 ); sizer->Add( filter_row, 0, wxEXPAND, 5 );
} }
m_log_list = new wxLogCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxScrolledWindowStyle|wxVSCROLL);//( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL ); m_log_list = new wxLogCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxScrolledWindowStyle|wxVSCROLL, true);//( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL );
sizer->Add( m_log_list, 1, wxALL | wxEXPAND, 5 ); sizer->Add( m_log_list, 1, wxALL | wxEXPAND, 5 );
this->SetSizer( sizer ); this->SetSizer( sizer );

View file

@ -1861,7 +1861,7 @@ public:
scrolledWindow->SetSizer(m_scrolledSizer); scrolledWindow->SetSizer(m_scrolledSizer);
scrolledWindow->FitInside(); scrolledWindow->FitInside();
scrolledWindow->SetScrollRate(25, 25); scrolledWindow->SetScrollRate(25, 25);
mainSizer->Add(scrolledWindow, wxSizerFlags(1).Expand().Border(wxLEFT | wxRIGHT, 10)); mainSizer->Add(scrolledWindow, wxSizerFlags(1).Expand().Border(wxLEFT, 10));
SetSizer(mainSizer); SetSizer(mainSizer);
CentreOnParent(); CentreOnParent();
@ -1872,7 +1872,7 @@ public:
auto versionString = formatWxString(_("Cemu\nVersion {0}\nCompiled on {1}\nOriginal authors: {2}"), BUILD_VERSION_STRING, BUILD_DATE, "Exzap, Petergov"); auto versionString = formatWxString(_("Cemu\nVersion {0}\nCompiled on {1}\nOriginal authors: {2}"), BUILD_VERSION_STRING, BUILD_DATE, "Exzap, Petergov");
sizer->Add(new wxStaticText(parent, wxID_ANY, versionString), wxSizerFlags().Border(wxALL, 3).Border(wxTOP, 10)); sizer->Add(new wxStaticText(parent, wxID_ANY, versionString), wxSizerFlags().Border(wxALL, 3).Border(wxTOP, 10));
sizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://cemu.info", "https://cemu.info"), wxSizerFlags().Expand().Border(wxTOP | wxBOTTOM, 3)); sizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://cemu.info", "https://cemu.info", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), wxSizerFlags().Expand().Border(wxTOP | wxBOTTOM, 3));
sizer->AddSpacer(3); sizer->AddSpacer(3);
sizer->Add(new wxStaticLine(parent), wxSizerFlags().Expand().Border(wxRIGHT, 4)); sizer->Add(new wxStaticLine(parent), wxSizerFlags().Expand().Border(wxRIGHT, 4));
@ -1893,7 +1893,7 @@ public:
{ {
wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, "zLib ("), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "zLib ("), 0);
lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.zlib.net", "https://www.zlib.net"), 0); lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.zlib.net", "https://www.zlib.net", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0);
sizer->Add(lineSizer); sizer->Add(lineSizer);
} }
@ -1901,7 +1901,7 @@ public:
{ {
wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, "wxWidgets ("), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "wxWidgets ("), 0);
lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.wxwidgets.org/", "https://www.wxwidgets.org/"), 0); lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.wxwidgets.org/", "https://www.wxwidgets.org/", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0);
sizer->Add(lineSizer); sizer->Add(lineSizer);
} }
@ -1909,7 +1909,7 @@ public:
{ {
wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, "OpenSSL ("), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "OpenSSL ("), 0);
lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.openssl.org/", "https://www.openssl.org/"), 0); lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.openssl.org/", "https://www.openssl.org/", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0);
sizer->Add(lineSizer); sizer->Add(lineSizer);
} }
@ -1917,7 +1917,7 @@ public:
{ {
wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, "libcurl ("), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "libcurl ("), 0);
lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://curl.haxx.se/libcurl/", "https://curl.haxx.se/libcurl/"), 0); lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://curl.haxx.se/libcurl/", "https://curl.haxx.se/libcurl/", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0);
sizer->Add(lineSizer); sizer->Add(lineSizer);
} }
@ -1925,7 +1925,7 @@ public:
{ {
wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, "imgui ("), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "imgui ("), 0);
lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://github.com/ocornut/imgui", "https://github.com/ocornut/imgui"), 0); lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://github.com/ocornut/imgui", "https://github.com/ocornut/imgui", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0);
sizer->Add(lineSizer); sizer->Add(lineSizer);
} }
@ -1933,7 +1933,7 @@ public:
{ {
wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, "fontawesome ("), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "fontawesome ("), 0);
lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://github.com/FortAwesome/Font-Awesome", "https://github.com/FortAwesome/Font-Awesome"), 0); lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://github.com/FortAwesome/Font-Awesome", "https://github.com/FortAwesome/Font-Awesome", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0);
sizer->Add(lineSizer); sizer->Add(lineSizer);
} }
@ -1941,7 +1941,7 @@ public:
{ {
wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, "boost ("), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "boost ("), 0);
lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.boost.org", "https://www.boost.org"), 0); lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://www.boost.org", "https://www.boost.org", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0);
sizer->Add(lineSizer); sizer->Add(lineSizer);
} }
@ -1949,7 +1949,7 @@ public:
{ {
wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, "libusb ("), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "libusb ("), 0);
lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://libusb.info", "https://libusb.info"), 0); lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://libusb.info", "https://libusb.info", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0);
sizer->Add(lineSizer); sizer->Add(lineSizer);
} }
@ -1958,7 +1958,7 @@ public:
{ {
wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL);
lineSizer->Add(new wxStaticText(parent, -1, "MoltenVK ("), 0); lineSizer->Add(new wxStaticText(parent, -1, "MoltenVK ("), 0);
lineSizer->Add(new wxHyperlinkCtrl(parent, -1, "https://github.com/KhronosGroup/MoltenVK", "https://github.com/KhronosGroup/MoltenVK"), 0); lineSizer->Add(new wxHyperlinkCtrl(parent, -1, "https://github.com/KhronosGroup/MoltenVK", "https://github.com/KhronosGroup/MoltenVK", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0);
lineSizer->Add(new wxStaticText(parent, -1, ")"), 0); lineSizer->Add(new wxStaticText(parent, -1, ")"), 0);
sizer->Add(lineSizer); sizer->Add(lineSizer);
} }
@ -1967,20 +1967,20 @@ public:
{ {
wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, "icons from "), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "icons from "), 0);
lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://icons8.com", "https://icons8.com"), 0); lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://icons8.com", "https://icons8.com", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0);
sizer->Add(lineSizer); sizer->Add(lineSizer);
} }
// Lato font (are we still using it?) // Lato font (are we still using it?)
{ {
wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, "\"Lato\" font by tyPoland Lukasz Dziedzic (OFL, V1.1)"), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "\"Lato\" font by tyPoland Lukasz Dziedzic (OFL, V1.1)", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0);
sizer->Add(lineSizer); sizer->Add(lineSizer);
} }
// SDL // SDL
{ {
wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, "SDL ("), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "SDL ("), 0, wxALIGN_NOT, 0);
lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://github.com/libsdl-org/SDL", "https://github.com/libsdl-org/SDL"), 0); lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "https://github.com/libsdl-org/SDL", "https://github.com/libsdl-org/SDL", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, ")"), 0);
sizer->Add(lineSizer); sizer->Add(lineSizer);
} }
@ -1988,9 +1988,9 @@ public:
{ {
wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL); wxSizer* lineSizer = new wxBoxSizer(wxHORIZONTAL);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, "Modified ih264 from Android project ("), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, "Modified ih264 from Android project ("), 0);
lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "Source", "https://cemu.info/oss/ih264d.zip"), 0); lineSizer->Add(new wxHyperlinkCtrl(parent, wxID_ANY, "Source", "https://cemu.info/oss/ih264d.zip", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT)), 0);
lineSizer->Add(new wxStaticText(parent, wxID_ANY, " "), 0); lineSizer->Add(new wxStaticText(parent, wxID_ANY, " "), 0);
wxHyperlinkCtrl* noticeLink = new wxHyperlinkCtrl(parent, wxID_ANY, "NOTICE", ""); wxHyperlinkCtrl* noticeLink = new wxHyperlinkCtrl(parent, wxID_ANY, "NOTICE", "", wxDefaultPosition, wxDefaultSize, (wxHL_CONTEXTMENU|wxNO_BORDER|wxHL_ALIGN_LEFT));
noticeLink->Bind(wxEVT_LEFT_DOWN, [](wxMouseEvent& event) noticeLink->Bind(wxEVT_LEFT_DOWN, [](wxMouseEvent& event)
{ {
fs::path tempPath = fs::temp_directory_path(); fs::path tempPath = fs::temp_directory_path();

View file

@ -3,7 +3,6 @@
#include <wx/wx.h> #include <wx/wx.h>
#include <wx/dataview.h> #include <wx/dataview.h>
#include <wx/infobar.h> #include <wx/infobar.h>
#include "wxcomponents/checkedlistctrl.h"
#include "wxgui/PadViewFrame.h" #include "wxgui/PadViewFrame.h"
#include "wxgui/MemorySearcherTool.h" #include "wxgui/MemorySearcherTool.h"

View file

@ -51,7 +51,6 @@ MemorySearcherTool::MemorySearcherTool(wxFrame* parent)
: wxFrame(parent, wxID_ANY, _("Memory Searcher"), wxDefaultPosition, wxSize(600, 540), wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL) : wxFrame(parent, wxID_ANY, _("Memory Searcher"), wxDefaultPosition, wxSize(600, 540), wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL)
{ {
this->SetSizeHints(wxDefaultSize, wxDefaultSize); this->SetSizeHints(wxDefaultSize, wxDefaultSize);
this->wxWindowBase::SetBackgroundColour(*wxWHITE);
this->wxTopLevelWindowBase::SetMinSize(wxSize(600, 540)); this->wxTopLevelWindowBase::SetMinSize(wxSize(600, 540));
auto* sizer = new wxBoxSizer(wxVERTICAL); auto* sizer = new wxBoxSizer(wxVERTICAL);

View file

@ -4,6 +4,8 @@
#include <thread> #include <thread>
#include <atomic> #include <atomic>
#include <wx/listctrl.h>
#include "Cafe/HW/MMU/MMU.h" #include "Cafe/HW/MMU/MMU.h"
#include "util/helpers/helpers.h" #include "util/helpers/helpers.h"
#include "wxgui/helpers/wxCustomEvents.h" #include "wxgui/helpers/wxCustomEvents.h"

View file

@ -30,6 +30,7 @@
#include <zip.h> #include <zip.h>
#include <wx/dirdlg.h> #include <wx/dirdlg.h>
#include <wx/notebook.h> #include <wx/notebook.h>
#include <wx/settings.h>
#include "Cafe/IOSU/legacy/iosu_crypto.h" #include "Cafe/IOSU/legacy/iosu_crypto.h"
#include "config/ActiveSettings.h" #include "config/ActiveSettings.h"
@ -60,14 +61,15 @@ wxPanel* TitleManager::CreateTitleManagerPage()
m_filter->Bind(wxEVT_TEXT, &TitleManager::OnFilterChanged, this); m_filter->Bind(wxEVT_TEXT, &TitleManager::OnFilterChanged, this);
row->Add(m_filter, 1, wxALL | wxEXPAND, 5); row->Add(m_filter, 1, wxALL | wxEXPAND, 5);
const wxImage refresh = wxBITMAP_PNG_FROM_DATA(PNG_REFRESH).ConvertToImage(); const wxImage refresh = wxHelper::LoadThemedBitmapFromPNG(PNG_REFRESH_png, sizeof(PNG_REFRESH_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)).ConvertToImage();
m_refresh_button = new wxBitmapButton(panel, wxID_ANY, refresh.Scale(16, 16)); m_refresh_button = new wxBitmapButton(panel, wxID_ANY, refresh.Scale(16, 16));
m_refresh_button->Disable(); m_refresh_button->Disable();
m_refresh_button->Bind(wxEVT_BUTTON, &TitleManager::OnRefreshButton, this); m_refresh_button->Bind(wxEVT_BUTTON, &TitleManager::OnRefreshButton, this);
m_refresh_button->SetToolTip(_("Refresh")); m_refresh_button->SetToolTip(_("Refresh"));
row->Add(m_refresh_button, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); row->Add(m_refresh_button, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
auto* help_button = new wxStaticBitmap(panel, wxID_ANY, wxBITMAP_PNG_FROM_DATA(PNG_HELP)); const wxBitmap help_bitmap = wxHelper::LoadThemedBitmapFromPNG(PNG_HELP_png, sizeof(PNG_HELP_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
auto* help_button = new wxStaticBitmap(panel, wxID_ANY, help_bitmap);
help_button->SetToolTip(formatWxString(_("The following prefixes are supported:\n{0}\n{1}\n{2}\n{3}\n{4}"), help_button->SetToolTip(formatWxString(_("The following prefixes are supported:\n{0}\n{1}\n{2}\n{3}\n{4}"),
"titleid:", "name:", "type:", "version:", "region:")); "titleid:", "name:", "type:", "version:", "region:"));
row->Add(help_button, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); row->Add(help_button, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);

View file

@ -13,6 +13,9 @@ VulkanCanvas::VulkanCanvas(wxWindow* parent, const wxSize& size, bool is_main_wi
{ {
Bind(wxEVT_PAINT, &VulkanCanvas::OnPaint, this); Bind(wxEVT_PAINT, &VulkanCanvas::OnPaint, this);
Bind(wxEVT_SIZE, &VulkanCanvas::OnResize, this); Bind(wxEVT_SIZE, &VulkanCanvas::OnResize, this);
#if __WXMSW__
MSWDisableComposited();
#endif
auto& canvas = is_main_window ? WindowSystem::GetWindowInfo().canvas_main : WindowSystem::GetWindowInfo().canvas_pad; auto& canvas = is_main_window ? WindowSystem::GetWindowInfo().canvas_main : WindowSystem::GetWindowInfo().canvas_pad;
canvas = initHandleContextFromWxWidgetsWindow(this); canvas = initHandleContextFromWxWidgetsWindow(this);

View file

@ -1,5 +1,8 @@
#include "wxgui/wxgui.h" #include "wxgui/wxgui.h"
#include "TextList.h" #include "TextList.h"
#include "debugger/DisasmCtrl.h"
#include <wx/setup.h> #include <wx/setup.h>
#include <wx/tooltip.h> #include <wx/tooltip.h>
@ -22,9 +25,11 @@ TextList::TextList(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wx
: wxControl(parent, id, pos, size, style), wxScrollHelper(this) : wxControl(parent, id, pos, size, style), wxScrollHelper(this)
{ {
m_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); m_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
wxWindowBase::SetBackgroundStyle(wxBG_STYLE_PAINT); this->wxWindowBase::SetBackgroundStyle(wxBG_STYLE_PAINT);
wxClientDC dc(this); wxInfoDC dc(this);
this->DoPrepareReadOnlyDC(dc);
dc.SetFont(m_font);
m_line_height = dc.GetCharHeight(); m_line_height = dc.GetCharHeight();
m_char_width = dc.GetCharWidth(); m_char_width = dc.GetCharWidth();
@ -76,7 +81,7 @@ void TextList::RefreshLine(uint32 line)
wxSize TextList::DoGetVirtualSize() const wxSize TextList::DoGetVirtualSize() const
{ {
return {wxDefaultCoord, (int)(m_element_count + 1) * m_line_height}; return {wxDefaultCoord, (int)m_element_count * m_line_height};
} }
void TextList::DoSetSize(int x, int y, int width, int height, int sizeFlags) void TextList::DoSetSize(int x, int y, int width, int height, int sizeFlags)
@ -252,7 +257,6 @@ void TextList::OnContextMenu(wxContextMenuEvent& event)
OnContextMenu(clientPosition, line); OnContextMenu(clientPosition, line);
} }
void TextList::OnTooltipTimer(wxTimerEvent& event) void TextList::OnTooltipTimer(wxTimerEvent& event)
{ {
m_tooltip_window->Hide(); m_tooltip_window->Hide();
@ -278,8 +282,7 @@ void TextList::OnTooltipTimer(wxTimerEvent& event)
void TextList::OnPaintEvent(wxPaintEvent& event) void TextList::OnPaintEvent(wxPaintEvent& event)
{ {
wxBufferedPaintDC dc(m_targetWindow, wxBUFFER_VIRTUAL_AREA); wxAutoBufferedPaintDC dc(m_targetWindow);
dc.SetFont(m_font);
// get window position // get window position
auto position = GetPosition(); auto position = GetPosition();
@ -291,9 +294,10 @@ void TextList::OnPaintEvent(wxPaintEvent& event)
position.y = (rect_update.y / m_line_height) * m_line_height; position.y = (rect_update.y / m_line_height) * m_line_height;
// paint background // paint background
const wxColour window_colour = COLOR_WHITE; dc.SetFont(m_font);
dc.SetBrush(window_colour); const wxColour window_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
dc.SetPen(window_colour); dc.SetBrush(GetBackgroundColour());
dc.SetPen(*wxTRANSPARENT_PEN);
dc.DrawRectangle(rect_update); dc.DrawRectangle(rect_update);
//// paint selection //// paint selection
@ -312,6 +316,5 @@ void TextList::OnPaintEvent(wxPaintEvent& event)
OnDraw(dc, start, count, position); OnDraw(dc, start, count, position);
// removed Update() here since all text is white
this->Update();
} }

View file

@ -5,12 +5,6 @@
#include <unordered_map> #include <unordered_map>
#include <sstream> #include <sstream>
#define COLOR_BLACK 0xFF000000
#define COLOR_GREY 0xFFA0A0A0
#define COLOR_LIGHT_GREY 0xFFE0E0E0
#define COLOR_WHITE 0xFFFFFFFF
#define COLOR_RED 0xFF0000FF
class TextList : public wxControl, public wxScrollHelper class TextList : public wxControl, public wxScrollHelper
{ {

View file

@ -1,12 +1,12 @@
#include "wxgui/components/wxDownloadManagerList.h" #include "wxgui/components/wxDownloadManagerList.h"
#include "wxHelper.h"
#include "wxgui/helpers/wxHelpers.h" #include "wxgui/helpers/wxHelpers.h"
#include "util/helpers/SystemException.h" #include "util/helpers/SystemException.h"
#include "Cafe/TitleList/GameInfo.h" #include "Cafe/TitleList/GameInfo.h"
#include "wxgui/components/wxGameList.h" #include "wxgui/components/wxGameList.h"
#include "wxgui/helpers/wxCustomEvents.h" #include "wxgui/helpers/wxCustomEvents.h"
#include <wx/imaglist.h>
#include <wx/wupdlock.h> #include <wx/wupdlock.h>
#include <wx/menu.h> #include <wx/menu.h>
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
@ -167,8 +167,8 @@ wxItemAttr* wxDownloadManagerList::OnGetItemAttr(long item) const
} }
} }
const wxColour kSecondColor{ 0xFDF9F2 }; wxColour bgColourSecondary = wxHelper::CalculateAccentColour(GetBackgroundColour());
static wxListItemAttr s_coloured_attr(GetTextColour(), kSecondColor, GetFont()); static wxListItemAttr s_coloured_attr(GetTextColour(), bgColourSecondary, GetFont());
return item % 2 == 0 ? nullptr : &s_coloured_attr; return item % 2 == 0 ? nullptr : &s_coloured_attr;
} }

View file

@ -140,32 +140,33 @@ wxGameList::wxGameList(wxWindow* parent, wxWindowID id)
{ {
const auto& config = GetWxGUIConfig(); const auto& config = GetWxGUIConfig();
char transparent_bitmap[kIconWidth * kIconWidth * 4] = {wxIMAGE_ALPHA_TRANSPARENT};
memset((void*)transparent_bitmap, wxIMAGE_ALPHA_TRANSPARENT, sizeof(transparent_bitmap));
wxBitmap blank(transparent_bitmap, kIconWidth, kIconWidth);
blank.UseAlpha(true);
m_image_list_data = {};
m_image_list_data.emplace_back(wxBitmapBundle::FromBitmap(blank));
wxListCtrl::SetNormalImages(m_image_list_data);
m_image_list_small_data = {};
wxBitmap::Rescale(blank, {kListIconWidth, kListIconWidth});
m_image_list_small_data.emplace_back(wxBitmapBundle::FromBitmap(blank));
wxListCtrl::SetSmallImages(m_image_list_small_data);
InsertColumn(ColumnHiddenName, "", wxLIST_FORMAT_LEFT, 0); InsertColumn(ColumnHiddenName, "", wxLIST_FORMAT_LEFT, 0);
if(config.show_icon_column) if(config.show_icon_column)
InsertColumn(ColumnIcon, _("Icon"), wxLIST_FORMAT_LEFT, kListIconWidth); InsertColumn(ColumnIcon, _("Icon"), wxLIST_FORMAT_LEFT, GetColumnDefaultWidth(ColumnIcon));
else else
InsertColumn(ColumnIcon, _("Icon"), wxLIST_FORMAT_LEFT, 0); InsertColumn(ColumnIcon, _("Icon"), wxLIST_FORMAT_LEFT, 0);
InsertColumn(ColumnName, _("Game"), wxLIST_FORMAT_LEFT, config.column_width.name); InsertColumn(ColumnName, _("Game"), wxLIST_FORMAT_LEFT, config.column_width.name);
InsertColumn(ColumnVersion, _("Version"), wxLIST_FORMAT_RIGHT, config.column_width.version); InsertColumn(ColumnVersion, _("Version"), wxLIST_FORMAT_LEFT, config.column_width.version);
InsertColumn(ColumnDLC, _("DLC"), wxLIST_FORMAT_RIGHT, config.column_width.dlc); InsertColumn(ColumnDLC, _("DLC"), wxLIST_FORMAT_LEFT, config.column_width.dlc);
InsertColumn(ColumnGameTime, _("You've played"), wxLIST_FORMAT_LEFT, config.column_width.game_time); InsertColumn(ColumnGameTime, _("You've played"), wxLIST_FORMAT_LEFT, config.column_width.game_time);
InsertColumn(ColumnGameStarted, _("Last played"), wxLIST_FORMAT_LEFT, config.column_width.game_started); InsertColumn(ColumnGameStarted, _("Last played"), wxLIST_FORMAT_LEFT, config.column_width.game_started);
InsertColumn(ColumnRegion, _("Region"), wxLIST_FORMAT_LEFT, config.column_width.region); InsertColumn(ColumnRegion, _("Region"), wxLIST_FORMAT_LEFT, config.column_width.region);
InsertColumn(ColumnTitleID, _("Title ID"), wxLIST_FORMAT_LEFT, config.column_width.title_id); InsertColumn(ColumnTitleID, _("Title ID"), wxLIST_FORMAT_LEFT, config.column_width.title_id);
const char transparent_bitmap[kIconWidth * kIconWidth * 4] = {0};
wxBitmap blank(transparent_bitmap, kIconWidth, kIconWidth);
blank.UseAlpha(true);
m_image_list = new wxImageList(kIconWidth, kIconWidth);
m_image_list->Add(blank);
wxListCtrl::SetImageList(m_image_list, wxIMAGE_LIST_NORMAL);
m_image_list_small = new wxImageList(kListIconWidth, kListIconWidth);
wxBitmap::Rescale(blank, {kListIconWidth, kListIconWidth});
m_image_list_small->Add(blank);
wxListCtrl::SetImageList(m_image_list_small, wxIMAGE_LIST_SMALL);
m_tooltip_window = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); m_tooltip_window = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER);
auto* tooltip_sizer = new wxBoxSizer(wxVERTICAL); auto* tooltip_sizer = new wxBoxSizer(wxVERTICAL);
tooltip_sizer->Add(new wxStaticText(m_tooltip_window, wxID_ANY, _("This game entry seems to be either an update or the base game was merged with update data\nBroken game dumps cause various problems during emulation and may even stop working at all in future Cemu versions\nPlease make sure the base game is intact and install updates only with the File->Install Update/DLC option")), 0, wxALL, 5); tooltip_sizer->Add(new wxStaticText(m_tooltip_window, wxID_ANY, _("This game entry seems to be either an update or the base game was merged with update data\nBroken game dumps cause various problems during emulation and may even stop working at all in future Cemu versions\nPlease make sure the base game is intact and install updates only with the File->Install Update/DLC option")), 0, wxALL, 5);
@ -210,10 +211,6 @@ wxGameList::~wxGameList()
m_async_task_count.increment(); m_async_task_count.increment();
m_async_worker_thread.join(); m_async_worker_thread.join();
// destroy image lists
delete m_image_list;
delete m_image_list_small;
// clear image cache // clear image cache
m_icon_cache_mtx.lock(); m_icon_cache_mtx.lock();
m_icon_cache.clear(); m_icon_cache.clear();
@ -306,6 +303,12 @@ int wxGameList::GetColumnDefaultWidth(int column)
switch (column) switch (column)
{ {
case ColumnIcon: case ColumnIcon:
#if __WXMSW__
// note: this is another workaround that could be used to fix the icon offset, but instead of this there's a vcpkg patch for wxWidgets that fixes the icon offset
// wxWidgets offsets the icon in the REPORT view so it's cut off if the column width is set to 64px, see https://github.com/wxWidgets/wxWidgets/blob/09f433faf39aab3f25b3c564b82448bb845fae56/src/msw/listctrl.cpp#L3091
// so add 6px to the column width to compensate, and add another 6px to the right side so that it has equal whitespace on both sides
// return kListIconWidth + 6 + 6;
#endif
return kListIconWidth; return kListIconWidth;
case ColumnName: case ColumnName:
return DefaultColumnSize::name; return DefaultColumnSize::name;
@ -408,10 +411,11 @@ void wxGameList::SetStyle(Style style, bool save)
switch(style) switch(style)
{ {
case Style::kIcons: case Style::kIcons:
wxListCtrl::SetImageList(m_image_list, wxIMAGE_LIST_NORMAL); wxListCtrl::SetNormalImages(m_image_list_data);
break; break;
case Style::kSmallIcons: case Style::kSmallIcons:
wxListCtrl::SetImageList(m_image_list_small, wxIMAGE_LIST_NORMAL); case Style::kList:
wxListCtrl::SetSmallImages(m_image_list_small_data);
break; break;
} }
@ -464,7 +468,7 @@ void wxGameList::UpdateItemColors(sint32 startIndex)
if (GetConfig().IsGameListFavorite(titleId)) if (GetConfig().IsGameListFavorite(titleId))
{ {
SetItemBackgroundColour(i, kFavoriteColor); SetItemBackgroundColour(i, kFavoriteColor);
SetItemTextColour(i, 0x000000UL); SetItemTextColour(i, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
} }
else if ((i&1) != 0) else if ((i&1) != 0)
{ {
@ -638,6 +642,7 @@ enum ContextMenuEntries
kContextMenuCopyTitleId, kContextMenuCopyTitleId,
kContextMenuCopyTitleImage kContextMenuCopyTitleImage
}; };
void wxGameList::OnContextMenu(wxContextMenuEvent& event) void wxGameList::OnContextMenu(wxContextMenuEvent& event)
{ {
auto& config = GetConfig(); auto& config = GetConfig();
@ -809,33 +814,34 @@ void wxGameList::OnContextMenuSelected(wxCommandEvent& event)
} }
case kContextMenuCopyTitleName: case kContextMenuCopyTitleName:
{ {
if (wxTheClipboard->Open()) if (wxClipboard::Get()->Open())
{ {
wxTheClipboard->SetData(new wxTextDataObject(wxString::FromUTF8(gameInfo.GetTitleName()))); wxClipboard::Get()->SetData(new wxTextDataObject(wxString::FromUTF8(gameInfo.GetTitleName())));
wxTheClipboard->Close(); wxClipboard::Get()->Close();
} }
break; break;
} }
case kContextMenuCopyTitleId: case kContextMenuCopyTitleId:
{ {
if (wxTheClipboard->Open()) if (wxClipboard::Get()->Open())
{ {
wxTheClipboard->SetData(new wxTextDataObject(fmt::format("{:016x}", gameInfo.GetBaseTitleId()))); wxClipboard::Get()->SetData(new wxTextDataObject(fmt::format("{:016x}", gameInfo.GetBaseTitleId())));
wxTheClipboard->Close(); wxClipboard::Get()->Close();
} }
break; break;
} }
case kContextMenuCopyTitleImage: case kContextMenuCopyTitleImage:
{ {
if (wxTheClipboard->Open()) if (wxClipboard::Get()->Open())
{ {
int icon_large; int icon_large;
int icon_small; int icon_small;
if (!QueryIconForTitle(title_id, icon_large, icon_small)) if (!QueryIconForTitle(title_id, icon_large, icon_small))
break; break;
auto icon = m_image_list->GetBitmap(icon_large); auto icon = m_image_list_data[icon_large];
wxTheClipboard->SetData(new wxBitmapDataObject(icon)); auto newClipboardData = wxBitmapDataObject(icon.GetBitmap(icon.GetDefaultSize()));
wxTheClipboard->Close(); wxClipboard::Get()->SetData(&newClipboardData);
wxClipboard::Get()->Close();
} }
break; break;
} }
@ -994,7 +1000,7 @@ void wxGameList::ApplyGameListColumnWidths()
const auto& config = GetWxGUIConfig(); const auto& config = GetWxGUIConfig();
wxWindowUpdateLocker lock(this); wxWindowUpdateLocker lock(this);
if(config.show_icon_column) if(config.show_icon_column)
SetColumnWidth(ColumnIcon, kListIconWidth); SetColumnWidth(ColumnIcon, GetColumnDefaultWidth(ColumnIcon));
else else
SetColumnWidth(ColumnIcon, 0); SetColumnWidth(ColumnIcon, 0);
SetColumnWidth(ColumnName, config.column_width.name); SetColumnWidth(ColumnName, config.column_width.name);
@ -1109,6 +1115,23 @@ void wxGameList::OnGameEntryUpdatedByTitleId(wxTitleIdEvent& event)
TitleId baseTitleId = gameInfo.GetBaseTitleId(); TitleId baseTitleId = gameInfo.GetBaseTitleId();
bool isNewEntry = false; bool isNewEntry = false;
if (m_style == Style::kIcons)
{
wxListCtrl::SetNormalImages(m_image_list_data);
}
else if (m_style == Style::kSmallIcons)
{
wxListCtrl::SetSmallImages(m_image_list_small_data);
}
else if (m_style == Style::kList)
{
wxListCtrl::SetSmallImages(m_image_list_small_data);
}
int icon = -1; /* 0 is the default empty icon */
int icon_small = -1; /* 0 is the default empty icon */
QueryIconForTitle(baseTitleId, icon, icon_small);
auto index = FindListItemByTitleId(baseTitleId); auto index = FindListItemByTitleId(baseTitleId);
if(index == wxNOT_FOUND) if(index == wxNOT_FOUND)
{ {
@ -1118,10 +1141,6 @@ void wxGameList::OnGameEntryUpdatedByTitleId(wxTitleIdEvent& event)
isNewEntry = true; isNewEntry = true;
} }
int icon = 0; /* 0 is the default empty icon */
int icon_small = 0; /* 0 is the default empty icon */
QueryIconForTitle(baseTitleId, icon, icon_small);
if (m_style == Style::kList) if (m_style == Style::kList)
{ {
SetItemColumnImage(index, ColumnIcon, icon_small); SetItemColumnImage(index, ColumnIcon, icon_small);
@ -1324,17 +1343,18 @@ void wxGameList::AsyncWorkerThread()
wxMemoryInputStream tmp_stream(tgaData->data(), tgaData->size()); wxMemoryInputStream tmp_stream(tgaData->data(), tgaData->size());
const wxImage image(tmp_stream); const wxImage image(tmp_stream);
// todo - is wxImageList thread safe? // todo - is wxImageList thread safe?
int icon = m_image_list->Add(image.Scale(kIconWidth, kIconWidth, wxIMAGE_QUALITY_BICUBIC)); m_image_list_data.emplace_back(image.Scale(kIconWidth, kIconWidth, wxIMAGE_QUALITY_BICUBIC));
int icon_small = m_image_list_small->Add(image.Scale(kListIconWidth, kListIconWidth, wxIMAGE_QUALITY_BICUBIC)); m_image_list_small_data.emplace_back(image.Scale(kListIconWidth, kListIconWidth, wxIMAGE_QUALITY_BICUBIC));
// store in cache // store in cache
m_icon_cache_mtx.lock(); m_icon_cache_mtx.lock();
m_icon_cache.try_emplace(titleId, icon, icon_small); m_icon_cache.try_emplace(titleId, m_image_list_data.size() - 1, m_image_list_small_data.size() - 1);
m_icon_cache_mtx.unlock(); m_icon_cache_mtx.unlock();
iconSuccessfullyLoaded = true; iconSuccessfullyLoaded = true;
} }
else else
{ {
cemuLog_log(LogType::Force, "Failed to load icon for title {:016x}", titleId); cemuLog_log(LogType::Force, "Failed to load icon for title {:016x}", titleId);
cemu_assert_debug(false);
} }
titleInfo.Unmount(tempMountPath); titleInfo.Unmount(tempMountPath);
// notify UI about loaded icon // notify UI about loaded icon
@ -1411,7 +1431,9 @@ void wxGameList::CreateShortcut(GameInfo2& gameInfo)
iconPath = outIconDir / fmt::format("{:016x}.png", gameInfo.GetBaseTitleId()); iconPath = outIconDir / fmt::format("{:016x}.png", gameInfo.GetBaseTitleId());
wxFileOutputStream pngFileStream(_pathToUtf8(iconPath.value())); wxFileOutputStream pngFileStream(_pathToUtf8(iconPath.value()));
auto image = m_image_list->GetIcon(iconIndex).ConvertToImage(); const auto icon = m_image_list_data[iconIndex];
wxBitmap bitmap{icon.GetBitmap(wxDefaultSize)};
wxImage image = bitmap.ConvertToImage();
wxPNGHandler pngHandler; wxPNGHandler pngHandler;
if (!pngHandler.SaveFile(&image, pngFileStream, false)) if (!pngHandler.SaveFile(&image, pngFileStream, false))
{ {
@ -1502,7 +1524,9 @@ void wxGameList::CreateShortcut(GameInfo2& gameInfo)
iconPath = outIconDir / fmt::format("{:016x}.png", gameInfo.GetBaseTitleId()); iconPath = outIconDir / fmt::format("{:016x}.png", gameInfo.GetBaseTitleId());
wxFileOutputStream pngFileStream(_pathToUtf8(iconPath.value())); wxFileOutputStream pngFileStream(_pathToUtf8(iconPath.value()));
auto image = m_image_list->GetIcon(iconIndex).ConvertToImage(); const auto icon = m_image_list_data[iconIndex];
wxBitmap bitmap{icon.GetBitmap(wxDefaultSize)};
wxImage image = bitmap.ConvertToImage();
wxPNGHandler pngHandler; wxPNGHandler pngHandler;
if (!pngHandler.SaveFile(&image, pngFileStream, false)) if (!pngHandler.SaveFile(&image, pngFileStream, false))
{ {
@ -1609,19 +1633,14 @@ void wxGameList::CreateShortcut(GameInfo2& gameInfo)
cemuLog_log(LogType::Force, "Icon hasn't loaded"); cemuLog_log(LogType::Force, "Icon hasn't loaded");
return; return;
} }
const auto icon = m_image_list->GetIcon(iconIdx); const auto icon = m_image_list_data[iconIdx];
const auto folder = ActiveSettings::GetUserDataPath("icons"); const auto folder = ActiveSettings::GetUserDataPath("icons");
if (!fs::exists(folder) && !fs::create_directories(folder)) if (!fs::exists(folder) && !fs::create_directories(folder))
{ {
cemuLog_log(LogType::Force, "Failed to create icon directory"); cemuLog_log(LogType::Force, "Failed to create icon directory");
return; return;
} }
wxBitmap bitmap{}; wxBitmap bitmap{icon.GetBitmap(wxDefaultSize)};
if (!bitmap.CopyFromIcon(icon))
{
cemuLog_log(LogType::Force, "Failed to copy icon");
return;
}
icon_path = folder / fmt::format("{:016x}.ico", titleId); icon_path = folder / fmt::format("{:016x}.ico", titleId);
auto stream = wxFileOutputStream(icon_path->wstring()); auto stream = wxFileOutputStream(icon_path->wstring());

View file

@ -10,6 +10,7 @@
#include <wx/listctrl.h> #include <wx/listctrl.h>
#include <wx/timer.h> #include <wx/timer.h>
#include <wx/panel.h> #include <wx/panel.h>
#include <wx/settings.h>
#include <Cafe/TitleList/GameInfo.h> #include <Cafe/TitleList/GameInfo.h>
#include "util/helpers/Semaphore.h" #include "util/helpers/Semaphore.h"
@ -63,9 +64,9 @@ private:
Style m_style; Style m_style;
long GetStyleFlags(Style style) const; long GetStyleFlags(Style style) const;
inline static const wxColour kUpdateColor{ 0x3939c3 }; const wxColour kUpdateColor{ wxSystemSettings::SelectLightDark(wxColour(195, 57, 57), wxColour(84, 29, 29)) };
inline static const wxColour kFavoriteColor{ 0xD3F6FD }; const wxColour kFavoriteColor{ wxSystemSettings::SelectLightDark(wxColour(253, 246, 211), wxColour(82, 84, 48)) };
inline static const wxColour kSecondColor{ 0xFDF9F2 }; const wxColour kSecondColor{ wxSystemSettings::SelectLightDark(wxColour(242, 249, 253), wxColour(34, 34, 34)) };
void UpdateItemColors(sint32 startIndex = 0); void UpdateItemColors(sint32 startIndex = 0);
enum ItemColumns : int enum ItemColumns : int
@ -121,7 +122,7 @@ private:
inline static constexpr int kListIconWidth = 64; inline static constexpr int kListIconWidth = 64;
inline static constexpr int kIconWidth = 128; inline static constexpr int kIconWidth = 128;
wxImageList* m_image_list, *m_image_list_small; wxWithImages::Images m_image_list_data, m_image_list_small_data;
std::mutex m_icon_cache_mtx; std::mutex m_icon_cache_mtx;
std::set<TitleId> m_icon_loaded; std::set<TitleId> m_icon_loaded;

View file

@ -1,6 +1,7 @@
#include "wxgui/components/wxInputDraw.h" #include "wxgui/components/wxInputDraw.h"
#include <wx/dcbuffer.h> #include <wx/dcbuffer.h>
#include <wx/settings.h>
wxInputDraw::wxInputDraw(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size) wxInputDraw::wxInputDraw(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size)
: wxWindow(parent, id, pos, size, 0, wxPanelNameStr) : wxWindow(parent, id, pos, size, 0, wxPanelNameStr)
@ -21,33 +22,35 @@ void wxInputDraw::OnRender(wxDC& dc)
{ {
dc.Clear(); dc.Clear();
glm::vec2 position; glm::vec2 position = m_position;
const wxPen *black, *red, *grey;
const wxBrush *black_brush, *red_brush, *grey_brush;
if(IsEnabled())
{
position = m_position;
black = wxBLACK_PEN; wxPen black = wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
red = wxRED_PEN; wxPen red = *wxRED_PEN;
grey = wxGREY_PEN; wxPen grey = wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT));
wxPen green = wxSystemSettings::SelectLightDark(0x336600, 0x99FF99);
black_brush = wxBLACK_BRUSH; wxBrush black_brush = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
red_brush = wxRED_BRUSH; wxBrush red_brush = *wxRED_BRUSH;
grey_brush = wxGREY_BRUSH; wxBrush grey_brush = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
} wxBrush green_brush = wxSystemSettings::SelectLightDark(0x336600, 0x99FF99);
else
if(!IsEnabled())
{ {
position = {}; position = {};
black = red = wxMEDIUM_GREY_PEN; black.SetColour(black.GetColour());
grey = wxLIGHT_GREY_PEN; red.SetColour(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT));
grey.SetColour(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT).MakeDisabled());
black_brush = red_brush = wxMEDIUM_GREY_BRUSH; black_brush = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
grey_brush = wxLIGHT_GREY_BRUSH; red_brush = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT).MakeDisabled();
grey_brush = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT).MakeDisabled();
} }
dc.SetBackgroundMode(wxSOLID); dc.SetBackgroundMode(wxSOLID);
dc.SetBackground(*wxWHITE_BRUSH); dc.SetBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
dc.Clear();
const auto size = GetSize(); const auto size = GetSize();
const auto min_size = (float)std::min(size.GetWidth(), size.GetHeight()) - 1.0f; const auto min_size = (float)std::min(size.GetWidth(), size.GetHeight()) - 1.0f;
@ -55,16 +58,16 @@ void wxInputDraw::OnRender(wxDC& dc)
// border // border
const wxRect border{0, 0, (int)min_size, (int)min_size}; const wxRect border{0, 0, (int)min_size, (int)min_size};
dc.SetPen(*black); dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT));
dc.DrawRectangle(border); dc.DrawRectangle(border);
dc.SetPen(IsEnabled() ? wxPen(wxColour(0x336600)) : *grey); // dark green dc.SetPen(IsEnabled() ? green.GetColour() : grey.GetColour());
dc.DrawCircle((int)middle.x, (int)middle.y, (int)middle.x); dc.DrawCircle((int)middle.x, (int)middle.y, (int)middle.x);
if (m_deadzone > 0) if (m_deadzone > 0)
{ {
dc.SetPen(*grey); dc.SetPen(grey);
dc.SetBrush(*wxLIGHT_GREY_BRUSH); dc.SetBrush(grey_brush);
const auto deadzone_size = m_deadzone * min_size / 2.0f; const auto deadzone_size = m_deadzone * min_size / 2.0f;
dc.DrawCircle( dc.DrawCircle(
static_cast<int>(middle.x), static_cast<int>(middle.x),
@ -73,25 +76,25 @@ void wxInputDraw::OnRender(wxDC& dc)
if (length(position) >= m_deadzone) if (length(position) >= m_deadzone)
{ {
dc.SetPen(*red); dc.SetPen(red);
dc.SetBrush(*red_brush); dc.SetBrush(red_brush);
if (std::abs(1.0f - length(position)) < 0.05f) if (std::abs(1.0f - length(position)) < 0.05f)
{ {
dc.SetPen(wxPen(wxColour(0x336600))); dc.SetPen(green);
dc.SetBrush(wxColour(0x336600)); dc.SetBrush(green_brush);
} }
} }
else else
{ {
dc.SetPen(*black); dc.SetPen(black);
dc.SetBrush(*black_brush); dc.SetBrush(black_brush);
} }
} }
else else
{ {
dc.SetPen(*red); dc.SetPen(red);
dc.SetBrush(*red_brush); dc.SetBrush(red_brush);
} }
// draw axis // draw axis

View file

@ -4,13 +4,15 @@
wxDEFINE_EVENT(EVT_ON_LIST_UPDATED, wxEvent); wxDEFINE_EVENT(EVT_ON_LIST_UPDATED, wxEvent);
wxLogCtrl::wxLogCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style) wxLogCtrl::wxLogCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, bool alternateRowColours)
: TextList(parent, id, pos, size, style) : TextList(parent, id, pos, size, style)
{ {
m_timer = new wxTimer(this); m_timer = new wxTimer(this);
this->Bind(wxEVT_TIMER, &wxLogCtrl::OnTimer, this); this->Bind(wxEVT_TIMER, &wxLogCtrl::OnTimer, this);
this->Bind(EVT_ON_LIST_UPDATED, &wxLogCtrl::OnActiveListUpdated, this); this->Bind(EVT_ON_LIST_UPDATED, &wxLogCtrl::OnActiveListUpdated, this);
m_timer->Start(250); m_timer->Start(250);
m_alternateRowColoursEnabled = alternateRowColours;
} }
wxLogCtrl::~wxLogCtrl() wxLogCtrl::~wxLogCtrl()
@ -93,15 +95,13 @@ void wxLogCtrl::OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& star
for (sint32 i = 0; i <= count && it != m_active_entries.cend(); ++i, ++it) for (sint32 i = 0; i <= count && it != m_active_entries.cend(); ++i, ++it)
{ {
wxColour background_colour; wxColour background_colour = GetBackgroundColour();
if((start + i) % 2 == 0) if((start + i) % 2 != 0 && m_alternateRowColoursEnabled)
background_colour = COLOR_WHITE; background_colour = GetAlternateRowColour();
else
background_colour = 0xFFFDF9F2;
DrawLineBackground(dc, position, background_colour); DrawLineBackground(dc, position, background_colour);
dc.SetTextForeground(COLOR_BLACK); dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
dc.DrawText(it->get().second, position); dc.DrawText(it->get().second, position);
NextLine(position, &start_position); NextLine(position, &start_position);

View file

@ -4,7 +4,7 @@
class wxLogCtrl : public TextList class wxLogCtrl : public TextList
{ {
public: public:
wxLogCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style); wxLogCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, bool alternateRowColours = false);
~wxLogCtrl(); ~wxLogCtrl();
void SetActiveFilter(const std::string& active_filter); void SetActiveFilter(const std::string& active_filter);
@ -23,6 +23,22 @@ private:
wxTimer* m_timer; wxTimer* m_timer;
bool m_alternateRowColoursEnabled = false;
wxColour m_alternateRowColour;
wxColour GetAlternateRowColour()
{
if (m_alternateRowColour.IsOk())
return m_alternateRowColour;
// Depending on the background, alternate row colour should be a bit
// darker or brighter.
const wxColour bgColour = GetBackgroundColour();
int alpha = bgColour.GetRGB() > 0x808080 ? 97 : 110;
m_alternateRowColour = bgColour.ChangeLightness(alpha);
return m_alternateRowColour;
}
std::string m_active_filter; std::string m_active_filter;
std::thread m_update_worker; std::thread m_update_worker;
bool m_filter_messages = false; bool m_filter_messages = false;

View file

@ -30,12 +30,10 @@ BreakpointWindow::BreakpointWindow(DebuggerWindow2& parent, const wxPoint& main_
{ {
this->SetSizeHints(wxDefaultSize, wxDefaultSize); this->SetSizeHints(wxDefaultSize, wxDefaultSize);
this->wxWindowBase::SetBackgroundColour(*wxWHITE);
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
m_breakpoints = new wxCheckedListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT); m_breakpoints = new wxListView(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
m_breakpoints->EnableCheckBoxes(true);
wxListItem col0; wxListItem col0;
col0.SetId(ColumnEnabled); col0.SetId(ColumnEnabled);
@ -71,8 +69,8 @@ BreakpointWindow::BreakpointWindow(DebuggerWindow2& parent, const wxPoint& main_
if (parent.GetConfig().data().pin_to_main) if (parent.GetConfig().data().pin_to_main)
OnMainMove(main_position, main_size); OnMainMove(main_position, main_size);
m_breakpoints->Bind(wxEVT_COMMAND_LIST_ITEM_CHECKED, (wxObjectEventFunction)&BreakpointWindow::OnBreakpointToggled, this); m_breakpoints->Bind(wxEVT_LIST_ITEM_CHECKED, &BreakpointWindow::OnBreakpointToggled, this);
m_breakpoints->Bind(wxEVT_COMMAND_LIST_ITEM_UNCHECKED, (wxObjectEventFunction)&BreakpointWindow::OnBreakpointToggled, this); m_breakpoints->Bind(wxEVT_LIST_ITEM_UNCHECKED, &BreakpointWindow::OnBreakpointToggled, this);
m_breakpoints->Bind(wxEVT_LEFT_DCLICK, &BreakpointWindow::OnLeftDClick, this); m_breakpoints->Bind(wxEVT_LEFT_DCLICK, &BreakpointWindow::OnLeftDClick, this);
m_breakpoints->Bind(wxEVT_RIGHT_DOWN, &BreakpointWindow::OnRightDown, this); m_breakpoints->Bind(wxEVT_RIGHT_DOWN, &BreakpointWindow::OnRightDown, this);
@ -81,8 +79,10 @@ BreakpointWindow::BreakpointWindow(DebuggerWindow2& parent, const wxPoint& main_
BreakpointWindow::~BreakpointWindow() BreakpointWindow::~BreakpointWindow()
{ {
m_breakpoints->Unbind(wxEVT_COMMAND_LIST_ITEM_CHECKED, (wxObjectEventFunction)&BreakpointWindow::OnBreakpointToggled, this); m_breakpoints->Unbind(wxEVT_LIST_ITEM_CHECKED, &BreakpointWindow::OnBreakpointToggled, this);
m_breakpoints->Unbind(wxEVT_COMMAND_LIST_ITEM_UNCHECKED, (wxObjectEventFunction)&BreakpointWindow::OnBreakpointToggled, this); m_breakpoints->Unbind(wxEVT_LIST_ITEM_UNCHECKED, &BreakpointWindow::OnBreakpointToggled, this);
m_breakpoints->Unbind(wxEVT_LEFT_DCLICK, &BreakpointWindow::OnLeftDClick, this);
m_breakpoints->Unbind(wxEVT_RIGHT_DOWN, &BreakpointWindow::OnRightDown, this);
} }
void BreakpointWindow::OnMainMove(const wxPoint& main_position, const wxSize& main_size) void BreakpointWindow::OnMainMove(const wxPoint& main_position, const wxSize& main_size)
@ -107,11 +107,10 @@ void BreakpointWindow::OnUpdateView()
uint32_t i = 0; uint32_t i = 0;
for (const auto bpBase : debuggerState.breakpoints) for (const auto bpBase : debuggerState.breakpoints)
{ {
DebuggerBreakpoint* bp = bpBase; DebuggerBreakpoint* bp = bpBase;
while (bp) while (bp)
{ {
wxListItem item; wxListItem item = {};
item.SetId(i++); item.SetId(i++);
const auto index = m_breakpoints->InsertItem(item); const auto index = m_breakpoints->InsertItem(item);
@ -130,12 +129,11 @@ void BreakpointWindow::OnUpdateView()
m_breakpoints->SetItem(index, ColumnType, typeName); m_breakpoints->SetItem(index, ColumnType, typeName);
m_breakpoints->SetItem(index, ColumnComment, bp->comment); m_breakpoints->SetItem(index, ColumnComment, bp->comment);
m_breakpoints->SetItemPtrData(item, (wxUIntPtr)bp); m_breakpoints->CheckItem(index, bp->enabled);
m_breakpoints->Check(index, bp->enabled); m_breakpoints->SetItemPtrData(index, (wxUIntPtr)bp);
bp = bp->next; bp = bp->next;
} }
} }
} }
@ -152,11 +150,12 @@ void BreakpointWindow::OnBreakpointToggled(wxListEvent& event)
const int32_t index = event.GetIndex(); const int32_t index = event.GetIndex();
if (0 <= index && index < m_breakpoints->GetItemCount()) if (0 <= index && index < m_breakpoints->GetItemCount())
{ {
const bool state = m_breakpoints->IsChecked(index); const bool state = m_breakpoints->IsItemChecked(index);
wxString line = m_breakpoints->GetItemText(index, ColumnAddress); wxString line = m_breakpoints->GetItemText(index, ColumnAddress);
DebuggerBreakpoint* bp = (DebuggerBreakpoint*)m_breakpoints->GetItemData(index); DebuggerBreakpoint* bp = (DebuggerBreakpoint*)m_breakpoints->GetItemData(index);
const uint32 address = std::stoul(line.c_str().AsChar(), nullptr, 16); const uint32 address = std::stoul(line.c_str().AsChar(), nullptr, 16);
debugger_toggleBreakpoint(address, state, bp); debugger_toggleBreakpoint(address, state, bp);
m_breakpoints->CheckItem(index, state);
} }
} }

View file

@ -1,5 +1,4 @@
#pragma once #pragma once
#include "wxgui/wxcomponents/checkedlistctrl.h"
class DebuggerWindow2; class DebuggerWindow2;
@ -21,5 +20,5 @@ private:
void OnContextMenuClick(wxCommandEvent& evt); void OnContextMenuClick(wxCommandEvent& evt);
void OnContextMenuClickSelected(wxCommandEvent& evt); void OnContextMenuClickSelected(wxCommandEvent& evt);
wxCheckedListCtrl* m_breakpoints; wxListView* m_breakpoints;
}; };

View file

@ -1,6 +1,8 @@
#include "wxgui/wxgui.h" #include "wxgui/wxgui.h"
#include "wxgui/debugger/DebuggerWindow2.h" #include "wxgui/debugger/DebuggerWindow2.h"
#include "wxHelper.h"
#include <filesystem> #include <filesystem>
#include "config/ActiveSettings.h" #include "config/ActiveSettings.h"
@ -220,18 +222,22 @@ void DebuggerWindow2::CreateToolBar()
m_toolbar = wxFrame::CreateToolBar(wxTB_HORIZONTAL, wxID_ANY); m_toolbar = wxFrame::CreateToolBar(wxTB_HORIZONTAL, wxID_ANY);
m_toolbar->SetToolBitmapSize(wxSize(16, 16)); m_toolbar->SetToolBitmapSize(wxSize(16, 16));
m_toolbar->AddTool(TOOL_ID_GOTO, wxEmptyString, wxBITMAP_PNG_FROM_DATA(DEBUGGER_GOTO), wxNullBitmap, wxITEM_NORMAL, _("GoTo (CTRL + G)"), "test", NULL); wxBitmap goto_bitmap = wxHelper::LoadThemedBitmapFromPNG(DEBUGGER_GOTO_png, sizeof(DEBUGGER_GOTO_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
m_toolbar->AddTool(TOOL_ID_GOTO, wxEmptyString, goto_bitmap, wxNullBitmap, wxITEM_NORMAL, _("GoTo (CTRL + G)"), "test", NULL);
m_toolbar->AddSeparator(); m_toolbar->AddSeparator();
m_toolbar->AddTool(TOOL_ID_BP, wxEmptyString, wxBITMAP_PNG_FROM_DATA(DEBUGGER_BP_RED), wxNullBitmap, wxITEM_NORMAL, _("Toggle Breakpoint (F9)"), wxEmptyString, NULL); wxBitmap bp_bitmap = wxHelper::LoadThemedBitmapFromPNG(DEBUGGER_BP_RED_png, sizeof(DEBUGGER_BP_RED_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
m_toolbar->AddTool(TOOL_ID_BP, wxEmptyString, bp_bitmap, wxNullBitmap, wxITEM_NORMAL, _("Toggle Breakpoint (F9)"), wxEmptyString, NULL);
m_toolbar->AddSeparator(); m_toolbar->AddSeparator();
m_pause = wxBITMAP_PNG_FROM_DATA(DEBUGGER_PAUSE); m_pause = wxHelper::LoadThemedBitmapFromPNG(DEBUGGER_PAUSE_png, sizeof(DEBUGGER_PAUSE_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
m_run = wxBITMAP_PNG_FROM_DATA(DEBUGGER_PLAY); m_run = wxHelper::LoadThemedBitmapFromPNG(DEBUGGER_PLAY_png, sizeof(DEBUGGER_PLAY_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
m_toolbar->AddTool(TOOL_ID_PAUSE, wxEmptyString, m_pause, wxNullBitmap, wxITEM_NORMAL, _("Break (F5)"), wxEmptyString, NULL); m_toolbar->AddTool(TOOL_ID_PAUSE, wxEmptyString, m_pause, wxNullBitmap, wxITEM_NORMAL, _("Break (F5)"), wxEmptyString, NULL);
m_toolbar->AddTool(TOOL_ID_STEP_INTO, wxEmptyString, wxBITMAP_PNG_FROM_DATA(DEBUGGER_STEP_INTO), wxNullBitmap, wxITEM_NORMAL, _("Step Into (F11)"), wxEmptyString, NULL); wxBitmap step_into_bitmap = wxHelper::LoadThemedBitmapFromPNG(DEBUGGER_STEP_INTO_png, sizeof(DEBUGGER_STEP_INTO_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
m_toolbar->AddTool(TOOL_ID_STEP_OVER, wxEmptyString, wxBITMAP_PNG_FROM_DATA(DEBUGGER_STEP_OVER), wxNullBitmap, wxITEM_NORMAL, _("Step Over (F10)"), wxEmptyString, NULL); wxBitmap step_over_bitmap = wxHelper::LoadThemedBitmapFromPNG(DEBUGGER_STEP_OVER_png, sizeof(DEBUGGER_STEP_OVER_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
m_toolbar->AddTool(TOOL_ID_STEP_INTO, wxEmptyString, step_into_bitmap, wxNullBitmap, wxITEM_NORMAL, _("Step Into (F11)"), wxEmptyString, NULL);
m_toolbar->AddTool(TOOL_ID_STEP_OVER, wxEmptyString, step_over_bitmap, wxNullBitmap, wxITEM_NORMAL, _("Step Over (F10)"), wxEmptyString, NULL);
m_toolbar->AddSeparator(); m_toolbar->AddSeparator();
m_toolbar->Realize(); m_toolbar->Realize();
@ -272,8 +278,6 @@ DebuggerWindow2::DebuggerWindow2(wxFrame& parent, const wxRect& display_size)
{ {
g_debuggerDispatcher.SetDebuggerCallbacks(this); g_debuggerDispatcher.SetDebuggerCallbacks(this);
this->wxWindowBase::SetBackgroundColour(*wxWHITE);
const auto file = ActiveSettings::GetConfigPath("debugger/config.xml"); const auto file = ActiveSettings::GetConfigPath("debugger/config.xml");
m_config.SetFilename(file.generic_wstring()); m_config.SetFilename(file.generic_wstring());
m_config.Load(); m_config.Load();
@ -311,7 +315,6 @@ DebuggerWindow2::DebuggerWindow2(wxFrame& parent, const wxRect& display_size)
} }
m_module_label = new wxStaticText(this, wxID_ANY, label_text); m_module_label = new wxStaticText(this, wxID_ANY, label_text);
m_module_label->SetBackgroundColour(*wxWHITE);
m_module_label->SetForegroundColour(wxColour(0xFFbf52fe)); m_module_label->SetForegroundColour(wxColour(0xFFbf52fe));
main_sizer->Add(m_module_label, 0, wxEXPAND | wxALL, 5); main_sizer->Add(m_module_label, 0, wxEXPAND | wxALL, 5);

View file

@ -8,6 +8,7 @@
#include <wx/bitmap.h> #include <wx/bitmap.h>
#include <wx/frame.h> #include <wx/frame.h>
#include <wx/mstream.h>
class BreakpointWindow; class BreakpointWindow;
class RegisterWindow; class RegisterWindow;
@ -56,6 +57,14 @@ struct DebuggerModuleStorage
}; };
typedef XMLDataConfig<DebuggerModuleStorage> XMLDebuggerModuleConfig; typedef XMLDataConfig<DebuggerModuleStorage> XMLDebuggerModuleConfig;
static wxBitmap LoadThemedBitmapFromPNG(const uint8* data, size_t size, const wxColour& tint)
{
wxMemoryInputStream strm(data, size);
wxImage img(strm, wxBITMAP_TYPE_PNG);
img.Replace(0x00, 0x00, 0x00, tint.Red(), tint.Green(), tint.Blue());
return wxBitmap(img);
}
class DebuggerWindow2 : public wxFrame, public DebuggerCallbacks class DebuggerWindow2 : public wxFrame, public DebuggerCallbacks
{ {
public: public:

View file

@ -1,6 +1,7 @@
#include "wxgui/wxgui.h" #include "wxgui/wxgui.h"
#include "wxgui/debugger/DisasmCtrl.h" #include "wxgui/debugger/DisasmCtrl.h"
#include "wxHelper.h"
#include "Cafe/OS/RPL/rpl_structs.h" #include "Cafe/OS/RPL/rpl_structs.h"
#include "Cafe/OS/RPL/rpl.h" #include "Cafe/OS/RPL/rpl.h"
#include "Cafe/OS/RPL/rpl_symbol_storage.h" #include "Cafe/OS/RPL/rpl_symbol_storage.h"
@ -12,35 +13,13 @@
#include "Cemu/ExpressionParser/ExpressionParser.h" #include "Cemu/ExpressionParser/ExpressionParser.h"
#include "Cafe/HW/Espresso/Debugger/DebugSymbolStorage.h" #include "Cafe/HW/Espresso/Debugger/DebugSymbolStorage.h"
#include <wx/mstream.h> // for wxMemoryInputStream
wxDEFINE_EVENT(wxEVT_DISASMCTRL_NOTIFY_GOTO_ADDRESS, wxCommandEvent); wxDEFINE_EVENT(wxEVT_DISASMCTRL_NOTIFY_GOTO_ADDRESS, wxCommandEvent);
#define MAX_SYMBOL_LEN (120) #define MAX_SYMBOL_LEN (120)
#define COLOR_DEBUG_ACTIVE_BP 0xFFFFA0FF
#define COLOR_DEBUG_ACTIVE 0xFFFFA080
#define COLOR_DEBUG_BP 0xFF8080FF
#define SYNTAX_COLOR_GPR 0xFF000066 constexpr uint8 arrowRightPNG[] =
#define SYNTAX_COLOR_FPR 0xFF006666
#define SYNTAX_COLOR_SPR 0xFF666600
#define SYNTAX_COLOR_CR 0xFF666600
#define SYNTAX_COLOR_IMM 0xFF006600
#define SYNTAX_COLOR_IMM_OFFSET 0xFF006600
#define SYNTAX_COLOR_CIMM 0xFF880000
#define SYNTAX_COLOR_PSEUDO 0xFFA0A0A0 // color for pseudo code
#define SYNTAX_COLOR_SYMBOL 0xFF0000A0 // color for function symbol
#define OFFSET_ADDRESS (60)
#define OFFSET_ADDRESS_RELATIVE (90)
#define OFFSET_DISASSEMBLY (300)
#define OFFSET_DISASSEMBLY_OPERAND (80)
wxBitmap* g_ipArrowBitmap = nullptr;
uint8 _arrowRightPNG[] =
{ {
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0B, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0B,
@ -59,17 +38,86 @@ uint8 _arrowRightPNG[] =
0x73, 0x8D, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x73, 0x8D, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
0x42, 0x60, 0x82 0x42, 0x60, 0x82
}; };
std::optional<wxBitmap> g_ipArrowBitmap;
static wxColour theme_textForeground;
static wxColour theme_textForegroundMuted;
static wxColour theme_background;
// background colors for lines in the disassembly view
static wxColour theme_lineBreakpointAndCurrentInstruction;
static wxColour theme_lineCurrentInstruction;
static wxColour theme_lineBreakpointSet;
static wxColour theme_lineLoggingBreakpointSet;
static wxColour theme_lineLastGotoAddress;
// text colors for addresses in the disassembly view
static wxColour theme_syntaxGPR;
static wxColour theme_syntaxFPR;
static wxColour theme_syntaxSPR;
static wxColour theme_syntaxCR;
static wxColour theme_syntaxIMM;
static wxColour theme_syntaxIMMOffset;
static wxColour theme_syntaxCallIMM;
static wxColour theme_syntaxPseudoOrUnknown;
static wxColour theme_syntaxSymbol;
static wxColour theme_opCode;
static wxColour theme_typeData;
static wxColour theme_patchedOpCode;
static wxColour theme_patchedData;
static void InitSyntaxColors()
{
theme_textForeground = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
theme_textForegroundMuted = wxSystemSettings::GetAppearance().IsDark() ? wxColour(140,142,145) : wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
theme_background = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
// line background highlights
theme_lineBreakpointSet = wxSystemSettings::SelectLightDark(wxColour(0xFF,0x80,0x80), wxColour(0x84,0x21,0x21)); // red for a non-current breakpoint
theme_lineBreakpointAndCurrentInstruction = wxSystemSettings::SelectLightDark(wxColour(0xD2,0x7E,0xD2), wxColour(0x91,0x44,0xA4)); // pink for a current breakpoint
theme_lineCurrentInstruction = wxSystemSettings::SelectLightDark(wxColour(0xFF,0xA0,0x80), wxColour(0x87,0x53,0x1A)); // light orange
theme_lineLoggingBreakpointSet = wxSystemSettings::SelectLightDark(wxColour(0xAB,0xED,0xEE), wxColour(0x25,0x5D,0x6D)); // light blue
theme_lineLastGotoAddress = wxSystemSettings::SelectLightDark(wxColour(0xE0,0xE0,0xE0), wxColour(0x40,0x40,0x40)); // very light gray to indicate the line that was last jumped to
// disassembly syntax colors
theme_syntaxGPR = wxSystemSettings::SelectLightDark(wxColour(0x66,0x00,0x00), wxColour(0xE0,0x6C,0x75));
theme_syntaxFPR = wxSystemSettings::SelectLightDark(wxColour(0x66,0x66,0x00), wxColour(0xD1,0x9A,0x66));
theme_syntaxSPR = wxSystemSettings::SelectLightDark(wxColour(0x00,0x66,0x66), wxColour(0x56,0xB6,0xC2));
theme_syntaxCR = wxSystemSettings::SelectLightDark(wxColour(0x00,0x66,0x66), wxColour(0x56,0xB6,0xC2));
theme_syntaxIMM = wxSystemSettings::SelectLightDark(wxColour(0x00,0x66,0x00), wxColour(0x9D,0xDE,0x6F));
theme_syntaxIMMOffset = wxSystemSettings::SelectLightDark(wxColour(0x00,0x66,0x00), wxColour(0x9D,0xDE,0x6F));
theme_syntaxCallIMM = wxSystemSettings::SelectLightDark(wxColour(0x00,0x00,0x88), wxColour(0x61,0xAF,0xEF));
theme_syntaxPseudoOrUnknown = wxSystemSettings::SelectLightDark(wxColour(0xA0,0xA0,0xA0), wxColour(0x5C,0x63,0x70));
theme_syntaxSymbol = wxSystemSettings::SelectLightDark(wxColour(0xA0,0x00,0x00), wxColour(0xE0,0x6C,0x75));
// opcode & data highlighting
theme_opCode = wxSystemSettings::SelectLightDark(wxColour(0xFF,0x00,0x40), wxColour(0xFF,0x70,0x7B));
theme_patchedOpCode = wxSystemSettings::SelectLightDark(wxColour(0xFF,0x20,0x20), wxColour(0xCC,0x52,0xF5));
theme_typeData = wxSystemSettings::SelectLightDark(wxColour(0xFF,0x20,0x20), wxColour(0xCE,0x91,0x78));
theme_patchedData = wxSystemSettings::SelectLightDark(wxColour(0xFF,0x20,0x20), wxColour(0xF4,0x43,0x36));
// theme the current instruction pointer arrow
g_ipArrowBitmap = wxHelper::LoadThemedBitmapFromPNG(arrowRightPNG, sizeof(arrowRightPNG), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
}
#define OFFSET_ADDRESS (60)
#define OFFSET_ADDRESS_RELATIVE (90)
#define OFFSET_DISASSEMBLY (300)
#define OFFSET_DISASSEMBLY_OPERAND (80)
DisasmCtrl::DisasmCtrl(wxWindow* parent, const wxWindowID& id, const wxPoint& pos, const wxSize& size, long style) DisasmCtrl::DisasmCtrl(wxWindow* parent, const wxWindowID& id, const wxPoint& pos, const wxSize& size, long style)
: TextList(parent, id, pos, size, style), m_mouse_line(-1), m_mouse_line_drawn(-1), m_active_line(-1) : TextList(parent, id, pos, size, style), m_mouse_line(-1), m_mouse_line_drawn(-1), m_active_line(-1)
{ {
Init(); Init();
if (!g_ipArrowBitmap) if (!g_ipArrowBitmap.has_value())
{ {
wxMemoryInputStream strm(_arrowRightPNG, sizeof(_arrowRightPNG)); InitSyntaxColors();
wxImage img(strm, wxBITMAP_TYPE_PNG);
g_ipArrowBitmap = new wxBitmap(img);
} }
auto tooltip_sizer = new wxBoxSizer(wxVERTICAL); auto tooltip_sizer = new wxBoxSizer(wxVERTICAL);
@ -106,8 +154,8 @@ void DisasmCtrl::SelectCodeRegion(uint32 newAddress)
// update line tracking // update line tracking
sint32 element_count = currentCodeRegionEnd - currentCodeRegionStart; sint32 element_count = currentCodeRegionEnd - currentCodeRegionStart;
if (element_count <= 0x00010000) // if (element_count <= 0x00010000)
element_count = 0x00010000; // element_count = 0x00010000;
if (this->SetElementCount(element_count / 4)) if (this->SetElementCount(element_count / 4))
{ {
@ -146,23 +194,23 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR
// write virtual address // write virtual address
wxColour background_colour; wxColour background_colour;
if (is_active_bp && bp != nullptr) if (is_active_bp && bp != nullptr)
background_colour = wxColour(0xFFFFA0FF); background_colour = theme_lineBreakpointAndCurrentInstruction;
else if (is_active_bp) else if (is_active_bp)
background_colour = wxColour(0xFF80A0FF); background_colour = theme_lineCurrentInstruction;
else if (bp != nullptr) else if (bp != nullptr)
background_colour = wxColour(bp->bpType == DEBUGGER_BP_T_NORMAL ? 0xFF8080FF : 0x80FFFFFF); background_colour = bp->bpType == DEBUGGER_BP_T_NORMAL ? theme_lineBreakpointSet : theme_lineLoggingBreakpointSet;
else if(virtualAddress == m_lastGotoTarget) else if(virtualAddress == m_lastGotoTarget)
background_colour = wxColour(0xFFE0E0E0); background_colour = theme_lineLastGotoAddress;
else else
background_colour = wxColour(COLOR_WHITE); background_colour = theme_background;
DrawLineBackground(dc, position, background_colour); DrawLineBackground(dc, position, background_colour);
dc.SetTextForeground(COLOR_BLACK); dc.SetTextForeground(theme_textForeground);
dc.DrawText(wxString::Format("%08x", virtualAddress), position); dc.DrawText(wxString::Format("%08x", virtualAddress), position);
position.x += OFFSET_ADDRESS; position.x += OFFSET_ADDRESS;
dc.SetTextForeground(COLOR_GREY); dc.SetTextForeground(theme_textForegroundMuted);
if (rplModule) if (rplModule)
dc.DrawText(wxString::Format("+0x%-8x", virtualAddress - rplModule->regionMappingBase_text.GetMPTR()), position); dc.DrawText(wxString::Format("+0x%-8x", virtualAddress - rplModule->regionMappingBase_text.GetMPTR()), position);
else else
@ -178,29 +226,29 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR
auto debugSymbolDataType = DebugSymbolStorage::GetDataType(virtualAddress); auto debugSymbolDataType = DebugSymbolStorage::GetDataType(virtualAddress);
if (debugSymbolDataType == DEBUG_SYMBOL_TYPE::FLOAT) if (debugSymbolDataType == DEBUG_SYMBOL_TYPE::FLOAT)
{ {
dc.SetTextForeground(hasPatch ? wxColour(0xFF2020FF) : wxColour(0xFF400000)); dc.SetTextForeground(hasPatch ? theme_patchedData : theme_typeData);
dc.DrawText(fmt::format(".float"), position); dc.DrawText(fmt::format(".float"), position);
position.x += OFFSET_DISASSEMBLY_OPERAND; position.x += OFFSET_DISASSEMBLY_OPERAND;
dc.SetTextForeground(hasPatch ? wxColour(0xFF2020FF) : wxColour(SYNTAX_COLOR_IMM)); dc.SetTextForeground(hasPatch ? theme_patchedData : theme_syntaxIMM);
dc.DrawText(fmt::format("{}", memory_readFloat(virtualAddress)), position); dc.DrawText(fmt::format("{}", memory_readFloat(virtualAddress)), position);
return; return;
} }
else if (debugSymbolDataType == DEBUG_SYMBOL_TYPE::U32) else if (debugSymbolDataType == DEBUG_SYMBOL_TYPE::U32)
{ {
dc.SetTextForeground(hasPatch ? wxColour(0xFF2020FF) : wxColour(0xFF400000)); dc.SetTextForeground(hasPatch ? theme_patchedData : theme_typeData);
dc.DrawText(fmt::format(".uint"), position); dc.DrawText(fmt::format(".uint"), position);
position.x += OFFSET_DISASSEMBLY_OPERAND; position.x += OFFSET_DISASSEMBLY_OPERAND;
dc.SetTextForeground(hasPatch ? wxColour(0xFF2020FF) : wxColour(SYNTAX_COLOR_IMM)); dc.SetTextForeground(hasPatch ? theme_patchedData : theme_syntaxIMM);
dc.DrawText(fmt::format("{}", memory_readU32(virtualAddress)), position); dc.DrawText(fmt::format("{}", memory_readU32(virtualAddress)), position);
return; return;
} }
sint32 start_width = position.x; sint32 start_width = position.x;
dc.SetTextForeground(hasPatch ? wxColour(0xFF2020FF) : wxColour(0xFF400000)); dc.SetTextForeground(hasPatch ? theme_patchedOpCode : theme_opCode);
char opName[32]; char opName[32];
strcpy(opName, ppcAssembler_getInstructionName(disasmInstr.ppcAsmCode)); strcpy(opName, ppcAssembler_getInstructionName(disasmInstr.ppcAsmCode));
std::transform(opName, opName + sizeof(opName), opName, tolower); std::transform(opName, opName + sizeof(opName), opName, tolower);
@ -221,7 +269,7 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR
if (disasmInstr.ppcAsmCode == PPCASM_OP_UKN) if (disasmInstr.ppcAsmCode == PPCASM_OP_UKN)
{ {
// show raw bytes // show raw bytes
WriteText(dc, wxString::Format("%02x %02x %02x %02x", (opcode >> 24) & 0xFF, (opcode >> 16) & 0xFF, (opcode >> 8) & 0xFF, (opcode >> 0) & 0xFF), position, SYNTAX_COLOR_PSEUDO); WriteText(dc, wxString::Format("%02x %02x %02x %02x", (opcode >> 24) & 0xFF, (opcode >> 16) & 0xFF, (opcode >> 8) & 0xFF, (opcode >> 0) & 0xFF), position, theme_syntaxPseudoOrUnknown);
} }
bool is_first_operand = true; bool is_first_operand = true;
@ -231,25 +279,25 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR
continue; continue;
if (!is_first_operand) if (!is_first_operand)
WriteText(dc, ", ", position, COLOR_BLACK); WriteText(dc, ", ", position, theme_textForeground);
is_first_operand = false; is_first_operand = false;
switch (disasmInstr.operand[o].type) switch (disasmInstr.operand[o].type)
{ {
case PPCASM_OPERAND_TYPE_GPR: case PPCASM_OPERAND_TYPE_GPR:
WriteText(dc, wxString::Format("r%d", disasmInstr.operand[o].registerIndex), position, SYNTAX_COLOR_GPR); WriteText(dc, wxString::Format("r%d", disasmInstr.operand[o].registerIndex), position, theme_syntaxGPR);
break; break;
case PPCASM_OPERAND_TYPE_FPR: case PPCASM_OPERAND_TYPE_FPR:
WriteText(dc, wxString::Format("f%d", disasmInstr.operand[o].registerIndex), position, SYNTAX_COLOR_FPR); WriteText(dc, wxString::Format("f%d", disasmInstr.operand[o].registerIndex), position, theme_syntaxFPR);
break; break;
case PPCASM_OPERAND_TYPE_SPR: case PPCASM_OPERAND_TYPE_SPR:
WriteText(dc, wxString::Format("spr%d", disasmInstr.operand[o].registerIndex), position, SYNTAX_COLOR_SPR); WriteText(dc, wxString::Format("spr%d", disasmInstr.operand[o].registerIndex), position, theme_syntaxSPR);
break; break;
case PPCASM_OPERAND_TYPE_CR: case PPCASM_OPERAND_TYPE_CR:
WriteText(dc, wxString::Format("cr%d", disasmInstr.operand[o].registerIndex), position, SYNTAX_COLOR_CR); WriteText(dc, wxString::Format("cr%d", disasmInstr.operand[o].registerIndex), position, theme_syntaxCR);
break; break;
case PPCASM_OPERAND_TYPE_IMM: case PPCASM_OPERAND_TYPE_IMM:
@ -280,16 +328,15 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR
string = wxString::Format("0x%x", uImm); string = wxString::Format("0x%x", uImm);
} }
WriteText(dc, string, position, theme_syntaxIMM);
WriteText(dc, string, position, SYNTAX_COLOR_IMM);
break; break;
} }
case PPCASM_OPERAND_TYPE_PSQMODE: case PPCASM_OPERAND_TYPE_PSQMODE:
{ {
if (disasmInstr.operand[o].immS32) if (disasmInstr.operand[o].immS32)
WriteText(dc, "single", position, SYNTAX_COLOR_IMM); WriteText(dc, "single", position, theme_syntaxIMM);
else else
WriteText(dc, "paired", position, SYNTAX_COLOR_IMM); WriteText(dc, "paired", position, theme_syntaxIMM);
break; break;
} }
case PPCASM_OPERAND_TYPE_CIMM: case PPCASM_OPERAND_TYPE_CIMM:
@ -322,7 +369,7 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR
string = wxString::Format("0x%08x", disasmInstr.operand[o].immU32); string = wxString::Format("0x%08x", disasmInstr.operand[o].immU32);
} }
WriteText(dc, string, position, SYNTAX_COLOR_CIMM); WriteText(dc, string, position, theme_syntaxCallIMM);
if (disasmInstr.ppcAsmCode != PPCASM_OP_BL) if (disasmInstr.ppcAsmCode != PPCASM_OP_BL)
{ {
@ -332,7 +379,7 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR
else else
x.Append(wxUniChar(0x2193)); // arrow down x.Append(wxUniChar(0x2193)); // arrow down
WriteText(dc, x, position, COLOR_BLACK); WriteText(dc, x, position, theme_textForeground);
} }
break; break;
@ -346,12 +393,12 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR
else else
string = wxString::Format("-0x%x", -disasmInstr.operand[o].immS32); string = wxString::Format("-0x%x", -disasmInstr.operand[o].immS32);
WriteText(dc, string, position, SYNTAX_COLOR_IMM_OFFSET); WriteText(dc, string, position, theme_syntaxIMMOffset);
WriteText(dc, "(", position, COLOR_BLACK); WriteText(dc, "(", position, theme_textForeground);
// register // register
WriteText(dc, wxString::Format("r%d", disasmInstr.operand[o].registerIndex), position, SYNTAX_COLOR_GPR); WriteText(dc, wxString::Format("r%d", disasmInstr.operand[o].registerIndex), position, theme_syntaxGPR);
WriteText(dc, ")", position, COLOR_BLACK); WriteText(dc, ")", position, theme_textForeground);
break; break;
} }
default: default:
@ -363,7 +410,7 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR
position.x = start_width + OFFSET_DISASSEMBLY; position.x = start_width + OFFSET_DISASSEMBLY;
const auto comment = static_cast<rplDebugSymbolComment*>(rplDebugSymbol_getForAddress(virtualAddress)); const auto comment = static_cast<rplDebugSymbolComment*>(rplDebugSymbol_getForAddress(virtualAddress));
if (comment && comment->type == RplDebugSymbolComment) if (comment && comment->type == RplDebugSymbolComment)
WriteText(dc, comment->comment, position, COLOR_BLACK); WriteText(dc, comment->comment, position, theme_textForeground);
else if (isRLWINM) else if (isRLWINM)
{ {
sint32 rS, rA, SH, MB, ME; sint32 rS, rA, SH, MB, ME;
@ -384,7 +431,7 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR
string = wxString::Format("r%d=r%d>>%d", rA, rS, 32 - SH); string = wxString::Format("r%d=r%d>>%d", rA, rS, 32 - SH);
else else
string = wxString::Format("r%d=(r%d<<<%d)&0x%x", rA, rS, SH, mask); string = wxString::Format("r%d=(r%d<<<%d)&0x%x", rA, rS, SH, mask);
WriteText(dc, string, position, COLOR_GREY); WriteText(dc, string, position, theme_textForegroundMuted);
} }
else if (disasmInstr.ppcAsmCode == PPCASM_OP_SUBF || disasmInstr.ppcAsmCode == PPCASM_OP_SUBF_) else if (disasmInstr.ppcAsmCode == PPCASM_OP_SUBF || disasmInstr.ppcAsmCode == PPCASM_OP_SUBF_)
{ {
@ -395,7 +442,7 @@ void DisasmCtrl::DrawDisassemblyLine(wxDC& dc, const wxPoint& linePosition, MPTR
wxString string; wxString string;
string = wxString::Format("r%d=r%d-r%d", rD, rB, rA); string = wxString::Format("r%d=r%d-r%d", rD, rB, rA);
WriteText(dc, string, position, COLOR_GREY); WriteText(dc, string, position, theme_textForegroundMuted);
} }
} }
@ -408,7 +455,7 @@ void DisasmCtrl::DrawLabelName(wxDC& dc, const wxPoint& linePosition, MPTR virtu
symbol_string.Append("..:"); symbol_string.Append("..:");
} }
wxPoint tmpPos(linePosition); wxPoint tmpPos(linePosition);
WriteText(dc, symbol_string, tmpPos, SYNTAX_COLOR_SYMBOL); WriteText(dc, symbol_string, tmpPos, theme_syntaxSymbol);
} }
void DisasmCtrl::OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start_position) void DisasmCtrl::OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start_position)

View file

@ -30,8 +30,6 @@ public:
void CenterOffset(uint32 offset); void CenterOffset(uint32 offset);
void GoToAddressDialog(); void GoToAddressDialog();
protected: protected:
void OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start_position) override; void OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start_position) override;
void OnMouseMove(const wxPoint& position, uint32 line) override; void OnMouseMove(const wxPoint& position, uint32 line) override;

View file

@ -7,31 +7,11 @@
#include "Cemu/ExpressionParser/ExpressionParser.h" #include "Cemu/ExpressionParser/ExpressionParser.h"
#define COLOR_BLACK 0xFF000000
#define COLOR_GREY 0xFFA0A0A0
#define COLOR_WHITE 0xFFFFFFFF
#define COLOR_DEBUG_ACTIVE_BP 0xFFFFA0FF
#define COLOR_DEBUG_ACTIVE 0xFFFFA080
#define COLOR_DEBUG_BP 0xFF8080FF
#define SYNTAX_COLOR_GPR 0xFF000066
#define SYNTAX_COLOR_FPR 0xFF006666
#define SYNTAX_COLOR_SPR 0xFF666600
#define SYNTAX_COLOR_CR 0xFF666600
#define SYNTAX_COLOR_IMM 0xFF006600
#define SYNTAX_COLOR_IMM_OFFSET 0xFF006600
#define SYNTAX_COLOR_CIMM 0xFF880000
#define SYNTAX_COLOR_PSEUDO 0xFFA0A0A0 // color for pseudo code
#define SYNTAX_COLOR_SYMBOL 0xFF0000A0 // color for function symbol
#define OFFSET_ADDRESS (60) #define OFFSET_ADDRESS (60)
#define OFFSET_ADDRESS_RELATIVE (90) #define OFFSET_ADDRESS_RELATIVE (90)
#define OFFSET_MEMORY (450) #define OFFSET_MEMORY (450)
#define OFFSET_DISASSEMBLY_OPERAND (80)
DumpCtrl::DumpCtrl(wxWindow* parent, const wxWindowID& id, const wxPoint& pos, const wxSize& size, long style) DumpCtrl::DumpCtrl(wxWindow* parent, const wxWindowID& id, const wxPoint& pos, const wxSize& size, long style)
: TextList(parent, id, pos, size, style) : TextList(parent, id, pos, size, style)
{ {
@ -68,11 +48,11 @@ void DumpCtrl::OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start
{ {
const uint32 virtual_address = m_memoryRegion.baseAddress + (start + i) * 0x10; const uint32 virtual_address = m_memoryRegion.baseAddress + (start + i) * 0x10;
dc.SetTextForeground(wxColour(COLOR_BLACK)); dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
dc.DrawText(wxString::Format("%08x", virtual_address), position); dc.DrawText(wxString::Format("%08x", virtual_address), position);
position.x += OFFSET_ADDRESS; position.x += OFFSET_ADDRESS;
dc.SetTextForeground(wxColour(COLOR_GREY)); dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT));
if (currentCodeRPL) if (currentCodeRPL)
{ {
dc.DrawText(wxString::Format("+0x%-8x", virtual_address - currentCodeRPL->regionMappingBase_text.GetMPTR()), position); dc.DrawText(wxString::Format("+0x%-8x", virtual_address - currentCodeRPL->regionMappingBase_text.GetMPTR()), position);
@ -110,7 +90,7 @@ void DumpCtrl::OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start
position.x += (m_char_width * 3); position.x += (m_char_width * 3);
} }
position.x = start_width = OFFSET_MEMORY; position.x = start_width = OFFSET_MEMORY;
dc.SetTextForeground(wxColour(COLOR_BLACK)); dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
for (auto b : data) for (auto b : data)
{ {
if (isprint(b)) if (isprint(b))
@ -144,7 +124,7 @@ void DumpCtrl::OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start
start_position.y start_position.y
); );
wxPoint line_to(line_from.x, line_from.y + m_line_height * (count + 1)); wxPoint line_to(line_from.x, line_from.y + m_line_height * (count + 1));
dc.SetPen(*wxLIGHT_GREY_PEN); dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_INACTIVECAPTIONTEXT));
for (sint32 i = 0; i < 3; i++) for (sint32 i = 0; i < 3; i++)
{ {
dc.DrawLine(line_from, line_to); dc.DrawLine(line_from, line_to);

View file

@ -17,8 +17,6 @@ enum
DumpWindow::DumpWindow(DebuggerWindow2& parent, const wxPoint& main_position, const wxSize& main_size) DumpWindow::DumpWindow(DebuggerWindow2& parent, const wxPoint& main_position, const wxSize& main_size)
: wxFrame(&parent, wxID_ANY, _("Memory Dump"), wxDefaultPosition, wxSize(600, 250), wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN | wxRESIZE_BORDER | wxFRAME_FLOAT_ON_PARENT) : wxFrame(&parent, wxID_ANY, _("Memory Dump"), wxDefaultPosition, wxSize(600, 250), wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN | wxRESIZE_BORDER | wxFRAME_FLOAT_ON_PARENT)
{ {
this->wxWindowBase::SetBackgroundColour(*wxWHITE);
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
m_dump_ctrl = new DumpCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxScrolledWindowStyle); m_dump_ctrl = new DumpCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxScrolledWindowStyle);
main_sizer->Add(m_dump_ctrl, 1, wxEXPAND); main_sizer->Add(m_dump_ctrl, 1, wxEXPAND);

View file

@ -23,7 +23,7 @@ ModuleWindow::ModuleWindow(DebuggerWindow2& parent, const wxPoint& main_position
{ {
this->SetSizeHints(wxDefaultSize, wxDefaultSize); this->SetSizeHints(wxDefaultSize, wxDefaultSize);
this->wxWindowBase::SetBackgroundColour(*wxWHITE); // this->wxWindowBase::SetBackgroundColour(*wxWHITE);
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);

View file

@ -1,255 +0,0 @@
#include "wxgui/wxgui.h"
#include "wxgui/debugger/RegisterCtrl.h"
#include <sstream>
#include "Cafe/OS/RPL/rpl_structs.h"
#include "Cafe/OS/RPL/rpl.h"
#include "Cafe/HW/Espresso/Debugger/Debugger.h"
#include "wxgui/debugger/DebuggerWindow2.h"
#define COLOR_DEBUG_ACTIVE_BP 0xFFFFA0FF
#define COLOR_DEBUG_ACTIVE 0xFFFFA080
#define COLOR_DEBUG_BP 0xFF8080FF
#define SYNTAX_COLOR_GPR 0xFF000066
#define SYNTAX_COLOR_FPR 0xFF006666
#define SYNTAX_COLOR_SPR 0xFF666600
#define SYNTAX_COLOR_CR 0xFF666600
#define SYNTAX_COLOR_IMM 0xFF006600
#define SYNTAX_COLOR_IMM_OFFSET 0xFF006600
#define SYNTAX_COLOR_CIMM 0xFF880000
#define SYNTAX_COLOR_PSEUDO 0xFFA0A0A0 // color for pseudo code
#define SYNTAX_COLOR_SYMBOL 0xFF0000A0 // color for function symbol
#define OFFSET_REGISTER (60)
#define OFFSET_REGISTER_LABEL (100)
#define OFFSET_FPR (120)
RegisterCtrl::RegisterCtrl(wxWindow* parent, const wxWindowID& id, const wxPoint& pos, const wxSize& size, long style)
: TextList(parent, id, pos, size, style), m_prev_snapshot({})
{
this->SetElementCount(32 + 1 + 32);
RefreshControl();
}
void RegisterCtrl::OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start_position)
{
wxPoint position = start_position;
//RPLModule* current_rpl_module = rpl3_getModuleByCodeAddr(MEMORY_CODEAREA_ADDR + start);
for (sint32 i = 0; i <= count; i++)
{
const uint32 line = start + i;
if (line < 32)
{
dc.SetTextForeground(COLOR_BLACK);
dc.DrawText(wxString::Format("R%d", line), position);
position.x += OFFSET_REGISTER;
const uint32 register_value = debuggerState.debugSession.ppcSnapshot.gpr[line];
if(register_value != m_prev_snapshot.gpr[line])
dc.SetTextForeground(COLOR_RED);
else
dc.SetTextForeground(COLOR_BLACK);
dc.DrawText(wxString::Format("%08x", register_value), position);
position.x += OFFSET_REGISTER_LABEL;
// check if address is a code offset
RPLModule* code_module = RPLLoader_FindModuleByCodeAddr(register_value);
if (code_module)
dc.DrawText(wxString::Format("<%s> + %x", code_module->moduleName2.c_str(), register_value - code_module->regionMappingBase_text.GetMPTR()), position);
// check if address is a string
uint32 string_offset = register_value;
if (string_offset >= MEMORY_DATA_AREA_ADDR && string_offset < (MEMORY_DATA_AREA_ADDR+MEMORY_DATA_AREA_SIZE) )
{
bool is_valid_string = true;
std::stringstream buffer;
uint32 string_offset = register_value;
while (string_offset < (MEMORY_DATA_AREA_ADDR + MEMORY_DATA_AREA_SIZE))
{
const uint8 c = memory_readU8(string_offset++);
if (isprint(c))
{
buffer << c;
}
else if( c == '\0' )
{
buffer << c;
break;
}
else
{
is_valid_string = false;
break;
}
}
if(is_valid_string && buffer.tellp() > 1)
{
dc.DrawText(wxString::Format("s \"%s\"", buffer.str().c_str()), position);
}
else
{
// check for widestring
is_valid_string = true;
string_offset = register_value;
std::wstringstream wbuffer;
while (string_offset < (MEMORY_DATA_AREA_ADDR + MEMORY_DATA_AREA_SIZE))
{
const uint16 c = memory_readU16(string_offset);
string_offset += 2;
if (iswprint(c))
{
wbuffer << c;
}
else if (c == L'\0')
{
wbuffer << c;
break;
}
else
{
is_valid_string = false;
break;
}
}
if (is_valid_string && buffer.tellp() > 1)
{
dc.DrawText(wxString::Format(L"ws \"%s\"", wbuffer.str().c_str()), position);
}
}
}
}
else if( 32 + 1 <= line && line <= 32 + 1 + 32)
{
const uint32 register_index = line - 32 - 1;
dc.SetTextForeground(COLOR_BLACK);
dc.DrawText(wxString::Format("F0_%d", register_index), position);
position.x += OFFSET_REGISTER;
const uint64 fpr0_value = debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp0int;
if (fpr0_value != m_prev_snapshot.fpr[register_index].fp0int)
dc.SetTextForeground(COLOR_RED);
else
dc.SetTextForeground(COLOR_BLACK);
//dc.DrawText(wxString::Format("%016llx", fpr0_value), position);
dc.DrawText(wxString::Format("%lf", debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp0), position);
position.x += OFFSET_FPR;
dc.SetTextForeground(COLOR_BLACK);
dc.DrawText(wxString::Format("F1_%d", register_index), position);
position.x += OFFSET_REGISTER;
const uint64 fpr1_value = debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp1int;
if (fpr1_value != m_prev_snapshot.fpr[register_index].fp1int)
dc.SetTextForeground(COLOR_RED);
else
dc.SetTextForeground(COLOR_BLACK);
//dc.DrawText(wxString::Format("%016llx", fpr1_value), position);
dc.DrawText(wxString::Format("%lf", debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp1), position);
}
else
{
// empty line
}
NextLine(position, &start_position);
}
memcpy(&m_prev_snapshot, &debuggerState.debugSession.ppcSnapshot, sizeof(m_prev_snapshot));
}
void RegisterCtrl::OnMouseMove(const wxPoint& position, uint32 line)
{
if (!m_mouse_down)
return;
wxPoint pos = position;
if(pos.x <= OFFSET_REGISTER)
{
}
pos.x -= OFFSET_REGISTER;
if (pos.x <= OFFSET_REGISTER_LABEL)
{
}
pos.x -= OFFSET_REGISTER_LABEL;
}
void RegisterCtrl::OnMouseDClick(const wxPoint& position, uint32 line)
{
if (!debuggerState.debugSession.isTrapped)
return;
if(line < 32)
{
const uint32 register_index = line;
if (position.x <= OFFSET_REGISTER + OFFSET_REGISTER_LABEL)
{
const uint32 register_value = debuggerState.debugSession.ppcSnapshot.gpr[register_index];
wxTextEntryDialog set_value_dialog(this, _("Enter a new value."), wxString::Format(_("Set R%d value"), register_index), wxString::Format("%08x", register_value));
if (set_value_dialog.ShowModal() == wxID_OK)
{
const uint32 new_value = std::stoul(set_value_dialog.GetValue().ToStdString(), nullptr, 16);
debuggerState.debugSession.hCPU->gpr[register_index] = new_value;
debuggerState.debugSession.ppcSnapshot.gpr[register_index] = new_value;
wxRect update_rect(0, line * m_line_height, GetSize().x, m_line_height);
RefreshControl(&update_rect);
}
}
}
// one line empty between = line 32
else if (32 + 1 <= line && line <= 32 + 1 + 32)
{
const uint32 register_index = line - 32 - 1;
if (position.x <= OFFSET_REGISTER + OFFSET_FPR)
{
const double register_value = debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp0;
wxTextEntryDialog set_value_dialog(this, _("Enter a new value."), wxString::Format(_("Set FP0_%d value"), register_index), wxString::Format("%lf", register_value));
if (set_value_dialog.ShowModal() == wxID_OK)
{
const double new_value = std::stod(set_value_dialog.GetValue().ToStdString());
debuggerState.debugSession.hCPU->fpr[register_index].fp0 = new_value;
debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp0 = new_value;
wxRect update_rect(0, line * m_line_height, GetSize().x, m_line_height);
RefreshControl(&update_rect);
}
}
else
{
const double register_value = debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp1;
wxTextEntryDialog set_value_dialog(this, _("Enter a new value."), wxString::Format(_("Set FP1_%d value"), register_index), wxString::Format("%lf", register_value));
if (set_value_dialog.ShowModal() == wxID_OK)
{
const double new_value = std::stod(set_value_dialog.GetValue().ToStdString());
debuggerState.debugSession.hCPU->fpr[register_index].fp1 = new_value;
debuggerState.debugSession.ppcSnapshot.fpr[register_index].fp1 = new_value;
wxRect update_rect(0, line * m_line_height, GetSize().x, m_line_height);
RefreshControl(&update_rect);
}
}
}
}
void RegisterCtrl::OnGameLoaded()
{
RefreshControl();
}

View file

@ -1,18 +0,0 @@
#pragma once
#include "wxgui/components/TextList.h"
#include "Cafe/HW/Espresso/Debugger/Debugger.h"
class RegisterCtrl : public TextList
{
public:
RegisterCtrl(wxWindow* parent, const wxWindowID& id, const wxPoint& pos, const wxSize& size, long style);
void OnGameLoaded();
protected:
void OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start_position) override;
void OnMouseMove(const wxPoint& position, uint32 line) override;
void OnMouseDClick(const wxPoint& position, uint32 line) override;
private:
PPCSnapshot m_prev_snapshot;
};

View file

@ -33,7 +33,7 @@ RegisterWindow::RegisterWindow(DebuggerWindow2& parent, const wxPoint& main_posi
{ {
SetSizeHints(wxDefaultSize, wxDefaultSize); SetSizeHints(wxDefaultSize, wxDefaultSize);
SetMaxSize({ 400, 975 }); SetMaxSize({ 400, 975 });
wxWindowBase::SetBackgroundColour(*wxWHITE); this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
@ -47,29 +47,33 @@ RegisterWindow::RegisterWindow(DebuggerWindow2& parent, const wxPoint& main_posi
{ {
gpr_sizer->Add(new wxStaticText(scrolled_win, wxID_ANY, wxString::Format("R%d", i)), 0, wxLEFT, 5); gpr_sizer->Add(new wxStaticText(scrolled_win, wxID_ANY, wxString::Format("R%d", i)), 0, wxLEFT, 5);
auto value = new wxTextCtrl(scrolled_win, kRegisterValueR0 + i, wxString::Format("%08x", 0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); auto value = new wxTextCtrl(scrolled_win, kRegisterValueR0 + i, wxString::Format("%08x", 0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2);
value->SetBackgroundColour(*wxWHITE); value->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
value->Bind(wxEVT_LEFT_DCLICK, &RegisterWindow::OnMouseDClickEvent, this); value->Bind(wxEVT_LEFT_DCLICK, &RegisterWindow::OnMouseDClickEvent, this);
//value->Bind(wxEVT_CONTEXT_MENU, &RegisterWindow::OnValueContextMenu, this); //value->Bind(wxEVT_CONTEXT_MENU, &RegisterWindow::OnValueContextMenu, this);
gpr_sizer->Add(value, 0, wxLEFT|wxRIGHT, 5); gpr_sizer->Add(value, 0, wxLEFT|wxRIGHT, 5);
auto label = new wxTextCtrl(scrolled_win, kRegisterLabelR0 + i, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); auto label = new wxTextCtrl(scrolled_win, kRegisterLabelR0 + i, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2);
label->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
label->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
label->SetMinSize(wxSize(500, -1)); label->SetMinSize(wxSize(500, -1));
label->SetBackgroundColour(*wxWHITE);
gpr_sizer->Add(label, 0, wxEXPAND); gpr_sizer->Add(label, 0, wxEXPAND);
} }
{ {
// LR // LR
gpr_sizer->Add(new wxStaticText(scrolled_win, wxID_ANY, wxString::Format("LR")), 0, wxLEFT, 5); gpr_sizer->Add(new wxStaticText(scrolled_win, wxID_ANY, wxString::Format("LR")), 0, wxLEFT, 5);
auto value = new wxTextCtrl(scrolled_win, kRegisterValueLR, wxString::Format("%08x", 0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); auto value = new wxTextCtrl(scrolled_win, kRegisterValueLR, wxString::Format("%08x", 0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2);
value->SetBackgroundColour(*wxWHITE); value->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
value->Bind(wxEVT_LEFT_DCLICK, &RegisterWindow::OnMouseDClickEvent, this); value->Bind(wxEVT_LEFT_DCLICK, &RegisterWindow::OnMouseDClickEvent, this);
//value->Bind(wxEVT_CONTEXT_MENU, &RegisterWindow::OnValueContextMenu, this); //value->Bind(wxEVT_CONTEXT_MENU, &RegisterWindow::OnValueContextMenu, this);
gpr_sizer->Add(value, 0, wxLEFT | wxRIGHT, 5); gpr_sizer->Add(value, 0, wxLEFT | wxRIGHT, 5);
auto label = new wxTextCtrl(scrolled_win, kRegisterLabelLR, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); auto label = new wxTextCtrl(scrolled_win, kRegisterLabelLR, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2);
label->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
label->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
label->SetMinSize(wxSize(500, -1)); label->SetMinSize(wxSize(500, -1));
label->SetBackgroundColour(*wxWHITE);
gpr_sizer->Add(label, 0, wxEXPAND); gpr_sizer->Add(label, 0, wxEXPAND);
} }
@ -84,13 +88,15 @@ RegisterWindow::RegisterWindow(DebuggerWindow2& parent, const wxPoint& main_posi
{ {
fp_sizer->Add(new wxStaticText(scrolled_win, wxID_ANY, wxString::Format("FP%d", i)), 0, wxLEFT, 5); fp_sizer->Add(new wxStaticText(scrolled_win, wxID_ANY, wxString::Format("FP%d", i)), 0, wxLEFT, 5);
auto value0 = new wxTextCtrl(scrolled_win, kRegisterValueFPR0_0 + i, wxString::Format("%lf", 0.0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); auto value0 = new wxTextCtrl(scrolled_win, kRegisterValueFPR0_0 + i, wxString::Format("%lf", 0.0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2);
value0->SetBackgroundColour(*wxWHITE); value0->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
value0->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
value0->Bind(wxEVT_LEFT_DCLICK, &RegisterWindow::OnMouseDClickEvent, this); value0->Bind(wxEVT_LEFT_DCLICK, &RegisterWindow::OnMouseDClickEvent, this);
fp_sizer->Add(value0, 0, wxLEFT | wxRIGHT, 5); fp_sizer->Add(value0, 0, wxLEFT | wxRIGHT, 5);
auto value1 = new wxTextCtrl(scrolled_win, kRegisterValueFPR1_0 + i, wxString::Format("%lf", 0.0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); auto value1 = new wxTextCtrl(scrolled_win, kRegisterValueFPR1_0 + i, wxString::Format("%lf", 0.0), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2);
value1->SetBackgroundColour(*wxWHITE); value1->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
value1->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
value1->Bind(wxEVT_LEFT_DCLICK, &RegisterWindow::OnMouseDClickEvent, this); value1->Bind(wxEVT_LEFT_DCLICK, &RegisterWindow::OnMouseDClickEvent, this);
fp_sizer->Add(value1, 0, wxLEFT | wxRIGHT, 5); fp_sizer->Add(value1, 0, wxLEFT | wxRIGHT, 5);
} }
@ -102,8 +108,9 @@ RegisterWindow::RegisterWindow(DebuggerWindow2& parent, const wxPoint& main_posi
for (sint32 i = 0; i < 8; ++i) for (sint32 i = 0; i < 8; ++i)
{ {
cr_sizer->Add(new wxStaticText(scrolled_win, wxID_ANY, wxString::Format("CR%d", i)), 0, wxLEFT, 5); cr_sizer->Add(new wxStaticText(scrolled_win, wxID_ANY, wxString::Format("CR%d", i)), 0, wxLEFT, 5);
auto value = new wxTextCtrl(scrolled_win, kRegisterValueCR0 + i, "-", wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER); auto value = new wxTextCtrl(scrolled_win, kRegisterValueCR0 + i, "-", wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RICH2);
value->SetBackgroundColour(*wxWHITE); value->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
//value->Bind(wxEVT_CONTEXT_MENU, &RegisterWindow::OnValueContextMenu, this); //value->Bind(wxEVT_CONTEXT_MENU, &RegisterWindow::OnValueContextMenu, this);
cr_sizer->Add(value, 0, wxRIGHT, 5); cr_sizer->Add(value, 0, wxRIGHT, 5);
} }
@ -141,15 +148,15 @@ void RegisterWindow::UpdateIntegerRegister(wxTextCtrl* label, wxTextCtrl* value,
//const bool has_changed = register_value != m_prev_snapshot.gpr[i]; //const bool has_changed = register_value != m_prev_snapshot.gpr[i];
if (hasChanged) if (hasChanged)
value->SetForegroundColour(COLOR_RED); value->SetForegroundColour(m_changed_color);
else if (value->GetForegroundColour() != COLOR_BLACK) else if (value->GetForegroundColour() != wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT))
value->SetForegroundColour(COLOR_BLACK); value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
value->ChangeValue(wxString::Format("%08x", registerValue)); value->ChangeValue(wxString::Format("%08x", registerValue));
//const auto label = dynamic_cast<wxTextCtrl*>(GetWindowChild(kRegisterLabelR0 + i)); //const auto label = dynamic_cast<wxTextCtrl*>(GetWindowChild(kRegisterLabelR0 + i));
//wxASSERT(label); //wxASSERT(label);
label->SetForegroundColour(hasChanged ? COLOR_RED : COLOR_BLACK); label->SetForegroundColour(hasChanged ? m_changed_color : wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
// check if address is a string // check if address is a string
if (registerValue >= MEMORY_DATA_AREA_ADDR && registerValue < (MEMORY_DATA_AREA_ADDR + MEMORY_DATA_AREA_SIZE)) if (registerValue >= MEMORY_DATA_AREA_ADDR && registerValue < (MEMORY_DATA_AREA_ADDR + MEMORY_DATA_AREA_SIZE))
@ -257,9 +264,9 @@ void RegisterWindow::OnUpdateView()
const bool has_changed = register_value != m_prev_snapshot.fpr[i].fp0int; const bool has_changed = register_value != m_prev_snapshot.fpr[i].fp0int;
if (has_changed) if (has_changed)
value->SetForegroundColour(COLOR_RED); value->SetForegroundColour(m_changed_color);
else if (value->GetForegroundColour() != COLOR_BLACK) else if (value->GetForegroundColour() != wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT))
value->SetForegroundColour(COLOR_BLACK); value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
else else
continue; continue;
@ -278,9 +285,9 @@ void RegisterWindow::OnUpdateView()
const bool has_changed = register_value != m_prev_snapshot.fpr[i].fp1int; const bool has_changed = register_value != m_prev_snapshot.fpr[i].fp1int;
if (has_changed) if (has_changed)
value->SetForegroundColour(COLOR_RED); value->SetForegroundColour(m_changed_color);
else if (value->GetForegroundColour() != COLOR_BLACK) else if (value->GetForegroundColour() != wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT))
value->SetForegroundColour(COLOR_BLACK); value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
else else
continue; continue;
@ -301,9 +308,9 @@ void RegisterWindow::OnUpdateView()
const bool has_changed = !std::equal(cr_bits_ptr, cr_bits_ptr + 4, cr_bits_ptr_cmp); const bool has_changed = !std::equal(cr_bits_ptr, cr_bits_ptr + 4, cr_bits_ptr_cmp);
if (has_changed) if (has_changed)
value->SetForegroundColour(COLOR_RED); value->SetForegroundColour(m_changed_color);
else if (value->GetForegroundColour() != COLOR_BLACK) else if (value->GetForegroundColour() != wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT))
value->SetForegroundColour(COLOR_BLACK); value->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
else else
continue; continue;

View file

@ -21,6 +21,7 @@ private:
PPCSnapshot m_prev_snapshot; PPCSnapshot m_prev_snapshot;
bool m_show_double_values; bool m_show_double_values;
wxColour m_changed_color = {0xFF0000FF};
wxTextCtrl* m_context_ctrl; wxTextCtrl* m_context_ctrl;
}; };

View file

@ -14,8 +14,6 @@ enum ItemColumns
SymbolWindow::SymbolWindow(DebuggerWindow2& parent, const wxPoint& main_position, const wxSize& main_size) SymbolWindow::SymbolWindow(DebuggerWindow2& parent, const wxPoint& main_position, const wxSize& main_size)
: wxFrame(&parent, wxID_ANY, _("Symbols"), wxDefaultPosition, wxSize(600, 250), wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN | wxRESIZE_BORDER | wxFRAME_FLOAT_ON_PARENT) : wxFrame(&parent, wxID_ANY, _("Symbols"), wxDefaultPosition, wxSize(600, 250), wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN | wxRESIZE_BORDER | wxFRAME_FLOAT_ON_PARENT)
{ {
this->wxWindowBase::SetBackgroundColour(*wxWHITE);
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
m_symbol_ctrl = new SymbolListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); m_symbol_ctrl = new SymbolListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
main_sizer->Add(m_symbol_ctrl, 1, wxEXPAND); main_sizer->Add(m_symbol_ctrl, 1, wxEXPAND);

View file

@ -4,6 +4,7 @@
#include <config/ActiveSettings.h> #include <config/ActiveSettings.h>
#include "input/InputManager.h" #include "input/InputManager.h"
#include "HotkeySettings.h" #include "HotkeySettings.h"
#include "MainWindow.h"
#include <wx/clipbrd.h> #include <wx/clipbrd.h>
@ -112,6 +113,7 @@ std::optional<std::string> SaveScreenshot(std::vector<uint8> data, int width, in
} }
extern WindowSystem::WindowInfo g_window_info; extern WindowSystem::WindowInfo g_window_info;
std::unordered_map<sHotkeyCfg*, std::function<void(void)>> HotkeySettings::s_cfgHotkeyToFuncMap; std::unordered_map<sHotkeyCfg*, std::function<void(void)>> HotkeySettings::s_cfgHotkeyToFuncMap;
struct HotkeyEntry struct HotkeyEntry
@ -140,7 +142,6 @@ HotkeySettings::HotkeySettings(wxWindow* parent)
m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE); m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE);
m_panel->SetSizer(m_sizer); m_panel->SetSizer(m_sizer);
m_panel->SetBackgroundColour(*wxWHITE);
Center(); Center();
@ -172,17 +173,17 @@ HotkeySettings::~HotkeySettings()
} }
} }
void HotkeySettings::Init(wxFrame* mainWindowFrame) void HotkeySettings::Init(MainWindow* mainWindowFrame)
{ {
s_cfgHotkeyToFuncMap.insert({ s_cfgHotkeyToFuncMap.insert({
{&s_cfgHotkeys.toggleFullscreen, [](void) { {&s_cfgHotkeys.toggleFullscreen, [](void) {
s_mainWindow->ShowFullScreen(!s_mainWindow->IsFullScreen()); s_mainWindow->SetFullScreen(!s_mainWindow->IsFullScreen());
}}, }},
{&s_cfgHotkeys.toggleFullscreenAlt, [](void) { {&s_cfgHotkeys.toggleFullscreenAlt, [](void) {
s_mainWindow->ShowFullScreen(!s_mainWindow->IsFullScreen()); s_mainWindow->SetFullScreen(!s_mainWindow->IsFullScreen());
}}, }},
{&s_cfgHotkeys.exitFullscreen, [](void) { {&s_cfgHotkeys.exitFullscreen, [](void) {
s_mainWindow->ShowFullScreen(false); s_mainWindow->SetFullScreen(false);
}}, }},
{&s_cfgHotkeys.takeScreenshot, [](void) { {&s_cfgHotkeys.takeScreenshot, [](void) {
if (g_renderer) if (g_renderer)
@ -242,11 +243,7 @@ void HotkeySettings::CreateHotkeyRow(const wxString& label, sHotkeyCfg& cfgHotke
keyInput->SetMinSize(m_minButtonSize); keyInput->SetMinSize(m_minButtonSize);
controllerInput->SetMinSize(m_minButtonSize); controllerInput->SetMinSize(m_minButtonSize);
#if BOOST_OS_WINDOWS
const wxColour inputButtonColor = 0xfafafa;
#else
const wxColour inputButtonColor = GetBackgroundColour(); const wxColour inputButtonColor = GetBackgroundColour();
#endif
keyInput->SetBackgroundColour(inputButtonColor); keyInput->SetBackgroundColour(inputButtonColor);
controllerInput->SetBackgroundColour(inputButtonColor); controllerInput->SetBackgroundColour(inputButtonColor);
@ -415,7 +412,8 @@ void HotkeySettings::FinalizeInput(wxButton* inputButton)
{ {
inputButton->Unbind(wxEVT_KEY_UP, &HotkeySettings::OnKeyUp, this); inputButton->Unbind(wxEVT_KEY_UP, &HotkeySettings::OnKeyUp, this);
inputButton->SetLabelText(To_wxString(cfgHotkey.keyboard)); inputButton->SetLabelText(To_wxString(cfgHotkey.keyboard));
} else if constexpr (std::is_same_v<T, ControllerHotkey_t>) }
else if constexpr (std::is_same_v<T, ControllerHotkey_t>)
{ {
inputButton->SetLabelText(To_wxString(cfgHotkey.controller)); inputButton->SetLabelText(To_wxString(cfgHotkey.controller));
} }

View file

@ -9,7 +9,7 @@ class HotkeyEntry;
class HotkeySettings : public wxFrame class HotkeySettings : public wxFrame
{ {
public: public:
static void Init(wxFrame* mainWindowFrame); static void Init(class MainWindow* mainWindow);
static void CaptureInput(wxKeyEvent& event); static void CaptureInput(wxKeyEvent& event);
static void CaptureInput(const ControllerState& currentState, const ControllerState& lastState); static void CaptureInput(const ControllerState& currentState, const ControllerState& lastState);
@ -18,7 +18,7 @@ public:
~HotkeySettings(); ~HotkeySettings();
private: private:
inline static wxFrame* s_mainWindow = nullptr; inline static class MainWindow* s_mainWindow = nullptr;
static std::unordered_map<sHotkeyCfg*, std::function<void(void)>> s_cfgHotkeyToFuncMap; static std::unordered_map<sHotkeyCfg*, std::function<void(void)>> s_cfgHotkeyToFuncMap;
inline static std::unordered_map<uint16, std::function<void(void)>> s_keyboardHotkeyToFuncMap{}; inline static std::unordered_map<uint16, std::function<void(void)>> s_keyboardHotkeyToFuncMap{};
inline static std::unordered_map<uint16, std::function<void(void)>> s_controllerHotkeyToFuncMap{}; inline static std::unordered_map<uint16, std::function<void(void)>> s_controllerHotkeyToFuncMap{};

View file

@ -15,6 +15,7 @@
#include <wx/button.h> #include <wx/button.h>
#include <wx/statline.h> #include <wx/statline.h>
#include <wx/bmpbuttn.h> #include <wx/bmpbuttn.h>
#include <wx/settings.h>
#include "config/ActiveSettings.h" #include "config/ActiveSettings.h"
#include "wxgui/input/InputAPIAddWindow.h" #include "wxgui/input/InputAPIAddWindow.h"
@ -70,9 +71,9 @@ InputSettings2::InputSettings2(wxWindow* parent)
g_inputConfigWindowHasFocus = true; g_inputConfigWindowHasFocus = true;
m_connected = wxBITMAP_PNG_FROM_DATA(INPUT_CONNECTED); m_connected = wxHelper::LoadThemedBitmapFromPNG(INPUT_CONNECTED_png, sizeof(INPUT_CONNECTED_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
m_disconnected = wxBITMAP_PNG_FROM_DATA(INPUT_DISCONNECTED); m_disconnected = wxHelper::LoadThemedBitmapFromPNG(INPUT_DISCONNECTED_png, sizeof(INPUT_DISCONNECTED_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
m_low_battery = wxBITMAP_PNG_FROM_DATA(INPUT_LOW_BATTERY); m_low_battery = wxHelper::LoadThemedBitmapFromPNG(INPUT_LOW_BATTERY_png, sizeof(INPUT_LOW_BATTERY_png), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
auto* sizer = new wxBoxSizer(wxVERTICAL); auto* sizer = new wxBoxSizer(wxVERTICAL);

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <wx/panel.h> #include <wx/panel.h>
#include <wx/settings.h>
#include "input/emulated/EmulatedController.h" #include "input/emulated/EmulatedController.h"
#include "input/api/Controller.h" #include "input/api/Controller.h"
@ -14,15 +15,9 @@ class wxComboBox;
class InputPanel : public wxPanel class InputPanel : public wxPanel
{ {
public: public:
#if BOOST_OS_WINDOWS
const wxColour kKeyColourNormalMode = 0xfafafa;
const wxColour kKeyColourEditMode = 0x99ccff;
const wxColour kKeyColourActiveMode = 0xE0E0E0;
#else
const wxColour kKeyColourNormalMode = GetBackgroundColour(); const wxColour kKeyColourNormalMode = GetBackgroundColour();
const wxColour kKeyColourEditMode = GetBackgroundColour(); const wxColour kKeyColourEditMode = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
const wxColour kKeyColourActiveMode = wxHelper::CalculateAccentColour(kKeyColourNormalMode); const wxColour kKeyColourActiveMode = wxHelper::CalculateAccentColour(GetBackgroundColour());
#endif
InputPanel(wxWindow* parent); InputPanel(wxWindow* parent);

View file

@ -40,8 +40,6 @@ DebugPPCThreadsWindow::DebugPPCThreadsWindow(wxFrame& parent)
: wxFrame(&parent, wxID_ANY, _("PPC threads"), wxDefaultPosition, wxSize(930, 280), : wxFrame(&parent, wxID_ANY, _("PPC threads"), wxDefaultPosition, wxSize(930, 280),
wxCLOSE_BOX | wxCLIP_CHILDREN | wxCAPTION | wxRESIZE_BORDER) wxCLOSE_BOX | wxCLIP_CHILDREN | wxCAPTION | wxRESIZE_BORDER)
{ {
wxFrame::SetBackgroundColour(*wxWHITE);
auto* sizer = new wxBoxSizer(wxVERTICAL); auto* sizer = new wxBoxSizer(wxVERTICAL);
m_thread_list = new wxListView(this, GPLIST_ID, wxPoint(0, 0), wxSize(930, 240), wxLC_REPORT); m_thread_list = new wxListView(this, GPLIST_ID, wxPoint(0, 0), wxSize(930, 240), wxLC_REPORT);

View file

@ -1,4 +1,5 @@
#include "wxgui/wxgui.h" #include "wxgui/wxgui.h"
#include "wxHelper.h"
#include "TextureRelationWindow.h" #include "TextureRelationWindow.h"
#include "Cafe/HW/Latte/Core/LatteTexture.h" #include "Cafe/HW/Latte/Core/LatteTexture.h"
@ -113,14 +114,14 @@ TextureRelationViewerWindow::TextureRelationViewerWindow(wxFrame& parent)
wxBoxSizer* sizerBottom = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* sizerBottom = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(textureRelationListA, 1, wxEXPAND | wxBOTTOM, 0); sizer->Add(textureRelationListA, 1, wxEXPAND | wxBOTTOM, 0);
wxButton* button = new wxButton(mainPane, REFRESH_ID, _("Refresh"), wxPoint(0, 0), wxSize(80, 26)); wxButton* button = new wxButton(mainPane, REFRESH_ID, _("Refresh"));
sizerBottom->Add(button, 0, wxBOTTOM | wxTOP | wxLEFT, 10); sizerBottom->Add(button, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxTOP | wxLEFT, 10);
wxCheckBox* checkboxShowOnlyActive = new wxCheckBox(mainPane, CHECKBOX_SHOW_ONLY_ACTIVE, _("Show only active"), wxPoint(0, 0), wxSize(110, 26)); wxCheckBox* checkboxShowOnlyActive = new wxCheckBox(mainPane, CHECKBOX_SHOW_ONLY_ACTIVE, _("Show only active"));
sizerBottom->Add(checkboxShowOnlyActive, 0, wxBOTTOM | wxTOP | wxLEFT, 10); sizerBottom->Add(checkboxShowOnlyActive, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxTOP | wxLEFT, 10);
wxCheckBox* checkboxShowViews = new wxCheckBox(mainPane, CHECKBOX_SHOW_VIEWS, _("Show views"), wxPoint(0, 0), wxSize(90, 26)); wxCheckBox* checkboxShowViews = new wxCheckBox(mainPane, CHECKBOX_SHOW_VIEWS, _("Show views"));
sizerBottom->Add(checkboxShowViews, 0, wxBOTTOM | wxTOP | wxLEFT, 10); sizerBottom->Add(checkboxShowViews, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxTOP | wxLEFT, 10);
checkboxShowViews->SetValue(true); checkboxShowViews->SetValue(true);
textureRelationListA->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(TextureRelationViewerWindow::OnTextureListRightClick), NULL, this); textureRelationListA->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(TextureRelationViewerWindow::OnTextureListRightClick), NULL, this);
@ -132,8 +133,6 @@ TextureRelationViewerWindow::TextureRelationViewerWindow(wxFrame& parent)
mainPane->SetSizer(sizer); mainPane->SetSizer(sizer);
RefreshTextureList(); RefreshTextureList();
wxFrame::SetBackgroundColour(*wxWHITE);
} }
TextureRelationViewerWindow::~TextureRelationViewerWindow() TextureRelationViewerWindow::~TextureRelationViewerWindow()
@ -183,11 +182,10 @@ void TextureRelationViewerWindow::_setTextureRelationListItemTexture(wxListCtrl*
{ {
sprintf(tempStr + strlen(tempStr), "(%d)", alternativeViewCount + 1); sprintf(tempStr + strlen(tempStr), "(%d)", alternativeViewCount + 1);
} }
uint32 bgColor = 0xFFEEEEEE;
wxListItem item; wxListItem item;
item.SetId(rowIndex); item.SetId(rowIndex);
item.SetText(tempStr); item.SetText(tempStr);
item.SetBackgroundColour(wxColour(bgColor)); item.SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
uiList->InsertItem(item); uiList->InsertItem(item);
sint32 columnIndex = 1; sint32 columnIndex = 1;
@ -279,11 +277,10 @@ void TextureRelationViewerWindow::_setTextureRelationListItemView(wxListCtrl* ui
else else
sprintf(tempStr, "> VIEW(%d)", alternativeViewCount+1); sprintf(tempStr, "> VIEW(%d)", alternativeViewCount+1);
// find and handle highlight entry // find and handle highlight entry
uint32 bgColor = 0xFFDDDDDD;
wxListItem item; wxListItem item;
item.SetId(rowIndex); item.SetId(rowIndex);
item.SetText(tempStr); item.SetText(tempStr);
item.SetBackgroundColour(wxColour(bgColor)); item.SetBackgroundColour(wxHelper::CalculateAccentColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)));
uiList->InsertItem(item); uiList->InsertItem(item);
//uiList->SetItemPtrData(item, (wxUIntPtr)viewInfo); //uiList->SetItemPtrData(item, (wxUIntPtr)viewInfo);
sint32 columnIndex = 1; sint32 columnIndex = 1;
@ -392,7 +389,6 @@ void TextureRelationViewerWindow::RefreshTextureList()
void TextureRelationViewerWindow::OnTextureListRightClick(wxMouseEvent& event) void TextureRelationViewerWindow::OnTextureListRightClick(wxMouseEvent& event)
{ {
} }
void TextureRelationViewerWindow::Close() void TextureRelationViewerWindow::Close()

View file

@ -26,6 +26,7 @@ void wxCemuConfig::AddRecentNfcFile(std::string_view file)
void wxCemuConfig::Load(XMLConfigParser& parser) void wxCemuConfig::Load(XMLConfigParser& parser)
{ {
language = parser.get<sint32>("language", wxLANGUAGE_DEFAULT); language = parser.get<sint32>("language", wxLANGUAGE_DEFAULT);
msw_theme = parser.get<sint32>("msw_theme", msw_theme);
use_discord_presence = parser.get("use_discord_presence", true); use_discord_presence = parser.get("use_discord_presence", true);
fullscreen_menubar = parser.get("fullscreen_menubar", false); fullscreen_menubar = parser.get("fullscreen_menubar", false);
feral_gamemode = parser.get("feral_gamemode", false); feral_gamemode = parser.get("feral_gamemode", false);
@ -120,6 +121,7 @@ void wxCemuConfig::Save(XMLConfigParser& config)
{ {
// general settings // general settings
config.set<sint32>("language", language); config.set<sint32>("language", language);
config.set<sint32>("msw_theme", msw_theme);
config.set<bool>("use_discord_presence", use_discord_presence); config.set<bool>("use_discord_presence", use_discord_presence);
config.set<bool>("fullscreen_menubar", fullscreen_menubar); config.set<bool>("fullscreen_menubar", fullscreen_menubar);
config.set<bool>("feral_gamemode", feral_gamemode); config.set<bool>("feral_gamemode", feral_gamemode);

View file

@ -20,6 +20,14 @@ namespace DefaultColumnSize
}; };
}; };
enum class MSWThemeOption : int
{
kAuto = 0,
kLight = 1,
kDark = 2,
};
ENABLE_ENUM_ITERATORS(MSWThemeOption, MSWThemeOption::kAuto, MSWThemeOption::kDark);
typedef union typedef union
{ {
struct struct
@ -67,6 +75,7 @@ struct fmt::formatter<sHotkeyCfg> : formatter<string_view>
struct wxCemuConfig struct wxCemuConfig
{ {
ConfigValue<sint32> language{wxLANGUAGE_DEFAULT}; ConfigValue<sint32> language{wxLANGUAGE_DEFAULT};
ConfigValue<int> msw_theme { static_cast<int>(MSWThemeOption::kAuto) };
ConfigValue<bool> use_discord_presence{true}; ConfigValue<bool> use_discord_presence{true};
ConfigValue<bool> fullscreen{ false }; ConfigValue<bool> fullscreen{ false };
ConfigValue<bool> fullscreen_menubar{false}; ConfigValue<bool> fullscreen_menubar{false};

View file

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <wx/string.h> #include <wx/string.h>
#include <wx/bitmap.h>
#include <wx/mstream.h>
namespace wxHelper namespace wxHelper
{ {
@ -33,4 +35,11 @@ namespace wxHelper
return bgColourSecondary; return bgColourSecondary;
} }
static wxBitmap LoadThemedBitmapFromPNG(const uint8* data, size_t size, const wxColour& tint)
{
wxMemoryInputStream strm(data, size);
wxImage img(strm, wxBITMAP_TYPE_PNG);
img.Replace(0x00, 0x00, 0x00, tint.Red(), tint.Green(), tint.Blue());
return wxBitmap(img);
}
}; };

View file

@ -1,24 +0,0 @@
/* XPM */
static const char * checked_xpm[] = {
"16 16 5 1",
" c None",
". c #808080",
"X c Black",
"o c #c0c0c0",
"w c White",
" ",
" ",
" ............ ",
" .XXXXXXXXXXo ",
" .Xwwwwwwwwwo ",
" .XwwwwwwwXwo ",
" .XwwwwwwXXwo ",
" .XwXwwwXXXwo ",
" .XwXXwXXXwwo ",
" .XwXXXXXwwwo ",
" .XwwXXXwwwwo ",
" .XwwwXwwwwwo ",
" .Xwwwwwwwwwo ",
" .ooooooooooo ",
" ",
" "};

View file

@ -1,38 +0,0 @@
/* XPM */
static const char * checked2_xpm[] = {
"14 15 20 1",
" c None",
". c #1C5180",
"+ c #E2E2DD",
"@ c #E3E3DF",
"# c #E5E5E1",
"$ c #E7E7E3",
"% c #EAEAE6",
"& c #ECECE9",
"* c #EFEFEC",
"= c #F1F1EF",
"- c #F3F3F1",
"; c #F5F5F3",
"> c #21A121",
", c #F7F7F6",
"' c #F9F9F8",
") c #FAFAF9",
"! c #FCFCFB",
"~ c #FDFDFD",
"{ c #FEFEFE",
"] c #FFFFFF",
"............. ",
".+++@#$%&*=-. ",
".++@#$%&*=-;. ",
".+@#$%&*=>;,. ",
".@#$%&*=>>,'. ",
".#$>&*=>>>'). ",
".$%>>=>>>')!. ",
".%&>>>>>')!~. ",
".&*=>>>')!~{. ",
".*=-;>')!~{]. ",
".=-;,')!~{]]. ",
".-;,')!~{]]]. ",
"............. ",
" ",
" "};

View file

@ -1,21 +0,0 @@
/* XPM */
static const char * checked_d_xpm[] = {
"14 15 3 1",
" c None",
". c #CAC8BB",
"+ c #FFFFFF",
"............. ",
".+++++++++++. ",
".+++++++++++. ",
".++++++++.++. ",
".+++++++..++. ",
".++.+++...++. ",
".++..+...+++. ",
".++.....++++. ",
".+++...+++++. ",
".++++.++++++. ",
".+++++++++++. ",
".+++++++++++. ",
"............. ",
" ",
" "};

View file

@ -1,23 +0,0 @@
/* XPM */
static const char * checked_dis_xpm[] = {
"16 16 4 1",
" c None",
". c #808080",
"X c Black",
"o c #c0c0c0",
" ",
" ",
" ............ ",
" .XXXXXXXXXXo ",
" .Xoooooooooo ",
" .Xooooooo.oo ",
" .Xoooooo..oo ",
" .Xo.ooo...oo ",
" .Xo..o...ooo ",
" .Xo.....oooo ",
" .Xoo...ooooo ",
" .Xooo.oooooo ",
" .Xoooooooooo ",
" .ooooooooooo ",
" ",
" "};

View file

@ -1,44 +0,0 @@
/* XPM */
static const char * checked_ld_xpm[] = {
"14 15 26 1",
" c None",
". c #1C5180",
"+ c #B0B0A7",
"@ c #B3B3AA",
"# c #B7B7AD",
"$ c #BCBBB1",
"% c #C1C1B6",
"& c #C7C6BB",
"* c #CDCCC0",
"= c #D2D1C5",
"- c #D7D5C8",
"; c #DBDACC",
"> c #1C861A",
", c #DFDDCF",
"' c #1C8A1A",
") c #E3E1D3",
"! c #197A18",
"~ c #1D8C1B",
"{ c #E6E5D6",
"] c #1A7D18",
"^ c #1B8119",
"/ c #EAE8D9",
"( c #1B8419",
"_ c #EDEBDB",
": c #EFEDDD",
"< c #F1EFDF",
"............. ",
".+++@#$%&*=-. ",
".++@#$%&*=-;. ",
".+@#$%&*=>;,. ",
".@#$%&*=>',). ",
".#$!&*=>'~){. ",
".$%]^=>'~){/. ",
".%&^(>'~){/_. ",
".&*=>'~){/_:. ",
".*=-;~){/_:<. ",
".=-;,){/_:<<. ",
".-;,){/_:<<<. ",
"............. ",
" ",
" "};

View file

@ -1,70 +0,0 @@
/* XPM */
static const char * checked_mo_xpm[] = {
"14 15 52 1",
" c None",
". c #1C5180",
"+ c #FFF0CF",
"@ c #FFEDC6",
"# c #FFE9BA",
"$ c #FEE4AC",
"% c #FEDF9C",
"& c #FDD98C",
"* c #FDD889",
"= c #FDDB95",
"- c #FDDC97",
"; c #FCD687",
"> c #FBCA6A",
", c #FDE3AC",
"' c #FDE6B6",
") c #FDDEA2",
"! c #FBD07A",
"~ c #FFEABD",
"{ c #FEE9BC",
"] c #F7F7F5",
"^ c #F6F6F4",
"/ c #F4F4F3",
"( c #F8F8F7",
"_ c #FAFAF9",
": c #21A121",
"< c #FDE3AE",
"[ c #FBD280",
"} c #FEECC4",
"| c #FDE1AB",
"1 c #FBD07B",
"2 c #FEE7B5",
"3 c #FEECC7",
"4 c #FDE0A8",
"5 c #FBCE77",
"6 c #FEE3A9",
"7 c #FEEBC3",
"8 c #FBD892",
"9 c #FAC867",
"0 c #FEE0A3",
"a c #FEE9BF",
"b c #F9BC46",
"c c #F9B73A",
"d c #FCD27A",
"e c #F8B636",
"f c #FBCC6B",
"g c #FCDB99",
"h c #F8B433",
"i c #FBC863",
"j c #FAC55A",
"k c #FAC55B",
"l c #FBCC70",
"m c #F8B330",
"............. ",
".+@#$%&*=-;>. ",
".@#$%&*=,')!. ",
".~{]^/^(_:<[. ",
".{}_(^(_::|1. ",
".23:_(_:::45. ",
".67::_:::_89. ",
".0a:::::_(9b. ",
".=,_:::_(^bc. ",
".d;(_:_(^/ce. ",
".f>!g489bceh. ",
".ijkl59bcehm. ",
"............. ",
" ",
" "};

View file

@ -1,402 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: checkedlistctrl.cpp
// Purpose: wxCheckedListCtrl
// Author: Unknown ? (found at http://wiki.wxwidgets.org/wiki.pl?WxListCtrl)
// Modified by: Francesco Montorsi
// Created: 2005/06/29
// RCS-ID: $Id: checkedlistctrl.cpp 1309 2010-05-01 09:49:59Z frm $
// Copyright: (c) 2005 Francesco Montorsi
// Licence: wxWidgets licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// includes
#include "wxgui/wxcomponents/checkedlistctrl.h"
#include <wx/icon.h>
#include <wx/settings.h>
#if wxUSE_CHECKEDLISTCTRL
// resources
#include "wxgui/wxcomponents/checked.xpm"
#include "wxgui/wxcomponents/unchecked.xpm"
#include "wxgui/wxcomponents/checked_dis.xpm"
#include "wxgui/wxcomponents/unchecked_dis.xpm"
IMPLEMENT_CLASS(wxCheckedListCtrl, wxListCtrl)
BEGIN_EVENT_TABLE(wxCheckedListCtrl, wxListCtrl)
EVT_LEFT_DOWN(wxCheckedListCtrl::OnMouseEvent)
END_EVENT_TABLE()
DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_CHECKED);
DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_UNCHECKED);
// ------------------
// wxCHECKEDLISTCTRL
// ------------------
bool wxCheckedListCtrl::Create(wxWindow* parent, wxWindowID id, const wxPoint& pt,
const wxSize& sz, long style, const wxValidator& validator, const wxString& name)
{
if (!wxListCtrl::Create(parent, id, pt, sz, style, validator, name))
return FALSE;
SetImageList(&m_imageList, wxIMAGE_LIST_SMALL);
// the add order must respect the wxCLC_XXX_IMGIDX defines in the headers !
m_imageList.Add(wxIcon(unchecked_xpm));
m_imageList.Add(wxIcon(checked_xpm));
m_imageList.Add(wxIcon(unchecked_dis_xpm));
m_imageList.Add(wxIcon(checked_dis_xpm));
return TRUE;
}
/* static */
int wxCheckedListCtrl::GetItemImageFromAdditionalState(int addstate)
{
bool checked = (addstate & wxLIST_STATE_CHECKED) != 0;
bool enabled = (addstate & wxLIST_STATE_ENABLED) != 0;
if (checked && enabled)
return wxCLC_CHECKED_IMGIDX;
else if (checked && !enabled)
return wxCLC_DISABLED_CHECKED_IMGIDX;
else if (!checked && enabled)
return wxCLC_UNCHECKED_IMGIDX;
wxASSERT(!checked && !enabled); // this is the last possibility
return wxCLC_DISABLED_UNCHECKED_IMGIDX;
}
wxColour wxCheckedListCtrl::GetBgColourFromAdditionalState(int additionalstate)
{
if ((additionalstate & wxLIST_STATE_ENABLED) &&
this->IsEnabled())
return *wxWHITE;
#ifdef __WXMSW__
return wxColour(212, 208, 200);
#else
return wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
#endif
}
/* static */
int wxCheckedListCtrl::GetAndRemoveAdditionalState(long *state, int statemask)
{
int additionalstate = 0;
if (!state) return -1;
// extract the bits we are interested in
bool checked = (*state & wxLIST_STATE_CHECKED) != 0;
bool enabled = (*state & wxLIST_STATE_ENABLED) != 0;
// and set them in a different variable if they are included in the statemask
if (checked && (statemask & wxLIST_STATE_CHECKED)) additionalstate |= wxLIST_STATE_CHECKED;
if (enabled && (statemask & wxLIST_STATE_ENABLED)) additionalstate |= wxLIST_STATE_ENABLED;
// remove them from the original state var...
*state &= ~wxLIST_STATE_CHECKED;
*state &= ~wxLIST_STATE_ENABLED;
return additionalstate;
}
bool wxCheckedListCtrl::GetItem(wxListItem& info) const
{
// wx internal wxListCtrl::GetItem remove from the state mask the
// wxLIST_STATE_CHECKED & wxLIST_STATE_ENABLED bits since they
// are not part of wx standard flags... so we need to check those
// flags against the original wxListItem's statemask...
wxListItem original(info);
#ifdef __WXDEBUG__
// we always want to retrieve also the image state for checking purposes...
info.m_mask |= wxLIST_MASK_IMAGE;
#endif
if (!wxListCtrl::GetItem(info))
return FALSE;
// these are our additional supported states: read them from m_stateList
bool checked = (m_stateList[info.m_itemId] & wxLIST_STATE_CHECKED) != 0;
bool enabled = (m_stateList[info.m_itemId] & wxLIST_STATE_ENABLED) != 0;
// now intercept state requests about enable or check mode
if ((original.m_mask & wxLIST_MASK_STATE) &&
(original.m_stateMask & wxLIST_STATE_CHECKED)) {
info.m_state |= (m_stateList[info.m_itemId] & wxLIST_STATE_CHECKED);
info.m_stateMask |= wxLIST_STATE_CHECKED;
info.m_mask |= wxLIST_MASK_STATE; // contains valid info !
}
if ((original.m_mask & wxLIST_MASK_STATE) &&
(original.m_stateMask & wxLIST_STATE_ENABLED)) {
info.m_state |= (m_stateList[info.m_itemId] & wxLIST_STATE_ENABLED);
info.m_stateMask |= wxLIST_STATE_ENABLED;
info.m_mask |= wxLIST_MASK_STATE; // contains valid info !
}
// check that state & image are synch
#ifdef __WXDEBUG__
wxASSERT_MSG((int)m_stateList.GetCount() == (int)GetItemCount(),
wxS("Something wrong ! See InsertItem()"));
// read info by image index
bool imagecheck = (info.m_image == wxCLC_CHECKED_IMGIDX) ||
(info.m_image == wxCLC_DISABLED_CHECKED_IMGIDX);
bool imageenabled = (info.m_image == wxCLC_CHECKED_IMGIDX) ||
(info.m_image == wxCLC_UNCHECKED_IMGIDX);
wxASSERT_MSG((checked && imagecheck) || (!checked && !imagecheck),
wxS("This is item has checked state but it's shown as unchecked (or viceversa)"));
wxASSERT_MSG((enabled && imageenabled) || (!enabled && !imageenabled),
wxS("This is item has enabled state but it's shown as disabled (or viceversa)"));
#endif
return TRUE;
}
bool wxCheckedListCtrl::SetItem(wxListItem& info)
{
// remove the checked & enabled states from the state flag:
// we'll store them in our separate array
int additionalstate = GetAndRemoveAdditionalState(&info.m_state, info.m_stateMask);
// set image index
// we will ignore the info.m_image field since we need
// to overwrite it...
if (info.m_mask & wxLIST_MASK_STATE) {
// if some state is not included in the state mask, then get the state info
// from our internal state array
if (!(info.m_stateMask & wxLIST_STATE_ENABLED))
additionalstate |= (m_stateList[info.m_itemId] & wxLIST_STATE_ENABLED);
if (!(info.m_stateMask & wxLIST_STATE_CHECKED))
additionalstate |= (m_stateList[info.m_itemId] & wxLIST_STATE_CHECKED);
// state is valid: use it to determine the image to set...
info.m_mask |= wxLIST_MASK_IMAGE;
info.m_image = GetItemImageFromAdditionalState(additionalstate);
// since when changing the background color, also the foreground color
// and the font of the item are changed, we try to respect the user
// choices of such attributes
info.SetTextColour(this->GetItemTextColour(info.GetId()));
#if wxCHECK_VERSION(2, 6, 2)
// before wx 2.6.2 the wxListCtrl::SetItemFont function is missing
info.SetFont(this->GetItemFont(info.GetId()));
#endif
// change the background color to respect the enabled/disabled status...
info.SetBackgroundColour(GetBgColourFromAdditionalState(additionalstate));
m_stateList[info.m_itemId] = additionalstate;
} else {
// state is invalid; don't change image
info.m_mask &= ~wxLIST_MASK_IMAGE;
}
// save the changes
return wxListCtrl::SetItem(info);
}
long wxCheckedListCtrl::InsertItem(wxListItem &info)
{
int additionalstate = GetAndRemoveAdditionalState(&info.m_state, info.m_stateMask);
if (!(info.m_mask & wxLIST_MASK_STATE) ||
!(info.m_stateMask & wxLIST_STATE_ENABLED)) {
// if not specified, the default additional state is ENABLED
additionalstate = wxLIST_STATE_ENABLED;
}
// we always want to insert items with images...
info.m_mask |= wxLIST_MASK_IMAGE;
info.m_image = GetItemImageFromAdditionalState(additionalstate);
info.SetBackgroundColour(GetBgColourFromAdditionalState(additionalstate));
int itemcount = GetItemCount();
wxASSERT_MSG(info.m_itemId <= itemcount, wxS("Invalid index !"));
wxASSERT_MSG((int)m_stateList.GetCount() == (int)GetItemCount(),
wxS("Something wrong !"));
if (info.m_itemId == itemcount) {
// we are adding a new item at the end of the list
m_stateList.Add(additionalstate);
} else {
// we must shift all following items
cemu_assert_suspicious();
//for (int i=itemcount; i > info.m_itemId; i--)
// m_stateList[i] = m_stateList[i-1];
m_stateList[info.m_itemId] = additionalstate;
}
return wxListCtrl::InsertItem(info);
}
bool wxCheckedListCtrl::SetItemState(long item, long state, long stateMask)
{
wxListItem li;
li.SetId(item);
li.SetMask(wxLIST_MASK_STATE);
li.SetState(state);
li.SetStateMask(stateMask);
// so we are sure to use wxCheckedListCtrl::SetItem
// (and not wxListCtrl::SetItem)
return SetItem(li);
}
int wxCheckedListCtrl::GetItemState(long item, long stateMask) const
{
wxListItem li;
li.SetId(item);
li.SetMask(wxLIST_MASK_STATE);
li.SetStateMask(stateMask);
// so we are sure to use wxCheckedListCtrl::GetItem
// (and not wxListCtrl::GetItem)
if (!GetItem(li))
return -1;
return li.GetState();
}
long wxCheckedListCtrl::SetItem(long index, int col, const wxString& label, int WXUNUSED(imageId))
{
wxListItem li;
li.SetId(index);
li.SetColumn(col);
li.SetText(label);
li.SetMask(wxLIST_MASK_TEXT);
// so we are sure to use wxCheckedListCtrl::SetItem
// (and not wxListCtrl::SetItem)
return SetItem(li);
}
long wxCheckedListCtrl::InsertItem( long index, const wxString& label, int WXUNUSED(imageIndex) )
{
wxListItem info;
info.m_text = label;
info.m_mask = wxLIST_MASK_TEXT;
info.m_itemId = index;
return InsertItem(info);
}
void wxCheckedListCtrl::Check(long item, bool checked)
{
// NB: the "statemask" is not the "mask" of a list item;
// in the "mask" you use the wxLIST_MASK_XXXX defines;
// in the "statemask" you use the wxLIST_STATE_XXX defines
// to set a specific bit of the wxListInfo::m_state var
if (checked)
// the 2nd parameter says: activate the STATE bit relative to CHECK feature
// the 3rd parameter says: set only *that* bit
SetItemState(item, wxLIST_STATE_CHECKED, wxLIST_STATE_CHECKED);
else
SetItemState(item, 0, wxLIST_STATE_CHECKED);
}
void wxCheckedListCtrl::Enable(long item, bool enable)
{
if (enable)
// the 2nd parameter says: activate the STATE bit relative to ENABLE feature
// the 3rd parameter says: set only *that* bit
SetItemState(item, wxLIST_STATE_ENABLED, wxLIST_STATE_ENABLED);
else
SetItemState(item, 0, wxLIST_STATE_ENABLED);
}
void wxCheckedListCtrl::EnableAll(bool enable)
{
for (int i=0; i < GetItemCount(); i++)
Enable(i, enable);
}
void wxCheckedListCtrl::CheckAll(bool check)
{
for (int i=0; i < GetItemCount(); i++)
Check(i, check);
}
bool wxCheckedListCtrl::DeleteItem(long item)
{
// shift our additional state array
//for (int i=item,max=GetItemCount(); i < max-1; i++)
// m_stateList[i] = m_stateList[i+1];
m_stateList.RemoveAt(item, 1);
return wxListCtrl::DeleteItem(item);
}
int wxCheckedListCtrl::GetCheckedItemCount() const
{
int res = 0;
for (int i=0; i<GetItemCount(); i++)
if (IsChecked(i))
res++;
return res;
}
// event handlers
void wxCheckedListCtrl::OnMouseEvent(wxMouseEvent& event)
{
if (!event.LeftDown()) {
event.Skip();
return;
}
int flags;
long item = HitTest(event.GetPosition(), flags);
if (item == wxNOT_FOUND || !IsEnabled(item)) {
// skip this item
event.Skip();
return;
}
// user clicked exactly on the checkbox or on the item row ?
bool processcheck = (flags & wxLIST_HITTEST_ONITEMICON) ||
((GetWindowStyle() & wxCLC_CHECK_WHEN_SELECTING) &&
(flags & wxLIST_HITTEST_ONITEM));
if (processcheck) {
wxListEvent ev(wxEVT_NULL, GetId());
ev.m_itemIndex = item;
// send the check event
if (IsChecked(item)) {
ev.SetEventType(wxEVT_COMMAND_LIST_ITEM_UNCHECKED);
Check(item, FALSE);
AddPendingEvent(ev);
} else {
ev.SetEventType(wxEVT_COMMAND_LIST_ITEM_CHECKED);
Check(item, TRUE);
AddPendingEvent(ev);
}
}
event.Skip();
}
#endif // wxUSE_CHECKEDLISTCTRL

View file

@ -1,178 +0,0 @@
#pragma once
/////////////////////////////////////////////////////////////////////////////
// Name: checkedlistctrl.h
// Purpose: wxCheckedListCtrl
// Author: Unknown ? (found at http://wiki.wxwidgets.org/wiki.pl?WxListCtrl)
// Modified by: Francesco Montorsi
// Created: 2005/06/29
// RCS-ID: $Id: checkedlistctrl.h 448 2007-03-06 22:06:38Z frm $
// Copyright: (c) 2005 Francesco Montorsi
// Licence: wxWidgets licence
/////////////////////////////////////////////////////////////////////////////
#define wxUSE_CHECKEDLISTCTRL 1
#ifndef _WX_CHECKEDLISTCTRL_H_
#define _WX_CHECKEDLISTCTRL_H_
// wxWidgets headers
//#include "wx/webupdatedef.h" // for the WXDLLIMPEXP_WEBUPDATE macro
#include <wx/listctrl.h>
#include <wx/imaglist.h>
#if wxUSE_CHECKEDLISTCTRL
// image indexes (used internally by wxCheckedListCtrl)
#define wxCLC_UNCHECKED_IMGIDX 0 // unchecked & enabled
#define wxCLC_CHECKED_IMGIDX 1 // checked & enabled
#define wxCLC_DISABLED_UNCHECKED_IMGIDX 2 // unchecked & disabled
#define wxCLC_DISABLED_CHECKED_IMGIDX 3 // checked & disabled
// additional state flags (wx's defines should end at 0x0100; see listbase.h)
#define wxLIST_STATE_CHECKED 0x010000
#define wxLIST_STATE_ENABLED 0x100000
// additional wxCheckedListCtrl style flags
// (wx's defines should at 0x8000; see listbase.h)
#define wxCLC_CHECK_WHEN_SELECTING 0x10000
// -------------------------
// wxCheckedListCtrl events
// -------------------------
//DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_WEBUPDATE, wxEVT_COMMAND_LIST_ITEM_CHECKED, -1);
//DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_WEBUPDATE, wxEVT_COMMAND_LIST_ITEM_UNCHECKED, -1);
DECLARE_EXPORTED_EVENT_TYPE(WXEXPORT, wxEVT_COMMAND_LIST_ITEM_CHECKED, -1);
DECLARE_EXPORTED_EVENT_TYPE(WXEXPORT, wxEVT_COMMAND_LIST_ITEM_UNCHECKED, -1);
//DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_CHECKED);
//DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_UNCHECKED);
#ifndef EVT_LIST_ITEM_CHECKED
#define EVT_LIST_ITEM_CHECKED(id, fn) \
DECLARE_EVENT_TABLE_ENTRY( \
wxEVT_COMMAND_LIST_ITEM_CHECKED, id, -1, \
(wxObjectEventFunction)(wxEventFunction)(wxListEventFunction)&fn, \
(wxObject *) NULL \
),
#endif
#ifndef EVT_LIST_ITEM_UNCHECKED
#define EVT_LIST_ITEM_UNCHECKED(id, fn) \
DECLARE_EVENT_TABLE_ENTRY( \
wxEVT_COMMAND_LIST_ITEM_UNCHECKED, id, -1, \
(wxObjectEventFunction)(wxEventFunction)(wxListEventFunction)&fn, \
(wxObject *) NULL \
),
#endif
//! This is the class which performs all transactions with the server.
//! It uses the wxSocket facilities.
class wxCheckedListCtrl : public wxListView
{
protected:
// we have to keep a different array to keep track of the additional
// states we support....
wxArrayInt m_stateList;
// our set of checkbox images...
wxImageList m_imageList;
public:
wxCheckedListCtrl()
: wxListView(), m_imageList(16, 16, TRUE) {}
wxCheckedListCtrl(wxWindow *parent, wxWindowID id = wxID_ANY,
const wxPoint& pt = wxDefaultPosition,
const wxSize& sz = wxDefaultSize,
long style = wxCLC_CHECK_WHEN_SELECTING,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxListCtrlNameStr)
: wxListView(), m_imageList(16, 16, TRUE)
{ Create(parent, id, pt, sz, style, validator, name); }
bool Create(wxWindow *parent, wxWindowID id = wxID_ANY,
const wxPoint& pt = wxDefaultPosition,
const wxSize& sz = wxDefaultSize,
long style = wxCLC_CHECK_WHEN_SELECTING,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxListCtrlNameStr);
virtual ~wxCheckedListCtrl() {}
public: // utilities
// core overloads (i.e. the most generic overloads)
bool GetItem(wxListItem& info) const;
bool SetItem(wxListItem& info);
long InsertItem(wxListItem& info);
bool DeleteItem(long item);
bool DeleteAllItems()
{ m_stateList.Clear(); return wxListCtrl::DeleteAllItems(); }
bool SortItems(wxListCtrlCompare, long)
{ wxASSERT_MSG(0, wxT("Not implemented yet ! sorry... ")); return FALSE; }
// shortcuts to the SetItemState function
void Check(long item, bool checked);
void Enable(long item, bool enable);
void CheckAll(bool checked = true);
void EnableAll(bool enable = true);
// this needs to be redeclared otherwise it's hidden by our other Enable() function.
// However you should use #EnableAll instead of this function if you want to get
// good graphics (try to understand)
virtual bool Enable(bool enable = true)
{ return wxListCtrl::Enable(enable); }
// shortcuts to the GetItemState function
bool IsChecked(long item) const
{ return GetItemState(item, wxLIST_STATE_CHECKED) != 0; }
bool IsEnabled(long item) const
{ return GetItemState(item, wxLIST_STATE_ENABLED) != 0; }
// this needs to be redeclared otherwise it's hidden by our other IsEnabled() function.
bool IsEnabled() const
{ return wxWindow::IsEnabled(); }
//! Returns the number of checked items in the control.
int GetCheckedItemCount() const;
// we overload these so we are sure they will use our
// #GetItem and #SetItem functions...
bool SetItemState(long item, long state, long stateMask);
int GetItemState(long item, long stateMask) const;
long InsertItem( long index, const wxString& label, int imageIndex = -1);
long SetItem(long index, int col, const wxString& label, int imageId = -1);
// the image associated with an element is already in used by wxCheckedListCtrl
// itself to show the checkbox and it cannot be handled by the user !
bool SetItemImage(long, int)
{ wxASSERT_MSG(0, wxT("This function cannot be used with wxCheckedListCtrl !")); return FALSE; }
protected: // event handlers
void OnMouseEvent(wxMouseEvent& event);
protected: // internal utilities
static int GetItemImageFromAdditionalState(int addstate);
static int GetAndRemoveAdditionalState(long *state, int statemask);
wxColour GetBgColourFromAdditionalState(int additionalstate);
private:
DECLARE_CLASS(wxCheckedListCtrl)
DECLARE_EVENT_TABLE()
};
#endif // wxUSE_CHECKEDLISTCTRL
#endif // _WX_CHECKEDLISTCTRL_H_

View file

@ -1,14 +1,9 @@
#include "wxgui/wxcomponents/checktree.h" #include "wxgui/wxcomponents/checktree.h"
#include "wxgui/wxcomponents/checked2.xpm"
#include "wxgui/wxcomponents/checked_d.xpm" #include <wx/dcmemory.h>
#include "wxgui/wxcomponents/checked_ld.xpm"
#include "wxgui/wxcomponents/checked_mo.xpm"
#include "wxgui/wxcomponents/unchecked2.xpm"
#include "wxgui/wxcomponents/unchecked_d.xpm"
#include "wxgui/wxcomponents/unchecked_ld.xpm"
#include "wxgui/wxcomponents/unchecked_mo.xpm"
#include <wx/icon.h> #include <wx/icon.h>
#include <wx/imaglist.h> #include <wx/imaglist.h>
#include <wx/renderer.h>
wxDEFINE_EVENT(wxEVT_CHECKTREE_FOCUS, wxTreeEvent); wxDEFINE_EVENT(wxEVT_CHECKTREE_FOCUS, wxTreeEvent);
wxDEFINE_EVENT(wxEVT_CHECKTREE_CHOICE, wxTreeEvent); wxDEFINE_EVENT(wxEVT_CHECKTREE_CHOICE, wxTreeEvent);
@ -108,16 +103,80 @@ wxCheckTree::wxCheckTree(wxWindow* parent, const wxWindowID id, const wxPoint& p
void wxCheckTree::Init() void wxCheckTree::Init()
{ {
wxIcon icons[8] = int width = wxRendererNative::Get().GetCheckBoxSize(this).GetWidth();
{ int height = wxRendererNative::Get().GetCheckBoxSize(this).GetHeight();
wxIcon(unchecked2_xpm), wxIcon(unchecked_mo_xpm), wxIcon(unchecked_ld_xpm), wxIcon(unchecked_d_xpm), wxIcon(checked2_xpm), wxIcon(checked_mo_xpm), wxIcon(checked_ld_xpm), wxIcon(checked_d_xpm)
};
// Make an state image list containing small icons auto states = new wxImageList(width, height, true);
auto states = new wxImageList(icons[0].GetWidth(), icons[0].GetHeight(), true);
for (const auto& icon : icons) wxBitmap unchecked_bmp(width, height);
states->Add(icon); wxBitmap unchecked_mouse_over_bmp(width, height);
wxBitmap unchecked_left_down_bmp(width, height);
wxBitmap unchecked_disabled_bmp(width, height);
wxBitmap checked_bmp(width, height);
wxBitmap checked_mouse_over_bmp(width, height);
wxBitmap checked_left_down_bmp(width, height);
wxBitmap checked_disabled_bmp(width, height);
wxMemoryDC renderer_dc;
// Unchecked
renderer_dc.SelectObject(unchecked_bmp);
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
renderer_dc.Clear();
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_NONE);
// Unchecked Mouse Over
renderer_dc.SelectObject(unchecked_mouse_over_bmp);
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
renderer_dc.Clear();
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_CURRENT);
// Unchecked and Disabled
renderer_dc.SelectObject(unchecked_disabled_bmp);
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
renderer_dc.Clear();
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_DISABLED);
// Unchecked Left Down
renderer_dc.SelectObject(unchecked_left_down_bmp);
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
renderer_dc.Clear();
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_CURRENT | wxCONTROL_PRESSED);
// Checked
renderer_dc.SelectObject(checked_bmp);
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
renderer_dc.Clear();
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_CHECKED);
// Checked Mouse Over
renderer_dc.SelectObject(checked_mouse_over_bmp);
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
renderer_dc.Clear();
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_CHECKED | wxCONTROL_CURRENT);
// Checked Left Down
renderer_dc.SelectObject(checked_left_down_bmp);
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
renderer_dc.Clear();
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_CHECKED | wxCONTROL_CURRENT | wxCONTROL_PRESSED);
// Checked and Disabled
renderer_dc.SelectObject(checked_disabled_bmp);
renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID));
renderer_dc.Clear();
wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, width, height), wxCONTROL_CHECKED | wxCONTROL_DISABLED);
renderer_dc.SelectObject(wxNullBitmap);
states->Add(unchecked_bmp);
states->Add(unchecked_mouse_over_bmp);
states->Add(unchecked_left_down_bmp);
states->Add(unchecked_disabled_bmp);
states->Add(checked_bmp);
states->Add(checked_mouse_over_bmp);
states->Add(checked_left_down_bmp);
states->Add(checked_disabled_bmp);
AssignStateImageList(states); AssignStateImageList(states);
@ -173,7 +232,7 @@ void wxCheckTree::SetItemTextColour(const wxTreeItemId& item, const wxColour& co
{ {
const auto it = m_colors.find(item); const auto it = m_colors.find(item);
if (it == m_colors.end()) if (it == m_colors.end())
m_colors.emplace(std::pair<wxTreeItemId,wxColor>(item, col)); m_colors.emplace(std::pair<wxTreeItemId,wxColour>(item, col));
else else
m_colors[item] = col; m_colors[item] = col;
@ -218,7 +277,7 @@ bool wxCheckTree::EnableCheckBox(const wxTreeItemId& item, bool enable)
else if (state == CHECKED || state == CHECKED_MOUSE_OVER || state == CHECKED_LEFT_DOWN) else if (state == CHECKED || state == CHECKED_MOUSE_OVER || state == CHECKED_LEFT_DOWN)
SetItemState(item, CHECKED_DISABLED); SetItemState(item, CHECKED_DISABLED);
const wxColor col = GetItemTextColour(item); const wxColour col = GetItemTextColour(item);
SetItemTextColour(item, wxColour(161, 161, 146)); SetItemTextColour(item, wxColour(161, 161, 146));
m_colors[item] = col; m_colors[item] = col;
return true; return true;

View file

@ -82,7 +82,7 @@ class WXDLLIMPEXP_CHECKTREE wxCheckTree : public wxTreeCtrl
void On_Tree_Focus_Lost( wxFocusEvent& event ); void On_Tree_Focus_Lost( wxFocusEvent& event );
//private data: //private data:
std::map<wxTreeItemId,wxColor> m_colors; std::map<wxTreeItemId,wxColour> m_colors;
bool mouse_entered_tree_with_left_down = false; bool mouse_entered_tree_with_left_down = false;

View file

@ -1,24 +0,0 @@
/* XPM */
static const char * unchecked_xpm[] = {
"16 16 5 1",
" c None",
". c #808080",
"X c Black",
"o c #c0c0c0",
"w c White",
" ",
" ",
" ............ ",
" .XXXXXXXXXXo ",
" .Xwwwwwwwwwo ",
" .Xwwwwwwwwwo ",
" .Xwwwwwwwwwo ",
" .Xwwwwwwwwwo ",
" .Xwwwwwwwwwo ",
" .Xwwwwwwwwwo ",
" .Xwwwwwwwwwo ",
" .Xwwwwwwwwwo ",
" .Xwwwwwwwwwo ",
" .ooooooooooo ",
" ",
" "};

View file

@ -1,37 +0,0 @@
/* XPM */
static const char * unchecked2_xpm[] = {
"14 15 19 1",
" c None",
". c #1C5180",
"+ c #DCDCD7",
"@ c #DEDED9",
"# c #E0E0DB",
"$ c #E2E2DE",
"% c #E5E5E2",
"& c #E8E8E5",
"* c #ECECE9",
"= c #EFEFEC",
"- c #F1F1EF",
"; c #F3F3F1",
"> c #F5F5F4",
", c #F7F7F6",
"' c #F9F9F8",
") c #FBFBFA",
"! c #FDFDFC",
"~ c #FEFEFE",
"{ c #FFFFFF",
"............. ",
".+++@#$%&*=-. ",
".++@#$%&*=-;. ",
".+@#$%&*=-;>. ",
".@#$%&*=-;>,. ",
".#$%&*=-;>,'. ",
".$%&*=-;>,'). ",
".%&*=-;>,')!. ",
".&*=-;>,')!~. ",
".*=-;>,')!~{. ",
".=-;>,')!~{{. ",
".-;>,')!~{{{. ",
"............. ",
" ",
" "};

View file

@ -1,21 +0,0 @@
/* XPM */
static const char * unchecked_d_xpm[] = {
"14 15 3 1",
" c None",
". c #CAC8BB",
"+ c #FFFFFF",
"............. ",
".+++++++++++. ",
".+++++++++++. ",
".+++++++++++. ",
".+++++++++++. ",
".+++++++++++. ",
".+++++++++++. ",
".+++++++++++. ",
".+++++++++++. ",
".+++++++++++. ",
".+++++++++++. ",
".+++++++++++. ",
"............. ",
" ",
" "};

View file

@ -1,23 +0,0 @@
/* XPM */
static const char * unchecked_dis_xpm[] = {
"16 16 4 1",
" c None",
". c #808080",
"X c Black",
"o c #c0c0c0",
" ",
" ",
" ............ ",
" .XXXXXXXXXXo ",
" .Xoooooooooo ",
" .Xoooooooooo ",
" .Xoooooooooo ",
" .Xoooooooooo ",
" .Xoooooooooo ",
" .Xoooooooooo ",
" .Xoooooooooo ",
" .Xoooooooooo ",
" .Xoooooooooo ",
" .ooooooooooo ",
" ",
" "};

View file

@ -1,37 +0,0 @@
/* XPM */
static const char * unchecked_ld_xpm[] = {
"14 15 19 1",
" c None",
". c #1C5180",
"+ c #B0B0A7",
"@ c #B3B3AA",
"# c #B7B7AD",
"$ c #BCBBB1",
"% c #C1C1B6",
"& c #C7C6BB",
"* c #CDCCC0",
"= c #D2D1C5",
"- c #D7D5C8",
"; c #DBDACC",
"> c #DFDDCF",
", c #E3E1D3",
"' c #E6E5D6",
") c #EAE8D9",
"! c #EDEBDB",
"~ c #EFEDDD",
"{ c #F1EFDF",
"............. ",
".+++@#$%&*=-. ",
".++@#$%&*=-;. ",
".+@#$%&*=-;>. ",
".@#$%&*=-;>,. ",
".#$%&*=-;>,'. ",
".$%&*=-;>,'). ",
".%&*=-;>,')!. ",
".&*=-;>,')!~. ",
".*=-;>,')!~{. ",
".=-;>,')!~{{. ",
".-;>,')!~{{{. ",
"............. ",
" ",
" "};

View file

@ -1,42 +0,0 @@
/* XPM */
static const char * unchecked_mo_xpm[] = {
"14 15 24 1",
" c None",
". c #1C5180",
"+ c #FFF0CF",
"@ c #FFEDC6",
"# c #FFE9BA",
"$ c #FEE4AC",
"% c #FEDF9C",
"& c #FDD98C",
"* c #FDD684",
"= c #FCD37C",
"- c #FCD074",
"; c #FBCC6B",
"> c #FBC863",
", c #FAC55A",
"' c #E7E7E3",
") c #FAC254",
"! c #FAC04E",
"~ c #F9BD48",
"{ c #F9BB43",
"] c #F9B93E",
"^ c #F9B73A",
"/ c #F8B636",
"( c #F8B433",
"_ c #F8B330",
"............. ",
".+@#$%&*=-;>. ",
".@#$%&*=-;>,. ",
".#$''''''',). ",
".$%''''''')!. ",
".%&'''''''!~. ",
".&*'''''''~{. ",
".*='''''''{]. ",
".=-''''''']^. ",
".-;'''''''^/. ",
".;>,)!~{]^/(. ",
".>,)!~{]^/(_. ",
"............. ",
" ",
" "};

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#undef GetHwnd
#include <dxgi1_4.h> #include <dxgi1_4.h>
#include <wrl/client.h> #include <wrl/client.h>

View file

@ -1,7 +1,7 @@
{ {
"name": "cemu", "name": "cemu",
"version-string": "1.0", "version-string": "1.0",
"builtin-baseline": "a4275b7eee79fb24ec2e135481ef5fce8b41c339", "builtin-baseline": "f0fb3ddba5135b80982668de39dbaa139c00d281",
"dependencies": [ "dependencies": [
"pugixml", "pugixml",
"zlib", "zlib",
@ -36,13 +36,18 @@
"zstd", "zstd",
{ {
"name": "wxwidgets", "name": "wxwidgets",
"features": [
"debug-support"
],
"default-features": false "default-features": false
}, },
"openssl", "openssl",
{ {
"name": "curl", "name": "curl",
"default-features": false, "default-features": false,
"features": [ "openssl" ] "features": [
"openssl"
]
}, },
{ {
"name": "dbus", "name": "dbus",
@ -52,7 +57,10 @@
{ {
"name": "tiff", "name": "tiff",
"default-features": false, "default-features": false,
"features": ["jpeg", "zip"] "features": [
"jpeg",
"zip"
]
}, },
"libusb" "libusb"
], ],
@ -64,6 +72,10 @@
{ {
"name": "sdl2", "name": "sdl2",
"version": "2.30.3" "version": "2.30.3"
},
{
"name": "wxwidgets",
"version": "3.3.1"
} }
] ]
} }