Added new WIP UI to the world editor for loading worlds/areas
This commit is contained in:
parent
9928a599be
commit
ce0c544168
|
@ -38,9 +38,15 @@ CDependencyTree* CWorld::BuildDependencyTree() const
|
||||||
|
|
||||||
void CWorld::SetAreaLayerInfo(CGameArea *pArea)
|
void CWorld::SetAreaLayerInfo(CGameArea *pArea)
|
||||||
{
|
{
|
||||||
// The AreaIndex parameter is a placeholder until an improved world loader is implemented.
|
for (u32 iArea = 0; iArea < mAreas.size(); iArea++)
|
||||||
// For now it's the easiest/fastest way to do this because this function is called from
|
{
|
||||||
// the start window and the start window already knows the area index.
|
if (mAreas[iArea].AreaResID == pArea->ID())
|
||||||
|
{
|
||||||
|
pArea->SetWorldIndex(iArea);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SArea& AreaInfo = mAreas[pArea->WorldIndex()];
|
SArea& AreaInfo = mAreas[pArea->WorldIndex()];
|
||||||
|
|
||||||
for (u32 iLyr = 0; iLyr < pArea->NumScriptLayers(); iLyr++)
|
for (u32 iLyr = 0; iLyr < pArea->NumScriptLayers(); iLyr++)
|
||||||
|
|
|
@ -56,9 +56,11 @@ bool CEditorApplication::CloseProject()
|
||||||
mpResourceBrowser->close();
|
mpResourceBrowser->close();
|
||||||
mpProjectDialog->close();
|
mpProjectDialog->close();
|
||||||
|
|
||||||
delete mpActiveProject;
|
// Emit before actually deleting the project to allow editor references to clean up
|
||||||
|
CGameProject *pOldProj = mpActiveProject;
|
||||||
mpActiveProject = nullptr;
|
mpActiveProject = nullptr;
|
||||||
emit ActiveProjectChanged(nullptr);
|
emit ActiveProjectChanged(nullptr);
|
||||||
|
delete pOldProj;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -134,7 +134,7 @@ void CProjectOverviewDialog::LaunchEditor()
|
||||||
{
|
{
|
||||||
pArea->SetWorldIndex(AreaIdx);
|
pArea->SetWorldIndex(AreaIdx);
|
||||||
mpWorld->SetAreaLayerInfo(pArea);
|
mpWorld->SetAreaLayerInfo(pArea);
|
||||||
gpEdApp->WorldEditor()->SetArea(mpWorld, pArea);
|
gpEdApp->WorldEditor()->SetArea(mpWorld, AreaIdx);
|
||||||
gpEdApp->WorldEditor()->showMaximized();
|
gpEdApp->WorldEditor()->showMaximized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,19 +182,7 @@ void CStartWindow::on_LaunchWorldEditorButton_clicked()
|
||||||
{
|
{
|
||||||
Log::ClearErrorLog();
|
Log::ClearErrorLog();
|
||||||
|
|
||||||
CAssetID AreaID = mpWorld->AreaResourceID(mSelectedAreaIndex);
|
mpWorldEditor->SetArea(mpWorld, mSelectedAreaIndex);
|
||||||
TString AreaPath = mpWorld->Entry()->CookedAssetPath().GetFileDirectory() + AreaID.ToString() + ".MREA";
|
|
||||||
TResPtr<CGameArea> pArea = gpResourceStore->LoadResource(AreaPath);
|
|
||||||
|
|
||||||
if (!pArea)
|
|
||||||
{
|
|
||||||
QMessageBox::warning(this, "Error", "Couldn't load area!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pArea->SetWorldIndex(mSelectedAreaIndex);
|
|
||||||
mpWorld->SetAreaLayerInfo(pArea);
|
|
||||||
mpWorldEditor->SetArea(mpWorld, pArea);
|
|
||||||
gpResourceStore->DestroyUnreferencedResources();
|
gpResourceStore->DestroyUnreferencedResources();
|
||||||
|
|
||||||
mpWorldEditor->setWindowModality(Qt::WindowModal);
|
mpWorldEditor->setWindowModality(Qt::WindowModal);
|
||||||
|
|
|
@ -181,7 +181,11 @@ HEADERS += \
|
||||||
CEditorApplication.h \
|
CEditorApplication.h \
|
||||||
IEditor.h \
|
IEditor.h \
|
||||||
Widgets/CResourceSelector.h \
|
Widgets/CResourceSelector.h \
|
||||||
CExportGameDialog.h
|
CExportGameDialog.h \
|
||||||
|
WorldEditor/CScriptEditSidebar.h \
|
||||||
|
WorldEditor/CWorldInfoSidebar.h \
|
||||||
|
WorldEditor/CWorldTreeModel.h \
|
||||||
|
Widgets/CTimedLineEdit.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -246,7 +250,10 @@ SOURCES += \
|
||||||
ResourceBrowser/CResourceBrowser.cpp \
|
ResourceBrowser/CResourceBrowser.cpp \
|
||||||
CEditorApplication.cpp \
|
CEditorApplication.cpp \
|
||||||
Widgets/CResourceSelector.cpp \
|
Widgets/CResourceSelector.cpp \
|
||||||
CExportGameDialog.cpp
|
CExportGameDialog.cpp \
|
||||||
|
WorldEditor/CScriptEditSidebar.cpp \
|
||||||
|
WorldEditor/CWorldInfoSidebar.cpp \
|
||||||
|
WorldEditor/CWorldTreeModel.cpp
|
||||||
|
|
||||||
# UI Files
|
# UI Files
|
||||||
FORMS += \
|
FORMS += \
|
||||||
|
@ -271,4 +278,5 @@ FORMS += \
|
||||||
WorldEditor/CCollisionRenderSettingsDialog.ui \
|
WorldEditor/CCollisionRenderSettingsDialog.ui \
|
||||||
CProjectOverviewDialog.ui \
|
CProjectOverviewDialog.ui \
|
||||||
ResourceBrowser/CResourceBrowser.ui \
|
ResourceBrowser/CResourceBrowser.ui \
|
||||||
CExportGameDialog.ui
|
CExportGameDialog.ui \
|
||||||
|
WorldEditor/CWorldInfoSidebar.ui
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
#ifndef CTIMEDLINEEDIT_H
|
||||||
|
#define CTIMEDLINEEDIT_H
|
||||||
|
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
// Simple line edit subclass that emits a signal when the user stops typing.
|
||||||
|
class CTimedLineEdit : public QLineEdit
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QString mCachedText;
|
||||||
|
float mTimeoutDuration;
|
||||||
|
QTimer mTimer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CTimedLineEdit(QWidget *pParent = 0)
|
||||||
|
: QLineEdit(pParent)
|
||||||
|
, mTimeoutDuration(0.3f)
|
||||||
|
{
|
||||||
|
connect(this, SIGNAL(textChanged(QString)), this, SLOT(OnTextChanged()));
|
||||||
|
connect(&mTimer, SIGNAL(timeout()), this, SLOT(OnTimeout()));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetTimeoutDuration(float Duration) { mTimeoutDuration = Duration; }
|
||||||
|
inline float TimeoutDuration() const { return mTimeoutDuration; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void StoppedTyping(const QString& rkText);
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
virtual void OnTextChanged()
|
||||||
|
{
|
||||||
|
mTimer.start(mTimeoutDuration * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void OnTimeout()
|
||||||
|
{
|
||||||
|
mTimer.stop();
|
||||||
|
|
||||||
|
// Don't emit if the text is the same
|
||||||
|
if (mCachedText != text())
|
||||||
|
emit StoppedTyping(text());
|
||||||
|
|
||||||
|
mCachedText = text();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CTIMEDLINEEDIT_H
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include "CScriptEditSidebar.h"
|
||||||
|
#include "WCreateTab.h"
|
||||||
|
#include "WModifyTab.h"
|
||||||
|
#include "WInstancesTab.h"
|
||||||
|
#include "CWorldEditor.h"
|
||||||
|
|
||||||
|
CScriptEditSidebar::CScriptEditSidebar(CWorldEditor *pEditor)
|
||||||
|
: QTabWidget(pEditor)
|
||||||
|
{
|
||||||
|
mpCreateTab = new WCreateTab(pEditor, this);
|
||||||
|
mpModifyTab = new WModifyTab(pEditor, this);
|
||||||
|
mpInstancesTab = new WInstancesTab(pEditor, this);
|
||||||
|
|
||||||
|
addTab(mpCreateTab, QIcon(":/icons/Create.png"), "Create");
|
||||||
|
addTab(mpModifyTab, QIcon(":/icons/Modify.png"), "Modify");
|
||||||
|
addTab(mpInstancesTab, QIcon(":/icons/Instances.png"), "Instances");
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef CSCRIPTEDITSIDEBAR_H
|
||||||
|
#define CSCRIPTEDITSIDEBAR_H
|
||||||
|
|
||||||
|
#include <QTabWidget>
|
||||||
|
|
||||||
|
class CWorldEditor;
|
||||||
|
class WCreateTab;
|
||||||
|
class WModifyTab;
|
||||||
|
class WInstancesTab;
|
||||||
|
|
||||||
|
class CScriptEditSidebar : public QTabWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
WCreateTab *mpCreateTab;
|
||||||
|
WModifyTab *mpModifyTab;
|
||||||
|
WInstancesTab *mpInstancesTab;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CScriptEditSidebar(CWorldEditor *pEditor);
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
inline WCreateTab* CreateTab() const { return mpCreateTab; }
|
||||||
|
inline WModifyTab* ModifyTab() const { return mpModifyTab; }
|
||||||
|
inline WInstancesTab* InstancesTab() const { return mpInstancesTab; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CSCRIPTEDITSIDEBAR_H
|
|
@ -4,6 +4,7 @@
|
||||||
#include "CLayerEditor.h"
|
#include "CLayerEditor.h"
|
||||||
#include "CRepackInfoDialog.h"
|
#include "CRepackInfoDialog.h"
|
||||||
#include "CTemplateMimeData.h"
|
#include "CTemplateMimeData.h"
|
||||||
|
#include "WCreateTab.h"
|
||||||
#include "WModifyTab.h"
|
#include "WModifyTab.h"
|
||||||
#include "WInstancesTab.h"
|
#include "WInstancesTab.h"
|
||||||
|
|
||||||
|
@ -52,9 +53,7 @@ CWorldEditor::CWorldEditor(QWidget *parent)
|
||||||
|
|
||||||
// Initialize UI stuff
|
// Initialize UI stuff
|
||||||
ui->MainViewport->SetScene(this, &mScene);
|
ui->MainViewport->SetScene(this, &mScene);
|
||||||
ui->CreateTabContents->SetEditor(this);
|
ui->MainViewport->setAcceptDrops(true);
|
||||||
ui->ModifyTabContents->SetEditor(this);
|
|
||||||
ui->InstancesTabContents->SetEditor(this, &mScene);
|
|
||||||
ui->TransformSpinBox->SetOrientation(Qt::Horizontal);
|
ui->TransformSpinBox->SetOrientation(Qt::Horizontal);
|
||||||
ui->TransformSpinBox->layout()->setContentsMargins(0,0,0,0);
|
ui->TransformSpinBox->layout()->setContentsMargins(0,0,0,0);
|
||||||
ui->CamSpeedSpinBox->SetDefaultValue(1.0);
|
ui->CamSpeedSpinBox->SetDefaultValue(1.0);
|
||||||
|
@ -65,6 +64,18 @@ CWorldEditor::CWorldEditor(QWidget *parent)
|
||||||
ui->menuEdit->insertActions(ui->ActionCut, mUndoActions);
|
ui->menuEdit->insertActions(ui->ActionCut, mUndoActions);
|
||||||
ui->menuEdit->insertSeparator(ui->ActionCut);
|
ui->menuEdit->insertSeparator(ui->ActionCut);
|
||||||
|
|
||||||
|
// Initialize sidebar
|
||||||
|
mpCurSidebarWidget = nullptr;
|
||||||
|
mpRightSidebarLayout = new QVBoxLayout();
|
||||||
|
mpRightSidebarLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
ui->RightSidebarFrame->setLayout(mpRightSidebarLayout);
|
||||||
|
|
||||||
|
mpWorldInfoSidebar = new CWorldInfoSidebar(this);
|
||||||
|
mpWorldInfoSidebar->setHidden(true);
|
||||||
|
mpScriptSidebar = new CScriptEditSidebar(this);
|
||||||
|
mpScriptSidebar->setHidden(true);
|
||||||
|
SetSidebarWidget(mpWorldInfoSidebar);
|
||||||
|
|
||||||
// Initialize actions
|
// Initialize actions
|
||||||
addAction(ui->ActionIncrementGizmo);
|
addAction(ui->ActionIncrementGizmo);
|
||||||
addAction(ui->ActionDecrementGizmo);
|
addAction(ui->ActionDecrementGizmo);
|
||||||
|
@ -156,15 +167,11 @@ CWorldEditor::CWorldEditor(QWidget *parent)
|
||||||
connect(ui->ActionCollisionRenderSettings, SIGNAL(triggered()), this, SLOT(EditCollisionRenderSettings()));
|
connect(ui->ActionCollisionRenderSettings, SIGNAL(triggered()), this, SLOT(EditCollisionRenderSettings()));
|
||||||
connect(ui->ActionEditLayers, SIGNAL(triggered()), this, SLOT(EditLayers()));
|
connect(ui->ActionEditLayers, SIGNAL(triggered()), this, SLOT(EditLayers()));
|
||||||
connect(ui->ActionEditPoiToWorldMap, SIGNAL(triggered()), this, SLOT(EditPoiToWorldMap()));
|
connect(ui->ActionEditPoiToWorldMap, SIGNAL(triggered()), this, SLOT(EditPoiToWorldMap()));
|
||||||
|
|
||||||
ui->CreateTabEditorProperties->SyncToEditor(this);
|
|
||||||
ui->ModifyTabEditorProperties->SyncToEditor(this);
|
|
||||||
ui->InstancesTabEditorProperties->SyncToEditor(this);
|
|
||||||
ui->MainViewport->setAcceptDrops(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CWorldEditor::~CWorldEditor()
|
CWorldEditor::~CWorldEditor()
|
||||||
{
|
{
|
||||||
|
delete mpScriptSidebar; // For some reason WCreateTab filters an event during the viewport's destructor
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,8 +203,6 @@ bool CWorldEditor::CloseWorld()
|
||||||
ExitPickMode();
|
ExitPickMode();
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
ui->MainViewport->ResetHover();
|
ui->MainViewport->ResetHover();
|
||||||
ui->ModifyTabContents->ClearUI();
|
|
||||||
ui->InstancesTabContents->SetMaster(nullptr);
|
|
||||||
|
|
||||||
mUndoStack.clear();
|
mUndoStack.clear();
|
||||||
mpCollisionDialog->close();
|
mpCollisionDialog->close();
|
||||||
|
@ -212,19 +217,18 @@ bool CWorldEditor::CloseWorld()
|
||||||
|
|
||||||
mpArea = nullptr;
|
mpArea = nullptr;
|
||||||
mpWorld = nullptr;
|
mpWorld = nullptr;
|
||||||
|
|
||||||
|
emit MapChanged(mpWorld, mpArea);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea)
|
void CWorldEditor::SetArea(CWorld *pWorld, int AreaIndex)
|
||||||
{
|
{
|
||||||
ExitPickMode();
|
ExitPickMode();
|
||||||
ui->MainViewport->ResetHover();
|
ui->MainViewport->ResetHover();
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
ui->ModifyTabContents->ClearUI();
|
|
||||||
ui->InstancesTabContents->SetMaster(nullptr);
|
|
||||||
ui->InstancesTabContents->SetArea(pArea);
|
|
||||||
mUndoStack.clear();
|
mUndoStack.clear();
|
||||||
|
|
||||||
if (mpPoiDialog)
|
if (mpPoiDialog)
|
||||||
|
@ -234,17 +238,24 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load new area
|
// Load new area
|
||||||
mpArea = pArea;
|
|
||||||
mpWorld = pWorld;
|
mpWorld = pWorld;
|
||||||
mScene.SetActiveWorld(pWorld);
|
CAssetID AreaID = mpWorld->AreaResourceID(AreaIndex);
|
||||||
mScene.SetActiveArea(pArea);
|
CResourceEntry *pAreaEntry = gpResourceStore->FindEntry(AreaID);
|
||||||
|
ASSERT(pAreaEntry);
|
||||||
|
|
||||||
|
mpArea = pAreaEntry->Load();
|
||||||
|
ASSERT(mpArea);
|
||||||
|
mpWorld->SetAreaLayerInfo(mpArea);
|
||||||
|
|
||||||
|
mScene.SetActiveWorld(mpWorld);
|
||||||
|
mScene.SetActiveArea(mpArea);
|
||||||
|
|
||||||
// Snap camera to new area
|
// Snap camera to new area
|
||||||
CCamera *pCamera = &ui->MainViewport->Camera();
|
CCamera *pCamera = &ui->MainViewport->Camera();
|
||||||
|
|
||||||
if (pCamera->MoveMode() == eFreeCamera)
|
if (pCamera->MoveMode() == eFreeCamera)
|
||||||
{
|
{
|
||||||
CTransform4f AreaTransform = pArea->Transform();
|
CTransform4f AreaTransform = mpArea->Transform();
|
||||||
CVector3f AreaPosition(AreaTransform[0][3], AreaTransform[1][3], AreaTransform[2][3]);
|
CVector3f AreaPosition(AreaTransform[0][3], AreaTransform[1][3], AreaTransform[2][3]);
|
||||||
pCamera->Snap(AreaPosition);
|
pCamera->Snap(AreaPosition);
|
||||||
}
|
}
|
||||||
|
@ -260,12 +271,8 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea)
|
||||||
bool AllowEGMC = ( (mpWorld->Game() >= eEchoesDemo) && (mpWorld->Game() <= eCorruption) );
|
bool AllowEGMC = ( (mpWorld->Game() >= eEchoesDemo) && (mpWorld->Game() <= eCorruption) );
|
||||||
ui->ActionEditPoiToWorldMap->setEnabled(AllowEGMC);
|
ui->ActionEditPoiToWorldMap->setEnabled(AllowEGMC);
|
||||||
|
|
||||||
// Set up sidebar tabs
|
|
||||||
CMasterTemplate *pMaster = CMasterTemplate::MasterForGame(mpArea->Game());
|
|
||||||
ui->CreateTabContents->SetMaster(pMaster);
|
|
||||||
ui->InstancesTabContents->SetMaster(pMaster);
|
|
||||||
|
|
||||||
// Set up dialogs
|
// Set up dialogs
|
||||||
|
CMasterTemplate *pMaster = CMasterTemplate::MasterForGame(mpArea->Game());
|
||||||
mpCollisionDialog->SetupWidgets(); // Won't modify any settings but will update widget visibility status if we've changed games
|
mpCollisionDialog->SetupWidgets(); // Won't modify any settings but will update widget visibility status if we've changed games
|
||||||
mpLinkDialog->SetMaster(pMaster);
|
mpLinkDialog->SetMaster(pMaster);
|
||||||
|
|
||||||
|
@ -275,8 +282,8 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea)
|
||||||
|
|
||||||
if (CurrentGame() < eReturns)
|
if (CurrentGame() < eReturns)
|
||||||
{
|
{
|
||||||
CStringTable *pAreaNameTable = mpWorld->AreaName(mpArea->WorldIndex());
|
CStringTable *pAreaNameTable = mpWorld->AreaName(AreaIndex);
|
||||||
TWideString AreaName = pAreaNameTable ? pAreaNameTable->String("ENGL", 0) : (TWideString("!") + mpWorld->AreaInternalName(mpArea->WorldIndex()).ToUTF16());
|
TWideString AreaName = pAreaNameTable ? pAreaNameTable->String("ENGL", 0) : (TWideString("!") + mpWorld->AreaInternalName(AreaIndex).ToUTF16());
|
||||||
|
|
||||||
if (AreaName.IsEmpty())
|
if (AreaName.IsEmpty())
|
||||||
AreaName = "[Untitled Area]";
|
AreaName = "[Untitled Area]";
|
||||||
|
@ -289,7 +296,7 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea)
|
||||||
{
|
{
|
||||||
QString LevelName;
|
QString LevelName;
|
||||||
if (pWorldNameTable) LevelName = TO_QSTRING(WorldName);
|
if (pWorldNameTable) LevelName = TO_QSTRING(WorldName);
|
||||||
else LevelName = "!" + TO_QSTRING(mpWorld->AreaInternalName(mpArea->WorldIndex()));
|
else LevelName = "!" + TO_QSTRING(mpWorld->AreaInternalName(AreaIndex));
|
||||||
|
|
||||||
SET_WINDOWTITLE_APPVARS( QString("%APP_FULL_NAME% - %1[*]").arg(LevelName) );
|
SET_WINDOWTITLE_APPVARS( QString("%APP_FULL_NAME% - %1[*]").arg(LevelName) );
|
||||||
Log::Write("Loaded level: World " + mpWorld->Source() + " / Area " + mpArea->Source() + " (" + TO_TSTRING(LevelName) + ")");
|
Log::Write("Loaded level: World " + mpWorld->Source() + " / Area " + mpArea->Source() + " (" + TO_TSTRING(LevelName) + ")");
|
||||||
|
@ -299,7 +306,11 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea)
|
||||||
OnClipboardDataModified();
|
OnClipboardDataModified();
|
||||||
|
|
||||||
// Emit signals
|
// Emit signals
|
||||||
|
emit MapChanged(mpWorld, mpArea);
|
||||||
emit LayersModified();
|
emit LayersModified();
|
||||||
|
|
||||||
|
// Make sure old area is destroyed
|
||||||
|
gpResourceStore->DestroyUnreferencedResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWorldEditor::CheckUnsavedChanges()
|
bool CWorldEditor::CheckUnsavedChanges()
|
||||||
|
@ -390,7 +401,7 @@ void CWorldEditor::Paste()
|
||||||
PastePoint = Ray.PointOnRay(10.f);
|
PastePoint = Ray.PointOnRay(10.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPasteNodesCommand *pCmd = new CPasteNodesCommand(this, ui->CreateTabContents->SpawnLayer(), PastePoint);
|
CPasteNodesCommand *pCmd = new CPasteNodesCommand(this, mpScriptSidebar->CreateTab()->SpawnLayer(), PastePoint);
|
||||||
mUndoStack.push(pCmd);
|
mUndoStack.push(pCmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -748,8 +759,8 @@ void CWorldEditor::UpdateNewLinkLine()
|
||||||
}
|
}
|
||||||
else if (mIsMakingLink && mpNewLinkSender)
|
else if (mIsMakingLink && mpNewLinkSender)
|
||||||
pSender = mpNewLinkSender;
|
pSender = mpNewLinkSender;
|
||||||
else if (ui->ModifyTabContents->IsPicking() && ui->ModifyTabContents->EditNode()->NodeType() == eScriptNode)
|
else if (mpScriptSidebar->ModifyTab()->IsPicking() && mpScriptSidebar->ModifyTab()->EditNode()->NodeType() == eScriptNode)
|
||||||
pSender = static_cast<CScriptNode*>(ui->ModifyTabContents->EditNode())->Instance();
|
pSender = static_cast<CScriptNode*>(mpScriptSidebar->ModifyTab()->EditNode())->Instance();
|
||||||
|
|
||||||
// No sender and no receiver = no line
|
// No sender and no receiver = no line
|
||||||
if (!pSender && !pReceiver)
|
if (!pSender && !pReceiver)
|
||||||
|
@ -765,7 +776,7 @@ void CWorldEditor::UpdateNewLinkLine()
|
||||||
// Compensate for missing sender or missing receiver
|
// Compensate for missing sender or missing receiver
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool IsPicking = (mIsMakingLink || mpLinkDialog->IsPicking() || ui->ModifyTabContents->IsPicking());
|
bool IsPicking = (mIsMakingLink || mpLinkDialog->IsPicking() || mpScriptSidebar->ModifyTab()->IsPicking());
|
||||||
|
|
||||||
if (ui->MainViewport->underMouse() && !ui->MainViewport->IsMouseInputActive() && IsPicking)
|
if (ui->MainViewport->underMouse() && !ui->MainViewport->IsMouseInputActive() && IsPicking)
|
||||||
{
|
{
|
||||||
|
@ -785,6 +796,23 @@ void CWorldEditor::UpdateNewLinkLine()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ PROTECTED ************
|
// ************ PROTECTED ************
|
||||||
|
void CWorldEditor::SetSidebarWidget(QWidget *pWidget)
|
||||||
|
{
|
||||||
|
if (mpCurSidebarWidget)
|
||||||
|
{
|
||||||
|
mpRightSidebarLayout->removeWidget(mpCurSidebarWidget);
|
||||||
|
mpCurSidebarWidget->setHidden(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
mpCurSidebarWidget = pWidget;
|
||||||
|
|
||||||
|
if (mpCurSidebarWidget)
|
||||||
|
{
|
||||||
|
mpRightSidebarLayout->addWidget(pWidget);
|
||||||
|
mpCurSidebarWidget->setHidden(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CWorldEditor::GizmoModeChanged(CGizmo::EGizmoMode mode)
|
void CWorldEditor::GizmoModeChanged(CGizmo::EGizmoMode mode)
|
||||||
{
|
{
|
||||||
ui->TransformSpinBox->SetSingleStep( (mode == CGizmo::eRotate ? 1.0 : 0.1) );
|
ui->TransformSpinBox->SetSingleStep( (mode == CGizmo::eRotate ? 1.0 : 0.1) );
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "CCollisionRenderSettingsDialog.h"
|
#include "CCollisionRenderSettingsDialog.h"
|
||||||
#include "CLinkDialog.h"
|
#include "CLinkDialog.h"
|
||||||
#include "CPoiMapEditDialog.h"
|
#include "CPoiMapEditDialog.h"
|
||||||
|
#include "CScriptEditSidebar.h"
|
||||||
|
#include "CWorldInfoSidebar.h"
|
||||||
#include "Editor/INodeEditor.h"
|
#include "Editor/INodeEditor.h"
|
||||||
#include "Editor/CGizmo.h"
|
#include "Editor/CGizmo.h"
|
||||||
#include "Editor/CSceneViewport.h"
|
#include "Editor/CSceneViewport.h"
|
||||||
|
@ -55,15 +57,23 @@ class CWorldEditor : public INodeEditor
|
||||||
QString mPakFileList;
|
QString mPakFileList;
|
||||||
QString mPakTarget;
|
QString mPakTarget;
|
||||||
|
|
||||||
|
// Sidebars
|
||||||
|
QVBoxLayout *mpRightSidebarLayout;
|
||||||
|
QWidget *mpCurSidebarWidget;
|
||||||
|
|
||||||
|
CWorldInfoSidebar *mpWorldInfoSidebar;
|
||||||
|
CScriptEditSidebar *mpScriptSidebar;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CWorldEditor(QWidget *parent = 0);
|
explicit CWorldEditor(QWidget *parent = 0);
|
||||||
~CWorldEditor();
|
~CWorldEditor();
|
||||||
void closeEvent(QCloseEvent *pEvent);
|
void closeEvent(QCloseEvent *pEvent);
|
||||||
bool CloseWorld();
|
bool CloseWorld();
|
||||||
void SetArea(CWorld *pWorld, CGameArea *pArea);
|
void SetArea(CWorld *pWorld, int AreaIndex);
|
||||||
bool CheckUnsavedChanges();
|
bool CheckUnsavedChanges();
|
||||||
bool HasAnyScriptNodesSelected() const;
|
bool HasAnyScriptNodesSelected() const;
|
||||||
|
|
||||||
|
inline CWorld* ActiveWorld() const { return mpWorld; }
|
||||||
inline CGameArea* ActiveArea() const { return mpArea; }
|
inline CGameArea* ActiveArea() const { return mpArea; }
|
||||||
inline EGame CurrentGame() const { return mpArea ? mpArea->Game() : eUnknownGame; }
|
inline EGame CurrentGame() const { return mpArea ? mpArea->Game() : eUnknownGame; }
|
||||||
inline CLinkDialog* LinkDialog() const { return mpLinkDialog; }
|
inline CLinkDialog* LinkDialog() const { return mpLinkDialog; }
|
||||||
|
@ -104,6 +114,7 @@ public slots:
|
||||||
void UpdateNewLinkLine();
|
void UpdateNewLinkLine();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void SetSidebarWidget(QWidget *pWidget);
|
||||||
void GizmoModeChanged(CGizmo::EGizmoMode Mode);
|
void GizmoModeChanged(CGizmo::EGizmoMode Mode);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -149,6 +160,7 @@ private slots:
|
||||||
void EditPoiToWorldMap();
|
void EditPoiToWorldMap();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void MapChanged(CWorld *pNewWorld, CGameArea *pNewArea);
|
||||||
void LayersModified();
|
void LayersModified();
|
||||||
void InstancesLayerAboutToChange();
|
void InstancesLayerAboutToChange();
|
||||||
void InstancesLayerChanged(const QList<CScriptNode*>& rkInstanceList);
|
void InstancesLayerChanged(const QList<CScriptNode*>& rkInstanceList);
|
||||||
|
|
|
@ -14,7 +14,156 @@
|
||||||
<string>%APP_FULL_NAME%</string>
|
<string>%APP_FULL_NAME%</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="LeftSidebarFrame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Sunken</enum>
|
||||||
|
</property>
|
||||||
|
<property name="lineWidth">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="EditWorldInfoButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>32</width>
|
||||||
|
<height>32</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>32</width>
|
||||||
|
<height>32</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>World Edit Mode</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../Icons.qrc">
|
||||||
|
<normaloff>:/icons/World.png</normaloff>:/icons/World.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="EditScriptButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>32</width>
|
||||||
|
<height>32</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>32</width>
|
||||||
|
<height>32</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Script Edit Mode</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../Icons.qrc">
|
||||||
|
<normaloff>:/icons/Modify.png</normaloff>:/icons/Modify.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>546</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QSplitter" name="splitter">
|
<widget class="QSplitter" name="splitter">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -209,167 +358,13 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QTabWidget" name="TabWidget">
|
<widget class="QFrame" name="RightSidebarFrame">
|
||||||
<property name="sizePolicy">
|
<property name="frameShape">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
<enum>QFrame::StyledPanel</enum>
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="baseSize">
|
<property name="frameShadow">
|
||||||
<size>
|
<enum>QFrame::Raised</enum>
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::NoFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="tabPosition">
|
|
||||||
<enum>QTabWidget::North</enum>
|
|
||||||
</property>
|
|
||||||
<property name="tabShape">
|
|
||||||
<enum>QTabWidget::Rounded</enum>
|
|
||||||
</property>
|
|
||||||
<property name="currentIndex">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="iconSize">
|
|
||||||
<size>
|
|
||||||
<width>24</width>
|
|
||||||
<height>24</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="documentMode">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="CreateTab">
|
|
||||||
<attribute name="icon">
|
|
||||||
<iconset resource="../Icons.qrc">
|
|
||||||
<normaloff>:/icons/Create.png</normaloff>:/icons/Create.png</iconset>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="title">
|
|
||||||
<string/>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="toolTip">
|
|
||||||
<string>Create</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<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="WEditorProperties" name="CreateTabEditorProperties" native="true"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="WCreateTab" name="CreateTabContents" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>1</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="ModifyTab">
|
|
||||||
<attribute name="icon">
|
|
||||||
<iconset resource="../Icons.qrc">
|
|
||||||
<normaloff>:/icons/Modify.png</normaloff>:/icons/Modify.png</iconset>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="title">
|
|
||||||
<string/>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="toolTip">
|
|
||||||
<string>Modify</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<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="WEditorProperties" name="ModifyTabEditorProperties" native="true"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="WModifyTab" name="ModifyTabContents" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="InstancesTab">
|
|
||||||
<attribute name="icon">
|
|
||||||
<iconset resource="../Icons.qrc">
|
|
||||||
<normaloff>:/icons/Instances.png</normaloff>:/icons/Instances.png</iconset>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="title">
|
|
||||||
<string/>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="toolTip">
|
|
||||||
<string>Instances</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
|
||||||
<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="WEditorProperties" name="InstancesTabEditorProperties" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="WInstancesTab" name="InstancesTabContents" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -408,7 +403,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1280</width>
|
<width>1280</width>
|
||||||
<height>21</height>
|
<height>20</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menuFile">
|
<widget class="QMenu" name="menuFile">
|
||||||
|
@ -858,18 +853,6 @@
|
||||||
<extends>QDoubleSpinBox</extends>
|
<extends>QDoubleSpinBox</extends>
|
||||||
<header>Editor/Widgets/WDraggableSpinBox.h</header>
|
<header>Editor/Widgets/WDraggableSpinBox.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
|
||||||
<class>WModifyTab</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>Editor/WorldEditor/WModifyTab.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>WInstancesTab</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>Editor/WorldEditor/WInstancesTab.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>WVectorEditor</class>
|
<class>WVectorEditor</class>
|
||||||
<extends>QWidget</extends>
|
<extends>QWidget</extends>
|
||||||
|
@ -882,18 +865,6 @@
|
||||||
<header>Editor/CSceneViewport.h</header>
|
<header>Editor/CSceneViewport.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
|
||||||
<class>WEditorProperties</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>Editor/WorldEditor/WEditorProperties.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>WCreateTab</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>Editor/WorldEditor/WCreateTab.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../Icons.qrc"/>
|
<include location="../Icons.qrc"/>
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
#include "CWorldInfoSidebar.h"
|
||||||
|
#include "ui_CWorldInfoSidebar.h"
|
||||||
|
#include "CWorldEditor.h"
|
||||||
|
#include "Editor/CEditorApplication.h"
|
||||||
|
|
||||||
|
CWorldInfoSidebar::CWorldInfoSidebar(CWorldEditor *pEditor)
|
||||||
|
: QWidget(pEditor)
|
||||||
|
, mpUI(new Ui::CWorldInfoSidebar)
|
||||||
|
, mModel(pEditor)
|
||||||
|
{
|
||||||
|
mpUI->setupUi(this);
|
||||||
|
mProxyModel.setSourceModel(&mModel);
|
||||||
|
mpUI->WorldTreeView->setModel(&mProxyModel);
|
||||||
|
mpUI->WorldTreeView->header()->setSortIndicator(0, Qt::AscendingOrder);
|
||||||
|
|
||||||
|
QHeaderView *pHeader = mpUI->WorldTreeView->header();
|
||||||
|
pHeader->resizeSection(0, pHeader->width() * 2); // I really have no idea how this works, I just got this from trial & error
|
||||||
|
|
||||||
|
connect(mpUI->AreaSearchLineEdit, SIGNAL(StoppedTyping(QString)), this, SLOT(OnAreaFilterStringChanged(QString)));
|
||||||
|
connect(mpUI->WorldTreeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnWorldTreeDoubleClicked(QModelIndex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CWorldInfoSidebar::~CWorldInfoSidebar()
|
||||||
|
{
|
||||||
|
delete mpUI;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************ SLOTS ************
|
||||||
|
void CWorldInfoSidebar::OnAreaFilterStringChanged(const QString& rkFilter)
|
||||||
|
{
|
||||||
|
mProxyModel.SetFilterString(rkFilter);
|
||||||
|
|
||||||
|
// Expand top-level items that contain matches for the new filter string
|
||||||
|
int NumTopLevel = mModel.rowCount(QModelIndex());
|
||||||
|
|
||||||
|
for (int iRow = 0; iRow < NumTopLevel; iRow++)
|
||||||
|
{
|
||||||
|
QModelIndex Index = mModel.index(iRow, 0, QModelIndex());
|
||||||
|
QModelIndex ProxyIndex = mProxyModel.mapFromSource(Index);
|
||||||
|
bool Matches = !rkFilter.isEmpty() && mProxyModel.rowCount(ProxyIndex) > 0;
|
||||||
|
mpUI->WorldTreeView->setExpanded(ProxyIndex, Matches);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWorldInfoSidebar::OnWorldTreeDoubleClicked(QModelIndex Index)
|
||||||
|
{
|
||||||
|
QModelIndex RealIndex = mProxyModel.mapToSource(Index);
|
||||||
|
|
||||||
|
if (!mModel.IndexIsWorld(RealIndex))
|
||||||
|
{
|
||||||
|
CWorld *pWorld = mModel.WorldForIndex(RealIndex);
|
||||||
|
int AreaIndex = mModel.AreaIndexForIndex(RealIndex);
|
||||||
|
gpEdApp->WorldEditor()->SetArea(pWorld, AreaIndex);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef CWORLDINFOSIDEBAR_H
|
||||||
|
#define CWORLDINFOSIDEBAR_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
#include "CWorldTreeModel.h"
|
||||||
|
|
||||||
|
class CWorldEditor;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class CWorldInfoSidebar;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CWorldInfoSidebar : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Ui::CWorldInfoSidebar *mpUI;
|
||||||
|
CWorldTreeModel mModel;
|
||||||
|
CWorldTreeProxyModel mProxyModel;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CWorldInfoSidebar(CWorldEditor *pEditor);
|
||||||
|
~CWorldInfoSidebar();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void OnAreaFilterStringChanged(const QString& rkFilter);
|
||||||
|
void OnWorldTreeDoubleClicked(QModelIndex Index);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CWORLDINFOSIDEBAR_H
|
|
@ -0,0 +1,73 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>CWorldInfoSidebar</class>
|
||||||
|
<widget class="QWidget" name="CWorldInfoSidebar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>314</width>
|
||||||
|
<height>585</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="CTimedLineEdit" name="AreaSearchLineEdit">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>10</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Search...</string>
|
||||||
|
</property>
|
||||||
|
<property name="clearButtonEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeView" name="WorldTreeView">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>10</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="verticalScrollMode">
|
||||||
|
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="indentation">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="sortingEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="headerVisible">
|
||||||
|
<bool>true</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>CTimedLineEdit</class>
|
||||||
|
<extends>QLineEdit</extends>
|
||||||
|
<header>Editor/Widgets/CTimedLineEdit.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -0,0 +1,268 @@
|
||||||
|
#include "CWorldTreeModel.h"
|
||||||
|
#include "CEditorApplication.h"
|
||||||
|
#include "CWorldEditor.h"
|
||||||
|
#include "UICommon.h"
|
||||||
|
#include <Core/GameProject/CGameProject.h>
|
||||||
|
#include <QIcon>
|
||||||
|
|
||||||
|
CWorldTreeModel::CWorldTreeModel(CWorldEditor *pEditor)
|
||||||
|
{
|
||||||
|
connect(gpEdApp, SIGNAL(ActiveProjectChanged(CGameProject*)), this, SLOT(OnProjectChanged(CGameProject*)));
|
||||||
|
connect(pEditor, SIGNAL(MapChanged(CWorld*,CGameArea*)), this, SLOT(OnMapChanged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
int CWorldTreeModel::rowCount(const QModelIndex& rkParent) const
|
||||||
|
{
|
||||||
|
if (!rkParent.isValid()) return mWorldList.size();
|
||||||
|
else if (IndexIsWorld(rkParent)) return WorldForIndex(rkParent)->NumAreas();
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CWorldTreeModel::columnCount(const QModelIndex&) const
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex CWorldTreeModel::index(int Row, int Column, const QModelIndex& rkParent) const
|
||||||
|
{
|
||||||
|
if (!hasIndex(Row, Column, rkParent))
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
// World
|
||||||
|
if (!rkParent.isValid())
|
||||||
|
return createIndex(Row, Column, quint64((Row << 16) | 0xFFFF));
|
||||||
|
|
||||||
|
// Area
|
||||||
|
else
|
||||||
|
return createIndex(Row, Column, quint64((rkParent.row() << 16) | (Row & 0xFFFF)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex CWorldTreeModel::parent(const QModelIndex& rkChild) const
|
||||||
|
{
|
||||||
|
if (IndexIsWorld(rkChild))
|
||||||
|
return QModelIndex();
|
||||||
|
else
|
||||||
|
return createIndex((rkChild.internalId() >> 16) & 0xFFFF, 0, rkChild.internalId() | 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant CWorldTreeModel::data(const QModelIndex& rkIndex, int Role) const
|
||||||
|
{
|
||||||
|
if (Role == Qt::DisplayRole || Role == Qt::ToolTipRole)
|
||||||
|
{
|
||||||
|
CWorld *pWorld = WorldForIndex(rkIndex);
|
||||||
|
|
||||||
|
// World
|
||||||
|
if (IndexIsWorld(rkIndex))
|
||||||
|
{
|
||||||
|
QString WorldAssetName = TO_QSTRING( pWorld->Entry()->Name() );
|
||||||
|
CStringTable *pWorldNameString = pWorld->WorldName();
|
||||||
|
|
||||||
|
if (rkIndex.column() == 1)
|
||||||
|
return WorldAssetName;
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pWorldNameString)
|
||||||
|
return TO_QSTRING( pWorldNameString->String("ENGL", 0) );
|
||||||
|
else
|
||||||
|
return WorldAssetName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Area
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u32 AreaIndex = AreaIndexForIndex(rkIndex);
|
||||||
|
ASSERT(AreaIndex >= 0 && AreaIndex < pWorld->NumAreas());
|
||||||
|
|
||||||
|
CAssetID AreaAssetID = pWorld->AreaResourceID(AreaIndex);
|
||||||
|
CResourceEntry *pAreaEntry = pWorld->Entry()->ResourceStore()->FindEntry(AreaAssetID);
|
||||||
|
ASSERT(pAreaEntry);
|
||||||
|
|
||||||
|
QString AreaAssetName = TO_QSTRING( pAreaEntry->Name() );
|
||||||
|
CStringTable *pAreaNameString = pWorld->AreaName(AreaIndex);
|
||||||
|
|
||||||
|
if (rkIndex.column() == 1)
|
||||||
|
return AreaAssetName;
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pAreaNameString)
|
||||||
|
return TO_QSTRING( pAreaNameString->String("ENGL", 0) );
|
||||||
|
else
|
||||||
|
return "!!" + AreaAssetName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (Role == Qt::DecorationRole)
|
||||||
|
{
|
||||||
|
static QIcon sWorldIcon = QIcon(":/icons/World.png");
|
||||||
|
static QIcon sAreaIcon = QIcon(":/icons/New_16px.png");
|
||||||
|
|
||||||
|
if (rkIndex.column() == 1)
|
||||||
|
return QVariant::Invalid;
|
||||||
|
else if (IndexIsWorld(rkIndex))
|
||||||
|
return sWorldIcon;
|
||||||
|
else
|
||||||
|
return sAreaIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (Role == Qt::FontRole)
|
||||||
|
{
|
||||||
|
CWorld *pWorld = WorldForIndex(rkIndex);
|
||||||
|
ASSERT(pWorld);
|
||||||
|
|
||||||
|
QFont Font;
|
||||||
|
int PointSize = Font.pointSize() + 2;
|
||||||
|
|
||||||
|
if (IndexIsWorld(rkIndex))
|
||||||
|
{
|
||||||
|
PointSize += 1;
|
||||||
|
|
||||||
|
CWorld *pWorld = WorldForIndex(rkIndex);
|
||||||
|
if (gpEdApp->WorldEditor()->ActiveWorld() == pWorld)
|
||||||
|
Font.setBold(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CResourceEntry *pEntry = AreaEntryForIndex(rkIndex);
|
||||||
|
ASSERT(pEntry);
|
||||||
|
|
||||||
|
if (pEntry->IsLoaded())
|
||||||
|
{
|
||||||
|
if (gpEdApp->WorldEditor()->ActiveArea() == pEntry->Resource())
|
||||||
|
Font.setBold(true);
|
||||||
|
else
|
||||||
|
Font.setItalic(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Font.setPointSize(PointSize);
|
||||||
|
return Font;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant CWorldTreeModel::headerData(int Section, Qt::Orientation Orientation, int Role) const
|
||||||
|
{
|
||||||
|
if (Orientation == Qt::Horizontal && Role == Qt::DisplayRole)
|
||||||
|
{
|
||||||
|
if (Section == 0)
|
||||||
|
return "In-Game Name";
|
||||||
|
else
|
||||||
|
return "Internal Name";
|
||||||
|
}
|
||||||
|
return QVariant::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWorldTreeModel::IndexIsWorld(const QModelIndex& rkIndex) const
|
||||||
|
{
|
||||||
|
return AreaIndexForIndex(rkIndex) == 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
CWorld* CWorldTreeModel::WorldForIndex(const QModelIndex& rkIndex) const
|
||||||
|
{
|
||||||
|
int WorldIndex = (rkIndex.internalId() >> 16) & 0xFFFF;
|
||||||
|
return mWorldList[WorldIndex].pWorld;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CWorldTreeModel::AreaIndexForIndex(const QModelIndex& rkIndex) const
|
||||||
|
{
|
||||||
|
int InternalID = (int) rkIndex.internalId();
|
||||||
|
return (InternalID & 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
CResourceEntry* CWorldTreeModel::AreaEntryForIndex(const QModelIndex& rkIndex) const
|
||||||
|
{
|
||||||
|
ASSERT(rkIndex.isValid() && !IndexIsWorld(rkIndex));
|
||||||
|
const SWorldInfo& rkInfo = mWorldList[rkIndex.parent().row()];
|
||||||
|
return rkInfo.Areas[rkIndex.row()];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************ SLOTS ************
|
||||||
|
void CWorldTreeModel::OnProjectChanged(CGameProject *pProj)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
mWorldList.clear();
|
||||||
|
|
||||||
|
if (pProj)
|
||||||
|
{
|
||||||
|
std::list<CAssetID> WorldIDs;
|
||||||
|
pProj->GetWorldList(WorldIDs);
|
||||||
|
QList<CAssetID> QWorldIDs = QList<CAssetID>::fromStdList(WorldIDs);
|
||||||
|
|
||||||
|
foreach (const CAssetID& rkID, QWorldIDs)
|
||||||
|
{
|
||||||
|
CResourceEntry *pEntry = pProj->ResourceStore()->FindEntry(rkID);
|
||||||
|
|
||||||
|
if (pEntry)
|
||||||
|
{
|
||||||
|
TResPtr<CWorld> pWorld = pEntry->Load();
|
||||||
|
|
||||||
|
if (pWorld)
|
||||||
|
{
|
||||||
|
SWorldInfo Info;
|
||||||
|
Info.pWorld = pWorld;
|
||||||
|
|
||||||
|
for (u32 iArea = 0; iArea < pWorld->NumAreas(); iArea++)
|
||||||
|
{
|
||||||
|
CAssetID AreaID = pWorld->AreaResourceID(iArea);
|
||||||
|
CResourceEntry *pAreaEntry = pWorld->Entry()->ResourceStore()->FindEntry(AreaID);
|
||||||
|
ASSERT(pAreaEntry);
|
||||||
|
Info.Areas << pAreaEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
mWorldList << Info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWorldTreeModel::OnMapChanged()
|
||||||
|
{
|
||||||
|
// Flag all data as changed to ensure the font updates correctly based on which areas are loaded
|
||||||
|
// note we don't know which areas used to be loaded, so flagging those specific indices isn't an option
|
||||||
|
int MaxRow = rowCount(QModelIndex()) - 1;
|
||||||
|
int MaxCol = columnCount(QModelIndex()) - 1;
|
||||||
|
emit dataChanged(index(0, 0, QModelIndex()), index(MaxRow, MaxCol, QModelIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************ PROXY MODEL ************
|
||||||
|
bool CWorldTreeProxyModel::lessThan(const QModelIndex& rkSourceLeft, const QModelIndex& rkSourceRight) const
|
||||||
|
{
|
||||||
|
CWorldTreeModel *pModel = qobject_cast<CWorldTreeModel*>(sourceModel());
|
||||||
|
ASSERT(pModel != nullptr);
|
||||||
|
|
||||||
|
if (pModel->IndexIsWorld(rkSourceLeft))
|
||||||
|
{
|
||||||
|
ASSERT(pModel->IndexIsWorld(rkSourceRight));
|
||||||
|
bool IsLessThan = (rkSourceLeft.row() < rkSourceRight.row());
|
||||||
|
return (sortOrder() == Qt::AscendingOrder ? IsLessThan : !IsLessThan);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return pModel->data(rkSourceLeft, Qt::DisplayRole).toString().toUpper() < pModel->data(rkSourceRight, Qt::DisplayRole).toString().toUpper();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWorldTreeProxyModel::filterAcceptsRow(int SourceRow, const QModelIndex& rkSourceParent) const
|
||||||
|
{
|
||||||
|
// Always accept worlds
|
||||||
|
if (!rkSourceParent.isValid() || mFilterString.isEmpty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CWorldTreeModel *pModel = qobject_cast<CWorldTreeModel*>(sourceModel());
|
||||||
|
ASSERT(pModel != nullptr);
|
||||||
|
|
||||||
|
for (int iCol = 0; iCol < pModel->columnCount(rkSourceParent); iCol++)
|
||||||
|
{
|
||||||
|
QModelIndex Index = pModel->index(SourceRow, iCol, rkSourceParent);
|
||||||
|
if (pModel->data(Index, Qt::DisplayRole).toString().contains(mFilterString, Qt::CaseInsensitive))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef CWORLDTREEMODEL_H
|
||||||
|
#define CWORLDTREEMODEL_H
|
||||||
|
|
||||||
|
#include <Core/Resource/CWorld.h>
|
||||||
|
#include <QAbstractItemModel>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
class CWorldEditor;
|
||||||
|
|
||||||
|
class CWorldTreeModel : public QAbstractItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
struct SWorldInfo
|
||||||
|
{
|
||||||
|
TResPtr<CWorld> pWorld;
|
||||||
|
QList<CResourceEntry*> Areas;
|
||||||
|
};
|
||||||
|
QList<SWorldInfo> mWorldList;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CWorldTreeModel(CWorldEditor *pEditor);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex& rkParent) const;
|
||||||
|
int columnCount(const QModelIndex& rkParent) const;
|
||||||
|
QModelIndex index(int Row, int Column, const QModelIndex& rkParent) const;
|
||||||
|
QModelIndex parent(const QModelIndex& rkChild) const;
|
||||||
|
QVariant data(const QModelIndex& rkIndex, int Role) const;
|
||||||
|
QVariant headerData(int Section, Qt::Orientation Orientation, int Role) const;
|
||||||
|
|
||||||
|
bool IndexIsWorld(const QModelIndex& rkIndex) const;
|
||||||
|
CWorld* WorldForIndex(const QModelIndex& rkIndex) const;
|
||||||
|
int AreaIndexForIndex(const QModelIndex& rkIndex) const;
|
||||||
|
CResourceEntry* AreaEntryForIndex(const QModelIndex& rkIndex) const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void OnProjectChanged(CGameProject *pProj);
|
||||||
|
void OnMapChanged();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Proxy Model
|
||||||
|
class CWorldTreeProxyModel : public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
QString mFilterString;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool lessThan(const QModelIndex& rkSourceLeft, const QModelIndex& rkSourceRight) const;
|
||||||
|
bool filterAcceptsRow(int SourceRow, const QModelIndex& rkSourceParent) const;
|
||||||
|
|
||||||
|
inline void SetFilterString(const QString& rkFilter) { mFilterString = rkFilter; invalidate(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CWORLDTREEMODEL_H
|
|
@ -4,13 +4,17 @@
|
||||||
#include "CWorldEditor.h"
|
#include "CWorldEditor.h"
|
||||||
#include "Editor/Undo/UndoCommands.h"
|
#include "Editor/Undo/UndoCommands.h"
|
||||||
|
|
||||||
WCreateTab::WCreateTab(QWidget *parent)
|
WCreateTab::WCreateTab(CWorldEditor *pEditor, QWidget *pParent /*= 0*/)
|
||||||
: QWidget(parent)
|
: QWidget(pParent)
|
||||||
, ui(new Ui::WCreateTab)
|
, ui(new Ui::WCreateTab)
|
||||||
, mpSpawnLayer(nullptr)
|
, mpSpawnLayer(nullptr)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
mpEditor = pEditor;
|
||||||
|
mpEditor->Viewport()->installEventFilter(this);
|
||||||
|
connect(mpEditor, SIGNAL(LayersModified()), this, SLOT(OnLayersChanged()));
|
||||||
|
|
||||||
connect(ui->SpawnLayerComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSpawnLayerChanged(int)));
|
connect(ui->SpawnLayerComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSpawnLayerChanged(int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,19 +56,14 @@ bool WCreateTab::eventFilter(QObject *pObj, QEvent *pEvent)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WCreateTab::SetEditor(CWorldEditor *pEditor)
|
// ************ PUBLIC SLOTS ************
|
||||||
{
|
void WCreateTab::OnMapChanged()
|
||||||
mpEditor = pEditor;
|
|
||||||
pEditor->Viewport()->installEventFilter(this);
|
|
||||||
connect(mpEditor, SIGNAL(LayersModified()), this, SLOT(OnLayersChanged()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WCreateTab::SetMaster(CMasterTemplate *pMaster)
|
|
||||||
{
|
{
|
||||||
|
EGame Game = mpEditor->CurrentGame();
|
||||||
|
CMasterTemplate *pMaster = CMasterTemplate::MasterForGame(Game);
|
||||||
ui->TemplateView->SetMaster(pMaster);
|
ui->TemplateView->SetMaster(pMaster);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ PUBLIC SLOTS ************
|
|
||||||
void WCreateTab::OnLayersChanged()
|
void WCreateTab::OnLayersChanged()
|
||||||
{
|
{
|
||||||
CGameArea *pArea = mpEditor->ActiveArea();
|
CGameArea *pArea = mpEditor->ActiveArea();
|
||||||
|
|
|
@ -16,16 +16,15 @@ class WCreateTab : public QWidget
|
||||||
CScriptLayer *mpSpawnLayer;
|
CScriptLayer *mpSpawnLayer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WCreateTab(QWidget *parent = 0);
|
explicit WCreateTab(CWorldEditor *pEditor, QWidget *parent = 0);
|
||||||
~WCreateTab();
|
~WCreateTab();
|
||||||
bool eventFilter(QObject *, QEvent *);
|
bool eventFilter(QObject *, QEvent *);
|
||||||
void SetEditor(CWorldEditor *pEditor);
|
|
||||||
void SetMaster(CMasterTemplate *pMaster);
|
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
inline CScriptLayer* SpawnLayer() const { return mpSpawnLayer; }
|
inline CScriptLayer* SpawnLayer() const { return mpSpawnLayer; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void OnMapChanged();
|
||||||
void OnLayersChanged();
|
void OnLayersChanged();
|
||||||
void OnSpawnLayerChanged(int LayerIndex);
|
void OnSpawnLayerChanged(int LayerIndex);
|
||||||
|
|
||||||
|
|
|
@ -6,17 +6,22 @@
|
||||||
#include <Core/Scene/CScene.h>
|
#include <Core/Scene/CScene.h>
|
||||||
#include <Core/Scene/CSceneIterator.h>
|
#include <Core/Scene/CSceneIterator.h>
|
||||||
|
|
||||||
WInstancesTab::WInstancesTab(QWidget *parent) :
|
WInstancesTab::WInstancesTab(CWorldEditor *pEditor, QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
ui(new Ui::WInstancesTab)
|
ui(new Ui::WInstancesTab)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
mpEditor = nullptr;
|
mpEditor = pEditor;
|
||||||
|
mpScene = mpEditor->Scene();
|
||||||
|
connect(mpEditor, SIGNAL(MapChanged(CWorld*,CGameArea*)), this, SLOT(OnMapChange(CWorld*,CGameArea*)));
|
||||||
|
|
||||||
mpLayersModel = new CInstancesModel(this);
|
mpLayersModel = new CInstancesModel(this);
|
||||||
mpLayersModel->SetModelType(CInstancesModel::eLayers);
|
mpLayersModel->SetModelType(CInstancesModel::eLayers);
|
||||||
|
mpLayersModel->SetEditor(mpEditor);
|
||||||
mpTypesModel = new CInstancesModel(this);
|
mpTypesModel = new CInstancesModel(this);
|
||||||
mpTypesModel->SetModelType(CInstancesModel::eTypes);
|
mpTypesModel->SetModelType(CInstancesModel::eTypes);
|
||||||
|
mpTypesModel->SetEditor(mpEditor);
|
||||||
mLayersProxyModel.setSourceModel(mpLayersModel);
|
mLayersProxyModel.setSourceModel(mpLayersModel);
|
||||||
mTypesProxyModel.setSourceModel(mpTypesModel);
|
mTypesProxyModel.setSourceModel(mpTypesModel);
|
||||||
|
|
||||||
|
@ -73,27 +78,16 @@ WInstancesTab::~WInstancesTab()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WInstancesTab::SetEditor(CWorldEditor *pEditor, CScene *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 ************
|
// ************ PRIVATE SLOTS ************
|
||||||
|
void WInstancesTab::OnMapChange(CWorld*, CGameArea *pNewArea)
|
||||||
|
{
|
||||||
|
EGame Game = mpEditor->CurrentGame();
|
||||||
|
CMasterTemplate *pMaster = CMasterTemplate::MasterForGame(Game);
|
||||||
|
mpTypesModel->SetMaster(pMaster);
|
||||||
|
mpLayersModel->SetArea(pNewArea);
|
||||||
|
ExpandTopLevelItems();
|
||||||
|
}
|
||||||
|
|
||||||
void WInstancesTab::OnTreeClick(QModelIndex Index)
|
void WInstancesTab::OnTreeClick(QModelIndex Index)
|
||||||
{
|
{
|
||||||
// Single click is used to process show/hide events
|
// Single click is used to process show/hide events
|
||||||
|
|
|
@ -43,13 +43,11 @@ class WInstancesTab : public QWidget
|
||||||
CInstancesModel::EIndexType mMenuIndexType;
|
CInstancesModel::EIndexType mMenuIndexType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WInstancesTab(QWidget *parent = 0);
|
explicit WInstancesTab(CWorldEditor *pEditor, QWidget *parent = 0);
|
||||||
~WInstancesTab();
|
~WInstancesTab();
|
||||||
void SetEditor(CWorldEditor *pEditor, CScene *pScene);
|
|
||||||
void SetMaster(CMasterTemplate *pMaster);
|
|
||||||
void SetArea(CGameArea *pArea);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void OnMapChange(CWorld*, CGameArea *pNewArea);
|
||||||
void OnTreeClick(QModelIndex Index);
|
void OnTreeClick(QModelIndex Index);
|
||||||
void OnTreeDoubleClick(QModelIndex Index);
|
void OnTreeDoubleClick(QModelIndex Index);
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,16 @@
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
|
|
||||||
WModifyTab::WModifyTab(QWidget *pParent)
|
WModifyTab::WModifyTab(CWorldEditor *pEditor, QWidget *pParent)
|
||||||
: QWidget(pParent)
|
: QWidget(pParent)
|
||||||
, ui(new Ui::WModifyTab)
|
, ui(new Ui::WModifyTab)
|
||||||
, mIsPicking(false)
|
, mIsPicking(false)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
mpWorldEditor = pEditor;
|
||||||
|
ui->PropertyView->SetEditor(mpWorldEditor);
|
||||||
|
|
||||||
int PropViewWidth = ui->PropertyView->width();
|
int PropViewWidth = ui->PropertyView->width();
|
||||||
ui->PropertyView->header()->resizeSection(0, PropViewWidth * 0.3);
|
ui->PropertyView->header()->resizeSection(0, PropViewWidth * 0.3);
|
||||||
ui->PropertyView->header()->resizeSection(1, PropViewWidth * 0.3);
|
ui->PropertyView->header()->resizeSection(1, PropViewWidth * 0.3);
|
||||||
|
@ -49,6 +52,10 @@ WModifyTab::WModifyTab(QWidget *pParent)
|
||||||
connect(ui->DeleteIncomingConnectionButton, SIGNAL(clicked()), this, SLOT(OnDeleteLinksClicked()));
|
connect(ui->DeleteIncomingConnectionButton, SIGNAL(clicked()), this, SLOT(OnDeleteLinksClicked()));
|
||||||
connect(ui->EditOutgoingConnectionButton, SIGNAL(clicked()), this, SLOT(OnEditLinkClicked()));
|
connect(ui->EditOutgoingConnectionButton, SIGNAL(clicked()), this, SLOT(OnEditLinkClicked()));
|
||||||
connect(ui->EditIncomingConnectionButton, SIGNAL(clicked()), this, SLOT(OnEditLinkClicked()));
|
connect(ui->EditIncomingConnectionButton, SIGNAL(clicked()), this, SLOT(OnEditLinkClicked()));
|
||||||
|
connect(mpWorldEditor, SIGNAL(MapChanged(CWorld*,CGameArea*)), this, SLOT(OnMapChanged()));
|
||||||
|
connect(mpWorldEditor, SIGNAL(SelectionTransformed()), this, SLOT(OnWorldSelectionTransformed()));
|
||||||
|
connect(mpWorldEditor, SIGNAL(InstanceLinksModified(const QList<CScriptObject*>&)), this, SLOT(OnInstanceLinksModified(const QList<CScriptObject*>&)));
|
||||||
|
connect(mpWorldEditor->Selection(), SIGNAL(Modified()), this, SLOT(GenerateUI()));
|
||||||
|
|
||||||
ClearUI();
|
ClearUI();
|
||||||
}
|
}
|
||||||
|
@ -58,15 +65,6 @@ WModifyTab::~WModifyTab()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WModifyTab::SetEditor(CWorldEditor *pEditor)
|
|
||||||
{
|
|
||||||
mpWorldEditor = pEditor;
|
|
||||||
ui->PropertyView->SetEditor(mpWorldEditor);
|
|
||||||
connect(mpWorldEditor, SIGNAL(SelectionTransformed()), this, SLOT(OnWorldSelectionTransformed()));
|
|
||||||
connect(mpWorldEditor, SIGNAL(InstanceLinksModified(const QList<CScriptObject*>&)), this, SLOT(OnInstanceLinksModified(const QList<CScriptObject*>&)));
|
|
||||||
connect(mpWorldEditor->Selection(), SIGNAL(Modified()), this, SLOT(GenerateUI()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WModifyTab::ClearUI()
|
void WModifyTab::ClearUI()
|
||||||
{
|
{
|
||||||
ui->ObjectsTabWidget->hide();
|
ui->ObjectsTabWidget->hide();
|
||||||
|
@ -131,6 +129,11 @@ void WModifyTab::OnWorldSelectionTransformed()
|
||||||
ui->PropertyView->UpdateEditorProperties(QModelIndex());
|
ui->PropertyView->UpdateEditorProperties(QModelIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WModifyTab::OnMapChanged()
|
||||||
|
{
|
||||||
|
ClearUI();
|
||||||
|
}
|
||||||
|
|
||||||
void WModifyTab::OnLinksSelectionModified()
|
void WModifyTab::OnLinksSelectionModified()
|
||||||
{
|
{
|
||||||
if (sender() == ui->InLinksTableView->selectionModel())
|
if (sender() == ui->InLinksTableView->selectionModel())
|
||||||
|
|
|
@ -34,15 +34,15 @@ class WModifyTab : public QWidget
|
||||||
bool mIsPicking;
|
bool mIsPicking;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WModifyTab(QWidget *pParent = 0);
|
explicit WModifyTab(CWorldEditor *pEditor, QWidget *pParent = 0);
|
||||||
~WModifyTab();
|
~WModifyTab();
|
||||||
void SetEditor(CWorldEditor *pEditor);
|
|
||||||
void ClearUI();
|
void ClearUI();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void GenerateUI();
|
void GenerateUI();
|
||||||
void OnInstanceLinksModified(const QList<CScriptObject*>& rkInstances);
|
void OnInstanceLinksModified(const QList<CScriptObject*>& rkInstances);
|
||||||
void OnWorldSelectionTransformed();
|
void OnWorldSelectionTransformed();
|
||||||
|
void OnMapChanged();
|
||||||
|
|
||||||
void OnLinksSelectionModified();
|
void OnLinksSelectionModified();
|
||||||
void OnAddLinkActionClicked(QAction *pAction);
|
void OnAddLinkActionClicked(QAction *pAction);
|
||||||
|
|
Loading…
Reference in New Issue