Files
o3de/Code/Editor/Controls/ReflectedPropertyControl/PropertyResourceCtrl.cpp
T
amzn-phist d6b268e84e Remove ResourceSelectorHost and clean up/refactor related bits (#3050)
* Sever dependency on legacy resource selector host

Audio resource selectors (browse dialogs) no longer need to be
registered with the legacy IResourceSelectorHost system.  Set up a new
EBus specifically to handle browse button presses and directly invokes
the dialog.

Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com>

* Hook up legacy audio control selector to new EBus

Remaining use of legacy audio selectors (trackview) need to be able to
bypass ResourceSelectorHost now.

Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com>

* Removes ResourceSelectorHost and legacy selectors

This removes various Variable types that were tied to resource
selectors, such as GeomCache, Model, Animation, File.  Removes the
ResourceSelectorHost completely.  The two things that still appeared to
have selectors in TrackView are Audio Controls and Texture.  Fixed the
audio control selector to work via EBus and the Texture selector didn't
seem to work at all, but left it in as it was.

Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com>

* Make the default audio selector return old value

Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com>

* Fix some signed/unsigned comparison warnings

Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com>

* Remove deleted function from Editor Mock

Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com>

* Change audio selector api to use string_view

Per feedback.

Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com>
2021-08-16 12:41:24 -05:00

392 lines
11 KiB
C++

/*
* 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 "EditorDefs.h"
#include "PropertyResourceCtrl.h"
// Qt
#include <QHBoxLayout>
#include <QLineEdit>
// AzToolsFramework
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/UI/PropertyEditor/PropertyAudioCtrl.h>
// Editor
#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. Old property control
if (path != m_path)
{
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
{
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:
newPath.replace("\\\\", "/");
if (newPath.size() > MAX_PATH)
{
newPath.resize(MAX_PATH);
}
}
SetPathAndEmit(newPath);
}
}
};
class AudioControlSelectorButton
: public BrowseButton
{
public:
AZ_CLASS_ALLOCATOR(AudioControlSelectorButton, AZ::SystemAllocator, 0);
AudioControlSelectorButton(PropertyType type, QWidget* pParent = nullptr)
: BrowseButton(type, pParent)
{
setToolTip(tr("Select Audio Control"));
}
private:
void OnClicked() override
{
AZStd::string resourceResult;
auto ConvertLegacyAudioPropertyType = [](const PropertyType type) -> AzToolsFramework::AudioPropertyType
{
switch (type)
{
case ePropertyAudioTrigger:
return AzToolsFramework::AudioPropertyType::Trigger;
case ePropertyAudioRTPC:
return AzToolsFramework::AudioPropertyType::Rtpc;
case ePropertyAudioSwitch:
return AzToolsFramework::AudioPropertyType::Switch;
case ePropertyAudioSwitchState:
return AzToolsFramework::AudioPropertyType::SwitchState;
case ePropertyAudioEnvironment:
return AzToolsFramework::AudioPropertyType::Environment;
case ePropertyAudioPreloadRequest:
return AzToolsFramework::AudioPropertyType::Preload;
default:
return AzToolsFramework::AudioPropertyType::NumTypes;
}
};
auto propType = ConvertLegacyAudioPropertyType(m_propertyType);
if (propType != AzToolsFramework::AudioPropertyType::NumTypes)
{
AzToolsFramework::AudioControlSelectorRequestBus::EventResult(
resourceResult, propType, &AzToolsFramework::AudioControlSelectorRequestBus::Events::SelectResource,
AZStd::string_view{ m_path.toUtf8().constData() });
SetPathAndEmit(QString{ resourceResult.c_str() });
}
}
};
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 ePropertyAudioTrigger:
case ePropertyAudioSwitch:
case ePropertyAudioSwitchState:
case ePropertyAudioRTPC:
case ePropertyAudioEnvironment:
case ePropertyAudioPreloadRequest:
AddButton(new AudioControlSelectorButton(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>