1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-27 02:20:05 +00:00

Development on drawables. ValueTree fix.

This commit is contained in:
Julian Storer 2010-06-23 21:51:28 +01:00
parent c8b977a482
commit fad682c1e1
5 changed files with 312 additions and 6 deletions

View file

@ -16649,7 +16649,7 @@ ValueTree ValueTree::getSibling (const int delta) const
return invalid;
const int index = object->parent->indexOf (*this) + delta;
return ValueTree (static_cast <SharedObject*> (object->children [index]));
return ValueTree (static_cast <SharedObject*> (object->parent->children [index]));
}
const var& ValueTree::operator[] (const Identifier& name) const
@ -85597,6 +85597,10 @@ const Identifier DrawablePath::ValueTreeWrapper::Element::lineToElement ("Line")
const Identifier DrawablePath::ValueTreeWrapper::Element::quadraticToElement ("Quad");
const Identifier DrawablePath::ValueTreeWrapper::Element::cubicToElement ("Cubic");
const char* DrawablePath::ValueTreeWrapper::Element::cornerMode = "corner";
const char* DrawablePath::ValueTreeWrapper::Element::roundedMode = "round";
const char* DrawablePath::ValueTreeWrapper::Element::symmetricMode = "symm";
DrawablePath::ValueTreeWrapper::Element::Element (const ValueTree& state_)
: state (state_)
{
@ -85666,6 +85670,33 @@ const RelativePoint DrawablePath::ValueTreeWrapper::Element::getEndPoint() const
return RelativePoint();
}
float DrawablePath::ValueTreeWrapper::Element::getLength (RelativeCoordinate::NamedCoordinateFinder* nameFinder) const
{
const Identifier i (state.getType());
if (i == lineToElement || i == closeSubPathElement)
return getEndPoint().resolve (nameFinder).getDistanceFrom (getStartPoint().resolve (nameFinder));
if (i == cubicToElement)
{
Path p;
p.startNewSubPath (getStartPoint().resolve (nameFinder));
p.cubicTo (getControlPoint (0).resolve (nameFinder), getControlPoint (1).resolve (nameFinder), getControlPoint (2).resolve (nameFinder));
return p.getLength();
}
if (i == quadraticToElement)
{
Path p;
p.startNewSubPath (getStartPoint().resolve (nameFinder));
p.quadraticTo (getControlPoint (0).resolve (nameFinder), getControlPoint (1).resolve (nameFinder));
return p.getLength();
}
jassert (i == startSubPathElement);
return 0;
}
const String DrawablePath::ValueTreeWrapper::Element::getModeOfEndPoint() const
{
return state [mode].toString();
@ -85724,8 +85755,129 @@ void DrawablePath::ValueTreeWrapper::Element::convertToPathBreak (UndoManager* u
}
}
void DrawablePath::ValueTreeWrapper::Element::insertPoint (double, RelativeCoordinate::NamedCoordinateFinder*, UndoManager*)
static const Point<float> findCubicSubdivisionPoint (double proportion, const Point<float> points[4])
{
const Point<float> mid1 (points[0] + (points[1] - points[0]) * proportion),
mid2 (points[1] + (points[2] - points[1]) * proportion),
mid3 (points[2] + (points[3] - points[2]) * proportion);
const Point<float> newCp1 (mid1 + (mid2 - mid1) * proportion),
newCp2 (mid2 + (mid3 - mid2) * proportion);
return newCp1 + (newCp2 - newCp1) * proportion;
}
static const Point<float> findQuadraticSubdivisionPoint (double proportion, const Point<float> points[3])
{
const Point<float> mid1 (points[0] + (points[1] - points[0]) * proportion),
mid2 (points[1] + (points[2] - points[1]) * proportion);
return mid1 + (mid2 - mid1) * proportion;
}
ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager)
{
ValueTree newTree;
const Identifier i (state.getType());
if (i == cubicToElement)
{
RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint());
const Point<float> points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder), rp4.resolve (nameFinder) };
double bestProp = 0;
float bestDistance = std::numeric_limits<float>::max();
for (int i = 110; --i >= 0;)
{
double prop = i > 10 ? ((i - 10) / 100.0) : (bestProp + ((i - 5) / 1000.0));
const Point<float> centre (findCubicSubdivisionPoint (prop, points));
const float distance = centre.getDistanceFrom (targetPoint);
if (distance < bestDistance)
{
bestProp = prop;
bestDistance = distance;
}
}
const Point<float> mid1 (points[0] + (points[1] - points[0]) * bestProp),
mid2 (points[1] + (points[2] - points[1]) * bestProp),
mid3 (points[2] + (points[3] - points[2]) * bestProp);
const Point<float> newCp1 (mid1 + (mid2 - mid1) * bestProp),
newCp2 (mid2 + (mid3 - mid2) * bestProp);
const Point<float> newCentre (newCp1 + (newCp2 - newCp1) * bestProp);
setControlPoint (0, mid1, undoManager);
setControlPoint (1, newCp1, undoManager);
setControlPoint (2, newCentre, undoManager);
setModeOfEndPoint (roundedMode, undoManager);
Element newElement (newTree = ValueTree (cubicToElement));
newElement.setControlPoint (0, newCp2, 0);
newElement.setControlPoint (1, mid3, 0);
newElement.setControlPoint (2, rp4, 0);
state.getParent().addChild (newTree, state.getParent().indexOf (state) + 1, undoManager);
}
else if (i == quadraticToElement)
{
RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint());
const Point<float> points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder) };
double bestProp = 0;
float bestDistance = std::numeric_limits<float>::max();
for (int i = 110; --i >= 0;)
{
double prop = i > 10 ? ((i - 10) / 100.0) : (bestProp + ((i - 5) / 1000.0));
const Point<float> centre (findQuadraticSubdivisionPoint (prop, points));
const float distance = centre.getDistanceFrom (targetPoint);
if (distance < bestDistance)
{
bestProp = prop;
bestDistance = distance;
}
}
const Point<float> mid1 (points[0] + (points[1] - points[0]) * bestProp),
mid2 (points[1] + (points[2] - points[1]) * bestProp);
const Point<float> newCentre (mid1 + (mid2 - mid1) * bestProp);
setControlPoint (0, mid1, undoManager);
setControlPoint (1, newCentre, undoManager);
setModeOfEndPoint (roundedMode, undoManager);
Element newElement (newTree = ValueTree (quadraticToElement));
newElement.setControlPoint (0, mid2, 0);
newElement.setControlPoint (1, rp3, 0);
state.getParent().addChild (newTree, state.getParent().indexOf (state) + 1, undoManager);
}
else if (i == lineToElement)
{
RelativePoint rp1 (getStartPoint()), rp2 (getEndPoint());
const Line<float> line (rp1.resolve (nameFinder), rp2.resolve (nameFinder));
const Point<float> newPoint (line.findNearestPointTo (targetPoint));
setControlPoint (0, newPoint, undoManager);
Element newElement (newTree = ValueTree (lineToElement));
newElement.setControlPoint (0, rp2, 0);
state.getParent().addChild (newTree, state.getParent().indexOf (state) + 1, undoManager);
}
else if (i == closeSubPathElement)
{
}
return newTree;
}
void DrawablePath::ValueTreeWrapper::Element::removePoint (UndoManager* undoManager)

