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

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

Fixed an issue where Apollo PLACE gesture was causing creating polylines not to work.

Explanation: It used to be that Apollo would get first go at interpreting mouse/keyboard actions and would then optionally pass off to Expeditee. This was changed with the new GIO rework for both base Expeditee and Apollo getting to run their gestures. In this scenario, Expeditee was getting it's go at performing PLACE, and actually doing polylines correctly, but then Apollo was getting it's go and clearing the FreeItems list (which contained the new part of the polyline).

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