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.

282 lines
9.6KB

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