The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

128 lines
4.2KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. BEGIN_JUCE_NAMESPACE
  19. //==============================================================================
  20. StretchableObjectResizer::StretchableObjectResizer()
  21. {
  22. }
  23. StretchableObjectResizer::~StretchableObjectResizer()
  24. {
  25. }
  26. void StretchableObjectResizer::addItem (const double size,
  27. const double minSize, const double maxSize,
  28. const int order)
  29. {
  30. // the order must be >= 0 but less than the maximum integer value.
  31. jassert (order >= 0 && order < std::numeric_limits<int>::max());
  32. Item* const item = new Item();
  33. item->size = size;
  34. item->minSize = minSize;
  35. item->maxSize = maxSize;
  36. item->order = order;
  37. items.add (item);
  38. }
  39. double StretchableObjectResizer::getItemSize (const int index) const noexcept
  40. {
  41. const Item* const it = items [index];
  42. return it != nullptr ? it->size : 0;
  43. }
  44. void StretchableObjectResizer::resizeToFit (const double targetSize)
  45. {
  46. int order = 0;
  47. for (;;)
  48. {
  49. double currentSize = 0;
  50. double minSize = 0;
  51. double maxSize = 0;
  52. int nextHighestOrder = std::numeric_limits<int>::max();
  53. for (int i = 0; i < items.size(); ++i)
  54. {
  55. const Item* const it = items.getUnchecked(i);
  56. currentSize += it->size;
  57. if (it->order <= order)
  58. {
  59. minSize += it->minSize;
  60. maxSize += it->maxSize;
  61. }
  62. else
  63. {
  64. minSize += it->size;
  65. maxSize += it->size;
  66. nextHighestOrder = jmin (nextHighestOrder, it->order);
  67. }
  68. }
  69. const double thisIterationTarget = jlimit (minSize, maxSize, targetSize);
  70. if (thisIterationTarget >= currentSize)
  71. {
  72. const double availableExtraSpace = maxSize - currentSize;
  73. const double targetAmountOfExtraSpace = thisIterationTarget - currentSize;
  74. const double scale = targetAmountOfExtraSpace / availableExtraSpace;
  75. for (int i = 0; i < items.size(); ++i)
  76. {
  77. Item* const it = items.getUnchecked(i);
  78. if (it->order <= order)
  79. it->size = jmin (it->maxSize, it->size + (it->maxSize - it->size) * scale);
  80. }
  81. }
  82. else
  83. {
  84. const double amountOfSlack = currentSize - minSize;
  85. const double targetAmountOfSlack = thisIterationTarget - minSize;
  86. const double scale = targetAmountOfSlack / amountOfSlack;
  87. for (int i = 0; i < items.size(); ++i)
  88. {
  89. Item* const it = items.getUnchecked(i);
  90. if (it->order <= order)
  91. it->size = jmax (it->minSize, it->minSize + (it->size - it->minSize) * scale);
  92. }
  93. }
  94. if (nextHighestOrder < std::numeric_limits<int>::max())
  95. order = nextHighestOrder;
  96. else
  97. break;
  98. }
  99. }
  100. END_JUCE_NAMESPACE