Initial commit of current work on Prime World Editor

This commit is contained in:
parax0
2015-07-26 17:39:49 -04:00
commit 66e8c2ebcb
305 changed files with 33469 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
#include "CLayerEditor.h"
#include "ui_CLayerEditor.h"
CLayerEditor::CLayerEditor(QWidget *parent) :
QDialog(parent),
ui(new Ui::CLayerEditor)
{
ui->setupUi(this);
mpArea = nullptr;
mpModel = new CLayerModel(this);
ui->LayerSelectComboBox->setModel(mpModel);
connect(ui->LayerSelectComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(SetCurrentIndex(int)));
connect(ui->NameLineEdit, SIGNAL(textEdited(QString)), this, SLOT(EditLayerName(QString)));
connect(ui->ActiveCheckBox, SIGNAL(toggled(bool)), this, SLOT(EditLayerActive(bool)));
}
CLayerEditor::~CLayerEditor()
{
delete ui;
}
void CLayerEditor::SetArea(CGameArea *pArea)
{
mpArea = pArea;
mpModel->SetArea(pArea);
SetCurrentIndex(0);
}
// ************ SLOTS ************
void CLayerEditor::SetCurrentIndex(int index)
{
ui->LayerSelectComboBox->blockSignals(true);
ui->LayerSelectComboBox->setCurrentIndex(index);
ui->LayerSelectComboBox->blockSignals(false);
QModelIndex ModelIndex = mpModel->index(index);
mpCurrentLayer = mpModel->Layer(ModelIndex);
ui->NameLineEdit->setText(QString::fromStdString(mpCurrentLayer->Name()));
ui->ActiveCheckBox->setChecked(mpCurrentLayer->IsActive());
}
void CLayerEditor::EditLayerName(const QString &name)
{
mpCurrentLayer->SetName(name.toStdString());
ui->LayerSelectComboBox->update();
}
void CLayerEditor::EditLayerActive(bool active)
{
mpCurrentLayer->SetActive(active);
}

View File

@@ -0,0 +1,32 @@
#ifndef CLAYEREDITOR_H
#define CLAYEREDITOR_H
#include <QDialog>
#include "CLayerModel.h"
namespace Ui {
class CLayerEditor;
}
class CLayerEditor : public QDialog
{
Q_OBJECT
CGameArea *mpArea;
CLayerModel *mpModel;
CScriptLayer *mpCurrentLayer;
public:
explicit CLayerEditor(QWidget *parent = 0);
~CLayerEditor();
void SetArea(CGameArea *pArea);
public slots:
void SetCurrentIndex(int index);
void EditLayerName(const QString& name);
void EditLayerActive(bool active);
private:
Ui::CLayerEditor *ui;
};
#endif // CLAYEREDITOR_H

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CLayerEditor</class>
<widget class="QDialog" name="CLayerEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>68</height>
</rect>
</property>
<property name="windowTitle">
<string>Edit Layers</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QComboBox" name="LayerSelectComboBox"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="NameLabel">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="NameLineEdit"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="ActiveLabel">
<property name="text">
<string>Active:</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ActiveCheckBox">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,46 @@
#include "CLayerModel.h"
CLayerModel::CLayerModel(QObject *pParent) : QAbstractListModel(pParent)
{
mpArea = nullptr;
mHasGenerateLayer = false;
}
CLayerModel::~CLayerModel()
{
}
int CLayerModel::rowCount(const QModelIndex &parent) const
{
if (!mpArea) return 0;
if (mHasGenerateLayer) return mpArea->GetScriptLayerCount() + 1;
else return mpArea->GetScriptLayerCount();
}
QVariant CLayerModel::data(const QModelIndex &index, int role) const
{
if (mpArea && (role == Qt::DisplayRole) && (index.row() < rowCount(QModelIndex())))
return QString::fromStdString(Layer(index)->Name());
return QVariant::Invalid;
}
void CLayerModel::SetArea(CGameArea *pArea)
{
mpArea = pArea;
mHasGenerateLayer = (pArea->GetGeneratorLayer() != nullptr);
emit layoutChanged();
}
CScriptLayer* CLayerModel::Layer(const QModelIndex& index) const
{
if (!mpArea) return nullptr;
u32 NumLayers = mpArea->GetScriptLayerCount();
if (index.row() < NumLayers)
return mpArea->GetScriptLayer(index.row());
if (mHasGenerateLayer && (index.row() == NumLayers))
return mpArea->GetGeneratorLayer();
return nullptr;
}

View File

@@ -0,0 +1,21 @@
#ifndef CLAYERMODEL_H
#define CLAYERMODEL_H
#include <QAbstractListModel>
#include <Resource/CGameArea.h>
class CLayerModel : public QAbstractListModel
{
CGameArea *mpArea;
bool mHasGenerateLayer;
public:
explicit CLayerModel(QObject *pParent = 0);
~CLayerModel();
int rowCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
void SetArea(CGameArea *pArea);
CScriptLayer* Layer(const QModelIndex& index) const;
};
#endif // CLAYERMODEL_H

View File

