Span the trade panel to the screen edges: SELL flush with the planet text, BUY out to the same right padding
The panel was centered as a group; now the SELL grid's left edge sits at the surface HUD's planet-text left edge (landing.hud.marginX, 24px — same key the HUD name/line use) so the cargo grid lines up vertically with the planet name above it, and the BUY list stretches from just past the grid all the way to the right edge minus that same padding (1280px window: BUY list 560 -> 770px wide; the 440px floor stays as the narrow-window fallback). The 16px gap between the panels is unchanged, and the sub-bar still anchors to the deck's Shop button. shopui.json's buyList.w is now only the headless fallback width.
This commit is contained in:
parent
cc4a15cafd
commit
c3d5e7fe74
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"_comment": "SHOP UI — the buy/sell (and buyback) screen over the shop clip (data/shopui.json). LAYOUT: the SELL grid (the player's cargo bays) sits on the LEFT, the BUY list (the shop's stock, as a scrollable list of wide rows) RIGHT NEXT TO it with just a bit of padding between (grid.centerW) — the panel is pure selection. The trade ACTIONS (Confirm/Clear) + the live NET-credits readout ride on the TAB SUB-BAR (→ tabs/preview/buttons), and the tab sub-bar toggles Buy/Sell ↔ Buyback (Buyback is disabled until the player has SOLD something this session). The panels are semi-transparent so the shop clip shows through; items + text are full alpha. SELL CELLS show the good's ICON only — the name + price appear in a hover TOOLTIP (→ tooltip) instead of over the icon. BUY ROWS carry their name + description (wraps to two lines, never over the price/stepper) + price INLINE (no tooltip — the row is wide enough). GEOMETRY (slot/gap/grid/centerW) is primitives the code (js/ui/shop/ShopView.js) lays out against the live scene size — not pixel positions. The ECONOMY itself (prices, stock) is Economy.js + data/goods.json + data/economy.json; this file is only presentation.",
|
"_comment": "SHOP UI — the buy/sell (and buyback) screen over the shop clip (data/shopui.json). LAYOUT: the SELL grid (the player's cargo bays) sits on the LEFT, the BUY list (the shop's stock, as a scrollable list of wide rows) RIGHT NEXT TO it with just a bit of padding between (grid.centerW) — the panel is pure selection. The panel SPANS the screen: the SELL grid's left edge is flush with the planet text (data/landing.json → landing.hud.marginX), and the BUY list stretches to the same right padding. The trade ACTIONS (Confirm/Clear) + the live NET-credits readout ride on the TAB SUB-BAR (→ tabs/preview/buttons), and the tab sub-bar toggles Buy/Sell ↔ Buyback (Buyback is disabled until the player has SOLD something this session). The panels are semi-transparent so the shop clip shows through; items + text are full alpha. SELL CELLS show the good's ICON only — the name + price appear in a hover TOOLTIP (→ tooltip) instead of over the icon. BUY ROWS carry their name + description (wraps to two lines, never over the price/stepper) + price INLINE (no tooltip — the row is wide enough). GEOMETRY (slot/gap/grid/centerW) is primitives the code (js/ui/shop/ShopView.js) lays out against the live scene size — not pixel positions. The ECONOMY itself (prices, stock) is Economy.js + data/goods.json + data/economy.json; this file is only presentation.",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
|
||||||
"tabs": {
|
"tabs": {
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"buyList": {
|
"buyList": {
|
||||||
"_comment": "The BUY side (js/ui/shop/BuyList.js): the shop's stock as a SCROLLABLE LIST of WIDE ROWS — [icon] NAME / description (the good's flavor, data/goods.json, wraps to up to desc.maxLines lines and NEVER over the price/stepper) … PRICE, − qty +. Sized to the SELL grid's height so the panels align top AND bottom; the list scrolls (drag on the body / mouse wheel) when the stock outgrows the viewport — rows outside it are hidden (row-based clipping; this Phaser build has no camera/mask clip). A row in the pending trade (qty > 0) gets the accent border + lit qty. `rowH` is tall enough for the two-line description. `pad` insets rows from the panel edge; the title bar reuses panel.title.",
|
"_comment": "The BUY side (js/ui/shop/BuyList.js): the shop's stock as a SCROLLABLE LIST of WIDE ROWS — [icon] NAME / description (the good's flavor, data/goods.json, wraps to up to desc.maxLines lines and NEVER over the price/stepper) … PRICE, − qty +. Live, ShopView STRETCHES the list from just past the SELL grid out to the right padding (data/landing.json → landing.hud.marginX) — `w` is only the fallback when no width is passed (headless/dev). Sized to the SELL grid's height so the panels align top AND bottom; the list scrolls (drag on the body / mouse wheel) when the stock outgrows the viewport — rows outside it are hidden (row-based clipping; this Phaser build has no camera/mask clip). A row in the pending trade (qty > 0) gets the accent border + lit qty. `rowH` is tall enough for the two-line description. `pad` insets rows from the panel edge; the title bar reuses panel.title.",
|
||||||
"w": 560,
|
"w": 560,
|
||||||
"pad": 14,
|
"pad": 14,
|
||||||
"rowH": 72,
|
"rowH": 72,
|
||||||
|
|
|
||||||
|
|
@ -266,14 +266,23 @@ console.log('\n== INTERACTION — icons bound per good + taps carry a hitAreaCal
|
||||||
assert.equal(typeof view.buyList.rows[0].objs.plus?._interactive?.hitAreaCallback, 'function', 'buy row + tap has a hitAreaCallback');
|
assert.equal(typeof view.buyList.rows[0].objs.plus?._interactive?.hitAreaCallback, 'function', 'buy row + tap has a hitAreaCallback');
|
||||||
|
|
||||||
// The two panels must settle at DIFFERENT layout positions — the slide-in
|
// The two panels must settle at DIFFERENT layout positions — the slide-in
|
||||||
// tween targets each grid's set position (the ShopView centers
|
// tween targets each grid's set position. The old bug tweened to x:0,
|
||||||
// [SELL] [center] [BUY]). The old bug tweened to x:0, stacking both panels
|
// stacking both panels at the left edge so the cargo/sell panel sat hidden
|
||||||
// at the left edge so the cargo/sell panel sat hidden behind the buy panel.
|
// behind the buy panel.
|
||||||
assert.ok(view.sellGrid.x > 0, `sell panel settles at a positive layout x (got ${view.sellGrid.x})`);
|
assert.ok(view.sellGrid.x > 0, `sell panel settles at a positive layout x (got ${view.sellGrid.x})`);
|
||||||
assert.ok(view.buyList.x > view.sellGrid.x, `buy panel is to the right of the sell panel (sell ${view.sellGrid.x} < buy ${view.buyList.x})`);
|
assert.ok(view.buyList.x > view.sellGrid.x, `buy panel is to the right of the sell panel (sell ${view.sellGrid.x} < buy ${view.buyList.x})`);
|
||||||
assert.notEqual(view.sellGrid.x, view.buyList.x, 'the panels do not overlap at the origin');
|
assert.notEqual(view.sellGrid.x, view.buyList.x, 'the panels do not overlap at the origin');
|
||||||
assert.ok(view.buyList.width > view.sellGrid.width, 'the BUY list is the wide panel (rows, not 4×4 cells)');
|
assert.ok(view.buyList.width > view.sellGrid.width, 'the BUY list is the wide panel (rows, not 4×4 cells)');
|
||||||
|
|
||||||
|
// The panel spans the screen like the HUD: the SELL grid's LEFT edge is
|
||||||
|
// the planet text's left edge (landing.hud.marginX), and the BUY list's
|
||||||
|
// RIGHT edge is the SAME padding in from the screen's right edge.
|
||||||
|
const leftPad = Number(config.get('landing.hud.marginX')) || 24;
|
||||||
|
const W = 1280; // the stub scene's width
|
||||||
|
assert.equal(view.sellGrid.x, leftPad, `SELL's left edge is flush with the planet text's left edge (x=${view.sellGrid.x}, hud margin=${leftPad})`);
|
||||||
|
const rightEdge = view.buyList.x + view.buyList.width;
|
||||||
|
assert.ok(Math.abs(rightEdge - (W - leftPad)) < 1, `BUY's right edge is the same padding in from the right (rightEdge=${rightEdge}, want ${W - leftPad})`);
|
||||||
|
|
||||||
// The two panels sit NEXT TO each other with just a bit of padding between
|
// The two panels sit NEXT TO each other with just a bit of padding between
|
||||||
// (grid.centerW — the actions moved onto the sub-bar, so there's no center
|
// (grid.centerW — the actions moved onto the sub-bar, so there's no center
|
||||||
// column anymore).
|
// column anymore).
|
||||||
|
|
|
||||||
|
|
@ -308,7 +308,10 @@ placement as the deck's **Menu** sub-bar (`js/ui/MenuSubBar.js`). It rests **abo
|
||||||
the command deck**, right-aligned to the deck's **Shop** button — so it reads as the same family
|
the command deck**, right-aligned to the deck's **Shop** button — so it reads as the same family
|
||||||
of UI as the Menu drawer. The screen stays open on the shop video so the clip plays. Clicking
|
of UI as the Menu drawer. The screen stays open on the shop video so the clip plays. Clicking
|
||||||
**Buy/Sell** reveals the trade panel in the middle of the screen: the **SELL grid** and the
|
**Buy/Sell** reveals the trade panel in the middle of the screen: the **SELL grid** and the
|
||||||
**BUY list** side by side with just a bit of padding between (the panels slide in).
|
**BUY list** side by side with just a bit of padding between (the panels slide in). The
|
||||||
|
panel **spans the screen** — the SELL grid's left edge is **flush with the planet name**
|
||||||
|
(the HUD's left margin), and the BUY list stretches to the **same padding** in from the
|
||||||
|
right edge.
|
||||||
|
|
||||||
```
|
```
|
||||||
# first click — shop video + the tab sub-bar (rests above the deck):
|
# first click — shop video + the tab sub-bar (rests above the deck):
|
||||||
|
|
|
||||||
|
|
@ -345,6 +345,12 @@ export class ShopView extends Phaser.GameObjects.Container {
|
||||||
// see _buildTabs — so the panel is pure selection).
|
// see _buildTabs — so the panel is pure selection).
|
||||||
const centerW = grid.centerW ?? 16;
|
const centerW = grid.centerW ?? 16;
|
||||||
const W = this._W();
|
const W = this._W();
|
||||||
|
// The panel's LEFT edge = the surface HUD's planet text's LEFT edge —
|
||||||
|
// the same margin key (data/landing.json → landing.hud.marginX) the
|
||||||
|
// name/line are drawn at (origin 0,0), so the cargo grid lines up
|
||||||
|
// vertically with the planet name above it. The BUY list then STRETCHES
|
||||||
|
// to the right, ending at the SAME padding from the screen's right edge.
|
||||||
|
const leftPad = Math.max(8, Number(config.get('landing.hud.marginX')) || 24);
|
||||||
|
|
||||||
const sellGrid = new TradeGrid(this.scene, {
|
const sellGrid = new TradeGrid(this.scene, {
|
||||||
side: 'sell', maxSlots: this.maxSlots, capacity: this.capacity,
|
side: 'sell', maxSlots: this.maxSlots, capacity: this.capacity,
|
||||||
|
|
@ -355,26 +361,26 @@ export class ShopView extends Phaser.GameObjects.Container {
|
||||||
// name + description + price + −/qty/+ stepper). Sized to the SELL
|
// name + description + price + −/qty/+ stepper). Sized to the SELL
|
||||||
// grid's height so the two panels align top AND bottom; the list scrolls
|
// grid's height so the two panels align top AND bottom; the list scrolls
|
||||||
// when the stock outgrows the viewport (it always does — 8–16 rows).
|
// when the stock outgrows the viewport (it always does — 8–16 rows).
|
||||||
const buyW = Math.min(
|
// Width: from just past the SELL grid out to the right padding — the
|
||||||
Number(config.get('shopui.buyList.w')) || 560,
|
// wide row gets all the room (the 440 floor is the narrow-window
|
||||||
Math.max(440, W - 24 - sellGrid.width - centerW),
|
// fallback, where stretching to the right edge isn't possible).
|
||||||
);
|
const buyW = Math.max(440, W - leftPad - (leftPad + sellGrid.width + centerW));
|
||||||
const buyList = new BuyList(this.scene, { width: buyW, height: sellGrid.height });
|
const buyList = new BuyList(this.scene, { width: buyW, height: sellGrid.height });
|
||||||
this.sellGrid = sellGrid;
|
this.sellGrid = sellGrid;
|
||||||
this.buyList = buyList;
|
this.buyList = buyList;
|
||||||
|
|
||||||
// Layout: [SELL grid] [gap] [BUY list]. The panel's TOP edge sits at
|
// Layout: [SELL grid] [gap] [BUY list]. The panel's TOP edge sits at
|
||||||
// this.topY — just under the surface HUD's planet text (upper-left) — so
|
// this.topY — just under the surface HUD's planet text (upper-left) —
|
||||||
// the whole panel reads as one unit near the top of the screen (not
|
// so the whole panel reads as one unit near the top of the screen (not
|
||||||
// hanging down to the deck/sub-bar).
|
// hanging down to the deck/sub-bar); its LEFT edge is the planet text's
|
||||||
|
// left edge (leftPad), and the BUY list ends at the right padding.
|
||||||
//
|
//
|
||||||
// IMPORTANT: a TradeGrid/BuyList lays its plate out in local (0,0)→(w,h)
|
// IMPORTANT: a TradeGrid/BuyList lays its plate out in local (0,0)→(w,h)
|
||||||
// and a Container's (x,y) is a pure TRANSLATION of that local space
|
// and a Container's (x,y) is a pure TRANSLATION of that local space
|
||||||
// (verified with dev/cbox-test.html) — so the panel's position IS its
|
// (verified with dev/cbox-test.html) — so the panel's position IS its
|
||||||
// top-left corner. Treating it as a centered origin (topY + h/2) drops
|
// top-left corner. Treating it as a centered origin (topY + h/2) drops
|
||||||
// the panel half a grid lower and clips the bottom rows.
|
// the panel half a grid lower and clips the bottom rows.
|
||||||
const totalW = sellGrid.width + centerW + buyList.width;
|
const leftX = leftPad;
|
||||||
const leftX = Math.max(8, (W - totalW) / 2);
|
|
||||||
sellGrid.setPosition(leftX, this.topY);
|
sellGrid.setPosition(leftX, this.topY);
|
||||||
const rightX = leftX + sellGrid.width + centerW;
|
const rightX = leftX + sellGrid.width + centerW;
|
||||||
buyList.setPosition(rightX, this.topY);
|
buyList.setPosition(rightX, this.topY);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue