Merge remote-tracking branch 'refs/remotes/upstream/Integration' into feat/frame_pacing_metal
# Conflicts: # VoidLink.xcodeproj/project.pbxproj # VoidLink/Input/PureNativeTouchHandler.m # VoidLink/Input/StreamView.m # VoidLink/UIComputerView.m
This commit is contained in:
commit
238d17020b
30 files changed
+367
-571
No files matched your search
@@ -78,7 +78,6 @@
|
|||||||
DC1F5A07206436B20037755F /* ConnectionHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1F5A06206436B20037755F /* ConnectionHelper.m */; };
|
DC1F5A07206436B20037755F /* ConnectionHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1F5A06206436B20037755F /* ConnectionHelper.m */; };
|
||||||
F74BEF9C2C1A705600224667 /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = F74BEF9B2C1A705600224667 /* OpenSSL */; };
|
F74BEF9C2C1A705600224667 /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = F74BEF9B2C1A705600224667 /* OpenSSL */; };
|
||||||
FB1A674D2131E65900507771 /* KeyboardSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1A674C2131E65900507771 /* KeyboardSupport.m */; };
|
FB1A674D2131E65900507771 /* KeyboardSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1A674C2131E65900507771 /* KeyboardSupport.m */; };
|
||||||
FB1D59971BBCCB6400F482CA /* ComputerScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1D59961BBCCB6400F482CA /* ComputerScrollView.m */; };
|
|
||||||
FB1D599A1BBCCD7E00F482CA /* AppCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */; };
|
FB1D599A1BBCCD7E00F482CA /* AppCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */; };
|
||||||
FB290CF219B2C406004C83CF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290CF119B2C406004C83CF /* Foundation.framework */; };
|
FB290CF219B2C406004C83CF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290CF119B2C406004C83CF /* Foundation.framework */; };
|
||||||
FB290CF419B2C406004C83CF /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290CF319B2C406004C83CF /* CoreGraphics.framework */; };
|
FB290CF419B2C406004C83CF /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290CF319B2C406004C83CF /* CoreGraphics.framework */; };
|
||||||
@@ -123,7 +122,6 @@
|
|||||||
FBD3495019FF2174002D2A60 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3494F19FF2174002D2A60 /* SettingsViewController.m */; };
|
FBD3495019FF2174002D2A60 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3494F19FF2174002D2A60 /* SettingsViewController.m */; };
|
||||||
FBD3495319FF36FB002D2A60 /* SWRevealViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3495219FF36FB002D2A60 /* SWRevealViewController.m */; };
|
FBD3495319FF36FB002D2A60 /* SWRevealViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD3495219FF36FB002D2A60 /* SWRevealViewController.m */; };
|
||||||
FBD349621A0089F6002D2A60 /* DataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD349611A0089F6002D2A60 /* DataManager.m */; };
|
FBD349621A0089F6002D2A60 /* DataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FBD349611A0089F6002D2A60 /* DataManager.m */; };
|
||||||
FBDE86E019F7A837001C18A8 /* UIComputerView.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86DF19F7A837001C18A8 /* UIComputerView.m */; };
|
|
||||||
FBDE86E619F82297001C18A8 /* UIAppView.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86E519F82297001C18A8 /* UIAppView.m */; };
|
FBDE86E619F82297001C18A8 /* UIAppView.m in Sources */ = {isa = PBXBuildFile; fileRef = FBDE86E519F82297001C18A8 /* UIAppView.m */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
@@ -290,8 +288,6 @@
|
|||||||
FB1A67642132419A00507771 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
FB1A67642132419A00507771 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||||
FB1A67E421324A1F00507771 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS11.4.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; };
|
FB1A67E421324A1F00507771 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS11.4.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
FB1A67E921324DF300507771 /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS11.4.sdk/usr/lib/libxml2.tbd; sourceTree = DEVELOPER_DIR; };
|
FB1A67E921324DF300507771 /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS11.4.sdk/usr/lib/libxml2.tbd; sourceTree = DEVELOPER_DIR; };
|
||||||
FB1D59951BBCCB6400F482CA /* ComputerScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComputerScrollView.h; sourceTree = "<group>"; };
|
|
||||||
FB1D59961BBCCB6400F482CA /* ComputerScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ComputerScrollView.m; sourceTree = "<group>"; };
|
|
||||||
FB1D59981BBCCD7E00F482CA /* AppCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppCollectionView.h; sourceTree = "<group>"; };
|
FB1D59981BBCCD7E00F482CA /* AppCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppCollectionView.h; sourceTree = "<group>"; };
|
||||||
FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppCollectionView.m; sourceTree = "<group>"; };
|
FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppCollectionView.m; sourceTree = "<group>"; };
|
||||||
FB290CEE19B2C406004C83CF /* VoidLink.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VoidLink.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
FB290CEE19B2C406004C83CF /* VoidLink.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VoidLink.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@@ -376,8 +372,6 @@
|
|||||||
FBD3495219FF36FB002D2A60 /* SWRevealViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWRevealViewController.m; sourceTree = "<group>"; };
|
FBD3495219FF36FB002D2A60 /* SWRevealViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWRevealViewController.m; sourceTree = "<group>"; };
|
||||||
FBD349601A0089F6002D2A60 /* DataManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DataManager.h; path = Database/DataManager.h; sourceTree = "<group>"; };
|
FBD349601A0089F6002D2A60 /* DataManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DataManager.h; path = Database/DataManager.h; sourceTree = "<group>"; };
|
||||||
FBD349611A0089F6002D2A60 /* DataManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DataManager.m; path = Database/DataManager.m; sourceTree = "<group>"; };
|
FBD349611A0089F6002D2A60 /* DataManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DataManager.m; path = Database/DataManager.m; sourceTree = "<group>"; };
|
||||||
FBDE86DE19F7A837001C18A8 /* UIComputerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIComputerView.h; sourceTree = "<group>"; };
|
|
||||||
FBDE86DF19F7A837001C18A8 /* UIComputerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIComputerView.m; sourceTree = "<group>"; };
|
|
||||||
FBDE86E419F82297001C18A8 /* UIAppView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAppView.h; sourceTree = "<group>"; };
|
FBDE86E419F82297001C18A8 /* UIAppView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAppView.h; sourceTree = "<group>"; };
|
||||||
FBDE86E519F82297001C18A8 /* UIAppView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAppView.m; sourceTree = "<group>"; };
|
FBDE86E519F82297001C18A8 /* UIAppView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAppView.m; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
@@ -619,8 +613,6 @@
|
|||||||
841BAC912DE35D6B00DA639E /* ThemeManager.m */,
|
841BAC912DE35D6B00DA639E /* ThemeManager.m */,
|
||||||
847D2FD82DDA00C800937A62 /* MenuSectionView.h */,
|
847D2FD82DDA00C800937A62 /* MenuSectionView.h */,
|
||||||
847D2FDA2DDA015F00937A62 /* MenuSectionView.m */,
|
847D2FDA2DDA015F00937A62 /* MenuSectionView.m */,
|
||||||
FBDE86DE19F7A837001C18A8 /* UIComputerView.h */,
|
|
||||||
FBDE86DF19F7A837001C18A8 /* UIComputerView.m */,
|
|
||||||
FBDE86E419F82297001C18A8 /* UIAppView.h */,
|
FBDE86E419F82297001C18A8 /* UIAppView.h */,
|
||||||
FBDE86E519F82297001C18A8 /* UIAppView.m */,
|
FBDE86E519F82297001C18A8 /* UIAppView.m */,
|
||||||
1888C1902E24C2C800108730 /* AboutView.swift */,
|
1888C1902E24C2C800108730 /* AboutView.swift */,
|
||||||
@@ -628,8 +620,6 @@
|
|||||||
FB89463719F6473800339C8A /* Launch Screen.xib */,
|
FB89463719F6473800339C8A /* Launch Screen.xib */,
|
||||||
FB290D0819B2C406004C83CF /* Images.xcassets */,
|
FB290D0819B2C406004C83CF /* Images.xcassets */,
|
||||||
FB290D0519B2C406004C83CF /* Limelight.xcdatamodeld */,
|
FB290D0519B2C406004C83CF /* Limelight.xcdatamodeld */,
|
||||||
FB1D59951BBCCB6400F482CA /* ComputerScrollView.h */,
|
|
||||||
FB1D59961BBCCB6400F482CA /* ComputerScrollView.m */,
|
|
||||||
FB1D59981BBCCD7E00F482CA /* AppCollectionView.h */,
|
FB1D59981BBCCD7E00F482CA /* AppCollectionView.h */,
|
||||||
FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */,
|
FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */,
|
||||||
843E93BD2C41528700B1651F /* OrientationHelper.swift */,
|
843E93BD2C41528700B1651F /* OrientationHelper.swift */,
|
||||||
@@ -1019,7 +1009,6 @@
|
|||||||
84351B112C29ACCB00A77989 /* OSCProfilesManager.m in Sources */,
|
84351B112C29ACCB00A77989 /* OSCProfilesManager.m in Sources */,
|
||||||
FB89462919F646E200339C8A /* mkcert.c in Sources */,
|
FB89462919F646E200339C8A /* mkcert.c in Sources */,
|
||||||
FB9AFD281A7C84ED00872C98 /* HttpResponse.m in Sources */,
|
FB9AFD281A7C84ED00872C98 /* HttpResponse.m in Sources */,
|
||||||
FBDE86E019F7A837001C18A8 /* UIComputerView.m in Sources */,
|
|
||||||
FB89463019F646E200339C8A /* StreamConfiguration.m in Sources */,
|
FB89463019F646E200339C8A /* StreamConfiguration.m in Sources */,
|
||||||
FBD3495319FF36FB002D2A60 /* SWRevealViewController.m in Sources */,
|
FBD3495319FF36FB002D2A60 /* SWRevealViewController.m in Sources */,
|
||||||
84203F232C5F24C00032EEED /* OnScreenWidgetView.swift in Sources */,
|
84203F232C5F24C00032EEED /* OnScreenWidgetView.swift in Sources */,
|
||||||
@@ -1027,7 +1016,6 @@
|
|||||||
9777AAF32E2CF7A400D7FBAF /* Shaders-Linear.metal in Sources */,
|
9777AAF32E2CF7A400D7FBAF /* Shaders-Linear.metal in Sources */,
|
||||||
84FD0B512C31338D006B5BE5 /* LocalizationHelper.m in Sources */,
|
84FD0B512C31338D006B5BE5 /* LocalizationHelper.m in Sources */,
|
||||||
97E20DEA2E216532000D5DCA /* SceneDelegate.m in Sources */,
|
97E20DEA2E216532000D5DCA /* SceneDelegate.m in Sources */,
|
||||||
FB1D59971BBCCB6400F482CA /* ComputerScrollView.m in Sources */,
|
|
||||||
FBD3495019FF2174002D2A60 /* SettingsViewController.m in Sources */,
|
FBD3495019FF2174002D2A60 /* SettingsViewController.m in Sources */,
|
||||||
843CC7F02C1E757D00BBC475 /* NativeTouchPointer.m in Sources */,
|
843CC7F02C1E757D00BBC475 /* NativeTouchPointer.m in Sources */,
|
||||||
FB89462C19F646E200339C8A /* HttpManager.m in Sources */,
|
FB89462C19F646E200339C8A /* HttpManager.m in Sources */,
|
||||||
@@ -1292,7 +1280,7 @@
|
|||||||
"$(PROJECT_DIR)/libs/SDL2/lib/iOS-Sim",
|
"$(PROJECT_DIR)/libs/SDL2/lib/iOS-Sim",
|
||||||
"$(PROJECT_DIR)/libs/FFmpeg/lib/iOS-Sim",
|
"$(PROJECT_DIR)/libs/FFmpeg/lib/iOS-Sim",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.0;
|
MARKETING_VERSION = 0.0.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.voidlink.tf.debug10.iOS;
|
PRODUCT_BUNDLE_IDENTIFIER = com.voidlink.tf.debug10.iOS;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE = "";
|
PROVISIONING_PROFILE = "";
|
||||||
@@ -1357,7 +1345,7 @@
|
|||||||
"$(PROJECT_DIR)/libs/SDL2/lib/iOS-Sim",
|
"$(PROJECT_DIR)/libs/SDL2/lib/iOS-Sim",
|
||||||
"$(PROJECT_DIR)/libs/FFmpeg/lib/iOS-Sim",
|
"$(PROJECT_DIR)/libs/FFmpeg/lib/iOS-Sim",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.0;
|
MARKETING_VERSION = 0.0.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.voidlink.tf.iOS;
|
PRODUCT_BUNDLE_IDENTIFIER = com.voidlink.tf.iOS;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE = "";
|
PROVISIONING_PROFILE = "";
|
||||||
|
|||||||
@@ -10,8 +10,10 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@available(iOS 13.0, *)
|
@available(iOS 13.0, *)
|
||||||
|
|
||||||
public struct AboutView: View {
|
public struct AboutView: View {
|
||||||
@Environment(\.presentationMode) var presentationMode
|
@Environment(\.presentationMode) var presentationMode
|
||||||
|
public var aboutVC:UIViewController
|
||||||
|
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
VStack(spacing: 10) {
|
VStack(spacing: 10) {
|
||||||
@@ -56,19 +58,18 @@ public struct AboutView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 链接按钮
|
// 链接按钮
|
||||||
if #available(iOS 14.0, *) {
|
if #available(iOS 14.0, *) {
|
||||||
Link(SwiftLocalizationHelper.localizedString(forKey: "Join us"), destination: URL(string: SwiftLocalizationHelper.localizedString(forKey: "supportLink"))!)
|
Link(SwiftLocalizationHelper.localizedString(forKey: "Join us"), destination: URL(string: SwiftLocalizationHelper.localizedString(forKey: "supportLink"))!)
|
||||||
.padding(.top, 10)
|
.padding(.top, 10)
|
||||||
Spacer()
|
Spacer()
|
||||||
// OK 按钮
|
// OK 按钮
|
||||||
Button("OK") {
|
Button(SwiftLocalizationHelper.localizedString(forKey: "OK")) {
|
||||||
presentationMode.wrappedValue.dismiss()
|
aboutVC.dismiss(animated:true)
|
||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
.background(Color.blue)
|
.background(Color.blue)
|
||||||
.foregroundColor(.white)
|
.foregroundColor(.white)
|
||||||
.frame(height: 46)
|
.frame(height: 46)
|
||||||
//.frame(width: 100)
|
|
||||||
.cornerRadius(12)
|
.cornerRadius(12)
|
||||||
} else {
|
} else {
|
||||||
HStack(spacing: 20) {
|
HStack(spacing: 20) {
|
||||||
@@ -84,8 +85,8 @@ public struct AboutView: View {
|
|||||||
.cornerRadius(12)
|
.cornerRadius(12)
|
||||||
.frame(height: 33)
|
.frame(height: 33)
|
||||||
.frame(minWidth: 100)
|
.frame(minWidth: 100)
|
||||||
|
/*
|
||||||
Button("OK") {
|
Button(SwiftLocalizationHelper.localizedString(forKey: "OK")) {
|
||||||
presentationMode.wrappedValue.dismiss()
|
presentationMode.wrappedValue.dismiss()
|
||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
@@ -93,7 +94,15 @@ public struct AboutView: View {
|
|||||||
.foregroundColor(.white)
|
.foregroundColor(.white)
|
||||||
.cornerRadius(12)
|
.cornerRadius(12)
|
||||||
.frame(height: 33)
|
.frame(height: 33)
|
||||||
.frame(minWidth: 100)
|
.frame(minWidth: 100)*/
|
||||||
|
Button(SwiftLocalizationHelper.localizedString(forKey: "OK")) {
|
||||||
|
aboutVC.dismiss(animated:true)
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.background(Color.blue)
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.cornerRadius(12)
|
||||||
|
.frame(height: 33)
|
||||||
}
|
}
|
||||||
.padding(.top, 10)
|
.padding(.top, 10)
|
||||||
}
|
}
|
||||||
@@ -101,3 +110,4 @@ public struct AboutView: View {
|
|||||||
.padding()
|
.padding()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,8 +13,9 @@ import SwiftUI
|
|||||||
@objc class AboutViewController: UIViewController {
|
@objc class AboutViewController: UIViewController {
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
let hostingVC = UIHostingController(rootView: AboutView())
|
let hostingVC = UIHostingController(rootView: AboutView( aboutVC: self))
|
||||||
|
|
||||||
addChild(hostingVC)
|
addChild(hostingVC)
|
||||||
hostingVC.view.translatesAutoresizingMaskIntoConstraints = false
|
hostingVC.view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
view.addSubview(hostingVC.view)
|
view.addSubview(hostingVC.view)
|
||||||
@@ -29,7 +30,6 @@ import SwiftUI
|
|||||||
|
|
||||||
// 🎯 设置弹窗大小
|
// 🎯 设置弹窗大小
|
||||||
preferredContentSize = CGSize(width: 530, height: 450)
|
preferredContentSize = CGSize(width: 530, height: 450)
|
||||||
//preferredContentSize = CGSize(width:150, height:120 )
|
|
||||||
|
|
||||||
// ⚠️ 一定要设置以下样式才会生效 preferredContentSize
|
// ⚠️ 一定要设置以下样式才会生效 preferredContentSize
|
||||||
modalPresentationStyle = .formSheet
|
modalPresentationStyle = .formSheet
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
//
|
|
||||||
// ComputerScrollView.h
|
|
||||||
// Moonlight
|
|
||||||
//
|
|
||||||
// Created by Diego Waxemberg on 9/30/15.
|
|
||||||
// Copyright © 2015 Moonlight Stream. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
|
||||||
|
|
||||||
@interface ComputerScrollView : UIScrollView
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
//
|
|
||||||
// ComputerScrollView.m
|
|
||||||
// Moonlight
|
|
||||||
//
|
|
||||||
// Created by Diego Waxemberg on 9/30/15.
|
|
||||||
// Copyright © 2015 Moonlight Stream. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "ComputerScrollView.h"
|
|
||||||
|
|
||||||
@implementation ComputerScrollView
|
|
||||||
|
|
||||||
- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
|
|
||||||
if ([view isKindOfClass:[UIButton class]]) {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
return [super touchesShouldCancelInContentView:view];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Only override drawRect: if you perform custom drawing.
|
|
||||||
// An empty implementation adversely affects performance during animation.
|
|
||||||
- (void)drawRect:(CGRect)rect {
|
|
||||||
// Drawing code
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -505,7 +505,7 @@ static const float REFRESH_CYCLE = 2.0f;
|
|||||||
|
|
||||||
- (void) updateLoop {
|
- (void) updateLoop {
|
||||||
// Stop immediately if the view has been detached
|
// Stop immediately if the view has been detached
|
||||||
if (self.superview == nil) {
|
if (self.superview == nil || [self.delegate isStreaming]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,7 +514,7 @@ static const float REFRESH_CYCLE = 2.0f;
|
|||||||
[self updateContentsForHost:_host];
|
[self updateContentsForHost:_host];
|
||||||
|
|
||||||
// Queue the next refresh cycle
|
// Queue the next refresh cycle
|
||||||
if(![self.delegate isStreaming]) [self performSelector:@selector(updateLoop) withObject:self afterDelay:REFRESH_CYCLE];
|
[self performSelector:@selector(updateLoop) withObject:self afterDelay:REFRESH_CYCLE];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) updateContentsForHost:(TemporaryHost*)host {
|
- (void) updateContentsForHost:(TemporaryHost*)host {
|
||||||
|
|||||||
@@ -417,7 +417,7 @@ import UIKit
|
|||||||
print("No match found for input: \(input)")
|
print("No match found for input: \(input)")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
print("Regex matched for input: \(input)")
|
// print("Regex matched for input: \(input)")
|
||||||
|
|
||||||
let matchedString = (input as NSString).substring(with: match.range(at: 0))
|
let matchedString = (input as NSString).substring(with: match.range(at: 0))
|
||||||
let keyStrings = matchedString.split(separator: "+").map { String($0) }
|
let keyStrings = matchedString.split(separator: "+").map { String($0) }
|
||||||
@@ -475,7 +475,7 @@ import UIKit
|
|||||||
print("No match found for input: \(input)")
|
print("No match found for input: \(input)")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
print("Regex matched for input: \(input)")
|
// print("Regex matched for input: \(input)")
|
||||||
|
|
||||||
let matchedString = (input as NSString).substring(with: match.range(at: 0))
|
let matchedString = (input as NSString).substring(with: match.range(at: 0))
|
||||||
let cmdStrings = matchedString.split(separator: "-").map { String($0) }
|
let cmdStrings = matchedString.split(separator: "-").map { String($0) }
|
||||||
|
|||||||
@@ -22,8 +22,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
@property NSMutableArray <OSCProfile *> *currentProfiles;
|
@property NSMutableArray <OSCProfile *> *currentProfiles;
|
||||||
|
|
||||||
|
|
||||||
+ (OSCProfilesManager *) sharedManager:(CGRect)viewBounds;
|
+ (OSCProfilesManager *)sharedManager:(CGRect)viewBounds;
|
||||||
+ (void) setOnScreenWidgetViewsSet:(NSMutableSet* )set;
|
+ (void)setOnScreenWidgetViewsSet:(NSMutableSet* )set;
|
||||||
|
+ (void)setLayoutViewBounds:(CGRect)bounds;
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Getters
|
#pragma mark - Getters
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -18,15 +18,15 @@
|
|||||||
@implementation OSCProfilesManager
|
@implementation OSCProfilesManager
|
||||||
|
|
||||||
static NSMutableSet *OnScreenWidgetViews;
|
static NSMutableSet *OnScreenWidgetViews;
|
||||||
static CGRect streamViewBounds;
|
static CGRect layoutViewBounds;
|
||||||
|
|
||||||
#pragma mark - Initializer
|
#pragma mark - Initializer
|
||||||
|
|
||||||
+ (OSCProfilesManager *) sharedManager:(CGRect)viewBounds {
|
+ (OSCProfilesManager *) sharedManager:(CGRect)viewBounds {
|
||||||
static OSCProfilesManager *_sharedManager = nil;
|
static OSCProfilesManager *_sharedManager = nil;
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
streamViewBounds = viewBounds;
|
layoutViewBounds = viewBounds;
|
||||||
NSLog(@"bounds width: %f, height: %f", streamViewBounds.size.width, streamViewBounds.size.height);
|
// NSLog(@"bounds width: %f, height: %f", layoutViewBounds.size.width, layoutViewBounds.size.height);
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
_sharedManager = [[self alloc] init];
|
_sharedManager = [[self alloc] init];
|
||||||
});
|
});
|
||||||
@@ -38,10 +38,14 @@ static CGRect streamViewBounds;
|
|||||||
#pragma mark - Class Helper Methods
|
#pragma mark - Class Helper Methods
|
||||||
|
|
||||||
|
|
||||||
+ (void) setOnScreenWidgetViewsSet:(NSMutableSet* )set{
|
+ (void)setOnScreenWidgetViewsSet:(NSMutableSet* )set{
|
||||||
OnScreenWidgetViews = set;
|
OnScreenWidgetViews = set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (void)setLayoutViewBounds:(CGRect)bounds{
|
||||||
|
layoutViewBounds = bounds;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the profile whose 'name' property has a value that is equal to the 'name' passed into the method
|
* Returns the profile whose 'name' property has a value that is equal to the 'name' passed into the method
|
||||||
*/
|
*/
|
||||||
@@ -297,17 +301,21 @@ static CGRect streamViewBounds;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (CGPoint)normalizeWidgetPosition:(CGPoint)position {
|
- (CGPoint)normalizeWidgetPosition:(CGPoint)position {
|
||||||
|
CGPoint newPosition = position;
|
||||||
if(position.x > 1.0 && position.y >1.0){
|
if(position.x > 1.0 && position.y >1.0){
|
||||||
position.x = position.x / streamViewBounds.size.width;
|
position.x = position.x / layoutViewBounds.size.width;
|
||||||
position.y = position.y / streamViewBounds.size.height;
|
position.y = position.y / layoutViewBounds.size.height;
|
||||||
}
|
}
|
||||||
|
// asdfsda;
|
||||||
|
NSLog(@"sef.view bounds: %f, %f", layoutViewBounds.size.width, layoutViewBounds.size.height);
|
||||||
|
NSLog(@"position: %f, %f, denormalized position: %f, %f", position.x, position.y, newPosition.x, newPosition.y);
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGPoint)denormalizeWidgetPosition:(CGPoint)position {
|
- (CGPoint)denormalizeWidgetPosition:(CGPoint)position {
|
||||||
if(position.x < 1.0 && position.y < 1.0){
|
if(position.x < 1.0 && position.y < 1.0){
|
||||||
position.x = position.x * streamViewBounds.size.width;
|
position.x = position.x * layoutViewBounds.size.width;
|
||||||
position.y = position.y * streamViewBounds.size.height;
|
position.y = position.y * layoutViewBounds.size.height;
|
||||||
}
|
}
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
NSMutableSet<NSNumber *> *pointerIdPool; //pre-defined pool of pointerIds.
|
NSMutableSet<NSNumber *> *pointerIdPool; //pre-defined pool of pointerIds.
|
||||||
NSMutableSet<NSNumber *> *unassignedPointerIds;
|
NSMutableSet<NSNumber *> *unassignedPointerIds;
|
||||||
NSMutableSet *blacklistedTouches;
|
NSMutableSet *blacklistedTouches;
|
||||||
bool doNotBlockTouchEvents;
|
|
||||||
|
|
||||||
NSMutableDictionary *pointerObjDict;
|
NSMutableDictionary *pointerObjDict;
|
||||||
|
|
||||||
@@ -61,7 +60,6 @@
|
|||||||
}
|
}
|
||||||
self->activePointerIds = [NSMutableSet set];
|
self->activePointerIds = [NSMutableSet set];
|
||||||
self->blacklistedTouches = [NSMutableSet set];
|
self->blacklistedTouches = [NSMutableSet set];
|
||||||
doNotBlockTouchEvents = true;
|
|
||||||
|
|
||||||
self->asyncNativeTouch = settings.asyncNativeTouchPriority.intValue != AsyncNativeTouchOff;
|
self->asyncNativeTouch = settings.asyncNativeTouchPriority.intValue != AsyncNativeTouchOff;
|
||||||
|
|
||||||
@@ -160,15 +158,14 @@
|
|||||||
NSNumber* touchAddrObj = @((uintptr_t)touch);
|
NSNumber* touchAddrObj = @((uintptr_t)touch);
|
||||||
unassignedPointerIds = [pointerIdPool mutableCopy]; //reset unassignedPointerIds
|
unassignedPointerIds = [pointerIdPool mutableCopy]; //reset unassignedPointerIds
|
||||||
[unassignedPointerIds minusSet:activePointerIds];
|
[unassignedPointerIds minusSet:activePointerIds];
|
||||||
uint8_t pointerId = [[unassignedPointerIds anyObject] unsignedIntValue];
|
NSNumber* pointerIdObj = @([[unassignedPointerIds anyObject] unsignedIntValue]);
|
||||||
[pointerIdDict setObject:@(pointerId) forKey:touchAddrObj];
|
[pointerIdDict setObject:pointerIdObj forKey:touchAddrObj];
|
||||||
[activePointerIds addObject:@(pointerId)];
|
[activePointerIds addObject:pointerIdObj];
|
||||||
|
|
||||||
//check if touch point is spawned on the left or right upper half screen edges, event to remote PC. this is for better handling in-stream slide gesture
|
//check if touch point is spawned on the left or right upper half screen edges, event to remote PC. this is for better handling in-stream slide gesture
|
||||||
CGPoint initialPoint = [touch locationInView:self->streamView];
|
CGPoint initialPoint = [touch locationInView:self->streamView];
|
||||||
if(initialPoint.y < slideGestureVerticalThreshold && (initialPoint.x < EDGE_TOLERANCE || initialPoint.x > screenWidthWithThreshold)) {
|
if(initialPoint.y < slideGestureVerticalThreshold && (initialPoint.x < EDGE_TOLERANCE || initialPoint.x > screenWidthWithThreshold)) {
|
||||||
doNotBlockTouchEvents = false;
|
[blacklistedTouches addObject:touchAddrObj];
|
||||||
// [blacklistedTouches addObject:touchAddrObj];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,8 +189,8 @@
|
|||||||
|
|
||||||
- (void)sendTouchEvent:(UITouch*)touch withTouchtype:(uint8_t)touchType{
|
- (void)sendTouchEvent:(UITouch*)touch withTouchtype:(uint8_t)touchType{
|
||||||
//if(touchPointSpawnedAtUpperScreenEdge && touchType != LI_TOUCH_EVENT_UP) return; // we're done here. this touch event will not be sent to the remote PC. and this must be checked after coord selector finishes populating new relative coords, or the app will crash
|
//if(touchPointSpawnedAtUpperScreenEdge && touchType != LI_TOUCH_EVENT_UP) return; // we're done here. this touch event will not be sent to the remote PC. and this must be checked after coord selector finishes populating new relative coords, or the app will crash
|
||||||
// if([blacklistedTouches containsObject:@((uintptr_t)touch)]) return;
|
if([blacklistedTouches containsObject:@((uintptr_t)touch)]) return;
|
||||||
|
|
||||||
CGPoint targetCoords;
|
CGPoint targetCoords;
|
||||||
//NSLog(@"selecting coords: %d", touch.phase == UITouchPhaseMoved);
|
//NSLog(@"selecting coords: %d", touch.phase == UITouchPhaseMoved);
|
||||||
// NSLog(@"excluded count: %d", (uint32_t)[excludedPointerIds count]);
|
// NSLog(@"excluded count: %d", (uint32_t)[excludedPointerIds count]);
|
||||||
@@ -239,7 +236,7 @@
|
|||||||
// continue to the next loop if current touch is already captured by OSC. works only in regular native touch
|
// continue to the next loop if current touch is already captured by OSC. works only in regular native touch
|
||||||
if([OnScreenControls.touchAddrsCapturedByOnScreenControls containsObject:@((uintptr_t)touch)]) continue;
|
if([OnScreenControls.touchAddrsCapturedByOnScreenControls containsObject:@((uintptr_t)touch)]) continue;
|
||||||
if(self->activateCoordSelector) [self updatePointerObjInDict:touch];
|
if(self->activateCoordSelector) [self updatePointerObjInDict:touch];
|
||||||
if(self->doNotBlockTouchEvents) [self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_MOVE];
|
[self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_MOVE];
|
||||||
[[self getPointerObjFromDict:touch] doesNeedResetCoords]; // execute the judging of doesReachBoundary for current pointer instance. (happens after the event is sent to Sunshine service)
|
[[self getPointerObjFromDict:touch] doesNeedResetCoords]; // execute the judging of doesReachBoundary for current pointer instance. (happens after the event is sent to Sunshine service)
|
||||||
usleep(self->touchMoveEventIntervalUs);
|
usleep(self->touchMoveEventIntervalUs);
|
||||||
}
|
}
|
||||||
@@ -265,9 +262,8 @@
|
|||||||
[self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_UP]; //send touch event before remove pointerId
|
[self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_UP]; //send touch event before remove pointerId
|
||||||
[self removePointerId:touch]; //then remove pointerId
|
[self removePointerId:touch]; //then remove pointerId
|
||||||
if(self->activateCoordSelector) [self removePointerObjFromDict:touch];
|
if(self->activateCoordSelector) [self removePointerObjFromDict:touch];
|
||||||
//[self->blacklistedTouches removeObject:@((uintptr_t)touch)];
|
[self->blacklistedTouches removeObject:@((uintptr_t)touch)];
|
||||||
}
|
}
|
||||||
self->doNotBlockTouchEvents = true;
|
|
||||||
//if(self->touchPointSpawnedAtUpperScreenEdge && [[event allTouches] count] == [touches count])
|
//if(self->touchPointSpawnedAtUpperScreenEdge && [[event allTouches] count] == [touches count])
|
||||||
});
|
});
|
||||||
else{
|
else{
|
||||||
@@ -297,10 +293,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)removePointerObjFromDict:(UITouch*)touch{
|
- (void)removePointerObjFromDict:(UITouch*)touch{
|
||||||
uintptr_t memAddrValue = (uintptr_t)touch;
|
NSNumber* touchAddrObj = @((uintptr_t)touch);
|
||||||
NativeTouchPointer* pointer = [pointerObjDict objectForKey:@(memAddrValue)];
|
NativeTouchPointer* pointer = [pointerObjDict objectForKey:touchAddrObj];
|
||||||
if(pointer != nil){
|
if(pointer != nil){
|
||||||
[pointerObjDict removeObjectForKey:@(memAddrValue)];
|
[pointerObjDict removeObjectForKey:touchAddrObj];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ static float L3_Y;
|
|||||||
if(position.x < 1.0 && position.y < 1.0) {
|
if(position.x < 1.0 && position.y < 1.0) {
|
||||||
position.x = position.x * _view.bounds.size.width;
|
position.x = position.x * _view.bounds.size.width;
|
||||||
position.y = position.y * _view.bounds.size.height;
|
position.y = position.y * _view.bounds.size.height;
|
||||||
NSLog(@"denormalizing position: %f, %f", position.x, position.y);
|
// NSLog(@"denormalizing position: %f, %f", position.x, position.y);
|
||||||
}
|
}
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
@@ -1560,7 +1560,7 @@ static float L3_Y;
|
|||||||
// on screen at the time
|
// on screen at the time
|
||||||
|
|
||||||
// DZ capturing shall be refactored in CustomOSC Mode & non-default profile condition
|
// DZ capturing shall be refactored in CustomOSC Mode & non-default profile condition
|
||||||
if(self._level == OnScreenControlsLevelCustom && [profilesManager getIndexOfSelectedProfile] != 0){
|
if(self._level == OnScreenControlsLevelCustom){
|
||||||
CGPoint touchLocation = [touch locationInView:_view];
|
CGPoint touchLocation = [touch locationInView:_view];
|
||||||
for (NSString *key in _activeCustomOscButtonPositionDict) {
|
for (NSString *key in _activeCustomOscButtonPositionDict) {
|
||||||
NSValue *value = _activeCustomOscButtonPositionDict[key];
|
NSValue *value = _activeCustomOscButtonPositionDict[key];
|
||||||
@@ -1930,7 +1930,7 @@ static float L3_Y;
|
|||||||
if(alpha < 0.23) targetAlpha = 0.23;
|
if(alpha < 0.23) targetAlpha = 0.23;
|
||||||
if(alpha == 0.0 || alpha == 1.0) targetAlpha = 5.0f/6.0f; // invalid alpha value
|
if(alpha == 0.0 || alpha == 1.0) targetAlpha = 5.0f/6.0f; // invalid alpha value
|
||||||
|
|
||||||
NSLog(@"alphas: %f",targetAlpha);
|
// NSLog(@"alphas: %f",targetAlpha);
|
||||||
|
|
||||||
if (layer == self._aButton ||
|
if (layer == self._aButton ||
|
||||||
layer == self._bButton ||
|
layer == self._bButton ||
|
||||||
|
|||||||
@@ -472,7 +472,7 @@ import UIKit
|
|||||||
if vibrationOn {
|
if vibrationOn {
|
||||||
vibrationGenerator.prepare()
|
vibrationGenerator.prepare()
|
||||||
vibrationGenerator.impactOccurred()
|
vibrationGenerator.impactOccurred()
|
||||||
print("vibrationInstance: \(vibrationGenerator)")
|
// print("vibrationInstance: \(vibrationGenerator)")
|
||||||
}
|
}
|
||||||
|
|
||||||
return indicatorBorder
|
return indicatorBorder
|
||||||
@@ -864,7 +864,7 @@ import UIKit
|
|||||||
if vibrationOn {
|
if vibrationOn {
|
||||||
vibrationGenerator.prepare()
|
vibrationGenerator.prepare()
|
||||||
vibrationGenerator.impactOccurred()
|
vibrationGenerator.impactOccurred()
|
||||||
print("vibrationInstance: \(vibrationGenerator)")
|
// print("vibrationInstance: \(vibrationGenerator)")
|
||||||
}
|
}
|
||||||
CATransaction.commit()
|
CATransaction.commit()
|
||||||
}
|
}
|
||||||
@@ -1138,8 +1138,8 @@ import UIKit
|
|||||||
let offsetX = currentLocation.x - latestTouchLocation.x;
|
let offsetX = currentLocation.x - latestTouchLocation.x;
|
||||||
let offsetY = currentLocation.y - latestTouchLocation.y;
|
let offsetY = currentLocation.y - latestTouchLocation.y;
|
||||||
|
|
||||||
let outOfBoundsX = center.x+offsetX > (self.superview?.bounds.width)! || center.x+offsetX < 0
|
let outOfBoundsX = center.x+offsetX >= (self.superview?.bounds.width)! || center.x+offsetX < 0
|
||||||
let outOfBoundsY = center.y+offsetY > (self.superview?.bounds.height)! || center.y+offsetY < 0
|
let outOfBoundsY = center.y+offsetY >= (self.superview?.bounds.height)! || center.y+offsetY < 0
|
||||||
|
|
||||||
center = CGPoint(x: outOfBoundsX ? center.x : center.x+offsetX, y: outOfBoundsY ? center.y : center.y+offsetY)
|
center = CGPoint(x: outOfBoundsX ? center.x : center.x+offsetX, y: outOfBoundsY ? center.y : center.y+offsetY)
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,6 @@
|
|||||||
NSMutableSet<NSNumber *> *pointerIdPool; //pre-defined pool of pointerIds.
|
NSMutableSet<NSNumber *> *pointerIdPool; //pre-defined pool of pointerIds.
|
||||||
NSMutableSet<NSNumber *> *unassignedPointerIds;
|
NSMutableSet<NSNumber *> *unassignedPointerIds;
|
||||||
NSMutableSet *blacklistedTouches;
|
NSMutableSet *blacklistedTouches;
|
||||||
bool doNotBlockTouchEvents;
|
|
||||||
|
|
||||||
NSMutableDictionary *pointerObjDict;
|
NSMutableDictionary *pointerObjDict;
|
||||||
|
|
||||||
@@ -60,8 +59,7 @@
|
|||||||
}
|
}
|
||||||
self->activePointerIds = [NSMutableSet set];
|
self->activePointerIds = [NSMutableSet set];
|
||||||
self->blacklistedTouches = [NSMutableSet set];
|
self->blacklistedTouches = [NSMutableSet set];
|
||||||
doNotBlockTouchEvents = true;
|
|
||||||
|
|
||||||
self->asyncNativeTouch = settings.asyncNativeTouchPriority.intValue != AsyncNativeTouchOff;
|
self->asyncNativeTouch = settings.asyncNativeTouchPriority.intValue != AsyncNativeTouchOff;
|
||||||
|
|
||||||
switch(settings.asyncNativeTouchPriority.intValue){
|
switch(settings.asyncNativeTouchPriority.intValue){
|
||||||
@@ -159,15 +157,14 @@
|
|||||||
NSNumber* touchAddrObj = @((uintptr_t)touch);
|
NSNumber* touchAddrObj = @((uintptr_t)touch);
|
||||||
unassignedPointerIds = [pointerIdPool mutableCopy]; //reset unassignedPointerIds
|
unassignedPointerIds = [pointerIdPool mutableCopy]; //reset unassignedPointerIds
|
||||||
[unassignedPointerIds minusSet:activePointerIds];
|
[unassignedPointerIds minusSet:activePointerIds];
|
||||||
uint8_t pointerId = [[unassignedPointerIds anyObject] unsignedIntValue];
|
NSNumber* pointerIdObj = @([[unassignedPointerIds anyObject] unsignedIntValue]);
|
||||||
[pointerIdDict setObject:@(pointerId) forKey:touchAddrObj];
|
[pointerIdDict setObject:pointerIdObj forKey:touchAddrObj];
|
||||||
[activePointerIds addObject:@(pointerId)];
|
[activePointerIds addObject:pointerIdObj];
|
||||||
|
|
||||||
//check if touch point is spawned on the left or right upper half screen edges, event to remote PC. this is for better handling in-stream slide gesture
|
//check if touch point is spawned on the left or right upper half screen edges, event to remote PC. this is for better handling in-stream slide gesture
|
||||||
CGPoint initialPoint = [touch locationInView:self->streamView];
|
CGPoint initialPoint = [touch locationInView:self->streamView];
|
||||||
if(initialPoint.y < slideGestureVerticalThreshold && (initialPoint.x < EDGE_TOLERANCE || initialPoint.x > screenWidthWithThreshold)) {
|
if(initialPoint.y < slideGestureVerticalThreshold && (initialPoint.x < EDGE_TOLERANCE || initialPoint.x > screenWidthWithThreshold)) {
|
||||||
doNotBlockTouchEvents = false;
|
[blacklistedTouches addObject:touchAddrObj];
|
||||||
// [blacklistedTouches addObject:touchAddrObj];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,8 +188,8 @@
|
|||||||
|
|
||||||
- (void)sendTouchEvent:(UITouch*)touch withTouchtype:(uint8_t)touchType{
|
- (void)sendTouchEvent:(UITouch*)touch withTouchtype:(uint8_t)touchType{
|
||||||
//if(touchPointSpawnedAtUpperScreenEdge && touchType != LI_TOUCH_EVENT_UP) return; // we're done here. this touch event will not be sent to the remote PC. and this must be checked after coord selector finishes populating new relative coords, or the app will crash
|
//if(touchPointSpawnedAtUpperScreenEdge && touchType != LI_TOUCH_EVENT_UP) return; // we're done here. this touch event will not be sent to the remote PC. and this must be checked after coord selector finishes populating new relative coords, or the app will crash
|
||||||
// if([blacklistedTouches containsObject:@((uintptr_t)touch)]) return;
|
if([blacklistedTouches containsObject:@((uintptr_t)touch)]) return;
|
||||||
|
|
||||||
CGPoint targetCoords;
|
CGPoint targetCoords;
|
||||||
//NSLog(@"selecting coords: %d", touch.phase == UITouchPhaseMoved);
|
//NSLog(@"selecting coords: %d", touch.phase == UITouchPhaseMoved);
|
||||||
// NSLog(@"excluded count: %d", (uint32_t)[excludedPointerIds count]);
|
// NSLog(@"excluded count: %d", (uint32_t)[excludedPointerIds count]);
|
||||||
@@ -235,14 +232,13 @@
|
|||||||
for (UITouch* touch in touches){
|
for (UITouch* touch in touches){
|
||||||
// continue to the next loop if current touch is already captured by OSC. works only in regular native touch
|
// continue to the next loop if current touch is already captured by OSC. works only in regular native touch
|
||||||
if(self->activateCoordSelector) [self updatePointerObjInDict:touch];
|
if(self->activateCoordSelector) [self updatePointerObjInDict:touch];
|
||||||
if(self->doNotBlockTouchEvents) [self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_MOVE];
|
[self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_MOVE];
|
||||||
[[self getPointerObjFromDict:touch] doesNeedResetCoords]; // execute the judging of doesReachBoundary for current pointer instance. (happens after the event is sent to Sunshine service)
|
[[self getPointerObjFromDict:touch] doesNeedResetCoords]; // execute the judging of doesReachBoundary for current pointer instance. (happens after the event is sent to Sunshine service)
|
||||||
usleep(self->touchMoveEventIntervalUs);
|
usleep(self->touchMoveEventIntervalUs);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
else {
|
else {
|
||||||
for (UITouch* touch in touches){
|
for (UITouch* touch in touches){
|
||||||
// continue to the next loop if current touch is already captured by OSC. works only in regular native touch
|
|
||||||
if(self->activateCoordSelector) [self updatePointerObjInDict:touch];
|
if(self->activateCoordSelector) [self updatePointerObjInDict:touch];
|
||||||
[self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_MOVE];
|
[self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_MOVE];
|
||||||
[[self getPointerObjFromDict:touch] doesNeedResetCoords]; // execute the judging of doesReachBoundary for current pointer instance. (happens after the event is sent to Sunshine service)
|
[[self getPointerObjFromDict:touch] doesNeedResetCoords]; // execute the judging of doesReachBoundary for current pointer instance. (happens after the event is sent to Sunshine service)
|
||||||
@@ -259,9 +255,8 @@
|
|||||||
[self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_UP]; //send touch event before remove pointerId
|
[self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_UP]; //send touch event before remove pointerId
|
||||||
[self removePointerId:touch]; //then remove pointerId
|
[self removePointerId:touch]; //then remove pointerId
|
||||||
if(self->activateCoordSelector) [self removePointerObjFromDict:touch];
|
if(self->activateCoordSelector) [self removePointerObjFromDict:touch];
|
||||||
//[self->blacklistedTouches removeObject:@((uintptr_t)touch)];
|
[self->blacklistedTouches removeObject:@((uintptr_t)touch)];
|
||||||
}
|
}
|
||||||
self->doNotBlockTouchEvents = true;
|
|
||||||
//if(self->touchPointSpawnedAtUpperScreenEdge && [[event allTouches] count] == [touches count])
|
//if(self->touchPointSpawnedAtUpperScreenEdge && [[event allTouches] count] == [touches count])
|
||||||
});
|
});
|
||||||
else{
|
else{
|
||||||
@@ -290,10 +285,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)removePointerObjFromDict:(UITouch*)touch{
|
- (void)removePointerObjFromDict:(UITouch*)touch{
|
||||||
uintptr_t memAddrValue = (uintptr_t)touch;
|
NSNumber* touchAddrObj = @((uintptr_t)touch);
|
||||||
NativeTouchPointer* pointer = [pointerObjDict objectForKey:@(memAddrValue)];
|
NativeTouchPointer* pointer = [pointerObjDict objectForKey:touchAddrObj];
|
||||||
if(pointer != nil){
|
if(pointer != nil){
|
||||||
[pointerObjDict removeObjectForKey:@(memAddrValue)];
|
[pointerObjDict removeObjectForKey:touchAddrObj];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,3 +303,4 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -36,6 +36,7 @@
|
|||||||
@property (assign, nonatomic) UIView* streamFrameTopLayerView;
|
@property (assign, nonatomic) UIView* streamFrameTopLayerView;
|
||||||
@property (assign, nonatomic) CGFloat streamAspectRatio;
|
@property (assign, nonatomic) CGFloat streamAspectRatio;
|
||||||
@property (assign, nonatomic) CGRect originalFrame;
|
@property (assign, nonatomic) CGRect originalFrame;
|
||||||
|
@property (assign, nonatomic) bool widgetToolOpened;
|
||||||
|
|
||||||
|
|
||||||
- (void) setupStreamView:(ControllerSupport*)controllerSupport
|
- (void) setupStreamView:(ControllerSupport*)controllerSupport
|
||||||
@@ -50,7 +51,7 @@
|
|||||||
andConfig:(StreamConfiguration*)streamConfig;
|
andConfig:(StreamConfiguration*)streamConfig;
|
||||||
- (void) reloadOnScreenControlsWith:(ControllerSupport*)controllerSupport
|
- (void) reloadOnScreenControlsWith:(ControllerSupport*)controllerSupport
|
||||||
andConfig:(StreamConfiguration*)streamConfig;
|
andConfig:(StreamConfiguration*)streamConfig;
|
||||||
- (void) clearOnScreenKeyboardButtons;
|
- (void) clearOnScreenWidgets;
|
||||||
- (void) reloadOnScreenWidgetViews;
|
- (void) reloadOnScreenWidgetViews;
|
||||||
|
|
||||||
- (CGSize) getVideoAreaSize;
|
- (CGSize) getVideoAreaSize;
|
||||||
|
|||||||
+38
-35
@@ -34,7 +34,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
@implementation StreamView {
|
@implementation StreamView {
|
||||||
UIView* streamFrameTopLayerView;
|
UIView* streamFrameTopLayerView;
|
||||||
TemporarySettings* settings;
|
TemporarySettings* settings;
|
||||||
|
|
||||||
OnScreenControls* onScreenControls;
|
OnScreenControls* onScreenControls;
|
||||||
|
|
||||||
KeyboardInputField* keyInputField;
|
KeyboardInputField* keyInputField;
|
||||||
@@ -43,7 +43,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
float streamAspectRatio;
|
float streamAspectRatio;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// iOS 13.4 mouse support
|
// iOS 13.4 mouse support
|
||||||
NSInteger lastMouseButtonMask;
|
NSInteger lastMouseButtonMask;
|
||||||
float lastMouseX;
|
float lastMouseX;
|
||||||
@@ -56,7 +56,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
double accumulatedMouseDeltaY;
|
double accumulatedMouseDeltaY;
|
||||||
|
|
||||||
int localMousePointerMode;
|
int localMousePointerMode;
|
||||||
|
|
||||||
UIResponder* touchHandler;
|
UIResponder* touchHandler;
|
||||||
|
|
||||||
id<UserInteractionDelegate> interactionDelegate;
|
id<UserInteractionDelegate> interactionDelegate;
|
||||||
@@ -72,7 +72,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
#endif
|
#endif
|
||||||
CGFloat HeightViewLiftedTo;
|
CGFloat HeightViewLiftedTo;
|
||||||
UILabel* keyboardToggleTip;
|
UILabel* keyboardToggleTip;
|
||||||
|
|
||||||
UIKeyModifierFlags comboKeyModifierFlags;
|
UIKeyModifierFlags comboKeyModifierFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,9 +87,9 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
self->interactionDelegate = interactionDelegate;
|
self->interactionDelegate = interactionDelegate;
|
||||||
self->streamAspectRatio = (float)streamConfig.width / (float)streamConfig.height;
|
self->streamAspectRatio = (float)streamConfig.width / (float)streamConfig.height;
|
||||||
self.streamAspectRatio = self->streamAspectRatio;
|
self.streamAspectRatio = self->streamAspectRatio;
|
||||||
|
|
||||||
settings = [[[DataManager alloc] init] getSettings];
|
settings = [[[DataManager alloc] init] getSettings];
|
||||||
|
|
||||||
localMousePointerMode = streamConfig.localMousePointerMode;
|
localMousePointerMode = streamConfig.localMousePointerMode;
|
||||||
|
|
||||||
keysDown = [[NSMutableSet alloc] init];
|
keysDown = [[NSMutableSet alloc] init];
|
||||||
@@ -114,18 +114,18 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
keyboardToggleTip.layer.cornerRadius = 10;
|
keyboardToggleTip.layer.cornerRadius = 10;
|
||||||
keyboardToggleTip.clipsToBounds = true;
|
keyboardToggleTip.clipsToBounds = true;
|
||||||
NSLog(@"setup streamView %f", CACurrentMediaTime());
|
NSLog(@"setup streamView %f", CACurrentMediaTime());
|
||||||
|
|
||||||
// if(settings.touchMode.intValue == NativeTouchOnly) [self addGestureRecognizer:keyboardToggleRecognizer]; //keep legacy approach in pure native mode
|
// if(settings.touchMode.intValue == NativeTouchOnly) [self addGestureRecognizer:keyboardToggleRecognizer]; //keep legacy approach in pure native mode
|
||||||
// else [self->streamFrameTopLayerView addGestureRecognizer:keyboardToggleRecognizer]; //add to the superview in other modes
|
// else [self->streamFrameTopLayerView addGestureRecognizer:keyboardToggleRecognizer]; //add to the superview in other modes
|
||||||
|
|
||||||
// [self->streamFrameTopLayerView addGestureRecognizer:keyboardToggleRecognizer]; //add to the superview in other modes
|
// [self->streamFrameTopLayerView addGestureRecognizer:keyboardToggleRecognizer]; //add to the superview in other modes
|
||||||
|
|
||||||
#if TARGET_OS_TV
|
#if TARGET_OS_TV
|
||||||
// tvOS requires RelativeTouchHandler to manage Apple Remote input
|
// tvOS requires RelativeTouchHandler to manage Apple Remote input
|
||||||
self->touchHandler = [[RelativeTouchHandler alloc] initWithView:self];
|
self->touchHandler = [[RelativeTouchHandler alloc] initWithView:self];
|
||||||
#else
|
#else
|
||||||
// iOS uses touch Mode depending on user preference
|
// iOS uses touch Mode depending on user preference
|
||||||
|
|
||||||
switch (settings.touchMode.intValue) {
|
switch (settings.touchMode.intValue) {
|
||||||
case NativeTouch:
|
case NativeTouch:
|
||||||
keyboardToggleRecognizer.immediateTriggering = false;
|
keyboardToggleRecognizer.immediateTriggering = false;
|
||||||
@@ -142,11 +142,11 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
self->touchHandler = [[AbsoluteTouchHandler alloc] initWithView:self];
|
self->touchHandler = [[AbsoluteTouchHandler alloc] initWithView:self];
|
||||||
keyboardToggleRecognizer.immediateTriggering = true; //triggers signal in touchesBegan callback stage
|
keyboardToggleRecognizer.immediateTriggering = true; //triggers signal in touchesBegan callback stage
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we'll render on-screen controls on the toplayer too:
|
// we'll render on-screen controls on the toplayer too:
|
||||||
onScreenControls = [[OnScreenControls alloc] initWithView:self->streamFrameTopLayerView controllerSup:controllerSupport streamConfig:streamConfig]; // don't delete, this is mandatory
|
onScreenControls = [[OnScreenControls alloc] initWithView:self->streamFrameTopLayerView controllerSup:controllerSupport streamConfig:streamConfig]; // don't delete, this is mandatory
|
||||||
/*
|
/*
|
||||||
@@ -155,15 +155,15 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
RelativeTouchHandler* relativeTouchHandler = (RelativeTouchHandler*) touchHandler;
|
RelativeTouchHandler* relativeTouchHandler = (RelativeTouchHandler*) touchHandler;
|
||||||
onScreenControls.mouseRightClickTapRecognizer = relativeTouchHandler.mouseRightClickTapRecognizer;
|
onScreenControls.mouseRightClickTapRecognizer = relativeTouchHandler.mouseRightClickTapRecognizer;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
OnScreenControlsLevel level = (OnScreenControlsLevel)[settings.onscreenControls integerValue];
|
OnScreenControlsLevel level = (OnScreenControlsLevel)[settings.onscreenControls integerValue];
|
||||||
if (settings.touchMode.intValue != RelativeTouch && settings.touchMode.intValue != NativeTouch ) {
|
if (settings.touchMode.intValue != RelativeTouch && settings.touchMode.intValue != NativeTouch ) {
|
||||||
Log(LOG_I, @"On-screen controls disabled in non-relative touch mode");
|
Log(LOG_I, @"On-screen controls disabled in non-relative touch mode");
|
||||||
[onScreenControls setLevel:OnScreenControlsLevelOff];
|
[onScreenControls setLevel:OnScreenControlsLevelOff];
|
||||||
|
|
||||||
//pass touchesCaptureByOnScreenButtons Set to the native touchhandler, this NSSet is init witihin onscreencontrols class, don't do it again in native touch handler class
|
//pass touchesCaptureByOnScreenButtons Set to the native touchhandler, this NSSet is init witihin onscreencontrols class, don't do it again in native touch handler class
|
||||||
[OnScreenControls.touchAddrsCapturedByOnScreenControls removeAllObjects]; // reset the attribute to nil
|
[OnScreenControls.touchAddrsCapturedByOnScreenControls removeAllObjects]; // reset the attribute to nil
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if(settings.touchMode.intValue == NativeTouch){
|
if(settings.touchMode.intValue == NativeTouch){
|
||||||
NativeTouchHandler* nativeTouchHandler = (NativeTouchHandler* )touchHandler;
|
NativeTouchHandler* nativeTouchHandler = (NativeTouchHandler* )touchHandler;
|
||||||
@@ -302,7 +302,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
UIBarButtonItem *altBarButton = [self createButtonWithImageNamed:@"AltIcon.png" backgroundColor:[UIColor blackColor] target:self action:@selector(toolbarButtonClicked:) keyCode:0x12 isToggleable:YES];
|
UIBarButtonItem *altBarButton = [self createButtonWithImageNamed:@"AltIcon.png" backgroundColor:[UIColor blackColor] target:self action:@selector(toolbarButtonClicked:) keyCode:0x12 isToggleable:YES];
|
||||||
UIBarButtonItem *deleteBarButton = [self createButtonWithImageNamed:@"DeleteIcon.png" backgroundColor:[UIColor blackColor] target:self action:@selector(toolbarButtonClicked:) keyCode:0x2E isToggleable:NO];
|
UIBarButtonItem *deleteBarButton = [self createButtonWithImageNamed:@"DeleteIcon.png" backgroundColor:[UIColor blackColor] target:self action:@selector(toolbarButtonClicked:) keyCode:0x2E isToggleable:NO];
|
||||||
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
|
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
|
||||||
|
|
||||||
[customToolbarView setItems:[NSArray arrayWithObjects:doneBarButton, windowsBarButton, escapeBarButton, tabBarButton, shiftBarButton, controlBarButton, altBarButton, deleteBarButton, flexibleSpace, nil]];
|
[customToolbarView setItems:[NSArray arrayWithObjects:doneBarButton, windowsBarButton, escapeBarButton, tabBarButton, shiftBarButton, controlBarButton, altBarButton, deleteBarButton, flexibleSpace, nil]];
|
||||||
keyInputField.inputAccessoryView = customToolbarView;
|
keyInputField.inputAccessoryView = customToolbarView;
|
||||||
}
|
}
|
||||||
@@ -311,7 +311,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
[keyInputField addTarget:self action:@selector(onKeyboardPressed:) forControlEvents:UIControlEventEditingChanged];
|
[keyInputField addTarget:self action:@selector(onKeyboardPressed:) forControlEvents:UIControlEventEditingChanged];
|
||||||
// Undo causes issues for our state management, so turn it off
|
// Undo causes issues for our state management, so turn it off
|
||||||
[keyInputField.undoManager disableUndoRegistration];
|
[keyInputField.undoManager disableUndoRegistration];
|
||||||
|
|
||||||
//[keyboardToggleTip removeFromSuperview];
|
//[keyboardToggleTip removeFromSuperview];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -350,7 +350,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
|
|
||||||
- (void) showOnScreenControls {
|
- (void) showOnScreenControls {
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
[onScreenControls show];
|
if(!_widgetToolOpened) [onScreenControls show];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,13 +385,13 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
|
|
||||||
- (void) reloadOnScreenControlsWith:(ControllerSupport*)controllerSupport
|
- (void) reloadOnScreenControlsWith:(ControllerSupport*)controllerSupport
|
||||||
andConfig:(StreamConfiguration*)streamConfig {
|
andConfig:(StreamConfiguration*)streamConfig {
|
||||||
|
|
||||||
// we'll render on-screen controllers on the toplayer too.
|
// we'll render on-screen controllers on the toplayer too.
|
||||||
onScreenControls = [[OnScreenControls alloc] initWithView:self->streamFrameTopLayerView controllerSup:controllerSupport streamConfig:streamConfig];
|
onScreenControls = [[OnScreenControls alloc] initWithView:self->streamFrameTopLayerView controllerSup:controllerSupport streamConfig:streamConfig];
|
||||||
/*
|
/*
|
||||||
// pass mouseRightClickTapRecognizer to onScreenControls obj here:
|
// pass mouseRightClickTapRecognizer to onScreenControls obj here:
|
||||||
if([self isOscEnabled]){
|
if([self isOscEnabled]){
|
||||||
|
|
||||||
RelativeTouchHandler* relativeTouchHandler = (RelativeTouchHandler *)touchHandler;
|
RelativeTouchHandler* relativeTouchHandler = (RelativeTouchHandler *)touchHandler;
|
||||||
onScreenControls.mouseRightClickTapRecognizer = relativeTouchHandler.mouseRightClickTapRecognizer;
|
onScreenControls.mouseRightClickTapRecognizer = relativeTouchHandler.mouseRightClickTapRecognizer;
|
||||||
} */
|
} */
|
||||||
@@ -399,7 +399,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void) clearOnScreenKeyboardButtons{
|
- (void) clearOnScreenWidgets{
|
||||||
for (UIView *subview in self->streamFrameTopLayerView.subviews) {
|
for (UIView *subview in self->streamFrameTopLayerView.subviews) {
|
||||||
// 检查子视图是否是特定类型的实例
|
// 检查子视图是否是特定类型的实例
|
||||||
if ([subview isKindOfClass:[OnScreenWidgetView class]]) {
|
if ([subview isKindOfClass:[OnScreenWidgetView class]]) {
|
||||||
@@ -411,23 +411,26 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
|
|
||||||
- (CGPoint)denormalizeWidgetPosition:(CGPoint)position {
|
- (CGPoint)denormalizeWidgetPosition:(CGPoint)position {
|
||||||
if(position.x < 1.0 && position.y < 1.0){
|
if(position.x < 1.0 && position.y < 1.0){
|
||||||
position.x = position.x * self.bounds.size.width;
|
position.x = position.x * streamFrameTopLayerView.bounds.size.width;
|
||||||
position.y = position.y * self.bounds.size.height;
|
position.y = position.y * streamFrameTopLayerView.bounds.size.height;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
NSLog(@"invalid coords");
|
||||||
}
|
}
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) reloadOnScreenWidgetViews{
|
- (void) reloadOnScreenWidgetViews{
|
||||||
|
|
||||||
// NSLog(@"reload on screen keyboard buttons here");
|
// NSLog(@"reload on screen keyboard buttons here");
|
||||||
|
|
||||||
// remove all keyboard widget views first
|
// remove all keyboard widget views first
|
||||||
[self clearOnScreenKeyboardButtons];
|
[self clearOnScreenWidgets];
|
||||||
|
|
||||||
// bool customOscEnabled = [self isOscEnabled] && settings.onscreenControls.intValue == OnScreenControlsLevelCustom;
|
// bool customOscEnabled = [self isOscEnabled] && settings.onscreenControls.intValue == OnScreenControlsLevelCustom;
|
||||||
|
|
||||||
if(![self isOnScreenButtonEnabled]) return;
|
if(![self isOnScreenButtonEnabled]) return;
|
||||||
|
|
||||||
OSCProfilesManager* profilesManager = [OSCProfilesManager sharedManager: self.bounds];
|
OSCProfilesManager* profilesManager = [OSCProfilesManager sharedManager: self.bounds];
|
||||||
OSCProfile *oscProfile = [profilesManager getSelectedProfile]; //returns the currently selected OSCProfile
|
OSCProfile *oscProfile = [profilesManager getSelectedProfile]; //returns the currently selected OSCProfile
|
||||||
|
|
||||||
@@ -630,7 +633,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
if ([self handleMouseButtonEvent:BUTTON_ACTION_PRESS
|
if ([self handleMouseButtonEvent:BUTTON_ACTION_PRESS
|
||||||
forTouches:touches
|
forTouches:touches
|
||||||
@@ -710,8 +713,8 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)handleMouseButtonEvent:(int)buttonAction forTouches:(NSSet *)touches withEvent:(UIEvent *)event {
|
- (BOOL)handleMouseButtonEvent:(int)buttonAction forTouches:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
|
|
||||||
|
|
||||||
// NSLog(@"mouse click time: %f", CACurrentMediaTime()*1000);
|
// NSLog(@"mouse click time: %f", CACurrentMediaTime()*1000);
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
if (@available(iOS 13.4, *)) {
|
if (@available(iOS 13.4, *)) {
|
||||||
@@ -775,12 +778,12 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
|
|
||||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
|
|
||||||
if (settings.touchMode.intValue == NativeTouchOnly) {
|
if (settings.touchMode.intValue == NativeTouchOnly) {
|
||||||
[touchHandler touchesMoved:touches withEvent:event];
|
[touchHandler touchesMoved:touches withEvent:event];
|
||||||
return; //This is a native touch oriented fork, in pure native touch mode, this call back method deals with native touch only.
|
return; //This is a native touch oriented fork, in pure native touch mode, this call back method deals with native touch only.
|
||||||
}
|
}
|
||||||
|
|
||||||
for (UITouch* touch in touches) {
|
for (UITouch* touch in touches) {
|
||||||
if (touch.type == UITouchTypePencil) {
|
if (touch.type == UITouchTypePencil) {
|
||||||
if ([self sendStylusEvent:touch]) return;
|
if ([self sendStylusEvent:touch]) return;
|
||||||
@@ -806,7 +809,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
hasUserInteracted = YES;
|
hasUserInteracted = YES;
|
||||||
|
|
||||||
if(self->settings.touchMode.intValue == NativeTouch || self->settings.touchMode.intValue == RelativeTouch){
|
if(self->settings.touchMode.intValue == NativeTouch || self->settings.touchMode.intValue == RelativeTouch){
|
||||||
@@ -884,7 +887,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
|
|||||||
[touchHandler touchesEnded:touches withEvent:event];
|
[touchHandler touchesEnded:touches withEvent:event];
|
||||||
return; //This is a native touch oriented fork, in pure native touch mode, this call back method deals with native touch only.
|
return; //This is a native touch oriented fork, in pure native touch mode, this call back method deals with native touch only.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (@available(iOS 13.4, *)){ //now only pencil events are restricted
|
if (@available(iOS 13.4, *)){ //now only pencil events are restricted
|
||||||
for (UITouch* touch in touches) {
|
for (UITouch* touch in touches) {
|
||||||
if (touch.type == UITouchTypePencil) {
|
if (touch.type == UITouchTypePencil) {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
<attribute name="localMousePointerMode" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="localMousePointerMode" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="mousePointerVelocityFactor" optional="YES" attributeType="Float" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="mousePointerVelocityFactor" optional="YES" attributeType="Float" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="multiController" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
|
<attribute name="multiController" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
|
||||||
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="optimizeGames" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
|
<attribute name="optimizeGames" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
|
||||||
<attribute name="oscLayoutToolFingers" optional="YES" attributeType="Integer 16" defaultValueString="4" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="oscLayoutToolFingers" optional="YES" attributeType="Integer 16" defaultValueString="4" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="playAudioOnPC" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
|
<attribute name="playAudioOnPC" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
|
||||||
|
|||||||
@@ -295,13 +295,13 @@
|
|||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "[ 開啟螢幕小工具 ]"
|
"value" : "[ 調整螢幕小工具版面配置 ]"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "[ 開啟螢幕小工具 ]"
|
"value" : "[ 調整螢幕小工具版面配置 ]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1457,25 +1457,25 @@
|
|||||||
"en" : {
|
"en" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/uscwmv3vz8g30rmk?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/uscwmv3vz8g30rmk?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bz6ggagp0ly4loq3?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bz6ggagp0ly4loq3?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "needs_review",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bz6ggagp0ly4loq3?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bz6ggagp0ly4loq3?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "needs_review",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bz6ggagp0ly4loq3?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bz6ggagp0ly4loq3?singleDoc"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1705,25 +1705,25 @@
|
|||||||
"en" : {
|
"en" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bu3hki4pezy93g6r?singleDoc# "
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bu3hki4pezy93g6r?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/cqbse6t4o6f9hil1?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/cqbse6t4o6f9hil1?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/cqbse6t4o6f9hil1?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/cqbse6t4o6f9hil1?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/cqbse6t4o6f9hil1?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/cqbse6t4o6f9hil1?singleDoc"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2022,25 +2022,25 @@
|
|||||||
"en" : {
|
"en" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/uscwmv3vz8g30rmk?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/uscwmv3vz8g30rmk?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bz6ggagp0ly4loq3?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bz6ggagp0ly4loq3?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bz6ggagp0ly4loq3?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bz6ggagp0ly4loq3?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bz6ggagp0ly4loq3?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/bz6ggagp0ly4loq3?singleDoc"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2454,25 +2454,25 @@
|
|||||||
"en" : {
|
"en" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/zdf5l29s3vohs6iq?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/zdf5l29s3vohs6iq?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/yfao3s5bhl93rs01?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/yfao3s5bhl93rs01?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/yfao3s5bhl93rs01?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/yfao3s5bhl93rs01?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/yfao3s5bhl93rs01?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/yfao3s5bhl93rs01?singleDoc"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2898,6 +2898,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Offline\n%@" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "离线\n%@"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "離線\n%@"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "離線\n%@"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Ok" : {
|
"Ok" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -2990,48 +3013,48 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Online - Not Paired" : {
|
"Online - Not Paired\n%@" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "在线 - 未配对"
|
"value" : "在线 - 未配对\n%@"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "線上 - 未配對"
|
"value" : "線上 - 未配對\n%@"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "線上 - 未配對"
|
"value" : "線上 - 未配對\n%@"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Online - Paired" : {
|
"Online - Paired\n%@" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "在线 - 已配对"
|
"value" : "在线 - 已配对\n%@"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "線上 - 已配對"
|
"value" : "線上 - 已配對\n%@"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "線上 - 已配對"
|
"value" : "線上 - 已配對\n%@"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3065,19 +3088,19 @@
|
|||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/zrg0ga93avz4s747?singleDoc# "
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/zrg0ga93avz4s747?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/zrg0ga93avz4s747?singleDoc# "
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/zrg0ga93avz4s747?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/zrg0ga93avz4s747?singleDoc# "
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/zrg0ga93avz4s747?singleDoc"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4240,25 +4263,25 @@
|
|||||||
"en" : {
|
"en" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/rgc9if4xrf352555?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/rgc9if4xrf352555?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/ok4egvu4lt37wc1f?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/ok4egvu4lt37wc1f?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/ok4egvu4lt37wc1f?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/ok4egvu4lt37wc1f?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/ok4egvu4lt37wc1f?singleDoc#"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/ok4egvu4lt37wc1f?singleDoc"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4344,25 +4367,25 @@
|
|||||||
"en" : {
|
"en" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/dhmg3h27ls8mwt4a?singleDoc# 《About VoidLink》"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/dhmg3h27ls8mwt4a?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/fdi4rxkxykhl5zpp?singleDoc# 《关于 VoidLink》"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/fdi4rxkxykhl5zpp?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/fdi4rxkxykhl5zpp?singleDoc# 《关于 VoidLink》"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/fdi4rxkxykhl5zpp?singleDoc"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/fdi4rxkxykhl5zpp?singleDoc# 《关于 VoidLink》"
|
"value" : "https://voidlink.yuque.com/org-wiki-voidlink-znirha/fa3tgr/fdi4rxkxykhl5zpp?singleDoc"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4603,25 +4626,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Touch & Control" : {
|
"Touch & Controller" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "触屏与控制"
|
"value" : "触屏与手柄"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "觸控與控制"
|
"value" : "觸控與控制器"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "觸控與控制"
|
"value" : "觸控與控制器"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#import "BandwidthTracker.h"
|
#import "BandwidthTracker.h"
|
||||||
#import "Plot.h"
|
#import "Plot.h"
|
||||||
|
|
||||||
#define CONN_TEST_SERVER "ios.conntest.moonlight-stream.org"
|
#define CONN_TEST_SERVER "www.baidu.com"
|
||||||
|
|
||||||
@interface Connection : NSOperation <NSStreamDelegate>
|
@interface Connection : NSOperation <NSStreamDelegate>
|
||||||
|
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ static UIImage* noImage;
|
|||||||
|
|
||||||
- (void) updateLoop {
|
- (void) updateLoop {
|
||||||
// Stop immediately if the view has been detached
|
// Stop immediately if the view has been detached
|
||||||
if (self.superview == nil) {
|
if (self.superview == nil || ![self.updateLoopDelegate isInAppView]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +282,7 @@ static UIImage* noImage;
|
|||||||
[self setAlpha:_app.hidden ? 0.4 : 1.0];
|
[self setAlpha:_app.hidden ? 0.4 : 1.0];
|
||||||
|
|
||||||
// Queue the next refresh cycle
|
// Queue the next refresh cycle
|
||||||
if([self.updateLoopDelegate isInAppView]) [self performSelector:@selector(updateLoop) withObject:self afterDelay:REFRESH_CYCLE];
|
[self performSelector:@selector(updateLoop) withObject:self afterDelay:REFRESH_CYCLE];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
//
|
|
||||||
// UIComputerView.h
|
|
||||||
// Moonlight
|
|
||||||
//
|
|
||||||
// Created by Diego Waxemberg on 10/22/14.
|
|
||||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
|
||||||
#import "TemporaryHost.h"
|
|
||||||
|
|
||||||
@protocol HostCallback <NSObject>
|
|
||||||
|
|
||||||
- (void) noneUserInitiatedHostAction:(TemporaryHost*)host view:(UIView*)view;
|
|
||||||
- (void) hostCardLongPressed:(TemporaryHost*)host view:(UIView*)view;
|
|
||||||
- (void) addHostTapped;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
#if !TARGET_OS_TV
|
|
||||||
@interface UIComputerView : UIButton <UIContextMenuInteractionDelegate>
|
|
||||||
#else
|
|
||||||
@interface UIComputerView : UIButton
|
|
||||||
#endif
|
|
||||||
|
|
||||||
- (id) initWithComputer:(TemporaryHost*)host andCallback:(id<HostCallback>)callback;
|
|
||||||
- (id) initForAddWithCallback:(id<HostCallback>)callback;
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -1,244 +0,0 @@
|
|||||||
//
|
|
||||||
// UIComputerView.m
|
|
||||||
// Moonlight
|
|
||||||
//
|
|
||||||
// Created by Diego Waxemberg on 10/22/14.
|
|
||||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
|
||||||
//
|
|
||||||
// Modified by True砖家 since 2024.6.30
|
|
||||||
// Copyright © 2024 True砖家 @ Bilibili. All rights reserved.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "UIComputerView.h"
|
|
||||||
#import "LocalizationHelper.h"
|
|
||||||
|
|
||||||
@implementation UIComputerView {
|
|
||||||
TemporaryHost* _host;
|
|
||||||
UIImageView* _hostIcon;
|
|
||||||
UILabel* _hostLabel;
|
|
||||||
UIImageView* _hostOverlay;
|
|
||||||
UIActivityIndicatorView* _hostSpinner;
|
|
||||||
id<HostCallback> _callback;
|
|
||||||
CGSize _labelSize;
|
|
||||||
}
|
|
||||||
static const float REFRESH_CYCLE = 2.0f;
|
|
||||||
|
|
||||||
#if TARGET_OS_TV
|
|
||||||
static const int ITEM_PADDING = 50;
|
|
||||||
static const int LABEL_DY = 40;
|
|
||||||
#else
|
|
||||||
static const int ITEM_PADDING = 0;
|
|
||||||
static const int LABEL_DY = 20;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
- (id) init {
|
|
||||||
self = [super init];
|
|
||||||
|
|
||||||
#if TARGET_OS_TV
|
|
||||||
self.frame = CGRectMake(0, 0, 400, 400);
|
|
||||||
#else
|
|
||||||
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
|
|
||||||
self.frame = CGRectMake(0, 0, 200, 200);
|
|
||||||
} else {
|
|
||||||
self.frame = CGRectMake(0, 0, 100, 100);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_hostIcon = [[UIImageView alloc] initWithFrame:self.frame];
|
|
||||||
[_hostIcon setImage:[UIImage imageNamed:@"Computer"]];
|
|
||||||
|
|
||||||
self.layer.shadowColor = [[UIColor blackColor] CGColor];
|
|
||||||
self.layer.shadowOffset = CGSizeMake(5,8);
|
|
||||||
self.layer.shadowOpacity = 0.3;
|
|
||||||
|
|
||||||
[self addTarget:self action:@selector(hostButtonSelected:) forControlEvents:UIControlEventTouchDown];
|
|
||||||
[self addTarget:self action:@selector(hostButtonDeselected:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchCancel | UIControlEventTouchDragExit];
|
|
||||||
|
|
||||||
_hostLabel = [[UILabel alloc] init];
|
|
||||||
_hostLabel.textColor = [UIColor whiteColor];
|
|
||||||
|
|
||||||
_hostOverlay = [[UIImageView alloc] initWithFrame:CGRectMake(self.frame.size.width / 3, _hostIcon.frame.size.height / 4, _hostIcon.frame.size.width / 3, self.frame.size.height / 3)];
|
|
||||||
_hostSpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge];
|
|
||||||
[_hostSpinner setFrame:_hostOverlay.frame];
|
|
||||||
_hostSpinner.userInteractionEnabled = NO;
|
|
||||||
_hostSpinner.hidesWhenStopped = YES;
|
|
||||||
|
|
||||||
[self addSubview:_hostLabel];
|
|
||||||
[self addSubview:_hostIcon];
|
|
||||||
|
|
||||||
#if TARGET_OS_TV
|
|
||||||
_hostIcon.clipsToBounds = NO;
|
|
||||||
_hostIcon.adjustsImageWhenAncestorFocused = YES;
|
|
||||||
_hostIcon.masksFocusEffectToContents = YES;
|
|
||||||
|
|
||||||
self.adjustsImageWhenHighlighted = NO;
|
|
||||||
|
|
||||||
_hostOverlay.masksFocusEffectToContents = YES;
|
|
||||||
_hostOverlay.adjustsImageWhenAncestorFocused = NO;
|
|
||||||
|
|
||||||
[_hostIcon.overlayContentView addSubview:_hostOverlay];
|
|
||||||
[_hostIcon.overlayContentView addSubview:_hostSpinner];
|
|
||||||
#else
|
|
||||||
[self addSubview:_hostOverlay];
|
|
||||||
[self addSubview:_hostSpinner];
|
|
||||||
|
|
||||||
if (@available(iOS 13.4.1, *)) {
|
|
||||||
// Allow the button style to change when moused over
|
|
||||||
self.pointerInteractionEnabled = YES;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) hostButtonSelected:(id)sender {
|
|
||||||
_hostIcon.layer.opacity = 0.5f;
|
|
||||||
_hostSpinner.layer.opacity = 0.5f;
|
|
||||||
_hostOverlay.layer.opacity = 0.5f;
|
|
||||||
}
|
|
||||||
- (void) hostButtonDeselected:(id)sender {
|
|
||||||
_hostIcon.layer.opacity = 1.0f;
|
|
||||||
_hostSpinner.layer.opacity = 1.0f;
|
|
||||||
_hostOverlay.layer.opacity = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id) initForAddWithCallback:(id<HostCallback>)callback {
|
|
||||||
self = [self init];
|
|
||||||
_callback = callback;
|
|
||||||
|
|
||||||
[self addTarget:self action:@selector(addClicked) forControlEvents:UIControlEventPrimaryActionTriggered];
|
|
||||||
|
|
||||||
[_hostLabel setText:[LocalizationHelper localizedStringForKey:@"Add Host Manually"]];
|
|
||||||
[_hostLabel sizeToFit];
|
|
||||||
|
|
||||||
[_hostOverlay setImage:[UIImage imageNamed:@"AddOverlayIcon"]];
|
|
||||||
|
|
||||||
[self updateBounds];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id) initWithComputer:(TemporaryHost*)host andCallback:(id<HostCallback>)callback {
|
|
||||||
self = [self init];
|
|
||||||
_host = host;
|
|
||||||
_callback = callback;
|
|
||||||
|
|
||||||
// Use UIContextMenuInteraction on iOS 13.0+ and a standard UILongPressGestureRecognizer
|
|
||||||
// for tvOS devices and iOS prior to 13.0.
|
|
||||||
#if !TARGET_OS_TV
|
|
||||||
if (@available(iOS 13.0, *)) {
|
|
||||||
UIContextMenuInteraction* rightClickInteraction = [[UIContextMenuInteraction alloc] initWithDelegate:self];
|
|
||||||
[self addInteraction:rightClickInteraction];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
UILongPressGestureRecognizer* longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(hostLongClicked:)];
|
|
||||||
[self addGestureRecognizer:longPressRecognizer];
|
|
||||||
}
|
|
||||||
|
|
||||||
[self addTarget:self action:@selector(hostClicked) forControlEvents:UIControlEventPrimaryActionTriggered];
|
|
||||||
|
|
||||||
[self updateContentsForHost:host];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)didMoveToSuperview {
|
|
||||||
// Start our update loop when we are added to our cell
|
|
||||||
if (self.superview != nil && _host != nil) {
|
|
||||||
[self updateLoop];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) updateBounds {
|
|
||||||
float x = FLT_MAX;
|
|
||||||
float y = FLT_MAX;
|
|
||||||
float width = 0;
|
|
||||||
float height;
|
|
||||||
|
|
||||||
float iconX = _hostIcon.frame.origin.x + _hostIcon.frame.size.width / 2;
|
|
||||||
_hostLabel.center = CGPointMake(iconX, _hostIcon.frame.origin.y + _hostIcon.frame.size.height + LABEL_DY);
|
|
||||||
|
|
||||||
x = MIN(x, _hostIcon.frame.origin.x);
|
|
||||||
x = MIN(x, _hostLabel.frame.origin.x);
|
|
||||||
|
|
||||||
y = MIN(y, _hostIcon.frame.origin.y);
|
|
||||||
y = MIN(y, _hostLabel.frame.origin.y);
|
|
||||||
|
|
||||||
width = MAX(width, _hostIcon.frame.size.width);
|
|
||||||
width = MAX(width, _hostLabel.frame.size.width);
|
|
||||||
|
|
||||||
height = _hostIcon.frame.size.height +
|
|
||||||
_hostLabel.frame.size.height +
|
|
||||||
LABEL_DY / 2;
|
|
||||||
|
|
||||||
self.bounds = CGRectMake(x - ITEM_PADDING, y - ITEM_PADDING, width + 2 * ITEM_PADDING, height + 2 * ITEM_PADDING);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) updateContentsForHost:(TemporaryHost*)host {
|
|
||||||
_hostLabel.text = _host.name;
|
|
||||||
[_hostLabel sizeToFit];
|
|
||||||
|
|
||||||
if (host.state == StateOnline) {
|
|
||||||
[_hostSpinner stopAnimating];
|
|
||||||
|
|
||||||
if (host.pairState == PairStateUnpaired) {
|
|
||||||
[_hostOverlay setImage:[UIImage imageNamed:@"LockedOverlayIcon"]];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
[_hostOverlay setImage:nil];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (host.state == StateOffline) {
|
|
||||||
[_hostSpinner stopAnimating];
|
|
||||||
[_hostOverlay setImage:[UIImage imageNamed:@"ErrorOverlayIcon"]];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
[_hostSpinner startAnimating];
|
|
||||||
}
|
|
||||||
|
|
||||||
[self updateBounds];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) updateLoop {
|
|
||||||
// Stop immediately if the view has been detached
|
|
||||||
if (self.superview == nil) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
[self updateContentsForHost:_host];
|
|
||||||
|
|
||||||
// Queue the next refresh cycle
|
|
||||||
[self performSelector:@selector(updateLoop) withObject:self afterDelay:REFRESH_CYCLE];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) hostLongClicked:(UILongPressGestureRecognizer*)gesture {
|
|
||||||
if (gesture.state == UIGestureRecognizerStateBegan) {
|
|
||||||
[_callback hostCardLongPressed:_host view:self];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !TARGET_OS_TV
|
|
||||||
- (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction
|
|
||||||
configurationForMenuAtLocation:(CGPoint)location {
|
|
||||||
// We don't want to trigger the primary action at this point, so cancel
|
|
||||||
// tracking touch on this view now. This will also have the (intended)
|
|
||||||
// effect of removing the touch highlight on this view.
|
|
||||||
[self cancelTrackingWithEvent:nil];
|
|
||||||
|
|
||||||
[_callback hostCardLongPressed:_host view:self];
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
- (void) hostClicked {
|
|
||||||
[_callback noneUserInitiatedHostAction:_host view:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) addClicked {
|
|
||||||
[_callback addHostTapped];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
+1
-1
@@ -27,7 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
- (void)presentProfilesTableView;
|
- (void)presentProfilesTableView;
|
||||||
|
|
||||||
@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 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) NSMutableSet* OnScreenWidgetViews;
|
@property (nonatomic) NSMutableSet* onScreenWidgetViews;
|
||||||
|
|
||||||
@property int OSCSegmentSelected;
|
@property int OSCSegmentSelected;
|
||||||
@property (nonatomic, assign) bool quickSwitchEnabled;
|
@property (nonatomic, assign) bool quickSwitchEnabled;
|
||||||
|
|||||||
+69
-37
@@ -31,6 +31,7 @@
|
|||||||
CGRect controllerLoadedBounds;
|
CGRect controllerLoadedBounds;
|
||||||
bool widgetViewSelected;
|
bool widgetViewSelected;
|
||||||
bool controllerLayerSelected;
|
bool controllerLayerSelected;
|
||||||
|
bool viewWillBeResized;
|
||||||
__weak IBOutlet NSLayoutConstraint *toolbarTopConstraintiPhone;
|
__weak IBOutlet NSLayoutConstraint *toolbarTopConstraintiPhone;
|
||||||
__weak IBOutlet NSLayoutConstraint *toolbarTopConstraintiPad;
|
__weak IBOutlet NSLayoutConstraint *toolbarTopConstraintiPad;
|
||||||
UIColor* trashCanStoryBoardColor;
|
UIColor* trashCanStoryBoardColor;
|
||||||
@@ -62,7 +63,7 @@
|
|||||||
|
|
||||||
- (void) viewWillDisappear:(BOOL)animated{
|
- (void) viewWillDisappear:(BOOL)animated{
|
||||||
OnScreenWidgetView.editMode = false;
|
OnScreenWidgetView.editMode = false;
|
||||||
for (OnScreenWidgetView* widgetView in self.OnScreenWidgetViews){
|
for (OnScreenWidgetView* widgetView in self.onScreenWidgetViews){
|
||||||
[widgetView.stickBallLayer removeFromSuperlayer];
|
[widgetView.stickBallLayer removeFromSuperlayer];
|
||||||
[widgetView.crossMarkLayer removeFromSuperlayer];
|
[widgetView.crossMarkLayer removeFromSuperlayer];
|
||||||
}
|
}
|
||||||
@@ -71,14 +72,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (CGPoint)denormalizeWidgetPosition:(CGPoint)position {
|
- (CGPoint)denormalizeWidgetPosition:(CGPoint)position {
|
||||||
|
// NSLog(@"position: %f, %f", position.x, position.y);
|
||||||
|
CGPoint newPosition = position;
|
||||||
if(position.x < 1.0 && position.y < 1.0){
|
if(position.x < 1.0 && position.y < 1.0){
|
||||||
position.x = position.x * self.view.bounds.size.width;
|
newPosition.x = position.x * self.view.bounds.size.width;
|
||||||
position.y = position.y * self.view.bounds.size.height;
|
newPosition.y = position.y * self.view.bounds.size.height;
|
||||||
}
|
}
|
||||||
return position;
|
return newPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) reloadOnScreenWidgetViews {
|
- (void)reloadLegacyOnScreenControls{
|
||||||
|
[self.layoutOSC updateControls]; // creates and saves a 'Default' OSC profile or loads the o//ne the user selected on the previous screen
|
||||||
|
[self addInnerAnalogSticksToOuterAnalogLayers];
|
||||||
|
[self.layoutOSC.layoutChanges removeAllObjects]; // since a new OSC profile is being loaded, this will remove all previous layout changes made from the array
|
||||||
|
[self OSCLayoutChanged]; // fades the 'Undo Button' out
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)reloadOnScreenWidgetViews{
|
||||||
NSLog(@"reloadOnScreenWidgets %f", CACurrentMediaTime());
|
NSLog(@"reloadOnScreenWidgets %f", CACurrentMediaTime());
|
||||||
OnScreenWidgetView.editMode = true;
|
OnScreenWidgetView.editMode = true;
|
||||||
[self clearStickIndicator];
|
[self clearStickIndicator];
|
||||||
@@ -89,7 +99,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[self.OnScreenWidgetViews removeAllObjects];
|
[self.onScreenWidgetViews removeAllObjects];
|
||||||
|
|
||||||
|
|
||||||
NSLog(@"reload os Key here");
|
NSLog(@"reload os Key here");
|
||||||
@@ -120,7 +130,7 @@
|
|||||||
[widgetView resizeWidgetView]; // resize must be called after relocation
|
[widgetView resizeWidgetView]; // resize must be called after relocation
|
||||||
[widgetView adjustTransparencyWithAlpha:buttonState.backgroundAlpha];
|
[widgetView adjustTransparencyWithAlpha:buttonState.backgroundAlpha];
|
||||||
[widgetView adjustBorderWithWidth:buttonState.borderWidth];
|
[widgetView adjustBorderWithWidth:buttonState.borderWidth];
|
||||||
[self.OnScreenWidgetViews addObject:widgetView];
|
[self.onScreenWidgetViews addObject:widgetView];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,11 +138,12 @@
|
|||||||
- (void) viewDidLoad {
|
- (void) viewDidLoad {
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
profilesManager = [OSCProfilesManager sharedManager:self.view.bounds];
|
profilesManager = [OSCProfilesManager sharedManager:self.view.bounds];
|
||||||
self.OnScreenWidgetViews = [[NSMutableSet alloc] init]; // will be revised to read persisted data , somewhere else
|
self.onScreenWidgetViews = [[NSMutableSet alloc] init]; // will be revised to read persisted data , somewhere else
|
||||||
[OSCProfilesManager setOnScreenWidgetViewsSet:self.OnScreenWidgetViews]; // pass the keyboard button dict to profiles manager
|
[OSCProfilesManager setOnScreenWidgetViewsSet:self.onScreenWidgetViews]; // 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
|
//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
|
||||||
_quickSwitchEnabled = false;
|
_quickSwitchEnabled = false;
|
||||||
|
viewWillBeResized = false;
|
||||||
|
|
||||||
/* add curve to bottom of chevron tab view */
|
/* add curve to bottom of chevron tab view */
|
||||||
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.chevronView.bounds byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(10.0, 10.0)];
|
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.chevronView.bounds byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(10.0, 10.0)];
|
||||||
@@ -155,8 +166,9 @@
|
|||||||
self.layoutOSC = [[LayoutOnScreenControls alloc] initWithView:self.view controllerSup:nil streamConfig:nil oscLevel:OSCSegmentSelected];
|
self.layoutOSC = [[LayoutOnScreenControls alloc] initWithView:self.view controllerSup:nil streamConfig:nil oscLevel:OSCSegmentSelected];
|
||||||
self.layoutOSC._level = OnScreenControlsLevelCustom;
|
self.layoutOSC._level = OnScreenControlsLevelCustom;
|
||||||
self.layoutOSC.layoutToolVC = self;
|
self.layoutOSC.layoutToolVC = self;
|
||||||
|
//[self.layoutOSC show]; // draw on screen controls
|
||||||
[self.layoutOSC show]; // draw on screen controls
|
[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
|
[self addInnerAnalogSticksToOuterAnalogLayers]; // allows inner and analog sticks to be dragged together around the screen together as one unit which is the expected behavior
|
||||||
|
|
||||||
self.undoButton.alpha = 0.3; // no changes to undo yet, so fade out the undo button a bit
|
self.undoButton.alpha = 0.3; // no changes to undo yet, so fade out the undo button a bit
|
||||||
@@ -238,12 +250,16 @@
|
|||||||
object:nil];
|
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
|
[[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
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver: self
|
||||||
|
selector: @selector(handleReturnToForeground)
|
||||||
|
name: UIApplicationDidBecomeActiveNotification
|
||||||
|
object: nil];
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
selector:@selector(applicationWillResignActive:)
|
selector:@selector(deviceOrientationDidChange) // handle orientation change since i made portrait mode available
|
||||||
name:UIApplicationWillResignActiveNotification
|
name:UIDeviceOrientationDidChangeNotification
|
||||||
object:nil];
|
object:nil];
|
||||||
|
|
||||||
OnScreenWidgetView.editMode = true;
|
OnScreenWidgetView.editMode = true;
|
||||||
[self handleMissingToolBarIcon:toolbarRootView];
|
[self handleMissingToolBarIcon:toolbarRootView];
|
||||||
[self profileRefresh];
|
[self profileRefresh];
|
||||||
@@ -251,10 +267,33 @@
|
|||||||
|
|
||||||
#pragma mark - Class Helper Functions
|
#pragma mark - Class Helper Functions
|
||||||
|
|
||||||
- (void)applicationWillResignActive:(NSNotification *)notification {
|
- (void)handleReturnToForeground {
|
||||||
[self saveTapped:nil];
|
[OSCProfilesManager setOnScreenWidgetViewsSet:self.onScreenWidgetViews]; // pass the keyboard button dict to profiles manager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
|
||||||
|
viewWillBeResized = true;
|
||||||
|
[self clearStickIndicator];
|
||||||
|
if(!_quickSwitchEnabled) [self saveTapped:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)deviceOrientationDidChange{
|
||||||
|
[self performSelector:@selector(handleOrientationChangeForOnScreenWidgets) withObject:self afterDelay:0.05];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleOrientationChangeForOnScreenWidgets{
|
||||||
|
if(!viewWillBeResized) return;
|
||||||
|
[self setupWidgetPanel];
|
||||||
|
|
||||||
|
viewWillBeResized = false;
|
||||||
|
selectedWidgetView = nil;
|
||||||
|
selectedControllerLayer = nil;
|
||||||
|
|
||||||
|
_oscProfilesTableViewController.layoutViewBounds = self.view.bounds;
|
||||||
|
[OSCProfilesManager setOnScreenWidgetViewsSet:self.onScreenWidgetViews]; // pass the keyboard button dict to profiles manager
|
||||||
|
[self reloadOnScreenWidgetViews];
|
||||||
|
[self reloadLegacyOnScreenControls];
|
||||||
|
}
|
||||||
|
|
||||||
/* fades the 'Undo Button' in or out depending on whether the user has any OSC layout changes to undo */
|
/* fades the 'Undo Button' in or out depending on whether the user has any OSC layout changes to undo */
|
||||||
- (void) OSCLayoutChanged {
|
- (void) OSCLayoutChanged {
|
||||||
@@ -379,8 +418,8 @@
|
|||||||
UIAlertAction *readInstruction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Read Widget Instruction"]
|
UIAlertAction *readInstruction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Read Widget Instruction"]
|
||||||
style:UIAlertActionStyleDefault
|
style:UIAlertActionStyleDefault
|
||||||
handler:^(UIAlertAction *action){
|
handler:^(UIAlertAction *action){
|
||||||
[self saveTapped:nil];
|
//[self saveTapped:nil];
|
||||||
NSURL *url = [NSURL URLWithString:@"https://b23.tv/J8qEXOr"];
|
NSURL *url = [NSURL URLWithString:[LocalizationHelper localizedStringForKey:@"onScreenWidgetStackDoc"]];
|
||||||
if ([[UIApplication sharedApplication] canOpenURL:url]) {
|
if ([[UIApplication sharedApplication] canOpenURL:url]) {
|
||||||
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
|
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
|
||||||
}
|
}
|
||||||
@@ -435,7 +474,8 @@
|
|||||||
UIAlertAction *readInstruction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Read Widget Instruction"]
|
UIAlertAction *readInstruction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Read Widget Instruction"]
|
||||||
style:UIAlertActionStyleDefault
|
style:UIAlertActionStyleDefault
|
||||||
handler:^(UIAlertAction *action){
|
handler:^(UIAlertAction *action){
|
||||||
NSURL *url = [NSURL URLWithString:@"https://b23.tv/J8qEXOr"];
|
//[self saveTapped:nil];
|
||||||
|
NSURL *url = [NSURL URLWithString:[LocalizationHelper localizedStringForKey:@"onScreenWidgetStackDoc"]];
|
||||||
if ([[UIApplication sharedApplication] canOpenURL:url]) {
|
if ([[UIApplication sharedApplication] canOpenURL:url]) {
|
||||||
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
|
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
|
||||||
}
|
}
|
||||||
@@ -503,7 +543,7 @@
|
|||||||
textField.spellCheckingType = UITextSpellCheckingTypeNo;
|
textField.spellCheckingType = UITextSpellCheckingTypeNo;
|
||||||
textField.text = self->selectedWidgetView.shape;
|
textField.text = self->selectedWidgetView.shape;
|
||||||
if([self->selectedWidgetView.shape isEqualToString: @"largeSquare"]) textField.enabled = false;
|
if([self->selectedWidgetView.shape isEqualToString: @"largeSquare"]) textField.enabled = false;
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
|
||||||
UIAlertAction *createNewAction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Create New"]
|
UIAlertAction *createNewAction = [UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Create New"]
|
||||||
@@ -587,10 +627,10 @@
|
|||||||
[newWidget resizeWidgetView]; // resize must be called after relocation
|
[newWidget resizeWidgetView]; // resize must be called after relocation
|
||||||
[newWidget adjustTransparencyWithAlpha:widget.backgroundAlpha];
|
[newWidget adjustTransparencyWithAlpha:widget.backgroundAlpha];
|
||||||
[newWidget adjustBorderWithWidth:widget.borderWidth];
|
[newWidget adjustBorderWithWidth:widget.borderWidth];
|
||||||
[self.OnScreenWidgetViews addObject:newWidget];
|
[self.onScreenWidgetViews addObject:newWidget];
|
||||||
self->selectedWidgetView = newWidget;
|
self->selectedWidgetView = newWidget;
|
||||||
if(!createNew){
|
if(!createNew){
|
||||||
[self.OnScreenWidgetViews removeObject:widget];
|
[self.onScreenWidgetViews removeObject:widget];
|
||||||
[widget removeFromSuperview];
|
[widget removeFromSuperview];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -603,7 +643,7 @@
|
|||||||
widgetView.guidelineDelegate = (id<OnScreenWidgetGuidelineUpdateDelegate>)self;
|
widgetView.guidelineDelegate = (id<OnScreenWidgetGuidelineUpdateDelegate>)self;
|
||||||
widgetView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
|
widgetView.translatesAutoresizingMaskIntoConstraints = NO; // weird but this is mandatory, or you will find no key views added to the right place
|
||||||
widgetView.minStickOffset = [widgetInitParams[@"minStickOffsetString"] floatValue];
|
widgetView.minStickOffset = [widgetInitParams[@"minStickOffsetString"] floatValue];
|
||||||
[self.OnScreenWidgetViews addObject:widgetView];
|
[self.onScreenWidgetViews addObject:widgetView];
|
||||||
// Add the widgetView to the view controller's view
|
// Add the widgetView to the view controller's view
|
||||||
[self.view insertSubview:widgetView belowSubview:self.widgetPanelStack];
|
[self.view insertSubview:widgetView belowSubview:self.widgetPanelStack];
|
||||||
[widgetView setLocationWithPosition:CGPointMake(90, 130)];
|
[widgetView setLocationWithPosition:CGPointMake(90, 130)];
|
||||||
@@ -614,6 +654,7 @@
|
|||||||
|
|
||||||
/* show pop up notification that lets users choose to save the current OSC layout configuration as a profile they can load when they want. User can also choose to cancel out of this pop up */
|
/* show pop up notification that lets users choose to save the current OSC layout configuration as a profile they can load when they want. User can also choose to cancel out of this pop up */
|
||||||
- (IBAction) saveTapped:(id)sender {
|
- (IBAction) saveTapped:(id)sender {
|
||||||
|
[OSCProfilesManager setLayoutViewBounds:self.view.bounds];
|
||||||
|
|
||||||
if([self->profilesManager updateSelectedProfile:self.layoutOSC.OSCButtonLayers]){
|
if([self->profilesManager updateSelectedProfile:self.layoutOSC.OSCButtonLayers]){
|
||||||
UIAlertController * savedAlertController = [UIAlertController alertControllerWithTitle: [NSString stringWithFormat:@""] message: [LocalizationHelper localizedStringForKey:@"Current profile updated successfully"] preferredStyle:UIAlertControllerStyleAlert];
|
UIAlertController * savedAlertController = [UIAlertController alertControllerWithTitle: [NSString stringWithFormat:@""] message: [LocalizationHelper localizedStringForKey:@"Current profile updated successfully"] preferredStyle:UIAlertControllerStyleAlert];
|
||||||
@@ -1105,12 +1146,9 @@
|
|||||||
|
|
||||||
//this part is just for registration, will not be immediately executed.
|
//this part is just for registration, will not be immediately executed.
|
||||||
self->_oscProfilesTableViewController.needToUpdateOscLayoutTVC = ^() { // a block that will be called when the modally presented 'OSCProfilesTableViewController' VC is dismissed. By the time the 'OSCProfilesTableViewController' VC is dismissed the user would have potentially selected a different OSC profile with a different layout and they want to see this layout on this 'LayoutOnScreenControlsViewController.' This block of code will load the profile and then hide/show and move each OSC button to their appropriate position
|
self->_oscProfilesTableViewController.needToUpdateOscLayoutTVC = ^() { // a block that will be called when the modally presented 'OSCProfilesTableViewController' VC is dismissed. By the time the 'OSCProfilesTableViewController' VC is dismissed the user would have potentially selected a different OSC profile with a different layout and they want to see this layout on this 'LayoutOnScreenControlsViewController.' This block of code will load the profile and then hide/show and move each OSC button to their appropriate position
|
||||||
[self.layoutOSC updateControls]; // creates and saves a 'Default' OSC profile or loads the one the user selected on the previous screen
|
NSLog(@"profile profile");
|
||||||
[self addInnerAnalogSticksToOuterAnalogLayers];
|
[self reloadLegacyOnScreenControls];
|
||||||
[self.layoutOSC.layoutChanges removeAllObjects]; // since a new OSC profile is being loaded, this will remove all previous layout changes made from the array
|
|
||||||
[self OSCLayoutChanged]; // fades the 'Undo Button' out
|
|
||||||
self->_oscProfilesTableViewController.currentOSCButtonLayers = self.layoutOSC.OSCButtonLayers; //pass updated OSCLayout to OSCProfileTableView again
|
self->_oscProfilesTableViewController.currentOSCButtonLayers = self.layoutOSC.OSCButtonLayers; //pass updated OSCLayout to OSCProfileTableView again
|
||||||
//[self reloadOnScreenKeyboardButtons];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
[self.oscProfilesTableViewController profileViewRefresh]; // execute this will make sure OSCLayout is updated from persisted profile, not any cache.
|
[self.oscProfilesTableViewController profileViewRefresh]; // execute this will make sure OSCLayout is updated from persisted profile, not any cache.
|
||||||
@@ -1133,16 +1171,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
_oscProfilesTableViewController = [storyboard instantiateViewControllerWithIdentifier:@"OSCProfilesTableViewController"];
|
_oscProfilesTableViewController = [storyboard instantiateViewControllerWithIdentifier:@"OSCProfilesTableViewController"];
|
||||||
_oscProfilesTableViewController.streamViewBounds = self.view.bounds;
|
_oscProfilesTableViewController.layoutViewBounds = self.view.bounds;
|
||||||
|
|
||||||
_oscProfilesTableViewController.needToUpdateOscLayoutTVC = ^() { // a block that will be called when the modally presented 'OSCProfilesTableViewController' VC is dismissed. By the time the 'OSCProfilesTableViewController' VC is dismissed the user would have potentially selected a different OSC ofile with a different layout and they want to see this layout on this 'LayoutOnScreenControlsViewController.' This block of code will load the proffile and then hide/show and move each OSC button to their appropriate position
|
_oscProfilesTableViewController.needToUpdateOscLayoutTVC = ^() { // a block that will be called when the modally presented 'OSCProfilesTableViewController' VC is dismissed. By the time the 'OSCProfilesTableViewController' VC is dismissed the user would have potentially selected a different OSC ofile with a different layout and they want to see this layout on this 'LayoutOnScreenControlsViewController.' This block of code will load the proffile and then hide/show and move each OSC button to their appropriate position
|
||||||
[self.layoutOSC updateControls]; // creates and saves a 'Default' OSC profile or loads the one the user selected on the previous screen
|
[self reloadLegacyOnScreenControls];
|
||||||
|
|
||||||
[self addInnerAnalogSticksToOuterAnalogLayers];
|
|
||||||
|
|
||||||
[self.layoutOSC.layoutChanges removeAllObjects]; // since a new OSC profile is being loaded, this will remove all previous layout changes made from the array
|
|
||||||
|
|
||||||
[self OSCLayoutChanged]; // fades the 'Undo Button' out
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.widgetPanelStack.hidden = YES;
|
self.widgetPanelStack.hidden = YES;
|
||||||
@@ -1252,7 +1284,7 @@
|
|||||||
|
|
||||||
if(!isToolbarHidden && self->selectedWidgetView != nil && [self layerIsOverlappingWithTrashcanButton:selectedWidgetView.layer]){
|
if(!isToolbarHidden && self->selectedWidgetView != nil && [self layerIsOverlappingWithTrashcanButton:selectedWidgetView.layer]){
|
||||||
[self->selectedWidgetView removeFromSuperview];
|
[self->selectedWidgetView removeFromSuperview];
|
||||||
[self.OnScreenWidgetViews removeObject:self->selectedWidgetView];
|
[self.onScreenWidgetViews removeObject:self->selectedWidgetView];
|
||||||
[self clearStickIndicator];
|
[self clearStickIndicator];
|
||||||
[selectedWidgetView.buttonDownVisualEffectLayer removeFromSuperlayer];
|
[selectedWidgetView.buttonDownVisualEffectLayer removeFromSuperlayer];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ typedef NS_ENUM(NSUInteger, FileOperation) {
|
|||||||
@property (weak, nonatomic) IBOutlet UITableView *tableView;
|
@property (weak, nonatomic) IBOutlet UITableView *tableView;
|
||||||
@property (nonatomic, copy) void (^needToUpdateOscLayoutTVC)(void);
|
@property (nonatomic, copy) void (^needToUpdateOscLayoutTVC)(void);
|
||||||
@property (nonatomic, assign) NSMutableArray *currentOSCButtonLayers;
|
@property (nonatomic, assign) NSMutableArray *currentOSCButtonLayers;
|
||||||
@property (nonatomic, assign) CGRect streamViewBounds;
|
@property (nonatomic, assign) CGRect layoutViewBounds;
|
||||||
@property (weak, nonatomic) IBOutlet UINavigationBar *profileTableViewNavigationBar;
|
@property (weak, nonatomic) IBOutlet UINavigationBar *profileTableViewNavigationBar;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ const double NAV_BAR_HEIGHT = 50;
|
|||||||
|
|
||||||
// self.profileTableViewNavigationBar.layer.cornerRadius = 15; // 设置圆角半径
|
// self.profileTableViewNavigationBar.layer.cornerRadius = 15; // 设置圆角半径
|
||||||
|
|
||||||
profilesManager = [OSCProfilesManager sharedManager:_streamViewBounds];
|
profilesManager = [OSCProfilesManager sharedManager:_layoutViewBounds];
|
||||||
|
|
||||||
self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, NAV_BAR_HEIGHT)];
|
self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, NAV_BAR_HEIGHT)];
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#import "DiscoveryManager.h"
|
#import "DiscoveryManager.h"
|
||||||
#import "PairManager.h"
|
#import "PairManager.h"
|
||||||
#import "StreamConfiguration.h"
|
#import "StreamConfiguration.h"
|
||||||
#import "UIComputerView.h"
|
|
||||||
#import "HostCardView.h"
|
#import "HostCardView.h"
|
||||||
#import "UIAppView.h"
|
#import "UIAppView.h"
|
||||||
#import "AppAssetManager.h"
|
#import "AppAssetManager.h"
|
||||||
@@ -21,7 +20,7 @@
|
|||||||
#import "HostCollectionViewController.h"
|
#import "HostCollectionViewController.h"
|
||||||
|
|
||||||
|
|
||||||
@interface MainFrameViewController : UICollectionViewController <DiscoveryCallback, PairCallback, HostCallback, AppCallback, AppAssetCallback, NSURLConnectionDelegate, SWRevealViewControllerDelegate, HostCardActionDelegate, AppViewUpdateLoopDelegate>
|
@interface MainFrameViewController : UICollectionViewController <DiscoveryCallback, PairCallback, AppCallback, AppAssetCallback, NSURLConnectionDelegate, SWRevealViewControllerDelegate, HostCardActionDelegate, AppViewUpdateLoopDelegate>
|
||||||
|
|
||||||
@property (nonatomic, strong) IBOutlet UIBarButtonItem *settingsButton;
|
@property (nonatomic, strong) IBOutlet UIBarButtonItem *settingsButton;
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
#import "Connection.h"
|
#import "Connection.h"
|
||||||
#import "StreamManager.h"
|
#import "StreamManager.h"
|
||||||
#import "Utils.h"
|
#import "Utils.h"
|
||||||
#import "UIComputerView.h"
|
|
||||||
#import "UIAppView.h"
|
#import "UIAppView.h"
|
||||||
#import "DataManager.h"
|
#import "DataManager.h"
|
||||||
#import "TemporarySettings.h"
|
#import "TemporarySettings.h"
|
||||||
@@ -25,7 +24,6 @@
|
|||||||
#import "ServerInfoResponse.h"
|
#import "ServerInfoResponse.h"
|
||||||
#import "StreamFrameViewController.h"
|
#import "StreamFrameViewController.h"
|
||||||
#import "LoadingFrameViewController.h"
|
#import "LoadingFrameViewController.h"
|
||||||
#import "ComputerScrollView.h"
|
|
||||||
#import "TemporaryApp.h"
|
#import "TemporaryApp.h"
|
||||||
#import "IdManager.h"
|
#import "IdManager.h"
|
||||||
#import "ConnectionHelper.h"
|
#import "ConnectionHelper.h"
|
||||||
@@ -597,22 +595,24 @@ static NSMutableSet* hostList;
|
|||||||
Log(LOG_D, @"Long clicked host: %@", host.name);
|
Log(LOG_D, @"Long clicked host: %@", host.name);
|
||||||
NSString* message;
|
NSString* message;
|
||||||
|
|
||||||
|
NSString* hostAddress = [host.activeAddress componentsSeparatedByString:@":"].firstObject;
|
||||||
|
|
||||||
switch (host.state) {
|
switch (host.state) {
|
||||||
case StateOffline:
|
case StateOffline:
|
||||||
message = [LocalizationHelper localizedStringForKey:@"Offline"];
|
message = [LocalizationHelper localizedStringForKey:@"Offline\n%@", hostAddress ? hostAddress : @"Unknown address"];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StateOnline:
|
case StateOnline:
|
||||||
if (host.pairState == PairStatePaired) {
|
if (host.pairState == PairStatePaired) {
|
||||||
message = [LocalizationHelper localizedStringForKey:@"Online - Paired"];
|
message = [LocalizationHelper localizedStringForKey:@"Online - Paired\n%@", hostAddress ? hostAddress : @"Unknown address"];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message = [LocalizationHelper localizedStringForKey:@"Online - Not Paired"];
|
message = [LocalizationHelper localizedStringForKey:@"Online - Not Paired\n%@", hostAddress ? hostAddress : @"Unknown address"];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StateUnknown:
|
case StateUnknown:
|
||||||
message = [LocalizationHelper localizedStringForKey:@"Connecting"];
|
message = [LocalizationHelper localizedStringForKey:@"Connecting\n"];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -622,7 +622,7 @@ static NSMutableSet* hostList;
|
|||||||
UIAlertController* longClickAlert = [UIAlertController alertControllerWithTitle:host.name message:message preferredStyle:UIAlertControllerStyleActionSheet];
|
UIAlertController* longClickAlert = [UIAlertController alertControllerWithTitle:host.name message:message preferredStyle:UIAlertControllerStyleActionSheet];
|
||||||
|
|
||||||
if (host.state != StateOnline) {
|
if (host.state != StateOnline) {
|
||||||
/*[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Wake PC"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Wake PC"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
||||||
UIAlertController* wolAlert = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Wake-On-LAN"] message:@"" preferredStyle:UIAlertControllerStyleAlert];
|
UIAlertController* wolAlert = [UIAlertController alertControllerWithTitle:[LocalizationHelper localizedStringForKey:@"Wake-On-LAN"] message:@"" preferredStyle:UIAlertControllerStyleAlert];
|
||||||
[wolAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:nil]];
|
[wolAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Ok"] style:UIAlertActionStyleDefault handler:nil]];
|
||||||
if (host.mac == nil || [host.mac isEqualToString:@"00:00:00:00:00:00"]) {
|
if (host.mac == nil || [host.mac isEqualToString:@"00:00:00:00:00:00"]) {
|
||||||
@@ -634,7 +634,7 @@ static NSMutableSet* hostList;
|
|||||||
wolAlert.message = [LocalizationHelper localizedStringForKey:@"Successfully sent wake-up request. It may take a few moments for the PC to wake. If it never wakes up, ensure it's properly configured for Wake-on-LAN."];
|
wolAlert.message = [LocalizationHelper localizedStringForKey:@"Successfully sent wake-up request. It may take a few moments for the PC to wake. If it never wakes up, ensure it's properly configured for Wake-on-LAN."];
|
||||||
}
|
}
|
||||||
[[self activeViewController] presentViewController:wolAlert animated:YES completion:nil];
|
[[self activeViewController] presentViewController:wolAlert animated:YES completion:nil];
|
||||||
}]];*/
|
}]];
|
||||||
}
|
}
|
||||||
else if (host.pairState == PairStatePaired) {
|
else if (host.pairState == PairStatePaired) {
|
||||||
/*
|
/*
|
||||||
@@ -644,18 +644,14 @@ static NSMutableSet* hostList;
|
|||||||
}]]; */
|
}]]; */
|
||||||
|
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
if (false) {
|
|
||||||
[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"NVIDIA GameStream End-of-Service"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
|
||||||
[Utils launchUrl:@"https://github.com/moonlight-stream/moonlight-docs/wiki/NVIDIA-GameStream-End-Of-Service-Announcement-FAQ"];
|
|
||||||
}]];
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Test Network"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action) {
|
/*[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Test Network"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action) {
|
||||||
[self showLoadingFrame:^{
|
[self showLoadingFrame:^{
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
// Perform the network test on a GCD worker thread. It may take a while.
|
// Perform the network test on a GCD worker thread. It may take a while.
|
||||||
unsigned int portTestResult = LiTestClientConnectivity(CONN_TEST_SERVER, 443, ML_PORT_FLAG_ALL);
|
unsigned int portTestResult = LiTestClientConnectivity([host.activeAddress UTF8String], 443, ML_PORT_FLAG_ALL);
|
||||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
[self hideLoadingFrame:^{
|
[self hideLoadingFrame:^{
|
||||||
NSString* message;
|
NSString* message;
|
||||||
@@ -681,8 +677,9 @@ static NSMutableSet* hostList;
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}];
|
}];
|
||||||
}]];
|
}]];*/
|
||||||
#if !TARGET_OS_TV
|
#if !TARGET_OS_TV
|
||||||
|
/*
|
||||||
if (host.state != StateOnline) {
|
if (host.state != StateOnline) {
|
||||||
[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"NVIDIA GameStream End-of-Service"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"NVIDIA GameStream End-of-Service"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
||||||
[Utils launchUrl:@"https://github.com/moonlight-stream/moonlight-docs/wiki/NVIDIA-GameStream-End-Of-Service-Announcement-FAQ"];
|
[Utils launchUrl:@"https://github.com/moonlight-stream/moonlight-docs/wiki/NVIDIA-GameStream-End-Of-Service-Announcement-FAQ"];
|
||||||
@@ -690,7 +687,7 @@ static NSMutableSet* hostList;
|
|||||||
[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Connection Help"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Connection Help"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){
|
||||||
[Utils launchUrl:@"https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting"];
|
[Utils launchUrl:@"https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting"];
|
||||||
}]];
|
}]];
|
||||||
}
|
}*/
|
||||||
#endif
|
#endif
|
||||||
[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Remove Host"] style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action) { // host removed here
|
[longClickAlert addAction:[UIAlertAction actionWithTitle:[LocalizationHelper localizedStringForKey:@"Remove Host"] style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action) { // host removed here
|
||||||
[self->_discMan removeHostFromDiscovery:host];
|
[self->_discMan removeHostFromDiscovery:host];
|
||||||
@@ -748,7 +745,7 @@ static NSMutableSet* hostList;
|
|||||||
}];
|
}];
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
unsigned int portTestResults = LiTestClientConnectivity(CONN_TEST_SERVER, 443,
|
unsigned int portTestResults = LiTestClientConnectivity([host.activeAddress UTF8String], 443,
|
||||||
ML_PORT_FLAG_TCP_47984 | ML_PORT_FLAG_TCP_47989);
|
ML_PORT_FLAG_TCP_47984 | ML_PORT_FLAG_TCP_47989);
|
||||||
if (portTestResults != ML_TEST_RESULT_INCONCLUSIVE && portTestResults != 0) {
|
if (portTestResults != ML_TEST_RESULT_INCONCLUSIVE && portTestResults != 0) {
|
||||||
error = [error stringByAppendingString:[LocalizationHelper localizedStringForKey:@"!ML_TEST_RESULT_INCONCLUSIVE"]];
|
error = [error stringByAppendingString:[LocalizationHelper localizedStringForKey:@"!ML_TEST_RESULT_INCONCLUSIVE"]];
|
||||||
@@ -1144,7 +1141,7 @@ static NSMutableSet* hostList;
|
|||||||
[settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.audioOnPcStack];
|
[settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.audioOnPcStack];
|
||||||
[settingsViewController.codecSelector setEnabled:!_settingsExpandedInStreamView];
|
[settingsViewController.codecSelector setEnabled:!_settingsExpandedInStreamView];
|
||||||
[settingsViewController.yuv444Switch setEnabled:!_settingsExpandedInStreamView];
|
[settingsViewController.yuv444Switch setEnabled:!_settingsExpandedInStreamView];
|
||||||
[settingsViewController.hdrSwitch setEnabled:!_settingsExpandedInStreamView];
|
[settingsViewController.hdrSwitch setEnabled:!_settingsExpandedInStreamView && [settingsViewController hdrSupported]];
|
||||||
[settingsViewController.gyroModeSelector setEnabled:!_settingsExpandedInStreamView || ![streamFrameViewController shallDisableGyroHotSwitch]];
|
[settingsViewController.gyroModeSelector setEnabled:!_settingsExpandedInStreamView || ![streamFrameViewController shallDisableGyroHotSwitch]];
|
||||||
[settingsViewController.emulatedControllerTypeSelector setEnabled:!_settingsExpandedInStreamView];
|
[settingsViewController.emulatedControllerTypeSelector setEnabled:!_settingsExpandedInStreamView];
|
||||||
[settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.framepacingStack];
|
[settingsViewController setHidden:_settingsExpandedInStreamView forStack:settingsViewController.framepacingStack];
|
||||||
@@ -1470,7 +1467,7 @@ static NSMutableSet* hostList;
|
|||||||
|
|
||||||
if (@available(iOS 13.0, *)) {
|
if (@available(iOS 13.0, *)) {
|
||||||
[_upButton setTitle:@""];
|
[_upButton setTitle:@""];
|
||||||
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:23 weight:UIImageSymbolWeightMedium ];
|
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithPointSize:21.5 weight:UIImageSymbolWeightMedium ];
|
||||||
UIImage *image = [[UIImage systemImageNamed:@"tv" withConfiguration:config] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
UIImage *image = [[UIImage systemImageNamed:@"tv" withConfiguration:config] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
||||||
[_upButton setImage:image];
|
[_upButton setImage:image];
|
||||||
_upButton.imageInsets = UIEdgeInsetsMake(25, 20, 0, 15);
|
_upButton.imageInsets = UIEdgeInsetsMake(25, 20, 0, 15);
|
||||||
@@ -1933,7 +1930,7 @@ static NSMutableSet* hostList;
|
|||||||
[self updateHostShortcuts];
|
[self updateHostShortcuts];
|
||||||
|
|
||||||
// Update the title in case we now have a PC
|
// Update the title in case we now have a PC
|
||||||
[self updateTitle];
|
// [self updateTitle];
|
||||||
|
|
||||||
// Reset state first so we can rediscover hosts that were deleted before
|
// Reset state first so we can rediscover hosts that were deleted before
|
||||||
[_discMan resetDiscoveryState];
|
[_discMan resetDiscoveryState];
|
||||||
@@ -1942,7 +1939,7 @@ static NSMutableSet* hostList;
|
|||||||
// This function forces immediate decoding of the UIImage, rather
|
// This function forces immediate decoding of the UIImage, rather
|
||||||
// than the default lazy decoding that results in janky scrolling.
|
// than the default lazy decoding that results in janky scrolling.
|
||||||
-(void)deviceOrientationDidChange{
|
-(void)deviceOrientationDidChange{
|
||||||
if(self.collectionView.superview == nil) return;
|
if(self.revealViewController.isStreaming || self.collectionView.superview == nil) return;
|
||||||
[NSLayoutConstraint activateConstraints:@[
|
[NSLayoutConstraint activateConstraints:@[
|
||||||
[self.collectionView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
|
[self.collectionView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
|
||||||
[self.collectionView.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
|
[self.collectionView.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
|
||||||
|
|||||||
@@ -133,6 +133,7 @@
|
|||||||
|
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
|
|
||||||
|
- (bool)hdrSupported;
|
||||||
- (void)saveSettings;
|
- (void)saveSettings;
|
||||||
+ (bool)isLandscapeNow;
|
+ (bool)isLandscapeNow;
|
||||||
- (void)updateResolutionTable;
|
- (void)updateResolutionTable;
|
||||||
|
|||||||
@@ -287,6 +287,8 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateResolutionTable{
|
- (void)updateResolutionTable{
|
||||||
|
if(self.mainFrameViewController.settingsExpandedInStreamView) return;
|
||||||
|
|
||||||
UIWindow *window = self.view.window;
|
UIWindow *window = self.view.window;
|
||||||
NSLog(@" window %@", window);
|
NSLog(@" window %@", window);
|
||||||
|
|
||||||
@@ -391,7 +393,7 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
_parentStack.translatesAutoresizingMaskIntoConstraints = NO;
|
_parentStack.translatesAutoresizingMaskIntoConstraints = NO;
|
||||||
[self.scrollView addSubview:_parentStack];
|
[self.scrollView addSubview:_parentStack];
|
||||||
[NSLayoutConstraint activateConstraints:@[
|
[NSLayoutConstraint activateConstraints:@[
|
||||||
[_parentStack.topAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.topAnchor constant: currentSettingsMenuMode == AllSettings ? [self getStandardNavBarHeight] : [self getStandardNavBarHeight]+20],
|
[_parentStack.topAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.topAnchor constant: currentSettingsMenuMode == AllSettings ? [self getStandardNavBarHeight] : [self getStandardNavBarHeight]+10],
|
||||||
[_parentStack.bottomAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.bottomAnchor constant:-20],
|
[_parentStack.bottomAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.bottomAnchor constant:-20],
|
||||||
[_parentStack.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor constant: 0], //mark: settingMenuLayout
|
[_parentStack.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor constant: 0], //mark: settingMenuLayout
|
||||||
[_parentStack.widthAnchor constraintEqualToAnchor:self.view.widthAnchor constant:-20] // section width adjusted here //mark: settingMenuLayout
|
[_parentStack.widthAnchor constraintEqualToAnchor:self.view.widthAnchor constant:-20] // section width adjusted here //mark: settingMenuLayout
|
||||||
@@ -533,7 +535,7 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
|
|
||||||
touchAndControlSection = [[MenuSectionView alloc] init];
|
touchAndControlSection = [[MenuSectionView alloc] init];
|
||||||
touchAndControlSection.delegate = self;
|
touchAndControlSection.delegate = self;
|
||||||
touchAndControlSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Touch & Control"];
|
touchAndControlSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Touch & Controller"];
|
||||||
if (@available(iOS 13.0, *)) {
|
if (@available(iOS 13.0, *)) {
|
||||||
[touchAndControlSection setSectionWithIcon:[UIImage imageNamed:@"arcade.stick.console"] andSize:20.5];
|
[touchAndControlSection setSectionWithIcon:[UIImage imageNamed:@"arcade.stick.console"] andSize:20.5];
|
||||||
}
|
}
|
||||||
@@ -1172,6 +1174,20 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
- (BOOL)isFirstLaunch {
|
||||||
|
NSString *key = @"appHasLaunchedBefore";
|
||||||
|
BOOL launchedBefore = [[NSUserDefaults standardUserDefaults] boolForKey:key];
|
||||||
|
|
||||||
|
if (!launchedBefore) {
|
||||||
|
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:key];
|
||||||
|
[[NSUserDefaults standardUserDefaults] synchronize]; // iOS 12+ 可省略
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
- (void)saveFavoriteSettingStackIdentifiers {
|
- (void)saveFavoriteSettingStackIdentifiers {
|
||||||
|
|
||||||
if(currentSettingsMenuMode != AllSettings){
|
if(currentSettingsMenuMode != AllSettings){
|
||||||
@@ -1181,18 +1197,40 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
[_favoriteSettingStackIdentifiers addObject:_parentStack.arrangedSubviews[i].accessibilityIdentifier];
|
[_favoriteSettingStackIdentifiers addObject:_parentStack.arrangedSubviews[i].accessibilityIdentifier];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:_favoriteSettingStackIdentifiers forKey:@"FavoriteSettingStackIdentifiers"];
|
[[NSUserDefaults standardUserDefaults] setObject:_favoriteSettingStackIdentifiers forKey:@"FavoriteSettingStackIdentifiers"];
|
||||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)loadFavoriteSettingStackIdentifiers {
|
- (void)loadFavoriteSettingStackIdentifiers {
|
||||||
NSArray *savedArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"FavoriteSettingStackIdentifiers"];
|
NSArray *savedArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"FavoriteSettingStackIdentifiers"];
|
||||||
|
|
||||||
if ([savedArray isKindOfClass:[NSArray class]]) {
|
if ([savedArray isKindOfClass:[NSArray class]]) {
|
||||||
_favoriteSettingStackIdentifiers = [savedArray mutableCopy];
|
_favoriteSettingStackIdentifiers = [savedArray mutableCopy];
|
||||||
} else {
|
} else {
|
||||||
_favoriteSettingStackIdentifiers = [NSMutableArray array];
|
_favoriteSettingStackIdentifiers = [NSMutableArray array];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"resolutionStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"fpsStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"bitrateStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"framepacingStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"codecStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"hdrStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"yuv444Stack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"pipStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"touchModeStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"pointerVelocityDividerStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"pointerVelocityFactorStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"mousePointerVelocityStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"onScreenWidgetStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"pipStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"backgroundSessionTimerStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"statsOverlayStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"softKeyboardGestureStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"slideToSettingsScreenEdgeStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"slideToToolboxScreenEdgeStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"slideToSettingsDistanceStack"];
|
||||||
|
[_favoriteSettingStackIdentifiers addObject:@"unlockDisplayOrientationStack"];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
for(NSString* str in _favoriteSettingStackIdentifiers){
|
for(NSString* str in _favoriteSettingStackIdentifiers){
|
||||||
NSLog(@"favarite setting loaded: %@", str);
|
NSLog(@"favarite setting loaded: %@", str);
|
||||||
@@ -1332,7 +1370,7 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
|
|
||||||
if (![self hdrSupported]) {
|
if (![self hdrSupported]) {
|
||||||
[self.hdrSwitch setOn:NO];
|
[self.hdrSwitch setOn:NO];
|
||||||
[self widget:self.hdrSwitch setEnabled:NO];
|
[self.hdrSwitch setEnabled:NO];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
[self.hdrSwitch setOn:currentSettings.enableHdr];
|
[self.hdrSwitch setOn:currentSettings.enableHdr];
|
||||||
@@ -1508,21 +1546,6 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
[self.enableOswForNativeTouchSwitch addTarget:self action:@selector(enableOswForNativeTouchSwitchFlipped:) forControlEvents:UIControlEventValueChanged];
|
[self.enableOswForNativeTouchSwitch addTarget:self action:@selector(enableOswForNativeTouchSwitchFlipped:) forControlEvents:UIControlEventValueChanged];
|
||||||
[self enableOswForNativeTouchSwitchFlipped:self.enableOswForNativeTouchSwitch];
|
[self enableOswForNativeTouchSwitchFlipped:self.enableOswForNativeTouchSwitch];
|
||||||
|
|
||||||
|
|
||||||
// init CustomOSC stuff
|
|
||||||
/* sets a reference to the correct 'LayoutOnScreenControlsViewController' depending on whether the user is on an iPhone or iPad */
|
|
||||||
// self.layoutOnScreenControlsVC = [[LayoutOnScreenControlsViewController alloc] init];
|
|
||||||
BOOL isIPhone = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone);
|
|
||||||
if (isIPhone) {
|
|
||||||
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"iPhone" bundle:nil];
|
|
||||||
self.layoutOnScreenControlsVC = [storyboard instantiateViewControllerWithIdentifier:@"LayoutOnScreenControlsViewController"];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"iPad" bundle:nil];
|
|
||||||
self.layoutOnScreenControlsVC = [storyboard instantiateViewControllerWithIdentifier:@"LayoutOnScreenControlsViewController"];
|
|
||||||
self.layoutOnScreenControlsVC.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
[self.externalDisplayModeSelector setSelectedSegmentIndex:currentSettings.externalDisplayMode.integerValue];
|
[self.externalDisplayModeSelector setSelectedSegmentIndex:currentSettings.externalDisplayMode.integerValue];
|
||||||
[self.localMousePointerModeSelector setSelectedSegmentIndex:currentSettings.localMousePointerMode.integerValue];
|
[self.localMousePointerModeSelector setSelectedSegmentIndex:currentSettings.localMousePointerMode.integerValue];
|
||||||
|
|
||||||
@@ -1628,6 +1651,20 @@ BOOL isCustomResolution(CGSize res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)invokeOscLayout{
|
- (void)invokeOscLayout{
|
||||||
|
// init CustomOSC stuff
|
||||||
|
/* sets a reference to the correct 'LayoutOnScreenControlsViewController' depending on whether the user is on an iPhone or iPad */
|
||||||
|
// self.layoutOnScreenControlsVC = [[LayoutOnScreenControlsViewController alloc] init];
|
||||||
|
BOOL isIPhone = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone);
|
||||||
|
if (isIPhone) {
|
||||||
|
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"iPhone" bundle:nil];
|
||||||
|
self.layoutOnScreenControlsVC = [storyboard instantiateViewControllerWithIdentifier:@"LayoutOnScreenControlsViewController"];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"iPad" bundle:nil];
|
||||||
|
self.layoutOnScreenControlsVC = [storyboard instantiateViewControllerWithIdentifier:@"LayoutOnScreenControlsViewController"];
|
||||||
|
self.layoutOnScreenControlsVC.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||||
|
}
|
||||||
|
|
||||||
self.layoutOnScreenControlsVC.view.backgroundColor = [UIColor colorWithWhite:0.55 alpha:1.0];
|
self.layoutOnScreenControlsVC.view.backgroundColor = [UIColor colorWithWhite:0.55 alpha:1.0];
|
||||||
[self presentViewController:self.layoutOnScreenControlsVC animated:YES completion:nil];
|
[self presentViewController:self.layoutOnScreenControlsVC animated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
UIScrollView *_scrollView;
|
UIScrollView *_scrollView;
|
||||||
BOOL _userIsInteracting;
|
BOOL _userIsInteracting;
|
||||||
bool viewJustLoaded;
|
bool viewJustLoaded;
|
||||||
|
bool viewIsBeingResized;
|
||||||
CGSize _keyboardSize;
|
CGSize _keyboardSize;
|
||||||
PlotMetrics _decodeMetrics;
|
PlotMetrics _decodeMetrics;
|
||||||
PlotMetrics _frameDropMetrics;
|
PlotMetrics _frameDropMetrics;
|
||||||
@@ -241,15 +242,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)configOscLayoutTool{
|
- (void)configOscLayoutTool{
|
||||||
|
|
||||||
if([self isOscLayoutToolEnabled]){
|
if([self isOscLayoutToolEnabled]){
|
||||||
_oscLayoutTapRecoginizer = [[CustomTapGestureRecognizer alloc] initWithTarget:self action:@selector(openWidgetLayoutTool)];
|
|
||||||
_oscLayoutTapRecoginizer.numberOfTouchesRequired = _settings.oscLayoutToolFingers.intValue; //tap a predefined number of fingers to open osc layout tool
|
|
||||||
_oscLayoutTapRecoginizer.tapDownTimeThreshold = 0.2;
|
|
||||||
_oscLayoutTapRecoginizer.delaysTouchesBegan = NO;
|
|
||||||
_oscLayoutTapRecoginizer.delaysTouchesEnded = NO;
|
|
||||||
if(_settings.touchMode.intValue == AbsoluteTouch) _oscLayoutTapRecoginizer.immediateTriggering = true; // make immediate triggering on for absolute touch mode
|
|
||||||
|
|
||||||
[self.view addGestureRecognizer:_oscLayoutTapRecoginizer]; //
|
|
||||||
/* sets a reference to the correct 'LayoutOnScreenControlsViewController' depending on whether the user is on an iPhone or iPad */
|
/* sets a reference to the correct 'LayoutOnScreenControlsViewController' depending on whether the user is on an iPhone or iPad */
|
||||||
// _layoutOnScreenControlsVC = [[LayoutOnScreenControlsViewController alloc] init];
|
// _layoutOnScreenControlsVC = [[LayoutOnScreenControlsViewController alloc] init];
|
||||||
BOOL isIPhone = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone);
|
BOOL isIPhone = ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone);
|
||||||
@@ -265,20 +259,22 @@
|
|||||||
_layoutOnScreenControlsVC.view.backgroundColor = UIColor.clearColor;
|
_layoutOnScreenControlsVC.view.backgroundColor = UIColor.clearColor;
|
||||||
_layoutOnScreenControlsVC.modalPresentationStyle = UIModalPresentationOverCurrentContext;
|
_layoutOnScreenControlsVC.modalPresentationStyle = UIModalPresentationOverCurrentContext;
|
||||||
}
|
}
|
||||||
|
//NSLog(@"in osc frameview gestures: %d", (uint32_t)[self.view.gestureRecognizers count]);
|
||||||
|
//NSLog(@"in osc streamview gestures: %d", (uint32_t)[_streamView.gestureRecognizers count]);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)presentToolboxViewController{
|
- (void)presentToolboxViewController{
|
||||||
|
[self configOscLayoutTool];
|
||||||
ToolboxViewController* oldToolboxVC = toolBoxViewController;
|
ToolboxViewController* oldToolboxVC = toolBoxViewController;
|
||||||
toolBoxViewController = [[ToolboxViewController alloc] init];
|
toolBoxViewController = [[ToolboxViewController alloc] init];
|
||||||
toolBoxViewController.specialEntryDelegate = self;
|
toolBoxViewController.specialEntryDelegate = self;
|
||||||
toolBoxViewController.specialEntries = oldToolboxVC.specialEntries;
|
toolBoxViewController.specialEntries = oldToolboxVC.specialEntries;
|
||||||
[self configOscLayoutTool];
|
|
||||||
[self presentViewController:toolBoxViewController animated:YES completion:^{
|
[self presentViewController:toolBoxViewController animated:YES completion:^{
|
||||||
//[self->toolBoxViewController setupConstraints];
|
//[self->toolBoxViewController setupConstraints];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)configSwipeGestures{
|
- (void)configGestures{
|
||||||
_slideToSettingsRecognizer = [[CustomEdgeSlideGestureRecognizer alloc] initWithTarget:self action:@selector(edgeSwiped)];
|
_slideToSettingsRecognizer = [[CustomEdgeSlideGestureRecognizer alloc] initWithTarget:self action:@selector(edgeSwiped)];
|
||||||
_slideToSettingsRecognizer.edges = _settings.slideToSettingsScreenEdge.intValue;
|
_slideToSettingsRecognizer.edges = _settings.slideToSettingsScreenEdge.intValue;
|
||||||
_slideToSettingsRecognizer.normalizedThresholdDistance = _settings.slideToSettingsDistance.floatValue;
|
_slideToSettingsRecognizer.normalizedThresholdDistance = _settings.slideToSettingsDistance.floatValue;
|
||||||
@@ -294,6 +290,17 @@
|
|||||||
_slideToCmdToolRecognizer.delaysTouchesBegan = NO;
|
_slideToCmdToolRecognizer.delaysTouchesBegan = NO;
|
||||||
_slideToCmdToolRecognizer.delaysTouchesEnded = NO;
|
_slideToCmdToolRecognizer.delaysTouchesEnded = NO;
|
||||||
[self.view addGestureRecognizer:_slideToCmdToolRecognizer];
|
[self.view addGestureRecognizer:_slideToCmdToolRecognizer];
|
||||||
|
|
||||||
|
if([self isOscLayoutToolEnabled]){
|
||||||
|
_oscLayoutTapRecoginizer = [[CustomTapGestureRecognizer alloc] initWithTarget:self action:@selector(handleWidgetLayoutGesture)];
|
||||||
|
_oscLayoutTapRecoginizer.numberOfTouchesRequired = _settings.oscLayoutToolFingers.intValue; //tap a predefined number of fingers to open osc layout tool
|
||||||
|
_oscLayoutTapRecoginizer.tapDownTimeThreshold = 0.2;
|
||||||
|
_oscLayoutTapRecoginizer.delaysTouchesBegan = NO;
|
||||||
|
_oscLayoutTapRecoginizer.delaysTouchesEnded = NO;
|
||||||
|
if(_settings.touchMode.intValue == AbsoluteTouch) _oscLayoutTapRecoginizer.immediateTriggering = true; // make immediate triggering on for absolute touch mode
|
||||||
|
[self.view addGestureRecognizer:_oscLayoutTapRecoginizer]; //
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)configZoomGestureAndAddStreamView{
|
- (void)configZoomGestureAndAddStreamView{
|
||||||
@@ -337,9 +344,10 @@
|
|||||||
_settings = [[[DataManager alloc] init] getSettings]; //StreamFrameViewController retrieve the settings here.
|
_settings = [[[DataManager alloc] init] getSettings]; //StreamFrameViewController retrieve the settings here.
|
||||||
}
|
}
|
||||||
overlayLevel = _settings.statsOverlayLevel.intValue;
|
overlayLevel = _settings.statsOverlayLevel.intValue;
|
||||||
[self configOscLayoutTool];
|
if(viewIsBeingResized) viewIsBeingResized = false;
|
||||||
|
else [self configOscLayoutTool];
|
||||||
[self updateToolboxSpecialEntries];
|
[self updateToolboxSpecialEntries];
|
||||||
[self configSwipeGestures];
|
[self configGestures];
|
||||||
[self configZoomGestureAndAddStreamView];
|
[self configZoomGestureAndAddStreamView];
|
||||||
[self->_streamView disableOnScreenControls]; //don't know why but this must be called outside the streamview class, just put it here. execute in streamview class cause hang
|
[self->_streamView disableOnScreenControls]; //don't know why but this must be called outside the streamview class, just put it here. execute in streamview class cause hang
|
||||||
[self.mainFrameViewcontroller reloadStreamConfig]; // reload streamconfig
|
[self.mainFrameViewcontroller reloadStreamConfig]; // reload streamconfig
|
||||||
@@ -542,6 +550,7 @@
|
|||||||
- (void)viewDidLoad
|
- (void)viewDidLoad
|
||||||
{
|
{
|
||||||
viewJustLoaded = true;
|
viewJustLoaded = true;
|
||||||
|
viewIsBeingResized = false;
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
|
||||||
[self.navigationController setNavigationBarHidden:YES animated:YES];
|
[self.navigationController setNavigationBarHidden:YES animated:YES];
|
||||||
@@ -699,10 +708,15 @@
|
|||||||
[_streamView keyboardWillHide];
|
[_streamView keyboardWillHide];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)handleWidgetLayoutGesture{
|
||||||
|
[self configOscLayoutTool];
|
||||||
|
[self openWidgetLayoutTool];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)openWidgetLayoutTool{
|
- (void)openWidgetLayoutTool{
|
||||||
|
_streamView.widgetToolOpened = true;
|
||||||
[self->_streamView disableOnScreenControls];
|
[self->_streamView disableOnScreenControls];
|
||||||
[self->_streamView clearOnScreenKeyboardButtons]; // clear all onScreenKeyboardButtons before entering edit mode
|
[self->_streamView clearOnScreenWidgets]; // clear all onScreenKeyboardButtons before entering edit mode
|
||||||
_layoutOnScreenControlsVC.quickSwitchEnabled = false;
|
_layoutOnScreenControlsVC.quickSwitchEnabled = false;
|
||||||
_layoutOnScreenControlsVC.toolbarStackView.hidden = false;
|
_layoutOnScreenControlsVC.toolbarStackView.hidden = false;
|
||||||
_layoutOnScreenControlsVC.toolbarRootView.hidden = false;
|
_layoutOnScreenControlsVC.toolbarRootView.hidden = false;
|
||||||
@@ -710,8 +724,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)switchWidgetProfile{
|
- (void)switchWidgetProfile{
|
||||||
|
_streamView.widgetToolOpened = true;
|
||||||
[self->_streamView disableOnScreenControls];
|
[self->_streamView disableOnScreenControls];
|
||||||
[self->_streamView clearOnScreenKeyboardButtons]; // clear all onScreenKeyboardButtons before entering edit mode
|
[self->_streamView clearOnScreenWidgets]; // clear all onScreenKeyboardButtons before entering edit mode
|
||||||
_layoutOnScreenControlsVC.quickSwitchEnabled = true;
|
_layoutOnScreenControlsVC.quickSwitchEnabled = true;
|
||||||
_layoutOnScreenControlsVC.toolbarStackView.hidden = true;
|
_layoutOnScreenControlsVC.toolbarStackView.hidden = true;
|
||||||
_layoutOnScreenControlsVC.toolbarRootView.hidden = true;
|
_layoutOnScreenControlsVC.toolbarRootView.hidden = true;
|
||||||
@@ -730,6 +745,7 @@
|
|||||||
|
|
||||||
- (void)oscLayoutClosed{
|
- (void)oscLayoutClosed{
|
||||||
// Handle the callback
|
// Handle the callback
|
||||||
|
_streamView.widgetToolOpened = false;
|
||||||
[self->_streamView disableOnScreenControls]; // add this to get realtime back menu working.
|
[self->_streamView disableOnScreenControls]; // add this to get realtime back menu working.
|
||||||
[self->_streamView reloadOnScreenControlsWith:(ControllerSupport*)_controllerSupport
|
[self->_streamView reloadOnScreenControlsWith:(ControllerSupport*)_controllerSupport
|
||||||
andConfig:(StreamConfiguration*)_streamConfig];
|
andConfig:(StreamConfiguration*)_streamConfig];
|
||||||
@@ -928,6 +944,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void) handleViewResize{
|
- (void) handleViewResize{
|
||||||
|
viewIsBeingResized = true;
|
||||||
_streamView.bounds = _deviceWindow.bounds;
|
_streamView.bounds = _deviceWindow.bounds;
|
||||||
_streamView.frame = _deviceWindow.frame;
|
_streamView.frame = _deviceWindow.frame;
|
||||||
if(![self isAirPlaying]){
|
if(![self isAirPlaying]){
|
||||||
|
|||||||
Reference in new issue
Block a user