Files
DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/UserTile.qml
T

190 lines
5.9 KiB
QML

import QtQuick
import QtQuick.Effects
import qs.Common
import qs.Modules.ControlCenter
import qs.Modules.DankDash
import qs.Services
import qs.Widgets
import "../utils/widgets.js" as WidgetUtils
Item {
id: root
property var widgetData: ({})
property var widgetDef: null
property var host: null
property bool live: true
property bool interactive: true
property real columns: 2
property real rows: 2
property bool compact: false
property bool docked: false
signal optionChanged(string key, var value)
readonly property bool wide: width >= height * 2
readonly property bool background: docked || widgetData?.background === true
readonly property bool tall: height >= CcMetrics.gridRowUnit * 2
readonly property real inset: background ? (tall ? Theme.spacingM : Theme.spacingS) : 0
readonly property real avatarSide: Math.min(width, height) - inset * 2
readonly property string shape: widgetData?.shape ?? WidgetUtils.USER_SHAPES[0]
readonly property bool editMode: host?.editMode ?? false
readonly property bool tapToClose: interactive && (host?.tapToClose ?? false)
readonly property Item passthrough: shapeButton
readonly property real bodyRadius: {
if (!background)
return Theme.fullRadius(avatarSide, avatarSide);
return tall ? Math.min(CcMetrics.tallTileRadius, width / 2, height / 2) : Theme.fullRadius(width, height);
}
readonly property real fallbackGlyphRatio: 0.5
readonly property string avatarSource: PortalService.profileImageUrl
readonly property bool hasImage: picture.status === Image.Ready
width: parent?.width ?? 0
height: parent?.height ?? 0
LayoutMirroring.enabled: I18n.isRtl
LayoutMirroring.childrenInherit: true
Accessible.role: Accessible.StaticText
Accessible.name: UserInfoService.fullName || UserInfoService.username
Rectangle {
anchors.fill: parent
radius: root.bodyRadius
color: CcMetrics.tileInactiveColor
border.width: Theme.layerOutlineWidth
border.color: Theme.outlineMedium
visible: root.background
}
UserIdentity {
anchors.fill: parent
anchors.margins: root.inset
visible: root.wide
live: root.live && root.wide
options: root.docked ? Object.assign({}, DashRegistry.resolvedOptions("user", root.widgetData), {
"compositor": false,
"uptime": false
}) : DashRegistry.resolvedOptions("user", root.widgetData)
avatarSize: height
textGap: root.docked ? Theme.spacingS : Theme.spacingM
stacked: root.rows >= 2
contentColor: Theme.onSurface
mutedColor: Theme.onSurfaceVariant
}
Item {
id: avatar
anchors.centerIn: parent
width: root.avatarSide
height: root.avatarSide
visible: !root.wide
DankMaterialShape {
anchors.fill: parent
shape: root.shape
color: Theme.primaryContainer
visible: !root.hasImage
}
DankIcon {
anchors.centerIn: parent
name: "person"
size: Math.round(root.avatarSide * root.fallbackGlyphRatio)
color: Theme.onPrimaryContainer
filled: true
visible: !root.hasImage
}
Item {
id: avatarMask
anchors.fill: parent
layer.enabled: root.hasImage
visible: false
DankMaterialShape {
anchors.fill: parent
shape: root.shape
}
}
Image {
id: picture
anchors.fill: parent
asynchronous: true
fillMode: Image.PreserveAspectCrop
smooth: true
mipmap: true
retainWhileLoading: true
visible: root.hasImage
sourceSize.width: Math.max(1, Math.ceil(width * Screen.devicePixelRatio))
sourceSize.height: Math.max(1, Math.ceil(height * Screen.devicePixelRatio))
source: avatar.visible ? root.avatarSource : ""
layer.enabled: root.hasImage
layer.effect: MultiEffect {
maskEnabled: true
maskSource: avatarMask
maskThresholdMin: 0.5
maskSpreadAtMin: 1
}
}
}
StyledButton {
objectName: "userCloseButton"
anchors.fill: parent
visible: root.tapToClose
radius: root.bodyRadius
Accessible.name: I18n.tr("Close")
onClicked: root.host?.closeRequested()
FocusRing {
visible: parent.visualFocus
}
StateLayer {
control: parent
cornerRadius: root.bodyRadius
}
}
StyledButton {
objectName: "userAvatarButton"
x: !root.wide ? (root.width - width) / 2 : I18n.isRtl ? root.width - root.inset - width : root.inset
y: (root.height - height) / 2
width: root.avatarSide
height: root.avatarSide
radius: Theme.fullRadius(width, height)
visible: root.interactive
Accessible.name: I18n.tr("Users & accounts", "settings sidebar category")
onClicked: root.host?.accountsRequested()
FocusRing {
visible: parent.visualFocus
}
StateLayer {
control: parent
cornerRadius: parent.radius
tooltipText: parent.Accessible.name
}
}
DankActionButton {
id: shapeButton
anchors.bottom: avatar.bottom
anchors.left: avatar.left
buttonSize: CcMetrics.shapeButtonSize
iconSize: Theme.iconSizeSmall
iconName: "shuffle"
iconColor: Theme.onSurface
backgroundColor: Theme.surfaceContainerHighest
Accessible.name: I18n.tr("Shuffle")
visible: root.editMode && avatar.visible
onClicked: root.optionChanged("shape", WidgetUtils.nextUserShape(root.shape))
}
}