mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-07-26 22:34:45 +00:00
The eventual goal is to have as few singletons with state as possible in the mobileshell component when it is imported into components such as the lockscreen. This doesn't fully accomplish it, but moves the audio provider singleton to MobileShellState, which will eventually need to be prevented from importing into non plasmashell processes. This also disables the sound feedback when changing volume, since it can be a source of lag when showing the applet.
228 lines
9.2 KiB
QML
228 lines
9.2 KiB
QML
/*
|
|
* SPDX-FileCopyrightText: 2014 Martin Klapetek <mklapetek@kde.org>
|
|
* SPDX-FileCopyrightText: 2019 Kai Uwe Broulik <kde@broulik.de>
|
|
* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
import QtQuick
|
|
import QtQuick.Controls as Controls
|
|
import QtQuick.Layouts
|
|
import QtQuick.Window
|
|
import Qt5Compat.GraphicalEffects
|
|
|
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
|
import org.kde.plasma.extras 2.0 as PlasmaExtra
|
|
import org.kde.plasma.components 3.0 as PlasmaComponents
|
|
import org.kde.plasma.extras 2.0 as PlasmaExtra
|
|
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
|
|
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
|
import org.kde.plasma.private.mobileshell.state 1.0 as MobileShellState
|
|
|
|
import org.kde.kirigami as Kirigami
|
|
|
|
Window {
|
|
id: window
|
|
|
|
required property int volume
|
|
|
|
// used by context menus opened in the applet to not autoclose the osd
|
|
property bool suppressActiveClose: false
|
|
|
|
// whether the applet is showing all devices
|
|
property bool showFullApplet: false
|
|
|
|
visible: false
|
|
|
|
color: showFullApplet ? Qt.rgba(0, 0, 0, 0.6) : "transparent"
|
|
Behavior on color {
|
|
ColorAnimation {}
|
|
}
|
|
|
|
function showOverlay() {
|
|
if (!window.visible) {
|
|
window.showFullApplet = false;
|
|
window.showFullScreen();
|
|
hideTimer.restart();
|
|
} else if (!window.showFullApplet) { // don't autohide applet when the full applet is showing
|
|
hideTimer.restart();
|
|
}
|
|
}
|
|
|
|
onActiveChanged: {
|
|
if (!active && !suppressActiveClose) {
|
|
hideTimer.stop();
|
|
hideTimer.triggered();
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: hideTimer
|
|
interval: 3000
|
|
running: false
|
|
onTriggered: {
|
|
window.close();
|
|
window.showFullApplet = false;
|
|
}
|
|
}
|
|
|
|
MobileShell.AudioInfo {
|
|
id: audioInfo
|
|
}
|
|
|
|
Flickable {
|
|
id: flickable
|
|
anchors.fill: parent
|
|
contentHeight: cards.implicitHeight
|
|
boundsBehavior: window.showFullApplet ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds
|
|
|
|
pressDelay: 50
|
|
|
|
MouseArea {
|
|
// capture taps behind cards to close
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
width: parent.width
|
|
height: Math.max(cards.implicitHeight, window.height)
|
|
onReleased: {
|
|
hideTimer.stop();
|
|
hideTimer.triggered();
|
|
}
|
|
|
|
ColumnLayout {
|
|
id: cards
|
|
width: parent.width
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
spacing: 0
|
|
|
|
// osd card
|
|
PopupCard {
|
|
id: osd
|
|
Layout.topMargin: PlasmaCore.Units.largeSpacing
|
|
Layout.alignment: Qt.AlignHCenter
|
|
|
|
contentItem: RowLayout {
|
|
id: containerLayout
|
|
spacing: PlasmaCore.Units.smallSpacing
|
|
|
|
anchors.leftMargin: PlasmaCore.Units.smallSpacing * 2
|
|
anchors.rightMargin: PlasmaCore.Units.smallSpacing
|
|
|
|
PlasmaComponents.ToolButton {
|
|
icon.name: !audioInfo.paSinkModel.preferredSink || audioInfo.paSinkModel.preferredSink.muted ? "audio-volume-muted" : "audio-volume-high"
|
|
text: !audioInfo.paSinkModel.preferredSink || audioInfo.paSinkModel.preferredSink.muted ? i18n("Unmute") : i18n("Mute")
|
|
display: Controls.AbstractButton.IconOnly
|
|
Layout.alignment: Qt.AlignVCenter
|
|
Layout.preferredWidth: PlasmaCore.Units.iconSizes.medium
|
|
Layout.preferredHeight: PlasmaCore.Units.iconSizes.medium
|
|
Layout.rightMargin: PlasmaCore.Units.smallSpacing
|
|
onClicked: muteVolume()
|
|
}
|
|
|
|
PlasmaComponents.ProgressBar {
|
|
id: volumeSlider
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignVCenter
|
|
Layout.rightMargin: PlasmaCore.Units.smallSpacing * 2
|
|
value: window.volume
|
|
from: 0
|
|
to: 100
|
|
Behavior on value { NumberAnimation { duration: PlasmaCore.Units.shortDuration } }
|
|
}
|
|
|
|
// Get the width of a three-digit number so we can size the label
|
|
// to the maximum width to avoid the progress bar resizing itself
|
|
TextMetrics {
|
|
id: widestLabelSize
|
|
text: i18n("100%")
|
|
font: percentageLabel.font
|
|
}
|
|
|
|
PlasmaExtra.Heading {
|
|
id: percentageLabel
|
|
Layout.preferredWidth: widestLabelSize.width
|
|
Layout.alignment: Qt.AlignVCenter
|
|
Layout.rightMargin: PlasmaCore.Units.smallSpacing
|
|
level: 3
|
|
text: i18nc("Percentage value", "%1%", window.volume)
|
|
|
|
// Display a subtle visual indication that the volume might be
|
|
// dangerously high
|
|
// ------------------------------------------------
|
|
// Keep this in sync with the copies in plasma-pa:ListItemBase.qml
|
|
// and plasma-pa:VolumeSlider.qml
|
|
color: {
|
|
if (volumeSlider.value <= 100) {
|
|
return PlasmaCore.Theme.textColor
|
|
} else if (volumeSlider.value > 100 && volumeSlider.value <= 125) {
|
|
return PlasmaCore.Theme.neutralTextColor
|
|
} else {
|
|
return PlasmaCore.Theme.negativeTextColor
|
|
}
|
|
}
|
|
}
|
|
|
|
PlasmaComponents.ToolButton {
|
|
icon.name: "configure"
|
|
text: i18n("Open audio settings")
|
|
visible: opacity !== 0
|
|
opacity: showFullApplet ? 1 : 0
|
|
display: Controls.AbstractButton.IconOnly
|
|
Layout.alignment: Qt.AlignVCenter
|
|
Layout.preferredWidth: PlasmaCore.Units.iconSizes.medium
|
|
Layout.preferredHeight: PlasmaCore.Units.iconSizes.medium
|
|
Layout.rightMargin: PlasmaCore.Units.smallSpacing
|
|
|
|
Behavior on opacity { NumberAnimation { duration: PlasmaCore.Units.shortDuration } }
|
|
|
|
onClicked: {
|
|
let coords = mapToItem(flickable, 0, 0);
|
|
MobileShellState.Shell.openAppLaunchAnimation("audio-volume-high", i18n("Audio Settings"), coords.x, coords.y, PlasmaCore.Units.iconSizes.medium);
|
|
MobileShell.ShellUtil.executeCommand("plasma-open-settings kcm_pulseaudio");
|
|
}
|
|
}
|
|
|
|
PlasmaComponents.ToolButton {
|
|
icon.name: window.showFullApplet ? "arrow-up" : "arrow-down"
|
|
text: i18n("Toggle showing audio streams")
|
|
display: Controls.AbstractButton.IconOnly
|
|
Layout.alignment: Qt.AlignVCenter
|
|
Layout.preferredWidth: PlasmaCore.Units.iconSizes.medium
|
|
Layout.preferredHeight: PlasmaCore.Units.iconSizes.medium
|
|
onClicked: {
|
|
window.showFullApplet = !window.showFullApplet
|
|
// don't autohide applet when full applet is shown
|
|
if (window.showFullApplet) {
|
|
hideTimer.stop();
|
|
} else {
|
|
hideTimer.restart();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// other applet cards
|
|
AudioApplet {
|
|
id: applet
|
|
Layout.topMargin: PlasmaCore.Units.largeSpacing
|
|
Layout.alignment: Qt.AlignHCenter
|
|
Layout.preferredWidth: cards.width
|
|
|
|
audioInfo: audioInfo
|
|
|
|
opacity: window.showFullApplet ? 1 : 0
|
|
visible: opacity !== 0
|
|
transform: Translate {
|
|
y: window.showFullApplet ? 0 : -PlasmaCore.Units.gridUnit
|
|
Behavior on y { NumberAnimation {} }
|
|
}
|
|
|
|
Behavior on opacity { NumberAnimation {} }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|