Merge pull request #7104 from aws-lumberyard-dev/Atom/guthadam/atom_tools_change_preset_browser_to_generic_asset_grid_dialog
Atom Tools: Changed ME preset browser dialog into generic asset grid dialog in ATF
This commit is contained in:
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#endif
|
||||
|
||||
#include <QDialog>
|
||||
#include <QString>
|
||||
|
||||
class QListWidgetItem;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class AssetGridDialog;
|
||||
}
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
//! Widget for managing and selecting from a library of assets
|
||||
class AssetGridDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
struct SelectableAsset
|
||||
{
|
||||
AZ::Data::AssetId m_assetId;
|
||||
QString m_title;
|
||||
};
|
||||
|
||||
using SelectableAssetVector = AZStd::vector<SelectableAsset>;
|
||||
|
||||
AssetGridDialog(
|
||||
const QString& title,
|
||||
const SelectableAssetVector& selectableAssets,
|
||||
const AZ::Data::AssetId& selectedAsset,
|
||||
const QSize& tileSize,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
~AssetGridDialog();
|
||||
|
||||
Q_SIGNALS:
|
||||
void AssetSelected(const AZ::Data::AssetId& assetId);
|
||||
|
||||
private:
|
||||
AZ_DISABLE_COPY_MOVE(AssetGridDialog);
|
||||
|
||||
QListWidgetItem* CreateListItem(const SelectableAsset& selectableAsset);
|
||||
void SetupAssetList();
|
||||
void SetupSearchWidget();
|
||||
void SetupDialogButtons();
|
||||
void ApplySearchFilter();
|
||||
void ShowSearchMenu(const QPoint& pos);
|
||||
void SelectCurrentAsset();
|
||||
void SelectInitialAsset();
|
||||
|
||||
QSize m_tileSize;
|
||||
AZ::Data::AssetId m_initialSelectedAsset;
|
||||
QScopedPointer<Ui::AssetGridDialog> m_ui;
|
||||
};
|
||||
} // namespace AtomToolsFramework
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AssetGridDialog/ui_AssetGridDialog.h>
|
||||
#include <AtomToolsFramework/AssetGridDialog/AssetGridDialog.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <AzQtComponents/Components/Widgets/ElidingLabel.h>
|
||||
#include <AzQtComponents/Components/Widgets/LineEdit.h>
|
||||
#include <AzQtComponents/Components/Widgets/Text.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailWidget.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
AssetGridDialog::AssetGridDialog(
|
||||
const QString& title,
|
||||
const SelectableAssetVector& selectableAssets,
|
||||
const AZ::Data::AssetId& selectedAsset,
|
||||
const QSize& tileSize,
|
||||
QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_tileSize(tileSize)
|
||||
, m_initialSelectedAsset(selectedAsset)
|
||||
, m_ui(new Ui::AssetGridDialog)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
QSignalBlocker signalBlocker(this);
|
||||
|
||||
setWindowTitle(title);
|
||||
|
||||
SetupAssetList();
|
||||
SetupSearchWidget();
|
||||
SetupDialogButtons();
|
||||
setModal(true);
|
||||
|
||||
QListWidgetItem* selectedItem = nullptr;
|
||||
for (const auto& selectableAsset : selectableAssets)
|
||||
{
|
||||
QListWidgetItem* item = CreateListItem(selectableAsset);
|
||||
if (!selectedItem || m_initialSelectedAsset == selectableAsset.m_assetId)
|
||||
{
|
||||
selectedItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
m_ui->m_assetList->sortItems();
|
||||
|
||||
if (selectedItem)
|
||||
{
|
||||
m_ui->m_assetList->setCurrentItem(selectedItem);
|
||||
m_ui->m_assetList->scrollToItem(selectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
AssetGridDialog::~AssetGridDialog()
|
||||
{
|
||||
}
|
||||
|
||||
QListWidgetItem* AssetGridDialog::CreateListItem(const SelectableAsset& selectableAsset)
|
||||
{
|
||||
const int itemBorder = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/AtomToolsFramework/AssetGridDialog/ItemBorder", 4));
|
||||
const int itemSpacing = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/AtomToolsFramework/AssetGridDialog/ItemSpacing", 10));
|
||||
const int headerHeight = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/AtomToolsFramework/AssetGridDialog/HeaderHeight", 15));
|
||||
|
||||
const QSize gridSize = m_ui->m_assetList->gridSize();
|
||||
m_ui->m_assetList->setGridSize(QSize(
|
||||
AZStd::max(gridSize.width(), m_tileSize.width() + itemSpacing),
|
||||
AZStd::max(gridSize.height(), m_tileSize.height() + itemSpacing + headerHeight)));
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem(m_ui->m_assetList);
|
||||
item->setData(Qt::DisplayRole, selectableAsset.m_title);
|
||||
item->setData(Qt::UserRole, QString(selectableAsset.m_assetId.ToString<AZStd::string>().c_str()));
|
||||
item->setSizeHint(m_tileSize + QSize(itemBorder, itemBorder + headerHeight));
|
||||
m_ui->m_assetList->addItem(item);
|
||||
|
||||
QWidget* itemWidget = new QWidget(m_ui->m_assetList);
|
||||
itemWidget->setLayout(new QVBoxLayout(itemWidget));
|
||||
itemWidget->layout()->setSpacing(0);
|
||||
itemWidget->layout()->setMargin(0);
|
||||
|
||||
AzQtComponents::ElidingLabel* header = new AzQtComponents::ElidingLabel(itemWidget);
|
||||
header->setText(selectableAsset.m_title);
|
||||
header->setFixedSize(QSize(m_tileSize.width(), headerHeight));
|
||||
header->setMargin(0);
|
||||
header->setStyleSheet("background-color: rgb(35, 35, 35)");
|
||||
AzQtComponents::Text::addPrimaryStyle(header);
|
||||
AzQtComponents::Text::addLabelStyle(header);
|
||||
itemWidget->layout()->addWidget(header);
|
||||
|
||||
AzToolsFramework::Thumbnailer::ThumbnailWidget* thumbnail = new AzToolsFramework::Thumbnailer::ThumbnailWidget(itemWidget);
|
||||
thumbnail->setFixedSize(m_tileSize);
|
||||
thumbnail->SetThumbnailKey(
|
||||
MAKE_TKEY(AzToolsFramework::AssetBrowser::ProductThumbnailKey, selectableAsset.m_assetId),
|
||||
AzToolsFramework::Thumbnailer::ThumbnailContext::DefaultContext);
|
||||
thumbnail->updateGeometry();
|
||||
itemWidget->layout()->addWidget(thumbnail);
|
||||
|
||||
m_ui->m_assetList->setItemWidget(item, itemWidget);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void AssetGridDialog::SetupAssetList()
|
||||
{
|
||||
m_ui->m_assetList->setFlow(QListView::LeftToRight);
|
||||
m_ui->m_assetList->setResizeMode(QListView::Adjust);
|
||||
m_ui->m_assetList->setGridSize(QSize(0, 0));
|
||||
m_ui->m_assetList->setWrapping(true);
|
||||
|
||||
QObject::connect(m_ui->m_assetList, &QListWidget::currentItemChanged, [this](){ SelectCurrentAsset(); });
|
||||
}
|
||||
|
||||
void AssetGridDialog::SetupSearchWidget()
|
||||
{
|
||||
m_ui->m_searchWidget->setReadOnly(false);
|
||||
m_ui->m_searchWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
AzQtComponents::LineEdit::applySearchStyle(m_ui->m_searchWidget);
|
||||
connect(m_ui->m_searchWidget, &QLineEdit::textChanged, this, [this](){ ApplySearchFilter(); });
|
||||
connect(m_ui->m_searchWidget, &QWidget::customContextMenuRequested, this, [this](const QPoint& pos){ ShowSearchMenu(pos); });
|
||||
}
|
||||
|
||||
void AssetGridDialog::SetupDialogButtons()
|
||||
{
|
||||
connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(m_ui->m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
connect(this, &QDialog::rejected, this, [this](){ SelectInitialAsset(); });
|
||||
}
|
||||
|
||||
void AssetGridDialog::ApplySearchFilter()
|
||||
{
|
||||
for (int index = 0; index < m_ui->m_assetList->count(); ++index)
|
||||
{
|
||||
QListWidgetItem* item = m_ui->m_assetList->item(index);
|
||||
const QString& title = item->data(Qt::DisplayRole).toString();
|
||||
const QString filter = m_ui->m_searchWidget->text();
|
||||
item->setHidden(!filter.isEmpty() && !title.contains(filter, Qt::CaseInsensitive));
|
||||
}
|
||||
}
|
||||
|
||||
void AssetGridDialog::ShowSearchMenu(const QPoint& pos)
|
||||
{
|
||||
QScopedPointer<QMenu> menu(m_ui->m_searchWidget->createStandardContextMenu());
|
||||
menu->setStyleSheet("background-color: #333333");
|
||||
menu->exec(m_ui->m_searchWidget->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void AssetGridDialog::SelectCurrentAsset()
|
||||
{
|
||||
auto item = m_ui->m_assetList->currentItem();
|
||||
if (item)
|
||||
{
|
||||
AZ::Data::AssetId assetId = AZ::Data::AssetId::CreateString(item->data(Qt::UserRole).toString().toUtf8().constData());
|
||||
emit AssetSelected(assetId);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetGridDialog::SelectInitialAsset()
|
||||
{
|
||||
emit AssetSelected(m_initialSelectedAsset);
|
||||
}
|
||||
} // namespace AtomToolsFramework
|
||||
|
||||
#include <AtomToolsFramework/AssetGridDialog/moc_AssetGridDialog.cpp>
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PresetBrowserDialog</class>
|
||||
<widget class="QWidget" name="PresetBrowserDialog">
|
||||
<class>AssetGridDialog</class>
|
||||
<widget class="QWidget" name="AssetGridDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
@@ -26,7 +26,7 @@
|
||||
<widget class="QLineEdit" name="m_searchWidget"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="m_presetList"/>
|
||||
<widget class="QListWidget" name="m_assetList"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@@ -9,6 +9,7 @@
|
||||
set(FILES
|
||||
Include/AtomToolsFramework/Application/AtomToolsApplication.h
|
||||
Include/AtomToolsFramework/AssetBrowser/AtomToolsAssetBrowser.h
|
||||
Include/AtomToolsFramework/AssetGridDialog/AssetGridDialog.h
|
||||
Include/AtomToolsFramework/Communication/LocalServer.h
|
||||
Include/AtomToolsFramework/Communication/LocalSocket.h
|
||||
Include/AtomToolsFramework/Debug/TraceRecorder.h
|
||||
@@ -41,6 +42,8 @@ set(FILES
|
||||
Source/AssetBrowser/AtomToolsAssetBrowser.cpp
|
||||
Source/AssetBrowser/AtomToolsAssetBrowser.qrc
|
||||
Source/AssetBrowser/AtomToolsAssetBrowser.ui
|
||||
Source/AssetGridDialog/AssetGridDialog.cpp
|
||||
Source/AssetGridDialog/AssetGridDialog.ui
|
||||
Source/Communication/LocalServer.cpp
|
||||
Source/Communication/LocalSocket.cpp
|
||||
Source/Debug/TraceRecorder.cpp
|
||||
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/Feature/Utils/LightingPreset.h>
|
||||
#include <Atom/RPI.Edit/Common/AssetUtils.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <Viewport/MaterialViewportRequestBus.h>
|
||||
#include <Window/PresetBrowserDialogs/LightingPresetBrowserDialog.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
LightingPresetBrowserDialog::LightingPresetBrowserDialog(QWidget* parent)
|
||||
: PresetBrowserDialog(parent)
|
||||
{
|
||||
QSignalBlocker signalBlocker(this);
|
||||
|
||||
setWindowTitle("Lighting Preset Browser");
|
||||
|
||||
MaterialViewportRequestBus::BroadcastResult(m_initialPreset, &MaterialViewportRequestBus::Events::GetLightingPresetSelection);
|
||||
|
||||
AZ::Render::LightingPresetPtrVector presets;
|
||||
MaterialViewportRequestBus::BroadcastResult(presets, &MaterialViewportRequestBus::Events::GetLightingPresets);
|
||||
AZStd::sort(presets.begin(), presets.end(), [](const auto& a, const auto& b) { return a->m_displayName < b->m_displayName; });
|
||||
|
||||
const int itemSize = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/MaterialEditor/PresetBrowserDialog/LightingItemSize", 180));
|
||||
|
||||
QListWidgetItem* selectedItem = nullptr;
|
||||
for (const auto& preset : presets)
|
||||
{
|
||||
AZStd::string path;
|
||||
MaterialViewportRequestBus::BroadcastResult(path, &MaterialViewportRequestBus::Events::GetLightingPresetLastSavePath, preset);
|
||||
QListWidgetItem* item = CreateListItem(
|
||||
preset->m_displayName.c_str(), AZ::RPI::AssetUtils::MakeAssetId(path, 0).GetValue(), QSize(itemSize, itemSize));
|
||||
|
||||
m_listItemToPresetMap[item] = preset;
|
||||
|
||||
if (m_initialPreset == preset)
|
||||
{
|
||||
selectedItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedItem)
|
||||
{
|
||||
m_ui->m_presetList->setCurrentItem(selectedItem);
|
||||
m_ui->m_presetList->scrollToItem(selectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
void LightingPresetBrowserDialog::SelectCurrentPreset()
|
||||
{
|
||||
auto presetItr = m_listItemToPresetMap.find(m_ui->m_presetList->currentItem());
|
||||
if (presetItr != m_listItemToPresetMap.end())
|
||||
{
|
||||
MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SelectLightingPreset, presetItr->second);
|
||||
}
|
||||
}
|
||||
|
||||
void LightingPresetBrowserDialog::SelectInitialPreset()
|
||||
{
|
||||
MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SelectLightingPreset, m_initialPreset);
|
||||
}
|
||||
|
||||
} // namespace MaterialEditor
|
||||
|
||||
#include <Window/PresetBrowserDialogs/moc_LightingPresetBrowserDialog.cpp>
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <Atom/Feature/Utils/LightingPreset.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <Viewport/MaterialViewportNotificationBus.h>
|
||||
#endif
|
||||
|
||||
#include <Window/PresetBrowserDialogs/PresetBrowserDialog.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
//! Widget for managing and selecting from a library of preset assets
|
||||
class LightingPresetBrowserDialog : public PresetBrowserDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LightingPresetBrowserDialog(QWidget* parent = nullptr);
|
||||
~LightingPresetBrowserDialog() = default;
|
||||
|
||||
private:
|
||||
void SelectCurrentPreset() override;
|
||||
void SelectInitialPreset() override;
|
||||
|
||||
AZ::Render::LightingPresetPtr m_initialPreset;
|
||||
AZStd::unordered_map<QListWidgetItem*, AZ::Render::LightingPresetPtr> m_listItemToPresetMap;
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/Feature/Utils/ModelPreset.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <Viewport/MaterialViewportRequestBus.h>
|
||||
#include <Window/PresetBrowserDialogs/ModelPresetBrowserDialog.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
ModelPresetBrowserDialog::ModelPresetBrowserDialog(QWidget* parent)
|
||||
: PresetBrowserDialog(parent)
|
||||
{
|
||||
QSignalBlocker signalBlocker(this);
|
||||
|
||||
setWindowTitle("Model Preset Browser");
|
||||
|
||||
MaterialViewportRequestBus::BroadcastResult(m_initialPreset, &MaterialViewportRequestBus::Events::GetModelPresetSelection);
|
||||
|
||||
AZ::Render::ModelPresetPtrVector presets;
|
||||
MaterialViewportRequestBus::BroadcastResult(presets, &MaterialViewportRequestBus::Events::GetModelPresets);
|
||||
AZStd::sort(presets.begin(), presets.end(), [](const auto& a, const auto& b) { return a->m_displayName < b->m_displayName; });
|
||||
|
||||
const int itemSize = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/MaterialEditor/PresetBrowserDialog/ModelItemSize", 90));
|
||||
|
||||
QListWidgetItem* selectedItem = nullptr;
|
||||
for (const auto& preset : presets)
|
||||
{
|
||||
QListWidgetItem* item = CreateListItem(preset->m_displayName.c_str(), preset->m_modelAsset.GetId(), QSize(itemSize, itemSize));
|
||||
|
||||
m_listItemToPresetMap[item] = preset;
|
||||
|
||||
if (m_initialPreset == preset)
|
||||
{
|
||||
selectedItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedItem)
|
||||
{
|
||||
m_ui->m_presetList->setCurrentItem(selectedItem);
|
||||
m_ui->m_presetList->scrollToItem(selectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelPresetBrowserDialog::SelectCurrentPreset()
|
||||
{
|
||||
auto presetItr = m_listItemToPresetMap.find(m_ui->m_presetList->currentItem());
|
||||
if (presetItr != m_listItemToPresetMap.end())
|
||||
{
|
||||
MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SelectModelPreset, presetItr->second);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelPresetBrowserDialog::SelectInitialPreset()
|
||||
{
|
||||
MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SelectModelPreset, m_initialPreset);
|
||||
}
|
||||
|
||||
} // namespace MaterialEditor
|
||||
|
||||
#include <Window/PresetBrowserDialogs/moc_ModelPresetBrowserDialog.cpp>
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <Atom/Feature/Utils/ModelPreset.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <Viewport/MaterialViewportNotificationBus.h>
|
||||
#endif
|
||||
|
||||
#include <Window/PresetBrowserDialogs/PresetBrowserDialog.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
//! Widget for managing and selecting from a library of preset assets
|
||||
class ModelPresetBrowserDialog : public PresetBrowserDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ModelPresetBrowserDialog(QWidget* parent = nullptr);
|
||||
~ModelPresetBrowserDialog() = default;
|
||||
|
||||
private:
|
||||
void SelectCurrentPreset() override;
|
||||
void SelectInitialPreset() override;
|
||||
|
||||
AZ::Render::ModelPresetPtr m_initialPreset;
|
||||
AZStd::unordered_map<QListWidgetItem*, AZ::Render::ModelPresetPtr> m_listItemToPresetMap;
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <AzQtComponents/Components/StyleManager.h>
|
||||
#include <AzQtComponents/Components/Widgets/ElidingLabel.h>
|
||||
#include <AzQtComponents/Components/Widgets/LineEdit.h>
|
||||
#include <AzQtComponents/Components/Widgets/Text.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailWidget.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
#include <Window/PresetBrowserDialogs/PresetBrowserDialog.h>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
PresetBrowserDialog::PresetBrowserDialog(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_ui(new Ui::PresetBrowserDialog)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
QSignalBlocker signalBlocker(this);
|
||||
|
||||
SetupPresetList();
|
||||
SetupSearchWidget();
|
||||
SetupDialogButtons();
|
||||
setModal(true);
|
||||
}
|
||||
|
||||
void PresetBrowserDialog::SetupPresetList()
|
||||
{
|
||||
m_ui->m_presetList->setFlow(QListView::LeftToRight);
|
||||
m_ui->m_presetList->setResizeMode(QListView::Adjust);
|
||||
m_ui->m_presetList->setGridSize(QSize(0, 0));
|
||||
m_ui->m_presetList->setWrapping(true);
|
||||
|
||||
QObject::connect(m_ui->m_presetList, &QListWidget::currentItemChanged, [this](){ SelectCurrentPreset(); });
|
||||
}
|
||||
|
||||
QListWidgetItem* PresetBrowserDialog::CreateListItem(const QString& title, const AZ::Data::AssetId& assetId, const QSize& size)
|
||||
{
|
||||
const int itemBorder = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/MaterialEditor/PresetBrowserDialog/ItemBorder", 4));
|
||||
const int itemSpacing = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/MaterialEditor/PresetBrowserDialog/ItemSpacing", 10));
|
||||
const int headerHeight = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/MaterialEditor/PresetBrowserDialog/HeaderHeight", 15));
|
||||
|
||||
const QSize gridSize = m_ui->m_presetList->gridSize();
|
||||
m_ui->m_presetList->setGridSize(QSize(
|
||||
AZStd::max(gridSize.width(), size.width() + itemSpacing),
|
||||
AZStd::max(gridSize.height(), size.height() + itemSpacing + headerHeight)));
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem(m_ui->m_presetList);
|
||||
item->setData(Qt::UserRole, title);
|
||||
item->setSizeHint(size + QSize(itemBorder, itemBorder + headerHeight));
|
||||
m_ui->m_presetList->addItem(item);
|
||||
|
||||
QWidget* itemWidget = new QWidget(m_ui->m_presetList);
|
||||
itemWidget->setLayout(new QVBoxLayout(itemWidget));
|
||||
itemWidget->layout()->setSpacing(0);
|
||||
itemWidget->layout()->setMargin(0);
|
||||
|
||||
AzQtComponents::ElidingLabel* header = new AzQtComponents::ElidingLabel(itemWidget);
|
||||
header->setText(title);
|
||||
header->setFixedSize(QSize(size.width(), headerHeight));
|
||||
header->setMargin(0);
|
||||
header->setStyleSheet("background-color: rgb(35, 35, 35)");
|
||||
AzQtComponents::Text::addPrimaryStyle(header);
|
||||
AzQtComponents::Text::addLabelStyle(header);
|
||||
itemWidget->layout()->addWidget(header);
|
||||
|
||||
AzToolsFramework::Thumbnailer::ThumbnailWidget* thumbnail = new AzToolsFramework::Thumbnailer::ThumbnailWidget(itemWidget);
|
||||
thumbnail->setFixedSize(size);
|
||||
thumbnail->SetThumbnailKey(
|
||||
MAKE_TKEY(AzToolsFramework::AssetBrowser::ProductThumbnailKey, assetId),
|
||||
AzToolsFramework::Thumbnailer::ThumbnailContext::DefaultContext);
|
||||
thumbnail->updateGeometry();
|
||||
itemWidget->layout()->addWidget(thumbnail);
|
||||
|
||||
m_ui->m_presetList->setItemWidget(item, itemWidget);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void PresetBrowserDialog::SetupSearchWidget()
|
||||
{
|
||||
m_ui->m_searchWidget->setReadOnly(false);
|
||||
m_ui->m_searchWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
AzQtComponents::LineEdit::applySearchStyle(m_ui->m_searchWidget);
|
||||
connect(m_ui->m_searchWidget, &QLineEdit::textChanged, this, [this](){ ApplySearchFilter(); });
|
||||
connect(m_ui->m_searchWidget, &QWidget::customContextMenuRequested, this, [this](const QPoint& pos){ ShowSearchMenu(pos); });
|
||||
}
|
||||
|
||||
void PresetBrowserDialog::SetupDialogButtons()
|
||||
{
|
||||
connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(m_ui->m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
connect(this, &QDialog::rejected, this, [this](){ SelectInitialPreset(); });
|
||||
}
|
||||
|
||||
void PresetBrowserDialog::ApplySearchFilter()
|
||||
{
|
||||
for (int index = 0; index < m_ui->m_presetList->count(); ++index)
|
||||
{
|
||||
QListWidgetItem* item = m_ui->m_presetList->item(index);
|
||||
const QString& title = item->data(Qt::UserRole).toString();
|
||||
const QString filter = m_ui->m_searchWidget->text();
|
||||
item->setHidden(!filter.isEmpty() && !title.contains(filter, Qt::CaseInsensitive));
|
||||
}
|
||||
}
|
||||
|
||||
void PresetBrowserDialog::ShowSearchMenu(const QPoint& pos)
|
||||
{
|
||||
QScopedPointer<QMenu> menu(m_ui->m_searchWidget->createStandardContextMenu());
|
||||
menu->setStyleSheet("background-color: #333333");
|
||||
menu->exec(m_ui->m_searchWidget->mapToGlobal(pos));
|
||||
}
|
||||
} // namespace MaterialEditor
|
||||
|
||||
#include <Window/PresetBrowserDialogs/moc_PresetBrowserDialog.cpp>
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <QDialog>
|
||||
#endif
|
||||
|
||||
#include <Window/PresetBrowserDialogs/ui_PresetBrowserDialog.h>
|
||||
|
||||
class QImage;
|
||||
class QListWidgetItem;
|
||||
class QString;
|
||||
|
||||
namespace MaterialEditor
|
||||
{
|
||||
//! Widget for managing and selecting from a library of preset assets
|
||||
class PresetBrowserDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PresetBrowserDialog(QWidget* parent = nullptr);
|
||||
~PresetBrowserDialog() = default;
|
||||
|
||||
protected:
|
||||
void SetupPresetList();
|
||||
QListWidgetItem* CreateListItem(const QString& title, const AZ::Data::AssetId& assetId, const QSize& size);
|
||||
|
||||
void SetupSearchWidget();
|
||||
void SetupDialogButtons();
|
||||
void ApplySearchFilter();
|
||||
void ShowSearchMenu(const QPoint& pos);
|
||||
virtual void SelectCurrentPreset() = 0;
|
||||
virtual void SelectInitialPreset() = 0;
|
||||
|
||||
QScopedPointer<Ui::PresetBrowserDialog> m_ui;
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
+111
-35
@@ -6,13 +6,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/RPI.Reflect/Model/ModelAsset.h>
|
||||
#include <Atom/Feature/Utils/LightingPreset.h>
|
||||
#include <Atom/Feature/Utils/ModelPreset.h>
|
||||
#include <Atom/RPI.Edit/Common/AssetUtils.h>
|
||||
#include <AtomToolsFramework/AssetGridDialog/AssetGridDialog.h>
|
||||
#include <AtomToolsFramework/Inspector/InspectorPropertyGroupWidget.h>
|
||||
#include <AtomToolsFramework/Util/Util.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
#include <Viewport/MaterialViewportRequestBus.h>
|
||||
#include <Window/PresetBrowserDialogs/LightingPresetBrowserDialog.h>
|
||||
#include <Window/PresetBrowserDialogs/ModelPresetBrowserDialog.h>
|
||||
#include <Window/ViewportSettingsInspector/ViewportSettingsInspector.h>
|
||||
|
||||
#include <QAction>
|
||||
@@ -110,17 +112,53 @@ namespace MaterialEditor
|
||||
|
||||
if (!savePath.empty())
|
||||
{
|
||||
AZ::Render::ModelPresetPtr preset;
|
||||
MaterialViewportRequestBus::BroadcastResult(
|
||||
preset, &MaterialViewportRequestBus::Events::AddModelPreset, AZ::Render::ModelPreset());
|
||||
MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SaveModelPreset, preset, savePath);
|
||||
MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SelectModelPreset, preset);
|
||||
MaterialViewportRequestBus::Broadcast(
|
||||
[&savePath](MaterialViewportRequestBus::Events* viewportRequests)
|
||||
{
|
||||
AZ::Render::ModelPresetPtr preset = viewportRequests->AddModelPreset(AZ::Render::ModelPreset());
|
||||
viewportRequests->SaveModelPreset(preset, savePath);
|
||||
viewportRequests->SelectModelPreset(preset);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportSettingsInspector::SelectModelPreset()
|
||||
{
|
||||
ModelPresetBrowserDialog dialog(QApplication::activeWindow());
|
||||
AZ::Data::AssetId selectedAsset;
|
||||
AtomToolsFramework::AssetGridDialog::SelectableAssetVector selectableAssets;
|
||||
AZStd::unordered_map<AZ::Data::AssetId, AZ::Render::ModelPresetPtr> assetIdToPresetMap;
|
||||
MaterialViewportRequestBus::Broadcast(
|
||||
[&](MaterialViewportRequestBus::Events* viewportRequests)
|
||||
{
|
||||
const auto& selectedPreset = viewportRequests->GetModelPresetSelection();
|
||||
selectedAsset = selectedPreset->m_modelAsset.GetId();
|
||||
|
||||
const auto& presets = viewportRequests->GetModelPresets();
|
||||
selectableAssets.reserve(presets.size());
|
||||
for (const auto& preset : presets)
|
||||
{
|
||||
const auto& presetAssetId = preset->m_modelAsset.GetId();
|
||||
selectableAssets.push_back({ presetAssetId, preset->m_displayName.c_str() });
|
||||
assetIdToPresetMap[presetAssetId] = preset;
|
||||
}
|
||||
});
|
||||
|
||||
const int itemSize = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/MaterialEditor/AssetGridDialog/ModelItemSize", 180));
|
||||
|
||||
AtomToolsFramework::AssetGridDialog dialog(
|
||||
"Model Preset Browser", selectableAssets, selectedAsset, QSize(itemSize, itemSize), QApplication::activeWindow());
|
||||
|
||||
connect(
|
||||
&dialog, &AtomToolsFramework::AssetGridDialog::AssetSelected, this,
|
||||
[assetIdToPresetMap](const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
const auto presetItr = assetIdToPresetMap.find(assetId);
|
||||
if (presetItr != assetIdToPresetMap.end())
|
||||
{
|
||||
MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SelectModelPreset, presetItr->second);
|
||||
}
|
||||
});
|
||||
|
||||
dialog.setFixedSize(800, 400);
|
||||
dialog.show();
|
||||
@@ -198,17 +236,55 @@ namespace MaterialEditor
|
||||
|
||||
if (!savePath.empty())
|
||||
{
|
||||
AZ::Render::LightingPresetPtr preset;
|
||||
MaterialViewportRequestBus::BroadcastResult(
|
||||
preset, &MaterialViewportRequestBus::Events::AddLightingPreset, AZ::Render::LightingPreset());
|
||||
MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SaveLightingPreset, preset, savePath);
|
||||
MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SelectLightingPreset, preset);
|
||||
MaterialViewportRequestBus::Broadcast(
|
||||
[&savePath](MaterialViewportRequestBus::Events* viewportRequests)
|
||||
{
|
||||
AZ::Render::LightingPresetPtr preset = viewportRequests->AddLightingPreset(AZ::Render::LightingPreset());
|
||||
viewportRequests->SaveLightingPreset(preset, savePath);
|
||||
viewportRequests->SelectLightingPreset(preset);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportSettingsInspector::SelectLightingPreset()
|
||||
{
|
||||
LightingPresetBrowserDialog dialog(QApplication::activeWindow());
|
||||
AZ::Data::AssetId selectedAsset;
|
||||
AtomToolsFramework::AssetGridDialog::SelectableAssetVector selectableAssets;
|
||||
AZStd::unordered_map<AZ::Data::AssetId, AZ::Render::LightingPresetPtr> assetIdToPresetMap;
|
||||
MaterialViewportRequestBus::Broadcast(
|
||||
[&](MaterialViewportRequestBus::Events* viewportRequests)
|
||||
{
|
||||
const auto& selectedPreset = viewportRequests->GetLightingPresetSelection();
|
||||
const auto& selectedPresetPath = viewportRequests->GetLightingPresetLastSavePath(selectedPreset);
|
||||
selectedAsset = AZ::RPI::AssetUtils::MakeAssetId(selectedPresetPath, 0).GetValue();
|
||||
|
||||
const auto& presets = viewportRequests->GetLightingPresets();
|
||||
selectableAssets.reserve(presets.size());
|
||||
for (const auto& preset : presets)
|
||||
{
|
||||
const auto& path = viewportRequests->GetLightingPresetLastSavePath(preset);
|
||||
const auto& presetAssetId = AZ::RPI::AssetUtils::MakeAssetId(path, 0).GetValue();
|
||||
selectableAssets.push_back({ presetAssetId, preset->m_displayName.c_str() });
|
||||
assetIdToPresetMap[presetAssetId] = preset;
|
||||
}
|
||||
});
|
||||
|
||||
const int itemSize = aznumeric_cast<int>(
|
||||
AtomToolsFramework::GetSettingOrDefault<AZ::u64>("/O3DE/Atom/MaterialEditor/AssetGridDialog/LightingItemSize", 180));
|
||||
|
||||
AtomToolsFramework::AssetGridDialog dialog(
|
||||
"Lighting Preset Browser", selectableAssets, selectedAsset, QSize(itemSize, itemSize), QApplication::activeWindow());
|
||||
|
||||
connect(
|
||||
&dialog, &AtomToolsFramework::AssetGridDialog::AssetSelected, this,
|
||||
[assetIdToPresetMap](const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
const auto presetItr = assetIdToPresetMap.find(assetId);
|
||||
if (presetItr != assetIdToPresetMap.end())
|
||||
{
|
||||
MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SelectLightingPreset, presetItr->second);
|
||||
}
|
||||
});
|
||||
|
||||
dialog.setFixedSize(800, 400);
|
||||
dialog.show();
|
||||
@@ -249,20 +325,18 @@ namespace MaterialEditor
|
||||
void ViewportSettingsInspector::Reset()
|
||||
{
|
||||
m_modelPreset.reset();
|
||||
MaterialViewportRequestBus::BroadcastResult(m_modelPreset, &MaterialViewportRequestBus::Events::GetModelPresetSelection);
|
||||
|
||||
m_lightingPreset.reset();
|
||||
MaterialViewportRequestBus::BroadcastResult(m_lightingPreset, &MaterialViewportRequestBus::Events::GetLightingPresetSelection);
|
||||
|
||||
MaterialViewportRequestBus::BroadcastResult(m_viewportSettings->m_enableGrid, &MaterialViewportRequestBus::Events::GetGridEnabled);
|
||||
MaterialViewportRequestBus::BroadcastResult(
|
||||
m_viewportSettings->m_enableShadowCatcher, &MaterialViewportRequestBus::Events::GetShadowCatcherEnabled);
|
||||
MaterialViewportRequestBus::BroadcastResult(
|
||||
m_viewportSettings->m_enableAlternateSkybox, &MaterialViewportRequestBus::Events::GetAlternateSkyboxEnabled);
|
||||
MaterialViewportRequestBus::BroadcastResult(
|
||||
m_viewportSettings->m_fieldOfView, &MaterialViewportRequestBus::Handler::GetFieldOfView);
|
||||
MaterialViewportRequestBus::BroadcastResult(
|
||||
m_viewportSettings->m_displayMapperOperationType, &MaterialViewportRequestBus::Handler::GetDisplayMapperOperationType);
|
||||
MaterialViewportRequestBus::Broadcast(
|
||||
[this](MaterialViewportRequestBus::Events* viewportRequests)
|
||||
{
|
||||
m_modelPreset = viewportRequests->GetModelPresetSelection();
|
||||
m_lightingPreset = viewportRequests->GetLightingPresetSelection();
|
||||
m_viewportSettings->m_enableGrid = viewportRequests->GetGridEnabled();
|
||||
m_viewportSettings->m_enableShadowCatcher = viewportRequests->GetShadowCatcherEnabled();
|
||||
m_viewportSettings->m_enableAlternateSkybox = viewportRequests->GetAlternateSkyboxEnabled();
|
||||
m_viewportSettings->m_fieldOfView = viewportRequests->GetFieldOfView();
|
||||
m_viewportSettings->m_displayMapperOperationType = viewportRequests->GetDisplayMapperOperationType();
|
||||
});
|
||||
|
||||
AtomToolsFramework::InspectorRequestBus::Handler::BusDisconnect();
|
||||
AtomToolsFramework::InspectorWidget::Reset();
|
||||
@@ -335,14 +409,16 @@ namespace MaterialEditor
|
||||
{
|
||||
MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnLightingPresetChanged, m_lightingPreset);
|
||||
MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnModelPresetChanged, m_modelPreset);
|
||||
MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Events::SetGridEnabled, m_viewportSettings->m_enableGrid);
|
||||
|
||||
MaterialViewportRequestBus::Broadcast(
|
||||
&MaterialViewportRequestBus::Events::SetShadowCatcherEnabled, m_viewportSettings->m_enableShadowCatcher);
|
||||
MaterialViewportRequestBus::Broadcast(
|
||||
&MaterialViewportRequestBus::Events::SetAlternateSkyboxEnabled, m_viewportSettings->m_enableAlternateSkybox);
|
||||
MaterialViewportRequestBus::Broadcast(&MaterialViewportRequestBus::Handler::SetFieldOfView, m_viewportSettings->m_fieldOfView);
|
||||
MaterialViewportRequestBus::Broadcast(
|
||||
&MaterialViewportRequestBus::Handler::SetDisplayMapperOperationType, m_viewportSettings->m_displayMapperOperationType);
|
||||
[this](MaterialViewportRequestBus::Events* viewportRequests)
|
||||
{
|
||||
viewportRequests->SetGridEnabled(m_viewportSettings->m_enableGrid);
|
||||
viewportRequests->SetShadowCatcherEnabled(m_viewportSettings->m_enableShadowCatcher);
|
||||
viewportRequests->SetAlternateSkyboxEnabled(m_viewportSettings->m_enableAlternateSkybox);
|
||||
viewportRequests->SetFieldOfView(m_viewportSettings->m_fieldOfView);
|
||||
viewportRequests->SetDisplayMapperOperationType(m_viewportSettings->m_displayMapperOperationType);
|
||||
});
|
||||
}
|
||||
|
||||
AZStd::string ViewportSettingsInspector::GetDefaultUniqueSaveFilePath(const AZStd::string& baseName) const
|
||||
|
||||
@@ -67,13 +67,6 @@ set(FILES
|
||||
Source/Window/CreateMaterialDialog/CreateMaterialDialog.cpp
|
||||
Source/Window/CreateMaterialDialog/CreateMaterialDialog.h
|
||||
Source/Window/CreateMaterialDialog/CreateMaterialDialog.ui
|
||||
Source/Window/PresetBrowserDialogs/PresetBrowserDialog.cpp
|
||||
Source/Window/PresetBrowserDialogs/PresetBrowserDialog.h
|
||||
Source/Window/PresetBrowserDialogs/PresetBrowserDialog.ui
|
||||
Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.cpp
|
||||
Source/Window/PresetBrowserDialogs/LightingPresetBrowserDialog.h
|
||||
Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.cpp
|
||||
Source/Window/PresetBrowserDialogs/ModelPresetBrowserDialog.h
|
||||
Source/Window/PerformanceMonitor/PerformanceMonitorWidget.cpp
|
||||
Source/Window/PerformanceMonitor/PerformanceMonitorWidget.h
|
||||
Source/Window/PerformanceMonitor/PerformanceMonitorWidget.ui
|
||||
|
||||
Reference in New Issue
Block a user