Added a key event listener which components can implement, and have also mapped termio keys into local keys.
This commit is contained in:
parent
4a831f7730
commit
6227b76b86
1
main.go
1
main.go
|
|
@ -22,6 +22,7 @@ func main() {
|
||||||
clientArea := &ui.RelativeLayout{ Client: grid, South: statusLayout }
|
clientArea := &ui.RelativeLayout{ Client: grid, South: statusLayout }
|
||||||
|
|
||||||
uiManager.SetRootComponent(clientArea)
|
uiManager.SetRootComponent(clientArea)
|
||||||
|
uiManager.SetFocusedComponent(grid)
|
||||||
|
|
||||||
uiManager.Loop()
|
uiManager.Loop()
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,13 @@ type UiComponent interface {
|
||||||
Remeasure(w, h int) (int, int)
|
Remeasure(w, h int) (int, int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A component implementing this interface can be given focus and will receive keyboard events.
|
||||||
|
type FocusableComponent interface {
|
||||||
|
|
||||||
|
// Called when the component has focus and a key has been pressed
|
||||||
|
KeyPressed(key rune)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// UI context.
|
// UI context.
|
||||||
|
|
|
||||||
66
ui/driver.go
66
ui/driver.go
|
|
@ -25,6 +25,68 @@ const (
|
||||||
AttrReverse
|
AttrReverse
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// Special keys
|
||||||
|
const (
|
||||||
|
KeyF1 rune = 0x8000 + iota
|
||||||
|
KeyF2
|
||||||
|
KeyF3
|
||||||
|
KeyF4
|
||||||
|
KeyF5
|
||||||
|
KeyF6
|
||||||
|
KeyF7
|
||||||
|
KeyF8
|
||||||
|
KeyF9
|
||||||
|
KeyF10
|
||||||
|
KeyF11
|
||||||
|
KeyF12
|
||||||
|
KeyInsert
|
||||||
|
KeyDelete
|
||||||
|
KeyHome
|
||||||
|
KeyEnd
|
||||||
|
KeyPgup
|
||||||
|
KeyPgdn
|
||||||
|
KeyArrowUp
|
||||||
|
KeyArrowDown
|
||||||
|
KeyArrowLeft
|
||||||
|
KeyArrowRight
|
||||||
|
|
||||||
|
KeyCtrlSpace
|
||||||
|
KeyCtrlA
|
||||||
|
KeyCtrlB
|
||||||
|
KeyCtrlC
|
||||||
|
KeyCtrlD
|
||||||
|
KeyCtrlE
|
||||||
|
KeyCtrlF
|
||||||
|
KeyCtrlG
|
||||||
|
KeyCtrlH
|
||||||
|
KeyCtrlI
|
||||||
|
KeyCtrlJ
|
||||||
|
KeyCtrlK
|
||||||
|
KeyCtrlL
|
||||||
|
KeyCtrlM
|
||||||
|
KeyCtrlN
|
||||||
|
KeyCtrlO
|
||||||
|
KeyCtrlP
|
||||||
|
KeyCtrlQ
|
||||||
|
KeyCtrlR
|
||||||
|
KeyCtrlS
|
||||||
|
KeyCtrlT
|
||||||
|
KeyCtrlU
|
||||||
|
KeyCtrlV
|
||||||
|
KeyCtrlW
|
||||||
|
KeyCtrlX
|
||||||
|
KeyCtrlY
|
||||||
|
KeyCtrlZ
|
||||||
|
KeyCtrl3
|
||||||
|
KeyCtrl4
|
||||||
|
KeyCtrl5
|
||||||
|
KeyCtrl6
|
||||||
|
KeyCtrl7
|
||||||
|
KeyCtrl8
|
||||||
|
KeySpace
|
||||||
|
)
|
||||||
|
|
||||||
// The type of events supported by the driver
|
// The type of events supported by the driver
|
||||||
type EventType int
|
type EventType int
|
||||||
|
|
||||||
|
|
@ -34,14 +96,14 @@ const (
|
||||||
// Event when the window is resized
|
// Event when the window is resized
|
||||||
EventResize
|
EventResize
|
||||||
|
|
||||||
// Event indicating a key press. The event parameter is the key scancode?
|
// Event indicating a key press. The key is set in Ch
|
||||||
EventKeyPress
|
EventKeyPress
|
||||||
)
|
)
|
||||||
|
|
||||||
// Data from an event callback.
|
// Data from an event callback.
|
||||||
type Event struct {
|
type Event struct {
|
||||||
Type EventType
|
Type EventType
|
||||||
Par int
|
Ch rune
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
14
ui/grid.go
14
ui/grid.go
|
|
@ -323,6 +323,20 @@ func (grid *Grid) Redraw(ctx *DrawContext) {
|
||||||
grid.cellsWide, grid.cellsHigh = grid.renderGrid(ctx, viewportRect, 0, 0, 0, 0)
|
grid.cellsWide, grid.cellsHigh = grid.renderGrid(ctx, viewportRect, 0, 0, 0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called when the component has focus and a key has been pressed
|
||||||
|
func (grid *Grid) KeyPressed(key rune) {
|
||||||
|
if (key == 'i') || (key == KeyArrowUp) {
|
||||||
|
grid.MoveBy(0, -1)
|
||||||
|
} else if (key == 'k') || (key == KeyArrowDown) {
|
||||||
|
grid.MoveBy(0, 1)
|
||||||
|
} else if (key == 'j') || (key == KeyArrowLeft) {
|
||||||
|
grid.MoveBy(-1, 0)
|
||||||
|
} else if (key == 'l') || (key == KeyArrowRight) {
|
||||||
|
grid.MoveBy(1, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
// Test Model
|
// Test Model
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ type Ui struct {
|
||||||
|
|
||||||
// The root component
|
// The root component
|
||||||
rootComponent UiComponent
|
rootComponent UiComponent
|
||||||
|
focusedComponent FocusableComponent
|
||||||
|
|
||||||
drawContext *DrawContext
|
drawContext *DrawContext
|
||||||
driver Driver
|
driver Driver
|
||||||
|
|
@ -61,6 +62,11 @@ func (ui *Ui) SetRootComponent(comp UiComponent) {
|
||||||
ui.Remeasure()
|
ui.Remeasure()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets the focused component
|
||||||
|
func (ui *Ui) SetFocusedComponent(newFocused FocusableComponent) {
|
||||||
|
ui.focusedComponent = newFocused
|
||||||
|
}
|
||||||
|
|
||||||
// Remeasures the UI
|
// Remeasures the UI
|
||||||
func (ui *Ui) Remeasure() {
|
func (ui *Ui) Remeasure() {
|
||||||
ui.drawContext.X = 0
|
ui.drawContext.X = 0
|
||||||
|
|
@ -104,7 +110,9 @@ func (ui *Ui) Loop() {
|
||||||
|
|
||||||
// TODO: If the event is a key-press, do something.
|
// TODO: If the event is a key-press, do something.
|
||||||
if event.Type == EventKeyPress {
|
if event.Type == EventKeyPress {
|
||||||
return
|
if ui.focusedComponent != nil {
|
||||||
|
ui.focusedComponent.KeyPressed(event.Ch)
|
||||||
|
}
|
||||||
} else if event.Type == EventResize {
|
} else if event.Type == EventResize {
|
||||||
|
|
||||||
// HACK: Find another way to refresh the size of the screen to prevent a full redraw.
|
// HACK: Find another way to refresh the size of the screen to prevent a full redraw.
|
||||||
|
|
|
||||||
|
|
@ -38,4 +38,4 @@ func (sbar *StatusBar) Redraw(context *DrawContext) {
|
||||||
termbox.SetCell(x1, y, runeToPrint, termbox.AttrReverse, termbox.AttrReverse)
|
termbox.SetCell(x1, y, runeToPrint, termbox.AttrReverse, termbox.AttrReverse)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ func (td *TermboxDriver) SetCell(x, y int, ch rune, fg, bg Attribute) {
|
||||||
|
|
||||||
// Synchronizes the internal buffer with the real buffer
|
// Synchronizes the internal buffer with the real buffer
|
||||||
func (td *TermboxDriver) Sync() {
|
func (td *TermboxDriver) Sync() {
|
||||||
termbox.Sync()
|
termbox.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for an event
|
// Wait for an event
|
||||||
|
|
@ -44,8 +44,76 @@ func (td *TermboxDriver) WaitForEvent() Event {
|
||||||
case termbox.EventResize:
|
case termbox.EventResize:
|
||||||
return Event{EventResize, 0}
|
return Event{EventResize, 0}
|
||||||
case termbox.EventKey:
|
case termbox.EventKey:
|
||||||
return Event{EventKeyPress, 0}
|
if tev.Ch != 0 {
|
||||||
|
return Event{EventKeyPress, tev.Ch}
|
||||||
|
} else if spec, hasSpec := termboxKeysToSpecialKeys[tev.Key] ; hasSpec {
|
||||||
|
return Event{EventKeyPress, spec}
|
||||||
|
} else {
|
||||||
|
return Event{EventNone, 0}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return Event{EventNone, 0}
|
return Event{EventNone, 0}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Map from termbox Keys to driver key runes
|
||||||
|
var termboxKeysToSpecialKeys = map[termbox.Key]rune {
|
||||||
|
termbox.KeyF1: KeyF1,
|
||||||
|
termbox.KeyF2: KeyF2,
|
||||||
|
termbox.KeyF3: KeyF3,
|
||||||
|
termbox.KeyF4: KeyF4,
|
||||||
|
termbox.KeyF5: KeyF5,
|
||||||
|
termbox.KeyF6: KeyF6,
|
||||||
|
termbox.KeyF7: KeyF7,
|
||||||
|
termbox.KeyF8: KeyF8,
|
||||||
|
termbox.KeyF9: KeyF9,
|
||||||
|
termbox.KeyF10: KeyF10,
|
||||||
|
termbox.KeyF11: KeyF11,
|
||||||
|
termbox.KeyF12: KeyF12,
|
||||||
|
termbox.KeyInsert: KeyInsert,
|
||||||
|
termbox.KeyDelete: KeyDelete,
|
||||||
|
termbox.KeyHome: KeyHome,
|
||||||
|
termbox.KeyEnd: KeyEnd,
|
||||||
|
termbox.KeyPgup: KeyPgup,
|
||||||
|
termbox.KeyPgdn: KeyPgdn,
|
||||||
|
termbox.KeyArrowUp: KeyArrowUp,
|
||||||
|
termbox.KeyArrowDown: KeyArrowDown,
|
||||||
|
termbox.KeyArrowLeft: KeyArrowLeft,
|
||||||
|
termbox.KeyArrowRight: KeyArrowRight,
|
||||||
|
|
||||||
|
termbox.KeyCtrlSpace: KeyCtrlSpace,
|
||||||
|
termbox.KeyCtrlA: KeyCtrlA,
|
||||||
|
termbox.KeyCtrlB: KeyCtrlB,
|
||||||
|
termbox.KeyCtrlC: KeyCtrlC,
|
||||||
|
termbox.KeyCtrlD: KeyCtrlD,
|
||||||
|
termbox.KeyCtrlE: KeyCtrlE,
|
||||||
|
termbox.KeyCtrlF: KeyCtrlF,
|
||||||
|
termbox.KeyCtrlG: KeyCtrlG,
|
||||||
|
termbox.KeyCtrlH: KeyCtrlH,
|
||||||
|
termbox.KeyCtrlI: KeyCtrlI,
|
||||||
|
termbox.KeyCtrlJ: KeyCtrlJ,
|
||||||
|
termbox.KeyCtrlK: KeyCtrlK,
|
||||||
|
termbox.KeyCtrlL: KeyCtrlL,
|
||||||
|
termbox.KeyCtrlM: KeyCtrlM,
|
||||||
|
termbox.KeyCtrlN: KeyCtrlN,
|
||||||
|
termbox.KeyCtrlO: KeyCtrlO,
|
||||||
|
termbox.KeyCtrlP: KeyCtrlP,
|
||||||
|
termbox.KeyCtrlQ: KeyCtrlQ,
|
||||||
|
termbox.KeyCtrlR: KeyCtrlR,
|
||||||
|
termbox.KeyCtrlS: KeyCtrlS,
|
||||||
|
termbox.KeyCtrlT: KeyCtrlT,
|
||||||
|
termbox.KeyCtrlU: KeyCtrlU,
|
||||||
|
termbox.KeyCtrlV: KeyCtrlV,
|
||||||
|
termbox.KeyCtrlW: KeyCtrlW,
|
||||||
|
termbox.KeyCtrlX: KeyCtrlX,
|
||||||
|
termbox.KeyCtrlY: KeyCtrlY,
|
||||||
|
termbox.KeyCtrlZ: KeyCtrlZ,
|
||||||
|
termbox.KeyCtrl3: KeyCtrl3,
|
||||||
|
termbox.KeyCtrl4: KeyCtrl4,
|
||||||
|
termbox.KeyCtrl5: KeyCtrl5,
|
||||||
|
termbox.KeyCtrl6: KeyCtrl6,
|
||||||
|
termbox.KeyCtrl7: KeyCtrl7,
|
||||||
|
termbox.KeySpace: KeySpace,
|
||||||
|
termbox.KeyCtrl8: KeyCtrl8,
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue