forked from Shinonome/dots-hyprland
waffles: expandable notifs
This commit is contained in:
@@ -5,17 +5,12 @@ import qs.modules.common
|
|||||||
import qs.modules.common.functions
|
import qs.modules.common.functions
|
||||||
import qs.modules.waffle.looks
|
import qs.modules.waffle.looks
|
||||||
|
|
||||||
WButton {
|
AcrylicButton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property var altAction: () => {}
|
property var altAction: () => {}
|
||||||
property var middleClickAction: () => {}
|
property var middleClickAction: () => {}
|
||||||
|
|
||||||
colBackground: ColorUtils.transparentize(Looks.colors.bg1)
|
|
||||||
colBackgroundHover: Looks.colors.bg1Hover
|
|
||||||
colBackgroundActive: Looks.colors.bg1Active
|
|
||||||
property color colBackgroundBorder
|
|
||||||
property color color
|
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
topInset: 4
|
topInset: 4
|
||||||
bottomInset: 4
|
bottomInset: 4
|
||||||
@@ -23,16 +18,7 @@ WButton {
|
|||||||
rightInset: 0
|
rightInset: 0
|
||||||
horizontalPadding: 8
|
horizontalPadding: 8
|
||||||
|
|
||||||
colBackgroundBorder: ColorUtils.transparentize(Looks.colors.bg1Border, (root.checked || root.hovered) ? Looks.backgroundTransparency : 1)
|
colBackground: ColorUtils.transparentize(Looks.colors.bg1)
|
||||||
color: {
|
|
||||||
if (root.down) {
|
|
||||||
return root.colBackgroundActive
|
|
||||||
} else if ((root.hovered && !root.down) || root.checked) {
|
|
||||||
return root.colBackgroundHover
|
|
||||||
} else {
|
|
||||||
return root.colBackground
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -50,15 +36,4 @@ WButton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
background: AcrylicRectangle {
|
|
||||||
shiny: ((root.hovered && !root.down) || root.checked)
|
|
||||||
color: root.color
|
|
||||||
radius: Looks.radius.medium
|
|
||||||
border.width: 1
|
|
||||||
border.color: root.colBackgroundBorder
|
|
||||||
|
|
||||||
Behavior on border.color {
|
|
||||||
animation: Looks.transition.color.createObject(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
|
import qs.modules.waffle.looks
|
||||||
|
|
||||||
|
WButton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
colBackground: Looks.colors.bg1
|
||||||
|
colBackgroundHover: Looks.colors.bg1Hover
|
||||||
|
colBackgroundActive: Looks.colors.bg1Active
|
||||||
|
property color colBackgroundBorder
|
||||||
|
property color color
|
||||||
|
property alias border: background.border
|
||||||
|
property alias shinyColor: background.borderColor
|
||||||
|
|
||||||
|
colBackgroundBorder: ColorUtils.transparentize(color, (root.checked || root.hovered) ? Looks.backgroundTransparency : 0)
|
||||||
|
color: {
|
||||||
|
if (root.down) {
|
||||||
|
return root.colBackgroundActive
|
||||||
|
} else if ((root.hovered && !root.down) || root.checked) {
|
||||||
|
return root.colBackgroundHover
|
||||||
|
} else {
|
||||||
|
return root.colBackground
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: AcrylicRectangle {
|
||||||
|
id: background
|
||||||
|
shiny: ((root.hovered && !root.down) || root.checked)
|
||||||
|
color: root.color
|
||||||
|
radius: Looks.radius.medium
|
||||||
|
border.width: 1
|
||||||
|
border.color: root.colBackgroundBorder
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
animation: Looks.transition.color.createObject(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,16 +9,17 @@ Rectangle {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool shiny: true // Top border
|
property bool shiny: true // Top border
|
||||||
property color borderColor: ColorUtils.transparentize(Looks.colors.bg2Border, shiny ? 0.5 : 1)
|
property color borderColor: ColorUtils.transparentize(Looks.colors.bg1Hover, 0.7)
|
||||||
|
property color internalBorderColor: ColorUtils.transparentize(borderColor, shiny ? 0.0 : 1)
|
||||||
color: Looks.colors.bg1Hover
|
color: Looks.colors.bg1Hover
|
||||||
radius: Looks.radius.medium
|
radius: Looks.radius.medium
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
animation: Looks.transition.color.createObject(this)
|
animation: Looks.transition.color.createObject(this)
|
||||||
}
|
}
|
||||||
Behavior on borderColor {
|
Behavior on internalBorderColor {
|
||||||
animation: Looks.transition.color.createObject(this)
|
animation: Looks.transition.color.createObject(this)
|
||||||
}
|
}
|
||||||
onBorderColorChanged: {
|
onInternalBorderColorChanged: {
|
||||||
borderCanvas.requestPaint();
|
borderCanvas.requestPaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +33,7 @@ Rectangle {
|
|||||||
var ctx = getContext("2d");
|
var ctx = getContext("2d");
|
||||||
ctx.clearRect(0, 0, width, height);
|
ctx.clearRect(0, 0, width, height);
|
||||||
|
|
||||||
var borderColor = root.borderColor;
|
var borderColor = root.internalBorderColor;
|
||||||
|
|
||||||
var r = root.radius;
|
var r = root.radius;
|
||||||
var fadeLength = Math.max(1, r);
|
var fadeLength = Math.max(1, r);
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ Singleton {
|
|||||||
property color controlBgHover: '#57575B'
|
property color controlBgHover: '#57575B'
|
||||||
property color controlFg: "#FFFFFF"
|
property color controlFg: "#FFFFFF"
|
||||||
property color accentUnfocused: "#848484"
|
property color accentUnfocused: "#848484"
|
||||||
|
property color link: "#235CCF"
|
||||||
}
|
}
|
||||||
darkColors: QtObject {
|
darkColors: QtObject {
|
||||||
id: darkColors
|
id: darkColors
|
||||||
@@ -80,6 +81,7 @@ Singleton {
|
|||||||
property color controlBgHover: "#CFCED1"
|
property color controlBgHover: "#CFCED1"
|
||||||
property color controlFg: "#454545"
|
property color controlFg: "#454545"
|
||||||
property color accentUnfocused: "#989898"
|
property color accentUnfocused: "#989898"
|
||||||
|
property color link: "#A7C9FC"
|
||||||
}
|
}
|
||||||
colors: QtObject {
|
colors: QtObject {
|
||||||
id: colors
|
id: colors
|
||||||
@@ -110,6 +112,7 @@ Singleton {
|
|||||||
property color controlBg: root.dark ? root.darkColors.controlBg : root.lightColors.controlBg
|
property color controlBg: root.dark ? root.darkColors.controlBg : root.lightColors.controlBg
|
||||||
property color controlBgHover: root.dark ? root.darkColors.controlBgHover : root.lightColors.controlBgHover
|
property color controlBgHover: root.dark ? root.darkColors.controlBgHover : root.lightColors.controlBgHover
|
||||||
property color controlFg: root.dark ? root.darkColors.controlFg : root.lightColors.controlFg
|
property color controlFg: root.dark ? root.darkColors.controlFg : root.lightColors.controlFg
|
||||||
|
property color link: root.dark ? root.darkColors.link : root.lightColors.link
|
||||||
property color danger: "#C42B1C"
|
property color danger: "#C42B1C"
|
||||||
property color dangerActive: "#B62D1F"
|
property color dangerActive: "#B62D1F"
|
||||||
property color warning: "#FF9900"
|
property color warning: "#FF9900"
|
||||||
|
|||||||
@@ -8,8 +8,11 @@ Text {
|
|||||||
color: Looks.colors.fg
|
color: Looks.colors.fg
|
||||||
|
|
||||||
font {
|
font {
|
||||||
|
hintingPreference: Font.PreferFullHinting
|
||||||
family: Looks.font.family.ui
|
family: Looks.font.family.ui
|
||||||
pixelSize: Looks.font.pixelSize.normal
|
pixelSize: Looks.font.pixelSize.normal
|
||||||
weight: Looks.font.weight.regular
|
weight: Looks.font.weight.regular
|
||||||
}
|
}
|
||||||
|
|
||||||
|
linkColor: Looks.colors.link
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-6
@@ -8,18 +8,24 @@ import qs.modules.common.functions
|
|||||||
import qs.modules.waffle.looks
|
import qs.modules.waffle.looks
|
||||||
|
|
||||||
WBorderlessButton {
|
WBorderlessButton {
|
||||||
id: headerButton
|
id: root
|
||||||
Layout.fillWidth: false
|
Layout.fillWidth: false
|
||||||
implicitWidth: 16
|
property real implicitSize: 16
|
||||||
implicitHeight: 16
|
implicitWidth: implicitSize
|
||||||
|
implicitHeight: implicitSize
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
colForeground: root.hovered && !root.pressed ? Looks.colors.fg : Looks.colors.fg1
|
||||||
|
|
||||||
|
Behavior on colForeground {
|
||||||
|
animation: Looks.transition.color.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
contentItem: Item {
|
contentItem: Item {
|
||||||
FluentIcon {
|
FluentIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
implicitSize: 16
|
implicitSize: root.implicitSize
|
||||||
icon: headerButton.icon.name
|
icon: root.icon.name
|
||||||
color: headerButton.hovered && !headerButton.pressed ? Looks.colors.fg : Looks.colors.fg1
|
color: root.colForeground
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-1
@@ -2,18 +2,27 @@ import QtQuick
|
|||||||
import qs
|
import qs
|
||||||
import qs.services
|
import qs.services
|
||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
import qs.modules.waffle.looks
|
import qs.modules.waffle.looks
|
||||||
|
|
||||||
SmallBorderedIconButton {
|
AcrylicButton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool iconVisible: true
|
property bool iconVisible: true
|
||||||
property string iconName: ""
|
property string iconName: ""
|
||||||
property bool iconFilled: true
|
property bool iconFilled: true
|
||||||
|
|
||||||
|
colBackground: Looks.colors.bg2
|
||||||
|
colBackgroundHover: Looks.colors.bg2Hover
|
||||||
|
colBackgroundActive: Looks.colors.bg2Active
|
||||||
|
property color colBorder: Looks.colors.bg2Border
|
||||||
|
property color colBorderToggled: Looks.colors.accent
|
||||||
|
border.color: checked ? colBorderToggled : colBorder
|
||||||
|
|
||||||
leftPadding: 12
|
leftPadding: 12
|
||||||
rightPadding: 12
|
rightPadding: 12
|
||||||
implicitWidth: focusButtonContent.implicitWidth + leftPadding + rightPadding
|
implicitWidth: focusButtonContent.implicitWidth + leftPadding + rightPadding
|
||||||
|
implicitHeight: 24
|
||||||
|
|
||||||
contentItem: Row {
|
contentItem: Row {
|
||||||
id: focusButtonContent
|
id: focusButtonContent
|
||||||
|
|||||||
+13
-1
@@ -12,6 +12,7 @@ MouseArea {
|
|||||||
|
|
||||||
required property var notificationGroup
|
required property var notificationGroup
|
||||||
readonly property var notifications: notificationGroup?.notifications ?? []
|
readonly property var notifications: notificationGroup?.notifications ?? []
|
||||||
|
property bool expanded: false
|
||||||
|
|
||||||
implicitWidth: contentLayout.implicitWidth
|
implicitWidth: contentLayout.implicitWidth
|
||||||
implicitHeight: contentLayout.implicitHeight
|
implicitHeight: contentLayout.implicitHeight
|
||||||
@@ -34,12 +35,23 @@ MouseArea {
|
|||||||
interactive: false
|
interactive: false
|
||||||
spacing: 4
|
spacing: 4
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
values: root.notifications.slice().reverse()
|
values: root.expanded ? root.notifications.slice().reverse() : root.notifications.slice(-1)
|
||||||
|
objectProp: "notificationId"
|
||||||
}
|
}
|
||||||
delegate: WSingleNotification {
|
delegate: WSingleNotification {
|
||||||
|
required property int index
|
||||||
required property var modelData
|
required property var modelData
|
||||||
width: ListView.view.width
|
width: ListView.view.width
|
||||||
notification: modelData
|
notification: modelData
|
||||||
|
groupExpandControlMessage: {
|
||||||
|
if (root.notifications.length === 0) return "";
|
||||||
|
if (!root.expanded) return Translation.tr("+%1 notifications").arg(root.notifications.length - 1);
|
||||||
|
if (index === root.notifications.length - 1) return Translation.tr("See fewer");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
onGroupExpandToggle: {
|
||||||
|
root.expanded = !root.expanded;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+95
-11
@@ -13,10 +13,17 @@ MouseArea {
|
|||||||
|
|
||||||
required property var notification
|
required property var notification
|
||||||
property bool expanded: false
|
property bool expanded: false
|
||||||
|
property string groupExpandControlMessage: ""
|
||||||
|
signal groupExpandToggle
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
implicitHeight: contentItem.implicitHeight
|
implicitHeight: contentItem.implicitHeight
|
||||||
implicitWidth: contentItem.implicitWidth
|
implicitWidth: contentItem.implicitWidth
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
animation: Looks.transition.enter.createObject(this)
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: contentItem
|
id: contentItem
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -26,32 +33,109 @@ MouseArea {
|
|||||||
implicitHeight: notificationContent.implicitHeight + padding * 2
|
implicitHeight: notificationContent.implicitHeight + padding * 2
|
||||||
implicitWidth: notificationContent.implicitWidth + padding * 2
|
implicitWidth: notificationContent.implicitWidth + padding * 2
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: Looks.applyContentTransparency(Looks.colors.ambientShadow)
|
border.color: ColorUtils.applyAlpha(Looks.colors.ambientShadow, 0.1)
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: notificationContent
|
id: notificationContent
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: contentItem.padding
|
anchors.margins: contentItem.padding
|
||||||
|
spacing: 19
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
WText {
|
|
||||||
text: NotificationUtils.getFriendlyNotifTimeString(root.notification?.time)
|
ExpandButton {
|
||||||
|
Layout.topMargin: -2
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationHeaderButton {
|
||||||
|
Layout.rightMargin: 4
|
||||||
|
opacity: root.containsMouse ? 1 : 0
|
||||||
|
icon.name: "dismiss"
|
||||||
|
implicitSize: 12
|
||||||
|
onClicked: {
|
||||||
|
Qt.callLater(() => {
|
||||||
|
Notifications.discardNotification(root.notification?.notificationId);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
WText {
|
spacing: 3
|
||||||
Layout.fillWidth: true
|
|
||||||
elide: Text.ElideRight
|
SummaryText {}
|
||||||
text: root.notification.summary
|
BodyText {}
|
||||||
|
}
|
||||||
|
|
||||||
|
AcrylicButton {
|
||||||
|
id: groupExpandButton
|
||||||
|
visible: root.groupExpandControlMessage !== ""
|
||||||
|
Layout.bottomMargin: 2
|
||||||
|
horizontalPadding: 10
|
||||||
|
implicitHeight: 24
|
||||||
|
implicitWidth: expandButtonText.implicitWidth + horizontalPadding * 2
|
||||||
|
onClicked: root.groupExpandToggle()
|
||||||
|
contentItem: Item {
|
||||||
|
WText {
|
||||||
|
id: expandButtonText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: root.groupExpandControlMessage
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component SummaryText: WText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
elide: Text.ElideRight
|
||||||
|
text: root.notification?.summary
|
||||||
|
font.pixelSize: Looks.font.pixelSize.large
|
||||||
|
}
|
||||||
|
|
||||||
|
component BodyText: WText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
elide: Text.ElideRight
|
||||||
|
verticalAlignment: Text.AlignTop
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
maximumLineCount: root.expanded ? 100 : 1
|
||||||
|
text: root.notification?.body
|
||||||
|
color: Looks.colors.subfg
|
||||||
|
}
|
||||||
|
|
||||||
|
component ExpandButton: NotificationHeaderButton {
|
||||||
|
id: expandButton
|
||||||
|
implicitWidth: expandButtonContent.implicitWidth
|
||||||
|
onClicked: root.expanded = !root.expanded
|
||||||
|
|
||||||
|
contentItem: Item {
|
||||||
|
id: expandButtonContent
|
||||||
|
implicitWidth: expandButtonRow.implicitWidth
|
||||||
|
implicitHeight: expandButtonRow.implicitHeight
|
||||||
|
RowLayout {
|
||||||
|
id: expandButtonRow
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 8
|
||||||
WText {
|
WText {
|
||||||
Layout.fillWidth: true
|
color: expandButton.colForeground
|
||||||
elide: Text.ElideRight
|
text: NotificationUtils.getFriendlyNotifTimeString(root.notification?.time)
|
||||||
wrapMode: Text.Wrap
|
}
|
||||||
maximumLineCount: root.expanded ? 100 : 1
|
FluentIcon {
|
||||||
|
Layout.rightMargin: 12
|
||||||
|
icon: "chevron-down"
|
||||||
|
implicitSize: 18
|
||||||
|
rotation: root.expanded ? -180 : 0
|
||||||
|
color: expandButton.colForeground
|
||||||
|
Behavior on rotation {
|
||||||
|
animation: Looks.transition.rotate.createObject(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user