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.

246 lines
8.6KB

  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 LiveBuildTab : public Component,
  18. private ChangeListener,
  19. private Button::Listener
  20. {
  21. public:
  22. LiveBuildTab (CompileEngineChildProcess* child, String lastErrorMessage)
  23. {
  24. addAndMakeVisible (settingsButton = new IconButton ("Settings", &getIcons().settings));
  25. settingsButton->addListener (this);
  26. if (child != nullptr)
  27. {
  28. addAndMakeVisible (concertinaPanel);
  29. buildConcertina (child);
  30. isEnabled = true;
  31. }
  32. else
  33. {
  34. isEnabled = false;
  35. errorMessage = getErrorMessage();
  36. errorMessageLabel = new Label ("Error", errorMessage);
  37. errorMessageLabel->setJustificationType (Justification::centred);
  38. errorMessageLabel->setFont (Font (12.0f));
  39. errorMessageLabel->setMinimumHorizontalScale (1.0f);
  40. addAndMakeVisible (errorMessageLabel);
  41. if (showDownloadButton)
  42. {
  43. addAndMakeVisible (downloadButton = new TextButton ("Download"));
  44. downloadButton->addListener (this);
  45. }
  46. if (showEnableButton)
  47. {
  48. auto buttonText = "Enable Now";
  49. if (! lastErrorMessage.isEmpty())
  50. {
  51. errorMessageLabel->setText (lastErrorMessage, dontSendNotification);
  52. buttonText = "Re-enable";
  53. }
  54. addAndMakeVisible (enableButton = new TextButton (buttonText));
  55. enableButton->addListener (this);
  56. }
  57. }
  58. }
  59. void paint (Graphics& g) override
  60. {
  61. g.fillAll (findColour (secondaryBackgroundColourId));
  62. }
  63. void resized() override
  64. {
  65. auto bounds = getLocalBounds();
  66. auto bottomSlice = bounds.removeFromBottom (25);
  67. bottomSlice.removeFromRight (5);
  68. settingsButton->setBounds (bottomSlice.removeFromRight (25).reduced (2));
  69. if (errorMessageLabel != nullptr)
  70. {
  71. bounds.removeFromTop ((bounds.getHeight() / 2) - 40);
  72. errorMessageLabel->setBounds (bounds.removeFromTop (80));
  73. if (downloadButton != nullptr)
  74. downloadButton->setBounds (bounds.removeFromTop (20).reduced (20, 0));
  75. if (enableButton != nullptr)
  76. enableButton->setBounds (bounds.removeFromTop (20).reduced (20, 0));
  77. }
  78. else
  79. {
  80. concertinaPanel.setBounds (bounds);
  81. for (auto h : headers)
  82. if (h->getName() == "Activities")
  83. h->yPosition = getHeight() - CurrentActivitiesComp::getMaxPanelHeight() - 55;
  84. }
  85. }
  86. bool isEnabled;
  87. String errorMessage;
  88. Component::SafePointer<ProjucerAppClasses::ErrorListComp> errorListComp;
  89. private:
  90. OwnedArray<ConcertinaHeader> headers;
  91. ConcertinaPanel concertinaPanel;
  92. ScopedPointer<IconButton> settingsButton;
  93. ScopedPointer<TextButton> downloadButton, enableButton;
  94. ScopedPointer<Label> errorMessageLabel;
  95. bool showDownloadButton;
  96. bool showEnableButton;
  97. Rectangle<int> textBounds;
  98. //==========================================================================
  99. String getErrorMessage()
  100. {
  101. showDownloadButton = false;
  102. showEnableButton = false;
  103. const auto osType = SystemStats::getOperatingSystemType();
  104. const bool isMac = (osType & SystemStats::MacOSX) != 0;
  105. const bool isWin = (osType & SystemStats::Windows) != 0;
  106. const bool isLinux = (osType & SystemStats::Linux) != 0;
  107. if (! isMac && ! isWin && ! isLinux)
  108. return String ("Live-build features are not supported on your system.\n\n"
  109. "Please check supported platforms at www.juce.com!");
  110. if (isLinux)
  111. return String ("Live-build features for Linux are under development.\n\n"
  112. "Please check for updates at www.juce.com!");
  113. if (isMac)
  114. if (osType < SystemStats::MacOSX_10_9)
  115. return String ("Live-build features are available only on MacOSX 10.9 or higher.");
  116. if (isWin)
  117. if (! SystemStats::isOperatingSystem64Bit() || osType < SystemStats::Windows8_0)
  118. return String ("Live-build features are available only on 64-Bit Windows 8 or higher.");
  119. const auto& compileEngineDll = *CompileEngineDLL::getInstance();
  120. const auto dllPresent = compileEngineDll.isLoaded();
  121. if (! dllPresent)
  122. {
  123. showDownloadButton = true;
  124. return String ("Download the live-build engine to get started");
  125. }
  126. showEnableButton = true;
  127. return String ("Enable compilation to use the live-build engine");
  128. }
  129. void buttonClicked (Button* b) override
  130. {
  131. auto* pcc = findParentComponentOfClass<ProjectContentComponent>();
  132. if (b == settingsButton)
  133. {
  134. if (pcc != nullptr)
  135. pcc->showLiveBuildSettings();
  136. }
  137. else if (b == downloadButton)
  138. {
  139. if (DownloadCompileEngineThread::downloadAndInstall())
  140. {
  141. if (! CompileEngineDLL::getInstance()->tryLoadDll())
  142. {
  143. AlertWindow::showMessageBox(AlertWindow::WarningIcon,
  144. "Download and install",
  145. "Loading the live-build engine failed");
  146. return;
  147. }
  148. if (pcc != nullptr)
  149. pcc->rebuildProjectTabs();
  150. }
  151. }
  152. else if (b == enableButton)
  153. {
  154. if (pcc != nullptr)
  155. pcc->setBuildEnabled (true);
  156. }
  157. }
  158. void buildConcertina (CompileEngineChildProcess* child)
  159. {
  160. for (int i = concertinaPanel.getNumPanels() - 1; i >= 0 ; --i)
  161. concertinaPanel.removePanel (concertinaPanel.getPanel (i));
  162. headers.clear();
  163. errorListComp = new ProjucerAppClasses::ErrorListComp (child->errorList);
  164. auto* activities = new CurrentActivitiesComp (child->activityList);
  165. auto* comps = new ComponentListComp (*child);
  166. concertinaPanel.addPanel (-1, errorListComp, true);
  167. concertinaPanel.addPanel (-1, comps, true);
  168. concertinaPanel.addPanel (-1, activities, true);
  169. headers.add (new ConcertinaHeader ("Errors", getIcons().bug));
  170. headers.add (new ConcertinaHeader ("Components", getIcons().modules));
  171. headers.add (new ConcertinaHeader ("Activities", getIcons().buildTab));
  172. for (int i = 0; i < concertinaPanel.getNumPanels(); ++i)
  173. {
  174. auto* p = concertinaPanel.getPanel (i);
  175. auto* h = headers.getUnchecked (i);
  176. h->addChangeListener (this);
  177. h->yPosition = i * 30;
  178. concertinaPanel.setCustomPanelHeader (p, h, false);
  179. concertinaPanel.setPanelHeaderSize (p, 30);
  180. }
  181. concertinaPanel.setMaximumPanelSize (activities, CurrentActivitiesComp::getMaxPanelHeight());
  182. concertinaPanel.setPanelSize (errorListComp, 200, false);
  183. concertinaPanel.setPanelSize (comps, 300, false);
  184. }
  185. void changeListenerCallback (ChangeBroadcaster* source) override
  186. {
  187. if (auto* header = dynamic_cast<ConcertinaHeader*> (source))
  188. {
  189. auto index = headers.indexOf (header);
  190. concertinaPanel.expandPanelFully (concertinaPanel.getPanel (index), true);
  191. }
  192. }
  193. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LiveBuildTab)
  194. };