Ensure ImGui menu is displayed when the Viewport UI viewport border is showing (#5240)
* add optimize off code temporarily Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> * ensure the imgui menu displays when the viewport border is active Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
d598a7c709
commit
4c41a4dfc9
@@ -43,10 +43,11 @@
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/API/ComponentEntityObjectBus.h>
|
||||
#include <AzToolsFramework/API/EditorCameraBus.h>
|
||||
#include <AzToolsFramework/API/ViewportEditorModeTrackerInterface.h>
|
||||
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemViewportSelectionRequestBus.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.h>
|
||||
#include <AzToolsFramework/API/EditorCameraBus.h>
|
||||
|
||||
// AtomToolsFramework
|
||||
#include <AtomToolsFramework/Viewport/RenderViewportWidget.h>
|
||||
@@ -1032,6 +1033,7 @@ void EditorViewportWidget::ConnectViewportInteractionRequestBus()
|
||||
AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Handler::BusConnect(GetViewportId());
|
||||
AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler::BusConnect(GetViewportId());
|
||||
m_viewportUi.ConnectViewportUiBus(GetViewportId());
|
||||
AzFramework::ViewportBorderRequestBus::Handler::BusConnect(GetViewportId());
|
||||
|
||||
AzFramework::InputSystemCursorConstraintRequestBus::Handler::BusConnect();
|
||||
}
|
||||
@@ -1040,6 +1042,7 @@ void EditorViewportWidget::DisconnectViewportInteractionRequestBus()
|
||||
{
|
||||
AzFramework::InputSystemCursorConstraintRequestBus::Handler::BusDisconnect();
|
||||
|
||||
AzFramework::ViewportBorderRequestBus::Handler::BusDisconnect();
|
||||
m_viewportUi.DisconnectViewportUiBus();
|
||||
AzToolsFramework::ViewportInteraction::EditorEntityViewportInteractionRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::ViewportInteraction::MainEditorViewportInteractionRequestBus::Handler::BusDisconnect();
|
||||
@@ -2638,4 +2641,25 @@ void EditorViewportWidget::StopFullscreenPreview()
|
||||
// Show the main window
|
||||
MainWindow::instance()->show();
|
||||
}
|
||||
|
||||
AZStd::optional<AzFramework::ViewportBorderPadding> EditorViewportWidget::GetViewportBorderPadding() const
|
||||
{
|
||||
if (auto viewportEditorModeTracker = AZ::Interface<AzToolsFramework::ViewportEditorModeTrackerInterface>::Get())
|
||||
{
|
||||
auto viewportEditorModes = viewportEditorModeTracker->GetViewportEditorModes({ AzToolsFramework::GetEntityContextId() });
|
||||
if (viewportEditorModes->IsModeActive(AzToolsFramework::ViewportEditorMode::Focus) ||
|
||||
viewportEditorModes->IsModeActive(AzToolsFramework::ViewportEditorMode::Component))
|
||||
{
|
||||
AzFramework::ViewportBorderPadding viewportBorderPadding = {};
|
||||
viewportBorderPadding.m_top = AzToolsFramework::ViewportUi::ViewportUiTopBorderSize;
|
||||
viewportBorderPadding.m_left = AzToolsFramework::ViewportUi::ViewportUiLeftRightBottomBorderSize;
|
||||
viewportBorderPadding.m_right = AzToolsFramework::ViewportUi::ViewportUiLeftRightBottomBorderSize;
|
||||
viewportBorderPadding.m_bottom = AzToolsFramework::ViewportUi::ViewportUiLeftRightBottomBorderSize;
|
||||
return viewportBorderPadding;
|
||||
}
|
||||
}
|
||||
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
#include <moc_EditorViewportWidget.cpp>
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include <AzFramework/Windowing/WindowBus.h>
|
||||
#include <AzFramework/Visibility/EntityVisibilityQuery.h>
|
||||
#include <AzFramework/Viewport/ViewportBus.h>
|
||||
|
||||
// forward declarations.
|
||||
class CBaseObject;
|
||||
@@ -86,6 +87,7 @@ AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
class SANDBOX_API EditorViewportWidget final
|
||||
: public QtViewport
|
||||
, public AzFramework::ViewportBorderRequestBus::Handler
|
||||
, private IEditorNotifyListener
|
||||
, private IUndoManagerListener
|
||||
, private Camera::EditorCameraRequestBus::Handler
|
||||
@@ -120,6 +122,9 @@ public:
|
||||
void SetFOV(float fov) override;
|
||||
float GetFOV() const override;
|
||||
|
||||
// AzFramework::ViewportBorderRequestBus overrides ...
|
||||
AZStd::optional<AzFramework::ViewportBorderPadding> GetViewportBorderPadding() const override;
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Private types ...
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Viewport/ViewportId.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzFramework/Viewport/ViewportId.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -20,18 +21,15 @@ namespace AZ
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
class ViewportRequests
|
||||
: public AZ::EBusTraits
|
||||
class ViewportRequests : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
using BusIdType = ViewportId;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
virtual ~ViewportRequests() {}
|
||||
|
||||
//! Gets the current camera's world to view matrix.
|
||||
virtual const AZ::Matrix4x4& GetCameraViewMatrix() const = 0;
|
||||
//! Sets the current camera's world to view matrix.
|
||||
@@ -44,8 +42,36 @@ namespace AzFramework
|
||||
virtual AZ::Transform GetCameraTransform() const = 0;
|
||||
//! Convenience method, sets the camera's world to view matrix from this AZ::Transform.
|
||||
virtual void SetCameraTransform(const AZ::Transform& transform) = 0;
|
||||
|
||||
protected:
|
||||
~ViewportRequests() = default;
|
||||
};
|
||||
|
||||
using ViewportRequestBus = AZ::EBus<ViewportRequests>;
|
||||
|
||||
} //namespace AzFramework
|
||||
//! The additional padding around the viewport when a viewport border is active.
|
||||
struct ViewportBorderPadding
|
||||
{
|
||||
float m_top;
|
||||
float m_bottom;
|
||||
float m_left;
|
||||
float m_right;
|
||||
};
|
||||
|
||||
//! For performing queries about the state of the viewport border.
|
||||
class ViewportBorderRequests : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
using BusIdType = ViewportId;
|
||||
|
||||
//! Returns if a viewport border is in effect and what the current dimensions (padding) of the border are.
|
||||
virtual AZStd::optional<ViewportBorderPadding> GetViewportBorderPadding() const = 0;
|
||||
|
||||
protected:
|
||||
~ViewportBorderRequests() = default;
|
||||
};
|
||||
|
||||
using ViewportBorderRequestBus = AZ::EBus<ViewportBorderRequests>;
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiCluster.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiDisplay.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiDisplayLayout.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiSwitcher.h>
|
||||
#include <AzToolsFramework/ViewportUi/ViewportUiTextField.h>
|
||||
#include <QWidget>
|
||||
@@ -19,7 +20,6 @@
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
const static int HighlightBorderSize = 5;
|
||||
const static int TopHighlightBorderSize = 25;
|
||||
const static char* HighlightBorderColor = "#4A90E2";
|
||||
|
||||
static void UnparentWidgets(ViewportUiElementIdInfoLookup& viewportUiElementIdInfoLookup)
|
||||
@@ -61,7 +61,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
, m_uiOverlay(parent)
|
||||
, m_fullScreenLayout(&m_uiOverlay)
|
||||
, m_uiOverlayLayout()
|
||||
, m_componentModeBorderText(&m_uiOverlay)
|
||||
, m_viewportBorderText(&m_uiOverlay)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -221,11 +221,11 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
AZStd::shared_ptr<QWidget> ViewportUiDisplay::GetViewportUiElement(ViewportUiElementId elementId)
|
||||
{
|
||||
auto element = m_viewportUiElements.find(elementId);
|
||||
if (element != m_viewportUiElements.end())
|
||||
if (auto element = m_viewportUiElements.find(elementId); element != m_viewportUiElements.end())
|
||||
{
|
||||
return element->second.m_widget;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -287,27 +287,30 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
return element.IsValid() && element.m_widget->isVisible();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::CreateViewportBorder(const AZStd::string& borderTitle)
|
||||
{
|
||||
const AZStd::string styleSheet = AZStd::string::format(
|
||||
"border: %dpx solid %s; border-top: %dpx solid %s;", HighlightBorderSize, HighlightBorderColor, TopHighlightBorderSize,
|
||||
"border: %dpx solid %s; border-top: %dpx solid %s;", HighlightBorderSize, HighlightBorderColor, ViewportUiTopBorderSize,
|
||||
HighlightBorderColor);
|
||||
m_uiOverlay.setStyleSheet(styleSheet.c_str());
|
||||
m_uiOverlayLayout.setContentsMargins(
|
||||
HighlightBorderSize + ViewportUiOverlayMargin, TopHighlightBorderSize + ViewportUiOverlayMargin,
|
||||
HighlightBorderSize + ViewportUiOverlayMargin, ViewportUiTopBorderSize + ViewportUiOverlayMargin,
|
||||
HighlightBorderSize + ViewportUiOverlayMargin, HighlightBorderSize + ViewportUiOverlayMargin);
|
||||
m_componentModeBorderText.setVisible(true);
|
||||
m_componentModeBorderText.setText(borderTitle.c_str());
|
||||
m_viewportBorderText.setVisible(true);
|
||||
m_viewportBorderText.setText(borderTitle.c_str());
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::RemoveViewportBorder()
|
||||
{
|
||||
m_componentModeBorderText.setVisible(false);
|
||||
m_viewportBorderText.setVisible(false);
|
||||
m_uiOverlay.setStyleSheet("border: none;");
|
||||
m_uiOverlayLayout.setMargin(ViewportUiOverlayMargin);
|
||||
m_uiOverlayLayout.setContentsMargins(
|
||||
ViewportUiOverlayMargin, ViewportUiOverlayMargin + ViewportUiOverlayTopMarginPadding, ViewportUiOverlayMargin,
|
||||
ViewportUiOverlayMargin);
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::PositionViewportUiElementFromWorldSpace(ViewportUiElementId elementId, const AZ::Vector3& pos)
|
||||
@@ -359,10 +362,10 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
// format the label which will appear on top of the highlight border
|
||||
AZStd::string styleSheet = AZStd::string::format("background-color: %s; border: none;", HighlightBorderColor);
|
||||
m_componentModeBorderText.setStyleSheet(styleSheet.c_str());
|
||||
m_componentModeBorderText.setFixedHeight(TopHighlightBorderSize);
|
||||
m_componentModeBorderText.setVisible(false);
|
||||
m_fullScreenLayout.addWidget(&m_componentModeBorderText, 0, 0, Qt::AlignTop | Qt::AlignHCenter);
|
||||
m_viewportBorderText.setStyleSheet(styleSheet.c_str());
|
||||
m_viewportBorderText.setFixedHeight(ViewportUiTopBorderSize);
|
||||
m_viewportBorderText.setVisible(false);
|
||||
m_fullScreenLayout.addWidget(&m_viewportBorderText, 0, 0, Qt::AlignTop | Qt::AlignHCenter);
|
||||
}
|
||||
|
||||
void ViewportUiDisplay::PrepareWidgetForViewportUi(QPointer<QWidget> widget)
|
||||
@@ -395,14 +398,14 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
|
||||
void ViewportUiDisplay::UpdateUiOverlayGeometry()
|
||||
{
|
||||
// add the component mode border region if visible
|
||||
// add the viewport border region if visible
|
||||
QRegion region;
|
||||
if (m_componentModeBorderText.isVisible())
|
||||
if (m_viewportBorderText.isVisible())
|
||||
{
|
||||
// get the border region by taking the entire region and subtracting the non-border area
|
||||
region += m_uiOverlay.rect();
|
||||
region -= QRect(
|
||||
QPoint(m_uiOverlay.rect().left() + HighlightBorderSize, m_uiOverlay.rect().top() + TopHighlightBorderSize),
|
||||
QPoint(m_uiOverlay.rect().left() + HighlightBorderSize, m_uiOverlay.rect().top() + ViewportUiTopBorderSize),
|
||||
QPoint(m_uiOverlay.rect().right() - HighlightBorderSize, m_uiOverlay.rect().bottom() - HighlightBorderSize));
|
||||
}
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace AzToolsFramework::ViewportUi::Internal
|
||||
QWidget m_uiOverlay; //!< The UI Overlay which displays Viewport UI Elements.
|
||||
QGridLayout m_fullScreenLayout; //!< The layout which extends across the full screen.
|
||||
ViewportUiDisplayLayout m_uiOverlayLayout; //!< The layout used for optionally anchoring Viewport UI Elements.
|
||||
QLabel m_componentModeBorderText; //!< The text used for the Component Mode border.
|
||||
QLabel m_viewportBorderText; //!< The text used for the viewport border.
|
||||
|
||||
QWidget* m_renderOverlay;
|
||||
QPointer<QWidget> m_fullScreenWidget; //!< Reference to the widget attached to m_fullScreenLayout if any.
|
||||
|
||||
+12
-5
@@ -14,13 +14,20 @@
|
||||
#include <QGridLayout>
|
||||
#include <QPointer>
|
||||
|
||||
namespace AzToolsFramework::ViewportUi
|
||||
{
|
||||
//! Margin for the Viewport UI Overlay (in pixels)
|
||||
constexpr int ViewportUiOverlayMargin = 5;
|
||||
//! Padding to make space for ImGui (in pixels)
|
||||
constexpr int ViewportUiOverlayTopMarginPadding = 20;
|
||||
//! Size of the top viewport border (in pixels)
|
||||
constexpr int ViewportUiTopBorderSize = 25;
|
||||
//! Size of the left, right and bottom viewport border (in pixels)
|
||||
constexpr int ViewportUiLeftRightBottomBorderSize = 5;
|
||||
} // namespace AzToolsFramework::ViewportUi
|
||||
|
||||
namespace AzToolsFramework::ViewportUi::Internal
|
||||
{
|
||||
// margin for the Viewport UI Overlay in pixels
|
||||
constexpr int ViewportUiOverlayMargin = 5;
|
||||
// padding to make space for ImGui
|
||||
constexpr int ViewportUiOverlayTopMarginPadding = 20;
|
||||
|
||||
//! QGridLayout implementation that uses a grid of QVBox/QHBoxLayouts internally to stack widgets.
|
||||
class ViewportUiDisplayLayout : public QGridLayout
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/std/sort.h>
|
||||
#include <AzFramework/Input/Buses/Requests/InputSystemCursorRequestBus.h>
|
||||
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
||||
#include <AzFramework/Viewport/ViewportBus.h>
|
||||
#include <ILevelSystem.h>
|
||||
#include "ImGuiColorDefines.h"
|
||||
#include "LYImGuiUtils/ImGuiDrawHelpers.h"
|
||||
@@ -92,8 +93,36 @@ namespace ImGui
|
||||
|
||||
void ImGuiLYCommonMenu::OnImGuiUpdate()
|
||||
{
|
||||
float dpiScalingFactor = 1.0f;
|
||||
ImGuiManagerBus::BroadcastResult(dpiScalingFactor, &ImGuiManagerBus::Events::GetDpiScalingFactor);
|
||||
|
||||
// Utility function to calculate the size in device pixels based on the current DPI
|
||||
const auto dpiAwareSizeFn = [dpiScalingFactor](float size)
|
||||
{
|
||||
return dpiScalingFactor * size;
|
||||
};
|
||||
|
||||
AZStd::optional<AzFramework::ViewportBorderPadding> viewportBorderPaddingOpt;
|
||||
AzFramework::ViewportBorderRequestBus::BroadcastResult(
|
||||
viewportBorderPaddingOpt, &AzFramework::ViewportBorderRequestBus::Events::GetViewportBorderPadding);
|
||||
|
||||
AzFramework::ViewportBorderPadding viewportBorderPadding = viewportBorderPaddingOpt.value_or(AzFramework::ViewportBorderPadding{});
|
||||
// Utility function to return the current offset (scaled by DPI) if a viewport border
|
||||
// is active (otherwise 0.0)
|
||||
auto dpiAwareBorderOffsetFn = [&viewportBorderPaddingOpt, &dpiAwareSizeFn](float size)
|
||||
{
|
||||
return viewportBorderPaddingOpt.has_value() ? dpiAwareSizeFn(size) : 0.0f;
|
||||
};
|
||||
|
||||
// Shift the menu down if a viewport border is active
|
||||
ImVec2 cachedSafeArea = ImGui::GetStyle().DisplaySafeAreaPadding;
|
||||
ImGui::GetStyle().DisplaySafeAreaPadding = ImVec2(cachedSafeArea.x, cachedSafeArea.y + dpiAwareSizeFn(viewportBorderPadding.m_top));
|
||||
|
||||
if (ImGui::BeginMainMenuBar())
|
||||
{
|
||||
// Constant to shift right aligned menu items by (distance to the left) when a viewport border is active
|
||||
const float rightAlignedBorderOffset = dpiAwareBorderOffsetFn(36.0f);
|
||||
|
||||
// Get Discrete Input state now, we will use it both inside the ImGui SubMenu, and along the main task bar ( when it is on )
|
||||
bool discreteInputEnabled = false;
|
||||
ImGuiManagerBus::BroadcastResult(discreteInputEnabled, &IImGuiManager::GetEnableDiscreteInputMode);
|
||||
@@ -101,7 +130,8 @@ namespace ImGui
|
||||
// Input Mode Display
|
||||
{
|
||||
const float prevCursorPos = ImGui::GetCursorPosX();
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - 300.0f);
|
||||
ImGui::SetCursorPosX(
|
||||
ImGui::GetWindowWidth() - dpiAwareSizeFn(300.0f + viewportBorderPadding.m_right) - rightAlignedBorderOffset);
|
||||
|
||||
AZStd::string inputTitle = "Input: ";
|
||||
if (!discreteInputEnabled)
|
||||
@@ -152,7 +182,7 @@ namespace ImGui
|
||||
}
|
||||
|
||||
// Add some space before the first menu so it won't overlap with view control buttons
|
||||
ImGui::SetCursorPosX(40.f);
|
||||
ImGui::SetCursorPosX(dpiAwareSizeFn(40.0f + viewportBorderPadding.m_left));
|
||||
|
||||
// Main Open 3D Engine menu
|
||||
if (ImGui::BeginMenu("O3DE"))
|
||||
@@ -557,11 +587,12 @@ namespace ImGui
|
||||
// End LY Common Tools menu
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
const int labelSize{ 100 };
|
||||
const int buttonSize{ 40 };
|
||||
|
||||
const float labelSize = dpiAwareSizeFn(100.0f + viewportBorderPadding.m_right) + rightAlignedBorderOffset;
|
||||
const float buttonSize = dpiAwareSizeFn(40.0f + viewportBorderPadding.m_right) + rightAlignedBorderOffset;
|
||||
ImGuiUpdateListenerBus::Broadcast(&IImGuiUpdateListener::OnImGuiMainMenuUpdate);
|
||||
ImGui::SameLine(ImGui::GetWindowContentRegionMax().x - labelSize);
|
||||
float backgroundHeight = ImGui::GetTextLineHeight() + 3;
|
||||
float backgroundHeight = ImGui::GetTextLineHeight() + dpiAwareSizeFn(3.0f);
|
||||
ImVec2 cursorPos = ImGui::GetCursorScreenPos();
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(
|
||||
cursorPos, ImVec2(cursorPos.x + labelSize, cursorPos.y + backgroundHeight), IM_COL32(0, 115, 187, 255));
|
||||
@@ -580,6 +611,9 @@ namespace ImGui
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
|
||||
// Restore original safe area.
|
||||
ImGui::GetStyle().DisplaySafeAreaPadding = cachedSafeArea;
|
||||
|
||||
// Update Contextual Controller Window
|
||||
if (m_controllerLegendWindowVisible)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user