Re-added the events files for Area.
This commit is contained in:
parent
f035792c1d
commit
95151ce6ea
|
@ -0,0 +1,132 @@
|
|||
// 30 march 2014
|
||||
|
||||
package ui
|
||||
|
||||
/*
|
||||
Mac OS X uses its own set of hardware key codes that are different from PC keyboard scancodes, but are positional (like PC keyboard scancodes). These are defined in <HIToolbox/Events.h>, a Carbon header. As far as I can tell, there's no way to include this header without either using an absolute path or linking Carbon into the program, so the constant values are used here instead.
|
||||
|
||||
The Cocoa docs do guarantee that -[NSEvent keyCode] results in key codes that are the same as those returned by Carbon; that is, these codes.
|
||||
*/
|
||||
|
||||
// use uintptr to be safe
|
||||
var keycodeKeys = map[uintptr]byte{
|
||||
0x00: 'a',
|
||||
0x01: 's',
|
||||
0x02: 'd',
|
||||
0x03: 'f',
|
||||
0x04: 'h',
|
||||
0x05: 'g',
|
||||
0x06: 'z',
|
||||
0x07: 'x',
|
||||
0x08: 'c',
|
||||
0x09: 'v',
|
||||
0x0B: 'b',
|
||||
0x0C: 'q',
|
||||
0x0D: 'w',
|
||||
0x0E: 'e',
|
||||
0x0F: 'r',
|
||||
0x10: 'y',
|
||||
0x11: 't',
|
||||
0x12: '1',
|
||||
0x13: '2',
|
||||
0x14: '3',
|
||||
0x15: '4',
|
||||
0x16: '6',
|
||||
0x17: '5',
|
||||
0x18: '=',
|
||||
0x19: '9',
|
||||
0x1A: '7',
|
||||
0x1B: '-',
|
||||
0x1C: '8',
|
||||
0x1D: '0',
|
||||
0x1E: ']',
|
||||
0x1F: 'o',
|
||||
0x20: 'u',
|
||||
0x21: '[',
|
||||
0x22: 'i',
|
||||
0x23: 'p',
|
||||
0x25: 'l',
|
||||
0x26: 'j',
|
||||
0x27: '\'',
|
||||
0x28: 'k',
|
||||
0x29: ';',
|
||||
0x2A: '\\',
|
||||
0x2B: ',',
|
||||
0x2C: '/',
|
||||
0x2D: 'n',
|
||||
0x2E: 'm',
|
||||
0x2F: '.',
|
||||
0x32: '`',
|
||||
0x24: '\n',
|
||||
0x30: '\t',
|
||||
0x31: ' ',
|
||||
0x33: '\b',
|
||||
}
|
||||
|
||||
var keycodeExtKeys = map[uintptr]ExtKey{
|
||||
0x41: NDot,
|
||||
0x43: NMultiply,
|
||||
0x45: NAdd,
|
||||
0x4B: NDivide,
|
||||
0x4C: NEnter,
|
||||
0x4E: NSubtract,
|
||||
0x52: N0,
|
||||
0x53: N1,
|
||||
0x54: N2,
|
||||
0x55: N3,
|
||||
0x56: N4,
|
||||
0x57: N5,
|
||||
0x58: N6,
|
||||
0x59: N7,
|
||||
0x5B: N8,
|
||||
0x5C: N9,
|
||||
0x35: Escape,
|
||||
0x60: F5,
|
||||
0x61: F6,
|
||||
0x62: F7,
|
||||
0x63: F3,
|
||||
0x64: F8,
|
||||
0x65: F9,
|
||||
0x67: F11,
|
||||
0x6D: F10,
|
||||
0x6F: F12,
|
||||
0x72: Insert, // listed as the Help key but it's in the same position on an Apple keyboard as the Insert key on a Windows keyboard; thanks to SeanieB from irc.badnik.net and Psy in irc.freenode.net/#macdev for confirming they have the same code
|
||||
0x73: Home,
|
||||
0x74: PageUp,
|
||||
0x75: Delete,
|
||||
0x76: F4,
|
||||
0x77: End,
|
||||
0x78: F2,
|
||||
0x79: PageDown,
|
||||
0x7A: F1,
|
||||
0x7B: Left,
|
||||
0x7C: Right,
|
||||
0x7D: Down,
|
||||
0x7E: Up,
|
||||
}
|
||||
|
||||
var keycodeModifiers = map[uintptr]Modifiers{
|
||||
0x37: Super, // left command
|
||||
0x38: Shift, // left shift
|
||||
0x3A: Alt, // left option
|
||||
0x3B: Ctrl, // left control
|
||||
0x3C: Shift, // right shift
|
||||
0x3D: Alt, // right alt
|
||||
0x3E: Ctrl, // right control
|
||||
|
||||
// the following is not in Events.h for some reason
|
||||
// thanks to Nicole and jedivulcan from irc.badnik.net
|
||||
0x36: Super, // right command
|
||||
}
|
||||
|
||||
func fromKeycode(keycode uintptr) (ke KeyEvent, ok bool) {
|
||||
if key, ok := keycodeKeys[keycode]; ok {
|
||||
ke.Key = key
|
||||
return ke, true
|
||||
}
|
||||
if extkey, ok := keycodeExtKeys[keycode]; ok {
|
||||
ke.ExtKey = extkey
|
||||
return ke, true
|
||||
}
|
||||
return ke, false
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
// +build !darwin
|
||||
// Mac OS X uses its own set of position-independent key codes
|
||||
|
||||
// 29 march 2014
|
||||
|
||||
package ui
|
||||
|
||||
import (
|
||||
"image"
|
||||
)
|
||||
|
||||
/*
|
||||
Windows and GTK+ have a limit of 2 and 3 clicks, respectively, natively supported. Fortunately, we can simulate the double/triple-click behavior to build higher-order clicks. We can use the same algorithm Windows uses on both:
|
||||
http://blogs.msdn.com/b/oldnewthing/archive/2004/10/18/243925.aspx
|
||||
For GTK+, we pull the double-click time and double-click distance, which work the same as the equivalents on Windows (so the distance is in all directions), from the GtkSettings system.
|
||||
|
||||
On GTK+ this will also allow us to discard the GDK_BUTTON_2PRESS and GDK_BUTTON_3PRESS events, so the button press stream will be just like on other platforms.
|
||||
|
||||
Thanks to mclasen, garnacho_, halfline, and tristan in irc.gimp.net/#gtk+.
|
||||
|
||||
TODO - technically a GDK_BUTTON_3PRESS is detected in half the time as a GDK_BUTTON_2PRESS... handle?
|
||||
*/
|
||||
|
||||
// the zero value is a reset clickCounter ready for use
|
||||
// it doesn't matter that all the non-count fields are zero: the first click will fail the curButton test straightaway, so it'll return 1 and set the rest of the structure accordingly
|
||||
type clickCounter struct {
|
||||
curButton uint
|
||||
rect image.Rectangle
|
||||
prevTime uintptr
|
||||
count uint
|
||||
}
|
||||
|
||||
// x, y, xdist, ydist, and c.rect must have the same units
|
||||
// so must time, maxTime, and c.prevTime
|
||||
func (c *clickCounter) click(button uint, x int, y int, time uintptr, maxTime uintptr, xdist int, ydist int) uint {
|
||||
if button != c.curButton { // different button; start over
|
||||
c.count = 0
|
||||
}
|
||||
if !image.Pt(x, y).In(c.rect) { // not in the allowed region for a double-click; don't count
|
||||
c.count = 0
|
||||
}
|
||||
if (time - c.prevTime) > maxTime { // too slow; don't count
|
||||
// note the above expression; time > (c.prevTime + maxTime) can overflow!
|
||||
c.count = 0
|
||||
}
|
||||
c.count++ // if either of the above ifs happened, this will make the click count 1; otherwise it will make the click count 2, 3, 4, 5, ...
|
||||
|
||||
// now we need to update the internal structures for the next test
|
||||
c.curButton = button
|
||||
c.prevTime = time
|
||||
c.rect = image.Rect(x-xdist, y-ydist,
|
||||
x+xdist, y+ydist)
|
||||
|
||||
return c.count
|
||||
}
|
||||
|
||||
// call this when losing focus, etc.
|
||||
func (c *clickCounter) reset() {
|
||||
c.count = 0
|
||||
}
|
||||
|
||||
/*
|
||||
For position independence across international keyboard layouts, typewriter keys are read using scancodes (which are always set 1).
|
||||
Windows provides the scancodes directly in the LPARAM.
|
||||
GTK+ provides the scancodes directly from the underlying window system via GdkEventKey.hardware_keycode.
|
||||
On X11, this is scancode + 8 (because X11 keyboard codes have a range of [8,255]).
|
||||
Wayland is guaranteed to give the same result (thanks ebassi in irc.gimp.net/#gtk+).
|
||||
On Linux, where evdev is used instead of polling scancodes directly from the keyboard, evdev's typewriter section key code constants are the same as scancodes anyway, so the rules above apply.
|
||||
Typewriter section scancodes are the same across international keyboards with some exceptions that have been accounted for (see KeyEvent's documentation); see http://www.quadibloc.com/comp/scan.htm for details.
|
||||
Non-typewriter keys can be handled safely using constants provided by the respective backend API.
|
||||
|
||||
Because GTK+ keysyms may or may not obey Num Lock, we also handle the 0-9 and . keys on the numeric keypad with scancodes (they match too).
|
||||
*/
|
||||
|
||||
// use uintptr to be safe; the size of the scancode/hardware key code field on each platform is different
|
||||
var scancodeKeys = map[uintptr]byte{
|
||||
0x02: '1',
|
||||
0x03: '2',
|
||||
0x04: '3',
|
||||
0x05: '4',
|
||||
0x06: '5',
|
||||
0x07: '6',
|
||||
0x08: '7',
|
||||
0x09: '8',
|
||||
0x0A: '9',
|
||||
0x0B: '0',
|
||||
0x0C: '-',
|
||||
0x0D: '=',
|
||||
0x0E: '\b', // seems to be safe on GTK+; TODO safe on windows?
|
||||
0x0F: '\t', // seems to be safe on GTK+; TODO safe on windows?
|
||||
0x10: 'q',
|
||||
0x11: 'w',
|
||||
0x12: 'e',
|
||||
0x13: 'r',
|
||||
0x14: 't',
|
||||
0x15: 'y',
|
||||
0x16: 'u',
|
||||
0x17: 'i',
|
||||
0x18: 'o',
|
||||
0x19: 'p',
|
||||
0x1A: '[',
|
||||
0x1B: ']',
|
||||
0x1C: '\n', // seems to be safe on GTK+; TODO safe on windows?
|
||||
0x1E: 'a',
|
||||
0x1F: 's',
|
||||
0x20: 'd',
|
||||
0x21: 'f',
|
||||
0x22: 'g',
|
||||
0x23: 'h',
|
||||
0x24: 'j',
|
||||
0x25: 'k',
|
||||
0x26: 'l',
|
||||
0x27: ';',
|
||||
0x28: '\'',
|
||||
0x29: '`',
|
||||
0x2B: '\\',
|
||||
0x2C: 'z',
|
||||
0x2D: 'x',
|
||||
0x2E: 'c',
|
||||
0x2F: 'v',
|
||||
0x30: 'b',
|
||||
0x31: 'n',
|
||||
0x32: 'm',
|
||||
0x33: ',',
|
||||
0x34: '.',
|
||||
0x35: '/',
|
||||
0x39: ' ',
|
||||
}
|
||||
|
||||
var scancodeExtKeys = map[uintptr]ExtKey{
|
||||
0x47: N7,
|
||||
0x48: N8,
|
||||
0x49: N9,
|
||||
0x4B: N4,
|
||||
0x4C: N5,
|
||||
0x4D: N6,
|
||||
0x4F: N1,
|
||||
0x50: N2,
|
||||
0x51: N3,
|
||||
0x52: N0,
|
||||
0x53: NDot,
|
||||
}
|
||||
|
||||
func fromScancode(scancode uintptr) (ke KeyEvent, ok bool) {
|
||||
if key, ok := scancodeKeys[scancode]; ok {
|
||||
ke.Key = key
|
||||
return ke, true
|
||||
}
|
||||
if extkey, ok := scancodeExtKeys[scancode]; ok {
|
||||
ke.ExtKey = extkey
|
||||
return ke, true
|
||||
}
|
||||
return ke, false
|
||||
}
|
Loading…
Reference in New Issue