diff --git a/go.mod b/go.mod index 7ba0c9f..28a4dd2 100644 --- a/go.mod +++ b/go.mod @@ -6,13 +6,14 @@ require ( github.com/0xAX/notificator v0.0.0-20181105090803-d81462e38c21 github.com/fatih/color v1.7.0 github.com/gizak/termui v2.3.0+incompatible + github.com/gizak/termui/v3 v3.1.0 // indirect github.com/jawher/mow.cli v1.0.4 github.com/maruel/panicparse v0.0.0-20180806203336-f20d4c4d746f github.com/mattn/go-colorable v0.0.9 github.com/mattn/go-isatty v0.0.4 - github.com/mattn/go-runewidth v0.0.4 + github.com/mattn/go-runewidth v0.0.13 github.com/mattn/go-sqlite3 v1.10.0 - github.com/mitchellh/go-wordwrap v1.0.0 - github.com/nsf/termbox-go v0.0.0-20190104133558-0938b5187e61 + github.com/mitchellh/go-wordwrap v1.0.1 + github.com/nsf/termbox-go v1.1.1 golang.org/x/sys v0.0.0-20190116161447-11f53e031339 ) diff --git a/go.sum b/go.sum index 6f8595e..398888d 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/gizak/termui v2.3.0+incompatible h1:S8wJoNumYfc/rR5UezUM4HsPEo3RJh0LKdiuDWQpjqw= github.com/gizak/termui v2.3.0+incompatible/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA= +github.com/gizak/termui/v3 v3.1.0 h1:ZZmVDgwHl7gR7elfKf1xc4IudXZ5qqfDh4wExk4Iajc= +github.com/gizak/termui/v3 v3.1.0/go.mod h1:bXQEBkJpzxUAKf0+xq9MSWAvWZlE7c+aidmyFlkYTrY= github.com/jawher/mow.cli v1.0.4 h1:hKjm95J7foZ2ngT8tGb15Aq9rj751R7IUDjG+5e3cGA= github.com/jawher/mow.cli v1.0.4/go.mod h1:5hQj2V8g+qYmLUVWqu4Wuja1pI57M83EChYLVZ0sMKk= github.com/maruel/panicparse v0.0.0-20180806203336-f20d4c4d746f h1:qiwX3rjQBtp68F8LsKgURRQiFCWiNdN8EB9b+EMLv1k= @@ -12,12 +14,24 @@ github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRU github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/nsf/termbox-go v0.0.0-20190104133558-0938b5187e61 h1:pEzZYac/uQ4cgaN1Q/UYZg+ZtCSWz2HQ3rvl8MeN9MA= github.com/nsf/termbox-go v0.0.0-20190104133558-0938b5187e61/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= +github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= +github.com/nsf/termbox-go v1.1.1 h1:nksUPLCb73Q++DwbYUBEglYBRPZyoXJdrj5L+TkjyZY= +github.com/nsf/termbox-go v1.1.1/go.mod h1:T0cTdVuOwf7pHQNtfhnEbzHbcNyCEcVU4YPpouCbVxo= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= golang.org/x/sys v0.0.0-20190116161447-11f53e031339/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/pkg/internal/ui.go b/pkg/internal/ui.go index 4aa5f99..b5f9475 100644 --- a/pkg/internal/ui.go +++ b/pkg/internal/ui.go @@ -2,15 +2,16 @@ package pomo import ( "fmt" + "time" - "github.com/gizak/termui" + ui "github.com/gizak/termui/v3" + "github.com/gizak/termui/v3/widgets" ) -func render(wheel *Wheel, status *Status) termui.GridBufferer { - var text string +func setContent(wheel *Wheel, status *Status, par *widgets.Paragraph) { switch status.State { case RUNNING: - text = fmt.Sprintf( + par.Text = fmt.Sprintf( `[%d/%d] Pomodoros completed %s %s remaining @@ -24,15 +25,15 @@ func render(wheel *Wheel, status *Status) termui.GridBufferer { status.Remaining, ) case BREAKING: - text = `It is time to take a break! + par.Text = `It is time to take a break! - Once you are ready, press [enter] + Once you are ready, press [enter] to begin the next Pomodoro. [q] - quit [p] - pause ` case PAUSED: - text = `Pomo is suspended. + par.Text = `Pomo is suspended. Press [p] to continue. @@ -40,84 +41,77 @@ func render(wheel *Wheel, status *Status) termui.GridBufferer { [q] - quit [p] - unpause ` case COMPLETE: - text = `This session has concluded. - + par.Text = `This session has concluded. + Press [q] to exit. [q] - quit ` } - par := termui.NewPar(text) - par.Height = 8 - par.BorderLabel = fmt.Sprintf("Pomo - %s", status.State) - par.BorderLabelFg = termui.ColorWhite - par.BorderFg = termui.ColorRed + par.Title = fmt.Sprintf("Pomo - %s", status.State) + par.TitleStyle.Fg = ui.ColorWhite + par.BorderStyle.Fg = ui.ColorRed if status.State == RUNNING { - par.BorderFg = termui.ColorGreen + par.BorderStyle.Fg = ui.ColorGreen } - return par -} - -func newBlk() termui.GridBufferer { - blk := termui.NewBlock() - blk.Height = termui.TermHeight() / 3 - blk.Border = false - return blk -} - -func centered(part termui.GridBufferer) *termui.Grid { - grid := termui.NewGrid( - termui.NewRow( - termui.NewCol(12, 0, newBlk()), - ), - termui.NewRow( - termui.NewCol(3, 0, newBlk()), - termui.NewCol(6, 0, part), - termui.NewCol(3, 0, newBlk()), - ), - termui.NewRow( - termui.NewCol(12, 0, newBlk()), - ), - ) - grid.BgColor = termui.ThemeAttr("bg") - grid.Width = termui.TermWidth() - grid.Align() - return grid } func StartUI(runner *TaskRunner) { - err := termui.Init() + err := ui.Init() if err != nil { panic(err) } + + ticker := time.NewTicker(250 * time.Millisecond) + + defer ui.Close() + wheel := Wheel(0) - defer termui.Close() + par := widgets.NewParagraph() - termui.Render(centered(render(&wheel, runner.Status()))) + resize := func() { + termWidth, termHeight := ui.TerminalDimensions() - termui.Handle("/timer/1s", func(termui.Event) { - termui.Render(centered(render(&wheel, runner.Status()))) - }) + x1 := (termWidth - 50) / 2 + x2 := x1 + 50 + y1 := (termHeight - 8) / 2 + y2 := y1 + 8 - termui.Handle("/sys/wnd/resize", func(termui.Event) { - termui.Render(centered(render(&wheel, runner.Status()))) - }) + par.SetRect(x1, y1, x2, y2) + ui.Clear() + } - termui.Handle("/sys/kbd/", func(termui.Event) { - runner.Toggle() - termui.Render(centered(render(&wheel, runner.Status()))) - }) + render := func() { + setContent(&wheel, runner.Status(), par) + ui.Render(par) + } - termui.Handle("/sys/kbd/p", func(termui.Event) { - runner.Pause() - termui.Render(centered(render(&wheel, runner.Status()))) - }) + resize() + render() - termui.Handle("/sys/kbd/q", func(termui.Event) { - termui.StopLoop() - }) + events := ui.PollEvents() + + for { + select { + case e := <-events: + switch e.ID { + case "q", "": + return + case "": + resize() + render() + case "": + runner.Toggle() + render() + case "p": + runner.Pause() + render() + } + case <-ticker.C: + render() + } + } - termui.Loop() }