]>
Commit | Line | Data |
---|---|---|
1 | ///////////////////////////////////////////////////////////////////////////// | |
2 | // Name: wx/evtloop.h | |
3 | // Purpose: wxEventLoop and related classes | |
4 | // Author: Vadim Zeitlin | |
5 | // Copyright: (C) 2008 Vadim Zeitlin | |
6 | // RCS-ID: $Id$ | |
7 | // Licence: wxWindows license | |
8 | ///////////////////////////////////////////////////////////////////////////// | |
9 | ||
10 | /** | |
11 | @class wxEventLoopBase | |
12 | ||
13 | Base class for all event loop implementations. | |
14 | ||
15 | An object of this class is created by wxAppTraits::CreateEventLoop() and | |
16 | used by wxApp to run the main application event loop. | |
17 | ||
18 | @library{wxbase} | |
19 | @category{appmanagement} | |
20 | ||
21 | @see wxApp, wxEventLoopActivator | |
22 | */ | |
23 | class wxEventLoopBase | |
24 | { | |
25 | public: | |
26 | /** | |
27 | Return the currently active (running) event loop. | |
28 | ||
29 | May return @NULL if there is no active event loop (e.g. during | |
30 | application startup or shutdown). | |
31 | */ | |
32 | static wxEventLoopBase *GetActive(); | |
33 | ||
34 | /** | |
35 | Set currently active (running) event loop. | |
36 | ||
37 | Called by wxEventLoopActivator, use an instance of this class instead | |
38 | of calling this method directly to ensure that the previously active | |
39 | event loop is restored. | |
40 | */ | |
41 | static void SetActive(wxEventLoopBase* loop); | |
42 | ||
43 | ||
44 | /** | |
45 | @name Dispatch and processing | |
46 | */ | |
47 | //@{ | |
48 | ||
49 | /** | |
50 | Start the event loop, return the exit code when it is finished. | |
51 | ||
52 | Logically, this method calls Dispatch() in a loop until it returns | |
53 | @false and also takes care of generating idle events during each loop | |
54 | iteration. However not all implementations of this class really | |
55 | implement it like this (e.g. wxGTK does not) so you shouldn't rely on | |
56 | Dispatch() being called from inside this function. | |
57 | ||
58 | @return The argument passed to Exit() which terminated this event loop. | |
59 | */ | |
60 | virtual int Run() = 0; | |
61 | ||
62 | /** | |
63 | Return true if this event loop is currently running. | |
64 | ||
65 | Notice that even if this event loop hasn't terminated yet but has just | |
66 | spawned a nested (e.g. modal) event loop, this method would return | |
67 | @false. | |
68 | */ | |
69 | bool IsRunning() const; | |
70 | ||
71 | /** | |
72 | Use this to check whether the event loop was successfully created | |
73 | before using it | |
74 | */ | |
75 | virtual bool IsOk() const; | |
76 | ||
77 | /** | |
78 | Exit from the loop with the given exit code. | |
79 | */ | |
80 | virtual void Exit(int rc = 0) = 0; | |
81 | ||
82 | /** | |
83 | Return true if any events are available. | |
84 | ||
85 | If this method returns @true, calling Dispatch() will not block. | |
86 | */ | |
87 | virtual bool Pending() const = 0; | |
88 | ||
89 | /** | |
90 | Dispatches the next event in the windowing system event queue. | |
91 | Blocks until an event appears if there are none currently | |
92 | (use Pending() if this is not wanted). | |
93 | ||
94 | This can be used for programming event loops, e.g. | |
95 | ||
96 | @code | |
97 | while (evtloop->Pending()) | |
98 | evtloop->Dispatch(); | |
99 | @endcode | |
100 | ||
101 | @return @false if the event loop should stop and @true otherwise. | |
102 | ||
103 | @see Pending(), wxEventLoopBase | |
104 | */ | |
105 | virtual bool Dispatch() = 0; | |
106 | ||
107 | /** | |
108 | Dispatch an event but not wait longer than the specified timeout for | |
109 | it. | |
110 | ||
111 | If an event is received before the specified @a timeout expires, it is | |
112 | processed and the function returns 1 normally or 0 if the event loop | |
113 | should quite. Otherwise, i.e. if the timeout expires, the functions | |
114 | returns -1 without processing any events. | |
115 | ||
116 | @param timeout | |
117 | The maximal time to wait for the events in milliseconds. | |
118 | ||
119 | @return | |
120 | 1 if an event was processed, 0 if the event loop should quit or -1 | |
121 | if the timeout expired. | |
122 | */ | |
123 | virtual int DispatchTimeout(unsigned long timeout) = 0; | |
124 | ||
125 | /** | |
126 | Called by wxWidgets to wake up the event loop even if it is currently | |
127 | blocked inside Dispatch(). | |
128 | */ | |
129 | virtual void WakeUp() = 0; | |
130 | ||
131 | //@} | |
132 | ||
133 | ||
134 | /** | |
135 | @name Pending events | |
136 | */ | |
137 | //@{ | |
138 | ||
139 | /** | |
140 | Process all pending events; it is necessary to call this function to | |
141 | process posted events. | |
142 | ||
143 | This happens during each event loop iteration in GUI mode but | |
144 | it may be also called directly. | |
145 | */ | |
146 | virtual void ProcessPendingEvents(); | |
147 | ||
148 | /** | |
149 | Returns @true if there are pending events on the internal pending event list. | |
150 | */ | |
151 | bool HasPendingEvents() const; | |
152 | ||
153 | /** | |
154 | Temporary suspends processing of the pending events. | |
155 | ||
156 | @see ResumeProcessingOfPendingEvents() | |
157 | */ | |
158 | void SuspendProcessingOfPendingEvents(); | |
159 | ||
160 | /** | |
161 | Resume processing of the pending events previously stopped because of a | |
162 | call to SuspendProcessingOfPendingEvents(). | |
163 | */ | |
164 | void ResumeProcessingOfPendingEvents(); | |
165 | ||
166 | //@} | |
167 | ||
168 | ||
169 | /** | |
170 | @name Idle handling | |
171 | */ | |
172 | //@{ | |
173 | ||
174 | /** | |
175 | Makes sure that idle events are sent again. | |
176 | */ | |
177 | virtual void WakeUpIdle(); | |
178 | ||
179 | /** | |
180 | This virtual function is called when the application becomes idle and | |
181 | normally just sends wxIdleEvent to all interested parties. | |
182 | ||
183 | It should return @true if more idle events are needed, @false if not. | |
184 | */ | |
185 | virtual bool ProcessIdle(); | |
186 | ||
187 | //@} | |
188 | ||
189 | ||
190 | /** | |
191 | @name Yield-related hooks | |
192 | */ | |
193 | //@{ | |
194 | ||
195 | /** | |
196 | Returns @true if called from inside Yield(). | |
197 | */ | |
198 | virtual bool IsYielding() const; | |
199 | ||
200 | /** | |
201 | Yields control to pending messages in the windowing system. | |
202 | ||
203 | This can be useful, for example, when a time-consuming process writes to a | |
204 | text window. Without an occasional yield, the text window will not be updated | |
205 | properly, and on systems with cooperative multitasking, such as Windows 3.1 | |
206 | other processes will not respond. | |
207 | ||
208 | Caution should be exercised, however, since yielding may allow the | |
209 | user to perform actions which are not compatible with the current task. | |
210 | Disabling menu items or whole menus during processing can avoid unwanted | |
211 | reentrance of code: see ::wxSafeYield for a better function. | |
212 | You can avoid unwanted reentrancies also using IsYielding(). | |
213 | ||
214 | Note that Yield() will not flush the message logs. This is intentional as | |
215 | calling Yield() is usually done to quickly update the screen and popping up | |
216 | a message box dialog may be undesirable. If you do wish to flush the log | |
217 | messages immediately (otherwise it will be done during the next idle loop | |
218 | iteration), call wxLog::FlushActive. | |
219 | ||
220 | Calling Yield() recursively is normally an error and an assert failure is | |
221 | raised in debug build if such situation is detected. However if the | |
222 | @a onlyIfNeeded parameter is @true, the method will just silently | |
223 | return @false instead. | |
224 | */ | |
225 | bool Yield(bool onlyIfNeeded = false); | |
226 | ||
227 | /** | |
228 | Works like Yield() with @e onlyIfNeeded == @true, except that it allows | |
229 | the caller to specify a mask of the ::wxEventCategory values which | |
230 | indicates which events should be processed and which should instead | |
231 | be "delayed" (i.e. processed by the main loop later). | |
232 | ||
233 | Note that this is a safer alternative to Yield() since it ensures that | |
234 | only the events you're interested to will be processed; i.e. this method | |
235 | helps to avoid unwanted reentrancies. | |
236 | ||
237 | Note that currently only wxMSW and wxGTK do support selective yield of | |
238 | native events coming from the underlying GUI toolkit. | |
239 | wxWidgets events posted using wxEvtHandler::AddPendingEvent or | |
240 | wxEvtHandler::QueueEvent are instead selectively processed by all ports. | |
241 | ||
242 | @see wxEvent::GetEventCategory | |
243 | */ | |
244 | bool YieldFor(long eventsToProcess); | |
245 | ||
246 | /** | |
247 | Returns @true if the given event category is allowed inside | |
248 | a YieldFor() call (i.e. compares the given category against the | |
249 | last mask passed to YieldFor()). | |
250 | ||
251 | @see wxEvent::GetEventCategory | |
252 | */ | |
253 | virtual bool IsEventAllowedInsideYield(wxEventCategory cat) const; | |
254 | ||
255 | //@} | |
256 | ||
257 | ||
258 | protected: | |
259 | /** | |
260 | This function is called before the event loop terminates, whether this | |
261 | happens normally (because of Exit() call) or abnormally (because of an | |
262 | exception thrown from inside the loop). | |
263 | ||
264 | Default version does nothing. | |
265 | */ | |
266 | virtual void OnExit(); | |
267 | }; | |
268 | ||
269 | /** | |
270 | @class wxEventLoopActivator | |
271 | ||
272 | Makes an event loop temporarily active. | |
273 | ||
274 | This class is used to make the event loop active during its life-time, | |
275 | e.g.: | |
276 | @code | |
277 | class MyEventLoop : public wxEventLoopBase { ... }; | |
278 | ||
279 | void RunMyLoop() | |
280 | { | |
281 | MyEventLoop loop; | |
282 | wxEventLoopActivator activate(&loop); | |
283 | ||
284 | ... | |
285 | } // the previously active event loop restored here | |
286 | @endcode | |
287 | ||
288 | @library{wxbase} | |
289 | @category{appmanagement} | |
290 | ||
291 | @see wxEventLoopBase | |
292 | */ | |
293 | class wxEventLoopActivator | |
294 | { | |
295 | public: | |
296 | /** | |
297 | Makes the loop passed as the parameter currently active. | |
298 | ||
299 | This saves the current return value of wxEventLoopBase::GetActive() and | |
300 | then calls wxEventLoopBase::SetActive() with the given @a loop. | |
301 | */ | |
302 | wxEventLoopActivator(wxEventLoopBase *loop); | |
303 | ||
304 | /** | |
305 | Restores the previously active event loop stored by the constructor. | |
306 | */ | |
307 | ~wxEventLoopActivator(); | |
308 | }; |