Fix init. Fix button enabling.
[qzeecontrol] / qml / QZeeControl / MainPage.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: mainPage
29     tools: commonTools
30
31     orientationLock: PageOrientation.LockPortrait
32
33     property bool initializing: true
34
35     Component.onCompleted: {
36         SettingsStorage.initialize();
37
38         var address = SettingsStorage.getSetting("address");
39         var port = SettingsStorage.getSetting("port");
40         if(address !== "Unknown" && port !== "Unknown"){
41             console.log("Loaded address " + address + " and port " + port + " from DB.")
42             addressField.text = address
43             portField.text = port
44         }
45
46         if(SettingsStorage.getSetting("A") === "Unknown"){
47             console.log("Initializing key bindings.")
48             setKeyBindingsToDefault()
49         }
50
51         loadKeyBindings()
52         initializing = false
53     }
54
55     function setKeyBindingsToDefault(){
56         console.log("Setting key bindings to default.")
57         SettingsStorage.setSetting("A", "a")
58         SettingsStorage.setSetting("B", "b")
59         SettingsStorage.setSetting("C", "c")
60         SettingsStorage.setSetting("D", "d")
61
62         SettingsStorage.setSetting("Up", "Up")
63         SettingsStorage.setSetting("Down", "Down")
64         SettingsStorage.setSetting("Left", "Left")
65         SettingsStorage.setSetting("Right", "Right")
66     }
67
68     function loadKeyBindings(){
69         console.log("Loading key bindings.")
70         btConn.keyBindingA = SettingsStorage.getSetting("A")
71         btConn.keyBindingB = SettingsStorage.getSetting("B")
72         btConn.keyBindingC = SettingsStorage.getSetting("C")
73         btConn.keyBindingD = SettingsStorage.getSetting("D")
74
75         btConn.keyBindingUp = SettingsStorage.getSetting("Up")
76         btConn.keyBindingDown = SettingsStorage.getSetting("Down")
77         btConn.keyBindingLeft = SettingsStorage.getSetting("Left")
78         btConn.keyBindingRight = SettingsStorage.getSetting("Right")
79     }
80
81     function updateConnectAndScanButton(){
82         if(!deviceInfo.currentBluetoothPowerState){
83             scanButton.enabled = false
84             connectButton.enabled = false
85             infoText.text = "To get started please turn Bluetooth on."
86             return
87         }
88
89         scanButton.enabled = true
90         connectButton.enabled = (addressField.text !== "No device found yet.")
91         infoText = (addressField.text !== "No device found yet.") ?
92                     "To enable remote control please press \"Connect\" when ready." :
93                     "Please scan for a Zeemote first."
94
95     }
96
97     states: [
98         State {
99             name: "active"
100             PropertyChanges {
101                 target: cursorRectangle
102                 x: moveArea.x + (moveArea.width * 0.5) + btConn.x - (cursorRectangle.width * 0.5)
103                 y: moveArea.y + (moveArea.height * 0.5) + btConn.y - (cursorRectangle.height * 0.5)
104             }
105             PropertyChanges {
106                 target: labelA
107                 color: btConn.a ? "red" : "blue"
108             }
109             PropertyChanges {
110                 target: labelB
111                 color: btConn.b ? "red" : "blue"
112             }
113             PropertyChanges {
114                 target: labelC
115                 color: btConn.c ? "red" : "blue"
116             }
117             PropertyChanges {
118                 target: labelD
119                 color: btConn.d ? "red" : "blue"
120             }
121         },
122         State {
123             name: "inactive"
124             PropertyChanges {
125                 target: cursorRectangle
126                 x: moveArea.x + (moveArea.width * 0.5) - (cursorRectangle.width * 0.5)
127                 y: moveArea.y + (moveArea.height * 0.5) - (cursorRectangle.height * 0.5)
128             }
129             PropertyChanges {
130                 target: labelA
131                 color: "blue"
132             }
133             PropertyChanges {
134                 target: labelB
135                 color: "blue"
136             }
137             PropertyChanges {
138                 target: labelC
139                 color: "blue"
140             }
141             PropertyChanges {
142                 target: labelD
143                 color: "blue"
144             }
145         },
146         State {
147             name: "connecting"
148             PropertyChanges {
149                 target: scanButton
150                 enabled: false
151             }
152             PropertyChanges {
153                 target: addressField
154                 enabled: false
155             }
156             PropertyChanges {
157                 target: portField
158                 enabled: false
159             }
160             PropertyChanges {
161                 target: connectButton
162                 enabled: false
163             }
164             PropertyChanges {
165                 target: disconnectButton
166                 enabled: false
167             }
168             PropertyChanges {
169                 target: infoText
170                 text: "Connecting..."
171             }
172         },
173         State {
174             name: "disconnected"
175             PropertyChanges {
176                 target: scanButton
177                 enabled: true
178             }
179             PropertyChanges {
180                 target: addressField
181                 enabled: true
182             }
183             PropertyChanges {
184                 target: portField
185                 enabled: true
186             }
187             PropertyChanges {
188                 target: connectButton
189                 enabled: true
190             }
191             PropertyChanges {
192                 target: disconnectButton
193                 enabled: false
194             }
195             PropertyChanges {
196                 target: infoText
197                 text: "Press \"Connect\" to connect to the device."
198             }
199         }
200     ]
201
202     Connections {
203         target: platformWindow
204
205         onActiveChanged: {
206             if(platformWindow.active){
207                 state = "active"
208             }else{
209                 state = "inactive"
210             }
211         }
212     }
213
214     Item {
215         id: headerItem
216         anchors{top: parent.top; left: parent.left; right: parent.right}
217         height: header.height
218         z: 1
219
220         Image {
221             id: header
222             height: 72
223             source: "image://theme/color8-meegotouch-view-header-fixed"
224             anchors.fill: parent
225
226             Text {
227                 text: "QZeeControl"
228                 color: "white"
229                 font.family: "Nokia Pure Text Light"
230                 font.pixelSize: 32
231                 anchors.left: parent.left
232                 anchors.leftMargin: 20
233                 anchors.verticalCenter: parent.verticalCenter
234             }
235         }
236     }
237
238     Flickable {
239         anchors{top: headerItem.bottom; bottom: parent.bottom; left: parent.left; right: parent.right}
240         contentHeight: contentColumn.height
241
242             Column{
243                 id: contentColumn
244                 spacing: 10
245                 anchors{top: parent.top; left: parent.left; right: parent.right; topMargin: 10}
246
247             Button{
248                 id: scanButton
249                 enabled: false
250
251                 anchors.horizontalCenter: parent.horizontalCenter
252                 text: "Scan"
253
254                 onClicked: {
255                     btDiscovery.discovery = true
256                 }
257             }
258
259             Row{
260                 id: addressRow
261                 anchors.horizontalCenter: parent.horizontalCenter
262                 spacing: 5
263
264                 TextField{
265                     id: addressField
266                     text: "No device found yet."
267
268                     onTextChanged: {
269                         if(mainPage.initializing)
270                             return
271
272                         if(text === "No device found yet.")
273                             return
274
275                         updateConnectAndScanButton();
276
277                         console.log("Storing address in DB: " + text)
278                         SettingsStorage.setSetting("address", text)
279                     }
280                 }
281                 TextField{
282                     id: portField
283                     text: "na"
284                     width: 60
285                     validator: IntValidator{}
286
287                     onTextChanged: {
288                         if(mainPage.initializing)
289                             return
290
291                         if(text === "na")
292                             return
293
294                         console.log("Storing port in DB: " + text)
295                         SettingsStorage.setSetting("port", text)
296                     }
297                 }
298             }
299
300             Label {
301                 id: infoText
302                 width: parent.width
303
304                 text: "Please scan for a device first."
305                 horizontalAlignment: Text.AlignHCenter
306                 wrapMode: Text.WordWrap
307             }
308
309             Button{
310                 id: connectButton
311                 anchors.horizontalCenter: parent.horizontalCenter
312                 enabled: false
313
314                 text: "Connect"
315
316                 onClicked: {
317                     mainPage.state = "connecting"
318                     btConn.connect(addressField.text, parseInt(portField.text))
319                 }
320             }
321
322             Button{
323                 id: disconnectButton
324                 anchors.horizontalCenter: parent.horizontalCenter
325
326                 text: "Disconnect"
327
328                 onClicked: {
329                     btConn.disconnect()
330                 }
331             }
332
333             Row{
334                 id: buttonRow
335                 anchors.horizontalCenter: parent.horizontalCenter
336
337                 spacing: 20
338
339                 Label{
340                     id: labelA
341                     text: "A"
342                     color: btConn.a ? "red" : "blue"
343                 }
344                 Label{
345                     id: labelB
346                     text: "B"
347                     color: btConn.b ? "red" : "blue"
348                 }
349                 Label{
350                     id: labelC
351                     text: "C"
352                     color: btConn.c ? "red" : "blue"
353                 }
354                 Label{
355                     id: labelD
356                     text: "D"
357                     color: btConn.d ? "red" : "blue"
358                 }
359             }
360
361             Item{
362                 id: testArea
363                 anchors.horizontalCenter: parent.horizontalCenter
364                 height: moveArea.height
365                 width: moveArea.width
366
367                 Rectangle{
368                     id: moveArea
369                     color: "gray"
370
371                     width: 256
372                     height: 256
373                 }
374
375                 Rectangle{
376                     id: cursorRectangle
377                     width: 10
378                     height: 10
379                     color: "red"
380
381                     x: moveArea.x + (moveArea.width * 0.5) + btConn.x - (cursorRectangle.width * 0.5)
382                     y: moveArea.y + (moveArea.height * 0.5) + btConn.y - (cursorRectangle.height * 0.5)
383                 }
384             }
385         }
386     }
387
388     DeviceInfo{
389         id: deviceInfo
390
391         monitorBluetoothStateChanges: true
392
393         onBluetoothStateChanged: {
394             updateConnectAndScanButton()
395         }
396     }
397
398     BluetoothDiscoveryModel{
399         id: btDiscovery
400
401         discovery: false
402         minimalDiscovery: true
403
404         onDiscoveryChanged: {
405             if(discovery){
406                 infoText.text = "Scanning for a device..."
407                 scanButton.enabled = false
408                 connectButton.enabled = false
409                 disconnectButton.enabled = false
410                 addressField.enabled = false
411                 portField.enabled = false
412             }else{
413                 scanButton.enabled = true
414                 disconnectButton.enabled = false
415                 addressField.enabled = true
416                 portField.enabled = true
417
418                 if(addressField.text !== "No device found yet." && portField.text !== "na"){
419                     infoText.text = "Device found. You can now connect."
420                     connectButton.enabled = true
421                 }
422             }
423         }
424
425         onNewServiceDiscovered: {
426             console.log("Service " + service.serviceName + " found on "
427                         + service.deviceName + " at address " + service.deviceAddress
428                         + " on port " + service.servicePort + ".")
429             if(service.serviceName === "Zeemote"){
430                 addressField.text = service.deviceAddress
431                 portField.text = service.servicePort
432                 discovery = false
433                 console.log("Found device. Stopped further discovery.")
434             }
435         }
436     }
437
438     BtConnector{
439         id: btConn
440
441         threshold: 50
442
443         property string keyBindingA
444         property string keyBindingB
445         property string keyBindingC
446         property string keyBindingD
447
448         property string keyBindingUp
449         property string keyBindingDown
450         property string keyBindingLeft
451         property string keyBindingRight
452
453         onConnected: {
454             disconnectButton.enabled = true
455             infoText.text = "Connected. Have fun."
456         }
457
458         onDisconnected: {
459             mainPage.state = "disconnected"
460         }
461
462 //        onStickMoved: {
463 //            console.log("Stick moved. x: " + x + " y: " + y)
464 //        }
465
466 //        onButtonsChanged: {
467 //            console.log("Buttons changed. A: " + a + " B: " + b + " C: " + c + " D: " + d)
468 //        }
469
470         onAChanged: {
471 //            console.log("A changed to: " + val)
472             xtstAdapter.sendKey(keyBindingA, val);
473         }
474         onBChanged: {
475 //            console.log("B changed to: " + val)
476             xtstAdapter.sendKey(keyBindingB, val);
477         }
478         onCChanged: {
479 //            console.log("C changed to: " + val)
480             xtstAdapter.sendKey(keyBindingC, val);
481         }
482         onDChanged: {
483 //            console.log("D changed to: " + val)
484             xtstAdapter.sendKey(keyBindingD, val);
485         }
486
487         onUpChanged: xtstAdapter.sendKey(keyBindingUp, val)
488         onDownChanged: xtstAdapter.sendKey(keyBindingDown, val)
489         onLeftChanged: xtstAdapter.sendKey(keyBindingLeft, val)
490         onRightChanged: xtstAdapter.sendKey(keyBindingRight, val)
491
492 //        onXChanged: {
493 //            if(val > joystickThreshold){
494 //                xtstAdapter.sendKey("Right", true);
495 //            }else if(val < -joystickThreshold){
496 //                xtstAdapter.sendKey("Left", true);
497 //            }else{
498 //                xtstAdapter.sendKey("Right", false);
499 //                xtstAdapter.sendKey("Left", false);
500 //            }
501 //        }
502
503 //        onYChanged: {
504 //            if(val > joystickThreshold){
505 //                xtstAdapter.sendKey("Down", true);
506 //            }else if(val < -joystickThreshold){
507 //                xtstAdapter.sendKey("Up", true);
508 //            }else{
509 //                xtstAdapter.sendKey("Down", false);
510 //                xtstAdapter.sendKey("Up", false);
511 //            }
512 //        }
513     }
514
515     XtstAdapter{
516         id: xtstAdapter
517     }
518 }