From d275c36e0aab920322b4e5ca36604d44e8d54290 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Thu, 17 May 2018 22:36:31 +0200 Subject: [PATCH] Qt: trophy manager overhaul --- rpcs3/rpcs3qt/custom_table_widget_item.h | 14 +- rpcs3/rpcs3qt/gui_settings.h | 3 + rpcs3/rpcs3qt/trophy_manager_dialog.cpp | 461 ++++++++++++++--------- rpcs3/rpcs3qt/trophy_manager_dialog.h | 28 +- 4 files changed, 312 insertions(+), 194 deletions(-) diff --git a/rpcs3/rpcs3qt/custom_table_widget_item.h b/rpcs3/rpcs3qt/custom_table_widget_item.h index 2b5ba64b43..db75c0e029 100644 --- a/rpcs3/rpcs3qt/custom_table_widget_item.h +++ b/rpcs3/rpcs3qt/custom_table_widget_item.h @@ -9,12 +9,20 @@ private: public: custom_table_widget_item(){} - custom_table_widget_item(const std::string& text, int sort_role = Qt::DisplayRole, int sort_index = 0) - : QTableWidgetItem(qstr(text).simplified()) // simplified() forces single line text + custom_table_widget_item(const std::string& text, int sort_role = Qt::DisplayRole, const QVariant& sort_value = 0) + : QTableWidgetItem(QString::fromStdString(text).simplified()) // simplified() forces single line text { if (sort_role != Qt::DisplayRole) { - setData(sort_role, sort_index, true); + setData(sort_role, sort_value, true); + } + } + custom_table_widget_item(const QString& text, int sort_role = Qt::DisplayRole, const QVariant& sort_value = 0) + : QTableWidgetItem(text.simplified()) // simplified() forces single line text + { + if (sort_role != Qt::DisplayRole) + { + setData(sort_role, sort_value, true); } } diff --git a/rpcs3/rpcs3qt/gui_settings.h b/rpcs3/rpcs3qt/gui_settings.h index aa30a45309..620865f133 100644 --- a/rpcs3/rpcs3qt/gui_settings.h +++ b/rpcs3/rpcs3qt/gui_settings.h @@ -179,6 +179,9 @@ namespace gui const gui_save tr_show_gold = gui_save(trophy, "show_gold", true); const gui_save tr_show_platinum = gui_save(trophy, "show_platinum", true); const gui_save tr_geometry = gui_save(trophy, "geometry", QByteArray()); + const gui_save tr_splitterState = gui_save(trophy, "splitterState", QByteArray()); + const gui_save tr_games_state = gui_save(trophy, "games_state", QByteArray()); + const gui_save tr_trophy_state = gui_save(trophy, "trophy_state", QByteArray()); const gui_save sd_geometry = gui_save(savedata, "geometry", QByteArray()); } diff --git a/rpcs3/rpcs3qt/trophy_manager_dialog.cpp b/rpcs3/rpcs3qt/trophy_manager_dialog.cpp index e222b317cf..501ded5cd5 100644 --- a/rpcs3/rpcs3qt/trophy_manager_dialog.cpp +++ b/rpcs3/rpcs3qt/trophy_manager_dialog.cpp @@ -1,5 +1,7 @@ #include "trophy_manager_dialog.h" -#include "trophy_tree_widget_item.h" +#include "custom_table_widget_item.h" +#include "table_item_delegate.h" +#include "qt_utils.h" #include "stdafx.h" @@ -16,17 +18,15 @@ #include #include #include -#include #include #include -#include #include -#include #include #include #include #include #include +#include static const char* m_TROPHY_DIR = "/dev_hdd0/home/00000001/trophy/"; @@ -37,7 +37,7 @@ namespace } trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_settings) - : QWidget(), m_sort_column(0), m_col_sort_order(Qt::AscendingOrder), m_gui_settings(gui_settings) + : QWidget(), m_gui_settings(gui_settings) { // Nonspecific widget settings setWindowTitle(tr("Trophy Manager")); @@ -55,17 +55,51 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s // HACK: dev_hdd0 must be mounted for vfs to work for loading trophies. vfs::mount("dev_hdd0", Emu.GetHddDir()); - // Trophy Tree - m_trophy_tree = new QTreeWidget(); - m_trophy_tree->setColumnCount(6); + // Game chooser combo box + m_game_combo = new QComboBox(); - QStringList column_names; - column_names << tr("Icon") << tr("Name") << tr("Description") << tr("Type") << tr("Status") << tr("ID"); - m_trophy_tree->setHeaderLabels(column_names); - m_trophy_tree->header()->setSectionResizeMode(QHeaderView::ResizeToContents); - m_trophy_tree->header()->setStretchLastSection(false); - m_trophy_tree->setSortingEnabled(true); - m_trophy_tree->setContextMenuPolicy(Qt::CustomContextMenu); + // Game progression label + m_game_progress = new QLabel(tr("Progress: %1% (%2/%3)").arg(0).arg(0).arg(0)); + + // Games Table + m_game_table = new QTableWidget(); + m_game_table->setShowGrid(false); + m_game_table->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + m_game_table->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); + m_game_table->verticalScrollBar()->setSingleStep(20); + m_game_table->horizontalScrollBar()->setSingleStep(20); + m_game_table->setItemDelegate(new table_item_delegate(this)); + 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->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); + m_game_table->horizontalHeader()->setStretchLastSection(true); + m_game_table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); + m_game_table->verticalHeader()->setVisible(false); + m_game_table->setAlternatingRowColors(true); + + // Trophy Table + m_trophy_table = new QTableWidget(); + m_trophy_table->setShowGrid(false); + m_trophy_table->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + m_trophy_table->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); + m_trophy_table->verticalScrollBar()->setSingleStep(20); + m_trophy_table->horizontalScrollBar()->setSingleStep(20); + m_trophy_table->setItemDelegate(new table_item_delegate(this)); + m_trophy_table->setSelectionBehavior(QAbstractItemView::SelectRows); + m_trophy_table->setEditTriggers(QAbstractItemView::NoEditTriggers); + m_trophy_table->setColumnCount(TrophyColumns::Count); + m_trophy_table->setHorizontalHeaderLabels(QStringList{ tr("Icon"), tr("Name"), tr("Description"), tr("Type"), tr("Status"), tr("ID") }); + m_trophy_table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); + m_trophy_table->horizontalHeader()->setStretchLastSection(true); + m_trophy_table->verticalHeader()->setVisible(false); + m_trophy_table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); + m_trophy_table->setContextMenuPolicy(Qt::CustomContextMenu); + + m_splitter = new QSplitter(); + m_splitter->addWidget(m_game_table); + m_splitter->addWidget(m_trophy_table); // Populate the trophy database QDirIterator dir_iter(qstr(vfs::get(m_TROPHY_DIR))); @@ -81,8 +115,23 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s LoadTrophyFolderToDB(dirName); } - PopulateUI(); - ApplyFilter(); + m_game_table->setRowCount(m_trophies_db.size()); + + 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 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); + + m_game_combo->addItem(name, i); + + 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)); + } + + m_game_table->setSortingEnabled(true); // Enable sorting only after using setItem calls // Checkboxes to control dialog QCheckBox* check_lock_trophy = new QCheckBox(tr("Show Locked Trophies")); @@ -121,8 +170,17 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s m_icon_slider->setValue(m_icon_height); // LAYOUTS + QGroupBox* choose_game = new QGroupBox(tr("Choose Game")); + QVBoxLayout* choose_layout = new QVBoxLayout(); + choose_layout->addWidget(m_game_combo); + choose_game->setLayout(choose_layout); + + QGroupBox* trophy_info = new QGroupBox(tr("Trophy Info")); + QVBoxLayout* info_layout = new QVBoxLayout(); + info_layout->addWidget(m_game_progress); + trophy_info->setLayout(info_layout); + QGroupBox* show_settings = new QGroupBox(tr("Trophy View Options")); - show_settings->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); QVBoxLayout* settings_layout = new QVBoxLayout(); settings_layout->addWidget(check_lock_trophy); settings_layout->addWidget(check_unlock_trophy); @@ -140,23 +198,64 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s icon_settings->setLayout(slider_layout); QVBoxLayout* options_layout = new QVBoxLayout(); - options_layout->addStretch(); + options_layout->addWidget(choose_game); + options_layout->addWidget(trophy_info); options_layout->addWidget(show_settings); options_layout->addWidget(icon_settings); options_layout->addStretch(); QHBoxLayout* all_layout = new QHBoxLayout(this); all_layout->addLayout(options_layout); - all_layout->addWidget(m_trophy_tree); + all_layout->addWidget(m_splitter); 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 + { + const int width_left = m_splitter->width() / 3; + const int width_right = m_splitter->width() - width_left; + m_splitter->setSizes({ width_left, width_right }); + } + else + { + m_splitter->restoreState(splitterstate); + } + + QByteArray game_table_state = m_gui_settings->GetValue(gui::tr_games_state).toByteArray(); + if (!game_table_state.isEmpty()) + { + m_game_table->horizontalHeader()->restoreState(game_table_state); + } + else if (m_game_table->rowCount() > 0) + { + // If no settings exist, go to default. + m_game_table->horizontalHeader()->resizeSections(QHeaderView::ResizeMode::ResizeToContents); + } + + QByteArray trophy_table_state = m_gui_settings->GetValue(gui::tr_trophy_state).toByteArray(); + if (!trophy_table_state.isEmpty()) + { + m_trophy_table->horizontalHeader()->restoreState(trophy_table_state); + } + else if (m_trophy_table->rowCount() > 0) + { + // 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); + } + // Make connects connect(m_icon_slider, &QSlider::valueChanged, this, [=](int val) { + m_icon_height = val; slider_label->setText(tr("Icon Size: %0").arg(val)); ResizeTrophyIcons(val); if (m_save_icon_height) @@ -228,9 +327,18 @@ trophy_manager_dialog::trophy_manager_dialog(std::shared_ptr gui_s m_gui_settings->SetValue(gui::tr_show_platinum, checked); }); - connect(m_trophy_tree->header(), &QHeaderView::sectionClicked, this, &trophy_manager_dialog::OnColClicked); + connect(m_trophy_table, &QTableWidget::customContextMenuRequested, this, &trophy_manager_dialog::ShowContextMenu); - connect(m_trophy_tree, &QTableWidget::customContextMenuRequested, this, &trophy_manager_dialog::ShowContextMenu); + connect(m_game_combo, &QComboBox::currentTextChanged, [this] + { + PopulateUI(); + ApplyFilter(); + }); + + connect(m_game_table, &QTableWidget::doubleClicked, [this] + { + m_game_combo->setCurrentText(m_game_table->item(m_game_table->currentRow(), GameColumns::GameName)->text()); + }); } bool trophy_manager_dialog::LoadTrophyFolderToDB(const std::string& trop_name) @@ -304,94 +412,74 @@ bool trophy_manager_dialog::LoadTrophyFolderToDB(const std::string& trop_name) return true; } -void trophy_manager_dialog::OnColClicked(int col) -{ - if (col == 0) return; // Don't "sort" icons. - - if (col == m_sort_column) - { - m_col_sort_order = (m_col_sort_order == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder; - } - else - { - m_col_sort_order = Qt::AscendingOrder; - } - m_sort_column = col; - - m_trophy_tree->sortByColumn(m_sort_column, m_col_sort_order); -} - void trophy_manager_dialog::ResizeTrophyIcons(int size) { - for (int i = 0; i < m_trophy_tree->topLevelItemCount(); ++i) - { - auto* game = m_trophy_tree->topLevelItem(i); - int db_pos = game->data(1, Qt::UserRole).toInt(); + if (m_game_combo->count() <= 0) + return; - for (int j = 0; j < game->childCount(); ++j) - { - auto* node = game->child(j); - int trophy_id = node->text(TrophyColumns::Id).toInt(); - node->setData(TrophyColumns::Icon, Qt::DecorationRole, m_trophies_db[db_pos]->trophy_images[trophy_id].scaledToHeight(size, Qt::SmoothTransformation)); - node->setSizeHint(TrophyColumns::Icon, QSize(-1, size)); - } + int db_pos = m_game_combo->currentData().toInt(); + + 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)); } + + ReadjustTable(); } void trophy_manager_dialog::ApplyFilter() { - for (int i = 0; i < m_trophy_tree->topLevelItemCount(); ++i) + if (m_game_combo->count() <= 0) + return; + + int db_pos = m_game_combo->currentData().toInt(); + + for (int i = 0; i < m_trophy_table->rowCount(); ++i) { - auto* game = m_trophy_tree->topLevelItem(i); - int db_pos = game->data(1, Qt::UserRole).toInt(); + int trophy_id = m_trophy_table->item(i, TrophyColumns::Id)->text().toInt(); + QString trophy_type = m_trophy_table->item(i, TrophyColumns::Type)->text(); - for (int j = 0; j < game->childCount(); ++j) + // I could use boolean logic and reduce this to something much shorter and also much more confusing... + bool hidden = m_trophy_table->item(i, TrophyColumns::Icon)->data(Qt::UserRole).toBool(); + bool trophy_unlocked = m_trophies_db[db_pos]->trop_usr->GetTrophyUnlockState(trophy_id); + + bool hide = false; + if (trophy_unlocked && !m_show_unlocked_trophies) { - auto* node = game->child(j); - int trophy_id = node->text(TrophyColumns::Id).toInt(); - QString trophy_type = node->text(TrophyColumns::Type); - - // I could use boolean logic and reduce this to something much shorter and also much more confusing... - bool hidden = node->data(TrophyColumns::Hidden, Qt::UserRole).toBool(); - bool trophy_unlocked = m_trophies_db[db_pos]->trop_usr->GetTrophyUnlockState(trophy_id); - - bool hide = false; - if (trophy_unlocked && !m_show_unlocked_trophies) - { - hide = true; - } - if (!trophy_unlocked && !m_show_locked_trophies) - { - hide = true; - } - if (hidden && !trophy_unlocked && !m_show_hidden_trophies) - { - hide = true; - } - if ((trophy_type == Bronze && !m_show_bronze_trophies) - || (trophy_type == Silver && !m_show_silver_trophies) - || (trophy_type == Gold && !m_show_gold_trophies) - || (trophy_type == Platinum && !m_show_platinum_trophies)) - { - hide = true; - } - - // Special override to show *just* hidden trophies. - if (!m_show_unlocked_trophies && !m_show_locked_trophies && m_show_hidden_trophies) - { - hide = !hidden; - } - - node->setHidden(hide); + hide = true; } + if (!trophy_unlocked && !m_show_locked_trophies) + { + hide = true; + } + if (hidden && !trophy_unlocked && !m_show_hidden_trophies) + { + hide = true; + } + if ((trophy_type == Bronze && !m_show_bronze_trophies) + || (trophy_type == Silver && !m_show_silver_trophies) + || (trophy_type == Gold && !m_show_gold_trophies) + || (trophy_type == Platinum && !m_show_platinum_trophies)) + { + hide = true; + } + + // Special override to show *just* hidden trophies. + if (!m_show_unlocked_trophies && !m_show_locked_trophies && m_show_hidden_trophies) + { + hide = !hidden; + } + + m_trophy_table->setRowHidden(i, hide); } } void trophy_manager_dialog::ShowContextMenu(const QPoint& loc) { - QPoint globalPos = m_trophy_tree->mapToGlobal(loc); + QPoint globalPos = m_trophy_table->mapToGlobal(loc); QMenu* menu = new QMenu(); - QTreeWidgetItem* item = m_trophy_tree->currentItem(); + QTableWidgetItem* item = m_trophy_table->item(m_trophy_table->currentRow(), TrophyColumns::Icon); if (!item) { return; @@ -399,17 +487,7 @@ void trophy_manager_dialog::ShowContextMenu(const QPoint& loc) QAction* show_trophy_dir = new QAction(tr("Open Trophy Dir"), menu); - // Only two levels in this tree (ignoring root). So getting the index as such works. - int db_ind; - bool is_game_node = m_trophy_tree->indexOfTopLevelItem(item) != -1; - if (is_game_node) - { - db_ind = item->data(1, Qt::UserRole).toInt(); - } - else - { - db_ind = item->parent()->data(1, Qt::UserRole).toInt(); - } + int db_ind = m_game_combo->currentData().toInt(); connect(show_trophy_dir, &QAction::triggered, [=]() { @@ -423,102 +501,117 @@ void trophy_manager_dialog::ShowContextMenu(const QPoint& loc) void trophy_manager_dialog::PopulateUI() { - for (int i = 0; i < m_trophies_db.size(); ++i) - { - auto& data = m_trophies_db[i]; + if (m_game_combo->count() <= 0) + return; - LOG_TRACE(GENERAL, "Populating Trophy Manager UI with %s %s", data->game_name, data->path); - std::shared_ptr trophy_base = data->trop_config.GetRoot(); - if (trophy_base->GetChildren()->GetName() == "trophyconf") + auto& data = m_trophies_db[m_game_combo->currentData().toInt()]; + LOG_TRACE(GENERAL, "Populating Trophy Manager UI with %s %s", data->game_name, data->path); + + const int all_trophies = data->trop_usr->GetTrophiesCount(); + const int unlocked_trophies = data->trop_usr->GetUnlockedTrophiesCount(); + const int percentage = 100 * unlocked_trophies / all_trophies; + + m_game_progress->setText(QString("Progress: %1% (%2/%3)").arg(percentage).arg(unlocked_trophies).arg(all_trophies)); + + m_trophy_table->clearContents(); + m_trophy_table->setRowCount(all_trophies); + m_trophy_table->setSortingEnabled(false); // Disable sorting before using setItem calls + + std::shared_ptr trophy_base = data->trop_config.GetRoot(); + if (trophy_base->GetChildren()->GetName() == "trophyconf") + { + trophy_base = trophy_base->GetChildren(); + } + else + { + LOG_ERROR(GENERAL, "Root name does not match trophyconf in trophy. Name received: %s", trophy_base->GetChildren()->GetName()); + return; + } + + int i = 0; + for (std::shared_ptr n = trophy_base->GetChildren(); n; n = n->GetNext()) + { + // Only show trophies. + if (n->GetName() != "trophy") { - trophy_base = trophy_base->GetChildren(); - } - else - { - LOG_ERROR(GENERAL, "Root name does not match trophyconf in trophy. Name received: %s", trophy_base->GetChildren()->GetName()); continue; } - QTreeWidgetItem* game_root = new QTreeWidgetItem(m_trophy_tree); - // Name is set later to include the trophy locked/unlocked count. - game_root->setData(1, Qt::UserRole, i); - m_trophy_tree->addTopLevelItem(game_root); + s32 trophy_id = atoi(n->GetAttribute("id").c_str()); - int unlocked_trophies = 0; + // Don't show hidden trophies + bool hidden = n->GetAttribute("hidden")[0] == 'y'; - for (std::shared_ptr n = trophy_base->GetChildren(); n; n = n->GetNext()) - { - // Only show trophies. - if (n->GetName() != "trophy") - { - continue; - } + // Get data (stolen graciously from sceNpTrophy.cpp) + SceNpTrophyDetails details; + details.trophyId = trophy_id; + QString trophy_type = ""; - s32 trophy_id = atoi(n->GetAttribute("id").c_str()); - - // Don't show hidden trophies - bool hidden = n->GetAttribute("hidden")[0] == 'y'; - - // Get data (stolen graciously from sceNpTrophy.cpp) - SceNpTrophyDetails details; - details.trophyId = trophy_id; - QString trophy_type = ""; - - switch (n->GetAttribute("ttype")[0]) - { - case 'B': details.trophyGrade = SCE_NP_TROPHY_GRADE_BRONZE; trophy_type = Bronze; break; - case 'S': details.trophyGrade = SCE_NP_TROPHY_GRADE_SILVER; trophy_type = Silver; break; - case 'G': details.trophyGrade = SCE_NP_TROPHY_GRADE_GOLD; trophy_type = Gold; break; - case 'P': details.trophyGrade = SCE_NP_TROPHY_GRADE_PLATINUM; trophy_type = Platinum; break; - } - - switch (n->GetAttribute("hidden")[0]) - { - case 'y': details.hidden = true; break; - case 'n': details.hidden = false; break; - } - - for (std::shared_ptr n2 = n->GetChildren(); n2; n2 = n2->GetNext()) - { - if (n2->GetName() == "name") - { - std::string name = n2->GetNodeContent(); - memcpy(details.name, name.c_str(), std::min((size_t)SCE_NP_TROPHY_NAME_MAX_SIZE, name.length() + 1)); - } - if (n2->GetName() == "detail") - { - std::string detail = n2->GetNodeContent(); - memcpy(details.description, detail.c_str(), std::min((size_t)SCE_NP_TROPHY_DESCR_MAX_SIZE, detail.length() + 1)); - } - } - - bool unlocked = data->trop_usr->GetTrophyUnlockState(trophy_id); - if (unlocked) - { - ++unlocked_trophies; - } - - trophy_tree_widget_item* trophy_item = new trophy_tree_widget_item(game_root); - trophy_item->setData(TrophyColumns::Icon, Qt::DecorationRole, data->trophy_images[trophy_id].scaledToHeight(m_icon_height, Qt::SmoothTransformation)); - trophy_item->setSizeHint(TrophyColumns::Icon, QSize(-1, m_icon_height)); - trophy_item->setText(TrophyColumns::Name, qstr(details.name)); - trophy_item->setText(TrophyColumns::Description, qstr(details.description)); - trophy_item->setText(TrophyColumns::Type, trophy_type); - trophy_item->setText(TrophyColumns::IsUnlocked, unlocked ? "Unlocked" : "Locked"); - trophy_item->setText(TrophyColumns::Id, QString::number(trophy_id)); - trophy_item->setData(TrophyColumns::Hidden, Qt::UserRole, hidden); - - game_root->addChild(trophy_item); + switch (n->GetAttribute("ttype")[0]) + { + case 'B': details.trophyGrade = SCE_NP_TROPHY_GRADE_BRONZE; trophy_type = Bronze; break; + case 'S': details.trophyGrade = SCE_NP_TROPHY_GRADE_SILVER; trophy_type = Silver; break; + case 'G': details.trophyGrade = SCE_NP_TROPHY_GRADE_GOLD; trophy_type = Gold; break; + case 'P': details.trophyGrade = SCE_NP_TROPHY_GRADE_PLATINUM; trophy_type = Platinum; break; } - int all_trophies = data->trop_usr->GetTrophiesCount(); - int percentage = 100 * unlocked_trophies / all_trophies; - game_root->setText(0, qstr(data->game_name) + QString(" : %1% (%2/%3)").arg(percentage).arg(unlocked_trophies).arg(all_trophies)); + switch (n->GetAttribute("hidden")[0]) + { + case 'y': details.hidden = true; break; + case 'n': details.hidden = false; break; + } + + for (std::shared_ptr n2 = n->GetChildren(); n2; n2 = n2->GetNext()) + { + if (n2->GetName() == "name") + { + std::string name = n2->GetNodeContent(); + memcpy(details.name, name.c_str(), std::min((size_t)SCE_NP_TROPHY_NAME_MAX_SIZE, name.length() + 1)); + } + if (n2->GetName() == "detail") + { + std::string detail = n2->GetNodeContent(); + memcpy(details.description, detail.c_str(), std::min((size_t)SCE_NP_TROPHY_DESCR_MAX_SIZE, detail.length() + 1)); + } + } + + QString unlockstate = data->trop_usr->GetTrophyUnlockState(trophy_id) ? tr("Unlocked") : tr("Locked"); + + custom_table_widget_item* icon_item = new custom_table_widget_item(); + icon_item->setData(Qt::DecorationRole, data->trophy_images[trophy_id].scaledToHeight(m_icon_height, Qt::SmoothTransformation)); + icon_item->setData(Qt::UserRole, hidden, true); + + custom_table_widget_item* type_item = new custom_table_widget_item(trophy_type); + type_item->setData(Qt::UserRole, uint(details.trophyGrade), true); + + m_trophy_table->setItem(i, TrophyColumns::Icon, icon_item); + m_trophy_table->setItem(i, TrophyColumns::Name, new custom_table_widget_item(qstr(details.name))); + m_trophy_table->setItem(i, TrophyColumns::Description, new custom_table_widget_item(qstr(details.description))); + m_trophy_table->setItem(i, TrophyColumns::Type, type_item); + m_trophy_table->setItem(i, TrophyColumns::IsUnlocked, new custom_table_widget_item(unlockstate)); + m_trophy_table->setItem(i, TrophyColumns::Id, new custom_table_widget_item(QString::number(trophy_id))); + + ++i; } + + m_trophy_table->setSortingEnabled(true); // Re-enable sorting after using setItem calls + + ReadjustTable(); +} + +void trophy_manager_dialog::ReadjustTable() +{ + m_trophy_table->verticalHeader()->setMinimumSectionSize(m_icon_height); + m_trophy_table->verticalHeader()->setMaximumSectionSize(m_icon_height); + m_trophy_table->resizeRowsToContents(); + m_trophy_table->resizeColumnToContents(TrophyColumns::Icon); } void trophy_manager_dialog::closeEvent(QCloseEvent * event) { // Save gui settings m_gui_settings->SetValue(gui::tr_geometry, saveGeometry()); + m_gui_settings->SetValue(gui::tr_splitterState, m_splitter->saveState()); + m_gui_settings->SetValue(gui::tr_games_state, m_game_table->horizontalHeader()->saveState()); + m_gui_settings->SetValue(gui::tr_trophy_state, m_trophy_table->horizontalHeader()->saveState()); } diff --git a/rpcs3/rpcs3qt/trophy_manager_dialog.h b/rpcs3/rpcs3qt/trophy_manager_dialog.h index 1d5e4cde8b..3cef6b52a5 100644 --- a/rpcs3/rpcs3qt/trophy_manager_dialog.h +++ b/rpcs3/rpcs3qt/trophy_manager_dialog.h @@ -8,9 +8,12 @@ #include "Utilities/rXml.h" #include +#include +#include #include -#include +#include #include +#include struct GameTrophiesData { @@ -29,7 +32,16 @@ enum TrophyColumns Type = 3, IsUnlocked = 4, Id = 5, - Hidden = 6, + + Count = 6, +}; + +enum GameColumns +{ + GameName = 0, + GameProgress = 1, + + GameColumnsCount = 2, }; class trophy_manager_dialog : public QWidget @@ -42,7 +54,6 @@ class trophy_manager_dialog : public QWidget public: explicit trophy_manager_dialog(std::shared_ptr gui_settings); private Q_SLOTS: - void OnColClicked(int col); void ResizeTrophyIcons(int val); void ApplyFilter(); void ShowContextMenu(const QPoint& pos); @@ -57,15 +68,18 @@ private: */ void PopulateUI(); + void ReadjustTable(); + void closeEvent(QCloseEvent* event) override; std::shared_ptr m_gui_settings; std::vector> m_trophies_db; //! Holds all the trophy information. - QTreeWidget* m_trophy_tree; //! UI element to display trophy stuff. - - int m_sort_column = 0; //! Tracks which row we are sorting by. - Qt::SortOrder m_col_sort_order = Qt::AscendingOrder; //! Tracks order in which we are sorting. + QComboBox* m_game_combo; //! Lets you choose a game + QLabel* m_game_progress; //! Shows you the current game's progress + QSplitter* m_splitter; //! Contains the game and trophy tables + QTableWidget* m_trophy_table; //! UI element to display trophy stuff. + QTableWidget* m_game_table; //! UI element to display games. bool m_show_hidden_trophies = false; bool m_show_unlocked_trophies = true;