Major resource browser UI overhaul

This commit is contained in:
Aruki 2017-07-12 20:45:14 -06:00
parent 31dec78050
commit 137c10f28f
20 changed files with 607 additions and 452 deletions

View File

@ -262,7 +262,7 @@ void CPackage::Cook(IProgressNotifier *pProgress)
// Note: Compressed asset data can be stored in multiple blocks. Normally, the only assets that make use of this are textures,
// which can store each separate component of the file (header, palette, image data) in separate blocks. However, some textures
// are stored in one block, and I've had no luck figuring out why. The game doesn't generally seem to care whether textures use
// multiple blocks or not, so for the sake of complicity we compress everything to one block.
// multiple blocks or not, so for the sake of simplicity we compress everything to one block.
Pak.WriteFourCC( FOURCC('CMPD') );
Pak.WriteLong(1);
Pak.WriteLong(0xA0000000 | CompressedSize);

View File

@ -18,7 +18,6 @@ CEditorApplication::CEditorApplication(int& rArgc, char **ppArgv)
: QApplication(rArgc, ppArgv)
, mpActiveProject(nullptr)
, mpWorldEditor(nullptr)
, mpResourceBrowser(nullptr)
, mpProjectDialog(nullptr)
{
mLastUpdate = CTimer::GlobalTime();
@ -36,7 +35,6 @@ CEditorApplication::~CEditorApplication()
void CEditorApplication::InitEditor()
{
mpWorldEditor = new CWorldEditor();
mpResourceBrowser = new CResourceBrowser(mpWorldEditor);
mpProjectDialog = new CProjectSettingsDialog(mpWorldEditor);
mpWorldEditor->showMaximized();
}
@ -54,7 +52,6 @@ bool CEditorApplication::CloseAllEditors()
if (!mpWorldEditor->CloseWorld())
return false;
mpResourceBrowser->close();
mpProjectDialog->close();
return true;
}
@ -202,8 +199,6 @@ bool CEditorApplication::CookPackageList(QList<CPackage*> PackageList)
bool CEditorApplication::RebuildResourceDatabase()
{
bool BrowserIsOpen = mpResourceBrowser->isVisible();
// Make sure all editors are closed
if (mpActiveProject && CloseAllEditors())
{
@ -225,13 +220,6 @@ bool CEditorApplication::RebuildResourceDatabase()
mpActiveProject = pProj;
emit ActiveProjectChanged(pProj);
// If the resource browser was open before, then reopen it now
if (BrowserIsOpen)
{
mpResourceBrowser->show();
mpResourceBrowser->raise();
}
UICommon::InfoMsg(mpWorldEditor, "Success", "Resource database rebuilt successfully!");
return true;
}
@ -302,3 +290,8 @@ void CEditorApplication::OnEditorClose()
mpActiveProject->ResourceStore()->DestroyUnreferencedResources();
}
}
CResourceBrowser* CEditorApplication::ResourceBrowser() const
{
return mpWorldEditor->ResourceBrowser();
}

View File

@ -21,7 +21,6 @@ class CEditorApplication : public QApplication
CGameProject *mpActiveProject;
CWorldEditor *mpWorldEditor;
CResourceBrowser *mpResourceBrowser;
CProjectSettingsDialog *mpProjectDialog;
QVector<IEditor*> mEditorWindows;
QMap<CResourceEntry*,IEditor*> mEditingMap;
@ -45,10 +44,11 @@ public:
bool RebuildResourceDatabase();
CResourceBrowser* ResourceBrowser() const;
// Accessors
inline CGameProject* ActiveProject() const { return mpActiveProject; }
inline CWorldEditor* WorldEditor() const { return mpWorldEditor; }
inline CResourceBrowser* ResourceBrowser() const { return mpResourceBrowser; }
inline CProjectSettingsDialog* ProjectDialog() const { return mpProjectDialog; }
inline EGame CurrentGame() const { return mpActiveProject ? mpActiveProject->Game() : eUnknownGame; }

View File

@ -185,7 +185,8 @@ HEADERS += \
IProgressNotifierUI.h \
CUIRelay.h \
Widgets/CSelectResourcePanel.h \
Widgets/CFilteredResourceModel.h
Widgets/CFilteredResourceModel.h \
ResourceBrowser/CResourceDelegate.h
# Source Files
SOURCES += \
@ -253,7 +254,8 @@ SOURCES += \
WorldEditor/CPoiMapSidebar.cpp \
WorldEditor/CWorldEditorSidebar.cpp \
CProgressDialog.cpp \
Widgets/CSelectResourcePanel.cpp
Widgets/CSelectResourcePanel.cpp \
ResourceBrowser/CResourceDelegate.cpp
# UI Files
FORMS += \

View File

@ -73,5 +73,9 @@
<file>icons/World_16px.png</file>
<file>icons/PoiSymbol_24px.png</file>
<file>icons/ArrowD_16px.png</file>
<file>icons/Tree_16px.png</file>
<file>icons/Tree_24px.png</file>
<file>icons/Gear_16px.png</file>
<file>icons/Gear_24px.png</file>
</qresource>
</RCC>

