/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace EMotionFX { class BlendNParamWeightElementWidget; class BlendNParamWeightContainerWidget; /// GUI data corresponding to the reflected element of the property container. /// Used to perform validation on the data in order to /// Write valid data to the property only after successful validation class BlendNParamWeightGuiEntry { public: AZ_RTTI(BlendNParamWeightGuiEntry, "{5267D4D9-60AD-49D3-85D5-84419F7C4569}") AZ_CLASS_ALLOCATOR_DECL BlendNParamWeightGuiEntry(AZ::u32 portId, float weightRange, const char* sourceNodeName); virtual ~BlendNParamWeightGuiEntry() = default; const char* GetPortLabel() const; AZ::u32 GetPortId() const; float GetWeightRange() const; void SetWeightRange(float value); void SetValid(bool valid); bool IsValid() const; const char* GetSourceNodeName() const; const AZStd::string& GetTooltipText() const; void SetTooltipText(const AZStd::string& text); private: AZStd::string m_tooltipText; const char* m_sourceNodeName = nullptr; bool m_isValid = false; AZ::u32 m_portId = MCORE_INVALIDINDEX32; float m_weightRange = 0; }; /// Every time a widget is created by the element property handler (a single entry in the container) /// The widget container is notified in order to be able to connect to its child widget class BlendNParemWeightWidgetBus : public AZ::EBusTraits { public: virtual void OnRequestDataBind(BlendNParamWeightElementWidget* /*elementWidget*/) { } }; using BlendNParemWeightWidgetNotificationBus = AZ::EBus; /// Widget that displays a single element of the property container class BlendNParamWeightElementWidget : public QWidget { Q_OBJECT //AUTOMOC public: AZ_CLASS_ALLOCATOR_DECL BlendNParamWeightElementWidget(QWidget* parent); ~BlendNParamWeightElementWidget(); void SetParentContainerWidget(BlendNParamWeightContainerWidget* parent) { m_parentContainerWidget = parent; } void SetDataSource(const BlendNParamWeightGuiEntry& paramWeight); float GetWeightRange() const; void SetId(size_t index); size_t GetId() const; void UpdateGui(); static const int s_decimalPlaces; signals: void DataChanged(BlendNParamWeightElementWidget* childWidget); private slots: void OnWeightRangeEdited(double value); private: BlendNParamWeightContainerWidget* m_parentContainerWidget = nullptr; const BlendNParamWeightGuiEntry* m_paramWeight = nullptr; QLabel* m_sourceNodeNameLabel = nullptr; AzQtComponents::DoubleSpinBox* m_weightField = nullptr; size_t m_dataElementIndex = MCORE_INVALIDINDEX32; }; /// Widget of the property container class BlendNParamWeightContainerWidget : public QWidget , private EMotionFX::AnimGraphNotificationBus::Handler { Q_OBJECT //AUTOMOC public: AZ_CLASS_ALLOCATOR_DECL BlendNParamWeightContainerWidget(QWidget* parent); ~BlendNParamWeightContainerWidget(); void SetParamWeights(const AZStd::vector& paramWeights, const AnimGraphNode* node); const AZStd::vector& GetParamWeights() const; void ConnectWidgetToDataSource(BlendNParamWeightElementWidget* elementWidget); void AddElementWidget(BlendNParamWeightElementWidget* widget); void RemoveElementWidget(BlendNParamWeightElementWidget* widget); void Update(); signals: void DataChanged(); private slots: void HandleOnChildWidgetDataChanged(BlendNParamWeightElementWidget* elementWidget); private: bool CheckAllElementsValidation(); bool CheckValidation(); bool CheckElementValidation(size_t index); void UpdateDataValidation(); void EqualizeWeightRanges(); void EqualizeWeightRanges(float min, float max); void SetAllValid(); /////////////////////////////////////////////////////////////////// // AnimGraphNotificationBus implementation void OnSyncVisualObject(AnimGraphObject* object) override; AZStd::vector m_elementWidgets; AZStd::vector m_paramWeights; size_t m_widgetBoundToDataCount = 0; }; class BlendNParamWeightElementHandler : public QObject , public AzToolsFramework::PropertyHandler { Q_OBJECT //AUTOMOC public: AZ_CLASS_ALLOCATOR_DECL AZ::u32 GetHandlerName() const override; QWidget* CreateGUI(QWidget* parent) override; bool AutoDelete() const override { return false; } void ConsumeAttribute(BlendNParamWeightElementWidget* widget, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) override { } void WriteGUIValuesIntoProperty(size_t index, BlendNParamWeightElementWidget* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node) override { } bool ReadValuesIntoGUI(size_t index, BlendNParamWeightElementWidget* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node) override; }; class BlendNParamWeightsHandler : public QObject , public AzToolsFramework::PropertyHandler, BlendNParamWeightContainerWidget> , private BlendNParemWeightWidgetNotificationBus::Handler { Q_OBJECT //AUTOMOC public: AZ_CLASS_ALLOCATOR_DECL BlendNParamWeightsHandler(); ~BlendNParamWeightsHandler(); AZ::u32 GetHandlerName() const override; QWidget* CreateGUI(QWidget* parent) override; bool AutoDelete() const override { return false; } void ConsumeAttribute(BlendNParamWeightContainerWidget* widget, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) override; void WriteGUIValuesIntoProperty(size_t index, BlendNParamWeightContainerWidget* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node) override; bool ReadValuesIntoGUI(size_t index, BlendNParamWeightContainerWidget* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node) override; private: ////////////////////////////////////////////////////////////////////////// // BlendNParemWeightWidgetNotificationBus::Handler implementation void OnRequestDataBind(BlendNParamWeightElementWidget* elementWidget) override; BlendNParamWeightContainerWidget* m_containerWidget = nullptr; AnimGraphNode* m_node = nullptr; }; }