X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/48c90c6e1e12ddbc806324a02c8f34a5130f037b..7c60222510bc5e197b12f153c4bf05db66cb0f4a:/interface/wx/evtloop.h diff --git a/interface/wx/evtloop.h b/interface/wx/evtloop.h index d4a7966a95..4e42be0dc4 100644 --- a/interface/wx/evtloop.h +++ b/interface/wx/evtloop.h @@ -4,7 +4,7 @@ // Author: Vadim Zeitlin // Copyright: (C) 2008 Vadim Zeitlin // RCS-ID: $Id$ -// Licence: wxWindows license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// /** @@ -12,13 +12,21 @@ Base class for all event loop implementations. + An event loop is a class which queries the queue of native events sent + to the wxWidgets application and dispatches them to the appropriate + wxEvtHandlers. + An object of this class is created by wxAppTraits::CreateEventLoop() and used by wxApp to run the main application event loop. + Temporary event loops are usually created by wxDialog::ShowModal(). + + You can create your own event loop if you need, provided that you restore + the main event loop once yours is destroyed (see wxEventLoopActivator). @library{wxbase} @category{appmanagement} - @see wxApp + @see wxApp, wxEventLoopActivator */ class wxEventLoopBase { @@ -37,15 +45,21 @@ public: Called by wxEventLoopActivator, use an instance of this class instead of calling this method directly to ensure that the previously active event loop is restored. + + Results in a call to wxAppConsole::OnEventLoopEnter. */ static void SetActive(wxEventLoopBase* loop); + /** + Returns @true if this is the main loop executed by wxApp::OnRun(). + */ + bool IsMain() const; + /** - Use this to check whether the event loop was successfully created - before using it - */ - virtual bool IsOk() const; + @name Dispatch and processing + */ + //@{ /** Start the event loop, return the exit code when it is finished. @@ -60,6 +74,21 @@ public: */ virtual int Run() = 0; + /** + Return true if this event loop is currently running. + + Notice that even if this event loop hasn't terminated yet but has just + spawned a nested (e.g. modal) event loop, this method would return + @false. + */ + bool IsRunning() const; + + /** + Use this to check whether the event loop was successfully created + before using it + */ + virtual bool IsOk() const; + /** Exit from the loop with the given exit code. */ @@ -73,23 +102,40 @@ public: virtual bool Pending() const = 0; /** - Dispatch a single event. + Dispatches the next event in the windowing system event queue. + Blocks until an event appears if there are none currently + (use Pending() if this is not wanted). - If there are currently no events in the queue, blocks until an event - becomes available. + This can be used for programming event loops, e.g. - @return @false only if the event loop should terminate. - */ + @code + while (evtloop->Pending()) + evtloop->Dispatch(); + @endcode + + @return @false if the event loop should stop and @true otherwise. + + @see Pending(), wxEventLoopBase + */ virtual bool Dispatch() = 0; /** - Return true if this event loop is currently running. + Dispatch an event but not wait longer than the specified timeout for + it. - Notice that even if this event loop hasn't terminated yet but has just - spawned a nested (e.g. modal) event loop, this method would return - @false. + If an event is received before the specified @a timeout expires, it is + processed and the function returns 1 normally or 0 if the event loop + should quite. Otherwise, i.e. if the timeout expires, the functions + returns -1 without processing any events. + + @param timeout + The maximal time to wait for the events in milliseconds. + + @return + 1 if an event was processed, 0 if the event loop should quit or -1 + if the timeout expired. */ - bool IsRunning() const; + virtual int DispatchTimeout(unsigned long timeout) = 0; /** Called by wxWidgets to wake up the event loop even if it is currently @@ -97,13 +143,105 @@ public: */ virtual void WakeUp() = 0; + //@} + + + /** + @name Idle handling + */ + //@{ + + /** + Makes sure that idle events are sent again. + */ + virtual void WakeUpIdle(); + + /** + This virtual function is called when the application becomes idle and + normally just sends wxIdleEvent to all interested parties. + + It should return @true if more idle events are needed, @false if not. + */ + virtual bool ProcessIdle(); + + //@} + + + /** + @name Yield-related hooks + */ + //@{ + + /** + Returns @true if called from inside Yield() or from inside YieldFor(). + */ + virtual bool IsYielding() const; + + /** + Yields control to pending messages in the windowing system. + + This can be useful, for example, when a time-consuming process writes to a + text window. Without an occasional yield, the text window will not be updated + properly, and on systems with cooperative multitasking, such as Windows 3.1 + other processes will not respond. + + Caution should be exercised, however, since yielding may allow the + user to perform actions which are not compatible with the current task. + Disabling menu items or whole menus during processing can avoid unwanted + reentrance of code: see ::wxSafeYield for a better function. + You can avoid unwanted reentrancies also using IsYielding(). + + Note that Yield() will not flush the message logs. This is intentional as + calling Yield() is usually done to quickly update the screen and popping up + a message box dialog may be undesirable. If you do wish to flush the log + messages immediately (otherwise it will be done during the next idle loop + iteration), call wxLog::FlushActive. + + Calling Yield() recursively is normally an error and an assert failure is + raised in debug build if such situation is detected. However if the + @a onlyIfNeeded parameter is @true, the method will just silently + return @false instead. + */ + bool Yield(bool onlyIfNeeded = false); + + /** + Works like Yield() with @e onlyIfNeeded == @true, except that it allows + the caller to specify a mask of the ::wxEventCategory values which + indicates which events should be processed and which should instead + be "delayed" (i.e. processed by the main loop later). + + Note that this is a safer alternative to Yield() since it ensures that + only the events you're interested to will be processed; i.e. this method + helps to avoid unwanted reentrancies. + + Note that currently only wxMSW and wxGTK do support selective yield of + native events coming from the underlying GUI toolkit. + wxWidgets events posted using wxEvtHandler::AddPendingEvent or + wxEvtHandler::QueueEvent are instead selectively processed by all ports. + + @see wxEvent::GetEventCategory + */ + bool YieldFor(long eventsToProcess); + + /** + Returns @true if the given event category is allowed inside + a YieldFor() call (i.e. compares the given category against the + last mask passed to YieldFor()). + + @see wxEvent::GetEventCategory + */ + virtual bool IsEventAllowedInsideYield(wxEventCategory cat) const; + + //@} + + protected: /** This function is called before the event loop terminates, whether this happens normally (because of Exit() call) or abnormally (because of an exception thrown from inside the loop). - Default version does nothing. + The default implementation calls wxAppConsole::OnEventLoopExit. */ virtual void OnExit(); }; @@ -148,3 +286,20 @@ public: */ ~wxEventLoopActivator(); }; + +/** + @class wxGUIEventLoop + + A generic implementation of the GUI event loop. + + @library{wxbase} + @category{appmanagement} +*/ +class wxGUIEventLoop : public wxEventLoopBase +{ +public: + wxGUIEventLoop(); + virtual ~wxGUIEventLoop(); +}; + +