| 
							- /*
 -   ==============================================================================
 - 
 -    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;
 - }
 - 
 - //==============================================================================
 - static void skipWhitespace (const String& s, int& i)
 - {
 -     while (CharacterFunctions::isWhitespace (s[i]))
 -         ++i;
 - }
 - 
 - const StringPairArray parsePreprocessorDefs (const String& s)
 - {
 -     StringPairArray result;
 -     int i = 0;
 - 
 -     while (s[i] != 0)
 -     {
 -         String token, value;
 -         skipWhitespace (s, i);
 - 
 -         while (s[i] != 0 && s[i] != '=' && ! CharacterFunctions::isWhitespace (s[i]))
 -             token << s[i++];
 - 
 -         skipWhitespace (s, i);
 - 
 -         if (s[i] == '=')
 -         {
 -             ++i;
 - 
 -             skipWhitespace (s, i);
 - 
 -             while (s[i] != 0 && ! CharacterFunctions::isWhitespace (s[i]))
 -             {
 -                 if (s[i] == ',')
 -                 {
 -                     ++i;
 -                     break;
 -                 }
 - 
 -                 if (s[i] == '\\' && (s[i + 1] == ' ' || s[i + 1] == ','))
 -                     ++i;
 - 
 -                 value << s[i++];
 -             }
 -         }
 - 
 -         if (token.isNotEmpty())
 -             result.set (token, value);
 -     }
 - 
 -     return result;
 - }
 - 
 - const StringPairArray mergePreprocessorDefs (StringPairArray inheritedDefs, const StringPairArray& overridingDefs)
 - {
 -     for (int i = 0; i < overridingDefs.size(); ++i)
 -         inheritedDefs.set (overridingDefs.getAllKeys()[i], overridingDefs.getAllValues()[i]);
 - 
 -     return inheritedDefs;
 - }
 - 
 - const String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString)
 - {
 -     for (int i = 0; i < definitions.size(); ++i)
 -     {
 -         const String key (definitions.getAllKeys()[i]);
 -         const String value (definitions.getAllValues()[i]);
 - 
 -         sourceString = sourceString.replace ("${" + key + "}", value);
 -     }
 - 
 -     return sourceString;
 - }
 - 
 - //==============================================================================
 - 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);
 -     startTimer (150);
 - }
 - 
 - PropertyPanelWithTooltips::~PropertyPanelWithTooltips()
 - {
 - }
 - 
 - 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* newComp = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse();
 - 
 -     if (newComp != 0 && newComp->getTopLevelComponent() != getTopLevelComponent())
 -         newComp = 0;
 - 
 -     if (newComp != lastComp)
 -     {
 -         lastComp = newComp;
 - 
 -         String newTip (findTip (newComp));
 - 
 -         if (newTip != lastTip)
 -         {
 -             lastTip = newTip;
 -             repaint (0, panel.getBottom(), getWidth(), getHeight());
 -         }
 -     }
 - }
 - 
 - const String PropertyPanelWithTooltips::findTip (Component* c)
 - {
 -     while (c != 0 && c != this)
 -     {
 -         TooltipClient* const tc = dynamic_cast <TooltipClient*> (c);
 -         if (tc != 0)
 -         {
 -             const String tip (tc->getTooltip());
 - 
 -             if (tip.isNotEmpty())
 -                 return tip;
 -         }
 - 
 -         c = c->getParentComponent();
 -     }
 - 
 -     return String::empty;
 - }
 - 
 - //==============================================================================
 - FloatingLabelComponent::FloatingLabelComponent()
 -     : font (10.0f)
 - {
 -     setInterceptsMouseClicks (false, false);
 - }
 - 
 - void FloatingLabelComponent::remove()
 - {
 -     if (getParentComponent() != 0)
 -         getParentComponent()->removeChildComponent (this);
 - }
 - 
 - void FloatingLabelComponent::update (Component* parent, const String& text, const Colour& textColour, int x, int y, bool toRight, bool below)
 - {
 -     colour = textColour;
 - 
 -     Rectangle<int> r;
 - 
 -     if (text != getName())
 -     {
 -         setName (text);
 -         glyphs.clear();
 -         glyphs.addJustifiedText (font, text, 0, 0, 200.0f, Justification::left);
 -         glyphs.justifyGlyphs (0, std::numeric_limits<int>::max(), 0, 0, 1000, 1000, Justification::topLeft);
 - 
 -         r = glyphs.getBoundingBox (0, std::numeric_limits<int>::max(), false)
 -                   .getSmallestIntegerContainer().expanded (1, 1);
 -     }
 -     else
 -     {
 -         r = getLocalBounds();
 -     }
 - 
 -     r.setPosition (x + (toRight ? 3 : -(r.getWidth() + 3)), y + (below ? 2 : -(r.getHeight() + 2)));
 -     setBounds (r);
 -     parent->addAndMakeVisible (this);
 - }
 - 
 - void FloatingLabelComponent::paint (Graphics& g)
 - {
 -     g.setFont (font);
 -     g.setColour (Colours::white.withAlpha (0.5f));
 -     g.fillRoundedRectangle (0, 0, (float) getWidth(), (float) getHeight(), 3);
 - 
 -     g.setColour (colour);
 -     glyphs.draw (g, AffineTransform::translation (1.0f, 1.0f));
 - }
 - 
 - //==============================================================================
 - RelativeRectangleLayoutManager::RelativeRectangleLayoutManager (Component* parentComponent)
 -     : parent (parentComponent)
 - {
 -     parent->addComponentListener (this);
 - }
 - 
 - RelativeRectangleLayoutManager::~RelativeRectangleLayoutManager()
 - {
 -     parent->removeComponentListener (this);
 - 
 -     for (int i = components.size(); --i >= 0;)
 -         components.getUnchecked(i)->component->removeComponentListener (this);
 - }
 - 
 - void RelativeRectangleLayoutManager::setMarker (const String& name, const RelativeCoordinate& coord)
 - {
 -     for (int i = markers.size(); --i >= 0;)
 -     {
 -         MarkerPosition* m = markers.getUnchecked(i);
 -         if (m->markerName == name)
 -         {
 -             m->position = coord;
 -             applyLayout();
 -             return;
 -         }
 -     }
 - 
 -     markers.add (new MarkerPosition (name, coord));
 -     applyLayout();
 - }
 - 
 - void RelativeRectangleLayoutManager::setComponentBounds (Component* comp, const String& name, const RelativeRectangle& coords)
 - {
 -     jassert (comp != 0);
 - 
 -     // All the components that this layout manages must be inside the parent component..
 -     jassert (parent->isParentOf (comp));
 - 
 -     for (int i = components.size(); --i >= 0;)
 -     {
 -         ComponentPosition* c = components.getUnchecked(i);
 -         if (c->component == comp)
 -         {
 -             c->name = name;
 -             c->coords = coords;
 -             triggerAsyncUpdate();
 -             return;
 -         }
 -     }
 - 
 -     components.add (new ComponentPosition (comp, name, coords));
 -     comp->addComponentListener (this);
 -     triggerAsyncUpdate();
 - }
 - 
 - void RelativeRectangleLayoutManager::applyLayout()
 - {
 -     for (int i = components.size(); --i >= 0;)
 -     {
 -         ComponentPosition* c = components.getUnchecked(i);
 - 
 -         // All the components that this layout manages must be inside the parent component..
 -         jassert (parent->isParentOf (c->component));
 - 
 -         c->component->setBounds (c->coords.resolve (this).getSmallestIntegerContainer());
 -     }
 - }
 - 
 - const Expression RelativeRectangleLayoutManager::getSymbolValue (const String& objectName, const String& edge) const
 - {
 -     if (objectName == RelativeCoordinate::Strings::parent)
 -     {
 -         if (edge == RelativeCoordinate::Strings::right)     return Expression ((double) parent->getWidth());
 -         if (edge == RelativeCoordinate::Strings::bottom)    return Expression ((double) parent->getHeight());
 -     }
 - 
 -     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.getExpression();
 -                 if (edge == RelativeCoordinate::Strings::right)  return c->coords.right.getExpression();
 -                 if (edge == RelativeCoordinate::Strings::top)    return c->coords.top.getExpression();
 -                 if (edge == RelativeCoordinate::Strings::bottom) return c->coords.bottom.getExpression();
 -             }
 -         }
 -     }
 - 
 -     for (int i = markers.size(); --i >= 0;)
 -     {
 -         MarkerPosition* m = markers.getUnchecked(i);
 - 
 -         if (m->markerName == objectName)
 -             return m->position.getExpression();
 -     }
 - 
 -     return Expression();
 - }
 - 
 - 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_)
 - {
 - }
 
 
  |