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.

278 lines
9.5KB

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