Terminal: two-column pages with table cells (holdings on the left, trading on the right)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a2dc1dd2f6
commit
00f7811e7c
3 files changed
+122
-39
No files matched your search
@@ -24,7 +24,6 @@ wallet.empty,The wallet is empty.
|
||||
wallet.total,Total value: {0} credits
|
||||
wallet.taint,Tainted value: {0} credits
|
||||
trade.amount,Amount
|
||||
trade.hint,Buy spends the amount in the quote coin. Sell sells the amount of the traded coin.
|
||||
trade.deposit,Deposit credits as CRC
|
||||
trade.withdraw,Withdraw CRC as credits
|
||||
trade.pair,"{0}/{1} ({2})"
|
||||
@@ -146,8 +145,21 @@ entry.web3.l2,"About {0} credits"
|
||||
bank.cash,"Credits: {0}"
|
||||
bank.rent,"Rent: {0} credits, due in {1} days"
|
||||
bank.crc,"Poinbase account (CRC): {0}"
|
||||
bank.hint,"Deposit turns credits into CRC; withdrawing turns CRC back into credits and passes compliance review."
|
||||
poin.account,"Poinbase account: CRC {0}, PSC {1}"
|
||||
avg.line,"{0} average buy price: {1} credits"
|
||||
avg.short,"avg. buy {0}"
|
||||
avg.none,"—"
|
||||
col.asset,"Asset"
|
||||
col.amount,"Amount"
|
||||
col.value,"Value"
|
||||
col.avg,"Avg. buy"
|
||||
bank.cash.k,"Credits"
|
||||
bank.rent.k,"Rent"
|
||||
bank.rent.v,"{0}, due in {1} days"
|
||||
bank.crc.k,"Poinbase account (CRC)"
|
||||
bank.ops,"Deposit / withdraw"
|
||||
poin.account.h,"Poinbase account"
|
||||
trade.h,"Trade"
|
||||
web3.wallet.h,"On-chain wallet"
|
||||
trade.hint,"Buying pays in the quote coin; |selling sells the traded coin."
|
||||
bank.hint,"Deposit turns credits into CRC; |withdrawing turns CRC back into credits |and passes compliance review."
|
||||
|
@@ -23,7 +23,6 @@ wallet.empty,钱包为空。
|
||||
wallet.total,总值:{0} 信用点
|
||||
wallet.taint,污点:{0} 信用点
|
||||
trade.amount,数量
|
||||
trade.hint,买入按计价币的数量支付;卖出按所交易币的数量卖出。
|
||||
trade.deposit,存入信用点(换成 CRC)
|
||||
trade.withdraw,提取 CRC(换成信用点)
|
||||
trade.pair,{0}/{1}({2})
|
||||
@@ -145,8 +144,21 @@ entry.web3.l2,"约 {0} 信用点"
|
||||
bank.cash,"信用点:{0}"
|
||||
bank.rent,"房租:{0} 信用点,{1} 天后支付"
|
||||
bank.crc,"Poinbase 账户(CRC):{0}"
|
||||
bank.hint,"存入把信用点换成 CRC,提取把 CRC 换回信用点,提取要过合规审查。"
|
||||
poin.account,"Poinbase 账户:CRC {0},PSC {1}"
|
||||
avg.line,"{0} 买入均价:{1} 信用点"
|
||||
avg.short,"买入均价 {0}"
|
||||
avg.none,"—"
|
||||
col.asset,"币种"
|
||||
col.amount,"数量"
|
||||
col.value,"估值"
|
||||
col.avg,"买入均价"
|
||||
bank.cash.k,"信用点"
|
||||
bank.rent.k,"房租"
|
||||
bank.rent.v,"{0},{1} 天后支付"
|
||||
bank.crc.k,"Poinbase 账户(CRC)"
|
||||
bank.ops,"存取"
|
||||
poin.account.h,"Poinbase 账户"
|
||||
trade.h,"交易"
|
||||
web3.wallet.h,"链上钱包"
|
||||
trade.hint,"买入按计价币的数量支付;|卖出按所交易币的数量卖出。"
|
||||
bank.hint,"存入把信用点换成 CRC;|提取把 CRC 换回信用点,|提取要过合规审查。"
|
||||
|
@@ -24,7 +24,7 @@ namespace Decentralized
|
||||
if (Session.Data == null) return;
|
||||
var b = CustomUIManager.Window(Id, L.T("term.title"));
|
||||
if (b == null) return;
|
||||
b.SetSize(640, 580).SetDraggable(true).SetCloseOnEscape(true).UseMachineryStyle();
|
||||
b.SetSize(780, 580).SetDraggable(true).SetCloseOnEscape(true).UseMachineryStyle();
|
||||
b.BeginRow();
|
||||
foreach (Page p in Enum.GetValues(typeof(Page)))
|
||||
{
|
||||
@@ -52,7 +52,7 @@ namespace Decentralized
|
||||
|
||||
private static void Entry(CustomUIBuilder b, string icon, string name, string line1, string line2, Page target)
|
||||
{
|
||||
b.BeginPanel(190f, 250f, TextAnchor.UpperCenter, 10f, 6f);
|
||||
b.BeginPanel(220f, 250f, TextAnchor.UpperCenter, 10f, 6f);
|
||||
b.AddImage(ModInfo.Id + ":" + icon, 96f, 96f);
|
||||
b.AddHeader(name);
|
||||
b.AddLabel(line1);
|
||||
@@ -79,31 +79,69 @@ namespace Decentralized
|
||||
b.AddLabel(r == null ? L.T("report.none") : L.T("home.lastnight", r.Day, Fmt.Num(r.Mined), r.PoweredRigs, r.Rigs));
|
||||
}
|
||||
|
||||
private const float LeftW = 430f, RightW = 300f;
|
||||
|
||||
private static void Cell(CustomUIBuilder b, float w, string text, bool header = false)
|
||||
{
|
||||
b.BeginPanel(w, 30f, TextAnchor.MiddleLeft, 6f, 0f);
|
||||
b.AddLabel(header ? "<b>" + text + "</b>" : text);
|
||||
b.End();
|
||||
}
|
||||
|
||||
private static void TableRow(CustomUIBuilder b, float[] widths, params string[] cells)
|
||||
{
|
||||
b.BeginRow(2f);
|
||||
for (int i = 0; i < widths.Length; i++) Cell(b, widths[i], i < cells.Length ? cells[i] : "");
|
||||
b.End();
|
||||
}
|
||||
|
||||
private static void TableHeader(CustomUIBuilder b, float[] widths, params string[] cells)
|
||||
{
|
||||
b.BeginRow(2f);
|
||||
for (int i = 0; i < widths.Length; i++) Cell(b, widths[i], cells[i], true);
|
||||
b.End();
|
||||
}
|
||||
|
||||
/// <summary>左右分栏:左边是账户与持仓表格,右边是操作区。</summary>
|
||||
private static void Columns(CustomUIBuilder b, Action<CustomUIBuilder> left, Action<CustomUIBuilder> right)
|
||||
{
|
||||
b.BeginRow(10f);
|
||||
b.BeginPanel(LeftW, -1f, TextAnchor.UpperLeft, 8f, 4f);
|
||||
left(b);
|
||||
b.End();
|
||||
b.BeginPanel(RightW, -1f, TextAnchor.UpperLeft, 8f, 6f);
|
||||
right(b);
|
||||
b.End();
|
||||
b.End();
|
||||
}
|
||||
|
||||
private static void AmountRow(CustomUIBuilder b)
|
||||
{
|
||||
b.BeginRow();
|
||||
b.AddLabel(L.T("trade.amount"));
|
||||
b.BeginPanel(240f, -1f, TextAnchor.MiddleCenter, 0f, 0f); // 给输入框一个固定宽度,容得下大额数字
|
||||
b.BeginPanel(RightW - 30f, -1f, TextAnchor.MiddleCenter, 0f, 0f); // 给输入框一个固定宽度,容得下大额数字
|
||||
b.AddInput("0", _amount, s => _amount = s, "amount", s => _amount = s);
|
||||
b.End();
|
||||
b.End();
|
||||
}
|
||||
|
||||
/// <summary>银行:真实的信用点。现金、房租,以及信用点与 Poinbase 账户(CRC)之间的存取。</summary>
|
||||
private static void BankPage(CustomUIBuilder b)
|
||||
{
|
||||
var ps = PlayerStore.Instance;
|
||||
b.AddHeader(L.T("entry.bank"));
|
||||
b.AddLabel(L.T("bank.cash", ps.playerCash));
|
||||
b.AddLabel(L.T("bank.rent", Session.Rent(), ps.GetRentDayCounter()));
|
||||
b.AddLabel(L.T("bank.crc", Fmt.Num(Session.Data.Hot.Get(Assets.CRC))));
|
||||
b.AddSeparator();
|
||||
b.AddLabel(L.T("bank.hint"));
|
||||
AmountRow(b);
|
||||
b.BeginRow();
|
||||
b.AddButton(L.T("trade.deposit"), Deposit);
|
||||
b.AddButton(L.T("trade.withdraw"), Withdraw);
|
||||
b.End();
|
||||
var w = new[] { 200f, 220f };
|
||||
Columns(b, l =>
|
||||
{
|
||||
l.AddHeader(L.T("entry.bank"));
|
||||
TableRow(l, w, L.T("bank.cash.k"), ps.playerCash.ToString());
|
||||
TableRow(l, w, L.T("bank.rent.k"), L.T("bank.rent.v", Session.Rent(), ps.GetRentDayCounter()));
|
||||
TableRow(l, w, L.T("bank.crc.k"), Fmt.Num(Session.Data.Hot.Get(Assets.CRC)));
|
||||
}, r =>
|
||||
{
|
||||
r.AddHeader(L.T("bank.ops"));
|
||||
foreach (var line in L.T("bank.hint").Split('|')) r.AddLabel(line);
|
||||
AmountRow(r);
|
||||
r.AddButton(L.T("trade.deposit"), Deposit);
|
||||
r.AddButton(L.T("trade.withdraw"), Withdraw);
|
||||
});
|
||||
}
|
||||
|
||||
private static void TradeRows(CustomUIBuilder b, Venue venue)
|
||||
@@ -119,34 +157,55 @@ namespace Decentralized
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Poinbase:合规交易所。账户余额与交易对;信用点的存取在银行。</summary>
|
||||
private static readonly float[] HoldW = { 80f, 100f, 110f, 110f };
|
||||
|
||||
private static void Holdings(CustomUIBuilder b, Wallet w, Func<string, bool> show)
|
||||
{
|
||||
TableHeader(b, HoldW, L.T("col.asset"), L.T("col.amount"), L.T("col.value"), L.T("col.avg"));
|
||||
bool any = false;
|
||||
foreach (var kv in w.Balances.OrderBy(k => k.Key).Where(k => show(k.Key)))
|
||||
{
|
||||
any = true;
|
||||
TableRow(b, HoldW, kv.Key, Fmt.Num(kv.Value), Fmt.Credits(kv.Value * Session.Price(kv.Key)), AvgText(w, kv.Key));
|
||||
}
|
||||
if (!any) b.AddLabel(L.T("wallet.empty"));
|
||||
}
|
||||
|
||||
/// <summary>Poinbase:合规交易所。左边账户持仓,右边交易;信用点的存取在银行。</summary>
|
||||
private static void ExchangePage(CustomUIBuilder b, Venue venue)
|
||||
{
|
||||
var w = Session.Data.Hot;
|
||||
b.AddHeader(L.T("entry.poinbase"));
|
||||
b.AddLabel(L.T("poin.account", Fmt.Num(w.Get(Assets.CRC)), Fmt.Num(w.Get(Assets.PSC))));
|
||||
b.AddLabel(L.T("avg.line", Assets.PSC, AvgText(w, Assets.PSC)));
|
||||
b.AddLabel(L.T("trade.hint"));
|
||||
AmountRow(b);
|
||||
b.AddSeparator();
|
||||
TradeRows(b, venue);
|
||||
Columns(b, l =>
|
||||
{
|
||||
l.AddHeader(L.T("poin.account.h"));
|
||||
Holdings(l, w, a => a == Assets.CRC || a == Assets.PSC);
|
||||
}, r =>
|
||||
{
|
||||
r.AddHeader(L.T("trade.h"));
|
||||
foreach (var line in L.T("trade.hint").Split('|')) r.AddLabel(line);
|
||||
AmountRow(r);
|
||||
TradeRows(r, venue);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Web3:链上钱包与去中心化交易。</summary>
|
||||
private static void Web3Page(CustomUIBuilder b)
|
||||
{
|
||||
var w = Session.Data.Hot;
|
||||
b.AddHeader(L.T("entry.web3"));
|
||||
if (w.Balances.Count == 0) b.AddLabel(L.T("wallet.empty"));
|
||||
foreach (var kv in w.Balances.OrderBy(k => k.Key))
|
||||
b.AddLabel(L.T("wallet.line", kv.Key, Fmt.Num(kv.Value), Fmt.Credits(kv.Value * Session.Price(kv.Key))) + " " + L.T("avg.short", AvgText(w, kv.Key)));
|
||||
b.AddLabel(L.T("wallet.total", Fmt.Credits(w.Value(Session.Price))));
|
||||
if (w.Taint > 0.5) b.AddLabel(L.T("wallet.taint", Fmt.Credits(w.Taint)));
|
||||
b.AddSeparator();
|
||||
b.AddLabel(L.T("trade.hint"));
|
||||
AmountRow(b);
|
||||
b.AddSeparator();
|
||||
TradeRows(b, Venue.Dex);
|
||||
Columns(b, l =>
|
||||
{
|
||||
l.AddHeader(L.T("web3.wallet.h"));
|
||||
Holdings(l, w, a => true);
|
||||
l.AddSeparator();
|
||||
l.AddLabel(L.T("wallet.total", Fmt.Credits(w.Value(Session.Price))));
|
||||
if (w.Taint > 0.5) l.AddLabel(L.T("wallet.taint", Fmt.Credits(w.Taint)));
|
||||
}, r =>
|
||||
{
|
||||
r.AddHeader(L.T("trade.h"));
|
||||
foreach (var line in L.T("trade.hint").Split('|')) r.AddLabel(line);
|
||||
AmountRow(r);
|
||||
TradeRows(r, Venue.Dex);
|
||||
});
|
||||
}
|
||||
|
||||
private static string AvgText(Wallet w, string asset) => w.AvgBuy(asset) is double a ? Fmt.Num(a) : L.T("avg.none");
|
||||
|
||||
Reference in new issue
Block a user