scrollbar.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // Flexlay - A Generic 2D Game Editor
  2. // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. #include <ClanLib/Display/display.h>
  17. #include <ClanLib/Display/keys.h>
  18. #include "scrollbar.hpp"
  19. class ScrollbarImpl
  20. {
  21. public:
  22. std::vector<CL_Slot> slots;
  23. ScrollbarImpl(Scrollbar* parent_) : parent(parent_) {}
  24. Scrollbar* parent;
  25. float min;
  26. float max;
  27. float pagesize;
  28. float pos;
  29. Scrollbar::Orientation orientation;
  30. CL_Signal_v1<float> on_scrollbar_move;
  31. float old_pos;
  32. bool pressed;
  33. CL_Point click_pos;
  34. void draw();
  35. void on_mouse_up(const CL_InputEvent& event);
  36. void on_mouse_down(const CL_InputEvent& event);
  37. void on_mouse_move(const CL_InputEvent& event);
  38. };
  39. Scrollbar::Scrollbar(const CL_Rect& rect, Orientation orientation, CL_Component* parent)
  40. : CL_Component(rect, parent),
  41. impl(new ScrollbarImpl(this))
  42. {
  43. impl->min = 0;
  44. impl->max = 100;
  45. impl->pagesize = 10;
  46. impl->pos = 0;
  47. impl->pressed = false;
  48. impl->orientation = orientation;
  49. impl->slots.push_back(sig_paint().connect(impl.get(), &ScrollbarImpl::draw));
  50. impl->slots.push_back(sig_mouse_down().connect(impl.get(), &ScrollbarImpl::on_mouse_down));
  51. impl->slots.push_back(sig_mouse_up().connect(impl.get(), &ScrollbarImpl::on_mouse_up));
  52. impl->slots.push_back(sig_mouse_move().connect(impl.get(), &ScrollbarImpl::on_mouse_move));
  53. }
  54. void
  55. Scrollbar::set_range(float min, float max)
  56. {
  57. impl->min = min;
  58. impl->max = max;
  59. }
  60. void
  61. Scrollbar::set_pagesize(float size)
  62. {
  63. impl->pagesize = size;
  64. }
  65. void
  66. Scrollbar::set_pos(float pos)
  67. {
  68. impl->pos = pos;
  69. }
  70. void
  71. ScrollbarImpl::draw()
  72. {
  73. CL_Display::push_cliprect(parent->get_screen_rect());
  74. CL_Display::push_translate(parent->get_screen_x(), parent->get_screen_y());
  75. CL_Rect rect = CL_Rect(CL_Point(0, 0),
  76. CL_Size(parent->get_width()-1,
  77. parent->get_height()-1));
  78. CL_Display::fill_rect(rect,
  79. CL_Color(255, 255, 255));
  80. if (orientation == Scrollbar::HORIZONTAL)
  81. {
  82. float scale = parent->get_width()/(max - min);
  83. CL_Display::fill_rect(CL_Rect(CL_Point(int((pos-min-(pagesize/2)) * scale), 2),
  84. CL_Size(int(pagesize*scale),
  85. parent->get_height()-5)),
  86. CL_Color(0, 0, 0));
  87. }
  88. else if (orientation == Scrollbar::VERTICAL)
  89. {
  90. float scale = parent->get_height()/(max - min);
  91. CL_Display::fill_rect(CL_Rect(CL_Point(2, int((pos-min-(pagesize/2)) * scale)),
  92. CL_Size(parent->get_width()-5,
  93. int(pagesize*scale))),
  94. CL_Color(0, 0, 0));
  95. }
  96. CL_Display::draw_rect(rect,
  97. CL_Color(155, 155, 155));
  98. CL_Display::pop_modelview();
  99. CL_Display::pop_cliprect();
  100. }
  101. void
  102. ScrollbarImpl::on_mouse_up(const CL_InputEvent& event)
  103. {
  104. if (event.id == CL_MOUSE_LEFT)
  105. {
  106. pressed = false;
  107. parent->release_mouse();
  108. }
  109. }
  110. void
  111. ScrollbarImpl::on_mouse_down(const CL_InputEvent& event)
  112. {
  113. if (event.id == CL_MOUSE_LEFT)
  114. {
  115. pressed = true;
  116. click_pos = event.mouse_pos;
  117. parent->capture_mouse();
  118. float scale = ((orientation == Scrollbar::VERTICAL)
  119. ? parent->get_height() : parent->get_width())/(max - min);
  120. old_pos = pos * scale;
  121. click_pos.x += parent->get_position().left;
  122. click_pos.y += parent->get_position().top;
  123. }
  124. }
  125. void
  126. ScrollbarImpl::on_mouse_move(const CL_InputEvent& event)
  127. {
  128. if(pressed)
  129. {
  130. CL_Rect rect = parent->get_position();
  131. float scale = ((orientation == Scrollbar::VERTICAL)
  132. ? parent->get_height() : parent->get_width())/(max - min);
  133. if (orientation == Scrollbar::VERTICAL)
  134. {
  135. pos = (old_pos - (click_pos.y - (rect.top + event.mouse_pos.y)))/scale;
  136. }
  137. else if (orientation == Scrollbar::HORIZONTAL)
  138. {
  139. pos = (old_pos - (click_pos.x - (rect.left + event.mouse_pos.x)))/scale;
  140. }
  141. on_scrollbar_move(pos);
  142. }
  143. }
  144. CL_Signal_v1<float>&
  145. Scrollbar::sig_scrollbar_move()
  146. {
  147. return impl->on_scrollbar_move;
  148. }
  149. /* EOF */