source: trunk/src_apollo/org/apollo/gui/FramePlaybackBarRenderer.java@ 315

Last change on this file since 315 was 315, checked in by bjn8, 16 years ago

Apollo spin-off added

File size: 6.3 KB
Line 
1package org.apollo.gui;
2
3import java.awt.BasicStroke;
4import java.awt.Color;
5import java.awt.Graphics2D;
6import java.awt.Rectangle;
7import java.awt.Stroke;
8import java.util.LinkedList;
9import java.util.List;
10
11import javax.swing.SwingUtilities;
12
13import org.apollo.audio.ApolloPlaybackMixer;
14import org.apollo.audio.ApolloSubjectChangedEvent;
15import org.apollo.audio.structure.OverdubbedFrame;
16import org.apollo.audio.util.FrameLayoutDaemon;
17import org.apollo.audio.util.MultiTrackPlaybackController;
18import org.apollo.audio.util.PlaybackClock;
19import org.apollo.audio.util.Timeline;
20import org.apollo.audio.util.PlaybackClock.PlaybackClockListener;
21import org.apollo.mvc.Observer;
22import org.apollo.mvc.Subject;
23import org.apollo.mvc.SubjectChangedEvent;
24import org.apollo.util.AudioMath;
25import org.apollo.widgets.FramePlayer;
26import org.expeditee.gui.Browser;
27import org.expeditee.gui.DisplayIO;
28import org.expeditee.gui.Frame;
29import org.expeditee.gui.FrameGraphics;
30
31/**
32 * Renders playback bars while the multi playback controller is playing.
33 * Depending on which frame the user is on etc...
34 *
35 * @author Brook Novak
36 *
37 */
38public class FramePlaybackBarRenderer implements PlaybackClockListener, Observer {
39
40 /** Relative to the current multi-track groups root frame. */
41 private long currentMSPosition = 0;
42
43 private List<Integer> pixelPositions = new LinkedList<Integer>();
44 private String pixelPositionsParent = null; // framename
45
46 private Timeline currentTimeline = null;
47
48 private PlaybackFrameBarUpdator updator = new PlaybackFrameBarUpdator();
49
50 private static final int BAR_STROKE_THICKNESS = 2;
51 private static final Stroke BAR_STROKE = new BasicStroke(BAR_STROKE_THICKNESS);
52 private static final Color BAR_COLOR = Color.DARK_GRAY;
53
54 private static FramePlaybackBarRenderer instance = new FramePlaybackBarRenderer();
55
56 private FramePlaybackBarRenderer() {
57 MultiTrackPlaybackController.getInstance().addObserver(this);
58 //DisplayIO.addDisplayIOObserver(this);
59 FrameLayoutDaemon.getInstance().addObserver(this);
60 }
61
62 public static FramePlaybackBarRenderer getInstance() {
63 return instance;
64 }
65
66 /**
67 * {@inheritDoc}
68 */
69 public Subject getObservedSubject() {
70 return null;
71 }
72
73 /**
74 * {@inheritDoc}
75 */
76 public void setObservedSubject(Subject parent) {
77 }
78
79 /**
80 * {@inheritDoc}
81 */
82 public void modelChanged(Subject source, SubjectChangedEvent event) {
83
84 if (source == FrameLayoutDaemon.getInstance()) {
85 currentTimeline = FrameLayoutDaemon.getInstance().getLastComputedTimeline();
86
87 updator.run();
88 // Asumming refresh will occur
89
90 return;
91 }
92
93 switch (event.getID()) {
94 case ApolloSubjectChangedEvent.PLAYBACK_STARTED:
95 PlaybackClock.getInstance().addPlaybackClockListener(this);
96 break;
97
98 case ApolloSubjectChangedEvent.PLAYBACK_STOPPED:
99 PlaybackClock.getInstance().removePlaybackClockListener(this);
100
101 if (MultiTrackPlaybackController.getInstance().isMarkedAsPaused() &&
102 FramePlayer.FRAME_PLAYERMASTER_CHANNEL_ID.equals(
103 MultiTrackPlaybackController.getInstance().getCurrentMasterChannelID())) {
104
105 currentMSPosition = AudioMath.framesToMilliseconds(
106 MultiTrackPlaybackController.getInstance().getLastSuspendedFrame(),
107 ApolloPlaybackMixer.getInstance().getLiveAudioFormat());
108
109 updator.run();
110
111 } else {
112 invalidate();
113 currentMSPosition = -1;
114 pixelPositions.clear();
115 }
116
117 FrameGraphics.refresh(true);
118
119
120 break;
121
122 case ApolloSubjectChangedEvent.PAUSE_MARK_CHANGED:
123
124
125 invalidate();
126 currentMSPosition = -1;
127 pixelPositions.clear();
128 FrameGraphics.refresh(true);
129
130 break;
131 }
132
133
134 }
135
136
137// /**
138// * {@inheritDoc}
139// */
140// public void frameChanged() {
141//
142// // TODO: Update positions... could be paused!
143//
144// // ...
145//
146// }
147//
148
149 private void invalidate() {
150 if (Browser._theBrowser == null) return;
151
152 int height = Browser._theBrowser.getHeight();
153
154 for (Integer n : pixelPositions) {
155 FrameGraphics.invalidateArea(new Rectangle(n - 1, 0, BAR_STROKE_THICKNESS + 2, height));
156 }
157 }
158
159 public void paint(Graphics2D g) {
160 if (Browser._theBrowser == null) return;
161
162 Frame currentFrame = DisplayIO.getCurrentFrame();
163
164 if (currentFrame == null || currentFrame.getName() == null || pixelPositionsParent == null ||
165 !currentFrame.getName().equals(pixelPositionsParent)) return;
166
167 int height = Browser._theBrowser.getHeight();
168
169 g.setColor(BAR_COLOR);
170 g.setStroke(BAR_STROKE);
171
172 for (Integer n : pixelPositions) {
173 g.drawLine(n, 0, n, height);
174 }
175 }
176
177 /**
178 * {@inheritDoc}
179 */
180 public void onTick(long framePosition, long msPosition) {
181
182 if (framePosition < 0) return; // let stop event handle it
183
184 // Convert the audio mixers frame position to the multiplaybacks frame position
185
186 int fpos = (int)(framePosition
187 - MultiTrackPlaybackController.getInstance().getLastInitiationFrame()
188 + MultiTrackPlaybackController.getInstance().getLastStartFrame());
189
190 // Clamp
191 if (fpos > MultiTrackPlaybackController.getInstance().getLastEndFrame())
192 fpos = MultiTrackPlaybackController.getInstance().getLastEndFrame();
193
194 currentMSPosition = AudioMath.framesToMilliseconds(
195 fpos,
196 ApolloPlaybackMixer.getInstance().getLiveAudioFormat());
197
198 // Notes: the clock will queue a refresh for the frame after this
199 // event proccesses ...
200 SwingUtilities.invokeLater(updator);
201 }
202
203 /**
204 * Note: refreshing is up to caller
205 *
206 * @author Brook Novak
207 */
208 private class PlaybackFrameBarUpdator implements Runnable {
209 public void run() {
210
211 if (currentMSPosition == -1 || currentTimeline == null) return;
212
213 Frame currentFrame = DisplayIO.getCurrentFrame();
214
215 if (currentFrame == null || currentFrame.getName() == null) return;
216
217 OverdubbedFrame od = MultiTrackPlaybackController.getInstance().getCurrentODFrame();
218 if (od == null) return;
219
220 // Invalidate old positions
221 invalidate();
222 pixelPositions.clear();
223
224 long firstInitTime = od.getFirstInitiationTime();
225
226 List<Integer> msPositions = od.getMSPositions(
227 currentFrame.getName(),
228 currentMSPosition + firstInitTime);
229
230 // Convert ms positions to pixel positions according to the current timeline
231 for (Integer n : msPositions) {
232 pixelPositions.add(new Integer(currentTimeline.getXAtMSTime(n + currentTimeline.getFirstInitiationTime())));
233 }
234
235 pixelPositionsParent = currentFrame.getName();
236
237 // Invalidate new positions
238 invalidate();
239 }
240 }
241
242
243
244}
Note: See TracBrowser for help on using the repository browser.