The tab headers are one TabHeader, the node board and the tile board pan and zoom through one helper, reordering tile pictures and tilemap layers goes through one moveItem, and a tilemap cell is one named type (#85)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c91c18f495
commit
6d7d0005cf
19 files changed
+187
-195
No files matched your search
@@ -1,9 +1,10 @@
|
||||
import { Container, type FederatedPointerEvent, type FederatedWheelEvent, Graphics } from 'pixi.js';
|
||||
import { Container, Graphics } from 'pixi.js';
|
||||
import type { NodeDef } from '../../core/graph';
|
||||
import { Button, HStack, Label, type Size, Spacer, Theme, VStack, Widget, zoomFactor } from '../../ui';
|
||||
import { Button, Label, type Size, Spacer, Theme, VStack, Widget } from '../../ui';
|
||||
import { type Box, frameBoxes } from '../framing';
|
||||
import { drawGraphGrid, FIT_MARGIN, type GraphView, ZOOM_LIMITS, zoomedAbout } from '../graph/graphView';
|
||||
import { drawGraphGrid, FIT_MARGIN, type GraphView, panAndZoom, ZOOM_LIMITS } from '../graph/graphView';
|
||||
import { NodeView } from '../graph/NodeView';
|
||||
import { TabHeader } from '../TabHeader';
|
||||
|
||||
/** One node as a plugin hands it over: a title at a position in graph units. */
|
||||
export interface BoardNode {
|
||||
@@ -50,7 +51,6 @@ class BoardCanvas extends Widget {
|
||||
private readonly layer = new Container();
|
||||
private readonly views: NodeView[] = [];
|
||||
private view: GraphView = { pan: { x: 0, y: 0 }, zoom: 1 };
|
||||
private panning: { start: { x: number; y: number }; pan: { x: number; y: number } } | null = null;
|
||||
/** Framed once there is a size and something to frame; after that the view is the user's. */
|
||||
private needsFit = true;
|
||||
|
||||
@@ -59,22 +59,14 @@ class BoardCanvas extends Widget {
|
||||
this.layer.eventMode = 'none';
|
||||
this.addChild(this.bg, this.grid, this.layer, this.clip);
|
||||
this.layer.mask = this.clip;
|
||||
this.on('pointerdown', (e: FederatedPointerEvent) => {
|
||||
this.panning = { start: { x: e.global.x, y: e.global.y }, pan: { ...this.view.pan } };
|
||||
});
|
||||
this.on('globalpointermove', (e: FederatedPointerEvent) => {
|
||||
if (!this.panning) return;
|
||||
const { start, pan } = this.panning;
|
||||
this.view.pan = { x: pan.x + e.global.x - start.x, y: pan.y + e.global.y - start.y };
|
||||
this.applyView();
|
||||
});
|
||||
this.on('pointerup', () => (this.panning = null));
|
||||
this.on('pointerupoutside', () => (this.panning = null));
|
||||
this.on('wheel', (e: FederatedWheelEvent) => {
|
||||
this.view = zoomedAbout(this.view, this.toLocal(e.global), zoomFactor(e.deltaY));
|
||||
this.applyView();
|
||||
e.preventDefault();
|
||||
});
|
||||
panAndZoom(
|
||||
this,
|
||||
() => this.view,
|
||||
(view) => {
|
||||
this.view = view;
|
||||
this.applyView();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
setNodes(nodes: readonly BoardNode[]): void {
|
||||
@@ -138,14 +130,11 @@ export class NodeBoard extends VStack {
|
||||
readonly fitButton: Button;
|
||||
private readonly canvas = new BoardCanvas();
|
||||
private readonly count = new Label('', { style: 'small', align: 'right' });
|
||||
private readonly headerBg = new Graphics();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.fitButton = new Button('Fit', { onClick: () => this.fit() });
|
||||
const header = new HStack({ gap: Theme.gap, padding: Theme.padding, align: 'center' });
|
||||
header.minHeight = Theme.controlHeight + Theme.padding * 2;
|
||||
header.addChildAt(this.headerBg, 0);
|
||||
const header = new TabHeader();
|
||||
header.add(this.fitButton);
|
||||
header.add(new Spacer(), 1);
|
||||
header.add(this.count);
|
||||
@@ -169,12 +158,4 @@ export class NodeBoard extends VStack {
|
||||
debugInfo(): ReturnType<BoardCanvas['debugInfo']> {
|
||||
return this.canvas.debugInfo();
|
||||
}
|
||||
|
||||
override redraw(): void {
|
||||
super.redraw();
|
||||
const h = Theme.controlHeight + Theme.padding * 2;
|
||||
this.headerBg.clear();
|
||||
this.headerBg.rect(0, 0, this.w, h).fill(Theme.colors.panelHeader);
|
||||
this.headerBg.rect(0, h - 1, this.w, 1).fill(Theme.colors.border);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Graphics } from 'pixi.js';
|
||||
import { Checkbox, HStack, Label, ScrollContainer, Spacer, Theme, VStack } from '../../ui';
|
||||
import { TabHeader } from '../TabHeader';
|
||||
import type { PluginManager, PluginRecord } from './loader';
|
||||
|
||||
const NAME_WIDTH = 200;
|
||||
@@ -65,7 +65,6 @@ class PluginRow extends HStack {
|
||||
* reading a name out of it would mean running it.
|
||||
*/
|
||||
export class PluginsPane extends VStack {
|
||||
private readonly headerBg = new Graphics();
|
||||
private readonly hint: Label;
|
||||
private readonly rows = new VStack();
|
||||
private readonly scroll = new ScrollContainer();
|
||||
@@ -75,9 +74,7 @@ export class PluginsPane extends VStack {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const header = new HStack({ gap: Theme.gap, padding: Theme.padding, align: 'center' });
|
||||
header.minHeight = Theme.controlHeight + Theme.padding * 2;
|
||||
header.addChildAt(this.headerBg, 0);
|
||||
const header = new TabHeader();
|
||||
header.add(new Label('Plugins', { style: 'bodyBold' }));
|
||||
header.add(new Spacer(Theme.padding));
|
||||
this.hint = new Label('', { style: 'small' });
|
||||
@@ -154,12 +151,4 @@ export class PluginsPane extends VStack {
|
||||
this.scroll.relayoutContent();
|
||||
this.relayout();
|
||||
}
|
||||
|
||||
override redraw(): void {
|
||||
super.redraw();
|
||||
const h = Theme.controlHeight + Theme.padding * 2;
|
||||
this.headerBg.clear();
|
||||
this.headerBg.rect(0, 0, this.w, h).fill(Theme.colors.panelHeader);
|
||||
this.headerBg.rect(0, h - 1, this.w, 1).fill(Theme.colors.border);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user