diff --git a/SmartDeviceLink/SDLCarWindow.h b/SmartDeviceLink/SDLCarWindow.h index aaed77b35..c3879fe3b 100755 --- a/SmartDeviceLink/SDLCarWindow.h +++ b/SmartDeviceLink/SDLCarWindow.h @@ -24,7 +24,20 @@ NS_ASSUME_NONNULL_BEGIN @param configuration The streaming media configuration @return An instance of this class */ -- (instancetype)initWithStreamManager:(SDLStreamingVideoLifecycleManager *)streamManager configuration:(SDLStreamingMediaConfiguration *)configuration; +- (instancetype)initWithStreamManager:(SDLStreamingVideoLifecycleManager *)streamManager + configuration:(SDLStreamingMediaConfiguration *)configuration; + +/** + Initialize the CarWindow automatic streamer. + + @param streamManager The stream manager to use for retrieving head unit dimension details and forwarding video frame data + @param configuration The streaming media configuration + @param scale The scale factor value to scale coordinates from one coordinate space to another + @return An instance of this class + */ +- (instancetype)initWithStreamManager:(SDLStreamingVideoLifecycleManager *)streamManager + configuration:(nonnull SDLStreamingMediaConfiguration *)configuration + scale:(float)scale; /** * View Controller that will be streamed. diff --git a/SmartDeviceLink/SDLCarWindow.m b/SmartDeviceLink/SDLCarWindow.m index bc96f2c8f..7d4097b94 100644 --- a/SmartDeviceLink/SDLCarWindow.m +++ b/SmartDeviceLink/SDLCarWindow.m @@ -10,6 +10,7 @@ #import #import #import +#import #import "SDLCarWindow.h" #import "SDLGlobals.h" @@ -38,14 +39,24 @@ @interface SDLCarWindow () @property (assign, nonatomic, getter=isVideoStreamStarted) BOOL videoStreamStarted; +@property (assign, nonatomic) float sdl_scale; + @end @implementation SDLCarWindow -- (instancetype)initWithStreamManager:(SDLStreamingVideoLifecycleManager *)streamManager configuration:(nonnull SDLStreamingMediaConfiguration *)configuration { +- (instancetype)initWithStreamManager:(SDLStreamingVideoLifecycleManager *)streamManager + configuration:(nonnull SDLStreamingMediaConfiguration *)configuration { + return [self initWithStreamManager:streamManager configuration:configuration scale:1.f]; +} + +- (instancetype)initWithStreamManager:(SDLStreamingVideoLifecycleManager *)streamManager + configuration:(nonnull SDLStreamingMediaConfiguration *)configuration + scale:(float)scale { self = [super init]; if (!self) { return nil; } + _sdl_scale = simd_clamp(scale, 1.f, 10.f); _streamManager = streamManager; _renderingType = configuration.carWindowRenderingType; _allowMultipleOrientations = configuration.allowMultipleViewControllerOrientations; @@ -129,8 +140,7 @@ - (void)sdl_didReceiveVideoStreamStarted:(NSNotification *)notification { } - (CGRect)sdl_getScaledScreenSizeFrame { - float scale = self.streamManager.videoStreamingCapability.scale.floatValue; - return CGRectMake(0, 0, self.streamManager.screenSize.width / scale, self.streamManager.screenSize.height / scale); + return CGRectMake(0, 0, self.streamManager.screenSize.width / self.sdl_scale, self.streamManager.screenSize.height / self.sdl_scale); } - (void)sdl_didReceiveVideoStreamStopped:(NSNotification *)notification { diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index c1530fbb5..a2074e06f 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -113,11 +113,11 @@ - (instancetype)initWithConnectionManager:(id)connecti } SDLLogD(@"Initializing CarWindow"); - _carWindow = [[SDLCarWindow alloc] initWithStreamManager:self configuration:configuration.streamingMediaConfig]; + _carWindow = [[SDLCarWindow alloc] initWithStreamManager:self configuration:configuration.streamingMediaConfig scale:self.sdl_scale]; _carWindow.rootViewController = configuration.streamingMediaConfig.rootViewController; } - _touchManager = [[SDLTouchManager alloc] initWithHitTester:(id)_focusableItemManager]; + _touchManager = [[SDLTouchManager alloc] initWithHitTester:(id)_focusableItemManager scale:self.sdl_scale]; _requestedEncryptionType = configuration.streamingMediaConfig.maximumDesiredEncryption; _dataSource = configuration.streamingMediaConfig.dataSource; @@ -252,6 +252,11 @@ - (SDLVideoStreamManagerState *)currentVideoStreamState { return self.videoStreamStateMachine.currentState; } +- (float)sdl_scale { + const float scale = self.videoStreamingCapability.scale.floatValue; + return (scale > 1.0) ? scale : 1.0; +} + #pragma mark - State Machines #pragma mark App State + (NSDictionary *)sdl_appStateTransitionDictionary { @@ -395,7 +400,7 @@ - (void)didEnterStateVideoStreamReady { NSAssert(self.videoFormat != nil, @"No video format is known, but it must be if we got a protocol start service response"); SDLLogD(@"Attempting to create video encoder"); - float scale = self.videoStreamingCapability.scale.floatValue; + const float scale = self.sdl_scale; CGSize scaledScreenSize = CGSizeMake(self.screenSize.width / scale, self.screenSize.height / scale); self.videoEncoder = [[SDLH264VideoEncoder alloc] initWithProtocol:self.videoFormat.protocol dimensions:scaledScreenSize ssrc:self.ssrc properties:self.videoEncoderSettings delegate:self error:&error]; diff --git a/SmartDeviceLink/SDLTouchManager.h b/SmartDeviceLink/SDLTouchManager.h index 9e01a8b0c..405a2aae9 100644 --- a/SmartDeviceLink/SDLTouchManager.h +++ b/SmartDeviceLink/SDLTouchManager.h @@ -102,6 +102,15 @@ typedef void(^SDLTouchEventHandler)(SDLTouch *touch, SDLTouchType type); */ - (instancetype)initWithHitTester:(nullable id)hitTester; +/** + Initialize a touch manager with a hit tester if available and a scale factor + + @param hitTester The hit tester to be used to correlate a point with a view + @param scale The scale factor value to scale coordinates from one coordinate space to another + @return The initialized touch manager + */ +- (instancetype)initWithHitTester:(nullable id)hitTester scale:(float)scale; + /** Called by SDLStreamingMediaManager in sync with the streaming framerate. This helps to moderate panning gestures by allowing the UI to be modified in time with the framerate. */ diff --git a/SmartDeviceLink/SDLTouchManager.m b/SmartDeviceLink/SDLTouchManager.m index 7f2ca8593..59f427652 100644 --- a/SmartDeviceLink/SDLTouchManager.m +++ b/SmartDeviceLink/SDLTouchManager.m @@ -6,8 +6,9 @@ // Copyright © 2016 smartdevicelink. All rights reserved. // -#import "SDLTouchManager.h" +#import +#import "SDLTouchManager.h" #import "CGPoint_Util.h" #import "SDLGlobals.h" @@ -99,17 +100,23 @@ @interface SDLTouchManager () */ @property (nonatomic) CGPoint lastNotifiedTouchLocation; +/** + The scale factor value to scale coordinates from one coordinate space to another + */ +@property (nonatomic, assign) float sdl_scale; + @end @implementation SDLTouchManager -- (instancetype)initWithHitTester:(nullable id)hitTester { - self = [super init]; - if (!self) { +- (instancetype)initWithHitTester:(nullable id)hitTester + scale:(float)scale { + if (!(self = [super init])) { return nil; } - + _hitTester = hitTester; + _sdl_scale = simd_clamp(scale, 1.f, 10.f); _movementTimeThreshold = 0.05f; _tapTimeThreshold = 0.4f; _tapDistanceThreshold = 50.0f; @@ -117,11 +124,16 @@ - (instancetype)initWithHitTester:(nullable id)hitTes _touchEnabled = YES; _enableSyncedPanning = YES; + //TODO: unsubscribe from notifications somewhere [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_onTouchEvent:) name:SDLDidReceiveTouchEventNotification object:nil]; return self; } +- (instancetype)initWithHitTester:(nullable id)hitTester { + return [self initWithHitTester:hitTester scale:1.f]; +} + #pragma mark - Public - (void)cancelPendingTouches { [self sdl_cancelSingleTapTimer]; @@ -222,13 +234,14 @@ - (void)sdl_onTouchEvent:(SDLRPCNotificationNotification *)notification { * @param onTouchEvent A SDLOnTouchEvent with coordinates. */ - (SDLOnTouchEvent *)sdl_applyScaleToEventCoordinates:(SDLOnTouchEvent *)onTouchEvent { - float scale = self.videoStreamingCapability.scale.floatValue; - if (scale > 1) { - for (SDLTouchEvent *touchEvent in onTouchEvent.event) { - for (SDLTouchCoord *coord in touchEvent.coord) { - coord.x = @(coord.x.floatValue / scale); - coord.y = @(coord.y.floatValue / scale); - } + const float scale = self.sdl_scale; + if (scale <= 1.f) { + return onTouchEvent; + } + for (SDLTouchEvent *touchEvent in onTouchEvent.event) { + for (SDLTouchCoord *coord in touchEvent.coord) { + coord.x = @(coord.x.floatValue / scale); + coord.y = @(coord.y.floatValue / scale); } } return onTouchEvent;