view.lua 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. local core = require "core"
  2. local config = require "core.config"
  3. local style = require "core.style"
  4. local common = require "core.common"
  5. local Object = require "core.object"
  6. local View = Object:extend()
  7. function View:new()
  8. self.position = { x = 0, y = 0 }
  9. self.size = { x = 0, y = 0 }
  10. self.scroll = { x = 0, y = 0, to = { x = 0, y = 0 } }
  11. self.cursor = "arrow"
  12. self.scrollable = false
  13. self.focusable = true
  14. end
  15. function View:move_towards(t, k, dest, rate)
  16. if type(t) ~= "table" then
  17. return self:move_towards(self, t, k, dest, rate)
  18. end
  19. local val = t[k]
  20. if math.abs(val - dest) < 0.5 then
  21. t[k] = dest
  22. else
  23. t[k] = common.lerp(val, dest, rate or 0.5)
  24. end
  25. if val ~= dest then
  26. core.redraw = true
  27. end
  28. end
  29. function View:try_close(do_close)
  30. do_close()
  31. end
  32. function View:get_name()
  33. return "---"
  34. end
  35. function View:get_scrollable_size()
  36. return 0
  37. end
  38. function View:get_scrollbar_rect()
  39. local sz = self:get_scrollable_size()
  40. if sz <= self.size.y then
  41. return 0, 0, 0, 0
  42. end
  43. local h = math.max(20, self.size.y * self.size.y / sz)
  44. return
  45. self.position.x + self.size.x - style.scrollbar_size,
  46. self.position.y + self.scroll.y * (self.size.y - h) / (sz - self.size.y),
  47. style.scrollbar_size,
  48. h
  49. end
  50. function View:scrollbar_overlaps_point(x, y)
  51. local sx, sy, sw, sh = self:get_scrollbar_rect()
  52. return x >= sx - sw * 3 and x < sx + sw and y >= sy and y < sy + sh
  53. end
  54. function View:on_mouse_pressed(button, x, y, clicks)
  55. if self:scrollbar_overlaps_point(x, y) then
  56. self.dragging_scrollbar = true
  57. return true
  58. end
  59. end
  60. function View:on_mouse_released(button, x, y)
  61. self.dragging_scrollbar = false
  62. end
  63. function View:on_mouse_moved(x, y, dx, dy)
  64. if self.dragging_scrollbar then
  65. local delta = self:get_scrollable_size() / self.size.y * dy
  66. self.scroll.to.y = self.scroll.to.y + delta
  67. end
  68. self.hovered_scrollbar = self:scrollbar_overlaps_point(x, y)
  69. end
  70. function View:on_text_input(text)
  71. -- no-op
  72. end
  73. function View:on_mouse_wheel(y)
  74. if self.scrollable then
  75. self.scroll.to.y = self.scroll.to.y + y * -config.mouse_wheel_scroll
  76. end
  77. end
  78. function View:get_content_bounds()
  79. local x = self.scroll.x
  80. local y = self.scroll.y
  81. return x, y, x + self.size.x, y + self.size.y
  82. end
  83. function View:get_content_offset()
  84. return self.position.x - self.scroll.x, self.position.y - self.scroll.y
  85. end
  86. function View:update()
  87. self:move_towards(self.scroll, "x", self.scroll.to.x, 0.3)
  88. self:move_towards(self.scroll, "y", self.scroll.to.y, 0.3)
  89. end
  90. function View:draw_background(color)
  91. local x, y = self.position.x, self.position.y
  92. local w, h = self.size.x, self.size.y
  93. renderer.draw_rect(x, y, math.ceil(w), math.ceil(h), color)
  94. end
  95. function View:draw_scrollbar()
  96. local x, y, w, h = self:get_scrollbar_rect()
  97. local highlight = self.hovered_scrollbar or self.dragging_scrollbar
  98. local color = highlight and style.scrollbar2 or style.scrollbar
  99. renderer.draw_rect(x, y, w, h, color)
  100. end
  101. function View:draw()
  102. end
  103. return View