582 // For debug / diagnostic purposes, we will copy across a name for this node down to 583 // the NG layer, where we can use the name to figure out what the NGNode represents. 584 // An alternative would be to have a back-reference from the NGNode back to the Node it 585 // is a peer to, however it was felt that this would make it too easy to communicate back 586 // to the Node and possibly violate thread invariants. But of course, we only need to do this 587 // if we're going to print the render graph (otherwise all the work we'd do to keep the name 588 // properly updated would be a waste). 589 if (PrismSettings.printRenderGraph && impl_isDirty(DirtyBits.DEBUG)) { 590 final String id = getId(); 591 String className = getClass().getSimpleName(); 592 if (className.isEmpty()) { 593 className = getClass().getName(); 594 } 595 peer.setName(id == null ? className : id + "(" + className + ")"); 596 } 597 598 if (impl_isDirty(DirtyBits.NODE_TRANSFORM)) { 599 peer.setTransformMatrix(localToParentTx); 600 } 601 602 if (impl_isDirty(DirtyBits.NODE_BOUNDS)) { 603 peer.setContentBounds(_geomBounds); 604 } 605 606 if (impl_isDirty(DirtyBits.NODE_TRANSFORMED_BOUNDS)) { 607 peer.setTransformedBounds(_txBounds, !impl_isDirty(DirtyBits.NODE_BOUNDS)); 608 } 609 610 if (impl_isDirty(DirtyBits.NODE_OPACITY)) { 611 peer.setOpacity((float)Utils.clamp(0, getOpacity(), 1)); 612 } 613 614 if (impl_isDirty(DirtyBits.NODE_CACHE)) { 615 peer.setCachedAsBitmap(isCache(), getCacheHint()); 616 } 617 618 if (impl_isDirty(DirtyBits.NODE_CLIP)) { 619 peer.setClipNode(getClip() != null ? getClip().impl_getPeer() : null); 620 } 621 5202 return 0.0; 5203 } else { 5204 return Double.NaN; 5205 } 5206 } else if (tmin > maxDistance) { 5207 return Double.NaN; 5208 } 5209 5210 return tmin; 5211 } 5212 5213 5214 // Good to find a home for commonly use util. code such as EPS. 5215 // and almostZero. This code currently defined in multiple places, 5216 // such as Affine3D and GeneralTransform3D. 5217 private static final double EPSILON_ABSOLUTE = 1.0e-5; 5218 5219 static boolean almostZero(double a) { 5220 return ((a < EPSILON_ABSOLUTE) && (a > -EPSILON_ABSOLUTE)); 5221 } 5222 /*************************************************************************** 5223 * * 5224 * Transformations * 5225 * * 5226 **************************************************************************/ 5227 /** 5228 * Defines the ObservableList of {@link javafx.scene.transform.Transform} objects 5229 * to be applied to this {@code Node}. This ObservableList of transforms is applied 5230 * before {@link #translateXProperty translateX}, {@link #translateYProperty translateY}, {@link #scaleXProperty scaleX}, and 5231 * {@link #scaleYProperty scaleY}, {@link #rotateProperty rotate} transforms. 5232 * 5233 * @defaultValue empty 5234 */ 5235 public final ObservableList<Transform> getTransforms() { 5236 return transformsProperty(); 5237 } 5238 5239 private ObservableList<Transform> transformsProperty() { 5240 return getNodeTransformation().getTransforms(); 5241 } 6401 fireValueChangedEvent(); 6402 } 6403 } 6404 6405 /*************************************************************************** 6406 * * 6407 * Misc Seldom Used Properties * 6408 * * 6409 **************************************************************************/ 6410 6411 private MiscProperties miscProperties; 6412 6413 private MiscProperties getMiscProperties() { 6414 if (miscProperties == null) { 6415 miscProperties = new MiscProperties(); 6416 } 6417 6418 return miscProperties; 6419 } 6420 6421 private static final boolean DEFAULT_CACHE = false; 6422 private static final CacheHint DEFAULT_CACHE_HINT = CacheHint.DEFAULT; 6423 private static final Node DEFAULT_CLIP = null; 6424 private static final Cursor DEFAULT_CURSOR = null; 6425 private static final DepthTest DEFAULT_DEPTH_TEST = DepthTest.INHERIT; 6426 private static final boolean DEFAULT_DISABLE = false; 6427 private static final Effect DEFAULT_EFFECT = null; 6428 private static final InputMethodRequests DEFAULT_INPUT_METHOD_REQUESTS = 6429 null; 6430 private static final boolean DEFAULT_MOUSE_TRANSPARENT = false; 6431 6432 private final class MiscProperties { 6433 private LazyBoundsProperty boundsInParent; 6434 private LazyBoundsProperty boundsInLocal; 6435 private BooleanProperty cache; 6436 private ObjectProperty<CacheHint> cacheHint; 6437 private ObjectProperty<Node> clip; 6438 private ObjectProperty<Cursor> cursor; 6439 private ObjectProperty<DepthTest> depthTest; 6440 private BooleanProperty disable; 6441 private ObjectProperty<Effect> effect; 6442 private ObjectProperty<InputMethodRequests> inputMethodRequests; 6443 private BooleanProperty mouseTransparent; 6444 6445 public final Bounds getBoundsInParent() { 6446 return boundsInParentProperty().get(); 6447 } 6448 6449 public final ReadOnlyObjectProperty<Bounds> boundsInParentProperty() { 6450 if (boundsInParent == null) { 6451 boundsInParent = new LazyBoundsProperty() { 6452 /** 6453 * Computes the bounds including the clip, effects, and all 6454 * transforms. This function is essentially how to compute 6455 * the boundsInParent. Optimizations are made to compute as 6456 * little as possible and create as little trash as 6457 * possible. 6458 */ 6459 @Override 6460 protected Bounds computeBounds() { 6461 BaseBounds tempBounds = TempState.getInstance().bounds; 6462 tempBounds = getTransformedBounds( 6463 tempBounds, 8694 public StyleableProperty<Number> getStyleableProperty(Node node) { 8695 return (StyleableProperty<Number>)node.translateYProperty(); 8696 } 8697 }; 8698 private static final CssMetaData<Node,Number> TRANSLATE_Z = 8699 new CssMetaData<Node,Number>("-fx-translate-z", 8700 SizeConverter.getInstance(), 0.0) { 8701 8702 @Override 8703 public boolean isSettable(Node node) { 8704 return node.nodeTransformation == null 8705 || node.nodeTransformation.translateZ == null 8706 || node.nodeTransformation.canSetTranslateZ(); 8707 } 8708 8709 @Override 8710 public StyleableProperty<Number> getStyleableProperty(Node node) { 8711 return (StyleableProperty<Number>)node.translateZProperty(); 8712 } 8713 }; 8714 private static final CssMetaData<Node,Boolean> VISIBILITY = 8715 new CssMetaData<Node,Boolean>("visibility", 8716 new StyleConverter<String,Boolean>() { 8717 8718 @Override 8719 // [ visible | hidden | collapse | inherit ] 8720 public Boolean convert(ParsedValue<String, Boolean> value, Font font) { 8721 final String sval = value != null ? value.getValue() : null; 8722 return "visible".equalsIgnoreCase(sval); 8723 } 8724 8725 }, 8726 Boolean.TRUE) { 8727 8728 @Override 8729 public boolean isSettable(Node node) { 8730 return node.visible == null || !node.visible.isBound(); 8731 } 8732 8733 @Override 8734 public StyleableProperty<Boolean> getStyleableProperty(Node node) { 8735 return (StyleableProperty<Boolean>)node.visibleProperty(); 8736 } 8737 }; 8738 8739 private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES; 8740 8741 static { 8742 8743 final List<CssMetaData<? extends Styleable, ?>> styleables = 8744 new ArrayList<CssMetaData<? extends Styleable, ?>>(); 8745 styleables.add(CURSOR); 8746 styleables.add(EFFECT); 8747 styleables.add(FOCUS_TRAVERSABLE); 8748 styleables.add(OPACITY); 8749 styleables.add(BLEND_MODE); 8750 styleables.add(ROTATE); 8751 styleables.add(SCALE_X); 8752 styleables.add(SCALE_Y); 8753 styleables.add(SCALE_Z); 8754 styleables.add(TRANSLATE_X); 8755 styleables.add(TRANSLATE_Y); 8756 styleables.add(TRANSLATE_Z); 8757 styleables.add(VISIBILITY); 8758 STYLEABLES = Collections.unmodifiableList(styleables); 8759 8760 } 8761 } 8762 8763 /** 8764 * @return The CssMetaData associated with this class, which may include the 8765 * CssMetaData of its super classes. 8766 * @since JavaFX 8.0 8767 */ 8768 public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { 8769 // 8770 // Super-lazy instantiation pattern from Bill Pugh. StyleableProperties 8771 // is referenced no earlier (and therefore loaded no earlier by the 8772 // class loader) than the moment that getClassCssMetaData() is called. 8773 // This avoids loading the CssMetaData instances until the point at | 582 // For debug / diagnostic purposes, we will copy across a name for this node down to 583 // the NG layer, where we can use the name to figure out what the NGNode represents. 584 // An alternative would be to have a back-reference from the NGNode back to the Node it 585 // is a peer to, however it was felt that this would make it too easy to communicate back 586 // to the Node and possibly violate thread invariants. But of course, we only need to do this 587 // if we're going to print the render graph (otherwise all the work we'd do to keep the name 588 // properly updated would be a waste). 589 if (PrismSettings.printRenderGraph && impl_isDirty(DirtyBits.DEBUG)) { 590 final String id = getId(); 591 String className = getClass().getSimpleName(); 592 if (className.isEmpty()) { 593 className = getClass().getName(); 594 } 595 peer.setName(id == null ? className : id + "(" + className + ")"); 596 } 597 598 if (impl_isDirty(DirtyBits.NODE_TRANSFORM)) { 599 peer.setTransformMatrix(localToParentTx); 600 } 601 602 if (impl_isDirty(DirtyBits.NODE_PRIORITY_ORDER)) { 603 peer.setPriorityOrder(getPriorityOrder()); 604 } 605 606 if (impl_isDirty(DirtyBits.NODE_BOUNDS)) { 607 peer.setContentBounds(_geomBounds); 608 } 609 610 if (impl_isDirty(DirtyBits.NODE_TRANSFORMED_BOUNDS)) { 611 peer.setTransformedBounds(_txBounds, !impl_isDirty(DirtyBits.NODE_BOUNDS)); 612 } 613 614 if (impl_isDirty(DirtyBits.NODE_OPACITY)) { 615 peer.setOpacity((float)Utils.clamp(0, getOpacity(), 1)); 616 } 617 618 if (impl_isDirty(DirtyBits.NODE_CACHE)) { 619 peer.setCachedAsBitmap(isCache(), getCacheHint()); 620 } 621 622 if (impl_isDirty(DirtyBits.NODE_CLIP)) { 623 peer.setClipNode(getClip() != null ? getClip().impl_getPeer() : null); 624 } 625 5206 return 0.0; 5207 } else { 5208 return Double.NaN; 5209 } 5210 } else if (tmin > maxDistance) { 5211 return Double.NaN; 5212 } 5213 5214 return tmin; 5215 } 5216 5217 5218 // Good to find a home for commonly use util. code such as EPS. 5219 // and almostZero. This code currently defined in multiple places, 5220 // such as Affine3D and GeneralTransform3D. 5221 private static final double EPSILON_ABSOLUTE = 1.0e-5; 5222 5223 static boolean almostZero(double a) { 5224 return ((a < EPSILON_ABSOLUTE) && (a > -EPSILON_ABSOLUTE)); 5225 } 5226 5227 /* ************************************************************************* 5228 * * 5229 * PriorityOrder Handling * 5230 * * 5231 **************************************************************************/ 5232 public final void setPriorityOrder(double value) { 5233 priorityOrderProperty().set(value); 5234 } 5235 5236 public final double getPriorityOrder() { 5237 return (miscProperties == null) ? DEFAULT_PRIORITY_ORDER 5238 : miscProperties.getPriorityOrder(); 5239 } 5240 5241 /** 5242 * Defines the traversal order of this {@code Node} within its parent. 5243 * <p> 5244 * This property is used to alter the rendering and picking order of a node 5245 * within its parent without disturbing its child physical index, which makes 5246 * it useful for animating a node's ordering such as transparency sorting. 5247 * <p> 5248 * The parent will traverse its children in a specific order. The children are 5249 * traversed in decreasing priorityOrder order. The child with the highest 5250 * priorityOrder is visited first, followed by the next higher priortyOrder 5251 * child, and so on, till the child with the lowest priorityOrder visited last. 5252 * 5253 * @defaultValue 0.0 5254 */ 5255 public final DoubleProperty priorityOrderProperty() { 5256 return getMiscProperties().priorityOrderProperty(); 5257 } 5258 5259 /*************************************************************************** 5260 * * 5261 * Transformations * 5262 * * 5263 **************************************************************************/ 5264 /** 5265 * Defines the ObservableList of {@link javafx.scene.transform.Transform} objects 5266 * to be applied to this {@code Node}. This ObservableList of transforms is applied 5267 * before {@link #translateXProperty translateX}, {@link #translateYProperty translateY}, {@link #scaleXProperty scaleX}, and 5268 * {@link #scaleYProperty scaleY}, {@link #rotateProperty rotate} transforms. 5269 * 5270 * @defaultValue empty 5271 */ 5272 public final ObservableList<Transform> getTransforms() { 5273 return transformsProperty(); 5274 } 5275 5276 private ObservableList<Transform> transformsProperty() { 5277 return getNodeTransformation().getTransforms(); 5278 } 6438 fireValueChangedEvent(); 6439 } 6440 } 6441 6442 /*************************************************************************** 6443 * * 6444 * Misc Seldom Used Properties * 6445 * * 6446 **************************************************************************/ 6447 6448 private MiscProperties miscProperties; 6449 6450 private MiscProperties getMiscProperties() { 6451 if (miscProperties == null) { 6452 miscProperties = new MiscProperties(); 6453 } 6454 6455 return miscProperties; 6456 } 6457 6458 private static final double DEFAULT_PRIORITY_ORDER = 0; 6459 private static final boolean DEFAULT_CACHE = false; 6460 private static final CacheHint DEFAULT_CACHE_HINT = CacheHint.DEFAULT; 6461 private static final Node DEFAULT_CLIP = null; 6462 private static final Cursor DEFAULT_CURSOR = null; 6463 private static final DepthTest DEFAULT_DEPTH_TEST = DepthTest.INHERIT; 6464 private static final boolean DEFAULT_DISABLE = false; 6465 private static final Effect DEFAULT_EFFECT = null; 6466 private static final InputMethodRequests DEFAULT_INPUT_METHOD_REQUESTS = 6467 null; 6468 private static final boolean DEFAULT_MOUSE_TRANSPARENT = false; 6469 6470 private final class MiscProperties { 6471 private LazyBoundsProperty boundsInParent; 6472 private LazyBoundsProperty boundsInLocal; 6473 private BooleanProperty cache; 6474 private ObjectProperty<CacheHint> cacheHint; 6475 private ObjectProperty<Node> clip; 6476 private ObjectProperty<Cursor> cursor; 6477 private ObjectProperty<DepthTest> depthTest; 6478 private BooleanProperty disable; 6479 private ObjectProperty<Effect> effect; 6480 private ObjectProperty<InputMethodRequests> inputMethodRequests; 6481 private BooleanProperty mouseTransparent; 6482 private DoubleProperty priorityOrder; 6483 6484 public double getPriorityOrder() { 6485 return (priorityOrder == null) ? DEFAULT_PRIORITY_ORDER : priorityOrder.get(); 6486 } 6487 6488 public final DoubleProperty priorityOrderProperty() { 6489 if (priorityOrder == null) { 6490 priorityOrder = new StyleableDoubleProperty(DEFAULT_PRIORITY_ORDER) { 6491 @Override 6492 public void invalidated() { 6493 Parent p = getParent(); 6494 if (p != null) { 6495 // Parent will be responsible to update peers of children 6496 p.markSortedChildrenDirty(); 6497 } else { 6498 impl_markDirty(DirtyBits.NODE_PRIORITY_ORDER); 6499 } 6500 } 6501 6502 @Override 6503 public CssMetaData getCssMetaData() { 6504 return StyleableProperties.PRIORITY_ORDER; 6505 } 6506 6507 @Override 6508 public Object getBean() { 6509 return Node.this; 6510 } 6511 6512 @Override 6513 public String getName() { 6514 return "priorityOrder"; 6515 } 6516 }; 6517 } 6518 return priorityOrder; 6519 } 6520 6521 public final Bounds getBoundsInParent() { 6522 return boundsInParentProperty().get(); 6523 } 6524 6525 public final ReadOnlyObjectProperty<Bounds> boundsInParentProperty() { 6526 if (boundsInParent == null) { 6527 boundsInParent = new LazyBoundsProperty() { 6528 /** 6529 * Computes the bounds including the clip, effects, and all 6530 * transforms. This function is essentially how to compute 6531 * the boundsInParent. Optimizations are made to compute as 6532 * little as possible and create as little trash as 6533 * possible. 6534 */ 6535 @Override 6536 protected Bounds computeBounds() { 6537 BaseBounds tempBounds = TempState.getInstance().bounds; 6538 tempBounds = getTransformedBounds( 6539 tempBounds, 8770 public StyleableProperty<Number> getStyleableProperty(Node node) { 8771 return (StyleableProperty<Number>)node.translateYProperty(); 8772 } 8773 }; 8774 private static final CssMetaData<Node,Number> TRANSLATE_Z = 8775 new CssMetaData<Node,Number>("-fx-translate-z", 8776 SizeConverter.getInstance(), 0.0) { 8777 8778 @Override 8779 public boolean isSettable(Node node) { 8780 return node.nodeTransformation == null 8781 || node.nodeTransformation.translateZ == null 8782 || node.nodeTransformation.canSetTranslateZ(); 8783 } 8784 8785 @Override 8786 public StyleableProperty<Number> getStyleableProperty(Node node) { 8787 return (StyleableProperty<Number>)node.translateZProperty(); 8788 } 8789 }; 8790 private static final CssMetaData<Node,Number> PRIORITY_ORDER = 8791 new CssMetaData<Node,Number>("-fx-priority-order", 8792 SizeConverter.getInstance(), 0.0) { 8793 8794 @Override 8795 public boolean isSettable(Node node) { 8796 return node.miscProperties == null 8797 || node.miscProperties.priorityOrder == null 8798 || !node.miscProperties.priorityOrder.isBound(); 8799 } 8800 8801 @Override 8802 public StyleableProperty<Number> getStyleableProperty(Node node) { 8803 return (StyleableProperty<Number>)node.priorityOrderProperty(); 8804 } 8805 }; 8806 private static final CssMetaData<Node,Boolean> VISIBILITY = 8807 new CssMetaData<Node,Boolean>("visibility", 8808 new StyleConverter<String,Boolean>() { 8809 8810 @Override 8811 // [ visible | hidden | collapse | inherit ] 8812 public Boolean convert(ParsedValue<String, Boolean> value, Font font) { 8813 final String sval = value != null ? value.getValue() : null; 8814 return "visible".equalsIgnoreCase(sval); 8815 } 8816 8817 }, 8818 Boolean.TRUE) { 8819 8820 @Override 8821 public boolean isSettable(Node node) { 8822 return node.visible == null || !node.visible.isBound(); 8823 } 8824 8825 @Override 8826 public StyleableProperty<Boolean> getStyleableProperty(Node node) { 8827 return (StyleableProperty<Boolean>)node.visibleProperty(); 8828 } 8829 }; 8830 8831 private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES; 8832 8833 static { 8834 8835 final List<CssMetaData<? extends Styleable, ?>> styleables = 8836 new ArrayList<CssMetaData<? extends Styleable, ?>>(); 8837 styleables.add(CURSOR); 8838 styleables.add(EFFECT); 8839 styleables.add(FOCUS_TRAVERSABLE); 8840 styleables.add(OPACITY); 8841 styleables.add(BLEND_MODE); 8842 styleables.add(ROTATE); 8843 styleables.add(SCALE_X); 8844 styleables.add(SCALE_Y); 8845 styleables.add(SCALE_Z); 8846 styleables.add(PRIORITY_ORDER); 8847 styleables.add(TRANSLATE_X); 8848 styleables.add(TRANSLATE_Y); 8849 styleables.add(TRANSLATE_Z); 8850 styleables.add(VISIBILITY); 8851 STYLEABLES = Collections.unmodifiableList(styleables); 8852 8853 } 8854 } 8855 8856 /** 8857 * @return The CssMetaData associated with this class, which may include the 8858 * CssMetaData of its super classes. 8859 * @since JavaFX 8.0 8860 */ 8861 public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { 8862 // 8863 // Super-lazy instantiation pattern from Bill Pugh. StyleableProperties 8864 // is referenced no earlier (and therefore loaded no earlier by the 8865 // class loader) than the moment that getClassCssMetaData() is called. 8866 // This avoids loading the CssMetaData instances until the point at |