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:
Danilo Aimini
2021-06-24 14:02:49 -07:00
committed by GitHub
2 changed files with 54 additions and 2 deletions
@@ -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
//////////////////////////////////////////////////////////////////////////
/*!