@@ -2268,7 +2268,7 @@ internal static void DoNumberField(RecycledTextEditor editor, Rect position, Rec
2268
2268
{
2269
2269
bool changed;
2270
2270
string allowedCharacters = value.isDouble ? s_AllowedCharactersForFloat : s_AllowedCharactersForInt;
2271
- if (draggable)
2271
+ if (draggable && GUI.enabled )
2272
2272
{
2273
2273
DragNumberValue(dragHotZone, id, ref value, dragSensitivity);
2274
2274
}
@@ -4197,7 +4197,7 @@ public static Vector2 Vector2Field(Rect position, GUIContent label, Vector2 valu
4197
4197
internal static Vector2 Vector2Field(Rect position, GUIContent label, Vector2 value, bool setWideMode)
4198
4198
{
4199
4199
int id = GUIUtility.GetControlID(s_FoldoutHash, FocusType.Keyboard, position);
4200
- position = MultiFieldPrefixLabel(position, id, label, 2, setWideMode);
4200
+ position = MultiFieldPrefixLabel(position, id, label, 2, 0, setWideMode);
4201
4201
position.height = kSingleLineHeight;
4202
4202
return Vector2Field(position, value);
4203
4203
}
@@ -4251,40 +4251,107 @@ private static Vector3 Vector3Field(Rect position, Vector3 value)
4251
4251
return value;
4252
4252
}
4253
4253
4254
- internal static Vector3 LinkedVector3Field(Rect position, GUIContent label, Vector3 value, ref bool linked )
4254
+ internal static Vector3 LinkedVector3Field(Rect position, GUIContent label, Vector3 value, ref bool proportionalScale )
4255
4255
{
4256
- int id = GUIUtility.GetControlID(s_FoldoutHash, FocusType.Keyboard, position);
4257
- position = MultiFieldPrefixLabel(position, id, label, 3);
4256
+ int axisModified = 0;// use X as default modified axis
4257
+ return LinkedVector3Field(position, label, GUIContent.none, value, ref proportionalScale, value, 0, ref axisModified);
4258
+ }
4259
+
4260
+ // Make an X, Y & Z field for entering a [[Vector3]], with a "lock"
4261
+ internal static Vector3 LinkedVector3Field(Rect position, GUIContent label, GUIContent toggleContent, Vector3 value, ref bool proportionalScale, Vector3 initialScale, uint mixedValues, ref int axisModified, SerializedProperty property = null, SerializedProperty proportionalScaleProperty = null)
4262
+ {
4263
+ GUIContent copy = label;
4264
+ Rect fullLabelRect = position;
4265
+ // If SerializedProperty is passed, make sure to call begin and end for property
4266
+
4267
+ // Since we have two separate properties to handle, make sure fields are not overlaping each other
4268
+ // If only localScale property has override, make sure constrainProportionsScale property is in the layer behind
4269
+ if (proportionalScaleProperty != null && property.prefabOverride && !proportionalScale)
4270
+ label = BeginPropertyInternal(fullLabelRect, label, proportionalScaleProperty);
4271
+
4272
+ if (property != null)
4273
+ label = BeginPropertyInternal(position, label, property);
4274
+
4275
+ SerializedProperty copiedProperty = property == null ? property : property.Copy();
4258
4276
var toggle = EditorStyles.toggle.CalcSize(GUIContent.none);
4277
+ int id = GUIUtility.GetControlID(s_FoldoutHash, FocusType.Keyboard, position);
4278
+ position = MultiFieldPrefixLabel(position, id, label, 3, toggle.x + kDefaultSpacing, false);
4259
4279
var toggleRect = position;
4260
4280
toggleRect.width = toggle.x;
4281
+ float toggleOffset = toggleRect.width + kDefaultSpacing;
4282
+ toggleRect.x -= toggleOffset;
4283
+ toggle.x -= toggleOffset;
4261
4284
BeginChangeCheck();
4262
4285
Styles.linkButton.alignment = TextAnchor.MiddleCenter;
4263
- linked = Toggle(toggleRect, linked, Styles.linkButton);
4264
- if (EndChangeCheck() && linked)
4265
- value = Vector3.one * value.x;
4286
+
4287
+ if (proportionalScaleProperty != null)
4288
+ {
4289
+ // If localScale property does not have override, make sure proportionalScale is in front layer
4290
+ if (!property.prefabOverride || proportionalScale)
4291
+ {
4292
+ // If proportional scaling is enabled, make sure to use full scale rect, to be able revert all axis and state at the same time,
4293
+ // otherwise rect size should match label size
4294
+ if (!proportionalScale)
4295
+ fullLabelRect.xMax = toggleRect.xMin;
4296
+
4297
+ label = BeginPropertyInternal(fullLabelRect, label, proportionalScaleProperty);
4298
+ }
4299
+
4300
+ BeginChangeCheck();
4301
+ bool previousProportionalScale = proportionalScale;
4302
+ proportionalScale = GUI.Toggle(toggleRect, proportionalScale, toggleContent, Styles.linkButton);
4303
+ if (previousProportionalScale != proportionalScale)
4304
+ proportionalScaleProperty.boolValue = proportionalScale;
4305
+ EndChangeCheck();
4306
+
4307
+ if (proportionalScale)
4308
+ EndProperty();
4309
+ }
4310
+ else
4311
+ {
4312
+ proportionalScale = GUI.Toggle(toggleRect, proportionalScale, toggleContent, Styles.linkButton);
4313
+ }
4314
+
4266
4315
position.x += toggle.x + kDefaultSpacing;
4267
4316
position.width -= toggle.x + kDefaultSpacing;
4268
4317
position.height = kSingleLineHeight;
4269
- return LinkedVector3Field(position, value, linked);
4318
+
4319
+ var newValue = LinkedVector3Field(position, value, proportionalScale, mixedValues, initialScale, ref axisModified, copiedProperty);
4320
+
4321
+ if (property != null)
4322
+ EndProperty();
4323
+
4324
+ if (proportionalScaleProperty != null && property.prefabOverride && !proportionalScale)
4325
+ EndProperty();
4326
+
4327
+ return newValue;
4328
+ }
4329
+
4330
+ static Vector3 LinkedVector3Field(Rect position, Vector3 value, bool proportionalScale)
4331
+ {
4332
+ int axisModified = 0;// Use X as default modified axis
4333
+ return LinkedVector3Field(position, value, proportionalScale, 0, value, ref axisModified);
4270
4334
}
4271
4335
4272
4336
// Make an X, Y & Z field for entering a [[Vector3]].
4273
- static Vector3 LinkedVector3Field(Rect position, Vector3 value, bool linked )
4337
+ static Vector3 LinkedVector3Field(Rect position, Vector3 value, bool proportionalScale, uint mixedValues, Vector3 initialScale, ref int axisModified, SerializedProperty property = null )
4274
4338
{
4339
+ Vector3 valueAfterChangeCheck = value;
4275
4340
s_Vector3Floats[0] = value.x;
4276
4341
s_Vector3Floats[1] = value.y;
4277
4342
s_Vector3Floats[2] = value.z;
4278
4343
position.height = kSingleLineHeight;
4279
4344
BeginChangeCheck();
4280
- LockingMultiFloatFieldInternal(position, linked, s_XYZLabels, s_Vector3Floats);
4345
+ LockingMultiFloatFieldInternal(position, proportionalScale, mixedValues, s_XYZLabels, s_Vector3Floats, new float[] {initialScale.x, initialScale.y, initialScale.z}, property, EditorGUI.CalcPrefixLabelWidth(s_XYZLabels[0]) + 3 );
4281
4346
if (EndChangeCheck())
4282
4347
{
4283
- value .x = s_Vector3Floats[0];
4284
- value .y = s_Vector3Floats[1];
4285
- value .z = s_Vector3Floats[2];
4348
+ valueAfterChangeCheck .x = s_Vector3Floats[0];
4349
+ valueAfterChangeCheck .y = s_Vector3Floats[1];
4350
+ valueAfterChangeCheck .z = s_Vector3Floats[2];
4286
4351
}
4287
- return value;
4352
+
4353
+ return proportionalScale && valueAfterChangeCheck != value ?
4354
+ ConstrainProportionsTransformScale.DoScaleProportions(valueAfterChangeCheck, value, initialScale, ref axisModified) : valueAfterChangeCheck;
4288
4355
}
4289
4356
4290
4357
// Make an X, Y field - not public (use PropertyField instead)
@@ -4735,6 +4802,11 @@ internal static void MultiFloatFieldInternal(Rect position, GUIContent[] subLabe
4735
4802
}
4736
4803
4737
4804
static void LockingMultiFloatFieldInternal(Rect position, bool locked, GUIContent[] subLabels, float[] values, float prefixLabelWidth = -1)
4805
+ {
4806
+ LockingMultiFloatFieldInternal(position, locked, 0, subLabels, values, null, null, prefixLabelWidth);
4807
+ }
4808
+
4809
+ static void LockingMultiFloatFieldInternal(Rect position, bool locked, uint mixedValues, GUIContent[] subLabels, float[] values, float[] initialValues = null, SerializedProperty property = null, float prefixLabelWidth = -1)
4738
4810
{
4739
4811
int eCount = values.Length;
4740
4812
float w = (position.width - (eCount - 1) * EditorGUI.kSpacingSubLabel) / eCount;
@@ -4743,20 +4815,53 @@ static void LockingMultiFloatFieldInternal(Rect position, bool locked, GUIConten
4743
4815
int l = EditorGUI.indentLevel;
4744
4816
EditorGUI.indentLevel = 0;
4745
4817
var guiEnabledState = GUI.enabled;
4746
- for (int i = 0; i < values.Length; i++)
4818
+ bool hasMixedValues = mixedValues != 0;
4819
+ uint multiselectionLock = ConstrainProportionsTransformScale.GetMultiSelectionLockedFields(property?.serializedObject?.targetObjects);
4820
+
4821
+ if (initialValues == null)
4822
+ initialValues = values;
4823
+
4824
+ bool mixedValueState = EditorGUI.showMixedValue;
4825
+
4826
+ for (int i = 0; i < initialValues.Length; i++)
4747
4827
{
4748
- EditorGUIUtility.labelWidth = GetLabelWidth(subLabels[i], prefixLabelWidth);
4828
+ if (property != null)
4829
+ property.Next(true);
4830
+ EditorGUIUtility.labelWidth = prefixLabelWidth > 0 ? prefixLabelWidth : EditorGUI.CalcPrefixLabelWidth(subLabels[i]);
4749
4831
4750
- if (locked && i > 0 )
4832
+ if (guiEnabledState )
4751
4833
{
4752
- GUI.enabled = false;
4753
- values[i] = values[0];
4834
+ if (locked)
4835
+ {
4836
+ // If initial field value is 0, it must be locked not to break proportions
4837
+ GUI.enabled = !Mathf.Approximately(initialValues[i], 0) && (property != null && property.serializedObject.targetObjectsCount > 1 ? !ConstrainProportionsTransformScale.IsBit(multiselectionLock, i) : true);
4838
+ }
4839
+ else
4840
+ {
4841
+ GUI.enabled = true;
4842
+ }
4843
+ }
4844
+
4845
+ if (hasMixedValues)
4846
+ EditorGUI.showMixedValue = ConstrainProportionsTransformScale.IsBit(mixedValues, i);
4847
+
4848
+ if (property != null)
4849
+ {
4850
+ EditorGUI.PropertyField(nr, property, subLabels[i]);
4851
+ values[i] = property.floatValue;
4754
4852
}
4853
+ else
4854
+ {
4855
+ values[i] = EditorGUI.FloatField(nr, subLabels[i], values[i]);
4856
+ }
4857
+
4858
+ if (hasMixedValues)
4859
+ EditorGUI.showMixedValue = false;
4755
4860
4756
- values[i] = EditorGUI.FloatField(nr, subLabels[i], values[i]);
4757
4861
nr.x += w + EditorGUI.kSpacingSubLabel;
4758
4862
}
4759
4863
GUI.enabled = guiEnabledState;
4864
+ EditorGUI.showMixedValue = mixedValueState;
4760
4865
EditorGUIUtility.labelWidth = t;
4761
4866
EditorGUI.indentLevel = l;
4762
4867
}
@@ -6144,7 +6249,6 @@ internal static void HandlePrefixLabelInternal(Rect totalPosition, Rect labelPos
6144
6249
if (label != null) Highlighter.Handle(totalPosition, label.text);
6145
6250
}
6146
6251
6147
- // DrawTextDebugHelpers (labelPosition);
6148
6252
switch (Event.current.type)
6149
6253
{
6150
6254
case EventType.Repaint:
@@ -6213,10 +6317,10 @@ internal static bool UseVTMaterial(Texture texture)
6213
6317
6214
6318
internal static Rect MultiFieldPrefixLabel(Rect totalPosition, int id, GUIContent label, int columns)
6215
6319
{
6216
- return MultiFieldPrefixLabel(totalPosition, id, label, columns, false);
6320
+ return MultiFieldPrefixLabel(totalPosition, id, label, columns, 0, false);
6217
6321
}
6218
6322
6219
- internal static Rect MultiFieldPrefixLabel(Rect totalPosition, int id, GUIContent label, int columns, bool setWideMode)
6323
+ internal static Rect MultiFieldPrefixLabel(Rect totalPosition, int id, GUIContent label, int columns, float labelWidthIndent, bool setWideMode)
6220
6324
{
6221
6325
if (!LabelHasContent(label))
6222
6326
{
@@ -6225,7 +6329,7 @@ internal static Rect MultiFieldPrefixLabel(Rect totalPosition, int id, GUIConten
6225
6329
6226
6330
if (EditorGUIUtility.wideMode || setWideMode)
6227
6331
{
6228
- Rect labelPosition = new Rect(totalPosition.x + indent, totalPosition.y, EditorGUIUtility.labelWidth - indent, kSingleLineHeight);
6332
+ Rect labelPosition = new Rect(totalPosition.x + indent, totalPosition.y, EditorGUIUtility.labelWidth - indent - labelWidthIndent , kSingleLineHeight);
6229
6333
Rect fieldPosition = totalPosition;
6230
6334
fieldPosition.xMin += EditorGUIUtility.labelWidth + kPrefixPaddingRight;
6231
6335
@@ -9763,11 +9867,19 @@ public static Vector3 Vector3Field(GUIContent label, Vector3 value, params GUILa
9763
9867
return EditorGUI.Vector3Field(r, label, value);
9764
9868
}
9765
9869
9766
- // Make an X, Y & Z field for entering a [[Vector3]], with a "lock" to set all values with just the X field.
9767
- internal static Vector3 LinkedVector3Field(GUIContent label, Vector3 value, ref bool linked, params GUILayoutOption[] options)
9870
+ // Make an X, Y & Z field for entering a [[Vector3]], with a "lock"
9871
+ internal static Vector3 LinkedVector3Field(GUIContent label, Vector3 value, ref bool proportionalScale, params GUILayoutOption[] options)
9872
+ {
9873
+ Rect r = s_LastRect = GetControlRect(true, EditorGUI.GetPropertyHeight(SerializedPropertyType.Vector3, label), EditorStyles.numberField, options);
9874
+ return EditorGUI.LinkedVector3Field(r, label, value, ref proportionalScale);
9875
+ }
9876
+
9877
+ // Make an X, Y & Z field for entering a [[Vector3]], with a "lock"
9878
+ internal static Vector3 LinkedVector3Field(GUIContent label, Vector3 value, Vector3 initialValue, ref bool proportionalScale, params GUILayoutOption[] options)
9768
9879
{
9769
9880
Rect r = s_LastRect = GetControlRect(true, EditorGUI.GetPropertyHeight(SerializedPropertyType.Vector3, label), EditorStyles.numberField, options);
9770
- return EditorGUI.LinkedVector3Field(r, label, value, ref linked);
9881
+ int axisModified = 0;// Use X as default modified axis
9882
+ return EditorGUI.LinkedVector3Field(r, label, GUIContent.none, value, ref proportionalScale, initialValue, 0, ref axisModified, null);
9771
9883
}
9772
9884
9773
9885
// Make an X, Y, Z & W field for entering a [[Vector4]].
0 commit comments