Add number node

This commit is contained in:
Misode
2020-05-26 02:08:36 +02:00
parent 387218193e
commit abbbc0bbfa
10 changed files with 57 additions and 12 deletions

View File

@@ -8,6 +8,7 @@ import { SourceView } from '../view/SourceView'
import { ListNode } from '../nodes/ListNode'
import { BooleanNode } from '../nodes/BooleanNode'
import { MapNode } from '../nodes/MapNode'
import { NumberNode } from '../nodes/NumberNode'
const EntityCollection = ['sheep', 'pig']
@@ -15,6 +16,7 @@ const predicateTree = new RootNode('predicate', {
condition: new EnumNode(['foo', 'bar'], {
transform: (s: string) => (s === 'foo') ? {test: 'baz'} : s
}),
number: new NumberNode({integer: false, min: 0}),
predicate: new ObjectNode({
type: new EnumNode(EntityCollection),
nbt: new StringNode(),

View File

@@ -21,6 +21,7 @@ export class DataModel {
}
invalidate() {
console.log(this.data)
this.listeners.forEach(listener => listener.invalidated(this))
}
@@ -35,7 +36,7 @@ export class DataModel {
console.log('Set', path.toString(), JSON.stringify(value))
if (value === undefined) {
if (value === undefined || (typeof value === 'number' && isNaN(value))) {
if (typeof path.last() === 'number') {
node.splice(path.last(), 1)
} else {

View File

@@ -4,7 +4,7 @@ import { TreeView } from "../view/TreeView"
export interface INode<T> {
setParent: (parent: INode<any>) => void
default: () => T | null
default: () => T
transform: (value: T) => any
render: (path: Path, value: T, view: TreeView, options?: RenderOptions) => string
renderRaw: (path: Path, value: T, view: TreeView, options?: RenderOptions) => string
@@ -30,11 +30,11 @@ export interface NodeMods<T> {
export abstract class AbstractNode<T> implements INode<T> {
parent?: INode<any>
defaultMod: () => T | null
defaultMod: () => T
transformMod: (v: T) => T
constructor(mods?: NodeMods<T>, def?: () => T | null) {
this.defaultMod = mods?.default ? mods.default : def ? def : () => null
constructor(def: () => T, mods?: NodeMods<T>) {
this.defaultMod = mods?.default ? mods.default : def
this.transformMod = mods?.transform ? mods.transform : (v: T) => v
}
@@ -51,7 +51,7 @@ export abstract class AbstractNode<T> implements INode<T> {
updateModel(el: Element, path: Path, model: DataModel) {}
default(): T | null {
default(): T {
return this.defaultMod()
}

View File

@@ -10,7 +10,7 @@ export class BooleanNode extends AbstractNode<boolean> {
force: boolean
constructor(mods?: BooleanNodeMods) {
super(mods, () => false)
super(() => false, mods)
this.force = (mods?.force === true)
}

View File

@@ -7,7 +7,7 @@ export class EnumNode extends AbstractNode<string> implements StateNode<string>
protected options: string[]
constructor(options: string[], mods?: NodeMods<string>) {
super(mods, () => '')
super(() => '', mods)
this.options = options
}

View File

@@ -8,7 +8,7 @@ export class ListNode extends AbstractNode<IObject[]> {
protected children: INode<any>
constructor(values: INode<any>, mods?: NodeMods<IObject[]>) {
super(mods, () => [])
super(() => [], mods)
this.children = values
}

View File

@@ -13,7 +13,7 @@ export class MapNode extends AbstractNode<IMap> {
protected values: INode<any>
constructor(keys: StateNode<string>, values: INode<any>, mods?: NodeMods<IMap>) {
super(mods, () => ({}))
super(() => ({}), mods)
this.keys = keys
this.values = values
}

42
src/nodes/NumberNode.ts Normal file
View File

@@ -0,0 +1,42 @@
import { AbstractNode, NodeMods, RenderOptions, StateNode } from './AbstractNode'
import { Path } from '../model/Path'
import { DataModel } from '../model/DataModel'
import { TreeView } from '../view/TreeView'
export interface NumberNodeMods extends NodeMods<number> {
integer?: boolean
min?: number
max?: number
}
export class NumberNode extends AbstractNode<number> implements StateNode<number> {
integer: boolean
min: number
max: number
constructor(mods?: NumberNodeMods) {
super(() => 0, mods)
console.log(mods)
this.integer = mods?.integer ? mods.integer : false
this.min = mods?.min !== undefined ? mods.min : -Infinity
this.max = mods?.max !== undefined ? mods.max : Infinity
}
getState(el: Element) {
const value = el.querySelector('input')!.value
const parsed = this.integer ? parseInt(value) : parseFloat(value)
console.log(this.min)
if (parsed < this.min) return this.min
if (parsed > this.max) return this.max
return parsed
}
updateModel(el: Element, path: Path, model: DataModel) {
model.set(path, this.getState(el))
}
renderRaw(path: Path, value: number, view: TreeView, options?: RenderOptions) {
return `${options?.hideLabel ? `` : `<label>${path.last()}</label>`}
<input value="${value === undefined ? '' : value}"></input>`
}
}

View File

@@ -10,7 +10,7 @@ export class ObjectNode extends AbstractNode<IObject> {
protected fields: NodeChildren
constructor(fields: NodeChildren, mods?: NodeMods<IObject>) {
super(mods, () => ({}))
super(() => ({}), mods)
this.fields = fields
Object.values(fields).forEach(child => {
child.setParent(this)

View File

@@ -5,7 +5,7 @@ import { TreeView } from '../view/TreeView'
export class StringNode extends AbstractNode<string> implements StateNode<string> {
constructor(mods?: NodeMods<string>) {
super(mods, () => '')
super(() => '', mods)
}
getState(el: Element) {