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.

174 lines
8.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. #ifndef __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__
  19. #define __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__
  20. #include "../geometry/juce_AffineTransform.h"
  21. #include "../geometry/juce_Rectangle.h"
  22. //==============================================================================
  23. /**
  24. Defines the method used to postion some kind of rectangular object within
  25. a rectangular viewport.
  26. Although similar to Justification, this is more specific, and has some extra
  27. options.
  28. */
  29. class JUCE_API RectanglePlacement
  30. {
  31. public:
  32. //==============================================================================
  33. /** Creates a RectanglePlacement object using a combination of flags. */
  34. inline RectanglePlacement (int flags_) noexcept : flags (flags_) {}
  35. /** Creates a copy of another RectanglePlacement object. */
  36. RectanglePlacement (const RectanglePlacement& other) noexcept;
  37. /** Copies another RectanglePlacement object. */
  38. RectanglePlacement& operator= (const RectanglePlacement& other) noexcept;
  39. bool operator== (const RectanglePlacement& other) const noexcept;
  40. bool operator!= (const RectanglePlacement& other) const noexcept;
  41. //==============================================================================
  42. /** Flag values that can be combined and used in the constructor. */
  43. enum
  44. {
  45. //==============================================================================
  46. /** Indicates that the source rectangle's left edge should be aligned with the left edge of the target rectangle. */
  47. xLeft = 1,
  48. /** Indicates that the source rectangle's right edge should be aligned with the right edge of the target rectangle. */
  49. xRight = 2,
  50. /** Indicates that the source should be placed in the centre between the left and right
  51. sides of the available space. */
  52. xMid = 4,
  53. //==============================================================================
  54. /** Indicates that the source's top edge should be aligned with the top edge of the
  55. destination rectangle. */
  56. yTop = 8,
  57. /** Indicates that the source's bottom edge should be aligned with the bottom edge of the
  58. destination rectangle. */
  59. yBottom = 16,
  60. /** Indicates that the source should be placed in the centre between the top and bottom
  61. sides of the available space. */
  62. yMid = 32,
  63. //==============================================================================
  64. /** If this flag is set, then the source rectangle will be resized to completely fill
  65. the destination rectangle, and all other flags are ignored.
  66. */
  67. stretchToFit = 64,
  68. //==============================================================================
  69. /** If this flag is set, then the source rectangle will be resized so that it is the
  70. minimum size to completely fill the destination rectangle, without changing its
  71. aspect ratio. This means that some of the source rectangle may fall outside
  72. the destination.
  73. If this flag is not set, the source will be given the maximum size at which none
  74. of it falls outside the destination rectangle.
  75. */
  76. fillDestination = 128,
  77. /** Indicates that the source rectangle can be reduced in size if required, but should
  78. never be made larger than its original size.
  79. */
  80. onlyReduceInSize = 256,
  81. /** Indicates that the source rectangle can be enlarged if required, but should
  82. never be made smaller than its original size.
  83. */
  84. onlyIncreaseInSize = 512,
  85. /** Indicates that the source rectangle's size should be left unchanged.
  86. */
  87. doNotResize = (onlyIncreaseInSize | onlyReduceInSize),
  88. //==============================================================================
  89. /** A shorthand value that is equivalent to (xMid | yMid). */
  90. centred = 4 + 32
  91. };
  92. //==============================================================================
  93. /** Returns the raw flags that are set for this object. */
  94. inline int getFlags() const noexcept { return flags; }
  95. /** Tests a set of flags for this object.
  96. @returns true if any of the flags passed in are set on this object.
  97. */
  98. inline bool testFlags (int flagsToTest) const noexcept { return (flags & flagsToTest) != 0; }
  99. //==============================================================================
  100. /** Adjusts the position and size of a rectangle to fit it into a space.
  101. The source rectangle co-ordinates will be adjusted so that they fit into
  102. the destination rectangle based on this object's flags.
  103. */
  104. void applyTo (double& sourceX,
  105. double& sourceY,
  106. double& sourceW,
  107. double& sourceH,
  108. double destinationX,
  109. double destinationY,
  110. double destinationW,
  111. double destinationH) const noexcept;
  112. /** Returns the transform that should be applied to these source co-ordinates to fit them
  113. into the destination rectangle using the current flags.
  114. */
  115. template <typename ValueType>
  116. const Rectangle<ValueType> appliedTo (const Rectangle<ValueType>& source,
  117. const Rectangle<ValueType>& destination) const noexcept
  118. {
  119. double x = source.getX(), y = source.getY(), w = source.getWidth(), h = source.getHeight();
  120. applyTo (x, y, w, h, static_cast <double> (destination.getX()), static_cast <double> (destination.getY()),
  121. static_cast <double> (destination.getWidth()), static_cast <double> (destination.getHeight()));
  122. return Rectangle<ValueType> (static_cast <ValueType> (x), static_cast <ValueType> (y),
  123. static_cast <ValueType> (w), static_cast <ValueType> (h));
  124. }
  125. /** Returns the transform that should be applied to these source co-ordinates to fit them
  126. into the destination rectangle using the current flags.
  127. */
  128. const AffineTransform getTransformToFit (const Rectangle<float>& source,
  129. const Rectangle<float>& destination) const noexcept;
  130. private:
  131. //==============================================================================
  132. int flags;
  133. };
  134. #endif // __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__