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.

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