Open the add menu with a right-click in the asset panel (#244)
game-maker / gate (push) Successful in 3m24s
game-maker / suite (push) Successful in 10m9s

New assets could only be added through the + button. A right-click
on a category heading or on the empty space below the rows now opens
the same menu at the pointer.

- ListView gets the callback onListMenu. It fires on a right-click
  on empty space or on a heading. Only the asset panel has headings,
  so other lists are not affected.
- AssetPanel opens its + menu from there.
- A right-click on a heading does not fold or unfold the category.
  A right-click on empty space clears the selection like a left-click.
- A right-click on an asset still opens the menu of that asset.
- The empty list now says "No assets - press + or right-click".

Tests:
- ./check.sh: 178 files, 2573 tests, CHECK EXIT 0
- e2e 1-4: ALL PASSED, 134 checks
- 3 new checks in e2e 04 with real right-clicks: menu on the
  "Scenes" heading (21 types, heading stays folded), menu on empty
  space, and "Behavior" from that menu creates one, undone again.
- Counter-probe: without the menu both right-click checks fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-09-27 12:27:34 +02:00
1 parent 38f009e035
commit e0b471c354
4 files changed
+58 -3

No files matched your search

+2 -1
View File
@@ -80,10 +80,11 @@ export class AssetPanel extends Panel {
add.onClick = () => new Menu(this.addMenuEntries()).openBelow(add);
this.header.add(add);
this.list.emptyText = 'No assets – press +';
this.list.emptyText = 'No assets – press + or right-click';
this.list.onSelect = (id) => state.select(id ? { kind: 'asset', assetId: id } : null);
this.list.onActivate = (id) => this.activate(id);
this.list.onContextMenu = (id, x, y) => this.openContextMenu(id, x, y);
this.list.onListMenu = (x, y) => new Menu(this.addMenuEntries()).open(x, y);
this.list.onDragOut = (id) => this.startPlacementDrag(id);
this.list.onToggle = (id, expand) => this.setFolded(id.slice(HEADING.length) as AssetType, !expand);
this.scroll.setContent(this.list);
+6 -1
View File
@@ -91,6 +91,8 @@ export class ListView extends Widget {
onActivate?: (id: string) => void;
/** Returning the opened menu keeps its row marked for as long as it is up. */
onContextMenu?: (id: string, globalX: number, globalY: number) => Popup | void;
/** A right-click on the empty space below the rows or on a heading, which have no menu of their own. */
onListMenu?: (globalX: number, globalY: number) => void;
/** Called when a dragged row is released somewhere that could take it. */
onDrop?: (draggedId: string, spot: DropSpot) => void;
/**
@@ -121,7 +123,9 @@ export class ListView extends Widget {
this.pingMarker.visible = false;
this.addChild(this.emptyLabel, this.pingMarker, this.dropMarker);
this.on('pointerdown', (e: FederatedPointerEvent) => {
if (e.target === this) this.select(null);
if (e.target !== this) return;
this.select(null);
if (e.button === 2) this.onListMenu?.(e.global.x, e.global.y);
});
this.on('globalpointermove', (e: FederatedPointerEvent) => this.onDragMove(e));
this.onPointerRelease(() => this.onDragEnd());
@@ -294,6 +298,7 @@ export class ListView extends Widget {
const modifiers: PickModifiers = { ctrl: e.ctrlKey || e.metaKey, shift: e.shiftKey };
if (item.heading) {
if (e.button === 0) this.onToggle?.(item.id, !item.expanded);
else if (e.button === 2) this.onListMenu?.(e.global.x, e.global.y);
return;
}
// The chevron only folds the row – it never selects, so folding keeps the selection put.