show method
void
show()
Builds, positions, paints and shows the overlay.
Implementation
void show() {
// Build the overlay canvas + context first so we can measure text.
_canvas = web.HTMLCanvasElement();
final ctx = _canvas.getContext('2d');
if (ctx == null) return;
_surface = WebCanvasSurface(ctx as web.CanvasRenderingContext2D);
// Lay out rows + compute size.
_rows = [];
var y = _padY;
var maxTextW = 0.0;
_surface.setFont(size: 12);
for (final mi in _item.menuItems) {
if (mi.isSeparator) {
_rows.add(_MenuRow.separator(y));
y += _sepH;
} else {
final w = _surface.measureTextWidth(mi.caption);
if (w > maxTextW) maxTextW = w;
_rows.add(_MenuRow.item(mi, y, _rowH));
y += _rowH;
}
}
_menuW = (maxTextW + _padX * 2).clamp(_minW, _maxW);
_menuH = y + _padY;
// Position in the viewport, anchored to the button's bottom-left.
final a = _anchor.getBoundingClientRect();
final dpr = web.window.devicePixelRatio.clamp(1.0, 3.0);
var left = a.left + _anchorRect.x;
var top = a.top + _anchorRect.bottom + 2;
// Flip above if it would overflow the bottom.
if (top + _menuH > web.window.innerHeight) {
final above = a.top + _anchorRect.y - _menuH - 2;
if (above > 4) top = above;
}
// Clamp into the viewport horizontally.
left = (left).clamp(4.0, math.max(4.0, web.window.innerWidth - _menuW - 4));
// Size the backing store for HiDPI and place the element.
_canvas.width = (_menuW * dpr).round();
_canvas.height = (_menuH * dpr).round();
_canvas.style
..position = 'fixed'
..left = '${left}px'
..top = '${top}px'
..width = '${_menuW}px'
..height = '${_menuH}px'
..zIndex = '99999'
..borderRadius = '6px'
..boxShadow = '0 6px 18px rgba(0,0,0,0.18)';
_surface.ctx.scale(dpr, dpr);
// Fullscreen transparent backdrop to catch outside clicks.
_backdrop = web.HTMLDivElement();
_backdrop.style
..position = 'fixed'
..left = '0'
..top = '0'
..width = '100%'
..height = '100%'
..zIndex = '99998';
_backdrop.onClick.listen((_) => dismiss());
_subs.add(_canvas.onMouseMove.listen(_onMove));
_subs.add(
_canvas.onMouseLeave.listen((_) {
_hover = -1;
_paint();
}),
);
_subs.add(_canvas.onMouseDown.listen(_onDown));
_paint();
web.document.body!.append(_backdrop);
web.document.body!.append(_canvas);
}