]> git.saurik.com Git - wxWidgets.git/blame - src/mac/classic/tooltip.cpp
Restore a use case that was lost with the last set of updates, using a
[wxWidgets.git] / src / mac / classic / tooltip.cpp
CommitLineData
2646f485 1/////////////////////////////////////////////////////////////////////////////
18f3decb 2// Name: src/mac/classic/tooltip.cpp
2646f485
SC
3// Purpose: wxToolTip implementation
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
65571936 7// Licence: wxWindows licence
2646f485
SC
8/////////////////////////////////////////////////////////////////////////////
9
18f3decb
WS
10#include "wx/wxprec.h"
11
12#ifdef __BORLANDC__
13 #pragma hdrstop
14#endif
2646f485
SC
15
16#if wxUSE_TOOLTIPS
17
670f9935
WS
18#include "wx/tooltip.h"
19
20#ifndef WX_PRECOMP
21 #include "wx/app.h"
cdccdfab 22 #include "wx/window.h"
da80ae71 23 #include "wx/dc.h"
c0badb70 24 #include "wx/timer.h"
670f9935
WS
25#endif
26
2646f485
SC
27#include "wx/geometry.h"
28#include "wx/mac/uma.h"
29
30//-----------------------------------------------------------------------------
31// global data
32//-----------------------------------------------------------------------------
33
34class wxMacToolTipTimer ;
35
36class wxMacToolTip
37{
38 public :
39 wxMacToolTip( ) ;
40 ~wxMacToolTip() ;
18f3decb 41
2646f485
SC
42 void Setup( WindowRef window , const wxString& text , wxPoint localPosition ) ;
43 long GetMark() { return m_mark ; }
44 void Draw() ;
45 void Clear() ;
46 bool IsShown() { return m_shown ; }
47 private :
18f3decb 48
2646f485
SC
49 wxString m_label ;
50 wxPoint m_position ;
51 Rect m_rect ;
18f3decb 52 WindowRef m_window ;
2646f485
SC
53 PicHandle m_backpict ;
54 bool m_shown ;
55 long m_mark ;
56 wxMacToolTipTimer* m_timer ;
57#if TARGET_CARBON
58 wxMacCFStringHolder m_helpTextRef ;
59#endif
60} ;
61
62class wxMacToolTipTimer : public wxTimer
63{
64public:
65 wxMacToolTipTimer() {} ;
66 wxMacToolTipTimer(wxMacToolTip* tip, int iMilliseconds) ;
67 virtual ~wxMacToolTipTimer() {} ;
68 void Notify()
69 {
70 if ( m_mark == m_tip->GetMark() )
18f3decb 71 m_tip->Draw() ;
2646f485
SC
72 }
73protected:
74 wxMacToolTip* m_tip;
75 long m_mark ;
76};
77
78//-----------------------------------------------------------------------------
79// wxToolTip
80//-----------------------------------------------------------------------------
81static long s_ToolTipDelay = 500 ;
82static bool s_ShowToolTips = true ;
83static wxMacToolTip s_ToolTip ;
84static wxWindow* s_LastWindowEntered = NULL ;
85static wxRect2DInt s_ToolTipArea ;
86static WindowRef s_ToolTipWindowRef = NULL ;
87
88IMPLEMENT_ABSTRACT_CLASS(wxToolTip, wxObject)
89
90wxToolTip::wxToolTip( const wxString &tip )
91{
92 m_text = tip;
93 m_window = (wxWindow*) NULL;
94}
95
96wxToolTip::~wxToolTip()
97{
98}
99
100void wxToolTip::SetTip( const wxString &tip )
101{
102 m_text = tip;
18f3decb 103
2646f485
SC
104 if ( m_window )
105 {
106 /*
107 // update it immediately
108 wxToolInfo ti(GetHwndOf(m_window));
109 ti.lpszText = (wxChar *)m_text.c_str();
18f3decb 110
2646f485
SC
111 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, 0, &ti);
112 */
113 }
114}
115
116void wxToolTip::SetWindow( wxWindow *win )
117{
118 m_window = win ;
119}
120
121void wxToolTip::Enable( bool flag )
122{
123 if ( s_ShowToolTips != flag )
124 {
125 s_ShowToolTips = flag ;
126 if ( s_ShowToolTips )
127 {
128 }
129 else
130 {
131 s_ToolTip.Clear() ;
132 }
133 }
134}
135
136void wxToolTip::SetDelay( long msecs )
137{
138 s_ToolTipDelay = msecs ;
139}
140
141void wxToolTip::RelayEvent( wxWindow *win , wxMouseEvent &event )
142{
143 if ( s_ShowToolTips )
144 {
145 if ( event.GetEventType() == wxEVT_LEAVE_WINDOW )
146 {
147 s_ToolTip.Clear() ;
148 }
149 else if (event.GetEventType() == wxEVT_ENTER_WINDOW || event.GetEventType() == wxEVT_MOTION )
150 {
151 wxPoint2DInt where( event.m_x , event.m_y ) ;
152 if ( s_LastWindowEntered == win && s_ToolTipArea.Contains( where ) )
153 {
154 }
155 else
156 {
157 s_ToolTip.Clear() ;
158 s_ToolTipArea = wxRect2DInt( event.m_x - 2 , event.m_y - 2 , 4 , 4 ) ;
159 s_LastWindowEntered = win ;
18f3decb 160
2646f485
SC
161 WindowRef window = MAC_WXHWND( win->MacGetRootWindow() ) ;
162 int x = event.m_x ;
163 int y = event.m_y ;
164 wxPoint local( x , y ) ;
165 win->MacClientToRootWindow( &x, &y ) ;
166 wxPoint windowlocal( x , y ) ;
167 s_ToolTip.Setup( window , win->MacGetToolTipString( local ) , windowlocal ) ;
168 }
169 }
170 }
171}
172
173void wxToolTip::RemoveToolTips()
174{
175 s_ToolTip.Clear() ;
176}
177// --- mac specific
178
179wxMacToolTipTimer::wxMacToolTipTimer( wxMacToolTip *tip , int msec )
180{
181 m_tip = tip;
182 m_mark = tip->GetMark() ;
183 Start(msec, true);
184}
185
186wxMacToolTip::wxMacToolTip()
187{
188 m_window = NULL ;
189 m_backpict = NULL ;
190 m_mark = 0 ;
191 m_shown = false ;
192 m_timer = NULL ;
193}
194
18f3decb 195void wxMacToolTip::Setup( WindowRef win , const wxString& text , wxPoint localPosition )
2646f485
SC
196{
197 m_mark++ ;
198 Clear() ;
199 m_position = localPosition ;
200 m_label = text ;
201 m_window =win;
202 s_ToolTipWindowRef = m_window ;
203 m_backpict = NULL ;
204 if ( m_timer )
205 delete m_timer ;
206 m_timer = new wxMacToolTipTimer( this , s_ToolTipDelay ) ;
207}
208
18f3decb 209wxMacToolTip::~wxMacToolTip()
2646f485
SC
210{
211 if ( m_timer ) {
212 delete m_timer ;
213 m_timer = NULL;
214 }
18f3decb 215 if ( m_backpict )
2646f485
SC
216 Clear() ;
217}
218
219const short kTipBorder = 2 ;
220const short kTipOffset = 5 ;
221
222void wxMacToolTip::Draw()
223{
670f9935 224 if ( m_label.empty() )
2646f485 225 return ;
18f3decb 226
2646f485
SC
227 if ( m_window == s_ToolTipWindowRef )
228 {
229 m_shown = true ;
230#if TARGET_CARBON
231 HMHelpContentRec tag ;
232 tag.version = kMacHelpVersion;
233 SetRect( &tag.absHotRect , m_position.x - 2 , m_position.y - 2 , m_position.x + 2 , m_position.y + 2 ) ;
234 GrafPtr port ;
235 GetPort( &port ) ;
236 SetPortWindowPort(m_window) ;
237 LocalToGlobal( (Point *) &tag.absHotRect.top );
238 LocalToGlobal( (Point *) &tag.absHotRect.bottom );
239 SetPort( port );
240 m_helpTextRef.Assign( m_label , wxFONTENCODING_DEFAULT ) ;
241 tag.content[kHMMinimumContentIndex].contentType = kHMCFStringContent ;
242 tag.content[kHMMinimumContentIndex].u.tagCFString = m_helpTextRef ;
243 tag.content[kHMMaximumContentIndex].contentType = kHMCFStringContent ;
244 tag.content[kHMMaximumContentIndex].u.tagCFString = m_helpTextRef ;
245 tag.tagSide = kHMDefaultSide;
246 HMDisplayTag( &tag );
247#else
248 wxMacPortStateHelper help( (GrafPtr) GetWindowPort( m_window ) );
249 FontFamilyID fontId ;
250 Str255 fontName ;
251 SInt16 fontSize ;
252 Style fontStyle ;
253 GetThemeFont(kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
254 GetFNum( fontName, &fontId );
18f3decb 255
2646f485
SC
256 TextFont( fontId ) ;
257 TextSize( fontSize ) ;
258 TextFace( fontStyle ) ;
259 FontInfo fontInfo;
260 ::GetFontInfo(&fontInfo);
261 short lineh = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
262 short height = 0 ;
18f3decb 263
2646f485 264 int i = 0 ;
670f9935 265 int length = m_label.length() ;
2646f485
SC
266 int width = 0 ;
267 int thiswidth = 0 ;
268 int laststop = 0 ;
269 wxCharBuffer text = m_label.mb_str( wxConvLocal) ;
270
271 while( i < length )
272 {
273 if( text[i] == 13 || text[i] == 10)
274 {
275 thiswidth = ::TextWidth( text , laststop , i - laststop ) ;
276 if ( thiswidth > width )
277 width = thiswidth ;
18f3decb 278
2646f485
SC
279 height += lineh ;
280 laststop = i+1 ;
281 }
282 i++ ;
283 }
284 if ( i - laststop > 0 )
285 {
286 thiswidth = ::TextWidth( text , laststop , i - laststop ) ;
287 if ( thiswidth > width )
288 width = thiswidth ;
289 height += lineh ;
290 }
18f3decb 291
2646f485
SC
292 m_rect.left = m_position.x + kTipOffset;
293 m_rect.top = m_position.y + kTipOffset;
294 m_rect.right = m_rect.left + width + 2 * kTipBorder;
295
296 m_rect.bottom = m_rect.top + height + 2 * kTipBorder;
297 Rect r ;
298 GetPortBounds( GetWindowPort( m_window ) , &r ) ;
299 if ( m_rect.top < 0 )
300 {
301 m_rect.bottom += -m_rect.top ;
302 m_rect.top = 0 ;
303 }
304 if ( m_rect.left < 0 )
305 {
306 m_rect.right += -m_rect.left ;
307 m_rect.left = 0 ;
308 }
309 if ( m_rect.right > r.right )
310 {
311 m_rect.left -= (m_rect.right - r.right ) ;
312 m_rect.right = r.right ;
313 }
314 if ( m_rect.bottom > r.bottom )
315 {
316 m_rect.top -= (m_rect.bottom - r.bottom) ;
317 m_rect.bottom = r.bottom ;
318 }
319 ClipRect( &m_rect ) ;
320 BackColor( whiteColor ) ;
321 ForeColor(blackColor ) ;
18f3decb 322 GWorldPtr port ;
2646f485
SC
323 NewGWorld( &port , wxDisplayDepth() , &m_rect , NULL , NULL , 0 ) ;
324 CGrafPtr origPort ;
325 GDHandle origDevice ;
18f3decb 326
2646f485
SC
327 GetGWorld( &origPort , &origDevice ) ;
328 SetGWorld( port , NULL ) ;
18f3decb 329
2646f485 330 m_backpict = OpenPicture(&m_rect);
18f3decb
WS
331
332 CopyBits(GetPortBitMapForCopyBits(GetWindowPort(m_window)),
333 GetPortBitMapForCopyBits(port),
334 &m_rect,
335 &m_rect,
336 srcCopy,
2646f485
SC
337 NULL);
338 ClosePicture();
339 SetGWorld( origPort , origDevice ) ;
340 DisposeGWorld( port ) ;
341 PenNormal() ;
18f3decb 342
2646f485
SC
343 RGBColor tooltipbackground = { 0xFFFF , 0xFFFF , 0xC000 } ;
344 BackColor( whiteColor ) ;
345 RGBForeColor( &tooltipbackground ) ;
18f3decb 346
2646f485
SC
347 PaintRect( &m_rect ) ;
348 ForeColor(blackColor ) ;
349 FrameRect( &m_rect ) ;
350 SetThemeTextColor(kThemeTextColorNotification,wxDisplayDepth(),true) ;
351 ::MoveTo( m_rect.left + kTipBorder , m_rect.top + fontInfo.ascent + kTipBorder);
18f3decb 352
2646f485
SC
353 i = 0 ;
354 laststop = 0 ;
355 height = 0 ;
18f3decb 356
2646f485
SC
357 while( i < length )
358 {
359 if( text[i] == 13 || text[i] == 10)
360 {
361 ::DrawText( text , laststop , i - laststop ) ;
362 height += lineh ;
363 ::MoveTo( m_rect.left + kTipBorder , m_rect.top + fontInfo.ascent + kTipBorder + height );
364 laststop = i+1 ;
365 }
366 i++ ;
367 }
368 ::DrawText( text , laststop , i - laststop ) ;
18f3decb 369 ::TextMode( srcOr ) ;
2646f485
SC
370#endif
371 }
372}
373
18f3decb 374void wxToolTip::NotifyWindowDelete( WXHWND win )
2646f485
SC
375{
376 if ( win == s_ToolTipWindowRef )
377 {
378 s_ToolTipWindowRef = NULL ;
379 }
380}
381
382void wxMacToolTip::Clear()
383{
384 m_mark++ ;
385 if ( m_timer )
386 {
387 delete m_timer ;
388 m_timer = NULL ;
389 }
390 if ( !m_shown )
391 return ;
392#if TARGET_CARBON
393 HMHideTag() ;
394 m_helpTextRef.Release() ;
18f3decb 395#else
2646f485
SC
396 if ( m_window == s_ToolTipWindowRef && m_backpict )
397 {
398 wxMacPortStateHelper help( (GrafPtr) GetWindowPort(m_window) ) ;
399
400 m_shown = false ;
401
402 BackColor( whiteColor ) ;
403 ForeColor(blackColor ) ;
404 DrawPicture(m_backpict, &m_rect);
405 KillPicture(m_backpict);
406 m_backpict = NULL ;
407 }
408#endif
409}
410
cdccdfab 411#endif // wxUSE_TOOLTIPS