mirror of
https://github.com/br0xen/termbox-screen.git
synced 2024-11-21 21:23:15 +00:00
Initial Commit
This commit is contained in:
parent
07f9bfdbc8
commit
baa25fe4cf
28
bundle.go
Normal file
28
bundle.go
Normal file
@ -0,0 +1,28 @@
|
||||
package termboxScreen
|
||||
|
||||
type Bundle map[string]interface{}
|
||||
|
||||
func (b Bundle) SetValue(key string, val interface{}) {
|
||||
b[key] = val
|
||||
}
|
||||
|
||||
func (b Bundle) GetBool(key string, def bool) bool {
|
||||
if v, ok := b[key].(bool); ok {
|
||||
return v
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
func (b Bundle) GetString(key, def string) string {
|
||||
if v, ok := b[key].(string); ok {
|
||||
return v
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
func (b Bundle) GetInt(key string, def int) int {
|
||||
if v, ok := b[key].(int); ok {
|
||||
return v
|
||||
}
|
||||
return def
|
||||
}
|
152
screen.go
Normal file
152
screen.go
Normal file
@ -0,0 +1,152 @@
|
||||
package termboxScreen
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
|
||||
termbox "github.com/nsf/termbox-go"
|
||||
)
|
||||
|
||||
type Screen interface {
|
||||
Id() int
|
||||
Initialize(Bundle) error
|
||||
HandleKeyEvent(termbox.Event) int
|
||||
HandleNoneEvent(termbox.Event) int
|
||||
DrawScreen()
|
||||
ResizeScreen()
|
||||
}
|
||||
|
||||
type Manager struct {
|
||||
defaultFg termbox.Attribute
|
||||
defaultBg termbox.Attribute
|
||||
|
||||
screens map[int]Screen
|
||||
displayScreenId int
|
||||
events chan termbox.Event
|
||||
}
|
||||
|
||||
func NewManager() *Manager {
|
||||
m := Manager{
|
||||
defaultFg: termbox.ColorWhite,
|
||||
defaultBg: termbox.ColorBlack,
|
||||
events: make(chan termbox.Event),
|
||||
screens: make(map[int]Screen),
|
||||
}
|
||||
// Add the default user-input provider
|
||||
m.AddEventProvider(func(e chan termbox.Event) {
|
||||
for {
|
||||
e <- termbox.PollEvent()
|
||||
}
|
||||
})
|
||||
return &m
|
||||
}
|
||||
|
||||
func (m *Manager) SetDefaultFg(c termbox.Attribute) { m.defaultFg = c }
|
||||
func (m *Manager) SetDefaultBg(c termbox.Attribute) { m.defaultBg = c }
|
||||
|
||||
// AddScreen adds a screen to the screens map, they're indexed by the value
|
||||
// returned from the screen's Id() function
|
||||
func (m *Manager) AddScreen(s Screen) {
|
||||
m.screens[s.Id()] = s
|
||||
// If this is the only screen we've added, set it to active
|
||||
if len(m.screens) == 1 {
|
||||
m.SetDisplayScreen(s.Id())
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) GetScreens() map[int]Screen {
|
||||
return m.screens
|
||||
}
|
||||
|
||||
func (m *Manager) SetDisplayScreen(id int) error {
|
||||
if id == m.displayScreenId {
|
||||
return nil
|
||||
}
|
||||
var ok bool
|
||||
if _, ok = m.screens[id]; !ok {
|
||||
return errors.New("Invalid Screen Id")
|
||||
}
|
||||
m.displayScreenId = id
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) InitializeScreen(id int, b Bundle) error {
|
||||
var ok bool
|
||||
if _, ok = m.screens[id]; !ok {
|
||||
return errors.New("Invalid screen id")
|
||||
}
|
||||
return m.screens[id].Initialize(b)
|
||||
}
|
||||
|
||||
func (m *Manager) AddEventProvider(provider func(chan termbox.Event)) {
|
||||
go provider(m.events)
|
||||
}
|
||||
|
||||
func (m *Manager) Loop() error {
|
||||
if len(m.screens) == 0 {
|
||||
return errors.New("Loop cannot run without screens")
|
||||
}
|
||||
if err := termbox.Init(); err != nil {
|
||||
return err
|
||||
}
|
||||
termbox.SetOutputMode(termbox.Output256)
|
||||
// We always start display the first screen added
|
||||
m.layoutAndDrawScreen()
|
||||
for {
|
||||
event := <-m.events
|
||||
if event.Type == termbox.EventKey {
|
||||
if event.Key == termbox.KeyCtrlC {
|
||||
break
|
||||
} else if event.Key == termbox.KeyCtrlZ {
|
||||
if runtime.GOOS != "windows" {
|
||||
process, _ := os.FindProcess(os.Getpid())
|
||||
termbox.Close()
|
||||
process.Signal(syscall.SIGSTOP)
|
||||
termbox.Init()
|
||||
}
|
||||
} else {
|
||||
newScreenIndex := m.handleKeyEvent(event)
|
||||
if err := m.SetDisplayScreen(newScreenIndex); err != nil {
|
||||
break
|
||||
}
|
||||
m.layoutAndDrawScreen()
|
||||
}
|
||||
} else if event.Type == termbox.EventNone {
|
||||
// Type = EventNone is how we can trigger automatic events
|
||||
newScreenIndex := m.handleNoneEvent(event)
|
||||
if err := m.SetDisplayScreen(newScreenIndex); err != nil {
|
||||
break
|
||||
}
|
||||
m.layoutAndDrawScreen()
|
||||
} else if event.Type == termbox.EventResize {
|
||||
m.resizeScreen()
|
||||
m.layoutAndDrawScreen()
|
||||
}
|
||||
}
|
||||
termbox.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) handleKeyEvent(event termbox.Event) int {
|
||||
return m.screens[m.displayScreenId].HandleKeyEvent(event)
|
||||
}
|
||||
|
||||
func (m *Manager) handleNoneEvent(event termbox.Event) int {
|
||||
return m.screens[m.displayScreenId].HandleNoneEvent(event)
|
||||
}
|
||||
|
||||
func (m *Manager) resizeScreen() {
|
||||
m.screens[m.displayScreenId].ResizeScreen()
|
||||
}
|
||||
|
||||
func (m *Manager) drawBackground() {
|
||||
termbox.Clear(0, m.defaultBg)
|
||||
}
|
||||
|
||||
func (m *Manager) layoutAndDrawScreen() {
|
||||
m.drawBackground()
|
||||
m.screens[m.displayScreenId].DrawScreen()
|
||||
termbox.Flush()
|
||||
}
|
Loading…
Reference in New Issue
Block a user