Files
o3de/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerSearchWidget.cpp
T
Esteban Papp 1f9b284de2 Merge branch 'development' into cmake/SPEC-7179
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>

# Conflicts:
#	Code/Editor/Plugins/ComponentEntityEditorPlugin/ComponentEntityEditorPlugin_precompiled.h
#	Code/Editor/Plugins/EditorCommon/EditorCommon_precompiled.h
#	Code/Editor/Plugins/EditorCommon/stdafx.cpp
#	Code/Editor/Plugins/FFMPEGPlugin/FFMPEGPlugin_precompiled.h
#	Code/Editor/Plugins/PerforcePlugin/PerforcePlugin_precompiled.h
#	Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsTool_precompiled.h
#	Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFramework_precompiled.h
#	Code/Tools/AssetProcessor/native/precompiled.h
#	Code/Tools/Standalone/StandaloneTools_precompiled.h
#	Gems/AssetMemoryAnalyzer/Code/Source/AssetMemoryAnalyzer_precompiled.h
#	Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageProcessing_precompiled.h
#	Gems/Atom/RHI/DX12/Code/Source/RHI/Atom_RHI_DX12_precompiled.h
#	Gems/Atom/RHI/Metal/Code/Include/Platform/Mac/Atom_RHI_Metal_precompiled_Platform.h
#	Gems/Atom/RHI/Metal/Code/Include/Platform/iOS/Atom_RHI_Metal_precompiled_Platform.h
#	Gems/Atom/RHI/Metal/Code/Source/Atom_RHI_Metal_precompiled.h
#	Gems/Atom/RHI/Metal/Code/atom_rhi_metal_common_files.cmake
#	Gems/Atom/RHI/Null/Code/Source/Atom_RHI_Null_precompiled.h
#	Gems/Atom/RHI/Null/Code/atom_rhi_null_common_files.cmake
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Android/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Linux/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Mac/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Include/Platform/Windows/Atom_RHI_Vulkan_precompiled_Platform.h
#	Gems/Atom/RHI/Vulkan/Code/Source/Atom_RHI_Vulkan_precompiled.h
#	Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp
#	Gems/Atom/RHI/Vulkan/Code/atom_rhi_vulkan_common_files.cmake
#	Gems/AtomLyIntegration/AtomFont/Code/Include/AtomLyIntegration/AtomFont/AtomFont_precompiled.h
#	Gems/Blast/Code/Source/StdAfx.cpp
#	Gems/Camera/Code/Source/Camera_precompiled.h
#	Gems/EMotionFX/Code/Source/EMotionFX_precompiled.h
#	Gems/FastNoise/Code/Source/FastNoise_precompiled.h
#	Gems/Gestures/Code/Source/Gestures_precompiled.h
#	Gems/GradientSignal/Code/Source/GradientSignal_precompiled.h
#	Gems/GraphCanvas/Code/precompiled.h
#	Gems/ImGui/Code/Source/ImGui_precompiled.h
#	Gems/InAppPurchases/Code/Source/InAppPurchases_precompiled.h
#	Gems/LmbrCentral/Code/Source/LmbrCentral_precompiled.h
#	Gems/LmbrCentral/Code/Tests/ShapeGeometryUtilTest.cpp
#	Gems/LyShine/Code/Editor/UiCanvasEditor_precompiled.h
#	Gems/LyShine/Code/Source/Animation/LyShine_precompiled.h
#	Gems/LyShine/Code/Source/LyShine_precompiled.h
#	Gems/LyShineExamples/Code/Source/LyShineExamples_precompiled.h
#	Gems/Maestro/Code/Source/Cinematics/Maestro_precompiled.h
#	Gems/Maestro/Code/Source/Maestro_precompiled.h
#	Gems/MessagePopup/Code/Source/MessagePopup_precompiled.h
#	Gems/Metastream/Code/Source/Metastream_precompiled.h
#	Gems/Microphone/Code/Source/Microphone_precompiled.h
#	Gems/Multiplayer/Code/Source/Multiplayer_precompiled.h
#	Gems/PhysX/Code/NumericalMethods/Source/NumericalMethods_precompiled.h
#	Gems/PhysX/Code/Source/PhysXUnsupported_precompiled.h
#	Gems/PhysX/Code/Source/PhysX_precompiled.h
#	Gems/PhysX/Code/physx_unsupported_files.cmake
#	Gems/PhysXDebug/Code/Source/PhysXDebugUnsupported_precompiled.h
#	Gems/PhysXDebug/Code/Source/PhysXDebug_precompiled.h
#	Gems/ScriptCanvas/Code/Editor/precompiled.h
#	Gems/ScriptCanvas/Code/Source/precompiled.h
#	Gems/ScriptCanvasDeveloper/Code/Source/precompiled.h
#	Gems/ScriptCanvasPhysics/Code/Source/ScriptCanvasPhysics_precompiled.h
#	Gems/ScriptEvents/Code/Source/precompiled.h
#	Gems/ScriptEvents/Code/Tests/Editor/EditorTests.cpp
#	Gems/ScriptedEntityTweener/Code/Source/ScriptedEntityTweener_precompiled.h
#	Gems/SliceFavorites/Code/Source/SliceFavorites_precompiled.h
#	Gems/StartingPointCamera/Code/Source/StartingPointCamera_precompiled.h
#	Gems/StartingPointInput/Code/Source/StartingPointInput_precompiled.h
#	Gems/StartingPointMovement/Code/Source/StartingPointMovement_precompiled.h
#	Gems/SurfaceData/Code/Source/SurfaceData_precompiled.h
#	Gems/TextureAtlas/Code/Source/TextureAtlas_precompiled.h
#	Gems/TickBusOrderViewer/Code/Source/TickBusOrderViewer_precompiled.h
#	Gems/Twitch/Code/Source/Twitch_precompiled.h
#	Gems/VirtualGamepad/Code/Source/VirtualGamepad_precompiled.h
#	Gems/WhiteBox/Code/Source/WhiteBoxUnsupported_precompiled.h
#	Gems/WhiteBox/Code/Source/WhiteBox_precompiled.h
2021-07-16 15:42:37 -07:00

