// The UI manager. This manages the components that make up the UI and dispatches // events. package ui // The UI manager type Ui struct { // The root component rootComponent UiComponent focusedComponent FocusableComponent drawContext *DrawContext driver Driver shutdown bool } // Creates a new UI context. This also initializes the UI state. // Returns the context and an error. func NewUI() (*Ui, error) { driver := &TermboxDriver{} err := driver.Init() if err != nil { return nil, err } drawContext := &DrawContext{driver: driver} ui := &Ui{drawContext: drawContext, driver: driver} return ui, nil } // Closes the UI context. func (ui *Ui) Close() { ui.driver.Close() } // Sets the root component func (ui *Ui) SetRootComponent(comp UiComponent) { ui.rootComponent = comp ui.Remeasure() } // Sets the focused component func (ui *Ui) SetFocusedComponent(newFocused FocusableComponent) { ui.focusedComponent = newFocused } // Remeasures the UI func (ui *Ui) Remeasure() { ui.drawContext.X = 0 ui.drawContext.Y = 0 ui.drawContext.W, ui.drawContext.H = ui.driver.Size() ui.rootComponent.Remeasure(ui.drawContext.W, ui.drawContext.H) } // Redraws the UI. func (ui *Ui) Redraw() { ui.Remeasure() ui.rootComponent.Redraw(ui.drawContext) ui.driver.Sync() } // Quit indicates to the UI that it should shutdown func (ui *Ui) Shutdown() { ui.shutdown = true } // Enter the UI loop func (ui *Ui) Loop() { for !ui.shutdown { ui.Redraw() event := ui.driver.WaitForEvent() // TODO: If the event is a key-press, do something. if event.Type == EventKeyPress { if ui.focusedComponent != nil { ui.focusedComponent.KeyPressed(event.Ch, event.Par) } } else if event.Type == EventResize { // HACK: Find another way to refresh the size of the screen to prevent a full redraw. ui.driver.Sync() } } }