nextgen example works now

This commit is contained in:
Andreas Rumpf 2017-08-28 12:10:48 +02:00
commit 775a4a1289
2 changed files with 47 additions and 26 deletions

View file

@ -1,13 +1,12 @@
import vdom, kdom, vstyles, karax, karaxdsl, jdict, jstrutils, reactive import vdom, kdom, vstyles, karax, karaxdsl, jdict, jstrutils, reactive
proc newTextInput*(text: RString; focus: RBool): VNode {.track.} = proc textInput*(text: RString; focus: RBool): VNode {.track.} =
proc onFlip(ev: Event; target: VNode) = proc onFlip(ev: Event; target: VNode) =
focus <- not focus.value focus <- not focus.value
proc onKeyupEnter(ev: Event; target: VNode) = proc onKeyupEnter(ev: Event; target: VNode) =
text <- target.value text <- target.value
#text.notifyObservers()
proc onkeyup(ev: Event; n: VNode) = proc onkeyup(ev: Event; n: VNode) =
# keep displayValue up to date, but do not tell the client yet! # keep displayValue up to date, but do not tell the client yet!
@ -30,29 +29,49 @@ var gu = newRSeq(@[ (User(firstname: "Some", lastname: "Body")),
(User(firstname: "Some", lastname: "Two"))]) (User(firstname: "Some", lastname: "Two"))])
var prevSelected: User = nil #newReactive[User](nil) var prevSelected: User = nil #newReactive[User](nil)
proc toUI*(): RString = proc unselect() =
if prevSelected != nil:
prevSelected.selected = false
notifyObservers(prevSelected)
prevSelected = nil
proc select(u: User) =
unselect()
u.selected = true
notifyObservers(u)
prevSelected = u
proc toUI*(isFirstname: bool): RString =
result = RString() result = RString()
result.subscribe proc (v: cstring) = result.subscribe proc (v: cstring) =
if v.len > 0: if v.len > 0:
let p = prevSelected #selected.value let p = prevSelected #selected.value
if p != nil: if p != nil:
# XXX what's happening here? if isFirstName:
p.firstname = v p.firstname = v
else:
p.lastname = v
notifyObservers(p) notifyObservers(p)
unselect()
errmsg <- "" errmsg <- ""
else: else:
errmsg <- "name must not be empty" errmsg <- "name must not be empty"
var inp = toUI() var firstname = toUI(true)
var lastname = toUI(false)
proc adaptFocus(def = false): RBool = proc adaptFocus(def = false): RBool =
result = RBool() result = RBool()
result.value = def result.value = def
result.subscribe proc (hasFocus: bool) = when false:
if not hasFocus: result.subscribe proc (hasFocus: bool) =
inp.notifyObservers() if not hasFocus:
unselect()
firstname.notifyObservers()
lastname.notifyObservers()
var focus = adaptFocus() var focusA = adaptFocus()
var focusB = adaptFocus()
proc styler(): VStyle = proc styler(): VStyle =
result = style( result = style(
@ -61,7 +80,7 @@ proc styler(): VStyle =
(StyleAttr.paddingRight, cstring"5px"), (StyleAttr.paddingRight, cstring"5px"),
(StyleAttr.height, cstring"30px"), (StyleAttr.height, cstring"30px"),
(StyleAttr.lineHeight, cstring"30px"), (StyleAttr.lineHeight, cstring"30px"),
(StyleAttr.border, cstring"solid 8px " & (if focus.value: cstring"red" else: cstring"black")), (StyleAttr.border, cstring"solid 8px " & (if focusA.value: cstring"red" else: cstring"black")),
(StyleAttr.fontSize, cstring"12px"), (StyleAttr.fontSize, cstring"12px"),
(StyleAttr.fontWeight, cstring"600") (StyleAttr.fontWeight, cstring"600")
) )
@ -88,22 +107,19 @@ template observe(s: cstring): RString =
proc renderUser(u: User): VNode {.track.} = proc renderUser(u: User): VNode {.track.} =
result = buildHtml(tdiv): result = buildHtml(tdiv):
let displayName = u.firstname & " " & u.lastname
if u.selected: if u.selected:
# == selected.value: !(firstname <- u.firstname)
!(inp <- displayName) tdiv:
newTextInput inp, focus textInput firstname, focusA
!(lastname <- u.lastname)
tdiv:
textInput lastname, focusB
else: else:
button: button:
text "..." text "..."
proc onclick(ev: Event; n: VNode) = proc onclick(ev: Event; n: VNode) =
if prevSelected != nil: select(u)
prevSelected.selected = false text u.firstname & " " & u.lastname
notifyObservers(prevSelected)
u.selected = true
notifyObservers(u)
prevSelected = u
text displayName
button: button:
text "(x)" text "(x)"
proc onclick(ev: Event; n: VNode) = proc onclick(ev: Event; n: VNode) =

View file

@ -52,8 +52,11 @@ proc addSink(x: ReactiveBase; sink: proc(msg: Message; pos: int)) =
inc rid inc rid
x.id = rid x.id = rid
var inhibited: int
proc broadcast(x: ReactiveBase, msg: Message; pos = 0) = proc broadcast(x: ReactiveBase, msg: Message; pos = 0) =
for s in x.sinks: s(msg, pos) if inhibited == 0:
for s in x.sinks: s(msg, pos)
var toTrack: proc (msg: Message; pos: int) = nil var toTrack: proc (msg: Message; pos: int) = nil
@ -220,10 +223,12 @@ proc map*[T, U](x: RSeq[T], f: proc(x: T): U): RSeq[U] =
import macros import macros
template protect(r: ReactiveBase; body: untyped) = template protect(r: ReactiveBase; body: untyped) =
var tmp: seq[proc(msg: Message, pos: int)] #var tmp: seq[proc(msg: Message, pos: int)]
swap(r.sinks, tmp) #swap(r.sinks, tmp)
inc inhibited
body body
swap(r.sinks, tmp) dec inhibited
#swap(r.sinks, tmp)
template trackImpl(r: ReactiveBase; key: cstring; a, b: untyped) = template trackImpl(r: ReactiveBase; key: cstring; a, b: untyped) =
when r is ReactiveBase: when r is ReactiveBase: