]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/classic/tooltip.cpp
don't create non-existing groups in HasEntry()
[wxWidgets.git] / src / mac / classic / tooltip.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/mac/classic/tooltip.cpp
3// Purpose: wxToolTip implementation
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10#include "wx/wxprec.h"
11
12#ifdef __BORLANDC__
13 #pragma hdrstop
14#endif
15
16#if wxUSE_TOOLTIPS
17
18#include "wx/tooltip.h"
19
20#ifndef WX_PRECOMP
21 #include "wx/app.h"
22 #include "wx/window.h"
23 #include "wx/dc.h"
24 #include "wx/timer.h"
25#endif
26
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() ;
41
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 :
48
49 wxString m_label ;
50 wxPoint m_position ;
51 Rect m_rect ;
52 WindowRef m_window ;
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() )
71 m_tip->Draw() ;
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;
103
104 if ( m_window )
105 {
106 /*
107 // update it immediately
108 wxToolInfo ti(GetHwndOf(m_window));
109 ti.lpszText = (wxChar *)m_text.c_str();
110
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 ;
160
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
195void wxMacToolTip::Setup( WindowRef win , const wxString& text , wxPoint localPosition )
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
209wxMacToolTip::~wxMacToolTip()
210{
211 if ( m_timer ) {
212 delete m_timer ;
213 m_timer = NULL;
214 }
215 if ( m_backpict )
216 Clear() ;
217}
218
219const short kTipBorder = 2 ;
220const short kTipOffset = 5 ;
221
222void wxMacToolTip::Draw()
223{
224 if ( m_label.empty() )
225 return ;
226
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 );
255
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 ;
263
264 int i = 0 ;
265 int length = m_label.length() ;
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 ;
278
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 }
291
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 ) ;
322 GWorldPtr port ;
323 NewGWorld( &port , wxDisplayDepth() , &m_rect , NULL , NULL , 0 ) ;
324 CGrafPtr origPort ;
325 GDHandle origDevice ;
326
327 GetGWorld( &origPort , &origDevice ) ;
328 SetGWorld( port , NULL ) ;
329
330 m_backpict = OpenPicture(&m_rect);
331
332 CopyBits(GetPortBitMapForCopyBits(GetWindowPort(m_window)),
333 GetPortBitMapForCopyBits(port),
334 &m_rect,
335 &m_rect,
336 srcCopy,
337 NULL);
338 ClosePicture();
339 SetGWorld( origPort , origDevice ) ;
340 DisposeGWorld( port ) ;
341 PenNormal() ;
342
343 RGBColor tooltipbackground = { 0xFFFF , 0xFFFF , 0xC000 } ;
344 BackColor( whiteColor ) ;
345 RGBForeColor( &tooltipbackground ) ;
346
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);
352
353 i = 0 ;
354 laststop = 0 ;
355 height = 0 ;
356
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 ) ;
369 ::TextMode( srcOr ) ;
370#endif
371 }
372}
373
374void wxToolTip::NotifyWindowDelete( WXHWND win )
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() ;
395#else
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
411#endif // wxUSE_TOOLTIPS