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