Update the rest of the UI on property changes and update properties on node transform

This commit is contained in:
parax0 2016-01-30 18:54:00 -07:00
parent 2e6024b413
commit c7d448225c
29 changed files with 270 additions and 90 deletions

View File

@ -344,11 +344,6 @@ bool CScriptTemplate::HasInGameModel(CPropertyStruct *pProperties)
return false;
}
bool CScriptTemplate::HasPosition()
{
return (!mPositionIDString.IsEmpty());
}
// ************ OBJECT TRACKING ************
u32 CScriptTemplate::NumObjects() const
{

View File

@ -116,7 +116,12 @@ public:
CTexture* FindBillboardTexture(CPropertyStruct *pProperties);
CCollisionMeshGroup* FindCollision(CPropertyStruct *pProperties);
bool HasInGameModel(CPropertyStruct *pProperties);
bool HasPosition();
inline bool HasName() const { return !mNameIDString.IsEmpty(); }
inline bool HasPosition() const { return !mPositionIDString.IsEmpty(); }
inline bool HasRotation() const { return !mRotationIDString.IsEmpty(); }
inline bool HasScale() const { return !mScaleIDString.IsEmpty(); }
inline bool HasActive() const { return !mActiveIDString.IsEmpty(); }
// Object Tracking
u32 NumObjects() const;

View File

@ -8,8 +8,6 @@
#include <Math/CTransform4f.h>
#include <algorithm>
#include <gtc/quaternion.hpp>
#include <gtx/transform.hpp>
u32 CSceneNode::smNumNodes = 0;
CColor CSceneNode::skSelectionTint = CColor::Integral(39, 154, 167);

View File

@ -54,11 +54,12 @@ public:
explicit CSceneNode(CScene *pScene, CSceneNode *pParent = 0);
virtual ~CSceneNode();
virtual ENodeType NodeType() = 0;
virtual void PostLoad() {}
virtual void OnTransformed() {}
virtual void AddToRenderer(CRenderer* /*pRenderer*/, const SViewInfo& /*ViewInfo*/) {}
virtual void DrawSelection();
virtual void RayAABoxIntersectTest(CRayCollisionTester& Tester, const SViewInfo& ViewInfo);
virtual SRayIntersection RayNodeIntersectTest(const CRay& Ray, u32 AssetID, const SViewInfo& ViewInfo) = 0;
virtual void PostLoad() {}
virtual bool AllowsTranslate() const { return true; }
virtual bool AllowsRotate() const { return true; }
virtual bool AllowsScale() const { return true; }

View File

@ -18,7 +18,7 @@ CScriptNode::CScriptNode(CScene *pScene, CSceneNode *pParent, CScriptObject *pOb
// Evaluate instance
mpInstance = pObject;
mpActiveModel = nullptr;
SetActiveModel(nullptr);
mpBillboard = nullptr;
mpCollisionNode = new CCollisionNode(pScene, this);
mpCollisionNode->SetInheritance(true, true, false);
@ -37,7 +37,7 @@ CScriptNode::CScriptNode(CScene *pScene, CSceneNode *pParent, CScriptObject *pOb
SetName("[" + pTemp->Name() + "] " + mpInstance->InstanceName());
// Determine display assets
mpActiveModel = mpInstance->GetDisplayModel();
SetActiveModel(mpInstance->GetDisplayModel());
mpBillboard = mpInstance->GetBillboard();
mpCollisionNode->SetCollision(mpInstance->GetCollision());
@ -66,11 +66,6 @@ CScriptNode::CScriptNode(CScene *pScene, CSceneNode *pParent, CScriptObject *pOb
SetName("ScriptNode - NO INSTANCE");
}
if (mpActiveModel)
mLocalAABox = mpActiveModel->AABox();
else
mLocalAABox = CAABox::skOne;
mpExtra = CScriptExtra::CreateExtra(this);
}
@ -79,6 +74,26 @@ ENodeType CScriptNode::NodeType()
return eScriptNode;
}
void CScriptNode::OnTransformed()
{
if (mpExtra)
mpExtra->OnTransformed();
if (mpInstance)
{
CScriptTemplate *pTemplate = Template();
if (pTemplate->HasPosition() && LocalPosition() != mpInstance->Position())
mpInstance->SetPosition(LocalPosition());
if (pTemplate->HasRotation() && LocalRotation().ToEuler() != mpInstance->Rotation())
mpInstance->SetRotation(LocalRotation().ToEuler());
if (pTemplate->HasScale() && LocalScale() != mpInstance->Scale())
mpInstance->SetScale(LocalScale());
}
}
void CScriptNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
{
if (!mpInstance) return;
@ -389,7 +404,7 @@ void CScriptNode::PropertyModified(IProperty *pProp)
if (pProp->Type() == eCharacterProperty)
{
mpInstance->EvaluateDisplayModel();
mpActiveModel = mpInstance->GetDisplayModel();
SetActiveModel(mpInstance->GetDisplayModel());
}
else if (pProp->Type() == eFileProperty)
{
@ -398,7 +413,7 @@ void CScriptNode::PropertyModified(IProperty *pProp)
if (pFile->AcceptsExtension("CMDL") || pFile->AcceptsExtension("ANCS") || pFile->AcceptsExtension("CHAR"))
{
mpInstance->EvaluateDisplayModel();
mpActiveModel = mpInstance->GetDisplayModel();
SetActiveModel(mpInstance->GetDisplayModel());
}
else if (pFile->AcceptsExtension("TXTR"))
{
@ -415,10 +430,20 @@ void CScriptNode::PropertyModified(IProperty *pProp)
// Update other editor properties
if (mpInstance->IsEditorProperty(pProp))
{
SetName("[" + mpInstance->Template()->Name() + "] " + mpInstance->InstanceName());
mPosition = mpInstance->Position();
mRotation = CQuaternion::FromEuler(mpInstance->Rotation());
mScale = mpInstance->Scale();
CScriptTemplate *pTemplate = Template();
if (pTemplate->HasName())
SetName("[" + mpInstance->Template()->Name() + "] " + mpInstance->InstanceName());
if (pTemplate->HasPosition())
mPosition = mpInstance->Position();
if (pTemplate->HasRotation())
mRotation = CQuaternion::FromEuler(mpInstance->Rotation());
if (pTemplate->HasScale())
mScale = mpInstance->Scale();
MarkTransformChanged();
SetLightLayerIndex(mpLightParameters->LightLayerIndex());
@ -460,7 +485,7 @@ void CScriptNode::UpdatePreviewVolume()
void CScriptNode::GeneratePosition()
{
if (!mHasValidPosition)
if (!mHasValidPosition)
{
// Default to center of the active area; this is to preven recursion issues
CTransform4f& AreaTransform = mpScene->GetActiveArea()->GetTransform();
@ -569,6 +594,13 @@ CVector2f CScriptNode::BillboardScale() const
}
// ************ PROTECTED ************
void CScriptNode::SetActiveModel(CModel *pModel)
{
mpActiveModel = pModel;
mLocalAABox = (pModel ? pModel->AABox() : CAABox::skOne);
MarkTransformChanged();
}
void CScriptNode::CalculateTransform(CTransform4f& rOut) const
{
CScriptTemplate *pTemp = Template();

View File

@ -27,6 +27,7 @@ class CScriptNode : public CSceneNode
public:
CScriptNode(CScene *pScene, CSceneNode *pParent = 0, CScriptObject *pObject = 0);
ENodeType NodeType();
void OnTransformed();
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
void DrawSelection();
@ -51,6 +52,7 @@ public:
CVector2f BillboardScale() const;
protected:
void SetActiveModel(CModel *pModel);
void CalculateTransform(CTransform4f& rOut) const;
};

View File

@ -53,7 +53,6 @@ INodeEditor::INodeEditor(QWidget *pParent)
connect(mGizmoActions[2], SIGNAL(triggered()), this, SLOT(OnRotateTriggered()));
connect(mGizmoActions[3], SIGNAL(triggered()), this, SLOT(OnScaleTriggered()));
connect(mpTransformCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(OnTransformSpaceChanged(int)));
connect(this, SIGNAL(SelectionModified()), this, SLOT(OnSelectionModified()));
}
INodeEditor::~INodeEditor()
@ -232,6 +231,20 @@ void INodeEditor::ExitPickMode()
}
}
void INodeEditor::NotifySelectionModified()
{
UpdateSelectionUI();
emit SelectionModified();
}
void INodeEditor::NotifySelectionTransformed()
{
foreach (CSceneNode *pNode, mSelection)
pNode->OnTransformed();
emit SelectionTransformed();
}
// ************ PUBLIC SLOTS ************
void INodeEditor::OnGizmoMoved()
{
@ -302,8 +315,6 @@ void INodeEditor::OnViewportClick(const SRayIntersection& rkRayIntersect, QMouse
ClearSelection();
}
}
UpdateSelectionUI();
}
// In pick mode: process node pick
@ -445,9 +456,3 @@ void INodeEditor::OnTransformSpaceChanged(int spaceIndex)
mGizmo.SetTransformSpace(space);
}
void INodeEditor::OnSelectionModified()
{
UpdateTransformActionsEnabled();
UpdateSelectionUI();
}

View File

@ -77,6 +77,9 @@ public:
void EnterPickMode(FNodeFlags AllowedNodes, bool ExitOnInvalidPick, bool EmitOnInvalidPick, bool EmitHoverOnButtonPress, QCursor Cursor = Qt::CrossCursor);
void ExitPickMode();
void NotifySelectionModified();
void NotifySelectionTransformed();
signals:
void SelectionModified();
void SelectionTransformed();
@ -107,7 +110,6 @@ private slots:
void OnRotateTriggered();
void OnScaleTriggered();
void OnTransformSpaceChanged(int spaceIndex);
void OnSelectionModified();
};
#endif // INODEEDITOR_H

