2024-10-28 13:02:57 -06:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"image/color"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"fyne.io/fyne/v2"
|
|
|
|
"fyne.io/fyne/v2/app"
|
|
|
|
"fyne.io/fyne/v2/canvas"
|
|
|
|
"fyne.io/fyne/v2/container"
|
|
|
|
"fyne.io/fyne/v2/driver/desktop"
|
|
|
|
"fyne.io/fyne/v2/widget"
|
|
|
|
"fyne.io/systray"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
ffffea = color.RGBA{R: 255, G: 255, B: 234, A: 255}
|
|
|
|
sixes = color.RGBA{R: 204, G: 204, B: 204, A: 255}
|
|
|
|
blue = color.RGBA{R: 74, G: 144, B: 226, A: 255}
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
debug := flag.Bool("d", false, "enable debugging (work / break time become 10 seconds)")
|
|
|
|
makeIcon := flag.Bool("i", false, "draw an icon and exit.")
|
|
|
|
flag.Parse()
|
|
|
|
enabled := true
|
|
|
|
rounds := 0
|
|
|
|
workTime := 25 * 60
|
|
|
|
breakTime := 5 * 60
|
|
|
|
|
|
|
|
if *debug {
|
|
|
|
workTime = 10
|
|
|
|
breakTime = 10
|
|
|
|
}
|
|
|
|
|
|
|
|
icon := CountIcon{
|
|
|
|
Enabled: enabled,
|
|
|
|
}
|
|
|
|
|
|
|
|
var desk desktop.App
|
2024-10-30 07:24:25 -06:00
|
|
|
|
|
|
|
disable := func() {
|
|
|
|
enabled = false
|
|
|
|
icon.Enabled = enabled
|
|
|
|
desk.SetSystemTrayIcon(icon.Draw(0.0))
|
|
|
|
systray.SetTooltip("Disabled")
|
|
|
|
}
|
|
|
|
|
|
|
|
enable := func() {
|
|
|
|
enabled = true
|
|
|
|
icon.Enabled = enabled
|
|
|
|
}
|
|
|
|
|
2024-10-28 13:02:57 -06:00
|
|
|
if !*makeIcon {
|
|
|
|
a := app.New()
|
|
|
|
driver := fyne.CurrentApp().Driver().(desktop.Driver)
|
|
|
|
w := driver.CreateSplashWindow()
|
|
|
|
|
|
|
|
if castDesk, ok := a.(desktop.App); ok {
|
|
|
|
desk = castDesk
|
|
|
|
desk.SetSystemTrayIcon(icon.Draw(1.0))
|
|
|
|
desk.SetSystemTrayMenu(
|
|
|
|
fyne.NewMenu("fynado",
|
|
|
|
fyne.NewMenuItem("Enable", func() {
|
2024-10-30 07:24:25 -06:00
|
|
|
enable()
|
2024-10-28 13:02:57 -06:00
|
|
|
}),
|
|
|
|
fyne.NewMenuItem("Disable", func() {
|
2024-10-30 07:24:25 -06:00
|
|
|
disable()
|
2024-10-28 13:02:57 -06:00
|
|
|
}),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
log.Fatalln("can't initialize deskto.App")
|
|
|
|
}
|
|
|
|
|
|
|
|
a.Lifecycle().SetOnExitedForeground(func() {
|
|
|
|
time.Sleep(time.Second * 3)
|
|
|
|
w.RequestFocus()
|
|
|
|
})
|
|
|
|
|
|
|
|
rect := canvas.NewRectangle(color.Black)
|
|
|
|
infoRect := canvas.NewRectangle(ffffea)
|
|
|
|
|
|
|
|
reminderText := canvas.NewText("Time for a break!", color.Black)
|
|
|
|
reminderText.TextSize = 80
|
|
|
|
reminderText.TextStyle = fyne.TextStyle{Bold: true}
|
|
|
|
reminderText.Alignment = fyne.TextAlignCenter
|
|
|
|
|
2024-10-29 07:39:53 -06:00
|
|
|
timerText := canvas.NewText("", blue)
|
2024-10-28 13:02:57 -06:00
|
|
|
timerText.TextSize = 50
|
|
|
|
timerText.TextStyle = fyne.TextStyle{Bold: true}
|
|
|
|
timerText.Alignment = fyne.TextAlignCenter
|
|
|
|
|
|
|
|
roundsText := canvas.NewText("", color.Black)
|
|
|
|
roundsText.TextSize = 50
|
|
|
|
roundsText.Alignment = fyne.TextAlignCenter
|
|
|
|
|
|
|
|
w.Resize(fyne.NewSize(1000, 600))
|
|
|
|
w.SetContent(
|
|
|
|
container.NewStack(
|
|
|
|
rect,
|
|
|
|
container.NewPadded(infoRect,
|
|
|
|
container.NewGridWithRows(4,
|
|
|
|
container.NewBorder(nil, reminderText, nil, nil),
|
|
|
|
container.NewBorder(timerText, nil, nil, nil),
|
|
|
|
container.NewBorder(roundsText, nil, nil, nil),
|
|
|
|
container.NewBorder(nil, widget.NewButton("Extended Break", func() {
|
|
|
|
rounds = 0
|
|
|
|
w.Hide()
|
2024-10-30 07:24:25 -06:00
|
|
|
disable()
|
2024-10-28 13:02:57 -06:00
|
|
|
}), nil, nil),
|
|
|
|
)),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
duration := workTime
|
|
|
|
w.Hide()
|
|
|
|
|
|
|
|
log.Println("work time starting")
|
|
|
|
|
|
|
|
for {
|
|
|
|
if !enabled {
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
duration--
|
|
|
|
timerText.Text = fmt.Sprintf("%02d:%02d", duration/60, duration&60)
|
|
|
|
timerText.Refresh()
|
|
|
|
|
|
|
|
w.Content().Refresh()
|
|
|
|
systray.SetTooltip(timerText.Text)
|
|
|
|
|
|
|
|
remainingPct := float64((workTime - duration)) / float64(workTime) * 1
|
|
|
|
|
|
|
|
desk.SetSystemTrayIcon(icon.Draw(remainingPct))
|
|
|
|
|
|
|
|
if duration == 0 {
|
|
|
|
rounds++
|
|
|
|
|
|
|
|
if rounds > 3 {
|
2024-10-29 07:39:53 -06:00
|
|
|
roundsText.Text = fmt.Sprintf("%d rounds! Take an extended break!", rounds)
|
2024-10-28 13:02:57 -06:00
|
|
|
} else {
|
|
|
|
roundsText.Text = fmt.Sprintf("Rounds: %d", rounds)
|
|
|
|
}
|
|
|
|
roundsText.Refresh()
|
|
|
|
|
|
|
|
log.Printf("break %d starting", rounds)
|
|
|
|
showBreak(breakTime, w, timerText)
|
|
|
|
duration = workTime
|
|
|
|
}
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
a.Run()
|
|
|
|
} else {
|
|
|
|
data := icon.Draw(.73).Content()
|
|
|
|
os.WriteFile("icon.png", data, 0644)
|
|
|
|
os.Exit(0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func showBreak(breakTime int, w fyne.Window, t *canvas.Text) {
|
|
|
|
|
|
|
|
w.Show()
|
|
|
|
duration := breakTime
|
|
|
|
for {
|
|
|
|
t.Text = fmt.Sprintf("%02d:%02d", duration/60, duration%60)
|
|
|
|
t.Refresh()
|
|
|
|
|
|
|
|
systray.SetTooltip(t.Text)
|
|
|
|
|
|
|
|
if duration == 0 {
|
|
|
|
w.Hide()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
duration--
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
}
|
|
|
|
}
|