mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-23 07:10:41 +00:00
Add number node
This commit is contained in:
@@ -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(),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
42
src/nodes/NumberNode.ts
Normal 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>`
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user