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.

289 lines
9.8KB

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