Files
matocock/main.go

181 lines
4.6 KiB
Go
Raw Normal View History

2025-08-30 12:15:55 +01:00
// See the LICENSE file to see your liberties and restrictions.
package main
import (
2025-09-30 06:31:16 +01:00
"fmt"
2025-08-30 16:28:42 +01:00
"time"
2025-09-30 10:28:11 +01:00
_ "embed"
2025-08-30 16:28:42 +01:00
2025-08-30 12:15:55 +01:00
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
)
2025-09-30 10:28:11 +01:00
//go:embed res/matocock.svg
var iconBytes []byte
var TomatoIcon *fyne.StaticResource = fyne.NewStaticResource("TomatoIcon", iconBytes)
2025-08-30 12:15:55 +01:00
func main() {
var timer time.Duration
var ticking bool = false
2025-08-30 16:28:42 +01:00
var status string = "WORK TIME"
2025-09-30 06:31:16 +01:00
var laps int = 0
2025-08-30 16:28:42 +01:00
// TODO: GET DEFAULT WORK AND BREAK TIMES FROM FILESYSTEM
var defaultWorkTime string = "25m"
var defaultBreakTime string = "5m"
2025-08-30 12:15:55 +01:00
a := app.New()
2025-09-30 10:28:11 +01:00
a.SetIcon(TomatoIcon)
2025-08-30 16:28:42 +01:00
w := a.NewWindow(status)
2025-08-30 12:15:55 +01:00
w.SetFixedSize(true)
w.Resize(fyne.NewSize(400, 50))
workEntry := widget.NewEntry()
2025-08-30 16:28:42 +01:00
workEntry.SetText(defaultWorkTime)
2025-08-30 12:15:55 +01:00
workEntry.TextStyle.Monospace = true
workEntry.Refresh()
breakEntry := widget.NewEntry()
2025-08-30 16:28:42 +01:00
breakEntry.SetText(defaultBreakTime)
2025-08-30 12:15:55 +01:00
breakEntry.TextStyle.Monospace = true
breakEntry.Refresh()
2025-09-30 06:31:16 +01:00
lapsLabel := widget.NewLabel("0 laps")
lapsLabel.TextStyle.Bold = true
lapsLabel.Alignment = fyne.TextAlignCenter
2025-08-30 12:15:55 +01:00
var beginButton *widget.Button
beginButton = widget.NewButtonWithIcon("Start", theme.Icon(theme.IconNameMediaPlay), func() {
go func() {
if !ticking {
ticking = true
2025-08-30 16:28:42 +01:00
var duration time.Duration
var err error
if status == "WORK TIME" {
duration, err = time.ParseDuration(workEntry.Text)
} else {
duration, err = time.ParseDuration(breakEntry.Text)
}
2025-08-30 12:15:55 +01:00
if err != nil {
neww := fyne.CurrentApp().NewWindow("Error")
neww.Resize(fyne.NewSize(500, 500))
fyne.Do(func() {
neww.Show()
})
err_dialog := dialog.NewError(err, neww)
err_dialog.SetOnClosed(func() {
neww.Close()
})
err_dialog.Show()
ticking = false
return
}
beginButton.Icon = theme.Icon(theme.IconNameMediaPause)
fyne.Do(func() {
beginButton.SetText("Stop")
})
beginButton.Importance = widget.LowImportance
fyne.Do(func() {
beginButton.Refresh()
})
timer = duration
timeStarted := time.Now()
for ticking {
cur := time.Since(timeStarted)
2025-08-30 16:28:42 +01:00
if status == "WORK TIME" {
2025-09-30 06:31:16 +01:00
fyne.Do(func() {
workEntry.Disable()
workEntry.SetText((cur.Round(time.Second) - timer.Round(time.Second)).Abs().String())
})
2025-08-30 16:28:42 +01:00
} else {
2025-09-30 06:31:16 +01:00
fyne.Do(func() {
breakEntry.Disable()
breakEntry.SetText((cur.Round(time.Second) - timer.Round(time.Second)).Abs().String())
})
2025-08-30 16:28:42 +01:00
}
2025-08-30 12:15:55 +01:00
if cur >= timer {
2025-08-30 16:28:42 +01:00
if status == "WORK TIME" {
status = "BREAK TIME"
workEntry.SetText(defaultWorkTime)
workEntry.Enable()
timer, err = time.ParseDuration(breakEntry.Text)
if err != nil {
panic(err)
}
timer = timer + cur
w.SetTitle(status)
} else {
status = "WORK TIME"
breakEntry.SetText(defaultBreakTime)
breakEntry.Enable()
timer, err = time.ParseDuration(workEntry.Text)
if err != nil {
panic(err)
}
timer = timer + cur
w.SetTitle(status)
2025-09-30 06:31:16 +01:00
laps++
lapsLabel.SetText(fmt.Sprintf("%d laps", laps))
2025-08-30 16:28:42 +01:00
}
2025-08-30 12:15:55 +01:00
} else {
time.Sleep(time.Second * 1)
}
}
} else {
ticking = false
workEntry.Enable()
2025-08-30 16:28:42 +01:00
breakEntry.Enable()
2025-08-30 12:15:55 +01:00
beginButton.Icon = theme.Icon(theme.IconNameMediaPlay)
fyne.Do(func() {
beginButton.SetText("Start")
})
beginButton.Importance = widget.HighImportance
fyne.Do(func() {
beginButton.Refresh()
})
}
}()
})
beginButton.Importance = widget.HighImportance
2025-09-30 06:31:16 +01:00
w.SetContent(container.NewVBox(container.NewGridWithColumns(3, workEntry, breakEntry, container.NewVBox(beginButton, widget.NewButtonWithIcon("Skip", theme.Icon(theme.IconNameMediaSkipNext), func() {
if !ticking {
if status == "WORK TIME" {
status = "BREAK TIME"
} else {
status = "WORK TIME"
laps++
lapsLabel.SetText(fmt.Sprintf("%d laps", laps))
lapsLabel.Refresh()
}
w.SetTitle(status)
2025-08-30 16:28:42 +01:00
}
2025-09-30 06:31:16 +01:00
}))), lapsLabel))
2025-09-30 10:28:11 +01:00
menu := fyne.NewMainMenu(fyne.NewMenu("🍅"), fyne.NewMenu("help", fyne.NewMenuItem("valid time arguments", func() {
2025-08-30 12:15:55 +01:00
neww := fyne.CurrentApp().NewWindow("Help")
neww.Resize(fyne.NewSize(500, 500))
fyne.Do(func() {
neww.Show()
})
help_dialog := dialog.NewInformation("Help", "Here are some valid time arguments:\n3ns (3 nanoseconds)\n3s (3 seconds)\n2m (2 minutes)\n2m3s (2 minutes and 3 seconds)\n2h1m1s (2 hours 1 minute and 1 second)", neww)
help_dialog.SetOnClosed(func() {
neww.Close()
})
help_dialog.Show()
})))
w.SetMainMenu(menu)
w.ShowAndRun()
}