migrating to the latest JUCE version

This commit is contained in:
2022-11-04 23:11:33 +01:00
committed by Nikolai Rodionov
parent 4257a0f8ba
commit faf8f18333
2796 changed files with 888518 additions and 784244 deletions

View File

@ -1,301 +1,301 @@
/*
==============================================================================
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_CodeHelpers.h"
//==============================================================================
namespace CodeHelpers
{
String indent (const String& code, const int numSpaces, bool indentFirstLine)
{
if (numSpaces == 0)
return code;
auto space = String::repeatedString (" ", numSpaces);
auto lines = StringArray::fromLines (code);
for (auto& line : lines)
{
if (! indentFirstLine)
{
indentFirstLine = true;
continue;
}
if (line.trimEnd().isNotEmpty())
line = space + line;
}
return lines.joinIntoString (newLine);
}
String unindent (const String& code, const int numSpaces)
{
if (numSpaces == 0)
return code;
auto space = String::repeatedString (" ", numSpaces);
auto lines = StringArray::fromLines (code);
for (auto& line : lines)
if (line.startsWith (space))
line = line.substring (numSpaces);
return lines.joinIntoString (newLine);
}
String createIncludeStatement (const File& includeFile, const File& targetFile)
{
return createIncludeStatement (build_tools::unixStylePath (build_tools::getRelativePathFrom (includeFile, targetFile.getParentDirectory())));
}
String createIncludeStatement (const String& includePath)
{
if (includePath.startsWithChar ('<') || includePath.startsWithChar ('"'))
return "#include " + includePath;
return "#include \"" + includePath + "\"";
}
String createIncludePathIncludeStatement (const String& includedFilename)
{
return "#include <" + includedFilename + ">";
}
String stringLiteral (const String& text, int maxLineLength)
{
if (text.isEmpty())
return "juce::String()";
StringArray lines;
{
auto t = text.getCharPointer();
bool finished = t.isEmpty();
while (! finished)
{
for (auto startOfLine = t;;)
{
switch (t.getAndAdvance())
{
case 0: finished = true; break;
case '\n': break;
case '\r': if (*t == '\n') ++t; break;
default: continue;
}
lines.add (String (startOfLine, t));
break;
}
}
}
if (maxLineLength > 0)
{
for (int i = 0; i < lines.size(); ++i)
{
auto& line = lines.getReference (i);
if (line.length() > maxLineLength)
{
const String start (line.substring (0, maxLineLength));
const String end (line.substring (maxLineLength));
line = start;
lines.insert (i + 1, end);
}
}
}
for (int i = 0; i < lines.size(); ++i)
lines.getReference(i) = CppTokeniserFunctions::addEscapeChars (lines.getReference(i));
lines.removeEmptyStrings();
for (int i = 0; i < lines.size(); ++i)
lines.getReference(i) = "\"" + lines.getReference(i) + "\"";
String result (lines.joinIntoString (newLine));
if (! CharPointer_ASCII::isValidString (text.toUTF8(), std::numeric_limits<int>::max()))
result = "juce::CharPointer_UTF8 (" + result + ")";
return result;
}
String alignFunctionCallParams (const String& call, const StringArray& parameters, const int maxLineLength)
{
String result, currentLine (call);
for (int i = 0; i < parameters.size(); ++i)
{
if (currentLine.length() >= maxLineLength)
{
result += currentLine.trimEnd() + newLine;
currentLine = String::repeatedString (" ", call.length()) + parameters[i];
}
else
{
currentLine += parameters[i];
}
if (i < parameters.size() - 1)
currentLine << ", ";
}
return result + currentLine.trimEnd() + ")";
}
String floatLiteral (double value, int numDecPlaces)
{
String s (value, numDecPlaces);
if (s.containsChar ('.'))
s << 'f';
else
s << ".0f";
return s;
}
String boolLiteral (bool value)
{
return value ? "true" : "false";
}
String colourToCode (Colour col)
{
const Colour colours[] =
{
#define COL(col) Colours::col,
#include "jucer_Colours.h"
#undef COL
Colours::transparentBlack
};
static const char* colourNames[] =
{
#define COL(col) #col,
#include "jucer_Colours.h"
#undef COL
nullptr
};
for (int i = 0; i < numElementsInArray (colourNames) - 1; ++i)
if (col == colours[i])
return "juce::Colours::" + String (colourNames[i]);
return "juce::Colour (0x" + build_tools::hexString8Digits ((int) col.getARGB()) + ')';
}
String justificationToCode (Justification justification)
{
switch (justification.getFlags())
{
case Justification::centred: return "juce::Justification::centred";
case Justification::centredLeft: return "juce::Justification::centredLeft";
case Justification::centredRight: return "juce::Justification::centredRight";
case Justification::centredTop: return "juce::Justification::centredTop";
case Justification::centredBottom: return "juce::Justification::centredBottom";
case Justification::topLeft: return "juce::Justification::topLeft";
case Justification::topRight: return "juce::Justification::topRight";
case Justification::bottomLeft: return "juce::Justification::bottomLeft";
case Justification::bottomRight: return "juce::Justification::bottomRight";
case Justification::left: return "juce::Justification::left";
case Justification::right: return "juce::Justification::right";
case Justification::horizontallyCentred: return "juce::Justification::horizontallyCentred";
case Justification::top: return "juce::Justification::top";
case Justification::bottom: return "juce::Justification::bottom";
case Justification::verticallyCentred: return "juce::Justification::verticallyCentred";
case Justification::horizontallyJustified: return "juce::Justification::horizontallyJustified";
default: break;
}
jassertfalse;
return "Justification (" + String (justification.getFlags()) + ")";
}
//==============================================================================
String getLeadingWhitespace (String line)
{
line = line.removeCharacters (line.endsWith ("\r\n") ? "\r\n" : "\n");
auto endOfLeadingWS = line.getCharPointer().findEndOfWhitespace();
return String (line.getCharPointer(), endOfLeadingWS);
}
int getBraceCount (String::CharPointerType line)
{
int braces = 0;
for (;;)
{
const juce_wchar c = line.getAndAdvance();
if (c == 0) break;
else if (c == '{') ++braces;
else if (c == '}') --braces;
else if (c == '/') { if (*line == '/') break; }
else if (c == '"' || c == '\'') { while (! (line.isEmpty() || line.getAndAdvance() == c)) {} }
}
return braces;
}
bool getIndentForCurrentBlock (CodeDocument::Position pos, const String& tab,
String& blockIndent, String& lastLineIndent)
{
int braceCount = 0;
bool indentFound = false;
while (pos.getLineNumber() > 0)
{
pos = pos.movedByLines (-1);
auto line = pos.getLineText();
auto trimmedLine = line.trimStart();
braceCount += getBraceCount (trimmedLine.getCharPointer());
if (braceCount > 0)
{
blockIndent = getLeadingWhitespace (line);
if (! indentFound)
lastLineIndent = blockIndent + tab;
return true;
}
if ((! indentFound) && trimmedLine.isNotEmpty())
{
indentFound = true;
lastLineIndent = getLeadingWhitespace (line);
}
}
return false;
}
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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_CodeHelpers.h"
//==============================================================================
namespace CodeHelpers
{
String indent (const String& code, const int numSpaces, bool indentFirstLine)
{
if (numSpaces == 0)
return code;
auto space = String::repeatedString (" ", numSpaces);
auto lines = StringArray::fromLines (code);
for (auto& line : lines)
{
if (! indentFirstLine)
{
indentFirstLine = true;
continue;
}
if (line.trimEnd().isNotEmpty())
line = space + line;
}
return lines.joinIntoString (newLine);
}
String unindent (const String& code, const int numSpaces)
{
if (numSpaces == 0)
return code;
auto space = String::repeatedString (" ", numSpaces);
auto lines = StringArray::fromLines (code);
for (auto& line : lines)
if (line.startsWith (space))
line = line.substring (numSpaces);
return lines.joinIntoString (newLine);
}
String createIncludeStatement (const File& includeFile, const File& targetFile)
{
return createIncludeStatement (build_tools::unixStylePath (build_tools::getRelativePathFrom (includeFile, targetFile.getParentDirectory())));
}
String createIncludeStatement (const String& includePath)
{
if (includePath.startsWithChar ('<') || includePath.startsWithChar ('"'))
return "#include " + includePath;
return "#include \"" + includePath + "\"";
}
String createIncludePathIncludeStatement (const String& includedFilename)
{
return "#include <" + includedFilename + ">";
}
String stringLiteral (const String& text, int maxLineLength)
{
if (text.isEmpty())
return "juce::String()";
StringArray lines;
{
auto t = text.getCharPointer();
bool finished = t.isEmpty();
while (! finished)
{
for (auto startOfLine = t;;)
{
switch (t.getAndAdvance())
{
case 0: finished = true; break;
case '\n': break;
case '\r': if (*t == '\n') ++t; break;
default: continue;
}
lines.add (String (startOfLine, t));
break;
}
}
}
if (maxLineLength > 0)
{
for (int i = 0; i < lines.size(); ++i)
{
auto& line = lines.getReference (i);
if (line.length() > maxLineLength)
{
const String start (line.substring (0, maxLineLength));
const String end (line.substring (maxLineLength));
line = start;
lines.insert (i + 1, end);
}
}
}
for (int i = 0; i < lines.size(); ++i)
lines.getReference(i) = CppTokeniserFunctions::addEscapeChars (lines.getReference(i));
lines.removeEmptyStrings();
for (int i = 0; i < lines.size(); ++i)
lines.getReference(i) = "\"" + lines.getReference(i) + "\"";
String result (lines.joinIntoString (newLine));
if (! CharPointer_ASCII::isValidString (text.toUTF8(), std::numeric_limits<int>::max()))
result = "juce::CharPointer_UTF8 (" + result + ")";
return result;
}
String alignFunctionCallParams (const String& call, const StringArray& parameters, const int maxLineLength)
{
String result, currentLine (call);
for (int i = 0; i < parameters.size(); ++i)
{
if (currentLine.length() >= maxLineLength)
{
result += currentLine.trimEnd() + newLine;
currentLine = String::repeatedString (" ", call.length()) + parameters[i];
}
else
{
currentLine += parameters[i];
}
if (i < parameters.size() - 1)
currentLine << ", ";
}
return result + currentLine.trimEnd() + ")";
}
String floatLiteral (double value, int numDecPlaces)
{
String s (value, numDecPlaces);
if (s.containsChar ('.'))
s << 'f';
else
s << ".0f";
return s;
}
String boolLiteral (bool value)
{
return value ? "true" : "false";
}
String colourToCode (Colour col)
{
const Colour colours[] =
{
#define COL(col) Colours::col,
#include "jucer_Colours.h"
#undef COL
Colours::transparentBlack
};
static const char* colourNames[] =
{
#define COL(col) #col,
#include "jucer_Colours.h"
#undef COL
nullptr
};
for (int i = 0; i < numElementsInArray (colourNames) - 1; ++i)
if (col == colours[i])
return "juce::Colours::" + String (colourNames[i]);
return "juce::Colour (0x" + build_tools::hexString8Digits ((int) col.getARGB()) + ')';
}
String justificationToCode (Justification justification)
{
switch (justification.getFlags())
{
case Justification::centred: return "juce::Justification::centred";
case Justification::centredLeft: return "juce::Justification::centredLeft";
case Justification::centredRight: return "juce::Justification::centredRight";
case Justification::centredTop: return "juce::Justification::centredTop";
case Justification::centredBottom: return "juce::Justification::centredBottom";
case Justification::topLeft: return "juce::Justification::topLeft";
case Justification::topRight: return "juce::Justification::topRight";
case Justification::bottomLeft: return "juce::Justification::bottomLeft";
case Justification::bottomRight: return "juce::Justification::bottomRight";
case Justification::left: return "juce::Justification::left";
case Justification::right: return "juce::Justification::right";
case Justification::horizontallyCentred: return "juce::Justification::horizontallyCentred";
case Justification::top: return "juce::Justification::top";
case Justification::bottom: return "juce::Justification::bottom";
case Justification::verticallyCentred: return "juce::Justification::verticallyCentred";
case Justification::horizontallyJustified: return "juce::Justification::horizontallyJustified";
default: break;
}
jassertfalse;
return "Justification (" + String (justification.getFlags()) + ")";
}
//==============================================================================
String getLeadingWhitespace (String line)
{
line = line.removeCharacters (line.endsWith ("\r\n") ? "\r\n" : "\n");
auto endOfLeadingWS = line.getCharPointer().findEndOfWhitespace();
return String (line.getCharPointer(), endOfLeadingWS);
}
int getBraceCount (String::CharPointerType line)
{
int braces = 0;
for (;;)
{
const juce_wchar c = line.getAndAdvance();
if (c == 0) break;
else if (c == '{') ++braces;
else if (c == '}') --braces;
else if (c == '/') { if (*line == '/') break; }
else if (c == '"' || c == '\'') { while (! (line.isEmpty() || line.getAndAdvance() == c)) {} }
}
return braces;
}
bool getIndentForCurrentBlock (CodeDocument::Position pos, const String& tab,
String& blockIndent, String& lastLineIndent)
{
int braceCount = 0;
bool indentFound = false;
while (pos.getLineNumber() > 0)
{
pos = pos.movedByLines (-1);
auto line = pos.getLineText();
auto trimmedLine = line.trimStart();
braceCount += getBraceCount (trimmedLine.getCharPointer());
if (braceCount > 0)
{
blockIndent = getLeadingWhitespace (line);
if (! indentFound)
lastLineIndent = blockIndent + tab;
return true;
}
if ((! indentFound) && trimmedLine.isNotEmpty())
{
indentFound = true;
lastLineIndent = getLeadingWhitespace (line);
}
}
return false;
}
}

View File

@ -1,52 +1,52 @@
/*
==============================================================================
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 CodeHelpers
{
String indent (const String& code, int numSpaces, bool indentFirstLine);
String unindent (const String& code, int numSpaces);
String createIncludeStatement (const File& includedFile, const File& targetFile);
String createIncludeStatement (const String& includePath);
String createIncludePathIncludeStatement (const String& includedFilename);
String stringLiteral (const String& text, int maxLineLength = -1);
String floatLiteral (double value, int numDecPlaces);
String boolLiteral (bool value);
String colourToCode (Colour);
String justificationToCode (Justification);
String alignFunctionCallParams (const String& call, const StringArray& parameters, int maxLineLength);
String getLeadingWhitespace (String line);
int getBraceCount (String::CharPointerType line);
bool getIndentForCurrentBlock (CodeDocument::Position pos, const String& tab,
String& blockIndent, String& lastLineIndent);
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 CodeHelpers
{
String indent (const String& code, int numSpaces, bool indentFirstLine);
String unindent (const String& code, int numSpaces);
String createIncludeStatement (const File& includedFile, const File& targetFile);
String createIncludeStatement (const String& includePath);
String createIncludePathIncludeStatement (const String& includedFilename);
String stringLiteral (const String& text, int maxLineLength = -1);
String floatLiteral (double value, int numDecPlaces);
String boolLiteral (bool value);
String colourToCode (Colour);
String justificationToCode (Justification);
String alignFunctionCallParams (const String& call, const StringArray& parameters, int maxLineLength);
String getLeadingWhitespace (String line);
int getBraceCount (String::CharPointerType line);
bool getIndentForCurrentBlock (CodeDocument::Position pos, const String& tab,
String& blockIndent, String& lastLineIndent);
}

View File

@ -1,162 +1,162 @@
/*
==============================================================================
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.
==============================================================================
*/
COL(black)
COL(white)
COL(blue)
COL(grey)
COL(green)
COL(red)
COL(yellow)
COL(aliceblue)
COL(antiquewhite)
COL(aqua)
COL(aquamarine)
COL(azure)
COL(beige)
COL(bisque)
COL(blanchedalmond)
COL(blueviolet)
COL(brown)
COL(burlywood)
COL(cadetblue)
COL(chartreuse)
COL(chocolate)
COL(coral)
COL(cornflowerblue)
COL(cornsilk)
COL(crimson)
COL(cyan)
COL(darkblue)
COL(darkcyan)
COL(darkgoldenrod)
COL(darkgrey)
COL(darkgreen)
COL(darkkhaki)
COL(darkmagenta)
COL(darkolivegreen)
COL(darkorange)
COL(darkorchid)
COL(darkred)
COL(darksalmon)
COL(darkseagreen)
COL(darkslateblue)
COL(darkslategrey)
COL(darkturquoise)
COL(darkviolet)
COL(deeppink)
COL(deepskyblue)
COL(dimgrey)
COL(dodgerblue)
COL(firebrick)
COL(floralwhite)
COL(forestgreen)
COL(fuchsia)
COL(gainsboro)
COL(gold)
COL(goldenrod)
COL(greenyellow)
COL(honeydew)
COL(hotpink)
COL(indianred)
COL(indigo)
COL(ivory)
COL(khaki)
COL(lavender)
COL(lavenderblush)
COL(lemonchiffon)
COL(lightblue)
COL(lightcoral)
COL(lightcyan)
COL(lightgoldenrodyellow)
COL(lightgreen)
COL(lightgrey)
COL(lightpink)
COL(lightsalmon)
COL(lightseagreen)
COL(lightskyblue)
COL(lightslategrey)
COL(lightsteelblue)
COL(lightyellow)
COL(lime)
COL(limegreen)
COL(linen)
COL(magenta)
COL(maroon)
COL(mediumaquamarine)
COL(mediumblue)
COL(mediumorchid)
COL(mediumpurple)
COL(mediumseagreen)
COL(mediumslateblue)
COL(mediumspringgreen)
COL(mediumturquoise)
COL(mediumvioletred)
COL(midnightblue)
COL(mintcream)
COL(mistyrose)
COL(navajowhite)
COL(navy)
COL(oldlace)
COL(olive)
COL(olivedrab)
COL(orange)
COL(orangered)
COL(orchid)
COL(palegoldenrod)
COL(palegreen)
COL(paleturquoise)
COL(palevioletred)
COL(papayawhip)
COL(peachpuff)
COL(peru)
COL(pink)
COL(plum)
COL(powderblue)
COL(purple)
COL(rosybrown)
COL(royalblue)
COL(saddlebrown)
COL(salmon)
COL(sandybrown)
COL(seagreen)
COL(seashell)
COL(sienna)
COL(silver)
COL(skyblue)
COL(slateblue)
COL(slategrey)
COL(snow)
COL(springgreen)
COL(steelblue)
COL(tan)
COL(teal)
COL(thistle)
COL(tomato)
COL(turquoise)
COL(violet)
COL(wheat)
COL(whitesmoke)
COL(yellowgreen)
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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.
==============================================================================
*/
COL(black)
COL(white)
COL(blue)
COL(grey)
COL(green)
COL(red)
COL(yellow)
COL(aliceblue)
COL(antiquewhite)
COL(aqua)
COL(aquamarine)
COL(azure)
COL(beige)
COL(bisque)
COL(blanchedalmond)
COL(blueviolet)
COL(brown)
COL(burlywood)
COL(cadetblue)
COL(chartreuse)
COL(chocolate)
COL(coral)
COL(cornflowerblue)
COL(cornsilk)
COL(crimson)
COL(cyan)
COL(darkblue)
COL(darkcyan)
COL(darkgoldenrod)
COL(darkgrey)
COL(darkgreen)
COL(darkkhaki)
COL(darkmagenta)
COL(darkolivegreen)
COL(darkorange)
COL(darkorchid)
COL(darkred)
COL(darksalmon)
COL(darkseagreen)
COL(darkslateblue)
COL(darkslategrey)
COL(darkturquoise)
COL(darkviolet)
COL(deeppink)
COL(deepskyblue)
COL(dimgrey)
COL(dodgerblue)
COL(firebrick)
COL(floralwhite)
COL(forestgreen)
COL(fuchsia)
COL(gainsboro)
COL(gold)
COL(goldenrod)
COL(greenyellow)
COL(honeydew)
COL(hotpink)
COL(indianred)
COL(indigo)
COL(ivory)
COL(khaki)
COL(lavender)
COL(lavenderblush)
COL(lemonchiffon)
COL(lightblue)
COL(lightcoral)
COL(lightcyan)
COL(lightgoldenrodyellow)
COL(lightgreen)
COL(lightgrey)
COL(lightpink)
COL(lightsalmon)
COL(lightseagreen)
COL(lightskyblue)
COL(lightslategrey)
COL(lightsteelblue)
COL(lightyellow)
COL(lime)
COL(limegreen)
COL(linen)
COL(magenta)
COL(maroon)
COL(mediumaquamarine)
COL(mediumblue)
COL(mediumorchid)
COL(mediumpurple)
COL(mediumseagreen)
COL(mediumslateblue)
COL(mediumspringgreen)
COL(mediumturquoise)
COL(mediumvioletred)
COL(midnightblue)
COL(mintcream)
COL(mistyrose)
COL(navajowhite)
COL(navy)
COL(oldlace)
COL(olive)
COL(olivedrab)
COL(orange)
COL(orangered)
COL(orchid)
COL(palegoldenrod)
COL(palegreen)
COL(paleturquoise)
COL(palevioletred)
COL(papayawhip)
COL(peachpuff)
COL(peru)
COL(pink)
COL(plum)
COL(powderblue)
COL(purple)
COL(rosybrown)
COL(royalblue)
COL(saddlebrown)
COL(salmon)
COL(sandybrown)
COL(seagreen)
COL(seashell)
COL(sienna)
COL(silver)
COL(skyblue)
COL(slateblue)
COL(slategrey)
COL(snow)
COL(springgreen)
COL(steelblue)
COL(tan)
COL(teal)
COL(thistle)
COL(tomato)
COL(turquoise)
COL(violet)
COL(wheat)
COL(whitesmoke)
COL(yellowgreen)

View File

