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 {
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(false)
70 ui.activeElement = element
72 element.View.setActive(true)
77 func (ui *Ui) Run() error {
81 if err := termbox.Init(); err != nil {
85 termbox.SetInputMode(termbox.InputAlt)
87 events := make(chan termbox.Event)
90 events <- termbox.PollEvent()
94 ui.manager.OnUiInitialize(ui)
95 width, height := termbox.Size()
96 ui.manager.OnUiResize(ui, width, height)
103 case event := <-events:
105 case termbox.EventResize:
106 ui.manager.OnUiResize(ui, event.Width, event.Height)
108 case termbox.EventKey:
110 ui.onCharacterEvent(event.Ch)
112 ui.onKeyEvent(Modifier(event.Mod), Key(event.Key))
119 func (ui *Ui) onCharacterEvent(ch rune) {
120 if ui.activeElement != nil {
121 ui.activeElement.View.characterEvent(ch)
125 func (ui *Ui) onKeyEvent(mod Modifier, key Key) {
126 if ui.keyListeners[key] != nil {
127 for _, listener := range ui.keyListeners[key] {
131 if ui.activeElement != nil {
132 ui.activeElement.View.keyEvent(mod, key)
136 func (ui *Ui) Add(name string, view View) error {
137 if _, ok := ui.elements[name]; ok {
138 return errors.New("view already exists")
140 ui.elements[name] = &uiElement{
143 view.uiInitialize(ui)
147 func (ui *Ui) SetBounds(name string, x0, y0, x1, y1 int) error {
148 element, ok := ui.elements[name]
150 return errors.New("view cannot be found")
156 element.View.setBounds(x0, y0, x1, y1)
160 func (ui *Ui) AddKeyListener(listener KeyListener, key Key) {
161 ui.keyListeners[key] = append(ui.keyListeners[key], listener)