pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import Weave.Controls import Weave.Templates as T import "internal" T.NotificationToast { id: root implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding) padding: Theme.generic.spacing._4 statusBarColor: status === T.NotificationToast.Information ? Theme.component.notificationtoast.info.icon.fill : status === T.NotificationToast.Success ? Theme.component.notificationtoast.success.icon.fill : status === T.NotificationToast.Warning ? Theme.component.notificationtoast.warning.icon.fill : status === T.NotificationToast.Error ? Theme.component.notificationtoast.error.icon.fill : status === T.NotificationToast.Read ? Theme.component.notificationtoast.read.icon.fill : backgroundColor backgroundColor: Theme.semantic.backgroundColor.surface._100 textColor: Theme.component.notificationtoast.messageContainer.textColor hoverEnabled: root.enabled image: T.IconImage { width: Theme.component.button.iconContainer.width height: Theme.component.button.iconContainer.height color: root.statusBarColor url: root.imageSource name: root.imageSource.toString().length > 0 ? "" : root.status === NotificationBanner.Information ? "info" : root.status === NotificationBanner.Success ? "complete" : root.status === NotificationBanner.Warning ? "alert" : "error" sourceSize: Qt.size(Theme.component.button.icon.width, Theme.component.button.icon.height) } contentItem: Item { implicitHeight: Math.max(Theme.generic.spacing._16 + descriptionLabel.implicitHeight + textLink.height + timestampLabel.height + (actionsRow.height ? actionsRow.height + actionsRow.anchors.topMargin : 0) + Theme.generic.spacing._16, Theme.generic.spacing._16 + icon.implicitHeight + Theme.generic.spacing._16) // TODO: NotificationToast-specific theme constant implicitWidth: icon.anchors.leftMargin + icon.implicitWidth + textContainer.leftMargin + textContainer.implicitWidth + textContainer.rightMargin + closeButton.implicitWidth + closeButton.anchors.rightMargin Loader { id: icon anchors { verticalCenter: parent.verticalCenter left: parent.left leftMargin: Theme.generic.spacing._16 // TODO: Non CSS style NotificationToast-specific theme constant } sourceComponent: root.status === T.NotificationToast.Basic ? null : root.image } Item { id: textContainer anchors { verticalCenter: parent.verticalCenter left: icon.right right: closeButton.left leftMargin: icon.width === 0 ? 0 : Theme.semantic.spacing.s // TODO: Theme.component.notificationtoast.icon.paddingRight rightMargin: Theme.generic.spacing._16 // TODO: Non CSS style NotificationToast-specific theme constant } height: descriptionLabel.height + textLink.height + timestampLabel.height + (actionsRow.height ? actionsRow.height + actionsRow.anchors.topMargin : 0) Text { id: objectLabel anchors { top: descriptionLabel.top left: descriptionLabel.left } width: root.objectText.length ? implicitWidth : 0 text: root.objectText verticalAlignment: Text.AlignVCenter color: root.textColor font { family: Theme.component.label.fontFamily // TODO: notification toast specific token weight: Theme.component.typography.bold.fontWeight pixelSize: Theme.component.notificationtoast.messageContainer.fontSize } lineHeight: Theme.component.notificationtoast.messageContainer.lineHeight lineHeightMode: Text.FixedHeight } Text { id: descriptionLabel anchors { top: parent.top left: parent.left right: parent.right } wrapMode: Text.Wrap verticalAlignment: Text.AlignVCenter color: root.textColor font { family: Theme.component.label.fontFamily // TODO: notification toast specific token weight: Theme.component.notificationtoast.messageContainer.fontWeight pixelSize: Theme.component.notificationtoast.messageContainer.fontSize } lineHeight: Theme.component.notificationtoast.messageContainer.lineHeight lineHeightMode: Text.FixedHeight text: leadingSpaces.text + root.text /* // alternative to the leadingSpaces.text solution; but it doesn't work (y offset is wonky) onLineLaidOut: { if (line.number === 0 && line.x < objectLabel.width) { var offset = objectLabel.width + leadingSpaces.advanceWidth(' ') // set leadingSpaces.font to objectLabel.font ... line.x = line.x + offset line.width = line.width - offset } } */ FontMetrics { // lead with spaces to avoid overdrawing the objectLabel text id: leadingSpaces font: descriptionLabel.font property string text: { if (root.objectText.length == 0) { return "" } leadingSpaces.font; // force capture // match the width of objectLabel with a series of spaces var str = " "; var bounding = leadingSpaces.tightBoundingRect(str) var strWidth = bounding.x + bounding.width while (strWidth < objectLabel.width) { str = str + " "; bounding = leadingSpaces.tightBoundingRect(str) strWidth = bounding.x + bounding.width } // add another space in between the objectLabel and the new text str = str + " "; return str } } } TextLink { id: textLink anchors { top: descriptionLabel.bottom left: descriptionLabel.left } height: text.length === 0 ? 0 : implicitHeight text: root.linkText font.pixelSize: descriptionLabel.font.pixelSize onLinkActivated: root.linkActivated() } Text { id: timestampLabel anchors { top: textLink.bottom left: descriptionLabel.left right: descriptionLabel.right } height: text.length === 0 ? 0 : implicitHeight text: root.secondaryText color: Theme.component.notificationtoast.timestamp.textColor font.family: Theme.generic.font.family font.pixelSize: Theme.component.notificationtoast.messageContainer.fontSize lineHeight: Theme.component.notificationtoast.messageContainer.lineHeight lineHeightMode: Text.FixedHeight } RowLayout { id: actionsRow anchors { topMargin: actionButtonsRepeater.count === 0 ? 0 : Theme.component.menu.paddingTop top: timestampLabel.bottom left: descriptionLabel.left } height: actionButtonsRepeater.count === 0 ? 0 : implicitHeight width: Math.min(implicitWidth, descriptionLabel.width) spacing: Theme.semantic.spacing.xs Repeater { id: actionButtonsRepeater model: root.actionButtonsModel } } } ActionIconButton { id: closeButton anchors { right: parent.right rightMargin: Theme.generic.spacing._12 } y: textContainer.height === descriptionLabel.height ? (parent.height - height)/2 : Theme.generic.spacing._16 icon.name: Theme.icon.small("close") onClicked: root.closeClicked() } } background: NotificationBackground { borderColor: root.statusBarColor backgroundColor: root.backgroundColor shadowRadius: root.padding } }