implementation.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include "implementation.h"
  2. #include "implementation.hpp"
  3. movable_bounds::movable_bounds(range2D bounds) : bounds(bounds) { }
  4. int2 movable_bounds::lower() const
  5. {
  6. return bounds.lower();
  7. }
  8. int2 movable_bounds::upper() const
  9. {
  10. return bounds.upper();
  11. }
  12. movable_bounds& movable_bounds::operator+=(const int2& offset)
  13. {
  14. bounds += offset;
  15. return *this;
  16. }
  17. ui_element::ui_element(const i_bounds<int2>& bounds) :
  18. current(state::idle),
  19. bounds_proxy(bounds),
  20. _focus(false)
  21. { }
  22. bool contains(const i_bounds<int2>& bounds, int2 point)
  23. {
  24. return bounds.lower() < point && point < bounds.upper();
  25. };
  26. void ui_element::update(const interactive::event& event) noexcept
  27. {
  28. if(state::disabled == current)
  29. return;
  30. std::visit(support::overload{
  31. [this](const interactive::mouse_down& mouse)
  32. {
  33. if(contains(bounds_proxy, mouse.data.position))
  34. {
  35. current = state::pressed;
  36. for(auto&& callback : on_press)
  37. callback(*this);
  38. }
  39. },
  40. [this](const interactive::mouse_up& mouse)
  41. {
  42. if(state::pressed == current)
  43. {
  44. current = state::idle;
  45. for(auto&& callback : on_release)
  46. callback(*this);
  47. if(contains(bounds_proxy, mouse.data.position))
  48. {
  49. current = state::hover;
  50. for(auto&& callback : on_click)
  51. callback(*this);
  52. }
  53. }
  54. },
  55. [this](const interactive::mouse_motion& mouse)
  56. {
  57. if(contains(bounds_proxy, mouse.data.position))
  58. {
  59. if(state::idle == current )
  60. current = state::hover;
  61. }
  62. else
  63. {
  64. if(state::hover == current )
  65. current = state::idle;
  66. }
  67. },
  68. [](auto) { }
  69. }, event);
  70. }
  71. auto ui_element::current_state() const noexcept -> state
  72. {
  73. return current;
  74. }
  75. void ui_element::disable(bool value) noexcept
  76. {
  77. if(value && current != state::disabled)
  78. current = state::disabled;
  79. else
  80. if(!value && current == state::disabled)
  81. current = state::idle;
  82. }
  83. void ui_element::enable(bool value) noexcept
  84. {
  85. disable(!value);
  86. }
  87. void ui_element::drop_focus() noexcept
  88. {
  89. _focus = false;
  90. }
  91. void ui_element::gain_focus() noexcept
  92. {
  93. _focus = true;
  94. }
  95. bool ui_element::focus() const noexcept
  96. {
  97. return _focus;
  98. }
  99. bool ui_element::focus_on(const i_focusable& target) noexcept
  100. {
  101. if(&target == this)
  102. {
  103. gain_focus();
  104. return true;
  105. }
  106. return false;
  107. }
  108. bool ui_element::focus(direction) noexcept
  109. {
  110. if(!focus())
  111. {
  112. gain_focus();
  113. return true;
  114. }
  115. return false;
  116. }
  117. template class focus_group<std::vector<std::reference_wrapper<i_focusable>>>;