From 507094bdfd92dc56d3cec5f65a9f4c2b7eee8a3d Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Tue, 11 Jul 2017 18:59:38 +0200 Subject: [PATCH] better event handling for components and in the DSL --- src/karax.nim | 1 + src/karaxdsl.nim | 38 ++++++++++++- src/vdom.nim | 19 ++++++- tests/components.nim | 128 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 tests/components.nim diff --git a/src/karax.nim b/src/karax.nim index c96901b..f284d31 100644 --- a/src/karax.nim +++ b/src/karax.nim @@ -61,6 +61,7 @@ template setNativeValue(ev, val) = cast[Element](ev.target).value = val template keyeventBody() = let v = nativeValue(ev) n.value = v + assert action != nil action(ev, n) if n.value != v: setNativeValue(ev, n.value) diff --git a/src/karaxdsl.nim b/src/karaxdsl.nim index c17d725..cfbe391 100644 --- a/src/karaxdsl.nim +++ b/src/karaxdsl.nim @@ -59,6 +59,19 @@ proc tcall2(n, tmpContext: NimNode): NimNode = result.add n[0] for i in 1 ..< n.len: result.add tcall2(n[i], tmpContext) + of nnkProcDef: + let name = getName n[0] + if name.startsWith"on": + # turn it into an anon proc: + let anon = copyNimTree(n) + anon[0] = newEmptyNode() + if tmpContext == nil: + error "no VNode to attach the event handler to" + else: + result = newCall(bindSym"addEventHandler", tmpContext, + newDotExpr(bindSym"EventKind", n[0]), anon, ident("kxi")) + else: + result = n of nnkVarSection, nnkLetSection, nnkConstSection: result = n of nnkCallKinds: @@ -87,6 +100,8 @@ proc tcall2(n, tmpContext: NimNode): NimNode = result.add newDotAsgn(tmp, key, x[1]) elif eqIdent(key, "setFocus"): result.add newCall(key, tmp, x[1], ident"kxi") + elif eqIdent(key, "events"): + result.add newCall(bindSym"mergeEvents", tmp, x[1]) else: result.add newCall(bindSym"setAttr", tmp, newLit(key), x[1]) elif ck != ComponentKind.Tag: @@ -100,7 +115,28 @@ proc tcall2(n, tmpContext: NimNode): NimNode = else: result.add newCall(bindSym"add", tmpContext, tmp) elif tmpContext != nil and op notin StmtContext: - result = newCall(bindSym"add", tmpContext, n) + var hasEventHandlers = false + for i in 1.. 0: + persons[index] = v + errmsg = "" + else: + errmsg = "name must not be empty" + button: + proc onclick(ev: Event; n: VNode) = + persons.delete(index) + errmsg = "" + echo persons + text "(x)" + + +proc createDom(): VNode = + result = buildHtml(tdiv): + tdiv: + for index, text in persons.pairs: + renderPerson(text, index) + tdiv: + newTextInput(VStyle(), &persons.len, ""): + proc onkeyuplater(ev: Event; n: VNode) = + let v = n.value + if v.len > 0: + persons.add v + errmsg = "" + else: + errmsg = "name must not be empty" + tdiv: + text errmsg + +setRenderer createDom