Added support for WResourceSelector to have multiple allowed file extensions (required for Prime 3)

This commit is contained in:
parax0 2015-07-27 16:17:22 -04:00
parent 8804c436ed
commit 0577c8a0fa
11 changed files with 366 additions and 180 deletions

View File

@ -108,3 +108,13 @@ bool CFourCC::operator<=(const CFourCC& other) const
{
return (ToLong() <= other.ToLong());
}
char CFourCC::operator[](int index)
{
return mFourCC[index];
}
const char CFourCC::operator[](int index) const
{
return mFourCC[index];
}

View File

@ -33,7 +33,8 @@ public:
bool operator>=(const CFourCC& other) const;
bool operator<(const CFourCC& other) const;
bool operator<=(const CFourCC& other) const;
char operator[](int index);
const char operator[](int index) const;
};
#endif // CFOURCC_H

View File

@ -51,15 +51,23 @@ EResType CResource::ResTypeForExtension(CFourCC Extension)
{
Extension = Extension.ToUpper();
if (Extension < "FONT")
{
if (Extension < "CSKR")
{
if (Extension == "AFSM") return eStateMachine;
if (Extension == "AGSC") return eAudioGrp;
if (Extension == "ANCS") return eCharacter;
if (Extension == "ANCS") return eAnimSet;
if (Extension == "ANIM") return eAnimation;
if (Extension == "ATBL") return eAudioTable;
if (Extension == "CAUD") return eAudioData;
if (Extension == "CHAR") return eAnimSet;
if (Extension == "CINF") return eSkeleton;
if (Extension == "CMDL") return eModel;
if (Extension == "CRSC") return eCollisionResponse;
}
else
{
if (Extension == "CSKR") return eSkin;
if (Extension == "CSMP") return eAudioSample;
if (Extension == "CSNG") return eMidi;
@ -70,6 +78,12 @@ EResType CResource::ResTypeForExtension(CFourCC Extension)
if (Extension == "DUMB") return eDataDump;
if (Extension == "ELSC") return eParticleElectric;
if (Extension == "EVNT") return eAnimEventData;
}
}
else
{
if (Extension < "PAK ")
{
if (Extension == "FONT") return eFont;
if (Extension == "FRME") return eGuiFrame;
if (Extension == "FSM2") return eStateMachine;
@ -80,6 +94,9 @@ EResType CResource::ResTypeForExtension(CFourCC Extension)
if (Extension == "MLVL") return eWorld;
if (Extension == "MREA") return eArea;
if (Extension == "NTWK") return eTweak;
}
else
{
if (Extension == "PAK ") return ePackFile;
if (Extension == "PART") return eParticle;
if (Extension == "PATH") return eNavMesh;
@ -91,6 +108,8 @@ EResType CResource::ResTypeForExtension(CFourCC Extension)
if (Extension == "THP ") return eVideo;
if (Extension == "TXTR") return eTexture;
if (Extension == "WPSC") return eProjectile;
}
}
return eInvalidResType;
}

View File

@ -5,45 +5,46 @@ enum EResType
{
eAnimation = 0,
eAnimEventData = 1,
eArea = 2,
eAudioData = 3,
eAudioGrp = 4,
eAudioSample = 5,
eAudioStream = 6,
eAudioTable = 7,
eCharacter = 8,
eCollisionMesh = 9,
eCollisionResponse = 10,
eDataDump = 11,
eDecal = 12,
eDependencyGroup = 13,
eFont = 14,
eGuiFrame = 15,
eHintSystem = 16,
eInvalidResType = 17,
eMapArea = 18,
eMapWorld = 19,
eMapUniverse = 20,
eMidi = 21,
eModel = 22,
eMusicTrack = 23,
eNavMesh = 24,
ePackFile = 25,
eParticle = 26,
eParticleElectric = 27,
eParticleSwoosh = 28,
eProjectile = 29,
eResource = 30,
eSaveWorld = 31,
eScan = 32,
eSkeleton = 33,
eSkin = 34,
eStateMachine = 35,
eStringTable = 36,
eTexture = 37,
eTweak = 38,
eVideo = 39,
eWorld = 40
eAnimSet = 2,
eArea = 3,
eAudioData = 4,
eAudioGrp = 5,
eAudioSample = 6,
eAudioStream = 7,
eAudioTable = 8,
eCharacter = 9,
eCollisionMesh = 10,
eCollisionResponse = 11,
eDataDump = 12,
eDecal = 13,
eDependencyGroup = 14,
eFont = 15,
eGuiFrame = 16,
eHintSystem = 17,
eInvalidResType = 18,
eMapArea = 19,
eMapWorld = 20,
eMapUniverse = 21,
eMidi = 22,
eModel = 23,
eMusicTrack = 24,
eNavMesh = 25,
ePackFile = 26,
eParticle = 27,
eParticleElectric = 28,
eParticleSwoosh = 29,
eProjectile = 30,
eResource = 31,
eSaveWorld = 32,
eScan = 33,
eSkeleton = 34,
eSkin = 35,
eStateMachine = 36,
eStringTable = 37,
eTexture = 38,
eTweak = 39,
eVideo = 40,
eWorld = 41
};
#endif // ERESTYPE

View File

@ -4,6 +4,7 @@
/*
* This header file declares some classes used to track script object properties
* CPropertyBase, __CProperty (and typedefs), CPropertyStruct
* It's a bit hard to read, should be reorganized at some point
*/
#include "../CResource.h"
#include "CScriptTemplate.h"
@ -91,6 +92,10 @@ public:
mToken = CToken(v);
}
}
const CStringList& AllowedExtensions()
{
return static_cast<CFileTemplate*>(Template())->Extensions();
}
};
/*

View File

@ -41,9 +41,9 @@ CModelEditorWindow::CModelEditorWindow(QWidget *parent) :
// UI initialization
UpdateAnimParamUI(-1);
ui->IndTextureResSelector->SetResType(eTexture);
ui->IndTextureResSelector->SetAllowedExtensions("TXTR");
ui->IndTextureResSelector->SetPreviewPanelEnabled(true);
ui->PassTextureResSelector->SetResType(eTexture);
ui->PassTextureResSelector->SetAllowedExtensions("TXTR");
ui->PassTextureResSelector->SetPreviewPanelEnabled(true);
ui->PassTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
ui->PassTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);

View File

@ -1,46 +1,153 @@
#include "UICommon.h"
// This array is intended to be used with the EResType enum
const QString gskResourceFilters[] = {
"Animation (*.ANIM)", // eAnimation
"Animation Event Data (*.EVNT)", // eAnimEventData
"Area (*.MREA)", // eArea
"Audio Metadata (*.CAUD)", // eAudioData
"Audio Group (*.AGSC)", // eAudioGrp
"Audio Sample (*.CSMP)", // eAudioSample
"Audio Stream (*.STRM)", // eAudioStream
"Audio Lookup Table (*.ATBL)", // eAudioTable
"Character (*.ANCS *.CHAR)", // eCharacter
"Collision Mesh (*.DCLN)", // eCollisionMesh
"Collision Response Data (*.CRSC)", // eCollisionResponse
"Data Dump (*.DUMB)", // eDataDump
"Decal (*.DPSC)", // eDecal
"Dependency Group (*.DGRP)", // eDependencyGroup
"Font (*.FONT)", // eFont
"GUI Frame (*.FRME)", // eGuiFrame
"Hint System Data (*.HINT)", // eHintSystem
"Invalid resource type", // eInvalid
"Area Map (*.MAPA)", // eMapArea
"World Map (*.MAPW)", // eMapWorld
"Universe Map (*.MAPU)", // eMapUniverse
"MIDI Data (*.CSNG)", // eMidi
"Model (*.CMDL)", // eModel
"Music Track (*.DSP)", // eMusicTrack
"Navigation Mesh (*.PATH)", // eNavMesh
"Pack File (*.pak)", // ePackFile
"Particle (*.PART)", // eParticle
"Electricity Particle (*.ELSC)", // eParticleElectric
"Swoosh Particle (*.SWHC)", // eParticleSwoosh
"Projectile (*.WPSC)", // eProjectile
"Invalid resource type", // eResource
"World Save Data (*.SAVW)", // eSaveWorld
"Scannable Object Info (*.SCAN)", // eScan
"Skeleton (*.CINF)", // eSkeleton
"Skin (*.CSKR)", // eSkin
"State Machine (*.AFSM *.FSM2)", // eStateMachine
"String Table (*.STRG)", // eStringTable
"Texture (*.TXTR)", // eTexture
"Tweak (*.CTWK *.ntwk)", // eTweak
"Video (*.thp)", // eVideo
"World (*.MLVL)" // eWorld
namespace UICommon
{
QMap<QString,QString> FilterMap = {
{ "AFSM", "AI Finite State Machine (*.AFSM)" },
{ "ANIM", "Animation (*.ANIM)" },
{ "ANCS", "Animation Character Set (*.ANCS)" },
{ "AGSC", "Audio Group (*.AGSC)" },
{ "ATBL", "Audio Lookup Table (*.ATBL)" },
{ "CAUD", "Audio Metadata (*.CAUD)" },
{ "CHAR", "Character (*.CHAR)" },
{ "CINF", "Skeleton (*.CINF)" },
{ "CMDL", "Model (*.CMDL)" },
{ "CRSC", "Collision Response Data (*.CRSC)" },
{ "CSKR", "Skin Rules (*.CSKR)" },
{ "CSMP", "Audio Sample (*.CSMP)" },
{ "CSNG", "MIDI Data (*.CSNG)" },
{ "CTWK", "Tweaks (*.CTWK)" },
{ "DCLN", "Collision Mesh (*.DCLN)" },
{ "DGRP", "Dependency Group (*.DGRP)" },
{ "DPSC", "Decal (*.DPSC)" },
{ "DSP", "Music Track (*.DSP)" },
{ "DUMB", "Binary Data Dump (*.DUMB)" },
{ "ELSC", "Electric Particle (*.ELSC)" },
{ "EVNT", "Animation Event Data (*.EVNT)" },
{ "FRME", "GUI Frame (*.FRME)" },
{ "FSM2", "AI Finite State Machine (*.FSM2)" },
{ "FONT", "Font (*.FONT)" },
{ "HINT", "Hint System Data (*.HINT)" },
{ "MAPA", "Area Map (*.MAPA)" },
{ "MAPW", "World Map (*.MAPW)" },
{ "MAPU", "Universe Map (*.MAPU)" },
{ "MLVL", "World (*.MLVL)" },
{ "MREA", "Area (*.MREA)" },
{ "NTWK", "Tweaks (*.NTWK)" },
{ "PATH", "AI Navigation Mesh (*.PATH)" },
{ "PAK", "Pack File (*.pak)" },
{ "PART", "Particle (*.PART)" },
{ "SAVW", "World Save Data (*.SAVW)" },
{ "SCAN", "Scannable Object Info (*.SCAN)" },
{ "STRG", "String Table (*.STRG)" },
{ "STRM", "Audio Stream (*.STRM)" },
{ "SWHC", "Swoosh Particle (*.SWHC)" },
{ "THP", "Video (*.thp)" },
{ "TXTR", "Texture (*.TXTR)" },
{ "WPSC", "Projectile (*.WPSC)" }
};
QString ExtensionFilterString(const QString& extension)
{
QMap<QString,QString>::const_iterator it = FilterMap.find(extension);
if (it != FilterMap.end())
return it.value();
else
return "Unknown Extension (*." + extension + ")";
/*if (extension.isEmpty()) return gskInvalidFilterString;
extension = extension.toUpper();
switch (extension[0])
{
case 'A':
if (extension == "AFSM") return "AI Finite State Machine (*.AFSM)";
if (extension == "ANIM") return "Animation (*.ANIM)";
if (extension == "ANCS") return "Animation Character Set (*.ANCS)";
if (extension == "AGSC") return "Audio Group (*.AGSC)";
if (extension == "ATBL") return "Audio Lookup Table (*.ATBL)";
break;
case 'C':
if (extension[1] <= 'R')
{
if (extension == "CAUD") return "Audio Metadata (*.CAUD)";
if (extension == "CHAR") return "Character (*.CHAR)";
if (extension == "CINF") return "Skeleton (*.CINF)";
if (extension == "CMDL") return "Model (*.CMDL)";
if (extension == "CRSC") return "Collision Response Data (*.CRSC)";
}
else
{
if (extension == "CSKR") return "Skin Rules (*.CSKR)";
if (extension == "CSMP") return "Audio Sample (*.CSMP)";
if (extension == "CSNG") return "MIDI Data (*.CSNG)";
if (extension == "CTWK") return "Tweaks (*.CTWK)";
}
break;
case 'D':
if (extension == "DCLN") return "Collision Mesh (*.DCLN)";
if (extension == "DGRP") return "Dependency Group (*.DGRP)";
if (extension == "DPSC") return "Decal (*.DPSC)";
if (extension == "DSP") return "Music Track (*.DSP)";
if (extension == "DUMB") return "Binary Data Dump (*.DUMB)";
break;
case 'E':
if (extension == "ELSC") return "Electric Particle (*.ELSC)";
if (extension == "EVNT") return "Animation Event Data (*.EVNT)";
break;
case 'F':
if (extension == "FRME") return "GUI Frame (*.FRME)";
if (extension == "FSM2") return "AI Finite State Machine (*.FSM2)";
if (extension == "FONT") return "Font (*.FONT)";
break;
case 'H':
if (extension == "HINT") return "Hint System Data (*.HINT)";
break;
case 'M':
if (extension == "MAPA") return "Area Map (*.MAPA)";
if (extension == "MAPW") return "World Map (*.MAPW)";
if (extension == "MAPU") return "Universe Map (*.MAPU)";
if (extension == "MLVL") return "World (*.MLVL)";
if (extension == "MREA") return "Area (*.MREA)";
break;
case 'N':
if (extension == "NTWK") return "Tweaks (*.ntwk)";
break;
case 'P':
if (extension == "PATH") return "AI Navigation Mesh (*.PATH)";
if (extension == "PAK") return "Pack File (*.pak)";
if (extension == "PART") return "Particle (*.PART)";
break;
case 'S':
if (extension == "SAVW") return "World Save Data (*.SAVW)";
if (extension == "SCAN") return "Scannable Object Info (*.SCAN)";
if (extension == "STRG") return "String Table (*.STRG)";
if (extension == "STRM") return "Audio Stream (*.STRM)";
if (extension == "SWHC") return "Swoosh Particle (*.SWHC)";
break;
case 'T':
if (extension == "THP") return "Video (*.thp)";
if (extension == "TXTR") return "Texture (*.TXTR)";
break;
case 'W':
if (extension == "WPSC") return "Projectile (*.WPSC)";
break;
}
return gskInvalidFilterString;*/
}
}

