Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
508ed8a8e7 | ||
|
|
d9fc623ef4 |
@@ -358,9 +358,14 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="full-row label-below-row" id="vchan-row">
|
<div class="full-row label-below-row" id="vchan-row">
|
||||||
<div class="label"><span>Channels / Scheduler</span></div>
|
<div class="label"><span>Channels</span></div>
|
||||||
<div class="channel-scheduler-controls">
|
<div class="channel-scheduler-controls">
|
||||||
<div class="vchan-picker" id="vchan-picker"></div>
|
<div class="vchan-picker" id="vchan-picker"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<details id="scheduler-controls" class="advanced-radio-controls scheduler-controls-section">
|
||||||
|
<summary>Scheduler controls</summary>
|
||||||
|
<div class="advanced-radio-body">
|
||||||
<div class="scheduler-control-row" style="display:none">
|
<div class="scheduler-control-row" style="display:none">
|
||||||
<div class="scheduler-release-wrap">
|
<div class="scheduler-release-wrap">
|
||||||
<button id="scheduler-release-btn" type="button">Release to Scheduler</button>
|
<button id="scheduler-release-btn" type="button">Release to Scheduler</button>
|
||||||
@@ -383,7 +388,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</details>
|
||||||
<div class="full-row label-below-row">
|
<div class="full-row label-below-row">
|
||||||
<div class="label"><span>Signal</span></div>
|
<div class="label"><span>Signal</span></div>
|
||||||
<div class="signal" style="gap: 1rem;">
|
<div class="signal" style="gap: 1rem;">
|
||||||
|
|||||||
@@ -2949,8 +2949,7 @@ button.is-active {
|
|||||||
#ptt-btn.is-active { background: var(--accent-red) !important; border-color: var(--accent-red) !important; color: white !important; }
|
#ptt-btn.is-active { background: var(--accent-red) !important; border-color: var(--accent-red) !important; color: white !important; }
|
||||||
.is-busy { cursor: progress !important; opacity: 0.68; }
|
.is-busy { cursor: progress !important; opacity: 0.68; }
|
||||||
.operator-layout-picker {
|
.operator-layout-picker {
|
||||||
display: inline-grid;
|
display: inline-flex;
|
||||||
grid-template-columns: auto auto;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-height: 2rem;
|
min-height: 2rem;
|
||||||
padding-left: 0.6rem;
|
padding-left: 0.6rem;
|
||||||
@@ -2980,17 +2979,6 @@ button.is-active {
|
|||||||
}
|
}
|
||||||
.operator-layout-picker:focus-within { border-color: var(--accent-green); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-green) 20%, transparent); }
|
.operator-layout-picker:focus-within { border-color: var(--accent-green); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-green) 20%, transparent); }
|
||||||
.operator-layout-picker select:focus-visible { outline: 0; }
|
.operator-layout-picker select:focus-visible { outline: 0; }
|
||||||
.operator-layout-description {
|
|
||||||
grid-column: 1 / -1;
|
|
||||||
max-width: 22rem;
|
|
||||||
padding: 0 0.55rem 0.35rem 0;
|
|
||||||
color: var(--text-muted);
|
|
||||||
font-size: var(--fs-xs);
|
|
||||||
font-weight: 500;
|
|
||||||
letter-spacing: 0;
|
|
||||||
line-height: 1.35;
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
.advanced-radio-controls {
|
.advanced-radio-controls {
|
||||||
margin-top: var(--space-3);
|
margin-top: var(--space-3);
|
||||||
border: 1px solid color-mix(in srgb, var(--border-light) 75%, transparent);
|
border: 1px solid color-mix(in srgb, var(--border-light) 75%, transparent);
|
||||||
@@ -3032,7 +3020,7 @@ body[data-operator-layout="broadcast"] #tx-meters,
|
|||||||
body[data-operator-layout="broadcast"] #tx-limit-row,
|
body[data-operator-layout="broadcast"] #tx-limit-row,
|
||||||
body[data-operator-layout="broadcast"] #vfo-row,
|
body[data-operator-layout="broadcast"] #vfo-row,
|
||||||
body[data-operator-layout="broadcast"] #sam-controls-col,
|
body[data-operator-layout="broadcast"] #sam-controls-col,
|
||||||
body[data-operator-layout="broadcast"] .advanced-radio-controls {
|
body[data-operator-layout="broadcast"] #advanced-radio-controls {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
body[data-operator-layout="broadcast"] .controls-row {
|
body[data-operator-layout="broadcast"] .controls-row {
|
||||||
|
|||||||
@@ -126,10 +126,10 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const layouts = {
|
const layouts = {
|
||||||
compact: { label: "Compact", description: "Essential tuning and audio controls", advanced: false, preferredTab: "main" },
|
compact: { label: "Compact", advanced: false, preferredTab: "main" },
|
||||||
broadcast: { label: "Broadcast", description: "WFM, RDS, stereo and interference monitoring", unavailable: "Broadcast requires an enumerated WFM-capable receiver", advanced: false, preferredTab: "main", capability: "broadcast" },
|
broadcast: { label: "Broadcast", unavailable: "Broadcast requires an enumerated WFM-capable receiver", advanced: false, preferredTab: "main", capability: "broadcast" },
|
||||||
digital: { label: "Digital", description: "Decoder status, messages and background decoding", unavailable: "Digital requires a compatible rig mode and an available decoder", advanced: false, preferredTab: "digital-modes", capability: "digital" },
|
digital: { label: "Digital", unavailable: "Digital requires a compatible rig mode and an available decoder", advanced: false, preferredTab: "digital-modes", capability: "digital" },
|
||||||
full: { label: "Full controls", description: "Every control supported by the selected rig", advanced: true, preferredTab: "main" },
|
full: { label: "Full controls", advanced: true, preferredTab: "main" },
|
||||||
};
|
};
|
||||||
const layoutCapabilities = { broadcast: false, digital: false };
|
const layoutCapabilities = { broadcast: false, digital: false };
|
||||||
let activeRigId = null;
|
let activeRigId = null;
|
||||||
@@ -151,12 +151,6 @@
|
|||||||
return unavailable.length ? `Unavailable: ${unavailable.map(layout => layout.unavailable).join("; ")}.` : "";
|
return unavailable.length ? `Unavailable: ${unavailable.map(layout => layout.unavailable).join("; ")}.` : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLayoutDescription(layout) {
|
|
||||||
const description = document.getElementById("operator-layout-description");
|
|
||||||
if (!description) return;
|
|
||||||
description.textContent = [layout.description, unavailableLayoutMessage()].filter(Boolean).join(" · ");
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshLayoutOptions() {
|
function refreshLayoutOptions() {
|
||||||
const select = document.getElementById("operator-layout-select");
|
const select = document.getElementById("operator-layout-select");
|
||||||
if (!select) return;
|
if (!select) return;
|
||||||
@@ -170,7 +164,6 @@
|
|||||||
select.value = available ? previous : "compact";
|
select.value = available ? previous : "compact";
|
||||||
if (!available && previous !== "compact") api.applyLayout("compact", { persist: false });
|
if (!available && previous !== "compact") api.applyLayout("compact", { persist: false });
|
||||||
select.title = unavailableLayoutMessage();
|
select.title = unavailableLayoutMessage();
|
||||||
updateLayoutDescription(layouts[select.value] || layouts.compact);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
api.setLayoutCapabilities = function setLayoutCapabilities(capabilities = {}) {
|
api.setLayoutCapabilities = function setLayoutCapabilities(capabilities = {}) {
|
||||||
@@ -202,7 +195,6 @@
|
|||||||
if (options.persist !== false) localStorage.setItem(layoutStorageKey(), document.body.dataset.operatorLayout);
|
if (options.persist !== false) localStorage.setItem(layoutStorageKey(), document.body.dataset.operatorLayout);
|
||||||
const details = document.getElementById("advanced-radio-controls");
|
const details = document.getElementById("advanced-radio-controls");
|
||||||
if (details) details.open = layout.advanced;
|
if (details) details.open = layout.advanced;
|
||||||
updateLayoutDescription(layout);
|
|
||||||
if (options.navigate && typeof window.navigateToTab === "function") {
|
if (options.navigate && typeof window.navigateToTab === "function") {
|
||||||
window.navigateToTab(layout.preferredTab);
|
window.navigateToTab(layout.preferredTab);
|
||||||
}
|
}
|
||||||
@@ -213,7 +205,7 @@
|
|||||||
if (actions && !document.getElementById("operator-layout-select")) {
|
if (actions && !document.getElementById("operator-layout-select")) {
|
||||||
const label = document.createElement("label");
|
const label = document.createElement("label");
|
||||||
label.className = "operator-layout-picker";
|
label.className = "operator-layout-picker";
|
||||||
label.innerHTML = '<span class="visually-hidden">Operator layout</span><select id="operator-layout-select" aria-label="Operator layout" aria-describedby="operator-layout-description"></select><span id="operator-layout-description" class="operator-layout-description"></span>';
|
label.innerHTML = '<span class="visually-hidden">Operator layout</span><select id="operator-layout-select" aria-label="Operator layout"></select>';
|
||||||
const select = label.querySelector("select");
|
const select = label.querySelector("select");
|
||||||
const savedLayout = savedLayoutName();
|
const savedLayout = savedLayoutName();
|
||||||
actions.insertBefore(label, actions.firstChild);
|
actions.insertBefore(label, actions.firstChild);
|
||||||
|
|||||||
@@ -88,5 +88,6 @@ mod tests {
|
|||||||
"UI primitives must load before application code"
|
"UI primitives must load before application code"
|
||||||
);
|
);
|
||||||
assert!(UI_CORE_JS.contains("window.trxUi"));
|
assert!(UI_CORE_JS.contains("window.trxUi"));
|
||||||
|
assert!(html.contains("<summary>Scheduler controls</summary>"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user