添加表格的强制样式更新。
优化样式状态集,添加了样式集基于默认值的默认样式路径。 优化样式表按钮等组件的刷新功能。
This commit is contained in:
@@ -1,203 +1,220 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
using XericLibrary.Runtime.SuperStyleSheet;
|
||||
using XericUI.Core.StyleSheetUI;
|
||||
using XericUI.Helper;
|
||||
|
||||
namespace XericUI.OverrideUI
|
||||
{
|
||||
/// <summary>
|
||||
/// 基于 SuperStyleSheet 的按钮组件。
|
||||
/// 通过两个独立的 StyleSheetState 实例分别管理颜色和纹理的五态样式切换,
|
||||
/// 替代 Unity 内置的 ColorBlock 和 SpriteState。
|
||||
/// </summary>
|
||||
[AddComponentMenu("Xeric UI Vessel/UI/Style Button", 51)]
|
||||
public class XericStyleButton : Button, IStyleRefreshable
|
||||
{
|
||||
#region 序列化字段
|
||||
/// <summary>
|
||||
/// 基于 SuperStyleSheet 的按钮组件。
|
||||
/// 通过 TransitionMode 选择颜色切换、纹理切换或两者并用,
|
||||
/// 替代 Unity 内置的 ColorBlock 和 SpriteState。
|
||||
/// </summary>
|
||||
[AddComponentMenu("Xeric UI Vessel/UI/Style Button", 51)]
|
||||
public class XericStyleButton : Button, IStyleRefreshable
|
||||
{
|
||||
/// <summary>样式过渡模式</summary>
|
||||
public enum TransitionMode
|
||||
{
|
||||
/// <summary>仅颜色切换</summary>
|
||||
Color,
|
||||
/// <summary>仅纹理/Sprite 切换</summary>
|
||||
Sprite,
|
||||
/// <summary>颜色 + 纹理切换</summary>
|
||||
ColorAndSprite
|
||||
}
|
||||
|
||||
[Header("样式表状态")]
|
||||
[SerializeField]
|
||||
[Tooltip("五态颜色样式块")]
|
||||
#region 序列化字段
|
||||
|
||||
[Header("过渡模式")]
|
||||
[SerializeField]
|
||||
[Tooltip("选择颜色 / 纹理 / 同时切换")]
|
||||
private TransitionMode m_TransitionMode = TransitionMode.ColorAndSprite;
|
||||
|
||||
[Header("样式表状态")] [SerializeField]
|
||||
[Tooltip("五态颜色样式块(ColorTint)")]
|
||||
private StyleSheetState m_ColorState = StyleSheetState.Default;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("五态纹理样式块")]
|
||||
private StyleSheetState m_TextureState = StyleSheetState.Default;
|
||||
[Tooltip("五态纹理样式块(SpriteState)")]
|
||||
private StyleSheetState m_TextureState = StyleSheetState.CreateTexture();
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("启用样式表驱动过渡(关闭则回退为 Unity ColorBlock)")]
|
||||
private bool m_EnableStyleTransition = true;
|
||||
[SerializeField] [Tooltip("启用样式表驱动过渡(关闭则回退为 Unity ColorBlock)")]
|
||||
private bool m_EnableStyleTransition = true;
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region 运行时
|
||||
#region 运行时
|
||||
|
||||
[System.NonSerialized] private StyleSheetSelectionState m_CurrentState = StyleSheetSelectionState.Normal;
|
||||
[System.NonSerialized] private Graphic m_TargetGraphic;
|
||||
[System.NonSerialized] private Image m_TargetImage;
|
||||
[System.NonSerialized] private StyleSheetSelectionState m_CurrentState = StyleSheetSelectionState.Normal;
|
||||
[System.NonSerialized] private Graphic m_TargetGraphic;
|
||||
[System.NonSerialized] private Image m_TargetImage;
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region 生命周期
|
||||
#region 生命周期
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
m_TargetGraphic = targetGraphic;
|
||||
m_TargetImage = m_TargetGraphic as Image;
|
||||
}
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
m_TargetGraphic = targetGraphic;
|
||||
m_TargetImage = m_TargetGraphic as Image;
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
|
||||
RevalidateStyles();
|
||||
RevalidateStyles();
|
||||
|
||||
StyleRefreshManager.Register(this);
|
||||
ApplyForState(m_CurrentState);
|
||||
}
|
||||
StyleRefreshManager.Register(this);
|
||||
ApplyForState(m_CurrentState);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate()
|
||||
{
|
||||
base.OnValidate();
|
||||
RevalidateStyles();
|
||||
ApplyForState(m_CurrentState);
|
||||
}
|
||||
protected override void OnValidate()
|
||||
{
|
||||
base.OnValidate();
|
||||
RevalidateStyles();
|
||||
ApplyForState(m_CurrentState);
|
||||
}
|
||||
#endif
|
||||
|
||||
private void RevalidateStyles()
|
||||
{
|
||||
m_ColorState?.UnsubscribeAll(OnStyleChanged);
|
||||
m_TextureState?.UnsubscribeAll(OnStyleChanged);
|
||||
private void RevalidateStyles()
|
||||
{
|
||||
m_ColorState?.UnsubscribeAll(OnStyleChanged);
|
||||
m_TextureState?.UnsubscribeAll(OnStyleChanged);
|
||||
|
||||
m_ColorState?.RegisterAll();
|
||||
m_TextureState?.RegisterAll();
|
||||
m_ColorState?.SubscribeAll(OnStyleChanged);
|
||||
m_TextureState?.SubscribeAll(OnStyleChanged);
|
||||
}
|
||||
m_ColorState?.RegisterAll();
|
||||
m_TextureState?.RegisterAll();
|
||||
m_ColorState?.SubscribeAll(OnStyleChanged);
|
||||
m_TextureState?.SubscribeAll(OnStyleChanged);
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
StyleRefreshManager.Unregister(this);
|
||||
protected override void OnDisable()
|
||||
{
|
||||
StyleRefreshManager.Unregister(this);
|
||||
|
||||
m_ColorState?.UnsubscribeAll(OnStyleChanged);
|
||||
m_TextureState?.UnsubscribeAll(OnStyleChanged);
|
||||
m_ColorState?.UnregisterAll();
|
||||
m_TextureState?.UnregisterAll();
|
||||
m_ColorState?.UnsubscribeAll(OnStyleChanged);
|
||||
m_TextureState?.UnsubscribeAll(OnStyleChanged);
|
||||
m_ColorState?.UnregisterAll();
|
||||
m_TextureState?.UnregisterAll();
|
||||
|
||||
base.OnDisable();
|
||||
}
|
||||
base.OnDisable();
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region 状态过渡
|
||||
#region 状态过渡
|
||||
|
||||
protected override void DoStateTransition(SelectionState state, bool instant)
|
||||
{
|
||||
if (!gameObject.activeInHierarchy) return;
|
||||
protected override void DoStateTransition(SelectionState state, bool instant)
|
||||
{
|
||||
if (!gameObject.activeInHierarchy) return;
|
||||
|
||||
m_CurrentState = (StyleSheetSelectionState)(int)state;
|
||||
m_CurrentState = (StyleSheetSelectionState)(int)state;
|
||||
|
||||
if (m_EnableStyleTransition)
|
||||
ApplyForState(m_CurrentState, instant);
|
||||
else
|
||||
base.DoStateTransition(state, instant);
|
||||
}
|
||||
if (m_EnableStyleTransition)
|
||||
ApplyForState(m_CurrentState, instant);
|
||||
else
|
||||
base.DoStateTransition(state, instant);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region 样式应用
|
||||
#region 样式应用
|
||||
|
||||
public void RefreshStyle()
|
||||
{
|
||||
ApplyForState(m_CurrentState, false);
|
||||
}
|
||||
public void RefreshStyle()
|
||||
{
|
||||
ApplyForState(m_CurrentState, false);
|
||||
}
|
||||
|
||||
private void ApplyForState(StyleSheetSelectionState state, bool instant = false)
|
||||
{
|
||||
// 颜色
|
||||
if (m_ColorState != null)
|
||||
{
|
||||
StyleField colorField = m_ColorState.GetForState(state);
|
||||
if (colorField != null && m_TargetGraphic != null)
|
||||
{
|
||||
StyleValue val = colorField.GetValue();
|
||||
if (val != null)
|
||||
m_TargetGraphic.CrossFadeColor((Color)val,
|
||||
instant ? 0f : m_ColorState.FadeDuration, true, true);
|
||||
}
|
||||
}
|
||||
private void ApplyForState(StyleSheetSelectionState state, bool instant = false)
|
||||
{
|
||||
if (m_TransitionMode == TransitionMode.Color || m_TransitionMode == TransitionMode.ColorAndSprite)
|
||||
{
|
||||
if (m_ColorState != null)
|
||||
{
|
||||
StyleField colorField = m_ColorState.GetForState(state);
|
||||
if (colorField != null && m_TargetGraphic != null)
|
||||
{
|
||||
StyleValue val = colorField.GetValue();
|
||||
if (val != null)
|
||||
m_TargetGraphic.CrossFadeColor((Color)val,
|
||||
instant ? 0f : m_ColorState.FadeDuration, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 纹理
|
||||
if (m_TextureState != null && m_TargetImage != null)
|
||||
{
|
||||
StyleField texField = m_TextureState.GetForState(state);
|
||||
if (texField != null)
|
||||
{
|
||||
StyleValue val = texField.GetValue();
|
||||
Texture2D tex = val?.GetValueAs<Texture2D>();
|
||||
if (tex != null)
|
||||
m_TargetImage.overrideSprite = Sprite.Create(tex,
|
||||
new Rect(0, 0, tex.width, tex.height),
|
||||
new Vector2(0.5f, 0.5f));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_TransitionMode == TransitionMode.Sprite || m_TransitionMode == TransitionMode.ColorAndSprite)
|
||||
{
|
||||
if (m_TextureState != null && m_TargetImage != null)
|
||||
{
|
||||
StyleField texField = m_TextureState.GetForState(state);
|
||||
if (texField != null)
|
||||
{
|
||||
StyleValue val = texField.GetValue();
|
||||
Texture2D tex = val?.GetValueAs<Texture2D>();
|
||||
if (tex != null)
|
||||
m_TargetImage.overrideSprite = Sprite.Create(tex,
|
||||
new Rect(0, 0, tex.width, tex.height),
|
||||
new Vector2(0.5f, 0.5f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStyleChanged(StyleValue _)
|
||||
{
|
||||
if (gameObject.activeInHierarchy)
|
||||
ApplyForState(m_CurrentState);
|
||||
}
|
||||
private void OnStyleChanged(StyleValue _)
|
||||
{
|
||||
if (gameObject.activeInHierarchy)
|
||||
ApplyForState(m_CurrentState);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region 组件替换
|
||||
#region 组件替换
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.MenuItem("CONTEXT/XericStyleButton/Xeric UI/强制刷新样式", false, 1)]
|
||||
private static void ForceRefreshStyle(UnityEditor.MenuCommand command)
|
||||
{
|
||||
StyleRefreshManager.ForceRefreshAll();
|
||||
}
|
||||
[UnityEditor.MenuItem("CONTEXT/XericStyleButton/Xeric UI/强制刷新样式", false, 1)]
|
||||
private static void ForceRefreshStyle(UnityEditor.MenuCommand command)
|
||||
{
|
||||
StyleRefreshManager.ForceRefreshAll();
|
||||
}
|
||||
|
||||
[UnityEditor.MenuItem("CONTEXT/Button/Replace To/Xeric (Style)", true)]
|
||||
private static bool ValidateReplaceToStyleButton(UnityEditor.MenuCommand command)
|
||||
=> command.context is Button and not XericStyleButton;
|
||||
[UnityEditor.MenuItem("CONTEXT/Button/Replace To/Xeric (Style)", true)]
|
||||
private static bool ValidateReplaceToStyleButton(UnityEditor.MenuCommand command)
|
||||
=> command.context is Button and not XericStyleButton;
|
||||
|
||||
[UnityEditor.MenuItem("CONTEXT/Button/Replace To/Xeric (Style)", false, 11)]
|
||||
private static void ReplaceToStyleButton(UnityEditor.MenuCommand command)
|
||||
=> command.ReplaceCommandContext<Button, XericStyleButton,
|
||||
(Graphic targetGraphic, ButtonClickedEvent onClick, Navigation navigation)>(
|
||||
o => (o.targetGraphic, o.onClick, o.navigation),
|
||||
(t, d) =>
|
||||
{
|
||||
t.targetGraphic = d.targetGraphic;
|
||||
t.onClick = d.onClick;
|
||||
t.navigation = d.navigation;
|
||||
});
|
||||
[UnityEditor.MenuItem("CONTEXT/Button/Replace To/Xeric (Style)", false, 11)]
|
||||
private static void ReplaceToStyleButton(UnityEditor.MenuCommand command)
|
||||
=> command.ReplaceCommandContext<Button, XericStyleButton,
|
||||
(Graphic targetGraphic, ButtonClickedEvent onClick, Navigation navigation)>(
|
||||
o => (o.targetGraphic, o.onClick, o.navigation),
|
||||
(t, d) =>
|
||||
{
|
||||
t.targetGraphic = d.targetGraphic;
|
||||
t.onClick = d.onClick;
|
||||
t.navigation = d.navigation;
|
||||
});
|
||||
|
||||
[UnityEditor.MenuItem("CONTEXT/Button/Replace To/Unity Button", true)]
|
||||
private static bool ValidateReplaceStyleToUnity(UnityEditor.MenuCommand command)
|
||||
=> command.context is XericStyleButton;
|
||||
[UnityEditor.MenuItem("CONTEXT/Button/Replace To/Unity Button", true)]
|
||||
private static bool ValidateReplaceStyleToUnity(UnityEditor.MenuCommand command)
|
||||
=> command.context is XericStyleButton;
|
||||
|
||||
[UnityEditor.MenuItem("CONTEXT/Button/Replace To/Unity Button", false, 100)]
|
||||
private static void ReplaceStyleToUnity(UnityEditor.MenuCommand command)
|
||||
=> command.ReplaceCommandContext<XericStyleButton, Button,
|
||||
(Graphic targetGraphic, ButtonClickedEvent onClick, Navigation navigation)>(
|
||||
o => (o.targetGraphic, o.onClick, o.navigation),
|
||||
(t, d) =>
|
||||
{
|
||||
t.targetGraphic = d.targetGraphic;
|
||||
t.onClick = d.onClick;
|
||||
t.navigation = d.navigation;
|
||||
});
|
||||
[UnityEditor.MenuItem("CONTEXT/Button/Replace To/Unity Button", false, 100)]
|
||||
private static void ReplaceStyleToUnity(UnityEditor.MenuCommand command)
|
||||
=> command.ReplaceCommandContext<XericStyleButton, Button,
|
||||
(Graphic targetGraphic, ButtonClickedEvent onClick, Navigation navigation)>(
|
||||
o => (o.targetGraphic, o.onClick, o.navigation),
|
||||
(t, d) =>
|
||||
{
|
||||
t.targetGraphic = d.targetGraphic;
|
||||
t.onClick = d.onClick;
|
||||
t.navigation = d.navigation;
|
||||
});
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -9,20 +9,38 @@ namespace XericUI.OverrideUI
|
||||
{
|
||||
/// <summary>
|
||||
/// 基于 SuperStyleSheet 的开关组件。
|
||||
/// 使用两个 StyleSheetState 实例管理五态颜色和纹理样式,
|
||||
/// 通过 TransitionMode 选择颜色切换、纹理切换或两者并用,
|
||||
/// 额外支持 isOn 覆盖和 Checkmark 样式。
|
||||
/// </summary>
|
||||
[AddComponentMenu("Xeric UI Vessel/UI/Style Toggle", 52)]
|
||||
public class XericStyleToggle : Toggle, IStyleRefreshable
|
||||
{
|
||||
/// <summary>样式过渡模式</summary>
|
||||
public enum TransitionMode
|
||||
{
|
||||
/// <summary>仅颜色切换</summary>
|
||||
Color,
|
||||
/// <summary>仅纹理/Sprite 切换</summary>
|
||||
Sprite,
|
||||
/// <summary>颜色 + 纹理切换</summary>
|
||||
ColorAndSprite
|
||||
}
|
||||
|
||||
#region 序列化字段
|
||||
|
||||
[Header("过渡模式")]
|
||||
[SerializeField]
|
||||
[Tooltip("选择颜色 / 纹理 / 同时切换")]
|
||||
private TransitionMode m_TransitionMode = TransitionMode.ColorAndSprite;
|
||||
|
||||
[Header("样式表状态")]
|
||||
[SerializeField]
|
||||
[Tooltip("五态颜色样式块(ColorTint)")]
|
||||
private StyleSheetState m_ColorState = StyleSheetState.Default;
|
||||
|
||||
[SerializeField]
|
||||
private StyleSheetState m_TextureState = StyleSheetState.Default;
|
||||
[Tooltip("五态纹理样式块(SpriteState)")]
|
||||
private StyleSheetState m_TextureState = StyleSheetState.CreateTexture();
|
||||
|
||||
[Header("Toggle 专用")]
|
||||
[SerializeField]
|
||||
@@ -163,37 +181,43 @@ namespace XericUI.OverrideUI
|
||||
|
||||
private void ApplyForState(StyleSheetSelectionState state, bool instant = false)
|
||||
{
|
||||
// 颜色:On 覆盖优先
|
||||
StyleField colorField = isOn && m_OnOverrideColor?.GetValue() != null
|
||||
? m_OnOverrideColor
|
||||
: m_ColorState?.GetForState(state);
|
||||
|
||||
if (colorField != null && m_TargetGraphic != null)
|
||||
if (m_TransitionMode == TransitionMode.Color || m_TransitionMode == TransitionMode.ColorAndSprite)
|
||||
{
|
||||
StyleValue val = colorField.GetValue();
|
||||
if (val != null)
|
||||
// 颜色:On 覆盖优先
|
||||
StyleField colorField = isOn && m_OnOverrideColor?.GetValue() != null
|
||||
? m_OnOverrideColor
|
||||
: m_ColorState?.GetForState(state);
|
||||
|
||||
if (colorField != null && m_TargetGraphic != null)
|
||||
{
|
||||
float dur = instant ? 0f : (m_ColorState?.FadeDuration ?? 0.1f);
|
||||
m_TargetGraphic.CrossFadeColor((Color)val, dur, true, true);
|
||||
StyleValue val = colorField.GetValue();
|
||||
if (val != null)
|
||||
{
|
||||
float dur = instant ? 0f : (m_ColorState?.FadeDuration ?? 0.1f);
|
||||
m_TargetGraphic.CrossFadeColor((Color)val, dur, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 纹理:On 覆盖优先
|
||||
StyleField texField = isOn && m_OnOverrideTexture?.GetValue() != null
|
||||
? m_OnOverrideTexture
|
||||
: m_TextureState?.GetForState(state);
|
||||
|
||||
if (texField != null && m_TargetImage != null)
|
||||
if (m_TransitionMode == TransitionMode.Sprite || m_TransitionMode == TransitionMode.ColorAndSprite)
|
||||
{
|
||||
StyleValue val = texField.GetValue();
|
||||
Texture2D tex = val?.GetValueAs<Texture2D>();
|
||||
if (tex != null)
|
||||
m_TargetImage.overrideSprite = Sprite.Create(tex,
|
||||
new Rect(0, 0, tex.width, tex.height),
|
||||
new Vector2(0.5f, 0.5f));
|
||||
// 纹理:On 覆盖优先
|
||||
StyleField texField = isOn && m_OnOverrideTexture?.GetValue() != null
|
||||
? m_OnOverrideTexture
|
||||
: m_TextureState?.GetForState(state);
|
||||
|
||||
if (texField != null && m_TargetImage != null)
|
||||
{
|
||||
StyleValue val = texField.GetValue();
|
||||
Texture2D tex = val?.GetValueAs<Texture2D>();
|
||||
if (tex != null)
|
||||
m_TargetImage.overrideSprite = Sprite.Create(tex,
|
||||
new Rect(0, 0, tex.width, tex.height),
|
||||
new Vector2(0.5f, 0.5f));
|
||||
}
|
||||
}
|
||||
|
||||
// Checkmark
|
||||
// Checkmark(独立于 TransitionMode)
|
||||
if (m_CheckmarkGraphic != null && m_CheckmarkStyle != null)
|
||||
{
|
||||
StyleValue val = m_CheckmarkStyle.GetValue();
|
||||
|
||||
Reference in New Issue
Block a user