Warning, /multimedia/kasts/src/qml/Desktop/HeaderBar.qml is written in an unsupported language. File is not indexed.

0001 /**
0002  * SPDX-FileCopyrightText: 2021 Swapnil Tripathi <swapnil06.st@gmail.com>
0003  * SPDX-FileCopyrightText: 2021-2023 Bart De Vries <bart@mogwai.be>
0004  *
0005  * SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 import QtQuick
0009 import QtQuick.Controls as Controls
0010 import QtQuick.Layouts
0011 import QtQuick.Effects
0012 import QtQml.Models
0013 
0014 import org.kde.kirigami as Kirigami
0015 import org.kde.kmediasession
0016 
0017 import org.kde.kasts
0018 
0019 import ".."
0020 
0021 FocusScope {
0022     id: headerBar
0023     height: headerMetaData.implicitHeight + desktopPlayerControls.implicitHeight
0024 
0025     property int handlePosition: settings.headerSize
0026     property int maximumHeight: Kirigami.Units.gridUnit * 8
0027     property int minimumImageSize: Kirigami.Units.gridUnit * 1.5
0028     property int subtitleCollapseHeight: Kirigami.Units.gridUnit * 2.5
0029     property int authorCollapseHeight: Kirigami.Units.gridUnit * 4
0030     property int disappearHeight: Kirigami.Units.gridUnit * 1.0
0031 
0032     function openEntry() {
0033         if (AudioManager.entry) {
0034             pushPage("QueuePage");
0035             pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/EntryPage.qml", {"entry": AudioManager.entry});
0036             pageStack.get(0).lastEntry = AudioManager.entry.id;
0037             var model = pageStack.get(0).queueList.model;
0038             for (var i = 0; i <  model.rowCount(); i++) {
0039                 var index = model.index(i, 0);
0040                 if (AudioManager.entry == model.data(index, AbstractEpisodeModel.EntryRole)) {
0041                     pageStack.get(0).queueList.currentIndex = i;
0042                     pageStack.get(0).queueList.selectionModel.setCurrentIndex(index, ItemSelectionModel.ClearAndSelect | ItemSelectionModel.Rows);
0043 
0044                 }
0045             }
0046         }
0047     }
0048 
0049     function openFeed() {
0050         if (AudioManager.entry) {
0051             pushPage("FeedListPage");
0052             pageStack.push("qrc:/qt/qml/org/kde/kasts/qml/FeedDetailsPage.qml", {"feed": AudioManager.entry.feed});
0053         }
0054     }
0055 
0056     function openFullScreenImage() {
0057         var options = {
0058             "image": Qt.binding(function() { return headerMetaData.image }),
0059             "description": Qt.binding(function() { return headerMetaData.title }),
0060             "loader": Qt.binding(function() { return fullScreenImageLoader})
0061         };
0062         fullScreenImageLoader.setSource("qrc:/qt/qml/org/kde/kasts/qml/FullScreenImage.qml", options);
0063         fullScreenImageLoader.active = true;
0064         fullScreenImageLoader.item.open();
0065     }
0066 
0067     Rectangle {
0068         //set background color
0069         anchors.fill: parent
0070         Kirigami.Theme.inherit: false
0071         Kirigami.Theme.colorSet: Kirigami.Theme.Header
0072         color: Kirigami.Theme.backgroundColor
0073     }
0074 
0075     Loader {
0076         id: backgroundImageLoader
0077         active: handlePosition > 0
0078         anchors.fill: parent
0079         sourceComponent: backgroundImageComponent
0080     }
0081 
0082     Component {
0083         id: backgroundImageComponent
0084         MultiEffect {
0085             source: backgroundImage
0086             anchors.fill: parent
0087 
0088             brightness: -0.3
0089             saturation: 0.6
0090             contrast: -0.5
0091             blurMax: 64
0092             blur: 1.0
0093             blurEnabled: true
0094             autoPaddingEnabled: false
0095 
0096             ImageWithFallback {
0097                 id: backgroundImage
0098 
0099                 visible: false
0100                 imageSource: headerMetaData.blurredImage
0101                 imageResize: false // no "stuttering" on resizing the window
0102                 anchors.fill: parent
0103             }
0104         }
0105     }
0106 
0107     Item {
0108         id: headerMetaData
0109         anchors.top: parent.top
0110         anchors.left: parent.left
0111         anchors.right: parent.right
0112 
0113         opacity: height - headerBar.disappearHeight > Kirigami.Units.largeSpacing ? 1 : (height - headerBar.disappearHeight < 0 ? 0 : (height - headerBar.disappearHeight) / Kirigami.Units.largeSpacing)
0114 
0115         visible: opacity === 0 ? false : true
0116 
0117         property string image: AudioManager.entry ? ((desktopPlayerControls.chapterModel.currentChapter && desktopPlayerControls.chapterModel.currentChapter !== undefined) ? desktopPlayerControls.chapterModel.currentChapter.cachedImage : AudioManager.entry.cachedImage) : "no-image"
0118         property string blurredImage: AudioManager.entry ? AudioManager.entry.cachedImage : "no-image"
0119         property string title: AudioManager.entry ? AudioManager.entry.title : i18n("No Track Title")
0120         property string feed: AudioManager.entry ? AudioManager.entry.feed.name : i18n("No track loaded")
0121         property string authors: AudioManager.entry ? AudioManager.entry.feed.authors : ""
0122 
0123         implicitHeight: headerBar.handlePosition
0124         implicitWidth: parent.width
0125 
0126         RowLayout {
0127             property int margin: Kirigami.Units.gridUnit * 1
0128             anchors.fill: parent
0129             anchors.margins: margin
0130             anchors.topMargin: parent.height > headerBar.minimumImageSize + 2 * margin ? margin : (parent.height - headerBar.minimumImageSize) / 2
0131             anchors.bottomMargin: parent.height > headerBar.minimumImageSize + 2 * margin ? margin : (parent.height - headerBar.minimumImageSize) / 2
0132 
0133             ImageWithFallback {
0134                 id: frontImage
0135                 imageSource: headerMetaData.image
0136                 Layout.fillHeight: true
0137                 Layout.preferredWidth: height
0138                 Layout.minimumHeight: Kirigami.Units.gridUnit * 1.5
0139                 absoluteRadius: Kirigami.Units.smallSpacing
0140                 imageResize: false
0141                 mipmap: true
0142                 MouseArea {
0143                     anchors.fill: parent
0144                     cursorShape: Qt.PointingHandCursor
0145                     onClicked: {
0146                         openFullScreenImage();
0147                     }
0148                 }
0149             }
0150 
0151             ColumnLayout {
0152                 id: labelLayout
0153                 Layout.fillWidth: true
0154                 Layout.fillHeight: true
0155                 Layout.leftMargin: parent.margin / 2
0156 
0157                 Controls.Label {
0158                     Layout.fillHeight: true
0159                     Layout.fillWidth: true
0160                     text: headerMetaData.title
0161                     fontSizeMode: Text.Fit
0162                     font.pointSize: Math.round(Kirigami.Theme.defaultFont.pointSize * 1.4)
0163                     minimumPointSize: Math.round(Kirigami.Theme.defaultFont.pointSize * 1.1)
0164                     horizontalAlignment: Text.AlignLeft
0165                     verticalAlignment: Text.AlignBottom
0166                     color: "#eff0f1" // breeze light text color
0167                     opacity: 1
0168                     elide: Text.ElideRight
0169                     wrapMode: Text.WordWrap
0170                     MouseArea {
0171                         anchors.fill: parent
0172                         cursorShape: Qt.PointingHandCursor
0173                         onClicked: {
0174                             openEntry();
0175                         }
0176                     }
0177                 }
0178 
0179                 Controls.Label {
0180                     visible: labelLayout.height > headerBar.subtitleCollapseHeight
0181                     Layout.fillWidth: true
0182                     text: headerMetaData.feed
0183                     fontSizeMode: Text.Fit
0184                     font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1.1
0185                     minimumPointSize: Kirigami.Theme.defaultFont.pointSize
0186                     horizontalAlignment: Text.AlignLeft
0187                     color: "#eff0f1" // breeze light text color
0188                     elide: Text.ElideRight
0189                     opacity: 1
0190                     MouseArea {
0191                         anchors.fill: parent
0192                         cursorShape: Qt.PointingHandCursor
0193                         onClicked: {
0194                             openFeed();
0195                         }
0196                     }
0197                 }
0198 
0199                 Controls.Label {
0200                     visible: (headerMetaData.authors) && labelLayout.height > headerBar.authorCollapseHeight
0201                     Layout.fillWidth: true
0202                     text: headerMetaData.authors
0203                     fontSizeMode: Text.Fit
0204                     font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1.1
0205                     minimumPointSize: Kirigami.Theme.defaultFont.pointSize
0206                     horizontalAlignment: Text.AlignLeft
0207                     color: "#eff0f1" // breeze light text color
0208                     elide: Text.ElideRight
0209                     opacity: 1
0210                     MouseArea {
0211                         anchors.fill: parent
0212                         cursorShape: Qt.PointingHandCursor
0213                         onClicked: {
0214                             openFeed();
0215                         }
0216                     }
0217                 }
0218             }
0219         }
0220     }
0221 
0222     DesktopPlayerControls {
0223         id: desktopPlayerControls
0224 
0225         anchors.top: headerMetaData.bottom
0226         anchors.bottom: parent.bottom
0227         anchors.left: parent.left
0228         anchors.right: parent.right
0229 
0230         onHandlePositionChanged: (y, offset) => {
0231             handlePosition = Math.max(0, Math.min(headerBar.maximumHeight, headerBar.height - implicitHeight - offset + y));
0232             settings.headerSize = handlePosition;
0233         }
0234     }
0235 
0236     Kirigami.Separator {
0237         width: parent.width
0238         anchors.bottom: parent.bottom
0239     }
0240 }