终端窗口可调大小(默认 1200×900)与布局放宽;mod 设置:界面、剧情、难度

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ZHU MINCHAOandClaude Sonnet 5.5 committed 2026-11-04 15:34:38 +08:00
1 parent fa8f416545
commit 861acac240
26 files changed
+302 -45

No files matched your search

+53 -31
View File
@@ -16,8 +16,19 @@ namespace Decentralized
public static class TerminalWindow
{
public const string Id = "pd_terminal";
private const float WinW = 828f, WinH = 680f, ScreenW = 768f, ScreenH = 578f, Bezel = 6f;
private const float LeftW = 420f, RightW = 310f;
private const float Bezel = 6f;
// 窗口尺寸取自 mod 设置(828×680 是基准,各页布局按多出来的宽高等比放宽)
private static float WinW => Settings.TerminalW;
private static float WinH => Settings.TerminalH;
private static float ScreenW => WinW - 60f;
private static float ScreenH => WinH - 102f;
private static float Ext => ScreenW - 768f;
private static float LeftW => 420f + Ext * 0.6f;
private static float RightW => 310f + Ext * 0.4f;
/// <summary>大窗口里文字放大(行高、卡片同步放大):基准窗口 1,1200 宽约 1.24,上限 1.3。</summary>
private static float F => Mathf.Clamp(1f + Ext * 0.00065f, 1f, 1.3f);
public static float ChartScale => LeftW >= 634f ? 3f : 2f;
private static float[] Sc(float[] b) { float k = LeftW / 420f; return b.Select(x => x * k).ToArray(); }
private enum Page { Home, Bank, Poinbase, Web3, Wallets }
private static Page _page = Page.Home;
@@ -69,7 +80,7 @@ namespace Decentralized
b.End();
b.End();
var win = b.Show();
Log.Guard("交易终端外观", () => PledgerSkin.Apply(win, screen, bezel, paper, _picked, _clear, _rows));
Log.Guard("交易终端外观", () => PledgerSkin.Apply(win, screen, bezel, paper, _picked, _clear, _rows, F));
Log.Guard("购物车按钮", () => CartFab(win));
}
@@ -84,7 +95,7 @@ namespace Decentralized
private static void Entry(CustomUIBuilder b, string icon, string name, string line1, string line2, Page target)
{
b.BeginPanel(230f, 250f, TextAnchor.UpperCenter, 10f, 6f);
b.BeginPanel((ScreenW - 80f) / 3f, 250f + (ScreenH - 578f) * 0.25f, TextAnchor.UpperCenter, 10f, 6f);
var cardImg = b.Last.image;
cardImg.sprite = MachineryStyle.White;
cardImg.color = PledgerSkin.RowNormal;
@@ -116,7 +127,7 @@ namespace Decentralized
private static void Cell(CustomUIBuilder b, float w, string text, bool header = false, TextAnchor align = TextAnchor.MiddleLeft)
{
b.BeginPanel(w, 26f, align, 0f, 0f);
b.BeginPanel(w, 26f * F, align, 0f, 0f);
_clear.Add(b.Last.image);
b.AddLabel(header ? "<b>" + text + "</b>" : text);
PledgerSkin.FitCurrent(b);
@@ -125,7 +136,7 @@ namespace Decentralized
private static void TableRow(CustomUIBuilder b, float totalW, float[] widths, TextAnchor[] aligns, string[] cells, bool selected = false, Action onClick = null)
{
b.BeginPanel(totalW, 28f, TextAnchor.MiddleLeft, 4f, 0f);
b.BeginPanel(totalW, 28f * F, TextAnchor.MiddleLeft, 4f, 0f);
_rows.Add(new PledgerSkin.RowDef { Root = b.Last.root, Image = b.Last.image, Selected = selected, OnClick = onClick });
b.BeginRow(0f, TextAnchor.MiddleLeft);
for (int i = 0; i < widths.Length; i++)
@@ -142,7 +153,7 @@ namespace Decentralized
private static void TableHeader(CustomUIBuilder b, float totalW, float[] widths, TextAnchor[] aligns, params string[] cells)
{
b.BeginPanel(totalW, 26f, TextAnchor.MiddleLeft, 4f, 0f);
b.BeginPanel(totalW, 26f * F, TextAnchor.MiddleLeft, 4f, 0f);
_clear.Add(b.Last.image);
b.BeginRow(0f, TextAnchor.MiddleLeft);
for (int i = 0; i < widths.Length; i++)
@@ -199,10 +210,10 @@ namespace Decentralized
AmlPreview(r);
r.AddSpace(6f);
r.AddButton(L.T("trade.deposit"), Deposit);
r.Last?.SetPreferredSize(RightW - 30f, 28f);
r.Last?.SetPreferredSize(RightW - 30f, 28f * F);
r.AddSpace(4f);
r.AddButton(L.T("trade.withdraw"), Withdraw);
r.Last?.SetPreferredSize(RightW - 30f, 28f);
r.Last?.SetPreferredSize(RightW - 30f, 28f * F);
});
}
@@ -216,7 +227,8 @@ namespace Decentralized
b.AddLabel(L.T("aml.taint", (int)Math.Round(taintRatio * 100)), taintRatio > 0.05 ? "aml_note" : "aml_dim");
}
private static readonly float[] StableW = { 80f, 100f, 220f };
private static readonly float[] StableWBase = new[] { 80f, 100f, 220f };
private static float[] StableW => Sc(StableWBase);
private static string StableStatus(Stablecoins st, string asset, int day)
{
@@ -250,7 +262,8 @@ namespace Decentralized
}
}
private static readonly float[] HoldW = { 80f, 100f, 110f, 110f };
private static readonly float[] HoldWBase = new[] { 80f, 100f, 110f, 110f };
private static float[] HoldW => Sc(HoldWBase);
private static readonly TextAnchor[] HoldAligns = { TextAnchor.MiddleLeft, TextAnchor.MiddleRight, TextAnchor.MiddleRight, TextAnchor.MiddleRight };
private static void Holdings(CustomUIBuilder b, Wallet w, Func<string, bool> show)
@@ -323,7 +336,8 @@ namespace Decentralized
private static string _perpProduct = "PSC";
private static bool _perpLong = true;
private static int _perpLev = 3;
private static readonly float[] PerpW = { 80f, 70f, 110f, 60f, 70f };
private static readonly float[] PerpWBase = new[] { 80f, 70f, 110f, 60f, 70f };
private static float[] PerpW => Sc(PerpWBase);
private static readonly TextAnchor[] PerpAligns = { TextAnchor.MiddleLeft, TextAnchor.MiddleRight, TextAnchor.MiddleRight, TextAnchor.MiddleRight, TextAnchor.MiddleRight };
private static double PerpSpot(string p) => p == "SPARK" ? Session.Data.Stable.Spark : Session.Data.Market.Price;
@@ -409,7 +423,8 @@ namespace Decentralized
});
}
private static readonly float[] PoolW = { 110f, 50f, 64f, 64f, 50f, 78f };
private static readonly float[] PoolWBase = new[] { 110f, 50f, 64f, 64f, 50f, 78f };
private static float[] PoolW => Sc(PoolWBase);
private static readonly TextAnchor[] PoolAligns = { TextAnchor.MiddleLeft, TextAnchor.MiddleRight, TextAnchor.MiddleRight, TextAnchor.MiddleRight, TextAnchor.MiddleRight, TextAnchor.MiddleRight };
/// <summary>第三方收益池:日息、储备、时间锁、审计、我的存款,存入 / 取出(合约调用,签名)。是不是骗局看不见。</summary>
@@ -804,7 +819,7 @@ namespace Decentralized
{
int tier = t;
r.AddButton(L.T("intel.tip.buy", (int)Math.Round(Tuning.IntelTipAcc[t] * 100), Fmt.Num(Tuning.IntelTipPrice[t] * m.MaxLoss)), () => IntelBuyTip(mk, tier));
r.Last?.SetPreferredSize(RightW - 30f, 28f);
r.Last?.SetPreferredSize(RightW - 30f, 28f * F);
if (t < 2) r.AddSpace(2f);
}
}
@@ -985,9 +1000,11 @@ namespace Decentralized
{
var d = Session.Data;
b.AddLabel(L.T("wallets.count", d.Wallets.Count, Tuning.WalletMax), "wallets_count_dim");
var cols = L.Wide ? new[] { 100f, 92f, 62f, 62f, 372f } : new[] { 100f, 110f, 85f, 70f, 375f };
bool wide = L.Wide && Ext < 100f;
float k = Ext < 100f ? 1f : (ScreenW - 28f) / 740f;
var cols = (wide ? new[] { 100f, 92f, 62f, 62f, 372f } : new[] { 100f, 110f, 85f, 70f, 375f }).Select(x => x * k).ToArray();
var aligns = new[] { TextAnchor.MiddleLeft, TextAnchor.MiddleLeft, TextAnchor.MiddleRight, TextAnchor.MiddleRight, TextAnchor.MiddleLeft };
TableHeader(b, 740f, cols, aligns, L.T("wallets.col.name"), L.T("wallets.col.addr"), L.T("col.value"), L.T("wallets.col.taint"), "");
TableHeader(b, 740f * k, cols, aligns, L.T("wallets.col.name"), L.T("wallets.col.addr"), L.T("col.value"), L.T("wallets.col.taint"), "");
for (int i = 0; i < d.Wallets.Count; i++)
{
var w = d.Wallets[i];
@@ -995,7 +1012,7 @@ namespace Decentralized
bool isCurrent = idx == d.Current;
// 一行三块:数据格(整行反色的是这一块)、操作键(和顶栏页签一样的黑色触控键,放在纸面上)、连接状态靠右
b.BeginRow(4f, TextAnchor.MiddleLeft);
b.BeginPanel(cols[0] + cols[1] + cols[2] + cols[3] + 8f, 32f, TextAnchor.MiddleLeft, 4f, 0f);
b.BeginPanel(cols[0] + cols[1] + cols[2] + cols[3] + 8f, 32f * F, TextAnchor.MiddleLeft, 4f, 0f);
_rows.Add(new PledgerSkin.RowDef
{
Root = b.Last.root,
@@ -1010,7 +1027,7 @@ namespace Decentralized
Cell(b, cols[3], Fmt.Credits(w.Taint), false, TextAnchor.MiddleRight);
b.End();
b.End();
b.BeginPanel(cols[4] - (L.Wide ? 112f : 150f), 32f, TextAnchor.MiddleLeft, 0f, 0f);
b.BeginPanel(cols[4] - (wide ? 112f : 150f) * k, 32f * F, TextAnchor.MiddleLeft, 0f, 0f);
_clear.Add(b.Last.image);
b.BeginRow(4f, TextAnchor.MiddleLeft);
RowKey(b, L.T("wallets.open"), () => WalletWindow.Open(w));
@@ -1019,7 +1036,7 @@ namespace Decentralized
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(L.Wide ? 92f : 84f, 32f, TextAnchor.MiddleRight, 0f, 0f);
b.BeginPanel((wide ? 92f : 84f) * k, 32f * F, 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(); });
@@ -1038,7 +1055,7 @@ namespace Decentralized
var go = b.Last.root;
if (go == null) return;
var le = go.GetComponent<LayoutElement>() ?? go.AddComponent<LayoutElement>();
le.minHeight = 26f; le.preferredHeight = 26f; le.flexibleHeight = 0f;
le.minHeight = 26f * F; le.preferredHeight = 26f * F; le.flexibleHeight = 0f;
}
private static string _destroyPick, _renamePick, _renameText = "";
@@ -1230,7 +1247,8 @@ namespace Decentralized
b.AddLabel(f.StartsWith("phish:") ? L.T("black.forum.phish", f.Substring(6)) : f.StartsWith("scam:") ? L.T("black.forum.scam", BlackDelivery.DisplayName(f.Substring(5))) : f.StartsWith("busted:") ? L.T("black.forum.busted", f.Substring(7)) : L.T("black.forum." + f), "forum_dim");
}
private const float SellerW = 176f, ShelfW = 560f;
private static float SellerW => 176f * F;
private static float ShelfW => 560f + Ext * 0.78f;
private static void PlatformShelf(CustomUIBuilder b, SaveData d)
{
@@ -1242,7 +1260,7 @@ namespace Decentralized
c.AddLabel(L.T("black.price", offer.Price));
c.AddFlexibleSpace();
c.AddButton(L.T("black.buy"), () => AddToCart(-1, offer));
}, 3);
});
}
// ——— 付款面板 ———
@@ -1425,7 +1443,7 @@ namespace Decentralized
c.AddLabel(L.T("black.price", g.Price));
c.AddFlexibleSpace();
c.AddButton(L.T("black.sell.list"), () => BeginEdit(new EditPrice { Item = it, Id = g.Item, Ref = BlackDelivery.RefValue(it) }, g.Price));
}, 3);
});
b.End();
b.End();
}
@@ -1725,12 +1743,14 @@ namespace Decentralized
}, 3);
}
private const int ShelfCols = 4;
private const float CardW = 172f, CardH = 268f;
private static int ShelfCols => Ext < 100f ? 3 : Math.Max(3, (int)Math.Round(ShelfW / (172f * F)));
private static float CardW => Ext < 100f ? 172f : (ShelfW - 6f * (ShelfCols - 1)) / ShelfCols;
private static float CardH => 268f * F;
/// <summary>货架:一行 4 张商品卡。</summary>
private static void Shelf(CustomUIBuilder b, System.Collections.Generic.List<BmGood> goods, Action<CustomUIBuilder, BmGood> card, int cols = ShelfCols)
private static void Shelf(CustomUIBuilder b, System.Collections.Generic.List<BmGood> goods, Action<CustomUIBuilder, BmGood> card, int cols = -1)
{
if (cols <= 0) cols = ShelfCols;
for (int i = 0; i < goods.Count; i += cols)
{
b.BeginRow(6f);
@@ -1755,7 +1775,7 @@ namespace Decentralized
var sprite = Icon(g.Item);
if (sprite != null) c.AddImage(sprite, 64f, 64f); else c.AddSpace(64f);
c.AddLabel("<b>" + ItemName(g.Item) + "</b>");
PledgerSkin.FitBox(c, 52f);
PledgerSkin.FitBox(c, 52f * F);
bool asic = g.Kind == GoodKind.Gpu && g.Model != null && Hardware.Specs.TryGetValue(g.Model, out var gs) && gs.Asic;
c.AddLabel(asic ? (g.Health >= 100 ? L.T("black.kind.asicnew") : L.T("black.kind.asic", (int)Math.Round(g.Health))) : g.Kind == GoodKind.Gpu ? (g.Health >= 100 ? L.T("black.kind.gpunew") : L.T("black.kind.gpu", (int)Math.Round(g.Health))) : L.T("black.kind." + g.Kind + (g.Kind == GoodKind.Contraband ? "." + g.Level : "")), "good_kind_dim");
if (!string.IsNullOrEmpty(line2)) c.AddLabel(line2, "good_line2_dim");
@@ -1902,14 +1922,14 @@ namespace Decentralized
{
var d = Session.Data;
b.BeginRow(8f, TextAnchor.UpperLeft);
b.BeginPanel(SellerW + 8f + 150f, -1f, TextAnchor.UpperLeft, 4f, 4f);
b.BeginPanel((SellerW + 8f + ShelfW) * 0.45f, -1f, TextAnchor.UpperLeft, 4f, 4f);
_clear.Add(b.Last.image);
b.AddHeader(L.T("black.orders.in"));
if (d.Black.Orders.Count == 0) b.AddLabel(L.T("black.mine.none"), "orders_in_none_dim");
foreach (var o in d.Black.Orders.OrderByDescending(x => x.PlacedDay))
b.AddLabel(L.T("black.mine.line", ItemName(o.Item) + (o.Count > 1 ? " ×" + o.Count : ""), BlackDelivery.DisplayName(o.Seller), L.T("black.mode." + o.Mode), L.T("black.state." + o.State + (o.Why != null && o.State != OrderState.Done ? "." + o.Why : "")), o.DueDay));
b.End();
b.BeginPanel(ShelfW - 150f, -1f, TextAnchor.UpperLeft, 4f, 4f);
b.BeginPanel((SellerW + 8f + ShelfW) * 0.55f, -1f, TextAnchor.UpperLeft, 4f, 4f);
_clear.Add(b.Last.image);
b.AddHeader(L.T("black.orders.out"));
if (d.Black.Sales.Count == 0) b.AddLabel(L.T("black.mine.none"), "orders_out_none_dim");
@@ -1979,7 +1999,8 @@ namespace Decentralized
private static Web3Tab _web3Tab = Web3Tab.Trade;
private static string _mixAsset = Assets.PSC;
private static int _mixRounds = 2;
private static readonly float[] MixW = { 70f, 100f, 100f, 80f };
private static readonly float[] MixWBase = new[] { 70f, 100f, 100f, 80f };
private static float[] MixW => Sc(MixWBase);
private static readonly TextAnchor[] MixAligns = { TextAnchor.MiddleLeft, TextAnchor.MiddleRight, TextAnchor.MiddleRight, TextAnchor.MiddleRight };
/// <summary>混币器:把币存进去,几轮之后提回同一个地址,污点降低,每轮扣手续费。</summary>
@@ -2048,7 +2069,8 @@ namespace Decentralized
Open();
}
private static readonly float[] StakeW = { 110f, 90f, 200f };
private static readonly float[] StakeWBase = new[] { 110f, 90f, 200f };
private static float[] StakeW => Sc(StakeWBase);
private static readonly TextAnchor[] StakeAligns = { TextAnchor.MiddleLeft, TextAnchor.MiddleRight, TextAnchor.MiddleRight };
/// <summary>质押页:革命军 CRA 质押池(日息、解锁排队)和平衡代币 SPARK 的铸销。都是合约调用,要在钱包上签名。</summary>