]> git.saurik.com Git - wxWidgets.git/blob - interface/wx/evtloop.h
recategorize many misplaced classes; move lots of classes from miscellaneous [window...
[wxWidgets.git] / interface / wx / evtloop.h
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 };