1 | package org.apollo;
|
---|
2 |
|
---|
3 | import java.awt.Point;
|
---|
4 | import java.awt.event.KeyEvent;
|
---|
5 | import java.awt.event.KeyListener;
|
---|
6 | import java.util.Collection;
|
---|
7 | import java.util.LinkedHashSet;
|
---|
8 | import java.util.LinkedList;
|
---|
9 |
|
---|
10 | import org.apollo.util.Mutable;
|
---|
11 | import org.apollo.widgets.LinkedTrack;
|
---|
12 | import org.apollo.widgets.SampledTrack;
|
---|
13 | import org.apollo.widgets.TrackWidgetCommons;
|
---|
14 | import org.expeditee.gui.Browser;
|
---|
15 | import org.expeditee.gui.DisplayIO;
|
---|
16 | import org.expeditee.gui.Frame;
|
---|
17 | import org.expeditee.gui.FrameGraphics;
|
---|
18 | import org.expeditee.gui.FrameIO;
|
---|
19 | import org.expeditee.gui.FrameKeyboardActions;
|
---|
20 | import org.expeditee.gui.FrameMouseActions;
|
---|
21 | import org.expeditee.gui.FrameUtils;
|
---|
22 | import org.expeditee.gui.FreeItems;
|
---|
23 | import org.expeditee.items.UserAppliedPermission;
|
---|
24 | import org.expeditee.items.Dot;
|
---|
25 | import org.expeditee.items.Item;
|
---|
26 | import org.expeditee.items.Line;
|
---|
27 | import org.expeditee.items.Text;
|
---|
28 | import org.expeditee.items.Item.HighlightMode;
|
---|
29 | import org.expeditee.items.widgets.InteractiveWidget;
|
---|
30 | import org.expeditee.items.widgets.WidgetCorner;
|
---|
31 | import org.expeditee.items.widgets.WidgetEdge;
|
---|
32 |
|
---|
33 | /**
|
---|
34 | * Apollos keyboards actions extensions.
|
---|
35 | *
|
---|
36 | * @author Brook Novak
|
---|
37 | *
|
---|
38 | */
|
---|
39 | public class AudioFrameKeyboardActions implements KeyListener {
|
---|
40 |
|
---|
41 | static boolean isControlDown = false;
|
---|
42 | static boolean isShiftDown = false;
|
---|
43 |
|
---|
44 | private static final long TRACK_WIDGET_TIMELINE_ADJUSTMENT = 50; // In audio-frames
|
---|
45 | private static final int TRACK_WIDGET_VERTICLE_ADJUSTMENT = 5; // In Pixels
|
---|
46 |
|
---|
47 | public void keyPressed(KeyEvent e) {
|
---|
48 |
|
---|
49 | isControlDown = e.isControlDown();
|
---|
50 | isShiftDown = e.isShiftDown();
|
---|
51 |
|
---|
52 | boolean forwardToExpeditee = true;
|
---|
53 |
|
---|
54 | switch(e.getKeyCode()) {
|
---|
55 |
|
---|
56 | case KeyEvent.VK_CONTROL:
|
---|
57 | FrameGraphics.refresh(false); // For special post effects
|
---|
58 | break;
|
---|
59 |
|
---|
60 | // Ultra-fine timeline placement of audio tracks
|
---|
61 | case KeyEvent.VK_RIGHT:
|
---|
62 | case KeyEvent.VK_LEFT:
|
---|
63 |
|
---|
64 | if (isControlDown) {
|
---|
65 | InteractiveWidget selectedIW = null;
|
---|
66 |
|
---|
67 | if (FrameMouseActions.getlastHighlightedItem() != null &&
|
---|
68 | FrameMouseActions.getlastHighlightedItem() instanceof WidgetEdge) {
|
---|
69 | selectedIW = ((WidgetEdge)FrameMouseActions.getlastHighlightedItem()).getWidgetSource();
|
---|
70 | } else if (FrameMouseActions.getlastHighlightedItem() != null &&
|
---|
71 | FrameMouseActions.getlastHighlightedItem() instanceof WidgetCorner) {
|
---|
72 | selectedIW = ((WidgetCorner)FrameMouseActions.getlastHighlightedItem()).getWidgetSource();
|
---|
73 | }
|
---|
74 |
|
---|
75 | if (selectedIW != null && selectedIW instanceof SampledTrack) {
|
---|
76 | adjustInitationTime((SampledTrack)selectedIW, e.getKeyCode() == KeyEvent.VK_LEFT);
|
---|
77 | forwardToExpeditee = false;
|
---|
78 | } else if (selectedIW != null && selectedIW instanceof LinkedTrack) {
|
---|
79 | adjustInitationTime((LinkedTrack)selectedIW, e.getKeyCode() == KeyEvent.VK_LEFT);
|
---|
80 | forwardToExpeditee = false;
|
---|
81 | }
|
---|
82 |
|
---|
83 | }
|
---|
84 |
|
---|
85 | break;
|
---|
86 |
|
---|
87 | case KeyEvent.VK_UP:
|
---|
88 | case KeyEvent.VK_DOWN:
|
---|
89 |
|
---|
90 | if (isControlDown) {
|
---|
91 | InteractiveWidget selectedIW = null;
|
---|
92 |
|
---|
93 | if (FrameMouseActions.getlastHighlightedItem() != null &&
|
---|
94 | FrameMouseActions.getlastHighlightedItem() instanceof WidgetEdge) {
|
---|
95 | selectedIW = ((WidgetEdge)FrameMouseActions.getlastHighlightedItem()).getWidgetSource();
|
---|
96 | } else if (FrameMouseActions.getlastHighlightedItem() != null &&
|
---|
97 | FrameMouseActions.getlastHighlightedItem() instanceof WidgetCorner) {
|
---|
98 | selectedIW = ((WidgetCorner)FrameMouseActions.getlastHighlightedItem()).getWidgetSource();
|
---|
99 | }
|
---|
100 |
|
---|
101 | if (selectedIW != null && selectedIW instanceof SampledTrack) {
|
---|
102 | adjustVerticlePosition((SampledTrack)selectedIW, e.getKeyCode() == KeyEvent.VK_UP);
|
---|
103 | forwardToExpeditee = false;
|
---|
104 | } else if (selectedIW != null && selectedIW instanceof LinkedTrack) {
|
---|
105 | adjustVerticlePosition((LinkedTrack)selectedIW, e.getKeyCode() == KeyEvent.VK_UP);
|
---|
106 | forwardToExpeditee = false;
|
---|
107 | }
|
---|
108 |
|
---|
109 | }
|
---|
110 |
|
---|
111 | break;
|
---|
112 |
|
---|
113 | case KeyEvent.VK_F:
|
---|
114 | if (e.isControlDown() && e.isShiftDown()) {
|
---|
115 | Frame current = DisplayIO.getCurrentFrame();
|
---|
116 | int maxX = Browser._theBrowser.getContentPane().getWidth();
|
---|
117 | int maxY = Browser._theBrowser.getContentPane().getHeight();
|
---|
118 |
|
---|
119 | for (Item i : current.getItems()) {
|
---|
120 | Point pos = i.getPosition();
|
---|
121 | pos.x %= maxX;
|
---|
122 | pos.y %= maxY;
|
---|
123 | i.setPosition(pos);
|
---|
124 | }
|
---|
125 | }
|
---|
126 | break;
|
---|
127 |
|
---|
128 | // Create linked tracks on enclosed items
|
---|
129 | case KeyEvent.VK_L:
|
---|
130 |
|
---|
131 | if (e.isControlDown() && FrameUtils.getCurrentItem() == null) {
|
---|
132 |
|
---|
133 | Collection<Item> enclosedItems = FrameUtils.getCurrentItems(null);
|
---|
134 | if (enclosedItems != null) {
|
---|
135 |
|
---|
136 | forwardToExpeditee = false;
|
---|
137 | Frame current = DisplayIO.getCurrentFrame();
|
---|
138 |
|
---|
139 | Collection<Item> toRemove = new LinkedHashSet<Item>(enclosedItems.size());
|
---|
140 | LinkedList<LinkedTrack> enclosedLinkedTracks = new LinkedList<LinkedTrack>();
|
---|
141 | LinkedList<SampledTrack> enclosedTracks = new LinkedList<SampledTrack>();
|
---|
142 |
|
---|
143 | // Get enclosing shape and enclosed tracks
|
---|
144 | for (Item ip : enclosedItems) {
|
---|
145 | if (ip.getParent() != current) continue;
|
---|
146 |
|
---|
147 | if (ip.hasPermission(UserAppliedPermission.full)) {
|
---|
148 | // Only include lines if one of their enpoints are also being removed
|
---|
149 | if (ip instanceof Line) {
|
---|
150 | Line l = (Line) ip;
|
---|
151 | Item end = l.getEndItem();
|
---|
152 | Item start = l.getStartItem();
|
---|
153 |
|
---|
154 | // If one end of a line is being delted, remove the
|
---|
155 | // other end if all its connecting lines are being
|
---|
156 | // delted
|
---|
157 | if (enclosedItems.contains(end)) {
|
---|
158 | if (!enclosedItems.contains(start)
|
---|
159 | && enclosedItems.containsAll(start.getLines())) {
|
---|
160 | toRemove.add(start);
|
---|
161 | }
|
---|
162 | } else if (enclosedItems.contains(start)) {
|
---|
163 | if (enclosedItems.containsAll(end.getLines())) {
|
---|
164 | toRemove.add(end);
|
---|
165 | }
|
---|
166 | } else {
|
---|
167 | continue;
|
---|
168 | }
|
---|
169 | } else if (ip instanceof WidgetCorner){
|
---|
170 | InteractiveWidget iw = ((WidgetCorner)ip).getWidgetSource();
|
---|
171 | if (!enclosedTracks.contains(iw) && iw instanceof SampledTrack) {
|
---|
172 | enclosedTracks.add((SampledTrack)iw);
|
---|
173 | } else if (!enclosedLinkedTracks.contains(iw) && iw instanceof LinkedTrack) {
|
---|
174 | enclosedLinkedTracks.add((LinkedTrack)iw);
|
---|
175 | }
|
---|
176 | } else {
|
---|
177 | if ((ip instanceof Line || ip instanceof Dot) && ip.getHighlightMode() == HighlightMode.Enclosed) {
|
---|
178 | toRemove.add(ip);
|
---|
179 | toRemove.addAll(ip.getConnected());
|
---|
180 | }
|
---|
181 | }
|
---|
182 |
|
---|
183 | }
|
---|
184 | } // End searching enclosed items
|
---|
185 |
|
---|
186 |
|
---|
187 | // If there was some enclosed tracks
|
---|
188 | if (current != null && !toRemove.isEmpty() && (!enclosedLinkedTracks.isEmpty() || !enclosedTracks.isEmpty())) {
|
---|
189 |
|
---|
190 | // Remove enclosure
|
---|
191 | current.removeAllItems(toRemove);
|
---|
192 |
|
---|
193 | // Determine initiation time of group
|
---|
194 | Mutable.Long initTime = null;
|
---|
195 | Point initiatePosition = null;
|
---|
196 |
|
---|
197 | for (SampledTrack st : enclosedTracks) {
|
---|
198 |
|
---|
199 | if (initTime == null) {
|
---|
200 | initTime = st.getInitiationTimeFromMeta();
|
---|
201 | initiatePosition = st.getPosition();
|
---|
202 | }
|
---|
203 | else if (st.getInitiationTimeFromMeta() != null &&
|
---|
204 | st.getInitiationTimeFromMeta().value < initTime.value) {
|
---|
205 | initTime = st.getInitiationTimeFromMeta();
|
---|
206 | initiatePosition = st.getPosition();
|
---|
207 | }
|
---|
208 | }
|
---|
209 | for (LinkedTrack lt : enclosedLinkedTracks) {
|
---|
210 |
|
---|
211 | if (initTime == null) {
|
---|
212 | initTime = lt.getInitiationTimeFromMeta();
|
---|
213 | initiatePosition = lt.getPosition();
|
---|
214 | }
|
---|
215 | else if (lt.getInitiationTimeFromMeta() != null &&
|
---|
216 | lt.getInitiationTimeFromMeta().value < initTime.value) {
|
---|
217 | initTime = lt.getInitiationTimeFromMeta();
|
---|
218 | initiatePosition = lt.getPosition();
|
---|
219 | }
|
---|
220 | }
|
---|
221 |
|
---|
222 | assert(initTime != null);
|
---|
223 | assert(initiatePosition != null);
|
---|
224 |
|
---|
225 | // Creat the link to contain all tracks
|
---|
226 | String name = current.getTitle();
|
---|
227 | if (name == null) name = "Unnamed";
|
---|
228 | name += " group";
|
---|
229 |
|
---|
230 | Text linkSource = new Text(current.getNextItemID());
|
---|
231 | linkSource.addToData(TrackWidgetCommons.META_NAME_TAG + name);
|
---|
232 | linkSource.addToData(TrackWidgetCommons.META_INITIATIONTIME_TAG + initTime);
|
---|
233 | linkSource.setPosition(initiatePosition);
|
---|
234 | linkSource.setParent(current);
|
---|
235 | LinkedTrack linkedVersion = new LinkedTrack(linkSource, null);
|
---|
236 |
|
---|
237 | // Create a new frame to hold the track group
|
---|
238 | Frame newFrame = FrameIO.CreateNewFrame(linkedVersion.getItems().get(0));
|
---|
239 |
|
---|
240 | for (SampledTrack st : enclosedTracks) {
|
---|
241 | st.saveAudio(); // Blocking
|
---|
242 | current.removeAllItems(st.getItems());
|
---|
243 | newFrame.addAllItems(st.getItems());
|
---|
244 | }
|
---|
245 |
|
---|
246 | for (LinkedTrack lt : enclosedLinkedTracks) {
|
---|
247 | current.removeAllItems(lt.getItems());
|
---|
248 | newFrame.addAllItems(lt.getItems());
|
---|
249 | }
|
---|
250 |
|
---|
251 | FrameIO.SaveFrame(newFrame);
|
---|
252 |
|
---|
253 | // Link the linked tracks
|
---|
254 | linkedVersion.setLink(newFrame.getName(), null);
|
---|
255 |
|
---|
256 | // Add the new link
|
---|
257 | current.addAllItems(linkedVersion.getItems());
|
---|
258 |
|
---|
259 | // Ensure initiation time is retained to the exact frame... avoiding loss due to resolution
|
---|
260 | linkedVersion.setInitiationTime(initTime.value);
|
---|
261 |
|
---|
262 | }
|
---|
263 |
|
---|
264 | }
|
---|
265 |
|
---|
266 | }
|
---|
267 | break;
|
---|
268 | }
|
---|
269 |
|
---|
270 | if (forwardToExpeditee) {
|
---|
271 | FrameKeyboardActions.getInstance().keyPressed(e);
|
---|
272 | }
|
---|
273 |
|
---|
274 | }
|
---|
275 |
|
---|
276 | public void keyReleased(KeyEvent e) {
|
---|
277 |
|
---|
278 | boolean wasYRestricted = AudioFrameMouseActions.isYAxisRestictionOn();
|
---|
279 |
|
---|
280 | isControlDown = e.isControlDown();
|
---|
281 | isShiftDown = e.isShiftDown();
|
---|
282 |
|
---|
283 | switch(e.getKeyCode()) {
|
---|
284 | case KeyEvent.VK_CONTROL:
|
---|
285 | FrameGraphics.refresh(false); // For special post effects
|
---|
286 | break;
|
---|
287 | case KeyEvent.VK_G:
|
---|
288 | if (isControlDown) {
|
---|
289 | ApolloSystem.useQualityGraphics = !ApolloSystem.useQualityGraphics;
|
---|
290 | }
|
---|
291 | break;
|
---|
292 |
|
---|
293 | }
|
---|
294 |
|
---|
295 | // Restore free items position with respected to cursur
|
---|
296 | if (wasYRestricted && !FreeItems.getInstance().isEmpty()) {
|
---|
297 | // TODO
|
---|
298 | }
|
---|
299 |
|
---|
300 | FrameKeyboardActions.getInstance().keyReleased(e);
|
---|
301 | }
|
---|
302 |
|
---|
303 | public void keyTyped(KeyEvent e) {
|
---|
304 | FrameKeyboardActions.getInstance().keyTyped(e);
|
---|
305 | }
|
---|
306 |
|
---|
307 |
|
---|
308 | /**
|
---|
309 | * @return True if control is down.
|
---|
310 | */
|
---|
311 | public static boolean isControlDown() {
|
---|
312 | return isControlDown;
|
---|
313 | }
|
---|
314 |
|
---|
315 |
|
---|
316 | /**
|
---|
317 | * @return True if shift is down.
|
---|
318 | */
|
---|
319 | public static boolean isShiftDown() {
|
---|
320 | return isShiftDown;
|
---|
321 | }
|
---|
322 |
|
---|
323 | public static void adjustInitationTime(SampledTrack track, boolean left) {
|
---|
324 | long frameAjdustment = TRACK_WIDGET_TIMELINE_ADJUSTMENT;
|
---|
325 | if (left) frameAjdustment *= -1;
|
---|
326 | Mutable.Long oldIt = track.getInitiationTimeFromMeta();
|
---|
327 | if (oldIt == null) oldIt = Mutable.createMutableLong(0);
|
---|
328 | track.setInitiationTime(oldIt.value + frameAjdustment);
|
---|
329 | }
|
---|
330 |
|
---|
331 | public static void adjustInitationTime(LinkedTrack track, boolean left) {
|
---|
332 | long frameAjdustment = TRACK_WIDGET_TIMELINE_ADJUSTMENT;
|
---|
333 | if (left) frameAjdustment *= -1;
|
---|
334 | Mutable.Long oldIt = track.getInitiationTimeFromMeta();
|
---|
335 | if (oldIt == null) oldIt = Mutable.createMutableLong(0);
|
---|
336 | track.setInitiationTime(oldIt.value + frameAjdustment);
|
---|
337 | }
|
---|
338 |
|
---|
339 | public static void adjustVerticlePosition(SampledTrack track, boolean up) {
|
---|
340 | int pixelAjdustment = TRACK_WIDGET_VERTICLE_ADJUSTMENT;
|
---|
341 | if (up) pixelAjdustment *= -1;
|
---|
342 | track.setYPosition(track.getY() + pixelAjdustment);
|
---|
343 | }
|
---|
344 |
|
---|
345 | public static void adjustVerticlePosition(LinkedTrack track, boolean up) {
|
---|
346 | int pixelAjdustment = TRACK_WIDGET_VERTICLE_ADJUSTMENT;
|
---|
347 | if (up) pixelAjdustment *= -1;
|
---|
348 | track.setYPosition(track.getY() + pixelAjdustment);
|
---|
349 | }
|
---|
350 |
|
---|
351 | }
|
---|