use of javafx.scene.shape.PathElement in project RichTextFX by FXMisc.
the class ParagraphText method getRangeBoundsOnScreen.
public Bounds getRangeBoundsOnScreen(int from, int to) {
// ensure layout, is a no-op if not dirty
layout();
PathElement[] rangeShape = getRangeShapeSafely(from, to);
Path p = new Path();
p.setManaged(false);
p.setLayoutX(getInsets().getLeft());
p.setLayoutY(getInsets().getTop());
getChildren().add(p);
p.getElements().setAll(rangeShape);
Bounds localBounds = p.getBoundsInLocal();
Bounds rangeBoundsOnScreen = p.localToScreen(localBounds);
getChildren().remove(p);
return rangeBoundsOnScreen;
}
use of javafx.scene.shape.PathElement in project RichTextFX by FXMisc.
the class ParagraphText method getRangeShapeSafely.
/**
* Gets the range shape for the given positions within the text, including the newline character, if range
* defined by the start/end arguments include it.
*
* @param start the start position of the range shape
* @param end the end position of the range shape. If {@code end == paragraph.length() + 1}, the newline character
* will be included in the selection by selecting the rest of the line
*/
private PathElement[] getRangeShapeSafely(int start, int end) {
PathElement[] shape;
if (end <= paragraph.length()) {
// selection w/o newline char
shape = getRangeShape(start, end);
} else {
// Selection includes a newline character.
if (paragraph.length() == 0) {
// empty paragraph
shape = createRectangle(0, 0, getWidth(), getHeight());
} else if (start == paragraph.length()) {
// selecting only the newline char
// calculate the bounds of the last character
shape = getRangeShape(start - 1, start);
LineTo lineToTopRight = (LineTo) shape[shape.length - 4];
shape = createRectangle(lineToTopRight.getX(), lineToTopRight.getY(), getWidth(), getHeight());
} else {
shape = getRangeShape(start, paragraph.length());
// Since this might be a wrapped multi-line paragraph,
// there may be multiple groups of (1 MoveTo, 3 LineTo objects) for each line:
// MoveTo(topLeft), LineTo(topRight), LineTo(bottomRight), LineTo(bottomLeft)
// We only need to adjust the top right and bottom right corners to extend to the
// width/height of the line, simulating a full line selection.
int length = shape.length;
if (// Prevent IndexOutOfBoundsException accessing shape[] issue #689
length > 3) {
int bottomRightIndex = length - 3;
int topRightIndex = bottomRightIndex - 1;
LineTo lineToTopRight = (LineTo) shape[topRightIndex];
shape[topRightIndex] = new LineTo(getWidth(), lineToTopRight.getY());
shape[bottomRightIndex] = new LineTo(getWidth(), getHeight());
}
}
}
if (getLineCount() > 1) {
// adjust right corners of wrapped lines
boolean wrappedAtEndPos = (end > 0 && getLineOfCharacter(end) > getLineOfCharacter(end - 1));
int adjustLength = shape.length - (wrappedAtEndPos ? 0 : 5);
for (int i = 0; i < adjustLength; i++) {
if (shape[i] instanceof MoveTo) {
((LineTo) shape[i + 1]).setX(getWidth());
((LineTo) shape[i + 2]).setX(getWidth());
}
}
}
return shape;
}
use of javafx.scene.shape.PathElement in project tilesfx by HanSolo.
the class SmoothAreaChartTileSkin method select.
private void select(final MouseEvent EVT) {
final double EVENT_X = EVT.getX();
final double CHART_X = 0;
final double CHART_WIDTH = width;
if (Double.compare(EVENT_X, CHART_X) < 0 || Double.compare(EVENT_X, CHART_WIDTH) > 0) {
return;
}
double upperBound = tile.getChartData().stream().max(Comparator.comparing(ChartData::getValue)).get().getValue();
double range = upperBound - tile.getMinValue();
double factor = range / (height * 0.5);
List<PathElement> elements = strokePath.getElements();
int noOfElements = elements.size();
PathElement lastElement = elements.get(0);
if (tile.isSnapToTicks()) {
double reverseFactor = (height * 0.5) / range;
int noOfDataElements = tile.getChartData().size();
double interval = width / (double) (noOfDataElements - 1);
int selectedIndex = Helper.roundDoubleToInt(EVENT_X / interval);
ChartData selectedData = tile.getChartData().get(selectedIndex);
double selectedValue = selectedData.getValue();
selector.setCenterX(interval * selectedIndex);
selector.setCenterY(height - selectedValue * reverseFactor);
selector.setVisible(true);
fadeInFadeOut.playFrom(Duration.millis(0));
String tooltipText = new StringBuilder(selectedData.getName()).append("\n").append(String.format(locale, formatString, selectedValue)).toString();
Point2D popupLocation = tile.localToScreen(selector.getCenterX() - selectorTooltip.getWidth() * 0.5, selector.getCenterY() - size * 0.025 - selectorTooltip.getHeight());
selectorTooltip.setText(tooltipText);
selectorTooltip.setX(popupLocation.getX());
selectorTooltip.setY(popupLocation.getY());
selectorTooltip.show(tile.getScene().getWindow());
tile.fireTileEvent(new TileEvent(EventType.SELECTED_CHART_DATA, selectedData));
} else {
for (int i = 1; i < noOfElements; i++) {
PathElement element = elements.get(i);
double[] xy = getXYFromPathElement(lastElement);
double[] xy1 = getXYFromPathElement(element);
if (EVENT_X > xy[0] && EVENT_X < xy1[0]) {
double deltaX = xy1[0] - xy[0];
double deltaY = xy1[1] - xy[1];
double m = deltaY / deltaX;
double y = m * (EVT.getX() - xy[0]) + xy[1];
double selectedValue = upperBound - (y - (height * 0.5)) * factor;
selector.setCenterX(EVT.getX());
selector.setCenterY(y);
selector.setVisible(true);
fadeInFadeOut.playFrom(Duration.millis(0));
Point2D popupLocation = tile.localToScreen(EVT.getX() - selectorTooltip.getWidth() * 0.5, selector.getCenterY() - size * 0.025 - selectorTooltip.getHeight());
selectorTooltip.setText(String.format(locale, formatString, selectedValue));
selectorTooltip.setX(popupLocation.getX());
selectorTooltip.setY(popupLocation.getY());
selectorTooltip.show(tile.getScene().getWindow());
tile.fireTileEvent(new TileEvent(EventType.SELECTED_CHART_DATA, new ChartData(selectedValue)));
break;
}
lastElement = element;
}
}
}
use of javafx.scene.shape.PathElement in project tilesfx by HanSolo.
the class Helper method smoothPath.
// Smooth given path defined by it's list of path elements
public static final Path smoothPath(final ObservableList<PathElement> ELEMENTS, final boolean FILLED) {
if (ELEMENTS.isEmpty()) {
return new Path();
}
final Point[] dataPoints = new Point[ELEMENTS.size()];
for (int i = 0; i < ELEMENTS.size(); i++) {
final PathElement element = ELEMENTS.get(i);
if (element instanceof MoveTo) {
MoveTo move = (MoveTo) element;
dataPoints[i] = new Point(move.getX(), move.getY());
} else if (element instanceof LineTo) {
LineTo line = (LineTo) element;
dataPoints[i] = new Point(line.getX(), line.getY());
}
}
double zeroY = ((MoveTo) ELEMENTS.get(0)).getY();
List<PathElement> smoothedElements = new ArrayList<>();
Pair<Point[], Point[]> result = calcCurveControlPoints(dataPoints);
Point[] firstControlPoints = result.getKey();
Point[] secondControlPoints = result.getValue();
// Start path dependent on filled or not
if (FILLED) {
smoothedElements.add(new MoveTo(dataPoints[0].getX(), zeroY));
smoothedElements.add(new LineTo(dataPoints[0].getX(), dataPoints[0].getY()));
} else {
smoothedElements.add(new MoveTo(dataPoints[0].getX(), dataPoints[0].getY()));
}
// Add curves
for (int i = 2; i < dataPoints.length; i++) {
final int ci = i - 1;
smoothedElements.add(new CubicCurveTo(firstControlPoints[ci].getX(), firstControlPoints[ci].getY(), secondControlPoints[ci].getX(), secondControlPoints[ci].getY(), dataPoints[i].getX(), dataPoints[i].getY()));
}
// Close the path if filled
if (FILLED) {
smoothedElements.add(new LineTo(dataPoints[dataPoints.length - 1].getX(), zeroY));
smoothedElements.add(new ClosePath());
}
return new Path(smoothedElements);
}
use of javafx.scene.shape.PathElement in project latexdraw by arnobl.
the class TestViewShape method duplicatePath.
protected static List<PathElement> duplicatePath(final List<PathElement> path) {
return path.stream().map(elt -> {
PathElement dupelt;
if (elt instanceof MoveTo) {
final MoveTo moveTo = (MoveTo) elt;
dupelt = ViewFactory.INSTANCE.createMoveTo(moveTo.getX(), moveTo.getY());
} else if (elt instanceof LineTo) {
final LineTo lineTo = (LineTo) elt;
dupelt = ViewFactory.INSTANCE.createLineTo(lineTo.getX(), lineTo.getY());
} else if (elt instanceof ClosePath) {
dupelt = ViewFactory.INSTANCE.createClosePath();
} else if (elt instanceof CubicCurveTo) {
final CubicCurveTo cct = (CubicCurveTo) elt;
dupelt = ViewFactory.INSTANCE.createCubicCurveTo(cct.getControlX1(), cct.getControlY1(), cct.getControlX2(), cct.getControlY2(), cct.getX(), cct.getY());
} else {
throw new IllegalArgumentException();
}
dupelt.setAbsolute(elt.isAbsolute());
return dupelt;
}).collect(Collectors.toList());
}
Aggregations