View File

@ -1,9 +1,14 @@
#ifndef UICOMMON
#define UICOMMON
#include <QMap>
#include <QString>
extern const QString gskResourceFilters[];
namespace UICommon
{
extern QMap<QString,QString> FilterMap;
QString ExtensionFilterString(const QString& extension);
}
#endif // UICOMMON

View File

@ -190,6 +190,7 @@ void WPropertyEditor::CreateEditor()
WResourceSelector *pResourceSelector = new WResourceSelector(this);
pResourceSelector->AdjustPreviewToParent(true);
pResourceSelector->SetAllowedExtensions(pFileCast->AllowedExtensions());
pResourceSelector->SetResource(pFileCast->Get());
mUI.EditorWidget = pResourceSelector;
@ -316,6 +317,7 @@ void WPropertyEditor::UpdateEditor()
{
CFileProperty *pFileCast = static_cast<CFileProperty*>(mpProperty);
WResourceSelector *pResourceSelector = static_cast<WResourceSelector*>(mUI.EditorWidget);
pResourceSelector->SetAllowedExtensions(pFileCast->AllowedExtensions());
pResourceSelector->SetResource(pFileCast->Get());
break;
}

View File

@ -13,19 +13,20 @@
WResourceSelector::WResourceSelector(QWidget *parent) : QWidget(parent)
{
// Initialize Members
mHasMultipleExtensions = false;
// Initialize Selector Members
mShowEditButton = false;
mShowExportButton = false;
// Initialize Preview Panel Members
mpPreviewPanel = nullptr;
mEnablePreviewPanel = true;
mPreviewPanelValid = false;
mShowingPreviewPanel = false;
mAdjustPreviewToParent = false;
// Initialize Resource Members
mpResource = nullptr;
mResType = eInvalidResType;
mResourceValid = false;
// Create Widgets
mUI.LineEdit = new QLineEdit(this);
@ -94,12 +95,20 @@ bool WResourceSelector::eventFilter(QObject *pObj, QEvent *pEvent)
return false;
}
// ************ GETTERS ************
EResType WResourceSelector::GetResType()
bool WResourceSelector::IsSupportedExtension(const QString& extension)
{
return mResType;
foreach(const QString& str, mSupportedExtensions)
if (str == extension) return true;
return false;
}
bool WResourceSelector::HasSupportedExtension(CResource* pRes)
{
return IsSupportedExtension( QString::fromStdString( StringUtil::GetExtension(pRes->FullSource()) ) );
}
// ************ GETTERS ************
QString WResourceSelector::GetText()
{
return mUI.LineEdit->text();
@ -129,14 +138,13 @@ void WResourceSelector::SetResource(CResource *pRes)
if (pRes)
{
CFourCC ext = StringUtil::GetExtension(pRes->Source());
mResType = CResource::ResTypeForExtension(ext);
mResourceValid = HasSupportedExtension(pRes);
mUI.LineEdit->setText(QString::fromStdString(pRes->Source()));
}
else
{
mResType = eInvalidResType;
mResourceValid = false;
mUI.LineEdit->clear();
}
@ -144,18 +152,17 @@ void WResourceSelector::SetResource(CResource *pRes)
SetButtonsBasedOnResType();
}
void WResourceSelector::SetResType(EResType Type)
void WResourceSelector::SetAllowedExtensions(const QString& extension)
{
mResType = Type;
mpResource = nullptr;
mResToken.Unlock();
mUI.LineEdit->clear();
CreatePreviewPanel();
SetButtonsBasedOnResType();
mSupportedExtensions.clear();
mSupportedExtensions << extension;
}
void WResourceSelector::SetResTypes(const CStringList &ExtensionList)
void WResourceSelector::SetAllowedExtensions(const CStringList& extensions)
{
mSupportedExtensions.clear();
for (auto it = extensions.begin(); it != extensions.end(); it++)
mSupportedExtensions << QString::fromStdString(*it);
}
void WResourceSelector::SetText(const QString& ResPath)
@ -197,14 +204,29 @@ void WResourceSelector::OnLineEditTextEdited()
void WResourceSelector::OnBrowseButtonClicked()
{
QString Filter = gskResourceFilters[mResType];
// Construct filter string
QString filter;
std::string ResTypeStr = Filter.toStdString();
size_t EndName = ResTypeStr.find_last_of("(") - 1;
ResTypeStr = ResTypeStr.substr(0, EndName);
QString ResType = QString::fromStdString(ResTypeStr);
if (mSupportedExtensions.size() > 1)
{
QString all = "All supported extensions (";
QString NewRes = QFileDialog::getOpenFileName(this, "Select " + ResType, "", Filter);
for (u32 iExt = 0; iExt < mSupportedExtensions.size(); iExt++)
{
if (iExt > 0) all += " ";
all += "*." + mSupportedExtensions[iExt];
}
all += ")";
filter += all + ";;";
}
for (u32 iExt = 0; iExt < mSupportedExtensions.size(); iExt++)
{
if (iExt > 0) filter += ";;";
filter += UICommon::ExtensionFilterString(mSupportedExtensions[iExt]);
}
QString NewRes = QFileDialog::getOpenFileName(this, "Select resource", "", filter);
if (!NewRes.isEmpty())
{
@ -236,10 +258,38 @@ void WResourceSelector::Export()
emit ExportResource(mpResource);
}
void WResourceSelector::LoadResource(const QString& ResPath)
{
mpResource = nullptr;
mResToken.Unlock();
std::string pathStr = ResPath.toStdString();
std::string ext = StringUtil::GetExtension(pathStr);
if (IsSupportedExtension( QString::fromStdString(ext) ))
{
if ((ext != "MREA") && (ext != "MLVL"))
{
mpResource = gResCache.GetResource(pathStr);
mResToken = CToken(mpResource);
if (mPreviewPanelValid) mpPreviewPanel->SetResource(mpResource);
}
else mResourceValid = false;
}
else mResourceValid = false;
SetButtonsBasedOnResType();
CreatePreviewPanel();
emit ResourceChanged(ResPath);
}
void WResourceSelector::CreatePreviewPanel()
{
delete mpPreviewPanel;
mpPreviewPanel = IPreviewPanel::CreatePanel(mResType, this);
if (mResourceValid)
mpPreviewPanel = IPreviewPanel::CreatePanel(mpResource->Type(), this);
if (!mpPreviewPanel) mPreviewPanelValid = false;
@ -253,7 +303,7 @@ void WResourceSelector::CreatePreviewPanel()
void WResourceSelector::ShowPreviewPanel()
{
if ((mPreviewPanelValid) && (mpResource != nullptr))
if (mPreviewPanelValid)
{
// Preferred panel point is lower-right, but can move if there's not enough room
QPoint Position = parentWidget()->mapToGlobal(pos());
@ -293,33 +343,17 @@ void WResourceSelector::HidePreviewPanel()
}
}
void WResourceSelector::LoadResource(const QString& ResPath)
{
mpResource = nullptr;
mResToken.Unlock();
if ((mResType != eArea) && (mResType != eWorld))
{
std::string PathStr = ResPath.toStdString();
CFourCC ResExt = StringUtil::GetExtension(PathStr).c_str();
if (CResource::ResTypeForExtension(ResExt) == mResType)
{
mpResource = gResCache.GetResource(PathStr);
mResToken = CToken(mpResource);
if (mPreviewPanelValid) mpPreviewPanel->SetResource(mpResource);
}
}
emit ResourceChanged(ResPath);
}
void WResourceSelector::SetButtonsBasedOnResType()
{
// Basically this function sets whether the "Export" and "Edit"
// buttons are present based on the resource type.
switch (mResType)
if (!mpResource)
{
SetEditButtonEnabled(false);
SetExportButtonEnabled(false);
}
else switch (mpResource->Type())
{
// Export button should be enabled here because CTexture already has a DDS export function
// However, need to figure out what sort of interface to create to do it. Disabling until then.

View File

@ -18,7 +18,6 @@ class WResourceSelector : public QWidget
// Selector
QStringList mSupportedExtensions;
bool mHasMultipleExtensions;
bool mShowEditButton;
bool mShowExportButton;
@ -32,7 +31,7 @@ class WResourceSelector : public QWidget
// Resource
CResource *mpResource;
CToken mResToken;
EResType mResType;
bool mResourceValid;
// UI
struct {
@ -43,6 +42,7 @@ class WResourceSelector : public QWidget
QHBoxLayout *Layout;
} mUI;
// Functions
signals:
void ResourceChanged(const QString& NewResPath);
void EditResource(CResource *pRes);
@ -53,9 +53,10 @@ public:
~WResourceSelector();
bool event(QEvent *);
bool eventFilter(QObject *, QEvent *);
bool IsSupportedExtension(const QString& extension);
bool HasSupportedExtension(CResource* pRes);
// Getters
EResType GetResType();
QString GetText();
bool IsEditButtonEnabled();
bool IsExportButtonEnabled();
@ -63,8 +64,9 @@ public:
// Setters
void SetResource(CResource *pRes);
void SetResType(EResType Type);
void SetResTypes(const CStringList& ExtensionList);
void SetAllowedExtensions(const QString& extension);
void SetAllowedExtensions(const QStringList& extensions);
void SetAllowedExtensions(const CStringList& extensions);
void SetText(const QString& ResPath);
void SetEditButtonEnabled(bool Enabled);
void SetExportButtonEnabled(bool Enabled);
@ -81,10 +83,10 @@ public slots:
private:
void Edit();
void Export();
void LoadResource(const QString& ResPath);
void CreatePreviewPanel();
void ShowPreviewPanel();
void HidePreviewPanel();
void LoadResource(const QString& ResPath);
void SetButtonsBasedOnResType();
};