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 }