summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--football/main.go62
-rw-r--r--tui/draw.go24
-rw-r--r--tui/event.go96
3 files changed, 87 insertions, 95 deletions
diff --git a/football/main.go b/football/main.go
index f6332c1..a8d0126 100644
--- a/football/main.go
+++ b/football/main.go
@@ -116,38 +116,38 @@ func main() {
tui.Clear()
drawFootball(balls[:])
- tui.Write(1, 9, " DIALOG:", tui.Style {Fg: tui.Red, Bold: true})
- tui.Write(1, 10, " ", tui.DefaultStyle)
- w := tui.Write(2, 10, sb.String(), tui.DefaultStyle)
+ tui.WriteAt(1, 9, " DIALOG:", tui.Style {Fg: tui.Red, Bold: true})
+ tui.WriteAt(1, 10, " ", tui.DefaultStyle)
+ w := tui.WriteAt(2, 10, sb.String(), tui.DefaultStyle)
tui.MoveCursor(2 + w, 10)
- tui.Write(1, 11, " RESPONSE:", tui.Style {Fg: tui.Green, Bold: true})
- tui.Write(1, 12, " ", tui.DefaultStyle)
- tui.Write(2, 12, response, tui.DefaultStyle)
+ tui.WriteAt(1, 11, " RESPONSE:", tui.Style {Fg: tui.Green, Bold: true})
+ tui.WriteAt(1, 12, " ", tui.DefaultStyle)
+ tui.WriteAt(2, 12, response, tui.DefaultStyle)
- tui.Write(1, 14, " TIP: click the mouse", tui.Style {Fg: tui.Yellow, Bold: true})
+ tui.WriteAt(1, 14, " TIP: click the mouse", tui.Style {Fg: tui.Yellow, Bold: true})
- tui.Write(1, 15, " ", tui.DefaultStyle)
- tui.Write(2, 15, lastKey.Name(), tui.DefaultStyle)
- tui.Write(11, 15, " ", tui.DefaultStyle)
- tui.Write(12, 15, strconv.FormatInt(int64(rune(lastKey)), 16), tui.DefaultStyle)
+ tui.WriteAt(1, 15, " ", tui.DefaultStyle)
+ tui.WriteAt(2, 15, lastKey.Name(), tui.DefaultStyle)
+ tui.WriteAt(11, 15, " ", tui.DefaultStyle)
+ tui.WriteAt(12, 15, strconv.FormatInt(int64(rune(lastKey)), 16), tui.DefaultStyle)
if mouseHeld {
- tui.Write(1, 18, " ", tui.DefaultStyle)
- tui.Write(2, 18, strconv.Itoa(mouseButton), tui.DefaultStyle)
+ tui.WriteAt(1, 18, " ", tui.DefaultStyle)
+ tui.WriteAt(2, 18, strconv.Itoa(mouseButton), tui.DefaultStyle)
}
- tui.Write(1, 19, " ", tui.DefaultStyle)
- tui.Write(2, 19, strconv.Itoa(scrolled), tui.DefaultStyle)
+ tui.WriteAt(1, 19, " ", tui.DefaultStyle)
+ tui.WriteAt(2, 19, strconv.Itoa(scrolled), tui.DefaultStyle)
s := tui.Size()
- tui.Write(s.Width - 26, 1, " ", tui.DefaultStyle)
- tui.Write(s.Width - 25, 1, "HOME", tui.Style {Bg: tui.Green, Bold: true})
+ tui.WriteAt(s.Width - 26, 1, " ", tui.DefaultStyle)
+ tui.WriteAt(s.Width - 25, 1, "HOME", tui.Style {Bg: tui.Green, Bold: true})
hs := fmt.Sprintf(" %02d", score.home)
- tui.Write(s.Width - 26, 2, hs, tui.Style {Fg: tui.Yellow, Bold: true})
+ tui.WriteAt(s.Width - 26, 2, hs, tui.Style {Fg: tui.Yellow, Bold: true})
- tui.Write(s.Width - 16, 1, " ", tui.DefaultStyle)
- tui.Write(s.Width - 15, 1, username, tui.Style {Bg: tui.Red, Bold: true})
+ tui.WriteAt(s.Width - 16, 1, " ", tui.DefaultStyle)
+ tui.WriteAt(s.Width - 15, 1, username, tui.Style {Bg: tui.Red, Bold: true})
gs := fmt.Sprintf(" %02d", score.guest)
- tui.Write(s.Width - 16, 2, gs, tui.Style {Fg: tui.Yellow, Bold: true})
+ tui.WriteAt(s.Width - 16, 2, gs, tui.Style {Fg: tui.Yellow, Bold: true})
if err := tui.Present(); err != nil {
log.Fatal(err)
@@ -220,24 +220,24 @@ func drawFootball(balls []ball) {
for y := 0; y < s.Height; y++ {
for x := 0; x < s.Width; x++ {
if (x + 66) % 10 == 1 && (y + 2) % 5 == 1 {
- tui.Write(x, y, "*", tui.Style {Fg: tui.Green})
+ tui.WriteAt(x, y, "*", tui.Style {Fg: tui.Green})
}
}
}
- tui.Write(2, 1, "normal", tui.Style {Fg: tui.Red})
- tui.Write(2, 2, "bold", tui.Style {Fg: tui.Yellow, Bold: true})
- tui.Write(2, 3, "italic", tui.Style {Fg: tui.Green, Italic: true})
- tui.Write(2, 4, "underline", tui.Style {Fg: tui.Blue, Underline: true})
- tui.Write(2, 5, "strikethrough", tui.Style {Fg: tui.Magenta, Strikethrough: true})
- tui.Write(2, 6, "hooray!", tui.Style {Fg: tui.White, Bold: true, Italic: true, Underline: true, Strikethrough: true})
+ tui.WriteAt(2, 1, "normal", tui.Style {Fg: tui.Red})
+ tui.WriteAt(2, 2, "bold", tui.Style {Fg: tui.Yellow, Bold: true})
+ tui.WriteAt(2, 3, "italic", tui.Style {Fg: tui.Green, Italic: true})
+ tui.WriteAt(2, 4, "underline", tui.Style {Fg: tui.Blue, Underline: true})
+ tui.WriteAt(2, 5, "strikethrough", tui.Style {Fg: tui.Magenta, Strikethrough: true})
+ tui.WriteAt(2, 6, "hooray!", tui.Style {Fg: tui.White, Bold: true, Italic: true, Underline: true, Strikethrough: true})
for _, b := range balls {
if b.explode > 0 {
- tui.Write(b.x, b.y, "💥", tui.DefaultStyle)
+ tui.WriteAt(b.x, b.y, "💥", tui.DefaultStyle)
} else if !b.inGoal {
- tui.Write(b.x, b.y, "âš½", tui.DefaultStyle)
+ tui.WriteAt(b.x, b.y, "âš½", tui.DefaultStyle)
}
}
gx := s.Width / 2 - 1
- tui.Write(gx, 0, "🥅", tui.DefaultStyle)
+ tui.WriteAt(gx, 0, "🥅", tui.DefaultStyle)
}
diff --git a/tui/draw.go b/tui/draw.go
index 01dfc83..2005f1a 100644
--- a/tui/draw.go
+++ b/tui/draw.go
@@ -26,30 +26,32 @@ type surface map[pos]char
type screen struct {
front surface
back surface
- prevSize Dims
+ prevSize ScreenSize
writer *bufio.Writer
cursor pos
}
-var terminfo *termfo.Terminfo
+var (
+ terminfo *termfo.Terminfo
+ scr screen
+)
-var scr screen
func init() {
scr.writer = bufio.NewWriterSize(os.Stdout, 50000)
Clear()
}
-type Dims struct {
+type ScreenSize struct {
Width int
Height int
}
-func Size() Dims {
+func Size() ScreenSize {
w, h, _ := term.GetSize(0)
- return Dims {w, h}
+ return ScreenSize {w, h}
}
-func Write(x int, y int, text string, style Style) int {
+func WriteAt(x int, y int, text string, style Style) int {
width := 0
g := uniseg.NewGraphemes(text)
for g.Next() {
@@ -107,15 +109,15 @@ func End() {
if saved == nil {
return
}
- if term.Restore(0, saved) != nil {
- return
- }
- saved = nil
os.Stdout.WriteString(
terminfo.Get(caps.ClearScreen) +
terminfo.Get(caps.XM, 0) +
terminfo.Get(caps.ExitCaMode),
)
+ if term.Restore(0, saved) != nil {
+ return
+ }
+ saved = nil
}
func writeCursor(x int, y int) error {
diff --git a/tui/event.go b/tui/event.go
index 997a8a4..5ce7c4e 100644
--- a/tui/event.go
+++ b/tui/event.go
@@ -26,60 +26,14 @@ type Event struct {
Resize bool
}
-var evChan chan Event
-var once sync.Once
+var (
+ evChan chan Event = make(chan Event, 1)
+ once sync.Once
+)
func Events() <-chan Event {
once.Do(func() {
- evChan = make(chan Event, 2)
-
- // buffer FindKeys
- ch := make(chan termfo.Event, 16)
- go func() {
- r := bufio.NewReader(os.Stdin)
- for e := range terminfo.FindKeys(r) {
- ch <- e
- if e.Err != nil {
- return
- }
- }
- }()
-
- go func() {
- for kev := range ch {
- var ev Event
- if kev.Err != nil {
- ev.Err = kev.Err
- evChan <- ev
- return
- }
-
- noMods := kev.Key & (keys.Ctrl | keys.Alt) == 0
- notSpecial := kev.Key.WithoutMods() < (1 << 32)
- if noMods && notSpecial {
- r := rune(kev.Key.WithoutMods())
- if kev.Key & keys.Shift != 0 && r >= 'a' && r <= 'z' {
- r -= 0x20
- }
- ev.TextInput = r
- }
- if kev.Key == keys.Tab {
- ev.TextInput = '\t'
- }
-
- switch kev.Key {
- case keys.Mouse:
- if err := parseMouse(&ev, ch); err != nil {
- ev.Err = err
- evChan <- ev
- return
- }
- default:
- ev.Key = kev.Key
- }
-
- evChan <- ev
- }
- }()
+ ch := terminfo.FindKeys(bufio.NewReader(os.Stdin))
+ go readKeys(ch, evChan)
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGWINCH)
@@ -89,10 +43,46 @@ func Events() <-chan Event {
}
}()
})
-
return evChan
}
+func readKeys(ch <-chan termfo.Event, evChan chan<- Event) {
+ for kev := range ch {
+ var ev Event
+ if kev.Err != nil {
+ ev.Err = kev.Err
+ evChan <- ev
+ return
+ }
+
+ noMods := kev.Key & (keys.Ctrl | keys.Alt) == 0
+ notSpecial := kev.Key.WithoutMods() < (1 << 32)
+ if noMods && notSpecial {
+ r := rune(kev.Key.WithoutMods())
+ if kev.Key & keys.Shift != 0 && r >= 'a' && r <= 'z' {
+ r -= 0x20
+ }
+ ev.TextInput = r
+ }
+ if kev.Key == keys.Tab {
+ ev.TextInput = '\t'
+ }
+
+ switch kev.Key {
+ case keys.Mouse:
+ if err := parseMouse(&ev, ch); err != nil {
+ ev.Err = err
+ evChan <- ev
+ return
+ }
+ default:
+ ev.Key = kev.Key
+ }
+
+ evChan <- ev
+ }
+}
+
func parseMouse(ev *Event, ch <-chan termfo.Event) error {
var (
arg strings.Builder