]> git.saurik.com Git - wxWidgets.git/blame - src/common/cshelp.cpp
switched to new XPM code in wxMSW
[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{
173e8bbf
JS
308 static wxTipWindow* s_tipWindow = NULL;
309
310 if (s_tipWindow)
311 {
312 // Prevent s_tipWindow being nulled in OnIdle,
313 // thereby removing the chance for the window to be closed by ShowHelp
314 s_tipWindow->SetTipWindowPtr(NULL);
315 s_tipWindow->Close();
316 }
317 s_tipWindow = NULL;
318
bd83cb56
VZ
319 wxString text = GetHelp(window);
320 if ( !text.empty() )
321 {
173e8bbf 322 s_tipWindow = new wxTipWindow((wxWindow *)window, text, 100, & s_tipWindow);
bd83cb56
VZ
323
324 return TRUE;
325 }
326
327 return FALSE;
328}
329
5100cabf
JS
330// ----------------------------------------------------------------------------
331// wxHelpControllerHelpProvider
332// ----------------------------------------------------------------------------
333
334wxHelpControllerHelpProvider::wxHelpControllerHelpProvider(wxHelpControllerBase* hc)
335{
336 m_helpController = hc;
337}
338
339bool wxHelpControllerHelpProvider::ShowHelp(wxWindowBase *window)
340{
341 wxString text = GetHelp(window);
342 if ( !text.empty() )
343 {
344 if (m_helpController)
345 {
346 if (text.IsNumber())
347 return m_helpController->DisplayContextPopup(wxAtoi(text));
348
349 // If the help controller is capable of popping up the text...
350 else if (m_helpController->DisplayTextPopup(text, wxGetMousePosition()))
351 {
352 return TRUE;
353 }
354 else
355 // ...else use the default method.
356 return wxSimpleHelpProvider::ShowHelp(window);
357 }
358 else
359 return wxSimpleHelpProvider::ShowHelp(window);
360
361 }
362
363 return FALSE;
364}
365
366// Convenience function for turning context id into wxString
367wxString wxContextId(int id)
368{
369 return wxString(IntToString(id));
370}
371
129caadd
JS
372// ----------------------------------------------------------------------------
373// wxHelpProviderModule: module responsible for cleaning up help provider.
374// ----------------------------------------------------------------------------
375
376class wxHelpProviderModule : public wxModule
377{
378public:
379 bool OnInit();
380 void OnExit();
381
382private:
383 DECLARE_DYNAMIC_CLASS(wxHelpProviderModule)
384};
385
386IMPLEMENT_DYNAMIC_CLASS(wxHelpProviderModule, wxModule)
387
388bool wxHelpProviderModule::OnInit()
389{
390 // Probably we don't want to do anything by default,
391 // since it could pull in extra code
392 // wxHelpProvider::Set(new wxSimpleHelpProvider);
393
394 return TRUE;
395}
396
397void wxHelpProviderModule::OnExit()
398{
399 if (wxHelpProvider::Get())
400 {
401 delete wxHelpProvider::Get();
402 wxHelpProvider::Set(NULL);
403 }
404}
405
fb6261e9 406#endif // wxUSE_HELP