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:
parent
c8b977a482
commit
fad682c1e1
5 changed files with 312 additions and 6 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue