mirror of
https://github.com/zakk4223/CocoaSplit.git
synced 2026-05-25 22:00:30 -06:00
Reworked replace/merge/remove layout so it plays nicely with animation script timings
This commit is contained in:
parent
0242b25ad7
commit
4d230a07d5
8 changed files with 361 additions and 123 deletions
|
|
@ -43,6 +43,7 @@
|
|||
342346BB15F5FBD700C8C77E /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 342346BA15F5FBD700C8C77E /* CoreMedia.framework */; };
|
||||
342346BE15F6103D00C8C77E /* FFMpegTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 342346BD15F6103D00C8C77E /* FFMpegTask.m */; };
|
||||
342346CF15F9F07E00C8C77E /* CSAbstractCaptureDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 342346CE15F9F07E00C8C77E /* CSAbstractCaptureDevice.m */; };
|
||||
3427864B1EA4337400877B7B /* CSTransitionAnimationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3427864A1EA4337400877B7B /* CSTransitionAnimationDelegate.m */; };
|
||||
342B33B3198073EC00492CB7 /* line.fgsh in Resources */ = {isa = PBXBuildFile; fileRef = 342B33B2198073EC00492CB7 /* line.fgsh */; };
|
||||
342B33B4198075F200492CB7 /* line.fgsh in CopyFiles */ = {isa = PBXBuildFile; fileRef = 342B33B2198073EC00492CB7 /* line.fgsh */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
342B33B61980771200492CB7 /* line.vtsh in Resources */ = {isa = PBXBuildFile; fileRef = 342B33B51980771200492CB7 /* line.vtsh */; };
|
||||
|
|
@ -703,6 +704,8 @@
|
|||
342346CC15F9D52000C8C77E /* CSCaptureSourceProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CSCaptureSourceProtocol.h; path = PluginHeaders/CSCaptureSourceProtocol.h; sourceTree = "<group>"; };
|
||||
342346CD15F9F07E00C8C77E /* CSAbstractCaptureDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSAbstractCaptureDevice.h; path = PluginHeaders/CSAbstractCaptureDevice.h; sourceTree = "<group>"; };
|
||||
342346CE15F9F07E00C8C77E /* CSAbstractCaptureDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSAbstractCaptureDevice.m; sourceTree = "<group>"; };
|
||||
342786491EA4337400877B7B /* CSTransitionAnimationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSTransitionAnimationDelegate.h; sourceTree = "<group>"; };
|
||||
3427864A1EA4337400877B7B /* CSTransitionAnimationDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSTransitionAnimationDelegate.m; sourceTree = "<group>"; };
|
||||
342B33B2198073EC00492CB7 /* line.fgsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = line.fgsh; path = Shaders/line.fgsh; sourceTree = "<group>"; };
|
||||
342B33B51980771200492CB7 /* line.vtsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = line.vtsh; path = Shaders/line.vtsh; sourceTree = "<group>"; };
|
||||
342F73F41A245316007AA99F /* CSPcmPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSPcmPlayer.h; path = PluginHeaders/CSPcmPlayer.h; sourceTree = "<group>"; };
|
||||
|
|
@ -1363,6 +1366,8 @@
|
|||
34B5FAD31E74C34B0078FC51 /* CSSequenceItemLayout.m */,
|
||||
34B5FAD51E75120C0078FC51 /* CSSequenceItemTransition.h */,
|
||||
34B5FAD61E75120C0078FC51 /* CSSequenceItemTransition.m */,
|
||||
342786491EA4337400877B7B /* CSTransitionAnimationDelegate.h */,
|
||||
3427864A1EA4337400877B7B /* CSTransitionAnimationDelegate.m */,
|
||||
);
|
||||
path = CocoaSplit;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -2657,6 +2662,7 @@
|
|||
34B5FADD1E75BC910078FC51 /* CSLayoutSwitcherViewController.m in Sources */,
|
||||
34ED8C851B07371C002C0674 /* MIKMIDIMetaTextEvent.m in Sources */,
|
||||
34B5FACB1E7461E60078FC51 /* CSLayoutSequence.m in Sources */,
|
||||
3427864B1EA4337400877B7B /* CSTransitionAnimationDelegate.m in Sources */,
|
||||
34348C2A19BDBDC000A122C2 /* PluginManagerWindowController.m in Sources */,
|
||||
34CFE4A018F154DD00092C6A /* AVFChannelManager.m in Sources */,
|
||||
34ED8C6B1B07371C002C0674 /* MIKMIDIMacDebugQuickLookSupport.m in Sources */,
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -55,7 +55,9 @@ class AnimationBlock:
|
|||
|
||||
|
||||
def add_waitmarker(self, duration=0, target=None, wait_only=None, **kwargs):
|
||||
|
||||
if not self.current_begin_time:
|
||||
self.current_begin_time = self.layout.rootLayer().convertTime_fromLayer_(CACurrentMediaTime(), None)
|
||||
|
||||
new_mark = CSAnimation(None, "__CS_WAIT_MARK", None, **kwargs)
|
||||
new_mark.isWaitMark = True
|
||||
new_mark.duration = duration
|
||||
|
|
@ -85,6 +87,8 @@ class AnimationBlock:
|
|||
if animation.label:
|
||||
self.label_map[animation.label] = animation
|
||||
|
||||
NSLog("CURRENT BEGIN %f", self.current_begin_time)
|
||||
|
||||
a_duration = animation.apply(self.current_begin_time)
|
||||
|
||||
self.latest_end_time = animation.end_time
|
||||
|
|
|
|||
|
|
@ -110,33 +110,36 @@ def switchToLayout(name):
|
|||
layout = layoutByName(name)
|
||||
if layout:
|
||||
target_layout = getCurrentLayout()
|
||||
target_layout.replaceWithSourceLayout_(layout)
|
||||
if (CSAnimationBlock.current_frame() and target_layout.transitionName() or target_layout.transitionFilter()) and target_layout.transitionDuration() > 0:
|
||||
dummy_animation = CSAnimation(None, None, None)
|
||||
dummy_animation.duration = target_layout.transitionDuration()
|
||||
CSAnimationBlock.current_frame().add_animation(dummy_animation, None, None)
|
||||
target_layout.replaceWithSourceLayout_(layout)
|
||||
|
||||
|
||||
|
||||
def mergeLayout(name):
|
||||
layout = layoutByName(name)
|
||||
if layout:
|
||||
target_layout = getCurrentLayout()
|
||||
target_layout.mergeSourceLayout_(layout)
|
||||
if (CSAnimationBlock.current_frame() and target_layout.transitionName() or target_layout.transitionFilter()) and target_layout.transitionDuration() > 0:
|
||||
dummy_animation = CSAnimation(None, None, None)
|
||||
dummy_animation.duration = target_layout.transitionDuration()
|
||||
CSAnimationBlock.current_frame().add_animation(dummy_animation, None, None)
|
||||
target_layout.mergeSourceLayout_(layout)
|
||||
|
||||
|
||||
|
||||
def removeLayout(name):
|
||||
layout = layoutByName(name)
|
||||
if layout:
|
||||
target_layout = getCurrentLayout()
|
||||
target_layout.removeSourceLayout_(layout)
|
||||
if (CSAnimationBlock.current_frame() and target_layout.transitionName() or target_layout.transitionFilter()) and target_layout.transitionDuration() > 0:
|
||||
dummy_animation = CSAnimation(None, None, None)
|
||||
dummy_animation.duration = target_layout.transitionDuration()
|
||||
CSAnimationBlock.current_frame().add_animation(dummy_animation, None, None)
|
||||
target_layout.removeSourceLayout_(layout)
|
||||
|
||||
|
||||
|
||||
def inputByName(name):
|
||||
|
|
|
|||
27
CocoaSplit/CSTransitionAnimationDelegate.h
Normal file
27
CocoaSplit/CSTransitionAnimationDelegate.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// CSTransitionAnimationDelegate.h
|
||||
// CocoaSplit
|
||||
//
|
||||
// Created by Zakk on 4/16/17.
|
||||
// Copyright © 2017 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Quartz/Quartz.h>
|
||||
#import "SourceLayout.h"
|
||||
|
||||
@interface CSTransitionAnimationDelegate : NSObject <CAAnimationDelegate>
|
||||
@property (strong) NSArray *changedInputs;
|
||||
@property (strong) NSArray *removedInputs;
|
||||
@property (strong) NSArray *addedInputs;
|
||||
@property (strong) NSArray *changeremoveInputs;
|
||||
|
||||
@property (strong) CAAnimation *useAnimation;
|
||||
@property (assign) bool fullScreen;
|
||||
|
||||
@property (weak) SourceLayout *forLayout;
|
||||
|
||||
-(void)animationDidStart:(CAAnimation *)anim;
|
||||
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
|
||||
|
||||
@end
|
||||
69
CocoaSplit/CSTransitionAnimationDelegate.m
Normal file
69
CocoaSplit/CSTransitionAnimationDelegate.m
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// CSTransitionAnimationDelegate.m
|
||||
// CocoaSplit
|
||||
//
|
||||
// Created by Zakk on 4/16/17.
|
||||
// Copyright © 2017 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSTransitionAnimationDelegate.h"
|
||||
#import "InputSource.h"
|
||||
|
||||
@implementation CSTransitionAnimationDelegate
|
||||
|
||||
-(void)animationDidStart:(CAAnimation *)anim
|
||||
{
|
||||
NSLog(@"DELEGATE ANIMATION STARTED");
|
||||
|
||||
if (self.fullScreen)
|
||||
{
|
||||
[self.forLayout.rootLayer addAnimation:self.useAnimation forKey:nil];
|
||||
}
|
||||
|
||||
for (InputSource *nSrc in self.addedInputs)
|
||||
{
|
||||
if (self.useAnimation && !self.fullScreen)
|
||||
{
|
||||
[nSrc.layer addAnimation:self.useAnimation forKey:nil];
|
||||
}
|
||||
nSrc.layer.hidden = NO;
|
||||
|
||||
}
|
||||
|
||||
for (InputSource *cSrc in self.changedInputs)
|
||||
{
|
||||
if (self.useAnimation && !self.fullScreen)
|
||||
{
|
||||
[cSrc.layer addAnimation:self.useAnimation forKey:nil];
|
||||
}
|
||||
cSrc.layer.hidden = NO;
|
||||
|
||||
}
|
||||
|
||||
for (InputSource *cSrc in self.changeremoveInputs)
|
||||
{
|
||||
if (self.useAnimation && !self.fullScreen)
|
||||
{
|
||||
[cSrc.layer addAnimation:self.useAnimation forKey:nil];
|
||||
}
|
||||
cSrc.layer.hidden = YES;
|
||||
|
||||
}
|
||||
|
||||
for (InputSource *rSrc in self.removedInputs)
|
||||
{
|
||||
if (self.useAnimation && !self.fullScreen)
|
||||
{
|
||||
[rSrc.layer addAnimation:self.useAnimation forKey:nil];
|
||||
}
|
||||
rSrc.layer.hidden = YES;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
|
||||
{
|
||||
NSLog(@"DELEGATE ANIMATION STOPPED");
|
||||
}
|
||||
@end
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
GLuint _rFbo;
|
||||
dispatch_queue_t _animationQueue;
|
||||
NSMutableDictionary *_uuidMap;
|
||||
NSMutableDictionary *_uuidMapPresentation;
|
||||
bool _noSceneTransactions;
|
||||
NSMutableArray *_topLevelSourceArray;
|
||||
bool _skipRefCounting;
|
||||
|
|
@ -45,6 +46,8 @@
|
|||
|
||||
|
||||
@property (strong) NSMutableArray *sourceList;
|
||||
@property (strong) NSMutableArray *sourceListPresentation;
|
||||
|
||||
@property (readonly) NSArray *topLevelSourceList;
|
||||
|
||||
@property (strong) NSData *savedSourceListData;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#import "SourceLayout.h"
|
||||
#import "InputSource.h"
|
||||
#import "CaptureController.h"
|
||||
#import "CSTransitionAnimationDelegate.h"
|
||||
|
||||
|
||||
@implementation SourceLayout
|
||||
|
|
@ -30,6 +31,8 @@
|
|||
_fboTexture = 0;
|
||||
_rFbo = 0;
|
||||
_uuidMap = [NSMutableDictionary dictionary];
|
||||
_uuidMapPresentation = [NSMutableDictionary dictionary];
|
||||
|
||||
|
||||
_pendingScripts = [NSMutableDictionary dictionary];
|
||||
|
||||
|
|
@ -42,6 +45,8 @@
|
|||
//self.rootLayer.geometryFlipped = YES;
|
||||
_rootSize = NSMakeSize(_canvas_width, _canvas_height);
|
||||
self.sourceList = [NSMutableArray array];
|
||||
self.sourceListPresentation = [NSMutableArray array];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(inputAttachEvent:) name:CSNotificationInputAttached object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(inputAttachEvent:) name:CSNotificationInputDetached object:nil];
|
||||
|
||||
|
|
@ -612,6 +617,8 @@
|
|||
-(void)replaceWithSourceLayout:(SourceLayout *)layout withCompletionBlock:(void (^)(void))completionBlock
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (self.undoManager)
|
||||
{
|
||||
[self.undoManager beginUndoGrouping];
|
||||
|
|
@ -668,13 +675,34 @@
|
|||
NSArray *sameInputs = diffResult[@"same"];
|
||||
NSArray *newInputs = diffResult[@"new"];
|
||||
|
||||
NSNumber *aStart = nil;
|
||||
|
||||
id athing = [CATransaction valueForKey:@"__CS_BLOCK_OBJECT__"];
|
||||
if (athing)
|
||||
{
|
||||
aStart = [athing valueForKey:@"current_begin_time"];
|
||||
}
|
||||
|
||||
|
||||
CATransition *rTrans = nil;
|
||||
CABasicAnimation *bTrans = nil;
|
||||
|
||||
CSTransitionAnimationDelegate *transitionDelegate = [[CSTransitionAnimationDelegate alloc] init];
|
||||
transitionDelegate.addedInputs = newInputs;
|
||||
transitionDelegate.changedInputs = changedInputs;
|
||||
transitionDelegate.removedInputs = removedInputs;
|
||||
|
||||
|
||||
if (self.transitionName || self.transitionFilter)
|
||||
{
|
||||
rTrans = [CATransition animation];
|
||||
|
||||
if (aStart)
|
||||
{
|
||||
[rTrans setBeginTime:aStart.floatValue];
|
||||
}
|
||||
|
||||
|
||||
rTrans.type = self.transitionName;
|
||||
rTrans.duration = self.transitionDuration;
|
||||
rTrans.removedOnCompletion = YES;
|
||||
|
|
@ -683,14 +711,33 @@
|
|||
{
|
||||
rTrans.filter = self.transitionFilter;
|
||||
}
|
||||
|
||||
}
|
||||
//We always create a dummy animation so we play nice with scripts that do additional animations. This way we don't do final remove/reveal until the proper time
|
||||
NSString *dummyKey = [NSString stringWithFormat:@"__DUMMY_KEY_%f", aStart.floatValue];
|
||||
bTrans = [CABasicAnimation animationWithKeyPath:dummyKey];
|
||||
bTrans.removedOnCompletion = YES;
|
||||
bTrans.fillMode = kCAFillModeForwards;
|
||||
bTrans.beginTime = aStart.floatValue;
|
||||
if (rTrans)
|
||||
{
|
||||
bTrans.duration = self.transitionDuration;
|
||||
}
|
||||
transitionDelegate.useAnimation = rTrans;
|
||||
|
||||
bTrans.fromValue = @0;
|
||||
bTrans.toValue = @1;
|
||||
bTrans.delegate = transitionDelegate;
|
||||
if (aStart)
|
||||
{
|
||||
bTrans.beginTime = aStart.floatValue;
|
||||
}
|
||||
|
||||
|
||||
[CATransaction begin];
|
||||
|
||||
[CATransaction setCompletionBlock:^{
|
||||
|
||||
|
||||
|
||||
for (InputSource *rSrc in removedInputs)
|
||||
{
|
||||
[self deleteSource:rSrc];
|
||||
|
|
@ -709,58 +756,45 @@
|
|||
completionBlock();
|
||||
}
|
||||
}];
|
||||
|
||||
|
||||
if (self.transitionFullScene)
|
||||
|
||||
if (bTrans)
|
||||
{
|
||||
if (rTrans)
|
||||
{
|
||||
[self.rootLayer addAnimation:rTrans forKey:kCATransition];
|
||||
}
|
||||
transitionDelegate.forLayout = self;
|
||||
transitionDelegate.fullScreen = self.transitionFullScene;
|
||||
|
||||
[self.rootLayer addAnimation:bTrans forKey:bTrans.keyPath];
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (InputSource *rSrc in removedInputs)
|
||||
{
|
||||
if (!self.transitionFullScene)
|
||||
{
|
||||
[rSrc.layer addAnimation:rTrans forKey:nil];
|
||||
}
|
||||
rSrc.layer.hidden = YES;
|
||||
[self deleteSourceFromPresentation:rSrc];
|
||||
}
|
||||
|
||||
for (InputSource *cSrc in changedInputs)
|
||||
{
|
||||
InputSource *mSrc = [self inputForUUID:cSrc.uuid];
|
||||
|
||||
if (!self.transitionFullScene)
|
||||
{
|
||||
[mSrc.layer addAnimation:rTrans forKey:nil];
|
||||
}
|
||||
|
||||
|
||||
[self deleteSourceFromPresentation:mSrc];
|
||||
[changedRemove addObject:mSrc];
|
||||
|
||||
if (!self.transitionFullScene)
|
||||
{
|
||||
cSrc.layer.hidden = YES;
|
||||
}
|
||||
cSrc.layer.hidden = YES;
|
||||
|
||||
|
||||
[self addSource:cSrc withParentLayer:mSrc.layer.superlayer];
|
||||
mSrc.layer.hidden = YES;
|
||||
|
||||
}
|
||||
transitionDelegate.changeremoveInputs = changedRemove;
|
||||
|
||||
for (InputSource *nSrc in newInputs)
|
||||
{
|
||||
|
||||
if (!self.transitionFullScene)
|
||||
{
|
||||
nSrc.layer.hidden = YES;
|
||||
}
|
||||
|
||||
|
||||
nSrc.layer.hidden = YES;
|
||||
|
||||
[self addSource:nSrc];
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -768,31 +802,8 @@
|
|||
|
||||
|
||||
[CATransaction commit];
|
||||
|
||||
[CATransaction flush];
|
||||
if (!self.transitionFullScene)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[CATransaction begin];
|
||||
for (InputSource *nSrc in newInputs)
|
||||
{
|
||||
|
||||
[nSrc.layer addAnimation:rTrans forKey:nil];
|
||||
nSrc.layer.hidden = NO;
|
||||
}
|
||||
|
||||
for (InputSource *cSrc in changedInputs)
|
||||
{
|
||||
[cSrc.layer addAnimation:rTrans forKey:nil];
|
||||
cSrc.layer.hidden = NO;
|
||||
}
|
||||
|
||||
|
||||
[CATransaction commit];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[CATransaction flush];
|
||||
_noSceneTransactions = NO;
|
||||
|
||||
|
||||
|
|
@ -867,12 +878,34 @@
|
|||
NSArray *removedInputs = diffResult[@"removed"];
|
||||
NSArray *sameInputs = diffResult[@"same"];
|
||||
NSArray *newInputs = diffResult[@"new"];
|
||||
|
||||
|
||||
NSNumber *aStart = nil;
|
||||
|
||||
id athing = [CATransaction valueForKey:@"__CS_BLOCK_OBJECT__"];
|
||||
if (athing)
|
||||
{
|
||||
aStart = [athing valueForKey:@"current_begin_time"];
|
||||
}
|
||||
|
||||
|
||||
CATransition *rTrans = nil;
|
||||
CABasicAnimation *bTrans = nil;
|
||||
CSTransitionAnimationDelegate *transitionDelegate = [[CSTransitionAnimationDelegate alloc] init];
|
||||
transitionDelegate.addedInputs = newInputs;
|
||||
transitionDelegate.changedInputs = changedInputs;
|
||||
|
||||
|
||||
|
||||
if (self.transitionName || self.transitionFilter)
|
||||
{
|
||||
rTrans = [CATransition animation];
|
||||
|
||||
if (aStart)
|
||||
{
|
||||
[rTrans setBeginTime:aStart.floatValue];
|
||||
}
|
||||
|
||||
|
||||
rTrans.type = self.transitionName;
|
||||
rTrans.duration = self.transitionDuration;
|
||||
rTrans.removedOnCompletion = YES;
|
||||
|
|
@ -881,9 +914,24 @@
|
|||
{
|
||||
rTrans.filter = self.transitionFilter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//We always create a dummy animation so we play nice with scripts that do additional animations. This way we don't do final remove/reveal until the proper time
|
||||
NSString *dummyKey = [NSString stringWithFormat:@"__DUMMY_KEY_%f", aStart.floatValue];
|
||||
bTrans = [CABasicAnimation animationWithKeyPath:dummyKey];
|
||||
bTrans.removedOnCompletion = YES;
|
||||
bTrans.fillMode = kCAFillModeForwards;
|
||||
if (aStart)
|
||||
{
|
||||
bTrans.beginTime = aStart.floatValue;
|
||||
}
|
||||
bTrans.fromValue = @0;
|
||||
bTrans.toValue = @1;
|
||||
bTrans.duration = self.transitionDuration;
|
||||
transitionDelegate.useAnimation = rTrans;
|
||||
bTrans.delegate = transitionDelegate;
|
||||
|
||||
|
||||
[CATransaction begin];
|
||||
|
||||
|
|
@ -894,65 +942,65 @@
|
|||
[self deleteSource:cSrc];
|
||||
}
|
||||
|
||||
|
||||
if (completionBlock)
|
||||
if (bTrans)
|
||||
{
|
||||
completionBlock();
|
||||
}
|
||||
}];
|
||||
|
||||
if (self.transitionFullScene)
|
||||
{
|
||||
[self.rootLayer addAnimation:rTrans forKey:nil];
|
||||
}
|
||||
|
||||
for (InputSource *nSrc in newInputs)
|
||||
{
|
||||
if (!self.transitionFullScene)
|
||||
{
|
||||
nSrc.layer.hidden = YES;
|
||||
}
|
||||
|
||||
[self addSource:nSrc];
|
||||
}
|
||||
|
||||
for (InputSource *cSrc in changedInputs)
|
||||
{
|
||||
InputSource *mSrc = [self inputForUUID:cSrc.uuid];
|
||||
[changedRemove addObject:mSrc];
|
||||
mSrc.layer.hidden = YES;
|
||||
cSrc.layer.hidden = YES;
|
||||
[self addSource:cSrc];
|
||||
[self incrementInputRef:cSrc];
|
||||
}
|
||||
[CATransaction commit];
|
||||
[CATransaction flush];
|
||||
|
||||
if (!self.transitionFullScene)
|
||||
{
|
||||
|
||||
CABasicAnimation *hackAnim = [CABasicAnimation animationWithKeyPath:@"dummyKeyPath"];
|
||||
hackAnim.duration = rTrans.duration;
|
||||
hackAnim.fromValue = @0;
|
||||
hackAnim.toValue = @100;
|
||||
hackAnim.removedOnCompletion = YES;
|
||||
|
||||
[self.rootLayer addAnimation:hackAnim forKey:@"dummyKey"];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
for (InputSource *nSrc in newInputs)
|
||||
{
|
||||
[nSrc.layer addAnimation:rTrans forKey:nil];
|
||||
nSrc.layer.hidden = NO;
|
||||
}
|
||||
|
||||
for (InputSource *cSrc in changedInputs)
|
||||
{
|
||||
[cSrc.layer addAnimation:rTrans forKey:nil];
|
||||
cSrc.layer.hidden = NO;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (completionBlock)
|
||||
{
|
||||
completionBlock();
|
||||
}
|
||||
|
||||
|
||||
}];
|
||||
|
||||
if (bTrans)
|
||||
{
|
||||
transitionDelegate.forLayout = self;
|
||||
transitionDelegate.fullScreen = self.transitionFullScene;
|
||||
|
||||
[self.rootLayer addAnimation:bTrans forKey:bTrans.keyPath];
|
||||
}
|
||||
|
||||
|
||||
for (InputSource *nSrc in newInputs)
|
||||
{
|
||||
|
||||
nSrc.layer.hidden = YES;
|
||||
[self addSource:nSrc];
|
||||
|
||||
}
|
||||
|
||||
for (InputSource *cSrc in changedInputs)
|
||||
{
|
||||
InputSource *mSrc = [self inputForUUID:cSrc.uuid];
|
||||
[self deleteSourceFromPresentation:mSrc];
|
||||
[changedRemove addObject:mSrc];
|
||||
|
||||
|
||||
cSrc.layer.hidden = YES;
|
||||
|
||||
[self addSource:cSrc withParentLayer:mSrc.layer.superlayer];
|
||||
[self incrementInputRef:cSrc];
|
||||
}
|
||||
transitionDelegate.changeremoveInputs = changedRemove;
|
||||
|
||||
[CATransaction commit];
|
||||
[CATransaction flush];
|
||||
|
||||
[self adjustAllInputs];
|
||||
|
||||
}
|
||||
|
|
@ -993,6 +1041,8 @@
|
|||
|
||||
NSDictionary *diffResult = [self diffSourceListWithData:toRemove];
|
||||
|
||||
NSMutableArray *realRemove = [NSMutableArray array];
|
||||
|
||||
NSArray *changedInputs = diffResult[@"changed"];
|
||||
NSArray *sameInputs = diffResult[@"same"];
|
||||
NSArray *newInputs = diffResult[@"new"];
|
||||
|
|
@ -1000,12 +1050,31 @@
|
|||
NSMutableArray *removeInputs = [NSMutableArray arrayWithArray:changedInputs];
|
||||
[removeInputs addObjectsFromArray:sameInputs];
|
||||
[removeInputs addObjectsFromArray:newInputs];
|
||||
NSNumber *aStart = nil;
|
||||
|
||||
id athing = [CATransaction valueForKey:@"__CS_BLOCK_OBJECT__"];
|
||||
if (athing)
|
||||
{
|
||||
aStart = [athing valueForKey:@"current_begin_time"];
|
||||
}
|
||||
|
||||
|
||||
CATransition *rTrans = nil;
|
||||
CABasicAnimation *bTrans = nil;
|
||||
|
||||
CSTransitionAnimationDelegate *transitionDelegate = [[CSTransitionAnimationDelegate alloc] init];
|
||||
|
||||
|
||||
if (self.transitionName || self.transitionFilter)
|
||||
{
|
||||
rTrans = [CATransition animation];
|
||||
|
||||
if (aStart)
|
||||
{
|
||||
[rTrans setBeginTime:aStart.floatValue];
|
||||
}
|
||||
|
||||
|
||||
rTrans.type = self.transitionName;
|
||||
rTrans.duration = self.transitionDuration;
|
||||
rTrans.removedOnCompletion = YES;
|
||||
|
|
@ -1015,16 +1084,34 @@
|
|||
rTrans.filter = self.transitionFilter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//We always create a dummy animation so we play nice with scripts that do additional animations. This way we don't do final remove/reveal until the proper time
|
||||
NSString *dummyKey = [NSString stringWithFormat:@"__DUMMY_KEY_%f", aStart.floatValue];
|
||||
bTrans = [CABasicAnimation animationWithKeyPath:dummyKey];
|
||||
bTrans.removedOnCompletion = YES;
|
||||
bTrans.fillMode = kCAFillModeForwards;
|
||||
if (aStart)
|
||||
{
|
||||
bTrans.beginTime = aStart.floatValue;
|
||||
}
|
||||
bTrans.fromValue = @0;
|
||||
bTrans.toValue = @1;
|
||||
if (rTrans)
|
||||
{
|
||||
bTrans.duration = self.transitionDuration;
|
||||
}
|
||||
transitionDelegate.useAnimation = rTrans;
|
||||
bTrans.delegate = transitionDelegate;
|
||||
|
||||
[CATransaction begin];
|
||||
[CATransaction setCompletionBlock:^{
|
||||
|
||||
|
||||
for (InputSource *rSrc in removeInputs)
|
||||
for (InputSource *rSrc in realRemove)
|
||||
{
|
||||
InputSource *eSrc = [self inputForUUID:rSrc.uuid];
|
||||
[self decrementInputRef:eSrc];
|
||||
[self deleteSource:eSrc];
|
||||
[self decrementInputRef:rSrc];
|
||||
[self deleteSource:rSrc];
|
||||
}
|
||||
|
||||
if (completionBlock)
|
||||
|
|
@ -1033,6 +1120,16 @@
|
|||
}
|
||||
}];
|
||||
|
||||
|
||||
if (bTrans)
|
||||
{
|
||||
transitionDelegate.forLayout = self;
|
||||
transitionDelegate.fullScreen = self.transitionFullScene;
|
||||
|
||||
[self.rootLayer addAnimation:bTrans forKey:bTrans.keyPath];
|
||||
}
|
||||
|
||||
|
||||
if (self.transitionFullScene)
|
||||
{
|
||||
[self.rootLayer addAnimation:rTrans forKey:nil];
|
||||
|
|
@ -1045,13 +1142,11 @@
|
|||
|
||||
if (eSrc)
|
||||
{
|
||||
if (!self.transitionFullScene)
|
||||
{
|
||||
[eSrc.layer addAnimation:rTrans forKey:kCAOnOrderOut];
|
||||
}
|
||||
eSrc.layer.hidden = YES;
|
||||
|
||||
[realRemove addObject:eSrc];
|
||||
[self deleteSourceFromPresentation:eSrc];
|
||||
}
|
||||
|
||||
transitionDelegate.removedInputs = realRemove;
|
||||
}
|
||||
[CATransaction commit];
|
||||
|
||||
|
|
@ -1135,6 +1230,9 @@
|
|||
|
||||
self.sourceList = [NSMutableArray array];
|
||||
_uuidMap = [NSMutableDictionary dictionary];
|
||||
self.sourceListPresentation = [NSMutableArray array];
|
||||
_uuidMapPresentation = [NSMutableDictionary dictionary];
|
||||
|
||||
|
||||
|
||||
if (!withData)
|
||||
|
|
@ -1206,6 +1304,21 @@
|
|||
|
||||
|
||||
|
||||
-(void)deleteSourceFromPresentation:(InputSource *)delSource
|
||||
{
|
||||
@synchronized (self) {
|
||||
[self.sourceListPresentation removeObject:delSource];
|
||||
}
|
||||
|
||||
InputSource *uSrc;
|
||||
|
||||
uSrc = _uuidMapPresentation[delSource.uuid];
|
||||
if ([uSrc isEqual:delSource])
|
||||
{
|
||||
[_uuidMapPresentation removeObjectForKey:delSource.uuid];
|
||||
}
|
||||
|
||||
}
|
||||
-(void)deleteSource:(InputSource *)delSource
|
||||
{
|
||||
|
||||
|
|
@ -1214,6 +1327,7 @@
|
|||
[self willChangeValueForKey:@"topLevelSourceList"];
|
||||
@synchronized (self) {
|
||||
[[self mutableArrayValueForKey:@"sourceList" ] removeObject:delSource];
|
||||
[self.sourceListPresentation removeObject:delSource];
|
||||
}
|
||||
[self generateTopLevelSourceList];
|
||||
[self didChangeValueForKey:@"topLevelSourceList"];
|
||||
|
|
@ -1226,6 +1340,12 @@
|
|||
[_uuidMap removeObjectForKey:delSource.uuid];
|
||||
}
|
||||
|
||||
uSrc = _uuidMapPresentation[delSource.uuid];
|
||||
if ([uSrc isEqual:delSource])
|
||||
{
|
||||
[_uuidMapPresentation removeObjectForKey:delSource.uuid];
|
||||
}
|
||||
|
||||
//[self.sourceList removeObject:delSource];
|
||||
if (delSource == self.layoutTimingSource)
|
||||
{
|
||||
|
|
@ -1280,6 +1400,7 @@
|
|||
newSource.sourceLayout = self;
|
||||
newSource.is_live = self.isActive;
|
||||
|
||||
[self.sourceListPresentation addObject:newSource];
|
||||
[[self mutableArrayValueForKey:@"sourceList" ] addObject:newSource];
|
||||
|
||||
|
||||
|
|
@ -1290,7 +1411,7 @@
|
|||
newSource.needsAdjustment = YES;
|
||||
|
||||
|
||||
|
||||
[_uuidMapPresentation setObject:newSource forKey:newSource.uuid];
|
||||
[_uuidMap setObject:newSource forKey:newSource.uuid];
|
||||
|
||||
[self incrementInputRef:newSource];
|
||||
|
|
@ -1308,11 +1429,13 @@
|
|||
@synchronized(self)
|
||||
{
|
||||
[self.sourceList removeAllObjects];
|
||||
[self.sourceListPresentation removeAllObjects];
|
||||
[self generateTopLevelSourceList];
|
||||
|
||||
|
||||
}
|
||||
[_uuidMap removeAllObjects];
|
||||
[_uuidMapPresentation removeAllObjects];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1503,7 +1626,10 @@
|
|||
|
||||
-(InputSource *)inputForName:(NSString *)name
|
||||
{
|
||||
for (InputSource *tSrc in self.sourceList)
|
||||
|
||||
NSArray *useList = self.sourceListPresentation;
|
||||
|
||||
for (InputSource *tSrc in useList)
|
||||
{
|
||||
if (tSrc.name && [tSrc.name isEqualToString:name])
|
||||
{
|
||||
|
|
@ -1516,7 +1642,7 @@
|
|||
|
||||
-(InputSource *)inputForUUID:(NSString *)uuid
|
||||
{
|
||||
return [_uuidMap objectForKey:uuid];
|
||||
return [_uuidMapPresentation objectForKey:uuid];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue