import { EffectScope , effectScope , markRaw , ref , Ref , shallowRef } from 'vue' ; import { Vector2 } from '../vectors' ; import type { ScopeElement } from './elements/scope-element' ; import { v4 as uuidv4 , validate as uuidValidate } from 'uuid' ; export type JsonType = null | boolean | number | string | JsonType [ ] | { [ prop ] : JsonType ; } ; export type QuantumElementType < T extends QuantumElement = QuantumElement , TCtor extends QuantumElementConstructor < T > = QuantumElementConstructor < T > , U extends string = string > = { readonly typeName : U ; elementType : TCtor ; serializeElement ( element ) : JsonType ; deserializeElement ( data ) : { element : T ; onAddedCallback : ( ) => void ; } ; } ; export interface QuantumElementConstructor < T > { new ( options ) : T ; } /**
 * Please be careful to not put elements into anything reactive
 */ export abstract class QuantumElement { readonly id : string = uuidv4 ( ) ; abstract typeName : string ; readonly position : Ref < Vector2 > = ref ( Vector2 . zero ) ; /** The size can include a fractional part */ readonly size : Ref < Vector2 > = ref ( new Vector2 ( 5 , 2 ) ) ; readonly resizable : Ref < boolean > = ref ( false ) ; readonly selected : Ref < boolean > = ref ( false ) ; readonly focused : Ref < boolean > = ref ( false ) ; readonly scope : Ref < ScopeElement | undefined > = shallowRef < ScopeElement > ( ) ; constructor ( options ) { markRaw ( this ) ; if ( options . position ) this . position . value = options . position ; if ( options . resizable ) this . resizable . value = options . resizable ; if ( options . size ) this . size . value = options . size ; if ( options . scope ) this . scope . value = options . scope ; if ( options . id && uuidValidate ( options . id ) ) this . id = options . id ; } setPosition ( value ) { this . position . value = value ; } setSize ( value ) { this . size . value = value ; } setSelected ( value ) { this . selected . value = value ; } setFocused ( value ) { this . focused . value = value ; } setScope ( value ) { this . scope . value = value ; } } /**
 * Parameters to pass when creating an element
 */ export interface QuantumElementCreationOptions { position ? : Vector2 ; resizable ? : boolean ; size ? : Vector2 ; scope ? : ScopeElement | undefined ; id ? : string ; }