github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/misc/logos/cmd/logos.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"runtime/debug"
     7  
     8  	"github.com/gdamore/tcell/v2"
     9  	"github.com/gdamore/tcell/v2/encoding"
    10  	"github.com/gnolang/gno/misc/logos"
    11  )
    12  
    13  func main() {
    14  	encoding.Register()
    15  
    16  	// construct screen
    17  	s, e := tcell.NewScreen()
    18  	if e != nil {
    19  		fmt.Fprintf(os.Stderr, "%v\n", e)
    20  		os.Exit(1)
    21  	}
    22  	// initialize screen
    23  	if e = s.Init(); e != nil {
    24  		fmt.Fprintf(os.Stderr, "%v\n", e)
    25  		os.Exit(1)
    26  	}
    27  	s.SetStyle(tcell.StyleDefault.
    28  		Foreground(tcell.ColorBlack).
    29  		Background(tcell.ColorWhite))
    30  	s.Clear()
    31  	sw, sh := s.Size()
    32  	size := logos.Size{Width: sw, Height: sh}
    33  
    34  	// make a buffered stack.
    35  	stack := logos.NewStack(size)
    36  	stack.PushLayer(makeTestPage())
    37  	bstack := logos.NewBufferedElemView(stack, size)
    38  	bstack.Render()
    39  	bstack.DrawToScreen(s)
    40  
    41  	// recover any panics.
    42  	var rec interface{}
    43  	var recStack []byte
    44  
    45  	// show the screen
    46  	quit := make(chan struct{})
    47  	s.Show()
    48  	go func() {
    49  		// capture panics to print error better.
    50  		defer func() {
    51  			if rec = recover(); rec != nil {
    52  				recStack = debug.Stack()
    53  				close(quit)
    54  				return
    55  			}
    56  		}()
    57  		// handle event
    58  		for {
    59  			ev := s.PollEvent()
    60  			switch ev := ev.(type) {
    61  			case *tcell.EventKey:
    62  				switch ev.Key() {
    63  				case tcell.KeyCtrlQ:
    64  					close(quit)
    65  					return
    66  				case tcell.KeyCtrlR:
    67  					// TODO somehow make it clearer that it happened.
    68  					bstack.DrawToScreen(s)
    69  					s.Sync()
    70  				default:
    71  					bstack.ProcessEventKey(ev)
    72  					if bstack.Render() {
    73  						bstack.DrawToScreen(s)
    74  						s.Sync()
    75  					}
    76  				}
    77  			case *tcell.EventResize:
    78  				s.Sync()
    79  			}
    80  		}
    81  	}()
    82  
    83  	// wait to quit
    84  	<-quit
    85  	s.Fini()
    86  	fmt.Println("charset:", s.CharacterSet())
    87  	fmt.Println("goodbye!")
    88  	fmt.Println(bstack.Sprint())
    89  
    90  	if rec != nil {
    91  		fmt.Println("====================")
    92  		fmt.Println("panic:", rec)
    93  		fmt.Println("stacktrace:\n", string(recStack))
    94  		fmt.Println("====================")
    95  	}
    96  }
    97  
    98  func makeTestString() string {
    99  	s := ""
   100  	putln := func(l string) {
   101  		s += l + "\n"
   102  	}
   103  	// putln("Character set: " + s.CharacterSet())
   104  	putln("Press Ctrl-Q to Exit")
   105  	putln("English:   October")
   106  	putln("Icelandic: október")
   107  	putln("Arabic:    أكتوبر")
   108  	putln("Russian:   октября")
   109  	putln("Greek:     Οκτωβρίου")
   110  	putln("Chinese:   十月 (note, two double wide characters)")
   111  	putln("Combining: A\u030a (should look like Angstrom)")
   112  	putln("Emoticon:  \U0001f618 (blowing a kiss)")
   113  	putln("Airplane:  \u2708 (fly away)")
   114  	putln("Command:   \u2318 (mac clover key)")
   115  	putln("Enclose:   !\u20e3 (should be enclosed exclamation)")
   116  	putln("ZWJ:       \U0001f9db\u200d\u2640 (female vampire)")
   117  	putln("ZWJ:       \U0001f9db\u200d\u2642 (male vampire)")
   118  	putln("Family:    \U0001f469\u200d\U0001f467\u200d\U0001f467 (woman girl girl)\n")
   119  	// XXX why is this broken?
   120  	// putln("Region:    \U0001f1fa\U0001f1f8 (USA! USA!)\n")
   121  	putln("")
   122  	putln("Box:")
   123  	putln(string([]rune{
   124  		tcell.RuneULCorner,
   125  		tcell.RuneHLine,
   126  		tcell.RuneTTee,
   127  		tcell.RuneHLine,
   128  		tcell.RuneURCorner,
   129  	}))
   130  	putln(string([]rune{
   131  		tcell.RuneVLine,
   132  		tcell.RuneBullet,
   133  		tcell.RuneVLine,
   134  		tcell.RuneLantern,
   135  		tcell.RuneVLine,
   136  	}) + "  (bullet, lantern/section)")
   137  	putln(string([]rune{
   138  		tcell.RuneLTee,
   139  		tcell.RuneHLine,
   140  		tcell.RunePlus,
   141  		tcell.RuneHLine,
   142  		tcell.RuneRTee,
   143  	}))
   144  	putln(string([]rune{
   145  		tcell.RuneVLine,
   146  		tcell.RuneDiamond,
   147  		tcell.RuneVLine,
   148  		tcell.RuneUArrow,
   149  		tcell.RuneVLine,
   150  	}) + "  (diamond, up arrow)")
   151  	putln(string([]rune{
   152  		tcell.RuneLLCorner,
   153  		tcell.RuneHLine,
   154  		tcell.RuneBTee,
   155  		tcell.RuneHLine,
   156  		tcell.RuneLRCorner,
   157  	}))
   158  	return s
   159  }
   160  
   161  func makeTestPage() *logos.BufferedElemView {
   162  	// make a buffered page.
   163  	ts := makeTestString()
   164  	style := logos.DefaultStyle()
   165  	style.Padding = logos.Padding{2, 2, 2, 2}
   166  	style.Border = logos.DefaultBorder()
   167  	// TODO width shouldn't matter.
   168  	page := logos.NewPage(ts, 84, true, style)
   169  	bpv := logos.NewBufferedElemView(page, logos.Size{})
   170  	return bpv
   171  }