This commit is contained in:
Araq 2017-06-18 18:01:48 +02:00
commit d1e0e1367b
4 changed files with 66 additions and 46 deletions

View file

@ -1,57 +1,72 @@
import vdom, vstyles, components, karax, karaxdsl, jdict, jstrutils, kdom import vdom, vstyles, karax, karaxdsl, jdict, jstrutils, kdom
type
Car = ref object of VComponent
counter: int
cntdown: int
timer: TimeOut
list: seq[cstring]
change: bool
onclick: proc (ev: Event; n: VNode)
const ticksUntilChange = 5
proc car*(images: seq[cstring]): Car =
new(result)
result.list = images
result.cntdown = ticksUntilChange
proc docount() =
dec result.cntdown
if result.cntdown == 0:
result.counter = (result.counter + 1) mod result.list.len
result.cntdown = ticksUntilChange
else:
result.timer = setTimeout(docount, 30)
result.change = true
redraw()
result.onclick = proc (ev: Event; n: VNode) =
result.change = false
if result.timer != nil:
clearTimeout(result.timer)
result.timer = setTimeout(docount, 30)
method changed(c: Car): bool = true
var var
images: seq[cstring] = @[cstring"a", "b", "c", "d"] images: seq[cstring] = @[cstring"a", "b", "c", "d"]
proc carousel*(key: VKey): VNode {.component.} = proc carousel*(): VNode =
state: let c = car(images)
var counter: int = 0
var cntdown: int = 5
var timer: Timeout = nil
proc docount() =
cntdown = cntdown - 1
if cntdown == 0:
counter = (counter + 1) mod images.len
cntdown = 5
else:
timer = setTimeout(docount, 30)
redraw()
proc next(ev: Event; n: VNode) =
if timer != nil:
clearTimeout(timer)
timer = setTimeout(docount, 30)
let col = let col =
case counter case c.counter
of 0: cstring"#4d4d4d" of 0: cstring"#4d4d4d"
of 1: cstring"#ff00ff" of 1: cstring"#ff00ff"
of 2: cstring"#00ffff" of 2: cstring"#00ffff"
of 3: cstring"#ffff00" of 3: cstring"#ffff00"
else: cstring"red" else: cstring"red"
result = buildHtml(tdiv(nref = c)):
result = buildHtml(tdiv(key=key)): text images[c.counter]
text images[counter] button(onclick = c.onclick):
button(onclick = next):
text "Next" text "Next"
tdiv(style = style(StyleAttr.color, col)): tdiv(style = style(StyleAttr.color, col)):
text "This changes its color." text "This changes its color."
if cntdown != 5: if c.cntdown != ticksUntilChange:
text &cntdown text &c.cntdown
proc createDom(): VNode = proc createDom(): VNode =
result = buildHtml(table): result = buildHtml(table):
tr: tr:
td: td:
carousel(0) carousel()
td: td:
carousel(1) carousel()
tr: tr:
td: td:
carousel(2) carousel()
td: td:
carousel(3) carousel()
setRenderer createDom setRenderer createDom

View file

