mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-19 01:04:20 +00:00
More Jucer reorganisation
This commit is contained in:
parent
ca5fbd17f0
commit
6e6ae97aae
14 changed files with 2254 additions and 0 deletions
456
extras/Jucer (experimental)/Source/Utility/jucer_CodeHelpers.cpp
Normal file
456
extras/Jucer (experimental)/Source/Utility/jucer_CodeHelpers.cpp
Normal file
|
|
@ -0,0 +1,456 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../jucer_Headers.h"
|
||||
#include "jucer_CodeHelpers.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
namespace CodeHelpers
|
||||
{
|
||||
const String indent (const String& code, const int numSpaces, bool indentFirstLine)
|
||||
{
|
||||
if (numSpaces == 0)
|
||||
return code;
|
||||
|
||||
const String space (String::repeatedString (" ", numSpaces));
|
||||
|
||||
StringArray lines;
|
||||
lines.addLines (code);
|
||||
|
||||
for (int i = (indentFirstLine ? 0 : 1); i < lines.size(); ++i)
|
||||
{
|
||||
String s (lines[i].trimEnd());
|
||||
if (s.isNotEmpty())
|
||||
s = space + s;
|
||||
|
||||
lines.set (i, s);
|
||||
}
|
||||
|
||||
return lines.joinIntoString (newLine);
|
||||
}
|
||||
|
||||
const String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates)
|
||||
{
|
||||
if (s.isEmpty())
|
||||
return "unknown";
|
||||
|
||||
if (removeColons)
|
||||
s = s.replaceCharacters (".,;:/@", "______");
|
||||
else
|
||||
s = s.replaceCharacters (".,;/@", "_____");
|
||||
|
||||
int i;
|
||||
for (i = s.length(); --i > 0;)
|
||||
if (CharacterFunctions::isLetter (s[i])
|
||||
&& CharacterFunctions::isLetter (s[i - 1])
|
||||
&& CharacterFunctions::isUpperCase (s[i])
|
||||
&& ! CharacterFunctions::isUpperCase (s[i - 1]))
|
||||
s = s.substring (0, i) + " " + s.substring (i);
|
||||
|
||||
String allowedChars ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ 0123456789");
|
||||
if (allowTemplates)
|
||||
allowedChars += "<>";
|
||||
|
||||
if (! removeColons)
|
||||
allowedChars += ":";
|
||||
|
||||
StringArray words;
|
||||
words.addTokens (s.retainCharacters (allowedChars), false);
|
||||
words.trim();
|
||||
|
||||
String n (words[0]);
|
||||
|
||||
if (capitalise)
|
||||
n = n.toLowerCase();
|
||||
|
||||
for (i = 1; i < words.size(); ++i)
|
||||
{
|
||||
if (capitalise && words[i].length() > 1)
|
||||
n << words[i].substring (0, 1).toUpperCase()
|
||||
<< words[i].substring (1).toLowerCase();
|
||||
else
|
||||
n << words[i];
|
||||
}
|
||||
|
||||
if (CharacterFunctions::isDigit (n[0]))
|
||||
n = "_" + n;
|
||||
|
||||
if (CPlusPlusCodeTokeniser::isReservedKeyword (n))
|
||||
n << '_';
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
template <class CharType>
|
||||
static void writeEscapeChars (OutputStream& out, const CharType* data, const int numChars,
|
||||
const int maxCharsOnLine, const bool breakAtNewLines, const bool replaceSingleQuotes)
|
||||
{
|
||||
int charsOnLine = 0;
|
||||
bool lastWasHexEscapeCode = false;
|
||||
|
||||
for (int i = 0; i < numChars || numChars < 0; ++i)
|
||||
{
|
||||
const CharType c = data[i];
|
||||
bool startNewLine = false;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\t': out << "\\t"; lastWasHexEscapeCode = false; break;
|
||||
case '\r': out << "\\r"; lastWasHexEscapeCode = false; break;
|
||||
case '\n': out << "\\n"; lastWasHexEscapeCode = false; startNewLine = breakAtNewLines; break;
|
||||
case '\\': out << "\\\\"; lastWasHexEscapeCode = false; break;
|
||||
case '\"': out << "\\\""; lastWasHexEscapeCode = false; break;
|
||||
|
||||
case 0:
|
||||
if (numChars < 0)
|
||||
return;
|
||||
|
||||
out << "\\0";
|
||||
lastWasHexEscapeCode = true;
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
if (replaceSingleQuotes)
|
||||
{
|
||||
out << "\\\'";
|
||||
lastWasHexEscapeCode = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// deliberate fall-through...
|
||||
|
||||
default:
|
||||
if (c >= 32 && c < 127 && ! (lastWasHexEscapeCode // (have to avoid following a hex escape sequence with a valid hex digit)
|
||||
&& ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))))
|
||||
{
|
||||
out << (char) c;
|
||||
lastWasHexEscapeCode = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << (c < 16 ? "\\x0" : "\\x") << String::toHexString ((int) (unsigned int) c);
|
||||
lastWasHexEscapeCode = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ((startNewLine || (maxCharsOnLine > 0 && ++charsOnLine >= maxCharsOnLine))
|
||||
&& (numChars < 0 || i < numChars - 1))
|
||||
{
|
||||
charsOnLine = 0;
|
||||
out << "\"" << newLine << "\"";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const String addEscapeChars (const String& s)
|
||||
{
|
||||
MemoryOutputStream out;
|
||||
writeEscapeChars (out, (const juce_wchar*) s, -1, -1, false, true);
|
||||
return out.toUTF8();
|
||||
}
|
||||
|
||||
const String createIncludeStatement (const File& includeFile, const File& targetFile)
|
||||
{
|
||||
return "#include \"" + FileHelpers::unixStylePath (includeFile.getRelativePathFrom (targetFile.getParentDirectory())) + "\"";
|
||||
}
|
||||
|
||||
const String makeHeaderGuardName (const File& file)
|
||||
{
|
||||
return "__" + file.getFileName().toUpperCase()
|
||||
.replaceCharacters (" .", "__")
|
||||
.retainCharacters ("_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||
+ "_" + String::toHexString (file.hashCode()).toUpperCase() + "__";
|
||||
}
|
||||
|
||||
const String stringLiteral (const String& text)
|
||||
{
|
||||
if (text.isEmpty())
|
||||
return "String::empty";
|
||||
|
||||
return CodeHelpers::addEscapeChars (text).quoted();
|
||||
}
|
||||
|
||||
const String boolLiteral (const bool b)
|
||||
{
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
const String floatLiteral (float v)
|
||||
{
|
||||
String s ((double) v, 4);
|
||||
|
||||
if (s.containsChar ('.'))
|
||||
{
|
||||
s = s.trimCharactersAtEnd ("0");
|
||||
if (s.endsWithChar ('.'))
|
||||
s << '0';
|
||||
|
||||
s << 'f';
|
||||
}
|
||||
else
|
||||
{
|
||||
s << ".0f";
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
const String doubleLiteral (double v)
|
||||
{
|
||||
String s (v, 7);
|
||||
|
||||
if (s.containsChar ('.'))
|
||||
{
|
||||
s = s.trimCharactersAtEnd ("0");
|
||||
if (s.endsWithChar ('.'))
|
||||
s << '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
s << ".0";
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
const String colourToCode (const 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
|
||||
0
|
||||
};
|
||||
|
||||
for (int i = 0; i < numElementsInArray (colourNames) - 1; ++i)
|
||||
if (col == colours[i])
|
||||
return "Colours::" + String (colourNames[i]);
|
||||
|
||||
return "Colour (0x" + hexString8Digits ((int) col.getARGB()) + ')';
|
||||
}
|
||||
|
||||
const String justificationToCode (const Justification& justification)
|
||||
{
|
||||
switch (justification.getFlags())
|
||||
{
|
||||
case Justification::centred: return "Justification::centred";
|
||||
case Justification::centredLeft: return "Justification::centredLeft";
|
||||
case Justification::centredRight: return "Justification::centredRight";
|
||||
case Justification::centredTop: return "Justification::centredTop";
|
||||
case Justification::centredBottom: return "Justification::centredBottom";
|
||||
case Justification::topLeft: return "Justification::topLeft";
|
||||
case Justification::topRight: return "Justification::topRight";
|
||||
case Justification::bottomLeft: return "Justification::bottomLeft";
|
||||
case Justification::bottomRight: return "Justification::bottomRight";
|
||||
case Justification::left: return "Justification::left";
|
||||
case Justification::right: return "Justification::right";
|
||||
case Justification::horizontallyCentred: return "Justification::horizontallyCentred";
|
||||
case Justification::top: return "Justification::top";
|
||||
case Justification::bottom: return "Justification::bottom";
|
||||
case Justification::verticallyCentred: return "Justification::verticallyCentred";
|
||||
case Justification::horizontallyJustified: return "Justification::horizontallyJustified";
|
||||
default: jassertfalse; break;
|
||||
}
|
||||
|
||||
return "Justification (" + String (justification.getFlags()) + ")";
|
||||
}
|
||||
|
||||
const String fontToCode (const Font& font)
|
||||
{
|
||||
String s ("Font (");
|
||||
String name (font.getTypefaceName());
|
||||
|
||||
if (name != Font::getDefaultSansSerifFontName())
|
||||
{
|
||||
if (name == Font::getDefaultSerifFontName())
|
||||
name = "Font::getDefaultSerifFontName()";
|
||||
else if (name == Font::getDefaultMonospacedFontName())
|
||||
name = "Font::getDefaultMonospacedFontName()";
|
||||
else
|
||||
name = stringLiteral (font.getTypefaceName());
|
||||
|
||||
s << name << ", ";
|
||||
}
|
||||
|
||||
s << floatLiteral (font.getHeight());
|
||||
|
||||
if (font.isBold() && font.isItalic())
|
||||
s << ", Font::bold | Font::italic";
|
||||
else if (font.isBold())
|
||||
s << ", Font::bold";
|
||||
else if (font.isItalic())
|
||||
s << ", Font::italic";
|
||||
|
||||
return s + ")";
|
||||
}
|
||||
|
||||
const String castToFloat (const String& expression)
|
||||
{
|
||||
if (expression.containsOnly ("0123456789.f"))
|
||||
{
|
||||
String s (expression.getFloatValue());
|
||||
|
||||
if (s.containsChar (T('.')))
|
||||
return s + "f";
|
||||
|
||||
return s + ".0f";
|
||||
}
|
||||
|
||||
return "(float) (" + expression + ")";
|
||||
}
|
||||
|
||||
void writeDataAsCppLiteral (const MemoryBlock& mb, OutputStream& out)
|
||||
{
|
||||
const int maxCharsOnLine = 250;
|
||||
|
||||
const unsigned char* data = (const unsigned char*) mb.getData();
|
||||
int charsOnLine = 0;
|
||||
|
||||
bool canUseStringLiteral = mb.getSize() < 32768; // MS compilers can't handle big string literals..
|
||||
|
||||
if (canUseStringLiteral)
|
||||
{
|
||||
unsigned int numEscaped = 0;
|
||||
|
||||
for (size_t i = 0; i < mb.getSize(); ++i)
|
||||
{
|
||||
const unsigned int num = (unsigned int) data[i];
|
||||
if (! ((num >= 32 && num < 127) || num == '\t' || num == '\r' || num == '\n'))
|
||||
{
|
||||
if (++numEscaped > mb.getSize() / 4)
|
||||
{
|
||||
canUseStringLiteral = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! canUseStringLiteral)
|
||||
{
|
||||
out << "{ ";
|
||||
|
||||
for (size_t i = 0; i < mb.getSize(); ++i)
|
||||
{
|
||||
const int num = (int) (unsigned int) data[i];
|
||||
out << num << ',';
|
||||
|
||||
charsOnLine += 2;
|
||||
if (num >= 10)
|
||||
++charsOnLine;
|
||||
if (num >= 100)
|
||||
++charsOnLine;
|
||||
|
||||
if (charsOnLine >= maxCharsOnLine)
|
||||
{
|
||||
charsOnLine = 0;
|
||||
out << newLine;
|
||||
}
|
||||
}
|
||||
|
||||
out << "0,0 };";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "\"";
|
||||
writeEscapeChars (out, data, (int) mb.getSize(), maxCharsOnLine, true, false);
|
||||
out << "\";";
|
||||
}
|
||||
}
|
||||
|
||||
static int calculateHash (const String& s, const int hashMultiplier)
|
||||
{
|
||||
const char* t = s.toUTF8();
|
||||
int hash = 0;
|
||||
while (*t != 0)
|
||||
hash = hashMultiplier * hash + *t++;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static int findBestHashMultiplier (const StringArray& strings)
|
||||
{
|
||||
int v = 31;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
SortedSet <int> hashes;
|
||||
bool collision = false;
|
||||
for (int i = strings.size(); --i >= 0;)
|
||||
{
|
||||
const int hash = calculateHash (strings[i], v);
|
||||
if (hashes.contains (hash))
|
||||
{
|
||||
collision = true;
|
||||
break;
|
||||
}
|
||||
|
||||
hashes.add (hash);
|
||||
}
|
||||
|
||||
if (! collision)
|
||||
break;
|
||||
|
||||
v += 2;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void createStringMatcher (OutputStream& out, const String& utf8PointerVariable,
|
||||
const StringArray& strings, const StringArray& codeToExecute, const int indentLevel)
|
||||
{
|
||||
jassert (strings.size() == codeToExecute.size());
|
||||
const String indent (String::repeatedString (" ", indentLevel));
|
||||
const int hashMultiplier = findBestHashMultiplier (strings);
|
||||
|
||||
out << indent << "int hash = 0;" << newLine
|
||||
<< indent << "if (" << utf8PointerVariable << " != 0)" << newLine
|
||||
<< indent << " while (*" << utf8PointerVariable << " != 0)" << newLine
|
||||
<< indent << " hash = " << hashMultiplier << " * hash + *" << utf8PointerVariable << "++;" << newLine
|
||||
<< newLine
|
||||
<< indent << "switch (hash)" << newLine
|
||||
<< indent << "{" << newLine;
|
||||
|
||||
for (int i = 0; i < strings.size(); ++i)
|
||||
out << indent << " case 0x" << hexString8Digits (calculateHash (strings[i], hashMultiplier))
|
||||
<< ": " << codeToExecute[i] << newLine;
|
||||
|
||||
out << indent << " default: break;" << newLine
|
||||
<< indent << "}" << newLine << newLine;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCER_CODEUTILITIES_H_B86AA5D2__
|
||||
#define __JUCER_CODEUTILITIES_H_B86AA5D2__
|
||||
|
||||
|
||||
//==============================================================================
|
||||
namespace CodeHelpers
|
||||
{
|
||||
const String indent (const String& code, const int numSpaces, bool indentFirstLine);
|
||||
const String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates);
|
||||
const String addEscapeChars (const String& text);
|
||||
const String createIncludeStatement (const File& includeFile, const File& targetFile);
|
||||
const String makeHeaderGuardName (const File& file);
|
||||
|
||||
const String stringLiteral (const String& text);
|
||||
const String boolLiteral (bool b);
|
||||
const String floatLiteral (float v);
|
||||
const String doubleLiteral (double v);
|
||||
|
||||
const String colourToCode (const Colour& col);
|
||||
const String justificationToCode (const Justification& justification);
|
||||
const String castToFloat (const String& expression);
|
||||
const String fontToCode (const Font& font);
|
||||
|
||||
void writeDataAsCppLiteral (const MemoryBlock& data, OutputStream& out);
|
||||
|
||||
void createStringMatcher (OutputStream& out, const String& utf8PointerVariable,
|
||||
const StringArray& strings, const StringArray& codeToExecute, const int indentLevel);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // __JUCER_CODEUTILITIES_H_B86AA5D2__
|
||||
162
extras/Jucer (experimental)/Source/Utility/jucer_Colours.h
Normal file
162
extras/Jucer (experimental)/Source/Utility/jucer_Colours.h
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
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)
|
||||
177
extras/Jucer (experimental)/Source/Utility/jucer_FileHelpers.cpp
Normal file
177
extras/Jucer (experimental)/Source/Utility/jucer_FileHelpers.cpp
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
jucer_FileUtilities.cpp
|
||||
Created: 14 May 2010 11:24:09pm
|
||||
Author: Julian Storer
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../jucer_Headers.h"
|
||||
#include "jucer_CodeHelpers.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
namespace FileHelpers
|
||||
{
|
||||
int64 calculateStreamHashCode (InputStream& in)
|
||||
{
|
||||
int64 t = 0;
|
||||
|
||||
const int bufferSize = 4096;
|
||||
HeapBlock <uint8> buffer;
|
||||
buffer.malloc (bufferSize);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const int num = in.read (buffer, bufferSize);
|
||||
|
||||
if (num <= 0)
|
||||
break;
|
||||
|
||||
for (int i = 0; i < num; ++i)
|
||||
t = t * 65599 + buffer[i];
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
int64 calculateFileHashCode (const File& file)
|
||||
{
|
||||
ScopedPointer <FileInputStream> stream (file.createInputStream());
|
||||
return stream != 0 ? calculateStreamHashCode (*stream) : 0;
|
||||
}
|
||||
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const char* data, int numBytes)
|
||||
{
|
||||
if (file.getSize() == numBytes)
|
||||
{
|
||||
MemoryInputStream newStream (data, numBytes, false);
|
||||
|
||||
if (calculateStreamHashCode (newStream) == calculateFileHashCode (file))
|
||||
return true;
|
||||
}
|
||||
|
||||
TemporaryFile temp (file);
|
||||
|
||||
return temp.getFile().appendData (data, numBytes)
|
||||
&& temp.overwriteTargetFileWithTemporary();
|
||||
}
|
||||
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData)
|
||||
{
|
||||
return overwriteFileWithNewDataIfDifferent (file, newData.getData(), newData.getDataSize());
|
||||
}
|
||||
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData)
|
||||
{
|
||||
return overwriteFileWithNewDataIfDifferent (file, newData.toUTF8(), strlen ((const char*) newData.toUTF8()));
|
||||
}
|
||||
|
||||
bool containsAnyNonHiddenFiles (const File& folder)
|
||||
{
|
||||
DirectoryIterator di (folder, false);
|
||||
|
||||
while (di.next())
|
||||
if (! di.getFile().isHidden())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const String unixStylePath (const String& path)
|
||||
{
|
||||
return path.replaceCharacter ('\\', '/');
|
||||
}
|
||||
|
||||
const String windowsStylePath (const String& path)
|
||||
{
|
||||
return path.replaceCharacter ('/', '\\');
|
||||
}
|
||||
|
||||
const String appendPath (const String& path, const String& subpath)
|
||||
{
|
||||
if (File::isAbsolutePath (subpath)
|
||||
|| subpath.startsWithChar ('$')
|
||||
|| subpath.startsWithChar ('~')
|
||||
|| (CharacterFunctions::isLetter (subpath[0]) && subpath[1] == ':'))
|
||||
return subpath.replaceCharacter ('\\', '/');
|
||||
|
||||
String path1 (path.replaceCharacter ('\\', '/'));
|
||||
if (! path1.endsWithChar ('/'))
|
||||
path1 << '/';
|
||||
|
||||
return path1 + subpath.replaceCharacter ('\\', '/');
|
||||
}
|
||||
|
||||
bool shouldPathsBeRelative (String path1, String path2)
|
||||
{
|
||||
path1 = unixStylePath (path1);
|
||||
path2 = 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();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool isJuceFolder (const File& folder)
|
||||
{
|
||||
return folder.getFileName().containsIgnoreCase ("juce")
|
||||
&& folder.getChildFile ("juce.h").exists()
|
||||
&& folder.getChildFile ("juce_Config.h").exists();
|
||||
}
|
||||
|
||||
static const File lookInFolderForJuceFolder (const File& folder)
|
||||
{
|
||||
for (DirectoryIterator di (folder, false, "*juce*", File::findDirectories); di.next();)
|
||||
{
|
||||
if (isJuceFolder (di.getFile()))
|
||||
return di.getFile();
|
||||
}
|
||||
|
||||
return File::nonexistent;
|
||||
}
|
||||
|
||||
const File findParentJuceFolder (const File& file)
|
||||
{
|
||||
File f (file);
|
||||
|
||||
while (f.exists() && f.getParentDirectory() != f)
|
||||
{
|
||||
if (isJuceFolder (f))
|
||||
return f;
|
||||
|
||||
File found = lookInFolderForJuceFolder (f);
|
||||
if (found.exists())
|
||||
return found;
|
||||
|
||||
f = f.getParentDirectory();
|
||||
}
|
||||
|
||||
return File::nonexistent;
|
||||
}
|
||||
|
||||
const File findDefaultJuceFolder()
|
||||
{
|
||||
File f = findParentJuceFolder (File::getSpecialLocation (File::currentApplicationFile));
|
||||
|
||||
if (! f.exists())
|
||||
f = lookInFolderForJuceFolder (File::getSpecialLocation (File::userHomeDirectory));
|
||||
|
||||
if (! f.exists())
|
||||
f = lookInFolderForJuceFolder (File::getSpecialLocation (File::userDocumentsDirectory));
|
||||
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCER_FILEUTILITIES_H_EEE25EE3__
|
||||
#define __JUCER_FILEUTILITIES_H_EEE25EE3__
|
||||
|
||||
|
||||
//==============================================================================
|
||||
namespace FileHelpers
|
||||
{
|
||||
int64 calculateStreamHashCode (InputStream& stream);
|
||||
int64 calculateFileHashCode (const File& file);
|
||||
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const char* data, int numBytes);
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData);
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData);
|
||||
|
||||
bool containsAnyNonHiddenFiles (const File& folder);
|
||||
|
||||
const String unixStylePath (const String& path);
|
||||
const String windowsStylePath (const String& path);
|
||||
|
||||
bool shouldPathsBeRelative (String path1, String path2);
|
||||
|
||||
//==============================================================================
|
||||
bool isJuceFolder (const File& folder);
|
||||
const File findParentJuceFolder (const File& file);
|
||||
const File findDefaultJuceFolder();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class FileModificationDetector
|
||||
{
|
||||
public:
|
||||
FileModificationDetector (const File& file_)
|
||||
: file (file_)
|
||||
{
|
||||
}
|
||||
|
||||
const File& getFile() const { return file; }
|
||||
void fileHasBeenRenamed (const File& newFile) { file = newFile; }
|
||||
|
||||
bool hasBeenModified() const
|
||||
{
|
||||
return fileModificationTime != file.getLastModificationTime()
|
||||
&& (fileSize != file.getSize()
|
||||
|| FileHelpers::calculateFileHashCode (file) != fileHashCode);
|
||||
}
|
||||
|
||||
void updateHash()
|
||||
{
|
||||
fileModificationTime = file.getLastModificationTime();
|
||||
fileSize = file.getSize();
|
||||
fileHashCode = FileHelpers::calculateFileHashCode (file);
|
||||
}
|
||||
|
||||
private:
|
||||
File file;
|
||||
Time fileModificationTime;
|
||||
int64 fileHashCode, fileSize;
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCER_FILEUTILITIES_H_EEE25EE3__
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "jucer_JucerTreeViewBase.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
JucerTreeViewBase::JucerTreeViewBase()
|
||||
{
|
||||
setLinesDrawnForSubItems (false);
|
||||
}
|
||||
|
||||
JucerTreeViewBase::~JucerTreeViewBase()
|
||||
{
|
||||
}
|
||||
|
||||
const Font JucerTreeViewBase::getFont() const
|
||||
{
|
||||
return Font (getItemHeight() * 0.6f);
|
||||
}
|
||||
|
||||
int JucerTreeViewBase::getTextX() const
|
||||
{
|
||||
return getItemHeight() + 6;
|
||||
}
|
||||
|
||||
void JucerTreeViewBase::paintItem (Graphics& g, int width, int height)
|
||||
{
|
||||
if (isSelected())
|
||||
g.fillAll (Colour (0x401111ee));
|
||||
|
||||
const int x = getTextX();
|
||||
|
||||
g.setColour (isMissing() ? Colours::red : Colours::black);
|
||||
|
||||
g.drawImageWithin (getIcon(), 2, 2, x - 4, height - 4,
|
||||
RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize,
|
||||
false);
|
||||
|
||||
g.setFont (getFont());
|
||||
g.drawFittedText (getDisplayName(), x, 0, width - x, height, Justification::centredLeft, 1, 0.8f);
|
||||
}
|
||||
|
||||
void JucerTreeViewBase::paintOpenCloseButton (Graphics& g, int width, int height, bool isMouseOver)
|
||||
{
|
||||
Path p;
|
||||
|
||||
if (isOpen())
|
||||
p.addTriangle (width * 0.2f, height * 0.25f, width * 0.8f, height * 0.25f, width * 0.5f, height * 0.75f);
|
||||
else
|
||||
p.addTriangle (width * 0.25f, height * 0.25f, width * 0.8f, height * 0.5f, width * 0.25f, height * 0.75f);
|
||||
|
||||
g.setColour (Colours::lightgrey);
|
||||
g.fillPath (p);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void JucerTreeViewBase::showRenameBox()
|
||||
{
|
||||
TextEditor ed (String::empty);
|
||||
ed.setMultiLine (false, false);
|
||||
ed.setPopupMenuEnabled (false);
|
||||
ed.setSelectAllWhenFocused (true);
|
||||
ed.setFont (getFont());
|
||||
ed.addListener (this);
|
||||
ed.setText (getRenamingName());
|
||||
|
||||
Rectangle<int> r (getItemPosition (true));
|
||||
r.setLeft (r.getX() + getTextX());
|
||||
r.setHeight (getItemHeight());
|
||||
ed.setBounds (r);
|
||||
getOwnerView()->addAndMakeVisible (&ed);
|
||||
|
||||
if (ed.runModalLoop() != 0)
|
||||
setName (ed.getText());
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCER_JUCERTREEVIEWBASE_JUCEHEADER__
|
||||
#define __JUCER_JUCERTREEVIEWBASE_JUCEHEADER__
|
||||
|
||||
#include "../jucer_Headers.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class JucerTreeViewBase : public TreeViewItem,
|
||||
public TextEditorListener
|
||||
{
|
||||
protected:
|
||||
//==============================================================================
|
||||
JucerTreeViewBase();
|
||||
~JucerTreeViewBase();
|
||||
|
||||
public:
|
||||
//==============================================================================
|
||||
int getItemWidth() const { return -1; }
|
||||
int getItemHeight() const { return 20; }
|
||||
Component* createItemComponent() { return 0; }
|
||||
|
||||
void paintItem (Graphics& g, int width, int height);
|
||||
void paintOpenCloseButton (Graphics& g, int width, int height, bool isMouseOver);
|
||||
|
||||
//==============================================================================
|
||||
virtual const String getRenamingName() const = 0;
|
||||
virtual const String getDisplayName() const = 0;
|
||||
virtual void setName (const String& newName) = 0;
|
||||
virtual bool isMissing() = 0;
|
||||
virtual const Image getIcon() const = 0;
|
||||
|
||||
virtual void showRenameBox();
|
||||
|
||||
// Text editor listener for renaming..
|
||||
void textEditorTextChanged (TextEditor& editor) {}
|
||||
void textEditorReturnKeyPressed (TextEditor& editor) { editor.exitModalState (1); }
|
||||
void textEditorEscapeKeyPressed (TextEditor& editor) { editor.exitModalState (0); }
|
||||
void textEditorFocusLost (TextEditor& editor) { editor.exitModalState (0); }
|
||||
|
||||
//==============================================================================
|
||||
private:
|
||||
const Font getFont() const;
|
||||
int getTextX() const;
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCER_JUCERTREEVIEWBASE_JUCEHEADER__
|
||||
|
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../jucer_Headers.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
const int64 hashCode64 (const String& s)
|
||||
{
|
||||
return s.hashCode64() + s.length() * s.hashCode() + s.toUpperCase().hashCode();
|
||||
}
|
||||
|
||||
const String createAlphaNumericUID()
|
||||
{
|
||||
String uid;
|
||||
static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
Random r (Random::getSystemRandom().nextInt64());
|
||||
|
||||
for (int i = 7; --i >= 0;)
|
||||
{
|
||||
r.setSeedRandomly();
|
||||
uid << chars [r.nextInt (numElementsInArray (chars))];
|
||||
}
|
||||
|
||||
return uid;
|
||||
}
|
||||
|
||||
const String randomHexString (Random& random, int numChars)
|
||||
{
|
||||
String s;
|
||||
const char hexChars[] = "0123456789ABCDEF";
|
||||
|
||||
while (--numChars >= 0)
|
||||
s << hexChars [random.nextInt (16)];
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
const String hexString8Digits (int value)
|
||||
{
|
||||
return String::toHexString (value).paddedLeft ('0', 8);
|
||||
}
|
||||
|
||||
const String createGUID (const String& seed)
|
||||
{
|
||||
String guid;
|
||||
Random r (hashCode64 (seed + "_jucersalt"));
|
||||
guid << "{" << randomHexString (r, 8); // (written as separate statements to enforce the order of execution)
|
||||
guid << "-" << randomHexString (r, 4);
|
||||
guid << "-" << randomHexString (r, 4);
|
||||
guid << "-" << randomHexString (r, 4);
|
||||
guid << "-" << randomHexString (r, 12) << "}";
|
||||
return guid;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void autoScrollForMouseEvent (const MouseEvent& e, bool scrollX, bool scrollY)
|
||||
{
|
||||
Viewport* const viewport = e.eventComponent->findParentComponentOfClass ((Viewport*) 0);
|
||||
|
||||
if (viewport != 0)
|
||||
{
|
||||
const MouseEvent e2 (e.getEventRelativeTo (viewport));
|
||||
viewport->autoScroll (scrollX ? e2.x : 20, scrollY ? e2.y : 20, 8, 16);
|
||||
}
|
||||
}
|
||||
|
||||
void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text)
|
||||
{
|
||||
g.fillAll (Colours::white.withAlpha (0.4f));
|
||||
g.setColour (Colours::grey);
|
||||
g.drawRect (0, 0, w, h);
|
||||
|
||||
g.drawLine (0.5f, 0.5f, w - 0.5f, h - 0.5f);
|
||||
g.drawLine (0.5f, h - 0.5f, w - 0.5f, 0.5f);
|
||||
|
||||
g.setColour (Colours::black);
|
||||
g.setFont (11.0f);
|
||||
g.drawFittedText (text, 2, 2, w - 4, h - 4, Justification::centredTop, 2);
|
||||
}
|
||||
|
||||
void drawRecessedShadows (Graphics& g, int w, int h, int shadowSize)
|
||||
{
|
||||
ColourGradient cg (Colours::black.withAlpha (0.15f), 0, 0,
|
||||
Colours::transparentBlack, 0, (float) shadowSize, false);
|
||||
cg.addColour (0.4, Colours::black.withAlpha (0.07f));
|
||||
cg.addColour (0.6, Colours::black.withAlpha (0.02f));
|
||||
|
||||
g.setGradientFill (cg);
|
||||
g.fillRect (0, 0, w, shadowSize);
|
||||
|
||||
cg.point1.setXY (0.0f, (float) h);
|
||||
cg.point2.setXY (0.0f, (float) h - shadowSize);
|
||||
g.setGradientFill (cg);
|
||||
g.fillRect (0, h - shadowSize, w, shadowSize);
|
||||
|
||||
cg.point1.setXY (0.0f, 0.0f);
|
||||
cg.point2.setXY ((float) shadowSize, 0.0f);
|
||||
g.setGradientFill (cg);
|
||||
g.fillRect (0, 0, shadowSize, h);
|
||||
|
||||
cg.point1.setXY ((float) w, 0.0f);
|
||||
cg.point2.setXY ((float) w - shadowSize, 0.0f);
|
||||
g.setGradientFill (cg);
|
||||
g.fillRect (w - shadowSize, 0, shadowSize, h);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex)
|
||||
{
|
||||
startIndex = jmax (0, startIndex);
|
||||
|
||||
while (startIndex < lines.size())
|
||||
{
|
||||
if (lines[startIndex].trimStart().startsWithIgnoreCase (text))
|
||||
return startIndex;
|
||||
|
||||
++startIndex;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
PropertyPanelWithTooltips::PropertyPanelWithTooltips()
|
||||
: lastComp (0)
|
||||
{
|
||||
addAndMakeVisible (panel = new PropertyPanel());
|
||||
startTimer (150);
|
||||
}
|
||||
|
||||
PropertyPanelWithTooltips::~PropertyPanelWithTooltips()
|
||||
{
|
||||
deleteAllChildren();
|
||||
}
|
||||
|
||||
void PropertyPanelWithTooltips::paint (Graphics& g)
|
||||
{
|
||||
g.setColour (Colour::greyLevel (0.15f));
|
||||
g.setFont (13.0f);
|
||||
|
||||
TextLayout tl;
|
||||
tl.appendText (lastTip, Font (14.0f));
|
||||
tl.layout (getWidth() - 10, Justification::left, true); // try to make it look nice
|
||||
if (tl.getNumLines() > 3)
|
||||
tl.layout (getWidth() - 10, Justification::left, false); // too big, so just squash it in..
|
||||
|
||||
tl.drawWithin (g, 5, panel->getBottom() + 2, getWidth() - 10,
|
||||
getHeight() - panel->getBottom() - 4,
|
||||
Justification::centredLeft);
|
||||
}
|
||||
|
||||
void PropertyPanelWithTooltips::resized()
|
||||
{
|
||||
panel->setBounds (0, 0, getWidth(), jmax (getHeight() - 60, proportionOfHeight (0.6f)));
|
||||
}
|
||||
|
||||
void PropertyPanelWithTooltips::timerCallback()
|
||||
{
|
||||
Component* const newComp = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse();
|
||||
|
||||
if (newComp != lastComp)
|
||||
{
|
||||
lastComp = newComp;
|
||||
|
||||
String newTip (findTip (newComp));
|
||||
|
||||
if (newTip != lastTip)
|
||||
{
|
||||
lastTip = newTip;
|
||||
repaint (0, panel->getBottom(), getWidth(), getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const String PropertyPanelWithTooltips::findTip (Component* c)
|
||||
{
|
||||
while (c != 0 && c != this)
|
||||
{
|
||||
TooltipClient* const tc = dynamic_cast <TooltipClient*> (c);
|
||||
if (tc != 0)
|
||||
{
|
||||
const String tip (tc->getTooltip());
|
||||
|
||||
if (tip.isNotEmpty())
|
||||
return tip;
|
||||
}
|
||||
|
||||
c = c->getParentComponent();
|
||||
}
|
||||
|
||||
return String::empty;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
FloatingLabelComponent::FloatingLabelComponent()
|
||||
: font (10.0f)
|
||||
{
|
||||
setInterceptsMouseClicks (false, false);
|
||||
}
|
||||
|
||||
void FloatingLabelComponent::remove()
|
||||
{
|
||||
if (getParentComponent() != 0)
|
||||
getParentComponent()->removeChildComponent (this);
|
||||
}
|
||||
|
||||
void FloatingLabelComponent::update (Component* parent, const String& text, const Colour& textColour, int x, int y, bool toRight, bool below)
|
||||
{
|
||||
colour = textColour;
|
||||
|
||||
Rectangle<int> r;
|
||||
|
||||
if (text != getName())
|
||||
{
|
||||
setName (text);
|
||||
glyphs.clear();
|
||||
glyphs.addJustifiedText (font, text, 0, 0, 200.0f, Justification::left);
|
||||
glyphs.justifyGlyphs (0, std::numeric_limits<int>::max(), 0, 0, 1000, 1000, Justification::topLeft);
|
||||
|
||||
r = glyphs.getBoundingBox (0, std::numeric_limits<int>::max(), false)
|
||||
.getSmallestIntegerContainer().expanded (1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = getLocalBounds();
|
||||
}
|
||||
|
||||
r.setPosition (x + (toRight ? 3 : -(r.getWidth() + 3)), y + (below ? 2 : -(r.getHeight() + 2)));
|
||||
setBounds (r);
|
||||
parent->addAndMakeVisible (this);
|
||||
}
|
||||
|
||||
void FloatingLabelComponent::paint (Graphics& g)
|
||||
{
|
||||
g.setFont (font);
|
||||
g.setColour (Colours::white.withAlpha (0.5f));
|
||||
g.fillRoundedRectangle (0, 0, (float) getWidth(), (float) getHeight(), 3);
|
||||
|
||||
g.setColour (colour);
|
||||
glyphs.draw (g, AffineTransform::translation (1.0f, 1.0f));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
RelativeRectangleLayoutManager::RelativeRectangleLayoutManager (Component* parentComponent)
|
||||
: parent (parentComponent)
|
||||
{
|
||||
parent->addComponentListener (this);
|
||||
}
|
||||
|
||||
RelativeRectangleLayoutManager::~RelativeRectangleLayoutManager()
|
||||
{
|
||||
parent->removeComponentListener (this);
|
||||
|
||||
for (int i = components.size(); --i >= 0;)
|
||||
components.getUnchecked(i)->component->removeComponentListener (this);
|
||||
}
|
||||
|
||||
void RelativeRectangleLayoutManager::setMarker (const String& name, const RelativeCoordinate& coord)
|
||||
{
|
||||
for (int i = markers.size(); --i >= 0;)
|
||||
{
|
||||
MarkerPosition* m = markers.getUnchecked(i);
|
||||
if (m->markerName == name)
|
||||
{
|
||||
m->position = coord;
|
||||
applyLayout();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
markers.add (new MarkerPosition (name, coord));
|
||||
applyLayout();
|
||||
}
|
||||
|
||||
void RelativeRectangleLayoutManager::setComponentBounds (Component* comp, const String& name, const RelativeRectangle& coords)
|
||||
{
|
||||
jassert (comp != 0);
|
||||
|
||||
// All the components that this layout manages must be inside the parent component..
|
||||
jassert (parent->isParentOf (comp));
|
||||
|
||||
for (int i = components.size(); --i >= 0;)
|
||||
{
|
||||
ComponentPosition* c = components.getUnchecked(i);
|
||||
if (c->component == comp)
|
||||
{
|
||||
c->name = name;
|
||||
c->coords = coords;
|
||||
triggerAsyncUpdate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
components.add (new ComponentPosition (comp, name, coords));
|
||||
comp->addComponentListener (this);
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
|
||||
void RelativeRectangleLayoutManager::applyLayout()
|
||||
{
|
||||
for (int i = components.size(); --i >= 0;)
|
||||
{
|
||||
ComponentPosition* c = components.getUnchecked(i);
|
||||
|
||||
// All the components that this layout manages must be inside the parent component..
|
||||
jassert (parent->isParentOf (c->component));
|
||||
|
||||
c->component->setBounds (c->coords.resolve (this).getSmallestIntegerContainer());
|
||||
}
|
||||
}
|
||||
|
||||
const RelativeCoordinate RelativeRectangleLayoutManager::findNamedCoordinate (const String& objectName, const String& edge) const
|
||||
{
|
||||
if (objectName == RelativeCoordinate::Strings::parent)
|
||||
{
|
||||
if (edge == RelativeCoordinate::Strings::right) return RelativeCoordinate ((double) parent->getWidth(), true);
|
||||
if (edge == RelativeCoordinate::Strings::bottom) return RelativeCoordinate ((double) parent->getHeight(), false);
|
||||
}
|
||||
|
||||
if (objectName.isNotEmpty() && edge.isNotEmpty())
|
||||
{
|
||||
for (int i = components.size(); --i >= 0;)
|
||||
{
|
||||
ComponentPosition* c = components.getUnchecked(i);
|
||||
|
||||
if (c->name == objectName)
|
||||
{
|
||||
if (edge == RelativeCoordinate::Strings::left) return c->coords.left;
|
||||
if (edge == RelativeCoordinate::Strings::right) return c->coords.right;
|
||||
if (edge == RelativeCoordinate::Strings::top) return c->coords.top;
|
||||
if (edge == RelativeCoordinate::Strings::bottom) return c->coords.bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = markers.size(); --i >= 0;)
|
||||
{
|
||||
MarkerPosition* m = markers.getUnchecked(i);
|
||||
|
||||
if (m->markerName == objectName)
|
||||
return m->position;
|
||||
}
|
||||
|
||||
return RelativeCoordinate();
|
||||
}
|
||||
|
||||
void RelativeRectangleLayoutManager::componentMovedOrResized (Component& component, bool wasMoved, bool wasResized)
|
||||
{
|
||||
triggerAsyncUpdate();
|
||||
|
||||
if (parent == &component)
|
||||
handleUpdateNowIfNeeded();
|
||||
}
|
||||
|
||||
void RelativeRectangleLayoutManager::componentBeingDeleted (Component& component)
|
||||
{
|
||||
for (int i = components.size(); --i >= 0;)
|
||||
{
|
||||
ComponentPosition* c = components.getUnchecked(i);
|
||||
if (c->component == &component)
|
||||
{
|
||||
components.remove (i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RelativeRectangleLayoutManager::handleAsyncUpdate()
|
||||
{
|
||||
applyLayout();
|
||||
}
|
||||
|
||||
RelativeRectangleLayoutManager::MarkerPosition::MarkerPosition (const String& name, const RelativeCoordinate& coord)
|
||||
: markerName (name), position (coord)
|
||||
{
|
||||
}
|
||||
|
||||
RelativeRectangleLayoutManager::ComponentPosition::ComponentPosition (Component* component_, const String& name_, const RelativeRectangle& coords_)
|
||||
: component (component_), name (name_), coords (coords_)
|
||||
{
|
||||
}
|
||||
207
extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.h
Normal file
207
extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.h
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// String::hashCode64 actually hit some dupes, so this is a more powerful version.
|
||||
const int64 hashCode64 (const String& s);
|
||||
const String randomHexString (Random& random, int numChars);
|
||||
const String hexString8Digits (int value);
|
||||
|
||||
const String createAlphaNumericUID();
|
||||
const String createGUID (const String& seed); // Turns a seed into a windows GUID
|
||||
|
||||
//==============================================================================
|
||||
int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex);
|
||||
|
||||
void autoScrollForMouseEvent (const MouseEvent& e, bool scrollX = true, bool scrollY = true);
|
||||
|
||||
void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text);
|
||||
void drawRecessedShadows (Graphics& g, int w, int h, int shadowSize);
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class PropertyPanelWithTooltips : public Component,
|
||||
public Timer
|
||||
{
|
||||
public:
|
||||
PropertyPanelWithTooltips();
|
||||
~PropertyPanelWithTooltips();
|
||||
|
||||
PropertyPanel* getPanel() const { return panel; }
|
||||
|
||||
void paint (Graphics& g);
|
||||
void resized();
|
||||
void timerCallback();
|
||||
|
||||
private:
|
||||
PropertyPanel* panel;
|
||||
TextLayout layout;
|
||||
Component* lastComp;
|
||||
String lastTip;
|
||||
|
||||
const String findTip (Component* c);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class FloatingLabelComponent : public Component
|
||||
{
|
||||
public:
|
||||
FloatingLabelComponent();
|
||||
|
||||
void remove();
|
||||
void update (Component* parent, const String& text, const Colour& textColour, int x, int y, bool toRight, bool below);
|
||||
void paint (Graphics& g);
|
||||
|
||||
private:
|
||||
Font font;
|
||||
Colour colour;
|
||||
GlyphArrangement glyphs;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class JucerToolbarButton : public ToolbarItemComponent
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
JucerToolbarButton (int itemId_, const String& labelText)
|
||||
: ToolbarItemComponent (itemId_, labelText, true)
|
||||
{
|
||||
setClickingTogglesState (false);
|
||||
}
|
||||
|
||||
~JucerToolbarButton()
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool getToolbarItemSizes (int toolbarDepth, bool isToolbarVertical, int& preferredSize, int& minSize, int& maxSize)
|
||||
{
|
||||
preferredSize = minSize = maxSize = 50;
|
||||
return true;
|
||||
}
|
||||
|
||||
void paintButton (Graphics& g, bool over, bool down)
|
||||
{
|
||||
Path p;
|
||||
p.addRoundedRectangle (1.5f, 2.5f, getWidth() - 3.0f, getHeight() - 5.0f, 3.0f);
|
||||
|
||||
if (getToggleState())
|
||||
{
|
||||
g.setColour (Colours::grey.withAlpha (0.5f));
|
||||
g.fillPath (p);
|
||||
}
|
||||
|
||||
g.setColour (Colours::darkgrey.withAlpha (0.3f));
|
||||
g.strokePath (p, PathStrokeType (1.0f));
|
||||
|
||||
g.setFont (11.0f);
|
||||
g.setColour (Colours::black.withAlpha ((over || down) ? 1.0f : 0.7f));
|
||||
g.drawFittedText (getButtonText(), 2, 2, getWidth() - 4, getHeight() - 4, Justification::centred, 2);
|
||||
}
|
||||
|
||||
void paintButtonArea (Graphics& g, int width, int height, bool isMouseOver, bool isMouseDown)
|
||||
{
|
||||
}
|
||||
|
||||
void contentAreaChanged (const Rectangle<int>& newBounds)
|
||||
{
|
||||
}
|
||||
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
JucerToolbarButton (const JucerToolbarButton&);
|
||||
JucerToolbarButton& operator= (const JucerToolbarButton&);
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
*/
|
||||
class RelativeRectangleLayoutManager : public ComponentListener,
|
||||
public RelativeCoordinate::NamedCoordinateFinder,
|
||||
public AsyncUpdater
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/**
|
||||
*/
|
||||
RelativeRectangleLayoutManager (Component* parentComponent);
|
||||
|
||||
/** Destructor. */
|
||||
~RelativeRectangleLayoutManager();
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
*/
|
||||
void setMarker (const String& name, const RelativeCoordinate& coord);
|
||||
|
||||
/**
|
||||
*/
|
||||
void setComponentBounds (Component* component, const String& componentName, const RelativeRectangle& bounds);
|
||||
|
||||
/**
|
||||
*/
|
||||
void applyLayout();
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
const RelativeCoordinate findNamedCoordinate (const String& objectName, const String& edge) const;
|
||||
/** @internal */
|
||||
void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized);
|
||||
/** @internal */
|
||||
void componentBeingDeleted (Component& component);
|
||||
/** @internal */
|
||||
void handleAsyncUpdate();
|
||||
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
struct ComponentPosition
|
||||
{
|
||||
ComponentPosition (Component* component, const String& name, const RelativeRectangle& coords);
|
||||
|
||||
Component* component;
|
||||
String name;
|
||||
RelativeRectangle coords;
|
||||
};
|
||||
|
||||
struct MarkerPosition
|
||||
{
|
||||
MarkerPosition (const String& name, const RelativeCoordinate& coord);
|
||||
|
||||
String markerName;
|
||||
RelativeCoordinate position;
|
||||
};
|
||||
|
||||
Component* parent;
|
||||
OwnedArray <ComponentPosition> components;
|
||||
OwnedArray <MarkerPosition> markers;
|
||||
|
||||
RelativeRectangleLayoutManager (const RelativeRectangleLayoutManager&);
|
||||
RelativeRectangleLayoutManager& operator= (const RelativeRectangleLayoutManager&);
|
||||
};
|
||||
109
extras/Jucer (experimental)/Source/Utility/jucer_PresetIDs.h
Normal file
109
extras/Jucer (experimental)/Source/Utility/jucer_PresetIDs.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCER_PRESETIDS_H_40E9E82E__
|
||||
#define __JUCER_PRESETIDS_H_40E9E82E__
|
||||
|
||||
|
||||
// Handy list of static Identifiers..
|
||||
namespace Ids
|
||||
{
|
||||
#define DECLARE_ID(name) const Identifier name (#name)
|
||||
|
||||
DECLARE_ID (text);
|
||||
DECLARE_ID (name);
|
||||
DECLARE_ID (file);
|
||||
DECLARE_ID (font);
|
||||
DECLARE_ID (mode);
|
||||
DECLARE_ID (type);
|
||||
DECLARE_ID (version);
|
||||
DECLARE_ID (position);
|
||||
DECLARE_ID (source);
|
||||
DECLARE_ID (readOnly);
|
||||
DECLARE_ID (editMode);
|
||||
DECLARE_ID (justification);
|
||||
DECLARE_ID (items);
|
||||
DECLARE_ID (editable);
|
||||
DECLARE_ID (textJustification);
|
||||
DECLARE_ID (unselectedText);
|
||||
DECLARE_ID (noItemsText);
|
||||
DECLARE_ID (min);
|
||||
DECLARE_ID (max);
|
||||
DECLARE_ID (width);
|
||||
DECLARE_ID (height);
|
||||
DECLARE_ID (background);
|
||||
DECLARE_ID (interval);
|
||||
DECLARE_ID (textBoxPos);
|
||||
DECLARE_ID (textBoxWidth);
|
||||
DECLARE_ID (textBoxHeight);
|
||||
DECLARE_ID (skew);
|
||||
DECLARE_ID (scrollBarV);
|
||||
DECLARE_ID (scrollBarH);
|
||||
DECLARE_ID (scrollbarWidth);
|
||||
DECLARE_ID (initialState);
|
||||
DECLARE_ID (scrollbarsShown);
|
||||
DECLARE_ID (caretVisible);
|
||||
DECLARE_ID (popupMenuEnabled);
|
||||
DECLARE_ID (radioGroup);
|
||||
DECLARE_ID (connectedLeft);
|
||||
DECLARE_ID (connectedRight);
|
||||
DECLARE_ID (connectedTop);
|
||||
DECLARE_ID (connectedBottom);
|
||||
DECLARE_ID (juceFolder);
|
||||
DECLARE_ID (targetFolder);
|
||||
DECLARE_ID (vstFolder);
|
||||
DECLARE_ID (rtasFolder);
|
||||
DECLARE_ID (auFolder);
|
||||
DECLARE_ID (extraCompilerFlags);
|
||||
DECLARE_ID (extraLinkerFlags);
|
||||
DECLARE_ID (extraDefs);
|
||||
DECLARE_ID (libraryName_Debug);
|
||||
DECLARE_ID (libraryName_Release);
|
||||
DECLARE_ID (libraryType);
|
||||
DECLARE_ID (isDebug);
|
||||
DECLARE_ID (targetName);
|
||||
DECLARE_ID (binaryPath);
|
||||
DECLARE_ID (optimisation);
|
||||
DECLARE_ID (defines);
|
||||
DECLARE_ID (headerPath);
|
||||
DECLARE_ID (osxSDK);
|
||||
DECLARE_ID (osxCompatibility);
|
||||
DECLARE_ID (jucerVersion);
|
||||
DECLARE_ID (projectType);
|
||||
DECLARE_ID (juceLinkage);
|
||||
DECLARE_ID (buildVST);
|
||||
DECLARE_ID (bundleIdentifier);
|
||||
DECLARE_ID (compile);
|
||||
DECLARE_ID (resource);
|
||||
DECLARE_ID (className);
|
||||
DECLARE_ID (classDesc);
|
||||
DECLARE_ID (controlPoint);
|
||||
const Identifier class_ ("class");
|
||||
const Identifier id_ ("id");
|
||||
|
||||
#undef DECLARE_ID
|
||||
}
|
||||
|
||||
#endif // __JUCER_PRESETIDS_H_40E9E82E__
|
||||
126
extras/Jucer (experimental)/Source/Utility/jucer_RelativePath.h
Normal file
126
extras/Jucer (experimental)/Source/Utility/jucer_RelativePath.h
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCER_RELATIVEPATH_JUCEHEADER__
|
||||
#define __JUCER_RELATIVEPATH_JUCEHEADER__
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** Manipulates a cross-platform partial file path. (Needed because File is designed
|
||||
for absolute paths on the active OS)
|
||||
*/
|
||||
class RelativePath
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
enum RootFolder
|
||||
{
|
||||
unknown,
|
||||
projectFolder,
|
||||
buildTargetFolder
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
RelativePath()
|
||||
: root (unknown)
|
||||
{}
|
||||
|
||||
RelativePath (const String& path_, const RootFolder root_)
|
||||
: path (path_), root (root_)
|
||||
{
|
||||
}
|
||||
|
||||
RelativePath (const File& file, const File& rootFolder, const RootFolder root_)
|
||||
: path (file.getRelativePathFrom (rootFolder)), root (root_)
|
||||
{
|
||||
}
|
||||
|
||||
RootFolder getRoot() const { return root; }
|
||||
|
||||
const String toUnixStyle() const { return FileHelpers::unixStylePath (path); }
|
||||
const String toWindowsStyle() const { return FileHelpers::windowsStylePath (path); }
|
||||
|
||||
const String getFileName() const { return getFakeFile().getFileName(); }
|
||||
const String getFileNameWithoutExtension() const { return getFakeFile().getFileNameWithoutExtension(); }
|
||||
|
||||
const String getFileExtension() const { return getFakeFile().getFileExtension(); }
|
||||
bool hasFileExtension (const String& extension) const { return getFakeFile().hasFileExtension (extension); }
|
||||
bool isAbsolute() const { return isAbsolute (path); }
|
||||
|
||||
const RelativePath withFileExtension (const String& extension) const
|
||||
{
|
||||
return RelativePath (path.upToLastOccurrenceOf (".", ! extension.startsWithChar ('.'), false) + extension, root);
|
||||
}
|
||||
|
||||
const RelativePath getParentDirectory() const
|
||||
{
|
||||
String p (path);
|
||||
if (path.endsWithChar ('/'))
|
||||
p = p.dropLastCharacters (1);
|
||||
|
||||
return RelativePath (p.upToLastOccurrenceOf ("/", false, false), root);
|
||||
}
|
||||
|
||||
const RelativePath getChildFile (const String& subpath) const
|
||||
{
|
||||
if (isAbsolute (subpath))
|
||||
return RelativePath (subpath, root);
|
||||
|
||||
String p (toUnixStyle());
|
||||
if (! p.endsWithChar ('/'))
|
||||
p << '/';
|
||||
|
||||
return RelativePath (p + subpath, root);
|
||||
}
|
||||
|
||||
const RelativePath rebased (const File& originalRoot, const File& newRoot, const RootFolder newRootType) const
|
||||
{
|
||||
if (isAbsolute())
|
||||
return RelativePath (path, newRootType);
|
||||
|
||||
return RelativePath (originalRoot.getChildFile (toUnixStyle()).getRelativePathFrom (newRoot), newRootType);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
String path;
|
||||
RootFolder root;
|
||||
|
||||
const File getFakeFile() const
|
||||
{
|
||||
return File::getCurrentWorkingDirectory().getChildFile (path);
|
||||
}
|
||||
|
||||
static bool isAbsolute (const String& path)
|
||||
{
|
||||
return File::isAbsolutePath (path)
|
||||
|| path.startsWithChar ('$')
|
||||
|| path.startsWithChar ('~')
|
||||
|| (CharacterFunctions::isLetter (path[0]) && path[1] == ':');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCER_RELATIVEPATH_JUCEHEADER__
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "../jucer_Headers.h"
|
||||
#include "jucer_StoredSettings.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
StoredSettings::StoredSettings()
|
||||
: props (0)
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
StoredSettings::~StoredSettings()
|
||||
{
|
||||
flush();
|
||||
props = 0;
|
||||
clearSingletonInstance();
|
||||
}
|
||||
|
||||
juce_ImplementSingleton (StoredSettings);
|
||||
|
||||
|
||||
//==============================================================================
|
||||
PropertiesFile& StoredSettings::getProps()
|
||||
{
|
||||
jassert (props != 0);
|
||||
return *props;
|
||||
}
|
||||
|
||||
void StoredSettings::flush()
|
||||
{
|
||||
if (props != 0)
|
||||
{
|
||||
props->setValue ("recentFiles", recentFiles.toString());
|
||||
|
||||
props->removeValue ("keyMappings");
|
||||
|
||||
if (commandManager != 0)
|
||||
{
|
||||
ScopedPointer <XmlElement> keys (commandManager->getKeyMappings()->createXml (true));
|
||||
|
||||
if (keys != 0)
|
||||
props->setValue ("keyMappings", (XmlElement*) keys);
|
||||
}
|
||||
}
|
||||
|
||||
props = 0;
|
||||
props = PropertiesFile::createDefaultAppPropertiesFile ("Jucer2",
|
||||
"settings",
|
||||
String::empty,
|
||||
false, 3000,
|
||||
PropertiesFile::storeAsXML);
|
||||
|
||||
// recent files...
|
||||
recentFiles.restoreFromString (props->getValue ("recentFiles"));
|
||||
recentFiles.removeNonExistentFiles();
|
||||
|
||||
// swatch colours...
|
||||
swatchColours.clear();
|
||||
|
||||
#define COL(col) Colours::col,
|
||||
|
||||
const Colour colours[] =
|
||||
{
|
||||
#include "jucer_Colours.h"
|
||||
Colours::transparentBlack
|
||||
};
|
||||
|
||||
#undef COL
|
||||
|
||||
const int numSwatchColours = 24;
|
||||
|
||||
for (int i = 0; i < numSwatchColours; ++i)
|
||||
{
|
||||
Colour defaultCol (colours [2 + i]);
|
||||
swatchColours.add (Colour (props->getValue ("swatchColour" + String (i),
|
||||
hexString8Digits (defaultCol.getARGB())).getHexValue32()));
|
||||
}
|
||||
}
|
||||
|
||||
const File StoredSettings::getLastProject() const
|
||||
{
|
||||
return props->getValue ("lastProject");
|
||||
}
|
||||
|
||||
void StoredSettings::setLastProject (const File& file)
|
||||
{
|
||||
props->setValue ("lastProject", file.getFullPathName());
|
||||
}
|
||||
|
||||
const File StoredSettings::getLastKnownJuceFolder() const
|
||||
{
|
||||
File defaultJuceFolder (FileHelpers::findDefaultJuceFolder());
|
||||
File f (props->getValue ("lastJuceFolder", defaultJuceFolder.getFullPathName()));
|
||||
|
||||
if ((! FileHelpers::isJuceFolder (f)) && FileHelpers::isJuceFolder (defaultJuceFolder))
|
||||
f = defaultJuceFolder;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
void StoredSettings::setLastKnownJuceFolder (const File& file)
|
||||
{
|
||||
jassert (FileHelpers::isJuceFolder (file));
|
||||
props->setValue ("lastJuceFolder", file.getFullPathName());
|
||||
}
|
||||
|
||||
const StringArray& StoredSettings::getFontNames()
|
||||
{
|
||||
if (fontNames.size() == 0)
|
||||
fontNames = Font::findAllTypefaceNames();
|
||||
|
||||
return fontNames;
|
||||
}
|
||||
|
||||
const Image StoredSettings::getFallbackImage()
|
||||
{
|
||||
if (fallbackImage.isNull())
|
||||
fallbackImage = ImageFileFormat::loadFrom (BinaryData::juce_icon_png, BinaryData::juce_icon_pngSize);
|
||||
|
||||
return fallbackImage;
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCER_STOREDSETTINGS_JUCEHEADER__
|
||||
#define __JUCER_STOREDSETTINGS_JUCEHEADER__
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A singleton to hold the jucer's persistent settings, and to save them in a
|
||||
suitable PropertiesFile.
|
||||
*/
|
||||
class StoredSettings
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
StoredSettings();
|
||||
~StoredSettings();
|
||||
|
||||
juce_DeclareSingleton (StoredSettings, false);
|
||||
|
||||
PropertiesFile& getProps();
|
||||
void flush();
|
||||
|
||||
//==============================================================================
|
||||
RecentlyOpenedFilesList recentFiles;
|
||||
|
||||
const File getLastProject() const;
|
||||
void setLastProject (const File& file);
|
||||
|
||||
const File getLastKnownJuceFolder() const;
|
||||
void setLastKnownJuceFolder (const File& file);
|
||||
|
||||
const StringArray& getFontNames();
|
||||
|
||||
//==============================================================================
|
||||
Array <Colour> swatchColours;
|
||||
|
||||
class ColourSelectorWithSwatches : public ColourSelector
|
||||
{
|
||||
public:
|
||||
ColourSelectorWithSwatches() {}
|
||||
|
||||
int getNumSwatches() const { return StoredSettings::getInstance()->swatchColours.size(); }
|
||||
const Colour getSwatchColour (int index) const { return StoredSettings::getInstance()->swatchColours [index]; }
|
||||
void setSwatchColour (int index, const Colour& newColour) const { StoredSettings::getInstance()->swatchColours.set (index, newColour); }
|
||||
};
|
||||
|
||||
|
||||
const Image getFallbackImage();
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
ScopedPointer<PropertiesFile> props;
|
||||
StringArray fontNames;
|
||||
|
||||
Image fallbackImage;
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCER_STOREDSETTINGS_JUCEHEADER__
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-10 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online at www.gnu.org/licenses.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To release a closed-source product which uses JUCE, commercial licenses are
|
||||
available: visit www.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifndef __JUCER_VALUEREMAPPERSOURCE_JUCEHEADER__
|
||||
#define __JUCER_VALUEREMAPPERSOURCE_JUCEHEADER__
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
*/
|
||||
template <typename Type>
|
||||
class NumericValueSource : public Value::ValueSource,
|
||||
public Value::Listener
|
||||
{
|
||||
public:
|
||||
NumericValueSource (const Value& sourceValue_)
|
||||
: sourceValue (sourceValue_)
|
||||
{
|
||||
sourceValue.addListener (this);
|
||||
}
|
||||
|
||||
~NumericValueSource() {}
|
||||
|
||||
void valueChanged (Value&) { sendChangeMessage (true); }
|
||||
const var getValue() const { return (Type) sourceValue.getValue(); }
|
||||
|
||||
void setValue (const var& newValue)
|
||||
{
|
||||
const Type newVal = (Type) newValue;
|
||||
|
||||
if (newVal != (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_UseDebuggingNewOperator
|
||||
|
||||
protected:
|
||||
Value sourceValue;
|
||||
|
||||
NumericValueSource (const NumericValueSource&);
|
||||
const NumericValueSource& operator= (const NumericValueSource&);
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCER_VALUEREMAPPERSOURCE_JUCEHEADER__
|
||||
Loading…
Add table
Add a link
Reference in a new issue