d6b268e84e
* 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>
392 lines
11 KiB
C++
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>
|