Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/packages/firebird-ng/display/src/lib/components/tool-panel/tool-panel.component.ts is written in an unsupported language. File is not indexed.

0001 import { Component, Output, EventEmitter, ChangeDetectionStrategy, Signal, inject } from '@angular/core';
0002 import { NgIf } from '@angular/common';
0003 import { toSignal } from '@angular/core/rxjs-interop';
0004 import { MatIcon } from '@angular/material/icon';
0005 import { ViewOptionsComponent } from '../view-options/view-options.component';
0006 import { ThreeService } from '../../services/three.service';
0007 import { ConfigService } from '@dexvis/app-features';
0008 import {MatIconButton} from "@angular/material/button";
0009 import {MatTooltip} from "@angular/material/tooltip";
0010 import * as THREE from 'three';
0011 
0012 
0013 @Component({
0014     selector: 'app-tool-panel',
0015   imports: [
0016     NgIf,
0017     MatIcon,
0018     ViewOptionsComponent,
0019     MatIconButton,
0020     MatTooltip,
0021 
0022   ],
0023     templateUrl: './tool-panel.component.html',
0024     changeDetection: ChangeDetectionStrategy.OnPush,
0025     styleUrls: ['./tool-panel.component.scss']
0026 })
0027 export class ToolPanelComponent {
0028   @Output() cameraControlsToggle = new EventEmitter<void>();
0029 
0030   isCollapsed = false;
0031 
0032   /** Factor to zoom by. */
0033   private zoomFactor = 1.1;
0034   /** Whether camera is orthographic or perspective. */
0035   private orthographicView = false;
0036 
0037   /**
0038    * Draw event data over geometry regardless of depth — tracks stay visible
0039    * from every camera angle instead of hiding behind detector volumes.
0040    * Config-backed (`display.tracksOnTop`), so the mode is deep-linkable and
0041    * survives reloads; EventDisplayService applies it to the main view.
0042    */
0043   private tracksOnTopProperty = inject(ConfigService).getConfigOrCreate<boolean>('display.tracksOnTop', false);
0044   tracksOnTop: Signal<boolean> = toSignal(this.tracksOnTopProperty.subject, { requireSync: true });
0045 
0046   toggleTracksOnTop() {
0047     this.tracksOnTopProperty.value = !this.tracksOnTopProperty.value;
0048   }
0049 
0050   constructor(
0051     private threeService: ThreeService // no more EventDisplayService
0052   ) {}
0053 
0054   /**
0055    * Zoom in or out around the orbit controls target.
0056    * Use OrbitControls or direct camera logic from threeService.
0057    */
0058   private zoomTo(factor: number): void {
0059     const controls = this.threeService.controls;
0060     const cam = this.threeService.camera as THREE.Camera;
0061 
0062     // Ensure matrices are up to date
0063     cam.updateMatrixWorld(true);
0064 
0065     const target = controls.target;
0066 
0067     if ((cam as any).isOrthographicCamera) {
0068       const ortho = cam as THREE.OrthographicCamera;
0069       const newZoom = ortho.zoom / Math.max(1e-6, factor);
0070 
0071       ortho.zoom = THREE.MathUtils.clamp(newZoom, 0.01, 1e5);
0072       ortho.updateProjectionMatrix();
0073 
0074     } else if ((cam as any).isPerspectiveCamera) {
0075       const persp = cam as THREE.PerspectiveCamera;
0076 
0077       const dir = new THREE.Vector3().subVectors(persp.position, target).normalize();
0078       const dist = persp.position.distanceTo(target);
0079 
0080       let newDist = dist * factor;
0081 
0082       const minD = (controls as any).minDistance ?? 0.001;
0083       const maxD = (controls as any).maxDistance ?? Infinity;
0084       newDist = THREE.MathUtils.clamp(newDist, minD, maxD);
0085 
0086       const newPos = new THREE.Vector3().copy(target).addScaledVector(dir, newDist);
0087       persp.position.copy(newPos);
0088 
0089       persp.lookAt(target);
0090     }
0091 
0092     controls.update();
0093   }
0094 
0095   onLeftClick(event: MouseEvent, action: string) {
0096     // Only respond to left-button
0097     if (event.button === 0) {
0098       if (action === 'zoomIn') {
0099         this.zoomIn();
0100       } else if (action === 'zoomOut') {
0101         this.zoomOut();
0102       }
0103     }
0104   }
0105 
0106   zoomIn() {
0107     this.zoomTo(1 / this.zoomFactor);
0108   }
0109 
0110   zoomOut() {
0111     this.zoomTo(this.zoomFactor);
0112   }
0113 
0114   clearZoom() {
0115     // If you had logic for continuous zoom while mouse is held, you can clear it here
0116   }
0117 
0118   togglePanel() {
0119     this.isCollapsed = !this.isCollapsed;
0120   }
0121 
0122   /**
0123    * Switch between orthographic and perspective camera.
0124    * You can define a method in ThreeService to do the actual swap or toggling.
0125    */
0126   switchMainView() {
0127     this.orthographicView = !this.orthographicView;
0128     this.threeService.toggleOrthographicView(this.orthographicView);
0129   }
0130 
0131   onCameraControlsToggle() {
0132     this.cameraControlsToggle.emit();
0133   }
0134 }