things
This commit is contained in:
parent
c193c25b15
commit
a0fd8a694b
23
box.go
23
box.go
@ -261,6 +261,9 @@ func (this *box) doLayout () {
|
||||
}
|
||||
|
||||
func (this *box) setParent (parent parent) {
|
||||
if this.parent != parent && this.Focused() {
|
||||
this.SetFocused(false)
|
||||
}
|
||||
this.parent = parent
|
||||
}
|
||||
|
||||
@ -316,3 +319,23 @@ func (this *box) handleMouseUp (button input.Button) {
|
||||
listener(button)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *box) handleKeyDown (key input.Key, numberPad bool) {
|
||||
for _, listener := range this.on.keyDown.Listeners() {
|
||||
listener(key, numberPad)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *box) handleKeyUp (key input.Key, numberPad bool) {
|
||||
for _, listener := range this.on.keyUp.Listeners() {
|
||||
listener(key, numberPad)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *box) propagate (callback func (anyBox) bool) bool {
|
||||
return callback(this)
|
||||
}
|
||||
|
||||
func (this *box) propagateAlt (callback func (anyBox) bool) bool {
|
||||
return callback(this)
|
||||
}
|
||||
|
@ -227,3 +227,23 @@ func (this *containerBox) boxUnder (point image.Point) anyBox {
|
||||
|
||||
return this.box.boxUnder(point)
|
||||
}
|
||||
|
||||
func (this *containerBox) propagate (callback func (anyBox) bool) bool {
|
||||
for _, box := range this.children {
|
||||
box := box.(anyBox)
|
||||
if !box.propagate(callback) { return false }
|
||||
}
|
||||
|
||||
return callback(this)
|
||||
}
|
||||
|
||||
func (this *containerBox) propagateAlt (callback func (anyBox) bool) bool {
|
||||
if !callback(this) { return false}
|
||||
|
||||
for _, box := range this.children {
|
||||
box := box.(anyBox)
|
||||
if !box.propagateAlt(callback) { return false }
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
170
event.go
170
event.go
@ -8,6 +8,102 @@ import "git.tebibyte.media/tomo/xgbkb"
|
||||
import "github.com/jezek/xgbutil/xevent"
|
||||
import "git.tebibyte.media/tomo/tomo/input"
|
||||
|
||||
var buttonCodeTable = map[xproto.Keysym] input.Key {
|
||||
0xFFFFFF: input.KeyNone,
|
||||
|
||||
0xFF63: input.KeyInsert,
|
||||
0xFF67: input.KeyMenu,
|
||||
0xFF61: input.KeyPrintScreen,
|
||||
0xFF6B: input.KeyPause,
|
||||
0xFFE5: input.KeyCapsLock,
|
||||
0xFF14: input.KeyScrollLock,
|
||||
0xFF7F: input.KeyNumLock,
|
||||
0xFF08: input.KeyBackspace,
|
||||
0xFF09: input.KeyTab,
|
||||
0xFE20: input.KeyTab,
|
||||
0xFF0D: input.KeyEnter,
|
||||
0xFF1B: input.KeyEscape,
|
||||
|
||||
0xFF52: input.KeyUp,
|
||||
0xFF54: input.KeyDown,
|
||||
0xFF51: input.KeyLeft,
|
||||
0xFF53: input.KeyRight,
|
||||
0xFF55: input.KeyPageUp,
|
||||
0xFF56: input.KeyPageDown,
|
||||
0xFF50: input.KeyHome,
|
||||
0xFF57: input.KeyEnd,
|
||||
|
||||
0xFFE1: input.KeyLeftShift,
|
||||
0xFFE2: input.KeyRightShift,
|
||||
0xFFE3: input.KeyLeftControl,
|
||||
0xFFE4: input.KeyRightControl,
|
||||
|
||||
0xFFE7: input.KeyLeftMeta,
|
||||
0xFFE8: input.KeyRightMeta,
|
||||
0xFFE9: input.KeyLeftAlt,
|
||||
0xFFEA: input.KeyRightAlt,
|
||||
0xFFEB: input.KeyLeftSuper,
|
||||
0xFFEC: input.KeyRightSuper,
|
||||
0xFFED: input.KeyLeftHyper,
|
||||
0xFFEE: input.KeyRightHyper,
|
||||
|
||||
0xFFFF: input.KeyDelete,
|
||||
|
||||
0xFFBE: input.KeyF1,
|
||||
0xFFBF: input.KeyF2,
|
||||
0xFFC0: input.KeyF3,
|
||||
0xFFC1: input.KeyF4,
|
||||
0xFFC2: input.KeyF5,
|
||||
0xFFC3: input.KeyF6,
|
||||
0xFFC4: input.KeyF7,
|
||||
0xFFC5: input.KeyF8,
|
||||
0xFFC6: input.KeyF9,
|
||||
0xFFC7: input.KeyF10,
|
||||
0xFFC8: input.KeyF11,
|
||||
0xFFC9: input.KeyF12,
|
||||
|
||||
0xFF20: input.KeyDead,
|
||||
}
|
||||
|
||||
var keypadCodeTable = map[xproto.Keysym] input.Key {
|
||||
0xff80: input.Key(' '),
|
||||
0xff89: input.KeyTab,
|
||||
0xff8d: input.KeyEnter,
|
||||
0xff91: input.KeyF1,
|
||||
0xff92: input.KeyF2,
|
||||
0xff93: input.KeyF3,
|
||||
0xff94: input.KeyF4,
|
||||
0xff95: input.KeyHome,
|
||||
0xff96: input.KeyLeft,
|
||||
0xff97: input.KeyUp,
|
||||
0xff98: input.KeyRight,
|
||||
0xff99: input.KeyDown,
|
||||
0xff9a: input.KeyPageUp,
|
||||
0xff9b: input.KeyPageDown,
|
||||
0xff9c: input.KeyEnd,
|
||||
0xff9d: input.KeyHome,
|
||||
0xff9e: input.KeyInsert,
|
||||
0xff9f: input.KeyDelete,
|
||||
0xffbd: input.Key('='),
|
||||
0xffaa: input.Key('*'),
|
||||
0xffab: input.Key('+'),
|
||||
0xffac: input.Key(','),
|
||||
0xffad: input.Key('-'),
|
||||
0xffae: input.Key('.'),
|
||||
0xffaf: input.Key('/'),
|
||||
|
||||
0xffb0: input.Key('0'),
|
||||
0xffb1: input.Key('1'),
|
||||
0xffb2: input.Key('2'),
|
||||
0xffb3: input.Key('3'),
|
||||
0xffb4: input.Key('4'),
|
||||
0xffb5: input.Key('5'),
|
||||
0xffb6: input.Key('6'),
|
||||
0xffb7: input.Key('7'),
|
||||
0xffb8: input.Key('8'),
|
||||
0xffb9: input.Key('9'),
|
||||
}
|
||||
|
||||
func (window *window) handleExpose (
|
||||
connection *xgbutil.XUtil,
|
||||
event xevent.ExposeEvent,
|
||||
@ -74,6 +170,80 @@ func (window *window) exposeEventFollows (event xproto.ConfigureNotifyEvent) (fo
|
||||
return false
|
||||
}
|
||||
|
||||
func keycodeToKey (keycode xproto.Keycode, state uint16) (input.Key, bool) {
|
||||
keysym, char := xgbkb.KeycodeToKeysym(keycode, state)
|
||||
|
||||
if xgbkb.IsOnNumpad(keysym) {
|
||||
// look up in keypad table
|
||||
key := keypadCodeTable[keysym]
|
||||
return key, true
|
||||
} else {
|
||||
// look up in control code table
|
||||
key, isControl := buttonCodeTable[keysym]
|
||||
if isControl {
|
||||
return key, false
|
||||
} else {
|
||||
// return as rune
|
||||
return input.Key(char), false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (window *window) handleKeyPress (
|
||||
connection *xgbutil.XUtil,
|
||||
event xevent.KeyPressEvent,
|
||||
) {
|
||||
if window.hasModal { return }
|
||||
|
||||
keyEvent := *event.KeyPressEvent
|
||||
key, numberPad := keycodeToKey(keyEvent.Detail, keyEvent.State)
|
||||
window.updateModifiers(keyEvent.State)
|
||||
|
||||
if key == input.KeyTab && window.modifiers.Alt {
|
||||
if window.modifiers.Shift {
|
||||
window.focusPrevious()
|
||||
} else {
|
||||
window.focusNext()
|
||||
}
|
||||
} else if key == input.KeyEscape && window.shy {
|
||||
window.Close()
|
||||
} else if window.focused != nil {
|
||||
window.focused.handleKeyDown(key, numberPad)
|
||||
}
|
||||
}
|
||||
|
||||
func (window *window) handleKeyRelease (
|
||||
connection *xgbutil.XUtil,
|
||||
event xevent.KeyReleaseEvent,
|
||||
) {
|
||||
if window.hasModal { return }
|
||||
|
||||
keyEvent := *event.KeyReleaseEvent
|
||||
|
||||
// do not process this event if it was generated from a key repeat
|
||||
nextEvents := xevent.Peek(window.backend.x)
|
||||
if len(nextEvents) > 0 {
|
||||
untypedEvent := nextEvents[0]
|
||||
if untypedEvent.Err == nil {
|
||||
typedEvent, ok :=
|
||||
untypedEvent.Event.(xproto.KeyPressEvent)
|
||||
|
||||
if ok && typedEvent.Detail == keyEvent.Detail &&
|
||||
typedEvent.Event == keyEvent.Event &&
|
||||
typedEvent.State == keyEvent.State {
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
key, numberPad := keycodeToKey(keyEvent.Detail, keyEvent.State)
|
||||
window.updateModifiers(keyEvent.State)
|
||||
|
||||
if window.focused != nil {
|
||||
window.focused.handleKeyUp(key, numberPad)
|
||||
}
|
||||
}
|
||||
|
||||
func (window *window) handleButtonPress (
|
||||
connection *xgbutil.XUtil,
|
||||
|
60
system.go
60
system.go
@ -48,6 +48,9 @@ type anyBox interface {
|
||||
boxUnder (image.Point) anyBox
|
||||
recalculateMinimumSize ()
|
||||
|
||||
propagate (func (anyBox) bool) bool
|
||||
propagateAlt (func (anyBox) bool) bool
|
||||
|
||||
handleFocusEnter ()
|
||||
handleFocusLeave ()
|
||||
// handleDndEnter ()
|
||||
@ -59,8 +62,8 @@ type anyBox interface {
|
||||
handleMouseDown (input.Button)
|
||||
handleMouseUp (input.Button)
|
||||
// handleScroll (float64, float64)
|
||||
// handleKeyDown (input.Key, bool)
|
||||
// handleKeyUp (input.Key, bool)
|
||||
handleKeyDown (input.Key, bool)
|
||||
handleKeyUp (input.Key, bool)
|
||||
}
|
||||
|
||||
func assertAnyBox (unknown tomo.Box) anyBox {
|
||||
@ -119,17 +122,68 @@ func (window *window) focus (box anyBox) {
|
||||
window.invalidateDraw(previous)
|
||||
previous.handleFocusLeave()
|
||||
}
|
||||
if box != nil {
|
||||
if box != nil && box.canBeFocused() {
|
||||
window.invalidateDraw(box)
|
||||
box.handleFocusEnter()
|
||||
}
|
||||
}
|
||||
|
||||
func (window *window) anyFocused () bool {
|
||||
return window.focused != nil
|
||||
}
|
||||
|
||||
func (this *window) boxUnder (point image.Point) anyBox {
|
||||
if this.root == nil { return nil }
|
||||
return this.root.boxUnder(point)
|
||||
}
|
||||
|
||||
func (this *window) focusNext () {
|
||||
found := !this.anyFocused()
|
||||
focused := false
|
||||
this.propagateAlt (func (box anyBox) bool {
|
||||
if found {
|
||||
// looking for the next box to select
|
||||
if box.canBeFocused() {
|
||||
// found it
|
||||
this.focus(box)
|
||||
focused = true
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
// looking for the current focused element
|
||||
if box == this.focused {
|
||||
// found it
|
||||
found = true
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if !focused { this.focus(nil) }
|
||||
}
|
||||
|
||||
func (this *window) focusPrevious () {
|
||||
var behind anyBox
|
||||
this.propagate (func (box anyBox) bool {
|
||||
if box == this.focused {
|
||||
return false
|
||||
}
|
||||
if box.canBeFocused() { behind = box }
|
||||
return true
|
||||
})
|
||||
this.focus(behind)
|
||||
}
|
||||
|
||||
func (this *window) propagate (callback func (box anyBox) bool) {
|
||||
if this.root == nil { return }
|
||||
this.root.propagate(callback)
|
||||
}
|
||||
|
||||
func (this *window) propagateAlt (callback func (box anyBox) bool) {
|
||||
if this.root == nil { return }
|
||||
this.root.propagateAlt(callback)
|
||||
}
|
||||
|
||||
func (window *window) afterEvent () {
|
||||
if window.xCanvas == nil { return }
|
||||
|
||||
|
@ -109,10 +109,10 @@ func (backend *Backend) newWindow (
|
||||
Connect(backend.x, window.xWindow.Id)
|
||||
xevent.ConfigureNotifyFun(window.handleConfigureNotify).
|
||||
Connect(backend.x, window.xWindow.Id)
|
||||
// xevent.KeyPressFun(window.handleKeyPress).
|
||||
// Connect(backend.x, window.xWindow.Id)
|
||||
// xevent.KeyReleaseFun(window.handleKeyRelease).
|
||||
// Connect(backend.x, window.xWindow.Id)
|
||||
xevent.KeyPressFun(window.handleKeyPress).
|
||||
Connect(backend.x, window.xWindow.Id)
|
||||
xevent.KeyReleaseFun(window.handleKeyRelease).
|
||||
Connect(backend.x, window.xWindow.Id)
|
||||
xevent.ButtonPressFun(window.handleButtonPress).
|
||||
Connect(backend.x, window.xWindow.Id)
|
||||
xevent.ButtonReleaseFun(window.handleButtonRelease).
|
||||
|
Reference in New Issue
Block a user