Initial work towards making the World Editor the main application window
This commit is contained in:
parent
568cd67994
commit
9928a599be
|
@ -142,7 +142,8 @@ void CScriptInstanceDependency::ParseStructDependencies(CScriptInstanceDependenc
|
|||
|
||||
if (SoundID != -1)
|
||||
{
|
||||
SSoundInfo Info = CGameProject::ActiveProject()->AudioManager()->GetSoundInfo(SoundID);
|
||||
CGameProject *pProj = pStruct->Instance()->Area()->Entry()->Project();
|
||||
SSoundInfo Info = pProj->AudioManager()->GetSoundInfo(SoundID);
|
||||
|
||||
if (Info.pAudioGroup)
|
||||
{
|
||||
|
|
|
@ -53,8 +53,6 @@ bool CGameExporter::Export(nod::DiscBase *pDisc, const TString& rkOutputDir, CAs
|
|||
return false;
|
||||
|
||||
// Create project
|
||||
CGameProject *pOldActiveProj = CGameProject::ActiveProject();
|
||||
|
||||
mpProject = CGameProject::CreateProjectForExport(
|
||||
this,
|
||||
mExportDir,
|
||||
|
@ -68,11 +66,13 @@ bool CGameExporter::Export(nod::DiscBase *pDisc, const TString& rkOutputDir, CAs
|
|||
mFilesystemAddress);
|
||||
|
||||
mpProject->SetProjectName(mGameName);
|
||||
mpProject->SetActive();
|
||||
mpStore = mpProject->ResourceStore();
|
||||
mContentDir = mpStore->RawDir(false);
|
||||
mCookedDir = mpStore->CookedDir(false);
|
||||
|
||||
CResourceStore *pOldStore = gpResourceStore;
|
||||
gpResourceStore = mpStore;
|
||||
|
||||
// Export game data
|
||||
LoadPaks();
|
||||
ExportCookedResources();
|
||||
|
@ -82,7 +82,7 @@ bool CGameExporter::Export(nod::DiscBase *pDisc, const TString& rkOutputDir, CAs
|
|||
// Export finished!
|
||||
mProjectPath = mpProject->ProjectPath();
|
||||
delete mpProject;
|
||||
if (pOldActiveProj) pOldActiveProj->SetActive();
|
||||
if (pOldStore) gpResourceStore = pOldStore;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,19 +3,14 @@
|
|||
#include "Core/Resource/Script/CMasterTemplate.h"
|
||||
#include <Common/Serialization/XML.h>
|
||||
|
||||
CGameProject *CGameProject::mspActiveProject = nullptr;
|
||||
|
||||
CGameProject::~CGameProject()
|
||||
{
|
||||
if (mpResourceStore)
|
||||
{
|
||||
ASSERT(!mpResourceStore->IsDirty());
|
||||
}
|
||||
|
||||
if (IsActive())
|
||||
{
|
||||
mspActiveProject = nullptr;
|
||||
gpResourceStore = nullptr;
|
||||
if (gpResourceStore == mpResourceStore)
|
||||
gpResourceStore = nullptr;
|
||||
}
|
||||
|
||||
for (u32 iPkg = 0; iPkg < mPackages.size(); iPkg++)
|
||||
|
@ -99,15 +94,6 @@ void CGameProject::Serialize(IArchive& rArc)
|
|||
}
|
||||
}
|
||||
|
||||
void CGameProject::SetActive()
|
||||
{
|
||||
if (mspActiveProject != this)
|
||||
{
|
||||
mspActiveProject = this;
|
||||
gpResourceStore = mpResourceStore;
|
||||
}
|
||||
}
|
||||
|
||||
void CGameProject::GetWorldList(std::list<CAssetID>& rOut) const
|
||||
{
|
||||
for (u32 iPkg = 0; iPkg < mPackages.size(); iPkg++)
|
||||
|
|
|
@ -45,8 +45,6 @@ class CGameProject
|
|||
eVer_Current = eVer_Max - 1
|
||||
};
|
||||
|
||||
static CGameProject *mspActiveProject;
|
||||
|
||||
// Private Constructor
|
||||
CGameProject()
|
||||
: mProjectName("Unnamed Project")
|
||||
|
@ -67,7 +65,6 @@ public:
|
|||
|
||||
bool Save();
|
||||
void Serialize(IArchive& rArc);
|
||||
void SetActive();
|
||||
void GetWorldList(std::list<CAssetID>& rOut) const;
|
||||
CAssetID FindNamedResource(const TString& rkName) const;
|
||||
|
||||
|
@ -107,10 +104,7 @@ public:
|
|||
inline CAudioManager* AudioManager() const { return mpAudioManager; }
|
||||
inline EGame Game() const { return mGame; }
|
||||
inline float BuildVersion() const { return mBuildVersion; }
|
||||
inline bool IsActive() const { return mspActiveProject == this; }
|
||||
inline bool IsWiiBuild() const { return mBuildVersion >= 3.f; }
|
||||
|
||||
static inline CGameProject* ActiveProject() { return mspActiveProject; }
|
||||
};
|
||||
|
||||
#endif // CGAMEPROJECT_H
|
||||
|
|
|
@ -497,3 +497,8 @@ void CResourceEntry::RemoveFromProject()
|
|||
Log::Error("RemoveFromProject called on transient resource entry: " + CookedAssetPath(true));
|
||||
}
|
||||
}
|
||||
|
||||
CGameProject* CResourceEntry::Project() const
|
||||
{
|
||||
return mpStore->Project();
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
class CResource;
|
||||
class CResourceStore;
|
||||
class CGameProject;
|
||||
class CDependencyTree;
|
||||
|
||||
enum EResEntryFlag
|
||||
|
@ -68,6 +69,7 @@ public:
|
|||
bool Move(const TWideString& rkDir, const TWideString& rkName);
|
||||
void AddToProject(const TWideString& rkDir, const TWideString& rkName);
|
||||
void RemoveFromProject();
|
||||
CGameProject* Project() const;
|
||||
|
||||
// Accessors
|
||||
void SetDirty() { mFlags.SetFlag(eREF_NeedsRecook); }
|
||||
|
|
|
@ -41,7 +41,7 @@ TResPtr<CTexture> CDrawUtil::mpLightMasks[4];
|
|||
bool CDrawUtil::mDrawUtilInitialized = false;
|
||||
|
||||
// ************ PUBLIC ************
|
||||
void CDrawUtil::DrawGrid()
|
||||
void CDrawUtil::DrawGrid(CColor LineColor, CColor BoldLineColor)
|
||||
{
|
||||
Init();
|
||||
|
||||
|
@ -55,11 +55,13 @@ void CDrawUtil::DrawGrid()
|
|||
glDepthMask(GL_TRUE);
|
||||
|
||||
glLineWidth(1.0f);
|
||||
UseColorShader(CColor(0.6f, 0.6f, 0.6f, 0.f));
|
||||
LineColor.A = 0.f;
|
||||
UseColorShader(LineColor);
|
||||
mGridIndices.DrawElements(0, mGridIndices.GetSize() - 4);
|
||||
|
||||
glLineWidth(1.5f);
|
||||
UseColorShader(CColor::skTransparentBlack);
|
||||
BoldLineColor.A = 0.f;
|
||||
UseColorShader(BoldLineColor);
|
||||
mGridIndices.DrawElements(mGridIndices.GetSize() - 4, 4);
|
||||
}
|
||||
|
||||
|
@ -405,25 +407,32 @@ void CDrawUtil::Init()
|
|||
void CDrawUtil::InitGrid()
|
||||
{
|
||||
Log::Write("Creating grid");
|
||||
mGridVertices.SetVertexDesc(ePosition);
|
||||
mGridVertices.Reserve(64);
|
||||
|
||||
for (s32 i = -7; i < 8; i++)
|
||||
const int kGridSize = 501; // must be odd
|
||||
const float kGridSpacing = 1.f;
|
||||
int MinIdx = (kGridSize - 1) / -2;
|
||||
int MaxIdx = (kGridSize - 1) / 2;
|
||||
|
||||
mGridVertices.SetVertexDesc(ePosition);
|
||||
mGridVertices.Reserve(kGridSize * 4);
|
||||
|
||||
for (s32 i = MinIdx; i <= MaxIdx; i++)
|
||||
{
|
||||
if (i == 0) continue;
|
||||
mGridVertices.AddVertex(CVector3f(-7.0f, float(i), 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f( 7.0f, float(i), 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f(float(i), -7.0f, 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f(float(i), 7.0f, 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f(MinIdx * kGridSpacing, i * kGridSpacing, 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f(MaxIdx * kGridSpacing, i * kGridSpacing, 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f(i * kGridSpacing, MinIdx * kGridSpacing, 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f(i * kGridSpacing, MaxIdx * kGridSpacing, 0.0f));
|
||||
}
|
||||
|
||||
mGridVertices.AddVertex(CVector3f(-7.0f, 0, 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f( 7.0f, 0, 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f(0, -7.0f, 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f(0, 7.0f, 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f(MinIdx * kGridSpacing, 0, 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f(MaxIdx * kGridSpacing, 0, 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f(0, MinIdx * kGridSpacing, 0.0f));
|
||||
mGridVertices.AddVertex(CVector3f(0, MaxIdx * kGridSpacing, 0.0f));
|
||||
|
||||
mGridIndices.Reserve(60);
|
||||
for (u16 i = 0; i < 60; i++) mGridIndices.AddIndex(i);
|
||||
int NumIndices = kGridSize * 4;
|
||||
mGridIndices.Reserve(NumIndices);
|
||||
for (u16 i = 0; i < NumIndices; i++) mGridIndices.AddIndex(i);
|
||||
mGridIndices.SetPrimitiveType(GL_LINES);
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ class CDrawUtil
|
|||
static bool mDrawUtilInitialized;
|
||||
|
||||
public:
|
||||
static void DrawGrid();
|
||||
static void DrawGrid(CColor LineColor, CColor BoldLineColor);
|
||||
|
||||
static void DrawSquare();
|
||||
static void DrawSquare(const CVector2f& TexUL, const CVector2f& TexUR, const CVector2f& TexBR, const CVector2f& TexBL);
|
||||
|
|
|
@ -67,7 +67,7 @@ void CAnimEventLoader::LoadEvents(IInputStream& rEVNT, bool IsEchoes)
|
|||
|
||||
if (SoundID != 0xFFFF)
|
||||
{
|
||||
SSoundInfo SoundInfo = CGameProject::ActiveProject()->AudioManager()->GetSoundInfo(SoundID);
|
||||
SSoundInfo SoundInfo = mpEventData->Entry()->Project()->AudioManager()->GetSoundInfo(SoundID);
|
||||
|
||||
if (SoundInfo.pAudioGroup)
|
||||
mpEventData->AddEvent(CharIndex, SoundInfo.pAudioGroup->ID());
|
||||
|
|
|
@ -1298,7 +1298,7 @@ void CUnsupportedParticleLoader::ParseSoundFunction(IInputStream& rFile)
|
|||
|
||||
if (SoundID != 0xFFFF)
|
||||
{
|
||||
SSoundInfo SoundInfo = CGameProject::ActiveProject()->AudioManager()->GetSoundInfo(SoundID);
|
||||
SSoundInfo SoundInfo = mpGroup->Entry()->Project()->AudioManager()->GetSoundInfo(SoundID);
|
||||
mpGroup->AddDependency(SoundInfo.pAudioGroup);
|
||||
}
|
||||
|
||||
|
|
|
@ -293,8 +293,6 @@ void CSceneNode::Rotate(const CQuaternion& rkRotation, ETransformSpace Transform
|
|||
|
||||
void CSceneNode::Rotate(const CQuaternion& rkRotation, const CVector3f& rkPivot, const CQuaternion& rkPivotRotation, ETransformSpace TransformSpace)
|
||||
{
|
||||
Rotate(rkRotation, TransformSpace);
|
||||
|
||||
switch (TransformSpace)
|
||||
{
|
||||
case eWorldTransform:
|
||||
|
@ -304,7 +302,7 @@ void CSceneNode::Rotate(const CQuaternion& rkRotation, const CVector3f& rkPivot,
|
|||
mPosition = rkPivot + ((rkPivotRotation * rkRotation * rkPivotRotation.Inverse()) * (mPosition - rkPivot));
|
||||
break;
|
||||
}
|
||||
MarkTransformChanged();
|
||||
Rotate(rkRotation, TransformSpace);
|
||||
}
|
||||
|
||||
void CSceneNode::Scale(const CVector3f& rkScale)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
CEditorApplication::CEditorApplication(int& rArgc, char **ppArgv)
|
||||
: QApplication(rArgc, ppArgv)
|
||||
, mpActiveProject(nullptr)
|
||||
, mpWorldEditor(nullptr)
|
||||
, mpResourceBrowser(nullptr)
|
||||
, mpProjectDialog(nullptr)
|
||||
|
@ -34,9 +35,56 @@ void CEditorApplication::InitEditor()
|
|||
mpWorldEditor = new CWorldEditor();
|
||||
mpResourceBrowser = new CResourceBrowser(mpWorldEditor);
|
||||
mpProjectDialog = new CProjectOverviewDialog();
|
||||
connect(mpProjectDialog, SIGNAL(ActiveProjectChanged(CGameProject*)), mpResourceBrowser, SLOT(UpdateStore()));
|
||||
mpWorldEditor->showMaximized();
|
||||
}
|
||||
|
||||
mpProjectDialog->show();
|
||||
bool CEditorApplication::CloseProject()
|
||||
{
|
||||
if (mpActiveProject)
|
||||
{
|
||||
// Close active editor windows. todo: check for unsaved changes
|
||||
foreach (IEditor *pEditor, mEditorWindows)
|
||||
{
|
||||
if (pEditor != mpWorldEditor && !pEditor->close())
|
||||
return false;
|
||||
}
|
||||
|
||||
// Close world
|
||||
if (!mpWorldEditor->CloseWorld())
|
||||
return false;
|
||||
|
||||
mpResourceBrowser->close();
|
||||
mpProjectDialog->close();
|
||||
|
||||
delete mpActiveProject;
|
||||
mpActiveProject = nullptr;
|
||||
emit ActiveProjectChanged(nullptr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CEditorApplication::OpenProject(const QString& rkProjPath)
|
||||
{
|
||||
// Close existing project
|
||||
if (!CloseProject())
|
||||
return false;
|
||||
|
||||
// Load new project
|
||||
TWideString Path = TO_TWIDESTRING(rkProjPath);
|
||||
mpActiveProject = CGameProject::LoadProject(Path);
|
||||
|
||||
if (mpActiveProject)
|
||||
{
|
||||
gpResourceStore = mpActiveProject->ResourceStore();
|
||||
emit ActiveProjectChanged(mpActiveProject);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
UICommon::ErrorMsg(mpWorldEditor, "Failed to open project! Is it already open in another Prime World Editor instance?");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CEditorApplication::EditResource(CResourceEntry *pEntry)
|
||||
|
@ -58,7 +106,7 @@ void CEditorApplication::EditResource(CResourceEntry *pEntry)
|
|||
|
||||
if (!pRes)
|
||||
{
|
||||
QMessageBox::warning(nullptr, "Error", "Failed to load resource!");
|
||||
UICommon::ErrorMsg(mpWorldEditor, "Failed to load resource!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -82,7 +130,7 @@ void CEditorApplication::EditResource(CResourceEntry *pEntry)
|
|||
mEditingMap[pEntry] = pEd;
|
||||
}
|
||||
else
|
||||
QMessageBox::information(0, "Unsupported Resource", "This resource type is currently unsupported for editing.");
|
||||
UICommon::InfoMsg(mpWorldEditor, "Unsupported Resource", "This resource type is currently unsupported for editing.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,19 +141,20 @@ void CEditorApplication::NotifyAssetsModified()
|
|||
|
||||
void CEditorApplication::CookAllDirtyPackages()
|
||||
{
|
||||
CGameProject *pProj = CGameProject::ActiveProject();
|
||||
ASSERT(mpActiveProject != nullptr);
|
||||
|
||||
for (u32 iPkg = 0; iPkg < pProj->NumPackages(); iPkg++)
|
||||
for (u32 iPkg = 0; iPkg < mpActiveProject->NumPackages(); iPkg++)
|
||||
{
|
||||
CPackage *pPackage = pProj->PackageByIndex(iPkg);
|
||||
CPackage *pPackage = mpActiveProject->PackageByIndex(iPkg);
|
||||
|
||||
if (pPackage->NeedsRecook())
|
||||
pPackage->Cook();
|
||||
}
|
||||
|
||||
mpProjectDialog->SetupPackagesList();
|
||||
emit PackagesCooked();
|
||||
}
|
||||
|
||||
// ************ SLOTS ************
|
||||
void CEditorApplication::AddEditor(IEditor *pEditor)
|
||||
{
|
||||
mEditorWindows << pEditor;
|
||||
|
@ -149,7 +198,7 @@ void CEditorApplication::OnEditorClose()
|
|||
IEditor *pEditor = qobject_cast<IEditor*>(sender());
|
||||
ASSERT(pEditor);
|
||||
|
||||
if (qobject_cast<CWorldEditor*>(pEditor) == nullptr)
|
||||
if (pEditor != mpWorldEditor)
|
||||
{
|
||||
for (auto Iter = mEditingMap.begin(); Iter != mEditingMap.end(); Iter++)
|
||||
{
|
||||
|
@ -162,7 +211,7 @@ void CEditorApplication::OnEditorClose()
|
|||
|
||||
mEditorWindows.removeOne(pEditor);
|
||||
delete pEditor;
|
||||
}
|
||||
|
||||
CGameProject::ActiveProject()->ResourceStore()->DestroyUnreferencedResources();
|
||||
mpActiveProject->ResourceStore()->DestroyUnreferencedResources();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CEDITORAPPLICATION_H
|
||||
#define CEDITORAPPLICATION_H
|
||||
|
||||
#include <Core/GameProject/CGameProject.h>
|
||||
#include <QApplication>
|
||||
#include <QTimer>
|
||||
#include <QVector>
|
||||
|
@ -18,23 +19,28 @@ class CEditorApplication : public QApplication
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
QTimer mRefreshTimer;
|
||||
CGameProject *mpActiveProject;
|
||||
CWorldEditor *mpWorldEditor;
|
||||
CResourceBrowser *mpResourceBrowser;
|
||||
CProjectOverviewDialog *mpProjectDialog;
|
||||
QVector<IEditor*> mEditorWindows;
|
||||
QMap<CResourceEntry*,IEditor*> mEditingMap;
|
||||
|
||||
QTimer mRefreshTimer;
|
||||
double mLastUpdate;
|
||||
|
||||
public:
|
||||
CEditorApplication(int& rArgc, char **ppArgv);
|
||||
~CEditorApplication();
|
||||
void InitEditor();
|
||||
bool CloseProject();
|
||||
bool OpenProject(const QString& rkProjPath);
|
||||
void EditResource(CResourceEntry *pEntry);
|
||||
void NotifyAssetsModified();
|
||||
void CookAllDirtyPackages();
|
||||
|
||||
// Accessors
|
||||
inline CGameProject* ActiveProject() const { return mpActiveProject; }
|
||||
inline CWorldEditor* WorldEditor() const { return mpWorldEditor; }
|
||||
inline CResourceBrowser* ResourceBrowser() const { return mpResourceBrowser; }
|
||||
inline CProjectOverviewDialog* ProjectDialog() const { return mpProjectDialog; }
|
||||
|
@ -48,7 +54,9 @@ public slots:
|
|||
void OnEditorClose();
|
||||
|
||||
signals:
|
||||
void ActiveProjectChanged(CGameProject *pNewProj);
|
||||
void AssetsModified();
|
||||
void PackagesCooked();
|
||||
};
|
||||
|
||||
#define gpEdApp static_cast<CEditorApplication*>(qApp)
|
||||
|
|
|
@ -7,7 +7,21 @@
|
|||
// Tiny helper to make sure the grid draws at the correct depth.
|
||||
class CGridRenderable : public IRenderable
|
||||
{
|
||||
CColor mLineColor;
|
||||
CColor mBoldLineColor;
|
||||
|
||||
public:
|
||||
CGridRenderable()
|
||||
: mLineColor(0.6f, 0.6f, 0.6f, 0.f)
|
||||
, mBoldLineColor(0.f, 0.f, 0.f, 0.f)
|
||||
{}
|
||||
|
||||
inline void SetColor(const CColor& rkLineColor, const CColor& rkBoldColor)
|
||||
{
|
||||
mLineColor = rkLineColor;
|
||||
mBoldLineColor = rkBoldColor;
|
||||
}
|
||||
|
||||
void AddToRenderer(CRenderer *pRenderer, const SViewInfo&)
|
||||
{
|
||||
pRenderer->AddMesh(this, 0, CAABox::skOne, false, eDrawMesh);
|
||||
|
@ -15,7 +29,7 @@ public:
|
|||
|
||||
void Draw(FRenderOptions, int, ERenderCommand, const SViewInfo&)
|
||||
{
|
||||
CDrawUtil::DrawGrid();
|
||||
CDrawUtil::DrawGrid(mLineColor, mBoldLineColor);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -32,35 +32,6 @@ CProjectOverviewDialog::~CProjectOverviewDialog()
|
|||
delete mpUI;
|
||||
}
|
||||
|
||||
void CProjectOverviewDialog::InternalLoadProject(const QString& rkPath)
|
||||
{
|
||||
// Load project
|
||||
TWideString Path = TO_TWIDESTRING(rkPath);
|
||||
CGameProject *pNewProj = CGameProject::LoadProject(Path);
|
||||
|
||||
if (pNewProj)
|
||||
{
|
||||
if (mpProject) delete mpProject;
|
||||
mpProject = pNewProj;
|
||||
mpProject->SetActive();
|
||||
SetupWorldsList();
|
||||
SetupPackagesList();
|
||||
emit ActiveProjectChanged(mpProject);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
UICommon::ErrorMsg(this, "Failed to open project! Is it already open in another Prime World Editor instance?");
|
||||
}
|
||||
}
|
||||
|
||||
void CProjectOverviewDialog::OpenProject()
|
||||
{
|
||||
// Open project file
|
||||
QString ProjPath = UICommon::OpenFileDialog(this, "Open Project", "Game Project (*.prj)");
|
||||
if (!ProjPath.isEmpty()) InternalLoadProject(ProjPath);
|
||||
}
|
||||
|
||||
void CProjectOverviewDialog::ExportGame()
|
||||
{
|
||||
QString IsoPath = UICommon::OpenFileDialog(this, "Select ISO", "*.iso *.gcm *.tgc *.wbfs");
|
||||
|
@ -77,14 +48,12 @@ void CProjectOverviewDialog::ExportGame()
|
|||
int OpenChoice = QMessageBox::information(this, "Export complete", "Export finished successfully! Open new project?", QMessageBox::Yes, QMessageBox::No);
|
||||
|
||||
if (OpenChoice == QMessageBox::Yes)
|
||||
InternalLoadProject(ExportDialog.ProjectPath());
|
||||
gpEdApp->OpenProject(ExportDialog.ProjectPath());
|
||||
}
|
||||
}
|
||||
|
||||
void CProjectOverviewDialog::SetupWorldsList()
|
||||
{
|
||||
ASSERT(mpProject != nullptr && mpProject->IsActive());
|
||||
|
||||
std::list<CAssetID> WorldIDs;
|
||||
mpProject->GetWorldList(WorldIDs);
|
||||
mWorldEntries.clear();
|
||||
|
@ -111,7 +80,6 @@ void CProjectOverviewDialog::SetupWorldsList()
|
|||
|
||||
void CProjectOverviewDialog::SetupPackagesList()
|
||||
{
|
||||
ASSERT(mpProject != nullptr && mpProject->IsActive());
|
||||
mpUI->PackagesList->clear();
|
||||
|
||||
for (u32 iPkg = 0; iPkg < mpProject->NumPackages(); iPkg++)
|
||||
|
|
|
@ -24,11 +24,7 @@ public:
|
|||
explicit CProjectOverviewDialog(QWidget *pParent = 0);
|
||||
~CProjectOverviewDialog();
|
||||
|
||||
protected:
|
||||
void InternalLoadProject(const QString& rkPath);
|
||||
|
||||
public slots:
|
||||
void OpenProject();
|
||||
void ExportGame();
|
||||
void LoadWorld();
|
||||
void LaunchEditor();
|
||||
|
|
|
@ -20,6 +20,7 @@ CSceneViewport::CSceneViewport(QWidget *pParent)
|
|||
, mpContextMenu(nullptr)
|
||||
, mpMenuNode(nullptr)
|
||||
{
|
||||
mGrid.SetColor(CColor(0.f, 0.f, 0.6f, 0.f), CColor(0.f, 0.f, 1.f, 0.f));
|
||||
mLinkLine.SetColor(CColor::skYellow);
|
||||
|
||||
mpRenderer = new CRenderer();
|
||||
|
@ -299,6 +300,7 @@ void CSceneViewport::Paint()
|
|||
{
|
||||
if (!mpScene) return;
|
||||
|
||||
mpRenderer->SetClearColor(CColor::skBlack);
|
||||
mpRenderer->BeginFrame();
|
||||
|
||||
// todo: The sky should really just be a regular node in the background depth group instead of having special rendering code here
|
||||
|
@ -319,6 +321,10 @@ void CSceneViewport::Paint()
|
|||
pGizmo->AddToRenderer(mpRenderer, mViewInfo);
|
||||
}
|
||||
|
||||
// Draw grid if the scene is empty
|
||||
if (!mViewInfo.GameMode && mpScene->ActiveArea() == nullptr)
|
||||
mGrid.AddToRenderer(mpRenderer, mViewInfo);
|
||||
|
||||
// Draw the line for the link the user is editing.
|
||||
if (mLinkLineEnabled) mLinkLine.AddToRenderer(mpRenderer, mViewInfo);
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define CSCENEVIEWPORT_H
|
||||
|
||||
#include "CBasicViewport.h"
|
||||
#include "CGridRenderable.h"
|
||||
#include "CLineRenderable.h"
|
||||
#include "INodeEditor.h"
|
||||
|
||||
|
@ -40,6 +41,9 @@ class CSceneViewport : public CBasicViewport
|
|||
QAction *mpSelectConnectedIncomingAction;
|
||||
QAction *mpSelectConnectedAllAction;
|
||||
|
||||
// Grid
|
||||
CGridRenderable mGrid;
|
||||
|
||||
// Link Line
|
||||
bool mLinkLineEnabled;
|
||||
CLineRenderable mLinkLine;
|
||||
|
|
|
@ -297,7 +297,7 @@ QVariant CPropertyModel::data(const QModelIndex& rkIndex, int Role) const
|
|||
u32 SoundID = pSound->Get();
|
||||
if (SoundID == -1) return "[None]";
|
||||
|
||||
CGameProject *pProj = CGameProject::ActiveProject();
|
||||
CGameProject *pProj = pSound->Instance()->Area()->Entry()->Project();
|
||||
SSoundInfo SoundInfo = pProj->AudioManager()->GetSoundInfo(SoundID);
|
||||
|
||||
QString Out = QString::number(SoundID);
|
||||
|
|
|
@ -69,14 +69,15 @@ CResourceBrowser::CResourceBrowser(QWidget *pParent)
|
|||
QAction *pImportFromContentsTxtAction = new QAction("Import from Pak Contents List", this);
|
||||
pImportNamesMenu->addAction(pImportFromContentsTxtAction);
|
||||
|
||||
#if !PUBLIC_RELEASE
|
||||
QAction *pGenerateAssetNamesAction = new QAction("Generate Asset Names", this);
|
||||
pImportNamesMenu->addAction(pGenerateAssetNamesAction);
|
||||
#endif
|
||||
|
||||
QAction *pImportFromAssetNameMapAction = new QAction("Import from Asset Name Map", this);
|
||||
pImportNamesMenu->addAction(pImportFromAssetNameMapAction);
|
||||
|
||||
QAction *pGenerateAssetNamesAction = new QAction("Generate Asset Names", this);
|
||||
pImportNamesMenu->addAction(pGenerateAssetNamesAction);
|
||||
#if !PUBLIC_RELEASE
|
||||
pGenerateAssetNamesAction->setVisible(false);
|
||||
#endif
|
||||
|
||||
// Set up connections
|
||||
connect(mpUI->StoreComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateStore()));
|
||||
connect(mpUI->SearchBar, SIGNAL(textChanged(QString)), this, SLOT(OnSearchStringChanged()));
|
||||
|
@ -87,13 +88,11 @@ CResourceBrowser::CResourceBrowser(QWidget *pParent)
|
|||
connect(mpUI->ResourceTableView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(OnResourceSelectionChanged(QModelIndex, QModelIndex)));
|
||||
connect(pImportFromContentsTxtAction, SIGNAL(triggered()), this, SLOT(OnImportPakContentsTxt()));
|
||||
connect(pImportFromAssetNameMapAction, SIGNAL(triggered()), this, SLOT(OnImportNamesFromAssetNameMap()));
|
||||
connect(pGenerateAssetNamesAction, SIGNAL(triggered()), this, SLOT(OnGenerateAssetNames()));
|
||||
connect(mpUI->ExportNamesButton, SIGNAL(clicked()), this, SLOT(ExportAssetNames()));
|
||||
connect(&mUpdateFilterTimer, SIGNAL(timeout()), this, SLOT(UpdateFilter()));
|
||||
connect(mpFilterAllBox, SIGNAL(toggled(bool)), this, SLOT(OnFilterTypeBoxTicked(bool)));
|
||||
|
||||
#if !PUBLIC_RELEASE
|
||||
connect(pGenerateAssetNamesAction, SIGNAL(triggered()), this, SLOT(OnGenerateAssetNames()));
|
||||
#endif
|
||||
connect(gpEdApp, SIGNAL(ActiveProjectChanged(CGameProject*)), this, SLOT(UpdateStore()));
|
||||
}
|
||||
|
||||
CResourceBrowser::~CResourceBrowser()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "TestDialog.h"
|
||||
#include "ui_TestDialog.h"
|
||||
#include "CEditorApplication.h"
|
||||
#include <Core/GameProject/CGameProject.h>
|
||||
|
||||
TestDialog::TestDialog(QWidget *pParent)
|
||||
|
@ -26,7 +27,7 @@ void TestDialog::OnSpinBoxChanged(int NewValue)
|
|||
void TestDialog::OnFind()
|
||||
{
|
||||
u32 SoundID = ui->spinBox->value();
|
||||
CGameProject *pProj = CGameProject::ActiveProject();
|
||||
CGameProject *pProj = gpEdApp->ActiveProject();
|
||||
|
||||
if (pProj)
|
||||
{
|
||||
|
|
|
@ -17,17 +17,16 @@
|
|||
#include "Editor/Widgets/WVectorEditor.h"
|
||||
#include "Editor/Undo/UndoCommands.h"
|
||||
|
||||
#include <Common/Log.h>
|
||||
#include <Core/GameProject/CGameProject.h>
|
||||
#include <Core/Render/CDrawUtil.h>
|
||||
#include <Core/Scene/CSceneIterator.h>
|
||||
#include <Common/Log.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <QClipboard>
|
||||
#include <QComboBox>
|
||||
#include <QFontMetrics>
|
||||
#include <QMessageBox>
|
||||
#include <QOpenGLContext>
|
||||
#include <QSettings>
|
||||
|
||||
CWorldEditor::CWorldEditor(QWidget *parent)
|
||||
: INodeEditor(parent)
|
||||
|
@ -90,7 +89,25 @@ CWorldEditor::CWorldEditor(QWidget *parent)
|
|||
|
||||
mpCollisionDialog = new CCollisionRenderSettingsDialog(this, this);
|
||||
|
||||
// "Open Recent" menu
|
||||
mpOpenRecentMenu = new QMenu(this);
|
||||
ui->ActionOpenRecent->setMenu(mpOpenRecentMenu);
|
||||
|
||||
for (u32 iAct = 0; iAct < mskMaxRecentProjects; iAct++)
|
||||
{
|
||||
QAction *pAction = new QAction(this);
|
||||
pAction->setVisible(false);
|
||||
connect(pAction, SIGNAL(triggered(bool)), this, SLOT(OpenRecentProject()));
|
||||
|
||||
mpOpenRecentMenu->addAction(pAction);
|
||||
mRecentProjectsActions[iAct] = pAction;
|
||||
}
|
||||
UpdateOpenRecentActions();
|
||||
|
||||
// Connect signals and slots
|
||||
connect(gpEdApp, SIGNAL(ActiveProjectChanged(CGameProject*)), this, SLOT(OnActiveProjectChanged(CGameProject*)));
|
||||
connect(gpEdApp->clipboard(), SIGNAL(dataChanged()), this, SLOT(OnClipboardDataModified()));
|
||||
|
||||
connect(ui->MainViewport, SIGNAL(ViewportClick(SRayIntersection,QMouseEvent*)), this, SLOT(OnViewportClick(SRayIntersection,QMouseEvent*)));
|
||||
connect(ui->MainViewport, SIGNAL(InputProcessed(SRayIntersection,QMouseEvent*)), this, SLOT(OnViewportInputProcessed(SRayIntersection,QMouseEvent*)));
|
||||
connect(ui->MainViewport, SIGNAL(InputProcessed(SRayIntersection,QMouseEvent*)), this, SLOT(UpdateGizmoUI()) );
|
||||
|
@ -105,10 +122,10 @@ CWorldEditor::CWorldEditor(QWidget *parent)
|
|||
connect(ui->TransformSpinBox, SIGNAL(ValueChanged(CVector3f)), this, SLOT(OnTransformSpinBoxModified(CVector3f)));
|
||||
connect(ui->TransformSpinBox, SIGNAL(EditingDone(CVector3f)), this, SLOT(OnTransformSpinBoxEdited(CVector3f)));
|
||||
connect(ui->CamSpeedSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnCameraSpeedChange(double)));
|
||||
connect(qApp->clipboard(), SIGNAL(dataChanged()), this, SLOT(OnClipboardDataModified()));
|
||||
connect(&mUndoStack, SIGNAL(indexChanged(int)), this, SLOT(OnUndoStackIndexChanged()));
|
||||
|
||||
connect(ui->ActionSave, SIGNAL(triggered()), this, SLOT(Save()));
|
||||
connect(ui->ActionOpenProject, SIGNAL(triggered()), this, SLOT(OpenProject()));
|
||||
connect(ui->ActionSave, SIGNAL(triggered()) , this, SLOT(Save()));
|
||||
connect(ui->ActionSaveAndRepack, SIGNAL(triggered()), this, SLOT(SaveAndRepack()));
|
||||
connect(ui->ActionCut, SIGNAL(triggered()), this, SLOT(Cut()));
|
||||
connect(ui->ActionCopy, SIGNAL(triggered()), this, SLOT(Copy()));
|
||||
|
@ -172,6 +189,34 @@ void CWorldEditor::closeEvent(QCloseEvent *pEvent)
|
|||
}
|
||||
}
|
||||
|
||||
bool CWorldEditor::CloseWorld()
|
||||
{
|
||||
if (CheckUnsavedChanges())
|
||||
{
|
||||
ExitPickMode();
|
||||
ClearSelection();
|
||||
ui->MainViewport->ResetHover();
|
||||
ui->ModifyTabContents->ClearUI();
|
||||
ui->InstancesTabContents->SetMaster(nullptr);
|
||||
|
||||
mUndoStack.clear();
|
||||
mpCollisionDialog->close();
|
||||
mpLinkDialog->close();
|
||||
|
||||
if (mpPoiDialog)
|
||||
mpPoiDialog->close();
|
||||
|
||||
// Clear old area - hack until better world/area loader is implemented
|
||||
if (mpArea)
|
||||
mpArea->ClearScriptLayers();
|
||||
|
||||
mpArea = nullptr;
|
||||
mpWorld = nullptr;
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea)
|
||||
{
|
||||
ExitPickMode();
|
||||
|
@ -188,10 +233,6 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea)
|
|||
mpPoiDialog = nullptr;
|
||||
}
|
||||
|
||||
// Clear old area - hack until better world/area loader is implemented
|
||||
if ((mpArea) && (pArea != mpArea))
|
||||
mpArea->ClearScriptLayers();
|
||||
|
||||
// Load new area
|
||||
mpArea = pArea;
|
||||
mpWorld = pWorld;
|
||||
|
@ -355,6 +396,32 @@ void CWorldEditor::Paste()
|
|||
}
|
||||
}
|
||||
|
||||
void CWorldEditor::OpenProject()
|
||||
{
|
||||
QString ProjPath = UICommon::OpenFileDialog(this, "Open Project", "Game Project (*.prj)");
|
||||
if (!ProjPath.isEmpty()) gpEdApp->OpenProject(ProjPath);
|
||||
}
|
||||
|
||||
void CWorldEditor::OpenRecentProject()
|
||||
{
|
||||
QAction *pSender = qobject_cast<QAction*>(sender());
|
||||
|
||||
if (pSender)
|
||||
{
|
||||
QSettings Settings;
|
||||
QStringList RecentProjectsList = Settings.value("WorldEditor/RecentProjectsList").toStringList();
|
||||
|
||||
int ProjIndex = pSender->data().toInt();
|
||||
QString ProjPath = RecentProjectsList[ProjIndex];
|
||||
gpEdApp->OpenProject(ProjPath);
|
||||
}
|
||||
}
|
||||
|
||||
void CWorldEditor::CloseProject()
|
||||
{
|
||||
gpEdApp->CloseProject();
|
||||
}
|
||||
|
||||
bool CWorldEditor::Save()
|
||||
{
|
||||
bool SaveAreaSuccess = mpArea->Entry()->Save();
|
||||
|
@ -384,6 +451,22 @@ bool CWorldEditor::SaveAndRepack()
|
|||
return true;
|
||||
}
|
||||
|
||||
void CWorldEditor::OnActiveProjectChanged(CGameProject *pProj)
|
||||
{
|
||||
ui->ActionCloseProject->setEnabled( pProj != nullptr );
|
||||
if (!pProj) return;
|
||||
|
||||
// Update recent projects list
|
||||
QSettings Settings;
|
||||
QStringList RecentProjectsList = Settings.value("WorldEditor/RecentProjectsList").toStringList();
|
||||
QString ProjPath = TO_QSTRING(pProj->ProjectPath());
|
||||
|
||||
RecentProjectsList.removeAll(ProjPath);
|
||||
RecentProjectsList.prepend(ProjPath);
|
||||
Settings.setValue("WorldEditor/RecentProjectsList", RecentProjectsList);
|
||||
UpdateOpenRecentActions();
|
||||
}
|
||||
|
||||
void CWorldEditor::OnLinksModified(const QList<CScriptObject*>& rkInstances)
|
||||
{
|
||||
foreach (CScriptObject *pInstance, rkInstances)
|
||||
|
@ -509,6 +592,27 @@ void CWorldEditor::DeleteSelection()
|
|||
}
|
||||
}
|
||||
|
||||
void CWorldEditor::UpdateOpenRecentActions()
|
||||
{
|
||||
QSettings Settings;
|
||||
QStringList RecentProjectsList = Settings.value("WorldEditor/RecentProjectsList").toStringList();
|
||||
|
||||
for (int iProj = 0; iProj < mskMaxRecentProjects; iProj++)
|
||||
{
|
||||
QAction *pAction = mRecentProjectsActions[iProj];
|
||||
|
||||
if (iProj < RecentProjectsList.size())
|
||||
{
|
||||
QString ActionText = QString("&%1 %2").arg(iProj).arg(RecentProjectsList[iProj]);
|
||||
pAction->setText(ActionText);
|
||||
pAction->setVisible(true);
|
||||
}
|
||||
|
||||
else
|
||||
pAction->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CWorldEditor::UpdateStatusBar()
|
||||
{
|
||||
// Would be cool to do more frequent status bar updates with more info. Unfortunately, this causes lag.
|
||||
|
|
|
@ -34,7 +34,11 @@ class CWorldEditor;
|
|||
class CWorldEditor : public INodeEditor
|
||||
{
|
||||
Q_OBJECT
|
||||
static const int mskMaxRecentProjects = 10;
|
||||
|
||||
Ui::CWorldEditor *ui;
|
||||
QMenu *mpOpenRecentMenu;
|
||||
QAction *mRecentProjectsActions[ mskMaxRecentProjects ];
|
||||
|
||||
TResPtr<CWorld> mpWorld;
|
||||
TResPtr<CGameArea> mpArea;
|
||||
|
@ -55,6 +59,7 @@ public:
|
|||
explicit CWorldEditor(QWidget *parent = 0);
|
||||
~CWorldEditor();
|
||||
void closeEvent(QCloseEvent *pEvent);
|
||||
bool CloseWorld();
|
||||
void SetArea(CWorld *pWorld, CGameArea *pArea);
|
||||
bool CheckUnsavedChanges();
|
||||
bool HasAnyScriptNodesSelected() const;
|
||||
|
@ -76,8 +81,14 @@ public slots:
|
|||
void Cut();
|
||||
void Copy();
|
||||
void Paste();
|
||||
|
||||
void OpenProject();
|
||||
void OpenRecentProject();
|
||||
void CloseProject();
|
||||
bool Save();
|
||||
bool SaveAndRepack();
|
||||
|
||||
void OnActiveProjectChanged(CGameProject *pProj);
|
||||
void OnLinksModified(const QList<CScriptObject*>& rkInstances);
|
||||
void OnPropertyModified(IProperty *pProp);
|
||||
void SetSelectionActive(bool Active);
|
||||
|
@ -85,6 +96,7 @@ public slots:
|
|||
void SetSelectionLayer(CScriptLayer *pLayer);
|
||||
void DeleteSelection();
|
||||
|
||||
void UpdateOpenRecentActions();
|
||||
void UpdateStatusBar();
|
||||
void UpdateGizmoUI();
|
||||
void UpdateSelectionUI();
|
||||
|
|
|
@ -415,8 +415,16 @@
|
|||
<property name="title">
|
||||
<string>File</string>
|
||||
</property>
|
||||
<addaction name="ActionOpenProject"/>
|
||||
<addaction name="ActionOpenRecent"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="ActionSave"/>
|
||||
<addaction name="ActionSaveAndRepack"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="ActionExportGame"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="ActionCloseProject"/>
|
||||
<addaction name="ActionExit"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuEdit">
|
||||
<property name="title">
|
||||
|
@ -478,26 +486,13 @@
|
|||
<addaction name="menuTools"/>
|
||||
<addaction name="menuView"/>
|
||||
</widget>
|
||||
<action name="ActionOpen">
|
||||
<property name="text">
|
||||
<string>Open</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionSave">
|
||||
<property name="icon">
|
||||
<iconset resource="../Icons.qrc">
|
||||
<normaloff>:/icons/Save.png</normaloff>:/icons/Save.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+S</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionOpen_model_viewer">
|
||||
<property name="text">
|
||||
<string>Open Model Viewer</string>
|
||||
<string>Save World</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionLink">
|
||||
|
@ -814,15 +809,48 @@
|
|||
<property name="toolTip">
|
||||
<string>Save and Repack</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+S</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionCollisionRenderSettings">
|
||||
<property name="text">
|
||||
<string>Collision Render Settings</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionOpenRecent">
|
||||
<property name="icon">
|
||||
<iconset resource="../Icons.qrc">
|
||||
<normaloff>:/icons/Open_16px.png</normaloff>:/icons/Open_16px.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open Recent</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionOpenProject">
|
||||
<property name="icon">
|
||||
<iconset resource="../Icons.qrc">
|
||||
<normaloff>:/icons/Open_16px.png</normaloff>:/icons/Open_16px.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open Project</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionExportGame">
|
||||
<property name="text">
|
||||
<string>Export Game</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionExit">
|
||||
<property name="text">
|
||||
<string>Exit</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionCloseProject">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Close Project</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
|
|
@ -25,6 +25,9 @@ int main(int argc, char *argv[])
|
|||
// Create application
|
||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
|
||||
CEditorApplication App(argc, argv);
|
||||
App.setApplicationName( APP_NAME );
|
||||
App.setApplicationVersion( APP_VERSION );
|
||||
App.setOrganizationName("Aruki");
|
||||
App.setWindowIcon(QIcon(":/icons/AppIcon.ico"));
|
||||
|
||||
// Init log
|
||||
|
|
Loading…
Reference in New Issue