mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
feat(awareness): render the Global Context compass from a store
The awareness layer presents the compass ring, heading, cardinal labels and contact bearing markers through subscribeDirectionOverlay(); the application shell publishes them to the gev-awareness-direction store and the scene chrome renders them in the viewer's container.
This commit is contained in:
1 parent
b22e138c55
commit
b96cc37ab5
14 files changed
+389
-100
No files matched your search
@@ -57,6 +57,7 @@ import { useContextStore } from './stores/context.js';
|
||||
import { useMissionReplayStore } from './stores/missionReplay.js';
|
||||
import { useCelestialRingStore } from './stores/celestialRing.js';
|
||||
import { useWorldOverlayActionsStore } from './stores/worldOverlayActions.js';
|
||||
import { useAwarenessDirectionStore } from './stores/awarenessDirection.js';
|
||||
import { useDisplayStore } from './stores/display.js';
|
||||
import { useLocaleStore } from './stores/locale.js';
|
||||
import { useLocationStore } from './stores/location.js';
|
||||
@@ -1042,6 +1043,15 @@ export class StyleManager extends ShellFacade {
|
||||
this._awarenessPanelUnsubscribe = militaryAwarenessLayer?.subscribePanel?.(
|
||||
(view) => contextStore.publishAwareness(view),
|
||||
);
|
||||
// And its compass and contact bearings, which the scene chrome renders.
|
||||
const awarenessDirectionStore =
|
||||
useAwarenessDirectionStore(applicationPinia());
|
||||
this._awarenessDirectionUnsubscribe?.();
|
||||
awarenessDirectionStore.publish(null);
|
||||
this._awarenessDirectionUnsubscribe =
|
||||
militaryAwarenessLayer?.subscribeDirectionOverlay?.((view) =>
|
||||
awarenessDirectionStore.publish(view),
|
||||
);
|
||||
// The Space Missions layer publishes its roster and selected mission.
|
||||
contextStore.connectMissions(rocketLaunchesLayer);
|
||||
this._missionsPanelUnsubscribe?.();
|
||||
@@ -1805,6 +1815,9 @@ export class StyleManager extends ShellFacade {
|
||||
this._localSdrControls?.destroy();
|
||||
this._awarenessPanelUnsubscribe?.();
|
||||
this._awarenessPanelUnsubscribe = null;
|
||||
this._awarenessDirectionUnsubscribe?.();
|
||||
this._awarenessDirectionUnsubscribe = null;
|
||||
useAwarenessDirectionStore(applicationPinia()).publish(null);
|
||||
this._missionsPanelUnsubscribe?.();
|
||||
this._missionsPanelUnsubscribe = null;
|
||||
this._missionReplayUnsubscribe?.();
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { shallowRef } from 'vue';
|
||||
|
||||
/**
|
||||
* The Global Context compass and contact direction overlay as its view
|
||||
* renders it. The awareness layer presents it through
|
||||
* `subscribeDirectionOverlay()` and the application shell publishes it here.
|
||||
*/
|
||||
export const useAwarenessDirectionStore = defineStore(
|
||||
'gev-awareness-direction',
|
||||
() => {
|
||||
/**
|
||||
* `{container, hidden, ring, heading, labels, markers}`, or null while
|
||||
* the layer has no overlay. `container` is the element it sits in.
|
||||
*/
|
||||
const overlay = shallowRef(null);
|
||||
|
||||
/**
|
||||
* @param {?object} next A fresh presentation, frozen by the layer; every
|
||||
* publish re-renders.
|
||||
*/
|
||||
function publish(next) {
|
||||
overlay.value = next;
|
||||
}
|
||||
|
||||
return { overlay, publish };
|
||||
},
|
||||
);
|
||||
@@ -14,6 +14,7 @@ import SplitFlapText from './panels/SplitFlapText.vue';
|
||||
import WindInspectionMarker from './panels/WindInspectionMarker.vue';
|
||||
import CelestialRing from './panels/CelestialRing.vue';
|
||||
import ScreenAnnotations from './panels/ScreenAnnotations.vue';
|
||||
import AwarenessDirection from './panels/AwarenessDirection.vue';
|
||||
|
||||
// The ACTIVE STYLE corner shows the style VisualSettings publishes.
|
||||
const { style } = storeToRefs(useDisplayStore());
|
||||
@@ -127,4 +128,5 @@ const vToastText = {
|
||||
<WindInspectionMarker />
|
||||
<MissionReplayOverlay />
|
||||
<ScreenAnnotations />
|
||||
<AwarenessDirection />
|
||||
</template>
|
||||
@@ -0,0 +1,18 @@
|
||||
<script setup>
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useAwarenessDirectionStore } from '../../stores/awarenessDirection.js';
|
||||
|
||||
// The Global Context compass and the nearest contacts' bearings, inside the
|
||||
// viewer's container, as the awareness layer presents them.
|
||||
const { overlay } = storeToRefs(useAwarenessDirectionStore());
|
||||
|
||||
// A part keeps no inline placement until the layer first places it.
|
||||
const place = (part) =>
|
||||
part.left === null ? undefined : { left: part.left, top: part.top };
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Teleport v-if="overlay" :to="overlay.container">
|
||||
<div id="military-awareness-direction-overlay" :hidden="overlay.hidden" aria-hidden="true"><span v-for="label in overlay.labels" :key="label.label" :class="`military-awareness-compass-label cardinal-${label.label.toLowerCase()}`" :data-bearing="String(label.bearing)" :style="place(label)">{{ label.label }}</span><div class="military-awareness-compass-ring" :style="overlay.ring ?? undefined"></div><span class="military-awareness-compass-heading" :style="place(overlay.heading)">{{ overlay.heading.text }}</span><div v-for="(marker, index) in overlay.markers" :key="index" class="military-awareness-direction-marker" :hidden="marker.hidden" :style="marker.style ?? undefined"><span class="military-awareness-direction-arrow" :style="marker.arrow ?? undefined">➜</span><span class="military-awareness-direction-label" :style="marker.caption.style ?? undefined">{{ marker.caption.text }}</span></div></div>
|
||||
</Teleport>
|
||||
</template>
|
||||
Reference in new issue
Block a user