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 @@
+
+
\ 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.