/* * 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. * * */ #include <Editor/PropertyWidgets/BlendTreeRotationLimitHandler.h> #include <AzCore/Memory/SystemAllocator.h> #include <EMotionFX/Source/ConstraintTransformRotationAngles.h> #include <AzToolsFramework/API/ToolsApplicationAPI.h> namespace EMotionFX { AZ_CLASS_ALLOCATOR_IMPL(BlendTreeRotationLimitHandler, EditorAllocator, 0); AZ_CLASS_ALLOCATOR_IMPL(BlendTreeRotationLimitContainerHandler, EditorAllocator, 0); AZ_CLASS_ALLOCATOR_IMPL(RotationLimitWdget, EditorAllocator, 0); AZ_CLASS_ALLOCATOR_IMPL(RotationLimitContainerWdget, EditorAllocator, 0); const int RotationLimitWdget::s_decimalPlaces = 1; RotationLimitWdget::RotationLimitWdget(QWidget* parent) { m_tooltipText = QString("Min %1 \xB0\n").arg((int)BlendTreeRotationLimitNode::RotationLimit::s_rotationLimitRangeMin); m_tooltipText += QString("Max %1 \xB0").arg((int)BlendTreeRotationLimitNode::RotationLimit::s_rotationLimitRangeMax); QHBoxLayout* hLayout = new QHBoxLayout(this); hLayout->setMargin(2); setLayout(hLayout); m_spinBoxMin = new AzQtComponents::DoubleSpinBox(this); layout()->addWidget(m_spinBoxMin); m_spinBoxMax = new AzQtComponents::DoubleSpinBox(this); layout()->addWidget(m_spinBoxMax); m_spinBoxMin->setRange(BlendTreeRotationLimitNode::RotationLimit::s_rotationLimitRangeMin, BlendTreeRotationLimitNode::RotationLimit::s_rotationLimitRangeMax); m_spinBoxMax->setRange(BlendTreeRotationLimitNode::RotationLimit::s_rotationLimitRangeMin, BlendTreeRotationLimitNode::RotationLimit::s_rotationLimitRangeMax); m_spinBoxMin->setDecimals(s_decimalPlaces); m_spinBoxMax->setDecimals(s_decimalPlaces); m_spinBoxMin->setToolTip(m_tooltipText); m_spinBoxMax->setToolTip(m_tooltipText); connect(m_spinBoxMin, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &RotationLimitWdget::HandleMinValueChanged); connect(m_spinBoxMax, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &RotationLimitWdget::HandleMaxValueChanged); } void RotationLimitWdget::SetRotationLimit(const BlendTreeRotationLimitNode::RotationLimit& rotationLimit) { m_rotationLimit = &rotationLimit; } void RotationLimitWdget::UpdateGui() { m_spinBoxMin->setValue(m_rotationLimit->GetLimitMin()); m_spinBoxMax->setValue(m_rotationLimit->GetLimitMax()); } void RotationLimitWdget::HandleMinValueChanged(double value) { m_spinBoxMin->setValue(value); if (m_spinBoxMin->value() <= m_spinBoxMax->value()) { AzQtComponents::SpinBox::setHasError(m_spinBoxMax, false); AzQtComponents::SpinBox::setHasError(m_spinBoxMin, false); m_spinBoxMin->setToolTip(m_tooltipText); m_spinBoxMax->setToolTip(m_tooltipText); emit DataChanged(); } else { AzQtComponents::SpinBox::setHasError(m_spinBoxMin, true); QString errorTooltip = QString("The value has to be less than or equal to %1 \xB0").arg(m_spinBoxMax->value()); m_spinBoxMin->setToolTip(errorTooltip); } } void RotationLimitWdget::HandleMaxValueChanged(double value) { m_spinBoxMax->setValue(value); if (m_spinBoxMin->value() <= m_spinBoxMax->value()) { AzQtComponents::SpinBox::setHasError(m_spinBoxMax, false); AzQtComponents::SpinBox::setHasError(m_spinBoxMin, false); m_spinBoxMin->setToolTip(m_tooltipText); m_spinBoxMax->setToolTip(m_tooltipText); emit DataChanged(); } else { AzQtComponents::SpinBox::setHasError(m_spinBoxMax, true); QString errorTooltip = QString("The value has to be greater than or equal to %1 \xB0").arg(m_spinBoxMin->value()); m_spinBoxMax->setToolTip(errorTooltip); } } float RotationLimitWdget::GetMin() const { return static_cast<float>(m_spinBoxMin->value()); } float RotationLimitWdget::GetMax() const { return static_cast<float>(m_spinBoxMax->value()); } QWidget* BlendTreeRotationLimitHandler::CreateGUI(QWidget* parent) { RotationLimitWdget* rotationLimitWdget = aznew RotationLimitWdget(parent); connect(rotationLimitWdget, &RotationLimitWdget::DataChanged, this, [rotationLimitWdget]() { AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(&AzToolsFramework::PropertyEditorGUIMessages::RequestWrite, rotationLimitWdget); }); return rotationLimitWdget; } AZ::u32 BlendTreeRotationLimitHandler::GetHandlerName() const { return AZ_CRC("BlendTreeRotationLimitHandler", 0xc1af4ea8); } void BlendTreeRotationLimitHandler::ConsumeAttribute(RotationLimitWdget* /*widget*/, AZ::u32 /*attrib*/, AzToolsFramework::PropertyAttributeReader* /*attrValue*/, const char* /*debugName*/) { } void BlendTreeRotationLimitHandler::WriteGUIValuesIntoProperty(size_t /*index*/, RotationLimitWdget* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* /*node*/) { instance.SetMin(GUI->GetMin()); instance.SetMax(GUI->GetMax()); } bool BlendTreeRotationLimitHandler::ReadValuesIntoGUI(size_t /*index*/, RotationLimitWdget* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* /*node*/) { QSignalBlocker signalBlocker(GUI); GUI->SetRotationLimit(instance); GUI->UpdateGui(); return true; } RotationLimitContainerWdget::RotationLimitContainerWdget(QWidget* parent) { QHBoxLayout* hLayout = new QHBoxLayout(this); hLayout->setMargin(2); setLayout(hLayout); QLabel* headerColumn1 = new QLabel("Min angle \xB0", this); layout()->addWidget(headerColumn1); QLabel* headerColumn2 = new QLabel("Max angle \xB0", this); layout()->addWidget(headerColumn2); } QWidget* BlendTreeRotationLimitContainerHandler::CreateGUI(QWidget* parent) { RotationLimitContainerWdget* rotationLimitWdget = aznew RotationLimitContainerWdget(parent); return rotationLimitWdget; } AZ::u32 BlendTreeRotationLimitContainerHandler::GetHandlerName() const { return AZ_CRC("BlendTreeRotationLimitContainerHandler", 0xb2c775fb); } void BlendTreeRotationLimitContainerHandler::ConsumeAttribute(RotationLimitContainerWdget* /*widget*/, AZ::u32 /*attrib*/, AzToolsFramework::PropertyAttributeReader* /*attrValue*/, const char* /*debugName*/) { } void BlendTreeRotationLimitContainerHandler::WriteGUIValuesIntoProperty(size_t /*index*/, RotationLimitContainerWdget* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* /*node*/) { } bool BlendTreeRotationLimitContainerHandler::ReadValuesIntoGUI(size_t /*index*/, RotationLimitContainerWdget* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* /*node*/) { return true; } }