Refactor calendar component
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
import Quickshell.Io
|
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Common.Styled
|
import qs.Common.Styled
|
||||||
@@ -19,8 +18,6 @@ Item {
|
|||||||
implicitWidth: clockText.implicitWidth * 1.6
|
implicitWidth: clockText.implicitWidth * 1.6
|
||||||
implicitHeight: Theme.heightGaps
|
implicitHeight: Theme.heightGaps
|
||||||
|
|
||||||
property string calendar: ""
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: clockText
|
id: clockText
|
||||||
|
|
||||||
@@ -28,22 +25,10 @@ Item {
|
|||||||
text: Time.time
|
text: Time.time
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
|
||||||
id: cal
|
|
||||||
running: true
|
|
||||||
command: ["cal", "-S3"]
|
|
||||||
stdout: StdioCollector {
|
|
||||||
onStreamFinished: {
|
|
||||||
clock.calendar = this.text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onEntered: {
|
onEntered: {
|
||||||
cal.running = true;
|
|
||||||
PopUpHover.start(clock, "time");
|
PopUpHover.start(clock, "time");
|
||||||
}
|
}
|
||||||
onExited: {
|
onExited: {
|
||||||
|
|||||||
102
Common/CalendarComponent.qml
Normal file
102
Common/CalendarComponent.qml
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
// CalendarComponent.qml (For one month)
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import qs.Common
|
||||||
|
import qs.Common.Styled
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
property int targetYear: new Date().getFullYear()
|
||||||
|
property int targetMonth: new Date().getMonth() // 0-11
|
||||||
|
property date currentDate: new Date()
|
||||||
|
|
||||||
|
function getLocalizedDayHeaders() {
|
||||||
|
const locale = Qt.locale();
|
||||||
|
const headers = [];
|
||||||
|
|
||||||
|
const firstDay = locale.firstDayOfWeek;
|
||||||
|
|
||||||
|
for (let i = 0; i < 7; i++) {
|
||||||
|
const dayIndex = (firstDay + i) % 7;
|
||||||
|
|
||||||
|
const dayDate = new Date(1970, 0, 4 + dayIndex);
|
||||||
|
headers.push(dayDate.toLocaleString(locale, "ddd").substring(0, 1));
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
function getMonthLayout(year, month) {
|
||||||
|
let date = new Date(year, month, 1);
|
||||||
|
let firstDayOfWeek = date.getDay();
|
||||||
|
|
||||||
|
let daysInMonth = new Date(year, month + 1, 0).getDate();
|
||||||
|
let days = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < firstDayOfWeek; i++) {
|
||||||
|
days.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 1; i <= daysInMonth; i++) {
|
||||||
|
days.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (days.length % 7 !== 0) {
|
||||||
|
days.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
monthName: date.toLocaleString(Qt.locale(), "MMMM yyyy"),
|
||||||
|
days: days
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var layoutData: getMonthLayout(targetYear, targetMonth)
|
||||||
|
|
||||||
|
implicitWidth: childrenRect.width
|
||||||
|
implicitHeight: childrenRect.height
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 5
|
||||||
|
|
||||||
|
// Month Title
|
||||||
|
StyledText {
|
||||||
|
text: root.layoutData.monthName
|
||||||
|
font.bold: true
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
width: parent.width
|
||||||
|
font.family: Theme.fontFamilyMono
|
||||||
|
}
|
||||||
|
|
||||||
|
Grid {
|
||||||
|
columns: 7
|
||||||
|
rowSpacing: 2
|
||||||
|
columnSpacing: 5
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.getLocalizedDayHeaders()
|
||||||
|
StyledText {
|
||||||
|
text: modelData
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
width: 18
|
||||||
|
font.family: Theme.fontFamilyMono
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.layoutData.days
|
||||||
|
StyledText {
|
||||||
|
text: modelData
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
width: 18
|
||||||
|
font.family: Theme.fontFamilyMono
|
||||||
|
|
||||||
|
color: {
|
||||||
|
let isCurrentMonth = root.targetYear === root.currentDate.getFullYear() && root.targetMonth === root.currentDate.getMonth();
|
||||||
|
let isCurrentDay = isCurrentMonth && modelData === root.currentDate.getDate();
|
||||||
|
|
||||||
|
return isCurrentDay ? Theme.color6Bright : Theme.textColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -75,13 +75,42 @@ Singleton {
|
|||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: time
|
id: time
|
||||||
StyledText {
|
|
||||||
property string calendar: (HoverMediator.component.calendar) ? HoverMediator.component.calendar : ""
|
|
||||||
|
|
||||||
text: calendar
|
RowLayout{
|
||||||
|
id: rowlayoutCalendar
|
||||||
|
|
||||||
textFormat: Text.AutoText
|
readonly property date now: new Date()
|
||||||
font.family: Theme.fontFamilyMono
|
readonly property int prevMonth: now.getMonth() - 1
|
||||||
|
readonly property int currentMonth: now.getMonth()
|
||||||
|
readonly property int nextMonth: now.getMonth() + 1
|
||||||
|
|
||||||
|
implicitWidth: childrenRect.width
|
||||||
|
implicitHeight: childrenRect.height
|
||||||
|
spacing: 20
|
||||||
|
|
||||||
|
CalendarComponent {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
targetYear: parent.prevMonth < 0 ? parent.now.getFullYear() - 1 : parent.now.getFullYear()
|
||||||
|
targetMonth: parent.prevMonth < 0 ? 11 : parent.prevMonth
|
||||||
|
currentDate: parent.now
|
||||||
|
}
|
||||||
|
|
||||||
|
CalendarComponent {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
targetYear: parent.now.getFullYear()
|
||||||
|
targetMonth: parent.currentMonth
|
||||||
|
currentDate: parent.now
|
||||||
|
}
|
||||||
|
|
||||||
|
CalendarComponent {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
targetYear: parent.nextMonth > 11 ? parent.now.getFullYear() + 1 : parent.now.getFullYear()
|
||||||
|
targetMonth: parent.nextMonth > 11 ? 0 : parent.nextMonth
|
||||||
|
currentDate: parent.now
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,9 +156,11 @@ Singleton {
|
|||||||
topMargin: Theme.gaps
|
topMargin: Theme.gaps
|
||||||
bottomMargin: Theme.gaps
|
bottomMargin: Theme.gaps
|
||||||
}
|
}
|
||||||
|
|
||||||
color: Theme.backgroudColor
|
color: Theme.backgroudColor
|
||||||
radius: 25
|
radius: 25
|
||||||
opacity: 1
|
opacity: 1
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
property: "opacity"
|
property: "opacity"
|
||||||
@@ -154,6 +185,5 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user