Scene: ausgeschaltete Objekte behalten ihren Auswahlrahmen

Ein ausgeschaltetes Objekt zeichnet nichts, verschwand bisher aber auch aus
der Auswahl - im Panel angeklickt blieb der Viewport leer, es gab kein
Anzeichen, wo es liegt. Der Rahmen kommt jetzt, gedimmt auf 45 %, damit er
sich nicht wie eine fehlgeschlagene Zeichnung liest. Ziehen bleibt aus: der
Node ist weiterhin nicht interaktiv.

Dazu __gm.gizmos() als Testhaken - Gizmos waren vorher gar nicht prüfbar. Es
meldet das alpha, das wirklich in den Strich geht, kein daneben abgeleitetes
Flag.
This commit is contained in:
root committed 2026-09-10 17:36:27 +02:00
1 parent 4b47741fac
commit 2218046738
6 files changed
+81 -7

No files matched your search

+2
View File
@@ -176,6 +176,8 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
assetRow: (id: string) => assets.rowGlobal(id),
assetRowColor: (id: string) => assets.rowColor(id),
gameInfo: () => gameView.debugInfo(),
/** Selection outlines in the Scene tab: a switched-off object is invisible but still framed. */
gizmos: () => viewport.gizmoInfo(),
layerOf: (id: string) => viewport.layerOf(id),
drawOrder: () => viewport.drawOrder(),
objectScreen: (id: string) => viewport.objectScreen(id),
+27 -4
View File
@@ -63,6 +63,15 @@ interface Marquee {
active: boolean;
}
/** One selection outline that was drawn – `alpha` is the value the stroke really got. */
export interface GizmoInfo {
id: string;
primary: boolean;
alpha: number;
}
const OFF_GIZMO_ALPHA = 0.45;
export class SceneViewport extends WorldViewport {
private readonly grid = new Graphics();
private readonly links = new Graphics();
@@ -74,6 +83,7 @@ export class SceneViewport extends WorldViewport {
private dragging: ObjectDrag | null = null;
private marquee: Marquee | null = null;
private dropPreview: DropPreview | null = null;
private lastGizmos: GizmoInfo[] = [];
constructor(state: EditorState) {
super(state);
@@ -348,6 +358,11 @@ export class SceneViewport extends WorldViewport {
this.gizmos.clear();
}
/** The selection outlines currently drawn (test hook). */
gizmoInfo(): GizmoInfo[] {
return this.lastGizmos;
}
protected override afterItems(items: DrawItem[], view: View): void {
this.drawParentLinks(items, view.scale);
this.drawGizmos(items, view);
@@ -443,24 +458,32 @@ export class SceneViewport extends WorldViewport {
/** Selection outlines – only the primary object gets corner handles – and the rubber band. */
private drawGizmos(items: DrawItem[], view: View): void {
this.lastGizmos = [];
const s = this.state.selection;
if (s?.kind === 'object') {
for (const id of s.objectIds) {
const item = items.find((i) => i.id === id);
if (!item || !item.enabled) continue;
if (!item) continue;
const { w, h } = footprintOf(item.type, item.props);
const tl = worldToScreen(view, item.x - w / 2, item.y - h / 2);
const sw = w * view.scale;
const sh = h * view.scale;
this.gizmos.rect(tl.x - 2, tl.y - 2, sw + 4, sh + 4).stroke({ width: 2, color: Theme.colors.gizmo });
if (id !== s.objectId) continue;
// A switched-off object draws nothing, so its outline is the only way to see where it
// sits – dimmed, because the empty frame would otherwise read as a drawing that failed.
const alpha = item.enabled ? 1 : OFF_GIZMO_ALPHA;
const primary = id === s.objectId;
this.lastGizmos.push({ id, primary, alpha });
this.gizmos
.rect(tl.x - 2, tl.y - 2, sw + 4, sh + 4)
.stroke({ width: 2, color: Theme.colors.gizmo, alpha });
if (!primary) continue;
for (const [cx, cy] of [
[tl.x, tl.y],
[tl.x + sw, tl.y],
[tl.x, tl.y + sh],
[tl.x + sw, tl.y + sh],
] as const) {
this.gizmos.rect(cx - 3, cy - 3, 6, 6).fill(Theme.colors.gizmo);
this.gizmos.rect(cx - 3, cy - 3, 6, 6).fill({ color: Theme.colors.gizmo, alpha });
}
}
}