UNPKG

scriptable-testlab

Version:

A lightweight, efficient tool designed to manage and update scripts for Scriptable.

237 lines (205 loc) 5.61 kB
import {AbsRect} from 'scriptable-abstract'; import {MockPoint} from './point'; import {MockSize} from './size'; interface RectState { x: number; y: number; width: number; height: number; minX: number; minY: number; maxX: number; maxY: number; midX: number; midY: number; origin: Point; size: Size; } const _DEFAULT_STATE: RectState = { x: 0, y: 0, width: 0, height: 0, minX: 0, minY: 0, maxX: 0, maxY: 0, midX: 0, midY: 0, origin: new MockPoint(0, 0) as unknown as Point, size: new MockSize(0, 0) as unknown as Size, }; export class MockRect extends AbsRect<RectState> { constructor(x: number = 0, y: number = 0, width: number = 0, height: number = 0) { if (Number.isNaN(x)) throw new Error('x coordinate must be a valid number'); if (!Number.isFinite(x)) throw new Error('x coordinate must be finite'); if (Number.isNaN(y)) throw new Error('y coordinate must be a valid number'); if (!Number.isFinite(y)) throw new Error('y coordinate must be finite'); if (Number.isNaN(width)) throw new Error('width must be a valid number'); if (!Number.isFinite(width)) throw new Error('width must be finite'); if (width < 0) throw new Error('width must be non-negative'); if (Number.isNaN(height)) throw new Error('height must be a valid number'); if (!Number.isFinite(height)) throw new Error('height must be finite'); if (height < 0) throw new Error('height must be non-negative'); super({ x, y, width, height, minX: x, minY: y, maxX: x + width, maxY: y + height, midX: x + width / 2, midY: y + height / 2, origin: new MockPoint(x, y) as unknown as Point, size: new MockSize(width, height) as unknown as Size, }); } private validateCoordinate(value: number, name: string) { if (Number.isNaN(value)) { throw new Error(`${name} coordinate must be a valid number`); } if (!Number.isFinite(value)) { throw new Error(`${name} coordinate must be finite`); } } private validateDimension(value: number, name: string) { if (Number.isNaN(value)) { throw new Error(`${name} must be a valid number`); } if (!Number.isFinite(value)) { throw new Error(`${name} must be finite`); } if (value < 0) { throw new Error(`${name} must be non-negative`); } } get x(): number { return this.state.x; } set x(value: number) { this.validateCoordinate(value, 'x'); const origin = new MockPoint(value, this.y) as unknown as Point; this.setState({ x: value, minX: value, maxX: value + this.width, midX: value + this.width / 2, origin, }); } get y(): number { return this.state.y; } set y(value: number) { this.validateCoordinate(value, 'y'); const origin = new MockPoint(this.x, value) as unknown as Point; this.setState({ y: value, minY: value, maxY: value + this.height, midY: value + this.height / 2, origin, }); } get width(): number { return this.state.width; } set width(value: number) { this.validateDimension(value, 'width'); const size = new MockSize(value, this.height) as unknown as Size; this.setState({ width: value, maxX: this.x + value, midX: this.x + value / 2, size, }); } get height(): number { return this.state.height; } set height(value: number) { this.validateDimension(value, 'height'); const size = new MockSize(this.width, value) as unknown as Size; this.setState({ height: value, maxY: this.y + value, midY: this.y + value / 2, size, }); } get origin(): Point { return this.state.origin; } set origin(value: Point) { this.setState({ x: value.x, y: value.y, minX: value.x, minY: value.y, maxX: value.x + this.width, maxY: value.y + this.height, midX: value.x + this.width / 2, midY: value.y + this.height / 2, origin: value, }); } get size(): Size { return this.state.size; } set size(value: Size) { this.setState({ width: value.width, height: value.height, maxX: this.x + value.width, maxY: this.y + value.height, midX: this.x + value.width / 2, midY: this.y + value.height / 2, size: value, }); } get minX(): number { return this.state.minX; } get minY(): number { return this.state.minY; } get maxX(): number { return this.state.maxX; } get maxY(): number { return this.state.maxY; } get midX(): number { return this.state.midX; } get midY(): number { return this.state.midY; } public setState(state: Partial<RectState>): this { const newState = { ...this.state, ...state, }; // Update derived properties if ('x' in state || 'width' in state) { newState.minX = newState.x; newState.maxX = newState.x + newState.width; newState.midX = newState.x + newState.width / 2; } if ('y' in state || 'height' in state) { newState.minY = newState.y; newState.maxY = newState.y + newState.height; newState.midY = newState.y + newState.height / 2; } if ('x' in state || 'y' in state) { newState.origin = new MockPoint(newState.x, newState.y) as unknown as Point; } if ('width' in state || 'height' in state) { newState.size = new MockSize(newState.width, newState.height) as unknown as Size; } super.setState(newState); return this; } }