From a5a3287696a3c99faa9115c5864787157f266ed0 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sat, 15 Mar 2014 21:36:10 -0400 Subject: [PATCH] Added portable code for Area's MouseEvent. --- area.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ sysdata.go | 1 + 2 files changed, 54 insertions(+) diff --git a/area.go b/area.go index f948ade..2b5c82a 100644 --- a/area.go +++ b/area.go @@ -17,6 +17,10 @@ type Area struct { // See the documentation of PaintRequest for details. Paint chan PaintRequest + // Mouse is signaled when the Area receives a mouse event. + // See MouseEvent for details. + Mouse chan MouseEvent + lock sync.Mutex created bool sysData *sysData @@ -44,11 +48,59 @@ type PaintRequest struct { Out chan<- *image.NRGBA } +// MouseEvent contains all the information for a mous event sent by Area.Mouse. +// Mouse button IDs start at 1, with 1 being the left mouse button, 2 being the middle mouse button, and 3 being the right mouse button. +// (TODO "If additional buttons are supported, they will be returned with 4 being the first additional button (XBUTTON1 on Windows), 5 being the second (XBUTTON2 on Windows), and so on."?) (TODO get the user-facing name for XBUTTON1/2; find out if there's a way to query available button count) +type MouseEvent struct { + // Pos is the position of the mouse in the Area at the time of the event. + Pos image.Point + + // If the event was generated by a mouse button being pressed, Down contains the ID of that button. + // Otherwise, Down contains 0. + Down uint + + // If the event was generated by a mouse button being released, Up contains the ID of that button. + // Otherwise, Up contains 0. + Up uint + + // If Down is nonzero, Count indicates the number of clicks: 1 for single-click, 2 for double-click. + // If Count == 2, AT LEAST one event with Count == 1 will have been sent prior. + // (This is a platform-specific issue: some platforms send one, some send two.) + Count uint + + // Modifiers is a bit mask indicating the modifier keys being held during the event. + Modifiers Modifiers + + // Held is a slice of button IDs that indicate which mouse buttons are being held during the event. + // (TODO "There is no guarantee that Held is sorted."?) + // (TODO will this include or exclude Down and Up?) + Held []uint +} + +// HeldBits returns Held as a bit mask. +// Bit 0 maps to button 1, bit 1 maps to button 2, etc. +func (e MouseEvent) HeldBits() (h uintptr) { + for _, x := range e.Held { + h |= uintptr(1) << (x - 1) + } + return h +} + +// Modifiers indicates modifier keys being held during a mouse event. +// There is no way to differentiate between left and right modifier keys. +type Modifiers uintptr +const ( + Ctrl Modifiers = 1 << iota // the canonical Ctrl keys ([TODO] on Mac OS X, Control on others) + Alt // the canonical Alt keys ([TODO] on Mac OS X, Meta on Unix systems, Alt on others) + Shift // the Shift keys +) + // NewArea creates a new Area. func NewArea() *Area { return &Area{ sysData: mksysdata(c_area), Paint: make(chan PaintRequest), + Mouse: make(chan MouseEvent), } } @@ -57,6 +109,7 @@ func (a *Area) make(window *sysData) error { defer a.lock.Unlock() a.sysData.paint = a.Paint + a.sysData.mouse = a.Mouse err := a.sysData.make("", window) if err != nil { return err diff --git a/sysdata.go b/sysdata.go index 93f521c..8d44f7f 100644 --- a/sysdata.go +++ b/sysdata.go @@ -22,6 +22,7 @@ type cSysData struct { // for Area paint chan PaintRequest + mouse chan MouseEvent } func (c *cSysData) make(initText string, window *sysData) error { panic(runtime.GOOS + " sysData does not define make()")