Compare commits

...

8 Commits

Author SHA1 Message Date
chaoticgd
d8187fbea4 Deps: Specify minimum version of KDDockWidgets 2025-06-04 20:02:02 -04:00
chaoticgd
02259ad0a5 Debugger: Add include required for older versions of KDDockWidgets 2025-06-04 20:02:02 -04:00
TellowKrinkle
220a68df9a GS: Warn on texture replacement folder with wrong case 2025-06-04 19:58:41 -04:00
TellowKrinkle
2ced24f69e GS: Create texture dump directory if it doesn't exist 2025-06-04 19:58:41 -04:00
TellowKrinkle
ec91d0dc74 GS: Formatting 2025-06-04 19:58:41 -04:00
TheLastRar
46874f4673 Qt: Add workaround for incorrectly tinted icons after theme switch 2025-06-04 19:39:18 -04:00
TheLastRar
9eac47dc6c Qt: Fix selected gamelist icons being wrong colour after theme switch 2025-06-04 19:39:18 -04:00
RedDevilus
9e3fd5c2e0 CI: Fix flatpak
Try to fix build failing
2025-06-04 20:19:46 +01:00
7 changed files with 83 additions and 37 deletions

View File

@@ -11,10 +11,9 @@
},
"sources": [
{
"type": "git",
"type": "git",
"url": "https://github.com/sammycage/plutovg.git",
"tag": "v0.0.13",
"sha256": "5e4712cf873b0c7829a4a6157763e2ad3ac49164"
"tag": "v0.0.13"
}
],
"cleanup": [

View File

@@ -12,10 +12,9 @@
},
"sources": [
{
"type": "git",
"type": "git",
"url": "https://github.com/sammycage/plutosvg.git",
"tag": "v0.0.6",
"sha256": "c5388fa96feca1f1376a3d0485d5e35159452707"
"tag": "v0.0.6"
}
],
"cleanup": [

View File

@@ -120,7 +120,7 @@ add_subdirectory(3rdparty/demangler EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/ccc EXCLUDE_FROM_ALL)
# The docking system for the debugger.
find_package(KDDockWidgets-qt6 REQUIRED)
find_package(KDDockWidgets-qt6 2.0.0 REQUIRED)
# Add an extra include path to work around a broken include directive.
# TODO: Remove this the next time we update KDDockWidgets.
get_target_property(KDDOCKWIDGETS_INCLUDE_DIRECTORY KDAB::kddockwidgets INTERFACE_INCLUDE_DIRECTORIES)

View File

@@ -10,6 +10,7 @@
#include <kddockwidgets/Config.h>
#include <kddockwidgets/core/Group.h>
#include <kddockwidgets/core/Platform.h>
#include <kddockwidgets/core/indicators/SegmentedDropIndicatorOverlay.h>
#include <kddockwidgets/qtwidgets/ViewFactory.h>

View File

@@ -138,16 +138,15 @@ namespace
if (option.state & QStyle::State_Selected)
{
// See QItemDelegate::selectedPixmap()
QString key = QString::fromStdString(fmt::format("{:016X}-{:d}", pix.cacheKey(), enabled));
QColor color = option.palette.color(enabled ? QPalette::Normal : QPalette::Disabled, QPalette::Highlight);
color.setAlphaF(0.3f);
QString key = QString::fromStdString(fmt::format("{:016X}-{:d}-{:08X}", pix.cacheKey(), enabled, color.rgba()));
QPixmap pm;
if (!QPixmapCache::find(key, &pm))
{
QImage img = pix.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
QColor color = option.palette.color(enabled ? QPalette::Normal : QPalette::Disabled,
QPalette::Highlight);
color.setAlphaF(0.3f);
QPainter tinted_painter(&img);
tinted_painter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
tinted_painter.fillRect(0, 0, img.width(), img.height(), color);

View File

@@ -10,6 +10,7 @@
#include <QtCore/QFile>
#include <QtGui/QPalette>
#include <QtGui/QPixmapCache>
#include <QtWidgets/QApplication>
#include <QtWidgets/QStyle>
#include <QtWidgets/QStyleFactory>
@@ -43,6 +44,12 @@ void QtHost::UpdateApplicationTheme()
SetStyleFromSettings();
SetIconThemeFromStyle();
// Qt generates tinted versions of icons and stores them in QPixmapCache
// The key used does not seem to include the theme (or tint colour).
// This can cause icons tinted for wrong theme to be used for selected/disabled.
// As a workaround, reset the pixmap cache to clear icons tinted for the old theme.
QPixmapCache::clear();
}
bool QtHost::IsDarkApplicationTheme()

View File

@@ -270,56 +270,57 @@ std::string GSTextureReplacements::GetDumpFilename(const TextureName& name, u32
return ret;
const std::string game_dir(GetGameTextureDirectory());
if (!FileSystem::DirectoryExists(game_dir.c_str()))
const std::string game_subdir(Path::Combine(game_dir, TEXTURE_DUMP_SUBDIRECTORY_NAME));
if (!FileSystem::DirectoryExists(game_subdir.c_str()))
{
// create both dumps and replacements
if (!FileSystem::CreateDirectoryPath(game_dir.c_str(), false) ||
!FileSystem::EnsureDirectoryExists(Path::Combine(game_dir, "dumps").c_str(), false) ||
!FileSystem::EnsureDirectoryExists(Path::Combine(game_dir, "replacements").c_str(), false))
!FileSystem::EnsureDirectoryExists(game_subdir.c_str(), false) ||
!FileSystem::EnsureDirectoryExists(Path::Combine(game_dir, TEXTURE_REPLACEMENT_SUBDIRECTORY_NAME).c_str(), false))
{
// if it fails to create, we're not going to be able to use it anyway
return ret;
}
}
const std::string game_subdir(Path::Combine(game_dir, TEXTURE_DUMP_SUBDIRECTORY_NAME));
std::string filename;
if (name.HasRegion())
{
if (name.HasPalette())
{
filename = (level > 0) ?
StringUtil::StdStringFromFormat(TEXTURE_FILENAME_REGION_CLUT_FORMAT_STRING "-mip%u.png",
name.TEX0Hash, name.CLUTHash, name.region_width, name.region_height, name.bits, level) :
StringUtil::StdStringFromFormat(TEXTURE_FILENAME_REGION_CLUT_FORMAT_STRING ".png",
name.TEX0Hash, name.CLUTHash, name.region_width, name.region_height, name.bits);
filename = (level > 0)
? StringUtil::StdStringFromFormat(TEXTURE_FILENAME_REGION_CLUT_FORMAT_STRING "-mip%u.png",
name.TEX0Hash, name.CLUTHash, name.region_width, name.region_height, name.bits, level)
: StringUtil::StdStringFromFormat(TEXTURE_FILENAME_REGION_CLUT_FORMAT_STRING ".png",
name.TEX0Hash, name.CLUTHash, name.region_width, name.region_height, name.bits);
}
else
{
filename = (level > 0) ? StringUtil::StdStringFromFormat(
TEXTURE_FILENAME_REGION_FORMAT_STRING "-mip%u.png", name.TEX0Hash,
name.region_width, name.region_height, name.bits, level) :
StringUtil::StdStringFromFormat(
TEXTURE_FILENAME_REGION_FORMAT_STRING ".png", name.TEX0Hash,
name.region_width, name.region_height, name.bits);
filename = (level > 0)
? StringUtil::StdStringFromFormat(TEXTURE_FILENAME_REGION_FORMAT_STRING "-mip%u.png",
name.TEX0Hash, name.region_width, name.region_height, name.bits, level)
: StringUtil::StdStringFromFormat(TEXTURE_FILENAME_REGION_FORMAT_STRING ".png",
name.TEX0Hash, name.region_width, name.region_height, name.bits);
}
}
else
{
if (name.HasPalette())
{
filename = (level > 0) ? StringUtil::StdStringFromFormat(TEXTURE_FILENAME_CLUT_FORMAT_STRING "-mip%u.png",
name.TEX0Hash, name.CLUTHash, name.bits, level) :
StringUtil::StdStringFromFormat(TEXTURE_FILENAME_CLUT_FORMAT_STRING ".png",
name.TEX0Hash, name.CLUTHash, name.bits);
filename = (level > 0)
? StringUtil::StdStringFromFormat(TEXTURE_FILENAME_CLUT_FORMAT_STRING "-mip%u.png",
name.TEX0Hash, name.CLUTHash, name.bits, level)
: StringUtil::StdStringFromFormat(TEXTURE_FILENAME_CLUT_FORMAT_STRING ".png",
name.TEX0Hash, name.CLUTHash, name.bits);
}
else
{
filename = (level > 0) ? StringUtil::StdStringFromFormat(
TEXTURE_FILENAME_FORMAT_STRING "-mip%u.png", name.TEX0Hash, name.bits, level) :
StringUtil::StdStringFromFormat(
TEXTURE_FILENAME_FORMAT_STRING ".png", name.TEX0Hash, name.bits);
filename = (level > 0)
? StringUtil::StdStringFromFormat(TEXTURE_FILENAME_FORMAT_STRING "-mip%u.png",
name.TEX0Hash, name.bits, level)
: StringUtil::StdStringFromFormat(TEXTURE_FILENAME_FORMAT_STRING ".png",
name.TEX0Hash, name.bits);
}
}
@@ -349,6 +350,28 @@ void GSTextureReplacements::GameChanged()
ClearDumpedTextureList();
}
/// If the given file exists in the given directory, but with a different case than the original file, write its path to `*output` and return true.
static bool GetWrongCasePath(std::string* output, const char* dir, std::string_view file, FileSystem::FindResultsArray* reuseme)
{
if (FileSystem::FindFiles(dir, "*", FILESYSTEM_FIND_FOLDERS | FILESYSTEM_FIND_HIDDEN_FILES, reuseme))
{
for (const FILESYSTEM_FIND_DATA& fd : *reuseme)
{
std::string_view name = Path::GetFileName(fd.FileName);
if (name.size() != file.size())
continue;
if (0 == strncmp(name.data(), file.data(), name.size()))
continue;
if (0 == StringUtil::Strncasecmp(name.data(), file.data(), name.size()))
{
*output = fd.FileName;
return true;
}
}
}
return false;
}
void GSTextureReplacements::ReloadReplacementMap()
{
SyncWorkerThread();
@@ -368,9 +391,27 @@ void GSTextureReplacements::ReloadReplacementMap()
if (s_current_serial.empty() || !GSConfig.LoadTextureReplacements)
return;
const std::string replacement_dir(Path::Combine(GetGameTextureDirectory(), TEXTURE_REPLACEMENT_SUBDIRECTORY_NAME));
const std::string texture_dir = GetGameTextureDirectory();
const std::string replacement_dir(Path::Combine(texture_dir, TEXTURE_REPLACEMENT_SUBDIRECTORY_NAME));
FileSystem::FindResultsArray files;
// For some reason texture pack authors think it's a good idea to rename the replacements directory to something with the wrong case...
std::string wrong_case_path;
const std::string* right_case_path = nullptr;
if (GetWrongCasePath(&wrong_case_path, EmuFolders::Textures.c_str(), s_current_serial, &files))
right_case_path = &texture_dir;
else if (GetWrongCasePath(&wrong_case_path, texture_dir.c_str(), TEXTURE_REPLACEMENT_SUBDIRECTORY_NAME, &files))
right_case_path = &replacement_dir;
if (right_case_path)
{
Host::AddKeyedOSDMessage("TextureReplacementDirCaseMismatch",
fmt::format(TRANSLATE_FS("TextureReplacement", "Texture replacement directory {} will not work on case sensitive filesystems.\n"
"Rename it to {} to remove this warning."),
wrong_case_path, *right_case_path),
Host::OSD_WARNING_DURATION);
}
if (!FileSystem::FindFiles(replacement_dir.c_str(), "*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RECURSIVE, &files))
return;