@ -1,107 +1,107 @@
/*
==============================================================================
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_CodeHelpers.h"
//==============================================================================
namespace FileHelpers
{
bool containsAnyNonHiddenFiles (const File& folder)
{
for (const auto& di : RangedDirectoryIterator (folder, false))
if (! di.getFile().isHidden())
return true;
return false;
}
bool shouldPathsBeRelative (String path1, String path2)
{
path1 = build_tools::unixStylePath (path1);
path2 = build_tools::unixStylePath (path2);
const int len = jmin (path1.length(), path2.length());
int commonBitLength = 0;
for (int i = 0; i < len; ++i)
{
if (CharacterFunctions::toLowerCase (path1[i]) != CharacterFunctions::toLowerCase (path2[i]))
break;
++commonBitLength;
}
return path1.substring (0, commonBitLength).removeCharacters ("/:").isNotEmpty();
}
// removes "/../" bits from the middle of the path
String simplifyPath (String::CharPointerType p)
{
#if JUCE_WINDOWS
if (CharacterFunctions::indexOf (p, CharPointer_ASCII ("/../")) >= 0
|| CharacterFunctions::indexOf (p, CharPointer_ASCII ("\\..\\")) >= 0)
#else
if (CharacterFunctions::indexOf (p, CharPointer_ASCII ("/../")) >= 0)
#endif
{
StringArray toks;
#if JUCE_WINDOWS
toks.addTokens (p, "\\/", StringRef());
#else
toks.addTokens (p, "/", StringRef());
#endif
while (toks[0] == ".")
toks.remove (0);
for (int i = 1; i < toks.size(); ++i)
{
if (toks[i] == ".." && toks [i - 1] != "..")
{
toks.removeRange (i - 1, 2);
i = jmax (0, i - 2);
}
}
return toks.joinIntoString ("/");
}
return p;
}
String simplifyPath (const String& path)
{
#if JUCE_WINDOWS
if (path.contains ("\\..\\") || path.contains ("/../"))
#else
if (path.contains ("/../"))
#endif
return simplifyPath (path.getCharPointer());
return path;
}
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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_CodeHelpers.h"
//==============================================================================
namespace FileHelpers
{
bool containsAnyNonHiddenFiles (const File& folder)
{
for (const auto& di : RangedDirectoryIterator (folder, false))
if (! di.getFile().isHidden())
return true;
return false;
}
bool shouldPathsBeRelative (String path1, String path2)
{
path1 = build_tools::unixStylePath (path1);
path2 = build_tools::unixStylePath (path2);
const int len = jmin (path1.length(), path2.length());
int commonBitLength = 0;
for (int i = 0; i < len; ++i)
{
if (CharacterFunctions::toLowerCase (path1[i]) != CharacterFunctions::toLowerCase (path2[i]))
break;
++commonBitLength;
}
return path1.substring (0, commonBitLength).removeCharacters ("/:").isNotEmpty();
}
// removes "/../" bits from the middle of the path
String simplifyPath (String::CharPointerType p)
{
#if JUCE_WINDOWS
if (CharacterFunctions::indexOf (p, CharPointer_ASCII ("/../")) >= 0
|| CharacterFunctions::indexOf (p, CharPointer_ASCII ("\\..\\")) >= 0)
#else
if (CharacterFunctions::indexOf (p, CharPointer_ASCII ("/../")) >= 0)
#endif
{
StringArray toks;
#if JUCE_WINDOWS
toks.addTokens (p, "\\/", StringRef());
#else
toks.addTokens (p, "/", StringRef());
#endif
while (toks[0] == ".")
toks.remove (0);
for (int i = 1; i < toks.size(); ++i)
{
if (toks[i] == ".." && toks [i - 1] != "..")
{
toks.removeRange (i - 1, 2);
i = jmax (0, i - 2);
}
}
return toks.joinIntoString ("/");
}
return p;
}
String simplifyPath (const String& path)
{
#if JUCE_WINDOWS
if (path.contains ("\\..\\") || path.contains ("/../"))
#else
if (path.contains ("/../"))
#endif
return simplifyPath (path.getCharPointer());
return path;
}
}

View File

@ -1,79 +1,79 @@
/*
==============================================================================
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 FileHelpers
{
bool containsAnyNonHiddenFiles (const File& folder);
bool shouldPathsBeRelative (String path1, String path2);
// removes "/../" bits from the middle of the path
String simplifyPath (String::CharPointerType path);
String simplifyPath (const String& path);
}
//==============================================================================
const char* const sourceFileExtensions = "cpp;mm;m;metal;c;cc;cxx;swift;s;asm;r";
const char* const headerFileExtensions = "h;hpp;hxx;hh;inl";
const char* const cOrCppFileExtensions = "cpp;cc;cxx;c";
const char* const cppFileExtensions = "cpp;cc;cxx";
const char* const objCFileExtensions = "mm;m";
const char* const asmFileExtensions = "s;S;asm";
const char* const sourceOrHeaderFileExtensions = "cpp;mm;m;metal;c;cc;cxx;swift;s;S;asm;h;hpp;hxx;hh;inl";
const char* const browseableFileExtensions = "cpp;mm;m;metal;c;cc;cxx;swift;s;S;asm;h;hpp;hxx;hh;inl;txt;md;rtf";
const char* const fileTypesToCompileByDefault = "cpp;mm;m;metal;c;cc;cxx;swift;s;S;asm;r";
//==============================================================================
struct FileModificationDetector
{
FileModificationDetector (const File& f) : file (f) {}
const File& getFile() const { return file; }
void fileHasBeenRenamed (const File& newFile) { file = newFile; }
bool hasBeenModified() const
{
return fileModificationTime != file.getLastModificationTime()
&& (fileSize != file.getSize()
|| build_tools::calculateFileHashCode (file) != fileHashCode);
}
void updateHash()
{
fileModificationTime = file.getLastModificationTime();
fileSize = file.getSize();
fileHashCode = build_tools::calculateFileHashCode (file);
}
private:
File file;
Time fileModificationTime;
uint64 fileHashCode = 0;
int64 fileSize = -1;
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 FileHelpers
{
bool containsAnyNonHiddenFiles (const File& folder);
bool shouldPathsBeRelative (String path1, String path2);
// removes "/../" bits from the middle of the path
String simplifyPath (String::CharPointerType path);
String simplifyPath (const String& path);
}
//==============================================================================
const char* const sourceFileExtensions = "cpp;mm;m;metal;c;cc;cxx;swift;s;asm;r";
const char* const headerFileExtensions = "h;hpp;hxx;hh;inl";
const char* const cOrCppFileExtensions = "cpp;cc;cxx;c";
const char* const cppFileExtensions = "cpp;cc;cxx";
const char* const objCFileExtensions = "mm;m";
const char* const asmFileExtensions = "s;S;asm";
const char* const sourceOrHeaderFileExtensions = "cpp;mm;m;metal;c;cc;cxx;swift;s;S;asm;h;hpp;hxx;hh;inl";
const char* const browseableFileExtensions = "cpp;mm;m;metal;c;cc;cxx;swift;s;S;asm;h;hpp;hxx;hh;inl;txt;md;rtf";
const char* const fileTypesToCompileByDefault = "cpp;mm;m;metal;c;cc;cxx;swift;s;S;asm;r";
//==============================================================================
struct FileModificationDetector
{
FileModificationDetector (const File& f) : file (f) {}
const File& getFile() const { return file; }
void fileHasBeenRenamed (const File& newFile) { file = newFile; }
bool hasBeenModified() const
{
return fileModificationTime != file.getLastModificationTime()
&& (fileSize != file.getSize()
|| build_tools::calculateFileHashCode (file) != fileHashCode);
}
void updateHash()
{
fileModificationTime = file.getLastModificationTime();
fileSize = file.getSize();
fileHashCode = build_tools::calculateFileHashCode (file);
}
private:
File file;
Time fileModificationTime;
uint64 fileHashCode = 0;
int64 fileSize = -1;
};

File diff suppressed because it is too large Load Diff

View File

@ -1,134 +1,138 @@
/*
==============================================================================
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
//==============================================================================
const char* getPreferredLineFeed();
String joinLinesIntoSourceFile (StringArray& lines);
String replaceLineFeeds (const String& content, const String& lineFeed);
String getLineFeedForFile (const String& fileContent);
var parseJUCEHeaderMetadata (const File&);
String trimCommentCharsFromStartOfLine (const String& line);
String createAlphaNumericUID();
String createGUID (const String& seed); // Turns a seed into a windows GUID
String escapeSpaces (const String& text); // replaces spaces with blackslash-space
String escapeQuotesAndSpaces (const String& text);
String addQuotesIfContainsSpaces (const String& text);
StringPairArray parsePreprocessorDefs (const String& defs);
StringPairArray mergePreprocessorDefs (StringPairArray inheritedDefs, const StringPairArray& overridingDefs);
String createGCCPreprocessorFlags (const StringPairArray& defs);
StringArray getCleanedStringArray (StringArray);
StringArray getSearchPathsFromString (const String& searchPath);
StringArray getCommaOrWhitespaceSeparatedItems (const String&);
void setValueIfVoid (Value value, const var& defaultValue);
bool fileNeedsCppSyntaxHighlighting (const File& file);
void writeAutoGenWarningComment (OutputStream& outStream);
StringArray getJUCEModules() noexcept;
bool isJUCEModule (const String& moduleID) noexcept;
StringArray getModulesRequiredForConsole() noexcept;
StringArray getModulesRequiredForComponent() noexcept;
StringArray getModulesRequiredForAudioProcessor() noexcept;
bool isPIPFile (const File&) noexcept;
int findBestLineToScrollToForClass (StringArray, const String&, bool isPlugin = false);
bool isValidJUCEExamplesDirectory (const File&) noexcept;
bool isJUCEModulesFolder (const File&);
bool isJUCEFolder (const File&);
//==============================================================================
int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex);
void autoScrollForMouseEvent (const MouseEvent& e, bool scrollX = true, bool scrollY = true);
//==============================================================================
struct PropertyListBuilder
{
void add (PropertyComponent* propertyComp)
{
components.add (propertyComp);
}
void add (PropertyComponent* propertyComp, const String& tooltip)
{
propertyComp->setTooltip (tooltip);
add (propertyComp);
}
void addSearchPathProperty (const Value& value, const String& name, const String& mainHelpText)
{
add (new TextPropertyComponent (value, name, 16384, true),
mainHelpText + " Use semi-colons or new-lines to separate multiple paths.");
}
void addSearchPathProperty (ValueWithDefault& value, const String& name, const String& mainHelpText)
{
add (new TextPropertyComponent (value, name, 16384, true),
mainHelpText + " Use semi-colons or new-lines to separate multiple paths.");
}
void setPreferredHeight (int height)
{
for (int j = components.size(); --j >= 0;)
components.getUnchecked(j)->setPreferredHeight (height);
}
Array<PropertyComponent*> components;
};
//==============================================================================
// A ValueSource which takes an input source, and forwards any changes in it.
// This class is a handy way to create sources which re-map a value.
class ValueSourceFilter : public Value::ValueSource,
private Value::Listener
{
public:
ValueSourceFilter (const Value& source) : sourceValue (source)
{
sourceValue.addListener (this);
}
protected:
Value sourceValue;
private:
void valueChanged (Value&) override { sendChangeMessage (true); }
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueSourceFilter)
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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
//==============================================================================
const char* getPreferredLineFeed();
String joinLinesIntoSourceFile (StringArray& lines);
String replaceLineFeeds (const String& content, const String& lineFeed);
String getLineFeedForFile (const String& fileContent);
var parseJUCEHeaderMetadata (const File&);
String trimCommentCharsFromStartOfLine (const String& line);
String createAlphaNumericUID();
String createGUID (const String& seed); // Turns a seed into a windows GUID
String escapeSpaces (const String& text); // replaces spaces with blackslash-space
String escapeQuotesAndSpaces (const String& text);
String addQuotesIfContainsSpaces (const String& text);
StringPairArray parsePreprocessorDefs (const String& defs);
StringPairArray mergePreprocessorDefs (StringPairArray inheritedDefs, const StringPairArray& overridingDefs);
String createGCCPreprocessorFlags (const StringPairArray& defs);
StringArray getCleanedStringArray (StringArray);
StringArray getSearchPathsFromString (const String& searchPath);
StringArray getCommaOrWhitespaceSeparatedItems (const String&);
void setValueIfVoid (Value value, const var& defaultValue);
bool fileNeedsCppSyntaxHighlighting (const File& file);
void writeAutoGenWarningComment (OutputStream& outStream);
StringArray getJUCEModules() noexcept;
bool isJUCEModule (const String& moduleID) noexcept;
StringArray getModulesRequiredForConsole() noexcept;
StringArray getModulesRequiredForComponent() noexcept;
StringArray getModulesRequiredForAudioProcessor() noexcept;
bool isPIPFile (const File&) noexcept;
int findBestLineToScrollToForClass (StringArray, const String&, bool isPlugin = false);
bool isValidJUCEExamplesDirectory (const File&) noexcept;
bool isJUCEModulesFolder (const File&);
bool isJUCEFolder (const File&);
//==============================================================================
int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex);
void autoScrollForMouseEvent (const MouseEvent& e, bool scrollX = true, bool scrollY = true);
//==============================================================================
struct PropertyListBuilder
{
void add (PropertyComponent* propertyComp)
{
components.add (propertyComp);
}
void add (PropertyComponent* propertyComp, const String& tooltip)
{
propertyComp->setTooltip (tooltip);
add (propertyComp);
}
void addSearchPathProperty (const Value& value,
const String& name,
const String& mainHelpText)
{
add (new TextPropertyComponent (value, name, 16384, true),
mainHelpText + " Use semi-colons or new-lines to separate multiple paths.");
}
void addSearchPathProperty (const ValueTreePropertyWithDefault& value,
const String& name,
const String& mainHelpText)
{
add (new TextPropertyComponent (value, name, 16384, true),
mainHelpText + " Use semi-colons or new-lines to separate multiple paths.");
}
void setPreferredHeight (int height)
{
for (int j = components.size(); --j >= 0;)
components.getUnchecked(j)->setPreferredHeight (height);
}
Array<PropertyComponent*> components;
};
//==============================================================================
// A ValueSource which takes an input source, and forwards any changes in it.
// This class is a handy way to create sources which re-map a value.
class ValueSourceFilter : public Value::ValueSource,
private Value::Listener
{
public:
ValueSourceFilter (const Value& source) : sourceValue (source)
{
sourceValue.addListener (this);
}
protected:
Value sourceValue;
private:
void valueChanged (Value&) override { sendChangeMessage (true); }
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueSourceFilter)
};

View File

@ -1,296 +1,296 @@
/*
==============================================================================
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_NewFileWizard.h"
//==============================================================================
namespace
{
static String fillInBasicTemplateFields (const File& file, const Project::Item& item, const char* templateName)
{
int dataSize;
if (auto* data = BinaryData::getNamedResource (templateName, dataSize))
{
auto fileTemplate = String::fromUTF8 (data, dataSize);
return replaceLineFeeds (fileTemplate.replace ("%%filename%%", file.getFileName(), false)
.replace ("%%date%%", Time::getCurrentTime().toString (true, true, true), false)
.replace ("%%author%%", SystemStats::getFullUserName(), false)
.replace ("%%include_corresponding_header%%", CodeHelpers::createIncludeStatement (file.withFileExtension (".h"), file)),
item.project.getProjectLineFeed());
}
jassertfalse;
return {};
}
static bool fillInNewCppFileTemplate (const File& file, const Project::Item& item, const char* templateName)
{
return build_tools::overwriteFileWithNewDataIfDifferent (file, fillInBasicTemplateFields (file, item, templateName));
}
const int menuBaseID = 0x12d83f0;
}
//==============================================================================
class NewCppFileWizard : public NewFileWizard::Type
{
public:
String getName() override { return "CPP File"; }
void createNewFile (Project&, Project::Item parent) override
{
askUserToChooseNewFile ("SourceCode.cpp", "*.cpp", parent, [parent] (File newFile)
{
if (newFile != File())
create (parent, newFile, "jucer_NewCppFileTemplate_cpp");
});
}
static bool create (Project::Item parent, const File& newFile, const char* templateName)
{
if (fillInNewCppFileTemplate (newFile, parent, templateName))
{
parent.addFileRetainingSortOrder (newFile, true);
return true;
}
showFailedToWriteMessage (newFile);
return false;
}
};
//==============================================================================
class NewHeaderFileWizard : public NewFileWizard::Type
{
public:
String getName() override { return "Header File"; }
void createNewFile (Project&, Project::Item parent) override
{
askUserToChooseNewFile ("SourceCode.h", "*.h", parent, [parent] (File newFile)
{
if (newFile != File())
create (parent, newFile, "jucer_NewCppFileTemplate_h");
});
}
static bool create (Project::Item parent, const File& newFile, const char* templateName)
{
if (fillInNewCppFileTemplate (newFile, parent, templateName))
{
parent.addFileRetainingSortOrder (newFile, true);
return true;
}
showFailedToWriteMessage (newFile);
return false;
}
};
//==============================================================================
class NewCppAndHeaderFileWizard : public NewFileWizard::Type
{
public:
String getName() override { return "CPP & Header File"; }
void createNewFile (Project&, Project::Item parent) override
{
askUserToChooseNewFile ("SourceCode.h", "*.h;*.cpp", parent, [parent] (File newFile)
{
if (NewCppFileWizard::create (parent, newFile.withFileExtension ("h"), "jucer_NewCppFileTemplate_h"))
NewCppFileWizard::create (parent, newFile.withFileExtension ("cpp"), "jucer_NewCppFileTemplate_cpp");
});
}
};
//==============================================================================
class NewComponentFileWizard : public NewFileWizard::Type
{
public:
String getName() override { return "Component class (split between a CPP & header)"; }
void createNewFile (Project&, Project::Item parent) override
{
createNewFileInternal (parent);
}
static bool create (const String& className, Project::Item parent,
const File& newFile, const char* templateName)
{
auto content = fillInBasicTemplateFields (newFile, parent, templateName)
.replace ("%%component_class%%", className)
.replace ("%%include_juce%%", CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename()));
content = replaceLineFeeds (content, parent.project.getProjectLineFeed());
if (build_tools::overwriteFileWithNewDataIfDifferent (newFile, content))
{
parent.addFileRetainingSortOrder (newFile, true);
return true;
}
showFailedToWriteMessage (newFile);
return false;
}
private:
virtual void createFiles (Project::Item parent, const String& className, const File& newFile)
{
if (create (className, parent, newFile.withFileExtension ("h"), "jucer_NewComponentTemplate_h"))
create (className, parent, newFile.withFileExtension ("cpp"), "jucer_NewComponentTemplate_cpp");
}
static String getClassNameFieldName() { return "Class Name"; }
void createNewFileInternal (Project::Item parent)
{
asyncAlertWindow = std::make_unique<AlertWindow> (TRANS ("Create new Component class"),
TRANS ("Please enter the name for the new class"),
MessageBoxIconType::NoIcon, nullptr);
asyncAlertWindow->addTextEditor (getClassNameFieldName(), String(), String(), false);
asyncAlertWindow->addButton (TRANS ("Create Files"), 1, KeyPress (KeyPress::returnKey));
asyncAlertWindow->addButton (TRANS ("Cancel"), 0, KeyPress (KeyPress::escapeKey));
auto resultCallback = [safeThis = WeakReference<NewComponentFileWizard> { this }, parent] (int result)
{
if (safeThis == nullptr)
return;
auto& aw = *(safeThis->asyncAlertWindow);
aw.exitModalState (result);
aw.setVisible (false);
if (result == 0)
return;
const String className (aw.getTextEditorContents (getClassNameFieldName()).trim());
if (className == build_tools::makeValidIdentifier (className, false, true, false))
{
safeThis->askUserToChooseNewFile (className + ".h", "*.h;*.cpp",
parent,
[safeThis, parent, className] (File newFile)
{
if (safeThis == nullptr)
return;
if (newFile != File())
safeThis->createFiles (parent, className, newFile);
});
return;
}
safeThis->createNewFileInternal (parent);
};
asyncAlertWindow->enterModalState (true, ModalCallbackFunction::create (std::move (resultCallback)), false);
}
std::unique_ptr<AlertWindow> asyncAlertWindow;
JUCE_DECLARE_WEAK_REFERENCEABLE (NewComponentFileWizard)
};
//==============================================================================
class NewSingleFileComponentFileWizard : public NewComponentFileWizard
{
public:
String getName() override { return "Component class (in a single source file)"; }
void createFiles (Project::Item parent, const String& className, const File& newFile) override
{
create (className, parent, newFile.withFileExtension ("h"), "jucer_NewInlineComponentTemplate_h");
}
};
//==============================================================================
void NewFileWizard::Type::showFailedToWriteMessage (const File& file)
{
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
"Failed to Create File!",
"Couldn't write to the file: " + file.getFullPathName());
}
void NewFileWizard::Type::askUserToChooseNewFile (const String& suggestedFilename, const String& wildcard,
const Project::Item& projectGroupToAddTo,
std::function<void (File)> callback)
{
chooser = std::make_unique<FileChooser> ("Select File to Create",
projectGroupToAddTo.determineGroupFolder()
.getChildFile (suggestedFilename)
.getNonexistentSibling(),
wildcard);
auto flags = FileBrowserComponent::saveMode
| FileBrowserComponent::canSelectFiles
| FileBrowserComponent::warnAboutOverwriting;
chooser->launchAsync (flags, [callback] (const FileChooser& fc)
{
callback (fc.getResult());
});
}
//==============================================================================
NewFileWizard::NewFileWizard()
{
registerWizard (new NewCppFileWizard());
registerWizard (new NewHeaderFileWizard());
registerWizard (new NewCppAndHeaderFileWizard());
registerWizard (new NewComponentFileWizard());
registerWizard (new NewSingleFileComponentFileWizard());
}
NewFileWizard::~NewFileWizard()
{
}
void NewFileWizard::addWizardsToMenu (PopupMenu& m) const
{
for (int i = 0; i < wizards.size(); ++i)
m.addItem (menuBaseID + i, "Add New " + wizards.getUnchecked(i)->getName() + "...");
}
bool NewFileWizard::runWizardFromMenu (int chosenMenuItemID, Project& project, const Project::Item& projectGroupToAddTo) const
{
if (Type* wiz = wizards [chosenMenuItemID - menuBaseID])
{
wiz->createNewFile (project, projectGroupToAddTo);
return true;
}
return false;
}
void NewFileWizard::registerWizard (Type* newWizard)
{
wizards.add (newWizard);
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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_NewFileWizard.h"
//==============================================================================
namespace
{
static String fillInBasicTemplateFields (const File& file, const Project::Item& item, const char* templateName)
{
int dataSize;
if (auto* data = BinaryData::getNamedResource (templateName, dataSize))
{
auto fileTemplate = String::fromUTF8 (data, dataSize);
return replaceLineFeeds (fileTemplate.replace ("%%filename%%", file.getFileName(), false)
.replace ("%%date%%", Time::getCurrentTime().toString (true, true, true), false)
.replace ("%%author%%", SystemStats::getFullUserName(), false)
.replace ("%%include_corresponding_header%%", CodeHelpers::createIncludeStatement (file.withFileExtension (".h"), file)),
item.project.getProjectLineFeed());
}
jassertfalse;
return {};
}
static bool fillInNewCppFileTemplate (const File& file, const Project::Item& item, const char* templateName)
{
return build_tools::overwriteFileWithNewDataIfDifferent (file, fillInBasicTemplateFields (file, item, templateName));
}
const int menuBaseID = 0x12d83f0;
}
//==============================================================================
class NewCppFileWizard : public NewFileWizard::Type
{
public:
String getName() override { return "CPP File"; }
void createNewFile (Project&, Project::Item parent) override
{
askUserToChooseNewFile ("SourceCode.cpp", "*.cpp", parent, [parent] (File newFile)
{
if (newFile != File())
create (parent, newFile, "jucer_NewCppFileTemplate_cpp");
});
}
static bool create (Project::Item parent, const File& newFile, const char* templateName)
{
if (fillInNewCppFileTemplate (newFile, parent, templateName))
{
parent.addFileRetainingSortOrder (newFile, true);
return true;
}
showFailedToWriteMessage (newFile);
return false;
}
};
//==============================================================================
class NewHeaderFileWizard : public NewFileWizard::Type
{
public:
String getName() override { return "Header File"; }
void createNewFile (Project&, Project::Item parent) override
{
askUserToChooseNewFile ("SourceCode.h", "*.h", parent, [parent] (File newFile)
{
if (newFile != File())
create (parent, newFile, "jucer_NewCppFileTemplate_h");
});
}
static bool create (Project::Item parent, const File& newFile, const char* templateName)
{
if (fillInNewCppFileTemplate (newFile, parent, templateName))
{
parent.addFileRetainingSortOrder (newFile, true);
return true;
}
showFailedToWriteMessage (newFile);
return false;
}
};
//==============================================================================
class NewCppAndHeaderFileWizard : public NewFileWizard::Type
{
public:
String getName() override { return "CPP & Header File"; }
void createNewFile (Project&, Project::Item parent) override
{
askUserToChooseNewFile ("SourceCode.h", "*.h;*.cpp", parent, [parent] (File newFile)
{
if (NewCppFileWizard::create (parent, newFile.withFileExtension ("h"), "jucer_NewCppFileTemplate_h"))
NewCppFileWizard::create (parent, newFile.withFileExtension ("cpp"), "jucer_NewCppFileTemplate_cpp");
});
}
};
//==============================================================================
class NewComponentFileWizard : public NewFileWizard::Type
{
public:
String getName() override { return "Component class (split between a CPP & header)"; }
void createNewFile (Project&, Project::Item parent) override
{
createNewFileInternal (parent);
}
static bool create (const String& className, Project::Item parent,
const File& newFile, const char* templateName)
{
auto content = fillInBasicTemplateFields (newFile, parent, templateName)
.replace ("%%component_class%%", className)
.replace ("%%include_juce%%", CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename()));
content = replaceLineFeeds (content, parent.project.getProjectLineFeed());
if (build_tools::overwriteFileWithNewDataIfDifferent (newFile, content))
{
parent.addFileRetainingSortOrder (newFile, true);
return true;
}
showFailedToWriteMessage (newFile);
return false;
}
private:
virtual void createFiles (Project::Item parent, const String& className, const File& newFile)
{
if (create (className, parent, newFile.withFileExtension ("h"), "jucer_NewComponentTemplate_h"))
create (className, parent, newFile.withFileExtension ("cpp"), "jucer_NewComponentTemplate_cpp");
}
static String getClassNameFieldName() { return "Class Name"; }
void createNewFileInternal (Project::Item parent)
{
asyncAlertWindow = std::make_unique<AlertWindow> (TRANS ("Create new Component class"),
TRANS ("Please enter the name for the new class"),
MessageBoxIconType::NoIcon, nullptr);
asyncAlertWindow->addTextEditor (getClassNameFieldName(), String(), String(), false);
asyncAlertWindow->addButton (TRANS ("Create Files"), 1, KeyPress (KeyPress::returnKey));
asyncAlertWindow->addButton (TRANS ("Cancel"), 0, KeyPress (KeyPress::escapeKey));
auto resultCallback = [safeThis = WeakReference<NewComponentFileWizard> { this }, parent] (int result)
{
if (safeThis == nullptr)
return;
auto& aw = *(safeThis->asyncAlertWindow);
aw.exitModalState (result);
aw.setVisible (false);
if (result == 0)
return;
const String className (aw.getTextEditorContents (getClassNameFieldName()).trim());
if (className == build_tools::makeValidIdentifier (className, false, true, false))
{
safeThis->askUserToChooseNewFile (className + ".h", "*.h;*.cpp",
parent,
[safeThis, parent, className] (File newFile)
{
if (safeThis == nullptr)
return;
if (newFile != File())
safeThis->createFiles (parent, className, newFile);
});
return;
}
safeThis->createNewFileInternal (parent);
};
asyncAlertWindow->enterModalState (true, ModalCallbackFunction::create (std::move (resultCallback)), false);
}
std::unique_ptr<AlertWindow> asyncAlertWindow;
JUCE_DECLARE_WEAK_REFERENCEABLE (NewComponentFileWizard)
};
//==============================================================================
class NewSingleFileComponentFileWizard : public NewComponentFileWizard
{
public:
String getName() override { return "Component class (in a single source file)"; }
void createFiles (Project::Item parent, const String& className, const File& newFile) override
{
create (className, parent, newFile.withFileExtension ("h"), "jucer_NewInlineComponentTemplate_h");
}
};
//==============================================================================
void NewFileWizard::Type::showFailedToWriteMessage (const File& file)
{
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
"Failed to Create File!",
"Couldn't write to the file: " + file.getFullPathName());
}
void NewFileWizard::Type::askUserToChooseNewFile (const String& suggestedFilename, const String& wildcard,
const Project::Item& projectGroupToAddTo,
std::function<void (File)> callback)
{
chooser = std::make_unique<FileChooser> ("Select File to Create",
projectGroupToAddTo.determineGroupFolder()
.getChildFile (suggestedFilename)
.getNonexistentSibling(),
wildcard);
auto flags = FileBrowserComponent::saveMode
| FileBrowserComponent::canSelectFiles
| FileBrowserComponent::warnAboutOverwriting;
chooser->launchAsync (flags, [callback] (const FileChooser& fc)
{
callback (fc.getResult());
});
}
//==============================================================================
NewFileWizard::NewFileWizard()
{
registerWizard (new NewCppFileWizard());
registerWizard (new NewHeaderFileWizard());
registerWizard (new NewCppAndHeaderFileWizard());
registerWizard (new NewComponentFileWizard());
registerWizard (new NewSingleFileComponentFileWizard());
}
NewFileWizard::~NewFileWizard()
{
}
void NewFileWizard::addWizardsToMenu (PopupMenu& m) const
{
for (int i = 0; i < wizards.size(); ++i)
m.addItem (menuBaseID + i, "Add New " + wizards.getUnchecked(i)->getName() + "...");
}
bool NewFileWizard::runWizardFromMenu (int chosenMenuItemID, Project& project, const Project::Item& projectGroupToAddTo) const
{
if (Type* wiz = wizards [chosenMenuItemID - menuBaseID])
{
wiz->createNewFile (project, projectGroupToAddTo);
return true;
}
return false;
}
void NewFileWizard::registerWizard (Type* newWizard)
{
wizards.add (newWizard);
}

View File

@ -1,70 +1,70 @@
/*
==============================================================================
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 NewFileWizard
{
public:
//==============================================================================
NewFileWizard();
~NewFileWizard();
//==============================================================================
class Type
{
public:
Type() {}
virtual ~Type() {}
//==============================================================================
virtual String getName() = 0;
virtual void createNewFile (Project&, Project::Item projectGroupToAddTo) = 0;
protected:
//==============================================================================
void askUserToChooseNewFile (const String& suggestedFilename, const String& wildcard,
const Project::Item& projectGroupToAddTo,
std::function<void (File)> callback);
static void showFailedToWriteMessage (const File& file);
private:
std::unique_ptr<FileChooser> chooser;
};
//==============================================================================
void addWizardsToMenu (PopupMenu&) const;
bool runWizardFromMenu (int chosenMenuItemID, Project&,
const Project::Item& projectGroupToAddTo) const;
void registerWizard (Type*);
private:
OwnedArray<Type> wizards;
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 NewFileWizard
{
public:
//==============================================================================
NewFileWizard();
~NewFileWizard();
//==============================================================================
class Type
{
public:
Type() {}
virtual ~Type() {}
//==============================================================================
virtual String getName() = 0;
virtual void createNewFile (Project&, Project::Item projectGroupToAddTo) = 0;
protected:
//==============================================================================
void askUserToChooseNewFile (const String& suggestedFilename, const String& wildcard,
const Project::Item& projectGroupToAddTo,
std::function<void (File)> callback);
static void showFailedToWriteMessage (const File& file);
private:
std::unique_ptr<FileChooser> chooser;
};
//==============================================================================
void addWizardsToMenu (PopupMenu&) const;
bool runWizardFromMenu (int chosenMenuItemID, Project&,
const Project::Item& projectGroupToAddTo) const;
void registerWizard (Type*);
private:
OwnedArray<Type> wizards;
};

View File

@ -1,393 +1,399 @@
/*
==============================================================================
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
//==============================================================================
// Handy list of static Identifiers..
namespace Ids
{
#define DECLARE_ID(name) const Identifier name (#name)
DECLARE_ID (name);
DECLARE_ID (file);
DECLARE_ID (path);
DECLARE_ID (text);
DECLARE_ID (vendor);
DECLARE_ID (version);
DECLARE_ID (license);
DECLARE_ID (minimumCppStandard);
DECLARE_ID (include);
DECLARE_ID (info);
DECLARE_ID (description);
DECLARE_ID (companyName);
DECLARE_ID (companyCopyright);
DECLARE_ID (companyWebsite);
DECLARE_ID (companyEmail);
DECLARE_ID (useAppConfig);
DECLARE_ID (addUsingNamespaceToJuceHeader);
DECLARE_ID (usePrecompiledHeaderFile);
DECLARE_ID (precompiledHeaderFile);
DECLARE_ID (displaySplashScreen);
DECLARE_ID (splashScreenColour);
DECLARE_ID (position);
DECLARE_ID (source);
DECLARE_ID (width);
DECLARE_ID (height);
DECLARE_ID (bounds);
DECLARE_ID (background);
DECLARE_ID (initialState);
DECLARE_ID (targetFolder);
DECLARE_ID (intermediatesPath);
DECLARE_ID (modulePaths);
DECLARE_ID (searchpaths);
DECLARE_ID (osxFallback);
DECLARE_ID (windowsFallback);
DECLARE_ID (linuxFallback);
DECLARE_ID (jucePath);
DECLARE_ID (defaultJuceModulePath);
DECLARE_ID (defaultUserModulePath);
DECLARE_ID (vstLegacyFolder);
DECLARE_ID (vst3Folder);
DECLARE_ID (rtasFolder);
DECLARE_ID (auFolder);
DECLARE_ID (vstLegacyPath);
DECLARE_ID (rtasPath);
DECLARE_ID (aaxPath);
DECLARE_ID (flags);
DECLARE_ID (line);
DECLARE_ID (index);
DECLARE_ID (type);
DECLARE_ID (time);
DECLARE_ID (extraCompilerFlags);
DECLARE_ID (extraLinkerFlags);
DECLARE_ID (externalLibraries);
DECLARE_ID (extraDefs);
DECLARE_ID (projectType);
DECLARE_ID (isDebug);
DECLARE_ID (alwaysGenerateDebugSymbols);
DECLARE_ID (targetName);
DECLARE_ID (binaryPath);
DECLARE_ID (recommendedWarnings);
DECLARE_ID (optimisation);
DECLARE_ID (defines);
DECLARE_ID (headerPath);
DECLARE_ID (systemHeaderPath);
DECLARE_ID (liveWindowsTargetPlatformVersion);
DECLARE_ID (libraryPath);
DECLARE_ID (customXcodeFlags);
DECLARE_ID (customXcassetsFolder);
DECLARE_ID (customLaunchStoryboard);
DECLARE_ID (customXcodeResourceFolders);
DECLARE_ID (plistPreprocessorDefinitions);
DECLARE_ID (applicationCategory);
DECLARE_ID (customPList);
DECLARE_ID (pListPrefixHeader);
DECLARE_ID (pListPreprocess);
DECLARE_ID (UIFileSharingEnabled);
DECLARE_ID (UISupportsDocumentBrowser);
DECLARE_ID (UIStatusBarHidden);
DECLARE_ID (UIRequiresFullScreen);
DECLARE_ID (documentExtensions);
DECLARE_ID (keepCustomXcodeSchemes);
DECLARE_ID (useHeaderMap);
DECLARE_ID (cppLanguageStandard);
DECLARE_ID (enableGNUExtensions);
DECLARE_ID (cppLibType);
DECLARE_ID (codeSigningIdentity);
DECLARE_ID (fastMath);
DECLARE_ID (linkTimeOptimisation);
DECLARE_ID (vstBinaryLocation);
DECLARE_ID (vst3BinaryLocation);
DECLARE_ID (auBinaryLocation);
DECLARE_ID (rtasBinaryLocation);
DECLARE_ID (aaxBinaryLocation);
DECLARE_ID (unityPluginBinaryLocation);
DECLARE_ID (enablePluginBinaryCopyStep);
DECLARE_ID (stripLocalSymbols);
DECLARE_ID (macOSBaseSDK);
DECLARE_ID (macOSDeploymentTarget);
DECLARE_ID (osxArchitecture);
DECLARE_ID (iosBaseSDK);
DECLARE_ID (iosDeploymentTarget);
DECLARE_ID (xcodeSubprojects);
DECLARE_ID (extraFrameworks);
DECLARE_ID (frameworkSearchPaths);
DECLARE_ID (extraCustomFrameworks);
DECLARE_ID (embeddedFrameworks);
DECLARE_ID (extraDLLs);
DECLARE_ID (winArchitecture);
DECLARE_ID (winWarningLevel);
DECLARE_ID (msvcManifestFile);
DECLARE_ID (warningsAreErrors);
DECLARE_ID (linuxArchitecture);
DECLARE_ID (linuxCodeBlocksArchitecture);
DECLARE_ID (windowsCodeBlocksArchitecture);
DECLARE_ID (codeBlocksWindowsTarget);
DECLARE_ID (toolset);
DECLARE_ID (windowsTargetPlatformVersion);
DECLARE_ID (debugInformationFormat);
DECLARE_ID (IPPLibrary);
DECLARE_ID (IPP1ALibrary);
DECLARE_ID (MKL1ALibrary);
DECLARE_ID (msvcModuleDefinitionFile);
DECLARE_ID (bigIcon);
DECLARE_ID (smallIcon);
DECLARE_ID (prebuildCommand);
DECLARE_ID (postbuildCommand);
DECLARE_ID (generateManifest);
DECLARE_ID (useRuntimeLibDLL);
DECLARE_ID (multiProcessorCompilation);
DECLARE_ID (enableIncrementalLinking);
DECLARE_ID (bundleIdentifier);
DECLARE_ID (aaxIdentifier);
DECLARE_ID (aaxFolder);
DECLARE_ID (compile);
DECLARE_ID (noWarnings);
DECLARE_ID (skipPCH);
DECLARE_ID (resource);
DECLARE_ID (xcodeResource);
DECLARE_ID (xcodeValidArchs);
DECLARE_ID (className);
DECLARE_ID (classDesc);
DECLARE_ID (controlPoint);
DECLARE_ID (createCallback);
DECLARE_ID (parentClasses);
DECLARE_ID (constructorParams);
DECLARE_ID (objectConstructionArgs);
DECLARE_ID (memberInitialisers);
DECLARE_ID (canBeAggregated);
DECLARE_ID (rootItemVisible);
DECLARE_ID (openByDefault);
DECLARE_ID (locked);
DECLARE_ID (tooltip);
DECLARE_ID (memberName);
DECLARE_ID (markerName);
DECLARE_ID (focusOrder);
DECLARE_ID (hidden);
DECLARE_ID (useStdCall);
DECLARE_ID (useGlobalPath);
DECLARE_ID (showAllCode);
DECLARE_ID (useLocalCopy);
DECLARE_ID (overwriteOnSave);
DECLARE_ID (appSandbox);
DECLARE_ID (appSandboxInheritance);
DECLARE_ID (appSandboxOptions);
DECLARE_ID (hardenedRuntime);
DECLARE_ID (hardenedRuntimeOptions);
DECLARE_ID (microphonePermissionNeeded);
DECLARE_ID (microphonePermissionsText);
DECLARE_ID (cameraPermissionNeeded);
DECLARE_ID (cameraPermissionText);
DECLARE_ID (sendAppleEventsPermissionNeeded);
DECLARE_ID (sendAppleEventsPermissionText);
DECLARE_ID (androidJavaLibs);
DECLARE_ID (androidAdditionalJavaFolders);
DECLARE_ID (androidAdditionalResourceFolders);
DECLARE_ID (androidProjectRepositories);
DECLARE_ID (androidRepositories);
DECLARE_ID (androidDependencies);
DECLARE_ID (androidCustomAppBuildGradleContent);
DECLARE_ID (androidBuildConfigRemoteNotifsConfigFile);
DECLARE_ID (androidAdditionalXmlValueResources);
DECLARE_ID (androidAdditionalDrawableResources);
DECLARE_ID (androidAdditionalRawValueResources);
// DECLARE_ID (androidActivityClass); // DEPRECATED!
const Identifier androidCustomActivityClass ("androidActivitySubClassName"); // old name is very confusing, but we need to remain backward compatible
// DECLARE_ID (androidActivityBaseClassName); // DEPRECATED!
DECLARE_ID (androidCustomApplicationClass);
DECLARE_ID (androidVersionCode);
DECLARE_ID (androidSDKPath);
DECLARE_ID (androidOboeRepositoryPath);
DECLARE_ID (androidInternetNeeded);
DECLARE_ID (androidArchitectures);
DECLARE_ID (androidManifestCustomXmlElements);
DECLARE_ID (androidGradleSettingsContent);
DECLARE_ID (androidCustomStringXmlElements);
DECLARE_ID (androidBluetoothNeeded);
DECLARE_ID (androidExternalReadNeeded);
DECLARE_ID (androidExternalWriteNeeded);
DECLARE_ID (androidInAppBilling);
DECLARE_ID (androidVibratePermissionNeeded);
DECLARE_ID (androidPushNotifications);
DECLARE_ID (androidEnableRemoteNotifications);
DECLARE_ID (androidRemoteNotificationsConfigFile);
DECLARE_ID (androidEnableContentSharing);
DECLARE_ID (androidMinimumSDK);
DECLARE_ID (androidTargetSDK);
DECLARE_ID (androidOtherPermissions);
DECLARE_ID (androidKeyStore);
DECLARE_ID (androidKeyStorePass);
DECLARE_ID (androidKeyAlias);
DECLARE_ID (androidKeyAliasPass);
DECLARE_ID (androidTheme);
DECLARE_ID (androidStaticLibraries);
DECLARE_ID (androidSharedLibraries);
DECLARE_ID (androidScreenOrientation);
DECLARE_ID (androidExtraAssetsFolder);
DECLARE_ID (androidStudioExePath);
DECLARE_ID (iosDeviceFamily);
const Identifier iPhoneScreenOrientation ("iosScreenOrientation"); // old name is confusing
DECLARE_ID (iPadScreenOrientation);
DECLARE_ID (iosScreenOrientation);
DECLARE_ID (iosInAppPurchases);
DECLARE_ID (iosContentSharing);
DECLARE_ID (iosBackgroundAudio);
DECLARE_ID (iosBackgroundBle);
DECLARE_ID (iosPushNotifications);
DECLARE_ID (iosAppGroups);
DECLARE_ID (iCloudPermissions);
DECLARE_ID (networkingMulticast);
DECLARE_ID (iosDevelopmentTeamID);
DECLARE_ID (iosAppGroupsId);
DECLARE_ID (iosBluetoothPermissionNeeded);
DECLARE_ID (iosBluetoothPermissionText);
DECLARE_ID (duplicateAppExResourcesFolder);
DECLARE_ID (buildToolsVersion);
DECLARE_ID (gradleVersion);
const Identifier androidPluginVersion ("gradleWrapperVersion"); // old name is very confusing, but we need to remain backward compatible
DECLARE_ID (gradleToolchain);
DECLARE_ID (gradleToolchainVersion);
DECLARE_ID (linuxExtraPkgConfig);
DECLARE_ID (clionMakefileEnabled);
DECLARE_ID (clionXcodeEnabled);
DECLARE_ID (clionCodeBlocksEnabled);
DECLARE_ID (clionExePath);
DECLARE_ID (font);
DECLARE_ID (colour);
DECLARE_ID (userNotes);
DECLARE_ID (maxBinaryFileSize);
DECLARE_ID (includeBinaryInJuceHeader);
DECLARE_ID (binaryDataNamespace);
DECLARE_ID (characterSet);
DECLARE_ID (JUCERPROJECT);
DECLARE_ID (MAINGROUP);
DECLARE_ID (EXPORTFORMATS);
DECLARE_ID (GROUP);
DECLARE_ID (FILE);
DECLARE_ID (MODULES);
DECLARE_ID (MODULE);
DECLARE_ID (JUCEOPTIONS);
DECLARE_ID (CONFIGURATIONS);
DECLARE_ID (CONFIGURATION);
DECLARE_ID (MODULEPATHS);
DECLARE_ID (MODULEPATH);
DECLARE_ID (PATH);
DECLARE_ID (userpath);
DECLARE_ID (systempath);
DECLARE_ID (utilsCppInclude);
DECLARE_ID (juceModulesFolder);
DECLARE_ID (parentActive);
DECLARE_ID (message);
DECLARE_ID (start);
DECLARE_ID (end);
DECLARE_ID (range);
DECLARE_ID (location);
DECLARE_ID (key);
DECLARE_ID (list);
DECLARE_ID (METADATA);
DECLARE_ID (DEPENDENCIES);
DECLARE_ID (CLASSLIST);
DECLARE_ID (CLASS);
DECLARE_ID (MEMBER);
DECLARE_ID (METHOD);
DECLARE_ID (LITERALS);
DECLARE_ID (LITERAL);
DECLARE_ID (abstract);
DECLARE_ID (anonymous);
DECLARE_ID (noDefConstructor);
DECLARE_ID (returnType);
DECLARE_ID (numArgs);
DECLARE_ID (declaration);
DECLARE_ID (definition);
DECLARE_ID (classDecl);
DECLARE_ID (initialisers);
DECLARE_ID (destructors);
DECLARE_ID (pluginFormats);
DECLARE_ID (buildVST);
DECLARE_ID (buildVST3);
DECLARE_ID (buildAU);
DECLARE_ID (buildAUv3);
DECLARE_ID (buildRTAS);
DECLARE_ID (buildAAX);
DECLARE_ID (buildStandalone);
DECLARE_ID (buildUnity);
DECLARE_ID (enableIAA);
DECLARE_ID (pluginName);
DECLARE_ID (pluginDesc);
DECLARE_ID (pluginManufacturer);
DECLARE_ID (pluginManufacturerCode);
DECLARE_ID (pluginCode);
DECLARE_ID (pluginChannelConfigs);
DECLARE_ID (pluginCharacteristicsValue);
DECLARE_ID (pluginCharacteristics);
DECLARE_ID (extraPluginFormats);
DECLARE_ID (pluginIsSynth);
DECLARE_ID (pluginWantsMidiIn);
DECLARE_ID (pluginProducesMidiOut);
DECLARE_ID (pluginIsMidiEffectPlugin);
DECLARE_ID (pluginEditorRequiresKeys);
DECLARE_ID (pluginVSTCategory);
DECLARE_ID (pluginVST3Category);
DECLARE_ID (pluginAUExportPrefix);
DECLARE_ID (pluginAUMainType);
DECLARE_ID (pluginAUIsSandboxSafe);
DECLARE_ID (pluginRTASCategory);
DECLARE_ID (pluginRTASDisableBypass);
DECLARE_ID (pluginRTASDisableMultiMono);
DECLARE_ID (pluginAAXCategory);
DECLARE_ID (pluginAAXDisableBypass);
DECLARE_ID (pluginAAXDisableMultiMono);
DECLARE_ID (pluginVSTNumMidiInputs);
DECLARE_ID (pluginVSTNumMidiOutputs);
DECLARE_ID (suppressPlistResourceUsage);
DECLARE_ID (useLegacyBuildSystem);
DECLARE_ID (exporters);
DECLARE_ID (website);
DECLARE_ID (mainClass);
DECLARE_ID (moduleFlags);
DECLARE_ID (projectLineFeed);
DECLARE_ID (compilerFlagSchemes);
DECLARE_ID (compilerFlagScheme);
DECLARE_ID (dontQueryForUpdate);
DECLARE_ID (dontAskAboutJUCEPath);
DECLARE_ID (postExportShellCommandPosix);
DECLARE_ID (postExportShellCommandWin);
DECLARE_ID (guiEditorEnabled);
DECLARE_ID (jucerFormatVersion);
DECLARE_ID (buildNumber);
DECLARE_ID (osxSDK);
DECLARE_ID (osxCompatibility);
DECLARE_ID (iosCompatibility);
const Identifier ID ("id");
const Identifier ID_uppercase ("ID");
const Identifier class_ ("class");
const Identifier dependencies_ ("dependencies");
#undef DECLARE_ID
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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
//==============================================================================
// Handy list of static Identifiers..
namespace Ids
{
#define DECLARE_ID(name) const Identifier name (#name)
DECLARE_ID (name);
DECLARE_ID (file);
DECLARE_ID (path);
DECLARE_ID (text);
DECLARE_ID (vendor);
DECLARE_ID (version);
DECLARE_ID (license);
DECLARE_ID (minimumCppStandard);
DECLARE_ID (include);
DECLARE_ID (info);
DECLARE_ID (description);
DECLARE_ID (companyName);
DECLARE_ID (companyCopyright);
DECLARE_ID (companyWebsite);
DECLARE_ID (companyEmail);
DECLARE_ID (useAppConfig);
DECLARE_ID (addUsingNamespaceToJuceHeader);
DECLARE_ID (usePrecompiledHeaderFile);
DECLARE_ID (precompiledHeaderFile);
DECLARE_ID (displaySplashScreen);
DECLARE_ID (splashScreenColour);
DECLARE_ID (position);
DECLARE_ID (source);
DECLARE_ID (width);
DECLARE_ID (height);
DECLARE_ID (bounds);
DECLARE_ID (background);
DECLARE_ID (initialState);
DECLARE_ID (targetFolder);
DECLARE_ID (intermediatesPath);
DECLARE_ID (modulePaths);
DECLARE_ID (searchpaths);
DECLARE_ID (osxFallback);
DECLARE_ID (windowsFallback);
DECLARE_ID (linuxFallback);
DECLARE_ID (jucePath);
DECLARE_ID (defaultJuceModulePath);
DECLARE_ID (defaultUserModulePath);
DECLARE_ID (vstLegacyFolder);
DECLARE_ID (vst3Folder);
DECLARE_ID (auFolder);
DECLARE_ID (vstLegacyPath);
DECLARE_ID (aaxPath);
DECLARE_ID (araPath);
DECLARE_ID (flags);
DECLARE_ID (line);
DECLARE_ID (index);
DECLARE_ID (type);
DECLARE_ID (time);
DECLARE_ID (extraCompilerFlags);
DECLARE_ID (extraLinkerFlags);
DECLARE_ID (externalLibraries);
DECLARE_ID (extraDefs);
DECLARE_ID (projectType);
DECLARE_ID (isDebug);
DECLARE_ID (alwaysGenerateDebugSymbols);
DECLARE_ID (targetName);
DECLARE_ID (binaryPath);
DECLARE_ID (recommendedWarnings);
DECLARE_ID (optimisation);
DECLARE_ID (defines);
DECLARE_ID (headerPath);
DECLARE_ID (systemHeaderPath);
DECLARE_ID (liveWindowsTargetPlatformVersion);
DECLARE_ID (libraryPath);
DECLARE_ID (customXcodeFlags);
DECLARE_ID (customXcassetsFolder);
DECLARE_ID (customLaunchStoryboard);
DECLARE_ID (customXcodeResourceFolders);
DECLARE_ID (plistPreprocessorDefinitions);
DECLARE_ID (applicationCategory);
DECLARE_ID (customPList);
DECLARE_ID (pListPrefixHeader);
DECLARE_ID (pListPreprocess);
DECLARE_ID (UIFileSharingEnabled);
DECLARE_ID (UISupportsDocumentBrowser);
DECLARE_ID (UIStatusBarHidden);
DECLARE_ID (UIRequiresFullScreen);
DECLARE_ID (documentExtensions);
DECLARE_ID (keepCustomXcodeSchemes);
DECLARE_ID (useHeaderMap);
DECLARE_ID (cppLanguageStandard);
DECLARE_ID (enableGNUExtensions);
DECLARE_ID (cppLibType);
DECLARE_ID (codeSigningIdentity);
DECLARE_ID (fastMath);
DECLARE_ID (linkTimeOptimisation);
DECLARE_ID (vstBinaryLocation);
DECLARE_ID (vst3BinaryLocation);
DECLARE_ID (auBinaryLocation);
DECLARE_ID (aaxBinaryLocation);
DECLARE_ID (unityPluginBinaryLocation);
DECLARE_ID (enablePluginBinaryCopyStep);
DECLARE_ID (stripLocalSymbols);
DECLARE_ID (macOSBaseSDK);
DECLARE_ID (macOSDeploymentTarget);
DECLARE_ID (osxArchitecture);
DECLARE_ID (iosBaseSDK);
DECLARE_ID (iosDeploymentTarget);
DECLARE_ID (xcodeSubprojects);
DECLARE_ID (extraFrameworks);
DECLARE_ID (frameworkSearchPaths);
DECLARE_ID (extraCustomFrameworks);
DECLARE_ID (embeddedFrameworks);
DECLARE_ID (extraDLLs);
DECLARE_ID (winArchitecture);
DECLARE_ID (winWarningLevel);
DECLARE_ID (msvcManifestFile);
DECLARE_ID (warningsAreErrors);
DECLARE_ID (linuxArchitecture);
DECLARE_ID (linuxCodeBlocksArchitecture);
DECLARE_ID (windowsCodeBlocksArchitecture);
DECLARE_ID (codeBlocksWindowsTarget);
DECLARE_ID (toolset);
DECLARE_ID (windowsTargetPlatformVersion);
DECLARE_ID (debugInformationFormat);
DECLARE_ID (IPPLibrary);
DECLARE_ID (IPP1ALibrary);
DECLARE_ID (MKL1ALibrary);
DECLARE_ID (msvcModuleDefinitionFile);
DECLARE_ID (bigIcon);
DECLARE_ID (smallIcon);
DECLARE_ID (prebuildCommand);
DECLARE_ID (postbuildCommand);
DECLARE_ID (generateManifest);
DECLARE_ID (useRuntimeLibDLL);
DECLARE_ID (multiProcessorCompilation);
DECLARE_ID (enableIncrementalLinking);
DECLARE_ID (bundleIdentifier);
DECLARE_ID (aaxIdentifier);
DECLARE_ID (araFactoryID);
DECLARE_ID (araDocumentArchiveID);
DECLARE_ID (araCompatibleArchiveIDs);
DECLARE_ID (aaxFolder);
DECLARE_ID (araFolder);
DECLARE_ID (compile);
DECLARE_ID (noWarnings);
DECLARE_ID (skipPCH);
DECLARE_ID (resource);
DECLARE_ID (xcodeResource);
DECLARE_ID (xcodeValidArchs);
DECLARE_ID (className);
DECLARE_ID (classDesc);
DECLARE_ID (controlPoint);
DECLARE_ID (createCallback);
DECLARE_ID (parentClasses);
DECLARE_ID (constructorParams);
DECLARE_ID (objectConstructionArgs);
DECLARE_ID (memberInitialisers);
DECLARE_ID (canBeAggregated);
DECLARE_ID (rootItemVisible);
DECLARE_ID (openByDefault);
DECLARE_ID (locked);
DECLARE_ID (tooltip);
DECLARE_ID (memberName);
DECLARE_ID (markerName);
DECLARE_ID (focusOrder);
DECLARE_ID (hidden);
DECLARE_ID (useStdCall);
DECLARE_ID (useGlobalPath);
DECLARE_ID (showAllCode);
DECLARE_ID (useLocalCopy);
DECLARE_ID (overwriteOnSave);
DECLARE_ID (appSandbox);
DECLARE_ID (appSandboxInheritance);
DECLARE_ID (appSandboxOptions);
DECLARE_ID (appSandboxHomeDirRO);
DECLARE_ID (appSandboxHomeDirRW);
DECLARE_ID (appSandboxAbsDirRO);
DECLARE_ID (appSandboxAbsDirRW);
DECLARE_ID (hardenedRuntime);
DECLARE_ID (hardenedRuntimeOptions);
DECLARE_ID (microphonePermissionNeeded);
DECLARE_ID (microphonePermissionsText);
DECLARE_ID (cameraPermissionNeeded);
DECLARE_ID (cameraPermissionText);
DECLARE_ID (sendAppleEventsPermissionNeeded);
DECLARE_ID (sendAppleEventsPermissionText);
DECLARE_ID (androidJavaLibs);
DECLARE_ID (androidAdditionalJavaFolders);
DECLARE_ID (androidAdditionalResourceFolders);
DECLARE_ID (androidProjectRepositories);
DECLARE_ID (androidRepositories);
DECLARE_ID (androidDependencies);
DECLARE_ID (androidCustomAppBuildGradleContent);
DECLARE_ID (androidBuildConfigRemoteNotifsConfigFile);
DECLARE_ID (androidAdditionalXmlValueResources);
DECLARE_ID (androidAdditionalDrawableResources);
DECLARE_ID (androidAdditionalRawValueResources);
// DECLARE_ID (androidActivityClass); // DEPRECATED!
const Identifier androidCustomActivityClass ("androidActivitySubClassName"); // old name is very confusing, but we need to remain backward compatible
// DECLARE_ID (androidActivityBaseClassName); // DEPRECATED!
DECLARE_ID (androidCustomApplicationClass);
DECLARE_ID (androidVersionCode);
DECLARE_ID (androidSDKPath);
DECLARE_ID (androidOboeRepositoryPath);
DECLARE_ID (androidInternetNeeded);
DECLARE_ID (androidArchitectures);
DECLARE_ID (androidManifestCustomXmlElements);
DECLARE_ID (androidGradleSettingsContent);
DECLARE_ID (androidCustomStringXmlElements);
DECLARE_ID (androidBluetoothNeeded);
DECLARE_ID (androidExternalReadNeeded);
DECLARE_ID (androidExternalWriteNeeded);
DECLARE_ID (androidInAppBilling);
DECLARE_ID (androidVibratePermissionNeeded);
DECLARE_ID (androidPushNotifications);
DECLARE_ID (androidEnableRemoteNotifications);
DECLARE_ID (androidRemoteNotificationsConfigFile);
DECLARE_ID (androidEnableContentSharing);
DECLARE_ID (androidMinimumSDK);
DECLARE_ID (androidTargetSDK);
DECLARE_ID (androidOtherPermissions);
DECLARE_ID (androidKeyStore);
DECLARE_ID (androidKeyStorePass);
DECLARE_ID (androidKeyAlias);
DECLARE_ID (androidKeyAliasPass);
DECLARE_ID (androidTheme);
DECLARE_ID (androidStaticLibraries);
DECLARE_ID (androidSharedLibraries);
DECLARE_ID (androidScreenOrientation);
DECLARE_ID (androidExtraAssetsFolder);
DECLARE_ID (androidStudioExePath);
DECLARE_ID (iosDeviceFamily);
const Identifier iPhoneScreenOrientation ("iosScreenOrientation"); // old name is confusing
DECLARE_ID (iPadScreenOrientation);
DECLARE_ID (iosScreenOrientation);
DECLARE_ID (iosInAppPurchases);
DECLARE_ID (iosContentSharing);
DECLARE_ID (iosBackgroundAudio);
DECLARE_ID (iosBackgroundBle);
DECLARE_ID (iosPushNotifications);
DECLARE_ID (iosAppGroups);
DECLARE_ID (iCloudPermissions);
DECLARE_ID (networkingMulticast);
DECLARE_ID (iosDevelopmentTeamID);
DECLARE_ID (iosAppGroupsId);
DECLARE_ID (iosBluetoothPermissionNeeded);
DECLARE_ID (iosBluetoothPermissionText);
DECLARE_ID (duplicateAppExResourcesFolder);
DECLARE_ID (buildToolsVersion);
DECLARE_ID (gradleVersion);
const Identifier androidPluginVersion ("gradleWrapperVersion"); // old name is very confusing, but we need to remain backward compatible
DECLARE_ID (gradleToolchain);
DECLARE_ID (gradleToolchainVersion);
DECLARE_ID (linuxExtraPkgConfig);
DECLARE_ID (font);
DECLARE_ID (colour);
DECLARE_ID (userNotes);
DECLARE_ID (maxBinaryFileSize);
DECLARE_ID (includeBinaryInJuceHeader);
DECLARE_ID (binaryDataNamespace);
DECLARE_ID (characterSet);
DECLARE_ID (JUCERPROJECT);
DECLARE_ID (MAINGROUP);
DECLARE_ID (EXPORTFORMATS);
DECLARE_ID (GROUP);
DECLARE_ID (FILE);
DECLARE_ID (MODULES);
DECLARE_ID (MODULE);
DECLARE_ID (JUCEOPTIONS);
DECLARE_ID (CONFIGURATIONS);
DECLARE_ID (CONFIGURATION);
DECLARE_ID (MODULEPATHS);
DECLARE_ID (MODULEPATH);
DECLARE_ID (PATH);
DECLARE_ID (userpath);
DECLARE_ID (systempath);
DECLARE_ID (utilsCppInclude);
DECLARE_ID (juceModulesFolder);
DECLARE_ID (parentActive);
DECLARE_ID (message);
DECLARE_ID (start);
DECLARE_ID (end);
DECLARE_ID (range);
DECLARE_ID (location);
DECLARE_ID (key);
DECLARE_ID (list);
DECLARE_ID (METADATA);
DECLARE_ID (DEPENDENCIES);
DECLARE_ID (CLASSLIST);
DECLARE_ID (CLASS);
DECLARE_ID (MEMBER);
DECLARE_ID (METHOD);
DECLARE_ID (LITERALS);
DECLARE_ID (LITERAL);
DECLARE_ID (abstract);
DECLARE_ID (anonymous);
DECLARE_ID (noDefConstructor);
DECLARE_ID (returnType);
DECLARE_ID (numArgs);
DECLARE_ID (declaration);
DECLARE_ID (definition);
DECLARE_ID (classDecl);
DECLARE_ID (initialisers);
DECLARE_ID (destructors);
DECLARE_ID (pluginFormats);
DECLARE_ID (buildVST);
DECLARE_ID (buildVST3);
DECLARE_ID (buildAU);
DECLARE_ID (buildAUv3);
DECLARE_ID (buildAAX);
DECLARE_ID (buildStandalone);
DECLARE_ID (buildUnity);
DECLARE_ID (buildLV2);
DECLARE_ID (enableIAA);
DECLARE_ID (enableARA);
DECLARE_ID (pluginName);
DECLARE_ID (pluginDesc);
DECLARE_ID (pluginManufacturer);
DECLARE_ID (pluginManufacturerCode);
DECLARE_ID (pluginCode);
DECLARE_ID (pluginChannelConfigs);
DECLARE_ID (pluginCharacteristicsValue);
DECLARE_ID (pluginCharacteristics);
DECLARE_ID (extraPluginFormats);
DECLARE_ID (pluginIsSynth);
DECLARE_ID (pluginWantsMidiIn);
DECLARE_ID (pluginProducesMidiOut);
DECLARE_ID (pluginIsMidiEffectPlugin);
DECLARE_ID (pluginEditorRequiresKeys);
DECLARE_ID (pluginVSTCategory);
DECLARE_ID (pluginVST3Category);
DECLARE_ID (pluginAUExportPrefix);
DECLARE_ID (pluginAUMainType);
DECLARE_ID (pluginAUIsSandboxSafe);
DECLARE_ID (pluginAAXCategory);
DECLARE_ID (pluginAAXDisableBypass);
DECLARE_ID (pluginAAXDisableMultiMono);
DECLARE_ID (pluginARAAnalyzableContent);
DECLARE_ID (pluginARATransformFlags);
DECLARE_ID (pluginVSTNumMidiInputs);
DECLARE_ID (pluginVSTNumMidiOutputs);
DECLARE_ID (suppressPlistResourceUsage);
DECLARE_ID (useLegacyBuildSystem);
DECLARE_ID (exporters);
DECLARE_ID (website);
DECLARE_ID (mainClass);
DECLARE_ID (documentControllerClass);
DECLARE_ID (moduleFlags);
DECLARE_ID (projectLineFeed);
DECLARE_ID (compilerFlagSchemes);
DECLARE_ID (compilerFlagScheme);
DECLARE_ID (dontQueryForUpdate);
DECLARE_ID (dontAskAboutJUCEPath);
DECLARE_ID (postExportShellCommandPosix);
DECLARE_ID (postExportShellCommandWin);
DECLARE_ID (guiEditorEnabled);
DECLARE_ID (jucerFormatVersion);
DECLARE_ID (buildNumber);
DECLARE_ID (lv2Uri);
DECLARE_ID (lv2UriUi);
DECLARE_ID (lv2BinaryLocation);
DECLARE_ID (osxSDK);
DECLARE_ID (osxCompatibility);
DECLARE_ID (iosCompatibility);
const Identifier ID ("id");
const Identifier ID_uppercase ("ID");
const Identifier class_ ("class");
const Identifier dependencies_ ("dependencies");
#undef DECLARE_ID
}

View File

@ -1,326 +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
//==============================================================================
struct TranslationHelpers
{
static void addString (StringArray& strings, const String& s)
{
if (s.isNotEmpty() && ! strings.contains (s))
strings.add (s);
}
static void scanFileForTranslations (StringArray& strings, const File& file)
{
auto content = file.loadFileAsString();
auto p = content.getCharPointer();
for (;;)
{
p = CharacterFunctions::find (p, CharPointer_ASCII ("TRANS"));
if (p.isEmpty())
break;
p += 5;
p.incrementToEndOfWhitespace();
if (*p == '(')
{
++p;
MemoryOutputStream text;
parseStringLiteral (p, text);
addString (strings, text.toString());
}
}
}
static void parseStringLiteral (String::CharPointerType& p, MemoryOutputStream& out) noexcept
{
p.incrementToEndOfWhitespace();
if (p.getAndAdvance() == '"')
{
auto start = p;
for (;;)
{
auto c = *p;
if (c == '"')
{
out << String (start, p);
++p;
parseStringLiteral (p, out);
return;
}
if (c == 0)
break;
if (c == '\\')
{
out << String (start, p);
++p;
out << String::charToString (readEscapedChar (p));
start = p + 1;
}
++p;
}
}
}
static juce_wchar readEscapedChar (String::CharPointerType& p)
{
auto c = *p;
switch (c)
{
case '"':
case '\\':
case '/': break;
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'x':
++p;
c = 0;
for (int i = 4; --i >= 0;)
{
const int digitValue = CharacterFunctions::getHexDigitValue (*p);
if (digitValue < 0)
break;
++p;
c = (c << 4) + (juce_wchar) digitValue;
}
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
c = 0;
for (int i = 4; --i >= 0;)
{
const auto digitValue = (int) (*p - '0');
if (digitValue < 0 || digitValue > 7)
break;
++p;
c = (c << 3) + (juce_wchar) digitValue;
}
break;
default:
break;
}
return c;
}
static void scanFilesForTranslations (StringArray& strings, const Project::Item& p)
{
if (p.isFile())
{
const File file (p.getFile());
if (file.hasFileExtension (sourceOrHeaderFileExtensions))
scanFileForTranslations (strings, file);
}
for (int i = 0; i < p.getNumChildren(); ++i)
scanFilesForTranslations (strings, p.getChild (i));
}
static void scanFolderForTranslations (StringArray& strings, const File& root)
{
for (const auto& i : RangedDirectoryIterator (root, true))
{
const auto file = i.getFile();
if (file.hasFileExtension (sourceOrHeaderFileExtensions))
scanFileForTranslations(strings, file);
}
}
static void scanProject (StringArray& strings, Project& project)
{
scanFilesForTranslations (strings, project.getMainGroup());
OwnedArray<LibraryModule> modules;
project.getEnabledModules().createRequiredModules (modules);
for (int j = 0; j < modules.size(); ++j)
{
const File localFolder (modules.getUnchecked(j)->getFolder());
Array<File> files;
modules.getUnchecked(j)->findBrowseableFiles (localFolder, files);
for (int i = 0; i < files.size(); ++i)
scanFileForTranslations (strings, files.getReference(i));
}
}
static const char* getMungingSeparator() { return "JCTRIDX"; }
static StringArray breakApart (const String& munged)
{
StringArray lines, result;
lines.addLines (munged);
String currentItem;
for (int i = 0; i < lines.size(); ++i)
{
if (lines[i].contains (getMungingSeparator()))
{
if (currentItem.isNotEmpty())
result.add (currentItem);
currentItem = String();
}
else
{
if (currentItem.isNotEmpty())
currentItem << newLine;
currentItem << lines[i];
}
}
if (currentItem.isNotEmpty())
result.add (currentItem);
return result;
}
static StringArray withTrimmedEnds (StringArray array)
{
for (auto& s : array)
s = s.trimEnd().removeCharacters ("\r\n");
return array;
}
static String escapeString (const String& s)
{
return s.replace ("\"", "\\\"")
.replace ("\'", "\\\'")
.replace ("\t", "\\t")
.replace ("\r", "\\r")
.replace ("\n", "\\n");
}
static String getPreTranslationText (Project& project)
{
StringArray strings;
scanProject (strings, project);
return mungeStrings (strings);
}
static String getPreTranslationText (const LocalisedStrings& strings)
{
return mungeStrings (strings.getMappings().getAllKeys());
}
static String mungeStrings (const StringArray& strings)
{
MemoryOutputStream s;
for (int i = 0; i < strings.size(); ++i)
{
s << getMungingSeparator() << i << "." << newLine << strings[i];
if (i < strings.size() - 1)
s << newLine;
}
return s.toString();
}
static String createLine (const String& preString, const String& postString)
{
return "\"" + escapeString (preString)
+ "\" = \""
+ escapeString (postString) + "\"";
}
static String createFinishedTranslationFile (StringArray preStrings,
StringArray postStrings,
const LocalisedStrings& original)
{
const StringPairArray& originalStrings (original.getMappings());
StringArray lines;
if (originalStrings.size() > 0)
{
lines.add ("language: " + original.getLanguageName());
lines.add ("countries: " + original.getCountryCodes().joinIntoString (" "));
lines.add (String());
const StringArray& originalKeys (originalStrings.getAllKeys());
const StringArray& originalValues (originalStrings.getAllValues());
int numRemoved = 0;
for (int i = preStrings.size(); --i >= 0;)
{
if (originalKeys.contains (preStrings[i]))
{
preStrings.remove (i);
postStrings.remove (i);
++numRemoved;
}
}
for (int i = 0; i < originalStrings.size(); ++i)
lines.add (createLine (originalKeys[i], originalValues[i]));
}
else
{
lines.add ("language: [enter full name of the language here!]");
lines.add ("countries: [enter list of 2-character country codes here!]");
lines.add (String());
}
for (int i = 0; i < preStrings.size(); ++i)
lines.add (createLine (preStrings[i], postStrings[i]));
return lines.joinIntoString (newLine);
}
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 TranslationHelpers
{
static void addString (StringArray& strings, const String& s)
{
if (s.isNotEmpty() && ! strings.contains (s))
strings.add (s);
}
static void scanFileForTranslations (StringArray& strings, const File& file)
{
auto content = file.loadFileAsString();
auto p = content.getCharPointer();
for (;;)
{
p = CharacterFunctions::find (p, CharPointer_ASCII ("TRANS"));
if (p.isEmpty())
break;
p += 5;
p.incrementToEndOfWhitespace();
if (*p == '(')
{
++p;
MemoryOutputStream text;
parseStringLiteral (p, text);
addString (strings, text.toString());
}
}
}
static void parseStringLiteral (String::CharPointerType& p, MemoryOutputStream& out) noexcept
{
p.incrementToEndOfWhitespace();
if (p.getAndAdvance() == '"')
{
auto start = p;
for (;;)
{
auto c = *p;
if (c == '"')
{
out << String (start, p);
++p;
parseStringLiteral (p, out);
return;
}
if (c == 0)
break;
if (c == '\\')
{
out << String (start, p);
++p;
out << String::charToString (readEscapedChar (p));
start = p + 1;
}
++p;
}
}
}
static juce_wchar readEscapedChar (String::CharPointerType& p)
{
auto c = *p;
switch (c)
{
case '"':
case '\\':
case '/': break;
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'x':
++p;
c = 0;
for (int i = 4; --i >= 0;)
{
const int digitValue = CharacterFunctions::getHexDigitValue (*p);
if (digitValue < 0)
break;
++p;
c = (c << 4) + (juce_wchar) digitValue;
}
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
c = 0;
for (int i = 4; --i >= 0;)
{
const auto digitValue = (int) (*p - '0');
if (digitValue < 0 || digitValue > 7)
break;
++p;
c = (c << 3) + (juce_wchar) digitValue;
}
break;
default:
break;
}
return c;
}
static void scanFilesForTranslations (StringArray& strings, const Project::Item& p)
{
if (p.isFile())
{
const File file (p.getFile());
if (file.hasFileExtension (sourceOrHeaderFileExtensions))
scanFileForTranslations (strings, file);
}
for (int i = 0; i < p.getNumChildren(); ++i)
scanFilesForTranslations (strings, p.getChild (i));
}
static void scanFolderForTranslations (StringArray& strings, const File& root)
{
for (const auto& i : RangedDirectoryIterator (root, true))
{
const auto file = i.getFile();
if (file.hasFileExtension (sourceOrHeaderFileExtensions))
scanFileForTranslations(strings, file);
}
}
static void scanProject (StringArray& strings, Project& project)
{
scanFilesForTranslations (strings, project.getMainGroup());
OwnedArray<LibraryModule> modules;
project.getEnabledModules().createRequiredModules (modules);
for (int j = 0; j < modules.size(); ++j)
{
const File localFolder (modules.getUnchecked(j)->getFolder());
Array<File> files;
modules.getUnchecked(j)->findBrowseableFiles (localFolder, files);
for (int i = 0; i < files.size(); ++i)
scanFileForTranslations (strings, files.getReference(i));
}
}
static const char* getMungingSeparator() { return "JCTRIDX"; }
static StringArray breakApart (const String& munged)
{
StringArray lines, result;
lines.addLines (munged);
String currentItem;
for (int i = 0; i < lines.size(); ++i)
{
if (lines[i].contains (getMungingSeparator()))
{
if (currentItem.isNotEmpty())
result.add (currentItem);
currentItem = String();
}
else
{
if (currentItem.isNotEmpty())
currentItem << newLine;
currentItem << lines[i];
}
}
if (currentItem.isNotEmpty())
result.add (currentItem);
return result;
}
static StringArray withTrimmedEnds (StringArray array)
{
for (auto& s : array)
s = s.trimEnd().removeCharacters ("\r\n");
return array;
}
static String escapeString (const String& s)
{
return s.replace ("\"", "\\\"")
.replace ("\'", "\\\'")
.replace ("\t", "\\t")
.replace ("\r", "\\r")
.replace ("\n", "\\n");
}
static String getPreTranslationText (Project& project)
{
StringArray strings;
scanProject (strings, project);
return mungeStrings (strings);
}
static String getPreTranslationText (const LocalisedStrings& strings)
{
return mungeStrings (strings.getMappings().getAllKeys());
}
static String mungeStrings (const StringArray& strings)
{
MemoryOutputStream s;
for (int i = 0; i < strings.size(); ++i)
{
s << getMungingSeparator() << i << "." << newLine << strings[i];
if (i < strings.size() - 1)
s << newLine;
}
return s.toString();
}
static String createLine (const String& preString, const String& postString)
{
return "\"" + escapeString (preString)
+ "\" = \""
+ escapeString (postString) + "\"";
}
static String createFinishedTranslationFile (StringArray preStrings,
StringArray postStrings,
const LocalisedStrings& original)
{
const StringPairArray& originalStrings (original.getMappings());
StringArray lines;
if (originalStrings.size() > 0)
{
lines.add ("language: " + original.getLanguageName());
lines.add ("countries: " + original.getCountryCodes().joinIntoString (" "));
lines.add (String());
const StringArray& originalKeys (originalStrings.getAllKeys());
const StringArray& originalValues (originalStrings.getAllValues());
int numRemoved = 0;
for (int i = preStrings.size(); --i >= 0;)
{
if (originalKeys.contains (preStrings[i]))
{
preStrings.remove (i);
postStrings.remove (i);
++numRemoved;
}
}
for (int i = 0; i < originalStrings.size(); ++i)
lines.add (createLine (originalKeys[i], originalValues[i]));
}
else
{
lines.add ("language: [enter full name of the language here!]");
lines.add ("countries: [enter list of 2-character country codes here!]");
lines.add (String());
}
for (int i = 0; i < preStrings.size(); ++i)
lines.add (createLine (preStrings[i], postStrings[i]));
return lines.joinIntoString (newLine);
}
};

View File

@ -1,50 +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
//==============================================================================
template <typename Type>
class NumericValueSource : public ValueSourceFilter
{
public:
NumericValueSource (const Value& source) : ValueSourceFilter (source) {}
var getValue() const override
{
return (Type) sourceValue.getValue();
}
void setValue (const var& newValue) override
{
const Type newVal = static_cast<Type> (newValue);
if (newVal != static_cast<Type> (getValue())) // this test is important, because if a property is missing, it won't
sourceValue = newVal; // create it (causing an unwanted undo action) when a control sets it to 0
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NumericValueSource)
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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
//==============================================================================
template <typename Type>
class NumericValueSource : public ValueSourceFilter
{
public:
NumericValueSource (const Value& source) : ValueSourceFilter (source) {}
var getValue() const override
{
return (Type) sourceValue.getValue();
}
void setValue (const var& newValue) override
{
const Type newVal = static_cast<Type> (newValue);
if (newVal != static_cast<Type> (getValue())) // this test is important, because if a property is missing, it won't
sourceValue = newVal; // create it (causing an unwanted undo action) when a control sets it to 0
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NumericValueSource)
};

View File

@ -1,73 +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
//==============================================================================
/**
Wraps a ValueWithDefault object that has a default which depends on a global value.
*/
class ValueWithDefaultWrapper : private Value::Listener
{
public:
ValueWithDefaultWrapper() = default;
void init (const ValueWithDefault& vwd, ValueWithDefault global, TargetOS::OS targetOS)
{
wrappedValue = vwd;
globalValue = global.getPropertyAsValue();
globalIdentifier = global.getPropertyID();
os = targetOS;
if (wrappedValue.get() == var())
wrappedValue.resetToDefault();
globalValue.addListener (this);
valueChanged (globalValue);
}
ValueWithDefault& getWrappedValueWithDefault()
{
return wrappedValue;
}
var getCurrentValue() const
{
return wrappedValue.get();
}
private:
void valueChanged (Value&) override
{
wrappedValue.setDefault (getAppSettings().getStoredPath (globalIdentifier, os).get());
}
ValueWithDefault wrappedValue;
Value globalValue;
Identifier globalIdentifier;
TargetOS::OS os;
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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
//==============================================================================
/**
Wraps a ValueTreePropertyWithDefault object that has a default which depends on a global value.
*/
class ValueTreePropertyWithDefaultWrapper : private Value::Listener
{
public:
ValueTreePropertyWithDefaultWrapper() = default;
void init (const ValueTreePropertyWithDefault& v,
ValueTreePropertyWithDefault global,
TargetOS::OS targetOS)
{
wrappedValue = v;
globalValue = global.getPropertyAsValue();
globalIdentifier = global.getPropertyID();
os = targetOS;
if (wrappedValue.get() == var())
wrappedValue.resetToDefault();
globalValue.addListener (this);
valueChanged (globalValue);
}
ValueTreePropertyWithDefault& getWrappedValueTreePropertyWithDefault()
{
return wrappedValue;
}
var getCurrentValue() const
{
return wrappedValue.get();
}
private:
void valueChanged (Value&) override
{
wrappedValue.setDefault (getAppSettings().getStoredPath (globalIdentifier, os).get());
}
ValueTreePropertyWithDefault wrappedValue;
Value globalValue;
Identifier globalIdentifier;
TargetOS::OS os;
};

View File

@ -1,126 +1,126 @@
/*
==============================================================================
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_VersionInfo.h"
VersionInfo::VersionInfo (String versionIn, String releaseNotesIn, std::vector<Asset> assetsIn)
: versionString (std::move (versionIn)),
releaseNotes (std::move (releaseNotesIn)),
assets (std::move (assetsIn))
{}
std::unique_ptr<VersionInfo> VersionInfo::fetchFromUpdateServer (const String& versionString)
{
return fetch ("tags/" + versionString);
}
std::unique_ptr<VersionInfo> VersionInfo::fetchLatestFromUpdateServer()
{
return fetch ("latest");
}
std::unique_ptr<InputStream> VersionInfo::createInputStreamForAsset (const Asset& asset, int& statusCode)
{
URL downloadUrl (asset.url);
StringPairArray responseHeaders;
return std::unique_ptr<InputStream> (downloadUrl.createInputStream (URL::InputStreamOptions (URL::ParameterHandling::inAddress)
.withExtraHeaders ("Accept: application/octet-stream")
.withConnectionTimeoutMs (5000)
.withResponseHeaders (&responseHeaders)
.withStatusCode (&statusCode)
.withNumRedirectsToFollow (1)));
}
bool VersionInfo::isNewerVersionThanCurrent()
{
jassert (versionString.isNotEmpty());
auto currentTokens = StringArray::fromTokens (ProjectInfo::versionString, ".", {});
auto thisTokens = StringArray::fromTokens (versionString, ".", {});
jassert (thisTokens.size() == 3);
if (currentTokens[0].getIntValue() == thisTokens[0].getIntValue())
{
if (currentTokens[1].getIntValue() == thisTokens[1].getIntValue())
return currentTokens[2].getIntValue() < thisTokens[2].getIntValue();
return currentTokens[1].getIntValue() < thisTokens[1].getIntValue();
}
return currentTokens[0].getIntValue() < thisTokens[0].getIntValue();
}
std::unique_ptr<VersionInfo> VersionInfo::fetch (const String& endpoint)
{
URL latestVersionURL ("https://api.github.com/repos/juce-framework/JUCE/releases/" + endpoint);
std::unique_ptr<InputStream> inStream (latestVersionURL.createInputStream (URL::InputStreamOptions (URL::ParameterHandling::inAddress)
.withConnectionTimeoutMs (5000)));
if (inStream == nullptr)
return nullptr;
auto content = inStream->readEntireStreamAsString();
auto latestReleaseDetails = JSON::parse (content);
auto* json = latestReleaseDetails.getDynamicObject();
if (json == nullptr)
return nullptr;
auto versionString = json->getProperty ("tag_name").toString();
if (versionString.isEmpty())
return nullptr;
auto* assets = json->getProperty ("assets").getArray();
if (assets == nullptr)
return nullptr;
auto releaseNotes = json->getProperty ("body").toString();
std::vector<VersionInfo::Asset> parsedAssets;
for (auto& asset : *assets)
{
if (auto* assetJson = asset.getDynamicObject())
{
parsedAssets.push_back ({ assetJson->getProperty ("name").toString(),
assetJson->getProperty ("url").toString() });
jassert (parsedAssets.back().name.isNotEmpty());
jassert (parsedAssets.back().url.isNotEmpty());
}
else
{
jassertfalse;
}
}
return std::unique_ptr<VersionInfo> (new VersionInfo { versionString, releaseNotes, std::move (parsedAssets) });
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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_VersionInfo.h"
VersionInfo::VersionInfo (String versionIn, String releaseNotesIn, std::vector<Asset> assetsIn)
: versionString (std::move (versionIn)),
releaseNotes (std::move (releaseNotesIn)),
assets (std::move (assetsIn))
{}
std::unique_ptr<VersionInfo> VersionInfo::fetchFromUpdateServer (const String& versionString)
{
return fetch ("tags/" + versionString);
}
std::unique_ptr<VersionInfo> VersionInfo::fetchLatestFromUpdateServer()
{
return fetch ("latest");
}
std::unique_ptr<InputStream> VersionInfo::createInputStreamForAsset (const Asset& asset, int& statusCode)
{
URL downloadUrl (asset.url);
StringPairArray responseHeaders;
return std::unique_ptr<InputStream> (downloadUrl.createInputStream (URL::InputStreamOptions (URL::ParameterHandling::inAddress)
.withExtraHeaders ("Accept: application/octet-stream")
.withConnectionTimeoutMs (5000)
.withResponseHeaders (&responseHeaders)
.withStatusCode (&statusCode)
.withNumRedirectsToFollow (1)));
}
bool VersionInfo::isNewerVersionThanCurrent()
{
jassert (versionString.isNotEmpty());
auto currentTokens = StringArray::fromTokens (ProjectInfo::versionString, ".", {});
auto thisTokens = StringArray::fromTokens (versionString, ".", {});
jassert (thisTokens.size() == 3);
if (currentTokens[0].getIntValue() == thisTokens[0].getIntValue())
{
if (currentTokens[1].getIntValue() == thisTokens[1].getIntValue())
return currentTokens[2].getIntValue() < thisTokens[2].getIntValue();
return currentTokens[1].getIntValue() < thisTokens[1].getIntValue();
}
return currentTokens[0].getIntValue() < thisTokens[0].getIntValue();
}
std::unique_ptr<VersionInfo> VersionInfo::fetch (const String& endpoint)
{
URL latestVersionURL ("https://api.github.com/repos/juce-framework/JUCE/releases/" + endpoint);
std::unique_ptr<InputStream> inStream (latestVersionURL.createInputStream (URL::InputStreamOptions (URL::ParameterHandling::inAddress)
.withConnectionTimeoutMs (5000)));
if (inStream == nullptr)
return nullptr;
auto content = inStream->readEntireStreamAsString();
auto latestReleaseDetails = JSON::parse (content);
auto* json = latestReleaseDetails.getDynamicObject();
if (json == nullptr)
return nullptr;
auto versionString = json->getProperty ("tag_name").toString();
if (versionString.isEmpty())
return nullptr;
auto* assets = json->getProperty ("assets").getArray();
if (assets == nullptr)
return nullptr;
auto releaseNotes = json->getProperty ("body").toString();
std::vector<VersionInfo::Asset> parsedAssets;
for (auto& asset : *assets)
{
if (auto* assetJson = asset.getDynamicObject())
{
parsedAssets.push_back ({ assetJson->getProperty ("name").toString(),
assetJson->getProperty ("url").toString() });
jassert (parsedAssets.back().name.isNotEmpty());
jassert (parsedAssets.back().url.isNotEmpty());
}
else
{
jassertfalse;
}
}
return std::unique_ptr<VersionInfo> (new VersionInfo { versionString, releaseNotes, std::move (parsedAssets) });
}

View File

@ -1,53 +1,53 @@
/*
==============================================================================
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 VersionInfo
{
public:
struct Asset
{
const String name;
const String url;
};
static std::unique_ptr<VersionInfo> fetchFromUpdateServer (const String& versionString);
static std::unique_ptr<VersionInfo> fetchLatestFromUpdateServer();
static std::unique_ptr<InputStream> createInputStreamForAsset (const Asset& asset, int& statusCode);
bool isNewerVersionThanCurrent();
const String versionString;
const String releaseNotes;
const std::vector<Asset> assets;
private:
VersionInfo (String version, String releaseNotes, std::vector<Asset> assets);
static std::unique_ptr<VersionInfo> fetch (const String&);
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 VersionInfo
{
public:
struct Asset
{
const String name;
const String url;
};
static std::unique_ptr<VersionInfo> fetchFromUpdateServer (const String& versionString);
static std::unique_ptr<VersionInfo> fetchLatestFromUpdateServer();
static std::unique_ptr<InputStream> createInputStreamForAsset (const Asset& asset, int& statusCode);
bool isNewerVersionThanCurrent();
const String versionString;
const String releaseNotes;
const std::vector<Asset> assets;
private:
VersionInfo (String version, String releaseNotes, std::vector<Asset> assets);
static std::unique_ptr<VersionInfo> fetch (const String&);
};

File diff suppressed because it is too large Load Diff

View File

@ -1,86 +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
#include "../Helpers/jucer_MiscUtilities.h"
#include "../../Project/Modules/jucer_AvailableModulesList.h"
//==============================================================================
class PIPGenerator
{
public:
PIPGenerator (const File& pipFile, const File& outputDirectory = {},
const File& pathToJUCEModules = {}, const File& pathToUserModules = {});
//==============================================================================
bool hasValidPIP() const noexcept { return ! metadata[Ids::name].toString().isEmpty(); }
File getJucerFile() const noexcept { return outputDirectory.getChildFile (metadata[Ids::name].toString() + ".jucer"); }
File getPIPFile() const noexcept { return useLocalCopy ? outputDirectory.getChildFile ("Source").getChildFile (pipFile.getFileName()) : pipFile; }
String getMainClassName() const noexcept { return metadata[Ids::mainClass]; }
File getOutputDirectory() const noexcept { return outputDirectory; }
//==============================================================================
Result createJucerFile();
Result createMainCpp();
private:
//==============================================================================
void addFileToTree (ValueTree& groupTree, const String& name, bool compile, const String& path);
void createFiles (ValueTree& jucerTree);
ValueTree createModulePathChild (const String& moduleID);
ValueTree createBuildConfigChild (bool isDebug);
ValueTree createExporterChild (const Identifier& exporterIdentifier);
ValueTree createModuleChild (const String& moduleID);
void addExporters (ValueTree& jucerTree);
void addModules (ValueTree& jucerTree);
Result setProjectSettings (ValueTree& jucerTree);
void setModuleFlags (ValueTree& jucerTree);
String getMainFileTextForType();
//==============================================================================
Array<File> replaceRelativeIncludesAndGetFilesToMove();
bool copyRelativeFileToLocalSourceDirectory (const File&) const noexcept;
StringArray getExtraPluginFormatsToBuild() const;
String getPathForModule (const String&) const;
File getExamplesDirectory() const;
//==============================================================================
File pipFile, outputDirectory, juceModulesPath, userModulesPath;
std::unique_ptr<AvailableModulesList> availableUserModules;
var metadata;
bool isTemp = false, useLocalCopy = false;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PIPGenerator)
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 "../Helpers/jucer_MiscUtilities.h"
#include "../../Project/Modules/jucer_AvailableModulesList.h"
//==============================================================================
class PIPGenerator
{
public:
PIPGenerator (const File& pipFile, const File& outputDirectory = {},
const File& pathToJUCEModules = {}, const File& pathToUserModules = {});
//==============================================================================
bool hasValidPIP() const noexcept { return ! metadata[Ids::name].toString().isEmpty(); }
File getJucerFile() const noexcept { return outputDirectory.getChildFile (metadata[Ids::name].toString() + ".jucer"); }
File getPIPFile() const noexcept { return useLocalCopy ? outputDirectory.getChildFile ("Source").getChildFile (pipFile.getFileName()) : pipFile; }
String getMainClassName() const noexcept { return metadata[Ids::mainClass]; }
File getOutputDirectory() const noexcept { return outputDirectory; }
//==============================================================================
Result createJucerFile();
Result createMainCpp();
private:
//==============================================================================
void addFileToTree (ValueTree& groupTree, const String& name, bool compile, const String& path);
void createFiles (ValueTree& jucerTree);
String getDocumentControllerClass() const;
ValueTree createModulePathChild (const String& moduleID);
ValueTree createBuildConfigChild (bool isDebug);
ValueTree createExporterChild (const Identifier& exporterIdentifier);
ValueTree createModuleChild (const String& moduleID);
void addExporters (ValueTree& jucerTree);
void addModules (ValueTree& jucerTree);
Result setProjectSettings (ValueTree& jucerTree);
void setModuleFlags (ValueTree& jucerTree);
String getMainFileTextForType();
//==============================================================================
Array<File> replaceRelativeIncludesAndGetFilesToMove();
bool copyRelativeFileToLocalSourceDirectory (const File&) const noexcept;
StringArray getExtraPluginFormatsToBuild() const;
String getPathForModule (const String&) const;
File getExamplesDirectory() const;
//==============================================================================
File pipFile, outputDirectory, juceModulesPath, userModulesPath;
std::unique_ptr<AvailableModulesList> availableUserModules;
var metadata;
bool isTemp = false, useLocalCopy = false;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PIPGenerator)
};

View File

@ -1,224 +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
//==============================================================================
struct ColourPropertyComponent : public PropertyComponent
{
ColourPropertyComponent (UndoManager* undoManager, const String& name, const Value& colour,
Colour defaultColour, bool canResetToDefault)
: PropertyComponent (name),
colourEditor (undoManager, colour, defaultColour, canResetToDefault)
{
addAndMakeVisible (colourEditor);
}
void resized() override
{
colourEditor.setBounds (getLookAndFeel().getPropertyComponentContentPosition (*this));
}
void refresh() override {}
private:
/**
A component that shows a colour swatch with hex ARGB value, and which pops up
a colour selector when you click it.
*/
struct ColourEditorComponent : public Component,
private Value::Listener
{
ColourEditorComponent (UndoManager* um, const Value& colour,
Colour defaultCol, const bool canReset)
: undoManager (um), colourValue (colour), defaultColour (defaultCol),
canResetToDefault (canReset)
{
colourValue.addListener (this);
}
void paint (Graphics& g) override
{
const Colour colour (getColour());
g.fillAll (Colours::grey);
g.fillCheckerBoard (getLocalBounds().reduced (2).toFloat(),
10.0f, 10.0f,
Colour (0xffdddddd).overlaidWith (colour),
Colour (0xffffffff).overlaidWith (colour));
g.setColour (Colours::white.overlaidWith (colour).contrasting());
g.setFont (Font ((float) getHeight() * 0.6f, Font::bold));
g.drawFittedText (colour.toDisplayString (true), getLocalBounds().reduced (2, 1),
Justification::centred, 1);
}
Colour getColour() const
{
if (colourValue.toString().isEmpty())
return defaultColour;
return Colour::fromString (colourValue.toString());
}
void setColour (Colour newColour)
{
if (getColour() != newColour)
{
if (newColour == defaultColour && canResetToDefault)
colourValue = var();
else
colourValue = newColour.toDisplayString (true);
}
}
void resetToDefault()
{
setColour (defaultColour);
}
void refresh()
{
const Colour col (getColour());
if (col != lastColour)
{
lastColour = col;
repaint();
}
}
void mouseDown (const MouseEvent&) override
{
if (undoManager != nullptr)
undoManager->beginNewTransaction();
CallOutBox::launchAsynchronously (std::make_unique<PopupColourSelector> (colourValue,
defaultColour,
canResetToDefault),
getScreenBounds(),
nullptr);
}
private:
void valueChanged (Value&) override
{
refresh();
}
UndoManager* undoManager;
Value colourValue;
Colour lastColour;
const Colour defaultColour;
const bool canResetToDefault;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ColourEditorComponent)
};
//==============================================================================
struct PopupColourSelector : public Component,
private ChangeListener,
private Value::Listener
{
PopupColourSelector (const Value& colour,
Colour defaultCol,
const bool canResetToDefault)
: defaultButton ("Reset to Default"),
colourValue (colour),
defaultColour (defaultCol)
{
addAndMakeVisible (selector);
selector.setName ("Colour");
selector.setCurrentColour (getColour());
selector.addChangeListener (this);
if (canResetToDefault)
{
addAndMakeVisible (defaultButton);
defaultButton.onClick = [this]
{
setColour (defaultColour);
selector.setCurrentColour (defaultColour);
};
}
colourValue.addListener (this);
setSize (300, 400);
}
void resized() override
{
if (defaultButton.isVisible())
{
selector.setBounds (0, 0, getWidth(), getHeight() - 30);
defaultButton.changeWidthToFitText (22);
defaultButton.setTopLeftPosition (10, getHeight() - 26);
}
else
{
selector.setBounds (getLocalBounds());
}
}
Colour getColour() const
{
if (colourValue.toString().isEmpty())
return defaultColour;
return Colour::fromString (colourValue.toString());
}
void setColour (Colour newColour)
{
if (getColour() != newColour)
{
if (newColour == defaultColour && defaultButton.isVisible())
colourValue = var();
else
colourValue = newColour.toDisplayString (true);
}
}
private:
void changeListenerCallback (ChangeBroadcaster*) override
{
if (selector.getCurrentColour() != getColour())
setColour (selector.getCurrentColour());
}
void valueChanged (Value&) override
{
selector.setCurrentColour (getColour());
}
StoredSettings::ColourSelectorWithSwatches selector;
TextButton defaultButton;
Value colourValue;
Colour defaultColour;
};
ColourEditorComponent colourEditor;
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 ColourPropertyComponent : public PropertyComponent
{
ColourPropertyComponent (UndoManager* undoManager, const String& name, const Value& colour,
Colour defaultColour, bool canResetToDefault)
: PropertyComponent (name),
colourEditor (undoManager, colour, defaultColour, canResetToDefault)
{
addAndMakeVisible (colourEditor);
}
void resized() override
{
colourEditor.setBounds (getLookAndFeel().getPropertyComponentContentPosition (*this));
}
void refresh() override {}
private:
/**
A component that shows a colour swatch with hex ARGB value, and which pops up
a colour selector when you click it.
*/
struct ColourEditorComponent : public Component,
private Value::Listener
{
ColourEditorComponent (UndoManager* um, const Value& colour,
Colour defaultCol, const bool canReset)
: undoManager (um), colourValue (colour), defaultColour (defaultCol),
canResetToDefault (canReset)
{
colourValue.addListener (this);
}
void paint (Graphics& g) override
{
const Colour colour (getColour());
g.fillAll (Colours::grey);
g.fillCheckerBoard (getLocalBounds().reduced (2).toFloat(),
10.0f, 10.0f,
Colour (0xffdddddd).overlaidWith (colour),
Colour (0xffffffff).overlaidWith (colour));
g.setColour (Colours::white.overlaidWith (colour).contrasting());
g.setFont (Font ((float) getHeight() * 0.6f, Font::bold));
g.drawFittedText (colour.toDisplayString (true), getLocalBounds().reduced (2, 1),
Justification::centred, 1);
}
Colour getColour() const
{
if (colourValue.toString().isEmpty())
return defaultColour;
return Colour::fromString (colourValue.toString());
}
void setColour (Colour newColour)
{
if (getColour() != newColour)
{
if (newColour == defaultColour && canResetToDefault)
colourValue = var();
else
colourValue = newColour.toDisplayString (true);
}
}
void resetToDefault()
{
setColour (defaultColour);
}
void refresh()
{
const Colour col (getColour());
if (col != lastColour)
{
lastColour = col;
repaint();
}
}
void mouseDown (const MouseEvent&) override
{
if (undoManager != nullptr)
undoManager->beginNewTransaction();
CallOutBox::launchAsynchronously (std::make_unique<PopupColourSelector> (colourValue,
defaultColour,
canResetToDefault),
getScreenBounds(),
nullptr);
}
private:
void valueChanged (Value&) override
{
refresh();
}
UndoManager* undoManager;
Value colourValue;
Colour lastColour;
const Colour defaultColour;
const bool canResetToDefault;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ColourEditorComponent)
};
//==============================================================================
struct PopupColourSelector : public Component,
private ChangeListener,
private Value::Listener
{
PopupColourSelector (const Value& colour,
Colour defaultCol,
const bool canResetToDefault)
: defaultButton ("Reset to Default"),
colourValue (colour),
defaultColour (defaultCol)
{
addAndMakeVisible (selector);
selector.setName ("Colour");
selector.setCurrentColour (getColour());
selector.addChangeListener (this);
if (canResetToDefault)
{
addAndMakeVisible (defaultButton);
defaultButton.onClick = [this]
{
setColour (defaultColour);
selector.setCurrentColour (defaultColour);
};
}
colourValue.addListener (this);
setSize (300, 400);
}
void resized() override
{
if (defaultButton.isVisible())
{
selector.setBounds (0, 0, getWidth(), getHeight() - 30);
defaultButton.changeWidthToFitText (22);
defaultButton.setTopLeftPosition (10, getHeight() - 26);
}
else
{
selector.setBounds (getLocalBounds());
}
}
Colour getColour() const
{
if (colourValue.toString().isEmpty())
return defaultColour;
return Colour::fromString (colourValue.toString());
}
void setColour (Colour newColour)
{
if (getColour() != newColour)
{
if (newColour == defaultColour && defaultButton.isVisible())
colourValue = var();
else
colourValue = newColour.toDisplayString (true);
}
}
private:
void changeListenerCallback (ChangeBroadcaster*) override
{
if (selector.getCurrentColour() != getColour())
setColour (selector.getCurrentColour());
}
void valueChanged (Value&) override
{
selector.setCurrentColour (getColour());
}
StoredSettings::ColourSelectorWithSwatches selector;
TextButton defaultButton;
Value colourValue;
Colour defaultColour;
};
ColourEditorComponent colourEditor;
};

