ElisaMainWindow.qml 39.3 KB
Newer Older
1
/*
2
 * Copyright 2016-2017 Matthieu Gallien <matthieu_gallien@yahoo.fr>
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

20
import QtQuick 2.7
21 22 23 24
import QtQuick.Controls 1.3
import QtQuick.Controls.Styles 1.3
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2
25
import Qt.labs.platform 1.0 as PlatformDialog
26
import org.kde.elisa 1.0
27
import Qt.labs.settings 1.0
28 29

ApplicationWindow {
30 31
    id: mainWindow

32
    visible: true
33

34 35
    minimumWidth: 1000
    minimumHeight: 600
36

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

40 41 42 43 44
    x: persistentSettings.x
    y: persistentSettings.y
    width: persistentSettings.width
    height: persistentSettings.height

45
    title: 'Elisa'
46

47 48 49 50 51
    property var helpAction: elisa.action("help_contents")
    property var quitApplication: elisa.action("file_quit")
    property var reportBugAction: elisa.action("help_report_bug")
    property var aboutAppAction: elisa.action("help_about_app")
    property var configureShortcutsAction: elisa.action("options_configure_keybinding")
52
    property var configureAction: elisa.action("options_configure")
53
    property var goBackAction: elisa.action("go_back")
54

55 56 57 58 59
    SystemPalette {
        id: myPalette
        colorGroup: SystemPalette.Active
    }

60 61 62 63
    Theme {
        id: elisaTheme
    }

64
    Settings {
65 66 67 68
        id: persistentSettings

        property int x
        property int y
69 70
        property int width : 1000
        property int height : 600
71

72
        property var playListState
73 74

        property var playListControlerState
75 76

        property var audioPlayerState
77

78
        property double playControlItemVolume : 100.0
79
        property bool playControlItemMuted : false
80 81
    }

82 83 84 85 86 87 88 89 90
    Action {
        text: goBackAction.text
        shortcut: goBackAction.shortcut
        iconName: elisa.iconName(goBackAction.icon)
        onTriggered: {
            localAlbums.goBack()
            localArtists.goBack()
        }
    }
91

92 93 94 95 96 97 98 99
    Action {
        id: qmlQuitAction
        text: quitApplication.text
        shortcut: quitApplication.shortcut
        iconName: elisa.iconName(quitApplication.icon)
        onTriggered: quitApplication.trigger()
    }

100 101 102 103
    property string globalBrowseFlag: 'BrowseDirectChildren'
    property string globalFilter: '*'
    property string globalSortCriteria: ''

104 105 106 107 108 109 110 111 112 113
    Connections {
        target: Qt.application
        onAboutToQuit:
        {
            persistentSettings.x = mainWindow.x;
            persistentSettings.y = mainWindow.y;
            persistentSettings.width = mainWindow.width;
            persistentSettings.height = mainWindow.height;

            persistentSettings.playListState = playListModelItem.persistentState;
114
            persistentSettings.playListControlerState = playListModelItem.persistentState;
115
            persistentSettings.audioPlayerState = manageAudioPlayer.persistentState
116

117 118
            persistentSettings.playControlItemVolume = headerBar.playerControl.volume
            persistentSettings.playControlItemMuted = headerBar.playerControl.muted
119 120 121
        }
    }

122 123
    PlatformIntegration {
        id: platformInterface
124

125
        playListModel: playListModelItem
126
        playListControler: playListModelItem
127 128 129
        audioPlayerManager: manageAudioPlayer
        headerBarManager: myHeaderBarManager
        manageMediaPlayerControl: myPlayControlManager
130
        player: audioPlayer
131 132 133

        onRaisePlayer:
        {
134
            mainWindow.show()
135 136 137
            mainWindow.raise()
            mainWindow.requestActivate()
        }
138 139
    }

140
    AudioWrapper {
141 142
        id: audioPlayer

143
        muted: headerBar.playerControl.muted
144

145
        volume: headerBar.playerControl.volume
146

147
        onVolumeChanged: headerBar.playerControl.volume = volume
148
        onMutedChanged: headerBar.playerControl.muted = muted
149

150 151 152 153 154 155 156 157 158
        source: manageAudioPlayer.playerSource

        onPlaying: {
            myPlayControlManager.playerPlaying()
        }

        onPaused: {
            myPlayControlManager.playerPaused()
        }
159

160 161 162
        onStopped: {
            myPlayControlManager.playerStopped()
        }
163 164 165 166
    }

    MediaPlayList {
        id: playListModelItem
167

168
        persistentState: persistentSettings.playListState
169
        musicListenersManager: allListeners
170

Matthieu Gallien's avatar
Matthieu Gallien committed
171 172
        onPlayListFinished: manageAudioPlayer.playListFinished()

173 174 175 176 177
        Component.onCompleted:
        {
            var d = new Date();
            var n = d.getMilliseconds();
            seedRandomGenerator(n);
178 179

            playFiles(elisa.arguments)
180 181 182 183 184
            allAlbumsProxyModel.setMediaPlayList(playListModelItem)
            allArtistsProxyModel.setMediaPlayList(playListModelItem)
            allTracksProxyModel.setMediaPlayList(playListModelItem)
            singleAlbumProxyModel.setMediaPlayList(playListModelItem)
            singleArtistProxyModel.setMediaPlayList(playListModelItem)
185
        }
186 187 188 189 190

        onPlayListLoadFailed:
        {
            messageNotification.showNotification(i18nc("message of passive notification when playlist load failed", "Load of playlist failed"), 3000)
        }
191 192 193

        function playFiles(listFiles)
        {
194 195 196 197 198 199
            if (listFiles.length > 0) {
                var previousTrackNumber = tracksCount
                enqueue(listFiles)
                switchTo(previousTrackNumber)
                manageAudioPlayer.ensurePlay()
            }
200 201 202 203 204 205 206 207 208 209
        }
    }

    Connections {
        target: elisa

        onEnqueue:
        {
            playListModelItem.playFiles(files)
        }
210 211 212 213 214 215
    }

    ManageHeaderBar {
        id: myHeaderBarManager

        playListModel: playListModelItem
216
        currentTrack: playListModelItem.currentTrack
217

218 219 220 221
        artistRole: MediaPlayList.ArtistRole
        titleRole: MediaPlayList.TitleRole
        albumRole: MediaPlayList.AlbumRole
        imageRole: MediaPlayList.ImageRole
222
        isValidRole: MediaPlayList.IsValidRole
223 224 225 226 227
    }

    ManageAudioPlayer {
        id: manageAudioPlayer

228
        currentTrack: playListModelItem.currentTrack
229
        playListModel: playListModelItem
230
        urlRole: MediaPlayList.ResourceRole
231
        isPlayingRole: MediaPlayList.IsPlayingRole
232 233 234
        titleRole: MediaPlayList.TitleRole
        artistNameRole: MediaPlayList.ArtistRole
        albumNameRole: MediaPlayList.AlbumRole
235

236 237 238
        playerStatus: audioPlayer.status
        playerPlaybackState: audioPlayer.playbackState
        playerError: audioPlayer.error
239
        audioDuration: audioPlayer.duration
240
        playerIsSeekable: audioPlayer.seekable
241
        playerPosition: audioPlayer.position
242

243
        persistentState: persistentSettings.audioPlayerState
244

245 246 247
        onPlayerPlay: audioPlayer.play()
        onPlayerPause: audioPlayer.pause()
        onPlayerStop: audioPlayer.stop()
248
        onSkipNextTrack: playListModelItem.skipNextTrack()
249
        onSeek: audioPlayer.seek(position)
250 251 252 253 254 255 256
        onSourceInError:
        {
            playListModelItem.trackInError(source, playerError)
            allListeners.playBackError(source, playerError)
        }

        onDisplayTrackError: messageNotification.showNotification(i18n("Error when playing %1", "" + fileName), 3000)
257 258 259 260 261 262 263 264

        Component.onCompleted: {
            allAlbumsProxyModel.setAudioControl(manageAudioPlayer)
            allArtistsProxyModel.setAudioControl(manageAudioPlayer)
            allTracksProxyModel.setAudioControl(manageAudioPlayer)
            singleAlbumProxyModel.setAudioControl(manageAudioPlayer)
            singleArtistProxyModel.setAudioControl(manageAudioPlayer)
        }
265 266 267 268 269 270
    }

    ManageMediaPlayerControl {
        id: myPlayControlManager

        playListModel: playListModelItem
271
        currentTrack: playListModelItem.currentTrack
272 273
    }

274 275 276 277 278
    Menu {
        id: applicationMenu
        title: i18nc("open application menu", "Application Menu")


Diego Gangl's avatar
Diego Gangl committed
279 280 281 282 283 284
        MenuItem {
            text: configureAction.text
            shortcut: configureAction.shortcut
            iconName: 'configure'
            onTriggered: configureAction.trigger()
            visible: configureAction.text !== ""
285 286 287
        }

        MenuItem {
Diego Gangl's avatar
Diego Gangl committed
288 289 290 291 292
            text: configureShortcutsAction.text
            shortcut: configureShortcutsAction.shortcut
            iconName: elisa.iconName(configureShortcutsAction.icon)
            onTriggered: configureShortcutsAction.trigger()
            visible: configureShortcutsAction.text !== ""
293 294 295
        }

        MenuSeparator {
Diego Gangl's avatar
Diego Gangl committed
296
            visible: reportBugAction.text !== ""
297 298 299 300 301 302 303
        }

        MenuItem {
            text: reportBugAction.text
            shortcut: reportBugAction.shortcut
            iconName: elisa.iconName(reportBugAction.icon)
            onTriggered: reportBugAction.trigger()
304
            visible: reportBugAction.text !== ""
305 306 307
        }

        MenuSeparator {
Diego Gangl's avatar
Diego Gangl committed
308
            visible: helpAction.text !== ""
309 310
        }

311
        MenuItem {
Diego Gangl's avatar
Diego Gangl committed
312 313 314 315 316
            text: helpAction.text
            shortcut: helpAction.shortcut
            iconName: elisa.iconName(helpAction.icon)
            onTriggered: helpAction.trigger()
            visible: helpAction.text !== ""
317 318
        }

319
        MenuItem {
Diego Gangl's avatar
Diego Gangl committed
320 321 322 323 324
            text: aboutAppAction.text
            shortcut: aboutAppAction.shortcut
            iconName: elisa.iconName(aboutAppAction.icon)
            onTriggered: aboutAppAction.trigger()
            visible: aboutAppAction.text !== ""
325 326 327
        }

        MenuSeparator {
Diego Gangl's avatar
Diego Gangl committed
328
            visible: qmlQuitAction.text !== ""
329 330 331
        }

        MenuItem {
Diego Gangl's avatar
Diego Gangl committed
332 333
            action: qmlQuitAction
            visible: qmlQuitAction.text !== ""
334
        }
Diego Gangl's avatar
Diego Gangl committed
335

336 337 338 339 340 341 342 343 344
    }

    Action {
        id: applicationMenuAction
        text: i18nc("open application menu", "Application Menu")
        iconName: "application-menu"
        onTriggered: applicationMenu.popup()
    }

345 346 347 348
    PassiveNotification {
        id: messageNotification
    }

349
    Rectangle {
350
        color: myPalette.base
351 352
        anchors.fill: parent

353 354 355
        ColumnLayout {
            anchors.fill: parent
            spacing: 0
356

357 358 359 360
            Item {
                Layout.preferredHeight: mainWindow.height * 0.2 + elisaTheme.mediaPlayerControlHeight
                Layout.minimumHeight: mainWindow.height * 0.2 + elisaTheme.mediaPlayerControlHeight
                Layout.maximumHeight: mainWindow.height * 0.2 + elisaTheme.mediaPlayerControlHeight
361
                Layout.fillWidth: true
362

363 364
                HeaderBar {
                    id: headerBar
365

366 367
                    focus: true

368
                    anchors.fill: parent
369

370 371 372 373 374
                    tracksCount: myHeaderBarManager.remainingTracks
                    album: myHeaderBarManager.album
                    title: myHeaderBarManager.title
                    artist: myHeaderBarManager.artist
                    image: myHeaderBarManager.image
375

376
                    ratingVisible: false
377

378 379
                    playerControl.duration: audioPlayer.duration
                    playerControl.seekable: audioPlayer.seekable
380

381 382 383 384 385 386 387
                    playerControl.volume: persistentSettings.playControlItemVolume
                    playerControl.muted: persistentSettings.playControlItemMuted
                    playerControl.position: audioPlayer.position
                    playerControl.skipBackwardEnabled: myPlayControlManager.skipBackwardControlEnabled
                    playerControl.skipForwardEnabled: myPlayControlManager.skipForwardControlEnabled
                    playerControl.playEnabled: myPlayControlManager.playControlEnabled
                    playerControl.isPlaying: myPlayControlManager.musicPlaying
388

389
                    playerControl.onSeek: audioPlayer.seek(position)
390

391 392
                    playerControl.onPlay: manageAudioPlayer.playPause()
                    playerControl.onPause: manageAudioPlayer.playPause()
393

394 395
                    playerControl.onPlayPrevious: playListModelItem.skipPreviousTrack()
                    playerControl.onPlayNext: playListModelItem.skipNextTrack()
396

397 398
                    ToolButton {
                        id: menuButton
399

400
                        action: applicationMenuAction
401

402
                        z: 2
403

404 405 406 407 408 409 410 411 412 413
                        anchors
                        {
                            right: parent.right
                            top: parent.top
                            rightMargin: elisaTheme.layoutHorizontalMargin * 3
                            topMargin: elisaTheme.layoutHorizontalMargin * 3
                        }
                    }
                    Rectangle {
                        anchors.fill: menuButton
414

415
                        z: 1
416

417
                        radius: width / 2
418

419 420
                        color: myPalette.window
                    }
421

422
                    TrackImportNotification {
423 424 425 426 427 428 429 430 431 432
                        id: importedTracksCountNotification

                        anchors
                        {
                            right: menuButton.left
                            top: menuButton.top
                            bottom: menuButton.bottom
                            rightMargin: elisaTheme.layoutHorizontalMargin * 3
                        }

433 434
                        indexingRunning: allListeners.indexingRunning
                        importedTracksCount: allListeners.importedTracksCount
435
                        musicManager: allListeners
436
                    }
437
                }
438
            }
439

440
            RowLayout {
441
                Layout.fillHeight: true
442 443
                Layout.fillWidth: true
                spacing: 0
444

445 446
                ViewSelector {
                    id: listViews
447

448
                    Layout.fillHeight: true
449 450
                    Layout.preferredWidth: mainWindow.width * 0.15
                    Layout.maximumWidth: mainWindow.width * 0.15
451 452
                }

453
                ColumnLayout {
454 455
                    Layout.fillHeight: true
                    Layout.fillWidth: true
456

457
                    spacing: 0
458

459
                    TopNotification {
460
                        id: invalidBalooConfiguration
461

462
                        Layout.fillWidth: true
463

464 465
                        musicManager: allListeners

466
                        focus: true
467 468 469 470 471 472 473 474 475 476 477 478 479
                    }

                    Item {
                        Layout.fillHeight: true
                        Layout.fillWidth: true

                        RowLayout {
                            anchors.fill: parent

                            spacing: 0

                            id: contentZone

480
                            FocusScope {
481 482
                                id: mainContentView

483
                                focus: true
484 485 486 487 488 489 490

                                Layout.fillHeight: true

                                Layout.minimumWidth: 0
                                Layout.maximumWidth: 0
                                Layout.preferredWidth: 0

Matthieu Gallien's avatar
Matthieu Gallien committed
491

492 493
                                visible: Layout.minimumWidth != 0

494 495 496 497 498 499 500 501
                                Rectangle {
                                    border {
                                        color: (mainContentView.activeFocus ? myPalette.highlight : myPalette.base)
                                        width: 1
                                    }

                                    radius: 3
                                    color: myPalette.base
502

503
                                    anchors.fill: parent
504

505 506
                                    BusyIndicator {
                                        id: busyScanningMusic
507

508
                                        anchors.fill: parent
509

510 511 512 513
                                        anchors.leftMargin: parent.width / 3
                                        anchors.rightMargin: parent.width / 3
                                        anchors.topMargin: parent.height / 3
                                        anchors.bottomMargin: parent.height / 3
514

515
                                        opacity: 0.8
516

517
                                        z: 2
518

519
                                        running: allListeners.indexerBusy
520 521 522 523 524 525 526 527 528 529 530 531 532 533
                                    }

                                    MediaBrowser {
                                        id: localAlbums

                                        focus: true

                                        anchors {
                                            fill: parent

                                            leftMargin: elisaTheme.layoutHorizontalMargin
                                            rightMargin: elisaTheme.layoutHorizontalMargin
                                        }

534 535 536
                                        firstPage: GridBrowserView {
                                            id: allAlbumsView

537 538
                                            tempMediaPlayList: playListModelItem
                                            tempMediaControl: manageAudioPlayer
539

540
                                            focus: true
541

542
                                            model: allAlbumsProxyModel
543

544
                                            image: elisaTheme.albumIcon
545 546 547
                                            mainTitle: i18nc("Title of the view of all albums", "Albums")

                                            onEnqueue: playListModelItem.enqueue(data)
548
                                            onReplaceAndPlay: {
549 550 551 552
                                                playListModelItem.clearAndEnqueue(data)
                                                manageAudioPlayer.ensurePlay()
                                            }
                                            onOpen: {
553
                                                singleAlbumProxyModel.sourceModel.loadAlbumData(databaseId)
554 555 556
                                                localAlbums.stackView.push(albumView, {
                                                                               stackView: localAlbums.stackView,
                                                                               albumName: innerMainTitle,
557
                                                                               artistName:  innerSecondaryTitle,
558 559 560 561
                                                                               albumArtUrl: innerImage,
                                                                           })
                                            }
                                            onGoBack: localAlbums.stackView.pop()
562
                                        }
563

564
                                        visible: opacity > 0
565
                                    }
566

567 568
                                    MediaBrowser {
                                        id: localArtists
569

570
                                        focus: true
571

572 573 574 575 576 577
                                        anchors {
                                            fill: parent

                                            leftMargin: elisaTheme.layoutHorizontalMargin
                                            rightMargin: elisaTheme.layoutHorizontalMargin
                                        }
578

579
                                        firstPage: GridBrowserView {
580
                                            id: allArtistsView
581
                                            focus: true
582 583
                                            tempMediaPlayList: playListModelItem
                                            tempMediaControl: manageAudioPlayer
584 585 586 587

                                            showRating: false
                                            delegateDisplaySecondaryText: false

588
                                            model: allArtistsProxyModel
589

590
                                            image: elisaTheme.artistIcon
591 592 593
                                            mainTitle: i18nc("Title of the view of all artists", "Artists")

                                            onEnqueue: playListModelItem.enqueue(data)
594
                                            onReplaceAndPlay: {
595 596 597 598
                                                playListModelItem.clearAndEnqueue(data)
                                                manageAudioPlayer.ensurePlay()
                                            }
                                            onOpen: {
599
                                                singleArtistProxyModel.setArtistFilterText(innerMainTitle)
600 601 602 603 604 605
                                                localArtists.stackView.push(innerAlbumView, {
                                                                                mainTitle: innerMainTitle,
                                                                                secondaryTitle: innerSecondaryTitle,
                                                                                image: innerImage,
                                                                                stackView: localArtists.stackView
                                                                            })
606

607 608
                                            }
                                            onGoBack: localArtists.stackView.pop()
609 610 611
                                        }

                                        visible: opacity > 0
612
                                    }
613

614 615
                                    MediaBrowser {
                                        id: localTracks
616

617
                                        focus: true
618

619 620 621 622 623 624
                                        anchors {
                                            fill: parent

                                            leftMargin: elisaTheme.layoutHorizontalMargin
                                            rightMargin: elisaTheme.layoutHorizontalMargin
                                        }
625

626
                                        firstPage: MediaAllTracksView {
627
                                            focus: true
628 629
                                            tempMediaPlayList: playListModelItem
                                            tempMediaControl: manageAudioPlayer
630
                                            stackView: localTracks.stackView
631 632

                                            model: allTracksProxyModel
633 634 635 636 637 638

                                            onEnqueue: playListModelItem.enqueue(data)
                                            onReplaceAndPlay: {
                                                playListModelItem.clearAndEnqueue(data)
                                                manageAudioPlayer.ensurePlay()
                                            }
639 640 641
                                        }

                                        visible: opacity > 0
642 643
                                    }

644 645 646 647 648
                                    Behavior on border.color {
                                        ColorAnimation {
                                            duration: 300
                                        }
                                    }
649
                                }
650
                            }
651

652 653
                            Rectangle {
                                id: firstViewSeparatorItem
654

655 656 657 658
                                border.width: 1
                                border.color: myPalette.mid
                                color: myPalette.mid
                                visible: true
659

660 661
                                Layout.bottomMargin: elisaTheme.layoutVerticalMargin
                                Layout.topMargin: elisaTheme.layoutVerticalMargin
662

663
                                Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
664

665
                                Layout.fillHeight: true
666

667 668 669 670
                                Layout.preferredWidth: 1
                                Layout.minimumWidth: 1
                                Layout.maximumWidth: 1
                            }
671

672 673
                            MediaPlayListView {
                                id: playList
674

675
                                playListModel: playListModelItem
676
                                playListControler: playListModelItem
677

678 679
                                randomPlayChecked: playListModelItem.randomPlay
                                repeatPlayChecked: playListModelItem.repeatPlay
680

681
                                Layout.fillHeight: true
682 683
                                Layout.leftMargin: elisaTheme.layoutHorizontalMargin
                                Layout.rightMargin: elisaTheme.layoutHorizontalMargin
684

685 686 687
                                Layout.minimumWidth: contentZone.width
                                Layout.maximumWidth: contentZone.width
                                Layout.preferredWidth: contentZone.width
688

689 690
                                Component.onCompleted:
                                {
691 692
                                    playListModelItem.randomPlay = Qt.binding(function() { return playList.randomPlayChecked })
                                    playListModelItem.repeatPlay = Qt.binding(function() { return playList.repeatPlayChecked })
693 694
                                    myPlayControlManager.randomOrContinuePlay = Qt.binding(function() { return playList.randomPlayChecked || playList.repeatPlayChecked })
                                }
695 696 697 698

                                onStartPlayback: manageAudioPlayer.ensurePlay()

                                onPausePlayback: manageAudioPlayer.playPause()
699 700

                                onDisplayError: messageNotification.showNotification(errorText)
701
                            }
702

703 704
                            Rectangle {
                                id: viewSeparatorItem
705

706 707 708 709
                                border.width: 1
                                border.color: myPalette.mid
                                color: myPalette.mid
                                visible: Layout.minimumWidth != 0
710

711 712
                                Layout.bottomMargin: elisaTheme.layoutVerticalMargin
                                Layout.topMargin: elisaTheme.layoutVerticalMargin
713

714
                                Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
715

716
                                Layout.fillHeight: true
717

718 719 720 721
                                Layout.preferredWidth: 1
                                Layout.minimumWidth: 1
                                Layout.maximumWidth: 1
                            }
722

723 724
                            ContextView {
                                id: albumContext
725

726
                                Layout.fillHeight: true
727

728 729 730
                                Layout.minimumWidth: contentZone.width
                                Layout.maximumWidth: contentZone.width
                                Layout.preferredWidth: contentZone.width
731

732
                                visible: Layout.minimumWidth != 0
733

734 735 736 737
                                artistName: myHeaderBarManager.artist
                                albumName: myHeaderBarManager.album
                                albumArtUrl: myHeaderBarManager.image
                            }
738 739
                        }
                    }
740 741

                    states: [
742 743
                        State {
                            name: 'full'
744
                            when: listViews.currentIndex === 0
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
                            PropertyChanges {
                                target: mainContentView
                                Layout.fillWidth: false
                                Layout.minimumWidth: 0
                                Layout.maximumWidth: 0
                                Layout.preferredWidth: 0
                            }
                            PropertyChanges {
                                target: firstViewSeparatorItem
                                Layout.minimumWidth: 0
                                Layout.maximumWidth: 0
                                Layout.preferredWidth: 0
                            }
                            PropertyChanges {
                                target: playList
                                Layout.minimumWidth: contentZone.width / 2
                                Layout.maximumWidth: contentZone.width / 2
                                Layout.preferredWidth: contentZone.width / 2
                            }
                            PropertyChanges {
                                target: viewSeparatorItem
                                Layout.minimumWidth: 1
                                Layout.maximumWidth: 1
                                Layout.preferredWidth: 1
                            }
                            PropertyChanges {
                                target: albumContext
                                Layout.minimumWidth: contentZone.width / 2
                                Layout.maximumWidth: contentZone.width / 2
                                Layout.preferredWidth: contentZone.width / 2
                            }
                            PropertyChanges {
                                target: localAlbums
                                opacity: 0
                            }
                            PropertyChanges {
                                target: localArtists
                                opacity: 0
                            }
                            PropertyChanges {
                                target: localTracks
                                opacity: 0
                            }
                        },
789
                        State {
790
                            name: 'allAlbums'
791
                            when: listViews.currentIndex === 1
792 793 794 795 796
                            StateChangeScript {
                                script: {
                                    localAlbums.stackView.pop({item: null, immediate: true})
                                }
                            }
797 798
                            PropertyChanges {
                                target: mainContentView
799
                                Layout.fillWidth: true
800 801 802
                                Layout.minimumWidth: contentZone.width * 0.66
                                Layout.maximumWidth: contentZone.width * 0.68
                                Layout.preferredWidth: contentZone.width * 0.68
803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827
                            }
                            PropertyChanges {
                                target: firstViewSeparatorItem
                                Layout.minimumWidth: 1
                                Layout.maximumWidth: 1
                                Layout.preferredWidth: 1
                            }
                            PropertyChanges {
                                target: playList
                                Layout.minimumWidth: contentZone.width * 0.33
                                Layout.maximumWidth: contentZone.width * 0.33
                                Layout.preferredWidth: contentZone.width * 0.33
                            }
                            PropertyChanges {
                                target: viewSeparatorItem
                                Layout.minimumWidth: 0
                                Layout.maximumWidth: 0
                                Layout.preferredWidth: 0
                            }
                            PropertyChanges {
                                target: albumContext
                                Layout.minimumWidth: 0
                                Layout.maximumWidth: 0
                                Layout.preferredWidth: 0
                            }
828 829 830 831 832 833 834 835
                            PropertyChanges {
                                target: localAlbums
                                opacity: 1
                            }
                            PropertyChanges {
                                target: localArtists
                                opacity: 0
                            }
836 837 838 839
                            PropertyChanges {
                                target: localTracks
                                opacity: 0
                            }
840 841 842
                        },
                        State {
                            name: 'allArtists'
843
                            when: listViews.currentIndex === 2
844 845 846 847 848
                            StateChangeScript {
                                script: {
                                    localArtists.stackView.pop({item: null, immediate: true})
                                }
                            }
849 850
                            PropertyChanges {
                                target: mainContentView
851
                                Layout.fillWidth: true
852 853 854
                                Layout.minimumWidth: contentZone.width * 0.66
                                Layout.maximumWidth: contentZone.width * 0.68
                                Layout.preferredWidth: contentZone.width * 0.68
855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887
                            }
                            PropertyChanges {
                                target: firstViewSeparatorItem
                                Layout.minimumWidth: 1
                                Layout.maximumWidth: 1
                                Layout.preferredWidth: 1
                            }
                            PropertyChanges {
                                target: playList
                                Layout.minimumWidth: contentZone.width * 0.33
                                Layout.maximumWidth: contentZone.width * 0.33
                                Layout.preferredWidth: contentZone.width * 0.33
                            }
                            PropertyChanges {
                                target: viewSeparatorItem
                                Layout.minimumWidth: 0
                                Layout.maximumWidth: 0
                                Layout.preferredWidth: 0
                            }
                            PropertyChanges {
                                target: albumContext
                                Layout.minimumWidth: 0
                                Layout.maximumWidth: 0
                                Layout.preferredWidth: 0
                            }
                            PropertyChanges {
                                target: localAlbums
                                opacity: 0
                            }
                            PropertyChanges {
                                target: localArtists
                                opacity: 1
                            }
888 889 890 891
                            PropertyChanges {
                                target: localTracks
                                opacity: 0
                            }
892 893
                        },
                        State {
894
                            name: 'allTracks'
895
                            when: listViews.currentIndex === 3
896 897
                            PropertyChanges {
                                target: mainContentView
898
                                Layout.fillWidth: true
899 900 901
                                Layout.minimumWidth: contentZone.width * 0.66
                                Layout.maximumWidth: contentZone.width * 0.68
                                Layout.preferredWidth: contentZone.width * 0.68
902 903 904
                            }
                            PropertyChanges {
                                target: firstViewSeparatorItem
905 906 907
                                Layout.minimumWidth: 1
                                Layout.maximumWidth: 1
                                Layout.preferredWidth: 1
908 909 910
                            }
                            PropertyChanges {
                                target: playList
911 912 913
                                Layout.minimumWidth: contentZone.width * 0.33
                                Layout.maximumWidth: contentZone.width * 0.33
                                Layout.preferredWidth: contentZone.width * 0.33
914 915 916
                            }
                            PropertyChanges {
                                target: viewSeparatorItem
917 918 919
                                Layout.minimumWidth: 0
                                Layout.maximumWidth: 0
                                Layout.preferredWidth: 0
920 921 922
                            }
                            PropertyChanges {
                                target: albumContext
923 924 925
                                Layout.minimumWidth: 0
                                Layout.maximumWidth: 0
                                Layout.preferredWidth: 0
926
                            }
927 928 929 930 931 932 933 934
                            PropertyChanges {
                                target: localAlbums
                                opacity: 0
                            }
                            PropertyChanges {
                                target: localArtists
                                opacity: 0
                            }
935 936 937 938
                            PropertyChanges {
                                target: localTracks
                                opacity: 1
                            }
939 940 941 942
                        }
                    ]
                    transitions: Transition {
                        NumberAnimation {
943
                            properties: "Layout.minimumWidth, Layout.maximumWidth, Layout.preferredWidth, opacity"
944 945 946
                            easing.type: Easing.InOutQuad
                            duration: 300
                        }