-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathDoubleClick.asc
More file actions
174 lines (157 loc) · 4.31 KB
/
DoubleClick.asc
File metadata and controls
174 lines (157 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// Size of the mouse button records array
#define TOP_REF_MOUSE_BTN 4
struct DoubleClickImpl
{
int Timeout; // delay between two clicks that lets to count them as one sequence
int MBtn; // a mouse button being sequenced right now
int Taps; // number of sequential clicks
bool DblClick; // the button was just double-clicked
};
DoubleClickImpl DblClk;
// Individual mouse button state record
struct MBtnRecord
{
bool IsDown; // is being held
bool StateJustChanged; // just pushed or released
int StateTimer; // current state time
};
MBtnRecord MBtnRec[TOP_REF_MOUSE_BTN];
//===========================================================================
//
// DoubleClick::Timeout property
//
//===========================================================================
int get_Timeout(this DoubleClick*)
{
return DblClk.Timeout;
}
void set_Timeout(this DoubleClick*, int value)
{
if (value < 0) value = 0;
DblClk.Timeout = value;
}
//===========================================================================
//
// DoubleClick::Event[] property
//
//===========================================================================
bool geti_Event(this DoubleClick*, MouseButton mb)
{
if (mb < 0 || mb >= TOP_REF_MOUSE_BTN)
return false;
return DblClk.MBtn == mb && DblClk.DblClick;
}
//===========================================================================
//
// DoubleClick::ClaimThisEvent()
//
//===========================================================================
static void DoubleClick::ClaimThisEvent()
{
DblClk.DblClick = false;
}
//===========================================================================
//
// DoubleClick::Reset()
//
//===========================================================================
static void DoubleClick::Reset()
{
DblClk.MBtn = 0;
DblClk.Taps = 0;
DblClk.DblClick = false;
MouseButton mb = eMouseLeft;
while (mb < TOP_REF_MOUSE_BTN)
{
MBtnRec[mb].IsDown = false;
MBtnRec[mb].StateJustChanged = false;
MBtnRec[mb].StateTimer = 0;
mb++;
}
}
//===========================================================================
//
// game_start()
// Initializing DoubleClick.
//
//===========================================================================
function game_start()
{
DblClk.Timeout = DOUBLECLICK_DEFAULT_TIMEOUT;
DoubleClick.Reset();
}
//===========================================================================
//
// repeatedly_execute_always()
// The listening routine.
//
//===========================================================================
function repeatedly_execute_always()
{
// find real milliseconds per tick
int tick_ms = 1000 / GetGameSpeed();
if (tick_ms == 0)
tick_ms = 1; // very unlikely, but who knows...
// Iterate through all the mouse buttons and update their state.
MouseButton mb = eMouseLeft;
while (mb < TOP_REF_MOUSE_BTN)
{
// new up/down state
bool mb_was_down = MBtnRec[mb].IsDown;
// last up/down state
bool mb_down = Mouse.IsButtonDown(mb);
// Clear signal key data, which is kept for a single tick only
if (MBtnRec[mb].StateJustChanged)
{
if (DblClk.MBtn == mb)
DblClk.DblClick = false;
MBtnRec[mb].StateTimer = 0;
MBtnRec[mb].StateJustChanged = false;
}
// Button state is the same
if (mb_was_down == mb_down)
{
// update state timer
MBtnRec[mb].StateTimer += tick_ms;
if (!mb_down)
{ // button is still up
if (MBtnRec[mb].StateTimer > DblClk.Timeout)
{
// too much time passed since last click
if (DblClk.MBtn == mb)
{
// reset tap sequence
DblClk.MBtn = 0;
DblClk.Taps = 0;
}
}
}
}
// Button state changed
else
{
MBtnRec[mb].StateJustChanged = true;
if (mb_down)
{ // button is now down
MBtnRec[mb].IsDown = true;
// update sequencing
if (DblClk.MBtn != mb)
{
DblClk.MBtn = mb;
DblClk.Taps = 1;
}
else
{
DblClk.Taps++;
if (DblClk.Taps == 2)
DblClk.DblClick = true;
}
}
else
{ // button is now up
MBtnRec[mb].IsDown = false;
}
}
mb++;
}
}