ElisaMainWindow.qml 11.2 KB
Newer Older
1
/*
2
 * Copyright 2016-2018 Matthieu Gallien <matthieu_gallien@yahoo.fr>
3
 *
4 5
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
6 7 8
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
9
 * This program is distributed in the hope that it will be useful,
10 11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
13
 *
14 15
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16 17
 */

18
import QtQuick 2.7
19
import QtQuick.Controls 2.3
20 21
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2
22
import org.kde.kirigami 2.5 as Kirigami
23
import org.kde.elisa 1.0
24
import Qt.labs.settings 1.0
25 26

ApplicationWindow {
27
    id: mainWindow
28
    
29
    visible: true
30 31 32
    
    minimumWidth: 590
    property int minHeight: 320
33

Safa AlFulaij's avatar
Safa AlFulaij committed
34 35 36
    LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft
    LayoutMirroring.childrenInherit: true

37 38 39 40 41
    x: persistentSettings.x
    y: persistentSettings.y
    width: persistentSettings.width
    height: persistentSettings.height

Safa AlFulaij's avatar
Safa AlFulaij committed
42
    title: i18n("Elisa")
43

44 45 46
    Accessible.role: Accessible.Application
    Accessible.name: title

47
    property var goBackAction: elisa.action("go_back")
48 49
    property var seekAction: elisa.action("Seek")
    property var scrubAction: elisa.action("Scrub")
50
    property var playPauseAction: elisa.action("Play-Pause")
51
    property var findAction: elisa.action("edit_find")
Diego Gangl's avatar
Diego Gangl committed
52

53
    Action {
54
        shortcut: goBackAction.shortcut
55
        onTriggered: contentView.goBack()
56 57
    }

58
    Action {
59 60
        shortcut: seekAction.shortcut
        onTriggered: elisa.audioControl.seek(headerBar.playerControl.position + 10000)
61 62 63
    }

    Action {
64 65
        shortcut: scrubAction.shortcut
        onTriggered: elisa.audioControl.seek(headerBar.playerControl.position - 10000)
66 67
    }

68
    Action {
69 70 71 72 73 74 75
        shortcut: playPauseAction.shortcut
        onTriggered: elisa.audioControl.playPause()
    }

    Action {
        shortcut: findAction.shortcut
        onTriggered: persistentSettings.expandedFilterView = !persistentSettings.expandedFilterView
76 77
    }

78 79 80 81
    ApplicationMenu {
        id: applicationMenu
    }

82 83 84 85 86
    SystemPalette {
        id: myPalette
        colorGroup: SystemPalette.Active
    }

87 88 89 90
    Theme {
        id: elisaTheme
    }

91
    Settings {
92 93 94 95
        id: persistentSettings

        property int x
        property int y
96 97
        property int width : 900
        property int height : 650
98

99
        property var playListState
100

101
        property var audioPlayerState
102

103
        property double playControlItemVolume : 100.0
104
        property bool playControlItemMuted : false
105

106
        property bool expandedFilterView: false
107

Diego Gangl's avatar
Diego Gangl committed
108
        property bool showPlaylist: true
109 110

        property bool headerBarIsMaximized: false
111 112 113 114
    }

    Connections {
        target: headerBar.playerControl
115 116 117 118 119 120 121
        onOpenMenu: {
            if (applicationMenu.visible) {
                applicationMenu.close()
            } else {
                applicationMenu.popup(mainWindow.width - applicationMenu.width, headerBar.height)
            }
        }
122
    }
123

124 125 126 127 128 129 130 131 132
    Connections {
        target: Qt.application
        onAboutToQuit:
        {
            persistentSettings.x = mainWindow.x;
            persistentSettings.y = mainWindow.y;
            persistentSettings.width = mainWindow.width;
            persistentSettings.height = mainWindow.height;

133
            persistentSettings.playListState = elisa.mediaPlayList.persistentState;
Alexander Stippich's avatar
Alexander Stippich committed
134
            persistentSettings.audioPlayerState = elisa.audioControl.persistentState
135

136 137
            persistentSettings.playControlItemVolume = headerBar.playerControl.volume
            persistentSettings.playControlItemMuted = headerBar.playerControl.muted
Diego Gangl's avatar
Diego Gangl committed
138

Diego Gangl's avatar
Diego Gangl committed
139
            persistentSettings.showPlaylist = contentView.showPlaylist
140 141

            persistentSettings.headerBarIsMaximized = headerBar.isMaximized
142 143 144
        }
    }

Alexander Stippich's avatar
Alexander Stippich committed
145 146 147
    Loader {
        id: mprisloader
        active: false
148

Alexander Stippich's avatar
Alexander Stippich committed
149 150
        sourceComponent:  PlatformIntegration {
            id: platformInterface
151

Alexander Stippich's avatar
Alexander Stippich committed
152 153 154
            playListModel: elisa.mediaPlayList
            audioPlayerManager: elisa.audioControl
            player: elisa.audioPlayer
155 156
            headerBarManager: elisa.manageHeaderBar
            manageMediaPlayerControl: elisa.playerControl
157
            showProgressOnTaskBar: elisa.showProgressOnTaskBar
158

159
            onRaisePlayer: {
Alexander Stippich's avatar
Alexander Stippich committed
160 161 162 163
                mainWindow.show()
                mainWindow.raise()
                mainWindow.requestActivate()
            }
164

165
        }
166 167
    }

Alexander Stippich's avatar
Alexander Stippich committed
168 169
    Connections {
        target: elisa.audioPlayer
170 171
        onVolumeChanged: headerBar.playerControl.volume = elisa.audioPlayer.volume
        onMutedChanged: headerBar.playerControl.muted = elisa.audioPlayer.muted
172 173
    }

174
    Rectangle {
175
        color: myPalette.base
176 177
        anchors.fill: parent

178 179 180
        ColumnLayout {
            anchors.fill: parent
            spacing: 0
181

182 183 184 185 186
            HeaderBar {
                id: headerBar

                focus: true

187 188
                Layout.minimumHeight: mainWindow.height * 0.2 + elisaTheme.mediaPlayerControlHeight
                Layout.maximumHeight: mainWindow.height * 0.2 + elisaTheme.mediaPlayerControlHeight
189
                Layout.fillWidth: true
Matthieu Gallien's avatar
Matthieu Gallien committed
190

191
                tracksCount: elisa.mediaPlayList.remainingTracks
192
                album: (elisa.manageHeaderBar.album !== undefined ? elisa.manageHeaderBar.album : '')
193
                title: elisa.manageHeaderBar.title
194 195
                artist: (elisa.manageHeaderBar.artist !== undefined ? elisa.manageHeaderBar.artist : '')
                albumArtist: (elisa.manageHeaderBar.albumArtist !== undefined ? elisa.manageHeaderBar.albumArtist : '')
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
                image: elisa.manageHeaderBar.image
                albumID: elisa.manageHeaderBar.albumId

                ratingVisible: false

                playerControl.duration: elisa.audioPlayer.duration
                playerControl.seekable: elisa.audioPlayer.seekable

                playerControl.volume: persistentSettings.playControlItemVolume
                playerControl.muted: persistentSettings.playControlItemMuted
                playerControl.position: elisa.audioPlayer.position
                playerControl.skipBackwardEnabled: elisa.playerControl.skipBackwardControlEnabled
                playerControl.skipForwardEnabled: elisa.playerControl.skipForwardControlEnabled
                playerControl.playEnabled: elisa.playerControl.playControlEnabled
                playerControl.isPlaying: elisa.playerControl.musicPlaying

                playerControl.repeat: elisa.mediaPlayList.repeatPlay
                playerControl.shuffle: elisa.mediaPlayList.randomPlay

                playerControl.onSeek: elisa.audioPlayer.seek(position)

                playerControl.onPlay: elisa.audioControl.playPause()
                playerControl.onPause: elisa.audioControl.playPause()
                playerControl.onPlayPrevious: elisa.mediaPlayList.skipPreviousTrack()
                playerControl.onPlayNext: elisa.mediaPlayList.skipNextTrack()

                playerControl.isMaximized: persistentSettings.headerBarIsMaximized
                onOpenArtist: { contentView.openArtist(artist) }
                onOpenNowPlaying: { contentView.openNowPlaying() }
                onOpenAlbum: { contentView.openAlbum(album, albumArtist, image, albumID) }

                TrackImportNotification {
                    id: importedTracksCountNotification

                    anchors
                    {
                        right: headerBar.right
                        top: headerBar.top
234 235
                        rightMargin: Kirigami.Units.largeSpacing * 2
                        topMargin: Kirigami.Units.largeSpacing * 3
236
                    }
237
                }
238

239 240
                Binding {
                    id: indexerBusyBinding
241

242 243 244 245 246
                    target: importedTracksCountNotification
                    property: 'indexingRunning'
                    value: elisa.musicManager.indexerBusy
                    when: elisa.musicManager !== undefined
                }
247

248 249 250 251 252
                Binding {
                    target: importedTracksCountNotification
                    property: 'importedTracksCount'
                    value: elisa.musicManager.importedTracksCount
                    when: elisa.musicManager !== undefined
253
                }
254
            }
255

256 257 258 259 260 261
            Rectangle {
                Layout.fillWidth: true
                height: 1
                color: myPalette.mid
            }

262 263
            ContentView {
                id: contentView
264
                Layout.fillHeight: true
265
                Layout.fillWidth: true
Diego Gangl's avatar
Diego Gangl committed
266
                showPlaylist: persistentSettings.showPlaylist
267
                showExpandedFilterView: persistentSettings.expandedFilterView
268
            }
269 270
        }
    }
271

272 273 274
    StateGroup {
        id: mainWindowState
        states: [
275 276 277 278 279 280
            State {
                name: "headerBarIsNormal"
                when: !headerBar.isMaximized
                changes: [
                    PropertyChanges {
                        target: mainWindow
281
                        minimumHeight: mainWindow.minHeight * 1.5
282 283 284
                        explicit: true
                    },
                    PropertyChanges {
285
                        target: headerBar
286 287 288 289 290
                        Layout.minimumHeight: mainWindow.height * 0.2 + elisaTheme.mediaPlayerControlHeight
                        Layout.maximumHeight: mainWindow.height * 0.2 + elisaTheme.mediaPlayerControlHeight
                    }
                ]
            },
291 292
            State {
                name: "headerBarIsMaximized"
Matthieu Gallien's avatar
Matthieu Gallien committed
293
                when: headerBar.isMaximized
294 295 296
                changes: [
                    PropertyChanges {
                        target: mainWindow
297
                        minimumHeight: mainWindow.minHeight
298 299 300
                        explicit: true
                    },
                    PropertyChanges {
301
                        target: headerBar
302 303 304 305 306 307
                        Layout.minimumHeight: mainWindow.height
                        Layout.maximumHeight: mainWindow.height
                    }
                ]
            }
        ]
308 309 310 311 312 313 314
        transitions: Transition {
            NumberAnimation {
                properties: "Layout.minimumHeight, Layout.maximumHeight, minimumHeight"
                easing.type: Easing.InOutQuad
                duration: 300
            }
        }
315 316
    }

317 318 319 320
    Component.onCompleted:
    {
        elisa.initialize()

321 322 323
        if (persistentSettings.playListState) {
            elisa.mediaPlayList.persistentState = persistentSettings.playListState
        }
Diego Gangl's avatar
Diego Gangl committed
324

Alexander Stippich's avatar
Alexander Stippich committed
325 326 327
        if (persistentSettings.audioPlayerState) {
            elisa.audioControl.persistentState = persistentSettings.audioPlayerState
        }
Alexander Stippich's avatar
Alexander Stippich committed
328

329 330
        elisa.mediaPlayList.randomPlay = Qt.binding(function() { return headerBar.playerControl.shuffle })
        elisa.mediaPlayList.repeatPlay = Qt.binding(function() { return headerBar.playerControl.repeat })
Alexander Stippich's avatar
Alexander Stippich committed
331 332 333
        elisa.audioPlayer.muted = Qt.binding(function() { return headerBar.playerControl.muted })
        elisa.audioPlayer.volume = Qt.binding(function() { return headerBar.playerControl.volume })

Alexander Stippich's avatar
Alexander Stippich committed
334
        mprisloader.active = true
335
    }
336
}