@@ -0,0 +1,119 @@
#include "CLayersInstanceModel.h"
/* The tree has 3 levels:
* 1. Node Type (Script Object, Light) - represented with ID of 0
* 2. Layer - represented with flags
* 3. Instance - represented with pointer to instance (0x1 bit is guaranteed to be clear)
*
* Flags for Layer tree items:
* AAAAAAAAAAAAAAAAAAAAAAAAAAABBBBC
* A: Row index
* B: Node type row index
* C: Item type (ObjType, Instance)
*/
#define LAYERS_ROW_INDEX_MASK 0xFFFFFFE0
#define LAYERS_NODE_TYPE_MASK 0x0000001E
#define LAYERS_ITEM_TYPE_MASK 0x00000001
#define LAYERS_ROW_INDEX_SHIFT 5
#define LAYERS_NODE_TYPE_SHIFT 1
#define LAYERS_ITEM_TYPE_SHIFT 0
CLayersInstanceModel::CLayersInstanceModel(QObject *pParent) : QAbstractItemModel(pParent)
{
}
CLayersInstanceModel::~CLayersInstanceModel()
{
}
QVariant CLayersInstanceModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole))
{
switch (section)
{
case 0: return "Name";
case 1: return "Type";
case 2: return "Show";
}
}
return QVariant::Invalid;
}
QModelIndex CLayersInstanceModel::index(int row, int column, const QModelIndex &parent) const
{
return QModelIndex();
}
QModelIndex CLayersInstanceModel::parent(const QModelIndex &child) const
{
return QModelIndex();
}
int CLayersInstanceModel::rowCount(const QModelIndex &parent) const
{
return 0;
}
int CLayersInstanceModel::columnCount(const QModelIndex &parent) const
{
return 3;
}
QVariant CLayersInstanceModel::data(const QModelIndex &index, int role) const
{
return QVariant::Invalid;
}
void CLayersInstanceModel::SetEditor(CWorldEditor *pEditor)
{
mpEditor = pEditor;
mpScene = (pEditor ? pEditor->Scene() : nullptr);
mpArea = (pEditor ? pEditor->ActiveArea() : nullptr);
}
void CLayersInstanceModel::NodeCreated(CSceneNode *pNode)
{
emit layoutChanged();
}
void CLayersInstanceModel::NodeDeleted(CSceneNode *pNode)
{
emit layoutChanged();
}
CScriptLayer* CLayersInstanceModel::IndexLayer(const QModelIndex& index) const
{
return nullptr;
}
CScriptObject* CLayersInstanceModel::IndexObject(const QModelIndex& index) const
{
return nullptr;
}
// ************ STATIC ************
CLayersInstanceModel::EIndexType CLayersInstanceModel::IndexType(const QModelIndex& index)
{
if (!index.isValid()) return eRootIndex;
else if (index.internalId() == 0) return eNodeTypeIndex;
else if (((index.internalId() & LAYERS_ITEM_TYPE_MASK) >> LAYERS_ITEM_TYPE_SHIFT) == 1) return eLayerIndex;
else return eInstanceIndex;
}
CLayersInstanceModel::ENodeType CLayersInstanceModel::IndexNodeType(const QModelIndex& index)
{
EIndexType type = IndexType(index);
switch (type)
{
case eRootIndex: return eInvalidType;
case eNodeTypeIndex: return (ENodeType) index.row();
case eLayerIndex: return (ENodeType) index.parent().row();
case eInstanceIndex: return (ENodeType) index.parent().parent().row();
default: return eInvalidType;
}
}

View File

@@ -0,0 +1,49 @@
#ifndef CLAYERSINSTANCEMODEL_H
#define CLAYERSINSTANCEMODEL_H
#include <QAbstractItemModel>
#include <Resource/script/CScriptLayer.h>
#include "../CWorldEditor.h"
// Only supports script layers atm - maybe light layers later...?
class CLayersInstanceModel : public QAbstractItemModel
{
Q_OBJECT
public:
enum EIndexType {
eRootIndex, eNodeTypeIndex, eLayerIndex, eInstanceIndex
};
enum ENodeType {
eScriptType = 0x0,
eLightType = 0x1,
eInvalidType = 0xFF
};
private:
CWorldEditor *mpEditor;
CSceneManager *mpScene;
CGameArea *mpArea;
public:
explicit CLayersInstanceModel(QObject *pParent = 0);
~CLayersInstanceModel();
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QModelIndex index(int row, int column, const QModelIndex &parent) const;
QModelIndex parent(const QModelIndex &child) const;
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
void SetEditor(CWorldEditor *pEditor);
void NodeCreated(CSceneNode *pNode);
void NodeDeleted(CSceneNode *pNode);
CScriptLayer* IndexLayer(const QModelIndex& index) const;
CScriptObject* IndexObject(const QModelIndex& index) const;
// Static
static EIndexType IndexType(const QModelIndex& index);
static ENodeType IndexNodeType(const QModelIndex& index);
};
#endif // CLAYERSINSTANCEMODEL_H

View File

@@ -0,0 +1,101 @@
#include "CLinkModel.h"
#include <Resource/CGameArea.h>
#include <Resource/script/CMasterTemplate.h>
CLinkModel::CLinkModel(QObject *pParent) : QAbstractTableModel(pParent)
{
mpObject = nullptr;
mType = eOutgoing;
}
void CLinkModel::SetObject(CScriptObject *pObj)
{
mpObject = pObj;
emit layoutChanged();
}
void CLinkModel::SetConnectionType(EConnectionType type)
{
mType = type;
emit layoutChanged();
}
int CLinkModel::rowCount(const QModelIndex&) const
{
if (mpObject)
{
if (mType == eIncoming)
return mpObject->NumInLinks();
else
return mpObject->NumOutLinks();
}
else return 0;
}
int CLinkModel::columnCount(const QModelIndex &parent) const
{
return 3;
}
QVariant CLinkModel::data(const QModelIndex &index, int role) const
{
if (!mpObject) return QVariant::Invalid;
else if ((role == Qt::DisplayRole) || (role == Qt::ToolTipRole))
{
SLink link = (mType == eIncoming ? mpObject->InLink(index.row()) : mpObject->OutLink(index.row()));
switch (index.column())
{
case 0: // Column 0 - Target Object
{
CScriptObject *pTargetObj = mpObject->Area()->GetInstanceByID(link.ObjectID);
if (role == Qt::DisplayRole) {
if (pTargetObj) return QString::fromStdString(pTargetObj->GetInstanceName());
else return QString("0x") + QString::number(link.ObjectID, 16);
}
else {
QString ObjType = QString("[%1] ").arg(QString::fromStdString(pTargetObj->Template()->TemplateName()));
if (pTargetObj) return ObjType + QString::fromStdString(pTargetObj->GetInstanceName());
else return ObjType + QString("0x") + QString::number(link.ObjectID, 16);
}
}
case 1: // Column 1 - State
{
std::string StateName = mpObject->MasterTemplate()->StateByID(link.State);
return QString::fromStdString(StateName);
}
case 2: // Column 2 - Message
{
std::string MessageName = mpObject->MasterTemplate()->MessageByID(link.Message);
return QString::fromStdString(MessageName);
}
default:
return QVariant::Invalid;
}
}
else return QVariant::Invalid;
}
QVariant CLinkModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole))
{
switch (section)
{
case 0: return (mType == eIncoming ? "Sender" : "Target");
case 1: return "State";
case 2: return "Message";
default: return QVariant::Invalid;
}
}
else return QVariant::Invalid;
}

View File

