ElisaMainWindow.qml 11.1 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 27
    id: mainWindow

28
    visible: true
29

Diego Gangl's avatar
Diego Gangl committed
30
    minimumWidth: contentView.showPlaylist ? 1100 : 700
31
    minimumHeight: 600
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
        property int width : 1100
96
        property int height : 600
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
        onOpenMenu: if (applicationMenu.visible) {
                        applicationMenu.close()
                    } else {
                        applicationMenu.popup()
                    }
119
    }
120

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

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

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

Diego Gangl's avatar
Diego Gangl committed
136
            persistentSettings.showPlaylist = contentView.showPlaylist
137 138

            persistentSettings.headerBarIsMaximized = headerBar.isMaximized
139 140 141
        }
    }

Alexander Stippich's avatar
Alexander Stippich committed
142 143 144
    Loader {
        id: mprisloader
        active: false
145

Alexander Stippich's avatar
Alexander Stippich committed
146 147
        sourceComponent:  PlatformIntegration {
            id: platformInterface
148

Alexander Stippich's avatar
Alexander Stippich committed
149 150 151
            playListModel: elisa.mediaPlayList
            audioPlayerManager: elisa.audioControl
            player: elisa.audioPlayer
152 153 154
            headerBarManager: elisa.manageHeaderBar
            manageMediaPlayerControl: elisa.playerControl
            onRaisePlayer: {
Alexander Stippich's avatar
Alexander Stippich committed
155 156 157 158
                mainWindow.show()
                mainWindow.raise()
                mainWindow.requestActivate()
            }
159

160
        }
161 162
    }

Alexander Stippich's avatar
Alexander Stippich committed
163 164
    Connections {
        target: elisa.audioPlayer
165 166
        onVolumeChanged: headerBar.playerControl.volume = elisa.audioPlayer.volume
        onMutedChanged: headerBar.playerControl.muted = elisa.audioPlayer.muted
167 168
    }

169
    Rectangle {
170
        color: myPalette.base
171 172
        anchors.fill: parent

173 174 175
        ColumnLayout {
            anchors.fill: parent
            spacing: 0
176

177 178 179 180 181
            HeaderBar {
                id: headerBar

                focus: true

182 183
                Layout.minimumHeight: mainWindow.height * 0.2 + elisaTheme.mediaPlayerControlHeight
                Layout.maximumHeight: mainWindow.height * 0.2 + elisaTheme.mediaPlayerControlHeight
184
                Layout.fillWidth: true
Matthieu Gallien's avatar
Matthieu Gallien committed
185

186
                tracksCount: elisa.mediaPlayList.remainingTracks
187 188 189 190 191 192 193 194 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
                album: elisa.manageHeaderBar.album
                title: elisa.manageHeaderBar.title
                artist: elisa.manageHeaderBar.artist
                albumArtist: elisa.manageHeaderBar.albumArtist
                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
231
                    }
232
                }
233

234 235
                Binding {
                    id: indexerBusyBinding
236

237 238 239 240 241
                    target: importedTracksCountNotification
                    property: 'indexingRunning'
                    value: elisa.musicManager.indexerBusy
                    when: elisa.musicManager !== undefined
                }
242

243 244 245 246 247
                Binding {
                    target: importedTracksCountNotification
                    property: 'importedTracksCount'
                    value: elisa.musicManager.importedTracksCount
                    when: elisa.musicManager !== undefined
248
                }
249
            }
250

251 252 253 254 255 256
            Rectangle {
                Layout.fillWidth: true
                height: 1
                color: myPalette.mid
            }

257 258
            ContentView {
                id: contentView
259
                Layout.fillHeight: true
260
                Layout.fillWidth: true
Diego Gangl's avatar
Diego Gangl committed
261
                showPlaylist: persistentSettings.showPlaylist
262
                showExpandedFilterView: persistentSettings.expandedFilterView
263
            }
264 265
        }
    }
266

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

312 313 314 315
    Component.onCompleted:
    {
        elisa.initialize()

316 317 318
        if (persistentSettings.playListState) {
            elisa.mediaPlayList.persistentState = persistentSettings.playListState
        }
Diego Gangl's avatar
Diego Gangl committed
319

Alexander Stippich's avatar
Alexander Stippich committed
320 321 322
        if (persistentSettings.audioPlayerState) {
            elisa.audioControl.persistentState = persistentSettings.audioPlayerState
        }
Alexander Stippich's avatar
Alexander Stippich committed
323

324 325 326
        elisa.mediaPlayList.randomPlay = Qt.binding(function() { return headerBar.playerControl.shuffle })
        elisa.mediaPlayList.repeatPlay = Qt.binding(function() { return headerBar.playerControl.repeat })
        elisa.playerControl.randomOrContinuePlay = Qt.binding(function() { return headerBar.playerControl.shuffle || headerBar.playerControl.repeat})
Alexander Stippich's avatar
Alexander Stippich committed
327 328 329
        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
330
        mprisloader.active = true
331
    }
332
}