1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/cshelp.cpp
3 // Purpose: Context sensitive help class implementation
4 // Author: Julian Smart, Vadim Zeitlin
8 // Copyright: (c) 2000 Julian Smart, Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
17 #pragma implementation "cshelp.h"
20 // ----------------------------------------------------------------------------
22 // ----------------------------------------------------------------------------
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
36 #include "wx/tipwin.h"
38 #include "wx/module.h"
39 #include "wx/cshelp.h"
41 // ----------------------------------------------------------------------------
42 // wxContextHelpEvtHandler private class
43 // ----------------------------------------------------------------------------
45 // This class exists in order to eat events until the left mouse button is
47 class wxContextHelpEvtHandler
: public wxEvtHandler
50 wxContextHelpEvtHandler(wxContextHelp
* contextHelp
)
52 m_contextHelp
= contextHelp
;
55 virtual bool ProcessEvent(wxEvent
& event
);
58 wxContextHelp
* m_contextHelp
;
61 // ============================================================================
63 // ============================================================================
65 // ----------------------------------------------------------------------------
67 // ----------------------------------------------------------------------------
70 * Invokes context-sensitive help
74 IMPLEMENT_DYNAMIC_CLASS(wxContextHelp
, wxObject
)
76 wxContextHelp::wxContextHelp(wxWindow
* win
, bool beginHelp
)
81 BeginContextHelp(win
);
84 wxContextHelp::~wxContextHelp()
90 // Not currently needed, but on some systems capture may not work as
91 // expected so we'll leave it here for now.
93 static void wxPushOrPopEventHandlers(wxContextHelp
* help
, wxWindow
* win
, bool push
)
96 win
->PushEventHandler(new wxContextHelpEvtHandler(help
));
98 win
->PopEventHandler();
100 wxNode
* node
= win
->GetChildren().First();
103 wxWindow
* child
= (wxWindow
*) node
->Data();
104 wxPushOrPopEventHandlers(help
, child
, push
);
111 // Begin 'context help mode'
112 bool wxContextHelp::BeginContextHelp(wxWindow
* win
)
115 win
= wxTheApp
->GetTopWindow();
119 wxCursor
cursor(wxCURSOR_QUESTION_ARROW
);
120 wxCursor oldCursor
= win
->GetCursor();
121 win
->SetCursor(cursor
);
124 // wxSetCursor(cursor);
129 win
->PushEventHandler(new wxContextHelpEvtHandler(this));
130 //wxPushOrPopEventHandlers(this, win, TRUE);
138 win
->PopEventHandler(TRUE
);
139 //wxPushOrPopEventHandlers(this, win, FALSE);
141 win
->SetCursor(oldCursor
);
146 wxWindow
* winAtPtr
= wxFindWindowAtPointer(pt
);
151 msg.Printf("Picked %s (%d)", (const char*) winAtPtr->GetName(), winAtPtr->GetId());
157 DispatchEvent(winAtPtr
, pt
);
163 bool wxContextHelp::EndContextHelp()
170 bool wxContextHelp::EventLoop()
176 if (wxTheApp
->Pending())
178 wxTheApp
->Dispatch();
182 wxTheApp
->ProcessIdle();
189 bool wxContextHelpEvtHandler::ProcessEvent(wxEvent
& event
)
191 if (event
.GetEventType() == wxEVT_LEFT_DOWN
)
193 m_contextHelp
->SetStatus(TRUE
);
194 m_contextHelp
->EndContextHelp();
198 if ((event
.GetEventType() == wxEVT_CHAR
) ||
199 (event
.GetEventType() == wxEVT_KEY_DOWN
) ||
200 (event
.GetEventType() == wxEVT_ACTIVATE
) ||
201 (event
.GetEventType() == wxEVT_MOUSE_CAPTURE_CHANGED
))
203 // May have already been set to TRUE by a left-click
204 //m_contextHelp->SetStatus(FALSE);
205 m_contextHelp
->EndContextHelp();
209 if ((event
.GetEventType() == wxEVT_PAINT
) ||
210 (event
.GetEventType() == wxEVT_ERASE_BACKGROUND
))
219 // Dispatch the help event to the relevant window
220 bool wxContextHelp::DispatchEvent(wxWindow
* win
, const wxPoint
& pt
)
222 wxWindow
* subjectOfHelp
= win
;
223 bool eventProcessed
= FALSE
;
224 while (subjectOfHelp
&& !eventProcessed
)
226 wxHelpEvent
helpEvent(wxEVT_HELP
, subjectOfHelp
->GetId(), pt
) ;
227 helpEvent
.SetEventObject(this);
229 eventProcessed
= win
->GetEventHandler()->ProcessEvent(helpEvent
);
231 // Go up the window hierarchy until the event is handled (or not).
232 // I.e. keep submitting ancestor windows until one is recognised
233 // by the app code that processes the ids and displays help.
234 subjectOfHelp
= subjectOfHelp
->GetParent();
236 return eventProcessed
;
239 // ----------------------------------------------------------------------------
240 // wxContextHelpButton
241 // ----------------------------------------------------------------------------
244 * wxContextHelpButton
245 * You can add this to your dialogs (especially on non-Windows platforms)
246 * to put the application into context help mode.
249 #if !defined(__WXMSW__)
250 static const char * csquery_xpm
[] = {
267 IMPLEMENT_CLASS(wxContextHelpButton
, wxBitmapButton
)
269 BEGIN_EVENT_TABLE(wxContextHelpButton
, wxBitmapButton
)
270 EVT_BUTTON(wxID_CONTEXT_HELP
, wxContextHelpButton::OnContextHelp
)
273 wxContextHelpButton::wxContextHelpButton(wxWindow
* parent
,
278 #if defined(__WXPM__)
279 : wxBitmapButton(parent
, id
, wxBitmap(wxCSQUERY_BITMAP
280 ,wxBITMAP_TYPE_RESOURCE
284 : wxBitmapButton(parent
, id
, wxBITMAP(csquery
),
290 void wxContextHelpButton::OnContextHelp(wxCommandEvent
& WXUNUSED(event
))
292 wxContextHelp
contextHelp(GetParent());
295 // ----------------------------------------------------------------------------
297 // ----------------------------------------------------------------------------
299 wxHelpProvider
*wxHelpProvider::ms_helpProvider
= (wxHelpProvider
*)NULL
;
301 // trivial implementation of some methods which we don't want to make pure
302 // virtual for convenience
304 void wxHelpProvider::AddHelp(wxWindowBase
* WXUNUSED(window
),
305 const wxString
& WXUNUSED(text
))
309 void wxHelpProvider::AddHelp(wxWindowID
WXUNUSED(id
),
310 const wxString
& WXUNUSED(text
))
314 // removes the association
315 void wxHelpProvider::RemoveHelp(wxWindowBase
* WXUNUSED(window
))
319 wxHelpProvider::~wxHelpProvider()
323 // ----------------------------------------------------------------------------
324 // wxSimpleHelpProvider
325 // ----------------------------------------------------------------------------
327 wxString
wxSimpleHelpProvider::GetHelp(const wxWindowBase
*window
)
330 wxString text
= m_hashWindows
.Get((long)window
, &wasFound
);
332 text
= m_hashIds
.Get(window
->GetId());
337 void wxSimpleHelpProvider::AddHelp(wxWindowBase
*window
, const wxString
& text
)
339 m_hashWindows
.Delete((long)window
);
340 m_hashWindows
.Put((long)window
, text
);
343 void wxSimpleHelpProvider::AddHelp(wxWindowID id
, const wxString
& text
)
345 m_hashIds
.Delete((long)id
);
346 m_hashIds
.Put(id
, text
);
349 // removes the association
350 void wxSimpleHelpProvider::RemoveHelp(wxWindowBase
* window
)
352 m_hashWindows
.Delete((long)window
);
355 bool wxSimpleHelpProvider::ShowHelp(wxWindowBase
*window
)
358 static wxTipWindow
* s_tipWindow
= NULL
;
362 // Prevent s_tipWindow being nulled in OnIdle,
363 // thereby removing the chance for the window to be closed by ShowHelp
364 s_tipWindow
->SetTipWindowPtr(NULL
);
365 s_tipWindow
->Close();
369 wxString text
= GetHelp(window
);
372 s_tipWindow
= new wxTipWindow((wxWindow
*)window
, text
, 100, & s_tipWindow
);
376 #endif // wxUSE_TIPWINDOW
381 // ----------------------------------------------------------------------------
382 // wxHelpControllerHelpProvider
383 // ----------------------------------------------------------------------------
385 wxHelpControllerHelpProvider::wxHelpControllerHelpProvider(wxHelpControllerBase
* hc
)
387 m_helpController
= hc
;
390 bool wxHelpControllerHelpProvider::ShowHelp(wxWindowBase
*window
)
392 wxString text
= GetHelp(window
);
395 if (m_helpController
)
398 return m_helpController
->DisplayContextPopup(wxAtoi(text
));
400 // If the help controller is capable of popping up the text...
401 else if (m_helpController
->DisplayTextPopup(text
, wxGetMousePosition()))
406 // ...else use the default method.
407 return wxSimpleHelpProvider::ShowHelp(window
);
410 return wxSimpleHelpProvider::ShowHelp(window
);
417 // Convenience function for turning context id into wxString
418 wxString
wxContextId(int id
)
420 return wxString(IntToString(id
));
423 // ----------------------------------------------------------------------------
424 // wxHelpProviderModule: module responsible for cleaning up help provider.
425 // ----------------------------------------------------------------------------
427 class wxHelpProviderModule
: public wxModule
434 DECLARE_DYNAMIC_CLASS(wxHelpProviderModule
)
437 IMPLEMENT_DYNAMIC_CLASS(wxHelpProviderModule
, wxModule
)
439 bool wxHelpProviderModule::OnInit()
441 // Probably we don't want to do anything by default,
442 // since it could pull in extra code
443 // wxHelpProvider::Set(new wxSimpleHelpProvider);
448 void wxHelpProviderModule::OnExit()
450 if (wxHelpProvider::Get())
452 delete wxHelpProvider::Get();
453 wxHelpProvider::Set(NULL
);