]> git.saurik.com Git - wxWidgets.git/blame - interface/wx/evtloop.h
Correct wxTranslations docs: CWD is not searched.
[wxWidgets.git] / interface / wx / evtloop.h
CommitLineData
48c90c6e
VZ
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$
526954c5 7// Licence: wxWindows licence
48c90c6e
VZ
8/////////////////////////////////////////////////////////////////////////////
9
10/**
11 @class wxEventLoopBase
12
13 Base class for all event loop implementations.
14
ec38d07d
FM
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
48c90c6e
VZ
19 An object of this class is created by wxAppTraits::CreateEventLoop() and
20 used by wxApp to run the main application event loop.
e10539a9 21 Temporary event loops are usually created by wxDialog::ShowModal().
48c90c6e 22
ec38d07d
FM
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
d3ad22bd
VZ
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
48c90c6e
VZ
39 @library{wxbase}
40 @category{appmanagement}
41
dde19c21 42 @see wxApp, wxEventLoopActivator
48c90c6e
VZ
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.
ec38d07d
FM
61
62 Results in a call to wxAppConsole::OnEventLoopEnter.
48c90c6e
VZ
63 */
64 static void SetActive(wxEventLoopBase* loop);
65
ec38d07d
FM
66 /**
67 Returns @true if this is the main loop executed by wxApp::OnRun().
68 */
69 bool IsMain() const;
70
48c90c6e
VZ
71
72 /**
dde19c21
FM
73 @name Dispatch and processing
74 */
75 //@{
48c90c6e
VZ
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
dde19c21
FM
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
48c90c6e 105 /**
d3ad22bd
VZ
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
48c90c6e 130 */
d3ad22bd 131 virtual void ScheduleExit(int rc = 0) = 0;
48c90c6e
VZ
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 /**
dde19c21
FM
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).
48c90c6e 144
dde19c21 145 This can be used for programming event loops, e.g.
48c90c6e 146
dde19c21
FM
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 */
48c90c6e
VZ
156 virtual bool Dispatch() = 0;
157
9af42efd
VZ
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
48c90c6e
VZ
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
dde19c21
FM
182 //@}
183
184
dde19c21
FM
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 /**
ec38d07d 212 Returns @true if called from inside Yield() or from inside YieldFor().
dde19c21
FM
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
48c90c6e
VZ
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
ec38d07d 280 The default implementation calls wxAppConsole::OnEventLoopExit.
48c90c6e
VZ
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};
3668a019
RD
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