first pass at custom keyboard

This commit is contained in:
Yoshi Sugawara 2020-07-31 15:22:03 -10:00
parent cc2221b434
commit 1b3d11c06b
8 changed files with 547 additions and 16 deletions

View File

@ -81,6 +81,8 @@
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>

View File

@ -245,6 +245,7 @@
9250DCB31CAEEF990093CE9A /* MfiGameControllerHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 9250DCB21CAEEF990093CE9A /* MfiGameControllerHandler.m */; };
9250DCB51CAEFD3B0093CE9A /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9250DCB41CAEFD3B0093CE9A /* GameController.framework */; };
928410581CA8443A00DC5D93 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 928410571CA8443A00DC5D93 /* Images.xcassets */; };
92B9EADF24D3369700E6CFB2 /* EmulatorKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92B9EADE24D3369700E6CFB2 /* EmulatorKeyboard.swift */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
@ -252,6 +253,8 @@
isa = PBXBuildRule;
compilerSpec = com.apple.compilers.proxy.script;
fileType = pattern.proxy;
inputFiles = (
);
isEditable = 1;
outputFiles = (
);
@ -593,6 +596,8 @@
9250DCB21CAEEF990093CE9A /* MfiGameControllerHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MfiGameControllerHandler.m; sourceTree = "<group>"; };
9250DCB41CAEFD3B0093CE9A /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; };
928410571CA8443A00DC5D93 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ActiveGS/Images.xcassets; sourceTree = "<group>"; };
92B9EADD24D3369600E6CFB2 /* ActiveGS-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ActiveGS-Bridging-Header.h"; sourceTree = "<group>"; };
92B9EADE24D3369700E6CFB2 /* EmulatorKeyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmulatorKeyboard.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -1006,6 +1011,8 @@
924A1BB11CB9685700D69162 /* KeyCapView.m */,
924A1BB31CBA049D00D69162 /* KeyMapper.h */,
924A1BB41CBA049D00D69162 /* KeyMapper.m */,
92B9EADE24D3369700E6CFB2 /* EmulatorKeyboard.swift */,
92B9EADD24D3369600E6CFB2 /* ActiveGS-Bridging-Header.h */,
);
name = Common.iphone;
path = ../Common.iphone;
@ -1149,6 +1156,7 @@
LastUpgradeCheck = 0820;
TargetAttributes = {
1D6058900D05DD3D006BFB54 = {
LastSwiftMigration = 1160;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.DataProtection = {
@ -1332,6 +1340,7 @@
09BB434711D92F65005ADA46 /* CEmulatorCtrlMac.cpp in Sources */,
09BB43B011D92F70005ADA46 /* activeconfig.cpp in Sources */,
09BB43B111D92F70005ADA46 /* ActiveDownload.cpp in Sources */,
92B9EADF24D3369700E6CFB2 /* EmulatorKeyboard.swift in Sources */,
09052B9419053C9F00853FAE /* uncompr.cpp in Sources */,
09BB43B211D92F70005ADA46 /* ActiveZip.cpp in Sources */,
09052B8619053C9F00853FAE /* pngwtran.cpp in Sources */,
@ -1459,12 +1468,13 @@
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
DEVELOPMENT_TEAM = TFQRCMRWP4;
DEVELOPMENT_TEAM = R72X3BF4KE;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = activegs_Prefix.pch;
GCC_PREPROCESSOR_DEFINITIONS = (
@ -1479,7 +1489,8 @@
GCC_THUMB_SUPPORT = NO;
GCC_VERSION = "";
INFOPLIST_FILE = activegs.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/GraphicsServices.framework\"",
@ -1489,6 +1500,8 @@
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = iphoneos;
SWIFT_OBJC_BRIDGING_HEADER = "../Common.iphone/ActiveGS-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
@ -1500,12 +1513,13 @@
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEVELOPMENT_TEAM = TFQRCMRWP4;
DEVELOPMENT_TEAM = R72X3BF4KE;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
@ -1522,7 +1536,8 @@
GCC_THUMB_SUPPORT = NO;
GCC_VERSION = "";
INFOPLIST_FILE = activegs.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/GraphicsServices.framework\"",
@ -1532,6 +1547,9 @@
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = iphoneos;
SWIFT_OBJC_BRIDGING_HEADER = "../Common.iphone/ActiveGS-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@ -1542,12 +1560,13 @@
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
DEVELOPMENT_TEAM = TFQRCMRWP4;
DEVELOPMENT_TEAM = R72X3BF4KE;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = activegs_Prefix.pch;
GCC_PREPROCESSOR_DEFINITIONS = (
@ -1561,7 +1580,8 @@
GCC_THUMB_SUPPORT = NO;
GCC_VERSION = "";
INFOPLIST_FILE = activegs.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks/GraphicsServices.framework\"",
@ -1571,6 +1591,8 @@
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = iphoneos;
SWIFT_OBJC_BRIDGING_HEADER = "../Common.iphone/ActiveGS-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};

View File

@ -0,0 +1,5 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "KeyMapper.h"

View File

@ -0,0 +1,428 @@
//
// EmulatorKeyboard.swift
// ActiveGS
//
// Created by Yoshi Sugawara on 7/30/20.
//
import Foundation
import UIKit
class KeyboardButton: UIButton {
let key: KeyCoded
var isModifierToggle = false
var toggleState = false
// MARK: - Functions
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let newArea = CGRect(
x: self.bounds.origin.x - 5.0,
y: self.bounds.origin.y - 5.0,
width: self.bounds.size.width + 20.0,
height: self.bounds.size.height + 20.0
)
return newArea.contains(point)
}
override open var isHighlighted: Bool {
didSet {
// this is the problem - the isHighlighted sets to false for the touchesEnded callback
// need to look ask something else
// let shouldHighlight = isModifierToggle ? toggleState : isHighlighted
if !isHighlighted && toggleState {
// don't update the highlught
} else {
backgroundColor = isHighlighted ? .white : .black
}
}
}
override open var isSelected: Bool {
didSet {
let shouldHighlight = isModifierToggle ? toggleState : isSelected
backgroundColor = shouldHighlight ? .red : .black
}
}
required init(key: KeyCoded, isModifier: Bool = false) {
self.key = key
self.isModifierToggle = isModifier
super.init(frame: .zero)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
@objc protocol EmulatorKeyboardKeyPressedDelegate: class {
func keyDown(_ key: KeyCoded)
func keyUp(_ key: KeyCoded)
}
@objc protocol EmulatorKeyboardModifierPressedDelegate: class {
func modifierPressedWithKey(_ key: KeyCoded, enable: Bool)
func isModifierEnabled(key: KeyCoded) -> Bool
}
class EmulatorKeyboardView: UIView {
@objc weak var delegate: EmulatorKeyboardKeyPressedDelegate?
@objc weak var modifierDelegate: EmulatorKeyboardModifierPressedDelegate?
var keyRowsDataSource: KeyRowsDataSource?
private var keyRowsStackView: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .equalCentering
stackView.spacing = 16
return stackView
}()
let dragMeView: UILabel = {
let label = UILabel(frame: .zero)
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "DRAG ME!"
label.textColor = UIColor.systemRed
return label
}()
private var pressedKeyLabels = [String: UILabel]()
convenience init() {
self.init(frame: CGRect.zero)
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
backgroundColor = .clear
layer.borderColor = UIColor.white.cgColor
layer.borderWidth = 1.0
layer.cornerRadius = 15.0
layoutMargins = UIEdgeInsets(top: 16, left: 4, bottom: 16, right: 4)
insetsLayoutMarginsFromSafeArea = false
addSubview(keyRowsStackView)
keyRowsStackView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true
keyRowsStackView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor).isActive = true
keyRowsStackView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor).isActive = true
addSubview(dragMeView)
dragMeView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
dragMeView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8.0).isActive = true
}
@objc private func keyPressed(_ sender: KeyboardButton) {
let label = UILabel(frame: .zero)
label.text = sender.titleLabel?.text
// hmm need to convert frame
let converted = sender.convert(sender.bounds, to: self)
print("sender frame: \(sender.frame), bounds: \(sender.bounds), convertedBounds = \(converted)")
var labelFrame = converted.offsetBy(dx: 0, dy: -60)
labelFrame = CGRect(x: labelFrame.origin.x, y: labelFrame.origin.y, width: labelFrame.width * 2, height: labelFrame.height * 2)
label.backgroundColor = .purple
label.textColor = .green
label.frame = labelFrame
addSubview(label)
pressedKeyLabels[label.text ?? "😭"] = label
if sender.isModifierToggle {
let isPressed = modifierDelegate?.isModifierEnabled(key: sender.key) ?? false
modifierDelegate?.modifierPressedWithKey(sender.key, enable: !isPressed)
}
delegate?.keyDown(sender.key)
}
@objc private func keyReleased(_ sender: KeyboardButton) {
// pass to delegate
let title = sender.titleLabel?.text ?? "😭"
// pressedKeyLabels.forEach { _, value in
// value.removeFromSuperview()
// }
if let label = pressedKeyLabels[title] {
label.removeFromSuperview()
pressedKeyLabels.removeValue(forKey: title)
}
if sender.isModifierToggle {
if modifierDelegate?.isModifierEnabled(key: sender.key) ?? false {
sender.toggleState = true
sender.isSelected = true
} else {
sender.toggleState = false
sender.isSelected = false
}
}
delegate?.keyUp(sender.key)
}
func setupWithModel(_ model: AppleIIKeysCluster) {
for row in model.keys {
let keysInRow = createKeyRow(keys: row)
keyRowsStackView.addArrangedSubview(keysInRow)
}
keyRowsDataSource = model
}
private func createKey(_ keyCoded: KeyCoded) -> UIButton {
let testKey = KeyboardButton(key: keyCoded, isModifier: keyCoded.isModifier)
testKey.setTitle(keyCoded.keyLabel, for: .normal)
testKey.titleLabel?.font = UIFont.systemFont(ofSize: 12.0)
testKey.setTitleColor(.white, for: .normal)
testKey.setTitleColor(.black, for: .highlighted)
testKey.translatesAutoresizingMaskIntoConstraints = false
testKey.widthAnchor.constraint(equalToConstant: (25 * CGFloat(keyCoded.keySize.rawValue))).isActive = true
testKey.heightAnchor.constraint(equalToConstant: 25).isActive = true
testKey.layer.borderWidth = 1.0
testKey.layer.borderColor = UIColor.white.cgColor
testKey.addTarget(self, action: #selector(keyPressed(_:)), for: .touchDown)
testKey.addTarget(self, action: #selector(keyReleased(_:)), for: .touchUpInside)
testKey.addTarget(self, action: #selector(keyReleased(_:)), for: .touchUpOutside)
return testKey
}
private func createKeyRow(keys: [KeyCoded]) -> UIStackView {
let spacer = UIView()
var subviews: [UIView] = keys.enumerated().map { index, keyCoded -> UIView in
createKey(keyCoded)
}
subviews.append(spacer)
let stack = UIStackView(arrangedSubviews: subviews)
stack.axis = .horizontal
stack.distribution = .fill
stack.spacing = 8
return stack
}
}
// represents a key that has an underlying code that gets sent to the emulator
@objc enum KeySize: Int {
case standard = 1, wide, wider
}
@objc protocol KeyCoded: AnyObject {
var keyLabel: String { get }
var keyCode: Int { get }
var keySize: KeySize { get }
var isModifier: Bool { get }
}
protocol KeyRowsDataSource {
func keyForPositionAt(_ position: KeyPosition) -> KeyCoded?
}
@objc class AppleIIKey: NSObject, KeyCoded {
let keyLabel: String
let keyCode: Int
let keySize: KeySize
let isModifier: Bool
override var description: String {
return String(format: "\(keyLabel) (%02X)", keyCode)
}
init(label: String, code: Int, keySize: KeySize, isModifier: Bool = false) {
self.keyLabel = label
self.keyCode = code
self.keySize = keySize
self.isModifier = isModifier
}
convenience init(label: String, code: Int) {
self.init(label: label, code: code, keySize: .standard)
}
}
struct KeyPosition {
let row: Int
let column: Int
}
struct AppleIIKeysCluster: KeyRowsDataSource {
var keys = [[AppleIIKey]]()
func keyForPositionAt(_ position: KeyPosition) -> KeyCoded? {
guard position.row < keys.count else {
return nil
}
let row = keys[position.row]
guard position.column < row.count else {
return nil
}
return row[position.column]
}
}
@objc class EmulatorKeyboardController: UIViewController {
@objc let leftKeyboardView = EmulatorKeyboardView()
@objc let rightKeyboardView = EmulatorKeyboardView()
var keyboardConstraints = [NSLayoutConstraint]()
@objc var modifierState: Int16 = 0
let leftKeyboardModel = AppleIIKeysCluster(keys:
[
[
AppleIIKey(label: "q", code: AppleKeyboardKey.KEY_Q.rawValue),
AppleIIKey(label: "w", code: AppleKeyboardKey.KEY_W.rawValue),
AppleIIKey(label: "e", code: AppleKeyboardKey.KEY_E.rawValue),
AppleIIKey(label: "r", code: AppleKeyboardKey.KEY_R.rawValue),
AppleIIKey(label: "t", code: AppleKeyboardKey.KEY_T.rawValue)
],
[
AppleIIKey(label: "a", code: AppleKeyboardKey.KEY_A.rawValue),
AppleIIKey(label: "s", code: AppleKeyboardKey.KEY_S.rawValue),
AppleIIKey(label: "d", code: AppleKeyboardKey.KEY_D.rawValue),
AppleIIKey(label: "f", code: AppleKeyboardKey.KEY_F.rawValue),
AppleIIKey(label: "g", code: AppleKeyboardKey.KEY_G.rawValue)
],
[
AppleIIKey(label: "z", code: AppleKeyboardKey.KEY_Z.rawValue),
AppleIIKey(label: "x", code: AppleKeyboardKey.KEY_X.rawValue),
AppleIIKey(label: "c", code: AppleKeyboardKey.KEY_C.rawValue),
AppleIIKey(label: "v", code: AppleKeyboardKey.KEY_V.rawValue),
AppleIIKey(label: "b", code: AppleKeyboardKey.KEY_B.rawValue)
],
[
AppleIIKey(label: "SHIFT", code: AppleKeyboardKey.KEY_SHIFT.rawValue, keySize: .wide, isModifier: true),
AppleIIKey(label: "SPACE", code: AppleKeyboardKey.KEY_SPACE.rawValue, keySize: .wider)
]
]
)
let rightKeyboardModel = AppleIIKeysCluster(keys:
[
[
AppleIIKey(label: "y", code: AppleKeyboardKey.KEY_Y.rawValue),
AppleIIKey(label: "u", code: AppleKeyboardKey.KEY_U.rawValue),
AppleIIKey(label: "i", code: AppleKeyboardKey.KEY_I.rawValue),
AppleIIKey(label: "o", code: AppleKeyboardKey.KEY_O.rawValue),
AppleIIKey(label: "p", code: AppleKeyboardKey.KEY_P.rawValue)
],
[
AppleIIKey(label: "h", code: AppleKeyboardKey.KEY_H.rawValue),
AppleIIKey(label: "j", code: AppleKeyboardKey.KEY_J.rawValue),
AppleIIKey(label: "k", code: AppleKeyboardKey.KEY_K.rawValue),
AppleIIKey(label: "l", code: AppleKeyboardKey.KEY_L.rawValue),
AppleIIKey(label: "'", code: AppleKeyboardKey.KEY_SQUOTE.rawValue)
],
[
AppleIIKey(label: "n", code: AppleKeyboardKey.KEY_N.rawValue),
AppleIIKey(label: "m", code: AppleKeyboardKey.KEY_M.rawValue),
AppleIIKey(label: ",", code: AppleKeyboardKey.KEY_COMMA.rawValue),
AppleIIKey(label: ".", code: AppleKeyboardKey.KEY_PERIOD.rawValue),
AppleIIKey(label: "/", code: AppleKeyboardKey.KEY_FSLASH.rawValue)
],
[
AppleIIKey(label: "RETURN", code: AppleKeyboardKey.KEY_RETURN.rawValue, keySize: .wider)
]
]
)
var arrowKeysModel = [[AppleIIKey]]()
init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
// setupView()
setupViewFrames()
setupKeyModels()
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(draggedView(_:)))
leftKeyboardView.dragMeView.isUserInteractionEnabled = true
leftKeyboardView.dragMeView.addGestureRecognizer(panGesture)
let panGestureRightKeyboard = UIPanGestureRecognizer(target: self, action: #selector(draggedView(_:)))
rightKeyboardView.dragMeView.isUserInteractionEnabled = true
rightKeyboardView.dragMeView.addGestureRecognizer(panGestureRightKeyboard)
}
func setupView() {
NSLayoutConstraint.deactivate(keyboardConstraints)
keyboardConstraints.removeAll()
leftKeyboardView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(leftKeyboardView)
leftKeyboardView.heightAnchor.constraint(equalToConstant: 200).isActive = true
leftKeyboardView.widthAnchor.constraint(equalToConstant: 180).isActive = true
keyboardConstraints.append(contentsOf: [
leftKeyboardView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
leftKeyboardView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
rightKeyboardView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(rightKeyboardView)
keyboardConstraints.append(contentsOf: [
rightKeyboardView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
rightKeyboardView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
rightKeyboardView.heightAnchor.constraint(equalToConstant: 200).isActive = true
rightKeyboardView.widthAnchor.constraint(equalToConstant: 180).isActive = true
NSLayoutConstraint.activate(keyboardConstraints)
}
func setupViewFrames() {
// initial placement on the bottom corners
// assume a size of 200x180 for now
// since we don't know the frame of this view yet until layout time,
// assume it's taking the full screen
let screenFrame = UIScreen.main.bounds
let keyboardHeight: CGFloat = 180.0
let keyboardWidth: CGFloat = 200.0
let bottomLeftFrame = CGRect(
x: self.view.safeAreaInsets.left,
y: screenFrame.size.height - self.view.safeAreaInsets.bottom - keyboardHeight,
width: keyboardWidth, height: keyboardHeight)
let bottomRightFrame = CGRect(
x: screenFrame.size.width - self.view.safeAreaInsets.right - keyboardWidth,
y:screenFrame.size.height - self.view.safeAreaInsets.bottom - keyboardHeight,
width: keyboardWidth, height: keyboardHeight
)
view.addSubview(leftKeyboardView)
view.addSubview(rightKeyboardView)
leftKeyboardView.frame = bottomLeftFrame
rightKeyboardView.frame = bottomRightFrame
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
// get relative positions of frames to size
for v in [leftKeyboardView, rightKeyboardView] {
let xPercent = v.frame.origin.x / view.frame.size.width
let yPercent = v.frame.origin.y / view.frame.size.height
var newX = size.width * xPercent
var newY = size.height * yPercent
// mmm need to check if the views fit within the frame and adjust
if newX + v.bounds.size.width > size.width {
newX = size.width - v.bounds.size.width
} else if newX < 0 {
newX = 0
}
if newY + v.bounds.size.height > size.height {
newY = size.height - v.bounds.size.height
}
let newFrame = CGRect(x: newX, y: newY, width: v.bounds.size.width, height: v.bounds.size.height)
v.frame = newFrame
}
}
func setupKeyModels() {
leftKeyboardView.setupWithModel(leftKeyboardModel)
rightKeyboardView.setupWithModel(rightKeyboardModel)
}
@objc func draggedView(_ sender:UIPanGestureRecognizer){
guard let keyboardView = sender.view?.superview else {
return
}
// NSLayoutConstraint.deactivate(keyboardConstraints)
// self.view.bringSubviewToFront(keyboardView)
let translation = sender.translation(in: self.view)
keyboardView.center = CGPoint(x: keyboardView.center.x + translation.x, y: keyboardView.center.y + translation.y)
sender.setTranslation(CGPoint.zero, in: self.view)
}
}

View File

@ -9,6 +9,8 @@
#import "../kegs/iOS/emulatorView.h"
#import "KBDController.h"
#import "ActiveGS-Swift.h"
enum gestureModes
{
@ -58,7 +60,7 @@ enum attachMode
ATTACH_SECONDARY
};
@interface activegsEmulatorController : UIVIEWCONTROLLERROOT
@interface activegsEmulatorController : UIVIEWCONTROLLERROOT<EmulatorKeyboardKeyPressedDelegate, EmulatorKeyboardModifierPressedDelegate>
{
@public
int attachedTo;
@ -74,7 +76,8 @@ enum attachMode
@property (nonatomic, strong) customView* contentView;
@property (nonatomic, strong) zoomEmulatorView* zv;
@property (nonatomic, strong) KBDController* kbdc ;
@property (nonatomic, strong) NSString* trackerName ;
@property (nonatomic, strong) EmulatorKeyboardController *emuKeyboardController;
@property (nonatomic, strong) NSString* trackerName;
@end

View File

@ -7,6 +7,10 @@
#import "activegsAppDelegate.h"
#include "../kegs/Src/protos_macdriver.h"
#include "../kegs/Src/sim65816.h"
#include "../kegs/Src/async_event.h"
#import "ActiveGS-Swift.h"
#define TIME_BEFORE_REENABLING_GESTURES 1.0
#define TIME_BEFORE_DISABLING_GESTURES 0.5
@ -87,8 +91,21 @@ int x_lock_zoom = 0;
return curHit;
}
}
EmulatorKeyboardView *leftKeyboard = [pManager getEmulatorView].emuKeyboardController.leftKeyboardView;
p = [self convertPoint:_point toView:leftKeyboard];
curHit = [leftKeyboard hitTest:p withEvent:event];
if ([curHit isDescendantOfView:leftKeyboard]) {
return curHit;
}
EmulatorKeyboardView *rightKeyboard = [pManager getEmulatorView].emuKeyboardController.rightKeyboardView;
p = [self convertPoint:_point toView:rightKeyboard];
curHit = [rightKeyboard hitTest:p withEvent:event];
if ([curHit isDescendantOfView:rightKeyboard]) {
return curHit;
}
// renvoie les évenements à l'emulator
return [pManager getEmulatorView].zv;
}
@ -133,8 +150,6 @@ int x_lock_zoom = 0;
return self;
}
-(void)invalidateTimers
{
@ -413,7 +428,7 @@ int x_lock_zoom = 0;
attachedTo = ATTACH_NONE;
CGRect apprect = [[UIScreen mainScreen] applicationFrame];
CGRect apprect = [[UIScreen mainScreen] bounds];
printf("mainScreen apprect %d x %d\n",(int)apprect.size.width,(int)apprect.size.height);
self.contentView = [[customView alloc] initWithFrame:apprect];
@ -428,9 +443,14 @@ int x_lock_zoom = 0;
[self.zv setUserInteractionEnabled:TRUE];
self.kbdc = [KBDController alloc];
self.kbdc = [[KBDController alloc] initWithNibName:nil bundle:nil];
[self.contentView addSubview:self.kbdc.view];
self.emuKeyboardController = [[EmulatorKeyboardController alloc] init];
self.emuKeyboardController.leftKeyboardView.delegate = self;
self.emuKeyboardController.leftKeyboardView.modifierDelegate = self;
self.emuKeyboardController.rightKeyboardView.delegate = self;
self.view = self.contentView;
@ -564,7 +584,7 @@ int x_lock_zoom = 0;
// l'interface est repositionnées mais non animée
CGRect uirectrotate = [[UIScreen mainScreen] applicationFrame];
CGRect uirectrotate = [[UIScreen mainScreen] bounds];
[self.kbdc updateView:uirectrotate];
[pManager updateNotificationView:uirectrotate];
@ -609,6 +629,18 @@ int x_lock_zoom = 0;
// Release any cached data, images, etc that aren't in use.
}
-(void)viewDidLoad {
[super viewDidLoad];
[self addChildViewController:self.emuKeyboardController];
self.emuKeyboardController.view.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.emuKeyboardController.view];
[[self.emuKeyboardController.view.topAnchor constraintEqualToAnchor:self.view.topAnchor] setActive:YES];
[[self.emuKeyboardController.view.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor] setActive:YES];
[[self.emuKeyboardController.view.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor] setActive:YES];
[[self.emuKeyboardController.view.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor] setActive:YES];
[self.emuKeyboardController didMoveToParentViewController:self];
[self.view bringSubviewToFront:self.emuKeyboardController.view];
}
-(void)viewWillAppear:(BOOL)animated
{
@ -681,4 +713,38 @@ int x_lock_zoom = 0;
self.zv.crt.hidden = (vfx==VIDEOFX_CRT?0:1);
}
#pragma mark - EmulatorKeyboardKeyPressedDelegate
-(void)keyDown:(id<KeyCoded>)key {
add_event_key((int)key.keyCode, 0);
}
-(void)keyUp:(id<KeyCoded>)key {
add_event_key((int)key.keyCode, 1);
}
#pragma mark - EmulatorKeyboardModifierPressedDelegate
-(void)modifierPressedWithKey:(id<KeyCoded>)key enable:(BOOL)enable {
// fix this to the enum later
if (key.keyCode == 0x38) {
// shift
if (enable) {
self.emuKeyboardController.modifierState |= shiftKey;
} else {
self.emuKeyboardController.modifierState &= ~shiftKey;
}
NSLog(@"modifier = %i",self.emuKeyboardController.modifierState);
}
}
-(BOOL)isModifierEnabledWithKey:(id<KeyCoded>)key {
if (key.keyCode == 0x38) {
// shift
NSLog(@"modifier = %i",self.emuKeyboardController.modifierState);
BOOL enabled = self.emuKeyboardController.modifierState & shiftKey;
NSLog(@"modifier enabled? %@",enabled ? @"YES" : @"NO");
return enabled;
}
return NO;
}
@end

View File

@ -256,7 +256,8 @@ static UIImage* defaultImageII = nil;
tempXML += "</config>";
};
for (NSString *s in fileList)
NSArray *sortedFileList = [fileList sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
for (NSString *s in sortedFileList)
{
const char* fn = [s UTF8String];
const char* ext = getext(fn);
@ -637,6 +638,8 @@ static NSInteger compareImagesUsingSelector(id p1, id p2, void *context)
[self reloadData:NO];
UILayoutGuide *lg = self.view.safeAreaLayoutGuide;
NSLog(@"safe area layout guide: %@",NSStringFromCGRect(lg.layoutFrame));
}

View File

@ -552,6 +552,7 @@ float refScaleLandscape;
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
#ifdef ACTIVEGS
if ([[pManager getEmulatorView].kbdc myTouchesBegan:touches])
{
@ -672,6 +673,7 @@ float refScaleLandscape;
{
debug_printf("touchesEnded : %d",[touches count]);
[super touchesEnded:touches withEvent:event];
#ifdef ACTIVEGS
if (! [[pManager getEmulatorView].kbdc myTouchesEnded:touches])
@ -750,7 +752,7 @@ float refScaleLandscape;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];
// on est ici car lez zoom a démarré => théoriquement, il ne doit y avoir aucun useTouch, secondTouch, ou mouseDown
if ([touches containsObject:self.useTouch])