No real changes, just refactor wxControlContainer code a little.
[wxWidgets.git] / include / wx / modalhook.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/modalhook.h
3 // Purpose: Allows to hook into showing modal dialogs.
4 // Author: Vadim Zeitlin
5 // Created: 2013-05-19
6 // RCS-ID: $Id$
7 // Copyright: (c) 2013 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 #ifndef _WX_MODALHOOK_H_
12 #define _WX_MODALHOOK_H_
13
14 #include "wx/vector.h"
15
16 class WXDLLIMPEXP_FWD_CORE wxDialog;
17
18 // ----------------------------------------------------------------------------
19 // Class allowing to be notified about any modal dialog calls.
20 // ----------------------------------------------------------------------------
21
22 // To be notified about entering and exiting modal dialogs and possibly to
23 // replace them with something else (e.g. just return a predefined value for
24 // testing), define an object of this class, override its Enter() and
25 // possibly Exit() methods and call Register() on it.
26 class WXDLLIMPEXP_CORE wxModalDialogHook
27 {
28 public:
29 // Default ctor doesn't do anything, call Register() to activate the hook.
30 wxModalDialogHook() { }
31
32 // Dtor unregisters the hook if it had been registered.
33 virtual ~wxModalDialogHook() { DoUnregister(); }
34
35 // Register this hook as being active, i.e. its Enter() and Exit() methods
36 // will be called.
37 //
38 // Notice that the order of registration matters: the last hook registered
39 // is called first, and if its Enter() returns something != wxID_NONE, the
40 // subsequent hooks are skipped.
41 void Register();
42
43 // Unregister this hook. Notice that is done automatically from the dtor.
44 void Unregister();
45
46 // Called from wxWidgets code before showing any modal dialogs and calls
47 // Enter() for every registered hook.
48 static int CallEnter(wxDialog* dialog);
49
50 // Called from wxWidgets code after dismissing the dialog and calls Exit()
51 // for every registered hook.
52 static void CallExit(wxDialog* dialog);
53
54 protected:
55 // Called by wxWidgets before showing any modal dialogs, override this to
56 // be notified about this and return anything but wxID_NONE to skip showing
57 // the modal dialog entirely and just return the specified result.
58 virtual int Enter(wxDialog* dialog) = 0;
59
60 // Called by wxWidgets after dismissing the modal dialog. Notice that it
61 // won't be called if Enter() hadn't been.
62 virtual void Exit(wxDialog* WXUNUSED(dialog)) { }
63
64 private:
65 // Unregister the given hook, return true if it was done or false if the
66 // hook wasn't found.
67 bool DoUnregister();
68
69 // All the hooks in reverse registration order (i.e. in call order).
70 typedef wxVector<wxModalDialogHook*> Hooks;
71 static Hooks ms_hooks;
72
73 wxDECLARE_NO_COPY_CLASS(wxModalDialogHook);
74 };
75
76 // Helper object used by WX_MODAL_DIALOG_HOOK below to ensure that CallExit()
77 // is called on scope exit.
78 class wxModalDialogHookExitGuard
79 {
80 public:
81 wxEXPLICIT wxModalDialogHookExitGuard(wxDialog* dialog)
82 : m_dialog(dialog)
83 {
84 }
85
86 ~wxModalDialogHookExitGuard()
87 {
88 wxModalDialogHook::CallExit(m_dialog);
89 }
90
91 private:
92 wxDialog* const m_dialog;
93
94 wxDECLARE_NO_COPY_CLASS(wxModalDialogHookExitGuard);
95 };
96
97 // This macro needs to be used at the top of every implementation of
98 // ShowModal() in order for wxModalDialogHook to work.
99 #define WX_HOOK_MODAL_DIALOG() \
100 const int modalDialogHookRC = wxModalDialogHook::CallEnter(this); \
101 if ( modalDialogHookRC != wxID_NONE ) \
102 return modalDialogHookRC; \
103 wxModalDialogHookExitGuard modalDialogHookExit(this)
104
105 #endif // _WX_MODALHOOK_H_