mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-07-11 01:34:17 +02:00
Qt: show full game titles in grid mode.
Added UI element with new icon to toggle showing full game titles by wrapping around to the next line.
This commit is contained in:
@@ -73,9 +73,10 @@ const char* GameListModel::getColumnName(const Column col)
|
||||
return s_column_names[static_cast<int>(col)];
|
||||
}
|
||||
|
||||
GameListModel::GameListModel(const float cover_scale, const bool show_cover_titles, const qreal dpr, QObject* parent /* = nullptr */)
|
||||
GameListModel::GameListModel(const float cover_scale, const bool show_cover_titles, bool show_full_cover_titles, const qreal dpr, QObject* parent /* = nullptr */)
|
||||
: QAbstractTableModel(parent)
|
||||
, m_show_titles_for_covers(show_cover_titles)
|
||||
, m_show_full_titles_for_covers(show_full_cover_titles)
|
||||
, m_dpr{dpr}
|
||||
{
|
||||
loadSettings();
|
||||
@@ -315,9 +316,33 @@ QVariant GameListModel::data(const QModelIndex& index, const int role) const
|
||||
switch (index.column())
|
||||
{
|
||||
case Column_Cover:
|
||||
return QSize(static_cast<int>(static_cast<float>(SIZE_HINT_WIDTH) * m_cover_scale),
|
||||
static_cast<int>(static_cast<float>(m_show_titles_for_covers ? SIZE_HINT_HEIGHT_TITLES : SIZE_HINT_HEIGHT) * m_cover_scale));
|
||||
{
|
||||
const int cover_width = static_cast<int>(static_cast<float>(SIZE_HINT_WIDTH) * m_cover_scale);
|
||||
const int cover_height = static_cast<int>(static_cast<float>(SIZE_HINT_HEIGHT) * m_cover_scale);
|
||||
|
||||
if (m_show_full_titles_for_covers && m_show_titles_for_covers)
|
||||
{
|
||||
// Find height needed for the longest title at the current font/width
|
||||
const int text_width = static_cast<int>(static_cast<float>(COVER_ART_WIDTH) * m_cover_scale);
|
||||
QFont font;
|
||||
font.setPointSizeF(20.0f * m_cover_scale);
|
||||
const QFontMetrics fm(font);
|
||||
int max_text_height = fm.height();
|
||||
const auto lock = GameList::GetLock();
|
||||
const u32 count = GameList::GetEntryCount();
|
||||
for (u32 i = 0; i < count; i++)
|
||||
{
|
||||
const GameList::Entry* entry = GameList::GetEntryByIndex(i);
|
||||
if (!entry) continue;
|
||||
const QString title = QString::fromStdString(entry->GetTitle(m_prefer_english_titles));
|
||||
const QRect bound = fm.boundingRect(QRect(0, 0, text_width, 0),
|
||||
Qt::TextWordWrap | Qt::AlignHCenter, title);
|
||||
max_text_height = std::max(max_text_height, bound.height());
|
||||
}
|
||||
return QSize(cover_width, cover_height + max_text_height);
|
||||
}
|
||||
return QSize(cover_width, static_cast<int>(static_cast<float>(m_show_titles_for_covers ? SIZE_HINT_HEIGHT_TITLES : SIZE_HINT_HEIGHT) * m_cover_scale));
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
@@ -354,7 +379,7 @@ bool GameListModel::titlesLessThan(const int left_row, const int right_row) cons
|
||||
const GameList::Entry* left = GameList::GetEntryByIndex(left_row);
|
||||
const GameList::Entry* right = GameList::GetEntryByIndex(right_row);
|
||||
return QtHost::LocaleSensitiveCompare(QString::fromStdString(left->GetTitleSort(m_prefer_english_titles)),
|
||||
QString::fromStdString(right->GetTitleSort(m_prefer_english_titles))) < 0;
|
||||
QString::fromStdString(right->GetTitleSort(m_prefer_english_titles))) < 0;
|
||||
}
|
||||
|
||||
bool GameListModel::lessThan(const QModelIndex& left_index, const QModelIndex& right_index, const int column) const
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
static QIcon getIconForType(GameList::EntryType type);
|
||||
static QIcon getIconForRegion(GameList::Region region);
|
||||
|
||||
GameListModel(float cover_scale, bool show_cover_titles, qreal dpr, QObject* parent = nullptr);
|
||||
GameListModel(float cover_scale, bool show_cover_titles, bool show_full_cover_titles, qreal dpr, QObject* parent = nullptr);
|
||||
~GameListModel();
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
@@ -63,6 +63,9 @@ public:
|
||||
bool getShowCoverTitles() const { return m_show_titles_for_covers; }
|
||||
void setShowCoverTitles(bool enabled) { m_show_titles_for_covers = enabled; }
|
||||
|
||||
bool getShowFullCoverTitles() const { return m_show_full_titles_for_covers; }
|
||||
void setShowFullCoverTitles(bool enabled) { m_show_full_titles_for_covers = enabled; }
|
||||
|
||||
float getCoverScale() const { return m_cover_scale; }
|
||||
void setCoverScale(float scale);
|
||||
int getCoverArtWidth() const;
|
||||
@@ -89,6 +92,7 @@ private:
|
||||
float m_cover_scale = 0.0f;
|
||||
std::atomic<u32> m_cover_scale_counter{0};
|
||||
bool m_show_titles_for_covers = false;
|
||||
bool m_show_full_titles_for_covers = false;
|
||||
bool m_prefer_english_titles = false;
|
||||
|
||||
std::array<QString, Column_Count> m_column_display_names;
|
||||
|
||||
@@ -239,7 +239,8 @@ void GameListWidget::initialize()
|
||||
{
|
||||
const float cover_scale = Host::GetBaseFloatSettingValue("UI", "GameListCoverArtScale", 0.45f);
|
||||
const bool show_cover_titles = Host::GetBaseBoolSettingValue("UI", "GameListShowCoverTitles", true);
|
||||
m_model = new GameListModel(cover_scale, show_cover_titles, devicePixelRatioF(), this);
|
||||
const bool show_full_cover_titles = Host::GetBaseBoolSettingValue("UI", "GameListShowFullCoverTitles", true);
|
||||
m_model = new GameListModel(cover_scale, show_cover_titles, show_full_cover_titles, devicePixelRatioF(), this);
|
||||
m_model->updateCacheSize(width(), height());
|
||||
|
||||
m_sort_model = new GameListSortModel(m_model);
|
||||
@@ -268,6 +269,7 @@ void GameListWidget::initialize()
|
||||
connect(m_ui.viewGameGrid, &QPushButton::clicked, this, &GameListWidget::showGameGrid);
|
||||
connect(m_ui.gridScale, &QSlider::valueChanged, this, &GameListWidget::gridIntScale);
|
||||
connect(m_ui.viewGridTitles, &QPushButton::toggled, this, &GameListWidget::setShowCoverTitles);
|
||||
connect(m_ui.viewFullGridTitles, &QPushButton::toggled, this, &GameListWidget::setShowFullCoverTitles);
|
||||
connect(m_ui.filterType, &QComboBox::currentIndexChanged, this, [this](int index) {
|
||||
m_sort_model->setFilterType((index == 0) ? GameList::EntryType::Count : static_cast<GameList::EntryType>(index - 1));
|
||||
});
|
||||
@@ -348,6 +350,7 @@ void GameListWidget::initialize()
|
||||
m_list_view->setFrameStyle(QFrame::NoFrame);
|
||||
m_list_view->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
|
||||
m_list_view->verticalScrollBar()->setSingleStep(15);
|
||||
m_list_view->setWordWrap(show_full_cover_titles);
|
||||
onCoverScaleChanged();
|
||||
|
||||
connect(m_list_view->selectionModel(), &QItemSelectionModel::currentChanged, this,
|
||||
@@ -542,6 +545,11 @@ bool GameListWidget::getShowGridCoverTitles() const
|
||||
return m_model->getShowCoverTitles();
|
||||
}
|
||||
|
||||
bool GameListWidget::getShowGridFullCoverTitles() const
|
||||
{
|
||||
return m_model->getShowFullCoverTitles();
|
||||
}
|
||||
|
||||
void GameListWidget::refresh(bool invalidate_cache, bool popup_on_error)
|
||||
{
|
||||
cancelRefresh();
|
||||
@@ -776,6 +784,21 @@ void GameListWidget::setShowCoverTitles(bool enabled)
|
||||
emit layoutChange();
|
||||
}
|
||||
|
||||
void GameListWidget::setShowFullCoverTitles(bool enabled)
|
||||
{
|
||||
if (m_model->getShowFullCoverTitles() == enabled)
|
||||
return;
|
||||
|
||||
Host::SetBaseBoolSettingValue("UI", "GameListShowFullCoverTitles", enabled);
|
||||
Host::CommitBaseSettingChanges();
|
||||
m_model->setShowFullCoverTitles(enabled);
|
||||
m_list_view->setWordWrap(enabled);
|
||||
if (isShowingGameGrid())
|
||||
m_model->refresh();
|
||||
updateToolbar();
|
||||
emit layoutChange();
|
||||
}
|
||||
|
||||
void GameListWidget::updateToolbar()
|
||||
{
|
||||
const bool grid_view = Host::GetBaseBoolSettingValue("UI", "GameListGridView", false);
|
||||
@@ -791,12 +814,17 @@ void GameListWidget::updateToolbar()
|
||||
QSignalBlocker sb(m_ui.viewGridTitles);
|
||||
m_ui.viewGridTitles->setChecked(m_model->getShowCoverTitles());
|
||||
}
|
||||
{
|
||||
QSignalBlocker sb(m_ui.viewFullGridTitles);
|
||||
m_ui.viewFullGridTitles->setChecked(m_model->getShowFullCoverTitles());
|
||||
}
|
||||
{
|
||||
QSignalBlocker sb(m_ui.gridScale);
|
||||
m_ui.gridScale->setValue(static_cast<int>(m_model->getCoverScale() * 100.0f));
|
||||
}
|
||||
|
||||
m_ui.viewGridTitles->setEnabled(grid_view);
|
||||
m_ui.viewFullGridTitles->setEnabled(grid_view && m_model->getShowCoverTitles());
|
||||
m_ui.gridScale->setEnabled(grid_view);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
bool isShowingGameList() const;
|
||||
bool isShowingGameGrid() const;
|
||||
bool getShowGridCoverTitles() const;
|
||||
bool getShowGridFullCoverTitles() const;
|
||||
|
||||
std::optional<GameList::Entry> getSelectedEntry() const;
|
||||
|
||||
@@ -95,6 +96,7 @@ public Q_SLOTS:
|
||||
void showGameList();
|
||||
void showGameGrid();
|
||||
void setShowCoverTitles(bool enabled);
|
||||
void setShowFullCoverTitles(bool enabled);
|
||||
void gridZoomIn();
|
||||
void gridZoomOut();
|
||||
void gridIntScale(int int_scale);
|
||||
|
||||
@@ -120,6 +120,31 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="viewFullGridTitles">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Show Full Titles</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show Full Titles</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="price-tag-2-line"/>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="gridScale">
|
||||
<property name="minimumSize">
|
||||
@@ -218,6 +243,7 @@
|
||||
<tabstop>viewGameList</tabstop>
|
||||
<tabstop>viewGameGrid</tabstop>
|
||||
<tabstop>viewGridTitles</tabstop>
|
||||
<tabstop>viewFullGridTitles</tabstop>
|
||||
<tabstop>gridScale</tabstop>
|
||||
<tabstop>filterType</tabstop>
|
||||
<tabstop>filterRegion</tabstop>
|
||||
|
||||
@@ -221,11 +221,13 @@ void MainWindow::setupAdditionalUi()
|
||||
}
|
||||
|
||||
const bool show_game_grid = Host::GetBaseBoolSettingValue("UI", "GameListGridView", false);
|
||||
updateGameGridActions(show_game_grid);
|
||||
const bool show_grid_cover_titles = Host::GetBaseBoolSettingValue("UI", "ShowGridCoverTitles", false);
|
||||
updateGameGridActions(show_game_grid, show_grid_cover_titles);
|
||||
|
||||
m_game_list_widget = new GameListWidget(getContentParent());
|
||||
m_game_list_widget->initialize();
|
||||
m_ui.actionGridViewShowTitles->setChecked(m_game_list_widget->getShowGridCoverTitles());
|
||||
m_ui.actionGridViewShowFullTitles->setChecked(m_game_list_widget->getShowGridFullCoverTitles());
|
||||
m_ui.mainContainer->addWidget(m_game_list_widget);
|
||||
|
||||
updateEmulationActions(false, false, false);
|
||||
@@ -543,6 +545,7 @@ void MainWindow::connectSignals()
|
||||
connect(m_ui.actionOpenDataDirectory, &QAction::triggered, this, &MainWindow::onToolsOpenDataDirectoryTriggered);
|
||||
connect(m_ui.actionCoverDownloader, &QAction::triggered, this, &MainWindow::onToolsCoverDownloaderTriggered);
|
||||
connect(m_ui.actionGridViewShowTitles, &QAction::triggered, m_game_list_widget, &GameListWidget::setShowCoverTitles);
|
||||
connect(m_ui.actionGridViewShowFullTitles, &QAction::triggered, m_game_list_widget, &GameListWidget::setShowFullCoverTitles);
|
||||
connect(m_ui.actionGridViewZoomIn, &QAction::triggered, m_game_list_widget, [this]() {
|
||||
if (isShowingGameList())
|
||||
m_game_list_widget->gridZoomIn();
|
||||
@@ -554,8 +557,10 @@ void MainWindow::connectSignals()
|
||||
connect(m_ui.actionGridViewRefreshCovers, &QAction::triggered, m_game_list_widget, &GameListWidget::refreshGridCovers);
|
||||
connect(m_game_list_widget, &GameListWidget::layoutChange, this, [this]() {
|
||||
QSignalBlocker sb(m_ui.actionGridViewShowTitles);
|
||||
QSignalBlocker sb2(m_ui.actionGridViewShowFullTitles);
|
||||
m_ui.actionGridViewShowTitles->setChecked(m_game_list_widget->getShowGridCoverTitles());
|
||||
updateGameGridActions(m_game_list_widget->isShowingGameGrid());
|
||||
m_ui.actionGridViewShowFullTitles->setChecked(m_game_list_widget->getShowGridFullCoverTitles());
|
||||
updateGameGridActions(m_game_list_widget->isShowingGameGrid(), m_game_list_widget->getShowGridCoverTitles());
|
||||
});
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionViewStatusBarVerbose, "UI", "VerboseStatusBar", false);
|
||||
@@ -3667,9 +3672,10 @@ void MainWindow::updateGameDependentActions()
|
||||
m_ui.actionReloadPatches->setEnabled(s_vm_valid);
|
||||
}
|
||||
|
||||
void MainWindow::updateGameGridActions(const bool show_game_grid)
|
||||
void MainWindow::updateGameGridActions(const bool show_game_grid, const bool show_grid_cover_titles)
|
||||
{
|
||||
m_ui.actionGridViewShowTitles->setEnabled(show_game_grid);
|
||||
m_ui.actionGridViewShowFullTitles->setEnabled(show_game_grid && show_grid_cover_titles);
|
||||
m_ui.actionGridViewZoomIn->setEnabled(show_game_grid);
|
||||
m_ui.actionGridViewZoomOut->setEnabled(show_game_grid);
|
||||
m_ui.actionGridViewRefreshCovers->setEnabled(show_game_grid);
|
||||
|
||||
@@ -257,7 +257,7 @@ private:
|
||||
void updateEmulationActions(bool starting, bool running, bool stopping);
|
||||
void updateDisplayRelatedActions(bool has_surface, bool render_to_main, bool fullscreen);
|
||||
void updateGameDependentActions();
|
||||
void updateGameGridActions(const bool show_game_grid);
|
||||
void updateGameGridActions(const bool show_game_grid, const bool show_grid_cover_titles);
|
||||
void updateStatusBarWidgetVisibility();
|
||||
void updateAdvancedSettingsVisibility();
|
||||
void updateWindowTitle();
|
||||
|
||||
@@ -175,6 +175,7 @@
|
||||
<addaction name="menuWindowSize"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionGridViewShowTitles"/>
|
||||
<addaction name="actionGridViewShowFullTitles"/>
|
||||
<addaction name="actionGridViewZoomIn"/>
|
||||
<addaction name="actionGridViewZoomOut"/>
|
||||
<addaction name="actionGridViewRefreshCovers"/>
|
||||
@@ -808,6 +809,20 @@
|
||||
<string>Show Titl&es (Grid View)</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGridViewShowFullTitles">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="price-tag-2-line"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show F&ull Titles (Grid View)</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGridViewZoomIn">
|
||||
<property name="icon">
|
||||
<iconset theme="zoom-in-line"/>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="rgba(0,0,0,1)"><path d="M3.00488 6.99972L11.4502 1.36952C11.7861 1.14559 12.2237 1.14559 12.5596 1.36952L21.0049 6.99972V20.9997C21.0049 21.552 20.5572 21.9997 20.0049 21.9997H4.00488C3.4526 21.9997 3.00488 21.552 3.00488 20.9997V6.99972ZM5.00488 8.07009V19.9997H19.0049V8.07009L12.0049 3.40342L5.00488 8.07009ZM8.00488 15.9997H16.0049V17.9997H8.00488V15.9997ZM8.00488 12.9997H16.0049V14.9997H8.00488V12.9997ZM12.0049 10.9997C10.9003 10.9997 10.0049 10.1043 10.0049 8.99972C10.0049 7.89515 10.9003 6.99972 12.0049 6.99972C13.1095 6.99972 14.0049 7.89515 14.0049 8.99972C14.0049 10.1043 13.1095 10.9997 12.0049 10.9997Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 699 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#fff"><path d="M3.00488 6.99972L11.4502 1.36952C11.7861 1.14559 12.2237 1.14559 12.5596 1.36952L21.0049 6.99972V20.9997C21.0049 21.552 20.5572 21.9997 20.0049 21.9997H4.00488C3.4526 21.9997 3.00488 21.552 3.00488 20.9997V6.99972ZM5.00488 8.07009V19.9997H19.0049V8.07009L12.0049 3.40342L5.00488 8.07009ZM8.00488 15.9997H16.0049V17.9997H8.00488V15.9997ZM8.00488 12.9997H16.0049V14.9997H8.00488V12.9997ZM12.0049 10.9997C10.9003 10.9997 10.0049 10.1043 10.0049 8.99972C10.0049 7.89515 10.9003 6.99972 12.0049 6.99972C13.1095 6.99972 14.0049 7.89515 14.0049 8.99972C14.0049 10.1043 13.1095 10.9997 12.0049 10.9997Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 691 B |
@@ -80,6 +80,7 @@
|
||||
<file>icons/black/svg/play-line.svg</file>
|
||||
<file>icons/black/svg/plus-line.svg</file>
|
||||
<file>icons/black/svg/Popn-line.svg</file>
|
||||
<file>icons/black/svg/price-tag-2-line.svg</file>
|
||||
<file>icons/black/svg/price-tag-3-line.svg</file>
|
||||
<file>icons/black/svg/printer-line.svg</file>
|
||||
<file>icons/black/svg/realplay-sphere-line.svg</file>
|
||||
@@ -193,6 +194,7 @@
|
||||
<file>icons/white/svg/play-line.svg</file>
|
||||
<file>icons/white/svg/plus-line.svg</file>
|
||||
<file>icons/white/svg/Popn-line.svg</file>
|
||||
<file>icons/white/svg/price-tag-2-line.svg</file>
|
||||
<file>icons/white/svg/price-tag-3-line.svg</file>
|
||||
<file>icons/white/svg/printer-line.svg</file>
|
||||
<file>icons/white/svg/realplay-sphere-line.svg</file>
|
||||
|
||||
Reference in New Issue
Block a user