source: trunk/src/org/apollo/items/FramePlaybackLauncher.java@ 1102

Last change on this file since 1102 was 1102, checked in by davidb, 6 years ago

Reworking of the code-base to separate logic from graphics. This version of Expeditee now supports a JFX graphics as an alternative to SWING

File size: 8.1 KB
Line 
1package org.apollo.items;
2
3import org.apollo.ApolloSystem;
4import org.apollo.audio.SampledAudioManager;
5import org.apollo.audio.structure.OverdubbedFrame;
6import org.apollo.audio.structure.TrackGraphLoopException;
7import org.apollo.audio.util.MultiTrackPlaybackController;
8import org.apollo.audio.util.SoundDesk;
9import org.apollo.audio.util.Timeline;
10import org.apollo.audio.util.MultiTrackPlaybackController.MultitrackLoadListener;
11import org.apollo.gui.FrameLayoutDaemon;
12import org.apollo.gui.Strokes;
13import org.apollo.io.IconRepository;
14import org.apollo.util.AudioMath;
15import org.apollo.util.Mutable;
16import org.apollo.util.ODFrameHeirarchyFetcher;
17import org.apollo.util.ODFrameHeirarchyFetcher.ODFrameReceiver;
18import org.apollo.widgets.FramePlayer;
19import org.expeditee.core.Colour;
20import org.expeditee.core.Dimension;
21import org.expeditee.core.Fill;
22import org.expeditee.core.GradientFill;
23import org.expeditee.core.Point;
24import org.expeditee.core.Stroke;
25import org.expeditee.core.bounds.AxisAlignedBoxBounds;
26import org.expeditee.core.bounds.Bounds;
27import org.expeditee.gio.EcosystemManager;
28import org.expeditee.gio.GraphicsManager;
29import org.expeditee.gui.Browser;
30import org.expeditee.gui.DisplayController;
31import org.expeditee.gui.Frame;
32import org.expeditee.gui.FrameIO;
33import org.expeditee.gui.MessageBay;
34import org.expeditee.items.Item;
35import org.expeditee.items.ItemParentStateChangedEvent;
36
37/**
38 * A transient widget that destroys self once anchored...
39 * once anchored it commences playback of a frame if there is something to play.
40 *
41 * @author Brook Novak
42 *
43 */
44public class FramePlaybackLauncher extends Item {
45
46 private static int WIDTH = 80;
47 private static int HEIGHT = 80;
48 private static Stroke BORDER_STROKE = Strokes.SOLID_1;
49
50 private static final Colour BASE_COLOR = Colour.FromRGB255(60, 148, 255);
51 private static final Colour HIGHLIGHT_COLOR = Colour.FromRGB255(253, 255, 201);
52
53 private String frameToPlay = null;
54
55 /**
56 * @param frameToPlay
57 * The frame to begin playback from. Null to play current frame.
58 */
59 public FramePlaybackLauncher(String frameToPlay) {
60 this.setID(getParentOrCurrentFrame().getNextItemID());
61 this.frameToPlay = frameToPlay;
62 }
63
64 @Override
65 public Item copy() {
66 FramePlaybackLauncher copy = new FramePlaybackLauncher(frameToPlay);
67
68 DuplicateItem(this, copy);
69
70 return copy;
71 }
72
73 @Override
74 public Item merge(Item merger, int mouseX, int mouseY) {
75 return null;
76 }
77
78 @Override
79 public void paint()
80 {
81 if (Browser._theBrowser == null) return;
82
83 GraphicsManager g = EcosystemManager.getGraphicsManager();
84
85 Fill fill = null;
86 if (ApolloSystem.useQualityGraphics) {
87 Point fromPoint = new Point(_x + (WIDTH / 2), _y);
88 Point toPoint = new Point(_x + (WIDTH / 2), _y + HEIGHT - (HEIGHT / 5));
89 fill = new GradientFill(HIGHLIGHT_COLOR, fromPoint, BASE_COLOR, toPoint);
90 } else {
91 fill = new Fill(BASE_COLOR);
92 }
93
94 Point topLeft = new Point((int)_x, (int)_y);
95 Dimension size = new Dimension(WIDTH, HEIGHT);
96 g.drawRectangle(topLeft, size, 0.0, fill, Colour.BLACK, BORDER_STROKE, null);
97
98 /*IconRepository.getIcon("frameplay.png").paintIcon(
99 Browser._theBrowser.getContentPane(), g, getX() + 25, getY() + 25);*/
100
101 g.drawImage(IconRepository.getIcon("frameplay.png"), new Point(getX() + 25, getY() + 25));
102
103 }
104
105 @Override
106 public void setAnnotation(boolean val) {
107 }
108
109
110 @Override
111 public int getHeight() {
112 return HEIGHT;
113 }
114
115 @Override
116 public Integer getWidth() {
117 return WIDTH;
118 }
119
120 @Override
121 public Bounds updateBounds()
122 {
123 return new AxisAlignedBoxBounds((int) _x, (int) _y, WIDTH, HEIGHT);
124 }
125
126 @Override
127 public void onParentStateChanged(ItemParentStateChangedEvent e) {
128 super.onParentStateChanged(e);
129
130 switch (e.getEventType()) {
131
132 case ItemParentStateChangedEvent.EVENT_TYPE_ADDED:
133 case ItemParentStateChangedEvent.EVENT_TYPE_ADDED_VIA_OVERLAY:
134 case ItemParentStateChangedEvent.EVENT_TYPE_SHOWN:
135 case ItemParentStateChangedEvent.EVENT_TYPE_SHOWN_VIA_OVERLAY:
136 // todo: Invoke later for concurrent modification possibility?
137 selfDestruct();
138 break;
139
140 }
141 }
142
143 private void selfDestruct()
144 {
145 Frame parent = getParent();
146 parent.removeItem(this);
147
148 if (DisplayController.getCurrentFrame() == null) return;
149
150 Frame audioFrame = null;
151
152 // Flag as null if frame to play is actually current frame
153 if (frameToPlay != null && frameToPlay.equals(DisplayController.getCurrentFrame().getName()))
154 frameToPlay = null;
155
156 if (frameToPlay == null) {
157 audioFrame = DisplayController.getCurrentFrame();
158 } else {
159 audioFrame = FrameIO.LoadFrame(frameToPlay);
160 }
161
162 if (audioFrame == null) {
163 if (frameToPlay != null)
164 MessageBay.errorMessage("Unable to play frame \"" + frameToPlay + "\" - unknown frame");
165 else
166 MessageBay.errorMessage("Unable to play current frame");
167
168 } else {
169
170 if (frameToPlay == null) {
171
172 Timeline tl = FrameLayoutDaemon.getInstance().getLastComputedTimeline();
173 if (tl == null)
174 tl = FrameLayoutDaemon.inferTimeline(audioFrame);
175 if (tl == null) return;
176
177 long initiateMS = tl.getMSTimeAtX((int)_x);
178
179 // Clamp
180 if (initiateMS < tl.getFirstInitiationTime())
181 initiateMS = tl.getFirstInitiationTime();
182
183 else if (initiateMS > (tl.getFirstInitiationTime() + tl.getRunningTime()))
184 initiateMS = tl.getFirstInitiationTime() + tl.getRunningTime();
185
186 int startFrame = AudioMath.millisecondsToFrames(
187 initiateMS - tl.getFirstInitiationTime(),
188 SampledAudioManager.getInstance().getDefaultPlaybackFormat());
189
190 playFrame(audioFrame.getName(), startFrame);
191
192 } else {
193 // Fetch the audio graph for the frame
194 GraphReceiver receiver = new GraphReceiver(DisplayController.getCurrentFrame());
195 ODFrameHeirarchyFetcher.getInstance().doFetch(audioFrame.getName(), receiver);
196 // The callback will later begin playback
197 }
198
199
200 }
201 }
202
203 private void playFrame(String framename, int startFrame) {
204
205 // To ensure that the frame channels are not in use
206 MultiTrackPlaybackController.getInstance().stopPlayback();
207 SoundDesk.getInstance().freeChannels(FramePlayer.FRAME_PLAYERMASTER_CHANNEL_ID);
208
209 FramePlayer.playFrame(
210 new MultitrackLoadListener() {
211
212 public void multiplaybackLoadStatusUpdate(int id, Object state) {
213 // Ignore
214 }
215
216 },
217 framename,
218 false,
219 startFrame,
220 Integer.MAX_VALUE
221 );
222
223 }
224
225 private class GraphReceiver implements ODFrameReceiver {
226
227 private Frame fromFrame;
228
229 public GraphReceiver(Frame fromFrame) {
230 assert(fromFrame != null);
231 this.fromFrame = fromFrame;
232 }
233 public void receiveResult(OverdubbedFrame odFrame, TrackGraphLoopException loopEx) {
234
235 if(odFrame == null){
236 if (loopEx != null)
237 MessageBay.errorMessage("Unable to play frame \"" + frameToPlay + "\" - bad structure");
238 return;
239 }
240
241 OverdubbedFrame fromODFrame = odFrame.getChild(fromFrame.getName());
242
243 int startFrame = 0;
244
245 // Get the timeline for the frame that the playback will be initated from
246 Timeline tl = FrameLayoutDaemon.getInstance().getTimeline(fromFrame);
247
248 if (tl == null || fromODFrame == null) {
249 // The user tried to play a frame, unreachable from some other frame.
250 // Thus the start frame will be hence taken as a percentage of the whole frame
251
252 float percent = _x / EcosystemManager.getGraphicsManager().getWindowSize().getWidth();
253 if (percent < 0) percent = 0;
254 if (percent > 1) percent = 1;
255
256 startFrame = AudioMath.millisecondsToFrames(
257 (long)((float)odFrame.calculateRunningTime() * percent),
258 SampledAudioManager.getInstance().getDefaultPlaybackFormat());
259
260 } else {
261
262 // Find the frames absolute init time
263 Mutable.Long childFrameABSStartTime = odFrame.getChildFrameInitiationTime(fromFrame.getName());
264
265 if (childFrameABSStartTime == null)
266 return; // nothing to play
267
268 long deltaMS = tl.getMSTimeAtX((int)_x) - fromODFrame.getFirstInitiationTime();
269
270 startFrame = AudioMath.millisecondsToFrames(
271 childFrameABSStartTime.value + deltaMS,
272 SampledAudioManager.getInstance().getDefaultPlaybackFormat());
273
274 }
275
276 playFrame(odFrame.getFrameName(), startFrame);
277
278 }
279 }
280
281}
Note: See TracBrowser for help on using the repository browser.