升级6.4.升级水,升级天气
This commit is contained in:
@@ -30,7 +30,7 @@ namespace WaveHarmonic.Crest.Attributes
|
||||
/// <summary>
|
||||
/// Override this method to customise the label.
|
||||
/// </summary>
|
||||
internal virtual GUIContent BuildLabel(GUIContent label) => label;
|
||||
internal virtual GUIContent BuildLabel(SerializedProperty property, GUIContent label, DecoratedDrawer drawer) => label;
|
||||
|
||||
/// <summary>
|
||||
/// Override this method to make your own IMGUI based GUI for the property.
|
||||
@@ -55,7 +55,7 @@ namespace WaveHarmonic.Crest.Attributes
|
||||
/// <summary>
|
||||
/// Override this method to customise the label.
|
||||
/// </summary>
|
||||
internal virtual GUIContent BuildLabel(GUIContent label) => label;
|
||||
internal virtual GUIContent BuildLabel(SerializedProperty property, GUIContent label, DecoratedDrawer drawer) => label;
|
||||
|
||||
/// <summary>
|
||||
/// Override this method to additively change the appearance of a decorated field.
|
||||
@@ -83,6 +83,37 @@ namespace WaveHarmonic.Crest.Attributes
|
||||
|
||||
namespace WaveHarmonic.Crest
|
||||
{
|
||||
sealed class CustomField : DecoratedProperty
|
||||
{
|
||||
internal override void OnGUI(Rect position, SerializedProperty property, GUIContent label, DecoratedDrawer drawer)
|
||||
{
|
||||
if (drawer._Inspector == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
drawer._Inspector.OnCustomField(position, property, label, drawer);
|
||||
}
|
||||
}
|
||||
|
||||
sealed class CustomLabel : Decorator
|
||||
{
|
||||
public override bool AlwaysVisible => false;
|
||||
|
||||
internal override GUIContent BuildLabel(SerializedProperty property, GUIContent label, DecoratedDrawer drawer)
|
||||
{
|
||||
label = base.BuildLabel(property, label, drawer);
|
||||
if (drawer._Inspector == null) return label;
|
||||
label = drawer._Inspector.OnCustomLabel(property, label, drawer);
|
||||
return label;
|
||||
}
|
||||
|
||||
internal override void Decorate(Rect position, SerializedProperty property, GUIContent label, DecoratedDrawer drawer)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the property using EditorGUI.PropertyField.
|
||||
/// </summary>
|
||||
@@ -142,11 +173,48 @@ namespace WaveHarmonic.Crest
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sealed class Order : Decorator
|
||||
{
|
||||
public override bool AlwaysVisible => true;
|
||||
|
||||
public readonly string _Target;
|
||||
public readonly Placement _Placement;
|
||||
|
||||
public enum Placement
|
||||
{
|
||||
Heading,
|
||||
Below,
|
||||
Above,
|
||||
}
|
||||
|
||||
public Order(string target, Placement placement = Placement.Heading)
|
||||
{
|
||||
_Target = target;
|
||||
_Placement = placement;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders foldout without the foldout.
|
||||
/// </summary>
|
||||
sealed class Stripped : DecoratedProperty
|
||||
{
|
||||
public enum Style
|
||||
{
|
||||
None,
|
||||
PlatformTab,
|
||||
}
|
||||
|
||||
readonly bool _KeepIndent;
|
||||
readonly Style _Style;
|
||||
|
||||
public Stripped(Style style = Style.None, bool indent = false)
|
||||
{
|
||||
_KeepIndent = indent;
|
||||
_Style = style;
|
||||
}
|
||||
|
||||
internal override bool NeedsControlRectangle(SerializedProperty property) => false;
|
||||
|
||||
internal override void OnGUI(Rect position, SerializedProperty property, GUIContent label, DecoratedDrawer drawer)
|
||||
@@ -155,11 +223,33 @@ namespace WaveHarmonic.Crest
|
||||
DecoratedDrawer.s_TemporaryColor = true;
|
||||
DecoratedDrawer.s_PreviousColor = GUI.color;
|
||||
|
||||
if (_Style == Style.PlatformTab)
|
||||
{
|
||||
EditorGUI.indentLevel += 1;
|
||||
EditorGUILayout.LabelField(label);
|
||||
EditorGUI.indentLevel -= 1;
|
||||
}
|
||||
|
||||
GUI.color = new(0, 0, 0, 0);
|
||||
|
||||
EditorGUI.indentLevel -= 1;
|
||||
if (!_KeepIndent) EditorGUI.indentLevel -= 1;
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
EditorGUI.indentLevel += 1;
|
||||
if (!_KeepIndent) EditorGUI.indentLevel += 1;
|
||||
|
||||
if (_Style == Style.PlatformTab)
|
||||
{
|
||||
EditorGUILayout.Space(4);
|
||||
EditorGUILayout.EndBuildTargetSelectionGrouping();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class PlatformTabs : DecoratedProperty
|
||||
{
|
||||
static readonly GUIContent s_DefaultTab = new(EditorGUIUtility.IconContent("d_Settings").image, "Default");
|
||||
internal override void OnGUI(Rect position, SerializedProperty property, GUIContent label, DecoratedDrawer drawer)
|
||||
{
|
||||
property.intValue = Editor.Reflected.EditorGUILayout.BeginBuildTargetSelectionGrouping(s_DefaultTab);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,7 +460,7 @@ namespace WaveHarmonic.Crest
|
||||
property.floatValue = Mathf.Max(_Minimum, property.floatValue);
|
||||
break;
|
||||
case SerializedPropertyType.Integer:
|
||||
property.floatValue = Mathf.Max((int)_Minimum, property.intValue);
|
||||
property.intValue = Mathf.Max((int)_Minimum, property.intValue);
|
||||
break;
|
||||
case SerializedPropertyType.Vector2:
|
||||
var vector2Value = property.vector2Value;
|
||||
@@ -621,29 +711,15 @@ namespace WaveHarmonic.Crest
|
||||
|
||||
sealed class InlineToggle : DecoratedProperty
|
||||
{
|
||||
// Add extra y offset. Needed for foldouts in foldouts so far.
|
||||
readonly bool _Fix;
|
||||
|
||||
public InlineToggle(bool fix = false)
|
||||
{
|
||||
_Fix = fix;
|
||||
}
|
||||
|
||||
internal override bool NeedsControlRectangle(SerializedProperty property)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
internal override void OnGUI(Rect position, SerializedProperty property, GUIContent label, DecoratedDrawer drawer)
|
||||
{
|
||||
var r = position;
|
||||
r.x -= 16f;
|
||||
// Align with Space offset.
|
||||
if (drawer.Space > 0) r.y += drawer.Space + 2f;
|
||||
if (_Fix) r.y += EditorGUIUtility.singleLineHeight + 2f;
|
||||
// Seems to be needed.
|
||||
|
||||
// Prevent click events blocking next property.
|
||||
r.width = 16f * (1f + EditorGUI.indentLevel);
|
||||
r.height = EditorGUIUtility.singleLineHeight;
|
||||
|
||||
// Hide text.
|
||||
label.text = "";
|
||||
|
||||
using (new EditorGUI.PropertyScope(r, label, property))
|
||||
@@ -654,6 +730,9 @@ namespace WaveHarmonic.Crest
|
||||
property.boolValue = EditorGUI.Toggle(r, property.boolValue);
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
|
||||
// Pull up next property. Extra space might be margin/padding.
|
||||
GUILayout.Space(-(EditorGUIUtility.singleLineHeight + 2f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -859,9 +938,9 @@ namespace WaveHarmonic.Crest
|
||||
_Label = label;
|
||||
}
|
||||
|
||||
internal override GUIContent BuildLabel(GUIContent label)
|
||||
internal override GUIContent BuildLabel(SerializedProperty property, GUIContent label, DecoratedDrawer drawer)
|
||||
{
|
||||
label = base.BuildLabel(label);
|
||||
label = base.BuildLabel(property, label, drawer);
|
||||
label.text = _Label;
|
||||
return label;
|
||||
}
|
||||
@@ -877,7 +956,7 @@ namespace WaveHarmonic.Crest
|
||||
/// </summary>
|
||||
sealed class Heading : Decorator
|
||||
{
|
||||
readonly GUIContent _Text;
|
||||
public readonly GUIContent _Text;
|
||||
readonly string _HelpLink;
|
||||
readonly Style _Style;
|
||||
readonly bool _AlwaysVisible;
|
||||
|
||||
@@ -23,6 +23,12 @@ namespace WaveHarmonic.Crest
|
||||
|
||||
internal override void OnGUI(Rect position, SerializedProperty property, GUIContent label, DecoratedDrawer drawer)
|
||||
{
|
||||
if (drawer._Inspector != null && !drawer._Inspector._EmbeddedEditors.Contains(_Editor))
|
||||
{
|
||||
drawer._Inspector._EmbeddedEditors.Add(_Editor);
|
||||
Inspector.s_EmbeddedEditors.Add(_Editor);
|
||||
}
|
||||
|
||||
_Editor.DrawEditorCombo(this, label, drawer, property, "asset");
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ using WaveHarmonic.Crest.Editor;
|
||||
|
||||
namespace WaveHarmonic.Crest
|
||||
{
|
||||
sealed class Predicated : Decorator
|
||||
abstract class Predicated : Decorator
|
||||
{
|
||||
enum Mode
|
||||
{
|
||||
@@ -24,6 +24,7 @@ namespace WaveHarmonic.Crest
|
||||
|
||||
readonly bool _Inverted;
|
||||
readonly bool _Hide;
|
||||
readonly bool _Implicit;
|
||||
|
||||
readonly string _PropertyName;
|
||||
readonly object _DisableValue;
|
||||
@@ -38,16 +39,16 @@ namespace WaveHarmonic.Crest
|
||||
/// </summary>
|
||||
/// <param name="type">The type to call the method on. Must be either a static type or the type the field is defined on.</param>
|
||||
/// <param name="member">Member name. Method must match signature: bool MethodName(Component component). Can be any visibility and static or instance.</param>
|
||||
/// <param name="disableValue"></param>
|
||||
/// <param name="value">Disable/Hide if matches this value.</param>
|
||||
/// <param name="inverted">Flip behaviour - for example disable if a bool field is set to true (instead of false).</param>
|
||||
/// <param name="hide">Hide this component in the inspector.</param>
|
||||
public Predicated(Type type, string member, object disableValue, bool inverted = false, bool hide = false)
|
||||
public Predicated(Type type, string member, object value, bool inverted = false, bool hide = false)
|
||||
{
|
||||
_Mode = Mode.Member;
|
||||
_Inverted = inverted;
|
||||
_Hide = hide;
|
||||
_Type = type;
|
||||
_DisableValue = disableValue;
|
||||
_DisableValue = value;
|
||||
_Member = _Type.GetMember(member, Helpers.s_AnyMethod)[0];
|
||||
}
|
||||
|
||||
@@ -71,21 +72,30 @@ namespace WaveHarmonic.Crest
|
||||
_Type = type;
|
||||
}
|
||||
|
||||
public Predicated(string property, bool inverted = false, bool hide = false)
|
||||
{
|
||||
_Mode = Mode.Property;
|
||||
_Inverted = inverted;
|
||||
_Hide = hide;
|
||||
_PropertyName = property;
|
||||
_Implicit = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The field with this attribute will be drawn enabled/disabled based on another field. For example can be used
|
||||
/// to disable a field if a toggle is false.
|
||||
/// </summary>
|
||||
/// <param name="property">The name of the other property whose value dictates whether this field is enabled or not.</param>
|
||||
/// <param name="inverted">Flip behaviour - for example disable if a bool field is set to true (instead of false).</param>
|
||||
/// <param name="disableValue">If the field has this value, disable the GUI (or enable if inverted is true).</param>
|
||||
/// <param name="value">If the field has this value, disable the GUI (or enable if inverted is true).</param>
|
||||
/// <param name="hide">Hide this component in the inspector.</param>
|
||||
public Predicated(string property, bool inverted = false, object disableValue = null, bool hide = false)
|
||||
public Predicated(string property, object value, bool inverted = false, bool hide = false)
|
||||
{
|
||||
_Mode = Mode.Property;
|
||||
_Inverted = inverted;
|
||||
_Hide = hide;
|
||||
_PropertyName = property;
|
||||
_DisableValue = disableValue;
|
||||
_DisableValue = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -106,18 +116,24 @@ namespace WaveHarmonic.Crest
|
||||
|
||||
public bool GUIEnabled(SerializedProperty property)
|
||||
{
|
||||
if (_Implicit && property.propertyType is not SerializedPropertyType.Boolean and not SerializedPropertyType.ObjectReference and not SerializedPropertyType.ManagedReference)
|
||||
{
|
||||
Debug.Log($"Crest.Predicated: Implicit predicated on {property.name} cannot be used for {property.propertyType}.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return _Inverted != property.propertyType switch
|
||||
{
|
||||
// Enable GUI if int value of field is not equal to 0, or whatever the disable-value is set to
|
||||
SerializedPropertyType.Integer => property.intValue != ((int?)_DisableValue ?? 0),
|
||||
// Enable GUI if disable-value is 0 and field is true, or disable-value is not 0 and field is false
|
||||
SerializedPropertyType.Boolean => property.boolValue ^ (((int?)_DisableValue ?? 0) != 0),
|
||||
SerializedPropertyType.Boolean => _Implicit ? !property.boolValue : (bool)_DisableValue == property.boolValue,
|
||||
SerializedPropertyType.Float => property.floatValue != ((float?)_DisableValue ?? 0),
|
||||
SerializedPropertyType.String => property.stringValue != ((string)_DisableValue ?? ""),
|
||||
// Must pass nameof enum entry as we are comparing names because index != value.
|
||||
SerializedPropertyType.Enum => property.enumNames[property.enumValueIndex] != ((string)_DisableValue ?? ""),
|
||||
SerializedPropertyType.ObjectReference => property.objectReferenceValue != null,
|
||||
SerializedPropertyType.ManagedReference => property.managedReferenceValue != null,
|
||||
SerializedPropertyType.ObjectReference => _Implicit ? property.objectReferenceValue == null : property.objectReferenceValue != null,
|
||||
SerializedPropertyType.ManagedReference => _Implicit ? property.managedReferenceValue == null : property.managedReferenceValue != null,
|
||||
_ => throw new ArgumentException($"Crest.Predicated: property type on <i>{property.serializedObject.targetObject}</i> not implemented yet: {property.propertyType}."),
|
||||
};
|
||||
}
|
||||
@@ -201,12 +217,12 @@ namespace WaveHarmonic.Crest
|
||||
}
|
||||
|
||||
var enabledByTypeCheck = _Type.IsAssignableFrom(type);
|
||||
if (_Inverted) enabledByTypeCheck = !enabledByTypeCheck;
|
||||
if (!_Inverted) enabledByTypeCheck = !enabledByTypeCheck;
|
||||
enabled = enabledByTypeCheck && enabled;
|
||||
}
|
||||
else if (_Mode == Mode.RenderPipeline)
|
||||
{
|
||||
enabled = RenderPipelineHelper.RenderPipeline == _RenderPipeline != _Inverted;
|
||||
enabled = RenderPipelineHelper.RenderPipeline == _RenderPipeline == _Inverted;
|
||||
}
|
||||
|
||||
// Keep current disabled state.
|
||||
@@ -216,4 +232,228 @@ namespace WaveHarmonic.Crest
|
||||
DecoratedDrawer.s_HideInInspector = DecoratedDrawer.s_HideInInspector || (_Hide && !enabled);
|
||||
}
|
||||
}
|
||||
|
||||
sealed class Show : Predicated
|
||||
{
|
||||
const bool k_Hide = true;
|
||||
const bool k_Inverted = true;
|
||||
|
||||
/// <summary>
|
||||
/// Show this field if member's (method) returned value matches provided.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="Predicated(Type, string, object, bool, bool)"/>
|
||||
public Show(Type type, string member, object value) : base(type, member, value, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show this field if member (method) returns true.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="Predicated(Type, string, bool, bool)"/>
|
||||
public Show(Type type, string member) : this(type, member, value: true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show field if owning class is of type.
|
||||
/// </summary>
|
||||
public Show(Type type) : base(type, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show if field is null or false if reference or boolean respectively.
|
||||
/// </summary>
|
||||
public Show(string property) : base(property, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show if field matches value.
|
||||
/// </summary>
|
||||
public Show(string property, object value) : base(property, value, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show if current render pipeline matches.
|
||||
/// </summary>
|
||||
public Show(RenderPipeline rp) : base(rp, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sealed class Hide : Predicated
|
||||
{
|
||||
const bool k_Hide = true;
|
||||
const bool k_Inverted = false;
|
||||
|
||||
/// <summary>
|
||||
/// Hide this field if member's (method) returned value matches provided.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="Predicated(Type, string, object, bool, bool)"/>
|
||||
public Hide(Type type, string member, object value) : base(type, member, value, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hide this field if member (method) returns true.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="Predicated(Type, string, bool, bool)"/>
|
||||
public Hide(Type type, string member) : this(type, member, value: true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hide field if owning class is of type.
|
||||
/// </summary>
|
||||
public Hide(Type type) : base(type, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hide if field is null or false if reference or boolean respectively.
|
||||
/// </summary>
|
||||
public Hide(string property) : base(property, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hide if field matches value.
|
||||
/// </summary>
|
||||
public Hide(string property, object value) : base(property, value, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hide if current render pipeline matches.
|
||||
/// </summary>
|
||||
public Hide(RenderPipeline rp) : base(rp, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sealed class Enable : Predicated
|
||||
{
|
||||
const bool k_Hide = false;
|
||||
const bool k_Inverted = true;
|
||||
|
||||
/// <summary>
|
||||
/// Enable this field if member's (method) returned value matches provided.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="Predicated(Type, string, object, bool, bool)"/>
|
||||
public Enable(Type type, string member, object value) : base(type, member, value, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable this field if member (method) returns true.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="Predicated(Type, string, bool, bool)"/>
|
||||
public Enable(Type type, string member) : this(type, member, value: true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable field if owning class is of type.
|
||||
/// </summary>
|
||||
public Enable(Type type) : base(type, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable if field is null or false if reference or boolean respectively.
|
||||
/// </summary>
|
||||
public Enable(string property) : base(property, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable if field matches value.
|
||||
/// </summary>
|
||||
public Enable(string property, object value) : base(property, value, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable if current render pipeline matches.
|
||||
/// </summary>
|
||||
public Enable(RenderPipeline rp) : base(rp, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sealed class Disable : Predicated
|
||||
{
|
||||
const bool k_Hide = false;
|
||||
const bool k_Inverted = false;
|
||||
|
||||
/// <summary>
|
||||
/// Disable this field if member's (method) returned value matches provided.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="Predicated(Type, string, object, bool, bool)"/>
|
||||
public Disable(Type type, string member, object value) : base(type, member, value, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disable this field if member (method) returns true.
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="Predicated(Type, string, bool, bool)"/>
|
||||
public Disable(Type type, string member) : this(type, member, value: true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disable field if owning class is of type.
|
||||
/// </summary>
|
||||
public Disable(Type type) : base(type, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disable if field is null or false if reference or boolean respectively.
|
||||
/// </summary>
|
||||
public Disable(string property) : base(property, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disable if field matches value.
|
||||
/// </summary>
|
||||
public Disable(string property, object value) : base(property, value, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disable if current render pipeline matches.
|
||||
/// </summary>
|
||||
public Disable(RenderPipeline rp) : base(rp, k_Inverted, k_Hide)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user