mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
First check-in of the "jucequake": a major re-organisation of the library to break it up into modules. For more details about this, see the website forum..
This commit is contained in:
parent
1a21c89755
commit
b70e0a28d2
1527 changed files with 90380 additions and 396643 deletions
286
modules/juce_gui_basics/positioning/juce_MarkerList.cpp
Normal file
286
modules/juce_gui_basics/positioning/juce_MarkerList.cpp
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
//==============================================================================
|
||||
MarkerList::MarkerList()
|
||||
{
|
||||
}
|
||||
|
||||
MarkerList::MarkerList (const MarkerList& other)
|
||||
{
|
||||
operator= (other);
|
||||
}
|
||||
|
||||
MarkerList& MarkerList::operator= (const MarkerList& other)
|
||||
{
|
||||
if (other != *this)
|
||||
{
|
||||
markers.clear();
|
||||
markers.addCopiesOf (other.markers);
|
||||
markersHaveChanged();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
MarkerList::~MarkerList()
|
||||
{
|
||||
listeners.call (&MarkerList::Listener::markerListBeingDeleted, this);
|
||||
}
|
||||
|
||||
bool MarkerList::operator== (const MarkerList& other) const noexcept
|
||||
{
|
||||
if (other.markers.size() != markers.size())
|
||||
return false;
|
||||
|
||||
for (int i = markers.size(); --i >= 0;)
|
||||
{
|
||||
const Marker* const m1 = markers.getUnchecked(i);
|
||||
jassert (m1 != nullptr);
|
||||
|
||||
const Marker* const m2 = other.getMarker (m1->name);
|
||||
|
||||
if (m2 == nullptr || *m1 != *m2)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MarkerList::operator!= (const MarkerList& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int MarkerList::getNumMarkers() const noexcept
|
||||
{
|
||||
return markers.size();
|
||||
}
|
||||
|
||||
const MarkerList::Marker* MarkerList::getMarker (const int index) const noexcept
|
||||
{
|
||||
return markers [index];
|
||||
}
|
||||
|
||||
const MarkerList::Marker* MarkerList::getMarker (const String& name) const noexcept
|
||||
{
|
||||
for (int i = 0; i < markers.size(); ++i)
|
||||
{
|
||||
const Marker* const m = markers.getUnchecked(i);
|
||||
|
||||
if (m->name == name)
|
||||
return m;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void MarkerList::setMarker (const String& name, const RelativeCoordinate& position)
|
||||
{
|
||||
Marker* const m = const_cast <Marker*> (getMarker (name));
|
||||
|
||||
if (m != nullptr)
|
||||
{
|
||||
if (m->position != position)
|
||||
{
|
||||
m->position = position;
|
||||
markersHaveChanged();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
markers.add (new Marker (name, position));
|
||||
markersHaveChanged();
|
||||
}
|
||||
|
||||
void MarkerList::removeMarker (const int index)
|
||||
{
|
||||
if (isPositiveAndBelow (index, markers.size()))
|
||||
{
|
||||
markers.remove (index);
|
||||
markersHaveChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void MarkerList::removeMarker (const String& name)
|
||||
{
|
||||
for (int i = 0; i < markers.size(); ++i)
|
||||
{
|
||||
const Marker* const m = markers.getUnchecked(i);
|
||||
|
||||
if (m->name == name)
|
||||
{
|
||||
markers.remove (i);
|
||||
markersHaveChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MarkerList::markersHaveChanged()
|
||||
{
|
||||
listeners.call (&MarkerList::Listener::markersChanged, this);
|
||||
}
|
||||
|
||||
void MarkerList::Listener::markerListBeingDeleted (MarkerList*)
|
||||
{
|
||||
}
|
||||
|
||||
void MarkerList::addListener (Listener* listener)
|
||||
{
|
||||
listeners.add (listener);
|
||||
}
|
||||
|
||||
void MarkerList::removeListener (Listener* listener)
|
||||
{
|
||||
listeners.remove (listener);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
MarkerList::Marker::Marker (const Marker& other)
|
||||
: name (other.name), position (other.position)
|
||||
{
|
||||
}
|
||||
|
||||
MarkerList::Marker::Marker (const String& name_, const RelativeCoordinate& position_)
|
||||
: name (name_), position (position_)
|
||||
{
|
||||
}
|
||||
|
||||
bool MarkerList::Marker::operator== (const Marker& other) const noexcept
|
||||
{
|
||||
return name == other.name && position == other.position;
|
||||
}
|
||||
|
||||
bool MarkerList::Marker::operator!= (const Marker& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
const Identifier MarkerList::ValueTreeWrapper::markerTag ("Marker");
|
||||
const Identifier MarkerList::ValueTreeWrapper::nameProperty ("name");
|
||||
const Identifier MarkerList::ValueTreeWrapper::posProperty ("position");
|
||||
|
||||
MarkerList::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_)
|
||||
: state (state_)
|
||||
{
|
||||
}
|
||||
|
||||
int MarkerList::ValueTreeWrapper::getNumMarkers() const
|
||||
{
|
||||
return state.getNumChildren();
|
||||
}
|
||||
|
||||
ValueTree MarkerList::ValueTreeWrapper::getMarkerState (int index) const
|
||||
{
|
||||
return state.getChild (index);
|
||||
}
|
||||
|
||||
ValueTree MarkerList::ValueTreeWrapper::getMarkerState (const String& name) const
|
||||
{
|
||||
return state.getChildWithProperty (nameProperty, name);
|
||||
}
|
||||
|
||||
bool MarkerList::ValueTreeWrapper::containsMarker (const ValueTree& marker) const
|
||||
{
|
||||
return marker.isAChildOf (state);
|
||||
}
|
||||
|
||||
MarkerList::Marker MarkerList::ValueTreeWrapper::getMarker (const ValueTree& marker) const
|
||||
{
|
||||
jassert (containsMarker (marker));
|
||||
|
||||
return MarkerList::Marker (marker [nameProperty], RelativeCoordinate (marker [posProperty].toString()));
|
||||
}
|
||||
|
||||
void MarkerList::ValueTreeWrapper::setMarker (const MarkerList::Marker& m, UndoManager* undoManager)
|
||||
{
|
||||
ValueTree marker (state.getChildWithProperty (nameProperty, m.name));
|
||||
|
||||
if (marker.isValid())
|
||||
{
|
||||
marker.setProperty (posProperty, m.position.toString(), undoManager);
|
||||
}
|
||||
else
|
||||
{
|
||||
marker = ValueTree (markerTag);
|
||||
marker.setProperty (nameProperty, m.name, nullptr);
|
||||
marker.setProperty (posProperty, m.position.toString(), nullptr);
|
||||
state.addChild (marker, -1, undoManager);
|
||||
}
|
||||
}
|
||||
|
||||
void MarkerList::ValueTreeWrapper::removeMarker (const ValueTree& marker, UndoManager* undoManager)
|
||||
{
|
||||
state.removeChild (marker, undoManager);
|
||||
}
|
||||
|
||||
double MarkerList::getMarkerPosition (const Marker& marker, Component* parentComponent) const
|
||||
{
|
||||
if (parentComponent != nullptr)
|
||||
{
|
||||
RelativeCoordinatePositionerBase::ComponentScope scope (*parentComponent);
|
||||
return marker.position.resolve (&scope);
|
||||
}
|
||||
else
|
||||
{
|
||||
return marker.position.resolve (nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MarkerList::ValueTreeWrapper::applyTo (MarkerList& markerList)
|
||||
{
|
||||
const int numMarkers = getNumMarkers();
|
||||
|
||||
StringArray updatedMarkers;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < numMarkers; ++i)
|
||||
{
|
||||
const ValueTree marker (state.getChild (i));
|
||||
const String name (marker [nameProperty].toString());
|
||||
markerList.setMarker (name, RelativeCoordinate (marker [posProperty].toString()));
|
||||
updatedMarkers.add (name);
|
||||
}
|
||||
|
||||
for (i = markerList.getNumMarkers(); --i >= 0;)
|
||||
if (! updatedMarkers.contains (markerList.getMarker (i)->name))
|
||||
markerList.removeMarker (i);
|
||||
}
|
||||
|
||||
void MarkerList::ValueTreeWrapper::readFrom (const MarkerList& markerList, UndoManager* undoManager)
|
||||
{
|
||||
state.removeAllChildren (undoManager);
|
||||
|
||||
for (int i = 0; i < markerList.getNumMarkers(); ++i)
|
||||
setMarker (*markerList.getMarker(i), undoManager);
|
||||
}
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
186
modules/juce_gui_basics/positioning/juce_MarkerList.h
Normal file
186
modules/juce_gui_basics/positioning/juce_MarkerList.h
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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 __JUCE_MARKERLIST_JUCEHEADER__
|
||||
#define __JUCE_MARKERLIST_JUCEHEADER__
|
||||
|
||||
#include "../positioning/juce_RelativeCoordinate.h"
|
||||
class Component;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Holds a set of named marker points along a one-dimensional axis.
|
||||
|
||||
This class is used to store sets of X and Y marker points in components.
|
||||
@see Component::getMarkers().
|
||||
*/
|
||||
class JUCE_API MarkerList
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty marker list. */
|
||||
MarkerList();
|
||||
/** Creates a copy of another marker list. */
|
||||
MarkerList (const MarkerList& other);
|
||||
/** Copies another marker list to this one. */
|
||||
MarkerList& operator= (const MarkerList& other);
|
||||
/** Destructor. */
|
||||
~MarkerList();
|
||||
|
||||
//==============================================================================
|
||||
/** Represents a marker in a MarkerList. */
|
||||
class JUCE_API Marker
|
||||
{
|
||||
public:
|
||||
/** Creates a copy of another Marker. */
|
||||
Marker (const Marker& other);
|
||||
/** Creates a Marker with a given name and position. */
|
||||
Marker (const String& name, const RelativeCoordinate& position);
|
||||
|
||||
/** The marker's name. */
|
||||
String name;
|
||||
|
||||
/** The marker's position.
|
||||
|
||||
The expression used to define the coordinate may use the names of other
|
||||
markers, so that markers can be linked in arbitrary ways, but be careful
|
||||
not to create recursive loops of markers whose positions are based on each
|
||||
other! It can also refer to "parent.right" and "parent.bottom" so that you
|
||||
can set markers which are relative to the size of the component that contains
|
||||
them.
|
||||
|
||||
To resolve the coordinate, you can use the MarkerList::getMarkerPosition() method.
|
||||
*/
|
||||
RelativeCoordinate position;
|
||||
|
||||
/** Returns true if both the names and positions of these two markers match. */
|
||||
bool operator== (const Marker&) const noexcept;
|
||||
/** Returns true if either the name or position of these two markers differ. */
|
||||
bool operator!= (const Marker&) const noexcept;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the number of markers in the list. */
|
||||
int getNumMarkers() const noexcept;
|
||||
|
||||
/** Returns one of the markers in the list, by its index. */
|
||||
const Marker* getMarker (int index) const noexcept;
|
||||
|
||||
/** Returns a named marker, or 0 if no such name is found.
|
||||
Note that name comparisons are case-sensitive.
|
||||
*/
|
||||
const Marker* getMarker (const String& name) const noexcept;
|
||||
|
||||
/** Evaluates the given marker and returns its absolute position.
|
||||
The parent component must be supplied in case the marker's expression refers to
|
||||
the size of its parent component.
|
||||
*/
|
||||
double getMarkerPosition (const Marker& marker, Component* parentComponent) const;
|
||||
|
||||
/** Sets the position of a marker.
|
||||
|
||||
If the name already exists, then the existing marker is moved; if it doesn't exist, then a
|
||||
new marker is added.
|
||||
*/
|
||||
void setMarker (const String& name, const RelativeCoordinate& position);
|
||||
|
||||
/** Deletes the marker at the given list index. */
|
||||
void removeMarker (int index);
|
||||
|
||||
/** Deletes the marker with the given name. */
|
||||
void removeMarker (const String& name);
|
||||
|
||||
/** Returns true if all the markers in these two lists match exactly. */
|
||||
bool operator== (const MarkerList& other) const noexcept;
|
||||
/** Returns true if not all the markers in these two lists match exactly. */
|
||||
bool operator!= (const MarkerList& other) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class for receiving events when changes are made to a MarkerList.
|
||||
|
||||
You can register a MarkerList::Listener with a MarkerList using the MarkerList::addListener()
|
||||
method, and it will be called when markers are moved, added, or deleted.
|
||||
|
||||
@see MarkerList::addListener, MarkerList::removeListener
|
||||
*/
|
||||
class JUCE_API Listener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~Listener() {}
|
||||
|
||||
/** Called when something in the given marker list changes. */
|
||||
virtual void markersChanged (MarkerList* markerList) = 0;
|
||||
|
||||
/** Called when the given marker list is being deleted. */
|
||||
virtual void markerListBeingDeleted (MarkerList* markerList);
|
||||
};
|
||||
|
||||
/** Registers a listener that will be called when the markers are changed. */
|
||||
void addListener (Listener* listener);
|
||||
|
||||
/** Deregisters a previously-registered listener. */
|
||||
void removeListener (Listener* listener);
|
||||
|
||||
/** Synchronously calls markersChanged() on all the registered listeners. */
|
||||
void markersHaveChanged();
|
||||
|
||||
//==============================================================================
|
||||
/** Forms a wrapper around a ValueTree that can be used for storing a MarkerList. */
|
||||
class ValueTreeWrapper
|
||||
{
|
||||
public:
|
||||
ValueTreeWrapper (const ValueTree& state);
|
||||
|
||||
ValueTree& getState() noexcept { return state; }
|
||||
int getNumMarkers() const;
|
||||
ValueTree getMarkerState (int index) const;
|
||||
ValueTree getMarkerState (const String& name) const;
|
||||
bool containsMarker (const ValueTree& state) const;
|
||||
MarkerList::Marker getMarker (const ValueTree& state) const;
|
||||
void setMarker (const MarkerList::Marker& marker, UndoManager* undoManager);
|
||||
void removeMarker (const ValueTree& state, UndoManager* undoManager);
|
||||
|
||||
void applyTo (MarkerList& markerList);
|
||||
void readFrom (const MarkerList& markerList, UndoManager* undoManager);
|
||||
|
||||
static const Identifier markerTag, nameProperty, posProperty;
|
||||
|
||||
private:
|
||||
ValueTree state;
|
||||
};
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
OwnedArray<Marker> markers;
|
||||
ListenerList<Listener> listeners;
|
||||
|
||||
JUCE_LEAK_DETECTOR (MarkerList);
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCE_MARKERLIST_JUCEHEADER__
|
||||
165
modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp
Normal file
165
modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
//==============================================================================
|
||||
const String RelativeCoordinate::Strings::parent ("parent");
|
||||
const String RelativeCoordinate::Strings::left ("left");
|
||||
const String RelativeCoordinate::Strings::right ("right");
|
||||
const String RelativeCoordinate::Strings::top ("top");
|
||||
const String RelativeCoordinate::Strings::bottom ("bottom");
|
||||
const String RelativeCoordinate::Strings::x ("x");
|
||||
const String RelativeCoordinate::Strings::y ("y");
|
||||
const String RelativeCoordinate::Strings::width ("width");
|
||||
const String RelativeCoordinate::Strings::height ("height");
|
||||
|
||||
RelativeCoordinate::StandardStrings::Type RelativeCoordinate::StandardStrings::getTypeOf (const String& s) noexcept
|
||||
{
|
||||
if (s == Strings::left) return left;
|
||||
if (s == Strings::right) return right;
|
||||
if (s == Strings::top) return top;
|
||||
if (s == Strings::bottom) return bottom;
|
||||
if (s == Strings::x) return x;
|
||||
if (s == Strings::y) return y;
|
||||
if (s == Strings::width) return width;
|
||||
if (s == Strings::height) return height;
|
||||
if (s == Strings::parent) return parent;
|
||||
return unknown;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
RelativeCoordinate::RelativeCoordinate()
|
||||
{
|
||||
}
|
||||
|
||||
RelativeCoordinate::RelativeCoordinate (const Expression& term_)
|
||||
: term (term_)
|
||||
{
|
||||
}
|
||||
|
||||
RelativeCoordinate::RelativeCoordinate (const RelativeCoordinate& other)
|
||||
: term (other.term)
|
||||
{
|
||||
}
|
||||
|
||||
RelativeCoordinate& RelativeCoordinate::operator= (const RelativeCoordinate& other)
|
||||
{
|
||||
term = other.term;
|
||||
return *this;
|
||||
}
|
||||
|
||||
RelativeCoordinate::RelativeCoordinate (const double absoluteDistanceFromOrigin)
|
||||
: term (absoluteDistanceFromOrigin)
|
||||
{
|
||||
}
|
||||
|
||||
RelativeCoordinate::RelativeCoordinate (const String& s)
|
||||
{
|
||||
try
|
||||
{
|
||||
term = Expression (s);
|
||||
}
|
||||
catch (...)
|
||||
{}
|
||||
}
|
||||
|
||||
RelativeCoordinate::~RelativeCoordinate()
|
||||
{
|
||||
}
|
||||
|
||||
bool RelativeCoordinate::operator== (const RelativeCoordinate& other) const noexcept
|
||||
{
|
||||
return term.toString() == other.term.toString();
|
||||
}
|
||||
|
||||
bool RelativeCoordinate::operator!= (const RelativeCoordinate& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
double RelativeCoordinate::resolve (const Expression::Scope* scope) const
|
||||
{
|
||||
try
|
||||
{
|
||||
if (scope != nullptr)
|
||||
return term.evaluate (*scope);
|
||||
else
|
||||
return term.evaluate();
|
||||
}
|
||||
catch (...)
|
||||
{}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
bool RelativeCoordinate::isRecursive (const Expression::Scope* scope) const
|
||||
{
|
||||
try
|
||||
{
|
||||
if (scope != nullptr)
|
||||
term.evaluate (*scope);
|
||||
else
|
||||
term.evaluate();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RelativeCoordinate::moveToAbsolute (double newPos, const Expression::Scope* scope)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (scope != nullptr)
|
||||
{
|
||||
term = term.adjustedToGiveNewResult (newPos, *scope);
|
||||
}
|
||||
else
|
||||
{
|
||||
Expression::Scope defaultScope;
|
||||
term = term.adjustedToGiveNewResult (newPos, defaultScope);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{}
|
||||
}
|
||||
|
||||
bool RelativeCoordinate::isDynamic() const
|
||||
{
|
||||
return term.usesAnySymbols();
|
||||
}
|
||||
|
||||
String RelativeCoordinate::toString() const
|
||||
{
|
||||
return term.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
143
modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h
Normal file
143
modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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 __JUCE_RELATIVECOORDINATE_JUCEHEADER__
|
||||
#define __JUCE_RELATIVECOORDINATE_JUCEHEADER__
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Expresses a coordinate as a dynamically evaluated expression.
|
||||
|
||||
@see RelativePoint, RelativeRectangle
|
||||
*/
|
||||
class JUCE_API RelativeCoordinate
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a zero coordinate. */
|
||||
RelativeCoordinate();
|
||||
RelativeCoordinate (const Expression& expression);
|
||||
RelativeCoordinate (const RelativeCoordinate& other);
|
||||
RelativeCoordinate& operator= (const RelativeCoordinate& other);
|
||||
|
||||
/** Creates an absolute position from the parent origin on either the X or Y axis.
|
||||
|
||||
@param absoluteDistanceFromOrigin the distance from the origin
|
||||
*/
|
||||
RelativeCoordinate (double absoluteDistanceFromOrigin);
|
||||
|
||||
/** Recreates a coordinate from a string description.
|
||||
The string will be parsed by ExpressionParser::parse().
|
||||
@param stringVersion the expression to use
|
||||
@see toString
|
||||
*/
|
||||
RelativeCoordinate (const String& stringVersion);
|
||||
|
||||
/** Destructor. */
|
||||
~RelativeCoordinate();
|
||||
|
||||
bool operator== (const RelativeCoordinate& other) const noexcept;
|
||||
bool operator!= (const RelativeCoordinate& other) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Calculates the absolute position of this coordinate.
|
||||
|
||||
You'll need to provide a suitable Expression::Scope for looking up any coordinates that may
|
||||
be needed to calculate the result.
|
||||
*/
|
||||
double resolve (const Expression::Scope* evaluationScope) const;
|
||||
|
||||
/** Returns true if this coordinate uses the specified coord name at any level in its evaluation.
|
||||
This will recursively check any coordinates upon which this one depends.
|
||||
*/
|
||||
bool references (const String& coordName, const Expression::Scope* evaluationScope) const;
|
||||
|
||||
/** Returns true if there's a recursive loop when trying to resolve this coordinate's position. */
|
||||
bool isRecursive (const Expression::Scope* evaluationScope) const;
|
||||
|
||||
/** Returns true if this coordinate depends on any other coordinates for its position. */
|
||||
bool isDynamic() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the value of this coord to make it resolve to the specified position.
|
||||
|
||||
Calling this will leave the anchor points unchanged, but will set this coordinate's absolute
|
||||
or relative position to whatever value is necessary to make its resultant position
|
||||
match the position that is provided.
|
||||
*/
|
||||
void moveToAbsolute (double absoluteTargetPosition, const Expression::Scope* evaluationScope);
|
||||
|
||||
/** Returns the expression that defines this coordinate. */
|
||||
const Expression& getExpression() const { return term; }
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a string which represents this coordinate.
|
||||
For details of the string syntax, see the constructor notes.
|
||||
*/
|
||||
String toString() const;
|
||||
|
||||
//==============================================================================
|
||||
/** A set of static strings that are commonly used by the RelativeCoordinate class.
|
||||
|
||||
As well as avoiding using string literals in your code, using these preset values
|
||||
has the advantage that all instances of the same string will share the same, reference-counted
|
||||
String object, so if you have thousands of points which all refer to the same
|
||||
anchor points, this can save a significant amount of memory allocation.
|
||||
*/
|
||||
struct Strings
|
||||
{
|
||||
static const String parent; /**< "parent" */
|
||||
static const String left; /**< "left" */
|
||||
static const String right; /**< "right" */
|
||||
static const String top; /**< "top" */
|
||||
static const String bottom; /**< "bottom" */
|
||||
static const String x; /**< "x" */
|
||||
static const String y; /**< "y" */
|
||||
static const String width; /**< "width" */
|
||||
static const String height; /**< "height" */
|
||||
};
|
||||
|
||||
struct StandardStrings
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
left, right, top, bottom,
|
||||
x, y, width, height,
|
||||
parent,
|
||||
unknown
|
||||
};
|
||||
|
||||
static Type getTypeOf (const String& s) noexcept;
|
||||
};
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
Expression term;
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCE_RELATIVECOORDINATE_JUCEHEADER__
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
//==============================================================================
|
||||
RelativeCoordinatePositionerBase::ComponentScope::ComponentScope (Component& component_)
|
||||
: component (component_)
|
||||
{
|
||||
}
|
||||
|
||||
Expression RelativeCoordinatePositionerBase::ComponentScope::getSymbolValue (const String& symbol) const
|
||||
{
|
||||
switch (RelativeCoordinate::StandardStrings::getTypeOf (symbol))
|
||||
{
|
||||
case RelativeCoordinate::StandardStrings::x:
|
||||
case RelativeCoordinate::StandardStrings::left: return Expression ((double) component.getX());
|
||||
case RelativeCoordinate::StandardStrings::y:
|
||||
case RelativeCoordinate::StandardStrings::top: return Expression ((double) component.getY());
|
||||
case RelativeCoordinate::StandardStrings::width: return Expression ((double) component.getWidth());
|
||||
case RelativeCoordinate::StandardStrings::height: return Expression ((double) component.getHeight());
|
||||
case RelativeCoordinate::StandardStrings::right: return Expression ((double) component.getRight());
|
||||
case RelativeCoordinate::StandardStrings::bottom: return Expression ((double) component.getBottom());
|
||||
default: break;
|
||||
}
|
||||
|
||||
MarkerList* list;
|
||||
const MarkerList::Marker* const marker = findMarker (symbol, list);
|
||||
|
||||
if (marker != nullptr)
|
||||
return marker->position.getExpression();
|
||||
|
||||
return Expression::Scope::getSymbolValue (symbol);
|
||||
}
|
||||
|
||||
void RelativeCoordinatePositionerBase::ComponentScope::visitRelativeScope (const String& scopeName, Visitor& visitor) const
|
||||
{
|
||||
Component* targetComp = nullptr;
|
||||
|
||||
if (scopeName == RelativeCoordinate::Strings::parent)
|
||||
targetComp = component.getParentComponent();
|
||||
else
|
||||
targetComp = findSiblingComponent (scopeName);
|
||||
|
||||
if (targetComp != nullptr)
|
||||
visitor.visit (ComponentScope (*targetComp));
|
||||
else
|
||||
Expression::Scope::visitRelativeScope (scopeName, visitor);
|
||||
}
|
||||
|
||||
String RelativeCoordinatePositionerBase::ComponentScope::getScopeUID() const
|
||||
{
|
||||
return String::toHexString ((int) (pointer_sized_int) (void*) &component);
|
||||
}
|
||||
|
||||
Component* RelativeCoordinatePositionerBase::ComponentScope::findSiblingComponent (const String& componentID) const
|
||||
{
|
||||
Component* const parent = component.getParentComponent();
|
||||
|
||||
if (parent != nullptr)
|
||||
{
|
||||
for (int i = parent->getNumChildComponents(); --i >= 0;)
|
||||
{
|
||||
Component* const c = parent->getChildComponent(i);
|
||||
|
||||
if (c->getComponentID() == componentID)
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const MarkerList::Marker* RelativeCoordinatePositionerBase::ComponentScope::findMarker (const String& name, MarkerList*& list) const
|
||||
{
|
||||
const MarkerList::Marker* marker = nullptr;
|
||||
|
||||
Component* const parent = component.getParentComponent();
|
||||
|
||||
if (parent != nullptr)
|
||||
{
|
||||
list = parent->getMarkers (true);
|
||||
if (list != nullptr)
|
||||
marker = list->getMarker (name);
|
||||
|
||||
if (marker == nullptr)
|
||||
{
|
||||
list = parent->getMarkers (false);
|
||||
|
||||
if (list != nullptr)
|
||||
marker = list->getMarker (name);
|
||||
}
|
||||
}
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class RelativeCoordinatePositionerBase::DependencyFinderScope : public ComponentScope
|
||||
{
|
||||
public:
|
||||
DependencyFinderScope (Component& component_, RelativeCoordinatePositionerBase& positioner_, bool& ok_)
|
||||
: ComponentScope (component_), positioner (positioner_), ok (ok_)
|
||||
{
|
||||
}
|
||||
|
||||
Expression getSymbolValue (const String& symbol) const
|
||||
{
|
||||
if (symbol == RelativeCoordinate::Strings::left || symbol == RelativeCoordinate::Strings::x
|
||||
|| symbol == RelativeCoordinate::Strings::width || symbol == RelativeCoordinate::Strings::right
|
||||
|| symbol == RelativeCoordinate::Strings::top || symbol == RelativeCoordinate::Strings::y
|
||||
|| symbol == RelativeCoordinate::Strings::height || symbol == RelativeCoordinate::Strings::bottom)
|
||||
{
|
||||
positioner.registerComponentListener (component);
|
||||
}
|
||||
else
|
||||
{
|
||||
MarkerList* list;
|
||||
const MarkerList::Marker* const marker = findMarker (symbol, list);
|
||||
|
||||
if (marker != nullptr)
|
||||
{
|
||||
positioner.registerMarkerListListener (list);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The marker we want doesn't exist, so watch all lists in case they change and the marker appears later..
|
||||
positioner.registerMarkerListListener (component.getMarkers (true));
|
||||
positioner.registerMarkerListListener (component.getMarkers (false));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
return ComponentScope::getSymbolValue (symbol);
|
||||
}
|
||||
|
||||
void visitRelativeScope (const String& scopeName, Visitor& visitor) const
|
||||
{
|
||||
Component* targetComp = nullptr;
|
||||
|
||||
if (scopeName == RelativeCoordinate::Strings::parent)
|
||||
targetComp = component.getParentComponent();
|
||||
else
|
||||
targetComp = findSiblingComponent (scopeName);
|
||||
|
||||
if (targetComp != nullptr)
|
||||
{
|
||||
visitor.visit (DependencyFinderScope (*targetComp, positioner, ok));
|
||||
}
|
||||
else
|
||||
{
|
||||
// The named component doesn't exist, so we'll watch the parent for changes in case it appears later..
|
||||
Component* const parent = component.getParentComponent();
|
||||
if (parent != nullptr)
|
||||
positioner.registerComponentListener (*parent);
|
||||
|
||||
positioner.registerComponentListener (component);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
RelativeCoordinatePositionerBase& positioner;
|
||||
bool& ok;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (DependencyFinderScope);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
RelativeCoordinatePositionerBase::RelativeCoordinatePositionerBase (Component& component_)
|
||||
: Component::Positioner (component_), registeredOk (false)
|
||||
{
|
||||
}
|
||||
|
||||
RelativeCoordinatePositionerBase::~RelativeCoordinatePositionerBase()
|
||||
{
|
||||
unregisterListeners();
|
||||
}
|
||||
|
||||
void RelativeCoordinatePositionerBase::componentMovedOrResized (Component&, bool /*wasMoved*/, bool /*wasResized*/)
|
||||
{
|
||||
apply();
|
||||
}
|
||||
|
||||
void RelativeCoordinatePositionerBase::componentParentHierarchyChanged (Component&)
|
||||
{
|
||||
apply();
|
||||
}
|
||||
|
||||
void RelativeCoordinatePositionerBase::componentChildrenChanged (Component& changed)
|
||||
{
|
||||
if (getComponent().getParentComponent() == &changed && ! registeredOk)
|
||||
apply();
|
||||
}
|
||||
|
||||
void RelativeCoordinatePositionerBase::componentBeingDeleted (Component& comp)
|
||||
{
|
||||
jassert (sourceComponents.contains (&comp));
|
||||
sourceComponents.removeValue (&comp);
|
||||
registeredOk = false;
|
||||
}
|
||||
|
||||
void RelativeCoordinatePositionerBase::markersChanged (MarkerList*)
|
||||
{
|
||||
apply();
|
||||
}
|
||||
|
||||
void RelativeCoordinatePositionerBase::markerListBeingDeleted (MarkerList* markerList)
|
||||
{
|
||||
jassert (sourceMarkerLists.contains (markerList));
|
||||
sourceMarkerLists.removeValue (markerList);
|
||||
}
|
||||
|
||||
void RelativeCoordinatePositionerBase::apply()
|
||||
{
|
||||
if (! registeredOk)
|
||||
{
|
||||
unregisterListeners();
|
||||
registeredOk = registerCoordinates();
|
||||
}
|
||||
|
||||
applyToComponentBounds();
|
||||
}
|
||||
|
||||
bool RelativeCoordinatePositionerBase::addCoordinate (const RelativeCoordinate& coord)
|
||||
{
|
||||
bool ok = true;
|
||||
DependencyFinderScope finderScope (getComponent(), *this, ok);
|
||||
coord.getExpression().evaluate (finderScope);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RelativeCoordinatePositionerBase::addPoint (const RelativePoint& point)
|
||||
{
|
||||
const bool ok = addCoordinate (point.x);
|
||||
return addCoordinate (point.y) && ok;
|
||||
}
|
||||
|
||||
void RelativeCoordinatePositionerBase::registerComponentListener (Component& comp)
|
||||
{
|
||||
if (! sourceComponents.contains (&comp))
|
||||
{
|
||||
comp.addComponentListener (this);
|
||||
sourceComponents.add (&comp);
|
||||
}
|
||||
}
|
||||
|
||||
void RelativeCoordinatePositionerBase::registerMarkerListListener (MarkerList* const list)
|
||||
{
|
||||
if (list != nullptr && ! sourceMarkerLists.contains (list))
|
||||
{
|
||||
list->addListener (this);
|
||||
sourceMarkerLists.add (list);
|
||||
}
|
||||
}
|
||||
|
||||
void RelativeCoordinatePositionerBase::unregisterListeners()
|
||||
{
|
||||
int i;
|
||||
for (i = sourceComponents.size(); --i >= 0;)
|
||||
sourceComponents.getUnchecked(i)->removeComponentListener (this);
|
||||
|
||||
for (i = sourceMarkerLists.size(); --i >= 0;)
|
||||
sourceMarkerLists.getUnchecked(i)->removeListener (this);
|
||||
|
||||
sourceComponents.clear();
|
||||
sourceMarkerLists.clear();
|
||||
}
|
||||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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 __JUCE_RELATIVECOORDINATEPOSITIONER_JUCEHEADER__
|
||||
#define __JUCE_RELATIVECOORDINATEPOSITIONER_JUCEHEADER__
|
||||
|
||||
#include "juce_RelativePoint.h"
|
||||
#include "juce_MarkerList.h"
|
||||
#include "../components/juce_Component.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Base class for Component::Positioners that are based upon relative coordinates.
|
||||
*/
|
||||
class JUCE_API RelativeCoordinatePositionerBase : public Component::Positioner,
|
||||
public ComponentListener,
|
||||
public MarkerList::Listener
|
||||
{
|
||||
public:
|
||||
RelativeCoordinatePositionerBase (Component& component_);
|
||||
~RelativeCoordinatePositionerBase();
|
||||
|
||||
void componentMovedOrResized (Component&, bool, bool);
|
||||
void componentParentHierarchyChanged (Component&);
|
||||
void componentChildrenChanged (Component& component);
|
||||
void componentBeingDeleted (Component& component);
|
||||
void markersChanged (MarkerList*);
|
||||
void markerListBeingDeleted (MarkerList* markerList);
|
||||
|
||||
void apply();
|
||||
|
||||
bool addCoordinate (const RelativeCoordinate& coord);
|
||||
bool addPoint (const RelativePoint& point);
|
||||
|
||||
//==============================================================================
|
||||
/** Used for resolving a RelativeCoordinate expression in the context of a component. */
|
||||
class ComponentScope : public Expression::Scope
|
||||
{
|
||||
public:
|
||||
ComponentScope (Component& component_);
|
||||
|
||||
Expression getSymbolValue (const String& symbol) const;
|
||||
void visitRelativeScope (const String& scopeName, Visitor& visitor) const;
|
||||
String getScopeUID() const;
|
||||
|
||||
protected:
|
||||
Component& component;
|
||||
|
||||
Component* findSiblingComponent (const String& componentID) const;
|
||||
const MarkerList::Marker* findMarker (const String& name, MarkerList*& list) const;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE (ComponentScope);
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual bool registerCoordinates() = 0;
|
||||
virtual void applyToComponentBounds() = 0;
|
||||
|
||||
private:
|
||||
class DependencyFinderScope;
|
||||
friend class DependencyFinderScope;
|
||||
Array <Component*> sourceComponents;
|
||||
Array <MarkerList*> sourceMarkerLists;
|
||||
bool registeredOk;
|
||||
|
||||
void registerComponentListener (Component& comp);
|
||||
void registerMarkerListListener (MarkerList* const list);
|
||||
void unregisterListeners();
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RelativeCoordinatePositionerBase);
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCE_RELATIVECOORDINATEPOSITIONER_JUCEHEADER__
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
//==============================================================================
|
||||
RelativeParallelogram::RelativeParallelogram()
|
||||
{
|
||||
}
|
||||
|
||||
RelativeParallelogram::RelativeParallelogram (const Rectangle<float>& r)
|
||||
: topLeft (r.getTopLeft()), topRight (r.getTopRight()), bottomLeft (r.getBottomLeft())
|
||||
{
|
||||
}
|
||||
|
||||
RelativeParallelogram::RelativeParallelogram (const RelativePoint& topLeft_, const RelativePoint& topRight_, const RelativePoint& bottomLeft_)
|
||||
: topLeft (topLeft_), topRight (topRight_), bottomLeft (bottomLeft_)
|
||||
{
|
||||
}
|
||||
|
||||
RelativeParallelogram::RelativeParallelogram (const String& topLeft_, const String& topRight_, const String& bottomLeft_)
|
||||
: topLeft (topLeft_), topRight (topRight_), bottomLeft (bottomLeft_)
|
||||
{
|
||||
}
|
||||
|
||||
RelativeParallelogram::~RelativeParallelogram()
|
||||
{
|
||||
}
|
||||
|
||||
void RelativeParallelogram::resolveThreePoints (Point<float>* points, Expression::Scope* const scope) const
|
||||
{
|
||||
points[0] = topLeft.resolve (scope);
|
||||
points[1] = topRight.resolve (scope);
|
||||
points[2] = bottomLeft.resolve (scope);
|
||||
}
|
||||
|
||||
void RelativeParallelogram::resolveFourCorners (Point<float>* points, Expression::Scope* const scope) const
|
||||
{
|
||||
resolveThreePoints (points, scope);
|
||||
points[3] = points[1] + (points[2] - points[0]);
|
||||
}
|
||||
|
||||
const Rectangle<float> RelativeParallelogram::getBounds (Expression::Scope* const scope) const
|
||||
{
|
||||
Point<float> points[4];
|
||||
resolveFourCorners (points, scope);
|
||||
return Rectangle<float>::findAreaContainingPoints (points, 4);
|
||||
}
|
||||
|
||||
void RelativeParallelogram::getPath (Path& path, Expression::Scope* const scope) const
|
||||
{
|
||||
Point<float> points[4];
|
||||
resolveFourCorners (points, scope);
|
||||
|
||||
path.startNewSubPath (points[0]);
|
||||
path.lineTo (points[1]);
|
||||
path.lineTo (points[3]);
|
||||
path.lineTo (points[2]);
|
||||
path.closeSubPath();
|
||||
}
|
||||
|
||||
const AffineTransform RelativeParallelogram::resetToPerpendicular (Expression::Scope* const scope)
|
||||
{
|
||||
Point<float> corners[3];
|
||||
resolveThreePoints (corners, scope);
|
||||
|
||||
const Line<float> top (corners[0], corners[1]);
|
||||
const Line<float> left (corners[0], corners[2]);
|
||||
const Point<float> newTopRight (corners[0] + Point<float> (top.getLength(), 0.0f));
|
||||
const Point<float> newBottomLeft (corners[0] + Point<float> (0.0f, left.getLength()));
|
||||
|
||||
topRight.moveToAbsolute (newTopRight, scope);
|
||||
bottomLeft.moveToAbsolute (newBottomLeft, scope);
|
||||
|
||||
return AffineTransform::fromTargetPoints (corners[0].getX(), corners[0].getY(), corners[0].getX(), corners[0].getY(),
|
||||
corners[1].getX(), corners[1].getY(), newTopRight.getX(), newTopRight.getY(),
|
||||
corners[2].getX(), corners[2].getY(), newBottomLeft.getX(), newBottomLeft.getY());
|
||||
}
|
||||
|
||||
bool RelativeParallelogram::isDynamic() const
|
||||
{
|
||||
return topLeft.isDynamic() || topRight.isDynamic() || bottomLeft.isDynamic();
|
||||
}
|
||||
|
||||
bool RelativeParallelogram::operator== (const RelativeParallelogram& other) const noexcept
|
||||
{
|
||||
return topLeft == other.topLeft && topRight == other.topRight && bottomLeft == other.bottomLeft;
|
||||
}
|
||||
|
||||
bool RelativeParallelogram::operator!= (const RelativeParallelogram& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
const Point<float> RelativeParallelogram::getInternalCoordForPoint (const Point<float>* const corners, Point<float> target) noexcept
|
||||
{
|
||||
const Point<float> tr (corners[1] - corners[0]);
|
||||
const Point<float> bl (corners[2] - corners[0]);
|
||||
target -= corners[0];
|
||||
|
||||
return Point<float> (Line<float> (Point<float>(), tr).getIntersection (Line<float> (target, target - bl)).getDistanceFromOrigin(),
|
||||
Line<float> (Point<float>(), bl).getIntersection (Line<float> (target, target - tr)).getDistanceFromOrigin());
|
||||
}
|
||||
|
||||
const Point<float> RelativeParallelogram::getPointForInternalCoord (const Point<float>* const corners, const Point<float>& point) noexcept
|
||||
{
|
||||
return corners[0]
|
||||
+ Line<float> (Point<float>(), corners[1] - corners[0]).getPointAlongLine (point.getX())
|
||||
+ Line<float> (Point<float>(), corners[2] - corners[0]).getPointAlongLine (point.getY());
|
||||
}
|
||||
|
||||
const Rectangle<float> RelativeParallelogram::getBoundingBox (const Point<float>* const p) noexcept
|
||||
{
|
||||
const Point<float> points[] = { p[0], p[1], p[2], p[1] + (p[2] - p[0]) };
|
||||
return Rectangle<float>::findAreaContainingPoints (points, 4);
|
||||
}
|
||||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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 __JUCE_RELATIVEPARALLELOGRAM_JUCEHEADER__
|
||||
#define __JUCE_RELATIVEPARALLELOGRAM_JUCEHEADER__
|
||||
|
||||
#include "juce_RelativePoint.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A parallelogram defined by three RelativePoint positions.
|
||||
|
||||
@see RelativePoint, RelativeCoordinate
|
||||
*/
|
||||
class JUCE_API RelativeParallelogram
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
RelativeParallelogram();
|
||||
RelativeParallelogram (const Rectangle<float>& simpleRectangle);
|
||||
RelativeParallelogram (const RelativePoint& topLeft, const RelativePoint& topRight, const RelativePoint& bottomLeft);
|
||||
RelativeParallelogram (const String& topLeft, const String& topRight, const String& bottomLeft);
|
||||
~RelativeParallelogram();
|
||||
|
||||
//==============================================================================
|
||||
void resolveThreePoints (Point<float>* points, Expression::Scope* scope) const;
|
||||
void resolveFourCorners (Point<float>* points, Expression::Scope* scope) const;
|
||||
const Rectangle<float> getBounds (Expression::Scope* scope) const;
|
||||
void getPath (Path& path, Expression::Scope* scope) const;
|
||||
const AffineTransform resetToPerpendicular (Expression::Scope* scope);
|
||||
bool isDynamic() const;
|
||||
|
||||
bool operator== (const RelativeParallelogram& other) const noexcept;
|
||||
bool operator!= (const RelativeParallelogram& other) const noexcept;
|
||||
|
||||
static const Point<float> getInternalCoordForPoint (const Point<float>* parallelogramCorners, Point<float> point) noexcept;
|
||||
static const Point<float> getPointForInternalCoord (const Point<float>* parallelogramCorners, const Point<float>& internalPoint) noexcept;
|
||||
static const Rectangle<float> getBoundingBox (const Point<float>* parallelogramCorners) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
RelativePoint topLeft, topRight, bottomLeft;
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCE_RELATIVEPARALLELOGRAM_JUCEHEADER__
|
||||
100
modules/juce_gui_basics/positioning/juce_RelativePoint.cpp
Normal file
100
modules/juce_gui_basics/positioning/juce_RelativePoint.cpp
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
namespace RelativePointHelpers
|
||||
{
|
||||
inline void skipComma (String::CharPointerType& s)
|
||||
{
|
||||
s = s.findEndOfWhitespace();
|
||||
|
||||
if (*s == ',')
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
RelativePoint::RelativePoint()
|
||||
{
|
||||
}
|
||||
|
||||
RelativePoint::RelativePoint (const Point<float>& absolutePoint)
|
||||
: x (absolutePoint.getX()), y (absolutePoint.getY())
|
||||
{
|
||||
}
|
||||
|
||||
RelativePoint::RelativePoint (const float x_, const float y_)
|
||||
: x (x_), y (y_)
|
||||
{
|
||||
}
|
||||
|
||||
RelativePoint::RelativePoint (const RelativeCoordinate& x_, const RelativeCoordinate& y_)
|
||||
: x (x_), y (y_)
|
||||
{
|
||||
}
|
||||
|
||||
RelativePoint::RelativePoint (const String& s)
|
||||
{
|
||||
String::CharPointerType text (s.getCharPointer());
|
||||
x = RelativeCoordinate (Expression::parse (text));
|
||||
RelativePointHelpers::skipComma (text);
|
||||
y = RelativeCoordinate (Expression::parse (text));
|
||||
}
|
||||
|
||||
bool RelativePoint::operator== (const RelativePoint& other) const noexcept
|
||||
{
|
||||
return x == other.x && y == other.y;
|
||||
}
|
||||
|
||||
bool RelativePoint::operator!= (const RelativePoint& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
const Point<float> RelativePoint::resolve (const Expression::Scope* scope) const
|
||||
{
|
||||
return Point<float> ((float) x.resolve (scope),
|
||||
(float) y.resolve (scope));
|
||||
}
|
||||
|
||||
void RelativePoint::moveToAbsolute (const Point<float>& newPos, const Expression::Scope* scope)
|
||||
{
|
||||
x.moveToAbsolute (newPos.getX(), scope);
|
||||
y.moveToAbsolute (newPos.getY(), scope);
|
||||
}
|
||||
|
||||
String RelativePoint::toString() const
|
||||
{
|
||||
return x.toString() + ", " + y.toString();
|
||||
}
|
||||
|
||||
bool RelativePoint::isDynamic() const
|
||||
{
|
||||
return x.isDynamic() || y.isDynamic();
|
||||
}
|
||||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
93
modules/juce_gui_basics/positioning/juce_RelativePoint.h
Normal file
93
modules/juce_gui_basics/positioning/juce_RelativePoint.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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 __JUCE_RELATIVEPOINT_JUCEHEADER__
|
||||
#define __JUCE_RELATIVEPOINT_JUCEHEADER__
|
||||
|
||||
#include "juce_RelativeCoordinate.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
An X-Y position stored as a pair of RelativeCoordinate values.
|
||||
|
||||
@see RelativeCoordinate, RelativeRectangle
|
||||
*/
|
||||
class JUCE_API RelativePoint
|
||||
{
|
||||
public:
|
||||
/** Creates a point at the origin. */
|
||||
RelativePoint();
|
||||
|
||||
/** Creates an absolute point, relative to the origin. */
|
||||
RelativePoint (const Point<float>& absolutePoint);
|
||||
|
||||
/** Creates an absolute point, relative to the origin. */
|
||||
RelativePoint (float absoluteX, float absoluteY);
|
||||
|
||||
/** Creates an absolute point from two coordinates. */
|
||||
RelativePoint (const RelativeCoordinate& x, const RelativeCoordinate& y);
|
||||
|
||||
/** Creates a point from a stringified representation.
|
||||
The string must contain a pair of coordinates, separated by space or a comma. The syntax for the coordinate
|
||||
strings is explained in the RelativeCoordinate class.
|
||||
@see toString
|
||||
*/
|
||||
RelativePoint (const String& stringVersion);
|
||||
|
||||
bool operator== (const RelativePoint& other) const noexcept;
|
||||
bool operator!= (const RelativePoint& other) const noexcept;
|
||||
|
||||
/** Calculates the absolute position of this point.
|
||||
|
||||
You'll need to provide a suitable Expression::Scope for looking up any coordinates that may
|
||||
be needed to calculate the result.
|
||||
*/
|
||||
const Point<float> resolve (const Expression::Scope* evaluationContext) const;
|
||||
|
||||
/** Changes the values of this point's coordinates to make it resolve to the specified position.
|
||||
|
||||
Calling this will leave any anchor points unchanged, but will set any absolute
|
||||
or relative positions to whatever values are necessary to make the resultant position
|
||||
match the position that is provided.
|
||||
*/
|
||||
void moveToAbsolute (const Point<float>& newPos, const Expression::Scope* evaluationContext);
|
||||
|
||||
/** Returns a string which represents this point.
|
||||
This returns a comma-separated pair of coordinates. For details of the string syntax used by the
|
||||
coordinates, see the RelativeCoordinate constructor notes.
|
||||
The string that is returned can be passed to the RelativePoint constructor to recreate the point.
|
||||
*/
|
||||
String toString() const;
|
||||
|
||||
/** Returns true if this point depends on any other coordinates for its position. */
|
||||
bool isDynamic() const;
|
||||
|
||||
// The actual X and Y coords...
|
||||
RelativeCoordinate x, y;
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCE_RELATIVEPOINT_JUCEHEADER__
|
||||
299
modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp
Normal file
299
modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
//==============================================================================
|
||||
RelativePointPath::RelativePointPath()
|
||||
: usesNonZeroWinding (true),
|
||||
containsDynamicPoints (false)
|
||||
{
|
||||
}
|
||||
|
||||
RelativePointPath::RelativePointPath (const RelativePointPath& other)
|
||||
: usesNonZeroWinding (true),
|
||||
containsDynamicPoints (false)
|
||||
{
|
||||
for (int i = 0; i < other.elements.size(); ++i)
|
||||
elements.add (other.elements.getUnchecked(i)->clone());
|
||||
}
|
||||
|
||||
RelativePointPath::RelativePointPath (const Path& path)
|
||||
: usesNonZeroWinding (path.isUsingNonZeroWinding()),
|
||||
containsDynamicPoints (false)
|
||||
{
|
||||
for (Path::Iterator i (path); i.next();)
|
||||
{
|
||||
switch (i.elementType)
|
||||
{
|
||||
case Path::Iterator::startNewSubPath: elements.add (new StartSubPath (RelativePoint (i.x1, i.y1))); break;
|
||||
case Path::Iterator::lineTo: elements.add (new LineTo (RelativePoint (i.x1, i.y1))); break;
|
||||
case Path::Iterator::quadraticTo: elements.add (new QuadraticTo (RelativePoint (i.x1, i.y1), RelativePoint (i.x2, i.y2))); break;
|
||||
case Path::Iterator::cubicTo: elements.add (new CubicTo (RelativePoint (i.x1, i.y1), RelativePoint (i.x2, i.y2), RelativePoint (i.x3, i.y3))); break;
|
||||
case Path::Iterator::closePath: elements.add (new CloseSubPath()); break;
|
||||
default: jassertfalse; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RelativePointPath::~RelativePointPath()
|
||||
{
|
||||
}
|
||||
|
||||
bool RelativePointPath::operator== (const RelativePointPath& other) const noexcept
|
||||
{
|
||||
if (elements.size() != other.elements.size()
|
||||
|| usesNonZeroWinding != other.usesNonZeroWinding
|
||||
|| containsDynamicPoints != other.containsDynamicPoints)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < elements.size(); ++i)
|
||||
{
|
||||
ElementBase* const e1 = elements.getUnchecked(i);
|
||||
ElementBase* const e2 = other.elements.getUnchecked(i);
|
||||
|
||||
if (e1->type != e2->type)
|
||||
return false;
|
||||
|
||||
int numPoints1, numPoints2;
|
||||
const RelativePoint* const points1 = e1->getControlPoints (numPoints1);
|
||||
const RelativePoint* const points2 = e2->getControlPoints (numPoints2);
|
||||
|
||||
jassert (numPoints1 == numPoints2);
|
||||
|
||||
for (int j = numPoints1; --j >= 0;)
|
||||
if (points1[j] != points2[j])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RelativePointPath::operator!= (const RelativePointPath& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
void RelativePointPath::swapWith (RelativePointPath& other) noexcept
|
||||
{
|
||||
elements.swapWithArray (other.elements);
|
||||
std::swap (usesNonZeroWinding, other.usesNonZeroWinding);
|
||||
std::swap (containsDynamicPoints, other.containsDynamicPoints);
|
||||
}
|
||||
|
||||
void RelativePointPath::createPath (Path& path, Expression::Scope* scope) const
|
||||
{
|
||||
for (int i = 0; i < elements.size(); ++i)
|
||||
elements.getUnchecked(i)->addToPath (path, scope);
|
||||
}
|
||||
|
||||
bool RelativePointPath::containsAnyDynamicPoints() const
|
||||
{
|
||||
return containsDynamicPoints;
|
||||
}
|
||||
|
||||
void RelativePointPath::addElement (ElementBase* newElement)
|
||||
{
|
||||
if (newElement != nullptr)
|
||||
{
|
||||
elements.add (newElement);
|
||||
containsDynamicPoints = containsDynamicPoints || newElement->isDynamic();
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
RelativePointPath::ElementBase::ElementBase (const ElementType type_) : type (type_)
|
||||
{
|
||||
}
|
||||
|
||||
bool RelativePointPath::ElementBase::isDynamic()
|
||||
{
|
||||
int numPoints;
|
||||
const RelativePoint* const points = getControlPoints (numPoints);
|
||||
|
||||
for (int i = numPoints; --i >= 0;)
|
||||
if (points[i].isDynamic())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
RelativePointPath::StartSubPath::StartSubPath (const RelativePoint& pos)
|
||||
: ElementBase (startSubPathElement), startPos (pos)
|
||||
{
|
||||
}
|
||||
|
||||
ValueTree RelativePointPath::StartSubPath::createTree() const
|
||||
{
|
||||
ValueTree v (DrawablePath::ValueTreeWrapper::Element::startSubPathElement);
|
||||
v.setProperty (DrawablePath::ValueTreeWrapper::point1, startPos.toString(), nullptr);
|
||||
return v;
|
||||
}
|
||||
|
||||
void RelativePointPath::StartSubPath::addToPath (Path& path, Expression::Scope* scope) const
|
||||
{
|
||||
path.startNewSubPath (startPos.resolve (scope));
|
||||
}
|
||||
|
||||
RelativePoint* RelativePointPath::StartSubPath::getControlPoints (int& numPoints)
|
||||
{
|
||||
numPoints = 1;
|
||||
return &startPos;
|
||||
}
|
||||
|
||||
RelativePointPath::ElementBase* RelativePointPath::StartSubPath::clone() const
|
||||
{
|
||||
return new StartSubPath (startPos);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
RelativePointPath::CloseSubPath::CloseSubPath()
|
||||
: ElementBase (closeSubPathElement)
|
||||
{
|
||||
}
|
||||
|
||||
ValueTree RelativePointPath::CloseSubPath::createTree() const
|
||||
{
|
||||
return ValueTree (DrawablePath::ValueTreeWrapper::Element::closeSubPathElement);
|
||||
}
|
||||
|
||||
void RelativePointPath::CloseSubPath::addToPath (Path& path, Expression::Scope*) const
|
||||
{
|
||||
path.closeSubPath();
|
||||
}
|
||||
|
||||
RelativePoint* RelativePointPath::CloseSubPath::getControlPoints (int& numPoints)
|
||||
{
|
||||
numPoints = 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RelativePointPath::ElementBase* RelativePointPath::CloseSubPath::clone() const
|
||||
{
|
||||
return new CloseSubPath();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
RelativePointPath::LineTo::LineTo (const RelativePoint& endPoint_)
|
||||
: ElementBase (lineToElement), endPoint (endPoint_)
|
||||
{
|
||||
}
|
||||
|
||||
ValueTree RelativePointPath::LineTo::createTree() const
|
||||
{
|
||||
ValueTree v (DrawablePath::ValueTreeWrapper::Element::lineToElement);
|
||||
v.setProperty (DrawablePath::ValueTreeWrapper::point1, endPoint.toString(), nullptr);
|
||||
return v;
|
||||
}
|
||||
|
||||
void RelativePointPath::LineTo::addToPath (Path& path, Expression::Scope* scope) const
|
||||
{
|
||||
path.lineTo (endPoint.resolve (scope));
|
||||
}
|
||||
|
||||
RelativePoint* RelativePointPath::LineTo::getControlPoints (int& numPoints)
|
||||
{
|
||||
numPoints = 1;
|
||||
return &endPoint;
|
||||
}
|
||||
|
||||
RelativePointPath::ElementBase* RelativePointPath::LineTo::clone() const
|
||||
{
|
||||
return new LineTo (endPoint);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
RelativePointPath::QuadraticTo::QuadraticTo (const RelativePoint& controlPoint, const RelativePoint& endPoint)
|
||||
: ElementBase (quadraticToElement)
|
||||
{
|
||||
controlPoints[0] = controlPoint;
|
||||
controlPoints[1] = endPoint;
|
||||
}
|
||||
|
||||
ValueTree RelativePointPath::QuadraticTo::createTree() const
|
||||
{
|
||||
ValueTree v (DrawablePath::ValueTreeWrapper::Element::quadraticToElement);
|
||||
v.setProperty (DrawablePath::ValueTreeWrapper::point1, controlPoints[0].toString(), nullptr);
|
||||
v.setProperty (DrawablePath::ValueTreeWrapper::point2, controlPoints[1].toString(), nullptr);
|
||||
return v;
|
||||
}
|
||||
|
||||
void RelativePointPath::QuadraticTo::addToPath (Path& path, Expression::Scope* scope) const
|
||||
{
|
||||
path.quadraticTo (controlPoints[0].resolve (scope),
|
||||
controlPoints[1].resolve (scope));
|
||||
}
|
||||
|
||||
RelativePoint* RelativePointPath::QuadraticTo::getControlPoints (int& numPoints)
|
||||
{
|
||||
numPoints = 2;
|
||||
return controlPoints;
|
||||
}
|
||||
|
||||
RelativePointPath::ElementBase* RelativePointPath::QuadraticTo::clone() const
|
||||
{
|
||||
return new QuadraticTo (controlPoints[0], controlPoints[1]);
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
RelativePointPath::CubicTo::CubicTo (const RelativePoint& controlPoint1, const RelativePoint& controlPoint2, const RelativePoint& endPoint)
|
||||
: ElementBase (cubicToElement)
|
||||
{
|
||||
controlPoints[0] = controlPoint1;
|
||||
controlPoints[1] = controlPoint2;
|
||||
controlPoints[2] = endPoint;
|
||||
}
|
||||
|
||||
ValueTree RelativePointPath::CubicTo::createTree() const
|
||||
{
|
||||
ValueTree v (DrawablePath::ValueTreeWrapper::Element::cubicToElement);
|
||||
v.setProperty (DrawablePath::ValueTreeWrapper::point1, controlPoints[0].toString(), nullptr);
|
||||
v.setProperty (DrawablePath::ValueTreeWrapper::point2, controlPoints[1].toString(), nullptr);
|
||||
v.setProperty (DrawablePath::ValueTreeWrapper::point3, controlPoints[2].toString(), nullptr);
|
||||
return v;
|
||||
}
|
||||
|
||||
void RelativePointPath::CubicTo::addToPath (Path& path, Expression::Scope* scope) const
|
||||
{
|
||||
path.cubicTo (controlPoints[0].resolve (scope),
|
||||
controlPoints[1].resolve (scope),
|
||||
controlPoints[2].resolve (scope));
|
||||
}
|
||||
|
||||
RelativePoint* RelativePointPath::CubicTo::getControlPoints (int& numPoints)
|
||||
{
|
||||
numPoints = 3;
|
||||
return controlPoints;
|
||||
}
|
||||
|
||||
RelativePointPath::ElementBase* RelativePointPath::CubicTo::clone() const
|
||||
{
|
||||
return new CubicTo (controlPoints[0], controlPoints[1], controlPoints[2]);
|
||||
}
|
||||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
194
modules/juce_gui_basics/positioning/juce_RelativePointPath.h
Normal file
194
modules/juce_gui_basics/positioning/juce_RelativePointPath.h
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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 __JUCE_RELATIVEPOINTPATH_JUCEHEADER__
|
||||
#define __JUCE_RELATIVEPOINTPATH_JUCEHEADER__
|
||||
|
||||
#include "juce_RelativePoint.h"
|
||||
class DrawablePath;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A path object that consists of RelativePoint coordinates rather than the normal fixed ones.
|
||||
|
||||
One of these paths can be converted into a Path object for drawing and manipulation, but
|
||||
unlike a Path, its points can be dynamic instead of just fixed.
|
||||
|
||||
@see RelativePoint, RelativeCoordinate
|
||||
*/
|
||||
class JUCE_API RelativePointPath
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
RelativePointPath();
|
||||
RelativePointPath (const RelativePointPath& other);
|
||||
explicit RelativePointPath (const Path& path);
|
||||
~RelativePointPath();
|
||||
|
||||
bool operator== (const RelativePointPath& other) const noexcept;
|
||||
bool operator!= (const RelativePointPath& other) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Resolves this points in this path and adds them to a normal Path object. */
|
||||
void createPath (Path& path, Expression::Scope* scope) const;
|
||||
|
||||
/** Returns true if the path contains any non-fixed points. */
|
||||
bool containsAnyDynamicPoints() const;
|
||||
|
||||
/** Quickly swaps the contents of this path with another. */
|
||||
void swapWith (RelativePointPath& other) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** The types of element that may be contained in this path.
|
||||
@see RelativePointPath::ElementBase
|
||||
*/
|
||||
enum ElementType
|
||||
{
|
||||
nullElement,
|
||||
startSubPathElement,
|
||||
closeSubPathElement,
|
||||
lineToElement,
|
||||
quadraticToElement,
|
||||
cubicToElement
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Base class for the elements that make up a RelativePointPath.
|
||||
*/
|
||||
class JUCE_API ElementBase
|
||||
{
|
||||
public:
|
||||
ElementBase (ElementType type);
|
||||
virtual ~ElementBase() {}
|
||||
virtual ValueTree createTree() const = 0;
|
||||
virtual void addToPath (Path& path, Expression::Scope*) const = 0;
|
||||
virtual RelativePoint* getControlPoints (int& numPoints) = 0;
|
||||
virtual ElementBase* clone() const = 0;
|
||||
bool isDynamic();
|
||||
|
||||
const ElementType type;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE (ElementBase);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class JUCE_API StartSubPath : public ElementBase
|
||||
{
|
||||
public:
|
||||
StartSubPath (const RelativePoint& pos);
|
||||
ValueTree createTree() const;
|
||||
void addToPath (Path& path, Expression::Scope*) const;
|
||||
RelativePoint* getControlPoints (int& numPoints);
|
||||
ElementBase* clone() const;
|
||||
|
||||
RelativePoint startPos;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE (StartSubPath);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class JUCE_API CloseSubPath : public ElementBase
|
||||
{
|
||||
public:
|
||||
CloseSubPath();
|
||||
ValueTree createTree() const;
|
||||
void addToPath (Path& path, Expression::Scope*) const;
|
||||
RelativePoint* getControlPoints (int& numPoints);
|
||||
ElementBase* clone() const;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE (CloseSubPath);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class JUCE_API LineTo : public ElementBase
|
||||
{
|
||||
public:
|
||||
LineTo (const RelativePoint& endPoint);
|
||||
ValueTree createTree() const;
|
||||
void addToPath (Path& path, Expression::Scope*) const;
|
||||
RelativePoint* getControlPoints (int& numPoints);
|
||||
ElementBase* clone() const;
|
||||
|
||||
RelativePoint endPoint;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE (LineTo);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class JUCE_API QuadraticTo : public ElementBase
|
||||
{
|
||||
public:
|
||||
QuadraticTo (const RelativePoint& controlPoint, const RelativePoint& endPoint);
|
||||
ValueTree createTree() const;
|
||||
void addToPath (Path& path, Expression::Scope*) const;
|
||||
RelativePoint* getControlPoints (int& numPoints);
|
||||
ElementBase* clone() const;
|
||||
|
||||
RelativePoint controlPoints[2];
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE (QuadraticTo);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class JUCE_API CubicTo : public ElementBase
|
||||
{
|
||||
public:
|
||||
CubicTo (const RelativePoint& controlPoint1, const RelativePoint& controlPoint2, const RelativePoint& endPoint);
|
||||
ValueTree createTree() const;
|
||||
void addToPath (Path& path, Expression::Scope*) const;
|
||||
RelativePoint* getControlPoints (int& numPoints);
|
||||
ElementBase* clone() const;
|
||||
|
||||
RelativePoint controlPoints[3];
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE (CubicTo);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
void addElement (ElementBase* newElement);
|
||||
|
||||
//==============================================================================
|
||||
OwnedArray <ElementBase> elements;
|
||||
bool usesNonZeroWinding;
|
||||
|
||||
private:
|
||||
class Positioner;
|
||||
friend class Positioner;
|
||||
bool containsDynamicPoints;
|
||||
|
||||
void applyTo (DrawablePath& path) const;
|
||||
|
||||
RelativePointPath& operator= (const RelativePointPath&);
|
||||
JUCE_LEAK_DETECTOR (RelativePointPath);
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCE_RELATIVEPOINTPATH_JUCEHEADER__
|
||||
268
modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp
Normal file
268
modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
//==============================================================================
|
||||
namespace RelativeRectangleHelpers
|
||||
{
|
||||
inline void skipComma (String::CharPointerType& s)
|
||||
{
|
||||
s = s.findEndOfWhitespace();
|
||||
|
||||
if (*s == ',')
|
||||
++s;
|
||||
}
|
||||
|
||||
bool dependsOnSymbolsOtherThanThis (const Expression& e)
|
||||
{
|
||||
if (e.getType() == Expression::operatorType && e.getSymbolOrFunction() == ".")
|
||||
return true;
|
||||
|
||||
if (e.getType() == Expression::symbolType)
|
||||
{
|
||||
switch (RelativeCoordinate::StandardStrings::getTypeOf (e.getSymbolOrFunction()))
|
||||
{
|
||||
case RelativeCoordinate::StandardStrings::x:
|
||||
case RelativeCoordinate::StandardStrings::y:
|
||||
case RelativeCoordinate::StandardStrings::left:
|
||||
case RelativeCoordinate::StandardStrings::right:
|
||||
case RelativeCoordinate::StandardStrings::top:
|
||||
case RelativeCoordinate::StandardStrings::bottom: return false;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = e.getNumInputs(); --i >= 0;)
|
||||
if (dependsOnSymbolsOtherThanThis (e.getInput(i)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
RelativeRectangle::RelativeRectangle()
|
||||
{
|
||||
}
|
||||
|
||||
RelativeRectangle::RelativeRectangle (const RelativeCoordinate& left_, const RelativeCoordinate& right_,
|
||||
const RelativeCoordinate& top_, const RelativeCoordinate& bottom_)
|
||||
: left (left_), right (right_), top (top_), bottom (bottom_)
|
||||
{
|
||||
}
|
||||
|
||||
RelativeRectangle::RelativeRectangle (const Rectangle<float>& rect)
|
||||
: left (rect.getX()),
|
||||
right (Expression::symbol (RelativeCoordinate::Strings::left) + Expression ((double) rect.getWidth())),
|
||||
top (rect.getY()),
|
||||
bottom (Expression::symbol (RelativeCoordinate::Strings::top) + Expression ((double) rect.getHeight()))
|
||||
{
|
||||
}
|
||||
|
||||
RelativeRectangle::RelativeRectangle (const String& s)
|
||||
{
|
||||
String::CharPointerType text (s.getCharPointer());
|
||||
left = RelativeCoordinate (Expression::parse (text));
|
||||
RelativeRectangleHelpers::skipComma (text);
|
||||
top = RelativeCoordinate (Expression::parse (text));
|
||||
RelativeRectangleHelpers::skipComma (text);
|
||||
right = RelativeCoordinate (Expression::parse (text));
|
||||
RelativeRectangleHelpers::skipComma (text);
|
||||
bottom = RelativeCoordinate (Expression::parse (text));
|
||||
}
|
||||
|
||||
bool RelativeRectangle::operator== (const RelativeRectangle& other) const noexcept
|
||||
{
|
||||
return left == other.left && top == other.top && right == other.right && bottom == other.bottom;
|
||||
}
|
||||
|
||||
bool RelativeRectangle::operator!= (const RelativeRectangle& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// An expression context that can evaluate expressions using "this"
|
||||
class RelativeRectangleLocalScope : public Expression::Scope
|
||||
{
|
||||
public:
|
||||
RelativeRectangleLocalScope (const RelativeRectangle& rect_) : rect (rect_) {}
|
||||
|
||||
Expression getSymbolValue (const String& symbol) const
|
||||
{
|
||||
switch (RelativeCoordinate::StandardStrings::getTypeOf (symbol))
|
||||
{
|
||||
case RelativeCoordinate::StandardStrings::x:
|
||||
case RelativeCoordinate::StandardStrings::left: return rect.left.getExpression();
|
||||
case RelativeCoordinate::StandardStrings::y:
|
||||
case RelativeCoordinate::StandardStrings::top: return rect.top.getExpression();
|
||||
case RelativeCoordinate::StandardStrings::right: return rect.right.getExpression();
|
||||
case RelativeCoordinate::StandardStrings::bottom: return rect.bottom.getExpression();
|
||||
default: break;
|
||||
}
|
||||
|
||||
return Expression::Scope::getSymbolValue (symbol);
|
||||
}
|
||||
|
||||
private:
|
||||
const RelativeRectangle& rect;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (RelativeRectangleLocalScope);
|
||||
};
|
||||
|
||||
const Rectangle<float> RelativeRectangle::resolve (const Expression::Scope* scope) const
|
||||
{
|
||||
if (scope == nullptr)
|
||||
{
|
||||
RelativeRectangleLocalScope defaultScope (*this);
|
||||
return resolve (&defaultScope);
|
||||
}
|
||||
else
|
||||
{
|
||||
const double l = left.resolve (scope);
|
||||
const double r = right.resolve (scope);
|
||||
const double t = top.resolve (scope);
|
||||
const double b = bottom.resolve (scope);
|
||||
|
||||
return Rectangle<float> ((float) l, (float) t, (float) jmax (0.0, r - l), (float) jmax (0.0, b - t));
|
||||
}
|
||||
}
|
||||
|
||||
void RelativeRectangle::moveToAbsolute (const Rectangle<float>& newPos, const Expression::Scope* scope)
|
||||
{
|
||||
left.moveToAbsolute (newPos.getX(), scope);
|
||||
right.moveToAbsolute (newPos.getRight(), scope);
|
||||
top.moveToAbsolute (newPos.getY(), scope);
|
||||
bottom.moveToAbsolute (newPos.getBottom(), scope);
|
||||
}
|
||||
|
||||
bool RelativeRectangle::isDynamic() const
|
||||
{
|
||||
using namespace RelativeRectangleHelpers;
|
||||
|
||||
return dependsOnSymbolsOtherThanThis (left.getExpression())
|
||||
|| dependsOnSymbolsOtherThanThis (right.getExpression())
|
||||
|| dependsOnSymbolsOtherThanThis (top.getExpression())
|
||||
|| dependsOnSymbolsOtherThanThis (bottom.getExpression());
|
||||
}
|
||||
|
||||
String RelativeRectangle::toString() const
|
||||
{
|
||||
return left.toString() + ", " + top.toString() + ", " + right.toString() + ", " + bottom.toString();
|
||||
}
|
||||
|
||||
void RelativeRectangle::renameSymbol (const Expression::Symbol& oldSymbol, const String& newName, const Expression::Scope& scope)
|
||||
{
|
||||
left = left.getExpression().withRenamedSymbol (oldSymbol, newName, scope);
|
||||
right = right.getExpression().withRenamedSymbol (oldSymbol, newName, scope);
|
||||
top = top.getExpression().withRenamedSymbol (oldSymbol, newName, scope);
|
||||
bottom = bottom.getExpression().withRenamedSymbol (oldSymbol, newName, scope);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class RelativeRectangleComponentPositioner : public RelativeCoordinatePositionerBase
|
||||
{
|
||||
public:
|
||||
RelativeRectangleComponentPositioner (Component& component_, const RelativeRectangle& rectangle_)
|
||||
: RelativeCoordinatePositionerBase (component_),
|
||||
rectangle (rectangle_)
|
||||
{
|
||||
}
|
||||
|
||||
bool registerCoordinates()
|
||||
{
|
||||
bool ok = addCoordinate (rectangle.left);
|
||||
ok = addCoordinate (rectangle.right) && ok;
|
||||
ok = addCoordinate (rectangle.top) && ok;
|
||||
ok = addCoordinate (rectangle.bottom) && ok;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool isUsingRectangle (const RelativeRectangle& other) const noexcept
|
||||
{
|
||||
return rectangle == other;
|
||||
}
|
||||
|
||||
void applyToComponentBounds()
|
||||
{
|
||||
for (int i = 4; --i >= 0;)
|
||||
{
|
||||
ComponentScope scope (getComponent());
|
||||
const Rectangle<int> newBounds (rectangle.resolve (&scope).getSmallestIntegerContainer());
|
||||
|
||||
if (newBounds == getComponent().getBounds())
|
||||
return;
|
||||
|
||||
getComponent().setBounds (newBounds);
|
||||
}
|
||||
|
||||
jassertfalse; // must be a recursive reference!
|
||||
}
|
||||
|
||||
void applyNewBounds (const Rectangle<int>& newBounds)
|
||||
{
|
||||
if (newBounds != getComponent().getBounds())
|
||||
{
|
||||
ComponentScope scope (getComponent());
|
||||
rectangle.moveToAbsolute (newBounds.toFloat(), &scope);
|
||||
|
||||
applyToComponentBounds();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
RelativeRectangle rectangle;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RelativeRectangleComponentPositioner);
|
||||
};
|
||||
|
||||
void RelativeRectangle::applyToComponent (Component& component) const
|
||||
{
|
||||
if (isDynamic())
|
||||
{
|
||||
RelativeRectangleComponentPositioner* current = dynamic_cast <RelativeRectangleComponentPositioner*> (component.getPositioner());
|
||||
|
||||
if (current == nullptr || ! current->isUsingRectangle (*this))
|
||||
{
|
||||
RelativeRectangleComponentPositioner* p = new RelativeRectangleComponentPositioner (component, *this);
|
||||
|
||||
component.setPositioner (p);
|
||||
p->apply();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
component.setPositioner (nullptr);
|
||||
component.setBounds (resolve (nullptr).getSmallestIntegerContainer());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
109
modules/juce_gui_basics/positioning/juce_RelativeRectangle.h
Normal file
109
modules/juce_gui_basics/positioning/juce_RelativeRectangle.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-11 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 __JUCE_RELATIVERECTANGLE_JUCEHEADER__
|
||||
#define __JUCE_RELATIVERECTANGLE_JUCEHEADER__
|
||||
|
||||
#include "juce_RelativeCoordinate.h"
|
||||
class Component;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
An rectangle stored as a set of RelativeCoordinate values.
|
||||
|
||||
The rectangle's top, left, bottom and right edge positions are each stored as a RelativeCoordinate.
|
||||
|
||||
@see RelativeCoordinate, RelativePoint
|
||||
*/
|
||||
class JUCE_API RelativeRectangle
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a zero-size rectangle at the origin. */
|
||||
RelativeRectangle();
|
||||
|
||||
/** Creates an absolute rectangle, relative to the origin. */
|
||||
explicit RelativeRectangle (const Rectangle<float>& rect);
|
||||
|
||||
/** Creates a rectangle from four coordinates. */
|
||||
RelativeRectangle (const RelativeCoordinate& left, const RelativeCoordinate& right,
|
||||
const RelativeCoordinate& top, const RelativeCoordinate& bottom);
|
||||
|
||||
/** Creates a rectangle from a stringified representation.
|
||||
The string must contain a sequence of 4 coordinates, separated by commas, in the order
|
||||
left, top, right, bottom. The syntax for the coordinate strings is explained in the
|
||||
RelativeCoordinate class.
|
||||
@see toString
|
||||
*/
|
||||
explicit RelativeRectangle (const String& stringVersion);
|
||||
|
||||
bool operator== (const RelativeRectangle& other) const noexcept;
|
||||
bool operator!= (const RelativeRectangle& other) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Calculates the absolute position of this rectangle.
|
||||
|
||||
You'll need to provide a suitable Expression::Scope for looking up any coordinates that may
|
||||
be needed to calculate the result.
|
||||
*/
|
||||
const Rectangle<float> resolve (const Expression::Scope* scope) const;
|
||||
|
||||
/** Changes the values of this rectangle's coordinates to make it resolve to the specified position.
|
||||
|
||||
Calling this will leave any anchor points unchanged, but will set any absolute
|
||||
or relative positions to whatever values are necessary to make the resultant position
|
||||
match the position that is provided.
|
||||
*/
|
||||
void moveToAbsolute (const Rectangle<float>& newPos, const Expression::Scope* scope);
|
||||
|
||||
/** Returns true if this rectangle depends on any external symbols for its position.
|
||||
Coordinates that refer to symbols based on "this" are assumed not to be dynamic.
|
||||
*/
|
||||
bool isDynamic() const;
|
||||
|
||||
/** Returns a string which represents this point.
|
||||
This returns a comma-separated list of coordinates, in the order left, top, right, bottom. For details of
|
||||
the string syntax used by the coordinates, see the RelativeCoordinate constructor notes.
|
||||
The string that is returned can be passed to the RelativeRectangle constructor to recreate the rectangle.
|
||||
*/
|
||||
String toString() const;
|
||||
|
||||
/** Renames a symbol if it is used by any of the coordinates.
|
||||
This calls Expression::withRenamedSymbol() on the rectangle's coordinates.
|
||||
*/
|
||||
void renameSymbol (const Expression::Symbol& oldSymbol, const String& newName, const Expression::Scope& scope);
|
||||
|
||||
/** Creates and sets an appropriate Component::Positioner object for the given component, which will
|
||||
keep it positioned with this rectangle.
|
||||
*/
|
||||
void applyToComponent (Component& component) const;
|
||||
|
||||
//==============================================================================
|
||||
// The actual rectangle coords...
|
||||
RelativeCoordinate left, right, top, bottom;
|
||||
};
|
||||
|
||||
|
||||
#endif // __JUCE_RELATIVERECTANGLE_JUCEHEADER__
|
||||
Loading…
Add table
Add a link
Reference in a new issue