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
proc newTextInput*(text: RString; focus: RBool): VNode {.track.} =
proc textInput*(text: RString; focus: RBool): VNode {.track.} =
proc onFlip(ev: Event; target: VNode) =
focus <- not focus.value
proc onKeyupEnter(ev: Event; target: VNode) =
text <- target.value
#text.notifyObservers()
proc onkeyup(ev: Event; n: VNode) =
# 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"))])
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.subscribe proc (v: cstring) =
if v.len > 0:
let p = prevSelected #selected.value
if p != nil:
# XXX what's happening here?
p.firstname = v
if isFirstName:
p.firstname = v
else:
p.lastname = v
notifyObservers(p)
unselect()
errmsg <- ""
else:
errmsg <- "name must not be empty"
var inp = toUI()
var firstname = toUI(true)
var lastname = toUI(false)
proc adaptFocus(def = false): RBool =
result = RBool()
result.value = def
result.subscribe proc (hasFocus: bool) =
if not hasFocus:
inp.notifyObservers()
when false:
result.subscribe proc (hasFocus: bool) =
if not hasFocus:
unselect()
firstname.notifyObservers()
lastname.notifyObservers()
var focus = adaptFocus()
var focusA = adaptFocus()
var focusB = adaptFocus()
proc styler(): VStyle =
result = style(
@ -61,7 +80,7 @@ proc styler(): VStyle =
(StyleAttr.paddingRight, cstring"5px"),
(StyleAttr.height, 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.fontWeight, cstring"600")
)
@ -88,22 +107,19 @@ template observe(s: cstring): RString =
proc renderUser(u: User): VNode {.track.} =
result = buildHtml(tdiv):
let displayName = u.firstname & " " & u.lastname
if u.selected:
# == selected.value:
!(inp <- displayName)
newTextInput inp, focus
!(firstname <- u.firstname)
tdiv:
textInput firstname, focusA
!(lastname <- u.lastname)
tdiv:
textInput lastname, focusB
else:
button:
text "..."
proc onclick(ev: Event; n: VNode) =
if prevSelected != nil:
prevSelected.selected = false
notifyObservers(prevSelected)
u.selected = true
notifyObservers(u)
prevSelected = u
text displayName
select(u)
text u.firstname & " " & u.lastname
button:
text "(x)"
proc onclick(ev: Event; n: VNode) =

View file

@ -52,8 +52,11 @@ proc addSink(x: ReactiveBase; sink: proc(msg: Message; pos: int)) =
inc rid
x.id = rid
var inhibited: int
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
@ -220,10 +223,12 @@ proc map*[T, U](x: RSeq[T], f: proc(x: T): U): RSeq[U] =
import macros
template protect(r: ReactiveBase; body: untyped) =
var tmp: seq[proc(msg: Message, pos: int)]
swap(r.sinks, tmp)
#var tmp: seq[proc(msg: Message, pos: int)]
#swap(r.sinks, tmp)
inc inhibited
body
swap(r.sinks, tmp)
dec inhibited
#swap(r.sinks, tmp)
template trackImpl(r: ReactiveBase; key: cstring; a, b: untyped) =
when r is ReactiveBase: