mirror of
https://github.com/redstrate/Novus.git
synced 2025-04-24 21:07:46 +00:00
Create and use gear list model and widget
This commit is contained in:
parent
8fb0b26c18
commit
10996a7f5a
9 changed files with 269 additions and 58 deletions
|
@ -11,7 +11,9 @@ add_executable(mdlviewer
|
|||
src/fullmodelviewer.cpp
|
||||
src/quaternionedit.cpp
|
||||
src/boneeditor.cpp
|
||||
src/cmpeditor.cpp)
|
||||
src/cmpeditor.cpp
|
||||
src/gearlistwidget.cpp
|
||||
src/gearlistmodel.cpp)
|
||||
target_include_directories(mdlviewer
|
||||
PUBLIC
|
||||
include)
|
||||
|
|
45
mdlviewer/include/gearlistmodel.h
Normal file
45
mdlviewer/include/gearlistmodel.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
|
||||
#include "gearview.h"
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
enum class TreeType {
|
||||
Root,
|
||||
Category,
|
||||
Item
|
||||
};
|
||||
|
||||
struct TreeInformation {
|
||||
TreeType type;
|
||||
std::optional<Slot> slotType;
|
||||
TreeInformation* parent = nullptr;
|
||||
std::optional<GearInfo> gear;
|
||||
int row = 0;
|
||||
|
||||
std::vector<TreeInformation*> children;
|
||||
};
|
||||
|
||||
class GearListModel : public QAbstractItemModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GearListModel(GameData* data);
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
|
||||
QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex& child) const override;
|
||||
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
std::optional<GearInfo> getGearFromIndex(const QModelIndex& index);
|
||||
|
||||
private:
|
||||
std::vector<GearInfo> gears;
|
||||
QStringList slotNames;
|
||||
|
||||
GameData* gameData = nullptr;
|
||||
TreeInformation* rootItem = nullptr;
|
||||
};
|
22
mdlviewer/include/gearlistwidget.h
Normal file
22
mdlviewer/include/gearlistwidget.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QWidget>
|
||||
#include <physis.hpp>
|
||||
|
||||
#include "gearview.h"
|
||||
|
||||
class GearListWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GearListWidget(GameData* data, QWidget* parent = nullptr);
|
||||
|
||||
Q_SIGNALS:
|
||||
void gearSelected(const GearInfo& gear);
|
||||
|
||||
private:
|
||||
QTreeView* listWidget = nullptr;
|
||||
|
||||
GameData* data = nullptr;
|
||||
};
|
|
@ -17,8 +17,6 @@ public:
|
|||
explicit MainWindow(GameData* data);
|
||||
|
||||
private:
|
||||
std::vector<GearInfo> gears;
|
||||
|
||||
SingleGearView* gearView = nullptr;
|
||||
FullModelViewer* fullModelViewer = nullptr;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ Q_SIGNALS:
|
|||
|
||||
public Q_SLOTS:
|
||||
void clear();
|
||||
void setGear(GearInfo& info);
|
||||
void setGear(const GearInfo& info);
|
||||
|
||||
void setRace(Race race);
|
||||
void setSubrace(Subrace subrace);
|
||||
|
|
164
mdlviewer/src/gearlistmodel.cpp
Normal file
164
mdlviewer/src/gearlistmodel.cpp
Normal file
|
@ -0,0 +1,164 @@
|
|||
#include "gearlistmodel.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <magic_enum.hpp>
|
||||
|
||||
GearListModel::GearListModel(GameData* data) : gameData(data), QAbstractItemModel() {
|
||||
beginResetModel();
|
||||
// smallclothes body
|
||||
{
|
||||
GearInfo info = {};
|
||||
info.name = "Smallclothes Body";
|
||||
info.slot = Slot::Body;
|
||||
|
||||
gears.push_back(info);
|
||||
}
|
||||
|
||||
// smallclothes legs
|
||||
{
|
||||
GearInfo info = {};
|
||||
info.name = "Smallclothes Legs";
|
||||
info.slot = Slot::Legs;
|
||||
|
||||
gears.push_back(info);
|
||||
}
|
||||
|
||||
auto exh = physis_gamedata_read_excel_sheet_header(data, "Item");
|
||||
|
||||
for (int p = 0; p < exh->page_count; p++) {
|
||||
auto exd = physis_gamedata_read_excel_sheet(data, "Item", exh, Language::English, p);
|
||||
|
||||
for (int i = 0; i < exd.row_count; i++) {
|
||||
const auto row = exd.row_data[i];
|
||||
auto primaryModel = row.column_data[47].u_int64._0;
|
||||
auto secondaryModel = row.column_data[48].u_int64._0;
|
||||
|
||||
int16_t parts[4];
|
||||
memcpy(parts, &primaryModel, sizeof(int16_t) * 4);
|
||||
|
||||
GearInfo info = {};
|
||||
info.name = row.column_data[9].string._0;
|
||||
info.slot = physis_slot_from_id(row.column_data[17].u_int8._0);
|
||||
info.modelInfo.primaryID = parts[0];
|
||||
|
||||
gears.push_back(info);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto slotName : magic_enum::enum_names<Slot>()) {
|
||||
slotNames.push_back(slotName.data());
|
||||
}
|
||||
endResetModel();
|
||||
|
||||
rootItem = new TreeInformation();
|
||||
rootItem->type = TreeType::Root;
|
||||
|
||||
int i = 0;
|
||||
for (auto slot : magic_enum::enum_values<Slot>()) {
|
||||
TreeInformation* categoryItem = new TreeInformation();
|
||||
categoryItem->type = TreeType::Category;
|
||||
categoryItem->slotType = slot;
|
||||
categoryItem->parent = rootItem;
|
||||
categoryItem->row = i++;
|
||||
rootItem->children.push_back(categoryItem);
|
||||
|
||||
int j = 0;
|
||||
for (auto gear : gears) {
|
||||
if (gear.slot == slot) {
|
||||
TreeInformation* item = new TreeInformation();
|
||||
item->type = TreeType::Item;
|
||||
item->gear = gear;
|
||||
item->parent = categoryItem;
|
||||
item->row = j++;
|
||||
categoryItem->children.push_back(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GearListModel::rowCount(const QModelIndex& parent) const {
|
||||
TreeInformation* parentItem;
|
||||
if (parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentItem = rootItem;
|
||||
else
|
||||
parentItem = static_cast<TreeInformation*>(parent.internalPointer());
|
||||
|
||||
return parentItem->children.size();
|
||||
}
|
||||
|
||||
int GearListModel::columnCount(const QModelIndex& parent) const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
QModelIndex GearListModel::index(int row, int column, const QModelIndex& parent) const {
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
TreeInformation* parentItem;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentItem = rootItem;
|
||||
else
|
||||
parentItem = static_cast<TreeInformation*>(parent.internalPointer());
|
||||
|
||||
TreeInformation* childItem = parentItem->children[row];
|
||||
if (childItem)
|
||||
return createIndex(row, column, childItem);
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex GearListModel::parent(const QModelIndex& index) const {
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
TreeInformation* childItem = static_cast<TreeInformation*>(index.internalPointer());
|
||||
TreeInformation* parentItem = childItem->parent;
|
||||
|
||||
if (parentItem == rootItem)
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(parentItem->row, 0, parentItem);
|
||||
}
|
||||
|
||||
QVariant GearListModel::data(const QModelIndex& index, int role) const {
|
||||
if (!index.isValid())
|
||||
return {};
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
TreeInformation* item = static_cast<TreeInformation*>(index.internalPointer());
|
||||
|
||||
if (item->type == TreeType::Category) {
|
||||
return magic_enum::enum_name(*item->slotType).data();
|
||||
} else if (item->type == TreeType::Item) {
|
||||
return item->gear->name.data();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QVariant GearListModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
||||
if (section == 0) {
|
||||
return "Name";
|
||||
}
|
||||
}
|
||||
|
||||
return QAbstractItemModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
std::optional<GearInfo> GearListModel::getGearFromIndex(const QModelIndex& index) {
|
||||
TreeInformation* item = static_cast<TreeInformation*>(index.internalPointer());
|
||||
if (item->type == TreeType::Item) {
|
||||
return item->gear;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
#include "moc_gearlistmodel.cpp"
|
26
mdlviewer/src/gearlistwidget.cpp
Normal file
26
mdlviewer/src/gearlistwidget.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include "gearlistwidget.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <magic_enum.hpp>
|
||||
|
||||
#include "gearlistmodel.h"
|
||||
|
||||
GearListWidget::GearListWidget(GameData* data, QWidget* parent) : data(data) {
|
||||
auto layout = new QVBoxLayout();
|
||||
setLayout(layout);
|
||||
|
||||
auto model = new GearListModel(data);
|
||||
|
||||
listWidget = new QTreeView();
|
||||
listWidget->setModel(model);
|
||||
|
||||
connect(listWidget, &QTreeView::clicked, [this, model](const QModelIndex& item) {
|
||||
if (auto gear = model->getGearFromIndex(item)) {
|
||||
Q_EMIT gearSelected(*gear);
|
||||
}
|
||||
});
|
||||
|
||||
layout->addWidget(listWidget);
|
||||
}
|
||||
|
||||
#include "moc_gearlistwidget.cpp"
|
|
@ -16,6 +16,7 @@
|
|||
#include <physis.hpp>
|
||||
|
||||
#include "cmpeditor.h"
|
||||
#include "gearlistwidget.h"
|
||||
|
||||
MainWindow::MainWindow(GameData* in_data) : data(*in_data) {
|
||||
setWindowTitle("mdlviewer");
|
||||
|
@ -52,50 +53,12 @@ MainWindow::MainWindow(GameData* in_data) : data(*in_data) {
|
|||
auto layout = new QHBoxLayout();
|
||||
dummyWidget->setLayout(layout);
|
||||
|
||||
// smallclothes body
|
||||
{
|
||||
GearInfo info = {};
|
||||
info.name = "Smallclothes Body";
|
||||
info.slot = Slot::Body;
|
||||
|
||||
gears.push_back(info);
|
||||
}
|
||||
|
||||
// smallclothes legs
|
||||
{
|
||||
GearInfo info = {};
|
||||
info.name = "Smallclothes Legs";
|
||||
info.slot = Slot::Legs;
|
||||
|
||||
gears.push_back(info);
|
||||
}
|
||||
|
||||
auto exh = physis_gamedata_read_excel_sheet_header(&data, "Item");
|
||||
auto exd = physis_gamedata_read_excel_sheet(&data, "Item", exh, Language::English, 1);
|
||||
|
||||
for (int i = 0; i < exd.row_count; i++) {
|
||||
const auto row = exd.row_data[i];
|
||||
auto primaryModel = row.column_data[47].u_int64._0;
|
||||
auto secondaryModel = row.column_data[48].u_int64._0;
|
||||
|
||||
int16_t parts[4];
|
||||
memcpy(parts, &primaryModel, sizeof(int16_t) * 4);
|
||||
|
||||
GearInfo info = {};
|
||||
info.name = row.column_data[9].string._0;
|
||||
info.slot = physis_slot_from_id(row.column_data[17].u_int8._0);
|
||||
info.modelInfo.primaryID = parts[0];
|
||||
|
||||
gears.push_back(info);
|
||||
}
|
||||
|
||||
auto listWidget = new QListWidget();
|
||||
for (auto gear : gears)
|
||||
listWidget->addItem(gear.name.c_str());
|
||||
|
||||
listWidget->setMaximumWidth(200);
|
||||
|
||||
layout->addWidget(listWidget);
|
||||
auto gearListWidget = new GearListWidget(&data);
|
||||
gearListWidget->setMaximumWidth(350);
|
||||
connect(gearListWidget, &GearListWidget::gearSelected, this, [=](const GearInfo& gear) {
|
||||
gearView->setGear(gear);
|
||||
});
|
||||
layout->addWidget(gearListWidget);
|
||||
|
||||
gearView = new SingleGearView(&data);
|
||||
connect(gearView, &SingleGearView::addToFullModelViewer, this, [=](GearInfo& info) {
|
||||
|
@ -103,15 +66,6 @@ MainWindow::MainWindow(GameData* in_data) : data(*in_data) {
|
|||
});
|
||||
layout->addWidget(gearView);
|
||||
|
||||
connect(listWidget, &QListWidget::itemClicked, [this](QListWidgetItem* item) {
|
||||
for (auto& gear : gears) {
|
||||
if (gear.name == item->text().toStdString()) {
|
||||
gearView->setGear(gear);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
fullModelViewer = new FullModelViewer(&data);
|
||||
fullModelViewer->show();
|
||||
}
|
|
@ -91,7 +91,7 @@ void SingleGearView::clear() {
|
|||
Q_EMIT gearChanged();
|
||||
}
|
||||
|
||||
void SingleGearView::setGear(GearInfo& info) {
|
||||
void SingleGearView::setGear(const GearInfo& info) {
|
||||
currentGear = info;
|
||||
|
||||
Q_EMIT gearChanged();
|
||||
|
|
Loading…
Add table
Reference in a new issue