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"
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
@ -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
@ -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
@ -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
@ -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
@ -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
@ -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)
|
||||
};
|
224
deps/juce/extras/Projucer/Source/Application/UserAccount/jucer_LicenseController.h
vendored
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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_LicenseState.h"
|
||||
#include "jucer_LicenseQueryThread.h"
|
||||
|
||||
//==============================================================================
|
||||
class LicenseController : private Timer
|
||||
{
|
||||
public:
|
||||
LicenseController()
|
||||
{
|
||||
checkLicense();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static LicenseState getGPLState()
|
||||
{
|
||||
return { LicenseState::Type::gpl, projucerMajorVersion, {}, {} };
|
||||
}
|
||||
|
||||
LicenseState getCurrentState() const noexcept
|
||||
{
|
||||
return state;
|
||||
}
|
||||
|
||||
void setState (const LicenseState& newState)
|
||||
{
|
||||
if (state != newState)
|
||||
{
|
||||
state = newState;
|
||||
licenseStateToSettings (state, getGlobalProperties());
|
||||
|
||||
stateListeners.call ([] (LicenseStateListener& l) { l.licenseStateChanged(); });
|
||||
}
|
||||
}
|
||||
|
||||
void resetState()
|
||||
{
|
||||
setState ({});
|
||||
}
|
||||
|
||||
void signIn (const String& email, const String& password,
|
||||
std::function<void (const String&)> completionCallback)
|
||||
{
|
||||
licenseQueryThread.doSignIn (email, password,
|
||||
[this, completionCallback] (LicenseQueryThread::ErrorMessageAndType error,
|
||||
LicenseState newState)
|
||||
{
|
||||
completionCallback (error.first);
|
||||
setState (newState);
|
||||
});
|
||||
}
|
||||
|
||||
void cancelSignIn()
|
||||
{
|
||||
licenseQueryThread.cancelRunningJobs();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct LicenseStateListener
|
||||
{
|
||||
virtual ~LicenseStateListener() = default;
|
||||
virtual void licenseStateChanged() = 0;
|
||||
};
|
||||
|
||||
void addListener (LicenseStateListener* listenerToAdd)
|
||||
{
|
||||
stateListeners.add (listenerToAdd);
|
||||
}
|
||||
|
||||
void removeListener (LicenseStateListener* listenerToRemove)
|
||||
{
|
||||
stateListeners.remove (listenerToRemove);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
static const char* getLicenseStateValue (LicenseState::Type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case LicenseState::Type::gpl: return "GPL";
|
||||
case LicenseState::Type::personal: return "personal";
|
||||
case LicenseState::Type::educational: return "edu";
|
||||
case LicenseState::Type::indie: return "indie";
|
||||
case LicenseState::Type::pro: return "pro";
|
||||
case LicenseState::Type::none:
|
||||
default: break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static LicenseState::Type getLicenseTypeFromValue (const String& d)
|
||||
{
|
||||
if (d == getLicenseStateValue (LicenseState::Type::gpl)) return LicenseState::Type::gpl;
|
||||
if (d == getLicenseStateValue (LicenseState::Type::personal)) return LicenseState::Type::personal;
|
||||
if (d == getLicenseStateValue (LicenseState::Type::educational)) return LicenseState::Type::educational;
|
||||
if (d == getLicenseStateValue (LicenseState::Type::indie)) return LicenseState::Type::indie;
|
||||
if (d == getLicenseStateValue (LicenseState::Type::pro)) return LicenseState::Type::pro;
|
||||
return LicenseState::Type::none;
|
||||
}
|
||||
|
||||
static LicenseState licenseStateFromSettings (PropertiesFile& props)
|
||||
{
|
||||
if (auto licenseXml = props.getXmlValue ("license"))
|
||||
{
|
||||
// this is here for backwards compatibility with old-style settings files using XML text elements
|
||||
if (licenseXml->getChildElementAllSubText ("type", {}).isNotEmpty())
|
||||
{
|
||||
auto stateFromOldSettings = [&licenseXml]() -> LicenseState
|
||||
{
|
||||
return { getLicenseTypeFromValue (licenseXml->getChildElementAllSubText ("type", {})),
|
||||
licenseXml->getChildElementAllSubText ("version", "-1").getIntValue(),
|
||||
licenseXml->getChildElementAllSubText ("username", {}),
|
||||
licenseXml->getChildElementAllSubText ("authToken", {}) };
|
||||
}();
|
||||
|
||||
licenseStateToSettings (stateFromOldSettings, props);
|
||||
|
||||
return stateFromOldSettings;
|
||||
}
|
||||
|
||||
return { getLicenseTypeFromValue (licenseXml->getStringAttribute ("type", {})),
|
||||
licenseXml->getIntAttribute ("version", -1),
|
||||
licenseXml->getStringAttribute ("username", {}),
|
||||
licenseXml->getStringAttribute ("authToken", {}) };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
static void licenseStateToSettings (const LicenseState& state, PropertiesFile& props)
|
||||
{
|
||||
props.removeValue ("license");
|
||||
|
||||
if (state.isSignedIn())
|
||||
{
|
||||
XmlElement licenseXml ("license");
|
||||
|
||||
if (auto* typeString = getLicenseStateValue (state.type))
|
||||
licenseXml.setAttribute ("type", typeString);
|
||||
|
||||
licenseXml.setAttribute ("version", state.version);
|
||||
licenseXml.setAttribute ("username", state.username);
|
||||
licenseXml.setAttribute ("authToken", state.authToken);
|
||||
|
||||
props.setValue ("license", &licenseXml);
|
||||
}
|
||||
|
||||
props.saveIfNeeded();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void checkLicense()
|
||||
{
|
||||
if (state.authToken.isNotEmpty() && ! state.isGPL())
|
||||
{
|
||||
auto completionCallback = [this] (LicenseQueryThread::ErrorMessageAndType error,
|
||||
LicenseState updatedState)
|
||||
{
|
||||
if (error == LicenseQueryThread::ErrorMessageAndType())
|
||||
{
|
||||
setState (updatedState);
|
||||
}
|
||||
else if ((error.second == LicenseQueryThread::ErrorType::busy
|
||||
|| error.second == LicenseQueryThread::ErrorType::cancelled
|
||||
|| error.second == LicenseQueryThread::ErrorType::connectionError)
|
||||
&& ! hasRetriedLicenseCheck)
|
||||
{
|
||||
hasRetriedLicenseCheck = true;
|
||||
startTimer (10000);
|
||||
}
|
||||
};
|
||||
|
||||
licenseQueryThread.checkLicenseValidity (state, std::move (completionCallback));
|
||||
}
|
||||
}
|
||||
|
||||
void timerCallback() override
|
||||
{
|
||||
stopTimer();
|
||||
checkLicense();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if JUCER_ENABLE_GPL_MODE
|
||||
LicenseState state = getGPLState();
|
||||
#else
|
||||
LicenseState state = licenseStateFromSettings (getGlobalProperties());
|
||||
#endif
|
||||
|
||||
ListenerList<LicenseStateListener> stateListeners;
|
||||
LicenseQueryThread licenseQueryThread;
|
||||
bool hasRetriedLicenseCheck = false;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LicenseController)
|
||||
};
|
371
deps/juce/extras/Projucer/Source/Application/UserAccount/jucer_LicenseQueryThread.h
vendored
Normal file
@ -0,0 +1,371 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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
|
||||
|
||||
//==============================================================================
|
||||
namespace LicenseHelpers
|
||||
{
|
||||
inline LicenseState::Type licenseTypeForString (const String& licenseString)
|
||||
{
|
||||
if (licenseString == "juce-pro") return LicenseState::Type::pro;
|
||||
if (licenseString == "juce-indie") return LicenseState::Type::indie;
|
||||
if (licenseString == "juce-edu") return LicenseState::Type::educational;
|
||||
if (licenseString == "juce-personal") return LicenseState::Type::personal;
|
||||
|
||||
jassertfalse; // unknown type
|
||||
return LicenseState::Type::none;
|
||||
}
|
||||
|
||||
using LicenseVersionAndType = std::pair<int, LicenseState::Type>;
|
||||
|
||||
inline LicenseVersionAndType findBestLicense (std::vector<LicenseVersionAndType>&& licenses)
|
||||
{
|
||||
if (licenses.size() == 1)
|
||||
return licenses[0];
|
||||
|
||||
auto getValueForLicenceType = [] (LicenseState::Type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case LicenseState::Type::pro: return 4;
|
||||
case LicenseState::Type::indie: return 3;
|
||||
case LicenseState::Type::educational: return 2;
|
||||
case LicenseState::Type::personal: return 1;
|
||||
case LicenseState::Type::gpl:
|
||||
case LicenseState::Type::none:
|
||||
default: return -1;
|
||||
}
|
||||
};
|
||||
|
||||
std::sort (licenses.begin(), licenses.end(),
|
||||
[getValueForLicenceType] (const LicenseVersionAndType& l1, const LicenseVersionAndType& l2)
|
||||
{
|
||||
if (l1.first > l2.first)
|
||||
return true;
|
||||
|
||||
if (l1.first == l2.first)
|
||||
return getValueForLicenceType (l1.second) > getValueForLicenceType (l2.second);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
auto findFirstLicense = [&licenses] (bool isPaid)
|
||||
{
|
||||
auto iter = std::find_if (licenses.begin(), licenses.end(),
|
||||
[isPaid] (const LicenseVersionAndType& l)
|
||||
{
|
||||
auto proOrIndie = (l.second == LicenseState::Type::pro || l.second == LicenseState::Type::indie);
|
||||
return isPaid ? proOrIndie : ! proOrIndie;
|
||||
});
|
||||
|
||||
return iter != licenses.end() ? *iter
|
||||
: LicenseVersionAndType();
|
||||
};
|
||||
|
||||
auto newestPaid = findFirstLicense (true);
|
||||
auto newestFree = findFirstLicense (false);
|
||||
|
||||
if (newestPaid.first >= projucerMajorVersion || newestPaid.first >= newestFree.first)
|
||||
return newestPaid;
|
||||
|
||||
return newestFree;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class LicenseQueryThread
|
||||
{
|
||||
public:
|
||||
enum class ErrorType
|
||||
{
|
||||
busy,
|
||||
cancelled,
|
||||
connectionError,
|
||||
webResponseError
|
||||
};
|
||||
|
||||
using ErrorMessageAndType = std::pair<String, ErrorType>;
|
||||
using LicenseQueryCallback = std::function<void (ErrorMessageAndType, LicenseState)>;
|
||||
|
||||
//==============================================================================
|
||||
LicenseQueryThread() = default;
|
||||
|
||||
void checkLicenseValidity (const LicenseState& state, LicenseQueryCallback completionCallback)
|
||||
{
|
||||
if (jobPool.getNumJobs() > 0)
|
||||
{
|
||||
completionCallback ({ {}, ErrorType::busy }, {});
|
||||
return;
|
||||
}
|
||||
|
||||
jobPool.addJob ([this, state, completionCallback]
|
||||
{
|
||||
auto updatedState = state;
|
||||
|
||||
auto result = runTask (std::make_unique<UserLicenseQuery> (state.authToken), updatedState);
|
||||
|
||||
WeakReference<LicenseQueryThread> weakThis (this);
|
||||
MessageManager::callAsync ([weakThis, result, updatedState, completionCallback]
|
||||
{
|
||||
if (weakThis != nullptr)
|
||||
completionCallback (result, updatedState);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void doSignIn (const String& email, const String& password, LicenseQueryCallback completionCallback)
|
||||
{
|
||||
cancelRunningJobs();
|
||||
|
||||
jobPool.addJob ([this, email, password, completionCallback]
|
||||
{
|
||||
LicenseState state;
|
||||
|
||||
auto result = runTask (std::make_unique<UserLogin> (email, password), state);
|
||||
|
||||
if (result == ErrorMessageAndType())
|
||||
result = runTask (std::make_unique<UserLicenseQuery> (state.authToken), state);
|
||||
|
||||
if (result != ErrorMessageAndType())
|
||||
state = {};
|
||||
|
||||
WeakReference<LicenseQueryThread> weakThis (this);
|
||||
MessageManager::callAsync ([weakThis, result, state, completionCallback]
|
||||
{
|
||||
if (weakThis != nullptr)
|
||||
completionCallback (result, state);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void cancelRunningJobs()
|
||||
{
|
||||
jobPool.removeAllJobs (true, 500);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
struct AccountEnquiryBase
|
||||
{
|
||||
virtual ~AccountEnquiryBase() = default;
|
||||
|
||||
virtual bool isPOSTLikeRequest() const = 0;
|
||||
virtual String getEndpointURLSuffix() const = 0;
|
||||
virtual StringPairArray getParameterNamesAndValues() const = 0;
|
||||
virtual String getExtraHeaders() const = 0;
|
||||
virtual int getSuccessCode() const = 0;
|
||||
virtual String errorCodeToString (int) const = 0;
|
||||
virtual bool parseServerResponse (const String&, LicenseState&) = 0;
|
||||
};
|
||||
|
||||
struct UserLogin : public AccountEnquiryBase
|
||||
{
|
||||
UserLogin (const String& e, const String& p)
|
||||
: userEmail (e), userPassword (p)
|
||||
{
|
||||
}
|
||||
|
||||
bool isPOSTLikeRequest() const override { return true; }
|
||||
String getEndpointURLSuffix() const override { return "/authenticate/projucer"; }
|
||||
int getSuccessCode() const override { return 200; }
|
||||
|
||||
StringPairArray getParameterNamesAndValues() const override
|
||||
{
|
||||
StringPairArray namesAndValues;
|
||||
namesAndValues.set ("email", userEmail);
|
||||
namesAndValues.set ("password", userPassword);
|
||||
|
||||
return namesAndValues;
|
||||
}
|
||||
|
||||
String getExtraHeaders() const override
|
||||
{
|
||||
return "Content-Type: application/json";
|
||||
}
|
||||
|
||||
String errorCodeToString (int errorCode) const override
|
||||
{
|
||||
switch (errorCode)
|
||||
{
|
||||
case 400: return "Please enter your email and password to sign in.";
|
||||
case 401: return "Your email and password are incorrect.";
|
||||
case 451: return "Access denied.";
|
||||
default: return "Something went wrong, please try again.";
|
||||
}
|
||||
}
|
||||
|
||||
bool parseServerResponse (const String& serverResponse, LicenseState& licenseState) override
|
||||
{
|
||||
auto json = JSON::parse (serverResponse);
|
||||
|
||||
licenseState.authToken = json.getProperty ("token", {}).toString();
|
||||
licenseState.username = json.getProperty ("user", {}).getProperty ("username", {}).toString();
|
||||
|
||||
return (licenseState.authToken.isNotEmpty() && licenseState.username.isNotEmpty());
|
||||
}
|
||||
|
||||
String userEmail, userPassword;
|
||||
};
|
||||
|
||||
struct UserLicenseQuery : public AccountEnquiryBase
|
||||
{
|
||||
UserLicenseQuery (const String& authToken)
|
||||
: userAuthToken (authToken)
|
||||
{
|
||||
}
|
||||
|
||||
bool isPOSTLikeRequest() const override { return false; }
|
||||
String getEndpointURLSuffix() const override { return "/user/licences/projucer"; }
|
||||
int getSuccessCode() const override { return 200; }
|
||||
|
||||
StringPairArray getParameterNamesAndValues() const override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
String getExtraHeaders() const override
|
||||
{
|
||||
return "x-access-token: " + userAuthToken;
|
||||
}
|
||||
|
||||
String errorCodeToString (int errorCode) const override
|
||||
{
|
||||
switch (errorCode)
|
||||
{
|
||||
case 401: return "User not found or could not be verified.";
|
||||
default: return "User licenses info fetch failed (unknown error).";
|
||||
}
|
||||
}
|
||||
|
||||
bool parseServerResponse (const String& serverResponse, LicenseState& licenseState) override
|
||||
{
|
||||
auto json = JSON::parse (serverResponse);
|
||||
|
||||
if (auto* licensesJson = json.getArray())
|
||||
{
|
||||
std::vector<LicenseHelpers::LicenseVersionAndType> licenses;
|
||||
|
||||
for (auto& license : *licensesJson)
|
||||
{
|
||||
auto version = license.getProperty ("product_version", {}).toString().trim();
|
||||
auto type = license.getProperty ("licence_type", {}).toString();
|
||||
auto status = license.getProperty ("status", {}).toString();
|
||||
|
||||
if (status == "active" && type.isNotEmpty() && version.isNotEmpty())
|
||||
licenses.push_back ({ version.getIntValue(), LicenseHelpers::licenseTypeForString (type) });
|
||||
}
|
||||
|
||||
if (! licenses.empty())
|
||||
{
|
||||
auto bestLicense = LicenseHelpers::findBestLicense (std::move (licenses));
|
||||
|
||||
licenseState.version = bestLicense.first;
|
||||
licenseState.type = bestLicense.second;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
String userAuthToken;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
static String postDataStringAsJSON (const StringPairArray& parameters)
|
||||
{
|
||||
DynamicObject::Ptr d (new DynamicObject());
|
||||
|
||||
for (auto& key : parameters.getAllKeys())
|
||||
d->setProperty (key, parameters[key]);
|
||||
|
||||
return JSON::toString (var (d.get()));
|
||||
}
|
||||
|
||||
static ErrorMessageAndType runTask (std::unique_ptr<AccountEnquiryBase> accountEnquiryTask, LicenseState& state)
|
||||
{
|
||||
const ErrorMessageAndType cancelledError ("Cancelled.", ErrorType::cancelled);
|
||||
const String endpointURL ("https://api.juce.com/api/v1");
|
||||
|
||||
URL url (endpointURL + accountEnquiryTask->getEndpointURLSuffix());
|
||||
|
||||
auto isPOST = accountEnquiryTask->isPOSTLikeRequest();
|
||||
|
||||
if (isPOST)
|
||||
url = url.withPOSTData (postDataStringAsJSON (accountEnquiryTask->getParameterNamesAndValues()));
|
||||
|
||||
if (ThreadPoolJob::getCurrentThreadPoolJob()->shouldExit())
|
||||
return cancelledError;
|
||||
|
||||
int statusCode = 0;
|
||||
auto urlStream = url.createInputStream (URL::InputStreamOptions (isPOST ? URL::ParameterHandling::inPostData
|
||||
: URL::ParameterHandling::inAddress)
|
||||
.withExtraHeaders (accountEnquiryTask->getExtraHeaders())
|
||||
.withConnectionTimeoutMs (5000)
|
||||
.withStatusCode (&statusCode));
|
||||
|
||||
if (urlStream == nullptr)
|
||||
return { "Failed to connect to the web server.", ErrorType::connectionError };
|
||||
|
||||
if (statusCode != accountEnquiryTask->getSuccessCode())
|
||||
return { accountEnquiryTask->errorCodeToString (statusCode), ErrorType::webResponseError };
|
||||
|
||||
if (ThreadPoolJob::getCurrentThreadPoolJob()->shouldExit())
|
||||
return cancelledError;
|
||||
|
||||
String response;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char buffer [8192] = "";
|
||||
auto num = urlStream->read (buffer, sizeof (buffer));
|
||||
|
||||
if (ThreadPoolJob::getCurrentThreadPoolJob()->shouldExit())
|
||||
return cancelledError;
|
||||
|
||||
if (num <= 0)
|
||||
break;
|
||||
|
||||
response += buffer;
|
||||
}
|
||||
|
||||
if (ThreadPoolJob::getCurrentThreadPoolJob()->shouldExit())
|
||||
return cancelledError;
|
||||
|
||||
if (! accountEnquiryTask->parseServerResponse (response, state))
|
||||
return { "Failed to parse server response.", ErrorType::webResponseError };
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ThreadPool jobPool { 1 };
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_WEAK_REFERENCEABLE (LicenseQueryThread)
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LicenseQueryThread)
|
||||
};
|
91
deps/juce/extras/Projucer/Source/Application/UserAccount/jucer_LicenseState.h
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 LicenseState
|
||||
{
|
||||
enum class Type
|
||||
{
|
||||
none,
|
||||
gpl,
|
||||
personal,
|
||||
educational,
|
||||
indie,
|
||||
pro
|
||||
};
|
||||
|
||||
LicenseState() = default;
|
||||
|
||||
LicenseState (Type t, int v, String user, String token)
|
||||
: type (t), version (v), username (user), authToken (token)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator== (const LicenseState& other) const noexcept
|
||||
{
|
||||
return type == other.type
|
||||
&& version == other.version
|
||||
&& username == other.username
|
||||
&& authToken == other.authToken;
|
||||
}
|
||||
|
||||
bool operator != (const LicenseState& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
bool isSignedIn() const noexcept { return isGPL() || (version > 0 && username.isNotEmpty()); }
|
||||
bool isOldLicense() const noexcept { return isSignedIn() && version < projucerMajorVersion; }
|
||||
bool isGPL() const noexcept { return type == Type::gpl; }
|
||||
|
||||
bool canUnlockFullFeatures() const noexcept
|
||||
{
|
||||
return isGPL() || (isSignedIn() && ! isOldLicense() && (type == Type::indie || type == Type::pro));
|
||||
}
|
||||
|
||||
String getLicenseTypeString() const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Type::none: return "No license";
|
||||
case Type::gpl: return "GPL";
|
||||
case Type::personal: return "Personal";
|
||||
case Type::educational: return "Educational";
|
||||
case Type::indie: return "Indie";
|
||||
case Type::pro: return "Pro";
|
||||
default: break;
|
||||
};
|
||||
|
||||
jassertfalse;
|
||||
return {};
|
||||
}
|
||||
|
||||
Type type = Type::none;
|
||||
int version = -1;
|
||||
String username, authToken;
|
||||
};
|
283
deps/juce/extras/Projucer/Source/Application/UserAccount/jucer_LoginFormComponent.h
vendored
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 "../../Project/UI/jucer_UserAvatarComponent.h"
|
||||
|
||||
//==============================================================================
|
||||
class LoginFormComponent : public Component
|
||||
{
|
||||
public:
|
||||
LoginFormComponent (MainWindow& window)
|
||||
: mainWindow (window)
|
||||
{
|
||||
setTitle ("Login");
|
||||
setFocusContainerType (FocusContainerType::focusContainer);
|
||||
|
||||
addAndMakeVisible (emailBox);
|
||||
emailBox.setTextToShowWhenEmpty ("Email", Colours::black.withAlpha (0.2f));
|
||||
emailBox.setJustification (Justification::centredLeft);
|
||||
emailBox.onReturnKey = [this] { submitDetails(); };
|
||||
emailBox.setTitle ("Email");
|
||||
|
||||
addAndMakeVisible (passwordBox);
|
||||
passwordBox.setTextToShowWhenEmpty ("Password", Colours::black.withAlpha (0.2f));
|
||||
passwordBox.setPasswordCharacter ((juce_wchar) 0x2022);
|
||||
passwordBox.setJustification (Justification::centredLeft);
|
||||
passwordBox.onReturnKey = [this] { submitDetails(); };
|
||||
passwordBox.setTitle ("Password");
|
||||
|
||||
addAndMakeVisible (logInButton);
|
||||
logInButton.onClick = [this] { submitDetails(); };
|
||||
|
||||
addAndMakeVisible (enableGPLButton);
|
||||
enableGPLButton.onClick = [this]
|
||||
{
|
||||
ProjucerApplication::getApp().getLicenseController().setState (LicenseController::getGPLState());
|
||||
mainWindow.hideLoginFormOverlay();
|
||||
};
|
||||
|
||||
addAndMakeVisible (userAvatar);
|
||||
|
||||
addAndMakeVisible (createAccountLabel);
|
||||
createAccountLabel.setFont (Font (14.0f, Font::underlined));
|
||||
createAccountLabel.addMouseListener (this, false);
|
||||
createAccountLabel.setMouseCursor (MouseCursor::PointingHandCursor);
|
||||
|
||||
addAndMakeVisible (errorMessageLabel);
|
||||
errorMessageLabel.setMinimumHorizontalScale (1.0f);
|
||||
errorMessageLabel.setFont (12.0f);
|
||||
errorMessageLabel.setColour (Label::textColourId, Colours::red);
|
||||
errorMessageLabel.setVisible (false);
|
||||
|
||||
dismissButton.setShape (getLookAndFeel().getCrossShape (1.0f), false, true, false);
|
||||
addAndMakeVisible (dismissButton);
|
||||
dismissButton.onClick = [this] { mainWindow.hideLoginFormOverlay(); };
|
||||
dismissButton.setTitle ("Dismiss");
|
||||
|
||||
setWantsKeyboardFocus (true);
|
||||
setOpaque (true);
|
||||
|
||||
lookAndFeelChanged();
|
||||
|
||||
setSize (300, 350);
|
||||
}
|
||||
|
||||
~LoginFormComponent() override
|
||||
{
|
||||
ProjucerApplication::getApp().getLicenseController().cancelSignIn();
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto bounds = getLocalBounds().reduced (20);
|
||||
auto spacing = bounds.getHeight() / 20;
|
||||
|
||||
userAvatar.setBounds (bounds.removeFromTop (iconHeight).reduced ((bounds.getWidth() / 2) - (iconHeight / 2), 0));
|
||||
|
||||
errorMessageLabel.setBounds (bounds.removeFromTop (spacing));
|
||||
bounds.removeFromTop (spacing / 2);
|
||||
|
||||
auto textEditorHeight = bounds.getHeight() / 5;
|
||||
|
||||
emailBox.setBounds (bounds.removeFromTop (textEditorHeight));
|
||||
bounds.removeFromTop (spacing);
|
||||
|
||||
passwordBox.setBounds (bounds.removeFromTop (textEditorHeight));
|
||||
bounds.removeFromTop (spacing * 2);
|
||||
|
||||
emailBox.setFont (Font ((float) textEditorHeight / 2.5f));
|
||||
passwordBox.setFont (Font ((float) textEditorHeight / 2.5f));
|
||||
|
||||
logInButton.setBounds (bounds.removeFromTop (textEditorHeight));
|
||||
|
||||
auto slice = bounds.removeFromTop (textEditorHeight);
|
||||
createAccountLabel.setBounds (slice.removeFromLeft (createAccountLabel.getFont().getStringWidth (createAccountLabel.getText()) + 5));
|
||||
slice.removeFromLeft (15);
|
||||
enableGPLButton.setBounds (slice.reduced (0, 5));
|
||||
|
||||
dismissButton.setBounds (getLocalBounds().reduced (10).removeFromTop (20).removeFromRight (20));
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (secondaryBackgroundColourId).contrasting (0.1f));
|
||||
}
|
||||
|
||||
void mouseUp (const MouseEvent& event) override
|
||||
{
|
||||
if (event.eventComponent == &createAccountLabel)
|
||||
URL ("https://juce.com/verification/register").launchInDefaultBrowser();
|
||||
}
|
||||
|
||||
void lookAndFeelChanged() override
|
||||
{
|
||||
enableGPLButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId));
|
||||
}
|
||||
|
||||
private:
|
||||
class ProgressButton : public TextButton,
|
||||
private Timer
|
||||
{
|
||||
public:
|
||||
ProgressButton (const String& buttonName)
|
||||
: TextButton (buttonName), text (buttonName)
|
||||
{
|
||||
}
|
||||
|
||||
void setBusy (bool shouldBeBusy)
|
||||
{
|
||||
isInProgress = shouldBeBusy;
|
||||
|
||||
if (isInProgress)
|
||||
{
|
||||
setEnabled (false);
|
||||
setButtonText ({});
|
||||
startTimerHz (30);
|
||||
}
|
||||
else
|
||||
{
|
||||
setEnabled (true);
|
||||
setButtonText (text);
|
||||
stopTimer();
|
||||
}
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
TextButton::paint (g);
|
||||
|
||||
if (isInProgress)
|
||||
{
|
||||
auto size = getHeight() - 10;
|
||||
auto halfSize = size / 2;
|
||||
|
||||
getLookAndFeel().drawSpinningWaitAnimation (g, Colours::white,
|
||||
(getWidth() / 2) - halfSize, (getHeight() / 2) - halfSize,
|
||||
size, size);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void timerCallback() override
|
||||
{
|
||||
repaint();
|
||||
}
|
||||
|
||||
String text;
|
||||
bool isInProgress = false;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
void updateLoginButtonStates (bool isLoggingIn)
|
||||
{
|
||||
logInButton.setBusy (isLoggingIn);
|
||||
|
||||
emailBox.setEnabled (! isLoggingIn);
|
||||
passwordBox.setEnabled (! isLoggingIn);
|
||||
}
|
||||
|
||||
void submitDetails()
|
||||
{
|
||||
auto loginFormError = checkLoginFormsAreValid();
|
||||
|
||||
if (loginFormError.isNotEmpty())
|
||||
{
|
||||
showErrorMessage (loginFormError);
|
||||
return;
|
||||
}
|
||||
|
||||
updateLoginButtonStates (true);
|
||||
|
||||
auto completionCallback = [weakThis = SafePointer<LoginFormComponent> { this }] (const String& errorMessage)
|
||||
{
|
||||
if (weakThis == nullptr)
|
||||
return;
|
||||
|
||||
weakThis->updateLoginButtonStates (false);
|
||||
|
||||
if (errorMessage.isNotEmpty())
|
||||
{
|
||||
weakThis->showErrorMessage (errorMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
weakThis->hideErrorMessage();
|
||||
weakThis->mainWindow.hideLoginFormOverlay();
|
||||
ProjucerApplication::getApp().getCommandManager().commandStatusChanged();
|
||||
}
|
||||
};
|
||||
|
||||
ProjucerApplication::getApp().getLicenseController().signIn (emailBox.getText(), passwordBox.getText(),
|
||||
std::move (completionCallback));
|
||||
}
|
||||
|
||||
String checkLoginFormsAreValid() const
|
||||
{
|
||||
auto email = emailBox.getText();
|
||||
|
||||
if (email.isEmpty() || email.indexOfChar ('@') < 0)
|
||||
return "Please enter a valid email.";
|
||||
|
||||
auto password = passwordBox.getText();
|
||||
|
||||
if (password.isEmpty() || password.length() < 8)
|
||||
return "Please enter a valid password.";
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void showErrorMessage (const String& errorMessage)
|
||||
{
|
||||
errorMessageLabel.setText (errorMessage, dontSendNotification);
|
||||
errorMessageLabel.setVisible (true);
|
||||
}
|
||||
|
||||
void hideErrorMessage()
|
||||
{
|
||||
errorMessageLabel.setText ({}, dontSendNotification);
|
||||
errorMessageLabel.setVisible (false);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static constexpr int iconHeight = 50;
|
||||
|
||||
MainWindow& mainWindow;
|
||||
|
||||
TextEditor emailBox, passwordBox;
|
||||
ProgressButton logInButton { "Sign In" };
|
||||
TextButton enableGPLButton { "Enable GPL Mode" };
|
||||
ShapeButton dismissButton { {},
|
||||
findColour (treeIconColourId),
|
||||
findColour (treeIconColourId).overlaidWith (findColour (defaultHighlightedTextColourId).withAlpha (0.2f)),
|
||||
findColour (treeIconColourId).overlaidWith (findColour (defaultHighlightedTextColourId).withAlpha (0.4f)) };
|
||||
UserAvatarComponent userAvatar { false };
|
||||
Label createAccountLabel { {}, "Create an account" },
|
||||
errorMessageLabel { {}, {} };
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LoginFormComponent)
|
||||
};
|
103
deps/juce/extras/Projucer/Source/Application/Windows/jucer_AboutWindowComponent.h
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 AboutWindowComponent : public Component
|
||||
{
|
||||
public:
|
||||
AboutWindowComponent()
|
||||
{
|
||||
addAndMakeVisible (titleLabel);
|
||||
titleLabel.setJustificationType (Justification::centred);
|
||||
titleLabel.setFont (Font (35.0f, Font::FontStyleFlags::bold));
|
||||
|
||||
auto buildDate = Time::getCompilationDate();
|
||||
addAndMakeVisible (versionLabel);
|
||||
versionLabel.setText ("JUCE v" + ProjucerApplication::getApp().getApplicationVersion()
|
||||
+ "\nBuild date: " + String (buildDate.getDayOfMonth())
|
||||
+ " " + Time::getMonthName (buildDate.getMonth(), true)
|
||||
+ " " + String (buildDate.getYear()),
|
||||
dontSendNotification);
|
||||
|
||||
versionLabel.setJustificationType (Justification::centred);
|
||||
addAndMakeVisible (copyrightLabel);
|
||||
copyrightLabel.setJustificationType (Justification::centred);
|
||||
|
||||
addAndMakeVisible (aboutButton);
|
||||
aboutButton.setTooltip ( {} );
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto bounds = getLocalBounds();
|
||||
bounds.removeFromBottom (20);
|
||||
|
||||
auto leftSlice = bounds.removeFromLeft (150);
|
||||
auto centreSlice = bounds.withTrimmedRight (150);
|
||||
|
||||
juceLogoBounds = leftSlice.removeFromTop (150).toFloat();
|
||||
juceLogoBounds.setWidth (juceLogoBounds.getWidth() + 100);
|
||||
juceLogoBounds.setHeight (juceLogoBounds.getHeight() + 100);
|
||||
|
||||
auto titleHeight = 40;
|
||||
|
||||
centreSlice.removeFromTop ((centreSlice.getHeight() / 2) - (titleHeight / 2));
|
||||
|
||||
titleLabel.setBounds (centreSlice.removeFromTop (titleHeight));
|
||||
|
||||
centreSlice.removeFromTop (10);
|
||||
versionLabel.setBounds (centreSlice.removeFromTop (40));
|
||||
|
||||
centreSlice.removeFromTop (10);
|
||||
aboutButton.setBounds (centreSlice.removeFromTop (20));
|
||||
|
||||
copyrightLabel.setBounds (getLocalBounds().removeFromBottom (50));
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (backgroundColourId));
|
||||
|
||||
if (juceLogo != nullptr)
|
||||
juceLogo->drawWithin (g, juceLogoBounds.translated (-75, -75), RectanglePlacement::centred, 1.0);
|
||||
}
|
||||
|
||||
private:
|
||||
Label titleLabel { "title", "PROJUCER" },
|
||||
versionLabel { "version" },
|
||||
copyrightLabel { "copyright", String (CharPointer_UTF8 ("\xc2\xa9")) + String (" 2020 Raw Material Software Limited") };
|
||||
|
||||
HyperlinkButton aboutButton { "About Us", URL ("https://juce.com") };
|
||||
|
||||
Rectangle<float> juceLogoBounds;
|
||||
|
||||
std::unique_ptr<Drawable> juceLogo { Drawable::createFromImageData (BinaryData::juce_icon_png,
|
||||
BinaryData::juce_icon_pngSize) };
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AboutWindowComponent)
|
||||
};
|
347
deps/juce/extras/Projucer/Source/Application/Windows/jucer_EditorColourSchemeWindowComponent.h
vendored
Normal file
@ -0,0 +1,347 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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/UI/PropertyComponents/jucer_ColourPropertyComponent.h"
|
||||
|
||||
//==============================================================================
|
||||
class EditorColourSchemeWindowComponent : public Component
|
||||
{
|
||||
public:
|
||||
EditorColourSchemeWindowComponent()
|
||||
{
|
||||
if (getAppSettings().monospacedFontNames.size() == 0)
|
||||
changeContent (new AppearanceEditor::FontScanPanel());
|
||||
else
|
||||
changeContent (new AppearanceEditor::EditorPanel());
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (backgroundColourId));
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
content->setBounds (getLocalBounds());
|
||||
}
|
||||
|
||||
void changeContent (Component* newContent)
|
||||
{
|
||||
content.reset (newContent);
|
||||
addAndMakeVisible (newContent);
|
||||
content->setBounds (getLocalBounds().reduced (10));
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Component> content;
|
||||
|
||||
//==============================================================================
|
||||
struct AppearanceEditor
|
||||
{
|
||||
struct FontScanPanel : public Component,
|
||||
private Timer
|
||||
{
|
||||
FontScanPanel()
|
||||
{
|
||||
fontsToScan = Font::findAllTypefaceNames();
|
||||
startTimer (1);
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (backgroundColourId));
|
||||
|
||||
g.setFont (14.0f);
|
||||
g.setColour (findColour (defaultTextColourId));
|
||||
g.drawFittedText ("Scanning for fonts..", getLocalBounds(), Justification::centred, 2);
|
||||
|
||||
const auto size = 30;
|
||||
getLookAndFeel().drawSpinningWaitAnimation (g, Colours::white, (getWidth() - size) / 2, getHeight() / 2 - 50, size, size);
|
||||
}
|
||||
|
||||
void timerCallback() override
|
||||
{
|
||||
repaint();
|
||||
|
||||
if (fontsToScan.size() == 0)
|
||||
{
|
||||
getAppSettings().monospacedFontNames = fontsFound;
|
||||
|
||||
if (auto* owner = findParentComponentOfClass<EditorColourSchemeWindowComponent>())
|
||||
owner->changeContent (new EditorPanel());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isMonospacedTypeface (fontsToScan[0]))
|
||||
fontsFound.add (fontsToScan[0]);
|
||||
|
||||
fontsToScan.remove (0);
|
||||
}
|
||||
}
|
||||
|
||||
// A rather hacky trick to select only the fixed-pitch fonts..
|
||||
// This is unfortunately a bit slow, but will work on all platforms.
|
||||
static bool isMonospacedTypeface (const String& name)
|
||||
{
|
||||
const Font font (name, 20.0f, Font::plain);
|
||||
|
||||
const auto width = font.getStringWidth ("....");
|
||||
|
||||
return width == font.getStringWidth ("WWWW")
|
||||
&& width == font.getStringWidth ("0000")
|
||||
&& width == font.getStringWidth ("1111")
|
||||
&& width == font.getStringWidth ("iiii");
|
||||
}
|
||||
|
||||
StringArray fontsToScan, fontsFound;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct EditorPanel : public Component
|
||||
{
|
||||
EditorPanel()
|
||||
: loadButton ("Load Scheme..."),
|
||||
saveButton ("Save Scheme...")
|
||||
{
|
||||
rebuildProperties();
|
||||
addAndMakeVisible (panel);
|
||||
|
||||
addAndMakeVisible (loadButton);
|
||||
addAndMakeVisible (saveButton);
|
||||
|
||||
loadButton.onClick = [this] { loadScheme(); };
|
||||
saveButton.onClick = [this] { saveScheme (false); };
|
||||
|
||||
lookAndFeelChanged();
|
||||
|
||||
saveSchemeState();
|
||||
}
|
||||
|
||||
~EditorPanel() override
|
||||
{
|
||||
if (hasSchemeBeenModifiedSinceSave())
|
||||
saveScheme (true);
|
||||
}
|
||||
|
||||
void rebuildProperties()
|
||||
{
|
||||
auto& scheme = getAppSettings().appearance;
|
||||
|
||||
Array<PropertyComponent*> props;
|
||||
auto fontValue = scheme.getCodeFontValue();
|
||||
props.add (FontNameValueSource::createProperty ("Code Editor Font", fontValue));
|
||||
props.add (FontSizeValueSource::createProperty ("Font Size", fontValue));
|
||||
|
||||
const auto colourNames = scheme.getColourNames();
|
||||
|
||||
for (int i = 0; i < colourNames.size(); ++i)
|
||||
props.add (new ColourPropertyComponent (nullptr, colourNames[i],
|
||||
scheme.getColourValue (colourNames[i]),
|
||||
Colours::white, false));
|
||||
|
||||
panel.clear();
|
||||
panel.addProperties (props);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto r = getLocalBounds();
|
||||
panel.setBounds (r.removeFromTop (getHeight() - 28).reduced (10, 2));
|
||||
loadButton.setBounds (r.removeFromLeft (getWidth() / 2).reduced (10, 1));
|
||||
saveButton.setBounds (r.reduced (10, 1));
|
||||
}
|
||||
|
||||
private:
|
||||
PropertyPanel panel;
|
||||
TextButton loadButton, saveButton;
|
||||
|
||||
Font codeFont;
|
||||
Array<var> colourValues;
|
||||
|
||||
void saveScheme (bool isExit)
|
||||
{
|
||||
chooser = std::make_unique<FileChooser> ("Select a file in which to save this colour-scheme...",
|
||||
getAppSettings().appearance.getSchemesFolder()
|
||||
.getNonexistentChildFile ("Scheme", AppearanceSettings::getSchemeFileSuffix()),
|
||||
AppearanceSettings::getSchemeFileWildCard());
|
||||
auto chooserFlags = FileBrowserComponent::saveMode
|
||||
| FileBrowserComponent::canSelectFiles
|
||||
| FileBrowserComponent::warnAboutOverwriting;
|
||||
|
||||
chooser->launchAsync (chooserFlags, [this, isExit] (const FileChooser& fc)
|
||||
{
|
||||
if (fc.getResult() == File{})
|
||||
{
|
||||
if (isExit)
|
||||
restorePreviousScheme();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
File file (fc.getResult().withFileExtension (AppearanceSettings::getSchemeFileSuffix()));
|
||||
getAppSettings().appearance.writeToFile (file);
|
||||
getAppSettings().appearance.refreshPresetSchemeList();
|
||||
|
||||
saveSchemeState();
|
||||
ProjucerApplication::getApp().selectEditorColourSchemeWithName (file.getFileNameWithoutExtension());
|
||||
});
|
||||
}
|
||||
|
||||
void loadScheme()
|
||||
{
|
||||
chooser = std::make_unique<FileChooser> ("Please select a colour-scheme file to load...",
|
||||
getAppSettings().appearance.getSchemesFolder(),
|
||||
AppearanceSettings::getSchemeFileWildCard());
|
||||
auto chooserFlags = FileBrowserComponent::openMode
|
||||
| FileBrowserComponent::canSelectFiles;
|
||||
|
||||
chooser->launchAsync (chooserFlags, [this] (const FileChooser& fc)
|
||||
{
|
||||
if (fc.getResult() == File{})
|
||||
return;
|
||||
|
||||
if (getAppSettings().appearance.readFromFile (fc.getResult()))
|
||||
{
|
||||
rebuildProperties();
|
||||
saveSchemeState();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void lookAndFeelChanged() override
|
||||
{
|
||||
loadButton.setColour (TextButton::buttonColourId,
|
||||
findColour (secondaryButtonBackgroundColourId));
|
||||
}
|
||||
|
||||
void saveSchemeState()
|
||||
{
|
||||
auto& appearance = getAppSettings().appearance;
|
||||
const auto colourNames = appearance.getColourNames();
|
||||
|
||||
codeFont = appearance.getCodeFont();
|
||||
|
||||
colourValues.clear();
|
||||
for (int i = 0; i < colourNames.size(); ++i)
|
||||
colourValues.add (appearance.getColourValue (colourNames[i]).getValue());
|
||||
}
|
||||
|
||||
bool hasSchemeBeenModifiedSinceSave()
|
||||
{
|
||||
auto& appearance = getAppSettings().appearance;
|
||||
const auto colourNames = appearance.getColourNames();
|
||||
|
||||
if (codeFont != appearance.getCodeFont())
|
||||
return true;
|
||||
|
||||
for (int i = 0; i < colourNames.size(); ++i)
|
||||
if (colourValues[i] != appearance.getColourValue (colourNames[i]).getValue())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void restorePreviousScheme()
|
||||
{
|
||||
auto& appearance = getAppSettings().appearance;
|
||||
const auto colourNames = appearance.getColourNames();
|
||||
|
||||
appearance.getCodeFontValue().setValue (codeFont.toString());
|
||||
|
||||
for (int i = 0; i < colourNames.size(); ++i)
|
||||
appearance.getColourValue (colourNames[i]).setValue (colourValues[i]);
|
||||
}
|
||||
|
||||
std::unique_ptr<FileChooser> chooser;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (EditorPanel)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct FontNameValueSource : public ValueSourceFilter
|
||||
{
|
||||
FontNameValueSource (const Value& source) : ValueSourceFilter (source) {}
|
||||
|
||||
var getValue() const override
|
||||
{
|
||||
return Font::fromString (sourceValue.toString()).getTypefaceName();
|
||||
}
|
||||
|
||||
void setValue (const var& newValue) override
|
||||
{
|
||||
auto font = Font::fromString (sourceValue.toString());
|
||||
font.setTypefaceName (newValue.toString().isEmpty() ? Font::getDefaultMonospacedFontName()
|
||||
: newValue.toString());
|
||||
sourceValue = font.toString();
|
||||
}
|
||||
|
||||
static ChoicePropertyComponent* createProperty (const String& title, const Value& value)
|
||||
{
|
||||
auto fontNames = getAppSettings().monospacedFontNames;
|
||||
|
||||
Array<var> values;
|
||||
values.add (Font::getDefaultMonospacedFontName());
|
||||
values.add (var());
|
||||
|
||||
for (int i = 0; i < fontNames.size(); ++i)
|
||||
values.add (fontNames[i]);
|
||||
|
||||
StringArray names;
|
||||
names.add ("<Default Monospaced>");
|
||||
names.add (String());
|
||||
names.addArray (getAppSettings().monospacedFontNames);
|
||||
|
||||
return new ChoicePropertyComponent (Value (new FontNameValueSource (value)),
|
||||
title, names, values);
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct FontSizeValueSource : public ValueSourceFilter
|
||||
{
|
||||
FontSizeValueSource (const Value& source) : ValueSourceFilter (source) {}
|
||||
|
||||
var getValue() const override
|
||||
{
|
||||
return Font::fromString (sourceValue.toString()).getHeight();
|
||||
}
|
||||
|
||||
void setValue (const var& newValue) override
|
||||
{
|
||||
sourceValue = Font::fromString (sourceValue.toString()).withHeight (newValue).toString();
|
||||
}
|
||||
|
||||
static PropertyComponent* createProperty (const String& title, const Value& value)
|
||||
{
|
||||
return new SliderPropertyComponent (Value (new FontSizeValueSource (value)),
|
||||
title, 5.0, 40.0, 0.1, 0.5);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EditorColourSchemeWindowComponent)
|
||||
};
|
89
deps/juce/extras/Projucer/Source/Application/Windows/jucer_FloatingToolWindow.h
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 FloatingToolWindow : public DialogWindow
|
||||
{
|
||||
FloatingToolWindow (const String& title,
|
||||
const String& windowPosPropertyName,
|
||||
Component* content,
|
||||
std::unique_ptr<Component>& ownerPointer,
|
||||
bool shouldBeResizable,
|
||||
int defaultW, int defaultH,
|
||||
int minW, int minH,
|
||||
int maxW, int maxH)
|
||||
: DialogWindow (title, content->findColour (secondaryBackgroundColourId), true, true),
|
||||
windowPosProperty (windowPosPropertyName),
|
||||
owner (ownerPointer)
|
||||
{
|
||||
setUsingNativeTitleBar (true);
|
||||
setResizable (shouldBeResizable, shouldBeResizable);
|
||||
setResizeLimits (minW, minH, maxW, maxH);
|
||||
setContentOwned (content, false);
|
||||
|
||||
String windowState;
|
||||
if (windowPosProperty.isNotEmpty())
|
||||
windowState = getGlobalProperties().getValue (windowPosProperty);
|
||||
|
||||
if (windowState.isNotEmpty())
|
||||
restoreWindowStateFromString (windowState);
|
||||
else
|
||||
centreAroundComponent (Component::getCurrentlyFocusedComponent(), defaultW, defaultH);
|
||||
|
||||
setVisible (true);
|
||||
owner.reset (this);
|
||||
}
|
||||
|
||||
~FloatingToolWindow() override
|
||||
{
|
||||
if (windowPosProperty.isNotEmpty())
|
||||
getGlobalProperties().setValue (windowPosProperty, getWindowStateAsString());
|
||||
}
|
||||
|
||||
void closeButtonPressed() override
|
||||
{
|
||||
owner.reset();
|
||||
}
|
||||
|
||||
bool escapeKeyPressed() override
|
||||
{
|
||||
closeButtonPressed();
|
||||
return true;
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (secondaryBackgroundColourId));
|
||||
}
|
||||
|
||||
private:
|
||||
String windowPosProperty;
|
||||
std::unique_ptr<Component>& owner;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FloatingToolWindow)
|
||||
};
|
318
deps/juce/extras/Projucer/Source/Application/Windows/jucer_GlobalPathsWindowComponent.h
vendored
Normal file
@ -0,0 +1,318 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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/UI/PropertyComponents/jucer_LabelPropertyComponent.h"
|
||||
|
||||
//==============================================================================
|
||||
class GlobalPathsWindowComponent : public Component,
|
||||
private Timer,
|
||||
private Value::Listener,
|
||||
private ChangeListener
|
||||
{
|
||||
public:
|
||||
GlobalPathsWindowComponent()
|
||||
{
|
||||
addChildComponent (rescanJUCEPathButton);
|
||||
rescanJUCEPathButton.onClick = [this]
|
||||
{
|
||||
ProjucerApplication::getApp().rescanJUCEPathModules();
|
||||
lastJUCEModulePath = getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get();
|
||||
};
|
||||
|
||||
addChildComponent (rescanUserPathButton);
|
||||
rescanUserPathButton.onClick = [this]
|
||||
{
|
||||
ProjucerApplication::getApp().rescanUserPathModules();
|
||||
lastUserModulePath = getAppSettings().getStoredPath (Ids::defaultUserModulePath, TargetOS::getThisOS()).get();
|
||||
};
|
||||
|
||||
addChildComponent (warnAboutJUCEPathButton);
|
||||
warnAboutJUCEPathButton.setToggleState (ProjucerApplication::getApp().shouldPromptUserAboutIncorrectJUCEPath(),
|
||||
dontSendNotification);
|
||||
warnAboutJUCEPathButton.onClick = [this]
|
||||
{
|
||||
ProjucerApplication::getApp().setShouldPromptUserAboutIncorrectJUCEPath (warnAboutJUCEPathButton.getToggleState());
|
||||
};
|
||||
|
||||
getGlobalProperties().addChangeListener (this);
|
||||
|
||||
addAndMakeVisible (resetToDefaultsButton);
|
||||
resetToDefaultsButton.onClick = [this] { resetCurrentOSPathsToDefaults(); };
|
||||
|
||||
addAndMakeVisible (propertyViewport);
|
||||
propertyViewport.setViewedComponent (&propertyGroup, false);
|
||||
|
||||
auto os = TargetOS::getThisOS();
|
||||
|
||||
if (os == TargetOS::osx) selectedOSValue = "osx";
|
||||
else if (os == TargetOS::windows) selectedOSValue = "windows";
|
||||
else if (os == TargetOS::linux) selectedOSValue = "linux";
|
||||
|
||||
selectedOSValue.addListener (this);
|
||||
|
||||
buildProps();
|
||||
|
||||
lastJUCEModulePath = getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get();
|
||||
lastUserModulePath = getAppSettings().getStoredPath (Ids::defaultUserModulePath, TargetOS::getThisOS()).get();
|
||||
}
|
||||
|
||||
~GlobalPathsWindowComponent() override
|
||||
{
|
||||
getGlobalProperties().removeChangeListener (this);
|
||||
|
||||
auto juceValue = getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS());
|
||||
auto userValue = getAppSettings().getStoredPath (Ids::defaultUserModulePath, TargetOS::getThisOS());
|
||||
|
||||
if (juceValue.get() != lastJUCEModulePath) ProjucerApplication::getApp().rescanJUCEPathModules();
|
||||
if (userValue.get() != lastUserModulePath) ProjucerApplication::getApp().rescanUserPathModules();
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (backgroundColourId));
|
||||
}
|
||||
|
||||
void paintOverChildren (Graphics& g) override
|
||||
{
|
||||
g.setColour (findColour (defaultHighlightColourId).withAlpha (flashAlpha));
|
||||
g.fillRect (boundsToHighlight);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto b = getLocalBounds().reduced (10);
|
||||
|
||||
auto bottomBounds = b.removeFromBottom (80);
|
||||
auto buttonBounds = bottomBounds.removeFromBottom (50);
|
||||
|
||||
rescanJUCEPathButton.setBounds (buttonBounds.removeFromLeft (150).reduced (5, 10));
|
||||
rescanUserPathButton.setBounds (buttonBounds.removeFromLeft (150).reduced (5, 10));
|
||||
|
||||
resetToDefaultsButton.setBounds (buttonBounds.removeFromRight (150).reduced (5, 10));
|
||||
warnAboutJUCEPathButton.setBounds (bottomBounds.reduced (0, 5));
|
||||
warnAboutJUCEPathButton.changeWidthToFitText();
|
||||
|
||||
propertyGroup.updateSize (0, 0, getWidth() - 20 - propertyViewport.getScrollBarThickness());
|
||||
propertyViewport.setBounds (b);
|
||||
}
|
||||
|
||||
void highlightJUCEPath()
|
||||
{
|
||||
if (isTimerRunning() || ! isSelectedOSThisOS())
|
||||
return;
|
||||
|
||||
const auto findJucePathPropertyComponent = [this]() -> PropertyComponent*
|
||||
{
|
||||
for (const auto& prop : propertyGroup.getProperties())
|
||||
if (prop->getName() == "Path to JUCE")
|
||||
return prop.get();
|
||||
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
if (auto* propComponent = findJucePathPropertyComponent())
|
||||
{
|
||||
boundsToHighlight = getLocalArea (nullptr, propComponent->getScreenBounds());
|
||||
flashAlpha = 0.0f;
|
||||
hasFlashed = false;
|
||||
|
||||
startTimer (25);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
void timerCallback() override
|
||||
{
|
||||
flashAlpha += (hasFlashed ? -0.05f : 0.05f);
|
||||
|
||||
if (flashAlpha > 0.75f)
|
||||
{
|
||||
hasFlashed = true;
|
||||
}
|
||||
else if (flashAlpha < 0.0f)
|
||||
{
|
||||
flashAlpha = 0.0f;
|
||||
boundsToHighlight = {};
|
||||
|
||||
stopTimer();
|
||||
}
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void valueChanged (Value&) override
|
||||
{
|
||||
buildProps();
|
||||
resized();
|
||||
}
|
||||
|
||||
void changeListenerCallback (ChangeBroadcaster*) override
|
||||
{
|
||||
warnAboutJUCEPathButton.setToggleState (ProjucerApplication::getApp().shouldPromptUserAboutIncorrectJUCEPath(),
|
||||
dontSendNotification);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool isSelectedOSThisOS() { return TargetOS::getThisOS() == getSelectedOS(); }
|
||||
|
||||
TargetOS::OS getSelectedOS() const
|
||||
{
|
||||
auto val = selectedOSValue.getValue();
|
||||
|
||||
if (val == "osx") return TargetOS::osx;
|
||||
else if (val == "windows") return TargetOS::windows;
|
||||
else if (val == "linux") return TargetOS::linux;
|
||||
|
||||
jassertfalse;
|
||||
return TargetOS::unknown;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void buildProps()
|
||||
{
|
||||
updateValues();
|
||||
|
||||
PropertyListBuilder builder;
|
||||
auto isThisOS = isSelectedOSThisOS();
|
||||
|
||||
builder.add (new ChoicePropertyComponent (selectedOSValue, "OS", { "OSX", "Windows", "Linux" }, { "osx", "windows", "linux" }),
|
||||
"Use this dropdown to set the global paths for different OSes. "
|
||||
"\nN.B. These paths are stored locally and will only be used when "
|
||||
"saving a project on this machine. Other machines will have their own "
|
||||
"locally stored paths.");
|
||||
|
||||
builder.add (new LabelPropertyComponent ("JUCE"), {});
|
||||
|
||||
builder.add (new FilePathPropertyComponent (jucePathValue, "Path to JUCE", true, isThisOS),
|
||||
"This should be the path to the top-level directory of your JUCE folder. "
|
||||
"This path will be used when searching for the JUCE examples and DemoRunner application.");
|
||||
|
||||
builder.add (new FilePathPropertyComponent (juceModulePathValue, "JUCE Modules", true, isThisOS),
|
||||
String ("This should be the path to the folder containing the JUCE modules that you wish to use, typically the \"modules\" directory of your JUCE folder.")
|
||||
+ (isThisOS ? " Use the button below to re-scan a new path." : ""));
|
||||
builder.add (new FilePathPropertyComponent (userModulePathValue, "User Modules", true, isThisOS),
|
||||
String ("A path to a folder containing any custom modules that you wish to use.")
|
||||
+ (isThisOS ? " Use the button below to re-scan new paths." : ""));
|
||||
|
||||
builder.add (new LabelPropertyComponent ("SDKs"), {});
|
||||
|
||||
builder.add (new FilePathPropertyComponent (vstPathValue, "VST (Legacy) SDK", true, isThisOS),
|
||||
"If you are building a legacy VST plug-in then this path should point to a VST2 SDK. "
|
||||
"The VST2 SDK can be obtained from the vstsdk3610_11_06_2018_build_37 (or older) VST3 SDK or JUCE version 5.3.2. "
|
||||
"You also need a VST2 license from Steinberg to distribute VST2 plug-ins.");
|
||||
|
||||
if (getSelectedOS() != TargetOS::linux)
|
||||
{
|
||||
builder.add (new FilePathPropertyComponent (aaxPathValue, "AAX SDK", true, isThisOS),
|
||||
"If you are building AAX plug-ins, this should be the path to the AAX SDK folder.");
|
||||
builder.add (new FilePathPropertyComponent (rtasPathValue, "RTAS SDK (deprecated)", true, isThisOS),
|
||||
"If you are building RTAS plug-ins, this should be the path to the RTAS SDK folder.");
|
||||
}
|
||||
|
||||
builder.add (new FilePathPropertyComponent (androidSDKPathValue, "Android SDK", true, isThisOS),
|
||||
"This path will be used when writing the local.properties file of an Android project and should point to the Android SDK folder.");
|
||||
|
||||
if (isThisOS)
|
||||
{
|
||||
builder.add (new LabelPropertyComponent ("Other"), {});
|
||||
|
||||
#if JUCE_MAC
|
||||
String exeLabel ("app");
|
||||
#elif JUCE_WINDOWS
|
||||
String exeLabel ("executable");
|
||||
#else
|
||||
String exeLabel ("startup script");
|
||||
#endif
|
||||
|
||||
builder.add (new FilePathPropertyComponent (clionExePathValue, "CLion " + exeLabel, false, isThisOS),
|
||||
"This path will be used for the \"Save Project and Open in IDE...\" option of the CLion exporter.");
|
||||
builder.add (new FilePathPropertyComponent (androidStudioExePathValue, "Android Studio " + exeLabel, false, isThisOS),
|
||||
"This path will be used for the \"Save Project and Open in IDE...\" option of the Android Studio exporter.");
|
||||
}
|
||||
|
||||
rescanJUCEPathButton.setVisible (isThisOS);
|
||||
rescanUserPathButton.setVisible (isThisOS);
|
||||
warnAboutJUCEPathButton.setVisible (isThisOS);
|
||||
|
||||
propertyGroup.setProperties (builder);
|
||||
}
|
||||
|
||||
void updateValues()
|
||||
{
|
||||
auto& settings = getAppSettings();
|
||||
auto os = getSelectedOS();
|
||||
|
||||
jucePathValue = settings.getStoredPath (Ids::jucePath, os);
|
||||
juceModulePathValue = settings.getStoredPath (Ids::defaultJuceModulePath, os);
|
||||
userModulePathValue = settings.getStoredPath (Ids::defaultUserModulePath, os);
|
||||
vstPathValue = settings.getStoredPath (Ids::vstLegacyPath, os);
|
||||
rtasPathValue = settings.getStoredPath (Ids::rtasPath, os);
|
||||
aaxPathValue = settings.getStoredPath (Ids::aaxPath, os);
|
||||
androidSDKPathValue = settings.getStoredPath (Ids::androidSDKPath, os);
|
||||
clionExePathValue = settings.getStoredPath (Ids::clionExePath, os);
|
||||
androidStudioExePathValue = settings.getStoredPath (Ids::androidStudioExePath, os);
|
||||
}
|
||||
|
||||
void resetCurrentOSPathsToDefaults()
|
||||
{
|
||||
jucePathValue .resetToDefault();
|
||||
juceModulePathValue .resetToDefault();
|
||||
userModulePathValue .resetToDefault();
|
||||
vstPathValue .resetToDefault();
|
||||
rtasPathValue .resetToDefault();
|
||||
aaxPathValue .resetToDefault();
|
||||
androidSDKPathValue .resetToDefault();
|
||||
clionExePathValue .resetToDefault();
|
||||
androidStudioExePathValue.resetToDefault();
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
Value selectedOSValue;
|
||||
|
||||
ValueWithDefault jucePathValue, juceModulePathValue, userModulePathValue,
|
||||
vstPathValue, rtasPathValue, aaxPathValue, androidSDKPathValue, clionExePathValue, androidStudioExePathValue;
|
||||
|
||||
Viewport propertyViewport;
|
||||
PropertyGroupComponent propertyGroup { "Global Paths", { getIcons().openFolder, Colours::transparentBlack } };
|
||||
|
||||
ToggleButton warnAboutJUCEPathButton { "Warn about incorrect JUCE path" };
|
||||
TextButton rescanJUCEPathButton { "Re-scan JUCE Modules" },
|
||||
rescanUserPathButton { "Re-scan User Modules" },
|
||||
resetToDefaultsButton { "Reset to Defaults" };
|
||||
|
||||
Rectangle<int> boundsToHighlight;
|
||||
float flashAlpha = 0.0f;
|
||||
bool hasFlashed = false;
|
||||
|
||||
var lastJUCEModulePath, lastUserModulePath;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GlobalPathsWindowComponent)
|
||||
};
|
347
deps/juce/extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h
vendored
Normal file
@ -0,0 +1,347 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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
|
||||
|
||||
|
||||
//==============================================================================
|
||||
static String getWidthLimitedStringFromVarArray (const var& varArray) noexcept
|
||||
{
|
||||
if (! varArray.isArray())
|
||||
return {};
|
||||
|
||||
int numLines = 1;
|
||||
const int lineWidth = 100;
|
||||
const String indent (" ");
|
||||
|
||||
String str;
|
||||
if (auto* arr = varArray.getArray())
|
||||
{
|
||||
for (auto& v : *arr)
|
||||
{
|
||||
if ((str.length() + v.toString().length()) > (lineWidth * numLines))
|
||||
{
|
||||
str += newLine;
|
||||
str += indent;
|
||||
|
||||
++numLines;
|
||||
}
|
||||
|
||||
str += v.toString() + (arr->indexOf (v) != arr->size() - 1 ? ", " : "");
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class PIPCreatorWindowComponent : public Component,
|
||||
private ValueTree::Listener
|
||||
{
|
||||
public:
|
||||
PIPCreatorWindowComponent()
|
||||
{
|
||||
lf.reset (new PIPCreatorLookAndFeel());
|
||||
setLookAndFeel (lf.get());
|
||||
|
||||
addAndMakeVisible (propertyViewport);
|
||||
propertyViewport.setViewedComponent (&propertyGroup, false);
|
||||
buildProps();
|
||||
|
||||
addAndMakeVisible (createButton);
|
||||
createButton.onClick = [this]
|
||||
{
|
||||
chooser = std::make_unique<FileChooser> ("Save PIP File",
|
||||
File::getSpecialLocation (File::SpecialLocationType::userDesktopDirectory)
|
||||
.getChildFile (nameValue.get().toString() + ".h"));
|
||||
auto browserFlags = FileBrowserComponent::saveMode
|
||||
| FileBrowserComponent::canSelectFiles
|
||||
| FileBrowserComponent::warnAboutOverwriting;
|
||||
|
||||
chooser->launchAsync (browserFlags, [this] (const FileChooser& fc)
|
||||
{
|
||||
const auto result = fc.getResult();
|
||||
|
||||
if (result != File{})
|
||||
createPIPFile (result);
|
||||
});
|
||||
};
|
||||
|
||||
pipTree.addListener (this);
|
||||
}
|
||||
|
||||
~PIPCreatorWindowComponent() override
|
||||
{
|
||||
setLookAndFeel (nullptr);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto bounds = getLocalBounds();
|
||||
|
||||
createButton.setBounds (bounds.removeFromBottom (50).reduced (100, 10));
|
||||
|
||||
propertyGroup.updateSize (0, 0, getWidth() - propertyViewport.getScrollBarThickness());
|
||||
propertyViewport.setBounds (bounds);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
struct PIPCreatorLookAndFeel : public ProjucerLookAndFeel
|
||||
{
|
||||
PIPCreatorLookAndFeel() {}
|
||||
|
||||
Rectangle<int> getPropertyComponentContentPosition (PropertyComponent& component)
|
||||
{
|
||||
auto textW = jmin (200, component.getWidth() / 3);
|
||||
return { textW, 0, component.getWidth() - textW, component.getHeight() - 1 };
|
||||
}
|
||||
};
|
||||
|
||||
void lookAndFeelChanged() override
|
||||
{
|
||||
lf->setColourScheme (ProjucerApplication::getApp().lookAndFeel.getCurrentColourScheme());
|
||||
lf->setupColours();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void buildProps()
|
||||
{
|
||||
PropertyListBuilder builder;
|
||||
|
||||
builder.add (new TextPropertyComponent (nameValue, "Name", 256, false),
|
||||
"The name of your JUCE project.");
|
||||
builder.add (new TextPropertyComponent (versionValue, "Version", 16, false),
|
||||
"This will be used for the \"Project Version\" field in the Projucer.");
|
||||
builder.add (new TextPropertyComponent (vendorValue, "Vendor", 2048, false),
|
||||
"This will be used for the \"Company Name\" field in the Projucer.");
|
||||
builder.add (new TextPropertyComponent (websiteValue, "Website", 2048, false),
|
||||
"This will be used for the \"Company Website\" field in the Projucer");
|
||||
builder.add (new TextPropertyComponent (descriptionValue, "Description", 2048, true),
|
||||
"A short description of your JUCE project.");
|
||||
|
||||
{
|
||||
Array<var> moduleVars;
|
||||
for (auto& m : getJUCEModules())
|
||||
moduleVars.add (m);
|
||||
|
||||
builder.add (new MultiChoicePropertyComponent (dependenciesValue, "Dependencies",
|
||||
getJUCEModules(), moduleVars),
|
||||
"The JUCE modules that should be added to your project.");
|
||||
}
|
||||
|
||||
{
|
||||
Array<var> exporterVars;
|
||||
StringArray exporterNames;
|
||||
|
||||
for (auto& exporterTypeInfo : ProjectExporter::getExporterTypeInfos())
|
||||
{
|
||||
exporterVars.add (exporterTypeInfo.identifier.toString());
|
||||
exporterNames.add (exporterTypeInfo.displayName);
|
||||
}
|
||||
|
||||
builder.add (new MultiChoicePropertyComponent (exportersValue, "Exporters", exporterNames, exporterVars),
|
||||
"The exporters that should be added to your project.");
|
||||
}
|
||||
|
||||
builder.add (new TextPropertyComponent (moduleFlagsValue, "Module Flags", 2048, true),
|
||||
"Use this to set one, or many, of the JUCE module flags");
|
||||
builder.add (new TextPropertyComponent (definesValue, "Defines", 2048, true),
|
||||
"This sets some global preprocessor definitions for your project. Used to populate the \"Preprocessor Definitions\" field in the Projucer.");
|
||||
builder.add (new ChoicePropertyComponent (typeValue, "Type",
|
||||
{ "Component", "Plugin", "Console Application" },
|
||||
{ "Component", "AudioProcessor", "Console" }),
|
||||
"The project type.");
|
||||
|
||||
builder.add (new TextPropertyComponent (mainClassValue, "Main Class", 2048, false),
|
||||
"The name of the main class that should be instantiated. "
|
||||
"There can only be one main class and it must have a default constructor. "
|
||||
"Depending on the type, this may need to inherit from a specific JUCE class");
|
||||
|
||||
builder.add (new ChoicePropertyComponent (useLocalCopyValue, "Use Local Copy"),
|
||||
"Enable this to specify that the PIP file should be copied to the generated project directory instead of just referred to.");
|
||||
|
||||
propertyGroup.setProperties (builder);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void valueTreePropertyChanged (ValueTree&, const Identifier& identifier) override
|
||||
{
|
||||
if (identifier == Ids::type)
|
||||
{
|
||||
auto type = typeValue.get().toString();
|
||||
|
||||
if (type == "Component")
|
||||
{
|
||||
nameValue.setDefault ("MyComponentPIP");
|
||||
dependenciesValue.setDefault (getModulesRequiredForComponent());
|
||||
mainClassValue.setDefault ("MyComponent");
|
||||
}
|
||||
else if (type == "AudioProcessor")
|
||||
{
|
||||
nameValue.setDefault ("MyPluginPIP");
|
||||
dependenciesValue.setDefault (getModulesRequiredForAudioProcessor());
|
||||
mainClassValue.setDefault ("MyPlugin");
|
||||
}
|
||||
else if (type == "Console")
|
||||
{
|
||||
nameValue.setDefault ("MyConsolePIP");
|
||||
dependenciesValue.setDefault (getModulesRequiredForConsole());
|
||||
mainClassValue.setDefault ({});
|
||||
}
|
||||
|
||||
MessageManager::callAsync ([this]
|
||||
{
|
||||
buildProps();
|
||||
resized();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
String getFormattedMetadataString() const noexcept
|
||||
{
|
||||
StringArray metadata;
|
||||
|
||||
{
|
||||
StringArray section;
|
||||
|
||||
if (nameValue.get().toString().isNotEmpty()) section.add (" name: " + nameValue.get().toString());
|
||||
if (versionValue.get().toString().isNotEmpty()) section.add (" version: " + versionValue.get().toString());
|
||||
if (vendorValue.get().toString().isNotEmpty()) section.add (" vendor: " + vendorValue.get().toString());
|
||||
if (websiteValue.get().toString().isNotEmpty()) section.add (" website: " + websiteValue.get().toString());
|
||||
if (descriptionValue.get().toString().isNotEmpty()) section.add (" description: " + descriptionValue.get().toString());
|
||||
|
||||
if (! section.isEmpty())
|
||||
metadata.add (section.joinIntoString (getPreferredLineFeed()));
|
||||
}
|
||||
|
||||
{
|
||||
StringArray section;
|
||||
|
||||
auto dependenciesString = getWidthLimitedStringFromVarArray (dependenciesValue.get());
|
||||
if (dependenciesString.isNotEmpty()) section.add (" dependencies: " + dependenciesString);
|
||||
|
||||
auto exportersString = getWidthLimitedStringFromVarArray (exportersValue.get());
|
||||
if (exportersString.isNotEmpty()) section.add (" exporters: " + exportersString);
|
||||
|
||||
if (! section.isEmpty())
|
||||
metadata.add (section.joinIntoString (getPreferredLineFeed()));
|
||||
}
|
||||
|
||||
{
|
||||
StringArray section;
|
||||
|
||||
if (moduleFlagsValue.get().toString().isNotEmpty()) section.add (" moduleFlags: " + moduleFlagsValue.get().toString());
|
||||
if (definesValue.get().toString().isNotEmpty()) section.add (" defines: " + definesValue.get().toString());
|
||||
|
||||
if (! section.isEmpty())
|
||||
metadata.add (section.joinIntoString (getPreferredLineFeed()));
|
||||
}
|
||||
|
||||
{
|
||||
StringArray section;
|
||||
|
||||
if (typeValue.get().toString().isNotEmpty()) section.add (" type: " + typeValue.get().toString());
|
||||
if (mainClassValue.get().toString().isNotEmpty()) section.add (" mainClass: " + mainClassValue.get().toString());
|
||||
|
||||
if (! section.isEmpty())
|
||||
metadata.add (section.joinIntoString (getPreferredLineFeed()));
|
||||
}
|
||||
|
||||
{
|
||||
StringArray section;
|
||||
|
||||
if (useLocalCopyValue.get()) section.add (" useLocalCopy: " + useLocalCopyValue.get().toString());
|
||||
|
||||
if (! section.isEmpty())
|
||||
metadata.add (section.joinIntoString (getPreferredLineFeed()));
|
||||
}
|
||||
|
||||
return metadata.joinIntoString (String (getPreferredLineFeed()) + getPreferredLineFeed());
|
||||
}
|
||||
|
||||
void createPIPFile (File fileToSave)
|
||||
{
|
||||
String fileTemplate (BinaryData::jucer_PIPTemplate_h);
|
||||
fileTemplate = fileTemplate.replace ("%%pip_metadata%%", getFormattedMetadataString());
|
||||
|
||||
auto type = typeValue.get().toString();
|
||||
|
||||
if (type == "Component")
|
||||
{
|
||||
String componentCode (BinaryData::jucer_ContentCompSimpleTemplate_h);
|
||||
componentCode = componentCode.substring (componentCode.indexOf ("class %%content_component_class%%"))
|
||||
.replace ("%%content_component_class%%", mainClassValue.get().toString());
|
||||
|
||||
fileTemplate = fileTemplate.replace ("%%pip_code%%", componentCode);
|
||||
}
|
||||
else if (type == "AudioProcessor")
|
||||
{
|
||||
String audioProcessorCode (BinaryData::jucer_PIPAudioProcessorTemplate_h);
|
||||
audioProcessorCode = audioProcessorCode.replace ("%%class_name%%", mainClassValue.get().toString())
|
||||
.replace ("%%name%%", nameValue.get().toString());
|
||||
|
||||
fileTemplate = fileTemplate.replace ("%%pip_code%%", audioProcessorCode);
|
||||
}
|
||||
else if (type == "Console")
|
||||
{
|
||||
String consoleCode (BinaryData::jucer_MainConsoleAppTemplate_cpp);
|
||||
consoleCode = consoleCode.substring (consoleCode.indexOf ("int main (int argc, char* argv[])"));
|
||||
|
||||
fileTemplate = fileTemplate.replace ("%%pip_code%%", consoleCode);
|
||||
}
|
||||
|
||||
if (fileToSave.create())
|
||||
fileToSave.replaceWithText (fileTemplate);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ValueTree pipTree { "PIPSettings" };
|
||||
ValueWithDefault nameValue { pipTree, Ids::name, nullptr, "MyComponentPIP" },
|
||||
versionValue { pipTree, Ids::version, nullptr },
|
||||
vendorValue { pipTree, Ids::vendor, nullptr },
|
||||
websiteValue { pipTree, Ids::website, nullptr },
|
||||
descriptionValue { pipTree, Ids::description, nullptr },
|
||||
dependenciesValue { pipTree, Ids::dependencies_, nullptr, getModulesRequiredForComponent(), "," },
|
||||
exportersValue { pipTree, Ids::exporters, nullptr, StringArray (ProjectExporter::getCurrentPlatformExporterTypeInfo().identifier.toString()), "," },
|
||||
moduleFlagsValue { pipTree, Ids::moduleFlags, nullptr, "JUCE_STRICT_REFCOUNTEDPOINTER=1" },
|
||||
definesValue { pipTree, Ids::defines, nullptr },
|
||||
typeValue { pipTree, Ids::type, nullptr, "Component" },
|
||||
mainClassValue { pipTree, Ids::mainClass, nullptr, "MyComponent" },
|
||||
useLocalCopyValue { pipTree, Ids::useLocalCopy, nullptr, false };
|
||||
|
||||
std::unique_ptr<PIPCreatorLookAndFeel> lf;
|
||||
|
||||
Viewport propertyViewport;
|
||||
PropertyGroupComponent propertyGroup { "PIP Creator", {} };
|
||||
|
||||
TextButton createButton { "Create PIP" };
|
||||
|
||||
std::unique_ptr<FileChooser> chooser;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PIPCreatorWindowComponent)
|
||||
};
|
218
deps/juce/extras/Projucer/Source/Application/Windows/jucer_SVGPathDataWindowComponent.h
vendored
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 SVGPathDataComponent : public Component,
|
||||
public FileDragAndDropTarget
|
||||
|
||||
{
|
||||
public:
|
||||
SVGPathDataComponent()
|
||||
{
|
||||
desc.setJustificationType (Justification::centred);
|
||||
addAndMakeVisible (desc);
|
||||
|
||||
userText.setFont (getAppSettings().appearance.getCodeFont().withHeight (13.0f));
|
||||
userText.setMultiLine (true, true);
|
||||
userText.setReturnKeyStartsNewLine (true);
|
||||
addAndMakeVisible (userText);
|
||||
userText.onTextChange = [this] { update(); };
|
||||
userText.onEscapeKey = [this] { getTopLevelComponent()->exitModalState (0); };
|
||||
|
||||
resultText.setFont (getAppSettings().appearance.getCodeFont().withHeight (13.0f));
|
||||
resultText.setMultiLine (true, true);
|
||||
resultText.setReadOnly (true);
|
||||
resultText.setSelectAllWhenFocused (true);
|
||||
addAndMakeVisible (resultText);
|
||||
|
||||
userText.setText (getLastText());
|
||||
|
||||
addAndMakeVisible (copyButton);
|
||||
copyButton.onClick = [this] { SystemClipboard::copyTextToClipboard (resultText.getText()); };
|
||||
|
||||
addAndMakeVisible (closeSubPathButton);
|
||||
closeSubPathButton.onClick = [this] { update(); };
|
||||
closeSubPathButton.setToggleState (true, NotificationType::dontSendNotification);
|
||||
|
||||
addAndMakeVisible (fillPathButton);
|
||||
fillPathButton.onClick = [this] { update(); };
|
||||
fillPathButton.setToggleState (true, NotificationType::dontSendNotification);
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
getLastText() = userText.getText();
|
||||
auto text = getLastText().trim().unquoted().trim();
|
||||
|
||||
path = Drawable::parseSVGPath (text);
|
||||
|
||||
if (path.isEmpty())
|
||||
path = pathFromPoints (text);
|
||||
|
||||
String result = "No path generated.. Not a valid SVG path string?";
|
||||
|
||||
if (! path.isEmpty())
|
||||
{
|
||||
MemoryOutputStream data;
|
||||
path.writePathToStream (data);
|
||||
|
||||
MemoryOutputStream out;
|
||||
|
||||
out << "static const unsigned char pathData[] = ";
|
||||
build_tools::writeDataAsCppLiteral (data.getMemoryBlock(), out, false, true);
|
||||
out << newLine
|
||||
<< newLine
|
||||
<< "Path path;" << newLine
|
||||
<< "path.loadPathFromData (pathData, sizeof (pathData));" << newLine;
|
||||
|
||||
result = out.toString();
|
||||
}
|
||||
|
||||
resultText.setText (result, false);
|
||||
repaint (previewPathArea);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto r = getLocalBounds().reduced (8);
|
||||
|
||||
auto bottomSection = r.removeFromBottom (30);
|
||||
copyButton.setBounds (bottomSection.removeFromLeft (50));
|
||||
bottomSection.removeFromLeft (25);
|
||||
fillPathButton.setBounds (bottomSection.removeFromLeft (bottomSection.getWidth() / 2));
|
||||
closeSubPathButton.setBounds (bottomSection);
|
||||
|
||||
r.removeFromBottom (5);
|
||||
desc.setBounds (r.removeFromTop (44));
|
||||
r.removeFromTop (8);
|
||||
userText.setBounds (r.removeFromTop (r.getHeight() / 2));
|
||||
r.removeFromTop (8);
|
||||
previewPathArea = r.removeFromRight (r.getHeight());
|
||||
resultText.setBounds (r);
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
if (dragOver)
|
||||
{
|
||||
g.setColour (findColour (secondaryBackgroundColourId).brighter());
|
||||
g.fillAll();
|
||||
}
|
||||
|
||||
g.setColour (findColour (defaultTextColourId));
|
||||
path.applyTransform (path.getTransformToScaleToFit (previewPathArea.reduced (4).toFloat(), true));
|
||||
|
||||
if (fillPathButton.getToggleState())
|
||||
g.fillPath (path);
|
||||
else
|
||||
g.strokePath (path, PathStrokeType (2.0f));
|
||||
}
|
||||
|
||||
void lookAndFeelChanged() override
|
||||
{
|
||||
userText.applyFontToAllText (userText.getFont());
|
||||
resultText.applyFontToAllText (resultText.getFont());
|
||||
}
|
||||
|
||||
bool isInterestedInFileDrag (const StringArray& files) override
|
||||
{
|
||||
return files.size() == 1
|
||||
&& File (files[0]).hasFileExtension ("svg");
|
||||
}
|
||||
|
||||
void fileDragEnter (const StringArray&, int, int) override
|
||||
{
|
||||
dragOver = true;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void fileDragExit (const StringArray&) override
|
||||
{
|
||||
dragOver = false;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void filesDropped (const StringArray& files, int, int) override
|
||||
{
|
||||
dragOver = false;
|
||||
repaint();
|
||||
|
||||
if (auto element = parseXML (File (files[0])))
|
||||
{
|
||||
if (auto* ePath = element->getChildByName ("path"))
|
||||
userText.setText (ePath->getStringAttribute ("d"), true);
|
||||
else if (auto* ePolygon = element->getChildByName ("polygon"))
|
||||
userText.setText (ePolygon->getStringAttribute ("points"), true);
|
||||
}
|
||||
}
|
||||
|
||||
Path pathFromPoints (String pointsText)
|
||||
{
|
||||
auto points = StringArray::fromTokens (pointsText, " ,", "");
|
||||
points.removeEmptyStrings();
|
||||
|
||||
jassert (points.size() % 2 == 0);
|
||||
|
||||
Path p;
|
||||
|
||||
for (int i = 0; i < points.size() / 2; i++)
|
||||
{
|
||||
auto x = points[i * 2].getFloatValue();
|
||||
auto y = points[i * 2 + 1].getFloatValue();
|
||||
|
||||
if (i == 0)
|
||||
p.startNewSubPath ({ x, y });
|
||||
else
|
||||
p.lineTo ({ x, y });
|
||||
}
|
||||
|
||||
if (closeSubPathButton.getToggleState())
|
||||
p.closeSubPath();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
private:
|
||||
Label desc { {}, "Paste an SVG path string into the top box, and it'll be converted to some C++ "
|
||||
"code that will load it as a Path object.." };
|
||||
TextButton copyButton { "Copy" };
|
||||
TextEditor userText, resultText;
|
||||
|
||||
ToggleButton closeSubPathButton { "Close sub-path" };
|
||||
ToggleButton fillPathButton { "Fill path" };
|
||||
|
||||
Rectangle<int> previewPathArea;
|
||||
Path path;
|
||||
bool dragOver = false;
|
||||
|
||||
String& getLastText()
|
||||
{
|
||||
static String t;
|
||||
return t;
|
||||
}
|
||||
};
|
198
deps/juce/extras/Projucer/Source/Application/Windows/jucer_TranslationToolWindowComponent.h
vendored
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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_TranslationHelpers.h"
|
||||
|
||||
//==============================================================================
|
||||
class TranslationToolComponent : public Component
|
||||
{
|
||||
public:
|
||||
TranslationToolComponent()
|
||||
: editorOriginal (documentOriginal, nullptr),
|
||||
editorPre (documentPre, nullptr),
|
||||
editorPost (documentPost, nullptr),
|
||||
editorResult (documentResult, nullptr)
|
||||
{
|
||||
instructionsLabel.setText (
|
||||
"This utility converts translation files to/from a format that can be passed to automatic translation tools."
|
||||
"\n\n"
|
||||
"First, choose whether to scan the current project for all TRANS() macros, or "
|
||||
"pick an existing translation file to load:", dontSendNotification);
|
||||
addAndMakeVisible (instructionsLabel);
|
||||
|
||||
label1.setText ("..then copy-and-paste this annotated text into Google Translate or some other translator:", dontSendNotification);
|
||||
addAndMakeVisible (label1);
|
||||
|
||||
label2.setText ("...then, take the translated result and paste it into the box below:", dontSendNotification);
|
||||
addAndMakeVisible (label2);
|
||||
|
||||
label3.setText ("Finally, click the 'Generate' button, and a translation file will be created below. "
|
||||
"Remember to update its language code at the top!", dontSendNotification);
|
||||
addAndMakeVisible (label3);
|
||||
|
||||
label4.setText ("If you load an existing file the already translated strings will be removed. Ensure this box is empty to create a fresh translation", dontSendNotification);
|
||||
addAndMakeVisible (label4);
|
||||
|
||||
addAndMakeVisible (editorOriginal);
|
||||
addAndMakeVisible (editorPre);
|
||||
addAndMakeVisible (editorPost);
|
||||
addAndMakeVisible (editorResult);
|
||||
|
||||
addAndMakeVisible (generateButton);
|
||||
generateButton.onClick = [this] { generate(); };
|
||||
|
||||
addAndMakeVisible (scanProjectButton);
|
||||
scanProjectButton.onClick = [this] { scanProject(); };
|
||||
|
||||
addAndMakeVisible (scanFolderButton);
|
||||
scanFolderButton.onClick = [this] { scanFolder(); };
|
||||
|
||||
addAndMakeVisible (loadTranslationButton);
|
||||
loadTranslationButton.onClick = [this] { loadFile(); };
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (backgroundColourId));
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
const int m = 6;
|
||||
const int textH = 44;
|
||||
const int extraH = (7 * textH);
|
||||
const int editorH = (getHeight() - extraH) / 4;
|
||||
const int numButtons = 3;
|
||||
|
||||
Rectangle<int> r (getLocalBounds().withTrimmedBottom (m));
|
||||
const int buttonWidth = r.getWidth() / numButtons;
|
||||
|
||||
instructionsLabel.setBounds (r.removeFromTop (textH * 2).reduced (m));
|
||||
r.removeFromTop (m);
|
||||
Rectangle<int> r2 (r.removeFromTop (textH - (2 * m)));
|
||||
scanProjectButton .setBounds (r2.removeFromLeft (buttonWidth).reduced (m, 0));
|
||||
scanFolderButton .setBounds (r2.removeFromLeft (buttonWidth).reduced (m, 0));
|
||||
loadTranslationButton.setBounds (r2.reduced (m, 0));
|
||||
|
||||
label1 .setBounds (r.removeFromTop (textH) .reduced (m));
|
||||
editorPre.setBounds (r.removeFromTop (editorH).reduced (m, 0));
|
||||
|
||||
label2 .setBounds (r.removeFromTop (textH) .reduced (m));
|
||||
editorPost.setBounds (r.removeFromTop (editorH).reduced (m, 0));
|
||||
|
||||
r2 = r.removeFromTop (textH);
|
||||
generateButton.setBounds (r2.removeFromRight (152).reduced (m));
|
||||
label3 .setBounds (r2.reduced (m));
|
||||
editorResult .setBounds (r.removeFromTop (editorH).reduced (m, 0));
|
||||
|
||||
label4 .setBounds (r.removeFromTop (textH).reduced (m));
|
||||
editorOriginal.setBounds (r.reduced (m, 0));
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
void generate()
|
||||
{
|
||||
StringArray preStrings (TranslationHelpers::breakApart (documentPre.getAllContent()));
|
||||
StringArray postStrings (TranslationHelpers::breakApart (documentPost.getAllContent()));
|
||||
|
||||
if (postStrings.size() != preStrings.size())
|
||||
{
|
||||
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
|
||||
TRANS("Error"),
|
||||
TRANS("The pre- and post-translation text doesn't match!\n\n"
|
||||
"Perhaps it got mangled by the translator?"));
|
||||
return;
|
||||
}
|
||||
|
||||
const LocalisedStrings originalTranslation (documentOriginal.getAllContent(), false);
|
||||
documentResult.replaceAllContent (TranslationHelpers::createFinishedTranslationFile (preStrings, postStrings, originalTranslation));
|
||||
}
|
||||
|
||||
void scanProject()
|
||||
{
|
||||
if (Project* project = ProjucerApplication::getApp().mainWindowList.getFrontmostProject())
|
||||
setPreTranslationText (TranslationHelpers::getPreTranslationText (*project));
|
||||
else
|
||||
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon, "Translation Tool",
|
||||
"This will only work when you have a project open!");
|
||||
}
|
||||
|
||||
void scanFolder()
|
||||
{
|
||||
chooser = std::make_unique<FileChooser> ("Choose the root folder to search for the TRANS macros",
|
||||
File(), "*");
|
||||
auto chooserFlags = FileBrowserComponent::openMode | FileBrowserComponent::canSelectDirectories;
|
||||
|
||||
chooser->launchAsync (chooserFlags, [this] (const FileChooser& fc)
|
||||
{
|
||||
if (fc.getResult() == File{})
|
||||
return;
|
||||
|
||||
StringArray strings;
|
||||
TranslationHelpers::scanFolderForTranslations (strings, fc.getResult());
|
||||
setPreTranslationText (TranslationHelpers::mungeStrings(strings));
|
||||
});
|
||||
}
|
||||
|
||||
void loadFile()
|
||||
{
|
||||
chooser = std::make_unique<FileChooser> ("Choose a translation file to load", File(), "*");
|
||||
auto chooserFlags = FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles;
|
||||
|
||||
chooser->launchAsync (chooserFlags, [this] (const FileChooser& fc)
|
||||
{
|
||||
if (fc.getResult() == File{})
|
||||
return;
|
||||
|
||||
const LocalisedStrings loadedStrings (fc.getResult(), false);
|
||||
documentOriginal.replaceAllContent (fc.getResult().loadFileAsString().trim());
|
||||
setPreTranslationText (TranslationHelpers::getPreTranslationText (loadedStrings));
|
||||
});
|
||||
}
|
||||
|
||||
void setPreTranslationText (const String& text)
|
||||
{
|
||||
documentPre.replaceAllContent (text);
|
||||
editorPre.grabKeyboardFocus();
|
||||
editorPre.selectAll();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
CodeDocument documentOriginal, documentPre, documentPost, documentResult;
|
||||
CodeEditorComponent editorOriginal, editorPre, editorPost, editorResult;
|
||||
|
||||
Label label1, label2, label3, label4;
|
||||
Label instructionsLabel;
|
||||
|
||||
TextButton generateButton { TRANS("Generate") },
|
||||
scanProjectButton { "Scan project for TRANS macros" },
|
||||
scanFolderButton { "Scan folder for TRANS macros" },
|
||||
loadTranslationButton { "Load existing translation file..."};
|
||||
|
||||
std::unique_ptr<FileChooser> chooser;
|
||||
};
|
87
deps/juce/extras/Projucer/Source/Application/Windows/jucer_UTF8WindowComponent.h
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 UTF8Component : public Component
|
||||
{
|
||||
public:
|
||||
UTF8Component()
|
||||
: desc (String(),
|
||||
"Type any string into the box, and it'll be shown below as a portable UTF-8 literal, "
|
||||
"ready to cut-and-paste into your source-code...")
|
||||
{
|
||||
desc.setJustificationType (Justification::centred);
|
||||
addAndMakeVisible (desc);
|
||||
|
||||
userText.setMultiLine (true, true);
|
||||
userText.setReturnKeyStartsNewLine (true);
|
||||
addAndMakeVisible (userText);
|
||||
userText.onTextChange = [this] { update(); };
|
||||
userText.onEscapeKey = [this] { getTopLevelComponent()->exitModalState (0); };
|
||||
|
||||
resultText.setFont (getAppSettings().appearance.getCodeFont().withHeight (13.0f));
|
||||
resultText.setMultiLine (true, true);
|
||||
resultText.setReadOnly (true);
|
||||
resultText.setSelectAllWhenFocused (true);
|
||||
addAndMakeVisible (resultText);
|
||||
|
||||
userText.setText (getLastText());
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
getLastText() = userText.getText();
|
||||
resultText.setText (CodeHelpers::stringLiteral (getLastText(), 100), false);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto r = getLocalBounds().reduced (8);
|
||||
desc.setBounds (r.removeFromTop (44));
|
||||
r.removeFromTop (8);
|
||||
userText.setBounds (r.removeFromTop (r.getHeight() / 2));
|
||||
r.removeFromTop (8);
|
||||
resultText.setBounds (r);
|
||||
}
|
||||
|
||||
void lookAndFeelChanged() override
|
||||
{
|
||||
userText.applyFontToAllText (userText.getFont());
|
||||
resultText.applyFontToAllText (resultText.getFont());
|
||||
}
|
||||
|
||||
private:
|
||||
Label desc;
|
||||
TextEditor userText, resultText;
|
||||
|
||||
String& getLastText()
|
||||
{
|
||||
static String t;
|
||||
return t;
|
||||
}
|
||||
};
|
1521
deps/juce/extras/Projucer/Source/Application/jucer_Application.cpp
vendored
Normal file
224
deps/juce/extras/Projucer/Source/Application/jucer_Application.h
vendored
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 "UserAccount/jucer_LicenseController.h"
|
||||
#include "jucer_MainWindow.h"
|
||||
#include "../Project/Modules/jucer_Modules.h"
|
||||
#include "jucer_AutoUpdater.h"
|
||||
#include "../CodeEditor/jucer_SourceCodeEditor.h"
|
||||
#include "../Utility/UI/jucer_ProjucerLookAndFeel.h"
|
||||
|
||||
//==============================================================================
|
||||
class ProjucerApplication : public JUCEApplication,
|
||||
private AsyncUpdater
|
||||
{
|
||||
public:
|
||||
ProjucerApplication() = default;
|
||||
|
||||
static ProjucerApplication& getApp();
|
||||
static ApplicationCommandManager& getCommandManager();
|
||||
|
||||
//==============================================================================
|
||||
void initialise (const String& commandLine) override;
|
||||
void shutdown() override;
|
||||
void systemRequestedQuit() override;
|
||||
void deleteLogger();
|
||||
|
||||
const String getApplicationName() override { return "Projucer"; }
|
||||
const String getApplicationVersion() override { return ProjectInfo::versionString; }
|
||||
|
||||
String getVersionDescription() const;
|
||||
bool moreThanOneInstanceAllowed() override { return true; } // this is handled manually in initialise()
|
||||
|
||||
void anotherInstanceStarted (const String& commandLine) override;
|
||||
|
||||
//==============================================================================
|
||||
MenuBarModel* getMenuModel();
|
||||
|
||||
void getAllCommands (Array<CommandID>&) override;
|
||||
void getCommandInfo (CommandID commandID, ApplicationCommandInfo&) override;
|
||||
bool perform (const InvocationInfo&) override;
|
||||
|
||||
bool isGUIEditorEnabled() const;
|
||||
|
||||
//==============================================================================
|
||||
void openFile (const File&, std::function<void (bool)>);
|
||||
void showPathsWindow (bool highlightJUCEPath = false);
|
||||
PropertiesFile::Options getPropertyFileOptionsFor (const String& filename, bool isProjectSettings);
|
||||
void selectEditorColourSchemeWithName (const String& schemeName);
|
||||
|
||||
//==============================================================================
|
||||
void rescanJUCEPathModules();
|
||||
void rescanUserPathModules();
|
||||
|
||||
AvailableModulesList& getJUCEPathModulesList() { return jucePathModulesList; }
|
||||
AvailableModulesList& getUserPathsModulesList() { return userPathsModulesList; }
|
||||
|
||||
LicenseController& getLicenseController() { return *licenseController; }
|
||||
|
||||
bool isAutomaticVersionCheckingEnabled() const;
|
||||
void setAutomaticVersionCheckingEnabled (bool shouldBeEnabled);
|
||||
|
||||
bool shouldPromptUserAboutIncorrectJUCEPath() const;
|
||||
void setShouldPromptUserAboutIncorrectJUCEPath (bool shouldPrompt);
|
||||
|
||||
static File getJUCEExamplesDirectoryPathFromGlobal() noexcept;
|
||||
static Array<File> getSortedExampleDirectories() noexcept;
|
||||
static Array<File> getSortedExampleFilesInDirectory (const File&) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
ProjucerLookAndFeel lookAndFeel;
|
||||
|
||||
std::unique_ptr<StoredSettings> settings;
|
||||
std::unique_ptr<Icons> icons;
|
||||
|
||||
struct MainMenuModel;
|
||||
std::unique_ptr<MainMenuModel> menuModel;
|
||||
|
||||
MainWindowList mainWindowList;
|
||||
OpenDocumentManager openDocumentManager;
|
||||
std::unique_ptr<ApplicationCommandManager> commandManager;
|
||||
|
||||
bool isRunningCommandLine = false;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
void handleAsyncUpdate() override;
|
||||
void doBasicApplicationSetup();
|
||||
|
||||
void initCommandManager();
|
||||
bool initialiseLogger (const char* filePrefix);
|
||||
void initialiseWindows (const String& commandLine);
|
||||
|
||||
void createNewProject();
|
||||
void createNewProjectFromClipboard();
|
||||
void createNewPIP();
|
||||
void askUserToOpenFile();
|
||||
void saveAllDocuments();
|
||||
void closeAllDocuments (OpenDocumentManager::SaveIfNeeded askUserToSave);
|
||||
void closeAllMainWindows (std::function<void (bool)>);
|
||||
void closeAllMainWindowsAndQuitIfNeeded();
|
||||
void clearRecentFiles();
|
||||
|
||||
StringArray getMenuNames();
|
||||
PopupMenu createMenu (const String& menuName);
|
||||
PopupMenu createFileMenu();
|
||||
PopupMenu createEditMenu();
|
||||
PopupMenu createViewMenu();
|
||||
void createColourSchemeItems (PopupMenu&);
|
||||
PopupMenu createWindowMenu();
|
||||
PopupMenu createDocumentMenu();
|
||||
PopupMenu createToolsMenu();
|
||||
PopupMenu createHelpMenu();
|
||||
PopupMenu createExtraAppleMenuItems();
|
||||
void handleMainMenuCommand (int menuItemID);
|
||||
PopupMenu createExamplesPopupMenu() noexcept;
|
||||
|
||||
void findAndLaunchExample (int);
|
||||
|
||||
void checkIfGlobalJUCEPathHasChanged();
|
||||
File tryToFindDemoRunnerExecutable();
|
||||
File tryToFindDemoRunnerProject();
|
||||
void launchDemoRunner();
|
||||
|
||||
void setColourScheme (int index, bool saveSetting);
|
||||
void setEditorColourScheme (int index, bool saveSetting);
|
||||
void updateEditorColourSchemeIfNeeded();
|
||||
|
||||
void showUTF8ToolWindow();
|
||||
void showSVGPathDataToolWindow();
|
||||
void showAboutWindow();
|
||||
void showEditorColourSchemeWindow();
|
||||
void showPIPCreatorWindow();
|
||||
|
||||
void launchForumBrowser();
|
||||
void launchModulesBrowser();
|
||||
void launchClassesBrowser();
|
||||
void launchTutorialsBrowser();
|
||||
|
||||
void doLoginOrLogout();
|
||||
void showLoginForm();
|
||||
|
||||
void enableOrDisableGUIEditor();
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_MAC
|
||||
class AppleMenuRebuildListener : private MenuBarModel::Listener
|
||||
{
|
||||
public:
|
||||
AppleMenuRebuildListener()
|
||||
{
|
||||
if (auto* model = ProjucerApplication::getApp().getMenuModel())
|
||||
model->addListener (this);
|
||||
}
|
||||
|
||||
~AppleMenuRebuildListener() override
|
||||
{
|
||||
if (auto* model = ProjucerApplication::getApp().getMenuModel())
|
||||
model->removeListener (this);
|
||||
}
|
||||
|
||||
private:
|
||||
void menuBarItemsChanged (MenuBarModel*) override {}
|
||||
|
||||
void menuCommandInvoked (MenuBarModel*,
|
||||
const ApplicationCommandTarget::InvocationInfo& info) override
|
||||
{
|
||||
if (info.commandID == CommandIDs::enableNewVersionCheck)
|
||||
Timer::callAfterDelay (50, [] { ProjucerApplication::getApp().rebuildAppleMenu(); });
|
||||
}
|
||||
};
|
||||
|
||||
void rebuildAppleMenu();
|
||||
|
||||
std::unique_ptr<AppleMenuRebuildListener> appleMenuRebuildListener;
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
std::unique_ptr<LicenseController> licenseController;
|
||||
|
||||
std::unique_ptr<TooltipWindow> tooltipWindow;
|
||||
AvailableModulesList jucePathModulesList, userPathsModulesList;
|
||||
|
||||
std::unique_ptr<Component> utf8Window, svgPathWindow, aboutWindow, pathsWindow,
|
||||
editorColourSchemeWindow, pipCreatorWindow;
|
||||
|
||||
std::unique_ptr<FileLogger> logger;
|
||||
|
||||
int numExamples = 0;
|
||||
std::unique_ptr<AlertWindow> demoRunnerAlert;
|
||||
bool hasScannedForDemoRunnerExecutable = false, hasScannedForDemoRunnerProject = false;
|
||||
File lastJUCEPath, lastDemoRunnerExectuableFile, lastDemoRunnerProjectFile;
|
||||
|
||||
int selectedColourSchemeIndex = 0, selectedEditorColourSchemeIndex = 0;
|
||||
|
||||
std::unique_ptr<FileChooser> chooser;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjucerApplication)
|
||||
JUCE_DECLARE_WEAK_REFERENCEABLE (ProjucerApplication)
|
||||
};
|
560
deps/juce/extras/Projucer/Source/Application/jucer_AutoUpdater.cpp
vendored
Normal file
@ -0,0 +1,560 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 "../Application/jucer_Headers.h"
|
||||
#include "jucer_Application.h"
|
||||
#include "jucer_AutoUpdater.h"
|
||||
|
||||
//==============================================================================
|
||||
LatestVersionCheckerAndUpdater::LatestVersionCheckerAndUpdater()
|
||||
: Thread ("VersionChecker")
|
||||
{
|
||||
}
|
||||
|
||||
LatestVersionCheckerAndUpdater::~LatestVersionCheckerAndUpdater()
|
||||
{
|
||||
stopThread (6000);
|
||||
clearSingletonInstance();
|
||||
}
|
||||
|
||||
void LatestVersionCheckerAndUpdater::checkForNewVersion (bool background)
|
||||
{
|
||||
if (! isThreadRunning())
|
||||
{
|
||||
backgroundCheck = background;
|
||||
startThread (3);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void LatestVersionCheckerAndUpdater::run()
|
||||
{
|
||||
auto info = VersionInfo::fetchLatestFromUpdateServer();
|
||||
|
||||
if (info == nullptr)
|
||||
{
|
||||
if (! backgroundCheck)
|
||||
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
|
||||
"Update Server Communication Error",
|
||||
"Failed to communicate with the JUCE update server.\n"
|
||||
"Please try again in a few minutes.\n\n"
|
||||
"If this problem persists you can download the latest version of JUCE from juce.com");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (! info->isNewerVersionThanCurrent())
|
||||
{
|
||||
if (! backgroundCheck)
|
||||
AlertWindow::showMessageBoxAsync (MessageBoxIconType::InfoIcon,
|
||||
"No New Version Available",
|
||||
"Your JUCE version is up to date.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto osString = []
|
||||
{
|
||||
#if JUCE_MAC
|
||||
return "osx";
|
||||
#elif JUCE_WINDOWS
|
||||
return "windows";
|
||||
#elif JUCE_LINUX
|
||||
return "linux";
|
||||
#elif JUCE_BSD
|
||||
return "bsd";
|
||||
#else
|
||||
jassertfalse;
|
||||
return "Unknown";
|
||||
#endif
|
||||
}();
|
||||
|
||||
String requiredFilename ("juce-" + info->versionString + "-" + osString + ".zip");
|
||||
|
||||
for (auto& asset : info->assets)
|
||||
{
|
||||
if (asset.name == requiredFilename)
|
||||
{
|
||||
auto versionString = info->versionString;
|
||||
auto releaseNotes = info->releaseNotes;
|
||||
|
||||
MessageManager::callAsync ([this, versionString, releaseNotes, asset]
|
||||
{
|
||||
askUserAboutNewVersion (versionString, releaseNotes, asset);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (! backgroundCheck)
|
||||
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
|
||||
"Failed to find any new downloads",
|
||||
"Please try again in a few minutes.");
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class UpdateDialog : public Component
|
||||
{
|
||||
public:
|
||||
UpdateDialog (const String& newVersion, const String& releaseNotes)
|
||||
{
|
||||
titleLabel.setText ("JUCE version " + newVersion, dontSendNotification);
|
||||
titleLabel.setFont ({ 15.0f, Font::bold });
|
||||
titleLabel.setJustificationType (Justification::centred);
|
||||
addAndMakeVisible (titleLabel);
|
||||
|
||||
contentLabel.setText ("A new version of JUCE is available - would you like to download it?", dontSendNotification);
|
||||
contentLabel.setFont (15.0f);
|
||||
contentLabel.setJustificationType (Justification::topLeft);
|
||||
addAndMakeVisible (contentLabel);
|
||||
|
||||
releaseNotesLabel.setText ("Release notes:", dontSendNotification);
|
||||
releaseNotesLabel.setFont (15.0f);
|
||||
releaseNotesLabel.setJustificationType (Justification::topLeft);
|
||||
addAndMakeVisible (releaseNotesLabel);
|
||||
|
||||
releaseNotesEditor.setMultiLine (true);
|
||||
releaseNotesEditor.setReadOnly (true);
|
||||
releaseNotesEditor.setText (releaseNotes);
|
||||
addAndMakeVisible (releaseNotesEditor);
|
||||
|
||||
addAndMakeVisible (chooseButton);
|
||||
chooseButton.onClick = [this] { exitModalStateWithResult (1); };
|
||||
|
||||
addAndMakeVisible (cancelButton);
|
||||
cancelButton.onClick = [this]
|
||||
{
|
||||
ProjucerApplication::getApp().setAutomaticVersionCheckingEnabled (! dontAskAgainButton.getToggleState());
|
||||
exitModalStateWithResult (-1);
|
||||
};
|
||||
|
||||
dontAskAgainButton.setToggleState (! ProjucerApplication::getApp().isAutomaticVersionCheckingEnabled(), dontSendNotification);
|
||||
addAndMakeVisible (dontAskAgainButton);
|
||||
|
||||
juceIcon = Drawable::createFromImageData (BinaryData::juce_icon_png,
|
||||
BinaryData::juce_icon_pngSize);
|
||||
lookAndFeelChanged();
|
||||
|
||||
setSize (500, 280);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
auto b = getLocalBounds().reduced (10);
|
||||
|
||||
auto topSlice = b.removeFromTop (juceIconBounds.getHeight())
|
||||
.withTrimmedLeft (juceIconBounds.getWidth());
|
||||
|
||||
titleLabel.setBounds (topSlice.removeFromTop (25));
|
||||
topSlice.removeFromTop (5);
|
||||
contentLabel.setBounds (topSlice.removeFromTop (25));
|
||||
|
||||
auto buttonBounds = b.removeFromBottom (60);
|
||||
buttonBounds.removeFromBottom (25);
|
||||
chooseButton.setBounds (buttonBounds.removeFromLeft (buttonBounds.getWidth() / 2).reduced (20, 0));
|
||||
cancelButton.setBounds (buttonBounds.reduced (20, 0));
|
||||
dontAskAgainButton.setBounds (cancelButton.getBounds().withY (cancelButton.getBottom() + 5).withHeight (20));
|
||||
|
||||
releaseNotesEditor.setBounds (b.reduced (0, 10));
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (backgroundColourId));
|
||||
|
||||
if (juceIcon != nullptr)
|
||||
juceIcon->drawWithin (g, juceIconBounds.toFloat(),
|
||||
RectanglePlacement::stretchToFit, 1.0f);
|
||||
}
|
||||
|
||||
static std::unique_ptr<DialogWindow> launchDialog (const String& newVersionString,
|
||||
const String& releaseNotes)
|
||||
{
|
||||
DialogWindow::LaunchOptions options;
|
||||
|
||||
options.dialogTitle = "Download JUCE version " + newVersionString + "?";
|
||||
options.resizable = false;
|
||||
|
||||
auto* content = new UpdateDialog (newVersionString, releaseNotes);
|
||||
options.content.set (content, true);
|
||||
|
||||
std::unique_ptr<DialogWindow> dialog (options.create());
|
||||
|
||||
content->setParentWindow (dialog.get());
|
||||
dialog->enterModalState (true, nullptr, true);
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private:
|
||||
void lookAndFeelChanged() override
|
||||
{
|
||||
cancelButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId));
|
||||
releaseNotesEditor.applyFontToAllText (releaseNotesEditor.getFont());
|
||||
}
|
||||
|
||||
void setParentWindow (DialogWindow* parent)
|
||||
{
|
||||
parentWindow = parent;
|
||||
}
|
||||
|
||||
void exitModalStateWithResult (int result)
|
||||
{
|
||||
if (parentWindow != nullptr)
|
||||
parentWindow->exitModalState (result);
|
||||
}
|
||||
|
||||
Label titleLabel, contentLabel, releaseNotesLabel;
|
||||
TextEditor releaseNotesEditor;
|
||||
TextButton chooseButton { "Choose Location..." }, cancelButton { "Cancel" };
|
||||
ToggleButton dontAskAgainButton { "Don't ask again" };
|
||||
std::unique_ptr<Drawable> juceIcon;
|
||||
Rectangle<int> juceIconBounds { 10, 10, 64, 64 };
|
||||
|
||||
DialogWindow* parentWindow = nullptr;
|
||||
};
|
||||
|
||||
void LatestVersionCheckerAndUpdater::askUserForLocationToDownload (const VersionInfo::Asset& asset)
|
||||
{
|
||||
chooser = std::make_unique<FileChooser> ("Please select the location into which you would like to install the new version",
|
||||
File { getAppSettings().getStoredPath (Ids::jucePath, TargetOS::getThisOS()).get() });
|
||||
|
||||
chooser->launchAsync (FileBrowserComponent::openMode | FileBrowserComponent::canSelectDirectories,
|
||||
[weakThis = WeakReference<LatestVersionCheckerAndUpdater> { this }, asset] (const FileChooser& fc)
|
||||
{
|
||||
auto targetFolder = fc.getResult();
|
||||
|
||||
if (targetFolder == File{})
|
||||
return;
|
||||
|
||||
// By default we will install into 'targetFolder/JUCE', but we should install into
|
||||
// 'targetFolder' if that is an existing JUCE directory.
|
||||
bool willOverwriteJuceFolder = [&targetFolder]
|
||||
{
|
||||
if (isJUCEFolder (targetFolder))
|
||||
return true;
|
||||
|
||||
targetFolder = targetFolder.getChildFile ("JUCE");
|
||||
|
||||
return isJUCEFolder (targetFolder);
|
||||
}();
|
||||
|
||||
auto targetFolderPath = targetFolder.getFullPathName();
|
||||
|
||||
const auto onResult = [weakThis, asset, targetFolder] (int result)
|
||||
{
|
||||
if (weakThis == nullptr || result == 0)
|
||||
return;
|
||||
|
||||
weakThis->downloadAndInstall (asset, targetFolder);
|
||||
};
|
||||
|
||||
if (willOverwriteJuceFolder)
|
||||
{
|
||||
if (targetFolder.getChildFile (".git").isDirectory())
|
||||
{
|
||||
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon, "Downloading New JUCE Version",
|
||||
targetFolderPath + "\n\nis a GIT repository!\n\nYou should use a \"git pull\" to update it to the latest version.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
AlertWindow::showOkCancelBox (MessageBoxIconType::WarningIcon,
|
||||
"Overwrite Existing JUCE Folder?",
|
||||
"Do you want to replace the folder\n\n" + targetFolderPath + "\n\nwith the latest version from juce.com?\n\n"
|
||||
"This will move the existing folder to " + targetFolderPath + "_old.\n\n"
|
||||
"Replacing the folder that contains the currently running Projucer executable may not work on Windows.",
|
||||
{},
|
||||
{},
|
||||
nullptr,
|
||||
ModalCallbackFunction::create (onResult));
|
||||
return;
|
||||
}
|
||||
|
||||
if (targetFolder.exists())
|
||||
{
|
||||
AlertWindow::showOkCancelBox (MessageBoxIconType::WarningIcon,
|
||||
"Existing File Or Directory",
|
||||
"Do you want to move\n\n" + targetFolderPath + "\n\nto\n\n" + targetFolderPath + "_old?",
|
||||
{},
|
||||
{},
|
||||
nullptr,
|
||||
ModalCallbackFunction::create (onResult));
|
||||
return;
|
||||
}
|
||||
|
||||
if (weakThis != nullptr)
|
||||
weakThis->downloadAndInstall (asset, targetFolder);
|
||||
});
|
||||
}
|
||||
|
||||
void LatestVersionCheckerAndUpdater::askUserAboutNewVersion (const String& newVersionString,
|
||||
const String& releaseNotes,
|
||||
const VersionInfo::Asset& asset)
|
||||
{
|
||||
if (backgroundCheck)
|
||||
addNotificationToOpenProjects (asset);
|
||||
else
|
||||
showDialogWindow (newVersionString, releaseNotes, asset);
|
||||
}
|
||||
|
||||
void LatestVersionCheckerAndUpdater::showDialogWindow (const String& newVersionString,
|
||||
const String& releaseNotes,
|
||||
const VersionInfo::Asset& asset)
|
||||
{
|
||||
dialogWindow = UpdateDialog::launchDialog (newVersionString, releaseNotes);
|
||||
|
||||
if (auto* mm = ModalComponentManager::getInstance())
|
||||
{
|
||||
mm->attachCallback (dialogWindow.get(),
|
||||
ModalCallbackFunction::create ([this, asset] (int result)
|
||||
{
|
||||
if (result == 1)
|
||||
askUserForLocationToDownload (asset);
|
||||
|
||||
dialogWindow.reset();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
void LatestVersionCheckerAndUpdater::addNotificationToOpenProjects (const VersionInfo::Asset& asset)
|
||||
{
|
||||
for (auto* window : ProjucerApplication::getApp().mainWindowList.windows)
|
||||
{
|
||||
if (auto* project = window->getProject())
|
||||
{
|
||||
auto ignore = [safeWindow = Component::SafePointer<MainWindow> { window }]
|
||||
{
|
||||
if (safeWindow != nullptr)
|
||||
safeWindow->getProject()->removeProjectMessage (ProjectMessages::Ids::newVersionAvailable);
|
||||
};
|
||||
|
||||
auto dontAskAgain = [ignore]
|
||||
{
|
||||
ignore();
|
||||
ProjucerApplication::getApp().setAutomaticVersionCheckingEnabled (false);
|
||||
};
|
||||
|
||||
project->addProjectMessage (ProjectMessages::Ids::newVersionAvailable,
|
||||
{ { "Download", [this, asset] { askUserForLocationToDownload (asset); } },
|
||||
{ "Ignore", std::move (ignore) },
|
||||
{ "Don't ask again", std::move (dontAskAgain) } });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class DownloadAndInstallThread : private ThreadWithProgressWindow
|
||||
{
|
||||
public:
|
||||
DownloadAndInstallThread (const VersionInfo::Asset& a, const File& t, std::function<void()>&& cb)
|
||||
: ThreadWithProgressWindow ("Downloading New Version", true, true),
|
||||
asset (a), targetFolder (t), completionCallback (std::move (cb))
|
||||
{
|
||||
launchThread (3);
|
||||
}
|
||||
|
||||
private:
|
||||
void run() override
|
||||
{
|
||||
setProgress (-1.0);
|
||||
|
||||
MemoryBlock zipData;
|
||||
auto result = download (zipData);
|
||||
|
||||
if (result.wasOk() && ! threadShouldExit())
|
||||
result = install (zipData);
|
||||
|
||||
if (result.failed())
|
||||
MessageManager::callAsync ([result] { AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
|
||||
"Installation Failed",
|
||||
result.getErrorMessage()); });
|
||||
else
|
||||
MessageManager::callAsync (completionCallback);
|
||||
}
|
||||
|
||||
Result download (MemoryBlock& dest)
|
||||
{
|
||||
setStatusMessage ("Downloading...");
|
||||
|
||||
int statusCode = 0;
|
||||
auto inStream = VersionInfo::createInputStreamForAsset (asset, statusCode);
|
||||
|
||||
if (inStream != nullptr && statusCode == 200)
|
||||
{
|
||||
int64 total = 0;
|
||||
MemoryOutputStream mo (dest, true);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (threadShouldExit())
|
||||
return Result::fail ("Cancelled");
|
||||
|
||||
auto written = mo.writeFromInputStream (*inStream, 8192);
|
||||
|
||||
if (written == 0)
|
||||
break;
|
||||
|
||||
total += written;
|
||||
|
||||
setStatusMessage ("Downloading... " + File::descriptionOfSizeInBytes (total));
|
||||
}
|
||||
|
||||
return Result::ok();
|
||||
}
|
||||
|
||||
return Result::fail ("Failed to download from: " + asset.url);
|
||||
}
|
||||
|
||||
Result install (const MemoryBlock& data)
|
||||
{
|
||||
setStatusMessage ("Installing...");
|
||||
|
||||
MemoryInputStream input (data, false);
|
||||
ZipFile zip (input);
|
||||
|
||||
if (zip.getNumEntries() == 0)
|
||||
return Result::fail ("The downloaded file was not a valid JUCE file!");
|
||||
|
||||
struct ScopedDownloadFolder
|
||||
{
|
||||
explicit ScopedDownloadFolder (const File& installTargetFolder)
|
||||
{
|
||||
folder = installTargetFolder.getSiblingFile (installTargetFolder.getFileNameWithoutExtension() + "_download").getNonexistentSibling();
|
||||
jassert (folder.createDirectory());
|
||||
}
|
||||
|
||||
~ScopedDownloadFolder() { folder.deleteRecursively(); }
|
||||
|
||||
File folder;
|
||||
};
|
||||
|
||||
ScopedDownloadFolder unzipTarget (targetFolder);
|
||||
|
||||
if (! unzipTarget.folder.isDirectory())
|
||||
return Result::fail ("Couldn't create a temporary folder to unzip the new version!");
|
||||
|
||||
auto r = zip.uncompressTo (unzipTarget.folder);
|
||||
|
||||
if (r.failed())
|
||||
return r;
|
||||
|
||||
if (threadShouldExit())
|
||||
return Result::fail ("Cancelled");
|
||||
|
||||
#if JUCE_LINUX || JUCE_BSD || JUCE_MAC
|
||||
r = setFilePermissions (unzipTarget.folder, zip);
|
||||
|
||||
if (r.failed())
|
||||
return r;
|
||||
|
||||
if (threadShouldExit())
|
||||
return Result::fail ("Cancelled");
|
||||
#endif
|
||||
|
||||
if (targetFolder.exists())
|
||||
{
|
||||
auto oldFolder = targetFolder.getSiblingFile (targetFolder.getFileNameWithoutExtension() + "_old").getNonexistentSibling();
|
||||
|
||||
if (! targetFolder.moveFileTo (oldFolder))
|
||||
return Result::fail ("Could not remove the existing folder!\n\n"
|
||||
"This may happen if you are trying to download into a directory that requires administrator privileges to modify.\n"
|
||||
"Please select a folder that is writable by the current user.");
|
||||
}
|
||||
|
||||
if (! unzipTarget.folder.getChildFile ("JUCE").moveFileTo (targetFolder))
|
||||
return Result::fail ("Could not overwrite the existing folder!\n\n"
|
||||
"This may happen if you are trying to download into a directory that requires administrator privileges to modify.\n"
|
||||
"Please select a folder that is writable by the current user.");
|
||||
|
||||
return Result::ok();
|
||||
}
|
||||
|
||||
Result setFilePermissions (const File& root, const ZipFile& zip)
|
||||
{
|
||||
constexpr uint32 executableFlag = (1 << 22);
|
||||
|
||||
for (int i = 0; i < zip.getNumEntries(); ++i)
|
||||
{
|
||||
auto* entry = zip.getEntry (i);
|
||||
|
||||
if ((entry->externalFileAttributes & executableFlag) != 0 && entry->filename.getLastCharacter() != '/')
|
||||
{
|
||||
auto exeFile = root.getChildFile (entry->filename);
|
||||
|
||||
if (! exeFile.exists())
|
||||
return Result::fail ("Failed to find executable file when setting permissions " + exeFile.getFileName());
|
||||
|
||||
if (! exeFile.setExecutePermission (true))
|
||||
return Result::fail ("Failed to set executable file permission for " + exeFile.getFileName());
|
||||
}
|
||||
}
|
||||
|
||||
return Result::ok();
|
||||
}
|
||||
|
||||
VersionInfo::Asset asset;
|
||||
File targetFolder;
|
||||
std::function<void()> completionCallback;
|
||||
};
|
||||
|
||||
static void restartProcess (const File& targetFolder)
|
||||
{
|
||||
#if JUCE_MAC || JUCE_LINUX || JUCE_BSD
|
||||
#if JUCE_MAC
|
||||
auto newProcess = targetFolder.getChildFile ("Projucer.app").getChildFile ("Contents").getChildFile ("MacOS").getChildFile ("Projucer");
|
||||
#elif JUCE_LINUX || JUCE_BSD
|
||||
auto newProcess = targetFolder.getChildFile ("Projucer");
|
||||
#endif
|
||||
|
||||
StringArray command ("/bin/sh", "-c", "while killall -0 Projucer; do sleep 5; done; " + newProcess.getFullPathName().quoted());
|
||||
#elif JUCE_WINDOWS
|
||||
auto newProcess = targetFolder.getChildFile ("Projucer.exe");
|
||||
|
||||
auto command = "cmd.exe /c\"@echo off & for /l %a in (0) do ( tasklist | find \"Projucer\" >nul & ( if errorlevel 1 ( "
|
||||
+ targetFolder.getChildFile ("Projucer.exe").getFullPathName().quoted() + " & exit /b ) else ( timeout /t 10 >nul ) ) )\"";
|
||||
#endif
|
||||
|
||||
if (newProcess.existsAsFile())
|
||||
{
|
||||
ChildProcess restartProcess;
|
||||
restartProcess.start (command, 0);
|
||||
|
||||
ProjucerApplication::getApp().systemRequestedQuit();
|
||||
}
|
||||
}
|
||||
|
||||
void LatestVersionCheckerAndUpdater::downloadAndInstall (const VersionInfo::Asset& asset, const File& targetFolder)
|
||||
{
|
||||
installer.reset (new DownloadAndInstallThread (asset, targetFolder,
|
||||
[this, targetFolder]
|
||||
{
|
||||
installer.reset();
|
||||
restartProcess (targetFolder);
|
||||
}));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
JUCE_IMPLEMENT_SINGLETON (LatestVersionCheckerAndUpdater)
|
62
deps/juce/extras/Projucer/Source/Application/jucer_AutoUpdater.h
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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_VersionInfo.h"
|
||||
|
||||
class DownloadAndInstallThread;
|
||||
|
||||
class LatestVersionCheckerAndUpdater : public DeletedAtShutdown,
|
||||
private Thread
|
||||
{
|
||||
public:
|
||||
LatestVersionCheckerAndUpdater();
|
||||
~LatestVersionCheckerAndUpdater() override;
|
||||
|
||||
void checkForNewVersion (bool isBackgroundCheck);
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (LatestVersionCheckerAndUpdater)
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
void run() override;
|
||||
void askUserAboutNewVersion (const String&, const String&, const VersionInfo::Asset&);
|
||||
void askUserForLocationToDownload (const VersionInfo::Asset&);
|
||||
void downloadAndInstall (const VersionInfo::Asset&, const File&);
|
||||
|
||||
void showDialogWindow (const String&, const String&, const VersionInfo::Asset&);
|
||||
void addNotificationToOpenProjects (const VersionInfo::Asset&);
|
||||
|
||||
//==============================================================================
|
||||
bool backgroundCheck = false;
|
||||
|
||||
std::unique_ptr<DownloadAndInstallThread> installer;
|
||||
std::unique_ptr<Component> dialogWindow;
|
||||
std::unique_ptr<FileChooser> chooser;
|
||||
|
||||
JUCE_DECLARE_WEAK_REFERENCEABLE (LatestVersionCheckerAndUpdater)
|
||||
};
|
108
deps/juce/extras/Projucer/Source/Application/jucer_CommandIDs.h
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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
|
||||
|
||||
/**
|
||||
A namespace to hold all the possible command IDs.
|
||||
*/
|
||||
namespace CommandIDs
|
||||
{
|
||||
enum
|
||||
{
|
||||
newProject = 0x300000,
|
||||
newProjectFromClipboard = 0x300001,
|
||||
newPIP = 0x300002,
|
||||
open = 0x300003,
|
||||
closeDocument = 0x300004,
|
||||
saveDocument = 0x300005,
|
||||
saveDocumentAs = 0x300006,
|
||||
|
||||
launchDemoRunner = 0x300007,
|
||||
|
||||
closeProject = 0x300010,
|
||||
saveProject = 0x300011,
|
||||
saveAll = 0x300012,
|
||||
openInIDE = 0x300013,
|
||||
saveAndOpenInIDE = 0x300014,
|
||||
createNewExporter = 0x300015,
|
||||
|
||||
showUTF8Tool = 0x300020,
|
||||
showGlobalPathsWindow = 0x300021,
|
||||
showTranslationTool = 0x300022,
|
||||
showSVGPathTool = 0x300023,
|
||||
showAboutWindow = 0x300024,
|
||||
checkForNewVersion = 0x300025,
|
||||
enableNewVersionCheck = 0x300026,
|
||||
enableGUIEditor = 0x300027,
|
||||
|
||||
showProjectSettings = 0x300030,
|
||||
showFileExplorerPanel = 0x300033,
|
||||
showModulesPanel = 0x300034,
|
||||
showExportersPanel = 0x300035,
|
||||
showExporterSettings = 0x300036,
|
||||
|
||||
closeWindow = 0x300040,
|
||||
closeAllWindows = 0x300041,
|
||||
closeAllDocuments = 0x300042,
|
||||
goToPreviousDoc = 0x300043,
|
||||
goToNextDoc = 0x300044,
|
||||
goToCounterpart = 0x300045,
|
||||
deleteSelectedItem = 0x300046,
|
||||
goToPreviousWindow = 0x300047,
|
||||
goToNextWindow = 0x300048,
|
||||
clearRecentFiles = 0x300049,
|
||||
|
||||
showFindPanel = 0x300050,
|
||||
findSelection = 0x300051,
|
||||
findNext = 0x300052,
|
||||
findPrevious = 0x300053,
|
||||
|
||||
enableSnapToGrid = 0x300070,
|
||||
zoomIn = 0x300071,
|
||||
zoomOut = 0x300072,
|
||||
zoomNormal = 0x300073,
|
||||
spaceBarDrag = 0x300074,
|
||||
|
||||
loginLogout = 0x300090,
|
||||
|
||||
showForum = 0x300100,
|
||||
showAPIModules = 0x300101,
|
||||
showAPIClasses = 0x300102,
|
||||
showTutorials = 0x300103,
|
||||
|
||||
addNewGUIFile = 0x300200,
|
||||
|
||||
lastCommandIDEntry
|
||||
};
|
||||
}
|
||||
|
||||
namespace CommandCategories
|
||||
{
|
||||
static const char* const general = "General";
|
||||
static const char* const editing = "Editing";
|
||||
static const char* const view = "View";
|
||||
static const char* const windows = "Windows";
|
||||
}
|
933
deps/juce/extras/Projucer/Source/Application/jucer_CommandLine.cpp
vendored
Normal file
@ -0,0 +1,933 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 "../Utility/Helpers/jucer_TranslationHelpers.h"
|
||||
|
||||
#include "jucer_CommandLine.h"
|
||||
|
||||
//==============================================================================
|
||||
const char* preferredLineFeed = "\r\n";
|
||||
const char* getPreferredLineFeed() { return preferredLineFeed; }
|
||||
|
||||
//==============================================================================
|
||||
namespace
|
||||
{
|
||||
static void hideDockIcon()
|
||||
{
|
||||
#if JUCE_MAC
|
||||
Process::setDockIconVisible (false);
|
||||
#endif
|
||||
}
|
||||
|
||||
static Array<File> findAllSourceFiles (const File& folder)
|
||||
{
|
||||
Array<File> files;
|
||||
|
||||
for (const auto& di : RangedDirectoryIterator (folder, true, "*.cpp;*.cxx;*.cc;*.c;*.h;*.hpp;*.hxx;*.hpp;*.mm;*.m;*.java;*.dox;*.soul;*.js", File::findFiles))
|
||||
if (! di.getFile().isSymbolicLink())
|
||||
files.add (di.getFile());
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
static void replaceFile (const File& file, const String& newText, const String& message)
|
||||
{
|
||||
std::cout << message << file.getFullPathName() << std::endl;
|
||||
|
||||
TemporaryFile temp (file);
|
||||
|
||||
if (! temp.getFile().replaceWithText (newText, false, false, nullptr))
|
||||
ConsoleApplication::fail ("!!! ERROR Couldn't write to temp file!");
|
||||
|
||||
if (! temp.overwriteTargetFileWithTemporary())
|
||||
ConsoleApplication::fail ("!!! ERROR Couldn't write to file!");
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct LoadedProject
|
||||
{
|
||||
explicit LoadedProject (const ArgumentList::Argument& fileToLoad)
|
||||
{
|
||||
hideDockIcon();
|
||||
|
||||
auto projectFile = fileToLoad.resolveAsExistingFile();
|
||||
|
||||
if (! projectFile.hasFileExtension (Project::projectFileExtension))
|
||||
ConsoleApplication::fail (projectFile.getFullPathName() + " isn't a valid jucer project file!");
|
||||
|
||||
project.reset (new Project (projectFile));
|
||||
|
||||
if (! project->loadFrom (projectFile, true, false))
|
||||
{
|
||||
project.reset();
|
||||
ConsoleApplication::fail ("Failed to load the project file: " + projectFile.getFullPathName());
|
||||
}
|
||||
|
||||
preferredLineFeed = project->getProjectLineFeed().toRawUTF8();
|
||||
}
|
||||
|
||||
void save (bool justSaveResources, bool fixMissingDependencies)
|
||||
{
|
||||
if (project != nullptr)
|
||||
{
|
||||
if (! justSaveResources)
|
||||
rescanModulePathsIfNecessary();
|
||||
|
||||
if (fixMissingDependencies)
|
||||
tryToFixMissingModuleDependencies();
|
||||
|
||||
const auto onCompletion = [this] (Result result)
|
||||
{
|
||||
project.reset();
|
||||
|
||||
if (result.failed())
|
||||
ConsoleApplication::fail ("Error when saving: " + result.getErrorMessage());
|
||||
};
|
||||
|
||||
if (justSaveResources)
|
||||
onCompletion (project->saveResourcesOnly());
|
||||
else
|
||||
project->saveProject (Async::no, nullptr, onCompletion);
|
||||
}
|
||||
}
|
||||
|
||||
void rescanModulePathsIfNecessary()
|
||||
{
|
||||
bool scanJUCEPath = false, scanUserPaths = false;
|
||||
|
||||
const auto& modules = project->getEnabledModules();
|
||||
|
||||
for (auto i = modules.getNumModules(); --i >= 0;)
|
||||
{
|
||||
const auto& id = modules.getModuleID (i);
|
||||
|
||||
if (isJUCEModule (id) && ! scanJUCEPath)
|
||||
{
|
||||
if (modules.shouldUseGlobalPath (id))
|
||||
scanJUCEPath = true;
|
||||
}
|
||||
else if (! scanUserPaths)
|
||||
{
|
||||
if (modules.shouldUseGlobalPath (id))
|
||||
scanUserPaths = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (scanJUCEPath)
|
||||
ProjucerApplication::getApp().rescanJUCEPathModules();
|
||||
|
||||
if (scanUserPaths)
|
||||
ProjucerApplication::getApp().rescanUserPathModules();
|
||||
}
|
||||
|
||||
void tryToFixMissingModuleDependencies()
|
||||
{
|
||||
auto& modules = project->getEnabledModules();
|
||||
|
||||
for (const auto& m : modules.getModulesWithMissingDependencies())
|
||||
modules.tryToFixMissingDependencies (m);
|
||||
}
|
||||
|
||||
std::unique_ptr<Project> project;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/* Running a command-line of the form "projucer --resave foobar.jucer" will try to load
|
||||
that project and re-export all of its targets.
|
||||
*/
|
||||
static void resaveProject (const ArgumentList& args, bool justSaveResources)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
LoadedProject proj (args[1]);
|
||||
|
||||
std::cout << (justSaveResources ? "Re-saving project resources: "
|
||||
: "Re-saving file: ")
|
||||
<< proj.project->getFile().getFullPathName() << std::endl;
|
||||
|
||||
proj.save (justSaveResources, args.containsOption ("--fix-missing-dependencies"));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static void getVersion (const ArgumentList& args)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
LoadedProject proj (args[1]);
|
||||
|
||||
std::cout << proj.project->getVersionString() << std::endl;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static void setVersion (const ArgumentList& args)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
LoadedProject proj (args[2]);
|
||||
|
||||
String version (args[1].text.trim());
|
||||
|
||||
std::cout << "Setting project version: " << version << std::endl;
|
||||
|
||||
proj.project->setProjectVersion (version);
|
||||
proj.save (false, false);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static void bumpVersion (const ArgumentList& args)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
LoadedProject proj (args[1]);
|
||||
|
||||
String version = proj.project->getVersionString();
|
||||
|
||||
version = version.upToLastOccurrenceOf (".", true, false)
|
||||
+ String (version.getTrailingIntValue() + 1);
|
||||
|
||||
std::cout << "Bumping project version to: " << version << std::endl;
|
||||
|
||||
proj.project->setProjectVersion (version);
|
||||
proj.save (false, false);
|
||||
}
|
||||
|
||||
static void gitTag (const ArgumentList& args)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
LoadedProject proj (args[1]);
|
||||
|
||||
String version (proj.project->getVersionString());
|
||||
|
||||
if (version.trim().isEmpty())
|
||||
ConsoleApplication::fail ("Cannot read version number from project!");
|
||||
|
||||
StringArray command;
|
||||
command.add ("git");
|
||||
command.add ("tag");
|
||||
command.add ("-a");
|
||||
command.add (version);
|
||||
command.add ("-m");
|
||||
command.add (version.quoted());
|
||||
|
||||
std::cout << "Performing command: " << command.joinIntoString(" ") << std::endl;
|
||||
|
||||
ChildProcess c;
|
||||
|
||||
if (! c.start (command, 0))
|
||||
ConsoleApplication::fail ("Cannot run git!");
|
||||
|
||||
c.waitForProcessToFinish (10000);
|
||||
|
||||
if (c.getExitCode() != 0)
|
||||
ConsoleApplication::fail ("git command failed!");
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static void showStatus (const ArgumentList& args)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
|
||||
LoadedProject proj (args[1]);
|
||||
|
||||
std::cout << "Project file: " << proj.project->getFile().getFullPathName() << std::endl
|
||||
<< "Name: " << proj.project->getProjectNameString() << std::endl
|
||||
<< "UID: " << proj.project->getProjectUIDString() << std::endl;
|
||||
|
||||
auto& modules = proj.project->getEnabledModules();
|
||||
|
||||
if (int numModules = modules.getNumModules())
|
||||
{
|
||||
std::cout << "Modules:" << std::endl;
|
||||
|
||||
for (int i = 0; i < numModules; ++i)
|
||||
std::cout << " " << modules.getModuleID (i) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static String getModulePackageName (const LibraryModule& module)
|
||||
{
|
||||
return module.getID() + ".jucemodule";
|
||||
}
|
||||
|
||||
static void zipModule (const File& targetFolder, const File& moduleFolder)
|
||||
{
|
||||
jassert (targetFolder.isDirectory());
|
||||
|
||||
auto moduleFolderParent = moduleFolder.getParentDirectory();
|
||||
LibraryModule module (moduleFolder);
|
||||
|
||||
if (! module.isValid())
|
||||
ConsoleApplication::fail (moduleFolder.getFullPathName() + " is not a valid module folder!");
|
||||
|
||||
auto targetFile = targetFolder.getChildFile (getModulePackageName (module));
|
||||
|
||||
ZipFile::Builder zip;
|
||||
|
||||
{
|
||||
for (const auto& i : RangedDirectoryIterator (moduleFolder, true, "*", File::findFiles))
|
||||
if (! i.getFile().isHidden())
|
||||
zip.addFile (i.getFile(), 9, i.getFile().getRelativePathFrom (moduleFolderParent));
|
||||
}
|
||||
|
||||
std::cout << "Writing: " << targetFile.getFullPathName() << std::endl;
|
||||
|
||||
TemporaryFile temp (targetFile);
|
||||
|
||||
{
|
||||
FileOutputStream out (temp.getFile());
|
||||
|
||||
if (! (out.openedOk() && zip.writeToStream (out, nullptr)))
|
||||
ConsoleApplication::fail ("Failed to write to the target file: " + targetFile.getFullPathName());
|
||||
}
|
||||
|
||||
if (! temp.overwriteTargetFileWithTemporary())
|
||||
ConsoleApplication::fail ("Failed to write to the target file: " + targetFile.getFullPathName());
|
||||
}
|
||||
|
||||
static void buildModules (const ArgumentList& args, const bool buildAllWithIndex)
|
||||
{
|
||||
hideDockIcon();
|
||||
args.checkMinNumArguments (3);
|
||||
|
||||
auto targetFolder = args[1].resolveAsFile();
|
||||
|
||||
if (! targetFolder.isDirectory())
|
||||
ConsoleApplication::fail ("The first argument must be the directory to put the result.");
|
||||
|
||||
if (buildAllWithIndex)
|
||||
{
|
||||
auto folderToSearch = args[2].resolveAsFile();
|
||||
var infoList;
|
||||
|
||||
for (const auto& i : RangedDirectoryIterator (folderToSearch, false, "*", File::findDirectories))
|
||||
{
|
||||
LibraryModule module (i.getFile());
|
||||
|
||||
if (module.isValid())
|
||||
{
|
||||
zipModule (targetFolder, i.getFile());
|
||||
|
||||
var moduleInfo (new DynamicObject());
|
||||
moduleInfo.getDynamicObject()->setProperty ("file", getModulePackageName (module));
|
||||
moduleInfo.getDynamicObject()->setProperty ("info", module.moduleInfo.getModuleInfo());
|
||||
infoList.append (moduleInfo);
|
||||
}
|
||||
}
|
||||
|
||||
auto indexFile = targetFolder.getChildFile ("modulelist");
|
||||
std::cout << "Writing: " << indexFile.getFullPathName() << std::endl;
|
||||
indexFile.replaceWithText (JSON::toString (infoList), false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 2; i < args.size(); ++i)
|
||||
zipModule (targetFolder, args[i].resolveAsFile());
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct CleanupOptions
|
||||
{
|
||||
bool removeTabs;
|
||||
bool fixDividerComments;
|
||||
};
|
||||
|
||||
static void cleanWhitespace (const File& file, CleanupOptions options)
|
||||
{
|
||||
auto content = file.loadFileAsString();
|
||||
|
||||
auto isProjucerTemplateFile = [file, content]
|
||||
{
|
||||
return file.getFullPathName().contains ("Templates")
|
||||
&& content.contains ("%""%") && content.contains ("//[");
|
||||
}();
|
||||
|
||||
if (isProjucerTemplateFile)
|
||||
return;
|
||||
|
||||
StringArray lines;
|
||||
lines.addLines (content);
|
||||
bool anyTabsRemoved = false;
|
||||
|
||||
for (int i = 0; i < lines.size(); ++i)
|
||||
{
|
||||
String& line = lines.getReference (i);
|
||||
|
||||
if (options.removeTabs && line.containsChar ('\t'))
|
||||
{
|
||||
anyTabsRemoved = true;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const int tabPos = line.indexOfChar ('\t');
|
||||
|
||||
if (tabPos < 0)
|
||||
break;
|
||||
|
||||
const int spacesPerTab = 4;
|
||||
const int spacesNeeded = spacesPerTab - (tabPos % spacesPerTab);
|
||||
line = line.replaceSection (tabPos, 1, String::repeatedString (" ", spacesNeeded));
|
||||
}
|
||||
}
|
||||
|
||||
if (options.fixDividerComments)
|
||||
{
|
||||
auto afterIndent = line.trim();
|
||||
|
||||
if (afterIndent.startsWith ("//") && afterIndent.length() > 20)
|
||||
{
|
||||
afterIndent = afterIndent.substring (2);
|
||||
|
||||
if (afterIndent.containsOnly ("=")
|
||||
|| afterIndent.containsOnly ("/")
|
||||
|| afterIndent.containsOnly ("-"))
|
||||
{
|
||||
line = line.substring (0, line.indexOfChar ('/'))
|
||||
+ "//" + String::repeatedString ("=", 78);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
line = line.trimEnd();
|
||||
}
|
||||
|
||||
if (options.removeTabs && ! anyTabsRemoved)
|
||||
return;
|
||||
|
||||
auto newText = joinLinesIntoSourceFile (lines);
|
||||
|
||||
if (newText != content && newText != content + getPreferredLineFeed())
|
||||
replaceFile (file, newText, options.removeTabs ? "Removing tabs in: "
|
||||
: "Cleaning file: ");
|
||||
}
|
||||
|
||||
static void scanFilesForCleanup (const ArgumentList& args, CleanupOptions options)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
|
||||
for (auto it = args.arguments.begin() + 1; it < args.arguments.end(); ++it)
|
||||
{
|
||||
auto target = it->resolveAsFile();
|
||||
|
||||
Array<File> files;
|
||||
|
||||
if (target.isDirectory())
|
||||
files = findAllSourceFiles (target);
|
||||
else
|
||||
files.add (target);
|
||||
|
||||
for (int i = 0; i < files.size(); ++i)
|
||||
cleanWhitespace (files.getReference (i), options);
|
||||
}
|
||||
}
|
||||
|
||||
static void cleanWhitespace (const ArgumentList& args, bool replaceTabs)
|
||||
{
|
||||
CleanupOptions options = { replaceTabs, false };
|
||||
scanFilesForCleanup (args, options);
|
||||
}
|
||||
|
||||
static void tidyDividerComments (const ArgumentList& args)
|
||||
{
|
||||
CleanupOptions options = { false, true };
|
||||
scanFilesForCleanup (args, options);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static File findSimilarlyNamedHeader (const Array<File>& allFiles, const String& name, const File& sourceFile)
|
||||
{
|
||||
File result;
|
||||
|
||||
for (auto& f : allFiles)
|
||||
{
|
||||
if (f.getFileName().equalsIgnoreCase (name) && f != sourceFile)
|
||||
{
|
||||
if (result.exists())
|
||||
return {}; // multiple possible results, so don't change it!
|
||||
|
||||
result = f;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void fixIncludes (const File& file, const Array<File>& allFiles)
|
||||
{
|
||||
const String content (file.loadFileAsString());
|
||||
|
||||
StringArray lines;
|
||||
lines.addLines (content);
|
||||
bool hasChanged = false;
|
||||
|
||||
for (auto& line : lines)
|
||||
{
|
||||
if (line.trimStart().startsWith ("#include \""))
|
||||
{
|
||||
auto includedFile = line.fromFirstOccurrenceOf ("\"", true, false)
|
||||
.upToLastOccurrenceOf ("\"", true, false)
|
||||
.trim()
|
||||
.unquoted();
|
||||
|
||||
auto target = file.getSiblingFile (includedFile);
|
||||
|
||||
if (! target.exists())
|
||||
{
|
||||
auto header = findSimilarlyNamedHeader (allFiles, target.getFileName(), file);
|
||||
|
||||
if (header.exists())
|
||||
{
|
||||
line = line.upToFirstOccurrenceOf ("#include \"", true, false)
|
||||
+ header.getRelativePathFrom (file.getParentDirectory())
|
||||
.replaceCharacter ('\\', '/')
|
||||
+ "\"";
|
||||
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasChanged)
|
||||
{
|
||||
auto newText = joinLinesIntoSourceFile (lines);
|
||||
|
||||
if (newText != content && newText != content + getPreferredLineFeed())
|
||||
replaceFile (file, newText, "Fixing includes in: ");
|
||||
}
|
||||
}
|
||||
|
||||
static void fixRelativeIncludePaths (const ArgumentList& args)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
auto target = args[1].resolveAsExistingFolder();
|
||||
auto files = findAllSourceFiles (target);
|
||||
|
||||
for (int i = 0; i < files.size(); ++i)
|
||||
fixIncludes (files.getReference(i), files);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static String getStringConcatenationExpression (Random& rng, int start, int length)
|
||||
{
|
||||
jassert (length > 0);
|
||||
|
||||
if (length == 1)
|
||||
return "s" + String (start);
|
||||
|
||||
int breakPos = jlimit (1, length - 1, (length / 3) + rng.nextInt (jmax (1, length / 3)));
|
||||
|
||||
return "(" + getStringConcatenationExpression (rng, start, breakPos)
|
||||
+ " + " + getStringConcatenationExpression (rng, start + breakPos, length - breakPos) + ")";
|
||||
}
|
||||
|
||||
static void generateObfuscatedStringCode (const ArgumentList& args)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
auto originalText = args[1].text.unquoted();
|
||||
|
||||
struct Section
|
||||
{
|
||||
String text;
|
||||
int position, index;
|
||||
|
||||
void writeGenerator (MemoryOutputStream& out) const
|
||||
{
|
||||
String name ("s" + String (index));
|
||||
|
||||
out << " String " << name << "; " << name;
|
||||
|
||||
auto escapeIfSingleQuote = [] (const String& s) -> String
|
||||
{
|
||||
if (s == "\'")
|
||||
return "\\'";
|
||||
|
||||
return s;
|
||||
};
|
||||
|
||||
for (int i = 0; i < text.length(); ++i)
|
||||
out << " << '" << escapeIfSingleQuote (String::charToString (text[i])) << "'";
|
||||
|
||||
out << ";" << preferredLineFeed;
|
||||
}
|
||||
};
|
||||
|
||||
Array<Section> sections;
|
||||
String text = originalText;
|
||||
Random rng;
|
||||
|
||||
while (text.isNotEmpty())
|
||||
{
|
||||
int pos = jmax (0, text.length() - (1 + rng.nextInt (6)));
|
||||
Section s = { text.substring (pos), pos, 0 };
|
||||
sections.insert (0, s);
|
||||
text = text.substring (0, pos);
|
||||
}
|
||||
|
||||
for (int i = 0; i < sections.size(); ++i)
|
||||
sections.getReference(i).index = i;
|
||||
|
||||
for (int i = 0; i < sections.size(); ++i)
|
||||
sections.swap (i, rng.nextInt (sections.size()));
|
||||
|
||||
MemoryOutputStream out;
|
||||
|
||||
out << "String createString()" << preferredLineFeed
|
||||
<< "{" << preferredLineFeed;
|
||||
|
||||
for (int i = 0; i < sections.size(); ++i)
|
||||
sections.getReference(i).writeGenerator (out);
|
||||
|
||||
out << preferredLineFeed
|
||||
<< " String result = " << getStringConcatenationExpression (rng, 0, sections.size()) << ";" << preferredLineFeed
|
||||
<< preferredLineFeed
|
||||
<< " jassert (result == " << originalText.quoted() << ");" << preferredLineFeed
|
||||
<< " return result;" << preferredLineFeed
|
||||
<< "}" << preferredLineFeed;
|
||||
|
||||
std::cout << out.toString() << std::endl;
|
||||
}
|
||||
|
||||
static void scanFoldersForTranslationFiles (const ArgumentList& args)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
|
||||
StringArray translations;
|
||||
|
||||
for (auto it = args.arguments.begin() + 1; it != args.arguments.end(); ++it)
|
||||
{
|
||||
auto directoryToSearch = it->resolveAsExistingFolder();
|
||||
TranslationHelpers::scanFolderForTranslations (translations, directoryToSearch);
|
||||
}
|
||||
|
||||
std::cout << TranslationHelpers::mungeStrings (translations) << std::endl;
|
||||
}
|
||||
|
||||
static void createFinishedTranslationFile (const ArgumentList& args)
|
||||
{
|
||||
args.checkMinNumArguments (3);
|
||||
|
||||
auto preTranslated = args[1].resolveAsExistingFile().loadFileAsString();
|
||||
auto postTranslated = args[2].resolveAsExistingFile().loadFileAsString();
|
||||
|
||||
auto localisedContent = (args.size() > 3 ? args[3].resolveAsExistingFile().loadFileAsString() : String());
|
||||
auto localised = LocalisedStrings (localisedContent, false);
|
||||
|
||||
using TH = TranslationHelpers;
|
||||
std::cout << TH::createFinishedTranslationFile (TH::withTrimmedEnds (TH::breakApart (preTranslated)),
|
||||
TH::withTrimmedEnds (TH::breakApart (postTranslated)),
|
||||
localised) << std::endl;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static void encodeBinary (const ArgumentList& args)
|
||||
{
|
||||
args.checkMinNumArguments (3);
|
||||
auto source = args[1].resolveAsExistingFile();
|
||||
auto target = args[2].resolveAsExistingFile();
|
||||
|
||||
MemoryOutputStream literal;
|
||||
size_t dataSize = 0;
|
||||
|
||||
{
|
||||
MemoryBlock data;
|
||||
FileInputStream input (source);
|
||||
input.readIntoMemoryBlock (data);
|
||||
build_tools::writeDataAsCppLiteral (data, literal, true, true);
|
||||
dataSize = data.getSize();
|
||||
}
|
||||
|
||||
auto variableName = build_tools::makeBinaryDataIdentifierName (source);
|
||||
|
||||
MemoryOutputStream header, cpp;
|
||||
|
||||
header << "// Auto-generated binary data by the Projucer" << preferredLineFeed
|
||||
<< "// Source file: " << source.getRelativePathFrom (target.getParentDirectory()) << preferredLineFeed
|
||||
<< preferredLineFeed;
|
||||
|
||||
cpp << header.toString();
|
||||
|
||||
if (target.hasFileExtension (headerFileExtensions))
|
||||
{
|
||||
header << "static constexpr unsigned char " << variableName << "[] =" << preferredLineFeed
|
||||
<< literal.toString() << preferredLineFeed
|
||||
<< preferredLineFeed;
|
||||
|
||||
replaceFile (target, header.toString(), "Writing: ");
|
||||
}
|
||||
else if (target.hasFileExtension (cppFileExtensions))
|
||||
{
|
||||
header << "extern const char* " << variableName << ";" << preferredLineFeed
|
||||
<< "const unsigned int " << variableName << "Size = " << (int) dataSize << ";" << preferredLineFeed
|
||||
<< preferredLineFeed;
|
||||
|
||||
cpp << CodeHelpers::createIncludeStatement (target.withFileExtension (".h").getFileName()) << preferredLineFeed
|
||||
<< preferredLineFeed
|
||||
<< "static constexpr unsigned char " << variableName << "_local[] =" << preferredLineFeed
|
||||
<< literal.toString() << preferredLineFeed
|
||||
<< preferredLineFeed
|
||||
<< "const char* " << variableName << " = (const char*) " << variableName << "_local;" << preferredLineFeed;
|
||||
|
||||
replaceFile (target, cpp.toString(), "Writing: ");
|
||||
replaceFile (target.withFileExtension (".h"), header.toString(), "Writing: ");
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleApplication::fail ("You need to specify a .h or .cpp file as the target");
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static bool isThisOS (const String& os)
|
||||
{
|
||||
auto targetOS = TargetOS::unknown;
|
||||
|
||||
if (os == "osx") targetOS = TargetOS::osx;
|
||||
else if (os == "windows") targetOS = TargetOS::windows;
|
||||
else if (os == "linux") targetOS = TargetOS::linux;
|
||||
|
||||
if (targetOS == TargetOS::unknown)
|
||||
ConsoleApplication::fail ("You need to specify a valid OS! Use osx, windows or linux");
|
||||
|
||||
return targetOS == TargetOS::getThisOS();
|
||||
}
|
||||
|
||||
static bool isValidPathIdentifier (const String& id, const String& os)
|
||||
{
|
||||
return id == "vstLegacyPath" || (id == "aaxPath" && os != "linux") || (id == "rtasPath" && os != "linux")
|
||||
|| id == "androidSDKPath" || id == "defaultJuceModulePath" || id == "defaultUserModulePath";
|
||||
}
|
||||
|
||||
static void setGlobalPath (const ArgumentList& args)
|
||||
{
|
||||
args.checkMinNumArguments (3);
|
||||
|
||||
if (! isValidPathIdentifier (args[2].text, args[1].text))
|
||||
ConsoleApplication::fail ("Identifier " + args[2].text + " is not valid for the OS " + args[1].text);
|
||||
|
||||
auto userAppData = File::getSpecialLocation (File::userApplicationDataDirectory);
|
||||
|
||||
#if JUCE_MAC
|
||||
userAppData = userAppData.getChildFile ("Application Support");
|
||||
#endif
|
||||
|
||||
auto settingsFile = userAppData.getChildFile ("Projucer").getChildFile ("Projucer.settings");
|
||||
auto xml = parseXML (settingsFile);
|
||||
|
||||
if (xml == nullptr)
|
||||
ConsoleApplication::fail ("Settings file not valid!");
|
||||
|
||||
auto settingsTree = ValueTree::fromXml (*xml);
|
||||
|
||||
if (! settingsTree.isValid())
|
||||
ConsoleApplication::fail ("Settings file not valid!");
|
||||
|
||||
ValueTree childToSet;
|
||||
|
||||
if (isThisOS (args[1].text))
|
||||
{
|
||||
childToSet = settingsTree.getChildWithProperty (Ids::name, "PROJECT_DEFAULT_SETTINGS")
|
||||
.getOrCreateChildWithName ("PROJECT_DEFAULT_SETTINGS", nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
childToSet = settingsTree.getChildWithProperty (Ids::name, "FALLBACK_PATHS")
|
||||
.getOrCreateChildWithName ("FALLBACK_PATHS", nullptr)
|
||||
.getOrCreateChildWithName (args[1].text + "Fallback", nullptr);
|
||||
}
|
||||
|
||||
if (! childToSet.isValid())
|
||||
ConsoleApplication::fail ("Failed to set the requested setting!");
|
||||
|
||||
childToSet.setProperty (args[2].text, args[3].resolveAsFile().getFullPathName(), nullptr);
|
||||
|
||||
settingsFile.replaceWithText (settingsTree.toXmlString());
|
||||
}
|
||||
|
||||
static void createProjectFromPIP (const ArgumentList& args)
|
||||
{
|
||||
args.checkMinNumArguments (3);
|
||||
|
||||
auto pipFile = args[1].resolveAsFile();
|
||||
|
||||
if (! pipFile.existsAsFile())
|
||||
ConsoleApplication::fail ("PIP file doesn't exist.");
|
||||
|
||||
auto outputDir = args[2].resolveAsFile();
|
||||
|
||||
if (! outputDir.exists())
|
||||
{
|
||||
auto res = outputDir.createDirectory();
|
||||
std::cout << "Creating directory " << outputDir.getFullPathName() << std::endl;
|
||||
}
|
||||
|
||||
File juceModulesPath, userModulesPath;
|
||||
|
||||
if (args.size() > 3)
|
||||
{
|
||||
juceModulesPath = args[3].resolveAsFile();
|
||||
|
||||
if (! juceModulesPath.exists())
|
||||
ConsoleApplication::fail ("Specified JUCE modules directory doesn't exist.");
|
||||
|
||||
if (args.size() == 5)
|
||||
{
|
||||
userModulesPath = args[4].resolveAsFile();
|
||||
|
||||
if (! userModulesPath.exists())
|
||||
ConsoleApplication::fail ("Specified JUCE modules directory doesn't exist.");
|
||||
}
|
||||
}
|
||||
|
||||
PIPGenerator generator (pipFile, outputDir, juceModulesPath, userModulesPath);
|
||||
|
||||
auto createJucerFileResult = generator.createJucerFile();
|
||||
|
||||
if (! createJucerFileResult)
|
||||
ConsoleApplication::fail (createJucerFileResult.getErrorMessage());
|
||||
|
||||
auto createMainCppResult = generator.createMainCpp();
|
||||
|
||||
if (! createMainCppResult)
|
||||
ConsoleApplication::fail (createMainCppResult.getErrorMessage());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static void showHelp()
|
||||
{
|
||||
hideDockIcon();
|
||||
|
||||
auto appName = JUCEApplication::getInstance()->getApplicationName();
|
||||
|
||||
std::cout << appName << std::endl
|
||||
<< std::endl
|
||||
<< "Usage: " << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --resave project_file" << std::endl
|
||||
<< " Resaves all files and resources in a project. Add the \"--fix-missing-dependencies\" option to automatically fix any missing module dependencies." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --resave-resources project_file" << std::endl
|
||||
<< " Resaves just the binary resources for a project." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --get-version project_file" << std::endl
|
||||
<< " Returns the version number of a project." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --set-version version_number project_file" << std::endl
|
||||
<< " Updates the version number in a project." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --bump-version project_file" << std::endl
|
||||
<< " Updates the minor version number in a project by 1." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --git-tag-version project_file" << std::endl
|
||||
<< " Invokes 'git tag' to attach the project's version number to the current git repository." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --status project_file" << std::endl
|
||||
<< " Displays information about a project." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --buildmodule target_folder module_folder" << std::endl
|
||||
<< " Zips a module into a downloadable file format." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --buildallmodules target_folder module_folder" << std::endl
|
||||
<< " Zips all modules in a given folder and creates an index for them." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --trim-whitespace target_folder" << std::endl
|
||||
<< " Scans the given folder for C/C++ source files (recursively), and trims any trailing whitespace from their lines, as well as normalising their line-endings to CR-LF." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --remove-tabs target_folder" << std::endl
|
||||
<< " Scans the given folder for C/C++ source files (recursively), and replaces any tab characters with 4 spaces." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --tidy-divider-comments target_folder" << std::endl
|
||||
<< " Scans the given folder for C/C++ source files (recursively), and normalises any juce-style comment division lines (i.e. any lines that look like //===== or //------- or /////////// will be replaced)." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --fix-broken-include-paths target_folder" << std::endl
|
||||
<< " Scans the given folder for C/C++ source files (recursively). Where a file contains an #include of one of the other filenames, it changes it to use the optimum relative path. Helpful for auto-fixing includes when re-arranging files and folders in a project." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --obfuscated-string-code string_to_obfuscate" << std::endl
|
||||
<< " Generates a C++ function which returns the given string, but in an obfuscated way." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --encode-binary source_binary_file target_cpp_file" << std::endl
|
||||
<< " Converts a binary file to a C++ file containing its contents as a block of data. Provide a .h file as the target if you want a single output file, or a .cpp file if you want a pair of .h/.cpp files." << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --trans target_folders..." << std::endl
|
||||
<< " Scans each of the given folders (recursively) for any NEEDS_TRANS macros, and generates a translation file that can be used with Projucer's translation file builder" << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --trans-finish pre_translated_file post_translated_file optional_existing_translation_file" << std::endl
|
||||
<< " Creates a completed translations mapping file, that can be used to initialise a LocalisedStrings object. This allows you to localise the strings in your project" << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --set-global-search-path os identifier_to_set new_path" << std::endl
|
||||
<< " Sets the global path for a specified os and identifier. The os should be either osx, windows or linux and the identifiers can be any of the following: "
|
||||
<< "defaultJuceModulePath, defaultUserModulePath, vstLegacyPath, aaxPath (not valid on linux), rtasPath (not valid on linux), or androidSDKPath. " << std::endl
|
||||
<< std::endl
|
||||
<< " " << appName << " --create-project-from-pip path/to/PIP path/to/output path/to/JUCE/modules (optional) path/to/user/modules (optional)" << std::endl
|
||||
<< " Generates a folder containing a JUCE project in the specified output path using the specified PIP file. Use the optional JUCE and user module paths to override "
|
||||
"the global module paths." << std::endl
|
||||
<< std::endl
|
||||
<< "Note that for any of the file-rewriting commands, add the option \"--lf\" if you want it to use LF linefeeds instead of CRLF" << std::endl
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int performCommandLine (const ArgumentList& args)
|
||||
{
|
||||
return ConsoleApplication::invokeCatchingFailures ([&]() -> int
|
||||
{
|
||||
if (args.containsOption ("--lf"))
|
||||
preferredLineFeed = "\n";
|
||||
|
||||
auto command = args[0];
|
||||
|
||||
auto matchCommand = [&] (StringRef name) -> bool
|
||||
{
|
||||
return command == name || command.isLongOption (name);
|
||||
};
|
||||
|
||||
if (matchCommand ("help")) { showHelp(); return 0; }
|
||||
if (matchCommand ("h")) { showHelp(); return 0; }
|
||||
if (matchCommand ("resave")) { resaveProject (args, false); return 0; }
|
||||
if (matchCommand ("resave-resources")) { resaveProject (args, true); return 0; }
|
||||
if (matchCommand ("get-version")) { getVersion (args); return 0; }
|
||||
if (matchCommand ("set-version")) { setVersion (args); return 0; }
|
||||
if (matchCommand ("bump-version")) { bumpVersion (args); return 0; }
|
||||
if (matchCommand ("git-tag-version")) { gitTag (args); return 0; }
|
||||
if (matchCommand ("buildmodule")) { buildModules (args, false); return 0; }
|
||||
if (matchCommand ("buildallmodules")) { buildModules (args, true); return 0; }
|
||||
if (matchCommand ("status")) { showStatus (args); return 0; }
|
||||
if (matchCommand ("trim-whitespace")) { cleanWhitespace (args, false); return 0; }
|
||||
if (matchCommand ("remove-tabs")) { cleanWhitespace (args, true); return 0; }
|
||||
if (matchCommand ("tidy-divider-comments")) { tidyDividerComments (args); return 0; }
|
||||
if (matchCommand ("fix-broken-include-paths")) { fixRelativeIncludePaths (args); return 0; }
|
||||
if (matchCommand ("obfuscated-string-code")) { generateObfuscatedStringCode (args); return 0; }
|
||||
if (matchCommand ("encode-binary")) { encodeBinary (args); return 0; }
|
||||
if (matchCommand ("trans")) { scanFoldersForTranslationFiles (args); return 0; }
|
||||
if (matchCommand ("trans-finish")) { createFinishedTranslationFile (args); return 0; }
|
||||
if (matchCommand ("set-global-search-path")) { setGlobalPath (args); return 0; }
|
||||
if (matchCommand ("create-project-from-pip")) { createProjectFromPIP (args); return 0; }
|
||||
|
||||
if (command.isLongOption() || command.isShortOption())
|
||||
ConsoleApplication::fail ("Unrecognised command: " + command.text.quoted());
|
||||
|
||||
return commandLineNotPerformed;
|
||||
});
|
||||
}
|
30
deps/juce/extras/Projucer/Source/Application/jucer_CommandLine.h
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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
|
||||
|
||||
int performCommandLine (const ArgumentList&);
|
||||
|
||||
enum { commandLineNotPerformed = 0x72346231 };
|
99
deps/juce/extras/Projucer/Source/Application/jucer_CommonHeaders.h
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// The GCC extensions define linux somewhere in the headers, so undef it here...
|
||||
#if JUCE_GCC
|
||||
#undef linux
|
||||
#endif
|
||||
|
||||
struct TargetOS
|
||||
{
|
||||
enum OS
|
||||
{
|
||||
windows = 0,
|
||||
osx,
|
||||
linux,
|
||||
unknown
|
||||
};
|
||||
|
||||
static OS getThisOS() noexcept
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
return windows;
|
||||
#elif JUCE_MAC
|
||||
return osx;
|
||||
#elif JUCE_LINUX || JUCE_BSD
|
||||
return linux;
|
||||
#else
|
||||
return unknown;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
typedef TargetOS::OS DependencyPathOS;
|
||||
|
||||
//==============================================================================
|
||||
#include "../Settings/jucer_StoredSettings.h"
|
||||
#include "../Utility/UI/jucer_Icons.h"
|
||||
#include "../Utility/Helpers/jucer_MiscUtilities.h"
|
||||
#include "../Utility/Helpers/jucer_CodeHelpers.h"
|
||||
#include "../Utility/Helpers/jucer_FileHelpers.h"
|
||||
#include "../Utility/Helpers/jucer_ValueSourceHelpers.h"
|
||||
#include "../Utility/Helpers/jucer_PresetIDs.h"
|
||||
#include "jucer_CommandIDs.h"
|
||||
|
||||
//==============================================================================
|
||||
const char* const projectItemDragType = "Project Items";
|
||||
const char* const drawableItemDragType = "Drawable Items";
|
||||
const char* const componentItemDragType = "Components";
|
||||
|
||||
enum ColourIds
|
||||
{
|
||||
backgroundColourId = 0x2340000,
|
||||
secondaryBackgroundColourId = 0x2340001,
|
||||
defaultTextColourId = 0x2340002,
|
||||
widgetTextColourId = 0x2340003,
|
||||
defaultButtonBackgroundColourId = 0x2340004,
|
||||
secondaryButtonBackgroundColourId = 0x2340005,
|
||||
userButtonBackgroundColourId = 0x2340006,
|
||||
defaultIconColourId = 0x2340007,
|
||||
treeIconColourId = 0x2340008,
|
||||
defaultHighlightColourId = 0x2340009,
|
||||
defaultHighlightedTextColourId = 0x234000a,
|
||||
codeEditorLineNumberColourId = 0x234000b,
|
||||
activeTabIconColourId = 0x234000c,
|
||||
inactiveTabBackgroundColourId = 0x234000d,
|
||||
inactiveTabIconColourId = 0x234000e,
|
||||
contentHeaderBackgroundColourId = 0x234000f,
|
||||
widgetBackgroundColourId = 0x2340010,
|
||||
secondaryWidgetBackgroundColourId = 0x2340011,
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
static constexpr int projucerMajorVersion = ProjectInfo::versionNumber >> 16;
|
29
deps/juce/extras/Projucer/Source/Application/jucer_Headers.h
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 <JuceHeader.h>
|
||||
#include "jucer_CommonHeaders.h"
|
48
deps/juce/extras/Projucer/Source/Application/jucer_Main.cpp
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 "../CodeEditor/jucer_OpenDocumentManager.h"
|
||||
#include "../CodeEditor/jucer_SourceCodeEditor.h"
|
||||
#include "../Utility/UI/PropertyComponents/jucer_FilePathPropertyComponent.h"
|
||||
#include "../Project/UI/jucer_ProjectContentComponent.h"
|
||||
#include "../Project/UI/Sidebar/jucer_TreeItemTypes.h"
|
||||
#include "Windows/jucer_UTF8WindowComponent.h"
|
||||
#include "Windows/jucer_SVGPathDataWindowComponent.h"
|
||||
#include "Windows/jucer_AboutWindowComponent.h"
|
||||
#include "Windows/jucer_EditorColourSchemeWindowComponent.h"
|
||||
#include "Windows/jucer_GlobalPathsWindowComponent.h"
|
||||
#include "Windows/jucer_PIPCreatorWindowComponent.h"
|
||||
#include "Windows/jucer_FloatingToolWindow.h"
|
||||
|
||||
#include "jucer_CommandLine.h"
|
||||
|
||||
#include "../Project/UI/jucer_ProjectContentComponent.cpp"
|
||||
#include "jucer_Application.cpp"
|
||||
|
||||
|
||||
START_JUCE_APPLICATION (ProjucerApplication)
|
1051
deps/juce/extras/Projucer/Source/Application/jucer_MainWindow.cpp
vendored
Normal file
146
deps/juce/extras/Projucer/Source/Application/jucer_MainWindow.h
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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/PIPs/jucer_PIPGenerator.h"
|
||||
#include "../Project/jucer_Project.h"
|
||||
#include "../CodeEditor/jucer_OpenDocumentManager.h"
|
||||
|
||||
class ProjectContentComponent;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
The big top-level window where everything happens.
|
||||
*/
|
||||
class MainWindow : public DocumentWindow,
|
||||
public ApplicationCommandTarget,
|
||||
public FileDragAndDropTarget,
|
||||
public DragAndDropContainer,
|
||||
private Value::Listener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
MainWindow();
|
||||
~MainWindow() override;
|
||||
|
||||
enum class OpenInIDE { no, yes };
|
||||
|
||||
//==============================================================================
|
||||
void closeButtonPressed() override;
|
||||
|
||||
//==============================================================================
|
||||
bool canOpenFile (const File& file) const;
|
||||
void openFile (const File& file, std::function<void (bool)> callback);
|
||||
|
||||
void setProject (std::unique_ptr<Project> newProject);
|
||||
Project* getProject() const { return currentProject.get(); }
|
||||
|
||||
void makeVisible();
|
||||
void restoreWindowPosition();
|
||||
void updateTitleBarIcon();
|
||||
void closeCurrentProject (OpenDocumentManager::SaveIfNeeded askToSave, std::function<void (bool)> callback);
|
||||
void moveProject (File newProjectFile, OpenInIDE openInIDE);
|
||||
|
||||
void showStartPage();
|
||||
|
||||
void showLoginFormOverlay();
|
||||
void hideLoginFormOverlay();
|
||||
bool isShowingLoginForm() const noexcept { return loginFormOpen; }
|
||||
|
||||
bool isInterestedInFileDrag (const StringArray& files) override;
|
||||
void filesDropped (const StringArray& filenames, int mouseX, int mouseY) override;
|
||||
|
||||
void activeWindowStatusChanged() override;
|
||||
|
||||
ProjectContentComponent* getProjectContentComponent() const;
|
||||
|
||||
//==============================================================================
|
||||
ApplicationCommandTarget* getNextCommandTarget() override;
|
||||
void getAllCommands (Array <CommandID>& commands) override;
|
||||
void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result) override;
|
||||
bool perform (const InvocationInfo& info) override;
|
||||
|
||||
bool shouldDropFilesWhenDraggedExternally (const DragAndDropTarget::SourceDetails& sourceDetails,
|
||||
StringArray& files, bool& canMoveFiles) override;
|
||||
private:
|
||||
void valueChanged (Value&) override;
|
||||
|
||||
static const char* getProjectWindowPosName() { return "projectWindowPos"; }
|
||||
void createProjectContentCompIfNeeded();
|
||||
|
||||
void openPIP (const File&, std::function<void (bool)> callback);
|
||||
void setupTemporaryPIPProject (PIPGenerator&);
|
||||
|
||||
void initialiseProjectWindow();
|
||||
|
||||
std::unique_ptr<Project> currentProject;
|
||||
Value projectNameValue;
|
||||
|
||||
std::unique_ptr<Component> blurOverlayComponent;
|
||||
bool loginFormOpen = false;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class MainWindowList
|
||||
{
|
||||
public:
|
||||
MainWindowList();
|
||||
|
||||
void forceCloseAllWindows();
|
||||
void askAllWindowsToClose (std::function<void (bool)> callback);
|
||||
void closeWindow (MainWindow*);
|
||||
|
||||
void goToSiblingWindow (MainWindow*, int delta);
|
||||
|
||||
void createWindowIfNoneAreOpen();
|
||||
void openDocument (OpenDocumentManager::Document*, bool grabFocus);
|
||||
void openFile (const File& file, std::function<void (bool)> callback, bool openInBackground = false);
|
||||
|
||||
MainWindow* createNewMainWindow();
|
||||
MainWindow* getFrontmostWindow (bool createIfNotFound = true);
|
||||
MainWindow* getOrCreateEmptyWindow();
|
||||
MainWindow* getMainWindowForFile (const File&);
|
||||
MainWindow* getMainWindowWithLoginFormOpen();
|
||||
|
||||
Project* getFrontmostProject();
|
||||
|
||||
void reopenLastProjects();
|
||||
void saveCurrentlyOpenProjectList();
|
||||
|
||||
void checkWindowBounds (MainWindow&);
|
||||
|
||||
void sendLookAndFeelChange();
|
||||
|
||||
OwnedArray<MainWindow> windows;
|
||||
|
||||
private:
|
||||
bool isInReopenLastProjects = false;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindowList)
|
||||
JUCE_DECLARE_WEAK_REFERENCEABLE (MainWindowList)
|
||||
};
|
12
deps/juce/extras/Projucer/Source/BinaryData/Icons/background_logo.svg
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
<svg width="145.75" height="145.75" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M72.87 84.28A42.36 42.36 0 0130.4 42.14a42.48 42.48 0 0184.95 0 42.36 42.36 0 01-42.48 42.14zm0-78.67A36.74 36.74 0 0036 42.14a36.88 36.88 0 0073.75 0A36.75 36.75 0 0072.87 5.61z" fill="#b8b8b8"/>
|
||||
<path d="M77.62 49.59a177.77 177.77 0 008.74 18.93A4.38 4.38 0 0092.69 70a34.5 34.5 0 008.84-9 4.3 4.3 0 00-2.38-6.49A176.73 176.73 0 0180 47.32a1.78 1.78 0 00-2.38 2.27z" fill="#c2c2c2"/>
|
||||
<path d="M81.05 44.27a169.68 169.68 0 0020.13 7.41 4.39 4.39 0 005.52-3.41 34.42 34.42 0 00.55-6.13 33.81 33.81 0 00-.67-6.72 4.37 4.37 0 00-6.31-3A192.32 192.32 0 0181.1 41a1.76 1.76 0 00-.05 3.27z" fill="#a1a1a1"/>
|
||||
<path d="M74.47 50.44a1.78 1.78 0 00-3.29 0 165.54 165.54 0 00-7.46 19.89 4.33 4.33 0 003.47 5.48 35.49 35.49 0 005.68.46 34.44 34.44 0 007.13-.79 4.32 4.32 0 003-6.25 187.83 187.83 0 01-8.53-18.79z" fill="#dcdcdc"/>
|
||||
<path d="M71.59 34.12a1.78 1.78 0 003.29.05 163.9 163.9 0 007.52-20.11A4.34 4.34 0 0079 8.59a35.15 35.15 0 00-13.06.17 4.32 4.32 0 00-3 6.26 188.41 188.41 0 018.65 19.1z" fill="#9b9b9b"/>
|
||||
<path d="M46.32 30.3a176.2 176.2 0 0120 7.48 1.78 1.78 0 002.37-2.28 180.72 180.72 0 00-9.13-19.84 4.38 4.38 0 00-6.33-1.47 34.27 34.27 0 00-9.32 9.65 4.31 4.31 0 002.41 6.46z" fill="#a8a8a8"/>
|
||||
<path d="M68.17 49.18a1.77 1.77 0 00-2.29-2.34 181.71 181.71 0 00-19.51 8.82A4.3 4.3 0 0044.91 62a34.36 34.36 0 009.42 8.88 4.36 4.36 0 006.5-2.38 175.11 175.11 0 017.34-19.32z" fill="#c5c5c5"/>
|
||||
<path d="M77.79 35.59a1.78 1.78 0 002.3 2.35 182.51 182.51 0 0019.6-8.88 4.3 4.3 0 001.5-6.25 34.4 34.4 0 00-9.41-9.14A4.36 4.36 0 0085.24 16a174.51 174.51 0 01-7.45 19.59z" fill="#6f6f6f"/>
|
||||
<path d="M64.69 40.6a167.72 167.72 0 00-20.22-7.44A4.36 4.36 0 0039 36.6a33.68 33.68 0 00-.45 5.54 34 34 0 00.81 7.4 4.36 4.36 0 006.28 2.84 189.19 189.19 0 0119-8.52 1.76 1.76 0 00.05-3.26z" fill="#b3b3b3"/>
|
||||
<path d="M20 129.315c0 5-2.72 8.16-7.11 8.16-2.37 0-4.17-1-6.2-3.56l-.69-.78-6 5 .57.76c3.25 4.36 7.16 6.39 12.31 6.39 9 0 15.34-6.57 15.34-16v-28.1H20zM61.69 126.505c0 6.66-3.76 11-9.57 11-5.81 0-9.56-4.31-9.56-11v-25.32h-8.23v25.69c0 10.66 7.4 18.4 17.6 18.4 10 0 17.61-7.72 18-18.4v-25.69h-8.24zM106.83 134.095c-3.58 2.43-6.18 3.38-9.25 3.38a14.53 14.53 0 010-29c3.24 0 5.66.88 9.25 3.38l.76.53 4.78-6-.75-.62a22.18 22.18 0 00-14.22-5.1 22.33 22.33 0 100 44.65 21.53 21.53 0 0014.39-5.08l.81-.64-5-6zM145.75 137.285h-19.06v-10.72h18.3v-7.61h-18.3v-10.16h19.06v-7.61h-27.28v43.53h27.28zM68.015 83.917c-7.723-.902-15.472-4.123-21.566-8.966-8.475-6.736-14.172-16.823-15.574-27.575C29.303 35.31 33.538 22.7 42.21 13.631 49.154 6.368 58.07 1.902 68.042.695c2.15-.26 7.524-.26 9.675 0 12.488 1.512 23.464 8.25 30.437 18.686 8.332 12.471 9.318 28.123 2.605 41.368-2.28 4.5-4.337 7.359-7.85 10.909A42.273 42.273 0 0177.613 83.92c-2.027.227-7.644.225-9.598-.003zm7.823-5.596c8.435-.415 17.446-4.678 23.683-11.205 5.976-6.254 9.35-13.723 10.181-22.537.632-6.705-1.346-14.948-5.065-21.108C98.88 13.935 89.397 7.602 78.34 5.906c-2.541-.39-8.398-.386-10.96.006C53.54 8.034 42.185 17.542 37.81 30.67c-2.807 8.426-2.421 17.267 1.11 25.444 4.877 11.297 14.959 19.41 26.977 21.709 2.136.408 6.1.755 7.377.645.325-.028 1.48-.094 2.564-.147z" fill="#b8b8b8"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
21
deps/juce/extras/Projucer/Source/BinaryData/Icons/export_android.svg
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="19px" height="23px" viewBox="0 0 19 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>androd</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Artboard" transform="translate(-71.000000, -8.000000)" fill-rule="nonzero">
|
||||
<g id="android" transform="translate(67.000000, 6.000000)">
|
||||
<g id="androd" transform="translate(4.149701, 2.592000)">
|
||||
<path d="M12.0887784,1.906092 L13.1751916,0.325404 C13.2397006,0.231444 13.2236407,0.108108 13.1392994,0.049788 C13.0550659,-0.008208 12.9342395,0.020466 12.8702156,0.114534 L11.7411198,1.75662 C10.9970299,1.462914 10.1707545,1.29924 9.29985629,1.29924 C8.42895808,1.29924 7.60246707,1.462752 6.85843114,1.75662 L5.72949701,0.11448 C5.66477246,0.02052 5.54416168,-0.008262 5.45987425,0.049734 C5.37558683,0.107892 5.35958084,0.231282 5.42408982,0.32535 L6.51088024,1.906038 C4.78293413,2.711502 3.57116766,4.242078 3.41676647,6.028398 L15.1822994,6.028398 C15.0284371,4.242078 13.8166168,2.711556 12.0887784,1.906092" id="Shape" fill="#9FBF3B"></path>
|
||||
<path d="M6.84194012,4.397652 C6.48231737,4.397652 6.19092216,4.105674 6.19092216,3.745386 C6.19092216,3.385152 6.48215569,3.093066 6.84194012,3.093066 C7.20129341,3.093066 7.49258084,3.385044 7.49258084,3.745386 C7.49263473,4.10562 7.20129341,4.397652 6.84194012,4.397652" id="Shape" fill="#FFFFFF"></path>
|
||||
<path d="M11.7571796,4.397652 C11.3978263,4.397652 11.106485,4.105674 11.106485,3.745386 C11.106485,3.385044 11.3978263,3.093066 11.7571796,3.093066 C12.1169102,3.093066 12.4081437,3.385152 12.4081437,3.745386 C12.4081437,4.10562 12.1168024,4.397652 11.7571796,4.397652" id="Shape" fill="#FFFFFF"></path>
|
||||
<path d="M2.66135928,13.478292 C2.66135928,14.204592 2.07371856,14.793408 1.34881437,14.793408 L1.34881437,14.793408 C0.623964072,14.793408 0.0363233533,14.204592 0.0363233533,13.478292 L0.0363233533,8.15886 C0.0363233533,7.43256 0.623964072,6.843744 1.34881437,6.843744 L1.34881437,6.843744 C2.07371856,6.843744 2.66135928,7.43256 2.66135928,8.15886 L2.66135928,13.478292 Z" id="Shape" fill="#9FBF3B"></path>
|
||||
<path d="M3.4165509,6.884406 L3.4165509,16.491816 C3.4165509,17.06238 3.87819162,17.524998 4.44777844,17.524998 L5.66752096,17.524998 L5.66752096,20.481174 C5.66752096,21.207528 6.25510778,21.79629 6.98001198,21.79629 C7.70491617,21.79629 8.29255689,21.207528 8.29255689,20.481174 L8.29255689,17.524998 L10.3065629,17.524998 L10.3065629,20.481174 C10.3065629,21.207528 10.8940958,21.79629 11.6190539,21.79629 C12.344012,21.79629 12.9315449,21.207528 12.9315449,20.481174 L12.9315449,17.524998 L14.1512874,17.524998 C14.7208743,17.524998 15.1826228,17.06265 15.1826228,16.491816 L15.1826228,6.884406 L3.4165509,6.884406 Z" id="Shape" fill="#9FBF3B"></path>
|
||||
<path d="M15.9377605,13.478292 C15.9377605,14.204592 16.5253473,14.793408 17.2502515,14.793408 L17.2502515,14.793408 C17.9751018,14.793408 18.5627425,14.204592 18.5627425,13.478292 L18.5627425,8.15886 C18.5627425,7.43256 17.9751018,6.843744 17.2502515,6.843744 L17.2502515,6.843744 C16.5253473,6.843744 15.9377605,7.43256 15.9377605,8.15886 L15.9377605,13.478292 Z" id="Shape" fill="#9FBF3B"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
34
deps/juce/extras/Projucer/Source/BinaryData/Icons/export_clion.svg
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 128 128">
|
||||
<defs>
|
||||
<linearGradient id="linear-gradient" x1="40.69" y1="-676.56" x2="83.48" y2="-676.56" gradientTransform="matrix(1, 0, 0, -1, 0, -648.86)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#ed358c"/>
|
||||
<stop offset="0.16" stop-color="#e9388c"/>
|
||||
<stop offset="0.3" stop-color="#de418c"/>
|
||||
<stop offset="0.43" stop-color="#cc508c"/>
|
||||
<stop offset="0.57" stop-color="#b2658d"/>
|
||||
<stop offset="0.7" stop-color="#90808d"/>
|
||||
<stop offset="0.83" stop-color="#67a18e"/>
|
||||
<stop offset="0.95" stop-color="#37c78f"/>
|
||||
<stop offset="1" stop-color="#22d88f"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-2" x1="32.58" y1="-665.27" x2="13.76" y2="-791.59" gradientTransform="matrix(1, 0, 0, -1, 0, -648.86)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.09" stop-color="#22d88f"/>
|
||||
<stop offset="0.9" stop-color="#029de0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-3" x1="116.68" y1="-660.66" x2="-12.09" y2="-796.66" xlink:href="#linear-gradient-2"/>
|
||||
<linearGradient id="linear-gradient-4" x1="73.35" y1="-739.1" x2="122.29" y2="-746.06" xlink:href="#linear-gradient-2"/>
|
||||
</defs>
|
||||
<title>icon_CLion</title>
|
||||
<g>
|
||||
<polygon points="49.2 51.8 40.6 55.4 48.4 0 77.8 16.2 49.2 51.8" fill="url(#linear-gradient)"/>
|
||||
<polygon points="44.6 76.8 48.8 0 11.8 23.2 0 94 44.6 76.8" fill="url(#linear-gradient-2)"/>
|
||||
<polygon points="125.4 38.4 109 4.8 77.8 16.2 55 41.4 0 94 41.6 124.4 93.6 77.2 125.4 38.4" fill="url(#linear-gradient-3)"/>
|
||||
<polygon points="53.8 54.6 46.6 98.4 75.8 121 107.8 128 128 82.4 53.8 54.6" fill="url(#linear-gradient-4)"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="24" y="24" width="80" height="80"/>
|
||||
<rect x="31.6" y="89" width="30" height="5" fill="#fff"/>
|
||||
<path d="M31,51.2h0A16.83,16.83,0,0,1,48.2,34c6.2,0,10,2,13,5.2l-4.6,5.4c-2.6-2.4-5.2-3.8-8.4-3.8-5.6,0-9.6,4.6-9.6,10.4h0c0,5.6,4,10.4,9.6,10.4,3.8,0,6.2-1.6,8.8-3.8l4.6,4.6c-3.4,3.6-7.2,6-13.6,6A17,17,0,0,1,31,51.2" fill="#fff"/>
|
||||
<path d="M66.6,34.4H74v27H88.4v6.2H66.6V34.4Z" fill="#fff"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
17
deps/juce/extras/Projucer/Source/BinaryData/Icons/export_codeBlocks.svg
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Group</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Artboard" transform="translate(-33.000000, -4.000000)">
|
||||
<g id="Group" transform="translate(33.000000, 4.000000)">
|
||||
<polygon id="Rectangle-5-Copy-4" fill="#FD3535" points="7.36842105 -1.87919855e-13 9.47368421 4.21052632 9.47368421 9.47368421 4.21052632 9.47368421 6.83692868e-14 7.36842105 3.55271368e-15 -1.67409946e-14"></polygon>
|
||||
<polygon id="Rectangle-5-Copy-5" fill="#6AC300" transform="translate(15.263158, 4.736842) scale(-1, 1) translate(-15.263158, -4.736842) " points="17.8947368 -1.87919855e-13 20 4.21052632 20 9.47368421 14.7368421 9.47368421 10.5263158 7.36842105 10.5263158 -1.67409946e-14"></polygon>
|
||||
<polygon id="Rectangle-5-Copy-7" fill="#EBBF20" transform="translate(4.736842, 15.263158) scale(1, -1) translate(-4.736842, -15.263158) " points="7.36842105 10.5263158 9.47368421 14.7368421 9.47368421 20 4.21052632 20 6.83692868e-14 17.8947368 3.55271368e-15 10.5263158"></polygon>
|
||||
<polygon id="Rectangle-5-Copy-6" fill="#1F6CE9" transform="translate(15.263158, 15.263158) scale(-1, -1) translate(-15.263158, -15.263158) " points="17.8947368 10.5263158 20 14.7368421 20 20 14.7368421 20 10.5263158 17.8947368 10.5263158 10.5263158"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
51
deps/juce/extras/Projucer/Source/BinaryData/Icons/export_linux.svg
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="63px" height="75px" viewBox="0 0 63 75" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Android</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Artboard" transform="translate(-115.000000, -15.000000)" fill-rule="nonzero">
|
||||
<g id="Android" transform="translate(115.000000, 15.000000)">
|
||||
<path d="M46.1535022,26.1203623 C46.9768865,27.8918861 47.8751239,29.6135078 48.6735572,31.3850316 C50.2205216,34.8033239 51.3932204,38.3962736 51.8922412,42.1139784 C52.391262,45.8316832 52.1667026,49.6741432 50.9940038,53.2171908 C49.6715987,57.2343081 47.2014459,60.8023067 44.1324681,63.7465293 C40.5145674,67.2147237 35.8986252,69.8844849 30.8834663,70.0840932 C27.6148802,70.2088484 24.3712451,69.28566 21.5018756,67.7636466 C19.0816248,66.4911436 16.8609823,64.7944729 15.0894586,62.6985856 C13.3179348,60.6026983 12.0204807,58.1075944 11.3967048,55.4378333 C10.6481736,52.1442961 10.9974881,48.6511506 12.1202849,45.4823687 C12.9187182,43.2118241 14.116368,41.0909858 14.9896544,38.8453923 C15.9128428,36.3752394 16.4368147,33.7553803 17.6843666,31.4099826 C18.8071634,29.2891443 20.478883,27.4926695 21.3771204,25.272027 C21.9010922,23.9496219 22.1506026,22.5274127 22.4749661,21.1301545 C22.8242807,19.7328963 23.2983504,18.3605892 24.2464899,17.2627434 C25.3692867,15.9652894 27.0659573,15.2666603 28.787579,15.067052 C30.4842497,14.8674437 32.2308224,15.1419051 33.902542,15.5161707 C35.2498981,15.8155832 36.5473522,16.1898488 37.8448062,16.6639185 C38.9426519,17.0631351 40.0404976,17.5122538 40.9886371,18.1859319 C42.2860912,19.1091203 43.2841327,20.4065744 44.0576149,21.8038326 C44.8310972,23.2010907 45.5047752,24.6732021 46.1535022,26.1203623" id="path29670-2" fill="#020204"></path>
|
||||
<path d="M32.3071772,70.3379664 C33.6794843,70.4128195 35.0517915,70.5625257 36.3991476,70.7621341 C37.5967974,70.9367913 38.7694963,71.1863017 39.9671462,71.4607632 C41.813523,71.9098819 43.6349489,72.4837558 45.5312279,72.5336578 C46.0302487,72.5586089 46.5292694,72.5336578 47.0282902,72.4089026 C47.527311,72.3090985 47.9764297,72.1094902 48.3756463,71.7851267 C48.9495202,71.3110569 49.3237858,70.6124278 49.4734921,69.8888477 C49.6231983,69.1652676 49.5233941,68.3917853 49.3237858,67.6931563 C48.8996182,66.270947 47.9764297,65.0483461 47.2278985,63.7758431 C46.8037309,63.052263 46.4045142,62.2787808 45.9304445,61.5801517 C45.4563748,60.8815226 44.8825009,60.2078445 44.1838718,59.7587258 C43.1858302,59.1099988 41.9632293,58.9103905 40.7905304,59.0351457 C39.6178316,59.1599009 38.4950348,59.5840685 37.4470912,60.1080404 C35.9749799,60.8565715 34.6026728,61.9045152 33.8042395,63.3516754 C33.5297781,63.8506962 33.3301698,64.3996191 33.0806594,64.9235909 C32.8561,65.4475627 32.5566875,65.9715346 32.1574709,66.3707512 C31.7083522,66.8198699 31.1344783,67.1442334 30.6604086,67.5933521 C30.4358492,67.8179114 30.2362409,68.0674218 30.1114857,68.3668343 C29.9867305,68.6662468 29.9617795,69.0155613 30.0615836,69.3149738 C30.1364368,69.5145821 30.2611919,69.7141904 30.4358492,69.8389456 C30.6105065,69.9886518 30.8101148,70.088456 31.0097231,70.1633091 C31.4338908,70.2880643 31.8830095,70.3130154 32.3071772,70.3379664" id="path29676-3" fill="#020204"></path>
|
||||
<path d="M27.9409416,70.2361543 C26.7931938,70.2611053 25.6703971,70.4607136 24.5476003,70.710224 C23.4747056,70.9347834 22.401811,71.1842938 21.3538673,71.4587552 C19.5573925,71.9328249 17.7858687,72.4817478 15.9394918,72.5316499 C15.4654221,72.5316499 14.9664013,72.5066988 14.4923316,72.4068947 C14.0182618,72.3070905 13.5691431,72.1074822 13.1699265,71.8080697 C12.5960526,71.334 12.221787,70.6603219 12.0720808,69.9117908 C11.9223745,69.1632596 12.0221787,68.4147284 12.221787,67.7160993 C12.6459547,66.2938901 13.5441921,65.0712892 14.2927233,63.7987862 C14.7168909,63.0752061 15.0911565,62.3017238 15.5402752,61.6030947 C15.9893939,60.9044656 16.5383168,60.2307876 17.2618969,59.7567179 C18.2100364,59.1329419 19.4076863,58.9083825 20.5554341,59.0331377 C21.7031819,59.1578929 22.8010276,59.5571095 23.7990692,60.1060324 C25.2212784,60.8795146 26.5187324,61.9524093 27.3421167,63.3496675 C27.9159906,64.322758 28.2653052,65.4455548 28.9389832,66.3687432 C29.3132488,66.867764 29.7623675,67.2919317 30.06178,67.8159035 C30.2114862,68.0903649 30.3112904,68.3648263 30.3611924,68.6891898 C30.3861435,68.9886023 30.3112904,69.3129658 30.1615841,69.5624762 C30.0368289,69.7371335 29.8871227,69.8618887 29.7124654,69.9616928 C29.5378081,70.061497 29.3381998,70.1363501 29.1385915,70.1613012 C28.7643259,70.2361543 28.3401583,70.2361543 27.9409416,70.2361543" id="path29676-7-1" fill="#020204"></path>
|
||||
<path d="M21.3925244,22.15769 C21.2428181,20.211509 21.2677692,18.290279 21.192916,16.3440979 C21.1180629,14.47277 20.9434057,12.6263931 21.0182588,10.7550652 C21.0931119,8.85878618 21.3925244,6.93755617 22.2408597,5.24088552 C23.089195,3.54421486 24.4615022,2.09705459 26.1332218,1.19881718 C27.7051373,0.350481853 29.5265631,-0.0237837335 31.2980869,0.0011673056 C33.7183377,0.0261183447 36.1635395,0.749698478 38.1097206,2.17190771 C39.3323215,3.07014511 40.3802651,4.21789291 41.2036494,5.49039591 C41.9022785,6.58824163 42.4512014,7.7858915 42.7755649,9.03344346 C43.474194,11.6034005 43.2995367,14.2981127 43.4492429,16.9678739 C43.5739981,19.4879288 43.9732147,22.0079838 43.8484595,24.5280387 C43.8235085,25.0769616 43.7486554,25.6258845 43.524096,26.1249052 C43.2745856,26.598975 42.875369,26.9981916 42.4262503,27.247702 C41.9521806,27.5221634 41.4531598,27.6718697 40.9042369,27.7467228 C39.8562933,27.9213801 38.7833986,27.7966249 37.7105039,27.896429 C36.1635395,28.0461352 34.6914282,28.6200091 33.1694148,28.8445685 C31.347989,29.1190299 29.476661,28.9194216 27.6552352,28.8445685 C26.906704,28.8196175 26.1831239,28.7946664 25.4345927,28.7198133 C24.7110126,28.6200091 23.9624814,28.4453519 23.3137544,28.0960373 C22.9145377,27.871478 22.5402722,27.5970165 22.2408597,27.272653 C21.9414472,26.9233385 21.7168879,26.5241219 21.5921327,26.0750032 C21.4174754,25.4013251 21.5172796,24.727647 21.5172796,24.029018 C21.5172796,23.405242 21.4424264,22.781466 21.3925244,22.15769" id="path28712-2" fill="#020204"></path>
|
||||
<path d="M24.4857731,22.0829382 C24.2362627,22.4073017 24.0616054,22.8065184 23.9618013,23.205735 C23.8619971,23.6049516 23.812095,24.0291193 23.812095,24.453287 C23.787144,25.3016223 23.8370461,26.1499576 23.6124867,26.9483909 C23.3879274,27.8216772 22.8390045,28.5702084 22.3150327,29.2937885 C21.4167953,30.5662915 20.5185579,31.8637456 20.0694392,33.3358569 C19.7949777,34.2340943 19.7201246,35.1822338 19.8199288,36.1303733 C18.8218872,37.6024846 17.9486009,39.1744 17.2250207,40.8211686 C16.127175,43.2913215 15.3786438,45.9361316 15.1041824,48.6308438 C14.7798189,51.924381 15.2039866,55.3426734 16.5014406,58.3867001 C17.4495801,60.5823916 18.8468383,62.6034257 20.6682641,64.1753412 C21.5914526,64.9737744 22.6144452,65.6474525 23.7122909,66.1963754 C27.5048488,68.0677033 32.1956442,68.0677033 35.9383,66.0716202 C37.8844811,65.0236765 39.5312497,63.5016631 41.1281162,61.9796498 C42.0762557,61.0564613 43.0243951,60.1083218 43.7729263,58.9855251 C45.1701845,56.8397357 45.6692053,54.2448276 45.9686178,51.6998216 C46.4925896,47.2585367 46.5175406,42.5427903 44.5713596,38.525673 C43.8976815,37.1284148 42.9994441,35.8559118 41.9265494,34.7580661 C41.652088,32.8118851 41.0782141,30.9156061 40.2548298,29.1440823 C39.6560049,27.8466283 38.9324247,26.6240274 38.3835019,25.3265733 C38.1589425,24.8026015 37.9593342,24.2536786 37.7098238,23.7297068 C37.4603134,23.205735 37.160901,22.7067142 36.7367333,22.3074976 C36.3125656,21.908281 35.7636428,21.6088685 35.2147199,21.4092602 C34.640846,21.2346029 34.0669721,21.1347988 33.4681472,21.1098477 C32.2704973,21.0599456 31.0977985,21.2096519 29.9001486,21.1597498 C28.9520091,21.1098477 28.0038696,20.9601415 27.0557301,21.0100436 C26.5816604,21.0349946 26.1075906,21.1347988 25.6584719,21.309456 C25.2093532,21.4841133 24.7851856,21.7086727 24.4857731,22.0829382" id="path29719-5" fill="#FDFDFB"></path>
|
||||
<path d="M25.1049189,11.0038778 C24.6558002,11.0288289 24.2316326,11.2284372 23.9072691,11.5278496 C23.5829056,11.8272621 23.3583462,12.2264787 23.20864,12.6506464 C22.9341785,13.4989817 22.9840806,14.4221702 23.0589337,15.2954566 C23.1088358,16.0938898 23.1836889,16.9172741 23.4831014,17.6658053 C23.6328076,18.0400709 23.857367,18.3893854 24.1318284,18.6887979 C24.4062898,18.9882103 24.7805554,19.1878187 25.154821,19.2876228 C25.5290866,19.387427 25.9033522,19.3624759 26.2776178,19.2377207 C26.6269323,19.1129655 26.9762469,18.9133572 27.2257573,18.6638468 C27.6249739,18.2895812 27.8744843,17.7656094 28.0491416,17.2416376 C28.1988478,16.7176658 28.2487499,16.1437919 28.2487499,15.594869 C28.2487499,14.8962399 28.1489457,14.2225619 27.9243864,13.5488838 C27.699827,12.9001568 27.3754635,12.2763808 26.8764427,11.77736 C26.6518834,11.5278496 26.3774219,11.3282413 26.0780095,11.1785351 C25.778597,11.0787309 25.4542335,10.9789268 25.1049189,11.0038778" id="path28795-9-5" fill="#FDFDFB"></path>
|
||||
<path d="M32.7547573,11.5576557 C32.0561282,12.0317255 31.4822543,12.7054035 31.2077928,13.5038368 C30.8584783,14.5018783 30.9832335,15.6246751 31.332548,16.6227167 C31.6818626,17.6457093 32.2806875,18.6187998 33.1789249,19.2425758 C33.6280436,19.5419882 34.1520155,19.7665476 34.6759873,19.8164497 C35.2249101,19.8913028 35.773833,19.7914986 36.2479027,19.5419882 C36.8467277,19.2425758 37.2708953,18.6936529 37.5703078,18.094828 C37.8447692,17.496003 37.9695244,16.822325 37.9944755,16.173598 C38.0443776,15.3252626 37.9695244,14.4769273 37.695063,13.678494 C37.3956505,12.8052077 36.8467277,12.0067744 36.0732455,11.5077536 C35.6989799,11.2582433 35.2498612,11.083586 34.8007425,11.0336839 C34.3516238,10.9588308 33.877554,11.0087329 33.4533864,11.1833901 C33.1789249,11.2831943 32.9543656,11.4079495 32.7547573,11.5576557" id="path28795-3" fill="#FDFDFB"></path>
|
||||
<g id="g28965-1" transform="translate(33.000000, 13.000000)" fill="#020204">
|
||||
<path d="M1.79647481,0.0998041564 C1.54696442,0.124755195 1.27250299,0.199608313 1.04794364,0.349314547 C0.82338429,0.499020782 0.648727016,0.673678056 0.499020782,0.898237407 C0.199608313,1.32240507 0.0748531173,1.84637689 0.0499020782,2.37034871 C0.0249510391,2.76956534 0.0748531173,3.16878196 0.199608313,3.51809651 C0.324363508,3.8923621 0.54892286,4.24167665 0.848335329,4.49118704 C1.1477478,4.74069743 1.54696442,4.89040366 1.94618105,4.9153547 C2.34539767,4.94030574 2.7446143,4.81555055 3.09392885,4.59099119 C3.36839028,4.41633392 3.56799859,4.16682353 3.71770482,3.86741106 C3.86741106,3.59294963 3.96721522,3.26858612 3.99216625,2.94422261 C4.06701937,2.39529975 3.99216625,1.79647481 3.71770482,1.29745403 C3.46819443,0.798433251 3.01907573,0.374265586 2.49510391,0.174657274 C2.27054456,0.124755195 2.02103417,0.0748531173 1.79647481,0.0998041564" id="path28879-6"></path>
|
||||
</g>
|
||||
<g id="g29497-8" transform="translate(24.000000, 14.000000)" fill="#020204">
|
||||
<path d="M0.224559352,1.42220923 C0.124755195,1.97113209 0.124755195,2.56995703 0.324363508,3.09392885 C0.449118704,3.44324339 0.673678056,3.7676069 0.923188446,4.04206833 C1.09784572,4.21672561 1.27250299,4.39138288 1.49706235,4.49118704 C1.7216217,4.59099119 1.97113209,4.64089327 2.22064248,4.59099119 C2.44520183,4.54108912 2.64481014,4.39138288 2.76956534,4.21672561 C2.91927157,4.04206833 2.99412469,3.81750898 3.06897781,3.61790067 C3.26858612,2.96917365 3.24363508,2.27054456 3.04402677,1.64676858 C2.89432053,1.17269884 2.66976118,0.723580134 2.2954956,0.424167665 C2.12083832,0.27446143 1.92123001,0.149706235 1.67171962,0.0998041564 C1.44716027,0.0499020782 1.19764988,0.0499020782 0.998041564,0.149706235 C0.773482212,0.249510391 0.573873899,0.449118704 0.474069743,0.698629095 C0.349314547,0.923188446 0.27446143,1.17269884 0.224559352,1.42220923" id="path29453-9"></path>
|
||||
</g>
|
||||
<g id="g29634-9" transform="translate(22.999845, 16.000000)">
|
||||
<path d="M0,5.72292607 C0.0249510391,5.79777918 0.0499020782,5.8726323 0.0748531173,5.92253438 C0.149706235,6.02233853 0.249510391,6.12214269 0.349314547,6.19699581 C0.449118704,6.27184893 0.573873899,6.34670204 0.673678056,6.39660412 C1.24755195,6.77086971 1.7216217,7.26989049 2.14578936,7.81881335 C2.71966326,8.54239348 3.21868404,9.36577777 3.96721522,9.88974959 C4.49118704,10.2640152 5.13991405,10.4885745 5.78864107,10.5384766 C6.56212328,10.6133297 7.31065445,10.4885745 8.05918563,10.2640152 C8.73286368,10.0644069 9.40654174,9.78994544 10.0053667,9.41567985 C11.1531145,8.71705076 12.101254,7.66910712 13.373757,7.19503737 C13.6482184,7.09523322 13.9476309,7.0203801 14.1971412,6.8956249 C14.4716027,6.77086971 14.7211131,6.57126139 14.8458683,6.321751 C14.9706235,6.07224061 14.9706235,5.77282814 14.9955745,5.49836671 C15.0454766,5.19895424 15.1452807,4.89954178 15.1951828,4.60012931 C15.2450849,4.30071684 15.2450849,3.97635333 15.1203297,3.7018919 C15.0205255,3.47733255 14.8209172,3.30267527 14.5963579,3.17792008 C14.3717985,3.05316488 14.1222881,3.0032628 13.8727777,3.0032628 C13.373757,2.97831177 12.8747362,3.10306696 12.3757154,3.15296904 C11.7269884,3.20287112 11.0533103,3.128018 10.3796323,3.15296904 C9.55624797,3.17792008 8.73286368,3.35257735 7.90947939,3.40247943 C6.96133991,3.45238151 6.03815146,3.30267527 5.09001198,3.2527732 C4.69079535,3.22782216 4.26662769,3.22782216 3.86741106,3.30267527 C3.46819443,3.37752839 3.06897781,3.50228359 2.7446143,3.75179398 C2.42025079,3.97635333 2.14578936,4.2757658 1.84637689,4.55022723 C1.69667066,4.67498242 1.54696442,4.79973762 1.34735611,4.87459074 C1.1477478,4.94944385 0.973090525,5.02429697 0.773482212,4.99934593 C0.673678056,4.99934593 0.573873899,4.97439489 0.474069743,4.99934593 C0.424167665,5.02429697 0.349314547,5.04924801 0.324363508,5.09915009 C0.299412469,5.14905217 0.249510391,5.19895424 0.199608313,5.24885632 C0.124755195,5.44846464 0.0499020782,5.57321983 0,5.72292607" id="path28461-2" fill="#FFB510"></path>
|
||||
<g id="path27476-7-8" transform="translate(0.000000, 3.000000)" fill="#604405">
|
||||
<path d="M1.52201338,1.32240507 C1.19764988,1.52201338 0.873286368,1.74657274 0.54892286,1.97113209 C0.374265586,2.09588728 0.224559352,2.22064248 0.124755195,2.39529975 C0.0748531173,2.52005495 0.0499020782,2.66976118 0.0499020782,2.81946742 L0.0499020782,3.24363508 C0.0249510391,3.34343924 0,3.44324339 0,3.54304755 C0,3.59294963 0,3.64285171 0.0249510391,3.69275379 C0.0499020782,3.74265586 0.0499020782,3.79255794 0.0998041564,3.81750898 C0.149706235,3.86741106 0.199608313,3.8923621 0.249510391,3.91731314 C0.299412469,3.94226418 0.374265586,3.94226418 0.424167665,3.96721522 C0.723580134,4.04206833 0.973090525,4.21672561 1.19764988,4.41633392 C1.42220923,4.61594223 1.62181754,4.84050158 1.84637689,5.0401099 C2.47015287,5.56408172 3.3184882,5.76369003 4.14187249,5.78864107 C4.96525678,5.81359211 5.76369003,5.63893484 6.56212328,5.46427756 C7.18589926,5.31457133 7.80967524,5.16486509 8.40850017,4.96525678 C9.33168862,4.61594223 10.180024,4.11692145 10.9285551,3.46819443 C11.2529186,3.16878196 11.5772821,2.84441846 11.9515477,2.6198591 C12.2759112,2.42025079 12.6501768,2.27054456 12.9994914,2.07093624 C13.0244424,2.04598521 13.0493934,2.04598521 13.0992955,2.02103417 C13.1242466,1.99608313 13.1491976,1.97113209 13.1741486,1.94618105 C13.1990997,1.89627897 13.1990997,1.82142585 13.1741486,1.77152378 C13.1491976,1.7216217 13.1242466,1.67171962 13.0743445,1.62181754 C13.0244424,1.57191546 12.9745403,1.52201338 12.9246383,1.47211131 C12.5753237,1.17269884 12.0763029,1.04794364 11.6271842,1.0229926 C11.1531145,0.998041564 10.6790447,1.0229926 10.229926,0.923188446 C9.80575836,0.848335329 9.3815907,0.698629095 8.95742303,0.54892286 C8.50830433,0.399216625 8.05918563,0.299412469 7.61006692,0.224559352 C6.53717224,0.0499020782 5.43932652,0.0748531173 4.36643184,0.299412469 C3.36839028,0.424167665 2.39529975,0.798433251 1.52201338,1.32240507" id="Shape"></path>
|
||||
</g>
|
||||
<path d="M1.99608313,2.36612373 C1.52201338,2.69048723 1.07289468,3.08970386 0.723580134,3.53882256 C0.523971821,3.78833295 0.324363508,4.08774542 0.224559352,4.38715789 C0.149706235,4.63666828 0.124755195,4.88617867 0.0499020782,5.1606401 C0.0249510391,5.26044426 0,5.36024842 0,5.46005257 C0,5.50995465 0,5.55985673 0.0249510391,5.60975881 C0.0499020782,5.65966089 0.0748531173,5.70956296 0.0998041564,5.734514 C0.149706235,5.78441608 0.224559352,5.83431816 0.324363508,5.83431816 C0.399216625,5.8592692 0.474069743,5.8592692 0.573873899,5.8592692 C0.948139486,5.90917128 1.27250299,6.08382855 1.57191546,6.28343686 C1.87132793,6.48304518 2.14578936,6.73255557 2.47015287,6.93216388 C3.14383093,7.35633154 3.96721522,7.55593986 4.76564847,7.5808909 C5.56408172,7.60584193 6.38746601,7.48108674 7.16094822,7.3313805 C7.7847242,7.20662531 8.40850017,7.05691907 9.00732511,6.83235972 C9.93051356,6.48304518 10.7538978,5.90917128 11.5273801,5.33529738 C11.8766946,5.06083595 12.2260092,4.78637452 12.5503727,4.48696205 C12.6501768,4.38715789 12.774932,4.2624027 12.8747362,4.18754958 C12.9994914,4.08774542 13.1242466,4.01289231 13.2739528,3.96299023 C13.4985121,3.88813711 13.7230715,3.91308815 13.9476309,3.96299023 C14.1222881,3.98794127 14.2969454,4.03784334 14.4716027,4.01289231 C14.5464558,4.01289231 14.6462599,3.98794127 14.7211131,3.96299023 C14.7959662,3.93803919 14.8708193,3.88813711 14.9207214,3.81328399 C14.9955745,3.71347984 15.0205255,3.61367568 15.0205255,3.48892048 C15.0205255,3.36416529 14.9955745,3.26436113 14.9207214,3.16455698 C14.7959662,2.96494866 14.5963579,2.84019347 14.3967496,2.74038931 C14.1222881,2.61563412 13.7979246,2.540781 13.4985121,2.46592788 C12.5753237,2.24136853 11.6521353,1.91700502 10.8037999,1.46788632 C10.3796323,1.24332697 9.9554646,1.01876761 9.53129693,0.794208262 C9.10712927,0.56964891 8.65801057,0.345089558 8.18394082,0.195383324 C7.13599718,-0.128980184 5.98824938,-0.029176028 4.94030574,0.345089558 C3.84246002,0.719355145 2.79451638,1.44293528 1.99608313,2.36612373 L1.99608313,2.36612373" id="path27476-4" fill="#FFB510"></path>
|
||||
</g>
|
||||
<path d="M47.3006272,37.3384927 C48.8226406,38.5610936 49.7707801,40.4074705 50.0701925,42.3287005 C50.2947519,43.8257629 50.1450456,45.3727273 49.8206821,46.8448386 C49.4963186,48.3169499 48.9473958,49.7641102 48.448375,51.1863194 C48.2487667,51.7601933 48.0242073,52.3340672 47.9493542,52.9328922 C47.8745011,53.5317171 47.9244032,54.1804441 48.1988646,54.7044159 C48.5232281,55.3032409 49.1470041,55.7274085 49.8206821,55.9270168 C50.4694091,56.1266252 51.1929893,56.1266252 51.8417163,55.9519679 C52.5153944,55.7773106 53.1391703,55.4529471 53.6631421,55.0537305 C55.0354493,53.9808358 55.8588336,52.3340672 56.1831971,50.6124455 C56.5075606,48.8908238 56.3578544,47.1193 56.0584419,45.4226294 C55.6592253,43.0772317 54.9605962,40.7817361 54.0873098,38.5860447 C53.4385828,36.9642271 52.6900516,35.3673606 51.642108,33.9701024 C50.6191154,32.5977953 49.3216613,31.4500475 48.3236198,30.0777403 C47.6249907,29.1046498 47.0760678,28.0567062 46.2277325,27.2083708 C45.8035648,26.7842032 45.3294951,26.4348886 44.7556212,26.2103293 C44.2066983,25.9857699 43.5829224,25.9358679 43.0090485,26.0855741 C42.2605173,26.3101334 41.6367413,26.8840073 41.3123778,27.6075875 C40.9880143,28.3311676 40.9381122,29.1296009 41.0628674,29.9030831 C41.2375247,30.9011246 41.6866434,31.8243131 42.1856642,32.6975994 C42.7595381,33.67069 43.4332161,34.6188295 44.3065025,35.3673606 C45.254642,36.0909408 46.3774387,36.5899615 47.3006272,37.3384927" id="path29705-5-0" fill="#020204"></path>
|
||||
<g id="g17048" transform="translate(41.000000, 52.000000)" fill="#FFB510">
|
||||
<path d="M21.707404,11.6022332 C21.5327467,12.0264008 21.3081874,12.4256175 21.0087749,12.774932 C20.3600479,13.5484142 19.4368595,14.072386 18.538622,14.5215048 C16.9916576,15.319938 15.3947911,15.9936161 13.9476309,16.9417555 C12.9745403,17.5655315 12.0763029,18.3140627 11.2279676,19.1124959 C10.5043875,19.811125 9.8307094,20.5347052 9.03227615,21.1085791 C8.20889186,21.707404 7.28570342,22.1315717 6.28766185,22.2812779 C5.09001198,22.4559352 3.84246002,22.2313758 2.71966326,21.7323551 C1.94618105,21.3830405 1.17269884,20.9089708 0.723580134,20.1853906 C0.27446143,19.4618105 0.174657274,18.5635731 0.174657274,17.7152378 C0.174657274,16.1932244 0.449118704,14.696162 0.723580134,13.1990997 C0.948139486,11.9515477 1.1477478,10.7039958 1.29745403,9.45644382 C1.54696442,7.18589926 1.54696442,4.86545262 1.37230715,2.59490807 C1.34735611,2.22064248 1.32240507,1.82142585 1.37230715,1.44716027 C1.42220923,1.07289468 1.5968665,0.698629095 1.87132793,0.449118704 C2.14578936,0.224559352 2.49510391,0.124755195 2.84441846,0.0998041564 C3.193733,0.0748531173 3.54304755,0.124755195 3.8923621,0.199608313 C4.71574639,0.324363508 5.56408172,0.424167665 6.36251497,0.623775977 C6.86153575,0.748531173 7.36055653,0.948139486 7.88452835,1.07289468 C8.73286368,1.29745403 9.63110109,1.42220923 10.5043875,1.32240507 C11.4525269,1.22260092 12.3507644,0.848335329 13.2989038,0.873286368 C13.6981205,0.873286368 14.072386,0.948139486 14.4466516,1.07289468 C14.8209172,1.19764988 15.1951828,1.37230715 15.4696442,1.64676858 C15.6692526,1.87132793 15.8189588,2.12083832 15.943714,2.42025079 C16.1183713,2.84441846 16.1932244,3.29353716 16.2431264,3.71770482 C16.2680775,4.11692145 16.2680775,4.51613808 16.3429306,4.9153547 C16.4676858,5.56408172 16.7920493,6.13795562 17.216217,6.6369764 C17.6403846,7.13599718 18.1394054,7.56016485 18.6384262,7.98433251 C19.137447,8.40850017 19.6364678,8.83266784 20.1853906,9.18198239 C20.434901,9.35663966 20.7093624,9.50634589 20.9339218,9.70595421 C21.1834322,9.90556252 21.3830405,10.1051708 21.5327467,10.3796323 C21.7323551,10.7538978 21.8072082,11.2030166 21.707404,11.6022332 L21.707404,11.6022332" id="path14296-0"></path>
|
||||
</g>
|
||||
<g id="path28767-9-3" opacity="0.25" transform="translate(20.000000, 28.000000)" fill="#7C7C7C">
|
||||
<path d="M1.1477478,0.399216625 C1.12279676,0.0499020782 0.598824938,-0.0249510391 0.374265586,0.174657274 C0.174657274,0.324363508 -2.65065747e-15,0.848335329 0.174657274,1.04794364 C0.424167665,1.37230715 1.17269884,0.898237407 1.1477478,0.399216625 Z" id="Shape"></path>
|
||||
</g>
|
||||
<g id="g14884-8" transform="translate(46.000000, 50.000000)" fill="#020204">
|
||||
<path d="M9.03227615,2.24559352 C8.932472,1.97113209 8.75781472,1.7216217 8.53325537,1.52201338 C8.30869602,1.32240507 8.05918563,1.17269884 7.7847242,1.04794364 C7.23580134,0.82338429 6.66192744,0.723580134 6.08805354,0.623775977 C5.53913068,0.523971821 5.01515886,0.399216625 4.466236,0.299412469 C3.8923621,0.199608313 3.3184882,0.149706235 2.7446143,0.27446143 C2.24559352,0.374265586 1.79647481,0.648727016 1.42220923,0.973090525 C1.04794364,1.29745403 0.773482212,1.74657274 0.54892286,2.19569144 C0.174657274,2.99412469 0.0748531173,3.91731314 0.124755195,4.79059951 C0.174657274,5.43932652 0.349314547,6.11300458 0.773482212,6.61202536 C1.12279676,7.01124199 1.62181754,7.26075238 2.12083832,7.41045861 C2.99412469,7.659969 3.96721522,7.659969 4.84050158,7.36055653 C6.28766185,6.88648679 7.56016485,5.91339627 8.40850017,4.66584431 C8.6829616,4.26662769 8.932472,3.81750898 9.05722719,3.3184882 C9.15703135,2.99412469 9.15703135,2.59490807 9.03227615,2.24559352" id="path29714-5-4"></path>
|
||||
</g>
|
||||
<g id="g15037-4" transform="translate(9.000000, 27.000000)" fill="#020204">
|
||||
<path d="M10.0303177,2.6198591 C9.30673758,3.51809651 8.60810849,4.41633392 7.88452835,5.31457133 C7.01124199,6.41241705 6.11300458,7.51026277 5.53913068,8.78276576 C5.0401099,9.88061148 4.81555055,11.0782614 4.466236,12.2260092 C4.09197041,13.5484142 3.56799859,14.8209172 2.96917365,16.0435181 C2.42025079,17.1912659 1.84637689,18.3140627 1.24755195,19.4119084 C0.82338429,20.2352927 0.374265586,21.058677 0.224559352,21.9569144 C0.0998041564,22.6804945 0.174657274,23.4040747 0.349314547,24.1276548 C0.523971821,24.8262839 0.82338429,25.499962 1.1477478,26.148689 C2.56995703,28.9182543 4.69079535,31.288603 7.18589926,33.1100289 C8.33364706,33.9334132 7.06114406,32.1618894 8.33364706,32.7357633 C9.03227615,33.0601268 9.75585629,33.3345882 10.5293385,33.3595393 C10.9036041,33.3595393 11.3028207,33.3096372 11.6521353,33.159931 C12.0014498,33.0102247 12.3258133,32.7607143 12.5254216,32.4363508 C12.774932,32.0371342 12.8747362,31.5630645 12.8248341,31.0889947 C12.774932,30.614925 12.6002747,30.1658063 12.3507644,29.7665896 C11.7519394,28.7934991 10.8037999,28.069919 9.90556252,27.3712899 C7.95938147,25.8492765 8.55820641,26.7475139 6.73678056,25.0757943 C6.23775977,24.6017245 5.71378795,24.1027038 5.36447341,23.5038788 C5.01515886,22.9300049 4.84050158,22.2563269 4.69079535,21.5826488 C4.3414808,19.761223 4.44128496,17.8150419 5.06506094,16.0684692 C5.31457133,15.3698401 5.63893484,14.7211131 5.9383473,14.072386 C6.48727016,12.9246383 6.98629095,11.7519394 7.68492004,10.7039958 C8.55820641,9.40654174 9.75585629,8.28374498 10.4794364,6.88648679 C11.0782614,5.71378795 11.3277717,4.36643184 11.5772821,3.06897781 C11.7519394,2.07093624 11.9265967,1.04794364 12.101254,0.0249510391 C11.4026249,0.898237407 10.7039958,1.77152378 10.0303177,2.6198591 Z" id="path14967-1-0"></path>
|
||||
</g>
|
||||
<g id="Group" transform="translate(0.000000, 51.000000)" fill="#FFB510">
|
||||
<g id="g14180-6" transform="translate(0.000000, -0.000000)">
|
||||
<path d="M10.3796323,0.174657274 C10.7788489,-1.26496036e-14 11.2279676,-0.0249510391 11.6521353,0.0499020782 C12.0763029,0.124755195 12.4755195,0.299412469 12.8248341,0.54892286 C13.5484142,1.0229926 14.072386,1.74657274 14.5714068,2.44520183 C15.7441057,4.04206833 16.8669024,5.68883691 17.864944,7.38550757 C18.6883283,8.75781472 19.4368595,10.204975 20.40995,11.502429 C21.033726,12.3507644 21.7323551,13.1242466 22.356131,13.9725819 C22.979907,14.8209172 23.5288299,15.7441057 23.8032913,16.7421472 C24.1526058,18.0645523 24.0278506,19.5117126 23.4040747,20.7343135 C22.954956,21.5826488 22.2812779,22.33118 21.4578936,22.8052497 C20.6345093,23.2793195 19.6614188,23.5537809 18.7132793,23.5288299 C17.1912659,23.4789278 15.7940077,22.7054456 14.3717985,22.1565227 C11.477478,21.0087749 8.33364706,20.6345093 5.36447341,19.7362719 C4.44128496,19.4618105 3.54304755,19.137447 2.6198591,18.8879366 C2.22064248,18.7631814 1.79647481,18.6883283 1.39725819,18.48872 C0.998041564,18.3140627 0.648727016,18.0645523 0.424167665,17.6902867 C0.249510391,17.4158253 0.199608313,17.0665107 0.199608313,16.7421472 C0.199608313,16.4177837 0.27446143,16.0934202 0.399216625,15.7690567 C0.623775977,15.1452807 0.973090525,14.5963579 1.22260092,13.9725819 C1.62181754,12.9745403 1.69667066,11.8766946 1.64676858,10.8037999 C1.5968665,9.73090525 1.42220923,8.6829616 1.34735611,7.61006692 C1.32240507,7.13599718 1.29745403,6.6369764 1.39725819,6.1878577 C1.49706235,5.73873899 1.69667066,5.26466925 2.04598521,4.9153547 C2.37034871,4.61594223 2.79451638,4.41633392 3.21868404,4.3414808 C3.64285171,4.24167665 4.09197041,4.24167665 4.54108912,4.26662769 C4.99020782,4.26662769 5.41437548,4.29157872 5.86349419,4.26662769 C6.31261289,4.24167665 6.73678056,4.14187249 7.13599718,3.91731314 C7.51026277,3.71770482 7.80967524,3.39334132 8.03423459,3.06897781 C8.25879394,2.7446143 8.48335329,2.37034871 8.6829616,1.99608313 C8.88256992,1.62181754 9.10712927,1.27250299 9.35663966,0.948139486 C9.60615005,0.623775977 9.98041564,0.324363508 10.3796323,0.174657274" id="path4635-1"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 28 KiB |
19
deps/juce/extras/Projucer/Source/BinaryData/Icons/export_visualStudio.svg
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Visual Studio</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Artboard" transform="translate(-77.000000, -43.000000)">
|
||||
<g id="Visual-Studio" transform="translate(76.000000, 41.000000)">
|
||||
<polygon id="Rectangle" fill="#68217A" points="1 7 3 6 3 18 1 17"></polygon>
|
||||
<polygon id="Rectangle-2" fill="#541D66" transform="translate(5.607051, 10.000000) rotate(-330.000000) translate(-5.607051, -10.000000) " points="1.34927858 7.83942379 7.86482304 8.6964746 9.86482304 12.1605762 2.84927858 10.4375"></polygon>
|
||||
<polygon id="Rectangle-3" fill="#541D66" points="3 15 8 10 8 14 3 18"></polygon>
|
||||
<polygon id="Rectangle-2-Copy" fill="#68217A" transform="translate(12.000000, 16.000000) rotate(-330.000000) translate(-12.000000, -16.000000) " points="5.53589838 12.8038476 15.4641016 14 18.4641016 19.1961524 7.53589838 16.2679492"></polygon>
|
||||
<polygon id="Rectangle-2-Copy-2" fill="#68217A" transform="translate(12.433013, 8.250000) rotate(-330.000000) translate(-12.433013, -8.250000) " points="9.46891109 11.9820508 12.3971143 1.05384758 15.3971143 6.25 11.4689111 15.4461524"></polygon>
|
||||
<polygon id="Rectangle-4" fill="#541D66" points="16 2 21 4 21 20 16 22"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
29
deps/juce/extras/Projucer/Source/BinaryData/Icons/export_xcode.svg
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="33px" height="32px" viewBox="0 0 33 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Group 2</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Artboard" transform="translate(-28.000000, -50.000000)">
|
||||
<g id="Group-2" transform="translate(28.000000, 50.000000)">
|
||||
<g id="folder" transform="translate(0.000000, 5.000000)">
|
||||
<polygon id="Rectangle-5" fill="#457EFD" points="0 4 27 0 30 21 3 25"></polygon>
|
||||
<path d="M19.9232759,13.0294985 C20.1413793,12.8123894 20.1034483,12.6519174 19.9517241,12.4725664 C19.3543103,11.7646018 18.7758621,11.0566372 18.1784483,10.3486726 C16.5189655,8.35693215 14.85,6.35575221 13.1905172,4.35457227 C13.0577586,4.19410029 12.9439655,3.97699115 12.9060345,3.76932153 C12.8396552,3.36342183 13.1146552,2.99528024 13.512931,2.83480826 C13.9396552,2.67433628 14.3094828,2.78761062 14.6698276,3.21238938 C16.3008621,5.15693215 17.9413793,7.10147493 19.5724138,9.0460177 C19.9612069,9.50855457 20.3594828,9.97109145 20.7672414,10.4525074 C20.9758621,10.2353982 20.9474138,10.0749263 20.7956897,9.89557522 C20.1413793,9.12153392 19.487069,8.3380531 18.8327586,7.5640118 C17.5146552,5.99705015 16.2060345,4.4300885 14.8784483,2.8820059 C14.3474138,2.26843658 13.5413793,2.23067847 12.9534483,2.74041298 C12.375,3.24070796 12.3465517,3.94867257 12.887069,4.59056047 C14.9353448,7.05427729 16.9836207,9.50855457 19.0318966,11.9722714 C19.3258621,12.3309735 19.6198276,12.6707965 19.9232759,13.0294985 Z" id="Shape" fill="#235EE1" fill-rule="nonzero"></path>
|
||||
<path d="M13.3801724,9.05545723 C13.3137931,9.00825959 13.237931,8.94218289 13.1525862,8.90442478 C12.4982759,8.65899705 11.8439655,8.43244838 11.1896552,8.18702065 C10.9810345,8.11150442 10.8862069,8.18702065 10.8103448,8.36637168 C9.61551724,11.2926254 8.42068966,14.2094395 7.22586207,17.1356932 C7.13103448,17.3528024 7.19741379,17.4566372 7.39655172,17.5321534 C8.01293103,17.7775811 8.62931034,18.0135693 9.2362069,18.2873156 C9.56810345,18.4383481 9.70086207,18.3628319 9.82413793,18.0324484 C10.962069,15.1345133 12.1189655,12.2460177 13.2663793,9.35752212 C13.2948276,9.29144543 13.3232759,9.19705015 13.3801724,9.05545723 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
<path d="M19.6293103,13.1050147 C19.1551724,12.5103245 18.7189655,12.019469 18.3586207,11.4908555 C18.0362069,11 17.6758621,10.7451327 17.0784483,10.9905605 C16.9362069,11.0471976 16.775,11.0471976 16.6232759,11.0660767 C15.3525862,11.2831858 14.0913793,11.500295 12.8206897,11.7174041 C12.6215517,11.7551622 12.4508621,11.8023599 12.3655172,12.0383481 C12.1189655,12.7368732 11.8534483,13.4259587 11.5974138,14.1244838 C11.5689655,14.2 11.5689655,14.2943953 11.55,14.4265487 C14.2525862,13.9923304 16.8887931,13.5581121 19.6293103,13.1050147 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
<path d="M8.97068966,12.2648968 C7.41551724,12.519764 5.9362069,12.7557522 4.40948276,13.0011799 C4.5137931,13.7091445 4.62758621,14.379351 4.70344828,15.0589971 C4.74137931,15.3516224 4.86465517,15.3893805 5.13017241,15.3516224 C5.90775862,15.2289086 6.69482759,15.1250737 7.48189655,15.0306785 C7.71896552,15.0023599 7.87068966,14.9079646 7.96551724,14.6908555 C8.25,14.0112094 8.55344828,13.3315634 8.84741379,12.6519174 C8.89482759,12.5386431 8.9137931,12.4442478 8.97068966,12.2648968 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
<path d="M25.6413793,18.1551622 C24.712069,17.5887906 23.7922414,17.0318584 22.787069,16.4277286 C22.825,16.6070796 22.8060345,16.8147493 22.9008621,16.9185841 C23.0810345,17.1168142 23.2991379,17.2867257 23.5362069,17.4094395 C23.8586207,17.5887906 24.2,17.7115044 24.5318966,17.8719764 C25.0155172,18.1079646 25.3663793,18.4477876 25.3663793,19.0330383 C25.3663793,19.1274336 25.4137931,19.2218289 25.4517241,19.3256637 C25.5086207,19.2973451 25.5275862,19.2879056 25.5465517,19.2784661 C25.575,19.2501475 25.5939655,19.2218289 25.612931,19.1935103 C26.1818966,18.3533923 26.2198276,17.4283186 25.9732759,16.4843658 C25.6982759,15.4271386 25.2051724,14.5115044 24.1715517,13.9828909 C23.887069,13.8412979 23.7068966,13.9640118 23.4982759,14.1056047 C23.2801724,14.2566372 23.1568966,14.4359882 23.2137931,14.7569322 C23.3655172,14.6625369 23.4982759,14.5964602 23.5931034,14.5020649 C23.8301724,14.2566372 24.0482759,14.3132743 24.3137931,14.4831858 C25.3568966,15.2100295 26.0112069,17.0412979 25.6413793,18.1551622 Z" id="Shape" fill="#235EE1" fill-rule="nonzero"></path>
|
||||
<path d="M6.57155172,22.1103245 C6.60948276,22.1292035 6.64741379,22.1480826 6.68534483,22.1575221 C7.62413793,20.9870206 8.57241379,19.8165192 9.53017241,18.6176991 C9.38793103,18.5421829 9.30258621,18.4855457 9.20775862,18.4477876 C8.60086207,18.2023599 7.99396552,17.9758112 7.39655172,17.720944 C7.11206897,17.5982301 7.02672414,17.6831858 7.00775862,17.9758112 C6.93189655,18.7687316 6.83706897,19.5616519 6.75172414,20.3640118 C6.68534483,20.9492625 6.62844828,21.5345133 6.57155172,22.1103245 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
<path d="M12.687931,5.83657817 C12.137931,5.89321534 11.7775862,6.11976401 11.5689655,6.60117994 C11.4267241,6.95044248 11.2939655,7.29970501 11.1327586,7.63952802 C11.037931,7.83775811 11.0663793,7.96047198 11.2939655,8.0359882 C11.9293103,8.25309735 12.5646552,8.48908555 13.1905172,8.73451327 C13.4181034,8.81946903 13.512931,8.7439528 13.5982759,8.54572271 C13.7405172,8.18702065 13.9017241,7.82831858 14.0534483,7.46961652 C14.2525862,6.98820059 14.1672414,6.58230088 13.7310345,6.29911504 C13.4181034,6.10088496 13.0387931,5.98761062 12.687931,5.83657817 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
<path d="M23.8112069,12.3498525 C24.6077586,12.2460177 25.3948276,12.1421829 26.1724138,12.019469 C26.2387931,12.0100295 26.3241379,11.840118 26.3146552,11.7646018 C26.2198276,11.1415929 26.1060345,10.5091445 25.9732759,9.89557522 C25.9543103,9.80117994 25.7931034,9.66902655 25.6982759,9.66902655 C25.3,9.69734513 24.9017241,9.7539823 24.5034483,9.820059 C24.3043103,9.84837758 24.162069,9.94277286 24.2758621,10.2259587 C24.6362069,10.1787611 25.0060345,10.1221239 25.3758621,10.0938053 C25.4612069,10.0843658 25.6224138,10.159882 25.6318966,10.2165192 C25.7362069,10.6884956 25.812069,11.179351 25.9068966,11.679646 C25.2905172,11.7646018 24.712069,11.840118 24.1431034,11.9156342 C23.9344828,11.9439528 23.7448276,11.9911504 23.8112069,12.3498525 Z" id="Shape" fill="#235EE1" fill-rule="nonzero"></path>
|
||||
<path d="M19.9232759,13.0294985 C19.6198276,12.6707965 19.3258621,12.3309735 19.0318966,11.9722714 C16.9836207,9.50855457 14.9353448,7.05427729 12.887069,4.59056047 C12.3465517,3.94867257 12.375,3.25014749 12.9534483,2.74041298 C13.5508621,2.22123894 14.3568966,2.25899705 14.8784483,2.8820059 C16.2060345,4.4300885 17.5146552,6.00648968 18.8327586,7.5640118 C19.487069,8.3380531 20.1318966,9.12153392 20.7956897,9.89557522 C20.9474138,10.0749263 20.9853448,10.2353982 20.7672414,10.4525074 C20.3594828,9.97109145 19.9612069,9.50855457 19.5724138,9.0460177 C17.9413793,7.10147493 16.3008621,5.15693215 14.6698276,3.21238938 C14.3094828,2.78761062 13.9396552,2.66489676 13.512931,2.83480826 C13.1051724,2.99528024 12.8396552,3.36342183 12.9060345,3.76932153 C12.9344828,3.97699115 13.0482759,4.19410029 13.1905172,4.35457227 C14.85,6.35575221 16.5094828,8.34749263 18.1784483,10.3486726 C18.7663793,11.0566372 19.3543103,11.7646018 19.9517241,12.4725664 C20.1034483,12.6519174 20.1508621,12.8123894 19.9232759,13.0294985 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
<path d="M25.6413793,18.1551622 C26.0112069,17.0412979 25.3568966,15.2100295 24.3137931,14.5020649 C24.0577586,14.3227139 23.8396552,14.2755162 23.5931034,14.520944 C23.4982759,14.6153392 23.3655172,14.6719764 23.2137931,14.7758112 C23.1568966,14.4454277 23.2801724,14.2755162 23.4982759,14.1244838 C23.7068966,13.9734513 23.887069,13.860177 24.1715517,14.0017699 C25.2051724,14.5303835 25.6982759,15.4460177 25.9732759,16.5032448 C26.2198276,17.4471976 26.1818966,18.3722714 25.612931,19.2123894 C25.5939655,19.240708 25.575,19.2690265 25.5465517,19.2973451 C25.5275862,19.3162242 25.5086207,19.3162242 25.4517241,19.3445428 C25.4232759,19.240708 25.3663793,19.1463127 25.3663793,19.0519174 C25.3663793,18.4666667 25.0155172,18.1268437 24.5318966,17.8908555 C24.2,17.7303835 23.8491379,17.6076696 23.5362069,17.4283186 C23.2991379,17.2961652 23.0715517,17.1356932 22.9008621,16.9374631 C22.8060345,16.8336283 22.825,16.6259587 22.787069,16.4466077 C23.7922414,17.0318584 24.712069,17.5887906 25.6413793,18.1551622 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
<path d="M23.8112069,12.3498525 C23.7353448,11.9911504 23.9344828,11.9439528 24.1431034,11.9156342 C24.712069,11.840118 25.2810345,11.7646018 25.9068966,11.679646 C25.812069,11.179351 25.7362069,10.6979351 25.6318966,10.2165192 C25.6224138,10.159882 25.4612069,10.0843658 25.3758621,10.0938053 C25.0060345,10.1221239 24.6362069,10.1787611 24.2758621,10.2259587 C24.1715517,9.93333333 24.3137931,9.84837758 24.5034483,9.820059 C24.9017241,9.76342183 25.3,9.69734513 25.6982759,9.66902655 C25.7931034,9.65958702 25.9543103,9.80117994 25.9732759,9.89557522 C26.1060345,10.5185841 26.2198276,11.1415929 26.3146552,11.7646018 C26.3241379,11.840118 26.2293103,12.0100295 26.1724138,12.019469 C25.3948276,12.1421829 24.6172414,12.2365782 23.8112069,12.3498525 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
<path d="M24.3232759,13.3569322 C23.687931,13.1681416 23.0810345,12.9982301 22.4836207,12.8283186 C22.2655172,12.7622419 22.3034483,12.6300885 22.3508621,12.4696165 C22.7017241,11.2330383 23.0431034,9.99646018 23.4034483,8.76932153 C23.7448276,7.60825959 23.9724138,6.42831858 23.8681034,5.220059 C23.7922414,4.35162242 23.6689655,3.5020649 23.0905172,2.76578171 C22.55,2.07669617 21.8198276,1.80294985 21.0043103,1.69911504 C19.8,1.53864307 18.6051724,1.55752212 17.3439655,1.66135693 C17.4672414,1.55752212 17.5715517,1.43480826 17.7043103,1.34041298 C18.6241379,0.689085546 19.6862069,0.396460177 20.7767241,0.226548673 C23.0525862,-0.132153392 25.2525862,0.207669617 27.4051724,0.943952802 C28.1543103,1.19882006 28.7801724,1.63303835 29.3301724,2.18053097 C29.8517241,2.69970501 30.4396552,2.80353982 31.0844828,2.53923304 C31.4827586,2.36932153 31.8241379,2.4259587 32.2034483,2.55811209 C33.1137931,2.87905605 33.1137931,2.86961652 32.8387931,3.80412979 C32.5922414,4.62536873 32.3456897,5.44660767 32.1086207,6.27728614 C32.0327586,6.53215339 31.9284483,6.6359882 31.6534483,6.54159292 C31.4543103,6.4660767 31.2456897,6.40943953 31.037069,6.38112094 C30.5913793,6.31504425 30.2689655,6.0979351 30.0034483,5.72035398 C29.5767241,5.14454277 28.9318966,5.19174041 28.3155172,5.25781711 C27.3862069,5.36165192 26.7887931,5.8619469 26.437931,6.74926254 C25.6508621,8.72212389 25.0724138,10.7610619 24.5034483,12.8 C24.4465517,12.9699115 24.3896552,13.139823 24.3232759,13.3569322 Z" id="Shape" fill="#D2D2D2" fill-rule="nonzero"></path>
|
||||
<path d="M18.4913793,31.9150442 C17.1163793,31.9056047 16.2155172,31.0182891 16.262931,29.7250737 C16.2724138,29.5079646 16.3387931,29.2814159 16.4146552,29.0737463 C18.2068966,23.9858407 20.0086207,18.9073746 21.8103448,13.8289086 C22.0189655,13.2247788 21.8862069,13.2058997 22.6163793,13.4135693 C23.0146552,13.5268437 23.412931,13.6495575 23.8112069,13.7439528 C24.1051724,13.8100295 24.1810345,13.9327434 24.1051724,14.2348083 C23.7258621,15.7923304 23.375,17.3498525 23.0051724,18.9073746 C22.1043103,22.6548673 21.2034483,26.4117994 20.2931034,30.159292 C20.2077586,30.5085546 20.0655172,30.8578171 19.8853448,31.1693215 C19.5724138,31.6884956 19.0887931,31.9622419 18.4913793,31.9150442 Z" id="Shape" fill="#000000" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
23
deps/juce/extras/Projucer/Source/BinaryData/Icons/gpl_logo.svg
vendored
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
deps/juce/extras/Projucer/Source/BinaryData/Icons/juce_icon.png
vendored
Normal file
After Width: | Height: | Size: 103 KiB |
175
deps/juce/extras/Projucer/Source/BinaryData/Icons/wizard_AnimatedApp.svg
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 136.9 114.8"
|
||||
enable-background="new 0 0 136.9 114.8"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="wizard_AnimatedApp.svg"><metadata
|
||||
id="metadata50"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs48" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1001"
|
||||
id="namedview46"
|
||||
showgrid="false"
|
||||
inkscape:zoom="5.6568543"
|
||||
inkscape:cx="85.414924"
|
||||
inkscape:cy="49.441529"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" /><g
|
||||
id="Layer_1_18_"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><rect
|
||||
x="16.3"
|
||||
y="10.9"
|
||||
stroke-miterlimit="10"
|
||||
width="103.6"
|
||||
height="67.5"
|
||||
id="rect4"
|
||||
stroke-width="1.3469"
|
||||
stroke="#a45c94"
|
||||
fill="none"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><rect
|
||||
x="16.3"
|
||||
y="10.9"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
width="103.6"
|
||||
height="2.4"
|
||||
id="rect6"
|
||||
style="stroke:#a45c9f;stroke-opacity:0.94117647" /><circle
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
cx="80.3"
|
||||
cy="45"
|
||||
r="20.8"
|
||||
id="circle8"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><g
|
||||
id="g10"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><g
|
||||
id="g12"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><path
|
||||
stroke-miterlimit="10"
|
||||
d="M97.8,40.1c0.9,3.2,0,8-2.1,8.3 c-2,0.2-10.5-2.2-14.8-3.6c2.9-3.4,8.9-10,10.8-10.8C93.5,33.2,96.9,36.9,97.8,40.1z"
|
||||
id="path14"
|
||||
stroke-width="1.3469"
|
||||
stroke="#a45c94"
|
||||
fill="none"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><g
|
||||
id="g16"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><path
|
||||
stroke-miterlimit="10"
|
||||
d="M93.3,57.7c-2.3,2.4-7,4-8.2,2.4 c-1.2-1.6-3.4-10.2-4.3-14.6c4.4,0.8,13.1,2.8,14.7,4C97.2,50.5,95.6,55.3,93.3,57.7z"
|
||||
id="path18"
|
||||
stroke-width="1.3469"
|
||||
stroke="#a45c94"
|
||||
fill="none"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><g
|
||||
id="g20"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><path
|
||||
stroke-miterlimit="10"
|
||||
d="M75.7,62.6c-3.2-0.8-7-4.1-6.1-6 c0.8-1.9,7.2-8,10.5-11.1c1.5,4.3,4.1,12.7,3.9,14.8C83.9,62.4,79,63.4,75.7,62.6z"
|
||||
id="path22"
|
||||
stroke-width="1.3469"
|
||||
stroke="#a45c94"
|
||||
fill="none"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><g
|
||||
id="g24"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><path
|
||||
stroke-miterlimit="10"
|
||||
d="M62.9,49.9c-0.9-3.2,0-8,2.1-8.3 c2-0.2,10.5,2.2,14.8,3.6c-2.9,3.4-8.9,10-10.8,10.8C67.2,56.8,63.8,53.1,62.9,49.9z"
|
||||
id="path26"
|
||||
stroke-width="1.3469"
|
||||
stroke="#a45c94"
|
||||
fill="none"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><g
|
||||
id="g28"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><path
|
||||
stroke-miterlimit="10"
|
||||
d="M67.4,32.3c2.3-2.4,7-4,8.2-2.4 c1.2,1.6,3.4,10.2,4.3,14.6c-4.4-0.8-13.1-2.8-14.7-4C63.5,39.4,65.1,34.7,67.4,32.3z"
|
||||
id="path30"
|
||||
stroke-width="1.3469"
|
||||
stroke="#a45c94"
|
||||
fill="none"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><g
|
||||
id="g32"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><path
|
||||
stroke-miterlimit="10"
|
||||
d="M84.8,27.4c3.2,0.8,7,4.1,6.1,6 c-0.8,1.9-7.2,8-10.5,11.1c-1.5-4.3-4.1-12.7-3.9-14.8C76.7,27.6,81.6,26.6,84.8,27.4z"
|
||||
id="path34"
|
||||
stroke-width="1.3469"
|
||||
stroke="#a45c94"
|
||||
fill="none"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g></g><path
|
||||
stroke-miterlimit="10"
|
||||
d="M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z"
|
||||
id="path36"
|
||||
stroke-width="1.3469"
|
||||
stroke="#a45c94"
|
||||
fill="none"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
opacity="0.8"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M62.6,61.4 c-9.1-9.1-9.1-23.7,0-32.8"
|
||||
id="path38"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
opacity="0.5"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M55.9,57.3 c-4.7-7.4-4.7-16.9-0.1-24.4"
|
||||
id="path40"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
opacity="0.7"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
x1="57.7"
|
||||
y1="41.5"
|
||||
x2="37.8"
|
||||
y2="41.5"
|
||||
id="line42"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
opacity="0.7"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
x1="57.7"
|
||||
y1="48.4"
|
||||
x2="34.2"
|
||||
y2="48.4"
|
||||
id="line44"
|
||||
style="stroke:#a45c94;stroke-opacity:0.94117647" /></svg>
|
After Width: | Height: | Size: 5.8 KiB |
752
deps/juce/extras/Projucer/Source/BinaryData/Icons/wizard_AudioApp.svg
vendored
Normal file
@ -0,0 +1,752 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 136.9 114.8"
|
||||
enable-background="new 0 0 136.9 114.8"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="wizard_AudioApp.svg"><metadata
|
||||
id="metadata137"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs135" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1001"
|
||||
id="namedview133"
|
||||
showgrid="false"
|
||||
inkscape:zoom="4.1114981"
|
||||
inkscape:cx="45.83412"
|
||||
inkscape:cy="47.98031"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z"
|
||||
id="path3"
|
||||
style="fill:none;fill-opacity:1;stroke:#a45c94;stroke-opacity:1" /><rect
|
||||
x="16.5"
|
||||
y="10.9"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3412"
|
||||
stroke-miterlimit="10"
|
||||
width="102.7"
|
||||
height="2.4"
|
||||
id="rect5"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><rect
|
||||
x="16.5"
|
||||
y="10.9"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
width="102.9"
|
||||
height="67.5"
|
||||
id="rect7"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="17.1"
|
||||
y1="43.8"
|
||||
x2="17.1"
|
||||
y2="44.5"
|
||||
id="line9"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="18.8"
|
||||
y1="43.6"
|
||||
x2="18.8"
|
||||
y2="44.7"
|
||||
id="line11"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="20.4"
|
||||
y1="43.8"
|
||||
x2="20.4"
|
||||
y2="44.5"
|
||||
id="line13"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="22.1"
|
||||
y1="43.6"
|
||||
x2="22.1"
|
||||
y2="44.7"
|
||||
id="line15"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="23.8"
|
||||
y1="43.1"
|
||||
x2="23.8"
|
||||
y2="45.2"
|
||||
id="line17"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="25.4"
|
||||
y1="42.3"
|
||||
x2="25.4"
|
||||
y2="46"
|
||||
id="line19"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="27.1"
|
||||
y1="43.9"
|
||||
x2="27.1"
|
||||
y2="44.4"
|
||||
id="line21"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="28.8"
|
||||
y1="43.3"
|
||||
x2="28.8"
|
||||
y2="45"
|
||||
id="line23"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="30.4"
|
||||
y1="29.3"
|
||||
x2="30.4"
|
||||
y2="59"
|
||||
id="line25"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="32.1"
|
||||
y1="40.9"
|
||||
x2="32.1"
|
||||
y2="47.4"
|
||||
id="line27"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="33.8"
|
||||
y1="42.7"
|
||||
x2="33.8"
|
||||
y2="45.6"
|
||||
id="line29"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="35.4"
|
||||
y1="36.6"
|
||||
x2="35.4"
|
||||
y2="51.7"
|
||||
id="line31"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="37.1"
|
||||
y1="33.3"
|
||||
x2="37.1"
|
||||
y2="55.1"
|
||||
id="line33"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="38.8"
|
||||
y1="42.6"
|
||||
x2="38.8"
|
||||
y2="45.7"
|
||||
id="line35"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="40.4"
|
||||
y1="37.4"
|
||||
x2="40.4"
|
||||
y2="50.9"
|
||||
id="line37"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="42.1"
|
||||
y1="27.4"
|
||||
x2="42.1"
|
||||
y2="60.9"
|
||||
id="line39"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="43.8"
|
||||
y1="39.3"
|
||||
x2="43.8"
|
||||
y2="49"
|
||||
id="line41"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="45.4"
|
||||
y1="41.1"
|
||||
x2="45.4"
|
||||
y2="47.2"
|
||||
id="line43"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="47.1"
|
||||
y1="42.6"
|
||||
x2="47.1"
|
||||
y2="45.7"
|
||||
id="line45"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="48.8"
|
||||
y1="36.2"
|
||||
x2="48.8"
|
||||
y2="52.1"
|
||||
id="line47"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="50.4"
|
||||
y1="42.5"
|
||||
x2="50.4"
|
||||
y2="45.9"
|
||||
id="line49"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="52.1"
|
||||
y1="39.3"
|
||||
x2="52.1"
|
||||
y2="49"
|
||||
id="line51"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="53.8"
|
||||
y1="34.8"
|
||||
x2="53.8"
|
||||
y2="53.5"
|
||||
id="line53"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="55.4"
|
||||
y1="42.2"
|
||||
x2="55.4"
|
||||
y2="46.1"
|
||||
id="line55"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="57.1"
|
||||
y1="41"
|
||||
x2="57.1"
|
||||
y2="47.3"
|
||||
id="line57"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="58.8"
|
||||
y1="35.4"
|
||||
x2="58.8"
|
||||
y2="53"
|
||||
id="line59"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="60.4"
|
||||
y1="32.6"
|
||||
x2="60.4"
|
||||
y2="55.8"
|
||||
id="line61"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="62.1"
|
||||
y1="37.4"
|
||||
x2="62.1"
|
||||
y2="50.9"
|
||||
id="line63"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="63.8"
|
||||
y1="38.1"
|
||||
x2="63.8"
|
||||
y2="50.2"
|
||||
id="line65"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="65.4"
|
||||
y1="42.2"
|
||||
x2="65.4"
|
||||
y2="46.1"
|
||||
id="line67"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="67.1"
|
||||
y1="38.9"
|
||||
x2="67.1"
|
||||
y2="49.4"
|
||||
id="line69"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="68.8"
|
||||
y1="43.6"
|
||||
x2="68.8"
|
||||
y2="44.7"
|
||||
id="line71"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="70.4"
|
||||
y1="41.4"
|
||||
x2="70.4"
|
||||
y2="47"
|
||||
id="line73"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="72.1"
|
||||
y1="39"
|
||||
x2="72.1"
|
||||
y2="49.3"
|
||||
id="line75"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="73.8"
|
||||
y1="40.9"
|
||||
x2="73.8"
|
||||
y2="47.5"
|
||||
id="line77"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="75.4"
|
||||
y1="40.6"
|
||||
x2="75.4"
|
||||
y2="47.8"
|
||||
id="line79"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="77.1"
|
||||
y1="38.4"
|
||||
x2="77.1"
|
||||
y2="49.9"
|
||||
id="line81"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="78.8"
|
||||
y1="42"
|
||||
x2="78.8"
|
||||
y2="46.3"
|
||||
id="line83"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="80.4"
|
||||
y1="42.2"
|
||||
x2="80.4"
|
||||
y2="46.1"
|
||||
id="line85"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="82.1"
|
||||
y1="43.6"
|
||||
x2="82.1"
|
||||
y2="44.7"
|
||||
id="line87"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="83.8"
|
||||
y1="42.6"
|
||||
x2="83.8"
|
||||
y2="45.7"
|
||||
id="line89"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="85.4"
|
||||
y1="43.3"
|
||||
x2="85.4"
|
||||
y2="45"
|
||||
id="line91"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="87.1"
|
||||
y1="39.9"
|
||||
x2="87.1"
|
||||
y2="48.4"
|
||||
id="line93"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="88.8"
|
||||
y1="42.9"
|
||||
x2="88.8"
|
||||
y2="45.4"
|
||||
id="line95"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="90.4"
|
||||
y1="43.6"
|
||||
x2="90.4"
|
||||
y2="44.7"
|
||||
id="line97"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="92.1"
|
||||
y1="43.6"
|
||||
x2="92.1"
|
||||
y2="44.7"
|
||||
id="line99"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="93.8"
|
||||
y1="42.7"
|
||||
x2="93.8"
|
||||
y2="45.6"
|
||||
id="line101"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="95.4"
|
||||
y1="41.1"
|
||||
x2="95.4"
|
||||
y2="47.2"
|
||||
id="line103"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="97.1"
|
||||
y1="42.7"
|
||||
x2="97.1"
|
||||
y2="45.6"
|
||||
id="line105"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="98.8"
|
||||
y1="43.6"
|
||||
x2="98.8"
|
||||
y2="44.7"
|
||||
id="line107"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="100.4"
|
||||
y1="43.1"
|
||||
x2="100.4"
|
||||
y2="45.2"
|
||||
id="line109"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="102.1"
|
||||
y1="43.6"
|
||||
x2="102.1"
|
||||
y2="44.7"
|
||||
id="line111"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="103.8"
|
||||
y1="42"
|
||||
x2="103.8"
|
||||
y2="46.3"
|
||||
id="line113"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="105.4"
|
||||
y1="43.6"
|
||||
x2="105.4"
|
||||
y2="44.7"
|
||||
id="line115"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="107.1"
|
||||
y1="43.8"
|
||||
x2="107.1"
|
||||
y2="44.5"
|
||||
id="line117"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="108.8"
|
||||
y1="43.6"
|
||||
x2="108.8"
|
||||
y2="44.7"
|
||||
id="line119"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="110.4"
|
||||
y1="43.6"
|
||||
x2="110.4"
|
||||
y2="44.7"
|
||||
id="line121"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="112.1"
|
||||
y1="42.6"
|
||||
x2="112.1"
|
||||
y2="45.7"
|
||||
id="line123"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="113.8"
|
||||
y1="43.1"
|
||||
x2="113.8"
|
||||
y2="45.2"
|
||||
id="line125"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="115.4"
|
||||
y1="43.6"
|
||||
x2="115.4"
|
||||
y2="44.7"
|
||||
id="line127"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="117.1"
|
||||
y1="43.8"
|
||||
x2="117.1"
|
||||
y2="44.5"
|
||||
id="line129"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="118.8"
|
||||
y1="43.8"
|
||||
x2="118.8"
|
||||
y2="44.5"
|
||||
id="line131"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></svg>
|
After Width: | Height: | Size: 17 KiB |
854
deps/juce/extras/Projucer/Source/BinaryData/Icons/wizard_AudioPlugin.svg
vendored
Normal file
@ -0,0 +1,854 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 136.9 114.8"
|
||||
enable-background="new 0 0 136.9 114.8"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="wizard_AudioPlugin.svg"><metadata
|
||||
id="metadata181"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs179" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1001"
|
||||
id="namedview177"
|
||||
showgrid="false"
|
||||
inkscape:zoom="8.2229963"
|
||||
inkscape:cx="67.455426"
|
||||
inkscape:cy="64.924074"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" /><g
|
||||
id="Layer_1_23_"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><rect
|
||||
x="16.3"
|
||||
y="10.9"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
width="103.6"
|
||||
height="67.5"
|
||||
id="rect4"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><rect
|
||||
x="16.3"
|
||||
y="10.9"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
width="103.6"
|
||||
height="2.4"
|
||||
id="rect6"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z"
|
||||
id="path8"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><g
|
||||
id="Layer_1_8_"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><rect
|
||||
x="35.7"
|
||||
y="23.6"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
width="64.4"
|
||||
height="42.3"
|
||||
id="rect11"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="36"
|
||||
y1="44.1"
|
||||
x2="36"
|
||||
y2="44.6"
|
||||
id="line13"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="37.1"
|
||||
y1="44"
|
||||
x2="37.1"
|
||||
y2="44.7"
|
||||
id="line15"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="38.1"
|
||||
y1="44.1"
|
||||
x2="38.1"
|
||||
y2="44.6"
|
||||
id="line17"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="39.2"
|
||||
y1="44"
|
||||
x2="39.2"
|
||||
y2="44.7"
|
||||
id="line19"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="40.2"
|
||||
y1="43.7"
|
||||
x2="40.2"
|
||||
y2="45"
|
||||
id="line21"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="41.3"
|
||||
y1="43.2"
|
||||
x2="41.3"
|
||||
y2="45.5"
|
||||
id="line23"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="42.3"
|
||||
y1="44.2"
|
||||
x2="42.3"
|
||||
y2="44.5"
|
||||
id="line25"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="43.3"
|
||||
y1="43.8"
|
||||
x2="43.3"
|
||||
y2="44.9"
|
||||
id="line27"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="44.4"
|
||||
y1="35.1"
|
||||
x2="44.4"
|
||||
y2="53.6"
|
||||
id="line29"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="45.4"
|
||||
y1="42.3"
|
||||
x2="45.4"
|
||||
y2="46.4"
|
||||
id="line31"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="46.5"
|
||||
y1="43.4"
|
||||
x2="46.5"
|
||||
y2="45.3"
|
||||
id="line33"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="47.5"
|
||||
y1="39.6"
|
||||
x2="47.5"
|
||||
y2="49.1"
|
||||
id="line35"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="48.6"
|
||||
y1="37.5"
|
||||
x2="48.6"
|
||||
y2="51.2"
|
||||
id="line37"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="49.6"
|
||||
y1="43.4"
|
||||
x2="49.6"
|
||||
y2="45.3"
|
||||
id="line39"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="50.6"
|
||||
y1="40.1"
|
||||
x2="50.6"
|
||||
y2="48.6"
|
||||
id="line41"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="51.7"
|
||||
y1="33.9"
|
||||
x2="51.7"
|
||||
y2="54.9"
|
||||
id="line43"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="52.7"
|
||||
y1="41.3"
|
||||
x2="52.7"
|
||||
y2="47.4"
|
||||
id="line45"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="53.8"
|
||||
y1="42.5"
|
||||
x2="53.8"
|
||||
y2="46.3"
|
||||
id="line47"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="54.8"
|
||||
y1="43.4"
|
||||
x2="54.8"
|
||||
y2="45.3"
|
||||
id="line49"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="55.9"
|
||||
y1="39.4"
|
||||
x2="55.9"
|
||||
y2="49.3"
|
||||
id="line51"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="56.9"
|
||||
y1="43.3"
|
||||
x2="56.9"
|
||||
y2="45.4"
|
||||
id="line53"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="57.9"
|
||||
y1="41.3"
|
||||
x2="57.9"
|
||||
y2="47.4"
|
||||
id="line55"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="59"
|
||||
y1="38.5"
|
||||
x2="59"
|
||||
y2="50.2"
|
||||
id="line57"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="60"
|
||||
y1="43.1"
|
||||
x2="60"
|
||||
y2="45.6"
|
||||
id="line59"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="61.1"
|
||||
y1="42.4"
|
||||
x2="61.1"
|
||||
y2="46.3"
|
||||
id="line61"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="62.1"
|
||||
y1="38.8"
|
||||
x2="62.1"
|
||||
y2="49.9"
|
||||
id="line63"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="63.2"
|
||||
y1="37.1"
|
||||
x2="63.2"
|
||||
y2="51.6"
|
||||
id="line65"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="64.2"
|
||||
y1="40.1"
|
||||
x2="64.2"
|
||||
y2="48.6"
|
||||
id="line67"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="65.2"
|
||||
y1="40.6"
|
||||
x2="65.2"
|
||||
y2="48.1"
|
||||
id="line69"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="66.3"
|
||||
y1="43.1"
|
||||
x2="66.3"
|
||||
y2="45.6"
|
||||
id="line71"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="67.3"
|
||||
y1="41.1"
|
||||
x2="67.3"
|
||||
y2="47.6"
|
||||
id="line73"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="68.4"
|
||||
y1="44"
|
||||
x2="68.4"
|
||||
y2="44.7"
|
||||
id="line75"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="69.4"
|
||||
y1="42.6"
|
||||
x2="69.4"
|
||||
y2="46.1"
|
||||
id="line77"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="70.5"
|
||||
y1="41.1"
|
||||
x2="70.5"
|
||||
y2="47.6"
|
||||
id="line79"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="71.5"
|
||||
y1="42.3"
|
||||
x2="71.5"
|
||||
y2="46.4"
|
||||
id="line81"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="72.5"
|
||||
y1="42.1"
|
||||
x2="72.5"
|
||||
y2="46.6"
|
||||
id="line83"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="73.6"
|
||||
y1="40.8"
|
||||
x2="73.6"
|
||||
y2="47.9"
|
||||
id="line85"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="74.6"
|
||||
y1="43"
|
||||
x2="74.6"
|
||||
y2="45.7"
|
||||
id="line87"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="75.7"
|
||||
y1="43.1"
|
||||
x2="75.7"
|
||||
y2="45.6"
|
||||
id="line89"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="76.7"
|
||||
y1="44"
|
||||
x2="76.7"
|
||||
y2="44.7"
|
||||
id="line91"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="77.8"
|
||||
y1="43.4"
|
||||
x2="77.8"
|
||||
y2="45.3"
|
||||
id="line93"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="78.8"
|
||||
y1="43.8"
|
||||
x2="78.8"
|
||||
y2="44.9"
|
||||
id="line95"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="79.9"
|
||||
y1="41.7"
|
||||
x2="79.9"
|
||||
y2="47"
|
||||
id="line97"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="80.9"
|
||||
y1="43.6"
|
||||
x2="80.9"
|
||||
y2="45.2"
|
||||
id="line99"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="81.9"
|
||||
y1="44"
|
||||
x2="81.9"
|
||||
y2="44.7"
|
||||
id="line101"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="83"
|
||||
y1="44"
|
||||
x2="83"
|
||||
y2="44.7"
|
||||
id="line103"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="84"
|
||||
y1="43.4"
|
||||
x2="84"
|
||||
y2="45.3"
|
||||
id="line105"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="85.1"
|
||||
y1="42.5"
|
||||
x2="85.1"
|
||||
y2="46.3"
|
||||
id="line107"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="86.1"
|
||||
y1="43.5"
|
||||
x2="86.1"
|
||||
y2="45.2"
|
||||
id="line109"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="87.2"
|
||||
y1="44"
|
||||
x2="87.2"
|
||||
y2="44.7"
|
||||
id="line111"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="88.2"
|
||||
y1="43.7"
|
||||
x2="88.2"
|
||||
y2="45"
|
||||
id="line113"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="89.2"
|
||||
y1="44"
|
||||
x2="89.2"
|
||||
y2="44.7"
|
||||
id="line115"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="90.3"
|
||||
y1="43"
|
||||
x2="90.3"
|
||||
y2="45.7"
|
||||
id="line117"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="91.3"
|
||||
y1="44"
|
||||
x2="91.3"
|
||||
y2="44.7"
|
||||
id="line119"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="92.4"
|
||||
y1="44.2"
|
||||
x2="92.4"
|
||||
y2="44.6"
|
||||
id="line121"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="93.4"
|
||||
y1="44"
|
||||
x2="93.4"
|
||||
y2="44.7"
|
||||
id="line123"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="94.5"
|
||||
y1="44"
|
||||
x2="94.5"
|
||||
y2="44.7"
|
||||
id="line125"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="95.5"
|
||||
y1="43.4"
|
||||
x2="95.5"
|
||||
y2="45.3"
|
||||
id="line127"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="96.5"
|
||||
y1="43.7"
|
||||
x2="96.5"
|
||||
y2="45"
|
||||
id="line129"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="97.6"
|
||||
y1="44"
|
||||
x2="97.6"
|
||||
y2="44.7"
|
||||
id="line131"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="98.6"
|
||||
y1="44.2"
|
||||
x2="98.6"
|
||||
y2="44.6"
|
||||
id="line133"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
x1="99.7"
|
||||
y1="44.2"
|
||||
x2="99.7"
|
||||
y2="44.6"
|
||||
id="line135"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><g
|
||||
id="g137"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><g
|
||||
id="g139"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-miterlimit="10"
|
||||
x1="16.3"
|
||||
y1="35.1"
|
||||
x2="35.8"
|
||||
y2="35.1"
|
||||
id="line141"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /><g
|
||||
id="g143"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><circle
|
||||
fill="#a45c94"
|
||||
cx="35.7"
|
||||
cy="35.1"
|
||||
r="1.7"
|
||||
id="circle145"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /></g></g></g><g
|
||||
id="g147"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><g
|
||||
id="g149"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-miterlimit="10"
|
||||
x1="16.3"
|
||||
y1="54.4"
|
||||
x2="35.8"
|
||||
y2="54.4"
|
||||
id="line151"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /><g
|
||||
id="g153"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><circle
|
||||
fill="#a45c94"
|
||||
cx="35.7"
|
||||
cy="54.4"
|
||||
r="1.7"
|
||||
id="circle155"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /></g></g></g><g
|
||||
id="g157"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><g
|
||||
id="g159"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-miterlimit="10"
|
||||
x1="119.7"
|
||||
y1="54.4"
|
||||
x2="100.2"
|
||||
y2="54.4"
|
||||
id="line161"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /><g
|
||||
id="g163"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><circle
|
||||
fill="#a45c94"
|
||||
cx="100.3"
|
||||
cy="54.4"
|
||||
r="1.7"
|
||||
id="circle165"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /></g></g></g><g
|
||||
id="g167"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><g
|
||||
id="g169"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.5"
|
||||
stroke-miterlimit="10"
|
||||
x1="119.7"
|
||||
y1="35.1"
|
||||
x2="100.2"
|
||||
y2="35.1"
|
||||
id="line171"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /><g
|
||||
id="g173"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><circle
|
||||
fill="#a45c94"
|
||||
cx="100.3"
|
||||
cy="35.1"
|
||||
r="1.7"
|
||||
id="circle175"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /></g></g></g></svg>
|
After Width: | Height: | Size: 21 KiB |
85
deps/juce/extras/Projucer/Source/BinaryData/Icons/wizard_ConsoleApp.svg
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 136.9 114.8"
|
||||
enable-background="new 0 0 136.9 114.8"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="wizard_ConsoleApp.svg"><metadata
|
||||
id="metadata25"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs23" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1001"
|
||||
id="namedview21"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.0557491"
|
||||
inkscape:cx="68.449997"
|
||||
inkscape:cy="57.400002"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z"
|
||||
id="path3"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><g
|
||||
id="Layer_1_22_"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><rect
|
||||
x="16.3"
|
||||
y="10.9"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
width="102.9"
|
||||
height="67.5"
|
||||
id="rect6"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><g
|
||||
id="Layer_3_3_"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><g
|
||||
opacity="0.8"
|
||||
id="g9"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><path
|
||||
fill="#a45c94"
|
||||
d="M40.6,28.3l-14.4-6.6v-2.3l17.3,7.8v2.1l-17.3,7.8v-2.3L40.6,28.3z"
|
||||
id="path11"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /><path
|
||||
fill="#a45c94"
|
||||
d="M62,39.5v1.7H45v-1.7H62z"
|
||||
id="path13"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /></g><g
|
||||
id="g15"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1"><path
|
||||
fill="#a45c94"
|
||||
d="M40.6,28.3l-14.4-6.6v-2.3l17.3,7.8v2.1l-17.3,7.8v-2.3L40.6,28.3z"
|
||||
id="path17"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /><path
|
||||
fill="#a45c94"
|
||||
d="M62,39.5v1.7H45v-1.7H62z"
|
||||
id="path19"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /></g></g></svg>
|
After Width: | Height: | Size: 3.2 KiB |
269
deps/juce/extras/Projucer/Source/BinaryData/Icons/wizard_DLL.svg
vendored
Normal file
@ -0,0 +1,269 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 136.9 114.8"
|
||||
enable-background="new 0 0 136.9 114.8"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="wizard_DLL.svg"><metadata
|
||||
id="metadata60"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs58" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1001"
|
||||
id="namedview56"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.0557491"
|
||||
inkscape:cx="68.449997"
|
||||
inkscape:cy="57.400002"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M130,114.9H6.9c-3.8,0-6.9-3.1-6.9-6.9V7 c0-3.8,3.1-6.9,6.9-6.9H130c3.8,0,6.9,3.1,6.9,6.9V108C136.9,111.8,133.9,114.9,130,114.9z"
|
||||
id="path3"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><g
|
||||
id="Layer_1_19_"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><rect
|
||||
x="16.3"
|
||||
y="11"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
width="102.9"
|
||||
height="67.5"
|
||||
id="rect6"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><g
|
||||
id="g8"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="39.6"
|
||||
y1="25"
|
||||
x2="39.6"
|
||||
y2="62.3"
|
||||
id="line10"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="41.2"
|
||||
y1="25"
|
||||
x2="41.2"
|
||||
y2="62.3"
|
||||
id="line12"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="42.8"
|
||||
y1="25"
|
||||
x2="42.8"
|
||||
y2="62.3"
|
||||
id="line14"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="44.5"
|
||||
y1="25"
|
||||
x2="44.5"
|
||||
y2="62.3"
|
||||
id="line16"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="46.1"
|
||||
y1="25"
|
||||
x2="46.1"
|
||||
y2="62.3"
|
||||
id="line18"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="47.7"
|
||||
y1="25"
|
||||
x2="47.7"
|
||||
y2="62.3"
|
||||
id="line20"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.0853"
|
||||
stroke-miterlimit="10"
|
||||
d="M49.9,23.9v38.6c0,0.9-0.7,1.6-1.6,1.6H39 c-0.9,0-1.6-0.7-1.6-1.6V23.9"
|
||||
id="path22"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><g
|
||||
id="g24"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="54.8"
|
||||
y1="27.5"
|
||||
x2="67.4"
|
||||
y2="62.6"
|
||||
id="line26"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="56.3"
|
||||
y1="27"
|
||||
x2="69"
|
||||
y2="62"
|
||||
id="line28"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="57.8"
|
||||
y1="26.4"
|
||||
x2="70.5"
|
||||
y2="61.5"
|
||||
id="line30"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="59.4"
|
||||
y1="25.9"
|
||||
x2="72.1"
|
||||
y2="60.9"
|
||||
id="line32"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="60.9"
|
||||
y1="25.3"
|
||||
x2="73.6"
|
||||
y2="60.4"
|
||||
id="line34"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="62.4"
|
||||
y1="24.8"
|
||||
x2="75.1"
|
||||
y2="59.8"
|
||||
id="line36"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.0853"
|
||||
stroke-miterlimit="10"
|
||||
d="M64.1,23l13.1,36.3c0.3,0.8-0.1,1.7-0.9,2 l-8.8,3.2c-0.8,0.3-1.7-0.1-2-0.9L52.4,27.2"
|
||||
id="path38"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><g
|
||||
id="g40"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="72.5"
|
||||
y1="30.6"
|
||||
x2="93.5"
|
||||
y2="61.4"
|
||||
id="line42"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="73.8"
|
||||
y1="29.7"
|
||||
x2="94.9"
|
||||
y2="60.5"
|
||||
id="line44"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="75.2"
|
||||
y1="28.8"
|
||||
x2="96.2"
|
||||
y2="59.6"
|
||||
id="line46"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="76.5"
|
||||
y1="27.9"
|
||||
x2="97.6"
|
||||
y2="58.6"
|
||||
id="line48"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="77.9"
|
||||
y1="27"
|
||||
x2="98.9"
|
||||
y2="57.7"
|
||||
id="line50"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4307"
|
||||
stroke-miterlimit="10"
|
||||
x1="79.2"
|
||||
y1="26"
|
||||
x2="100.3"
|
||||
y2="56.8"
|
||||
id="line52"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.0853"
|
||||
stroke-miterlimit="10"
|
||||
d="M80.4,23.9l21.8,31.9c0.5,0.7,0.3,1.7-0.4,2.2 l-7.7,5.3c-0.7,0.5-1.7,0.3-2.2-0.4L70.1,31"
|
||||
id="path54"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></svg>
|
After Width: | Height: | Size: 7.3 KiB |
168
deps/juce/extras/Projucer/Source/BinaryData/Icons/wizard_GUI.svg
vendored
Normal file
@ -0,0 +1,168 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 136.9 114.8"
|
||||
enable-background="new 0 0 136.9 114.8"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="wizard_GUI.svg"><metadata
|
||||
id="metadata53"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs51" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1001"
|
||||
id="namedview49"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.0557491"
|
||||
inkscape:cx="68.449997"
|
||||
inkscape:cy="57.400002"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" /><rect
|
||||
x="16.3"
|
||||
y="10.9"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
width="103.6"
|
||||
height="67.5"
|
||||
id="rect3"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.7078"
|
||||
stroke-miterlimit="10"
|
||||
d="M55.2,62.5H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0 c0-0.5,0.3-0.9,0.7-0.9h31.8c0.4,0,0.7,0.4,0.7,0.9l0,0C55.9,62.1,55.5,62.5,55.2,62.5z"
|
||||
id="path5"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="#a45c94"
|
||||
d="M38.1,62.5H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0c0-0.5,0.3-0.9,0.7-0.9h14.7c0.4,0,0.7,0.4,0.7,0.9l0,0 C38.7,62.1,38.4,62.5,38.1,62.5z"
|
||||
id="path7"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.7078"
|
||||
stroke-miterlimit="10"
|
||||
d="M55.2,67.8H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0 c0-0.5,0.3-0.9,0.7-0.9h31.8c0.4,0,0.7,0.4,0.7,0.9l0,0C55.9,67.4,55.5,67.8,55.2,67.8z"
|
||||
id="path9"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="#a45c94"
|
||||
d="M44.2,67.8H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0c0-0.5,0.3-0.9,0.7-0.9h20.8c0.4,0,0.7,0.4,0.7,0.9l0,0 C44.8,67.4,44.6,67.8,44.2,67.8z"
|
||||
id="path11"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.7078"
|
||||
stroke-miterlimit="10"
|
||||
d="M55.2,73H23.4c-0.4,0-0.7-0.4-0.7-0.9l0,0 c0-0.5,0.3-0.9,0.7-0.9h31.8c0.4,0,0.7,0.4,0.7,0.9l0,0C55.9,72.6,55.5,73,55.2,73z"
|
||||
id="path13"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="#a45c94"
|
||||
d="M49.4,73h-26c-0.4,0-0.7-0.4-0.7-0.9l0,0c0-0.5,0.3-0.9,0.7-0.9h26c0.4,0,0.7,0.4,0.7,0.9l0,0 C50.1,72.6,49.8,73,49.4,73z"
|
||||
id="path15"
|
||||
style="stroke:#a45c94;stroke-opacity:1;fill:#a45c94;fill-opacity:1" /><rect
|
||||
x="16.3"
|
||||
y="10.9"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
width="103.6"
|
||||
height="2.4"
|
||||
id="rect17"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><circle
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
cx="69.3"
|
||||
cy="39.6"
|
||||
r="13.9"
|
||||
id="circle19"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><g
|
||||
id="g21"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><g
|
||||
id="g23"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.2523"
|
||||
stroke-miterlimit="10"
|
||||
d="M79.8,33.5c1.1,1.9,1.3,5.2,0,5.7 c-1.3,0.5-7.2,0.3-10.2,0.2c1.3-2.7,4.1-7.9,5.2-8.8C75.9,29.7,78.7,31.6,79.8,33.5z"
|
||||
id="path25"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><g
|
||||
id="g27"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.2523"
|
||||
stroke-miterlimit="10"
|
||||
d="M79.8,45.6c-1.1,1.9-3.8,3.7-4.9,2.9 c-1.1-0.9-3.9-6.1-5.2-8.8c3-0.2,8.9-0.4,10.2,0.1C81.2,40.4,80.9,43.7,79.8,45.6z"
|
||||
id="path29"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><g
|
||||
id="g31"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.2523"
|
||||
stroke-miterlimit="10"
|
||||
d="M69.3,51.7c-2.2,0-5.2-1.5-5-2.8 s3.3-6.4,5-8.9c1.7,2.5,4.8,7.5,5,8.9S71.5,51.7,69.3,51.7z"
|
||||
id="path33"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><g
|
||||
id="g35"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.2523"
|
||||
stroke-miterlimit="10"
|
||||
d="M58.9,45.6c-1.1-1.9-1.3-5.2,0-5.7 c1.3-0.5,7.2-0.3,10.2-0.2c-1.3,2.7-4.1,7.9-5.2,8.8C62.8,49.4,60,47.6,58.9,45.6z"
|
||||
id="path37"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><g
|
||||
id="g39"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.2523"
|
||||
stroke-miterlimit="10"
|
||||
d="M58.9,33.5c1.1-1.9,3.8-3.7,4.9-2.9 c1.1,0.9,3.9,6.1,5.2,8.8c-3,0.2-8.9,0.4-10.2-0.1C57.5,38.8,57.8,35.5,58.9,33.5z"
|
||||
id="path41"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><g
|
||||
id="g43"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.2523"
|
||||
stroke-miterlimit="10"
|
||||
d="M69.3,27.5c2.2,0,5.2,1.5,5,2.8 s-3.3,6.4-5,8.9c-1.7-2.5-4.8-7.5-5-8.9S67.1,27.5,69.3,27.5z"
|
||||
id="path45"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g></g><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z"
|
||||
id="path47"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></svg>
|
After Width: | Height: | Size: 6.4 KiB |
48
deps/juce/extras/Projucer/Source/BinaryData/Icons/wizard_Highlight.svg
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 136.9 114.8"
|
||||
enable-background="new 0 0 136.9 114.8"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="wizard_Highlight.svg"><metadata
|
||||
id="metadata9"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs7" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1001"
|
||||
id="namedview5"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.0557491"
|
||||
inkscape:cx="68.449997"
|
||||
inkscape:cy="57.400002"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" /><path
|
||||
opacity="0.2"
|
||||
fill="#a45c94"
|
||||
d="M130.1,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9C0,3.1,3.1,0,6.9,0h123.2c3.8,0,6.9,3.1,6.9,6.9 V108C136.9,111.8,133.9,114.8,130.1,114.8z"
|
||||
id="path3"
|
||||
style="fill:#a45c94;fill-opacity:1" /></svg>
|
After Width: | Height: | Size: 1.8 KiB |
126
deps/juce/extras/Projucer/Source/BinaryData/Icons/wizard_OpenGL.svg
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 136.9 114.8"
|
||||
enable-background="new 0 0 136.9 114.8"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="wizard_OpenGL.svg"><metadata
|
||||
id="metadata29"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs27" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1001"
|
||||
id="namedview25"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.0557491"
|
||||
inkscape:cx="-16.190683"
|
||||
inkscape:cy="57.400002"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" /><rect
|
||||
x="16.3"
|
||||
y="10.9"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
width="103.6"
|
||||
height="67.5"
|
||||
id="rect3"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><rect
|
||||
x="16.3"
|
||||
y="10.9"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
width="103.6"
|
||||
height="2.4"
|
||||
id="rect5"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M75.8,31.5c8.7,4.7,14.8,13.2,13.5,20 c-1.6,8.5-13.8,11.4-26.8,4.3S45.3,36.9,51.6,30.9C56.7,26.1,67.1,26.7,75.8,31.5z"
|
||||
id="path7"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M86.1,43.6c1,2.4,0.5,5.5-1.3,5 c-1.9-0.5-9.8-5-13.8-7.4c2.9-1.2,8.2-3.2,9.8-3.2C82.2,38.2,85.2,41.4,86.1,43.6z"
|
||||
id="path9"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M83,55.3c-2.3,1.3-7.3,1.2-8.6-0.7 c-1.2-1.9-2.9-9.5-3.5-12.9c4.2,2.1,12.2,6.3,13.8,7.7C86.3,50.7,85.2,54,83,55.3z"
|
||||
id="path11"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M63.6,53.5c-3.6-2-7.3-6.3-5.9-7.6 c1.3-1.2,9-3.5,12.5-4.4c1.2,3.5,3.4,11.2,3.1,13C73,56.3,67.3,55.5,63.6,53.5z"
|
||||
id="path13"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M51.9,38.3c-0.1-2.5,2-5.2,4.1-4.6 c2.1,0.6,9.9,5.1,13.9,7.5c-3.2,1.3-10.5,4.1-12.8,4.1C54.9,45.1,52,40.9,51.9,38.3z"
|
||||
id="path15"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M60,29.3c2.4-0.4,6.6,0.3,7.5,1.5 c0.9,1.2,2.1,6.8,2.6,9.9c-4.2-2.1-12.3-6.3-13.7-7.6C55,31.8,57.4,29.8,60,29.3z"
|
||||
id="path17"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M75.2,32.5c2.5,1.4,5.6,4.3,5,5 c-0.7,0.8-6.3,2.5-9.5,3.3c-1.1-3.2-2.7-8.9-2.4-9.9C68.6,30,72.6,31.1,75.2,32.5z"
|
||||
id="path19"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3.1,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z"
|
||||
id="path21"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M87.4,55.5c-6.6,10.4-20.4,14.6-30.8,8 s-13.4-19.6-6.9-30"
|
||||
id="path23"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></svg>
|
After Width: | Height: | Size: 4.4 KiB |
50
deps/juce/extras/Projucer/Source/BinaryData/Icons/wizard_Openfile.svg
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 177.9 114.8"
|
||||
enable-background="new 0 0 177.9 114.8"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="wizard_Openfile.svg"><metadata
|
||||
id="metadata9"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs7" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1001"
|
||||
id="namedview5"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.7425521"
|
||||
inkscape:cx="88.949997"
|
||||
inkscape:cy="57.400002"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M164.7,71.4H13.2c-3.8,0-6.9-3.1-6.9-6.9V43.6 c0-3.8,3.1-6.9,6.9-6.9h151.5c3.8,0,6.9,3.1,6.9,6.9v20.9C171.6,68.3,168.5,71.4,164.7,71.4z"
|
||||
id="path3"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></svg>
|
After Width: | Height: | Size: 1.8 KiB |
269
deps/juce/extras/Projucer/Source/BinaryData/Icons/wizard_StaticLibrary.svg
vendored
Normal file
@ -0,0 +1,269 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 136.9 114.8"
|
||||
enable-background="new 0 0 136.9 114.8"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="wizard_StaticLibrary.svg"><metadata
|
||||
id="metadata60"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs58" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1001"
|
||||
id="namedview56"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.0557491"
|
||||
inkscape:cx="68.449997"
|
||||
inkscape:cy="57.400002"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" /><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
d="M130,114.8H6.9c-3.8,0-6.9-3.1-6.9-6.9V6.9 C0,3,3.1,0,6.9,0H130c3.8,0,6.9,3.1,6.9,6.9v101.1C136.9,111.7,133.9,114.8,130,114.8z"
|
||||
id="path3"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><g
|
||||
id="Layer_1_21_"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><rect
|
||||
x="16.3"
|
||||
y="10.9"
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.3469"
|
||||
stroke-miterlimit="10"
|
||||
width="102.9"
|
||||
height="67.5"
|
||||
id="rect6"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><g
|
||||
id="g8"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="43.1"
|
||||
y1="22.1"
|
||||
x2="43.1"
|
||||
y2="64.9"
|
||||
id="line10"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="45"
|
||||
y1="22.1"
|
||||
x2="45"
|
||||
y2="64.9"
|
||||
id="line12"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="46.8"
|
||||
y1="22.1"
|
||||
x2="46.8"
|
||||
y2="64.9"
|
||||
id="line14"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="48.7"
|
||||
y1="22.1"
|
||||
x2="48.7"
|
||||
y2="64.9"
|
||||
id="line16"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="50.6"
|
||||
y1="22.1"
|
||||
x2="50.6"
|
||||
y2="64.9"
|
||||
id="line18"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="52.5"
|
||||
y1="22.1"
|
||||
x2="52.5"
|
||||
y2="64.9"
|
||||
id="line20"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.2453"
|
||||
stroke-miterlimit="10"
|
||||
d="M54.9,20.8v44.3c0,1-0.8,1.8-1.8,1.8H42.4 c-1,0-1.8-0.8-1.8-1.8V20.8"
|
||||
id="path22"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><g
|
||||
id="g24"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="64.5"
|
||||
y1="22.1"
|
||||
x2="64.5"
|
||||
y2="64.9"
|
||||
id="line26"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="66.4"
|
||||
y1="22.1"
|
||||
x2="66.4"
|
||||
y2="64.9"
|
||||
id="line28"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="68.3"
|
||||
y1="22.1"
|
||||
x2="68.3"
|
||||
y2="64.9"
|
||||
id="line30"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="70.1"
|
||||
y1="22.1"
|
||||
x2="70.1"
|
||||
y2="64.9"
|
||||
id="line32"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="72"
|
||||
y1="22.1"
|
||||
x2="72"
|
||||
y2="64.9"
|
||||
id="line34"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="73.9"
|
||||
y1="22.1"
|
||||
x2="73.9"
|
||||
y2="64.9"
|
||||
id="line36"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.2453"
|
||||
stroke-miterlimit="10"
|
||||
d="M76.4,20.8v44.3c0,1-0.8,1.8-1.8,1.8H63.8 c-1,0-1.8-0.8-1.8-1.8V20.8"
|
||||
id="path38"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><g
|
||||
id="g40"
|
||||
style="stroke:#a45c94;stroke-opacity:1"><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="85.9"
|
||||
y1="22.1"
|
||||
x2="85.9"
|
||||
y2="64.9"
|
||||
id="line42"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="87.8"
|
||||
y1="22.1"
|
||||
x2="87.8"
|
||||
y2="64.9"
|
||||
id="line44"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="89.7"
|
||||
y1="22.1"
|
||||
x2="89.7"
|
||||
y2="64.9"
|
||||
id="line46"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="91.6"
|
||||
y1="22.1"
|
||||
x2="91.6"
|
||||
y2="64.9"
|
||||
id="line48"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="93.4"
|
||||
y1="22.1"
|
||||
x2="93.4"
|
||||
y2="64.9"
|
||||
id="line50"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /><line
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="0.4942"
|
||||
stroke-miterlimit="10"
|
||||
x1="95.3"
|
||||
y1="22.1"
|
||||
x2="95.3"
|
||||
y2="64.9"
|
||||
id="line52"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></g><path
|
||||
fill="none"
|
||||
stroke="#a45c94"
|
||||
stroke-width="1.2453"
|
||||
stroke-miterlimit="10"
|
||||
d="M97.8,20.8v44.3c0,1-0.8,1.8-1.8,1.8H85.3 c-1,0-1.8-0.8-1.8-1.8V20.8"
|
||||
id="path54"
|
||||
style="stroke:#a45c94;stroke-opacity:1" /></svg>
|
After Width: | Height: | Size: 7.3 KiB |
56
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentSimpleTemplate.h
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
%%include_juce%%
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
This component lives inside our window, and this is where you should put all
|
||||
your controls and content.
|
||||
*/
|
||||
class %%content_component_class%% : public juce::AnimatedAppComponent
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
%%content_component_class%%()
|
||||
{
|
||||
// Make sure you set the size of the component after
|
||||
// you add any child components.
|
||||
setSize (800, 600);
|
||||
setFramesPerSecond (60); // This sets the frequency of the update calls.
|
||||
}
|
||||
|
||||
~%%content_component_class%%() override
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void update() override
|
||||
{
|
||||
// This function is called at the frequency specified by the setFramesPerSecond() call
|
||||
// in the constructor. You can use it to update counters, animate values, etc.
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void paint (juce::Graphics& g) override
|
||||
{
|
||||
// (Our component is opaque, so we must completely fill the background with a solid colour)
|
||||
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
|
||||
|
||||
// You can add your drawing code here!
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
// This is called when the MainContentComponent is resized.
|
||||
// If you add any child components, this is where you should
|
||||
// update their positions.
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
// Your private member variables go here...
|
||||
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)
|
||||
};
|
37
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.cpp
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
%%include_corresponding_header%%
|
||||
|
||||
//==============================================================================
|
||||
%%content_component_class%%::%%content_component_class%%()
|
||||
{
|
||||
// Make sure you set the size of the component after
|
||||
// you add any child components.
|
||||
setSize (800, 600);
|
||||
setFramesPerSecond (60); // This sets the frequency of the update calls.
|
||||
}
|
||||
|
||||
%%content_component_class%%::~%%content_component_class%%()
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void %%content_component_class%%::update()
|
||||
{
|
||||
// This function is called at the frequency specified by the setFramesPerSecond() call
|
||||
// in the constructor. You can use it to update counters, animate values, etc.
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void %%content_component_class%%::paint (juce::Graphics& g)
|
||||
{
|
||||
// (Our component is opaque, so we must completely fill the background with a solid colour)
|
||||
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
|
||||
|
||||
// You can add your drawing code here!
|
||||
}
|
||||
|
||||
void %%content_component_class%%::resized()
|
||||
{
|
||||
// This is called when the MainContentComponent is resized.
|
||||
// If you add any child components, this is where you should
|
||||
// update their positions.
|
||||
}
|
30
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_AnimatedComponentTemplate.h
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
%%include_juce%%
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
This component lives inside our window, and this is where you should put all
|
||||
your controls and content.
|
||||
*/
|
||||
class %%content_component_class%% : public juce::AnimatedAppComponent
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
%%content_component_class%%();
|
||||
~%%content_component_class%%() override;
|
||||
|
||||
//==============================================================================
|
||||
void update() override;
|
||||
|
||||
//==============================================================================
|
||||
void paint (juce::Graphics& g) override;
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
// Your private member variables go here...
|
||||
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)
|
||||
};
|
94
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentSimpleTemplate.h
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
#pragma once
|
||||
|
||||
%%include_juce%%
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
This component lives inside our window, and this is where you should put all
|
||||
your controls and content.
|
||||
*/
|
||||
class %%content_component_class%% : public juce::AudioAppComponent
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
%%content_component_class%%()
|
||||
{
|
||||
// Make sure you set the size of the component after
|
||||
// you add any child components.
|
||||
setSize (800, 600);
|
||||
|
||||
// Some platforms require permissions to open input channels so request that here
|
||||
if (juce::RuntimePermissions::isRequired (juce::RuntimePermissions::recordAudio)
|
||||
&& ! juce::RuntimePermissions::isGranted (juce::RuntimePermissions::recordAudio))
|
||||
{
|
||||
juce::RuntimePermissions::request (juce::RuntimePermissions::recordAudio,
|
||||
[&] (bool granted) { setAudioChannels (granted ? 2 : 0, 2); });
|
||||
}
|
||||
else
|
||||
{
|
||||
// Specify the number of input and output channels that we want to open
|
||||
setAudioChannels (2, 2);
|
||||
}
|
||||
}
|
||||
|
||||
~%%content_component_class%%() override
|
||||
{
|
||||
// This shuts down the audio device and clears the audio source.
|
||||
shutdownAudio();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override
|
||||
{
|
||||
// This function will be called when the audio device is started, or when
|
||||
// its settings (i.e. sample rate, block size, etc) are changed.
|
||||
|
||||
// You can use this function to initialise any resources you might need,
|
||||
// but be careful - it will be called on the audio thread, not the GUI thread.
|
||||
|
||||
// For more details, see the help for AudioProcessor::prepareToPlay()
|
||||
}
|
||||
|
||||
void getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill) override
|
||||
{
|
||||
// Your audio-processing code goes here!
|
||||
|
||||
// For more details, see the help for AudioProcessor::getNextAudioBlock()
|
||||
|
||||
// Right now we are not producing any data, in which case we need to clear the buffer
|
||||
// (to prevent the output of random noise)
|
||||
bufferToFill.clearActiveBufferRegion();
|
||||
}
|
||||
|
||||
void releaseResources() override
|
||||
{
|
||||
// This will be called when the audio device stops, or when it is being
|
||||
// restarted due to a setting change.
|
||||
|
||||
// For more details, see the help for AudioProcessor::releaseResources()
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void paint (juce::Graphics& g) override
|
||||
{
|
||||
// (Our component is opaque, so we must completely fill the background with a solid colour)
|
||||
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
|
||||
|
||||
// You can add your drawing code here!
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
// This is called when the MainContentComponent is resized.
|
||||
// If you add any child components, this is where you should
|
||||
// update their positions.
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
// Your private member variables go here...
|
||||
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)
|
||||
};
|
75
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentTemplate.cpp
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
%%include_corresponding_header%%
|
||||
|
||||
//==============================================================================
|
||||
%%content_component_class%%::%%content_component_class%%()
|
||||
{
|
||||
// Make sure you set the size of the component after
|
||||
// you add any child components.
|
||||
setSize (800, 600);
|
||||
|
||||
// Some platforms require permissions to open input channels so request that here
|
||||
if (juce::RuntimePermissions::isRequired (juce::RuntimePermissions::recordAudio)
|
||||
&& ! juce::RuntimePermissions::isGranted (juce::RuntimePermissions::recordAudio))
|
||||
{
|
||||
juce::RuntimePermissions::request (juce::RuntimePermissions::recordAudio,
|
||||
[&] (bool granted) { setAudioChannels (granted ? 2 : 0, 2); });
|
||||
}
|
||||
else
|
||||
{
|
||||
// Specify the number of input and output channels that we want to open
|
||||
setAudioChannels (2, 2);
|
||||
}
|
||||
}
|
||||
|
||||
%%content_component_class%%::~%%content_component_class%%()
|
||||
{
|
||||
// This shuts down the audio device and clears the audio source.
|
||||
shutdownAudio();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void %%content_component_class%%::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
|
||||
{
|
||||
// This function will be called when the audio device is started, or when
|
||||
// its settings (i.e. sample rate, block size, etc) are changed.
|
||||
|
||||
// You can use this function to initialise any resources you might need,
|
||||
// but be careful - it will be called on the audio thread, not the GUI thread.
|
||||
|
||||
// For more details, see the help for AudioProcessor::prepareToPlay()
|
||||
}
|
||||
|
||||
void %%content_component_class%%::getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill)
|
||||
{
|
||||
// Your audio-processing code goes here!
|
||||
|
||||
// For more details, see the help for AudioProcessor::getNextAudioBlock()
|
||||
|
||||
// Right now we are not producing any data, in which case we need to clear the buffer
|
||||
// (to prevent the output of random noise)
|
||||
bufferToFill.clearActiveBufferRegion();
|
||||
}
|
||||
|
||||
void %%content_component_class%%::releaseResources()
|
||||
{
|
||||
// This will be called when the audio device stops, or when it is being
|
||||
// restarted due to a setting change.
|
||||
|
||||
// For more details, see the help for AudioProcessor::releaseResources()
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void %%content_component_class%%::paint (juce::Graphics& g)
|
||||
{
|
||||
// (Our component is opaque, so we must completely fill the background with a solid colour)
|
||||
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
|
||||
|
||||
// You can add your drawing code here!
|
||||
}
|
||||
|
||||
void %%content_component_class%%::resized()
|
||||
{
|
||||
// This is called when the MainContentComponent is resized.
|
||||
// If you add any child components, this is where you should
|
||||
// update their positions.
|
||||
}
|
32
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_AudioComponentTemplate.h
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
%%include_juce%%
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
This component lives inside our window, and this is where you should put all
|
||||
your controls and content.
|
||||
*/
|
||||
class %%content_component_class%% : public juce::AudioAppComponent
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
%%content_component_class%%();
|
||||
~%%content_component_class%%() override;
|
||||
|
||||
//==============================================================================
|
||||
void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override;
|
||||
void getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill) override;
|
||||
void releaseResources() override;
|
||||
|
||||
//==============================================================================
|
||||
void paint (juce::Graphics& g) override;
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
// Your private member variables go here...
|
||||
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)
|
||||
};
|
39
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.cpp
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file contains the basic framework code for a JUCE plugin editor.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
%%editor_cpp_headers%%
|
||||
|
||||
//==============================================================================
|
||||
%%editor_class_name%%::%%editor_class_name%% (%%filter_class_name%%& p)
|
||||
: AudioProcessorEditor (&p), audioProcessor (p)
|
||||
{
|
||||
// Make sure that before the constructor has finished, you've set the
|
||||
// editor's size to whatever you need it to be.
|
||||
setSize (400, 300);
|
||||
}
|
||||
|
||||
%%editor_class_name%%::~%%editor_class_name%%()
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void %%editor_class_name%%::paint (juce::Graphics& g)
|
||||
{
|
||||
// (Our component is opaque, so we must completely fill the background with a solid colour)
|
||||
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
|
||||
|
||||
g.setColour (juce::Colours::white);
|
||||
g.setFont (15.0f);
|
||||
g.drawFittedText ("Hello World!", getLocalBounds(), juce::Justification::centred, 1);
|
||||
}
|
||||
|
||||
void %%editor_class_name%%::resized()
|
||||
{
|
||||
// This is generally where you'll want to lay out the positions of any
|
||||
// subcomponents in your editor..
|
||||
}
|
32
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginEditorTemplate.h
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file contains the basic framework code for a JUCE plugin editor.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
%%editor_headers%%
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
*/
|
||||
class %%editor_class_name%% : public juce::AudioProcessorEditor
|
||||
{
|
||||
public:
|
||||
%%editor_class_name%% (%%filter_class_name%%&);
|
||||
~%%editor_class_name%%() override;
|
||||
|
||||
//==============================================================================
|
||||
void paint (juce::Graphics&) override;
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
// This reference is provided as a quick way for your editor to
|
||||
// access the processor object that created it.
|
||||
%%filter_class_name%%& audioProcessor;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%editor_class_name%%)
|
||||
};
|
190
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.cpp
vendored
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file contains the basic framework code for a JUCE plugin processor.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
%%filter_headers%%
|
||||
|
||||
//==============================================================================
|
||||
%%filter_class_name%%::%%filter_class_name%%()
|
||||
#ifndef JucePlugin_PreferredChannelConfigurations
|
||||
: AudioProcessor (BusesProperties()
|
||||
#if ! JucePlugin_IsMidiEffect
|
||||
#if ! JucePlugin_IsSynth
|
||||
.withInput ("Input", juce::AudioChannelSet::stereo(), true)
|
||||
#endif
|
||||
.withOutput ("Output", juce::AudioChannelSet::stereo(), true)
|
||||
#endif
|
||||
)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
%%filter_class_name%%::~%%filter_class_name%%()
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
const juce::String %%filter_class_name%%::getName() const
|
||||
{
|
||||
return JucePlugin_Name;
|
||||
}
|
||||
|
||||
bool %%filter_class_name%%::acceptsMidi() const
|
||||
{
|
||||
#if JucePlugin_WantsMidiInput
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool %%filter_class_name%%::producesMidi() const
|
||||
{
|
||||
#if JucePlugin_ProducesMidiOutput
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool %%filter_class_name%%::isMidiEffect() const
|
||||
{
|
||||
#if JucePlugin_IsMidiEffect
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
double %%filter_class_name%%::getTailLengthSeconds() const
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
int %%filter_class_name%%::getNumPrograms()
|
||||
{
|
||||
return 1; // NB: some hosts don't cope very well if you tell them there are 0 programs,
|
||||
// so this should be at least 1, even if you're not really implementing programs.
|
||||
}
|
||||
|
||||
int %%filter_class_name%%::getCurrentProgram()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void %%filter_class_name%%::setCurrentProgram (int index)
|
||||
{
|
||||
}
|
||||
|
||||
const juce::String %%filter_class_name%%::getProgramName (int index)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
void %%filter_class_name%%::changeProgramName (int index, const juce::String& newName)
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void %%filter_class_name%%::prepareToPlay (double sampleRate, int samplesPerBlock)
|
||||
{
|
||||
// Use this method as the place to do any pre-playback
|
||||
// initialisation that you need..
|
||||
}
|
||||
|
||||
void %%filter_class_name%%::releaseResources()
|
||||
{
|
||||
// When playback stops, you can use this as an opportunity to free up any
|
||||
// spare memory, etc.
|
||||
}
|
||||
|
||||
#ifndef JucePlugin_PreferredChannelConfigurations
|
||||
bool %%filter_class_name%%::isBusesLayoutSupported (const BusesLayout& layouts) const
|
||||
{
|
||||
#if JucePlugin_IsMidiEffect
|
||||
juce::ignoreUnused (layouts);
|
||||
return true;
|
||||
#else
|
||||
// This is the place where you check if the layout is supported.
|
||||
// In this template code we only support mono or stereo.
|
||||
// Some plugin hosts, such as certain GarageBand versions, will only
|
||||
// load plugins that support stereo bus layouts.
|
||||
if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()
|
||||
&& layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())
|
||||
return false;
|
||||
|
||||
// This checks if the input layout matches the output layout
|
||||
#if ! JucePlugin_IsSynth
|
||||
if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void %%filter_class_name%%::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
|
||||
{
|
||||
juce::ScopedNoDenormals noDenormals;
|
||||
auto totalNumInputChannels = getTotalNumInputChannels();
|
||||
auto totalNumOutputChannels = getTotalNumOutputChannels();
|
||||
|
||||
// In case we have more outputs than inputs, this code clears any output
|
||||
// channels that didn't contain input data, (because these aren't
|
||||
// guaranteed to be empty - they may contain garbage).
|
||||
// This is here to avoid people getting screaming feedback
|
||||
// when they first compile a plugin, but obviously you don't need to keep
|
||||
// this code if your algorithm always overwrites all the output channels.
|
||||
for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
|
||||
buffer.clear (i, 0, buffer.getNumSamples());
|
||||
|
||||
// This is the place where you'd normally do the guts of your plugin's
|
||||
// audio processing...
|
||||
// Make sure to reset the state if your inner loop is processing
|
||||
// the samples and the outer loop is handling the channels.
|
||||
// Alternatively, you can process the samples with the channels
|
||||
// interleaved by keeping the same state.
|
||||
for (int channel = 0; channel < totalNumInputChannels; ++channel)
|
||||
{
|
||||
auto* channelData = buffer.getWritePointer (channel);
|
||||
|
||||
// ..do something to the data...
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool %%filter_class_name%%::hasEditor() const
|
||||
{
|
||||
return true; // (change this to false if you choose to not supply an editor)
|
||||
}
|
||||
|
||||
juce::AudioProcessorEditor* %%filter_class_name%%::createEditor()
|
||||
{
|
||||
return new %%editor_class_name%% (*this);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void %%filter_class_name%%::getStateInformation (juce::MemoryBlock& destData)
|
||||
{
|
||||
// You should use this method to store your parameters in the memory block.
|
||||
// You could do that either as raw data, or use the XML or ValueTree classes
|
||||
// as intermediaries to make it easy to save and load complex data.
|
||||
}
|
||||
|
||||
void %%filter_class_name%%::setStateInformation (const void* data, int sizeInBytes)
|
||||
{
|
||||
// You should use this method to restore your parameters from this memory block,
|
||||
// whose contents will have been created by the getStateInformation() call.
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// This creates new instances of the plugin..
|
||||
juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()
|
||||
{
|
||||
return new %%filter_class_name%%();
|
||||
}
|
59
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_AudioPluginFilterTemplate.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file contains the basic framework code for a JUCE plugin processor.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
%%app_headers%%
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
*/
|
||||
class %%filter_class_name%% : public juce::AudioProcessor
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
%%filter_class_name%%();
|
||||
~%%filter_class_name%%() override;
|
||||
|
||||
//==============================================================================
|
||||
void prepareToPlay (double sampleRate, int samplesPerBlock) override;
|
||||
void releaseResources() override;
|
||||
|
||||
#ifndef JucePlugin_PreferredChannelConfigurations
|
||||
bool isBusesLayoutSupported (const BusesLayout& layouts) const override;
|
||||
#endif
|
||||
|
||||
void processBlock (juce::AudioBuffer<float>&, juce::MidiBuffer&) override;
|
||||
|
||||
//==============================================================================
|
||||
juce::AudioProcessorEditor* createEditor() override;
|
||||
bool hasEditor() const override;
|
||||
|
||||
//==============================================================================
|
||||
const juce::String getName() const override;
|
||||
|
||||
bool acceptsMidi() const override;
|
||||
bool producesMidi() const override;
|
||||
bool isMidiEffect() const override;
|
||||
double getTailLengthSeconds() const override;
|
||||
|
||||
//==============================================================================
|
||||
int getNumPrograms() override;
|
||||
int getCurrentProgram() override;
|
||||
void setCurrentProgram (int index) override;
|
||||
const juce::String getProgramName (int index) override;
|
||||
void changeProgramName (int index, const juce::String& newName) override;
|
||||
|
||||
//==============================================================================
|
||||
void getStateInformation (juce::MemoryBlock& destData) override;
|
||||
void setStateInformation (const void* data, int sizeInBytes) override;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%filter_class_name%%)
|
||||
};
|
74
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_ComponentTemplate.cpp
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This is an automatically generated GUI class created by the Projucer!
|
||||
|
||||
Be careful when adding custom code to these files, as only the code within
|
||||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
|
||||
and re-saved.
|
||||
|
||||
Created with Projucer version: %%version%%
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The Projucer is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
//[Headers] You can add your own extra header files here...
|
||||
//[/Headers]
|
||||
|
||||
%%include_files_cpp%%
|
||||
|
||||
//[MiscUserDefs] You can add your own user definitions and misc code here...
|
||||
//[/MiscUserDefs]
|
||||
|
||||
//==============================================================================
|
||||
%%class_name%%::%%class_name%% (%%constructor_params%%)
|
||||
%%initialisers%%{
|
||||
//[Constructor_pre] You can add your own custom stuff here..
|
||||
//[/Constructor_pre]
|
||||
|
||||
%%constructor%%
|
||||
|
||||
//[Constructor] You can add your own custom stuff here..
|
||||
//[/Constructor]
|
||||
}
|
||||
|
||||
%%class_name%%::~%%class_name%%()
|
||||
{
|
||||
//[Destructor_pre]. You can add your own custom destruction code here..
|
||||
//[/Destructor_pre]
|
||||
|
||||
%%destructor%%
|
||||
|
||||
//[Destructor]. You can add your own custom destruction code here..
|
||||
//[/Destructor]
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
%%method_definitions%%
|
||||
|
||||
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
|
||||
//[/MiscUserCode]
|
||||
|
||||
|
||||
//==============================================================================
|
||||
#if 0
|
||||
/* -- Projucer information section --
|
||||
|
||||
This is where the Projucer stores the metadata that describe this GUI layout, so
|
||||
make changes in here at your peril!
|
||||
|
||||
BEGIN_JUCER_METADATA
|
||||
|
||||
%%metadata%%
|
||||
END_JUCER_METADATA
|
||||
*/
|
||||
#endif
|
||||
|
||||
%%static_member_definitions%%
|
||||
//[EndFile] You can add extra defines here...
|
||||
//[/EndFile]
|
61
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_ComponentTemplate.h
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This is an automatically generated GUI class created by the Projucer!
|
||||
|
||||
Be careful when adding custom code to these files, as only the code within
|
||||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
|
||||
and re-saved.
|
||||
|
||||
Created with Projucer version: %%version%%
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The Projucer is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//[Headers] -- You can add your own extra header files here --
|
||||
%%include_juce%%
|
||||
//[/Headers]
|
||||
|
||||
%%include_files_h%%
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
//[Comments]
|
||||
An auto-generated component, created by the Projucer.
|
||||
|
||||
Describe your class and how it works here!
|
||||
//[/Comments]
|
||||
*/
|
||||
%%class_declaration%%
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
%%class_name%% (%%constructor_params%%);
|
||||
~%%class_name%%() override;
|
||||
|
||||
//==============================================================================
|
||||
//[UserMethods] -- You can add your own custom methods in this section.
|
||||
//[/UserMethods]
|
||||
|
||||
%%public_member_declarations%%
|
||||
|
||||
private:
|
||||
//[UserVariables] -- You can add your own custom variables in this section.
|
||||
//[/UserVariables]
|
||||
|
||||
//==============================================================================
|
||||
%%private_member_declarations%%
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%class_name%%)
|
||||
};
|
||||
|
||||
//[EndFile] You can add extra defines here...
|
||||
//[/EndFile]
|
48
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompSimpleTemplate.h
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
%%include_juce%%
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
This component lives inside our window, and this is where you should put all
|
||||
your controls and content.
|
||||
*/
|
||||
class %%content_component_class%% : public juce::Component
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
%%content_component_class%%()
|
||||
{
|
||||
setSize (600, 400);
|
||||
}
|
||||
|
||||
~%%content_component_class%%() override
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void paint (juce::Graphics& g) override
|
||||
{
|
||||
// (Our component is opaque, so we must completely fill the background with a solid colour)
|
||||
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
|
||||
|
||||
g.setFont (juce::Font (16.0f));
|
||||
g.setColour (juce::Colours::white);
|
||||
g.drawText ("Hello World!", getLocalBounds(), juce::Justification::centred, true);
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
// This is called when the %%content_component_class%% is resized.
|
||||
// If you add any child components, this is where you should
|
||||
// update their positions.
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
// Your private member variables go here...
|
||||
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)
|
||||
};
|
29
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompTemplate.cpp
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
%%include_corresponding_header%%
|
||||
|
||||
//==============================================================================
|
||||
%%content_component_class%%::%%content_component_class%%()
|
||||
{
|
||||
setSize (600, 400);
|
||||
}
|
||||
|
||||
%%content_component_class%%::~%%content_component_class%%()
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void %%content_component_class%%::paint (juce::Graphics& g)
|
||||
{
|
||||
// (Our component is opaque, so we must completely fill the background with a solid colour)
|
||||
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
|
||||
|
||||
g.setFont (juce::Font (16.0f));
|
||||
g.setColour (juce::Colours::white);
|
||||
g.drawText ("Hello World!", getLocalBounds(), juce::Justification::centred, true);
|
||||
}
|
||||
|
||||
void %%content_component_class%%::resized()
|
||||
{
|
||||
// This is called when the %%content_component_class%% is resized.
|
||||
// If you add any child components, this is where you should
|
||||
// update their positions.
|
||||
}
|
27
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_ContentCompTemplate.h
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
%%include_juce%%
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
This component lives inside our window, and this is where you should put all
|
||||
your controls and content.
|
||||
*/
|
||||
class %%content_component_class%% : public juce::Component
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
%%content_component_class%%();
|
||||
~%%content_component_class%%() override;
|
||||
|
||||
//==============================================================================
|
||||
void paint (juce::Graphics&) override;
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
// Your private member variables go here...
|
||||
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)
|
||||
};
|
40
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_InlineComponentTemplate.h
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
//==============================================================================
|
||||
class %%component_class%% : public juce::Component
|
||||
{
|
||||
public:
|
||||
%%component_class%%()
|
||||
{
|
||||
// In your constructor, you should add any child components, and
|
||||
// initialise any special settings that your component needs.
|
||||
|
||||
}
|
||||
|
||||
~%%component_class%%() override
|
||||
{
|
||||
}
|
||||
|
||||
void paint (juce::Graphics& g) override
|
||||
{
|
||||
// You should replace everything in this method with your own drawing code..
|
||||
|
||||
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // clear the background
|
||||
|
||||
g.setColour (juce::Colours::grey);
|
||||
g.drawRect (getLocalBounds(), 1); // draw an outline around the component
|
||||
|
||||
g.setColour (juce::Colours::white);
|
||||
g.setFont (14.0f);
|
||||
g.drawText ("%%component_class%%", getLocalBounds(),
|
||||
juce::Justification::centred, true); // draw some placeholder text
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
// This method is where you should set the bounds of any child
|
||||
// components that your component contains..
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%component_class%%)
|
||||
};
|
19
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_MainConsoleAppTemplate.cpp
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file contains the basic startup code for a JUCE application.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
%%app_headers%%
|
||||
|
||||
//==============================================================================
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
|
||||
// ..your code goes here!
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
51
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_NoWindow.cpp
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file contains the basic startup code for a JUCE application.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
%%app_headers%%
|
||||
|
||||
//==============================================================================
|
||||
class %%app_class_name%% : public juce::JUCEApplication
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
%%app_class_name%%() {}
|
||||
|
||||
const juce::String getApplicationName() override { return ProjectInfo::projectName; }
|
||||
const juce::String getApplicationVersion() override { return ProjectInfo::versionString; }
|
||||
bool moreThanOneInstanceAllowed() override { return true; }
|
||||
|
||||
//==============================================================================
|
||||
void initialise (const juce::String& commandLine) override
|
||||
{
|
||||
// Add your application's initialisation code here..
|
||||
}
|
||||
|
||||
void shutdown() override
|
||||
{
|
||||
// Add your application's shutdown code here..
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void systemRequestedQuit() override
|
||||
{
|
||||
// This is called when the app is being asked to quit: you can ignore this
|
||||
// request and let the app carry on running, or call quit() to allow the app to close.
|
||||
quit();
|
||||
}
|
||||
|
||||
void anotherInstanceStarted (const juce::String& commandLine) override
|
||||
{
|
||||
// When another instance of the app is launched while this one is running,
|
||||
// this method is invoked, and the commandLine parameter tells you what
|
||||
// the other instance's command-line arguments were.
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// This macro generates the main() routine that launches the app.
|
||||
START_JUCE_APPLICATION (%%app_class_name%%)
|
104
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_MainTemplate_Window.cpp
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file contains the basic startup code for a JUCE application.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
%%app_headers%%
|
||||
|
||||
//==============================================================================
|
||||
class %%app_class_name%% : public juce::JUCEApplication
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
%%app_class_name%%() {}
|
||||
|
||||
const juce::String getApplicationName() override { return ProjectInfo::projectName; }
|
||||
const juce::String getApplicationVersion() override { return ProjectInfo::versionString; }
|
||||
bool moreThanOneInstanceAllowed() override { return true; }
|
||||
|
||||
//==============================================================================
|
||||
void initialise (const juce::String& commandLine) override
|
||||
{
|
||||
// This method is where you should put your application's initialisation code..
|
||||
|
||||
mainWindow.reset (new MainWindow (getApplicationName()));
|
||||
}
|
||||
|
||||
void shutdown() override
|
||||
{
|
||||
// Add your application's shutdown code here..
|
||||
|
||||
mainWindow = nullptr; // (deletes our window)
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void systemRequestedQuit() override
|
||||
{
|
||||
// This is called when the app is being asked to quit: you can ignore this
|
||||
// request and let the app carry on running, or call quit() to allow the app to close.
|
||||
quit();
|
||||
}
|
||||
|
||||
void anotherInstanceStarted (const juce::String& commandLine) override
|
||||
{
|
||||
// When another instance of the app is launched while this one is running,
|
||||
// this method is invoked, and the commandLine parameter tells you what
|
||||
// the other instance's command-line arguments were.
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
This class implements the desktop window that contains an instance of
|
||||
our %%content_component_class%% class.
|
||||
*/
|
||||
class MainWindow : public juce::DocumentWindow
|
||||
{
|
||||
public:
|
||||
MainWindow (juce::String name)
|
||||
: DocumentWindow (name,
|
||||
juce::Desktop::getInstance().getDefaultLookAndFeel()
|
||||
.findColour (juce::ResizableWindow::backgroundColourId),
|
||||
DocumentWindow::allButtons)
|
||||
{
|
||||
setUsingNativeTitleBar (true);
|
||||
setContentOwned (new %%content_component_class%%(), true);
|
||||
|
||||
#if JUCE_IOS || JUCE_ANDROID
|
||||
setFullScreen (true);
|
||||
#else
|
||||
setResizable (true, true);
|
||||
centreWithSize (getWidth(), getHeight());
|
||||
#endif
|
||||
|
||||
setVisible (true);
|
||||
}
|
||||
|
||||
void closeButtonPressed() override
|
||||
{
|
||||
// This is called when the user tries to close this window. Here, we'll just
|
||||
// ask the app to quit when this happens, but you can change this to do
|
||||
// whatever you need.
|
||||
JUCEApplication::getInstance()->systemRequestedQuit();
|
||||
}
|
||||
|
||||
/* Note: Be careful if you override any DocumentWindow methods - the base
|
||||
class uses a lot of them, so by overriding you might break its functionality.
|
||||
It's best to do all your work in your content component instead, but if
|
||||
you really have to override any DocumentWindow methods, make sure your
|
||||
subclass also calls the superclass's method.
|
||||
*/
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)
|
||||
};
|
||||
|
||||
private:
|
||||
std::unique_ptr<MainWindow> mainWindow;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// This macro generates the main() routine that launches the app.
|
||||
START_JUCE_APPLICATION (%%app_class_name%%)
|
51
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_NewComponentTemplate.cpp
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
%%filename%%
|
||||
Created: %%date%%
|
||||
Author: %%author%%
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
%%include_juce%%
|
||||
%%include_corresponding_header%%
|
||||
|
||||
//==============================================================================
|
||||
%%component_class%%::%%component_class%%()
|
||||
{
|
||||
// In your constructor, you should add any child components, and
|
||||
// initialise any special settings that your component needs.
|
||||
|
||||
}
|
||||
|
||||
%%component_class%%::~%%component_class%%()
|
||||
{
|
||||
}
|
||||
|
||||
void %%component_class%%::paint (juce::Graphics& g)
|
||||
{
|
||||
/* This demo code just fills the component's background and
|
||||
draws some placeholder text to get you started.
|
||||
|
||||
You should replace everything in this method with your own
|
||||
drawing code..
|
||||
*/
|
||||
|
||||
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // clear the background
|
||||
|
||||
g.setColour (juce::Colours::grey);
|
||||
g.drawRect (getLocalBounds(), 1); // draw an outline around the component
|
||||
|
||||
g.setColour (juce::Colours::white);
|
||||
g.setFont (14.0f);
|
||||
g.drawText ("%%component_class%%", getLocalBounds(),
|
||||
juce::Justification::centred, true); // draw some placeholder text
|
||||
}
|
||||
|
||||
void %%component_class%%::resized()
|
||||
{
|
||||
// This method is where you should set the bounds of any child
|
||||
// components that your component contains..
|
||||
|
||||
}
|
29
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_NewComponentTemplate.h
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
%%filename%%
|
||||
Created: %%date%%
|
||||
Author: %%author%%
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
%%include_juce%%
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
*/
|
||||
class %%component_class%% : public juce::Component
|
||||
{
|
||||
public:
|
||||
%%component_class%%();
|
||||
~%%component_class%%() override;
|
||||
|
||||
void paint (juce::Graphics&) override;
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%component_class%%)
|
||||
};
|
11
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_NewCppFileTemplate.cpp
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
%%filename%%
|
||||
Created: %%date%%
|
||||
Author: %%author%%
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
%%include_corresponding_header%%
|
11
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_NewCppFileTemplate.h
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
%%filename%%
|
||||
Created: %%date%%
|
||||
Author: %%author%%
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
61
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_NewInlineComponentTemplate.h
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
%%filename%%
|
||||
Created: %%date%%
|
||||
Author: %%author%%
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
%%include_juce%%
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
*/
|
||||
class %%component_class%% : public juce::Component
|
||||
{
|
||||
public:
|
||||
%%component_class%%()
|
||||
{
|
||||
// In your constructor, you should add any child components, and
|
||||
// initialise any special settings that your component needs.
|
||||
|
||||
}
|
||||
|
||||
~%%component_class%%() override
|
||||
{
|
||||
}
|
||||
|
||||
void paint (juce::Graphics& g) override
|
||||
{
|
||||
/* This demo code just fills the component's background and
|
||||
draws some placeholder text to get you started.
|
||||
|
||||
You should replace everything in this method with your own
|
||||
drawing code..
|
||||
*/
|
||||
|
||||
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // clear the background
|
||||
|
||||
g.setColour (juce::Colours::grey);
|
||||
g.drawRect (getLocalBounds(), 1); // draw an outline around the component
|
||||
|
||||
g.setColour (juce::Colours::white);
|
||||
g.setFont (14.0f);
|
||||
g.drawText ("%%component_class%%", getLocalBounds(),
|
||||
juce::Justification::centred, true); // draw some placeholder text
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
// This method is where you should set the bounds of any child
|
||||
// components that your component contains..
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%component_class%%)
|
||||
};
|
67
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentSimpleTemplate.h
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
%%include_juce%%
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
This component lives inside our window, and this is where you should put all
|
||||
your controls and content.
|
||||
*/
|
||||
class %%content_component_class%% : public juce::OpenGLAppComponent
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
%%content_component_class%%()
|
||||
{
|
||||
// Make sure you set the size of the component after
|
||||
// you add any child components.
|
||||
setSize (800, 600);
|
||||
}
|
||||
|
||||
~%%content_component_class%%() override
|
||||
{
|
||||
// This shuts down the GL system and stops the rendering calls.
|
||||
shutdownOpenGL();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void initialise() override
|
||||
{
|
||||
// Initialise GL objects for rendering here.
|
||||
}
|
||||
|
||||
void shutdown() override
|
||||
{
|
||||
// Free any GL objects created for rendering here.
|
||||
}
|
||||
|
||||
void render() override
|
||||
{
|
||||
// This clears the context with a black background.
|
||||
juce::OpenGLHelpers::clear (Colours::black);
|
||||
|
||||
// Add your rendering code here...
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void paint (juce::Graphics& g) override
|
||||
{
|
||||
// You can add your component specific drawing code here!
|
||||
// This will draw over the top of the openGL background.
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
// This is called when the MainContentComponent is resized.
|
||||
// If you add any child components, this is where you should
|
||||
// update their positions.
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
// Your private member variables go here...
|
||||
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)
|
||||
};
|
48
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.cpp
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
%%include_corresponding_header%%
|
||||
|
||||
//==============================================================================
|
||||
%%content_component_class%%::%%content_component_class%%()
|
||||
{
|
||||
// Make sure you set the size of the component after
|
||||
// you add any child components.
|
||||
setSize (800, 600);
|
||||
}
|
||||
|
||||
%%content_component_class%%::~%%content_component_class%%()
|
||||
{
|
||||
// This shuts down the GL system and stops the rendering calls.
|
||||
shutdownOpenGL();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void %%content_component_class%%::initialise()
|
||||
{
|
||||
// Initialise GL objects for rendering here.
|
||||
}
|
||||
|
||||
void %%content_component_class%%::shutdown()
|
||||
{
|
||||
// Free any GL objects created for rendering here.
|
||||
}
|
||||
|
||||
void %%content_component_class%%::render()
|
||||
{
|
||||
// This clears the context with a black background.
|
||||
juce::OpenGLHelpers::clear (juce::Colours::black);
|
||||
|
||||
// Add your rendering code here...
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void %%content_component_class%%::paint (juce::Graphics& g)
|
||||
{
|
||||
// You can add your component specific drawing code here!
|
||||
// This will draw over the top of the openGL background.
|
||||
}
|
||||
|
||||
void %%content_component_class%%::resized()
|
||||
{
|
||||
// This is called when the %%content_component_class%% is resized.
|
||||
// If you add any child components, this is where you should
|
||||
// update their positions.
|
||||
}
|
32
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_OpenGLComponentTemplate.h
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
%%include_juce%%
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
This component lives inside our window, and this is where you should put all
|
||||
your controls and content.
|
||||
*/
|
||||
class %%content_component_class%% : public juce::OpenGLAppComponent
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
%%content_component_class%%();
|
||||
~%%content_component_class%%() override;
|
||||
|
||||
//==============================================================================
|
||||
void initialise() override;
|
||||
void shutdown() override;
|
||||
void render() override;
|
||||
|
||||
//==============================================================================
|
||||
void paint (juce::Graphics& g) override;
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
// Your private member variables go here...
|
||||
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%content_component_class%%)
|
||||
};
|
107
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_PIPAudioProcessorTemplate.h
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
class %%class_name%% : public juce::AudioProcessor
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
%%class_name%%()
|
||||
: AudioProcessor (BusesProperties().withInput ("Input", juce::AudioChannelSet::stereo())
|
||||
.withOutput ("Output", juce::AudioChannelSet::stereo()))
|
||||
{
|
||||
}
|
||||
|
||||
~%%class_name%%() override
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void prepareToPlay (double, int) override
|
||||
{
|
||||
// Use this method as the place to do any pre-playback
|
||||
// initialisation that you need..
|
||||
}
|
||||
|
||||
void releaseResources() override
|
||||
{
|
||||
// When playback stops, you can use this as an opportunity to free up any
|
||||
// spare memory, etc.
|
||||
}
|
||||
|
||||
void processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer&) override
|
||||
{
|
||||
juce::ScopedNoDenormals noDenormals;
|
||||
auto totalNumInputChannels = getTotalNumInputChannels();
|
||||
auto totalNumOutputChannels = getTotalNumOutputChannels();
|
||||
|
||||
// In case we have more outputs than inputs, this code clears any output
|
||||
// channels that didn't contain input data, (because these aren't
|
||||
// guaranteed to be empty - they may contain garbage).
|
||||
// This is here to avoid people getting screaming feedback
|
||||
// when they first compile a plugin, but obviously you don't need to keep
|
||||
// this code if your algorithm always overwrites all the output channels.
|
||||
for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
|
||||
buffer.clear (i, 0, buffer.getNumSamples());
|
||||
|
||||
// This is the place where you'd normally do the guts of your plugin's
|
||||
// audio processing...
|
||||
// Make sure to reset the state if your inner loop is processing
|
||||
// the samples and the outer loop is handling the channels.
|
||||
// Alternatively, you can process the samples with the channels
|
||||
// interleaved by keeping the same state.
|
||||
for (int channel = 0; channel < totalNumInputChannels; ++channel)
|
||||
{
|
||||
auto* channelData = buffer.getWritePointer (channel);
|
||||
|
||||
// ..do something to the data...
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
juce::AudioProcessorEditor* createEditor() override { return nullptr; }
|
||||
bool hasEditor() const override { return false; }
|
||||
|
||||
//==============================================================================
|
||||
const juce::String getName() const override { return "%%name%%"; }
|
||||
bool acceptsMidi() const override { return false; }
|
||||
bool producesMidi() const override { return false; }
|
||||
double getTailLengthSeconds() const override { return 0; }
|
||||
|
||||
//==============================================================================
|
||||
int getNumPrograms() override { return 1; }
|
||||
int getCurrentProgram() override { return 0; }
|
||||
void setCurrentProgram (int) override {}
|
||||
const juce::String getProgramName (int) override { return {}; }
|
||||
void changeProgramName (int, const juce::String&) override {}
|
||||
|
||||
//==============================================================================
|
||||
void getStateInformation (juce::MemoryBlock& destData) override
|
||||
{
|
||||
// You should use this method to store your parameters in the memory block.
|
||||
// You could do that either as raw data, or use the XML or ValueTree classes
|
||||
// as intermediaries to make it easy to save and load complex data.
|
||||
}
|
||||
|
||||
void setStateInformation (const void* data, int sizeInBytes) override
|
||||
{
|
||||
// You should use this method to restore your parameters from this memory block,
|
||||
// whose contents will have been created by the getStateInformation() call.
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool isBusesLayoutSupported (const BusesLayout& layouts) const override
|
||||
{
|
||||
// This is the place where you check if the layout is supported.
|
||||
// In this template code we only support mono or stereo.
|
||||
if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()
|
||||
&& layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())
|
||||
return false;
|
||||
|
||||
// This checks if the input layout matches the output layout
|
||||
if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%class_name%%)
|
||||
};
|
17
deps/juce/extras/Projucer/Source/BinaryData/Templates/jucer_PIPTemplate.h
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
/*******************************************************************************
|
||||
The block below describes the properties of this PIP. A PIP is a short snippet
|
||||
of code that can be read by the Projucer and used to generate a JUCE project.
|
||||
|
||||
BEGIN_JUCE_PIP_METADATA
|
||||
|
||||
%%pip_metadata%%
|
||||
|
||||
END_JUCE_PIP_METADATA
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
%%pip_code%%
|
23
deps/juce/extras/Projucer/Source/BinaryData/colourscheme_dark.xml
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<COLOUR_SCHEME font="<Monospaced>; 13.0">
|
||||
<COLOUR name="Main Window Bkgd" colour="FF29292A"/>
|
||||
<COLOUR name="Treeview Highlight" colour="2BFFFEC3"/>
|
||||
<COLOUR name="Code Background" colour="FF222222"/>
|
||||
<COLOUR name="Line Number Bkgd" colour="44C1C1C1"/>
|
||||
<COLOUR name="Line Numbers" colour="E9B2B2B2"/>
|
||||
<COLOUR name="Plain Text" colour="FFCECECE"/>
|
||||
<COLOUR name="Selected Text Bkgd" colour="FF2859AC"/>
|
||||
<COLOUR name="Caret" colour="FFFFFFFF"/>
|
||||
<COLOUR name="Preprocessor Text" colour="FFF8F631"/>
|
||||
<COLOUR name="Punctuation" colour="FFCFBEFF"/>
|
||||
<COLOUR name="Bracket" colour="FF058202"/>
|
||||
<COLOUR name="String" colour="FFBC45DD"/>
|
||||
<COLOUR name="Float" colour="ff885500"/>
|
||||
<COLOUR name="Integer" colour="FF42C8C4"/>
|
||||
<COLOUR name="Identifier" colour="FFCFCFCF"/>
|
||||
<COLOUR name="Operator" colour="FFC4EB19"/>
|
||||
<COLOUR name="Keyword" colour="FFEE6F6F"/>
|
||||
<COLOUR name="Comment" colour="FF72D20C"/>
|
||||
<COLOUR name="Error" colour="FFE60000"/>
|
||||
</COLOUR_SCHEME>
|
23
deps/juce/extras/Projucer/Source/BinaryData/colourscheme_light.xml
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<COLOUR_SCHEME font="<Monospaced>; 13.0">
|
||||
<COLOUR name="Main Window Bkgd" colour="FFE6E7E9"/>
|
||||
<COLOUR name="Treeview Highlight" colour="401111ee"/>
|
||||
<COLOUR name="Code Background" colour="ffffffff"/>
|
||||
<COLOUR name="Line Number Bkgd" colour="44999999"/>
|
||||
<COLOUR name="Line Numbers" colour="44000000"/>
|
||||
<COLOUR name="Plain Text" colour="ff000000"/>
|
||||
<COLOUR name="Selected Text Bkgd" colour="401111ee"/>
|
||||
<COLOUR name="Caret" colour="ff000000"/>
|
||||
<COLOUR name="Preprocessor Text" colour="ff660000"/>
|
||||
<COLOUR name="Punctuation" colour="ff004400"/>
|
||||
<COLOUR name="Bracket" colour="ff000055"/>
|
||||
<COLOUR name="String" colour="ff990099"/>
|
||||
<COLOUR name="Float" colour="ff885500"/>
|
||||
<COLOUR name="Integer" colour="ff880000"/>
|
||||
<COLOUR name="Identifier" colour="ff000000"/>
|
||||
<COLOUR name="Operator" colour="ff225500"/>
|
||||
<COLOUR name="Keyword" colour="ff0000cc"/>
|
||||
<COLOUR name="Comment" colour="ff00aa00"/>
|
||||
<COLOUR name="Error" colour="ffcc0000"/>
|
||||
</COLOUR_SCHEME>
|
202
deps/juce/extras/Projucer/Source/BinaryData/gradle/LICENSE
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
BIN
deps/juce/extras/Projucer/Source/BinaryData/gradle/gradle-wrapper.jar
vendored
Normal file
160
deps/juce/extras/Projucer/Source/BinaryData/gradle/gradlew
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
90
deps/juce/extras/Projucer/Source/BinaryData/gradle/gradlew.bat
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
65
deps/juce/extras/Projucer/Source/CodeEditor/jucer_DocumentEditorComponent.cpp
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 "../Application/jucer_Headers.h"
|
||||
#include "jucer_DocumentEditorComponent.h"
|
||||
#include "../Application/jucer_Application.h"
|
||||
#include "../Project/UI/jucer_ProjectContentComponent.h"
|
||||
|
||||
//==============================================================================
|
||||
DocumentEditorComponent::DocumentEditorComponent (OpenDocumentManager::Document* doc)
|
||||
: document (doc)
|
||||
{
|
||||
ProjucerApplication::getApp().openDocumentManager.addListener (this);
|
||||
}
|
||||
|
||||
DocumentEditorComponent::~DocumentEditorComponent()
|
||||
{
|
||||
ProjucerApplication::getApp().openDocumentManager.removeListener (this);
|
||||
}
|
||||
|
||||
bool DocumentEditorComponent::documentAboutToClose (OpenDocumentManager::Document* closingDoc)
|
||||
{
|
||||
if (document == closingDoc)
|
||||
{
|
||||
jassert (document != nullptr);
|
||||
|
||||
if (auto* pcc = findParentComponentOfClass<ProjectContentComponent>())
|
||||
pcc->hideDocument (document);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DocumentEditorComponent::setEditedState (bool hasBeenEdited)
|
||||
{
|
||||
if (hasBeenEdited != lastEditedState)
|
||||
{
|
||||
if (auto* pcc = findParentComponentOfClass<ProjectContentComponent>())
|
||||
pcc->refreshProjectTreeFileStatuses();
|
||||
|
||||
lastEditedState = hasBeenEdited;
|
||||
}
|
||||
}
|
51
deps/juce/extras/Projucer/Source/CodeEditor/jucer_DocumentEditorComponent.h
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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_OpenDocumentManager.h"
|
||||
|
||||
//==============================================================================
|
||||
class DocumentEditorComponent : public Component,
|
||||
private OpenDocumentManager::DocumentCloseListener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
DocumentEditorComponent (OpenDocumentManager::Document* document);
|
||||
~DocumentEditorComponent() override;
|
||||
|
||||
OpenDocumentManager::Document* getDocument() const { return document; }
|
||||
|
||||
protected:
|
||||
OpenDocumentManager::Document* document;
|
||||
bool lastEditedState = false;
|
||||
|
||||
void setEditedState (bool hasBeenEdited);
|
||||
|
||||
private:
|
||||
bool documentAboutToClose (OpenDocumentManager::Document*) override;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DocumentEditorComponent)
|
||||
};
|
117
deps/juce/extras/Projucer/Source/CodeEditor/jucer_ItemPreviewComponent.h
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 ItemPreviewComponent : public Component
|
||||
{
|
||||
public:
|
||||
ItemPreviewComponent (const File& f) : file (f)
|
||||
{
|
||||
setOpaque (true);
|
||||
tryToLoadImage();
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (findColour (backgroundColourId));
|
||||
|
||||
if (drawable != nullptr)
|
||||
{
|
||||
auto contentBounds = drawable->getDrawableBounds();
|
||||
|
||||
if (auto* dc = dynamic_cast<DrawableComposite*> (drawable.get()))
|
||||
{
|
||||
auto r = dc->getContentArea();
|
||||
|
||||
if (! r.isEmpty())
|
||||
contentBounds = r;
|
||||
}
|
||||
|
||||
auto area = RectanglePlacement (RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize)
|
||||
.appliedTo (contentBounds, Rectangle<float> (4.0f, 22.0f, (float) getWidth() - 8.0f, (float) getHeight() - 26.0f));
|
||||
|
||||
Path p;
|
||||
p.addRectangle (area);
|
||||
DropShadow (Colours::black.withAlpha (0.5f), 6, Point<int> (0, 1)).drawForPath (g, p);
|
||||
|
||||
g.fillCheckerBoard (area, 24.0f, 24.0f, Colour (0xffffffff), Colour (0xffeeeeee));
|
||||
|
||||
drawable->draw (g, 1.0f, RectanglePlacement (RectanglePlacement::stretchToFit)
|
||||
.getTransformToFit (contentBounds, area.toFloat()));
|
||||
}
|
||||
|
||||
g.setFont (Font (14.0f, Font::bold));
|
||||
g.setColour (findColour (defaultTextColourId));
|
||||
g.drawMultiLineText (facts.joinIntoString ("\n"), 10, 15, getWidth() - 16);
|
||||
}
|
||||
|
||||
private:
|
||||
StringArray facts;
|
||||
File file;
|
||||
std::unique_ptr<Drawable> drawable;
|
||||
|
||||
void tryToLoadImage()
|
||||
{
|
||||
facts.clear();
|
||||
facts.add (file.getFullPathName());
|
||||
drawable.reset();
|
||||
|
||||
if (auto input = std::unique_ptr<FileInputStream> (file.createInputStream()))
|
||||
{
|
||||
auto totalSize = input->getTotalLength();
|
||||
String formatName;
|
||||
|
||||
if (auto* format = ImageFileFormat::findImageFormatForStream (*input))
|
||||
formatName = " " + format->getFormatName();
|
||||
|
||||
input.reset();
|
||||
|
||||
auto image = ImageCache::getFromFile (file);
|
||||
|
||||
if (image.isValid())
|
||||
{
|
||||
auto* d = new DrawableImage();
|
||||
d->setImage (image);
|
||||
drawable.reset (d);
|
||||
|
||||
facts.add (String (image.getWidth()) + " x " + String (image.getHeight()) + formatName);
|
||||
}
|
||||
|
||||
if (totalSize > 0)
|
||||
facts.add (File::descriptionOfSizeInBytes (totalSize));
|
||||
}
|
||||
|
||||
if (drawable == nullptr)
|
||||
if (auto svg = parseXML (file))
|
||||
drawable = Drawable::createFromSVG (*svg);
|
||||
|
||||
facts.removeEmptyStrings (true);
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ItemPreviewComponent)
|
||||
};
|
544
deps/juce/extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.cpp
vendored
Normal file
@ -0,0 +1,544 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 "../Application/jucer_Headers.h"
|
||||
#include "jucer_OpenDocumentManager.h"
|
||||
#include "../CodeEditor/jucer_ItemPreviewComponent.h"
|
||||
#include "../Application/jucer_Application.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class UnknownDocument : public OpenDocumentManager::Document
|
||||
{
|
||||
public:
|
||||
UnknownDocument (Project* p, const File& f)
|
||||
: project (p), file (f)
|
||||
{
|
||||
reloadFromFile();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct Type : public OpenDocumentManager::DocumentType
|
||||
{
|
||||
bool canOpenFile (const File&) override { return true; }
|
||||
Document* openFile (Project* p, const File& f) override { return new UnknownDocument (p, f); }
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
bool loadedOk() const override { return true; }
|
||||
bool isForFile (const File& f) const override { return file == f; }
|
||||
bool isForNode (const ValueTree&) const override { return false; }
|
||||
bool refersToProject (Project& p) const override { return project == &p; }
|
||||
Project* getProject() const override { return project; }
|
||||
bool needsSaving() const override { return false; }
|
||||
bool saveSyncWithoutAsking() override { return true; }
|
||||
void saveAsync (std::function<void (bool)>) override {}
|
||||
void saveAsAsync (std::function<void (bool)>) override {}
|
||||
bool hasFileBeenModifiedExternally() override { return fileModificationTime != file.getLastModificationTime(); }
|
||||
void reloadFromFile() override { fileModificationTime = file.getLastModificationTime(); }
|
||||
String getName() const override { return file.getFileName(); }
|
||||
File getFile() const override { return file; }
|
||||
std::unique_ptr<Component> createEditor() override { return std::make_unique<ItemPreviewComponent> (file); }
|
||||
std::unique_ptr<Component> createViewer() override { return createEditor(); }
|
||||
void fileHasBeenRenamed (const File& newFile) override { file = newFile; }
|
||||
String getState() const override { return {}; }
|
||||
void restoreState (const String&) override {}
|
||||
|
||||
String getType() const override
|
||||
{
|
||||
if (file.getFileExtension().isNotEmpty())
|
||||
return file.getFileExtension() + " file";
|
||||
|
||||
jassertfalse;
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
private:
|
||||
Project* const project;
|
||||
File file;
|
||||
Time fileModificationTime;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UnknownDocument)
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
OpenDocumentManager::DocumentType* createGUIDocumentType();
|
||||
|
||||
OpenDocumentManager::OpenDocumentManager()
|
||||
{
|
||||
registerType (new UnknownDocument::Type());
|
||||
registerType (new SourceCodeDocument::Type());
|
||||
registerType (createGUIDocumentType());
|
||||
}
|
||||
|
||||
OpenDocumentManager::~OpenDocumentManager()
|
||||
{
|
||||
}
|
||||
|
||||
void OpenDocumentManager::clear()
|
||||
{
|
||||
documents.clear();
|
||||
types.clear();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void OpenDocumentManager::registerType (DocumentType* type, int index)
|
||||
{
|
||||
types.insert (index, type);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void OpenDocumentManager::addListener (DocumentCloseListener* listener)
|
||||
{
|
||||
listeners.addIfNotAlreadyThere (listener);
|
||||
}
|
||||
|
||||
void OpenDocumentManager::removeListener (DocumentCloseListener* listener)
|
||||
{
|
||||
listeners.removeFirstMatchingValue (listener);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool OpenDocumentManager::canOpenFile (const File& file)
|
||||
{
|
||||
for (int i = types.size(); --i >= 0;)
|
||||
if (types.getUnchecked(i)->canOpenFile (file))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
OpenDocumentManager::Document* OpenDocumentManager::openFile (Project* project, const File& file)
|
||||
{
|
||||
for (int i = documents.size(); --i >= 0;)
|
||||
if (documents.getUnchecked(i)->isForFile (file))
|
||||
return documents.getUnchecked(i);
|
||||
|
||||
Document* d = nullptr;
|
||||
|
||||
for (int i = types.size(); --i >= 0 && d == nullptr;)
|
||||
{
|
||||
if (types.getUnchecked(i)->canOpenFile (file))
|
||||
{
|
||||
d = types.getUnchecked(i)->openFile (project, file);
|
||||
jassert (d != nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
jassert (d != nullptr); // should always at least have been picked up by UnknownDocument
|
||||
|
||||
documents.add (d);
|
||||
ProjucerApplication::getCommandManager().commandStatusChanged();
|
||||
return d;
|
||||
}
|
||||
|
||||
int OpenDocumentManager::getNumOpenDocuments() const
|
||||
{
|
||||
return documents.size();
|
||||
}
|
||||
|
||||
OpenDocumentManager::Document* OpenDocumentManager::getOpenDocument (int index) const
|
||||
{
|
||||
return documents.getUnchecked (index);
|
||||
}
|
||||
|
||||
void OpenDocumentManager::saveIfNeededAndUserAgrees (OpenDocumentManager::Document* doc,
|
||||
std::function<void (FileBasedDocument::SaveResult)> callback)
|
||||
{
|
||||
if (! doc->needsSaving())
|
||||
{
|
||||
if (callback != nullptr)
|
||||
callback (FileBasedDocument::savedOk);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
AlertWindow::showYesNoCancelBox (MessageBoxIconType::QuestionIcon,
|
||||
TRANS("Closing document..."),
|
||||
TRANS("Do you want to save the changes to \"")
|
||||
+ doc->getName() + "\"?",
|
||||
TRANS("Save"),
|
||||
TRANS("Discard changes"),
|
||||
TRANS("Cancel"),
|
||||
nullptr,
|
||||
ModalCallbackFunction::create ([parent = WeakReference<OpenDocumentManager> { this }, doc, callback] (int r)
|
||||
{
|
||||
if (parent == nullptr)
|
||||
return;
|
||||
|
||||
if (r == 1)
|
||||
{
|
||||
doc->saveAsync ([parent, callback] (bool hasSaved)
|
||||
{
|
||||
if (parent == nullptr)
|
||||
return;
|
||||
|
||||
if (callback != nullptr)
|
||||
callback (hasSaved ? FileBasedDocument::savedOk : FileBasedDocument::failedToWriteToFile);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback != nullptr)
|
||||
callback (r == 2 ? FileBasedDocument::savedOk : FileBasedDocument::userCancelledSave);
|
||||
}));
|
||||
}
|
||||
|
||||
bool OpenDocumentManager::closeDocumentWithoutSaving (Document* doc)
|
||||
{
|
||||
if (documents.contains (doc))
|
||||
{
|
||||
bool canClose = true;
|
||||
|
||||
for (int i = listeners.size(); --i >= 0;)
|
||||
if (auto* l = listeners[i])
|
||||
if (! l->documentAboutToClose (doc))
|
||||
canClose = false;
|
||||
|
||||
if (! canClose)
|
||||
return false;
|
||||
|
||||
documents.removeObject (doc);
|
||||
ProjucerApplication::getCommandManager().commandStatusChanged();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenDocumentManager::closeDocumentAsync (Document* doc, SaveIfNeeded saveIfNeeded, std::function<void (bool)> callback)
|
||||
{
|
||||
if (! documents.contains (doc))
|
||||
{
|
||||
if (callback != nullptr)
|
||||
callback (true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (saveIfNeeded == SaveIfNeeded::yes)
|
||||
{
|
||||
saveIfNeededAndUserAgrees (doc,
|
||||
[parent = WeakReference<OpenDocumentManager> { this }, doc, callback] (FileBasedDocument::SaveResult result)
|
||||
{
|
||||
if (parent == nullptr)
|
||||
return;
|
||||
|
||||
if (result != FileBasedDocument::savedOk)
|
||||
{
|
||||
if (callback != nullptr)
|
||||
callback (false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback != nullptr)
|
||||
callback (parent->closeDocumentWithoutSaving (doc));
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback != nullptr)
|
||||
callback (closeDocumentWithoutSaving (doc));
|
||||
}
|
||||
|
||||
void OpenDocumentManager::closeFileWithoutSaving (const File& f)
|
||||
{
|
||||
for (int i = documents.size(); --i >= 0;)
|
||||
if (auto* d = documents[i])
|
||||
if (d->isForFile (f))
|
||||
closeDocumentWithoutSaving (d);
|
||||
}
|
||||
|
||||
static void closeLastAsyncRecusrsive (WeakReference<OpenDocumentManager> parent,
|
||||
OpenDocumentManager::SaveIfNeeded askUserToSave,
|
||||
std::function<void (bool)> callback)
|
||||
{
|
||||
auto lastIndex = parent->getNumOpenDocuments() - 1;
|
||||
|
||||
if (lastIndex < 0)
|
||||
{
|
||||
if (callback != nullptr)
|
||||
callback (true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
parent->closeDocumentAsync (parent->getOpenDocument (lastIndex),
|
||||
askUserToSave,
|
||||
[parent, askUserToSave, callback] (bool closedSuccessfully)
|
||||
{
|
||||
if (parent == nullptr)
|
||||
return;
|
||||
|
||||
if (! closedSuccessfully)
|
||||
{
|
||||
if (callback != nullptr)
|
||||
callback (false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
closeLastAsyncRecusrsive (parent, askUserToSave, std::move (callback));
|
||||
});
|
||||
}
|
||||
|
||||
void OpenDocumentManager::closeAllAsync (SaveIfNeeded askUserToSave, std::function<void (bool)> callback)
|
||||
{
|
||||
closeLastAsyncRecusrsive (this, askUserToSave, std::move (callback));
|
||||
}
|
||||
|
||||
void OpenDocumentManager::closeLastDocumentUsingProjectRecursive (WeakReference<OpenDocumentManager> parent,
|
||||
Project* project,
|
||||
SaveIfNeeded askUserToSave,
|
||||
std::function<void (bool)> callback)
|
||||
{
|
||||
for (int i = documents.size(); --i >= 0;)
|
||||
{
|
||||
if (auto* d = documents[i])
|
||||
{
|
||||
if (d->getProject() == project)
|
||||
{
|
||||
closeDocumentAsync (d, askUserToSave, [parent, project, askUserToSave, callback] (bool closedSuccessfully)
|
||||
{
|
||||
if (parent == nullptr)
|
||||
return;
|
||||
|
||||
if (! closedSuccessfully)
|
||||
{
|
||||
if (callback != nullptr)
|
||||
callback (false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
parent->closeLastDocumentUsingProjectRecursive (parent, project, askUserToSave, std::move (callback));
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (callback != nullptr)
|
||||
callback (true);
|
||||
}
|
||||
|
||||
void OpenDocumentManager::closeAllDocumentsUsingProjectAsync (Project& project, SaveIfNeeded askUserToSave, std::function<void (bool)> callback)
|
||||
{
|
||||
WeakReference<OpenDocumentManager> parent { this };
|
||||
closeLastDocumentUsingProjectRecursive (parent, &project, askUserToSave, std::move (callback));
|
||||
}
|
||||
|
||||
void OpenDocumentManager::closeAllDocumentsUsingProjectWithoutSaving (Project& project)
|
||||
{
|
||||
for (int i = documents.size(); --i >= 0;)
|
||||
if (Document* d = documents[i])
|
||||
if (d->refersToProject (project))
|
||||
closeDocumentWithoutSaving (d);
|
||||
}
|
||||
|
||||
bool OpenDocumentManager::anyFilesNeedSaving() const
|
||||
{
|
||||
for (int i = documents.size(); --i >= 0;)
|
||||
if (documents.getUnchecked (i)->needsSaving())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OpenDocumentManager::saveAllSyncWithoutAsking()
|
||||
{
|
||||
for (int i = documents.size(); --i >= 0;)
|
||||
{
|
||||
if (documents.getUnchecked (i)->saveSyncWithoutAsking())
|
||||
ProjucerApplication::getCommandManager().commandStatusChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenDocumentManager::reloadModifiedFiles()
|
||||
{
|
||||
for (int i = documents.size(); --i >= 0;)
|
||||
{
|
||||
Document* d = documents.getUnchecked (i);
|
||||
|
||||
if (d->hasFileBeenModifiedExternally())
|
||||
d->reloadFromFile();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenDocumentManager::fileHasBeenRenamed (const File& oldFile, const File& newFile)
|
||||
{
|
||||
for (int i = documents.size(); --i >= 0;)
|
||||
{
|
||||
Document* d = documents.getUnchecked (i);
|
||||
|
||||
if (d->isForFile (oldFile))
|
||||
d->fileHasBeenRenamed (newFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
RecentDocumentList::RecentDocumentList()
|
||||
{
|
||||
ProjucerApplication::getApp().openDocumentManager.addListener (this);
|
||||
}
|
||||
|
||||
RecentDocumentList::~RecentDocumentList()
|
||||
{
|
||||
ProjucerApplication::getApp().openDocumentManager.removeListener (this);
|
||||
}
|
||||
|
||||
void RecentDocumentList::clear()
|
||||
{
|
||||
previousDocs.clear();
|
||||
nextDocs.clear();
|
||||
}
|
||||
|
||||
void RecentDocumentList::newDocumentOpened (OpenDocumentManager::Document* document)
|
||||
{
|
||||
if (document != nullptr && document != getCurrentDocument())
|
||||
{
|
||||
nextDocs.clear();
|
||||
previousDocs.add (document);
|
||||
}
|
||||
}
|
||||
|
||||
bool RecentDocumentList::canGoToPrevious() const
|
||||
{
|
||||
return previousDocs.size() > 1;
|
||||
}
|
||||
|
||||
bool RecentDocumentList::canGoToNext() const
|
||||
{
|
||||
return nextDocs.size() > 0;
|
||||
}
|
||||
|
||||
OpenDocumentManager::Document* RecentDocumentList::getPrevious()
|
||||
{
|
||||
if (! canGoToPrevious())
|
||||
return nullptr;
|
||||
|
||||
nextDocs.insert (0, previousDocs.removeAndReturn (previousDocs.size() - 1));
|
||||
return previousDocs.getLast();
|
||||
}
|
||||
|
||||
OpenDocumentManager::Document* RecentDocumentList::getNext()
|
||||
{
|
||||
if (! canGoToNext())
|
||||
return nullptr;
|
||||
|
||||
OpenDocumentManager::Document* d = nextDocs.removeAndReturn (0);
|
||||
previousDocs.add (d);
|
||||
return d;
|
||||
}
|
||||
|
||||
bool RecentDocumentList::contains (const File& f) const
|
||||
{
|
||||
for (int i = previousDocs.size(); --i >= 0;)
|
||||
if (previousDocs.getUnchecked(i)->getFile() == f)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
OpenDocumentManager::Document* RecentDocumentList::getClosestPreviousDocOtherThan (OpenDocumentManager::Document* oneToAvoid) const
|
||||
{
|
||||
for (int i = previousDocs.size(); --i >= 0;)
|
||||
if (previousDocs.getUnchecked(i) != oneToAvoid)
|
||||
return previousDocs.getUnchecked(i);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool RecentDocumentList::documentAboutToClose (OpenDocumentManager::Document* document)
|
||||
{
|
||||
previousDocs.removeAllInstancesOf (document);
|
||||
nextDocs.removeAllInstancesOf (document);
|
||||
|
||||
jassert (! previousDocs.contains (document));
|
||||
jassert (! nextDocs.contains (document));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void restoreDocList (Project& project, Array <OpenDocumentManager::Document*>& list, const XmlElement* xml)
|
||||
{
|
||||
if (xml != nullptr)
|
||||
{
|
||||
OpenDocumentManager& odm = ProjucerApplication::getApp().openDocumentManager;
|
||||
|
||||
for (auto* e : xml->getChildWithTagNameIterator ("DOC"))
|
||||
{
|
||||
const File file (e->getStringAttribute ("file"));
|
||||
|
||||
if (file.exists())
|
||||
{
|
||||
if (OpenDocumentManager::Document* doc = odm.openFile (&project, file))
|
||||
{
|
||||
doc->restoreState (e->getStringAttribute ("state"));
|
||||
|
||||
list.add (doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RecentDocumentList::restoreFromXML (Project& project, const XmlElement& xml)
|
||||
{
|
||||
clear();
|
||||
|
||||
if (xml.hasTagName ("RECENT_DOCUMENTS"))
|
||||
{
|
||||
restoreDocList (project, previousDocs, xml.getChildByName ("PREVIOUS"));
|
||||
restoreDocList (project, nextDocs, xml.getChildByName ("NEXT"));
|
||||
}
|
||||
}
|
||||
|
||||
static void saveDocList (const Array <OpenDocumentManager::Document*>& list, XmlElement& xml)
|
||||
{
|
||||
for (int i = 0; i < list.size(); ++i)
|
||||
{
|
||||
const OpenDocumentManager::Document& doc = *list.getUnchecked(i);
|
||||
|
||||
XmlElement* e = xml.createNewChildElement ("DOC");
|
||||
|
||||
e->setAttribute ("file", doc.getFile().getFullPathName());
|
||||
e->setAttribute ("state", doc.getState());
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<XmlElement> RecentDocumentList::createXML() const
|
||||
{
|
||||
auto xml = std::make_unique<XmlElement> ("RECENT_DOCUMENTS");
|
||||
|
||||
saveDocList (previousDocs, *xml->createNewChildElement ("PREVIOUS"));
|
||||
saveDocList (nextDocs, *xml->createNewChildElement ("NEXT"));
|
||||
|
||||
return xml;
|
||||
}
|
167
deps/juce/extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.h
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 "../Project/jucer_Project.h"
|
||||
|
||||
//==============================================================================
|
||||
class OpenDocumentManager
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
OpenDocumentManager();
|
||||
~OpenDocumentManager();
|
||||
|
||||
//==============================================================================
|
||||
class Document
|
||||
{
|
||||
public:
|
||||
Document() {}
|
||||
virtual ~Document() {}
|
||||
|
||||
virtual bool loadedOk() const = 0;
|
||||
virtual bool isForFile (const File& file) const = 0;
|
||||
virtual bool isForNode (const ValueTree& node) const = 0;
|
||||
virtual bool refersToProject (Project& project) const = 0;
|
||||
virtual Project* getProject() const = 0;
|
||||
virtual String getName() const = 0;
|
||||
virtual String getType() const = 0;
|
||||
virtual File getFile() const = 0;
|
||||
virtual bool needsSaving() const = 0;
|
||||
virtual bool saveSyncWithoutAsking() = 0;
|
||||
virtual void saveAsync (std::function<void (bool)>) = 0;
|
||||
virtual void saveAsAsync (std::function<void (bool)>) = 0;
|
||||
virtual bool hasFileBeenModifiedExternally() = 0;
|
||||
virtual void reloadFromFile() = 0;
|
||||
virtual std::unique_ptr<Component> createEditor() = 0;
|
||||
virtual std::unique_ptr<Component> createViewer() = 0;
|
||||
virtual void fileHasBeenRenamed (const File& newFile) = 0;
|
||||
virtual String getState() const = 0;
|
||||
virtual void restoreState (const String& state) = 0;
|
||||
virtual File getCounterpartFile() const { return {}; }
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
int getNumOpenDocuments() const;
|
||||
Document* getOpenDocument (int index) const;
|
||||
void clear();
|
||||
|
||||
enum class SaveIfNeeded { no, yes };
|
||||
|
||||
bool canOpenFile (const File& file);
|
||||
Document* openFile (Project* project, const File& file);
|
||||
|
||||
void closeDocumentAsync (Document* document, SaveIfNeeded saveIfNeeded, std::function<void (bool)> callback);
|
||||
bool closeDocumentWithoutSaving (Document* document);
|
||||
|
||||
void closeAllAsync (SaveIfNeeded askUserToSave, std::function<void (bool)> callback);
|
||||
void closeAllDocumentsUsingProjectAsync (Project& project, SaveIfNeeded askUserToSave, std::function<void (bool)> callback);
|
||||
void closeAllDocumentsUsingProjectWithoutSaving (Project& project);
|
||||
|
||||
void closeFileWithoutSaving (const File& f);
|
||||
bool anyFilesNeedSaving() const;
|
||||
|
||||
void saveAllSyncWithoutAsking();
|
||||
void saveIfNeededAndUserAgrees (Document* doc, std::function<void (FileBasedDocument::SaveResult)>);
|
||||
|
||||
void reloadModifiedFiles();
|
||||
void fileHasBeenRenamed (const File& oldFile, const File& newFile);
|
||||
|
||||
//==============================================================================
|
||||
class DocumentCloseListener
|
||||
{
|
||||
public:
|
||||
DocumentCloseListener() {}
|
||||
virtual ~DocumentCloseListener() {}
|
||||
|
||||
// return false to force it to stop.
|
||||
virtual bool documentAboutToClose (Document* document) = 0;
|
||||
};
|
||||
|
||||
void addListener (DocumentCloseListener*);
|
||||
void removeListener (DocumentCloseListener*);
|
||||
|
||||
//==============================================================================
|
||||
class DocumentType
|
||||
{
|
||||
public:
|
||||
DocumentType() {}
|
||||
virtual ~DocumentType() {}
|
||||
|
||||
virtual bool canOpenFile (const File& file) = 0;
|
||||
virtual Document* openFile (Project* project, const File& file) = 0;
|
||||
};
|
||||
|
||||
void registerType (DocumentType* type, int index = -1);
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
void closeLastDocumentUsingProjectRecursive (WeakReference<OpenDocumentManager>,
|
||||
Project*,
|
||||
SaveIfNeeded,
|
||||
std::function<void (bool)>);
|
||||
|
||||
//==============================================================================
|
||||
OwnedArray<DocumentType> types;
|
||||
OwnedArray<Document> documents;
|
||||
Array<DocumentCloseListener*> listeners;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenDocumentManager)
|
||||
JUCE_DECLARE_WEAK_REFERENCEABLE (OpenDocumentManager)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class RecentDocumentList : private OpenDocumentManager::DocumentCloseListener
|
||||
{
|
||||
public:
|
||||
RecentDocumentList();
|
||||
~RecentDocumentList();
|
||||
|
||||
void clear();
|
||||
|
||||
void newDocumentOpened (OpenDocumentManager::Document* document);
|
||||
|
||||
OpenDocumentManager::Document* getCurrentDocument() const { return previousDocs.getLast(); }
|
||||
|
||||
bool canGoToPrevious() const;
|
||||
bool canGoToNext() const;
|
||||
|
||||
bool contains (const File&) const;
|
||||
|
||||
OpenDocumentManager::Document* getPrevious();
|
||||
OpenDocumentManager::Document* getNext();
|
||||
|
||||
OpenDocumentManager::Document* getClosestPreviousDocOtherThan (OpenDocumentManager::Document* oneToAvoid) const;
|
||||
|
||||
void restoreFromXML (Project& project, const XmlElement& xml);
|
||||
std::unique_ptr<XmlElement> createXML() const;
|
||||
|
||||
private:
|
||||
bool documentAboutToClose (OpenDocumentManager::Document*);
|
||||
|
||||
Array<OpenDocumentManager::Document*> previousDocs, nextDocs;
|
||||
};
|
697
deps/juce/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.cpp
vendored
Normal file
@ -0,0 +1,697 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 "../Application/jucer_Headers.h"
|
||||
#include "jucer_SourceCodeEditor.h"
|
||||
#include "../Application/jucer_Application.h"
|
||||
|
||||
//==============================================================================
|
||||
SourceCodeDocument::SourceCodeDocument (Project* p, const File& f)
|
||||
: modDetector (f), project (p)
|
||||
{
|
||||
}
|
||||
|
||||
CodeDocument& SourceCodeDocument::getCodeDocument()
|
||||
{
|
||||
if (codeDoc == nullptr)
|
||||
{
|
||||
codeDoc.reset (new CodeDocument());
|
||||
reloadInternal();
|
||||
codeDoc->clearUndoHistory();
|
||||
}
|
||||
|
||||
return *codeDoc;
|
||||
}
|
||||
|
||||
std::unique_ptr<Component> SourceCodeDocument::createEditor()
|
||||
{
|
||||
auto e = std::make_unique<SourceCodeEditor> (this, getCodeDocument());
|
||||
applyLastState (*(e->editor));
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wredundant-move")
|
||||
return std::move (e);
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
}
|
||||
|
||||
void SourceCodeDocument::reloadFromFile()
|
||||
{
|
||||
getCodeDocument();
|
||||
reloadInternal();
|
||||
}
|
||||
|
||||
void SourceCodeDocument::reloadInternal()
|
||||
{
|
||||
jassert (codeDoc != nullptr);
|
||||
modDetector.updateHash();
|
||||
|
||||
auto fileContent = getFile().loadFileAsString();
|
||||
|
||||
auto lineFeed = getLineFeedForFile (fileContent);
|
||||
|
||||
if (lineFeed.isEmpty())
|
||||
{
|
||||
if (project != nullptr)
|
||||
lineFeed = project->getProjectLineFeed();
|
||||
else
|
||||
lineFeed = "\r\n";
|
||||
}
|
||||
|
||||
codeDoc->setNewLineCharacters (lineFeed);
|
||||
|
||||
codeDoc->applyChanges (fileContent);
|
||||
codeDoc->setSavePoint();
|
||||
}
|
||||
|
||||
static bool writeCodeDocToFile (const File& file, CodeDocument& doc)
|
||||
{
|
||||
TemporaryFile temp (file);
|
||||
|
||||
{
|
||||
FileOutputStream fo (temp.getFile());
|
||||
|
||||
if (! (fo.openedOk() && doc.writeToStream (fo)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return temp.overwriteTargetFileWithTemporary();
|
||||
}
|
||||
|
||||
bool SourceCodeDocument::saveSyncWithoutAsking()
|
||||
{
|
||||
if (writeCodeDocToFile (getFile(), getCodeDocument()))
|
||||
{
|
||||
getCodeDocument().setSavePoint();
|
||||
modDetector.updateHash();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SourceCodeDocument::saveAsync (std::function<void (bool)> callback)
|
||||
{
|
||||
callback (saveSyncWithoutAsking());
|
||||
}
|
||||
|
||||
void SourceCodeDocument::saveAsAsync (std::function<void (bool)> callback)
|
||||
{
|
||||
chooser = std::make_unique<FileChooser> (TRANS("Save As..."), getFile(), "*");
|
||||
auto flags = FileBrowserComponent::saveMode
|
||||
| FileBrowserComponent::canSelectFiles
|
||||
| FileBrowserComponent::warnAboutOverwriting;
|
||||
|
||||
chooser->launchAsync (flags, [this, callback] (const FileChooser& fc)
|
||||
{
|
||||
if (fc.getResult() == File{})
|
||||
{
|
||||
callback (true);
|
||||
return;
|
||||
}
|
||||
|
||||
callback (writeCodeDocToFile (fc.getResult(), getCodeDocument()));
|
||||
});
|
||||
}
|
||||
|
||||
void SourceCodeDocument::updateLastState (CodeEditorComponent& editor)
|
||||
{
|
||||
lastState.reset (new CodeEditorComponent::State (editor));
|
||||
}
|
||||
|
||||
void SourceCodeDocument::applyLastState (CodeEditorComponent& editor) const
|
||||
{
|
||||
if (lastState != nullptr)
|
||||
lastState->restoreState (editor);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
SourceCodeEditor::SourceCodeEditor (OpenDocumentManager::Document* doc, CodeDocument& codeDocument)
|
||||
: DocumentEditorComponent (doc)
|
||||
{
|
||||
GenericCodeEditorComponent* ed = nullptr;
|
||||
auto file = document->getFile();
|
||||
|
||||
if (fileNeedsCppSyntaxHighlighting (file))
|
||||
{
|
||||
ed = new CppCodeEditorComponent (file, codeDocument);
|
||||
}
|
||||
else
|
||||
{
|
||||
CodeTokeniser* tokeniser = nullptr;
|
||||
|
||||
if (file.hasFileExtension ("xml;svg"))
|
||||
{
|
||||
static XmlTokeniser xmlTokeniser;
|
||||
tokeniser = &xmlTokeniser;
|
||||
}
|
||||
|
||||
if (file.hasFileExtension ("lua"))
|
||||
{
|
||||
static LuaTokeniser luaTokeniser;
|
||||
tokeniser = &luaTokeniser;
|
||||
}
|
||||
|
||||
ed = new GenericCodeEditorComponent (file, codeDocument, tokeniser);
|
||||
}
|
||||
|
||||
setEditor (ed);
|
||||
}
|
||||
|
||||
SourceCodeEditor::SourceCodeEditor (OpenDocumentManager::Document* doc, GenericCodeEditorComponent* ed)
|
||||
: DocumentEditorComponent (doc)
|
||||
{
|
||||
setEditor (ed);
|
||||
}
|
||||
|
||||
SourceCodeEditor::~SourceCodeEditor()
|
||||
{
|
||||
if (editor != nullptr)
|
||||
editor->getDocument().removeListener (this);
|
||||
|
||||
getAppSettings().appearance.settings.removeListener (this);
|
||||
|
||||
if (auto* doc = dynamic_cast<SourceCodeDocument*> (getDocument()))
|
||||
doc->updateLastState (*editor);
|
||||
}
|
||||
|
||||
void SourceCodeEditor::setEditor (GenericCodeEditorComponent* newEditor)
|
||||
{
|
||||
if (editor != nullptr)
|
||||
editor->getDocument().removeListener (this);
|
||||
|
||||
editor.reset (newEditor);
|
||||
addAndMakeVisible (newEditor);
|
||||
|
||||
editor->setFont (AppearanceSettings::getDefaultCodeFont());
|
||||
editor->setTabSize (4, true);
|
||||
|
||||
updateColourScheme();
|
||||
getAppSettings().appearance.settings.addListener (this);
|
||||
|
||||
editor->getDocument().addListener (this);
|
||||
}
|
||||
|
||||
void SourceCodeEditor::scrollToKeepRangeOnScreen (Range<int> range)
|
||||
{
|
||||
auto space = jmin (10, editor->getNumLinesOnScreen() / 3);
|
||||
const CodeDocument::Position start (editor->getDocument(), range.getStart());
|
||||
const CodeDocument::Position end (editor->getDocument(), range.getEnd());
|
||||
|
||||
editor->scrollToKeepLinesOnScreen ({ start.getLineNumber() - space, end.getLineNumber() + space });
|
||||
}
|
||||
|
||||
void SourceCodeEditor::highlight (Range<int> range, bool cursorAtStart)
|
||||
{
|
||||
scrollToKeepRangeOnScreen (range);
|
||||
|
||||
if (cursorAtStart)
|
||||
{
|
||||
editor->moveCaretTo (CodeDocument::Position (editor->getDocument(), range.getEnd()), false);
|
||||
editor->moveCaretTo (CodeDocument::Position (editor->getDocument(), range.getStart()), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
editor->setHighlightedRegion (range);
|
||||
}
|
||||
}
|
||||
|
||||
void SourceCodeEditor::resized()
|
||||
{
|
||||
editor->setBounds (getLocalBounds());
|
||||
}
|
||||
|
||||
void SourceCodeEditor::updateColourScheme()
|
||||
{
|
||||
getAppSettings().appearance.applyToCodeEditor (*editor);
|
||||
}
|
||||
|
||||
void SourceCodeEditor::checkSaveState()
|
||||
{
|
||||
setEditedState (getDocument()->needsSaving());
|
||||
}
|
||||
|
||||
void SourceCodeEditor::lookAndFeelChanged()
|
||||
{
|
||||
updateColourScheme();
|
||||
}
|
||||
|
||||
void SourceCodeEditor::valueTreePropertyChanged (ValueTree&, const Identifier&) { updateColourScheme(); }
|
||||
void SourceCodeEditor::valueTreeChildAdded (ValueTree&, ValueTree&) { updateColourScheme(); }
|
||||
void SourceCodeEditor::valueTreeChildRemoved (ValueTree&, ValueTree&, int) { updateColourScheme(); }
|
||||
void SourceCodeEditor::valueTreeChildOrderChanged (ValueTree&, int, int) { updateColourScheme(); }
|
||||
void SourceCodeEditor::valueTreeParentChanged (ValueTree&) { updateColourScheme(); }
|
||||
void SourceCodeEditor::valueTreeRedirected (ValueTree&) { updateColourScheme(); }
|
||||
|
||||
void SourceCodeEditor::codeDocumentTextInserted (const String&, int) { checkSaveState(); }
|
||||
void SourceCodeEditor::codeDocumentTextDeleted (int, int) { checkSaveState(); }
|
||||
|
||||
//==============================================================================
|
||||
GenericCodeEditorComponent::GenericCodeEditorComponent (const File& f, CodeDocument& codeDocument,
|
||||
CodeTokeniser* tokeniser)
|
||||
: CodeEditorComponent (codeDocument, tokeniser), file (f)
|
||||
{
|
||||
setScrollbarThickness (6);
|
||||
setCommandManager (&ProjucerApplication::getCommandManager());
|
||||
}
|
||||
|
||||
GenericCodeEditorComponent::~GenericCodeEditorComponent() {}
|
||||
|
||||
enum
|
||||
{
|
||||
showInFinderID = 0x2fe821e3,
|
||||
insertComponentID = 0x2fe821e4
|
||||
};
|
||||
|
||||
void GenericCodeEditorComponent::addPopupMenuItems (PopupMenu& menu, const MouseEvent* e)
|
||||
{
|
||||
menu.addItem (showInFinderID,
|
||||
#if JUCE_MAC
|
||||
"Reveal " + file.getFileName() + " in Finder");
|
||||
#else
|
||||
"Reveal " + file.getFileName() + " in Explorer");
|
||||
#endif
|
||||
menu.addSeparator();
|
||||
|
||||
CodeEditorComponent::addPopupMenuItems (menu, e);
|
||||
}
|
||||
|
||||
void GenericCodeEditorComponent::performPopupMenuAction (int menuItemID)
|
||||
{
|
||||
if (menuItemID == showInFinderID)
|
||||
file.revealToUser();
|
||||
else
|
||||
CodeEditorComponent::performPopupMenuAction (menuItemID);
|
||||
}
|
||||
|
||||
void GenericCodeEditorComponent::getAllCommands (Array <CommandID>& commands)
|
||||
{
|
||||
CodeEditorComponent::getAllCommands (commands);
|
||||
|
||||
const CommandID ids[] = { CommandIDs::showFindPanel,
|
||||
CommandIDs::findSelection,
|
||||
CommandIDs::findNext,
|
||||
CommandIDs::findPrevious };
|
||||
|
||||
commands.addArray (ids, numElementsInArray (ids));
|
||||
}
|
||||
|
||||
void GenericCodeEditorComponent::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result)
|
||||
{
|
||||
auto anythingSelected = isHighlightActive();
|
||||
|
||||
switch (commandID)
|
||||
{
|
||||
case CommandIDs::showFindPanel:
|
||||
result.setInfo (TRANS ("Find"), TRANS ("Searches for text in the current document."), "Editing", 0);
|
||||
result.defaultKeypresses.add (KeyPress ('f', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case CommandIDs::findSelection:
|
||||
result.setInfo (TRANS ("Find Selection"), TRANS ("Searches for the currently selected text."), "Editing", 0);
|
||||
result.setActive (anythingSelected);
|
||||
result.defaultKeypresses.add (KeyPress ('l', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case CommandIDs::findNext:
|
||||
result.setInfo (TRANS ("Find Next"), TRANS ("Searches for the next occurrence of the current search-term."), "Editing", 0);
|
||||
result.defaultKeypresses.add (KeyPress ('g', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case CommandIDs::findPrevious:
|
||||
result.setInfo (TRANS ("Find Previous"), TRANS ("Searches for the previous occurrence of the current search-term."), "Editing", 0);
|
||||
result.defaultKeypresses.add (KeyPress ('g', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0));
|
||||
result.defaultKeypresses.add (KeyPress ('d', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
default:
|
||||
CodeEditorComponent::getCommandInfo (commandID, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool GenericCodeEditorComponent::perform (const InvocationInfo& info)
|
||||
{
|
||||
switch (info.commandID)
|
||||
{
|
||||
case CommandIDs::showFindPanel: showFindPanel(); return true;
|
||||
case CommandIDs::findSelection: findSelection(); return true;
|
||||
case CommandIDs::findNext: findNext (true, true); return true;
|
||||
case CommandIDs::findPrevious: findNext (false, false); return true;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return CodeEditorComponent::perform (info);
|
||||
}
|
||||
|
||||
void GenericCodeEditorComponent::addListener (GenericCodeEditorComponent::Listener* listener)
|
||||
{
|
||||
listeners.add (listener);
|
||||
}
|
||||
|
||||
void GenericCodeEditorComponent::removeListener (GenericCodeEditorComponent::Listener* listener)
|
||||
{
|
||||
listeners.remove (listener);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class GenericCodeEditorComponent::FindPanel : public Component
|
||||
{
|
||||
public:
|
||||
FindPanel()
|
||||
{
|
||||
editor.setColour (CaretComponent::caretColourId, Colours::black);
|
||||
|
||||
addAndMakeVisible (editor);
|
||||
label.setColour (Label::textColourId, Colours::white);
|
||||
label.attachToComponent (&editor, false);
|
||||
|
||||
addAndMakeVisible (caseButton);
|
||||
caseButton.setColour (ToggleButton::textColourId, Colours::white);
|
||||
caseButton.setToggleState (isCaseSensitiveSearch(), dontSendNotification);
|
||||
caseButton.onClick = [this] { setCaseSensitiveSearch (caseButton.getToggleState()); };
|
||||
|
||||
findPrev.setConnectedEdges (Button::ConnectedOnRight);
|
||||
findNext.setConnectedEdges (Button::ConnectedOnLeft);
|
||||
addAndMakeVisible (findPrev);
|
||||
addAndMakeVisible (findNext);
|
||||
|
||||
setWantsKeyboardFocus (false);
|
||||
setFocusContainerType (FocusContainerType::keyboardFocusContainer);
|
||||
findPrev.setWantsKeyboardFocus (false);
|
||||
findNext.setWantsKeyboardFocus (false);
|
||||
|
||||
editor.setText (getSearchString());
|
||||
editor.onTextChange = [this] { changeSearchString(); };
|
||||
editor.onReturnKey = [] { ProjucerApplication::getCommandManager().invokeDirectly (CommandIDs::findNext, true); };
|
||||
editor.onEscapeKey = [this]
|
||||
{
|
||||
if (auto* ed = getOwner())
|
||||
ed->hideFindPanel();
|
||||
};
|
||||
}
|
||||
|
||||
void setCommandManager (ApplicationCommandManager* cm)
|
||||
{
|
||||
findPrev.setCommandToTrigger (cm, CommandIDs::findPrevious, true);
|
||||
findNext.setCommandToTrigger (cm, CommandIDs::findNext, true);
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
Path outline;
|
||||
outline.addRoundedRectangle (1.0f, 1.0f, (float) getWidth() - 2.0f, (float) getHeight() - 2.0f, 8.0f);
|
||||
|
||||
g.setColour (Colours::black.withAlpha (0.6f));
|
||||
g.fillPath (outline);
|
||||
g.setColour (Colours::white.withAlpha (0.8f));
|
||||
g.strokePath (outline, PathStrokeType (1.0f));
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
int y = 30;
|
||||
editor.setBounds (10, y, getWidth() - 20, 24);
|
||||
y += 30;
|
||||
caseButton.setBounds (10, y, getWidth() / 2 - 10, 22);
|
||||
findNext.setBounds (getWidth() - 40, y, 30, 22);
|
||||
findPrev.setBounds (getWidth() - 70, y, 30, 22);
|
||||
}
|
||||
|
||||
void changeSearchString()
|
||||
{
|
||||
setSearchString (editor.getText());
|
||||
|
||||
if (auto* ed = getOwner())
|
||||
ed->findNext (true, false);
|
||||
}
|
||||
|
||||
GenericCodeEditorComponent* getOwner() const
|
||||
{
|
||||
return findParentComponentOfClass <GenericCodeEditorComponent>();
|
||||
}
|
||||
|
||||
TextEditor editor;
|
||||
Label label { {}, "Find:" };
|
||||
ToggleButton caseButton { "Case-sensitive" };
|
||||
TextButton findPrev { "<" },
|
||||
findNext { ">" };
|
||||
};
|
||||
|
||||
void GenericCodeEditorComponent::resized()
|
||||
{
|
||||
CodeEditorComponent::resized();
|
||||
|
||||
if (findPanel != nullptr)
|
||||
{
|
||||
findPanel->setSize (jmin (260, getWidth() - 32), 100);
|
||||
findPanel->setTopRightPosition (getWidth() - 16, 8);
|
||||
}
|
||||
}
|
||||
|
||||
void GenericCodeEditorComponent::showFindPanel()
|
||||
{
|
||||
if (findPanel == nullptr)
|
||||
{
|
||||
findPanel.reset (new FindPanel());
|
||||
findPanel->setCommandManager (&ProjucerApplication::getCommandManager());
|
||||
addAndMakeVisible (findPanel.get());
|
||||
resized();
|
||||
}
|
||||
|
||||
if (findPanel != nullptr)
|
||||
{
|
||||
findPanel->editor.grabKeyboardFocus();
|
||||
findPanel->editor.selectAll();
|
||||
}
|
||||
}
|
||||
|
||||
void GenericCodeEditorComponent::hideFindPanel()
|
||||
{
|
||||
findPanel.reset();
|
||||
}
|
||||
|
||||
void GenericCodeEditorComponent::findSelection()
|
||||
{
|
||||
auto selected = getTextInRange (getHighlightedRegion());
|
||||
|
||||
if (selected.isNotEmpty())
|
||||
{
|
||||
setSearchString (selected);
|
||||
findNext (true, true);
|
||||
}
|
||||
}
|
||||
|
||||
void GenericCodeEditorComponent::findNext (bool forwards, bool skipCurrentSelection)
|
||||
{
|
||||
auto highlight = getHighlightedRegion();
|
||||
const CodeDocument::Position startPos (getDocument(), skipCurrentSelection ? highlight.getEnd()
|
||||
: highlight.getStart());
|
||||
auto lineNum = startPos.getLineNumber();
|
||||
auto linePos = startPos.getIndexInLine();
|
||||
|
||||
auto totalLines = getDocument().getNumLines();
|
||||
auto searchText = getSearchString();
|
||||
auto caseSensitive = isCaseSensitiveSearch();
|
||||
|
||||
for (auto linesToSearch = totalLines; --linesToSearch >= 0;)
|
||||
{
|
||||
auto line = getDocument().getLine (lineNum);
|
||||
int index;
|
||||
|
||||
if (forwards)
|
||||
{
|
||||
index = caseSensitive ? line.indexOf (linePos, searchText)
|
||||
: line.indexOfIgnoreCase (linePos, searchText);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (linePos >= 0)
|
||||
line = line.substring (0, linePos);
|
||||
|
||||
index = caseSensitive ? line.lastIndexOf (searchText)
|
||||
: line.lastIndexOfIgnoreCase (searchText);
|
||||
}
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
const CodeDocument::Position p (getDocument(), lineNum, index);
|
||||
selectRegion (p, p.movedBy (searchText.length()));
|
||||
break;
|
||||
}
|
||||
|
||||
if (forwards)
|
||||
{
|
||||
linePos = 0;
|
||||
lineNum = (lineNum + 1) % totalLines;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (--lineNum < 0)
|
||||
lineNum = totalLines - 1;
|
||||
|
||||
linePos = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GenericCodeEditorComponent::handleEscapeKey()
|
||||
{
|
||||
CodeEditorComponent::handleEscapeKey();
|
||||
hideFindPanel();
|
||||
}
|
||||
|
||||
void GenericCodeEditorComponent::editorViewportPositionChanged()
|
||||
{
|
||||
CodeEditorComponent::editorViewportPositionChanged();
|
||||
listeners.call ([this] (Listener& l) { l.codeEditorViewportMoved (*this); });
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static CPlusPlusCodeTokeniser cppTokeniser;
|
||||
|
||||
CppCodeEditorComponent::CppCodeEditorComponent (const File& f, CodeDocument& doc)
|
||||
: GenericCodeEditorComponent (f, doc, &cppTokeniser)
|
||||
{
|
||||
}
|
||||
|
||||
CppCodeEditorComponent::~CppCodeEditorComponent() {}
|
||||
|
||||
void CppCodeEditorComponent::handleReturnKey()
|
||||
{
|
||||
GenericCodeEditorComponent::handleReturnKey();
|
||||
|
||||
auto pos = getCaretPos();
|
||||
|
||||
String blockIndent, lastLineIndent;
|
||||
CodeHelpers::getIndentForCurrentBlock (pos, getTabString (getTabSize()), blockIndent, lastLineIndent);
|
||||
|
||||
auto remainderOfBrokenLine = pos.getLineText();
|
||||
auto numLeadingWSChars = CodeHelpers::getLeadingWhitespace (remainderOfBrokenLine).length();
|
||||
|
||||
if (numLeadingWSChars > 0)
|
||||
getDocument().deleteSection (pos, pos.movedBy (numLeadingWSChars));
|
||||
|
||||
if (remainderOfBrokenLine.trimStart().startsWithChar ('}'))
|
||||
insertTextAtCaret (blockIndent);
|
||||
else
|
||||
insertTextAtCaret (lastLineIndent);
|
||||
|
||||
auto previousLine = pos.movedByLines (-1).getLineText();
|
||||
auto trimmedPreviousLine = previousLine.trim();
|
||||
|
||||
if ((trimmedPreviousLine.startsWith ("if ")
|
||||
|| trimmedPreviousLine.startsWith ("if(")
|
||||
|| trimmedPreviousLine.startsWith ("for ")
|
||||
|| trimmedPreviousLine.startsWith ("for(")
|
||||
|| trimmedPreviousLine.startsWith ("while(")
|
||||
|| trimmedPreviousLine.startsWith ("while "))
|
||||
&& trimmedPreviousLine.endsWithChar (')'))
|
||||
{
|
||||
insertTabAtCaret();
|
||||
}
|
||||
}
|
||||
|
||||
void CppCodeEditorComponent::insertTextAtCaret (const String& newText)
|
||||
{
|
||||
if (getHighlightedRegion().isEmpty())
|
||||
{
|
||||
auto pos = getCaretPos();
|
||||
|
||||
if ((newText == "{" || newText == "}")
|
||||
&& pos.getLineNumber() > 0
|
||||
&& pos.getLineText().trim().isEmpty())
|
||||
{
|
||||
moveCaretToStartOfLine (true);
|
||||
|
||||
String blockIndent, lastLineIndent;
|
||||
if (CodeHelpers::getIndentForCurrentBlock (pos, getTabString (getTabSize()), blockIndent, lastLineIndent))
|
||||
{
|
||||
GenericCodeEditorComponent::insertTextAtCaret (blockIndent);
|
||||
|
||||
if (newText == "{")
|
||||
insertTabAtCaret();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GenericCodeEditorComponent::insertTextAtCaret (newText);
|
||||
}
|
||||
|
||||
void CppCodeEditorComponent::addPopupMenuItems (PopupMenu& menu, const MouseEvent* e)
|
||||
{
|
||||
GenericCodeEditorComponent::addPopupMenuItems (menu, e);
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addItem (insertComponentID, TRANS("Insert code for a new Component class..."));
|
||||
}
|
||||
|
||||
void CppCodeEditorComponent::performPopupMenuAction (int menuItemID)
|
||||
{
|
||||
if (menuItemID == insertComponentID)
|
||||
insertComponentClass();
|
||||
|
||||
GenericCodeEditorComponent::performPopupMenuAction (menuItemID);
|
||||
}
|
||||
|
||||
void CppCodeEditorComponent::insertComponentClass()
|
||||
{
|
||||
asyncAlertWindow = std::make_unique<AlertWindow> (TRANS ("Insert a new Component class"),
|
||||
TRANS ("Please enter a name for the new class"),
|
||||
MessageBoxIconType::NoIcon,
|
||||
nullptr);
|
||||
|
||||
const String classNameField { "Class Name" };
|
||||
|
||||
asyncAlertWindow->addTextEditor (classNameField, String(), String(), false);
|
||||
asyncAlertWindow->addButton (TRANS ("Insert Code"), 1, KeyPress (KeyPress::returnKey));
|
||||
asyncAlertWindow->addButton (TRANS ("Cancel"), 0, KeyPress (KeyPress::escapeKey));
|
||||
|
||||
asyncAlertWindow->enterModalState (true,
|
||||
ModalCallbackFunction::create ([parent = SafePointer<CppCodeEditorComponent> { this }, classNameField] (int result)
|
||||
{
|
||||
if (parent == nullptr)
|
||||
return;
|
||||
|
||||
auto& aw = *(parent->asyncAlertWindow);
|
||||
|
||||
aw.exitModalState (result);
|
||||
aw.setVisible (false);
|
||||
|
||||
if (result == 0)
|
||||
return;
|
||||
|
||||
auto className = aw.getTextEditorContents (classNameField).trim();
|
||||
|
||||
if (className == build_tools::makeValidIdentifier (className, false, true, false))
|
||||
{
|
||||
String code (BinaryData::jucer_InlineComponentTemplate_h);
|
||||
code = code.replace ("%%component_class%%", className);
|
||||
|
||||
parent->insertTextAtCaret (code);
|
||||
return;
|
||||
}
|
||||
|
||||
parent->insertComponentClass();
|
||||
}));
|
||||
}
|
245
deps/juce/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.h
vendored
Normal file
@ -0,0 +1,245 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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_DocumentEditorComponent.h"
|
||||
|
||||
//==============================================================================
|
||||
class SourceCodeDocument : public OpenDocumentManager::Document
|
||||
{
|
||||
public:
|
||||
SourceCodeDocument (Project*, const File&);
|
||||
|
||||
bool loadedOk() const override { return true; }
|
||||
bool isForFile (const File& file) const override { return getFile() == file; }
|
||||
bool isForNode (const ValueTree&) const override { return false; }
|
||||
bool refersToProject (Project& p) const override { return project == &p; }
|
||||
Project* getProject() const override { return project; }
|
||||
String getName() const override { return getFile().getFileName(); }
|
||||
String getType() const override { return getFile().getFileExtension() + " file"; }
|
||||
File getFile() const override { return modDetector.getFile(); }
|
||||
bool needsSaving() const override { return codeDoc != nullptr && codeDoc->hasChangedSinceSavePoint(); }
|
||||
bool hasFileBeenModifiedExternally() override { return modDetector.hasBeenModified(); }
|
||||
void fileHasBeenRenamed (const File& newFile) override { modDetector.fileHasBeenRenamed (newFile); }
|
||||
String getState() const override { return lastState != nullptr ? lastState->toString() : String(); }
|
||||
void restoreState (const String& state) override { lastState.reset (new CodeEditorComponent::State (state)); }
|
||||
|
||||
File getCounterpartFile() const override
|
||||
{
|
||||
auto file = getFile();
|
||||
|
||||
if (file.hasFileExtension (sourceFileExtensions))
|
||||
{
|
||||
static const char* extensions[] = { "h", "hpp", "hxx", "hh", nullptr };
|
||||
return findCounterpart (file, extensions);
|
||||
}
|
||||
|
||||
if (file.hasFileExtension (headerFileExtensions))
|
||||
{
|
||||
static const char* extensions[] = { "cpp", "mm", "cc", "cxx", "c", "m", nullptr };
|
||||
return findCounterpart (file, extensions);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
static File findCounterpart (const File& file, const char** extensions)
|
||||
{
|
||||
while (*extensions != nullptr)
|
||||
{
|
||||
auto f = file.withFileExtension (*extensions++);
|
||||
|
||||
if (f.existsAsFile())
|
||||
return f;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void reloadFromFile() override;
|
||||
bool saveSyncWithoutAsking() override;
|
||||
void saveAsync (std::function<void (bool)>) override;
|
||||
void saveAsAsync (std::function<void (bool)>) override;
|
||||
|
||||
std::unique_ptr<Component> createEditor() override;
|
||||
std::unique_ptr<Component> createViewer() override { return createEditor(); }
|
||||
|
||||
void updateLastState (CodeEditorComponent&);
|
||||
void applyLastState (CodeEditorComponent&) const;
|
||||
|
||||
CodeDocument& getCodeDocument();
|
||||
|
||||
//==============================================================================
|
||||
struct Type : public OpenDocumentManager::DocumentType
|
||||
{
|
||||
bool canOpenFile (const File& file) override
|
||||
{
|
||||
if (file.hasFileExtension (sourceOrHeaderFileExtensions)
|
||||
|| file.hasFileExtension ("txt;inc;tcc;xml;plist;rtf;html;htm;php;py;rb;cs"))
|
||||
return true;
|
||||
|
||||
MemoryBlock mb;
|
||||
if (file.loadFileAsData (mb)
|
||||
&& seemsToBeText (static_cast<const char*> (mb.getData()), (int) mb.getSize())
|
||||
&& ! file.hasFileExtension ("svg"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool seemsToBeText (const char* const chars, const int num) noexcept
|
||||
{
|
||||
for (int i = 0; i < num; ++i)
|
||||
{
|
||||
const char c = chars[i];
|
||||
if ((c < 32 && c != '\t' && c != '\r' && c != '\n') || chars[i] > 126)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Document* openFile (Project* p, const File& file) override { return new SourceCodeDocument (p, file); }
|
||||
};
|
||||
|
||||
protected:
|
||||
FileModificationDetector modDetector;
|
||||
std::unique_ptr<CodeDocument> codeDoc;
|
||||
Project* project;
|
||||
|
||||
std::unique_ptr<CodeEditorComponent::State> lastState;
|
||||
|
||||
void reloadInternal();
|
||||
|
||||
private:
|
||||
std::unique_ptr<FileChooser> chooser;
|
||||
};
|
||||
|
||||
class GenericCodeEditorComponent;
|
||||
|
||||
//==============================================================================
|
||||
class SourceCodeEditor : public DocumentEditorComponent,
|
||||
private ValueTree::Listener,
|
||||
private CodeDocument::Listener
|
||||
{
|
||||
public:
|
||||
SourceCodeEditor (OpenDocumentManager::Document*, CodeDocument&);
|
||||
SourceCodeEditor (OpenDocumentManager::Document*, GenericCodeEditorComponent*);
|
||||
~SourceCodeEditor() override;
|
||||
|
||||
void scrollToKeepRangeOnScreen (Range<int> range);
|
||||
void highlight (Range<int> range, bool cursorAtStart);
|
||||
|
||||
std::unique_ptr<GenericCodeEditorComponent> editor;
|
||||
|
||||
private:
|
||||
void resized() override;
|
||||
void lookAndFeelChanged() override;
|
||||
|
||||
void valueTreePropertyChanged (ValueTree&, const Identifier&) override;
|
||||
void valueTreeChildAdded (ValueTree&, ValueTree&) override;
|
||||
void valueTreeChildRemoved (ValueTree&, ValueTree&, int) override;
|
||||
void valueTreeChildOrderChanged (ValueTree&, int, int) override;
|
||||
void valueTreeParentChanged (ValueTree&) override;
|
||||
void valueTreeRedirected (ValueTree&) override;
|
||||
|
||||
void codeDocumentTextInserted (const String&, int) override;
|
||||
void codeDocumentTextDeleted (int, int) override;
|
||||
|
||||
void setEditor (GenericCodeEditorComponent*);
|
||||
void updateColourScheme();
|
||||
void checkSaveState();
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SourceCodeEditor)
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class GenericCodeEditorComponent : public CodeEditorComponent
|
||||
{
|
||||
public:
|
||||
GenericCodeEditorComponent (const File&, CodeDocument&, CodeTokeniser*);
|
||||
~GenericCodeEditorComponent() override;
|
||||
|
||||
void addPopupMenuItems (PopupMenu&, const MouseEvent*) override;
|
||||
void performPopupMenuAction (int menuItemID) override;
|
||||
|
||||
void getAllCommands (Array<CommandID>&) override;
|
||||
void getCommandInfo (CommandID, ApplicationCommandInfo&) override;
|
||||
bool perform (const InvocationInfo&) override;
|
||||
|
||||
void showFindPanel();
|
||||
void hideFindPanel();
|
||||
void findSelection();
|
||||
void findNext (bool forwards, bool skipCurrentSelection);
|
||||
void handleEscapeKey() override;
|
||||
void editorViewportPositionChanged() override;
|
||||
|
||||
void resized() override;
|
||||
|
||||
static String getSearchString() { return getAppSettings().getGlobalProperties().getValue ("searchString"); }
|
||||
static void setSearchString (const String& s) { getAppSettings().getGlobalProperties().setValue ("searchString", s); }
|
||||
static bool isCaseSensitiveSearch() { return getAppSettings().getGlobalProperties().getBoolValue ("searchCaseSensitive"); }
|
||||
static void setCaseSensitiveSearch (bool b) { getAppSettings().getGlobalProperties().setValue ("searchCaseSensitive", b); }
|
||||
|
||||
struct Listener
|
||||
{
|
||||
virtual ~Listener() {}
|
||||
virtual void codeEditorViewportMoved (CodeEditorComponent&) = 0;
|
||||
};
|
||||
|
||||
void addListener (Listener* listener);
|
||||
void removeListener (Listener* listener);
|
||||
|
||||
private:
|
||||
File file;
|
||||
class FindPanel;
|
||||
std::unique_ptr<FindPanel> findPanel;
|
||||
ListenerList<Listener> listeners;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GenericCodeEditorComponent)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class CppCodeEditorComponent : public GenericCodeEditorComponent
|
||||
{
|
||||
public:
|
||||
CppCodeEditorComponent (const File&, CodeDocument&);
|
||||
~CppCodeEditorComponent() override;
|
||||
|
||||
void addPopupMenuItems (PopupMenu&, const MouseEvent*) override;
|
||||
void performPopupMenuAction (int menuItemID) override;
|
||||
|
||||
void handleReturnKey() override;
|
||||
void insertTextAtCaret (const String& newText) override;
|
||||
|
||||
private:
|
||||
void insertComponentClass();
|
||||
|
||||
std::unique_ptr<AlertWindow> asyncAlertWindow;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CppCodeEditorComponent)
|
||||
};
|
389
deps/juce/extras/Projucer/Source/ComponentEditor/Components/jucer_ButtonHandler.h
vendored
Normal file
@ -0,0 +1,389 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 ButtonHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
ButtonHandler (const String& typeDescription_,
|
||||
const String& className_,
|
||||
const std::type_info& componentClass,
|
||||
const int defaultWidth_,
|
||||
const int defaultHeight_)
|
||||
: ComponentTypeHandler (typeDescription_, className_, componentClass,
|
||||
defaultWidth_, defaultHeight_)
|
||||
{}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* b = dynamic_cast<Button*> (component))
|
||||
{
|
||||
props.add (new ButtonTextProperty (b, document));
|
||||
|
||||
props.add (new ButtonCallbackProperty (b, document));
|
||||
|
||||
props.add (new ButtonRadioGroupProperty (b, document));
|
||||
|
||||
props.add (new ButtonConnectedEdgeProperty ("connected left", Button::ConnectedOnLeft, b, document));
|
||||
props.add (new ButtonConnectedEdgeProperty ("connected right", Button::ConnectedOnRight, b, document));
|
||||
props.add (new ButtonConnectedEdgeProperty ("connected top", Button::ConnectedOnTop, b, document));
|
||||
props.add (new ButtonConnectedEdgeProperty ("connected bottom", Button::ConnectedOnBottom, b, document));
|
||||
}
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
Button* const b = dynamic_cast<Button*> (comp);
|
||||
|
||||
XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout);
|
||||
e->setAttribute ("buttonText", b->getButtonText());
|
||||
e->setAttribute ("connectedEdges", b->getConnectedEdgeFlags());
|
||||
e->setAttribute ("needsCallback", needsButtonListener (b));
|
||||
e->setAttribute ("radioGroupId", b->getRadioGroupId());
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
Button* const b = dynamic_cast<Button*> (comp);
|
||||
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
b->setButtonText (xml.getStringAttribute ("buttonText", b->getButtonText()));
|
||||
b->setConnectedEdges (xml.getIntAttribute ("connectedEdges", 0));
|
||||
setNeedsButtonListener (b, xml.getBoolAttribute ("needsCallback", true));
|
||||
b->setRadioGroupId (xml.getIntAttribute ("radioGroupId", 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* component) override
|
||||
{
|
||||
return quotedString (component->getName(), false);
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
Button* const b = dynamic_cast<Button*> (component);
|
||||
|
||||
if (b->getButtonText() != b->getName())
|
||||
{
|
||||
code.constructorCode
|
||||
<< memberVariableName << "->setButtonText ("
|
||||
<< quotedString (b->getButtonText(), code.shouldUseTransMacro()) << ");\n";
|
||||
}
|
||||
|
||||
if (b->getConnectedEdgeFlags() != 0)
|
||||
{
|
||||
StringArray flags;
|
||||
|
||||
if (b->isConnectedOnLeft())
|
||||
flags.add ("juce::Button::ConnectedOnLeft");
|
||||
|
||||
if (b->isConnectedOnRight())
|
||||
flags.add ("juce::Button::ConnectedOnRight");
|
||||
|
||||
if (b->isConnectedOnTop())
|
||||
flags.add ("juce::Button::ConnectedOnTop");
|
||||
|
||||
if (b->isConnectedOnBottom())
|
||||
flags.add ("juce::Button::ConnectedOnBottom");
|
||||
|
||||
String s;
|
||||
s << memberVariableName << "->setConnectedEdges ("
|
||||
<< flags.joinIntoString (" | ") << ");\n";
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
|
||||
if (b->getRadioGroupId() != 0)
|
||||
code.constructorCode << memberVariableName << "->setRadioGroupId ("
|
||||
<< b->getRadioGroupId() << ");\n";
|
||||
|
||||
if (needsButtonListener (component))
|
||||
code.constructorCode << memberVariableName << "->addListener (this);\n";
|
||||
}
|
||||
|
||||
void fillInGeneratedCode (Component* component, GeneratedCode& code) override
|
||||
{
|
||||
ComponentTypeHandler::fillInGeneratedCode (component, code);
|
||||
|
||||
if (needsButtonListener (component))
|
||||
{
|
||||
String& callback = code.getCallbackCode ("public juce::Button::Listener",
|
||||
"void",
|
||||
"buttonClicked (juce::Button* buttonThatWasClicked)",
|
||||
true);
|
||||
|
||||
if (callback.isNotEmpty())
|
||||
callback << "else ";
|
||||
|
||||
const String memberVariableName (code.document->getComponentLayout()->getComponentMemberVariableName (component));
|
||||
const String userCodeComment ("UserButtonCode_" + memberVariableName);
|
||||
|
||||
callback
|
||||
<< "if (buttonThatWasClicked == " << memberVariableName << ".get())\n"
|
||||
<< "{\n //[" << userCodeComment << "] -- add your button handler code here..\n //[/" << userCodeComment << "]\n}\n";
|
||||
}
|
||||
}
|
||||
|
||||
static bool needsButtonListener (Component* button)
|
||||
{
|
||||
return button->getProperties().getWithDefault ("generateListenerCallback", true);
|
||||
}
|
||||
|
||||
static void setNeedsButtonListener (Component* button, const bool shouldDoCallback)
|
||||
{
|
||||
button->getProperties().set ("generateListenerCallback", shouldDoCallback);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class ButtonTextProperty : public ComponentTextProperty <Button>
|
||||
{
|
||||
public:
|
||||
ButtonTextProperty (Button* button_, JucerDocument& doc)
|
||||
: ComponentTextProperty <Button> ("text", 100, false, button_, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ButtonTextChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change button text");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getButtonText();
|
||||
}
|
||||
|
||||
private:
|
||||
class ButtonTextChangeAction : public ComponentUndoableAction <Button>
|
||||
{
|
||||
public:
|
||||
ButtonTextChangeAction (Button* const comp, ComponentLayout& l, const String& newName_)
|
||||
: ComponentUndoableAction <Button> (comp, l),
|
||||
newName (newName_)
|
||||
{
|
||||
oldName = comp->getButtonText();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setButtonText (newName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setButtonText (oldName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
|
||||
class ButtonCallbackProperty : public ComponentBooleanProperty <Button>
|
||||
{
|
||||
public:
|
||||
ButtonCallbackProperty (Button* b, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <Button> ("callback", "Generate ButtonListener", "Generate ButtonListener", b, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new ButtonCallbackChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change button callback");
|
||||
}
|
||||
|
||||
bool getState() const { return needsButtonListener (component); }
|
||||
|
||||
private:
|
||||
class ButtonCallbackChangeAction : public ComponentUndoableAction <Button>
|
||||
{
|
||||
public:
|
||||
ButtonCallbackChangeAction (Button* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <Button> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = needsButtonListener (comp);
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
setNeedsButtonListener (getComponent(), newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
setNeedsButtonListener (getComponent(), oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
class ButtonRadioGroupProperty : public ComponentTextProperty <Button>
|
||||
{
|
||||
public:
|
||||
ButtonRadioGroupProperty (Button* const button_, JucerDocument& doc)
|
||||
: ComponentTextProperty <Button> ("radio group", 10, false, button_, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ButtonRadioGroupChangeAction (component, *document.getComponentLayout(), newText.getIntValue()),
|
||||
"Change radio group ID");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return String (component->getRadioGroupId());
|
||||
}
|
||||
|
||||
private:
|
||||
class ButtonRadioGroupChangeAction : public ComponentUndoableAction <Button>
|
||||
{
|
||||
public:
|
||||
ButtonRadioGroupChangeAction (Button* const comp, ComponentLayout& l, const int newId_)
|
||||
: ComponentUndoableAction <Button> (comp, l),
|
||||
newId (newId_)
|
||||
{
|
||||
oldId = comp->getRadioGroupId();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setRadioGroupId (newId);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setRadioGroupId (oldId);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
int newId, oldId;
|
||||
};
|
||||
};
|
||||
|
||||
class ButtonConnectedEdgeProperty : public ComponentBooleanProperty <Button>
|
||||
{
|
||||
public:
|
||||
ButtonConnectedEdgeProperty (const String& name, const int flag_,
|
||||
Button* b, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <Button> (name, "Connected", "Connected", b, doc),
|
||||
flag (flag_)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new ButtonConnectedChangeAction (component, *document.getComponentLayout(), flag, newState),
|
||||
"Change button connected edges");
|
||||
}
|
||||
|
||||
bool getState() const
|
||||
{
|
||||
return (component->getConnectedEdgeFlags() & flag) != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
const int flag;
|
||||
|
||||
class ButtonConnectedChangeAction : public ComponentUndoableAction <Button>
|
||||
{
|
||||
public:
|
||||
ButtonConnectedChangeAction (Button* const comp, ComponentLayout& l, const int flag_, const bool newState_)
|
||||
: ComponentUndoableAction <Button> (comp, l),
|
||||
flag (flag_),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = ((comp->getConnectedEdgeFlags() & flag) != 0);
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
|
||||
if (newState)
|
||||
getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() | flag);
|
||||
else
|
||||
getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() & ~flag);
|
||||
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
|
||||
if (oldState)
|
||||
getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() | flag);
|
||||
else
|
||||
getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() & ~flag);
|
||||
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
const int flag;
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
446
deps/juce/extras/Projucer/Source/ComponentEditor/Components/jucer_ComboBoxHandler.h
vendored
Normal file
@ -0,0 +1,446 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 ComboBoxHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
ComboBoxHandler()
|
||||
: ComponentTypeHandler ("Combo Box", "juce::ComboBox", typeid (ComboBox), 150, 24)
|
||||
{}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new ComboBox ("new combo box");
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
if (auto* const c = dynamic_cast<ComboBox*> (comp))
|
||||
{
|
||||
if (auto* e = ComponentTypeHandler::createXmlFor (comp, layout))
|
||||
{
|
||||
e->setAttribute ("editable", c->isTextEditable());
|
||||
e->setAttribute ("layout", c->getJustificationType().getFlags());
|
||||
e->setAttribute ("items", c->getProperties() ["items"].toString());
|
||||
e->setAttribute ("textWhenNonSelected", c->getTextWhenNothingSelected());
|
||||
e->setAttribute ("textWhenNoItems", c->getTextWhenNoChoicesAvailable());
|
||||
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
ComboBox defaultBox;
|
||||
|
||||
if (ComboBox* const c = dynamic_cast<ComboBox*> (comp))
|
||||
{
|
||||
c->setEditableText (xml.getBoolAttribute ("editable", defaultBox.isTextEditable()));
|
||||
c->setJustificationType (Justification (xml.getIntAttribute ("layout", defaultBox.getJustificationType().getFlags())));
|
||||
c->getProperties().set ("items", xml.getStringAttribute ("items", String()));
|
||||
c->setTextWhenNothingSelected (xml.getStringAttribute ("textWhenNonSelected", defaultBox.getTextWhenNothingSelected()));
|
||||
c->setTextWhenNoChoicesAvailable (xml.getStringAttribute ("textWhenNoItems", defaultBox.getTextWhenNoChoicesAvailable()));
|
||||
|
||||
updateItems (c);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* c = dynamic_cast<ComboBox*> (component))
|
||||
{
|
||||
props.add (new ComboItemsProperty (c, document));
|
||||
props.add (new ComboEditableProperty (c, document));
|
||||
props.add (new ComboJustificationProperty (c, document));
|
||||
props.add (new ComboTextWhenNoneSelectedProperty (c, document));
|
||||
props.add (new ComboTextWhenNoItemsProperty (c, document));
|
||||
}
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* component) override
|
||||
{
|
||||
return quotedString (component->getName(), false);
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
ComboBox* const c = dynamic_cast<ComboBox*> (component);
|
||||
|
||||
if (c == nullptr)
|
||||
{
|
||||
jassertfalse;
|
||||
return;
|
||||
}
|
||||
|
||||
String s;
|
||||
s << memberVariableName << "->setEditableText (" << CodeHelpers::boolLiteral (c->isTextEditable()) << ");\n"
|
||||
<< memberVariableName << "->setJustificationType (" << CodeHelpers::justificationToCode (c->getJustificationType()) << ");\n"
|
||||
<< memberVariableName << "->setTextWhenNothingSelected (" << quotedString (c->getTextWhenNothingSelected(), code.shouldUseTransMacro()) << ");\n"
|
||||
<< memberVariableName << "->setTextWhenNoChoicesAvailable (" << quotedString (c->getTextWhenNoChoicesAvailable(), code.shouldUseTransMacro()) << ");\n";
|
||||
|
||||
StringArray lines;
|
||||
lines.addLines (c->getProperties() ["items"].toString());
|
||||
int itemId = 1;
|
||||
|
||||
for (int i = 0; i < lines.size(); ++i)
|
||||
{
|
||||
if (lines[i].trim().isEmpty())
|
||||
s << memberVariableName << "->addSeparator();\n";
|
||||
else
|
||||
s << memberVariableName << "->addItem ("
|
||||
<< quotedString (lines[i], code.shouldUseTransMacro()) << ", " << itemId++ << ");\n";
|
||||
}
|
||||
|
||||
if (needsCallback (component))
|
||||
s << memberVariableName << "->addListener (this);\n";
|
||||
|
||||
s << '\n';
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
|
||||
void fillInGeneratedCode (Component* component, GeneratedCode& code) override
|
||||
{
|
||||
ComponentTypeHandler::fillInGeneratedCode (component, code);
|
||||
|
||||
if (needsCallback (component))
|
||||
{
|
||||
String& callback = code.getCallbackCode ("public juce::ComboBox::Listener",
|
||||
"void",
|
||||
"comboBoxChanged (juce::ComboBox* comboBoxThatHasChanged)",
|
||||
true);
|
||||
|
||||
if (callback.trim().isNotEmpty())
|
||||
callback << "else ";
|
||||
|
||||
const String memberVariableName (code.document->getComponentLayout()->getComponentMemberVariableName (component));
|
||||
const String userCodeComment ("UserComboBoxCode_" + memberVariableName);
|
||||
|
||||
callback
|
||||
<< "if (comboBoxThatHasChanged == " << memberVariableName << ".get())\n"
|
||||
<< "{\n //[" << userCodeComment << "] -- add your combo box handling code here..\n //[/" << userCodeComment << "]\n}\n";
|
||||
}
|
||||
}
|
||||
|
||||
static void updateItems (ComboBox* c)
|
||||
{
|
||||
StringArray lines;
|
||||
lines.addLines (c->getProperties() ["items"].toString());
|
||||
|
||||
c->clear();
|
||||
int itemId = 1;
|
||||
|
||||
for (int i = 0; i < lines.size(); ++i)
|
||||
{
|
||||
if (lines[i].trim().isEmpty())
|
||||
c->addSeparator();
|
||||
else
|
||||
c->addItem (lines[i], itemId++);
|
||||
}
|
||||
}
|
||||
|
||||
static bool needsCallback (Component*)
|
||||
{
|
||||
return true; // xxx should be configurable
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboEditableProperty : public ComponentBooleanProperty <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboEditableProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <ComboBox> ("editable", "Text is editable", "Text is editable", comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new ComboEditableChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change combo box editability");
|
||||
}
|
||||
|
||||
bool getState() const
|
||||
{
|
||||
return component->isTextEditable();
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboEditableChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboEditableChangeAction (ComboBox* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->isTextEditable();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setEditableText (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setEditableText (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComboJustificationProperty : public JustificationProperty
|
||||
{
|
||||
public:
|
||||
ComboJustificationProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: JustificationProperty ("text layout", false),
|
||||
component (comp),
|
||||
document (doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setJustification (Justification newJustification)
|
||||
{
|
||||
document.perform (new ComboJustifyChangeAction (component, *document.getComponentLayout(), newJustification),
|
||||
"Change combo box justification");
|
||||
}
|
||||
|
||||
Justification getJustification() const { return component->getJustificationType(); }
|
||||
|
||||
private:
|
||||
ComboBox* const component;
|
||||
JucerDocument& document;
|
||||
|
||||
class ComboJustifyChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboJustifyChangeAction (ComboBox* const comp, ComponentLayout& l, Justification newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_),
|
||||
oldState (comp->getJustificationType())
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setJustificationType (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setJustificationType (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
Justification newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComboItemsProperty : public ComponentTextProperty <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboItemsProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <ComboBox> ("items", 10000, true, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ComboItemsChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change combo box items");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getProperties() ["items"];
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboItemsChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboItemsChangeAction (ComboBox* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getProperties() ["items"];
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->getProperties().set ("items", newState);
|
||||
ComboBoxHandler::updateItems (getComponent());
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->getProperties().set ("items", oldState);
|
||||
ComboBoxHandler::updateItems (getComponent());
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComboTextWhenNoneSelectedProperty : public ComponentTextProperty <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboTextWhenNoneSelectedProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <ComboBox> ("text when none selected", 200, false, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ComboNonSelTextChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change combo box text when nothing selected");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getTextWhenNothingSelected();
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboNonSelTextChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboNonSelTextChangeAction (ComboBox* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getTextWhenNothingSelected();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextWhenNothingSelected (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextWhenNothingSelected (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComboTextWhenNoItemsProperty : public ComponentTextProperty <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboTextWhenNoItemsProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <ComboBox> ("text when no items", 200, false, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ComboNoItemTextChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change combo box 'no items' text");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getTextWhenNoChoicesAvailable();
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboNoItemTextChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboNoItemTextChangeAction (ComboBox* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getTextWhenNoChoicesAvailable();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextWhenNoChoicesAvailable (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextWhenNoChoicesAvailable (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
178
deps/juce/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentNameProperty.h
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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_ComponentTypeHandler.h"
|
||||
#include "jucer_ComponentUndoableAction.h"
|
||||
#include "../Properties/jucer_ComponentTextProperty.h"
|
||||
|
||||
//==============================================================================
|
||||
class ComponentNameProperty : public ComponentTextProperty <Component>
|
||||
{
|
||||
public:
|
||||
ComponentNameProperty (Component* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <Component> ("name", 40, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new CompNameChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change component name");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getName();
|
||||
}
|
||||
|
||||
private:
|
||||
class CompNameChangeAction : public ComponentUndoableAction <Component>
|
||||
{
|
||||
public:
|
||||
CompNameChangeAction (Component* const comp, ComponentLayout& l, const String& nm)
|
||||
: ComponentUndoableAction <Component> (comp, l),
|
||||
newName (nm), oldName (comp->getName())
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setName (newName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setName (oldName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComponentMemberNameProperty : public ComponentTextProperty <Component>
|
||||
{
|
||||
public:
|
||||
ComponentMemberNameProperty (Component* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <Component> ("member name", 40, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new CompMemberNameChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change component member name");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return document.getComponentLayout()->getComponentMemberVariableName (component);
|
||||
}
|
||||
|
||||
private:
|
||||
class CompMemberNameChangeAction : public ComponentUndoableAction <Component>
|
||||
{
|
||||
public:
|
||||
CompMemberNameChangeAction (Component* const comp, ComponentLayout& l, const String& nm)
|
||||
: ComponentUndoableAction <Component> (comp, l),
|
||||
newName (nm), oldName (layout.getComponentMemberVariableName (comp))
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
layout.setComponentMemberVariableName (getComponent(), newName);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
layout.setComponentMemberVariableName (getComponent(), oldName);
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class ComponentVirtualClassProperty : public ComponentTextProperty <Component>
|
||||
{
|
||||
public:
|
||||
ComponentVirtualClassProperty (Component* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <Component> ("virtual class", 40, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new CompVirtualClassChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change component virtual class name");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return document.getComponentLayout()->getComponentVirtualClassName (component);
|
||||
}
|
||||
|
||||
private:
|
||||
class CompVirtualClassChangeAction : public ComponentUndoableAction <Component>
|
||||
{
|
||||
public:
|
||||
CompVirtualClassChangeAction (Component* const comp, ComponentLayout& l, const String& nm)
|
||||
: ComponentUndoableAction <Component> (comp, l),
|
||||
newName (nm), oldName (layout.getComponentVirtualClassName (comp))
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
layout.setComponentVirtualClassName (getComponent(), newName);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
layout.setComponentVirtualClassName (getComponent(), oldName);
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
638
deps/juce/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentTypeHandler.cpp
vendored
Normal file
@ -0,0 +1,638 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 "../../Application/jucer_Headers.h"
|
||||
#include "../../Application/jucer_Application.h"
|
||||
#include "../jucer_ObjectTypes.h"
|
||||
#include "../jucer_UtilityFunctions.h"
|
||||
#include "../UI/jucer_JucerCommandIDs.h"
|
||||
#include "../UI/jucer_ComponentOverlayComponent.h"
|
||||
#include "jucer_ComponentNameProperty.h"
|
||||
#include "../Properties/jucer_PositionPropertyBase.h"
|
||||
#include "../Properties/jucer_ComponentColourProperty.h"
|
||||
#include "../UI/jucer_TestComponent.h"
|
||||
|
||||
static String getTypeInfoName (const std::type_info& info)
|
||||
{
|
||||
#if JUCE_MSVC
|
||||
return info.raw_name();
|
||||
#else
|
||||
return info.name();
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
ComponentTypeHandler::ComponentTypeHandler (const String& typeName_,
|
||||
const String& className_,
|
||||
const std::type_info& componentClass_,
|
||||
const int defaultWidth_,
|
||||
const int defaultHeight_)
|
||||
: typeName (typeName_),
|
||||
className (className_),
|
||||
componentClassRawName (getTypeInfoName (componentClass_)),
|
||||
defaultWidth (defaultWidth_),
|
||||
defaultHeight (defaultHeight_)
|
||||
{
|
||||
}
|
||||
|
||||
Component* ComponentTypeHandler::createCopyOf (JucerDocument* document, Component& existing)
|
||||
{
|
||||
jassert (getHandlerFor (existing) == this);
|
||||
|
||||
Component* const newOne = createNewComponent (document);
|
||||
std::unique_ptr<XmlElement> xml (createXmlFor (&existing, document->getComponentLayout()));
|
||||
|
||||
if (xml != nullptr)
|
||||
restoreFromXml (*xml, newOne, document->getComponentLayout());
|
||||
|
||||
return newOne;
|
||||
}
|
||||
|
||||
ComponentOverlayComponent* ComponentTypeHandler::createOverlayComponent (Component* child, ComponentLayout& layout)
|
||||
{
|
||||
return new ComponentOverlayComponent (child, layout);
|
||||
}
|
||||
|
||||
static void dummyMenuCallback (int, int) {}
|
||||
|
||||
void ComponentTypeHandler::showPopupMenu (Component*, ComponentLayout& layout)
|
||||
{
|
||||
PopupMenu m;
|
||||
|
||||
ApplicationCommandManager* commandManager = &ProjucerApplication::getCommandManager();
|
||||
|
||||
m.addCommandItem (commandManager, JucerCommandIDs::toFront);
|
||||
m.addCommandItem (commandManager, JucerCommandIDs::toBack);
|
||||
m.addSeparator();
|
||||
|
||||
if (layout.getSelectedSet().getNumSelected() > 1)
|
||||
{
|
||||
m.addCommandItem (commandManager, JucerCommandIDs::alignTop);
|
||||
m.addCommandItem (commandManager, JucerCommandIDs::alignRight);
|
||||
m.addCommandItem (commandManager, JucerCommandIDs::alignBottom);
|
||||
m.addCommandItem (commandManager, JucerCommandIDs::alignLeft);
|
||||
m.addSeparator();
|
||||
}
|
||||
|
||||
m.addCommandItem (commandManager, StandardApplicationCommandIDs::cut);
|
||||
m.addCommandItem (commandManager, StandardApplicationCommandIDs::copy);
|
||||
m.addCommandItem (commandManager, StandardApplicationCommandIDs::paste);
|
||||
m.addCommandItem (commandManager, StandardApplicationCommandIDs::del);
|
||||
|
||||
m.showMenuAsync (PopupMenu::Options(),
|
||||
ModalCallbackFunction::create (dummyMenuCallback, 0));
|
||||
}
|
||||
|
||||
JucerDocument* ComponentTypeHandler::findParentDocument (Component* component)
|
||||
{
|
||||
Component* p = component->getParentComponent();
|
||||
|
||||
while (p != nullptr)
|
||||
{
|
||||
if (JucerDocumentEditor* const ed = dynamic_cast<JucerDocumentEditor*> (p))
|
||||
return ed->getDocument();
|
||||
|
||||
if (TestComponent* const t = dynamic_cast<TestComponent*> (p))
|
||||
return t->getDocument();
|
||||
|
||||
p = p->getParentComponent();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool ComponentTypeHandler::canHandle (Component& component) const
|
||||
{
|
||||
return componentClassRawName == getTypeInfoName (typeid (component));
|
||||
}
|
||||
|
||||
ComponentTypeHandler* ComponentTypeHandler::getHandlerFor (Component& component)
|
||||
{
|
||||
for (int i = 0; i < ObjectTypes::numComponentTypes; ++i)
|
||||
if (ObjectTypes::componentTypeHandlers[i]->canHandle (component))
|
||||
return ObjectTypes::componentTypeHandlers[i];
|
||||
|
||||
jassertfalse;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ComponentTypeHandler* ComponentTypeHandler::getHandlerForXmlTag (const String& tagName)
|
||||
{
|
||||
for (int i = 0; i < ObjectTypes::numComponentTypes; ++i)
|
||||
if (ObjectTypes::componentTypeHandlers[i]->getXmlTagName().equalsIgnoreCase (tagName))
|
||||
return ObjectTypes::componentTypeHandlers[i];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
XmlElement* ComponentTypeHandler::createXmlFor (Component* comp, const ComponentLayout* layout)
|
||||
{
|
||||
XmlElement* e = new XmlElement (getXmlTagName());
|
||||
|
||||
e->setAttribute ("name", comp->getName());
|
||||
e->setAttribute ("id", String::toHexString (getComponentId (comp)));
|
||||
e->setAttribute ("memberName", comp->getProperties() ["memberName"].toString());
|
||||
e->setAttribute ("virtualName", comp->getProperties() ["virtualName"].toString());
|
||||
e->setAttribute ("explicitFocusOrder", comp->getExplicitFocusOrder());
|
||||
|
||||
RelativePositionedRectangle pos (getComponentPosition (comp));
|
||||
pos.updateFromComponent (*comp, layout);
|
||||
pos.applyToXml (*e);
|
||||
|
||||
if (SettableTooltipClient* const ttc = dynamic_cast<SettableTooltipClient*> (comp))
|
||||
if (ttc->getTooltip().isNotEmpty())
|
||||
e->setAttribute ("tooltip", ttc->getTooltip());
|
||||
|
||||
for (int i = 0; i < colours.size(); ++i)
|
||||
{
|
||||
if (comp->isColourSpecified (colours[i]->colourId))
|
||||
{
|
||||
e->setAttribute (colours[i]->xmlTagName,
|
||||
comp->findColour (colours[i]->colourId).toString());
|
||||
}
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool ComponentTypeHandler::restoreFromXml (const XmlElement& xml,
|
||||
Component* comp,
|
||||
const ComponentLayout* layout)
|
||||
{
|
||||
jassert (xml.hasTagName (getXmlTagName()));
|
||||
|
||||
if (! xml.hasTagName (getXmlTagName()))
|
||||
return false;
|
||||
|
||||
comp->setName (xml.getStringAttribute ("name", comp->getName()));
|
||||
setComponentId (comp, xml.getStringAttribute ("id").getHexValue64());
|
||||
comp->getProperties().set ("memberName", xml.getStringAttribute ("memberName"));
|
||||
comp->getProperties().set ("virtualName", xml.getStringAttribute ("virtualName"));
|
||||
comp->setExplicitFocusOrder (xml.getIntAttribute ("explicitFocusOrder"));
|
||||
|
||||
RelativePositionedRectangle currentPos (getComponentPosition (comp));
|
||||
currentPos.updateFromComponent (*comp, layout);
|
||||
|
||||
RelativePositionedRectangle rpr;
|
||||
rpr.restoreFromXml (xml, currentPos);
|
||||
|
||||
jassert (layout != nullptr);
|
||||
setComponentPosition (comp, rpr, layout);
|
||||
|
||||
if (SettableTooltipClient* const ttc = dynamic_cast<SettableTooltipClient*> (comp))
|
||||
ttc->setTooltip (xml.getStringAttribute ("tooltip"));
|
||||
|
||||
for (int i = 0; i < colours.size(); ++i)
|
||||
{
|
||||
const String col (xml.getStringAttribute (colours[i]->xmlTagName, String()));
|
||||
|
||||
if (col.isNotEmpty())
|
||||
comp->setColour (colours[i]->colourId, Colour::fromString (col));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int64 ComponentTypeHandler::getComponentId (Component* comp)
|
||||
{
|
||||
if (comp == nullptr)
|
||||
return 0;
|
||||
|
||||
int64 compId = comp->getProperties() ["jucerCompId"].toString().getHexValue64();
|
||||
|
||||
if (compId == 0)
|
||||
{
|
||||
compId = Random::getSystemRandom().nextInt64();
|
||||
setComponentId (comp, compId);
|
||||
}
|
||||
|
||||
return compId;
|
||||
}
|
||||
|
||||
void ComponentTypeHandler::setComponentId (Component* comp, const int64 newID)
|
||||
{
|
||||
jassert (comp != nullptr);
|
||||
if (newID != 0)
|
||||
comp->getProperties().set ("jucerCompId", String::toHexString (newID));
|
||||
}
|
||||
|
||||
RelativePositionedRectangle ComponentTypeHandler::getComponentPosition (Component* comp)
|
||||
{
|
||||
RelativePositionedRectangle rp;
|
||||
rp.rect = PositionedRectangle (comp->getProperties() ["pos"]);
|
||||
rp.relativeToX = comp->getProperties() ["relativeToX"].toString().getHexValue64();
|
||||
rp.relativeToY = comp->getProperties() ["relativeToY"].toString().getHexValue64();
|
||||
rp.relativeToW = comp->getProperties() ["relativeToW"].toString().getHexValue64();
|
||||
rp.relativeToH = comp->getProperties() ["relativeToH"].toString().getHexValue64();
|
||||
|
||||
return rp;
|
||||
}
|
||||
|
||||
void ComponentTypeHandler::setComponentPosition (Component* comp,
|
||||
const RelativePositionedRectangle& newPos,
|
||||
const ComponentLayout* layout)
|
||||
{
|
||||
comp->getProperties().set ("pos", newPos.rect.toString());
|
||||
comp->getProperties().set ("relativeToX", String::toHexString (newPos.relativeToX));
|
||||
comp->getProperties().set ("relativeToY", String::toHexString (newPos.relativeToY));
|
||||
comp->getProperties().set ("relativeToW", String::toHexString (newPos.relativeToW));
|
||||
comp->getProperties().set ("relativeToH", String::toHexString (newPos.relativeToH));
|
||||
|
||||
comp->setBounds (newPos.getRectangle (Rectangle<int> (0, 0, comp->getParentWidth(), comp->getParentHeight()),
|
||||
layout));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class TooltipProperty : public ComponentTextProperty <Component>
|
||||
{
|
||||
public:
|
||||
TooltipProperty (Component* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty<Component> ("tooltip", 1024, true, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
SettableTooltipClient* ttc = dynamic_cast<SettableTooltipClient*> (component);
|
||||
return ttc->getTooltip();
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new SetTooltipAction (component, *document.getComponentLayout(), newText),
|
||||
"Change tooltip");
|
||||
}
|
||||
|
||||
private:
|
||||
class SetTooltipAction : public ComponentUndoableAction <Component>
|
||||
{
|
||||
public:
|
||||
SetTooltipAction (Component* const comp, ComponentLayout& l, const String& newValue_)
|
||||
: ComponentUndoableAction<Component> (comp, l),
|
||||
newValue (newValue_)
|
||||
{
|
||||
SettableTooltipClient* ttc = dynamic_cast<SettableTooltipClient*> (comp);
|
||||
jassert (ttc != nullptr);
|
||||
oldValue = ttc->getTooltip();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
|
||||
if (SettableTooltipClient* ttc = dynamic_cast<SettableTooltipClient*> (getComponent()))
|
||||
{
|
||||
ttc->setTooltip (newValue);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
|
||||
if (SettableTooltipClient* ttc = dynamic_cast<SettableTooltipClient*> (getComponent()))
|
||||
{
|
||||
ttc->setTooltip (oldValue);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
String newValue, oldValue;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComponentPositionProperty : public PositionPropertyBase
|
||||
{
|
||||
public:
|
||||
ComponentPositionProperty (Component* comp,
|
||||
JucerDocument& doc,
|
||||
const String& name,
|
||||
ComponentPositionDimension dimension_)
|
||||
: PositionPropertyBase (comp, name, dimension_,
|
||||
true, true,
|
||||
doc.getComponentLayout()),
|
||||
document (doc)
|
||||
{
|
||||
document.addChangeListener (this);
|
||||
}
|
||||
|
||||
~ComponentPositionProperty()
|
||||
{
|
||||
document.removeChangeListener (this);
|
||||
}
|
||||
|
||||
void setPosition (const RelativePositionedRectangle& newPos)
|
||||
{
|
||||
auto* l = document.getComponentLayout();
|
||||
|
||||
if (l->getSelectedSet().getNumSelected() > 1)
|
||||
positionOtherSelectedComponents (ComponentTypeHandler::getComponentPosition (component), newPos);
|
||||
|
||||
l->setComponentPosition (component, newPos, true);
|
||||
}
|
||||
|
||||
RelativePositionedRectangle getPosition() const
|
||||
{
|
||||
return ComponentTypeHandler::getComponentPosition (component);
|
||||
}
|
||||
|
||||
private:
|
||||
JucerDocument& document;
|
||||
|
||||
void positionOtherSelectedComponents (const RelativePositionedRectangle& oldPos, const RelativePositionedRectangle& newPos)
|
||||
{
|
||||
for (auto* s : document.getComponentLayout()->getSelectedSet())
|
||||
{
|
||||
if (s != component)
|
||||
{
|
||||
auto currentPos = ComponentTypeHandler::getComponentPosition (s);
|
||||
auto diff = 0.0;
|
||||
|
||||
if (dimension == ComponentPositionDimension::componentX)
|
||||
{
|
||||
diff = newPos.rect.getX() - oldPos.rect.getX();
|
||||
currentPos.rect.setX (currentPos.rect.getX() + diff);
|
||||
}
|
||||
else if (dimension == ComponentPositionDimension::componentY)
|
||||
{
|
||||
diff = newPos.rect.getY() - oldPos.rect.getY();
|
||||
currentPos.rect.setY (currentPos.rect.getY() + diff);
|
||||
}
|
||||
else if (dimension == ComponentPositionDimension::componentWidth)
|
||||
{
|
||||
diff = newPos.rect.getWidth() - oldPos.rect.getWidth();
|
||||
currentPos.rect.setWidth (currentPos.rect.getWidth() + diff);
|
||||
}
|
||||
else if (dimension == ComponentPositionDimension::componentHeight)
|
||||
{
|
||||
diff = newPos.rect.getHeight() - oldPos.rect.getHeight();
|
||||
currentPos.rect.setHeight (currentPos.rect.getHeight() + diff);
|
||||
}
|
||||
|
||||
document.getComponentLayout()->setComponentPosition (s, currentPos, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class FocusOrderProperty : public ComponentTextProperty <Component>
|
||||
{
|
||||
public:
|
||||
FocusOrderProperty (Component* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <Component> ("focus order", 8, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return String (component->getExplicitFocusOrder());
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new SetFocusOrderAction (component, *document.getComponentLayout(), jmax (0, newText.getIntValue())),
|
||||
"Change focus order");
|
||||
}
|
||||
|
||||
private:
|
||||
class SetFocusOrderAction : public ComponentUndoableAction <Component>
|
||||
{
|
||||
public:
|
||||
SetFocusOrderAction (Component* const comp, ComponentLayout& l, const int newOrder_)
|
||||
: ComponentUndoableAction <Component> (comp, l),
|
||||
newValue (newOrder_)
|
||||
{
|
||||
oldValue = comp->getExplicitFocusOrder();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setExplicitFocusOrder (newValue);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setExplicitFocusOrder (oldValue);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
int newValue, oldValue;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
void ComponentTypeHandler::getEditableProperties (Component* component,
|
||||
JucerDocument& document,
|
||||
Array<PropertyComponent*>& props,
|
||||
bool multipleSelected)
|
||||
{
|
||||
if (! multipleSelected)
|
||||
{
|
||||
props.add (new ComponentMemberNameProperty (component, document));
|
||||
props.add (new ComponentNameProperty (component, document));
|
||||
props.add (new ComponentVirtualClassProperty (component, document));
|
||||
|
||||
if (dynamic_cast<SettableTooltipClient*> (component) != nullptr)
|
||||
props.add (new TooltipProperty (component, document));
|
||||
|
||||
props.add (new FocusOrderProperty (component, document));
|
||||
}
|
||||
|
||||
props.add (new ComponentPositionProperty (component, document, "x", ComponentPositionProperty::componentX));
|
||||
props.add (new ComponentPositionProperty (component, document, "y", ComponentPositionProperty::componentY));
|
||||
props.add (new ComponentPositionProperty (component, document, "width", ComponentPositionProperty::componentWidth));
|
||||
props.add (new ComponentPositionProperty (component, document, "height", ComponentPositionProperty::componentHeight));
|
||||
}
|
||||
|
||||
void ComponentTypeHandler::addPropertiesToPropertyPanel (Component* comp, JucerDocument& document,
|
||||
PropertyPanel& panel, bool multipleSelected)
|
||||
{
|
||||
Array <PropertyComponent*> props;
|
||||
getEditableProperties (comp, document, props, multipleSelected);
|
||||
|
||||
panel.addSection (getClassName (comp), props);
|
||||
}
|
||||
|
||||
void ComponentTypeHandler::registerEditableColour (int colourId,
|
||||
const String& colourIdCode,
|
||||
const String& colourName, const String& xmlTagName)
|
||||
{
|
||||
ComponentColourInfo* const c = new ComponentColourInfo();
|
||||
|
||||
c->colourId = colourId;
|
||||
c->colourIdCode = colourIdCode;
|
||||
c->colourName = colourName;
|
||||
c->xmlTagName = xmlTagName;
|
||||
|
||||
colours.add (c);
|
||||
}
|
||||
|
||||
void ComponentTypeHandler::addColourProperties (Component* component,
|
||||
JucerDocument& document,
|
||||
Array<PropertyComponent*>& props)
|
||||
{
|
||||
for (int i = 0; i < colours.size(); ++i)
|
||||
props.add (new ComponentColourIdProperty (component, document,
|
||||
colours[i]->colourId,
|
||||
colours[i]->colourName,
|
||||
true));
|
||||
}
|
||||
|
||||
String ComponentTypeHandler::getColourIntialisationCode (Component* component,
|
||||
const String& objectName)
|
||||
{
|
||||
String s;
|
||||
|
||||
for (int i = 0; i < colours.size(); ++i)
|
||||
{
|
||||
if (component->isColourSpecified (colours[i]->colourId))
|
||||
{
|
||||
s << objectName << "->setColour ("
|
||||
<< colours[i]->colourIdCode
|
||||
<< ", "
|
||||
<< CodeHelpers::colourToCode (component->findColour (colours[i]->colourId))
|
||||
<< ");\n";
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void ComponentTypeHandler::fillInGeneratedCode (Component* component, GeneratedCode& code)
|
||||
{
|
||||
const String memberVariableName (code.document->getComponentLayout()->getComponentMemberVariableName (component));
|
||||
|
||||
fillInMemberVariableDeclarations (code, component, memberVariableName);
|
||||
fillInCreationCode (code, component, memberVariableName);
|
||||
fillInDeletionCode (code, component, memberVariableName);
|
||||
fillInResizeCode (code, component, memberVariableName);
|
||||
}
|
||||
|
||||
void ComponentTypeHandler::fillInMemberVariableDeclarations (GeneratedCode& code, Component* component, const String& memberVariableName)
|
||||
{
|
||||
String clsName (component->getProperties() ["virtualName"].toString());
|
||||
|
||||
if (clsName.isNotEmpty())
|
||||
clsName = build_tools::makeValidIdentifier (clsName, false, false, true);
|
||||
else
|
||||
clsName = getClassName (component);
|
||||
|
||||
code.privateMemberDeclarations
|
||||
<< "std::unique_ptr<" << clsName << "> " << memberVariableName << ";\n";
|
||||
}
|
||||
|
||||
void ComponentTypeHandler::fillInResizeCode (GeneratedCode& code, Component* component, const String& memberVariableName)
|
||||
{
|
||||
const RelativePositionedRectangle pos (getComponentPosition (component));
|
||||
|
||||
String x, y, w, h, r;
|
||||
positionToCode (pos, code.document->getComponentLayout(), x, y, w, h);
|
||||
|
||||
r << memberVariableName << "->setBounds ("
|
||||
<< x << ", " << y << ", " << w << ", " << h << ");\n";
|
||||
|
||||
if (pos.rect.isPositionAbsolute() && ! code.document->getComponentLayout()->isComponentPositionRelative (component))
|
||||
code.constructorCode += r + "\n";
|
||||
else
|
||||
code.getCallbackCode (String(), "void", "resized()", false) += r;
|
||||
}
|
||||
|
||||
String ComponentTypeHandler::getCreationParameters (GeneratedCode&, Component*)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
void ComponentTypeHandler::fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName)
|
||||
{
|
||||
String params (getCreationParameters (code, component));
|
||||
const String virtualName (component->getProperties() ["virtualName"].toString());
|
||||
|
||||
String s;
|
||||
s << memberVariableName << ".reset (new ";
|
||||
|
||||
if (virtualName.isNotEmpty())
|
||||
s << build_tools::makeValidIdentifier (virtualName, false, false, true);
|
||||
else
|
||||
s << getClassName (component);
|
||||
|
||||
if (params.isEmpty())
|
||||
{
|
||||
s << "());\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
StringArray lines;
|
||||
lines.addLines (params);
|
||||
|
||||
params = lines.joinIntoString ("\n" + String::repeatedString (" ", s.length() + 2));
|
||||
|
||||
s << " (" << params << "));\n";
|
||||
}
|
||||
|
||||
s << "addAndMakeVisible (" << memberVariableName << ".get());\n";
|
||||
|
||||
|
||||
if (auto* ttc = dynamic_cast<SettableTooltipClient*> (component))
|
||||
{
|
||||
if (ttc->getTooltip().isNotEmpty())
|
||||
{
|
||||
s << memberVariableName << "->setTooltip ("
|
||||
<< quotedString (ttc->getTooltip(), code.shouldUseTransMacro())
|
||||
<< ");\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (component != nullptr && component->getExplicitFocusOrder() > 0)
|
||||
s << memberVariableName << "->setExplicitFocusOrder ("
|
||||
<< component->getExplicitFocusOrder()
|
||||
<< ");\n";
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
|
||||
void ComponentTypeHandler::fillInDeletionCode (GeneratedCode& code, Component*,
|
||||
const String& memberVariableName)
|
||||
{
|
||||
code.destructorCode
|
||||
<< memberVariableName << " = nullptr;\n";
|
||||
}
|
147
deps/juce/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentTypeHandler.h
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 ComponentOverlayComponent;
|
||||
class ComponentLayout;
|
||||
#include "../jucer_GeneratedCode.h"
|
||||
#include "../UI/jucer_RelativePositionedRectangle.h"
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Base class for handlers that can understand the properties of all the component classes.
|
||||
*/
|
||||
class ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
ComponentTypeHandler (const String& typeDescription_,
|
||||
const String& className_,
|
||||
const std::type_info& componentClass,
|
||||
const int defaultWidth_,
|
||||
const int defaultHeight_);
|
||||
|
||||
virtual ~ComponentTypeHandler() {}
|
||||
|
||||
//==============================================================================
|
||||
virtual bool canHandle (Component& component) const;
|
||||
|
||||
static ComponentTypeHandler* getHandlerFor (Component& component);
|
||||
|
||||
//==============================================================================
|
||||
virtual String getXmlTagName() const noexcept
|
||||
{
|
||||
if (className.startsWith ("juce::"))
|
||||
return className.substring (6).toUpperCase();
|
||||
|
||||
return className.toUpperCase();
|
||||
}
|
||||
|
||||
static ComponentTypeHandler* getHandlerForXmlTag (const String& tagName);
|
||||
|
||||
virtual XmlElement* createXmlFor (Component* component, const ComponentLayout* layout);
|
||||
virtual bool restoreFromXml (const XmlElement& xml, Component* component, const ComponentLayout* layout);
|
||||
|
||||
virtual void getEditableProperties (Component* component,
|
||||
JucerDocument& document,
|
||||
Array<PropertyComponent*>& props,
|
||||
bool multipleSelected);
|
||||
|
||||
virtual void addPropertiesToPropertyPanel (Component* component,
|
||||
JucerDocument& document,
|
||||
PropertyPanel& panel,
|
||||
bool multipleSelected);
|
||||
|
||||
|
||||
void registerEditableColour (int colourId,
|
||||
const String& colourIdCode,
|
||||
const String& colourName,
|
||||
const String& xmlTagName);
|
||||
|
||||
#define registerColour(colourId, colourName, xmlTagName) \
|
||||
registerEditableColour (colourId, #colourId, colourName, xmlTagName)
|
||||
|
||||
void addColourProperties (Component* component,
|
||||
JucerDocument& document,
|
||||
Array<PropertyComponent*>& props);
|
||||
|
||||
String getColourIntialisationCode (Component* component,
|
||||
const String& objectName);
|
||||
|
||||
//==============================================================================
|
||||
virtual Component* createNewComponent (JucerDocument*) = 0;
|
||||
|
||||
virtual Component* createCopyOf (JucerDocument*, Component& existing);
|
||||
|
||||
virtual ComponentOverlayComponent* createOverlayComponent (Component* child, ComponentLayout& layout);
|
||||
|
||||
virtual void showPopupMenu (Component* component,
|
||||
ComponentLayout& layout);
|
||||
|
||||
//==============================================================================
|
||||
// Code-generation methods:
|
||||
|
||||
virtual void fillInGeneratedCode (Component* component, GeneratedCode& code);
|
||||
|
||||
virtual void fillInMemberVariableDeclarations (GeneratedCode&, Component*, const String& memberVariableName);
|
||||
virtual void fillInResizeCode (GeneratedCode&, Component*, const String& memberVariableName);
|
||||
virtual void fillInCreationCode (GeneratedCode&, Component*, const String& memberVariableName);
|
||||
virtual String getCreationParameters (GeneratedCode&, Component*);
|
||||
virtual void fillInDeletionCode (GeneratedCode&, Component*, const String& memberVariableName);
|
||||
|
||||
//==============================================================================
|
||||
const String& getTypeName() const noexcept { return typeName; }
|
||||
virtual String getClassName (Component*) const { return className; }
|
||||
|
||||
int getDefaultWidth() const noexcept { return defaultWidth; }
|
||||
int getDefaultHeight() const noexcept { return defaultHeight; }
|
||||
|
||||
static int64 getComponentId (Component* comp);
|
||||
static void setComponentId (Component* comp, const int64 newID);
|
||||
|
||||
static RelativePositionedRectangle getComponentPosition (Component* comp);
|
||||
static void setComponentPosition (Component* comp,
|
||||
const RelativePositionedRectangle& newPos,
|
||||
const ComponentLayout* layout);
|
||||
|
||||
static JucerDocument* findParentDocument (Component* component);
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
const String typeName, className, virtualClass, componentClassRawName;
|
||||
int defaultWidth, defaultHeight;
|
||||
|
||||
struct ComponentColourInfo
|
||||
{
|
||||
int colourId;
|
||||
String colourIdCode, colourName, xmlTagName;
|
||||
};
|
||||
|
||||
OwnedArray<ComponentColourInfo> colours;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE (ComponentTypeHandler)
|
||||
};
|
75
deps/juce/extras/Projucer/Source/ComponentEditor/Components/jucer_ComponentUndoableAction.h
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 "../UI/jucer_JucerDocumentEditor.h"
|
||||
|
||||
//==============================================================================
|
||||
template <class ComponentType>
|
||||
class ComponentUndoableAction : public UndoableAction
|
||||
{
|
||||
public:
|
||||
ComponentUndoableAction (ComponentType* const comp,
|
||||
ComponentLayout& layout_)
|
||||
: layout (layout_),
|
||||
componentIndex (layout_.indexOfComponent (comp))
|
||||
{
|
||||
jassert (comp != nullptr);
|
||||
jassert (componentIndex >= 0);
|
||||
}
|
||||
|
||||
ComponentType* getComponent() const
|
||||
{
|
||||
ComponentType* const c = dynamic_cast<ComponentType*> (layout.getComponent (componentIndex));
|
||||
jassert (c != nullptr);
|
||||
return c;
|
||||
}
|
||||
|
||||
int getSizeInUnits() { return 2; }
|
||||
|
||||
protected:
|
||||
ComponentLayout& layout;
|
||||
const int componentIndex;
|
||||
|
||||
void changed() const
|
||||
{
|
||||
jassert (layout.getDocument() != nullptr);
|
||||
layout.getDocument()->changed();
|
||||
}
|
||||
|
||||
void showCorrectTab() const
|
||||
{
|
||||
if (JucerDocumentEditor* const ed = JucerDocumentEditor::getActiveDocumentHolder())
|
||||
ed->showLayout();
|
||||
|
||||
if (layout.getSelectedSet().getNumSelected() == 0)
|
||||
if (ComponentType* const c = dynamic_cast<ComponentType*> (layout.getComponent (componentIndex)))
|
||||
layout.getSelectedSet().selectOnly (getComponent());
|
||||
}
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentUndoableAction)
|
||||
};
|
241
deps/juce/extras/Projucer/Source/ComponentEditor/Components/jucer_GenericComponentHandler.h
vendored
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 GenericComponent : public Component
|
||||
{
|
||||
public:
|
||||
GenericComponent()
|
||||
: Component ("new component"),
|
||||
actualClassName ("juce::Component")
|
||||
{
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (Colours::white.withAlpha (0.25f));
|
||||
|
||||
g.setColour (Colours::black.withAlpha (0.5f));
|
||||
g.drawRect (getLocalBounds());
|
||||
g.drawLine (0.0f, 0.0f, (float) getWidth(), (float) getHeight());
|
||||
g.drawLine (0.0f, (float) getHeight(), (float) getWidth(), 0.0f);
|
||||
|
||||
g.setFont (14.0f);
|
||||
g.drawText (actualClassName, 0, 0, getWidth(), getHeight() / 2, Justification::centred, true);
|
||||
}
|
||||
|
||||
void setClassName (const String& newName)
|
||||
{
|
||||
if (actualClassName != newName)
|
||||
{
|
||||
actualClassName = newName;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void setParams (const String& newParams)
|
||||
{
|
||||
if (constructorParams != newParams)
|
||||
{
|
||||
constructorParams = newParams;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
String actualClassName, constructorParams;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class GenericComponentHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
GenericComponentHandler()
|
||||
: ComponentTypeHandler ("Generic Component", "GenericComponent", typeid (GenericComponent), 150, 24)
|
||||
{}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new GenericComponent();
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout);
|
||||
e->setAttribute ("class", ((GenericComponent*) comp)->actualClassName);
|
||||
e->setAttribute ("params", ((GenericComponent*) comp)->constructorParams);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
((GenericComponent*) comp)->actualClassName = xml.getStringAttribute ("class", "juce::Component");
|
||||
((GenericComponent*) comp)->constructorParams = xml.getStringAttribute ("params", String());
|
||||
return true;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
props.add (new GenericCompClassProperty (dynamic_cast<GenericComponent*> (component), document));
|
||||
props.add (new GenericCompParamsProperty (dynamic_cast<GenericComponent*> (component), document));
|
||||
}
|
||||
|
||||
String getClassName (Component* comp) const override
|
||||
{
|
||||
return static_cast<GenericComponent*> (comp)->actualClassName;
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* comp) override
|
||||
{
|
||||
return static_cast<GenericComponent*> (comp)->constructorParams;
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
if (component->getName().isNotEmpty())
|
||||
code.constructorCode
|
||||
<< memberVariableName << "->setName ("
|
||||
<< quotedString (component->getName(), false)
|
||||
<< ");\n\n";
|
||||
else
|
||||
code.constructorCode << "\n";
|
||||
}
|
||||
|
||||
private:
|
||||
class GenericCompClassProperty : public ComponentTextProperty <GenericComponent>
|
||||
{
|
||||
public:
|
||||
GenericCompClassProperty (GenericComponent* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <GenericComponent> ("class", 300, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new GenericCompClassChangeAction (component, *document.getComponentLayout(),
|
||||
build_tools::makeValidIdentifier (newText, false, false, true)),
|
||||
"Change generic component class");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->actualClassName;
|
||||
}
|
||||
|
||||
private:
|
||||
class GenericCompClassChangeAction : public ComponentUndoableAction <GenericComponent>
|
||||
{
|
||||
public:
|
||||
GenericCompClassChangeAction (GenericComponent* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <GenericComponent> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->actualClassName;
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setClassName (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setClassName (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
class GenericCompParamsProperty : public ComponentTextProperty <GenericComponent>
|
||||
{
|
||||
public:
|
||||
GenericCompParamsProperty (GenericComponent* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <GenericComponent> ("constructor params", 1024, true, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new GenericCompParamsChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change generic component class");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->constructorParams;
|
||||
}
|
||||
|
||||
private:
|
||||
class GenericCompParamsChangeAction : public ComponentUndoableAction <GenericComponent>
|
||||
{
|
||||
public:
|
||||
GenericCompParamsChangeAction (GenericComponent* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <GenericComponent> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->constructorParams;
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setParams (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setParams (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
237
deps/juce/extras/Projucer/Source/ComponentEditor/Components/jucer_GroupComponentHandler.h
vendored
Normal file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 GroupComponentHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
GroupComponentHandler()
|
||||
: ComponentTypeHandler ("Group Box", "juce::GroupComponent", typeid (GroupComponent), 200, 150)
|
||||
{
|
||||
registerColour (juce::GroupComponent::outlineColourId, "outline", "outlinecol");
|
||||
registerColour (juce::GroupComponent::textColourId, "text", "textcol");
|
||||
}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new GroupComponent ("new group", "group");
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
GroupComponent* const g = (GroupComponent*) comp;
|
||||
|
||||
XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout);
|
||||
e->setAttribute ("title", g->getText());
|
||||
|
||||
GroupComponent defaultComp;
|
||||
|
||||
if (g->getTextLabelPosition().getFlags() != defaultComp.getTextLabelPosition().getFlags())
|
||||
e->setAttribute ("textpos", g->getTextLabelPosition().getFlags());
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
GroupComponent* const g = (GroupComponent*) comp;
|
||||
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
g->setText (xml.getStringAttribute ("title", g->getText()));
|
||||
g->setTextLabelPosition (Justification (xml.getIntAttribute ("textpos", g->getTextLabelPosition().getFlags())));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode& code, Component* component) override
|
||||
{
|
||||
GroupComponent* g = dynamic_cast<GroupComponent*> (component);
|
||||
|
||||
return quotedString (component->getName(), false)
|
||||
+ ",\n"
|
||||
+ quotedString (g->getText(), code.shouldUseTransMacro());
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
GroupComponent* const g = dynamic_cast<GroupComponent*> (component);
|
||||
|
||||
String s;
|
||||
|
||||
GroupComponent defaultComp;
|
||||
|
||||
if (g->getTextLabelPosition().getFlags() != defaultComp.getTextLabelPosition().getFlags())
|
||||
{
|
||||
s << memberVariableName << "->setTextLabelPosition ("
|
||||
<< CodeHelpers::justificationToCode (g->getTextLabelPosition())
|
||||
<< ");\n";
|
||||
}
|
||||
|
||||
s << getColourIntialisationCode (component, memberVariableName)
|
||||
<< '\n';
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* gc = dynamic_cast<GroupComponent*> (component))
|
||||
{
|
||||
props.add (new GroupTitleProperty (gc, document));
|
||||
props.add (new GroupJustificationProperty (gc, document));
|
||||
}
|
||||
|
||||
addColourProperties (component, document, props);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class GroupTitleProperty : public ComponentTextProperty <GroupComponent>
|
||||
{
|
||||
public:
|
||||
GroupTitleProperty (GroupComponent* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <GroupComponent> ("text", 200, false, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new GroupTitleChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change group title");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getText();
|
||||
}
|
||||
|
||||
private:
|
||||
class GroupTitleChangeAction : public ComponentUndoableAction <GroupComponent>
|
||||
{
|
||||
public:
|
||||
GroupTitleChangeAction (GroupComponent* const comp, ComponentLayout& l, const String& newName_)
|
||||
: ComponentUndoableAction <GroupComponent> (comp, l),
|
||||
newName (newName_)
|
||||
{
|
||||
oldName = comp->getText();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setText (newName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setText (oldName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class GroupJustificationProperty : public JustificationProperty,
|
||||
private ChangeListener
|
||||
{
|
||||
public:
|
||||
GroupJustificationProperty (GroupComponent* const group_, JucerDocument& doc)
|
||||
: JustificationProperty ("layout", true),
|
||||
group (group_),
|
||||
document (doc)
|
||||
{
|
||||
document.addChangeListener (this);
|
||||
}
|
||||
|
||||
~GroupJustificationProperty() override
|
||||
{
|
||||
document.removeChangeListener (this);
|
||||
}
|
||||
|
||||
void setJustification (Justification newJustification) override
|
||||
{
|
||||
document.perform (new GroupJustifyChangeAction (group, *document.getComponentLayout(), newJustification),
|
||||
"Change text label position");
|
||||
}
|
||||
|
||||
Justification getJustification() const override
|
||||
{
|
||||
return group->getTextLabelPosition();
|
||||
}
|
||||
|
||||
private:
|
||||
void changeListenerCallback (ChangeBroadcaster*) override { refresh(); }
|
||||
|
||||
GroupComponent* const group;
|
||||
JucerDocument& document;
|
||||
|
||||
class GroupJustifyChangeAction : public ComponentUndoableAction <GroupComponent>
|
||||
{
|
||||
public:
|
||||
GroupJustifyChangeAction (GroupComponent* const comp, ComponentLayout& l, Justification newState_)
|
||||
: ComponentUndoableAction <GroupComponent> (comp, l),
|
||||
newState (newState_),
|
||||
oldState (comp->getTextLabelPosition())
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextLabelPosition (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextLabelPosition (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
Justification newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|