]> git.saurik.com Git - wxWidgets.git/blob - src/osx/uiaction_osx.cpp
Fix for #15224: wxRichTextTable: Setting a cell's text colour affects subsequent...
[wxWidgets.git] / src / osx / uiaction_osx.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/uiaction_osx.cpp
3 // Purpose: wxUIActionSimulator implementation
4 // Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
5 // Modified by:
6 // Created: 2010-03-06
7 // Copyright: (c) Kevin Ollivier
8 // (c) 2010 Steven Lamerton
9 // (c) 2010 Vadim Zeitlin
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 #include "wx/wxprec.h"
14
15 #ifndef WX_PRECOMP
16 #include "wx/object.h"
17 #endif
18
19 #if wxUSE_UIACTIONSIMULATOR
20
21 #include "wx/uiaction.h"
22
23 #include "wx/log.h"
24
25 #include "wx/osx/private.h"
26 #include "wx/osx/core/cfref.h"
27
28 #include "wx/evtloop.h"
29
30 namespace
31 {
32
33 CGEventTapLocation tap = kCGSessionEventTap;
34
35 CGEventType CGEventTypeForMouseButton(int button, bool isDown)
36 {
37 switch ( button )
38 {
39 case wxMOUSE_BTN_LEFT:
40 return isDown ? kCGEventLeftMouseDown : kCGEventLeftMouseUp;
41
42 case wxMOUSE_BTN_RIGHT:
43 return isDown ? kCGEventRightMouseDown : kCGEventRightMouseUp;
44
45 // All the other buttons use the constant OtherMouseDown but we still
46 // want to check for invalid parameters so assert first
47 default:
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;
53 }
54 }
55
56 CGEventType 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 }
80
81 CGMouseButton 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
102 CGPoint GetMousePosition()
103 {
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
114 } // anonymous namespace
115
116 bool wxUIActionSimulator::MouseDown(int button)
117 {
118 CGEventType type = CGEventTypeForMouseButton(button, true);
119 wxCFRef<CGEventRef> event(
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
134 bool 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
157 bool wxUIActionSimulator::MouseUp(int button)
158 {
159 CGEventType type = CGEventTypeForMouseButton(button, false);
160 wxCFRef<CGEventRef> event(
161 CGEventCreateMouseEvent(NULL, type, GetMousePosition(), CGButtonForMouseButton(button)));
162
163 if ( !event )
164 return false;
165
166 CGEventSetType(event, type);
167 CGEventPost(tap, event);
168 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
169 if (loop)
170 loop->SetShouldWaitForEvent(true);
171
172 return true;
173 }
174
175 bool wxUIActionSimulator::MouseDblClick(int button)
176 {
177 CGEventType downtype = CGEventTypeForMouseButton(button, true);
178 CGEventType uptype = CGEventTypeForMouseButton(button, false);
179 wxCFRef<CGEventRef> event(
180 CGEventCreateMouseEvent(NULL, downtype, GetMousePosition(), CGButtonForMouseButton(button)));
181
182 if ( !event )
183 return false;
184
185 CGEventSetType(event,downtype);
186 CGEventPost(tap, event);
187
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
201 return true;
202 }
203
204 bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2,
205 int button)
206 {
207 CGPoint pos1,pos2;
208 pos1.x = x1;
209 pos1.y = y1;
210 pos2.x = x2;
211 pos2.y = y2;
212
213 CGEventType downtype = CGEventTypeForMouseButton(button, true);
214 CGEventType uptype = CGEventTypeForMouseButton(button, false);
215 CGEventType dragtype = CGEventTypeForMouseDrag(button) ;
216
217 wxCFRef<CGEventRef> event(
218 CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, pos1, CGButtonForMouseButton(button)));
219
220 if ( !event )
221 return false;
222
223 CGEventSetType(event,kCGEventMouseMoved);
224 CGEventPost(tap, event);
225
226 CGEventSetType(event,downtype);
227 CGEventPost(tap, event);
228
229
230 CGEventSetType(event, dragtype);
231 CGEventSetLocation(event,pos2);
232 CGEventPost(tap, event);
233
234 CGEventSetType(event, uptype);
235 CGEventPost(tap, event);
236 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
237 if (loop)
238 loop->SetShouldWaitForEvent(true);
239
240 return true;
241 }
242
243 bool
244 wxUIActionSimulator::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown)
245 {
246 CGKeyCode cgcode = wxCharCodeWXToOSX((wxKeyCode)keycode);
247
248 wxCFRef<CGEventRef>
249 event(CGEventCreateKeyboardEvent(NULL, cgcode, isDown));
250 if ( !event )
251 return false;
252
253 CGEventPost(kCGHIDEventTap, event);
254 wxCFEventLoop* loop = dynamic_cast<wxCFEventLoop*>(wxEventLoop::GetActive());
255 if (loop)
256 loop->SetShouldWaitForEvent(true);
257
258 return true;
259 }
260
261 #endif // wxUSE_UIACTIONSIMULATOR
262