View File

@ -24,6 +24,7 @@
CPropertyDelegate::CPropertyDelegate(QObject *pParent /*= 0*/)
: QStyledItemDelegate(pParent)
, mpModel(nullptr)
, mRelaysBlocked(false)
{
}
@ -181,6 +182,8 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
void CPropertyDelegate::setEditorData(QWidget *pEditor, const QModelIndex &rkIndex) const
{
BlockRelays(true);
if (pEditor)
{
// Set editor data for regular property
@ -322,6 +325,8 @@ void CPropertyDelegate::setEditorData(QWidget *pEditor, const QModelIndex &rkInd
}
}
}
BlockRelays(false);
}
void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pModel*/, const QModelIndex &rkIndex) const
@ -402,6 +407,14 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo
break;
}
case eFileProperty:
{
WResourceSelector *pSelector = static_cast<WResourceSelector*>(pEditor);
TFileProperty *pFile = static_cast<TFileProperty*>(pProp);
pFile->Set(pSelector->GetResourceInfo());
break;
}
case eArrayProperty:
{
WIntegralSpinBox *pSpinBox = static_cast<WIntegralSpinBox*>(pEditor);
@ -544,7 +557,7 @@ void CPropertyDelegate::SetCharacterEditorData(QWidget *pEditor, const QModelInd
if (Type == eFileProperty)
{
static_cast<WResourceSelector*>(pEditor)->SetResource(Params.AnimSet());
static_cast<WResourceSelector*>(pEditor)->SetResource(Params.AnimSet());
}
else if (Type == eEnumProperty)
@ -569,6 +582,10 @@ void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelInde
if (Type == eFileProperty)
{
Params.SetResource( static_cast<WResourceSelector*>(pEditor)->GetResource() );
// Reset all other parameters to 0
Params.SetNodeIndex(0);
for (u32 iUnk = 0; iUnk < 4; iUnk++)
Params.SetUnknown(iUnk, 0);
}
else if (Type == eEnumProperty)
@ -583,6 +600,14 @@ void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelInde
}
pProp->Set(Params);
// If we just updated the resource, make sure all the sub-properties of the character are flagged as changed.
// We want to do this -after- updating the anim params on the property, which is why we have a second type check.
if (Type == eFileProperty)
{
QModelIndex ParentIndex = rkIndex.parent();
mpModel->dataChanged(mpModel->index(1, 1, ParentIndex), mpModel->index(mpModel->rowCount(ParentIndex) - 1, 1, ParentIndex));
}
}
EPropertyType CPropertyDelegate::DetermineCharacterPropType(EGame Game, const QModelIndex& rkIndex) const
@ -611,5 +636,6 @@ void CPropertyDelegate::WidgetEdited(QWidget *pWidget, const QModelIndex& rkInde
{
// This slot is used to update property values as they're being updated so changes can be
// reflected in realtime in other parts of the application.
setModelData(pWidget, mpModel, rkIndex);
if (!mRelaysBlocked)
setModelData(pWidget, mpModel, rkIndex);
}

View File

@ -9,6 +9,7 @@ class CPropertyDelegate : public QStyledItemDelegate
Q_OBJECT
CPropertyModel *mpModel;
mutable bool mRelaysBlocked;
public:
CPropertyDelegate(QObject *pParent = 0);
@ -26,6 +27,9 @@ public:
public slots:
void WidgetEdited(QWidget *pWidget, const QModelIndex& rkIndex);
protected:
void BlockRelays(bool Block) const { mRelaysBlocked = Block; }
signals:
void PropertyEdited(const QModelIndex& rkIndex, bool IsDone) const;
};

