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.

131 lines
3.4KB

  1. #pragma once
  2. #include "ui/common.hpp"
  3. #include "math.hpp"
  4. #include "string.hpp"
  5. namespace rack {
  6. /** A controller for manipulating a float value (which subclasses must store somehow) with limits and labels
  7. Often used as a decorator component for Widgets that read or write a quantity.
  8. */
  9. struct Quantity {
  10. virtual ~Quantity() {}
  11. /** Sets the value directly
  12. Override this to change the state of your subclass to represent the new value.
  13. */
  14. virtual void setValue(float value) {}
  15. /** Returns the value
  16. Override this to return the state of your subclass.
  17. */
  18. virtual float getValue() {return 0.f;}
  19. /** Returns the minimum allowed value */
  20. virtual float getMinValue() {return 0.f;}
  21. /** Returns the maximum allowed value */
  22. virtual float getMaxValue() {return 1.f;}
  23. /** Returns the default value, for resetting */
  24. virtual float getDefaultValue() {return 0.f;}
  25. /** Returns the value, possibly transformed for displaying
  26. Useful for logarithmic scaling, multiplying by 100 for percentages, etc.
  27. */
  28. virtual float getDisplayValue() {return getValue();}
  29. /** Inversely transforms the display value and sets the value */
  30. virtual void setDisplayValue(float displayValue) {setValue(displayValue);}
  31. /** The number of decimal places for displaying
  32. A precision of 2 will display as "1.00" for example.
  33. */
  34. virtual int getDisplayPrecision() {return 2;}
  35. /** Returns a string representation of the display value */
  36. virtual std::string getDisplayValueString() {
  37. return string::f("%.*f", getDisplayPrecision(), getDisplayValue());
  38. }
  39. /** The name of the quantity */
  40. virtual std::string getLabel() {return "";}
  41. /** The unit abbreviation of the quantity
  42. Include an initial space character if you want a space after the number, e.g. "440 Hz". This allows space-less units, like "100%".
  43. */
  44. virtual std::string getUnit() {return "";}
  45. /** Returns a string representation of the quantity */
  46. virtual std::string getString() {
  47. std::string s;
  48. std::string label = getLabel();
  49. if (!label.empty())
  50. s += label + ": ";
  51. s += getDisplayValueString() + getUnit();
  52. return s;
  53. }
  54. // Helper methods
  55. /** Resets the value to the default value */
  56. void reset() {
  57. setValue(getDefaultValue());
  58. }
  59. /** Checks whether the value is at the min value */
  60. bool isMin() {
  61. return getValue() <= getMinValue();
  62. }
  63. /** Checks whether the value is at the max value */
  64. bool isMax() {
  65. return getValue() >= getMaxValue();
  66. }
  67. /** Sets the value to the min value */
  68. void setMin() {
  69. setValue(getMinValue());
  70. }
  71. /** Sets the value to the max value */
  72. void setMax() {
  73. setValue(getMaxValue());
  74. }
  75. /** Sets value from the range 0 to 1 */
  76. void setScaledValue(float scaledValue) {
  77. setValue(math::rescale(scaledValue, 0.f, 1.f, getMinValue(), getMaxValue()));
  78. }
  79. /** Returns the value rescaled to the range 0 to 1 */
  80. float getScaledValue() {
  81. return math::rescale(getValue(), getMinValue(), getMaxValue(), 0.f, 1.f);
  82. }
  83. /** The difference between the max and min values */
  84. float getRange() {
  85. return getMaxValue() - getMinValue();
  86. }
  87. /** Checks whether the bounds are finite */
  88. bool isBounded() {
  89. return std::isfinite(getMinValue()) && std::isfinite(getMaxValue());
  90. }
  91. /** Adds an amount to the value */
  92. void moveValue(float deltaValue) {
  93. setValue(getValue() + deltaValue);
  94. }
  95. /** Adds an amount to the value scaled to the range 0 to 1 */
  96. void moveScaledValue(float deltaScaledValue) {
  97. moveValue(deltaScaledValue * getRange());
  98. }
  99. };
  100. } // namespace rack