scroll.nim 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. # author: Ethosa
  2. import
  3. ../thirdparty/opengl,
  4. ../core/vector2,
  5. ../core/rect2,
  6. ../core/anchor,
  7. ../core/input,
  8. ../core/enums,
  9. ../core/color,
  10. ../nodes/node,
  11. control
  12. type
  13. ScrollObj* = object of ControlObj
  14. thumb_y_has_mouse*, thumb_x_has_mouse*: bool
  15. thumb_width*, thumb_height*: float
  16. viewport_w*, viewport_h*: float
  17. viewport_x*, viewport_y*: float
  18. thumb_color*: ColorRef
  19. back_color*: ColorRef
  20. ScrollPtr* = ptr ScrollObj
  21. proc Scroll*(name: string, variable: var ScrollObj): ScrollPtr =
  22. nodepattern(ScrollObj)
  23. controlpattern()
  24. variable.rect_size.x = 256
  25. variable.rect_size.y = 256
  26. variable.viewport_h = 256
  27. variable.viewport_w = 256
  28. variable.viewport_x = 0
  29. variable.viewport_y = 0
  30. variable.thumb_width = 8
  31. variable.thumb_height = 8
  32. variable.back_color = Color(0, 0, 0, 128)
  33. variable.thumb_color = Color(0, 0, 0, 128)
  34. variable.thumb_y_has_mouse = false
  35. variable.thumb_x_has_mouse = false
  36. variable.mousemode = MOUSEMODE_IGNORE
  37. proc Scroll*(obj: var ScrollObj): ScrollPtr {.inline.} =
  38. Scroll("Scroll", obj)
  39. method addChild*(self: ScrollPtr, other: NodePtr) =
  40. ## Adds a new node in Scroll.
  41. ##
  42. if self.children.len() == 0:
  43. self.children.add(other)
  44. other.parent = self
  45. method dublicate*(self: ScrollPtr, obj: var ScrollObj): ScrollPtr {.base.} =
  46. obj = self[]
  47. obj.addr
  48. method resize*(canvas: ScrollPtr, w, h: GLfloat) =
  49. canvas.rect_size.x = w
  50. canvas.rect_size.y = h
  51. method draw*(self: ScrollPtr, w, h: GLfloat) =
  52. self.calcGlobalPosition()
  53. let
  54. x = -w/2 + self.global_position.x
  55. y = h/2 - self.global_position.y
  56. glColor4f(self.background_color.r, self.background_color.g, self.background_color.b, self.background_color.a)
  57. glRectf(x, y, x+self.viewport_w, y-self.viewport_h)
  58. # Press
  59. if self.pressed:
  60. self.press(last_event.x, last_event.y)
  61. method draw2stage*(self: ScrollPtr, w, h: GLfloat) =
  62. let
  63. x = -w/2 + self.global_position.x
  64. y = h/2 - self.global_position.y
  65. if self.children.len() > 0:
  66. var child = self.children[0]
  67. self.resize(child.rect_size.x, child.rect_size.y)
  68. let
  69. thumb_h = self.viewport_h * (self.viewport_h / self.rect_size.y)
  70. thumb_w = self.viewport_w * (self.viewport_w / self.rect_size.x)
  71. thumb_x = self.viewport_w * (self.viewport_x / self.rect_size.x)
  72. thumb_y = self.viewport_h * (self.viewport_y / self.rect_size.y)
  73. child.position.x = -self.viewport_x
  74. child.position.y = -self.viewport_y
  75. # Vertical
  76. if self.viewport_h < self.rect_size.y:
  77. # Back:
  78. glColor4f(self.back_color.r, self.back_color.g, self.back_color.b, self.back_color.a)
  79. glRectf(x + self.viewport_w - self.thumb_width, y, x+self.viewport_w, y-self.viewport_h)
  80. # Thumb:
  81. glColor4f(self.thumb_color.r, self.thumb_color.g, self.thumb_color.b, self.thumb_color.a)
  82. glRectf(x + self.viewport_w - self.thumb_width, y - thumb_y, x+self.viewport_w, y - thumb_y - thumb_h)
  83. # Horizontal
  84. if self.viewport_w < self.rect_size.x:
  85. # Back:
  86. glColor4f(self.back_color.r, self.back_color.g, self.back_color.b, self.back_color.a)
  87. glRectf(x, y - self.viewport_h + self.thumb_height, x + self.viewport_w - self.thumb_width, y-self.viewport_h)
  88. # Thumb:
  89. glColor4f(self.thumb_color.r, self.thumb_color.g, self.thumb_color.b, self.thumb_color.a)
  90. glRectf(x + thumb_x, y - self.viewport_h + self.thumb_height, x + thumb_x + thumb_w, y-self.viewport_h)
  91. method scrollBy*(self: ScrollPtr, x, y: float) {.base.} =
  92. if x + self.viewport_x + self.viewport_w < self.rect_size.x and x + self.viewport_x > 0:
  93. self.viewport_x += x
  94. elif x < 0:
  95. self.viewport_x = 0
  96. elif x > 0:
  97. self.viewport_x = self.rect_size.x - self.viewport_w
  98. if y + self.viewport_y + self.viewport_h < self.rect_size.y and y + self.viewport_y > 0:
  99. self.viewport_y += y
  100. elif y < 0:
  101. self.viewport_y = 0
  102. elif y > 0:
  103. self.viewport_y = self.rect_size.y - self.viewport_h
  104. method handle*(self: ScrollPtr, event: InputEvent, mouse_on: var NodePtr) =
  105. procCall self.ControlPtr.handle(event, mouse_on)
  106. let
  107. mouse_in = Rect2(self.global_position, Vector2(self.viewport_w, self.viewport_h)).hasPoint(event.x, event.y)
  108. thumb_h = self.viewport_h * (self.viewport_h / self.rect_size.y)
  109. thumb_w = self.viewport_w * (self.viewport_w / self.rect_size.x)
  110. thumb_x = self.viewport_w * (self.viewport_x / self.rect_size.x)
  111. thumb_y = self.viewport_h * (self.viewport_y / self.rect_size.y)
  112. mouse_in_y = Rect2(
  113. self.global_position.x + self.viewport_w - self.thumb_width,
  114. self.global_position.y + thumb_y,
  115. self.thumb_width,
  116. thumb_h
  117. ).hasPoint(event.x, event.y)
  118. mouse_in_x = Rect2(
  119. self.global_position.x + thumb_x,
  120. self.global_position.y + self.viewport_h - self.thumb_height,
  121. thumb_w,
  122. self.thumb_height
  123. ).hasPoint(event.x, event.y)
  124. if mouse_in: # Keyboard movement
  125. if event.kind == KEYBOARD:
  126. if event.key_cint in pressed_keys_cints: # Special chars
  127. if event.key_cint == K_UP:
  128. self.scrollBy(0, -40)
  129. elif event.key_cint == K_DOWN:
  130. self.scrollBy(0, 40)
  131. # Mouse Y
  132. if (mouse_in_y and mouse_pressed and event.kind == MOUSE) or self.thumb_y_has_mouse:
  133. self.thumb_y_has_mouse = true
  134. self.scrollBy(0, -event.yrel)
  135. if not mouse_pressed and self.thumb_y_has_mouse:
  136. self.thumb_y_has_mouse = false
  137. # Mouse X
  138. if (mouse_in_x and mouse_pressed and event.kind == MOUSE) or self.thumb_x_has_mouse:
  139. self.thumb_x_has_mouse = true
  140. self.scrollBy(-event.xrel, 0)
  141. if not mouse_pressed and self.thumb_x_has_mouse:
  142. self.thumb_x_has_mouse = false