Added a key event listener which components can implement, and have also mapped termio keys into local keys.

This commit is contained in:
lmika 2015-01-03 23:09:35 +11:00
parent 4a831f7730
commit 6227b76b86
7 changed files with 167 additions and 7 deletions

View file

@ -22,6 +22,7 @@ func main() {
clientArea := &ui.RelativeLayout{ Client: grid, South: statusLayout }
uiManager.SetRootComponent(clientArea)
uiManager.SetFocusedComponent(grid)
uiManager.Loop()
/*

View file

@ -20,6 +20,13 @@ type UiComponent interface {
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.

View file

@ -25,6 +25,68 @@ const (
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
type EventType int
@ -34,14 +96,14 @@ const (
// Event when the window is resized
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
)
// Data from an event callback.
type Event struct {
Type EventType
Par int
Ch rune
}

View file

@ -323,6 +323,20 @@ func (grid *Grid) Redraw(ctx *DrawContext) {
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

View file

@ -11,6 +11,7 @@ type Ui struct {
// The root component
rootComponent UiComponent
focusedComponent FocusableComponent
drawContext *DrawContext
driver Driver
@ -61,6 +62,11 @@ func (ui *Ui) SetRootComponent(comp UiComponent) {
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
@ -104,7 +110,9 @@ func (ui *Ui) Loop() {
// TODO: If the event is a key-press, do something.
if event.Type == EventKeyPress {
return
if ui.focusedComponent != nil {
ui.focusedComponent.KeyPressed(event.Ch)
}
} else if event.Type == EventResize {
// HACK: Find another way to refresh the size of the screen to prevent a full redraw.

View file

@ -38,4 +38,4 @@ func (sbar *StatusBar) Redraw(context *DrawContext) {
termbox.SetCell(x1, y, runeToPrint, termbox.AttrReverse, termbox.AttrReverse)
}
*/
}
}

View file

@ -33,7 +33,7 @@ func (td *TermboxDriver) SetCell(x, y int, ch rune, fg, bg Attribute) {
// Synchronizes the internal buffer with the real buffer
func (td *TermboxDriver) Sync() {
termbox.Sync()
termbox.Flush()
}
// Wait for an event
@ -44,8 +44,76 @@ func (td *TermboxDriver) WaitForEvent() Event {
case termbox.EventResize:
return Event{EventResize, 0}
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:
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,
}