Put wxContextHelp into cshelp.h/cpp, added wxContextHelpButton
[wxWidgets.git] / src / common / cshelp.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: cshelp.cpp
3 // Purpose: Context sensitive help class implementation
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 08/09/2000
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "cshelp.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/defs.h"
25 #endif
26
27 #include "wx/app.h"
28
29 #if wxUSE_HELP
30
31 #include "wx/cshelp.h"
32
33 /*
34 * Invokes context-sensitive help
35 */
36
37 // This class exists in order to eat events until the left mouse
38 // button is pressed
39 class wxContextHelpEvtHandler: public wxEvtHandler
40 {
41 public:
42 wxContextHelpEvtHandler(wxContextHelp* contextHelp)
43 {
44 m_contextHelp = contextHelp;
45 }
46
47 virtual bool ProcessEvent(wxEvent& event);
48
49 //// Data
50 wxContextHelp* m_contextHelp;
51 };
52
53 IMPLEMENT_DYNAMIC_CLASS(wxContextHelp, wxObject)
54
55 wxContextHelp::wxContextHelp(wxWindow* win, bool beginHelp)
56 {
57 m_inHelp = FALSE;
58
59 if (beginHelp)
60 BeginContextHelp(win);
61 }
62
63 wxContextHelp::~wxContextHelp()
64 {
65 if (m_inHelp)
66 EndContextHelp();
67 }
68
69 // Begin 'context help mode'
70 bool wxContextHelp::BeginContextHelp(wxWindow* win)
71 {
72 if (!win)
73 win = wxTheApp->GetTopWindow();
74 if (!win)
75 return FALSE;
76
77 wxCursor cursor(wxCURSOR_QUESTION_ARROW);
78 wxCursor oldCursor = win->GetCursor();
79 win->SetCursor(cursor);
80
81 #ifdef __WXMSW__
82 // wxSetCursor(cursor);
83 #endif
84
85 win->PushEventHandler(new wxContextHelpEvtHandler(this));
86
87 win->CaptureMouse();
88
89 EventLoop();
90
91 win->ReleaseMouse();
92
93 win->PopEventHandler(TRUE);
94
95 win->SetCursor(oldCursor);
96
97 if (m_status)
98 {
99 wxPoint pt;
100 wxWindow* winAtPtr = wxFindWindowAtPointer(pt);
101 if (winAtPtr)
102 DispatchEvent(winAtPtr, pt);
103 }
104
105 return TRUE;
106 }
107
108 bool wxContextHelp::EndContextHelp()
109 {
110 m_inHelp = FALSE;
111
112 return TRUE;
113 }
114
115 bool wxContextHelp::EventLoop()
116 {
117 m_inHelp = TRUE;
118 while ( m_inHelp )
119 {
120 if (wxTheApp->Pending())
121 {
122 wxTheApp->Dispatch();
123 }
124 else
125 {
126 wxTheApp->ProcessIdle();
127 }
128 }
129 return TRUE;
130 }
131
132 bool wxContextHelpEvtHandler::ProcessEvent(wxEvent& event)
133 {
134 switch (event.GetEventType())
135 {
136 case wxEVT_LEFT_DOWN:
137 {
138 //wxMouseEvent& mouseEvent = (wxMouseEvent&) event;
139 m_contextHelp->SetStatus(TRUE);
140 m_contextHelp->EndContextHelp();
141 return TRUE;
142 break;
143 }
144 case wxEVT_CHAR:
145 case wxEVT_KEY_DOWN:
146 case wxEVT_ACTIVATE:
147 case wxEVT_MOUSE_CAPTURE_CHANGED:
148 {
149 m_contextHelp->SetStatus(FALSE);
150 m_contextHelp->EndContextHelp();
151 return TRUE;
152 break;
153 }
154 case wxEVT_PAINT:
155 case wxEVT_ERASE_BACKGROUND:
156 {
157 event.Skip();
158 return FALSE;
159 break;
160 }
161 }
162
163 return TRUE;
164 }
165
166 // Dispatch the help event to the relevant window
167 bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt)
168 {
169 wxWindow* subjectOfHelp = win;
170 bool eventProcessed = FALSE;
171 while (subjectOfHelp && !eventProcessed)
172 {
173 wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), pt) ;
174 helpEvent.SetEventObject(this);
175 eventProcessed = win->GetEventHandler()->ProcessEvent(helpEvent);
176
177 // Go up the window hierarchy until the event is handled (or not).
178 // I.e. keep submitting ancestor windows until one is recognised
179 // by the app code that processes the ids and displays help.
180 subjectOfHelp = subjectOfHelp->GetParent();
181 }
182 return eventProcessed;
183 }
184
185 /*
186 * wxContextHelpButton
187 * You can add this to your dialogs (especially on non-Windows platforms)
188 * to put the application into context help mode.
189 */
190
191 #if !defined(__WXMSW__)
192 static char * csquery_xpm[] = {
193 "12 11 2 1",
194 " c None",
195 ". c Black",
196 " ",
197 " .... ",
198 " .. .. ",
199 " .. .. ",
200 " .. ",
201 " .. ",
202 " .. ",
203 " ",
204 " .. ",
205 " .. ",
206 " "};
207 #endif
208
209 IMPLEMENT_CLASS(wxContextHelpButton, wxBitmapButton)
210
211 BEGIN_EVENT_TABLE(wxContextHelpButton, wxBitmapButton)
212 EVT_BUTTON(wxID_CONTEXT_HELP, wxContextHelpButton::OnContextHelp)
213 END_EVENT_TABLE()
214
215 wxContextHelpButton::wxContextHelpButton(wxWindow* parent, wxWindowID id,
216 const wxPoint& pos, const wxSize& size,
217 long style):
218 wxBitmapButton(parent, id, wxNullBitmap, pos, size, style)
219 {
220 #ifdef __WXMSW__
221 wxBitmap bitmap(wxT("csquery_bmp"), wxBITMAP_TYPE_BMP_RESOURCE);
222 #else
223 wxBitmap bitmap(csquery_xpm);
224 #endif
225
226 SetBitmapLabel(bitmap);
227 }
228
229 void wxContextHelpButton::OnContextHelp(wxCommandEvent& event)
230 {
231 wxContextHelp contextHelp;
232 }
233
234 #endif // wxUSE_HELP