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.

135 lines
4.0KB

  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 (state == errors ? Colours::red : Colours::yellow);
  55. const Path& icon = (state == errors) ? getIcons().warning
  56. : getIcons().info;
  57. g.fillPath (icon, RectanglePlacement (RectanglePlacement::centred)
  58. .getTransformToFit (icon.getBounds(),
  59. getCentralArea().reduced (1, 1).toFloat()));
  60. }
  61. }
  62. void resized() override
  63. {
  64. spinner.setBounds (getCentralArea());
  65. }
  66. Rectangle<int> getCentralArea() const
  67. {
  68. return getLocalBounds().withTrimmedRight (4);
  69. }
  70. private:
  71. ErrorList& errorList;
  72. ActivityList& activityList;
  73. void changeListenerCallback (ChangeBroadcaster*) override { if (! isTimerRunning()) startTimer (150); }
  74. void timerCallback() override { stopTimer(); updateStatus(); }
  75. enum State
  76. {
  77. nothing,
  78. busy,
  79. errors,
  80. warnings
  81. };
  82. State state;
  83. //==============================================================================
  84. struct Spinner : public Component,
  85. private Timer
  86. {
  87. Spinner()
  88. {
  89. setInterceptsMouseClicks (false, false);
  90. }
  91. void paint (Graphics& g) override
  92. {
  93. if (findParentComponentOfClass<TabBarButton>() != nullptr)
  94. {
  95. getLookAndFeel().drawSpinningWaitAnimation (g, findColour (treeIconColourId),
  96. 0, 0, getWidth(), getHeight());
  97. startTimer (1000 / 20);
  98. }
  99. }
  100. void timerCallback() override
  101. {
  102. if (isVisible())
  103. repaint();
  104. else
  105. stopTimer();
  106. }
  107. };
  108. Spinner spinner;
  109. };