control.nim 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. # author: Ethosa
  2. import
  3. ../thirdparty/opengl,
  4. ../core/vector2,
  5. ../core/rect2,
  6. ../core/anchor,
  7. ../core/input,
  8. ../core/enums,
  9. ../nodes/node,
  10. ../nodes/canvas
  11. type
  12. ControlObj* = object of CanvasObj
  13. hovered*: bool
  14. pressed*: bool
  15. focused*: bool
  16. mousemode*: MouseMode
  17. mouse_enter*: proc(x, y: float): void ## This called when the mouse enters the Control node.
  18. mouse_exit*: proc(x, y: float): void ## This called when the mouse exit from the Control node.
  19. click*: proc(x, y: float): void ## This called when the user clicks on the Control node.
  20. press*: proc(x, y: float): void ## This called when the user holds on the mouse on the Control node.
  21. release*: proc(x, y: float): void ## This called when the user no more holds on the mouse.
  22. focus*: proc(): void ## This called when the Control node gets focus.
  23. unfocus*: proc(): void ## This called when the Control node loses focus.
  24. ControlPtr* = ptr ControlObj
  25. template controlpattern*: untyped =
  26. variable.hovered = false
  27. variable.focused = false
  28. variable.pressed = false
  29. variable.mousemode = MOUSEMODE_SEE
  30. variable.mouse_enter = proc(x, y: float) = discard
  31. variable.mouse_exit = proc(x, y: float) = discard
  32. variable.click = proc(x, y: float) = discard
  33. variable.press = proc(x, y: float) = discard
  34. variable.release = proc(x, y: float) = discard
  35. variable.focus = proc() = discard
  36. variable.unfocus = proc() = discard
  37. proc Control*(name: string, variable: var ControlObj): ControlPtr =
  38. nodepattern(ControlObj)
  39. controlpattern()
  40. proc Control*(obj: var ControlObj): ControlPtr {.inline.} =
  41. Control("Control", obj)
  42. method calcPositionAnchor*(self: ControlPtr) =
  43. if self.parent != nil:
  44. if self.can_use_size_anchor:
  45. if self.size_anchor.x > 0.0:
  46. self.rect_size.x = self.parent.rect_size.x * self.size_anchor.x
  47. if self.size_anchor.y > 0.0:
  48. self.rect_size.y = self.parent.rect_size.y * self.size_anchor.y
  49. if self.can_use_anchor:
  50. self.position.x = self.parent.rect_size.x*self.anchor.x1 - self.rect_size.x*self.anchor.x2
  51. self.position.y = self.parent.rect_size.y*self.anchor.y1 - self.rect_size.y*self.anchor.y2
  52. method draw*(self: ControlPtr, w, h: GLfloat) =
  53. {.warning[LockLevel]: off.}
  54. self.calcGlobalPosition()
  55. # Press
  56. if self.pressed:
  57. self.press(last_event.x, last_event.y)
  58. method getGlobalMousePosition*(self: ControlPtr): Vector2Ref {.base, inline.} =
  59. ## Returns mouse position.
  60. Vector2Ref(x: last_event.x, y: last_event.y)
  61. method handle*(self: ControlPtr, event: InputEvent, mouse_on: var NodePtr) =
  62. {.warning[LockLevel]: off.}
  63. if self.mousemode == MOUSEMODE_IGNORE:
  64. return
  65. let
  66. hasmouse = Rect2(self.global_position, self.rect_size).hasPoint(event.x, event.y)
  67. click = mouse_pressed and event.kind == MOUSE
  68. if mouse_on == nil and hasmouse:
  69. mouse_on = self
  70. # Hover
  71. if not self.hovered:
  72. self.mouse_enter(event.x, event.y)
  73. self.hovered = true
  74. # Focus
  75. if not self.focused and click:
  76. self.focused = true
  77. self.focus()
  78. # Click
  79. if mouse_pressed and not self.pressed:
  80. self.pressed = true
  81. self.click(event.x, event.y)
  82. elif not hasmouse:
  83. if not mouse_pressed and self.hovered:
  84. self.mouse_exit(event.x, event.y)
  85. self.hovered = false
  86. # Unfocus
  87. if self.focused and click:
  88. self.unfocus()
  89. self.focused = false
  90. if not mouse_pressed and self.pressed:
  91. self.pressed = false
  92. self.release(event.x, event.y)