Add Calendar widget to display the monthly calendar and integrate it into the layout

This commit is contained in:
Arindy 2025-12-28 21:09:01 +01:00
parent ec85f87377
commit a0be24b074
2 changed files with 159 additions and 10 deletions

24
main.go
View File

@ -34,6 +34,7 @@ func initWidgets(ctx context.Context, term *tcell.Terminal) {
widgets.Create(ctx, term,
widgets.New("Clock", widgets.Clock()),
widgets.New("Date", widgets.Date()),
widgets.New("Calendar", widgets.Calendar()),
widgets.New("ChangeTitle", widgets.TextInput(titleUpdate, textinput.Label("Update Title: "), textinput.PlaceHolder("New Title"))),
widgets.New("Wifi", widgets.WifiQRCode()),
widgets.New("NetworkDevices", widgets.NetworkDevices()),
@ -73,15 +74,7 @@ func layout() []container.Option {
container.BorderColor(cell.ColorWhite),
),
),
grid.RowHeightFixed(3,
grid.Widget(widgets.Get["Date"],
container.AlignHorizontal(align.HorizontalCenter),
container.BorderTitle("Date"),
container.Border(linestyle.Light),
container.BorderColor(cell.ColorWhite),
),
),
grid.RowHeightFixed(8,
grid.RowHeightFixed(11,
grid.Widget(widgets.Get["PiHole"],
container.BorderTitle("pi-hole"),
container.Border(linestyle.Light),
@ -99,7 +92,18 @@ func layout() []container.Option {
grid.Widget(widgets.Get["empty"]),
),
),
grid.ColWidthPerc(35,
grid.ColWidthPerc(10,
grid.RowHeightFixed(19,
grid.Widget(widgets.Get["Calendar"],
container.BorderTitle("Calendar"),
container.Border(linestyle.Light),
container.BorderColor(cell.ColorWhite)),
),
grid.RowHeightPerc(25,
grid.Widget(widgets.Get["empty"]),
),
),
grid.ColWidthPerc(25,
grid.RowHeightPerc(25,
grid.Widget(widgets.Get["empty"]),
),

145
widgets/calendar.go Normal file
View File

@ -0,0 +1,145 @@
package widgets
import (
"ArinDash/util"
"context"
"fmt"
"time"
"github.com/mum4k/termdash/cell"
"github.com/mum4k/termdash/terminal/terminalapi"
"github.com/mum4k/termdash/widgetapi"
"github.com/mum4k/termdash/widgets/text"
)
type CalendarOptions struct {
}
func Calendar() CalendarOptions {
widgetOptions["CalendarOptions"] = createCalendar
return CalendarOptions{}
}
func createCalendar(ctx context.Context, _ terminalapi.Terminal, _ interface{}) widgetapi.Widget {
widget := util.PanicOnErrorWithResult(text.New())
go util.Periodic(ctx, 1*time.Hour, func() error {
widget.Reset()
if err := widget.Write("┌────────────────────┐\n", text.WriteCellOpts(cell.FgColor(cell.ColorWhite))); err != nil {
return err
}
if err := widget.Write(fmt.Sprintf("|%-20s|\n", time.Now().Format("January 2006")), text.WriteCellOpts(cell.FgColor(cell.ColorWhite))); err != nil {
return err
}
if err := widget.Write("├────────────────────┤\n", text.WriteCellOpts(cell.FgColor(cell.ColorWhite))); err != nil {
return err
}
if err := createRow(widget, "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"); err != nil {
return err
}
if err := createTableForMonth(widget); err != nil {
return err
}
if err := createLowerBorder(widget); err != nil {
return err
}
return nil
})
return widget
}
func createTableForMonth(widget *text.Text) error {
table := make([]int, 0)
now := time.Now()
firstMonthday := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.UTC)
for range (firstMonthday.Weekday() + 6) % 7 {
table = append(table, 0)
}
for {
day := firstMonthday.Day()
table = append(table, day)
firstMonthday = firstMonthday.AddDate(0, 0, 1)
if firstMonthday.Month() != now.Month() {
break
}
}
remainingDays := 8 - len(table)/7
for range remainingDays {
table = append(table, 0)
}
for index, field := range table {
if index%7 == 0 {
if err := createMiddle(widget); err != nil {
return err
}
}
var str string
if err := widget.Write("|"); err != nil {
return err
}
if field == 0 {
str = fmt.Sprintf(" ")
} else {
str = fmt.Sprintf("%2d", field)
}
var color text.WriteOption
if field == now.Day() {
color = text.WriteCellOpts(cell.FgColor(cell.ColorBlack), cell.BgColor(cell.ColorWhite), cell.Bold())
} else {
color = text.WriteCellOpts(cell.FgColor(cell.ColorWhite), cell.BgColor(cell.ColorDefault))
}
if err := widget.Write(str, color); err != nil {
return err
}
if index%7 == 6 {
if err := widget.Write("|\n"); err != nil {
return err
}
}
}
return nil
}
func createLowerBorder(widget *text.Text) error {
result := "└─"
for range 6 {
result += "─┴─"
}
result += "─┘\n"
if err := widget.Write(result, text.WriteCellOpts(cell.FgColor(cell.ColorWhite))); err != nil {
return err
}
return nil
}
func createMiddle(widget *text.Text) error {
result := "├─"
for range 6 {
result += "─┼─"
}
result += "─┤\n"
if err := widget.Write(result, text.WriteCellOpts(cell.FgColor(cell.ColorWhite))); err != nil {
return err
}
return nil
}
func createRow(widget *text.Text, cells ...string) error {
result := "|"
for index, field := range cells {
result += fmt.Sprintf("%2s", field)
if index < len(cells)-1 {
result += "|"
} else {
result += "|\n"
}
}
if err := widget.Write(result, text.WriteCellOpts(cell.FgColor(cell.ColorWhite))); err != nil {
return err
}
return nil
}