twidgets.nim 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. discard """
  2. cmd: '''nim c -d:nimAllocStats --newruntime $file'''
  3. output: '''button
  4. clicked!
  5. (allocCount: 4, deallocCount: 4)'''
  6. """
  7. import system / ansi_c
  8. type
  9. Widget* = ref object of RootObj
  10. drawImpl: owned(proc (self: Widget))
  11. Button* = ref object of Widget
  12. caption: string
  13. onclick: owned(proc())
  14. Window* = ref object of Widget
  15. elements: seq[owned Widget]
  16. proc newButton(caption: string; onclick: owned(proc())): owned Button =
  17. proc draw(self: Widget) =
  18. let b = Button(self)
  19. echo b.caption
  20. #result = Button(drawImpl: draw, caption: caption, onclick: onclick)
  21. new(result)
  22. result.drawImpl = draw
  23. result.caption = caption
  24. result.onclick = onclick
  25. iterator unitems*[T](a: seq[owned T]): T {.inline.} =
  26. ## Iterates over each item of `a`.
  27. var i = 0
  28. let L = len(a)
  29. while i < L:
  30. yield a[i]
  31. inc(i)
  32. assert(len(a) == L, "the length of the seq changed while iterating over it")
  33. proc newWindow(): owned Window =
  34. proc windraw(self: Widget) =
  35. let w = Window(self)
  36. for i in 0..<len(w.elements):
  37. let e = Widget(w.elements[i])
  38. let d = (proc(self: Widget))e.drawImpl
  39. if not d.isNil: d(e)
  40. result = Window(drawImpl: windraw, elements: @[])
  41. proc draw(w: Widget) =
  42. let d = (proc(self: Widget))w.drawImpl
  43. if not d.isNil: d(w)
  44. proc add*(w: Window; elem: owned Widget) =
  45. w.elements.add elem
  46. proc main =
  47. var w = newWindow()
  48. var b = newButton("button", nil)
  49. let u: Button = b
  50. b.onclick = proc () =
  51. u.caption = "clicked!"
  52. w.add b
  53. w.draw()
  54. # simulate button click:
  55. u.onclick()
  56. w.draw()
  57. dumpAllocstats:
  58. main()