@@ -0,0 +1,30 @@
#ifndef CCONNECTIONMODEL_H
#define CCONNECTIONMODEL_H
#include <QAbstractTableModel>
#include <Resource/script/CScriptObject.h>
class CLinkModel : public QAbstractTableModel
{
Q_OBJECT
public:
enum EConnectionType {
eIncoming, eOutgoing
};
private:
CScriptObject *mpObject;
EConnectionType mType;
public:
explicit CLinkModel(QObject *pParent = 0);
void SetObject(CScriptObject *pObj);
void SetConnectionType(EConnectionType type);
int rowCount(const QModelIndex& parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
};
#endif // CCONNECTIONMODEL_H

View File

@@ -0,0 +1,451 @@
#include "CTypesInstanceModel.h"
#include <Scene/CScriptNode.h>
#include <QApplication>
#include <QIcon>
/* The tree has 3 levels:
* 1. Node Type (Script Object, Light, World Mesh, etc) - represented with ID of 0
* 2. Object Type (Actor, Platform, SpawnPoint, etc) - represented with flags
* 3. Instance - represented with pointer to instance (0x1 bit is guaranteed to be clear)
*
* Flags for Object Type tree items
* AAAAAAAAAAAAAAAAAAAAAAAAAAABBBBC
* A: Row index
* B: Node type row index
* C: Item type (ObjType, Instance)
*/
#define TYPES_ROW_INDEX_MASK 0xFFFFFFE0
#define TYPES_NODE_TYPE_MASK 0x0000001E
#define TYPES_ITEM_TYPE_MASK 0x00000001
#define TYPES_ROW_INDEX_SHIFT 5
#define TYPES_NODE_TYPE_SHIFT 1
#define TYPES_ITEM_TYPE_SHIFT 0
bool SortTemplatesAlphabetical(CScriptTemplate *pA, CScriptTemplate *pB)
{
return (pA->TemplateName() < pB->TemplateName());
}
CTypesInstanceModel::CTypesInstanceModel(QObject *pParent) : QAbstractItemModel(pParent)
{
mpEditor = nullptr;
mpScene = nullptr;
mpArea = nullptr;
mpCurrentMaster = nullptr;
mModelType = eLayers;
mBaseItems << "Script";
}
CTypesInstanceModel::~CTypesInstanceModel()
{
}
QVariant CTypesInstanceModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole))
{
switch (section)
{
case 0: return "Name";
case 1: return (mModelType == eLayers ? "Type" : "Layer");
case 2: return "Show";
}
}
return QVariant::Invalid;
}
QModelIndex CTypesInstanceModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
EIndexType type = IndexType(parent);
// Node type index
if (type == eRootIndex)
{
if (row < mBaseItems.count())
return createIndex(row, column, quint32(0));
else
return QModelIndex();
}
// Object type index
else if (type == eNodeTypeIndex)
return createIndex(row, column, ((row << TYPES_ROW_INDEX_SHIFT) | (parent.row() << TYPES_NODE_TYPE_SHIFT) | 1));
// Instance index
else if (type == eObjectTypeIndex)
{
u32 RootRow = parent.parent().row();
// Object
if (RootRow == 0)
{
if (mModelType == eLayers)
{
CScriptLayer *pLayer = mpArea->GetScriptLayer(parent.row());
if (row >= pLayer->GetNumObjects())
return QModelIndex();
else
return createIndex(row, column, (*pLayer)[row]);
}
else if (mModelType == eTypes)
{
const std::list<CScriptObject*>& list = mTemplateList[parent.row()]->ObjectList();
if (row >= list.size())
return QModelIndex();
else
{
auto it = std::next(list.begin(), row);
return createIndex(row, column, *it);
}
}
}
// todo: implement getters for other types
}
return QModelIndex();
}
QModelIndex CTypesInstanceModel::parent(const QModelIndex &child) const
{
EIndexType type = IndexType(child);
// Root parent
if (type == eNodeTypeIndex)
return QModelIndex();
// Node type parent
if (type == eObjectTypeIndex)
{
u32 NodeTypeRow = (child.internalId() & TYPES_NODE_TYPE_MASK) >> TYPES_NODE_TYPE_SHIFT;
return createIndex(NodeTypeRow, 0, quint32(0));
}
// Object type parent
else if (type == eInstanceIndex)
{
CScriptObject *pObj = static_cast<CScriptObject*> (child.internalPointer());
if (mModelType == eLayers)
{
CScriptLayer *pLayer = pObj->Layer();
for (u32 iLyr = 0; iLyr < mpArea->GetScriptLayerCount(); iLyr++)
{
if (mpArea->GetScriptLayer(iLyr) == pLayer)
return createIndex(iLyr, 0, (iLyr << TYPES_ROW_INDEX_SHIFT) | 1);
}
}
else if (mModelType == eTypes)
{
CScriptTemplate *pTemp = pObj->Template();
for (u32 iTemp = 0; iTemp < mTemplateList.size(); iTemp++)
{
if (mTemplateList[iTemp] == pTemp)
return createIndex(iTemp, 0, (iTemp << TYPES_ROW_INDEX_SHIFT) | 1);
}
}
}
return QModelIndex();
}
int CTypesInstanceModel::rowCount(const QModelIndex &parent) const
{
EIndexType type = IndexType(parent);
// Node types
if (type == eRootIndex)
return mBaseItems.count();
// Object types
else if (type == eNodeTypeIndex)
{
// Script Objects
if (parent.row() == 0) {
if (mModelType == eLayers)
return (mpArea ? mpArea->GetScriptLayerCount() : 0);
else
return mTemplateList.size();
}
else
return 0;
}
// Instances
else if (type == eObjectTypeIndex)
{
u32 RowIndex = ((parent.internalId() & TYPES_ROW_INDEX_MASK) >> TYPES_ROW_INDEX_SHIFT);
if (mModelType == eLayers)
return (mpArea ? mpArea->GetScriptLayer(RowIndex)->GetNumObjects() : 0);
else
return mTemplateList[RowIndex]->NumObjects();
}
else
return 0;
}
int CTypesInstanceModel::columnCount(const QModelIndex &parent) const
{
return 3;
}
QVariant CTypesInstanceModel::data(const QModelIndex &index, int role) const
{
EIndexType type = IndexType(index);
// Name/Layer
if ((role == Qt::DisplayRole) || (role == Qt::ToolTipRole))
{
// Node types
if (type == eNodeTypeIndex)
{
if (index.column() == 0)
return mBaseItems[index.row()];
else
return QVariant::Invalid;
}
// Object types
else if (type == eObjectTypeIndex)
{
if (index.column() == 0) {
if (mModelType == eLayers)
return QString::fromStdString(mpEditor->ActiveArea()->GetScriptLayer(index.row())->Name());
else
return QString::fromStdString(mTemplateList[index.row()]->TemplateName());
}
// todo: show/hide button in column 2
else
return QVariant::Invalid;
}
// Instances
else if (type == eInstanceIndex)
{
// todo: show/hide button
CScriptObject *pObj = static_cast<CScriptObject*>(index.internalPointer());
if (index.column() == 0)
return QString::fromStdString(pObj->GetInstanceName());
else if (index.column() == 1)
{
if (mModelType == eLayers)
return QString::fromStdString(pObj->Template()->TemplateName());
else if (mModelType == eTypes)
return QString::fromStdString(pObj->Layer()->Name());
}
else
return QVariant::Invalid;
}
}
// Show/Hide Buttons
else if ((role == Qt::DecorationRole) && (index.column() == 2))
{
if (!mpScene) return QVariant::Invalid;
static QIcon Visible(":/icons/EditorAssets/Show.png");
static QIcon Invisible(":/icons/EditorAssets/Hide.png");
// Show/Hide Node Types
if (type == eNodeTypeIndex)
{
// Commented out pending a proper implementation of turning node types on/off from the instance view
/*bool IsVisible;
switch (index.row())
{
case 0: IsVisible = mpScene->AreScriptObjectsEnabled();
case 1: IsVisible = mpScene->AreLightsEnabled();
default: IsVisible = false;
}
if (IsVisible) return Visible;
else return Invisible;*/
}
// Show/Hide Object Types
else if (type == eObjectTypeIndex)
{
if (mModelType == eLayers)
{
CScriptLayer *pLayer = IndexLayer(index);
if (pLayer->IsVisible()) return Visible;
else return Invisible;
}
else if (mModelType == eTypes)
{
CScriptTemplate *pTemp = IndexTemplate(index);
if (pTemp->IsVisible()) return Visible;
else return Invisible;
}
}
// Show/Hide Instance
else if (type == eInstanceIndex)
{
CScriptObject *pObj = IndexObject(index);
CScriptNode *pNode = mpScene->NodeForObject(pObj);
if (pNode->MarkedVisible()) return Visible;
else return Invisible;
}
}
return QVariant::Invalid;
}
void CTypesInstanceModel::SetEditor(CWorldEditor *pEditor)
{
mpEditor = pEditor;
mpScene = (pEditor ? pEditor->Scene() : nullptr);
}
void CTypesInstanceModel::SetMaster(CMasterTemplate *pMaster)
{
mpCurrentMaster = pMaster;
GenerateList();
}
void CTypesInstanceModel::SetArea(CGameArea *pArea)
{
beginResetModel();
mpArea = pArea;
endResetModel();
}
void CTypesInstanceModel::SetModelType(EInstanceModelType type)
{
mModelType = type;
}
void CTypesInstanceModel::NodeCreated(CSceneNode *pNode)
{
if (mModelType == eTypes)
{
if (pNode->NodeType() == eScriptNode)
{
CScriptNode *pScript = static_cast<CScriptNode*>(pNode);
CScriptObject *pObj = pScript->Object();
pObj->Template()->SortObjects();
if (pObj->Template()->NumObjects() == 1)
{
mTemplateList << pObj->Template();
qSort(mTemplateList.begin(), mTemplateList.end(), SortTemplatesAlphabetical);
emit layoutChanged();
}
}
}
}
void CTypesInstanceModel::NodeDeleted(CSceneNode *pNode)
{
if (mModelType = eTypes)
{
if (pNode->NodeType() == eScriptNode)
{
CScriptNode *pScript = static_cast<CScriptNode*>(pNode);
CScriptObject *pObj = pScript->Object();
if (pObj->Template()->NumObjects() == 0)
{
for (auto it = mTemplateList.begin(); it != mTemplateList.end(); it++)
{
if (*it == pObj->Template())
{
mTemplateList.erase(it);
break;
}
}
emit layoutChanged();
}
}
}
}
CScriptLayer* CTypesInstanceModel::IndexLayer(const QModelIndex& index) const
{
if ((mModelType != eLayers) || (IndexNodeType(index) != eScriptType) || (IndexType(index) != eObjectTypeIndex))
return nullptr;
u32 RowIndex = ((index.internalId() & TYPES_ROW_INDEX_MASK) >> TYPES_ROW_INDEX_SHIFT);
return mpArea->GetScriptLayer(RowIndex);
}
CScriptTemplate* CTypesInstanceModel::IndexTemplate(const QModelIndex& index) const
{
if ((mModelType != eTypes) || (IndexNodeType(index) != eScriptType) || (IndexType(index) != eObjectTypeIndex))
return nullptr;
u32 RowIndex = ((index.internalId() & TYPES_ROW_INDEX_MASK) >> TYPES_ROW_INDEX_SHIFT);
return mTemplateList[RowIndex];
}
CScriptObject* CTypesInstanceModel::IndexObject(const QModelIndex& index) const
{
if ((IndexNodeType(index) != eScriptType) || (IndexType(index) != eInstanceIndex))
return nullptr;
return static_cast<CScriptObject*>(index.internalPointer());
}
// ************ STATIC ************
CTypesInstanceModel::EIndexType CTypesInstanceModel::IndexType(const QModelIndex& index)
{
if (!index.isValid()) return eRootIndex;
else if (index.internalId() == 0) return eNodeTypeIndex;
else if (((index.internalId() & TYPES_ITEM_TYPE_MASK) >> TYPES_ITEM_TYPE_SHIFT) == 1) return eObjectTypeIndex;
else return eInstanceIndex;
}
CTypesInstanceModel::ENodeType CTypesInstanceModel::IndexNodeType(const QModelIndex& index)
{
EIndexType type = IndexType(index);
switch (type)
{
case eRootIndex: return eInvalidType;
case eNodeTypeIndex: return (ENodeType) index.row();
case eObjectTypeIndex: return (ENodeType) index.parent().row();
case eInstanceIndex: return (ENodeType) index.parent().parent().row();
default: return eInvalidType;
}
}
// ************ PRIVATE ************
void CTypesInstanceModel::GenerateList()
{
beginResetModel();
mTemplateList.clear();
if (mpCurrentMaster)
{
u32 NumTemplates = mpCurrentMaster->NumScriptTemplates();
for (u32 iTemp = 0; iTemp < NumTemplates; iTemp++)
{
CScriptTemplate *pTemp = mpCurrentMaster->TemplateByIndex(iTemp);
if (pTemp->NumObjects() > 0)
mTemplateList << pTemp;
}
qSort(mTemplateList.begin(), mTemplateList.end(), SortTemplatesAlphabetical);
}
endResetModel();
}

