From bb8e89f84acf323beb666fe7d024b79ebd72da86 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Thu, 17 May 2018 19:30:13 +0200 Subject: [PATCH] Qt: add game icons to the trophy manager and fix some header behaviour --- rpcs3/rpcs3qt/game_list_frame.cpp | 3 +- rpcs3/rpcs3qt/gui_settings.cpp | 5 + rpcs3/rpcs3qt/gui_settings.h | 3 + rpcs3/rpcs3qt/trophy_manager_dialog.cpp | 130 ++++++++++++++++++++---- rpcs3/rpcs3qt/trophy_manager_dialog.h | 18 +++- 5 files changed, 135 insertions(+), 24 deletions(-) diff --git a/rpcs3/rpcs3qt/game_list_frame.cpp b/rpcs3/rpcs3qt/game_list_frame.cpp index 2a51c1744f..f83d559da0 100644 --- a/rpcs3/rpcs3qt/game_list_frame.cpp +++ b/rpcs3/rpcs3qt/game_list_frame.cpp @@ -21,7 +21,6 @@ #include inline std::string sstr(const QString& _in) { return _in.toStdString(); } -inline QSize sizeFromSlider(const int& pos) { return gui::gl_icon_size_min + (gui::gl_icon_size_max - gui::gl_icon_size_min) * (pos / (float)gui::gl_max_slider_pos); } game_list_frame::game_list_frame(std::shared_ptr guiSettings, std::shared_ptr emuSettings, QWidget *parent) : custom_dock_widget(tr("Game List"), parent), xgui_settings(guiSettings), xemu_settings(emuSettings) @@ -808,7 +807,7 @@ void game_list_frame::ShowCustomConfigIcon(QTableWidgetItem* item, bool enabled) void game_list_frame::ResizeIcons(const int& sliderPos) { m_icon_size_index = sliderPos; - m_Icon_Size = sizeFromSlider(sliderPos); + m_Icon_Size = gui_settings::SizeFromSlider(sliderPos); RepaintIcons(); } diff --git a/rpcs3/rpcs3qt/gui_settings.cpp b/rpcs3/rpcs3qt/gui_settings.cpp index b1fd777041..2c4bac69e2 100644 --- a/rpcs3/rpcs3qt/gui_settings.cpp +++ b/rpcs3/rpcs3qt/gui_settings.cpp @@ -259,3 +259,8 @@ QString gui_settings::GetCurrentStylesheetPath() return m_settingsDir.absoluteFilePath(stylesheet + ".qss"); } + +QSize gui_settings::SizeFromSlider(int pos) +{ + return gui::gl_icon_size_min + (gui::gl_icon_size_max - gui::gl_icon_size_min) * (pos / (float)gui::gl_max_slider_pos); +} diff --git a/rpcs3/rpcs3qt/gui_settings.h b/rpcs3/rpcs3qt/gui_settings.h index 620865f133..94d145f652 100644 --- a/rpcs3/rpcs3qt/gui_settings.h +++ b/rpcs3/rpcs3qt/gui_settings.h @@ -171,6 +171,7 @@ namespace gui const gui_save gs_height = gui_save(gs_frame, "height", 720); const gui_save tr_icon_height = gui_save(trophy, "icon_height", 75); + const gui_save tr_game_iconSize = gui_save(trophy, "game_iconSize", 25); const gui_save tr_show_locked = gui_save(trophy, "show_locked", true); const gui_save tr_show_unlocked = gui_save(trophy, "show_unlocked", true); const gui_save tr_show_hidden = gui_save(trophy, "show_hidden", false); @@ -231,6 +232,8 @@ public Q_SLOTS: void SaveCurrentConfig(const QString& friendlyName); + static QSize SizeFromSlider(int pos); + private: QString ComputeSettingsDir(); void BackupSettingsToTarget(const QString& destination); diff --git a/rpcs3/rpcs3qt/trophy_manager_dialog.cpp b/rpcs3/rpcs3qt/trophy_manager_dialog.cpp index 501ded5cd5..9586f60e6d 100644 --- a/rpcs3/rpcs3qt/trophy_manager_dialog.cpp +++ b/rpcs3/rpcs3qt/trophy_manager_dialog.cpp @@ -43,6 +43,7 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s setWindowTitle(tr("Trophy Manager")); setObjectName("trophy_manager"); + m_game_icon_size_index = m_gui_settings->GetValue(gui::tr_game_iconSize).toInt(); m_icon_height = m_gui_settings->GetValue(gui::tr_icon_height).toInt(); m_show_locked_trophies = m_gui_settings->GetValue(gui::tr_show_locked).toBool(); m_show_unlocked_trophies = m_gui_settings->GetValue(gui::tr_show_unlocked).toBool(); @@ -72,7 +73,7 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s m_game_table->setSelectionBehavior(QAbstractItemView::SelectRows); m_game_table->setEditTriggers(QAbstractItemView::NoEditTriggers); m_game_table->setColumnCount(GameColumns::GameColumnsCount); - m_game_table->setHorizontalHeaderLabels(QStringList{ tr("Game"), tr("Progress") }); + m_game_table->setHorizontalHeaderLabels(QStringList{ tr("Icon"), tr("Game"), tr("Progress") }); m_game_table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); m_game_table->horizontalHeader()->setStretchLastSection(true); m_game_table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); @@ -96,6 +97,7 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s m_trophy_table->verticalHeader()->setVisible(false); m_trophy_table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); m_trophy_table->setContextMenuPolicy(Qt::CustomContextMenu); + m_trophy_table->setAlternatingRowColors(true); m_splitter = new QSplitter(); m_splitter->addWidget(m_game_table); @@ -117,16 +119,31 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s m_game_table->setRowCount(m_trophies_db.size()); + m_game_icon_size = gui_settings::SizeFromSlider(m_game_icon_size_index); + for (int i = 0; i < m_trophies_db.size(); ++i) { const int all_trophies = m_trophies_db[i]->trop_usr->GetTrophiesCount(); const int unlocked_trophies = m_trophies_db[i]->trop_usr->GetUnlockedTrophiesCount(); const int percentage = 100 * unlocked_trophies / all_trophies; + const std::string icon_path = m_trophies_db[i]->path + "/ICON0.PNG"; const QString name = qstr(m_trophies_db[i]->game_name).simplified(); - const QString progress = QString("%1% (%2/%3)").arg(percentage).arg(unlocked_trophies).arg(all_trophies); + const QString progress = QString("%0% (%1/%2)").arg(percentage).arg(unlocked_trophies).arg(all_trophies); m_game_combo->addItem(name, i); + // Load game icon + QPixmap icon; + if (!icon.load(qstr(icon_path))) + { + LOG_WARNING(GENERAL, "Could not load trophy game icon from path %s", icon_path); + } + + custom_table_widget_item* icon_item = new custom_table_widget_item; + icon_item->setData(Qt::UserRole, icon); + icon_item->setData(Qt::DecorationRole, icon.scaled(m_game_icon_size, Qt::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation)); + + m_game_table->setItem(i, GameColumns::GameIcon, icon_item); m_game_table->setItem(i, GameColumns::GameName, new custom_table_widget_item(name)); m_game_table->setItem(i, GameColumns::GameProgress, new custom_table_widget_item(progress, Qt::UserRole, percentage)); } @@ -162,13 +179,20 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s check_platinum_trophy->setCheckable(true); check_platinum_trophy->setChecked(m_show_platinum_trophies); - QLabel* slider_label = new QLabel(); - slider_label->setText(tr("Icon Size: %0").arg(m_icon_height)); + QLabel* trophy_slider_label = new QLabel(); + trophy_slider_label->setText(tr("Trophy Icon Size: %0x%1").arg(m_icon_height).arg(m_icon_height)); + + QLabel* game_slider_label = new QLabel(); + game_slider_label->setText(tr("Game Icon Size: %0x%1").arg(m_game_icon_size.width()).arg(m_game_icon_size.height())); m_icon_slider = new QSlider(Qt::Horizontal); m_icon_slider->setRange(25, 225); m_icon_slider->setValue(m_icon_height); + m_game_icon_slider = new QSlider(Qt::Horizontal); + m_game_icon_slider->setRange(0, gui::gl_max_slider_pos); + m_game_icon_slider->setValue(m_game_icon_size_index); + // LAYOUTS QGroupBox* choose_game = new QGroupBox(tr("Choose Game")); QVBoxLayout* choose_layout = new QVBoxLayout(); @@ -191,10 +215,12 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s settings_layout->addWidget(check_platinum_trophy); show_settings->setLayout(settings_layout); - QGroupBox* icon_settings = new QGroupBox(tr("Trophy Icon Options")); + QGroupBox* icon_settings = new QGroupBox(tr("Icon Options")); QVBoxLayout* slider_layout = new QVBoxLayout(); - slider_layout->addWidget(slider_label); + slider_layout->addWidget(trophy_slider_label); slider_layout->addWidget(m_icon_slider); + slider_layout->addWidget(game_slider_label); + slider_layout->addWidget(m_game_icon_slider); icon_settings->setLayout(slider_layout); QVBoxLayout* options_layout = new QVBoxLayout(); @@ -210,16 +236,13 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s all_layout->setStretch(1, 1); setLayout(all_layout); - PopulateUI(); - ApplyFilter(); - if (!restoreGeometry(m_gui_settings->GetValue(gui::tr_geometry).toByteArray())) resize(QDesktopWidget().availableGeometry().size() * 0.7); QByteArray splitterstate = m_gui_settings->GetValue(gui::tr_splitterState).toByteArray(); - if (splitterstate.isEmpty()) // resize 1:2 + if (splitterstate.isEmpty()) { - const int width_left = m_splitter->width() / 3; + const int width_left = m_splitter->width() * 0.4; const int width_right = m_splitter->width() - width_left; m_splitter->setSizes({ width_left, width_right }); } @@ -236,6 +259,7 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s else if (m_game_table->rowCount() > 0) { // If no settings exist, go to default. + m_game_table->verticalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents); m_game_table->horizontalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents); } @@ -249,14 +273,16 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s // If no settings exist, go to default. m_trophy_table->verticalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents); m_trophy_table->horizontalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents); - m_trophy_table->horizontalHeader()->setSectionResizeMode(TrophyColumns::Icon, QHeaderView::Fixed); } + PopulateUI(); + ApplyFilter(); + // Make connects connect(m_icon_slider, &QSlider::valueChanged, this, [=](int val) { m_icon_height = val; - slider_label->setText(tr("Icon Size: %0").arg(val)); + trophy_slider_label->setText(tr("Trophy Icon Size: %0x%1").arg(val).arg(val)); ResizeTrophyIcons(val); if (m_save_icon_height) { @@ -278,6 +304,32 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s } }); + connect(m_game_icon_slider, &QSlider::valueChanged, this, [=](int val) + { + m_game_icon_size_index = val; + m_game_icon_size = gui_settings::SizeFromSlider(val);; + game_slider_label->setText(tr("Game Icon Size: %0x%1").arg(m_game_icon_size.width()).arg(m_game_icon_size.height())); + ResizeGameIcons(val); + if (m_save_game_icon_size) + { + m_save_game_icon_size = false; + m_gui_settings->SetValue(gui::tr_game_iconSize, val); + } + }); + + connect(m_game_icon_slider, &QSlider::sliderReleased, this, [&]() + { + m_gui_settings->SetValue(gui::tr_game_iconSize, m_game_icon_slider->value()); + }); + + connect(m_game_icon_slider, &QSlider::actionTriggered, [&](int action) + { + if (action != QAbstractSlider::SliderNoAction && action != QAbstractSlider::SliderMove) + { // we only want to save on mouseclicks or slider release (the other connect handles this) + m_save_game_icon_size = true; // actionTriggered happens before the value was changed + } + }); + connect(check_lock_trophy, &QCheckBox::clicked, [this](bool checked) { m_show_locked_trophies = checked; @@ -339,6 +391,11 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s { m_game_combo->setCurrentText(m_game_table->item(m_game_table->currentRow(), GameColumns::GameName)->text()); }); + + // Show dialog and then paint gui in order to adjust headers correctly + show(); + ReadjustGameTable(); + ReadjustTrophyTable(); } bool trophy_manager_dialog::LoadTrophyFolderToDB(const std::string& trop_name) @@ -412,6 +469,22 @@ bool trophy_manager_dialog::LoadTrophyFolderToDB(const std::string& trop_name) return true; } +void trophy_manager_dialog::ResizeGameIcons(int val) +{ + if (m_game_combo->count() <= 0) + return; + + for (int i = 0; i < m_game_table->rowCount(); ++i) + { + QTableWidgetItem* item = m_game_table->item(i, GameColumns::GameIcon); + QPixmap pixmap = item->data(Qt::UserRole).value(); + QPixmap scaled = pixmap.scaled(m_game_icon_size, Qt::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation); + item->setData(Qt::DecorationRole, scaled); + } + + ReadjustGameTable(); +} + void trophy_manager_dialog::ResizeTrophyIcons(int size) { if (m_game_combo->count() <= 0) @@ -422,10 +495,11 @@ void trophy_manager_dialog::ResizeTrophyIcons(int size) for (int i = 0; i < m_trophy_table->rowCount(); ++i) { int trophy_id = m_trophy_table->item(i, TrophyColumns::Id)->text().toInt(); - m_trophy_table->item(i, TrophyColumns::Icon)->setData(Qt::DecorationRole, m_trophies_db[db_pos]->trophy_images[trophy_id].scaledToHeight(size, Qt::SmoothTransformation)); + QPixmap scaled = m_trophies_db[db_pos]->trophy_images[trophy_id].scaledToHeight(size, Qt::SmoothTransformation); + m_trophy_table->item(i, TrophyColumns::Icon)->setData(Qt::DecorationRole, scaled); } - ReadjustTable(); + ReadjustTrophyTable(); } void trophy_manager_dialog::ApplyFilter() @@ -596,15 +670,37 @@ void trophy_manager_dialog::PopulateUI() m_trophy_table->setSortingEnabled(true); // Re-enable sorting after using setItem calls - ReadjustTable(); + ReadjustTrophyTable(); } -void trophy_manager_dialog::ReadjustTable() +void trophy_manager_dialog::ReadjustGameTable() { + // Fixate vertical header and row height + m_game_table->verticalHeader()->setMinimumSectionSize(m_game_icon_size.height()); + m_game_table->verticalHeader()->setMaximumSectionSize(m_game_icon_size.height()); + m_game_table->resizeRowsToContents(); + + // Resize and fixate icon column + m_game_table->resizeColumnToContents(GameColumns::GameIcon); + m_game_table->horizontalHeader()->setSectionResizeMode(GameColumns::GameIcon, QHeaderView::Fixed); + + // Shorten the last section to remove horizontal scrollbar if possible + m_game_table->resizeColumnToContents(GameColumns::GameColumnsCount - 1); +} + +void trophy_manager_dialog::ReadjustTrophyTable() +{ + // Fixate vertical header and row height m_trophy_table->verticalHeader()->setMinimumSectionSize(m_icon_height); m_trophy_table->verticalHeader()->setMaximumSectionSize(m_icon_height); m_trophy_table->resizeRowsToContents(); + + // Resize and fixate icon column m_trophy_table->resizeColumnToContents(TrophyColumns::Icon); + m_trophy_table->horizontalHeader()->setSectionResizeMode(TrophyColumns::Icon, QHeaderView::Fixed); + + // Shorten the last section to remove horizontal scrollbar if possible + m_trophy_table->resizeColumnToContents(TrophyColumns::Count - 1); } void trophy_manager_dialog::closeEvent(QCloseEvent * event) diff --git a/rpcs3/rpcs3qt/trophy_manager_dialog.h b/rpcs3/rpcs3qt/trophy_manager_dialog.h index 3cef6b52a5..f134d17812 100644 --- a/rpcs3/rpcs3qt/trophy_manager_dialog.h +++ b/rpcs3/rpcs3qt/trophy_manager_dialog.h @@ -33,15 +33,16 @@ enum TrophyColumns IsUnlocked = 4, Id = 5, - Count = 6, + Count }; enum GameColumns { - GameName = 0, - GameProgress = 1, + GameIcon = 0, + GameName = 1, + GameProgress = 2, - GameColumnsCount = 2, + GameColumnsCount }; class trophy_manager_dialog : public QWidget @@ -54,6 +55,7 @@ class trophy_manager_dialog : public QWidget public: explicit trophy_manager_dialog(std::shared_ptr gui_settings); private Q_SLOTS: + void ResizeGameIcons(int val); void ResizeTrophyIcons(int val); void ApplyFilter(); void ShowContextMenu(const QPoint& pos); @@ -68,7 +70,8 @@ private: */ void PopulateUI(); - void ReadjustTable(); + void ReadjustGameTable(); + void ReadjustTrophyTable(); void closeEvent(QCloseEvent* event) override; @@ -92,6 +95,11 @@ private: int m_icon_height = 75; bool m_save_icon_height = false; QSlider* m_icon_slider = nullptr; + + int m_game_icon_size_index = 25; + QSize m_game_icon_size = QSize(m_game_icon_size_index, m_game_icon_size_index); + bool m_save_game_icon_size = false; + QSlider* m_game_icon_slider = nullptr; }; #endif