View File

@ -284,9 +284,18 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
{
if (!(rkIndex.internalId() & 0x1))
{
// Add name
IProperty *pProp = PropertyForIndex(rkIndex, false);
QString DisplayText = data(rkIndex, Qt::DisplayRole).toString();
QString Text = QString("<b>%1</b> <i>(%2)</i>").arg(DisplayText).arg(TO_QSTRING(PropEnumToPropString(pProp->Type())));
// Add uncooked notification
if (pProp->Template()->CookPreference() == eNeverCook)
{
Text += "<br/><b>This is an uncooked property.</b>";
}
// Add description
TString Desc = pProp->Template()->Description();
if (!Desc.IsEmpty()) Text += "<br/>" + TO_QSTRING(Desc);
return Text;

View File

@ -16,7 +16,7 @@ CPropertyView::CPropertyView(QWidget *pParent)
connect(mpModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(SetPersistentEditors(QModelIndex)));
connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(SetPersistentEditors(QModelIndex)));
connect(mpDelegate, SIGNAL(PropertyEdited(QModelIndex,bool)), this, SIGNAL(PropertyModified(QModelIndex,bool)));
connect(mpDelegate, SIGNAL(PropertyEdited(QModelIndex,bool)), this, SLOT(OnPropertyModified(QModelIndex,bool)));
}
void CPropertyView::setModel(QAbstractItemModel *pModel)
@ -38,30 +38,33 @@ bool CPropertyView::event(QEvent *pEvent)
{
if (pEvent->type() == QEvent::ToolTip)
{
QPoint MousePos = mapFromGlobal(QCursor::pos());
QModelIndex Index = indexAt(MousePos);
QString Desc = mpModel->data(Index, Qt::ToolTipRole).toString();
QPoint MousePos = QCursor::pos();
QModelIndex Index = indexAt(viewport()->mapFromGlobal(MousePos));
if (!Desc.isEmpty())
if (Index.isValid())
{
QToolTip::showText(MousePos, Desc, this);
pEvent->accept();
}
else
{
QToolTip::hideText();
pEvent->ignore();
QString Desc = mpModel->data(Index, Qt::ToolTipRole).toString();
if (!Desc.isEmpty())
{
QToolTip::showText(MousePos, Desc, this);
pEvent->accept();
return true;
}
}
QToolTip::hideText();
pEvent->ignore();
return true;
}
else return QTreeView::event(pEvent);
}
void CPropertyView::SetBaseStruct(CPropertyStruct *pStruct)
void CPropertyView::SetObject(CScriptObject *pObj)
{
mpModel->SetBaseStruct(pStruct);
mpObject = pObj;
mpModel->SetBaseStruct(pObj ? pObj->Properties() : nullptr);
SetPersistentEditors(QModelIndex());
// Auto-expand EditorProperties
@ -71,6 +74,42 @@ void CPropertyView::SetBaseStruct(CPropertyStruct *pStruct)
expand(Index);
}
void CPropertyView::UpdateEditorProperties(const QModelIndex& rkParent)
{
// Iterate over all properties and update if they're an editor property. Ignore structs unless they're EditorProperties or a single struct.
for (int iRow = 0; iRow < mpModel->rowCount(rkParent); iRow++)
{
QModelIndex Index0 = mpModel->index(iRow, 0, rkParent);
QModelIndex Index1 = mpModel->index(iRow, 1, rkParent);
IProperty *pProp = mpModel->PropertyForIndex(Index0, false);
if (pProp)
{
if (pProp->Type() == eStructProperty)
{
CStructTemplate *pStruct = static_cast<CStructTemplate*>(pProp->Template());
if (pStruct->IsSingleProperty() || pStruct->PropertyID() == 0x255A4580)
UpdateEditorProperties(Index0);
else
continue;
}
else if (mpObject->IsEditorProperty(pProp))
{
mpModel->dataChanged(Index1, Index1);
if (mpModel->rowCount(Index0) != 0)
{
QModelIndex SubIndexA = mpModel->index(0, 1, Index0);
QModelIndex SubIndexB = mpModel->index(mpModel->rowCount(Index0) - 1, 1, Index0);
mpModel->dataChanged(SubIndexA, SubIndexB);
}
}
}
}
}
void CPropertyView::SetPersistentEditors(const QModelIndex& rkParent)
{
u32 NumChildren = mpModel->rowCount(rkParent);
@ -96,6 +135,7 @@ void CPropertyView::SetPersistentEditors(const QModelIndex& rkParent)
Type = eBoolProperty;
}
switch (Type)
{
case eBoolProperty:
@ -114,3 +154,37 @@ void CPropertyView::SetPersistentEditors(const QModelIndex& rkParent)
}
}
void CPropertyView::ClosePersistentEditors(const QModelIndex& rkIndex)
{
u32 NumChildren = mpModel->rowCount(rkIndex);
for (u32 iChild = 0; iChild < NumChildren; iChild++)
{
QModelIndex ChildIndex = rkIndex.child(iChild, 1);
closePersistentEditor(ChildIndex);
if (mpModel->rowCount(ChildIndex) != 0)
ClosePersistentEditors(ChildIndex);
}
}
void CPropertyView::OnPropertyModified(const QModelIndex &rkIndex, bool IsDone)
{
// Check for a resource being changed on a character property. If that's the case we need to remake the persistent editors.
if (rkIndex.internalId() & 0x1)
{
if (mpModel->PropertyForIndex(rkIndex, true)->Type() == eCharacterProperty)
{
EGame Game = static_cast<TCharacterProperty*>(mpModel->PropertyForIndex(rkIndex, true))->Get().Version();
if (mpDelegate->DetermineCharacterPropType(Game, rkIndex) == eFileProperty)
{
QModelIndex Parent = rkIndex.parent();
ClosePersistentEditors(Parent);
SetPersistentEditors(Parent);
}
}
}
emit PropertyModified(rkIndex, IsDone);
}