View File

@@ -0,0 +1,67 @@
#ifndef CTYPESINSTANCEMODEL_H
#define CTYPESINSTANCEMODEL_H
#include <QAbstractItemModel>
#include <QList>
#include <Resource/script/CMasterTemplate.h>
#include <Resource/script/CScriptTemplate.h>
#include <Scene/CSceneNode.h>
#include "../CWorldEditor.h"
class CTypesInstanceModel : public QAbstractItemModel
{
Q_OBJECT
public:
enum EIndexType {
eRootIndex, eNodeTypeIndex, eObjectTypeIndex, eInstanceIndex
};
enum ENodeType {
eScriptType = 0x0,
eLightType = 0x1,
eInvalidType = 0xFF
};
enum EInstanceModelType {
eLayers, eTypes
};
private:
CWorldEditor *mpEditor;
CSceneManager *mpScene;
CGameArea *mpArea;
CMasterTemplate *mpCurrentMaster;
EInstanceModelType mModelType;
QList<CScriptTemplate*> mTemplateList;
QStringList mBaseItems;
public:
explicit CTypesInstanceModel(QObject *pParent = 0);
~CTypesInstanceModel();
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &child) const;
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
void SetEditor(CWorldEditor *pEditor);
void SetMaster(CMasterTemplate *pMaster);
void SetArea(CGameArea *pArea);
void SetModelType(EInstanceModelType type);
void NodeCreated(CSceneNode *pNode);
void NodeDeleted(CSceneNode *pNode);
CScriptLayer* IndexLayer(const QModelIndex& index) const;
CScriptTemplate* IndexTemplate(const QModelIndex& index) const;
CScriptObject* IndexObject(const QModelIndex& index) const;
// Static
static EIndexType IndexType(const QModelIndex& index);
static ENodeType IndexNodeType(const QModelIndex& index);
private:
void GenerateList();
};
#endif // CTYPESINSTANCEMODEL_H

