You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Nothing/src/app/plan-display/plan-display.component.ts

238 lines
6.8 KiB

import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, Input, NgZone, 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, StateEvent } from '../services/overlay.service';
import { appWindow } from '@tauri-apps/api/window';
import { EventsService } from '../services/events.service';
@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" };
@ViewChild("moveable") moveable?: NgxMoveableComponent;
// slides: PlanElement[] = [];
slideIndex: number = 0;
zoneSlides?: CarouselComponent<PlanElement>;
currentSlides?: CarouselComponent<PlanElement>;
worldAreaMap?: Map<String, WorldArea>;
settingsOpen: boolean = false;
init: boolean = false;
hasAttachedOnce: boolean = false;
constructor(private events: EventsService, public configService: ConfigService, private cdr: ChangeDetectorRef, private shortcut: ShortcutService, public planService: PlanService, public worldAreaService: WorldAreaService, public overlayService: OverlayService, private zone: NgZone) {
window.addEventListener("resize", () => {
this.zone.run(() => {
this.windowInitHandler()
})
});
// const test = this.events.listen<StateEvent>("OverlayStateChange").subscribe(event => {
// if (!this.hasAttachedOnce) {
// this.hasAttachedOnce = true;
// test.unsubscribe();
// if (!event.payload.Hidden)
// overlayService.setInteractable();
// }
// });
appWindow.listen("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].area_key) {
this.zone.run(() => this.next());
}
}
}
});
}
windowInitHandler() {
if (window.innerWidth > 0) {
this.ngAfterViewInit();
}
}
ngOnInit() {
this.worldAreaService.getWorldAreas().subscribe(a => this.worldAreaMap = a);
}
abs(v: number) {
return Math.abs(v);
}
transform() {
return `translate(${this.rect!.x}px, ${this.rect!.y}px)`;
}
width() {
return `${this.rect!.width}px`;
}
height() {
return `${this.rect!.height}px`;
}
hasWaypoint(key?: string): boolean {
if(!key) {
key = this.planService.currentPlan!.plan[this.planService.currentPlan!.current].area_key;
}
const world_area = this.worldAreaMap?.get(key);
return world_area!.has_waypoint;
}
ngAfterViewInit(): void {
if (window.innerWidth > 0) {
console.log("recalculating");
const cfgRect = this.configService.config.initialPlanWindowPosition;
this.rect = {
x: cfgRect.x * window.innerWidth,
y: cfgRect.y * window.innerHeight,
width: cfgRect.width * window.innerWidth,
height: cfgRect.height * window.innerHeight,
}
this.moveable?.updateRect();
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<PlanElement>) {
this.zoneSlides = carousel;
}
registerCurrentSlides(carousel: CarouselComponent<PlanElement>) {
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() {
if (this.planService.currentPlan!.current + 1 < this.planService.currentPlan!.plan.length) {
this.planService.currentPlan!.current++;
}
this.currentSlides?.next();
this.zoneSlides?.next();
}
prev() {
if (this.planService.currentPlan!.current - 1 >= 0) {
this.planService.currentPlan!.current--;
}
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})`;
}
settingsClick(event: any) {
this.settingsOpen = !this.settingsOpen;
event.stopPropagation();
}
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;
}
});
}
});
}
loadBasePlan() {
this.planService.loadBasePlan().subscribe(plan => {
this.planService.currentPlan = plan;
})
}
}