Browse Source

Development on drawables. ValueTree fix.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
fad682c1e1
5 changed files with 312 additions and 6 deletions
  1. +154
    -2
      juce_amalgamated.cpp
  2. +2
    -1
      juce_amalgamated.h
  3. +1
    -1
      src/containers/juce_ValueTree.cpp
  4. +153
    -1
      src/gui/graphics/drawables/juce_DrawablePath.cpp
  5. +2
    -1
      src/gui/graphics/drawables/juce_DrawablePath.h

+ 154
- 2
juce_amalgamated.cpp 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)


+ 2
- 1
juce_amalgamated.h 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,


+ 1
- 1
src/containers/juce_ValueTree.cpp 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


+ 153
- 1
src/gui/graphics/drawables/juce_DrawablePath.cpp 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)


+ 2
- 1
src/gui/graphics/drawables/juce_DrawablePath.h 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,


Loading…
Cancel
Save