Subversion Repositories Mobile Apps.GyroMouse

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
//
2
//  MouseViewController.swift
3
//  GyroMouse
4
//
5
//  Created by Matteo Riva on 08/08/15.
6
//  Copyright © 2015 Matteo Riva. All rights reserved.
7
//
8
 
9
import UIKit
10
import CoreMotion
11
 
12
 
13
// Extend from MyUITextFieldDelegate instead of UITextFieldDelegate in your class
14
protocol MyUITextFieldDelegate : UITextFieldDelegate {
15
    func didPressBackspace(_ textField: MyUITextField)
16
}
17
class MyUITextField: UITextField {
18
    override func deleteBackward() {
19
        super.deleteBackward()
20
        if let myDelegate = self.delegate as? MyUITextFieldDelegate {
21
            myDelegate.didPressBackspace(self)
22
        }
23
    }
24
}
25
 
26
 
27
class MouseViewController: UIViewController, MyUITextFieldDelegate, SettingsViewControllerDelegate {
28
 
29
    private var txtInput = MyUITextField(frame: CGRect(x: UIScreen.main.bounds.size.width * 1 / 8,
30
                                                       y: UIScreen.main.bounds.size.height * 1 / 32,
31
                                                       width: UIScreen.main.bounds.size.width * 6 / 8,
32
                                                       height: UIScreen.main.bounds.size.width * 1 / 16))
33
 
34
    private var lButton = UIButton(frame: CGRect(x: 0,
35
                                                 y: UIScreen.main.bounds.size.height * 2 / 16,
36
                                                 width: UIScreen.main.bounds.size.width * 3 / 4,
37
                                                 height: UIScreen.main.bounds.size.height * 14 / 16))
38
    private var rButton = UIButton(frame: CGRect(x: UIScreen.main.bounds.size.width * 3 / 4,
39
                                                 y: UIScreen.main.bounds.size.height * 2 / 16,
40
                                                 width: UIScreen.main.bounds.size.width * 1 / 4,
41
                                                 height: UIScreen.main.bounds.size.height * 14 / 16))
42
 
43
    private let client = (UIApplication.shared.delegate as! AppDelegate).client
44
    private let manager = CMMotionManager()
45
 
46
    private var moveVelocity = UserDefaults.standard.double(forKey: "moveVelocity")
47
    private var scrollVelocity = UserDefaults.standard.double(forKey: "scrollVelocity")
48
    private var shakeToReset = UserDefaults.standard.bool(forKey: "shakeToReset")
49
 
50
    private lazy var handler: CMDeviceMotionHandler = {
51
        return {[weak self] (data, error) -> Void in
52
            if error == nil {
53
 
54
                let roll = data!.attitude.roll
55
 
56
                var type = GyroPacketType.scroll
57
 
58
                if roll > -0.45 && roll < 0.45 {
59
                    type = .movement
60
                }
61
 
62
                let packet = GyroPacket(type: type, minimumVersion: minimumVersion)
63
 
64
                packet.gravX = data!.gravity.x
65
                packet.gravY = data!.gravity.y
66
                packet.gravZ = data!.gravity.z
67
                packet.rotatX =  data!.rotationRate.x//data!.attitude.pitch
68
                packet.roll = roll
69
                packet.rotatZ = data!.rotationRate.z//data!.attitude.yaw
70
                packet.accX = data!.userAcceleration.x
71
                packet.accY = data!.userAcceleration.y
72
                packet.accZ = data!.userAcceleration.z
73
                packet.moveVelocity = self?.moveVelocity ?? 0
74
                packet.scrollVelocity = self?.scrollVelocity ?? 0
75
 
76
                self?.client.sendPacket(packet)
77
            }
78
        }
79
    }()
80
 
81
    override func viewDidLoad() {
82
        super.viewDidLoad()
83
 
84
        if manager.isDeviceMotionAvailable {
85
            manager.deviceMotionUpdateInterval = 0.01
86
            manager.startDeviceMotionUpdates(to: OperationQueue.main, withHandler: handler)
87
        }
88
 
89
        NotificationCenter.default.addObserver(forName: ClientDidDisconnectNotification, object: client, queue: OperationQueue.main) {[weak self] (_) -> Void in
90
            _=self?.navigationController?.popViewController(animated: true)
91
        }
92
 
93
        txtInput.tintColor = UIColor.white
94
        txtInput.backgroundColor = UIColor.darkGray.withAlphaComponent(0.7)
95
        txtInput.textColor = UIColor.white
96
        txtInput.textAlignment = .center
97
        txtInput.font = UIFont.systemFont(ofSize: 15)
98
        txtInput.borderStyle = UITextField.BorderStyle.roundedRect
99
        txtInput.keyboardType = UIKeyboardType.default
100
        txtInput.returnKeyType = UIReturnKeyType.done
101
        txtInput.clearButtonMode = UITextField.ViewMode.whileEditing
102
        txtInput.autocorrectionType = .no
103
        txtInput.spellCheckingType = .no
104
        txtInput.delegate = self
105
        self.view.addSubview(txtInput)
106
 
107
        lButton.backgroundColor = .black
108
        lButton.layer.borderWidth = CGFloat(1.0)
109
        lButton.layer.borderColor = UIColor.darkGray.cgColor//(gray: 0.25, alpha: 1)//(red: 0.25, green: 0.25, blue: 0.25, alpha: 1)
110
        lButton.addTarget(self, action: #selector(lButtonDown), for: .touchDown)
111
        lButton.addTarget(self, action: #selector(lButtonUp), for: .touchUpInside)
112
        self.view.addSubview(lButton)
113
 
114
        rButton.backgroundColor = .black
115
        rButton.layer.borderWidth = CGFloat(1.0)
116
        rButton.layer.borderColor = UIColor.darkGray.cgColor//CGColor(red: 0.25, green: 0.25, blue: 0.25, alpha: 1)
117
        rButton.addTarget(self, action: #selector(rButtonDown), for: .touchDown)
118
        rButton.addTarget(self, action: #selector(rButtonUp), for: .touchUpInside)
119
        self.view.addSubview(rButton)
120
    }
121
 
122
    @objc func lButtonDown()
123
    {
124
        let packet = GyroPacket(type: .click, minimumVersion: minimumVersion)
125
        packet.button = ButtonType.left
126
        packet.click = .down
127
        lButton.backgroundColor = UIColor (red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5) // grey
128
        client.sendPacket(packet)
129
    }
130
    @objc func lButtonUp()
131
    {
132
        let packet = GyroPacket(type: .click, minimumVersion: minimumVersion)
133
        packet.button = ButtonType.left
134
        packet.click = .up
135
        lButton.backgroundColor = UIColor (red: 0, green: 0, blue: 0, alpha: 0.8) // black
136
        client.sendPacket(packet)
137
    }
138
 
139
    @objc func rButtonDown()
140
    {
141
        let packet = GyroPacket(type: .click, minimumVersion: minimumVersion)
142
        packet.button = ButtonType.right
143
        packet.click = .down
144
        rButton.backgroundColor = UIColor (red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5) // grey
145
        client.sendPacket(packet)
146
    }
147
 
148
    @objc func rButtonUp()
149
    {
150
        let packet = GyroPacket(type: .click, minimumVersion: minimumVersion)
151
        packet.button = ButtonType.right
152
        packet.click = .up
153
        rButton.backgroundColor = UIColor (red: 0, green: 0, blue: 0, alpha: 0.8) // black
154
        client.sendPacket(packet)
155
    }
156
 
157
    deinit {
158
        NotificationCenter.default.removeObserver(self)
159
        manager.stopDeviceMotionUpdates()
160
        client.endConnection()
161
    }
162
 
163
    //MARK: - Mouse actions
164
 
165
    override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
166
        if event?.subtype == .motionShake && shakeToReset {
167
            resetPointerPositionAction()
168
        }
169
    }
170
 
171
    //MARK: - Button actions
172
 
173
    @IBAction func resetPointerPositionAction() {
174
        let packet = GyroPacket(type: .resetPointerPosition, minimumVersion: minimumVersion)
175
        client.sendPacket(packet)
176
    }
177
 
178
    //MARK: - KeyboardHandlerDelegate
179
 
180
    override func viewDidAppear(_ animated: Bool) {
181
        txtInput.becomeFirstResponder() // forces iOS keyboard to appear
182
    }
183
 
184
    func didPressBackspace(_ textField: MyUITextField) {
185
        let packet = GyroPacket(type: .deleteBackward, minimumVersion: minimumVersion)
186
        client.sendPacket(packet)
187
    }
188
 
189
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
190
        let packet = GyroPacket(type: .keyTapped, minimumVersion: minimumVersion)
191
        packet.key = string
192
        client.sendPacket(packet)
193
        return true
194
    }
195
 
196
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
197
        let packet = GyroPacket(type: .returnTapped, minimumVersion: minimumVersion)
198
        client.sendPacket(packet)
199
        txtInput.text = ""
200
        return false
201
    }
202
 
203
    //MARK: - SettingsViewControllerDelegate
204
 
205
    func settingsDidChangeMoveVelocity(_ moveVelocity: Double) {
206
        self.moveVelocity = moveVelocity
207
    }
208
 
209
    func settingsDidChangeScrollVelocity(_ scrollVelocity: Double) {
210
        self.scrollVelocity = scrollVelocity
211
    }
212
 
213
    func settingsDidChangeShakeToReset(_ shakeActive: Bool) {
214
        self.shakeToReset = shakeActive
215
    }
216
 
217
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
218
        if segue.identifier == "settingsSegue" {
219
            let controller = segue.destination as! UINavigationController
220
            let view = controller.viewControllers.first! as! SettingsViewController
221
            view.delegate = self
222
        }
223
    }
224
 
225
}