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