View File

@@ -0,0 +1,14 @@
#include "WCreateTab.h"
#include "ui_WCreateTab.h"
WCreateTab::WCreateTab(QWidget *parent) :
QWidget(parent),
ui(new Ui::WCreateTab)
{
ui->setupUi(this);
}
WCreateTab::~WCreateTab()
{
delete ui;
}

View File

@@ -0,0 +1,22 @@
#ifndef WCREATETAB_H
#define WCREATETAB_H
#include <QWidget>
namespace Ui {
class WCreateTab;
}
class WCreateTab : public QWidget
{
Q_OBJECT
public:
explicit WCreateTab(QWidget *parent = 0);
~WCreateTab();
private:
Ui::WCreateTab *ui;
};
#endif // WCREATETAB_H

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WCreateTab</class>
<widget class="QWidget" name="WCreateTab">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>216</width>
<height>421</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,163 @@
#include "WInstancesTab.h"
#include "ui_WInstancesTab.h"
#include "../CWorldEditor.h"
#include <Core/CSceneManager.h>
WInstancesTab::WInstancesTab(QWidget *parent) :
QWidget(parent),
ui(new Ui::WInstancesTab)
{
ui->setupUi(this);
mpEditor = nullptr;
mpLayersModel = new CTypesInstanceModel(this);
mpLayersModel->SetModelType(CTypesInstanceModel::eLayers);
mpTypesModel = new CTypesInstanceModel(this);
mpTypesModel->SetModelType(CTypesInstanceModel::eTypes);
ui->LayersTreeView->setModel(mpLayersModel);
ui->LayersTreeView->header()->setSectionResizeMode(2, QHeaderView::Fixed);
ui->LayersTreeView->resizeColumnToContents(2);
ui->TypesTreeView->setModel(mpTypesModel);
ui->TypesTreeView->header()->setSectionResizeMode(2, QHeaderView::Fixed);
ui->TypesTreeView->resizeColumnToContents(2);
// Create context menu
mpTreeContextMenu = new QMenu(this);
mpHideInstance = new QAction("Hide instance", this);
mpHideType = new QAction("", this);
mpHideAllExceptType = new QAction("", this);
mpTreeContextMenu->addAction(mpHideInstance);
mpTreeContextMenu->addAction(mpHideType);
mpTreeContextMenu->addAction(mpHideAllExceptType);
// Configure signals/slots
connect(ui->LayersTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(OnTreeClick(QModelIndex)));
connect(ui->LayersTreeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnTreeDoubleClick(QModelIndex)));
connect(ui->TypesTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(OnTreeClick(QModelIndex)));
connect(ui->TypesTreeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnTreeDoubleClick(QModelIndex)));
connect(mpHideInstance, SIGNAL(triggered()), this, SLOT(OnHideInstanceAction()));
connect(mpHideType, SIGNAL(triggered()), this, SLOT(OnHideTypeAction()));
connect(mpHideAllExceptType, SIGNAL(triggered()), this, SLOT(OnHideAllExceptTypeAction()));
}
WInstancesTab::~WInstancesTab()
{
delete ui;
}
void WInstancesTab::SetEditor(CWorldEditor *pEditor, CSceneManager *pScene)
{
mpEditor = pEditor;
mpScene = pScene;
mpTypesModel->SetEditor(pEditor);
mpLayersModel->SetEditor(pEditor);
}
void WInstancesTab::SetMaster(CMasterTemplate *pMaster)
{
mpTypesModel->SetMaster(pMaster);
ExpandTopLevelItems();
}
void WInstancesTab::SetArea(CGameArea *pArea)
{
mpLayersModel->SetArea(pArea);
ExpandTopLevelItems();
}
// ************ PRIVATE SLOTS ************
void WInstancesTab::OnTreeClick(QModelIndex Index)
{
// Single click is used to process show/hide events
if (Index.column() == 2)
{
// Show/Hide Instance
if (mpTypesModel->IndexType(Index) == CTypesInstanceModel::eInstanceIndex)
{
CScriptObject *pObj = mpTypesModel->IndexObject(Index);
CScriptNode *pNode = mpScene->NodeForObject(pObj);
pNode->SetVisible(!pNode->IsVisible());
}
// Show/Hide Object Type
else if (mpTypesModel->IndexType(Index) == CTypesInstanceModel::eObjectTypeIndex)
{
if (sender() == ui->LayersTreeView)
{
CScriptLayer *pLayer = mpLayersModel->IndexLayer(Index);
pLayer->SetVisible(!pLayer->IsVisible());
}
else if (sender() == ui->TypesTreeView)
{
CScriptTemplate *pTmp = mpTypesModel->IndexTemplate(Index);
pTmp->SetVisible(!pTmp->IsVisible());
}
}
// Show/Hide Node Type
else if (mpTypesModel->IndexType(Index) == CTypesInstanceModel::eNodeTypeIndex)
{
CTypesInstanceModel::ENodeType type = mpTypesModel->IndexNodeType(Index);
if (type == CTypesInstanceModel::eScriptType)
mpScene->SetObjects(!mpScene->AreScriptObjectsEnabled());
}
if (sender() == ui->LayersTreeView)
ui->LayersTreeView->update(Index);
else if (sender() == ui->TypesTreeView)
ui->TypesTreeView->update(Index);
}
}
void WInstancesTab::OnTreeDoubleClick(QModelIndex Index)
{
CTypesInstanceModel::EIndexType IndexType = mpTypesModel->IndexType(Index);
if ((mpEditor) && (IndexType == CTypesInstanceModel::eInstanceIndex))
{
CTypesInstanceModel::ENodeType NodeType = mpTypesModel->IndexNodeType(Index);
CSceneNode *pSelectedNode = nullptr;
if (NodeType == CTypesInstanceModel::eScriptType)
pSelectedNode = mpScene->NodeForObject( static_cast<CScriptObject*>(Index.internalPointer()) );
if (pSelectedNode)
{
mpEditor->ClearSelection();
mpEditor->SelectNode(pSelectedNode);
}
}
}
void WInstancesTab::OnHideInstanceAction()
{
}
void WInstancesTab::OnHideTypeAction()
{
}
void WInstancesTab::OnHideAllExceptTypeAction()
{
}
// ************ PRIVATE ************
void WInstancesTab::ExpandTopLevelItems()
{
for (u32 iModel = 0; iModel < 2; iModel++)
{
QAbstractItemModel *pModel = (iModel == 0 ? mpLayersModel : mpTypesModel);
QTreeView *pView = (iModel == 0 ? ui->LayersTreeView : ui->TypesTreeView);
QModelIndex Index = pModel->index(0,0);
while (Index.isValid())
{
pView->expand(Index);
Index = Index.sibling(Index.row() + 1, 0);
}
}
}

