/** * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose * @author David Sehnal */ import { Color as ColorData } from './color'; import { shallowClone } from 'mol-util'; export namespace ParamDefinition { export interface Base { label: string description: string defaultValue: T } export interface GenericValue extends Base { type: 'generic-value' } export function GenericValue(label: string, description: string, defaultValue: T): GenericValue { return { type: 'generic-value', label, description, defaultValue } } export interface Select extends Base { type: 'select' /** array of (value, label) tuples */ options: [T, string][] } export function Select(label: string, description: string, defaultValue: T, options: [T, string][]): Select { return { type: 'select', label, description, defaultValue, options } } export interface MultiSelect extends Base { type: 'multi-select' /** array of (value, label) tuples */ options: [E, string][] } export function MultiSelect(label: string, description: string, defaultValue: T, options: [E, string][]): MultiSelect { return { type: 'multi-select', label, description, defaultValue, options } } export interface Boolean extends Base { type: 'boolean' } export function Boolean(label: string, description: string, defaultValue: boolean): Boolean { return { type: 'boolean', label, description, defaultValue } } export interface Range extends Base { type: 'range' min: number max: number /** if an `integer` parse value with parseInt, otherwise use parseFloat */ step: number } export function Range(label: string, description: string, defaultValue: number, min: number, max: number, step: number): Range { return { type: 'range', label, description, defaultValue, min, max, step } } export interface Text extends Base { type: 'text' } export function Text(label: string, description: string, defaultValue: string = ''): Text { return { type: 'text', label, description, defaultValue } } export interface Color extends Base { type: 'color' } export function Color(label: string, description: string, defaultValue: ColorData): Color { return { type: 'color', label, description, defaultValue } } export interface Numeric extends Base { type: 'number' min: number max: number /** if an `integer` parse value with parseInt, otherwise use parseFloat */ step: number } export function Numeric(label: string, description: string, defaultValue: number, min: number, max: number, step: number): Numeric { return { type: 'number', label, description, defaultValue, min, max, step } } export interface Interval extends Base<[number, number]> { type: 'interval' } export function Interval(label: string, description: string, defaultValue: [number, number]): Interval { return { type: 'interval', label, description, defaultValue } } export interface Group extends Base { type: 'group', params: T } export function Group(label: string, description: string, params: T): Group { return { type: 'group', label, description, defaultValue: getDefaultValues(params), params }; } export interface Mapped extends Base<{ name: string, params: T }> { type: 'mapped', select: Select, map(name: string): Params } export function Mapped(label: string, description: string, defaultKey: string, names: [string, string][], map: Mapped['map']): Mapped { return { type: 'mapped', label, description, defaultValue: { name: defaultKey, params: getDefaultValues(map(defaultKey)) as any }, select: Select(label, description, defaultKey, names), map }; } export type Any = Select | MultiSelect | Boolean | Range | Text | Color | Numeric | Interval | Group | Mapped export type Params = { [k: string]: Any } export type Values = { [k in keyof T]: T[k]['defaultValue'] } export function getDefaultValues(params: T) { const d: { [k: string]: any } = {} Object.keys(params).forEach(k => d[k] = params[k].defaultValue) return d as Values } export function clone

(params: P): P { return shallowClone(params) } /** * List of [error text, pathToValue] * i.e. ['Missing Nested Id', ['group1', 'id']] */ export type ParamErrors = [string, string | string[]][] export interface Provider { /** Check the parameters and return a list of errors if the are not valid. */ default?(a: A, globalCtx: Ctx): P, /** Specify default control descriptors for the parameters */ definition?(a: A, globalCtx: Ctx): { [K in keyof P]?: Any }, /** Check the parameters and return a list of errors if the are not valid. */ validate?(params: P, a: A, globalCtx: unknown): ParamErrors | undefined, /** Optional custom parameter equality. Use shallow structural equal by default. */ areEqual?(oldParams: P, newParams: P): boolean } }