source: trunk/src/org/apollo/AudioFrameKeyboardActions.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: 11.3 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.Text;
28import org.expeditee.items.Item.HighlightMode;
29import org.expeditee.items.widgets.InteractiveWidget;
30import org.expeditee.items.widgets.WidgetCorner;
31import org.expeditee.items.widgets.WidgetEdge;
32
33/**
34 * Apollos keyboards actions extensions.
35 *
36 * @author Brook Novak
37 *
38 */
39public 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}
Note: See TracBrowser for help on using the repository browser.