Remove ResourceSelectorHost and clean up/refactor related bits (#3050)
* Sever dependency on legacy resource selector host Audio resource selectors (browse dialogs) no longer need to be registered with the legacy IResourceSelectorHost system. Set up a new EBus specifically to handle browse button presses and directly invokes the dialog. Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com> * Hook up legacy audio control selector to new EBus Remaining use of legacy audio selectors (trackview) need to be able to bypass ResourceSelectorHost now. Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com> * Removes ResourceSelectorHost and legacy selectors This removes various Variable types that were tied to resource selectors, such as GeomCache, Model, Animation, File. Removes the ResourceSelectorHost completely. The two things that still appeared to have selectors in TrackView are Audio Controls and Texture. Fixed the audio control selector to work via EBus and the Texture selector didn't seem to work at all, but left it in as it was. Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com> * Make the default audio selector return old value Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com> * Fix some signed/unsigned comparison warnings Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com> * Remove deleted function from Editor Mock Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com> * Change audio selector api to use string_view Per feedback. Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com>monroegm-disable-blank-issue-2
parent
b88a7faf64
commit
d6b268e84e
@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// Description : implementation file
|
|
||||||
|
|
||||||
#include "EditorDefs.h"
|
|
||||||
|
|
||||||
#include "ReflectedPropertiesPanel.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ReflectedPropertiesPanel dialog
|
|
||||||
|
|
||||||
|
|
||||||
ReflectedPropertiesPanel::ReflectedPropertiesPanel(QWidget* pParent)
|
|
||||||
: ReflectedPropertyControl(pParent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void ReflectedPropertiesPanel::DeleteVars()
|
|
||||||
{
|
|
||||||
ClearVarBlock();
|
|
||||||
m_updateCallbacks.clear();
|
|
||||||
m_varBlock = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void ReflectedPropertiesPanel::SetVarBlock(class CVarBlock* vb, ReflectedPropertyControl::UpdateVarCallback* updCallback, const char* category)
|
|
||||||
{
|
|
||||||
assert(vb);
|
|
||||||
|
|
||||||
m_varBlock = vb;
|
|
||||||
|
|
||||||
RemoveAllItems();
|
|
||||||
m_varBlock = vb;
|
|
||||||
AddVarBlock(m_varBlock, category);
|
|
||||||
|
|
||||||
SetUpdateCallback(AZStd::bind(&ReflectedPropertiesPanel::OnPropertyChanged, this, AZStd::placeholders::_1));
|
|
||||||
|
|
||||||
// When new object set all previous callbacks freed.
|
|
||||||
m_updateCallbacks.clear();
|
|
||||||
if (updCallback)
|
|
||||||
{
|
|
||||||
stl::push_back_unique(m_updateCallbacks, updCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void ReflectedPropertiesPanel::AddVars(CVarBlock* vb, ReflectedPropertyControl::UpdateVarCallback* updCallback, const char* category)
|
|
||||||
{
|
|
||||||
assert(vb);
|
|
||||||
|
|
||||||
bool bNewBlock = false;
|
|
||||||
// Make a clone of properties.
|
|
||||||
if (!m_varBlock)
|
|
||||||
{
|
|
||||||
RemoveAllItems();
|
|
||||||
m_varBlock = vb->Clone(true);
|
|
||||||
AddVarBlock(m_varBlock, category);
|
|
||||||
bNewBlock = true;
|
|
||||||
}
|
|
||||||
m_varBlock->Wire(vb);
|
|
||||||
|
|
||||||
if (bNewBlock)
|
|
||||||
{
|
|
||||||
SetUpdateCallback(AZStd::bind(&ReflectedPropertiesPanel::OnPropertyChanged, this, AZStd::placeholders::_1));
|
|
||||||
|
|
||||||
// When new object set all previous callbacks freed.
|
|
||||||
m_updateCallbacks.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updCallback)
|
|
||||||
{
|
|
||||||
stl::push_back_unique(m_updateCallbacks, updCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReflectedPropertiesPanel::OnPropertyChanged(IVariable* pVar)
|
|
||||||
{
|
|
||||||
std::list<ReflectedPropertyControl::UpdateVarCallback*>::iterator iter;
|
|
||||||
for (iter = m_updateCallbacks.begin(); iter != m_updateCallbacks.end(); ++iter)
|
|
||||||
{
|
|
||||||
(*iter)->operator()(pVar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CRYINCLUDE_EDITOR_REFLECTEDPROPERTIESPANEL_H
|
|
||||||
#define CRYINCLUDE_EDITOR_REFLECTEDPROPERTIESPANEL_H
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.h"
|
|
||||||
#include "Util/Variable.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ReflectedPropertiesPanel dialog
|
|
||||||
|
|
||||||
AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
|
||||||
//This class is a port of ReflectedPropertiesPanel to use the ReflectedPropertyControl
|
|
||||||
class SANDBOX_API ReflectedPropertiesPanel
|
|
||||||
: public ReflectedPropertyControl
|
|
||||||
{
|
|
||||||
AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
|
||||||
public:
|
|
||||||
ReflectedPropertiesPanel(QWidget* pParent = nullptr); // standard constructor
|
|
||||||
|
|
||||||
void DeleteVars();
|
|
||||||
void AddVars(class CVarBlock* vb, ReflectedPropertyControl::UpdateVarCallback* func = nullptr, const char* category = nullptr);
|
|
||||||
|
|
||||||
void SetVarBlock(class CVarBlock* vb, ReflectedPropertyControl::UpdateVarCallback* func = nullptr, const char* category = nullptr);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void OnPropertyChanged(IVariable* pVar);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
|
||||||
TSmartPtr<CVarBlock> m_varBlock;
|
|
||||||
|
|
||||||
std::list<ReflectedPropertyControl::UpdateVarCallback*> m_updateCallbacks;
|
|
||||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // CRYINCLUDE_EDITOR_REFLECTEDPROPERTIESPANEL_H
|
|
||||||
@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
// The aim of IResourceSelectorHost is to unify resource selection dialogs in a one
|
|
||||||
// API that can be reused with plugins. It also makes possible to register new
|
|
||||||
// resource selectors dynamically, e.g. inside plugins.
|
|
||||||
//
|
|
||||||
// Here is how new selectors are created. In your implementation file you add handler function:
|
|
||||||
//
|
|
||||||
// #include "IResourceSelectorHost.h"
|
|
||||||
//
|
|
||||||
// QString SoundFileSelector(const SResourceSelectorContext& x, const QString& previousValue)
|
|
||||||
// {
|
|
||||||
// CMyModalDialog dialog(CWnd::FromHandle(x.parentWindow));
|
|
||||||
// ...
|
|
||||||
// return previousValue;
|
|
||||||
// }
|
|
||||||
// REGISTER_RESOURCE_SELECTOR("Sound", SoundFileSelector, "Icons/sound_16x16.png")
|
|
||||||
//
|
|
||||||
// Here is how it can be invoked directly:
|
|
||||||
//
|
|
||||||
// SResourceSelectorContext x;
|
|
||||||
// x.parentWindow = parent.GetSafeHwnd();
|
|
||||||
// x.typeName = "Sound";
|
|
||||||
// string newValue = GetIEditor()->GetResourceSelector()->SelectResource(x, previousValue).c_str();
|
|
||||||
//
|
|
||||||
// If you have your own resource selectors in the plugin you will need to run
|
|
||||||
//
|
|
||||||
// RegisterModuleResourceSelectors(GetIEditor()->GetResourceSelector())
|
|
||||||
//
|
|
||||||
// during plugin initialization.
|
|
||||||
//
|
|
||||||
// If you want to be able to pass some custom context to the selector (e.g. source of the information for the
|
|
||||||
// list of items or something similar) then you can add a poitner argument to your selector function, i.e.:
|
|
||||||
//
|
|
||||||
// QString SoundFileSelector(const SResourceSelectorContext& x, const QString& previousValue,
|
|
||||||
// SoundFileList* list) // your context argument
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
class QWidget;
|
|
||||||
|
|
||||||
struct SResourceSelectorContext
|
|
||||||
{
|
|
||||||
const char* typeName;
|
|
||||||
|
|
||||||
// use either parentWidget or parentWindow (not both) until everything porting to QWidget.
|
|
||||||
QWidget* parentWidget;
|
|
||||||
|
|
||||||
unsigned int entityId;
|
|
||||||
void* contextObject;
|
|
||||||
|
|
||||||
SResourceSelectorContext()
|
|
||||||
: parentWidget(0)
|
|
||||||
, typeName(0)
|
|
||||||
, entityId(0)
|
|
||||||
, contextObject()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// TResourceSelecitonFunction is used to declare handlers for specific types.
|
|
||||||
//
|
|
||||||
// For canceled dialogs previousValue should be returned.
|
|
||||||
typedef QString (* TResourceSelectionFunction)(const SResourceSelectorContext& selectorContext, const QString& previousValue);
|
|
||||||
typedef QString (* TResourceSelectionFunctionWithContext)(const SResourceSelectorContext& selectorContext, const QString& previousValue, void* contextObject);
|
|
||||||
|
|
||||||
struct SStaticResourceSelectorEntry;
|
|
||||||
|
|
||||||
// See note at the beginning of the file.
|
|
||||||
struct IResourceSelectorHost
|
|
||||||
{
|
|
||||||
virtual ~IResourceSelectorHost() = default;
|
|
||||||
virtual QString SelectResource(const SResourceSelectorContext& context, const QString& previousValue) = 0;
|
|
||||||
virtual const char* ResourceIconPath(const char* typeName) const = 0;
|
|
||||||
|
|
||||||
virtual void RegisterResourceSelector(const SStaticResourceSelectorEntry* entry) = 0;
|
|
||||||
|
|
||||||
// secondary responsibility of this class is to store global selections
|
|
||||||
virtual void SetGlobalSelection(const char* resourceType, const char* value) = 0;
|
|
||||||
virtual const char* GetGlobalSelection(const char* resourceType) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
#define INTERNAL_RSH_COMBINE_UTIL(A, B) A##B
|
|
||||||
#define INTERNAL_RSH_COMBINE(A, B) INTERNAL_RSH_COMBINE_UTIL(A, B)
|
|
||||||
#define REGISTER_RESOURCE_SELECTOR(name, function, icon) \
|
|
||||||
static SStaticResourceSelectorEntry INTERNAL_RSH_COMBINE(selector_##function, __LINE__)((name), (function), (icon));
|
|
||||||
|
|
||||||
struct SStaticResourceSelectorEntry
|
|
||||||
{
|
|
||||||
const char* typeName;
|
|
||||||
TResourceSelectionFunction function;
|
|
||||||
TResourceSelectionFunctionWithContext functionWithContext;
|
|
||||||
const char* iconPath;
|
|
||||||
|
|
||||||
static SStaticResourceSelectorEntry*& GetFirst() { static SStaticResourceSelectorEntry* first; return first; }
|
|
||||||
SStaticResourceSelectorEntry* next;
|
|
||||||
|
|
||||||
SStaticResourceSelectorEntry(const char* typeName, TResourceSelectionFunction function, const char* icon)
|
|
||||||
: typeName(typeName)
|
|
||||||
, function(function)
|
|
||||||
, functionWithContext()
|
|
||||||
, iconPath(icon)
|
|
||||||
{
|
|
||||||
next = GetFirst();
|
|
||||||
GetFirst() = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
SStaticResourceSelectorEntry(const char* typeName, QString (*function)(const SResourceSelectorContext&, const QString& previousValue, T * context), const char* icon)
|
|
||||||
: typeName(typeName)
|
|
||||||
, function()
|
|
||||||
, functionWithContext(TResourceSelectionFunctionWithContext(function))
|
|
||||||
, iconPath(icon)
|
|
||||||
{
|
|
||||||
next = GetFirst();
|
|
||||||
GetFirst() = this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void RegisterModuleResourceSelectors(IResourceSelectorHost* editorResourceSelector)
|
|
||||||
{
|
|
||||||
for (SStaticResourceSelectorEntry* current = SStaticResourceSelectorEntry::GetFirst(); current != 0; current = current->next)
|
|
||||||
{
|
|
||||||
editorResourceSelector->RegisterResourceSelector(current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,163 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "EditorDefs.h"
|
|
||||||
|
|
||||||
#include "ResourceSelectorHost.h"
|
|
||||||
|
|
||||||
// Qt
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
// AzToolsFramework
|
|
||||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
|
||||||
#include <AzToolsFramework/AssetBrowser/Search/Filter.h>
|
|
||||||
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
|
|
||||||
|
|
||||||
|
|
||||||
class CResourceSelectorHost
|
|
||||||
: public IResourceSelectorHost
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CResourceSelectorHost()
|
|
||||||
{
|
|
||||||
RegisterModuleResourceSelectors(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SelectResource(const SResourceSelectorContext& context, const QString& previousValue) override
|
|
||||||
{
|
|
||||||
if (!context.typeName)
|
|
||||||
{
|
|
||||||
assert(false && "SResourceSelectorContext::typeName is not specified");
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
TTypeMap::iterator it = m_typeMap.find(context.typeName);
|
|
||||||
if (it == m_typeMap.end())
|
|
||||||
{
|
|
||||||
QMessageBox::critical(QApplication::activeWindow(), QString(), QObject::tr("No Resource Selector is registered for resource type \"%1\"").arg(context.typeName));
|
|
||||||
return previousValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString result = previousValue;
|
|
||||||
if (it->second->function)
|
|
||||||
{
|
|
||||||
result = it->second->function(context, previousValue);
|
|
||||||
}
|
|
||||||
else if (it->second->functionWithContext)
|
|
||||||
{
|
|
||||||
result = it->second->functionWithContext(context, previousValue, context.contextObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* ResourceIconPath(const char* typeName) const override
|
|
||||||
{
|
|
||||||
TTypeMap::const_iterator it = m_typeMap.find(typeName);
|
|
||||||
if (it != m_typeMap.end())
|
|
||||||
{
|
|
||||||
return it->second->iconPath;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegisterResourceSelector(const SStaticResourceSelectorEntry* entry) override
|
|
||||||
{
|
|
||||||
m_typeMap[entry->typeName] = entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetGlobalSelection(const char* resourceType, const char* value) override
|
|
||||||
{
|
|
||||||
if (!resourceType || !value)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_globallySelectedResources[resourceType] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* GetGlobalSelection(const char* resourceType) const override
|
|
||||||
{
|
|
||||||
if (!resourceType)
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
auto it = m_globallySelectedResources.find(resourceType);
|
|
||||||
if (it != m_globallySelectedResources.end())
|
|
||||||
{
|
|
||||||
return it->second.c_str();
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
using TTypeMap = std::map<AZStd::string, const SStaticResourceSelectorEntry *, stl::less_stricmp<AZStd::string>>;
|
|
||||||
TTypeMap m_typeMap;
|
|
||||||
|
|
||||||
std::map<AZStd::string, AZStd::string> m_globallySelectedResources;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
IResourceSelectorHost* CreateResourceSelectorHost()
|
|
||||||
{
|
|
||||||
return new CResourceSelectorHost();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
QString SoundFileSelector([[maybe_unused]] const SResourceSelectorContext& x, const QString& previousValue)
|
|
||||||
{
|
|
||||||
AssetSelectionModel selection = AssetSelectionModel::AssetTypeSelection("Audio");
|
|
||||||
AzToolsFramework::EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::BrowseForAssets, selection);
|
|
||||||
if (selection.IsValid())
|
|
||||||
{
|
|
||||||
return Path::FullPathToGamePath(QString(selection.GetResult()->GetFullPath().c_str()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Path::FullPathToGamePath(previousValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
REGISTER_RESOURCE_SELECTOR("Sound", SoundFileSelector, "")
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
QString ModelFileSelector([[maybe_unused]] const SResourceSelectorContext& x, const QString& previousValue)
|
|
||||||
{
|
|
||||||
AssetSelectionModel selection = AssetSelectionModel::AssetGroupSelection("Geometry");
|
|
||||||
AzToolsFramework::EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::BrowseForAssets, selection);
|
|
||||||
if (selection.IsValid())
|
|
||||||
{
|
|
||||||
return Path::FullPathToGamePath(QString(selection.GetResult()->GetFullPath().c_str()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Path::FullPathToGamePath(previousValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
REGISTER_RESOURCE_SELECTOR("Model", ModelFileSelector, "")
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
QString GeomCacheFileSelector([[maybe_unused]] const SResourceSelectorContext& x, const QString& previousValue)
|
|
||||||
{
|
|
||||||
AssetSelectionModel selection = AssetSelectionModel::AssetTypeSelection("Geom Cache");
|
|
||||||
AzToolsFramework::EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::BrowseForAssets, selection);
|
|
||||||
if (selection.IsValid())
|
|
||||||
{
|
|
||||||
return Path::FullPathToGamePath(QString(selection.GetResult()->GetFullPath().c_str()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Path::FullPathToGamePath(previousValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER_RESOURCE_SELECTOR("GeomCache", GeomCacheFileSelector, "")
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CRYINCLUDE_EDITOR_RESOURCESELECTORHOST_H
|
|
||||||
#define CRYINCLUDE_EDITOR_RESOURCESELECTORHOST_H
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "IResourceSelectorHost.h"
|
|
||||||
|
|
||||||
IResourceSelectorHost* CreateResourceSelectorHost();
|
|
||||||
|
|
||||||
#endif // CRYINCLUDE_EDITOR_RESOURCESELECTORHOST_H
|
|
||||||
Loading…
Reference in New Issue