Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/firebird-ng/src/app/components/object-clipping/object-clipping.component.ts is written in an unsupported language. File is not indexed.

0001 import {
0002   Component,
0003   OnInit,
0004   OnDestroy,
0005   ViewChild,
0006   TemplateRef,
0007   ElementRef,
0008   ViewContainerRef,
0009   ChangeDetectorRef
0010 } from '@angular/core';
0011 import {MatCheckbox, MatCheckboxChange} from '@angular/material/checkbox';
0012 import { Subscription } from 'rxjs';
0013 
0014 import { ThreeService } from '../../services/three.service';
0015 import { LocalStorageService } from '../../services/local-storage.service';
0016 import {MatMenuItem} from "@angular/material/menu";
0017 import {MatSlider, MatSliderThumb} from "@angular/material/slider";
0018 
0019 import {MatButton, MatIconButton} from "@angular/material/button";
0020 
0021 import {MatDialog, MatDialogClose, MatDialogRef} from "@angular/material/dialog";
0022 import {MatIcon} from "@angular/material/icon";
0023 import {MatTooltip} from "@angular/material/tooltip";
0024 import {FormsModule} from "@angular/forms";
0025 
0026 
0027 
0028 @Component({
0029   selector: 'app-custom-object-clipping',
0030   templateUrl: './object-clipping.component.html',
0031   styleUrls: ['./object-clipping.component.scss'],
0032   imports: [
0033     MatSlider,
0034     MatMenuItem,
0035     MatSliderThumb,
0036     MatCheckbox,
0037     MatButton,
0038     MatIcon,
0039     MatDialogClose,
0040     MatIconButton,
0041     MatTooltip,
0042     FormsModule,
0043 
0044   ]
0045 })
0046 export class ObjectClippingComponent implements OnInit, OnDestroy {
0047   /** Local copies that reflect the config property values. */
0048   clippingEnabled = false;
0049   startClippingAngle = 0;
0050   openingClippingAngle = 180;
0051 
0052   private subscriptions: Subscription[] = [];
0053 
0054   @ViewChild('openBtn', { read: ElementRef }) openBtn!: ElementRef;
0055   @ViewChild('dialogTemplate') dialogTemplate!: TemplateRef<any>;
0056   dialogRef: MatDialogRef<any> | null = null;
0057 
0058   constructor(
0059     private threeService: ThreeService,
0060     private config: LocalStorageService,
0061     private dialog: MatDialog,
0062     private viewContainerRef: ViewContainerRef,
0063     private cdr: ChangeDetectorRef
0064   ) {}
0065 
0066   ngOnInit(): void {
0067     // 1) Initialize local values from the config
0068     this.clippingEnabled = this.config.clippingEnabled.value;
0069     this.startClippingAngle = this.config.clippingStartAngle.value;
0070     this.openingClippingAngle = this.config.clippingOpeningAngle.value;
0071 
0072     // 2) Subscribe to config changes so if another component or code updates them,
0073     //    this component sees the updated values automatically:
0074     this.subscriptions.push(
0075       this.config.clippingEnabled.changes$.subscribe((enabled) => {
0076         this.clippingEnabled = enabled;
0077         // Also immediately update ThreeService
0078         this.threeService.enableClipping(enabled);
0079         if (enabled) {
0080           this.threeService.setClippingAngle(
0081             this.config.clippingStartAngle.value,
0082             this.config.clippingOpeningAngle.value
0083           );
0084         }
0085       })
0086     );
0087 
0088     this.subscriptions.push(
0089       this.config.clippingStartAngle.changes$.subscribe((value) => {
0090         this.startClippingAngle = value;
0091         if (this.config.clippingEnabled.value) {
0092           this.threeService.setClippingAngle(
0093             value,
0094             this.config.clippingOpeningAngle.value
0095           );
0096         }
0097       })
0098     );
0099 
0100     this.subscriptions.push(
0101       this.config.clippingOpeningAngle.changes$.subscribe((value) => {
0102         this.openingClippingAngle = value;
0103         if (this.config.clippingEnabled.value) {
0104           this.threeService.setClippingAngle(
0105             this.config.clippingStartAngle.value,
0106             value
0107           );
0108         }
0109       })
0110     );
0111 
0112     // 3) Optionally trigger an initial clipping if was enabled:
0113     if (this.clippingEnabled) {
0114       this.threeService.enableClipping(true);
0115       this.threeService.setClippingAngle(this.startClippingAngle, this.openingClippingAngle);
0116     }
0117   }
0118 
0119   ngOnDestroy(): void {
0120     // Unsubscribe from config property streams to avoid memory leaks.
0121     for (const sub of this.subscriptions) {
0122       sub.unsubscribe();
0123     }
0124   }
0125 
0126   /**
0127    * User toggles clipping in the UI checkbox.
0128    */
0129   toggleClipping(change: MatCheckboxChange): void {
0130     // Update the config property. This automatically saves to localStorage
0131     // and triggers the subscription above, which updates the ThreeService.
0132     this.config.clippingEnabled.value = change.checked;
0133   }
0134 
0135   /**
0136    * User changes the start angle. Use the config property setter to persist and update the scene.
0137    */
0138   changeStartClippingAngle(angle: number): void {
0139     this.config.clippingStartAngle.value = angle;
0140   }
0141 
0142   /**
0143    * User changes the opening angle. Use the config property setter to persist and update the scene.
0144    */
0145   changeOpeningClippingAngle(angle: number): void {
0146     this.config.clippingOpeningAngle.value = angle;
0147   }
0148 
0149 
0150   openDialog(): void {
0151   if (this.dialogRef) {
0152     this.dialogRef.close();
0153     return;
0154   }
0155 
0156     const rect = this.openBtn.nativeElement.getBoundingClientRect();
0157     const dialogWidth = 320;
0158 
0159     const left = Math.max(rect.right - dialogWidth, 8);
0160     const top = rect.bottom + 12;
0161 
0162     this.dialogRef = this.dialog.open(this.dialogTemplate, {
0163       position: {
0164         top: `${top}px`,
0165         left: `${left}px`
0166       },
0167       hasBackdrop: false,
0168       panelClass: 'custom-position-dialog',
0169       autoFocus: false,
0170       viewContainerRef: this.viewContainerRef
0171     });
0172 
0173     this.dialogRef.afterClosed().subscribe(() => {
0174       this.dialogRef = null;
0175     });
0176   }
0177 
0178 
0179   /**
0180    * Updates angle value in real-time as any slider moves
0181    * @param event The slider input event
0182    * @param sliderType Identifier for which slider is being updated ('start' or 'opening')
0183    */
0184   onSliderInput(event: any, sliderType: 'start' | 'opening'): void {
0185     // Extract the value safely from the event
0186     let newValue: number | null = null;
0187 
0188     // Try different ways to get the value based on Angular Material version
0189     if (event && event.value !== undefined) {
0190       newValue = event.value;
0191     } else if (event && event.source && event.source.value !== undefined) {
0192       newValue = event.source.value;
0193     } else if (event && event.target && event.target.value !== undefined) {
0194       newValue = Number(event.target.value);
0195     }
0196 
0197     // Only update if we got a valid number
0198     if (newValue !== null && !isNaN(newValue)) {
0199       // Update the appropriate property based on which slider was moved
0200       if (sliderType === 'start') {
0201         this.startClippingAngle = newValue;
0202       } else if (sliderType === 'opening') {
0203         this.openingClippingAngle = newValue;
0204       }
0205     }
0206   }
0207 
0208 
0209 }