]> git.saurik.com Git - wxWidgets.git/blame - src/common/cshelp.cpp
fixed event processing for the target window
[wxWidgets.git] / src / common / cshelp.cpp
CommitLineData
fb6261e9 1/////////////////////////////////////////////////////////////////////////////
bd83cb56 2// Name: src/common/cshelp.cpp
fb6261e9 3// Purpose: Context sensitive help class implementation
bd83cb56 4// Author: Julian Smart, Vadim Zeitlin
fb6261e9
JS
5// Modified by:
6// Created: 08/09/2000
7// RCS-ID: $Id$
bd83cb56 8// Copyright: (c) 2000 Julian Smart, Vadim Zeitlin
fb6261e9
JS
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
bd83cb56
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
fb6261e9 16#ifdef __GNUG__
bd83cb56 17 #pragma implementation "cshelp.h"
fb6261e9
JS
18#endif
19
bd83cb56
VZ
20// ----------------------------------------------------------------------------
21// headers
22// ----------------------------------------------------------------------------
23
fb6261e9
JS
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
bd83cb56 28 #pragma hdrstop
fb6261e9
JS
29#endif
30
bd83cb56
VZ
31#if wxUSE_HELP
32
fb6261e9 33#ifndef WX_PRECOMP
fb6261e9
JS
34#endif
35
afb02ca5 36#include "wx/tipwin.h"
fb6261e9 37#include "wx/app.h"
129caadd 38#include "wx/module.h"
fb6261e9
JS
39#include "wx/cshelp.h"
40
bd83cb56
VZ
41// ----------------------------------------------------------------------------
42// wxContextHelpEvtHandler private class
43// ----------------------------------------------------------------------------
fb6261e9 44
bd83cb56
VZ
45// This class exists in order to eat events until the left mouse button is
46// pressed
fb6261e9
JS
47class wxContextHelpEvtHandler: public wxEvtHandler
48{
49public:
50 wxContextHelpEvtHandler(wxContextHelp* contextHelp)
51 {
52 m_contextHelp = contextHelp;
53 }
54
55 virtual bool ProcessEvent(wxEvent& event);
56
57//// Data
58 wxContextHelp* m_contextHelp;
59};
60
bd83cb56
VZ
61// ============================================================================
62// implementation
63// ============================================================================
64
65// ----------------------------------------------------------------------------
66// wxContextHelp
67// ----------------------------------------------------------------------------
68
69/*
70 * Invokes context-sensitive help
71 */
72
73
fb6261e9
JS
74IMPLEMENT_DYNAMIC_CLASS(wxContextHelp, wxObject)
75
76wxContextHelp::wxContextHelp(wxWindow* win, bool beginHelp)
77{
78 m_inHelp = FALSE;
79
80 if (beginHelp)
81 BeginContextHelp(win);
82}
83
84wxContextHelp::~wxContextHelp()
85{
86 if (m_inHelp)
87 EndContextHelp();
88}
89
90// Begin 'context help mode'
91bool wxContextHelp::BeginContextHelp(wxWindow* win)
92{
93 if (!win)
94 win = wxTheApp->GetTopWindow();
95 if (!win)
96 return FALSE;
97
98 wxCursor cursor(wxCURSOR_QUESTION_ARROW);
99 wxCursor oldCursor = win->GetCursor();
100 win->SetCursor(cursor);
101
102#ifdef __WXMSW__
103 // wxSetCursor(cursor);
104#endif
105
106 win->PushEventHandler(new wxContextHelpEvtHandler(this));
107
108 win->CaptureMouse();
109
110 EventLoop();
111
112 win->ReleaseMouse();
113
114 win->PopEventHandler(TRUE);
115
116 win->SetCursor(oldCursor);
117
118 if (m_status)
119 {
120 wxPoint pt;
121 wxWindow* winAtPtr = wxFindWindowAtPointer(pt);
d1c8aaa3
JS
122 /*
123 if (winAtPtr)
124 {
125 wxString msg;
126 msg.Printf("Picked %s (%d)", (const char*) winAtPtr->GetName(), winAtPtr->GetId());
127 cout << msg << '\n';
128 }
129 */
130
fb6261e9
JS
131 if (winAtPtr)
132 DispatchEvent(winAtPtr, pt);
133 }
134
135 return TRUE;
136}
137
138bool wxContextHelp::EndContextHelp()
139{
140 m_inHelp = FALSE;
141
142 return TRUE;
143}
144
145bool wxContextHelp::EventLoop()
146{
147 m_inHelp = TRUE;
148 while ( m_inHelp )
149 {
150 if (wxTheApp->Pending())
151 {
152 wxTheApp->Dispatch();
153 }
154 else
155 {
156 wxTheApp->ProcessIdle();
157 }
158 }
159 return TRUE;
160}
161
162bool wxContextHelpEvtHandler::ProcessEvent(wxEvent& event)
163{
77d4384e 164 if (event.GetEventType() == wxEVT_LEFT_DOWN)
fb6261e9 165 {
77d4384e
RR
166 m_contextHelp->SetStatus(TRUE);
167 m_contextHelp->EndContextHelp();
168 return TRUE;
fb6261e9 169 }
33ac7e6f 170
77d4384e
RR
171 if ((event.GetEventType() == wxEVT_CHAR) ||
172 (event.GetEventType() == wxEVT_KEY_DOWN) ||
173 (event.GetEventType() == wxEVT_ACTIVATE) ||
174 (event.GetEventType() == wxEVT_MOUSE_CAPTURE_CHANGED))
175 {
176 m_contextHelp->SetStatus(FALSE);
177 m_contextHelp->EndContextHelp();
178 return TRUE;
179 }
33ac7e6f 180
77d4384e
RR
181 if ((event.GetEventType() == wxEVT_PAINT) ||
182 (event.GetEventType() == wxEVT_ERASE_BACKGROUND))
183 {
184 event.Skip();
185 return FALSE;
186 }
33ac7e6f 187
fb6261e9
JS
188 return TRUE;
189}
190
191// Dispatch the help event to the relevant window
192bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt)
193{
194 wxWindow* subjectOfHelp = win;
195 bool eventProcessed = FALSE;
196 while (subjectOfHelp && !eventProcessed)
197 {
198 wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), pt) ;
199 helpEvent.SetEventObject(this);
200 eventProcessed = win->GetEventHandler()->ProcessEvent(helpEvent);
33ac7e6f 201
fb6261e9
JS
202 // Go up the window hierarchy until the event is handled (or not).
203 // I.e. keep submitting ancestor windows until one is recognised
204 // by the app code that processes the ids and displays help.
205 subjectOfHelp = subjectOfHelp->GetParent();
206 }
207 return eventProcessed;
208}
209
bd83cb56
VZ
210// ----------------------------------------------------------------------------
211// wxContextHelpButton
212// ----------------------------------------------------------------------------
213
fb6261e9
JS
214/*
215 * wxContextHelpButton
216 * You can add this to your dialogs (especially on non-Windows platforms)
217 * to put the application into context help mode.
218 */
219
220#if !defined(__WXMSW__)
221static char * csquery_xpm[] = {
222"12 11 2 1",
57591e0e
JS
223" c None",
224". c #000000",
fb6261e9
JS
225" ",
226" .... ",
227" .. .. ",
228" .. .. ",
229" .. ",
230" .. ",
231" .. ",
232" ",
233" .. ",
234" .. ",
235" "};
236#endif
237
238IMPLEMENT_CLASS(wxContextHelpButton, wxBitmapButton)
239
240BEGIN_EVENT_TABLE(wxContextHelpButton, wxBitmapButton)
241 EVT_BUTTON(wxID_CONTEXT_HELP, wxContextHelpButton::OnContextHelp)
242END_EVENT_TABLE()
243
84bfc0d5
VZ
244wxContextHelpButton::wxContextHelpButton(wxWindow* parent,
245 wxWindowID id,
246 const wxPoint& pos,
247 const wxSize& size,
248 long style)
249 : wxBitmapButton(parent, id, wxBITMAP(csquery),
250 pos, size, style)
fb6261e9 251{
fb6261e9
JS
252}
253
33ac7e6f 254void wxContextHelpButton::OnContextHelp(wxCommandEvent& WXUNUSED(event))
fb6261e9 255{
57591e0e 256 wxContextHelp contextHelp(GetParent());
fb6261e9
JS
257}
258
bd83cb56
VZ
259// ----------------------------------------------------------------------------
260// wxHelpProvider
261// ----------------------------------------------------------------------------
262
263wxHelpProvider *wxHelpProvider::ms_helpProvider = (wxHelpProvider *)NULL;
264
265// trivial implementation of some methods which we don't want to make pure
266// virtual for convenience
267
268void wxHelpProvider::AddHelp(wxWindowBase * WXUNUSED(window),
269 const wxString& WXUNUSED(text))
270{
271}
272
273void wxHelpProvider::AddHelp(wxWindowID WXUNUSED(id),
274 const wxString& WXUNUSED(text))
275{
276}
277
278wxHelpProvider::~wxHelpProvider()
279{
280}
281
282// ----------------------------------------------------------------------------
283// wxSimpleHelpProvider
284// ----------------------------------------------------------------------------
285
286wxString wxSimpleHelpProvider::GetHelp(const wxWindowBase *window)
287{
288 bool wasFound;
289 wxString text = m_hashWindows.Get((long)window, &wasFound);
290 if ( !wasFound )
291 text = m_hashIds.Get(window->GetId());
292
293 return text;
294}
295
296void wxSimpleHelpProvider::AddHelp(wxWindowBase *window, const wxString& text)
297{
298 m_hashWindows.Put((long)window, text);
299}
300
301void wxSimpleHelpProvider::AddHelp(wxWindowID id, const wxString& text)
302{
303 m_hashIds.Put(id, text);
304}
305
306bool wxSimpleHelpProvider::ShowHelp(wxWindowBase *window)
307{
f38bcae5 308#if wxUSE_TIPWINDOW
173e8bbf
JS
309 static wxTipWindow* s_tipWindow = NULL;
310
311 if (s_tipWindow)
312 {
313 // Prevent s_tipWindow being nulled in OnIdle,
314 // thereby removing the chance for the window to be closed by ShowHelp
315 s_tipWindow->SetTipWindowPtr(NULL);
316 s_tipWindow->Close();
317 }
318 s_tipWindow = NULL;
319
bd83cb56
VZ
320 wxString text = GetHelp(window);
321 if ( !text.empty() )
322 {
173e8bbf 323 s_tipWindow = new wxTipWindow((wxWindow *)window, text, 100, & s_tipWindow);
bd83cb56
VZ
324
325 return TRUE;
326 }
f38bcae5 327#endif // wxUSE_TIPWINDOW
bd83cb56
VZ
328
329 return FALSE;
330}
331
5100cabf
JS
332// ----------------------------------------------------------------------------
333// wxHelpControllerHelpProvider
334// ----------------------------------------------------------------------------
335
336wxHelpControllerHelpProvider::wxHelpControllerHelpProvider(wxHelpControllerBase* hc)
337{
338 m_helpController = hc;
339}
340
341bool wxHelpControllerHelpProvider::ShowHelp(wxWindowBase *window)
342{
343 wxString text = GetHelp(window);
344 if ( !text.empty() )
345 {
346 if (m_helpController)
347 {
348 if (text.IsNumber())
349 return m_helpController->DisplayContextPopup(wxAtoi(text));
350
351 // If the help controller is capable of popping up the text...
352 else if (m_helpController->DisplayTextPopup(text, wxGetMousePosition()))
353 {
354 return TRUE;
355 }
356 else
357 // ...else use the default method.
358 return wxSimpleHelpProvider::ShowHelp(window);
359 }
360 else
361 return wxSimpleHelpProvider::ShowHelp(window);
362
363 }
364
365 return FALSE;
366}
367
368// Convenience function for turning context id into wxString
369wxString wxContextId(int id)
370{
371 return wxString(IntToString(id));
372}
373
129caadd
JS
374// ----------------------------------------------------------------------------
375// wxHelpProviderModule: module responsible for cleaning up help provider.
376// ----------------------------------------------------------------------------
377
378class wxHelpProviderModule : public wxModule
379{
380public:
381 bool OnInit();
382 void OnExit();
383
384private:
385 DECLARE_DYNAMIC_CLASS(wxHelpProviderModule)
386};
387
388IMPLEMENT_DYNAMIC_CLASS(wxHelpProviderModule, wxModule)
389
390bool wxHelpProviderModule::OnInit()
391{
392 // Probably we don't want to do anything by default,
393 // since it could pull in extra code
394 // wxHelpProvider::Set(new wxSimpleHelpProvider);
395
396 return TRUE;
397}
398
399void wxHelpProviderModule::OnExit()
400{
401 if (wxHelpProvider::Get())
402 {
403 delete wxHelpProvider::Get();
404 wxHelpProvider::Set(NULL);
405 }
406}
407
fb6261e9 408#endif // wxUSE_HELP