]> git.saurik.com Git - wxWidgets.git/blame - src/common/cshelp.cpp
applied (slightly modified) wxToggleButton patch from John Norris and Axel Schlueter
[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 }
77d4384e
RR
170
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 }
180
181 if ((event.GetEventType() == wxEVT_PAINT) ||
182 (event.GetEventType() == wxEVT_ERASE_BACKGROUND))
183 {
184 event.Skip();
185 return FALSE;
186 }
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);
201
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
254void wxContextHelpButton::OnContextHelp(wxCommandEvent& event)
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{
308 wxString text = GetHelp(window);
309 if ( !text.empty() )
310 {
01fa3fe7 311 new wxTipWindow((wxWindow *)window, text);
bd83cb56
VZ
312
313 return TRUE;
314 }
315
316 return FALSE;
317}
318
5100cabf
JS
319// ----------------------------------------------------------------------------
320// wxHelpControllerHelpProvider
321// ----------------------------------------------------------------------------
322
323wxHelpControllerHelpProvider::wxHelpControllerHelpProvider(wxHelpControllerBase* hc)
324{
325 m_helpController = hc;
326}
327
328bool wxHelpControllerHelpProvider::ShowHelp(wxWindowBase *window)
329{
330 wxString text = GetHelp(window);
331 if ( !text.empty() )
332 {
333 if (m_helpController)
334 {
335 if (text.IsNumber())
336 return m_helpController->DisplayContextPopup(wxAtoi(text));
337
338 // If the help controller is capable of popping up the text...
339 else if (m_helpController->DisplayTextPopup(text, wxGetMousePosition()))
340 {
341 return TRUE;
342 }
343 else
344 // ...else use the default method.
345 return wxSimpleHelpProvider::ShowHelp(window);
346 }
347 else
348 return wxSimpleHelpProvider::ShowHelp(window);
349
350 }
351
352 return FALSE;
353}
354
355// Convenience function for turning context id into wxString
356wxString wxContextId(int id)
357{
358 return wxString(IntToString(id));
359}
360
129caadd
JS
361// ----------------------------------------------------------------------------
362// wxHelpProviderModule: module responsible for cleaning up help provider.
363// ----------------------------------------------------------------------------
364
365class wxHelpProviderModule : public wxModule
366{
367public:
368 bool OnInit();
369 void OnExit();
370
371private:
372 DECLARE_DYNAMIC_CLASS(wxHelpProviderModule)
373};
374
375IMPLEMENT_DYNAMIC_CLASS(wxHelpProviderModule, wxModule)
376
377bool wxHelpProviderModule::OnInit()
378{
379 // Probably we don't want to do anything by default,
380 // since it could pull in extra code
381 // wxHelpProvider::Set(new wxSimpleHelpProvider);
382
383 return TRUE;
384}
385
386void wxHelpProviderModule::OnExit()
387{
388 if (wxHelpProvider::Get())
389 {
390 delete wxHelpProvider::Get();
391 wxHelpProvider::Set(NULL);
392 }
393}
394
fb6261e9 395#endif // wxUSE_HELP