mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 02:44:02 +00:00
The picker's options are data: CctvControls computes the cameras in view and the closing note for those left out, keeps a focused picker's list and prepends a camera activated under it, and publishes the options, disabled state and selection. CctvPicker renders them keyed by camera id and applies the selection once the options are in place; it updates only when the controls publish, as the old picker did on layer notifications. A picker about to be disabled no longer counts as focused. This completes the CCTV panel: everything it shows is rendered from the gev-cctv store.
164 lines
5.6 KiB
JavaScript
164 lines
5.6 KiB
JavaScript
import { t } from '../i18n/index.js';
|
|
|
|
export function _initCctvPanel() {
|
|
if (!this._cctvPanel) return;
|
|
|
|
this.listen(this._cctvEnableBtn, 'click', async () => {
|
|
this._actionGeneration++;
|
|
await this.actions.toggleEnabled();
|
|
});
|
|
|
|
this.listen(this._cctvNearestBtn, 'click', async () => {
|
|
const generation = ++this._actionGeneration;
|
|
const activeId = this._cctvState?.activeCameraId;
|
|
if (!(await this.actions.toggleEnabled(true))) return;
|
|
if (
|
|
this.destroyed ||
|
|
generation !== this._actionGeneration ||
|
|
!this.actions.isEnabled() ||
|
|
(activeId && activeId !== this._cctvState?.activeCameraId)
|
|
)
|
|
return;
|
|
this.actions.runExplicitFocus(
|
|
() => this.cctv.focusNearest({ focus: false }),
|
|
(cameraId) => this.cctv.focusCamera(cameraId, 1.8),
|
|
);
|
|
});
|
|
|
|
this.listen(this._cctvPrevBtn, 'click', async () => {
|
|
const generation = ++this._actionGeneration;
|
|
const activeId = this._cctvState?.activeCameraId;
|
|
if (!(await this.actions.toggleEnabled(true))) return;
|
|
if (
|
|
this.destroyed ||
|
|
generation !== this._actionGeneration ||
|
|
!this.actions.isEnabled() ||
|
|
(activeId && activeId !== this._cctvState?.activeCameraId)
|
|
)
|
|
return;
|
|
this.actions.runExplicitFocus(
|
|
() => this.cctv.cycleCamera(-1),
|
|
(cameraId) => this.cctv.focusCamera(cameraId, 1.4),
|
|
);
|
|
});
|
|
|
|
this.listen(this._cctvNextBtn, 'click', async () => {
|
|
const generation = ++this._actionGeneration;
|
|
const activeId = this._cctvState?.activeCameraId;
|
|
if (!(await this.actions.toggleEnabled(true))) return;
|
|
if (
|
|
this.destroyed ||
|
|
generation !== this._actionGeneration ||
|
|
!this.actions.isEnabled() ||
|
|
(activeId && activeId !== this._cctvState?.activeCameraId)
|
|
)
|
|
return;
|
|
this.actions.runExplicitFocus(
|
|
() => this.cctv.cycleCamera(1),
|
|
(cameraId) => this.cctv.focusCamera(cameraId, 1.4),
|
|
);
|
|
});
|
|
|
|
// The picker defers rebuilds while focused; catch up once it lets go.
|
|
this.listen(this._cctvSelect, 'blur', () => {
|
|
this._picker = null;
|
|
this._renderCctvState(this._cctvState);
|
|
});
|
|
|
|
this.listen(this._cctvSelect, 'change', async () => {
|
|
const generation = ++this._actionGeneration;
|
|
const activeId = this._cctvState?.activeCameraId;
|
|
const cameraId = this._cctvSelect.value;
|
|
if (!cameraId) return;
|
|
if (!(await this.actions.toggleEnabled(true))) return;
|
|
if (
|
|
this.destroyed ||
|
|
generation !== this._actionGeneration ||
|
|
!this.actions.isEnabled() ||
|
|
(activeId && activeId !== this._cctvState?.activeCameraId)
|
|
)
|
|
return;
|
|
// Picking a camera from the dropdown flies to it. The dropdown lists the
|
|
// cameras in view (and the active camera, which may be far away), so a
|
|
// bare selection could leave the view somewhere else.
|
|
this.actions.runExplicitFocus(
|
|
() => (this.cctv.selectCamera(cameraId) ? cameraId : null),
|
|
(selectedId) => this.cctv.focusCamera(selectedId, 2.2),
|
|
);
|
|
this.actions.setParams({ selectedCameraId: cameraId }, { origin: 'user' });
|
|
});
|
|
|
|
this.listen(this._cctvFocusBtn, 'click', async () => {
|
|
const generation = ++this._actionGeneration;
|
|
const activeId = this._cctvState?.activeCameraId;
|
|
const selected = this._cctvState?.activeCameraId || this._cctvSelect?.value;
|
|
if (!selected) return;
|
|
if (!(await this.actions.toggleEnabled(true))) return;
|
|
if (
|
|
this.destroyed ||
|
|
generation !== this._actionGeneration ||
|
|
!this.actions.isEnabled() ||
|
|
(activeId && activeId !== this._cctvState?.activeCameraId)
|
|
)
|
|
return;
|
|
this.actions.runExplicitFocus(
|
|
() => selected,
|
|
(cameraId) => this.cctv.focusCamera(cameraId, 1.9),
|
|
);
|
|
this.actions.setParams({ selectedCameraId: selected }, { origin: 'user' });
|
|
});
|
|
|
|
this.listen(this._cctvCoverageBtn, 'click', () => {
|
|
const current =
|
|
this._cctvState?.coverageMode ||
|
|
(this._cctvState?.showCoverage ? 'on' : 'off');
|
|
const next =
|
|
current === 'off' ? 'on' : current === 'on' ? 'viewshed' : 'off';
|
|
this.actions.setParams({ coverageMode: next }, { origin: 'user' });
|
|
});
|
|
|
|
this.listen(this._cctvAutoHopBtn, 'click', () => {
|
|
const current = !!this._cctvState?.autoHop;
|
|
this.actions.setParams({ autoHop: !current }, { origin: 'user' });
|
|
});
|
|
|
|
this.listen(this._cctvProjectionBtn, 'click', () => {
|
|
const current = this._cctvState?.showProjection !== false;
|
|
this.actions.setParams({ showProjection: !current }, { origin: 'user' });
|
|
});
|
|
|
|
this.listen(this._cctvAdjustBtn, 'click', () => {
|
|
const current = !!this._cctvState?.calibrationMode;
|
|
this.actions.setParams({ calibrationMode: !current }, { origin: 'user' });
|
|
});
|
|
|
|
// Click-to-edit pose readout: each chip swaps to a number input; Enter or
|
|
// blur commits (converted to a calibration offset against basePose),
|
|
// Escape cancels. Delegated so re-renders never re-bind.
|
|
this.listen(this._cctvCalReadout, 'click', (event) => {
|
|
const chip = event.target.closest?.('.cctv-cal-value');
|
|
if (!chip || chip.disabled || chip.querySelector('input')) return;
|
|
this._beginCctvCalValueEdit(chip);
|
|
});
|
|
|
|
this.listen(this._cctvCalibSaveBtn, 'click', () => {
|
|
const cameraId = this._activeCctvCameraId();
|
|
if (!cameraId || !this.actions.setParams) return;
|
|
this.actions.setParams(
|
|
{
|
|
selectedCameraId: cameraId,
|
|
calibration: { cameraId, save: true },
|
|
},
|
|
{ origin: 'user' },
|
|
);
|
|
this.actions.showToast(t('CCTV calibration saved'));
|
|
});
|
|
|
|
this.listen(this._cctvCalibResetBtn, 'click', () => {
|
|
this._resetCctvCalibration();
|
|
});
|
|
|
|
this._renderCctvState(null);
|
|
this.actions.syncViewport();
|
|
}
|