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.

137 lines
4.2KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. class BuildStatusTabComp : public Component,
  18. private ChangeListener,
  19. private Timer
  20. {
  21. public:
  22. BuildStatusTabComp (ErrorList& el, ActivityList& al)
  23. : errorList (el), activityList (al)
  24. {
  25. setInterceptsMouseClicks (false, false);
  26. addAndMakeVisible (&spinner);
  27. activityList.addChangeListener (this);
  28. errorList.addChangeListener (this);
  29. }
  30. ~BuildStatusTabComp()
  31. {
  32. activityList.removeChangeListener (this);
  33. errorList.removeChangeListener (this);
  34. }
  35. enum { size = 20 };
  36. void updateStatus()
  37. {
  38. State newState = nothing;
  39. if (activityList.getNumActivities() > 0) newState = busy;
  40. else if (errorList.getNumErrors() > 0) newState = errors;
  41. else if (errorList.getNumWarnings() > 0) newState = warnings;
  42. if (newState != state)
  43. {
  44. state = newState;
  45. setSize (state != nothing ? size : 0, size);
  46. spinner.setVisible (state == busy);
  47. repaint();
  48. }
  49. }
  50. void paint (Graphics& g) override
  51. {
  52. if (state == errors || state == warnings)
  53. {
  54. g.setColour (findColour (mainBackgroundColourId).contrasting (state == errors ? Colours::red
  55. : Colours::yellow, 0.4f));
  56. const Path& icon = (state == errors) ? getIcons().warning
  57. : getIcons().info;
  58. g.fillPath (icon, RectanglePlacement (RectanglePlacement::centred)
  59. .getTransformToFit (icon.getBounds(),
  60. getCentralArea().reduced (1, 1).toFloat()));
  61. }
  62. }
  63. void resized() override
  64. {
  65. spinner.setBounds (getCentralArea());
  66. }
  67. Rectangle<int> getCentralArea() const
  68. {
  69. return getLocalBounds().withTrimmedRight (4);
  70. }
  71. private:
  72. ErrorList& errorList;
  73. ActivityList& activityList;
  74. void changeListenerCallback (ChangeBroadcaster*) override { if (! isTimerRunning()) startTimer (150); }
  75. void timerCallback() override { stopTimer(); updateStatus(); }
  76. enum State
  77. {
  78. nothing,
  79. busy,
  80. errors,
  81. warnings
  82. };
  83. State state;
  84. //==============================================================================
  85. class Spinner : public Component,
  86. private Timer
  87. {
  88. public:
  89. Spinner()
  90. {
  91. setInterceptsMouseClicks (false, false);
  92. }
  93. void paint (Graphics& g) override
  94. {
  95. if (TabBarButton* tbb = findParentComponentOfClass<TabBarButton>())
  96. {
  97. getLookAndFeel().drawSpinningWaitAnimation (g, ProjucerLookAndFeel::getTabBackgroundColour (*tbb).contrasting(),
  98. 0, 0, getWidth(), getHeight());
  99. startTimer (1000 / 20);
  100. }
  101. }
  102. void timerCallback() override
  103. {
  104. if (isVisible())
  105. repaint();
  106. else
  107. stopTimer();
  108. }
  109. };
  110. Spinner spinner;
  111. };