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.

149 lines
4.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-10 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 __JUCER_TICKITERATOR_H_8D744D8A__
  19. #define __JUCER_TICKITERATOR_H_8D744D8A__
  20. //==============================================================================
  21. class TickIterator
  22. {
  23. public:
  24. TickIterator (const double startValue_, const double endValue_, const double valuePerPixel_,
  25. int minPixelsPerTick, int minWidthForLabels)
  26. : startValue (startValue_),
  27. endValue (endValue_),
  28. valuePerPixel (valuePerPixel_)
  29. {
  30. tickLevelIndex = findLevelIndexForValue (valuePerPixel * minPixelsPerTick);
  31. labelLevelIndex = findLevelIndexForValue (valuePerPixel * minWidthForLabels);
  32. tickPosition = pixelsToValue (-minWidthForLabels);
  33. tickPosition = snapValueDown (tickPosition, tickLevelIndex);
  34. }
  35. bool getNextTick (float& pixelX, float& tickLength, String& label)
  36. {
  37. const double tickUnits = getTickSizes() [tickLevelIndex];
  38. tickPosition += tickUnits;
  39. const int totalLevels = getNumTickSizes();
  40. int highestIndex = tickLevelIndex;
  41. while (++highestIndex < totalLevels)
  42. {
  43. const double ticksAtThisLevel = tickPosition / getTickSizes() [highestIndex];
  44. if (fabs (ticksAtThisLevel - floor (ticksAtThisLevel + 0.5)) > 0.000001)
  45. break;
  46. }
  47. --highestIndex;
  48. if (highestIndex >= labelLevelIndex)
  49. label = getDescriptionOfValue (tickPosition, labelLevelIndex);
  50. else
  51. label = String::empty;
  52. tickLength = (highestIndex + 1 - tickLevelIndex) / (float) (totalLevels + 1 - tickLevelIndex);
  53. pixelX = valueToPixels (tickPosition);
  54. return tickPosition < endValue;
  55. }
  56. private:
  57. double tickPosition;
  58. int tickLevelIndex, labelLevelIndex;
  59. const double startValue, endValue, valuePerPixel;
  60. static int getNumTickSizes()
  61. {
  62. return 10;
  63. }
  64. static const double* getTickSizes()
  65. {
  66. static const double tickSizes[] = { 1.0, 2.0, 5.0,
  67. 10.0, 20.0, 50.0,
  68. 100.0, 200.0, 500.0, 1000.0 };
  69. return tickSizes;
  70. }
  71. int findLevelIndexForValue (const double value) const
  72. {
  73. int i;
  74. for (i = 0; i < getNumTickSizes(); ++i)
  75. if (getTickSizes() [i] >= value)
  76. break;
  77. return i;
  78. }
  79. double pixelsToValue (int pixels) const
  80. {
  81. return startValue + pixels * valuePerPixel;
  82. }
  83. float valueToPixels (double value) const
  84. {
  85. return (float) ((value - startValue) / valuePerPixel);
  86. }
  87. static double snapValueToNearest (const double t, const int valueLevelIndex)
  88. {
  89. const double unitsPerInterval = getTickSizes() [valueLevelIndex];
  90. return unitsPerInterval * floor (t / unitsPerInterval + 0.5);
  91. }
  92. static double snapValueDown (const double t, const int valueLevelIndex)
  93. {
  94. const double unitsPerInterval = getTickSizes() [valueLevelIndex];
  95. return unitsPerInterval * floor (t / unitsPerInterval);
  96. }
  97. static inline int roundDoubleToInt (const double value)
  98. {
  99. union { int asInt[2]; double asDouble; } n;
  100. n.asDouble = value + 6755399441055744.0;
  101. #if TARGET_RT_BIG_ENDIAN
  102. return n.asInt [1];
  103. #else
  104. return n.asInt [0];
  105. #endif
  106. }
  107. static const String getDescriptionOfValue (const double value, const int valueLevelIndex)
  108. {
  109. return String (roundToInt (value));
  110. }
  111. TickIterator (const TickIterator&);
  112. TickIterator& operator= (const TickIterator&);
  113. };
  114. #endif // __JUCER_TICKITERATOR_H_8D744D8A__