View File

@ -1,245 +1,249 @@
/*
==============================================================================
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 PropertyComponent for selecting files or folders.
The user may drag files over the property box, enter the path manually and/or click
the '...' button to open a file selection dialog box.
*/
class FilePathPropertyComponent : public PropertyComponent,
public FileDragAndDropTarget,
protected Value::Listener
{
public:
FilePathPropertyComponent (Value valueToControl, const String& propertyName, bool isDir, bool thisOS = true,
const String& wildcardsToUse = "*", const File& relativeRoot = File())
: PropertyComponent (propertyName),
text (valueToControl, propertyName, 1024, false),
isDirectory (isDir), isThisOS (thisOS), wildcards (wildcardsToUse), root (relativeRoot)
{
textValue.referTo (valueToControl);
init();
}
/** Displays a default value when no value is specified by the user. */
FilePathPropertyComponent (ValueWithDefault& valueToControl, const String& propertyName, bool isDir, bool thisOS = true,
const String& wildcardsToUse = "*", const File& relativeRoot = File())
: PropertyComponent (propertyName),
text (valueToControl, propertyName, 1024, false),
isDirectory (isDir), isThisOS (thisOS), wildcards (wildcardsToUse), root (relativeRoot)
{
textValue = valueToControl.getPropertyAsValue();
init();
}
//==============================================================================
void refresh() override {}
void resized() override
{
auto bounds = getLocalBounds();
text.setBounds (bounds.removeFromLeft (jmax (400, bounds.getWidth() - 55)));
bounds.removeFromLeft (5);
browseButton.setBounds (bounds);
}
void paintOverChildren (Graphics& g) override
{
if (highlightForDragAndDrop)
{
g.setColour (findColour (defaultHighlightColourId).withAlpha (0.5f));
g.fillRect (getLookAndFeel().getPropertyComponentContentPosition (text));
}
}
//==============================================================================
bool isInterestedInFileDrag (const StringArray&) override { return true; }
void fileDragEnter (const StringArray&, int, int) override { highlightForDragAndDrop = true; repaint(); }
void fileDragExit (const StringArray&) override { highlightForDragAndDrop = false; repaint(); }
void filesDropped (const StringArray& selectedFiles, int, int) override
{
setTo (selectedFiles[0]);
highlightForDragAndDrop = false;
repaint();
}
protected:
void valueChanged (Value&) override
{
updateEditorColour();
}
private:
//==============================================================================
void init()
{
textValue.addListener (this);
text.setInterestedInFileDrag (false);
addAndMakeVisible (text);
browseButton.onClick = [this] { browse(); };
addAndMakeVisible (browseButton);
lookAndFeelChanged();
}
void setTo (File f)
{
if (isDirectory && ! f.isDirectory())
f = f.getParentDirectory();
auto pathName = (root == File()) ? f.getFullPathName()
: f.getRelativePathFrom (root);
text.setText (pathName);
updateEditorColour();
}
void browse()
{
File currentFile = {};
if (text.getText().isNotEmpty())
currentFile = root.getChildFile (text.getText());
if (isDirectory)
{
chooser = std::make_unique<FileChooser> ("Select directory", currentFile);
auto chooserFlags = FileBrowserComponent::openMode | FileBrowserComponent::canSelectDirectories;
chooser->launchAsync (chooserFlags, [this] (const FileChooser& fc)
{
if (fc.getResult() == File{})
return;
setTo (fc.getResult());
});
}
else
{
chooser = std::make_unique<FileChooser> ("Select file", currentFile, wildcards);
auto chooserFlags = FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles;
chooser->launchAsync (chooserFlags, [this] (const FileChooser& fc)
{
if (fc.getResult() == File{})
return;
setTo (fc.getResult());
});
}
}
void updateEditorColour()
{
if (isThisOS)
{
text.setColour (TextPropertyComponent::textColourId, findColour (widgetTextColourId));
auto pathToCheck = text.getText();
if (pathToCheck.isNotEmpty())
{
pathToCheck.replace ("${user.home}", "~");
#if JUCE_WINDOWS
if (pathToCheck.startsWith ("~"))
pathToCheck = pathToCheck.replace ("~", File::getSpecialLocation (File::userHomeDirectory).getFullPathName());
#endif
if (! root.getChildFile (pathToCheck).exists())
text.setColour (TextPropertyComponent::textColourId, Colours::red);
}
}
}
void lookAndFeelChanged() override
{
browseButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId));
browseButton.setColour (TextButton::textColourOffId, Colours::white);
updateEditorColour();
}
//==============================================================================
Value textValue;
TextPropertyComponent text;
TextButton browseButton { "..." };
bool isDirectory, isThisOS, highlightForDragAndDrop = false;
String wildcards;
File root;
std::unique_ptr<FileChooser> chooser;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilePathPropertyComponent)
};
//==============================================================================
class FilePathPropertyComponentWithEnablement : public FilePathPropertyComponent
{
public:
FilePathPropertyComponentWithEnablement (ValueWithDefault& valueToControl,
ValueWithDefault valueToListenTo,
const String& propertyName,
bool isDir,
bool thisOS = true,
const String& wildcardsToUse = "*",
const File& relativeRoot = File())
: FilePathPropertyComponent (valueToControl,
propertyName,
isDir,
thisOS,
wildcardsToUse,
relativeRoot),
valueWithDefault (valueToListenTo),
value (valueToListenTo.getPropertyAsValue())
{
value.addListener (this);
valueChanged (value);
}
~FilePathPropertyComponentWithEnablement() override { value.removeListener (this); }
private:
void valueChanged (Value& v) override
{
FilePathPropertyComponent::valueChanged (v);
setEnabled (valueWithDefault.get());
}
ValueWithDefault valueWithDefault;
Value value;
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 PropertyComponent for selecting files or folders.
The user may drag files over the property box, enter the path manually and/or click
the '...' button to open a file selection dialog box.
*/
class FilePathPropertyComponent : public PropertyComponent,
public FileDragAndDropTarget,
protected Value::Listener
{
public:
FilePathPropertyComponent (Value valueToControl, const String& propertyName, bool isDir, bool thisOS = true,
const String& wildcardsToUse = "*", const File& relativeRoot = File())
: PropertyComponent (propertyName),
text (valueToControl, propertyName, 1024, false),
isDirectory (isDir), isThisOS (thisOS), wildcards (wildcardsToUse), root (relativeRoot)
{
textValue.referTo (valueToControl);
init();
}
/** Displays a default value when no value is specified by the user. */
FilePathPropertyComponent (ValueTreePropertyWithDefault valueToControl,
const String& propertyName,
bool isDir,
bool thisOS = true,
const String& wildcardsToUse = "*",
const File& relativeRoot = File())
: PropertyComponent (propertyName),
text (valueToControl, propertyName, 1024, false),
isDirectory (isDir), isThisOS (thisOS), wildcards (wildcardsToUse), root (relativeRoot)
{
textValue = valueToControl.getPropertyAsValue();
init();
}
//==============================================================================
void refresh() override {}
void resized() override
{
auto bounds = getLocalBounds();
text.setBounds (bounds.removeFromLeft (jmax (400, bounds.getWidth() - 55)));
bounds.removeFromLeft (5);
browseButton.setBounds (bounds);
}
void paintOverChildren (Graphics& g) override
{
if (highlightForDragAndDrop)
{
g.setColour (findColour (defaultHighlightColourId).withAlpha (0.5f));
g.fillRect (getLookAndFeel().getPropertyComponentContentPosition (text));
}
}
//==============================================================================
bool isInterestedInFileDrag (const StringArray&) override { return true; }
void fileDragEnter (const StringArray&, int, int) override { highlightForDragAndDrop = true; repaint(); }
void fileDragExit (const StringArray&) override { highlightForDragAndDrop = false; repaint(); }
void filesDropped (const StringArray& selectedFiles, int, int) override
{
setTo (selectedFiles[0]);
highlightForDragAndDrop = false;
repaint();
}
protected:
void valueChanged (Value&) override
{
updateEditorColour();
}
private:
//==============================================================================
void init()
{
textValue.addListener (this);
text.setInterestedInFileDrag (false);
addAndMakeVisible (text);
browseButton.onClick = [this] { browse(); };
addAndMakeVisible (browseButton);
lookAndFeelChanged();
}
void setTo (File f)
{
if (isDirectory && ! f.isDirectory())
f = f.getParentDirectory();
auto pathName = (root == File()) ? f.getFullPathName()
: f.getRelativePathFrom (root);
text.setText (pathName);
updateEditorColour();
}
void browse()
{
File currentFile = {};
if (text.getText().isNotEmpty())
currentFile = root.getChildFile (text.getText());
if (isDirectory)
{
chooser = std::make_unique<FileChooser> ("Select directory", currentFile);
auto chooserFlags = FileBrowserComponent::openMode | FileBrowserComponent::canSelectDirectories;
chooser->launchAsync (chooserFlags, [this] (const FileChooser& fc)
{
if (fc.getResult() == File{})
return;
setTo (fc.getResult());
});
}
else
{
chooser = std::make_unique<FileChooser> ("Select file", currentFile, wildcards);
auto chooserFlags = FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles;
chooser->launchAsync (chooserFlags, [this] (const FileChooser& fc)
{
if (fc.getResult() == File{})
return;
setTo (fc.getResult());
});
}
}
void updateEditorColour()
{
if (isThisOS)
{
text.setColour (TextPropertyComponent::textColourId, findColour (widgetTextColourId));
auto pathToCheck = text.getText();
if (pathToCheck.isNotEmpty())
{
pathToCheck.replace ("${user.home}", "~");
#if JUCE_WINDOWS
if (pathToCheck.startsWith ("~"))
pathToCheck = pathToCheck.replace ("~", File::getSpecialLocation (File::userHomeDirectory).getFullPathName());
#endif
if (! root.getChildFile (pathToCheck).exists())
text.setColour (TextPropertyComponent::textColourId, Colours::red);
}
}
}
void lookAndFeelChanged() override
{
browseButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId));
browseButton.setColour (TextButton::textColourOffId, Colours::white);
updateEditorColour();
}
//==============================================================================
Value textValue;
TextPropertyComponent text;
TextButton browseButton { "..." };
bool isDirectory, isThisOS, highlightForDragAndDrop = false;
String wildcards;
File root;
std::unique_ptr<FileChooser> chooser;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilePathPropertyComponent)
};
//==============================================================================
class FilePathPropertyComponentWithEnablement : public FilePathPropertyComponent
{
public:
FilePathPropertyComponentWithEnablement (const ValueTreePropertyWithDefault& valueToControl,
ValueTreePropertyWithDefault valueToListenTo,
const String& propertyName,
bool isDir,
bool thisOS = true,
const String& wildcardsToUse = "*",
const File& relativeRoot = File())
: FilePathPropertyComponent (valueToControl,
propertyName,
isDir,
thisOS,
wildcardsToUse,
relativeRoot),
propertyWithDefault (valueToListenTo),
value (valueToListenTo.getPropertyAsValue())
{
value.addListener (this);
valueChanged (value);
}
~FilePathPropertyComponentWithEnablement() override { value.removeListener (this); }
private:
void valueChanged (Value& v) override
{
FilePathPropertyComponent::valueChanged (v);
setEnabled (propertyWithDefault.get());
}
ValueTreePropertyWithDefault propertyWithDefault;
Value value;
};

