mirror of
				https://github.com/br0xen/termbox-screen.git
				synced 2025-10-30 12:53:11 -05:00 
			
		
		
		
	Initial Commit
This commit is contained in:
		
							
								
								
									
										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() | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user