/* * Copyright (c) 2002-2015, JIDE Software Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package jidefx.scene.control.popup; import javafx.beans.property.DoubleProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.geometry.Insets; import javafx.geometry.Point2D; import javafx.geometry.Pos; import javafx.scene.shape.ArcTo; import javafx.scene.shape.HLineTo; import javafx.scene.shape.MoveTo; import javafx.scene.shape.StrokeType; import javafx.scene.shape.VLineTo; /** * {@code RectanglePopupOutline} is a rectangle shaped {@link javafx.scene.shape.Path} which can be used to display a * rectangle or rounded rectangle popup. */ public class RectanglePopupOutline extends PopupOutline { private ObjectProperty<Pos> _originPositionProperty; private DoubleProperty _widthProperty; private DoubleProperty _heightProperty; private DoubleProperty _roundedRadiusProperty; public RectanglePopupOutline() { createPath(); initializeStyle(); } protected void initializeStyle() { getStyleClass().add("rectangle-popup-outline"); } public DoubleProperty widthProperty() { if (_widthProperty == null) { _widthProperty = new SimpleDoubleProperty(); } return _widthProperty; } /** * Gets the width of the balloon content. * * @return the width of the balloon content. */ public double getWidth() { return widthProperty().get(); } /** * Sets the width of the balloon content. * * @param width the width of the balloon content. */ public void setWidth(double width) { widthProperty().set(width); } public DoubleProperty heightProperty() { if (_heightProperty == null) { _heightProperty = new SimpleDoubleProperty(); } return _heightProperty; } /** * Gets the height of the balloon content. * * @return the height of the balloon content. */ public double getHeight() { return heightProperty().get(); } /** * Sets the height of the balloon content. * * @param height the height of the balloon content. */ public void setHeight(double height) { heightProperty().set(height); } public DoubleProperty roundedRadiusProperty() { if (_roundedRadiusProperty == null) { _roundedRadiusProperty = new SimpleDoubleProperty(8.0); } return _roundedRadiusProperty; } /** * Gets the radius of the rounded rectangle corner of the balloon content. * * @return the radius of the rounded rectangle corner. */ public double getRoundedRadius() { return roundedRadiusProperty().get(); } /** * Sets the radius of the rounded rectangle corner of the balloon content. * * @param roundedRadius the radius of the rounded rectangle corner. */ public void setRoundedRadius(double roundedRadius) { roundedRadiusProperty().set(roundedRadius); } public ObjectProperty<Pos> originPositionProperty() { if (_originPositionProperty == null) { _originPositionProperty = new SimpleObjectProperty<>(Pos.CENTER); } return _originPositionProperty; } /** * Gets the origin point position. * * @return the origin point position. */ public Pos getOriginPosition() { return originPositionProperty().get(); } /** * Sets origin point position. * * @param pos the origin point position. */ public void setOriginPosition(Pos pos) { originPositionProperty().set(pos); } @SuppressWarnings("SuspiciousNameCombination") public Insets getContentPadding() { return new Insets(0); } /** * Gets the location of the origin point in the local coordinates. * * @return the location of the origin point. */ public Point2D getOriginPoint() { double width = getWidth(); double height = getHeight(); Pos originPosition = getOriginPosition(); switch (originPosition) { case TOP_LEFT: return new Point2D(0, 0); case TOP_CENTER: return new Point2D(width / 2, 0); case TOP_RIGHT: return new Point2D(width, 0); case BASELINE_LEFT: case CENTER_LEFT: return new Point2D(0, height / 2); case CENTER: case BASELINE_CENTER: return new Point2D(width / 2, height / 2); case CENTER_RIGHT: case BASELINE_RIGHT: return new Point2D(width, height / 2); case BOTTOM_LEFT: return new Point2D(0, height); case BOTTOM_CENTER: return new Point2D(width / 2, height); case BOTTOM_RIGHT: return new Point2D(width, height); } return null; } protected void createPath() { getElements().clear(); setStrokeType(StrokeType.INSIDE); MoveTo startPoint = new MoveTo(); startPoint.xProperty().bind(roundedRadiusProperty()); startPoint.setY(0.0f); HLineTo topLine = new HLineTo(); topLine.xProperty().bind(widthProperty().subtract(roundedRadiusProperty())); ArcTo trArc = new ArcTo(); trArc.setSweepFlag(true); trArc.xProperty().bind(widthProperty()); trArc.yProperty().bind(roundedRadiusProperty()); trArc.radiusXProperty().bind(roundedRadiusProperty()); trArc.radiusYProperty().bind(roundedRadiusProperty()); VLineTo rightLine = new VLineTo(); rightLine.yProperty().bind(heightProperty().subtract(roundedRadiusProperty())); ArcTo brArc = new ArcTo(); brArc.setSweepFlag(true); brArc.xProperty().bind(widthProperty().subtract(roundedRadiusProperty())); brArc.yProperty().bind(heightProperty()); brArc.radiusXProperty().bind(roundedRadiusProperty()); brArc.radiusYProperty().bind(roundedRadiusProperty()); HLineTo bottomLine = new HLineTo(); bottomLine.xProperty().bind(roundedRadiusProperty()); ArcTo blArc = new ArcTo(); blArc.setSweepFlag(true); blArc.setX(0); blArc.yProperty().bind(heightProperty().subtract(roundedRadiusProperty())); blArc.radiusXProperty().bind(roundedRadiusProperty()); blArc.radiusYProperty().bind(roundedRadiusProperty()); VLineTo leftLine = new VLineTo(); leftLine.yProperty().bind(roundedRadiusProperty()); ArcTo tlArc = new ArcTo(); tlArc.setSweepFlag(true); tlArc.xProperty().bind(startPoint.xProperty()); // close the path tlArc.yProperty().bind(startPoint.yProperty()); tlArc.radiusXProperty().bind(roundedRadiusProperty()); tlArc.radiusYProperty().bind(roundedRadiusProperty()); getElements().addAll(startPoint, topLine, trArc, rightLine, brArc, bottomLine, blArc, leftLine, tlArc); } }