2015-01-03 07:50:37 +00:00
|
|
|
// The UI manager. This manages the components that make up the UI and dispatches
|
|
|
|
|
// events.
|
|
|
|
|
|
|
|
|
|
package ui
|
|
|
|
|
|
|
|
|
|
// The UI manager
|
|
|
|
|
type Ui struct {
|
2017-08-25 23:48:22 +00:00
|
|
|
// The root component
|
|
|
|
|
rootComponent UiComponent
|
|
|
|
|
focusedComponent FocusableComponent
|
2015-01-03 07:50:37 +00:00
|
|
|
|
2017-08-25 23:48:22 +00:00
|
|
|
drawContext *DrawContext
|
|
|
|
|
driver Driver
|
|
|
|
|
shutdown bool
|
2015-01-03 07:50:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Creates a new UI context. This also initializes the UI state.
|
|
|
|
|
// Returns the context and an error.
|
|
|
|
|
func NewUI() (*Ui, error) {
|
2017-08-25 23:48:22 +00:00
|
|
|
driver := &TermboxDriver{}
|
|
|
|
|
err := driver.Init()
|
2015-01-03 07:50:37 +00:00
|
|
|
|
2017-08-25 23:48:22 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2015-01-03 07:50:37 +00:00
|
|
|
|
2017-08-25 23:48:22 +00:00
|
|
|
drawContext := &DrawContext{driver: driver}
|
|
|
|
|
ui := &Ui{drawContext: drawContext, driver: driver}
|
2015-01-03 07:50:37 +00:00
|
|
|
|
2017-08-25 23:48:22 +00:00
|
|
|
return ui, nil
|
2015-01-03 07:50:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Closes the UI context.
|
|
|
|
|
func (ui *Ui) Close() {
|
2017-08-25 23:48:22 +00:00
|
|
|
ui.driver.Close()
|
2015-01-03 07:50:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sets the root component
|
|
|
|
|
func (ui *Ui) SetRootComponent(comp UiComponent) {
|
2017-08-25 23:48:22 +00:00
|
|
|
ui.rootComponent = comp
|
|
|
|
|
ui.Remeasure()
|
2015-01-03 07:50:37 +00:00
|
|
|
}
|
|
|
|
|
|
2015-01-03 12:09:35 +00:00
|
|
|
// Sets the focused component
|
|
|
|
|
func (ui *Ui) SetFocusedComponent(newFocused FocusableComponent) {
|
2017-08-25 23:48:22 +00:00
|
|
|
ui.focusedComponent = newFocused
|
2015-01-03 12:09:35 +00:00
|
|
|
}
|
|
|
|
|
|
2015-01-03 07:50:37 +00:00
|
|
|
// Remeasures the UI
|
|
|
|
|
func (ui *Ui) Remeasure() {
|
2017-08-25 23:48:22 +00:00
|
|
|
ui.drawContext.X = 0
|
|
|
|
|
ui.drawContext.Y = 0
|
|
|
|
|
ui.drawContext.W, ui.drawContext.H = ui.driver.Size()
|
2015-01-03 07:50:37 +00:00
|
|
|
|
2017-08-25 23:48:22 +00:00
|
|
|
ui.rootComponent.Remeasure(ui.drawContext.W, ui.drawContext.H)
|
2015-01-03 07:50:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Redraws the UI.
|
|
|
|
|
func (ui *Ui) Redraw() {
|
2017-08-25 23:48:22 +00:00
|
|
|
ui.Remeasure()
|
2015-01-03 07:50:37 +00:00
|
|
|
|
2017-08-25 23:48:22 +00:00
|
|
|
ui.rootComponent.Redraw(ui.drawContext)
|
|
|
|
|
ui.driver.Sync()
|
2015-01-03 07:50:37 +00:00
|
|
|
}
|
|
|
|
|
|
2017-08-25 23:48:22 +00:00
|
|
|
// Quit indicates to the UI that it should shutdown
|
|
|
|
|
func (ui *Ui) Shutdown() {
|
|
|
|
|
ui.shutdown = true
|
|
|
|
|
}
|
2015-01-03 07:50:37 +00:00
|
|
|
|
|
|
|
|
// Enter the UI loop
|
|
|
|
|
func (ui *Ui) Loop() {
|
2017-08-25 23:48:22 +00:00
|
|
|
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()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|