Changed resource selector widgets so they can pop up a panel with a list of acceptable resources

This commit is contained in:
Aruki 2017-07-10 15:19:11 -06:00
parent 2348b8514f
commit 581d5f7267
20 changed files with 507 additions and 82 deletions

View File

@ -229,7 +229,8 @@ HEADERS += \
Resource/CMapArea.h \
Resource/CSavedStateID.h \
IProgressNotifier.h \
IUIRelay.h
IUIRelay.h \
Resource/CResTypeFilter.h
# Source Files
SOURCES += \

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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());
}
}

View File

@ -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

View File

@ -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).

View File

@ -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());

View File

@ -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

View File

@ -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>

View File

@ -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));

View File

@ -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;

View File

@ -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

View File

@ -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()

View File

@ -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();

View File

@ -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();
}

View File

@ -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

View File

@ -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>

View File

@ -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