9fb80cdfc8
- QML 根元素使用 AppletItem,参照 dde-weather 插件实现 - 使用 Panel.rootObject.dockItemMaxSize 适配任务栏图标尺寸 - dockOrder 设为 21,定位在系统托盘左侧 - 使用 PanelPopup + PanelToolTip + TapHandler 实现点击弹窗和悬停提示 - 弹窗打开前设置 DockPanelPositioner.bounding 修正弹窗定位 - C++ 后端新增 dbusAvailable 属性,D-Bus 不可用时优雅降级 - 使用 isServiceRegistered 正确检测 D-Bus 服务可用性 - install.sh 改用 SCRIPT_DIR 自动定位项目根目录
246 lines
7.4 KiB
QML
246 lines
7.4 KiB
QML
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
|
|
//
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
import QtQuick 2.15
|
|
import QtQuick.Controls 2.15
|
|
import QtQuick.Layouts 1.15
|
|
import org.deepin.ds 1.0
|
|
import org.deepin.ds.dock 1.0
|
|
|
|
AppletItem {
|
|
id: root
|
|
objectName: "graphics driver applet"
|
|
property int dockOrder: 21
|
|
property int dockSize: Panel.rootObject.dockItemMaxSize || 48
|
|
|
|
implicitWidth: dockSize
|
|
implicitHeight: dockSize
|
|
|
|
// 访问 C++ 后端
|
|
readonly property var applet: Applet
|
|
readonly property bool dbusAvailable: applet && applet.dbusAvailable
|
|
readonly property string currentDriver: applet ? (applet.currentDriver || qsTr("Unknown")) : qsTr("Unknown")
|
|
readonly property string deviceInfo: applet ? (applet.deviceInfo || qsTr("Unknown")) : qsTr("Unknown")
|
|
readonly property bool isInstalling: applet ? applet.isInstalling : false
|
|
readonly property int installProgress: applet ? applet.installProgress : 0
|
|
|
|
// 图标区域
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: "#3498db"
|
|
radius: 8
|
|
|
|
Text {
|
|
anchors.centerIn: parent
|
|
text: "GPU"
|
|
font.pixelSize: root.dockSize * 0.3
|
|
color: "white"
|
|
}
|
|
}
|
|
|
|
// 悬停提示
|
|
PanelToolTip {
|
|
id: toolTip
|
|
text: qsTr("Graphics Driver: ") + root.currentDriver
|
|
toolTipX: DockPanelPositioner.x
|
|
toolTipY: DockPanelPositioner.y
|
|
}
|
|
|
|
Timer {
|
|
id: toolTipShowTimer
|
|
interval: 50
|
|
onTriggered: {
|
|
const point = root.mapToItem(null, root.width / 2, root.height / 2)
|
|
toolTip.DockPanelPositioner.bounding = Qt.rect(point.x, point.y, toolTip.width, toolTip.height)
|
|
toolTip.open()
|
|
}
|
|
}
|
|
|
|
HoverHandler {
|
|
onHoveredChanged: {
|
|
if (hovered && !driverPopup.popupVisible) {
|
|
toolTipShowTimer.start()
|
|
} else {
|
|
if (toolTipShowTimer.running) {
|
|
toolTipShowTimer.stop()
|
|
}
|
|
toolTip.close()
|
|
}
|
|
}
|
|
}
|
|
|
|
// 弹出窗口
|
|
PanelPopup {
|
|
id: driverPopup
|
|
width: 320
|
|
height: 400
|
|
popupX: DockPanelPositioner.x
|
|
popupY: DockPanelPositioner.y
|
|
|
|
onPopupVisibleChanged: {
|
|
if (popupVisible) {
|
|
toolTip.close()
|
|
}
|
|
}
|
|
|
|
Control {
|
|
id: popupContainer
|
|
anchors.fill: parent
|
|
padding: 16
|
|
|
|
contentItem: ColumnLayout {
|
|
spacing: 12
|
|
|
|
Text {
|
|
text: qsTr("Graphics Driver Manager")
|
|
font.pixelSize: 16
|
|
font.bold: true
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Rectangle {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 1
|
|
color: "#cccccc"
|
|
}
|
|
|
|
// D-Bus 不可用提示
|
|
Rectangle {
|
|
Layout.fillWidth: true
|
|
height: 40
|
|
visible: !root.dbusAvailable
|
|
color: "#fff3cd"
|
|
radius: 6
|
|
|
|
Text {
|
|
anchors.centerIn: parent
|
|
text: qsTr("Driver service is not available")
|
|
color: "#856404"
|
|
font.pixelSize: 12
|
|
}
|
|
}
|
|
|
|
// 设备信息
|
|
GroupBox {
|
|
Layout.fillWidth: true
|
|
title: qsTr("Device Information")
|
|
visible: root.dbusAvailable
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
spacing: 8
|
|
|
|
Text {
|
|
text: qsTr("Current Driver: ") + root.currentDriver
|
|
font.pixelSize: 12
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Text {
|
|
text: qsTr("Device: ") + root.deviceInfo
|
|
font.pixelSize: 12
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
|
|
// 操作按钮
|
|
Button {
|
|
text: qsTr("Refresh")
|
|
Layout.fillWidth: true
|
|
enabled: root.dbusAvailable && !root.isInstalling
|
|
onClicked: {
|
|
if (root.applet) {
|
|
root.applet.refreshDeviceInfo()
|
|
}
|
|
}
|
|
}
|
|
|
|
Button {
|
|
text: qsTr("Test Install")
|
|
Layout.fillWidth: true
|
|
enabled: root.dbusAvailable && !root.isInstalling
|
|
onClicked: {
|
|
if (root.applet) {
|
|
root.applet.testInstall()
|
|
}
|
|
}
|
|
}
|
|
|
|
// 安装进度
|
|
ColumnLayout {
|
|
visible: root.isInstalling
|
|
Layout.fillWidth: true
|
|
spacing: 8
|
|
|
|
Text {
|
|
text: qsTr("Installing... ") + root.installProgress + "%"
|
|
font.pixelSize: 12
|
|
}
|
|
|
|
ProgressBar {
|
|
Layout.fillWidth: true
|
|
value: root.installProgress / 100
|
|
}
|
|
|
|
Button {
|
|
text: qsTr("Cancel")
|
|
Layout.fillWidth: true
|
|
onClicked: {
|
|
if (root.applet) {
|
|
root.applet.cancelInstall()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
Layout.fillHeight: true
|
|
}
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
DockPanelPositioner.bounding = Qt.binding(function () {
|
|
const point = root.mapToItem(null, root.width / 2, root.height / 2)
|
|
return Qt.rect(point.x, point.y, driverPopup.width, driverPopup.height)
|
|
})
|
|
}
|
|
}
|
|
|
|
// 点击处理
|
|
TapHandler {
|
|
acceptedButtons: Qt.LeftButton
|
|
gesturePolicy: TapHandler.ReleaseWithinBounds
|
|
|
|
onTapped: {
|
|
if (driverPopup.popupVisible) {
|
|
driverPopup.close()
|
|
} else {
|
|
Panel.requestClosePopup()
|
|
// 在打开前设置定位,确保弹窗出现在插件附近
|
|
const point = root.mapToItem(null, root.width / 2, root.height / 2)
|
|
driverPopup.DockPanelPositioner.bounding = Qt.rect(point.x, point.y, driverPopup.width, driverPopup.height)
|
|
driverPopup.open()
|
|
}
|
|
toolTip.close()
|
|
}
|
|
}
|
|
|
|
// 后端信号处理
|
|
Connections {
|
|
target: root.applet
|
|
function onInstallSuccess() {
|
|
console.log("Install succeeded")
|
|
}
|
|
function onInstallFailed(error) {
|
|
console.log("Install failed:", error)
|
|
}
|
|
function onRequestReboot() {
|
|
console.log("Reboot requested")
|
|
}
|
|
}
|
|
}
|