import { Graphics } from 'pixi.js'; import { Theme } from '../Theme'; import type { Size } from '../Widget'; import { Button, type ButtonOptions } from './Button'; /** Space reserved at the right edge for the chevron. */ const CHEVRON_SLOT = 16; /** * A button that opens a menu: value flush left, chevron flush right. The chevron is drawn * rather than written into the label, so the label stays the plain value – which keeps it * readable, lets it be compared against the menu entries, and stays crisp at any size. */ export class Dropdown extends Button { private readonly chevron = new Graphics(); constructor(label: string, options: ButtonOptions = {}) { super(label, { ...options, align: 'left' }); this.addChild(this.chevron); } override measure(): Size { const size = super.measure(); return { w: size.w + CHEVRON_SLOT, h: size.h }; } /** The chevron's room is not the label's: a long value is shortened, not drawn under it. */ protected override labelSlot(): number { return super.labelSlot() - CHEVRON_SLOT; } override redraw(): void { super.redraw(); const x = this.w - CHEVRON_SLOT / 2 - Theme.padding / 2; const y = this.h / 2; this.chevron .clear() .moveTo(x - 4, y - 2) .lineTo(x + 4, y - 2) .lineTo(x, y + 3) .fill(this.onAccent ? Theme.colors.accentText : Theme.colors.textMuted); } }