DISTRHO Plugin Framework
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
6.4KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any purpose with
  6. * or without fee is hereby granted, provided that the above copyright notice and this
  7. * permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  10. * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  11. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  13. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include "../Layout.hpp"
  17. #include "../SubWidget.hpp"
  18. START_NAMESPACE_DGL
  19. typedef std::list<SubWidgetWithSizeHint>::iterator SubWidgetWithSizeHintIterator;
  20. typedef std::list<HorizontalLayout*>::iterator HorizontalLayoutIterator;
  21. typedef std::list<VerticalLayout*>::iterator VerticalLayoutIterator;
  22. // --------------------------------------------------------------------------------------------------------------------
  23. template<> // horizontal
  24. uint Layout<true>::setAbsolutePos(int x, const int y, const uint padding)
  25. {
  26. uint maxHeight = 0;
  27. for (SubWidgetWithSizeHintIterator it=widgets.begin(), end=widgets.end(); it != end; ++it)
  28. {
  29. SubWidgetWithSizeHint& s(*it);
  30. maxHeight = std::max(maxHeight, s.widget->getHeight());
  31. s.widget->setAbsolutePos(x, y);
  32. x += s.widget->getWidth();
  33. x += padding;
  34. }
  35. return maxHeight;
  36. }
  37. template<> // vertical
  38. uint Layout<false>::setAbsolutePos(const int x, int y, const uint padding)
  39. {
  40. uint maxWidth = 0;
  41. for (SubWidgetWithSizeHintIterator it=widgets.begin(), end=widgets.end(); it != end; ++it)
  42. {
  43. SubWidgetWithSizeHint& s(*it);
  44. maxWidth = std::max(maxWidth, s.widget->getWidth());
  45. s.widget->setAbsolutePos(x, y);
  46. y += s.widget->getHeight();
  47. y += padding;
  48. }
  49. return maxWidth;
  50. }
  51. template<> // horizontal
  52. void Layout<true>::setSize(const uint width, const uint padding)
  53. {
  54. uint maxHeight = 0;
  55. uint nonFixedWidth = width;
  56. uint numDynamiclySizedWidgets = 0;
  57. for (SubWidgetWithSizeHintIterator it=widgets.begin(), end=widgets.end(); it != end; ++it)
  58. {
  59. SubWidgetWithSizeHint& s(*it);
  60. maxHeight = std::max(maxHeight, s.widget->getHeight());
  61. if (s.sizeHint == Fixed)
  62. nonFixedWidth -= s.widget->getWidth();
  63. else
  64. ++numDynamiclySizedWidgets;
  65. }
  66. if (const size_t numWidgets = widgets.size())
  67. nonFixedWidth -= padding * (numWidgets - 1);
  68. const uint widthPerWidget = numDynamiclySizedWidgets != 0 ? nonFixedWidth / numDynamiclySizedWidgets : 0;
  69. for (SubWidgetWithSizeHintIterator it=widgets.begin(), end=widgets.end(); it != end; ++it)
  70. {
  71. SubWidgetWithSizeHint& s(*it);
  72. if (s.sizeHint != Fixed)
  73. s.widget->setSize(widthPerWidget, maxHeight);
  74. else
  75. s.widget->setHeight(maxHeight);
  76. }
  77. }
  78. template<> // vertical
  79. void Layout<false>::setSize(const uint height, const uint padding)
  80. {
  81. uint biggestWidth = 0;
  82. uint nonFixedHeight = height;
  83. uint numDynamiclySizedWidgets = 0;
  84. for (SubWidgetWithSizeHintIterator it=widgets.begin(), end=widgets.end(); it != end; ++it)
  85. {
  86. SubWidgetWithSizeHint& s(*it);
  87. biggestWidth = std::max(biggestWidth, s.widget->getWidth());
  88. if (s.sizeHint == Fixed)
  89. nonFixedHeight -= s.widget->getHeight();
  90. else
  91. ++numDynamiclySizedWidgets;
  92. }
  93. if (const size_t numWidgets = widgets.size())
  94. nonFixedHeight -= padding * (numWidgets - 1);
  95. const uint heightPerWidget = numDynamiclySizedWidgets != 0 ? nonFixedHeight / numDynamiclySizedWidgets : 0;
  96. for (SubWidgetWithSizeHintIterator it=widgets.begin(), end=widgets.end(); it != end; ++it)
  97. {
  98. SubWidgetWithSizeHint& s(*it);
  99. if (s.sizeHint != Fixed)
  100. s.widget->setSize(biggestWidth, heightPerWidget);
  101. else
  102. s.widget->setWidth(biggestWidth);
  103. }
  104. }
  105. // --------------------------------------------------------------------------------------------------------------------
  106. /* TODO
  107. void HorizontallyStackedVerticalLayout::adjustSize(const uint padding)
  108. {
  109. }
  110. */
  111. void HorizontallyStackedVerticalLayout::setAbsolutePos(int x, const int y, const uint padding)
  112. {
  113. for (VerticalLayoutIterator it=items.begin(), end=items.end(); it != end; ++it)
  114. {
  115. VerticalLayout* l(*it);
  116. x += l->setAbsolutePos(x, y, padding);
  117. x += padding;
  118. }
  119. }
  120. // --------------------------------------------------------------------------------------------------------------------
  121. Size<uint> VerticallyStackedHorizontalLayout::adjustSize(const uint padding)
  122. {
  123. uint biggestWidth = 0;
  124. uint totalHeight = 0;
  125. // iterate all widgets to find which one is the biggest (horizontally)
  126. for (HorizontalLayoutIterator it=items.begin(), end=items.end(); it != end; ++it)
  127. {
  128. HorizontalLayout* const l(*it);
  129. uint width = 0;
  130. uint height = 0;
  131. for (SubWidgetWithSizeHintIterator it=l->widgets.begin(), end=l->widgets.end(); it != end; ++it)
  132. {
  133. SubWidgetWithSizeHint& s(*it);
  134. if (width != 0)
  135. width += padding;
  136. width += s.widget->getWidth();
  137. height = std::max(height, s.widget->getHeight());
  138. }
  139. biggestWidth = std::max(biggestWidth, width);
  140. if (totalHeight != 0)
  141. totalHeight += padding;
  142. totalHeight += height;
  143. }
  144. // now make all horizontal lines the same width
  145. for (HorizontalLayoutIterator it=items.begin(), end=items.end(); it != end; ++it)
  146. {
  147. HorizontalLayout* const l(*it);
  148. l->setSize(biggestWidth, padding);
  149. }
  150. return Size<uint>(biggestWidth, totalHeight);
  151. }
  152. void VerticallyStackedHorizontalLayout::setAbsolutePos(const int x, int y, const uint padding)
  153. {
  154. for (HorizontalLayoutIterator it=items.begin(), end=items.end(); it != end; ++it)
  155. {
  156. HorizontalLayout* l(*it);
  157. y += l->setAbsolutePos(x, y, padding);
  158. y += padding;
  159. }
  160. }
  161. // --------------------------------------------------------------------------------------------------------------------
  162. END_NAMESPACE_DGL