ui: extract PledgerSkin common visual components and refactor WalletWindow

This commit is contained in:
ZHU MINCHAO committed 2026-11-04 09:57:18 +08:00
1 parent fb29b61a6a
commit d7d2fec536
2 files changed
+265 -69

No files matched your search

+10 -69
View File
@@ -89,9 +89,6 @@ namespace Decentralized
return t.ToArray();
}
private static readonly Color Ink = new Color(0.12f, 0.12f, 0.14f),
Key = new Color(0.16f, 0.16f, 0.19f), KeyText = new Color(0.93f, 0.93f, 0.90f),
Dim = new Color(0.38f, 0.39f, 0.40f), Alert = new Color(0.62f, 0.16f, 0.12f);
public static string NameOf(Wallet w)
{
@@ -190,83 +187,27 @@ namespace Decentralized
private static void Skin(CustomUIWindow win, RectTransform screen, Image bezel, Image paper, Image plate, GameObject ok, Device dev)
{
if (win?.root == null) return;
Slice(win.root.GetComponent<Image>(), "ui_hw_shell", 10);
Slice(bezel, "ui_hw_bezel", 5);
Slice(paper, "ui_hw_paper", 3);
// 标题栏和分隔线透明,标题当作机身上的刻字
foreach (var name in new[] { "header", "rule" })
var rows = _rows.Select(x => new PledgerSkin.RowDef
{
var img = win.root.transform.Find(name)?.GetComponent<Image>();
if (img != null) img.color = new Color(0, 0, 0, 0);
}
if (win.frame?.titleText != null)
{
var t = win.frame.titleText;
t.color = new Color(0.62f, 0.64f, 0.70f); t.fontStyle = FontStyles.Bold; t.characterSpacing = 18f; t.fontSize = 16f; t.horizontalAlignment = HorizontalAlignmentOptions.Center;
}
var content = win.frame?.contentRoot?.GetComponent<VerticalLayoutGroup>();
if (content != null) content.childAlignment = TextAnchor.UpperCenter;
if (plate != null) plate.color = new Color(0, 0, 0, 0);
foreach (var t in screen.GetComponentsInChildren<TextMeshProUGUI>(true))
{
if (t.GetComponentInParent<Button>() != null || t.GetComponentInParent<TMP_InputField>() != null) continue;
t.color = t.gameObject.name.Contains("_note") ? Alert : t.gameObject.name.Contains("_dim") ? Dim : Ink;
}
foreach (var btn in screen.GetComponentsInChildren<Button>(true))
{
var img = btn.GetComponent<Image>();
bool on = _picked.Contains(btn.gameObject);
if (img != null) { if (on) Slice(img, "ui_hw_sel", 5); else img.color = Key; }
foreach (var t in btn.GetComponentsInChildren<TextMeshProUGUI>(true)) { t.color = on ? Ink : KeyText; if (on) t.fontStyle |= FontStyles.Bold; }
}
foreach (var img in _clear) if (img != null) img.color = new Color(0, 0, 0, 0);
// 余额行:整行可点,选中的一行反色高亮
foreach (var (root, img, asset) in _rows)
{
if (root == null || img == null) continue;
bool on = asset == dev.Asset;
img.sprite = MachineryStyle.White; img.type = Image.Type.Simple; img.raycastTarget = true;
img.color = on ? Ink : new Color(0, 0, 0, 0.04f);
foreach (var t in root.GetComponentsInChildren<TextMeshProUGUI>(true)) t.color = on ? KeyText : Ink;
var btn = root.GetComponent<Button>() ?? root.AddComponent<Button>();
btn.transition = Selectable.Transition.None;
btn.onClick.RemoveAllListeners();
string a = asset;
btn.onClick.AddListener(() => { dev.Asset = a; dev.Note = null; Open(dev); });
}
Root = x.root,
Image = x.image,
Selected = (x.asset == dev.Asset),
OnClick = () => { dev.Asset = x.asset; dev.Note = null; Open(dev); }
});
PledgerSkin.Apply(win, screen, bezel, paper, _picked, _clear, rows);
if (plate != null) plate.color = PledgerSkin.Transparent;
// 签名要按住 ✓:在按键上挂一个按住计时
if (ok != null && dev.Screen == Screen.Review && ok.GetComponent<HoldToSign>() == null) ok.AddComponent<HoldToSign>().Device = dev.Address;
}
/// <summary>把本 mod 的像素图做成九宫格贴到 Image 上:边角 border 像素不拉伸,一个像素放大成 3 个界面单位。</summary>
private static void Slice(Image img, string key, int border)
{
var src = Items.ModSprite(key);
if (img == null || src == null) return;
if (!Sliced.TryGetValue(key, out var sp))
{
src.texture.filterMode = FilterMode.Point;
sp = Sprite.Create(src.texture, src.rect, new Vector2(0.5f, 0.5f), src.pixelsPerUnit, 0, SpriteMeshType.FullRect, new Vector4(border, border, border, border));
Sliced[key] = sp;
}
img.sprite = sp;
img.type = Image.Type.Sliced;
img.pixelsPerUnitMultiplier = 100f / (3f * sp.pixelsPerUnit);
img.color = Color.white;
}
private static readonly Dictionary<string, Sprite> Sliced = new Dictionary<string, Sprite>();
private const float RowW = ScreenW - 28f;
private static readonly List<(GameObject root, Image image, string asset)> _rows = new List<(GameObject, Image, string)>();
private static readonly List<Image> _clear = new List<Image>();
private static readonly List<GameObject> _picked = new List<GameObject>();
/// <summary>屏上的选择按钮(币种、手续费档位):选中的一个画成白底黑框黑字、四角带准星角标。</summary>
private static void Pick(CustomUIBuilder b, string text, bool selected, Action onClick)
{
b.AddButton(text, onClick);
if (selected) _picked.Add(b.Last.root);
}
private static void Pick(CustomUIBuilder b, string text, bool selected, Action onClick) =>
PledgerSkin.Pick(b, text, selected, onClick, _picked);
public static string Amt(double v) => v.ToString(v >= 100 ? "0.##" : "0.####", CultureInfo.InvariantCulture);