Enhance Infinity Manager Figure Creator Dialog (#17529)
Some checks failed
Generate Translation Template / Generate Translation Template (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux-aarch64.sh, gcc, rpcs3/rpcs3-ci-jammy-aarch64:1.6, ubuntu-24.04-arm) (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux.sh, gcc, rpcs3/rpcs3-ci-jammy:1.6, ubuntu-24.04) (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (a1d35836e8d45bfc6f63c26f0a3e5d46ef622fe1, rpcs3/rpcs3-binaries-linux-arm64, /rpcs3/.ci/build-linux-aarch64.sh, clang, rpcs3/rpcs3-ci-jammy-aarch64:1.6, ubuntu-24.04-arm) (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (d812f1254a1157c80fd402f94446310560f54e5f, rpcs3/rpcs3-binaries-linux, /rpcs3/.ci/build-linux.sh, clang, rpcs3/rpcs3-ci-jammy:1.6, ubuntu-24.04) (push) Has been cancelled
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (51ae32f468089a8169aaf1567de355ff4a3e0842, rpcs3/rpcs3-binaries-mac, .ci/build-mac.sh, Intel) (push) Has been cancelled
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (8e21bdbc40711a3fccd18fbf17b742348b0f4281, rpcs3/rpcs3-binaries-mac-arm64, .ci/build-mac-arm64.sh, Apple Silicon) (push) Has been cancelled
Build RPCS3 / RPCS3 Windows (push) Has been cancelled
Build RPCS3 / RPCS3 Windows Clang (win64, clang, clang64) (push) Has been cancelled
Build RPCS3 / RPCS3 FreeBSD (push) Has been cancelled

## Summary
This will enhance and add filters for the Figure Creator dialog of
Infinity manager, adding selectable filters for the character dropdown
and displays the series number after the figure/power disc.

## Changes
- Added filter buttons for Disney Infinity 1.0, 2.0, 3.0, and "All"
- Character names now display series information (e.g., "Buzz Lightyear
(1.0)")
- Dynamic dropdown population based on selected filter
- Maintains all existing functionality and slot validation

## Benefits
- Easier character discovery in large character lists
- Better organization by game series
This commit is contained in:
Swordmaster3214 2025-09-28 15:29:54 -05:00 committed by GitHub
parent 359163c442
commit 6fe6c4e0f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -14,6 +14,7 @@
#include <QPushButton>
#include <QStringList>
#include <QCompleter>
#include <QButtonGroup>
infinity_dialog* infinity_dialog::inst = nullptr;
std::array<std::optional<u32>, 9> infinity_dialog::figure_slots = {};
@ -407,46 +408,94 @@ figure_creator_dialog::figure_creator_dialog(QWidget* parent, u8 slot)
{
setWindowTitle(tr("Figure Creator"));
setObjectName("figure_creator");
setMinimumSize(QSize(500, 150));
setMinimumSize(QSize(500, 200));
QVBoxLayout* vbox_panel = new QVBoxLayout();
QComboBox* combo_figlist = new QComboBox();
QStringList filterlist;
u32 first_entry = 0;
// Add series filter buttons
QHBoxLayout* hbox_filters = new QHBoxLayout();
QLabel* filter_label = new QLabel(tr("Filter by Series:"));
QPushButton* btn_all = new QPushButton(tr("All"));
QPushButton* btn_series1 = new QPushButton(tr("1.0"));
QPushButton* btn_series2 = new QPushButton(tr("2.0"));
QPushButton* btn_series3 = new QPushButton(tr("3.0"));
for (const auto& [figure, entry] : list_figures)
// Style the active filter button
btn_all->setCheckable(true);
btn_series1->setCheckable(true);
btn_series2->setCheckable(true);
btn_series3->setCheckable(true);
btn_all->setChecked(true); // Default to "All"
hbox_filters->addWidget(filter_label);
hbox_filters->addWidget(btn_all);
hbox_filters->addWidget(btn_series1);
hbox_filters->addWidget(btn_series2);
hbox_filters->addWidget(btn_series3);
hbox_filters->addStretch();
vbox_panel->addLayout(hbox_filters);
QComboBox* combo_figlist = new QComboBox();
// Lambda to populate the combo box based on series filter
auto populate_combo = [=](int series_filter) -> u32
{
// Only display entry if it is a piece appropriate for the slot
if ((slot == 0 &&
((figure > 0x1E8480 && figure < 0x2DC6BF) || (figure > 0x3D0900 && figure < 0x4C4B3F))) ||
((slot == 1 || slot == 2) && (figure > 0x3D0900 && figure < 0x4C4B3F)) ||
((slot == 3 || slot == 6) && figure < 0x1E847F) ||
((slot == 4 || slot == 5 || slot == 7 || slot == 8) &&
(figure > 0x2DC6C0 && figure < 0x3D08FF)))
combo_figlist->clear();
QStringList filterlist;
u32 first_entry = 0;
for (const auto& [figure, entry] : list_figures)
{
const auto& [num, figure_name] = entry;
const u32 qnum = (figure << 8) | num;
QString name = QString::fromStdString(figure_name);
combo_figlist->addItem(name, QVariant(qnum));
filterlist << std::move(name);
if (first_entry == 0)
// Apply series filter (0 = all, 1-3 = specific series)
if (series_filter != 0 && num != series_filter)
continue;
// Only display entry if it is a piece appropriate for the slot
if ((slot == 0 &&
((figure > 0x1E8480 && figure < 0x2DC6BF) || (figure > 0x3D0900 && figure < 0x4C4B3F))) ||
((slot == 1 || slot == 2) && (figure > 0x3D0900 && figure < 0x4C4B3F)) ||
((slot == 3 || slot == 6) && figure < 0x1E847F) ||
((slot == 4 || slot == 5 || slot == 7 || slot == 8) &&
(figure > 0x2DC6C0 && figure < 0x3D08FF)))
{
first_entry = figure;
const u32 qnum = (figure << 8) | num;
const QString name = QString::fromStdString(figure_name);
// Add series indicator to the name for clarity
QString display_name = QString("%1 (%2.0)").arg(name).arg(num);
combo_figlist->addItem(display_name, QVariant(qnum));
filterlist << std::move(display_name);
if (first_entry == 0)
{
first_entry = figure;
}
}
}
}
combo_figlist->addItem(tr("--Unknown--"), QVariant(0xFFFFFFFF));
combo_figlist->setEditable(true);
combo_figlist->setInsertPolicy(QComboBox::NoInsert);
combo_figlist->model()->sort(0, Qt::AscendingOrder);
combo_figlist->addItem(tr("--Unknown--"), QVariant(0xFFFFFFFF));
combo_figlist->setEditable(true);
combo_figlist->setInsertPolicy(QComboBox::NoInsert);
combo_figlist->model()->sort(0, Qt::AscendingOrder);
QCompleter* co_compl = new QCompleter(filterlist, this);
co_compl->setCaseSensitivity(Qt::CaseInsensitive);
co_compl->setCompletionMode(QCompleter::PopupCompletion);
co_compl->setFilterMode(Qt::MatchContains);
combo_figlist->setCompleter(co_compl);
// Update completer with new filter list
QCompleter* co_compl = new QCompleter(filterlist, this);
co_compl->setCaseSensitivity(Qt::CaseInsensitive);
co_compl->setCompletionMode(QCompleter::PopupCompletion);
co_compl->setFilterMode(Qt::MatchContains);
combo_figlist->setCompleter(co_compl);
connect(co_compl, QOverload<const QString&>::of(&QCompleter::activated), [=](const QString& text)
{
combo_figlist->setCurrentIndex(combo_figlist->findText(text));
});
return first_entry;
};
// Initially populate with all figures
u32 first_entry = populate_combo(0);
vbox_panel->addWidget(combo_figlist);
@ -480,65 +529,72 @@ figure_creator_dialog::figure_creator_dialog(QWidget* parent, u8 slot)
setLayout(vbox_panel);
connect(combo_figlist, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index)
{
const u32 fig_info = combo_figlist->itemData(index).toUInt();
if (fig_info != 0xFFFFFFFF)
{
const u32 fig_num = fig_info >> 8;
const u8 series = fig_info & 0xFF;
// Connect filter buttons using QButtonGroup
QButtonGroup* filter_group = new QButtonGroup(this);
filter_group->addButton(btn_all, 0); // ID 0 for "All"
filter_group->addButton(btn_series1, 1); // ID 1 for series 1
filter_group->addButton(btn_series2, 2); // ID 2 for series 2
filter_group->addButton(btn_series3, 3); // ID 3 for series 3
edit_number->setText(QString::number(fig_num));
edit_series->setText(QString::number(series));
}
});
connect(filter_group, QOverload<int>::of(&QButtonGroup::idClicked), [=](int id)
{
populate_combo(id);
});
connect(combo_figlist, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index)
{
const u32 fig_info = combo_figlist->itemData(index).toUInt();
if (fig_info != 0xFFFFFFFF)
{
const u32 fig_num = fig_info >> 8;
const u8 series = fig_info & 0xFF;
edit_number->setText(QString::number(fig_num));
edit_series->setText(QString::number(series));
}
});
connect(btn_create, &QAbstractButton::clicked, this, [=, this]()
{
bool ok_num = false, ok_series = false;
const u32 fig_num = edit_number->text().toULong(&ok_num);
if (!ok_num)
{
bool ok_num = false, ok_series = false;
const u32 fig_num = edit_number->text().toULong(&ok_num);
if (!ok_num)
{
QMessageBox::warning(this, tr("Error converting value"), tr("Figure number entered is invalid!"), QMessageBox::Ok);
return;
}
const u8 series = edit_series->text().toUShort(&ok_series);
if (!ok_series || series > 3 || series < 1)
{
QMessageBox::warning(this, tr("Error converting value"), tr("Series number entered is invalid!"), QMessageBox::Ok);
return;
}
const auto found_figure = list_figures.find(fig_num);
if (found_figure != list_figures.cend())
{
s_last_figure_path += QString::fromStdString(found_figure->second.second + ".bin");
}
else
{
s_last_figure_path += QString("Unknown(%1 %2).bin").arg(fig_num).arg(series);
}
QMessageBox::warning(this, tr("Error converting value"), tr("Figure number entered is invalid!"), QMessageBox::Ok);
return;
}
const u8 series = edit_series->text().toUShort(&ok_series);
if (!ok_series || series > 3 || series < 1)
{
QMessageBox::warning(this, tr("Error converting value"), tr("Series number entered is invalid!"), QMessageBox::Ok);
return;
}
const auto found_figure = list_figures.find(fig_num);
if (found_figure != list_figures.cend())
{
s_last_figure_path += QString::fromStdString(found_figure->second.second + ".bin");
}
else
{
s_last_figure_path += QString("Unknown(%1 %2).bin").arg(fig_num).arg(series);
}
m_file_path = QFileDialog::getSaveFileName(this, tr("Create Figure File"), s_last_figure_path, tr("Infinity Figure (*.bin);;"));
if (m_file_path.isEmpty())
{
return;
}
if (!create_blank_figure(fig_num, series))
{
QMessageBox::warning(this, tr("Failed to create figure file!"), tr("Failed to create figure file:\n%1").arg(m_file_path), QMessageBox::Ok);
return;
}
m_file_path = QFileDialog::getSaveFileName(this, tr("Create Figure File"), s_last_figure_path, tr("Infinity Figure (*.bin);;"));
if (m_file_path.isEmpty())
{
return;
}
if (!create_blank_figure(fig_num, series))
{
QMessageBox::warning(this, tr("Failed to create figure file!"), tr("Failed to create figure file:\n%1").arg(m_file_path), QMessageBox::Ok);
return;
}
s_last_figure_path = QFileInfo(m_file_path).absolutePath() + "/";
accept();
});
s_last_figure_path = QFileInfo(m_file_path).absolutePath() + "/";
accept();
});
connect(btn_cancel, &QAbstractButton::clicked, this, &QDialog::reject);
connect(co_compl, QOverload<const QString&>::of(&QCompleter::activated), [=](const QString& text)
{
combo_figlist->setCurrentIndex(combo_figlist->findText(text));
});
}
bool figure_creator_dialog::create_blank_figure(u32 character, u8 series)