mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-02-06 04:00:08 +00:00
Projucer: Removed the live build
This commit is contained in:
parent
64896eefcd
commit
bfdda737a2
74 changed files with 673 additions and 7583 deletions
|
|
@ -1,277 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
struct LiveBuildSettingsComponent : public Component
|
||||
{
|
||||
LiveBuildSettingsComponent (Project& p)
|
||||
{
|
||||
addAndMakeVisible (&group);
|
||||
|
||||
PropertyListBuilder props;
|
||||
p.getCompileEngineSettings().getLiveSettings (props);
|
||||
|
||||
group.setProperties (props);
|
||||
group.setName ("Live Build Settings");
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
group.updateSize (12, 0, getWidth() - 24);
|
||||
group.setBounds (getLocalBounds().reduced (12, 0));
|
||||
}
|
||||
|
||||
void parentSizeChanged() override
|
||||
{
|
||||
auto width = jmax (550, getParentWidth());
|
||||
auto y = group.updateSize (12, 0, width - 12);
|
||||
|
||||
y = jmax (getParentHeight(), y);
|
||||
|
||||
setSize (width, y);
|
||||
}
|
||||
|
||||
PropertyGroupComponent group { "Live Build Settings", Icon (getIcons().settings, Colours::transparentBlack) };
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LiveBuildSettingsComponent)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class LiveBuildTab : public Component,
|
||||
private ChangeListener
|
||||
{
|
||||
public:
|
||||
LiveBuildTab (const CompileEngineChildProcess::Ptr& child, String lastErrorMessage)
|
||||
{
|
||||
addAndMakeVisible (settingsButton);
|
||||
settingsButton.onClick = [this]
|
||||
{
|
||||
if (auto* pcc = findParentComponentOfClass<ProjectContentComponent>())
|
||||
pcc->showLiveBuildSettings();
|
||||
};
|
||||
|
||||
if (child != nullptr)
|
||||
{
|
||||
addAndMakeVisible (concertinaPanel);
|
||||
buildConcertina (*child);
|
||||
isEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = getErrorMessage();
|
||||
errorMessageLabel.reset (new Label ("Error", errorMessage));
|
||||
errorMessageLabel->setJustificationType (Justification::centred);
|
||||
errorMessageLabel->setFont (Font (12.0f));
|
||||
errorMessageLabel->setMinimumHorizontalScale (1.0f);
|
||||
|
||||
addAndMakeVisible (errorMessageLabel.get());
|
||||
|
||||
if (showDownloadButton)
|
||||
{
|
||||
downloadButton.reset (new TextButton ("Download"));
|
||||
addAndMakeVisible (downloadButton.get());
|
||||
downloadButton->onClick = [this] { downloadDLL(); };
|
||||
}
|
||||
|
||||
if (showEnableButton)
|
||||
{
|
||||
String buttonText ("Enable Now");
|
||||
|
||||
if (! lastErrorMessage.isEmpty())
|
||||
{
|
||||
errorMessageLabel->setText (lastErrorMessage, dontSendNotification);
|
||||
buttonText = "Re-enable";
|
||||
}
|
||||
|
||||
enableButton.reset (new TextButton (buttonText));
|
||||
addAndMakeVisible (enableButton.get());
|
||||
enableButton->onClick = [this]
|
||||
{
|
||||
if (auto* pcc = findParentComponentOfClass<ProjectContentComponent>())
|
||||
pcc->setBuildEnabled (true);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (secondaryBackgroundColourId));
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto bounds = getLocalBounds();
|
||||
|
||||
settingsButton.setBounds (bounds.removeFromBottom (25)
|
||||
.removeFromRight (25)
|
||||
.reduced (3));
|
||||
|
||||
if (errorMessageLabel != nullptr)
|
||||
{
|
||||
bounds.removeFromTop ((bounds.getHeight() / 2) - 40);
|
||||
|
||||
errorMessageLabel->setBounds (bounds.removeFromTop (80));
|
||||
|
||||
if (downloadButton != nullptr)
|
||||
downloadButton->setBounds (bounds.removeFromTop (20).reduced (20, 0));
|
||||
|
||||
if (enableButton != nullptr)
|
||||
enableButton->setBounds (bounds.removeFromTop (20).reduced (20, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
concertinaPanel.setBounds (bounds);
|
||||
|
||||
for (auto h : headers)
|
||||
if (h->getName() == "Activities")
|
||||
h->yPosition = getHeight() - CurrentActivitiesComp::getMaxPanelHeight() - 55;
|
||||
}
|
||||
}
|
||||
|
||||
bool isEnabled = false;
|
||||
String errorMessage;
|
||||
Component::SafePointer<ProjucerAppClasses::ErrorListComp> errorListComp;
|
||||
|
||||
private:
|
||||
OwnedArray<ConcertinaHeader> headers;
|
||||
ConcertinaPanel concertinaPanel;
|
||||
IconButton settingsButton { "Settings", getIcons().settings };
|
||||
|
||||
std::unique_ptr<TextButton> downloadButton, enableButton;
|
||||
std::unique_ptr<Label> errorMessageLabel;
|
||||
bool showDownloadButton;
|
||||
bool showEnableButton;
|
||||
|
||||
Rectangle<int> textBounds;
|
||||
|
||||
//==============================================================================
|
||||
String getErrorMessage()
|
||||
{
|
||||
showDownloadButton = false;
|
||||
showEnableButton = false;
|
||||
|
||||
auto osType = SystemStats::getOperatingSystemType();
|
||||
|
||||
auto isMac = (osType & SystemStats::MacOSX) != 0;
|
||||
auto isWin = (osType & SystemStats::Windows) != 0;
|
||||
auto isLinux = (osType & SystemStats::Linux) != 0;
|
||||
|
||||
if (! isMac && ! isWin && ! isLinux)
|
||||
return "Live-build features are not supported on your system.\n\n"
|
||||
"Please check supported platforms at www.juce.com!";
|
||||
|
||||
if (isLinux)
|
||||
return "Live-build features for Linux are under development.\n\n"
|
||||
"Please check for updates at www.juce.com!";
|
||||
|
||||
if (isMac)
|
||||
if (osType < SystemStats::MacOSX_10_9)
|
||||
return "Live-build features are available only on macOS 10.9 or higher.";
|
||||
|
||||
if (isWin)
|
||||
if (! SystemStats::isOperatingSystem64Bit() || osType < SystemStats::Windows8_0)
|
||||
return "Live-build features are available only on 64-Bit Windows 8 or higher.";
|
||||
|
||||
auto& compileEngineDll = *CompileEngineDLL::getInstance();
|
||||
auto dllPresent = compileEngineDll.isLoaded();
|
||||
|
||||
if (! dllPresent)
|
||||
{
|
||||
showDownloadButton = true;
|
||||
return "Download the live-build engine to get started";
|
||||
}
|
||||
|
||||
showEnableButton = true;
|
||||
return "Enable compilation to use the live-build engine";
|
||||
}
|
||||
|
||||
void downloadDLL()
|
||||
{
|
||||
if (DownloadCompileEngineThread::downloadAndInstall())
|
||||
{
|
||||
if (! CompileEngineDLL::getInstance()->tryLoadDll())
|
||||
{
|
||||
AlertWindow::showMessageBox(AlertWindow::WarningIcon,
|
||||
"Download and install",
|
||||
"Loading the live-build engine failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto* pcc = findParentComponentOfClass<ProjectContentComponent>())
|
||||
pcc->rebuildProjectUI();
|
||||
}
|
||||
}
|
||||
|
||||
void buildConcertina (CompileEngineChildProcess& child)
|
||||
{
|
||||
for (auto i = concertinaPanel.getNumPanels() - 1; i >= 0 ; --i)
|
||||
concertinaPanel.removePanel (concertinaPanel.getPanel (i));
|
||||
|
||||
headers.clear();
|
||||
|
||||
errorListComp = new ProjucerAppClasses::ErrorListComp (child.errorList);
|
||||
auto* activities = new CurrentActivitiesComp (child.activityList);
|
||||
auto* comps = new ComponentListComp (child);
|
||||
|
||||
concertinaPanel.addPanel (-1, errorListComp, true);
|
||||
concertinaPanel.addPanel (-1, comps, true);
|
||||
concertinaPanel.addPanel (-1, activities, true);
|
||||
|
||||
headers.add (new ConcertinaHeader ("Errors", getIcons().bug));
|
||||
headers.add (new ConcertinaHeader ("Components", getIcons().modules));
|
||||
headers.add (new ConcertinaHeader ("Activities", getIcons().buildTab));
|
||||
|
||||
for (int i = 0; i < concertinaPanel.getNumPanels(); ++i)
|
||||
{
|
||||
auto* p = concertinaPanel.getPanel (i);
|
||||
auto* h = headers.getUnchecked (i);
|
||||
|
||||
h->addChangeListener (this);
|
||||
h->yPosition = i * 30;
|
||||
|
||||
concertinaPanel.setCustomPanelHeader (p, h, false);
|
||||
concertinaPanel.setPanelHeaderSize (p, 30);
|
||||
}
|
||||
|
||||
concertinaPanel.setMaximumPanelSize (activities, CurrentActivitiesComp::getMaxPanelHeight());
|
||||
concertinaPanel.setPanelSize (errorListComp, 200, false);
|
||||
concertinaPanel.setPanelSize (comps, 300, false);
|
||||
}
|
||||
|
||||
void changeListenerCallback (ChangeBroadcaster* source) override
|
||||
{
|
||||
if (auto* header = dynamic_cast<ConcertinaHeader*> (source))
|
||||
{
|
||||
auto index = headers.indexOf (header);
|
||||
concertinaPanel.expandPanelFully (concertinaPanel.getPanel (index), true);
|
||||
}
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LiveBuildTab)
|
||||
};
|
||||
|
|
@ -1,307 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
struct ProjectSettingsComponent : public Component,
|
||||
private ChangeListener
|
||||
{
|
||||
ProjectSettingsComponent (Project& p)
|
||||
: project (p),
|
||||
group (project.getProjectFilenameRootString(),
|
||||
Icon (getIcons().settings, Colours::transparentBlack))
|
||||
{
|
||||
setTitle ("Project Settings");
|
||||
setFocusContainerType (FocusContainerType::focusContainer);
|
||||
|
||||
addAndMakeVisible (group);
|
||||
|
||||
updatePropertyList();
|
||||
project.addChangeListener (this);
|
||||
}
|
||||
|
||||
~ProjectSettingsComponent() override
|
||||
{
|
||||
project.removeChangeListener (this);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
group.updateSize (12, 0, getWidth() - 24);
|
||||
group.setBounds (getLocalBounds().reduced (12, 0));
|
||||
}
|
||||
|
||||
void updatePropertyList()
|
||||
{
|
||||
PropertyListBuilder props;
|
||||
project.createPropertyEditors (props);
|
||||
group.setProperties (props);
|
||||
group.setName ("Project Settings");
|
||||
|
||||
lastProjectType = project.getProjectTypeString();
|
||||
parentSizeChanged();
|
||||
}
|
||||
|
||||
void changeListenerCallback (ChangeBroadcaster*) override
|
||||
{
|
||||
if (lastProjectType != project.getProjectTypeString())
|
||||
updatePropertyList();
|
||||
}
|
||||
|
||||
void parentSizeChanged() override
|
||||
{
|
||||
auto width = jmax (550, getParentWidth());
|
||||
auto y = group.updateSize (12, 0, width - 12);
|
||||
|
||||
y = jmax (getParentHeight(), y);
|
||||
|
||||
setSize (width, y);
|
||||
}
|
||||
|
||||
Project& project;
|
||||
var lastProjectType;
|
||||
PropertyGroupComponent group;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectSettingsComponent)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct FileTreePanel : public TreePanelBase
|
||||
{
|
||||
FileTreePanel (Project& p)
|
||||
: TreePanelBase (&p, "fileTreeState")
|
||||
{
|
||||
tree.setMultiSelectEnabled (true);
|
||||
setRoot (new TreeItemTypes::GroupItem (p.getMainGroup()));
|
||||
tree.setRootItemVisible (false);
|
||||
}
|
||||
|
||||
void updateMissingFileStatuses()
|
||||
{
|
||||
if (auto* p = dynamic_cast<TreeItemTypes::FileTreeItemBase*> (rootItem.get()))
|
||||
p->checkFileStatus();
|
||||
}
|
||||
};
|
||||
|
||||
struct ModuleTreePanel : public TreePanelBase
|
||||
{
|
||||
ModuleTreePanel (Project& p)
|
||||
: TreePanelBase (&p, "moduleTreeState")
|
||||
{
|
||||
tree.setMultiSelectEnabled (false);
|
||||
setRoot (new TreeItemTypes::EnabledModulesItem (p));
|
||||
tree.setRootItemVisible (false);
|
||||
}
|
||||
};
|
||||
|
||||
struct ExportersTreePanel : public TreePanelBase
|
||||
{
|
||||
ExportersTreePanel (Project& p)
|
||||
: TreePanelBase (&p, "exportersTreeState")
|
||||
{
|
||||
tree.setMultiSelectEnabled (false);
|
||||
setRoot (new TreeItemTypes::ExportersTreeRoot (p));
|
||||
tree.setRootItemVisible (false);
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ProjectTab : public Component,
|
||||
private ChangeListener
|
||||
{
|
||||
public:
|
||||
ProjectTab (Project* p)
|
||||
: project (p)
|
||||
{
|
||||
addAndMakeVisible (concertinaPanel);
|
||||
buildConcertina();
|
||||
}
|
||||
|
||||
~ProjectTab() override
|
||||
{
|
||||
getFileTreePanel()->saveOpenness();
|
||||
getModuleTreePanel()->saveOpenness();
|
||||
getExportersTreePanel()->saveOpenness();
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (secondaryBackgroundColourId));
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
concertinaPanel.setBounds (getLocalBounds().withTrimmedBottom (3));
|
||||
}
|
||||
|
||||
TreePanelBase* getTreeWithSelectedItems()
|
||||
{
|
||||
for (auto i = concertinaPanel.getNumPanels() - 1; i >= 0; --i)
|
||||
{
|
||||
if (auto* treeComponent = dynamic_cast<ConcertinaTreeComponent*> (concertinaPanel.getPanel (i)))
|
||||
{
|
||||
if (auto* base = treeComponent->getTree())
|
||||
if (base->tree.getNumSelectedItems() != 0)
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileTreePanel* getFileTreePanel()
|
||||
{
|
||||
if (auto* panel = dynamic_cast<ConcertinaTreeComponent*> (concertinaPanel.getPanel (0)))
|
||||
return dynamic_cast<FileTreePanel*> (panel->getTree());
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ModuleTreePanel* getModuleTreePanel()
|
||||
{
|
||||
if (auto* panel = dynamic_cast<ConcertinaTreeComponent*> (concertinaPanel.getPanel (1)))
|
||||
return dynamic_cast<ModuleTreePanel*> (panel->getTree());
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ExportersTreePanel* getExportersTreePanel()
|
||||
{
|
||||
if (auto* panel = dynamic_cast<ConcertinaTreeComponent*> (concertinaPanel.getPanel (2)))
|
||||
return dynamic_cast<ExportersTreePanel*> (panel->getTree());
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void showPanel (int panelIndex)
|
||||
{
|
||||
jassert (isPositiveAndBelow (panelIndex, concertinaPanel.getNumPanels()));
|
||||
|
||||
concertinaPanel.expandPanelFully (concertinaPanel.getPanel (panelIndex), true);
|
||||
}
|
||||
|
||||
void setPanelHeightProportion (int panelIndex, float prop)
|
||||
{
|
||||
jassert (isPositiveAndBelow (panelIndex, concertinaPanel.getNumPanels()));
|
||||
|
||||
concertinaPanel.setPanelSize (concertinaPanel.getPanel (panelIndex),
|
||||
roundToInt (prop * (float) (concertinaPanel.getHeight() - 90)), false);
|
||||
}
|
||||
|
||||
float getPanelHeightProportion (int panelIndex)
|
||||
{
|
||||
jassert (isPositiveAndBelow (panelIndex, concertinaPanel.getNumPanels()));
|
||||
|
||||
return ((float) (concertinaPanel.getPanel (panelIndex)->getHeight()) / (float) (concertinaPanel.getHeight() - 90));
|
||||
}
|
||||
|
||||
private:
|
||||
ConcertinaPanel concertinaPanel;
|
||||
OwnedArray<ConcertinaHeader> headers;
|
||||
Project* project = nullptr;
|
||||
|
||||
//==============================================================================
|
||||
void changeListenerCallback (ChangeBroadcaster* source) override
|
||||
{
|
||||
if (auto* header = dynamic_cast<ConcertinaHeader*> (source))
|
||||
{
|
||||
auto index = headers.indexOf (header);
|
||||
concertinaPanel.expandPanelFully (concertinaPanel.getPanel (index), true);
|
||||
}
|
||||
}
|
||||
|
||||
void buildConcertina()
|
||||
{
|
||||
for (auto i = concertinaPanel.getNumPanels() - 1; i >= 0 ; --i)
|
||||
concertinaPanel.removePanel (concertinaPanel.getPanel (i));
|
||||
|
||||
headers.clear();
|
||||
|
||||
auto addPanel = [this] (const String& name,
|
||||
TreePanelBase* tree,
|
||||
ConcertinaTreeComponent::AdditionalComponents components,
|
||||
const Path& icon)
|
||||
{
|
||||
if (project != nullptr)
|
||||
concertinaPanel.addPanel (-1, new ConcertinaTreeComponent (name, tree, components), true);
|
||||
|
||||
headers.add (new ConcertinaHeader (name, icon));
|
||||
};
|
||||
|
||||
using AdditionalComponents = ConcertinaTreeComponent::AdditionalComponents;
|
||||
|
||||
addPanel ("File Explorer", new FileTreePanel (*project),
|
||||
AdditionalComponents{}
|
||||
.with (AdditionalComponents::addButton)
|
||||
.with (AdditionalComponents::findPanel),
|
||||
getIcons().fileExplorer);
|
||||
|
||||
addPanel ("Modules", new ModuleTreePanel (*project),
|
||||
AdditionalComponents{}
|
||||
.with (AdditionalComponents::addButton)
|
||||
.with (AdditionalComponents::settingsButton),
|
||||
getIcons().modules);
|
||||
|
||||
addPanel ("Exporters", new ExportersTreePanel (*project),
|
||||
AdditionalComponents{}.with (AdditionalComponents::addButton),
|
||||
getIcons().exporter);
|
||||
|
||||
for (int i = 0; i < concertinaPanel.getNumPanels(); ++i)
|
||||
{
|
||||
auto* p = concertinaPanel.getPanel (i);
|
||||
auto* h = headers.getUnchecked (i);
|
||||
p->addMouseListener (this, true);
|
||||
|
||||
h->addChangeListener (this);
|
||||
h->yPosition = i * 30;
|
||||
|
||||
concertinaPanel.setCustomPanelHeader (p, h, false);
|
||||
concertinaPanel.setPanelHeaderSize (p, 30);
|
||||
}
|
||||
}
|
||||
|
||||
void mouseDown (const MouseEvent& e) override
|
||||
{
|
||||
for (auto i = concertinaPanel.getNumPanels() - 1; i >= 0; --i)
|
||||
{
|
||||
auto* p = concertinaPanel.getPanel (i);
|
||||
|
||||
if (! (p->isParentOf (e.eventComponent)))
|
||||
{
|
||||
auto* base = dynamic_cast<TreePanelBase*> (p);
|
||||
|
||||
if (base == nullptr)
|
||||
base = dynamic_cast<ConcertinaTreeComponent*> (p)->getTree();
|
||||
|
||||
if (base != nullptr)
|
||||
base->tree.clearSelectedItems();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectTab)
|
||||
};
|
||||
558
extras/Projucer/Source/Project/UI/Sidebar/jucer_Sidebar.h
Normal file
558
extras/Projucer/Source/Project/UI/Sidebar/jucer_Sidebar.h
Normal file
|
|
@ -0,0 +1,558 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//==============================================================================
|
||||
class ConcertinaHeader : public Component,
|
||||
public ChangeBroadcaster
|
||||
{
|
||||
public:
|
||||
ConcertinaHeader (String n, Path p)
|
||||
: Component (n), name (n), iconPath (p)
|
||||
{
|
||||
setTitle (getName());
|
||||
|
||||
panelIcon = Icon (iconPath, Colours::white);
|
||||
|
||||
nameLabel.setText (name, dontSendNotification);
|
||||
nameLabel.setJustificationType (Justification::centredLeft);
|
||||
nameLabel.setInterceptsMouseClicks (false, false);
|
||||
nameLabel.setAccessible (false);
|
||||
nameLabel.setColour (Label::textColourId, Colours::white);
|
||||
|
||||
addAndMakeVisible (nameLabel);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto b = getLocalBounds().toFloat();
|
||||
|
||||
iconBounds = b.removeFromLeft (b.getHeight()).reduced (7, 7);
|
||||
arrowBounds = b.removeFromRight (b.getHeight());
|
||||
nameLabel.setBounds (b.toNearestInt());
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.setColour (findColour (defaultButtonBackgroundColourId));
|
||||
g.fillRoundedRectangle (getLocalBounds().reduced (2, 3).toFloat(), 2.0f);
|
||||
|
||||
g.setColour (Colours::white);
|
||||
g.fillPath (ProjucerLookAndFeel::getArrowPath (arrowBounds,
|
||||
getParentComponent()->getBoundsInParent().getY() == yPosition ? 2 : 0,
|
||||
true, Justification::centred));
|
||||
|
||||
panelIcon.draw (g, iconBounds.toFloat(), false);
|
||||
}
|
||||
|
||||
void mouseUp (const MouseEvent& e) override
|
||||
{
|
||||
if (! e.mouseWasDraggedSinceMouseDown())
|
||||
sendChangeMessage();
|
||||
}
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override
|
||||
{
|
||||
return std::make_unique<AccessibilityHandler> (*this,
|
||||
AccessibilityRole::button,
|
||||
AccessibilityActions().addAction (AccessibilityActionType::press,
|
||||
[this] { sendChangeMessage(); }));
|
||||
}
|
||||
|
||||
int direction = 0;
|
||||
int yPosition = 0;
|
||||
|
||||
private:
|
||||
String name;
|
||||
Label nameLabel;
|
||||
|
||||
Path iconPath;
|
||||
Icon panelIcon;
|
||||
|
||||
Rectangle<float> arrowBounds, iconBounds;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConcertinaHeader)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class FindPanel : public Component,
|
||||
private Timer,
|
||||
private FocusChangeListener
|
||||
{
|
||||
public:
|
||||
FindPanel (std::function<void (const String&)> cb)
|
||||
: callback (cb)
|
||||
{
|
||||
addAndMakeVisible (editor);
|
||||
editor.onTextChange = [this] { startTimer (250); };
|
||||
editor.onFocusLost = [this]
|
||||
{
|
||||
isFocused = false;
|
||||
repaint();
|
||||
};
|
||||
|
||||
Desktop::getInstance().addFocusChangeListener (this);
|
||||
|
||||
lookAndFeelChanged();
|
||||
}
|
||||
|
||||
~FindPanel() override
|
||||
{
|
||||
Desktop::getInstance().removeFocusChangeListener (this);
|
||||
}
|
||||
|
||||
void paintOverChildren (Graphics& g) override
|
||||
{
|
||||
if (! isFocused)
|
||||
return;
|
||||
|
||||
g.setColour (findColour (defaultHighlightColourId));
|
||||
|
||||
Path p;
|
||||
p.addRoundedRectangle (getLocalBounds().reduced (2), 3.0f);
|
||||
g.strokePath (p, PathStrokeType (2.0f));
|
||||
}
|
||||
|
||||
|
||||
void resized() override
|
||||
{
|
||||
editor.setBounds (getLocalBounds().reduced (2));
|
||||
}
|
||||
|
||||
private:
|
||||
TextEditor editor;
|
||||
bool isFocused = false;
|
||||
std::function<void (const String&)> callback;
|
||||
|
||||
//==============================================================================
|
||||
void lookAndFeelChanged() override
|
||||
{
|
||||
editor.setTextToShowWhenEmpty ("Filter...", findColour (widgetTextColourId).withAlpha (0.3f));
|
||||
}
|
||||
|
||||
void globalFocusChanged (Component* focusedComponent) override
|
||||
{
|
||||
if (focusedComponent == &editor)
|
||||
{
|
||||
isFocused = true;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void timerCallback() override
|
||||
{
|
||||
stopTimer();
|
||||
callback (editor.getText());
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FindPanel)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ConcertinaTreeComponent : public Component
|
||||
{
|
||||
public:
|
||||
class AdditionalComponents
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
addButton = (1 << 0),
|
||||
settingsButton = (1 << 1),
|
||||
findPanel = (1 << 2)
|
||||
};
|
||||
|
||||
AdditionalComponents with (Type t)
|
||||
{
|
||||
auto copy = *this;
|
||||
copy.componentTypes |= t;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool has (Type t) const noexcept
|
||||
{
|
||||
return (componentTypes & t) != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
int componentTypes = 0;
|
||||
};
|
||||
|
||||
ConcertinaTreeComponent (const String& name,
|
||||
TreePanelBase* tree,
|
||||
AdditionalComponents additionalComponents)
|
||||
: Component (name),
|
||||
treeToDisplay (tree)
|
||||
{
|
||||
setTitle (getName());
|
||||
setFocusContainerType (FocusContainerType::focusContainer);
|
||||
|
||||
if (additionalComponents.has (AdditionalComponents::addButton))
|
||||
{
|
||||
addButton = std::make_unique<IconButton> ("Add", getIcons().plus);
|
||||
addAndMakeVisible (addButton.get());
|
||||
addButton->onClick = [this] { showAddMenu(); };
|
||||
}
|
||||
|
||||
if (additionalComponents.has (AdditionalComponents::settingsButton))
|
||||
{
|
||||
settingsButton = std::make_unique<IconButton> ("Settings", getIcons().settings);
|
||||
addAndMakeVisible (settingsButton.get());
|
||||
settingsButton->onClick = [this] { showSettings(); };
|
||||
}
|
||||
|
||||
if (additionalComponents.has (AdditionalComponents::findPanel))
|
||||
{
|
||||
findPanel = std::make_unique<FindPanel> ([this] (const String& filter) { treeToDisplay->rootItem->setSearchFilter (filter); });
|
||||
addAndMakeVisible (findPanel.get());
|
||||
}
|
||||
|
||||
addAndMakeVisible (treeToDisplay.get());
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto bounds = getLocalBounds();
|
||||
|
||||
if (addButton != nullptr || settingsButton != nullptr || findPanel != nullptr)
|
||||
{
|
||||
auto bottomSlice = bounds.removeFromBottom (25);
|
||||
bottomSlice.removeFromRight (3);
|
||||
|
||||
if (addButton != nullptr)
|
||||
addButton->setBounds (bottomSlice.removeFromRight (25).reduced (2));
|
||||
|
||||
if (settingsButton != nullptr)
|
||||
settingsButton->setBounds (bottomSlice.removeFromRight (25).reduced (2));
|
||||
|
||||
if (findPanel != nullptr)
|
||||
findPanel->setBounds (bottomSlice.reduced (2));
|
||||
}
|
||||
|
||||
treeToDisplay->setBounds (bounds);
|
||||
}
|
||||
|
||||
TreePanelBase* getTree() const noexcept { return treeToDisplay.get(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<TreePanelBase> treeToDisplay;
|
||||
std::unique_ptr<IconButton> addButton, settingsButton;
|
||||
std::unique_ptr<FindPanel> findPanel;
|
||||
|
||||
void showAddMenu()
|
||||
{
|
||||
auto numSelected = treeToDisplay->tree.getNumSelectedItems();
|
||||
|
||||
if (numSelected > 1)
|
||||
return;
|
||||
|
||||
if (numSelected == 0)
|
||||
{
|
||||
if (auto* root = dynamic_cast<JucerTreeViewBase*> (treeToDisplay->tree.getRootItem()))
|
||||
root->showPopupMenu (addButton->getScreenBounds().getCentre());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto* item = dynamic_cast<JucerTreeViewBase*> (treeToDisplay->tree.getSelectedItem (0)))
|
||||
item->showAddMenu (addButton->getScreenBounds().getCentre());
|
||||
}
|
||||
}
|
||||
|
||||
void showSettings()
|
||||
{
|
||||
if (auto* root = dynamic_cast<JucerTreeViewBase*> (treeToDisplay->tree.getRootItem()))
|
||||
{
|
||||
treeToDisplay->tree.clearSelectedItems();
|
||||
root->showDocument();
|
||||
}
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConcertinaTreeComponent)
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
struct ProjectSettingsComponent : public Component,
|
||||
private ChangeListener
|
||||
{
|
||||
ProjectSettingsComponent (Project& p)
|
||||
: project (p),
|
||||
group (project.getProjectFilenameRootString(),
|
||||
Icon (getIcons().settings, Colours::transparentBlack))
|
||||
{
|
||||
setTitle ("Project Settings");
|
||||
setFocusContainerType (FocusContainerType::focusContainer);
|
||||
|
||||
addAndMakeVisible (group);
|
||||
|
||||
updatePropertyList();
|
||||
project.addChangeListener (this);
|
||||
}
|
||||
|
||||
~ProjectSettingsComponent() override
|
||||
{
|
||||
project.removeChangeListener (this);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
group.updateSize (12, 0, getWidth() - 24);
|
||||
group.setBounds (getLocalBounds().reduced (12, 0));
|
||||
}
|
||||
|
||||
void updatePropertyList()
|
||||
{
|
||||
PropertyListBuilder props;
|
||||
project.createPropertyEditors (props);
|
||||
group.setProperties (props);
|
||||
group.setName ("Project Settings");
|
||||
|
||||
lastProjectType = project.getProjectTypeString();
|
||||
parentSizeChanged();
|
||||
}
|
||||
|
||||
void changeListenerCallback (ChangeBroadcaster*) override
|
||||
{
|
||||
if (lastProjectType != project.getProjectTypeString())
|
||||
updatePropertyList();
|
||||
}
|
||||
|
||||
void parentSizeChanged() override
|
||||
{
|
||||
auto width = jmax (550, getParentWidth());
|
||||
auto y = group.updateSize (12, 0, width - 12);
|
||||
|
||||
y = jmax (getParentHeight(), y);
|
||||
|
||||
setSize (width, y);
|
||||
}
|
||||
|
||||
Project& project;
|
||||
var lastProjectType;
|
||||
PropertyGroupComponent group;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectSettingsComponent)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct FileTreePanel : public TreePanelBase
|
||||
{
|
||||
FileTreePanel (Project& p)
|
||||
: TreePanelBase (&p, "fileTreeState")
|
||||
{
|
||||
tree.setMultiSelectEnabled (true);
|
||||
setRoot (std::make_unique<TreeItemTypes::GroupItem> (p.getMainGroup()));
|
||||
tree.setRootItemVisible (false);
|
||||
}
|
||||
|
||||
void updateMissingFileStatuses()
|
||||
{
|
||||
if (auto* p = dynamic_cast<TreeItemTypes::FileTreeItemBase*> (rootItem.get()))
|
||||
p->checkFileStatus();
|
||||
}
|
||||
};
|
||||
|
||||
struct ModuleTreePanel : public TreePanelBase
|
||||
{
|
||||
ModuleTreePanel (Project& p)
|
||||
: TreePanelBase (&p, "moduleTreeState")
|
||||
{
|
||||
tree.setMultiSelectEnabled (false);
|
||||
setRoot (std::make_unique<TreeItemTypes::EnabledModulesItem> (p));
|
||||
tree.setRootItemVisible (false);
|
||||
}
|
||||
};
|
||||
|
||||
struct ExportersTreePanel : public TreePanelBase
|
||||
{
|
||||
ExportersTreePanel (Project& p)
|
||||
: TreePanelBase (&p, "exportersTreeState")
|
||||
{
|
||||
tree.setMultiSelectEnabled (false);
|
||||
setRoot (std::make_unique<TreeItemTypes::ExportersTreeRoot> (p));
|
||||
tree.setRootItemVisible (false);
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class Sidebar : public Component,
|
||||
private ChangeListener
|
||||
{
|
||||
public:
|
||||
Sidebar (Project* p)
|
||||
: project (p)
|
||||
{
|
||||
setFocusContainerType (FocusContainerType::focusContainer);
|
||||
|
||||
if (project != nullptr)
|
||||
buildConcertina();
|
||||
}
|
||||
|
||||
~Sidebar() override
|
||||
{
|
||||
TreePanelBase* panels[] = { getFileTreePanel(), getModuleTreePanel(), getExportersTreePanel() };
|
||||
|
||||
for (auto* panel : panels)
|
||||
if (panel != nullptr)
|
||||
panel->saveOpenness();
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (secondaryBackgroundColourId));
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
concertinaPanel.setBounds (getLocalBounds().withTrimmedBottom (3));
|
||||
}
|
||||
|
||||
TreePanelBase* getTreeWithSelectedItems()
|
||||
{
|
||||
for (auto i = concertinaPanel.getNumPanels() - 1; i >= 0; --i)
|
||||
{
|
||||
if (auto* treeComponent = dynamic_cast<ConcertinaTreeComponent*> (concertinaPanel.getPanel (i)))
|
||||
{
|
||||
if (auto* base = treeComponent->getTree())
|
||||
if (base->tree.getNumSelectedItems() != 0)
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileTreePanel* getFileTreePanel() { return getPanel<FileTreePanel> (0); }
|
||||
ModuleTreePanel* getModuleTreePanel() { return getPanel<ModuleTreePanel> (1); }
|
||||
ExportersTreePanel* getExportersTreePanel() { return getPanel<ExportersTreePanel> (2); }
|
||||
|
||||
void showPanel (int panelIndex)
|
||||
{
|
||||
jassert (isPositiveAndBelow (panelIndex, concertinaPanel.getNumPanels()));
|
||||
|
||||
concertinaPanel.expandPanelFully (concertinaPanel.getPanel (panelIndex), true);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
template <typename PanelType>
|
||||
PanelType* getPanel (int panelIndex)
|
||||
{
|
||||
if (auto* panel = dynamic_cast<ConcertinaTreeComponent*> (concertinaPanel.getPanel (panelIndex)))
|
||||
return dynamic_cast<PanelType*> (panel->getTree());
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void changeListenerCallback (ChangeBroadcaster* source) override
|
||||
{
|
||||
const auto pointerMatches = [source] (const std::unique_ptr<ConcertinaHeader>& header) { return header.get() == source; };
|
||||
const auto it = std::find_if (headers.begin(), headers.end(), pointerMatches);
|
||||
const auto index = (int) std::distance (headers.begin(), it);
|
||||
|
||||
if (index != (int) headers.size())
|
||||
concertinaPanel.expandPanelFully (concertinaPanel.getPanel (index), true);
|
||||
}
|
||||
|
||||
void buildConcertina()
|
||||
{
|
||||
for (auto i = concertinaPanel.getNumPanels() - 1; i >= 0 ; --i)
|
||||
concertinaPanel.removePanel (concertinaPanel.getPanel (i));
|
||||
|
||||
headers.clear();
|
||||
|
||||
auto addPanel = [this] (const String& name,
|
||||
TreePanelBase* tree,
|
||||
ConcertinaTreeComponent::AdditionalComponents components,
|
||||
const Path& icon)
|
||||
{
|
||||
if (project != nullptr)
|
||||
concertinaPanel.addPanel (-1, new ConcertinaTreeComponent (name, tree, components), true);
|
||||
|
||||
headers.push_back (std::make_unique<ConcertinaHeader> (name, icon));
|
||||
};
|
||||
|
||||
using AdditionalComponents = ConcertinaTreeComponent::AdditionalComponents;
|
||||
|
||||
addPanel ("File Explorer", new FileTreePanel (*project),
|
||||
AdditionalComponents{}
|
||||
.with (AdditionalComponents::addButton)
|
||||
.with (AdditionalComponents::findPanel),
|
||||
getIcons().fileExplorer);
|
||||
|
||||
addPanel ("Modules", new ModuleTreePanel (*project),
|
||||
AdditionalComponents{}
|
||||
.with (AdditionalComponents::addButton)
|
||||
.with (AdditionalComponents::settingsButton),
|
||||
getIcons().modules);
|
||||
|
||||
addPanel ("Exporters", new ExportersTreePanel (*project),
|
||||
AdditionalComponents{}.with (AdditionalComponents::addButton),
|
||||
getIcons().exporter);
|
||||
|
||||
for (int i = 0; i < concertinaPanel.getNumPanels(); ++i)
|
||||
{
|
||||
auto* p = concertinaPanel.getPanel (i);
|
||||
auto* h = headers[(size_t) i].get();
|
||||
p->addMouseListener (this, true);
|
||||
|
||||
h->addChangeListener (this);
|
||||
h->yPosition = i * 30;
|
||||
|
||||
concertinaPanel.setCustomPanelHeader (p, h, false);
|
||||
concertinaPanel.setPanelHeaderSize (p, 30);
|
||||
}
|
||||
|
||||
addAndMakeVisible (concertinaPanel);
|
||||
}
|
||||
|
||||
void mouseDown (const MouseEvent& e) override
|
||||
{
|
||||
for (auto i = concertinaPanel.getNumPanels() - 1; i >= 0; --i)
|
||||
{
|
||||
auto* p = concertinaPanel.getPanel (i);
|
||||
|
||||
if (! (p->isParentOf (e.eventComponent)))
|
||||
{
|
||||
auto* base = dynamic_cast<TreePanelBase*> (p);
|
||||
|
||||
if (base == nullptr)
|
||||
base = dynamic_cast<ConcertinaTreeComponent*> (p)->getTree();
|
||||
|
||||
if (base != nullptr)
|
||||
base->tree.clearSelectedItems();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ConcertinaPanel concertinaPanel;
|
||||
std::vector<std::unique_ptr<ConcertinaHeader>> headers;
|
||||
Project* project = nullptr;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Sidebar)
|
||||
};
|
||||
|
|
@ -1,297 +0,0 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class ConcertinaHeader : public Component,
|
||||
public ChangeBroadcaster
|
||||
{
|
||||
public:
|
||||
ConcertinaHeader (String n, Path p)
|
||||
: Component (n), name (n), iconPath (p)
|
||||
{
|
||||
setTitle (getName());
|
||||
|
||||
panelIcon = Icon (iconPath, Colours::white);
|
||||
|
||||
nameLabel.setText (name, dontSendNotification);
|
||||
nameLabel.setJustificationType (Justification::centredLeft);
|
||||
nameLabel.setInterceptsMouseClicks (false, false);
|
||||
nameLabel.setAccessible (false);
|
||||
nameLabel.setColour (Label::textColourId, Colours::white);
|
||||
|
||||
addAndMakeVisible (nameLabel);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto b = getLocalBounds().toFloat();
|
||||
|
||||
iconBounds = b.removeFromLeft (b.getHeight()).reduced (7, 7);
|
||||
arrowBounds = b.removeFromRight (b.getHeight());
|
||||
nameLabel.setBounds (b.toNearestInt());
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.setColour (findColour (defaultButtonBackgroundColourId));
|
||||
g.fillRoundedRectangle (getLocalBounds().reduced (2, 3).toFloat(), 2.0f);
|
||||
|
||||
g.setColour (Colours::white);
|
||||
g.fillPath (arrowPath = ProjucerLookAndFeel::getArrowPath (arrowBounds,
|
||||
getParentComponent()->getBoundsInParent().getY() == yPosition ? 2 : 0,
|
||||
true, Justification::centred));
|
||||
|
||||
panelIcon.draw (g, iconBounds.toFloat(), false);
|
||||
}
|
||||
|
||||
void mouseUp (const MouseEvent& e) override
|
||||
{
|
||||
if (! e.mouseWasDraggedSinceMouseDown())
|
||||
sendChangeMessage();
|
||||
}
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override
|
||||
{
|
||||
return std::make_unique<AccessibilityHandler> (*this,
|
||||
AccessibilityRole::button,
|
||||
AccessibilityActions().addAction (AccessibilityActionType::press,
|
||||
[this] { sendChangeMessage(); }));
|
||||
}
|
||||
|
||||
int direction = 0;
|
||||
int yPosition = 0;
|
||||
|
||||
private:
|
||||
String name;
|
||||
Label nameLabel;
|
||||
|
||||
Path iconPath;
|
||||
Icon panelIcon;
|
||||
|
||||
Rectangle<float> arrowBounds, iconBounds;
|
||||
Path arrowPath;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConcertinaHeader)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class FindPanel : public Component,
|
||||
private Timer,
|
||||
private FocusChangeListener
|
||||
{
|
||||
public:
|
||||
FindPanel (std::function<void (const String&)> cb)
|
||||
: callback (cb)
|
||||
{
|
||||
addAndMakeVisible (editor);
|
||||
editor.onTextChange = [this] { startTimer (250); };
|
||||
editor.onFocusLost = [this]
|
||||
{
|
||||
isFocused = false;
|
||||
repaint();
|
||||
};
|
||||
|
||||
Desktop::getInstance().addFocusChangeListener (this);
|
||||
|
||||
lookAndFeelChanged();
|
||||
}
|
||||
|
||||
~FindPanel() override
|
||||
{
|
||||
Desktop::getInstance().removeFocusChangeListener (this);
|
||||
}
|
||||
|
||||
void paintOverChildren (Graphics& g) override
|
||||
{
|
||||
if (! isFocused)
|
||||
return;
|
||||
|
||||
g.setColour (findColour (defaultHighlightColourId));
|
||||
|
||||
Path p;
|
||||
p.addRoundedRectangle (getLocalBounds().reduced (2), 3.0f);
|
||||
g.strokePath (p, PathStrokeType (2.0f));
|
||||
}
|
||||
|
||||
|
||||
void resized() override
|
||||
{
|
||||
editor.setBounds (getLocalBounds().reduced (2));
|
||||
}
|
||||
|
||||
private:
|
||||
TextEditor editor;
|
||||
bool isFocused = false;
|
||||
std::function<void (const String&)> callback;
|
||||
|
||||
//==============================================================================
|
||||
void lookAndFeelChanged() override
|
||||
{
|
||||
editor.setTextToShowWhenEmpty ("Filter...", findColour (widgetTextColourId).withAlpha (0.3f));
|
||||
}
|
||||
|
||||
void globalFocusChanged (Component* focusedComponent) override
|
||||
{
|
||||
if (focusedComponent == &editor)
|
||||
{
|
||||
isFocused = true;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void timerCallback() override
|
||||
{
|
||||
stopTimer();
|
||||
callback (editor.getText());
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FindPanel)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ConcertinaTreeComponent : public Component
|
||||
{
|
||||
public:
|
||||
class AdditionalComponents
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
addButton = (1 << 0),
|
||||
settingsButton = (1 << 1),
|
||||
findPanel = (1 << 2)
|
||||
};
|
||||
|
||||
AdditionalComponents with (Type t)
|
||||
{
|
||||
auto copy = *this;
|
||||
copy.componentTypes |= t;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool has (Type t) const noexcept
|
||||
{
|
||||
return (componentTypes & t) != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
int componentTypes = 0;
|
||||
};
|
||||
|
||||
ConcertinaTreeComponent (const String& name,
|
||||
TreePanelBase* tree,
|
||||
AdditionalComponents additionalComponents)
|
||||
: Component (name),
|
||||
treeToDisplay (tree)
|
||||
{
|
||||
setTitle (getName());
|
||||
setFocusContainerType (FocusContainerType::focusContainer);
|
||||
|
||||
if (additionalComponents.has (AdditionalComponents::addButton))
|
||||
{
|
||||
addButton = std::make_unique<IconButton> ("Add", getIcons().plus);
|
||||
addAndMakeVisible (addButton.get());
|
||||
addButton->onClick = [this] { showAddMenu(); };
|
||||
}
|
||||
|
||||
if (additionalComponents.has (AdditionalComponents::settingsButton))
|
||||
{
|
||||
settingsButton = std::make_unique<IconButton> ("Settings", getIcons().settings);
|
||||
addAndMakeVisible (settingsButton.get());
|
||||
settingsButton->onClick = [this] { showSettings(); };
|
||||
}
|
||||
|
||||
if (additionalComponents.has (AdditionalComponents::findPanel))
|
||||
{
|
||||
findPanel = std::make_unique<FindPanel> ([this] (const String& filter) { treeToDisplay->rootItem->setSearchFilter (filter); });
|
||||
addAndMakeVisible (findPanel.get());
|
||||
}
|
||||
|
||||
addAndMakeVisible (treeToDisplay.get());
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto bounds = getLocalBounds();
|
||||
|
||||
if (addButton != nullptr || settingsButton != nullptr || findPanel != nullptr)
|
||||
{
|
||||
auto bottomSlice = bounds.removeFromBottom (25);
|
||||
bottomSlice.removeFromRight (3);
|
||||
|
||||
if (addButton != nullptr)
|
||||
addButton->setBounds (bottomSlice.removeFromRight (25).reduced (2));
|
||||
|
||||
if (settingsButton != nullptr)
|
||||
settingsButton->setBounds (bottomSlice.removeFromRight (25).reduced (2));
|
||||
|
||||
if (findPanel != nullptr)
|
||||
findPanel->setBounds (bottomSlice.reduced (2));
|
||||
}
|
||||
|
||||
treeToDisplay->setBounds (bounds);
|
||||
}
|
||||
|
||||
TreePanelBase* getTree() const noexcept { return treeToDisplay.get(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<TreePanelBase> treeToDisplay;
|
||||
std::unique_ptr<IconButton> addButton, settingsButton;
|
||||
std::unique_ptr<FindPanel> findPanel;
|
||||
|
||||
void showAddMenu()
|
||||
{
|
||||
auto numSelected = treeToDisplay->tree.getNumSelectedItems();
|
||||
|
||||
if (numSelected > 1)
|
||||
return;
|
||||
|
||||
if (numSelected == 0)
|
||||
{
|
||||
if (auto* root = dynamic_cast<JucerTreeViewBase*> (treeToDisplay->tree.getRootItem()))
|
||||
root->showPopupMenu (addButton->getScreenBounds().getCentre());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto* item = dynamic_cast<JucerTreeViewBase*> (treeToDisplay->tree.getSelectedItem (0)))
|
||||
item->showAddMenu (addButton->getScreenBounds().getCentre());
|
||||
}
|
||||
}
|
||||
|
||||
void showSettings()
|
||||
{
|
||||
if (auto* root = dynamic_cast<JucerTreeViewBase*> (treeToDisplay->tree.getRootItem()))
|
||||
{
|
||||
treeToDisplay->tree.clearSelectedItems();
|
||||
root->showDocument();
|
||||
}
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConcertinaTreeComponent)
|
||||
};
|
||||
|
|
@ -30,12 +30,6 @@
|
|||
#include "../../ProjectSaving/jucer_ProjectExporter.h"
|
||||
#include "../../Project/UI/jucer_ProjectContentComponent.h"
|
||||
|
||||
#include "../../LiveBuildEngine/jucer_MessageIDs.h"
|
||||
#include "../../LiveBuildEngine/jucer_SourceCodeRange.h"
|
||||
#include "../../LiveBuildEngine/jucer_ClassDatabase.h"
|
||||
#include "../../LiveBuildEngine/jucer_DiagnosticMessage.h"
|
||||
#include "../../LiveBuildEngine/jucer_CompileEngineClient.h"
|
||||
|
||||
//==============================================================================
|
||||
HeaderComponent::HeaderComponent (ProjectContentComponent* pcc)
|
||||
: projectContentComponent (pcc)
|
||||
|
|
@ -60,15 +54,6 @@ HeaderComponent::HeaderComponent (ProjectContentComponent* pcc)
|
|||
initialiseButtons();
|
||||
}
|
||||
|
||||
HeaderComponent::~HeaderComponent()
|
||||
{
|
||||
if (childProcess != nullptr)
|
||||
{
|
||||
childProcess->activityList.removeChangeListener (this);
|
||||
childProcess->errorList.removeChangeListener (this);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void HeaderComponent::resized()
|
||||
{
|
||||
|
|
@ -95,7 +80,6 @@ void HeaderComponent::resized()
|
|||
|
||||
exporterBounds.setCentre (bounds.getCentre());
|
||||
|
||||
runAppButton.setBounds (exporterBounds.removeFromRight (exporterBounds.getHeight()).reduced (2));
|
||||
saveAndOpenInIDEButton.setBounds (exporterBounds.removeFromRight (exporterBounds.getHeight()).reduced (2));
|
||||
|
||||
exporterBounds.removeFromRight (5);
|
||||
|
|
@ -110,17 +94,11 @@ void HeaderComponent::resized()
|
|||
void HeaderComponent::paint (Graphics& g)
|
||||
{
|
||||
g.fillAll (findColour (backgroundColourId));
|
||||
|
||||
if (isBuilding)
|
||||
getLookAndFeel().drawSpinningWaitAnimation (g, findColour (treeIconColourId),
|
||||
runAppButton.getX(), runAppButton.getY(),
|
||||
runAppButton.getWidth(), runAppButton.getHeight());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void HeaderComponent::setCurrentProject (Project* newProject)
|
||||
{
|
||||
isBuilding = false;
|
||||
stopTimer();
|
||||
repaint();
|
||||
|
||||
|
|
@ -137,22 +115,6 @@ void HeaderComponent::setCurrentProject (Project* newProject)
|
|||
projectNameValue.referTo (project->getProjectValue (Ids::name));
|
||||
projectNameValue.addListener (this);
|
||||
updateName();
|
||||
|
||||
childProcess = ProjucerApplication::getApp().childProcessCache->getExisting (*project);
|
||||
|
||||
if (childProcess != nullptr)
|
||||
{
|
||||
childProcess->activityList.addChangeListener (this);
|
||||
childProcess->errorList.addChangeListener (this);
|
||||
|
||||
runAppButton.setTooltip ({});
|
||||
runAppButton.setEnabled (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
runAppButton.setTooltip ("Enable live-build engine to launch application");
|
||||
runAppButton.setEnabled (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -236,25 +198,11 @@ void HeaderComponent::sidebarTabsWidthChanged (int newWidth)
|
|||
resized();
|
||||
}
|
||||
|
||||
void HeaderComponent::liveBuildEnablementChanged (bool isEnabled)
|
||||
{
|
||||
runAppButton.setVisible (isEnabled);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void HeaderComponent::changeListenerCallback (ChangeBroadcaster* source)
|
||||
{
|
||||
if (source == &userAvatar)
|
||||
{
|
||||
resized();
|
||||
}
|
||||
else if (childProcess != nullptr && source == &childProcess->activityList)
|
||||
{
|
||||
if (childProcess->activityList.getNumActivities() > 0)
|
||||
buildPing();
|
||||
else
|
||||
buildFinished (childProcess->errorList.getNumErrors() == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void HeaderComponent::valueChanged (Value&)
|
||||
|
|
@ -305,14 +253,6 @@ void HeaderComponent::initialiseButtons()
|
|||
}
|
||||
};
|
||||
|
||||
addAndMakeVisible (runAppButton);
|
||||
runAppButton.setIconInset (7);
|
||||
runAppButton.onClick = [this]
|
||||
{
|
||||
if (childProcess != nullptr)
|
||||
childProcess->launchApp();
|
||||
};
|
||||
|
||||
updateExporterButton();
|
||||
}
|
||||
|
||||
|
|
@ -339,57 +279,3 @@ void HeaderComponent::updateExporterButton()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void HeaderComponent::buildPing()
|
||||
{
|
||||
if (! isTimerRunning())
|
||||
{
|
||||
isBuilding = true;
|
||||
runAppButton.setEnabled (false);
|
||||
runAppButton.setTooltip ("Building...");
|
||||
|
||||
startTimer (50);
|
||||
}
|
||||
}
|
||||
|
||||
void HeaderComponent::buildFinished (bool success)
|
||||
{
|
||||
stopTimer();
|
||||
isBuilding = false;
|
||||
|
||||
repaint();
|
||||
|
||||
setRunAppButtonState (success);
|
||||
}
|
||||
|
||||
void HeaderComponent::setRunAppButtonState (bool buildWasSuccessful)
|
||||
{
|
||||
bool shouldEnableButton = false;
|
||||
|
||||
if (buildWasSuccessful)
|
||||
{
|
||||
if (childProcess != nullptr)
|
||||
{
|
||||
if (childProcess->isAppRunning() || (! childProcess->isAppRunning() && childProcess->canLaunchApp()))
|
||||
{
|
||||
runAppButton.setTooltip ("Launch application");
|
||||
shouldEnableButton = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
runAppButton.setTooltip ("Application can't be launched");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
runAppButton.setTooltip ("Enable live-build engine to launch application");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
runAppButton.setTooltip ("Error building application");
|
||||
}
|
||||
|
||||
runAppButton.setEnabled (shouldEnableButton);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
class Project;
|
||||
class ProjectContentComponent;
|
||||
class ProjectExporter;
|
||||
class CompileEngineChildProcess;
|
||||
|
||||
//==============================================================================
|
||||
class HeaderComponent : public Component,
|
||||
|
|
@ -43,7 +42,6 @@ class HeaderComponent : public Component,
|
|||
{
|
||||
public:
|
||||
HeaderComponent (ProjectContentComponent* projectContentComponent);
|
||||
~HeaderComponent() override;
|
||||
|
||||
//==============================================================================
|
||||
void resized() override;
|
||||
|
|
@ -57,7 +55,6 @@ public:
|
|||
bool canCurrentExporterLaunchProject() const;
|
||||
|
||||
void sidebarTabsWidthChanged (int newWidth);
|
||||
void liveBuildEnablementChanged (bool isEnabled);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
|
|
@ -82,14 +79,8 @@ private:
|
|||
void updateName();
|
||||
void updateExporterButton();
|
||||
|
||||
//==============================================================================
|
||||
void buildPing();
|
||||
void buildFinished (bool);
|
||||
void setRunAppButtonState (bool);
|
||||
|
||||
//==============================================================================
|
||||
int tabsWidth = 200;
|
||||
bool isBuilding = false;
|
||||
|
||||
ProjectContentComponent* projectContentComponent = nullptr;
|
||||
Project* project = nullptr;
|
||||
|
|
@ -104,10 +95,7 @@ private:
|
|||
UserAvatarComponent userAvatar { true };
|
||||
|
||||
IconButton projectSettingsButton { "Project Settings", getIcons().settings },
|
||||
saveAndOpenInIDEButton { "Save and Open in IDE", Image() },
|
||||
runAppButton { "Run Application", getIcons().play };
|
||||
|
||||
ReferenceCountedObjectPtr<CompileEngineChildProcess> childProcess;
|
||||
saveAndOpenInIDEButton { "Save and Open in IDE", Image() };
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HeaderComponent)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,17 +25,14 @@
|
|||
|
||||
#include "../../Application/jucer_Headers.h"
|
||||
#include "jucer_ProjectContentComponent.h"
|
||||
#include "../../LiveBuildEngine/jucer_DownloadCompileEngineThread.h"
|
||||
#include "../../LiveBuildEngine/jucer_CompileEngineSettings.h"
|
||||
|
||||
#include "Sidebar/jucer_TabComponents.h"
|
||||
#include "Sidebar/jucer_ProjectTab.h"
|
||||
#include "Sidebar/jucer_LiveBuildTab.h"
|
||||
#include "Sidebar/jucer_Sidebar.h"
|
||||
|
||||
NewFileWizard::Type* createGUIComponentWizard();
|
||||
|
||||
//==============================================================================
|
||||
ProjectContentComponent::ProjectContentComponent()
|
||||
: sidebar (new Sidebar (project))
|
||||
{
|
||||
setOpaque (true);
|
||||
setWantsKeyboardFocus (true);
|
||||
|
|
@ -47,25 +44,13 @@ ProjectContentComponent::ProjectContentComponent()
|
|||
sidebarSizeConstrainer.setMinimumWidth (200);
|
||||
sidebarSizeConstrainer.setMaximumWidth (500);
|
||||
|
||||
sidebarTabs.setOutline (0);
|
||||
sidebarTabs.getTabbedButtonBar().setMinimumTabScaleFactor (0.5);
|
||||
sidebarTabs.setTitle ("Sidebar");
|
||||
sidebarTabs.setFocusContainerType (FocusContainerType::focusContainer);
|
||||
|
||||
ProjucerApplication::getApp().openDocumentManager.addListener (this);
|
||||
|
||||
isLiveBuildEnabled = getGlobalProperties().getBoolValue (Ids::liveBuildEnabled);
|
||||
getGlobalProperties().addChangeListener (this);
|
||||
liveBuildEnablementChanged (isLiveBuildEnabled);
|
||||
|
||||
Desktop::getInstance().addFocusChangeListener (this);
|
||||
}
|
||||
|
||||
ProjectContentComponent::~ProjectContentComponent()
|
||||
{
|
||||
Desktop::getInstance().removeFocusChangeListener (this);
|
||||
killChildProcess();
|
||||
|
||||
getGlobalProperties().removeChangeListener (this);
|
||||
ProjucerApplication::getApp().openDocumentManager.removeListener (this);
|
||||
|
||||
|
|
@ -91,18 +76,18 @@ void ProjectContentComponent::resized()
|
|||
|
||||
r.removeFromTop (10);
|
||||
|
||||
auto sidebarArea = r.removeFromLeft (sidebarTabs.getWidth() != 0 ? sidebarTabs.getWidth()
|
||||
: r.getWidth() / 4);
|
||||
auto sidebarArea = r.removeFromLeft (sidebar->getWidth() != 0 ? sidebar->getWidth()
|
||||
: r.getWidth() / 4);
|
||||
|
||||
if (sidebarTabs.isVisible())
|
||||
sidebarTabs.setBounds (sidebarArea);
|
||||
if (sidebar->isVisible())
|
||||
sidebar->setBounds (sidebarArea);
|
||||
|
||||
if (resizerBar != nullptr)
|
||||
resizerBar->setBounds (r.withWidth (4));
|
||||
|
||||
contentViewComponent.setBounds (r);
|
||||
|
||||
headerComponent.sidebarTabsWidthChanged (sidebarTabs.getWidth());
|
||||
headerComponent.sidebarTabsWidthChanged (sidebar->getWidth());
|
||||
}
|
||||
|
||||
void ProjectContentComponent::lookAndFeelChanged()
|
||||
|
|
@ -115,7 +100,7 @@ void ProjectContentComponent::lookAndFeelChanged()
|
|||
|
||||
void ProjectContentComponent::childBoundsChanged (Component* child)
|
||||
{
|
||||
if (child == &sidebarTabs)
|
||||
if (child == sidebar.get())
|
||||
resized();
|
||||
}
|
||||
|
||||
|
|
@ -123,135 +108,47 @@ void ProjectContentComponent::setProject (Project* newProject)
|
|||
{
|
||||
if (project != newProject)
|
||||
{
|
||||
lastCrashMessage = {};
|
||||
killChildProcess();
|
||||
|
||||
if (project != nullptr)
|
||||
project->removeChangeListener (this);
|
||||
|
||||
hideEditor();
|
||||
resizerBar = nullptr;
|
||||
|
||||
deleteProjectTabs();
|
||||
project = newProject;
|
||||
|
||||
rebuildProjectUI();
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static LiveBuildTab* findBuildTab (const TabbedComponent& tabs)
|
||||
{
|
||||
return dynamic_cast<LiveBuildTab*> (tabs.getTabContentComponent (1));
|
||||
}
|
||||
|
||||
bool ProjectContentComponent::isBuildTabEnabled() const
|
||||
{
|
||||
auto bt = findBuildTab (sidebarTabs);
|
||||
|
||||
return bt != nullptr && bt->isEnabled;
|
||||
}
|
||||
|
||||
void ProjectContentComponent::createProjectTabs()
|
||||
{
|
||||
jassert (project != nullptr);
|
||||
|
||||
auto tabColour = Colours::transparentBlack;
|
||||
|
||||
sidebarTabs.addTab (getProjectTabName(), tabColour, new ProjectTab (project), true);
|
||||
|
||||
if (isLiveBuildEnabled)
|
||||
{
|
||||
CompileEngineChildProcess::Ptr childProc (getChildProcess());
|
||||
sidebarTabs.addTab (getBuildTabName(), tabColour, new LiveBuildTab (childProc, lastCrashMessage), true);
|
||||
|
||||
if (childProc != nullptr)
|
||||
if (project != nullptr)
|
||||
{
|
||||
childProc->crashHandler = [this] (const String& m) { this->handleCrash (m); };
|
||||
sidebar = std::make_unique<Sidebar> (project);
|
||||
addAndMakeVisible (sidebar.get());
|
||||
|
||||
sidebarTabs.getTabbedButtonBar().getTabButton (1)->setExtraComponent (new BuildStatusTabComp (childProc->errorList,
|
||||
childProc->activityList),
|
||||
TabBarButton::afterText);
|
||||
//==============================================================================
|
||||
resizerBar.reset (new ResizableEdgeComponent (sidebar.get(), &sidebarSizeConstrainer,
|
||||
ResizableEdgeComponent::rightEdge));
|
||||
addAndMakeVisible (resizerBar.get());
|
||||
resizerBar->setAlwaysOnTop (true);
|
||||
|
||||
project->addChangeListener (this);
|
||||
|
||||
updateMissingFileStatuses();
|
||||
|
||||
headerComponent.setVisible (true);
|
||||
headerComponent.setCurrentProject (project);
|
||||
|
||||
projectMessagesComponent.setVisible (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
sidebar->setVisible (false);
|
||||
headerComponent.setVisible (false);
|
||||
projectMessagesComponent.setVisible (false);
|
||||
}
|
||||
|
||||
projectMessagesComponent.setProject (project);
|
||||
|
||||
resized();
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectContentComponent::deleteProjectTabs()
|
||||
{
|
||||
if (project != nullptr && sidebarTabs.getNumTabs() > 0)
|
||||
{
|
||||
auto& settings = project->getStoredProperties();
|
||||
|
||||
if (sidebarTabs.getWidth() > 0)
|
||||
settings.setValue ("projectPanelWidth", sidebarTabs.getWidth());
|
||||
|
||||
settings.setValue ("lastViewedTabIndex", sidebarTabs.getCurrentTabIndex());
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
settings.setValue ("projectTabPanelHeight" + String (i),
|
||||
getProjectTab()->getPanelHeightProportion (i));
|
||||
}
|
||||
|
||||
sidebarTabs.clearTabs();
|
||||
}
|
||||
|
||||
void ProjectContentComponent::rebuildProjectUI()
|
||||
{
|
||||
deleteProjectTabs();
|
||||
|
||||
if (project != nullptr)
|
||||
{
|
||||
addAndMakeVisible (sidebarTabs);
|
||||
createProjectTabs();
|
||||
|
||||
//==============================================================================
|
||||
auto& settings = project->getStoredProperties();
|
||||
|
||||
auto lastTreeWidth = settings.getValue ("projectPanelWidth").getIntValue();
|
||||
if (lastTreeWidth < 150)
|
||||
lastTreeWidth = 240;
|
||||
|
||||
sidebarTabs.setBounds (0, 0, lastTreeWidth, getHeight());
|
||||
|
||||
auto lastTabIndex = settings.getValue ("lastViewedTabIndex", "0").getIntValue();
|
||||
|
||||
if (lastTabIndex >= sidebarTabs.getNumTabs())
|
||||
lastTabIndex = 0;
|
||||
|
||||
sidebarTabs.setCurrentTabIndex (lastTabIndex);
|
||||
|
||||
auto* projectTab = getProjectTab();
|
||||
for (int i = 2; i >= 0; --i)
|
||||
projectTab->setPanelHeightProportion (i, settings.getValue ("projectTabPanelHeight" + String (i), "1")
|
||||
.getFloatValue());
|
||||
|
||||
//==============================================================================
|
||||
resizerBar.reset (new ResizableEdgeComponent (&sidebarTabs, &sidebarSizeConstrainer,
|
||||
ResizableEdgeComponent::rightEdge));
|
||||
addAndMakeVisible (resizerBar.get());
|
||||
resizerBar->setAlwaysOnTop (true);
|
||||
|
||||
project->addChangeListener (this);
|
||||
|
||||
updateMissingFileStatuses();
|
||||
|
||||
headerComponent.setVisible (true);
|
||||
headerComponent.setCurrentProject (project);
|
||||
|
||||
projectMessagesComponent.setVisible (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
sidebarTabs.setVisible (false);
|
||||
headerComponent.setVisible (false);
|
||||
projectMessagesComponent.setVisible (false);
|
||||
}
|
||||
|
||||
projectMessagesComponent.setProject (project);
|
||||
|
||||
resized();
|
||||
}
|
||||
|
||||
void ProjectContentComponent::saveTreeViewState()
|
||||
{
|
||||
}
|
||||
|
|
@ -288,30 +185,19 @@ bool ProjectContentComponent::documentAboutToClose (OpenDocumentManager::Documen
|
|||
void ProjectContentComponent::changeListenerCallback (ChangeBroadcaster* broadcaster)
|
||||
{
|
||||
if (broadcaster == project)
|
||||
{
|
||||
updateMissingFileStatuses();
|
||||
}
|
||||
else if (broadcaster == &getGlobalProperties())
|
||||
{
|
||||
auto isEnabled = ProjucerApplication::getApp().isLiveBuildEnabled();
|
||||
|
||||
if (isLiveBuildEnabled != isEnabled)
|
||||
liveBuildEnablementChanged (isEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectContentComponent::refreshProjectTreeFileStatuses()
|
||||
{
|
||||
if (auto* projectTab = getProjectTab())
|
||||
if (auto* fileTree = projectTab->getFileTreePanel())
|
||||
fileTree->repaint();
|
||||
if (auto* fileTree = sidebar->getFileTreePanel())
|
||||
fileTree->repaint();
|
||||
}
|
||||
|
||||
void ProjectContentComponent::updateMissingFileStatuses()
|
||||
{
|
||||
if (auto* pTab = getProjectTab())
|
||||
if (auto* tree = pTab->getFileTreePanel())
|
||||
tree->updateMissingFileStatuses();
|
||||
if (auto* tree = sidebar->getFileTreePanel())
|
||||
tree->updateMissingFileStatuses();
|
||||
}
|
||||
|
||||
bool ProjectContentComponent::showEditorForFile (const File& fileToShow, bool grabFocus)
|
||||
|
|
@ -529,7 +415,7 @@ void ProjectContentComponent::showExporterSettings (const String& exporterName)
|
|||
|
||||
showExportersPanel();
|
||||
|
||||
if (auto* exportersPanel = getProjectTab()->getExportersTreePanel())
|
||||
if (auto* exportersPanel = sidebar->getExportersTreePanel())
|
||||
{
|
||||
if (auto* exporters = dynamic_cast<TreeItemTypes::ExportersTreeRoot*> (exportersPanel->rootItem.get()))
|
||||
{
|
||||
|
|
@ -554,7 +440,7 @@ void ProjectContentComponent::showModule (const String& moduleID)
|
|||
{
|
||||
showModulesPanel();
|
||||
|
||||
if (auto* modsPanel = getProjectTab()->getModuleTreePanel())
|
||||
if (auto* modsPanel = sidebar->getModuleTreePanel())
|
||||
{
|
||||
if (auto* mods = dynamic_cast<TreeItemTypes::EnabledModulesItem*> (modsPanel->rootItem.get()))
|
||||
{
|
||||
|
|
@ -575,11 +461,6 @@ void ProjectContentComponent::showModule (const String& moduleID)
|
|||
}
|
||||
}
|
||||
|
||||
void ProjectContentComponent::showLiveBuildSettings()
|
||||
{
|
||||
setScrollableEditorComponent (std::make_unique<LiveBuildSettingsComponent> (*project));
|
||||
}
|
||||
|
||||
StringArray ProjectContentComponent::getExportersWhichCanLaunch() const
|
||||
{
|
||||
StringArray s;
|
||||
|
|
@ -640,7 +521,7 @@ void ProjectContentComponent::showNewExporterMenu()
|
|||
|
||||
void ProjectContentComponent::deleteSelectedTreeItems()
|
||||
{
|
||||
if (auto* tree = getProjectTab()->getTreeWithSelectedItems())
|
||||
if (auto* tree = sidebar->getTreeWithSelectedItems())
|
||||
tree->deleteSelectedItems();
|
||||
}
|
||||
|
||||
|
|
@ -721,8 +602,6 @@ void ProjectContentComponent::getAllCommands (Array <CommandID>& commands)
|
|||
CommandIDs::goToNextDoc,
|
||||
CommandIDs::goToCounterpart,
|
||||
CommandIDs::showProjectSettings,
|
||||
CommandIDs::showProjectTab,
|
||||
CommandIDs::showBuildTab,
|
||||
CommandIDs::showFileExplorerPanel,
|
||||
CommandIDs::showModulesPanel,
|
||||
CommandIDs::showExportersPanel,
|
||||
|
|
@ -732,16 +611,6 @@ void ProjectContentComponent::getAllCommands (Array <CommandID>& commands)
|
|||
CommandIDs::createNewExporter,
|
||||
CommandIDs::deleteSelectedItem,
|
||||
CommandIDs::showTranslationTool,
|
||||
CommandIDs::cleanAll,
|
||||
CommandIDs::toggleBuildEnabled,
|
||||
CommandIDs::buildNow,
|
||||
CommandIDs::toggleContinuousBuild,
|
||||
CommandIDs::launchApp,
|
||||
CommandIDs::killApp,
|
||||
CommandIDs::reinstantiateComp,
|
||||
CommandIDs::showWarnings,
|
||||
CommandIDs::nextError,
|
||||
CommandIDs::prevError,
|
||||
CommandIDs::addNewGUIFile });
|
||||
}
|
||||
|
||||
|
|
@ -830,22 +699,6 @@ void ProjectContentComponent::getCommandInfo (const CommandID commandID, Applica
|
|||
result.defaultKeypresses.add ({ 'x', cmdCtrl, 0 });
|
||||
break;
|
||||
|
||||
case CommandIDs::showProjectTab:
|
||||
result.setInfo ("Show Project Tab",
|
||||
"Shows the tab containing the project information",
|
||||
CommandCategories::general, 0);
|
||||
result.setActive (project != nullptr);
|
||||
result.defaultKeypresses.add ({ 'p', cmdCtrl, 0 });
|
||||
break;
|
||||
|
||||
case CommandIDs::showBuildTab:
|
||||
result.setInfo ("Show Build Tab",
|
||||
"Shows the tab containing the build panel",
|
||||
CommandCategories::general, 0);
|
||||
result.setActive (project != nullptr && isLiveBuildEnabled);
|
||||
result.defaultKeypresses.add ({ 'b', cmdCtrl, 0 });
|
||||
break;
|
||||
|
||||
case CommandIDs::showFileExplorerPanel:
|
||||
result.setInfo ("Show File Explorer Panel",
|
||||
"Shows the panel containing the tree of files for this project",
|
||||
|
|
@ -906,7 +759,6 @@ void ProjectContentComponent::getCommandInfo (const CommandID commandID, Applica
|
|||
CommandCategories::general, 0);
|
||||
result.defaultKeypresses.add ({ KeyPress::deleteKey, 0, 0 });
|
||||
result.defaultKeypresses.add ({ KeyPress::backspaceKey, 0, 0 });
|
||||
result.setActive (sidebarTabs.getCurrentTabIndex() == 0);
|
||||
break;
|
||||
|
||||
case CommandIDs::showTranslationTool:
|
||||
|
|
@ -915,87 +767,6 @@ void ProjectContentComponent::getCommandInfo (const CommandID commandID, Applica
|
|||
CommandCategories::general, 0);
|
||||
break;
|
||||
|
||||
case CommandIDs::cleanAll:
|
||||
result.setInfo ("Clean All",
|
||||
"Cleans all intermediate files",
|
||||
CommandCategories::general, 0);
|
||||
result.defaultKeypresses.add ({ 'k', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0 });
|
||||
result.setActive (project != nullptr);
|
||||
break;
|
||||
|
||||
case CommandIDs::toggleBuildEnabled:
|
||||
result.setInfo ("Enable Compilation",
|
||||
"Enables/disables the compiler",
|
||||
CommandCategories::general, 0);
|
||||
result.defaultKeypresses.add ({ 'b', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0 });
|
||||
result.setActive (project != nullptr);
|
||||
result.setTicked (childProcess != nullptr);
|
||||
break;
|
||||
|
||||
case CommandIDs::buildNow:
|
||||
result.setInfo ("Build Now",
|
||||
"Recompiles any out-of-date files and updates the JIT engine",
|
||||
CommandCategories::general, 0);
|
||||
result.defaultKeypresses.add ({ 'b', ModifierKeys::commandModifier, 0 });
|
||||
result.setActive (childProcess != nullptr);
|
||||
break;
|
||||
|
||||
case CommandIDs::toggleContinuousBuild:
|
||||
result.setInfo ("Enable Continuous Recompiling",
|
||||
"Continuously recompiles any changes made in code editors",
|
||||
CommandCategories::general, 0);
|
||||
result.setActive (childProcess != nullptr);
|
||||
result.setTicked (isContinuousRebuildEnabled());
|
||||
break;
|
||||
|
||||
case CommandIDs::launchApp:
|
||||
result.setInfo ("Launch Application",
|
||||
"Invokes the app's main() function",
|
||||
CommandCategories::general, 0);
|
||||
result.defaultKeypresses.add ({ 'r', ModifierKeys::commandModifier, 0 });
|
||||
result.setActive (childProcess != nullptr && childProcess->canLaunchApp());
|
||||
break;
|
||||
|
||||
case CommandIDs::killApp:
|
||||
result.setInfo ("Stop Application",
|
||||
"Kills the app if it's running",
|
||||
CommandCategories::general, 0);
|
||||
result.defaultKeypresses.add ({ '.', ModifierKeys::commandModifier, 0 });
|
||||
result.setActive (childProcess != nullptr && childProcess->canKillApp());
|
||||
break;
|
||||
|
||||
case CommandIDs::reinstantiateComp:
|
||||
result.setInfo ("Re-instantiate Components",
|
||||
"Re-loads any component editors that are open",
|
||||
CommandCategories::general, 0);
|
||||
result.defaultKeypresses.add ({ 'r', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0 });
|
||||
result.setActive (childProcess != nullptr);
|
||||
break;
|
||||
|
||||
case CommandIDs::showWarnings:
|
||||
result.setInfo ("Show Warnings",
|
||||
"Shows or hides compilation warnings",
|
||||
CommandCategories::general, 0);
|
||||
result.setActive (project != nullptr);
|
||||
result.setTicked (areWarningsEnabled());
|
||||
break;
|
||||
|
||||
case CommandIDs::nextError:
|
||||
result.setInfo ("Highlight next error",
|
||||
"Jumps to the next error or warning",
|
||||
CommandCategories::general, 0);
|
||||
result.defaultKeypresses.add ({ '\'', ModifierKeys::commandModifier, 0 });
|
||||
result.setActive (childProcess != nullptr && ! childProcess->errorList.isEmpty());
|
||||
break;
|
||||
|
||||
case CommandIDs::prevError:
|
||||
result.setInfo ("Highlight previous error",
|
||||
"Jumps to the last error or warning",
|
||||
CommandCategories::general, 0);
|
||||
result.defaultKeypresses.add ({ '\"', ModifierKeys::commandModifier, 0 });
|
||||
result.setActive (childProcess != nullptr && ! childProcess->errorList.isEmpty());
|
||||
break;
|
||||
|
||||
case CommandIDs::addNewGUIFile:
|
||||
result.setInfo ("Add new GUI Component...",
|
||||
"Adds a new GUI Component file to the project",
|
||||
|
|
@ -1052,8 +823,6 @@ bool ProjectContentComponent::perform (const InvocationInfo& info)
|
|||
case CommandIDs::goToCounterpart: goToCounterpart(); break;
|
||||
|
||||
case CommandIDs::showProjectSettings: showProjectSettings(); break;
|
||||
case CommandIDs::showProjectTab: showProjectTab(); break;
|
||||
case CommandIDs::showBuildTab: showBuildTab(); break;
|
||||
case CommandIDs::showFileExplorerPanel: showFilesPanel(); break;
|
||||
case CommandIDs::showModulesPanel: showModulesPanel(); break;
|
||||
case CommandIDs::showExportersPanel: showExportersPanel(); break;
|
||||
|
|
@ -1068,17 +837,6 @@ bool ProjectContentComponent::perform (const InvocationInfo& info)
|
|||
|
||||
case CommandIDs::showTranslationTool: showTranslationTool(); break;
|
||||
|
||||
case CommandIDs::cleanAll: cleanAll(); break;
|
||||
case CommandIDs::toggleBuildEnabled: setBuildEnabled (! isBuildEnabled()); break;
|
||||
case CommandIDs::buildNow: rebuildNow(); break;
|
||||
case CommandIDs::toggleContinuousBuild: setContinuousRebuildEnabled (! isContinuousRebuildEnabled()); break;
|
||||
case CommandIDs::launchApp: launchApp(); break;
|
||||
case CommandIDs::killApp: killApp(); break;
|
||||
case CommandIDs::reinstantiateComp: reinstantiateLivePreviewWindows(); break;
|
||||
case CommandIDs::showWarnings: toggleWarnings(); break;
|
||||
case CommandIDs::nextError: showNextError(); break;
|
||||
case CommandIDs::prevError: showPreviousError(); break;
|
||||
|
||||
case CommandIDs::addNewGUIFile: addNewGUIFile(); break;
|
||||
|
||||
default:
|
||||
|
|
@ -1099,122 +857,6 @@ void ProjectContentComponent::getSelectedProjectItemsBeingDragged (const DragAnd
|
|||
TreeItemTypes::FileTreeItemBase::getSelectedProjectItemsBeingDragged (dragSourceDetails, selectedNodes);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void ProjectContentComponent::killChildProcess()
|
||||
{
|
||||
if (childProcess != nullptr)
|
||||
{
|
||||
deleteProjectTabs();
|
||||
childProcess = nullptr;
|
||||
ProjucerApplication::getApp().childProcessCache->removeOrphans();
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectContentComponent::setBuildEnabled (bool isEnabled, bool displayError)
|
||||
{
|
||||
if (project != nullptr && isEnabled != isBuildEnabled())
|
||||
{
|
||||
if (! displayError)
|
||||
lastCrashMessage = {};
|
||||
|
||||
project->getCompileEngineSettings().setBuildEnabled (isEnabled);
|
||||
killChildProcess();
|
||||
refreshTabsIfBuildStatusChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectContentComponent::cleanAll()
|
||||
{
|
||||
lastCrashMessage = {};
|
||||
|
||||
if (childProcess != nullptr)
|
||||
childProcess->cleanAll();
|
||||
else if (auto* p = getProject())
|
||||
CompileEngineChildProcess::cleanAllCachedFilesForProject (*p);
|
||||
}
|
||||
|
||||
void ProjectContentComponent::handleCrash (const String& message)
|
||||
{
|
||||
lastCrashMessage = message.isEmpty() ? TRANS("JIT process stopped responding!")
|
||||
: (TRANS("JIT process crashed!") + ":\n\n" + message);
|
||||
|
||||
if (project != nullptr)
|
||||
{
|
||||
setBuildEnabled (false, true);
|
||||
showBuildTab();
|
||||
}
|
||||
}
|
||||
|
||||
bool ProjectContentComponent::isBuildEnabled() const
|
||||
{
|
||||
return isLiveBuildEnabled
|
||||
&& project != nullptr
|
||||
&& project->getCompileEngineSettings().isBuildEnabled()
|
||||
&& CompileEngineDLL::getInstance()->isLoaded();
|
||||
}
|
||||
|
||||
void ProjectContentComponent::refreshTabsIfBuildStatusChanged()
|
||||
{
|
||||
if (project != nullptr
|
||||
&& isLiveBuildEnabled
|
||||
&& (sidebarTabs.getNumTabs() < 2 || isBuildEnabled() != isBuildTabEnabled()))
|
||||
{
|
||||
rebuildProjectUI();
|
||||
}
|
||||
}
|
||||
|
||||
bool ProjectContentComponent::areWarningsEnabled() const
|
||||
{
|
||||
return project != nullptr && project->getCompileEngineSettings().areWarningsEnabled();
|
||||
}
|
||||
|
||||
void ProjectContentComponent::updateWarningState()
|
||||
{
|
||||
if (childProcess != nullptr)
|
||||
childProcess->errorList.setWarningsEnabled (areWarningsEnabled());
|
||||
}
|
||||
|
||||
void ProjectContentComponent::toggleWarnings()
|
||||
{
|
||||
if (project != nullptr)
|
||||
{
|
||||
project->getCompileEngineSettings().setWarningsEnabled (! areWarningsEnabled());
|
||||
updateWarningState();
|
||||
}
|
||||
}
|
||||
|
||||
static ProjucerAppClasses::ErrorListComp* findErrorListComp (const TabbedComponent& tabs)
|
||||
{
|
||||
if (auto* bt = findBuildTab (tabs))
|
||||
return bt->errorListComp;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ProjectContentComponent::showNextError()
|
||||
{
|
||||
if (auto* el = findErrorListComp (sidebarTabs))
|
||||
{
|
||||
showBuildTab();
|
||||
el->showNext();
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectContentComponent::showPreviousError()
|
||||
{
|
||||
if (auto* el = findErrorListComp (sidebarTabs))
|
||||
{
|
||||
showBuildTab();
|
||||
el->showPrevious();
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectContentComponent::reinstantiateLivePreviewWindows()
|
||||
{
|
||||
if (childProcess != nullptr)
|
||||
childProcess->reinstantiatePreviews();
|
||||
}
|
||||
|
||||
void ProjectContentComponent::addNewGUIFile()
|
||||
{
|
||||
if (project != nullptr)
|
||||
|
|
@ -1224,131 +866,8 @@ void ProjectContentComponent::addNewGUIFile()
|
|||
}
|
||||
}
|
||||
|
||||
void ProjectContentComponent::launchApp()
|
||||
{
|
||||
if (childProcess != nullptr)
|
||||
childProcess->launchApp();
|
||||
}
|
||||
|
||||
void ProjectContentComponent::killApp()
|
||||
{
|
||||
if (childProcess != nullptr)
|
||||
childProcess->killApp();
|
||||
}
|
||||
|
||||
void ProjectContentComponent::rebuildNow()
|
||||
{
|
||||
if (childProcess != nullptr)
|
||||
childProcess->flushEditorChanges();
|
||||
}
|
||||
|
||||
void ProjectContentComponent::globalFocusChanged (Component* focusedComponent)
|
||||
{
|
||||
auto nowForeground = (Process::isForegroundProcess()
|
||||
&& (focusedComponent == this || isParentOf (focusedComponent)));
|
||||
|
||||
if (nowForeground != isForeground)
|
||||
{
|
||||
isForeground = nowForeground;
|
||||
|
||||
if (childProcess != nullptr)
|
||||
childProcess->processActivationChanged (isForeground);
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectContentComponent::timerCallback()
|
||||
{
|
||||
if (! isBuildEnabled())
|
||||
killChildProcess();
|
||||
|
||||
refreshTabsIfBuildStatusChanged();
|
||||
}
|
||||
|
||||
void ProjectContentComponent::liveBuildEnablementChanged (bool isEnabled)
|
||||
{
|
||||
isLiveBuildEnabled = isEnabled;
|
||||
|
||||
if (isLiveBuildEnabled)
|
||||
{
|
||||
startTimer (1600);
|
||||
}
|
||||
else
|
||||
{
|
||||
stopTimer();
|
||||
killChildProcess();
|
||||
}
|
||||
|
||||
rebuildProjectUI();
|
||||
headerComponent.liveBuildEnablementChanged (isLiveBuildEnabled);
|
||||
}
|
||||
|
||||
bool ProjectContentComponent::isContinuousRebuildEnabled()
|
||||
{
|
||||
return project != nullptr && project->getCompileEngineSettings().isContinuousRebuildEnabled();
|
||||
}
|
||||
|
||||
void ProjectContentComponent::setContinuousRebuildEnabled (bool b)
|
||||
{
|
||||
if (project != nullptr && childProcess != nullptr)
|
||||
{
|
||||
project->getCompileEngineSettings().setContinuousRebuildEnabled (b);
|
||||
ProjucerApplication::getCommandManager().commandStatusChanged();
|
||||
}
|
||||
}
|
||||
|
||||
ReferenceCountedObjectPtr<CompileEngineChildProcess> ProjectContentComponent::getChildProcess()
|
||||
{
|
||||
if (childProcess == nullptr && isBuildEnabled())
|
||||
childProcess = ProjucerApplication::getApp().childProcessCache->getOrCreate (*project);
|
||||
|
||||
return childProcess;
|
||||
}
|
||||
|
||||
void ProjectContentComponent::handleMissingSystemHeaders()
|
||||
{
|
||||
#if JUCE_MAC
|
||||
String tabMessage ("Compiler not available due to missing system headers\nPlease install a recent version of Xcode");
|
||||
String alertWindowMessage ("Missing system headers\nPlease install a recent version of Xcode");
|
||||
#elif JUCE_WINDOWS
|
||||
String tabMessage ("Compiler not available due to missing system headers\nPlease install a recent version of Visual Studio and the Windows Desktop SDK");
|
||||
String alertWindowMessage ("Missing system headers\nPlease install a recent version of Visual Studio and the Windows Desktop SDK");
|
||||
#elif JUCE_LINUX || JUCE_BSD
|
||||
String tabMessage ("Compiler not available due to missing system headers\nPlease install using your package manager");
|
||||
String alertWindowMessage ("Missing system headers\nPlease install using your package manager");
|
||||
#endif
|
||||
|
||||
setBuildEnabled (false, true);
|
||||
|
||||
deleteProjectTabs();
|
||||
createProjectTabs();
|
||||
|
||||
if (auto* bt = getLiveBuildTab())
|
||||
{
|
||||
bt->isEnabled = false;
|
||||
bt->errorMessage = tabMessage;
|
||||
}
|
||||
|
||||
showBuildTab();
|
||||
|
||||
AlertWindow::showMessageBox (AlertWindow::AlertIconType::WarningIcon,
|
||||
"Missing system headers", alertWindowMessage);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void ProjectContentComponent::showProjectPanel (const int index)
|
||||
{
|
||||
showProjectTab();
|
||||
|
||||
if (auto* pTab = getProjectTab())
|
||||
pTab->showPanel (index);
|
||||
}
|
||||
|
||||
ProjectTab* ProjectContentComponent::getProjectTab()
|
||||
{
|
||||
return dynamic_cast<ProjectTab*> (sidebarTabs.getTabContentComponent (0));
|
||||
}
|
||||
|
||||
LiveBuildTab* ProjectContentComponent::getLiveBuildTab()
|
||||
{
|
||||
return dynamic_cast<LiveBuildTab*> (sidebarTabs.getTabContentComponent (1));
|
||||
sidebar->showPanel (index);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,17 +30,13 @@
|
|||
#include "jucer_ProjectMessagesComponent.h"
|
||||
#include "jucer_ContentViewComponent.h"
|
||||
|
||||
class CompileEngineChildProcess;
|
||||
class ProjectTab;
|
||||
class LiveBuildTab;
|
||||
class Sidebar;
|
||||
|
||||
//==============================================================================
|
||||
class ProjectContentComponent : public Component,
|
||||
public ApplicationCommandTarget,
|
||||
private ChangeListener,
|
||||
private OpenDocumentManager::DocumentCloseListener,
|
||||
private FocusChangeListener,
|
||||
private Timer
|
||||
private OpenDocumentManager::DocumentCloseListener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
|
|
@ -70,7 +66,7 @@ public:
|
|||
void setEditorDocument (std::unique_ptr<Component> component, OpenDocumentManager::Document* doc);
|
||||
Component* getEditorComponent();
|
||||
|
||||
Component& getSidebarComponent() { return sidebarTabs; }
|
||||
Component& getSidebarComponent();
|
||||
|
||||
bool goToPreviousFile();
|
||||
bool goToNextFile();
|
||||
|
|
@ -82,10 +78,6 @@ public:
|
|||
void openInSelectedIDE (bool saveFirst);
|
||||
void showNewExporterMenu();
|
||||
|
||||
void showProjectTab() { sidebarTabs.setCurrentTabIndex (0); }
|
||||
void showBuildTab() { sidebarTabs.setCurrentTabIndex (1); }
|
||||
int getCurrentTabIndex() { return sidebarTabs.getCurrentTabIndex(); }
|
||||
|
||||
void showFilesPanel() { showProjectPanel (0); }
|
||||
void showModulesPanel() { showProjectPanel (1); }
|
||||
void showExportersPanel() { showProjectPanel (2); }
|
||||
|
|
@ -94,21 +86,12 @@ public:
|
|||
void showCurrentExporterSettings();
|
||||
void showExporterSettings (const String& exporterName);
|
||||
void showModule (const String& moduleID);
|
||||
void showLiveBuildSettings();
|
||||
void showUserSettings();
|
||||
|
||||
void deleteSelectedTreeItems();
|
||||
|
||||
void refreshProjectTreeFileStatuses();
|
||||
void updateMissingFileStatuses();
|
||||
void createProjectTabs();
|
||||
void deleteProjectTabs();
|
||||
void rebuildProjectUI();
|
||||
void refreshTabsIfBuildStatusChanged();
|
||||
void toggleWarnings();
|
||||
void showNextError();
|
||||
void showPreviousError();
|
||||
void reinstantiateLivePreviewWindows();
|
||||
void addNewGUIFile();
|
||||
|
||||
void showBubbleMessage (Rectangle<int>, const String&);
|
||||
|
|
@ -118,15 +101,6 @@ public:
|
|||
static void getSelectedProjectItemsBeingDragged (const DragAndDropTarget::SourceDetails&,
|
||||
OwnedArray<Project::Item>& selectedNodes);
|
||||
|
||||
//==============================================================================
|
||||
void killChildProcess();
|
||||
void cleanAll();
|
||||
void handleMissingSystemHeaders();
|
||||
bool isBuildTabEnabled() const;
|
||||
void setBuildEnabled (bool enabled, bool displayError = false);
|
||||
bool isBuildEnabled() const;
|
||||
bool areWarningsEnabled() const;
|
||||
|
||||
//==============================================================================
|
||||
ApplicationCommandTarget* getNextCommandTarget() override;
|
||||
void getAllCommands (Array<CommandID>&) override;
|
||||
|
|
@ -143,7 +117,6 @@ public:
|
|||
ProjectMessagesComponent& getProjectMessagesComponent() { return projectMessagesComponent; }
|
||||
|
||||
static String getProjectTabName() { return "Project"; }
|
||||
static String getBuildTabName() { return "Build"; }
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
|
|
@ -151,26 +124,8 @@ private:
|
|||
void changeListenerCallback (ChangeBroadcaster*) override;
|
||||
void showTranslationTool();
|
||||
|
||||
void globalFocusChanged (Component*) override;
|
||||
void timerCallback() override;
|
||||
|
||||
void liveBuildEnablementChanged (bool isEnabled);
|
||||
|
||||
bool isContinuousRebuildEnabled();
|
||||
void setContinuousRebuildEnabled (bool b);
|
||||
|
||||
void rebuildNow();
|
||||
void handleCrash (const String& message);
|
||||
void updateWarningState();
|
||||
void launchApp();
|
||||
void killApp();
|
||||
|
||||
ReferenceCountedObjectPtr<CompileEngineChildProcess> getChildProcess();
|
||||
|
||||
//==============================================================================
|
||||
void showProjectPanel (const int index);
|
||||
ProjectTab* getProjectTab();
|
||||
LiveBuildTab* getLiveBuildTab();
|
||||
bool canSelectedProjectBeLaunch();
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -179,7 +134,7 @@ private:
|
|||
RecentDocumentList recentDocumentList;
|
||||
|
||||
HeaderComponent headerComponent { this };
|
||||
TabbedComponent sidebarTabs { TabbedButtonBar::TabsAtTop };
|
||||
std::unique_ptr<Sidebar> sidebar;
|
||||
ProjectMessagesComponent projectMessagesComponent;
|
||||
ContentViewComponent contentViewComponent;
|
||||
|
||||
|
|
@ -188,10 +143,7 @@ private:
|
|||
std::unique_ptr<Component> translationTool;
|
||||
BubbleMessageComponent bubbleMessage;
|
||||
|
||||
ReferenceCountedObjectPtr<CompileEngineChildProcess> childProcess;
|
||||
String lastCrashMessage;
|
||||
|
||||
bool isForeground = false, isLiveBuildEnabled = false;
|
||||
bool isForeground = false;
|
||||
int lastViewedTab = 0;
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#include "jucer_Project.h"
|
||||
#include "../ProjectSaving/jucer_ProjectSaver.h"
|
||||
#include "../Application/jucer_Application.h"
|
||||
#include "../LiveBuildEngine/jucer_CompileEngineSettings.h"
|
||||
|
||||
//==============================================================================
|
||||
Project::ProjectFileModificationPoller::ProjectFileModificationPoller (Project& p)
|
||||
|
|
@ -641,8 +640,6 @@ Result Project::loadDocument (const File& file)
|
|||
moveOldPropertyFromProjectToAllExporters (Ids::smallIcon);
|
||||
getEnabledModules().sortAlphabetically();
|
||||
|
||||
compileEngineSettings.reset (new CompileEngineSettings (projectRoot));
|
||||
|
||||
rescanExporterPathModules (! ProjucerApplication::getApp().isRunningCommandLine);
|
||||
exporterPathsModulesList.addListener (this);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
class ProjectExporter;
|
||||
class LibraryModule;
|
||||
class EnabledModulesList;
|
||||
class CompileEngineSettings;
|
||||
|
||||
namespace ProjectMessages
|
||||
{
|
||||
|
|
@ -493,9 +492,6 @@ public:
|
|||
File getTemporaryDirectory() const noexcept { return tempDirectory; }
|
||||
void setTemporaryDirectory (const File&) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
CompileEngineSettings& getCompileEngineSettings() { return *compileEngineSettings; }
|
||||
|
||||
//==============================================================================
|
||||
ValueTree getProjectMessages() const { return projectMessages; }
|
||||
|
||||
|
|
@ -547,7 +543,6 @@ private:
|
|||
pluginVSTNumMidiInputsValue, pluginVSTNumMidiOutputsValue;
|
||||
|
||||
//==============================================================================
|
||||
std::unique_ptr<CompileEngineSettings> compileEngineSettings;
|
||||
std::unique_ptr<EnabledModulesList> enabledModulesList;
|
||||
|
||||
AvailableModulesList exporterPathsModulesList;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue