new InfoPanel
[qtmediahub:flunder.git] / r720 / Flunder.qml
1 /*
2  * Copyright (C) 2010 Johannes Zellner <webmaster@nebulon.de>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 import QtQuick 1.0
20 //import Qt.labs.particles 1.0
21 import DirModel 1.0
22 import MediaModel 1.0
23
24 Rectangle {
25     id : flunder
26
27     height: 720
28     width: 1280
29     focus: true
30     clip: true
31
32     property real scalingCorrection: flunder.width == 1280 ? 1.0 : flunder.width/1280
33     property string themeResourcePath: runtime.skin.path + "/media/"
34
35     property variant rootMenuModel: ListModel { }
36
37     function showOptionDialog(model) {
38         optionsList.model = model
39         optionsList.state = "visible"
40         optionsList.focus = true
41         flunder.blackout.show()
42     }
43
44     function hideOptionDialog() {
45         optionsList.state = ""
46         optionsList.focus = false
47         currentElement.focus = true
48         flunder.blackout.hide()
49     }
50
51     function showMainMenu() {
52         show(menuView, "")
53     }
54
55     property variant avPlayer
56
57     property variant currentElement
58     property variant background : backgroundImage
59     property variant blackout : blackoutItem
60
61     // some global z-layer values
62     property int layerBackground: 1
63     property int layerAVPlayer: layerBackground+1
64     property int layerViews: layerAVPlayer+1
65     // layerViews - 1000 reserved for stuff like clock, global busy, context menus
66     property int layerBlackout: 1000
67     property int layerDialogs: layerBlackout+10
68
69     function createQmlObjectFromFile(file, parent) {
70         var qmlComponent = Qt.createComponent(file)
71         if (qmlComponent.status == Component.Ready) {
72             return qmlComponent.createObject(parent)
73         }
74         console.log(qmlComponent.errorString())
75         return null
76     }
77
78     Component.onCompleted: {
79         var musicWindow = createQmlObjectFromFile("MusicWindow.qml", flunder);
80         flunder.rootMenuModel.append({name: qsTr("Music"), visualElement: musicWindow, icon: themeResourcePath + "Music.png", url: "MusicWindow.qml"})
81
82         var videoWindow = createQmlObjectFromFile("VideoWindow.qml", flunder);
83         flunder.rootMenuModel.append({name: qsTr("Video"), visualElement: videoWindow, icon: themeResourcePath + "Video.png", url: "VideoWindow.qml"})
84
85         var pictureWindow = createQmlObjectFromFile("PictureWindow.qml", flunder);
86         flunder.rootMenuModel.append({name: qsTr("Picture"), visualElement: pictureWindow, icon: themeResourcePath + "Picture.png", url: "PictureWindow.qml"})
87
88         var radioWindow = createQmlObjectFromFile("RadioWindow.qml", flunder);
89         flunder.rootMenuModel.append({name: qsTr("Radio"), visualElement: radioWindow, icon: themeResourcePath + "Radio.png", url: "RadioWindow.qml"})
90
91         var apps = runtime.file.findApplications()
92         for (var idx in apps) {
93             var path = apps[idx]
94             if ((path.indexOf('demolition') < 0)) {
95                 var manifest = createQmlObjectFromFile(path + "qmhmanifest.qml", flunder)
96                 var uiType = manifest.ui.substring(manifest.ui.lastIndexOf('.')+1)
97                 if (uiType == "qml") {
98                     flunder.rootMenuModel.append({ name: manifest.name, visualElement: undefined, icon: manifest.icon != undefined ? path + manifest.icon : themeResourcePath + "Application.png", url: path + manifest.ui })
99                     runtime.view.addImportPath(path + "imports")
100                 } else {
101                     console.log('Application ' + manifest.name + ' at ' + path + ' with ui:' + manifest.ui + ' could not be loaded.')
102                 }
103             }
104         }
105
106         menuView.model = flunder.rootMenuModel
107
108         show(menuView, "")
109     }
110
111     function show(element, url)
112     {
113         if (currentElement == element)
114             return;
115
116         if (currentElement && currentElement != avPlayer)
117             currentElement.state = ""
118
119         if (element === undefined) {
120             currentElement = createQmlObjectFromFile("ApplicationWindow.qml", flunder)
121             createQmlObjectFromFile(url, currentElement);
122         } else {
123             currentElement = element
124         }
125
126         if (currentElement == avPlayer) {
127             currentElement.state = "maximized"
128         } else if (currentElement == menuView) {
129             menuView.state = "visible"
130             avPlayer.state = "background"
131         } else {
132             //particleEffect.burst(500);
133             currentElement.state = "visible"
134             avPlayer.state = "background"
135         }
136         currentElement.forceActiveFocus()
137     }
138
139     AVPlayer {
140         id: avPlayer
141         state: "background"
142     }
143
144     Background {
145         id: backgroundImage
146         anchors.fill: parent
147         smooth: true
148         z: layerBackground
149     }
150
151 //    Particles {
152 //        id: particleEffect
153 //        anchors.centerIn: parent
154 //        width: 1
155 //        height: 1
156 //        source: themeResourcePath + "/particle.png"
157 //        lifeSpan: 500
158 //        count: 0
159 //        angle: 0
160 //        angleDeviation: 360
161 //        velocity: 500
162 //        velocityDeviation: 4000
163 //        z: layerViews
164 //    }
165
166 //    DigitalClock {
167 //        id: digitalClock
168 //        anchors { right: parent.right; top: parent.top; }
169 //        textColor : "white"
170 //        showSeconds : false
171 //        z: layerViews+1
172 //        state: avPlayer && avPlayer.state == "maximized" && avPlayer.hasVideo ? "" : "visible"
173 //    }
174
175     InfoPanel {
176         id: infoPanel
177         anchors.left: parent.left
178         y: 0
179         z: layerViews+1
180     }
181
182     Keys.onMenuPressed:
183         if (menuView.state == "visible") {
184             if (avPlayer.playing)
185                 show(avPlayer, "");
186         } else
187             show(menuView, "");
188     Keys.onVolumeUpPressed: avPlayer.increaseVolume();
189     Keys.onVolumeDownPressed: avPlayer.decreaseVolume();
190
191     Keys.onPressed: {
192         if (event.key == Qt.Key_MediaTogglePlayPause) {
193             avPlayer.togglePlayPause()
194         } else if (event.key == Qt.Key_MediaStop) {
195             avPlayer.stop()
196         } else if (event.key == Qt.Key_MediaPrevious) {
197             avPlayer.playPrevious()
198         } else if (event.key == Qt.Key_MediaNext) {
199             avPlayer.playNext()
200         } else if (event.key == Qt.Key_I) {
201             infoPanel.show()
202         }
203     }
204
205     MenuView {
206         id: menuView
207         opacity: 0.0
208         anchors.top: parent.top
209         anchors.left: parent.left
210         width: parent.width
211         height: parent.height
212         state:  "visible"
213         z: layerViews
214
215         onActivated: flunder.show(visualElement, url)
216     }
217
218     VolumeOSD {
219         id: volumeOSD
220
221         anchors.left: parent.left
222         anchors.top: parent.top
223         z: layerAVPlayer+1
224     }
225
226     Rectangle {
227         id: blackoutItem
228         anchors.fill: parent
229         color: "black"
230         opacity: 0
231         z: layerBlackout
232
233         function show() {
234             opacity = 0.6
235         }
236
237         function hide() {
238             opacity = 0
239         }
240
241         Behavior on opacity { NumberAnimation {} }
242
243         MouseArea {
244             id: mouseConsumer
245             anchors.fill: parent
246             hoverEnabled: true
247             onClicked: mouse.accepted = true
248         }
249     }
250
251     Connections {
252         target: runtime.deviceManager
253         onDeviceAdded: {
254             console.log("new device detected");
255             console.log("mount device "+device)
256             runtime.deviceManager.getDeviceByPath(device).mount();
257         }
258         onDeviceRemoved: {
259             console.log("device removed "+device)
260         }
261     }
262
263     ScannerProgress {
264         id: scannerProgress
265         z: layerAVPlayer+1
266     }
267
268     ActionListView {
269         id: optionsList
270         anchors.horizontalCenter: parent.horizontalCenter
271         anchors.verticalCenter: parent.verticalCenter
272         anchors.verticalCenterOffset: -parent.height/2.0 - height
273         height: 150
274         width: model ? height*model.length :0
275
276         Keys.onUpPressed: hideOptionDialog()
277         Keys.onDownPressed: hideOptionDialog()
278         Keys.onBackPressed: hideOptionDialog()
279         Keys.onMenuPressed: hideOptionDialog()
280     }
281 }