6 "github.com/nsf/termbox-go"
9 type LayoutFunc func(ui *Ui, width, height int)
11 type KeyListener func(ui *Ui, key Key)
13 type UiManager interface {
14 OnUiInitialize(ui *Ui)
15 OnUiResize(ui *Ui, width, height int)
25 elements map[string]*uiElement
26 activeElement *uiElement
28 keyListeners map[Key][]KeyListener
31 type uiElement struct {
36 func New(manager UiManager) *Ui {
38 close: make(chan bool, 10),
39 elements: make(map[string]*uiElement),
41 keyListeners: make(map[Key][]KeyListener),
46 func (ui *Ui) Close() {
52 func (ui *Ui) Refresh() {
54 termbox.Clear(termbox.Attribute(ui.Fg), termbox.Attribute(ui.Bg))
56 for _, element := range ui.elements {
63 func (ui *Ui) Active() View {
64 return ui.activeElement.View
67 func (ui *Ui) SetActive(name string) {
68 element, _ := ui.elements[name]
69 if ui.activeElement != nil {
70 ui.activeElement.View.setActive(false)
72 ui.activeElement = element
74 element.View.setActive(true)
79 func (ui *Ui) Run() error {
83 if err := termbox.Init(); err != nil {
87 termbox.SetInputMode(termbox.InputAlt)
89 events := make(chan termbox.Event)
92 events <- termbox.PollEvent()
96 ui.manager.OnUiInitialize(ui)
97 width, height := termbox.Size()
98 ui.manager.OnUiResize(ui, width, height)
105 case event := <-events:
107 case termbox.EventResize:
108 ui.manager.OnUiResize(ui, event.Width, event.Height)
110 case termbox.EventKey:
112 ui.onCharacterEvent(event.Ch)
114 ui.onKeyEvent(Modifier(event.Mod), Key(event.Key))
121 func (ui *Ui) onCharacterEvent(ch rune) {
122 if ui.activeElement != nil {
123 ui.activeElement.View.characterEvent(ch)
127 func (ui *Ui) onKeyEvent(mod Modifier, key Key) {
128 if ui.keyListeners[key] != nil {
129 for _, listener := range ui.keyListeners[key] {
133 if ui.activeElement != nil {
134 ui.activeElement.View.keyEvent(mod, key)
138 func (ui *Ui) Add(name string, view View) error {
139 if _, ok := ui.elements[name]; ok {
140 return errors.New("view already exists")
142 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 cannot be found")
158 element.View.setBounds(x0, y0, x1, y1)
162 func (ui *Ui) AddKeyListener(listener KeyListener, key Key) {
163 ui.keyListeners[key] = append(ui.keyListeners[key], listener)