fcc395053a
- 弹窗标题居中显示 - GPU卡片图标根据厂商显示简称(NV/AMD/Intel等) - 任务栏图标改为透明背景+边框样式 - 加深蓝色调提高文字对比度 - 刷新按钮改为蓝底白字 - tooltip多显卡分行显示
359 lines
12 KiB
QML
359 lines
12 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
|
|
import org.deepin.dtk 1.0
|
|
|
|
AppletItem {
|
|
id: root
|
|
objectName: "graphics driver applet"
|
|
property int dockOrder: 21
|
|
property int dockSize: Panel.rootObject.dockItemMaxSize || 48
|
|
|
|
implicitWidth: dockSize
|
|
implicitHeight: dockSize
|
|
|
|
readonly property var applet: Applet
|
|
readonly property bool ready: applet ? applet.ready : false
|
|
readonly property string gpuSummary: applet ? (applet.gpuSummary || qsTr("No GPU detected")) : qsTr("No GPU detected")
|
|
readonly property string deviceInfo: applet ? (applet.deviceInfo || qsTr("Unknown")) : qsTr("Unknown")
|
|
readonly property string currentDriver: applet ? (applet.currentDriver || qsTr("Unknown")) : qsTr("Unknown")
|
|
|
|
property Palette basePalette: DockPalette.iconTextPalette
|
|
readonly property color primaryText: Qt.rgba(basePalette.r, basePalette.g, basePalette.b, 0.9)
|
|
readonly property color secondaryText: Qt.rgba(basePalette.r, basePalette.g, basePalette.b, 0.65)
|
|
readonly property color tertiaryText: Qt.rgba(basePalette.r, basePalette.g, basePalette.b, 0.5)
|
|
readonly property color cardBackground: Qt.rgba(basePalette.r, basePalette.g, basePalette.b, 0.06)
|
|
readonly property color cardBorder: Qt.rgba(basePalette.r, basePalette.g, basePalette.b, 0.1)
|
|
readonly property color accentBlue: Qt.rgba(20 / 255, 80 / 255, 160 / 255, 1)
|
|
readonly property color accentBlueLight: Qt.rgba(20 / 255, 80 / 255, 160 / 255, 0.12)
|
|
|
|
// 图标区域
|
|
Rectangle {
|
|
anchors.centerIn: parent
|
|
width: dockSize * 0.7
|
|
height: dockSize * 0.7
|
|
color: "transparent"
|
|
radius: width * 0.45
|
|
border.width: 1
|
|
border.color: root.secondaryText
|
|
|
|
Text {
|
|
anchors.centerIn: parent
|
|
text: "GPU"
|
|
font.pixelSize: root.dockSize * 0.22
|
|
font.bold: true
|
|
color: root.primaryText
|
|
}
|
|
}
|
|
|
|
// 悬停提示
|
|
PanelToolTip {
|
|
id: toolTip
|
|
text: root.ready ? root.deviceInfo.replace(/\n/g, "\n") : qsTr("No GPU detected")
|
|
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: 360
|
|
height: 320
|
|
popupX: DockPanelPositioner.x
|
|
popupY: DockPanelPositioner.y
|
|
|
|
onPopupVisibleChanged: {
|
|
if (popupVisible) {
|
|
toolTip.close()
|
|
}
|
|
}
|
|
|
|
Control {
|
|
id: popupContainer
|
|
anchors.fill: parent
|
|
padding: 16
|
|
|
|
contentItem: ColumnLayout {
|
|
spacing: 14
|
|
|
|
// 标题区域
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: 10
|
|
|
|
Item { Layout.fillWidth: true }
|
|
|
|
Rectangle {
|
|
width: 28
|
|
height: 28
|
|
color: accentBlueLight
|
|
radius: 8
|
|
|
|
Text {
|
|
anchors.centerIn: parent
|
|
text: "GPU"
|
|
font.pixelSize: 12
|
|
font.bold: true
|
|
color: accentBlue
|
|
}
|
|
}
|
|
|
|
Text {
|
|
text: qsTr("Graphics Driver Manager")
|
|
font.pixelSize: 16
|
|
font.bold: true
|
|
color: root.primaryText
|
|
}
|
|
|
|
Item { Layout.fillWidth: true }
|
|
}
|
|
|
|
// 分隔线
|
|
Rectangle {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 1
|
|
color: root.cardBorder
|
|
}
|
|
|
|
// 当前驱动信息
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: 8
|
|
visible: root.ready
|
|
|
|
Text {
|
|
text: qsTr("Current Driver:")
|
|
font.pixelSize: 12
|
|
color: root.secondaryText
|
|
}
|
|
|
|
Text {
|
|
text: root.currentDriver
|
|
font.pixelSize: 12
|
|
font.bold: true
|
|
color: root.primaryText
|
|
Layout.fillWidth: true
|
|
elide: Text.ElideRight
|
|
}
|
|
}
|
|
|
|
// GPU 列表区域
|
|
Flickable {
|
|
id: gpuListFlick
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
clip: true
|
|
contentWidth: width
|
|
contentHeight: gpuColumn.height
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
|
|
Column {
|
|
id: gpuColumn
|
|
width: gpuListFlick.width
|
|
spacing: 10
|
|
visible: root.ready
|
|
|
|
Repeater {
|
|
model: root.ready ? root.deviceInfo.split("\n").filter(function(line) { return line.trim().length > 0 }) : []
|
|
|
|
delegate: Rectangle {
|
|
width: gpuColumn.width
|
|
height: 72
|
|
color: root.cardBackground
|
|
radius: 10
|
|
border.width: 1
|
|
border.color: root.cardBorder
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
anchors.margins: 12
|
|
spacing: 12
|
|
|
|
// GPU 图标
|
|
Rectangle {
|
|
width: 44
|
|
height: 44
|
|
color: root.accentBlueLight
|
|
radius: 8
|
|
|
|
Text {
|
|
anchors.centerIn: parent
|
|
text: parseGpuVendorShort(modelData)
|
|
font.pixelSize: 14
|
|
font.bold: true
|
|
color: root.accentBlue
|
|
}
|
|
}
|
|
|
|
// GPU 信息
|
|
ColumnLayout {
|
|
spacing: 4
|
|
Layout.fillWidth: true
|
|
|
|
Text {
|
|
text: parseGpuName(modelData)
|
|
font.pixelSize: 13
|
|
font.bold: true
|
|
color: root.primaryText
|
|
Layout.fillWidth: true
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
Text {
|
|
text: parseDriverInfo(modelData)
|
|
font.pixelSize: 11
|
|
color: root.secondaryText
|
|
Layout.fillWidth: true
|
|
elide: Text.ElideRight
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 未检测到 GPU 提示
|
|
Rectangle {
|
|
anchors.centerIn: parent
|
|
width: gpuListFlick.width - 32
|
|
height: 80
|
|
color: root.cardBackground
|
|
radius: 10
|
|
border.width: 1
|
|
border.color: root.cardBorder
|
|
visible: !root.ready
|
|
|
|
ColumnLayout {
|
|
anchors.centerIn: parent
|
|
spacing: 6
|
|
|
|
Text {
|
|
text: "⚠"
|
|
font.pixelSize: 24
|
|
}
|
|
|
|
Text {
|
|
text: qsTr("No GPU detected")
|
|
font.pixelSize: 13
|
|
color: root.secondaryText
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 刷新按钮
|
|
Button {
|
|
id: refreshBtn
|
|
text: qsTr("Refresh")
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 36
|
|
font.pixelSize: 13
|
|
|
|
background: Rectangle {
|
|
color: refreshBtn.hovered ? Qt.darker(root.accentBlue, 1.2) : root.accentBlue
|
|
radius: 8
|
|
}
|
|
|
|
contentItem: Text {
|
|
text: refreshBtn.text
|
|
color: "white"
|
|
font.pixelSize: refreshBtn.font.pixelSize
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
|
|
onClicked: {
|
|
if (root.applet) {
|
|
root.applet.refreshDeviceInfo()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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)
|
|
})
|
|
}
|
|
}
|
|
|
|
// 解析 GPU 名称的辅助函数
|
|
function parseGpuName(info) {
|
|
var parts = info.split("(")
|
|
if (parts.length > 0) {
|
|
return parts[0].trim()
|
|
}
|
|
return info
|
|
}
|
|
|
|
// 解析驱动信息的辅助函数
|
|
function parseDriverInfo(info) {
|
|
var startIndex = info.indexOf("(")
|
|
var endIndex = info.lastIndexOf(")")
|
|
if (startIndex !== -1 && endIndex !== -1) {
|
|
return info.substring(startIndex + 1, endIndex)
|
|
}
|
|
return info
|
|
}
|
|
|
|
// 识别 GPU 厂商简称
|
|
function parseGpuVendorShort(info) {
|
|
var name = info.toLowerCase()
|
|
if (name.indexOf("nvidia") !== -1) return "NV"
|
|
if (name.indexOf("amd") !== -1 || name.indexOf("ati") !== -1 || name.indexOf("advanced micro") !== -1) return "AMD"
|
|
if (name.indexOf("intel") !== -1) return "Intel"
|
|
if (name.indexOf("qualcomm") !== -1) return "QC"
|
|
if (name.indexOf("microsoft") !== -1) return "MS"
|
|
return "GPU"
|
|
}
|
|
|
|
// 点击处理
|
|
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()
|
|
}
|
|
}
|
|
}
|