- on-screen button & on-screen controller resize test
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES" initialViewController="EVd-wq-ego">
|
||||
<device id="ipad11_0rounded" orientation="portrait" layout="fullscreen" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
@@ -12,7 +11,7 @@
|
||||
<objects>
|
||||
<viewController id="wb7-af-jn8" customClass="MainFrameViewController" sceneMemberID="viewController">
|
||||
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" indicatorStyle="black" dataMode="prototypes" id="TZj-Lc-M9d" customClass="AppCollectionView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="834" height="1120"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="834" height="1194"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="0.3333333432674408" green="0.3333333432674408" blue="0.3333333432674408" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="f7l-kG-hJc">
|
||||
@@ -830,7 +829,7 @@ ICAgICAgICAgICAgICA
|
||||
</constraints>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Current Profile:" textAlignment="center" lineBreakMode="tailTruncation" adjustsFontSizeToFit="NO" id="cRV-Xw-CVi">
|
||||
<rect key="frame" x="207" y="128" width="420" height="54"/>
|
||||
<rect key="frame" x="207" y="109" width="420" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="0.38551661729999998" green="0.28289704380000003" blue="0.61853601300000005" alpha="0.28999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
@@ -838,6 +837,18 @@ ICAgICAgICAgICAgICA
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="100" minValue="60" maxValue="390" id="Efn-Si-TPp" userLabel="Button Width Slider">
|
||||
<rect key="frame" x="205" y="172" width="420" height="31"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
|
||||
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</slider>
|
||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="100" minValue="60" maxValue="390" id="ZOF-sL-e7p" userLabel="Button Height Slider">
|
||||
<rect key="frame" x="205" y="211" width="420" height="31"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" systemColor="secondaryLabelColor"/>
|
||||
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</slider>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
@@ -849,6 +860,8 @@ ICAgICAgICAgICAgICA
|
||||
<toolbarItems/>
|
||||
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
|
||||
<connections>
|
||||
<outlet property="buttonAndControllerHeightSlider" destination="ZOF-sL-e7p" id="OHK-5i-3RY"/>
|
||||
<outlet property="buttonAndControllerWidthSlider" destination="Efn-Si-TPp" id="CgK-cC-Yo0"/>
|
||||
<outlet property="chevronImageView" destination="iVZ-Fd-dY7" id="403-Nj-wRx"/>
|
||||
<outlet property="chevronView" destination="hKp-ds-86I" id="Og9-aT-zNH"/>
|
||||
<outlet property="currentProfileLabel" destination="cRV-Xw-CVi" id="Zrb-zn-ptp"/>
|
||||
@@ -936,11 +949,14 @@ ICAgICAgICAgICAgICA
|
||||
<image name="SquareAndArrowDown" width="40" height="40"/>
|
||||
<image name="SquaresArrowUp" width="40" height="40"/>
|
||||
<image name="Trash" width="40" height="40"/>
|
||||
<systemColor name="secondaryLabelColor">
|
||||
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="tintColor">
|
||||
<color red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="viewFlipsideBackgroundColor">
|
||||
<color red="0.12156862745098039" green="0.12941176470588237" blue="0.14117647058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
|
||||
@@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (id) initWithView:(UIView*)view controllerSup:(ControllerSupport*)controllerSupport
|
||||
streamConfig:(StreamConfiguration*)streamConfig oscLevel:(int)oscLevel;
|
||||
|
||||
- (CALayer*) buttonLayerFromName:(NSString*)name;
|
||||
- (CALayer*) controllerLayerFromName:(NSString*)name;
|
||||
- (BOOL) isLayer:(CALayer*)layer hoveringOverButton:(UIButton*)button;
|
||||
|
||||
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
}
|
||||
|
||||
/* returns reference to button layer object given the button's name*/
|
||||
- (CALayer*)buttonLayerFromName: (NSString*)name {
|
||||
- (CALayer*)controllerLayerFromName: (NSString*)name {
|
||||
for (CALayer *buttonLayer in self.OSCButtonLayers) {
|
||||
|
||||
if ([buttonLayer.name isEqualToString:name]) {
|
||||
@@ -159,10 +159,21 @@
|
||||
else if (layer == self._leftStick) { // only let user drag left stick's background, not the inner analog stick itself
|
||||
layerBeingDragged = self._leftStickBackground;
|
||||
}
|
||||
else { // let user drag whatever other valid button they're touching
|
||||
else if(layer == self._aButton ||
|
||||
layer == self._bButton ||
|
||||
layer == self._xButton ||
|
||||
layer == self._yButton ||
|
||||
layer == self._l1Button ||
|
||||
layer == self._l2Button ||
|
||||
layer == self._r1Button ||
|
||||
layer == self._r2Button ||
|
||||
layer == self._selectButton ||
|
||||
layer == self._startButton){ // we must iterates all the controller button layers manually here, to prevent other widgets being dragged accidently
|
||||
layerBeingDragged = layer;
|
||||
}
|
||||
|
||||
[[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];
|
||||
// add hidden attr here
|
||||
@@ -241,4 +252,5 @@
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -200,7 +200,7 @@ static NSMutableDictionary *onScreenButtonViewsDict;
|
||||
|
||||
|
||||
- (bool) updateSelectedProfile:(NSMutableArray *) oscButtonLayers {
|
||||
NSMutableArray* buttonStatesEncoded = [self convertOnscreenButtonsToButtonStates:oscButtonLayers];
|
||||
NSMutableArray* buttonStatesEncoded = [self convertOnScreenControllerAndButtonsToButtonStates:oscButtonLayers];
|
||||
if([self getIndexOfSelectedProfile]==0) return false;
|
||||
OSCProfile *newProfile = [[OSCProfile alloc] initWithName:[self getSelectedProfile].name
|
||||
buttonStates:buttonStatesEncoded isSelected:YES]; // create a new 'OSCProfile'. Set the array of encoded button states created above to the 'buttonStates' property of the new profile, along with a 'name'. Set 'isSelected' argument to YES which will set this saved profile as the one that will show up in the game stream view
|
||||
@@ -217,7 +217,7 @@ static NSMutableDictionary *onScreenButtonViewsDict;
|
||||
|
||||
|
||||
- (void) saveProfileWithName:(NSString*)name andButtonLayers:(NSMutableArray *)oscButtonLayers {
|
||||
NSMutableArray* buttonStatesEncoded = [self convertOnscreenButtonsToButtonStates:oscButtonLayers];
|
||||
NSMutableArray* buttonStatesEncoded = [self convertOnScreenControllerAndButtonsToButtonStates:oscButtonLayers];
|
||||
OSCProfile *newProfile = [[OSCProfile alloc] initWithName:name
|
||||
buttonStates:buttonStatesEncoded isSelected:YES]; // create a new 'OSCProfile'. Set the array of encoded button states created above to the 'buttonStates' property of the new profile, along with a 'name'. Set 'isSelected' argument to YES which will set this saved profile as the one that will show up in the game stream view
|
||||
/* set all saved OSCProfiles 'isSelected' property to NO since the new profile you're adding will be set as the selected profile */
|
||||
@@ -243,7 +243,7 @@ static NSMutableDictionary *onScreenButtonViewsDict;
|
||||
}
|
||||
|
||||
|
||||
- (NSMutableArray* ) convertOnscreenButtonsToButtonStates:(NSMutableArray *) oscButtonLayers {
|
||||
- (NSMutableArray* ) convertOnScreenControllerAndButtonsToButtonStates:(NSMutableArray *) oscButtonLayers {
|
||||
/* iterate through each OSC button the user sees on screen, create an 'OnScreenButtonState' object from each button, encode each object, and then add each object to an array */
|
||||
/*
|
||||
NSSet *validPositionButtonNames = [NSSet setWithObjects:
|
||||
@@ -262,6 +262,8 @@ static NSMutableDictionary *onScreenButtonViewsDict;
|
||||
@"startButton",
|
||||
nil]; */
|
||||
NSMutableArray *buttonStatesEncoded = [[NSMutableArray alloc] init];
|
||||
|
||||
// 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];
|
||||
@@ -271,12 +273,14 @@ static NSMutableDictionary *onScreenButtonViewsDict;
|
||||
[buttonStatesEncoded addObject: buttonStateEncoded];
|
||||
}
|
||||
|
||||
// save keyboard button as buttonstate, this is for the new onscreen keyboard buttons:
|
||||
// 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;
|
||||
NSData *buttonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil];
|
||||
[buttonStatesEncoded addObject: buttonStateEncoded];
|
||||
}];
|
||||
|
||||
@@ -25,6 +25,9 @@ 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) BOOL hasValidPosition;
|
||||
|
||||
typedef NS_ENUM(NSInteger, OnScreenButtonType) {
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
[encoder encodeInt:self.buttonType forKey:@"buttonType"];
|
||||
[encoder encodeCGPoint:self.position forKey:@"position"];
|
||||
[encoder encodeBool:self.isHidden forKey:@"isHidden"];
|
||||
[encoder encodeFloat:self.widthFactor forKey:@"widthFactor"];
|
||||
[encoder encodeFloat:self.heightFactor forKey:@"heightFactor"];
|
||||
}
|
||||
|
||||
- (id) initWithCoder:(NSCoder*)decoder {
|
||||
@@ -43,6 +45,8 @@
|
||||
self.buttonType = [decoder decodeIntForKey:@"buttonType"];
|
||||
self.position = [decoder decodeCGPointForKey:@"position"];
|
||||
self.isHidden = [decoder decodeBoolForKey:@"isHidden"];
|
||||
self.widthFactor = [decoder decodeFloatForKey:@"widthFactor"];
|
||||
self.heightFactor = [decoder decodeFloatForKey:@"heightFactor"];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
@@ -16,8 +16,9 @@ import UIKit
|
||||
@objc public var keyString: String
|
||||
@objc public var timestamp: TimeInterval
|
||||
@objc public var pressed: Bool
|
||||
@objc public var widthFactor: CGFloat
|
||||
@objc public var heightFactor: CGFloat
|
||||
|
||||
|
||||
private let label: UILabel
|
||||
private let originalBackgroundColor: UIColor
|
||||
private var storedLocation: CGPoint = .zero
|
||||
@@ -30,6 +31,8 @@ import UIKit
|
||||
self.originalBackgroundColor = UIColor(white: 0.2, alpha: 0.7)
|
||||
self.timestamp = 0
|
||||
self.pressed = false
|
||||
self.widthFactor = 1.0
|
||||
self.heightFactor = 1.0
|
||||
super.init(frame: .zero)
|
||||
setupView()
|
||||
}
|
||||
@@ -38,7 +41,7 @@ import UIKit
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc public func setKeyLocation(xOffset:CGFloat, yOffset:CGFloat) {
|
||||
@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),
|
||||
@@ -49,7 +52,38 @@ import UIKit
|
||||
OnScreenButtonView.editMode = enabled
|
||||
}
|
||||
|
||||
private func setupView() {
|
||||
@objc public func resizeButtonView(){
|
||||
guard let superview = superview else { return }
|
||||
|
||||
|
||||
// Deactivate existing constraints if necessary
|
||||
NSLayoutConstraint.deactivate(self.constraints)
|
||||
|
||||
// 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
|
||||
let newWidthConstraint = self.widthAnchor.constraint(equalToConstant: 70 * self.widthFactor)
|
||||
let newHeightConstraint = self.heightAnchor.constraint(equalToConstant: 65 * self.heightFactor)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
self.widthAnchor.constraint(equalToConstant: 70 * self.widthFactor),
|
||||
self.heightAnchor.constraint(equalToConstant: 65 * self.heightFactor),
|
||||
])
|
||||
|
||||
// Trigger layout update
|
||||
superview.layoutIfNeeded()
|
||||
|
||||
// Re-setup buttonView style
|
||||
setupView()
|
||||
}
|
||||
|
||||
@objc public func setupView() {
|
||||
label.text = self.keyLabel
|
||||
label.font = UIFont.boldSystemFont(ofSize: 19)
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
@@ -77,8 +111,8 @@ import UIKit
|
||||
NSLayoutConstraint.activate([
|
||||
//self.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.088),
|
||||
//self.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height * 0.1),
|
||||
self.widthAnchor.constraint(equalToConstant: 70),
|
||||
self.heightAnchor.constraint(equalToConstant: 65),
|
||||
self.widthAnchor.constraint(equalToConstant: 70 * self.widthFactor),
|
||||
self.heightAnchor.constraint(equalToConstant: 65 * self.widthFactor),
|
||||
])
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
@@ -135,7 +169,9 @@ import UIKit
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 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
|
||||
if let touch = touches.first {
|
||||
let touchLocation = touch.location(in: superview)
|
||||
storedLocation = touchLocation
|
||||
|
||||
@@ -36,10 +36,28 @@ typedef NS_ENUM(NSInteger, OnScreenControlsLevel) {
|
||||
// @property (nonatomic, assign) CustomTapGestureRecognizer* mouseRightClickTapRecognizer; // this object will be passed to onscreencontrols class for areVirtualControllerTaps flag setting
|
||||
@property (nonatomic, assign) bool isLayingOut;
|
||||
//@property (nonatomic) NSMutableSet<UITouch* >* touchesCapturedByOnScreenButtons;
|
||||
|
||||
|
||||
@property (nonatomic, assign) CGRect standardRoundButtonBounds;
|
||||
@property (nonatomic, assign) CGRect standardRectangleButtonBounds;
|
||||
@property (nonatomic, assign) CGRect standardStickBounds;
|
||||
@property (nonatomic, assign) CGRect standardStickBackgroundBounds;
|
||||
@property (nonatomic, assign) CGRect standardUpDownButtonBounds;
|
||||
@property (nonatomic, assign) CGRect standardLeftRightButtonBounds;
|
||||
|
||||
@property (nonatomic, assign) CGPoint leftStickCenter;
|
||||
@property (nonatomic, assign) CGPoint rightStickCenter;
|
||||
|
||||
@property CALayer* _aButton;
|
||||
@property (nonatomic, assign) CGFloat aButtonSizeFactor;
|
||||
@property CALayer* _bButton;
|
||||
@property (nonatomic, assign) CGFloat bButtonSizeFactor;
|
||||
@property CALayer* _xButton;
|
||||
@property (nonatomic, assign) CGFloat xButtonSizeFactor;
|
||||
@property CALayer* _yButton;
|
||||
@property (nonatomic, assign) CGFloat yButtonSizeFactor;
|
||||
|
||||
|
||||
@property CALayer* _startButton;
|
||||
@property CALayer* _selectButton;
|
||||
@property CALayer* _r1Button;
|
||||
@@ -56,7 +74,7 @@ typedef NS_ENUM(NSInteger, OnScreenControlsLevel) {
|
||||
@property CALayer* _leftStick;
|
||||
@property CALayer* _rightStickBackground;
|
||||
@property CALayer* _rightStick;
|
||||
@property CALayer *_dPadBackground; // parent layer that contains each individual dPad button so user can drag them around the screen together
|
||||
@property CALayer* _dPadBackground; // parent layer that contains each individual dPad button so user can drag them around the screen together
|
||||
|
||||
@property float D_PAD_CENTER_X;
|
||||
@property float D_PAD_CENTER_Y;
|
||||
@@ -81,5 +99,6 @@ typedef NS_ENUM(NSInteger, OnScreenControlsLevel) {
|
||||
- (void) setDPadCenter;
|
||||
- (void) setAnalogStickPositions;
|
||||
- (void) positionOSCButtons;
|
||||
- (void) resizeControllerLayersWith:(CALayer*)layer and:(CGFloat)sizeFactor;
|
||||
|
||||
@end
|
||||
|
||||
@@ -233,6 +233,14 @@ static float L3_Y;
|
||||
_downButton.name = @"downButton";
|
||||
_leftButton.name = @"leftButton";
|
||||
|
||||
|
||||
_standardRoundButtonBounds = CGRectMake(0, 0, [UIImage imageNamed:@"AButton"].size.width, [UIImage imageNamed:@"AButton"].size.height);
|
||||
_standardRectangleButtonBounds = CGRectMake(0, 0, [UIImage imageNamed:@"StartButton"].size.width, [UIImage imageNamed:@"StartButton"].size.height);
|
||||
_standardStickBounds = CGRectMake(0, 0, [UIImage imageNamed:@"StickInner"].size.width * 1.33, [UIImage imageNamed:@"StickInner"].size.height * 1.33);
|
||||
_standardStickBackgroundBounds = CGRectMake(0, 0, [UIImage imageNamed:@"StickOuter"].size.width * 1.10, [UIImage imageNamed:@"StickOuter"].size.height * 1.10);
|
||||
_standardUpDownButtonBounds = CGRectMake(0, 0, [UIImage imageNamed:@"UpButton"].size.width, [UIImage imageNamed:@"UpButton"].size.height);
|
||||
_standardLeftRightButtonBounds = CGRectMake(0, 0, [UIImage imageNamed:@"LeftButton"].size.width, [UIImage imageNamed:@"LeftButton"].size.height);
|
||||
|
||||
_activeCustomOscButtonPositionDict = [[NSMutableDictionary alloc] init];
|
||||
touchAddrsCapturedByOnScreenControls = [[NSMutableSet alloc] init];
|
||||
|
||||
@@ -1429,5 +1437,90 @@ static float L3_Y;
|
||||
|
||||
}
|
||||
|
||||
- (void) resizeControllerLayersWith:(CALayer*)layer and:(CGFloat)sizeFactor{
|
||||
// CALayer* superLayer = layer.superlayer;
|
||||
// if(layerBeingDragged.name == @"")
|
||||
if (layer == self._aButton ||
|
||||
layer == self._bButton ||
|
||||
layer == self._xButton ||
|
||||
layer == self._yButton ||
|
||||
layer == self._l1Button ||
|
||||
layer == self._l2Button ||
|
||||
layer == self._r1Button ||
|
||||
layer == self._r2Button){
|
||||
layer.bounds = CGRectMake(0, 0, self.standardRoundButtonBounds.size.width * sizeFactor, self.standardRoundButtonBounds.size.height * sizeFactor);
|
||||
}
|
||||
|
||||
if (layer == self._selectButton ||
|
||||
layer == self._startButton) {
|
||||
layer.bounds = CGRectMake(0, 0, self.standardRectangleButtonBounds.size.width * sizeFactor, self.standardRectangleButtonBounds.size.height * sizeFactor);
|
||||
}
|
||||
|
||||
if (layer == self._rightStickBackground) {
|
||||
// Resize the rightStick & Background bounds
|
||||
self._rightStickBackground.bounds = CGRectMake(0, 0, self.standardStickBackgroundBounds.size.width * sizeFactor, self.standardStickBackgroundBounds.size.height * sizeFactor);
|
||||
self._rightStick.bounds = CGRectMake(0, 0, self.standardStickBounds.size.width * sizeFactor, self.standardStickBounds.size.height * sizeFactor);
|
||||
|
||||
// Retrieve the current frame to account for transformations, this will update the coords for new position CGPointMake
|
||||
CGRect transformedBackgroundFrame = self._rightStickBackground.frame;
|
||||
|
||||
// Explicitly adjust the position of _rightStickBackground using the transformed frame
|
||||
self._rightStickBackground.position = CGPointMake(CGRectGetMidX(transformedBackgroundFrame), CGRectGetMidY(transformedBackgroundFrame));
|
||||
|
||||
// Update the position of _rightStick to match the new center of the transformed _rightStickBackground
|
||||
self._rightStick.position = CGPointMake(CGRectGetMidX(self._rightStickBackground.bounds), CGRectGetMidY(self._rightStickBackground.bounds));
|
||||
}
|
||||
|
||||
if (layer == self._leftStickBackground){
|
||||
// Resize the rightStick & Background bounds
|
||||
self._leftStickBackground.bounds = CGRectMake(0, 0, self.standardStickBackgroundBounds.size.width * sizeFactor, self.standardStickBackgroundBounds.size.height * sizeFactor);
|
||||
self._leftStick.bounds = CGRectMake(0, 0, self.standardStickBounds.size.width * sizeFactor, self.standardStickBounds.size.height * sizeFactor);
|
||||
|
||||
// Retrieve the current frame to account for transformations, this will update the coords for new position CGPointMake
|
||||
CGRect transformedBackgroundFrame = self._leftStickBackground.frame;
|
||||
|
||||
// Explicitly adjust the position of _rightStickBackground using the transformed frame
|
||||
self._leftStickBackground.position = CGPointMake(CGRectGetMidX(transformedBackgroundFrame), CGRectGetMidY(transformedBackgroundFrame));
|
||||
|
||||
// Update the position of _rightStick to match the new center of the transformed _rightStickBackground
|
||||
self._leftStick.position = CGPointMake(CGRectGetMidX(self._leftStickBackground.bounds), CGRectGetMidY(self._leftStickBackground.bounds));
|
||||
}
|
||||
|
||||
if (layer == self._dPadBackground){
|
||||
|
||||
// Calculate the distances of each button from the shared center based on their transformed positions
|
||||
CGFloat newDPadDistFactor = 0.1/sizeFactor;
|
||||
|
||||
// 1. Resize and reposition the Down button
|
||||
|
||||
CGFloat newLongSideLength = _standardLeftRightButtonBounds.size.width * sizeFactor;
|
||||
CGFloat newShortSideLength = _standardLeftRightButtonBounds.size.height * sizeFactor;
|
||||
|
||||
CGPoint sharedCenter = CGPointMake(_standardLeftRightButtonBounds.size.width, _standardLeftRightButtonBounds.size.width); // this will anchor the center point of the dPad
|
||||
|
||||
// Resize and reposition the Up button
|
||||
_upButton.anchorPoint = CGPointMake(0.5, 1 + newDPadDistFactor);
|
||||
_upButton.bounds = CGRectMake(0, 0, newShortSideLength, newLongSideLength);
|
||||
_upButton.position = CGPointMake(sharedCenter.x, sharedCenter.y);
|
||||
|
||||
// Resize and reposition the Down button
|
||||
_downButton.anchorPoint = CGPointMake(0.5, 0 - newDPadDistFactor);
|
||||
_downButton.bounds = CGRectMake(0, 0, newShortSideLength, newLongSideLength);
|
||||
_downButton.position = CGPointMake(sharedCenter.x, sharedCenter.y);
|
||||
|
||||
// Resize and reposition the Right button
|
||||
_rightButton.anchorPoint = CGPointMake(0 - newDPadDistFactor, 0.5);
|
||||
_rightButton.bounds = CGRectMake(0, 0, newLongSideLength, newShortSideLength);
|
||||
_rightButton.position = CGPointMake(sharedCenter.x, sharedCenter.y);
|
||||
|
||||
// Resize and reposition the Left button
|
||||
_leftButton.anchorPoint = CGPointMake(1 + newDPadDistFactor, 0.5);
|
||||
_leftButton.bounds = CGRectMake(0, 0, newLongSideLength, newShortSideLength);
|
||||
_leftButton.position = CGPointMake(sharedCenter.x, sharedCenter.y);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -383,9 +383,12 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
||||
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.widthFactor = buttonState.widthFactor;
|
||||
buttonView.heightFactor = buttonState.heightFactor;
|
||||
// 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 setKeyLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y];
|
||||
[buttonView setLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y];
|
||||
[buttonView resizeButtonView]; // resize must be called after relocation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property (strong, nonatomic) OSCProfilesTableViewController *oscProfilesTableViewController;
|
||||
@property (nonatomic, assign) NSString *currentProfileName;
|
||||
@property (strong, nonatomic) IBOutlet UILabel *currentProfileLabel;
|
||||
@property (strong, nonatomic) IBOutlet UISlider *buttonAndControllerWidthSlider;
|
||||
@property (strong, nonatomic) IBOutlet UISlider *buttonAndControllerHeightSlider;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
+106
-15
@@ -21,7 +21,12 @@
|
||||
|
||||
@implementation LayoutOnScreenControlsViewController {
|
||||
BOOL isToolbarHidden;
|
||||
OSCProfilesManager *profilesManager;
|
||||
OSCProfilesManager* profilesManager;
|
||||
OnScreenButtonView* selectedButtonView;
|
||||
CALayer* selectedControllerLayer;
|
||||
CGRect controllerOriginalBounds;
|
||||
bool buttonViewSelected;
|
||||
bool controllerLayerSelected;
|
||||
__weak IBOutlet NSLayoutConstraint *toolbarTopConstraintiPhone;
|
||||
__weak IBOutlet NSLayoutConstraint *toolbarTopConstraintiPad;
|
||||
}
|
||||
@@ -61,10 +66,12 @@
|
||||
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;
|
||||
// Add the buttonView to the view controller's view
|
||||
[self.view addSubview:buttonView];
|
||||
[buttonView setKeyLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y];
|
||||
|
||||
[buttonView setLocationWithXOffset:buttonState.position.x yOffset:buttonState.position.y];
|
||||
[buttonView resizeButtonView]; // resize must be called after relocation
|
||||
[self.onScreenButtonViewsDict setObject:buttonView forKey:@(buttonView.timestamp)];
|
||||
}
|
||||
}
|
||||
@@ -120,7 +127,16 @@
|
||||
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(setButtonViewSizeSliderValues:)
|
||||
name:@"OnScreenButtonViewSelected"
|
||||
object:nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(setControllerCALayerSizeSliderValues:)
|
||||
name:@"ControllerCALayerSelected"
|
||||
object:nil];
|
||||
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(OSCLayoutChanged) name:@"OSCLayoutChanged" object:nil]; // used to notifiy this view controller that the user made a change to the OSC layout so that the VC can either fade in or out its 'Undo button' which will signify to the user whether there are any OSC layout changes to undo
|
||||
|
||||
@@ -234,7 +250,7 @@
|
||||
if ([self.layoutOSC.layoutChanges count] > 0) { // check if there are layout changes to roll back to
|
||||
OnScreenButtonState *buttonState = [self.layoutOSC.layoutChanges lastObject]; // Get the 'OnScreenButtonState' object that contains the name, position, and visiblity state of the button the user last moved
|
||||
|
||||
CALayer *buttonLayer = [self.layoutOSC buttonLayerFromName:buttonState.name]; // get the on screen button layer that corresponds with the 'OnScreenButtonState' object that we retrieved above
|
||||
CALayer *buttonLayer = [self.layoutOSC controllerLayerFromName:buttonState.name]; // get the on screen button layer that corresponds with the 'OnScreenButtonState' object that we retrieved above
|
||||
|
||||
/* Set the button's position and visiblity to what it was before the user last moved it */
|
||||
buttonLayer.position = buttonState.position;
|
||||
@@ -319,7 +335,7 @@
|
||||
[self.onScreenButtonViewsDict setObject:buttonView forKey:@(buttonView.timestamp)];
|
||||
// Add the buttonView to the view controller's view
|
||||
[self.view addSubview:buttonView];
|
||||
[buttonView setKeyLocationWithXOffset:50 yOffset:50];
|
||||
[buttonView setLocationWithXOffset:50 yOffset:50];
|
||||
}];
|
||||
[alertController addAction:cancelAction];
|
||||
[alertController addAction:okAction];
|
||||
@@ -346,6 +362,87 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setButtonViewSizeSliderValues: (NSNotification *)notification{
|
||||
// receive the selected buttonView obj passed from the notification
|
||||
OnScreenButtonView* buttonView = (OnScreenButtonView* )notification.object;
|
||||
self->buttonViewSelected = true;
|
||||
self->controllerLayerSelected = false;
|
||||
self->selectedButtonView = buttonView;
|
||||
// setup slider values
|
||||
[self.buttonAndControllerWidthSlider setValue:100 * self->selectedButtonView.widthFactor];
|
||||
[self.buttonAndControllerHeightSlider setValue:100 * self->selectedButtonView.heightFactor];
|
||||
}
|
||||
|
||||
- (void)setControllerCALayerSizeSliderValues: (NSNotification *)notification{
|
||||
// receive the selected buttonView obj passed from the notification
|
||||
CALayer* controllerLayer = (CALayer* )notification.object;
|
||||
self->buttonViewSelected = false;
|
||||
self->controllerLayerSelected = true;
|
||||
self->selectedControllerLayer = controllerLayer;
|
||||
self->controllerOriginalBounds = controllerLayer.bounds;
|
||||
// setup slider values
|
||||
// [self.buttonAndControllerWidthSlider setValue:100 * self->selectedButtonView.widthFactor];
|
||||
// [self.buttonAndControllerHeightSlider setValue:100 * self->selectedButtonView.heightFactor];
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void)buttonAndControllerWidthSliderMoved{
|
||||
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.buttonAndControllerWidthSlider.value / 100;
|
||||
[self.buttonAndControllerHeightSlider setValue: self.buttonAndControllerWidthSlider.value];
|
||||
[self->selectedButtonView resizeButtonView];
|
||||
}
|
||||
if(self->selectedControllerLayer != nil && self->controllerLayerSelected){
|
||||
[self.layoutOSC resizeControllerLayersWith:self->selectedControllerLayer and:self.buttonAndControllerWidthSlider.value/100];
|
||||
return;
|
||||
|
||||
CALayer* superLayer = self->selectedControllerLayer.superlayer;
|
||||
// if(self->selectedControllerLayer.name == @"")
|
||||
if ([self->selectedControllerLayer.name isEqualToString:@"r1Button"] ||
|
||||
[self->selectedControllerLayer.name isEqualToString:@"r2Button"] ||
|
||||
[self->selectedControllerLayer.name isEqualToString:@"l1Button"] ||
|
||||
[self->selectedControllerLayer.name isEqualToString:@"l2Button"] ||
|
||||
[self->selectedControllerLayer.name isEqualToString:@"aButton"] ||
|
||||
[self->selectedControllerLayer.name isEqualToString:@"bButton"] ||
|
||||
[self->selectedControllerLayer.name isEqualToString:@"xButton"] ||
|
||||
[self->selectedControllerLayer.name isEqualToString:@"yButton"]){
|
||||
[self->selectedControllerLayer removeFromSuperlayer];
|
||||
self->selectedControllerLayer.bounds = CGRectMake(0, 0, self.layoutOSC.standardRoundButtonBounds.size.width * self.buttonAndControllerWidthSlider.value/100, self.layoutOSC.standardRoundButtonBounds.size.height * self.buttonAndControllerWidthSlider.value/100);
|
||||
[superLayer addSublayer:self->selectedControllerLayer];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)buttonAndControllerHeightSliderMoved{
|
||||
if(self->selectedButtonView != nil && self->buttonViewSelected){
|
||||
self->selectedButtonView.translatesAutoresizingMaskIntoConstraints = true; // this is mandatory to prevent unexpected key view location change
|
||||
self->selectedButtonView.heightFactor = self.buttonAndControllerHeightSlider.value / 100;
|
||||
[self->selectedButtonView resizeButtonView];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)setupProfileLableAndSliders{
|
||||
CGFloat xPosition = (self.view.bounds.size.width - self.currentProfileLabel.frame.size.width) / 2;
|
||||
// Set the label's frame with the calculated x-position
|
||||
self.currentProfileLabel.frame = CGRectMake(xPosition, self.currentProfileLabel.frame.origin.y, self.currentProfileLabel.frame.size.width, self.currentProfileLabel.frame.size.height);
|
||||
self.currentProfileLabel.hidden = NO; // Show Current Profile display
|
||||
[self.currentProfileLabel setText:[LocalizationHelper localizedStringForKey:@"Current Profile: %@",[profilesManager getSelectedProfile].name]]; // display current profile name when profile is being refreshed.
|
||||
|
||||
// button size sliders
|
||||
self.buttonAndControllerWidthSlider.hidden = NO;
|
||||
self.buttonAndControllerWidthSlider.frame = CGRectMake(xPosition, self.buttonAndControllerWidthSlider.frame.origin.y, self.buttonAndControllerWidthSlider.frame.size.width, self.buttonAndControllerWidthSlider.frame.size.height);
|
||||
[self.buttonAndControllerWidthSlider addTarget:self action:@selector(buttonAndControllerWidthSliderMoved) forControlEvents:(UIControlEventValueChanged)];
|
||||
|
||||
// button size sliders
|
||||
self.buttonAndControllerHeightSlider.hidden = NO;
|
||||
self.buttonAndControllerHeightSlider.frame = CGRectMake(xPosition, self.buttonAndControllerHeightSlider.frame.origin.y, self.buttonAndControllerHeightSlider.frame.size.width, self.buttonAndControllerHeightSlider.frame.size.height);
|
||||
[self.buttonAndControllerHeightSlider addTarget:self action:@selector(buttonAndControllerHeightSliderMoved) forControlEvents:(UIControlEventValueChanged)];
|
||||
}
|
||||
|
||||
|
||||
/* Basically the same method as loadTapped, without parameter*/
|
||||
@@ -360,13 +457,8 @@
|
||||
storyboard = [UIStoryboard storyboardWithName:@"iPad" bundle:nil];
|
||||
}
|
||||
|
||||
// Center the current profile lable horizontally:;
|
||||
// Calculate the x-position
|
||||
CGFloat xPosition = (self.view.bounds.size.width - self.currentProfileLabel.frame.size.width) / 2;
|
||||
// Set the label's frame with the calculated x-position
|
||||
self.currentProfileLabel.frame = CGRectMake(xPosition, self.currentProfileLabel.frame.origin.y, self.currentProfileLabel.frame.size.width, self.currentProfileLabel.frame.size.height);
|
||||
self.currentProfileLabel.hidden = NO; // Show Current Profile display
|
||||
[self.currentProfileLabel setText:[LocalizationHelper localizedStringForKey:@"Current Profile: %@",[profilesManager getSelectedProfile].name]]; // display current profile name when profile is being refreshed.
|
||||
// setup: current profile lable, button width slider, button height slider & button alpha slider
|
||||
[self setupProfileLableAndSliders];
|
||||
|
||||
//initialiaze _oscProfilesTableViewController
|
||||
self->_oscProfilesTableViewController = [storyboard instantiateViewControllerWithIdentifier:@"OSCProfilesTableViewController"];
|
||||
@@ -411,6 +503,7 @@
|
||||
[self OSCLayoutChanged]; // fades the 'Undo Button' out
|
||||
};
|
||||
self.currentProfileLabel.hidden = YES; // Hide Current Profile display before entering the profile table view
|
||||
self.buttonAndControllerWidthSlider.hidden = YES;
|
||||
_oscProfilesTableViewController.currentOSCButtonLayers = self.layoutOSC.OSCButtonLayers;
|
||||
[self presentViewController:_oscProfilesTableViewController animated:YES completion:nil];
|
||||
}
|
||||
@@ -454,8 +547,6 @@
|
||||
trashCanButton.tintColor = [UIColor redColor];
|
||||
}
|
||||
else trashCanButton.tintColor = [UIColor colorWithRed:171.0/255.0 green:157.0/255.0 blue:255.0/255.0 alpha:1];
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (bool)touchWithinTashcanButton:(UITouch* )touch {
|
||||
|
||||
Reference in New Issue
Block a user