View File

@ -3,6 +3,7 @@
#include "CPropertyModel.h"
#include "CPropertyDelegate.h"
#include <Core/Resource/Script/CScriptObject.h>
#include <QTreeView>
class CPropertyView : public QTreeView
@ -11,20 +12,24 @@ class CPropertyView : public QTreeView
CPropertyModel *mpModel;
CPropertyDelegate *mpDelegate;
CScriptObject *mpObject;
public:
CPropertyView(QWidget *pParent = 0);
void setModel(QAbstractItemModel *pModel);
bool event(QEvent *pEvent);
void SetBaseStruct(CPropertyStruct *pStruct);
void SetObject(CScriptObject *pObj);
void UpdateEditorProperties(const QModelIndex& rkParent);
inline CPropertyModel* PropertyModel() const { return mpModel; }
public slots:
void SetPersistentEditors(const QModelIndex& rkIndex);
void ClosePersistentEditors(const QModelIndex& rkIndex);
void OnPropertyModified(const QModelIndex& rkIndex, bool IsDone);
signals:
void PropertyModified(const QModelIndex& rkIndex, bool IsDone);
void PropertyModified(const QModelIndex &rkIndex, bool IsDone);
};
#endif // CPROPERTYVIEW_H

View File

@ -17,13 +17,13 @@ TestDialog::TestDialog(QWidget *parent) :
{
ui->setupUi(this);
CTemplateLoader::LoadGameTemplates(eCorruption);
/*CTemplateLoader::LoadGameTemplates(eCorruption);
CMasterTemplate *pMaster = CMasterTemplate::GetMasterForGame(eCorruption);
CScriptTemplate *pTemp = pMaster->TemplateByID("PCKP");
CPropertyStruct *pBase = static_cast<CPropertyStruct*>(pTemp->BaseStruct()->InstantiateProperty(nullptr));
ui->treeView->setItemDelegate(new CPropertyDelegate(ui->treeView));
ui->treeView->SetBaseStruct(pBase);
ui->treeView->SetObject(pBase);*/
}
TestDialog::~TestDialog()

