Skip to content

Commit

Permalink
Qt: Add option to prefer English titles in Game List
Browse files Browse the repository at this point in the history
  • Loading branch information
TellowKrinkle committed Sep 10, 2023
1 parent d064635 commit e739535
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 18 deletions.
12 changes: 7 additions & 5 deletions pcsx2-qt/GameList/GameListModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ void GameListModel::loadOrGenerateCover(const GameList::Entry* ge)
// while there's outstanding jobs, the old jobs won't proceed (at the wrong size), or get added into the grid.
const u32 counter = m_cover_scale_counter.load(std::memory_order_acquire);

QFuture<QPixmap> future = QtConcurrent::run([this, path = ge->path, title = ge->title, serial = ge->serial, counter]() -> QPixmap {
QFuture<QPixmap> future = QtConcurrent::run([this, path = ge->path, title = ge->GetTitle(m_prefer_english_titles), serial = ge->serial, counter]() -> QPixmap {
QPixmap image;
if (m_cover_scale_counter.load(std::memory_order_acquire) == counter)
{
Expand Down Expand Up @@ -291,7 +291,7 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const
return QString::fromStdString(ge->serial);

case Column_Title:
return QString::fromStdString(ge->title);
return QString::fromStdString(ge->GetTitle(m_prefer_english_titles));

case Column_FileTitle:
return QtUtils::StringViewToQString(Path::GetFileTitle(ge->path));
Expand All @@ -316,7 +316,7 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const
case Column_Cover:
{
if (m_show_titles_for_covers)
return QString::fromStdString(ge->title);
return QString::fromStdString(ge->GetTitle(m_prefer_english_titles));
else
return {};
}
Expand All @@ -338,7 +338,7 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const

case Column_Title:
case Column_Cover:
return QString::fromStdString(ge->GetTitleSort());
return QString::fromStdString(ge->GetTitleSort(m_prefer_english_titles));

case Column_FileTitle:
return QtUtils::StringViewToQString(Path::GetFileTitle(ge->path));
Expand Down Expand Up @@ -421,6 +421,7 @@ QVariant GameListModel::headerData(int section, Qt::Orientation orientation, int

void GameListModel::refresh()
{
m_prefer_english_titles = Host::GetBaseBoolSettingValue("UI", "PreferEnglishGameList", false);
beginResetModel();
endResetModel();
}
Expand All @@ -435,7 +436,8 @@ bool GameListModel::titlesLessThan(int left_row, int right_row) const

const GameList::Entry* left = GameList::GetEntryByIndex(left_row);
const GameList::Entry* right = GameList::GetEntryByIndex(right_row);
return QtHost::LocaleSensitiveCompare(QString::fromStdString(left->GetTitleSort()), QString::fromStdString(right->GetTitleSort())) < 0;
return QtHost::LocaleSensitiveCompare(QString::fromStdString(left->GetTitleSort(m_prefer_english_titles)),
QString::fromStdString(right->GetTitleSort(m_prefer_english_titles))) < 0;
}

bool GameListModel::lessThan(const QModelIndex& left_index, const QModelIndex& right_index, int column) const
Expand Down
1 change: 1 addition & 0 deletions pcsx2-qt/GameList/GameListModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class GameListModel final : public QAbstractTableModel
float m_cover_scale = 0.0f;
std::atomic<u32> m_cover_scale_counter{0};
bool m_show_titles_for_covers = false;
bool m_prefer_english_titles = false;

std::array<QString, Column_Count> m_column_display_names;
std::array<QPixmap, static_cast<u32>(GameList::EntryType::Count)> m_type_pixmaps;
Expand Down
3 changes: 2 additions & 1 deletion pcsx2-qt/GameList/GameListWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ class GameListSortModel final : public QSortFilterProxyModel
if (!m_filter_name.isEmpty() &&
!QString::fromStdString(entry->path).contains(m_filter_name, Qt::CaseInsensitive) &&
!QString::fromStdString(entry->serial).contains(m_filter_name, Qt::CaseInsensitive) &&
!QString::fromStdString(entry->title).contains(m_filter_name, Qt::CaseInsensitive))
!QString::fromStdString(entry->title).contains(m_filter_name, Qt::CaseInsensitive) &&
!QString::fromStdString(entry->title_en).contains(m_filter_name, Qt::CaseInsensitive))
return false;
}

Expand Down
3 changes: 3 additions & 0 deletions pcsx2-qt/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2175,6 +2175,9 @@ SettingsDialog* MainWindow::getSettingsDialog()
g_main_window->doSettings("Interface");
});
});
connect(m_settings_dialog->getInterfaceSettingsWidget(), &InterfaceSettingsWidget::preferEnglishGameListChanged, this, []{
g_main_window->m_game_list_widget->refreshGridCovers();
});
}

