@@ -333,11 +333,8 @@ void RelativeRectangleLayoutManager::applyLayout() | |||||
} | } | ||||
} | } | ||||
const Expression RelativeRectangleLayoutManager::getSymbolValue (const String& symbol) const | |||||
const Expression RelativeRectangleLayoutManager::getSymbolValue (const String& objectName, const String& edge) const | |||||
{ | { | ||||
const String objectName (symbol.upToFirstOccurrenceOf (".", false, false).trim()); | |||||
const String edge (symbol.fromFirstOccurrenceOf (".", false, false).trim()); | |||||
if (objectName == RelativeCoordinate::Strings::parent) | if (objectName == RelativeCoordinate::Strings::parent) | ||||
{ | { | ||||
if (edge == RelativeCoordinate::Strings::right) return Expression ((double) parent->getWidth()); | if (edge == RelativeCoordinate::Strings::right) return Expression ((double) parent->getWidth()); | ||||
@@ -169,7 +169,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
/** @internal */ | /** @internal */ | ||||
const Expression getSymbolValue (const String& symbol) const; | |||||
const Expression getSymbolValue (const String& symbol, const String& member) const; | |||||
/** @internal */ | /** @internal */ | ||||
void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized); | void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized); | ||||
/** @internal */ | /** @internal */ | ||||
@@ -4632,7 +4632,15 @@ public: | |||||
class Symbol : public Term | class Symbol : public Term | ||||
{ | { | ||||
public: | public: | ||||
Symbol (const String& symbol_) : symbol (symbol_) {} | |||||
explicit Symbol (const String& symbol_) | |||||
: mainSymbol (symbol_.upToFirstOccurrenceOf (".", false, false).trim()), | |||||
member (symbol_.fromFirstOccurrenceOf (".", false, false).trim()) | |||||
{} | |||||
Symbol (const String& symbol_, const String& member_) | |||||
: mainSymbol (symbol_), | |||||
member (member_) | |||||
{} | |||||
double evaluate (const EvaluationContext& c, int recursionDepth) const | double evaluate (const EvaluationContext& c, int recursionDepth) const | ||||
{ | { | ||||
@@ -4641,7 +4649,7 @@ public: | |||||
try | try | ||||
{ | { | ||||
return c.getSymbolValue (symbol).term->evaluate (c, recursionDepth); | |||||
return c.getSymbolValue (mainSymbol, member).term->evaluate (c, recursionDepth); | |||||
} | } | ||||
catch (...) | catch (...) | ||||
{} | {} | ||||
@@ -4649,23 +4657,35 @@ public: | |||||
return 0; | return 0; | ||||
} | } | ||||
Term* clone() const { return new Symbol (symbol); } | |||||
Term* clone() const { return new Symbol (mainSymbol, member); } | |||||
int getNumInputs() const { return 0; } | int getNumInputs() const { return 0; } | ||||
Term* getInput (int) const { return 0; } | Term* getInput (int) const { return 0; } | ||||
const String toString() const { return symbol; } | |||||
const String toString() const | |||||
{ | |||||
return member.isEmpty() ? mainSymbol | |||||
: mainSymbol + "." + member; | |||||
} | |||||
bool referencesSymbol (const String& s, const EvaluationContext& c, int recursionDepth) const | bool referencesSymbol (const String& s, const EvaluationContext& c, int recursionDepth) const | ||||
{ | { | ||||
if (s == symbol) | |||||
if (s == mainSymbol) | |||||
return true; | return true; | ||||
if (++recursionDepth > 256) | if (++recursionDepth > 256) | ||||
throw EvaluationError ("Recursive symbol references"); | throw EvaluationError ("Recursive symbol references"); | ||||
return c.getSymbolValue (symbol).term->referencesSymbol (s, c, recursionDepth); | |||||
try | |||||
{ | |||||
return c.getSymbolValue (mainSymbol, member).term->referencesSymbol (s, c, recursionDepth); | |||||
} | |||||
catch (EvaluationError&) | |||||
{ | |||||
return false; | |||||
} | |||||
} | } | ||||
String symbol; | |||||
String mainSymbol, member; | |||||
}; | }; | ||||
class Function : public Term | class Function : public Term | ||||
@@ -4937,6 +4957,9 @@ public: | |||||
if (c != 0 && (c->isResolutionTarget || ! mustBeFlagged)) | if (c != 0 && (c->isResolutionTarget || ! mustBeFlagged)) | ||||
return c; | return c; | ||||
if (dynamic_cast<Function*> (term) != 0) | |||||
return 0; | |||||
int i; | int i; | ||||
const int numIns = term->getNumInputs(); | const int numIns = term->getNumInputs(); | ||||
for (i = 0; i < numIns; ++i) | for (i = 0; i < numIns; ++i) | ||||
@@ -4970,20 +4993,12 @@ public: | |||||
static bool renameSymbol (Term* const t, const String& oldName, const String& newName) | static bool renameSymbol (Term* const t, const String& oldName, const String& newName) | ||||
{ | { | ||||
Symbol* sym = dynamic_cast <Symbol*> (t); | |||||
Symbol* const sym = dynamic_cast <Symbol*> (t); | |||||
if (sym != 0) | |||||
if (sym != 0 && sym->mainSymbol == oldName) | |||||
{ | { | ||||
if (sym->symbol == oldName) | |||||
{ | |||||
sym->symbol = newName; | |||||
return true; | |||||
} | |||||
else if (sym->symbol.startsWith (oldName + ".")) | |||||
{ | |||||
sym->symbol = newName + "." + sym->symbol.substring (0, oldName.length() + 1); | |||||
return true; | |||||
} | |||||
sym->mainSymbol = newName; | |||||
return true; | |||||
} | } | ||||
bool anyChanged = false; | bool anyChanged = false; | ||||
@@ -5109,6 +5124,12 @@ public: | |||||
textIndex = i; | textIndex = i; | ||||
} | } | ||||
if (text[i] == '-') | |||||
{ | |||||
++i; | |||||
skipWhitespace (i); | |||||
} | |||||
int numDigits = 0; | int numDigits = 0; | ||||
while (isDecimalDigit (text[i])) | while (isDecimalDigit (text[i])) | ||||
@@ -5154,9 +5175,9 @@ public: | |||||
return 0; | return 0; | ||||
} | } | ||||
Constant* t = new Constant (String (text + textIndex, i - textIndex).getDoubleValue(), isResolutionTarget); | |||||
const int start = textIndex; | |||||
textIndex = i; | textIndex = i; | ||||
return t; | |||||
return new Constant (String (text + start, i - start).getDoubleValue(), isResolutionTarget); | |||||
} | } | ||||
const TermPtr readMultiplyOrDivideExpression() | const TermPtr readMultiplyOrDivideExpression() | ||||
@@ -5386,7 +5407,7 @@ const Expression Expression::adjustedToGiveNewResult (const double targetValue, | |||||
const Helpers::TermPtr reverseTerm (parent->createTermToEvaluateInput (context, termToAdjust, targetValue, newTerm)); | const Helpers::TermPtr reverseTerm (parent->createTermToEvaluateInput (context, termToAdjust, targetValue, newTerm)); | ||||
if (reverseTerm == 0) | if (reverseTerm == 0) | ||||
return Expression(); | |||||
return Expression (targetValue); | |||||
termToAdjust->value = reverseTerm->evaluate (context, 0); | termToAdjust->value = reverseTerm->evaluate (context, 0); | ||||
} | } | ||||
@@ -5396,7 +5417,7 @@ const Expression Expression::adjustedToGiveNewResult (const double targetValue, | |||||
const Expression Expression::withRenamedSymbol (const String& oldSymbol, const String& newSymbol) const | const Expression Expression::withRenamedSymbol (const String& oldSymbol, const String& newSymbol) const | ||||
{ | { | ||||
jassert (newSymbol.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); | |||||
jassert (newSymbol.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_")); | |||||
Expression newExpression (term->clone()); | Expression newExpression (term->clone()); | ||||
Helpers::renameSymbol (newExpression.term, oldSymbol, newSymbol); | Helpers::renameSymbol (newExpression.term, oldSymbol, newSymbol); | ||||
@@ -5454,9 +5475,9 @@ Expression::EvaluationError::EvaluationError (const String& message) | |||||
Expression::EvaluationContext::EvaluationContext() {} | Expression::EvaluationContext::EvaluationContext() {} | ||||
Expression::EvaluationContext::~EvaluationContext() {} | Expression::EvaluationContext::~EvaluationContext() {} | ||||
const Expression Expression::EvaluationContext::getSymbolValue (const String& symbol) const | |||||
const Expression Expression::EvaluationContext::getSymbolValue (const String& symbol, const String& member) const | |||||
{ | { | ||||
throw EvaluationError ("Unknown symbol: \"" + symbol + "\""); | |||||
throw EvaluationError ("Unknown symbol: \"" + symbol + (member.isEmpty() ? "\"" : ("." + member + "\""))); | |||||
} | } | ||||
double Expression::EvaluationContext::evaluateFunction (const String& functionName, const double* parameters, int numParams) const | double Expression::EvaluationContext::evaluateFunction (const String& functionName, const double* parameters, int numParams) const | ||||
@@ -19550,8 +19571,6 @@ FileBasedDocument::SaveResult FileBasedDocument::saveAsInteractive (const bool w | |||||
if (fc.browseForFileToSave (warnAboutOverwritingExistingFiles)) | if (fc.browseForFileToSave (warnAboutOverwritingExistingFiles)) | ||||
{ | { | ||||
setLastDocumentOpened (fc.getResult()); | |||||
File chosen (fc.getResult()); | File chosen (fc.getResult()); | ||||
if (chosen.getFileExtension().isEmpty()) | if (chosen.getFileExtension().isEmpty()) | ||||
{ | { | ||||
@@ -19572,6 +19591,7 @@ FileBasedDocument::SaveResult FileBasedDocument::saveAsInteractive (const bool w | |||||
} | } | ||||
} | } | ||||
setLastDocumentOpened (chosen); | |||||
return saveAs (chosen, false, false, true); | return saveAs (chosen, false, false, true); | ||||
} | } | ||||
@@ -57322,6 +57342,17 @@ void TreeViewItem::paintRecursively (Graphics& g, int width) | |||||
const int indent = getIndentX(); | const int indent = getIndentX(); | ||||
const int itemW = itemWidth < 0 ? width - indent : itemWidth; | const int itemW = itemWidth < 0 ? width - indent : itemWidth; | ||||
{ | |||||
g.saveState(); | |||||
g.setOrigin (indent, 0); | |||||
if (g.reduceClipRegion (drawsInLeftMargin ? -indent : 0, 0, | |||||
drawsInLeftMargin ? itemW + indent : itemW, itemHeight)) | |||||
paintItem (g, itemW, itemHeight); | |||||
g.restoreState(); | |||||
} | |||||
g.setColour (ownerView->findColour (TreeView::linesColourId)); | g.setColour (ownerView->findColour (TreeView::linesColourId)); | ||||
const float halfH = itemHeight * 0.5f; | const float halfH = itemHeight * 0.5f; | ||||
@@ -57383,17 +57414,6 @@ void TreeViewItem::paintRecursively (Graphics& g, int width) | |||||
} | } | ||||
} | } | ||||
{ | |||||
g.saveState(); | |||||
g.setOrigin (indent, 0); | |||||
if (g.reduceClipRegion (drawsInLeftMargin ? -indent : 0, 0, | |||||
drawsInLeftMargin ? itemW + indent : itemW, itemHeight)) | |||||
paintItem (g, itemW, itemHeight); | |||||
g.restoreState(); | |||||
} | |||||
if (isOpen()) | if (isOpen()) | ||||
{ | { | ||||
const Rectangle<int> clip (g.getClipBounds()); | const Rectangle<int> clip (g.getClipBounds()); | ||||
@@ -79785,7 +79805,7 @@ const String RelativeCoordinate::toString() const | |||||
void RelativeCoordinate::renameSymbolIfUsed (const String& oldName, const String& newName, | void RelativeCoordinate::renameSymbolIfUsed (const String& oldName, const String& newName, | ||||
const Expression::EvaluationContext* context) | const Expression::EvaluationContext* context) | ||||
{ | { | ||||
jassert (newName.isNotEmpty() && newName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); | |||||
jassert (newName.isNotEmpty() && newName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_")); | |||||
if (term.referencesSymbol (oldName, *context)) | if (term.referencesSymbol (oldName, *context)) | ||||
{ | { | ||||
@@ -86144,9 +86164,9 @@ void DrawableComposite::render (const Drawable::RenderingContext& context) const | |||||
} | } | ||||
} | } | ||||
const Expression DrawableComposite::getSymbolValue (const String& symbol) const | |||||
const Expression DrawableComposite::getSymbolValue (const String& symbol, const String& member) const | |||||
{ | { | ||||
jassert (! symbol.containsChar ('.')) // the only symbols available in a Drawable are markers. | |||||
jassert (member.isEmpty()) // the only symbols available in a Drawable are markers. | |||||
int i; | int i; | ||||
for (i = 0; i < markersX.size(); ++i) | for (i = 0; i < markersX.size(); ++i) | ||||
@@ -86163,7 +86183,7 @@ const Expression DrawableComposite::getSymbolValue (const String& symbol) const | |||||
return m->position.getExpression(); | return m->position.getExpression(); | ||||
} | } | ||||
return Expression::EvaluationContext::getSymbolValue (symbol); | |||||
return Expression::EvaluationContext::getSymbolValue (symbol, member); | |||||
} | } | ||||
const Rectangle<float> DrawableComposite::getUntransformedBounds (const bool includeMarkers) const | const Rectangle<float> DrawableComposite::getUntransformedBounds (const bool includeMarkers) const | ||||
@@ -64,7 +64,7 @@ | |||||
*/ | */ | ||||
#define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
#define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
#define JUCE_BUILDNUMBER 53 | |||||
#define JUCE_BUILDNUMBER 54 | |||||
/** Current Juce version number. | /** Current Juce version number. | ||||
@@ -6630,9 +6630,11 @@ public: | |||||
/** Returns the value of a symbol. | /** Returns the value of a symbol. | ||||
If the symbol is unknown, this can throw an Expression::EvaluationError exception. | If the symbol is unknown, this can throw an Expression::EvaluationError exception. | ||||
The member value is set to the part of the symbol that followed the dot, if there is | |||||
one, e.g. for "foo.bar", symbol = "foo" and member = "bar". | |||||
@throws Expression::EvaluationError | @throws Expression::EvaluationError | ||||
*/ | */ | ||||
virtual const Expression getSymbolValue (const String& symbol) const; | |||||
virtual const Expression getSymbolValue (const String& symbol, const String& member) const; | |||||
/** Executes a named function. | /** Executes a named function. | ||||
If the function name is unknown, this can throw an Expression::EvaluationError exception. | If the function name is unknown, this can throw an Expression::EvaluationError exception. | ||||
@@ -59306,7 +59308,7 @@ public: | |||||
/** @internal */ | /** @internal */ | ||||
const Identifier getValueTreeType() const { return valueTreeType; } | const Identifier getValueTreeType() const { return valueTreeType; } | ||||
/** @internal */ | /** @internal */ | ||||
const Expression getSymbolValue (const String& symbol) const; | |||||
const Expression getSymbolValue (const String& symbol, const String& member) const; | |||||
/** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */ | /** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */ | ||||
class ValueTreeWrapper : public ValueTreeWrapperBase | class ValueTreeWrapper : public ValueTreeWrapperBase | ||||
@@ -70,7 +70,15 @@ public: | |||||
class Symbol : public Term | class Symbol : public Term | ||||
{ | { | ||||
public: | public: | ||||
Symbol (const String& symbol_) : symbol (symbol_) {} | |||||
explicit Symbol (const String& symbol_) | |||||
: mainSymbol (symbol_.upToFirstOccurrenceOf (".", false, false).trim()), | |||||
member (symbol_.fromFirstOccurrenceOf (".", false, false).trim()) | |||||
{} | |||||
Symbol (const String& symbol_, const String& member_) | |||||
: mainSymbol (symbol_), | |||||
member (member_) | |||||
{} | |||||
double evaluate (const EvaluationContext& c, int recursionDepth) const | double evaluate (const EvaluationContext& c, int recursionDepth) const | ||||
{ | { | ||||
@@ -79,7 +87,7 @@ public: | |||||
try | try | ||||
{ | { | ||||
return c.getSymbolValue (symbol).term->evaluate (c, recursionDepth); | |||||
return c.getSymbolValue (mainSymbol, member).term->evaluate (c, recursionDepth); | |||||
} | } | ||||
catch (...) | catch (...) | ||||
{} | {} | ||||
@@ -87,23 +95,35 @@ public: | |||||
return 0; | return 0; | ||||
} | } | ||||
Term* clone() const { return new Symbol (symbol); } | |||||
Term* clone() const { return new Symbol (mainSymbol, member); } | |||||
int getNumInputs() const { return 0; } | int getNumInputs() const { return 0; } | ||||
Term* getInput (int) const { return 0; } | Term* getInput (int) const { return 0; } | ||||
const String toString() const { return symbol; } | |||||
const String toString() const | |||||
{ | |||||
return member.isEmpty() ? mainSymbol | |||||
: mainSymbol + "." + member; | |||||
} | |||||
bool referencesSymbol (const String& s, const EvaluationContext& c, int recursionDepth) const | bool referencesSymbol (const String& s, const EvaluationContext& c, int recursionDepth) const | ||||
{ | { | ||||
if (s == symbol) | |||||
if (s == mainSymbol) | |||||
return true; | return true; | ||||
if (++recursionDepth > 256) | if (++recursionDepth > 256) | ||||
throw EvaluationError ("Recursive symbol references"); | throw EvaluationError ("Recursive symbol references"); | ||||
return c.getSymbolValue (symbol).term->referencesSymbol (s, c, recursionDepth); | |||||
try | |||||
{ | |||||
return c.getSymbolValue (mainSymbol, member).term->referencesSymbol (s, c, recursionDepth); | |||||
} | |||||
catch (EvaluationError&) | |||||
{ | |||||
return false; | |||||
} | |||||
} | } | ||||
String symbol; | |||||
String mainSymbol, member; | |||||
}; | }; | ||||
//============================================================================== | //============================================================================== | ||||
@@ -383,6 +403,9 @@ public: | |||||
if (c != 0 && (c->isResolutionTarget || ! mustBeFlagged)) | if (c != 0 && (c->isResolutionTarget || ! mustBeFlagged)) | ||||
return c; | return c; | ||||
if (dynamic_cast<Function*> (term) != 0) | |||||
return 0; | |||||
int i; | int i; | ||||
const int numIns = term->getNumInputs(); | const int numIns = term->getNumInputs(); | ||||
for (i = 0; i < numIns; ++i) | for (i = 0; i < numIns; ++i) | ||||
@@ -416,20 +439,12 @@ public: | |||||
static bool renameSymbol (Term* const t, const String& oldName, const String& newName) | static bool renameSymbol (Term* const t, const String& oldName, const String& newName) | ||||
{ | { | ||||
Symbol* sym = dynamic_cast <Symbol*> (t); | |||||
Symbol* const sym = dynamic_cast <Symbol*> (t); | |||||
if (sym != 0) | |||||
if (sym != 0 && sym->mainSymbol == oldName) | |||||
{ | { | ||||
if (sym->symbol == oldName) | |||||
{ | |||||
sym->symbol = newName; | |||||
return true; | |||||
} | |||||
else if (sym->symbol.startsWith (oldName + ".")) | |||||
{ | |||||
sym->symbol = newName + "." + sym->symbol.substring (0, oldName.length() + 1); | |||||
return true; | |||||
} | |||||
sym->mainSymbol = newName; | |||||
return true; | |||||
} | } | ||||
bool anyChanged = false; | bool anyChanged = false; | ||||
@@ -557,6 +572,12 @@ public: | |||||
textIndex = i; | textIndex = i; | ||||
} | } | ||||
if (text[i] == '-') | |||||
{ | |||||
++i; | |||||
skipWhitespace (i); | |||||
} | |||||
int numDigits = 0; | int numDigits = 0; | ||||
while (isDecimalDigit (text[i])) | while (isDecimalDigit (text[i])) | ||||
@@ -602,9 +623,9 @@ public: | |||||
return 0; | return 0; | ||||
} | } | ||||
Constant* t = new Constant (String (text + textIndex, i - textIndex).getDoubleValue(), isResolutionTarget); | |||||
const int start = textIndex; | |||||
textIndex = i; | textIndex = i; | ||||
return t; | |||||
return new Constant (String (text + start, i - start).getDoubleValue(), isResolutionTarget); | |||||
} | } | ||||
const TermPtr readMultiplyOrDivideExpression() | const TermPtr readMultiplyOrDivideExpression() | ||||
@@ -835,7 +856,7 @@ const Expression Expression::adjustedToGiveNewResult (const double targetValue, | |||||
const Helpers::TermPtr reverseTerm (parent->createTermToEvaluateInput (context, termToAdjust, targetValue, newTerm)); | const Helpers::TermPtr reverseTerm (parent->createTermToEvaluateInput (context, termToAdjust, targetValue, newTerm)); | ||||
if (reverseTerm == 0) | if (reverseTerm == 0) | ||||
return Expression(); | |||||
return Expression (targetValue); | |||||
termToAdjust->value = reverseTerm->evaluate (context, 0); | termToAdjust->value = reverseTerm->evaluate (context, 0); | ||||
} | } | ||||
@@ -845,7 +866,7 @@ const Expression Expression::adjustedToGiveNewResult (const double targetValue, | |||||
const Expression Expression::withRenamedSymbol (const String& oldSymbol, const String& newSymbol) const | const Expression Expression::withRenamedSymbol (const String& oldSymbol, const String& newSymbol) const | ||||
{ | { | ||||
jassert (newSymbol.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); | |||||
jassert (newSymbol.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_")); | |||||
Expression newExpression (term->clone()); | Expression newExpression (term->clone()); | ||||
Helpers::renameSymbol (newExpression.term, oldSymbol, newSymbol); | Helpers::renameSymbol (newExpression.term, oldSymbol, newSymbol); | ||||
@@ -906,9 +927,9 @@ Expression::EvaluationError::EvaluationError (const String& message) | |||||
Expression::EvaluationContext::EvaluationContext() {} | Expression::EvaluationContext::EvaluationContext() {} | ||||
Expression::EvaluationContext::~EvaluationContext() {} | Expression::EvaluationContext::~EvaluationContext() {} | ||||
const Expression Expression::EvaluationContext::getSymbolValue (const String& symbol) const | |||||
const Expression Expression::EvaluationContext::getSymbolValue (const String& symbol, const String& member) const | |||||
{ | { | ||||
throw EvaluationError ("Unknown symbol: \"" + symbol + "\""); | |||||
throw EvaluationError ("Unknown symbol: \"" + symbol + (member.isEmpty() ? "\"" : ("." + member + "\""))); | |||||
} | } | ||||
double Expression::EvaluationContext::evaluateFunction (const String& functionName, const double* parameters, int numParams) const | double Expression::EvaluationContext::evaluateFunction (const String& functionName, const double* parameters, int numParams) const | ||||
@@ -113,9 +113,11 @@ public: | |||||
/** Returns the value of a symbol. | /** Returns the value of a symbol. | ||||
If the symbol is unknown, this can throw an Expression::EvaluationError exception. | If the symbol is unknown, this can throw an Expression::EvaluationError exception. | ||||
The member value is set to the part of the symbol that followed the dot, if there is | |||||
one, e.g. for "foo.bar", symbol = "foo" and member = "bar". | |||||
@throws Expression::EvaluationError | @throws Expression::EvaluationError | ||||
*/ | */ | ||||
virtual const Expression getSymbolValue (const String& symbol) const; | |||||
virtual const Expression getSymbolValue (const String& symbol, const String& member) const; | |||||
/** Executes a named function. | /** Executes a named function. | ||||
If the function name is unknown, this can throw an Expression::EvaluationError exception. | If the function name is unknown, this can throw an Expression::EvaluationError exception. | ||||
@@ -33,7 +33,7 @@ | |||||
*/ | */ | ||||
#define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
#define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
#define JUCE_BUILDNUMBER 53 | |||||
#define JUCE_BUILDNUMBER 54 | |||||
/** Current Juce version number. | /** Current Juce version number. | ||||
@@ -1427,6 +1427,17 @@ void TreeViewItem::paintRecursively (Graphics& g, int width) | |||||
const int indent = getIndentX(); | const int indent = getIndentX(); | ||||
const int itemW = itemWidth < 0 ? width - indent : itemWidth; | const int itemW = itemWidth < 0 ? width - indent : itemWidth; | ||||
{ | |||||
g.saveState(); | |||||
g.setOrigin (indent, 0); | |||||
if (g.reduceClipRegion (drawsInLeftMargin ? -indent : 0, 0, | |||||
drawsInLeftMargin ? itemW + indent : itemW, itemHeight)) | |||||
paintItem (g, itemW, itemHeight); | |||||
g.restoreState(); | |||||
} | |||||
g.setColour (ownerView->findColour (TreeView::linesColourId)); | g.setColour (ownerView->findColour (TreeView::linesColourId)); | ||||
const float halfH = itemHeight * 0.5f; | const float halfH = itemHeight * 0.5f; | ||||
@@ -1489,17 +1500,6 @@ void TreeViewItem::paintRecursively (Graphics& g, int width) | |||||
} | } | ||||
} | } | ||||
{ | |||||
g.saveState(); | |||||
g.setOrigin (indent, 0); | |||||
if (g.reduceClipRegion (drawsInLeftMargin ? -indent : 0, 0, | |||||
drawsInLeftMargin ? itemW + indent : itemW, itemHeight)) | |||||
paintItem (g, itemW, itemHeight); | |||||
g.restoreState(); | |||||
} | |||||
if (isOpen()) | if (isOpen()) | ||||
{ | { | ||||
const Rectangle<int> clip (g.getClipBounds()); | const Rectangle<int> clip (g.getClipBounds()); | ||||
@@ -247,9 +247,9 @@ void DrawableComposite::render (const Drawable::RenderingContext& context) const | |||||
} | } | ||||
} | } | ||||
const Expression DrawableComposite::getSymbolValue (const String& symbol) const | |||||
const Expression DrawableComposite::getSymbolValue (const String& symbol, const String& member) const | |||||
{ | { | ||||
jassert (! symbol.containsChar ('.')) // the only symbols available in a Drawable are markers. | |||||
jassert (member.isEmpty()) // the only symbols available in a Drawable are markers. | |||||
int i; | int i; | ||||
for (i = 0; i < markersX.size(); ++i) | for (i = 0; i < markersX.size(); ++i) | ||||
@@ -266,7 +266,7 @@ const Expression DrawableComposite::getSymbolValue (const String& symbol) const | |||||
return m->position.getExpression(); | return m->position.getExpression(); | ||||
} | } | ||||
return Expression::EvaluationContext::getSymbolValue (symbol); | |||||
return Expression::EvaluationContext::getSymbolValue (symbol, member); | |||||
} | } | ||||
const Rectangle<float> DrawableComposite::getUntransformedBounds (const bool includeMarkers) const | const Rectangle<float> DrawableComposite::getUntransformedBounds (const bool includeMarkers) const | ||||
@@ -201,7 +201,7 @@ public: | |||||
/** @internal */ | /** @internal */ | ||||
const Identifier getValueTreeType() const { return valueTreeType; } | const Identifier getValueTreeType() const { return valueTreeType; } | ||||
/** @internal */ | /** @internal */ | ||||
const Expression getSymbolValue (const String& symbol) const; | |||||
const Expression getSymbolValue (const String& symbol, const String& member) const; | |||||
//============================================================================== | //============================================================================== | ||||
/** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */ | /** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */ | ||||
@@ -185,7 +185,7 @@ const String RelativeCoordinate::toString() const | |||||
void RelativeCoordinate::renameSymbolIfUsed (const String& oldName, const String& newName, | void RelativeCoordinate::renameSymbolIfUsed (const String& oldName, const String& newName, | ||||
const Expression::EvaluationContext* context) | const Expression::EvaluationContext* context) | ||||
{ | { | ||||
jassert (newName.isNotEmpty() && newName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); | |||||
jassert (newName.isNotEmpty() && newName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_")); | |||||
if (term.referencesSymbol (oldName, *context)) | if (term.referencesSymbol (oldName, *context)) | ||||
{ | { | ||||
@@ -263,8 +263,6 @@ FileBasedDocument::SaveResult FileBasedDocument::saveAsInteractive (const bool w | |||||
if (fc.browseForFileToSave (warnAboutOverwritingExistingFiles)) | if (fc.browseForFileToSave (warnAboutOverwritingExistingFiles)) | ||||
{ | { | ||||
setLastDocumentOpened (fc.getResult()); | |||||
File chosen (fc.getResult()); | File chosen (fc.getResult()); | ||||
if (chosen.getFileExtension().isEmpty()) | if (chosen.getFileExtension().isEmpty()) | ||||
{ | { | ||||
@@ -285,6 +283,7 @@ FileBasedDocument::SaveResult FileBasedDocument::saveAsInteractive (const bool w | |||||
} | } | ||||
} | } | ||||
setLastDocumentOpened (chosen); | |||||
return saveAs (chosen, false, false, true); | return saveAs (chosen, false, false, true); | ||||
} | } | ||||