230 lines
9.0 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 "OutlinerSearchWidget.h"
#include <AzCore/Casting/numeric_cast.h>
#include <AzQtComponents/Components/FlowLayout.h>
#include <AzQtComponents/Components/StyleManager.h>
#include <QLabel>
#include <QTreeView>
#include <QTextDocument>
#include <QPainter>
#include <QToolButton>
#include <QApplication>
namespace AzQtComponents
{
OutlinerIcons::OutlinerIcons()
{
m_globalIcons[static_cast<int>(OutlinerSearchWidget::GlobalSearchCriteria::Unlocked)] = QIcon(QString(":Icons/unlocked.svg"));
m_globalIcons[static_cast<int>(OutlinerSearchWidget::GlobalSearchCriteria::Locked)] = QIcon(QString(":Icons/locked.svg"));
m_globalIcons[static_cast<int>(OutlinerSearchWidget::GlobalSearchCriteria::Visible)] = QIcon(QString(":Icons/visb.svg"));
m_globalIcons[static_cast<int>(OutlinerSearchWidget::GlobalSearchCriteria::Hidden)] = QIcon(QString(":Icons/visb_hidden.svg"));
m_globalIcons[static_cast<int>(OutlinerSearchWidget::GlobalSearchCriteria::Separator)] = QIcon();
}
OutlinerSearchTypeSelector::OutlinerSearchTypeSelector(QWidget* parent)
: SearchTypeSelector(parent)
{
}
bool OutlinerSearchTypeSelector::filterItemOut(const QModelIndex& sourceIndex, bool filteredByBase)
{
auto* currItem = m_model->itemFromIndex(sourceIndex);
if (currItem != nullptr)
{
int unfilteredIndex = getUnfilteredDataIndex(currItem);
if (unfilteredIndex >= 0 && unfilteredIndex < aznumeric_cast<int>(OutlinerSearchWidget::GlobalSearchCriteria::FirstRealFilter))
{
// never filter out the categories before FirstRealFilter (unlocked/locked, visible/hidden, etc.)
return false;
}
}
// no special case, return the result of the base filter
return filteredByBase;
}
void OutlinerSearchTypeSelector::initItem(QStandardItem* item, const SearchTypeFilter& filter, int unfilteredDataIndex)
{
SearchTypeSelector::initItem(item, filter, unfilteredDataIndex);
if (filter.displayName == "--------")
{
item->setCheckable(false);
}
if (unfilteredDataIndex >= 0 && unfilteredDataIndex < static_cast<int>(OutlinerSearchWidget::GlobalSearchCriteria::FirstRealFilter))
{
item->setIcon(OutlinerIcons::GetInstance().GetIcon(unfilteredDataIndex));
}
}
int OutlinerSearchTypeSelector::GetNumFixedItems()
{
return static_cast<int>(OutlinerSearchWidget::GlobalSearchCriteria::FirstRealFilter);
}
OutlinerCriteriaButton::OutlinerCriteriaButton(QString labelText, QWidget* parent, int index)
: FilterCriteriaButton(labelText, parent)
{
if (index >= 0 && index < static_cast<int>(OutlinerSearchWidget::GlobalSearchCriteria::FirstRealFilter))
{
QLabel* icon = new QLabel(this);
icon->setStyleSheet(m_tagLabel->styleSheet() + "border: 0px; background-color: transparent;");
icon->setPixmap(OutlinerIcons::GetInstance().GetIcon(index).pixmap(10, 10));
m_frameLayout->insertWidget(0, icon);
}
}
OutlinerSearchWidget::OutlinerSearchWidget(QWidget* parent)
: FilteredSearchWidget(parent, true)
{
SetupOwnSelector(new OutlinerSearchTypeSelector(assetTypeSelectorButton()));
const SearchTypeFilterList globalMenu{
{"Global Settings", "Unlocked"},
{"Global Settings", "Locked"},
{"Global Settings", "Visible"},
{"Global Settings", "Hidden"},
{"Global Settings", "--------"}
};
int value = 0;
for (const SearchTypeFilter& filter : globalMenu)
{
AddTypeFilter(filter.category, filter.displayName, QVariant::fromValue<AZ::Uuid>(AZ::Uuid::Create()), value);
++value;
}
}
OutlinerSearchWidget::~OutlinerSearchWidget()
{
delete m_delegate;
m_delegate = nullptr;
delete m_selector;
m_selector = nullptr;
}
void OutlinerSearchWidget::SetupPaintDelegates()
{
m_delegate = new OutlinerSearchItemDelegate(m_selector->GetTree());
m_selector->GetTree()->setItemDelegate(m_delegate);
m_delegate->SetSelector(m_selector);
}
FilterCriteriaButton* OutlinerSearchWidget::createCriteriaButton(const SearchTypeFilter& filter, int filterIndex)
{
return new OutlinerCriteriaButton(filter.displayName, this, filterIndex);
}
OutlinerSearchItemDelegate::OutlinerSearchItemDelegate(QWidget* parent) : QStyledItemDelegate(parent)
{
}
void OutlinerSearchItemDelegate::PaintRichText(QPainter* painter, QStyleOptionViewItem& opt, QString& text) const
{
int textDocDrawYOffset = 3;
QPoint paintertextDocRenderOffset = QPoint(-2, -1);
QTextDocument textDoc;
textDoc.setDefaultFont(opt.font);
opt.palette.color(QPalette::Text);
textDoc.setDefaultStyleSheet("body {color: " + opt.palette.color(QPalette::Text).name() + "}");
textDoc.setHtml("<body>" + text + "</body>");
QRect textRect = opt.widget->style()->proxy()->subElementRect(QStyle::SE_ItemViewItemText, &opt);
painter->translate(textRect.topLeft() - paintertextDocRenderOffset);
textDoc.setTextWidth(textRect.width());
textDoc.drawContents(painter, QRectF(0, textDocDrawYOffset, textRect.width(), textRect.height() + textDocDrawYOffset));
}
void OutlinerSearchItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
bool isGlobalOption = false;
painter->save();
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
const QWidget* widget = option.widget;
QStyle* style = widget ? widget->style() : QApplication::style();
if (!opt.icon.isNull())
{
// Draw the icon if there is one.
QRect r = style->subElementRect(QStyle::SubElement::SE_ItemViewItemDecoration, &opt, widget);
r.setX(-r.width());
QIcon::Mode mode = QIcon::Normal;
QIcon::State state = QIcon::On;
opt.icon.paint(painter, r, opt.decorationAlignment, mode, state);
opt.icon = QIcon();
opt.decorationSize = QSize(0, 0);
isGlobalOption = true;
}
// Handle the separator
if (opt.text.contains("-------"))
{
// Draw this item as a solid line.
painter->setPen(QColor(FilteredSearchWidget::GetSeparatorColor()));
painter->drawLine(0, opt.rect.center().y() + 3, opt.rect.right(), opt.rect.center().y() + 4);
}
else
{
if (m_selector->GetFilterString().length() > 0 && !isGlobalOption && opt.features & QStyleOptionViewItem::ViewItemFeature::HasCheckIndicator)
{
// Create rich text menu text to show filterstring
QString label{ opt.text };
opt.text = "";
style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
int highlightTextIndex = 0;
do
{
// Find filter term within the text.
highlightTextIndex = label.lastIndexOf(m_selector->GetFilterString(), highlightTextIndex - 1, Qt::CaseInsensitive);
if (highlightTextIndex >= 0)
{
// Insert background-color terminator at appropriate place to return to normal text.
label.insert(highlightTextIndex + m_selector->GetFilterString().length(), "</span>");
// Insert background-color command at appropriate place to highlight filter term.
label.insert(highlightTextIndex, "<span style=\"background-color: " + FilteredSearchWidget::GetBackgroundColor() + "\">");
}
} while (highlightTextIndex > 0);// Repeat in case there are multiple occurrences.
PaintRichText(painter, opt, label);
}
else
{
// There's no filter to apply, just draw it.
QString label = opt.text;
opt.text = "";
style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
PaintRichText(painter, opt, label);
}
}
painter->restore();
}
QSize OutlinerSearchItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
if (opt.text.contains("-------"))
{
return QSize(0, 6);
}
return QStyledItemDelegate::sizeHint(option, index);
}
}
#include <UI/Outliner/moc_OutlinerSearchWidget.cpp>