ElisaMainWindow.qml 11.5 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
import Qt.labs.platform 1.1
26 27

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

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

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

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

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

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

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

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

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

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

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

79 80 81 82
    ApplicationMenu {
        id: applicationMenu
    }

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

88 89 90 91
    Theme {
        id: elisaTheme
    }

92
    Settings {
93 94 95 96
        id: persistentSettings

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

100
        property var playListState
101

102
        property var audioPlayerState
103

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

107
        property bool expandedFilterView: false
108

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

        property bool headerBarIsMaximized: false
112 113 114 115
    }

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

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

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

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

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

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

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

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

153
            playListModel: elisa.mediaPlayListProxyModel
Alexander Stippich's avatar
Alexander Stippich committed
154 155
            audioPlayerManager: elisa.audioControl
            player: elisa.audioPlayer
156 157
            headerBarManager: elisa.manageHeaderBar
            manageMediaPlayerControl: elisa.playerControl
158
            showProgressOnTaskBar: elisa.showProgressOnTaskBar
159 160
            showSystemTrayIcon: elisa.showSystemTrayIcon
            elisaMainWindow: mainWindow
161

162
            onRaisePlayer: {
163
                mainWindow.visible = true
Alexander Stippich's avatar
Alexander Stippich committed
164 165 166
                mainWindow.raise()
                mainWindow.requestActivate()
            }
167

168
        }
169 170
    }

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

177
    Rectangle {
178
        color: myPalette.base
179 180
        anchors.fill: parent

181 182 183
        ColumnLayout {
            anchors.fill: parent
            spacing: 0
184

185 186 187 188 189
            HeaderBar {
                id: headerBar

                focus: true

190 191
                Layout.minimumHeight: mainWindow.height * 0.2 + elisaTheme.mediaPlayerControlHeight
                Layout.maximumHeight: mainWindow.height * 0.2 + elisaTheme.mediaPlayerControlHeight
192
                Layout.fillWidth: true
Matthieu Gallien's avatar
Matthieu Gallien committed
193

194
                tracksCount: elisa.mediaPlayListProxyModel.remainingTracks
195
                album: (elisa.manageHeaderBar.album !== undefined ? elisa.manageHeaderBar.album : '')
196
                title: elisa.manageHeaderBar.title
197 198
                artist: (elisa.manageHeaderBar.artist !== undefined ? elisa.manageHeaderBar.artist : '')
                albumArtist: (elisa.manageHeaderBar.albumArtist !== undefined ? elisa.manageHeaderBar.albumArtist : '')
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
                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

215
                playerControl.repeat: elisa.mediaPlayListProxyModel.repeatPlay
216
                playerControl.shuffle: elisa.mediaPlayListProxyModel.shufflePlayList
217 218 219 220 221

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

                playerControl.onPlay: elisa.audioControl.playPause()
                playerControl.onPause: elisa.audioControl.playPause()
222 223
                playerControl.onPlayPrevious: elisa.mediaPlayListProxyModel.skipPreviousTrack()
                playerControl.onPlayNext: elisa.mediaPlayListProxyModel.skipNextTrack()
224 225 226 227 228 229 230 231 232 233 234 235 236

                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
237 238
                        rightMargin: Kirigami.Units.largeSpacing * 2
                        topMargin: Kirigami.Units.largeSpacing * 3
239
                    }
240
                }
241

242 243
                Binding {
                    id: indexerBusyBinding
244

245 246 247 248 249
                    target: importedTracksCountNotification
                    property: 'indexingRunning'
                    value: elisa.musicManager.indexerBusy
                    when: elisa.musicManager !== undefined
                }
250

251 252 253 254 255
                Binding {
                    target: importedTracksCountNotification
                    property: 'importedTracksCount'
                    value: elisa.musicManager.importedTracksCount
                    when: elisa.musicManager !== undefined
256
                }
257
            }
258

259 260 261 262 263 264
            Rectangle {
                Layout.fillWidth: true
                height: 1
                color: myPalette.mid
            }

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

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

320 321 322 323
    Component.onCompleted:
    {
        elisa.initialize()

324
        if (persistentSettings.playListState) {
325
            elisa.mediaPlayListProxyModel.persistentState = persistentSettings.playListState
326
        }
Diego Gangl's avatar
Diego Gangl committed
327

Alexander Stippich's avatar
Alexander Stippich committed
328 329 330
        if (persistentSettings.audioPlayerState) {
            elisa.audioControl.persistentState = persistentSettings.audioPlayerState
        }
Alexander Stippich's avatar
Alexander Stippich committed
331

332
        elisa.mediaPlayListProxyModel.shufflePlayList = Qt.binding(function() { return headerBar.playerControl.shuffle })
333
        elisa.mediaPlayListProxyModel.repeatPlay = Qt.binding(function() { return headerBar.playerControl.repeat })
Alexander Stippich's avatar
Alexander Stippich committed
334 335 336
        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
337
        mprisloader.active = true
338
    }
339
}