ScrollLayout.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include "Base.h"
  2. #include "Control.h"
  3. #include "ScrollLayout.h"
  4. #include "Container.h"
  5. namespace gameplay
  6. {
  7. ScrollLayout::ScrollLayout()
  8. : _scrollPosition(Vector2::zero()), _lastX(0), _lastY(0), _scrolling(false),
  9. _positionVertically(false), _positionHorizontally(false)
  10. {
  11. }
  12. ScrollLayout::ScrollLayout(const ScrollLayout& copy)
  13. {
  14. }
  15. ScrollLayout::~ScrollLayout()
  16. {
  17. }
  18. ScrollLayout* ScrollLayout::create()
  19. {
  20. return new ScrollLayout();
  21. }
  22. Layout::Type ScrollLayout::getType()
  23. {
  24. return Layout::LAYOUT_SCROLL;
  25. }
  26. void ScrollLayout::update(const Container* container)
  27. {
  28. // Position controls if automatic positioning is enabled.
  29. if (_positionVertically && _positionHorizontally)
  30. {
  31. // Treat as scrollable flow layout.
  32. }
  33. else if (_positionVertically)
  34. {
  35. // Scrollable vertical layout.
  36. }
  37. else if (_positionHorizontally)
  38. {
  39. // Scrollable horizontal layout.
  40. }
  41. // Calculate total width and height.
  42. float totalWidth = 0;
  43. float totalHeight = 0;
  44. std::vector<Control*> controls = container->getControls();
  45. unsigned int controlsCount = controls.size();
  46. for (unsigned int i = 0; i < controlsCount; i++)
  47. {
  48. Control* control = controls.at(i);
  49. const Rectangle& bounds = control->getBounds();
  50. const Theme::Margin& margin = control->getMargin();
  51. float newWidth = bounds.x + bounds.width + margin.left + margin.right;
  52. if (newWidth > totalWidth)
  53. {
  54. totalWidth = newWidth;
  55. }
  56. float newHeight = bounds.y + bounds.height + margin.top + margin.bottom;
  57. if (newHeight > totalHeight)
  58. {
  59. totalHeight = newHeight;
  60. }
  61. }
  62. const Rectangle& containerBounds = container->getBounds();
  63. const Theme::Border& containerBorder = container->getBorder(container->getState());
  64. const Theme::Padding& containerPadding = container->getPadding();
  65. float clipWidth = containerBounds.width - containerBorder.left - containerBorder.right - containerPadding.left - containerPadding.right;
  66. float clipHeight = containerBounds.height - containerBorder.top - containerBorder.bottom - containerPadding.top - containerPadding.bottom;
  67. // Stop scrolling when the far edge is reached.
  68. if (-_scrollPosition.x > totalWidth - clipWidth)
  69. {
  70. _scrollPosition.x = -(totalWidth - clipWidth);
  71. }
  72. if (-_scrollPosition.y > totalHeight - clipHeight)
  73. {
  74. _scrollPosition.y = -(totalHeight - clipHeight);
  75. }
  76. if (_scrollPosition.x > 0)
  77. {
  78. _scrollPosition.x = 0;
  79. }
  80. if (_scrollPosition.y > 0)
  81. {
  82. _scrollPosition.y = 0;
  83. }
  84. // Position controls within scroll area.
  85. for (unsigned int i = 0; i < controlsCount; i++)
  86. {
  87. Control* control = controls.at(i);
  88. control->update(container->getClip(), _scrollPosition);
  89. }
  90. }
  91. bool ScrollLayout::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  92. {
  93. switch(evt)
  94. {
  95. case Touch::TOUCH_PRESS:
  96. _lastX = x;
  97. _lastY = y;
  98. _scrolling = true;
  99. break;
  100. case Touch::TOUCH_MOVE:
  101. if (_scrolling)
  102. {
  103. // Calculate the latest movement delta for the next update to use.
  104. _scrollPosition.x += x - _lastX;
  105. _scrollPosition.y += y - _lastY;
  106. _lastX = x;
  107. _lastY = y;
  108. return true;
  109. }
  110. break;
  111. case Touch::TOUCH_RELEASE:
  112. _scrolling = false;
  113. break;
  114. }
  115. return false;
  116. }
  117. }