From e6f36114bd53c71448390626d6334ed6043c5b0c Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Mon, 24 Nov 2025 10:18:05 +0100 Subject: [PATCH] waffles: notif center: calendar header and focus --- .../ii/assets/icons/fluent/add-filled.svg | 1 + .../quickshell/ii/assets/icons/fluent/add.svg | 1 + .../ii/assets/icons/fluent/stop-filled.svg | 1 + .../ii/assets/icons/fluent/stop.svg | 1 + .../assets/icons/fluent/subtract-filled.svg | 1 + .../ii/assets/icons/fluent/subtract.svg | 1 + .../actionCenter/ActionCenterContent.qml | 15 ++-- .../actionCenter/WaffleActionCenter.qml | 13 +-- .../bluetooth/BluetoothControl.qml | 4 +- .../nightLight/NightLightControl.qml | 4 +- .../volumeControl/VolumeControl.qml | 8 +- .../waffle/actionCenter/wifi/WifiControl.qml | 4 +- .../{actionCenter => looks}/BodyRectangle.qml | 0 .../FooterMoreButton.qml | 0 .../FooterRectangle.qml | 2 +- .../ii/modules/waffle/looks/Looks.qml | 6 +- .../waffle/looks/WBarAttachedPanelContent.qml | 68 ++++++++++----- .../modules/waffle/looks/WBorderedButton.qml | 18 ++++ .../ii/modules/waffle/looks/WPane.qml | 4 +- .../WPanelPageColumn.qml} | 0 .../WPanelSeparator.qml} | 0 .../notificationCenter/CalendarHeader.qml | 51 +++++++++++ .../notificationCenter/CalendarView.qml | 23 +++++ .../waffle/notificationCenter/FocusFooter.qml | 87 +++++++++++++++++++ .../NotificationCenterContent.qml | 57 ++++++++++++ .../SmallBorderedIconButton.qml | 18 ++++ .../WaffleNotificationCenter.qml | 85 ++++++++++++++++++ .../quickshell/ii/services/DateTime.qml | 2 +- dots/.config/quickshell/ii/shell.qml | 4 +- 29 files changed, 420 insertions(+), 59 deletions(-) create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/add-filled.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/add.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/stop-filled.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/stop.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/subtract-filled.svg create mode 100644 dots/.config/quickshell/ii/assets/icons/fluent/subtract.svg rename dots/.config/quickshell/ii/modules/waffle/{actionCenter => looks}/BodyRectangle.qml (100%) rename dots/.config/quickshell/ii/modules/waffle/{actionCenter => looks}/FooterMoreButton.qml (100%) rename dots/.config/quickshell/ii/modules/waffle/{actionCenter => looks}/FooterRectangle.qml (92%) create mode 100644 dots/.config/quickshell/ii/modules/waffle/looks/WBorderedButton.qml rename dots/.config/quickshell/ii/modules/waffle/{actionCenter/PageColumn.qml => looks/WPanelPageColumn.qml} (100%) rename dots/.config/quickshell/ii/modules/waffle/{actionCenter/Separator.qml => looks/WPanelSeparator.qml} (100%) create mode 100644 dots/.config/quickshell/ii/modules/waffle/notificationCenter/CalendarHeader.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/notificationCenter/CalendarView.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/notificationCenter/FocusFooter.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/notificationCenter/NotificationCenterContent.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/notificationCenter/SmallBorderedIconButton.qml create mode 100644 dots/.config/quickshell/ii/modules/waffle/notificationCenter/WaffleNotificationCenter.qml diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/add-filled.svg b/dots/.config/quickshell/ii/assets/icons/fluent/add-filled.svg new file mode 100644 index 000000000..6b1a81835 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/add-filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/add.svg b/dots/.config/quickshell/ii/assets/icons/fluent/add.svg new file mode 100644 index 000000000..c983f3518 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/stop-filled.svg b/dots/.config/quickshell/ii/assets/icons/fluent/stop-filled.svg new file mode 100644 index 000000000..ef8a91225 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/stop-filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/stop.svg b/dots/.config/quickshell/ii/assets/icons/fluent/stop.svg new file mode 100644 index 000000000..26eb3ea04 --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/stop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/subtract-filled.svg b/dots/.config/quickshell/ii/assets/icons/fluent/subtract-filled.svg new file mode 100644 index 000000000..128a7f96b --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/subtract-filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/assets/icons/fluent/subtract.svg b/dots/.config/quickshell/ii/assets/icons/fluent/subtract.svg new file mode 100644 index 000000000..3e1e2471c --- /dev/null +++ b/dots/.config/quickshell/ii/assets/icons/fluent/subtract.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dots/.config/quickshell/ii/modules/waffle/actionCenter/ActionCenterContent.qml b/dots/.config/quickshell/ii/modules/waffle/actionCenter/ActionCenterContent.qml index d01502444..b69666660 100644 --- a/dots/.config/quickshell/ii/modules/waffle/actionCenter/ActionCenterContent.qml +++ b/dots/.config/quickshell/ii/modules/waffle/actionCenter/ActionCenterContent.qml @@ -15,7 +15,7 @@ WBarAttachedPanelContent { readonly property bool barAtBottom: Config.options.waffles.bar.bottom - contentItem: Column { + contentItem: ColumnLayout { // This somewhat sophisticated anchoring is needed to make opening anim not jump abruptly when stuff appear anchors { left: parent.left @@ -28,24 +28,21 @@ WBarAttachedPanelContent { spacing: 12 WPane { - visible: MprisController.activePlayer != null && MprisController.isRealPlayer(MprisController.activePlayer) - anchors { - left: parent.left - right: parent.right - } + opacity: (MprisController.activePlayer != null && MprisController.isRealPlayer(MprisController.activePlayer)) ? 1 : 0 + Layout.fillWidth: true contentItem: MediaPaneContent {} } WPane { + Layout.fillWidth: true contentItem: WStackView { id: stackView - anchors.fill: parent implicitWidth: initItem.implicitWidth implicitHeight: initItem.implicitHeight - initialItem: PageColumn { + initialItem: WPanelPageColumn { id: initItem MainPageBody {} - Separator {} + WPanelSeparator {} MainPageFooter {} } diff --git a/dots/.config/quickshell/ii/modules/waffle/actionCenter/WaffleActionCenter.qml b/dots/.config/quickshell/ii/modules/waffle/actionCenter/WaffleActionCenter.qml index 8fe33fa47..56fbedda3 100644 --- a/dots/.config/quickshell/ii/modules/waffle/actionCenter/WaffleActionCenter.qml +++ b/dots/.config/quickshell/ii/modules/waffle/actionCenter/WaffleActionCenter.qml @@ -15,12 +15,12 @@ Scope { target: GlobalStates function onSidebarLeftOpenChanged() { - if (GlobalStates.sidebarLeftOpen) barLoader.active = true; + if (GlobalStates.sidebarLeftOpen) panelLoader.active = true; } } Loader { - id: barLoader + id: panelLoader active: GlobalStates.sidebarLeftOpen sourceComponent: PanelWindow { id: panelWindow @@ -56,16 +56,9 @@ Scope { id: content anchors.fill: parent - focus: true - Keys.onPressed: event => { // Esc to close - if (event.key === Qt.Key_Escape) { - content.close() - } - } - onClosed: { GlobalStates.sidebarLeftOpen = false; - barLoader.active = false; + panelLoader.active = false; } } } diff --git a/dots/.config/quickshell/ii/modules/waffle/actionCenter/bluetooth/BluetoothControl.qml b/dots/.config/quickshell/ii/modules/waffle/actionCenter/bluetooth/BluetoothControl.qml index e0e6327a6..72f442b87 100644 --- a/dots/.config/quickshell/ii/modules/waffle/actionCenter/bluetooth/BluetoothControl.qml +++ b/dots/.config/quickshell/ii/modules/waffle/actionCenter/bluetooth/BluetoothControl.qml @@ -23,7 +23,7 @@ Item { Bluetooth.defaultAdapter.discovering = false; } - PageColumn { + WPanelPageColumn { anchors.fill: parent BodyRectangle { @@ -96,7 +96,7 @@ Item { } } - Separator {} + WPanelSeparator {} FooterRectangle { FooterMoreButton { diff --git a/dots/.config/quickshell/ii/modules/waffle/actionCenter/nightLight/NightLightControl.qml b/dots/.config/quickshell/ii/modules/waffle/actionCenter/nightLight/NightLightControl.qml index 71630295c..591e56399 100644 --- a/dots/.config/quickshell/ii/modules/waffle/actionCenter/nightLight/NightLightControl.qml +++ b/dots/.config/quickshell/ii/modules/waffle/actionCenter/nightLight/NightLightControl.qml @@ -24,7 +24,7 @@ Item { Bluetooth.defaultAdapter.discovering = false; } - PageColumn { + WPanelPageColumn { anchors.fill: parent BodyRectangle { @@ -61,7 +61,7 @@ Item { } } - Separator {} + WPanelSeparator {} FooterRectangle {} } diff --git a/dots/.config/quickshell/ii/modules/waffle/actionCenter/volumeControl/VolumeControl.qml b/dots/.config/quickshell/ii/modules/waffle/actionCenter/volumeControl/VolumeControl.qml index b3e97a78e..52fe9ab3d 100644 --- a/dots/.config/quickshell/ii/modules/waffle/actionCenter/volumeControl/VolumeControl.qml +++ b/dots/.config/quickshell/ii/modules/waffle/actionCenter/volumeControl/VolumeControl.qml @@ -14,7 +14,7 @@ Item { id: root property bool output: true - PageColumn { + WPanelPageColumn { anchors.fill: parent BodyRectangle { @@ -48,7 +48,7 @@ Item { } } - Separator {} + WPanelSeparator {} FooterRectangle { WButton { @@ -103,7 +103,7 @@ Item { } } - Separator { + WPanelSeparator { visible: EasyEffects.available && root.output color: Looks.colors.bg2Hover } @@ -129,7 +129,7 @@ Item { onClicked: EasyEffects.enable() } - Separator { + WPanelSeparator { color: Looks.colors.bg2Hover } diff --git a/dots/.config/quickshell/ii/modules/waffle/actionCenter/wifi/WifiControl.qml b/dots/.config/quickshell/ii/modules/waffle/actionCenter/wifi/WifiControl.qml index e6c91292a..c90d06fc0 100644 --- a/dots/.config/quickshell/ii/modules/waffle/actionCenter/wifi/WifiControl.qml +++ b/dots/.config/quickshell/ii/modules/waffle/actionCenter/wifi/WifiControl.qml @@ -19,7 +19,7 @@ Item { Network.rescanWifi(); } - PageColumn { + WPanelPageColumn { anchors.fill: parent BodyRectangle { @@ -86,7 +86,7 @@ Item { } } - Separator {} + WPanelSeparator {} FooterRectangle { FooterMoreButton { diff --git a/dots/.config/quickshell/ii/modules/waffle/actionCenter/BodyRectangle.qml b/dots/.config/quickshell/ii/modules/waffle/looks/BodyRectangle.qml similarity index 100% rename from dots/.config/quickshell/ii/modules/waffle/actionCenter/BodyRectangle.qml rename to dots/.config/quickshell/ii/modules/waffle/looks/BodyRectangle.qml diff --git a/dots/.config/quickshell/ii/modules/waffle/actionCenter/FooterMoreButton.qml b/dots/.config/quickshell/ii/modules/waffle/looks/FooterMoreButton.qml similarity index 100% rename from dots/.config/quickshell/ii/modules/waffle/actionCenter/FooterMoreButton.qml rename to dots/.config/quickshell/ii/modules/waffle/looks/FooterMoreButton.qml diff --git a/dots/.config/quickshell/ii/modules/waffle/actionCenter/FooterRectangle.qml b/dots/.config/quickshell/ii/modules/waffle/looks/FooterRectangle.qml similarity index 92% rename from dots/.config/quickshell/ii/modules/waffle/actionCenter/FooterRectangle.qml rename to dots/.config/quickshell/ii/modules/waffle/looks/FooterRectangle.qml index e3f7cd120..dcf4f519d 100644 --- a/dots/.config/quickshell/ii/modules/waffle/actionCenter/FooterRectangle.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/FooterRectangle.qml @@ -12,6 +12,6 @@ Rectangle { Layout.fillWidth: true color: "transparent" - implicitWidth: 360 + implicitWidth: 358 implicitHeight: 47 } diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml index 26ef9f101..0350f5004 100644 --- a/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/Looks.qml @@ -20,7 +20,7 @@ Singleton { property real backgroundTransparency: 0.13 property real panelBackgroundTransparency: 0.12 property real panelLayerTransparency: root.dark ? 0.9 : 0.7 - property real contentTransparency: root.dark ? 0.9 : 0.5 + property real contentTransparency: root.dark ? 0.87 : 0.5 function applyBackgroundTransparency(col) { return ColorUtils.applyAlpha(col, 1 - root.backgroundTransparency) } @@ -41,8 +41,8 @@ Singleton { property color bg1Border: '#d7d7d7' property color bg2: "#FBFBFB" property color bg2Base: "#FBFBFB" - property color bg2Hover: "#FDFDFD" - property color bg2Active: "#FDFDFD" + property color bg2Hover: '#ffffff' + property color bg2Active: '#eeeeee' property color bg2Border: '#cdcdcd' property color subfg: "#5C5C5C" property color fg: "#000000" diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/WBarAttachedPanelContent.qml b/dots/.config/quickshell/ii/modules/waffle/looks/WBarAttachedPanelContent.qml index 657897ef1..97ee49d1e 100644 --- a/dots/.config/quickshell/ii/modules/waffle/looks/WBarAttachedPanelContent.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/WBarAttachedPanelContent.qml @@ -1,3 +1,4 @@ +pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import Qt5Compat.GraphicalEffects @@ -10,11 +11,13 @@ import qs.modules.waffle.looks Item { id: root - signal closed() + signal closed required property Item contentItem property real visualMargin: 12 property int closeAnimDuration: 150 + property bool revealFromSides: false + property bool revealFromLeft: true function close() { closeAnim.start(); @@ -25,16 +28,25 @@ Item { implicitHeight: contentItem.implicitHeight + visualMargin * 2 implicitWidth: contentItem.implicitWidth + visualMargin * 2 + focus: true + Keys.onPressed: event => { // Esc to close + if (event.key === Qt.Key_Escape) { + content.close(); + } + } + Item { id: panelContent anchors { - left: parent.left - right: parent.right - top: root.barAtBottom ? undefined : parent.top - bottom: root.barAtBottom ? parent.bottom : undefined + left: (root.revealFromSides && !root.revealFromLeft) ? undefined : parent.left + right: (root.revealFromSides && root.revealFromLeft) ? undefined : parent.right + top: (!root.revealFromSides && root.barAtBottom) ? undefined : parent.top + bottom: (!root.revealFromSides && !root.barAtBottom) ? undefined : parent.bottom // Opening anim - bottomMargin: root.barAtBottom ? sourceEdgeMargin : root.visualMargin - topMargin: root.barAtBottom ? root.visualMargin : sourceEdgeMargin + bottomMargin: (!root.revealFromSides && root.barAtBottom) ? sourceEdgeMargin : root.visualMargin + topMargin: (!root.revealFromSides && !root.barAtBottom) ? sourceEdgeMargin : root.visualMargin + leftMargin: (root.revealFromSides && root.revealFromLeft) ? sideEdgeMargin : root.visualMargin + rightMargin: (root.revealFromSides && !root.revealFromLeft) ? sideEdgeMargin : root.visualMargin } Component.onCompleted: { @@ -42,24 +54,22 @@ Item { } property real sourceEdgeMargin: -(implicitHeight + root.visualMargin) - PropertyAnimation { + property real sideEdgeMargin: -(implicitWidth + root.visualMargin) + OpenAnim { id: openAnim - target: panelContent - property: "sourceEdgeMargin" - to: root.visualMargin - duration: 200 - easing.type: Easing.BezierSpline - easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn + properties: "sourceEdgeMargin, sideEdgeMargin" } SequentialAnimation { id: closeAnim - PropertyAnimation { - target: panelContent - property: "sourceEdgeMargin" - to: -(implicitHeight + root.visualMargin) - duration: root.closeAnimDuration - easing.type: Easing.BezierSpline - easing.bezierCurve: Looks.transition.easing.bezierCurve.easeOut + ParallelAnimation { + CloseAnim { + property: "sourceEdgeMargin" + to: -(implicitHeight + root.visualMargin) + } + CloseAnim { + property: "sideEdgeMargin" + to: -(implicitWidth + root.visualMargin) + } } ScriptAction { script: { @@ -70,5 +80,19 @@ Item { implicitWidth: root.contentItem.implicitWidth implicitHeight: root.contentItem.implicitHeight children: [root.contentItem] - } + } + + component OpenAnim: PropertyAnimation { + target: panelContent + to: root.visualMargin + duration: 200 + easing.type: Easing.BezierSpline + easing.bezierCurve: Looks.transition.easing.bezierCurve.easeIn + } + component CloseAnim: PropertyAnimation { + target: panelContent + duration: root.closeAnimDuration + easing.type: Easing.BezierSpline + easing.bezierCurve: Looks.transition.easing.bezierCurve.easeOut + } } diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/WBorderedButton.qml b/dots/.config/quickshell/ii/modules/waffle/looks/WBorderedButton.qml new file mode 100644 index 000000000..74cb35f8b --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/looks/WBorderedButton.qml @@ -0,0 +1,18 @@ +import QtQuick +import QtQuick.Controls +import Quickshell +import qs.modules.common +import qs.modules.common.functions +import qs.modules.waffle.looks + +WButton { + id: root + + colBackground: Looks.colors.bg2 + colBackgroundHover: Looks.colors.bg2Hover + colBackgroundActive: Looks.colors.bg2Active + border.color: Looks.colors.bg2Border + border.width: root.pressed ? 2 : 1 + + +} diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/WPane.qml b/dots/.config/quickshell/ii/modules/waffle/looks/WPane.qml index 806afcd37..68e836b66 100644 --- a/dots/.config/quickshell/ii/modules/waffle/looks/WPane.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/WPane.qml @@ -15,8 +15,8 @@ Item { property alias border: borderRect property alias borderColor: borderRect.border.color - implicitWidth: contentItem.implicitWidth - implicitHeight: contentItem.implicitHeight + implicitWidth: borderRect.implicitWidth + implicitHeight: borderRect.implicitHeight WRectangularShadow { target: borderRect diff --git a/dots/.config/quickshell/ii/modules/waffle/actionCenter/PageColumn.qml b/dots/.config/quickshell/ii/modules/waffle/looks/WPanelPageColumn.qml similarity index 100% rename from dots/.config/quickshell/ii/modules/waffle/actionCenter/PageColumn.qml rename to dots/.config/quickshell/ii/modules/waffle/looks/WPanelPageColumn.qml diff --git a/dots/.config/quickshell/ii/modules/waffle/actionCenter/Separator.qml b/dots/.config/quickshell/ii/modules/waffle/looks/WPanelSeparator.qml similarity index 100% rename from dots/.config/quickshell/ii/modules/waffle/actionCenter/Separator.qml rename to dots/.config/quickshell/ii/modules/waffle/looks/WPanelSeparator.qml diff --git a/dots/.config/quickshell/ii/modules/waffle/notificationCenter/CalendarHeader.qml b/dots/.config/quickshell/ii/modules/waffle/notificationCenter/CalendarHeader.qml new file mode 100644 index 000000000..79543846b --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/notificationCenter/CalendarHeader.qml @@ -0,0 +1,51 @@ +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell +import qs +import qs.services +import qs.modules.common +import qs.modules.common.functions +import qs.modules.waffle.looks + +FooterRectangle { + id: root + + property bool collapsed + implicitWidth: 334 + + RowLayout { + anchors { + fill: parent + leftMargin: 16 + rightMargin: 16 + topMargin: 12 + bottomMargin: 12 + } + + WText { + Layout.fillWidth: true + font.pixelSize: Looks.font.pixelSize.large + text: DateTime.collapsedCalendarFormat + } + + WBorderedButton { + implicitWidth: 24 + implicitHeight: 24 + padding: 0 + onClicked: root.collapsed = !root.collapsed + contentItem: Item { + FluentIcon { + anchors.centerIn: parent + implicitSize: 12 + icon: "chevron-down" + rotation: root.collapsed ? 180 : 0 + Behavior on rotation { + animation: Looks.transition.rotate.createObject(this) + } + } + } + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/notificationCenter/CalendarView.qml b/dots/.config/quickshell/ii/modules/waffle/notificationCenter/CalendarView.qml new file mode 100644 index 000000000..335cecf5a --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/notificationCenter/CalendarView.qml @@ -0,0 +1,23 @@ +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell +import qs +import qs.services +import qs.modules.common +import qs.modules.common.functions +import qs.modules.waffle.looks + +BodyRectangle { + id: root + + property bool collapsed + implicitHeight: collapsed ? 0 : 400 // For now + implicitWidth: 334 + + Behavior on implicitHeight { + animation: Looks.transition.enter.createObject(this) + } + +} diff --git a/dots/.config/quickshell/ii/modules/waffle/notificationCenter/FocusFooter.qml b/dots/.config/quickshell/ii/modules/waffle/notificationCenter/FocusFooter.qml new file mode 100644 index 000000000..95fc529c2 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/notificationCenter/FocusFooter.qml @@ -0,0 +1,87 @@ +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell +import qs +import qs.services +import qs.modules.common +import qs.modules.common.functions +import qs.modules.waffle.looks + +FooterRectangle { + Layout.fillWidth: true + implicitWidth: 334 + + RowLayout { + anchors { + fill: parent + leftMargin: 16 + rightMargin: 16 + topMargin: 12 + bottomMargin: 12 + } + spacing: 0 + + SmallBorderedIconButton { + visible: !TimerService.pomodoroRunning + icon.name: "subtract" + onClicked: Config.options.time.pomodoro.focus -= 300 // 5 mins + } + + WTextWithFixedWidth { + visible: !TimerService.pomodoroRunning + implicitWidth: 81 + horizontalAlignment: Text.AlignHCenter + color: Looks.colors.subfg + text: Translation.tr("%1 mins").arg(`${TimerService.focusTime / 60}`) + } + + SmallBorderedIconButton { + visible: !TimerService.pomodoroRunning + icon.name: "add" + onClicked: Config.options.time.pomodoro.focus += 300 // 5 mins + } + + WText { + visible: TimerService.pomodoroRunning + font.pixelSize: Looks.font.pixelSize.large + text: Translation.tr("Focusing") + } + + Item { + Layout.fillWidth: true + } + + SmallBorderedIconButton { + leftPadding: 12 + rightPadding: 12 + implicitWidth: focusButtonContent.implicitWidth + leftPadding + rightPadding + + onClicked: { + if (TimerService.pomodoroRunning) { + TimerService.togglePomodoro() + TimerService.resetPomodoro() + } else { + TimerService.togglePomodoro() + Quickshell.execDetached(["qs", "-p", Quickshell.shellPath(""), "ipc", "call", "sidebarRight", "toggle"]); + } + } + + contentItem: Row { + id: focusButtonContent + spacing: 4 + FluentIcon { + icon: TimerService.pomodoroRunning ? "stop" : "play" + filled: true + implicitSize: 14 + anchors.verticalCenter: parent.verticalCenter + } + WText { + anchors.verticalCenter: parent.verticalCenter + text: TimerService.pomodoroRunning ? Translation.tr("End session") : Translation.tr("Focus") + } + } + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/notificationCenter/NotificationCenterContent.qml b/dots/.config/quickshell/ii/modules/waffle/notificationCenter/NotificationCenterContent.qml new file mode 100644 index 000000000..44ceef6ba --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/notificationCenter/NotificationCenterContent.qml @@ -0,0 +1,57 @@ +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell +import Qt.labs.synchronizer +import qs +import qs.services +import qs.modules.common +import qs.modules.common.functions +import qs.modules.waffle.looks + +WBarAttachedPanelContent { + id: root + + readonly property bool barAtBottom: Config.options.waffles.bar.bottom + revealFromSides: true + revealFromLeft: false + + property bool collapsed: false + + contentItem: Column { + anchors { + horizontalCenter: parent.horizontalCenter + top: root.barAtBottom ? undefined : parent.top + bottom: root.barAtBottom ? parent.bottom : undefined + } + spacing: 12 + + WPane { + contentItem: ColumnLayout { + spacing: 0 + CalendarHeader { + Layout.fillWidth: true + Synchronizer on collapsed { + property alias source: root.collapsed + } + } + + WPanelSeparator { visible: !root.collapsed } + + CalendarView { + Layout.fillWidth: true + Synchronizer on collapsed { + property alias source: root.collapsed + } + } + + WPanelSeparator {} + + FocusFooter { + Layout.fillWidth: true + } + } + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/notificationCenter/SmallBorderedIconButton.qml b/dots/.config/quickshell/ii/modules/waffle/notificationCenter/SmallBorderedIconButton.qml new file mode 100644 index 000000000..1236779a7 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/notificationCenter/SmallBorderedIconButton.qml @@ -0,0 +1,18 @@ +import QtQuick +import qs +import qs.services +import qs.modules.common +import qs.modules.waffle.looks + +WBorderedButton { + id: root + implicitWidth: 24 + implicitHeight: 24 + contentItem: Item { + FluentIcon { + anchors.centerIn: parent + implicitSize: 12 + icon: root.icon.name + } + } +} diff --git a/dots/.config/quickshell/ii/modules/waffle/notificationCenter/WaffleNotificationCenter.qml b/dots/.config/quickshell/ii/modules/waffle/notificationCenter/WaffleNotificationCenter.qml new file mode 100644 index 000000000..4caed7664 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/waffle/notificationCenter/WaffleNotificationCenter.qml @@ -0,0 +1,85 @@ +import QtQuick +import Quickshell +import Quickshell.Io +import Quickshell.Wayland +import Quickshell.Hyprland +import qs +import qs.services +import qs.modules.common +import qs.modules.common.widgets + +Scope { + id: root + + Connections { + target: GlobalStates + + function onSidebarRightOpenChanged() { + if (GlobalStates.sidebarRightOpen) panelLoader.active = true; + } + } + + Loader { + id: panelLoader + active: GlobalStates.sidebarRightOpen + sourceComponent: PanelWindow { + id: panelWindow + exclusiveZone: 0 + WlrLayershell.namespace: "quickshell:wNotificationCenter" + WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand + color: "transparent" + + anchors { + bottom: true + top: true + right: true + } + + implicitWidth: content.implicitWidth + implicitHeight: content.implicitHeight + + HyprlandFocusGrab { + id: focusGrab + active: true + windows: [panelWindow] + onCleared: content.close(); + } + + Connections { + target: GlobalStates + function onSidebarRightOpenChanged() { + if (!GlobalStates.sidebarRightOpen) content.close(); + } + } + + NotificationCenterContent { + id: content + anchors.fill: parent + + onClosed: { + GlobalStates.sidebarRightOpen = false; + panelLoader.active = false; + } + } + } + } + + function toggleOpen() { + GlobalStates.sidebarRightOpen = !GlobalStates.sidebarRightOpen; + } + + IpcHandler { + target: "sidebarRight" + + function toggle() { + root.toggleOpen(); + } + } + + GlobalShortcut { + name: "sidebarRightToggle" + description: "Toggles notification center on press" + + onPressed: root.toggleOpen(); + } +} diff --git a/dots/.config/quickshell/ii/services/DateTime.qml b/dots/.config/quickshell/ii/services/DateTime.qml index 514da212b..e1a8300d4 100644 --- a/dots/.config/quickshell/ii/services/DateTime.qml +++ b/dots/.config/quickshell/ii/services/DateTime.qml @@ -22,7 +22,7 @@ Singleton { property string shortDate: Qt.locale().toString(clock.date, Config.options?.time.shortDateFormat ?? "dd/MM") property string date: Qt.locale().toString(clock.date, Config.options?.time.dateWithYearFormat ?? "dd/MM/yyyy") property string longDate: Qt.locale().toString(clock.date, Config.options?.time.dateFormat ?? "dddd, dd/MM") - property string collapsedCalendarFormat: Qt.locale().toString(clock.date, "dd MMMM yyyy") + property string collapsedCalendarFormat: Qt.locale().toString(clock.date, "dddd, MMMM dd") property string uptime: "0h, 0m" Timer { diff --git a/dots/.config/quickshell/ii/shell.qml b/dots/.config/quickshell/ii/shell.qml index b8193812f..6f401c90f 100644 --- a/dots/.config/quickshell/ii/shell.qml +++ b/dots/.config/quickshell/ii/shell.qml @@ -31,6 +31,7 @@ import qs.modules.ii.wallpaperSelector import qs.modules.waffle.actionCenter import qs.modules.waffle.background import qs.modules.waffle.bar +import qs.modules.waffle.notificationCenter import qs.modules.waffle.onScreenDisplay import QtQuick @@ -79,6 +80,7 @@ ShellRoot { PanelLoader { identifier: "wActionCenter"; component: WaffleActionCenter {} } PanelLoader { identifier: "wBar"; component: WaffleBar {} } PanelLoader { identifier: "wBackground"; component: WaffleBackground {} } + PanelLoader { identifier: "wNotificationCenter"; component: WaffleNotificationCenter {} } PanelLoader { identifier: "wOnScreenDisplay"; component: WaffleOSD {} } ReloadPopup {} @@ -92,7 +94,7 @@ ShellRoot { property list families: ["ii", "waffle"] property var panelFamilies: ({ "ii": ["iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector"], - "waffle": ["wActionCenter", "wBar", "wBackground", "wOnScreenDisplay", "iiCheatsheet", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiSessionScreen", "iiSidebarRight", "iiWallpaperSelector"], + "waffle": ["wActionCenter", "wBar", "wBackground", "wNotificationCenter", "wOnScreenDisplay", "iiCheatsheet", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiSessionScreen", "iiWallpaperSelector"], }) function cyclePanelFamily() { const currentIndex = families.indexOf(Config.options.panelFamily)