1// Copyright 2019 The TCell Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use file except in compliance with the License.
5// You may obtain a copy of the license at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// colors just displays a single centered rectangle that should pulse
16// through available colors.  It uses the RGB color cube, bumping at
17// predefined larger intervals (values of about 8) in order that the
18// changes happen quickly enough to be appreciable.
19//
20// Press ESC to exit the program.
21package main
22
23import (
24	"fmt"
25	"math/rand"
26	"os"
27	"time"
28
29	"github.com/gdamore/tcell"
30)
31
32var red = int32(rand.Int() % 256)
33var grn = int32(rand.Int() % 256)
34var blu = int32(rand.Int() % 256)
35var inc = int32(8) // rate of color change
36var redi = int32(inc)
37var grni = int32(inc)
38var blui = int32(inc)
39
40func makebox(s tcell.Screen) {
41	w, h := s.Size()
42
43	if w == 0 || h == 0 {
44		return
45	}
46
47	glyphs := []rune{'@', '#', '&', '*', '=', '%', 'Z', 'A'}
48
49	lh := h / 2
50	lw := w / 2
51	lx := w / 4
52	ly := h / 4
53	st := tcell.StyleDefault
54	gl := ' '
55
56	if s.Colors() == 0 {
57		st = st.Reverse(rand.Int()%2 == 0)
58		gl = glyphs[rand.Int()%len(glyphs)]
59	} else {
60
61		red += redi
62		if (red >= 256) || (red < 0) {
63			redi = -redi
64			red += redi
65		}
66		grn += grni
67		if (grn >= 256) || (grn < 0) {
68			grni = -grni
69			grn += grni
70		}
71		blu += blui
72		if (blu >= 256) || (blu < 0) {
73			blui = -blui
74			blu += blui
75
76		}
77		st = st.Background(tcell.NewRGBColor(red, grn, blu))
78	}
79	for row := 0; row < lh; row++ {
80		for col := 0; col < lw; col++ {
81			s.SetCell(lx+col, ly+row, st, gl)
82		}
83	}
84	s.Show()
85}
86
87func flipcoin() bool {
88	if rand.Int()&1 == 0 {
89		return false
90	}
91	return true
92}
93
94func main() {
95
96	rand.Seed(time.Now().UnixNano())
97	tcell.SetEncodingFallback(tcell.EncodingFallbackASCII)
98	s, e := tcell.NewScreen()
99	if e != nil {
100		fmt.Fprintf(os.Stderr, "%v\n", e)
101		os.Exit(1)
102	}
103	if e = s.Init(); e != nil {
104		fmt.Fprintf(os.Stderr, "%v\n", e)
105		os.Exit(1)
106	}
107
108	s.SetStyle(tcell.StyleDefault.
109		Foreground(tcell.ColorBlack).
110		Background(tcell.ColorWhite))
111	s.Clear()
112
113	quit := make(chan struct{})
114	go func() {
115		for {
116			ev := s.PollEvent()
117			switch ev := ev.(type) {
118			case *tcell.EventKey:
119				switch ev.Key() {
120				case tcell.KeyEscape, tcell.KeyEnter:
121					close(quit)
122					return
123				case tcell.KeyCtrlL:
124					s.Sync()
125				}
126			case *tcell.EventResize:
127				s.Sync()
128			}
129		}
130	}()
131
132	cnt := 0
133	dur := time.Duration(0)
134loop:
135	for {
136		select {
137		case <-quit:
138			break loop
139		case <-time.After(time.Millisecond * 50):
140		}
141		start := time.Now()
142		makebox(s)
143		dur += time.Now().Sub(start)
144		cnt++
145		if cnt%(256/int(inc)) == 0 {
146			if flipcoin() {
147				redi = -redi
148			}
149			if flipcoin() {
150				grni = -grni
151			}
152			if flipcoin() {
153				blui = -blui
154			}
155		}
156	}
157
158	s.Fini()
159	fmt.Printf("Finished %d boxes in %s\n", cnt, dur)
160	fmt.Printf("Average is %0.3f ms / box\n", (float64(dur)/float64(cnt))/1000000.0)
161}
162