Commit 488aaf7a authored by vertighel's avatar vertighel
Browse files

refactor+feat: guider-panel resolveTargetCoords, disable guide on active, exptime on scicam expose



- Extract resolveTargetCoords() to eliminate center/stick/custom logic duplicated
  in onTargetChange and the non-destructive right-click handler
- Disable Guide button via noctua-telemetry when guider-active is truthy
- Disable all guider exptime inputs via noctua-telemetry when scicam snapshot-state=2 (Exposing);
  onCameraChange no longer unconditionally disables exptime for passive cameras

Co-Authored-By: default avatarClaude Sonnet 4.6 <noreply@anthropic.com>
parent 53d52da1
Loading
Loading
Loading
Loading
Loading
+49 −36
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@

import { showToast }        from './ui.js';
import { get as getViewer } from './viewer/viewer-registry.js';
import { resolveValue }     from './ui-core.js';

// --- Constants ---

@@ -26,23 +27,41 @@ const ACTUATOR_PARAMS = {
// --- 1. Camera → exptime ---

/**
 * Disables and clears the exptime input for passive cameras (scicam reads FITS
 * from disk — exptime is irrelevant and could mislead the operator).
 * Re-enables it when an active (triggering) camera is selected.
 * No-op for now: exptime enable/disable is driven by scicam telemetry globally.
 * Kept as a hook for future per-camera UI changes on camera switch.
 *
 * @param {string} panelId
 * @param {string} camera
 */
function onCameraChange(panelId, camera) {
    const el = document.getElementById(`guider-exptime-val-${panelId}`);
    if (!el) return;
    const passive = PASSIVE_CAMERAS.has(camera);
    el.disabled = passive;
    if (passive) el.value = '';
function onCameraChange(panelId, camera) {  // eslint-disable-line no-unused-vars
}

// --- 2. Target → coord fields ---

/**
 * Sets state.targetX/Y from the current target mode without touching the DOM.
 * Reads TX/TY field values for 'custom'; reads image size for 'center'.
 *
 * @param {string} panelId
 * @param {string} target
 * @param {object} state  - mutable per-panel pick state
 */
function resolveTargetCoords(panelId, target, state) {
    if (target === 'center') {
        const { width, height } = state.viewer?.getImageSize() ?? {};
        state.targetX = (width && height) ? Math.round(width  / 2) : null;
        state.targetY = (width && height) ? Math.round(height / 2) : null;
    } else if (target === 'stick') {
        state.targetX = state.centerX;
        state.targetY = state.centerY;
    } else {
        const tx = parseFloat(document.getElementById(`guider-tx-${panelId}`)?.value);
        const ty = parseFloat(document.getElementById(`guider-ty-${panelId}`)?.value);
        state.targetX = isNaN(tx) ? null : tx;
        state.targetY = isNaN(ty) ? null : ty;
    }
}

/**
 * Enables/disables TX/TY and auto-populates them based on target mode:
 *   center → image centre (width/2, height/2) from the registered viewer
@@ -82,19 +101,7 @@ function onTargetChange(panelId, target) {

    const state = _pickState[panelId];
    if (state?.annotating && state.phase === 'idle') {
        if (target === 'center') {
            const { width, height } = state.viewer?.getImageSize() ?? {};
            state.targetX = (width && height) ? Math.round(width  / 2) : null;
            state.targetY = (width && height) ? Math.round(height / 2) : null;
        } else if (target === 'stick') {
            state.targetX = state.centerX;
            state.targetY = state.centerY;
        } else {
            const txv = parseFloat(tx.value);
            const tyv = parseFloat(ty.value);
            state.targetX = isNaN(txv) ? null : txv;
            state.targetY = isNaN(tyv) ? null : tyv;
        }
        resolveTargetCoords(panelId, target, state);
        state.viewer?.redrawOverlay();
    }
}
@@ -334,25 +341,14 @@ function initPickMode(panelId) {
                wrap?.classList.remove('pick-warning', 'pick-success');

                const target = document.getElementById(`guider-target-${panelId}`)?.value;
                if (target === 'center') {
                    const { width, height } = state.viewer?.getImageSize() ?? {};
                    state.targetX = (width  && height) ? Math.round(width  / 2) : null;
                    state.targetY = (width  && height) ? Math.round(height / 2) : null;
                } else if (target === 'stick') {
                    state.targetX = state.centerX;
                    state.targetY = state.centerY;
                if (target === 'stick') {
                    // sync TX/TY fields to the center that was just locked in
                    const txEl = document.getElementById(`guider-tx-${panelId}`);
                    const tyEl = document.getElementById(`guider-ty-${panelId}`);
                    if (txEl) txEl.value = state.centerX !== null ? Math.round(state.centerX) : '';
                    if (tyEl) tyEl.value = state.centerY !== null ? Math.round(state.centerY) : '';
                } else {
                    // custom: read whatever is in the TX/TY fields
                    const tx = parseFloat(document.getElementById(`guider-tx-${panelId}`)?.value);
                    const ty = parseFloat(document.getElementById(`guider-ty-${panelId}`)?.value);
                    state.targetX = isNaN(tx) ? null : tx;
                    state.targetY = isNaN(ty) ? null : ty;
                }

                resolveTargetCoords(panelId, target, state);
                state.viewer?.redrawOverlay();
                for (const id of [`guider-tx-${panelId}`, `guider-ty-${panelId}`]) {
                    document.getElementById(id)?.classList.remove('border-warning');
@@ -495,6 +491,15 @@ function initPanel(panelId) {
    targetEl?.addEventListener('change', e => onTargetChange(panelId, e.target.value));
    guideBtn?.addEventListener('click',  () => postGuider(guideBtn, collectParams(panelId)));

    if (guideBtn) {
        document.addEventListener('noctua-telemetry', e => {
            const msg = e.detail;
            if (msg?.name !== 'all-guider') return;
            const active = resolveValue(msg.data, 'guider-active')?.value;
            guideBtn.disabled = !!active;
        });
    }

    // Keep TX/TY in sync with CX/CY when target=stick.
    // syncStickTarget listeners are added before redrawIfAnnotating so that
    // TX/TY are updated before the overlay redraw reads them.
@@ -542,4 +547,12 @@ document.addEventListener('DOMContentLoaded', () => {
        const panelId = btn.id.replace(/^btn-/, '').replace(/-guide-start$/, '');
        initPanel(panelId);
    });

    document.addEventListener('noctua-telemetry', e => {
        const msg = e.detail;
        if (msg?.name !== 'all-camera') return;
        const exposing = resolveValue(msg.data, 'camera-snapshot-state')?.value === 2;
        document.querySelectorAll('[id^="guider-exptime-val-"]')
            .forEach(el => { el.disabled = exposing; });
    });
});