mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
307 lines
9.7 KiB
C++
307 lines
9.7 KiB
C++
/*
|
|
==============================================================================
|
|
|
|
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)
|
|
};
|