]> git.saurik.com Git - wxWidgets.git/blob - src/mac/tooltip.cpp
added a call for invalidating the dc setup on mac explicitely (needed in case of...
[wxWidgets.git] / src / mac / tooltip.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #ifdef __GNUG__
11 #pragma implementation "tooltip.h"
12 #endif
13
14 #include "wx/setup.h"
15
16 #if wxUSE_TOOLTIPS
17
18 #include "wx/app.h"
19 #include "wx/window.h"
20 #include "wx/tooltip.h"
21 #include "wx/timer.h"
22 #include "wx/geometry.h"
23 #include "wx/mac/aga.h"
24 #include "wx/mac/uma.h"
25
26 //-----------------------------------------------------------------------------
27 // global data
28 //-----------------------------------------------------------------------------
29
30 class wxMacToolTip
31 {
32 public :
33 wxMacToolTip( ) ;
34 ~wxMacToolTip() ;
35
36 void Setup( WindowRef window , wxString text , wxPoint localPosition ) ;
37 long GetMark() { return m_mark ; }
38 void Draw() ;
39 void Clear() ;
40 bool IsShown() { return m_shown ; }
41 private :
42
43 wxString m_label ;
44 wxPoint m_position ;
45 Rect m_rect ;
46 WindowRef m_window ;
47 PicHandle m_backpict ;
48 bool m_shown ;
49 long m_mark ;
50 } ;
51
52 class wxMacToolTipTimer : wxTimer
53 {
54 public:
55 wxMacToolTipTimer(wxMacToolTip* tip, int iMilliseconds) ;
56
57 void Notify()
58 {
59 if ( m_mark == m_tip->GetMark() )
60 m_tip->Draw() ;
61
62 delete this;
63 }
64
65 protected:
66 wxMacToolTip* m_tip;
67 long m_mark ;
68 };
69
70 //-----------------------------------------------------------------------------
71 // wxToolTip
72 //-----------------------------------------------------------------------------
73 static long s_ToolTipDelay = 500 ;
74 static bool s_ShowToolTips = true ;
75 static wxMacToolTip s_ToolTip ;
76 static wxWindow* s_LastWindowEntered = NULL ;
77 static wxRect2DInt s_ToolTipArea ;
78 static WindowRef s_ToolTipWindowRef = NULL ;
79 wxToolTip::wxToolTip( const wxString &tip )
80 {
81 m_text = tip;
82 m_window = (wxWindow*) NULL;
83 }
84
85 wxToolTip::~wxToolTip()
86 {
87 }
88
89 void wxToolTip::SetTip( const wxString &tip )
90 {
91 m_text = tip;
92
93 if ( m_window )
94 {
95 /*
96 // update it immediately
97 wxToolInfo ti(GetHwndOf(m_window));
98 ti.lpszText = (wxChar *)m_text.c_str();
99
100 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, 0, &ti);
101 */
102 }
103 }
104
105 void wxToolTip::SetWindow( wxWindow *win )
106 {
107 m_window = win;
108 }
109
110 void wxToolTip::Enable( bool flag )
111 {
112 if ( s_ShowToolTips != flag )
113 {
114 s_ShowToolTips = flag ;
115 if ( s_ShowToolTips )
116 {
117 }
118 else
119 {
120 s_ToolTip.Clear() ;
121 }
122 }
123 }
124
125 void wxToolTip::SetDelay( long msecs )
126 {
127 s_ToolTipDelay = msecs ;
128 }
129
130 void wxToolTip::RelayEvent( wxWindow *win , wxMouseEvent &event )
131 {
132 if ( s_ShowToolTips )
133 {
134 if ( event.GetEventType() == wxEVT_LEAVE_WINDOW )
135 {
136 s_ToolTip.Clear() ;
137 }
138 else if (event.GetEventType() == wxEVT_ENTER_WINDOW || event.GetEventType() == wxEVT_MOTION )
139 {
140 wxPoint2DInt where( event.m_x , event.m_y ) ;
141 if ( s_LastWindowEntered == win && s_ToolTipArea.Contains( where ) )
142 {
143 }
144 else
145 {
146 s_ToolTip.Clear() ;
147 s_ToolTipArea = wxRect2DInt( event.m_x - 2 , event.m_y - 2 , 4 , 4 ) ;
148 s_LastWindowEntered = win ;
149
150 WindowRef window = win->GetMacRootWindow() ;
151 int x = event.m_x ;
152 int y = event.m_y ;
153 wxPoint local( x , y ) ;
154 win->MacClientToRootWindow( &x, &y ) ;
155 wxPoint windowlocal( x , y ) ;
156 s_ToolTip.Setup( window , win->MacGetToolTipString( local ) , windowlocal ) ;
157 }
158 }
159 }
160 }
161
162 void wxToolTip::RemoveToolTips()
163 {
164 s_ToolTip.Clear() ;
165 }
166 // --- mac specific
167
168 wxMacToolTipTimer::wxMacToolTipTimer( wxMacToolTip *tip , int msec )
169 {
170 m_tip = tip;
171 m_mark = tip->GetMark() ;
172 Start(msec, true);
173 }
174
175 wxMacToolTip::wxMacToolTip()
176 {
177 m_window = NULL ;
178 m_backpict = NULL ;
179 m_mark = 0 ;
180 m_shown = false ;
181 }
182
183 void wxMacToolTip::Setup( WindowRef window , wxString text , wxPoint localPosition )
184 {
185 m_mark++ ;
186 Clear() ;
187 m_position = localPosition ;
188 m_label = wxMacMakeMacStringFromPC( text ) ;
189 m_window = window ;
190 s_ToolTipWindowRef = window ;
191 m_backpict = NULL ;
192 new wxMacToolTipTimer( this , s_ToolTipDelay ) ;
193 }
194
195 wxMacToolTip::~wxMacToolTip()
196 {
197 if ( m_backpict )
198 Clear() ;
199 }
200
201 const short kTipBorder = 2 ;
202 const short kTipOffset = 5 ;
203
204 void wxMacToolTip::Draw()
205 {
206 if ( m_label.Length() == 0 )
207 return ;
208
209 if ( m_window == s_ToolTipWindowRef )
210 {
211 #if TARGET_CARBON
212 AGAPortHelper help( GetWindowPort( m_window ) );
213 #else
214 AGAPortHelper help( ( m_window ) );
215 #endif
216 m_shown = true ;
217
218 SetOrigin( 0 , 0 ) ;
219 TextFont( kFontIDGeneva ) ;
220 TextSize( 9 ) ;
221 TextFace( 0 ) ;
222 FontInfo fontInfo;
223 ::GetFontInfo(&fontInfo);
224 short lineh = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
225 short height = 0 ;
226 // short width = TextWidth( m_label , 0 ,m_label.Length() ) ;
227
228 int i = 0 ;
229 int length = m_label.Length() ;
230 int width = 0 ;
231 int thiswidth = 0 ;
232 int laststop = 0 ;
233 const char *text = m_label ;
234 while( i < length )
235 {
236 if( text[i] == 13 || text[i] == 10)
237 {
238 thiswidth = ::TextWidth( text , laststop , i - laststop ) ;
239 if ( thiswidth > width )
240 width = thiswidth ;
241
242 height += lineh ;
243 laststop = i+1 ;
244 }
245 i++ ;
246 }
247 if ( i - laststop > 0 )
248 {
249 thiswidth = ::TextWidth( text , laststop , i - laststop ) ;
250 if ( thiswidth > width )
251 width = thiswidth ;
252 height += lineh ;
253 }
254
255
256 m_rect.left = m_position.x + kTipOffset;
257 m_rect.top = m_position.y + kTipOffset;
258 m_rect.right = m_rect.left + width + 2 * kTipBorder;
259 m_rect.bottom = m_rect.top + height + 2 * kTipBorder;
260 ClipRect( &m_rect ) ;
261 BackColor( whiteColor ) ;
262 ForeColor(blackColor ) ;
263 m_backpict = OpenPicture(&m_rect);
264
265 CopyBits(GetPortBitMapForCopyBits(GetWindowPort(m_window)),
266 GetPortBitMapForCopyBits(GetWindowPort(m_window)),
267 &m_rect,
268 &m_rect,
269 srcCopy,
270 NULL);
271
272 ClosePicture();
273 RGBColor yellow = { 0xFFFF , 0xFFFF , (153<<8)+153 } ;
274 RGBBackColor( &yellow ) ;
275 EraseRect( &m_rect ) ;
276 FrameRect( &m_rect ) ;
277 BackColor( whiteColor ) ;
278 ForeColor(blackColor ) ;
279 ::MoveTo( m_rect.left + kTipBorder , m_rect.top + fontInfo.ascent + kTipBorder);
280
281 i = 0 ;
282 laststop = 0 ;
283 height = 0 ;
284 while( i < length )
285 {
286 if( text[i] == 13 || text[i] == 10)
287 {
288 ::DrawText( text , laststop , i - laststop ) ;
289 height += lineh ;
290 ::MoveTo( m_rect.left + kTipBorder , m_rect.top + fontInfo.ascent + kTipBorder + height );
291 laststop = i+1 ;
292 }
293 i++ ;
294 }
295
296 ::DrawText( text , laststop , i - laststop ) ;
297 ::TextMode( srcOr ) ;
298
299 // DrawText( m_label , 0 , m_label.Length() ) ;
300 }
301 }
302
303 void wxToolTip::NotifyWindowDelete( WindowRef win )
304 {
305 if ( win == s_ToolTipWindowRef )
306 {
307 s_ToolTipWindowRef = NULL ;
308 }
309 }
310
311 void wxMacToolTip::Clear()
312 {
313 m_mark++ ;
314 if ( !m_shown )
315 return ;
316
317 if ( m_window == s_ToolTipWindowRef && m_backpict )
318 {
319 #if TARGET_CARBON
320 AGAPortHelper help( GetWindowPort(m_window) ) ;
321 #else
322 AGAPortHelper help( (m_window) ) ;
323 #endif
324 m_shown = false ;
325
326 SetOrigin( 0 , 0 ) ;
327 BackColor( whiteColor ) ;
328 ForeColor(blackColor ) ;
329 DrawPicture(m_backpict, &m_rect);
330 KillPicture(m_backpict);
331 m_backpict = NULL ;
332 }
333 }
334
335 #endif
336