View File

@ -1,73 +1,73 @@
/*
==============================================================================
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 LabelPropertyComponent : public PropertyComponent
{
public:
LabelPropertyComponent (const String& labelText, int propertyHeight = 25,
Font labelFont = Font (16.0f, Font::bold),
Justification labelJustification = Justification::centred)
: PropertyComponent (labelText),
labelToDisplay ({}, labelText)
{
setPreferredHeight (propertyHeight);
labelToDisplay.setJustificationType (labelJustification);
labelToDisplay.setFont (labelFont);
addAndMakeVisible (labelToDisplay);
setLookAndFeel (&lf);
}
~LabelPropertyComponent() override { setLookAndFeel (nullptr); }
//==============================================================================
void refresh() override {}
void resized() override
{
labelToDisplay.setBounds (getLocalBounds());
}
private:
//==============================================================================
struct LabelLookAndFeel : public ProjucerLookAndFeel
{
void drawPropertyComponentLabel (Graphics&, int, int, PropertyComponent&) {}
};
void lookAndFeelChanged() override
{
labelToDisplay.setColour (Label::textColourId, ProjucerApplication::getApp().lookAndFeel.findColour (defaultTextColourId));
}
//==============================================================================
LabelLookAndFeel lf;
Label labelToDisplay;
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 LabelPropertyComponent : public PropertyComponent
{
public:
LabelPropertyComponent (const String& labelText, int propertyHeight = 25,
Font labelFont = Font (16.0f, Font::bold),
Justification labelJustification = Justification::centred)
: PropertyComponent (labelText),
labelToDisplay ({}, labelText)
{
setPreferredHeight (propertyHeight);
labelToDisplay.setJustificationType (labelJustification);
labelToDisplay.setFont (labelFont);
addAndMakeVisible (labelToDisplay);
setLookAndFeel (&lf);
}
~LabelPropertyComponent() override { setLookAndFeel (nullptr); }
//==============================================================================
void refresh() override {}
void resized() override
{
labelToDisplay.setBounds (getLocalBounds());
}
private:
//==============================================================================
struct LabelLookAndFeel : public ProjucerLookAndFeel
{
void drawPropertyComponentLabel (Graphics&, int, int, PropertyComponent&) {}
};
void lookAndFeelChanged() override
{
labelToDisplay.setColour (Label::textColourId, ProjucerApplication::getApp().lookAndFeel.findColour (defaultTextColourId));
}
//==============================================================================
LabelLookAndFeel lf;
Label labelToDisplay;
};

View File

@ -1,160 +1,160 @@
/*
==============================================================================
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 TextPropertyComponentWithEnablement : public TextPropertyComponent,
private Value::Listener
{
public:
TextPropertyComponentWithEnablement (ValueWithDefault& valueToControl,
ValueWithDefault valueToListenTo,
const String& propertyName,
int maxNumChars,
bool multiLine)
: TextPropertyComponent (valueToControl, propertyName, maxNumChars, multiLine),
valueWithDefault (valueToListenTo),
value (valueWithDefault.getPropertyAsValue())
{
value.addListener (this);
setEnabled (valueWithDefault.get());
}
~TextPropertyComponentWithEnablement() override { value.removeListener (this); }
private:
ValueWithDefault valueWithDefault;
Value value;
void valueChanged (Value&) override { setEnabled (valueWithDefault.get()); }
};
//==============================================================================
class ChoicePropertyComponentWithEnablement : public ChoicePropertyComponent,
private Value::Listener
{
public:
ChoicePropertyComponentWithEnablement (ValueWithDefault& valueToControl,
ValueWithDefault valueToListenTo,
const String& propertyName,
const StringArray& choiceToUse,
const Array<var>& correspondingValues)
: ChoicePropertyComponent (valueToControl, propertyName, choiceToUse, correspondingValues),
valueWithDefault (valueToListenTo),
value (valueToListenTo.getPropertyAsValue())
{
value.addListener (this);
valueChanged (value);
}
ChoicePropertyComponentWithEnablement (ValueWithDefault& valueToControl,
ValueWithDefault valueToListenTo,
const Identifier& multiChoiceID,
const String& propertyName,
const StringArray& choicesToUse,
const Array<var>& correspondingValues)
: ChoicePropertyComponentWithEnablement (valueToControl, valueToListenTo, propertyName, choicesToUse, correspondingValues)
{
jassert (valueToListenTo.get().getArray() != nullptr);
isMultiChoice = true;
idToCheck = multiChoiceID;
valueChanged (value);
}
ChoicePropertyComponentWithEnablement (ValueWithDefault& valueToControl,
ValueWithDefault valueToListenTo,
const String& propertyName)
: ChoicePropertyComponent (valueToControl, propertyName),
valueWithDefault (valueToListenTo),
value (valueToListenTo.getPropertyAsValue())
{
value.addListener (this);
valueChanged (value);
}
~ChoicePropertyComponentWithEnablement() override { value.removeListener (this); }
private:
ValueWithDefault valueWithDefault;
Value value;
bool isMultiChoice = false;
Identifier idToCheck;
bool checkMultiChoiceVar() const
{
jassert (isMultiChoice);
auto v = valueWithDefault.get();
if (auto* varArray = v.getArray())
return varArray->contains (idToCheck.toString());
jassertfalse;
return false;
}
void valueChanged (Value&) override
{
if (isMultiChoice)
setEnabled (checkMultiChoiceVar());
else
setEnabled (valueWithDefault.get());
}
};
//==============================================================================
class MultiChoicePropertyComponentWithEnablement : public MultiChoicePropertyComponent,
private Value::Listener
{
public:
MultiChoicePropertyComponentWithEnablement (ValueWithDefault& valueToControl,
ValueWithDefault valueToListenTo,
const String& propertyName,
const StringArray& choices,
const Array<var>& correspondingValues)
: MultiChoicePropertyComponent (valueToControl,
propertyName,
choices,
correspondingValues),
valueWithDefault (valueToListenTo),
value (valueToListenTo.getPropertyAsValue())
{
value.addListener (this);
valueChanged (value);
}
~MultiChoicePropertyComponentWithEnablement() override { value.removeListener (this); }
private:
void valueChanged (Value&) override { setEnabled (valueWithDefault.get()); }
ValueWithDefault valueWithDefault;
Value value;
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 TextPropertyComponentWithEnablement : public TextPropertyComponent,
private Value::Listener
{
public:
TextPropertyComponentWithEnablement (const ValueTreePropertyWithDefault& valueToControl,
ValueTreePropertyWithDefault valueToListenTo,
const String& propertyName,
int maxNumChars,
bool multiLine)
: TextPropertyComponent (valueToControl, propertyName, maxNumChars, multiLine),
propertyWithDefault (valueToListenTo),
value (propertyWithDefault.getPropertyAsValue())
{
value.addListener (this);
setEnabled (propertyWithDefault.get());
}
~TextPropertyComponentWithEnablement() override { value.removeListener (this); }
private:
ValueTreePropertyWithDefault propertyWithDefault;
Value value;
void valueChanged (Value&) override { setEnabled (propertyWithDefault.get()); }
};
//==============================================================================
class ChoicePropertyComponentWithEnablement : public ChoicePropertyComponent,
private Value::Listener
{
public:
ChoicePropertyComponentWithEnablement (const ValueTreePropertyWithDefault& valueToControl,
ValueTreePropertyWithDefault valueToListenTo,
const String& propertyName,
const StringArray& choiceToUse,
const Array<var>& correspondingValues)
: ChoicePropertyComponent (valueToControl, propertyName, choiceToUse, correspondingValues),
propertyWithDefault (valueToListenTo),
value (valueToListenTo.getPropertyAsValue())
{
value.addListener (this);
valueChanged (value);
}
ChoicePropertyComponentWithEnablement (const ValueTreePropertyWithDefault& valueToControl,
ValueTreePropertyWithDefault valueToListenTo,
const Identifier& multiChoiceID,
const String& propertyName,
const StringArray& choicesToUse,
const Array<var>& correspondingValues)
: ChoicePropertyComponentWithEnablement (valueToControl, valueToListenTo, propertyName, choicesToUse, correspondingValues)
{
jassert (valueToListenTo.get().getArray() != nullptr);
isMultiChoice = true;
idToCheck = multiChoiceID;
valueChanged (value);
}
ChoicePropertyComponentWithEnablement (const ValueTreePropertyWithDefault& valueToControl,
ValueTreePropertyWithDefault valueToListenTo,
const String& propertyName)
: ChoicePropertyComponent (valueToControl, propertyName),
propertyWithDefault (valueToListenTo),
value (valueToListenTo.getPropertyAsValue())
{
value.addListener (this);
valueChanged (value);
}
~ChoicePropertyComponentWithEnablement() override { value.removeListener (this); }
private:
ValueTreePropertyWithDefault propertyWithDefault;
Value value;
bool isMultiChoice = false;
Identifier idToCheck;
bool checkMultiChoiceVar() const
{
jassert (isMultiChoice);
auto v = propertyWithDefault.get();
if (auto* varArray = v.getArray())
return varArray->contains (idToCheck.toString());
jassertfalse;
return false;
}
void valueChanged (Value&) override
{
if (isMultiChoice)
setEnabled (checkMultiChoiceVar());
else
setEnabled (propertyWithDefault.get());
}
};
//==============================================================================
class MultiChoicePropertyComponentWithEnablement : public MultiChoicePropertyComponent,
private Value::Listener
{
public:
MultiChoicePropertyComponentWithEnablement (const ValueTreePropertyWithDefault& valueToControl,
ValueTreePropertyWithDefault valueToListenTo,
const String& propertyName,
const StringArray& choices,
const Array<var>& correspondingValues)
: MultiChoicePropertyComponent (valueToControl,
propertyName,
choices,
correspondingValues),
propertyWithDefault (valueToListenTo),
value (valueToListenTo.getPropertyAsValue())
{
value.addListener (this);
valueChanged (value);
}
~MultiChoicePropertyComponentWithEnablement() override { value.removeListener (this); }
private:
void valueChanged (Value&) override { setEnabled (propertyWithDefault.get()); }
ValueTreePropertyWithDefault propertyWithDefault;
Value value;
};

View File

@ -1,136 +1,136 @@
/*
==============================================================================
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 IconButton : public Button
{
public:
IconButton (String buttonName, Image imageToDisplay)
: Button (buttonName),
iconImage (imageToDisplay)
{
setTooltip (buttonName);
}
IconButton (String buttonName, Path pathToDisplay)
: Button (buttonName),
iconPath (pathToDisplay),
iconImage (createImageFromPath (iconPath))
{
setTooltip (buttonName);
}
void setImage (Image newImage)
{
iconImage = newImage;
repaint();
}
void setPath (Path newPath)
{
iconImage = createImageFromPath (newPath);
repaint();
}
void setBackgroundColour (Colour backgroundColourToUse)
{
backgroundColour = backgroundColourToUse;
usingNonDefaultBackgroundColour = true;
}
void setIconInset (int newIconInset)
{
iconInset = newIconInset;
repaint();
}
void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) override
{
float alpha = 1.0f;
if (! isEnabled())
{
isMouseOverButton = false;
isButtonDown = false;
alpha = 0.2f;
}
auto fill = isButtonDown ? backgroundColour.darker (0.5f)
: isMouseOverButton ? backgroundColour.darker (0.2f)
: backgroundColour;
auto bounds = getLocalBounds();
if (isButtonDown)
bounds.reduce (2, 2);
Path ellipse;
ellipse.addEllipse (bounds.toFloat());
g.reduceClipRegion (ellipse);
g.setColour (fill.withAlpha (alpha));
g.fillAll();
g.setOpacity (alpha);
g.drawImage (iconImage, bounds.reduced (iconInset).toFloat(), RectanglePlacement::fillDestination, false);
}
private:
void lookAndFeelChanged() override
{
if (! usingNonDefaultBackgroundColour)
backgroundColour = findColour (defaultButtonBackgroundColourId);
if (iconPath != Path())
iconImage = createImageFromPath (iconPath);
repaint();
}
Image createImageFromPath (Path path)
{
Image image (Image::ARGB, 250, 250, true);
Graphics g (image);
g.setColour (findColour (defaultIconColourId));
g.fillPath (path, RectanglePlacement (RectanglePlacement::centred)
.getTransformToFit (path.getBounds(), image.getBounds().toFloat()));
return image;
}
Path iconPath;
Image iconImage;
Colour backgroundColour { findColour (defaultButtonBackgroundColourId) };
bool usingNonDefaultBackgroundColour = false;
int iconInset = 2;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (IconButton)
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 IconButton : public Button
{
public:
IconButton (String buttonName, Image imageToDisplay)
: Button (buttonName),
iconImage (imageToDisplay)
{
setTooltip (buttonName);
}
IconButton (String buttonName, Path pathToDisplay)
: Button (buttonName),
iconPath (pathToDisplay),
iconImage (createImageFromPath (iconPath))
{
setTooltip (buttonName);
}
void setImage (Image newImage)
{
iconImage = newImage;
repaint();
}
void setPath (Path newPath)
{
iconImage = createImageFromPath (newPath);
repaint();
}
void setBackgroundColour (Colour backgroundColourToUse)
{
backgroundColour = backgroundColourToUse;
usingNonDefaultBackgroundColour = true;
}
void setIconInset (int newIconInset)
{
iconInset = newIconInset;
repaint();
}
void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) override
{
float alpha = 1.0f;
if (! isEnabled())
{
isMouseOverButton = false;
isButtonDown = false;
alpha = 0.2f;
}
auto fill = isButtonDown ? backgroundColour.darker (0.5f)
: isMouseOverButton ? backgroundColour.darker (0.2f)
: backgroundColour;
auto bounds = getLocalBounds();
if (isButtonDown)
bounds.reduce (2, 2);
Path ellipse;
ellipse.addEllipse (bounds.toFloat());
g.reduceClipRegion (ellipse);
g.setColour (fill.withAlpha (alpha));
g.fillAll();
g.setOpacity (alpha);
g.drawImage (iconImage, bounds.reduced (iconInset).toFloat(), RectanglePlacement::fillDestination, false);
}
private:
void lookAndFeelChanged() override
{
if (! usingNonDefaultBackgroundColour)
backgroundColour = findColour (defaultButtonBackgroundColourId);
if (iconPath != Path())
iconImage = createImageFromPath (iconPath);
repaint();
}
Image createImageFromPath (Path path)
{
Image image (Image::ARGB, 250, 250, true);
Graphics g (image);
g.setColour (findColour (defaultIconColourId));
g.fillPath (path, RectanglePlacement (RectanglePlacement::centred)
.getTransformToFit (path.getBounds(), image.getBounds().toFloat()));
return image;
}
Path iconPath;
Image iconImage;
Colour backgroundColour { findColour (defaultButtonBackgroundColourId) };
bool usingNonDefaultBackgroundColour = false;
int iconInset = 2;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (IconButton)
};

File diff suppressed because it is too large Load Diff

View File

@ -1,86 +1,86 @@
/*
==============================================================================
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 Icon
{
Icon() = default;
Icon (const Path& pathToUse, Colour pathColour)
: path (pathToUse),
colour (pathColour)
{
}
void draw (Graphics& g, const juce::Rectangle<float>& area, bool isCrossedOut) const
{
if (! path.isEmpty())
{
g.setColour (colour);
const RectanglePlacement placement (RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize);
g.fillPath (path, placement.getTransformToFit (path.getBounds(), area));
if (isCrossedOut)
{
g.setColour (Colours::red.withAlpha (0.8f));
g.drawLine ((float) area.getX(), area.getY() + area.getHeight() * 0.2f,
(float) area.getRight(), area.getY() + area.getHeight() * 0.8f, 3.0f);
}
}
}
Icon withContrastingColourTo (Colour background) const
{
return Icon (path, background.contrasting (colour, 0.6f));
}
Icon withColour (Colour newColour)
{
return Icon (path, newColour);
}
Path path;
Colour colour;
};
//==============================================================================
class Icons
{
public:
Icons();
Path imageDoc, config, graph, info, warning, user, closedFolder, exporter, fileExplorer, file,
modules, openFolder, settings, singleModule, plus, android, codeBlocks,
linux, xcode, visualStudio, clion;
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Icons)
};
const Icons& getIcons();
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 Icon
{
Icon() = default;
Icon (const Path& pathToUse, Colour pathColour)
: path (pathToUse),
colour (pathColour)
{
}
void draw (Graphics& g, const juce::Rectangle<float>& area, bool isCrossedOut) const
{
if (! path.isEmpty())
{
g.setColour (colour);
const RectanglePlacement placement (RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize);
g.fillPath (path, placement.getTransformToFit (path.getBounds(), area));
if (isCrossedOut)
{
g.setColour (Colours::red.withAlpha (0.8f));
g.drawLine ((float) area.getX(), area.getY() + area.getHeight() * 0.2f,
(float) area.getRight(), area.getY() + area.getHeight() * 0.8f, 3.0f);
}
}
}
Icon withContrastingColourTo (Colour background) const
{
return Icon (path, background.contrasting (colour, 0.6f));
}
Icon withColour (Colour newColour)
{
return Icon (path, newColour);
}
Path path;
Colour colour;
};
//==============================================================================
class Icons
{
public:
Icons();
Path imageDoc, config, graph, info, warning, user, closedFolder, exporter, fileExplorer, file,
modules, openFolder, settings, singleModule, plus, android, codeBlocks,
linux, xcode, visualStudio;
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Icons)
};
const Icons& getIcons();

View File

@ -1,251 +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.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_JucerTreeViewBase.h"
#include "../../Project/UI/jucer_ProjectContentComponent.h"
//==============================================================================
void TreePanelBase::setRoot (std::unique_ptr<JucerTreeViewBase> root)
{
rootItem = std::move (root);
tree.setRootItem (rootItem.get());
tree.getRootItem()->setOpen (true);
if (project != nullptr)
{
if (auto treeOpenness = project->getStoredProperties().getXmlValue (opennessStateKey))
{
tree.restoreOpennessState (*treeOpenness, true);
for (int i = tree.getNumSelectedItems(); --i >= 0;)
if (auto item = dynamic_cast<JucerTreeViewBase*> (tree.getSelectedItem (i)))
item->cancelDelayedSelectionTimer();
}
}
}
void TreePanelBase::saveOpenness()
{
if (project != nullptr)
{
std::unique_ptr<XmlElement> opennessState (tree.getOpennessState (true));
if (opennessState != nullptr)
project->getStoredProperties().setValue (opennessStateKey, opennessState.get());
else
project->getStoredProperties().removeValue (opennessStateKey);
}
}
//==============================================================================
JucerTreeViewBase::JucerTreeViewBase()
{
setLinesDrawnForSubItems (false);
setDrawsInLeftMargin (true);
}
void JucerTreeViewBase::refreshSubItems()
{
WholeTreeOpennessRestorer wtor (*this);
clearSubItems();
addSubItems();
}
Font JucerTreeViewBase::getFont() const
{
return Font ((float) getItemHeight() * 0.6f);
}
void JucerTreeViewBase::paintOpenCloseButton (Graphics& g, const Rectangle<float>& area, Colour /*backgroundColour*/, bool isMouseOver)
{
g.setColour (getOwnerView()->findColour (isSelected() ? defaultHighlightedTextColourId : treeIconColourId));
TreeViewItem::paintOpenCloseButton (g, area, getOwnerView()->findColour (defaultIconColourId), isMouseOver);
}
void JucerTreeViewBase::paintIcon (Graphics& g, Rectangle<float> area)
{
g.setColour (getContentColour (true));
getIcon().draw (g, area, isIconCrossedOut());
textX = roundToInt (area.getRight()) + 7;
}
void JucerTreeViewBase::paintItem (Graphics& g, int width, int height)
{
ignoreUnused (width, height);
auto bounds = g.getClipBounds().withY (0).withHeight (height).toFloat();
g.setColour (getOwnerView()->findColour (treeIconColourId).withMultipliedAlpha (0.4f));
g.fillRect (bounds.removeFromBottom (0.5f).reduced (5, 0));
}
Colour JucerTreeViewBase::getContentColour (bool isIcon) const
{
if (isMissing()) return Colours::red;
if (isSelected()) return getOwnerView()->findColour (defaultHighlightedTextColourId);
if (hasWarnings()) return getOwnerView()->findColour (defaultHighlightColourId);
return getOwnerView()->findColour (isIcon ? treeIconColourId : defaultTextColourId);
}
void JucerTreeViewBase::paintContent (Graphics& g, Rectangle<int> area)
{
g.setFont (getFont());
g.setColour (getContentColour (false));
g.drawFittedText (getDisplayName(), area, Justification::centredLeft, 1, 1.0f);
}
std::unique_ptr<Component> JucerTreeViewBase::createItemComponent()
{
return std::make_unique<TreeItemComponent> (*this);
}
//==============================================================================
class RenameTreeItemCallback : public ModalComponentManager::Callback
{
public:
RenameTreeItemCallback (JucerTreeViewBase& ti, Component& parent, const Rectangle<int>& bounds)
: item (ti)
{
ed.setMultiLine (false, false);
ed.setPopupMenuEnabled (false);
ed.setSelectAllWhenFocused (true);
ed.setFont (item.getFont());
ed.onReturnKey = [this] { ed.exitModalState (1); };
ed.onEscapeKey = [this] { ed.exitModalState (0); };
ed.onFocusLost = [this] { ed.exitModalState (0); };
ed.setText (item.getRenamingName());
ed.setBounds (bounds);
parent.addAndMakeVisible (ed);
ed.enterModalState (true, this);
}
void modalStateFinished (int resultCode) override
{
if (resultCode != 0)
item.setName (ed.getText());
}
private:
struct RenameEditor : public TextEditor
{
void inputAttemptWhenModal() override { exitModalState (0); }
};
RenameEditor ed;
JucerTreeViewBase& item;
JUCE_DECLARE_NON_COPYABLE (RenameTreeItemCallback)
};
void JucerTreeViewBase::showRenameBox()
{
Rectangle<int> r (getItemPosition (true));
r.setLeft (r.getX() + textX);
r.setHeight (getItemHeight());
new RenameTreeItemCallback (*this, *getOwnerView(), r);
}
void JucerTreeViewBase::itemClicked (const MouseEvent& e)
{
if (e.mods.isPopupMenu())
{
if (getOwnerView()->getNumSelectedItems() > 1)
showMultiSelectionPopupMenu (e.getMouseDownScreenPosition());
else
showPopupMenu (e.getMouseDownScreenPosition());
}
else if (isSelected())
{
itemSelectionChanged (true);
}
}
static void treeViewMenuItemChosen (int resultCode, WeakReference<JucerTreeViewBase> item)
{
if (item != nullptr)
item->handlePopupMenuResult (resultCode);
}
void JucerTreeViewBase::launchPopupMenu (PopupMenu& m, Point<int> p)
{
m.showMenuAsync (PopupMenu::Options().withTargetScreenArea ({ p.x, p.y, 1, 1 }),
ModalCallbackFunction::create (treeViewMenuItemChosen, WeakReference<JucerTreeViewBase> (this)));
}
ProjectContentComponent* JucerTreeViewBase::getProjectContentComponent() const
{
for (Component* c = getOwnerView(); c != nullptr; c = c->getParentComponent())
if (ProjectContentComponent* pcc = dynamic_cast<ProjectContentComponent*> (c))
return pcc;
return nullptr;
}
//==============================================================================
class JucerTreeViewBase::ItemSelectionTimer : public Timer
{
public:
explicit ItemSelectionTimer (JucerTreeViewBase& tvb) : owner (tvb) {}
void timerCallback() override { owner.invokeShowDocument(); }
private:
JucerTreeViewBase& owner;
JUCE_DECLARE_NON_COPYABLE (ItemSelectionTimer)
};
void JucerTreeViewBase::itemSelectionChanged (bool isNowSelected)
{
if (isNowSelected)
{
delayedSelectionTimer.reset (new ItemSelectionTimer (*this));
delayedSelectionTimer->startTimer (getMillisecsAllowedForDragGesture());
}
else
{
cancelDelayedSelectionTimer();
}
}
void JucerTreeViewBase::invokeShowDocument()
{
cancelDelayedSelectionTimer();
showDocument();
}
void JucerTreeViewBase::itemDoubleClicked (const MouseEvent&)
{
invokeShowDocument();
}
void JucerTreeViewBase::cancelDelayedSelectionTimer()
{
delayedSelectionTimer.reset();
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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_JucerTreeViewBase.h"
#include "../../Project/UI/jucer_ProjectContentComponent.h"
//==============================================================================
void TreePanelBase::setRoot (std::unique_ptr<JucerTreeViewBase> root)
{
rootItem = std::move (root);
tree.setRootItem (rootItem.get());
tree.getRootItem()->setOpen (true);
if (project != nullptr)
{
if (auto treeOpenness = project->getStoredProperties().getXmlValue (opennessStateKey))
{
tree.restoreOpennessState (*treeOpenness, true);
for (int i = tree.getNumSelectedItems(); --i >= 0;)
if (auto item = dynamic_cast<JucerTreeViewBase*> (tree.getSelectedItem (i)))
item->cancelDelayedSelectionTimer();
}
}
}
void TreePanelBase::saveOpenness()
{
if (project != nullptr)
{
std::unique_ptr<XmlElement> opennessState (tree.getOpennessState (true));
if (opennessState != nullptr)
project->getStoredProperties().setValue (opennessStateKey, opennessState.get());
else
project->getStoredProperties().removeValue (opennessStateKey);
}
}
//==============================================================================
JucerTreeViewBase::JucerTreeViewBase()
{
setLinesDrawnForSubItems (false);
setDrawsInLeftMargin (true);
}
void JucerTreeViewBase::refreshSubItems()
{
WholeTreeOpennessRestorer wtor (*this);
clearSubItems();
addSubItems();
}
Font JucerTreeViewBase::getFont() const
{
return Font ((float) getItemHeight() * 0.6f);
}
void JucerTreeViewBase::paintOpenCloseButton (Graphics& g, const Rectangle<float>& area, Colour /*backgroundColour*/, bool isMouseOver)
{
g.setColour (getOwnerView()->findColour (isSelected() ? defaultHighlightedTextColourId : treeIconColourId));
TreeViewItem::paintOpenCloseButton (g, area, getOwnerView()->findColour (defaultIconColourId), isMouseOver);
}
void JucerTreeViewBase::paintIcon (Graphics& g, Rectangle<float> area)
{
g.setColour (getContentColour (true));
getIcon().draw (g, area, isIconCrossedOut());
textX = roundToInt (area.getRight()) + 7;
}
void JucerTreeViewBase::paintItem (Graphics& g, int width, int height)
{
ignoreUnused (width, height);
auto bounds = g.getClipBounds().withY (0).withHeight (height).toFloat();
g.setColour (getOwnerView()->findColour (treeIconColourId).withMultipliedAlpha (0.4f));
g.fillRect (bounds.removeFromBottom (0.5f).reduced (5, 0));
}
Colour JucerTreeViewBase::getContentColour (bool isIcon) const
{
if (isMissing()) return Colours::red;
if (isSelected()) return getOwnerView()->findColour (defaultHighlightedTextColourId);
if (hasWarnings()) return getOwnerView()->findColour (defaultHighlightColourId);
return getOwnerView()->findColour (isIcon ? treeIconColourId : defaultTextColourId);
}
void JucerTreeViewBase::paintContent (Graphics& g, Rectangle<int> area)
{
g.setFont (getFont());
g.setColour (getContentColour (false));
g.drawFittedText (getDisplayName(), area, Justification::centredLeft, 1, 1.0f);
}
std::unique_ptr<Component> JucerTreeViewBase::createItemComponent()
{
return std::make_unique<TreeItemComponent> (*this);
}
//==============================================================================
class RenameTreeItemCallback : public ModalComponentManager::Callback
{
public:
RenameTreeItemCallback (JucerTreeViewBase& ti, Component& parent, const Rectangle<int>& bounds)
: item (ti)
{
ed.setMultiLine (false, false);
ed.setPopupMenuEnabled (false);
ed.setSelectAllWhenFocused (true);
ed.setFont (item.getFont());
ed.onReturnKey = [this] { ed.exitModalState (1); };
ed.onEscapeKey = [this] { ed.exitModalState (0); };
ed.onFocusLost = [this] { ed.exitModalState (0); };
ed.setText (item.getRenamingName());
ed.setBounds (bounds);
parent.addAndMakeVisible (ed);
ed.enterModalState (true, this);
}
void modalStateFinished (int resultCode) override
{
if (resultCode != 0)
item.setName (ed.getText());
}
private:
struct RenameEditor : public TextEditor
{
void inputAttemptWhenModal() override { exitModalState (0); }
};
RenameEditor ed;
JucerTreeViewBase& item;
JUCE_DECLARE_NON_COPYABLE (RenameTreeItemCallback)
};
void JucerTreeViewBase::showRenameBox()
{
Rectangle<int> r (getItemPosition (true));
r.setLeft (r.getX() + textX);
r.setHeight (getItemHeight());
new RenameTreeItemCallback (*this, *getOwnerView(), r);
}
void JucerTreeViewBase::itemClicked (const MouseEvent& e)
{
if (e.mods.isPopupMenu())
{
if (getOwnerView()->getNumSelectedItems() > 1)
showMultiSelectionPopupMenu (e.getMouseDownScreenPosition());
else
showPopupMenu (e.getMouseDownScreenPosition());
}
else if (isSelected())
{
itemSelectionChanged (true);
}
}
static void treeViewMenuItemChosen (int resultCode, WeakReference<JucerTreeViewBase> item)
{
if (item != nullptr)
item->handlePopupMenuResult (resultCode);
}
void JucerTreeViewBase::launchPopupMenu (PopupMenu& m, Point<int> p)
{
m.showMenuAsync (PopupMenu::Options().withTargetScreenArea ({ p.x, p.y, 1, 1 }),
ModalCallbackFunction::create (treeViewMenuItemChosen, WeakReference<JucerTreeViewBase> (this)));
}
ProjectContentComponent* JucerTreeViewBase::getProjectContentComponent() const
{
for (Component* c = getOwnerView(); c != nullptr; c = c->getParentComponent())
if (ProjectContentComponent* pcc = dynamic_cast<ProjectContentComponent*> (c))
return pcc;
return nullptr;
}
//==============================================================================
class JucerTreeViewBase::ItemSelectionTimer : public Timer
{
public:
explicit ItemSelectionTimer (JucerTreeViewBase& tvb) : owner (tvb) {}
void timerCallback() override { owner.invokeShowDocument(); }
private:
JucerTreeViewBase& owner;
JUCE_DECLARE_NON_COPYABLE (ItemSelectionTimer)
};
void JucerTreeViewBase::itemSelectionChanged (bool isNowSelected)
{
if (isNowSelected)
{
delayedSelectionTimer.reset (new ItemSelectionTimer (*this));
delayedSelectionTimer->startTimer (getMillisecsAllowedForDragGesture());
}
else
{
cancelDelayedSelectionTimer();
}
}
void JucerTreeViewBase::invokeShowDocument()
{
cancelDelayedSelectionTimer();
showDocument();
}
void JucerTreeViewBase::itemDoubleClicked (const MouseEvent&)
{
invokeShowDocument();
}
void JucerTreeViewBase::cancelDelayedSelectionTimer()
{
delayedSelectionTimer.reset();
}

View File

@ -1,249 +1,249 @@
/*
==============================================================================
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 ProjectContentComponent;
class Project;
//==============================================================================
class JucerTreeViewBase : public TreeViewItem,
public TooltipClient
{
public:
JucerTreeViewBase();
~JucerTreeViewBase() override = default;
int getItemWidth() const override { return -1; }
int getItemHeight() const override { return 25; }
void paintOpenCloseButton (Graphics&, const Rectangle<float>& area, Colour backgroundColour, bool isMouseOver) override;
void paintItem (Graphics& g, int width, int height) override;
void itemClicked (const MouseEvent& e) override;
void itemSelectionChanged (bool isNowSelected) override;
void itemDoubleClicked (const MouseEvent&) override;
std::unique_ptr<Component> createItemComponent() override;
String getTooltip() override { return {}; }
String getAccessibilityName() override { return getDisplayName(); }
void cancelDelayedSelectionTimer();
//==============================================================================
virtual bool isRoot() const { return false; }
virtual Font getFont() const;
virtual String getRenamingName() const = 0;
virtual String getDisplayName() const = 0;
virtual void setName (const String& newName) = 0;
virtual bool isMissing() const = 0;
virtual bool hasWarnings() const { return false; }
virtual Icon getIcon() const = 0;
virtual bool isIconCrossedOut() const { return false; }
virtual void paintIcon (Graphics& g, Rectangle<float> area);
virtual void paintContent (Graphics& g, Rectangle<int> area);
virtual int getRightHandButtonSpace() { return 0; }
virtual Colour getContentColour (bool isIcon) const;
virtual int getMillisecsAllowedForDragGesture() { return 120; }
virtual File getDraggableFile() const { return {}; }
void refreshSubItems();
void showRenameBox();
virtual void deleteItem() {}
virtual void deleteAllSelectedItems() {}
virtual void showDocument() {}
virtual void showMultiSelectionPopupMenu (Point<int>) {}
virtual void showPopupMenu (Point<int>) {}
virtual void showAddMenu (Point<int>) {}
virtual void handlePopupMenuResult (int) {}
virtual void setSearchFilter (const String&) {}
void launchPopupMenu (PopupMenu&, Point<int>); // runs asynchronously, and produces a callback to handlePopupMenuResult().
//==============================================================================
// To handle situations where an item gets deleted before openness is
// restored for it, this OpennessRestorer keeps only a pointer to the
// topmost tree item.
struct WholeTreeOpennessRestorer : public OpennessRestorer
{
WholeTreeOpennessRestorer (TreeViewItem& item) : OpennessRestorer (getTopLevelItem (item))
{}
private:
static TreeViewItem& getTopLevelItem (TreeViewItem& item)
{
if (TreeViewItem* const p = item.getParentItem())
return getTopLevelItem (*p);
return item;
}
};
int textX = 0;
protected:
ProjectContentComponent* getProjectContentComponent() const;
virtual void addSubItems() {}
private:
class ItemSelectionTimer;
friend class ItemSelectionTimer;
std::unique_ptr<Timer> delayedSelectionTimer;
void invokeShowDocument();
JUCE_DECLARE_WEAK_REFERENCEABLE (JucerTreeViewBase)
};
//==============================================================================
class TreePanelBase : public Component
{
public:
TreePanelBase (const Project* p, const String& treeviewID)
: project (p), opennessStateKey (treeviewID)
{
addAndMakeVisible (tree);
tree.setRootItemVisible (true);
tree.setDefaultOpenness (true);
tree.setColour (TreeView::backgroundColourId, Colours::transparentBlack);
tree.setIndentSize (14);
tree.getViewport()->setScrollBarThickness (6);
tree.addMouseListener (this, true);
}
~TreePanelBase() override
{
tree.setRootItem (nullptr);
}
void setRoot (std::unique_ptr<JucerTreeViewBase>);
void saveOpenness();
virtual void deleteSelectedItems()
{
if (rootItem != nullptr)
rootItem->deleteAllSelectedItems();
}
void setEmptyTreeMessage (const String& newMessage)
{
if (emptyTreeMessage != newMessage)
{
emptyTreeMessage = newMessage;
repaint();
}
}
static void drawEmptyPanelMessage (Component& comp, Graphics& g, const String& message)
{
const int fontHeight = 13;
const Rectangle<int> area (comp.getLocalBounds());
g.setColour (comp.findColour (defaultTextColourId));
g.setFont ((float) fontHeight);
g.drawFittedText (message, area.reduced (4, 2), Justification::centred, area.getHeight() / fontHeight);
}
void paint (Graphics& g) override
{
if (emptyTreeMessage.isNotEmpty() && (rootItem == nullptr || rootItem->getNumSubItems() == 0))
drawEmptyPanelMessage (*this, g, emptyTreeMessage);
}
void resized() override
{
tree.setBounds (getAvailableBounds());
}
Rectangle<int> getAvailableBounds() const
{
return Rectangle<int> (0, 2, getWidth() - 2, getHeight() - 2);
}
void mouseDown (const MouseEvent& e) override
{
if (e.eventComponent == &tree)
{
tree.clearSelectedItems();
if (e.mods.isRightButtonDown())
rootItem->showPopupMenu (e.getMouseDownScreenPosition());
}
}
const Project* project;
TreeView tree;
std::unique_ptr<JucerTreeViewBase> rootItem;
private:
String opennessStateKey, emptyTreeMessage;
};
//==============================================================================
class TreeItemComponent : public Component
{
public:
TreeItemComponent (JucerTreeViewBase& i) : item (&i)
{
setAccessible (false);
setInterceptsMouseClicks (false, true);
item->textX = iconWidth;
}
void paint (Graphics& g) override
{
if (item == nullptr)
return;
auto bounds = getLocalBounds().toFloat();
auto iconBounds = bounds.removeFromLeft ((float) iconWidth).reduced (7, 5);
bounds.removeFromRight ((float) buttons.size() * bounds.getHeight());
item->paintIcon (g, iconBounds);
item->paintContent (g, bounds.toNearestInt());
}
void resized() override
{
auto r = getLocalBounds();
for (int i = buttons.size(); --i >= 0;)
buttons.getUnchecked (i)->setBounds (r.removeFromRight (r.getHeight()));
}
void addRightHandButton (Component* button)
{
buttons.add (button);
addAndMakeVisible (button);
}
WeakReference<JucerTreeViewBase> item;
OwnedArray<Component> buttons;
const int iconWidth = 25;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TreeItemComponent)
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 ProjectContentComponent;
class Project;
//==============================================================================
class JucerTreeViewBase : public TreeViewItem,
public TooltipClient
{
public:
JucerTreeViewBase();
~JucerTreeViewBase() override = default;
int getItemWidth() const override { return -1; }
int getItemHeight() const override { return 25; }
void paintOpenCloseButton (Graphics&, const Rectangle<float>& area, Colour backgroundColour, bool isMouseOver) override;
void paintItem (Graphics& g, int width, int height) override;
void itemClicked (const MouseEvent& e) override;
void itemSelectionChanged (bool isNowSelected) override;
void itemDoubleClicked (const MouseEvent&) override;
std::unique_ptr<Component> createItemComponent() override;
String getTooltip() override { return {}; }
String getAccessibilityName() override { return getDisplayName(); }
void cancelDelayedSelectionTimer();
//==============================================================================
virtual bool isRoot() const { return false; }
virtual Font getFont() const;
virtual String getRenamingName() const = 0;
virtual String getDisplayName() const = 0;
virtual void setName (const String& newName) = 0;
virtual bool isMissing() const = 0;
virtual bool hasWarnings() const { return false; }
virtual Icon getIcon() const = 0;
virtual bool isIconCrossedOut() const { return false; }
virtual void paintIcon (Graphics& g, Rectangle<float> area);
virtual void paintContent (Graphics& g, Rectangle<int> area);
virtual int getRightHandButtonSpace() { return 0; }
virtual Colour getContentColour (bool isIcon) const;
virtual int getMillisecsAllowedForDragGesture() { return 120; }
virtual File getDraggableFile() const { return {}; }
void refreshSubItems();
void showRenameBox();
virtual void deleteItem() {}
virtual void deleteAllSelectedItems() {}
virtual void showDocument() {}
virtual void showMultiSelectionPopupMenu (Point<int>) {}
virtual void showPopupMenu (Point<int>) {}
virtual void showAddMenu (Point<int>) {}
virtual void handlePopupMenuResult (int) {}
virtual void setSearchFilter (const String&) {}
void launchPopupMenu (PopupMenu&, Point<int>); // runs asynchronously, and produces a callback to handlePopupMenuResult().
//==============================================================================
// To handle situations where an item gets deleted before openness is
// restored for it, this OpennessRestorer keeps only a pointer to the
// topmost tree item.
struct WholeTreeOpennessRestorer : public OpennessRestorer
{
WholeTreeOpennessRestorer (TreeViewItem& item) : OpennessRestorer (getTopLevelItem (item))
{}
private:
static TreeViewItem& getTopLevelItem (TreeViewItem& item)
{
if (TreeViewItem* const p = item.getParentItem())
return getTopLevelItem (*p);
return item;
}
};
int textX = 0;
protected:
ProjectContentComponent* getProjectContentComponent() const;
virtual void addSubItems() {}
private:
class ItemSelectionTimer;
friend class ItemSelectionTimer;
std::unique_ptr<Timer> delayedSelectionTimer;
void invokeShowDocument();
JUCE_DECLARE_WEAK_REFERENCEABLE (JucerTreeViewBase)
};
//==============================================================================
class TreePanelBase : public Component
{
public:
TreePanelBase (const Project* p, const String& treeviewID)
: project (p), opennessStateKey (treeviewID)
{
addAndMakeVisible (tree);
tree.setRootItemVisible (true);
tree.setDefaultOpenness (true);
tree.setColour (TreeView::backgroundColourId, Colours::transparentBlack);
tree.setIndentSize (14);
tree.getViewport()->setScrollBarThickness (6);
tree.addMouseListener (this, true);
}
~TreePanelBase() override
{
tree.setRootItem (nullptr);
}
void setRoot (std::unique_ptr<JucerTreeViewBase>);
void saveOpenness();
virtual void deleteSelectedItems()
{
if (rootItem != nullptr)
rootItem->deleteAllSelectedItems();
}
void setEmptyTreeMessage (const String& newMessage)
{
if (emptyTreeMessage != newMessage)
{
emptyTreeMessage = newMessage;
repaint();
}
}
static void drawEmptyPanelMessage (Component& comp, Graphics& g, const String& message)
{
const int fontHeight = 13;
const Rectangle<int> area (comp.getLocalBounds());
g.setColour (comp.findColour (defaultTextColourId));
g.setFont ((float) fontHeight);
g.drawFittedText (message, area.reduced (4, 2), Justification::centred, area.getHeight() / fontHeight);
}
void paint (Graphics& g) override
{
if (emptyTreeMessage.isNotEmpty() && (rootItem == nullptr || rootItem->getNumSubItems() == 0))
drawEmptyPanelMessage (*this, g, emptyTreeMessage);
}
void resized() override
{
tree.setBounds (getAvailableBounds());
}
Rectangle<int> getAvailableBounds() const
{
return Rectangle<int> (0, 2, getWidth() - 2, getHeight() - 2);
}
void mouseDown (const MouseEvent& e) override
{
if (e.eventComponent == &tree)
{
tree.clearSelectedItems();
if (e.mods.isRightButtonDown())
rootItem->showPopupMenu (e.getMouseDownScreenPosition());
}
}
const Project* project;
TreeView tree;
std::unique_ptr<JucerTreeViewBase> rootItem;
private:
String opennessStateKey, emptyTreeMessage;
};
//==============================================================================
class TreeItemComponent : public Component
{
public:
TreeItemComponent (JucerTreeViewBase& i) : item (&i)
{
setAccessible (false);
setInterceptsMouseClicks (false, true);
item->textX = iconWidth;
}
void paint (Graphics& g) override
{
if (item == nullptr)
return;
auto bounds = getLocalBounds().toFloat();
auto iconBounds = bounds.removeFromLeft ((float) iconWidth).reduced (7, 5);
bounds.removeFromRight ((float) buttons.size() * bounds.getHeight());
item->paintIcon (g, iconBounds);
item->paintContent (g, bounds.toNearestInt());
}
void resized() override
{
auto r = getLocalBounds();
for (int i = buttons.size(); --i >= 0;)
buttons.getUnchecked (i)->setBounds (r.removeFromRight (r.getHeight()));
}
void addRightHandButton (Component* button)
{
buttons.add (button);
addAndMakeVisible (button);
}
WeakReference<JucerTreeViewBase> item;
OwnedArray<Component> buttons;
const int iconWidth = 25;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TreeItemComponent)
};

File diff suppressed because it is too large Load Diff

View File

@ -1,100 +1,100 @@
/*
==============================================================================
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 ProjucerLookAndFeel : public LookAndFeel_V4
{
public:
ProjucerLookAndFeel();
~ProjucerLookAndFeel() override;
void drawTabButton (TabBarButton& button, Graphics&, bool isMouseOver, bool isMouseDown) override;
int getTabButtonBestWidth (TabBarButton&, int tabDepth) override;
void drawTabAreaBehindFrontButton (TabbedButtonBar&, Graphics&, int, int) override {}
void drawPropertyComponentBackground (Graphics&, int, int, PropertyComponent&) override {}
void drawPropertyComponentLabel (Graphics&, int width, int height, PropertyComponent&) override;
Rectangle<int> getPropertyComponentContentPosition (PropertyComponent&) override;
void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour,
bool isMouseOverButton, bool isButtonDown) override;
void drawButtonText (Graphics&, TextButton&, bool isMouseOverButton, bool isButtonDown) override;
void drawToggleButton (Graphics&, ToggleButton&, bool isMouseOverButton, bool isButtonDown) override;
void drawTextEditorOutline (Graphics&, int, int, TextEditor&) override {}
void fillTextEditorBackground (Graphics&, int width, int height, TextEditor&) override;
void layoutFileBrowserComponent (FileBrowserComponent&, DirectoryContentsDisplayComponent*,
FilePreviewComponent*, ComboBox* currentPathBox,
TextEditor* filenameBox,Button* goUpButton) override;
void drawFileBrowserRow (Graphics&, int width, int height, const File&, const String& filename, Image* icon,
const String& fileSizeDescription, const String& fileTimeDescription,
bool isDirectory, bool isItemSelected, int itemIndex, DirectoryContentsDisplayComponent&) override;
void drawCallOutBoxBackground (CallOutBox&, Graphics&, const Path&, Image&) override;
void drawMenuBarBackground (Graphics&, int width, int height, bool isMouseOverBar, MenuBarComponent&) override;
void drawMenuBarItem (Graphics&, int width, int height,
int itemIndex, const String& itemText,
bool isMouseOverItem, bool isMenuOpen, bool isMouseOverBar,
MenuBarComponent&) override;
void drawResizableFrame (Graphics&, int w, int h, const BorderSize<int>&) override;
void drawComboBox (Graphics&, int width, int height, bool isButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH,
ComboBox&) override;
void drawTreeviewPlusMinusBox (Graphics&, const Rectangle<float>& area,
Colour backgroundColour, bool isItemOpen, bool isMouseOver) override;
void drawProgressBar (Graphics&, ProgressBar&, int width, int height, double progress, const String& textToShow) override;
//==============================================================================
static Path getArrowPath (Rectangle<float> arrowZone, const int direction,
const bool filled, const Justification justification);
static Path getChoiceComponentArrowPath (Rectangle<float> arrowZone);
static Font getPropertyComponentFont() { return { 14.0f, Font::FontStyleFlags::bold }; }
static int getTextWidthForPropertyComponent (PropertyComponent* pp) { return jmin (200, pp->getWidth() / 2); }
static ColourScheme getProjucerDarkColourScheme()
{
return { 0xff323e44, 0xff263238, 0xff323e44,
0xff8e989b, 0xffffffff, 0xffa45c94,
0xffffffff, 0xff181f22, 0xffffffff };
}
//==============================================================================
void setupColours();
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjucerLookAndFeel)
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 ProjucerLookAndFeel : public LookAndFeel_V4
{
public:
ProjucerLookAndFeel();
~ProjucerLookAndFeel() override;
void drawTabButton (TabBarButton& button, Graphics&, bool isMouseOver, bool isMouseDown) override;
int getTabButtonBestWidth (TabBarButton&, int tabDepth) override;
void drawTabAreaBehindFrontButton (TabbedButtonBar&, Graphics&, int, int) override {}
void drawPropertyComponentBackground (Graphics&, int, int, PropertyComponent&) override {}
void drawPropertyComponentLabel (Graphics&, int width, int height, PropertyComponent&) override;
Rectangle<int> getPropertyComponentContentPosition (PropertyComponent&) override;
void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour,
bool isMouseOverButton, bool isButtonDown) override;
void drawButtonText (Graphics&, TextButton&, bool isMouseOverButton, bool isButtonDown) override;
void drawToggleButton (Graphics&, ToggleButton&, bool isMouseOverButton, bool isButtonDown) override;
void drawTextEditorOutline (Graphics&, int, int, TextEditor&) override {}
void fillTextEditorBackground (Graphics&, int width, int height, TextEditor&) override;
void layoutFileBrowserComponent (FileBrowserComponent&, DirectoryContentsDisplayComponent*,
FilePreviewComponent*, ComboBox* currentPathBox,
TextEditor* filenameBox,Button* goUpButton) override;
void drawFileBrowserRow (Graphics&, int width, int height, const File&, const String& filename, Image* icon,
const String& fileSizeDescription, const String& fileTimeDescription,
bool isDirectory, bool isItemSelected, int itemIndex, DirectoryContentsDisplayComponent&) override;
void drawCallOutBoxBackground (CallOutBox&, Graphics&, const Path&, Image&) override;
void drawMenuBarBackground (Graphics&, int width, int height, bool isMouseOverBar, MenuBarComponent&) override;
void drawMenuBarItem (Graphics&, int width, int height,
int itemIndex, const String& itemText,
bool isMouseOverItem, bool isMenuOpen, bool isMouseOverBar,
MenuBarComponent&) override;
void drawResizableFrame (Graphics&, int w, int h, const BorderSize<int>&) override;
void drawComboBox (Graphics&, int width, int height, bool isButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH,
ComboBox&) override;
void drawTreeviewPlusMinusBox (Graphics&, const Rectangle<float>& area,
Colour backgroundColour, bool isItemOpen, bool isMouseOver) override;
void drawProgressBar (Graphics&, ProgressBar&, int width, int height, double progress, const String& textToShow) override;
//==============================================================================
static Path getArrowPath (Rectangle<float> arrowZone, const int direction,
const bool filled, const Justification justification);
static Path getChoiceComponentArrowPath (Rectangle<float> arrowZone);
static Font getPropertyComponentFont() { return { 14.0f, Font::FontStyleFlags::bold }; }
static int getTextWidthForPropertyComponent (const PropertyComponent& pc) { return jmin (200, pc.getWidth() / 2); }
static ColourScheme getProjucerDarkColourScheme()
{
return { 0xff323e44, 0xff263238, 0xff323e44,
0xff8e989b, 0xffffffff, 0xffa45c94,
0xffffffff, 0xff181f22, 0xffffffff };
}
//==============================================================================
void setupColours();
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjucerLookAndFeel)
};

View File

@ -1,118 +1,118 @@
/*
==============================================================================
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_SlidingPanelComponent.h"
//==============================================================================
struct SlidingPanelComponent::DotButton : public Button
{
DotButton (SlidingPanelComponent& sp, int pageIndex)
: Button (String()), owner (sp), index (pageIndex) {}
void paintButton (Graphics& g, bool /*isMouseOverButton*/, bool /*isButtonDown*/) override
{
g.setColour (findColour (defaultButtonBackgroundColourId));
const auto r = getLocalBounds().reduced (getWidth() / 4).toFloat();
if (index == owner.getCurrentTabIndex())
g.fillEllipse (r);
else
g.drawEllipse (r, 1.0f);
}
void clicked() override
{
owner.goToTab (index);
}
using Button::clicked;
SlidingPanelComponent& owner;
int index;
};
//==============================================================================
SlidingPanelComponent::SlidingPanelComponent()
: currentIndex (0), dotSize (20)
{
addAndMakeVisible (pageHolder);
}
SlidingPanelComponent::~SlidingPanelComponent()
{
}
SlidingPanelComponent::PageInfo::~PageInfo()
{
if (shouldDelete)
content.deleteAndZero();
}
void SlidingPanelComponent::addTab (const String& tabName,
Component* const contentComponent,
const bool deleteComponentWhenNotNeeded,
const int insertIndex)
{
PageInfo* page = new PageInfo();
pages.insert (insertIndex, page);
page->content = contentComponent;
page->dotButton.reset (new DotButton (*this, pages.indexOf (page)));
addAndMakeVisible (page->dotButton.get());
page->name = tabName;
page->shouldDelete = deleteComponentWhenNotNeeded;
pageHolder.addAndMakeVisible (contentComponent);
resized();
}
void SlidingPanelComponent::goToTab (int targetTabIndex)
{
currentIndex = targetTabIndex;
Desktop::getInstance().getAnimator()
.animateComponent (&pageHolder, pageHolder.getBounds().withX (-targetTabIndex * getWidth()),
1.0f, 600, false, 0.0, 0.0);
repaint();
}
void SlidingPanelComponent::resized()
{
pageHolder.setBounds (-currentIndex * getWidth(), pageHolder.getPosition().y,
getNumTabs() * getWidth(), getHeight());
Rectangle<int> content (getLocalBounds());
Rectangle<int> dotHolder = content.removeFromBottom (20 + dotSize)
.reduced ((content.getWidth() - dotSize * getNumTabs()) / 2, 10);
for (int i = 0; i < getNumTabs(); ++i)
pages.getUnchecked(i)->dotButton->setBounds (dotHolder.removeFromLeft (dotSize));
for (int i = pages.size(); --i >= 0;)
if (Component* c = pages.getUnchecked(i)->content)
c->setBounds (content.translated (i * content.getWidth(), 0));
}
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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_SlidingPanelComponent.h"
//==============================================================================
struct SlidingPanelComponent::DotButton : public Button
{
DotButton (SlidingPanelComponent& sp, int pageIndex)
: Button (String()), owner (sp), index (pageIndex) {}
void paintButton (Graphics& g, bool /*isMouseOverButton*/, bool /*isButtonDown*/) override
{
g.setColour (findColour (defaultButtonBackgroundColourId));
const auto r = getLocalBounds().reduced (getWidth() / 4).toFloat();
if (index == owner.getCurrentTabIndex())
g.fillEllipse (r);
else
g.drawEllipse (r, 1.0f);
}
void clicked() override
{
owner.goToTab (index);
}
using Button::clicked;
SlidingPanelComponent& owner;
int index;
};
//==============================================================================
SlidingPanelComponent::SlidingPanelComponent()
: currentIndex (0), dotSize (20)
{
addAndMakeVisible (pageHolder);
}
SlidingPanelComponent::~SlidingPanelComponent()
{
}
SlidingPanelComponent::PageInfo::~PageInfo()
{
if (shouldDelete)
content.deleteAndZero();
}
void SlidingPanelComponent::addTab (const String& tabName,
Component* const contentComponent,
const bool deleteComponentWhenNotNeeded,
const int insertIndex)
{
PageInfo* page = new PageInfo();
pages.insert (insertIndex, page);
page->content = contentComponent;
page->dotButton.reset (new DotButton (*this, pages.indexOf (page)));
addAndMakeVisible (page->dotButton.get());
page->name = tabName;
page->shouldDelete = deleteComponentWhenNotNeeded;
pageHolder.addAndMakeVisible (contentComponent);
resized();
}
void SlidingPanelComponent::goToTab (int targetTabIndex)
{
currentIndex = targetTabIndex;
Desktop::getInstance().getAnimator()
.animateComponent (&pageHolder, pageHolder.getBounds().withX (-targetTabIndex * getWidth()),
1.0f, 600, false, 0.0, 0.0);
repaint();
}
void SlidingPanelComponent::resized()
{
pageHolder.setBounds (-currentIndex * getWidth(), pageHolder.getPosition().y,
getNumTabs() * getWidth(), getHeight());
Rectangle<int> content (getLocalBounds());
Rectangle<int> dotHolder = content.removeFromBottom (20 + dotSize)
.reduced ((content.getWidth() - dotSize * getNumTabs()) / 2, 10);
for (int i = 0; i < getNumTabs(); ++i)
pages.getUnchecked(i)->dotButton->setBounds (dotHolder.removeFromLeft (dotSize));
for (int i = pages.size(); --i >= 0;)
if (Component* c = pages.getUnchecked(i)->content)
c->setBounds (content.translated (i * content.getWidth(), 0));
}

