Changed resource selector widgets so they can pop up a panel with a list of acceptable resources
This commit is contained in:
parent
2348b8514f
commit
581d5f7267
|
@ -229,7 +229,8 @@ HEADERS += \
|
|||
Resource/CMapArea.h \
|
||||
Resource/CSavedStateID.h \
|
||||
IProgressNotifier.h \
|
||||
IUIRelay.h
|
||||
IUIRelay.h \
|
||||
Resource/CResTypeFilter.h
|
||||
|
||||
# Source Files
|
||||
SOURCES += \
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef CRESTYPEFILTER_H
|
||||
#define CRESTYPEFILTER_H
|
||||
|
||||
#include "EResType.h"
|
||||
#include "CResTypeInfo.h"
|
||||
#include "Core/GameProject/CResourceEntry.h"
|
||||
|
||||
class CResTypeFilter
|
||||
{
|
||||
EGame mGame;
|
||||
std::set<EResType> mAcceptedTypes;
|
||||
|
||||
public:
|
||||
CResTypeFilter() { }
|
||||
CResTypeFilter(EGame Game, const TString& rkTypeList) { FromString(Game, rkTypeList); }
|
||||
|
||||
void SetAcceptedTypes(EGame Game, const TStringList& rkTypes)
|
||||
{
|
||||
mAcceptedTypes.clear();
|
||||
mGame = Game;
|
||||
|
||||
for (auto Iter = rkTypes.begin(); Iter != rkTypes.end(); Iter++)
|
||||
{
|
||||
CResTypeInfo *pTypeInfo = CResTypeInfo::TypeForCookedExtension(mGame, CFourCC(*Iter));
|
||||
|
||||
if (pTypeInfo)
|
||||
mAcceptedTypes.insert(pTypeInfo->Type());
|
||||
}
|
||||
}
|
||||
|
||||
TString ToString() const
|
||||
{
|
||||
TString Out;
|
||||
|
||||
for (auto Iter = mAcceptedTypes.begin(); Iter != mAcceptedTypes.end(); Iter++)
|
||||
{
|
||||
if (!Out.IsEmpty()) Out += ',';
|
||||
CResTypeInfo *pTypeInfo = CResTypeInfo::FindTypeInfo(*Iter);
|
||||
Out += pTypeInfo->CookedExtension(mGame).ToString();
|
||||
}
|
||||
|
||||
return Out;
|
||||
}
|
||||
|
||||
void FromString(EGame Game, const TString& rkString)
|
||||
{
|
||||
SetAcceptedTypes(Game, rkString.Split(","));
|
||||
}
|
||||
|
||||
inline bool Accepts(EResType Type) const
|
||||
{
|
||||
return mAcceptedTypes.find(Type) != mAcceptedTypes.end();
|
||||
}
|
||||
|
||||
inline bool Accepts(CResTypeInfo *pType) const
|
||||
{
|
||||
return pType && Accepts(pType->Type());
|
||||
}
|
||||
|
||||
inline bool Accepts(CResourceEntry *pEntry) const
|
||||
{
|
||||
return pEntry && Accepts(pEntry->ResourceType());
|
||||
}
|
||||
|
||||
inline bool Accepts(const CResTypeFilter& rkFilter) const
|
||||
{
|
||||
for (auto Iter = mAcceptedTypes.begin(); Iter != mAcceptedTypes.end(); Iter++)
|
||||
{
|
||||
if (rkFilter.Accepts(*Iter))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool operator==(const CResTypeFilter& rkOther) const
|
||||
{
|
||||
return mAcceptedTypes == rkOther.mAcceptedTypes;
|
||||
}
|
||||
|
||||
inline bool operator!=(const CResTypeFilter& rkOther) const
|
||||
{
|
||||
return !(*this == rkOther);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CRESTYPEFILTER_H
|
|
@ -93,8 +93,12 @@ CResTypeInfo* CResTypeInfo::TypeForCookedExtension(EGame Game, CFourCC Ext)
|
|||
}
|
||||
|
||||
// Haven't found it; caller gave us an invalid type
|
||||
Log::Error("Failed to find resource type for cooked extension: " + Ext.ToString());
|
||||
DEBUG_BREAK;
|
||||
// Note UNKN is used to indicate unknown asset type
|
||||
if (Ext != FOURCC('UNKN'))
|
||||
{
|
||||
Log::Error("Failed to find resource type for cooked extension: " + Ext.ToString());
|
||||
DEBUG_BREAK;
|
||||
}
|
||||
sCachedTypeMap[Ext] = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -624,13 +624,8 @@ void CTemplateWriter::SaveProperties(XMLDocument *pDoc, XMLElement *pParent, CSt
|
|||
if (pProp->Type() == eAssetProperty)
|
||||
{
|
||||
CAssetTemplate *pAsset = static_cast<CAssetTemplate*>(pProp);
|
||||
const TStringList& rkExtensions = pAsset->AllowedExtensions();
|
||||
TString ExtensionsString;
|
||||
|
||||
for (auto it = rkExtensions.begin(); it != rkExtensions.end(); it++)
|
||||
ExtensionsString += *it + ",";
|
||||
|
||||
ExtensionsString = ExtensionsString.ChopBack(1); // Remove extra comma
|
||||
const CResTypeFilter& rkFilter = pAsset->TypeFilter();
|
||||
TString ExtensionsString = rkFilter.ToString();
|
||||
if (ExtensionsString.IsEmpty()) ExtensionsString = "UNKN";
|
||||
pElem->SetAttribute("extensions", *ExtensionsString);
|
||||
}
|
||||
|
@ -796,14 +791,9 @@ void CTemplateWriter::SavePropertyOverrides(XMLDocument *pDoc, XMLElement *pPare
|
|||
CAssetTemplate *pAsset = static_cast<CAssetTemplate*>(pProp);
|
||||
CAssetTemplate *pSourceAsset = static_cast<CAssetTemplate*>(pSource);
|
||||
|
||||
if (pAsset->AllowedExtensions() != pSourceAsset->AllowedExtensions())
|
||||
if (pAsset->TypeFilter() != pSourceAsset->TypeFilter())
|
||||
{
|
||||
TString ExtensionsString;
|
||||
|
||||
for (auto it = pAsset->AllowedExtensions().begin(); it != pAsset->AllowedExtensions().end(); it++)
|
||||
ExtensionsString += *it + ",";
|
||||
|
||||
ExtensionsString = ExtensionsString.ChopBack(1);
|
||||
TString ExtensionsString = pAsset->TypeFilter().ToString();
|
||||
if (ExtensionsString.IsEmpty()) ExtensionsString = "UNKN";
|
||||
pElem->SetAttribute("extensions", *ExtensionsString);
|
||||
}
|
||||
|
|
|
@ -133,21 +133,11 @@ void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& rSCLY
|
|||
|
||||
if (pEntry)
|
||||
{
|
||||
TString CookedExt = pEntry->CookedExtension().ToString();
|
||||
const TStringList& rkExtensions = static_cast<CAssetTemplate*>(pTemp)->AllowedExtensions();
|
||||
bool Valid = false;
|
||||
|
||||
for (auto It = rkExtensions.begin(); It != rkExtensions.end(); It++)
|
||||
{
|
||||
if (*It == CookedExt)
|
||||
{
|
||||
Valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const CResTypeFilter& rkFilter = static_cast<CAssetTemplate*>(pTemp)->TypeFilter();
|
||||
bool Valid = rkFilter.Accepts(pEntry->ResourceType());
|
||||
|
||||
if (!Valid)
|
||||
Log::FileWarning(rSCLY.GetSourceString(), rSCLY.Tell() - ID.Length(), "Asset property \"" + pTemp->FullName() + "\" (" + pTemp->IDString(true) + ") has a reference to an illegal asset type: " + CookedExt);
|
||||
Log::FileWarning(rSCLY.GetSourceString(), rSCLY.Tell() - ID.Length(), "Asset property \"" + pTemp->FullName() + "\" (" + pTemp->IDString(true) + ") has a reference to an illegal asset type: " + pEntry->CookedExtension());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ IPropertyTemplate* CTemplateLoader::LoadProperty(XMLElement *pElem, CScriptTempl
|
|||
{
|
||||
TStringList ExtensionsList = ExtensionsAttr.Split(", ");
|
||||
CAssetTemplate *pAsset = static_cast<CAssetTemplate*>(pProp);
|
||||
pAsset->SetAllowedExtensions(ExtensionsList);
|
||||
pAsset->SetTypeFilter(ExtensionsList);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -606,7 +606,7 @@ CScriptTemplate* CTemplateLoader::LoadScriptTemplate(XMLDocument *pDoc, const TS
|
|||
|
||||
if (!pProp)
|
||||
Log::Error(rkTemplateName + ": Invalid property for attachment " + TString::FromInt32(AttachIdx) + ": " + Attachment.AttachProperty);
|
||||
else if (pProp->Type() != eCharacterProperty && (pProp->Type() != eAssetProperty || !static_cast<CAssetTemplate*>(pProp)->AcceptsExtension("CMDL")))
|
||||
else if (pProp->Type() != eCharacterProperty && (pProp->Type() != eAssetProperty || !static_cast<CAssetTemplate*>(pProp)->TypeFilter().Accepts(eModel)))
|
||||
Log::Error(rkTemplateName + ": Property referred to by attachment " + TString::FromInt32(AttachIdx) + " is not an attachable asset! Must be a file property that accepts CMDLs, or a character property.");
|
||||
|
||||
else
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "EPropertyType.h"
|
||||
#include "IProperty.h"
|
||||
#include "IPropertyValue.h"
|
||||
#include "Core/Resource/CResTypeFilter.h"
|
||||
#include "Core/Resource/Animation/CAnimationParameters.h"
|
||||
#include <Common/CColor.h>
|
||||
#include <Common/TString.h>
|
||||
|
@ -389,7 +390,7 @@ class CAssetTemplate : public IPropertyTemplate
|
|||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
TStringList mAcceptedExtensions;
|
||||
CResTypeFilter mTypeFilter;
|
||||
public:
|
||||
CAssetTemplate(u32 ID, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
|
||||
: IPropertyTemplate(ID, pScript, pMaster, pParent) {}
|
||||
|
@ -411,7 +412,7 @@ public:
|
|||
virtual void Copy(const IPropertyTemplate *pkTemp)
|
||||
{
|
||||
IPropertyTemplate::Copy(pkTemp);
|
||||
mAcceptedExtensions = static_cast<const CAssetTemplate*>(pkTemp)->mAcceptedExtensions;
|
||||
mTypeFilter = static_cast<const CAssetTemplate*>(pkTemp)->mTypeFilter;
|
||||
}
|
||||
|
||||
virtual bool Matches(const IPropertyTemplate *pkTemp) const
|
||||
|
@ -419,18 +420,11 @@ public:
|
|||
const CAssetTemplate *pkAsset = static_cast<const CAssetTemplate*>(pkTemp);
|
||||
|
||||
return ( (IPropertyTemplate::Matches(pkTemp)) &&
|
||||
(mAcceptedExtensions == pkAsset->mAcceptedExtensions) );
|
||||
(mTypeFilter == pkAsset->mTypeFilter) );
|
||||
}
|
||||
|
||||
bool AcceptsExtension(const TString& rkExtension)
|
||||
{
|
||||
for (auto it = mAcceptedExtensions.begin(); it != mAcceptedExtensions.end(); it++)
|
||||
if (*it == rkExtension) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetAllowedExtensions(const TStringList& rkExtensions) { mAcceptedExtensions = rkExtensions; }
|
||||
const TStringList& AllowedExtensions() const { return mAcceptedExtensions; }
|
||||
void SetTypeFilter(const TStringList& rkExtensions) { mTypeFilter.SetAcceptedTypes(Game(), rkExtensions); }
|
||||
const CResTypeFilter& TypeFilter() const { return mTypeFilter; }
|
||||
};
|
||||
|
||||
// CEnumTemplate - Property template for enums. Tracks a list of possible values (enumerators).
|
||||
|
|
|
@ -476,13 +476,14 @@ void CScriptNode::PropertyModified(IProperty *pProp)
|
|||
else if (pProp->Type() == eAssetProperty)
|
||||
{
|
||||
CAssetTemplate *pAssetTemp = static_cast<CAssetTemplate*>(pProp->Template());
|
||||
const CResTypeFilter& rkFilter = pAssetTemp->TypeFilter();
|
||||
|
||||
if (pAssetTemp->AcceptsExtension("CMDL") || pAssetTemp->AcceptsExtension("TXTR") || pAssetTemp->AcceptsExtension("ANCS") || pAssetTemp->AcceptsExtension("CHAR"))
|
||||
if (rkFilter.Accepts(eModel) || rkFilter.Accepts(eTexture) || rkFilter.Accepts(eAnimSet) || rkFilter.Accepts(eCharacter))
|
||||
{
|
||||
mpInstance->EvaluateDisplayAsset();
|
||||
SetDisplayAsset(mpInstance->DisplayAsset());
|
||||
}
|
||||
else if (pAssetTemp->AcceptsExtension("DCLN"))
|
||||
else if (rkFilter.Accepts(eDynamicCollision))
|
||||
{
|
||||
mpInstance->EvaluateCollisionModel();
|
||||
mpCollisionNode->SetCollision(mpInstance->Collision());
|
||||
|
|
|
@ -183,7 +183,9 @@ HEADERS += \
|
|||
WorldEditor/CWorldEditorSidebar.h \
|
||||
CProgressDialog.h \
|
||||
IProgressNotifierUI.h \
|
||||
CUIRelay.h
|
||||
CUIRelay.h \
|
||||
Widgets/CSelectResourcePanel.h \
|
||||
Widgets/CFilteredResourceModel.h
|
||||
|
||||
# Source Files
|
||||
SOURCES += \
|
||||
|
@ -250,7 +252,8 @@ SOURCES += \
|
|||
CProjectSettingsDialog.cpp \
|
||||
WorldEditor/CPoiMapSidebar.cpp \
|
||||
WorldEditor/CWorldEditorSidebar.cpp \
|
||||
CProgressDialog.cpp
|
||||
CProgressDialog.cpp \
|
||||
Widgets/CSelectResourcePanel.cpp
|
||||
|
||||
# UI Files
|
||||
FORMS += \
|
||||
|
@ -275,4 +278,5 @@ FORMS += \
|
|||
WorldEditor/CWorldInfoSidebar.ui \
|
||||
CProjectSettingsDialog.ui \
|
||||
WorldEditor/CPoiMapSidebar.ui \
|
||||
CProgressDialog.ui
|
||||
CProgressDialog.ui \
|
||||
Widgets/CSelectResourcePanel.ui
|
||||
|
|
|
@ -72,5 +72,6 @@
|
|||
<file>icons/Disc_16px.png</file>
|
||||
<file>icons/World_16px.png</file>
|
||||
<file>icons/PoiSymbol_24px.png</file>
|
||||
<file>icons/ArrowD_16px.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -44,8 +44,8 @@ CModelEditorWindow::CModelEditorWindow(CModel *pModel, QWidget *pParent)
|
|||
|
||||
// UI initialization
|
||||
UpdateAnimParamUI(-1);
|
||||
ui->IndTextureResSelector->SetAllowedExtensions("TXTR");
|
||||
ui->PassTextureResSelector->SetAllowedExtensions("TXTR");
|
||||
ui->IndTextureResSelector->SetTypeFilter(pModel->Game(), "TXTR");
|
||||
ui->PassTextureResSelector->SetTypeFilter(pModel->Game(), "TXTR");
|
||||
ui->PassTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
ui->PassTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
|
||||
ui->ClearColorPicker->SetColor(QColor(76, 76, 76, 255));
|
||||
|
|
|
@ -143,7 +143,7 @@ QWidget* CPropertyDelegate::createEditor(QWidget *pParent, const QStyleOptionVie
|
|||
pSelector->SetFrameVisible(false);
|
||||
|
||||
CAssetTemplate *pTemp = static_cast<CAssetTemplate*>(pProp->Template());
|
||||
pSelector->SetAllowedExtensions(pTemp->AllowedExtensions());
|
||||
pSelector->SetTypeFilter(pTemp->TypeFilter());
|
||||
|
||||
CONNECT_RELAY(pSelector, rkIndex, ResourceChanged(CResourceEntry*))
|
||||
pOut = pSelector;
|
||||
|
@ -603,9 +603,9 @@ QWidget* CPropertyDelegate::CreateCharacterEditor(QWidget *pParent, const QModel
|
|||
pSelector->SetFrameVisible(false);
|
||||
|
||||
if (Params.Version() <= eEchoes)
|
||||
pSelector->SetAllowedExtensions("ANCS");
|
||||
pSelector->SetTypeFilter(mpEditor->CurrentGame(), "ANCS");
|
||||
else
|
||||
pSelector->SetAllowedExtensions("CHAR");
|
||||
pSelector->SetTypeFilter(mpEditor->CurrentGame(), "CHAR");
|
||||
|
||||
CONNECT_RELAY(pSelector, rkIndex, ResourceChanged(CResourceEntry*));
|
||||
return pSelector;
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
#ifndef CFILTEREDRESOURCEMODEL_H
|
||||
#define CFILTEREDRESOURCEMODEL_H
|
||||
|
||||
#include "CResourceSelector.h"
|
||||
#include "Editor/UICommon.h"
|
||||
|
||||
#include <Core/GameProject/CResourceEntry.h>
|
||||
#include <Core/GameProject/CResourceIterator.h>
|
||||
#include <Core/Resource/CResTypeFilter.h>
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class CFilteredResourceModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
QVector<CResourceEntry*> mEntries;
|
||||
int mInitialRow;
|
||||
|
||||
public:
|
||||
CFilteredResourceModel(CResourceSelector *pSelector, QObject *pParent = 0)
|
||||
: QAbstractTableModel(pParent)
|
||||
, mInitialRow(0)
|
||||
{
|
||||
const CResTypeFilter& rkFilter = pSelector->TypeFilter();
|
||||
|
||||
for (CResourceIterator It; It; ++It)
|
||||
{
|
||||
if (rkFilter.Accepts(*It))
|
||||
{
|
||||
mEntries << *It;
|
||||
}
|
||||
}
|
||||
|
||||
qSort(mEntries.begin(), mEntries.end(), [](CResourceEntry *pA, CResourceEntry *pB) -> bool {
|
||||
return pA->UppercaseName() < pB->UppercaseName();
|
||||
});
|
||||
|
||||
for (int ResIdx = 0; ResIdx < mEntries.size(); ResIdx++)
|
||||
{
|
||||
if (mEntries[ResIdx] == pSelector->Entry())
|
||||
{
|
||||
mInitialRow = ResIdx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// QAbstractTableModel interface
|
||||
int rowCount(const QModelIndex&) const
|
||||
{
|
||||
return mEntries.size();
|
||||
}
|
||||
|
||||
int columnCount(const QModelIndex&) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex& rkIndex, int Role) const
|
||||
{
|
||||
CResourceEntry *pEntry = EntryForIndex(rkIndex);
|
||||
|
||||
if (rkIndex.column() == 0)
|
||||
{
|
||||
if (Role == Qt::DisplayRole)
|
||||
{
|
||||
return TO_QSTRING( pEntry->Name() + "." + pEntry->CookedExtension() );
|
||||
}
|
||||
else if (Role == Qt::ToolTipRole)
|
||||
{
|
||||
return TO_QSTRING( pEntry->CookedAssetPath(true) );
|
||||
}
|
||||
else if (Role == Qt::DecorationRole)
|
||||
{
|
||||
return QIcon(":/icons/Sphere Preview.png");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Role == Qt::DisplayRole || Role == Qt::ToolTipRole)
|
||||
{
|
||||
return TO_QSTRING( pEntry->TypeInfo()->TypeName() );
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant::Invalid;
|
||||
}
|
||||
|
||||
// Accessors
|
||||
inline QModelIndex InitialIndex() const
|
||||
{
|
||||
return index(mInitialRow, 0);
|
||||
}
|
||||
|
||||
inline CResourceEntry* EntryForIndex(const QModelIndex& rkIndex) const
|
||||
{
|
||||
return mEntries[rkIndex.row()];
|
||||
}
|
||||
};
|
||||
|
||||
class CFilteredResourceProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
TString mSearchString;
|
||||
|
||||
public:
|
||||
CFilteredResourceProxyModel(QObject *pParent = 0)
|
||||
: QSortFilterProxyModel(pParent)
|
||||
{}
|
||||
|
||||
bool filterAcceptsRow(int SourceRow, const QModelIndex&) const
|
||||
{
|
||||
if (mSearchString.IsEmpty())
|
||||
return true;
|
||||
|
||||
CFilteredResourceModel *pModel = qobject_cast<CFilteredResourceModel*>(sourceModel());
|
||||
ASSERT(pModel);
|
||||
|
||||
QModelIndex SrcIndex = pModel->index(SourceRow, 0);
|
||||
return pModel->EntryForIndex(SrcIndex)->UppercaseName().Contains(mSearchString);
|
||||
}
|
||||
|
||||
inline void SetSearchString(const QString& rkString)
|
||||
{
|
||||
mSearchString = TO_TSTRING(rkString).ToUpper();
|
||||
invalidate();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CFILTEREDRESOURCEMODEL_H
|
|
@ -1,4 +1,5 @@
|
|||
#include "CResourceSelector.h"
|
||||
#include "CSelectResourcePanel.h"
|
||||
#include "Editor/CEditorApplication.h"
|
||||
#include "Editor/UICommon.h"
|
||||
#include "Editor/ResourceBrowser/CResourceBrowser.h"
|
||||
|
@ -20,11 +21,11 @@ CResourceSelector::CResourceSelector(QWidget *pParent /*= 0*/)
|
|||
mpResNameButton->setFlat(true);
|
||||
mpResNameButton->setStyleSheet("text-align:left; font-size:10pt; margin:0px; padding-left:2px");
|
||||
|
||||
mpSetButton = new QPushButton(this);
|
||||
mpSetButton->setToolTip("Use selected asset in Resource Browser");
|
||||
mpSetButton->setIcon(QIcon(":/icons/ArrowL_16px.png"));
|
||||
mpSetButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
mpSetButton->setFixedSize(16, 16);
|
||||
mpSelectButton = new QPushButton(this);
|
||||
mpSelectButton->setToolTip("Select Resource");
|
||||
mpSelectButton->setIcon(QIcon(":/icons/ArrowD_16px.png"));
|
||||
mpSelectButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
mpSelectButton->setFixedSize(16, 16);
|
||||
|
||||
mpClearButton = new QPushButton(this);
|
||||
mpClearButton->setToolTip("Clear");
|
||||
|
@ -36,7 +37,7 @@ CResourceSelector::CResourceSelector(QWidget *pParent /*= 0*/)
|
|||
mpFrameLayout->setSpacing(2);
|
||||
mpFrameLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mpFrameLayout->addWidget(mpResNameButton);
|
||||
mpFrameLayout->addWidget(mpSetButton);
|
||||
mpFrameLayout->addWidget(mpSelectButton);
|
||||
mpFrameLayout->addWidget(mpClearButton);
|
||||
mpFrame = new QFrame(this);
|
||||
mpFrame->setBackgroundRole(QPalette::AlternateBase);
|
||||
|
@ -51,7 +52,7 @@ CResourceSelector::CResourceSelector(QWidget *pParent /*= 0*/)
|
|||
// UI Connections
|
||||
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CreateContextMenu(QPoint)));
|
||||
connect(mpResNameButton, SIGNAL(clicked()), this, SLOT(Find()));
|
||||
connect(mpSetButton, SIGNAL(clicked()), this, SLOT(Set()));
|
||||
connect(mpSelectButton, SIGNAL(clicked()), this, SLOT(Select()));
|
||||
connect(mpClearButton, SIGNAL(clicked()), this, SLOT(Clear()));
|
||||
|
||||
// Set up context menu
|
||||
|
@ -75,7 +76,7 @@ void CResourceSelector::SetFrameVisible(bool Visible)
|
|||
|
||||
void CResourceSelector::SetEditable(bool Editable)
|
||||
{
|
||||
mpSetButton->setVisible(Editable);
|
||||
mpSelectButton->setVisible(Editable);
|
||||
mpClearButton->setVisible(Editable);
|
||||
mIsEditable = Editable;
|
||||
}
|
||||
|
@ -95,14 +96,16 @@ void CResourceSelector::UpdateUI()
|
|||
mpCopyPathAction->setEnabled(HasResource);
|
||||
}
|
||||
|
||||
void CResourceSelector::SetAllowedExtensions(const QString& /*rkExtension*/)
|
||||
void CResourceSelector::SetTypeFilter(const CResTypeFilter& rkFilter)
|
||||
{
|
||||
// todo
|
||||
mTypeFilter = rkFilter;
|
||||
ASSERT(!mpResEntry || mTypeFilter.Accepts(mpResEntry));
|
||||
}
|
||||
|
||||
void CResourceSelector::SetAllowedExtensions(const TStringList& /*rkExtensions*/)
|
||||
void CResourceSelector::SetTypeFilter(EGame Game, const TString& rkTypeList)
|
||||
{
|
||||
// todo
|
||||
mTypeFilter.FromString(Game, rkTypeList);
|
||||
ASSERT(!mpResEntry || mTypeFilter.Accepts(mpResEntry));
|
||||
}
|
||||
|
||||
void CResourceSelector::SetResource(const CAssetID& rkID)
|
||||
|
@ -149,16 +152,9 @@ void CResourceSelector::CopyPath()
|
|||
gpEdApp->clipboard()->setText(Text);
|
||||
}
|
||||
|
||||
void CResourceSelector::Set()
|
||||
void CResourceSelector::Select()
|
||||
{
|
||||
// todo - validate this resource is a valid type
|
||||
CResourceBrowser *pBrowser = gpEdApp->ResourceBrowser();
|
||||
|
||||
if (pBrowser->isVisible() && pBrowser->SelectedEntry())
|
||||
{
|
||||
mpResEntry = gpEdApp->ResourceBrowser()->SelectedEntry();
|
||||
OnResourceChanged();
|
||||
}
|
||||
new CSelectResourcePanel(this);
|
||||
}
|
||||
|
||||
void CResourceSelector::Find()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define CRESOURCESELECTOR
|
||||
|
||||
#include <Core/GameProject/CResourceEntry.h>
|
||||
#include <Core/Resource/CResTypeFilter.h>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
@ -12,6 +13,7 @@ class CResourceSelector : public QWidget
|
|||
Q_OBJECT
|
||||
|
||||
CResourceEntry *mpResEntry;
|
||||
CResTypeFilter mTypeFilter;
|
||||
bool mIsEditable;
|
||||
|
||||
// UI
|
||||
|
@ -19,7 +21,7 @@ class CResourceSelector : public QWidget
|
|||
QHBoxLayout *mpFrameLayout;
|
||||
QFrame *mpFrame;
|
||||
QPushButton *mpResNameButton;
|
||||
QPushButton *mpSetButton;
|
||||
QPushButton *mpSelectButton;
|
||||
QPushButton *mpClearButton;
|
||||
|
||||
// Context Menu
|
||||
|
@ -31,19 +33,20 @@ public:
|
|||
explicit CResourceSelector(QWidget *pParent = 0);
|
||||
void SetFrameVisible(bool Visible);
|
||||
void SetEditable(bool Editable);
|
||||
void SetAllowedExtensions(const QString& rkExtension);
|
||||
void SetAllowedExtensions(const TStringList& rkExtensions);
|
||||
void SetTypeFilter(const CResTypeFilter& rkFilter);
|
||||
void SetTypeFilter(EGame Game, const TString& rkTypeList);
|
||||
void SetResource(const CAssetID& rkID);
|
||||
void SetResource(CResourceEntry *pEntry);
|
||||
void SetResource(CResource *pRes);
|
||||
|
||||
// Accessors
|
||||
inline CResourceEntry* Entry() const { return mpResEntry; }
|
||||
inline bool IsEditable() const { return mIsEditable; }
|
||||
inline CResourceEntry* Entry() const { return mpResEntry; }
|
||||
inline const CResTypeFilter& TypeFilter() const { return mTypeFilter; }
|
||||
inline bool IsEditable() const { return mIsEditable; }
|
||||
|
||||
public slots:
|
||||
void CreateContextMenu(const QPoint& rkPoint);
|
||||
void Set();
|
||||
void Select();
|
||||
void Find();
|
||||
void Clear();
|
||||
void EditAsset();
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
#include "CSelectResourcePanel.h"
|
||||
#include "ui_CSelectResourcePanel.h"
|
||||
#include "Editor/CEditorApplication.h"
|
||||
#include <Math/MathUtil.h>
|
||||
#include <QDesktopWidget>
|
||||
#include <QDebug>
|
||||
|
||||
CSelectResourcePanel::CSelectResourcePanel(CResourceSelector *pSelector)
|
||||
: QWidget(pSelector)
|
||||
, mpUI(new Ui::CSelectResourcePanel)
|
||||
, mpSelector(pSelector)
|
||||
, mModel(pSelector)
|
||||
{
|
||||
setWindowFlags( windowFlags() | Qt::FramelessWindowHint | Qt::Window );
|
||||
|
||||
mpUI->setupUi(this);
|
||||
mProxyModel.setSourceModel(&mModel);
|
||||
mpUI->ResourceTableView->setModel(&mProxyModel);
|
||||
|
||||
// Signals/slots
|
||||
connect(gpEdApp, SIGNAL(focusChanged(QWidget*,QWidget*)), this, SLOT(FocusChanged(QWidget*,QWidget*)));
|
||||
connect(mpUI->SearchBar, SIGNAL(StoppedTyping(QString)), this, SLOT(SearchStringChanged(QString)));
|
||||
connect(mpUI->ResourceTableView, SIGNAL(clicked(QModelIndex)), this, SLOT(ResourceClicked(QModelIndex)));
|
||||
|
||||
// Determine size
|
||||
QPoint SelectorPos = pSelector->parentWidget()->mapToGlobal( pSelector->pos() );
|
||||
QRect ScreenRect = gpEdApp->desktop()->availableGeometry();
|
||||
|
||||
int MaxWidthLeft = SelectorPos.x();
|
||||
int MaxWidthRight = ScreenRect.width() - SelectorPos.x() - pSelector->width();
|
||||
int MaxWidth = Math::Max(MaxWidthLeft, MaxWidthRight);
|
||||
|
||||
int MaxHeightTop = SelectorPos.y();
|
||||
int MaxHeightBottom = ScreenRect.height() - SelectorPos.y() - pSelector->height();
|
||||
int MaxHeight = Math::Max(MaxHeightTop, MaxHeightBottom);
|
||||
|
||||
QSize PanelSize(Math::Min(width(), MaxWidth), Math::Min(height(), MaxHeight));
|
||||
|
||||
// Determine position; place wherever we have the most amount of space
|
||||
QPoint PanelPos;
|
||||
|
||||
if (MaxHeightTop > MaxHeightBottom)
|
||||
PanelPos.ry() = SelectorPos.y() - PanelSize.height();
|
||||
else
|
||||
PanelPos.ry() = SelectorPos.y() + pSelector->height();
|
||||
|
||||
if (MaxWidthLeft > MaxWidthRight)
|
||||
PanelPos.rx() = SelectorPos.x() + (pSelector->width() - PanelSize.width());
|
||||
else
|
||||
PanelPos.rx() = SelectorPos.x();
|
||||
|
||||
// Clamp position to screen boundaries
|
||||
PanelPos.rx() = Math::Clamp(0, ScreenRect.width() - PanelSize.width(), PanelPos.x());
|
||||
PanelPos.ry() = Math::Clamp(0, ScreenRect.height() - PanelSize.height(), PanelPos.y());
|
||||
|
||||
// Create widget geometry
|
||||
QRect PanelRect(PanelPos, PanelSize);
|
||||
setGeometry(PanelRect);
|
||||
|
||||
// Jump to the currently-selected resource
|
||||
QModelIndex Index = mModel.InitialIndex();
|
||||
QModelIndex ProxyIndex = mProxyModel.mapFromSource(Index);
|
||||
|
||||
mpUI->ResourceTableView->scrollTo(ProxyIndex, QAbstractItemView::PositionAtCenter);
|
||||
mpUI->ResourceTableView->selectionModel()->setCurrentIndex(ProxyIndex, QItemSelectionModel::ClearAndSelect);
|
||||
|
||||
// Show
|
||||
show();
|
||||
mpUI->SearchBar->setFocus();
|
||||
}
|
||||
|
||||
CSelectResourcePanel::~CSelectResourcePanel()
|
||||
{
|
||||
delete mpUI;
|
||||
}
|
||||
|
||||
// Slots
|
||||
void CSelectResourcePanel::FocusChanged(QWidget*, QWidget *pNew)
|
||||
{
|
||||
// Destroy when the panel loses focus
|
||||
if (pNew != this && !isAncestorOf(pNew))
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void CSelectResourcePanel::SearchStringChanged(QString SearchString)
|
||||
{
|
||||
mProxyModel.SetSearchString(SearchString);
|
||||
}
|
||||
|
||||
void CSelectResourcePanel::ResourceClicked(QModelIndex Index)
|
||||
{
|
||||
QModelIndex SourceIndex = mProxyModel.mapToSource(Index);
|
||||
CResourceEntry *pEntry = mModel.EntryForIndex(SourceIndex);
|
||||
mpSelector->SetResource(pEntry);
|
||||
close();
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef CSELECTRESOURCEPANEL_H
|
||||
#define CSELECTRESOURCEPANEL_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "CFilteredResourceModel.h"
|
||||
#include "CResourceSelector.h"
|
||||
|
||||
namespace Ui {
|
||||
class CSelectResourcePanel;
|
||||
}
|
||||
|
||||
class CSelectResourcePanel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Ui::CSelectResourcePanel *mpUI;
|
||||
CResourceSelector *mpSelector;
|
||||
|
||||
CFilteredResourceModel mModel;
|
||||
CFilteredResourceProxyModel mProxyModel;
|
||||
|
||||
public:
|
||||
explicit CSelectResourcePanel(CResourceSelector *pSelector);
|
||||
~CSelectResourcePanel();
|
||||
|
||||
public slots:
|
||||
void FocusChanged(QWidget *pOld, QWidget *pNew);
|
||||
void SearchStringChanged(QString SearchString);
|
||||
void ResourceClicked(QModelIndex Index);
|
||||
};
|
||||
|
||||
#endif // CSELECTRESOURCEPANEL_H
|
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CSelectResourcePanel</class>
|
||||
<widget class="QWidget" name="CSelectResourcePanel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>360</width>
|
||||
<height>500</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="CTimedLineEdit" name="SearchBar">
|
||||
<property name="placeholderText">
|
||||
<string>Search...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableView" name="ResourceTableView">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="showGrid">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderDefaultSectionSize">
|
||||
<number>20</number>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>CTimedLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>Editor/Widgets/CTimedLineEdit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -606,8 +606,9 @@ void CWorldEditor::OnPropertyModified(IProperty *pProp)
|
|||
if (pProp->Type() == eAssetProperty)
|
||||
{
|
||||
CAssetTemplate *pAsset = static_cast<CAssetTemplate*>(pProp->Template());
|
||||
const CResTypeFilter& rkFilter = pAsset->TypeFilter();
|
||||
|
||||
if (pAsset->AcceptsExtension("CMDL") || pAsset->AcceptsExtension("ANCS") || pAsset->AcceptsExtension("CHAR"))
|
||||
if (rkFilter.Accepts(eModel) || rkFilter.Accepts(eAnimSet) || rkFilter.Accepts(eCharacter))
|
||||
SelectionModified();
|
||||
}
|
||||
else if (pProp->Type() == eCharacterProperty)
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 160 B |
Loading…
Reference in New Issue