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.

118 lines
4.1KB

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