import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; import { NgxMoveableComponent, OnDragEnd, OnResize, OnResizeEnd } from 'ngx-moveable'; import { OnDrag } from 'ngx-moveable'; import { ConfigService } from '../services/config.service'; import { Rect } from '../models/generated/Rect'; import { Color } from '../color-picker/color-picker.component'; import { ShortcutService } from '../services/shortcut.service'; import { CarouselComponent } from '../carousel/carousel.component'; import { PlanService } from '../services/plan.service'; import { Plan, PlanElement } from '../models/plan'; import { WorldAreaService } from '../services/world-area.service'; import { WorldArea } from '../models/world-area'; import { NotesComponent } from '../editor/notes/notes.component'; import { ResizedEvent } from 'angular-resize-event'; import { from } from 'rxjs'; import { open } from '@tauri-apps/api/dialog'; import { OverlayRef } from '@angular/cdk/overlay'; import { OverlayService } from '../services/overlay.service'; import { appWindow } from '@tauri-apps/api/window'; @Component({ selector: 'plan-display', templateUrl: './plan-display.component.html', styleUrls: ['./plan-display.component.scss'] }) export class PlanDisplayComponent implements AfterViewInit, OnInit { @Input() backgroundColor?: String; draggable: boolean = true; rect?: Rect; bounds: any = { "left": 0, "top": 0, "right": 0, "bottom": 0, "position": "css" }; // slides: PlanElement[] = []; slideIndex: number = 0; zoneSlides?: CarouselComponent; currentSlides?: CarouselComponent; worldAreaMap?: Map; settingsOpen: boolean = false; init: boolean = false; constructor(private configService: ConfigService, private cdr: ChangeDetectorRef, private shortcut: ShortcutService, public planService: PlanService, public worldAreaService: WorldAreaService, public overlayService: OverlayService) { // for (let i = 0; i < 100; i++) { // this.slides.push(i); // } window.addEventListener("resize", this.windowInitHandler.bind(this)); overlayService.setInteractable(); appWindow.listen("entered", (entered) => { console.log("entered", entered); if (this.planService.currentPlan) { const current = this.planService.currentPlan.current; const length = this.planService.currentPlan.plan.length; if (current + 1 < length) { if (entered.payload === this.planService.currentPlan.plan[current + 1]) { this.next(); } } } }); } windowInitHandler() { if (window.innerWidth > 0) { this.ngAfterViewInit(); window.removeEventListener("resize", this.windowInitHandler.bind(this)); } } ngOnInit() { this.worldAreaService.getWorldAreas().subscribe(a => this.worldAreaMap = a); } abs(v: number) { return Math.abs(v); } transform() { console.log("transform:", `translate(${this.rect!.x}px, ${this.rect!.y}px)`, "rect", this.rect); return `translate(${this.rect!.x}px, ${this.rect!.y}px)`; } width() { return `${this.rect!.width}px`; } height() { return `${this.rect!.height}px`; } ngAfterViewInit(): void { if (window.innerWidth > 0) { const cfgRect = this.configService.config.initialPlanWindowPosition; console.log("cfgrect", cfgRect); console.log("window res", window.innerWidth); console.log("window res", window.innerHeight); this.rect = { x: cfgRect.x * window.innerWidth, y: cfgRect.y * window.innerHeight, width: cfgRect.width * window.innerWidth, height: cfgRect.height * window.innerHeight, } console.log("rect", this.rect); setTimeout(() => this.cdr.detectChanges(), 0); this.init = true; } } onDrag(e: OnDrag) { this.rect!.x = e.translate[0]; this.rect!.y = e.translate[1]; } onDragEnd(e: OnDragEnd) { this.saveRect(); } onResize(e: OnResize) { this.rect!.width = e.width; this.rect!.height = e.height; this.onDrag(e.drag); } onResizeEnd(e: OnResizeEnd) { this.saveRect(); } saveRect() { const toCfgRect = this.rect!; this.configService.config.initialPlanWindowPosition = { x: toCfgRect.x / window.innerWidth, y: toCfgRect.y / window.innerHeight, width: toCfgRect.width / window.innerWidth, height: toCfgRect.height / window.innerHeight, } } registerZoneSlides(carousel: CarouselComponent) { this.zoneSlides = carousel; console.log("zone slides"); } registerCurrentSlides(carousel: CarouselComponent) { this.currentSlides = carousel; if (this.currentSlides) { this.shortcut.register(this.configService.config.prev, this.prev.bind(this)); this.shortcut.register(this.configService.config.next, this.next.bind(this)); } } next() { this.currentSlides?.next(); this.zoneSlides?.next(); } prev() { this.currentSlides?.prev(); this.zoneSlides?.prev(); } onResizeNote(noteSlide: NotesComponent) { if (!noteSlide.ref) { return; } let bounds = noteSlide.ref.nativeElement.getBoundingClientRect(); const children = noteSlide.ref.nativeElement.children; let sumWidth = 0; let sumHeight = 0; for (let child of children) { const c = child.getBoundingClientRect(); sumWidth += c.width; sumHeight += c.height; } const scale = Math.min( sumWidth / bounds.width, sumHeight / bounds.height, ) noteSlide.ref.nativeElement.style.transform = `scale(1, ${scale})`; } openDialog() { from(open({ multiple: false, filters: [ { name: "JSON (.json)", extensions: ['json'] } ] })).subscribe(file => { if (file) { this.planService.loadPlan(file as string).subscribe(plan => { if (plan) { this.settingsOpen = false; } }); } }); } }