View File

@@ -0,0 +1,51 @@
#ifndef WINSTANCESTAB_H
#define WINSTANCESTAB_H
#include <QWidget>
#include <QAction>
#include <QMenu>
#include "CTypesInstanceModel.h"
class CWorldEditor;
class CSceneManager;
namespace Ui {
class WInstancesTab;
}
class WInstancesTab : public QWidget
{
Q_OBJECT
CWorldEditor *mpEditor;
CSceneManager *mpScene;
CTypesInstanceModel *mpLayersModel;
CTypesInstanceModel *mpTypesModel;
// Tree right-click context menu
QMenu *mpTreeContextMenu;
QAction *mpHideInstance;
QAction *mpHideType;
QAction *mpHideAllExceptType;
public:
explicit WInstancesTab(QWidget *parent = 0);
~WInstancesTab();
void SetEditor(CWorldEditor *pEditor, CSceneManager *pScene);
void SetMaster(CMasterTemplate *pMaster);
void SetArea(CGameArea *pArea);
private slots:
void OnTreeClick(QModelIndex Index);
void OnTreeDoubleClick(QModelIndex Index);
void OnHideInstanceAction();
void OnHideTypeAction();
void OnHideAllExceptTypeAction();
private:
Ui::WInstancesTab *ui;
void ExpandTopLevelItems();
};
#endif // WINSTANCESTAB_H

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WInstancesTab</class>
<widget class="QWidget" name="WInstancesTab">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>253</width>
<height>437</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="TabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="ShowLayersTab">
<attribute name="title">
<string>Layer</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTreeView" name="LayersTreeView">
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="indentation">
<number>13</number>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="ShowTypesTab">
<attribute name="title">
<string>Type</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTreeView" name="TypesTreeView">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="alternatingRowColors">
<bool>false</bool>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="indentation">
<number>13</number>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,145 @@
#include "WModifyTab.h"
#include "ui_WModifyTab.h"
#include <Scene/CScriptNode.h>
#include <QScrollArea>
#include <QScrollBar>
#include "../CWorldEditor.h"
WModifyTab::WModifyTab(QWidget *pParent) :
QWidget(pParent),
ui(new Ui::WModifyTab)
{
ui->setupUi(this);
mpCurPropEditor = nullptr;
mpInLinkModel = new CLinkModel(this);
mpInLinkModel->SetConnectionType(CLinkModel::eIncoming);
mpOutLinkModel = new CLinkModel(this);
mpOutLinkModel->SetConnectionType(CLinkModel::eOutgoing);
ui->InLinksTableView->setModel(mpInLinkModel);
ui->OutLinksTableView->setModel(mpOutLinkModel);
ui->InLinksTableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
ui->OutLinksTableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
connect(ui->InLinksTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnLinkTableDoubleClick(QModelIndex)));
connect(ui->OutLinksTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnLinkTableDoubleClick(QModelIndex)));
ClearUI();
}
WModifyTab::~WModifyTab()
{
delete ui;
}
void WModifyTab::SetEditor(CWorldEditor *pEditor)
{
mpWorldEditor = pEditor;
}
void WModifyTab::GenerateUI(std::list<CSceneNode*>& Selection)
{
WPropertyEditor *pOldEditor = mpCurPropEditor;
ClearUI();
if (Selection.size() == 1)
{
mpSelectedNode = Selection.front();
// todo: set up editing UI for Light Nodes
if (mpSelectedNode->NodeType() == eScriptNode)
{
ui->ObjectsTabWidget->show();
CScriptNode *pScriptNode = static_cast<CScriptNode*>(mpSelectedNode);
CScriptObject *pObj = pScriptNode->Object();
CScriptTemplate *pTemplate = pObj->Template();
CPropertyStruct *pProperties = pObj->Properties();
// Check whether a cached UI for this object exists
auto it = mCachedPropEditors.find(pTemplate);
// Load precached UI
if (it != mCachedPropEditors.end())
{
mpCurPropEditor = *it;
mpCurPropEditor->SetProperty(pProperties);
}
// Generate new UI
else
{
mpCurPropEditor = new WPropertyEditor(ui->PropertiesScrollContents, pProperties);
mCachedPropEditors[pTemplate] = mpCurPropEditor;
}
ui->PropertiesScrollLayout->insertWidget(0, mpCurPropEditor);
mpCurPropEditor->show();
// Scroll back up to the top, but only if this is a new editor.
// (This is so clicking on multiple objects of the same type, or even
// the same object twice, won't cause you to lose your place.)
if (pOldEditor != mpCurPropEditor)
{
ui->PropertiesScrollArea->horizontalScrollBar()->setValue(0);
ui->PropertiesScrollArea->verticalScrollBar()->setValue(0);
}
// Set up connection table model
mpInLinkModel->SetObject(pObj);
mpOutLinkModel->SetObject(pObj);
}
}
else
ClearUI();
}
void WModifyTab::ClearUI()
{
if (mpCurPropEditor)
{
ui->PropertiesScrollLayout->removeWidget(mpCurPropEditor);
mpCurPropEditor->hide();
mpCurPropEditor = nullptr;
}
ui->ObjectsTabWidget->hide();
ui->LightGroupBox->hide();
}
void WModifyTab::ClearCachedEditors()
{
foreach(WPropertyEditor *pEditor, mCachedPropEditors)
delete pEditor;
mCachedPropEditors.clear();
}
void WModifyTab::OnLinkTableDoubleClick(QModelIndex Index)
{
if (Index.column() == 0)
{
// The link table will only be visible if the selected node is a script node
CScriptNode *pNode = static_cast<CScriptNode*>(mpSelectedNode);
SLink Link;
if (sender() == ui->InLinksTableView)
Link = pNode->Object()->InLink(Index.row());
else if (sender() == ui->OutLinksTableView)
Link = pNode->Object()->OutLink(Index.row());
else
std::cout << "Error - OnLinkTableDoubleClick() activated by invalid sender\n";
CScriptNode *pLinkedNode = pNode->Scene()->ScriptNodeByID(Link.ObjectID);
if (pLinkedNode)
{
mpWorldEditor->ClearSelection();
mpWorldEditor->SelectNode(pLinkedNode);
}
ui->InLinksTableView->clearSelection();
ui->OutLinksTableView->clearSelection();
}
}