View File

@ -1,79 +1,79 @@
/*
==============================================================================
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 "../../Application/jucer_Application.h"
//==============================================================================
class SlidingPanelComponent : public Component
{
public:
SlidingPanelComponent();
~SlidingPanelComponent() override;
/** Adds a new tab to the panel slider. */
void addTab (const String& tabName,
Component* contentComponent,
bool deleteComponentWhenNotNeeded,
int insertIndex = -1);
/** Gets rid of one of the tabs. */
void removeTab (int tabIndex);
/** Gets index of current tab. */
int getCurrentTabIndex() const noexcept { return currentIndex; }
/** Returns the number of tabs. */
int getNumTabs() const noexcept { return pages.size(); }
/** Animates the window to the desired tab. */
void goToTab (int targetTabIndex);
//==============================================================================
/** @internal */
void resized() override;
private:
struct DotButton;
friend struct DotButton;
struct PageInfo
{
~PageInfo();
Component::SafePointer<Component> content;
std::unique_ptr<DotButton> dotButton;
String name;
bool shouldDelete;
};
OwnedArray<PageInfo> pages;
Component pageHolder;
int currentIndex, dotSize;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SlidingPanelComponent)
};
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - 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 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-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 "../../Application/jucer_Application.h"
//==============================================================================
class SlidingPanelComponent : public Component
{
public:
SlidingPanelComponent();
~SlidingPanelComponent() override;
/** Adds a new tab to the panel slider. */
void addTab (const String& tabName,
Component* contentComponent,
bool deleteComponentWhenNotNeeded,
int insertIndex = -1);
/** Gets rid of one of the tabs. */
void removeTab (int tabIndex);
/** Gets index of current tab. */
int getCurrentTabIndex() const noexcept { return currentIndex; }
/** Returns the number of tabs. */
int getNumTabs() const noexcept { return pages.size(); }
/** Animates the window to the desired tab. */
void goToTab (int targetTabIndex);
//==============================================================================
/** @internal */
void resized() override;
private:
struct DotButton;
friend struct DotButton;
struct PageInfo
{
~PageInfo();
Component::SafePointer<Component> content;
std::unique_ptr<DotButton> dotButton;
String name;
bool shouldDelete;
};
OwnedArray<PageInfo> pages;
Component pageHolder;
int currentIndex, dotSize;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SlidingPanelComponent)
};