diff --git a/Limelight/Base.lproj/iPad.storyboard b/Limelight/Base.lproj/iPad.storyboard
index 43338ddc..c887646f 100644
--- a/Limelight/Base.lproj/iPad.storyboard
+++ b/Limelight/Base.lproj/iPad.storyboard
@@ -445,11 +445,12 @@ ICAgICAgICAgICAgICA
-
+
-
-
+
+
+
@@ -867,32 +868,32 @@ ICAgICAgICAgICAgICA
-
+
-
+
-
-
+
+
-
-
+
+
-
+
+
+
+
+
+
+
@@ -928,6 +935,7 @@ ICAgICAgICAgICAgICA
+
diff --git a/Limelight/Base.lproj/iPhone.storyboard b/Limelight/Base.lproj/iPhone.storyboard
index 5b74ce52..ab2a8ffd 100644
--- a/Limelight/Base.lproj/iPhone.storyboard
+++ b/Limelight/Base.lproj/iPhone.storyboard
@@ -407,11 +407,12 @@ ICAgICAgICAgICAgIA
-
+
-
-
+
+
+
@@ -731,14 +732,14 @@ ICAgICAgICAgICAgIA
-
+
-
+
-
+
-
+
@@ -870,40 +871,46 @@ ICAgICAgICAgICAgIA
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
@@ -918,6 +925,7 @@ ICAgICAgICAgICAgIA
+
@@ -930,13 +938,14 @@ ICAgICAgICAgICAgIA
+
-
+
diff --git a/Limelight/Database/DataManager.h b/Limelight/Database/DataManager.h
index b852b5cc..d250fa94 100644
--- a/Limelight/Database/DataManager.h
+++ b/Limelight/Database/DataManager.h
@@ -41,7 +41,8 @@
btMouseSupport:(BOOL)btMouseSupport
// absoluteTouchMode:(BOOL)absoluteTouchMode
touchMode:(NSInteger)touchMode
- statsOverlay:(BOOL)statsOverlay
+ statsOverlayLevel:(NSInteger)statsOverlayLevel
+ statsOverlayEnabled:(BOOL)statsOverlayEnabled
unlockDisplayOrientation:(BOOL)unlockDisplayOrientation
resolutionSelected:(NSInteger)resolutionSelected
externalDisplayMode:(NSInteger)externalDisplayMode
diff --git a/Limelight/Database/DataManager.m b/Limelight/Database/DataManager.m
index 8fa7f0e2..7e2975f9 100644
--- a/Limelight/Database/DataManager.m
+++ b/Limelight/Database/DataManager.m
@@ -80,7 +80,8 @@
btMouseSupport:(BOOL)btMouseSupport
// absoluteTouchMode:(BOOL)absoluteTouchMode
touchMode:(NSInteger)touchMode
- statsOverlay:(BOOL)statsOverlay
+ statsOverlayLevel:(NSInteger)statsOverlayLevel
+ statsOverlayEnabled:(BOOL)statsOverlayEnabled
unlockDisplayOrientation:(BOOL)unlockDisplayOrientation
resolutionSelected:(NSInteger)resolutionSelected
externalDisplayMode:(NSInteger)externalDisplayMode
@@ -116,7 +117,8 @@
settingsToSave.btMouseSupport = btMouseSupport;
// settingsToSave.absoluteTouchMode = absoluteTouchMode;
settingsToSave.touchMode = [NSNumber numberWithInteger:(uint16_t)touchMode];
- settingsToSave.statsOverlay = statsOverlay;
+ settingsToSave.statsOverlayEnabled = statsOverlayEnabled;
+ settingsToSave.statsOverlayLevel = [NSNumber numberWithInteger:(uint16_t)statsOverlayLevel];
settingsToSave.unlockDisplayOrientation = unlockDisplayOrientation;
settingsToSave.resolutionSelected = [NSNumber numberWithInteger:resolutionSelected];
settingsToSave.externalDisplayMode = [NSNumber numberWithInteger:externalDisplayMode];
diff --git a/Limelight/Database/TemporarySettings.h b/Limelight/Database/TemporarySettings.h
index d0cc6da9..5dbe9e65 100644
--- a/Limelight/Database/TemporarySettings.h
+++ b/Limelight/Database/TemporarySettings.h
@@ -53,7 +53,8 @@
@property (nonatomic) BOOL btMouseSupport;
// @property (nonatomic) BOOL absoluteTouchMode;
@property (nonatomic, retain) NSNumber * touchMode;
-@property (nonatomic) BOOL statsOverlay;
+@property (nonatomic, retain) NSNumber * statsOverlayLevel;
+@property (nonatomic) BOOL statsOverlayEnabled;
@property (nonatomic) BOOL liftStreamViewForKeyboard;
@property (nonatomic) BOOL showKeyboardToolbar;
@property (nonatomic) BOOL unlockDisplayOrientation;
diff --git a/Limelight/Database/TemporarySettings.m b/Limelight/Database/TemporarySettings.m
index 87e010c5..dbc78d7c 100644
--- a/Limelight/Database/TemporarySettings.m
+++ b/Limelight/Database/TemporarySettings.m
@@ -87,7 +87,8 @@
self.btMouseSupport = settings.btMouseSupport;
// self.absoluteTouchMode = settings.absoluteTouchMode;
self.touchMode = settings.touchMode;
- self.statsOverlay = settings.statsOverlay;
+ self.statsOverlayLevel = settings.statsOverlayLevel;
+ self.statsOverlayEnabled = settings.statsOverlayEnabled;
self.keyboardToggleFingers = settings.keyboardToggleFingers;
self.oscLayoutToolFingers = settings.oscLayoutToolFingers;
self.slideToSettingsScreenEdge = settings.slideToSettingsScreenEdge;
diff --git a/Limelight/Input/CommandManager.swift b/Limelight/Input/CommandManager.swift
index 7ba17d1e..8767ffef 100644
--- a/Limelight/Input/CommandManager.swift
+++ b/Limelight/Input/CommandManager.swift
@@ -74,6 +74,14 @@ import UIKit
"OSCL2" : 0,
"OSCR2" : 0]
+ @objc public static let oscRectangleButtonCmds: [String] = [
+ "OSCUP",
+ "OSCDOWN",
+ "OSCLEFT",
+ "OSCRIGHT",
+ "OSCSTART",
+ "OSCSELECT"]
+
@objc public static let touchPadCmds: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD", "MOUSEPAD", "DPAD", "WASDPAD", "ARROWPAD"]
@objc public static let stickTouchPads: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD"]
@objc public static let nonVectorStickPads: [String] = ["LSPAD", "RSPAD"]
diff --git a/Limelight/Input/CustomOSC/LayoutOnScreenControls.h b/Limelight/Input/CustomOSC/LayoutOnScreenControls.h
index 957ab5ba..d90832a3 100644
--- a/Limelight/Input/CustomOSC/LayoutOnScreenControls.h
+++ b/Limelight/Input/CustomOSC/LayoutOnScreenControls.h
@@ -8,6 +8,7 @@
#import
#import "OnScreenControls.h"
+#import "Moonlight-Swift.h"
NS_ASSUME_NONNULL_BEGIN
/**
@@ -19,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
@property UIView* _view;
@property NSMutableArray *layoutChanges;
@property CALayer *layerBeingDragged;
+@property UIViewController *layoutToolVC;
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport
streamConfig:(StreamConfiguration*)streamConfig oscLevel:(int)oscLevel;
@@ -29,7 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
-
+// - (void) updateGuidelinesForOnScreenWidget:(OnScreenWidgetView* )widget;
@end
NS_ASSUME_NONNULL_END
diff --git a/Limelight/Input/CustomOSC/LayoutOnScreenControls.m b/Limelight/Input/CustomOSC/LayoutOnScreenControls.m
index 0c69cdb5..7b688e95 100644
--- a/Limelight/Input/CustomOSC/LayoutOnScreenControls.m
+++ b/Limelight/Input/CustomOSC/LayoutOnScreenControls.m
@@ -11,7 +11,6 @@
#import "OnScreenButtonState.h"
#import "OSCProfilesManager.h"
-
@interface LayoutOnScreenControls ()
@end
@@ -26,7 +25,16 @@
@synthesize _view;
@synthesize layoutChanges;
+
+
+
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport streamConfig:(StreamConfiguration*)streamConfig oscLevel:(int)oscLevel {
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(updateGuidelinesForOnScreenWidget:)
+ name:@"OnScreenWidgetMovedByTouch" // This is a special notification for reloading the on screen keyboard buttons. which can't be executed by _oscProfilesTableViewController.needToUpdateOscLayoutTVC code block, and has to be triggered by a notification
+ object:nil];
+
+
_view = view;
_view.multipleTouchEnabled = false;
@@ -101,6 +109,57 @@
[self._view addSubview: verticalGuideline];
}
+- (void) updateGuidelinesForOnScreenWidget: (NSNotification *)notification{
+ /* have guidelines follow wherever the user is touching on the screen */
+ OnScreenWidgetView* widget = notification.object;
+ horizontalGuideline.hidden = verticalGuideline.hidden = NO;
+ horizontalGuideline.center = verticalGuideline.center = CGPointMake(CGRectGetMidX(widget.frame), CGRectGetMidY(widget.frame));
+ /*
+ Telegraph to the user whether the horizontal and/or vertical guidelines line up with one or more of the buttons on screen by doing the following:
+ -Change horizontal guideline color to yellow if its y-position is almost equal to that of one of the buttons on screen.
+ -Change vertical guideline color to yellow if its x-position is almost equal to that of one of the buttons on screen.
+ */
+
+ horizontalGuideline.backgroundColor = [UIColor blueColor]; // change horizontal guideline back to blue if it doesn't line up with one of the on screen buttons
+ for (CALayer *button in self.OSCButtonLayers) { // horizontal guideline position check
+ if ((layerBeingDragged != button) && !button.isHidden) {
+ if ((horizontalGuideline.center.y < button.position.y + 1) &&
+ (horizontalGuideline.center.y > button.position.y - 1)) {
+ horizontalGuideline.backgroundColor = [UIColor yellowColor];
+ break;
+ }
+ }
+ }
+ for(UIView* view in self.layoutToolVC.view.subviews){
+ if ([view isKindOfClass:[OnScreenWidgetView class]] && view != widget) {
+ if ((horizontalGuideline.center.y < view.center.y + 1) && (horizontalGuideline.center.y > view.center.y - 1)) {
+ horizontalGuideline.backgroundColor = [UIColor yellowColor];
+ break;
+ }
+ }
+ }
+
+ verticalGuideline.backgroundColor = [UIColor blueColor]; // change vertical guideline back to blue if it doesn't line up with one of the on screen buttons
+ for (CALayer *button in self.OSCButtonLayers) { // vertical guideline position check
+ if ((layerBeingDragged != button) && !button.isHidden) {
+ if ((verticalGuideline.center.x < button.position.x + 1) &&
+ (verticalGuideline.center.x > button.position.x - 1)) {
+ verticalGuideline.backgroundColor = [UIColor yellowColor];
+ break;
+ }
+ }
+ }
+ for(UIView* view in self.layoutToolVC.view.subviews){
+ if ([view isKindOfClass:[OnScreenWidgetView class]] && view != widget) {
+ if ((verticalGuideline.center.x < view.center.x + 1) && (verticalGuideline.center.x > view.center.x - 1)) {
+ verticalGuideline.backgroundColor = [UIColor yellowColor];
+ break;
+ }
+ }
+ }
+
+}
+
#pragma mark - Queries
@@ -179,7 +238,7 @@
[[NSNotificationCenter defaultCenter] postNotificationName:@"ControllerCALayerSelected" object:layerBeingDragged]; // inform that a CALayer of onScreen controller has being selected
/* save the name, position, and visibility of button being touched in array in case user wants to undo the change later */
- OnScreenButtonState *onScreenButtonState = [[OnScreenButtonState alloc] initWithButtonName:layerBeingDragged.name buttonType:GameControllerButton andPosition:layerBeingDragged.position];
+ OnScreenButtonState *onScreenButtonState = [[OnScreenButtonState alloc] initWithButtonName:layerBeingDragged.name buttonType:LegacyOscButton andPosition:layerBeingDragged.position];
// add hidden attr here
onScreenButtonState.isHidden = layerBeingDragged.isHidden;
@@ -198,6 +257,7 @@
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInView:_view];
+
layerBeingDragged.position = touchLocation; // move object to touch location
/* have guidelines follow wherever the user is touching on the screen */
@@ -206,32 +266,47 @@
/*
Telegraph to the user whether the horizontal and/or vertical guidelines line up with one or more of the buttons on screen by doing the following:
- -Change horizontal guideline color to white if its y-position is almost equal to that of one of the buttons on screen.
- -Change vertical guideline color to white if its x-position is almost equal to that of one of the buttons on screen.
+ -Change horizontal guideline color to yellow if its y-position is almost equal to that of one of the buttons on screen.
+ -Change vertical guideline color to yellow if its x-position is almost equal to that of one of the buttons on screen.
*/
+ horizontalGuideline.backgroundColor = [UIColor blueColor]; // change horizontal guideline back to blue if it doesn't line up with one of the on screen buttons
for (CALayer *button in self.OSCButtonLayers) { // horizontal guideline position check
-
if ((layerBeingDragged != button) && !button.isHidden) {
if ((horizontalGuideline.center.y < button.position.y + 1) &&
(horizontalGuideline.center.y > button.position.y - 1)) {
- horizontalGuideline.backgroundColor = [UIColor whiteColor];
+ horizontalGuideline.backgroundColor = [UIColor yellowColor];
break;
}
}
-
- horizontalGuideline.backgroundColor = [UIColor blueColor]; // change horizontal guideline back to blue if it doesn't line up with one of the on screen buttons
}
+ // alignment with onScreenWidgets
+ for(UIView* view in self.layoutToolVC.view.subviews){
+ if ([view isKindOfClass:[OnScreenWidgetView class]]) {
+ if ((horizontalGuideline.center.y < view.center.y + 1) && (horizontalGuideline.center.y > view.center.y - 1)) {
+ horizontalGuideline.backgroundColor = [UIColor yellowColor];
+ break;
+ }
+ }
+ }
+
+ verticalGuideline.backgroundColor = [UIColor blueColor]; // change vertical guideline back to blue if it doesn't line up with one of the on screen buttons
for (CALayer *button in self.OSCButtonLayers) { // vertical guideline position check
-
if ((layerBeingDragged != button) && !button.isHidden) {
if ((verticalGuideline.center.x < button.position.x + 1) &&
(verticalGuideline.center.x > button.position.x - 1)) {
- verticalGuideline.backgroundColor = [UIColor whiteColor];
+ verticalGuideline.backgroundColor = [UIColor yellowColor];
+ break;
+ }
+ }
+ }
+ // alignment with onScreenWidgets
+ for(UIView* view in self.layoutToolVC.view.subviews){
+ if ([view isKindOfClass:[OnScreenWidgetView class]]) {
+ if ((verticalGuideline.center.x < view.center.x + 1) && (verticalGuideline.center.x > view.center.x - 1)) {
+ verticalGuideline.backgroundColor = [UIColor yellowColor];
break;
}
}
-
- verticalGuideline.backgroundColor = [UIColor blueColor]; // change vertical guideline back to blue if it doesn't line up with one of the on screen buttons
}
}
diff --git a/Limelight/Input/CustomOSC/OSCProfilesManager.h b/Limelight/Input/CustomOSC/OSCProfilesManager.h
index cc036f1a..dd3c5de6 100644
--- a/Limelight/Input/CustomOSC/OSCProfilesManager.h
+++ b/Limelight/Input/CustomOSC/OSCProfilesManager.h
@@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (OSCProfilesManager *) sharedManager;
-+ (void) setOnScreenButtonViewsDict:(NSMutableDictionary* )dict;
++ (void) setOnScreenWidgetViewsDict:(NSMutableDictionary* )dict;
#pragma mark - Getters
/**
diff --git a/Limelight/Input/CustomOSC/OSCProfilesManager.m b/Limelight/Input/CustomOSC/OSCProfilesManager.m
index b7fc9834..5274e82b 100644
--- a/Limelight/Input/CustomOSC/OSCProfilesManager.m
+++ b/Limelight/Input/CustomOSC/OSCProfilesManager.m
@@ -14,7 +14,7 @@
@implementation OSCProfilesManager
-static NSMutableDictionary *onScreenButtonViewsDict;
+static NSMutableDictionary *OnScreenWidgetViewsDict;
#pragma mark - Initializer
@@ -32,8 +32,8 @@ static NSMutableDictionary *onScreenButtonViewsDict;
#pragma mark - Class Helper Methods
-+ (void) setOnScreenButtonViewsDict:(NSMutableDictionary* )dict{
- onScreenButtonViewsDict = dict;
++ (void) setOnScreenWidgetViewsDict:(NSMutableDictionary* )dict{
+ OnScreenWidgetViewsDict = dict;
}
/**
@@ -267,7 +267,7 @@ static NSMutableDictionary *onScreenButtonViewsDict;
// save on-screen game controller buttons & sticks as buttonstate:
for (CALayer *oscButtonLayer in oscButtonLayers) {
- OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:oscButtonLayer.name buttonType:GameControllerButton andPosition:oscButtonLayer.position];
+ OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:oscButtonLayer.name buttonType:LegacyOscButton andPosition:oscButtonLayer.position];
// add hidden attr here
buttonState.isHidden = oscButtonLayer.isHidden;
buttonState.oscLayerSizeFactor = [OnScreenControls getControllerLayerSizeFactor:oscButtonLayer];
@@ -281,17 +281,18 @@ static NSMutableDictionary *onScreenButtonViewsDict;
[buttonStatesEncoded addObject: buttonStateEncoded];
}
- // save on-screen button views (keyboard & mouse command) as buttonstate:
- [onScreenButtonViewsDict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { // this dict is passed from the layout tool VC, as a static obj in this class.
- OnScreenButtonView *buttonView = value;
- OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:buttonView.keyString buttonType:KeyboardOrMouseButton andPosition:buttonView.frame.origin];
- buttonState.alias = buttonView.keyLabel;
- buttonState.timestamp = buttonView.timestamp;
- buttonState.widthFactor = buttonView.widthFactor;
- buttonState.heightFactor = buttonView.heightFactor;
- buttonState.backgroundAlpha = buttonView.backgroundAlpha;
- buttonState.sensitivityFactor = buttonView.sensitivityFactor;
- buttonState.stickIndicatorXOffset = buttonView.stickIndicatorXOffset;
+ // save on-screen widget views (keyboard & mouse command) as buttonstate:
+ [OnScreenWidgetViewsDict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { // this dict is passed from the layout tool VC, as a static obj in this class.
+ OnScreenWidgetView *widgetView = value;
+ OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:widgetView.keyString buttonType:CustomOnScreenWidget andPosition:widgetView.center];
+ buttonState.alias = widgetView.keyLabel;
+ buttonState.timestamp = widgetView.timestamp;
+ buttonState.widthFactor = widgetView.widthFactor;
+ buttonState.heightFactor = widgetView.heightFactor;
+ buttonState.backgroundAlpha = widgetView.backgroundAlpha;
+ buttonState.borderWidth = widgetView.borderWidth;
+ buttonState.sensitivityFactor = widgetView.sensitivityFactor;
+ buttonState.stickIndicatorXOffset = widgetView.stickIndicatorXOffset;
NSData *buttonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil];
[buttonStatesEncoded addObject: buttonStateEncoded];
diff --git a/Limelight/Input/CustomOSC/OnScreenButtonState.h b/Limelight/Input/CustomOSC/OnScreenButtonState.h
index 2394defe..13b44d90 100644
--- a/Limelight/Input/CustomOSC/OnScreenButtonState.h
+++ b/Limelight/Input/CustomOSC/OnScreenButtonState.h
@@ -25,10 +25,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) BOOL isHidden;
@property (nonatomic, assign) uint8_t buttonType;
@property (nonatomic, assign) NSTimeInterval timestamp;
-@property (nonatomic, assign) CGFloat widthFactor; // for OnScreenButtonView
-@property (nonatomic, assign) CGFloat heightFactor; // for OnScreenButtonView
-@property (nonatomic, assign) CGFloat sensitivityFactor; // for OnScreenButtonView
-@property (nonatomic, assign) CGFloat stickIndicatorXOffset; // for OnScreenButtonView
+@property (nonatomic, assign) CGFloat widthFactor; // for OnScreenWidgetView
+@property (nonatomic, assign) CGFloat heightFactor; // for OnScreenWidgetView
+@property (nonatomic, assign) CGFloat borderWidth; // for OnScreenWidgetView
+@property (nonatomic, assign) CGFloat sensitivityFactor; // for OnScreenWidgetView
+@property (nonatomic, assign) CGFloat stickIndicatorXOffset; // for OnScreenWidgetView
@property (nonatomic, assign) CGFloat oscLayerSizeFactor; // for OnScreenController CALayer
@property (nonatomic, assign) CGFloat backgroundAlpha; // for OnScreenController CALayer
@@ -36,8 +37,8 @@ NS_ASSUME_NONNULL_BEGIN
// @property (nonatomic, assign) BOOL hasValidPosition;
typedef NS_ENUM(NSInteger, OnScreenButtonType) {
- GameControllerButton,
- KeyboardOrMouseButton
+ LegacyOscButton,
+ CustomOnScreenWidget
};
- (id) initWithButtonName:(NSString*)name buttonType:(uint8_t)buttonType andPosition:(CGPoint)position;
diff --git a/Limelight/Input/CustomOSC/OnScreenButtonState.m b/Limelight/Input/CustomOSC/OnScreenButtonState.m
index 71f1419f..0bf89321 100644
--- a/Limelight/Input/CustomOSC/OnScreenButtonState.m
+++ b/Limelight/Input/CustomOSC/OnScreenButtonState.m
@@ -39,6 +39,7 @@
[encoder encodeFloat:self.stickIndicatorXOffset forKey:@"stickIndicatorOffset"];
[encoder encodeFloat:self.oscLayerSizeFactor forKey:@"oscLayerSizeFactor"];
[encoder encodeFloat:self.backgroundAlpha forKey:@"backgroundAlpha"];
+ [encoder encodeFloat:self.borderWidth forKey:@"borderWidth"];
}
- (id) initWithCoder:(NSCoder*)decoder {
@@ -55,6 +56,7 @@
self.stickIndicatorXOffset = [decoder decodeFloatForKey:@"stickIndicatorOffset"];
self.oscLayerSizeFactor = [decoder decodeFloatForKey:@"oscLayerSizeFactor"];
self.backgroundAlpha = [decoder decodeFloatForKey:@"backgroundAlpha"];
+ self.borderWidth = [decoder decodeFloatForKey:@"borderWidth"];
}
return self;
}
diff --git a/Limelight/Input/CustomTapGestureRecognizer.m b/Limelight/Input/CustomTapGestureRecognizer.m
index a55fed85..9e27ef64 100644
--- a/Limelight/Input/CustomTapGestureRecognizer.m
+++ b/Limelight/Input/CustomTapGestureRecognizer.m
@@ -74,7 +74,7 @@ static CGFloat screenWidthInPoints;
_gestureCaptured = false;
self.state = UIGestureRecognizerStateFailed;
}
- else if(_gestureCaptured && allTouchesCount == [touches count] && !_isOnScreenControllerBeingPressed && ![self isOnScreenButtonViewBeingPressed]){ //must exclude virtual controller & onscreen button taps here to prevent stucked button, _areVirtualControllerTaps flag is set by onscreencontrols, containOnScreenButtonsTaps will be returned by iterating all button views in streamframeview
+ else if(_gestureCaptured && allTouchesCount == [touches count] && !_isOnScreenControllerBeingPressed && ![self isOnScreenWidgetViewBeingPressed]){ //must exclude virtual controller & onscreen button taps here to prevent stucked button, _areVirtualControllerTaps flag is set by onscreencontrols, containOnScreenButtonsTaps will be returned by iterating all widget views in streamframeview
_gestureCaptured = false; //reset for next recognition
if((CACurrentMediaTime() - _gestureCapturedTime) < _tapDownTimeThreshold){
lowestTouchPointYCoord = 0.0; //reset for next recognition
@@ -85,28 +85,28 @@ static CGFloat screenWidthInPoints;
}
-// it was a not a perfect choice to code OnScreenButtonView in Swift...
+// it was a not a perfect choice to code OnScreenWidgetView in Swift...
// we're unable to import this class to swift codebase by the bridging header,and have to exlucde the onscreen button taps here
-// by iterating every button view instances. but it's basically ok since the number of buttonViews are always limited.
+// by iterating every widget view instances. but it's basically ok since the number of widgetViews are always limited.
// and this method will only be called when the recognizer is active & and the taps passes all the checks and is about to ge triggered.
-- (bool)isOnScreenButtonViewBeingPressed {
- NSTimeInterval allFingersTapDownTime = CACurrentMediaTime() - _gestureCapturedTime; //RIGHTCLICK_TAP_DOWN_TIME_THRESHOLD_S has been passed to this recognizer as _tapDownTimeShreshold, we'll decide how to deal with pressed flag of on-screen button views based on tapDownTime
- bool gotOneButtonPressed = false;
- // the tap gestures are all added to the streamFrameTopLayerView, where all the onScreenButtonViews are added. so we can iterate them in this way:
+- (bool)isOnScreenWidgetViewBeingPressed {
+ NSTimeInterval allFingersTapDownTime = CACurrentMediaTime() - _gestureCapturedTime; //RIGHTCLICK_TAP_DOWN_TIME_THRESHOLD_S has been passed to this recognizer as _tapDownTimeShreshold, we'll decide how to deal with pressed flag of on-screen widget views based on tapDownTime
+ bool gotOneWidgetPressed = false;
+ // the tap gestures are all added to the streamFrameTopLayerView, where all the OnScreenWidgetViews are added. so we can iterate them in this way:
for(UIView* view in self.view.subviews){
- if ([view isKindOfClass:[OnScreenButtonView class]]) {
- OnScreenButtonView* buttonView = (OnScreenButtonView*) view;
- if(gotOneButtonPressed && allFingersTapDownTime <= _tapDownTimeThreshold){ // once we have just 1 button pressed already,& the tapDownTime has not exceeded the threshold, we'll reset pressed flag for the all the buttonViews.
- buttonView.pressed = false; //reset the flag for buttonView
+ if ([view isKindOfClass:[OnScreenWidgetView class]]) {
+ OnScreenWidgetView* widgetView = (OnScreenWidgetView*) view;
+ if(gotOneWidgetPressed && allFingersTapDownTime <= _tapDownTimeThreshold){ // once we have just 1 button pressed already,& the tapDownTime has not exceeded the threshold, we'll reset pressed flag for the all the widgetViews.
+ widgetView.pressed = false; //reset the flag for widgetView
continue;
}
- if(buttonView.pressed){
- gotOneButtonPressed = true; //got one button pressed
- if(allFingersTapDownTime <= _tapDownTimeThreshold) buttonView.pressed = false; // reset the flag for current buttonView if tapDowntime is still within the threshold, if not, leave the flag for mouse scroller gesture in relative touch mode.
+ if(widgetView.pressed){
+ gotOneWidgetPressed = true; //got one button pressed
+ if(allFingersTapDownTime <= _tapDownTimeThreshold) widgetView.pressed = false; // reset the flag for current widgetView if tapDowntime is still within the threshold, if not, leave the flag for mouse scroller gesture in relative touch mode.
}
}
}
- return gotOneButtonPressed;
+ return gotOneWidgetPressed;
}
@end
diff --git a/Limelight/Input/OnScreenControls.h b/Limelight/Input/OnScreenControls.h
index 73914977..949a9a8c 100644
--- a/Limelight/Input/OnScreenControls.h
+++ b/Limelight/Input/OnScreenControls.h
@@ -15,7 +15,7 @@
@class ControllerSupport;
@class StreamConfiguration;
-// sending self as an instance to OnScreenButtonView or other related classes
+// sending self as an instance to OnScreenWidgetView or other related classes
@protocol InstanceProviderDelegate
- (void)getOnScreenControlsInstance:(id)sender; // Renamed delegate method
@end
diff --git a/Limelight/Input/OnScreenControls.m b/Limelight/Input/OnScreenControls.m
index 8a17ccb7..8853fc43 100644
--- a/Limelight/Input/OnScreenControls.m
+++ b/Limelight/Input/OnScreenControls.m
@@ -189,7 +189,7 @@ static float L3_Y;
[_controllerSupport updateFinished:_controller];
}
-// sending self as an instance to OnScreenButtonView
+// sending self as an instance to OnScreenWidgetView
- (void)sendInstance{
NSLog(@"OnScreenControls is sending its instance...");
if ([self.delegate respondsToSelector:@selector(getOnScreenControlsInstance:)]) {
@@ -258,7 +258,7 @@ static float L3_Y;
_rightStickBackground = [CALayer layer];
_leftStick = [CALayer layer];
_rightStick = [CALayer layer];
-
+
[self.OSCButtonLayers addObject:_aButton];
[self.OSCButtonLayers addObject:_bButton];
[self.OSCButtonLayers addObject:_xButton];
@@ -362,7 +362,7 @@ static float L3_Y;
for (NSData *buttonStateEncoded in oscProfile.buttonStates) {
OnScreenButtonState *buttonState = [NSKeyedUnarchiver unarchivedObjectOfClass:[OnScreenButtonState class] fromData:buttonStateEncoded error:nil];
- if(!buttonState.isHidden && [validPositionButtonNames containsObject:buttonState.name] && (buttonState.buttonType == GameControllerButton || [profilesManager getIndexOfSelectedProfile] == 0 ) ){
+ if(!buttonState.isHidden && [validPositionButtonNames containsObject:buttonState.name] && (buttonState.buttonType == LegacyOscButton || [profilesManager getIndexOfSelectedProfile] == 0 ) ){
[_activeCustomOscButtonPositionDict setObject:[NSValue valueWithCGPoint:buttonState.position] forKey:buttonState.name]; // we got a buttonname -> position dict here
NSLog(@"_activeCustomOscButtonPositionDict update, button name:%@, position: %f, %f", buttonState.name, buttonState.position.x, buttonState.position.y);
}
@@ -1894,9 +1894,9 @@ static float L3_Y;
// CALayer* superLayer = layer.superlayer;
// if(layerBeingDragged.name == @"")
CGFloat targetAlpha;
-
+ targetAlpha = alpha;
+ if(alpha < 0.23) targetAlpha = 0.23;
if(alpha == 0.0 || alpha == 1.0) targetAlpha = 5.0f/6.0f; // invalid alpha value
- else targetAlpha = alpha;
NSLog(@"alphas: %f",targetAlpha);
diff --git a/Limelight/Input/OnScreenButtonView.swift b/Limelight/Input/OnScreenWidgetView.swift
similarity index 91%
rename from Limelight/Input/OnScreenButtonView.swift
rename to Limelight/Input/OnScreenWidgetView.swift
index 12519898..c1d0c42f 100644
--- a/Limelight/Input/OnScreenButtonView.swift
+++ b/Limelight/Input/OnScreenWidgetView.swift
@@ -8,7 +8,7 @@
import UIKit
-@objc class OnScreenButtonView: UIView, InstanceProviderDelegate {
+@objc class OnScreenWidgetView: UIView, InstanceProviderDelegate {
// receiving the OnScreenControls instance from delegate
@objc func getOnScreenControlsInstance(_ sender: Any) {
if let controls = sender as? OnScreenControls {
@@ -27,6 +27,7 @@ import UIKit
@objc public var pressed: Bool
@objc public var widthFactor: CGFloat = 1.0
@objc public var heightFactor: CGFloat = 1.0
+ @objc public var borderWidth: CGFloat = 0.0
@objc public var backgroundAlpha: CGFloat = 0.5
@objc public var latestTouchLocation: CGPoint
@objc public var selfViewOnTheRight: Bool = false
@@ -85,7 +86,7 @@ import UIKit
private var mousePointerMoved: Bool
private var twoTouchesDetected: Bool
- private var storedLocation: CGPoint = .zero // location from persisted data
+ private var storedCenter: CGPoint = .zero // location from persisted data
private let minimumBorderAlpha: CGFloat = 0.19
private var defaultBorderColor: CGColor = UIColor(white: 0.2, alpha: 0.3).cgColor
private let moonlightPurple: CGColor = UIColor(red: 0.5, green: 0.5, blue: 1.0, alpha: 0.86).cgColor
@@ -142,28 +143,39 @@ import UIKit
}
@objc public func setLocation(xOffset:CGFloat, yOffset:CGFloat) {
+ /*
NSLayoutConstraint.activate([
- self.leadingAnchor.constraint(equalTo: self.superview!.leadingAnchor, constant: xOffset),
- self.topAnchor.constraint(equalTo: self.superview!.topAnchor, constant: yOffset),
+ self.centerXAnchor.constraint(equalTo: self.superview!.leadingAnchor, constant: xOffset),
+ self.centerYAnchor.constraint(equalTo: self.superview!.topAnchor, constant: yOffset),
])
- storedLocation = CGPointMake(xOffset, yOffset)
+ */
+ storedCenter = CGPointMake(xOffset, yOffset)
+ center = storedCenter
}
@objc public func enableRelocationMode(enabled: Bool){
- OnScreenButtonView.editMode = enabled
+ OnScreenWidgetView.editMode = enabled
}
- @objc public func adjustButtonTransparency(alpha: CGFloat){
+ @objc public func adjustTransparency(alpha: CGFloat){
if alpha != 0 {
self.backgroundAlpha = alpha
}
else{
- self.backgroundAlpha = 0.5
+ // self.backgroundAlpha = 0.5
+ self.backgroundAlpha = alpha
}
self.tweakAlpha()
}
- @objc public func resizeButtonView(){
+ @objc public func adjustBorder(width: CGFloat){
+ self.borderWidth = width
+ // self.layer.borderWidth = borderWidth
+ // if CommandManager.touchPadCmds.contains(self.keyString) && width == 0 {self.layer.borderWidth = 1}
+ setupView()
+ }
+
+ @objc public func resizeWidgetView(){
guard let superview = superview else { return }
@@ -172,20 +184,26 @@ import UIKit
// To resize the button, we must set this to false temporarily
translatesAutoresizingMaskIntoConstraints = false
-
-
+
// replace invalid factor values
if self.widthFactor == 0 {self.widthFactor = 1.0}
if self.heightFactor == 0 {self.heightFactor = 1.0}
- // Constraints for resizing
+
+ /*
+ NSLayoutConstraint.activate([
+ self.centerXAnchor.constraint(equalTo: self.superview!.leadingAnchor, constant: storedLocation.x),
+ self.centerYAnchor.constraint(equalTo: self.superview!.topAnchor, constant: storedLocation.y)])
+ */
+
+ // Constraints for resizing
self.changeAndActivateContraints()
// Trigger layout update
superview.layoutIfNeeded()
- // Re-setup buttonView style
+ // Re-setup widgetView style
setupView()
}
@@ -207,10 +225,13 @@ import UIKit
}
private func changeAndActivateContraints(){
- if CommandManager.oscButtonMappings.keys.contains(self.keyString){ // we'll make custom osc buttons round & smaller
+ if CommandManager.oscButtonMappings.keys.contains(self.keyString) && !CommandManager.oscRectangleButtonCmds.contains(self.keyString){ // we'll make custom osc buttons round & smaller
+
NSLayoutConstraint.activate([
self.widthAnchor.constraint(equalToConstant: 60 * self.widthFactor),
self.heightAnchor.constraint(equalToConstant: 60 * self.heightFactor),])
+
+ // self.frame = CGRectMake(0, 0, 60*self.widthFactor, 60*self.heightFactor)
}
else if CommandManager.touchPadCmds.contains(self.keyString) { // make touchPads larger
NSLayoutConstraint.activate([
@@ -222,6 +243,7 @@ import UIKit
self.widthAnchor.constraint(equalToConstant: 70 * self.widthFactor),
self.heightAnchor.constraint(equalToConstant: 65 * self.heightFactor),])
}
+
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10), // set up label size contrain within UIView
label.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -10),
@@ -244,21 +266,23 @@ import UIKit
self.translatesAutoresizingMaskIntoConstraints = true // this is mandatory to prevent unexpected key view location change
- self.layer.cornerRadius = 20
- self.layer.borderWidth = 1
+ self.layer.cornerRadius = 16
+ self.layer.borderWidth = self.borderWidth
self.tweakAlpha()
- if CommandManager.oscButtonMappings.keys.contains(self.keyString){ //make oscButtons round and no border
+ if CommandManager.oscButtonMappings.keys.contains(self.keyString) && !CommandManager.oscRectangleButtonCmds.contains(self.keyString){ //make oscButtons round and no border
self.layer.cornerRadius = self.frame.width/2
- self.layer.borderWidth = 0
+ // self.layer.borderWidth = self.borderWidth
label.minimumScaleFactor = 0.15 // Adjust the scale factor for oscButtons
label.font = UIFont.boldSystemFont(ofSize: 22)
}
if CommandManager.touchPadCmds.contains(self.keyString){
+ if(self.borderWidth < 1) {self.layer.borderWidth = 1}
+ else {self.layer.borderWidth = self.borderWidth}
label.text = "" // make touchPad display no text
- if OnScreenButtonView.editMode { //display label in edit mode to make the pad more visible
+ if OnScreenWidgetView.editMode { //display label in edit mode to make the pad more visible
label.text = self.keyString
}
}
@@ -276,6 +300,8 @@ import UIKit
self.changeAndActivateContraints()
+ center = storedCenter //anchor the center while resizing self
+
setupButtonDownVisualEffectLayer();
}
@@ -312,10 +338,10 @@ import UIKit
// create stick indicator: the crossMark & stickBall:
@objc public func showStickIndicator(){
// tell if the self button is located on the left or right
- self.selfViewOnTheRight = (self.storedLocation.x > self.appWindow.frame.width*0.5)
+ self.selfViewOnTheRight = (self.storedCenter.x > self.appWindow.frame.width*0.5)
let offsetSign = selfViewOnTheRight ? -1 : 1
let stickMarkerRelativeLocation:CGPoint
- if !OnScreenButtonView.editMode {
+ if !OnScreenWidgetView.editMode {
stickMarkerRelativeLocation = CGPointMake(touchBeganLocation.x + CGFloat(offsetSign) * self.stickIndicatorXOffset, touchBeganLocation.y)
}
else{
@@ -384,7 +410,7 @@ import UIKit
CATransaction.begin()
CATransaction.setDisableActions(true)
self.stickBallLayer.removeAllAnimations()
- if !OnScreenButtonView.editMode {
+ if !OnScreenWidgetView.editMode {
self.stickBallLayer.position = CGPointMake(CGRectGetMidX(self.crossMarkLayer.frame) + touchInputToStickBallCoord(input: offSetX*sensitivityFactor), CGRectGetMidY(self.crossMarkLayer.frame) + touchInputToStickBallCoord(input: offSetY*sensitivityFactor))
}
else{
@@ -634,7 +660,10 @@ import UIKit
private func setupButtonDownVisualEffectLayer() {
self.buttonDownVisualEffectWidth = 8.6
- if CommandManager.oscButtonMappings.keys.contains(self.keyString) {self.buttonDownVisualEffectWidth = 15.3} // wider visual effect for osc buttons
+ if CommandManager.oscButtonMappings.keys.contains(self.keyString) && !CommandManager.oscRectangleButtonCmds.contains(self.keyString){
+ if widthFactor < 1.3 {self.buttonDownVisualEffectWidth = 15.3} // wider visual effect for osc buttons
+ else {self.buttonDownVisualEffectWidth = 9}
+ }
// Set the frame to be larger than the view to expand outward
buttonDownVisualEffectLayer.borderWidth = 0 // set this 0 to hide the visual effect first
@@ -683,7 +712,7 @@ import UIKit
self.onScreenControls.sendLeftStickTouchPadEvent(targetX, targetY)
}
//==========================================================================================================
-
+
// Touch event handling
override func touchesBegan(_ touches: Set, with event: UIEvent?) {
@@ -697,18 +726,19 @@ import UIKit
quickDoubleTapDetected = touchTapTimeInterval < QUICK_TAP_TIME_INTERVAL
let touch = touches.first
- self.touchBeganLocation = touch!.location(in: self)
+ if OnScreenWidgetView.editMode {self.touchBeganLocation = touch!.location(in: superview)}
+ else {self.touchBeganLocation = touch!.location(in: self)}
self.latestTouchLocation = touchBeganLocation
}
- let allCapturedTouchesCount = event?.allTouches?.filter({ $0.view == self }).count // this will counts all valid touches within the self buttonView, and excludes touches in other buttonViews
+ let allCapturedTouchesCount = event?.allTouches?.filter({ $0.view == self }).count // this will counts all valid touches within the self widgetView, and excludes touches in other widgetViews
if allCapturedTouchesCount == 2 {
self.twoTouchesDetected = true
}
self.pressed = true
- if !OnScreenButtonView.editMode {
+ if !OnScreenWidgetView.editMode {
if CommandManager.touchPadCmds.contains(self.keyString) && touches.count == 1{ // don't use event?.allTouches?.count here, it will counts all touches including the ones captured by other UIViews
switch self.keyString {
case "LSPAD":
@@ -770,29 +800,37 @@ import UIKit
}
// here is in edit mode:
else{
- NotificationCenter.default.post(name: Notification.Name("OnScreenButtonViewSelected"),object: self) // inform layout tool controller to fetch button size factors. self will be passed as the object of the notification
+ NotificationCenter.default.post(name: Notification.Name("OnScreenWidgetViewSelected"),object: self) // inform layout tool controller to fetch button size factors. self will be passed as the object of the notification
if let touch = touches.first {
let touchLocation = touch.location(in: superview)
- storedLocation = touchLocation
+ storedCenter = touchLocation
}
}
}
private func moveByTouch(touch: UITouch){
- let currentLocation = touch.location(in: superview)
- let offsetX = currentLocation.x - storedLocation.x
- let offsetY = currentLocation.y - storedLocation.y
+ let currentLocation: CGPoint
+ if OnScreenWidgetView.editMode {currentLocation = touch.location(in: superview)}
+ else {currentLocation = touch.location(in: self)}
+
+ let offsetX = currentLocation.x - latestTouchLocation.x
+ let offsetY = currentLocation.y - latestTouchLocation.y
center = CGPoint(x: center.x + offsetX, y: center.y + offsetY)
+ latestTouchLocation = currentLocation
+ // center = currentLocation;
//NSLog("x coord: %f, y coord: %f", self.frame.origin.x, self.frame.origin.y)
- storedLocation = currentLocation // Update initial center for next movement
+ storedCenter = center // Update initial center for next movement
+ if OnScreenWidgetView.editMode {
+ NotificationCenter.default.post(name: Notification.Name("OnScreenWidgetMovedByTouch"), object:self) // inform the layoutOnScreenControl to update guideLines for this widget view
+ }
}
override func touchesMoved(_ touches: Set, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
- OnScreenButtonView.timestampOfButtonBeingDragged = self.timestamp
+ OnScreenWidgetView.timestampOfButtonBeingDragged = self.timestamp
- if !OnScreenButtonView.editMode {
+ if !OnScreenWidgetView.editMode {
if CommandManager.touchPadCmds.contains(self.keyString){
handleTouchPadMoveEvent(touches, with: event)
}
@@ -808,8 +846,8 @@ import UIKit
}
}
- // Move the buttonView based on touch movement in relocation mode
- if OnScreenButtonView.editMode {
+ // Move the widgetView based on touch movement in relocation mode
+ if OnScreenWidgetView.editMode {
if let touch = touches.first {
self.moveByTouch(touch: touch)
}
@@ -858,10 +896,10 @@ import UIKit
if self.keyString != "MOUSEPAD" {quickDoubleTapDetected = false} //do not reset this flag here in mousePad mode
- let allCapturedTouchesCount = event?.allTouches?.filter({ $0.view == self }).count // this will counts all valid touches within the self buttonView, and excludes touches in other buttonViews
+ let allCapturedTouchesCount = event?.allTouches?.filter({ $0.view == self }).count // this will counts all valid touches within the self widgetView, and excludes touches in other widgetViews
// deal with MOUSPAD first
- if !OnScreenButtonView.editMode && self.keyString == "MOUSEPAD" && allCapturedTouchesCount == 1 && !twoTouchesDetected {
+ if !OnScreenWidgetView.editMode && self.keyString == "MOUSEPAD" && allCapturedTouchesCount == 1 && !twoTouchesDetected {
if !mousePointerMoved && !quickDoubleTapDetected {self.sendLongMouseLeftButtonClickEvent()} // deal with single tap(click)
if quickDoubleTapDetected { //deal with quick double tap
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_RELEASE), BUTTON_LEFT) //must release the button anyway, because the button is likely being held down since the long click turned into a dragging event.
@@ -871,14 +909,14 @@ import UIKit
mousePointerMoved = false // reset this flag
}
- if !OnScreenButtonView.editMode && self.keyString == "MOUSEPAD" && twoTouchesDetected && touches.count == allCapturedTouchesCount { // need to enable multi-touch first
+ if !OnScreenWidgetView.editMode && self.keyString == "MOUSEPAD" && twoTouchesDetected && touches.count == allCapturedTouchesCount { // need to enable multi-touch first
// touches.count == allCapturedTouchesCount means allfingers are lifting
self.sendMouseRightButtonClickEvent()
twoTouchesDetected = false
}
// then other types of pads
- if !OnScreenButtonView.editMode && CommandManager.touchPadCmds.contains(self.keyString) {
+ if !OnScreenWidgetView.editMode && CommandManager.touchPadCmds.contains(self.keyString) {
switch self.keyString{
case "LSPAD":
self.onScreenControls.clearLeftStickTouchPadFlag()
@@ -912,7 +950,7 @@ import UIKit
}
}
- if !OnScreenButtonView.editMode && CommandManager.specialOverlayButtonCmds.contains(self.keyString){
+ if !OnScreenWidgetView.editMode && CommandManager.specialOverlayButtonCmds.contains(self.keyString){
if CACurrentMediaTime() - self.touchTapTimeStamp < 0.3 {
switch self.keyString {
case "SETTINGS":
@@ -940,7 +978,7 @@ import UIKit
if self.keyString == "OSCR2" {self.onScreenControls.updateRightTrigger(0x00)}
}
- if !OnScreenButtonView.editMode && !self.keyString.contains("+") { // if the command(keystring contains "+", it's a multi-key command rather than a single key button
+ if !OnScreenWidgetView.editMode && !self.keyString.contains("+") { // if the command(keystring contains "+", it's a multi-key command rather than a single key button
if CommandManager.mouseButtonMappings.keys.contains(self.keyString){
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_RELEASE), Int32(CommandManager.mouseButtonMappings[self.keyString]!))
@@ -950,7 +988,7 @@ import UIKit
}
}
- if OnScreenButtonView.editMode {
+ if OnScreenWidgetView.editMode {
guard let superview = superview else { return }
// Deactivate existing constraints if necessary
@@ -969,7 +1007,7 @@ import UIKit
// Trigger layout update
superview.layoutIfNeeded()
- setupView(); //re-setup buttonView style
+ setupView(); //re-setup widgetView style
if CommandManager.nonVectorStickPads.contains(self.keyString) {
self.crossMarkLayer.removeFromSuperlayer()
diff --git a/Limelight/Input/RelativeTouchHandler.m b/Limelight/Input/RelativeTouchHandler.m
index 9ee6e255..8ab391c4 100644
--- a/Limelight/Input/RelativeTouchHandler.m
+++ b/Limelight/Input/RelativeTouchHandler.m
@@ -91,12 +91,12 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
}
-- (bool)isOnScreenButtonViewBeingPressed {
+- (bool)isOnScreenWidgetViewBeingPressed {
bool gotOneButtonPressed = false;
- for(UIView* view in self->streamView.superview.subviews){ // iterates all on-screen button views in StreamFrameView
- if ([view isKindOfClass:[OnScreenButtonView class]]) {
- OnScreenButtonView* buttonView = (OnScreenButtonView*) view;
- if(buttonView.pressed){
+ for(UIView* view in self->streamView.superview.subviews){ // iterates all on-screen widget views in StreamFrameView
+ if ([view isKindOfClass:[OnScreenWidgetView class]]) {
+ OnScreenWidgetView* widgetView = (OnScreenWidgetView*) view;
+ if(widgetView.pressed){
gotOneButtonPressed = true; //got one button pressed
}
}
@@ -104,11 +104,11 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
return gotOneButtonPressed;
}
-- (void)resetAllPressedFlagsForOnscreenButtonViews {
- for(UIView* view in self->streamView.superview.subviews){ // iterates all on-screen button views in StreamFrameView
- if ([view isKindOfClass:[OnScreenButtonView class]]) {
- OnScreenButtonView* buttonView = (OnScreenButtonView*) view;
- buttonView.pressed = false;
+- (void)resetAllPressedFlagsForOnScreenWidgetViews {
+ for(UIView* view in self->streamView.superview.subviews){ // iterates all on-screen widget views in StreamFrameView
+ if ([view isKindOfClass:[OnScreenWidgetView class]]) {
+ OnScreenWidgetView* widgetView = (OnScreenWidgetView*) view;
+ widgetView.pressed = false;
}
}
}
@@ -146,7 +146,7 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
touchPointSpawnedAtUpperScreenEdge = false; // reset this flag immediately if we get a touch event passing the check above, this fixes irresponsive touch after closing the command tool menu.
- if([[event allTouches] count] == 2 && ![self isOnScreenButtonViewBeingPressed] && ![self isOnScreenControllerBeingPressed:[event allTouches]]){
+ if([[event allTouches] count] == 2 && ![self isOnScreenWidgetViewBeingPressed] && ![self isOnScreenControllerBeingPressed:[event allTouches]]){
NSLog(@"get in scrolling mode");
isInMouseWheelScrollingMode = true;
return; // if we got 2 touches on the blank area, it's gonna be a mouse scroll touch, and must prevent UITtouch object for mouse pointer being captured & locked
@@ -190,7 +190,7 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
//NSLog(@"%f, touchesMoved callback, is scrolling: %d, touches count: %d", CACurrentMediaTime(), isInMouseWheelScrollingMode, (uint32_t)[touches count]);
- if(isInMouseWheelScrollingMode && [[event allTouches] count] == 2 && ![self isOnScreenButtonViewBeingPressed] && ![self isOnScreenControllerBeingPressed:touches]){
+ if(isInMouseWheelScrollingMode && [[event allTouches] count] == 2 && ![self isOnScreenWidgetViewBeingPressed] && ![self isOnScreenControllerBeingPressed:touches]){
NSSet* twoTouches = [event allTouches];
CGPoint firstLocation = [[[twoTouches allObjects] objectAtIndex:0] locationInView:streamView];
CGPoint secondLocation = [[[twoTouches allObjects] objectAtIndex:1] locationInView:streamView];
@@ -237,7 +237,7 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
isInMouseWheelScrollingMode = false;
touchLockedForMouseMove = nil;
mousePointerMoved = false; // need to reset this anyway
- [self resetAllPressedFlagsForOnscreenButtonViews]; // reset all pressed flag for on-screen button views after all fingers lifted from screen.
+ [self resetAllPressedFlagsForOnScreenWidgetViews]; // reset all pressed flag for on-screen widget views after all fingers lifted from screen.
touchPointSpawnedAtUpperScreenEdge = false;
}
}
diff --git a/Limelight/Input/StreamView.h b/Limelight/Input/StreamView.h
index 8b8709d2..c32bca5e 100644
--- a/Limelight/Input/StreamView.h
+++ b/Limelight/Input/StreamView.h
@@ -43,7 +43,7 @@
- (void) reloadOnScreenControlsWith:(ControllerSupport*)controllerSupport
andConfig:(StreamConfiguration*)streamConfig;
- (void) clearOnScreenKeyboardButtons;
-- (void) reloadOnScreenButtonViews;
+- (void) reloadOnScreenWidgetViews;
- (CGSize) getVideoAreaSize;
- (CGPoint) adjustCoordinatesForVideoArea:(CGPoint)point;
diff --git a/Limelight/Input/StreamView.m b/Limelight/Input/StreamView.m
index f51f8df2..430e082a 100644
--- a/Limelight/Input/StreamView.m
+++ b/Limelight/Input/StreamView.m
@@ -368,18 +368,18 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
- (void) clearOnScreenKeyboardButtons{
for (UIView *subview in self->streamFrameTopLayerView.subviews) {
// 检查子视图是否是特定类型的实例
- if ([subview isKindOfClass:[OnScreenButtonView class]]) {
+ if ([subview isKindOfClass:[OnScreenWidgetView class]]) {
// 如果是,就添加到将要被移除的数组中
[subview removeFromSuperview];
}
}
}
-- (void) reloadOnScreenButtonViews{
+- (void) reloadOnScreenWidgetViews{
NSLog(@"reload on screen keyboard buttons here");
- // remove all keyboard button views first
+ // remove all keyboard widget views first
[self clearOnScreenKeyboardButtons];
// bool customOscEnabled = [self isOscEnabled] && settings.onscreenControls.intValue == OnScreenControlsLevelCustom;
@@ -389,25 +389,27 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
OSCProfilesManager* profilesManager = [OSCProfilesManager sharedManager];
OSCProfile *oscProfile = [profilesManager getSelectedProfile]; //returns the currently selected OSCProfile
- if(!OnScreenButtonView.editMode){ // in edit mode, keyboard button view will be updated within layoutool view controller.
+ if(!OnScreenWidgetView.editMode){ // in edit mode, keyboard widget view will be updated within layoutool view controller.
for (NSData *buttonStateEncoded in oscProfile.buttonStates) {
OnScreenButtonState* buttonState = [NSKeyedUnarchiver unarchivedObjectOfClass:[OnScreenButtonState class] fromData:buttonStateEncoded error:nil];
- if(buttonState.buttonType == KeyboardOrMouseButton){
- OnScreenButtonView* buttonView = [[OnScreenButtonView alloc] initWithKeyString:buttonState.name keyLabel:buttonState.alias]; //reconstruct buttonView
+ if(buttonState.buttonType == CustomOnScreenWidget){
+ OnScreenWidgetView* widgetView = [[OnScreenWidgetView alloc] initWithKeyString:buttonState.name keyLabel:buttonState.alias]; //reconstruct widgetView
//--------------------------------------------------
- onScreenControls.delegate = buttonView; // connecting onScreenControls to OnScreenButtonView, sending the active instance for touchPad stick control
+ onScreenControls.delegate = widgetView; // connecting onScreenControls to OnScreenWidgetView, sending the active instance for touchPad stick control
[onScreenControls sendInstance];
//--------------------------------------------------
- buttonView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
- buttonView.widthFactor = buttonState.widthFactor;
- buttonView.heightFactor = buttonState.heightFactor;
- buttonView.sensitivityFactor = buttonState.sensitivityFactor;
- buttonView.stickIndicatorXOffset = buttonState.stickIndicatorXOffset;
- // Add the buttonView to the view controller's view
- [self->streamFrameTopLayerView addSubview:buttonView]; // add keyboard button to the stream frame view. must add it to the target view before setting location.
- [buttonView setLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y];
- [buttonView resizeButtonView]; // resize must be called after relocation
- [buttonView adjustButtonTransparencyWithAlpha:buttonState.backgroundAlpha];
+ widgetView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
+ widgetView.widthFactor = buttonState.widthFactor;
+ widgetView.heightFactor = buttonState.heightFactor;
+ widgetView.borderWidth = buttonState.borderWidth;
+ widgetView.sensitivityFactor = buttonState.sensitivityFactor;
+ widgetView.stickIndicatorXOffset = buttonState.stickIndicatorXOffset;
+ // Add the widgetView to the view controller's view
+ [self->streamFrameTopLayerView addSubview:widgetView]; // add keyboard button to the stream frame view. must add it to the target view before setting location.
+ [widgetView setLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y];
+ [widgetView resizeWidgetView]; // resize must be called after relocation
+ [widgetView adjustTransparencyWithAlpha:buttonState.backgroundAlpha];
+ [widgetView adjustBorderWithWidth:buttonState.borderWidth];
}
}
}
diff --git a/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents b/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents
index c6733dac..e716f972 100644
--- a/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents
+++ b/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents
@@ -47,7 +47,8 @@
-
+
+
diff --git a/Limelight/Limelight.xcdatamodeld/Moonlight v1.6.xcdatamodel/contents b/Limelight/Limelight.xcdatamodeld/Moonlight v1.6.xcdatamodel/contents
index 39de9e94..aa610d21 100644
--- a/Limelight/Limelight.xcdatamodeld/Moonlight v1.6.xcdatamodel/contents
+++ b/Limelight/Limelight.xcdatamodeld/Moonlight v1.6.xcdatamodel/contents
@@ -1,5 +1,5 @@
-
+
@@ -31,14 +31,9 @@
-
+
-
-
-
-
-
\ No newline at end of file
diff --git a/Limelight/Limelight.xcdatamodeld/Moonlight v1.7.xcdatamodel/contents b/Limelight/Limelight.xcdatamodeld/Moonlight v1.7.xcdatamodel/contents
index 712c76a7..2f29198e 100644
--- a/Limelight/Limelight.xcdatamodeld/Moonlight v1.7.xcdatamodel/contents
+++ b/Limelight/Limelight.xcdatamodeld/Moonlight v1.7.xcdatamodel/contents
@@ -1,5 +1,5 @@
-
+
@@ -32,15 +32,10 @@
-
+
-
-
-
-
-
\ No newline at end of file
diff --git a/Limelight/Limelight.xcdatamodeld/Moonlight v1.8.xcdatamodel/contents b/Limelight/Limelight.xcdatamodeld/Moonlight v1.8.xcdatamodel/contents
index 19d6d78a..c1d0a1e2 100644
--- a/Limelight/Limelight.xcdatamodeld/Moonlight v1.8.xcdatamodel/contents
+++ b/Limelight/Limelight.xcdatamodeld/Moonlight v1.8.xcdatamodel/contents
@@ -1,5 +1,5 @@
-
+
@@ -32,16 +32,11 @@
-
+
-
-
-
-
-
\ No newline at end of file
diff --git a/Limelight/Limelight.xcdatamodeld/Moonlight v1.9.xcdatamodel/contents b/Limelight/Limelight.xcdatamodeld/Moonlight v1.9.xcdatamodel/contents
index 30a96bc0..33e91c66 100644
--- a/Limelight/Limelight.xcdatamodeld/Moonlight v1.9.xcdatamodel/contents
+++ b/Limelight/Limelight.xcdatamodeld/Moonlight v1.9.xcdatamodel/contents
@@ -1,5 +1,5 @@
-
+
@@ -32,16 +32,11 @@
-
+
-
-
-
-
-
\ No newline at end of file
diff --git a/Limelight/Localization/Localizable.xcstrings b/Limelight/Localization/Localizable.xcstrings
index 74ae4514..39e5d0cd 100644
--- a/Limelight/Localization/Localizable.xcstrings
+++ b/Limelight/Localization/Localizable.xcstrings
@@ -283,6 +283,52 @@
}
}
},
+ "Border Width" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "边界宽度"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "边界宽度"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "边界宽度"
+ }
+ }
+ }
+ },
+ "Border Width: %.2f" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "边界宽度: %.2f"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "边界宽度: %.2f"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "边界宽度: %.2f"
+ }
+ }
+ }
+ },
"Cancel" : {
"extractionState" : "manual",
"localizations" : {
@@ -870,6 +916,29 @@
}
}
},
+ "FPS: %5.2f Network dropped frames: %.2f%% Network latency: %@" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "帧率: %5.2f 网络丢帧: %.2f%% 网络延迟: %@"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "帧率: %5.2f 网络丢帧: %.2f%% 网络延迟: %@"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "帧率: %5.2f 网络丢帧: %.2f%% 网络延迟: %@"
+ }
+ }
+ }
+ },
"Got it!" : {
"extractionState" : "manual",
"localizations" : {
@@ -2660,31 +2729,25 @@
}
}
},
- "Video stream: %dx%d %.2f FPS (Codec: %@)\nFrames dropped by your network connection: %.2f%%\nAverage network latency: %@%@" : {
+ "Video stream: %dx%d %.2f FPS (Codec: %@)\nNetwork dropped frames: %.2f%%\nAverage network latency: %@%@" : {
"extractionState" : "manual",
"localizations" : {
- "en" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "Video stream: %dx%d %.2f FPS (Codec: %@)\nFrames dropped by your network connection: %.2f%%\nAverage network latency: %@%@"
- }
- },
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
- "value" : "视频流: %dx%d %.2f FPS (编码格式: %@)\n网络造成的丢帧: %.2f%%\n平均网络延迟: %@%@"
+ "value" : "视频流: %dx%d %.2f FPS (编解码: %@)\n网络丢帧: %.2f%%\n平均网络延迟: %@%@"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
- "value" : "视频流: %dx%d %.2f FPS (编码格式: %@)\n网络造成的丢帧: %.2f%%\n平均网络延迟: %@%@"
+ "value" : "视频流: %dx%d %.2f FPS (编解码: %@)\n网络丢帧: %.2f%%\n平均网络延迟: %@%@"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
- "value" : "视频流: %dx%d %.2f FPS (编码格式: %@)\n网络造成的丢帧: %.2f%%\n平均网络延迟: %@%@"
+ "value" : "视频流: %dx%d %.2f FPS (编解码: %@)\n网络丢帧: %.2f%%\n平均网络延迟: %@%@"
}
}
}
diff --git a/Limelight/Stream/StreamManager.h b/Limelight/Stream/StreamManager.h
index 277d6fe4..1cef0a45 100644
--- a/Limelight/Stream/StreamManager.h
+++ b/Limelight/Stream/StreamManager.h
@@ -15,6 +15,6 @@
- (void) stopStream;
-- (NSString*) getStatsOverlayText;
+- (NSString*) getStatsOverlayText: (uint16_t) overlayLevel;
@end
diff --git a/Limelight/Stream/StreamManager.m b/Limelight/Stream/StreamManager.m
index a1c39a22..e4ce8c91 100644
--- a/Limelight/Stream/StreamManager.m
+++ b/Limelight/Stream/StreamManager.m
@@ -148,9 +148,11 @@
return TRUE;
}
-- (NSString*) getStatsOverlayText {
+- (NSString*) getStatsOverlayText: (uint16_t) overlayLevel {
video_stats_t stats;
+ // NSLog(@"overlayLevel: %d", overlayLevel);
+
if (!_connection) {
return nil;
}
@@ -169,6 +171,7 @@
}
NSString* hostProcessingString;
+ // overlayLevel 2: detailed
if (stats.framesWithHostProcessingLatency != 0) {
hostProcessingString = [LocalizationHelper localizedStringForKey:@"\nHost processing latency min/max/avg: %.1f/%.1f/%.1f ms",
stats.minHostProcessingLatency / 10.f,
@@ -180,7 +183,7 @@
}
float interval = stats.endTime - stats.startTime;
- return [LocalizationHelper localizedStringForKey:@"Video stream: %dx%d %.2f FPS (Codec: %@)\nFrames dropped by your network connection: %.2f%%\nAverage network latency: %@%@",
+ if(overlayLevel == 2) return [LocalizationHelper localizedStringForKey:@"Video stream: %dx%d %.2f FPS (Codec: %@)\nNetwork dropped frames: %.2f%%\nAverage network latency: %@%@",
_config.width,
_config.height,
stats.totalFrames / interval,
@@ -188,6 +191,10 @@
stats.networkDroppedFrames / interval,
latencyString,
hostProcessingString];
+ else return [LocalizationHelper localizedStringForKey:@"FPS: %5.2f Network dropped frames: %.2f%% Network latency: %@",
+ stats.totalFrames / interval,
+ stats.networkDroppedFrames / interval,
+ latencyString];
}
@end
diff --git a/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.h b/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.h
index 83621485..c5a3a8be 100644
--- a/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.h
+++ b/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.h
@@ -20,10 +20,10 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface LayoutOnScreenControlsViewController : UIViewController
- (void)profileRefresh;
-- (void)reloadOnScreenButtonViews;
+- (void)reloadOnScreenWidgetViews;
@property LayoutOnScreenControls *layoutOSC; // object that contains a view which contains the on screen controller buttons that allows the user to drag and positions each button on the screen using touch
-@property (nonatomic) NSMutableDictionary* onScreenButtonViewsDict;
+@property (nonatomic) NSMutableDictionary* OnScreenWidgetViewsDict;
@property int OSCSegmentSelected;
@@ -42,6 +42,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (strong, nonatomic) IBOutlet UISlider *widgetAlphaSlider;
@property (strong, nonatomic) IBOutlet UISlider *sensitivityFactorSlider;
@property (strong, nonatomic) IBOutlet UISlider *stickIndicatorOffsetSlider;
+@property (strong, nonatomic) IBOutlet UISlider *widgetBorderWidthSlider;
@end
diff --git a/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m b/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m
index c3d8a40e..cb4724c1 100644
--- a/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m
+++ b/Limelight/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m
@@ -22,16 +22,17 @@
@implementation LayoutOnScreenControlsViewController {
BOOL isToolbarHidden;
OSCProfilesManager* profilesManager;
- OnScreenButtonView* selectedButtonView;
+ OnScreenWidgetView* selectedWidgetView;
CALayer* selectedControllerLayer;
CGRect controllerLoadedBounds;
- bool buttonViewSelected;
+ bool widgetViewSelected;
bool controllerLayerSelected;
__weak IBOutlet NSLayoutConstraint *toolbarTopConstraintiPhone;
__weak IBOutlet NSLayoutConstraint *toolbarTopConstraintiPad;
UILabel *widgetSizeSliderLabel;
UILabel *widgetHeightSliderLabel;
UILabel *widgetAlphaSliderLabel;
+ UILabel *widgetBorderWidthSliderLabel;
UILabel *sensitivitySliderLabel;
UILabel *stickIndicatorOffsetSliderLabel;
UILabel *stickIndicatorOffsetExplain;
@@ -46,25 +47,25 @@
- (void) viewWillDisappear:(BOOL)animated{
- OnScreenButtonView.editMode = false;
- for (OnScreenButtonView* buttonView in self.onScreenButtonViewsDict.allValues){
- [buttonView.stickBallLayer removeFromSuperlayer];
- [buttonView.crossMarkLayer removeFromSuperlayer];
+ OnScreenWidgetView.editMode = false;
+ for (OnScreenWidgetView* widgetView in self.OnScreenWidgetViewsDict.allValues){
+ [widgetView.stickBallLayer removeFromSuperlayer];
+ [widgetView.crossMarkLayer removeFromSuperlayer];
}
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] postNotificationName:@"OscLayoutCloseNotification" object:self];
}
-- (void) reloadOnScreenButtonViews {
+- (void) reloadOnScreenWidgetViews {
for (UIView *subview in self.view.subviews) {
// 检查子视图是否是特定类型的实例
- if ([subview isKindOfClass:[OnScreenButtonView class]]) {
+ if ([subview isKindOfClass:[OnScreenWidgetView class]]) {
// 如果是,就添加到将要被移除的数组中
[subview removeFromSuperview];
}
}
- [self.onScreenButtonViewsDict removeAllObjects];
+ [self.OnScreenWidgetViewsDict removeAllObjects];
NSLog(@"reload os Key here");
@@ -72,21 +73,23 @@
OSCProfile *oscProfile = [profilesManager getSelectedProfile]; //returns the currently selected OSCProfile
for (NSData *buttonStateEncoded in oscProfile.buttonStates) {
OnScreenButtonState* buttonState = [NSKeyedUnarchiver unarchivedObjectOfClass:[OnScreenButtonState class] fromData:buttonStateEncoded error:nil];
- if(buttonState.buttonType == KeyboardOrMouseButton){
- OnScreenButtonView* buttonView = [[OnScreenButtonView alloc] initWithKeyString:buttonState.name keyLabel:buttonState.alias]; //reconstruct buttonView
- buttonView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
- buttonView.timestamp = buttonState.timestamp; // will be set as key in in the dict.
- buttonView.widthFactor = buttonState.widthFactor;
- buttonView.heightFactor = buttonState.heightFactor;
- buttonView.sensitivityFactor = buttonState.sensitivityFactor;
- buttonView.stickIndicatorXOffset = buttonState.stickIndicatorXOffset;
- // buttonView.backgroundAlpha = buttonState.backgroundAlpha;
- // Add the buttonView to the view controller's view
- [self.view addSubview:buttonView];
- [buttonView setLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y];
- [buttonView resizeButtonView]; // resize must be called after relocation
- [buttonView adjustButtonTransparencyWithAlpha:buttonState.backgroundAlpha];
- [self.onScreenButtonViewsDict setObject:buttonView forKey:@(buttonView.timestamp)];
+ if(buttonState.buttonType == CustomOnScreenWidget){
+ OnScreenWidgetView* widgetView = [[OnScreenWidgetView alloc] initWithKeyString:buttonState.name keyLabel:buttonState.alias]; //reconstruct widgetView
+ widgetView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
+ widgetView.timestamp = buttonState.timestamp; // will be set as key in in the dict.
+ widgetView.widthFactor = buttonState.widthFactor;
+ widgetView.heightFactor = buttonState.heightFactor;
+ widgetView.borderWidth = buttonState.borderWidth;
+ widgetView.sensitivityFactor = buttonState.sensitivityFactor;
+ widgetView.stickIndicatorXOffset = buttonState.stickIndicatorXOffset;
+ // widgetView.backgroundAlpha = buttonState.backgroundAlpha;
+ // Add the widgetView to the view controller's view
+ [self.view addSubview:widgetView];
+ [widgetView setLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y];
+ [widgetView resizeWidgetView]; // resize must be called after relocation
+ [widgetView adjustTransparencyWithAlpha:buttonState.backgroundAlpha];
+ [widgetView adjustBorderWithWidth:buttonState.borderWidth];
+ [self.OnScreenWidgetViewsDict setObject:widgetView forKey:@(widgetView.timestamp)];
}
}
}
@@ -95,14 +98,15 @@
- (void) viewDidLoad {
[super viewDidLoad];
profilesManager = [OSCProfilesManager sharedManager];
- self.onScreenButtonViewsDict = [[NSMutableDictionary alloc] init]; // will be revised to read persisted data , somewhere else
- [OSCProfilesManager setOnScreenButtonViewsDict:self.onScreenButtonViewsDict]; // pass the keyboard button dict to profiles manager
+ self.OnScreenWidgetViewsDict = [[NSMutableDictionary alloc] init]; // will be revised to read persisted data , somewhere else
+ [OSCProfilesManager setOnScreenWidgetViewsDict:self.OnScreenWidgetViewsDict]; // pass the keyboard button dict to profiles manager
isToolbarHidden = NO; // keeps track if the toolbar is hidden up above the screen so that we know whether to hide or show it when the user taps the toolbar's hide/show button
widgetSizeSliderLabel = [[UILabel alloc] init];
widgetHeightSliderLabel = [[UILabel alloc] init];
widgetAlphaSliderLabel = [[UILabel alloc] init];
+ widgetBorderWidthSliderLabel = [[UILabel alloc] init];
sensitivitySliderLabel = [[UILabel alloc] init];
stickIndicatorOffsetSliderLabel = [[UILabel alloc] init];
stickIndicatorOffsetExplain = [[UILabel alloc] init];
@@ -127,6 +131,7 @@
self.layoutOSC = [[LayoutOnScreenControls alloc] initWithView:self.view controllerSup:nil streamConfig:nil oscLevel:OSCSegmentSelected];
self.layoutOSC._level = OnScreenControlsLevelCustom;
+ self.layoutOSC.layoutToolVC = self;
[self.layoutOSC show]; // draw on screen controls
[self addInnerAnalogSticksToOuterAnalogLayers]; // allows inner and analog sticks to be dragged together around the screen together as one unit which is the expected behavior
@@ -144,13 +149,13 @@
[[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(reloadOnScreenButtonViews)
+ selector:@selector(reloadOnScreenWidgetViews)
name:@"OscLayoutProfileSelctedInTableView" // This is a special notification for reloading the on screen keyboard buttons. which can't be executed by _oscProfilesTableViewController.needToUpdateOscLayoutTVC code block, and has to be triggered by a notification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(buttonViewTapped:)
- name:@"OnScreenButtonViewSelected"
+ selector:@selector(widgetViewTapped:)
+ name:@"OnScreenWidgetViewSelected"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
@@ -190,7 +195,7 @@
- (void) viewDidAppear:(BOOL)animated {
- OnScreenButtonView.editMode = true;
+ OnScreenWidgetView.editMode = true;
[super viewWillAppear:animated];
[self profileRefresh];
}
@@ -354,14 +359,14 @@
if(noValidKeyboardString && noValidMouseButtonString && noValidTouchPadString && noValidOscButtonString && noValidSpecialButtonString) return;
//saving & present the keyboard button:
- OnScreenButtonView* buttonView = [[OnScreenButtonView alloc] initWithKeyString:cmdString keyLabel:keyLabel];
- buttonView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
- buttonView.timestamp = CACurrentMediaTime(); // will be set as key in in the dict.
- [self.onScreenButtonViewsDict setObject:buttonView forKey:@(buttonView.timestamp)];
- // Add the buttonView to the view controller's view
- [self.view addSubview:buttonView];
- [buttonView setLocationWithXOffset:50 yOffset:50];
- [buttonView resizeButtonView];
+ OnScreenWidgetView* widgetView = [[OnScreenWidgetView alloc] initWithKeyString:cmdString keyLabel:keyLabel];
+ widgetView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
+ widgetView.timestamp = CACurrentMediaTime(); // will be set as key in in the dict.
+ [self.OnScreenWidgetViewsDict setObject:widgetView forKey:@(widgetView.timestamp)];
+ // Add the widgetView to the view controller's view
+ [self.view addSubview:widgetView];
+ [widgetView setLocationWithXOffset:50 yOffset:50];
+ [widgetView resizeWidgetView];
}];
[alertController addAction:cancelAction];
[alertController addAction:okAction];
@@ -388,48 +393,50 @@
}
}
-- (void)buttonViewTapped: (NSNotification *)notification{
- // receive the selected buttonView obj passed from the notification
- OnScreenButtonView* buttonView = (OnScreenButtonView* )notification.object;
- self->buttonViewSelected = true;
+- (void)widgetViewTapped: (NSNotification *)notification{
+ // receive the selected widgetView obj passed from the notification
+ OnScreenWidgetView* widgetView = (OnScreenWidgetView* )notification.object;
+ self->widgetViewSelected = true;
self->controllerLayerSelected = false;
- self->selectedButtonView = buttonView;
+ self->selectedWidgetView = widgetView;
// setup slider values
- [self.widgetSizeSlider setValue: self->selectedButtonView.widthFactor];
- [self.widgetHeightSlider setValue: self->selectedButtonView.heightFactor];
- [self.widgetAlphaSlider setValue: self->selectedButtonView.backgroundAlpha];
+ [self.widgetSizeSlider setValue: self->selectedWidgetView.widthFactor];
+ [self.widgetHeightSlider setValue: self->selectedWidgetView.heightFactor];
+ [self.widgetAlphaSlider setValue: self->selectedWidgetView.backgroundAlpha];
+ [self.widgetBorderWidthSlider setValue:self->selectedWidgetView.borderWidth];
NSSet *stickAndMouseTouchpads = [NSSet setWithObjects:@"LSPAD", @"RSPAD", @"LSVPAD", @"RSVPAD", @"MOUSEPAD", nil];
NSSet *nonVectorStickPads = [NSSet setWithObjects:@"LSPAD", @"RSPAD", nil];
- bool showSensitivityFactorSlider = [stickAndMouseTouchpads containsObject:self->selectedButtonView.keyString];
- bool showStickIndicatorOffsetSlider = [nonVectorStickPads containsObject:self->selectedButtonView.keyString];
+ bool showSensitivityFactorSlider = [stickAndMouseTouchpads containsObject:self->selectedWidgetView.keyString];
+ bool showStickIndicatorOffsetSlider = [nonVectorStickPads containsObject:self->selectedWidgetView.keyString];
self.sensitivityFactorSlider.hidden = self->sensitivitySliderLabel.hidden = !showSensitivityFactorSlider;
self.stickIndicatorOffsetSlider.hidden = self->stickIndicatorOffsetExplain.hidden = self->stickIndicatorOffsetSliderLabel.hidden = !showStickIndicatorOffsetSlider;
if(showSensitivityFactorSlider){
- [self.sensitivityFactorSlider setValue:self->selectedButtonView.sensitivityFactor];
- [sensitivitySliderLabel setText:[LocalizationHelper localizedStringForKey:@"Sensitivity: %.2f", self->selectedButtonView.sensitivityFactor]];
+ [self.sensitivityFactorSlider setValue:self->selectedWidgetView.sensitivityFactor];
+ [sensitivitySliderLabel setText:[LocalizationHelper localizedStringForKey:@"Sensitivity: %.2f", self->selectedWidgetView.sensitivityFactor]];
}
if(showStickIndicatorOffsetSlider){
// illustrating the indicator offset,
- [selectedButtonView.stickBallLayer removeFromSuperlayer];
- [selectedButtonView.crossMarkLayer removeFromSuperlayer];
- selectedButtonView.touchBeganLocation = CGPointMake(CGRectGetWidth(selectedButtonView.frame)/2, CGRectGetHeight(selectedButtonView.frame)/4);
- [selectedButtonView showStickIndicator];// this will create the indicator CAShapeLayers
- [self.stickIndicatorOffsetSlider setValue:self->selectedButtonView.stickIndicatorXOffset];
- [stickIndicatorOffsetSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Indicator Offset: %.2f", self->selectedButtonView.stickIndicatorXOffset]];
- [self->selectedButtonView updateStickIndicator];
+ [selectedWidgetView.stickBallLayer removeFromSuperlayer];
+ [selectedWidgetView.crossMarkLayer removeFromSuperlayer];
+ selectedWidgetView.touchBeganLocation = CGPointMake(CGRectGetWidth(selectedWidgetView.frame)/2, CGRectGetHeight(selectedWidgetView.frame)/4);
+ [selectedWidgetView showStickIndicator];// this will create the indicator CAShapeLayers
+ [self.stickIndicatorOffsetSlider setValue:self->selectedWidgetView.stickIndicatorXOffset];
+ [stickIndicatorOffsetSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Indicator Offset: %.2f", self->selectedWidgetView.stickIndicatorXOffset]];
+ [self->selectedWidgetView updateStickIndicator];
}
- [widgetSizeSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Size: %.2f", self->selectedButtonView.widthFactor]];
- [widgetHeightSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Height: %.2f", self->selectedButtonView.heightFactor]];
- [widgetAlphaSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Alpha: %.2f", self->selectedButtonView.backgroundAlpha]];
+ [widgetSizeSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Size: %.2f", self->selectedWidgetView.widthFactor]];
+ [widgetHeightSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Height: %.2f", self->selectedWidgetView.heightFactor]];
+ [widgetAlphaSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Alpha: %.2f", self->selectedWidgetView.backgroundAlpha]];
+ [widgetBorderWidthSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Border Width: %.2f", self->selectedWidgetView.borderWidth]];
}
- (void)setControllerCALayerSliderValues: (NSNotification *)notification{
- // receive the selected buttonView obj passed from the notification
+ // receive the selected widgetView obj passed from the notification
CALayer* controllerLayer = (CALayer* )notification.object;
- self->buttonViewSelected = false;
+ self->widgetViewSelected = false;
self->stickIndicatorOffsetExplain.hidden = true;
self->stickIndicatorOffsetSliderLabel.hidden = true;
self.stickIndicatorOffsetSlider.hidden = true;
@@ -457,11 +464,11 @@
[widgetHeightSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Height: %.2f", self.widgetSizeSlider.value]]; // resizing the whole button
[self.widgetHeightSlider setValue: self.widgetSizeSlider.value];
- if(self->selectedButtonView != nil && self->buttonViewSelected){
- self->selectedButtonView.translatesAutoresizingMaskIntoConstraints = true; // this is mandatory to prevent unexpected key view location change
- // when adjusting width, the buttonView height will be syncronized
- self->selectedButtonView.widthFactor = self->selectedButtonView.heightFactor = self.widgetSizeSlider.value;
- [self->selectedButtonView resizeButtonView];
+ if(self->selectedWidgetView != nil && self->widgetViewSelected){
+ self->selectedWidgetView.translatesAutoresizingMaskIntoConstraints = true; // this is mandatory to prevent unexpected key view location change
+ // when adjusting width, the widgetView height will be syncronized
+ self->selectedWidgetView.widthFactor = self->selectedWidgetView.heightFactor = self.widgetSizeSlider.value;
+ [self->selectedWidgetView resizeWidgetView];
}
if(self->selectedControllerLayer != nil && self->controllerLayerSelected){
[self.layoutOSC resizeControllerLayerWith:self->selectedControllerLayer and:self.widgetSizeSlider.value];
@@ -470,18 +477,18 @@
- (void)widgetHeightSliderMoved{
[widgetHeightSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Height: %.2f", self.widgetHeightSlider.value]];
- if(self->selectedButtonView != nil && self->buttonViewSelected){
- self->selectedButtonView.translatesAutoresizingMaskIntoConstraints = true; // this is mandatory to prevent unexpected key view location change
- if([CommandManager.oscButtonMappings.allKeys containsObject:selectedButtonView.keyString]) return; // don't change custom osc button height
- self->selectedButtonView.heightFactor = self.widgetHeightSlider.value;
- [self->selectedButtonView resizeButtonView];
+ if(self->selectedWidgetView != nil && self->widgetViewSelected){
+ self->selectedWidgetView.translatesAutoresizingMaskIntoConstraints = true; // this is mandatory to prevent unexpected key view location change
+ if([CommandManager.oscButtonMappings.allKeys containsObject:selectedWidgetView.keyString] && ![CommandManager.oscRectangleButtonCmds containsObject:selectedWidgetView.keyString]) return; // don't change custom osc button height, except for dPad buttons which are in rectangle shape
+ self->selectedWidgetView.heightFactor = self.widgetHeightSlider.value;
+ [self->selectedWidgetView resizeWidgetView];
}
}
- (void)widgetAlphaSliderMoved{
[widgetAlphaSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Widget Alpha: %.2f", self.widgetAlphaSlider.value]];
- if(self->selectedButtonView != nil && self->buttonViewSelected){
- [self->selectedButtonView adjustButtonTransparencyWithAlpha:self.widgetAlphaSlider.value];
+ if(self->selectedWidgetView != nil && self->widgetViewSelected){
+ [self->selectedWidgetView adjustTransparencyWithAlpha:self.widgetAlphaSlider.value];
}
if(self->selectedControllerLayer != nil && self->controllerLayerSelected){
@@ -490,24 +497,32 @@
return;
}
+- (void)widgetBorderWidthSliderMoved{
+ [widgetBorderWidthSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Border Width: %.2f", self.widgetBorderWidthSlider.value]];
+ if(self->selectedWidgetView != nil && self->widgetViewSelected){
+ [self->selectedWidgetView adjustBorderWithWidth:self.widgetBorderWidthSlider.value];
+ }
+ return;
+}
+
- (void)sensitivitySliderMoved{
[sensitivitySliderLabel setText:[LocalizationHelper localizedStringForKey:@"Sensitivity: %.2f", self.sensitivityFactorSlider.value]];
- if(self->selectedButtonView != nil && self->buttonViewSelected) self->selectedButtonView.sensitivityFactor = self.sensitivityFactorSlider.value;
+ if(self->selectedWidgetView != nil && self->widgetViewSelected) self->selectedWidgetView.sensitivityFactor = self.sensitivityFactorSlider.value;
return;
}
- (void)stickIndicatorOffsetSliderMoved{
[stickIndicatorOffsetSliderLabel setText:[LocalizationHelper localizedStringForKey:@"Indicator Offset: %.2f", self.stickIndicatorOffsetSlider.value]];
- if(self->selectedButtonView != nil && self->buttonViewSelected){
- self->selectedButtonView.stickIndicatorXOffset = self.stickIndicatorOffsetSlider.value;
- [self->selectedButtonView updateStickIndicator];
+ if(self->selectedWidgetView != nil && self->widgetViewSelected){
+ self->selectedWidgetView.stickIndicatorXOffset = self.stickIndicatorOffsetSlider.value;
+ [self->selectedWidgetView updateStickIndicator];
}
return;
}
- (void)showIndicatorOffset{
- selectedButtonView.touchBeganLocation = CGPointMake(CGRectGetWidth(selectedButtonView.frame)/2, CGRectGetHeight(selectedButtonView.frame)/4);
- [selectedButtonView showStickIndicator];
+ selectedWidgetView.touchBeganLocation = CGPointMake(CGRectGetWidth(selectedWidgetView.frame)/2, CGRectGetHeight(selectedWidgetView.frame)/4);
+ [selectedWidgetView showStickIndicator];
}
- (void)setupProfileLableAndSliders{
@@ -589,6 +604,27 @@
widgetAlphaSliderLabel.hidden = NO;
+ // border Width slider
+ self.widgetBorderWidthSlider.hidden = NO;
+ self.widgetBorderWidthSlider.frame = CGRectMake(CGRectGetMaxX(self.currentProfileLabel.frame)-self.widgetBorderWidthSlider.frame.size.width, self.widgetBorderWidthSlider.frame.origin.y, self.widgetBorderWidthSlider.frame.size.width, self.widgetBorderWidthSlider.frame.size.height);
+
+ [self.widgetBorderWidthSlider addTarget:self action:@selector(widgetBorderWidthSliderMoved) forControlEvents:(UIControlEventValueChanged)];
+ widgetBorderWidthSliderLabel.text = [LocalizationHelper localizedStringForKey:@"Border Width"];
+ widgetBorderWidthSliderLabel.font = [UIFont systemFontOfSize:18];
+ widgetBorderWidthSliderLabel.textColor = [UIColor whiteColor];
+ widgetBorderWidthSliderLabel.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
+ widgetBorderWidthSliderLabel.translatesAutoresizingMaskIntoConstraints = NO; // Disable autoresizing mask for Auto Layout
+ [self.view addSubview:widgetBorderWidthSliderLabel];
+ [NSLayoutConstraint activateConstraints:@[
+ // Position the label to the left of the slider
+ [widgetBorderWidthSliderLabel.trailingAnchor constraintEqualToAnchor:self.widgetBorderWidthSlider.leadingAnchor constant:-10],
+ // Align vertically with the slider
+ [widgetBorderWidthSliderLabel.centerYAnchor constraintEqualToAnchor:self.widgetBorderWidthSlider.centerYAnchor]
+ ]];
+ widgetBorderWidthSliderLabel.hidden = NO;
+
+
+
// sensitivity slider
self.sensitivityFactorSlider.hidden = YES;
self.sensitivityFactorSlider.frame = CGRectMake(sliderXPosition, self.sensitivityFactorSlider.frame.origin.y, self.sensitivityFactorSlider.frame.size.width, self.sensitivityFactorSlider.frame.size.height);
@@ -609,6 +645,7 @@
]];
sensitivitySliderLabel.hidden = self.sensitivityFactorSlider.hidden;
+
// stick indicator offset slider
self.stickIndicatorOffsetSlider.hidden = YES;
self.stickIndicatorOffsetSlider.frame = CGRectMake(sliderXPosition, self.stickIndicatorOffsetSlider.frame.origin.y, self.stickIndicatorOffsetSlider.frame.size.width, self.stickIndicatorOffsetSlider.frame.size.height); // make this label bigger to show some tips
@@ -671,7 +708,7 @@
};
[self.oscProfilesTableViewController profileViewRefresh]; // execute this will make sure OSCLayout is updated from persisted profile, not any cache.
- [self reloadOnScreenButtonViews];
+ [self reloadOnScreenWidgetViews];
// [self presentViewController:vc animated:YES completion:nil];
}
@@ -732,7 +769,9 @@
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
-
+ // for OnScreenWidgets:
+
+
// -------- for OSC buttons
[self.layoutOSC touchesMoved:touches withEvent:event];
if ([self.layoutOSC isLayer:self.layoutOSC.layerBeingDragged
@@ -768,11 +807,11 @@
// removing keyboard buttons objs
UITouch *touch = [touches anyObject]; // Get the first touch in the set
if([self touchWithinTashcanButton:touch]){
- [self.onScreenButtonViewsDict[@(OnScreenButtonView.timestampOfButtonBeingDragged)] removeFromSuperview];
- [self.onScreenButtonViewsDict removeObjectForKey:@(OnScreenButtonView.timestampOfButtonBeingDragged)];
- [selectedButtonView.stickBallLayer removeFromSuperlayer];
- [selectedButtonView.crossMarkLayer removeFromSuperlayer];
- OnScreenButtonView.timestampOfButtonBeingDragged = 0; //reset thie timestamp
+ [self.OnScreenWidgetViewsDict[@(OnScreenWidgetView.timestampOfButtonBeingDragged)] removeFromSuperview];
+ [self.OnScreenWidgetViewsDict removeObjectForKey:@(OnScreenWidgetView.timestampOfButtonBeingDragged)];
+ [selectedWidgetView.stickBallLayer removeFromSuperlayer];
+ [selectedWidgetView.crossMarkLayer removeFromSuperlayer];
+ OnScreenWidgetView.timestampOfButtonBeingDragged = 0; //reset thie timestamp
}
diff --git a/Limelight/ViewControllers/SWRevealViewController.m b/Limelight/ViewControllers/SWRevealViewController.m
index 694c2330..54ed9fe7 100755
--- a/Limelight/ViewControllers/SWRevealViewController.m
+++ b/Limelight/ViewControllers/SWRevealViewController.m
@@ -625,6 +625,7 @@ const int FrontViewPositionNone = 0xff;
- (void)_initDefaultProperties
{
+ _mainFrameIsInHostView = true;
_frontViewPosition = FrontViewPositionLeft;
_rearViewPosition = FrontViewPositionLeft;
_rightViewPosition = FrontViewPositionLeft;
@@ -736,7 +737,6 @@ const int FrontViewPositionNone = 0xff;
// tested on iOS17. this method does not call back on iOS14, runtime orientation limitation not working for iOS14. Probably depends on iOS16 or higher.
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
// Return the supported interface orientations acoordingly
-
if(self.mainFrameIsInHostView){
if([self isIphone]) return UIInterfaceOrientationMaskLandscape; //always try to lock orientaion to landscape in mainFrameView in order to prevent bug.
else return [self getCurrentOrientation]; //always try to lock current orientaion in mainFrameView for iPad in order to prevent bug.
diff --git a/Limelight/ViewControllers/SettingsViewController.m b/Limelight/ViewControllers/SettingsViewController.m
index 4a46a85a..b7151623 100644
--- a/Limelight/ViewControllers/SettingsViewController.m
+++ b/Limelight/ViewControllers/SettingsViewController.m
@@ -452,7 +452,7 @@ BOOL isCustomResolution(CGSize res) {
[self.hdrSelector setSelectedSegmentIndex:currentSettings.enableHdr ? 1 : 0];
}
- [self.statsOverlaySelector setSelectedSegmentIndex:currentSettings.statsOverlay ? 1 : 0];
+ [self.statsOverlaySelector setSelectedSegmentIndex:currentSettings.statsOverlayLevel.intValue];
[self.btMouseSelector setSelectedSegmentIndex:currentSettings.btMouseSupport ? 1 : 0];
[self.optimizeSettingsSelector setSelectedSegmentIndex:currentSettings.optimizeGames ? 1 : 0];
[self.framePacingSelector setSelectedSegmentIndex:currentSettings.useFramePacing ? 1 : 0];
@@ -503,17 +503,17 @@ BOOL isCustomResolution(CGSize res) {
//TouchMode & OSC Related Settings:
// pointer veloc setting, will be enable/disabled by touchMode
- [self.pointerVelocityModeDividerSlider setValue:[self map_SliderValue_fromVelocFactor:currentSettings.pointerVelocityModeDivider.floatValue] animated:YES]; // Load old setting.
+ [self.pointerVelocityModeDividerSlider setValue: (uint8_t)(currentSettings.pointerVelocityModeDivider.floatValue * 100) animated:YES]; // Load old setting.
[self.pointerVelocityModeDividerSlider addTarget:self action:@selector(pointerVelocityModeDividerSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved.
[self pointerVelocityModeDividerSliderMoved];
// init pointer veloc setting, will be enable/disabled by touchMode
- [self.touchPointerVelocityFactorSlider setValue:currentSettings.touchPointerVelocityFactor.floatValue * 100 animated:YES]; // Load old setting.
+ [self.touchPointerVelocityFactorSlider setValue: [self map_SliderValue_fromVelocFactor: currentSettings.touchPointerVelocityFactor.floatValue] animated:YES]; // Load old setting.
[self.touchPointerVelocityFactorSlider addTarget:self action:@selector(touchPointerVelocityFactorSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved.
[self touchPointerVelocityFactorSliderMoved];
// init relative touch mouse pointer veloc setting, will be enable/disabled by touchMode
- [self.mousePointerVelocityFactorSlider setValue:currentSettings.mousePointerVelocityFactor.floatValue * 100 animated:YES]; // Load old setting.
+ [self.mousePointerVelocityFactorSlider setValue:[self map_SliderValue_fromVelocFactor: currentSettings.mousePointerVelocityFactor.floatValue] animated:YES]; // Load old setting.
[self.mousePointerVelocityFactorSlider addTarget:self action:@selector(mousePointerVelocityFactorSliderMoved) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved.
[self mousePointerVelocityFactorSliderMoved];
@@ -687,6 +687,7 @@ BOOL isCustomResolution(CGSize res) {
}
// veloc factor upto 700%
+
- (CGFloat) map_SliderValue_fromVelocFactor:(CGFloat)velocFactor{
CGFloat sliderValue = 0.0f;
if(velocFactor < 2.0f) sliderValue = velocFactor * 100;
@@ -695,7 +696,7 @@ BOOL isCustomResolution(CGSize res) {
}
- (void) mousePointerVelocityFactorSliderMoved {
- [self.mousePointerVelocityFactorUILabel setText:[LocalizationHelper localizedStringForKey: @"Mouse Pointer Velocity: %d%%", (uint16_t)self.mousePointerVelocityFactorSlider.value]]; // Update label display
+ [self.mousePointerVelocityFactorUILabel setText:[LocalizationHelper localizedStringForKey: @"Mouse Pointer Velocity: %d%%", [self map_velocFactorDisplay_fromSliderValue: self.mousePointerVelocityFactorSlider.value]]]; // Update label display
}
- (uint32_t) getScreenEdgeFromSelector {
@@ -1046,8 +1047,10 @@ BOOL isCustomResolution(CGSize res) {
CGFloat slideToSettingsDistance = self.slideToMenuDistanceSlider.value;
uint32_t slideToSettingsScreenEdge = [self getScreenEdgeFromSelector];
CGFloat pointerVelocityModeDivider = (CGFloat)(uint8_t)self.pointerVelocityModeDividerSlider.value/100;
- CGFloat touchPointerVelocityFactor =(CGFloat)(uint16_t)[self map_velocFactorDisplay_fromSliderValue:self.touchPointerVelocityFactorSlider.value]/100;
- CGFloat mousePointerVelocityFactor =(CGFloat)(uint16_t)self.mousePointerVelocityFactorSlider.value/100;
+ CGFloat touchPointerVelocityFactor = (CGFloat)(uint16_t)[self map_velocFactorDisplay_fromSliderValue:self.touchPointerVelocityFactorSlider.value]/100;
+ CGFloat mousePointerVelocityFactor = (CGFloat)(uint16_t)[self map_velocFactorDisplay_fromSliderValue:self.mousePointerVelocityFactorSlider.value]/100;
+
+ // CGFloat mousePointerVelocityFactor =(CGFloat)(uint16_t)self.mousePointerVelocityFactorSlider.value/100;
CGFloat oscTapExlusionAreaSize =(CGFloat)(uint16_t)self.oscTapExlusionAreaSizeSlider.value/100;
BOOL reverseMouseWheelDirection = [self.reverseMouseWheelDirectionSelector selectedSegmentIndex] == 1;
@@ -1063,7 +1066,8 @@ BOOL isCustomResolution(CGSize res) {
BOOL useFramePacing = [self.framePacingSelector selectedSegmentIndex] == 1;
// BOOL absoluteTouchMode = [self.touchModeSelector selectedSegmentIndex] == 1;
NSInteger touchMode = [self.touchModeSelector selectedSegmentIndex];
- BOOL statsOverlay = [self.statsOverlaySelector selectedSegmentIndex] == 1;
+ NSInteger statsOverlayLevel = [self.statsOverlaySelector selectedSegmentIndex];
+ BOOL statsOverlayEnabled = statsOverlayLevel != 0;
BOOL enableHdr = [self.hdrSelector selectedSegmentIndex] == 1;
BOOL unlockDisplayOrientation = [self.unlockDisplayOrientationSelector selectedSegmentIndex] == 1;
NSInteger resolutionSelected = [self.resolutionSelector selectedSegmentIndex];
@@ -1097,7 +1101,8 @@ BOOL isCustomResolution(CGSize res) {
btMouseSupport:btMouseSupport
// absoluteTouchMode:absoluteTouchMode
touchMode:touchMode
- statsOverlay:statsOverlay
+ statsOverlayLevel:statsOverlayLevel
+ statsOverlayEnabled:statsOverlayEnabled
unlockDisplayOrientation:unlockDisplayOrientation
resolutionSelected:resolutionSelected
externalDisplayMode:externalDisplayMode
diff --git a/Limelight/ViewControllers/StreamFrameViewController.m b/Limelight/ViewControllers/StreamFrameViewController.m
index fca44e3a..f7277533 100644
--- a/Limelight/ViewControllers/StreamFrameViewController.m
+++ b/Limelight/ViewControllers/StreamFrameViewController.m
@@ -47,6 +47,7 @@
UITapGestureRecognizer *_menuDoubleTapGestureRecognizer;
UITapGestureRecognizer *_playPauseTapGestureRecognizer;
UITextView *_overlayView;
+ uint16_t overlayLevel;
UILabel *_stageLabel;
UILabel *_tipLabel;
UIActivityIndicatorView *_spinner;
@@ -58,7 +59,7 @@
UIView *_streamVideoRenderView;
/*
* View architecture of this viewController:
- * self.view (named `streamFrameTopLayerView` in StreamView.m, where slide & tap gestures, and onScreenControls & onScreenButtonView buttons are registered)
+ * self.view (named `streamFrameTopLayerView` in StreamView.m, where slide & tap gestures, and onScreenControls & OnScreenWidgetView buttons are registered)
* - streamView (where touchHandlers are registered)
* - streamVideoRenderView (where stream view is rendered)
*/
@@ -160,6 +161,7 @@
}
_settings = [[[DataManager alloc] init] getSettings]; //StreamFrameViewController retrieve the settings here.
+ overlayLevel = _settings.statsOverlayLevel.intValue;
[self configOscLayoutTool];
[self configSwipeGestures];
[self configZoomGestureAndAddStreamView];
@@ -171,7 +173,7 @@
// we got self.view passed to streamView class as the topLayerView, will be useful in many cases
[self->_streamView reloadOnScreenControlsRealtimeWith:(ControllerSupport*)_controllerSupport
andConfig:(StreamConfiguration*)_streamConfig]; //reload OSC here.
- [self->_streamView reloadOnScreenButtonViews]; //reload keyboard buttons here. the keyboard button view will be added to the streamframe view instead streamview, the highest layer, which saves a lot of reengineering
+ [self->_streamView reloadOnScreenWidgetViews]; //reload keyboard buttons here. the keyboard widget view will be added to the streamframe view instead streamview, the highest layer, which saves a lot of reengineering
[self reloadAirPlayConfig];
[self mousePresenceChanged];
@@ -180,7 +182,7 @@
target:self
selector:@selector(updateStatsOverlay)
userInfo:nil
- repeats:_settings.statsOverlay];
+ repeats:_settings.statsOverlayEnabled];
NSLog(@"frameview gestures: %d", (uint32_t)[self.view.gestureRecognizers count]);
NSLog(@"streamview gestures: %d", (uint32_t)[_streamView.gestureRecognizers count]);
@@ -400,7 +402,7 @@
[self->_streamView reloadOnScreenControlsWith:(ControllerSupport*)_controllerSupport
andConfig:(StreamConfiguration*)_streamConfig];
[self->_streamView showOnScreenControls];
- [self->_streamView reloadOnScreenButtonViews]; //update keyboard buttons here
+ [self->_streamView reloadOnScreenWidgetViews]; //update keyboard buttons here
}
@@ -447,13 +449,13 @@
#endif
- (void)updateStatsOverlay {
- if(!_settings.statsOverlay){
+ if(!_settings.statsOverlayEnabled){
[_overlayView removeFromSuperview];
return; // add this for realtime streamview reconfig
}
else [self.view addSubview:_overlayView]; // don't know why but this is necessary for reactivating overlay.
- NSString* overlayText = [self->_streamMan getStatsOverlayText];
+ NSString* overlayText = [self->_streamMan getStatsOverlayText:overlayLevel];
dispatch_async(dispatch_get_main_queue(), ^{
[self updateOverlayText:overlayText];
});
@@ -479,7 +481,13 @@
#if TARGET_OS_TV
[_overlayView setFont:[UIFont systemFontOfSize:24]];
#else
- [_overlayView setFont:[UIFont systemFontOfSize:12]];
+ if (@available(iOS 13.0, *)) {
+ [_overlayView setFont:[UIFont monospacedSystemFontOfSize:12 weight:UIFontWeightRegular]];
+ } else {
+ [_overlayView setFont:[UIFont systemFontOfSize:12]];// Fallback on earlier versions
+ }
+ //[_overlayView setFont:[UIFont fontWithName:@"Menlo" size:12]];
+
#endif
[_overlayView setAlpha:0.5];
[self.view addSubview:_overlayView];
@@ -675,7 +683,7 @@
[self->_controllerSupport connectionEstablished];
- if (self->_settings.statsOverlay) {
+ if (self->_settings.statsOverlayEnabled) {
self->_statsUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(updateStatsOverlay)
@@ -976,7 +984,7 @@
DataManager* dataMan = [[DataManager alloc] init];
Settings *currentSettings = [dataMan retrieveSettings];
- currentSettings.statsOverlay = !currentSettings.statsOverlay;
+ currentSettings.statsOverlayEnabled = !currentSettings.statsOverlayEnabled;
[dataMan saveData];
[self reConfigStreamViewRealtime];
diff --git a/Limelight/mul.lproj/iPad.xcstrings b/Limelight/mul.lproj/iPad.xcstrings
index fc16b19c..00cff39c 100644
--- a/Limelight/mul.lproj/iPad.xcstrings
+++ b/Limelight/mul.lproj/iPad.xcstrings
@@ -1718,61 +1718,91 @@
}
},
"NLH-qN-qCo.segmentTitles[0]" : {
- "comment" : "Class = \"UISegmentedControl\"; NLH-qN-qCo.segmentTitles[0] = \"No\"; ObjectID = \"NLH-qN-qCo\";",
+ "comment" : "Class = \"UISegmentedControl\"; NLH-qN-qCo.segmentTitles[0] = \"Off\"; ObjectID = \"NLH-qN-qCo\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
- "value" : "No"
+ "value" : "Off"
}
},
"zh-Hans" : {
"stringUnit" : {
- "state" : "translated",
+ "state" : "needs_review",
"value" : "关闭"
}
},
"zh-Hant" : {
"stringUnit" : {
- "state" : "translated",
+ "state" : "needs_review",
"value" : "关闭"
}
},
"zh-HK" : {
"stringUnit" : {
- "state" : "translated",
+ "state" : "needs_review",
"value" : "关闭"
}
}
}
},
"NLH-qN-qCo.segmentTitles[1]" : {
- "comment" : "Class = \"UISegmentedControl\"; NLH-qN-qCo.segmentTitles[1] = \"Yes\"; ObjectID = \"NLH-qN-qCo\";",
+ "comment" : "Class = \"UISegmentedControl\"; NLH-qN-qCo.segmentTitles[1] = \"Simplified\"; ObjectID = \"NLH-qN-qCo\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
- "value" : "Yes"
+ "value" : "Simplified"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
- "value" : "启用"
+ "value" : "精简"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
- "value" : "启用"
+ "value" : "精简"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
- "value" : "启用"
+ "value" : "精简"
+ }
+ }
+ }
+ },
+ "NLH-qN-qCo.segmentTitles[2]" : {
+ "comment" : "Class = \"UISegmentedControl\"; NLH-qN-qCo.segmentTitles[2] = \"Detailed\"; ObjectID = \"NLH-qN-qCo\";",
+ "extractionState" : "extracted_with_value",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Detailed"
+ }
+ },
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "完整"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "完整"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "完整"
}
}
}
diff --git a/Limelight/mul.lproj/iPhone.xcstrings b/Limelight/mul.lproj/iPhone.xcstrings
index 17c9efd7..28cdd79b 100644
--- a/Limelight/mul.lproj/iPhone.xcstrings
+++ b/Limelight/mul.lproj/iPhone.xcstrings
@@ -1940,61 +1940,91 @@
}
},
"rdz-eg-2oR.segmentTitles[0]" : {
- "comment" : "Class = \"UISegmentedControl\"; rdz-eg-2oR.segmentTitles[0] = \"No\"; ObjectID = \"rdz-eg-2oR\";",
+ "comment" : "Class = \"UISegmentedControl\"; rdz-eg-2oR.segmentTitles[0] = \"Off\"; ObjectID = \"rdz-eg-2oR\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
- "value" : "No"
+ "value" : "Off"
}
},
"zh-Hans" : {
"stringUnit" : {
- "state" : "translated",
+ "state" : "needs_review",
"value" : "关闭"
}
},
"zh-Hant" : {
"stringUnit" : {
- "state" : "translated",
+ "state" : "needs_review",
"value" : "关闭"
}
},
"zh-HK" : {
"stringUnit" : {
- "state" : "translated",
+ "state" : "needs_review",
"value" : "关闭"
}
}
}
},
"rdz-eg-2oR.segmentTitles[1]" : {
- "comment" : "Class = \"UISegmentedControl\"; rdz-eg-2oR.segmentTitles[1] = \"Yes\"; ObjectID = \"rdz-eg-2oR\";",
+ "comment" : "Class = \"UISegmentedControl\"; rdz-eg-2oR.segmentTitles[1] = \"Simplified\"; ObjectID = \"rdz-eg-2oR\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
- "value" : "Yes"
+ "value" : "Simplified"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
- "value" : "启用"
+ "value" : "精简"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
- "value" : "启用"
+ "value" : "精简"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
- "value" : "启用"
+ "value" : "精简"
+ }
+ }
+ }
+ },
+ "rdz-eg-2oR.segmentTitles[2]" : {
+ "comment" : "Class = \"UISegmentedControl\"; rdz-eg-2oR.segmentTitles[2] = \"Detailed\"; ObjectID = \"rdz-eg-2oR\";",
+ "extractionState" : "extracted_with_value",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Detailed"
+ }
+ },
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "完整"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "完整"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "完整"
}
}
}
diff --git a/Moonlight.xcodeproj/project.pbxproj b/Moonlight.xcodeproj/project.pbxproj
index 22ab7a13..ec96a55d 100644
--- a/Moonlight.xcodeproj/project.pbxproj
+++ b/Moonlight.xcodeproj/project.pbxproj
@@ -8,7 +8,7 @@
/* Begin PBXBuildFile section */
840751B32BF49C050096B657 /* CustomTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */; };
- 84203F232C5F24C00032EEED /* OnScreenButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84203F222C5F24C00032EEED /* OnScreenButtonView.swift */; };
+ 84203F232C5F24C00032EEED /* OnScreenWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84203F222C5F24C00032EEED /* OnScreenWidgetView.swift */; };
84351B0E2C29ACCB00A77989 /* LayoutOnScreenControls.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B072C29ACCA00A77989 /* LayoutOnScreenControls.m */; };
84351B0F2C29ACCB00A77989 /* OnScreenButtonState.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B092C29ACCA00A77989 /* OnScreenButtonState.m */; };
84351B102C29ACCB00A77989 /* OSCProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 84351B0A2C29ACCA00A77989 /* OSCProfile.m */; };
@@ -127,7 +127,7 @@
693B3A9A218638CD00982F7B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; };
840751B12BF49B5A0096B657 /* CustomTapGestureRecognizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomTapGestureRecognizer.h; sourceTree = ""; };
840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomTapGestureRecognizer.m; sourceTree = ""; };
- 84203F222C5F24C00032EEED /* OnScreenButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnScreenButtonView.swift; sourceTree = ""; };
+ 84203F222C5F24C00032EEED /* OnScreenWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnScreenWidgetView.swift; sourceTree = ""; };
84351B062C29ACCA00A77989 /* OnScreenButtonState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OnScreenButtonState.h; sourceTree = ""; };
84351B072C29ACCA00A77989 /* LayoutOnScreenControls.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LayoutOnScreenControls.m; sourceTree = ""; };
84351B082C29ACCA00A77989 /* OSCProfilesManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSCProfilesManager.h; sourceTree = ""; };
@@ -630,7 +630,7 @@
988FCD3F293B091B003050E2 /* KeyboardInputField.h */,
988FCD40293B091B003050E2 /* KeyboardInputField.m */,
84E1CDEB2C4F67D300547904 /* CommandManager.swift */,
- 84203F222C5F24C00032EEED /* OnScreenButtonView.swift */,
+ 84203F222C5F24C00032EEED /* OnScreenWidgetView.swift */,
);
path = Input;
sourceTree = "";
@@ -1036,7 +1036,7 @@
FBDE86E019F7A837001C18A8 /* UIComputerView.m in Sources */,
FB89463019F646E200339C8A /* StreamConfiguration.m in Sources */,
FBD3495319FF36FB002D2A60 /* SWRevealViewController.m in Sources */,
- 84203F232C5F24C00032EEED /* OnScreenButtonView.swift in Sources */,
+ 84203F232C5F24C00032EEED /* OnScreenWidgetView.swift in Sources */,
84FD0B512C31338D006B5BE5 /* LocalizationHelper.m in Sources */,
FB1D59971BBCCB6400F482CA /* ComputerScrollView.m in Sources */,
FBD3495019FF2174002D2A60 /* SettingsViewController.m in Sources */,