4 "github.com/nsf/termbox-go"
7 type LayoutFunc func(ui *Ui, width, height int)
9 type KeyListener func(ui *Ui, key Key)
11 type UiManager interface {
12 OnUiInitialize(ui *Ui)
13 OnUiResize(ui *Ui, width, height int)
20 elements map[string]*uiElement
21 activeElement *uiElement
23 keyListeners map[Key][]KeyListener
29 type uiElement struct {
34 func New(manager UiManager) *Ui {
36 close: make(chan bool, 10),
37 elements: make(map[string]*uiElement),
39 keyListeners: make(map[Key][]KeyListener),
44 func (ui *Ui) Close() {
50 func (ui *Ui) Refresh() {
52 termbox.Clear(termbox.Attribute(ui.fg), termbox.Attribute(ui.bg))
54 for _, element := range ui.elements {
61 func (ui *Ui) Active() View {
62 return ui.activeElement.View
65 func (ui *Ui) SetActive(name string) {
66 element, _ := ui.elements[name]
67 if ui.activeElement != nil {
68 ui.activeElement.View.setActive(ui, false)
70 ui.activeElement = element
72 element.View.setActive(ui, true)
77 func (ui *Ui) SetClear(fg, bg Attribute) {
82 func (ui *Ui) Run() error {
86 if err := termbox.Init(); err != nil {
90 termbox.SetInputMode(termbox.InputAlt)
92 events := make(chan termbox.Event)
95 events <- termbox.PollEvent()
99 ui.manager.OnUiInitialize(ui)
100 width, height := termbox.Size()
101 ui.manager.OnUiResize(ui, width, height)
108 case event := <-events:
110 case termbox.EventResize:
111 ui.manager.OnUiResize(ui, event.Width, event.Height)
113 case termbox.EventKey:
115 ui.onCharacterEvent(event.Ch)
117 ui.onKeyEvent(Modifier(event.Mod), Key(event.Key))
124 func (ui *Ui) onCharacterEvent(ch rune) {
125 if ui.activeElement != nil {
126 ui.activeElement.View.characterEvent(ui, ch)
130 func (ui *Ui) onKeyEvent(mod Modifier, key Key) {
131 if ui.keyListeners[key] != nil {
132 for _, listener := range ui.keyListeners[key] {
136 if ui.activeElement != nil {
137 ui.activeElement.View.keyEvent(ui, mod, key)
141 func (ui *Ui) SetView(name string, x0, y0, x1, y1 int, view View) {
142 if element, ok := ui.elements[name]; ok {
149 ui.elements[name] = &uiElement{
157 view.setBounds(ui, x0, y0, x1, y1)
160 func (ui *Ui) View(name string) View {
161 if element, ok := ui.elements[name]; !ok {
168 func (ui *Ui) AddKeyListener(listener KeyListener, key Key) {
169 ui.keyListeners[key] = append(ui.keyListeners[key], listener)