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.elisa 1.0
23
import Qt.labs.settings 1.0
24 25

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

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

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

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

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

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

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

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

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

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

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

77 78 79 80
    ApplicationMenu {
        id: applicationMenu
    }

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

86 87 88 89
    Theme {
        id: elisaTheme
    }

90
    Settings {
91 92 93 94
        id: persistentSettings

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

98
        property var playListState
99

100
        property var audioPlayerState
101

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

105
        property bool expandedFilterView: false
106

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

        property bool headerBarIsMaximized: false
110 111 112 113
    }

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

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

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

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

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

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

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

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

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

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

164
        }
165 166
    }

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

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

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

181 182 183 184 185
            HeaderBar {
                id: headerBar

                focus: true

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

190
                tracksCount: elisa.mediaPlayList.remainingTracks
191
                album: (elisa.manageHeaderBar.album !== undefined ? elisa.manageHeaderBar.album : '')
192
                title: elisa.manageHeaderBar.title
193 194
                artist: (elisa.manageHeaderBar.artist !== undefined ? elisa.manageHeaderBar.artist : '')
                albumArtist: (elisa.manageHeaderBar.albumArtist !== undefined ? elisa.manageHeaderBar.albumArtist : '')
195 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 234
                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
                        rightMargin: elisaTheme.layoutHorizontalMargin * 1.75
                        topMargin: elisaTheme.layoutHorizontalMargin * 3
235
                    }
236
                }
237

238 239
                Binding {
                    id: indexerBusyBinding
240

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

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

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

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

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

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

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

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

328 329
        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
330 331 332
        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
333
        mprisloader.active = true
334
    }
335
}