11/*
2- * Copyright (c) 2009-2020 jMonkeyEngine
2+ * Copyright (c) 2009-2024 jMonkeyEngine
33 * All rights reserved.
44 *
55 * Redistribution and use in source and binary forms, with or without
4343import java .awt .event .ActionListener ;
4444import java .beans .PropertyChangeEvent ;
4545import java .io .IOException ;
46+ import java .util .ArrayList ;
47+ import java .util .List ;
4648import java .util .concurrent .ExecutionException ;
4749import javax .swing .Action ;
4850import javax .swing .SwingUtilities ;
5860
5961/**
6062 * Visual representation of the AnimClip Class in the Scene Explorer
61- * @author MeFisto94
63+ * @author MeFisto94, neph1
6264 */
6365@ org .openide .util .lookup .ServiceProvider (service = SceneExplorerNode .class )
6466@ SuppressWarnings ({"unchecked" , "rawtypes" })
@@ -67,7 +69,6 @@ public class JmeAnimClip extends AbstractSceneExplorerNode {
6769 private AnimClip animClip ;
6870 private Image icon ;
6971 private JmeAnimComposer jmeControl ;
70- private boolean playing = false ;
7172
7273 public JmeAnimClip () {
7374 }
@@ -103,7 +104,7 @@ public Image getOpenedIcon(int type) {
103104 }
104105
105106 public void toggleIcon (boolean enabled ) {
106- if (!playing ) {
107+ if (!enabled ) {
107108 icon = IconList .animation .getImage ();
108109 } else {
109110 icon = IconList .animationPlay .getImage ();
@@ -113,13 +114,12 @@ public void toggleIcon(boolean enabled) {
113114
114115 @ Override
115116 public Action getPreferredAction () {
116- return Actions .alwaysEnabled (new PlayAction (), "Play" , "" , false );
117+ return Actions .alwaysEnabled (new PlayAction (AnimComposer . DEFAULT_LAYER ), "Play" , "" , false );
117118 }
118119
119- private void play () {
120- playing = !playing ;
121- toggleIcon (playing );
122- jmeControl .setAnimClip (this );
120+ private void play (String layer ) {
121+ toggleIcon (true );
122+ jmeControl .setAnimClip (layer , this );
123123 }
124124
125125 @ Override
@@ -142,13 +142,25 @@ public void setChanged() {
142142
143143 @ Override
144144 public Action [] getActions (boolean context ) {
145- return new Action []{Actions .alwaysEnabled (new PlayAction (), playing ? "Stop" : "Play" , "" , false ),
146- SystemAction .get (RenameAction .class ),
147- SystemAction .get (DeleteAction .class ),
148- //Actions.alwaysEnabled(new EffectTrackWizardAction(jmeControl.getLookup().lookup(AnimComposer.class).getSpatial(), this), "Add Effect Track", "", false),
149- //Actions.alwaysEnabled(new AudioTrackWizardAction(jmeControl.getLookup().lookup(AnimComposer.class).getSpatial(), this), "Add Audio Track", "", false),
150- // @TODO: not working yet, Actions.alwaysEnabled(new ExtractAnimationAction(), "Extract sub-animation", "", true)
151- };
145+ final AnimComposer control = jmeControl .getLookup ().lookup (AnimComposer .class );
146+ if (control == null ) {
147+ return new Action []{
148+ Actions .alwaysEnabled (new PlayAction (AnimComposer .DEFAULT_LAYER ), jmeControl .getPlaying (AnimComposer .DEFAULT_LAYER ) == this ? "Stop" : "Play" , "" , false ),
149+ SystemAction .get (RenameAction .class ),
150+ SystemAction .get (DeleteAction .class ),
151+ };
152+ }
153+ final String [] layers = control .getLayerNames ().stream ().toArray (String [] ::new );
154+
155+ List <Action > playActions = new ArrayList <>();
156+
157+ for (String layer : layers ) {
158+ playActions .add (Actions .alwaysEnabled (new PlayAction (layer ), jmeControl .getPlaying (layer ) == this ? "Stop " + layer : "Play " + layer , "" , false ));
159+ }
160+ playActions .add (SystemAction .get (RenameAction .class ));
161+ playActions .add (SystemAction .get (DeleteAction .class ));
162+ final Action [] actions = new Action [playActions .size ()];
163+ return playActions .toArray (actions );
152164 }
153165
154166 @ Override
@@ -157,19 +169,19 @@ public boolean canDestroy() {
157169 }
158170
159171 public void stop () {
160- playing = false ;
161- toggleIcon (playing );
172+ toggleIcon (false );
162173 }
163174
164175 @ Override
165176 public void destroy () throws IOException {
166177 super .destroy ();
167178 final AnimComposer control = jmeControl .getLookup ().lookup (AnimComposer .class );
168- if (playing ) {
179+
180+ if (jmeControl .getPlaying (AnimComposer .DEFAULT_LAYER ) == this ) {
169181 control .removeCurrentAction (AnimComposer .DEFAULT_LAYER );
170- jmeControl .setAnimClip (null );
171-
182+ jmeControl .setAnimClip (AnimComposer .DEFAULT_LAYER , null );
172183 }
184+
173185 lookupContents .remove (JmeAnimClip .this .animClip );
174186 lookupContents .remove (this );
175187 SceneApplication .getApplication ().enqueue ( () -> {
@@ -202,6 +214,13 @@ public Node[] createNodes(Object key, DataObject key2, boolean cookie) {
202214 }
203215
204216 class PlayAction implements ActionListener {
217+
218+ private final String layer ;
219+
220+ public PlayAction (String layer ) {
221+ this .layer = layer ;
222+ }
223+
205224 @ Override
206225 public void actionPerformed (ActionEvent e ) {
207226 final AnimComposer control = jmeControl .getLookup ().lookup (AnimComposer .class );
@@ -211,14 +230,14 @@ public void actionPerformed(ActionEvent e) {
211230
212231 try {
213232 SceneApplication .getApplication ().enqueue (() -> {
214- if (playing ) { // Stop Playing
215- control .removeCurrentAction (AnimComposer . DEFAULT_LAYER );
216- jmeControl .setAnimClip (null );
233+ if (jmeControl . getPlaying ( layer ) == JmeAnimClip . this ) { // Stop Playing
234+ control .removeCurrentAction (layer );
235+ jmeControl .setAnimClip (layer , null );
217236 return null ;
218237 } else {
219- control .setCurrentAction (animClip .getName ());
238+ control .setCurrentAction (animClip .getName (), layer );
220239 java .awt .EventQueue .invokeLater (() -> {
221- play ();
240+ play (layer );
222241 });
223242 return null ;
224243 }
0 commit comments