View File

@ -27,7 +27,7 @@ void CClearSelectionCommand::undo()
}
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionModified();
mpEditor->NotifySelectionModified();
}
void CClearSelectionCommand::redo()
@ -38,5 +38,5 @@ void CClearSelectionCommand::redo()
mpSelection->clear();
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionModified();
mpEditor->NotifySelectionModified();
}

View File

@ -18,7 +18,7 @@ void CDeselectNodeCommand::undo()
}
mpEditor->ExpandSelectionBounds(mpNode);
mpEditor->SelectionModified();
mpEditor->NotifySelectionModified();
}
void CDeselectNodeCommand::redo()
@ -38,5 +38,5 @@ void CDeselectNodeCommand::redo()
}
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionModified();
mpEditor->NotifySelectionModified();
}

View File

@ -35,7 +35,7 @@ void CInvertSelectionCommand::undo()
// Update editor
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionModified();
mpEditor->NotifySelectionModified();
}
void CInvertSelectionCommand::redo()
@ -52,5 +52,5 @@ void CInvertSelectionCommand::redo()
// Update editor
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionModified();
mpEditor->NotifySelectionModified();
}

View File

@ -28,7 +28,7 @@ CRotateNodeCommand::CRotateNodeCommand(INodeEditor *pEditor, const QList<CSceneN
mNodeList.push_back(rotate);
}
mpEditor->SelectionTransformed();
mpEditor->NotifySelectionTransformed();
}
CRotateNodeCommand::~CRotateNodeCommand()
@ -80,7 +80,7 @@ void CRotateNodeCommand::undo()
}
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionTransformed();
mpEditor->NotifySelectionTransformed();
mpEditor->UpdateGizmoUI();
}
@ -95,7 +95,7 @@ void CRotateNodeCommand::redo()
}
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionTransformed();
mpEditor->NotifySelectionTransformed();
mpEditor->UpdateGizmoUI();
}

