Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
//
// MouseViewController.swift
// GyroMouse
//
// Created by Matteo Riva on 08/08/15.
// Copyright © 2015 Matteo Riva. All rights reserved.
//
import UIKit
import CoreMotion
// Extend from MyUITextFieldDelegate instead of UITextFieldDelegate in your class
protocol MyUITextFieldDelegate : UITextFieldDelegate {
func didPressBackspace(_ textField: MyUITextField)
}
class MyUITextField: UITextField {
override func deleteBackward() {
super.deleteBackward()
if let myDelegate = self.delegate as? MyUITextFieldDelegate {
myDelegate.didPressBackspace(self)
}
}
}
class MouseViewController: UIViewController, MyUITextFieldDelegate, SettingsViewControllerDelegate {
private var txtInput = MyUITextField(frame: CGRect(x: UIScreen.main.bounds.size.width * 1 / 8,
y: UIScreen.main.bounds.size.height * 1 / 32,
width: UIScreen.main.bounds.size.width * 6 / 8,
height: UIScreen.main.bounds.size.width * 1 / 16))
private var lButton = UIButton(frame: CGRect(x: 0,
y: UIScreen.main.bounds.size.height * 2 / 16,
width: UIScreen.main.bounds.size.width * 3 / 4,
height: UIScreen.main.bounds.size.height * 14 / 16))
private var rButton = UIButton(frame: CGRect(x: UIScreen.main.bounds.size.width * 3 / 4,
y: UIScreen.main.bounds.size.height * 2 / 16,
width: UIScreen.main.bounds.size.width * 1 / 4,
height: UIScreen.main.bounds.size.height * 14 / 16))
private let client = (UIApplication.shared.delegate as! AppDelegate).client
private let manager = CMMotionManager()
private var moveVelocity = UserDefaults.standard.double(forKey: "moveVelocity")
private var scrollVelocity = UserDefaults.standard.double(forKey: "scrollVelocity")
private var shakeToReset = UserDefaults.standard.bool(forKey: "shakeToReset")
private lazy var handler: CMDeviceMotionHandler = {
return {[weak self] (data, error) -> Void in
if error == nil {
let roll = data!.attitude.roll
var type = GyroPacketType.scroll
if roll > -0.45 && roll < 0.45 {
type = .movement
}
let packet = GyroPacket(type: type, minimumVersion: minimumVersion)
packet.gravX = data!.gravity.x
packet.gravY = data!.gravity.y
packet.gravZ = data!.gravity.z
packet.rotatX = data!.rotationRate.x//data!.attitude.pitch
packet.roll = roll
packet.rotatZ = data!.rotationRate.z//data!.attitude.yaw
packet.accX = data!.userAcceleration.x
packet.accY = data!.userAcceleration.y
packet.accZ = data!.userAcceleration.z
packet.moveVelocity = self?.moveVelocity ?? 0
packet.scrollVelocity = self?.scrollVelocity ?? 0
self?.client.sendPacket(packet)
}
}
}()
override func viewDidLoad() {
super.viewDidLoad()
if manager.isDeviceMotionAvailable {
manager.deviceMotionUpdateInterval = 0.01
manager.startDeviceMotionUpdates(to: OperationQueue.main, withHandler: handler)
}
NotificationCenter.default.addObserver(forName: ClientDidDisconnectNotification, object: client, queue: OperationQueue.main) {[weak self] (_) -> Void in
_=self?.navigationController?.popViewController(animated: true)
}
txtInput.tintColor = UIColor.white
txtInput.backgroundColor = UIColor.darkGray.withAlphaComponent(0.7)
txtInput.textColor = UIColor.white
txtInput.textAlignment = .center
txtInput.font = UIFont.systemFont(ofSize: 15)
txtInput.borderStyle = UITextField.BorderStyle.roundedRect
txtInput.keyboardType = UIKeyboardType.default
txtInput.returnKeyType = UIReturnKeyType.done
txtInput.clearButtonMode = UITextField.ViewMode.whileEditing
txtInput.autocorrectionType = .no
txtInput.spellCheckingType = .no
txtInput.delegate = self
self.view.addSubview(txtInput)
lButton.backgroundColor = .black
lButton.layer.borderWidth = CGFloat(1.0)
lButton.layer.borderColor = UIColor.darkGray.cgColor//(gray: 0.25, alpha: 1)//(red: 0.25, green: 0.25, blue: 0.25, alpha: 1)
lButton.addTarget(self, action: #selector(lButtonDown), for: .touchDown)
lButton.addTarget(self, action: #selector(lButtonUp), for: .touchUpInside)
self.view.addSubview(lButton)
rButton.backgroundColor = .black
rButton.layer.borderWidth = CGFloat(1.0)
rButton.layer.borderColor = UIColor.darkGray.cgColor//CGColor(red: 0.25, green: 0.25, blue: 0.25, alpha: 1)
rButton.addTarget(self, action: #selector(rButtonDown), for: .touchDown)
rButton.addTarget(self, action: #selector(rButtonUp), for: .touchUpInside)
self.view.addSubview(rButton)
}
@objc func lButtonDown()
{
let packet = GyroPacket(type: .click, minimumVersion: minimumVersion)
packet.button = ButtonType.left
packet.click = .down
lButton.backgroundColor = UIColor (red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5) // grey
client.sendPacket(packet)
}
@objc func lButtonUp()
{
let packet = GyroPacket(type: .click, minimumVersion: minimumVersion)
packet.button = ButtonType.left
packet.click = .up
lButton.backgroundColor = UIColor (red: 0, green: 0, blue: 0, alpha: 0.8) // black
client.sendPacket(packet)
}
@objc func rButtonDown()
{
let packet = GyroPacket(type: .click, minimumVersion: minimumVersion)
packet.button = ButtonType.right
packet.click = .down
rButton.backgroundColor = UIColor (red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5) // grey
client.sendPacket(packet)
}
@objc func rButtonUp()
{
let packet = GyroPacket(type: .click, minimumVersion: minimumVersion)
packet.button = ButtonType.right
packet.click = .up
rButton.backgroundColor = UIColor (red: 0, green: 0, blue: 0, alpha: 0.8) // black
client.sendPacket(packet)
}
deinit {
NotificationCenter.default.removeObserver(self)
manager.stopDeviceMotionUpdates()
client.endConnection()
}
//MARK: - Mouse actions
override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
if event?.subtype == .motionShake && shakeToReset {
resetPointerPositionAction()
}
}
//MARK: - Button actions
@IBAction func resetPointerPositionAction() {
let packet = GyroPacket(type: .resetPointerPosition, minimumVersion: minimumVersion)
client.sendPacket(packet)
}
//MARK: - KeyboardHandlerDelegate
override func viewDidAppear(_ animated: Bool) {
txtInput.becomeFirstResponder() // forces iOS keyboard to appear
}
func didPressBackspace(_ textField: MyUITextField) {
let packet = GyroPacket(type: .deleteBackward, minimumVersion: minimumVersion)
client.sendPacket(packet)
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let packet = GyroPacket(type: .keyTapped, minimumVersion: minimumVersion)
packet.key = string
client.sendPacket(packet)
return true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
let packet = GyroPacket(type: .returnTapped, minimumVersion: minimumVersion)
client.sendPacket(packet)
txtInput.text = ""
return false
}
//MARK: - SettingsViewControllerDelegate
func settingsDidChangeMoveVelocity(_ moveVelocity: Double) {
self.moveVelocity = moveVelocity
}
func settingsDidChangeScrollVelocity(_ scrollVelocity: Double) {
self.scrollVelocity = scrollVelocity
}
func settingsDidChangeShakeToReset(_ shakeActive: Bool) {
self.shakeToReset = shakeActive
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "settingsSegue" {
let controller = segue.destination as! UINavigationController
let view = controller.viewControllers.first! as! SettingsViewController
view.delegate = self
}
}
}