diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_CodeHelpers.cpp b/extras/Jucer (experimental)/Source/Utility/jucer_CodeHelpers.cpp new file mode 100644 index 0000000000..be0afcc5c3 --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_CodeHelpers.cpp @@ -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 + 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 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; + } +} diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_CodeHelpers.h b/extras/Jucer (experimental)/Source/Utility/jucer_CodeHelpers.h new file mode 100644 index 0000000000..91965b815a --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_CodeHelpers.h @@ -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__ diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_Colours.h b/extras/Jucer (experimental)/Source/Utility/jucer_Colours.h new file mode 100644 index 0000000000..e2a75ba8c0 --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_Colours.h @@ -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) diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_FileHelpers.cpp b/extras/Jucer (experimental)/Source/Utility/jucer_FileHelpers.cpp new file mode 100644 index 0000000000..5aebac4fc3 --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_FileHelpers.cpp @@ -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 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 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; + } +} diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_FileHelpers.h b/extras/Jucer (experimental)/Source/Utility/jucer_FileHelpers.h new file mode 100644 index 0000000000..dd19d66aa3 --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_FileHelpers.h @@ -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__ diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_JucerTreeViewBase.cpp b/extras/Jucer (experimental)/Source/Utility/jucer_JucerTreeViewBase.cpp new file mode 100644 index 0000000000..66c5f2030a --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_JucerTreeViewBase.cpp @@ -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 r (getItemPosition (true)); + r.setLeft (r.getX() + getTextX()); + r.setHeight (getItemHeight()); + ed.setBounds (r); + getOwnerView()->addAndMakeVisible (&ed); + + if (ed.runModalLoop() != 0) + setName (ed.getText()); +} diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_JucerTreeViewBase.h b/extras/Jucer (experimental)/Source/Utility/jucer_JucerTreeViewBase.h new file mode 100644 index 0000000000..2a70435ed3 --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_JucerTreeViewBase.h @@ -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__ diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.cpp b/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.cpp new file mode 100644 index 0000000000..ddc254e6d6 --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.cpp @@ -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 (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 r; + + if (text != getName()) + { + setName (text); + glyphs.clear(); + glyphs.addJustifiedText (font, text, 0, 0, 200.0f, Justification::left); + glyphs.justifyGlyphs (0, std::numeric_limits::max(), 0, 0, 1000, 1000, Justification::topLeft); + + r = glyphs.getBoundingBox (0, std::numeric_limits::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_) +{ +} diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.h b/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.h new file mode 100644 index 0000000000..b537343935 --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.h @@ -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& 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 components; + OwnedArray markers; + + RelativeRectangleLayoutManager (const RelativeRectangleLayoutManager&); + RelativeRectangleLayoutManager& operator= (const RelativeRectangleLayoutManager&); +}; diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_PresetIDs.h b/extras/Jucer (experimental)/Source/Utility/jucer_PresetIDs.h new file mode 100644 index 0000000000..97b056b271 --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_PresetIDs.h @@ -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__ diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_RelativePath.h b/extras/Jucer (experimental)/Source/Utility/jucer_RelativePath.h new file mode 100644 index 0000000000..100754efe3 --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_RelativePath.h @@ -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__ diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_StoredSettings.cpp b/extras/Jucer (experimental)/Source/Utility/jucer_StoredSettings.cpp new file mode 100644 index 0000000000..cd3cef758c --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_StoredSettings.cpp @@ -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 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; +} diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_StoredSettings.h b/extras/Jucer (experimental)/Source/Utility/jucer_StoredSettings.h new file mode 100644 index 0000000000..ff8dfb09e8 --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_StoredSettings.h @@ -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 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 props; + StringArray fontNames; + + Image fallbackImage; +}; + + +#endif // __JUCER_STOREDSETTINGS_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_ValueSourceHelpers.h b/extras/Jucer (experimental)/Source/Utility/jucer_ValueSourceHelpers.h new file mode 100644 index 0000000000..e3e55b099c --- /dev/null +++ b/extras/Jucer (experimental)/Source/Utility/jucer_ValueSourceHelpers.h @@ -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 +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__