View File

@ -28,7 +28,7 @@ CScaleNodeCommand::CScaleNodeCommand(INodeEditor *pEditor, const QList<CSceneNod
mNodeList.push_back(scale);
}
mpEditor->SelectionTransformed();
mpEditor->NotifySelectionTransformed();
}
CScaleNodeCommand::~CScaleNodeCommand()
@ -80,7 +80,7 @@ void CScaleNodeCommand::undo()
}
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionTransformed();
mpEditor->NotifySelectionTransformed();
mpEditor->UpdateGizmoUI();
}
@ -95,7 +95,7 @@ void CScaleNodeCommand::redo()
}
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionTransformed();
mpEditor->NotifySelectionTransformed();
mpEditor->UpdateGizmoUI();
}

View File

@ -35,7 +35,7 @@ void CSelectAllCommand::undo()
// Update editor
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionModified();
mpEditor->NotifySelectionModified();
}
void CSelectAllCommand::redo()
@ -52,5 +52,5 @@ void CSelectAllCommand::redo()
// Update editor
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionModified();
mpEditor->NotifySelectionModified();
}

View File

@ -26,7 +26,7 @@ void CSelectNodeCommand::undo()
}
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionModified();
mpEditor->NotifySelectionModified();
}
void CSelectNodeCommand::redo()
@ -38,5 +38,5 @@ void CSelectNodeCommand::redo()
}
mpEditor->ExpandSelectionBounds(mpNode);
mpEditor->SelectionModified();
mpEditor->NotifySelectionModified();
}

