On Thu, 5 Sep 2024 20:55:37 GMT, Michael Strauß <mstra...@openjdk.org> wrote:
>> This PR completes the CSS Transitions story (see #870) by adding >> interpolation support for backgrounds and borders, making them targetable by >> transitions. >> >> `Background` and `Border` objects are deeply immutable, but not >> interpolatable. Consider the following `Background`, which describes the >> background of a `Region`: >> >> >> Background { >> fills = [ >> BackgroundFill { >> fill = Color.RED >> } >> ] >> } >> >> >> Since backgrounds are deeply immutable, changing the region's background to >> another color requires the construction of a new `Background`, containing a >> new `BackgroundFill`, containing the new `Color`. >> >> Animating the background color using a CSS transition therefore requires the >> entire Background object graph to be interpolatable in order to generate >> intermediate backgrounds. >> >> More specifically, the following types will now implement `Interpolatable`. >> >> - `Insets` >> - `Background` >> - `BackgroundFill` >> - `BackgroundImage` >> - `BackgroundPosition` >> - `BackgroundSize` >> - `Border` >> - `BorderImage` >> - `BorderStroke` >> - `BorderWidths` >> - `CornerRadii` >> - `Stop` >> - `Paint` and all of its subclasses >> - `Margins` (internal type) >> - `BorderImageSlices` (internal type) >> >> ## Interpolation of composite objects >> >> As of now, only `Color`, `Point2D`, and `Point3D` are interpolatable. Each >> of these classes is an aggregate of `double` values, which are combined >> using linear interpolation. However, many of the new interpolatable classes >> comprise of not only `double` values, but a whole range of other types. This >> requires us to more precisely define what we mean by "interpolation". >> >> Mirroring the CSS specification, the `Interpolatable` interface defines >> several types of component interpolation: >> >> | Interpolation type | Description | >> |---|---| >> | default | Component types that implement `Interpolatable` are interpolated >> by calling the `interpolate(Object, double)}` method. | >> | linear | Two components are combined by linear interpolation such that `t >> = 0` produces the start value, and `t = 1` produces the end value. This >> interpolation type is usually applicable for numeric components. | >> | discrete | If two components cannot be meaningfully combined, the >> intermediate component value is equal to the start value for `t < 0.5` and >> equal to the end value for `t >= 0.5`. | >> | pairwise | Two lists are combined by pairwise interpolation. If the start >> list has fewer elements than the target list, the... > > Michael Strauß has updated the pull request incrementally with one additional > commit since the last revision: > > javadoc changes Testing this with the monkey tester. Select Button page, open CSS Playground, pasted the following CSS, click update. .test-content .button { -fx-border-color: red; -fx-border-width: 5; transition: -fx-border-color 1s linear, -fx-border-width 4s ease; } .test-content .button:hover { -fx-border-color: green; -fx-border-width: 200; } Changed value for `-fx-border-width: 200;` in `.test-content .button:hover { ` and clicked update (may need to do it several times). (the exact sequence was 10, 100, 1000, 200) Got Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: Cannot invoke "javafx.scene.layout.Border.getStrokes()" because "border" is null at javafx.graphics/javafx.scene.layout.BorderConverter.convertBack(BorderConverter.java:212) at javafx.graphics/javafx.scene.layout.BorderConverter.convertBack(BorderConverter.java:1) at javafx.graphics/javafx.css.StyleableObjectProperty.applyComponents(StyleableObjectProperty.java:159) at javafx.graphics/javafx.css.StyleableObjectProperty.applyStyle(StyleableObjectProperty.java:87) at javafx.graphics/javafx.scene.CssStyleHelper.resetToInitialValues(CssStyleHelper.java:485) at javafx.graphics/javafx.scene.CssStyleHelper.createStyleHelper(CssStyleHelper.java:193) at javafx.graphics/javafx.scene.Node.reapplyCss(Node.java:9874) at javafx.graphics/javafx.scene.Node.reapplyCss(Node.java:9903) at javafx.graphics/javafx.scene.Node.reapplyCss(Node.java:9903) at javafx.graphics/javafx.scene.Node.reapplyCss(Node.java:9903) at javafx.graphics/javafx.scene.Node.reapplyCss(Node.java:9903) at javafx.graphics/javafx.scene.Node.reapplyCss(Node.java:9903) at javafx.graphics/javafx.scene.Node.reapplyCss(Node.java:9903) at javafx.graphics/javafx.scene.Node.reapplyCss(Node.java:9903) at javafx.graphics/javafx.scene.Node.reapplyCss(Node.java:9903) at javafx.graphics/javafx.scene.Node.reapplyCss(Node.java:9903) at javafx.graphics/javafx.scene.Node.reapplyCss(Node.java:9903) at javafx.graphics/javafx.scene.Node.reapplyCss(Node.java:9903) at javafx.graphics/javafx.scene.Node.reapplyCSS(Node.java:9837) at javafx.graphics/javafx.scene.Scene$3.onChanged(Scene.java:1632) at javafx.base/com.sun.javafx.collections.TrackableObservableList.lambda$0(TrackableObservableList.java:44) at javafx.base/com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:162) at javafx.base/com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:71) at javafx.base/javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:246) at javafx.base/javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482) at javafx.base/javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541) at javafx.base/javafx.collections.ObservableListBase.endChange(ObservableListBase.java:210) at javafx.base/javafx.collections.ModifiableObservableListBase.remove(ModifiableObservableListBase.java:228) at javafx.base/javafx.collections.ModifiableObservableListBase.remove(ModifiableObservableListBase.java:216) at monkey_tester/com.oracle.tools.fx.monkey.tools.CssPlaygroundPane.applyStyleSheet(CssPlaygroundPane.java:204) at monkey_tester/com.oracle.tools.fx.monkey.tools.CssPlaygroundPane.update(CssPlaygroundPane.java:147) at monkey_tester/com.oracle.tools.fx.monkey.util.FX.lambda$5(FX.java:331) at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:232) at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:189) at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49) at javafx.base/javafx.event.Event.fireEvent(Event.java:199) at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8975) at javafx.controls/javafx.scene.control.Button.fire(Button.java:203) at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:207) at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274) at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247) at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:232) at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:189) at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) at javafx.base/javafx.event.Event.fireEvent(Event.java:199) at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3987) at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1893) at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2711) at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411) at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:1) at java.base/java.security.AccessController.doPrivileged(AccessController.java:400) at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$2(GlassViewEventHandler.java:450) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:430) at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449) at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:560) at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:946) at javafx.graphics/com.sun.glass.ui.mac.MacView.notifyMouse(MacView.java:128) ------------- PR Comment: https://git.openjdk.org/jfx/pull/1522#issuecomment-2334392278