Applied #15375 to stop event-sending in generic wxSpinCtrl ctor (eco)
[wxWidgets.git] / src / osx / uiaction_osx.cpp
CommitLineData
a02a5cfc
KO
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/osx/uiaction_osx.cpp
3// Purpose: wxUIActionSimulator implementation
571d991b 4// Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
a02a5cfc
KO
5// Modified by:
6// Created: 2010-03-06
a02a5cfc 7// Copyright: (c) Kevin Ollivier
571d991b
VZ
8// (c) 2010 Steven Lamerton
9// (c) 2010 Vadim Zeitlin
a02a5cfc
KO
10// Licence: wxWindows licence
11/////////////////////////////////////////////////////////////////////////////
12
d6eb3ff8
SC
13#include "wx/wxprec.h"
14
15#ifndef WX_PRECOMP
16#include "wx/object.h"
17#endif
9b7e0226
VZ
18
19#if wxUSE_UIACTIONSIMULATOR
20
21#include "wx/uiaction.h"
a02a5cfc 22
571d991b
VZ
23#include "wx/log.h"
24
25#include "wx/osx/private.h"
26#include "wx/osx/core/cfref.h"
27
cd0f218c
SC
28#include "wx/evtloop.h"
29
571d991b
VZ
30namespace
31{
eeb7bdd0 32
a02a5cfc
KO
33CGEventTapLocation tap = kCGSessionEventTap;
34
35CGEventType CGEventTypeForMouseButton(int button, bool isDown)
36{
571d991b 37 switch ( button )
a02a5cfc
KO
38 {
39 case wxMOUSE_BTN_LEFT:
571d991b 40 return isDown ? kCGEventLeftMouseDown : kCGEventLeftMouseUp;
9b7e0226 41
571d991b
VZ
42 case wxMOUSE_BTN_RIGHT:
43 return isDown ? kCGEventRightMouseDown : kCGEventRightMouseUp;
9b7e0226 44
571d991b
VZ
45 // All the other buttons use the constant OtherMouseDown but we still
46 // want to check for invalid parameters so assert first
a02a5cfc 47 default:
571d991b
VZ
48 wxFAIL_MSG("Unsupported button passed in.");
49 // fall back to the only known remaining case
50
51 case wxMOUSE_BTN_MIDDLE:
52 return isDown ? kCGEventOtherMouseDown : kCGEventOtherMouseUp;
a02a5cfc
KO
53 }
54}
5ed9f8b2
SC
55
56CGEventType CGEventTypeForMouseDrag(int button)
57{
58 switch ( button )
59 {
60 case wxMOUSE_BTN_LEFT:
61 return kCGEventLeftMouseDragged;
62 break;
63
64 case wxMOUSE_BTN_RIGHT:
65 return kCGEventRightMouseDragged;
66 break;
67
68 // All the other buttons use the constant OtherMouseDown but we still
69 // want to check for invalid parameters so assert first
70 default:
71 wxFAIL_MSG("Unsupported button passed in.");
72 // fall back to the only known remaining case
73
74 case wxMOUSE_BTN_MIDDLE:
75 return kCGEventOtherMouseDragged;
76 break;
77 }
78
79}
a02a5cfc 80
5ed9f8b2
SC
81CGMouseButton CGButtonForMouseButton(int button)
82{
83 switch ( button )
84 {
85 case wxMOUSE_BTN_LEFT:
86 return kCGMouseButtonLeft;
87
88 case wxMOUSE_BTN_RIGHT:
89 return kCGMouseButtonRight;
90
91 // All the other buttons use the constant OtherMouseDown but we still
92 // want to check for invalid parameters so assert first
93 default:
94 wxFAIL_MSG("Unsupported button passed in.");
95 // fall back to the only known remaining case
96
97 case wxMOUSE_BTN_MIDDLE:
98 return kCGMouseButtonCenter;
99 }
100}
101
571d991b 102CGPoint GetMousePosition()
a02a5cfc 103{
571d991b
VZ
104 int x, y;
105 wxGetMousePosition(&x, &y);
106
107 CGPoint pos;
108 pos.x = x;
109 pos.y = y;
110
111 return pos;
112}
113
571d991b
VZ
114} // anonymous namespace
115
a02a5cfc
KO
116bool wxUIActionSimulator::MouseDown(int button)
117{
a02a5cfc 118 CGEventType type = CGEventTypeForMouseButton(button, true);
571d991b 119 wxCFRef<CGEventRef> event(
5ed9f8b2
SC
120 CGEventCreateMouseEvent(NULL, type, GetMousePosition(), CGButtonForMouseButton(button)));
121
122 if ( !event )
123 return false;
124
125 CGEventSetType(event, type);
126 CGEventPost(tap, event);
127 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
128 if (loop)
129 loop->SetShouldWaitForEvent(true);
130
131 return true;
132}
133
134bool wxUIActionSimulator::MouseMove(long x, long y)
135{
136 CGPoint pos;
137 pos.x = x;
138 pos.y = y;
139
140 CGEventType type = kCGEventMouseMoved;
141 wxCFRef<CGEventRef> event(
142 CGEventCreateMouseEvent(NULL, type, pos, kCGMouseButtonLeft));
143
144 if ( !event )
145 return false;
146
147 CGEventSetType(event, type);
148 CGEventPost(tap, event);
149
150 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
151 if (loop)
152 loop->SetShouldWaitForEvent(true);
153
154 return true;
155}
156
157bool wxUIActionSimulator::MouseUp(int button)
158{
159 CGEventType type = CGEventTypeForMouseButton(button, false);
160 wxCFRef<CGEventRef> event(
161 CGEventCreateMouseEvent(NULL, type, GetMousePosition(), CGButtonForMouseButton(button)));
571d991b
VZ
162
163 if ( !event )
164 return false;
165
a02a5cfc 166 CGEventSetType(event, type);
571d991b 167 CGEventPost(tap, event);
cd0f218c
SC
168 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
169 if (loop)
170 loop->SetShouldWaitForEvent(true);
171
172 return true;
173}
174
175bool wxUIActionSimulator::MouseDblClick(int button)
176{
177 CGEventType downtype = CGEventTypeForMouseButton(button, true);
178 CGEventType uptype = CGEventTypeForMouseButton(button, false);
179 wxCFRef<CGEventRef> event(
5ed9f8b2 180 CGEventCreateMouseEvent(NULL, downtype, GetMousePosition(), CGButtonForMouseButton(button)));
cd0f218c
SC
181
182 if ( !event )
183 return false;
184
185 CGEventSetType(event,downtype);
186 CGEventPost(tap, event);
5ed9f8b2 187
cd0f218c
SC
188 CGEventSetType(event, uptype);
189 CGEventPost(tap, event);
190
191 CGEventSetIntegerValueField(event, kCGMouseEventClickState, 2);
192 CGEventSetType(event, downtype);
193 CGEventPost(tap, event);
194
195 CGEventSetType(event, uptype);
196 CGEventPost(tap, event);
197 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
198 if (loop)
199 loop->SetShouldWaitForEvent(true);
200
a02a5cfc
KO
201 return true;
202}
203
e5354813
SC
204bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2,
205 int button)
a02a5cfc 206{
e5354813
SC
207 CGPoint pos1,pos2;
208 pos1.x = x1;
209 pos1.y = y1;
210 pos2.x = x2;
211 pos2.y = y2;
212
5ed9f8b2
SC
213 CGEventType downtype = CGEventTypeForMouseButton(button, true);
214 CGEventType uptype = CGEventTypeForMouseButton(button, false);
215 CGEventType dragtype = CGEventTypeForMouseDrag(button) ;
571d991b 216
571d991b 217 wxCFRef<CGEventRef> event(
e5354813 218 CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, pos1, CGButtonForMouseButton(button)));
5ed9f8b2 219
571d991b
VZ
220 if ( !event )
221 return false;
5ed9f8b2 222
e5354813
SC
223 CGEventSetType(event,kCGEventMouseMoved);
224 CGEventPost(tap, event);
225
5ed9f8b2 226 CGEventSetType(event,downtype);
571d991b 227 CGEventPost(tap, event);
cd0f218c 228
5ed9f8b2
SC
229
230 CGEventSetType(event, dragtype);
e5354813 231 CGEventSetLocation(event,pos2);
5ed9f8b2
SC
232 CGEventPost(tap, event);
233
234 CGEventSetType(event, uptype);
571d991b 235 CGEventPost(tap, event);
cd0f218c
SC
236 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
237 if (loop)
238 loop->SetShouldWaitForEvent(true);
239
a02a5cfc
KO
240 return true;
241}
242
03bec791
VZ
243bool
244wxUIActionSimulator::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown)
a02a5cfc 245{
571d991b 246 CGKeyCode cgcode = wxCharCodeWXToOSX((wxKeyCode)keycode);
571d991b 247
37141214
VZ
248 wxCFRef<CGEventRef>
249 event(CGEventCreateKeyboardEvent(NULL, cgcode, isDown));
250 if ( !event )
251 return false;
9b7e0226 252
37141214 253 CGEventPost(kCGHIDEventTap, event);
cd0f218c
SC
254 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
255 if (loop)
256 loop->SetShouldWaitForEvent(true);
257
a02a5cfc
KO
258 return true;
259}
260
9b7e0226 261#endif // wxUSE_UIACTIONSIMULATOR
a02a5cfc 262