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.

122 lines
4.0KB

  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. StretchableObjectResizer::StretchableObjectResizer()
  19. {
  20. }
  21. StretchableObjectResizer::~StretchableObjectResizer()
  22. {
  23. }
  24. void StretchableObjectResizer::addItem (const double size,
  25. const double minSize, const double maxSize,
  26. const int order)
  27. {
  28. // the order must be >= 0 but less than the maximum integer value.
  29. jassert (order >= 0 && order < std::numeric_limits<int>::max());
  30. Item* const item = new Item();
  31. item->size = size;
  32. item->minSize = minSize;
  33. item->maxSize = maxSize;
  34. item->order = order;
  35. items.add (item);
  36. }
  37. double StretchableObjectResizer::getItemSize (const int index) const noexcept
  38. {
  39. const Item* const it = items [index];
  40. return it != nullptr ? it->size : 0;
  41. }
  42. void StretchableObjectResizer::resizeToFit (const double targetSize)
  43. {
  44. int order = 0;
  45. for (;;)
  46. {
  47. double currentSize = 0;
  48. double minSize = 0;
  49. double maxSize = 0;
  50. int nextHighestOrder = std::numeric_limits<int>::max();
  51. for (int i = 0; i < items.size(); ++i)
  52. {
  53. const Item* const it = items.getUnchecked(i);
  54. currentSize += it->size;
  55. if (it->order <= order)
  56. {
  57. minSize += it->minSize;
  58. maxSize += it->maxSize;
  59. }
  60. else
  61. {
  62. minSize += it->size;
  63. maxSize += it->size;
  64. nextHighestOrder = jmin (nextHighestOrder, it->order);
  65. }
  66. }
  67. const double thisIterationTarget = jlimit (minSize, maxSize, targetSize);
  68. if (thisIterationTarget >= currentSize)
  69. {
  70. const double availableExtraSpace = maxSize - currentSize;
  71. const double targetAmountOfExtraSpace = thisIterationTarget - currentSize;
  72. const double scale = targetAmountOfExtraSpace / availableExtraSpace;
  73. for (int i = 0; i < items.size(); ++i)
  74. {
  75. Item* const it = items.getUnchecked(i);
  76. if (it->order <= order)
  77. it->size = jmin (it->maxSize, it->size + (it->maxSize - it->size) * scale);
  78. }
  79. }
  80. else
  81. {
  82. const double amountOfSlack = currentSize - minSize;
  83. const double targetAmountOfSlack = thisIterationTarget - minSize;
  84. const double scale = targetAmountOfSlack / amountOfSlack;
  85. for (int i = 0; i < items.size(); ++i)
  86. {
  87. Item* const it = items.getUnchecked(i);
  88. if (it->order <= order)
  89. it->size = jmax (it->minSize, it->minSize + (it->size - it->minSize) * scale);
  90. }
  91. }
  92. if (nextHighestOrder < std::numeric_limits<int>::max())
  93. order = nextHighestOrder;
  94. else
  95. break;
  96. }
  97. }