aboutsummaryrefslogtreecommitdiff
path: root/quickshell/Calendar.qml
blob: 0b79553dbf7efff8c62d123fbd4958a1101ea4a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import QtQuick
import QtQuick.Layouts
import Quickshell
import Quickshell.Io

Rectangle {
  id: calendarRoot
  
  color: shellRoot.black
  antialiasing: true
  focus: true
  
  property bool isVisible: false
  property int monthOffset: 0
  
  signal requestClose()
  Keys.onEscapePressed: {
    monthOffset = 0;
    requestClose()
  }
  
  Column {
    anchors.fill: parent
    spacing: 1
    Rectangle {
      width: parent.width
      height: parent.height
      color: shellRoot.black
      
      Column {
        anchors.fill: parent
        anchors.margins: 5
        spacing: 6

        RowLayout {
          width: parent.width
          Text {
            text: " <"
            font.pixelSize: 20
            font.family: shellRoot.fontFamily
            color: shellRoot.white
            MouseArea {
              anchors.fill: parent
              onClicked: monthOffset--;
            }
          }
          Item { Layout.fillWidth: true }
          Text {
            text: {
              const now = new Date()
              const monthNames = ["January", "February", "March", "April", "May", "June",
              "July", "August", "September", "October", "November", "December"]
              let shiftedMonth = now.getMonth() + monthOffset;
              let year = now.getFullYear();
              year += Math.floor(shiftedMonth / 12);
              shiftedMonth %= 12;
              return monthNames[shiftedMonth] + " " + year
            }
            font.family: shellRoot.fontFamily
            font.pixelSize: 20
            font.weight: Font.Medium
            color: shellRoot.white
            horizontalAlignment: Text.AlignHCenter
          }
          Item { Layout.fillWidth: true }
          Text {
            text: "> "
            font.pixelSize: 20
            font.family: shellRoot.fontFamily
            color: shellRoot.white
            MouseArea {
              anchors.fill: parent
              onClicked: monthOffset++;
            }
          }
        }
        Grid {
          width: parent.width
          columns: 7
          columnSpacing: 1
          rowSpacing: 1
       
          Repeater {
            model: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
            
            Text {
              text: modelData
              font.family: shellRoot.fontFamily
              font.pixelSize: 15
              font.weight: Font.Medium
              color: shellRoot.white
              width: 50
              height: 20
              horizontalAlignment: Text.AlignHCenter
              verticalAlignment: Text.AlignVCenter
            }
          }
          Repeater {
            model: 35
            
            Rectangle {
              width: 60
              height: 60
              
              property var now: new Date()
              property int currentDay: now.getDate()
              property int currentMonth: (now.getMonth() + monthOffset) % 12
              property int currentYear: now.getFullYear() + Math.floor((now.getMonth() + monthOffset) / 12)
              
              // Calculate what day this cell represents
              property var firstDay: new Date(currentYear, currentMonth, 1)
              property int startOffset: firstDay.getDay()  // 0 = Sunday
              property int dayNumber: index - startOffset + 1
              property var lastDay: new Date(currentYear, currentMonth + 1, 0)
              property int daysInMonth: lastDay.getDate()
              property bool isCurrentDay: dayNumber === currentDay
              property bool isValidDay: dayNumber >= 1 && dayNumber <= daysInMonth
              
              color: {
                if (!isValidDay) return "transparent"
                if (monthOffset == 0 && isCurrentDay) return shellRoot.green
                return shellRoot.gray
              }
              
              Text {
                anchors.centerIn: parent
                text: parent.isValidDay ? parent.dayNumber : ""
                font.family: shellRoot.fontFamily
                font.pixelSize: 20
                color: {
                  if (parent.isValidDay && parent.isCurrentDay) return shellRoot.white
                  if (!parent.isValidDay) return shellRoot.white
                  return shellRoot.white
                }
                font.weight: parent.isValidDay && parent.isCurrentDay ? Font.DemiBold : Font.Normal
              }
            }
          }
        }
      }
    }
  }
}