diff --git a/src/Core/Resource/CResTypeInfo.cpp b/src/Core/Resource/CResTypeInfo.cpp index 2adc7c3d..ce8e34ca 100644 --- a/src/Core/Resource/CResTypeInfo.cpp +++ b/src/Core/Resource/CResTypeInfo.cpp @@ -127,6 +127,7 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes() { CResTypeInfo *pType = new CResTypeInfo(eAnimation, "Animation"); AddExtension(pType, "ANIM", ePrimeDemo, eReturns); + pType->mRawExtension = "ani"; pType->mHidden = true; } { @@ -142,6 +143,7 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes() { CResTypeInfo *pType = new CResTypeInfo(eAnimSet, "Animation Character Set"); AddExtension(pType, "ANCS", ePrimeDemo, eEchoes); + pType->mRawExtension = "acs"; } { CResTypeInfo *pType = new CResTypeInfo(eArea, "Area"); @@ -166,13 +168,15 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes() pType->mHidden = true; } { - CResTypeInfo *pType = new CResTypeInfo(eBinaryData, "Binary Data"); + CResTypeInfo *pType = new CResTypeInfo(eBinaryData, "Generic Data"); AddExtension(pType, "DUMB", ePrimeDemo, eCorruption); + pType->mRawExtension = "dat"; pType->mHidden = true; } { CResTypeInfo *pType = new CResTypeInfo(eBurstFireData, "Burst Fire Data"); AddExtension(pType, "BFRC", eCorruptionProto, eCorruption); + pType->mRawExtension = "bfre"; } { CResTypeInfo *pType = new CResTypeInfo(eCharacter, "Character"); @@ -189,6 +193,7 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes() { CResTypeInfo *pType = new CResTypeInfo(eFont, "Font"); AddExtension(pType, "FONT", ePrimeDemo, eReturns); + pType->mRawExtension = "rpff"; } { CResTypeInfo *pType = new CResTypeInfo(eGuiFrame, "Gui Frame"); @@ -229,6 +234,7 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes() { CResTypeInfo *pType = new CResTypeInfo(eParticle, "Particle System"); AddExtension(pType, "PART", ePrimeDemo, eReturns); + pType->mRawExtension = "gpsm"; } { CResTypeInfo *pType = new CResTypeInfo(eParticleCollisionResponse, "Collision Response Particle System"); @@ -237,30 +243,37 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes() { CResTypeInfo *pType = new CResTypeInfo(eParticleDecal, "Decal Particle System"); AddExtension(pType, "DPSC", ePrimeDemo, eCorruption); + pType->mRawExtension = "dpsm"; } { CResTypeInfo *pType = new CResTypeInfo(eParticleElectric, "Electric Particle System"); AddExtension(pType, "ELSC", ePrimeDemo, eCorruption); + pType->mRawExtension = "elsm"; } { CResTypeInfo *pType = new CResTypeInfo(eParticleSorted, "Sorted Particle System"); AddExtension(pType, "SRSC", eEchoesDemo, eEchoes); + pType->mRawExtension = "srsm"; } { CResTypeInfo *pType = new CResTypeInfo(eParticleSpawn, "Spawn Particle System"); AddExtension(pType, "SPSC", eEchoesDemo, eReturns); + pType->mRawExtension = "spsm"; } { CResTypeInfo *pType = new CResTypeInfo(eParticleSwoosh, "Swoosh Particle System"); AddExtension(pType, "SWHC", ePrimeDemo, eReturns); + pType->mRawExtension = "swsh"; } { CResTypeInfo *pType = new CResTypeInfo(eParticleTransform, "Transform Particle System"); AddExtension(pType, "XFSC", eReturns, eReturns); + pType->mRawExtension = "xfsm"; } { CResTypeInfo *pType = new CResTypeInfo(eParticleWeapon, "Weapon Particle System"); AddExtension(pType, "WPSC", ePrimeDemo, eCorruption); + pType->mRawExtension = "wpsm"; } { CResTypeInfo *pType = new CResTypeInfo(ePathfinding, "Pathfinding Mesh"); @@ -292,6 +305,7 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes() { CResTypeInfo *pType = new CResTypeInfo(eSkeleton, "Skeleton"); AddExtension(pType, "CINF", ePrimeDemo, eReturns); + pType->mRawExtension = "cin"; pType->mHidden = true; } { @@ -313,10 +327,12 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes() AddExtension(pType, "AFSM", ePrimeDemo, eEchoes); AddExtension(pType, "FSM2", eCorruptionProto, eCorruption); AddExtension(pType, "FSMC", eReturns, eReturns); + pType->mRawExtension = "fsm"; } { CResTypeInfo *pType = new CResTypeInfo(eStateMachine2, "State Machine 2"); AddExtension(pType, "FSM2", eEchoesDemo, eEchoes); + pType->mRawExtension = "fsm2"; } { CResTypeInfo *pType = new CResTypeInfo(eStaticGeometryMap, "Static Geometry Map"); diff --git a/src/Core/Resource/Script/CScriptTemplate.cpp b/src/Core/Resource/Script/CScriptTemplate.cpp index a15eac19..79d318d0 100644 --- a/src/Core/Resource/Script/CScriptTemplate.cpp +++ b/src/Core/Resource/Script/CScriptTemplate.cpp @@ -179,7 +179,7 @@ CResource* CScriptTemplate::FindDisplayAsset(CPropertyStruct *pProperties, u32& if (pRes) { - rOutCharIndex = (it->ForceNodeIndex >= 0 ? it->ForceNodeIndex : pChar->Get().CharacterIndex()); + rOutCharIndex = (it->ForceNodeIndex >= 0 && it->ForceNodeIndex < (s32) static_cast(pRes)->NumCharacters() ? it->ForceNodeIndex : pChar->Get().CharacterIndex()); rOutAnimIndex = pChar->Get().AnimIndex(); } } diff --git a/src/Editor/CEditorApplication.cpp b/src/Editor/CEditorApplication.cpp index e3eb6f60..60817d12 100644 --- a/src/Editor/CEditorApplication.cpp +++ b/src/Editor/CEditorApplication.cpp @@ -1,6 +1,8 @@ #include "CEditorApplication.h" #include "IEditor.h" #include "CBasicViewport.h" +#include "CProjectOverviewDialog.h" +#include "Editor/ResourceBrowser/CResourceBrowser.h" #include "Editor/WorldEditor/CWorldEditor.h" #include #include @@ -8,6 +10,9 @@ CEditorApplication::CEditorApplication(int& rArgc, char **ppArgv) : QApplication(rArgc, ppArgv) + , mpWorldEditor(nullptr) + , mpResourceBrowser(nullptr) + , mpProjectDialog(nullptr) { mLastUpdate = CTimer::GlobalTime(); @@ -15,6 +20,21 @@ CEditorApplication::CEditorApplication(int& rArgc, char **ppArgv) mRefreshTimer.start(8); } +CEditorApplication::~CEditorApplication() +{ + delete mpWorldEditor; + delete mpResourceBrowser; + delete mpProjectDialog; +} + +void CEditorApplication::InitEditor() +{ + mpWorldEditor = new CWorldEditor(); + mpResourceBrowser = new CResourceBrowser(mpWorldEditor); + mpProjectDialog = new CProjectOverviewDialog(); + connect(mpProjectDialog, SIGNAL(ActiveProjectChanged(CGameProject*)), mpResourceBrowser, SLOT(RefreshResources())); +} + void CEditorApplication::AddEditor(IEditor *pEditor) { mEditorWindows << pEditor; diff --git a/src/Editor/CEditorApplication.h b/src/Editor/CEditorApplication.h index d7b8fce5..9fa70c78 100644 --- a/src/Editor/CEditorApplication.h +++ b/src/Editor/CEditorApplication.h @@ -6,6 +6,9 @@ #include class CBasicViewport; +class CProjectOverviewDialog; +class CResourceBrowser; +class CWorldEditor; class IEditor; class CEditorApplication : public QApplication @@ -13,11 +16,21 @@ class CEditorApplication : public QApplication Q_OBJECT QTimer mRefreshTimer; + CWorldEditor *mpWorldEditor; + CResourceBrowser *mpResourceBrowser; + CProjectOverviewDialog *mpProjectDialog; QVector mEditorWindows; double mLastUpdate; public: CEditorApplication(int& rArgc, char **ppArgv); + ~CEditorApplication(); + void InitEditor(); + + // Accessors + inline CWorldEditor* WorldEditor() const { return mpWorldEditor; } + inline CResourceBrowser* ResourceBrowser() const { return mpResourceBrowser; } + inline CProjectOverviewDialog* ProjectDialog() const { return mpProjectDialog; } public slots: void AddEditor(IEditor *pEditor); diff --git a/src/Editor/CProjectOverviewDialog.cpp b/src/Editor/CProjectOverviewDialog.cpp index 8ae1b54f..e57c5d91 100644 --- a/src/Editor/CProjectOverviewDialog.cpp +++ b/src/Editor/CProjectOverviewDialog.cpp @@ -1,5 +1,6 @@ #include "CProjectOverviewDialog.h" #include "ui_CProjectOverviewDialog.h" +#include "CEditorApplication.h" #include "UICommon.h" #include "Editor/ResourceBrowser/CResourceBrowser.h" #include @@ -13,7 +14,6 @@ CProjectOverviewDialog::CProjectOverviewDialog(QWidget *pParent) , mpProject(nullptr) { mpUI->setupUi(this); - mpWorldEditor = new CWorldEditor(); connect(mpUI->OpenProjectButton, SIGNAL(clicked()), this, SLOT(OpenProject())); connect(mpUI->ExportGameButton, SIGNAL(clicked()), this, SLOT(ExportGame())); @@ -26,7 +26,6 @@ CProjectOverviewDialog::CProjectOverviewDialog(QWidget *pParent) CProjectOverviewDialog::~CProjectOverviewDialog() { delete mpUI; - delete mpWorldEditor; } void CProjectOverviewDialog::OpenProject() @@ -46,6 +45,7 @@ void CProjectOverviewDialog::OpenProject() mpProject->SetActive(); SetupWorldsList(); SetupPackagesList(); + emit ActiveProjectChanged(mpProject); } else @@ -176,8 +176,8 @@ void CProjectOverviewDialog::LaunchEditor() { pArea->SetWorldIndex(AreaIdx); mpWorld->SetAreaLayerInfo(pArea); - mpWorldEditor->SetArea(mpWorld, pArea); - mpWorldEditor->showMaximized(); + gpEdApp->WorldEditor()->SetArea(mpWorld, pArea); + gpEdApp->WorldEditor()->showMaximized(); } else @@ -188,8 +188,7 @@ void CProjectOverviewDialog::LaunchEditor() void CProjectOverviewDialog::LaunchResourceBrowser() { - CResourceBrowser *pBrowser = new CResourceBrowser(mpWorldEditor); - pBrowser->show(); + gpEdApp->ResourceBrowser()->show(); } void CProjectOverviewDialog::CookPackage() diff --git a/src/Editor/CProjectOverviewDialog.h b/src/Editor/CProjectOverviewDialog.h index e6dce89d..78b28ecb 100644 --- a/src/Editor/CProjectOverviewDialog.h +++ b/src/Editor/CProjectOverviewDialog.h @@ -14,7 +14,6 @@ class CProjectOverviewDialog : public QDialog { Q_OBJECT Ui::CProjectOverviewDialog *mpUI; - CWorldEditor *mpWorldEditor; CGameProject *mpProject; QVector mWorldEntries; @@ -35,6 +34,9 @@ public slots: void SetupWorldsList(); void SetupPackagesList(); + +signals: + void ActiveProjectChanged(CGameProject *pNewProj); }; #endif // CPROJECTOVERVIEWDIALOG_H diff --git a/src/Editor/Editor.pro b/src/Editor/Editor.pro index 7a0b07cc..7cbc219b 100644 --- a/src/Editor/Editor.pro +++ b/src/Editor/Editor.pro @@ -170,7 +170,8 @@ HEADERS += \ ResourceBrowser/CResourceProxyModel.h \ ResourceBrowser/CVirtualDirectoryModel.h \ CEditorApplication.h \ - IEditor.h + IEditor.h \ + Widgets/CResourceSelector.h # Source Files SOURCES += \ @@ -233,7 +234,8 @@ SOURCES += \ WorldEditor/CCollisionRenderSettingsDialog.cpp \ CProjectOverviewDialog.cpp \ ResourceBrowser/CResourceBrowser.cpp \ - CEditorApplication.cpp + CEditorApplication.cpp \ + Widgets/CResourceSelector.cpp # UI Files FORMS += \ diff --git a/src/Editor/Icons.qrc b/src/Editor/Icons.qrc index d152b660..5ce8682c 100644 --- a/src/Editor/Icons.qrc +++ b/src/Editor/Icons.qrc @@ -64,5 +64,8 @@ icons/Grid_24px.png icons/Grid_32px.png icons/OrbitCamera_32px.png + icons/X_16px.png + icons/ArrowL_16px.png + icons/Search_16px.png diff --git a/src/Editor/PropertyEdit/CPropertyDelegate.cpp b/src/Editor/PropertyEdit/CPropertyDelegate.cpp index df4de6e7..6b6ef64f 100644 --- a/src/Editor/PropertyEdit/CPropertyDelegate.cpp +++ b/src/Editor/PropertyEdit/CPropertyDelegate.cpp @@ -4,6 +4,7 @@ #include "Editor/UICommon.h" #include "Editor/Undo/CEditScriptPropertyCommand.h" #include "Editor/Undo/CResizeScriptArrayCommand.h" +#include "Editor/Widgets/CResourceSelector.h" #include "Editor/Widgets/WColorPicker.h" #include "Editor/Widgets/WDraggableSpinBox.h" #include "Editor/Widgets/WIntegralSpinBox.h" @@ -138,10 +139,9 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie case eAssetProperty: { - WResourceSelector *pSelector = new WResourceSelector(pParent); + CResourceSelector *pSelector = new CResourceSelector(pParent); CAssetTemplate *pTemp = static_cast(pProp->Template()); pSelector->SetAllowedExtensions(pTemp->AllowedExtensions()); - pSelector->setFont(qobject_cast(parent())->font()); // bit of a hack to stop the resource selector font from changing CONNECT_RELAY(pSelector, rkIndex, ResourceChanged(CResourceEntry*)) pOut = pSelector; @@ -307,7 +307,7 @@ void CPropertyDelegate::setEditorData(QWidget *pEditor, const QModelIndex &rkInd case eAssetProperty: { - WResourceSelector *pSelector = static_cast(pEditor); + CResourceSelector *pSelector = static_cast(pEditor); TAssetProperty *pAsset = static_cast(pProp); pSelector->SetResource(pAsset->Get()); break; @@ -462,8 +462,8 @@ void CPropertyDelegate::setModelData(QWidget *pEditor, QAbstractItemModel* /*pMo case eAssetProperty: { - WResourceSelector *pSelector = static_cast(pEditor); - CResourceEntry *pEntry = pSelector->GetResourceEntry(); + CResourceSelector *pSelector = static_cast(pEditor); + CResourceEntry *pEntry = pSelector->Entry(); TAssetProperty *pAsset = static_cast(pProp); pAsset->Set(pEntry ? pEntry->ID() : CAssetID::InvalidID(mpEditor->CurrentGame())); @@ -597,15 +597,14 @@ QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModel // Create widget if (Type == eAssetProperty) { - WResourceSelector *pSelector = new WResourceSelector(pParent); - pSelector->setFont(qobject_cast(parent())->font()); // hack to keep the selector font from changing + CResourceSelector *pSelector = new CResourceSelector(pParent); if (Params.Version() <= eEchoes) pSelector->SetAllowedExtensions("ANCS"); else pSelector->SetAllowedExtensions("CHAR"); - CONNECT_RELAY(pSelector, rkIndex, ResourceChanged(QString)); + CONNECT_RELAY(pSelector, rkIndex, ResourceChanged(CResourceEntry*)); return pSelector; } @@ -643,7 +642,7 @@ void CPropertyDelegate::SetCharacterEditorData(QWidget *pEditor, const QModelInd if (Type == eAssetProperty) { - static_cast(pEditor)->SetResource(Params.AnimSet()); + static_cast(pEditor)->SetResource(Params.AnimSet()); } else if (Type == eEnumProperty) @@ -667,7 +666,7 @@ void CPropertyDelegate::SetCharacterModelData(QWidget *pEditor, const QModelInde if (Type == eAssetProperty) { - Params.SetResource( static_cast(pEditor)->GetResourceEntry()->ID() ); + Params.SetResource( static_cast(pEditor)->Entry()->ID() ); // Reset all other parameters to 0 Params.SetCharIndex(0); for (u32 iUnk = 0; iUnk < 3; iUnk++) diff --git a/src/Editor/PropertyEdit/CPropertyView.cpp b/src/Editor/PropertyEdit/CPropertyView.cpp index 46eaf3cf..30114f2e 100644 --- a/src/Editor/PropertyEdit/CPropertyView.cpp +++ b/src/Editor/PropertyEdit/CPropertyView.cpp @@ -209,7 +209,7 @@ void CPropertyView::CreateContextMenu(const QPoint& rkPos) { QModelIndex Index = indexAt(rkPos); - if (Index.isValid()) + if (Index.isValid() && Index.column() == 0) { IProperty *pProp = mpModel->PropertyForIndex(Index, true); mpMenuProperty = pProp; diff --git a/src/Editor/ResourceBrowser/CResourceBrowser.cpp b/src/Editor/ResourceBrowser/CResourceBrowser.cpp index 17585a25..fb7fc6c2 100644 --- a/src/Editor/ResourceBrowser/CResourceBrowser.cpp +++ b/src/Editor/ResourceBrowser/CResourceBrowser.cpp @@ -11,6 +11,7 @@ CResourceBrowser::CResourceBrowser(QWidget *pParent) : QDialog(pParent) , mpUI(new Ui::CResourceBrowser) + , mpSelectedEntry(nullptr) , mpStore(gpResourceStore) { mpUI->setupUi(this); @@ -49,11 +50,12 @@ CResourceBrowser::CResourceBrowser(QWidget *pParent) pImportNamesMenu->addAction(pImportFromAssetNameMapAction); // Set up connections - connect(mpUI->StoreComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnStoreChanged(int))); + connect(mpUI->StoreComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(RefreshResources())); connect(mpUI->SearchBar, SIGNAL(textChanged(QString)), this, SLOT(OnSearchStringChanged())); connect(mpUI->SortComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSortModeChanged(int))); connect(mpUI->DirectoryTreeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(OnDirectorySelectionChanged(QModelIndex,QModelIndex))); connect(mpUI->ResourceTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnDoubleClickResource(QModelIndex))); + 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(mpUI->ExportNamesButton, SIGNAL(clicked()), this, SLOT(ExportAssetNames())); @@ -72,6 +74,7 @@ CResourceBrowser::~CResourceBrowser() void CResourceBrowser::RefreshResources() { // Fill resource table + mpStore = (mpUI->StoreComboBox->currentIndex() == 0 ? gpResourceStore : gpEditorStore); mpModel->FillEntryList(mpStore); // Fill directory tree @@ -82,12 +85,6 @@ void CResourceBrowser::RefreshResources() OnDirectorySelectionChanged(QModelIndex(), QModelIndex()); } -void CResourceBrowser::OnStoreChanged(int Index) -{ - mpStore = (Index == 0 ? gpResourceStore : gpEditorStore); - RefreshResources(); -} - void CResourceBrowser::OnSortModeChanged(int Index) { CResourceProxyModel::ESortMode Mode = (Index == 0 ? CResourceProxyModel::eSortByName : CResourceProxyModel::eSortBySize); @@ -147,6 +144,13 @@ void CResourceBrowser::OnDoubleClickResource(QModelIndex Index) QMessageBox::information(this, "Unsupported Resource", "The selected resource type is currently unsupported for editing."); } +void CResourceBrowser::OnResourceSelectionChanged(const QModelIndex& rkNewIndex, const QModelIndex& /*rkPrevIndex*/) +{ + QModelIndex SourceIndex = mpProxyModel->mapToSource(rkNewIndex); + mpSelectedEntry = mpModel->IndexEntry(SourceIndex); + emit SelectedResourceChanged(mpSelectedEntry); +} + void CResourceBrowser::OnImportPakContentsTxt() { QStringList PathList = QFileDialog::getOpenFileNames(this, "Open pak contents list", "", "*.pak.contents.txt"); diff --git a/src/Editor/ResourceBrowser/CResourceBrowser.h b/src/Editor/ResourceBrowser/CResourceBrowser.h index 720bea23..9be50a36 100644 --- a/src/Editor/ResourceBrowser/CResourceBrowser.h +++ b/src/Editor/ResourceBrowser/CResourceBrowser.h @@ -15,6 +15,7 @@ class CResourceBrowser : public QDialog { Q_OBJECT Ui::CResourceBrowser *mpUI; + CResourceEntry *mpSelectedEntry; CResourceStore *mpStore; CResourceTableModel *mpModel; CResourceProxyModel *mpProxyModel; @@ -24,19 +25,25 @@ class CResourceBrowser : public QDialog public: explicit CResourceBrowser(QWidget *pParent = 0); ~CResourceBrowser(); - void RefreshResources(); + + // Accessors + inline CResourceEntry* SelectedEntry() const { return mpSelectedEntry; } public slots: - void OnStoreChanged(int Index); + void RefreshResources(); void OnSortModeChanged(int Index); void OnSearchStringChanged(); void OnDirectorySelectionChanged(const QModelIndex& rkNewIndex, const QModelIndex& rkPrevIndex); void OnDoubleClickResource(QModelIndex Index); + void OnResourceSelectionChanged(const QModelIndex& rkNewIndex, const QModelIndex& rkPrevIndex); void OnImportPakContentsTxt(); void OnGenerateAssetNames(); void OnImportNamesFromAssetNameMap(); void ExportAssetNames(); void UpdateFilter(); + +signals: + void SelectedResourceChanged(CResourceEntry *pNewRes); }; #endif // CRESOURCEBROWSER_H diff --git a/src/Editor/Widgets/CResourceSelector.cpp b/src/Editor/Widgets/CResourceSelector.cpp new file mode 100644 index 00000000..f90d4fbd --- /dev/null +++ b/src/Editor/Widgets/CResourceSelector.cpp @@ -0,0 +1,135 @@ +#include "CResourceSelector.h" +#include "Editor/CEditorApplication.h" +#include "Editor/UICommon.h" +#include "Editor/ResourceBrowser/CResourceBrowser.h" +#include +#include +#include +#include +#include + +CResourceSelector::CResourceSelector(QWidget *pParent /*= 0*/) + : QWidget(pParent) + , mpResEntry(nullptr) +{ + setContextMenuPolicy(Qt::CustomContextMenu); + + // Set up UI + mpResNameLabel = new QLabel(this); + + mpSetButton = new QPushButton(this); + mpSetButton->setToolTip("Set"); + mpSetButton->setIcon(QIcon(":/icons/ArrowL_16px.png")); + mpSetButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + mpSetButton->setFixedSize(16, 16); + + mpFindButton = new QPushButton(this); + mpFindButton->setToolTip("Find in Resource Browser"); + mpFindButton->setIcon(QIcon(":/icons/Search_16px.png")); + mpFindButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + mpFindButton->setFixedSize(16, 16); + + mpClearButton = new QPushButton(this); + mpClearButton->setToolTip("Clear"); + mpClearButton->setIcon(QIcon(":/icons/X_16px.png")); + mpClearButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + mpClearButton->setFixedSize(16, 16); + + mpLayout = new QHBoxLayout(this); + mpLayout->setSpacing(2); + mpLayout->setContentsMargins(0, 0, 0, 0); + mpLayout->addWidget(mpResNameLabel); + mpLayout->addWidget(mpSetButton); + mpLayout->addWidget(mpFindButton); + mpLayout->addWidget(mpClearButton); + setLayout(mpLayout); + + UpdateUI(); + + // UI Connections + connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CreateContextMenu(QPoint))); + connect(mpSetButton, SIGNAL(clicked()), this, SLOT(Set())); + connect(mpClearButton, SIGNAL(clicked()), this, SLOT(Clear())); + + // Set up context menu + mpCopyNameAction = new QAction("Copy name", this); + mpCopyPathAction = new QAction("Copy path", this); + + // Context menu connections + connect(mpCopyNameAction, SIGNAL(triggered()), this, SLOT(CopyName())); + connect(mpCopyPathAction, SIGNAL(triggered()), this, SLOT(CopyPath())); +} + +void CResourceSelector::UpdateUI() +{ + mpResNameLabel->setText(mpResEntry ? TO_QSTRING(mpResEntry->Name()) + "." + TO_QSTRING(mpResEntry->CookedExtension().ToString()) : ""); + mpResNameLabel->setToolTip(mpResEntry ? TO_QSTRING(mpResEntry->CookedAssetPath(true)) : ""); + mpFindButton->setEnabled(mpResEntry != nullptr); + mpClearButton->setEnabled(mpResEntry != nullptr); +} + +void CResourceSelector::SetAllowedExtensions(const QString& /*rkExtension*/) +{ + // todo +} + +void CResourceSelector::SetAllowedExtensions(const TStringList& /*rkExtensions*/) +{ + // todo +} + +void CResourceSelector::SetResource(const CAssetID& rkID) +{ + mpResEntry = gpResourceStore->FindEntry(rkID); + OnResourceChanged(); +} + +void CResourceSelector::SetResource(CResourceEntry *pEntry) +{ + mpResEntry = pEntry; + OnResourceChanged(); +} + +void CResourceSelector::SetResource(CResource *pRes) +{ + mpResEntry = (pRes ? pRes->Entry() : nullptr); + OnResourceChanged(); +} + +void CResourceSelector::CreateContextMenu(const QPoint& rkPoint) +{ + QMenu Menu; + Menu.addAction(mpCopyNameAction); + Menu.addAction(mpCopyPathAction); + Menu.exec(mapToGlobal(rkPoint)); +} + +void CResourceSelector::CopyName() +{ + gpEdApp->clipboard()->setText(mpResNameLabel->text()); +} + +void CResourceSelector::CopyPath() +{ + QString Text = (mpResEntry ? TO_QSTRING(mpResEntry->CookedAssetPath(true)) : ""); + gpEdApp->clipboard()->setText(Text); +} + +void CResourceSelector::Set() +{ + // todo - validate this resource is a valid type + mpResEntry = gpEdApp->ResourceBrowser()->SelectedEntry(); + OnResourceChanged(); +} + +void CResourceSelector::Clear() +{ + mpResEntry = nullptr; + OnResourceChanged(); +} + +void CResourceSelector::OnResourceChanged() +{ + UpdateUI(); + emit ResourceChanged(mpResEntry); +} diff --git a/src/Editor/Widgets/CResourceSelector.h b/src/Editor/Widgets/CResourceSelector.h new file mode 100644 index 00000000..c32b2aba --- /dev/null +++ b/src/Editor/Widgets/CResourceSelector.h @@ -0,0 +1,52 @@ +#ifndef CRESOURCESELECTOR +#define CRESOURCESELECTOR + +#include +#include +#include +#include +#include + +class CResourceSelector : public QWidget +{ + Q_OBJECT + + CResourceEntry *mpResEntry; + + // UI + QHBoxLayout *mpLayout; + QLabel *mpResNameLabel; + QPushButton *mpSetButton; + QPushButton *mpFindButton; + QPushButton *mpClearButton; + + // Context Menu + QAction *mpCopyNameAction; + QAction *mpCopyPathAction; + +public: + explicit CResourceSelector(QWidget *pParent = 0); + void SetAllowedExtensions(const QString& rkExtension); + void SetAllowedExtensions(const TStringList& rkExtensions); + void SetResource(const CAssetID& rkID); + void SetResource(CResourceEntry *pEntry); + void SetResource(CResource *pRes); + + // Accessors + inline CResourceEntry* Entry() const { return mpResEntry; } + +public slots: + void CreateContextMenu(const QPoint& rkPoint); + void Set(); + void Clear(); + void CopyName(); + void CopyPath(); + void OnResourceChanged(); + void UpdateUI(); + +signals: + void ResourceChanged(CResourceEntry *pNewRes); +}; + +#endif // CRESOURCESELECTOR + diff --git a/src/Editor/icons/ArrowL_16px.png b/src/Editor/icons/ArrowL_16px.png new file mode 100644 index 00000000..67a7b033 Binary files /dev/null and b/src/Editor/icons/ArrowL_16px.png differ diff --git a/src/Editor/icons/Search_16px.png b/src/Editor/icons/Search_16px.png new file mode 100644 index 00000000..15260414 Binary files /dev/null and b/src/Editor/icons/Search_16px.png differ diff --git a/src/Editor/icons/X_16px.png b/src/Editor/icons/X_16px.png new file mode 100644 index 00000000..eb80a747 Binary files /dev/null and b/src/Editor/icons/X_16px.png differ diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 9d98af5c..55b3ea90 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -58,8 +58,7 @@ int main(int argc, char *argv[]) qApp->setPalette(DarkPalette); // Execute application - CProjectOverviewDialog Dialog; - Dialog.show(); - + App.InitEditor(); + App.ProjectDialog()->show(); return App.exec(); }