]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/window.cpp
make wxScrollBar derive from wxScrollBarBase under wxMac too
[wxWidgets.git] / src / mac / carbon / window.cpp
CommitLineData
e9576ca5 1/////////////////////////////////////////////////////////////////////////////
fb5246be 2// Name: src/mac/carbon/window.cpp
e766c8a9 3// Purpose: wxWindowMac
a31a5f85 4// Author: Stefan Csomor
e9576ca5 5// Modified by:
a31a5f85 6// Created: 1998-01-01
e9576ca5 7// RCS-ID: $Id$
a31a5f85 8// Copyright: (c) Stefan Csomor
65571936 9// Licence: wxWindows licence
e9576ca5
SC
10/////////////////////////////////////////////////////////////////////////////
11
3d1a4878
SC
12#include "wx/wxprec.h"
13
5fde6fcc 14#include "wx/window.h"
e4db172a
WS
15
16#ifndef WX_PRECOMP
17 #include "wx/log.h"
670f9935 18 #include "wx/app.h"
de6185e2 19 #include "wx/utils.h"
8e609c82 20 #include "wx/panel.h"
76b49cf4 21 #include "wx/frame.h"
da80ae71 22 #include "wx/dc.h"
ed4b0fdc 23 #include "wx/dcclient.h"
f1e01716 24 #include "wx/button.h"
3b3dc801 25 #include "wx/menu.h"
fdf565fe 26 #include "wx/dialog.h"
9eddec69 27 #include "wx/settings.h"
246c5004 28 #include "wx/msgdlg.h"
851dee09 29 #include "wx/scrolbar.h"
876cd6f7 30 #include "wx/statbox.h"
fec9cc08 31 #include "wx/textctrl.h"
4e3e485b 32 #include "wx/toolbar.h"
ed2fbeb8 33 #include "wx/layout.h"
3304646d 34 #include "wx/statusbr.h"
25466131 35 #include "wx/menuitem.h"
ed9a7a63
KO
36 #include "wx/treectrl.h"
37 #include "wx/listctrl.h"
e4db172a
WS
38#endif
39
2f1ae414 40#include "wx/tooltip.h"
4ac219f6 41#include "wx/spinctrl.h"
467e3168 42#include "wx/geometry.h"
e9576ca5 43
c1cef60b
CE
44#if wxUSE_LISTCTRL
45 #include "wx/listctrl.h"
46#endif
47
48#if wxUSE_TREECTRL
49 #include "wx/treectrl.h"
50#endif
51
7c551d95
SC
52#if wxUSE_CARET
53 #include "wx/caret.h"
e15f0a5e 54#endif
7c551d95 55
b46dde27
DS
56#if wxUSE_DRAG_AND_DROP
57#include "wx/dnd.h"
58#endif
519cb848 59
d497dca4 60#include "wx/mac/uma.h"
898d9035 61
b46dde27
DS
62#define MAC_SCROLLBAR_SIZE 15
63#define MAC_SMALL_SCROLLBAR_SIZE 11
64
66a09d47
SC
65#ifndef __DARWIN__
66#include <Windows.h>
67#include <ToolUtils.h>
1d879215
DS
68#include <Scrap.h>
69#include <MacTextEditor.h>
66a09d47 70#endif
519cb848 71
41218df1 72#if TARGET_API_MAC_OSX
facd6764 73#ifndef __HIVIEW__
8b573fb8 74 #include <HIToolbox/HIView.h>
facd6764 75#endif
41218df1 76#endif
facd6764 77
e9576ca5
SC
78#include <string.h>
79
fc0daf84
SC
80#ifdef __WXUNIVERSAL__
81 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase)
898d9035 82#else
fc0daf84 83 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
898d9035 84#endif
fc0daf84 85
fc0daf84 86BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase)
facd6764
SC
87 EVT_NC_PAINT(wxWindowMac::OnNcPaint)
88 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground)
ff3795ee
SC
89#if TARGET_API_MAC_OSX
90 EVT_PAINT(wxWindowMac::OnPaint)
91#endif
5ca0d812
SC
92 EVT_SET_FOCUS(wxWindowMac::OnSetFocus)
93 EVT_KILL_FOCUS(wxWindowMac::OnSetFocus)
facd6764 94 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent)
e9576ca5
SC
95END_EVENT_TABLE()
96
94abc21f
SC
97#define wxMAC_DEBUG_REDRAW 0
98#ifndef wxMAC_DEBUG_REDRAW
99#define wxMAC_DEBUG_REDRAW 0
100#endif
101
42ef83fa
SC
102// ---------------------------------------------------------------------------
103// Utility Routines to move between different coordinate systems
104// ---------------------------------------------------------------------------
105
106/*
107 * Right now we have the following setup :
108 * a border that is not part of the native control is always outside the
109 * control's border (otherwise we loose all native intelligence, future ways
110 * may be to have a second embedding control responsible for drawing borders
111 * and backgrounds eventually)
112 * so all this border calculations have to be taken into account when calling
113 * native methods or getting native oriented data
114 * so we have three coordinate systems here
115 * wx client coordinates
116 * wx window coordinates (including window frames)
117 * native coordinates
118 */
8b573fb8 119
42ef83fa
SC
120//
121// originating from native control
122//
123
124
125void wxMacNativeToWindow( const wxWindow* window , RgnHandle handle )
126{
8b573fb8 127 OffsetRgn( handle , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ;
42ef83fa
SC
128}
129
130void wxMacNativeToWindow( const wxWindow* window , Rect *rect )
131{
8b573fb8 132 OffsetRect( rect , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ;
42ef83fa
SC
133}
134
135//
136// directed towards native control
137//
138
139void wxMacWindowToNative( const wxWindow* window , RgnHandle handle )
140{
8b573fb8 141 OffsetRgn( handle , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() );
42ef83fa
SC
142}
143
144void wxMacWindowToNative( const wxWindow* window , Rect *rect )
145{
8b573fb8 146 OffsetRect( rect , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() ) ;
42ef83fa
SC
147}
148
facd6764
SC
149// ---------------------------------------------------------------------------
150// Carbon Events
151// ---------------------------------------------------------------------------
8b573fb8 152
f1d527c1
SC
153#if TARGET_API_MAC_OSX
154
8b573fb8 155#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3
898d9035
DS
156enum
157{
158 kEventControlVisibilityChanged = 157
c2697b87
SC
159};
160#endif
161
f1d527c1
SC
162#endif
163
facd6764
SC
164static const EventTypeSpec eventList[] =
165{
e3aeade0
SC
166 { kEventClassCommand, kEventProcessCommand } ,
167 { kEventClassCommand, kEventCommandUpdateStatus } ,
b46dde27 168
e9a4bf7d 169 { kEventClassControl , kEventControlGetClickActivation } ,
f1d527c1 170 { kEventClassControl , kEventControlHit } ,
898d9035 171
980ee83f
SC
172 { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
173 { kEventClassTextInput, kEventTextInputUpdateActiveInputArea } ,
b46dde27 174
73fe67bd 175 { kEventClassControl , kEventControlDraw } ,
cdef0334 176#if TARGET_API_MAC_OSX
73fe67bd
SC
177 { kEventClassControl , kEventControlVisibilityChanged } ,
178 { kEventClassControl , kEventControlEnabledStateChanged } ,
179 { kEventClassControl , kEventControlHiliteChanged } ,
ed9a7a63
KO
180
181 { kEventClassControl , kEventControlActivate } ,
182 { kEventClassControl , kEventControlDeactivate } ,
cdef0334 183#endif
f1d527c1 184 { kEventClassControl , kEventControlSetFocusPart } ,
8b573fb8
VZ
185
186 { kEventClassService , kEventServiceGetTypes },
187 { kEventClassService , kEventServiceCopy },
188 { kEventClassService , kEventServicePaste },
189
898d9035
DS
190// { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
191// { kEventClassControl , kEventControlBoundsChanged } ,
facd6764
SC
192} ;
193
194static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
195{
196 OSStatus result = eventNotHandledErr ;
197
198 wxMacCarbonEvent cEvent( event ) ;
8b573fb8 199
facd6764
SC
200 ControlRef controlRef ;
201 wxWindowMac* thisWindow = (wxWindowMac*) data ;
202
203 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
204
898d9035 205 switch ( GetEventKind( event ) )
facd6764 206 {
f1d527c1 207#if TARGET_API_MAC_OSX
facd6764
SC
208 case kEventControlDraw :
209 {
1e8cde71 210 RgnHandle updateRgn = NULL ;
055a486b 211 RgnHandle allocatedRgn = NULL ;
1e8cde71 212 wxRegion visRegion = thisWindow->MacGetVisibleRegion() ;
898d9035 213
76c7012c 214 if ( cEvent.GetParameter<RgnHandle>(kEventParamRgnHandle, &updateRgn) != noErr )
1e8cde71
SC
215 {
216 updateRgn = (RgnHandle) visRegion.GetWXHRGN() ;
217 }
055a486b
SC
218 else
219 {
a9b456ff 220 if ( thisWindow->MacGetLeftBorderSize() != 0 || thisWindow->MacGetTopBorderSize() != 0 )
055a486b 221 {
a9b456ff 222 // as this update region is in native window locals we must adapt it to wx window local
055a486b
SC
223 allocatedRgn = NewRgn() ;
224 CopyRgn( updateRgn , allocatedRgn ) ;
898d9035 225
42ef83fa
SC
226 // hide the given region by the new region that must be shifted
227 wxMacNativeToWindow( thisWindow , allocatedRgn ) ;
902725ee 228 updateRgn = allocatedRgn ;
e6616741 229 }
055a486b 230 }
e15f0a5e 231
e6616741
SC
232 Rect rgnBounds ;
233 GetRegionBounds( updateRgn , &rgnBounds ) ;
898d9035 234
1f1c8bd4 235#if wxMAC_DEBUG_REDRAW
facd6764
SC
236 if ( thisWindow->MacIsUserPane() )
237 {
bcbd6987
SC
238 static float color = 0.5 ;
239 static channel = 0 ;
898d9035
DS
240 HIRect bounds;
241 CGContextRef cgContext = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef) ;
242
243 HIViewGetBounds( controlRef, &bounds );
8b573fb8
VZ
244 CGContextSetRGBFillColor( cgContext, channel == 0 ? color : 0.5 ,
245 channel == 1 ? color : 0.5 , channel == 2 ? color : 0.5 , 1 );
246 CGContextFillRect( cgContext, bounds );
247 color += 0.1 ;
248 if ( color > 0.9 )
249 {
250 color = 0.5 ;
251 channel++ ;
252 if ( channel == 3 )
253 channel = 0 ;
254 }
facd6764 255 }
20b69855 256#endif
898d9035 257
c79aad8b 258 {
20b69855 259#if wxMAC_USE_CORE_GRAPHICS
e6616741 260 bool created = false ;
8523a5f5 261 CGContextRef cgContext = NULL ;
a9b456ff
SC
262 OSStatus err = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef, &cgContext) ;
263 wxASSERT_MSG( err == noErr , wxT("Unable to retrieve CGContextRef") ) ;
c79aad8b 264 thisWindow->MacSetCGContextRef( cgContext ) ;
898d9035 265
e6616741
SC
266 {
267 wxMacCGContextStateSaver sg( cgContext ) ;
a9b456ff
SC
268 float alpha = 1.0 ;
269 {
270 wxWindow* iter = thisWindow ;
271 while ( iter )
272 {
273 alpha *= (float) iter->GetTransparent()/255.0 ;
274 if ( iter->IsTopLevel() )
275 iter = NULL ;
276 else
277 iter = iter->GetParent() ;
278 }
279 }
280 CGContextSetAlpha( cgContext , alpha ) ;
4488a1d3
VZ
281
282 if ( thisWindow->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
283 {
284 HIRect bounds;
285 HIViewGetBounds( controlRef, &bounds );
286 CGContextClearRect( cgContext, bounds );
287 }
288
289
facd6764 290#endif
e6616741
SC
291 if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
292 result = noErr ;
898d9035 293
20b69855 294#if wxMAC_USE_CORE_GRAPHICS
e6616741
SC
295 thisWindow->MacSetCGContextRef( NULL ) ;
296 }
898d9035 297
e6616741 298 if ( created )
e6616741 299 CGContextRelease( cgContext ) ;
20b69855 300#endif
c79aad8b 301 }
e15f0a5e 302
055a486b
SC
303 if ( allocatedRgn )
304 DisposeRgn( allocatedRgn ) ;
facd6764
SC
305 }
306 break ;
e15f0a5e 307
73fe67bd 308 case kEventControlVisibilityChanged :
e15f0a5e 309 thisWindow->MacVisibilityChanged() ;
73fe67bd 310 break ;
e15f0a5e 311
73fe67bd 312 case kEventControlEnabledStateChanged :
e15f0a5e 313 thisWindow->MacEnabledStateChanged() ;
73fe67bd 314 break ;
e15f0a5e 315
73fe67bd 316 case kEventControlHiliteChanged :
e15f0a5e 317 thisWindow->MacHiliteChanged() ;
73fe67bd 318 break ;
ed9a7a63
KO
319
320 case kEventControlActivate :
321 case kEventControlDeactivate :
0b8055d2
VZ
322 // FIXME: we should have a virtual function for this!
323#if wxUSE_TREECTRL
324 if ( thisWindow->IsKindOf( CLASSINFO( wxTreeCtrl ) ) )
ed9a7a63 325 thisWindow->Refresh();
6449b3a8 326#endif
0b8055d2
VZ
327#if wxUSE_LISTCTRL
328 if ( thisWindow->IsKindOf( CLASSINFO( wxListCtrl ) ) )
329 thisWindow->Refresh();
330#endif
331 break ;
332#endif // TARGET_API_MAC_OSX
e15f0a5e 333
6449b3a8 334 // we emulate this event under Carbon CFM
f1d527c1
SC
335 case kEventControlSetFocusPart :
336 {
337 Boolean focusEverything = false ;
338 ControlPartCode controlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
898d9035 339
6449b3a8 340#ifdef __WXMAC_OSX__
f1d527c1
SC
341 if ( cEvent.GetParameter<Boolean>(kEventParamControlFocusEverything , &focusEverything ) == noErr )
342 {
343 }
6449b3a8 344#endif
e15f0a5e 345
6a74af89
VZ
346 if ( thisWindow->MacIsUserPane() )
347 result = noErr ;
348
f1d527c1
SC
349 if ( controlPart == kControlFocusNoPart )
350 {
e15f0a5e 351#if wxUSE_CARET
f1d527c1 352 if ( thisWindow->GetCaret() )
f1d527c1 353 thisWindow->GetCaret()->OnKillFocus();
e15f0a5e
DS
354#endif
355
92b6cd62 356 static bool inKillFocusEvent = false ;
898d9035 357
92b6cd62
SC
358 if ( !inKillFocusEvent )
359 {
360 inKillFocusEvent = true ;
361 wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
362 event.SetEventObject(thisWindow);
363 thisWindow->GetEventHandler()->ProcessEvent(event) ;
364 inKillFocusEvent = false ;
365 }
f1d527c1
SC
366 }
367 else
368 {
369 // panel wants to track the window which was the last to have focus in it
370 wxChildFocusEvent eventFocus(thisWindow);
371 thisWindow->GetEventHandler()->ProcessEvent(eventFocus);
8b573fb8 372
e15f0a5e 373#if wxUSE_CARET
f1d527c1 374 if ( thisWindow->GetCaret() )
f1d527c1 375 thisWindow->GetCaret()->OnSetFocus();
e15f0a5e 376#endif
f1d527c1
SC
377
378 wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
379 event.SetEventObject(thisWindow);
380 thisWindow->GetEventHandler()->ProcessEvent(event) ;
381 }
382 }
383 break ;
e15f0a5e 384
f1d527c1 385 case kEventControlHit :
e15f0a5e 386 result = thisWindow->MacControlHit( handler , event ) ;
f1d527c1 387 break ;
e15f0a5e 388
e9a4bf7d
SC
389 case kEventControlGetClickActivation :
390 {
391 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
392 WindowRef owner = cEvent.GetParameter<WindowRef>(kEventParamWindowRef);
393 if ( !IsWindowActive(owner) )
394 {
395 cEvent.SetParameter(kEventParamClickActivation,(UInt32) kActivateAndIgnoreClick) ;
396 result = noErr ;
397 }
398 }
399 break ;
400
facd6764
SC
401 default :
402 break ;
403 }
e15f0a5e 404
facd6764
SC
405 return result ;
406}
407
e4727773
SC
408static pascal OSStatus wxMacWindowServiceEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
409{
410 OSStatus result = eventNotHandledErr ;
411
412 wxMacCarbonEvent cEvent( event ) ;
8b573fb8 413
e4727773
SC
414 ControlRef controlRef ;
415 wxWindowMac* thisWindow = (wxWindowMac*) data ;
416 wxTextCtrl* textCtrl = wxDynamicCast( thisWindow , wxTextCtrl ) ;
417 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
418
e15f0a5e 419 switch ( GetEventKind( event ) )
e4727773
SC
420 {
421 case kEventServiceGetTypes :
e15f0a5e 422 if ( textCtrl )
e4727773
SC
423 {
424 long from, to ;
425 textCtrl->GetSelection( &from , &to ) ;
426
8b573fb8 427 CFMutableArrayRef copyTypes = 0 , pasteTypes = 0;
e15f0a5e 428 if ( from != to )
e4727773
SC
429 copyTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServiceCopyTypes , typeCFMutableArrayRef ) ;
430 if ( textCtrl->IsEditable() )
431 pasteTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServicePasteTypes , typeCFMutableArrayRef ) ;
8b573fb8 432
898d9035 433 static const OSType textDataTypes[] = { kTXNTextData /* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
e4727773
SC
434 for ( size_t i = 0 ; i < WXSIZEOF(textDataTypes) ; ++i )
435 {
436 CFStringRef typestring = CreateTypeStringWithOSType(textDataTypes[i]);
437 if ( typestring )
438 {
439 if ( copyTypes )
898d9035 440 CFArrayAppendValue(copyTypes, typestring) ;
e4727773 441 if ( pasteTypes )
898d9035 442 CFArrayAppendValue(pasteTypes, typestring) ;
e15f0a5e 443
e4727773
SC
444 CFRelease( typestring ) ;
445 }
446 }
e15f0a5e 447
e4727773
SC
448 result = noErr ;
449 }
450 break ;
e15f0a5e 451
e4727773
SC
452 case kEventServiceCopy :
453 if ( textCtrl )
454 {
455 long from, to ;
e15f0a5e 456
e4727773
SC
457 textCtrl->GetSelection( &from , &to ) ;
458 wxString val = textCtrl->GetValue() ;
459 val = val.Mid( from , to - from ) ;
460 ScrapRef scrapRef = cEvent.GetParameter< ScrapRef > ( kEventParamScrapRef , typeScrapRef ) ;
461 verify_noerr( ClearScrap( &scrapRef ) ) ;
fb5246be 462 verify_noerr( PutScrapFlavor( scrapRef , kTXNTextData , 0 , val.length() , val.c_str() ) ) ;
e4727773
SC
463 result = noErr ;
464 }
465 break ;
e15f0a5e 466
e4727773
SC
467 case kEventServicePaste :
468 if ( textCtrl )
469 {
470 ScrapRef scrapRef = cEvent.GetParameter< ScrapRef > ( kEventParamScrapRef , typeScrapRef ) ;
471 Size textSize, pastedSize ;
898d9035 472 verify_noerr( GetScrapFlavorSize(scrapRef, kTXNTextData, &textSize) ) ;
e4727773
SC
473 textSize++ ;
474 char *content = new char[textSize] ;
898d9035
DS
475 GetScrapFlavorData(scrapRef, kTXNTextData, &pastedSize, content );
476 content[textSize - 1] = 0 ;
e15f0a5e 477
8ef4d6e2 478#if wxUSE_UNICODE
58603178 479 textCtrl->WriteText( wxString( content , wxConvLocal ) );
8ef4d6e2 480#else
e4727773 481 textCtrl->WriteText( wxString( content ) ) ;
8ef4d6e2 482#endif
e15f0a5e 483
e4727773
SC
484 delete[] content ;
485 result = noErr ;
486 }
487 break ;
e15f0a5e
DS
488
489 default:
490 break ;
e4727773 491 }
8b573fb8 492
e4727773 493 return result ;
8b573fb8 494}
e4727773 495
980ee83f
SC
496pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
497{
498 OSStatus result = eventNotHandledErr ;
499 wxWindowMac* focus = (wxWindowMac*) data ;
b46dde27 500
980ee83f
SC
501 wchar_t* uniChars = NULL ;
502 UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
b46dde27 503
75b32421 504 UniChar* charBuf = NULL;
4f74e0d1 505 ByteCount dataSize = 0 ;
980ee83f
SC
506 int numChars = 0 ;
507 UniChar buf[2] ;
508 if ( GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, 0 , &dataSize, NULL ) == noErr )
509 {
3281bf67 510 numChars = dataSize / sizeof( UniChar) + 1;
980ee83f 511 charBuf = buf ;
b46dde27 512
6d49e4bb 513 if ( (size_t) numChars * 2 > sizeof(buf) )
980ee83f
SC
514 charBuf = new UniChar[ numChars ] ;
515 else
516 charBuf = buf ;
b46dde27 517
980ee83f
SC
518 uniChars = new wchar_t[ numChars ] ;
519 GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, dataSize , NULL , charBuf ) ;
e4db172a 520 charBuf[ numChars - 1 ] = 0;
980ee83f 521#if SIZEOF_WCHAR_T == 2
cdef0334 522 uniChars = (wchar_t*) charBuf ;
5ca930b1 523/* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
980ee83f
SC
524#else
525 // the resulting string will never have more chars than the utf16 version, so this is safe
526 wxMBConvUTF16 converter ;
527 numChars = converter.MB2WC( uniChars , (const char*)charBuf , numChars ) ;
528#endif
529 }
b46dde27 530
980ee83f
SC
531 switch ( GetEventKind( event ) )
532 {
533 case kEventTextInputUpdateActiveInputArea :
534 {
535 // An IME input event may return several characters, but we need to send one char at a time to
536 // EVT_CHAR
537 for (int pos=0 ; pos < numChars ; pos++)
538 {
980ee83f
SC
539 WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
540 WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
541 wxTheApp->MacSetCurrentEvent( event , handler ) ;
b46dde27 542
5ca930b1
VZ
543 UInt32 message = uniChars[pos] < 128 ? (char)uniChars[pos] : '?';
544/*
545 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
546 multiple times to update the active range during inline input, so this handler will often receive
547 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
548 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
549 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
550 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
551 should add new event types to support advanced text input. For now, I would keep things as they are.
552
553 However, the code that was being used caused additional problems:
980ee83f 554 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
5ca930b1
VZ
555 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
556 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
557 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
558 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
559 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
560 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
561 overlap with Unicode within the (7-bit) ASCII range.
562 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
563 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
564 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
565 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
566 I don't have time to look into that right now.
567 -- CL
568*/
980ee83f
SC
569 if ( wxTheApp->MacSendCharEvent(
570 focus , message , 0 , when , 0 , 0 , uniChars[pos] ) )
571 {
572 result = noErr ;
573 }
b46dde27 574
980ee83f
SC
575 wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
576 }
577 }
578 break ;
579 case kEventTextInputUnicodeForKeyEvent :
580 {
581 UInt32 keyCode, modifiers ;
582 Point point ;
583 EventRef rawEvent ;
584 unsigned char charCode ;
585
586 GetEventParameter( event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent ) ;
587 GetEventParameter( rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode );
588 GetEventParameter( rawEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
589 GetEventParameter( rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers );
590 GetEventParameter( rawEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point );
b46dde27 591
980ee83f 592 UInt32 message = (keyCode << 8) + charCode;
aa44b55d 593
980ee83f
SC
594 // An IME input event may return several characters, but we need to send one char at a time to
595 // EVT_CHAR
596 for (int pos=0 ; pos < numChars ; pos++)
597 {
980ee83f
SC
598 WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
599 WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
600 wxTheApp->MacSetCurrentEvent( event , handler ) ;
b46dde27 601
980ee83f
SC
602 if ( wxTheApp->MacSendCharEvent(
603 focus , message , modifiers , when , point.h , point.v , uniChars[pos] ) )
604 {
605 result = noErr ;
606 }
b46dde27 607
980ee83f
SC
608 wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
609 }
610 }
611 break;
612 default:
613 break ;
614 }
b46dde27
DS
615
616 delete [] uniChars ;
980ee83f 617 if ( charBuf != buf )
b46dde27 618 delete [] charBuf ;
2e91d506 619
980ee83f 620 return result ;
980ee83f
SC
621}
622
e3aeade0
SC
623static pascal OSStatus wxMacWindowCommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
624{
625 OSStatus result = eventNotHandledErr ;
626 wxWindowMac* focus = (wxWindowMac*) data ;
b46dde27 627
e3aeade0 628 HICommand command ;
b46dde27 629
e3aeade0
SC
630 wxMacCarbonEvent cEvent( event ) ;
631 cEvent.GetParameter<HICommand>(kEventParamDirectObject,typeHICommand,&command) ;
b46dde27 632
e3aeade0
SC
633 wxMenuItem* item = NULL ;
634 wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ;
635 int id = wxMacCommandToId( command.commandID ) ;
b46dde27 636
e3aeade0
SC
637 if ( item )
638 {
639 wxASSERT( itemMenu != NULL ) ;
b46dde27 640
e3aeade0
SC
641 switch ( cEvent.GetKind() )
642 {
643 case kEventProcessCommand :
644 {
645 if (item->IsCheckable())
646 item->Check( !item->IsChecked() ) ;
b46dde27 647
e3aeade0
SC
648 if ( itemMenu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) )
649 result = noErr ;
650 else
651 {
652 wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED , id);
653 event.SetEventObject(focus);
654 event.SetInt(item->IsCheckable() ? item->IsChecked() : -1);
b46dde27 655
e3aeade0
SC
656 if ( focus->GetEventHandler()->ProcessEvent(event) )
657 result = noErr ;
658 }
659 }
660 break ;
b46dde27 661
e3aeade0
SC
662 case kEventCommandUpdateStatus:
663 {
664 wxUpdateUIEvent event(id);
665 event.SetEventObject( itemMenu );
b46dde27 666
e3aeade0 667 bool processed = false;
b46dde27 668
e3aeade0
SC
669 // Try the menu's event handler
670 {
671 wxEvtHandler *handler = itemMenu->GetEventHandler();
672 if ( handler )
673 processed = handler->ProcessEvent(event);
674 }
b46dde27 675
e3aeade0
SC
676 // Try the window the menu was popped up from
677 // (and up through the hierarchy)
678 if ( !processed )
679 {
680 const wxMenuBase *menu = itemMenu;
681 while ( menu )
682 {
683 wxWindow *win = menu->GetInvokingWindow();
684 if ( win )
685 {
686 processed = win->GetEventHandler()->ProcessEvent(event);
687 break;
688 }
b46dde27 689
e3aeade0
SC
690 menu = menu->GetParent();
691 }
692 }
b46dde27 693
e3aeade0
SC
694 if ( !processed )
695 {
696 processed = focus->GetEventHandler()->ProcessEvent(event);
697 }
b46dde27 698
e3aeade0
SC
699 if ( processed )
700 {
701 // if anything changed, update the changed attribute
702 if (event.GetSetText())
703 itemMenu->SetLabel(id, event.GetText());
704 if (event.GetSetChecked())
705 itemMenu->Check(id, event.GetChecked());
706 if (event.GetSetEnabled())
707 itemMenu->Enable(id, event.GetEnabled());
b46dde27 708
e3aeade0
SC
709 result = noErr ;
710 }
711 }
712 break ;
b46dde27 713
e3aeade0
SC
714 default :
715 break ;
716 }
717 }
718 return result ;
719}
720
facd6764
SC
721pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
722{
af6b7b80
SC
723 EventRef formerEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ;
724 EventHandlerCallRef formerEventHandlerCallRef = (EventHandlerCallRef) wxTheApp->MacGetCurrentEventHandlerCallRef() ;
725 wxTheApp->MacSetCurrentEvent( event , handler ) ;
facd6764
SC
726 OSStatus result = eventNotHandledErr ;
727
728 switch ( GetEventClass( event ) )
729 {
e3aeade0
SC
730 case kEventClassCommand :
731 result = wxMacWindowCommandEventHandler( handler , event , data ) ;
732 break ;
733
facd6764
SC
734 case kEventClassControl :
735 result = wxMacWindowControlEventHandler( handler, event, data ) ;
736 break ;
e15f0a5e 737
e4727773
SC
738 case kEventClassService :
739 result = wxMacWindowServiceEventHandler( handler, event , data ) ;
902725ee 740 break ;
e15f0a5e 741
980ee83f
SC
742 case kEventClassTextInput :
743 result = wxMacUnicodeTextEventHandler( handler , event , data ) ;
744 break ;
b46dde27 745
facd6764
SC
746 default :
747 break ;
748 }
e15f0a5e 749
af6b7b80 750 wxTheApp->MacSetCurrentEvent( formerEvent, formerEventHandlerCallRef ) ;
e15f0a5e 751
facd6764
SC
752 return result ;
753}
754
755DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler )
756
20b69855
SC
757#if !TARGET_API_MAC_OSX
758
facd6764
SC
759// ---------------------------------------------------------------------------
760// UserPane events for non OSX builds
761// ---------------------------------------------------------------------------
8b573fb8 762
facd6764
SC
763static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part)
764{
765 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
766 if ( win )
767 win->MacControlUserPaneDrawProc(part) ;
facd6764 768}
1f1c8bd4 769wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP , wxMacControlUserPaneDrawProc ) ;
facd6764
SC
770
771static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where)
772{
773 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
774 if ( win )
775 return win->MacControlUserPaneHitTestProc(where.h , where.v) ;
776 else
777 return kControlNoPart ;
facd6764 778}
1f1c8bd4 779wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP , wxMacControlUserPaneHitTestProc ) ;
facd6764
SC
780
781static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc)
782{
783 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
784 if ( win )
785 return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc) ;
786 else
787 return kControlNoPart ;
facd6764 788}
1f1c8bd4 789wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP , wxMacControlUserPaneTrackingProc ) ;
facd6764
SC
790
791static pascal void wxMacControlUserPaneIdleProc(ControlRef control)
792{
793 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
794 if ( win )
795 win->MacControlUserPaneIdleProc() ;
facd6764 796}
1f1c8bd4 797wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP , wxMacControlUserPaneIdleProc ) ;
facd6764
SC
798
799static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
800{
801 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
802 if ( win )
803 return win->MacControlUserPaneKeyDownProc(keyCode,charCode,modifiers) ;
804 else
805 return kControlNoPart ;
facd6764 806}
1f1c8bd4 807wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP , wxMacControlUserPaneKeyDownProc ) ;
facd6764
SC
808
809static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating)
810{
811 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
812 if ( win )
813 win->MacControlUserPaneActivateProc(activating) ;
facd6764 814}
1f1c8bd4 815wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP , wxMacControlUserPaneActivateProc ) ;
facd6764
SC
816
817static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action)
818{
819 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
820 if ( win )
821 return win->MacControlUserPaneFocusProc(action) ;
822 else
823 return kControlNoPart ;
facd6764 824}
1f1c8bd4 825wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP , wxMacControlUserPaneFocusProc ) ;
facd6764
SC
826
827static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info)
828{
829 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
830 if ( win )
831 win->MacControlUserPaneBackgroundProc(info) ;
facd6764 832}
1f1c8bd4 833wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP , wxMacControlUserPaneBackgroundProc ) ;
facd6764 834
8b573fb8 835void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part)
facd6764 836{
e15f0a5e 837 int x = 0 , y = 0;
bcbd6987
SC
838 RgnHandle rgn = NewRgn() ;
839 GetClip( rgn ) ;
8523a5f5 840 MacWindowToRootWindow( &x, &y ) ;
d35bd499 841 OffsetRgn( rgn , -x , -y ) ;
bcbd6987
SC
842 wxMacWindowStateSaver sv( this ) ;
843 SectRgn( rgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , rgn ) ;
844 MacDoRedraw( rgn , 0 ) ;
845 DisposeRgn( rgn ) ;
facd6764
SC
846}
847
8b573fb8 848wxInt16 wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
facd6764
SC
849{
850 return kControlNoPart ;
851}
852
8b573fb8 853wxInt16 wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
facd6764
SC
854{
855 return kControlNoPart ;
856}
857
8b573fb8 858void wxWindowMac::MacControlUserPaneIdleProc()
facd6764
SC
859{
860}
861
8b573fb8 862wxInt16 wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
facd6764
SC
863{
864 return kControlNoPart ;
865}
866
8b573fb8 867void wxWindowMac::MacControlUserPaneActivateProc(bool activating)
facd6764
SC
868{
869}
870
8b573fb8 871wxInt16 wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action)
facd6764 872{
fb5246be
WS
873 if ( AcceptsFocus() )
874 return 1 ;
875 else
876 return kControlNoPart ;
facd6764
SC
877}
878
8b573fb8 879void wxWindowMac::MacControlUserPaneBackgroundProc(void* info)
facd6764
SC
880{
881}
882
20b69855
SC
883#endif
884
1f1c8bd4
SC
885// ---------------------------------------------------------------------------
886// Scrollbar Tracking for all
887// ---------------------------------------------------------------------------
888
889pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode ) ;
890pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode )
891{
892 if ( partCode != 0)
893 {
894 wxWindow* wx = wxFindControlFromMacControl( control ) ;
895 if ( wx )
1f1c8bd4 896 wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ;
1f1c8bd4
SC
897 }
898}
899wxMAC_DEFINE_PROC_GETTER( ControlActionUPP , wxMacLiveScrollbarActionProc ) ;
900
e7549107
SC
901// ===========================================================================
902// implementation
903// ===========================================================================
904
71f2fb52
RN
905WX_DECLARE_HASH_MAP(ControlRef, wxWindow*, wxPointerHash, wxPointerEqual, MacControlMap);
906
907static MacControlMap wxWinMacControlList;
908
909wxWindow *wxFindControlFromMacControl(ControlRef inControl )
910{
911 MacControlMap::iterator node = wxWinMacControlList.find(inControl);
912
913 return (node == wxWinMacControlList.end()) ? NULL : node->second;
914}
915
916void wxAssociateControlWithMacControl(ControlRef inControl, wxWindow *control)
917{
918 // adding NULL ControlRef is (first) surely a result of an error and
919 // (secondly) breaks native event processing
920 wxCHECK_RET( inControl != (ControlRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
921
922 wxWinMacControlList[inControl] = control;
923}
924
925void wxRemoveMacControlAssociation(wxWindow *control)
926{
927 // iterate over all the elements in the class
a8683134
SC
928 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
929 // we should go on...
930
931 bool found = true ;
e15f0a5e 932 while ( found )
71f2fb52 933 {
a8683134
SC
934 found = false ;
935 MacControlMap::iterator it;
936 for ( it = wxWinMacControlList.begin(); it != wxWinMacControlList.end(); ++it )
71f2fb52 937 {
a8683134
SC
938 if ( it->second == control )
939 {
940 wxWinMacControlList.erase(it);
941 found = true ;
942 break;
943 }
71f2fb52
RN
944 }
945 }
946}
facd6764 947
e7549107 948// ----------------------------------------------------------------------------
facd6764 949 // constructors and such
e7549107
SC
950// ----------------------------------------------------------------------------
951
94f9b1f0 952wxWindowMac::wxWindowMac()
8b573fb8
VZ
953{
954 Init();
94f9b1f0
SC
955}
956
957wxWindowMac::wxWindowMac(wxWindowMac *parent,
958 wxWindowID id,
959 const wxPoint& pos ,
960 const wxSize& size ,
961 long style ,
962 const wxString& name )
963{
964 Init();
965 Create(parent, id, pos, size, style, name);
966}
967
e766c8a9 968void wxWindowMac::Init()
519cb848 969{
21fd5529 970 m_peer = NULL ;
79392158 971 m_frozenness = 0 ;
a9b456ff 972 m_macAlpha = 255 ;
898d9035 973
e15f0a5e
DS
974#if wxMAC_USE_CORE_GRAPHICS
975 m_cgContextRef = NULL ;
976#endif
977
e7549107 978 // as all windows are created with WS_VISIBLE style...
902725ee 979 m_isShown = true;
e7549107 980
6264b550
RR
981 m_hScrollBar = NULL ;
982 m_vScrollBar = NULL ;
facd6764
SC
983 m_macBackgroundBrush = wxNullBrush ;
984
902725ee 985 m_macIsUserPane = true;
8adc196b 986 m_clipChildren = false ;
5c840e5b 987 m_cachedClippedRectValid = false ;
e15f0a5e 988
c6f9fb05
SC
989 // we need a valid font for the encodings
990 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
e9576ca5
SC
991}
992
e766c8a9 993wxWindowMac::~wxWindowMac()
e9576ca5 994{
7de59551
RD
995 SendDestroyEvent();
996
902725ee 997 m_isBeingDeleted = true;
6ed71b4f 998
6449b3a8 999 MacInvalidateBorders() ;
7ebf5540 1000
d4380aaf
SC
1001#ifndef __WXUNIVERSAL__
1002 // VS: make sure there's no wxFrame with last focus set to us:
1003 for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
1004 {
1005 wxFrame *frame = wxDynamicCast(win, wxFrame);
1006 if ( frame )
1007 {
1008 if ( frame->GetLastFocus() == this )
d4380aaf 1009 frame->SetLastFocus((wxWindow*)NULL);
d4380aaf
SC
1010 break;
1011 }
1012 }
b46dde27 1013#endif
8b573fb8
VZ
1014
1015 // destroy children before destroying this window itself
1016 DestroyChildren();
1017
facd6764
SC
1018 // wxRemoveMacControlAssociation( this ) ;
1019 // If we delete an item, we should initialize the parent panel,
1020 // because it could now be invalid.
6c20e8f8
VZ
1021 wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow);
1022 if ( tlw )
facd6764 1023 {
6c20e8f8
VZ
1024 if ( tlw->GetDefaultItem() == (wxButton*) this)
1025 tlw->SetDefaultItem(NULL);
facd6764 1026 }
e15f0a5e 1027
21fd5529 1028 if ( m_peer && m_peer->Ok() )
facd6764
SC
1029 {
1030 // in case the callback might be called during destruction
1031 wxRemoveMacControlAssociation( this) ;
229f6270 1032 ::RemoveEventHandler( (EventHandlerRef ) m_macControlEventHandler ) ;
5ca0d812
SC
1033 // we currently are not using this hook
1034 // ::SetControlColorProc( *m_peer , NULL ) ;
1035 m_peer->Dispose() ;
facd6764 1036 }
d4380aaf 1037
facd6764 1038 if ( g_MacLastWindow == this )
facd6764 1039 g_MacLastWindow = NULL ;
7de59551 1040
fd76aa8d
SC
1041 wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame ) ;
1042 if ( frame )
1043 {
e40298d5
JS
1044 if ( frame->GetLastFocus() == this )
1045 frame->SetLastFocus( NULL ) ;
fd76aa8d 1046 }
e7549107 1047
42683dfb
SC
1048 // delete our drop target if we've got one
1049#if wxUSE_DRAG_AND_DROP
1050 if ( m_dropTarget != NULL )
1051 {
1052 delete m_dropTarget;
1053 m_dropTarget = NULL;
1054 }
e15f0a5e
DS
1055#endif
1056
21fd5529
SC
1057 delete m_peer ;
1058}
1059
8b573fb8
VZ
1060WXWidget wxWindowMac::GetHandle() const
1061{
1062 return (WXWidget) m_peer->GetControlRef() ;
e9576ca5
SC
1063}
1064
5ca0d812 1065void wxWindowMac::MacInstallEventHandler( WXWidget control )
facd6764 1066{
898d9035
DS
1067 wxAssociateControlWithMacControl( (ControlRef) control , this ) ;
1068 InstallControlEventHandler( (ControlRef)control , GetwxMacWindowEventHandlerUPP(),
8b573fb8 1069 GetEventTypeCount(eventList), eventList, this,
facd6764 1070 (EventHandlerRef *)&m_macControlEventHandler);
e15f0a5e 1071
4a63451b
SC
1072#if !TARGET_API_MAC_OSX
1073 if ( (ControlRef) control == m_peer->GetControlRef() )
1074 {
898d9035
DS
1075 m_peer->SetData<ControlUserPaneDrawUPP>(kControlEntireControl, kControlUserPaneDrawProcTag, GetwxMacControlUserPaneDrawProc()) ;
1076 m_peer->SetData<ControlUserPaneHitTestUPP>(kControlEntireControl, kControlUserPaneHitTestProcTag, GetwxMacControlUserPaneHitTestProc()) ;
1077 m_peer->SetData<ControlUserPaneTrackingUPP>(kControlEntireControl, kControlUserPaneTrackingProcTag, GetwxMacControlUserPaneTrackingProc()) ;
1078 m_peer->SetData<ControlUserPaneIdleUPP>(kControlEntireControl, kControlUserPaneIdleProcTag, GetwxMacControlUserPaneIdleProc()) ;
1079 m_peer->SetData<ControlUserPaneKeyDownUPP>(kControlEntireControl, kControlUserPaneKeyDownProcTag, GetwxMacControlUserPaneKeyDownProc()) ;
1080 m_peer->SetData<ControlUserPaneActivateUPP>(kControlEntireControl, kControlUserPaneActivateProcTag, GetwxMacControlUserPaneActivateProc()) ;
1081 m_peer->SetData<ControlUserPaneFocusUPP>(kControlEntireControl, kControlUserPaneFocusProcTag, GetwxMacControlUserPaneFocusProc()) ;
1082 m_peer->SetData<ControlUserPaneBackgroundUPP>(kControlEntireControl, kControlUserPaneBackgroundProcTag, GetwxMacControlUserPaneBackgroundProc()) ;
4a63451b
SC
1083 }
1084#endif
facd6764
SC
1085}
1086
e9576ca5 1087// Constructor
58603178
DS
1088bool wxWindowMac::Create(wxWindowMac *parent,
1089 wxWindowID id,
1090 const wxPoint& pos,
1091 const wxSize& size,
1092 long style,
1093 const wxString& name)
e9576ca5 1094{
902725ee 1095 wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") );
e9576ca5 1096
e7549107 1097 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
902725ee 1098 return false;
e9576ca5 1099
facd6764 1100 m_windowVariant = parent->GetWindowVariant() ;
8b573fb8 1101
facd6764
SC
1102 if ( m_macIsUserPane )
1103 {
1104 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
8b573fb8 1105
ebe86b1e 1106 UInt32 features = 0
8b573fb8 1107 | kControlSupportsEmbedding
1f1c8bd4
SC
1108 | kControlSupportsLiveFeedback
1109 | kControlGetsFocusOnClick
8b573fb8
VZ
1110// | kControlHasSpecialBackground
1111// | kControlSupportsCalcBestRect
1f1c8bd4 1112 | kControlHandlesTracking
8b573fb8 1113 | kControlSupportsFocus
1f1c8bd4 1114 | kControlWantsActivate
58603178 1115 | kControlWantsIdle ;
ebe86b1e 1116
6449b3a8 1117 m_peer = new wxMacControl(this) ;
58603178
DS
1118 OSStatus err =::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , m_peer->GetControlRefAddr() );
1119 verify_noerr( err );
8b573fb8 1120
898d9035 1121 MacPostControlCreate(pos, size) ;
facd6764 1122 }
898d9035 1123
e766c8a9 1124#ifndef __WXUNIVERSAL__
14c9cbdb 1125 // Don't give scrollbars to wxControls unless they ask for them
58603178
DS
1126 if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar)))
1127 || (IsKindOf(CLASSINFO(wxControl)) && ((style & wxHSCROLL) || (style & wxVSCROLL))))
6264b550
RR
1128 {
1129 MacCreateScrollBars( style ) ;
1130 }
e766c8a9 1131#endif
3dfafdb9
RD
1132
1133 wxWindowCreateEvent event(this);
7e4a196e 1134 GetEventHandler()->AddPendingEvent(event);
3dfafdb9 1135
902725ee 1136 return true;
e9576ca5
SC
1137}
1138
902725ee 1139void wxWindowMac::MacChildAdded()
08422003
SC
1140{
1141 if ( m_vScrollBar )
08422003 1142 m_vScrollBar->Raise() ;
08422003 1143 if ( m_hScrollBar )
08422003 1144 m_hScrollBar->Raise() ;
08422003
SC
1145}
1146
facd6764
SC
1147void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size)
1148{
21fd5529 1149 wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid mac control") ) ;
facd6764 1150
4f74e0d1 1151 m_peer->SetReference( (URefCon) this ) ;
58603178 1152 GetParent()->AddChild( this );
facd6764 1153
5ca0d812 1154 MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() );
facd6764
SC
1155
1156 ControlRef container = (ControlRef) GetParent()->GetHandle() ;
1157 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
5ca0d812 1158 ::EmbedControl( m_peer->GetControlRef() , container ) ;
08422003 1159 GetParent()->MacChildAdded() ;
facd6764
SC
1160
1161 // adjust font, controlsize etc
1162 DoSetWindowVariant( m_windowVariant ) ;
1163
32cd189d 1164 m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ;
facd6764 1165
facd6764 1166 if (!m_macIsUserPane)
170acdc9 1167 SetInitialSize(size);
facd6764
SC
1168
1169 SetCursor( *wxSTANDARD_CURSOR ) ;
facd6764
SC
1170}
1171
1172void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
1173{
23176131
JS
1174 // Don't assert, in case we set the window variant before
1175 // the window is created
21fd5529 1176 // wxASSERT( m_peer->Ok() ) ;
facd6764 1177
23176131
JS
1178 m_windowVariant = variant ;
1179
21fd5529 1180 if (m_peer == NULL || !m_peer->Ok())
23176131 1181 return;
facd6764 1182
8b573fb8 1183 ControlSize size ;
facd6764
SC
1184 ThemeFontID themeFont = kThemeSystemFont ;
1185
1186 // we will get that from the settings later
8b573fb8 1187 // and make this NORMAL later, but first
facd6764 1188 // we have a few calculations that we must fix
8b573fb8 1189
facd6764
SC
1190 switch ( variant )
1191 {
1192 case wxWINDOW_VARIANT_NORMAL :
8b573fb8
VZ
1193 size = kControlSizeNormal;
1194 themeFont = kThemeSystemFont ;
facd6764 1195 break ;
e15f0a5e 1196
facd6764 1197 case wxWINDOW_VARIANT_SMALL :
8b573fb8
VZ
1198 size = kControlSizeSmall;
1199 themeFont = kThemeSmallSystemFont ;
facd6764 1200 break ;
e15f0a5e 1201
facd6764
SC
1202 case wxWINDOW_VARIANT_MINI :
1203 if (UMAGetSystemVersion() >= 0x1030 )
1204 {
8b573fb8
VZ
1205 // not always defined in the headers
1206 size = 3 ;
1207 themeFont = 109 ;
facd6764
SC
1208 }
1209 else
1210 {
8b573fb8
VZ
1211 size = kControlSizeSmall;
1212 themeFont = kThemeSmallSystemFont ;
facd6764
SC
1213 }
1214 break ;
e15f0a5e 1215
facd6764 1216 case wxWINDOW_VARIANT_LARGE :
8b573fb8
VZ
1217 size = kControlSizeLarge;
1218 themeFont = kThemeSystemFont ;
facd6764 1219 break ;
e15f0a5e 1220
facd6764
SC
1221 default:
1222 wxFAIL_MSG(_T("unexpected window variant"));
1223 break ;
1224 }
e15f0a5e 1225
898d9035 1226 m_peer->SetData<ControlSize>(kControlEntireControl, kControlSizeTag, &size ) ;
facd6764
SC
1227
1228 wxFont font ;
1229 font.MacCreateThemeFont( themeFont ) ;
1230 SetFont( font ) ;
1231}
1232
8b573fb8 1233void wxWindowMac::MacUpdateControlFont()
facd6764 1234{
ac99838a 1235 m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
8b573fb8 1236 Refresh() ;
facd6764
SC
1237}
1238
1239bool wxWindowMac::SetFont(const wxFont& font)
1240{
58603178 1241 bool retval = wxWindowBase::SetFont( font );
8b573fb8 1242
facd6764 1243 MacUpdateControlFont() ;
8b573fb8 1244
facd6764
SC
1245 return retval;
1246}
1247
1248bool wxWindowMac::SetForegroundColour(const wxColour& col )
1249{
58603178 1250 bool retval = wxWindowBase::SetForegroundColour( col );
8b573fb8 1251
898d9035 1252 if (retval)
58603178 1253 MacUpdateControlFont();
8b573fb8 1254
898d9035 1255 return retval;
facd6764
SC
1256}
1257
1258bool wxWindowMac::SetBackgroundColour(const wxColour& col )
1259{
1260 if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol )
1261 return false ;
1262
1263 wxBrush brush ;
b52acd03 1264 wxColour newCol(GetBackgroundColour());
58603178 1265
26af4dbd 1266 if ( newCol == wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) )
facd6764 1267 brush.MacSetTheme( kThemeBrushDocumentWindowBackground ) ;
58603178 1268 else if ( newCol == wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ) )
8b573fb8 1269 brush.MacSetTheme( kThemeBrushDialogBackgroundActive ) ;
facd6764 1270 else
b52acd03 1271 brush.SetColour( newCol ) ;
e15f0a5e 1272
facd6764 1273 MacSetBackgroundBrush( brush ) ;
db7a550b 1274 MacUpdateControlFont() ;
8b573fb8 1275
facd6764
SC
1276 return true ;
1277}
1278
7ea087b7
SC
1279void wxWindowMac::MacSetBackgroundBrush( const wxBrush &brush )
1280{
1281 m_macBackgroundBrush = brush ;
1282 m_peer->SetBackground( brush ) ;
1283}
facd6764
SC
1284
1285bool wxWindowMac::MacCanFocus() const
1286{
90b4f7b5 1287 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
2e91d506
DS
1288 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1289 // but the value range is nowhere documented
90b4f7b5 1290 Boolean keyExistsAndHasValidFormat ;
2e91d506
DS
1291 CFIndex fullKeyboardAccess = CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1292 kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat );
1293
90b4f7b5 1294 if ( keyExistsAndHasValidFormat && fullKeyboardAccess > 0 )
2e91d506 1295 {
90b4f7b5 1296 return true ;
2e91d506 1297 }
90b4f7b5
SC
1298 else
1299 {
1300 UInt32 features = 0 ;
1301 m_peer->GetFeatures( &features ) ;
1302
1303 return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ;
1304 }
facd6764
SC
1305}
1306
e766c8a9 1307void wxWindowMac::SetFocus()
e9576ca5 1308{
e15f0a5e 1309 if ( !AcceptsFocus() )
7d0cfe71
SC
1310 return ;
1311
e15f0a5e
DS
1312 wxWindow* former = FindFocus() ;
1313 if ( former == this )
1314 return ;
1315
1316 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1317 // we can only leave in case of an error
1318 OSStatus err = m_peer->SetFocus( kControlFocusNextPart ) ;
1319 if ( err == errCouldntSetFocus )
1320 return ;
1321
e15f0a5e 1322 SetUserFocusWindow( (WindowRef)MacGetTopLevelWindowRef() );
f1d527c1
SC
1323
1324#if !TARGET_API_MAC_OSX
e15f0a5e
DS
1325 // emulate carbon events when running under CarbonLib where they are not natively available
1326 if ( former )
1327 {
1328 EventRef evRef = NULL ;
58603178
DS
1329
1330 err = MacCreateEvent(
1331 NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) ,
1332 kEventAttributeUserEvent , &evRef );
1333 verify_noerr( err );
f1d527c1 1334
e15f0a5e
DS
1335 wxMacCarbonEvent cEvent( evRef ) ;
1336 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) former->GetHandle() ) ;
1337 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNoPart ) ;
8b573fb8 1338
e15f0a5e 1339 wxMacWindowEventHandler( NULL , evRef , former ) ;
58603178 1340 ReleaseEvent( evRef ) ;
e15f0a5e 1341 }
f1d527c1 1342
e15f0a5e
DS
1343 // send new focus event
1344 {
1345 EventRef evRef = NULL ;
58603178
DS
1346
1347 err = MacCreateEvent(
1348 NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) ,
1349 kEventAttributeUserEvent , &evRef );
1350 verify_noerr( err );
8b573fb8 1351
e15f0a5e
DS
1352 wxMacCarbonEvent cEvent( evRef ) ;
1353 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) GetHandle() ) ;
1354 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNextPart ) ;
1355
1356 wxMacWindowEventHandler( NULL , evRef , this ) ;
58603178 1357 ReleaseEvent( evRef ) ;
6264b550 1358 }
e15f0a5e 1359#endif
e9576ca5
SC
1360}
1361
4116c221 1362void wxWindowMac::DoCaptureMouse()
e9576ca5 1363{
2a1f999f 1364 wxApp::s_captureWindow = this ;
e9576ca5
SC
1365}
1366
2e91d506 1367wxWindow * wxWindowBase::GetCapture()
90b959ae 1368{
2a1f999f 1369 return wxApp::s_captureWindow ;
90b959ae
SC
1370}
1371
4116c221 1372void wxWindowMac::DoReleaseMouse()
e9576ca5 1373{
2a1f999f 1374 wxApp::s_captureWindow = NULL ;
e9576ca5
SC
1375}
1376
e15f0a5e 1377#if wxUSE_DRAG_AND_DROP
e9576ca5 1378
e766c8a9 1379void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
e9576ca5 1380{
e15f0a5e 1381 if ( m_dropTarget != NULL )
e40298d5 1382 delete m_dropTarget;
6ed71b4f 1383
e40298d5 1384 m_dropTarget = pDropTarget;
e15f0a5e 1385 if ( m_dropTarget != NULL )
e40298d5 1386 {
58603178 1387 // TODO:
e40298d5 1388 }
e9576ca5
SC
1389}
1390
1391#endif
1392
2e91d506 1393// Old-style File Manager Drag & Drop
e766c8a9 1394void wxWindowMac::DragAcceptFiles(bool accept)
e9576ca5 1395{
58603178 1396 // TODO:
e9576ca5
SC
1397}
1398
055a486b
SC
1399// Returns the size of the native control. In the case of the toplevel window
1400// this is the content area root control
1401
facd6764 1402void wxWindowMac::MacGetPositionAndSizeFromControl(int& x, int& y,
8b573fb8 1403 int& w, int& h) const
e9576ca5 1404{
898d9035 1405 wxFAIL_MSG( wxT("Not currently supported") ) ;
e9576ca5
SC
1406}
1407
055a486b 1408// From a wx position / size calculate the appropriate size of the native control
8b573fb8 1409
898d9035
DS
1410bool wxWindowMac::MacGetBoundsForControl(
1411 const wxPoint& pos,
1412 const wxSize& size,
1413 int& x, int& y,
1414 int& w, int& h , bool adjustOrigin ) const
51abe921 1415{
5ca0d812 1416 // the desired size, minus the border pixels gives the correct size of the control
facd6764
SC
1417 x = (int)pos.x;
1418 y = (int)pos.y;
58603178
DS
1419
1420 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
898d9035
DS
1421 w = wxMax(size.x, 0) ; // WidthDefault( size.x );
1422 h = wxMax(size.y, 0) ; // HeightDefault( size.y ) ;
789ae0cf 1423
5ca0d812
SC
1424 x += MacGetLeftBorderSize() ;
1425 y += MacGetTopBorderSize() ;
1426 w -= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1427 h -= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
8b573fb8 1428
79392158
SC
1429 if ( adjustOrigin )
1430 AdjustForParentClientOrigin( x , y ) ;
789ae0cf 1431
7ebf5540 1432 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
789ae0cf 1433 if ( !GetParent()->IsTopLevel() )
7ebf5540
SC
1434 {
1435 x -= GetParent()->MacGetLeftBorderSize() ;
1436 y -= GetParent()->MacGetTopBorderSize() ;
1437 }
789ae0cf 1438
facd6764
SC
1439 return true ;
1440}
1441
42ef83fa 1442// Get window size (not client size)
facd6764
SC
1443void wxWindowMac::DoGetSize(int *x, int *y) const
1444{
1f1c8bd4
SC
1445 Rect bounds ;
1446 m_peer->GetRect( &bounds ) ;
8b573fb8 1447
e15f0a5e
DS
1448 if (x)
1449 *x = bounds.right - bounds.left + MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1450 if (y)
1451 *y = bounds.bottom - bounds.top + MacGetTopBorderSize() + MacGetBottomBorderSize() ;
facd6764
SC
1452}
1453
42ef83fa 1454// get the position of the bounds of this window in client coordinates of its parent
facd6764
SC
1455void wxWindowMac::DoGetPosition(int *x, int *y) const
1456{
1f1c8bd4
SC
1457 Rect bounds ;
1458 m_peer->GetRect( &bounds ) ;
902725ee 1459
1f1c8bd4
SC
1460 int x1 = bounds.left ;
1461 int y1 = bounds.top ;
789ae0cf 1462
bc2b0c1b
SC
1463 // get the wx window position from the native one
1464 x1 -= MacGetLeftBorderSize() ;
1465 y1 -= MacGetTopBorderSize() ;
1466
facd6764 1467 if ( !IsTopLevel() )
2b5f62a0 1468 {
facd6764
SC
1469 wxWindow *parent = GetParent();
1470 if ( parent )
8950f7cc 1471 {
e15f0a5e
DS
1472 // we must first adjust it to be in window coordinates of the parent,
1473 // as otherwise it gets lost by the ClientAreaOrigin fix
1a02aff9
SC
1474 x1 += parent->MacGetLeftBorderSize() ;
1475 y1 += parent->MacGetTopBorderSize() ;
e15f0a5e 1476
1a02aff9 1477 // and now to client coordinates
facd6764
SC
1478 wxPoint pt(parent->GetClientAreaOrigin());
1479 x1 -= pt.x ;
1480 y1 -= pt.y ;
6ed71b4f 1481 }
2b5f62a0 1482 }
e15f0a5e
DS
1483
1484 if (x)
1485 *x = x1 ;
1486 if (y)
1487 *y = y1 ;
facd6764 1488}
51abe921 1489
e766c8a9 1490void wxWindowMac::DoScreenToClient(int *x, int *y) const
e9576ca5 1491{
facd6764 1492 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
58603178 1493 wxCHECK_RET( window , wxT("TopLevel Window missing") ) ;
8b573fb8 1494
58603178 1495 Point localwhere = { 0, 0 } ;
519cb848 1496
58603178
DS
1497 if (x)
1498 localwhere.h = *x ;
1499 if (y)
1500 localwhere.v = *y ;
8b573fb8 1501
4f74e0d1 1502 wxMacGlobalToLocal( window , &localwhere ) ;
6ed71b4f 1503
58603178
DS
1504 if (x)
1505 *x = localwhere.h ;
1506 if (y)
1507 *y = localwhere.v ;
e15f0a5e 1508
2078220e 1509 MacRootWindowToWindow( x , y ) ;
8b573fb8 1510
facd6764 1511 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1512 if (x)
1513 *x -= origin.x ;
1514 if (y)
1515 *y -= origin.y ;
e9576ca5
SC
1516}
1517
e766c8a9 1518void wxWindowMac::DoClientToScreen(int *x, int *y) const
e9576ca5 1519{
facd6764 1520 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
8523a5f5 1521 wxCHECK_RET( window , wxT("TopLevel window missing") ) ;
14c9cbdb 1522
facd6764 1523 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1524 if (x)
1525 *x += origin.x ;
1526 if (y)
1527 *y += origin.y ;
14c9cbdb 1528
2078220e 1529 MacWindowToRootWindow( x , y ) ;
14c9cbdb 1530
58603178
DS
1531 Point localwhere = { 0, 0 };
1532 if (x)
1533 localwhere.h = *x ;
1534 if (y)
1535 localwhere.v = *y ;
e15f0a5e 1536
4f74e0d1 1537 wxMacLocalToGlobal( window, &localwhere ) ;
e15f0a5e 1538
58603178
DS
1539 if (x)
1540 *x = localwhere.h ;
1541 if (y)
1542 *y = localwhere.v ;
519cb848
SC
1543}
1544
e766c8a9 1545void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const
519cb848 1546{
1c310985 1547 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1548 if (x)
1549 *x += origin.x ;
1550 if (y)
1551 *y += origin.y ;
14c9cbdb 1552
1c310985
SC
1553 MacWindowToRootWindow( x , y ) ;
1554}
1555
1556void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const
1557{
1c310985 1558 MacRootWindowToWindow( x , y ) ;
facd6764
SC
1559
1560 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1561 if (x)
1562 *x -= origin.x ;
1563 if (y)
1564 *y -= origin.y ;
1c310985
SC
1565}
1566
1567void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
1568{
5ca0d812 1569 wxPoint pt ;
58603178 1570
e15f0a5e
DS
1571 if (x)
1572 pt.x = *x ;
1573 if (y)
1574 pt.y = *y ;
facd6764 1575
125c7984 1576 if ( !IsTopLevel() )
5437ff47
RD
1577 {
1578 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
1579 if (top)
5ca0d812
SC
1580 {
1581 pt.x -= MacGetLeftBorderSize() ;
1582 pt.y -= MacGetTopBorderSize() ;
1583 wxMacControl::Convert( &pt , m_peer , top->m_peer ) ;
1584 }
5437ff47 1585 }
8b573fb8 1586
e15f0a5e
DS
1587 if (x)
1588 *x = (int) pt.x ;
1589 if (y)
1590 *y = (int) pt.y ;
facd6764
SC
1591}
1592
1593void wxWindowMac::MacWindowToRootWindow( short *x , short *y ) const
1594{
1595 int x1 , y1 ;
e15f0a5e
DS
1596
1597 if (x)
1598 x1 = *x ;
1599 if (y)
1600 y1 = *y ;
1601
facd6764 1602 MacWindowToRootWindow( &x1 , &y1 ) ;
e15f0a5e
DS
1603
1604 if (x)
1605 *x = x1 ;
1606 if (y)
1607 *y = y1 ;
519cb848
SC
1608}
1609
1c310985 1610void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
519cb848 1611{
5ca0d812 1612 wxPoint pt ;
e15f0a5e
DS
1613
1614 if (x)
1615 pt.x = *x ;
1616 if (y)
1617 pt.y = *y ;
facd6764 1618
125c7984 1619 if ( !IsTopLevel() )
5ca0d812 1620 {
5c840e5b
SC
1621 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
1622 if (top)
1623 {
1624 wxMacControl::Convert( &pt , top->m_peer , m_peer ) ;
1625 pt.x += MacGetLeftBorderSize() ;
1626 pt.y += MacGetTopBorderSize() ;
1627 }
5ca0d812 1628 }
8b573fb8 1629
e15f0a5e
DS
1630 if (x)
1631 *x = (int) pt.x ;
1632 if (y)
1633 *y = (int) pt.y ;
e9576ca5
SC
1634}
1635
facd6764 1636void wxWindowMac::MacRootWindowToWindow( short *x , short *y ) const
e9576ca5 1637{
facd6764 1638 int x1 , y1 ;
e15f0a5e
DS
1639
1640 if (x)
1641 x1 = *x ;
1642 if (y)
1643 y1 = *y ;
1644
facd6764 1645 MacRootWindowToWindow( &x1 , &y1 ) ;
e15f0a5e
DS
1646
1647 if (x)
1648 *x = x1 ;
1649 if (y)
1650 *y = y1 ;
facd6764 1651}
6ed71b4f 1652
29281095
SC
1653void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom )
1654{
1655 RgnHandle rgn = NewRgn() ;
898d9035 1656
5ca0d812 1657 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
29281095 1658 {
898d9035
DS
1659 Rect structure, content ;
1660
29281095 1661 GetRegionBounds( rgn , &content ) ;
1f1c8bd4
SC
1662 m_peer->GetRect( &structure ) ;
1663 OffsetRect( &structure, -structure.left , -structure.top ) ;
902725ee 1664
1f1c8bd4 1665 left = content.left - structure.left ;
898d9035 1666 top = content.top - structure.top ;
1f1c8bd4
SC
1667 right = structure.right - content.right ;
1668 bottom = structure.bottom - content.bottom ;
29281095
SC
1669 }
1670 else
1671 {
1f1c8bd4 1672 left = top = right = bottom = 0 ;
29281095 1673 }
898d9035 1674
7596e51d 1675 DisposeRgn( rgn ) ;
29281095
SC
1676}
1677
facd6764
SC
1678wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const
1679{
1680 wxSize sizeTotal = size;
1681
1682 RgnHandle rgn = NewRgn() ;
5ca0d812 1683 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
6618870d 1684 {
898d9035 1685 Rect content, structure ;
facd6764 1686 GetRegionBounds( rgn , &content ) ;
1f1c8bd4 1687 m_peer->GetRect( &structure ) ;
898d9035 1688
1f1c8bd4 1689 // structure is in parent coordinates, but we only need width and height, so it's ok
6ed71b4f 1690
1f1c8bd4 1691 sizeTotal.x += (structure.right - structure.left) - (content.right - content.left) ;
8523a5f5 1692 sizeTotal.y += (structure.bottom - structure.top) - (content.bottom - content.top) ;
1f1c8bd4 1693 }
898d9035 1694
1f1c8bd4 1695 DisposeRgn( rgn ) ;
6ed71b4f 1696
e15f0a5e
DS
1697 sizeTotal.x += MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1698 sizeTotal.y += MacGetTopBorderSize() + MacGetBottomBorderSize() ;
6ed71b4f 1699
facd6764 1700 return sizeTotal;
e9576ca5
SC
1701}
1702
e9576ca5 1703// Get size *available for subwindows* i.e. excluding menu bar etc.
e15f0a5e 1704void wxWindowMac::DoGetClientSize( int *x, int *y ) const
e9576ca5 1705{
9453cf2b 1706 int ww, hh;
6ed71b4f 1707
facd6764
SC
1708 RgnHandle rgn = NewRgn() ;
1709 Rect content ;
5ca0d812 1710 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
facd6764 1711 GetRegionBounds( rgn , &content ) ;
facd6764 1712 else
5ca0d812 1713 m_peer->GetRect( &content ) ;
7596e51d 1714 DisposeRgn( rgn ) ;
789ae0cf 1715
facd6764
SC
1716 ww = content.right - content.left ;
1717 hh = content.bottom - content.top ;
6ed71b4f 1718
db7a550b 1719 if (m_hScrollBar && m_hScrollBar->IsShown() )
e905b636 1720 hh -= m_hScrollBar->GetSize().y ;
e15f0a5e 1721
db7a550b 1722 if (m_vScrollBar && m_vScrollBar->IsShown() )
e905b636 1723 ww -= m_vScrollBar->GetSize().x ;
e15f0a5e
DS
1724
1725 if (x)
1726 *x = ww;
1727 if (y)
1728 *y = hh;
facd6764
SC
1729}
1730
1731bool wxWindowMac::SetCursor(const wxCursor& cursor)
1732{
a3ab1c18 1733 if (m_cursor.IsSameAs(cursor))
902725ee 1734 return false;
facd6764 1735
2e573683 1736 if (!cursor.IsOk())
facd6764
SC
1737 {
1738 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
902725ee 1739 return false ;
facd6764
SC
1740 }
1741 else
1742 {
1743 if ( ! wxWindowBase::SetCursor( cursor ) )
902725ee 1744 return false ;
facd6764
SC
1745 }
1746
1747 wxASSERT_MSG( m_cursor.Ok(),
1748 wxT("cursor must be valid after call to the base version"));
8b573fb8 1749
2d1760d3 1750 wxWindowMac *mouseWin = 0 ;
facd6764 1751 {
789ae0cf
SC
1752 wxTopLevelWindowMac *tlw = MacGetTopLevelWindow() ;
1753 WindowRef window = (WindowRef) ( tlw ? tlw->MacGetWindowRef() : 0 ) ;
4f74e0d1
SC
1754
1755 ControlPartCode part ;
1756 ControlRef control ;
1757 Point pt ;
1758 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1759 HIPoint hiPoint ;
1760 HIGetMousePosition(kHICoordSpaceWindow, window, &hiPoint);
1761 pt.h = hiPoint.x;
1762 pt.v = hiPoint.y;
1763 #else
2d1760d3
SC
1764 CGrafPtr savePort ;
1765 Boolean swapped = QDSwapPort( GetWindowPort( window ) , &savePort ) ;
8b573fb8 1766
58603178
DS
1767 // TODO: If we ever get a GetCurrentEvent... replacement
1768 // for the mouse position, use it...
8b573fb8 1769
58603178
DS
1770
1771 GetMouse( &pt ) ;
4f74e0d1 1772#endif
789ae0cf 1773 control = wxMacFindControlUnderMouse( tlw , pt , window , &part ) ;
2d1760d3
SC
1774 if ( control )
1775 mouseWin = wxFindControlFromMacControl( control ) ;
8b573fb8 1776
4f74e0d1
SC
1777#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1778 if ( swapped )
2d1760d3 1779 QDSwapPort( savePort , NULL ) ;
4f74e0d1 1780#endif
facd6764 1781 }
2d1760d3
SC
1782
1783 if ( mouseWin == this && !wxIsBusy() )
facd6764 1784 m_cursor.MacInstall() ;
facd6764 1785
902725ee 1786 return true ;
519cb848
SC
1787}
1788
facd6764
SC
1789#if wxUSE_MENUS
1790bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
1791{
1792 menu->SetInvokingWindow(this);
1793 menu->UpdateUI();
8b573fb8 1794
851dee09 1795 if ( x == wxDefaultCoord && y == wxDefaultCoord )
971562cb
VS
1796 {
1797 wxPoint mouse = wxGetMousePosition();
898d9035
DS
1798 x = mouse.x;
1799 y = mouse.y;
971562cb
VS
1800 }
1801 else
1802 {
1803 ClientToScreen( &x , &y ) ;
1804 }
facd6764
SC
1805
1806 menu->MacBeforeDisplay( true ) ;
898d9035 1807 long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() , y, x, 0) ;
facd6764
SC
1808 if ( HiWord(menuResult) != 0 )
1809 {
e8027adb
SC
1810 MenuCommand macid;
1811 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &macid );
b46dde27
DS
1812 int id = wxMacCommandToId( macid );
1813 wxMenuItem* item = NULL ;
facd6764 1814 wxMenu* realmenu ;
58603178 1815 item = menu->FindItem( id, &realmenu ) ;
e8027adb
SC
1816 if ( item )
1817 {
1818 if (item->IsCheckable())
1819 item->Check( !item->IsChecked() ) ;
e15f0a5e 1820
e8027adb
SC
1821 menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
1822 }
facd6764 1823 }
facd6764 1824
898d9035 1825 menu->MacAfterDisplay( true ) ;
8523a5f5 1826 menu->SetInvokingWindow( NULL );
facd6764 1827
902725ee 1828 return true;
facd6764
SC
1829}
1830#endif
51abe921
SC
1831
1832// ----------------------------------------------------------------------------
1833// tooltips
1834// ----------------------------------------------------------------------------
1835
1836#if wxUSE_TOOLTIPS
1837
e766c8a9 1838void wxWindowMac::DoSetToolTip(wxToolTip *tooltip)
51abe921
SC
1839{
1840 wxWindowBase::DoSetToolTip(tooltip);
6ed71b4f 1841
6264b550
RR
1842 if ( m_tooltip )
1843 m_tooltip->SetWindow(this);
51abe921
SC
1844}
1845
898d9035 1846#endif
51abe921 1847
902725ee 1848void wxWindowMac::MacInvalidateBorders()
6449b3a8
SC
1849{
1850 if ( m_peer == NULL )
1851 return ;
1852
1853 bool vis = MacIsReallyShown() ;
1854 if ( !vis )
1855 return ;
902725ee 1856
6449b3a8
SC
1857 int outerBorder = MacGetLeftBorderSize() ;
1858 if ( m_peer->NeedsFocusRect() && m_peer->HasFocus() )
1859 outerBorder += 4 ;
1860
1861 if ( outerBorder == 0 )
1862 return ;
902725ee
WS
1863
1864 // now we know that we have something to do at all
6449b3a8
SC
1865
1866 // as the borders are drawn on the parent we have to properly invalidate all these areas
58603178
DS
1867 RgnHandle updateInner , updateOuter;
1868 Rect rect ;
6449b3a8
SC
1869
1870 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
58603178
DS
1871 updateInner = NewRgn() ;
1872 updateOuter = NewRgn() ;
1873
6449b3a8 1874 m_peer->GetRect( &rect ) ;
898d9035 1875 RectRgn( updateInner, &rect ) ;
6449b3a8 1876 InsetRect( &rect , -outerBorder , -outerBorder ) ;
898d9035
DS
1877 RectRgn( updateOuter, &rect ) ;
1878 DiffRgn( updateOuter, updateInner , updateOuter ) ;
e15f0a5e 1879
6449b3a8 1880#ifdef __WXMAC_OSX__
1f1c8bd4 1881 GetParent()->m_peer->SetNeedsDisplay( updateOuter ) ;
6449b3a8
SC
1882#else
1883 WindowRef tlw = (WindowRef) MacGetTopLevelWindowRef() ;
1884 if ( tlw )
1885 InvalWindowRgn( tlw , updateOuter ) ;
1886#endif
e15f0a5e 1887
58603178
DS
1888 DisposeRgn( updateOuter ) ;
1889 DisposeRgn( updateInner ) ;
6449b3a8
SC
1890}
1891
e766c8a9 1892void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
51abe921 1893{
db7a550b 1894 // this is never called for a toplevel window, so we know we have a parent
facd6764 1895 int former_x , former_y , former_w, former_h ;
db7a550b
SC
1896
1897 // Get true coordinates of former position
facd6764
SC
1898 DoGetPosition( &former_x , &former_y ) ;
1899 DoGetSize( &former_w , &former_h ) ;
db7a550b
SC
1900
1901 wxWindow *parent = GetParent();
1902 if ( parent )
1903 {
1904 wxPoint pt(parent->GetClientAreaOrigin());
1905 former_x += pt.x ;
1906 former_y += pt.y ;
1907 }
6ed71b4f 1908
29ee02df
SC
1909 int actualWidth = width ;
1910 int actualHeight = height ;
e40298d5
JS
1911 int actualX = x;
1912 int actualY = y;
6ed71b4f 1913
14c9cbdb 1914 if ((m_minWidth != -1) && (actualWidth < m_minWidth))
6264b550 1915 actualWidth = m_minWidth;
14c9cbdb 1916 if ((m_minHeight != -1) && (actualHeight < m_minHeight))
6264b550 1917 actualHeight = m_minHeight;
14c9cbdb 1918 if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
6264b550 1919 actualWidth = m_maxWidth;
14c9cbdb 1920 if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
902725ee 1921 actualHeight = m_maxHeight;
6ed71b4f 1922
898d9035 1923 bool doMove = false, doResize = false ;
6ed71b4f 1924
6264b550 1925 if ( actualX != former_x || actualY != former_y )
6264b550 1926 doMove = true ;
e15f0a5e 1927
6264b550 1928 if ( actualWidth != former_w || actualHeight != former_h )
6264b550 1929 doResize = true ;
6ed71b4f 1930
6264b550
RR
1931 if ( doMove || doResize )
1932 {
902725ee 1933 // as the borders are drawn outside the native control, we adjust now
1f1c8bd4 1934
902725ee
WS
1935 wxRect bounds( wxPoint( actualX + MacGetLeftBorderSize() ,actualY + MacGetTopBorderSize() ),
1936 wxSize( actualWidth - (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1f1c8bd4
SC
1937 actualHeight - (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1938
1939 Rect r ;
1940 wxMacRectToNative( &bounds , &r ) ;
1941
1942 if ( !GetParent()->IsTopLevel() )
1f1c8bd4 1943 wxMacWindowToNative( GetParent() , &r ) ;
8b573fb8 1944
6449b3a8 1945 MacInvalidateBorders() ;
902725ee 1946
5c840e5b 1947 m_cachedClippedRectValid = false ;
8b573fb8 1948 m_peer->SetRect( &r ) ;
902725ee 1949
e905b636 1950 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
91ae6e3a 1951
6449b3a8
SC
1952 MacInvalidateBorders() ;
1953
6264b550
RR
1954 MacRepositionScrollBars() ;
1955 if ( doMove )
1956 {
898d9035 1957 wxPoint point(actualX, actualY);
6264b550
RR
1958 wxMoveEvent event(point, m_windowId);
1959 event.SetEventObject(this);
1960 GetEventHandler()->ProcessEvent(event) ;
1961 }
e15f0a5e 1962
6264b550
RR
1963 if ( doResize )
1964 {
e40298d5 1965 MacRepositionScrollBars() ;
facd6764 1966 wxSize size(actualWidth, actualHeight);
e40298d5
JS
1967 wxSizeEvent event(size, m_windowId);
1968 event.SetEventObject(this);
1969 GetEventHandler()->ProcessEvent(event);
6264b550
RR
1970 }
1971 }
954fc50b
SC
1972}
1973
facd6764
SC
1974wxSize wxWindowMac::DoGetBestSize() const
1975{
eb69d46e
SC
1976 if ( m_macIsUserPane || IsTopLevel() )
1977 return wxWindowBase::DoGetBestSize() ;
8b573fb8 1978
facd6764 1979 Rect bestsize = { 0 , 0 , 0 , 0 } ;
facd6764 1980 int bestWidth, bestHeight ;
facd6764 1981
898d9035 1982 m_peer->GetBestRect( &bestsize ) ;
facd6764
SC
1983 if ( EmptyRect( &bestsize ) )
1984 {
898d9035
DS
1985 bestsize.left =
1986 bestsize.top = 0 ;
1987 bestsize.right =
facd6764 1988 bestsize.bottom = 16 ;
898d9035 1989
facd6764
SC
1990 if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
1991 {
1992 bestsize.bottom = 16 ;
1993 }
902725ee 1994#if wxUSE_SPINBTN
facd6764
SC
1995 else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) )
1996 {
8b573fb8 1997 bestsize.bottom = 24 ;
facd6764 1998 }
898d9035 1999#endif
facd6764
SC
2000 else
2001 {
8b573fb8 2002 // return wxWindowBase::DoGetBestSize() ;
facd6764
SC
2003 }
2004 }
2005
2006 bestWidth = bestsize.right - bestsize.left ;
2007 bestHeight = bestsize.bottom - bestsize.top ;
2008 if ( bestHeight < 10 )
2009 bestHeight = 13 ;
8b573fb8 2010
facd6764
SC
2011 return wxSize(bestWidth, bestHeight);
2012}
2013
954fc50b
SC
2014// set the size of the window: if the dimensions are positive, just use them,
2015// but if any of them is equal to -1, it means that we must find the value for
2016// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
2017// which case -1 is a valid value for x and y)
2018//
2019// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
2020// the width/height to best suit our contents, otherwise we reuse the current
2021// width/height
2022void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags)
2023{
2024 // get the current size and position...
2025 int currentX, currentY;
898d9035 2026 int currentW, currentH;
6ed71b4f 2027
898d9035 2028 GetPosition(&currentX, &currentY);
954fc50b 2029 GetSize(&currentW, &currentH);
6ed71b4f 2030
954fc50b
SC
2031 // ... and don't do anything (avoiding flicker) if it's already ok
2032 if ( x == currentX && y == currentY &&
769ac869 2033 width == currentW && height == currentH && ( height != -1 && width != -1 ) )
954fc50b 2034 {
e15f0a5e 2035 // TODO: REMOVE
6264b550 2036 MacRepositionScrollBars() ; // we might have a real position shift
898d9035 2037
954fc50b
SC
2038 return;
2039 }
6ed71b4f 2040
58603178
DS
2041 if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
2042 {
2043 if ( x == wxDefaultCoord )
2044 x = currentX;
2045 if ( y == wxDefaultCoord )
2046 y = currentY;
2047 }
6ed71b4f 2048
58603178 2049 AdjustForParentClientOrigin( x, y, sizeFlags );
6ed71b4f 2050
3dee36ae
WS
2051 wxSize size = wxDefaultSize;
2052 if ( width == wxDefaultCoord )
954fc50b
SC
2053 {
2054 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
2055 {
2056 size = DoGetBestSize();
2057 width = size.x;
2058 }
2059 else
2060 {
2061 // just take the current one
2062 width = currentW;
2063 }
2064 }
6ed71b4f 2065
3dee36ae 2066 if ( height == wxDefaultCoord )
954fc50b
SC
2067 {
2068 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
2069 {
3dee36ae 2070 if ( size.x == wxDefaultCoord )
954fc50b 2071 size = DoGetBestSize();
898d9035 2072 // else: already called DoGetBestSize() above
6ed71b4f 2073
954fc50b
SC
2074 height = size.y;
2075 }
2076 else
2077 {
2078 // just take the current one
2079 height = currentH;
2080 }
2081 }
6ed71b4f 2082
58603178 2083 DoMoveWindow( x, y, width, height );
e9576ca5 2084}
519cb848 2085
e766c8a9 2086wxPoint wxWindowMac::GetClientAreaOrigin() const
e9576ca5 2087{
facd6764
SC
2088 RgnHandle rgn = NewRgn() ;
2089 Rect content ;
04d4e684 2090 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
21638402
SC
2091 {
2092 GetRegionBounds( rgn , &content ) ;
2093 }
2094 else
2095 {
898d9035
DS
2096 content.left =
2097 content.top = 0 ;
21638402 2098 }
898d9035 2099
facd6764 2100 DisposeRgn( rgn ) ;
e15f0a5e
DS
2101
2102 return wxPoint( content.left + MacGetLeftBorderSize() , content.top + MacGetTopBorderSize() );
facd6764
SC
2103}
2104
2105void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight)
2106{
d0dec992 2107 if ( clientwidth != wxDefaultCoord || clientheight != wxDefaultCoord )
facd6764
SC
2108 {
2109 int currentclientwidth , currentclientheight ;
2110 int currentwidth , currentheight ;
2111
2112 GetClientSize( &currentclientwidth , &currentclientheight ) ;
2113 GetSize( &currentwidth , &currentheight ) ;
2114
3dee36ae 2115 DoSetSize( wxDefaultCoord , wxDefaultCoord , currentwidth + clientwidth - currentclientwidth ,
facd6764
SC
2116 currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ;
2117 }
e9576ca5
SC
2118}
2119
fb5246be 2120void wxWindowMac::SetLabel(const wxString& title)
e9576ca5 2121{
32cd189d 2122 m_label = wxStripMenuCodes(title, wxStrip_Mnemonics) ;
facd6764 2123
21fd5529 2124 if ( m_peer && m_peer->Ok() )
fb5246be 2125 m_peer->SetLabel( m_label ) ;
e15f0a5e 2126
facd6764 2127 Refresh() ;
519cb848
SC
2128}
2129
fb5246be 2130wxString wxWindowMac::GetLabel() const
519cb848 2131{
ed60b502 2132 return m_label ;
519cb848
SC
2133}
2134
8ab50549
SC
2135bool wxWindowMac::Show(bool show)
2136{
542f604f 2137 bool former = MacIsReallyShown() ;
8ab50549 2138 if ( !wxWindowBase::Show(show) )
902725ee 2139 return false;
8b573fb8 2140
58603178 2141 // TODO: use visibilityChanged Carbon Event for OSX
2c899c20 2142 if ( m_peer )
2c899c20 2143 m_peer->SetVisibility( show , true ) ;
e15f0a5e 2144
542f604f
SC
2145 if ( former != MacIsReallyShown() )
2146 MacPropagateVisibilityChanged() ;
898d9035 2147
902725ee 2148 return true;
8ab50549
SC
2149}
2150
47a8a4d5 2151void wxWindowMac::DoEnable(bool enable)
8ab50549 2152{
5ca0d812 2153 m_peer->Enable( enable ) ;
8ab50549
SC
2154}
2155
8b573fb8 2156//
8ab50549
SC
2157// status change propagations (will be not necessary for OSX later )
2158//
2159
facd6764
SC
2160void wxWindowMac::MacPropagateVisibilityChanged()
2161{
73fe67bd 2162#if !TARGET_API_MAC_OSX
facd6764 2163 MacVisibilityChanged() ;
8b573fb8 2164
e15f0a5e 2165 wxWindowMac *child;
71f2fb52 2166 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
facd6764
SC
2167 while ( node )
2168 {
e15f0a5e 2169 child = node->GetData();
facd6764 2170 if ( child->IsShown() )
e15f0a5e
DS
2171 child->MacPropagateVisibilityChanged() ;
2172
facd6764
SC
2173 node = node->GetNext();
2174 }
73fe67bd 2175#endif
facd6764
SC
2176}
2177
47a8a4d5 2178void wxWindowMac::OnEnabled(bool enabled)
e9576ca5 2179{
73fe67bd 2180#if !TARGET_API_MAC_OSX
8ab50549 2181 MacEnabledStateChanged() ;
73fe67bd 2182#endif
8ab50549
SC
2183}
2184
e15f0a5e 2185void wxWindowMac::MacPropagateHiliteChanged()
8ab50549 2186{
73fe67bd 2187#if !TARGET_API_MAC_OSX
8ab50549 2188 MacHiliteChanged() ;
8b573fb8 2189
e15f0a5e 2190 wxWindowMac *child;
71f2fb52 2191 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
8ab50549
SC
2192 while ( node )
2193 {
e15f0a5e 2194 child = node->GetData();
898d9035 2195 if (child /* && child->IsEnabled() */)
8ab50549 2196 child->MacPropagateHiliteChanged() ;
e15f0a5e 2197
8ab50549
SC
2198 node = node->GetNext();
2199 }
73fe67bd 2200#endif
8ab50549
SC
2201}
2202
2203//
2204// status change notifications
8b573fb8 2205//
8ab50549 2206
8b573fb8 2207void wxWindowMac::MacVisibilityChanged()
8ab50549
SC
2208{
2209}
2210
8b573fb8 2211void wxWindowMac::MacHiliteChanged()
8ab50549
SC
2212{
2213}
2214
8b573fb8 2215void wxWindowMac::MacEnabledStateChanged()
8ab50549 2216{
facd6764 2217}
e7549107 2218
8ab50549
SC
2219//
2220// status queries on the inherited window's state
2221//
2222
8b573fb8 2223bool wxWindowMac::MacIsReallyShown()
facd6764
SC
2224{
2225 // only under OSX the visibility of the TLW is taken into account
66ffb23b
SC
2226 if ( m_isBeingDeleted )
2227 return false ;
902725ee 2228
facd6764 2229#if TARGET_API_MAC_OSX
aa522e33
SC
2230 if ( m_peer && m_peer->Ok() )
2231 return m_peer->IsVisible();
2232#endif
e15f0a5e 2233
facd6764 2234 wxWindow* win = this ;
898d9035 2235 while ( win->IsShown() )
facd6764
SC
2236 {
2237 if ( win->IsTopLevel() )
2238 return true ;
8b573fb8 2239
facd6764
SC
2240 win = win->GetParent() ;
2241 if ( win == NULL )
2242 return true ;
e15f0a5e 2243 }
8b573fb8 2244
facd6764 2245 return false ;
facd6764 2246}
4241baae 2247
8b573fb8 2248bool wxWindowMac::MacIsReallyEnabled()
facd6764 2249{
5ca0d812 2250 return m_peer->IsEnabled() ;
facd6764
SC
2251}
2252
8b573fb8 2253bool wxWindowMac::MacIsReallyHilited()
c809f3be 2254{
5ca0d812 2255 return m_peer->IsActive();
c809f3be
SC
2256}
2257
8b573fb8 2258void wxWindowMac::MacFlashInvalidAreas()
002c9672
SC
2259{
2260#if TARGET_API_MAC_OSX
2261 HIViewFlashDirtyArea( (WindowRef) MacGetTopLevelWindowRef() ) ;
2262#endif
2263}
2264
e766c8a9 2265int wxWindowMac::GetCharHeight() const
e9576ca5 2266{
e15f0a5e
DS
2267 wxClientDC dc( (wxWindowMac*)this ) ;
2268
6264b550 2269 return dc.GetCharHeight() ;
e9576ca5
SC
2270}
2271
e766c8a9 2272int wxWindowMac::GetCharWidth() const
e9576ca5 2273{
e15f0a5e
DS
2274 wxClientDC dc( (wxWindowMac*)this ) ;
2275
6264b550 2276 return dc.GetCharWidth() ;
e9576ca5
SC
2277}
2278
e766c8a9 2279void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
e7549107 2280 int *descent, int *externalLeading, const wxFont *theFont ) const
e9576ca5 2281{
e7549107
SC
2282 const wxFont *fontToUse = theFont;
2283 if ( !fontToUse )
2284 fontToUse = &m_font;
14c9cbdb 2285
e766c8a9 2286 wxClientDC dc( (wxWindowMac*) this ) ;
659863d8 2287 wxCoord lx,ly,ld,le ;
5fde6fcc 2288 dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ;
2f1ae414 2289 if ( externalLeading )
6264b550 2290 *externalLeading = le ;
2f1ae414 2291 if ( descent )
6264b550 2292 *descent = ld ;
2f1ae414 2293 if ( x )
6264b550 2294 *x = lx ;
2f1ae414 2295 if ( y )
6264b550 2296 *y = ly ;
e9576ca5
SC
2297}
2298
0a67a93b 2299/*
14c9cbdb 2300 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
1c310985
SC
2301 * we always intersect with the entire window, not only with the client area
2302 */
14c9cbdb 2303
e766c8a9 2304void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect)
e9576ca5 2305{
065ab451
SC
2306 if ( m_peer == NULL )
2307 return ;
8b573fb8 2308
1f1c8bd4
SC
2309 if ( !MacIsReallyShown() )
2310 return ;
789ae0cf 2311
1f1c8bd4 2312 if ( rect )
1e8cde71 2313 {
1f1c8bd4 2314 Rect r ;
898d9035 2315
1f1c8bd4
SC
2316 wxMacRectToNative( rect , &r ) ;
2317 m_peer->SetNeedsDisplay( &r ) ;
facd6764 2318 }
1f1c8bd4 2319 else
9a456218 2320 {
1f1c8bd4 2321 m_peer->SetNeedsDisplay() ;
e9576ca5 2322 }
facd6764
SC
2323}
2324
79392158
SC
2325void wxWindowMac::Freeze()
2326{
2327#if TARGET_API_MAC_OSX
2328 if ( !m_frozenness++ )
2329 {
52ef5c3c
RD
2330 if ( m_peer && m_peer->Ok() )
2331 m_peer->SetDrawingEnabled( false ) ;
79392158
SC
2332 }
2333#endif
2334}
2335
2336void wxWindowMac::Thaw()
2337{
2338#if TARGET_API_MAC_OSX
898d9035 2339 wxASSERT_MSG( m_frozenness > 0, wxT("Thaw() without matching Freeze()") );
79392158
SC
2340
2341 if ( !--m_frozenness )
2342 {
52ef5c3c
RD
2343 if ( m_peer && m_peer->Ok() )
2344 {
2345 m_peer->SetDrawingEnabled( true ) ;
2346 m_peer->InvalidateWithChildren() ;
2347 }
79392158
SC
2348 }
2349#endif
2350}
2351
fd39f7a8
RD
2352bool wxWindowMac::IsFrozen() const
2353{
2354 return m_frozenness != 0;
2355}
2356
e766c8a9 2357wxWindowMac *wxGetActiveWindow()
e9576ca5 2358{
519cb848 2359 // actually this is a windows-only concept
e9576ca5
SC
2360 return NULL;
2361}
2362
e9576ca5 2363// Coordinates relative to the window
898d9035 2364void wxWindowMac::WarpPointer(int x_pos, int y_pos)
e9576ca5 2365{
e40298d5 2366 // We really don't move the mouse programmatically under Mac.
e9576ca5
SC
2367}
2368
facd6764 2369void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
e9576ca5 2370{
3dee36ae
WS
2371 if ( MacGetTopLevelWindow() == NULL )
2372 return ;
898d9035 2373
be346c26 2374#if TARGET_API_MAC_OSX
4488a1d3
VZ
2375 if ( !m_macBackgroundBrush.Ok() || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT
2376 || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
94abc21f 2377 {
facd6764 2378 event.Skip() ;
94abc21f
SC
2379 }
2380 else
be346c26 2381#endif
7ebf5540 2382 {
8b573fb8 2383 event.GetDC()->Clear() ;
7ebf5540 2384 }
1c310985
SC
2385}
2386
2387void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
2388{
af6b7b80 2389 event.Skip() ;
e9576ca5
SC
2390}
2391
e766c8a9 2392int wxWindowMac::GetScrollPos(int orient) const
e9576ca5 2393{
1c310985
SC
2394 if ( orient == wxHORIZONTAL )
2395 {
2396 if ( m_hScrollBar )
2397 return m_hScrollBar->GetThumbPosition() ;
2398 }
2399 else
2400 {
2401 if ( m_vScrollBar )
2402 return m_vScrollBar->GetThumbPosition() ;
2403 }
e15f0a5e 2404
e9576ca5
SC
2405 return 0;
2406}
2407
2408// This now returns the whole range, not just the number
2409// of positions that we can scroll.
e766c8a9 2410int wxWindowMac::GetScrollRange(int orient) const
e9576ca5 2411{
1c310985
SC
2412 if ( orient == wxHORIZONTAL )
2413 {
2414 if ( m_hScrollBar )
2415 return m_hScrollBar->GetRange() ;
2416 }
2417 else
2418 {
2419 if ( m_vScrollBar )
2420 return m_vScrollBar->GetRange() ;
2421 }
e15f0a5e 2422
e9576ca5
SC
2423 return 0;
2424}
2425
e766c8a9 2426int wxWindowMac::GetScrollThumb(int orient) const
e9576ca5 2427{
1c310985
SC
2428 if ( orient == wxHORIZONTAL )
2429 {
2430 if ( m_hScrollBar )
2431 return m_hScrollBar->GetThumbSize() ;
2432 }
2433 else
2434 {
2435 if ( m_vScrollBar )
2436 return m_vScrollBar->GetThumbSize() ;
2437 }
e15f0a5e 2438
e9576ca5
SC
2439 return 0;
2440}
2441
e766c8a9 2442void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh)
e9576ca5 2443{
1c310985 2444 if ( orient == wxHORIZONTAL )
6264b550 2445 {
1c310985
SC
2446 if ( m_hScrollBar )
2447 m_hScrollBar->SetThumbPosition( pos ) ;
6264b550
RR
2448 }
2449 else
2450 {
1c310985
SC
2451 if ( m_vScrollBar )
2452 m_vScrollBar->SetThumbPosition( pos ) ;
6264b550 2453 }
2f1ae414
SC
2454}
2455
c79aad8b
SC
2456//
2457// we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2458// our own window origin is at leftOrigin/rightOrigin
2459//
2460
2461void wxWindowMac::MacPaintBorders( int leftOrigin , int rightOrigin )
2f1ae414 2462{
e15f0a5e 2463 if ( IsTopLevel() )
6264b550 2464 return ;
8b573fb8 2465
fd926bcc 2466 Rect rect ;
c79aad8b 2467 bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ;
e15f0a5e 2468 bool hasBothScrollbars = (m_hScrollBar && m_hScrollBar->IsShown()) && (m_vScrollBar && m_vScrollBar->IsShown()) ;
c79aad8b 2469
8f39b6c4 2470 // back to the surrounding frame rectangle
58603178 2471 m_peer->GetRect( &rect ) ;
8f39b6c4 2472 InsetRect( &rect, -1 , -1 ) ;
fd926bcc 2473
4f74e0d1 2474#if wxMAC_USE_CORE_GRAPHICS
c79aad8b 2475 {
8f39b6c4
SC
2476 CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left ,
2477 rect.bottom - rect.top ) ;
2478
c79aad8b 2479 HIThemeFrameDrawInfo info ;
58603178 2480 memset( &info, 0 , sizeof(info) ) ;
902725ee 2481
c79aad8b
SC
2482 info.version = 0 ;
2483 info.kind = 0 ;
2484 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
2485 info.isFocused = hasFocus ;
c79aad8b
SC
2486
2487 CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ;
2488 wxASSERT( cgContext ) ;
902725ee 2489
e15f0a5e 2490 if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
c79aad8b 2491 {
c79aad8b 2492 info.kind = kHIThemeFrameTextFieldSquare ;
8f39b6c4 2493 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
c79aad8b 2494 }
e15f0a5e 2495 else if ( HasFlag(wxSIMPLE_BORDER) )
c79aad8b 2496 {
c79aad8b 2497 info.kind = kHIThemeFrameListBox ;
c79aad8b
SC
2498 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
2499 }
2500 else if ( hasFocus )
2501 {
c79aad8b
SC
2502 HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ;
2503 }
902725ee 2504
c79aad8b
SC
2505 m_peer->GetRect( &rect ) ;
2506 if ( hasBothScrollbars )
2507 {
c79aad8b 2508 int size = m_hScrollBar->GetWindowVariant() == wxWINDOW_VARIANT_NORMAL ? 16 : 12 ;
8f39b6c4
SC
2509 CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
2510 CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
902725ee 2511 HIThemeGrowBoxDrawInfo info ;
e15f0a5e 2512 memset( &info, 0, sizeof(info) ) ;
c79aad8b
SC
2513 info.version = 0 ;
2514 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
2515 info.kind = kHIThemeGrowBoxKindNone ;
2516 info.size = kHIThemeGrowBoxSizeNormal ;
2517 info.direction = kThemeGrowRight | kThemeGrowDown ;
2518 HIThemeDrawGrowBox( &cgpoint , &info , cgContext , kHIThemeOrientationNormal ) ;
2519 }
2520 }
4f74e0d1 2521 #else
fd926bcc
SC
2522 {
2523 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
e15f0a5e 2524 if ( top )
fd926bcc 2525 {
e15f0a5e 2526 wxPoint pt(0, 0) ;
fd926bcc 2527 wxMacControl::Convert( &pt , GetParent()->m_peer , top->m_peer ) ;
1f1c8bd4 2528 OffsetRect( &rect , pt.x , pt.y ) ;
fd926bcc 2529 }
8b573fb8 2530
e15f0a5e
DS
2531 if ( HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
2532 DrawThemeEditTextFrame( &rect, IsEnabled() ? kThemeStateActive : kThemeStateInactive ) ;
2533 else if ( HasFlag(wxSIMPLE_BORDER) )
2534 DrawThemeListBoxFrame( &rect, IsEnabled() ? kThemeStateActive : kThemeStateInactive ) ;
902725ee 2535
c79aad8b 2536 if ( hasFocus )
8f39b6c4 2537 DrawThemeFocusRect( &rect , true ) ;
8f39b6c4 2538
c79aad8b
SC
2539 if ( hasBothScrollbars )
2540 {
902725ee 2541 // GetThemeStandaloneGrowBoxBounds
e15f0a5e 2542 // DrawThemeStandaloneNoGrowBox
c79aad8b 2543 }
eec462f8 2544 }
4f74e0d1 2545#endif
8208e181
SC
2546}
2547
abda5788
SC
2548void wxWindowMac::RemoveChild( wxWindowBase *child )
2549{
2550 if ( child == m_hScrollBar )
2551 m_hScrollBar = NULL ;
2552 if ( child == m_vScrollBar )
2553 m_vScrollBar = NULL ;
14c9cbdb 2554
abda5788
SC
2555 wxWindowBase::RemoveChild( child ) ;
2556}
2557
e9576ca5 2558// New function that will replace some of the above.
e766c8a9 2559void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible,
e9576ca5
SC
2560 int range, bool refresh)
2561{
58603178 2562 bool showScroller;
42cc0b31 2563 bool triggerSizeEvent = false;
58603178 2564
e40298d5
JS
2565 if ( orient == wxHORIZONTAL )
2566 {
2567 if ( m_hScrollBar )
6264b550 2568 {
58603178
DS
2569 showScroller = ((range != 0) && (range > thumbVisible));
2570 if ( m_hScrollBar->IsShown() != showScroller )
42cc0b31
SC
2571 {
2572 m_hScrollBar->Show( showScroller );
2573 triggerSizeEvent = true;
2574 }
e15f0a5e 2575
11ca2edf 2576 m_hScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
6264b550 2577 }
e40298d5
JS
2578 }
2579 else
2580 {
2581 if ( m_vScrollBar )
6264b550 2582 {
58603178
DS
2583 showScroller = ((range != 0) && (range > thumbVisible));
2584 if ( m_vScrollBar->IsShown() != showScroller )
42cc0b31 2585 {
58603178 2586 m_vScrollBar->Show( showScroller ) ;
42cc0b31
SC
2587 triggerSizeEvent = true;
2588 }
e15f0a5e 2589
11ca2edf 2590 m_vScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
6264b550 2591 }
e40298d5 2592 }
e15f0a5e 2593
e40298d5 2594 MacRepositionScrollBars() ;
42cc0b31
SC
2595 if ( triggerSizeEvent )
2596 {
2597 wxSizeEvent event(GetSize(), m_windowId);
2598 event.SetEventObject(this);
2599 GetEventHandler()->ProcessEvent(event);
2600 }
e9576ca5
SC
2601}
2602
2603// Does a physical scroll
e766c8a9 2604void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
e9576ca5 2605{
898d9035 2606 if ( dx == 0 && dy == 0 )
ba87f54c 2607 return ;
8b573fb8 2608
3dee36ae
WS
2609 int width , height ;
2610 GetClientSize( &width , &height ) ;
e15f0a5e 2611
902725ee 2612 {
002c9672 2613 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
8b573fb8 2614 // area is scrolled, this does not occur if width and height are 2 pixels less,
58603178 2615 // TODO: write optimal workaround
898d9035 2616 wxRect scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ;
8b573fb8 2617 if ( rect )
5ca0d812 2618 scrollrect.Intersect( *rect ) ;
e15f0a5e 2619
5ca0d812 2620 if ( m_peer->GetNeedsDisplay() )
002c9672 2621 {
58603178 2622 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
8dd37b03 2623 // in case there is already a pending redraw on that area
002c9672
SC
2624 // either immediate redraw or full invalidate
2625#if 1
2626 // is the better overall solution, as it does not slow down scrolling
1f1c8bd4 2627 m_peer->SetNeedsDisplay() ;
002c9672 2628#else
8b573fb8 2629 // this would be the preferred version for fast drawing controls
92346151 2630
f474cc8c 2631#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
a9b456ff 2632 if ( UMAGetSystemVersion() >= 0x1030 )
42ef83fa 2633 HIViewRender(m_peer->GetControlRef()) ;
f474cc8c
SC
2634 else
2635#endif
2636 Update() ;
002c9672
SC
2637#endif
2638 }
e15f0a5e 2639
84e5d27d
SC
2640 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2641 scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
898d9035 2642 m_peer->ScrollRect( &scrollrect , dx , dy ) ;
92346151 2643
92346151 2644#if 0
902725ee 2645 // this would be the preferred version for fast drawing controls
4f74e0d1 2646 HIViewRender(m_peer->GetControlRef()) ;
92346151 2647#endif
902725ee 2648 }
6ed71b4f 2649
e15f0a5e
DS
2650 wxWindowMac *child;
2651 int x, y, w, h;
71f2fb52 2652 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
6264b550 2653 {
e15f0a5e
DS
2654 child = node->GetData();
2655 if (child == NULL)
2656 continue;
2657 if (child == m_vScrollBar)
2658 continue;
2659 if (child == m_hScrollBar)
2660 continue;
2661 if (child->IsTopLevel())
2662 continue;
6ed71b4f 2663
6264b550 2664 child->GetPosition( &x, &y );
6264b550 2665 child->GetSize( &w, &h );
00f55394
SC
2666 if (rect)
2667 {
e15f0a5e
DS
2668 wxRect rc( x, y, w, h );
2669 if (rect->Intersects( rc ))
8d1547ef 2670 child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
00f55394
SC
2671 }
2672 else
2673 {
8d1547ef 2674 child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
8b573fb8 2675 }
6264b550 2676 }
e9576ca5
SC
2677}
2678
e15f0a5e 2679void wxWindowMac::MacOnScroll( wxScrollEvent &event )
7c74e7fe 2680{
687706f5 2681 if ( event.GetEventObject() == m_vScrollBar || event.GetEventObject() == m_hScrollBar )
6264b550
RR
2682 {
2683 wxScrollWinEvent wevent;
2684 wevent.SetPosition(event.GetPosition());
2685 wevent.SetOrientation(event.GetOrientation());
687706f5
KH
2686 wevent.SetEventObject(this);
2687
2688 if (event.GetEventType() == wxEVT_SCROLL_TOP)
2689 wevent.SetEventType( wxEVT_SCROLLWIN_TOP );
2690 else if (event.GetEventType() == wxEVT_SCROLL_BOTTOM)
2691 wevent.SetEventType( wxEVT_SCROLLWIN_BOTTOM );
2692 else if (event.GetEventType() == wxEVT_SCROLL_LINEUP)
2693 wevent.SetEventType( wxEVT_SCROLLWIN_LINEUP );
2694 else if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN)
2695 wevent.SetEventType( wxEVT_SCROLLWIN_LINEDOWN );
2696 else if (event.GetEventType() == wxEVT_SCROLL_PAGEUP)
2697 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEUP );
2698 else if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN)
2699 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN );
2700 else if (event.GetEventType() == wxEVT_SCROLL_THUMBTRACK)
2701 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK );
2702 else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE)
2703 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE );
6ed71b4f
VZ
2704
2705 GetEventHandler()->ProcessEvent(wevent);
7c74e7fe
SC
2706 }
2707}
2708
e9576ca5 2709// Get the window with the focus
0fe02759 2710wxWindowMac *wxWindowBase::DoFindFocus()
e9576ca5 2711{
f1d527c1
SC
2712 ControlRef control ;
2713 GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
2714 return wxFindControlFromMacControl( control ) ;
519cb848
SC
2715}
2716
e15f0a5e 2717void wxWindowMac::OnSetFocus( wxFocusEvent& event )
7810c95b
SC
2718{
2719 // panel wants to track the window which was the last to have focus in it,
2720 // so we want to set ourselves as the window which last had focus
2721 //
dac390e9 2722 // notice that it's also important to do it upwards the tree because
7810c95b
SC
2723 // otherwise when the top level panel gets focus, it won't set it back to
2724 // us, but to some other sibling
6ed71b4f 2725
dac390e9 2726 // CS: don't know if this is still needed:
c1fb8167
SC
2727 //wxChildFocusEvent eventFocus(this);
2728 //(void)GetEventHandler()->ProcessEvent(eventFocus);
7810c95b 2729
5ca0d812
SC
2730 if ( MacGetTopLevelWindow() && m_peer->NeedsFocusRect() )
2731 {
dac390e9
DS
2732#if wxMAC_USE_CORE_GRAPHICS
2733 GetParent()->Refresh() ;
2734#else
788e118f 2735 wxMacWindowStateSaver sv( this ) ;
6449b3a8 2736 Rect rect ;
dac390e9 2737
6449b3a8 2738 m_peer->GetRect( &rect ) ;
8d1547ef 2739