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