1// Copyright 2020 The TCell Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use file except in compliance with the License.
5// You may obtain a copy of the license at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package tcell
16
17import (
18	"time"
19)
20
21// EventMouse is a mouse event.  It is sent on either mouse up or mouse down
22// events.  It is also sent on mouse motion events - if the terminal supports
23// it.  We make every effort to ensure that mouse release events are delivered.
24// Hence, click drag can be identified by a motion event with the mouse down,
25// without any intervening button release.  On some terminals only the initiating
26// press and terminating release event will be delivered.
27//
28// Mouse wheel events, when reported, may appear on their own as individual
29// impulses; that is, there will normally not be a release event delivered
30// for mouse wheel movements.
31//
32// Most terminals cannot report the state of more than one button at a time --
33// and some cannot report motion events unless a button is pressed.
34//
35// Applications can inspect the time between events to resolve double or
36// triple clicks.
37type EventMouse struct {
38	t   time.Time
39	btn ButtonMask
40	mod ModMask
41	x   int
42	y   int
43}
44
45// When returns the time when this EventMouse was created.
46func (ev *EventMouse) When() time.Time {
47	return ev.t
48}
49
50// Buttons returns the list of buttons that were pressed or wheel motions.
51func (ev *EventMouse) Buttons() ButtonMask {
52	return ev.btn
53}
54
55// Modifiers returns a list of keyboard modifiers that were pressed
56// with the mouse button(s).
57func (ev *EventMouse) Modifiers() ModMask {
58	return ev.mod
59}
60
61// Position returns the mouse position in character cells.  The origin
62// 0, 0 is at the upper left corner.
63func (ev *EventMouse) Position() (int, int) {
64	return ev.x, ev.y
65}
66
67// NewEventMouse is used to create a new mouse event.  Applications
68// shouldn't need to use this; its mostly for screen implementors.
69func NewEventMouse(x, y int, btn ButtonMask, mod ModMask) *EventMouse {
70	return &EventMouse{t: time.Now(), x: x, y: y, btn: btn, mod: mod}
71}
72
73// ButtonMask is a mask of mouse buttons and wheel events.  Mouse button presses
74// are normally delivered as both press and release events.  Mouse wheel events
75// are normally just single impulse events.  Windows supports up to eight
76// separate buttons plus all four wheel directions, but XTerm can only support
77// mouse buttons 1-3 and wheel up/down.  Its not unheard of for terminals
78// to support only one or two buttons (think Macs).  Old terminals, and true
79// emulations (such as vt100) won't support mice at all, of course.
80type ButtonMask int16
81
82// These are the actual button values.  Note that tcell version 1.x reversed buttons
83// two and three on *nix based terminals.  We use button 1 as the primary, and
84// button 2 as the secondary, and button 3 (which is often missing) as the middle.
85const (
86	Button1 ButtonMask = 1 << iota // Usually the left (primary) mouse button.
87	Button2                        // Usually the right (secondary) mouse button.
88	Button3                        // Usually the middle mouse button.
89	Button4                        // Often a side button (thumb/next).
90	Button5                        // Often a side button (thumb/prev).
91	Button6
92	Button7
93	Button8
94	WheelUp                   // Wheel motion up/away from user.
95	WheelDown                 // Wheel motion down/towards user.
96	WheelLeft                 // Wheel motion to left.
97	WheelRight                // Wheel motion to right.
98	ButtonNone ButtonMask = 0 // No button or wheel events.
99
100	ButtonPrimary   = Button1
101	ButtonSecondary = Button2
102	ButtonMiddle    = Button3
103)
104