|
21 | 21 | import java.util.Collection; |
22 | 22 | import java.util.List; |
23 | 23 |
|
| 24 | +import javafx.animation.KeyFrame; |
| 25 | +import javafx.animation.KeyValue; |
| 26 | +import javafx.animation.Timeline; |
| 27 | +import javafx.animation.TimelineBuilder; |
| 28 | +import javafx.beans.property.DoubleProperty; |
| 29 | +import javafx.event.ActionEvent; |
| 30 | +import javafx.event.EventHandler; |
24 | 31 | import javafx.fxml.FXML; |
25 | 32 | import javafx.scene.Node; |
26 | 33 | import javafx.scene.control.Button; |
|
29 | 36 | import javafx.scene.image.ImageView; |
30 | 37 | import javafx.scene.layout.HBox; |
31 | 38 | import javafx.scene.layout.VBox; |
32 | | - |
| 39 | +import javafx.util.Duration; |
33 | 40 | import javax.inject.Inject; |
34 | 41 |
|
35 | 42 | /** |
@@ -169,24 +176,89 @@ private void moveStepRight() { |
169 | 176 | private void expand() { |
170 | 177 | if (expanded) { |
171 | 178 | for (InputSocketController input : inputSockets) { |
| 179 | + inputs.setMaxHeight(inputs.getHeight()); |
| 180 | + inputs.setPrefHeight(inputs.getHeight()); |
172 | 181 | if (input.getSocket().getConnections().isEmpty()) { |
173 | | - input.getRoot().setVisible(false); |
174 | | - input.getRoot().setManaged(false); |
| 182 | + fadeOut(input); |
175 | 183 | } |
176 | 184 | } |
| 185 | + closeUp(); |
177 | 186 | expandIcon.setImage(new Image("/edu/wpi/grip/ui/icons/down.png")); |
178 | 187 | expanded = false; |
179 | 188 | } else { |
180 | 189 | for (InputSocketController input : inputSockets) { |
181 | | - input.getRoot().setManaged(true); |
182 | | - input.getRoot().setVisible(true); |
| 190 | + fadeIn(input); |
183 | 191 | } |
| 192 | + reopen(); |
184 | 193 | expandIcon.setImage(new Image("/edu/wpi/grip/ui/icons/up.png")); |
185 | 194 | expanded = true; |
186 | 195 | } |
187 | 196 |
|
188 | 197 | } |
189 | 198 |
|
| 199 | + /** |
| 200 | + * Makes an animation to make an input socket fade out over 0.1 seconds. |
| 201 | + * |
| 202 | + * @param input the input socket controller that will be faded out. |
| 203 | + */ |
| 204 | + private void fadeOut(InputSocketController input) { |
| 205 | + DoubleProperty opacity = input.getRoot().opacityProperty(); |
| 206 | + Timeline fadeOut = new Timeline( |
| 207 | + new KeyFrame(Duration.ZERO, new KeyValue(opacity, 1.0)), |
| 208 | + new KeyFrame(new Duration(100), new KeyValue(opacity, 0.0))); |
| 209 | + fadeOut.setOnFinished(new EventHandler<ActionEvent>() { |
| 210 | + @Override |
| 211 | + public void handle(ActionEvent event) { |
| 212 | + for (InputSocketController input : inputSockets) { |
| 213 | + input.getRoot().setVisible(false); |
| 214 | + input.getRoot().setManaged(false); |
| 215 | + } |
| 216 | + } |
| 217 | + }); |
| 218 | + fadeOut.play(); |
| 219 | + } |
| 220 | + |
| 221 | + /** |
| 222 | + * Makes an animation to make an input socket fade in over 0.25 seconds. |
| 223 | + * |
| 224 | + * @param input the input socket controller that will be faded out. |
| 225 | + */ |
| 226 | + private void fadeIn(InputSocketController input) { |
| 227 | + input.getRoot().setVisible(true); |
| 228 | + DoubleProperty opacity = input.getRoot().opacityProperty(); |
| 229 | + Timeline fadeIn = new Timeline( |
| 230 | + new KeyFrame(new Duration(250), new KeyValue(opacity, 1.0))); |
| 231 | + fadeIn.setOnFinished(new EventHandler<ActionEvent>() { |
| 232 | + @Override |
| 233 | + public void handle(ActionEvent event) { |
| 234 | + for (InputSocketController input : inputSockets) { |
| 235 | + input.getRoot().setManaged(true); |
| 236 | + } |
| 237 | + } |
| 238 | + }); |
| 239 | + fadeIn.play(); |
| 240 | + } |
| 241 | + |
| 242 | + /** |
| 243 | + * Makes an animation to make the input vbox slide closed over .25 seconds |
| 244 | + */ |
| 245 | + private void closeUp() { |
| 246 | + Timeline animation = TimelineBuilder.create().cycleCount(1).keyFrames( |
| 247 | + new KeyFrame(Duration.seconds(0.25), |
| 248 | + new KeyValue(inputs.prefHeightProperty(), 0))).build(); |
| 249 | + animation.play(); |
| 250 | + } |
| 251 | + |
| 252 | + /** |
| 253 | + * Makes an animation to make the input vbox slide open over .1 seconds |
| 254 | + */ |
| 255 | + private void reopen() { |
| 256 | + Timeline animation = TimelineBuilder.create().cycleCount(1).keyFrames( |
| 257 | + new KeyFrame(Duration.seconds(0.1), |
| 258 | + new KeyValue(inputs.prefHeightProperty(), inputs.getMaxHeight()))).build(); |
| 259 | + animation.play(); |
| 260 | + } |
| 261 | + |
190 | 262 | /** |
191 | 263 | * Used for assisted injects. Guice will automatically create an instance of this interface so we |
192 | 264 | * can create step controllers. This lets us use injection with StepController even though it |
|
0 commit comments