diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/toolbar/Locked_Status.svg b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/toolbar/Locked_Status.svg new file mode 100644 index 0000000000..2612059dce --- /dev/null +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/img/UI20/toolbar/Locked_Status.svg @@ -0,0 +1,12 @@ + + + Icon / Locked Status + + + + + + + + + \ No newline at end of file diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc index 00fa95d094..7070bd372b 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc +++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/resources.qrc @@ -356,7 +356,8 @@ img/UI20/toolbar/Load.svg img/UI20/toolbar/Local.svg img/UI20/toolbar/Locked.svg - img/UI20/toolbar/LUA.svg + img/UI20/toolbar/Locked_Status.svg + img/UI20/toolbar/LUA.svg img/UI20/toolbar/Material.svg img/UI20/toolbar/Measure.svg img/UI20/toolbar/Move.svg diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp index db321d6818..5603c1a0f7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp @@ -2646,6 +2646,9 @@ namespace AzToolsFramework m_spaceCluster.m_spaceLock = ReferenceFrame::World; } } + ViewportUi::ViewportUiRequestBus::Event( + ViewportUi::DefaultViewportId, &ViewportUi::ViewportUiRequestBus::Events::SetClusterButtonLocked, + m_spaceCluster.m_spaceClusterId, buttonId, m_spaceCluster.m_spaceLock.has_value()); }; m_spaceCluster.m_spaceSelectionHandler = AZ::Event::Handler(onButtonClicked); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.cpp index 79744f1dbf..d452d47508 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.cpp @@ -108,6 +108,61 @@ namespace AzToolsFramework::ViewportUi::Internal m_widgetCallbacks.Update(); } + void ViewportUiCluster::SetButtonLocked(const ButtonId buttonId, const bool isLocked) + { + const auto& buttons = m_buttonGroup->GetButtons(); + + // unlocked previously locked button + if (m_lockedButtonId.has_value() && isLocked) + { + // find the button to extract the old icon (without overlay) + auto findLocked = [this](const Button* button) { return (button->m_buttonId == m_lockedButtonId); }; + if (auto lockedButtonIt = AZStd::find_if(buttons.begin(), buttons.end(), findLocked); lockedButtonIt != buttons.end()) + { + // get the action corresponding to the lockedButtonId + if (auto actionEntry = m_buttonActionMap.find(m_lockedButtonId.value()); actionEntry != m_buttonActionMap.end()) + { + // remove the overlay + auto action = actionEntry->second; + action->setIcon(QIcon(QString((*lockedButtonIt)->m_icon.c_str()))); + } + } + } + + auto found = [buttonId](Button* button) { return (button->m_buttonId == buttonId); }; + if (auto buttonIt = AZStd::find_if(buttons.begin(), buttons.end(), found); buttonIt != buttons.end()) + { + QIcon newIcon; + + if (isLocked) + { + // overlay the locked icon ontop of the button's icon + QPixmap comboPixmap(24, 24); + comboPixmap.fill(Qt::transparent); + QPixmap firstImage(QString((*buttonIt)->m_icon.c_str())); + QPixmap secondImage(QString(":/stylesheet/img/UI20/toolbar/Locked_Status.svg")); + + QPainter painter(&comboPixmap); + painter.drawPixmap(0, 0, firstImage); + painter.drawPixmap(0, 0, secondImage); + newIcon.addPixmap(comboPixmap); + m_lockedButtonId = buttonId; + } + else + { + // remove the overlay + newIcon = QIcon(QString((*buttonIt)->m_icon.c_str())); + m_lockedButtonId = AZStd::nullopt; + } + + if (auto actionEntry = m_buttonActionMap.find(buttonId); actionEntry != m_buttonActionMap.end()) + { + auto action = actionEntry->second; + action->setIcon(newIcon); + } + } + } + ViewportUiWidgetCallbacks ViewportUiCluster::GetWidgetCallbacks() { return m_widgetCallbacks; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.h index 4f738177ea..027a201a9c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiCluster.h @@ -17,6 +17,7 @@ #include #include #include +#include namespace AzToolsFramework::ViewportUi::Internal { @@ -38,6 +39,8 @@ namespace AzToolsFramework::ViewportUi::Internal void RemoveButton(ButtonId buttonId); //! Updates all registered actions. void Update(); + //! Adds a locked overlay to the button's icon. + void SetButtonLocked(ButtonId buttonId, bool isLocked); //! Returns the widget manager. ViewportUiWidgetCallbacks GetWidgetCallbacks(); @@ -52,5 +55,6 @@ namespace AzToolsFramework::ViewportUi::Internal AZStd::shared_ptr m_buttonGroup; //!< Data structure which the cluster will be displaying to the Viewport UI. AZStd::unordered_map> m_buttonActionMap; //!< Map for buttons to their corresponding actions. ViewportUiWidgetCallbacks m_widgetCallbacks; //!< Registers actions and manages updates. + AZStd::optional m_lockedButtonId = AZStd::nullopt; //!< Used to track the last button locked. }; } // namespace AzToolsFramework::ViewportUi::Internal diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.cpp index e9e7dcc1cc..3565d33174 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.cpp @@ -100,6 +100,14 @@ namespace AzToolsFramework::ViewportUi::Internal } } + void ViewportUiDisplay::SetClusterButtonLocked(const ViewportUiElementId clusterId, const ButtonId buttonId, const bool isLocked) + { + if (auto viewportUiCluster = qobject_cast(GetViewportUiElement(clusterId).get())) + { + viewportUiCluster->SetButtonLocked(buttonId, isLocked); + } + } + void ViewportUiDisplay::RemoveClusterButton(ViewportUiElementId clusterId, ButtonId buttonId) { if (auto cluster = qobject_cast(GetViewportUiElement(clusterId).get())) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.h index d46e01c978..19d04e63ff 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiDisplay.h @@ -58,6 +58,7 @@ namespace AzToolsFramework::ViewportUi::Internal void AddCluster(AZStd::shared_ptr buttonGroup, Alignment align); void AddClusterButton(ViewportUiElementId clusterId, Button* button); + void SetClusterButtonLocked(ViewportUiElementId clusterId, ButtonId buttonId, bool isLocked); void RemoveClusterButton(ViewportUiElementId clusterId, ButtonId buttonId); void UpdateCluster(const ViewportUiElementId clusterId); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.cpp index 12c3b5c9bb..0668af383b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.cpp @@ -67,6 +67,16 @@ namespace AzToolsFramework::ViewportUi } } + void ViewportUiManager::SetClusterButtonLocked(const ClusterId clusterId, const ButtonId buttonId, const bool isLocked) + { + if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end()) + { + auto cluster = clusterIt->second; + m_viewportUi->SetClusterButtonLocked(cluster->GetViewportUiElementId(), buttonId, isLocked); + UpdateButtonGroupUi(cluster.get()); + } + } + void ViewportUiManager::RegisterClusterEventHandler(const ClusterId clusterId, AZ::Event::Handler& handler) { if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end()) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.h index 04a58cef65..14609ccc14 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiManager.h @@ -35,6 +35,7 @@ namespace AzToolsFramework::ViewportUi const SwitcherId CreateSwitcher(Alignment align) override; void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) override; void SetSwitcherActiveButton(SwitcherId switcherId, ButtonId buttonId) override; + void SetClusterButtonLocked(ClusterId clusterId, ButtonId buttonId, bool isLocked) override; const ButtonId CreateClusterButton(ClusterId clusterId, const AZStd::string& icon) override; const ButtonId CreateSwitcherButton( SwitcherId switcherId, const AZStd::string& icon, const AZStd::string& name = AZStd::string()) override; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiRequestBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiRequestBus.h index 3879817ccb..a068ffe9ee 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiRequestBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportUi/ViewportUiRequestBus.h @@ -65,6 +65,8 @@ namespace AzToolsFramework::ViewportUi virtual void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) = 0; //! Sets the active button of the switcher. This is the button which has a text label. virtual void SetSwitcherActiveButton(SwitcherId clusterId, ButtonId buttonId) = 0; + //! Adds a locked overlay to the cluster button's icon. + virtual void SetClusterButtonLocked(ClusterId clusterId, ButtonId buttonId, bool isLocked) = 0; //! Registers a new button onto a cluster. virtual const ButtonId CreateClusterButton(const ClusterId clusterId, const AZStd::string& icon) = 0; //! Registers a new button onto a switcher.