| <?xml version="1.0" encoding="UTF-8"?> |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to you under the Apache License, |
| Version 2.0 (the "License"); you may not use this file except in |
| compliance with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| <document id="effects.transitions"> |
| <properties> |
| <title>Transitions</title> |
| </properties> |
| |
| <body> |
| <p> |
| Transitions are used to execute a set of operations over a given period of time, |
| producing an animation effect. For example, they are used to slide sheets in and out of |
| view, fade menu items, and "slide" from one card to another in a card pane. |
| </p> |
| |
| <p> |
| Because transitions are often very specific to the item on which they operate, Pivot |
| does not include any stock transitions. However, it is very easy to create one. The |
| following application demonstrates the use of a "collapse transition" that causes a |
| button to shrink and fade as it is removed from its parent container: |
| </p> |
| |
| <application class="org.apache.pivot.wtk.ScriptApplication" |
| width="180" height="40"> |
| <libraries> |
| <library>core</library> |
| <library>wtk</library> |
| <library>wtk-terra</library> |
| <library>tutorials</library> |
| </libraries> |
| <startup-properties> |
| <src>/org/apache/pivot/tutorials/effects/transitions.bxml</src> |
| </startup-properties> |
| </application> |
| |
| <p>The BXML source for the example is shown below. It simply creates a box pane containing several push buttons:</p> |
| |
| <source type="xml" location="org/apache/pivot/tutorials/effects/transitions.bxml"> |
| <![CDATA[ |
| <effects:Transitions title="Transitions" maximized="true" |
| xmlns:bxml="http://pivot.apache.org/bxml" |
| xmlns:effects="org.apache.pivot.tutorials.effects" |
| xmlns="org.apache.pivot.wtk"> |
| <BoxPane styles="{padding:4, spacing:4}"> |
| <PushButton bxml:id="button1" buttonData="One"/> |
| <PushButton bxml:id="button2" buttonData="Two"/> |
| <PushButton bxml:id="button3" buttonData="Three"/> |
| <PushButton bxml:id="button4" buttonData="Four"/> |
| </BoxPane> |
| </effects:Transitions> |
| ]]> |
| </source> |
| |
| <p> |
| The Java source for the application is below. It attaches a button press listener to |
| each button that starts the collapse transition when the button is pressed (or reverses |
| it if one is already running): |
| </p> |
| |
| <source type="java" location="org/apache/pivot/tutorials/effects/Transitions.java"> |
| <![CDATA[ |
| package org.apache.pivot.tutorials.effects; |
| |
| import java.net.URL; |
| |
| import org.apache.pivot.beans.Bindable; |
| import org.apache.pivot.collections.Map; |
| import org.apache.pivot.util.Resources; |
| import org.apache.pivot.wtk.Button; |
| import org.apache.pivot.wtk.ButtonPressListener; |
| import org.apache.pivot.wtk.Component; |
| import org.apache.pivot.wtk.PushButton; |
| import org.apache.pivot.wtk.Window; |
| import org.apache.pivot.wtk.effects.Transition; |
| import org.apache.pivot.wtk.effects.TransitionListener; |
| |
| public class Transitions extends Window implements Bindable { |
| private PushButton button1 = null; |
| private PushButton button2 = null; |
| private PushButton button3 = null; |
| private PushButton button4 = null; |
| |
| private CollapseTransition collapseTransition = null; |
| |
| public static int TRANSITION_DURATION = 250; |
| public static int TRANSITION_RATE = 30; |
| |
| @Override |
| public void initialize(Map<String, Object> namespace, URL location, Resources resources) { |
| button1 = (PushButton)namespace.get("button1"); |
| button2 = (PushButton)namespace.get("button2"); |
| button3 = (PushButton)namespace.get("button3"); |
| button4 = (PushButton)namespace.get("button4"); |
| |
| ButtonPressListener buttonPressListener = new ButtonPressListener() { |
| @Override |
| public void buttonPressed(final Button button) { |
| if (collapseTransition == null) { |
| collapseTransition = new CollapseTransition(button, TRANSITION_DURATION, TRANSITION_RATE); |
| |
| TransitionListener transitionListener = new TransitionListener() { |
| @Override |
| public void transitionCompleted(Transition transition) { |
| CollapseTransition collapseTransition = (CollapseTransition)transition; |
| |
| if (!transition.isReversed()) { |
| Component component = collapseTransition.getComponent(); |
| component.getParent().remove(component); |
| } |
| |
| Transitions.this.collapseTransition = null; |
| } |
| }; |
| |
| collapseTransition.start(transitionListener); |
| } else { |
| collapseTransition.reverse(); |
| |
| if (collapseTransition.getComponent() != button) { |
| collapseTransition.end(); |
| } |
| } |
| } |
| }; |
| |
| button1.getButtonPressListeners().add(buttonPressListener); |
| button2.getButtonPressListeners().add(buttonPressListener); |
| button3.getButtonPressListeners().add(buttonPressListener); |
| button4.getButtonPressListeners().add(buttonPressListener); |
| } |
| } |
| ]]> |
| </source> |
| |
| <p> |
| Finally, the source for the transition itself is shown below: |
| </p> |
| |
| <source type="java" location="org/apache/pivot/tutorials/effects/CollapseTransition.java"> |
| <![CDATA[ |
| package org.apache.pivot.tutorials.effects; |
| |
| import org.apache.pivot.wtk.Component; |
| import org.apache.pivot.wtk.effects.FadeDecorator; |
| import org.apache.pivot.wtk.effects.Transition; |
| import org.apache.pivot.wtk.effects.TransitionListener; |
| import org.apache.pivot.wtk.effects.easing.Easing; |
| import org.apache.pivot.wtk.effects.easing.Quadratic; |
| |
| public class CollapseTransition extends Transition { |
| private Component component; |
| private int initialWidth; |
| private Easing easing = new Quadratic(); |
| private FadeDecorator fadeDecorator = new FadeDecorator(); |
| |
| public CollapseTransition(Component component, int duration, int rate) { |
| super(duration, rate, false); |
| |
| this.component = component; |
| initialWidth = component.getWidth(); |
| } |
| |
| public Component getComponent() { |
| return component; |
| } |
| |
| @Override |
| public void start(TransitionListener transitionListener) { |
| component.getDecorators().add(fadeDecorator); |
| |
| super.start(transitionListener); |
| } |
| |
| @Override |
| public void stop() { |
| component.getDecorators().remove(fadeDecorator); |
| |
| super.stop(); |
| } |
| |
| @Override |
| protected void update() { |
| float percentComplete = getPercentComplete(); |
| |
| if (percentComplete < 1.0f) { |
| int duration = getDuration(); |
| int width = (int)(initialWidth * (1.0f - percentComplete)); |
| |
| width = (int)easing.easeInOut(getElapsedTime(), initialWidth, width - initialWidth, duration); |
| |
| component.setPreferredWidth(width); |
| |
| fadeDecorator.setOpacity(1.0f - percentComplete); |
| component.repaint(); |
| } |
| } |
| } |
| ]]> |
| </source> |
| |
| <p> |
| In the transition's <tt>start()</tt> method, it attaches a fade decorator to the |
| component, which is later used by the <tt>update()</tt> method to produce the fade |
| part of the effect. The decorator is removed in <tt>stop()</tt>. |
| </p> |
| |
| <p> |
| The <tt>update()</tt> method is called periodically to update the state of the |
| transition. In this example, it will be called 30 times per second for a duration of |
| 250 milliseconds. Each time <tt>update()</tt> is called, the transition adjusts the |
| opacity of the fade decorator to the inverse of the completion percentage and sets the |
| component's preferred width to the given percentage of the component's initial width |
| when the transition started. When the transition is complete, the opacity value will be |
| zero, as will its preferred width. It is then removed from the parent box pane by the |
| transition listener that had been passed to the <tt>start()</tt> method. |
| </p> |
| </body> |
| </document> |