mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-03 13:18:58 +00:00
fix: make devices inert in the Background editor
Issue: #362 User-Visible: yes
This commit is contained in:
committed by
claude[bot]
parent
f6da1ff57c
commit
5d37438e11
+20
-5
@@ -5177,9 +5177,12 @@ export class HouseplanCard extends LitElement {
|
||||
}
|
||||
|
||||
private _clickDevice(ev: Event, d: DevItem): void {
|
||||
// Devices are passive landmarks in Plan/Background. Guard before stopping
|
||||
// propagation so a Background tool still owns the same canvas point even
|
||||
// if a future CSS change accidentally makes a marker a hit target again.
|
||||
if (this._mode !== 'view' && this._mode !== 'devices') return;
|
||||
ev.stopPropagation();
|
||||
if (this._drag?.moved || this._suppressClick || this._holdFired) return;
|
||||
if (this._mode === 'plan') return;
|
||||
if (this._mode === 'devices') {
|
||||
this._openMarkerDialog(d);
|
||||
return;
|
||||
@@ -6335,7 +6338,10 @@ export class HouseplanCard extends LitElement {
|
||||
}
|
||||
|
||||
private _pointerDown(ev: PointerEvent, d: DevItem): void {
|
||||
if (this._mode === 'plan') return; // icons are hidden in plan mode anyway
|
||||
// Only View and the Devices editor own device input. In Background the
|
||||
// event must keep bubbling to the active decor tool; do not prevent it,
|
||||
// capture it or create a layout drag.
|
||||
if (this._mode !== 'view' && this._mode !== 'devices') return;
|
||||
if (this._mode === 'view') {
|
||||
// view: no drag, no capture — panning may start on an icon; only the
|
||||
// long-press timer runs (cancelled by stage movement)
|
||||
@@ -6361,6 +6367,7 @@ export class HouseplanCard extends LitElement {
|
||||
}
|
||||
|
||||
private _pointerMove(ev: PointerEvent, d: DevItem): void {
|
||||
if (this._mode !== 'devices') return;
|
||||
if (!this._drag || this._drag.id !== d.id) return;
|
||||
const stage = this.renderRoot.querySelector('.stage') as HTMLElement;
|
||||
if (!stage) return;
|
||||
@@ -6387,6 +6394,7 @@ export class HouseplanCard extends LitElement {
|
||||
|
||||
private _pointerUp(_ev: PointerEvent, d: DevItem): void {
|
||||
clearTimeout(this._holdTimer);
|
||||
if (this._mode !== 'devices') return;
|
||||
if (!this._drag || this._drag.id !== d.id) return;
|
||||
const moved = this._drag.moved;
|
||||
this._drag = moved ? this._drag : null;
|
||||
@@ -12017,11 +12025,14 @@ export class HouseplanCard extends LitElement {
|
||||
@click=${(e: MouseEvent) => this._clickDevice(e, d)}
|
||||
@keydown=${(e: KeyboardEvent) => this._keyDevice(e, d)}
|
||||
@contextmenu=${(e: MouseEvent) => this._ctxDevice(e, d)}
|
||||
@pointerover=${(e: PointerEvent) =>
|
||||
this._showTip(e, d.name, presentation.haDisabled ? ghostLabel : metrics)}
|
||||
@pointerover=${(e: PointerEvent) => {
|
||||
if (this._mode !== 'view' && this._mode !== 'devices') return;
|
||||
this._showTip(e, d.name, presentation.haDisabled ? ghostLabel : metrics);
|
||||
}}
|
||||
@pointerleave=${() => this._clearTransientHover()}
|
||||
@pointerdown=${(e: PointerEvent) => this._pointerDown(e, d)}
|
||||
@pointermove=${(e: PointerEvent) => {
|
||||
if (this._mode !== 'view' && this._mode !== 'devices') return;
|
||||
this._pointerMove(e, d);
|
||||
this._showTip(e, d.name, presentation.haDisabled ? ghostLabel : metrics);
|
||||
}}
|
||||
@@ -12527,7 +12538,11 @@ export class HouseplanCard extends LitElement {
|
||||
const top = ((point[1] - view.y) / view.h) * 100;
|
||||
return html`<div class="oplock ${deviceThemeClass(this._renderPlanHass)} ${locked ? 'locked' : known ? 'unlocked' : 'unknown'}"
|
||||
style="left:${left}%;top:${top}%"
|
||||
@click=${(e: MouseEvent) => { e.stopPropagation(); if (this._mode === 'view') this._openingInfo = o; }}>
|
||||
@click=${(e: MouseEvent) => {
|
||||
if (this._mode !== 'view') return;
|
||||
e.stopPropagation();
|
||||
this._openingInfo = o;
|
||||
}}>
|
||||
<span class="oplock-shell" aria-hidden="true">
|
||||
<span class="oplock-core">
|
||||
<ha-icon icon="${locked ? 'mdi:lock' : known ? 'mdi:lock-open-variant' : 'mdi:lock-question'}"></ha-icon>
|
||||
|
||||
@@ -853,8 +853,18 @@ export const planStyles = css`
|
||||
.stage.mode-decor.dtool-erase .decorlayer .dshape {
|
||||
cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cg transform='rotate(-45 12 12)'%3E%3Crect x='7' y='2' width='10' height='18' rx='2' fill='%23fff' stroke='%23111' stroke-width='1.5'/%3E%3Cpath d='M7 13h10v5a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2z' fill='%23ff9f43' stroke='%23111' stroke-width='1.5'/%3E%3C/g%3E%3C/svg%3E") 5 22, pointer;
|
||||
}
|
||||
.stage.mode-decor .room, .stage.mode-decor .devlayer { pointer-events: none; }
|
||||
.stage.mode-decor .oplock { pointer-events: none; }
|
||||
.stage.mode-decor .room { pointer-events: none; }
|
||||
/* Devices are landmarks in Background, never editing targets. The marker
|
||||
package deliberately re-enables pointer events on the core, its 44 px
|
||||
pseudo hit area and the visible capsule for View/Devices. A none on
|
||||
devlayer alone therefore does not make its HTML descendants inert.
|
||||
Scope the boundary to the whole subtree (including the pseudo element)
|
||||
so a Background tool receives the exact point below every visible part. */
|
||||
.stage.mode-decor .devlayer,
|
||||
.stage.mode-decor .devlayer *,
|
||||
.stage.mode-decor .dev::before {
|
||||
pointer-events: none;
|
||||
}
|
||||
/* Backdrop-editor de-emphasis is a shared mode-transition coordinate.
|
||||
It multiplies whole presentation groups and never changes Glow source
|
||||
alpha, additive blending, or the underlying resolved state. */
|
||||
|
||||
Reference in New Issue
Block a user