mirror of
https://github.com/isledecomp/SIEdit.git
synced 2024-11-30 02:55:34 -05:00
app: add object-focused tab
This commit is contained in:
parent
9ce113f1f0
commit
0fb49a780b
10 changed files with 233 additions and 40 deletions
|
@ -17,11 +17,15 @@ set(PROJECT_SOURCES
|
||||||
panels/riff.cpp
|
panels/riff.cpp
|
||||||
panels/riff.h
|
panels/riff.h
|
||||||
|
|
||||||
|
abstractsiitemmodel.cpp
|
||||||
|
abstractsiitemmodel.h
|
||||||
chunkmodel.cpp
|
chunkmodel.cpp
|
||||||
chunkmodel.h
|
chunkmodel.h
|
||||||
main.cpp
|
main.cpp
|
||||||
mainwindow.cpp
|
mainwindow.cpp
|
||||||
mainwindow.h
|
mainwindow.h
|
||||||
|
objectmodel.cpp
|
||||||
|
objectmodel.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||||
|
|
26
app/abstractsiitemmodel.cpp
Normal file
26
app/abstractsiitemmodel.cpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include "abstractsiitemmodel.h"
|
||||||
|
|
||||||
|
using namespace si;
|
||||||
|
|
||||||
|
AbstractSIItemModel::AbstractSIItemModel(QObject *parent) :
|
||||||
|
QAbstractItemModel{parent},
|
||||||
|
chunk_(nullptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractSIItemModel::SetChunk(si::Chunk *c)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
chunk_ = c;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
si::Chunk *AbstractSIItemModel::GetChunkFromIndex(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid()) {
|
||||||
|
return chunk_;
|
||||||
|
} else {
|
||||||
|
return static_cast<Chunk*>(index.internalPointer());
|
||||||
|
}
|
||||||
|
}
|
25
app/abstractsiitemmodel.h
Normal file
25
app/abstractsiitemmodel.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef ABSTRACTSIITEMMODEL_H
|
||||||
|
#define ABSTRACTSIITEMMODEL_H
|
||||||
|
|
||||||
|
#include <chunk.h>
|
||||||
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
class AbstractSIItemModel : public QAbstractItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit AbstractSIItemModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
void SetChunk(si::Chunk *c);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
si::Chunk *GetChunkFromIndex(const QModelIndex &index) const;
|
||||||
|
|
||||||
|
si::Chunk *root() const { return chunk_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
si::Chunk *chunk_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ABSTRACTSIITEMMODEL_H
|
|
@ -2,13 +2,12 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#define super QAbstractItemModel
|
#define super AbstractSIItemModel
|
||||||
|
|
||||||
using namespace si;
|
using namespace si;
|
||||||
|
|
||||||
ChunkModel::ChunkModel(QObject *parent) :
|
ChunkModel::ChunkModel(QObject *parent) :
|
||||||
super{parent},
|
super{parent}
|
||||||
chunk_(nullptr)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +44,7 @@ QModelIndex ChunkModel::parent(const QModelIndex &index) const
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t row = grandparent->IndexOfChild(parent);
|
size_t row = grandparent->IndexOfChild(parent);
|
||||||
return createIndex(row, 0, parent);
|
return createIndex(int(row), 0, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ChunkModel::rowCount(const QModelIndex &parent) const
|
int ChunkModel::rowCount(const QModelIndex &parent) const
|
||||||
|
@ -55,7 +54,7 @@ int ChunkModel::rowCount(const QModelIndex &parent) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return c->GetChildCount();
|
return int(c->GetChildCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant ChunkModel::data(const QModelIndex &index, int role) const
|
QVariant ChunkModel::data(const QModelIndex &index, int role) const
|
||||||
|
@ -99,19 +98,3 @@ QVariant ChunkModel::headerData(int section, Qt::Orientation orientation, int ro
|
||||||
|
|
||||||
return super::headerData(section, orientation, role);
|
return super::headerData(section, orientation, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChunkModel::SetChunk(si::Chunk *c)
|
|
||||||
{
|
|
||||||
beginResetModel();
|
|
||||||
chunk_ = c;
|
|
||||||
endResetModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
si::Chunk *ChunkModel::GetChunkFromIndex(const QModelIndex &index) const
|
|
||||||
{
|
|
||||||
if (!index.isValid()) {
|
|
||||||
return chunk_;
|
|
||||||
} else {
|
|
||||||
return static_cast<Chunk*>(index.internalPointer());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#ifndef CHUNKMODEL_H
|
#ifndef CHUNKMODEL_H
|
||||||
#define CHUNKMODEL_H
|
#define CHUNKMODEL_H
|
||||||
|
|
||||||
#include <chunk.h>
|
#include "abstractsiitemmodel.h"
|
||||||
#include <QAbstractItemModel>
|
|
||||||
|
|
||||||
class ChunkModel : public QAbstractItemModel
|
class ChunkModel : public AbstractSIItemModel
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum Columns
|
enum Columns
|
||||||
{
|
{
|
||||||
|
@ -25,13 +25,6 @@ public:
|
||||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
void SetChunk(si::Chunk *c);
|
|
||||||
|
|
||||||
private:
|
|
||||||
si::Chunk *GetChunkFromIndex(const QModelIndex &index) const;
|
|
||||||
|
|
||||||
si::Chunk *chunk_;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHUNKMODEL_H
|
#endif // CHUNKMODEL_H
|
||||||
|
|
|
@ -16,12 +16,18 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
splitter->setChildrenCollapsible(false);
|
splitter->setChildrenCollapsible(false);
|
||||||
this->setCentralWidget(splitter);
|
this->setCentralWidget(splitter);
|
||||||
|
|
||||||
model_.SetChunk(&chunk_);
|
auto tree_tab = new QTabWidget();
|
||||||
|
splitter->addWidget(tree_tab);
|
||||||
|
|
||||||
auto tree = new QTreeView();
|
auto simple_tree = new QTreeView();
|
||||||
tree->setModel(&model_);
|
simple_tree->setModel(&object_model_);
|
||||||
splitter->addWidget(tree);
|
tree_tab->addTab(simple_tree, tr("Simple"));
|
||||||
connect(tree->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &MainWindow::SelectionChanged);
|
connect(simple_tree->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &MainWindow::SelectionChanged);
|
||||||
|
|
||||||
|
auto lowlevel_tree = new QTreeView();
|
||||||
|
lowlevel_tree->setModel(&chunk_model_);
|
||||||
|
tree_tab->addTab(lowlevel_tree, tr("Advanced"));
|
||||||
|
connect(lowlevel_tree->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &MainWindow::SelectionChanged);
|
||||||
|
|
||||||
config_stack_ = new QStackedWidget();
|
config_stack_ = new QStackedWidget();
|
||||||
splitter->addWidget(config_stack_);
|
splitter->addWidget(config_stack_);
|
||||||
|
@ -51,10 +57,12 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
|
||||||
void MainWindow::OpenFilename(const QString &s)
|
void MainWindow::OpenFilename(const QString &s)
|
||||||
{
|
{
|
||||||
model_.SetChunk(nullptr);
|
object_model_.SetChunk(nullptr);
|
||||||
|
chunk_model_.SetChunk(nullptr);
|
||||||
SetPanel(panel_blank_, nullptr);
|
SetPanel(panel_blank_, nullptr);
|
||||||
chunk_.Read(s.toStdString());
|
chunk_.Read(s.toStdString());
|
||||||
model_.SetChunk(&chunk_);
|
object_model_.SetChunk(&chunk_);
|
||||||
|
chunk_model_.SetChunk(&chunk_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::InitializeMenuBar()
|
void MainWindow::InitializeMenuBar()
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <QStackedWidget>
|
#include <QStackedWidget>
|
||||||
|
|
||||||
#include "chunkmodel.h"
|
#include "chunkmodel.h"
|
||||||
|
#include "objectmodel.h"
|
||||||
#include "panels/mxch.h"
|
#include "panels/mxch.h"
|
||||||
#include "panels/mxhd.h"
|
#include "panels/mxhd.h"
|
||||||
#include "panels/mxob.h"
|
#include "panels/mxob.h"
|
||||||
|
@ -30,7 +31,8 @@ private:
|
||||||
|
|
||||||
void SetPanel(Panel *panel, si::Chunk *chunk);
|
void SetPanel(Panel *panel, si::Chunk *chunk);
|
||||||
|
|
||||||
ChunkModel model_;
|
ObjectModel object_model_;
|
||||||
|
ChunkModel chunk_model_;
|
||||||
si::Chunk chunk_;
|
si::Chunk chunk_;
|
||||||
|
|
||||||
QStackedWidget *config_stack_;
|
QStackedWidget *config_stack_;
|
||||||
|
|
119
app/objectmodel.cpp
Normal file
119
app/objectmodel.cpp
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
#include "objectmodel.h"
|
||||||
|
|
||||||
|
#define super AbstractSIItemModel
|
||||||
|
|
||||||
|
using namespace si;
|
||||||
|
|
||||||
|
ObjectModel::ObjectModel(QObject *parent) :
|
||||||
|
super{parent}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int ObjectModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return kColCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex ObjectModel::index(int row, int column, const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return createIndex(row, column, GetItem(row));
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex ObjectModel::parent(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ObjectModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
if (parent.isValid()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
Chunk *mxof = GetMxOf();
|
||||||
|
if (!mxof) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mxof->data("Offsets").size() / sizeof(u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ObjectModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
u32 offset;
|
||||||
|
Chunk *c = GetItem(index.row(), &offset);
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
|
||||||
|
switch (index.column()) {
|
||||||
|
case kColIndex:
|
||||||
|
return index.row();
|
||||||
|
case kColOffset:
|
||||||
|
return QStringLiteral("0x%1").arg(QString::number(offset, 16).toUpper());
|
||||||
|
case kColName:
|
||||||
|
if (c) {
|
||||||
|
Chunk *mxob = c->FindChildWithType(Chunk::TYPE_MxOb);
|
||||||
|
if (mxob) {
|
||||||
|
return QString(mxob->data("Name"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ObjectModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||||
|
switch (section) {
|
||||||
|
case kColIndex:
|
||||||
|
return tr("Index");
|
||||||
|
case kColOffset:
|
||||||
|
return tr("Offset");
|
||||||
|
case kColName:
|
||||||
|
return tr("Name");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super::headerData(section, orientation, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
Chunk *ObjectModel::GetMxOf() const
|
||||||
|
{
|
||||||
|
Chunk *root = this->root();
|
||||||
|
if (!root) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return root->FindChildWithType(Chunk::TYPE_MxOf);
|
||||||
|
}
|
||||||
|
|
||||||
|
Chunk *ObjectModel::GetItem(size_t index, si::u32 *offset_out) const
|
||||||
|
{
|
||||||
|
Chunk *mxof = GetMxOf();
|
||||||
|
if (!mxof) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Data &offset_bytes = mxof->data("Offsets");
|
||||||
|
if (index >= offset_bytes.size()/sizeof(u32)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u32 *offsets = reinterpret_cast<const u32*>(offset_bytes.data());
|
||||||
|
u32 offset = offsets[index];
|
||||||
|
if (offset_out) {
|
||||||
|
*offset_out = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset == 0) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return root()->FindChildWithOffset(offset);
|
||||||
|
}
|
||||||
|
}
|
33
app/objectmodel.h
Normal file
33
app/objectmodel.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef OBJECTMODEL_H
|
||||||
|
#define OBJECTMODEL_H
|
||||||
|
|
||||||
|
#include "abstractsiitemmodel.h"
|
||||||
|
|
||||||
|
class ObjectModel : public AbstractSIItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum Columns {
|
||||||
|
kColIndex,
|
||||||
|
kColOffset,
|
||||||
|
kColName,
|
||||||
|
|
||||||
|
kColCount
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit ObjectModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
virtual QModelIndex parent(const QModelIndex &index) const override;
|
||||||
|
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
si::Chunk *GetMxOf() const;
|
||||||
|
si::Chunk *GetItem(size_t index, si::u32 *offset_out = NULL) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // OBJECTMODEL_H
|
|
@ -92,7 +92,7 @@ void MxChPanel::OnOpeningData(Chunk *chunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
const Data &data = chunk->data("Data");
|
const Data &data = chunk->data("Data");
|
||||||
QByteArray ba(data.data(), data.size());
|
QByteArray ba(data.data(), int(data.size()));
|
||||||
data_edit_->setPlainText(ba.toHex());
|
data_edit_->setPlainText(ba.toHex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue