Commit ffb967ea authored by vertighel's avatar vertighel
Browse files

viewer layout variants + telemetry pill removal + camera2/3 monitor



- camera_panel macro: layout='full'/'stacked'/'compact' param for
  different explore/panner arrangements in wide vs control views
- status.html: add camera2 and camera3 monitor containers
- ui-core.js: drop badge/pill for string telemetry values

Co-Authored-By: default avatarClaude Sonnet 4.6 <noreply@anthropic.com>
parent 7d365aad
Loading
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -216,22 +216,22 @@
#}
{# combo1 — station1 — visible by default #}
<div data-combo-view="combo1">
{% call camera_panel('ctrl-combo1-sci', 'station1', 'scicam', false, api_base) %}
    {{ camera_panel('ctrl-combo1-tec', 'station1', 'teccam', true, api_base) }}
{% call camera_panel('ctrl-combo1-sci', 'station1', 'scicam', false, api_base, layout='stacked') %}
    {{ camera_panel('ctrl-combo1-tec', 'station1', 'teccam', true, api_base, layout='compact') }}
{% endcall %}
</div>

{# combo2 — station2 — hidden #}
<div data-combo-view="combo2" class="d-none">
{% call camera_panel('ctrl-combo2-sci', 'station2', 'scicam', false, api_base) %}
    {{ camera_panel('ctrl-combo2-tec', 'station2', 'teccam', true, api_base) }}
{% call camera_panel('ctrl-combo2-sci', 'station2', 'scicam', false, api_base, layout='stacked') %}
    {{ camera_panel('ctrl-combo2-tec', 'station2', 'teccam', true, api_base, layout='compact') }}
{% endcall %}
</div>

{# combo3 — station3 — hidden #}
<div data-combo-view="combo3" class="d-none">
{% call camera_panel('ctrl-combo3-sci', 'station3', 'scicam', false, api_base) %}
    {{ camera_panel('ctrl-combo3-tec', 'station3', 'teccam', true, api_base) }}
{% call camera_panel('ctrl-combo3-sci', 'station3', 'scicam', false, api_base, layout='stacked') %}
    {{ camera_panel('ctrl-combo3-tec', 'station3', 'teccam', true, api_base, layout='compact') }}
{% endcall %}
</div>
{% endmacro %}
+112 −22
Original line number Diff line number Diff line
{# macros/viewer_panel.html
   Shared camera_panel macro — imported by viewer.html and control_panel.html.

   Usage (single):
     {{ camera_panel('scicam1', 'station1', 'scicam', false, '/api') }}
   Shared camera_panel macro.

   layout='full'    (default) — outer panel, wide page:
                               canvas left | explore+panner SIDE BY SIDE right
   layout='stacked'           — nested teccam in wide page OR outer panel in narrow page:
                               canvas left | explore+panner STACKED right
   layout='compact'           — nested teccam in narrow page (control.html):
                               explore+panner row on top, canvas full-width below

   Combo usage (call block puts the nested panel into the right-column slot):
     {% call camera_panel('sci-id', ..., layout='full') %}
         {{ camera_panel('tec-id', ..., layout='stacked') }}   ← wide viewer
     {% endcall %}

   Usage (combo — teccam nested in scicam's right column):
     {% call camera_panel('combo1-sci', 'station1', 'scicam', false, '/api') %}
         {{ camera_panel('combo1-tec', 'station1', 'teccam', true, '/api') }}
     {% call camera_panel('sci-id', ..., layout='stacked') %}
         {{ camera_panel('tec-id', ..., layout='compact') }}   ← control.html
     {% endcall %}
#}

{% macro camera_panel(panel_id, station, camera, has_loop, api_base) %}
{% macro camera_panel(panel_id, station, camera, has_loop, api_base, layout='full') %}
<div id="viewer-panel-{{ panel_id }}"
     class="viewer-panel"
     data-station="{{ station }}"
@@ -26,16 +34,96 @@
                title="Fetch current image">↺ Refresh</button>
    </div>

    {% if layout == 'compact' %}
    {# ── Compact: explore+panner row on top, canvas full-width below ─────── #}

    <div class="row g-1 mb-2">
        <div class="col-6" style="background:#000; border-radius:4px; overflow:hidden;">
            <canvas class="cv-explore d-block" width="256" height="256"
                    style="width:100%; image-rendering:pixelated;"></canvas>
        </div>
        <div class="col-6" style="background:#000; border-radius:4px; overflow:hidden;">
            <canvas class="cv-panoramic d-block" width="256" height="256"
                    style="width:100%; height:auto;"></canvas>
        </div>
        <div class="col-12 mt-1">
            <div class="input-group input-group-sm">
                <span class="input-group-text"
                      style="font-size:.65rem; padding:2px 6px;
                             background:#1a1a1a; border-color:#333; color:#aaa;">Box</span>
                <input type="number" class="ctrl-explore-w form-control form-control-sm"
                       value="70" step="10"
                       style="background:#111; border-color:#333; font-size:.7rem; color:#b0ffb0;">
            </div>
        </div>
    </div>

    <div class="viewer-canvas-wrap position-relative"
         style="background:#000; overflow:hidden; border-radius:6px;">
        <canvas class="cv-main d-block" width="800" height="800"
                style="width:100%; cursor:crosshair; transform-origin:0 0;"></canvas>
        <div class="cv-crosshair position-absolute"
             style="pointer-events:none; width:12px; height:12px;
                    transform:translate(-50%,-50%); display:none;">
            <svg width="12" height="12" viewBox="0 0 12 12">
                <line x1="6" y1="0" x2="6" y2="12" stroke="#ffff00" stroke-width="1"/>
                <line x1="0" y1="6" x2="12" y2="6" stroke="#ffff00" stroke-width="1"/>
            </svg>
        </div>
        <div class="position-absolute bottom-0 start-0 m-2">
            <span class="badge bg-black bg-opacity-75 info-main"
                  style="font-family:monospace; font-size:.65rem;"></span>
        </div>
    </div>

    <div class="viewer-controls mt-2 p-2 rounded"
         style="background:#0d0d0d; border:1px solid #222;">
        <div class="row g-2 align-items-center flex-wrap">
            <div class="col-auto d-flex align-items-center gap-1">
                <label class="text-muted small">Min</label>
                <input type="number" class="ctrl-vmin form-control form-control-sm"
                       style="width:90px; background:#111; border-color:#333;" step="any">
                <label class="text-muted small">Max</label>
                <input type="number" class="ctrl-vmax form-control form-control-sm"
                       style="width:90px; background:#111; border-color:#333;" step="any">
                <button class="btn btn-sm btn-outline-secondary btn-reset-{{ panel_id }}">Reset</button>
            </div>
            <div class="col-auto d-flex align-items-center gap-1">
                <input type="checkbox" class="ctrl-auto form-check-input"
                       id="ctrl-auto-{{ panel_id }}"
                       data-camera="{{ camera }}" checked>
                <label class="text-muted small"
                       for="ctrl-auto-{{ panel_id }}">Auto&nbsp;update</label>
            </div>
            {% if has_loop %}
            <div class="col-auto">
                <div class="input-group input-group-sm">
                    <input type="number" id="loop-exp-{{ panel_id }}"
                           class="form-control" value="1" min="0.1" step="0.5"
                           title="Exposure (s)"
                           style="background:#111; border-color:#333; max-width:70px;">
                    <button id="loop-start-{{ panel_id }}"
                            class="btn btn-primary">Start</button>
                    <button id="loop-stop-{{ panel_id }}"
                            class="btn btn-outline-secondary" disabled>Stop</button>
                </div>
            </div>
            {% endif %}
        </div>
    </div>

    {% else %}
    {# ── Standard two-column layout (full / stacked) ─────────────────────── #}

    <div class="row g-2 align-items-start">

        {# ── Left: main image canvas ── #}
        {# Left: main canvas + controls strip #}
        <div class="col-xl-9 col-lg-8">

            <div class="viewer-canvas-wrap position-relative"
                 style="background:#000; overflow:hidden; border-radius:6px;">
                <canvas class="cv-main d-block" width="800" height="800"
                        style="width:100%; cursor:crosshair; transform-origin:0 0;">
                </canvas>
                        style="width:100%; cursor:crosshair; transform-origin:0 0;"></canvas>
                <div class="cv-crosshair position-absolute"
                     style="pointer-events:none; width:12px; height:12px;
                            transform:translate(-50%,-50%); display:none;">
@@ -53,7 +141,6 @@
            <div class="viewer-controls mt-2 p-2 rounded"
                 style="background:#0d0d0d; border:1px solid #222;">
                <div class="row g-2 align-items-center flex-wrap">

                    <div class="col-auto d-flex align-items-center gap-1">
                        <label class="text-muted small">Min</label>
                        <input type="number" class="ctrl-vmin form-control form-control-sm"
@@ -61,11 +148,8 @@
                        <label class="text-muted small">Max</label>
                        <input type="number" class="ctrl-vmax form-control form-control-sm"
                               style="width:90px; background:#111; border-color:#333;" step="any">
                        <button class="btn btn-sm btn-outline-secondary btn-reset-{{ panel_id }}">
                            Reset
                        </button>
                        <button class="btn btn-sm btn-outline-secondary btn-reset-{{ panel_id }}">Reset</button>
                    </div>

                    <div class="col-auto d-flex align-items-center gap-1">
                        <input type="checkbox" class="ctrl-auto form-check-input"
                               id="ctrl-auto-{{ panel_id }}"
@@ -73,7 +157,6 @@
                        <label class="text-muted small"
                               for="ctrl-auto-{{ panel_id }}">Auto&nbsp;update</label>
                    </div>

                    {% if has_loop %}
                    <div class="col-auto">
                        <div class="input-group input-group-sm">
@@ -88,20 +171,24 @@
                        </div>
                    </div>
                    {% endif %}

                </div>
            </div>

        </div>

        {# ── Right: explore + panner + nested slot ── #}
        {# Right: explore + panner + nested slot #}
        <div class="col-xl-3 col-lg-4 d-flex flex-column gap-2">

            {# 'full' → side by side (col-6); 'stacked' → stacked (col-12) #}
            {% set mini_col = 'col-6' if layout == 'full' else 'col-12' %}
            <div class="row g-1">
                <div class="col-6" style="background:#000; border-radius:4px; overflow:hidden;">
                <div class="{{ mini_col }}"
                     style="background:#000; border-radius:4px; overflow:hidden;">
                    <canvas class="cv-explore d-block" width="256" height="256"
                            style="width:100%; image-rendering:pixelated;"></canvas>
                </div>
                <div class="col-6" style="background:#000; border-radius:4px; overflow:hidden;">
                <div class="{{ mini_col }}"
                     style="background:#000; border-radius:4px; overflow:hidden;">
                    <canvas class="cv-panoramic d-block" width="256" height="256"
                            style="width:100%; height:auto;"></canvas>
                </div>
@@ -118,7 +205,7 @@
                </div>
            </div>

            {# Nested viewer slot — filled by {% call %} block in combo views #}
            {# Nested slot — filled by {% call %} in combo views #}
            {% if caller is defined %}
            <div class="viewer-nested-slot">{{ caller() }}</div>
            {% endif %}
@@ -126,5 +213,8 @@
        </div>

    </div>

    {% endif %}

</div>
{% endmacro %}
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@
    {{ w.widget_monitor("dome", "dome") }}
    {{ w.widget_monitor("stage", "stage") }}
    {{ w.widget_monitor("camera", "camera") }}
    {{ w.widget_monitor("camera2", "camera2") }}
    {{ w.widget_monitor("camera3", "camera3") }}
    {{ w.widget_monitor("telescope", "telescope") }}
</div>

+2 −2
Original line number Diff line number Diff line
@@ -12,8 +12,8 @@
{% if is_combo %}
    {% set p0 = panels[0] %}
    {% set p1 = panels[1] %}
    {% call camera_panel(p0.id, p0.station, p0.camera, p0.has_loop, api_base) %}
        {{ camera_panel(p1.id, p1.station, p1.camera, p1.has_loop, api_base) }}
    {% call camera_panel(p0.id, p0.station, p0.camera, p0.has_loop, api_base, layout='full') %}
        {{ camera_panel(p1.id, p1.station, p1.camera, p1.has_loop, api_base, layout='stacked') }}
    {% endcall %}
{% else %}
    {% set p = panels[0] %}
+3 −3
Original line number Diff line number Diff line
@@ -141,13 +141,13 @@ export function applyVarStatusStyles(el, value) {
        return;
    }

    // Stati testuali/booleani/NA: reimposta alla pillola arrotondata di Bootstrap
    el.setAttribute('class', 'badge rounded-pill font-monospace');
    // Stati testuali/booleani/NA: testo monospazio colorato, senza pill
    el.setAttribute('class', 'font-monospace');

    const statusType = getStatusType(value);
    const theme = UI_CONFIG.COLORS[statusType];

    el.classList.add(theme.css, theme.text, 'border', theme.border);
    el.classList.add(theme.text);
}