You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
398 lines
11 KiB
C++
398 lines
11 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates, or
|
|
* a third party where indicated.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
|
|
#include "EditorDefs.h"
|
|
|
|
#include "PropertyResourceCtrl.h"
|
|
|
|
// Qt
|
|
#include <QHBoxLayout>
|
|
#include <QLineEdit>
|
|
|
|
// AzToolsFramework
|
|
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
|
|
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
|
|
|
// Editor
|
|
#include "IResourceSelectorHost.h"
|
|
#include "Controls/QToolTipWidget.h"
|
|
#include "Controls/BitmapToolTip.h"
|
|
|
|
|
|
BrowseButton::BrowseButton(PropertyType type, QWidget* parent /*= nullptr*/)
|
|
: QToolButton(parent)
|
|
, m_propertyType(type)
|
|
{
|
|
setAutoRaise(true);
|
|
setIcon(QIcon(QStringLiteral(":/stylesheet/img/UI20/browse-edit.svg")));
|
|
connect(this, &QAbstractButton::clicked, this, &BrowseButton::OnClicked);
|
|
}
|
|
|
|
void BrowseButton::SetPathAndEmit(const QString& path)
|
|
{
|
|
//only emit if path changes, except for ePropertyGeomCache. Old property control
|
|
if (path != m_path || m_propertyType == ePropertyGeomCache)
|
|
{
|
|
m_path = path;
|
|
emit PathChanged(m_path);
|
|
}
|
|
}
|
|
|
|
class FileBrowseButton
|
|
: public BrowseButton
|
|
{
|
|
public:
|
|
AZ_CLASS_ALLOCATOR(FileBrowseButton, AZ::SystemAllocator, 0);
|
|
FileBrowseButton(PropertyType type, QWidget* pParent = nullptr)
|
|
: BrowseButton(type, pParent)
|
|
{
|
|
setToolTip("Browse...");
|
|
}
|
|
|
|
private:
|
|
void OnClicked() override
|
|
{
|
|
QString tempValue("");
|
|
QString ext("");
|
|
if (m_path.isEmpty() == false)
|
|
{
|
|
if (Path::GetExt(m_path) == "")
|
|
{
|
|
tempValue = "";
|
|
}
|
|
else
|
|
{
|
|
tempValue = m_path;
|
|
}
|
|
}
|
|
|
|
AssetSelectionModel selection;
|
|
|
|
if (m_propertyType == ePropertyTexture)
|
|
{
|
|
// Filters for texture.
|
|
selection = AssetSelectionModel::AssetGroupSelection("Texture");
|
|
}
|
|
else if (m_propertyType == ePropertyModel)
|
|
{
|
|
// Filters for models.
|
|
selection = AssetSelectionModel::AssetGroupSelection("Geometry");
|
|
}
|
|
else if (m_propertyType == ePropertyGeomCache)
|
|
{
|
|
// Filters for geom caches.
|
|
selection = AssetSelectionModel::AssetTypeSelection("Geom Cache");
|
|
}
|
|
else if (m_propertyType == ePropertyFile)
|
|
{
|
|
// Filters for files.
|
|
selection = AssetSelectionModel::AssetTypeSelection("File");
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
|
|
AzToolsFramework::EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::BrowseForAssets, selection);
|
|
if (selection.IsValid())
|
|
{
|
|
QString newPath = Path::FullPathToGamePath(selection.GetResult()->GetFullPath().c_str()).c_str();
|
|
|
|
switch (m_propertyType)
|
|
{
|
|
case ePropertyTexture:
|
|
case ePropertyModel:
|
|
newPath.replace("\\\\", "/");
|
|
}
|
|
switch (m_propertyType)
|
|
{
|
|
case ePropertyTexture:
|
|
case ePropertyModel:
|
|
case ePropertyFile:
|
|
if (newPath.size() > MAX_PATH)
|
|
{
|
|
newPath.resize(MAX_PATH);
|
|
}
|
|
}
|
|
|
|
SetPathAndEmit(newPath);
|
|
}
|
|
}
|
|
};
|
|
|
|
class ResourceSelectorButton
|
|
: public BrowseButton
|
|
{
|
|
public:
|
|
AZ_CLASS_ALLOCATOR(ResourceSelectorButton, AZ::SystemAllocator, 0);
|
|
|
|
ResourceSelectorButton(PropertyType type, QWidget* pParent = nullptr)
|
|
: BrowseButton(type, pParent)
|
|
{
|
|
setToolTip(tr("Select resource"));
|
|
}
|
|
|
|
private:
|
|
void OnClicked() override
|
|
{
|
|
SResourceSelectorContext x;
|
|
x.parentWidget = this;
|
|
x.typeName = Prop::GetPropertyTypeToResourceType(m_propertyType);
|
|
QString newPath = GetIEditor()->GetResourceSelectorHost()->SelectResource(x, m_path);
|
|
SetPathAndEmit(newPath);
|
|
}
|
|
};
|
|
|
|
class TextureEditButton
|
|
: public BrowseButton
|
|
{
|
|
public:
|
|
AZ_CLASS_ALLOCATOR(TextureEditButton, AZ::SystemAllocator, 0);
|
|
TextureEditButton(QWidget* pParent = nullptr)
|
|
: BrowseButton(ePropertyTexture, pParent)
|
|
{
|
|
setIcon(QIcon(QStringLiteral(":/stylesheet/img/UI20/open-in-internal-app.svg")));
|
|
setToolTip(tr("Launch default editor"));
|
|
}
|
|
|
|
private:
|
|
void OnClicked() override
|
|
{
|
|
CFileUtil::EditTextureFile(m_path.toUtf8().data(), true);
|
|
}
|
|
};
|
|
|
|
FileResourceSelectorWidget::FileResourceSelectorWidget(QWidget* pParent /*= nullptr*/)
|
|
: QWidget(pParent)
|
|
, m_propertyType(ePropertyInvalid)
|
|
, m_tooltip(nullptr)
|
|
{
|
|
m_pathEdit = new QLineEdit;
|
|
m_mainLayout = new QHBoxLayout(this);
|
|
m_mainLayout->addWidget(m_pathEdit, 1);
|
|
|
|
m_mainLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
// KDAB just ported the MFC texture preview tooltip, but looks like Amazon added their own. Not sure which to use.
|
|
// To switch to Amazon QToolTipWidget, remove FileResourceSelectorWidget::event and m_previewTooltip
|
|
#ifdef USE_QTOOLTIPWIDGET
|
|
m_tooltip = new QToolTipWidget(this);
|
|
|
|
installEventFilter(this);
|
|
#endif
|
|
connect(m_pathEdit, &QLineEdit::editingFinished, this, [this]() { OnPathChanged(m_pathEdit->text()); });
|
|
}
|
|
|
|
bool FileResourceSelectorWidget::eventFilter([[maybe_unused]] QObject* obj, QEvent* event)
|
|
{
|
|
if (m_propertyType == ePropertyTexture)
|
|
{
|
|
if (event->type() == QEvent::ToolTip)
|
|
{
|
|
QHelpEvent* e = (QHelpEvent*)event;
|
|
|
|
m_tooltip->AddSpecialContent("TEXTURE", m_path);
|
|
m_tooltip->TryDisplay(e->globalPos(), m_pathEdit, QToolTipWidget::ArrowDirection::ARROW_RIGHT);
|
|
|
|
return true;
|
|
}
|
|
|
|
if (event->type() == QEvent::Leave)
|
|
{
|
|
m_tooltip->hide();
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void FileResourceSelectorWidget::SetPropertyType(PropertyType type)
|
|
{
|
|
if (m_propertyType == type)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//if the property type changed for some reason, delete all the existing widgets
|
|
if (!m_buttons.isEmpty())
|
|
{
|
|
qDeleteAll(m_buttons.begin(), m_buttons.end());
|
|
m_buttons.clear();
|
|
}
|
|
|
|
m_previewToolTip.reset();
|
|
m_propertyType = type;
|
|
|
|
switch (type)
|
|
{
|
|
case ePropertyTexture:
|
|
AddButton(new FileBrowseButton(type));
|
|
AddButton(new TextureEditButton);
|
|
m_previewToolTip.reset(new CBitmapToolTip);
|
|
break;
|
|
case ePropertyModel:
|
|
case ePropertyGeomCache:
|
|
case ePropertyAudioTrigger:
|
|
case ePropertyAudioSwitch:
|
|
case ePropertyAudioSwitchState:
|
|
case ePropertyAudioRTPC:
|
|
case ePropertyAudioEnvironment:
|
|
case ePropertyAudioPreloadRequest:
|
|
AddButton(new ResourceSelectorButton(type));
|
|
break;
|
|
case ePropertyFile:
|
|
AddButton(new FileBrowseButton(type));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
m_mainLayout->invalidate();
|
|
}
|
|
|
|
void FileResourceSelectorWidget::AddButton(BrowseButton* button)
|
|
{
|
|
m_mainLayout->addWidget(button);
|
|
m_buttons.push_back(button);
|
|
connect(button, &BrowseButton::PathChanged, this, &FileResourceSelectorWidget::OnPathChanged);
|
|
}
|
|
|
|
void FileResourceSelectorWidget::OnPathChanged(const QString& path)
|
|
{
|
|
bool changed = SetPath(path);
|
|
if (changed)
|
|
{
|
|
emit PathChanged(m_path);
|
|
}
|
|
}
|
|
|
|
bool FileResourceSelectorWidget::SetPath(const QString& path)
|
|
{
|
|
bool changed = false;
|
|
|
|
const QString newPath = path.toLower();
|
|
if (m_path != newPath)
|
|
{
|
|
m_path = newPath;
|
|
UpdateWidgets();
|
|
|
|
changed = true;
|
|
}
|
|
|
|
return changed;
|
|
}
|
|
|
|
|
|
void FileResourceSelectorWidget::UpdateWidgets()
|
|
{
|
|
m_pathEdit->setText(m_path);
|
|
|
|
foreach(BrowseButton * button, m_buttons)
|
|
{
|
|
button->SetPath(m_path);
|
|
}
|
|
|
|
if (m_previewToolTip)
|
|
{
|
|
m_previewToolTip->SetTool(this, rect());
|
|
}
|
|
}
|
|
|
|
QString FileResourceSelectorWidget::GetPath() const
|
|
{
|
|
return m_path;
|
|
}
|
|
|
|
|
|
|
|
QWidget* FileResourceSelectorWidget::GetLastInTabOrder()
|
|
{
|
|
return m_buttons.empty() ? nullptr : m_buttons.last();
|
|
}
|
|
|
|
QWidget* FileResourceSelectorWidget::GetFirstInTabOrder()
|
|
{
|
|
return m_buttons.empty() ? nullptr : m_buttons.first();
|
|
}
|
|
|
|
void FileResourceSelectorWidget::UpdateTabOrder()
|
|
{
|
|
if (m_buttons.count() >= 2)
|
|
{
|
|
for (int i = 0; i < m_buttons.count() - 1; ++i)
|
|
{
|
|
setTabOrder(m_buttons[i], m_buttons[i + 1]);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool FileResourceSelectorWidget::event(QEvent* event)
|
|
{
|
|
if (event->type() == QEvent::ToolTip && m_previewToolTip && !m_previewToolTip->isVisible())
|
|
{
|
|
if (!m_path.isEmpty())
|
|
{
|
|
m_previewToolTip->LoadImage(m_path);
|
|
m_previewToolTip->setVisible(true);
|
|
}
|
|
event->accept();
|
|
return true;
|
|
}
|
|
|
|
if (event->type() == QEvent::Resize && m_previewToolTip)
|
|
{
|
|
m_previewToolTip->SetTool(this, rect());
|
|
}
|
|
|
|
return QWidget::event(event);
|
|
}
|
|
|
|
QWidget* FileResourceSelectorWidgetHandler::CreateGUI(QWidget* pParent)
|
|
{
|
|
FileResourceSelectorWidget* newCtrl = aznew FileResourceSelectorWidget(pParent);
|
|
connect(newCtrl, &FileResourceSelectorWidget::PathChanged, newCtrl, [newCtrl]()
|
|
{
|
|
EBUS_EVENT(AzToolsFramework::PropertyEditorGUIMessages::Bus, RequestWrite, newCtrl);
|
|
});
|
|
return newCtrl;
|
|
}
|
|
|
|
void FileResourceSelectorWidgetHandler::ConsumeAttribute(FileResourceSelectorWidget* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName)
|
|
{
|
|
Q_UNUSED(GUI);
|
|
Q_UNUSED(attrib);
|
|
Q_UNUSED(attrValue);
|
|
Q_UNUSED(debugName);
|
|
}
|
|
|
|
void FileResourceSelectorWidgetHandler::WriteGUIValuesIntoProperty(size_t index, FileResourceSelectorWidget* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node)
|
|
{
|
|
Q_UNUSED(index);
|
|
Q_UNUSED(node);
|
|
CReflectedVarResource val = instance;
|
|
val.m_propertyType = GUI->GetPropertyType();
|
|
val.m_path = GUI->GetPath().toUtf8().data();
|
|
instance = static_cast<property_t>(val);
|
|
}
|
|
|
|
bool FileResourceSelectorWidgetHandler::ReadValuesIntoGUI(size_t index, FileResourceSelectorWidget* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node)
|
|
{
|
|
Q_UNUSED(index);
|
|
Q_UNUSED(node);
|
|
CReflectedVarResource val = instance;
|
|
GUI->SetPropertyType(val.m_propertyType);
|
|
GUI->SetPath(val.m_path.c_str());
|
|
return false;
|
|
}
|
|
|
|
#include <Controls/ReflectedPropertyControl/moc_PropertyResourceCtrl.cpp>
|