@@ -479,9 +479,21 @@ internal class RecycledTextEditor : TextEditor
479479 {
480480 internal static bool s_ActuallyEditing = false; // internal so we can save this state.
481481 internal static bool s_AllowContextCutOrPaste = true; // e.g. selectable labels only allow for copying
482+ private long[] s_OriginalLongValues;
483+ private double[] s_OriginalDoubleValues;
482484
483485 IMECompositionMode m_IMECompositionModeBackup;
484486
487+ public long[] GetOriginalLongValues()
488+ {
489+ return s_OriginalLongValues;
490+ }
491+
492+ public double[] GetOriginalDoubleValues()
493+ {
494+ return s_OriginalDoubleValues;
495+ }
496+
485497 internal bool IsEditingControl(int id)
486498 {
487499 return GUIUtility.keyboardControl == id && controlID == id && s_ActuallyEditing && GUIView.current.hasFocus;
@@ -509,6 +521,29 @@ public virtual void BeginEditing(int id, string newText, Rect _position, GUIStyl
509521
510522 m_IMECompositionModeBackup = Input.imeCompositionMode;
511523 Input.imeCompositionMode = IMECompositionMode.On;
524+
525+ if (EditorGUI.s_PropertyStack.Count > 0)
526+ {
527+ var property = EditorGUI.s_PropertyStack.Peek().property;
528+
529+ switch (property.propertyType)
530+ {
531+ case SerializedPropertyType.Integer:
532+ s_OriginalLongValues = new long[property.serializedObject.targetObjectsCount];
533+ property.allLongValues.CopyTo(s_OriginalLongValues, 0);
534+ break;
535+
536+ case SerializedPropertyType.Float:
537+ s_OriginalDoubleValues = new double[property.serializedObject.targetObjectsCount];
538+ property.allDoubleValues.CopyTo(s_OriginalDoubleValues, 0);
539+ break;
540+
541+ default:
542+ s_OriginalDoubleValues = null;
543+ s_OriginalLongValues = null;
544+ break;
545+ }
546+ }
512547 }
513548
514549 public virtual void EndEditing()
@@ -1189,6 +1224,17 @@ internal static string DoTextField(RecycledTextEditor editor, int id, Rect posit
11891224 s_OriginalText = "";
11901225 }
11911226
1227+ if (s_PropertyStack.Count > 0)
1228+ {
1229+ if (s_RecycledEditor.GetOriginalDoubleValues() != null)
1230+ s_PropertyStack.Peek().property.allDoubleValues =
1231+ s_RecycledEditor.GetOriginalDoubleValues();
1232+
1233+ if (s_RecycledEditor.GetOriginalLongValues() != null)
1234+ s_PropertyStack.Peek().property.allLongValues =
1235+ s_RecycledEditor.GetOriginalLongValues();
1236+ }
1237+
11921238 editor.text = s_OriginalText;
11931239
11941240 editor.EndEditing();
@@ -2345,6 +2391,60 @@ internal static void DoNumberField(RecycledTextEditor editor, Rect position, Rec
23452391 }
23462392 }
23472393
2394+ internal static void StringToNumericValue(in string str, ref NumberFieldValue value)
2395+ {
2396+ if (value.isDouble)
2397+ StringToDouble(str, ref value);
2398+ else
2399+ StringToLong(str, ref value);
2400+ }
2401+
2402+ internal static void EvaluateExpressionOnNumberFieldValue(ref NumberFieldValue value)
2403+ {
2404+ if (value.isDouble)
2405+ value.success = value.expression.Evaluate(ref value.doubleVal);
2406+ else
2407+ value.success = value.expression.Evaluate(ref value.longVal);
2408+ }
2409+
2410+ internal static void GetInitialValue(ref NumberFieldValue value)
2411+ {
2412+ if (value.isDouble)
2413+ {
2414+ double oldValue = default;
2415+ if (UINumericFieldsUtils.StringToDouble(s_OriginalText, out oldValue) && oldValue != value.doubleVal)
2416+ {
2417+ value.doubleVal = oldValue;
2418+ return;
2419+ }
2420+ }
2421+ else
2422+ {
2423+ long oldValue = default;
2424+ if (UINumericFieldsUtils.StringToLong(s_OriginalText, out oldValue) && oldValue != value.longVal)
2425+ {
2426+ value.longVal = oldValue;
2427+ return;
2428+ }
2429+ }
2430+ }
2431+
2432+ internal static void UpdateNumberValueIfNeeded(ref NumberFieldValue value, in string str)
2433+ {
2434+ StringToNumericValue(str, ref value);
2435+
2436+ if (!value.success && value.expression != null)
2437+ {
2438+ using (s_EvalExpressionMarker.Auto())
2439+ {
2440+ GetInitialValue(ref value);
2441+
2442+ EvaluateExpressionOnNumberFieldValue(ref value);
2443+ }
2444+ }
2445+
2446+ GUI.changed = value.success || value.expression != null;
2447+ }
23482448 internal static void DoNumberField(RecycledTextEditor editor, Rect position, Rect dragHotZone, int id,
23492449 ref NumberFieldValue value, string formatString, GUIStyle style, bool draggable,
23502450 double dragSensitivity)
@@ -2378,25 +2478,14 @@ internal static void DoNumberField(RecycledTextEditor editor, Rect position, Rec
23782478 str = value.isDouble ? value.doubleVal.ToString(formatString, CultureInfo.InvariantCulture) : value.longVal.ToString(formatString, CultureInfo.InvariantCulture);
23792479 }
23802480
2381- if (GUIUtility.keyboardControl == id)
2382- {
2383- str = DoTextField(editor, id, position, str, style, allowedCharacters, out changed, false, false, false);
2481+ str = DoTextField(editor, id, position, str, style, allowedCharacters, out changed, false, false, false);
23842482
2483+ if (GUIUtility.keyboardControl == id && changed)
2484+ {
23852485 // If we are still actively editing, return the input values
2386- if (changed)
2387- {
2388- GUI.changed = true;
2389- s_RecycledCurrentEditingString = str;
2486+ s_RecycledCurrentEditingString = str;
23902487
2391- if (value.isDouble)
2392- StringToDouble(str, ref value);
2393- else
2394- StringToLong(str, ref value);
2395- }
2396- }
2397- else
2398- {
2399- DoTextField(editor, id, position, str, style, allowedCharacters, out changed, false, false, false);
2488+ UpdateNumberValueIfNeeded(ref value, str);
24002489 }
24012490 }
24022491
@@ -2622,11 +2711,7 @@ static void DelayedNumberFieldInternal(Rect position, Rect dragHotZone, int id,
26222711 }
26232712 else
26242713 {
2625- GUI.changed = true;
2626- if (value.isDouble)
2627- StringToDouble(str, ref value);
2628- else
2629- StringToLong(str, ref value);
2714+ UpdateNumberValueIfNeeded(ref value, str);
26302715 }
26312716 GUI.changed |= wasChanged;
26322717 }
@@ -6581,7 +6666,7 @@ internal static GUIContent BeginPropertyInternal(Rect totalPosition, GUIContent
65816666 Highlighter.HighlightIdentifier(totalPosition, property.propertyPath);
65826667
65836668 s_PropertyFieldTempContent.text = (label == null) ? property.localizedDisplayName : label.text; // no necessary to be translated.
6584- s_PropertyFieldTempContent.tooltip = (label == null) ? property.tooltip : label.tooltip;
6669+ s_PropertyFieldTempContent.tooltip = (label == null || string.IsNullOrEmpty(label.tooltip) ) ? property.tooltip : label.tooltip;
65856670 s_PropertyFieldTempContent.image = label?.image;
65866671
65876672 // In inspector debug mode & when holding down alt. Show the property path of the property.
@@ -7265,9 +7350,14 @@ internal static bool DefaultPropertyField(Rect position, SerializedProperty prop
72657350 {
72667351 using (s_EvalExpressionMarker.Auto())
72677352 {
7353+ var originalValues = s_RecycledEditor.GetOriginalLongValues();
7354+
72687355 var values = property.allLongValues;
72697356 for (var i = 0; i < values.Length; ++i)
7357+ {
7358+ values[i] = originalValues[i];
72707359 val.expression.Evaluate(ref values[i], i, values.Length);
7360+ }
72717361 property.allLongValues = values;
72727362 }
72737363 }
@@ -7296,14 +7386,24 @@ internal static bool DefaultPropertyField(Rect position, SerializedProperty prop
72967386 {
72977387 using (s_EvalExpressionMarker.Auto())
72987388 {
7389+ var originalValues = s_RecycledEditor.GetOriginalDoubleValues();
7390+
72997391 var values = property.allDoubleValues;
7392+ bool changed = false;
73007393 for (var i = 0; i < values.Length; ++i)
73017394 {
7302- val.expression.Evaluate(ref values[i], i, values.Length);
7303- if (isFloat)
7304- values[i] = MathUtils.ClampToFloat(values[i]);
7395+ values[i] = originalValues[i];
7396+ if (val.expression.Evaluate(ref values[i], i, values.Length))
7397+ {
7398+ if (isFloat)
7399+ values[i] = MathUtils.ClampToFloat(values[i]);
7400+
7401+ changed = true;
7402+ }
73057403 }
7306- property.allDoubleValues = values;
7404+
7405+ if (changed)
7406+ property.allDoubleValues = values;
73077407 }
73087408 }
73097409 else
0 commit comments