modules/graphics/src/main/java/javafx/scene/layout/Region.java
Print this page
@@ -64,11 +64,13 @@
import com.sun.javafx.css.converters.InsetsConverter;
import com.sun.javafx.css.converters.ShapeConverter;
import com.sun.javafx.css.converters.SizeConverter;
import com.sun.javafx.geom.BaseBounds;
import com.sun.javafx.geom.PickRay;
+import com.sun.javafx.geom.RectBounds;
import com.sun.javafx.geom.Vec2d;
+import com.sun.javafx.geom.transform.Affine2D;
import com.sun.javafx.geom.transform.BaseTransform;
import com.sun.javafx.scene.DirtyBits;
import com.sun.javafx.scene.input.PickResultChooser;
import com.sun.javafx.sg.prism.NGNode;
import com.sun.javafx.sg.prism.NGRegion;
@@ -865,10 +867,11 @@
// is now going to recompute the width eagerly. The cost of excessive and
// unnecessary bounds changes, however, is relatively high.
if (value != _width) {
_width = value;
boundingBox = null;
+ scaledShape = null;
impl_layoutBoundsChanged();
impl_geomChanged();
impl_markDirty(DirtyBits.NODE_GEOMETRY);
setNeedsLayout(true);
requestParentLayout();
@@ -923,10 +926,12 @@
// it previously held. If this is the case, we want to avoid excessive layouts.
// Note that I have biased this for layout over binding, because the heightProperty
// is now going to recompute the height eagerly. The cost of excessive and
// unnecessary bounds changes, however, is relatively high.
boundingBox = null;
+ // Scaled shape might depend on width/height if it's centered or scaled.
+ scaledShape = null;
// Note: although impl_geomChanged will usually also invalidate the
// layout bounds, that is not the case for Regions, and both must
// be called separately.
impl_geomChanged();
impl_layoutBoundsChanged();
@@ -1238,15 +1243,17 @@
// we therefore need to fire that the insets value may have changed.
insets.fireValueChanged();
}
// Update our reference to the old shape
_shape = value;
+ scaledShape = null;
}
}
@Override public void run() {
impl_geomChanged();
+ scaledShape = null;
impl_markDirty(DirtyBits.REGION_SHAPE);
}
};
/**
@@ -1270,10 +1277,11 @@
@Override public CssMetaData<Region, Boolean> getCssMetaData() {
return StyleableProperties.SCALE_SHAPE;
}
@Override public void invalidated() {
impl_geomChanged();
+ scaledShape = null;
impl_markDirty(DirtyBits.REGION_SHAPE);
}
};
}
return scaleShape;
@@ -1299,10 +1307,11 @@
@Override public CssMetaData<Region, Boolean> getCssMetaData() {
return StyleableProperties.POSITION_SHAPE;
}
@Override public void invalidated() {
impl_geomChanged();
+ scaledShape = null;
impl_markDirty(DirtyBits.REGION_SHAPE);
}
};
}
return centerShape;
@@ -2456,10 +2465,20 @@
/** @treatAsPrivate */
@Override public NGNode impl_createPeer() {
return new NGRegion();
}
+ private com.sun.javafx.geom.Shape scaledShape;
+
+ private com.sun.javafx.geom.Shape getShapeScaledAndPositioned() {
+ if (scaledShape == null) {
+ scaledShape = NGRegion.resizeShape(_shape.impl_configShape(), isScaleShape(), isCenterShape(),
+ (float)getWidth(), (float)getHeight(), 0f,0f,0f,0f);
+ }
+ return scaledShape;
+ }
+
/**
* @treatAsPrivate implementation detail
* @deprecated This is an internal API that is not intended for use and will be removed in the next version
*/
@Deprecated
@@ -2475,19 +2494,13 @@
final double y2 = getHeight();
// Figure out what the maximum possible radius value is.
final double maxRadius = Math.min(x2 / 2.0, y2 / 2.0);
// First check the shape. Shape could be impacted by scaleShape & positionShape properties.
- // This is going to be ugly! The problem is that basically all the scale / position operations
- // have to be implemented here in Region, whereas right now they are all implemented in
- // NGRegion. Drat. Basically I can't implement this properly until I have a way to get the
- // geometry backing an arbitrary FX shape. For example, in this case I need an NGShape peer
- // of this shape so that I can resize it as appropriate for these picking tests.
- // Lacking that, for now, I will simply check the shape (so that picking works for pie charts)
- // Bug is filed as RT-27775.
+ // We are calling NGRegion static method here because we lack a better place for the code.
if (_shape != null) {
- return _shape.contains(localX, localY);
+ return getShapeScaledAndPositioned().contains((float)localX, (float)localY);
}
// OK, there was no background shape, so I'm going to work on the principle of
// nested rounded rectangles. We'll start by checking the backgrounds. The
// first background which passes the test is good enough for us!