Warning, /firebird/packages/firebird-ng/display/src/lib/components/event-time-control/event-time-control.component.ts is written in an unsupported language. File is not indexed.
0001 import {
0002 Component,
0003 computed,
0004 Signal,
0005 ViewChild,
0006 TemplateRef,
0007 ElementRef,
0008 ChangeDetectionStrategy
0009 } from '@angular/core';
0010 import { MatSliderModule } from '@angular/material/slider';
0011 import {DecimalPipe} from '@angular/common';
0012 import { MatInputModule } from '@angular/material/input';
0013 import {EventDisplayService} from "../../services/event-display.service";
0014 import {FormsModule} from "@angular/forms";
0015 import {MatButton, MatIconButton} from "@angular/material/button";
0016 import {MatIcon} from "@angular/material/icon";
0017 import {MatTooltip} from "@angular/material/tooltip";
0018 import {MatDialog, MatDialogClose, MatDialogRef} from "@angular/material/dialog";
0019
0020 @Component({
0021 selector: 'app-event-time-control',
0022 standalone: true,
0023 imports: [MatSliderModule, MatInputModule, DecimalPipe, MatButton, FormsModule, MatIcon, MatIconButton, MatTooltip, MatDialogClose],
0024 templateUrl: './event-time-control.component.html',
0025 changeDetection: ChangeDetectionStrategy.OnPush,
0026 styleUrls: ['./event-time-control.component.scss']
0027 })
0028 export class EventTimeControlComponent {
0029
0030 @ViewChild('openBtn', { read: ElementRef })
0031 openBtn!: ElementRef;
0032
0033 @ViewChild('dialogTemplate')
0034 dialogTemplate!: TemplateRef<any>;
0035
0036 dialogRef: MatDialogRef<any> | null = null;
0037
0038
0039 // Dialog form fields. Read and written only inside the dialog template
0040 // (the dialog's own view), and refreshed from the service on every open:
0041 // an event load changes the range after this component was created.
0042 customStartTime = 0;
0043 customEndTime = 0;
0044 animationSpeed = 1.0;
0045
0046 constructor(public eventDisplayService: EventDisplayService,
0047 private dialog: MatDialog)
0048 {
0049
0050 }
0051
0052 public shownTime: Signal<number> = computed(()=>{
0053 const edTime = this.eventDisplayService.eventTime();
0054 if(edTime === null || edTime === undefined) {
0055 return this.eventDisplayService.minTime();
0056 }
0057 return edTime;
0058 })
0059
0060 /**
0061 * Called whenever the slider input changes.
0062 * It extracts the new value and updates the service's time.
0063 */
0064 changeCurrentTime(event: Event): void {
0065 if (!event) return;
0066 const input = event.target as HTMLInputElement;
0067 const value = parseFloat(input.value);
0068 this.eventDisplayService.updateEventTime(value);
0069 }
0070
0071 onThumbInput(event: Event): void {
0072 const input = event.target as HTMLInputElement;
0073 const value = parseFloat(input.value);
0074 this.eventDisplayService.updateEventTime(value);
0075 }
0076
0077 /**
0078 * A function to format the numeric slider value to display e.g. 1 decimal place.
0079 */
0080 formatCurrentTime(value: number): string {
0081 return value.toFixed(1);
0082 }
0083
0084
0085 openDialog(): void {
0086 if (this.dialogRef) {
0087 this.dialogRef.close();
0088 return;
0089 }
0090
0091 this.customStartTime = this.eventDisplayService.minTime();
0092 this.customEndTime = this.eventDisplayService.maxTime();
0093 this.animationSpeed = this.eventDisplayService.animationSpeed();
0094
0095 const rect = this.openBtn.nativeElement.getBoundingClientRect();
0096 const dialogWidth = this.dialogTemplate?.elementRef.nativeElement.offsetWidth || 320;
0097
0098
0099 const left = rect.right - dialogWidth;
0100
0101 this.dialogRef = this.dialog.open(this.dialogTemplate, {
0102 position: {
0103 bottom: `${window.innerHeight - rect.bottom + 55}px`,
0104 left: `${Math.max(left, 0)}px`
0105 },
0106 hasBackdrop: false,
0107 panelClass: 'custom-position-dialog',
0108 autoFocus: false
0109 });
0110
0111 this.dialogRef.afterClosed().subscribe(() => {
0112 this.dialogRef = null;
0113 });
0114 }
0115
0116 /**
0117 * Applies the dialog's range and step. They go to service signals: the
0118 * slider and the range label live in this component's own view, which an
0119 * event inside the dialog does not mark for check (the dialog renders the
0120 * template elsewhere), but a signal read there does.
0121 */
0122 applyCustomTimeRange(): void {
0123 this.eventDisplayService.setTimeRange(this.customStartTime, this.customEndTime);
0124 this.eventDisplayService.setAnimationSpeed(this.animationSpeed);
0125 this.dialogRef?.close();
0126 }
0127 }