new component system: blur.nim example now works
This commit is contained in:
parent
d538b7bc93
commit
a93e739081
3 changed files with 49 additions and 44 deletions
|
|
@ -283,7 +283,6 @@ proc diff(newNode, oldNode: VNode; parent, current: Node; kxi: KaraxInstance): E
|
|||
if newNode.events.len != 0 or oldNode.events.len != 0:
|
||||
mergeEvents(newNode, oldNode, kxi)
|
||||
if oldNode.kind == VNodeKind.input or oldNode.kind == VNodeKind.textarea:
|
||||
echo "comparing ", oldNode.text != newNode.text
|
||||
if oldNode.text != newNode.text:
|
||||
oldNode.text = newNode.text
|
||||
oldNode.dom.value = newNode.text
|
||||
|
|
@ -364,8 +363,8 @@ proc diff(newNode, oldNode: VNode; parent, current: Node; kxi: KaraxInstance): E
|
|||
x.updatedImpl(x, VComponent newNode)
|
||||
let oldExpanded = x.expanded
|
||||
x.expanded = x.renderImpl(x)
|
||||
x.version = VComponent(newNode).version
|
||||
#x.updatedImpl(x)
|
||||
x.renderedVersion = x.version
|
||||
#echo "expanding ", x.debugId
|
||||
if oldExpanded == nil:
|
||||
detach(oldNode)
|
||||
kxi.addPatch(pkReplace, parent, current, x.expanded)
|
||||
|
|
|
|||
13
src/vdom.nim
13
src/vdom.nim
|
|
@ -131,8 +131,11 @@ type
|
|||
version*: int ## Update this to trigger a redraw by karax. Usually you
|
||||
## should call 'markDirty' instead which is an alias for
|
||||
## 'inc version'.
|
||||
renderedVersion*: int ## Do not touch. Used by karax. The last version of the
|
||||
## component we rendered.
|
||||
expanded*: VNode ## Do not touch. Used by karax. The VDOM the component
|
||||
## expanded to.
|
||||
debugId*: int
|
||||
|
||||
proc value*(n: VNode): cstring = n.text
|
||||
proc `value=`*(n: VNode; v: cstring) = n.text = v
|
||||
|
|
@ -154,11 +157,16 @@ proc dthunk*(name: cstring; args: varargs[VNode, vn]): VNode =
|
|||
|
||||
proc defaultChangedImpl*(v, newInstance: VComponent): bool =
|
||||
## The default implementation of 'changed'.
|
||||
result = v.version != newInstance.version
|
||||
result = v.version != v.renderedVersion
|
||||
|
||||
proc defaultUpdatedImpl*(v, newInstance: VComponent) =
|
||||
discard
|
||||
|
||||
var gid = 0
|
||||
proc getDebugId(): int =
|
||||
inc(gid)
|
||||
gid
|
||||
|
||||
template newComponent*[T](t: typeDesc[T];
|
||||
render: (proc(self: VComponent): VNode) not nil,
|
||||
onAttach: proc(self: VComponent) = nil,
|
||||
|
|
@ -169,7 +177,8 @@ template newComponent*[T](t: typeDesc[T];
|
|||
T(kind: VNodeKind.component, key: -1,
|
||||
text: cstring(astToStr(t)), renderImpl: render,
|
||||
changedImpl: changed, updatedImpl: updated,
|
||||
onAttachImpl: onAttach, onDetachImpl: onDetach)
|
||||
onAttachImpl: onAttach, onDetachImpl: onDetach,
|
||||
debugId: getDebugId())
|
||||
|
||||
template markDirty*(c: VComponent) =
|
||||
## mark the component as dirty so that it is re-rendered.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import vdom, kdom, vstyles, karax, karaxdsl, jdict, jstrutils
|
||||
|
||||
type TextInput* = ref object of VComponent
|
||||
value: cstring
|
||||
value, guid: cstring
|
||||
isActive: bool
|
||||
onchange: proc (value: cstring)
|
||||
|
||||
|
|
@ -35,63 +35,60 @@ proc render(x: VComponent): VNode =
|
|||
|
||||
proc flip(ev: Event; n: VNode) =
|
||||
self.isActive = not self.isActive
|
||||
kout cstring"onflip", n.value
|
||||
echo "flip! ", self.isActive, " id: ", self.debugId, " version ", self.version
|
||||
markDirty(self)
|
||||
|
||||
proc onchanged(ev: Event; n: VNode) =
|
||||
if self.onchange != nil and self.value != n.value:
|
||||
if self.onchange != nil:
|
||||
self.onchange n.value
|
||||
#self.value = n.value
|
||||
self.value = n.value
|
||||
|
||||
result = buildHtml(tdiv(style=style)):
|
||||
input(style=inputStyle, value=self.value, onblur=flip, onfocus=flip, onkeyup=onchanged)
|
||||
|
||||
#proc setValue(x: TextInput; value: cstring) =
|
||||
# x.value = value
|
||||
# markDirty(x)
|
||||
proc changed(current, next: VComponent): bool =
|
||||
let current = TextInput(current)
|
||||
let next = TextInput(next)
|
||||
if current.guid != next.guid:
|
||||
result = true
|
||||
else:
|
||||
result = defaultChangedImpl(current, next)
|
||||
|
||||
proc update(current, next: VComponent) =
|
||||
let current = TextInput(current)
|
||||
let next = TextInput(next)
|
||||
if not current.isActive:
|
||||
current.value = next.value
|
||||
echo "updated! ", current.value
|
||||
else:
|
||||
echo "not updated! ", current.value
|
||||
#markDirty(current)
|
||||
current.value = next.value
|
||||
current.guid = next.guid
|
||||
next.isActive = current.isActive
|
||||
|
||||
proc changed(current, next: VComponent): bool =
|
||||
let current = TextInput(current)
|
||||
let next = TextInput(next)
|
||||
result = next.value != current.value or true
|
||||
|
||||
proc newTextInput*(style: VStyle = VStyle(); value: cstring = cstring"",
|
||||
proc newTextInput*(style: VStyle = VStyle(); guid: cstring; value: cstring = cstring"",
|
||||
onchange: proc(v: cstring) = nil): TextInput =
|
||||
result = newComponent(TextInput, render, changed=changed, updated=update)
|
||||
result.style = style
|
||||
result.value = value
|
||||
result.onchange = onchange
|
||||
|
||||
type
|
||||
Combined = ref object of VComponent
|
||||
a, b: TextInput
|
||||
|
||||
proc renderComb(self: VComponent): VNode =
|
||||
let self = Combined(self)
|
||||
|
||||
proc bu(ev: Event; n: VNode) =
|
||||
self.a.value = ""
|
||||
self.b.value = ""
|
||||
markDirty(self.a)
|
||||
markDirty(self.b)
|
||||
|
||||
result = buildHtml(tdiv(style=self.style)):
|
||||
self.a
|
||||
self.b
|
||||
button(onclick=bu):
|
||||
text "reset"
|
||||
result.guid = guid
|
||||
|
||||
when false:
|
||||
type
|
||||
Combined = ref object of VComponent
|
||||
a, b: TextInput
|
||||
|
||||
proc renderComb(self: VComponent): VNode =
|
||||
let self = Combined(self)
|
||||
|
||||
proc bu(ev: Event; n: VNode) =
|
||||
self.a.value = ""
|
||||
self.b.value = ""
|
||||
markDirty(self.a)
|
||||
markDirty(self.b)
|
||||
|
||||
result = buildHtml(tdiv(style=self.style)):
|
||||
self.a
|
||||
self.b
|
||||
button(onclick=bu):
|
||||
text "reset"
|
||||
|
||||
proc changed(self: VComponent): bool =
|
||||
let self = Combined(self)
|
||||
result = self.a.changedImpl(self.a) or self.b.changedImpl(self.b)
|
||||
|
|
@ -121,7 +118,7 @@ proc createDom(): VNode =
|
|||
for index, text in persons.pairs:
|
||||
renderPerson(text, index)
|
||||
tdiv:
|
||||
newTextInput(VStyle(), if selected >= 0: persons[selected] else: "", proc (v: cstring) =
|
||||
newTextInput(VStyle(), &selected, if selected >= 0: persons[selected] else: "", proc (v: cstring) =
|
||||
if v.len > 0:
|
||||
if selected >= 0: persons[selected] = v
|
||||
errmsg = ""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue