终端只重建内容区并合并同帧刷新;平台费页文案;按住签名随 Gas 档位缩短

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Sonnet 5.5 committed 2026-11-05 21:57:15 +08:00
1 parent 876a8c4daa
commit f5beeea900
14 files changed
+138 -28

No files matched your search

+98 -16
View File
@@ -39,19 +39,42 @@ namespace Decentralized
private static readonly List<Image> _clear = new List<Image>();
private static readonly List<PledgerSkin.RowDef> _rows = new List<PledgerSkin.RowDef>();
// 窗口建好之后保留:之后的刷新只重建页签栏、滚动内容和消息行,不重建窗口框架,滚动位置也不丢。
private static CustomUIWindow _win;
private static RectTransform _screen, _topRoot, _bodyRoot, _noteRoot;
private static ScrollRect _scroll;
private static float _builtW, _builtH;
private static string _scrollKey;
private static bool _dirty;
private static bool Alive() =>
CustomUIManager.Instance != null && CustomUIManager.Instance.IsOpen(Id) && _win != null && _win.root != null
&& _screen != null && _topRoot != null && _bodyRoot != null && _noteRoot != null
&& Math.Abs(_builtW - WinW) < 0.5f && Math.Abs(_builtH - WinH) < 0.5f;
/// <summary>打开或刷新终端。窗口还没开(或窗口大小变了)时马上完整构建;已经开着就只标记要刷新,同一帧里的多次刷新合并成一次(见 <see cref="Flush"/>)。</summary>
public static void Open()
{
if (Session.Data == null) return;
var b = CustomUIManager.Window(Id, L.T("term.title"));
if (b == null) return;
_picked.Clear(); _clear.Clear(); _rows.Clear();
b.SetSize(WinW, WinH).SetDraggable(true).SetCloseOnEscape(true).UseMachineryStyle();
// 黑色外边框包裹墨水屏
b.BeginPanel(ScreenW + Bezel * 2, ScreenH + Bezel * 2, TextAnchor.MiddleCenter, Bezel + 3f, 0f);
var bezel = b.Last.image;
b.BeginPanel(ScreenW, ScreenH, TextAnchor.UpperLeft, 12f, 4f);
var screen = b.CurrentContainer;
var paper = b.Last.image;
if (!Alive()) { OpenFull(); return; }
_dirty = true;
WalletDriver.Ensure();
}
/// <summary>每帧由常驻驱动调用:有待刷新的就重建一次内容区。</summary>
public static void Flush()
{
if (!_dirty) return;
_dirty = false;
if (Session.Data == null || CustomUIManager.Instance == null || !CustomUIManager.Instance.IsOpen(Id)) return;
if (!Alive()) { OpenFull(); return; }
Rebuild();
}
private static string ScrollKey() => string.Join("|", _page, _web3Tab, _grayTab, _blackTab, _sellView, _walletTab, _poinTab);
private static void BuildTop(CustomUIBuilder b)
{
if (_page == Page.Gray && !GrayAvailable) _page = Page.Web3;
TabRows(b, Enum.GetValues(typeof(Page)).Cast<Page>().Where(p => p != Page.Gray || GrayAvailable).Select(p =>
{
@@ -59,9 +82,10 @@ namespace Decentralized
return new TabDef { Name = L.T("tab." + p.ToString().ToLowerInvariant()), On = page == _page, Click = () => { _page = page; _message = null; Open(); } };
}).ToList(), true);
ConnectPicker(b);
b.AddSeparator();
b.BeginScroll(ScreenH - 52f);
_clear.Add(b.Last.image);
}
private static void BuildBody(CustomUIBuilder b)
{
if ((_page == Page.Web3 || _page == Page.Gray) && WalletWindow.Pending != null && !WalletWindow.Pending.Contract) PayPage(b);
else switch (_page)
{
@@ -74,15 +98,74 @@ namespace Decentralized
case Page.Wallets: WalletsPage(b); break;
default: break;
}
b.End();
}
private static void BuildNote(CustomUIBuilder b)
{
if (!string.IsNullOrEmpty(_message)) b.AddLabel(_message, "term_note");
}
/// <summary>完整构建:窗口、黑边、屏幕、页签栏、滚动区、消息行。</summary>
private static void OpenFull()
{
var b = CustomUIManager.Window(Id, L.T("term.title"));
if (b == null) return;
_picked.Clear(); _clear.Clear(); _rows.Clear();
b.SetSize(WinW, WinH).SetDraggable(true).SetCloseOnEscape(true).UseMachineryStyle();
// 黑色外边框包裹墨水屏
b.BeginPanel(ScreenW + Bezel * 2, ScreenH + Bezel * 2, TextAnchor.MiddleCenter, Bezel + 3f, 0f);
var bezel = b.Last.image;
b.BeginPanel(ScreenW, ScreenH, TextAnchor.UpperLeft, 12f, 4f);
var screen = b.CurrentContainer;
var paper = b.Last.image;
b.BeginPanel(ScreenW - 24f, -1f, TextAnchor.UpperLeft, 0f, 4f);
_clear.Add(b.Last.image);
var top = b.CurrentContainer;
BuildTop(b);
b.End();
b.AddSeparator();
b.BeginScroll(ScreenH - 52f);
_clear.Add(b.Last.image);
var body = b.CurrentContainer;
BuildBody(b);
b.End();
b.BeginPanel(ScreenW - 24f, -1f, TextAnchor.UpperLeft, 0f, 0f);
_clear.Add(b.Last.image);
var note = b.CurrentContainer;
BuildNote(b);
b.End();
b.End();
b.End();
var win = b.Show();
_win = win; _screen = screen; _topRoot = top; _bodyRoot = body; _noteRoot = note;
_scroll = body != null ? body.GetComponentInParent<ScrollRect>() : null;
_builtW = WinW; _builtH = WinH; _scrollKey = ScrollKey(); _dirty = false;
Log.Guard("交易终端外观", () => PledgerSkin.Apply(win, screen, bezel, paper, _picked, _clear, _rows, F));
Log.Guard("购物车按钮", () => CartFab(win));
}
/// <summary>只重建页签栏、滚动内容和消息行;窗口框架和滚动视图保留(滚动位置自然不变,换页或换子页签时回到顶部)。</summary>
private static void Rebuild()
{
var m = CustomUIManager.Instance;
_picked.Clear(); _clear.Clear(); _rows.Clear();
CustomUIBuilder.ClearContainer(_topRoot);
CustomUIBuilder.ClearContainer(_bodyRoot);
CustomUIBuilder.ClearContainer(_noteRoot);
BuildTop(new CustomUIBuilder(m, _win, _topRoot));
BuildBody(new CustomUIBuilder(m, _win, _bodyRoot));
BuildNote(new CustomUIBuilder(m, _win, _noteRoot));
string key = ScrollKey();
if (key != _scrollKey)
{
_scrollKey = key;
if (_scroll != null && _scroll.content != null) { var cp = _scroll.content.anchoredPosition; _scroll.content.anchoredPosition = new Vector2(cp.x, 0f); }
}
CustomUIBuilder.RebuildLayout(_topRoot); CustomUIBuilder.RebuildLayout(_bodyRoot); CustomUIBuilder.RebuildLayout(_noteRoot);
Log.Guard("交易终端外观", () => PledgerSkin.Apply(_win, _screen, null, null, _picked, _clear, _rows, F, false));
Log.Guard("购物车按钮", () => CartFab(_win));
}
private static void Go(Page p) { _page = p; _message = null; Open(); }
/// <summary>钱包那边交易落地后刷新终端(开着的话),带上结果消息。</summary>
@@ -1762,8 +1845,7 @@ namespace Decentralized
l.AddLabel(L.T("black.fee.total", Fmt.Credits(fee)), "cart_total");
}, r =>
{
r.AddHeader(L.T("bpay.h"));
r.AddLabel(L.T("bpay.coin"), "bpay_coin_dim");
r.AddHeader(L.T("black.fee.pay"));
r.BeginRow(4f);
foreach (var a in acc) { string asset = a; PledgerSkin.Pick(r, asset, asset == _feeCoin, () => { _feeCoin = asset; Open(); }, _picked); }
r.End();