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