@ -2,7 +2,7 @@ include karaxprelude
import future, sequtils import future, sequtils
type type
CustomRef = ref object of VNodeRef CustomRef = ref object of VComponent
method onAttach(r: CustomRef) = method onAttach(r: CustomRef) =
kout(cstring"custom ref attached") kout(cstring"custom ref attached")
@ -13,10 +13,10 @@ method onDetach(r: CustomRef) =
var var
modelData = @[5, 2, 4] modelData = @[5, 2, 4]
refA = VNodeRef() refA = VComponent()
refB = VNodeRef() refB = VComponent()
refC = CustomRef() refC = CustomRef()
refSeq = newSeq[VNodeRef]() refSeq = newSeq[VComponent]()
proc onClick(ev: Event, n: VNode) = proc onClick(ev: Event, n: VNode) =
modelData.add(0) modelData.add(0)
@ -25,11 +25,13 @@ proc showRefs() =
kout(refA) kout(refA)
kout(refB) kout(refB)
kout(refC) kout(refC)
kout(refSeq.map(nref => nref.vnode)) for i in 0 ..< refSeq.len:
kout(refSeq[i].vnode)
#kout(refSeq.map(nref => nref.vnode))
proc secureRefSlot(i: int): VNodeRef = proc secureRefSlot(i: int): VComponent =
while refSeq.len <= i: while refSeq.len <= i:
refSeq.add(VNodeRef()) refSeq.add(VComponent())
result = refSeq[i] result = refSeq[i]
proc view(): VNode = proc view(): VNode =
@ -53,4 +55,4 @@ proc view(): VNode =
proc renderer(): VNode = proc renderer(): VNode =
view() view()
setRenderer(renderer, showRefs) setRenderer(renderer, "ROOT", showRefs)

View file

@ -150,6 +150,9 @@ proc eq(a, b: VNode; deep: bool): EqResult =
if a.id != b.id: return different if a.id != b.id: return different
result = identical result = identical
if a.key != b.key: return different if a.key != b.key: return different
if a.nref != nil and changed(a.nref):
kout cstring"yes, change!"
return different
if a.kind == VNodeKind.text: if a.kind == VNodeKind.text:
if a.text != b.text: return different if a.text != b.text: return different
elif a.kind == VNodeKind.vthunk or a.kind == VNodeKind.dthunk: elif a.kind == VNodeKind.vthunk or a.kind == VNodeKind.dthunk:
@ -201,6 +204,7 @@ proc updateStyles(newNode, oldNode: VNode; deep: bool) =
proc updateDom(newNode, oldNode: VNode) = proc updateDom(newNode, oldNode: VNode) =
newNode.dom = oldNode.dom newNode.dom = oldNode.dom
newNode.nref = oldNode.nref
assert newNode.len == oldNode.len assert newNode.len == oldNode.len
for i in 0 ..< newNode.len: for i in 0 ..< newNode.len:
updateDom(newNode[i], oldNode[i]) updateDom(newNode[i], oldNode[i])

View file

@ -101,8 +101,7 @@ macro buildLookupTables(): untyped =
buildLookupTables() buildLookupTables()
type type
VNodeRef* = ref object of RootObj VComponent* = ref object of RootObj
vnode*: VNode
EventHandler* = proc (ev: Event; target: VNode) {.closure.} EventHandler* = proc (ev: Event; target: VNode) {.closure.}
VKey* = int VKey* = int
@ -111,7 +110,7 @@ type
kind*: VNodeKind kind*: VNodeKind
key*: VKey key*: VKey
id*, class*, text*: cstring id*, class*, text*: cstring
nref*: VNodeRef nref*: VComponent
kids: seq[VNode] kids: seq[VNode]
# even index: key, odd index: value; done this way for memory efficiency: # even index: key, odd index: value; done this way for memory efficiency:
attrs: seq[cstring] attrs: seq[cstring]
@ -122,9 +121,9 @@ type
dom*: Node ## the attached real DOM node. Can be 'nil' if the virtual node dom*: Node ## the attached real DOM node. Can be 'nil' if the virtual node
## is not part of the virtual DOM anymore. ## is not part of the virtual DOM anymore.
method onAttach*(v: VNodeRef) {.base.} = discard method onAttach*(v: VComponent) {.base.} = discard
method onDetach*(v: VNodeRef) {.base.} = discard method onDetach*(v: VComponent) {.base.} = discard
method changed*(v: VNodeRef): bool {.base.} = false method changed*(v: VComponent): bool {.base.} = false
proc value*(n: VNode): cstring = n.text proc value*(n: VNode): cstring = n.text
proc `value=`*(n: VNode; v: cstring) = n.text = v proc `value=`*(n: VNode; v: cstring) = n.text = v