import { type FederatedPointerEvent, Graphics } from 'pixi.js'; import { Theme } from '../Theme'; import { Widget } from '../Widget'; /** Thin draggable divider between two panes. Reports the drag delta; the parent resizes. */ export class Splitter extends Widget { /** Size across the drag axis; the visible bar fills it, so this is also the grab area. */ static readonly THICKNESS = 5; private readonly bar = new Graphics(); private dragging = false; private last = 0; onDrag?: (delta: number) => void; constructor(private readonly axis: 'x' | 'y') { super(); this.cursor = axis === 'x' ? 'col-resize' : 'row-resize'; this.minWidth = axis === 'x' ? Splitter.THICKNESS : 0; this.minHeight = axis === 'y' ? Splitter.THICKNESS : 0; this.addChild(this.bar); this.trackHover(); this.on('pointerdown', (e: FederatedPointerEvent) => { this.dragging = true; this.last = this.axis === 'x' ? e.global.x : e.global.y; e.stopPropagation(); }); this.on('globalpointermove', (e: FederatedPointerEvent) => { if (!this.dragging) return; const now = this.axis === 'x' ? e.global.x : e.global.y; const delta = now - this.last; this.last = now; if (delta !== 0) this.onDrag?.(delta); }); this.onPointerRelease(() => { this.dragging = false; this.invalidate(); }); } override redraw(): void { this.bar.clear(); const active = this.hovered || this.dragging; this.bar.rect(0, 0, this.w, this.h).fill(active ? Theme.colors.accent : Theme.colors.border); } }