6 "github.com/nsf/termbox-go"
9 type KeyListener func(ui *Ui, key Key)
11 type UiManager interface {
12 OnUiInitialize(ui *Ui)
13 OnUiResize(ui *Ui, width, height int)
23 elements map[string]*uiElement
24 activeElement *uiElement
26 keyListeners map[Key][]KeyListener
29 type uiElement struct {
35 func New(manager UiManager) *Ui {
37 close: make(chan bool, 10),
38 elements: make(map[string]*uiElement),
40 keyListeners: make(map[Key][]KeyListener),
45 func (ui *Ui) Close() {
51 func (ui *Ui) Refresh() {
53 termbox.Clear(termbox.Attribute(ui.Fg), termbox.Attribute(ui.Bg))
55 for _, element := range ui.elements {
62 func (ui *Ui) Active() string {
63 return ui.activeElement.Name
66 func (ui *Ui) SetActive(name string) {
67 element, _ := ui.elements[name]
68 if ui.activeElement != nil {
69 ui.activeElement.View.uiSetActive(false)
71 ui.activeElement = element
73 element.View.uiSetActive(true)
78 func (ui *Ui) Run() error {
82 if err := termbox.Init(); err != nil {
86 termbox.SetInputMode(termbox.InputAlt)
88 events := make(chan termbox.Event)
91 events <- termbox.PollEvent()
95 ui.manager.OnUiInitialize(ui)
96 width, height := termbox.Size()
97 ui.manager.OnUiResize(ui, width, height)
104 case event := <-events:
106 case termbox.EventResize:
107 ui.manager.OnUiResize(ui, event.Width, event.Height)
109 case termbox.EventKey:
111 ui.onCharacterEvent(event.Ch)
113 ui.onKeyEvent(Modifier(event.Mod), Key(event.Key))
120 func (ui *Ui) onCharacterEvent(ch rune) {
121 if ui.activeElement != nil {
122 ui.activeElement.View.uiCharacterEvent(ch)
126 func (ui *Ui) onKeyEvent(mod Modifier, key Key) {
127 if ui.keyListeners[key] != nil {
128 for _, listener := range ui.keyListeners[key] {
132 if ui.activeElement != nil {
133 ui.activeElement.View.uiKeyEvent(mod, key)
137 func (ui *Ui) Add(name string, view View) error {
138 if _, ok := ui.elements[name]; ok {
139 return errors.New("view already exists")
141 ui.elements[name] = &uiElement{
145 view.uiInitialize(ui)
149 func (ui *Ui) SetBounds(name string, x0, y0, x1, y1 int) error {
150 element, ok := ui.elements[name]
152 return errors.New("view does not exist")
154 element.X0, element.Y0, element.X1, element.Y1 = x0, y0, x1, y1
155 element.View.uiSetBounds(x0, y0, x1, y1)
159 func (ui *Ui) AddKeyListener(listener KeyListener, key Key) {
160 ui.keyListeners[key] = append(ui.keyListeners[key], listener)