mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
feat(ui): render the Display panel's HUD and Sonar controls from the store
This commit is contained in:
1 parent
c99c0e8000
commit
3aa5a3e5e3
11 files changed
+118
-94
No files matched your search
@@ -94,7 +94,7 @@ They contain no application state.
|
||||
renders `LayerRows` synchronously; keyed chips and list items keep focus
|
||||
through the refresh their own click triggers, and clicks re-read the live
|
||||
descriptor before acting), Display (in progress: `DisplayPanel` renders
|
||||
bloom, sharpen and detection from the `gev-display` store, which VisualSettings
|
||||
the HUD, Sonar, detection, bloom and sharpen from the `gev-display` store, which VisualSettings
|
||||
publishes to; the other groups follow one owner at a time), Context and
|
||||
Radio, the command dock,
|
||||
the phone shell, then Cockpit. Layers that write into the right rail
|
||||
|
||||
@@ -116,6 +116,7 @@ export class StyleManager extends ShellFacade {
|
||||
this._lifetime = new UiLifetime();
|
||||
this._recording = new RecordingControls({
|
||||
syncShareState: () => this._syncShareState(),
|
||||
syncHudControls: () => this._visualSettings._syncHudControls(),
|
||||
});
|
||||
Object.assign(this, readShellElements());
|
||||
this._panelChrome = new PanelChrome({
|
||||
@@ -209,20 +210,6 @@ export class StyleManager extends ShellFacade {
|
||||
elements: {
|
||||
_celestialBtn: this._celestialBtn,
|
||||
_cockpitDisplayToggleBtn: this._cockpitDisplayToggleBtn,
|
||||
_hudBtn: this._hudBtn,
|
||||
_cyberSonarBtn: this._cyberSonarBtn,
|
||||
_cyberSonarRings: this._cyberSonarRings,
|
||||
_cyberSonarRingsValue: this._cyberSonarRingsValue,
|
||||
_cyberSonarRange: this._cyberSonarRange,
|
||||
_cyberSonarRangeValue: this._cyberSonarRangeValue,
|
||||
_cyberSonarIntensity: this._cyberSonarIntensity,
|
||||
_cyberSonarIntensityValue: this._cyberSonarIntensityValue,
|
||||
_cyberSonarOpacity: this._cyberSonarOpacity,
|
||||
_cyberSonarOpacityValue: this._cyberSonarOpacityValue,
|
||||
_cyberSonarSector: this._cyberSonarSector,
|
||||
_cyberSonarSectorValue: this._cyberSonarSectorValue,
|
||||
_hudLayoutRow: this._hudLayoutRow,
|
||||
_hudLayoutSelect: this._hudLayoutSelect,
|
||||
_ppToggles: this._ppToggles,
|
||||
_scopeBtn: this._scopeBtn,
|
||||
_scopeFeatherSlider: this._scopeFeatherSlider,
|
||||
@@ -1693,9 +1680,6 @@ export class StyleManager extends ShellFacade {
|
||||
*/
|
||||
|
||||
_initHUDToggle() {
|
||||
if (this._hudLayoutSelect) {
|
||||
this._hudLayoutSelect.value = 'tactical';
|
||||
}
|
||||
this._setHudVariant('tactical');
|
||||
this.hud.setMode('on');
|
||||
this._updateHudButtonState();
|
||||
|
||||
@@ -48,6 +48,8 @@ test('real runner and facade use visual settings, preserve visibility and return
|
||||
const renders = [];
|
||||
const visual = Object.create(VisualSettings.prototype);
|
||||
visual.services = { governorRequestRender: (reason) => renders.push(reason) };
|
||||
// No Display panel here: the controls' render is not under test.
|
||||
visual._publishDisplay = () => {};
|
||||
const owner = Object.create(StyleManager.prototype);
|
||||
owner._visualSettings = visual;
|
||||
Object.defineProperty(owner, 'hud', { value: f.owner.hud });
|
||||
|
||||
@@ -65,6 +65,7 @@ function styleOwner(t, initialVariant = 'cyber') {
|
||||
const owner = Object.create(VisualSettings.prototype);
|
||||
Object.assign(owner, {
|
||||
activeStyle: 'normal',
|
||||
store: { publish() {} },
|
||||
readHud: () => hud,
|
||||
readShareLinks: () => ({ onStyleChange() {} }),
|
||||
_visualEffects: {
|
||||
@@ -76,7 +77,6 @@ function styleOwner(t, initialVariant = 'cyber') {
|
||||
),
|
||||
},
|
||||
services: { governorRequestRender() {}, setDetectionStyle() {} },
|
||||
_hudLayoutSelect: { value: initialVariant },
|
||||
_styleIndicator: {},
|
||||
_setBloomEnabled: (value) => calls.push(['bloom', value]),
|
||||
_setSharpenEnabled: (value) => calls.push(['sharpen', value]),
|
||||
@@ -116,7 +116,6 @@ test('visual styles retain Cyber through real preset application without droppin
|
||||
assert.equal(owner.activeStyle, style);
|
||||
assert.equal(hud.getVariant(), 'cyber');
|
||||
assert.equal(root.dataset.uiTheme, 'cyber');
|
||||
assert.equal(owner._hudLayoutSelect.value, 'cyber');
|
||||
assert.deepEqual(calls.at(-1), ['share', 'cyber']);
|
||||
}
|
||||
assert.equal(owner.stages.thermal.uniforms.sensitivity, 0.85);
|
||||
|
||||
@@ -205,3 +205,51 @@ test('detection renders its mode, rows, sliders and allocation', async (t) => {
|
||||
assert.equal(button.className, 'pp-toggle-btn');
|
||||
assert.equal($('detection-slider-row').classList.contains('visible'), false);
|
||||
});
|
||||
|
||||
test('the HUD and Sonar controls render what VisualSettings shows', async (t) => {
|
||||
const { store, $ } = fixture(t);
|
||||
const { owner } = settings(store);
|
||||
let visible = true;
|
||||
let variant = 'minimal';
|
||||
owner.readHud = () => ({
|
||||
get visible() {
|
||||
return visible;
|
||||
},
|
||||
getVariant: () => variant,
|
||||
});
|
||||
owner._scheduleAdaptivePanelLayout = () => {};
|
||||
assert.equal($('cyber-sonar-toggle').textContent, 'ON');
|
||||
assert.equal($('cyber-sonar-toggle').getAttribute('aria-pressed'), 'true');
|
||||
|
||||
owner._syncHudControls();
|
||||
await nextTick();
|
||||
assert.equal($('hud-toggle').classList.contains('active'), true);
|
||||
assert.equal($('hud-layout-row').classList.contains('visible'), true);
|
||||
assert.equal($('hud-layout-select').value, 'minimal');
|
||||
|
||||
visible = false;
|
||||
owner._updateHudButtonState();
|
||||
await nextTick();
|
||||
assert.equal($('hud-toggle').classList.contains('active'), false);
|
||||
assert.equal($('hud-layout-row').classList.contains('visible'), false);
|
||||
|
||||
owner._sonarShown = {
|
||||
enabled: false,
|
||||
rings: 5,
|
||||
range: 90,
|
||||
intensity: 40,
|
||||
opacity: 60,
|
||||
sector: 30,
|
||||
};
|
||||
owner._publishDisplay();
|
||||
await nextTick();
|
||||
const toggle = $('cyber-sonar-toggle');
|
||||
assert.equal(toggle.textContent, 'OFF');
|
||||
assert.equal(toggle.getAttribute('aria-pressed'), 'false');
|
||||
assert.equal(toggle.classList.contains('active'), false);
|
||||
assert.equal($('cyber-sonar-rings').value, '5');
|
||||
assert.equal($('cyber-sonar-rings-value').textContent, '5');
|
||||
assert.equal($('cyber-sonar-range-value').textContent, '90%');
|
||||
assert.equal($('cyber-sonar-sector').value, '30');
|
||||
assert.equal($('cyber-sonar-sector-value').textContent, '30°');
|
||||
});
|
||||
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* `v-range-value`: a range input's live value, written only when it differs.
|
||||
* `v-range-value`: a range input's (or select's) live value, written only
|
||||
* when it differs.
|
||||
* A `:value` binding would also rewrite the value attribute on every patch;
|
||||
* the directive runs after the element's min, max and step are patched, so
|
||||
* the value is never clamped to a stale range.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/** Own recording chrome, safe frames and the pre-recording HUD snapshot. */
|
||||
export class RecordingControls {
|
||||
constructor({ syncShareState }) {
|
||||
constructor({ syncShareState, syncHudControls }) {
|
||||
this._syncShareState = syncShareState;
|
||||
// Shows the HUD's visibility and layout on the Display controls.
|
||||
this._syncHudControls = syncHudControls;
|
||||
this.destroyed = false;
|
||||
this._recordingMode = false;
|
||||
this._recordingConfig = {
|
||||
@@ -12,8 +14,6 @@ export class RecordingControls {
|
||||
this._preRecordingHudState = null;
|
||||
this._safeFrameOverlay = document.getElementById('safe-frame-overlay');
|
||||
this._safeFrameBox = document.getElementById('safe-frame-box');
|
||||
this._hudLayoutSelect = document.getElementById('hud-layout-select');
|
||||
this._hudBtn = document.getElementById('hud-toggle');
|
||||
this.hud = null;
|
||||
}
|
||||
_initRecordingOverlay() {
|
||||
@@ -63,8 +63,6 @@ export class RecordingControls {
|
||||
} else if (hudMode === 'full' || hudMode === 'minimal') {
|
||||
this.hud.setMode('on');
|
||||
this.hud.setVariant(hudMode === 'minimal' ? 'minimal' : 'tactical');
|
||||
if (this._hudLayoutSelect)
|
||||
this._hudLayoutSelect.value = this.hud.getVariant();
|
||||
} else {
|
||||
this.hud.setMode('auto');
|
||||
}
|
||||
@@ -73,8 +71,6 @@ export class RecordingControls {
|
||||
this._preRecordingHudState = null;
|
||||
if (saved) {
|
||||
this.hud.setVariant(saved.variant);
|
||||
if (this._hudLayoutSelect)
|
||||
this._hudLayoutSelect.value = this.hud.getVariant();
|
||||
}
|
||||
this.hud.setMode(saved ? saved.mode : 'auto');
|
||||
if (this._safeFrameOverlay) {
|
||||
@@ -85,7 +81,7 @@ export class RecordingControls {
|
||||
);
|
||||
}
|
||||
}
|
||||
this._hudBtn.classList.toggle('active', this.hud.visible);
|
||||
this._syncHudControls();
|
||||
this._syncShareState();
|
||||
}
|
||||
destroy() {
|
||||
|
||||
@@ -11,23 +11,13 @@ export function readShellElements(document = globalThis.document) {
|
||||
_sharpenBtn: document.getElementById('sharpen-toggle'),
|
||||
_sharpenSlider: document.getElementById('sharpen-intensity-slider'),
|
||||
_hudBtn: document.getElementById('hud-toggle'),
|
||||
_hudLayoutRow: document.getElementById('hud-layout-row'),
|
||||
_hudLayoutSelect: document.getElementById('hud-layout-select'),
|
||||
_cyberSonarBtn: document.getElementById('cyber-sonar-toggle'),
|
||||
_cyberSonarRings: document.getElementById('cyber-sonar-rings'),
|
||||
_cyberSonarRingsValue: document.getElementById('cyber-sonar-rings-value'),
|
||||
_cyberSonarRange: document.getElementById('cyber-sonar-range'),
|
||||
_cyberSonarRangeValue: document.getElementById('cyber-sonar-range-value'),
|
||||
_cyberSonarIntensity: document.getElementById('cyber-sonar-intensity'),
|
||||
_cyberSonarIntensityValue: document.getElementById(
|
||||
'cyber-sonar-intensity-value',
|
||||
),
|
||||
_cyberSonarOpacity: document.getElementById('cyber-sonar-opacity'),
|
||||
_cyberSonarOpacityValue: document.getElementById(
|
||||
'cyber-sonar-opacity-value',
|
||||
),
|
||||
_cyberSonarSector: document.getElementById('cyber-sonar-sector'),
|
||||
_cyberSonarSectorValue: document.getElementById('cyber-sonar-sector-value'),
|
||||
_detectionDensitySlider: document.getElementById(
|
||||
'detection-density-slider',
|
||||
),
|
||||
|
||||
@@ -200,7 +200,11 @@ test('recording restores the original HUD after repeated entry and revokes retai
|
||||
try {
|
||||
let mode = 'auto',
|
||||
variant = 'tactical';
|
||||
const owner = new RecordingControls({ syncShareState() {} });
|
||||
const hudSyncs = [];
|
||||
const owner = new RecordingControls({
|
||||
syncShareState() {},
|
||||
syncHudControls: () => hudSyncs.push(variant),
|
||||
});
|
||||
owner.hud = {
|
||||
getMode: () => mode,
|
||||
getVariant: () => variant,
|
||||
@@ -218,6 +222,11 @@ test('recording restores the original HUD after repeated entry and revokes retai
|
||||
owner.setRecordingMode(true);
|
||||
assert.equal(mode, 'auto');
|
||||
assert.equal(variant, 'tactical');
|
||||
assert.deepEqual(
|
||||
hudSyncs,
|
||||
['minimal', 'minimal', 'tactical'],
|
||||
'each change shows the HUD layout it leaves',
|
||||
);
|
||||
assert.equal(document.body.classList.contains('recording-mode'), false);
|
||||
assert.equal(
|
||||
f.nodes.get('safe-frame-overlay').classList.contains('active'),
|
||||
|
||||
@@ -5,11 +5,14 @@ import { t } from '../../../i18n/index.js';
|
||||
import { vRangeValue } from '../../rail/rangeValue.js';
|
||||
import { useDisplayStore } from '../../stores/display.js';
|
||||
|
||||
// The Display panel. VisualSettings presents bloom, sharpen and detection
|
||||
// and publishes them; until it does, the panel shows its initial markup.
|
||||
// The other groups keep their owners' element bindings.
|
||||
// The Display panel. VisualSettings presents the HUD, Sonar, detection,
|
||||
// bloom and sharpen and publishes them; until it does, the panel shows its
|
||||
// initial markup. The other groups keep their owners' element bindings.
|
||||
const { view } = storeToRefs(useDisplayStore());
|
||||
const pct = (value) => `${value}%`;
|
||||
const hud = computed(() => view.value?.hud ?? null);
|
||||
const sonar = computed(() => view.value?.sonar ?? null);
|
||||
const sonarOn = computed(() => sonar.value?.enabled ?? true);
|
||||
const detection = computed(() => view.value?.detection ?? null);
|
||||
const detectButton = computed(() => detection.value?.button ?? null);
|
||||
const allocation = computed(() => detection.value?.allocation ?? 'ELASTIC');
|
||||
@@ -29,13 +32,13 @@ const allocationSegment = (value) => ({
|
||||
</div>
|
||||
<div class="pp-panel-body" data-rail-scroller>
|
||||
<div class="pp-toggle-group">
|
||||
<button class="pp-toggle-btn" id="hud-toggle" title="Intelligence HUD (H)" data-i18n-title>
|
||||
<button class="pp-toggle-btn" :class="{ active: hud?.visible }" id="hud-toggle" title="Intelligence HUD (H)" data-i18n-title>
|
||||
<span class="pp-icon">◎</span>
|
||||
<span class="pp-label" translate="no">HUD</span>
|
||||
</button>
|
||||
<div class="pp-slider-row" id="hud-layout-row">
|
||||
<div class="pp-slider-row" :class="{ visible: hud?.visible }" id="hud-layout-row">
|
||||
<span class="pp-slider-mini-label" data-i18n>Layout</span>
|
||||
<select id="hud-layout-select" class="pp-select gev-field gev-field--compact" aria-label="HUD layout" data-i18n-aria-label>
|
||||
<select id="hud-layout-select" class="pp-select gev-field gev-field--compact" v-range-value="hud?.variant ?? 'tactical'" aria-label="HUD layout" data-i18n-aria-label>
|
||||
<option value="tactical" data-i18n>Tactical</option>
|
||||
<option value="minimal" data-i18n>Minimal</option>
|
||||
<option value="cyber" data-i18n>Cyber</option>
|
||||
@@ -43,33 +46,33 @@ const allocationSegment = (value) => ({
|
||||
</div>
|
||||
<div class="pp-slider-row cyber-sonar-control cyber-sonar-toggle-row" id="cyber-sonar-row">
|
||||
<span class="pp-slider-mini-label" data-i18n>Sonar</span>
|
||||
<button class="pp-mode-btn active" id="cyber-sonar-toggle" title="Cyber sonar contact scanner" aria-label="Cyber sonar contact scanner" aria-pressed="true" data-i18n-title data-i18n-aria-label data-i18n>ON</button>
|
||||
<button class="pp-mode-btn" :class="{ active: sonarOn }" id="cyber-sonar-toggle" title="Cyber sonar contact scanner" aria-label="Cyber sonar contact scanner" :aria-pressed="String(sonarOn)" data-i18n-title data-i18n-aria-label>{{ sonarOn ? t('ON') : t('OFF') }}</button>
|
||||
</div>
|
||||
<output id="cyber-sonar-status" class="cyber-sonar-control" role="status"></output>
|
||||
<div class="pp-slider-row cyber-sonar-control cyber-sonar-setting" id="cyber-sonar-rings-row">
|
||||
<label class="pp-slider-mini-label" for="cyber-sonar-rings" data-i18n>Rings</label>
|
||||
<input type="range" class="gev-quantitative-slider pp-slider" id="cyber-sonar-rings" min="3" max="12" step="1" value="8" aria-label="Sonar ring count" data-i18n-aria-label />
|
||||
<span class="pp-slider-value" id="cyber-sonar-rings-value">8</span>
|
||||
<input type="range" class="gev-quantitative-slider pp-slider" id="cyber-sonar-rings" min="3" max="12" step="1" value="8" v-range-value="sonar?.rings ?? 8" aria-label="Sonar ring count" data-i18n-aria-label />
|
||||
<span class="pp-slider-value" id="cyber-sonar-rings-value">{{ sonar?.rings ?? 8 }}</span>
|
||||
</div>
|
||||
<div class="pp-slider-row cyber-sonar-control cyber-sonar-setting" id="cyber-sonar-range-row">
|
||||
<label class="pp-slider-mini-label" for="cyber-sonar-range" data-i18n>Range</label>
|
||||
<input type="range" class="gev-quantitative-slider pp-slider" id="cyber-sonar-range" min="60" max="120" step="1" value="100" aria-label="Sonar ring range" data-i18n-aria-label />
|
||||
<span class="pp-slider-value" id="cyber-sonar-range-value">100%</span>
|
||||
<input type="range" class="gev-quantitative-slider pp-slider" id="cyber-sonar-range" min="60" max="120" step="1" value="100" v-range-value="sonar?.range ?? 100" aria-label="Sonar ring range" data-i18n-aria-label />
|
||||
<span class="pp-slider-value" id="cyber-sonar-range-value">{{ pct(sonar?.range ?? 100) }}</span>
|
||||
</div>
|
||||
<div class="pp-slider-row cyber-sonar-control cyber-sonar-setting" id="cyber-sonar-intensity-row">
|
||||
<label class="pp-slider-mini-label" for="cyber-sonar-intensity" data-i18n>Power</label>
|
||||
<input type="range" class="gev-quantitative-slider pp-slider" id="cyber-sonar-intensity" min="0" max="100" step="1" value="70" aria-label="Sonar intensity" data-i18n-aria-label />
|
||||
<span class="pp-slider-value" id="cyber-sonar-intensity-value">70%</span>
|
||||
<input type="range" class="gev-quantitative-slider pp-slider" id="cyber-sonar-intensity" min="0" max="100" step="1" value="70" v-range-value="sonar?.intensity ?? 70" aria-label="Sonar intensity" data-i18n-aria-label />
|
||||
<span class="pp-slider-value" id="cyber-sonar-intensity-value">{{ pct(sonar?.intensity ?? 70) }}</span>
|
||||
</div>
|
||||
<div class="pp-slider-row cyber-sonar-control cyber-sonar-setting" id="cyber-sonar-opacity-row">
|
||||
<label class="pp-slider-mini-label" for="cyber-sonar-opacity" data-i18n>Opacity</label>
|
||||
<input type="range" class="gev-quantitative-slider pp-slider" id="cyber-sonar-opacity" min="35" max="100" step="1" value="84" aria-label="Cyber contact and label opacity" title="Minimum opacity for map dots, icons, models, brackets, and labels between sonar passes" data-i18n-aria-label data-i18n-title />
|
||||
<span class="pp-slider-value" id="cyber-sonar-opacity-value">84%</span>
|
||||
<input type="range" class="gev-quantitative-slider pp-slider" id="cyber-sonar-opacity" min="35" max="100" step="1" value="84" v-range-value="sonar?.opacity ?? 84" aria-label="Cyber contact and label opacity" title="Minimum opacity for map dots, icons, models, brackets, and labels between sonar passes" data-i18n-aria-label data-i18n-title />
|
||||
<span class="pp-slider-value" id="cyber-sonar-opacity-value">{{ pct(sonar?.opacity ?? 84) }}</span>
|
||||
</div>
|
||||
<div class="pp-slider-row cyber-sonar-control cyber-sonar-setting" id="cyber-sonar-sector-row">
|
||||
<label class="pp-slider-mini-label" for="cyber-sonar-sector" data-i18n>Sector</label>
|
||||
<input type="range" class="gev-quantitative-slider pp-slider" id="cyber-sonar-sector" min="8" max="60" step="1" value="24" aria-label="Sonar sector width" data-i18n-aria-label />
|
||||
<span class="pp-slider-value" id="cyber-sonar-sector-value">24°</span>
|
||||
<input type="range" class="gev-quantitative-slider pp-slider" id="cyber-sonar-sector" min="8" max="60" step="1" value="24" v-range-value="sonar?.sector ?? 24" aria-label="Sonar sector width" data-i18n-aria-label />
|
||||
<span class="pp-slider-value" id="cyber-sonar-sector-value">{{ `${sonar?.sector ?? 24}°` }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pp-toggle-group">
|
||||
|
||||
+29
-37
@@ -213,6 +213,11 @@ export class VisualSettings {
|
||||
this._detectionOutsidePct = 1;
|
||||
this._detectionModeLabel = null;
|
||||
this._detectionAllocationShown = null;
|
||||
// What the HUD and Sonar controls show; null until first synced, so the
|
||||
// initial markup stands.
|
||||
this._hudVisibleShown = null;
|
||||
this._hudVariantShown = null;
|
||||
this._sonarShown = null;
|
||||
this.activeStyle = 'normal';
|
||||
this._preCyberStyle = null;
|
||||
this._cyberStyleUserSelected = false;
|
||||
@@ -476,6 +481,8 @@ export class VisualSettings {
|
||||
bloom: { active: this.bloomEnabled, intensity: this.bloomIntensityPct },
|
||||
sharpen: { active: this.sharpenEnabled, intensity: this._sharpenPct },
|
||||
detection: this._presentDetection(),
|
||||
hud: { visible: this._hudVisibleShown, variant: this._hudVariantShown },
|
||||
sonar: this._sonarShown,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -666,9 +673,8 @@ export class VisualSettings {
|
||||
this._preCyberStyle = this.activeStyle;
|
||||
this._cyberStyleUserSelected = false;
|
||||
}
|
||||
if (this._hudLayoutSelect && this._hudLayoutSelect.value !== nextVariant) {
|
||||
this._hudLayoutSelect.value = nextVariant;
|
||||
}
|
||||
this._hudVariantShown = nextVariant;
|
||||
this._publishDisplay();
|
||||
const visualDefaults = cyberVisualDefaultsForHudTransition(
|
||||
previousVariant,
|
||||
nextVariant,
|
||||
@@ -709,37 +715,16 @@ export class VisualSettings {
|
||||
}
|
||||
|
||||
_syncCyberSonarControl() {
|
||||
if (!this._cyberSonarBtn) return;
|
||||
const enabled = isCyberSonarEnabled();
|
||||
const settings = applyCyberSonarSettings(readCyberSonarSettings());
|
||||
this._cyberSonarBtn.classList.toggle('active', enabled);
|
||||
this._cyberSonarBtn.setAttribute('aria-pressed', String(enabled));
|
||||
this._cyberSonarBtn.textContent = enabled ? t('ON') : t('OFF');
|
||||
for (const [input, output, value, suffix] of [
|
||||
[this._cyberSonarRings, this._cyberSonarRingsValue, settings.rings, ''],
|
||||
[this._cyberSonarRange, this._cyberSonarRangeValue, settings.range, '%'],
|
||||
[
|
||||
this._cyberSonarIntensity,
|
||||
this._cyberSonarIntensityValue,
|
||||
settings.intensity,
|
||||
'%',
|
||||
],
|
||||
[
|
||||
this._cyberSonarOpacity,
|
||||
this._cyberSonarOpacityValue,
|
||||
settings.opacity,
|
||||
'%',
|
||||
],
|
||||
[
|
||||
this._cyberSonarSector,
|
||||
this._cyberSonarSectorValue,
|
||||
settings.sector,
|
||||
'°',
|
||||
],
|
||||
]) {
|
||||
if (input) input.value = String(value);
|
||||
if (output) output.textContent = `${value}${suffix}`;
|
||||
}
|
||||
this._sonarShown = {
|
||||
enabled: isCyberSonarEnabled(),
|
||||
rings: settings.rings,
|
||||
range: settings.range,
|
||||
intensity: settings.intensity,
|
||||
opacity: settings.opacity,
|
||||
sector: settings.sector,
|
||||
};
|
||||
this._publishDisplay();
|
||||
}
|
||||
|
||||
_setCyberSonarEnabled(enabled = !isCyberSonarEnabled()) {
|
||||
@@ -1587,10 +1572,17 @@ export class VisualSettings {
|
||||
}
|
||||
|
||||
_updateHudButtonState() {
|
||||
this._hudBtn.classList.toggle('active', this.hud.visible);
|
||||
if (this._hudLayoutRow) {
|
||||
this._hudLayoutRow.classList.toggle('visible', this.hud.visible);
|
||||
}
|
||||
this._syncHudControls();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the HUD's current visibility and layout on its controls; the layout
|
||||
* row's visibility changes the panel's height, so the rails settle again.
|
||||
*/
|
||||
_syncHudControls() {
|
||||
this._hudVisibleShown = Boolean(this.hud.visible);
|
||||
this._hudVariantShown = this.hud.getVariant();
|
||||
this._publishDisplay();
|
||||
this._scheduleAdaptivePanelLayout({ settle: true });
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user