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