import React from "react"; import {Class, getOrCall, PartialRecord} from "ts-browser-helpers"; import {BPComponentProps, BPComponentState, UiConfigRendererContext} from "./bpComponents/BPComponent"; import {BPFolderComponent, FolderHeadCard} from "./bpComponents/BPFolderComponent"; import {BPTextInputComponent} from "./bpComponents/BPTextInputComponent"; import {BPNumberInputComponent} from "./bpComponents/BPNumberInputComponent"; import {BPButtonComponent} from "./bpComponents/BPButtonComponent"; import {BPToggleInputComponent} from "./bpComponents/BPToggleInputComponent"; import {BPSliderInputComponent} from "./bpComponents/BPSliderInputComponent"; import {BPDropdownInputComponent} from "./bpComponents/BPDropdownInputComponent"; import {PanelActions} from "@blueprintjs/core/lib/esm/components/panel-stack2/panelTypes"; import {BPPanelComponent} from "./bpComponents/BPPanelComponent"; import {UiObjectConfig} from 'uiconfig.js' import {BPColorInputComponent} from './bpComponents/BPColorInputComponent' import {BPVectorInputComponent} from './bpComponents/BPVectorInputComponent' import {IconName, MaybeElement} from "@blueprintjs/core"; // import {BPVectorInputComponent} from "./bpComponents/BPVectorInputComponent"; // import {BPFileComponent} from "./bpComponents/BPFileComponent"; // import {BPColorInputComponent} from "./bpComponents/BPColorInputComponent"; // import {BPHierarchyComponent} from "./bpComponents/BPHierarchyComponent"; export type UiConfigTypes = 'input' | 'button' | 'folder' | 'checkbox' | 'toggle' | 'dropdown' | 'slider' | 'color' | 'image' | 'number' | 'panel' | 'tree' | 'hierarchy' | 'materials' | 'textures' | 'vec' | 'vec2' | 'vec3' | 'vec4' | 'monitor' | 'vector' | 'select' | 'textarea' | 'tabs' export interface ConfigProps extends PanelActions { config: UiObjectConfig; isPanel?: boolean, level?: number, className?: string icon?: IconName|MaybeElement // only for top level folders right now. } export const ConfigObjectGenerators: PartialRecord, BPComponentState>>> = { input: BPTextInputComponent, number: BPNumberInputComponent, button: BPButtonComponent, // folder: BPPanelComponent, folder: BPFolderComponent, panel: BPPanelComponent, // folder: bpPopFolderGenerator, checkbox: BPToggleInputComponent, toggle: BPToggleInputComponent, dropdown: BPDropdownInputComponent, select: BPDropdownInputComponent, slider: BPSliderInputComponent, color: BPColorInputComponent, // image: BPFileComponent, vec: BPVectorInputComponent, vec2: BPVectorInputComponent, vec3: BPVectorInputComponent, vec4: BPVectorInputComponent, vector: BPVectorInputComponent, // hierarchy: BPHierarchyComponent, // todo textarea, textArea, multiline, tabs, tab, other aliases } export class ConfigObject extends React.Component { static contextType = UiConfigRendererContext declare context: React.ContextType state = {} render() { if (!this.props.config || !this.props.config.type) return (
) this.context.methods.initUiConfig(this.props.config) if(!this.props.config.dispatchMode) this.props.config.dispatchMode = 'immediate' const order = this.props.config.order ? getOrCall(this.props.config.order, this.props.config) ?? undefined : undefined const orderStyle = {order: order && typeof order === 'string' ? parseInt(order): order} let type = this.props.config.type as any as UiConfigTypes const val = this.context.methods.getRawValue(this.props.config) // hacks if (type === 'input' && typeof val === 'number') this.props.config.type = type = 'number' if (type === 'input' && typeof val === 'boolean') this.props.config.type = type = 'toggle' if (type === 'monitor') { this.props.config.type = type = 'input' this.props.config.readOnly = true } if (val && type === 'input' && typeof (val as any).x === 'number') this.props.config.type = type = 'vec' let BPComp = ConfigObjectGenerators[type] if (type === 'panel' && !this.props.isPanel) { const label = this.context.methods.getLabel(this.props.config) const children = this.context.methods.getChildren(this.props.config) const enabledToggle = children[0] && this.context.methods.getLabel(children[0]).toLowerCase() === 'enabled' ? children[0] : undefined enabledToggle && (enabledToggle.hidden = true) return (
enabledToggle && this.context.methods.setValue(enabledToggle, e.target.checked, {}).then(() => this.setState(this.state))} level={0} label={label} minimal={false} open={false} icon={this.props.icon} onClick={() => { this.props.openPanel<{ config: UiObjectConfig }>({ props: {config: this.props.config}, title: label, renderPanel: props => { if (BPComp) return () else return <> } }) }}/>
) } if (BPComp) { return (
) } return (
{/*Unknown type: {this.props.config.type}*/}
) // return null // let uiRef: React.FC | BPUiRef | null = this.props.uiConfig.uiRef // if (uiRef) { // if (typeof uiRef === 'function') { // const FC = uiRef // return (
  • ) // } // const FC = uiRef.FC // return (
  • {this.setState({...this.state, ...s})}}/>
  • ) // } // if (!this.props.uiConfig.type) return (
  • ) // if (!this.props.uiConfig.uuid) this.props.uiConfig.uuid = v4() // const g = ConfigObjectGenerators[this.props.uiConfig.type as any as UiConfigTypes] // // console.log(props.uiConfig) // if (!g) return
  • // this.props.uiConfig.uiRefresh = (mode, deep, delay) => { // console.log('refresh', mode, deep, delay) // todo handle mode, deep, delay // const _uiRef: React.FC | BPUiRef | null = g(this.props.uiConfig) // this.props.uiConfig.uiRef = _uiRef // if (typeof _uiRef !== 'function') { // this.setState(_uiRef.state) // } // } // uiRef = g(this.props.uiConfig) // this.props.uiConfig.uiRef = uiRef // if (typeof uiRef !== 'function') { // this.state = {...uiRef.state} // } // if (uiRef) { // if (typeof uiRef === 'function') // return (
  • {uiRef({})}
  • ) // return (
  • {uiRef.FC({ // defaultState: this.state, onChange: (s) => { // this.setState(s) // } // })}
  • ) // } // return (
  • Error rendering ConfigObject
  • ) } }