]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/tooltip.cpp
minimize overlay area to avoid eg scrolling artifacts when using a caret
[wxWidgets.git] / src / mac / carbon / tooltip.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/tooltip.cpp
3 // Purpose: wxToolTip implementation
4 // Author: Stefan Csomor
5 // Id: $Id$
6 // Copyright: (c) Stefan Csomor
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 #include "wx/wxprec.h"
11
12 #if wxUSE_TOOLTIPS
13
14 #include "wx/tooltip.h"
15
16 #ifndef WX_PRECOMP
17 #include "wx/app.h"
18 #include "wx/window.h"
19 #include "wx/dc.h"
20 #include "wx/timer.h"
21 #endif // WX_PRECOMP
22
23 #include "wx/geometry.h"
24 #include "wx/mac/uma.h"
25
26 //-----------------------------------------------------------------------------
27 // global data
28 //-----------------------------------------------------------------------------
29
30 class wxMacToolTipTimer ;
31
32 class wxMacToolTip
33 {
34 public :
35 wxMacToolTip() ;
36 ~wxMacToolTip() ;
37
38 void Setup( WindowRef window , const wxString& text , const wxPoint& localPosition ) ;
39 void Draw() ;
40 void Clear() ;
41
42 long GetMark()
43 { return m_mark ; }
44
45 bool IsShown()
46 { return m_shown ; }
47
48 private :
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 #if wxUSE_TIMER
57 wxMacToolTipTimer* m_timer ;
58 #endif
59 #if TARGET_CARBON
60 wxMacCFStringHolder m_helpTextRef ;
61 #endif
62 } ;
63
64 #if wxUSE_TIMER
65 class wxMacToolTipTimer : public wxTimer
66 {
67 public:
68 wxMacToolTipTimer(wxMacToolTip* tip, int iMilliseconds) ;
69 wxMacToolTipTimer() {} ;
70 virtual ~wxMacToolTipTimer() {} ;
71
72 void Notify()
73 {
74 if ( m_mark == m_tip->GetMark() )
75 m_tip->Draw() ;
76 }
77
78 protected:
79 wxMacToolTip* m_tip;
80 long m_mark ;
81 };
82 #endif // wxUSE_TIMER
83
84 //-----------------------------------------------------------------------------
85 // wxToolTip
86 //-----------------------------------------------------------------------------
87 static long s_ToolTipDelay = 500 ;
88 static bool s_ShowToolTips = true ;
89 static wxMacToolTip s_ToolTip ;
90 static wxWindow* s_LastWindowEntered = NULL ;
91 static wxRect2DInt s_ToolTipArea ;
92 static WindowRef s_ToolTipWindowRef = NULL ;
93
94 IMPLEMENT_ABSTRACT_CLASS(wxToolTip, wxObject)
95
96
97 wxToolTip::wxToolTip( const wxString &tip )
98 {
99 m_text = tip;
100 m_window = (wxWindow*) NULL;
101 }
102
103 wxToolTip::~wxToolTip()
104 {
105 }
106
107 void wxToolTip::SetTip( const wxString &tip )
108 {
109 m_text = tip;
110
111 if ( m_window )
112 {
113 #if 0
114 // update it immediately
115 wxToolInfo ti(GetHwndOf(m_window));
116 ti.lpszText = (wxChar *)m_text.c_str();
117
118 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, 0, &ti);
119 #endif
120 }
121 }
122
123 void wxToolTip::SetWindow( wxWindow *win )
124 {
125 m_window = win ;
126 }
127
128 void wxToolTip::Enable( bool flag )
129 {
130 if ( s_ShowToolTips != flag )
131 {
132 s_ShowToolTips = flag ;
133
134 if ( s_ShowToolTips )
135 {
136 }
137 else
138 {
139 s_ToolTip.Clear() ;
140 }
141 }
142 }
143
144 void wxToolTip::SetDelay( long msecs )
145 {
146 s_ToolTipDelay = msecs ;
147 }
148
149 void wxToolTip::RelayEvent( wxWindow *win , wxMouseEvent &event )
150 {
151 if ( s_ShowToolTips )
152 {
153 if ( event.GetEventType() == wxEVT_LEAVE_WINDOW )
154 {
155 s_ToolTip.Clear() ;
156 }
157 else if (event.GetEventType() == wxEVT_ENTER_WINDOW || event.GetEventType() == wxEVT_MOTION )
158 {
159 wxPoint2DInt where( event.m_x , event.m_y ) ;
160 if ( s_LastWindowEntered == win && s_ToolTipArea.Contains( where ) )
161 {
162 }
163 else
164 {
165 s_ToolTip.Clear() ;
166 s_ToolTipArea = wxRect2DInt( event.m_x - 2 , event.m_y - 2 , 4 , 4 ) ;
167 s_LastWindowEntered = win ;
168
169 WindowRef window = MAC_WXHWND( win->MacGetTopLevelWindowRef() ) ;
170 int x = event.m_x ;
171 int y = event.m_y ;
172 wxPoint local( x , y ) ;
173 win->MacClientToRootWindow( &x, &y ) ;
174 wxPoint windowlocal( x , y ) ;
175 s_ToolTip.Setup( window , win->MacGetToolTipString( local ) , windowlocal ) ;
176 }
177 }
178 }
179 }
180
181 void wxToolTip::RemoveToolTips()
182 {
183 s_ToolTip.Clear() ;
184 }
185
186 // --- mac specific
187 #if wxUSE_TIMER
188 wxMacToolTipTimer::wxMacToolTipTimer( wxMacToolTip *tip , int msec )
189 {
190 m_tip = tip;
191 m_mark = tip->GetMark() ;
192 Start(msec, true);
193 }
194 #endif // wxUSE_TIMER
195
196 wxMacToolTip::wxMacToolTip()
197 {
198 m_window = NULL ;
199 m_backpict = NULL ;
200 #if wxUSE_TIMER
201 m_timer = NULL ;
202 #endif
203 m_mark = 0 ;
204 m_shown = false ;
205 }
206
207 void wxMacToolTip::Setup( WindowRef win , const wxString& text , const wxPoint& localPosition )
208 {
209 m_mark++ ;
210
211 Clear() ;
212 m_position = localPosition ;
213 m_label = text ;
214 m_window =win;
215 s_ToolTipWindowRef = m_window ;
216 m_backpict = NULL ;
217 #if wxUSE_TIMER
218 if ( m_timer )
219 delete m_timer ;
220
221 m_timer = new wxMacToolTipTimer( this , s_ToolTipDelay ) ;
222 #endif // wxUSE_TIMER
223 }
224
225 wxMacToolTip::~wxMacToolTip()
226 {
227 #if wxUSE_TIMER
228 if ( m_timer )
229 {
230 delete m_timer ;
231 m_timer = NULL;
232 }
233 #endif // wxUSE_TIMER
234 if ( m_backpict )
235 Clear() ;
236 }
237
238 const short kTipBorder = 2 ;
239 const short kTipOffset = 5 ;
240
241 void wxMacToolTip::Draw()
242 {
243 if ( m_label.empty() )
244 return ;
245
246 if ( m_window == s_ToolTipWindowRef )
247 {
248 m_shown = true ;
249
250 HMHelpContentRec tag ;
251 tag.version = kMacHelpVersion;
252
253 Point p = { m_position.y , m_position.x };
254 wxMacLocalToGlobal( m_window , &p ) ;
255 SetRect( &tag.absHotRect , p.h - 2 , p.v - 2 , p.h + 2 , p.v + 2 );
256
257 m_helpTextRef.Assign( m_label , wxFONTENCODING_DEFAULT ) ;
258 tag.content[kHMMinimumContentIndex].contentType = kHMCFStringContent ;
259 tag.content[kHMMinimumContentIndex].u.tagCFString = m_helpTextRef ;
260 tag.content[kHMMaximumContentIndex].contentType = kHMCFStringContent ;
261 tag.content[kHMMaximumContentIndex].u.tagCFString = m_helpTextRef ;
262 tag.tagSide = kHMDefaultSide;
263 HMDisplayTag( &tag );
264 }
265 }
266
267 void wxToolTip::NotifyWindowDelete( WXHWND win )
268 {
269 if ( win == s_ToolTipWindowRef )
270 s_ToolTipWindowRef = NULL ;
271 }
272
273 void wxMacToolTip::Clear()
274 {
275 m_mark++ ;
276 #if wxUSE_TIMER
277 if ( m_timer )
278 {
279 delete m_timer ;
280 m_timer = NULL ;
281 }
282 #endif // wxUSE_TIMER
283 if ( !m_shown )
284 return ;
285
286 HMHideTag() ;
287 m_helpTextRef.Release() ;
288 }
289
290 #endif // wxUSE_TOOLTIPS