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.

123 lines
3.2KB

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