Compare commits

..

11 Commits

Author SHA1 Message Date
83aa943fd9 added contextmenu and hide tray icon 2024-06-08 18:41:43 +02:00
3a1a5588d4 remove fullrepresentation 2024-06-08 18:41:11 +02:00
8b68977425 wrong color 2024-06-07 16:33:19 +02:00
c1dae41baa update readme 2024-06-07 02:08:19 +02:00
6e47175625 bring back config 2024-06-07 02:05:50 +02:00
b2e7b948fe irgendwas mit json 2024-06-07 01:56:43 +02:00
6290a78666 plasma6 alpha 2024-03-07 12:44:01 +01:00
4adea966fa critical notification & bugfix 2024-01-25 16:53:07 +01:00
d821e5b5c0 notifications! 2024-01-25 16:21:39 +01:00
f3529afeb1 debug mode 2024-01-22 03:08:31 +01:00
b15a5946a7 fix 100% charge lol 2024-01-22 03:08:25 +01:00
10 changed files with 320 additions and 132 deletions

View File

@ -2,25 +2,25 @@
## Requirements
- [HeadsetControl](https://github.com/Sapd/HeadsetControl)
- [HeadsetControl](https://github.com/Sapd/HeadsetControl) v3.0.0 or newer
## Install
```
git clone https://git.lat/Flummi/headsetcontrol-battery-widget.git
cd headsetcontrol-battery-widget
kpackagetool5 -t Plasma/Applet --install ./package
kpackagetool6 -t Plasma/Applet --install ./package
```
## Uninstall
```
kpackagetool5 -t Plasma/Applet --remove org.kde.plasma.headsetcontrol-battery-widget
kpackagetool6 -t Plasma/Applet --remove org.kde.plasma.headsetcontrol-battery-widget
```
## Development
```
cd headsetcontrol-battery-widget
kpackagetool5 -t Plasma/Applet --upgrade ./package ; systemctl --user restart plasma-plasmashell
kpackagetool6 -t Plasma/Applet --upgrade ./package ; systemctl --user restart plasma-plasmashell
```

View File

@ -1,10 +1,15 @@
import QtQuick 2.0
import org.kde.plasma.configuration 2.0
import QtQuick
import org.kde.plasma.configuration
ConfigModel {
ConfigCategory {
name: i18n("General")
icon: "configure"
source: "configGeneral.qml"
source: "config/general.qml"
}
ConfigCategory {
name: i18n("Debug")
icon: "cab_view"
source: "config/debug.qml"
}
}

View File

@ -12,7 +12,6 @@
<entry name="batteryheight" type="Int">
<default>8</default>
</entry>
<entry name="colorEmpty" type="String">
<default>#ff0000</default>
</entry>
@ -22,5 +21,20 @@
<entry name="colorFull" type="String">
<default>#008800</default>
</entry>
<entry name="batteryThreshold" type="Int">
<default>10</default>
</entry>
<entry name="notifications" type="Bool">
<default>true</default>
</entry>
<entry name="debug_active" type="Bool">
<default>false</default>
</entry>
<entry name="debug_charge" type="Int">
<default>0</default>
</entry>
</group>
</kcfg>

View File

@ -1,26 +1,20 @@
import QtQuick 2.15
import QtQuick.Layouts 1.3
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.kirigami 2.14 as Kirigami
import QtQuick
import QtQuick.Layouts
import org.kde.plasma.plasmoid
import org.kde.kirigami as Kirigami
import "./lib/helper.js" as Helper
Item {
Layout.minimumWidth: units.iconSizes.medium
Layout.alignment: Qt.AlignHCenter
Rectangle { // battery
id: container
anchors.fill: parent
anchors.rightMargin: 2
anchors.rightMargin: 1
anchors.topMargin: 10 - batteryheight
anchors.bottomMargin: 10 - batteryheight
color: "transparent"
border.color: PlasmaCore.Theme.textColor
border.color: Kirigami.Theme.textColor
radius: 4
Plasmoid.toolTipMainText: "battery level: " + Helper.batteryLevel(batteryPercent)
Plasmoid.toolTipSubText: "polling rate: " + pollingrate + " seconds"
Item {
anchors.fill: parent
@ -29,7 +23,7 @@ Item {
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
color: Helper.interpolateColor(parseFloat("." + batteryPercent), [ colorEmpty, colorHalf, colorFull ])
color: Helper.interpolateColor(batteryPercent / 100, [ colorEmpty, colorHalf, colorFull ])
width: parent.width * Math.max(0, Math.min(batteryPercent, 100)) / 100
}
Kirigami.Icon { // headphones icon
@ -38,8 +32,8 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 1
anchors.bottomMargin: 1
source: Helper.batteryIcon(batteryPercent)
color: batteryPercent == -1 ? colorFull : PlasmaCore.Theme.textColor
source: Helper.batteryIcon(batteryStatus)
color: batteryPercent == -1 ? colorEmpty : Kirigami.Theme.textColor
}
}
}
@ -51,13 +45,6 @@ Item {
radius: 4
height: parent.height / 3
width: 2
color: PlasmaCore.Theme.textColor
}
MouseArea {
anchors.fill: parent
onClicked: {
plasmoid.expanded = !plasmoid.expanded
}
color: Kirigami.Theme.textColor
}
}

View File

@ -1,44 +0,0 @@
import QtQuick 2.15
import QtQuick.Layouts 1.3
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.kirigami 2.14 as Kirigami
import "./lib/helper.js" as Helper
Item {
id: fullRep
Layout.preferredWidth: 250 * PlasmaCore.Units.devicePixelRatio
Layout.preferredHeight: 250 * PlasmaCore.Units.devicePixelRatio
Layout.minimumWidth: Layout.preferredWidth
Layout.maximumWidth: Layout.preferredWidth
Layout.minimumHeight: Layout.preferredHeight
Layout.maximumHeight: Layout.preferredHeight
clip: true
ColumnLayout {
id: wrapper
anchors.fill: parent
spacing: 0
RowLayout {
spacing: 0
Layout.fillWidth: true
ColumnLayout {
spacing: 0
// Items
Text {
text: "henlo"
color: PlasmaCore.Theme.textColor
}
}
}
Item {
Layout.fillHeight: true
}
}
}

View File

@ -0,0 +1,77 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components as PlasmaComponents
import org.kde.kirigami as Kirigami
import org.kde.kquickcontrols as KQControls
import org.kde.kcmutils as KCM
import "../lib/helper.js" as Helper
KCM.SimpleKCM {
id: root
property alias cfg_debug_active: debug_active.checked
property alias cfg_debug_charge: debug_charge.value
property bool debug_activeDefault
property int debug_chargeDefault
property int cfg_pollingrate
property int cfg_batteryheight
property string cfg_colorEmpty
property string cfg_colorHalf
property string cfg_colorFull
property bool cfg_notifications
property int cfg_batteryThreshold
property int cfg_pollingrateDefault
property int cfg_batteryheightDefault
property string cfg_colorEmptyDefault
property string cfg_colorHalfDefault
property string cfg_colorFullDefault
property bool cfg_notificationsDefault
property int cfg_batteryThresholdDefault
Kirigami.FormLayout {
anchors.fill: parent
wideMode: false
GridLayout {
columns: 3
rows: 2
rowSpacing: 10
// first row
Text {
text: "debug:"
color: PlasmaCore.Theme.textColor
}
PlasmaComponents.CheckBox {
id: debug_active
}
Text {
text: ""
}
// second row
Text {
text: "battery charge:"
color: PlasmaCore.Theme.textColor
}
Slider {
id: debug_charge
value: 0
from: 0
to: 100
stepSize: 1
}
Text {
text: cfg_debug_charge + "%"
color: PlasmaCore.Theme.textColor
}
}
}
}

View File

@ -1,14 +1,15 @@
import QtQuick 2.0
import QtQuick.Layouts 1.3
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import QtQuick.Controls 2.5 as QQC2
import org.kde.kirigami 2.4 as Kirigami
import org.kde.kquickcontrols 2.0 as KQControls
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components as PlasmaComponents
import org.kde.kirigami as Kirigami
import org.kde.kquickcontrols as KQControls
import org.kde.kcmutils as KCM
import "./lib/helper.js" as Helper
import "../lib/helper.js" as Helper
QQC2.Pane {
KCM.SimpleKCM {
id: root
property alias cfg_pollingrate: pollingrate.value
@ -16,6 +17,21 @@ QQC2.Pane {
property alias cfg_colorEmpty: colorEmpty.color
property alias cfg_colorHalf: colorHalf.color
property alias cfg_colorFull: colorFull.color
property alias cfg_notifications: notifications.checked
property alias cfg_batteryThreshold: batteryThreshold.value
property int cfg_pollingrateDefault
property int cfg_batteryheightDefault
property string cfg_colorEmptyDefault
property string cfg_colorHalfDefault
property string cfg_colorFullDefault
property bool cfg_notificationsDefault
property int cfg_batteryThresholdDefault
property bool cfg_debug_active
property int cfg_debug_charge
property bool cfg_debug_activeDefault
property int cfg_debug_chargeDefault
Kirigami.FormLayout {
anchors.fill: parent
@ -31,11 +47,11 @@ QQC2.Pane {
text: "polling rate:"
color: PlasmaCore.Theme.textColor
}
PlasmaComponents.Slider {
Slider {
id: pollingrate
value: 10
minimumValue: 2
maximumValue: 60
from: 2
to: 60
stepSize: 2
}
Text {
@ -48,11 +64,11 @@ QQC2.Pane {
text: "battery height:"
color: PlasmaCore.Theme.textColor
}
PlasmaComponents.Slider {
Slider {
id: batteryheight
value: 8.0
minimumValue: 1
maximumValue: 10
from: 1
to: 10
stepSize: 1
}
Text {
@ -157,5 +173,40 @@ QQC2.Pane {
color: Helper.interpolateColor( 1, [ cfg_colorEmpty.toString(), cfg_colorHalf.toString(), cfg_colorFull.toString() ])
}
}
GridLayout {
columns: 3
rows: 2
rowSpacing: 10
// first row
Text {
text: "notifications:"
color: PlasmaCore.Theme.textColor
}
PlasmaComponents.CheckBox {
id: notifications
}
Text {
text: ""
}
// second row
Text {
text: "battery threshold:"
color: PlasmaCore.Theme.textColor
}
Slider {
id: batteryThreshold
value: 10
from: 1
to: 50
stepSize: 1
}
Text {
text: cfg_batteryThreshold
color: PlasmaCore.Theme.textColor
}
}
}
}

View File

@ -1,12 +1,15 @@
const batteryLevel = batteryPercent => ({
"-2": "not connected",
"-1": "charging"
})[batteryPercent] ?? batteryPercent + "%";
const batteryLevel = (batteryStatus, batteryPercent) => ({
"BATTERY_UNAVAILABLE": "not connected",
"BATTERY_CHARGING": "charging (" + batteryPercent + "%)",
"HEADSET_UNAVAILABLE": "no headset connected"
})[batteryStatus] ?? batteryPercent + "%";
const batteryIcon = batteryPercent => ({
"-2": "action-unavailable",
"-1": "reload"
})[batteryPercent] ?? "audio-headphones-symbolic";
const batteryIcon = batteryStatus => ({
"BATTERY_UNAVAILABLE": "action-unavailable",
"BATTERY_AVAILABLE": "audio-headphones-symbolic",
"BATTERY_CHARGING": "freon-voltage-symbolic",
"HEADSET_UNAVAILABLE": "dialog-error"
})[batteryStatus] ?? "audio-headphones-symbolic";
const hex2rgb = (hex, h = hex.replace('#', '0x')) => ({ r: h >> 16 & 255, g: h >> 8 & 255, b: h & 255 });
const rgb2Hex = rgb => "#" + ((1 << 24) + (rgb.r << 16) + (rgb.g << 8) + rgb.b).toString(16).slice(1);
@ -14,7 +17,7 @@ const rgb2Hex = rgb => "#" + ((1 << 24) + (rgb.r << 16) + (rgb.g << 8) + rgb.b).
const interpolateColor = (f, c) => {
if(!f) return "transparent";
if(f >= 1) return c.pop();
if(f <= 0) return c[0];
if(f <= 0) return c.shift();
f *= c.length - 1;
const i = ~~f;

View File

@ -1,34 +1,128 @@
import QtQuick 2.15
import QtQuick.Layouts 1.3
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.kirigami 2.14 as Kirigami
import QtQuick
import QtQuick.Layouts
import org.kde.plasma.plasmoid
import org.kde.kirigami as Kirigami
import org.kde.plasma.plasma5support as Plasma5Support
import org.kde.plasma.core as PlasmaCore
import org.kde.notification
import "./lib/helper.js" as Helper
Item {
id: main
PlasmoidItem {
id: root
Plasmoid.status: PlasmaCore.Types.ActiveStatus
property int pollingrate: Plasmoid.configuration.pollingrate
property int batteryheight: Plasmoid.configuration.batteryheight
property string colorEmpty: Plasmoid.configuration.colorEmpty
property string colorHalf: Plasmoid.configuration.colorHalf
property string colorFull: Plasmoid.configuration.colorFull
property int batteryPercent: -2
readonly property int pollingrate: Plasmoid.configuration.pollingrate
readonly property int batteryheight: Plasmoid.configuration.batteryheight
readonly property string colorEmpty: Plasmoid.configuration.colorEmpty
readonly property string colorHalf: Plasmoid.configuration.colorHalf
readonly property string colorFull: Plasmoid.configuration.colorFull
PlasmaCore.DataSource {
readonly property bool notifications: Plasmoid.configuration.notifications
readonly property int batteryThreshold: Plasmoid.configuration.batteryThreshold
readonly property bool debug_active: Plasmoid.configuration.debug_active
readonly property int debug_charge: Plasmoid.configuration.debug_charge
property string batteryStatus: "BATTERY_UNAVAILABLE"
property int batteryPercent: 0
property bool notification_sent: false
property variant deviceList: []
property int activeDevice: 0
//property variant capabilities: []
Plasma5Support.DataSource {
id: hsSource
engine: "executable"
connectedSources: ["headsetcontrol -bc"]
connectedSources: ["headsetcontrol -o json"]
interval: pollingrate * 1e3
onNewData: {
return batteryPercent = data['exit code'] > 0
? -2 // not connected
: data['stdout'];
onNewData: (_, data) => {
const res = JSON.parse(data.stdout);
if(res.device_count === 0) {
batteryStatus = "HEADSET_UNAVAILABLE";
batteryPercent = 0;
root.Plasmoid.status = PlasmaCore.Types.PassiveStatus;
return;
}
//if(capabilities.length != res.devices[activeDevice].capabilities_str.length)
// capabilities = res.devices[activeDevice].capabilities_str;
deviceList = res.devices.map(e => e.product);
batteryPercent = res.devices[activeDevice].battery.level;
batteryStatus = batteryPercent > 0 ? res.devices[activeDevice].battery.status : "BATTERY_UNAVAILABLE";
// debug deshmug
if(debug_active) {
batteryStatus = "BATTERY_AVAILABLE";
batteryPercent = debug_charge;
}
// hide trayicon if headset isn't connected
root.Plasmoid.status = batteryStatus == "BATTERY_UNAVAILABLE"
? PlasmaCore.Types.PassiveStatus
: PlasmaCore.Types.ActiveStatus;
// send notification if necessary
if(batteryPercent <= batteryThreshold && batteryPercent >= 0 && !notification_sent && notifications) {
notification_sent = true;
notification.text = "Battery Level is low (" + batteryPercent + "%)";
notification.title = "Headset Battery Level Alert";
notification.iconName = "notification-battery-low";
notification.sendEvent();
}
// reset notifications if battery level is over batteryThreshold
if((batteryPercent > batteryThreshold || batteryPercent < 0) && notification_sent && notifications) {
notification_sent = false;
}
return;
}
}
Plasmoid.preferredRepresentation: Plasmoid.compactRepresentation
Plasmoid.fullRepresentation: FullRepresentation{}
Plasmoid.compactRepresentation: CompactRepresentation{}
toolTipMainText: "battery level: " + Helper.batteryLevel(batteryStatus, batteryPercent)
toolTipSubText: "polling rate: " + pollingrate + " seconds"
preferredRepresentation: compactRepresentation
compactRepresentation: CompactRepresentation{}
fullRepresentation: Item{}
Notification {
id: notification
componentName: "plasma_workspace"
eventId: "notification"
flags: Notification.DefaultEvent
urgency: Notification.CriticalUrgency
}
Instantiator {
model: deviceList
delegate: PlasmaCore.Action {
text: modelData
icon.name: "audio-headphones-symbolic"
/*onTriggered: {
console.log("headset lel");
}*/
}
onObjectAdded: (index, object) => {
Plasmoid.contextualActions.splice(Plasmoid.contextualActions.indexOf(separator2), 0, object)
}
onObjectRemoved: (index, object) => {
Plasmoid.contextualActions.splice(Plasmoid.contextualActions.indexOf(object), 1)
}
}
Plasmoid.contextualActions: [
PlasmaCore.Action {
id: separator1
isSeparator: true
},
PlasmaCore.Action {
id: separator2
isSeparator: true
}
]
}

View File

@ -1,24 +1,25 @@
{
"KPackageStructure": "Plasma/Applet",
"KPlugin": {
"Name": "Headset Battery Widget",
"Description": "Headset Battery Widget",
"Icon": "battery",
"Category": "System Information",
"Authors": [{
"Email": "flummi@srv.fail",
"Name": "Flummi"
}],
"Category": "System Information",
"Dependencies": [
],
"EnabledByDefault": true,
"Icon": "battery",
"Id": "org.kde.plasma.headsetcontrol-battery-widget",
"Name": "Headset Battery Widget",
"License": "",
"Version": "1.7",
"EnabledByDefault": true,
"Website": "https://git.lat/Flummi/headsetcontrol-battery-widget",
"BugReportUrl": "https://git.lat/Flummi/headsetcontrol-battery-widget/issues",
"ServiceTypes": [
"Plasma/Applet"
],
"Version": "1.5",
"Website": "https://git.lat/Flummi/headsetcontrol-battery-widget"
]
},
"X-Plasma-NotificationArea": true,
"X-Plasma-NotificationAreaCategory": "Hardware",
"X-Plasma-API": "declarativeappletscript",
"X-Plasma-MainScript": "ui/main.qml"
"X-Plasma-API-Minimum-Version": "6.0"
}