Refactor code. Add tabs for enabling using two remote controls at once.
[qzeecontrol] / qml / QZeeControl / ZeeConnectPage.qml
1 /*
2  *  Copyright 2012 Ruediger Gad
3  *
4  *  This file is part of QZeeControl.
5  *
6  *  QZeeControl is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  QZeeControl is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with QZeeControl.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 import QtQuick 1.1
21 import com.nokia.meego 1.0
22 import QtMobility.connectivity 1.2
23 import QtMobility.systeminfo 1.2
24 import "settingsstorage.js" as SettingsStorage
25 import qzeecontrol 1.0
26
27 Page {
28     id: zeeConnectPage
29     tools: commonTools
30
31     anchors.fill: parent
32
33     orientationLock: PageOrientation.LockPortrait
34
35     property bool connected: false
36     property alias currentAddress: addressField.text
37     property bool initializing: true
38     property string name: "none"
39     property string usedAddresses: "none"
40
41     Component.onCompleted: {
42         SettingsStorage.initialize();
43
44         var address = SettingsStorage.getSetting(name + "address");
45         var port = SettingsStorage.getSetting(name + "port");
46         if(address !== "Unknown" && port !== "Unknown"){
47             console.log("Loaded address " + address + " and port " + port + " from DB for " + name + ".")
48             addressField.text = address
49             portField.text = port
50         }
51
52         if(SettingsStorage.getSetting(name + "A") === "Unknown"){
53             console.log("Initializing key bindings for " + name + ".")
54             setKeyBindingsToDefault()
55         }
56
57         loadKeyBindings()
58         updateConnectAndScanButton()
59         initializing = false
60     }
61
62     function setKeyBindingsToDefault(){
63         console.log("Setting key bindings to default for " + name + ".")
64         SettingsStorage.setSetting(name + "A", "a")
65         SettingsStorage.setSetting(name + "B", "b")
66         SettingsStorage.setSetting(name + "C", "c")
67         SettingsStorage.setSetting(name + "D", "d")
68
69         SettingsStorage.setSetting(name + "Up", "Up")
70         SettingsStorage.setSetting(name + "Down", "Down")
71         SettingsStorage.setSetting(name + "Left", "Left")
72         SettingsStorage.setSetting(name + "Right", "Right")
73
74         SettingsStorage.setSetting(name + "Threshold", "50")
75
76         /*
77          * The following settings are not used right now but
78          * we initialize these anyhow for possibly later use.
79          */
80         SettingsStorage.setSetting(name + "MousePointerMode", "false")
81         SettingsStorage.setSetting(name + "AlternateActionTrigger", "none")
82     }
83
84     function loadKeyBindings(){
85         console.log("Loading key bindings for " + name + ".")
86         zeeRemoteControl.keyBindingA = SettingsStorage.getSetting(name + "A")
87         zeeRemoteControl.keyBindingB = SettingsStorage.getSetting(name + "B")
88         zeeRemoteControl.keyBindingC = SettingsStorage.getSetting(name + "C")
89         zeeRemoteControl.keyBindingD = SettingsStorage.getSetting(name + "D")
90
91         zeeRemoteControl.keyBindingUp = SettingsStorage.getSetting(name + "Up")
92         zeeRemoteControl.keyBindingDown = SettingsStorage.getSetting(name + "Down")
93         zeeRemoteControl.keyBindingLeft = SettingsStorage.getSetting(name + "Left")
94         zeeRemoteControl.keyBindingRight = SettingsStorage.getSetting(name + "Right")
95
96         zeeRemoteControl.threshold = SettingsStorage.getSetting(name + "Threshold")
97     }
98
99     function updateConnectAndScanButton(){
100         if(!deviceInfo.currentBluetoothPowerState){
101             scanButton.enabled = false
102             connectButton.enabled = false
103
104             addressField.enabled = false
105             portField.enabled = false
106
107             infoText.text = "To get started please turn Bluetooth on."
108             return
109         }
110
111         scanButton.enabled = true
112
113         addressField.enabled = true
114         portField.enabled = true
115
116         connectButton.enabled = (addressField.text !== "No Zeemote found yet.")
117         infoText.text = (addressField.text !== "No Zeemote found yet.") ?
118                     "To enable remote control please press \"Connect\" when ready." :
119                     "Please scan for a Zeemote first."
120     }
121
122     states: [
123         State {
124             name: "active"
125             PropertyChanges {
126                 target: cursorRectangle
127                 x: moveArea.x + (moveArea.width * 0.5) + zeeRemoteControl.x - (cursorRectangle.width * 0.5)
128                 y: moveArea.y + (moveArea.height * 0.5) + zeeRemoteControl.y - (cursorRectangle.height * 0.5)
129             }
130             PropertyChanges {
131                 target: labelA
132                 color: zeeRemoteControl.a ? "red" : "blue"
133             }
134             PropertyChanges {
135                 target: labelB
136                 color: zeeRemoteControl.b ? "red" : "blue"
137             }
138             PropertyChanges {
139                 target: labelC
140                 color: zeeRemoteControl.c ? "red" : "blue"
141             }
142             PropertyChanges {
143                 target: labelD
144                 color: zeeRemoteControl.d ? "red" : "blue"
145             }
146         },
147         State {
148             name: "inactive"
149             PropertyChanges {
150                 target: cursorRectangle
151                 x: moveArea.x + (moveArea.width * 0.5) - (cursorRectangle.width * 0.5)
152                 y: moveArea.y + (moveArea.height * 0.5) - (cursorRectangle.height * 0.5)
153             }
154             PropertyChanges {
155                 target: labelA
156                 color: "blue"
157             }
158             PropertyChanges {
159                 target: labelB
160                 color: "blue"
161             }
162             PropertyChanges {
163                 target: labelC
164                 color: "blue"
165             }
166             PropertyChanges {
167                 target: labelD
168                 color: "blue"
169             }
170         }
171     ]
172
173     Connections {
174         target: platformWindow
175
176         onActiveChanged: {
177             if(platformWindow.active){
178                 state = "active"
179             }else{
180                 state = "inactive"
181             }
182         }
183     }
184
185     Item {
186         id: headerItem
187         anchors{top: parent.top; left: parent.left; right: parent.right}
188         height: header.height
189         z: 1
190
191         Image {
192             id: header
193             height: 72
194             source: "image://theme/color8-meegotouch-view-header-fixed"
195             anchors.fill: parent
196
197             Text {
198                 text: "QZeeControl"
199                 color: "white"
200                 font.family: "Nokia Pure Text Light"
201                 font.pixelSize: 32
202                 anchors.left: parent.left
203                 anchors.leftMargin: 20
204                 anchors.verticalCenter: parent.verticalCenter
205             }
206         }
207     }
208
209     Flickable {
210         anchors{top: headerItem.bottom; bottom: parent.bottom; left: parent.left; right: parent.right}
211         contentHeight: contentColumn.height
212
213         Column{
214             id: contentColumn
215             spacing: 10
216             anchors{top: parent.top; left: parent.left; right: parent.right; topMargin: 10}
217
218             Button{
219                 id: scanButton
220                 enabled: false
221
222                 anchors.horizontalCenter: parent.horizontalCenter
223                 text: "Scan"
224
225                 onClicked: {
226                     btDiscovery.discovery = true
227                 }
228             }
229
230             Row{
231                 id: addressRow
232                 anchors.horizontalCenter: parent.horizontalCenter
233                 spacing: 5
234
235                 TextField{
236                     id: addressField
237                     text: "No Zeemote found yet."
238                     width: 280
239
240                     onTextChanged: {
241                         if(zeeConnectPage.initializing)
242                             return
243
244                         if(text === "No Zeemote found yet.")
245                             return
246
247                         if(text === usedAddresses){
248                             console.log("Not using address " + text + " as it is already used somewhere else.")
249                             return
250                         }
251
252                         updateConnectAndScanButton();
253
254                         console.log("Storing address in DB for " + name + ": " + text)
255                         SettingsStorage.setSetting(name + "address", text)
256                     }
257                 }
258                 TextField{
259                     id: portField
260                     text: "na"
261                     width: 60
262                     validator: IntValidator{}
263
264                     onTextChanged: {
265                         if(zeeConnectPage.initializing)
266                             return
267
268                         if(text === "na")
269                             return
270
271                         console.log("Storing port in DB for " + name + ": " + text)
272                         SettingsStorage.setSetting(name + "port", text)
273                     }
274                 }
275             }
276
277             Label {
278                 id: infoText
279                 width: parent.width
280
281                 horizontalAlignment: Text.AlignHCenter
282                 wrapMode: Text.WordWrap
283             }
284
285             Button{
286                 id: connectButton
287                 anchors.horizontalCenter: parent.horizontalCenter
288                 enabled: false
289
290                 text: "Connect"
291
292                 onClicked: {
293                     scanButton.enabled = false
294                     addressField.enabled = false
295                     portField.enabled = false
296                     connectButton.enabled = false
297                     disconnectButton.enabled = false
298                     infoText.text = "Connecting..."
299
300                     zeeRemoteControl.connect(addressField.text, parseInt(portField.text))
301                 }
302             }
303
304             Button{
305                 id: disconnectButton
306                 anchors.horizontalCenter: parent.horizontalCenter
307
308                 text: "Disconnect"
309                 enabled: false
310
311                 onClicked: {
312                     zeeRemoteControl.disconnect()
313                 }
314             }
315
316             Row{
317                 id: buttonRow
318                 anchors.horizontalCenter: parent.horizontalCenter
319
320                 spacing: 20
321
322                 Label{
323                     id: labelA
324                     text: "A"
325                     color: zeeRemoteControl.a ? "red" : "blue"
326                 }
327                 Label{
328                     id: labelB
329                     text: "B"
330                     color: zeeRemoteControl.b ? "red" : "blue"
331                 }
332                 Label{
333                     id: labelC
334                     text: "C"
335                     color: zeeRemoteControl.c ? "red" : "blue"
336                 }
337                 Label{
338                     id: labelD
339                     text: "D"
340                     color: zeeRemoteControl.d ? "red" : "blue"
341                 }
342             }
343
344             Item{
345                 id: testArea
346                 anchors.horizontalCenter: parent.horizontalCenter
347                 height: moveArea.height
348                 width: moveArea.width
349
350                 Rectangle{
351                     id: moveArea
352                     color: "gray"
353
354                     width: 256
355                     height: 256
356                 }
357
358                 Rectangle{
359                     id: cursorRectangle
360                     width: 10
361                     height: 10
362                     color: "red"
363
364                     x: moveArea.x + (moveArea.width * 0.5) + zeeRemoteControl.x - (cursorRectangle.width * 0.5)
365                     y: moveArea.y + (moveArea.height * 0.5) + zeeRemoteControl.y - (cursorRectangle.height * 0.5)
366                 }
367             }
368         }
369     }
370
371     DeviceInfo{
372         id: deviceInfo
373
374         monitorBluetoothStateChanges: true
375
376         onBluetoothStateChanged: {
377             updateConnectAndScanButton()
378         }
379     }
380
381     BluetoothDiscoveryModel{
382         id: btDiscovery
383
384         discovery: false
385         minimalDiscovery: true
386
387         onDiscoveryChanged: {
388             if(initializing)
389                 return
390
391             if(discovery){
392                 infoText.text = "Scanning for a Zeemote..."
393                 scanButton.enabled = false
394                 connectButton.enabled = false
395                 disconnectButton.enabled = false
396                 addressField.enabled = false
397                 portField.enabled = false
398             }else{
399                 scanButton.enabled = true
400                 disconnectButton.enabled = false
401                 addressField.enabled = true
402                 portField.enabled = true
403
404                 if(addressField.text !== "No Zeemote found yet." && portField.text !== "na"){
405                     infoText.text = "Zeemote found. To enable remote control please press \"Connect\" when ready."
406                     connectButton.enabled = true
407                 }
408             }
409         }
410
411         onNewServiceDiscovered: {
412             console.log("Service " + service.serviceName + " found on "
413                         + service.deviceName + " at address " + service.deviceAddress
414                         + " on port " + service.servicePort + ".")
415
416             if(service.serviceName !== "Zeemote")
417                 return
418
419             if(service.deviceAddress === usedAddresses){
420                 console.log("Zeemote at address " + service.deviceAddress + " already in use somewhere else. " +
421                             "Not going to use this one.")
422                 return
423             }
424
425             addressField.text = service.deviceAddress
426             portField.text = service.servicePort
427             discovery = false
428             console.log("Found Zeemote. Stopped further discovery.")
429         }
430     }
431
432     ZeeRemoteControl{
433         id: zeeRemoteControl
434
435         onConnected: {
436             zeeConnectPage.connected = true
437             disconnectButton.enabled = true
438             infoText.text = "Connected. Have fun."
439         }
440         onDisconnected: {
441             zeeConnectPage.connected = false
442             scanButton.enabled = true
443             addressField.enabled = true
444             portField.enabled = true
445             connectButton.enabled = true
446             disconnectButton.enabled = false
447             infoText.text = "To enable remote control please press \"Connect\" when ready."
448         }
449     }
450
451     XtstAdapter{
452         id: xtstAdapter
453     }
454 }