1 | package org.apollo.gui;
|
---|
2 |
|
---|
3 | import java.util.LinkedList;
|
---|
4 |
|
---|
5 | import org.apollo.ApolloGestureActions;
|
---|
6 | import org.apollo.audio.util.Timeline;
|
---|
7 | import org.apollo.items.FramePlaybackLauncher;
|
---|
8 | import org.apollo.items.RecordOverdubLauncher;
|
---|
9 | import org.apollo.util.Mutable;
|
---|
10 | import org.apollo.widgets.LinkedTrack;
|
---|
11 | import org.apollo.widgets.SampledTrack;
|
---|
12 | import org.expeditee.core.Clip;
|
---|
13 | import org.expeditee.core.Colour;
|
---|
14 | import org.expeditee.core.Dimension;
|
---|
15 | import org.expeditee.core.Fill;
|
---|
16 | import org.expeditee.core.Point;
|
---|
17 | import org.expeditee.core.Stroke;
|
---|
18 | import org.expeditee.core.TextLayout;
|
---|
19 | import org.expeditee.core.bounds.AxisAlignedBoxBounds;
|
---|
20 | import org.expeditee.gio.EcosystemManager;
|
---|
21 | import org.expeditee.gio.GraphicsManager;
|
---|
22 | import org.expeditee.gio.gesture.StandardGestureActions;
|
---|
23 | import org.expeditee.gio.input.KBMInputEvent.Key;
|
---|
24 | import org.expeditee.gio.input.StandardInputEventListeners;
|
---|
25 | import org.expeditee.gui.Browser;
|
---|
26 | import org.expeditee.gui.FrameGraphics;
|
---|
27 | import org.expeditee.gui.FreeItems;
|
---|
28 | import org.expeditee.gui.FrameGraphics.FrameRenderPass;
|
---|
29 | import org.expeditee.items.Item;
|
---|
30 | import org.expeditee.items.widgets.Widget;
|
---|
31 | import org.expeditee.items.widgets.WidgetCorner;
|
---|
32 | import org.expeditee.items.widgets.WidgetEdge;
|
---|
33 |
|
---|
34 | /**
|
---|
35 | * All final effects rendered here - to give extra feedback to the user and simply to make
|
---|
36 | * it more appealing.
|
---|
37 | * @author Brook Novak
|
---|
38 | *
|
---|
39 | */
|
---|
40 | public class FrameRenderPasses implements FrameRenderPass {
|
---|
41 |
|
---|
42 | private static final Colour SHADED_EXPANDED_BACKING_COLOR = Colour.FromRGBA255(80, 80, 80, 140);
|
---|
43 | private static final Colour Y_HELPER_LINES_COLOR = Colour.DARK_GREY;
|
---|
44 | private static final Stroke Y_HELPER_LINES_STROKE = OverdubbedFrameTimeAxis.TRACK_TIMELINE_STROKE;
|
---|
45 |
|
---|
46 | private static FrameRenderPasses instance = new FrameRenderPasses();
|
---|
47 |
|
---|
48 | private LinkedList<Integer> timeHelperLinesToPaint = null;
|
---|
49 | private Mutable.Integer yAxisTimelineHelperToPaint = null;
|
---|
50 |
|
---|
51 | private boolean shouldDrawFullscreenHelpers = false;
|
---|
52 |
|
---|
53 | private FrameRenderPasses()
|
---|
54 | {
|
---|
55 | FrameGraphics.addFrameRenderPass(this);
|
---|
56 | }
|
---|
57 |
|
---|
58 | public static FrameRenderPasses getInstance()
|
---|
59 | {
|
---|
60 | return instance;
|
---|
61 | }
|
---|
62 |
|
---|
63 | public void paintFinalPass()
|
---|
64 | {
|
---|
65 | if (Browser._theBrowser == null) return;
|
---|
66 |
|
---|
67 | GraphicsManager gm = EcosystemManager.getGraphicsManager();
|
---|
68 |
|
---|
69 | int frameHeight = EcosystemManager.getGraphicsManager().getWindowSize().getHeight();
|
---|
70 | if (ExpandedTrackManager.getInstance().isAnyExpandedTrackVisible()
|
---|
71 | && !FreeItems.getInstance().isEmpty()) {
|
---|
72 |
|
---|
73 | // Conceivable could have multiple
|
---|
74 | LinkedList<SampledTrack> toPaint = null;
|
---|
75 |
|
---|
76 | for (Item i : FreeItems.getInstance()) {
|
---|
77 | if (i instanceof WidgetCorner) {
|
---|
78 | Widget iw = ((WidgetCorner)i).getWidgetSource();
|
---|
79 |
|
---|
80 | if (iw != null && iw instanceof SampledTrack) {
|
---|
81 |
|
---|
82 | if (toPaint == null) {
|
---|
83 | toPaint = new LinkedList<SampledTrack>();
|
---|
84 | } else if (toPaint.contains(iw)) {
|
---|
85 | continue;
|
---|
86 | }
|
---|
87 |
|
---|
88 | toPaint.add((SampledTrack)iw);
|
---|
89 | }
|
---|
90 | }
|
---|
91 | }
|
---|
92 |
|
---|
93 | if (toPaint != null) {
|
---|
94 | for (SampledTrack trackWidget : toPaint) {
|
---|
95 | if (gm.peekClip() == null || gm.peekClip().isNotClipped() || (!gm.peekClip().isFullyClipped() && gm.peekClip().getBounds().intersects(trackWidget.getBounds()))) {
|
---|
96 | trackWidget.paintInFreeSpace(true);
|
---|
97 | }
|
---|
98 | }
|
---|
99 | }
|
---|
100 |
|
---|
101 | }
|
---|
102 |
|
---|
103 | OverdubbedFrameTimeAxis.getInstance().paint();
|
---|
104 |
|
---|
105 | TimeAxis timeAxis = OverdubbedFrameTimeAxis.getInstance().getTimeAxis();
|
---|
106 | Timeline lastTimeline = OverdubbedFrameTimeAxis.getInstance().getLastTimeline();
|
---|
107 |
|
---|
108 | FramePlaybackBarRenderer.getInstance().paint();
|
---|
109 |
|
---|
110 | if (timeHelperLinesToPaint != null && timeAxis != null && lastTimeline != null) {
|
---|
111 |
|
---|
112 | AxisAlignedBoxBounds r = OverdubbedFrameTimeAxis.getInstance().getCurrentTimelineArea();
|
---|
113 |
|
---|
114 | // Draw helper bar and text
|
---|
115 | for (Integer x : timeHelperLinesToPaint) {
|
---|
116 |
|
---|
117 | if (shouldDrawFullscreenHelpers) {
|
---|
118 | gm.drawLine(new Point(x, 0), new Point(x, frameHeight), Colour.RED, OverdubbedFrameTimeAxis.TRACK_TIMELINE_STROKE);
|
---|
119 | } else {
|
---|
120 | gm.drawLine(new Point(x, r.getMinY()), new Point(x, r.getMinY() + r.getHeight()), Colour.RED, OverdubbedFrameTimeAxis.TRACK_TIMELINE_STROKE);
|
---|
121 | }
|
---|
122 |
|
---|
123 | long ms = lastTimeline.getMSTimeAtX(x) - lastTimeline.getFirstInitiationTime();
|
---|
124 |
|
---|
125 | String label = timeAxis.createSpecificTimeLabel(Math.abs(ms), 500.0);
|
---|
126 | if (ms < 0) label = "-" + label;
|
---|
127 |
|
---|
128 | //FontMetrics fm = g.getFontMetrics(SampledTrackGraphViewPort.TIME_HELPER_FONT);
|
---|
129 | //Rectangle2D rect = fm.getStringBounds(label, g);
|
---|
130 | TextLayout layout = EcosystemManager.getTextLayoutManager().layoutStringSimple(label, SampledTrackGraphViewPort.TIME_HELPER_FONT);
|
---|
131 | AxisAlignedBoxBounds rect = layout.getPixelBounds(0, 0);
|
---|
132 | int labelWidth = (int)(rect.getWidth());
|
---|
133 | int labelHeight = (int)(rect.getHeight());
|
---|
134 |
|
---|
135 | int y = r.getMinY() + (r.getHeight() / 2) - ((labelHeight + 4) / 2);
|
---|
136 |
|
---|
137 | gm.drawRectangle(new Point(x + 2, y), new Dimension(labelWidth + 3, labelHeight + 4), 0.0, new Fill(SampledTrackGraphViewPort.TIME_HELPER_COLOR), SampledTrackGraphViewPort.TIME_HELPER_BORDERCOLOR, SampledTrackGraphViewPort.ZOOM_BACKING_BORDER_STROKE, null);
|
---|
138 |
|
---|
139 | gm.drawTextLayout(layout, new Point(x + 4, y + labelHeight), Colour.BLACK);
|
---|
140 | }
|
---|
141 |
|
---|
142 | }
|
---|
143 |
|
---|
144 | // Draw Y helper
|
---|
145 | if (yAxisTimelineHelperToPaint != null) {
|
---|
146 | gm.drawLine(0, yAxisTimelineHelperToPaint.value, EcosystemManager.getGraphicsManager().getWindowSize().getWidth(), yAxisTimelineHelperToPaint.value, Y_HELPER_LINES_COLOR, Y_HELPER_LINES_STROKE);
|
---|
147 | }
|
---|
148 |
|
---|
149 |
|
---|
150 | }
|
---|
151 |
|
---|
152 | public void paintPreLayeredPanePass()
|
---|
153 | {
|
---|
154 | if (Browser._theBrowser == null) return;
|
---|
155 |
|
---|
156 | if (ExpandedTrackManager.getInstance().isAnyExpandedTrackVisible()) {
|
---|
157 | Dimension windowSize = EcosystemManager.getGraphicsManager().getWindowSize();
|
---|
158 | EcosystemManager.getGraphicsManager().drawRectangle(Point.ORIGIN, windowSize, 0.0, new Fill(SHADED_EXPANDED_BACKING_COLOR), null, null, null);
|
---|
159 | }
|
---|
160 |
|
---|
161 | }
|
---|
162 |
|
---|
163 | public Clip paintStarted(Clip currentClip)
|
---|
164 | {
|
---|
165 | if (Browser._theBrowser == null) return currentClip;
|
---|
166 |
|
---|
167 | LinkedList<Widget> seen = null;
|
---|
168 |
|
---|
169 | //boolean idDirty = false;
|
---|
170 | //if (helperLinesToPaint != null) {
|
---|
171 | // idDirty = true;
|
---|
172 |
|
---|
173 | //}
|
---|
174 |
|
---|
175 | invalidateHelperLines(currentClip);
|
---|
176 |
|
---|
177 | timeHelperLinesToPaint = null;
|
---|
178 | yAxisTimelineHelperToPaint = null;
|
---|
179 | shouldDrawFullscreenHelpers = StandardInputEventListeners.kbmStateListener.isKeyDown(Key.CTRL) ||
|
---|
180 | (StandardInputEventListeners.kbmStateListener.isKeyDown(Key.SHIFT) && !FreeItems.getInstance().isEmpty());
|
---|
181 |
|
---|
182 | // Get free tracks and paint line helpers
|
---|
183 | if (!FreeItems.getInstance().isEmpty() || StandardGestureActions.getlastHighlightedItem() != null) {
|
---|
184 |
|
---|
185 | LinkedList<Item> possibles = new LinkedList<Item>(FreeItems.getInstance());
|
---|
186 | if (FreeItems.getInstance().isEmpty() && StandardGestureActions.getlastHighlightedItem() != null) {
|
---|
187 | possibles.add(StandardGestureActions.getlastHighlightedItem());
|
---|
188 | }
|
---|
189 |
|
---|
190 | for (Item i : possibles) {
|
---|
191 |
|
---|
192 | Widget iw = null;
|
---|
193 |
|
---|
194 | if (i instanceof WidgetCorner) {
|
---|
195 | iw = ((WidgetCorner)i).getWidgetSource();
|
---|
196 | } else if (i instanceof WidgetEdge) {
|
---|
197 | iw = ((WidgetEdge)i).getWidgetSource();
|
---|
198 | }
|
---|
199 |
|
---|
200 | if (iw != null) {
|
---|
201 |
|
---|
202 | if (iw != null && (iw instanceof SampledTrack ||
|
---|
203 | iw instanceof LinkedTrack)) {
|
---|
204 |
|
---|
205 | if (seen == null) {
|
---|
206 | seen = new LinkedList<Widget>();
|
---|
207 | } else if (seen.contains(iw)) {
|
---|
208 | continue;
|
---|
209 | }
|
---|
210 |
|
---|
211 | if (timeHelperLinesToPaint == null)
|
---|
212 | timeHelperLinesToPaint = new LinkedList<Integer>();
|
---|
213 |
|
---|
214 | timeHelperLinesToPaint.add(iw.getX());
|
---|
215 | }
|
---|
216 | } else if (i instanceof FramePlaybackLauncher || i instanceof RecordOverdubLauncher) {
|
---|
217 | if (timeHelperLinesToPaint == null)
|
---|
218 | timeHelperLinesToPaint = new LinkedList<Integer>();
|
---|
219 | timeHelperLinesToPaint.add(i.getX());
|
---|
220 | }
|
---|
221 | }
|
---|
222 |
|
---|
223 | }
|
---|
224 |
|
---|
225 | if ((ApolloGestureActions.isYAxisRestictionOn() || ApolloGestureActions.isSnapOn())
|
---|
226 | && !FreeItems.getInstance().isEmpty()) {
|
---|
227 |
|
---|
228 | int smallestY = FreeItems.getInstance().get(0).getY();
|
---|
229 | for (Item i : FreeItems.getInstance()) {
|
---|
230 | if (i.getY() < smallestY) smallestY = i.getY();
|
---|
231 | }
|
---|
232 |
|
---|
233 | if (smallestY > 0) {
|
---|
234 | yAxisTimelineHelperToPaint = Mutable.createMutableInteger(smallestY);
|
---|
235 | }
|
---|
236 | }
|
---|
237 |
|
---|
238 | // Invalidate on the fly
|
---|
239 | invalidateHelperLines(currentClip);
|
---|
240 |
|
---|
241 | return currentClip;
|
---|
242 |
|
---|
243 | }
|
---|
244 |
|
---|
245 | private void invalidateHelperLines(Clip currentClip)
|
---|
246 | {
|
---|
247 | if (currentClip == null) return;
|
---|
248 |
|
---|
249 | if (timeHelperLinesToPaint != null && !timeHelperLinesToPaint.isEmpty()) {
|
---|
250 | currentClip.includeBounds(OverdubbedFrameTimeAxis.getInstance().getCurrentTimelineArea().clone());
|
---|
251 | if (shouldDrawFullscreenHelpers) {
|
---|
252 | int fsHeight = EcosystemManager.getGraphicsManager().getWindowSize().getHeight();
|
---|
253 | for (Integer n : timeHelperLinesToPaint) {
|
---|
254 | currentClip.includeBounds(new AxisAlignedBoxBounds(n - 1, 0, 3, fsHeight));
|
---|
255 | }
|
---|
256 | }
|
---|
257 | }
|
---|
258 |
|
---|
259 | if (yAxisTimelineHelperToPaint != null && shouldDrawFullscreenHelpers) {
|
---|
260 |
|
---|
261 | currentClip.includeBounds(new AxisAlignedBoxBounds(
|
---|
262 | 0,
|
---|
263 | yAxisTimelineHelperToPaint.value - 1,
|
---|
264 | EcosystemManager.getGraphicsManager().getWindowSize().getWidth(),
|
---|
265 | 3));
|
---|
266 |
|
---|
267 | }
|
---|
268 | }
|
---|
269 | }
|
---|