1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/evtloop.h
3 // Purpose:     declares wxEventLoop class
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     01.06.01
7 // RCS-ID:      $Id: evtloop.h 53607 2008-05-16 15:21:40Z SN $
8 // Copyright:   (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence:     wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef _WX_EVTLOOP_H_
13 #define _WX_EVTLOOP_H_
14 
15 #include "wx/utils.h"
16 
17 class WXDLLIMPEXP_FWD_CORE wxEventLoop;
18 
19 // ----------------------------------------------------------------------------
20 // wxEventLoop: a GUI event loop
21 // ----------------------------------------------------------------------------
22 
23 class WXDLLEXPORT wxEventLoopBase
24 {
25 public:
26     // trivial, but needed (because of wxEventLoopBase) ctor
wxEventLoopBase()27     wxEventLoopBase() { }
28 
29     // dtor
~wxEventLoopBase()30     virtual ~wxEventLoopBase() { }
31 
32     // start the event loop, return the exit code when it is finished
33     virtual int Run() = 0;
34 
35     // exit from the loop with the given exit code
36     virtual void Exit(int rc = 0) = 0;
37 
38     // return true if any events are available
39     virtual bool Pending() const = 0;
40 
41     // dispatch a single event, return false if we should exit from the loop
42     virtual bool Dispatch() = 0;
43 
44     // return currently active (running) event loop, may be NULL
GetActive()45     static wxEventLoop *GetActive() { return ms_activeLoop; }
46 
47     // set currently active (running) event loop
SetActive(wxEventLoop * loop)48     static void SetActive(wxEventLoop* loop) { ms_activeLoop = loop; }
49 
50     // is this event loop running now?
51     //
52     // notice that even if this event loop hasn't terminated yet but has just
53     // spawned a nested (e.g. modal) event loop, this would return false
54     bool IsRunning() const;
55 
56 protected:
57     // this function should be called before the event loop terminates, whether
58     // this happens normally (because of Exit() call) or abnormally (because of
59     // an exception thrown from inside the loop)
OnExit()60     virtual void OnExit() { }
61 
62 
63     // the pointer to currently active loop
64     static wxEventLoop *ms_activeLoop;
65 
66     DECLARE_NO_COPY_CLASS(wxEventLoopBase)
67 };
68 
69 #if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXDFB__)
70 
71 // this class can be used to implement a standard event loop logic using
72 // Pending() and Dispatch()
73 //
74 // it also handles idle processing automatically
75 class WXDLLEXPORT wxEventLoopManual : public wxEventLoopBase
76 {
77 public:
78     wxEventLoopManual();
79 
80     // enters a loop calling OnNextIteration(), Pending() and Dispatch() and
81     // terminating when Exit() is called
82     virtual int Run();
83 
84     // sets the "should exit" flag and wakes up the loop so that it terminates
85     // soon
86     virtual void Exit(int rc = 0);
87 
88 protected:
89     // implement this to wake up the loop: usually done by posting a dummy event
90     // to it (called from Exit())
91     virtual void WakeUp() = 0;
92 
93     // may be overridden to perform some action at the start of each new event
94     // loop iteration
OnNextIteration()95     virtual void OnNextIteration() { }
96 
97 
98     // the loop exit code
99     int m_exitcode;
100 
101     // should we exit the loop?
102     bool m_shouldExit;
103 };
104 
105 #endif // platforms using "manual" loop
106 
107 // we're moving away from old m_impl wxEventLoop model as otherwise the user
108 // code doesn't have access to platform-specific wxEventLoop methods and this
109 // can sometimes be very useful (e.g. under MSW this is necessary for
110 // integration with MFC) but currently this is done for MSW only, other ports
111 // should follow a.s.a.p.
112 #if defined(__WXPALMOS__)
113     #include "wx/palmos/evtloop.h"
114 #elif defined(__WXMSW__)
115     #include "wx/msw/evtloop.h"
116 #elif defined(__WXMAC__)
117     #include "wx/mac/evtloop.h"
118 #elif defined(__WXDFB__)
119     #include "wx/dfb/evtloop.h"
120 #else // other platform
121 
122 class WXDLLEXPORT wxEventLoopImpl;
123 
124 class WXDLLEXPORT wxEventLoop : public wxEventLoopBase
125 {
126 public:
wxEventLoop()127     wxEventLoop() { m_impl = NULL; }
128     virtual ~wxEventLoop();
129 
130     virtual int Run();
131     virtual void Exit(int rc = 0);
132     virtual bool Pending() const;
133     virtual bool Dispatch();
134 
135 protected:
136     // the pointer to the port specific implementation class
137     wxEventLoopImpl *m_impl;
138 
139     DECLARE_NO_COPY_CLASS(wxEventLoop)
140 };
141 
142 #endif // platforms
143 
IsRunning()144 inline bool wxEventLoopBase::IsRunning() const { return GetActive() == this; }
145 
146 // ----------------------------------------------------------------------------
147 // wxModalEventLoop
148 // ----------------------------------------------------------------------------
149 
150 // this is a naive generic implementation which uses wxWindowDisabler to
151 // implement modality, we will surely need platform-specific implementations
152 // too, this generic implementation is here only temporarily to see how it
153 // works
154 class WXDLLEXPORT wxModalEventLoop : public wxEventLoop
155 {
156 public:
wxModalEventLoop(wxWindow * winModal)157     wxModalEventLoop(wxWindow *winModal)
158     {
159         m_windowDisabler = new wxWindowDisabler(winModal);
160     }
161 
162 protected:
OnExit()163     virtual void OnExit()
164     {
165         delete m_windowDisabler;
166         m_windowDisabler = NULL;
167 
168         wxEventLoop::OnExit();
169     }
170 
171 private:
172     wxWindowDisabler *m_windowDisabler;
173 };
174 
175 // ----------------------------------------------------------------------------
176 // wxEventLoopActivator: helper class for wxEventLoop implementations
177 // ----------------------------------------------------------------------------
178 
179 // this object sets the wxEventLoop given to the ctor as the currently active
180 // one and unsets it in its dtor, this is especially useful in presence of
181 // exceptions but is more tidy even when we don't use them
182 class wxEventLoopActivator
183 {
184 public:
wxEventLoopActivator(wxEventLoop * evtLoop)185     wxEventLoopActivator(wxEventLoop *evtLoop)
186     {
187         m_evtLoopOld = wxEventLoop::GetActive();
188         wxEventLoop::SetActive(evtLoop);
189     }
190 
~wxEventLoopActivator()191     ~wxEventLoopActivator()
192     {
193         // restore the previously active event loop
194         wxEventLoop::SetActive(m_evtLoopOld);
195     }
196 
197 private:
198     wxEventLoop *m_evtLoopOld;
199 };
200 
201 #if wxABI_VERSION >= 20808
202 class wxEventLoopGuarantor
203 {
204 public:
wxEventLoopGuarantor()205     wxEventLoopGuarantor()
206     {
207         m_evtLoopNew = NULL;
208         if (!wxEventLoop::GetActive())
209         {
210             m_evtLoopNew = new wxEventLoop;
211             wxEventLoop::SetActive(m_evtLoopNew);
212         }
213     }
214 
~wxEventLoopGuarantor()215     ~wxEventLoopGuarantor()
216     {
217         if (m_evtLoopNew)
218         {
219             wxEventLoop::SetActive(NULL);
220             delete m_evtLoopNew;
221         }
222     }
223 
224 private:
225     wxEventLoop *m_evtLoopNew;
226 };
227 #endif // wxABI_VERSION >= 20805
228 
229 #endif // _WX_EVTLOOP_H_
230