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.

121 lines
3.3KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #pragma once
  20. #include "../JuceLibraryCode/JuceHeader.h"
  21. // A very simple decaying meter.
  22. class SimpleMeter : public Component,
  23. private Timer
  24. {
  25. public:
  26. SimpleMeter()
  27. {
  28. startTimerHz (30);
  29. }
  30. //==============================================================================
  31. void paint (Graphics& g) override
  32. {
  33. g.fillAll (Colours::transparentBlack);
  34. auto area = g.getClipBounds();
  35. g.setColour (getLookAndFeel().findColour (Slider::thumbColourId));
  36. g.fillRoundedRectangle (area.toFloat(), 6.0);
  37. auto unfilledHeight = area.getHeight() * (1.0 - level);
  38. g.reduceClipRegion (area.getX(), area.getY(),
  39. area.getWidth(), (int) unfilledHeight);
  40. g.setColour (getLookAndFeel().findColour (Slider::trackColourId));
  41. g.fillRoundedRectangle (area.toFloat(), 6.0);
  42. }
  43. void resized() override {}
  44. //==============================================================================
  45. // Called from the audio thread.
  46. void update (float newLevel)
  47. {
  48. // We don't care if maxLevel gets set to zero (in timerCallback) between the
  49. // load and the assignment.
  50. maxLevel = jmax (maxLevel.load(), newLevel);
  51. }
  52. private:
  53. //==============================================================================
  54. void timerCallback() override
  55. {
  56. auto callbackLevel = maxLevel.exchange (0.0);
  57. auto decayFactor = 0.95;
  58. if (callbackLevel > level)
  59. level = callbackLevel;
  60. else if (level > 0.001)
  61. level *= decayFactor;
  62. else
  63. level = 0;
  64. repaint();
  65. }
  66. std::atomic<float> maxLevel {0.0};
  67. float level = 0;
  68. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SimpleMeter)
  69. };
  70. #if JUCE_PROJUCER_LIVE_BUILD
  71. // Animate the meter in the Projucer live build.
  72. struct MockSimpleMeter : public Component,
  73. private Timer
  74. {
  75. MockSimpleMeter()
  76. {
  77. addAndMakeVisible (meter);
  78. resized();
  79. startTimerHz (100);
  80. }
  81. void paint (Graphics&) override {}
  82. void resized() override
  83. {
  84. meter.setBounds (getBounds());
  85. }
  86. void timerCallback() override
  87. {
  88. meter.update (std::pow (randomNumberGenerator.nextFloat(), 2));
  89. }
  90. SimpleMeter meter;
  91. Random randomNumberGenerator;
  92. };
  93. #endif