View File

@ -1,6 +1,7 @@
#include "CResourceBrowser.h"
#include "ui_CResourceBrowser.h"
#include "CProgressDialog.h"
#include "CResourceDelegate.h"
#include "Editor/CEditorApplication.h"
#include <Core/GameProject/AssetNameGeneration.h>
#include <Core/GameProject/CAssetNameMap.h>
@ -11,22 +12,25 @@
#include <QtConcurrent/QtConcurrentRun>
CResourceBrowser::CResourceBrowser(QWidget *pParent)
: QDialog(pParent)
: QWidget(pParent)
, mpUI(new Ui::CResourceBrowser)
, mpSelectedEntry(nullptr)
, mpStore(nullptr)
, mpSelectedDir(nullptr)
, mAssetListMode(true)
, mEditorStore(false)
, mAssetListMode(false)
, mSearching(false)
{
mpUI->setupUi(this);
setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint);
#if PUBLIC_RELEASE
// Hide store select combo box in public release build; we don't want users to edit the editor store
mpUI->StoreLabel->setHidden(true);
mpUI->StoreComboBox->setHidden(true);
#endif
// Hide sorting combo box for now. The size isn't displayed on the UI so this isn't really useful for the end user.
mpUI->SortComboBox->hide();
// Configure display mode buttons
QButtonGroup *pModeGroup = new QButtonGroup(this);
pModeGroup->addButton(mpUI->ResourceTreeButton);
pModeGroup->addButton(mpUI->ResourceListButton);
pModeGroup->setExclusive(true);
// Set up table models
mpModel = new CResourceTableModel(this);
@ -36,8 +40,9 @@ CResourceBrowser::CResourceBrowser(QWidget *pParent)
QHeaderView *pHeader = mpUI->ResourceTableView->horizontalHeader();
pHeader->setSectionResizeMode(0, QHeaderView::Stretch);
pHeader->resizeSection(1, 215);
pHeader->resizeSection(2, 75);
mpDelegate = new CResourceBrowserDelegate(this);
mpUI->ResourceTableView->setItemDelegate(mpDelegate);
// Set up directory tree model
mpDirectoryModel = new CVirtualDirectoryModel(this);
@ -70,35 +75,49 @@ CResourceBrowser::CResourceBrowser(QWidget *pParent)
CreateFilterCheckboxes();
// Set up Import Names menu
QMenu *pImportNamesMenu = new QMenu(this);
mpUI->ImportNamesButton->setMenu(pImportNamesMenu);
// Set up the options menu
QMenu *pOptionsMenu = new QMenu(this);
QMenu *pImportMenu = pOptionsMenu->addMenu("Import Names");
pOptionsMenu->addAction("Export Names", this, SLOT(ExportAssetNames()));
pOptionsMenu->addSeparator();
QAction *pImportFromContentsTxtAction = new QAction("Import from Pak Contents List", this);
pImportNamesMenu->addAction(pImportFromContentsTxtAction);
pImportMenu->addAction("Asset Name Map", this, SLOT(ImportAssetNameMap()));
pImportMenu->addAction("Package Contents List", this, SLOT(ImportPackageContentsList()));
pImportMenu->addAction("Generate Asset Names", this, SLOT(GenerateAssetNames()));
QAction *pImportFromAssetNameMapAction = new QAction("Import from Asset Name Map", this);
pImportNamesMenu->addAction(pImportFromAssetNameMapAction);
QAction *pDisplayAssetIDsAction = new QAction("Display Asset IDs", this);
pDisplayAssetIDsAction->setCheckable(true);
connect(pDisplayAssetIDsAction, SIGNAL(toggled(bool)), this, SLOT(SetAssetIdDisplayEnabled(bool)));
pOptionsMenu->addAction(pDisplayAssetIDsAction);
QAction *pGenerateAssetNamesAction = new QAction("Generate Asset Names", this);
pImportNamesMenu->addAction(pGenerateAssetNamesAction);
#if PUBLIC_RELEASE
pGenerateAssetNamesAction->setVisible(false);
pOptionsMenu->addAction("Rebuild Database", this, SLOT(RebuildResourceDB()));
mpUI->OptionsToolButton->setMenu(pOptionsMenu);
#if !PUBLIC_RELEASE
// Only add the store menu in debug builds. We don't want end users editing the editor store.
pOptionsMenu->addSeparator();
QMenu *pStoreMenu = pOptionsMenu->addMenu("Set Store");
QAction *pProjStoreAction = pStoreMenu->addAction("Project Store", this, SLOT(SetProjectStore()));
QAction *pEdStoreAction = pStoreMenu->addAction("Editor Store", this, SLOT(SetEditorStore()));
pProjStoreAction->setCheckable(true);
pProjStoreAction->setChecked(true);
pEdStoreAction->setCheckable(true);
QActionGroup *pGroup = new QActionGroup(this);
pGroup->addAction(pProjStoreAction);
pGroup->addAction(pEdStoreAction);
#endif
// Set up connections
connect(mpUI->StoreComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateStore()));
connect(mpUI->SearchBar, SIGNAL(textChanged(QString)), this, SLOT(OnSearchStringChanged()));
connect(mpUI->DisplayTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnDisplayModeChanged(int)));
connect(mpUI->ResourceTreeButton, SIGNAL(pressed()), this, SLOT(SetResourceTreeView()));
connect(mpUI->ResourceListButton, SIGNAL(pressed()), this, SLOT(SetResourceListView()));
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(OnDoubleClickTable(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(pGenerateAssetNamesAction, SIGNAL(triggered()), this, SLOT(OnGenerateAssetNames()));
connect(mpUI->ExportNamesButton, SIGNAL(clicked()), this, SLOT(ExportAssetNames()));
connect(mpUI->RebuildDatabaseButton, SIGNAL(clicked(bool)), this, SLOT(RebuildResourceDB()));
connect(mpProxyModel, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)), mpUI->ResourceTableView, SLOT(resizeRowsToContents()));
connect(&mUpdateFilterTimer, SIGNAL(timeout()), this, SLOT(UpdateFilter()));
connect(mpFilterAllBox, SIGNAL(toggled(bool)), this, SLOT(OnFilterTypeBoxTicked(bool)));
connect(gpEdApp, SIGNAL(ActiveProjectChanged(CGameProject*)), this, SLOT(UpdateStore()));
@ -113,23 +132,21 @@ void CResourceBrowser::SelectResource(CResourceEntry *pEntry)
{
ASSERT(pEntry);
// Clear search
mpUI->SearchBar->clear();
UpdateFilter();
// Select target directory
SelectDirectory(pEntry->Directory());
// Select resource
int Row = mpModel->GetIndexForEntry(pEntry).row();
mpUI->ResourceTableView->selectionModel()->clearSelection();
for (int iCol = 0; iCol < mpModel->columnCount(QModelIndex()); iCol++)
// Clear search
if (!mpUI->SearchBar->text().isEmpty())
{
QModelIndex Index = mpModel->index(Row, iCol, QModelIndex());
QModelIndex ProxyIndex = mpProxyModel->mapFromSource(Index);
mpUI->ResourceTableView->selectionModel()->setCurrentIndex(ProxyIndex, QItemSelectionModel::Select);
mpUI->SearchBar->clear();
UpdateFilter();
}
// Select resource
QModelIndex SourceIndex = mpModel->GetIndexForEntry(pEntry);
QModelIndex ProxyIndex = mpProxyModel->mapFromSource(SourceIndex);
mpUI->ResourceTableView->selectionModel()->select(ProxyIndex, QItemSelectionModel::ClearAndSelect);
mpUI->ResourceTableView->scrollTo(ProxyIndex, QAbstractItemView::PositionAtCenter);
}
void CResourceBrowser::SelectDirectory(CVirtualDirectory *pDir)
@ -185,13 +202,7 @@ void CResourceBrowser::CreateFilterCheckboxes()
void CResourceBrowser::RefreshResources()
{
// Fill resource table
mpModel->FillEntryList(mpSelectedDir, InAssetListMode());
// Mark directories to span all three columns
mpUI->ResourceTableView->clearSpans();
for (u32 iDir = 0; iDir < mpModel->NumDirectories(); iDir++)
mpUI->ResourceTableView->setSpan(iDir, 0, 1, 3);
mpModel->FillEntryList(mpSelectedDir, mAssetListMode);
}
void CResourceBrowser::RefreshDirectories()
@ -232,37 +243,16 @@ void CResourceBrowser::UpdateDescriptionLabel()
mpUI->TableDescriptionLabel->setText(Desc);
}
void CResourceBrowser::UpdateStore()
void CResourceBrowser::SetResourceTreeView()
{
int StoreIndex = mpUI->StoreComboBox->currentIndex();
CGameProject *pProj = gpEdApp->ActiveProject();
CResourceStore *pProjStore = (pProj ? pProj->ResourceStore() : nullptr);
CResourceStore *pNewStore = (StoreIndex == 0 ? pProjStore : gpEditorStore);
if (mpStore != pNewStore)
{
mpStore = pNewStore;
// Refresh type filter list
CreateFilterCheckboxes();
// Refresh directory tree
mpDirectoryModel->SetRoot(mpStore ? mpStore->RootDirectory() : nullptr);
QModelIndex RootIndex = mpDirectoryModel->index(0, 0, QModelIndex());
mpUI->DirectoryTreeView->expand(RootIndex);
mpUI->DirectoryTreeView->clearSelection();
OnDirectorySelectionChanged(QModelIndex(), QModelIndex());
}
mAssetListMode = false;
RefreshResources();
}
void CResourceBrowser::OnDisplayModeChanged(int Index)
void CResourceBrowser::SetResourceListView()
{
bool OldIsAssetList = InAssetListMode();
mAssetListMode = Index == 0;
if (InAssetListMode() != OldIsAssetList)
RefreshResources();
mAssetListMode = true;
RefreshResources();
}
void CResourceBrowser::OnSortModeChanged(int Index)
@ -314,9 +304,49 @@ void CResourceBrowser::OnResourceSelectionChanged(const QModelIndex& rkNewIndex,
emit SelectedResourceChanged(mpSelectedEntry);
}
void CResourceBrowser::OnImportPakContentsTxt()
void CResourceBrowser::SetAssetIdDisplayEnabled(bool Enable)
{
QStringList PathList = UICommon::OpenFilesDialog(this, "Open pak contents list", "*.pak.contents.txt");
mpDelegate->SetDisplayAssetIDs(Enable);
mpUI->ResourceTableView->repaint();
}
void CResourceBrowser::UpdateStore()
{
CGameProject *pProj = gpEdApp->ActiveProject();
CResourceStore *pProjStore = (pProj ? pProj->ResourceStore() : nullptr);
CResourceStore *pNewStore = (mEditorStore ? gpEditorStore : pProjStore);
if (mpStore != pNewStore)
{
mpStore = pNewStore;
// Refresh type filter list
CreateFilterCheckboxes();
// Refresh directory tree
mpDirectoryModel->SetRoot(mpStore ? mpStore->RootDirectory() : nullptr);
QModelIndex RootIndex = mpDirectoryModel->index(0, 0, QModelIndex());
mpUI->DirectoryTreeView->expand(RootIndex);
mpUI->DirectoryTreeView->clearSelection();
OnDirectorySelectionChanged(QModelIndex(), QModelIndex());
}
}
void CResourceBrowser::SetProjectStore()
{
mEditorStore = false;
UpdateStore();
}
void CResourceBrowser::SetEditorStore()
{
mEditorStore = true;
UpdateStore();
}
void CResourceBrowser::ImportPackageContentsList()
{
QStringList PathList = UICommon::OpenFilesDialog(this, "Open package contents list", "*.pak.contents.txt");
if (PathList.isEmpty()) return;
SelectDirectory(nullptr);
@ -327,7 +357,7 @@ void CResourceBrowser::OnImportPakContentsTxt()
RefreshDirectories();
}
void CResourceBrowser::OnGenerateAssetNames()
void CResourceBrowser::GenerateAssetNames()
{
SelectDirectory(nullptr);
@ -338,7 +368,7 @@ void CResourceBrowser::OnGenerateAssetNames()
// Temporarily set root to null to ensure the window doesn't access the resource store while we're running.
mpDirectoryModel->SetRoot(mpStore->RootDirectory());
QFuture<void> Future = QtConcurrent::run(&GenerateAssetNames, mpStore->Project());
QFuture<void> Future = QtConcurrent::run(&::GenerateAssetNames, mpStore->Project());
Dialog.WaitForResults(Future);
RefreshResources();
@ -347,7 +377,7 @@ void CResourceBrowser::OnGenerateAssetNames()
UICommon::InfoMsg(this, "Complete", "Asset name generation complete!");
}
void CResourceBrowser::OnImportNamesFromAssetNameMap()
void CResourceBrowser::ImportAssetNameMap()
{
CAssetNameMap Map( mpStore->Game() );
bool LoadSuccess = Map.LoadAssetNames();
@ -410,7 +440,7 @@ void CResourceBrowser::ExportAssetNames()
void CResourceBrowser::RebuildResourceDB()
{
if (UICommon::YesNoQuestion(this, "Rebuild resource database", "Are you sure you want to rebuild the resource database?"))
if (UICommon::YesNoQuestion(this, "Rebuild resource database", "Are you sure you want to rebuild the resource database? This will take a while."))
{
gpEdApp->RebuildResourceDatabase();
}
@ -418,15 +448,9 @@ void CResourceBrowser::RebuildResourceDB()
void CResourceBrowser::UpdateFilter()
{
bool OldIsAssetList = InAssetListMode();
QString SearchText = mpUI->SearchBar->text();
mSearching = !SearchText.isEmpty();
if (InAssetListMode() != OldIsAssetList)
{
RefreshResources();
}
UpdateDescriptionLabel();
mpProxyModel->SetSearchString( TO_TSTRING(mpUI->SearchBar->text()) );
mpProxyModel->invalidate();

View File

@ -1,11 +1,11 @@
#ifndef CRESOURCEBROWSER_H
#define CRESOURCEBROWSER_H
#include "CResourceDelegate.h"
#include "CResourceProxyModel.h"
#include "CResourceTableModel.h"
#include "CVirtualDirectoryModel.h"
#include <QCheckBox>
#include <QDialog>
#include <QTimer>
#include <QVBoxLayout>
@ -13,7 +13,7 @@ namespace Ui {
class CResourceBrowser;
}
class CResourceBrowser : public QDialog
class CResourceBrowser : public QWidget
{
Q_OBJECT
Ui::CResourceBrowser *mpUI;
@ -21,9 +21,11 @@ class CResourceBrowser : public QDialog
CResourceStore *mpStore;
CResourceTableModel *mpModel;
CResourceProxyModel *mpProxyModel;
CResourceBrowserDelegate *mpDelegate;
CVirtualDirectory *mpSelectedDir;
CVirtualDirectoryModel *mpDirectoryModel;
QTimer mUpdateFilterTimer;
bool mEditorStore;
bool mAssetListMode;
bool mSearching;
@ -56,16 +58,21 @@ public slots:
void RefreshResources();
void RefreshDirectories();
void UpdateDescriptionLabel();
void UpdateStore();
void OnDisplayModeChanged(int Index);
void SetResourceTreeView();
void SetResourceListView();
void OnSortModeChanged(int Index);
void OnSearchStringChanged();
void OnDirectorySelectionChanged(const QModelIndex& rkNewIndex, const QModelIndex& rkPrevIndex);
void OnDoubleClickTable(QModelIndex Index);
void OnResourceSelectionChanged(const QModelIndex& rkNewIndex, const QModelIndex& rkPrevIndex);
void OnImportPakContentsTxt();
void OnGenerateAssetNames();
void OnImportNamesFromAssetNameMap();
void SetAssetIdDisplayEnabled(bool Enable);
void UpdateStore();
void SetProjectStore();
void SetEditorStore();
void ImportPackageContentsList();
void GenerateAssetNames();
void ImportAssetNameMap();
void ExportAssetNames();
void RebuildResourceDB();
void UpdateFilter();

View File

@ -1,293 +1,308 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CResourceBrowser</class>
<widget class="QDialog" name="CResourceBrowser">
<widget class="QWidget" name="CResourceBrowser">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>789</width>
<height>577</height>
<width>435</width>
<height>639</height>
</rect>
</property>
<property name="windowTitle">
<string>Resource Browser</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0,1">
<property name="spacing">
<number>2</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="QWidget" name="SidebarContainerWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QToolButton" name="OptionsToolButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../Icons.qrc">
<normaloff>:/icons/Gear_16px.png</normaloff>:/icons/Gear_16px.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="arrowType">
<enum>Qt::NoArrow</enum>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="SearchBar">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>5</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="placeholderText">
<string>Search</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ResourceTreeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../Icons.qrc">
<normaloff>:/icons/Tree_24px.png</normaloff>:/icons/Tree_24px.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ResourceListButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../Icons.qrc">
<normaloff>:/icons/Instances.png</normaloff>:/icons/Instances.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="SortComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>5</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Sort by Name</string>
</property>
</item>
<item>
<property name="text">
<string>Sort by Size</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="TableDescriptionLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="StoreLabel">
<property name="text">
<string>Store:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="StoreComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Project</string>
</property>
</item>
<item>
<property name="text">
<string>Editor</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLineEdit" name="SearchBar">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>5</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="placeholderText">
<string>Search</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="DisplayTypeComboBox">
<item>
<property name="text">
<string>Asset List</string>
</property>
</item>
<item>
<property name="text">
<string>Filesystem</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QComboBox" name="SortComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>5</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Sort by Name</string>
</property>
</item>
<item>
<property name="text">
<string>Sort by Size</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QScrollArea" name="FilterCheckboxScrollArea">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>189</width>
<height>117</height>
</rect>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QTreeView" name="DirectoryTreeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>2</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="indentation">
<number>12</number>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<widget class="QPushButton" name="ImportNamesButton">
<property name="text">
<string>Import Names</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ExportNamesButton">
<property name="text">
<string>Export Names</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="RebuildDatabaseButton">
<property name="text">
<string>Rebuild Database</string>
</property>
</widget>
</item>
</layout>
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="TableContainerWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>3</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
<widget class="QWidget" name="">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QScrollArea" name="FilterCheckboxScrollArea">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>200</height>
</size>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>209</width>
<height>190</height>
</rect>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QTreeView" name="DirectoryTreeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>2</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="indentation">
<number>12</number>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<widget class="QTableView" name="ResourceTableView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="leftMargin">
<number>0</number>
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="topMargin">
<number>0</number>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="rightMargin">
<number>0</number>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="bottomMargin">
<number>0</number>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<item>
<widget class="QLabel" name="TableDescriptionLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QTableView" name="ResourceTableView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>3</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</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="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>21</number>
</attribute>
<attribute name="verticalHeaderMinimumSectionSize">
<number>21</number>
</attribute>
</widget>
</item>
</layout>
<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="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<resources>
<include location="../Icons.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,130 @@
#include "CResourceDelegate.h"
#include "CResourceProxyModel.h"
#include "CResourceTableModel.h"
#include <Common/Common.h>
#include <QPainter>
struct SResDelegateInfo
{
QFont NameFont;
QFont InfoFont;
QFontMetrics NameFontMetrics;
QFontMetrics InfoFontMetrics;
QPen NamePen;
QPen InfoPen;
int Margin;
int Spacing;
SResDelegateInfo()
: NameFontMetrics(NameFont), InfoFontMetrics(InfoFont) {}
};
SResDelegateInfo GetDelegateInfo(const QStyleOptionViewItem& rkOption)
{
SResDelegateInfo Info;
Info.NameFont = rkOption.font;
Info.NameFont.setPointSize( rkOption.font.pointSize() + 1 );
Info.NameFontMetrics = QFontMetrics(Info.NameFont);
Info.InfoFont = rkOption.font;
Info.InfoFont.setPointSize( rkOption.font.pointSize() - 1 );
Info.InfoFontMetrics = QFontMetrics(Info.InfoFont);
Info.NamePen = QPen(rkOption.palette.text(), 1.f);
Info.InfoPen = QPen(rkOption.palette.text(), 1.f);
Info.InfoPen.setColor( Info.InfoPen.color().darker(140) );
Info.Margin = 3;
Info.Spacing = 3;
return Info;
}
QSize CResourceBrowserDelegate::sizeHint(const QStyleOptionViewItem& rkOption, const QModelIndex&) const
{
// Get string info
SResDelegateInfo Info = GetDelegateInfo(rkOption);
// Calculate height
int Height = (Info.Margin * 2) + Info.NameFontMetrics.height() + Info.Spacing + Info.InfoFontMetrics.height();
return QSize(0, Height);
}
void CResourceBrowserDelegate::paint(QPainter *pPainter, const QStyleOptionViewItem& rkOption, const QModelIndex& rkIndex) const
{
const CResourceProxyModel *pkProxy = qobject_cast<const CResourceProxyModel*>(rkIndex.model());
ASSERT(pkProxy != nullptr);
const CResourceTableModel *pkModel = qobject_cast<const CResourceTableModel*>(pkProxy->sourceModel());
ASSERT(pkModel != nullptr);
// Get resource entry
QModelIndex SourceIndex = pkProxy->mapToSource(rkIndex);
CResourceEntry *pEntry = pkModel->IndexEntry(SourceIndex);
// Initialize
SResDelegateInfo Info = GetDelegateInfo(rkOption);
QRect InnerRect = rkOption.rect.adjusted(Info.Margin, Info.Margin, -Info.Margin, -Info.Margin);
QPoint PainterPos = InnerRect.topLeft();
// Draw icon
QVariant IconVariant = rkIndex.model()->data(rkIndex, Qt::DecorationRole);
if (IconVariant != QVariant::Invalid)
{
QIcon Icon = IconVariant.value<QIcon>();
// Determine icon size. Ideally 24x24 if we have space, but downscale if we don't
int IdealIconSize = 24;
int IconSize = Math::Min(InnerRect.height(), IdealIconSize);
// Adjust icon position so it's centered in the ideal rect
QPoint IconPos = PainterPos;
IconPos.rx() += (IdealIconSize - IconSize) / 2;
IconPos.ry() += (InnerRect.height() - IconSize) / 2;
// Paint the icon
QRect IconRect(IconPos, QSize(IconSize, IconSize));
Icon.paint(pPainter, IconRect);
PainterPos.rx() += IdealIconSize + Info.Spacing + Info.Spacing;
}
// Calculate rects
if (!pEntry)
PainterPos.ry() += (InnerRect.height() - Info.NameFontMetrics.height()) / 2;
int ResNameWidth = InnerRect.width() - (PainterPos.x() - InnerRect.left());
QSize ResNameSize(ResNameWidth, Info.NameFontMetrics.height());
QRect ResNameRect = QRect(PainterPos, ResNameSize);
PainterPos.ry() += ResNameRect.height() + Info.Spacing;
int ResInfoWidth = ResNameWidth;
QSize ResInfoSize(ResInfoWidth, Info.InfoFontMetrics.height());
QRect ResInfoRect = QRect(PainterPos, ResInfoSize);
// Draw resource name
QString ResName = pkModel->data(SourceIndex, Qt::DisplayRole).toString();
QString ElidedName = Info.NameFontMetrics.elidedText(ResName, Qt::ElideRight, ResNameWidth);
pPainter->setFont(Info.NameFont);
pPainter->setPen(Info.NamePen);
pPainter->drawText(ResNameRect, ElidedName);
// Draw resource info string
if (pEntry)
{
QString ResInfo = TO_QSTRING( pEntry->TypeInfo()->TypeName() );
if (mDisplayAssetIDs)
ResInfo.prepend( TO_QSTRING(pEntry->ID().ToString()) + " | " );
QString ElidedResInfo = Info.InfoFontMetrics.elidedText(ResInfo, Qt::ElideRight, ResInfoWidth);
pPainter->setFont(Info.InfoFont);
pPainter->setPen(Info.InfoPen);
pPainter->drawText(ResInfoRect, ElidedResInfo);
}
}

View File

@ -0,0 +1,22 @@
#ifndef CRESOURCEBROWSERDELEGATE_H
#define CRESOURCEBROWSERDELEGATE_H
#include <QStyledItemDelegate>
class CResourceBrowserDelegate : public QStyledItemDelegate
{
bool mDisplayAssetIDs;
public:
CResourceBrowserDelegate(QObject *pParent = 0)
: QStyledItemDelegate(pParent)
, mDisplayAssetIDs(false)
{}
QSize sizeHint(const QStyleOptionViewItem& rkOption, const QModelIndex& rkIndex) const;
void paint(QPainter *pPainter, const QStyleOptionViewItem& rkOption, const QModelIndex& rkIndex) const;
inline void SetDisplayAssetIDs(bool Display) { mDisplayAssetIDs = Display; }
};
#endif // CRESOURCEBROWSERDELEGATE_H

View File

@ -15,6 +15,7 @@ class CResourceTableModel : public QAbstractTableModel
QList<CVirtualDirectory*> mDirectories;
QList<CResourceEntry*> mEntries;
QMap<CResourceEntry*, int> mEntryIndexMap;
bool mHasParent;
public:
@ -29,19 +30,17 @@ public:
int columnCount(const QModelIndex& /*rkParent*/) const
{
return 3;
return 1;
}
QVariant data(const QModelIndex& rkIndex, int Role) const
{
u32 Col = rkIndex.column();
if (rkIndex.column() != 0)
return QVariant::Invalid;
// Directory
if (IsIndexDirectory(rkIndex))
{
if (Col != 0)
return QVariant::Invalid;
CVirtualDirectory *pDir = IndexDirectory(rkIndex);
if (Role == Qt::DisplayRole || Role == Qt::ToolTipRole)
@ -58,46 +57,23 @@ public:
CResourceEntry *pEntry = IndexEntry(rkIndex);
if (Role == Qt::DisplayRole)
{
if (Col == 0)
{
return TO_QSTRING(pEntry->Name());
}
if (Col == 1)
{
return TO_QSTRING(pEntry->TypeInfo()->TypeName());
}
if (Col == 2)
{
u64 Size = pEntry->Size();
return Size ? TO_QSTRING( TString::FileSizeString(pEntry->Size()) ) : "";
}
}
return TO_QSTRING(pEntry->Name());
else if (Role == Qt::ToolTipRole)
return TO_QSTRING(pEntry->CookedAssetPath(true));
else if (Role == Qt::TextAlignmentRole && rkIndex.column() == 2)
return Qt::AlignRight;
else if (Role == Qt::DecorationRole)
return QIcon(":/icons/Sphere Preview.png");
return QVariant::Invalid;
}
QModelIndex GetIndexForEntry(CResourceEntry *pEntry) const
{
for (int iRes = 0; iRes < mEntries.size(); iRes++)
{
if (mEntries[iRes] == pEntry)
{
QModelIndex Out = index(mDirectories.size() + iRes, 0);
ASSERT(IndexEntry(Out) == pEntry);
return Out;
}
}
return QModelIndex();
if (mEntryIndexMap.contains(pEntry))
return index(mEntryIndexMap[pEntry] + mDirectories.size(), 0, QModelIndex());
else
return QModelIndex();
}
CResourceEntry* IndexEntry(const QModelIndex& rkIndex) const
@ -122,6 +98,7 @@ public:
mEntries.clear();
mDirectories.clear();
mEntryIndexMap.clear();
mHasParent = false;
if (pDir)
@ -143,7 +120,10 @@ public:
CResourceEntry *pEntry = pDir->ResourceByIndex(iRes);
if (pEntry->TypeInfo()->IsVisibleInBrowser() && !pEntry->IsHidden())
{
mEntryIndexMap[pEntry] = mEntries.size();
mEntries << pEntry;
}
}
}
@ -163,7 +143,10 @@ protected:
CResourceEntry *pEntry = pDir->ResourceByIndex(iRes);
if (pEntry->TypeInfo()->IsVisibleInBrowser() && !pEntry->IsHidden())
mEntries << pDir->ResourceByIndex(iRes);
{
mEntryIndexMap[pEntry] = mEntries.size();
mEntries << pEntry;
}
}
for (u32 iDir = 0; iDir < pDir->NumSubdirectories(); iDir++)

View File

@ -6,7 +6,7 @@
#include <QDebug>
CSelectResourcePanel::CSelectResourcePanel(CResourceSelector *pSelector)
: QWidget(pSelector)
: QFrame(pSelector)
, mpUI(new Ui::CSelectResourcePanel)
, mpSelector(pSelector)
, mModel(pSelector)

View File

@ -9,7 +9,7 @@ namespace Ui {
class CSelectResourcePanel;
}
class CSelectResourcePanel : public QWidget
class CSelectResourcePanel : public QFrame
{
Q_OBJECT
Ui::CSelectResourcePanel *mpUI;

View File

@ -110,26 +110,6 @@ CWorldEditor::CWorldEditor(QWidget *parent)
mpCollisionDialog = new CCollisionRenderSettingsDialog(this, this);
// Resource Browser button
QPushButton *pBrowserButton = new QPushButton(this);
pBrowserButton->setText("Resource Browser");
connect(pBrowserButton, SIGNAL(pressed()), this, SLOT(OpenResourceBrowser()));
QPalette Palette = pBrowserButton->palette();
QBrush ButtonBrush = Palette.button();
ButtonBrush.setColor( UICommon::kImportantButtonColor );
Palette.setBrush(QPalette::Button, ButtonBrush);
pBrowserButton->setPalette(Palette);
QFont BrowserButtonFont = pBrowserButton->font();
BrowserButtonFont.setPointSize( BrowserButtonFont.pointSize() + 3 );
pBrowserButton->setFont(BrowserButtonFont);
QWidget *pSpacerWidget = new QWidget(this);
pSpacerWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
ui->MainToolBar->addWidget(pSpacerWidget);
ui->MainToolBar->addWidget(pBrowserButton);
// "Open Recent" menu
mpOpenRecentMenu = new QMenu(this);
ui->ActionOpenRecent->setMenu(mpOpenRecentMenu);
@ -183,7 +163,6 @@ CWorldEditor::CWorldEditor(QWidget *parent)
connect(ui->ActionLink, SIGNAL(toggled(bool)), this, SLOT(OnLinkButtonToggled(bool)));
connect(ui->ActionUnlink, SIGNAL(triggered()), this, SLOT(OnUnlinkClicked()));
connect(ui->ActionResourceBrowser, SIGNAL(triggered()), this, SLOT(OpenResourceBrowser()));
connect(ui->ActionEditLayers, SIGNAL(triggered()), this, SLOT(EditLayers()));
connect(ui->ActionDrawWorld, SIGNAL(triggered()), this, SLOT(ToggleDrawWorld()));
@ -353,6 +332,11 @@ bool CWorldEditor::HasAnyScriptNodesSelected() const
return false;
}
CResourceBrowser* CWorldEditor::ResourceBrowser() const
{
return ui->ResourceBrowser;
}
CSceneViewport* CWorldEditor::Viewport() const
{
return ui->MainViewport;
@ -543,13 +527,6 @@ void CWorldEditor::OpenProjectSettings()
pDialog->raise();
}
void CWorldEditor::OpenResourceBrowser()
{
CResourceBrowser *pBrowser = gpEdApp->ResourceBrowser();
pBrowser->show();
pBrowser->raise();
}
void CWorldEditor::OnActiveProjectChanged(CGameProject *pProj)
{
ui->ActionProjectSettings->setEnabled( pProj != nullptr );

View File

@ -89,6 +89,7 @@ public:
inline CGameArea* ActiveArea() const { return mpArea; }
inline EGame CurrentGame() const { return gpEdApp->CurrentGame(); }
inline CLinkDialog* LinkDialog() const { return mpLinkDialog; }
CResourceBrowser* ResourceBrowser() const;
CSceneViewport* Viewport() const;
inline void SetWorldDir(QString WorldDir) { mWorldDir = (QDir(WorldDir).exists() ? WorldDir : ""); }
@ -116,7 +117,6 @@ public slots:
void ChangeEditMode(EWorldEditorMode Mode);
void SetRenderingMergedWorld(bool RenderMerged);
void OpenProjectSettings();
void OpenResourceBrowser();
void OnActiveProjectChanged(CGameProject *pProj);
void OnLinksModified(const QList<CScriptObject*>& rkInstances);

View File

@ -14,27 +14,25 @@
<string/>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>3</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>3</number>
<number>0</number>
</property>
<property name="topMargin">
<number>3</number>
<number>0</number>
</property>
<property name="rightMargin">
<number>3</number>
<number>0</number>
</property>
<property name="bottomMargin">
<number>3</number>
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="CResourceBrowser" name="ResourceBrowser" native="true"/>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
@ -340,7 +338,6 @@
<property name="title">
<string>Tools</string>
</property>
<addaction name="ActionResourceBrowser"/>
<addaction name="ActionEditLayers"/>
</widget>
<addaction name="menuFile"/>
@ -735,11 +732,6 @@
<string>Close Project</string>
</property>
</action>
<action name="ActionResourceBrowser">
<property name="text">
<string>Resource Browser</string>
</property>
</action>
<action name="ActionEditWorldInfoMode">
<property name="checkable">
<bool>true</bool>
@ -794,6 +786,12 @@
<header>Editor/CSceneViewport.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CResourceBrowser</class>
<extends>QWidget</extends>
<header>Editor/ResourceBrowser/CResourceBrowser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../Icons.qrc"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B