|
|
|
|
@ -116,17 +116,35 @@ function makeVScroll(parent: Node, w: number, h: number): { host: Node; content: |
|
|
|
|
return { host, content }; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const ITEM_C = { |
|
|
|
|
text: new Color(255, 255, 255, 255), |
|
|
|
|
dim: new Color(170, 185, 210, 255), |
|
|
|
|
accent: new Color(255, 220, 70, 255), |
|
|
|
|
card: new Color(28, 36, 56, 255), |
|
|
|
|
cellBg: new Color(18, 24, 40, 255), |
|
|
|
|
cellLine: new Color(90, 120, 170, 160), |
|
|
|
|
selLine: new Color(255, 220, 70, 255), |
|
|
|
|
selBg: new Color(48, 42, 18, 255), |
|
|
|
|
btn: new Color(45, 105, 190, 255), |
|
|
|
|
btnHot: new Color(18, 92, 78, 255), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 道具图标点选 + 数量步进。 |
|
|
|
|
*/ |
|
|
|
|
class GmItemPickerPanel implements IGmContentPanel { |
|
|
|
|
private _root: Node | null = null; |
|
|
|
|
private _ctx: IGmPanelContext | null = null; |
|
|
|
|
private _selectedId = 0; |
|
|
|
|
private _qty = 1; |
|
|
|
|
private _lbSel: Label | null = null; |
|
|
|
|
private _selectedName = ''; |
|
|
|
|
private _lbHead: Label | null = null; |
|
|
|
|
private _lbQty: Label | null = null; |
|
|
|
|
private _cells: { [id: number]: Node } = {}; |
|
|
|
|
private _cellSz = 76; |
|
|
|
|
|
|
|
|
|
open(parent: Node, ctx: IGmPanelContext): void { |
|
|
|
|
this.close(); |
|
|
|
|
this._ctx = ctx; |
|
|
|
|
const pUt = parent.getComponent(UITransform); |
|
|
|
|
const W = pUt?.width || 660; |
|
|
|
|
const H = pUt?.height || 900; |
|
|
|
|
@ -139,117 +157,202 @@ class GmItemPickerPanel implements IGmContentPanel { |
|
|
|
|
rw.left = rw.right = rw.top = rw.bottom = 0; |
|
|
|
|
parent.addChild(this._root); |
|
|
|
|
|
|
|
|
|
const tip = new Node('tip'); |
|
|
|
|
tip.layer = Layers.Enum.UI_2D; |
|
|
|
|
tip.addComponent(UITransform).setContentSize(W - 24, 40); |
|
|
|
|
const tl = tip.addComponent(Label); |
|
|
|
|
tl.string = '点图标立刻 +1 · 底部可一次 +10/+100'; |
|
|
|
|
tl.fontSize = 22; |
|
|
|
|
tl.color = new Color(255, 196, 72, 255); |
|
|
|
|
tl.horizontalAlign = HorizontalTextAlignment.CENTER; |
|
|
|
|
tip.setPosition(0, H / 2 - 28); |
|
|
|
|
this._root.addChild(tip); |
|
|
|
|
|
|
|
|
|
const barH = 120; |
|
|
|
|
const scrollH = H - 80 - barH; |
|
|
|
|
const headH = 88; |
|
|
|
|
const barH = 108; |
|
|
|
|
const head = new Node('head'); |
|
|
|
|
head.layer = Layers.Enum.UI_2D; |
|
|
|
|
head.addComponent(UITransform).setContentSize(W - 16, headH); |
|
|
|
|
this._drawRound(head, ITEM_C.card, W - 16, headH, 14, ITEM_C.selLine); |
|
|
|
|
head.setPosition(0, H / 2 - headH / 2 - 4); |
|
|
|
|
this._root.addChild(head); |
|
|
|
|
|
|
|
|
|
this._lbHead = this._makeLb(head, '点击道具图标:选中并 +1', W - 40, 32, 24, ITEM_C.accent); |
|
|
|
|
this._lbHead.node.setPosition(0, 18); |
|
|
|
|
this._lbQty = this._makeLb(head, '底部可一次 +10 / +100', W - 40, 28, 20, ITEM_C.dim); |
|
|
|
|
this._lbQty.node.setPosition(0, -18); |
|
|
|
|
|
|
|
|
|
const scrollH = H - headH - barH - 16; |
|
|
|
|
const { host, content } = makeVScroll(this._root, W - 16, scrollH); |
|
|
|
|
host.setPosition(0, barH / 2 - 10); |
|
|
|
|
host.setPosition(0, (barH - headH) / 2); |
|
|
|
|
|
|
|
|
|
const items = gg.data.table.getTableList<ITableItem>(TableNames.Item) ?? []; |
|
|
|
|
items.sort((a, b) => Number(a.id) - Number(b.id)); |
|
|
|
|
const cell = 80; |
|
|
|
|
const cols = Math.max(4, Math.floor((W - 24) / (cell + 6))); |
|
|
|
|
const gap = 8; |
|
|
|
|
this._cellSz = 76; |
|
|
|
|
const cols = Math.max(4, Math.floor((W - 24) / (this._cellSz + gap))); |
|
|
|
|
let rowNode: Node | null = null; |
|
|
|
|
for (let i = 0; i < items.length; i++) { |
|
|
|
|
if (i % cols === 0) { |
|
|
|
|
rowNode = new Node(`row${i}`); |
|
|
|
|
rowNode.layer = Layers.Enum.UI_2D; |
|
|
|
|
rowNode.addComponent(UITransform).setContentSize(W - 24, cell); |
|
|
|
|
rowNode.addComponent(UITransform).setContentSize(W - 24, this._cellSz); |
|
|
|
|
const lay = rowNode.addComponent(Layout); |
|
|
|
|
lay.type = Layout.Type.HORIZONTAL; |
|
|
|
|
lay.spacingX = 6; |
|
|
|
|
lay.spacingX = gap; |
|
|
|
|
content.addChild(rowNode); |
|
|
|
|
} |
|
|
|
|
const row = items[i]; |
|
|
|
|
const cellN = new Node(`i${row.id}`); |
|
|
|
|
cellN.layer = Layers.Enum.UI_2D; |
|
|
|
|
cellN.addComponent(UITransform).setContentSize(cell - 4, cell - 4); |
|
|
|
|
const sp = cellN.addComponent(Sprite); |
|
|
|
|
sp.sizeMode = Sprite.SizeMode.CUSTOM; |
|
|
|
|
const loader = cellN.addComponent(SpriteLoad); |
|
|
|
|
if (row.icon) loader.setSprite(GPath.Item(row.icon), GBundle.Items); |
|
|
|
|
cellN.addComponent(Button); |
|
|
|
|
const id = Number(row.id); |
|
|
|
|
const name = row.name ?? ''; |
|
|
|
|
cellN.on(Button.EventType.CLICK, () => { |
|
|
|
|
this._selectedId = id; |
|
|
|
|
ProjectGmActions.addItemNum(id, 1); |
|
|
|
|
this._qty = gg.data.getItemNum(id); |
|
|
|
|
this._paint(); |
|
|
|
|
ctx.host.toast(`${name} +1 → ${this._qty}`); |
|
|
|
|
}, this); |
|
|
|
|
const cellN = this._makeCell(id, name, row.icon); |
|
|
|
|
rowNode!.addChild(cellN); |
|
|
|
|
this._cells[id] = cellN; |
|
|
|
|
} |
|
|
|
|
content.getComponent(Layout)?.updateLayout(); |
|
|
|
|
|
|
|
|
|
const bar = new Node('bar'); |
|
|
|
|
bar.layer = Layers.Enum.UI_2D; |
|
|
|
|
bar.addComponent(UITransform).setContentSize(W - 16, barH - 16); |
|
|
|
|
bar.addComponent(UITransform).setContentSize(W - 16, barH - 12); |
|
|
|
|
this._drawRound(bar, ITEM_C.card, W - 16, barH - 12, 14, ITEM_C.cellLine); |
|
|
|
|
bar.setPosition(0, -H / 2 + barH / 2); |
|
|
|
|
this._root.addChild(bar); |
|
|
|
|
|
|
|
|
|
this._lbSel = (() => { |
|
|
|
|
const sel = new Node('sel'); |
|
|
|
|
sel.layer = Layers.Enum.UI_2D; |
|
|
|
|
sel.addComponent(UITransform).setContentSize(W - 40, 28); |
|
|
|
|
const lb = sel.addComponent(Label); |
|
|
|
|
lb.fontSize = 20; |
|
|
|
|
lb.color = new Color(180, 220, 255, 255); |
|
|
|
|
lb.horizontalAlign = HorizontalTextAlignment.CENTER; |
|
|
|
|
lb.overflow = Overflow.SHRINK; |
|
|
|
|
sel.setPosition(0, 28); |
|
|
|
|
bar.addChild(sel); |
|
|
|
|
return lb; |
|
|
|
|
})(); |
|
|
|
|
makeLabelBtn(bar, '+10', 100, 44, () => { |
|
|
|
|
if (!this._selectedId) { |
|
|
|
|
ctx.host.toast('先点一个图标'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
ProjectGmActions.addItemNum(this._selectedId, 10); |
|
|
|
|
this._qty = gg.data.getItemNum(this._selectedId); |
|
|
|
|
this._paint(); |
|
|
|
|
}).setPosition(-160, -16); |
|
|
|
|
|
|
|
|
|
makeLabelBtn(bar, '+100', 100, 44, () => { |
|
|
|
|
if (!this._selectedId) { |
|
|
|
|
ctx.host.toast('先点一个图标'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
ProjectGmActions.addItemNum(this._selectedId, 100); |
|
|
|
|
this._qty = gg.data.getItemNum(this._selectedId); |
|
|
|
|
this._paint(); |
|
|
|
|
}).setPosition(-40, -16); |
|
|
|
|
|
|
|
|
|
makeLabelBtn(bar, '返回', 120, 44, () => { |
|
|
|
|
ctx.refreshList(); |
|
|
|
|
ctx.goBack(); |
|
|
|
|
}).setPosition(120, -16); |
|
|
|
|
const embedded = !!ctx.embedded; |
|
|
|
|
const btnY = 0; |
|
|
|
|
this._pill(bar, '+10', 120, 48, ITEM_C.btnHot, () => this._addQty(10)).setPosition(embedded ? -140 : -180, btnY); |
|
|
|
|
this._pill(bar, '+100', 120, 48, ITEM_C.btn, () => this._addQty(100)).setPosition(embedded ? 140 : -40, btnY); |
|
|
|
|
if (!embedded) { |
|
|
|
|
this._pill(bar, '返回', 110, 48, new Color(70, 78, 96, 255), () => { |
|
|
|
|
ctx.refreshList(); |
|
|
|
|
ctx.goBack(); |
|
|
|
|
}).setPosition(160, btnY); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this._paint(); |
|
|
|
|
this._paintSel(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
close(): void { |
|
|
|
|
if (this._root?.isValid) this._root.destroy(); |
|
|
|
|
this._root = null; |
|
|
|
|
this._lbSel = null; |
|
|
|
|
this._ctx = null; |
|
|
|
|
this._lbHead = null; |
|
|
|
|
this._lbQty = null; |
|
|
|
|
this._cells = {}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private _paint(): void { |
|
|
|
|
if (this._lbSel) { |
|
|
|
|
this._lbSel.string = this._selectedId |
|
|
|
|
? `最近:${this._selectedId} 持有 ${gg.data.getItemNum(this._selectedId)}` |
|
|
|
|
: '点图标立刻 +1'; |
|
|
|
|
private _makeCell(id: number, name: string, icon: string | undefined): Node { |
|
|
|
|
const sz = this._cellSz; |
|
|
|
|
const cellN = new Node(`i${id}`); |
|
|
|
|
cellN.layer = Layers.Enum.UI_2D; |
|
|
|
|
cellN.addComponent(UITransform).setContentSize(sz, sz); |
|
|
|
|
this._drawRound(cellN, ITEM_C.cellBg, sz, sz, 12, ITEM_C.cellLine); |
|
|
|
|
|
|
|
|
|
const iconN = new Node('icon'); |
|
|
|
|
iconN.layer = Layers.Enum.UI_2D; |
|
|
|
|
iconN.addComponent(UITransform).setContentSize(sz - 16, sz - 16); |
|
|
|
|
const sp = iconN.addComponent(Sprite); |
|
|
|
|
sp.sizeMode = Sprite.SizeMode.CUSTOM; |
|
|
|
|
const loader = iconN.addComponent(SpriteLoad); |
|
|
|
|
if (icon) loader.setSprite(GPath.Item(icon), GBundle.Items); |
|
|
|
|
cellN.addChild(iconN); |
|
|
|
|
|
|
|
|
|
const badge = new Node('qty'); |
|
|
|
|
badge.layer = Layers.Enum.UI_2D; |
|
|
|
|
badge.addComponent(UITransform).setContentSize(sz - 8, 20); |
|
|
|
|
const bl = badge.addComponent(Label); |
|
|
|
|
bl.string = `${gg.data.getItemNum(id)}`; |
|
|
|
|
bl.fontSize = 16; |
|
|
|
|
bl.isBold = true; |
|
|
|
|
bl.color = ITEM_C.accent; |
|
|
|
|
bl.horizontalAlign = HorizontalTextAlignment.RIGHT; |
|
|
|
|
bl.verticalAlign = VerticalTextAlignment.CENTER; |
|
|
|
|
bl.overflow = Overflow.SHRINK; |
|
|
|
|
badge.setPosition(0, -sz / 2 + 12); |
|
|
|
|
cellN.addChild(badge); |
|
|
|
|
|
|
|
|
|
cellN.addComponent(Button); |
|
|
|
|
cellN.on(Button.EventType.CLICK, () => { |
|
|
|
|
this._selectedId = id; |
|
|
|
|
this._selectedName = name; |
|
|
|
|
ProjectGmActions.addItemNum(id, 1); |
|
|
|
|
this._paintSel(); |
|
|
|
|
this._ctx?.host.toast(`${name} +1 → ${gg.data.getItemNum(id)}`); |
|
|
|
|
}, this); |
|
|
|
|
return cellN; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private _addQty(delta: number): void { |
|
|
|
|
if (!this._selectedId) { |
|
|
|
|
this._ctx?.host.toast('先点选一个道具'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
ProjectGmActions.addItemNum(this._selectedId, delta); |
|
|
|
|
this._paintSel(); |
|
|
|
|
this._ctx?.host.toast(`${this._selectedName || this._selectedId} +${delta}`); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private _paintSel(): void { |
|
|
|
|
const ids = Object.keys(this._cells); |
|
|
|
|
for (let i = 0; i < ids.length; i++) { |
|
|
|
|
const id = Number(ids[i]); |
|
|
|
|
const cell = this._cells[id]; |
|
|
|
|
if (!cell?.isValid) continue; |
|
|
|
|
const on = id === this._selectedId; |
|
|
|
|
this._drawRound(cell, on ? ITEM_C.selBg : ITEM_C.cellBg, this._cellSz, this._cellSz, 12, on ? ITEM_C.selLine : ITEM_C.cellLine); |
|
|
|
|
const qtyLb = cell.getChildByName('qty')?.getComponent(Label); |
|
|
|
|
if (qtyLb) qtyLb.string = `${gg.data.getItemNum(id)}`; |
|
|
|
|
} |
|
|
|
|
if (this._lbHead) { |
|
|
|
|
this._lbHead.string = this._selectedId |
|
|
|
|
? `已选 · ${this._selectedId} ${this._selectedName}` |
|
|
|
|
: '点击道具图标:选中并 +1'; |
|
|
|
|
} |
|
|
|
|
if (this._lbQty) { |
|
|
|
|
this._lbQty.string = this._selectedId |
|
|
|
|
? `持有 ${gg.data.getItemNum(this._selectedId)} · 点图标再 +1` |
|
|
|
|
: '底部可一次 +10 / +100'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private _makeLb(parent: Node, text: string, w: number, h: number, size: number, color: Color): Label { |
|
|
|
|
const n = new Node('lb'); |
|
|
|
|
n.layer = Layers.Enum.UI_2D; |
|
|
|
|
n.addComponent(UITransform).setContentSize(w, h); |
|
|
|
|
const lb = n.addComponent(Label); |
|
|
|
|
lb.string = text; |
|
|
|
|
lb.fontSize = size; |
|
|
|
|
lb.isBold = true; |
|
|
|
|
lb.color = color; |
|
|
|
|
lb.horizontalAlign = HorizontalTextAlignment.CENTER; |
|
|
|
|
lb.verticalAlign = VerticalTextAlignment.CENTER; |
|
|
|
|
lb.overflow = Overflow.SHRINK; |
|
|
|
|
parent.addChild(n); |
|
|
|
|
return lb; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private _pill(parent: Node, text: string, w: number, h: number, bg: Color, onClick: () => void): Node { |
|
|
|
|
const n = new Node(text); |
|
|
|
|
n.layer = Layers.Enum.UI_2D; |
|
|
|
|
n.addComponent(UITransform).setContentSize(w, h); |
|
|
|
|
this._drawRound(n, bg, w, h, 12); |
|
|
|
|
const lbN = new Node('lb'); |
|
|
|
|
lbN.layer = Layers.Enum.UI_2D; |
|
|
|
|
lbN.addComponent(UITransform).setContentSize(w - 6, h - 4); |
|
|
|
|
const lb = lbN.addComponent(Label); |
|
|
|
|
lb.string = text; |
|
|
|
|
lb.fontSize = 24; |
|
|
|
|
lb.isBold = true; |
|
|
|
|
lb.color = ITEM_C.text; |
|
|
|
|
lb.horizontalAlign = HorizontalTextAlignment.CENTER; |
|
|
|
|
lb.verticalAlign = VerticalTextAlignment.CENTER; |
|
|
|
|
n.addChild(lbN); |
|
|
|
|
n.addComponent(Button); |
|
|
|
|
n.on(Button.EventType.CLICK, onClick, this); |
|
|
|
|
parent.addChild(n); |
|
|
|
|
return n; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private _drawRound(node: Node, fill: Color, w: number, h: number, r: number, stroke?: Color): void { |
|
|
|
|
const g = node.getComponent(Graphics) || node.addComponent(Graphics); |
|
|
|
|
g.clear(); |
|
|
|
|
g.fillColor = fill; |
|
|
|
|
g.roundRect(-w / 2, -h / 2, w, h, r); |
|
|
|
|
g.fill(); |
|
|
|
|
if (stroke) { |
|
|
|
|
g.strokeColor = stroke; |
|
|
|
|
g.lineWidth = stroke === ITEM_C.selLine ? 3 : 2; |
|
|
|
|
g.roundRect(-w / 2, -h / 2, w, h, r); |
|
|
|
|
g.stroke(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -575,26 +678,39 @@ class GmLevelPickerPanel implements IGmContentPanel { |
|
|
|
|
|
|
|
|
|
open(parent: Node, ctx: IGmPanelContext): void { |
|
|
|
|
this.close(); |
|
|
|
|
const pUt = parent.getComponent(UITransform); |
|
|
|
|
const W = pUt?.width || 660; |
|
|
|
|
const H = pUt?.height || 900; |
|
|
|
|
const cur = ProjectGmActions.fixedMapSummary(); |
|
|
|
|
|
|
|
|
|
this._root = new Node('levelPicker'); |
|
|
|
|
this._root.layer = Layers.Enum.UI_2D; |
|
|
|
|
this._root.addComponent(UITransform).setContentSize(660, 900); |
|
|
|
|
this._root.addComponent(UITransform).setContentSize(W, H); |
|
|
|
|
const rw = this._root.addComponent(Widget); |
|
|
|
|
rw.isAlignLeft = rw.isAlignRight = rw.isAlignTop = rw.isAlignBottom = true; |
|
|
|
|
rw.left = rw.right = rw.top = rw.bottom = 0; |
|
|
|
|
parent.addChild(this._root); |
|
|
|
|
|
|
|
|
|
const title = new Node('t'); |
|
|
|
|
title.layer = Layers.Enum.UI_2D; |
|
|
|
|
title.addComponent(UITransform).setContentSize(600, 36); |
|
|
|
|
const tl = title.addComponent(Label); |
|
|
|
|
tl.string = ctx.command.title; |
|
|
|
|
tl.fontSize = 26; |
|
|
|
|
tl.color = Color.WHITE; |
|
|
|
|
tl.horizontalAlign = HorizontalTextAlignment.CENTER; |
|
|
|
|
title.setPosition(0, 420); |
|
|
|
|
this._root.addChild(title); |
|
|
|
|
|
|
|
|
|
const { host, content } = makeVScroll(this._root, 640, 700); |
|
|
|
|
host.setPosition(0, 20); |
|
|
|
|
|
|
|
|
|
makeLabelBtn(content, '0 关闭固定(随机)', 620, 44, () => { |
|
|
|
|
const head = new Node('head'); |
|
|
|
|
head.layer = Layers.Enum.UI_2D; |
|
|
|
|
head.addComponent(UITransform).setContentSize(W - 16, 72); |
|
|
|
|
const hl = head.addComponent(Label); |
|
|
|
|
hl.string = `固定地图 · 当前 ${cur}`; |
|
|
|
|
hl.fontSize = 26; |
|
|
|
|
hl.isBold = true; |
|
|
|
|
hl.color = new Color(255, 220, 70, 255); |
|
|
|
|
hl.horizontalAlign = HorizontalTextAlignment.CENTER; |
|
|
|
|
hl.verticalAlign = VerticalTextAlignment.CENTER; |
|
|
|
|
head.setPosition(0, H / 2 - 40); |
|
|
|
|
this._root.addChild(head); |
|
|
|
|
|
|
|
|
|
const footH = 72; |
|
|
|
|
const { host, content } = makeVScroll(this._root, W - 16, H - 120 - footH); |
|
|
|
|
const lay = content.getComponent(Layout); |
|
|
|
|
if (lay) lay.spacingY = 8; |
|
|
|
|
host.setPosition(0, footH / 2 - 20); |
|
|
|
|
|
|
|
|
|
makeLabelBtn(content, '0 关闭固定(随机)', W - 40, 52, () => { |
|
|
|
|
ProjectGmActions.setFixedMap(0); |
|
|
|
|
ctx.refreshList(); |
|
|
|
|
ctx.goBack(); |
|
|
|
|
@ -606,14 +722,14 @@ class GmLevelPickerPanel implements IGmContentPanel { |
|
|
|
|
const row = list[i]; |
|
|
|
|
const id = Number(row.id); |
|
|
|
|
const name = row.name ?? ''; |
|
|
|
|
makeLabelBtn(content, `${id} ${name}`, 620, 44, () => { |
|
|
|
|
makeLabelBtn(content, `${id} ${name}`, W - 40, 52, () => { |
|
|
|
|
ProjectGmActions.setFixedMap(id); |
|
|
|
|
ctx.refreshList(); |
|
|
|
|
ctx.goBack(); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
content.getComponent(Layout)?.updateLayout(); |
|
|
|
|
makeLabelBtn(this._root, '返回', 140, 44, () => ctx.goBack()).setPosition(0, -400); |
|
|
|
|
makeLabelBtn(this._root, '返回', 160, 48, () => ctx.goBack()).setPosition(0, -H / 2 + footH / 2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
close(): void { |
|
|
|
|
@ -622,6 +738,21 @@ class GmLevelPickerPanel implements IGmContentPanel { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const RANK_C = { |
|
|
|
|
text: new Color(255, 255, 255, 255), |
|
|
|
|
dim: new Color(170, 185, 210, 255), |
|
|
|
|
accent: new Color(255, 220, 70, 255), |
|
|
|
|
card: new Color(28, 36, 56, 255), |
|
|
|
|
row: new Color(22, 30, 48, 255), |
|
|
|
|
rowLine: new Color(90, 120, 170, 140), |
|
|
|
|
selBg: new Color(48, 42, 18, 255), |
|
|
|
|
selLine: new Color(255, 220, 70, 255), |
|
|
|
|
btn: new Color(45, 105, 190, 255), |
|
|
|
|
btnHot: new Color(18, 92, 78, 255), |
|
|
|
|
starOn: new Color(255, 200, 60, 255), |
|
|
|
|
starOff: new Color(80, 88, 110, 255), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 段位点选 + 星级步进。 |
|
|
|
|
*/ |
|
|
|
|
@ -629,41 +760,52 @@ class GmRankPickerPanel implements IGmContentPanel { |
|
|
|
|
private _root: Node | null = null; |
|
|
|
|
private _rankId = 1; |
|
|
|
|
private _star = 1; |
|
|
|
|
private _lb: Label | null = null; |
|
|
|
|
private _rankName = ''; |
|
|
|
|
private _lbHead: Label | null = null; |
|
|
|
|
private _lbStar: Label | null = null; |
|
|
|
|
private _listW = 640; |
|
|
|
|
private _rows: { [id: number]: Node } = {}; |
|
|
|
|
|
|
|
|
|
open(parent: Node, ctx: IGmPanelContext): void { |
|
|
|
|
this.close(); |
|
|
|
|
this._rankId = RankDataManager.getPlayerRankId() || 1; |
|
|
|
|
this._star = RankDataManager.getIntraTierStars() || 1; |
|
|
|
|
|
|
|
|
|
const pUt = parent.getComponent(UITransform); |
|
|
|
|
const W = pUt?.width || 660; |
|
|
|
|
const H = pUt?.height || 900; |
|
|
|
|
this._listW = W - 16; |
|
|
|
|
|
|
|
|
|
this._root = new Node('rankPicker'); |
|
|
|
|
this._root.layer = Layers.Enum.UI_2D; |
|
|
|
|
this._root.addComponent(UITransform).setContentSize(660, 900); |
|
|
|
|
this._root.addComponent(UITransform).setContentSize(W, H); |
|
|
|
|
const rw = this._root.addComponent(Widget); |
|
|
|
|
rw.isAlignLeft = rw.isAlignRight = rw.isAlignTop = rw.isAlignBottom = true; |
|
|
|
|
rw.left = rw.right = rw.top = rw.bottom = 0; |
|
|
|
|
parent.addChild(this._root); |
|
|
|
|
|
|
|
|
|
const title = new Node('t'); |
|
|
|
|
title.layer = Layers.Enum.UI_2D; |
|
|
|
|
title.addComponent(UITransform).setContentSize(600, 36); |
|
|
|
|
const tl = title.addComponent(Label); |
|
|
|
|
tl.string = ctx.command.title; |
|
|
|
|
tl.fontSize = 26; |
|
|
|
|
tl.color = Color.WHITE; |
|
|
|
|
tl.horizontalAlign = HorizontalTextAlignment.CENTER; |
|
|
|
|
title.setPosition(0, 420); |
|
|
|
|
this._root.addChild(title); |
|
|
|
|
|
|
|
|
|
const cur = new Node('cur'); |
|
|
|
|
cur.layer = Layers.Enum.UI_2D; |
|
|
|
|
cur.addComponent(UITransform).setContentSize(600, 36); |
|
|
|
|
this._lb = cur.addComponent(Label); |
|
|
|
|
this._lb.fontSize = 24; |
|
|
|
|
this._lb.color = Color.YELLOW; |
|
|
|
|
this._lb.horizontalAlign = HorizontalTextAlignment.CENTER; |
|
|
|
|
cur.setPosition(0, 360); |
|
|
|
|
this._root.addChild(cur); |
|
|
|
|
|
|
|
|
|
const { host, content } = makeVScroll(this._root, 640, 480); |
|
|
|
|
host.setPosition(0, 40); |
|
|
|
|
const headH = 100; |
|
|
|
|
const footH = 120; |
|
|
|
|
const head = new Node('head'); |
|
|
|
|
head.layer = Layers.Enum.UI_2D; |
|
|
|
|
head.addComponent(UITransform).setContentSize(this._listW, headH); |
|
|
|
|
this._drawRound(head, RANK_C.card, this._listW, headH, 14, RANK_C.selLine); |
|
|
|
|
head.setPosition(0, H / 2 - headH / 2 - 4); |
|
|
|
|
this._root.addChild(head); |
|
|
|
|
|
|
|
|
|
this._lbHead = this._makeLb(head, '', this._listW - 24, 36, 26, RANK_C.accent); |
|
|
|
|
this._lbHead.node.setPosition(0, 22); |
|
|
|
|
this._lbStar = this._makeLb(head, '', this._listW - 24, 32, 28, RANK_C.starOn); |
|
|
|
|
this._lbStar.node.setPosition(0, -22); |
|
|
|
|
|
|
|
|
|
const scrollH = H - headH - footH - 16; |
|
|
|
|
const { host, content } = makeVScroll(this._root, this._listW, scrollH); |
|
|
|
|
const lay = content.getComponent(Layout); |
|
|
|
|
if (lay) { |
|
|
|
|
lay.spacingY = 8; |
|
|
|
|
lay.paddingBottom = 12; |
|
|
|
|
} |
|
|
|
|
host.setPosition(0, (footH - headH) / 2); |
|
|
|
|
|
|
|
|
|
const list = gg.data.table.getTableList<ITableRank>(TableNames.Rank) ?? []; |
|
|
|
|
list.sort((a, b) => Number(a.id) - Number(b.id)); |
|
|
|
|
@ -671,40 +813,138 @@ class GmRankPickerPanel implements IGmContentPanel { |
|
|
|
|
const row = list[i]; |
|
|
|
|
const id = Number(row.id); |
|
|
|
|
const name = row.name ?? ''; |
|
|
|
|
makeLabelBtn(content, `${id} ${name}`, 620, 44, () => { |
|
|
|
|
this._rankId = id; |
|
|
|
|
this._paint(); |
|
|
|
|
}); |
|
|
|
|
if (id === this._rankId) this._rankName = name; |
|
|
|
|
const card = this._makeRankRow(id, name); |
|
|
|
|
content.addChild(card); |
|
|
|
|
this._rows[id] = card; |
|
|
|
|
} |
|
|
|
|
content.getComponent(Layout)?.updateLayout(); |
|
|
|
|
|
|
|
|
|
makeLabelBtn(this._root, '星-1', 100, 40, () => { |
|
|
|
|
const foot = new Node('foot'); |
|
|
|
|
foot.layer = Layers.Enum.UI_2D; |
|
|
|
|
foot.addComponent(UITransform).setContentSize(this._listW, footH - 12); |
|
|
|
|
this._drawRound(foot, RANK_C.card, this._listW, footH - 12, 14, RANK_C.rowLine); |
|
|
|
|
foot.setPosition(0, -H / 2 + footH / 2); |
|
|
|
|
this._root.addChild(foot); |
|
|
|
|
|
|
|
|
|
this._pill(foot, '星 -1', 110, 48, new Color(70, 78, 96, 255), () => { |
|
|
|
|
this._star = Math.max(1, this._star - 1); |
|
|
|
|
this._paint(); |
|
|
|
|
}).setPosition(-160, -260); |
|
|
|
|
makeLabelBtn(this._root, '星+1', 100, 40, () => { |
|
|
|
|
}).setPosition(-200, 0); |
|
|
|
|
this._pill(foot, '星 +1', 110, 48, new Color(70, 78, 96, 255), () => { |
|
|
|
|
this._star = Math.min(5, this._star + 1); |
|
|
|
|
this._paint(); |
|
|
|
|
}).setPosition(-40, -260); |
|
|
|
|
|
|
|
|
|
makeLabelBtn(this._root, '应用', 120, 44, () => { |
|
|
|
|
}).setPosition(-70, 0); |
|
|
|
|
this._pill(foot, '应用', 140, 52, RANK_C.btnHot, () => { |
|
|
|
|
ProjectGmActions.setRankAndStar(this._rankId, this._star); |
|
|
|
|
ctx.host.toast(`已设段位 ${this._rankId} 星 ${this._star}`); |
|
|
|
|
ctx.refreshList(); |
|
|
|
|
ctx.goBack(); |
|
|
|
|
}).setPosition(100, -260); |
|
|
|
|
if (!ctx.embedded) ctx.goBack(); |
|
|
|
|
}).setPosition(120, 0); |
|
|
|
|
|
|
|
|
|
makeLabelBtn(this._root, '返回', 120, 44, () => ctx.goBack()).setPosition(0, -320); |
|
|
|
|
this._paint(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
close(): void { |
|
|
|
|
if (this._root?.isValid) this._root.destroy(); |
|
|
|
|
this._root = null; |
|
|
|
|
this._lb = null; |
|
|
|
|
this._lbHead = null; |
|
|
|
|
this._lbStar = null; |
|
|
|
|
this._rows = {}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private _makeRankRow(id: number, name: string): Node { |
|
|
|
|
const h = 64; |
|
|
|
|
const w = this._listW; |
|
|
|
|
const card = new Node(`rank${id}`); |
|
|
|
|
card.layer = Layers.Enum.UI_2D; |
|
|
|
|
card.addComponent(UITransform).setContentSize(w, h); |
|
|
|
|
this._drawRound(card, RANK_C.row, w, h, 12, RANK_C.rowLine); |
|
|
|
|
|
|
|
|
|
const idLb = this._makeLb(card, `${id}`, 56, 36, 24, RANK_C.accent); |
|
|
|
|
idLb.node.setPosition(-w / 2 + 40, 0); |
|
|
|
|
const nameLb = this._makeLb(card, name, w - 120, 36, 24, RANK_C.text); |
|
|
|
|
nameLb.horizontalAlign = HorizontalTextAlignment.LEFT; |
|
|
|
|
nameLb.node.setPosition(20, 0); |
|
|
|
|
|
|
|
|
|
card.addComponent(Button); |
|
|
|
|
card.on(Button.EventType.CLICK, () => { |
|
|
|
|
this._rankId = id; |
|
|
|
|
this._rankName = name; |
|
|
|
|
this._paint(); |
|
|
|
|
}, this); |
|
|
|
|
return card; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private _paint(): void { |
|
|
|
|
if (this._lb) this._lb.string = `段位 ${this._rankId} 星 ${this._star}`; |
|
|
|
|
const ids = Object.keys(this._rows); |
|
|
|
|
for (let i = 0; i < ids.length; i++) { |
|
|
|
|
const id = Number(ids[i]); |
|
|
|
|
const row = this._rows[id]; |
|
|
|
|
if (!row?.isValid) continue; |
|
|
|
|
const on = id === this._rankId; |
|
|
|
|
this._drawRound(row, on ? RANK_C.selBg : RANK_C.row, this._listW, 64, 12, on ? RANK_C.selLine : RANK_C.rowLine); |
|
|
|
|
} |
|
|
|
|
if (this._lbHead) { |
|
|
|
|
this._lbHead.string = `当前选中 · ${this._rankId} ${this._rankName || ''}`.trim(); |
|
|
|
|
} |
|
|
|
|
if (this._lbStar) { |
|
|
|
|
let stars = ''; |
|
|
|
|
for (let i = 1; i <= 5; i++) stars += i <= this._star ? '★' : '☆'; |
|
|
|
|
this._lbStar.string = `${stars} 星级 ${this._star}`; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private _makeLb(parent: Node, text: string, w: number, h: number, size: number, color: Color): Label { |
|
|
|
|
const n = new Node('lb'); |
|
|
|
|
n.layer = Layers.Enum.UI_2D; |
|
|
|
|
n.addComponent(UITransform).setContentSize(w, h); |
|
|
|
|
const lb = n.addComponent(Label); |
|
|
|
|
lb.string = text; |
|
|
|
|
lb.fontSize = size; |
|
|
|
|
lb.isBold = true; |
|
|
|
|
lb.color = color; |
|
|
|
|
lb.horizontalAlign = HorizontalTextAlignment.CENTER; |
|
|
|
|
lb.verticalAlign = VerticalTextAlignment.CENTER; |
|
|
|
|
lb.overflow = Overflow.SHRINK; |
|
|
|
|
parent.addChild(n); |
|
|
|
|
return lb; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private _pill(parent: Node, text: string, w: number, h: number, bg: Color, onClick: () => void): Node { |
|
|
|
|
const n = new Node(text); |
|
|
|
|
n.layer = Layers.Enum.UI_2D; |
|
|
|
|
n.addComponent(UITransform).setContentSize(w, h); |
|
|
|
|
this._drawRound(n, bg, w, h, 12); |
|
|
|
|
const lbN = new Node('lb'); |
|
|
|
|
lbN.layer = Layers.Enum.UI_2D; |
|
|
|
|
lbN.addComponent(UITransform).setContentSize(w - 6, h - 4); |
|
|
|
|
const lb = lbN.addComponent(Label); |
|
|
|
|
lb.string = text; |
|
|
|
|
lb.fontSize = 22; |
|
|
|
|
lb.isBold = true; |
|
|
|
|
lb.color = RANK_C.text; |
|
|
|
|
lb.horizontalAlign = HorizontalTextAlignment.CENTER; |
|
|
|
|
lb.verticalAlign = VerticalTextAlignment.CENTER; |
|
|
|
|
n.addChild(lbN); |
|
|
|
|
n.addComponent(Button); |
|
|
|
|
n.on(Button.EventType.CLICK, onClick, this); |
|
|
|
|
parent.addChild(n); |
|
|
|
|
return n; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private _drawRound(node: Node, fill: Color, w: number, h: number, r: number, stroke?: Color): void { |
|
|
|
|
const g = node.getComponent(Graphics) || node.addComponent(Graphics); |
|
|
|
|
g.clear(); |
|
|
|
|
g.fillColor = fill; |
|
|
|
|
g.roundRect(-w / 2, -h / 2, w, h, r); |
|
|
|
|
g.fill(); |
|
|
|
|
if (stroke) { |
|
|
|
|
g.strokeColor = stroke; |
|
|
|
|
g.lineWidth = stroke === RANK_C.selLine ? 3 : 2; |
|
|
|
|
g.roundRect(-w / 2, -h / 2, w, h, r); |
|
|
|
|
g.stroke(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|