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