Bug fix for inability to change actor transform properties | #1468
Actor motion extraction applies at all times, sending transform change events to the Qt widget and overwriting any editing the user is doing. (LY-124903)
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include <AzQtComponents/Components/StyleManager.h>
|
||||
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzCore/std/limits.h>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QStyleOptionSpinBox>
|
||||
@@ -38,7 +39,7 @@ VectorElement::VectorElement(QWidget* parent)
|
||||
VectorElement::layout(this, m_spinBox, m_label, false);
|
||||
|
||||
connect(m_spinBox, QOverload<double>::of(&AzQtComponents::DoubleSpinBox::valueChanged), this, &VectorElement::onValueChanged);
|
||||
connect(m_spinBox, &AzQtComponents::DoubleSpinBox::editingFinished, this, &VectorElement::editingFinished);
|
||||
connect(m_spinBox, &AzQtComponents::DoubleSpinBox::editingFinished, this, &VectorElement::onSpinBoxEditingFinished);
|
||||
}
|
||||
|
||||
void VectorElement::SetLabel(const char* label)
|
||||
@@ -60,6 +61,22 @@ const QString& VectorElement::label() const
|
||||
|
||||
void VectorElement::setValue(double newValue)
|
||||
{
|
||||
// Nothing to do if the value is not actually changed
|
||||
if (AZ::IsCloseMag(m_value, newValue, AZStd::numeric_limits<double>::epsilon()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the spin box currently has focus, the user is editing it, so we should not
|
||||
// change the value from non-user input while they're in the middle of editing
|
||||
if (m_spinBox->hasFocus())
|
||||
{
|
||||
auto& deferredValue = m_deferredExternalValue.emplace();
|
||||
deferredValue.value = newValue;
|
||||
deferredValue.prevValue = m_value;
|
||||
return;
|
||||
}
|
||||
|
||||
m_value = newValue;
|
||||
const QSignalBlocker blocker(m_spinBox);
|
||||
m_spinBox->setValue(newValue);
|
||||
@@ -67,6 +84,23 @@ void VectorElement::setValue(double newValue)
|
||||
emit valueChanged(newValue);
|
||||
}
|
||||
|
||||
void VectorElement::onSpinBoxEditingFinished()
|
||||
{
|
||||
if (m_deferredExternalValue)
|
||||
{
|
||||
DeferredSetValue deferredValue = *m_deferredExternalValue;
|
||||
m_deferredExternalValue.reset();
|
||||
|
||||
if (m_value == deferredValue.prevValue)
|
||||
{
|
||||
AZ_Assert(!m_spinBox->hasFocus(), "Editing finished but the spinbox still has focus");
|
||||
setValue(deferredValue.value);
|
||||
}
|
||||
}
|
||||
|
||||
emit editingFinished();
|
||||
}
|
||||
|
||||
void VectorElement::setCoordinate(VectorElement::Coordinate coordinate)
|
||||
{
|
||||
setProperty(g_CoordinatePropertyName, QVariant::fromValue(coordinate));
|
||||
@@ -249,7 +283,7 @@ VectorInput::VectorInput(QWidget* parent, int elementCount, int elementsPerRow,
|
||||
{
|
||||
OnValueChangedInElement(value, elementIndex);
|
||||
});
|
||||
connect(m_elements[elementIndex]->GetSpinBox(), &AzQtComponents::DoubleSpinBox::editingFinished, this, &VectorInput::editingFinished);
|
||||
connect(m_elements[elementIndex], &VectorElement::editingFinished, this, &VectorInput::editingFinished);
|
||||
|
||||
numberOfElementsRemaining--;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzQtComponents/AzQtComponentsAPI.h>
|
||||
#include <AzQtComponents/Components/Widgets/SpinBox.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
#endif
|
||||
|
||||
class QLabel;
|
||||
@@ -18,6 +19,10 @@ namespace AzQtComponents
|
||||
|
||||
class Style;
|
||||
|
||||
// 'AzQtComponents::VectorElement::m_deferredExternalValue': class 'AZStd::optional<AzQtComponents::VectorElement::DeferredSetValue>' needs to
|
||||
// have dll-interface to be used by clients of class 'AzQtComponents::VectorElement'
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
/*!
|
||||
* \class VectorElement
|
||||
* \brief All flexible vector GUI's are constructed using a number vector elements. Each Vector
|
||||
@@ -98,7 +103,15 @@ namespace AzQtComponents
|
||||
|
||||
void resizeLabel();
|
||||
|
||||
void onSpinBoxEditingFinished();
|
||||
|
||||
private:
|
||||
struct DeferredSetValue
|
||||
{
|
||||
double prevValue;
|
||||
double value;
|
||||
};
|
||||
|
||||
// m_labelText must be initialised before m_spinBox. It is used by editFieldRect, which gets
|
||||
// called by the spin box constructor.
|
||||
QString m_labelText = {};
|
||||
@@ -108,8 +121,13 @@ namespace AzQtComponents
|
||||
double m_value = 0.0;
|
||||
//! Indicates whether the value in the spin box has been edited by the user or not
|
||||
bool m_wasValueEditedByUser = false;
|
||||
//! If a value is editing, but not by the user, and the user is currently editing the value,
|
||||
//! avoid overwriting their work, until they finish editing
|
||||
AZStd::optional<DeferredSetValue> m_deferredExternalValue;
|
||||
};
|
||||
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
|
||||
Reference in New Issue
Block a user