diff --git a/art/sprites.py b/art/sprites.py
index 49d4482..3678758 100644
--- a/art/sprites.py
+++ b/art/sprites.py
@@ -752,6 +752,19 @@ UI_ICONS['ui_hw_shell'] = lambda: rounded(32, 7, 'K', 'E', 'z')
UI_ICONS['ui_hw_bezel'] = lambda: rounded(16, 4, 'n')
UI_ICONS['ui_hw_paper'] = lambda: rounded(12, 2, 'P')
UI_ICONS['ui_hw_sel'] = hw_selected
+def hw_key():
+ """触控键底图(九宫格,白色,可着色):圆角 3 像素,没有描边,颜色由界面按状态着色。"""
+ size, r = 12, 3
+ c = Canvas(size, size)
+ for y in range(size):
+ for x in range(size):
+ cx = min(max(x, r), size - 1 - r); cy = min(max(y, r), size - 1 - r)
+ if (x - cx) ** 2 + (y - cy) ** 2 <= r * r + r * 0.6:
+ c.put(x, y, 'w')
+ return c
+
+
+UI_ICONS['ui_hw_key'] = hw_key
UI_ICONS['ui_hw_groove'] = hw_groove
UI_ICONS['ui_hw_ok'] = lambda: hw_button('ok')
UI_ICONS['ui_hw_no'] = lambda: hw_button('no')
diff --git a/src/Decentralized/ModFiles/Textures/Items/ui_hw_key.png b/src/Decentralized/ModFiles/Textures/Items/ui_hw_key.png
new file mode 100644
index 0000000..0631730
Binary files /dev/null and b/src/Decentralized/ModFiles/Textures/Items/ui_hw_key.png differ
diff --git a/src/Decentralized/PledgerSkin.cs b/src/Decentralized/PledgerSkin.cs
index f853de4..27e4894 100644
--- a/src/Decentralized/PledgerSkin.cs
+++ b/src/Decentralized/PledgerSkin.cs
@@ -57,6 +57,13 @@ namespace Decentralized
}
/// 把输入框切片为墨水屏凹槽:浅色底、1 像素深墨边框(1:1 像素映射)。
+ /// 圆角触控键:白色的九宫格底图按颜色着色(黑底白字键、选中行里的浅色键共用同一张图)。
+ public static void KeyShape(Image img, Color color)
+ {
+ Slice(img, "ui_hw_key", 4);
+ if (img != null) img.color = color;
+ }
+
public static void SliceGroove(Image img)
{
if (img == null) return;
@@ -218,7 +225,7 @@ namespace Decentralized
}
else
{
- img.color = Key;
+ KeyShape(img, Key);
}
}
foreach (var t in btn.GetComponentsInChildren(true))
@@ -325,9 +332,7 @@ namespace Decentralized
var img = cBtn.GetComponent();
if (img != null)
{
- img.sprite = MachineryStyle.White;
- img.type = Image.Type.Simple;
- img.color = KeyText;
+ KeyShape(img, KeyText);
}
foreach (var t in cBtn.GetComponentsInChildren(true))
{
diff --git a/src/Decentralized/TerminalWindow.cs b/src/Decentralized/TerminalWindow.cs
index d09139d..00c5f10 100644
--- a/src/Decentralized/TerminalWindow.cs
+++ b/src/Decentralized/TerminalWindow.cs
@@ -1003,15 +1003,21 @@ namespace Decentralized
Cell(b, cols[1], w.Address, false, TextAnchor.MiddleLeft);
Cell(b, cols[2], Fmt.Credits(w.Value(Session.Price)), false, TextAnchor.MiddleRight);
Cell(b, cols[3], Fmt.Credits(w.Taint), false, TextAnchor.MiddleRight);
- b.BeginPanel(cols[4], 28f, TextAnchor.MiddleLeft, 0f, 0f);
+ // 操作键一组(垂直居中、固定高度),连接状态单独靠右
+ b.BeginPanel(cols[4] - 140f, 32f, TextAnchor.MiddleLeft, 0f, 0f);
_clear.Add(b.Last.image);
b.BeginRow(4f, TextAnchor.MiddleLeft);
- b.AddButton(L.T("wallets.open"), () => WalletWindow.Open(w));
- b.AddButton(L.T("hw.copy"), () => { Clipboard.Copy(w.Address); _message = L.T("hw.copied.addr", w.Address); Open(); });
- b.AddButton(L.T("wallets.rename"), () => { _renamePick = w.Address; _renameText = w.Label ?? ""; _message = null; Open(); });
- if (idx != d.Current) b.AddButton(L.T("wallets.use"), () => { d.Current = idx; Session.Save(); Open(); });
+ RowKey(b, L.T("wallets.open"), () => WalletWindow.Open(w));
+ RowKey(b, L.T("hw.copy"), () => { Clipboard.Copy(w.Address); _message = L.T("hw.copied.addr", w.Address); Open(); });
+ RowKey(b, L.T("wallets.rename"), () => { _renamePick = w.Address; _renameText = w.Label ?? ""; _message = null; Open(); });
+ if (idx > 0) RowKey(b, _destroyPick == w.Address ? L.T("wallets.destroy.sure") : L.T("wallets.destroy"), () => DestroyWallet(w));
+ b.End();
+ b.End();
+ b.BeginPanel(100f, 32f, TextAnchor.MiddleRight, 0f, 0f);
+ _clear.Add(b.Last.image);
+ b.BeginRow(0f, TextAnchor.MiddleRight);
+ if (idx != d.Current) RowKey(b, L.T("wallets.use"), () => { d.Current = idx; Session.Save(); Open(); });
else b.AddLabel(L.T("wallets.current"), "wallets_cur_dim");
- if (idx > 0) b.AddButton(_destroyPick == w.Address ? L.T("wallets.destroy.sure") : L.T("wallets.destroy"), () => DestroyWallet(w));
b.End();
b.End();
b.End();
@@ -1020,6 +1026,16 @@ namespace Decentralized
if (_renamePick != null) RenameRow(b);
}
+ /// 表格行里的操作键:固定 24 高,垂直居中(行高 32)。
+ private static void RowKey(CustomUIBuilder b, string text, Action onClick)
+ {
+ b.AddButton(text, onClick);
+ var go = b.Last.root;
+ if (go == null) return;
+ var le = go.GetComponent() ?? go.AddComponent();
+ le.minHeight = 24f; le.preferredHeight = 24f; le.flexibleHeight = 0f;
+ }
+
private static string _destroyPick, _renamePick, _renameText = "";
/// 改名:表格下方一行输入框;留空恢复默认名。