waffles: notif center: calendar header and focus

This commit is contained in:
end-4
2025-11-24 10:18:05 +01:00
parent 449d6fc285
commit e6f36114bd
29 changed files with 420 additions and 59 deletions
@@ -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)
}
}
}
}
}
}
@@ -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)
}
}
@@ -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(`<font color="${Looks.colors.fg.toString()}">${TimerService.focusTime / 60}</font>`)
}
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")
}
}
}
}
}
@@ -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
}
}
}
}
}
@@ -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
}
}
}
@@ -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();
}
}