return m_settings_dialog;
Expand Down
1 change: 1 addition & 0 deletions pcsx2-qt/QtHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,7 @@ void Host::SetDefaultUISettings(SettingsInterface& si)
si.SetBoolValue("UI", "RenderToSeparateWindow", false);
si.SetBoolValue("UI", "HideMainWindowWhenRunning", false);
si.SetBoolValue("UI", "DisableWindowResize", false);
si.SetBoolValue("UI", "PreferEnglishGameList", false);
si.SetStringValue("UI", "Theme", QtHost::GetDefaultThemeName());
}

Expand Down
9 changes: 9 additions & 0 deletions pcsx2-qt/Settings/InterfaceSettingsWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsDialog* dialog, QWidget
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableWindowResizing, "UI", "DisableWindowResize", false);
connect(m_ui.renderToSeparateWindow, &QCheckBox::stateChanged, this, &InterfaceSettingsWidget::onRenderToSeparateWindowChanged);

SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.preferEnglishGameList, "UI", "PreferEnglishGameList", false);
connect(m_ui.preferEnglishGameList, &QCheckBox::stateChanged, [this]{ emit preferEnglishGameListChanged(); });

SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.theme, "UI", "Theme", THEME_NAMES, THEME_VALUES,
QtHost::GetDefaultThemeName(), "InterfaceSettingsWidget");
connect(m_ui.theme, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]() { emit themeChanged(); });
Expand Down Expand Up @@ -141,6 +144,10 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsDialog* dialog, QWidget
m_ui.verticalLayout->removeWidget(m_ui.preferencesGroup);
m_ui.preferencesGroup->hide();

// Same with game list settings
m_ui.verticalLayout->removeWidget(m_ui.gameListGroup);
m_ui.gameListGroup->hide();

// start paused doesn't make sense, because settings are applied after ELF load.
m_ui.pauseOnStart->setEnabled(false);
}
Expand Down Expand Up @@ -184,6 +191,8 @@ InterfaceSettingsWidget::InterfaceSettingsWidget(SettingsDialog* dialog, QWidget
dialog->registerWidgetHelp(
m_ui.disableWindowResizing, tr("Disable Window Resizing"), tr("Unchecked"),
tr("Prevents the main window from being resized."));
dialog->registerWidgetHelp(m_ui.preferEnglishGameList, tr("Prefer English Titles"), tr("Unchecked"),
tr("For games with both a title in the game's native language and one in English, prefer the English title."));

onRenderToSeparateWindowChanged();
}
Expand Down
1 change: 1 addition & 0 deletions pcsx2-qt/Settings/InterfaceSettingsWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class InterfaceSettingsWidget : public QWidget
Q_SIGNALS:
void themeChanged();
void languageChanged();
void preferEnglishGameListChanged();

private Q_SLOTS:
void onRenderToSeparateWindowChanged();
Expand Down
16 changes: 16 additions & 0 deletions pcsx2-qt/Settings/InterfaceSettingsWidget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,22 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gameListGroup">
<property name="title">
<string>Game List</string>
</property>
<layout class="QGridLayout" name="gridLayout_gameList">
<item row="0" column="0">
<widget class="QCheckBox" name="preferEnglishGameList">
<property name="text">
<string>Prefer English Titles</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="preferencesGroup">
<property name="title">
Expand Down
13 changes: 11 additions & 2 deletions pcsx2/GameList.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,17 @@ namespace GameList
std::time_t last_played_time = 0;
std::time_t total_played_time = 0;

const std::string& GetTitleEN() const { return title_en.empty() ? title : title_en; }
const std::string& GetTitleSort() const { return title_sort.empty() ? title : title_sort; }
const std::string& GetTitle(bool force_en = false) const
{
return title_en.empty() || !force_en ? title : title_en;
}
const std::string& GetTitleSort(bool force_en = false) const
{
// If there's a separate EN title, then title_sort is in the wrong language and we can't use it
if (force_en && !title_en.empty())
return title_en;
return title_sort.empty() ? title : title_sort;
}

u32 crc = 0;

