source: trunk/src_apollo/org/apollo/items/FramePlaybackLauncher.java@ 489

Last change on this file since 489 was 489, checked in by davidb, 11 years ago

Changes made when making Apollo run as an applet

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