How to Enter and Manage Cockpit Mode in God's Eye View

God's Eye View provides a dedicated Cockpit mode that locks onto a single aircraft, hides the map UI, and displays flight-instrument-style data through a coordinated system of tracking, input, and view controllers.

The Cockpit mode in God's Eye View (GEV) transforms the Cesium-based viewer into an immersive flight deck interface. This self-contained UI component manages the camera, renders HUD elements, and handles keyboard shortcuts while broadcasting state changes through global events. Understanding how to enter and manage Cockpit mode requires familiarity with three core modules that coordinate the lifecycle between the tracked aircraft, user input, and DOM rendering.

Prerequisites for Entering Cockpit Mode

Before activating Cockpit mode, the application must meet specific tracking requirements enforced by the CockpitTrackingController in src/ui/cockpitTrackingController.js.

The primary prerequisite is an actively tracked aircraft in the Cesium viewer. The system checks that viewer.trackedEntity exists and has a valid .position property. Additionally, any custom isEntryAllowed callback passed to the controller must return true. The syncEntry() method in the tracking controller evaluates these conditions and conditionally displays the entry button (#cockpit-entry) in the DOM.

Entering Cockpit Mode

Users can initiate Cockpit mode through two primary interaction paths: clicking the dedicated entry button or pressing the assigned keyboard shortcut. Both methods eventually invoke the enter() method in CockpitTrackingController.

Using the Entry Button

When a user clicks the Entry button (#cockpit-entry), the click listener installed in CockpitViewController (src/ui/cockpitController.js) forwards the call to the tracking controller.

The enter() method (lines 29-33 in cockpitTrackingController.js) performs the following sequence:

  1. Validates that the controller is not destroyed, already active, or blocked by entry restrictions.
  2. Captures the current viewer.trackedEntity and hides the entity from the default view.
  3. Stores the previously focused DOM element for restoration upon exit.
  4. Disables the default Cesium camera controller (viewer.scene.screenSpaceCameraController.enableInputs = false).
  5. Requests continuous rendering via services.holdContinuousRender('cockpit').
  6. Emits the gev:cockpit-mode-changed event with active: true and the aircraft identifier.
// In CockpitViewController constructor
this._listen(this.entry, 'click', () => this.enter());

// Core entry logic in CockpitTrackingController
export function enter() {
  if (this.destroyed || this.active || !this.isEntryAllowed()) return false;
  const info = this.readAircraftInfo();
  const entity = this.viewer.trackedEntity;
  if (!info || !entity?.position) return false;

  // Store focus for later restoration
  this.entryFocusOrigin = document.activeElement instanceof HTMLElement
    ? document.activeElement
    : null;

  // Take over the camera
  this.viewer.camera.cancelFlight();
  this.trackedEntity = entity;
  this.trackedEntityWasShown = entity.show;
  entity.show = false;
  this.heading = normalizeHeading(info.track ?? 0);
  this.active = true;

  // Enable exclusive rendering & UI
  this.services.holdContinuousRender('cockpit');
  this.viewer.scene.screenSpaceCameraController.enableInputs = false;
  document.body.classList.add('cockpit-mode');
  
  this.dispatchCockpitModeChanged(true, info);
  return true;
}

Using the Keyboard Shortcut

The c key toggles Cockpit mode globally when no input element has focus. The CockpitInput module in src/ui/cockpitInput.js captures this via onKeyDown(event) and forwards the command to the tracking controller. If entry criteria are satisfied, the system executes the same enter() sequence as the button click.

Managing Cockpit Mode

Once active, Cockpit mode provides specialized UI controls for vision modes, context navigation, and signal streams. These interactions are managed through CockpitViewController and CockpitInstruments (src/ui/cockpitInstruments.js).

Vision Mode and HUD Controls

The cockpit interface includes three vision mode buttons (#cockpit-vision-previous, #cockpit-vision-current, #cockpit-vision-next) that cycle through available visualization states. Clicking these triggers cycleVisionMode(dir) in the instruments module, which updates the HUD rendering via setVisionMode(mode).

Additional management controls include:

  • TR-3B toggle (#tr3b-toggle): Calls toggleTrackedTr3b() with UI synchronization via syncTr3bToggle().
  • Context navigation: Arrow buttons (#cockpit-context-previous / #cockpit-context-next) invoke navigateContext(dir, {origin:'user'}) to shift situational awareness contexts.
  • Signal stream collapse: The toggle button (#cockpit-signal-toggle) executes setSignalCollapsed(!this.signalCollapsed, {user:true}) to minimize data streams.

Keyboard Shortcuts for Panel Management

The Escape key serves a dual purpose within Cockpit mode. When pressed inside a specific panel (such as the context or signal stream panels), it collapses that panel and returns focus to the corresponding toggle button. When pressed with no panel active, it triggers the exit sequence.

// In cockpitInput.js
export function onKeyDown(event) {
  if (this.destroyed) return false;
  if (event.key === 'Escape' && this.active) {
    // Collapse context panel if active
    if (this.context?.contains(event.target) && !this.contextCollapsed) {
      event.preventDefault();
      this.setContextCollapsed(true);
      this.contextToggle?.focus({preventScroll:true});
      return;
    }
    // Collapse signal panel if active
    if (this.signalStream?.contains(event.target) && !this.signalCollapsed) {
      event.preventDefault();
      this.setSignalCollapsed(true, {user:true});
      this.signalToggle?.focus({preventScroll:true});
      return;
    }
    // No panel active → exit Cockpit
    event.preventDefault();
    this.exit();
    return;
  }
}

Exiting Cockpit Mode

Exiting restores the default Cesium camera controls and map interface. Users can exit via the Map-view button (#map-view-switch), pressing Escape (when no panels are focused), or toggling the c key again.

The exit() method in CockpitTrackingController performs cleanup in reverse order of entry:

  1. Sets this.active = false and releases the continuous render lock (services.releaseContinuousRender('cockpit')).
  2. Removes the cockpit-mode CSS class from the document body.
  3. Re-enables Cesium camera inputs (screenSpaceCameraController.enableInputs = true).
  4. Restores the previously tracked aircraft entity to its original visibility state.
  5. Dispatches the gev:cockpit-mode-changed event with active: false.
  6. Restores keyboard focus to the entry button or previously focused element.
// Exit handler in CockpitViewController
this._listen(this.mapViewButton, 'click', () => this.exit());

// Core exit logic
export function exit({ restoreTracking = true } = {}) {
  if (!this.active) return false;
  const entity = this.trackedEntity;
  this.active = false;
  this.services.releaseContinuousRender('cockpit');
  document.body.classList.remove('cockpit-mode');
  this.hud?.hidden = true;
  this.viewer.scene.screenSpaceCameraController.enableInputs = true;

  // Restore the aircraft entity
  if (restoreTracking && entity && this.viewer.entities.contains(entity)) {
    entity.show = this.trackedEntityWasShown;
    this.viewer.trackedEntity = entity;
    this.restoreTrackingFrame(entity);
  }

  this.dispatchCockpitModeChanged(false);
  this.syncEntry(); // re-show the entry button if applicable
  
  // Restore focus
  const restoreTarget = this.entryFocusOrigin === this.entry
    ? this.entry
    : this.entry || this.entryFocusOrigin;
  if (restoreTarget?.isConnected && !restoreTarget.hidden) {
    restoreTarget.focus({preventScroll:true});
  }
  return true;
}

Integrating with External Components

The dispatchCockpitModeChanged method emits the gev:cockpit-mode-changed event, enabling other application modules to react to state changes. The event detail includes active (boolean), subjectId (aircraft identifier), and layerId.

External controllers can listen for these events to hide overlays, pause background processes, or synchronize auxiliary displays:

window.addEventListener('gev:cockpit-mode-changed', (e) => {
  const { active, subjectId, layerId } = e.detail;
  console.log(`Cockpit mode ${active ? 'entered' : 'exited'} – aircraft ${subjectId}`);
  // Hide a custom overlay when cockpit starts
  document.getElementById('my-overlay').hidden = active;
});

Custom callbacks such as onEntered, onExited, and isEntryAllowed can be injected when instantiating CockpitViewController to integrate with application-specific business logic.

Summary

  • Prerequisites: Cockpit mode requires an active viewer.trackedEntity with a valid position; the entry button only appears when isEntryAllowed returns true.
  • Entry methods: Click the #cockpit-entry button or press c to invoke enter() in cockpitTrackingController.js, which locks the camera and hides the entity.
  • Management: Use vision mode buttons to cycle HUD styles, context arrows for navigation, and Escape to collapse panels; all input routes through cockpitInput.js.
  • Exit paths: Click the map-view button, press Escape (when no panel is focused), or press c again to trigger exit(), which restores camera controls and entity visibility.
  • Events: The system broadcasts gev:cockpit-mode-changed on every transition, allowing external modules to synchronize with Cockpit state changes.

Frequently Asked Questions

What keyboard shortcuts are available in God's Eye View Cockpit mode?

The c key toggles Cockpit mode on and off when no input field has focus. The Escape key collapses focused panels (such as context or signal streams) when pressed inside them, or exits Cockpit mode entirely when pressed elsewhere. These shortcuts are captured in src/ui/cockpitInput.js and forwarded to the tracking controller for execution.

Why is the Cockpit entry button disabled or hidden?

The entry button (#cockpit-entry) is controlled by the syncEntry() method in src/ui/cockpitTrackingController.js. It requires two conditions: the Cesium viewer must have an active trackedEntity with a defined position property, and any custom isEntryAllowed callback must return true. If either condition fails, the button remains hidden or inactive.

How do I programmatically detect when a user enters or exits Cockpit mode?

Listen for the gev:cockpit-mode-changed event on the window object. The event detail object contains active (boolean indicating entry or exit), subjectId (the aircraft identifier), and layerId. You can also pass onEntered and onExited callbacks when constructing the CockpitViewController instance to hook directly into the state transition logic.

Can I customize which aircraft or entities allow Cockpit mode entry?

Yes. When creating the CockpitViewController, provide an isEntryAllowed callback function in the configuration options. This function receives the current tracked entity and aircraft info, returning true to permit entry or false to block it. The callback is evaluated in the enter() method before any UI transitions occur.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →