git subrepo clone --branch=sono6good https://github.com/essej/JUCE.git deps/juce
subrepo: subdir: "deps/juce" merged: "b13f9084e" upstream: origin: "https://github.com/essej/JUCE.git" branch: "sono6good" commit: "b13f9084e" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596"
This commit is contained in:
326
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_ContentComponents.h
vendored
Normal file
326
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_ContentComponents.h
vendored
Normal file
@ -0,0 +1,326 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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
|
||||
|
||||
#include "../../ProjectSaving/jucer_ProjectExporter.h"
|
||||
#include "../../Utility/UI/PropertyComponents/jucer_FilePathPropertyComponent.h"
|
||||
#include "../../Utility/Helpers/jucer_ValueWithDefaultWrapper.h"
|
||||
|
||||
#include "jucer_NewProjectWizard.h"
|
||||
|
||||
//==============================================================================
|
||||
class ItemHeader : public Component
|
||||
{
|
||||
public:
|
||||
ItemHeader (StringRef name, StringRef description, const char* iconSvgData)
|
||||
: nameLabel ({}, name),
|
||||
descriptionLabel ({}, description),
|
||||
icon (makeIcon (iconSvgData))
|
||||
{
|
||||
addAndMakeVisible (nameLabel);
|
||||
nameLabel.setFont (18.0f);
|
||||
nameLabel.setMinimumHorizontalScale (1.0f);
|
||||
|
||||
addAndMakeVisible (descriptionLabel);
|
||||
descriptionLabel.setMinimumHorizontalScale (1.0f);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto bounds = getLocalBounds();
|
||||
|
||||
auto topSlice = bounds.removeFromTop (50);
|
||||
iconBounds = topSlice.removeFromRight (75);
|
||||
nameLabel.setBounds (topSlice);
|
||||
|
||||
bounds.removeFromTop (10);
|
||||
descriptionLabel.setBounds (bounds.removeFromTop (50));
|
||||
bounds.removeFromTop (20);
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (secondaryBackgroundColourId));
|
||||
|
||||
if (icon != nullptr)
|
||||
icon->drawWithin (g, iconBounds.toFloat(), RectanglePlacement::centred, 1.0f);
|
||||
}
|
||||
|
||||
private:
|
||||
static std::unique_ptr<Drawable> makeIcon (const char* iconSvgData)
|
||||
{
|
||||
if (auto svg = XmlDocument::parse (iconSvgData))
|
||||
return Drawable::createFromSVG (*svg);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Label nameLabel, descriptionLabel;
|
||||
|
||||
Rectangle<int> iconBounds;
|
||||
std::unique_ptr<Drawable> icon;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ItemHeader)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TemplateComponent : public Component
|
||||
{
|
||||
public:
|
||||
TemplateComponent (const NewProjectTemplates::ProjectTemplate& temp,
|
||||
std::function<void (std::unique_ptr<Project>)>&& createdCallback)
|
||||
: projectTemplate (temp),
|
||||
projectCreatedCallback (std::move (createdCallback)),
|
||||
header (projectTemplate.displayName, projectTemplate.description, projectTemplate.icon)
|
||||
{
|
||||
createProjectButton.onClick = [this]
|
||||
{
|
||||
chooser = std::make_unique<FileChooser> ("Save Project", NewProjectWizard::getLastWizardFolder());
|
||||
auto browserFlags = FileBrowserComponent::openMode | FileBrowserComponent::canSelectDirectories;
|
||||
|
||||
chooser->launchAsync (browserFlags, [this] (const FileChooser& fc)
|
||||
{
|
||||
auto dir = fc.getResult();
|
||||
|
||||
if (dir == File{})
|
||||
return;
|
||||
|
||||
SafePointer<TemplateComponent> safeThis { this };
|
||||
NewProjectWizard::createNewProject (projectTemplate,
|
||||
dir.getChildFile (projectNameValue.get().toString()),
|
||||
projectNameValue.get(),
|
||||
modulesValue.get(),
|
||||
exportersValue.get(),
|
||||
fileOptionsValue.get(),
|
||||
modulePathValue.getCurrentValue(),
|
||||
modulePathValue.getWrappedValueWithDefault().isUsingDefault(),
|
||||
[safeThis, dir] (std::unique_ptr<Project> project)
|
||||
{
|
||||
if (safeThis == nullptr)
|
||||
return;
|
||||
|
||||
safeThis->projectCreatedCallback (std::move (project));
|
||||
getAppSettings().lastWizardFolder = dir;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
addAndMakeVisible (createProjectButton);
|
||||
addAndMakeVisible (header);
|
||||
|
||||
modulePathValue.init ({ settingsTree, Ids::defaultJuceModulePath, nullptr },
|
||||
getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()),
|
||||
TargetOS::getThisOS());
|
||||
|
||||
panel.addProperties (buildPropertyList(), 2);
|
||||
addAndMakeVisible (panel);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto bounds = getLocalBounds().reduced (10);
|
||||
|
||||
header.setBounds (bounds.removeFromTop (150));
|
||||
createProjectButton.setBounds (bounds.removeFromBottom (30).removeFromRight (150));
|
||||
bounds.removeFromBottom (5);
|
||||
|
||||
panel.setBounds (bounds);
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (secondaryBackgroundColourId));
|
||||
}
|
||||
|
||||
private:
|
||||
NewProjectTemplates::ProjectTemplate projectTemplate;
|
||||
|
||||
std::unique_ptr<FileChooser> chooser;
|
||||
std::function<void (std::unique_ptr<Project>)> projectCreatedCallback;
|
||||
|
||||
ItemHeader header;
|
||||
TextButton createProjectButton { "Create Project..." };
|
||||
|
||||
ValueTree settingsTree { "NewProjectSettings" };
|
||||
|
||||
ValueWithDefault projectNameValue { settingsTree, Ids::name, nullptr, "NewProject" },
|
||||
modulesValue { settingsTree, Ids::dependencies_, nullptr, projectTemplate.requiredModules, "," },
|
||||
exportersValue { settingsTree, Ids::exporters, nullptr, StringArray (ProjectExporter::getCurrentPlatformExporterTypeInfo().identifier.toString()), "," },
|
||||
fileOptionsValue { settingsTree, Ids::file, nullptr, NewProjectTemplates::getVarForFileOption (projectTemplate.defaultFileOption) };
|
||||
|
||||
ValueWithDefaultWrapper modulePathValue;
|
||||
|
||||
PropertyPanel panel;
|
||||
|
||||
//==============================================================================
|
||||
PropertyComponent* createProjectNamePropertyComponent()
|
||||
{
|
||||
return new TextPropertyComponent (projectNameValue, "Project Name", 1024, false);
|
||||
}
|
||||
|
||||
PropertyComponent* createModulesPropertyComponent()
|
||||
{
|
||||
Array<var> moduleVars;
|
||||
var requiredModules;
|
||||
|
||||
for (auto& m : getJUCEModules())
|
||||
{
|
||||
moduleVars.add (m);
|
||||
|
||||
if (projectTemplate.requiredModules.contains (m))
|
||||
requiredModules.append (m);
|
||||
}
|
||||
|
||||
modulesValue = requiredModules;
|
||||
|
||||
return new MultiChoicePropertyComponent (modulesValue, "Modules",
|
||||
getJUCEModules(), moduleVars);
|
||||
}
|
||||
|
||||
PropertyComponent* createModulePathPropertyComponent()
|
||||
{
|
||||
return new FilePathPropertyComponent (modulePathValue.getWrappedValueWithDefault(), "Path to Modules", true);
|
||||
}
|
||||
|
||||
PropertyComponent* createExportersPropertyValue()
|
||||
{
|
||||
Array<var> exporterVars;
|
||||
StringArray exporterNames;
|
||||
|
||||
for (auto& exporterTypeInfo : ProjectExporter::getExporterTypeInfos())
|
||||
{
|
||||
exporterVars.add (exporterTypeInfo.identifier.toString());
|
||||
exporterNames.add (exporterTypeInfo.displayName);
|
||||
}
|
||||
|
||||
return new MultiChoicePropertyComponent (exportersValue, "Exporters", exporterNames, exporterVars);
|
||||
}
|
||||
|
||||
PropertyComponent* createFileCreationOptionsPropertyComponent()
|
||||
{
|
||||
Array<var> optionVars;
|
||||
StringArray optionStrings;
|
||||
|
||||
for (auto& opt : projectTemplate.fileOptionsAndFiles)
|
||||
{
|
||||
optionVars.add (NewProjectTemplates::getVarForFileOption (opt.first));
|
||||
optionStrings.add (NewProjectTemplates::getStringForFileOption (opt.first));
|
||||
}
|
||||
|
||||
return new ChoicePropertyComponent (fileOptionsValue, "File Creation Options", optionStrings, optionVars);
|
||||
}
|
||||
|
||||
Array<PropertyComponent*> buildPropertyList()
|
||||
{
|
||||
PropertyListBuilder builder;
|
||||
|
||||
builder.add (createProjectNamePropertyComponent());
|
||||
builder.add (createModulesPropertyComponent());
|
||||
builder.add (createModulePathPropertyComponent());
|
||||
builder.add (createExportersPropertyValue());
|
||||
|
||||
if (! projectTemplate.fileOptionsAndFiles.empty())
|
||||
builder.add (createFileCreationOptionsPropertyComponent());
|
||||
|
||||
return builder.components;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TemplateComponent)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ExampleComponent : public Component
|
||||
{
|
||||
public:
|
||||
ExampleComponent (const File& f, std::function<void (const File&)> selectedCallback)
|
||||
: exampleFile (f),
|
||||
metadata (parseJUCEHeaderMetadata (exampleFile)),
|
||||
exampleSelectedCallback (std::move (selectedCallback)),
|
||||
header (metadata[Ids::name].toString(), metadata[Ids::description].toString(), BinaryData::background_logo_svg),
|
||||
codeViewer (doc, &cppTokeniser)
|
||||
{
|
||||
setTitle (exampleFile.getFileName());
|
||||
setFocusContainerType (FocusContainerType::focusContainer);
|
||||
|
||||
addAndMakeVisible (header);
|
||||
|
||||
openExampleButton.onClick = [this] { exampleSelectedCallback (exampleFile); };
|
||||
addAndMakeVisible (openExampleButton);
|
||||
|
||||
setupCodeViewer();
|
||||
addAndMakeVisible (codeViewer);
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (secondaryBackgroundColourId));
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto bounds = getLocalBounds().reduced (10);
|
||||
|
||||
header.setBounds (bounds.removeFromTop (125));
|
||||
openExampleButton.setBounds (bounds.removeFromBottom (30).removeFromRight (150));
|
||||
codeViewer.setBounds (bounds);
|
||||
}
|
||||
|
||||
private:
|
||||
void setupCodeViewer()
|
||||
{
|
||||
auto fileString = exampleFile.loadFileAsString();
|
||||
|
||||
doc.replaceAllContent (fileString);
|
||||
|
||||
codeViewer.setScrollbarThickness (6);
|
||||
codeViewer.setReadOnly (true);
|
||||
codeViewer.setTitle ("Code");
|
||||
getAppSettings().appearance.applyToCodeEditor (codeViewer);
|
||||
|
||||
codeViewer.scrollToLine (findBestLineToScrollToForClass (StringArray::fromLines (fileString),
|
||||
metadata[Ids::name].toString(),
|
||||
metadata[Ids::type] == "AudioProcessor"));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
File exampleFile;
|
||||
var metadata;
|
||||
|
||||
std::function<void (const File&)> exampleSelectedCallback;
|
||||
|
||||
ItemHeader header;
|
||||
|
||||
CPlusPlusCodeTokeniser cppTokeniser;
|
||||
CodeDocument doc;
|
||||
CodeEditorComponent codeViewer;
|
||||
|
||||
TextButton openExampleButton { "Open Example..." };
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ExampleComponent)
|
||||
};
|
251
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_NewProjectTemplates.h
vendored
Normal file
251
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_NewProjectTemplates.h
vendored
Normal file
@ -0,0 +1,251 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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
|
||||
|
||||
#include "../../Utility/Helpers/jucer_MiscUtilities.h"
|
||||
|
||||
//==============================================================================
|
||||
namespace NewProjectTemplates
|
||||
{
|
||||
enum class ProjectCategory
|
||||
{
|
||||
application,
|
||||
plugin,
|
||||
library
|
||||
};
|
||||
|
||||
inline String getProjectCategoryString (ProjectCategory category)
|
||||
{
|
||||
if (category == ProjectCategory::application) return "Application";
|
||||
if (category == ProjectCategory::plugin) return "Plug-In";
|
||||
if (category == ProjectCategory::library) return "Library";
|
||||
|
||||
jassertfalse;
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
enum class FileCreationOptions
|
||||
{
|
||||
noFiles,
|
||||
main,
|
||||
header,
|
||||
headerAndCpp,
|
||||
processorAndEditor
|
||||
};
|
||||
|
||||
using FilenameAndContent = std::pair<String, String>;
|
||||
using OptionAndFilenameAndContent = std::pair<FileCreationOptions, std::vector<FilenameAndContent>>;
|
||||
using OptionsAndFiles = std::vector<OptionAndFilenameAndContent>;
|
||||
|
||||
struct ProjectTemplate
|
||||
{
|
||||
ProjectCategory category;
|
||||
String displayName, description, projectTypeString;
|
||||
|
||||
const char* icon;
|
||||
StringArray requiredModules;
|
||||
OptionsAndFiles fileOptionsAndFiles;
|
||||
FileCreationOptions defaultFileOption;
|
||||
|
||||
std::vector<FilenameAndContent> getFilesForOption (FileCreationOptions option) const
|
||||
{
|
||||
auto iter = std::find_if (fileOptionsAndFiles.begin(), fileOptionsAndFiles.end(),
|
||||
[option] (const OptionAndFilenameAndContent& opt) { return opt.first == option; });
|
||||
|
||||
if (iter != fileOptionsAndFiles.end())
|
||||
return iter->second;
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
inline bool isApplication (const ProjectTemplate& t) noexcept { return t.category == ProjectCategory::application; }
|
||||
inline bool isPlugin (const ProjectTemplate& t) noexcept { return t.category == ProjectCategory::plugin; }
|
||||
inline bool isLibrary (const ProjectTemplate& t) noexcept { return t.category == ProjectCategory::library; }
|
||||
|
||||
//==============================================================================
|
||||
inline var getVarForFileOption (FileCreationOptions opt)
|
||||
{
|
||||
if (opt == FileCreationOptions::noFiles) return "none";
|
||||
if (opt == FileCreationOptions::main) return "main";
|
||||
if (opt == FileCreationOptions::header) return "header";
|
||||
if (opt == FileCreationOptions::headerAndCpp) return "headercpp";
|
||||
if (opt == FileCreationOptions::processorAndEditor) return "processoreditor";
|
||||
|
||||
jassertfalse;
|
||||
return {};
|
||||
}
|
||||
|
||||
inline FileCreationOptions getFileOptionForVar (var opt)
|
||||
{
|
||||
if (opt == "none") return FileCreationOptions::noFiles;
|
||||
if (opt == "main") return FileCreationOptions::main;
|
||||
if (opt == "header") return FileCreationOptions::header;
|
||||
if (opt == "headercpp") return FileCreationOptions::headerAndCpp;
|
||||
if (opt == "processoreditor") return FileCreationOptions::processorAndEditor;
|
||||
|
||||
jassertfalse;
|
||||
return {};
|
||||
}
|
||||
|
||||
inline String getStringForFileOption (FileCreationOptions opt)
|
||||
{
|
||||
if (opt == FileCreationOptions::noFiles) return "No Files";
|
||||
if (opt == FileCreationOptions::main) return "Main.cpp";
|
||||
if (opt == FileCreationOptions::header) return "Main.cpp + .h";
|
||||
if (opt == FileCreationOptions::headerAndCpp) return "Main.cpp + .h/.cpp ";
|
||||
if (opt == FileCreationOptions::processorAndEditor) return "Processor and Editor";
|
||||
|
||||
jassertfalse;
|
||||
return {};
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
template <typename... Strings>
|
||||
inline StringArray addAndReturn (StringArray arr, Strings... strings)
|
||||
{
|
||||
arr.addArray ({ strings... });
|
||||
return arr;
|
||||
}
|
||||
|
||||
inline std::vector<ProjectTemplate> getAllTemplates()
|
||||
{
|
||||
return
|
||||
{
|
||||
{ ProjectCategory::application,
|
||||
"Blank", "Creates a blank JUCE GUI application.",
|
||||
build_tools::ProjectType_GUIApp::getTypeName(),
|
||||
BinaryData::wizard_GUI_svg,
|
||||
getModulesRequiredForComponent(),
|
||||
{},
|
||||
FileCreationOptions::noFiles
|
||||
},
|
||||
|
||||
{ ProjectCategory::application,
|
||||
"GUI", "Creates a blank JUCE GUI application with a single window component.",
|
||||
build_tools::ProjectType_GUIApp::getTypeName(),
|
||||
BinaryData::wizard_GUI_svg,
|
||||
getModulesRequiredForComponent(),
|
||||
{
|
||||
{ FileCreationOptions::noFiles, {} },
|
||||
{ FileCreationOptions::main, { { "Main.cpp", "jucer_MainTemplate_NoWindow_cpp" } } },
|
||||
{ FileCreationOptions::header, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" },
|
||||
{ "MainComponent.h", "jucer_ContentCompSimpleTemplate_h" } } },
|
||||
{ FileCreationOptions::headerAndCpp, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" },
|
||||
{ "MainComponent.h", "jucer_ContentCompTemplate_h" },
|
||||
{ "MainComponent.cpp", "jucer_ContentCompTemplate_cpp" } } }
|
||||
},
|
||||
FileCreationOptions::headerAndCpp },
|
||||
|
||||
{ ProjectCategory::application,
|
||||
"Audio", "Creates a blank JUCE GUI application with a single window component and audio and MIDI in/out functions.",
|
||||
build_tools::ProjectType_GUIApp::getTypeName(),
|
||||
BinaryData::wizard_AudioApp_svg,
|
||||
addAndReturn (getModulesRequiredForComponent(), "juce_audio_basics", "juce_audio_devices", "juce_audio_formats",
|
||||
"juce_audio_processors", "juce_audio_utils", "juce_gui_extra"),
|
||||
{
|
||||
{ FileCreationOptions::header, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" },
|
||||
{ "MainComponent.h", "jucer_AudioComponentSimpleTemplate_h" } } },
|
||||
{ FileCreationOptions::headerAndCpp, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" },
|
||||
{ "MainComponent.h", "jucer_AudioComponentTemplate_h" },
|
||||
{ "MainComponent.cpp", "jucer_AudioComponentTemplate_cpp" } } }
|
||||
},
|
||||
FileCreationOptions::headerAndCpp },
|
||||
|
||||
{ ProjectCategory::application,
|
||||
"Console", "Creates a command-line application without GUI support.",
|
||||
build_tools::ProjectType_ConsoleApp::getTypeName(),
|
||||
BinaryData::wizard_ConsoleApp_svg,
|
||||
getModulesRequiredForConsole(),
|
||||
{
|
||||
{ FileCreationOptions::noFiles, {} },
|
||||
{ FileCreationOptions::main, { { "Main.cpp", "jucer_MainConsoleAppTemplate_cpp" } } }
|
||||
},
|
||||
FileCreationOptions::main },
|
||||
|
||||
{ ProjectCategory::application,
|
||||
"Animated", "Creates a JUCE GUI application which draws an animated graphical display.",
|
||||
build_tools::ProjectType_GUIApp::getTypeName(),
|
||||
BinaryData::wizard_AnimatedApp_svg,
|
||||
addAndReturn (getModulesRequiredForComponent(), "juce_gui_extra"),
|
||||
{
|
||||
{ FileCreationOptions::header, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" },
|
||||
{ "MainComponent.h", "jucer_AudioComponentSimpleTemplate_h" } } },
|
||||
{ FileCreationOptions::headerAndCpp, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" },
|
||||
{ "MainComponent.h", "jucer_AnimatedComponentTemplate_h" },
|
||||
{ "MainComponent.cpp", "jucer_AnimatedComponentTemplate_cpp" } } }
|
||||
},
|
||||
FileCreationOptions::headerAndCpp },
|
||||
|
||||
{ ProjectCategory::application,
|
||||
"OpenGL", "Creates a blank JUCE application with a single window component. "
|
||||
"This component supports openGL drawing features including 3D model import and GLSL shaders.",
|
||||
build_tools::ProjectType_GUIApp::getTypeName(),
|
||||
BinaryData::wizard_OpenGL_svg,
|
||||
addAndReturn (getModulesRequiredForComponent(), "juce_gui_extra", "juce_opengl"),
|
||||
{
|
||||
{ FileCreationOptions::header, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" },
|
||||
{ "MainComponent.h", "jucer_AudioComponentSimpleTemplate_h" } } },
|
||||
{ FileCreationOptions::headerAndCpp, { { "Main.cpp", "jucer_MainTemplate_Window_cpp" },
|
||||
{ "MainComponent.h", "jucer_OpenGLComponentTemplate_h" },
|
||||
{ "MainComponent.cpp", "jucer_OpenGLComponentTemplate_cpp" } } }
|
||||
},
|
||||
FileCreationOptions::headerAndCpp },
|
||||
|
||||
{ ProjectCategory::plugin,
|
||||
"Basic", "Creates an audio plug-in with a single window GUI and audio/MIDI IO functions.",
|
||||
build_tools::ProjectType_AudioPlugin::getTypeName(),
|
||||
BinaryData::wizard_AudioPlugin_svg,
|
||||
getModulesRequiredForAudioProcessor(),
|
||||
{
|
||||
{ FileCreationOptions::processorAndEditor, { { "PluginProcessor.cpp", "jucer_AudioPluginFilterTemplate_cpp" },
|
||||
{ "PluginProcessor.h", "jucer_AudioPluginFilterTemplate_h" },
|
||||
{ "PluginEditor.cpp", "jucer_AudioPluginEditorTemplate_cpp" },
|
||||
{ "PluginEditor.h", "jucer_AudioPluginEditorTemplate_h" } } }
|
||||
},
|
||||
FileCreationOptions::processorAndEditor
|
||||
},
|
||||
|
||||
{ ProjectCategory::library,
|
||||
"Static Library", "Creates a static library.",
|
||||
build_tools::ProjectType_StaticLibrary::getTypeName(),
|
||||
BinaryData::wizard_StaticLibrary_svg,
|
||||
getModulesRequiredForConsole(),
|
||||
{},
|
||||
FileCreationOptions::noFiles
|
||||
},
|
||||
|
||||
{ ProjectCategory::library,
|
||||
"Dynamic Library", "Creates a dynamic library.",
|
||||
build_tools::ProjectType_DLL::getTypeName(),
|
||||
BinaryData::wizard_DLL_svg,
|
||||
getModulesRequiredForConsole(),
|
||||
{},
|
||||
FileCreationOptions::noFiles
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
310
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.cpp
vendored
Normal file
310
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.cpp
vendored
Normal file
@ -0,0 +1,310 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../jucer_Headers.h"
|
||||
#include "../jucer_Application.h"
|
||||
#include "../../ProjectSaving/jucer_ProjectExporter.h"
|
||||
|
||||
#include "jucer_NewProjectWizard.h"
|
||||
|
||||
//==============================================================================
|
||||
static String getFileTemplate (const String& templateName)
|
||||
{
|
||||
int dataSize = 0;
|
||||
|
||||
if (auto* data = BinaryData::getNamedResource (templateName.toUTF8(), dataSize))
|
||||
return String::fromUTF8 (data, dataSize);
|
||||
|
||||
jassertfalse;
|
||||
return {};
|
||||
}
|
||||
|
||||
static String getJuceHeaderInclude()
|
||||
{
|
||||
return CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename());
|
||||
}
|
||||
|
||||
static String getContentComponentName()
|
||||
{
|
||||
return "MainComponent";
|
||||
}
|
||||
|
||||
using Opts = NewProjectTemplates::FileCreationOptions;
|
||||
|
||||
static bool shouldCreateHeaderFile (Opts opts) noexcept { return opts == Opts::header || opts == Opts::headerAndCpp; }
|
||||
static bool shouldCreateCppFile (Opts opts) noexcept { return opts == Opts::headerAndCpp; }
|
||||
|
||||
static void doBasicProjectSetup (Project& project, const NewProjectTemplates::ProjectTemplate& projectTemplate, const String& name)
|
||||
{
|
||||
project.setTitle (name);
|
||||
project.setProjectType (projectTemplate.projectTypeString);
|
||||
project.getMainGroup().addNewSubGroup ("Source", 0);
|
||||
|
||||
project.getConfigFlag ("JUCE_STRICT_REFCOUNTEDPOINTER") = true;
|
||||
project.getProjectValue (Ids::useAppConfig) = false;
|
||||
project.getProjectValue (Ids::addUsingNamespaceToJuceHeader) = false;
|
||||
|
||||
if (! ProjucerApplication::getApp().getLicenseController().getCurrentState().canUnlockFullFeatures())
|
||||
project.getProjectValue (Ids::displaySplashScreen) = true;
|
||||
|
||||
if (NewProjectTemplates::isPlugin (projectTemplate))
|
||||
project.getConfigFlag ("JUCE_VST3_CAN_REPLACE_VST2") = 0;
|
||||
}
|
||||
|
||||
static std::map<String, String> getSharedFileTokenReplacements()
|
||||
{
|
||||
return { { "%%app_headers%%", getJuceHeaderInclude() } };
|
||||
}
|
||||
|
||||
static std::map<String, String> getApplicationFileTokenReplacements (const String& name,
|
||||
NewProjectTemplates::FileCreationOptions fileOptions,
|
||||
const File& sourceFolder)
|
||||
{
|
||||
auto tokenReplacements = getSharedFileTokenReplacements();
|
||||
|
||||
tokenReplacements.insert ({ "%%app_class_name%%",
|
||||
build_tools::makeValidIdentifier (name + "Application", false, true, false) });
|
||||
tokenReplacements.insert ({ "%%content_component_class%%",
|
||||
getContentComponentName() });
|
||||
tokenReplacements.insert ({ "%%include_juce%%",
|
||||
getJuceHeaderInclude() });
|
||||
|
||||
if (shouldCreateHeaderFile (fileOptions))
|
||||
tokenReplacements["%%app_headers%%"] << newLine
|
||||
<< CodeHelpers::createIncludeStatement (sourceFolder.getChildFile ("MainComponent.h"),
|
||||
sourceFolder.getChildFile ("Main.cpp"));
|
||||
|
||||
if (shouldCreateCppFile (fileOptions))
|
||||
tokenReplacements.insert ({ "%%include_corresponding_header%%",
|
||||
CodeHelpers::createIncludeStatement (sourceFolder.getChildFile ("MainComponent.h"),
|
||||
sourceFolder.getChildFile ("MainComponent.cpp")) });
|
||||
|
||||
return tokenReplacements;
|
||||
}
|
||||
|
||||
static std::map<String, String> getPluginFileTokenReplacements (const String& name,
|
||||
const File& sourceFolder)
|
||||
{
|
||||
auto tokenReplacements = getSharedFileTokenReplacements();
|
||||
|
||||
auto processorCppFile = sourceFolder.getChildFile ("PluginProcessor.cpp");
|
||||
auto processorHFile = processorCppFile.withFileExtension (".h");
|
||||
auto editorCppFile = sourceFolder.getChildFile ("PluginEditor.cpp");
|
||||
auto editorHFile = editorCppFile.withFileExtension (".h");
|
||||
|
||||
auto processorHInclude = CodeHelpers::createIncludeStatement (processorHFile, processorCppFile);
|
||||
auto editorHInclude = CodeHelpers::createIncludeStatement (editorHFile, processorCppFile);
|
||||
|
||||
auto processorClassName = build_tools::makeValidIdentifier (name, false, true, false) + "AudioProcessor";
|
||||
processorClassName = processorClassName.substring (0, 1).toUpperCase() + processorClassName.substring (1);
|
||||
auto editorClassName = processorClassName + "Editor";
|
||||
|
||||
tokenReplacements.insert ({"%%filter_headers%%", processorHInclude + newLine + editorHInclude });
|
||||
tokenReplacements.insert ({"%%filter_class_name%%", processorClassName });
|
||||
tokenReplacements.insert ({"%%editor_class_name%%", editorClassName });
|
||||
tokenReplacements.insert ({"%%editor_cpp_headers%%", processorHInclude + newLine + editorHInclude });
|
||||
tokenReplacements.insert ({"%%editor_headers%%", getJuceHeaderInclude() + newLine + processorHInclude });
|
||||
|
||||
return tokenReplacements;
|
||||
}
|
||||
|
||||
static bool addFiles (Project& project, const NewProjectTemplates::ProjectTemplate& projectTemplate,
|
||||
const String& name, var fileOptionsVar, StringArray& failedFiles)
|
||||
{
|
||||
auto sourceFolder = project.getFile().getSiblingFile ("Source");
|
||||
|
||||
if (! sourceFolder.createDirectory())
|
||||
{
|
||||
failedFiles.add (sourceFolder.getFullPathName());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto fileOptions = NewProjectTemplates::getFileOptionForVar (fileOptionsVar);
|
||||
|
||||
if (fileOptions == Opts::noFiles)
|
||||
return true;
|
||||
|
||||
auto tokenReplacements = [&]() -> std::map<String, String>
|
||||
{
|
||||
if (NewProjectTemplates::isApplication (projectTemplate))
|
||||
return getApplicationFileTokenReplacements (name, fileOptions, sourceFolder);
|
||||
|
||||
if (NewProjectTemplates::isPlugin (projectTemplate))
|
||||
return getPluginFileTokenReplacements (name, sourceFolder);
|
||||
|
||||
jassertfalse;
|
||||
return {};
|
||||
}();
|
||||
|
||||
auto sourceGroup = project.getMainGroup().getOrCreateSubGroup ("Source");
|
||||
|
||||
for (auto& files : projectTemplate.getFilesForOption (fileOptions))
|
||||
{
|
||||
auto file = sourceFolder.getChildFile (files.first);
|
||||
auto fileContent = getFileTemplate (files.second);
|
||||
|
||||
for (auto& tokenReplacement : tokenReplacements)
|
||||
fileContent = fileContent.replace (tokenReplacement.first, tokenReplacement.second, false);
|
||||
|
||||
if (! build_tools::overwriteFileWithNewDataIfDifferent (file, fileContent))
|
||||
{
|
||||
failedFiles.add (file.getFullPathName());
|
||||
return false;
|
||||
}
|
||||
|
||||
sourceGroup.addFileAtIndex (file, -1, (file.hasFileExtension (sourceFileExtensions)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void addModules (Project& project, Array<var> modules, const String& modulePath, bool useGlobalPath)
|
||||
{
|
||||
AvailableModulesList list;
|
||||
list.scanPaths ({ modulePath });
|
||||
|
||||
auto& projectModules = project.getEnabledModules();
|
||||
|
||||
for (auto& mod : list.getAllModules())
|
||||
if (modules.contains (mod.first))
|
||||
projectModules.addModule (mod.second, false, useGlobalPath);
|
||||
|
||||
for (auto& mod : projectModules.getModulesWithMissingDependencies())
|
||||
projectModules.tryToFixMissingDependencies (mod);
|
||||
}
|
||||
|
||||
static void addExporters (Project& project, Array<var> exporters)
|
||||
{
|
||||
for (auto exporter : exporters)
|
||||
project.addNewExporter (exporter.toString());
|
||||
|
||||
for (Project::ExporterIterator exporter (project); exporter.next();)
|
||||
for (ProjectExporter::ConfigIterator config (*exporter); config.next();)
|
||||
config->getValue (Ids::targetName) = project.getProjectFilenameRootString();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
File NewProjectWizard::getLastWizardFolder()
|
||||
{
|
||||
if (getAppSettings().lastWizardFolder.isDirectory())
|
||||
return getAppSettings().lastWizardFolder;
|
||||
|
||||
#if JUCE_WINDOWS
|
||||
static File lastFolderFallback (File::getSpecialLocation (File::userDocumentsDirectory));
|
||||
#else
|
||||
static File lastFolderFallback (File::getSpecialLocation (File::userHomeDirectory));
|
||||
#endif
|
||||
|
||||
return lastFolderFallback;
|
||||
}
|
||||
|
||||
static void displayFailedFilesMessage (const StringArray& failedFiles)
|
||||
{
|
||||
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
|
||||
TRANS("Errors in Creating Project!"),
|
||||
TRANS("The following files couldn't be written:")
|
||||
+ "\n\n"
|
||||
+ failedFiles.joinIntoString ("\n", 0, 10));
|
||||
}
|
||||
|
||||
template <typename Callback>
|
||||
static void prepareDirectory (const File& targetFolder, Callback&& callback)
|
||||
{
|
||||
StringArray failedFiles;
|
||||
|
||||
if (! targetFolder.exists())
|
||||
{
|
||||
if (! targetFolder.createDirectory())
|
||||
{
|
||||
displayFailedFilesMessage ({ targetFolder.getFullPathName() });
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (FileHelpers::containsAnyNonHiddenFiles (targetFolder))
|
||||
{
|
||||
AlertWindow::showOkCancelBox (MessageBoxIconType::InfoIcon,
|
||||
TRANS("New JUCE Project"),
|
||||
TRANS("You chose the folder:\n\nXFLDRX\n\n").replace ("XFLDRX", targetFolder.getFullPathName())
|
||||
+ TRANS("This folder isn't empty - are you sure you want to create the project there?")
|
||||
+ "\n\n"
|
||||
+ TRANS("Any existing files with the same names may be overwritten by the new files."),
|
||||
{},
|
||||
{},
|
||||
nullptr,
|
||||
ModalCallbackFunction::create ([callback] (int result)
|
||||
{
|
||||
if (result != 0)
|
||||
callback();
|
||||
}));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
callback();
|
||||
}
|
||||
|
||||
void NewProjectWizard::createNewProject (const NewProjectTemplates::ProjectTemplate& projectTemplate,
|
||||
const File& targetFolder, const String& name, var modules, var exporters, var fileOptions,
|
||||
const String& modulePath, bool useGlobalModulePath,
|
||||
std::function<void (std::unique_ptr<Project>)> callback)
|
||||
{
|
||||
prepareDirectory (targetFolder, [=]
|
||||
{
|
||||
auto project = std::make_unique<Project> (targetFolder.getChildFile (File::createLegalFileName (name))
|
||||
.withFileExtension (Project::projectFileExtension));
|
||||
|
||||
doBasicProjectSetup (*project, projectTemplate, name);
|
||||
|
||||
StringArray failedFiles;
|
||||
|
||||
if (addFiles (*project, projectTemplate, name, fileOptions, failedFiles))
|
||||
{
|
||||
addExporters (*project, *exporters.getArray());
|
||||
addModules (*project, *modules.getArray(), modulePath, useGlobalModulePath);
|
||||
|
||||
auto sharedProject = std::make_shared<std::unique_ptr<Project>> (std::move (project));
|
||||
(*sharedProject)->saveAsync (false, true, [sharedProject, failedFiles, callback] (FileBasedDocument::SaveResult r)
|
||||
{
|
||||
auto uniqueProject = std::move (*sharedProject.get());
|
||||
|
||||
if (r == FileBasedDocument::savedOk)
|
||||
{
|
||||
uniqueProject->setChangedFlag (false);
|
||||
uniqueProject->loadFrom (uniqueProject->getFile(), true);
|
||||
callback (std::move (uniqueProject));
|
||||
return;
|
||||
}
|
||||
|
||||
auto failedFilesCopy = failedFiles;
|
||||
failedFilesCopy.add (uniqueProject->getFile().getFullPathName());
|
||||
displayFailedFilesMessage (failedFilesCopy);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
displayFailedFilesMessage (failedFiles);
|
||||
});
|
||||
}
|
39
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.h
vendored
Normal file
39
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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
|
||||
|
||||
#include "jucer_NewProjectTemplates.h"
|
||||
|
||||
//==============================================================================
|
||||
namespace NewProjectWizard
|
||||
{
|
||||
File getLastWizardFolder();
|
||||
|
||||
void createNewProject (const NewProjectTemplates::ProjectTemplate& projectTemplate,
|
||||
const File& targetFolder, const String& name, var modules, var exporters, var fileOptions,
|
||||
const String& modulePath, bool useGlobalModulePath,
|
||||
std::function<void (std::unique_ptr<Project>)> callback);
|
||||
}
|
288
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.cpp
vendored
Normal file
288
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.cpp
vendored
Normal file
@ -0,0 +1,288 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../jucer_Headers.h"
|
||||
#include "../jucer_Application.h"
|
||||
|
||||
#include "jucer_StartPageComponent.h"
|
||||
#include "jucer_StartPageTreeHolder.h"
|
||||
#include "jucer_NewProjectTemplates.h"
|
||||
#include "jucer_ContentComponents.h"
|
||||
|
||||
//==============================================================================
|
||||
struct ContentComponent : public Component
|
||||
{
|
||||
ContentComponent()
|
||||
{
|
||||
setTitle ("Content");
|
||||
setFocusContainerType (FocusContainerType::focusContainer);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
if (content != nullptr)
|
||||
content->setBounds (getLocalBounds());
|
||||
}
|
||||
|
||||
void setContent (std::unique_ptr<Component>&& newContent)
|
||||
{
|
||||
if (content.get() != newContent.get())
|
||||
{
|
||||
content = std::move (newContent);
|
||||
addAndMakeVisible (content.get());
|
||||
resized();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Component> content;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_LEAK_DETECTOR (ContentComponent)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
static File findExampleFile (int dirIndex, int index)
|
||||
{
|
||||
auto dir = ProjucerApplication::getSortedExampleDirectories()[dirIndex];
|
||||
return ProjucerApplication::getSortedExampleFilesInDirectory (dir)[index];
|
||||
}
|
||||
|
||||
static std::unique_ptr<Component> createExampleProjectsTab (ContentComponent& content, std::function<void (const File&)> cb)
|
||||
{
|
||||
StringArray exampleCategories;
|
||||
std::vector<StringArray> examples;
|
||||
|
||||
for (auto& dir : ProjucerApplication::getSortedExampleDirectories())
|
||||
{
|
||||
exampleCategories.add (dir.getFileName());
|
||||
|
||||
StringArray ex;
|
||||
for (auto& f : ProjucerApplication::getSortedExampleFilesInDirectory (dir))
|
||||
ex.add (f.getFileNameWithoutExtension());
|
||||
|
||||
examples.push_back (ex);
|
||||
}
|
||||
|
||||
if (exampleCategories.isEmpty())
|
||||
return nullptr;
|
||||
|
||||
auto selectedCallback = [&, cb] (int category, int index) mutable
|
||||
{
|
||||
content.setContent (std::make_unique<ExampleComponent> (findExampleFile (category, index), cb));
|
||||
};
|
||||
|
||||
return std::make_unique<StartPageTreeHolder> ("Examples",
|
||||
exampleCategories,
|
||||
examples,
|
||||
std::move (selectedCallback),
|
||||
StartPageTreeHolder::Open::no);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static StringArray getAllTemplateCategoryStrings()
|
||||
{
|
||||
StringArray categories;
|
||||
|
||||
for (auto& t : NewProjectTemplates::getAllTemplates())
|
||||
categories.addIfNotAlreadyThere (NewProjectTemplates::getProjectCategoryString (t.category));
|
||||
|
||||
return categories;
|
||||
}
|
||||
|
||||
static std::vector<NewProjectTemplates::ProjectTemplate> getTemplatesInCategory (const String& category)
|
||||
{
|
||||
std::vector<NewProjectTemplates::ProjectTemplate> templates;
|
||||
|
||||
for (auto& t : NewProjectTemplates::getAllTemplates())
|
||||
if (NewProjectTemplates::getProjectCategoryString (t.category) == category)
|
||||
templates.push_back (t);
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
static StringArray getAllTemplateNamesForCategory (const String& category)
|
||||
{
|
||||
StringArray types;
|
||||
|
||||
for (auto& t : getTemplatesInCategory (category))
|
||||
types.add (t.displayName);
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
static std::unique_ptr<Component> createProjectTemplatesTab (ContentComponent& content,
|
||||
std::function<void (std::unique_ptr<Project>&&)>&& cb)
|
||||
{
|
||||
auto categories = getAllTemplateCategoryStrings();
|
||||
|
||||
std::vector<StringArray> templateNames;
|
||||
|
||||
for (auto& c : categories)
|
||||
templateNames.push_back (getAllTemplateNamesForCategory (c));
|
||||
|
||||
auto selectedCallback = [&, cb] (int category, int index)
|
||||
{
|
||||
auto categoryString = getAllTemplateCategoryStrings()[category];
|
||||
auto templates = getTemplatesInCategory (categoryString);
|
||||
|
||||
content.setContent (std::make_unique<TemplateComponent> (templates[(size_t) index], std::move (cb)));
|
||||
};
|
||||
|
||||
auto holder = std::make_unique<StartPageTreeHolder> ("Templates",
|
||||
categories,
|
||||
templateNames,
|
||||
std::move (selectedCallback),
|
||||
StartPageTreeHolder::Open::yes);
|
||||
holder->setSelectedItem (categories[0], 1);
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wredundant-move")
|
||||
return std::move (holder);
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct ProjectTemplatesAndExamples : public TabbedComponent
|
||||
{
|
||||
ProjectTemplatesAndExamples (ContentComponent& c,
|
||||
std::function<void (std::unique_ptr<Project>&&)>&& newProjectCb,
|
||||
std::function<void (const File&)>&& exampleCb)
|
||||
: TabbedComponent (TabbedButtonBar::Orientation::TabsAtTop),
|
||||
content (c),
|
||||
exampleSelectedCallback (std::move (exampleCb))
|
||||
{
|
||||
setTitle ("Templates and Examples");
|
||||
setFocusContainerType (FocusContainerType::focusContainer);
|
||||
|
||||
addTab ("New Project",
|
||||
Colours::transparentBlack,
|
||||
createProjectTemplatesTab (content, std::move (newProjectCb)).release(),
|
||||
true);
|
||||
|
||||
refreshExamplesTab();
|
||||
}
|
||||
|
||||
void refreshExamplesTab()
|
||||
{
|
||||
auto wasOpen = (getCurrentTabIndex() == 1);
|
||||
|
||||
removeTab (1);
|
||||
|
||||
auto exampleTabs = createExampleProjectsTab (content, exampleSelectedCallback);
|
||||
|
||||
addTab ("Open Example",
|
||||
Colours::transparentBlack,
|
||||
exampleTabs == nullptr ? new SetJUCEPathComponent (*this) : exampleTabs.release(),
|
||||
true);
|
||||
|
||||
if (wasOpen)
|
||||
setCurrentTabIndex (1);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
struct SetJUCEPathComponent : public Component,
|
||||
private ChangeListener
|
||||
{
|
||||
explicit SetJUCEPathComponent (ProjectTemplatesAndExamples& o)
|
||||
: owner (o)
|
||||
{
|
||||
getGlobalProperties().addChangeListener (this);
|
||||
|
||||
setPathButton.setButtonText ("Set path to JUCE...");
|
||||
setPathButton.onClick = [] { ProjucerApplication::getApp().showPathsWindow (true); };
|
||||
|
||||
addAndMakeVisible (setPathButton);
|
||||
}
|
||||
|
||||
~SetJUCEPathComponent() override
|
||||
{
|
||||
getGlobalProperties().removeChangeListener (this);
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (secondaryBackgroundColourId));
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto bounds = getLocalBounds().reduced (5);
|
||||
bounds.removeFromTop (25);
|
||||
|
||||
setPathButton.setBounds (bounds.removeFromTop (25));
|
||||
}
|
||||
|
||||
private:
|
||||
void changeListenerCallback (ChangeBroadcaster*) override
|
||||
{
|
||||
if (isValidJUCEExamplesDirectory (ProjucerApplication::getJUCEExamplesDirectoryPathFromGlobal()))
|
||||
owner.refreshExamplesTab();
|
||||
}
|
||||
|
||||
ProjectTemplatesAndExamples& owner;
|
||||
TextButton setPathButton;
|
||||
};
|
||||
|
||||
ContentComponent& content;
|
||||
std::function<void (const File&)> exampleSelectedCallback;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
StartPageComponent::StartPageComponent (std::function<void (std::unique_ptr<Project>&&)>&& newProjectCb,
|
||||
std::function<void (const File&)>&& exampleCb)
|
||||
: content (std::make_unique<ContentComponent>()),
|
||||
tabs (std::make_unique<ProjectTemplatesAndExamples> (*content, std::move (newProjectCb), std::move (exampleCb)))
|
||||
{
|
||||
tabs->setOutline (0);
|
||||
addAndMakeVisible (*tabs);
|
||||
|
||||
addAndMakeVisible (openExistingButton);
|
||||
openExistingButton.setCommandToTrigger (&ProjucerApplication::getCommandManager(), CommandIDs::open, true);
|
||||
|
||||
addAndMakeVisible (*content);
|
||||
|
||||
setSize (900, 600);
|
||||
}
|
||||
|
||||
void StartPageComponent::paint (Graphics& g)
|
||||
{
|
||||
g.fillAll (findColour (backgroundColourId));
|
||||
}
|
||||
|
||||
void StartPageComponent::resized()
|
||||
{
|
||||
auto bounds = getLocalBounds().reduced (10);
|
||||
|
||||
auto tabBounds = bounds.removeFromLeft (bounds.getWidth() / 3);
|
||||
|
||||
openExistingButton.setBounds (tabBounds.removeFromBottom (30).reduced (10, 0));
|
||||
tabBounds.removeFromBottom (5);
|
||||
|
||||
tabs->setBounds (tabBounds);
|
||||
bounds.removeFromLeft (10);
|
||||
|
||||
content->setBounds (bounds);
|
||||
}
|
50
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.h
vendored
Normal file
50
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.h
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 ContentComponent;
|
||||
struct ProjectTemplatesAndExamples;
|
||||
|
||||
//==============================================================================
|
||||
class StartPageComponent : public Component
|
||||
{
|
||||
public:
|
||||
StartPageComponent (std::function<void (std::unique_ptr<Project>&&)>&& newProjectCb,
|
||||
std::function<void (const File&)>&& exampleCb);
|
||||
|
||||
void paint (Graphics& g) override;
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
std::unique_ptr<ContentComponent> content;
|
||||
std::unique_ptr<ProjectTemplatesAndExamples> tabs;
|
||||
|
||||
TextButton openExistingButton { "Open Existing Project..." };
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StartPageComponent)
|
||||
};
|
182
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_StartPageTreeHolder.h
vendored
Normal file
182
deps/juce/extras/Projucer/Source/Application/StartPage/jucer_StartPageTreeHolder.h
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 StartPageTreeHolder : public Component
|
||||
{
|
||||
public:
|
||||
enum class Open { no, yes };
|
||||
|
||||
StartPageTreeHolder (const String& title,
|
||||
const StringArray& headerNames,
|
||||
const std::vector<StringArray>& itemNames,
|
||||
std::function<void (int, int)>&& selectedCallback,
|
||||
Open shouldBeOpen)
|
||||
: headers (headerNames),
|
||||
items (itemNames),
|
||||
itemSelectedCallback (std::move (selectedCallback))
|
||||
{
|
||||
jassert (headers.size() == (int) items.size());
|
||||
|
||||
tree.setTitle (title);
|
||||
tree.setRootItem (new TreeRootItem (*this));
|
||||
tree.setRootItemVisible (false);
|
||||
tree.setIndentSize (15);
|
||||
tree.setDefaultOpenness (shouldBeOpen == Open::yes);
|
||||
|
||||
addAndMakeVisible (tree);
|
||||
}
|
||||
|
||||
~StartPageTreeHolder() override
|
||||
{
|
||||
tree.deleteRootItem();
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (secondaryBackgroundColourId));
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
tree.setBounds (getLocalBounds());
|
||||
}
|
||||
|
||||
void setSelectedItem (const String& category, int index)
|
||||
{
|
||||
auto* root = tree.getRootItem();
|
||||
|
||||
for (int i = root->getNumSubItems(); --i >=0;)
|
||||
{
|
||||
if (auto* item = root->getSubItem (i))
|
||||
{
|
||||
if (item->getUniqueName() == category)
|
||||
item->getSubItem (index)->setSelected (true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class TreeSubItem : public TreeViewItem
|
||||
{
|
||||
public:
|
||||
TreeSubItem (StartPageTreeHolder& o, const String& n, const StringArray& subItemsIn)
|
||||
: owner (o), name (n), isHeader (subItemsIn.size() > 0)
|
||||
{
|
||||
for (auto& s : subItemsIn)
|
||||
addSubItem (new TreeSubItem (owner, s, {}));
|
||||
}
|
||||
|
||||
bool mightContainSubItems() override { return isHeader; }
|
||||
bool canBeSelected() const override { return ! isHeader; }
|
||||
|
||||
int getItemWidth() const override { return -1; }
|
||||
int getItemHeight() const override { return 25; }
|
||||
|
||||
String getUniqueName() const override { return name; }
|
||||
String getAccessibilityName() override { return getUniqueName(); }
|
||||
|
||||
void paintOpenCloseButton (Graphics& g, const Rectangle<float>& area, Colour, bool isMouseOver) override
|
||||
{
|
||||
g.setColour (getOwnerView()->findColour (isSelected() ? defaultHighlightedTextColourId
|
||||
: treeIconColourId));
|
||||
|
||||
TreeViewItem::paintOpenCloseButton (g, area, getOwnerView()->findColour (defaultIconColourId), isMouseOver);
|
||||
}
|
||||
|
||||
void paintItem (Graphics& g, int w, int h) override
|
||||
{
|
||||
Rectangle<int> bounds (w, h);
|
||||
|
||||
auto shouldBeHighlighted = isSelected();
|
||||
|
||||
if (shouldBeHighlighted)
|
||||
{
|
||||
g.setColour (getOwnerView()->findColour (defaultHighlightColourId));
|
||||
g.fillRect (bounds);
|
||||
}
|
||||
|
||||
g.setColour (shouldBeHighlighted ? getOwnerView()->findColour (defaultHighlightedTextColourId)
|
||||
: getOwnerView()->findColour (defaultTextColourId));
|
||||
|
||||
g.drawFittedText (name, bounds.reduced (5).withTrimmedLeft (10), Justification::centredLeft, 1);
|
||||
}
|
||||
|
||||
void itemClicked (const MouseEvent& e) override
|
||||
{
|
||||
if (isSelected())
|
||||
itemSelectionChanged (true);
|
||||
|
||||
if (e.mods.isPopupMenu() && mightContainSubItems())
|
||||
setOpen (! isOpen());
|
||||
}
|
||||
|
||||
void itemSelectionChanged (bool isNowSelected) override
|
||||
{
|
||||
jassert (! isHeader);
|
||||
|
||||
if (isNowSelected)
|
||||
owner.itemSelectedCallback (getParentItem()->getIndexInParent(), getIndexInParent());
|
||||
}
|
||||
|
||||
private:
|
||||
StartPageTreeHolder& owner;
|
||||
String name;
|
||||
bool isHeader = false;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TreeSubItem)
|
||||
};
|
||||
|
||||
struct TreeRootItem : public TreeViewItem
|
||||
{
|
||||
explicit TreeRootItem (StartPageTreeHolder& o)
|
||||
: owner (o)
|
||||
{
|
||||
for (int i = 0; i < owner.headers.size(); ++i)
|
||||
addSubItem (new TreeSubItem (owner, owner.headers[i], owner.items[(size_t) i]));
|
||||
}
|
||||
|
||||
bool mightContainSubItems() override { return ! owner.headers.isEmpty();}
|
||||
|
||||
StartPageTreeHolder& owner;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TreeRootItem)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
TreeView tree;
|
||||
StringArray headers;
|
||||
std::vector<StringArray> items;
|
||||
|
||||
std::function<void (int, int)> itemSelectedCallback;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StartPageTreeHolder)
|
||||
};
|
Reference in New Issue
Block a user