src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/cli/examples/widget/main.go (about)

     1  // Command widget allows manually testing a single widget.
     2  package main
     3  
     4  import (
     5  	"flag"
     6  	"fmt"
     7  	"os"
     8  	"strconv"
     9  
    10  	"src.elv.sh/pkg/cli"
    11  	"src.elv.sh/pkg/cli/term"
    12  	"src.elv.sh/pkg/cli/tk"
    13  	"src.elv.sh/pkg/ui"
    14  )
    15  
    16  var (
    17  	maxHeight  = flag.Int("max-height", 10, "maximum height")
    18  	horizontal = flag.Bool("horizontal", false, "use horizontal listbox layout")
    19  )
    20  
    21  func makeWidget() tk.Widget {
    22  	items := tk.TestItems{Prefix: "list item "}
    23  	w := tk.NewComboBox(tk.ComboBoxSpec{
    24  		CodeArea: tk.CodeAreaSpec{
    25  			Prompt: func() ui.Text {
    26  				return ui.Concat(ui.T(" NUMBER ", ui.Bold, ui.BgMagenta), ui.T(" "))
    27  			},
    28  		},
    29  		ListBox: tk.ListBoxSpec{
    30  			State:       tk.ListBoxState{Items: &items},
    31  			Placeholder: ui.T("(no items)"),
    32  			Horizontal:  *horizontal,
    33  		},
    34  		OnFilter: func(w tk.ComboBox, filter string) {
    35  			if n, err := strconv.Atoi(filter); err == nil {
    36  				items.NItems = n
    37  			}
    38  		},
    39  	})
    40  	return w
    41  }
    42  
    43  func main() {
    44  	flag.Parse()
    45  	widget := makeWidget()
    46  
    47  	tty := cli.NewTTY(os.Stdin, os.Stderr)
    48  	restore, err := tty.Setup()
    49  	if err != nil {
    50  		fmt.Fprintln(os.Stderr, err)
    51  		return
    52  	}
    53  	defer restore()
    54  	defer tty.CloseReader()
    55  	for {
    56  		h, w := tty.Size()
    57  		if h > *maxHeight {
    58  			h = *maxHeight
    59  		}
    60  		tty.UpdateBuffer(nil, widget.Render(w, h), false)
    61  		event, err := tty.ReadEvent()
    62  		if err != nil {
    63  			errBuf := term.NewBufferBuilder(w).Write(err.Error(), ui.FgRed).Buffer()
    64  			tty.UpdateBuffer(nil, errBuf, true)
    65  			break
    66  		}
    67  		handled := widget.Handle(event)
    68  		if !handled && event == term.K('D', ui.Ctrl) {
    69  			tty.UpdateBuffer(nil, term.NewBufferBuilder(w).Buffer(), true)
    70  			break
    71  		}
    72  	}
    73  }