From 4f42c502ed396fff9497b1f23138d2acc994b4d8 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Fri, 17 Jan 2020 15:37:04 -0500 Subject: [PATCH] Fullscreen mode via altscreen + fullscreen example --- examples/fullscreen/main.go | 59 +++++++++++++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 13 ++------ tea.go | 21 +++++++++---- 4 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 examples/fullscreen/main.go diff --git a/examples/fullscreen/main.go b/examples/fullscreen/main.go new file mode 100644 index 0000000..df04efa --- /dev/null +++ b/examples/fullscreen/main.go @@ -0,0 +1,59 @@ +package main + +// A simple program that counts down from 5 and then exits. + +import ( + "fmt" + "log" + "tea" + "time" +) + +type model int + +type tickMsg struct{} + +func main() { + tea.Fullscreen() + defer tea.ExitFullscreen() + err := tea.NewProgram(model(5), update, view, []tea.Sub{tick}).Start() + if err != nil { + log.Fatal(err) + } +} + +func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) { + m, _ := mdl.(model) + + switch message := msg.(type) { + + case tea.KeyPressMsg: + switch message { + case "ctrl+c": + fallthrough + case "esc": + fallthrough + case "q": + return m, tea.Quit + } + + case tickMsg: + m -= 1 + if m <= 0 { + return m, tea.Quit + } + + } + + return m, nil +} + +func view(mdl tea.Model) string { + m, _ := mdl.(model) + return fmt.Sprintf("\n\n Hi. This program will exit in %d seconds...", m) +} + +func tick(_ tea.Model) tea.Msg { + time.Sleep(time.Second) + return tickMsg{} +} diff --git a/go.mod b/go.mod index 10ab6e6..de543ea 100644 --- a/go.mod +++ b/go.mod @@ -5,5 +5,5 @@ go 1.13 require ( github.com/fogleman/ease v0.0.0-20170301025033-8da417bf1776 github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 - github.com/tj/go-terminput v1.0.0 + golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 // indirect ) diff --git a/go.sum b/go.sum index 8d87886..347edff 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,6 @@ github.com/fogleman/ease v0.0.0-20170301025033-8da417bf1776 h1:VRIbnDWRmAh5yBdz+J6yFMF5vso1It6vn+WmM/5l7MA= github.com/fogleman/ease v0.0.0-20170301025033-8da417bf1776/go.mod h1:9wvnDu3YOfxzWM9Cst40msBF1C2UdQgDv962oTxSuMs= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 h1:A7GG7zcGjl3jqAqGPmcNjd/D9hzL95SuoOQAaFNdLU0= github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/tj/go-terminput v1.0.0 h1:X928u7ohxr7Dfzlxppvc5Zql5Lwd1bOH5VyIL2RPrFw= -github.com/tj/go-terminput v1.0.0/go.mod h1:8zzAs+cqdjZlTxE9DbGyjKDfGNxaJjC5bvg4vkWX2V0= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10= +golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/tea.go b/tea.go index 5e6abd3..5af309b 100644 --- a/tea.go +++ b/tea.go @@ -87,10 +87,9 @@ func (p *Program) Start() error { hideCursor() p.render(model) - // Subscribe to user input - // TODO: should we move this to the end-user program level or just keep this - // here, since it blocks nicely and user input will probably be something - // users typically need? + // Subscribe to user input. We could move this out of here and offer it + // as a subscription, but it blocks nicely and seems to be a common enough + // need that we're enabling it by default. go func() { for { msg, _ := ReadKey(p.rw) @@ -195,7 +194,19 @@ func clearLines(n int) { } } -// ClearScreen clears the visible portion of the terminal +// Fullscreen switches to the altscreen and clears the terminal. The former +// view can be restored with ExitFullscreen(). +func Fullscreen() { + fmt.Print(esc + "?1049h" + esc + "H") +} + +// ExitFullscreen exits the altscreen and returns the former terminal view +func ExitFullscreen() { + fmt.Print(esc + "?1049l") +} + +// ClearScreen clears the visible portion of the terminal. Effectively, it +// fills the terminal with blank spaces. func ClearScreen() { fmt.Printf(esc + "2J" + esc + "3J" + esc + "1;1H") }