View File

@ -26,7 +26,7 @@ CTranslateNodeCommand::CTranslateNodeCommand(INodeEditor *pEditor, const QList<C
mNodeList.push_back(translate);
}
mpEditor->SelectionTransformed();
mpEditor->NotifySelectionTransformed();
}
CTranslateNodeCommand::~CTranslateNodeCommand()
@ -72,7 +72,7 @@ void CTranslateNodeCommand::undo()
translate.pNode->SetPosition(translate.initialPos);
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionTransformed();
mpEditor->NotifySelectionTransformed();
mpEditor->UpdateGizmoUI();
}
@ -84,7 +84,7 @@ void CTranslateNodeCommand::redo()
translate.pNode->SetPosition(translate.newPos);
mpEditor->RecalculateSelectionBounds();
mpEditor->SelectionTransformed();
mpEditor->NotifySelectionTransformed();
mpEditor->UpdateGizmoUI();
}

View File

@ -107,6 +107,11 @@ bool WResourceSelector::HasSupportedExtension(const CResourceInfo& rkRes)
}
// ************ GETTERS ************
CResourceInfo WResourceSelector::GetResourceInfo()
{
return mResource;
}
CResource* WResourceSelector::GetResource()
{
return mResource.Load();
@ -137,7 +142,7 @@ bool WResourceSelector::IsPreviewPanelEnabled()
void WResourceSelector::SetResource(CResource *pRes)
{
if (pRes)
SetResource(CResourceInfo(pRes->ResID(), CFourCC(pRes->Source().GetFileExtension())));
SetResource(CResourceInfo(pRes->FullSource()));
else
SetResource(CResourceInfo());
}

View File

@ -56,6 +56,7 @@ public:
bool HasSupportedExtension(const CResourceInfo& rkRes);
// Getters
CResourceInfo GetResourceInfo();
CResource* GetResource();
QString GetText();
bool IsEditButtonEnabled();

View File

@ -248,7 +248,9 @@ void CWorldEditor::UpdateSelectionUI()
QFontMetrics Metrics(ui->SelectionInfoLabel->font());
SelectionText = Metrics.elidedText(SelectionText, Qt::ElideRight, ui->SelectionInfoFrame->width() - 10);
ui->SelectionInfoLabel->setText(SelectionText);
if (ui->SelectionInfoLabel->text() != SelectionText)
ui->SelectionInfoLabel->setText(SelectionText);
// Update gizmo stuff
UpdateGizmoUI();

View File

@ -41,27 +41,30 @@ WModifyTab::~WModifyTab()
void WModifyTab::SetEditor(CWorldEditor *pEditor)
{
mpWorldEditor = pEditor;
connect(mpWorldEditor, SIGNAL(SelectionTransformed()), this, SLOT(OnWorldSelectionTransformed()));
}
void WModifyTab::GenerateUI(QList<CSceneNode*>& Selection)
{
ClearUI();
if (Selection.size() == 1)
{
mpSelectedNode = Selection.front();
// todo: set up editing UI for Light Nodes
if (mpSelectedNode->NodeType() == eScriptNode)
if (mpSelectedNode != Selection.front())
{
ui->ObjectsTabWidget->show();
CScriptNode *pScriptNode = static_cast<CScriptNode*>(mpSelectedNode);
CScriptObject *pObj = pScriptNode->Object();
mpSelectedNode = Selection.front();
// Set up UI
ui->PropertyView->SetBaseStruct(pObj->Properties());
mpInLinkModel->SetObject(pObj);
mpOutLinkModel->SetObject(pObj);
// 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();
// Set up UI
ui->PropertyView->SetObject(pObj);
mpInLinkModel->SetObject(pObj);
mpOutLinkModel->SetObject(pObj);
ui->LightGroupBox->hide();
}
}
}
@ -72,8 +75,14 @@ void WModifyTab::GenerateUI(QList<CSceneNode*>& Selection)
void WModifyTab::ClearUI()
{
ui->ObjectsTabWidget->hide();
ui->PropertyView->SetBaseStruct(nullptr);
ui->PropertyView->SetObject(nullptr);
ui->LightGroupBox->hide();
mpSelectedNode = nullptr;
}
void WModifyTab::OnWorldSelectionTransformed()
{
ui->PropertyView->UpdateEditorProperties(QModelIndex());
}
void WModifyTab::OnPropertyModified(const QModelIndex& rkIndex, bool /*IsDone*/)
@ -83,6 +92,10 @@ void WModifyTab::OnPropertyModified(const QModelIndex& rkIndex, bool /*IsDone*/)
CScriptNode *pNode = static_cast<CScriptNode*>(mpSelectedNode);
IProperty *pProperty = ui->PropertyView->PropertyModel()->PropertyForIndex(rkIndex, true);
pNode->PropertyModified(pProperty);
// If this is the instance name property, then other parts of the UI need to be updated to reflect the new name.
if (pNode->Object()->IsEditorProperty(pProperty) && pProperty->Type() == eStringProperty)
mpWorldEditor->UpdateSelectionUI();
}
}

View File

@ -35,6 +35,7 @@ public:
void ClearUI();
public slots:
void OnWorldSelectionTransformed();
void OnPropertyModified(const QModelIndex& rkIndex, bool IsDone);
private:

View File

@ -30,7 +30,7 @@
<object ID="0x1C" template="Script/CameraShaker.xml"/>
<object ID="0x1D" template="Script/ActorKeyframe.xml"/>
<object ID="0x20" template="Script/Water.xml"/>
<object ID="0x21" template="Script/Warwasp.xml"/>
<object ID="0x21" template="Script/WarWasp.xml"/>
<object ID="0x24" template="Script/SpacePirate.xml"/>
<object ID="0x25" template="Script/FlyingPirate.xml"/>
<object ID="0x26" template="Script/ElitePirate.xml"/>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<ScriptTemplate version="4">
<name>Warwasp</name>
<name>WarWasp</name>
<properties>
<property ID="0x00" name="Name" type="string"/>
<property ID="0x01" name="Unknown 1" type="long"/>