Bug fix for inability to change actor transform properties.

Actor motion extraction applies at all times, sending transform change events to the Qt widget and overwriting any editing the user is doing.

If the user is in the middle of editing, do not overwrite the current spinbox value.
This commit is contained in:
Yuriy Toporovskyy
2021-06-21 18:00:38 -04:00
parent ca76a4d1ab
commit f1d2d380fa
2 changed files with 54 additions and 2 deletions
@@ -43,7 +43,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)
@@ -65,6 +65,22 @@ const QString& VectorElement::label() const
void VectorElement::setValue(double newValue)
{
// Nothing to do if the value is not actually changed
if (AZ::IsClose(m_value, newValue, std::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);
@@ -72,6 +88,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_Warning("VectorElement", !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));
@@ -254,7 +287,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--;
}
@@ -14,6 +14,7 @@
#if !defined(Q_MOC_RUN)
#include <AzQtComponents/AzQtComponentsAPI.h>
#include <AzQtComponents/Components/Widgets/SpinBox.h>
#include <AzCore/std/optional.h>
#endif
class QLabel;
@@ -23,6 +24,12 @@ namespace AzQtComponents
class Style;
#pragma warning(push)
// 'AzQtComponents::VectorElement::m_deferredExternalValue': class 'AZStd::optional<AzQtComponents::VectorElement::DeferredSetValue>' needs to
// have dll-interface to be used by clients of class 'AzQtComponents::VectorElement'
#pragma warning(disable:4251)
/*!
* \class VectorElement
* \brief All flexible vector GUI's are constructed using a number vector elements. Each Vector
@@ -103,7 +110,14 @@ namespace AzQtComponents
void resizeLabel();
void onSpinBoxEditingFinished();
private:
struct DeferredSetValue
{
double prevValue, 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 = {};
@@ -113,8 +127,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;
};
#pragma warning(pop)
//////////////////////////////////////////////////////////////////////////
/*!