]> git.0d.be Git - barnard.git/blobdiff - uiterm/ui.go
update import path
[barnard.git] / uiterm / ui.go
index 63a005197ee73848ccb84c293a0ecfcb54fc2f10..3eb12220a4fcc74e0e01e034c242ec68055ad3b9 100644 (file)
@@ -1,11 +1,12 @@
-package uiterm
+package uiterm // import "layeh.com/barnard/uiterm"
 
 import (
+       "errors"
+       "sync/atomic"
+
        "github.com/nsf/termbox-go"
 )
 
-type LayoutFunc func(ui *Ui, width, height int)
-
 type KeyListener func(ui *Ui, key Key)
 
 type UiManager interface {
@@ -14,19 +15,20 @@ type UiManager interface {
 }
 
 type Ui struct {
+       Fg, Bg Attribute
+
        close   chan bool
        manager UiManager
 
+       drawCount     int32
        elements      map[string]*uiElement
        activeElement *uiElement
 
        keyListeners map[Key][]KeyListener
-
-       fg Attribute
-       bg Attribute
 }
 
 type uiElement struct {
+       Name           string
        X0, Y0, X1, Y1 int
        View           View
 }
@@ -49,36 +51,43 @@ func (ui *Ui) Close() {
 
 func (ui *Ui) Refresh() {
        if termbox.IsInit {
-               termbox.Clear(termbox.Attribute(ui.fg), termbox.Attribute(ui.bg))
+               ui.beginDraw()
+               defer ui.endDraw()
+
+               termbox.Clear(termbox.Attribute(ui.Fg), termbox.Attribute(ui.Bg))
                termbox.HideCursor()
                for _, element := range ui.elements {
-                       element.View.draw()
+                       element.View.uiDraw()
                }
+       }
+}
+
+func (ui *Ui) beginDraw() {
+       atomic.AddInt32(&ui.drawCount, 1)
+}
+
+func (ui *Ui) endDraw() {
+       if count := atomic.AddInt32(&ui.drawCount, -1); count == 0 {
                termbox.Flush()
        }
 }
 
-func (ui *Ui) Active() View {
-       return ui.activeElement.View
+func (ui *Ui) Active() string {
+       return ui.activeElement.Name
 }
 
 func (ui *Ui) SetActive(name string) {
        element, _ := ui.elements[name]
        if ui.activeElement != nil {
-               ui.activeElement.View.setActive(false)
+               ui.activeElement.View.uiSetActive(false)
        }
        ui.activeElement = element
        if element != nil {
-               element.View.setActive(true)
+               element.View.uiSetActive(true)
        }
        ui.Refresh()
 }
 
-func (ui *Ui) SetClear(fg, bg Attribute) {
-       ui.fg = fg
-       ui.bg = bg
-}
-
 func (ui *Ui) Run() error {
        if termbox.IsInit {
                return nil
@@ -123,7 +132,7 @@ func (ui *Ui) Run() error {
 
 func (ui *Ui) onCharacterEvent(ch rune) {
        if ui.activeElement != nil {
-               ui.activeElement.View.characterEvent(ch)
+               ui.activeElement.View.uiCharacterEvent(ch)
        }
 }
 
@@ -134,36 +143,30 @@ func (ui *Ui) onKeyEvent(mod Modifier, key Key) {
                }
        }
        if ui.activeElement != nil {
-               ui.activeElement.View.keyEvent(mod, key)
+               ui.activeElement.View.uiKeyEvent(mod, key)
        }
 }
 
-func (ui *Ui) SetView(name string, x0, y0, x1, y1 int, view View) {
-       if element, ok := ui.elements[name]; ok {
-               element.X0 = x0
-               element.Y0 = y0
-               element.X1 = x1
-               element.Y1 = y1
-               view = element.View
-       } else {
-               ui.elements[name] = &uiElement{
-                       X0:   x0,
-                       Y0:   y0,
-                       X1:   x1,
-                       Y1:   y1,
-                       View: view,
-               }
-               view.uiInitialize(ui)
+func (ui *Ui) Add(name string, view View) error {
+       if _, ok := ui.elements[name]; ok {
+               return errors.New("view already exists")
+       }
+       ui.elements[name] = &uiElement{
+               Name: name,
+               View: view,
        }
-       view.setBounds(x0, y0, x1, y1)
+       view.uiInitialize(ui)
+       return nil
 }
 
-func (ui *Ui) View(name string) View {
-       if element, ok := ui.elements[name]; !ok {
-               return nil
-       } else {
-               return element.View
+func (ui *Ui) SetBounds(name string, x0, y0, x1, y1 int) error {
+       element, ok := ui.elements[name]
+       if !ok {
+               return errors.New("view does not exist")
        }
+       element.X0, element.Y0, element.X1, element.Y1 = x0, y0, x1, y1
+       element.View.uiSetBounds(x0, y0, x1, y1)
+       return nil
 }
 
 func (ui *Ui) AddKeyListener(listener KeyListener, key Key) {