on screen key test
This commit is contained in:
@@ -354,6 +354,8 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
|
||||
rightStickY = MAX_MAGNITUDE(rightStickY, controller.mergedWithController.lastRightStickY);
|
||||
}
|
||||
|
||||
NSLog(@"gamepadMask: %@", [self binaryRepresentationOfInteger:buttonFlags]); // we got the pressed OSC buttons here.
|
||||
|
||||
// Player 1 is always present for OSC
|
||||
LiSendMultiControllerEvent(_multiController ? controller.playerIndex : 0, [self getActiveGamepadMask],
|
||||
buttonFlags, leftTrigger, rightTrigger,
|
||||
@@ -370,6 +372,19 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)binaryRepresentationOfInteger:(int)number {
|
||||
NSMutableString *binaryString = [NSMutableString string];
|
||||
int numBits = sizeof(number) * 8;
|
||||
|
||||
for (int i = numBits - 1; i >= 0; i--) {
|
||||
[binaryString appendString:((number >> i) & 1) ? @"1" : @"0"];
|
||||
}
|
||||
|
||||
return binaryString;
|
||||
}
|
||||
|
||||
|
||||
+(BOOL) hasKeyboardOrMouse {
|
||||
if (@available(iOS 14.0, tvOS 14.0, *)) {
|
||||
return GCMouse.mice.count > 0 || GCKeyboard.coalescedKeyboard != nil;
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
}
|
||||
|
||||
/* 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 isHidden:layerBeingDragged.isHidden andPosition:layerBeingDragged.position];
|
||||
OnScreenButtonState *onScreenButtonState = [[OnScreenButtonState alloc] initWithButtonName:layerBeingDragged.name isKeyboardButton:NO isHidden:layerBeingDragged.isHidden andPosition:layerBeingDragged.position];
|
||||
[layoutChanges addObject:onScreenButtonState];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"OSCLayoutChanged" object:self]; // lets the view controller know whether to fade the undo button in or out depending on whether there are any further OSC layout changes the user is allowed to undo
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
NSMutableArray *buttonStatesEncoded = [[NSMutableArray alloc] init];
|
||||
for (CALayer *buttonLayer in buttonLayers) {
|
||||
|
||||
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:buttonLayer.name isHidden:buttonLayer.isHidden andPosition:buttonLayer.position];
|
||||
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:buttonLayer.name isKeyboardButton:NO isHidden:buttonLayer.isHidden andPosition:buttonLayer.position];
|
||||
NSData *buttonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil];
|
||||
[buttonStatesEncoded addObject: buttonStateEncoded];
|
||||
}
|
||||
@@ -220,7 +220,7 @@
|
||||
NSMutableArray *buttonStatesEncoded = [[NSMutableArray alloc] init];
|
||||
for (CALayer *buttonLayer in buttonLayers) {
|
||||
|
||||
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:buttonLayer.name isHidden:buttonLayer.isHidden andPosition:buttonLayer.position];
|
||||
OnScreenButtonState *buttonState = [[OnScreenButtonState alloc] initWithButtonName:buttonLayer.name isKeyboardButton:NO isHidden:buttonLayer.isHidden andPosition:buttonLayer.position];
|
||||
NSData *buttonStateEncoded = [NSKeyedArchiver archivedDataWithRootObject:buttonState requiringSecureCoding:YES error:nil];
|
||||
[buttonStatesEncoded addObject: buttonStateEncoded];
|
||||
}
|
||||
|
||||
@@ -15,13 +15,16 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
We are able to associate this 'OnScreenButtonState' object and its corresponding CALayer onscreen controller button by setting their 'name' properties equal; in our particular case we give them descriptive names such as 'aButton', 'upButton', 'leftStick', etc. By keeping references to the 19 on screen controller buttons (CALayers) in an array, and creating 19 'OnScreenButtonState' objects with names corresponding to these 19 CALayers and keeping them in an array, we can iterate through both arrays to find OSC buttons (CALayers) with the same name as one of the 'OnScreenButtonStateObjects' and then set the CALayer on screen control button's 'position' and 'hidden' property according to the value of the 'OnScreenButtonState' objects 'position' and 'isHidden' properties.
|
||||
Naturally we would like the user to be able to save their controller layout configurations so that they can load them between app launches, so we adopt encoding/decoding related protocols so we encode these 'OnScreenButtonState' objects and save them to NSUserDefaults
|
||||
*/
|
||||
|
||||
// OS Button state info obj to be modified
|
||||
@interface OnScreenButtonState : NSObject <NSCoding, NSSecureCoding>
|
||||
|
||||
@property NSString *name;
|
||||
@property CGPoint position;
|
||||
@property BOOL isHidden;
|
||||
@property (nonatomic, assign) BOOL isKeyboardButton;
|
||||
|
||||
- (id) initWithButtonName:(NSString*)name isHidden:(BOOL)isHidden andPosition:(CGPoint)position;
|
||||
- (id) initWithButtonName:(NSString*)name isKeyboardButton:(BOOL)isKeyboardButton isHidden:(BOOL)isHidden andPosition:(CGPoint)position;
|
||||
|
||||
+ (BOOL) supportsSecureCoding;
|
||||
- (void) encodeWithCoder:(NSCoder*)encoder;
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
|
||||
@implementation OnScreenButtonState
|
||||
|
||||
- (id) initWithButtonName:(NSString*)name isHidden:(BOOL)isHidden andPosition:(CGPoint)position {
|
||||
- (id) initWithButtonName:(NSString*)name isKeyboardButton:(BOOL)isKeyboardButton isHidden:(BOOL)isHidden andPosition:(CGPoint)position {
|
||||
if ((self = [self init])) {
|
||||
self.name = name;
|
||||
self.isHidden = isHidden;
|
||||
self.position = position;
|
||||
self.isKeyboardButton = isKeyboardButton;
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -26,6 +27,7 @@
|
||||
|
||||
- (void) encodeWithCoder:(NSCoder*)encoder {
|
||||
[encoder encodeObject:self.name forKey:@"name"];
|
||||
[encoder encodeBool:self.isKeyboardButton forKey:@"isKeyboardButton"];
|
||||
[encoder encodeBool:self.isHidden forKey:@"isHidden"];
|
||||
[encoder encodeCGPoint:self.position forKey:@"position"];
|
||||
}
|
||||
@@ -33,6 +35,7 @@
|
||||
- (id) initWithCoder:(NSCoder*)decoder {
|
||||
if (self = [super init]) {
|
||||
self.name = [decoder decodeObjectForKey:@"name"];
|
||||
self.isKeyboardButton = [decoder decodeBoolForKey:@"isKeyboardButton"];
|
||||
self.isHidden = [decoder decodeBoolForKey:@"isHidden"];
|
||||
self.position = [decoder decodeCGPointForKey:@"position"];
|
||||
}
|
||||
|
||||
@@ -457,7 +457,7 @@ static float L3_Y;
|
||||
// create A button
|
||||
_aButton.contents = (id) aButtonImage.CGImage;
|
||||
_aButton.frame = _swapABXY ? bButtonFrame : aButtonFrame;
|
||||
[_view.layer addSublayer:_aButton];
|
||||
[_view.layer addSublayer:_aButton]; // rendering OSC Button here
|
||||
|
||||
// create B button
|
||||
_bButton.frame = _swapABXY ? aButtonFrame : bButtonFrame;
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
//
|
||||
// OnScreenKey.swift
|
||||
// Moonlight-ZWM
|
||||
//
|
||||
// Created by ZWM on 2024/8/4.
|
||||
// Copyright © 2024 Moonlight Game Streaming Project. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@objc class OnScreenKeyView: UIView {
|
||||
@objc static var relocationMode: Bool = false
|
||||
@objc var keyLabel: String
|
||||
@objc var keyString: String
|
||||
private let label: UILabel
|
||||
private let originalBackgroundColor: UIColor
|
||||
private var storedLocation: CGPoint = .zero
|
||||
|
||||
|
||||
@objc init(keyString: String, keyLabel: String) {
|
||||
self.keyString = keyString
|
||||
self.keyLabel = keyLabel
|
||||
self.label = UILabel()
|
||||
self.originalBackgroundColor = UIColor(white: 0.2, alpha: 0.7)
|
||||
|
||||
super.init(frame: .zero)
|
||||
setupView()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc public func setKeyLocation(xOffset:CGFloat, yOffset:CGFloat) {
|
||||
NSLayoutConstraint.activate([
|
||||
self.leadingAnchor.constraint(equalTo: self.superview!.leadingAnchor, constant: xOffset),
|
||||
self.topAnchor.constraint(equalTo: self.superview!.topAnchor, constant: yOffset),
|
||||
])
|
||||
}
|
||||
|
||||
@objc public func enableRelocationMode(enabled: Bool){
|
||||
OnScreenKeyView.relocationMode = enabled
|
||||
}
|
||||
|
||||
private func setupView() {
|
||||
label.text = self.keyLabel
|
||||
label.font = UIFont.systemFont(ofSize: 30)
|
||||
label.textColor = UIColor(white: 1.0, alpha: 0.8)
|
||||
label.shadowColor = .black
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
self.layer.borderColor = UIColor.black.cgColor
|
||||
self.layer.borderWidth = 2
|
||||
self.layer.cornerRadius = 8
|
||||
self.backgroundColor = UIColor(white: 0.2, alpha: 0.7)
|
||||
self.layer.shadowRadius = 4
|
||||
self.layer.shadowOpacity = 0.5
|
||||
|
||||
addSubview(label)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
label.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
label.centerYAnchor.constraint(equalTo: centerYAnchor),
|
||||
])
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
self.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.088),
|
||||
self.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height * 0.1),
|
||||
])
|
||||
}
|
||||
|
||||
// Touch event handling
|
||||
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
super.touchesBegan(touches, with: event)
|
||||
//self.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 1.0, alpha: 0.7)
|
||||
self.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.7)
|
||||
|
||||
|
||||
if !OnScreenKeyView.relocationMode { LiSendKeyboardEvent(CommandManager.keyMappings[self.keyString]!,Int8(KEY_ACTION_DOWN), 0) }
|
||||
else {
|
||||
// Store the initial center point of the key
|
||||
if let touch = touches.first {
|
||||
let touchLocation = touch.location(in: superview)
|
||||
storedLocation = touchLocation
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
super.touchesMoved(touches, with: event)
|
||||
|
||||
// Move the KeyView based on touch movement in relocation mode
|
||||
if OnScreenKeyView.relocationMode {
|
||||
if let touch = touches.first {
|
||||
let currentLocation = touch.location(in: superview)
|
||||
let offsetX = currentLocation.x - storedLocation.x
|
||||
let offsetY = currentLocation.y - storedLocation.y
|
||||
|
||||
center = CGPoint(x: center.x + offsetX, y: center.y + offsetY)
|
||||
storedLocation = currentLocation // Update initial center for next movement
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
super.touchesEnded(touches, with: event)
|
||||
self.backgroundColor = self.originalBackgroundColor
|
||||
if !OnScreenKeyView.relocationMode { LiSendKeyboardEvent(CommandManager.keyMappings[self.keyString]!,Int8(KEY_ACTION_UP), 0) }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user