You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
latte-dock/plasmoid/contents/ui/ToolTipDelegate.qml

439 lines
16 KiB
QML

/*
* Copyright 2013 by Sebastian Kügler <sebas@kde.org>
* Copyright 2014 by Martin Gräßlin <mgraesslin@kde.org>
* Copyright 2016 by Kai Uwe Broulik <kde@privat.broulik.de>
*
* This program 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 2, or
* (at your option) any later version.
*
* This program 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 program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 2.010-1301, USA.
*/
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons
//Column {
MouseArea{
id: tooltipContentItem
hoverEnabled: true
property Item toolTip
property var parentIndex
property var titles
property var windows
property string mainText
property string subText
property variant icon
property url launcherUrl
property bool group: windows ? (windows.length > 1) : false
readonly property int thumbnailWidth: units.gridUnit * 15
readonly property int thumbnailHeight: units.gridUnit * 10
property int preferredTextWidth: theme.mSize(theme.defaultFont).width * 30
property int _s: units.largeSpacing / 2
Layout.minimumWidth: Math.max(thumbnailWidth, windowRow.width, appLabelRow.width) + _s
Layout.minimumHeight: childrenRect.height
Layout.maximumWidth: Layout.minimumWidth
Layout.maximumHeight: Layout.minimumHeight
onContainsMouseChanged: {
checkMouseInside();
}
function checkMouseInside(){
var isInside = containsMouse || windowRow.containsMouse();
if (isInside){
toolTipDelegate.currentItem = parentIndex;
}
else{
toolTipDelegate.currentItem = -1;
checkListHovered.restart();
}
}
states: State {
when: mpris2Source.hasPlayer
PropertyChanges {
target: thumbnailSourceItem
opacity: 0 // cannot set visible to false or else WindowThumbnail won't provide thumbnail
}
PropertyChanges {
target: playerControlsOpacityMask
visible: true
source: thumbnailSourceItem
maskSource: playerControlsShadowMask
}
PropertyChanges {
target: playerControlsRow
visible: mpris2Source.hasPlayer
}
}
PlasmaCore.DataSource {
id: mpris2Source
readonly property string current: {
var desktopFileName = launcherUrl.toString().split('/').pop().replace(".desktop", "")
for (var i = 0, length = sources.length; i < length; ++i) {
var source = sources[i];
var sourceData = data[source];
if (sourceData && sourceData.DesktopEntry === desktopFileName) {
return source
}
}
return ""
}
readonly property bool hasPlayer: !!current
readonly property bool playing: hasPlayer && data[current].PlaybackStatus === "Playing"
readonly property bool canControl: hasPlayer && data[current].CanControl
readonly property bool canGoBack: hasPlayer && data[current].CanGoPrevious
readonly property bool canGoNext: hasPlayer && data[current].CanGoNext
readonly property bool canRaise: hasPlayer && data[current].CanRaise
readonly property var currentMetadata: hasPlayer ? data[current].Metadata : ({})
readonly property string track: {
var xesamTitle = currentMetadata["xesam:title"]
if (xesamTitle) {
return xesamTitle
}
// if no track title is given, print out the file name
var xesamUrl = currentMetadata["xesam:url"] ? currentMetadata["xesam:url"].toString() : ""
if (!xesamUrl) {
return ""
}
var lastSlashPos = xesamUrl.lastIndexOf('/')
if (lastSlashPos < 0) {
return ""
}
var lastUrlPart = xesamUrl.substring(lastSlashPos + 1)
return decodeURIComponent(lastUrlPart)
}
readonly property string artist: currentMetadata["xesam:artist"] || ""
readonly property string albumArt: currentMetadata["mpris:artUrl"] || ""
function goPrevious() {
startOperation("Previous")
}
function goNext() {
startOperation("Next")
}
function playPause() {
startOperation("PlayPause")
}
function raise() {
startOperation("Raise")
}
function startOperation(op) {
var service = mpris2Source.serviceForSource(current)
var operation = service.operationDescription(op)
return service.startOperationCall(operation)
}
engine: "mpris2"
connectedSources: sources
}
Column{
spacing: _s
Item {
id: thumbnailContainer
width: Math.max(tooltipContentItem.width, windowRow.width)
height: albumArtImage.available ? albumArtImage.height :
raisePlayerArea.visible ? raisePlayerArea.height :
windowRow.height
Item {
id: thumbnailSourceItem
anchors.fill: parent
PlasmaExtras.ScrollArea {
id: scrollArea
anchors.horizontalCenter: parent.horizontalCenter
width: Math.max(windowRow.width, thumbnailWidth)
height: parent.height
visible: !albumArtImage.available
verticalScrollBarPolicy: Qt.ScrollBarAlwaysOff
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
Component.onCompleted: {
flickableItem.interactive = Qt.binding(function() {
return contentItem.width > viewport.width;
});
}
Row {
id: windowRow
width: childrenRect.width
height: childrenRect.height
spacing: units.largeSpacing
Repeater {
model: (plasmoid.configuration.showToolTips && !albumArtImage.available)
|| !windowSystem.compositingActive ? windows : null
Column{
PlasmaCore.WindowThumbnail {
id: windowThumbnail
width: thumbnailWidth
height: thumbnailHeight
winId: modelData
ToolTipWindowMouseArea {
anchors.fill: parent
modelIndex: tasksModel.makeModelIndex(parentIndex, group ? index : -1)
winId: modelData
thumbnailItem: parent
}
}
PlasmaComponents.Label{
text: titles && titles[index] ? titles[index] : ""
wrapMode: Text.Wrap
font.italic: true
elide: Text.ElideRight
opacity: 0.7
textFormat: Text.PlainText
verticalAlignment: Text.AlignVCenter
width: thumbnailWidth
}
}
}
function containsMouse(){
for(var i=0; i<children.length-1; ++i){
if(children[i].children[0].containsMouse)
return true;
}
return false;
}
}
}
Image {
id: albumArtImage
// also Image.Loading to prevent loading thumbnails just because the album art takes a split second to load
readonly property bool available: status === Image.Ready || status === Image.Loading
anchors.centerIn: parent
width: parent.width
height: thumbnailHeight
sourceSize: Qt.size(thumbnailWidth, thumbnailHeight)
asynchronous: true
source: mpris2Source.albumArt
fillMode: Image.PreserveAspectCrop
visible: available
ToolTipWindowMouseArea {
id: albumMouseArea
anchors.fill: parent
modelIndex: tasksModel.makeModelIndex(parentIndex)//, group ? (index ? index : -1) : -1)
winId: windows != undefined ? (windows[0] || 0) : 0
}
}
MouseArea {
id: raisePlayerArea
anchors.centerIn: parent
width: thumbnailWidth
height: thumbnailHeight
// if there's no window associated with this task, we might still be able to raise the player
visible: windows == undefined || !windows[0] && mpris2Source.canRaise
onClicked: mpris2Source.raise()
PlasmaCore.IconItem {
anchors.fill: parent
source: icon
animated: false
usesPlasmaTheme: false
visible: !albumArtImage.available
}
}
}
Item {
id: playerControlsShadowMask
anchors.fill: thumbnailSourceItem
visible: false // OpacityMask would render it
Rectangle {
width: parent.width
height: parent.height - playerControlsRow.height
}
Rectangle {
anchors.bottom: parent.bottom
width: parent.width
height: playerControlsRow.height
opacity: 0.2
}
}
OpacityMask {
id: playerControlsOpacityMask
anchors.fill: thumbnailSourceItem
visible: false
}
// prevent accidental click-through when a control is disabled
MouseArea {
anchors.fill: playerControlsRow
enabled: playerControlsRow.visible
}
RowLayout {
id: playerControlsRow
anchors {
horizontalCenter: parent.horizontalCenter
bottom: thumbnailSourceItem.bottom
}
width: thumbnailWidth
spacing: 0
enabled: mpris2Source.canControl
visible: false
ColumnLayout {
Layout.fillWidth: true
spacing: 0
PlasmaExtras.Heading {
Layout.fillWidth: true
level: 4
wrapMode: Text.NoWrap
elide: Text.ElideRight
text: mpris2Source.track || ""
}
PlasmaExtras.Heading {
Layout.fillWidth: true
level: 5
wrapMode: Text.NoWrap
elide: Text.ElideRight
text: mpris2Source.artist || ""
}
}
PlasmaComponents.ToolButton {
enabled: mpris2Source.canGoBack
iconName: "media-skip-backward"
tooltip: i18nc("Go to previous song", "Previous")
Accessible.name: tooltip
onClicked: mpris2Source.goPrevious()
}
PlasmaComponents.ToolButton {
Layout.fillHeight: true
Layout.preferredWidth: height // make this button bigger
iconName: mpris2Source.playing ? "media-playback-pause" : "media-playback-start"
tooltip: mpris2Source.playing ? i18nc("Pause player", "Pause") : i18nc("Start player", "Play")
Accessible.name: tooltip
onClicked: mpris2Source.playPause()
}
PlasmaComponents.ToolButton {
enabled: mpris2Source.canGoNext
iconName: "media-skip-forward"
tooltip: i18nc("Go to next song", "Next")
Accessible.name: tooltip
onClicked: mpris2Source.goNext()
}
}
}
Row {
id: appLabelRow
width: childrenRect.width + _s
height: childrenRect.height + units.largeSpacing
spacing: units.largeSpacing
Item {
id: imageContainer
width: tooltipIcon.width
height: tooltipIcon.height
y: _s
PlasmaCore.IconItem {
id: tooltipIcon
x: _s
width: units.iconSizes.desktop
height: width
animated: false
usesPlasmaTheme: false
source: icon
}
}
Column {
id: mainColumn
y: _s
//This instance is purely for metrics
PlasmaExtras.Heading {
id: tooltipMaintextPlaceholder
visible: false
level: 3
text: mainText
textFormat: Text.PlainText
}
PlasmaExtras.Heading {
id: tooltipMaintext
level: 3
width: Math.min(tooltipMaintextPlaceholder.width, preferredTextWidth)
//width: 400
elide: Text.ElideRight
text: mainText
textFormat: Text.PlainText
}
PlasmaComponents.Label {
id: tooltipSubtext
width: tooltipContentItem.preferredTextWidth
height: Math.min(theme.mSize(theme.defaultFont), contentHeight)
wrapMode: Text.WordWrap
text: subText
textFormat: Text.PlainText
opacity: 0.5
visible: text !== ""
}
}
}
}
}