Expand Down
20 changes: 10 additions & 10 deletions pcsx2/ImGui/FullscreenUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2579,7 +2579,7 @@ void FullscreenUI::DrawSettingsWindow()
if (s_game_settings_entry)
{
NavTitle(SmallString::from_fmt(
"{} ({})", Host::TranslateToCString(TR_CONTEXT, titles[static_cast<u32>(pages[index])]), s_game_settings_entry->GetTitleEN()));
"{} ({})", Host::TranslateToCString(TR_CONTEXT, titles[static_cast<u32>(pages[index])]), s_game_settings_entry->GetTitle(true)));
}
else
{
Expand Down Expand Up @@ -2694,8 +2694,8 @@ void FullscreenUI::DrawSummarySettingsPage()

if (s_game_settings_entry)
{
if (MenuButton(FSUI_ICONSTR(ICON_FA_WINDOW_MAXIMIZE, "Title"), s_game_settings_entry->GetTitleEN().c_str(), true))
CopyTextToClipboard(FSUI_STR("Game title copied to clipboard."), s_game_settings_entry->GetTitleEN());
if (MenuButton(FSUI_ICONSTR(ICON_FA_WINDOW_MAXIMIZE, "Title"), s_game_settings_entry->GetTitle(true).c_str(), true))
CopyTextToClipboard(FSUI_STR("Game title copied to clipboard."), s_game_settings_entry->GetTitle(true));
if (MenuButton(FSUI_ICONSTR(ICON_FA_PAGER, "Serial"), s_game_settings_entry->serial.c_str(), true))
CopyTextToClipboard(FSUI_STR("Game serial copied to clipboard."), s_game_settings_entry->serial);
if (MenuButton(FSUI_ICONSTR(ICON_FA_CODE, "CRC"), fmt::format("{:08X}", s_game_settings_entry->crc).c_str(), true))
Expand Down Expand Up @@ -5579,7 +5579,7 @@ void FullscreenUI::PopulateGameListEntryList()
}

// fallback to title when all else is equal
const int res = StringUtil::Strcasecmp(lhs->GetTitleEN().c_str(), rhs->GetTitleEN().c_str());
const int res = StringUtil::Strcasecmp(lhs->GetTitleSort(true).c_str(), rhs->GetTitleSort(true).c_str());
return reverse ? (res > 0) : (res < 0);
});
}
Expand Down Expand Up @@ -5716,7 +5716,7 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)

ImGui::PushFont(g_large_font);
// TODO: Fix font fallback issues and enable native-language titles
ImGui::RenderTextClipped(title_bb.Min, title_bb.Max, entry->GetTitleEN().c_str(), entry->GetTitleEN().c_str() + entry->GetTitleEN().size(), nullptr,
ImGui::RenderTextClipped(title_bb.Min, title_bb.Max, entry->GetTitle(true).c_str(), entry->GetTitle(true).c_str() + entry->GetTitle(true).size(), nullptr,
ImVec2(0.0f, 0.0f), &title_bb);
ImGui::PopFont();

Expand Down Expand Up @@ -5776,11 +5776,11 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)
{
// title
ImGui::PushFont(g_large_font);
const std::string_view title(std::string_view(selected_entry->GetTitleEN()).substr(0, 37));
const std::string_view title(std::string_view(selected_entry->GetTitle(true)).substr(0, 37));
text_width = ImGui::CalcTextSize(title.data(), title.data() + title.length(), false, work_width).x;
ImGui::SetCursorPosX((work_width - text_width) / 2.0f);
ImGui::TextWrapped(
"%.*s%s", static_cast<int>(title.size()), title.data(), (title.length() == selected_entry->GetTitleEN().length()) ? "" : "...");
"%.*s%s", static_cast<int>(title.size()), title.data(), (title.length() == selected_entry->GetTitle(true).length()) ? "" : "...");
ImGui::PopFont();

ImGui::PushFont(g_medium_font);
Expand Down Expand Up @@ -5926,9 +5926,9 @@ void FullscreenUI::DrawGameGrid(const ImVec2& heading_size)
ImVec2(1.0f, 1.0f), IM_COL32(255, 255, 255, 255));

const ImRect title_bb(ImVec2(bb.Min.x, bb.Min.y + image_height + title_spacing), bb.Max);
const std::string_view title(std::string_view(entry->GetTitleEN()).substr(0, 31));
const std::string_view title(std::string_view(entry->GetTitle(true)).substr(0, 31));
draw_title.clear();
fmt::format_to(std::back_inserter(draw_title), "{}{}", title, (title.length() == entry->GetTitleEN().length()) ? "" : "...");
fmt::format_to(std::back_inserter(draw_title), "{}{}", title, (title.length() == entry->GetTitle(true).length()) ? "" : "...");
ImGui::PushFont(g_medium_font);
ImGui::RenderTextClipped(title_bb.Min, title_bb.Max, draw_title.c_str(), draw_title.c_str() + draw_title.length(), nullptr,
ImVec2(0.5f, 0.0f), &title_bb);
Expand Down Expand Up @@ -5982,7 +5982,7 @@ void FullscreenUI::HandleGameListOptions(const GameList::Entry* entry)
};

const bool has_resume_state = VMManager::HasSaveStateInSlot(entry->serial.c_str(), entry->crc, -1);
OpenChoiceDialog(entry->GetTitleEN().c_str(), false, std::move(options),
OpenChoiceDialog(entry->GetTitle(true).c_str(), false, std::move(options),
[has_resume_state, entry_path = entry->path, entry_serial = entry->serial](s32 index, const std::string& title, bool checked) {
switch (index)
{
Expand Down

0 comments on commit e739535

Please sign in to comment.