source: trunk/src/org/apollo/ApolloGestureActions.java@ 1523

Last change on this file since 1523 was 1523, checked in by bnemhaus, 4 years ago

Reimplementing snapping of SampledTracks and LinkedTracks so that it does not interfere with StandardGestureActions.

File size: 22.5 KB
Line 
1package org.apollo;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.HashMap;
6import java.util.LinkedHashSet;
7import java.util.LinkedList;
8import java.util.List;
9import java.util.Map;
10
11import org.apollo.gio.gesture.data.TrackAdjustmentGestureData;
12import org.apollo.util.Mutable;
13import org.apollo.widgets.LinkedTrack;
14import org.apollo.widgets.SampledTrack;
15import org.apollo.widgets.TrackWidgetCommons;
16import org.expeditee.core.Dimension;
17import org.expeditee.core.Point;
18import org.expeditee.core.bounds.AxisAlignedBoxBounds;
19import org.expeditee.gio.EcosystemManager;
20import org.expeditee.gio.gesture.Gesture;
21import org.expeditee.gio.gesture.Gesture.GestureType;
22import org.expeditee.gio.gesture.GestureAction;
23import org.expeditee.gio.gesture.GestureListener;
24import org.expeditee.gio.gesture.StandardGestureActions;
25import org.expeditee.gio.gesture.StandardGestureActions.StandardGestureType;
26import org.expeditee.gio.gesture.data.ItemSpecificGestureData;
27import org.expeditee.gio.gesture.data.PickUpGestureData;
28import org.expeditee.gio.input.KBMInputEvent.Key;
29import org.expeditee.gio.input.StandardInputEventListeners;
30import org.expeditee.gui.DisplayController;
31import org.expeditee.gui.Frame;
32import org.expeditee.gui.FrameIO;
33import org.expeditee.gui.FreeItems;
34import org.expeditee.items.Dot;
35import org.expeditee.items.Item;
36import org.expeditee.items.Item.HighlightMode;
37import org.expeditee.items.ItemUtils;
38import org.expeditee.items.Line;
39import org.expeditee.items.Text;
40import org.expeditee.items.UserAppliedPermission;
41import org.expeditee.items.widgets.InteractiveWidgetInitialisationFailedException;
42import org.expeditee.items.widgets.InteractiveWidgetNotAvailableException;
43import org.expeditee.items.widgets.Widget;
44import org.expeditee.items.widgets.WidgetCorner;
45import org.expeditee.items.widgets.WidgetEdge;
46
47public class ApolloGestureActions implements GestureListener {
48 //@formatter:off
49 public enum ApolloGestureType {
50 ADJUST_INITIATION_TIME,
51 ADJUST_VERTICAL_POSITION,
52 CREATE_LINKED_TRACKS,
53 MODULUS_POSITION, // TODO: Think of a better name. cts16
54 TOGGLE_QUALITY_GRAPHICS
55 }
56 //@formatter:on
57
58 private static ApolloGestureActions _instance = null;
59
60 public static ApolloGestureActions getInstance() {
61 if (_instance == null) {
62 _instance = new ApolloGestureActions();
63 }
64
65 return _instance;
66 }
67
68 private HashMap<ApolloGestureType, GestureType> _gestureTypes;
69
70 private HashMap<GestureType, GestureAction> _actions;
71
72 private ApolloGestureActions() {
73 _gestureTypes = new HashMap<ApolloGestureType, GestureType>();
74 initialiseGestureTypes();
75 _actions = new HashMap<GestureType, GestureAction>();
76 initialiseActions();
77 }
78
79 @Override
80 public void preGesture(final Gesture gesture) {
81 final GestureAction action = getGestureAction(gesture.getType());
82 if (action == null) {
83 return;
84 }
85 action.prepare(gesture);
86 }
87
88 @Override
89 public void onGesture(final Gesture gesture) {
90 final GestureAction action = getGestureAction(gesture.getType());
91 if (action == null) {
92 return;
93 }
94 action.exec(gesture);
95 }
96
97 @Override
98 public void postGesture(final Gesture gesture) {
99 final GestureAction action = getGestureAction(gesture.getType());
100 if (action == null) {
101 return;
102 }
103 action.finalise(gesture);
104 }
105
106 private void setGestureAction(GestureType type, GestureAction action) {
107 if (type == null) {
108 return;
109 }
110
111 _actions.put(type, action);
112 }
113
114 private GestureAction getGestureAction(GestureType type) {
115 if (type == null) {
116 return null;
117 }
118
119 return _actions.get(type);
120 }
121
122 private void initialiseActions() {
123 // Set the ADJUST_INITIATION_TIME action
124 setGestureAction(gestureType(ApolloGestureType.ADJUST_INITIATION_TIME), new GestureAction() {
125 @Override
126 public void exec(Gesture gesture) {
127 TrackAdjustmentGestureData data = (TrackAdjustmentGestureData) gesture.getData();
128
129 Widget selectedIW = null;
130
131 if (data.getCurrentItem() != null) {
132 if (data.getCurrentItem() instanceof WidgetEdge) {
133 selectedIW = ((WidgetEdge) data.getCurrentItem()).getWidgetSource();
134 } else if (data.getCurrentItem() instanceof WidgetCorner) {
135 selectedIW = ((WidgetCorner) data.getCurrentItem()).getWidgetSource();
136 }
137 }
138
139 if (selectedIW != null) {
140 adjustInitiationTime(selectedIW, data.getAdjustment());
141 }
142 }
143 });
144
145 // Set the ADJUST_VERTICAL_POSITION action
146 setGestureAction(gestureType(ApolloGestureType.ADJUST_VERTICAL_POSITION), new GestureAction() {
147 @Override
148 public void exec(Gesture gesture) {
149 TrackAdjustmentGestureData data = (TrackAdjustmentGestureData) gesture.getData();
150
151 Widget selectedIW = null;
152
153 if (data.getCurrentItem() != null) {
154 if (data.getCurrentItem() instanceof WidgetEdge) {
155 selectedIW = ((WidgetEdge) data.getCurrentItem()).getWidgetSource();
156 } else if (data.getCurrentItem() instanceof WidgetCorner) {
157 selectedIW = ((WidgetCorner) data.getCurrentItem()).getWidgetSource();
158 }
159 }
160
161 if (selectedIW != null) {
162 adjustVerticalPosition(selectedIW, data.getAdjustment());
163 }
164 }
165 });
166
167 // Set the CREATE_LINKED_TRACKS action
168 setGestureAction(gestureType(ApolloGestureType.CREATE_LINKED_TRACKS), new GestureAction() {
169 @Override
170 public void exec(Gesture gesture) {
171 ItemSpecificGestureData data = (ItemSpecificGestureData) gesture.getData();
172
173 createLinkedTracks(data.getCurrentItem(), data.getCurrentItems());
174 }
175 });
176
177 // Set the MOD_POSITION action
178 setGestureAction(gestureType(ApolloGestureType.MODULUS_POSITION), new GestureAction() {
179 @Override
180 public void exec(Gesture gesture) {
181 Frame current = DisplayController.getCurrentFrame();
182 Dimension windowSize = EcosystemManager.getGraphicsManager().getWindowSize();
183
184 for (Item i : current.getSortedItems()) {
185 Point pos = i.getPosition();
186 pos.setX(pos.getX() % windowSize.width);
187 pos.setY(pos.getY() % windowSize.height);
188 i.setPosition(pos);
189 }
190 }
191 });
192
193 // Set the TOGGLE_QUALITY_GRAPHICS action
194 setGestureAction(gestureType(ApolloGestureType.TOGGLE_QUALITY_GRAPHICS), new GestureAction() {
195 @Override
196 public void exec(Gesture gesture) {
197 ApolloSystem.useQualityGraphics = !ApolloSystem.useQualityGraphics;
198 }
199 });
200
201 // Set the MOVE_CURSOR action
202 setGestureAction(StandardGestureActions.getInstance().gestureType(StandardGestureType.MOVE_CURSOR),
203 new GestureAction() {
204 @Override
205 public void exec(Gesture gesture) {
206 //mouseMoved(gesture.getData().getPosition());
207 if (isSnapOn()) {
208 snapFreeTracks(gesture.getData().getPosition());
209 }
210 }
211 });
212
213 // Set the PLACE action
214 setGestureAction(StandardGestureActions.getInstance().gestureType(StandardGestureType.PLACE),
215 new GestureAction() {
216
217 final List<SampledTrack> sampledTracksOnFreeItems = new ArrayList<SampledTrack>();
218
219 @Override
220 public void prepare(final Gesture gesture) {
221 final FreeItems freeItems = FreeItems.getInstance();
222 List<Widget> widgets = null;
223 if (freeItems != null && !freeItems.isEmpty()) {
224 widgets = ItemUtils.extractWidgets(freeItems);
225 }
226 widgets.forEach(w -> {
227 if (w instanceof SampledTrack) {
228 final SampledTrack st = (SampledTrack) w;
229 st.setIgnoreInjection(true);
230 sampledTracksOnFreeItems.add(st);
231 }
232 });
233 }
234
235 @Override
236 public void exec(final Gesture gesture) {
237 final PickUpGestureData data = (PickUpGestureData) gesture.getData();
238 final List<Item> widgetPieces = new LinkedList<Item>();
239 if (data.getCopy()) {
240 sampledTracksOnFreeItems.forEach(st -> {
241 st.getItems().forEach(i -> {
242 StandardGestureActions.anchor(i);
243 widgetPieces.add(i);
244 });
245 });
246 //FreeItems.getInstance().clear();
247 FreeItems.getInstance().removeAll(widgetPieces);
248 anchorTracks(widgetPieces);
249 final List<Item> toPickup = new LinkedList<Item>();
250 sampledTracksOnFreeItems.forEach(st -> {
251 try {
252 final Widget copy = st.copy();
253 toPickup.addAll(copy.getItems());
254 } catch (InteractiveWidgetNotAvailableException e) {
255 e.printStackTrace();
256 } catch (InteractiveWidgetInitialisationFailedException e) {
257 e.printStackTrace();
258 }
259 });
260 StandardGestureActions.pickup(toPickup);
261 } else {
262 anchorTracks(FreeItems.getInstance());
263 }
264 }
265
266 @Override
267 public void finalise(final Gesture gesture) {
268 sampledTracksOnFreeItems.forEach(st -> st.setIgnoreInjection(false));
269 sampledTracksOnFreeItems.clear();
270 }
271 });
272 }
273
274 /** Initialises the set of gesture types. */
275 private void initialiseGestureTypes() {
276 for (ApolloGestureType type : ApolloGestureType.values()) {
277 GestureType gestureType;
278 if ((gestureType = GestureType.register(type.toString())) == null) {
279 gestureType = GestureType.get(type.toString());
280 }
281 _gestureTypes.put(type, gestureType);
282 }
283 }
284
285 /** Gets the gesture type associated with the given standard type. */
286 public GestureType gestureType(ApolloGestureType type) {
287 if (type == null) {
288 return null;
289 }
290
291 return _gestureTypes.get(type);
292 }
293
294 /*
295 * TODO: EVERYTHING BELOW HERE IS ONLY TEMPORARILY SITUATED IN THIS CLASS
296 *
297 * The following methods were mostly copy-pasted here from the old
298 * ApolloFrameKeyboardActions and ApolloFrameMouseActions classes (to enable
299 * quick change-over to the new input system). Really they should be relocated
300 * to more suitable homes based on their function.
301 */
302
303 public static void adjustInitiationTime(Widget track, long adjustment) {
304 if (track instanceof SampledTrack) {
305 adjustInitiationTime((SampledTrack) track, adjustment);
306 } else if (track instanceof LinkedTrack) {
307 adjustInitiationTime((LinkedTrack) track, adjustment);
308 }
309 }
310
311 public static void adjustInitiationTime(SampledTrack track, long adjustment) {
312 Mutable.Long oldIt = track.getInitiationTimeFromMeta();
313 if (oldIt == null) {
314 oldIt = Mutable.createMutableLong(0);
315 }
316 track.setInitiationTime(oldIt.value + adjustment);
317 }
318
319 public static void adjustInitiationTime(LinkedTrack track, long adjustment) {
320 Mutable.Long oldIt = track.getInitiationTimeFromMeta();
321 if (oldIt == null) {
322 oldIt = Mutable.createMutableLong(0);
323 }
324 track.setInitiationTime(oldIt.value + adjustment);
325 }
326
327 public static void adjustVerticalPosition(Widget track, long adjustment) {
328 if (track instanceof SampledTrack) {
329 adjustVerticalPosition((SampledTrack) track, adjustment);
330 } else if (track instanceof LinkedTrack) {
331 adjustVerticalPosition((LinkedTrack) track, adjustment);
332 }
333 }
334
335 public static void adjustVerticalPosition(SampledTrack track, long adjustment) {
336 track.setYPosition(track.getY() + (int) adjustment);
337 }
338
339 public static void adjustVerticalPosition(LinkedTrack track, long adjustment) {
340 track.setYPosition(track.getY() + (int) adjustment);
341 }
342
343 public static void createLinkedTracks(Item currentItem, Collection<Item> enclosedItems) {
344 if (currentItem == null) {
345
346 if (enclosedItems != null) {
347
348 Frame current = DisplayController.getCurrentFrame();
349
350 Collection<Item> toRemove = new LinkedHashSet<Item>(enclosedItems.size());
351 LinkedList<LinkedTrack> enclosedLinkedTracks = new LinkedList<LinkedTrack>();
352 LinkedList<SampledTrack> enclosedTracks = new LinkedList<SampledTrack>();
353
354 // Get enclosing shape and enclosed tracks
355 for (Item ip : enclosedItems) {
356 if (ip.getParent() != current) {
357 continue;
358 }
359
360 if (ip.hasPermission(UserAppliedPermission.full)) {
361 // Only include lines if one of their enpoints are also being removed
362 if (ip instanceof Line) {
363 Line l = (Line) ip;
364 Item end = l.getEndItem();
365 Item start = l.getStartItem();
366
367 // If one end of a line is being delted, remove the
368 // other end if all its connecting lines are being
369 // delted
370 if (enclosedItems.contains(end)) {
371 if (!enclosedItems.contains(start) && enclosedItems.containsAll(start.getLines())) {
372 toRemove.add(start);
373 }
374 } else if (enclosedItems.contains(start)) {
375 if (enclosedItems.containsAll(end.getLines())) {
376 toRemove.add(end);
377 }
378 } else {
379 continue;
380 }
381 } else if (ip instanceof WidgetCorner) {
382 Widget iw = ((WidgetCorner) ip).getWidgetSource();
383 if (!enclosedTracks.contains(iw) && iw instanceof SampledTrack) {
384 enclosedTracks.add((SampledTrack) iw);
385 } else if (!enclosedLinkedTracks.contains(iw) && iw instanceof LinkedTrack) {
386 enclosedLinkedTracks.add((LinkedTrack) iw);
387 }
388 } else {
389 if ((ip instanceof Line || ip instanceof Dot)
390 && ip.getHighlightMode() == HighlightMode.Enclosed) {
391 toRemove.add(ip);
392 toRemove.addAll(ip.getConnected());
393 }
394 }
395
396 }
397 } // End searching enclosed items
398
399 // If there was some enclosed tracks
400 if (current != null && !toRemove.isEmpty()
401 && (!enclosedLinkedTracks.isEmpty() || !enclosedTracks.isEmpty())) {
402
403 // Remove enclosure
404 current.removeAllItems(toRemove);
405
406 // Determine initiation time of group
407 Mutable.Long initTime = null;
408 Point initiatePosition = null;
409
410 for (SampledTrack st : enclosedTracks) {
411
412 if (initTime == null) {
413 initTime = st.getInitiationTimeFromMeta();
414 initiatePosition = st.getPosition();
415 } else if (st.getInitiationTimeFromMeta() != null
416 && st.getInitiationTimeFromMeta().value < initTime.value) {
417 initTime = st.getInitiationTimeFromMeta();
418 initiatePosition = st.getPosition();
419 }
420 }
421 for (LinkedTrack lt : enclosedLinkedTracks) {
422
423 if (initTime == null) {
424 initTime = lt.getInitiationTimeFromMeta();
425 initiatePosition = lt.getPosition();
426 } else if (lt.getInitiationTimeFromMeta() != null
427 && lt.getInitiationTimeFromMeta().value < initTime.value) {
428 initTime = lt.getInitiationTimeFromMeta();
429 initiatePosition = lt.getPosition();
430 }
431 }
432
433 assert (initTime != null);
434 assert (initiatePosition != null);
435
436 // Creat the link to contain all tracks
437 String name = current.getTitle();
438 if (name == null) {
439 name = "Unnamed";
440 }
441 name += " group";
442
443 Text linkSource = new Text(current.getNextItemID());
444 linkSource.addToData(TrackWidgetCommons.META_NAME_TAG + name);
445 linkSource.addToData(TrackWidgetCommons.META_INITIATIONTIME_TAG + initTime);
446 linkSource.setPosition(initiatePosition);
447 linkSource.setParent(current);
448 LinkedTrack linkedVersion = new LinkedTrack(linkSource, null);
449
450 // Create a new frame to hold the track group
451 Frame newFrame = FrameIO.CreateNewFrame(linkedVersion.getItems().get(0));
452
453 for (SampledTrack st : enclosedTracks) {
454 st.saveAudio(); // Blocking
455 current.removeAllItems(st.getItems());
456 newFrame.addAllItems(st.getItems());
457 }
458
459 for (LinkedTrack lt : enclosedLinkedTracks) {
460 current.removeAllItems(lt.getItems());
461 newFrame.addAllItems(lt.getItems());
462 }
463
464 FrameIO.SaveFrame(newFrame);
465
466 // Link the linked tracks
467 linkedVersion.setLink(newFrame.getName(), null);
468
469 // Add the new link
470 current.addAllItems(linkedVersion.getItems());
471
472 // Ensure initiation time is retained to the exact frame... avoiding loss due to
473 // resolution
474 linkedVersion.setInitiationTime(initTime.value);
475 }
476 }
477 }
478 }
479
480 /**
481 * The minimum distance from a track widget to auto-align free space items to.
482 */
483 private static final int COARSE_X_PLACEMENT_TOLERANCE = 80;
484
485 private static final int COARSE_Y_PLACEMENT_TOLERANCE = 20;
486
487 private void snapFreeTracks(Point position) {
488 // Get Apollo widgets that are attached to cursor
489 FreeItems freeItems = FreeItems.getInstance();
490 List<Widget> freeWidgets = ItemUtils.extractWidgets(freeItems);
491 List<Widget> freeApolloWidgets = new ArrayList<Widget>();
492 for (Widget w: freeWidgets) {
493 if (w instanceof SampledTrack || w instanceof LinkedTrack) { freeApolloWidgets.add(w); }
494 }
495 if (freeApolloWidgets.isEmpty()) { return; }
496
497 // Get Apollo widgets that are on frame
498 Frame currentFrame = DisplayController.getCurrentFrame();
499 List<Widget> interactiveWidgets = currentFrame.getInteractiveWidgets();
500 List<Widget> anchoredApolloWidgets = new ArrayList<Widget>();
501 for (Widget w: interactiveWidgets) {
502 if (w instanceof SampledTrack || w instanceof LinkedTrack) { anchoredApolloWidgets.add(w); }
503 }
504 if (anchoredApolloWidgets.isEmpty()) { return; }
505
506 // Snap the first freeApolloWidget.
507 // Snap the freeApolloWidgets, using the first as a guidepost.
508 Widget toSnap = freeApolloWidgets.remove(0);
509 Point origin = new Point(0,0);
510 Point canditateDistance = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
511 Widget anchoredWidgetToSnapTo = null;
512 AxisAlignedBoxBounds freeWidgetBounds = toSnap.getBounds();
513 for (Widget anchoredWidget: anchoredApolloWidgets) {
514 AxisAlignedBoxBounds anchoredWidgetBounds = anchoredWidget.getBounds();
515 Point distance = freeWidgetBounds.distanceFrom(anchoredWidgetBounds);
516 if (distance.getDistanceTo(origin) < canditateDistance.getDistanceTo(origin)) {
517 canditateDistance = distance;
518 anchoredWidgetToSnapTo = anchoredWidget;
519 }
520 }
521 AxisAlignedBoxBounds anchoredWidgetToSnapToBounds = anchoredWidgetToSnapTo.getBounds();
522
523 int xDist = anchoredWidgetToSnapToBounds.getCentreX() < freeWidgetBounds.getCentreX() ? canditateDistance.getX() : -canditateDistance.getX();
524 int yDist = anchoredWidgetToSnapToBounds.getCentreY() < freeWidgetBounds.getCentreY() ? canditateDistance.getY() : -canditateDistance.getY();
525
526 int direction = -1;
527 int tlX = toSnap.getX();
528 int tlY = toSnap.getY();
529 if ((xDist > 0 && yDist == 0) || (xDist == 0 && yDist == 0)) {
530 tlX = anchoredWidgetToSnapTo.getBounds().getMaxX();
531 tlY = anchoredWidgetToSnapTo.getBounds().getMinY();
532 direction = 0;
533 } else if (xDist < 0 && yDist == 0) {
534 tlX = anchoredWidgetToSnapTo.getBounds().getMinX() - toSnap.getWidth();
535 tlY = anchoredWidgetToSnapTo.getBounds().getMinY();
536 direction = 1;
537 } else if (yDist > 0 && xDist == 0) {
538 tlX = anchoredWidgetToSnapTo.getBounds().getMinX();
539 tlY = anchoredWidgetToSnapTo.getBounds().getMaxY();
540 direction = 2;
541 } else if (yDist < 0 && xDist == 0) {
542 tlX = anchoredWidgetToSnapTo.getBounds().getMinX();
543 tlY = anchoredWidgetToSnapTo.getBounds().getMinY() - toSnap.getHeight();
544 direction = 3;
545 }
546 toSnap.setPosition(tlX, tlY);
547
548 for (Widget toSnapNext: freeApolloWidgets) {
549 switch (direction) {
550 case 0:
551 tlX = toSnap.getBounds().getMaxX();
552 tlY = toSnap.getBounds().getMinY();
553 toSnapNext.setPosition(tlX, tlY);
554 break;
555 case 1:
556 tlX = toSnap.getBounds().getMinX() - toSnapNext.getWidth();
557 tlY = toSnap.getBounds().getMinY();
558 toSnapNext.setPosition(tlX, tlY);
559 break;
560 case 2:
561 tlX = toSnap.getBounds().getMinX();
562 tlY = toSnap.getBounds().getMaxX();
563 toSnapNext.setPosition(tlX, tlY);
564 break;
565 case 3:
566 tlX = toSnap.getBounds().getMinX();
567 tlY = toSnap.getBounds().getMinY() - toSnapNext.getHeight();
568 toSnapNext.setPosition(tlX, tlY);
569 break;
570 default:
571 break;
572 }
573 toSnap = toSnapNext;
574 }
575 }
576
577 /**
578 * @return True if the user is restricting movement on the y-axis only
579 */
580 public static boolean isYAxisRestictionOn() {
581 return StandardInputEventListeners.kbmStateListener.isKeyDown(Key.CTRL)
582 && !StandardInputEventListeners.kbmStateListener.isKeyDown(Key.SHIFT);
583 }
584
585 public static boolean isSnapOn() {
586 return StandardInputEventListeners.kbmStateListener.isKeyDown(Key.SHIFT)
587 && !StandardInputEventListeners.kbmStateListener.isKeyDown(Key.CTRL);
588 }
589
590 private void anchorTracks(final List<Item> widgetPieces) {
591
592 // Widget -> delta IT time
593 Map<LinkedTrack, Mutable.Long> anchoredLinkedTracks = null;
594 Map<SampledTrack, Mutable.Long> anchoredTracks = null;
595
596// if (FreeItems.getInstance().size() > 1) {
597 if (widgetPieces.size() > 1) {
598// List<Widget> anchoringWidgets = ItemUtils.extractWidgets(FreeItems.getInstance());
599 List<Widget> anchoringWidgets = ItemUtils.extractWidgets(widgetPieces);
600
601 Mutable.Long firstInitTime = null;
602 anchoredLinkedTracks = new HashMap<LinkedTrack, Mutable.Long>();
603 anchoredTracks = new HashMap<SampledTrack, Mutable.Long>();
604
605 for (Widget iw : anchoringWidgets) {
606
607 Mutable.Long it = null;
608
609 if (iw instanceof LinkedTrack) {
610
611 LinkedTrack lt = (LinkedTrack) iw;
612 it = lt.getInitiationTimeFromMeta();
613 if (it == null) {
614 it = Mutable.createMutableLong(0);
615 }
616
617 anchoredLinkedTracks.put(lt, it);
618
619 } else if (iw instanceof SampledTrack) {
620
621 SampledTrack st = (SampledTrack) iw;
622 it = st.getInitiationTimeFromMeta();
623 if (it == null) {
624 it = Mutable.createMutableLong(0);
625 }
626
627 anchoredTracks.put(st, it);
628
629 } else {
630 continue;
631 }
632
633 if (firstInitTime == null) {
634 firstInitTime = Mutable.createMutableLong(it.value); // Important to create new instance
635 } else if (it.value < firstInitTime.value) {
636 firstInitTime = Mutable.createMutableLong(it.value); // Important to create new instance
637 }
638 }
639
640 // Should do a accurate anchor with init times properly aligned?
641 if ((anchoredLinkedTracks.size() + anchoredTracks.size()) > 1) {
642
643 assert (firstInitTime != null);
644
645 // Then calc all the deltas
646 for (LinkedTrack lt : anchoredLinkedTracks.keySet()) {
647 Mutable.Long it = anchoredLinkedTracks.get(lt);
648 it.value -= firstInitTime.value;
649 }
650
651 for (SampledTrack st : anchoredTracks.keySet()) {
652 Mutable.Long it = anchoredTracks.get(st);
653 it.value -= firstInitTime.value;
654 }
655
656 } else {
657 anchoredLinkedTracks = null;
658 anchoredTracks = null;
659 }
660
661 }
662
663 // If anchored a group of tracks .. adjust initiation times to
664 if (anchoredLinkedTracks != null) {
665
666 Mutable.Long firstInitTime = null;
667
668 for (LinkedTrack lt : anchoredLinkedTracks.keySet()) {
669 Mutable.Long it = anchoredLinkedTracks.get(lt);
670 if (it.value == 0) {
671 firstInitTime = lt.getInitiationTimeFromMeta();
672 break;
673 }
674 }
675 if (firstInitTime == null) {
676 for (SampledTrack st : anchoredTracks.keySet()) {
677 Mutable.Long it = anchoredTracks.get(st);
678 if (it.value == 0) {
679 firstInitTime = st.getInitiationTimeFromMeta();
680 break;
681 }
682 }
683 }
684 assert (firstInitTime != null);
685
686 for (LinkedTrack lt : anchoredLinkedTracks.keySet()) {
687 Mutable.Long it = anchoredLinkedTracks.get(lt);
688 if (it.value == 0) {
689 continue;
690 }
691 lt.setInitiationTime(firstInitTime.value + it.value);
692 }
693
694 for (SampledTrack st : anchoredTracks.keySet()) {
695 Mutable.Long it = anchoredTracks.get(st);
696 if (it.value == 0) {
697 continue;
698 }
699 st.setInitiationTime(firstInitTime.value + it.value);
700 }
701
702 }
703 }
704}
Note: See TracBrowser for help on using the repository browser.