View File

@@ -0,0 +1,47 @@
#ifndef WMODIFYTAB_H
#define WMODIFYTAB_H
#include <QWidget>
#include <QScrollArea>
#include <QTabWidget>
#include <QVBoxLayout>
#include <QMap>
#include "CLinkModel.h"
#include "../WPropertyEditor.h"
#include <Scene/CSceneNode.h>
class CWorldEditor;
namespace Ui {
class WModifyTab;
}
class WModifyTab : public QWidget
{
Q_OBJECT
CWorldEditor *mpWorldEditor;
CSceneNode *mpSelectedNode;
QMap<CScriptTemplate*, WPropertyEditor*> mCachedPropEditors;
WPropertyEditor *mpCurPropEditor;
CLinkModel *mpInLinkModel;
CLinkModel *mpOutLinkModel;
public:
explicit WModifyTab(QWidget *pParent = 0);
~WModifyTab();
void SetEditor(CWorldEditor *pEditor);
void GenerateUI(std::list<CSceneNode*>& Selection);
void ClearUI();
void ClearCachedEditors();
private:
Ui::WModifyTab *ui;
private slots:
void OnLinkTableDoubleClick(QModelIndex Index);
};
#endif // WMODIFYTAB_H

View File

@@ -0,0 +1,222 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WModifyTab</class>
<widget class="QWidget" name="WModifyTab">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>282</width>
<height>502</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="MainLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item>
<widget class="QTabWidget" name="ObjectsTabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="PropertiesTab">
<attribute name="title">
<string>Properties</string>
</attribute>
<layout class="QVBoxLayout" name="PropertiesLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="PropertiesScrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="PropertiesScrollContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>276</width>
<height>439</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="PropertiesScrollLayout">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="ConnectionsTab">
<attribute name="title">
<string>Connections</string>
</attribute>
<layout class="QVBoxLayout" name="ConnectionsLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="ConnectionsScrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="ConnectionsScrollContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>276</width>
<height>439</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="OutLinksGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Outgoing</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QTableView" name="OutLinksTableView">
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>75</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="InLinksGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Incoming</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTableView" name="InLinksTableView">
<attribute name="horizontalHeaderDefaultSectionSize">
<number>75</number>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QGroupBox" name="LightGroupBox">
<property name="title">
<string>Light</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>