dash: rebuild the calendar event editor on settings rows

notifications: paint the popup and toast surface once
This commit is contained in:
bbedward
2026-10-04 17:49:25 -04:00
parent d7dc8ae5d2
commit 23e8bb5935
11 changed files with 310 additions and 282 deletions
@@ -190,7 +190,6 @@ Singleton {
readonly property real eventActionIconSize: Theme.iconSizeSmall
readonly property real taskInputHeight: Theme.buttonHeightS
readonly property real sheetWidth: 400
readonly property real sheetFormHeight: 300
readonly property real mediaCardMargin: Theme.spacingL
readonly property real mediaArtSize: 150
@@ -2,7 +2,7 @@ import QtQuick
import qs.Common
import qs.Services
import qs.Widgets
import qs.Modules.DankDash
import qs.Modules.Settings.Widgets
Column {
id: root
@@ -20,8 +20,10 @@ Column {
property string fTitle: ""
property bool fAllDay: false
property date fDate: initialDate
property string fStart: "10:00"
property string fEnd: "11:00"
property int fStartHour: 10
property int fStartMinute: 0
property int fEndHour: 11
property int fEndMinute: 0
property string fLocation: ""
property string fDescription: ""
property string fCalendarId: ""
@@ -35,20 +37,6 @@ Column {
spacing: Theme.spacingM
function _parseTime(value) {
const m = value.trim().match(/^(\d{1,2}):(\d{2})$/);
if (!m)
return null;
const h = parseInt(m[1]);
const min = parseInt(m[2]);
if (h > 23 || min > 59)
return null;
return {
"h": h,
"m": min
};
}
function _isoFromDateTime(dateObj, h, m) {
const d = new Date(dateObj);
d.setHours(h, m, 0, 0);
@@ -93,14 +81,8 @@ Column {
startIso = _allDayIso(fDate, 0);
endIso = _allDayIso(fDate, 1);
} else {
const s = _parseTime(fStart);
const e = _parseTime(fEnd);
if (!s || !e) {
errorText = I18n.tr("Use HH:MM time format");
return;
}
startIso = _isoFromDateTime(fDate, s.h, s.m);
endIso = _isoFromDateTime(fDate, e.h, e.m);
startIso = _isoFromDateTime(fDate, fStartHour, fStartMinute);
endIso = _isoFromDateTime(fDate, fEndHour, fEndMinute);
if (new Date(endIso).getTime() <= new Date(startIso).getTime()) {
errorText = I18n.tr("End must be after start");
return;
@@ -145,8 +127,10 @@ Column {
fTitle = eventData.title || "";
fAllDay = !!eventData.allDay;
fDate = eventData.start;
fStart = Qt.formatTime(eventData.start, "HH:mm");
fEnd = Qt.formatTime(eventData.end, "HH:mm");
fStartHour = eventData.start.getHours();
fStartMinute = eventData.start.getMinutes();
fEndHour = eventData.end.getHours();
fEndMinute = eventData.end.getMinutes();
fLocation = eventData.location || "";
fDescription = eventData.description || "";
fCalendarId = eventData.calendarId || "";
@@ -154,149 +138,101 @@ Column {
fReminder = eventData.reminders[0].minutes;
}
DankFlickable {
SettingsGroup {
width: parent.width
height: Math.min(DashMetrics.sheetFormHeight, form.implicitHeight)
showScrollBar: false
contentWidth: width
contentHeight: form.implicitHeight
clip: true
slotColor: Theme.chipSurface
Column {
id: form
width: parent.width
spacing: Theme.spacingS
SettingsTextFieldRow {
text: I18n.tr("Title")
leftIconName: "title"
placeholderText: I18n.tr("Event title")
value: root.fTitle
onValueEdited: value => root.fTitle = value
onAccepted: root.save()
}
DankTextField {
width: parent.width
labelText: I18n.tr("Title")
leftIconName: "title"
leftIconSize: Theme.iconSizeSmall
placeholderText: I18n.tr("Event title")
text: root.fTitle
onTextChanged: root.fTitle = text
SettingsToggleRow {
text: I18n.tr("All day")
checked: root.fAllDay
onToggled: checked => root.fAllDay = checked
}
SettingsRow {
title: I18n.tr("Date")
subtitle: Qt.formatDate(root.fDate, "ddd, MMM d yyyy")
subtitleColor: Theme.surfaceText
DankActionButton {
iconName: I18n.isRtl ? "chevron_right" : "chevron_left"
Accessible.name: I18n.tr("Previous")
onClicked: root.shiftDate(-1)
}
DankToggle {
width: parent.width
text: I18n.tr("All day")
checked: root.fAllDay
onToggled: checked => root.fAllDay = checked
}
Row {
width: parent.width
spacing: Theme.spacingXS
DankActionButton {
id: prevDay
iconName: I18n.isRtl ? "chevron_right" : "chevron_left"
Accessible.name: I18n.tr("Previous")
iconSize: Theme.iconSizeSmall
onClicked: root.shiftDate(-1)
}
StyledText {
width: parent.width - prevDay.width - nextDay.width - parent.spacing * 2
text: Qt.formatDate(root.fDate, "ddd, MMM d yyyy")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
height: Theme.buttonHeightXS
}
DankActionButton {
id: nextDay
iconName: I18n.isRtl ? "chevron_left" : "chevron_right"
Accessible.name: I18n.tr("Next")
iconSize: Theme.iconSizeSmall
onClicked: root.shiftDate(1)
}
}
Row {
width: parent.width
spacing: Theme.spacingS
visible: !root.fAllDay
DankTextField {
width: (parent.width - Theme.spacingS) / 2
labelText: I18n.tr("Start")
leftIconName: "schedule"
leftIconSize: Theme.iconSizeSmall
placeholderText: "HH:MM"
text: root.fStart
onTextChanged: root.fStart = text
}
DankTextField {
width: (parent.width - Theme.spacingS) / 2
labelText: I18n.tr("End")
placeholderText: "HH:MM"
text: root.fEnd
onTextChanged: root.fEnd = text
}
}
DankDropdown {
width: parent.width
text: I18n.tr("Calendar")
transientSurfaceTracker: root.transientSurfaceTracker
options: root._cals.map(c => c.name)
currentValue: root._calendarName(root.fCalendarId)
onValueChanged: value => {
for (let i = 0; i < root._cals.length; i++) {
if (root._cals[i].name === value) {
root.fCalendarId = root._cals[i].id;
return;
}
}
}
}
DankDropdown {
width: parent.width
text: I18n.tr("Reminder", "noun, calendar event reminder time dropdown label")
transientSurfaceTracker: root.transientSurfaceTracker
options: root._remLabels
currentValue: root._remLabels[Math.max(0, root._remMins.indexOf(root.fReminder))]
onValueChanged: value => {
const idx = root._remLabels.indexOf(value);
if (idx >= 0)
root.fReminder = root._remMins[idx];
}
}
DankTextField {
width: parent.width
labelText: I18n.tr("Location", "calendar event venue field label", true)
leftIconName: "place"
leftIconSize: Theme.iconSizeSmall
placeholderText: I18n.tr("Add location")
text: root.fLocation
onTextChanged: root.fLocation = text
}
DankTextField {
width: parent.width
labelText: I18n.tr("Notes", "noun, calendar event notes field label")
leftIconName: "notes"
leftIconSize: Theme.iconSizeSmall
placeholderText: I18n.tr("Add notes")
text: root.fDescription
onTextChanged: root.fDescription = text
DankActionButton {
iconName: I18n.isRtl ? "chevron_left" : "chevron_right"
Accessible.name: I18n.tr("Next")
onClicked: root.shiftDate(1)
}
}
}
StyledText {
width: parent.width
text: root.errorText
visible: root.errorText !== ""
font.pixelSize: Theme.fontSizeSmall
color: Theme.error
wrapMode: Text.WordWrap
SettingsTimeRow {
visible: !root.fAllDay
is24Hour: SettingsData.use24HourClock
startTitle: I18n.tr("Start")
startHour: root.fStartHour
startMinute: root.fStartMinute
endTitle: I18n.tr("End")
endHour: root.fEndHour
endMinute: root.fEndMinute
onStartChanged: (hour, minute) => {
root.fStartHour = hour;
root.fStartMinute = minute;
}
onEndChanged: (hour, minute) => {
root.fEndHour = hour;
root.fEndMinute = minute;
}
}
SettingsDropdownRow {
text: I18n.tr("Calendar")
transientSurfaceTracker: root.transientSurfaceTracker
options: root._cals.map(c => c.name)
currentValue: root._calendarName(root.fCalendarId)
onValueChanged: value => {
const cal = root._cals.find(c => c.name === value);
if (cal)
root.fCalendarId = cal.id;
}
}
SettingsDropdownRow {
text: I18n.tr("Reminder", "noun, calendar event reminder time dropdown label")
transientSurfaceTracker: root.transientSurfaceTracker
options: root._remLabels
currentValue: root._remLabels[Math.max(0, root._remMins.indexOf(root.fReminder))]
onValueChanged: value => {
const idx = root._remLabels.indexOf(value);
if (idx >= 0)
root.fReminder = root._remMins[idx];
}
}
SettingsTextFieldRow {
text: I18n.tr("Location", "calendar event venue field label", true)
leftIconName: "place"
placeholderText: I18n.tr("Add location")
value: root.fLocation
onValueEdited: value => root.fLocation = value
}
SettingsTextFieldRow {
text: I18n.tr("Notes", "noun, calendar event notes field label")
leftIconName: "notes"
placeholderText: I18n.tr("Add notes")
value: root.fDescription
onValueEdited: value => root.fDescription = value
}
}
Row {
@@ -307,16 +243,14 @@ Column {
DankButton {
text: root.saving ? I18n.tr("Saving...") : I18n.tr("Save")
iconName: "check"
buttonHeight: Theme.buttonHeightS
backgroundColor: Theme.primary
textColor: Theme.onPrimary
enabled: !root.saving
onClicked: root.save()
}
DankButton {
text: I18n.tr("Cancel")
buttonHeight: Theme.buttonHeightS
backgroundColor: "transparent"
textColor: Theme.primary
onClicked: root.closeRequested()
}
}
@@ -596,6 +596,13 @@ Card {
}
}
StateLayer {
cornerRadius: taskItem.radius
stateColor: taskItem.accentColor
disabled: !taskItem.modelData || taskItem.isEditing || !root.interactive
onClicked: taskItem.activate()
}
FocusRing {}
onIndexChanged: visualIndex = index
@@ -777,15 +784,6 @@ Card {
}
}
StateLayer {
anchors.leftMargin: taskItem.leadingWidth
anchors.rightMargin: taskItem.trailingWidth
cornerRadius: taskItem.radius
stateColor: taskItem.accentColor
disabled: !taskItem.modelData || taskItem.isEditing || !root.interactive
onClicked: taskItem.activate()
}
DankActionButton {
anchors.right: parent.right
anchors.rightMargin: Theme.spacingS
@@ -181,6 +181,8 @@ FocusScope {
panelWidth: DashMetrics.sheetWidth
iconName: "edit_calendar"
title: eventData ? I18n.tr("Edit event") : I18n.tr("New event")
statusText: editorLoader.item?.errorText ?? ""
statusColor: Theme.error
onDismissed: {
eventData = null;
@@ -188,6 +190,8 @@ FocusScope {
}
Loader {
id: editorLoader
width: parent.width
active: editorSheet.visible
+10 -1
View File
@@ -87,6 +87,13 @@ Item {
return Qt.point(guideX ?? snapped.x, guideY ?? snapped.y);
}
function pinPosition() {
geometry.savePosition(geometry.widgetX, geometry.widgetY);
SettingsData.updateDesktopWidgetInstanceConfig(instanceId, {
autoPosition: false
});
}
function commitPosition(finalX, finalY) {
if (stock && finalX === stock.x && finalY === stock.y) {
SessionData.resetDesktopWidgetInstanceGeometry(instanceId, ["x", "y"]);
@@ -223,8 +230,10 @@ Item {
geometry.dragOverrideH = next.height;
}
onResizeEnded: {
resizing = false;
geometry.saveSize(geometry.dragOverrideW, geometry.dragOverrideH);
if (root.automaticPlacement)
root.pinPosition();
resizing = false;
geometry.clearDragOverrides();
}
onResizeCanceled: {
+22 -1
View File
@@ -95,8 +95,20 @@ FocusScope {
readonly property real edgeInset: Theme.spacingXL * 2
property bool completed: false
property var lockedPositions: ({})
// Snapshot taken when a drag or resize starts so the auto-placed clock cannot jump under the pointer.
property var heldPlacement: ({})
readonly property string backgroundKey: LockPlacementService.backgroundKey(screenName, width, height)
readonly property var autoPositions: editMode && completed ? currentPlacement() : lockedPositions
readonly property var autoPositions: {
if (!editMode || !completed)
return lockedPositions;
if (interactingItem)
return heldPlacement;
return currentPlacement();
}
onInteractingItemChanged: {
if (interactingItem)
heldPlacement = currentPlacement();
}
function currentPlacement() {
return LockPlacementService.layoutFor(screenName, LockPlacementService.sampleFor(screenName, backgroundKey), placementKey, placeClocks);
@@ -218,6 +230,15 @@ FocusScope {
return null;
}
readonly property var interactingItem: {
for (let i = 0; i < repeater.count; i++) {
const item = repeater.itemAt(i);
if (item && item.interacting)
return item;
}
return null;
}
Rectangle {
x: (parent.width - width) / 2
width: Theme.dividerWidth
@@ -842,6 +842,8 @@ Item {
}
if (root.pam.passwd.active)
return I18n.tr("Authenticating...", "lock screen status text while the password is checked");
if (root.passwordVisibility !== "always")
return "";
return I18n.tr("Password", "lock screen password field placeholder") + "…";
}
color: {
@@ -16,7 +16,9 @@ Item {
readonly property int notificationMode: cfg.mode ?? 1
readonly property bool resizable: true
readonly property real minWidth: Theme.listItemTwoLineHeight * 2
readonly property real minHeight: Theme.listItemHeight
readonly property real minHeight: Theme.buttonHeightXS
readonly property real defaultWidth: LockMetrics.notificationCardWidth
readonly property real defaultHeight: fullContent ? LockMetrics.notificationMaxHeight : Theme.buttonHeightS
readonly property var notifications: NotificationService.groupedNotifications
readonly property int totalCount: {
@@ -46,53 +48,98 @@ Item {
readonly property bool editPlaceholder: !hasNotifications && (lockHost?.demoMode ?? false)
readonly property bool chips: notificationMode === 2 && !editPlaceholder
readonly property bool fullContent: notificationMode === 3 && !editPlaceholder
readonly property var visibleGroups: appNameGroups.slice(0, LockMetrics.notificationLimit)
readonly property int hiddenGroups: Math.max(0, appNameGroups.length - LockMetrics.notificationLimit)
implicitWidth: chips ? contentLoader.implicitWidth : LockMetrics.notificationCardWidth
implicitWidth: contentLoader.implicitWidth
implicitHeight: hasNotifications || editPlaceholder ? contentLoader.implicitHeight : 0
clip: true
Loader {
id: contentLoader
anchors.left: parent.left
anchors.right: root.chips ? undefined : parent.right
anchors.top: parent.top
anchors.fill: parent
active: root.hasNotifications || root.editPlaceholder
sourceComponent: {
if (root.notificationMode === 1 || root.editPlaceholder)
return countOnlyComponent;
return root.chips ? chipRowComponent : notificationListComponent;
if (root.chips)
return chipRowComponent;
if (root.fullContent)
return notificationListComponent;
return countOnlyComponent;
}
}
component Chip: Rectangle {
default property alias content: chipContent.data
readonly property real contentWidth: chipContent.implicitWidth
height: Theme.buttonHeightXS
width: contentWidth + Theme.spacingM * 2
radius: Theme.cornerRadiusM
color: Theme.notificationFloatingSurface
border.width: Theme.layerOutlineWidth
border.color: Theme.outlineVariant
Row {
id: chipContent
anchors.centerIn: parent
spacing: Theme.spacingXS
}
}
Component {
id: chipRowComponent
Row {
spacing: Theme.spacingS
Item {
id: chipHost
Repeater {
model: root.visibleGroups
property int fitCount: root.visibleGroups.length
readonly property int hiddenCount: root.appNameGroups.length - fitCount
implicitWidth: chipRow.implicitWidth
implicitHeight: chipRow.implicitHeight
Rectangle {
id: chip
function measure() {
const widths = [];
for (let i = 0; i < chipRepeater.count; i++)
widths.push(chipRepeater.itemAt(i)?.width ?? 0);
const total = count => widths.slice(0, count).reduce((sum, w) => sum + w, 0) + Math.max(0, count - 1) * chipRow.spacing;
const overflow = count => root.appNameGroups.length > count ? moreMetrics.width + Theme.spacingM * 2 + chipRow.spacing : 0;
let count = widths.length;
while (count > 1 && total(count) + overflow(count) > width)
count--;
fitCount = count;
}
required property var modelData
readonly property string appIcon: NotificationService.notificationAppIcon(modelData.latestNotification?.appIcon || "", modelData.latestNotification?.desktopEntry || "")
onWidthChanged: Qt.callLater(measure)
Component.onCompleted: measure()
height: Theme.buttonHeightXS
width: chipRow.implicitWidth + Theme.spacingM * 2
radius: Theme.cornerRadiusM
color: Theme.notificationFloatingSurface
border.width: Theme.layerOutlineWidth
border.color: Theme.outlineVariant
Accessible.name: modelData.appName
TextMetrics {
id: moreMetrics
font.pixelSize: Theme.fontSizeSmall
font.weight: Theme.fontWeightMedium
text: I18n.tr("+ %1 more", "lock screen notification list overflow, %1 is a count of hidden apps").arg(root.appNameGroups.length)
onWidthChanged: Qt.callLater(chipHost.measure)
}
Row {
id: chipRow
anchors.centerIn: parent
spacing: Theme.spacingXS
Row {
id: chipRow
anchors.centerIn: parent
spacing: Theme.spacingS
Repeater {
id: chipRepeater
model: root.visibleGroups
onItemAdded: Qt.callLater(chipHost.measure)
onItemRemoved: Qt.callLater(chipHost.measure)
Chip {
id: chip
required property var modelData
required property int index
readonly property string appIcon: NotificationService.notificationAppIcon(modelData.latestNotification?.appIcon || "", modelData.latestNotification?.desktopEntry || "")
visible: index < chipHost.fitCount
Accessible.name: modelData.appName
onWidthChanged: Qt.callLater(chipHost.measure)
Item {
width: Theme.iconSizeSmall
@@ -151,24 +198,17 @@ Item {
}
}
}
}
Rectangle {
visible: root.hiddenGroups > 0
height: Theme.buttonHeightXS
width: moreText.implicitWidth + Theme.spacingM * 2
radius: Theme.cornerRadiusM
color: Theme.notificationFloatingSurface
border.width: Theme.layerOutlineWidth
border.color: Theme.outlineVariant
Chip {
visible: chipHost.hiddenCount > 0
StyledText {
id: moreText
anchors.centerIn: parent
text: I18n.tr("+ %1 more", "lock screen notification list overflow, %1 is a count of hidden apps").arg(root.hiddenGroups)
font.pixelSize: Theme.fontSizeSmall
font.weight: Theme.fontWeightMedium
color: Theme.onSurfaceVariant
StyledText {
anchors.verticalCenter: parent.verticalCenter
text: I18n.tr("+ %1 more", "lock screen notification list overflow, %1 is a count of hidden apps").arg(chipHost.hiddenCount)
font.pixelSize: Theme.fontSizeSmall
font.weight: Theme.fontWeightMedium
color: Theme.onSurfaceVariant
}
}
}
}
@@ -177,28 +217,42 @@ Item {
Component {
id: countOnlyComponent
LockNotificationCard {
implicitHeight: Theme.listItemHeight
color: Theme.notificationFloatingSurface
Accessible.name: countLabel.text
Item {
implicitWidth: countPill.width
implicitHeight: countPill.height
Row {
Rectangle {
id: countPill
anchors.centerIn: parent
spacing: Theme.spacingS
width: countRow.implicitWidth + Theme.spacingL * 2
height: Theme.buttonHeightS
radius: Theme.fullRadius(width, height)
color: Theme.notificationFloatingSurface
border.width: Theme.layerOutlineWidth
border.color: Theme.outlineVariant
scale: Math.min(1, parent.width / width, parent.height / height)
Accessible.name: countLabel.text
DankIcon {
name: "notifications"
size: Theme.iconSize
color: Theme.onSurfaceVariant
anchors.verticalCenter: parent.verticalCenter
}
Row {
id: countRow
anchors.centerIn: parent
spacing: Theme.spacingS
StyledText {
id: countLabel
text: root.editPlaceholder ? I18n.tr("Notifications") : root.totalCount === 1 ? I18n.tr("1 notification") : I18n.tr("%1 notifications").arg(root.totalCount)
font.pixelSize: Theme.fontSizeMedium
color: Theme.onSurface
anchors.verticalCenter: parent.verticalCenter
DankIcon {
name: "notifications"
size: Theme.iconSizeSmall + Theme.spacingXXS
color: Theme.onSurfaceVariant
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
id: countLabel
text: root.editPlaceholder ? I18n.tr("Notifications") : root.totalCount === 1 ? I18n.tr("1 notification") : I18n.tr("%1 notifications").arg(root.totalCount)
font.pixelSize: Theme.fontSizeMedium
font.weight: Theme.fontWeightMedium
color: Theme.onSurface
anchors.verticalCenter: parent.verticalCenter
}
}
}
}
@@ -207,46 +261,52 @@ Item {
Component {
id: notificationListComponent
DankFlickable {
implicitHeight: Math.min(notificationColumn.implicitHeight, LockMetrics.notificationMaxHeight, Math.max(0, (root.lockHost?.height ?? 0) - (root.parent?.y ?? 0) - Theme.spacingXL))
height: Math.min(notificationColumn.implicitHeight, root.height)
contentHeight: notificationColumn.implicitHeight
clip: true
Item {
implicitWidth: LockMetrics.notificationCardWidth
implicitHeight: Math.min(notificationColumn.implicitHeight, LockMetrics.notificationMaxHeight)
Column {
id: notificationColumn
DankFlickable {
anchors.centerIn: parent
width: parent.width
spacing: Theme.groupedListGap
height: Math.min(notificationColumn.implicitHeight, parent.height)
contentHeight: notificationColumn.implicitHeight
clip: true
Repeater {
id: notificationRepeater
model: root.appNameGroups.slice(0, LockMetrics.notificationLimit)
Notifications.NotificationCard {
required property var modelData
required property int index
width: notificationColumn.width
notificationData: modelData.latestNotification
groupCount: modelData.count
interactive: false
headerOnly: false
showActions: false
showDismiss: false
showClose: false
showTime: !headerOnly
animateHeight: false
firstInGroup: index === 0
lastInGroup: index === notificationRepeater.count - 1
}
}
StyledText {
Column {
id: notificationColumn
width: parent.width
visible: root.appNameGroups.length > LockMetrics.notificationLimit
text: I18n.tr("+ %1 more", "lock screen notification list overflow, %1 is a count of hidden apps").arg(root.appNameGroups.length - LockMetrics.notificationLimit)
font.pixelSize: Theme.fontSizeSmall
color: Theme.lockScreenContentColor
horizontalAlignment: Text.AlignHCenter
spacing: Theme.groupedListGap
Repeater {
id: notificationRepeater
model: root.visibleGroups
Notifications.NotificationCard {
required property var modelData
required property int index
width: notificationColumn.width
notificationData: modelData.latestNotification
groupCount: modelData.count
interactive: false
headerOnly: false
showActions: false
showDismiss: false
showClose: false
showTime: !headerOnly
animateHeight: false
firstInGroup: index === 0
lastInGroup: index === notificationRepeater.count - 1
}
}
StyledText {
width: parent.width
visible: root.appNameGroups.length > LockMetrics.notificationLimit
text: I18n.tr("+ %1 more", "lock screen notification list overflow, %1 is a count of hidden apps").arg(root.appNameGroups.length - LockMetrics.notificationLimit)
font.pixelSize: Theme.fontSizeSmall
color: Theme.lockScreenContentColor
horizontalAlignment: Text.AlignHCenter
}
}
}
}
@@ -667,7 +667,7 @@ PanelWindow {
anchors.fill: parent
anchors.margins: content.cardInset
radius: win.connectedFrameMode ? Theme.connectedSurfaceRadius : NotificationMetrics.popupRadius
color: Theme.notificationFloatingSurface
color: "transparent"
HoverHandler {
id: cardHoverHandler
@@ -711,7 +711,7 @@ PanelWindow {
dismissText: I18n.tr("Clear")
animateHeight: false
outerRadius: win.connectedFrameMode ? Theme.connectedSurfaceRadius : NotificationMetrics.popupRadius
color: Theme.notificationFloatingSurface
color: "transparent"
onExpandRequested: win.descriptionExpanded = !win.descriptionExpanded
onCloseRequested: win.dismissPopupReliably()
onDismissRequested: {
+4 -3
View File
@@ -107,7 +107,7 @@ PanelWindow {
y: shadowBuffer
width: root.toastWidth
height: root.toastHeight
color: {
readonly property color surfaceColor: {
switch (ToastService.currentLevel) {
case ToastService.levelError:
return Theme.error;
@@ -119,6 +119,7 @@ PanelWindow {
return Theme.readableSurface;
}
}
color: "transparent"
radius: Theme.windowRadius
opacity: presented ? 1 : 0
@@ -452,7 +453,7 @@ PanelWindow {
level: Theme.elevationLevel3
fallbackOffset: 6
targetRadius: toast.radius
targetColor: toast.color
targetColor: toast.surfaceColor
shadowOpacity: Theme.elevationLevel3 && Theme.elevationLevel3.alpha !== undefined ? Theme.elevationLevel3.alpha : 0.3
shadowEnabled: Theme.elevationEnabled
}
@@ -480,7 +481,7 @@ PanelWindow {
WindowBlur {
targetWindow: root
blurEnabled: root.presented
surfaceColor: toast.color
surfaceColor: toast.surfaceColor
blurX: toast.x
blurY: toast.y
blurWidth: root.presented ? toast.width : 0