View file

@ -59392,6 +59392,7 @@ public:
const RelativePoint getStartPoint() const;
const RelativePoint getEndPoint() const;
void setControlPoint (int index, const RelativePoint& point, UndoManager* undoManager);
float getLength (RelativeCoordinate::NamedCoordinateFinder* nameFinder) const;
ValueTreeWrapper getParent() const;
Element getPreviousElement() const;
@ -59402,7 +59403,7 @@ public:
void convertToLine (UndoManager* undoManager);
void convertToCubic (RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager);
void convertToPathBreak (UndoManager* undoManager);
void insertPoint (double proportionOfLength, RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager);
ValueTree insertPoint (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager);
void removePoint (UndoManager* undoManager);
static const Identifier mode, startSubPathElement, closeSubPathElement,

View file

@ -616,7 +616,7 @@ ValueTree ValueTree::getSibling (const int delta) const
return invalid;
const int index = object->parent->indexOf (*this) + delta;
return ValueTree (static_cast <SharedObject*> (object->children [index]));
return ValueTree (static_cast <SharedObject*> (object->parent->children [index]));
}
const var& ValueTree::operator[] (const Identifier& name) const

View file

@ -295,6 +295,10 @@ const Identifier DrawablePath::ValueTreeWrapper::Element::lineToElement ("Line")
const Identifier DrawablePath::ValueTreeWrapper::Element::quadraticToElement ("Quad");
const Identifier DrawablePath::ValueTreeWrapper::Element::cubicToElement ("Cubic");
const char* DrawablePath::ValueTreeWrapper::Element::cornerMode = "corner";
const char* DrawablePath::ValueTreeWrapper::Element::roundedMode = "round";
const char* DrawablePath::ValueTreeWrapper::Element::symmetricMode = "symm";
DrawablePath::ValueTreeWrapper::Element::Element (const ValueTree& state_)
: state (state_)
{
@ -364,6 +368,33 @@ const RelativePoint DrawablePath::ValueTreeWrapper::Element::getEndPoint() const
return RelativePoint();
}
float DrawablePath::ValueTreeWrapper::Element::getLength (RelativeCoordinate::NamedCoordinateFinder* nameFinder) const
{
const Identifier i (state.getType());
if (i == lineToElement || i == closeSubPathElement)
return getEndPoint().resolve (nameFinder).getDistanceFrom (getStartPoint().resolve (nameFinder));
if (i == cubicToElement)
{
Path p;
p.startNewSubPath (getStartPoint().resolve (nameFinder));
p.cubicTo (getControlPoint (0).resolve (nameFinder), getControlPoint (1).resolve (nameFinder), getControlPoint (2).resolve (nameFinder));
return p.getLength();
}
if (i == quadraticToElement)
{
Path p;
p.startNewSubPath (getStartPoint().resolve (nameFinder));
p.quadraticTo (getControlPoint (0).resolve (nameFinder), getControlPoint (1).resolve (nameFinder));
return p.getLength();
}
jassert (i == startSubPathElement);
return 0;
}
const String DrawablePath::ValueTreeWrapper::Element::getModeOfEndPoint() const
{
return state [mode].toString();
@ -422,8 +453,129 @@ void DrawablePath::ValueTreeWrapper::Element::convertToPathBreak (UndoManager* u
}
}
void DrawablePath::ValueTreeWrapper::Element::insertPoint (double, RelativeCoordinate::NamedCoordinateFinder*, UndoManager*)
static const Point<float> findCubicSubdivisionPoint (double proportion, const Point<float> points[4])
{
const Point<float> mid1 (points[0] + (points[1] - points[0]) * proportion),
mid2 (points[1] + (points[2] - points[1]) * proportion),
mid3 (points[2] + (points[3] - points[2]) * proportion);
const Point<float> newCp1 (mid1 + (mid2 - mid1) * proportion),
newCp2 (mid2 + (mid3 - mid2) * proportion);
return newCp1 + (newCp2 - newCp1) * proportion;
}
static const Point<float> findQuadraticSubdivisionPoint (double proportion, const Point<float> points[3])
{
const Point<float> mid1 (points[0] + (points[1] - points[0]) * proportion),
mid2 (points[1] + (points[2] - points[1]) * proportion);
return mid1 + (mid2 - mid1) * proportion;
}
ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager)
{
ValueTree newTree;
const Identifier i (state.getType());
if (i == cubicToElement)
{
RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint());
const Point<float> points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder), rp4.resolve (nameFinder) };
double bestProp = 0;
float bestDistance = std::numeric_limits<float>::max();
for (int i = 110; --i >= 0;)
{
double prop = i > 10 ? ((i - 10) / 100.0) : (bestProp + ((i - 5) / 1000.0));
const Point<float> centre (findCubicSubdivisionPoint (prop, points));
const float distance = centre.getDistanceFrom (targetPoint);
if (distance < bestDistance)
{
bestProp = prop;
bestDistance = distance;
}
}
const Point<float> mid1 (points[0] + (points[1] - points[0]) * bestProp),
mid2 (points[1] + (points[2] - points[1]) * bestProp),
mid3 (points[2] + (points[3] - points[2]) * bestProp);
const Point<float> newCp1 (mid1 + (mid2 - mid1) * bestProp),
newCp2 (mid2 + (mid3 - mid2) * bestProp);
const Point<float> newCentre (newCp1 + (newCp2 - newCp1) * bestProp);
setControlPoint (0, mid1, undoManager);
setControlPoint (1, newCp1, undoManager);
setControlPoint (2, newCentre, undoManager);
setModeOfEndPoint (roundedMode, undoManager);
Element newElement (newTree = ValueTree (cubicToElement));
newElement.setControlPoint (0, newCp2, 0);
newElement.setControlPoint (1, mid3, 0);
newElement.setControlPoint (2, rp4, 0);
state.getParent().addChild (newTree, state.getParent().indexOf (state) + 1, undoManager);
}
else if (i == quadraticToElement)
{
RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint());
const Point<float> points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder) };
double bestProp = 0;
float bestDistance = std::numeric_limits<float>::max();
for (int i = 110; --i >= 0;)
{
double prop = i > 10 ? ((i - 10) / 100.0) : (bestProp + ((i - 5) / 1000.0));
const Point<float> centre (findQuadraticSubdivisionPoint (prop, points));
const float distance = centre.getDistanceFrom (targetPoint);
if (distance < bestDistance)
{
bestProp = prop;
bestDistance = distance;
}
}
const Point<float> mid1 (points[0] + (points[1] - points[0]) * bestProp),
mid2 (points[1] + (points[2] - points[1]) * bestProp);
const Point<float> newCentre (mid1 + (mid2 - mid1) * bestProp);
setControlPoint (0, mid1, undoManager);
setControlPoint (1, newCentre, undoManager);
setModeOfEndPoint (roundedMode, undoManager);
Element newElement (newTree = ValueTree (quadraticToElement));
newElement.setControlPoint (0, mid2, 0);
newElement.setControlPoint (1, rp3, 0);
state.getParent().addChild (newTree, state.getParent().indexOf (state) + 1, undoManager);
}
else if (i == lineToElement)
{
RelativePoint rp1 (getStartPoint()), rp2 (getEndPoint());
const Line<float> line (rp1.resolve (nameFinder), rp2.resolve (nameFinder));
const Point<float> newPoint (line.findNearestPointTo (targetPoint));
setControlPoint (0, newPoint, undoManager);
Element newElement (newTree = ValueTree (lineToElement));
newElement.setControlPoint (0, rp2, 0);
state.getParent().addChild (newTree, state.getParent().indexOf (state) + 1, undoManager);
}
else if (i == closeSubPathElement)
{
}
return newTree;
}
void DrawablePath::ValueTreeWrapper::Element::removePoint (UndoManager* undoManager)

View file

@ -163,6 +163,7 @@ public:
const RelativePoint getStartPoint() const;
const RelativePoint getEndPoint() const;
void setControlPoint (int index, const RelativePoint& point, UndoManager* undoManager);
float getLength (RelativeCoordinate::NamedCoordinateFinder* nameFinder) const;
ValueTreeWrapper getParent() const;
Element getPreviousElement() const;
@ -173,7 +174,7 @@ public:
void convertToLine (UndoManager* undoManager);
void convertToCubic (RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager);
void convertToPathBreak (UndoManager* undoManager);
void insertPoint (double proportionOfLength, RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager);
ValueTree insertPoint (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager);
void removePoint (UndoManager* undoManager);
static const Identifier mode, startSubPathElement, closeSubPathElement,