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