mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-28 06:33:09 +00:00
Rework top panel and improve appearance
This commit is contained in:
parent
2154671058
commit
0ed2053e79
22 changed files with 1326 additions and 1056 deletions
|
|
@ -7,12 +7,16 @@
|
||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import QtQuick.Layouts 1.4
|
import QtQuick.Layouts 1.4
|
||||||
import QtQuick.Controls 2.4 as QQC2
|
import QtQuick.Controls 2.4 as QQC2
|
||||||
|
import QtGraphicalEffects 1.12
|
||||||
|
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
import org.kde.kirigami 2.12 as Kirigami
|
import org.kde.kirigami 2.12 as Kirigami
|
||||||
|
|
||||||
QQC2.Control {
|
QQC2.Control {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
required property color backgroundColor
|
||||||
|
|
||||||
leftPadding: units.largeSpacing
|
leftPadding: units.largeSpacing
|
||||||
topPadding: units.largeSpacing
|
topPadding: units.largeSpacing
|
||||||
rightPadding: units.largeSpacing
|
rightPadding: units.largeSpacing
|
||||||
|
|
@ -22,9 +26,15 @@ QQC2.Control {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
|
PlasmaCore.FrameSvgItem {
|
||||||
|
imagePath: "widgets/panel-background"
|
||||||
|
prefix: "shadow"
|
||||||
|
anchors.fill: container
|
||||||
|
anchors.margins: -PlasmaCore.Units.smallSpacing
|
||||||
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: container
|
id: container
|
||||||
color: Kirigami.ColorUtils.adjustColor(PlasmaCore.ColorScope.backgroundColor, {"alpha": 0.85*255})
|
color: backgroundColor
|
||||||
anchors {
|
anchors {
|
||||||
fill: parent
|
fill: parent
|
||||||
leftMargin: PlasmaCore.Units.smallSpacing
|
leftMargin: PlasmaCore.Units.smallSpacing
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import QtQuick 2.12
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import QtQml.Models 2.12
|
import QtQml.Models 2.12
|
||||||
|
|
||||||
|
import org.kde.kirigami 2.12 as Kirigami
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
|
||||||
DrawerBackground {
|
DrawerBackground {
|
||||||
|
|
@ -15,8 +16,12 @@ DrawerBackground {
|
||||||
property Item applet
|
property Item applet
|
||||||
property ObjectModel fullRepresentationModel
|
property ObjectModel fullRepresentationModel
|
||||||
property ListView fullRepresentationView
|
property ListView fullRepresentationView
|
||||||
|
|
||||||
|
backgroundColor: (applet.backgroundHints === PlasmaCore.Types.NoBackground) ? "transparent" : Kirigami.ColorUtils.adjustColor(PlasmaCore.Theme.backgroundColor, {"alpha": 0.8*255})
|
||||||
visible: shouldBeVisible
|
visible: shouldBeVisible
|
||||||
|
|
||||||
property bool shouldBeVisible: applet && (applet.status != PlasmaCore.Types.HiddenStatus && applet.status != PlasmaCore.Types.PassiveStatus)
|
property bool shouldBeVisible: applet && (applet.status != PlasmaCore.Types.HiddenStatus && applet.status != PlasmaCore.Types.PassiveStatus)
|
||||||
|
|
||||||
height: parent.height
|
height: parent.height
|
||||||
width: visible ? quickSettings.width : 0
|
width: visible ? quickSettings.width : 0
|
||||||
Layout.minimumHeight: applet && applet.switchHeight
|
Layout.minimumHeight: applet && applet.switchHeight
|
||||||
|
|
|
||||||
|
|
@ -20,5 +20,6 @@ FullContainer {
|
||||||
id: historyModel
|
id: historyModel
|
||||||
showExpired: true
|
showExpired: true
|
||||||
showDismissed: true
|
showDismissed: true
|
||||||
|
expandUnread: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
147
containments/panel/package/contents/ui/IndicatorsRow.qml
Normal file
147
containments/panel/package/contents/ui/IndicatorsRow.qml
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
import QtQml.Models 2.12
|
||||||
|
import QtGraphicalEffects 1.12
|
||||||
|
|
||||||
|
import org.kde.plasma.plasmoid 2.0
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||||
|
|
||||||
|
import org.kde.plasma.workspace.components 2.0 as PlasmaWorkspace
|
||||||
|
import org.kde.taskmanager 0.1 as TaskManager
|
||||||
|
|
||||||
|
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
|
||||||
|
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||||
|
|
||||||
|
import "LayoutManager.js" as LayoutManager
|
||||||
|
|
||||||
|
import "indicators" as Indicators
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: indicatorsRow
|
||||||
|
required property var colorGroup
|
||||||
|
required property bool showGradientBackground
|
||||||
|
required property bool showDropShadow
|
||||||
|
required property color backgroundColor
|
||||||
|
|
||||||
|
property alias colorScopeColor: icons.backgroundColor
|
||||||
|
property alias applets: appletIconsRow
|
||||||
|
|
||||||
|
PlasmaCore.DataSource {
|
||||||
|
id: timeSource
|
||||||
|
engine: "time"
|
||||||
|
connectedSources: ["Local"]
|
||||||
|
interval: 60 * 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
DropShadow {
|
||||||
|
anchors.fill: icons
|
||||||
|
visible: showDropShadow
|
||||||
|
cached: true
|
||||||
|
horizontalOffset: 0
|
||||||
|
verticalOffset: 1
|
||||||
|
radius: 4.0
|
||||||
|
samples: 17
|
||||||
|
color: Qt.rgba(0,0,0,0.8)
|
||||||
|
source: icons
|
||||||
|
}
|
||||||
|
|
||||||
|
// screen top panel
|
||||||
|
PlasmaCore.ColorScope {
|
||||||
|
id: icons
|
||||||
|
z: 1
|
||||||
|
colorGroup: indicatorsRow.colorGroup
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
// background
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: backgroundColor
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
visible: showGradientBackground
|
||||||
|
anchors.fill: parent
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop {
|
||||||
|
position: 1.0
|
||||||
|
color: "transparent"
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 0.0
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: strengthLoader
|
||||||
|
height: parent.height
|
||||||
|
width: item ? item.width : 0
|
||||||
|
active: signalStrengthProvider
|
||||||
|
sourceComponent: Indicators.SignalStrength {
|
||||||
|
provider: signalStrengthProvider
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: statusNotifierIndicatorsRow
|
||||||
|
anchors.left: strengthLoader.right
|
||||||
|
height: parent.height
|
||||||
|
Repeater {
|
||||||
|
id: statusNotifierRepeater
|
||||||
|
model: PlasmaCore.SortFilterModel {
|
||||||
|
id: filteredStatusNotifiers
|
||||||
|
filterRole: "Title"
|
||||||
|
sourceModel: PlasmaCore.DataModel {
|
||||||
|
dataSource: statusNotifierSource
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: TaskWidget {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaComponents.Label {
|
||||||
|
id: clock
|
||||||
|
property bool is24HourTime: plasmoid.nativeInterface.isSystem24HourFormat
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
text: Qt.formatTime(timeSource.data.Local.DateTime, is24HourTime ? "h:mm" : "h:mm ap")
|
||||||
|
color: PlasmaCore.ColorScope.textColor
|
||||||
|
horizontalAlignment: Qt.AlignHCenter
|
||||||
|
verticalAlignment: Qt.AlignVCenter
|
||||||
|
font.pixelSize: height / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: appletIconsRow
|
||||||
|
anchors {
|
||||||
|
bottom: parent.bottom
|
||||||
|
right: simpleIndicatorsLayout.left
|
||||||
|
}
|
||||||
|
height: parent.height
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: simpleIndicatorsLayout
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: units.smallSpacing
|
||||||
|
}
|
||||||
|
Indicators.Bluetooth { provider: bluetoothProvider }
|
||||||
|
Indicators.Wifi { provider: wifiProvider }
|
||||||
|
Indicators.Volume { provider: volumeProvider }
|
||||||
|
Indicators.Battery { provider: batteryProvider }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
216
containments/panel/package/contents/ui/SlidingContainer.qml
Normal file
216
containments/panel/package/contents/ui/SlidingContainer.qml
Normal file
|
|
@ -0,0 +1,216 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2014 Marco Martin <notmart@gmail.com>
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
import QtQuick.Window 2.2
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||||
|
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
|
||||||
|
|
||||||
|
NanoShell.FullScreenOverlay {
|
||||||
|
id: window
|
||||||
|
|
||||||
|
property int offset: 0 // slide progress
|
||||||
|
property int openThreshold: PlasmaCore.Units.gridUnit * 2
|
||||||
|
property bool userInteracting: false
|
||||||
|
property bool initiallyOpened: false // whether the panel is already open after a touch release (then don't restrict to collapsed height)
|
||||||
|
|
||||||
|
// height when quicksettings is fully open
|
||||||
|
required property int fullyOpenHeight
|
||||||
|
|
||||||
|
// flickable contentY
|
||||||
|
readonly property int openedContentY: wideScreen || offset > (collapsedHeight + openThreshold) ? -topEmptyAreaHeight : offsetToContentY(collapsedHeight)
|
||||||
|
readonly property int closedContentY: mainFlickable.contentHeight
|
||||||
|
|
||||||
|
readonly property bool wideScreen: width > height || width > units.gridUnit * 45
|
||||||
|
readonly property int drawerWidth: wideScreen ? contentItem.implicitWidth : width
|
||||||
|
|
||||||
|
property int drawerX: 0
|
||||||
|
property alias fixedArea: mainScope
|
||||||
|
property alias flickable: mainFlickable
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
property alias contentItem: contentArea.contentItem
|
||||||
|
property int topPanelHeight
|
||||||
|
property int collapsedHeight
|
||||||
|
property real topEmptyAreaHeight
|
||||||
|
|
||||||
|
property bool appletsShown: false // whether notifications or media player applets are shown
|
||||||
|
|
||||||
|
signal closed
|
||||||
|
|
||||||
|
width: Screen.width
|
||||||
|
height: Screen.height
|
||||||
|
|
||||||
|
onInitiallyOpenedChanged: {
|
||||||
|
if (initiallyOpened) mainFlickable.focus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function offsetToContentY(num) { return -num + window.fullyOpenHeight; }
|
||||||
|
function contentYToOffset(num) { return offsetToContentY(num); }
|
||||||
|
|
||||||
|
// avoids binding loops
|
||||||
|
function updateOffset(delta) {
|
||||||
|
// only go to collapsed height for mousearea when not widescreen
|
||||||
|
let maximum = window.wideScreen ? window.fullyOpenHeight : collapsedHeight + openThreshold / 2;
|
||||||
|
offset = Math.max(0, Math.min(maximum, offset + delta));
|
||||||
|
if (!mainFlickable.moving && !mainFlickable.dragging && !mainFlickable.flicking) {
|
||||||
|
mainFlickable.contentY = offsetToContentY(window.offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MovementDirection {
|
||||||
|
None = 0,
|
||||||
|
Up,
|
||||||
|
Down
|
||||||
|
}
|
||||||
|
property int direction: SlidingContainer.MovementDirection.None
|
||||||
|
|
||||||
|
function cancelAnimations() {
|
||||||
|
closeAnim.stop();
|
||||||
|
openAnim.stop();
|
||||||
|
}
|
||||||
|
function open() {
|
||||||
|
cancelAnimations();
|
||||||
|
openAnim.restart();
|
||||||
|
initiallyOpened = true;
|
||||||
|
}
|
||||||
|
function close() {
|
||||||
|
cancelAnimations();
|
||||||
|
closeAnim.restart();
|
||||||
|
initiallyOpened = false;
|
||||||
|
}
|
||||||
|
function updateState() {
|
||||||
|
cancelAnimations();
|
||||||
|
if (window.offset <= 0) {
|
||||||
|
// close immediately, so that we don't have to wait units.longDuration
|
||||||
|
window.visible = false;
|
||||||
|
window.closed();
|
||||||
|
close();
|
||||||
|
} else if (window.direction === SlidingContainer.MovementDirection.None) {
|
||||||
|
if (window.offset < openThreshold) {
|
||||||
|
close();
|
||||||
|
} else {
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
} else if (offset > openThreshold && window.direction === SlidingContainer.MovementDirection.Down) {
|
||||||
|
open();
|
||||||
|
} else if (mainFlickable.contentY > openThreshold) {
|
||||||
|
close();
|
||||||
|
} else {
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Timer {
|
||||||
|
id: updateStateTimer
|
||||||
|
interval: 0
|
||||||
|
onTriggered: updateState()
|
||||||
|
}
|
||||||
|
|
||||||
|
onActiveChanged: {
|
||||||
|
if (!active) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyAnimation {
|
||||||
|
id: closeAnim
|
||||||
|
target: mainFlickable
|
||||||
|
properties: "contentY"
|
||||||
|
duration: PlasmaCore.Units.longDuration
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
to: window.closedContentY
|
||||||
|
onFinished: {
|
||||||
|
window.visible = false;
|
||||||
|
window.closed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PropertyAnimation {
|
||||||
|
id: openAnim
|
||||||
|
target: mainFlickable
|
||||||
|
properties: "contentY"
|
||||||
|
duration: PlasmaCore.Units.longDuration
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
to: window.openedContentY
|
||||||
|
}
|
||||||
|
|
||||||
|
// fullscreen background
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.75)
|
||||||
|
opacity: (appletsShown ? 0.85 : 0.6) * Math.max(0, Math.min(1, offset / window.collapsedHeight))
|
||||||
|
Behavior on opacity { // smooth opacity changes
|
||||||
|
NumberAnimation { duration: 70 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaCore.ColorScope {
|
||||||
|
id: mainScope
|
||||||
|
colorGroup: PlasmaCore.Theme.ViewColorGroup
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
id: mainFlickable
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
property real oldContentY
|
||||||
|
contentY: contentHeight
|
||||||
|
|
||||||
|
onContentYChanged: {
|
||||||
|
if (contentY === oldContentY) {
|
||||||
|
window.direction = SlidingContainer.MovementDirection.None;
|
||||||
|
} else {
|
||||||
|
window.direction = contentY > oldContentY ? SlidingContainer.MovementDirection.Up : SlidingContainer.MovementDirection.Down;
|
||||||
|
}
|
||||||
|
window.offset = contentYToOffset(contentY);
|
||||||
|
oldContentY = contentY;
|
||||||
|
|
||||||
|
// close panel immediately after panel is not shown, and the flickable is not being dragged
|
||||||
|
if (initiallyOpened && window.offset <= 0 && !mainFlickable.dragging && !closeAnim.running && !openAnim.running) {
|
||||||
|
window.updateState();
|
||||||
|
focus = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boundsMovement: Flickable.StopAtBounds
|
||||||
|
contentWidth: window.width
|
||||||
|
contentHeight: window.height
|
||||||
|
bottomMargin: window.height
|
||||||
|
onMovementStarted: {
|
||||||
|
window.cancelAnimations();
|
||||||
|
window.userInteracting = true;
|
||||||
|
}
|
||||||
|
onFlickStarted: window.userInteracting = true;
|
||||||
|
onMovementEnded: {
|
||||||
|
window.userInteracting = false;
|
||||||
|
window.updateState();
|
||||||
|
}
|
||||||
|
onFlickEnded: {
|
||||||
|
window.userInteracting = true;
|
||||||
|
window.updateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: dismissArea
|
||||||
|
z: 2
|
||||||
|
width: parent.width
|
||||||
|
height: mainFlickable.contentHeight
|
||||||
|
onClicked: window.close();
|
||||||
|
|
||||||
|
// actual sliding contents
|
||||||
|
PlasmaComponents.Control {
|
||||||
|
id: contentArea
|
||||||
|
z: 1
|
||||||
|
x: drawerX
|
||||||
|
width: drawerWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,225 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2014 Marco Martin <notmart@gmail.com>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.14
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import QtQuick.Window 2.2
|
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
|
||||||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
|
||||||
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
|
|
||||||
|
|
||||||
NanoShell.FullScreenOverlay {
|
|
||||||
id: window
|
|
||||||
|
|
||||||
property int offset: 0
|
|
||||||
property int openThreshold
|
|
||||||
property bool userInteracting: false
|
|
||||||
readonly property bool wideScreen: width > height || width > units.gridUnit * 45
|
|
||||||
readonly property int drawerWidth: wideScreen ? contentItem.implicitWidth : width
|
|
||||||
property int drawerX: 0
|
|
||||||
property alias fixedArea: mainScope
|
|
||||||
property alias flickable: mainFlickable
|
|
||||||
|
|
||||||
color: "transparent"
|
|
||||||
property alias contentItem: contentArea.contentItem
|
|
||||||
property int headerHeight
|
|
||||||
property real topEmptyAreaHeight
|
|
||||||
|
|
||||||
signal closed
|
|
||||||
|
|
||||||
width: Screen.width
|
|
||||||
height: Screen.height
|
|
||||||
|
|
||||||
enum MovementDirection {
|
|
||||||
None = 0,
|
|
||||||
Up,
|
|
||||||
Down
|
|
||||||
}
|
|
||||||
property int direction: SlidingPanel.MovementDirection.None
|
|
||||||
|
|
||||||
function cancelAnimations() {
|
|
||||||
closeAnim.stop();
|
|
||||||
openAnim.stop();
|
|
||||||
}
|
|
||||||
function open() {
|
|
||||||
cancelAnimations();
|
|
||||||
window.showFullScreen();
|
|
||||||
openAnim.restart();
|
|
||||||
}
|
|
||||||
function close() {
|
|
||||||
cancelAnimations();
|
|
||||||
closeAnim.restart();
|
|
||||||
}
|
|
||||||
function updateState() {
|
|
||||||
cancelAnimations();
|
|
||||||
if (window.offset <= -headerHeight) {
|
|
||||||
// close immediately, so that we don't have to wait units.longDuration
|
|
||||||
window.visible = false;
|
|
||||||
window.closed();
|
|
||||||
} else if (window.direction === SlidingPanel.MovementDirection.None) {
|
|
||||||
if (offset < openThreshold) {
|
|
||||||
close();
|
|
||||||
} else {
|
|
||||||
openAnim.restart();
|
|
||||||
}
|
|
||||||
} else if (offset > openThreshold && window.direction === SlidingPanel.MovementDirection.Down) {
|
|
||||||
openAnim.restart();
|
|
||||||
} else if (mainFlickable.contentY > openThreshold) {
|
|
||||||
close();
|
|
||||||
} else {
|
|
||||||
openAnim.restart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Timer {
|
|
||||||
id: updateStateTimer
|
|
||||||
interval: 0
|
|
||||||
onTriggered: updateState()
|
|
||||||
}
|
|
||||||
|
|
||||||
onActiveChanged: {
|
|
||||||
if (!active) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*onVisibleChanged: {
|
|
||||||
if (visible) {
|
|
||||||
window.width = Screen.width;
|
|
||||||
window.height = Screen.height;
|
|
||||||
window.requestActivate();
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
SequentialAnimation {
|
|
||||||
id: closeAnim
|
|
||||||
PropertyAnimation {
|
|
||||||
target: window
|
|
||||||
duration: units.longDuration
|
|
||||||
easing.type: Easing.InOutQuad
|
|
||||||
properties: "offset"
|
|
||||||
from: window.offset
|
|
||||||
to: -headerHeight
|
|
||||||
}
|
|
||||||
ScriptAction {
|
|
||||||
script: {
|
|
||||||
window.visible = false;
|
|
||||||
window.closed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PropertyAnimation {
|
|
||||||
id: openAnim
|
|
||||||
target: window
|
|
||||||
duration: units.longDuration
|
|
||||||
easing.type: Easing.InOutQuad
|
|
||||||
properties: "offset"
|
|
||||||
from: window.offset
|
|
||||||
to: contentArea.height - topEmptyAreaHeight
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
bottom: parent.bottom
|
|
||||||
}
|
|
||||||
height: parent.height - headerHeight // don't layer on top panel indicators (area is darkened separately)
|
|
||||||
color: "black"
|
|
||||||
opacity: 0.6 * Math.min(1, offset/contentArea.height)
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
height: headerHeight
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
bottom: parent.top
|
|
||||||
}
|
|
||||||
color: "black"
|
|
||||||
opacity: 0.2
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
height: units.smallSpacing
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
top: parent.top
|
|
||||||
}
|
|
||||||
gradient: Gradient {
|
|
||||||
GradientStop {
|
|
||||||
position: 1.0
|
|
||||||
color: Qt.rgba(0, 0, 0, 0.0)
|
|
||||||
}
|
|
||||||
GradientStop {
|
|
||||||
position: 0.5
|
|
||||||
color: Qt.rgba(0, 0, 0, 0.4)
|
|
||||||
}
|
|
||||||
GradientStop {
|
|
||||||
position: 1.0
|
|
||||||
color: "transparent"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PlasmaCore.ColorScope {
|
|
||||||
id: mainScope
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
Flickable {
|
|
||||||
id: mainFlickable
|
|
||||||
anchors {
|
|
||||||
fill: parent
|
|
||||||
topMargin: headerHeight
|
|
||||||
}
|
|
||||||
Binding {
|
|
||||||
target: mainFlickable
|
|
||||||
property: "contentY"
|
|
||||||
value: -window.offset + contentArea.height
|
|
||||||
when: !mainFlickable.moving && !mainFlickable.dragging && !mainFlickable.flicking
|
|
||||||
}
|
|
||||||
//no loop as those 2 values compute to exactly the same
|
|
||||||
onContentYChanged: {
|
|
||||||
if (contentY === oldContentY) {
|
|
||||||
window.direction = SlidingPanel.MovementDirection.None;
|
|
||||||
} else {
|
|
||||||
window.direction = contentY > oldContentY ? SlidingPanel.MovementDirection.Up : SlidingPanel.MovementDirection.Down;
|
|
||||||
}
|
|
||||||
window.offset = -contentY + contentArea.height
|
|
||||||
oldContentY = contentY;
|
|
||||||
}
|
|
||||||
property real oldContentY
|
|
||||||
boundsMovement: Flickable.StopAtBounds
|
|
||||||
contentWidth: window.width
|
|
||||||
contentHeight: window.height*2 - headerHeight*2
|
|
||||||
bottomMargin: window.height
|
|
||||||
onMovementStarted: {
|
|
||||||
window.cancelAnimations();
|
|
||||||
window.userInteracting = true;
|
|
||||||
}
|
|
||||||
onFlickStarted: window.userInteracting = true;
|
|
||||||
onMovementEnded: {
|
|
||||||
window.userInteracting = false;
|
|
||||||
window.updateState();
|
|
||||||
}
|
|
||||||
onFlickEnded: {
|
|
||||||
window.userInteracting = true;
|
|
||||||
window.updateState();
|
|
||||||
}
|
|
||||||
MouseArea {
|
|
||||||
id: dismissArea
|
|
||||||
z: 2
|
|
||||||
width: parent.width
|
|
||||||
height: mainFlickable.contentHeight
|
|
||||||
onClicked: window.close();
|
|
||||||
PlasmaComponents.Control {
|
|
||||||
id: contentArea
|
|
||||||
z: 1
|
|
||||||
y: 0
|
|
||||||
x: drawerX
|
|
||||||
width: drawerWidth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
* SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
|
* SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
@ -11,31 +12,27 @@ import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||||
import org.kde.plasma.workspace.components 2.0 as PW
|
import org.kde.plasma.workspace.components 2.0 as PW
|
||||||
|
|
||||||
|
import "providers"
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
visible: pmSource.data["Battery"]["Has Cumulative"]
|
required property BatteryProvider provider
|
||||||
|
visible: provider.isVisible
|
||||||
|
|
||||||
PW.BatteryIcon {
|
PW.BatteryIcon {
|
||||||
id: battery
|
id: battery
|
||||||
Layout.preferredWidth: height
|
Layout.preferredWidth: height
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
hasBattery: true
|
hasBattery: true
|
||||||
percent: pmSource.data["Battery"]["Percent"]
|
percent: provider.percent
|
||||||
pluggedIn: pmSource.data["AC Adapter"] ? pmSource.data["AC Adapter"]["Plugged in"] : false
|
pluggedIn: provider.pluggedIn
|
||||||
|
|
||||||
height: batteryLabel.height
|
height: batteryLabel.height
|
||||||
width: batteryLabel.height
|
width: batteryLabel.height
|
||||||
|
|
||||||
PlasmaCore.DataSource {
|
|
||||||
id: pmSource
|
|
||||||
engine: "powermanagement"
|
|
||||||
connectedSources: ["Battery", "AC Adapter"]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PlasmaComponents.Label {
|
PlasmaComponents.Label {
|
||||||
id: batteryLabel
|
id: batteryLabel
|
||||||
text: i18n("%1%", battery.percent)
|
text: i18n("%1%", provider.percent)
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
|
||||||
color: PlasmaCore.ColorScope.textColor
|
color: PlasmaCore.ColorScope.textColor
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com
|
||||||
SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
|
SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
|
||||||
SPDX-FileCopyrightText: 2013-2017 Jan Grulich <jgrulich@redhat.com>
|
SPDX-FileCopyrightText: 2013-2017 Jan Grulich <jgrulich@redhat.com>
|
||||||
|
|
||||||
|
|
@ -11,38 +12,17 @@ import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
import org.kde.bluezqt 1.0 as BluezQt
|
import org.kde.bluezqt 1.0 as BluezQt
|
||||||
|
|
||||||
|
import "providers"
|
||||||
|
|
||||||
PlasmaCore.IconItem {
|
PlasmaCore.IconItem {
|
||||||
id: connectionIcon
|
id: connectionIcon
|
||||||
|
required property BluetoothProvider provider
|
||||||
|
|
||||||
property bool deviceConnected : false
|
source: provider.icon;
|
||||||
|
|
||||||
source: deviceConnected ? "preferences-system-bluetooth-activated" : "preferences-system-bluetooth";
|
|
||||||
colorGroup: PlasmaCore.ColorScope.colorGroup
|
colorGroup: PlasmaCore.ColorScope.colorGroup
|
||||||
|
|
||||||
visible: BluezQt.Manager.bluetoothOperational
|
visible: provider.isVisible
|
||||||
|
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.preferredWidth: height
|
Layout.preferredWidth: height
|
||||||
function updateStatus()
|
|
||||||
{
|
|
||||||
var connectedDevices = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < BluezQt.Manager.devices.length; ++i) {
|
|
||||||
var device = BluezQt.Manager.devices[i];
|
|
||||||
if (device.connected) {
|
|
||||||
connectedDevices.push(device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deviceConnected = connectedDevices.length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
BluezQt.Manager.deviceAdded.connect(updateStatus);
|
|
||||||
BluezQt.Manager.deviceRemoved.connect(updateStatus);
|
|
||||||
BluezQt.Manager.deviceChanged.connect(updateStatus);
|
|
||||||
BluezQt.Manager.bluetoothBlockedChanged.connect(updateStatus);
|
|
||||||
BluezQt.Manager.bluetoothOperationalChanged.connect(updateStatus);
|
|
||||||
|
|
||||||
updateStatus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
* SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
* SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
@ -7,34 +8,19 @@
|
||||||
import QtQuick 2.1
|
import QtQuick 2.1
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
import MeeGo.QOfono 0.2
|
|
||||||
|
|
||||||
import org.kde.plasma.plasmoid 2.0
|
import org.kde.plasma.plasmoid 2.0
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
|
|
||||||
|
import "providers"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
// we can't use SignalStrengthProvider as the var type as it would import ofono (which may cause it to break if ofono is not installed)
|
||||||
|
required property QtObject provider
|
||||||
|
|
||||||
width: strengthIcon.height + strengthLabel.width
|
width: strengthIcon.height + strengthLabel.width
|
||||||
Layout.minimumWidth: strengthIcon.height + strengthLabel.width
|
Layout.minimumWidth: strengthIcon.height + strengthLabel.width
|
||||||
|
|
||||||
OfonoManager {
|
|
||||||
id: ofonoManager
|
|
||||||
}
|
|
||||||
|
|
||||||
OfonoNetworkRegistration {
|
|
||||||
id: netreg
|
|
||||||
Component.onCompleted: {
|
|
||||||
netreg.scan()
|
|
||||||
}
|
|
||||||
|
|
||||||
modemPath: ofonoManager.modems.length ? ofonoManager.modems[0] : ""
|
|
||||||
}
|
|
||||||
|
|
||||||
OfonoSimManager {
|
|
||||||
id: simManager
|
|
||||||
modemPath: ofonoManager.modems.length ? ofonoManager.modems[0] : ""
|
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaCore.IconItem {
|
PlasmaCore.IconItem {
|
||||||
id: strengthIcon
|
id: strengthIcon
|
||||||
colorGroup: PlasmaCore.ColorScope.colorGroup
|
colorGroup: PlasmaCore.ColorScope.colorGroup
|
||||||
|
|
@ -43,12 +29,7 @@ Item {
|
||||||
width: height
|
width: height
|
||||||
height: parent.height
|
height: parent.height
|
||||||
|
|
||||||
source: netreg.strength == 100 ? "network-mobile-100"
|
source: provider.icon
|
||||||
: netreg.strength >= 80 ? "network-mobile-80"
|
|
||||||
: netreg.strength >= 60 ? "network-mobile-60"
|
|
||||||
: netreg.strength >= 40 ? "network-mobile-40"
|
|
||||||
: netreg.strength >= 20 ? "network-mobile-20"
|
|
||||||
: "network-mobile-0"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PlasmaComponents.Label {
|
PlasmaComponents.Label {
|
||||||
|
|
@ -56,7 +37,7 @@ Item {
|
||||||
anchors.left: strengthIcon.right
|
anchors.left: strengthIcon.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
text: simManager.pinRequired !== OfonoSimManager.NoPin ? i18n("Sim locked") : netreg.name
|
text: provider.label
|
||||||
color: PlasmaCore.ColorScope.textColor
|
color: PlasmaCore.ColorScope.textColor
|
||||||
font.pixelSize: parent.height / 2
|
font.pixelSize: parent.height / 2
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2021 Devin Lin <eespidev@gmail.com>
|
||||||
SPDX-FileCopyrightText: 2019 Aditya Mehra <Aix.m@outlook.com>
|
SPDX-FileCopyrightText: 2019 Aditya Mehra <Aix.m@outlook.com>
|
||||||
SPDX-FileCopyrightText: 2014-2015 Harald Sitter <sitter@kde.org>
|
SPDX-FileCopyrightText: 2014-2015 Harald Sitter <sitter@kde.org>
|
||||||
|
|
||||||
|
|
@ -11,152 +12,17 @@ import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
import org.kde.plasma.private.volume 0.1
|
import org.kde.plasma.private.volume 0.1
|
||||||
|
|
||||||
PlasmaCore.IconItem {
|
import "providers"
|
||||||
|
|
||||||
|
PlasmaCore.IconItem {
|
||||||
id: paIcon
|
id: paIcon
|
||||||
|
required property VolumeProvider provider
|
||||||
|
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.preferredWidth: height
|
Layout.preferredWidth: height
|
||||||
property bool volumeFeedback: true
|
source: provider.icon
|
||||||
property int maxVolumeValue: Math.round(100 * PulseAudio.NormalVolume / 100.0)
|
|
||||||
property int volumeStep: Math.round(5 * PulseAudio.NormalVolume / 100.0)
|
|
||||||
readonly property string dummyOutputName: "auto_null"
|
|
||||||
source: paSinkModel.preferredSink && !isDummyOutput(paSinkModel.preferredSink)
|
|
||||||
? iconName(paSinkModel.preferredSink.volume, paSinkModel.preferredSink.muted)
|
|
||||||
: iconName(0, true)
|
|
||||||
|
|
||||||
colorGroup: PlasmaCore.ColorScope.colorGroup
|
colorGroup: PlasmaCore.ColorScope.colorGroup
|
||||||
|
|
||||||
visible: paSinkModel.preferredSink && paSinkModel.preferredSink.muted
|
visible: provider.isVisible
|
||||||
|
|
||||||
function iconName(volume, muted, prefix) {
|
|
||||||
if (!prefix) {
|
|
||||||
prefix = "audio-volume";
|
|
||||||
}
|
|
||||||
var icon = null;
|
|
||||||
var percent = volume / maxVolumeValue;
|
|
||||||
if (percent <= 0.0 || muted) {
|
|
||||||
icon = prefix + "-muted";
|
|
||||||
} else if (percent <= 0.25) {
|
|
||||||
icon = prefix + "-low";
|
|
||||||
} else if (percent <= 0.75) {
|
|
||||||
icon = prefix + "-medium";
|
|
||||||
} else {
|
|
||||||
icon = prefix + "-high";
|
|
||||||
}
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isDummyOutput(output) {
|
|
||||||
return output && output.name === dummyOutputName;
|
|
||||||
}
|
|
||||||
|
|
||||||
function boundVolume(volume) {
|
|
||||||
return Math.max(PulseAudio.MinimalVolume, Math.min(volume, maxVolumeValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
function volumePercent(volume, max){
|
|
||||||
if(!max) {
|
|
||||||
max = PulseAudio.NormalVolume;
|
|
||||||
}
|
|
||||||
return Math.round(volume / max * 100.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function playFeedback(sinkIndex) {
|
|
||||||
if(!volumeFeedback){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(sinkIndex == undefined) {
|
|
||||||
sinkIndex = paSinkModel.preferredSink.index;
|
|
||||||
}
|
|
||||||
feedback.play(sinkIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
function increaseVolume() {
|
|
||||||
if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var volume = boundVolume(paSinkModel.preferredSink.volume + volumeStep);
|
|
||||||
var percent = volumePercent(volume, maxVolumeValue);
|
|
||||||
paSinkModel.preferredSink.muted = percent == 0;
|
|
||||||
paSinkModel.preferredSink.volume = volume;
|
|
||||||
osd.show(percent);
|
|
||||||
playFeedback();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function decreaseVolume() {
|
|
||||||
if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var volume = boundVolume(paSinkModel.preferredSink.volume - volumeStep);
|
|
||||||
var percent = volumePercent(volume, maxVolumeValue);
|
|
||||||
paSinkModel.preferredSink.muted = percent == 0;
|
|
||||||
paSinkModel.preferredSink.volume = volume;
|
|
||||||
osd.show(percent);
|
|
||||||
playFeedback();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function muteVolume() {
|
|
||||||
if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var toMute = !paSinkModel.preferredSink.muted;
|
|
||||||
paSinkModel.preferredSink.muted = toMute;
|
|
||||||
osd.show(toMute ? 0 : volumePercent(paSinkModel.preferredSink.volume, maxVolumeValue));
|
|
||||||
if (!toMute) {
|
|
||||||
playFeedback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SinkModel {
|
|
||||||
id: paSinkModel
|
|
||||||
}
|
|
||||||
|
|
||||||
VolumeOSD {
|
|
||||||
id: osd
|
|
||||||
}
|
|
||||||
|
|
||||||
VolumeFeedback {
|
|
||||||
id: feedback
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalActionCollection {
|
|
||||||
// KGlobalAccel cannot transition from kmix to something else, so if
|
|
||||||
// the user had a custom shortcut set for kmix those would get lost.
|
|
||||||
// To avoid this we hijack kmix name and actions. Entirely mental but
|
|
||||||
// best we can do to not cause annoyance for the user.
|
|
||||||
// The display name actually is updated to whatever registered last
|
|
||||||
// though, so as far as user visible strings go we should be fine.
|
|
||||||
// As of 2015-07-21:
|
|
||||||
// componentName: kmix
|
|
||||||
// actions: increase_volume, decrease_volume, mute
|
|
||||||
name: "kmix"
|
|
||||||
displayName: i18n("Audio")
|
|
||||||
|
|
||||||
GlobalAction {
|
|
||||||
objectName: "increase_volume"
|
|
||||||
text: i18n("Increase Volume")
|
|
||||||
shortcut: Qt.Key_VolumeUp
|
|
||||||
onTriggered: increaseVolume()
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalAction {
|
|
||||||
objectName: "decrease_volume"
|
|
||||||
text: i18n("Decrease Volume")
|
|
||||||
shortcut: Qt.Key_VolumeDown
|
|
||||||
onTriggered: decreaseVolume()
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalAction {
|
|
||||||
objectName: "mute"
|
|
||||||
text: i18n("Mute")
|
|
||||||
shortcut: Qt.Key_VolumeMute
|
|
||||||
onTriggered: muteVolume()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
|
SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
|
||||||
SPDX-FileCopyrightText: 2013-2017 Jan Grulich <jgrulich@redhat.com>
|
SPDX-FileCopyrightText: 2013-2017 Jan Grulich <jgrulich@redhat.com>
|
||||||
|
|
||||||
|
|
@ -11,10 +12,13 @@ import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
import org.kde.plasma.networkmanagement 0.2 as PlasmaNM
|
import org.kde.plasma.networkmanagement 0.2 as PlasmaNM
|
||||||
|
|
||||||
|
import "providers"
|
||||||
|
|
||||||
PlasmaCore.IconItem {
|
PlasmaCore.IconItem {
|
||||||
id: connectionIcon
|
id: connectionIcon
|
||||||
|
required property WifiProvider provider
|
||||||
|
|
||||||
source: connectionIconProvider.connectionIcon
|
source: provider.icon
|
||||||
colorGroup: PlasmaCore.ColorScope.colorGroup
|
colorGroup: PlasmaCore.ColorScope.colorGroup
|
||||||
|
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
@ -24,23 +28,7 @@ PlasmaCore.IconItem {
|
||||||
id: connectingIndicator
|
id: connectingIndicator
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
running: connectionIconProvider.connecting
|
running: provider.indicatorRunning
|
||||||
visible: running
|
visible: running
|
||||||
}
|
}
|
||||||
|
|
||||||
PlasmaNM.NetworkStatus {
|
|
||||||
id: networkStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaNM.NetworkModel {
|
|
||||||
id: connectionModel
|
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaNM.Handler {
|
|
||||||
id: handler
|
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaNM.ConnectionIcon {
|
|
||||||
id: connectionIconProvider
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
|
* SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.6
|
||||||
|
import QtQuick.Layouts 1.4
|
||||||
|
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||||
|
import org.kde.plasma.workspace.components 2.0 as PW
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property bool isVisible: pmSource.data["Battery"]["Has Cumulative"]
|
||||||
|
property int percent: pmSource.data["Battery"]["Percent"]
|
||||||
|
property bool pluggedIn: pmSource.data["AC Adapter"] ? pmSource.data["AC Adapter"]["Plugged in"] : false
|
||||||
|
|
||||||
|
property PlasmaCore.DataSource pmSource: PlasmaCore.DataSource {
|
||||||
|
engine: "powermanagement"
|
||||||
|
connectedSources: ["Battery", "AC Adapter"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
|
SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
|
||||||
|
SPDX-FileCopyrightText: 2013-2017 Jan Grulich <jgrulich@redhat.com>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.2
|
||||||
|
import QtQuick.Layouts 1.4
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
|
import org.kde.bluezqt 1.0 as BluezQt
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
property bool isVisible: BluezQt.Manager.bluetoothOperational
|
||||||
|
property string icon: deviceConnected ? "preferences-system-bluetooth-activated" : "preferences-system-bluetooth"
|
||||||
|
|
||||||
|
property bool deviceConnected : false
|
||||||
|
|
||||||
|
function updateStatus() {
|
||||||
|
var connectedDevices = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < BluezQt.Manager.devices.length; ++i) {
|
||||||
|
var device = BluezQt.Manager.devices[i];
|
||||||
|
if (device.connected) {
|
||||||
|
connectedDevices.push(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deviceConnected = connectedDevices.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
BluezQt.Manager.deviceAdded.connect(updateStatus);
|
||||||
|
BluezQt.Manager.deviceRemoved.connect(updateStatus);
|
||||||
|
BluezQt.Manager.deviceChanged.connect(updateStatus);
|
||||||
|
BluezQt.Manager.bluetoothBlockedChanged.connect(updateStatus);
|
||||||
|
BluezQt.Manager.bluetoothOperationalChanged.connect(updateStatus);
|
||||||
|
|
||||||
|
updateStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
|
* SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
|
import MeeGo.QOfono 0.2
|
||||||
|
|
||||||
|
import org.kde.plasma.plasmoid 2.0
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
property string icon: netreg.strength == 100 ? "network-mobile-100"
|
||||||
|
: netreg.strength >= 80 ? "network-mobile-80"
|
||||||
|
: netreg.strength >= 60 ? "network-mobile-60"
|
||||||
|
: netreg.strength >= 40 ? "network-mobile-40"
|
||||||
|
: netreg.strength >= 20 ? "network-mobile-20"
|
||||||
|
: "network-mobile-0"
|
||||||
|
|
||||||
|
property string label: simManager.pinRequired !== OfonoSimManager.NoPin ? i18n("Sim locked") : netreg.name
|
||||||
|
|
||||||
|
property OfonoManager ofonoManager: OfonoManager {}
|
||||||
|
|
||||||
|
property OfonoNetworkRegistration netreg: OfonoNetworkRegistration {
|
||||||
|
Component.onCompleted: {
|
||||||
|
netreg.scan()
|
||||||
|
}
|
||||||
|
|
||||||
|
modemPath: ofonoManager.modems.length ? ofonoManager.modems[0] : ""
|
||||||
|
}
|
||||||
|
|
||||||
|
property OfonoSimManager simManager: OfonoSimManager {
|
||||||
|
modemPath: ofonoManager.modems.length ? ofonoManager.modems[0] : ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
|
SPDX-FileCopyrightText: 2019 Aditya Mehra <Aix.m@outlook.com>
|
||||||
|
SPDX-FileCopyrightText: 2014-2015 Harald Sitter <sitter@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.2
|
||||||
|
import QtQuick.Layouts 1.4
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
|
import org.kde.plasma.private.volume 0.1
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
property bool isVisible: paSinkModel.preferredSink && paSinkModel.preferredSink.muted
|
||||||
|
property string icon: paSinkModel.preferredSink && !isDummyOutput(paSinkModel.preferredSink)
|
||||||
|
? iconName(paSinkModel.preferredSink.volume, paSinkModel.preferredSink.muted)
|
||||||
|
: iconName(0, true)
|
||||||
|
|
||||||
|
property bool volumeFeedback: true
|
||||||
|
property int maxVolumeValue: Math.round(100 * PulseAudio.NormalVolume / 100.0)
|
||||||
|
property int volumeStep: Math.round(5 * PulseAudio.NormalVolume / 100.0)
|
||||||
|
readonly property string dummyOutputName: "auto_null"
|
||||||
|
|
||||||
|
function iconName(volume, muted, prefix) {
|
||||||
|
if (!prefix) {
|
||||||
|
prefix = "audio-volume";
|
||||||
|
}
|
||||||
|
var icon = null;
|
||||||
|
var percent = volume / maxVolumeValue;
|
||||||
|
if (percent <= 0.0 || muted) {
|
||||||
|
icon = prefix + "-muted";
|
||||||
|
} else if (percent <= 0.25) {
|
||||||
|
icon = prefix + "-low";
|
||||||
|
} else if (percent <= 0.75) {
|
||||||
|
icon = prefix + "-medium";
|
||||||
|
} else {
|
||||||
|
icon = prefix + "-high";
|
||||||
|
}
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDummyOutput(output) {
|
||||||
|
return output && output.name === dummyOutputName;
|
||||||
|
}
|
||||||
|
|
||||||
|
function boundVolume(volume) {
|
||||||
|
return Math.max(PulseAudio.MinimalVolume, Math.min(volume, maxVolumeValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
function volumePercent(volume, max){
|
||||||
|
if(!max) {
|
||||||
|
max = PulseAudio.NormalVolume;
|
||||||
|
}
|
||||||
|
return Math.round(volume / max * 100.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function playFeedback(sinkIndex) {
|
||||||
|
if(!volumeFeedback){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(sinkIndex == undefined) {
|
||||||
|
sinkIndex = paSinkModel.preferredSink.index;
|
||||||
|
}
|
||||||
|
feedback.play(sinkIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
function increaseVolume() {
|
||||||
|
if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var volume = boundVolume(paSinkModel.preferredSink.volume + volumeStep);
|
||||||
|
var percent = volumePercent(volume, maxVolumeValue);
|
||||||
|
paSinkModel.preferredSink.muted = percent == 0;
|
||||||
|
paSinkModel.preferredSink.volume = volume;
|
||||||
|
osd.show(percent);
|
||||||
|
playFeedback();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function decreaseVolume() {
|
||||||
|
if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var volume = boundVolume(paSinkModel.preferredSink.volume - volumeStep);
|
||||||
|
var percent = volumePercent(volume, maxVolumeValue);
|
||||||
|
paSinkModel.preferredSink.muted = percent == 0;
|
||||||
|
paSinkModel.preferredSink.volume = volume;
|
||||||
|
osd.show(percent);
|
||||||
|
playFeedback();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function muteVolume() {
|
||||||
|
if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var toMute = !paSinkModel.preferredSink.muted;
|
||||||
|
paSinkModel.preferredSink.muted = toMute;
|
||||||
|
osd.show(toMute ? 0 : volumePercent(paSinkModel.preferredSink.volume, maxVolumeValue));
|
||||||
|
if (!toMute) {
|
||||||
|
playFeedback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property SinkModel paSinkModel: SinkModel {}
|
||||||
|
|
||||||
|
property VolumeOSD osd: VolumeOSD {}
|
||||||
|
|
||||||
|
property VolumeFeedback feedback: VolumeFeedback {}
|
||||||
|
|
||||||
|
property GlobalActionCollection actionCollection: GlobalActionCollection {
|
||||||
|
// KGlobalAccel cannot transition from kmix to something else, so if
|
||||||
|
// the user had a custom shortcut set for kmix those would get lost.
|
||||||
|
// To avoid this we hijack kmix name and actions. Entirely mental but
|
||||||
|
// best we can do to not cause annoyance for the user.
|
||||||
|
// The display name actually is updated to whatever registered last
|
||||||
|
// though, so as far as user visible strings go we should be fine.
|
||||||
|
// As of 2015-07-21:
|
||||||
|
// componentName: kmix
|
||||||
|
// actions: increase_volume, decrease_volume, mute
|
||||||
|
name: "kmix"
|
||||||
|
displayName: i18n("Audio")
|
||||||
|
|
||||||
|
GlobalAction {
|
||||||
|
objectName: "increase_volume"
|
||||||
|
text: i18n("Increase Volume")
|
||||||
|
shortcut: Qt.Key_VolumeUp
|
||||||
|
onTriggered: increaseVolume()
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalAction {
|
||||||
|
objectName: "decrease_volume"
|
||||||
|
text: i18n("Decrease Volume")
|
||||||
|
shortcut: Qt.Key_VolumeDown
|
||||||
|
onTriggered: decreaseVolume()
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalAction {
|
||||||
|
objectName: "mute"
|
||||||
|
text: i18n("Mute")
|
||||||
|
shortcut: Qt.Key_VolumeMute
|
||||||
|
onTriggered: muteVolume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
|
SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
|
||||||
|
SPDX-FileCopyrightText: 2013-2017 Jan Grulich <jgrulich@redhat.com>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.2
|
||||||
|
import QtQuick.Layouts 1.4
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
|
import org.kde.plasma.networkmanagement 0.2 as PlasmaNM
|
||||||
|
|
||||||
|
Item {
|
||||||
|
visible: false
|
||||||
|
property string icon: connectionIconProvider.connectionIcon
|
||||||
|
property bool indicatorRunning: connectionIconProvider.connecting
|
||||||
|
|
||||||
|
PlasmaNM.NetworkStatus {
|
||||||
|
id: networkStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaNM.NetworkModel {
|
||||||
|
id: connectionModel
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaNM.Handler {
|
||||||
|
id: handler
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaNM.ConnectionIcon {
|
||||||
|
id: connectionIconProvider
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
* SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
* SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
@ -9,6 +10,8 @@ import QtQuick.Layouts 1.3
|
||||||
import QtQml.Models 2.12
|
import QtQml.Models 2.12
|
||||||
import QtGraphicalEffects 1.12
|
import QtGraphicalEffects 1.12
|
||||||
|
|
||||||
|
import org.kde.kirigami 2.12 as Kirigami
|
||||||
|
|
||||||
import org.kde.plasma.plasmoid 2.0
|
import org.kde.plasma.plasmoid 2.0
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
import org.kde.plasma.components 3.0 as PlasmaComponents
|
import org.kde.plasma.components 3.0 as PlasmaComponents
|
||||||
|
|
@ -23,7 +26,7 @@ import "LayoutManager.js" as LayoutManager
|
||||||
|
|
||||||
import "quicksettings"
|
import "quicksettings"
|
||||||
import "indicators" as Indicators
|
import "indicators" as Indicators
|
||||||
|
import "indicators/providers" as IndicatorProviders
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
@ -37,7 +40,7 @@ Item {
|
||||||
property bool reorderingApps: false
|
property bool reorderingApps: false
|
||||||
property var layoutManager: LayoutManager
|
property var layoutManager: LayoutManager
|
||||||
|
|
||||||
readonly property color backgroundColor: NanoShell.StartupFeedback.visible ? NanoShell.StartupFeedback.backgroundColor : icons.backgroundColor
|
readonly property color backgroundColor: NanoShell.StartupFeedback.visible ? NanoShell.StartupFeedback.backgroundColor : topPanel.colorScopeColor
|
||||||
readonly property bool showingApp: !MobileShell.HomeScreenControls.homeScreenVisible
|
readonly property bool showingApp: !MobileShell.HomeScreenControls.homeScreenVisible
|
||||||
|
|
||||||
readonly property bool hasTasks: tasksModel.count > 0
|
readonly property bool hasTasks: tasksModel.count > 0
|
||||||
|
|
@ -48,7 +51,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
function addApplet(applet, x, y) {
|
function addApplet(applet, x, y) {
|
||||||
var compactContainer = compactContainerComponent.createObject(appletIconsRow)
|
var compactContainer = compactContainerComponent.createObject(topPanel.applets)
|
||||||
print("Applet added: " + applet + " " + applet.title)
|
print("Applet added: " + applet + " " + applet.title)
|
||||||
|
|
||||||
applet.parent = compactContainer;
|
applet.parent = compactContainer;
|
||||||
|
|
@ -115,138 +118,59 @@ Item {
|
||||||
property Item applet
|
property Item applet
|
||||||
visible: applet && (applet.status != PlasmaCore.Types.HiddenStatus && applet.status != PlasmaCore.Types.PassiveStatus)
|
visible: applet && (applet.status != PlasmaCore.Types.HiddenStatus && applet.status != PlasmaCore.Types.PassiveStatus)
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.minimumWidth: applet && applet.compactRepresentationItem ? Math.max(applet.compactRepresentationItem.Layout.minimumWidth, appletIconsRow.height) : appletIconsRow.height
|
Layout.minimumWidth: applet && applet.compactRepresentationItem ? Math.max(applet.compactRepresentationItem.Layout.minimumWidth, topPanel.applets.height) : topPanel.applets.height
|
||||||
Layout.maximumWidth: Layout.minimumWidth
|
Layout.maximumWidth: Layout.minimumWidth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: fullContainerComponent
|
id: fullContainerComponent
|
||||||
FullContainer {
|
FullContainer {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: fullNotificationsContainerComponent
|
id: fullNotificationsContainerComponent
|
||||||
FullNotificationsContainer {
|
FullNotificationsContainer {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PlasmaCore.DataSource {
|
// indicator providers
|
||||||
id: timeSource
|
IndicatorProviders.BatteryProvider {
|
||||||
engine: "time"
|
id: batteryProvider
|
||||||
connectedSources: ["Local"]
|
}
|
||||||
interval: 60 * 1000
|
IndicatorProviders.BluetoothProvider {
|
||||||
|
id: bluetoothProvider
|
||||||
|
}
|
||||||
|
property alias signalStrengthProvider: signalStrengthProviderLoader.item
|
||||||
|
Loader {
|
||||||
|
id: signalStrengthProviderLoader
|
||||||
|
source: Qt.resolvedUrl("indicators/providers/SignalStrengthProvider.qml")
|
||||||
|
}
|
||||||
|
IndicatorProviders.VolumeProvider {
|
||||||
|
id: volumeProvider
|
||||||
|
}
|
||||||
|
IndicatorProviders.WifiProvider {
|
||||||
|
id: wifiProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
DropShadow {
|
// top panel component
|
||||||
anchors.fill: icons
|
IndicatorsRow {
|
||||||
visible: !showingApp
|
id: topPanel
|
||||||
cached: true
|
anchors.fill: parent
|
||||||
horizontalOffset: 0
|
|
||||||
verticalOffset: 1
|
|
||||||
radius: 4.0
|
|
||||||
samples: 17
|
|
||||||
color: Qt.rgba(0,0,0,0.8)
|
|
||||||
source: icons
|
|
||||||
}
|
|
||||||
|
|
||||||
// screen top panel
|
|
||||||
PlasmaCore.ColorScope {
|
|
||||||
id: icons
|
|
||||||
z: 1
|
z: 1
|
||||||
colorGroup: showingApp ? PlasmaCore.Theme.HeaderColorGroup : PlasmaCore.Theme.ComplementaryColorGroup
|
colorGroup: showingApp ? PlasmaCore.Theme.HeaderColorGroup : PlasmaCore.Theme.ComplementaryColorGroup
|
||||||
//parent: slidingPanel.visible && !slidingPanel.wideScreen ? panelContents : root
|
backgroundColor: !showingApp ? "transparent" : root.backgroundColor
|
||||||
anchors {
|
showGradientBackground: !showingApp
|
||||||
left: parent.left
|
showDropShadow: !showingApp
|
||||||
right: parent.right
|
|
||||||
bottom: parent.bottom
|
|
||||||
}
|
|
||||||
height: root.height
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
gradient: Gradient {
|
|
||||||
GradientStop {
|
|
||||||
position: 1.0
|
|
||||||
color: showingApp ? root.backgroundColor : "transparent"
|
|
||||||
}
|
|
||||||
GradientStop {
|
|
||||||
position: 0.0
|
|
||||||
color: showingApp ? root.backgroundColor : Qt.rgba(0, 0, 0, 0.1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: strengthLoader
|
|
||||||
height: parent.height
|
|
||||||
width: item ? item.width : 0
|
|
||||||
source: Qt.resolvedUrl("indicators/SignalStrength.qml")
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: sniRow
|
|
||||||
anchors.left: strengthLoader.right
|
|
||||||
height: parent.height
|
|
||||||
Repeater {
|
|
||||||
id: statusNotifierRepeater
|
|
||||||
model: PlasmaCore.SortFilterModel {
|
|
||||||
id: filteredStatusNotifiers
|
|
||||||
filterRole: "Title"
|
|
||||||
sourceModel: PlasmaCore.DataModel {
|
|
||||||
dataSource: statusNotifierSource
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: TaskWidget {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaComponents.Label {
|
|
||||||
id: clock
|
|
||||||
property bool is24HourTime: plasmoid.nativeInterface.isSystem24HourFormat
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
text: Qt.formatTime(timeSource.data.Local.DateTime, is24HourTime ? "h:mm" : "h:mm ap")
|
|
||||||
color: PlasmaCore.ColorScope.textColor
|
|
||||||
horizontalAlignment: Qt.AlignHCenter
|
|
||||||
verticalAlignment: Qt.AlignVCenter
|
|
||||||
font.pixelSize: height / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: appletIconsRow
|
|
||||||
anchors {
|
|
||||||
bottom: parent.bottom
|
|
||||||
right: simpleIndicatorsLayout.left
|
|
||||||
}
|
|
||||||
height: parent.height
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: pluggable
|
|
||||||
RowLayout {
|
|
||||||
id: simpleIndicatorsLayout
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
bottom: parent.bottom
|
|
||||||
right: parent.right
|
|
||||||
rightMargin: units.smallSpacing
|
|
||||||
}
|
|
||||||
Indicators.Bluetooth {}
|
|
||||||
Indicators.Wifi {}
|
|
||||||
Indicators.Volume {}
|
|
||||||
Indicators.Battery {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// screen top panel background (background for the rest of the screen in SlidingPanel.qml)
|
// top panel background (background for the rest of the screen in SlidingPanel.qml)
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: "black"
|
color: PlasmaCore.Theme.backgroundColor
|
||||||
opacity: 0.6 * Math.min(1, slidingPanel.offset/panelContents.height)
|
opacity: 0.6 * Math.min(1, slidingPanel.offset/panelContents.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initial swipe down
|
||||||
MouseArea {
|
MouseArea {
|
||||||
z: 99
|
z: 99
|
||||||
property int oldMouseY: 0
|
property int oldMouseY: 0
|
||||||
|
|
@ -256,13 +180,12 @@ Item {
|
||||||
slidingPanel.cancelAnimations();
|
slidingPanel.cancelAnimations();
|
||||||
slidingPanel.drawerX = Math.min(Math.max(0, mouse.x - slidingPanel.drawerWidth/2), slidingPanel.width - slidingPanel.contentItem.width)
|
slidingPanel.drawerX = Math.min(Math.max(0, mouse.x - slidingPanel.drawerWidth/2), slidingPanel.width - slidingPanel.contentItem.width)
|
||||||
slidingPanel.userInteracting = true;
|
slidingPanel.userInteracting = true;
|
||||||
|
slidingPanel.flickable.contentY = slidingPanel.closedContentY;
|
||||||
oldMouseY = mouse.y;
|
oldMouseY = mouse.y;
|
||||||
slidingPanel.offset = 0//units.gridUnit * 2;
|
|
||||||
slidingPanel.showFullScreen();
|
slidingPanel.showFullScreen();
|
||||||
}
|
}
|
||||||
onPositionChanged: {
|
onPositionChanged: {
|
||||||
slidingPanel.offset = Math.min(slidingPanel.contentItem.height, slidingPanel.offset + (mouse.y - oldMouseY));
|
slidingPanel.updateOffset(mouse.y - oldMouseY);
|
||||||
|
|
||||||
oldMouseY = mouse.y;
|
oldMouseY = mouse.y;
|
||||||
}
|
}
|
||||||
onReleased: {
|
onReleased: {
|
||||||
|
|
@ -275,61 +198,65 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SlidingPanel {
|
// sliding component
|
||||||
|
SlidingContainer {
|
||||||
id: slidingPanel
|
id: slidingPanel
|
||||||
width: plasmoid.availableScreenRect.width
|
width: plasmoid.availableScreenRect.width
|
||||||
height: plasmoid.availableScreenRect.height
|
height: plasmoid.availableScreenRect.height
|
||||||
openThreshold: units.gridUnit * 2
|
topPanelHeight: topPanel.height
|
||||||
headerHeight: root.height
|
|
||||||
topEmptyAreaHeight: quickSettings.topEmptyAreaHeight
|
topEmptyAreaHeight: quickSettings.topEmptyAreaHeight
|
||||||
|
collapsedHeight: quickSettings.collapsedHeight
|
||||||
|
fullyOpenHeight: quickSettings.implicitHeight
|
||||||
|
|
||||||
|
appletsShown: fullRepresentationView.count > 0
|
||||||
|
|
||||||
offset: quickSettings.height
|
offset: quickSettings.height
|
||||||
|
|
||||||
onClosed: quickSettings.closed()
|
onClosed: quickSettings.closed()
|
||||||
|
|
||||||
contentItem: Item {
|
contentItem: MouseArea {
|
||||||
implicitWidth: panelContents.implicitWidth
|
// mousearea captures touch presses so that the flickable picks them up for swiping
|
||||||
|
implicitWidth: slidingPanel.width
|
||||||
implicitHeight: Math.min(slidingPanel.height, quickSettings.implicitHeight)
|
implicitHeight: Math.min(slidingPanel.height, quickSettings.implicitHeight)
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
id: panelContents
|
id: panelContents
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
implicitWidth: quickSettings.implicitWidth
|
|
||||||
implicitHeight: Math.min(slidingPanel.height, quickSettings.implicitHeight)
|
|
||||||
|
|
||||||
columns: slidingPanel.wideScreen ? 2 : 1
|
columns: slidingPanel.wideScreen ? 2 : 1
|
||||||
rows: slidingPanel.wideScreen ? 1 : 2
|
rows: slidingPanel.wideScreen ? 1 : 2
|
||||||
|
|
||||||
QuickSettings {
|
QuickSettingsPanel {
|
||||||
id: quickSettings
|
id: quickSettings
|
||||||
|
property int trueHeight: height + Math.round(Kirigami.Units.gridUnit * 1.5) // add height of bottom bar
|
||||||
|
z: 4
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
Layout.preferredWidth: slidingPanel.wideScreen ? Math.min(slidingPanel.width/2, units.gridUnit * 25) : panelContents.width
|
Layout.preferredWidth: slidingPanel.wideScreen ? Math.min(slidingPanel.width/2, units.gridUnit * 25) : panelContents.width
|
||||||
z: 4
|
|
||||||
parentSlidingPanel: slidingPanel
|
parentSlidingPanel: slidingPanel
|
||||||
onCloseRequested: {
|
onCloseRequested: slidingPanel.hide()
|
||||||
slidingPanel.hide()
|
|
||||||
}
|
|
||||||
background: DrawerBackground {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// notifications
|
||||||
ListView {
|
ListView {
|
||||||
id: fullRepresentationView
|
id: fullRepresentationView
|
||||||
z: 1
|
implicitHeight: units.gridUnit * 20
|
||||||
interactive: width < contentWidth
|
Layout.topMargin: slidingPanel.wideScreen ? 0 : Math.round(Kirigami.Units.gridUnit * 1.5) // add height of bottom bar
|
||||||
//parent: slidingPanel.wideScreen ? slidingPanel.flickable.contentItem : panelContents
|
|
||||||
|
|
||||||
Layout.preferredWidth: slidingPanel.wideScreen ? Math.min(slidingPanel.width/2, quickSettings.width*fullRepresentationModel.count) : panelContents.width
|
Layout.preferredWidth: slidingPanel.wideScreen ? Math.min(slidingPanel.width/2, quickSettings.width*fullRepresentationModel.count) : panelContents.width
|
||||||
|
Layout.preferredHeight: Math.min(plasmoid.screenGeometry.height - quickSettings.implicitHeight - bottomBar.height + slidingPanel.topEmptyAreaHeight, implicitHeight)
|
||||||
|
z: 1
|
||||||
|
interactive: count > 0 && width < contentWidth
|
||||||
|
|
||||||
//Layout.fillWidth: true
|
|
||||||
clip: slidingPanel.wideScreen
|
clip: slidingPanel.wideScreen
|
||||||
y: slidingPanel.wideScreen ? 0 : quickSettings.height - (quickSettings.height + height) * (1-opacity)
|
y: slidingPanel.wideScreen ? 0 : quickSettings.trueHeight
|
||||||
opacity: slidingPanel.wideScreen ? 1 : fullRepresentationModel.count > 0 && (slidingPanel.offset + slidingPanel.headerHeight)/(quickSettings.height -slidingPanel.topEmptyAreaHeight)
|
opacity: {
|
||||||
Layout.preferredHeight: Math.min(plasmoid.screenGeometry.height - slidingPanel.headerHeight - quickSettings.height - bottomBar.height + slidingPanel.topEmptyAreaHeight, implicitHeight)
|
if (slidingPanel.wideScreen) {
|
||||||
//leftMargin: slidingPanel.drawerX
|
return 1;
|
||||||
|
} else {
|
||||||
|
return fullRepresentationModel.count > 0 && slidingPanel.offset / slidingPanel.collapsedHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
preferredHighlightBegin: slidingPanel.drawerX
|
preferredHighlightBegin: slidingPanel.drawerX
|
||||||
|
|
||||||
implicitHeight: units.gridUnit * 20
|
|
||||||
cacheBuffer: width * 100
|
cacheBuffer: width * 100
|
||||||
highlightFollowsCurrentItem: true
|
highlightFollowsCurrentItem: true
|
||||||
highlightRangeMode: ListView.StrictlyEnforceRange
|
highlightRangeMode: ListView.StrictlyEnforceRange
|
||||||
|
|
@ -346,10 +273,6 @@ Item {
|
||||||
z: -1
|
z: -1
|
||||||
onClicked: slidingPanel.close()
|
onClicked: slidingPanel.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
//implicitHeight: fullRepresentationLayout.implicitHeight
|
|
||||||
//clip: true
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -360,11 +283,11 @@ Item {
|
||||||
right: parent.right
|
right: parent.right
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
}
|
}
|
||||||
|
backgroundColor: Kirigami.ColorUtils.adjustColor(PlasmaCore.Theme.backgroundColor, {"alpha": 0.8*255})
|
||||||
|
|
||||||
parent: slidingPanel.fixedArea
|
parent: slidingPanel.fixedArea
|
||||||
opacity: fullRepresentationView.opacity
|
opacity: fullRepresentationView.opacity
|
||||||
visible: !slidingPanel.wideScreen && fullRepresentationModel.count > 1
|
visible: !slidingPanel.wideScreen && fullRepresentationModel.count > 1
|
||||||
//height: 40
|
|
||||||
z: 100
|
z: 100
|
||||||
contentItem: RowLayout {
|
contentItem: RowLayout {
|
||||||
PlasmaComponents.TabBar {
|
PlasmaComponents.TabBar {
|
||||||
|
|
|
||||||
|
|
@ -9,40 +9,89 @@
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
|
import org.kde.kirigami 2.12 as Kirigami
|
||||||
|
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
import org.kde.plasma.components 3.0 as PC3
|
import org.kde.plasma.components 3.0 as PC3
|
||||||
|
|
||||||
RowLayout {
|
Item {
|
||||||
id: brightnessRoot
|
id: brightnessRoot
|
||||||
property alias value: brightnessSlider.value
|
|
||||||
property alias maximumValue: brightnessSlider.to
|
|
||||||
|
|
||||||
signal moved
|
implicitHeight: brightnessRow.implicitHeight
|
||||||
|
|
||||||
spacing: units.smallSpacing
|
property int screenBrightness
|
||||||
|
property bool disableBrightnessUpdate: true
|
||||||
|
readonly property int maximumScreenBrightness: pmSource.data["PowerDevil"] ? pmSource.data["PowerDevil"]["Maximum Screen Brightness"] || 0 : 0
|
||||||
|
|
||||||
PlasmaCore.IconItem {
|
onScreenBrightnessChanged: {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
brightnessSlider.value = brightnessRoot.screenBrightness
|
||||||
Layout.leftMargin: Kirigami.Units.largeSpacing
|
if (!disableBrightnessUpdate) {
|
||||||
Layout.preferredWidth: units.iconSizes.medium
|
var service = pmSource.serviceForSource("PowerDevil");
|
||||||
Layout.preferredHeight: width
|
var operation = service.operationDescription("setBrightness");
|
||||||
source: "low-brightness"
|
operation.brightness = screenBrightness;
|
||||||
|
operation.silent = true
|
||||||
|
service.startOperationCall(operation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Slider {
|
PlasmaCore.DataSource {
|
||||||
id: brightnessSlider
|
id: pmSource
|
||||||
Layout.fillWidth: true
|
engine: "powermanagement"
|
||||||
Layout.alignment: Qt.AlignVCenter
|
connectedSources: ["PowerDevil"]
|
||||||
onMoved: brightnessRoot.moved()
|
onSourceAdded: {
|
||||||
from: 1
|
if (source === "PowerDevil") {
|
||||||
|
disconnectSource(source);
|
||||||
|
connectSource(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onDataChanged: {
|
||||||
|
disableBrightnessUpdate = true;
|
||||||
|
brightnessRoot.screenBrightness = pmSource.data["PowerDevil"]["Screen Brightness"];
|
||||||
|
disableBrightnessUpdate = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlasmaCore.IconItem {
|
Component.onCompleted: {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
brightnessSlider.moved.connect(function() {
|
||||||
Layout.rightMargin: Kirigami.Units.largeSpacing
|
brightnessRoot.screenBrightness = brightnessSlider.value;
|
||||||
Layout.preferredWidth: units.iconSizes.medium
|
});
|
||||||
Layout.preferredHeight: width
|
disableBrightnessUpdate = false;
|
||||||
source: "high-brightness"
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: brightnessRow
|
||||||
|
spacing: PlasmaCore.Units.smallSpacing * 2
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
|
||||||
|
Kirigami.Icon {
|
||||||
|
color: PlasmaCore.Theme.textColor
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.leftMargin: PlasmaCore.Units.smallSpacing
|
||||||
|
Layout.preferredWidth: Math.round(PlasmaCore.Units.gridUnit * 1.75)
|
||||||
|
Layout.preferredHeight: width
|
||||||
|
source: "low-brightness"
|
||||||
|
}
|
||||||
|
|
||||||
|
Slider {
|
||||||
|
id: brightnessSlider
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
value: screenBrightness
|
||||||
|
from: 1
|
||||||
|
to: maximumScreenBrightness
|
||||||
|
}
|
||||||
|
|
||||||
|
Kirigami.Icon {
|
||||||
|
color: PlasmaCore.Theme.textColor
|
||||||
|
isMask: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.rightMargin: PlasmaCore.Units.smallSpacing
|
||||||
|
Layout.preferredWidth: Math.round(PlasmaCore.Units.gridUnit * 1.75)
|
||||||
|
Layout.preferredHeight: width
|
||||||
|
source: "high-brightness"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015 Marco Martin <notmart@gmail.com>
|
* SPDX-FileCopyrightText: 2015 Marco Martin <notmart@gmail.com>
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: LGPL-2.0-or-later
|
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
@ -14,6 +15,9 @@ import org.kde.plasma.private.nanoshell 2.0 as NanoShell
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: delegateRoot
|
id: delegateRoot
|
||||||
spacing: units.smallSpacing
|
spacing: units.smallSpacing
|
||||||
|
|
||||||
|
required property var settingsModel
|
||||||
|
|
||||||
signal closeRequested
|
signal closeRequested
|
||||||
signal panelClosed
|
signal panelClosed
|
||||||
|
|
||||||
|
|
@ -25,66 +29,67 @@ ColumnLayout {
|
||||||
required property var toggleFunction
|
required property var toggleFunction
|
||||||
property alias labelOpacity: label.opacity
|
property alias labelOpacity: label.opacity
|
||||||
|
|
||||||
|
property color disabledButtonColor: PlasmaCore.Theme.backgroundColor
|
||||||
|
property color disabledPressedButtonColor: Qt.darker(disabledButtonColor, 1.1)
|
||||||
|
property color enabledButtonColor: Kirigami.ColorUtils.adjustColor(PlasmaCore.ColorScope.highlightColor, {"alpha": 0.4*255})
|
||||||
|
property color enabledPressedButtonColor: Kirigami.ColorUtils.adjustColor(PlasmaCore.ColorScope.highlightColor, {"alpha": 0.6*255});
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.preferredWidth: units.iconSizes.large + units.smallSpacing
|
Layout.preferredWidth: PlasmaCore.Units.iconSizes.large + PlasmaCore.Units.smallSpacing
|
||||||
Layout.minimumHeight: width
|
Layout.minimumHeight: width
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
radius: units.smallSpacing
|
radius: PlasmaCore.Units.smallSpacing
|
||||||
border.color: delegateRoot.enabled ?
|
border.color: delegateRoot.enabled ?
|
||||||
Qt.darker(Kirigami.ColorUtils.adjustColor(PlasmaCore.ColorScope.highlightColor, {}), 1.25) :
|
Qt.darker(Kirigami.ColorUtils.adjustColor(PlasmaCore.ColorScope.highlightColor, {}), 1.25) :
|
||||||
Kirigami.ColorUtils.adjustColor(PlasmaCore.ColorScope.textColor, {"alpha": 0.2*255})
|
Kirigami.ColorUtils.adjustColor(PlasmaCore.ColorScope.textColor, {"alpha": 0.2*255})
|
||||||
color: {
|
color: {
|
||||||
if (delegateRoot.enabled) {
|
if (delegateRoot.enabled) {
|
||||||
return Kirigami.ColorUtils.adjustColor(PlasmaCore.ColorScope.highlightColor, {"alpha": iconMouseArea.pressed ? 0.5*255 : 0.3*255});
|
return iconMouseArea.pressed ? enabledPressedButtonColor : enabledButtonColor
|
||||||
} else {
|
} else {
|
||||||
if (iconMouseArea.pressed) {
|
return iconMouseArea.pressed ? disabledPressedButtonColor : disabledButtonColor
|
||||||
return Qt.darker(Kirigami.ColorUtils.adjustColor(PlasmaCore.ColorScope.backgroundColor, {"alpha": 0.9*255}), 1.25);
|
|
||||||
} else {
|
|
||||||
return Kirigami.ColorUtils.adjustColor(PlasmaCore.ColorScope.backgroundColor, {"alpha": 0.3*255});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlasmaCore.IconItem {
|
Kirigami.Icon {
|
||||||
id: icon
|
id: icon
|
||||||
colorGroup: PlasmaCore.ColorScope.colorGroup
|
color: PlasmaCore.Theme.textColor
|
||||||
anchors {
|
anchors.centerIn: parent
|
||||||
fill: parent
|
implicitWidth: Math.round(parent.width * 0.6)
|
||||||
margins: units.smallSpacing
|
implicitHeight: width
|
||||||
}
|
|
||||||
source: delegateRoot.icon
|
source: delegateRoot.icon
|
||||||
MouseArea {
|
}
|
||||||
id: iconMouseArea
|
|
||||||
anchors.fill: parent
|
MouseArea {
|
||||||
onClicked: {
|
id: iconMouseArea
|
||||||
if (delegateRoot.toggle) {
|
anchors.fill: parent
|
||||||
delegateRoot.toggle();
|
onClicked: {
|
||||||
} else if (delegateRoot.toggleFunction) {
|
if (delegateRoot.toggle) {
|
||||||
root[delegateRoot.toggleFunction]();
|
delegateRoot.toggle();
|
||||||
} else if (delegateRoot.settingsCommand) {
|
} else if (delegateRoot.toggleFunction) {
|
||||||
NanoShell.StartupFeedback.open(
|
settingsModel[delegateRoot.toggleFunction]();
|
||||||
delegateRoot.icon,
|
} else if (delegateRoot.settingsCommand) {
|
||||||
delegateRoot.text,
|
NanoShell.StartupFeedback.open(
|
||||||
icon.Kirigami.ScenePosition.x + icon.width/2,
|
delegateRoot.icon,
|
||||||
icon.Kirigami.ScenePosition.y + icon.height/2,
|
delegateRoot.text,
|
||||||
Math.min(icon.width, icon.height))
|
icon.Kirigami.ScenePosition.x + icon.width/2,
|
||||||
plasmoid.nativeInterface.executeCommand(delegateRoot.settingsCommand);
|
icon.Kirigami.ScenePosition.y + icon.height/2,
|
||||||
root.closeRequested();
|
Math.min(icon.width, icon.height))
|
||||||
}
|
plasmoid.nativeInterface.executeCommand(delegateRoot.settingsCommand);
|
||||||
|
root.closeRequested();
|
||||||
}
|
}
|
||||||
onPressAndHold: {
|
}
|
||||||
if (delegateRoot.settingsCommand) {
|
onPressAndHold: {
|
||||||
NanoShell.StartupFeedback.open(
|
if (delegateRoot.settingsCommand) {
|
||||||
delegateRoot.icon,
|
NanoShell.StartupFeedback.open(
|
||||||
delegateRoot.text,
|
delegateRoot.icon,
|
||||||
icon.Kirigami.ScenePosition.x + icon.width/2,
|
delegateRoot.text,
|
||||||
icon.Kirigami.ScenePosition.y + icon.height/2,
|
icon.Kirigami.ScenePosition.x + icon.width/2,
|
||||||
Math.min(icon.width, icon.height))
|
icon.Kirigami.ScenePosition.y + icon.height/2,
|
||||||
closeRequested();
|
Math.min(icon.width, icon.height))
|
||||||
plasmoid.nativeInterface.executeCommand(delegateRoot.settingsCommand);
|
closeRequested();
|
||||||
} else if (delegateRoot.toggleFunction) {
|
plasmoid.nativeInterface.executeCommand(delegateRoot.settingsCommand);
|
||||||
root[delegateRoot.toggleFunction]();
|
} else if (delegateRoot.toggleFunction) {
|
||||||
}
|
root[delegateRoot.toggleFunction]();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +136,7 @@ ColumnLayout {
|
||||||
plasmoid.nativeInterface.executeCommand(delegateRoot.settingsCommand);
|
plasmoid.nativeInterface.executeCommand(delegateRoot.settingsCommand);
|
||||||
closeRequested();
|
closeRequested();
|
||||||
} else if (delegateRoot.toggleFunction) {
|
} else if (delegateRoot.toggleFunction) {
|
||||||
root[delegateRoot.toggleFunction]();
|
settingsModel[delegateRoot.toggleFunction]();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,385 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2015 Marco Martin <notmart@gmail.com>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.14
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import QtQuick.Window 2.2
|
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
|
||||||
import org.kde.plasma.components 2.0 as PlasmaComponents
|
|
||||||
import org.kde.plasma.networkmanagement 0.2 as PlasmaNM
|
|
||||||
import org.kde.bluezqt 1.0 as BluezQt
|
|
||||||
import org.kde.colorcorrect 0.1 as CC
|
|
||||||
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
|
|
||||||
|
|
||||||
import org.kde.plasma.components 3.0 as PC3
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
implicitWidth: column.implicitWidth + units.smallSpacing * 6
|
|
||||||
implicitHeight: column.implicitHeight + units.smallSpacing * 2
|
|
||||||
|
|
||||||
signal closeRequested
|
|
||||||
signal closed
|
|
||||||
|
|
||||||
property bool expandedMode: parentSlidingPanel.wideScreen
|
|
||||||
readonly property real expandedRatio: expandedMode ? 1 : Math.max(0, Math.min(1, (parentSlidingPanel.offset - firstRowHeight - parentSlidingPanel.headerHeight) / otherRowsHeight))
|
|
||||||
|
|
||||||
readonly property real topEmptyAreaHeight: parentSlidingPanel.userInteracting
|
|
||||||
? (root.height - collapsedHeight) * (1 - expandedRatio)
|
|
||||||
: (expandedMode ? 0 : root.height - collapsedHeight)
|
|
||||||
|
|
||||||
readonly property real collapsedHeight: firstRowHeight + PlasmaCore.Units.smallSpacing * 2
|
|
||||||
readonly property real firstRowHeight: flow.children[0].height
|
|
||||||
readonly property real otherRowsHeight: column.height - firstRowHeight
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root.parentSlidingPanel
|
|
||||||
function onUserInteractingChanged() {
|
|
||||||
if (!parentSlidingPanel.userInteracting) {
|
|
||||||
if (root.expandedRatio > 0.7) {
|
|
||||||
root.expandedMode = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
property bool screenshotRequested: false
|
|
||||||
|
|
||||||
property NanoShell.FullScreenOverlay parentSlidingPanel
|
|
||||||
property Item background
|
|
||||||
onBackgroundChanged: {
|
|
||||||
background.parent = backgroundParent
|
|
||||||
background.anchors.fill = backgroundParent
|
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaNM.Handler {
|
|
||||||
id: nmHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaNM.EnabledConnections {
|
|
||||||
id: enabledConnections
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root.Window.window
|
|
||||||
function onVisibilityChanged() {
|
|
||||||
root.expandedMode = parentSlidingPanel.wideScreen;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: BluezQt.Manager
|
|
||||||
|
|
||||||
function onBluetoothOperationalChanged() {
|
|
||||||
settingsModel.get(2).enabled = BluezQt.Manager.bluetoothOperational
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleAirplane() {
|
|
||||||
print("toggle airplane mode")
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleTorch() {
|
|
||||||
plasmoid.nativeInterface.toggleTorch()
|
|
||||||
settingsModel.get(6).enabled = plasmoid.nativeInterface.torchEnabled
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleWifi() {
|
|
||||||
nmHandler.enableWireless(!enabledConnections.wirelessEnabled)
|
|
||||||
settingsModel.get(1).enabled = !enabledConnections.wirelessEnabled
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleWwan() {
|
|
||||||
nmHandler.enableWwan(!enabledConnections.wwanEnabled)
|
|
||||||
settingsModel.get(3).enabled = !enabledConnections.wwanEnabled
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleRotation() {
|
|
||||||
const enable = !plasmoid.nativeInterface.autoRotateEnabled
|
|
||||||
plasmoid.nativeInterface.autoRotateEnabled = enable
|
|
||||||
settingsModel.get(9).enabled = enable
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleBluetooth() {
|
|
||||||
var enable = !BluezQt.Manager.bluetoothOperational;
|
|
||||||
BluezQt.Manager.bluetoothBlocked = !enable;
|
|
||||||
|
|
||||||
for (var i = 0; i < BluezQt.Manager.adapters.length; ++i) {
|
|
||||||
var adapter = BluezQt.Manager.adapters[i];
|
|
||||||
adapter.powered = enable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleNightColor() {
|
|
||||||
if (compositorAdaptor.active) {
|
|
||||||
compositorAdaptor.activeStaged = false;
|
|
||||||
} else {
|
|
||||||
compositorAdaptor.activeStaged = true;
|
|
||||||
compositorAdaptor.modeStaged = 3; // always on
|
|
||||||
}
|
|
||||||
compositorAdaptor.sendConfigurationAll();
|
|
||||||
settingsModel.get(10).enabled = compositorAdaptor.active;
|
|
||||||
}
|
|
||||||
|
|
||||||
function requestShutdown() {
|
|
||||||
print("Shutdown requested, depends on ksmserver running");
|
|
||||||
var service = pmSource.serviceForSource("PowerDevil");
|
|
||||||
//note the strange camelCasing is intentional
|
|
||||||
var operation = service.operationDescription("requestShutDown");
|
|
||||||
return service.startOperationCall(operation);
|
|
||||||
}
|
|
||||||
|
|
||||||
signal plasmoidTriggered(var applet, var id)
|
|
||||||
Layout.minimumHeight: flow.implicitHeight + units.largeSpacing*2
|
|
||||||
|
|
||||||
property int screenBrightness
|
|
||||||
property bool disableBrightnessUpdate: true
|
|
||||||
readonly property int maximumScreenBrightness: pmSource.data["PowerDevil"] ? pmSource.data["PowerDevil"]["Maximum Screen Brightness"] || 0 : 0
|
|
||||||
|
|
||||||
onScreenBrightnessChanged: {
|
|
||||||
if(!disableBrightnessUpdate) {
|
|
||||||
var service = pmSource.serviceForSource("PowerDevil");
|
|
||||||
var operation = service.operationDescription("setBrightness");
|
|
||||||
operation.brightness = screenBrightness;
|
|
||||||
operation.silent = true
|
|
||||||
service.startOperationCall(operation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function requestScreenshot() {
|
|
||||||
screenshotRequested = true;
|
|
||||||
root.closeRequested();
|
|
||||||
}
|
|
||||||
|
|
||||||
onClosed: {
|
|
||||||
if (screenshotRequested) {
|
|
||||||
plasmoid.nativeInterface.takeScreenshot();
|
|
||||||
screenshotRequested = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaCore.DataSource {
|
|
||||||
id: pmSource
|
|
||||||
engine: "powermanagement"
|
|
||||||
connectedSources: ["PowerDevil"]
|
|
||||||
onSourceAdded: {
|
|
||||||
if (source === "PowerDevil") {
|
|
||||||
disconnectSource(source);
|
|
||||||
connectSource(source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onDataChanged: {
|
|
||||||
disableBrightnessUpdate = true;
|
|
||||||
root.screenBrightness = pmSource.data["PowerDevil"]["Screen Brightness"];
|
|
||||||
disableBrightnessUpdate = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// night color
|
|
||||||
CC.CompositorAdaptor {
|
|
||||||
id: compositorAdaptor
|
|
||||||
}
|
|
||||||
|
|
||||||
//HACK: make the list know about the applet delegate which is a qtobject
|
|
||||||
QtObject {
|
|
||||||
id: nullApplet
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
|
||||||
//NOTE: add all in javascript as the static decl of listelements can't have scripts
|
|
||||||
settingsModel.append({
|
|
||||||
"text": i18n("Settings"),
|
|
||||||
"icon": "configure",
|
|
||||||
"enabled": false,
|
|
||||||
"settingsCommand": "plasma-settings",
|
|
||||||
"toggleFunction": "",
|
|
||||||
"applet": null
|
|
||||||
});
|
|
||||||
settingsModel.append({
|
|
||||||
"text": i18n("Wifi"),
|
|
||||||
"icon": "network-wireless-signal",
|
|
||||||
"settingsCommand": "plasma-settings -m kcm_mobile_wifi",
|
|
||||||
"toggleFunction": "toggleWifi",
|
|
||||||
"enabled": enabledConnections.wirelessEnabled,
|
|
||||||
"applet": null
|
|
||||||
});
|
|
||||||
settingsModel.append({
|
|
||||||
"text": i18n("Bluetooth"),
|
|
||||||
"icon": "network-bluetooth",
|
|
||||||
"settingsCommand": "plasma-settings -m kcm_bluetooth",
|
|
||||||
"toggleFunction": "toggleBluetooth",
|
|
||||||
"delegate": "",
|
|
||||||
"enabled": BluezQt.Manager.bluetoothOperational,
|
|
||||||
"applet": null
|
|
||||||
});
|
|
||||||
settingsModel.append({
|
|
||||||
"text": i18n("Mobile Data"),
|
|
||||||
"icon": "network-modem",
|
|
||||||
"settingsCommand": "plasma-settings -m kcm_mobile_broadband",
|
|
||||||
"toggleFunction": "toggleWwan",
|
|
||||||
"enabled": enabledConnections.wwanEnabled,
|
|
||||||
"applet": null
|
|
||||||
});
|
|
||||||
settingsModel.append({
|
|
||||||
"text": i18n("Battery"),
|
|
||||||
"icon": "battery-full",
|
|
||||||
"enabled": false,
|
|
||||||
"settingsCommand": "plasma-settings -m kcm_mobile_power",
|
|
||||||
"toggleFunction": "",
|
|
||||||
"applet": null
|
|
||||||
});
|
|
||||||
settingsModel.append({
|
|
||||||
"text": i18n("Sound"),
|
|
||||||
"icon": "audio-speakers-symbolic",
|
|
||||||
"enabled": false,
|
|
||||||
"settingsCommand": "plasma-settings -m kcm_pulseaudio",
|
|
||||||
"toggleFunction": "",
|
|
||||||
"applet": null
|
|
||||||
});
|
|
||||||
settingsModel.append({
|
|
||||||
"text": i18n("Flashlight"),
|
|
||||||
"icon": "flashlight-on",
|
|
||||||
"enabled": plasmoid.nativeInterface.torchEnabled,
|
|
||||||
"settingsCommand": "",
|
|
||||||
"toggleFunction": "toggleTorch",
|
|
||||||
"applet": null
|
|
||||||
});
|
|
||||||
settingsModel.append({
|
|
||||||
"text": i18n("Location"),
|
|
||||||
"icon": "gps",
|
|
||||||
"enabled": false,
|
|
||||||
"settingsCommand": "",
|
|
||||||
"applet": null
|
|
||||||
});
|
|
||||||
settingsModel.append({
|
|
||||||
"text": i18n("Screenshot"),
|
|
||||||
"icon": "spectacle",
|
|
||||||
"enabled": false,
|
|
||||||
"settingsCommand": "",
|
|
||||||
"toggleFunction": "requestScreenshot",
|
|
||||||
"applet": null
|
|
||||||
});
|
|
||||||
settingsModel.append({
|
|
||||||
"text": i18n("Auto-rotate"),
|
|
||||||
"icon": "rotation-allowed",
|
|
||||||
"enabled": plasmoid.nativeInterface.autoRotateEnabled,
|
|
||||||
"settingsCommand": "",
|
|
||||||
"toggleFunction": "toggleRotation",
|
|
||||||
"applet": null
|
|
||||||
});
|
|
||||||
settingsModel.append({
|
|
||||||
"text": i18n("Night Color"),
|
|
||||||
"icon": "redshift-status-on",
|
|
||||||
"enabled": compositorAdaptor.active,
|
|
||||||
"settingsCommand": "", // change once night color kcm is added
|
|
||||||
"toggleFunction": "toggleNightColor",
|
|
||||||
"applet": null
|
|
||||||
});
|
|
||||||
|
|
||||||
brightnessSlider.moved.connect(function() {
|
|
||||||
root.screenBrightness = brightnessSlider.value;
|
|
||||||
});
|
|
||||||
disableBrightnessUpdate = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: settingsModel
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: backgroundParent
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
bottom: parent.bottom
|
|
||||||
}
|
|
||||||
height: firstRowHeight + otherRowsHeight * root.expandedRatio
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors {
|
|
||||||
fill: parent
|
|
||||||
margins: units.smallSpacing
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property real cellSizeHint: units.iconSizes.large + units.smallSpacing * 6
|
|
||||||
readonly property real columnWidth: Math.floor(width / Math.floor(width / cellSizeHint))
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: column
|
|
||||||
anchors.fill: parent
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Flow {
|
|
||||||
id: flow
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: units.smallSpacing + (units.largeSpacing - units.smallSpacing) * root.expandedRatio
|
|
||||||
Layout.rightMargin: units.largeSpacing
|
|
||||||
Layout.topMargin: units.largeSpacing
|
|
||||||
|
|
||||||
readonly property real cellSizeHint: units.iconSizes.large + units.smallSpacing * 6
|
|
||||||
readonly property real columnWidth: Math.floor(width / Math.floor(width / cellSizeHint))
|
|
||||||
spacing: 0
|
|
||||||
Repeater {
|
|
||||||
model: settingsModel
|
|
||||||
delegate: Delegate {
|
|
||||||
id: delegateItem
|
|
||||||
|
|
||||||
//FIXME: why this is needed?
|
|
||||||
width: flow.columnWidth - (y > 0 ? 0 : (flow.columnWidth/Math.floor(flow.width / flow.columnWidth)) * (1 - root.expandedRatio))
|
|
||||||
height: item ? item.implicitHeight : 0
|
|
||||||
|
|
||||||
labelOpacity: y > 0 ? 1 : root.expandedRatio
|
|
||||||
|
|
||||||
opacity: y <= 0 ? 1 : root.expandedRatio
|
|
||||||
transform: Translate {
|
|
||||||
y: otherRowsHeight * (1 - root.expandedRatio)
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: delegateItem
|
|
||||||
onCloseRequested: root.closeRequested();
|
|
||||||
}
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
onClosed: delegateItem.panelClosed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
move: Transition {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: units.shortDuration
|
|
||||||
//Here a linear easing actually looks better
|
|
||||||
//easing.type: Easing.InOutQuad
|
|
||||||
properties: "x,y"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BrightnessItem {
|
|
||||||
id: brightnessSlider
|
|
||||||
|
|
||||||
Layout.bottomMargin: units.largeSpacing
|
|
||||||
Layout.leftMargin: units.largeSpacing
|
|
||||||
Layout.rightMargin: units.largeSpacing
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
value: root.screenBrightness
|
|
||||||
maximumValue: root.maximumScreenBrightness
|
|
||||||
opacity: root.expandedRatio
|
|
||||||
transform: Translate {
|
|
||||||
y: otherRowsHeight * (1 - root.expandedRatio)
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
onScreenBrightnessChanged: brightnessSlider.value = root.screenBrightness
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,190 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015 Marco Martin <notmart@gmail.com>
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.14
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
import QtQuick.Window 2.2
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
|
import org.kde.plasma.networkmanagement 0.2 as PlasmaNM
|
||||||
|
import org.kde.bluezqt 1.0 as BluezQt
|
||||||
|
import org.kde.colorcorrect 0.1 as CC
|
||||||
|
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
|
||||||
|
|
||||||
|
import org.kde.plasma.components 3.0 as PC3
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property alias model: settingsModel
|
||||||
|
property bool screenshotRequested: false
|
||||||
|
|
||||||
|
signal panelClosed()
|
||||||
|
|
||||||
|
onPanelClosed: {
|
||||||
|
if (screenshotRequested) {
|
||||||
|
plasmoid.nativeInterface.takeScreenshot();
|
||||||
|
screenshotRequested = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: settingsModel
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaNM.Handler {
|
||||||
|
id: nmHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaNM.EnabledConnections {
|
||||||
|
id: enabledConnections
|
||||||
|
}
|
||||||
|
|
||||||
|
// night color
|
||||||
|
CC.CompositorAdaptor {
|
||||||
|
id: compositorAdaptor
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: BluezQt.Manager
|
||||||
|
function onBluetoothOperationalChanged() {
|
||||||
|
settingsModel.get(2).enabled = BluezQt.Manager.bluetoothOperational
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleAirplane() {
|
||||||
|
print("toggle airplane mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleTorch() {
|
||||||
|
plasmoid.nativeInterface.toggleTorch()
|
||||||
|
settingsModel.get(6).enabled = plasmoid.nativeInterface.torchEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleWifi() {
|
||||||
|
nmHandler.enableWireless(!enabledConnections.wirelessEnabled)
|
||||||
|
settingsModel.get(1).enabled = !enabledConnections.wirelessEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleWwan() {
|
||||||
|
nmHandler.enableWwan(!enabledConnections.wwanEnabled)
|
||||||
|
settingsModel.get(3).enabled = !enabledConnections.wwanEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleRotation() {
|
||||||
|
const enable = !plasmoid.nativeInterface.autoRotateEnabled
|
||||||
|
plasmoid.nativeInterface.autoRotateEnabled = enable
|
||||||
|
settingsModel.get(9).enabled = enable
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleBluetooth() {
|
||||||
|
var enable = !BluezQt.Manager.bluetoothOperational;
|
||||||
|
BluezQt.Manager.bluetoothBlocked = !enable;
|
||||||
|
|
||||||
|
for (var i = 0; i < BluezQt.Manager.adapters.length; ++i) {
|
||||||
|
var adapter = BluezQt.Manager.adapters[i];
|
||||||
|
adapter.powered = enable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleNightColor() {
|
||||||
|
if (compositorAdaptor.active) {
|
||||||
|
compositorAdaptor.activeStaged = false;
|
||||||
|
} else {
|
||||||
|
compositorAdaptor.activeStaged = true;
|
||||||
|
compositorAdaptor.modeStaged = 3; // always on
|
||||||
|
}
|
||||||
|
compositorAdaptor.sendConfigurationAll();
|
||||||
|
settingsModel.get(10).enabled = compositorAdaptor.active;
|
||||||
|
}
|
||||||
|
|
||||||
|
// components needed for quick settings
|
||||||
|
function requestScreenshot() {
|
||||||
|
screenshotRequested = true;
|
||||||
|
root.closeRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize quick settings
|
||||||
|
Component.onCompleted: {
|
||||||
|
//NOTE: add all in javascript as the static decl of listelements can't have scripts
|
||||||
|
settingsModel.append({
|
||||||
|
"text": i18n("Settings"),
|
||||||
|
"icon": "configure",
|
||||||
|
"enabled": false,
|
||||||
|
"settingsCommand": "plasma-settings",
|
||||||
|
"toggleFunction": ""
|
||||||
|
});
|
||||||
|
settingsModel.append({
|
||||||
|
"text": i18n("Wifi"),
|
||||||
|
"icon": "network-wireless-signal",
|
||||||
|
"settingsCommand": "plasma-settings -m kcm_mobile_wifi",
|
||||||
|
"toggleFunction": "toggleWifi",
|
||||||
|
"enabled": enabledConnections.wirelessEnabled
|
||||||
|
});
|
||||||
|
settingsModel.append({
|
||||||
|
"text": i18n("Bluetooth"),
|
||||||
|
"icon": "network-bluetooth",
|
||||||
|
"settingsCommand": "plasma-settings -m kcm_bluetooth",
|
||||||
|
"toggleFunction": "toggleBluetooth",
|
||||||
|
"delegate": "",
|
||||||
|
"enabled": BluezQt.Manager.bluetoothOperational
|
||||||
|
});
|
||||||
|
settingsModel.append({
|
||||||
|
"text": i18n("Mobile Data"),
|
||||||
|
"icon": "network-modem",
|
||||||
|
"settingsCommand": "plasma-settings -m kcm_mobile_broadband",
|
||||||
|
"toggleFunction": "toggleWwan",
|
||||||
|
"enabled": enabledConnections.wwanEnabled
|
||||||
|
});
|
||||||
|
settingsModel.append({
|
||||||
|
"text": i18n("Battery"),
|
||||||
|
"icon": "battery-full",
|
||||||
|
"enabled": false,
|
||||||
|
"settingsCommand": "plasma-settings -m kcm_mobile_power",
|
||||||
|
"toggleFunction": ""
|
||||||
|
});
|
||||||
|
settingsModel.append({
|
||||||
|
"text": i18n("Sound"),
|
||||||
|
"icon": "audio-speakers-symbolic",
|
||||||
|
"enabled": false,
|
||||||
|
"settingsCommand": "plasma-settings -m kcm_pulseaudio",
|
||||||
|
"toggleFunction": ""
|
||||||
|
});
|
||||||
|
settingsModel.append({
|
||||||
|
"text": i18n("Flashlight"),
|
||||||
|
"icon": "flashlight-on",
|
||||||
|
"enabled": plasmoid.nativeInterface.torchEnabled,
|
||||||
|
"settingsCommand": "",
|
||||||
|
"toggleFunction": "toggleTorch"
|
||||||
|
});
|
||||||
|
settingsModel.append({
|
||||||
|
"text": i18n("Location"),
|
||||||
|
"icon": "gps",
|
||||||
|
"enabled": false,
|
||||||
|
"settingsCommand": ""
|
||||||
|
});
|
||||||
|
settingsModel.append({
|
||||||
|
"text": i18n("Screenshot"),
|
||||||
|
"icon": "spectacle",
|
||||||
|
"enabled": false,
|
||||||
|
"settingsCommand": "",
|
||||||
|
"toggleFunction": "requestScreenshot"
|
||||||
|
});
|
||||||
|
settingsModel.append({
|
||||||
|
"text": i18n("Auto-rotate"),
|
||||||
|
"icon": "rotation-allowed",
|
||||||
|
"enabled": plasmoid.nativeInterface.autoRotateEnabled,
|
||||||
|
"settingsCommand": "",
|
||||||
|
"toggleFunction": "toggleRotation"
|
||||||
|
});
|
||||||
|
settingsModel.append({
|
||||||
|
"text": i18n("Night Color"),
|
||||||
|
"icon": "redshift-status-on",
|
||||||
|
"enabled": compositorAdaptor.active,
|
||||||
|
"settingsCommand": "", // change once night color kcm is added
|
||||||
|
"toggleFunction": "toggleNightColor"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,226 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015 Marco Martin <notmart@gmail.com>
|
||||||
|
* SPDX-FileCopyrightText: 2021 Devin Lin <espidev@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.14
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
import QtQuick.Window 2.2
|
||||||
|
import QtGraphicalEffects 1.12
|
||||||
|
import org.kde.kirigami 2.12 as Kirigami
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
|
import org.kde.plasma.networkmanagement 0.2 as PlasmaNM
|
||||||
|
import org.kde.bluezqt 1.0 as BluezQt
|
||||||
|
import org.kde.colorcorrect 0.1 as CC
|
||||||
|
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
|
||||||
|
|
||||||
|
import org.kde.plasma.components 3.0 as PC3
|
||||||
|
|
||||||
|
import "../"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
implicitWidth: column.implicitWidth + PlasmaCore.Units.smallSpacing * 6
|
||||||
|
implicitHeight: column.implicitHeight + PlasmaCore.Units.smallSpacing * 2
|
||||||
|
|
||||||
|
signal closeRequested
|
||||||
|
signal closed
|
||||||
|
|
||||||
|
property bool expandedMode: parentSlidingPanel.wideScreen
|
||||||
|
readonly property real expandedRatio: expandedMode ? 1 : Math.max(0, Math.min(1, (parentSlidingPanel.offset - (parentSlidingPanel.topPanelHeight + firstRowHeight) - parentSlidingPanel.topPanelHeight) / otherRowsHeight + 0.05)) // HACK: add 0.05 to prevent jumping since this height isn't exact
|
||||||
|
|
||||||
|
readonly property real topEmptyAreaHeight: parentSlidingPanel.userInteracting
|
||||||
|
? (root.height - collapsedHeight) * (1 - expandedRatio)
|
||||||
|
: (expandedMode ? 0 : root.height - collapsedHeight)
|
||||||
|
|
||||||
|
readonly property real collapsedHeight: parentSlidingPanel.topPanelHeight + firstRowHeight + PlasmaCore.Units.smallSpacing * 2
|
||||||
|
readonly property real firstRowHeight: flow.children[0].height
|
||||||
|
readonly property real otherRowsHeight: column.implicitHeight - firstRowHeight - parentSlidingPanel.topPanelHeight
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root.parentSlidingPanel
|
||||||
|
function onUserInteractingChanged() {
|
||||||
|
if (!parentSlidingPanel.userInteracting) {
|
||||||
|
if (root.expandedRatio > 0.7) {
|
||||||
|
root.expandedMode = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property NanoShell.FullScreenOverlay parentSlidingPanel
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root.Window.window
|
||||||
|
function onVisibilityChanged() {
|
||||||
|
root.expandedMode = parentSlidingPanel.wideScreen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signal plasmoidTriggered(var applet, var id)
|
||||||
|
Layout.minimumHeight: flow.implicitHeight + units.largeSpacing*2
|
||||||
|
|
||||||
|
onClosed: quickSettingsModel.panelClosed()
|
||||||
|
|
||||||
|
property QuickSettingsModel quickSettingsModel: QuickSettingsModel {}
|
||||||
|
|
||||||
|
// shadow below panel (only if not widescreen)
|
||||||
|
Rectangle {
|
||||||
|
visible: !parentSlidingPanel.wideScreen
|
||||||
|
anchors.bottom: background.bottom
|
||||||
|
anchors.left: background.left
|
||||||
|
anchors.right: background.right
|
||||||
|
height: PlasmaCore.Units.gridUnit
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop {
|
||||||
|
position: 0.0
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.05)
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1.0
|
||||||
|
color: "transparent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// shadow for bottom bar
|
||||||
|
RectangularGlow {
|
||||||
|
z: 1
|
||||||
|
anchors.topMargin: 1
|
||||||
|
anchors.fill: bottomBar
|
||||||
|
cached: true
|
||||||
|
glowRadius: 4
|
||||||
|
spread: 0.2
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.1)
|
||||||
|
}
|
||||||
|
// shadow for whole panel (only if widescreen)
|
||||||
|
RectangularGlow {
|
||||||
|
visible: parentSlidingPanel.wideScreen
|
||||||
|
anchors.topMargin: 1
|
||||||
|
anchors.top: background.top
|
||||||
|
anchors.left: background.left
|
||||||
|
anchors.right: background.right
|
||||||
|
anchors.bottom: bottomBar.bottom
|
||||||
|
cached: true
|
||||||
|
glowRadius: 4
|
||||||
|
spread: 0.2
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// bottom "handle bar"
|
||||||
|
Rectangle {
|
||||||
|
id: bottomBar
|
||||||
|
anchors.top: background.bottom
|
||||||
|
anchors.left: background.left
|
||||||
|
anchors.right: background.right
|
||||||
|
color: PlasmaCore.Theme.backgroundColor
|
||||||
|
height: Math.round(PlasmaCore.Units.gridUnit * 1.3)
|
||||||
|
z: 1
|
||||||
|
|
||||||
|
Kirigami.Icon {
|
||||||
|
visible: !parentSlidingPanel.wideScreen
|
||||||
|
color: PlasmaCore.Theme.disabledTextColor
|
||||||
|
source: expandedRatio >= 1 ? "go-up-symbolic" : "go-down-symbolic"
|
||||||
|
implicitWidth: PlasmaCore.Units.gridUnit
|
||||||
|
implicitHeight: width
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: background
|
||||||
|
color: PlasmaCore.Theme.backgroundColor
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: column
|
||||||
|
anchors.leftMargin: PlasmaCore.Units.smallSpacing
|
||||||
|
anchors.rightMargin: PlasmaCore.Units.smallSpacing
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
spacing: 0
|
||||||
|
clip: expandedRatio > 0 && expandedRatio < 1 // only clip when necessary to improve performance
|
||||||
|
|
||||||
|
readonly property real cellSizeHint: units.iconSizes.large + units.smallSpacing * 6
|
||||||
|
readonly property real columnWidth: Math.floor(width / Math.floor(width / cellSizeHint))
|
||||||
|
|
||||||
|
IndicatorsRow {
|
||||||
|
id: indicatorsRow
|
||||||
|
z: 1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: parentSlidingPanel.topPanelHeight
|
||||||
|
colorGroup: PlasmaCore.Theme.NormalColorGroup
|
||||||
|
backgroundColor: "transparent"
|
||||||
|
showGradientBackground: false
|
||||||
|
showDropShadow: false
|
||||||
|
transform: Translate {
|
||||||
|
y: otherRowsHeight * (1 - root.expandedRatio) - PlasmaCore.Units.smallSpacing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Flow {
|
||||||
|
id: flow
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: units.smallSpacing + (units.largeSpacing - units.smallSpacing) * root.expandedRatio
|
||||||
|
Layout.rightMargin: units.smallSpacing + (units.largeSpacing - units.smallSpacing) * root.expandedRatio
|
||||||
|
Layout.topMargin: units.largeSpacing
|
||||||
|
|
||||||
|
readonly property real cellSizeHint: units.iconSizes.large + units.smallSpacing * 6
|
||||||
|
readonly property real columns: Math.floor(width / cellSizeHint)
|
||||||
|
readonly property real columnsWhenCollapsed: 1.05 // .05 to account for the fact that we have an overshoot on the panel on first flick, we don't want the movement to be jarring
|
||||||
|
readonly property real columnWidth: Math.floor(width / (columns + (columnsWhenCollapsed - columnsWhenCollapsed * root.expandedRatio)))
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
Repeater {
|
||||||
|
model: quickSettingsModel.model
|
||||||
|
delegate: Delegate {
|
||||||
|
id: delegateItem
|
||||||
|
settingsModel: quickSettingsModel
|
||||||
|
width: flow.columnWidth
|
||||||
|
|
||||||
|
labelOpacity: y > 0 ? 1 : root.expandedRatio
|
||||||
|
opacity: y <= 0 ? 1 : root.expandedRatio
|
||||||
|
transform: Translate {
|
||||||
|
y: otherRowsHeight * (1 - root.expandedRatio) - PlasmaCore.Units.smallSpacing * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: delegateItem
|
||||||
|
onCloseRequested: root.closeRequested();
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
onClosed: delegateItem.panelClosed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
move: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: units.shortDuration
|
||||||
|
easing.type: Easing.Linear
|
||||||
|
properties: "x,y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BrightnessItem {
|
||||||
|
id: brightnessSlider
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.topMargin: units.smallSpacing
|
||||||
|
Layout.bottomMargin: units.smallSpacing
|
||||||
|
Layout.leftMargin: units.largeSpacing
|
||||||
|
Layout.rightMargin: units.largeSpacing
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
opacity: root.expandedRatio
|
||||||
|
transform: Translate {
|
||||||
|
y: otherRowsHeight * (1 - root.expandedRatio) - PlasmaCore.Units.smallSpacing * 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue