UNPKG

scriptable-testlab

Version:

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

246 lines (211 loc) 5.92 kB
import {AbsWidgetImage} from 'scriptable-abstract'; import {MockData} from '../../data'; import {MockImage} from '../../media/image'; import {MockColor} from '../color'; import {MockSize} from '../size'; /** * Represents the content mode options for an image. */ type ContentMode = 'fitting' | 'filling'; /** * Represents the alignment options for an image. */ type ImageAlignment = 'left' | 'center' | 'right'; /** * Represents the state of a widget image element. */ interface WidgetImageMockState { readonly image: Image; readonly resizable: boolean; readonly imageSize: Size; readonly imageOpacity: number; readonly cornerRadius: number; readonly borderWidth: number; readonly borderColor: Color; readonly containerRelativeShape: boolean; readonly tintColor: Color; readonly url: string; readonly contentMode: ContentMode; readonly alignment: ImageAlignment; } /** * Default state for a new widget image element. */ const DEFAULT_STATE: WidgetImageMockState = { image: MockImage.fromData(MockData.fromString('')), resizable: true, imageSize: new MockSize(100, 100), imageOpacity: 1.0, cornerRadius: 0, borderWidth: 0, borderColor: new MockColor('#000000'), containerRelativeShape: false, tintColor: new MockColor('#000000'), url: '', contentMode: 'fitting', alignment: 'center', }; /** * Mock implementation of Scriptable's WidgetImage. * Represents an image that can be displayed in a widget. * * @example * ```typescript * const image = MockImage.fromFile('example.jpg'); * const widgetImage = new MockWidgetImage(image); * widgetImage.imageSize = new MockSize(200, 100); * widgetImage.cornerRadius = 10; * widgetImage.centerAlignImage(); * ``` */ export class MockWidgetImage extends AbsWidgetImage<WidgetImageMockState> { /** * Creates a new widget image element with the specified image. */ constructor(image?: Image) { super({ ...DEFAULT_STATE, ...(image ? {image} : {}), }); } /** * Creates a new widget image instance. * @param image - The image to display in the widget. * @returns A new widget image instance. */ static create(image?: Image): WidgetImage { return new MockWidgetImage(image); } // Property accessors get image(): Image { return this.state.image; } set image(value: Image) { this.setState({image: value}); } get resizable(): boolean { return this.state.resizable; } set resizable(value: boolean) { this.setState({resizable: value}); } get imageSize(): Size { return this.state.imageSize; } set imageSize(value: Size) { this.setState({imageSize: value}); } /** * Gets or sets the opacity of the image. * Value should be between 0 (fully transparent) and 1 (fully opaque). */ get imageOpacity(): number { return this.state.imageOpacity; } set imageOpacity(value: number) { const numValue = Number(value); const clampedValue = isNaN(numValue) ? 0 : Math.max(0, Math.min(1, numValue)); this.setState({imageOpacity: clampedValue}); } /** * Gets or sets the corner radius of the image. * Negative values will be converted to 0. */ get cornerRadius(): number { return this.state.cornerRadius; } set cornerRadius(value: number) { const numValue = Number(value); const validValue = isNaN(numValue) || numValue < 0 ? 0 : numValue; this.setState({cornerRadius: validValue}); } /** * Gets or sets the border width of the image. * Negative values will be converted to 0. */ get borderWidth(): number { return this.state.borderWidth; } set borderWidth(value: number) { const numValue = isNaN(Number(value)) ? 0 : Number(value); this.setState({borderWidth: Math.max(0, numValue)}); } get borderColor(): Color { return this.state.borderColor; } set borderColor(value: Color) { this.setState({borderColor: value}); } get containerRelativeShape(): boolean { return this.state.containerRelativeShape; } set containerRelativeShape(value: boolean) { this.setState({containerRelativeShape: value}); } get tintColor(): Color { return this.state.tintColor; } set tintColor(value: Color) { this.setState({tintColor: value}); } get url(): string { return this.state.url; } set url(value: string) { this.setState({url: value}); } /** * Aligns the image to the left of its container. * @returns this for method chaining */ leftAlignImage(): this { this.setState({alignment: 'left'}); return this; } /** * Centers the image in its container. * @returns this for method chaining */ centerAlignImage(): this { this.setState({alignment: 'center'}); return this; } /** * Aligns the image to the right of its container. * @returns this for method chaining */ rightAlignImage(): this { this.setState({alignment: 'right'}); return this; } /** * Sets the content mode to fitting, which scales the image to fit within its container while maintaining aspect ratio. * @returns this for method chaining */ applyFittingContentMode(): this { this.setState({contentMode: 'fitting'}); return this; } /** * Sets the content mode to filling, which scales the image to fill its container while maintaining aspect ratio. * @returns this for method chaining */ applyFillingContentMode(): this { this.setState({contentMode: 'filling'}); return this; } /** * Gets the current alignment of the image. * @returns The current alignment ('left', 'center', or 'right'). */ getAlignment(): ImageAlignment { return this.state.alignment; } /** * Gets the current content mode of the image. * @returns The current content mode ('fitting' or 'filling'). */ getContentMode(): ContentMode { return this.state.contentMode; } }