]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/window.cpp
non-pch build fix
[wxWidgets.git] / src / mac / carbon / window.cpp
CommitLineData
e9576ca5 1/////////////////////////////////////////////////////////////////////////////
fb5246be 2// Name: src/mac/carbon/window.cpp
e766c8a9 3// Purpose: wxWindowMac
a31a5f85 4// Author: Stefan Csomor
e9576ca5 5// Modified by:
a31a5f85 6// Created: 1998-01-01
e9576ca5 7// RCS-ID: $Id$
a31a5f85 8// Copyright: (c) Stefan Csomor
65571936 9// Licence: wxWindows licence
e9576ca5
SC
10/////////////////////////////////////////////////////////////////////////////
11
3d1a4878
SC
12#include "wx/wxprec.h"
13
5fde6fcc 14#include "wx/window.h"
e4db172a
WS
15
16#ifndef WX_PRECOMP
17 #include "wx/log.h"
670f9935 18 #include "wx/app.h"
de6185e2 19 #include "wx/utils.h"
8e609c82 20 #include "wx/panel.h"
76b49cf4 21 #include "wx/frame.h"
da80ae71 22 #include "wx/dc.h"
ed4b0fdc 23 #include "wx/dcclient.h"
f1e01716 24 #include "wx/button.h"
3b3dc801 25 #include "wx/menu.h"
fdf565fe 26 #include "wx/dialog.h"
9eddec69 27 #include "wx/settings.h"
246c5004 28 #include "wx/msgdlg.h"
851dee09 29 #include "wx/scrolbar.h"
876cd6f7 30 #include "wx/statbox.h"
fec9cc08 31 #include "wx/textctrl.h"
4e3e485b 32 #include "wx/toolbar.h"
ed2fbeb8 33 #include "wx/layout.h"
3304646d 34 #include "wx/statusbr.h"
25466131 35 #include "wx/menuitem.h"
ed9a7a63
KO
36 #include "wx/treectrl.h"
37 #include "wx/listctrl.h"
e4db172a
WS
38#endif
39
2f1ae414 40#include "wx/tooltip.h"
4ac219f6 41#include "wx/spinctrl.h"
467e3168 42#include "wx/geometry.h"
e9576ca5 43
c1cef60b
CE
44#if wxUSE_LISTCTRL
45 #include "wx/listctrl.h"
46#endif
47
48#if wxUSE_TREECTRL
49 #include "wx/treectrl.h"
50#endif
51
7c551d95
SC
52#if wxUSE_CARET
53 #include "wx/caret.h"
e15f0a5e 54#endif
7c551d95 55
6239ee05
SC
56#if wxUSE_POPUPWIN
57 #include "wx/popupwin.h"
58#endif
59
b46dde27
DS
60#if wxUSE_DRAG_AND_DROP
61#include "wx/dnd.h"
62#endif
519cb848 63
d497dca4 64#include "wx/mac/uma.h"
898d9035 65
b46dde27
DS
66#define MAC_SCROLLBAR_SIZE 15
67#define MAC_SMALL_SCROLLBAR_SIZE 11
68
66a09d47
SC
69#ifndef __DARWIN__
70#include <Windows.h>
71#include <ToolUtils.h>
1d879215 72#include <MacTextEditor.h>
66a09d47 73#endif
519cb848 74
41218df1 75#if TARGET_API_MAC_OSX
facd6764 76#ifndef __HIVIEW__
8b573fb8 77 #include <HIToolbox/HIView.h>
facd6764 78#endif
41218df1 79#endif
facd6764 80
e9576ca5
SC
81#include <string.h>
82
fc0daf84
SC
83#ifdef __WXUNIVERSAL__
84 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase)
898d9035 85#else
fc0daf84 86 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
898d9035 87#endif
fc0daf84 88
fc0daf84 89BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase)
facd6764
SC
90 EVT_NC_PAINT(wxWindowMac::OnNcPaint)
91 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground)
ff3795ee
SC
92#if TARGET_API_MAC_OSX
93 EVT_PAINT(wxWindowMac::OnPaint)
94#endif
5ca0d812
SC
95 EVT_SET_FOCUS(wxWindowMac::OnSetFocus)
96 EVT_KILL_FOCUS(wxWindowMac::OnSetFocus)
facd6764 97 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent)
e9576ca5
SC
98END_EVENT_TABLE()
99
94abc21f
SC
100#define wxMAC_DEBUG_REDRAW 0
101#ifndef wxMAC_DEBUG_REDRAW
102#define wxMAC_DEBUG_REDRAW 0
103#endif
104
42ef83fa
SC
105// ---------------------------------------------------------------------------
106// Utility Routines to move between different coordinate systems
107// ---------------------------------------------------------------------------
108
109/*
110 * Right now we have the following setup :
111 * a border that is not part of the native control is always outside the
112 * control's border (otherwise we loose all native intelligence, future ways
113 * may be to have a second embedding control responsible for drawing borders
114 * and backgrounds eventually)
115 * so all this border calculations have to be taken into account when calling
116 * native methods or getting native oriented data
117 * so we have three coordinate systems here
118 * wx client coordinates
119 * wx window coordinates (including window frames)
120 * native coordinates
121 */
8b573fb8 122
42ef83fa
SC
123//
124// originating from native control
125//
126
127
128void wxMacNativeToWindow( const wxWindow* window , RgnHandle handle )
129{
8b573fb8 130 OffsetRgn( handle , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ;
42ef83fa
SC
131}
132
133void wxMacNativeToWindow( const wxWindow* window , Rect *rect )
134{
8b573fb8 135 OffsetRect( rect , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ;
42ef83fa
SC
136}
137
138//
139// directed towards native control
140//
141
142void wxMacWindowToNative( const wxWindow* window , RgnHandle handle )
143{
8b573fb8 144 OffsetRgn( handle , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() );
42ef83fa
SC
145}
146
147void wxMacWindowToNative( const wxWindow* window , Rect *rect )
148{
8b573fb8 149 OffsetRect( rect , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() ) ;
42ef83fa
SC
150}
151
facd6764
SC
152// ---------------------------------------------------------------------------
153// Carbon Events
154// ---------------------------------------------------------------------------
8b573fb8 155
f1d527c1
SC
156#if TARGET_API_MAC_OSX
157
8b573fb8 158#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3
898d9035
DS
159enum
160{
161 kEventControlVisibilityChanged = 157
c2697b87
SC
162};
163#endif
164
f1d527c1
SC
165#endif
166
facd6764
SC
167static const EventTypeSpec eventList[] =
168{
e3aeade0
SC
169 { kEventClassCommand, kEventProcessCommand } ,
170 { kEventClassCommand, kEventCommandUpdateStatus } ,
b46dde27 171
e9a4bf7d 172 { kEventClassControl , kEventControlGetClickActivation } ,
f1d527c1 173 { kEventClassControl , kEventControlHit } ,
898d9035 174
980ee83f
SC
175 { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
176 { kEventClassTextInput, kEventTextInputUpdateActiveInputArea } ,
b46dde27 177
73fe67bd 178 { kEventClassControl , kEventControlDraw } ,
cdef0334 179#if TARGET_API_MAC_OSX
73fe67bd
SC
180 { kEventClassControl , kEventControlVisibilityChanged } ,
181 { kEventClassControl , kEventControlEnabledStateChanged } ,
182 { kEventClassControl , kEventControlHiliteChanged } ,
ed9a7a63
KO
183
184 { kEventClassControl , kEventControlActivate } ,
185 { kEventClassControl , kEventControlDeactivate } ,
cdef0334 186#endif
f1d527c1 187 { kEventClassControl , kEventControlSetFocusPart } ,
8b573fb8
VZ
188
189 { kEventClassService , kEventServiceGetTypes },
190 { kEventClassService , kEventServiceCopy },
191 { kEventClassService , kEventServicePaste },
192
898d9035
DS
193// { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
194// { kEventClassControl , kEventControlBoundsChanged } ,
facd6764
SC
195} ;
196
197static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
198{
199 OSStatus result = eventNotHandledErr ;
200
201 wxMacCarbonEvent cEvent( event ) ;
8b573fb8 202
facd6764
SC
203 ControlRef controlRef ;
204 wxWindowMac* thisWindow = (wxWindowMac*) data ;
205
206 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
207
898d9035 208 switch ( GetEventKind( event ) )
facd6764 209 {
f1d527c1 210#if TARGET_API_MAC_OSX
facd6764
SC
211 case kEventControlDraw :
212 {
1e8cde71 213 RgnHandle updateRgn = NULL ;
055a486b 214 RgnHandle allocatedRgn = NULL ;
1e8cde71 215 wxRegion visRegion = thisWindow->MacGetVisibleRegion() ;
898d9035 216
76c7012c 217 if ( cEvent.GetParameter<RgnHandle>(kEventParamRgnHandle, &updateRgn) != noErr )
1e8cde71
SC
218 {
219 updateRgn = (RgnHandle) visRegion.GetWXHRGN() ;
220 }
055a486b
SC
221 else
222 {
a9b456ff 223 if ( thisWindow->MacGetLeftBorderSize() != 0 || thisWindow->MacGetTopBorderSize() != 0 )
055a486b 224 {
a9b456ff 225 // as this update region is in native window locals we must adapt it to wx window local
055a486b
SC
226 allocatedRgn = NewRgn() ;
227 CopyRgn( updateRgn , allocatedRgn ) ;
898d9035 228
42ef83fa
SC
229 // hide the given region by the new region that must be shifted
230 wxMacNativeToWindow( thisWindow , allocatedRgn ) ;
902725ee 231 updateRgn = allocatedRgn ;
e6616741 232 }
055a486b 233 }
e15f0a5e 234
e6616741
SC
235 Rect rgnBounds ;
236 GetRegionBounds( updateRgn , &rgnBounds ) ;
898d9035 237
1f1c8bd4 238#if wxMAC_DEBUG_REDRAW
facd6764
SC
239 if ( thisWindow->MacIsUserPane() )
240 {
bcbd6987
SC
241 static float color = 0.5 ;
242 static channel = 0 ;
898d9035
DS
243 HIRect bounds;
244 CGContextRef cgContext = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef) ;
245
246 HIViewGetBounds( controlRef, &bounds );
8b573fb8
VZ
247 CGContextSetRGBFillColor( cgContext, channel == 0 ? color : 0.5 ,
248 channel == 1 ? color : 0.5 , channel == 2 ? color : 0.5 , 1 );
249 CGContextFillRect( cgContext, bounds );
250 color += 0.1 ;
251 if ( color > 0.9 )
252 {
253 color = 0.5 ;
254 channel++ ;
255 if ( channel == 3 )
256 channel = 0 ;
257 }
facd6764 258 }
20b69855 259#endif
898d9035 260
c79aad8b 261 {
20b69855 262#if wxMAC_USE_CORE_GRAPHICS
e6616741 263 bool created = false ;
8523a5f5 264 CGContextRef cgContext = NULL ;
a9b456ff
SC
265 OSStatus err = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef, &cgContext) ;
266 wxASSERT_MSG( err == noErr , wxT("Unable to retrieve CGContextRef") ) ;
c79aad8b 267 thisWindow->MacSetCGContextRef( cgContext ) ;
898d9035 268
e6616741
SC
269 {
270 wxMacCGContextStateSaver sg( cgContext ) ;
a9b456ff
SC
271 float alpha = 1.0 ;
272 {
273 wxWindow* iter = thisWindow ;
89954433 274 while ( iter )
a9b456ff
SC
275 {
276 alpha *= (float) iter->GetTransparent()/255.0 ;
277 if ( iter->IsTopLevel() )
278 iter = NULL ;
279 else
280 iter = iter->GetParent() ;
281 }
282 }
283 CGContextSetAlpha( cgContext , alpha ) ;
4488a1d3
VZ
284
285 if ( thisWindow->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
286 {
287 HIRect bounds;
288 HIViewGetBounds( controlRef, &bounds );
289 CGContextClearRect( cgContext, bounds );
290 }
291
292
facd6764 293#endif
e6616741
SC
294 if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
295 result = noErr ;
898d9035 296
20b69855 297#if wxMAC_USE_CORE_GRAPHICS
e6616741
SC
298 thisWindow->MacSetCGContextRef( NULL ) ;
299 }
898d9035 300
e6616741 301 if ( created )
e6616741 302 CGContextRelease( cgContext ) ;
20b69855 303#endif
c79aad8b 304 }
e15f0a5e 305
055a486b
SC
306 if ( allocatedRgn )
307 DisposeRgn( allocatedRgn ) ;
facd6764
SC
308 }
309 break ;
e15f0a5e 310
73fe67bd 311 case kEventControlVisibilityChanged :
e15f0a5e 312 thisWindow->MacVisibilityChanged() ;
73fe67bd 313 break ;
e15f0a5e 314
73fe67bd 315 case kEventControlEnabledStateChanged :
e15f0a5e 316 thisWindow->MacEnabledStateChanged() ;
73fe67bd 317 break ;
e15f0a5e 318
73fe67bd 319 case kEventControlHiliteChanged :
e15f0a5e 320 thisWindow->MacHiliteChanged() ;
73fe67bd 321 break ;
89954433 322
ed9a7a63
KO
323 case kEventControlActivate :
324 case kEventControlDeactivate :
0b8055d2
VZ
325 // FIXME: we should have a virtual function for this!
326#if wxUSE_TREECTRL
327 if ( thisWindow->IsKindOf( CLASSINFO( wxTreeCtrl ) ) )
ed9a7a63 328 thisWindow->Refresh();
6449b3a8 329#endif
0b8055d2
VZ
330#if wxUSE_LISTCTRL
331 if ( thisWindow->IsKindOf( CLASSINFO( wxListCtrl ) ) )
332 thisWindow->Refresh();
333#endif
334 break ;
335#endif // TARGET_API_MAC_OSX
e15f0a5e 336
6449b3a8 337 // we emulate this event under Carbon CFM
f1d527c1
SC
338 case kEventControlSetFocusPart :
339 {
340 Boolean focusEverything = false ;
341 ControlPartCode controlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
898d9035 342
6449b3a8 343#ifdef __WXMAC_OSX__
f1d527c1
SC
344 if ( cEvent.GetParameter<Boolean>(kEventParamControlFocusEverything , &focusEverything ) == noErr )
345 {
346 }
6449b3a8 347#endif
e15f0a5e 348
6a74af89
VZ
349 if ( thisWindow->MacIsUserPane() )
350 result = noErr ;
351
f1d527c1
SC
352 if ( controlPart == kControlFocusNoPart )
353 {
e15f0a5e 354#if wxUSE_CARET
f1d527c1 355 if ( thisWindow->GetCaret() )
f1d527c1 356 thisWindow->GetCaret()->OnKillFocus();
e15f0a5e
DS
357#endif
358
92b6cd62 359 static bool inKillFocusEvent = false ;
898d9035 360
92b6cd62
SC
361 if ( !inKillFocusEvent )
362 {
363 inKillFocusEvent = true ;
364 wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
365 event.SetEventObject(thisWindow);
366 thisWindow->GetEventHandler()->ProcessEvent(event) ;
367 inKillFocusEvent = false ;
368 }
f1d527c1
SC
369 }
370 else
371 {
372 // panel wants to track the window which was the last to have focus in it
373 wxChildFocusEvent eventFocus(thisWindow);
374 thisWindow->GetEventHandler()->ProcessEvent(eventFocus);
8b573fb8 375
e15f0a5e 376#if wxUSE_CARET
f1d527c1 377 if ( thisWindow->GetCaret() )
f1d527c1 378 thisWindow->GetCaret()->OnSetFocus();
e15f0a5e 379#endif
f1d527c1
SC
380
381 wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
382 event.SetEventObject(thisWindow);
383 thisWindow->GetEventHandler()->ProcessEvent(event) ;
384 }
385 }
386 break ;
e15f0a5e 387
f1d527c1 388 case kEventControlHit :
e15f0a5e 389 result = thisWindow->MacControlHit( handler , event ) ;
f1d527c1 390 break ;
e15f0a5e 391
e9a4bf7d
SC
392 case kEventControlGetClickActivation :
393 {
394 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
395 WindowRef owner = cEvent.GetParameter<WindowRef>(kEventParamWindowRef);
396 if ( !IsWindowActive(owner) )
397 {
398 cEvent.SetParameter(kEventParamClickActivation,(UInt32) kActivateAndIgnoreClick) ;
399 result = noErr ;
400 }
401 }
402 break ;
403
facd6764
SC
404 default :
405 break ;
406 }
e15f0a5e 407
facd6764
SC
408 return result ;
409}
410
89954433
VZ
411static pascal OSStatus
412wxMacWindowServiceEventHandler(EventHandlerCallRef WXUNUSED(handler),
413 EventRef event,
414 void *data)
e4727773
SC
415{
416 OSStatus result = eventNotHandledErr ;
417
418 wxMacCarbonEvent cEvent( event ) ;
8b573fb8 419
e4727773
SC
420 ControlRef controlRef ;
421 wxWindowMac* thisWindow = (wxWindowMac*) data ;
422 wxTextCtrl* textCtrl = wxDynamicCast( thisWindow , wxTextCtrl ) ;
423 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
424
e15f0a5e 425 switch ( GetEventKind( event ) )
e4727773
SC
426 {
427 case kEventServiceGetTypes :
e15f0a5e 428 if ( textCtrl )
e4727773
SC
429 {
430 long from, to ;
431 textCtrl->GetSelection( &from , &to ) ;
432
8b573fb8 433 CFMutableArrayRef copyTypes = 0 , pasteTypes = 0;
e15f0a5e 434 if ( from != to )
e4727773
SC
435 copyTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServiceCopyTypes , typeCFMutableArrayRef ) ;
436 if ( textCtrl->IsEditable() )
437 pasteTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServicePasteTypes , typeCFMutableArrayRef ) ;
8b573fb8 438
898d9035 439 static const OSType textDataTypes[] = { kTXNTextData /* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
e4727773
SC
440 for ( size_t i = 0 ; i < WXSIZEOF(textDataTypes) ; ++i )
441 {
442 CFStringRef typestring = CreateTypeStringWithOSType(textDataTypes[i]);
443 if ( typestring )
444 {
445 if ( copyTypes )
898d9035 446 CFArrayAppendValue(copyTypes, typestring) ;
e4727773 447 if ( pasteTypes )
898d9035 448 CFArrayAppendValue(pasteTypes, typestring) ;
e15f0a5e 449
e4727773
SC
450 CFRelease( typestring ) ;
451 }
452 }
e15f0a5e 453
e4727773
SC
454 result = noErr ;
455 }
456 break ;
e15f0a5e 457
e4727773
SC
458 case kEventServiceCopy :
459 if ( textCtrl )
460 {
461 long from, to ;
e15f0a5e 462
e4727773
SC
463 textCtrl->GetSelection( &from , &to ) ;
464 wxString val = textCtrl->GetValue() ;
465 val = val.Mid( from , to - from ) ;
6239ee05
SC
466 PasteboardRef pasteboard = cEvent.GetParameter<PasteboardRef>( kEventParamPasteboardRef, typePasteboardRef );
467 verify_noerr( PasteboardClear( pasteboard ) ) ;
468 PasteboardSynchronize( pasteboard );
469 // TODO add proper conversion
470 CFDataRef data = CFDataCreate( kCFAllocatorDefault, (const UInt8*)val.c_str(), val.length() );
471 PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) 1, CFSTR("com.apple.traditional-mac-plain-text"), data, 0);
472 CFRelease( data );
e4727773
SC
473 result = noErr ;
474 }
475 break ;
e15f0a5e 476
e4727773
SC
477 case kEventServicePaste :
478 if ( textCtrl )
479 {
6239ee05
SC
480 PasteboardRef pasteboard = cEvent.GetParameter<PasteboardRef>( kEventParamPasteboardRef, typePasteboardRef );
481 PasteboardSynchronize( pasteboard );
482 ItemCount itemCount;
483 verify_noerr( PasteboardGetItemCount( pasteboard, &itemCount ) );
484 for( UInt32 itemIndex = 1; itemIndex <= itemCount; itemIndex++ )
485 {
486 PasteboardItemID itemID;
487 if ( PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ) == noErr )
488 {
489 CFDataRef flavorData = NULL;
490 if ( PasteboardCopyItemFlavorData( pasteboard, itemID, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData ) == noErr )
491 {
492 CFIndex flavorDataSize = CFDataGetLength( flavorData );
493 char *content = new char[flavorDataSize+1] ;
494 memcpy( content, CFDataGetBytePtr( flavorData ), flavorDataSize );
495 content[flavorDataSize]=0;
496 CFRelease( flavorData );
8ef4d6e2 497#if wxUSE_UNICODE
6239ee05 498 textCtrl->WriteText( wxString( content , wxConvLocal ) );
8ef4d6e2 499#else
6239ee05 500 textCtrl->WriteText( wxString( content ) ) ;
8ef4d6e2 501#endif
e15f0a5e 502
6239ee05
SC
503 delete[] content ;
504 result = noErr ;
505 }
506 }
507 }
e4727773
SC
508 }
509 break ;
e15f0a5e
DS
510
511 default:
512 break ;
e4727773 513 }
8b573fb8 514
e4727773 515 return result ;
8b573fb8 516}
e4727773 517
980ee83f
SC
518pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
519{
520 OSStatus result = eventNotHandledErr ;
521 wxWindowMac* focus = (wxWindowMac*) data ;
b46dde27 522
980ee83f
SC
523 wchar_t* uniChars = NULL ;
524 UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
b46dde27 525
75b32421 526 UniChar* charBuf = NULL;
4f74e0d1 527 ByteCount dataSize = 0 ;
980ee83f
SC
528 int numChars = 0 ;
529 UniChar buf[2] ;
530 if ( GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, 0 , &dataSize, NULL ) == noErr )
531 {
3281bf67 532 numChars = dataSize / sizeof( UniChar) + 1;
980ee83f 533 charBuf = buf ;
b46dde27 534
6d49e4bb 535 if ( (size_t) numChars * 2 > sizeof(buf) )
980ee83f
SC
536 charBuf = new UniChar[ numChars ] ;
537 else
538 charBuf = buf ;
b46dde27 539
980ee83f
SC
540 uniChars = new wchar_t[ numChars ] ;
541 GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, dataSize , NULL , charBuf ) ;
e4db172a 542 charBuf[ numChars - 1 ] = 0;
980ee83f 543#if SIZEOF_WCHAR_T == 2
cdef0334 544 uniChars = (wchar_t*) charBuf ;
5ca930b1 545/* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
980ee83f
SC
546#else
547 // the resulting string will never have more chars than the utf16 version, so this is safe
548 wxMBConvUTF16 converter ;
549 numChars = converter.MB2WC( uniChars , (const char*)charBuf , numChars ) ;
550#endif
551 }
b46dde27 552
980ee83f
SC
553 switch ( GetEventKind( event ) )
554 {
555 case kEventTextInputUpdateActiveInputArea :
556 {
557 // An IME input event may return several characters, but we need to send one char at a time to
558 // EVT_CHAR
559 for (int pos=0 ; pos < numChars ; pos++)
560 {
980ee83f
SC
561 WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
562 WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
563 wxTheApp->MacSetCurrentEvent( event , handler ) ;
b46dde27 564
5ca930b1
VZ
565 UInt32 message = uniChars[pos] < 128 ? (char)uniChars[pos] : '?';
566/*
567 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
568 multiple times to update the active range during inline input, so this handler will often receive
569 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
570 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
571 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
572 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
573 should add new event types to support advanced text input. For now, I would keep things as they are.
89954433 574
5ca930b1 575 However, the code that was being used caused additional problems:
980ee83f 576 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
5ca930b1
VZ
577 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
578 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
579 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
580 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
581 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
582 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
583 overlap with Unicode within the (7-bit) ASCII range.
584 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
585 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
586 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
587 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
588 I don't have time to look into that right now.
589 -- CL
590*/
980ee83f
SC
591 if ( wxTheApp->MacSendCharEvent(
592 focus , message , 0 , when , 0 , 0 , uniChars[pos] ) )
593 {
594 result = noErr ;
595 }
b46dde27 596
980ee83f
SC
597 wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
598 }
599 }
600 break ;
601 case kEventTextInputUnicodeForKeyEvent :
602 {
603 UInt32 keyCode, modifiers ;
604 Point point ;
605 EventRef rawEvent ;
606 unsigned char charCode ;
607
608 GetEventParameter( event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent ) ;
609 GetEventParameter( rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode );
610 GetEventParameter( rawEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
611 GetEventParameter( rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers );
612 GetEventParameter( rawEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point );
b46dde27 613
980ee83f 614 UInt32 message = (keyCode << 8) + charCode;
aa44b55d 615
980ee83f
SC
616 // An IME input event may return several characters, but we need to send one char at a time to
617 // EVT_CHAR
618 for (int pos=0 ; pos < numChars ; pos++)
619 {
980ee83f
SC
620 WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
621 WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
622 wxTheApp->MacSetCurrentEvent( event , handler ) ;
b46dde27 623
980ee83f
SC
624 if ( wxTheApp->MacSendCharEvent(
625 focus , message , modifiers , when , point.h , point.v , uniChars[pos] ) )
626 {
627 result = noErr ;
628 }
b46dde27 629
980ee83f
SC
630 wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
631 }
632 }
633 break;
634 default:
635 break ;
636 }
b46dde27
DS
637
638 delete [] uniChars ;
980ee83f 639 if ( charBuf != buf )
b46dde27 640 delete [] charBuf ;
2e91d506 641
980ee83f 642 return result ;
980ee83f
SC
643}
644
89954433
VZ
645static pascal OSStatus
646wxMacWindowCommandEventHandler(EventHandlerCallRef WXUNUSED(handler),
647 EventRef event,
648 void *data)
e3aeade0
SC
649{
650 OSStatus result = eventNotHandledErr ;
651 wxWindowMac* focus = (wxWindowMac*) data ;
b46dde27 652
e3aeade0 653 HICommand command ;
b46dde27 654
e3aeade0
SC
655 wxMacCarbonEvent cEvent( event ) ;
656 cEvent.GetParameter<HICommand>(kEventParamDirectObject,typeHICommand,&command) ;
b46dde27 657
e3aeade0
SC
658 wxMenuItem* item = NULL ;
659 wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ;
660 int id = wxMacCommandToId( command.commandID ) ;
b46dde27 661
e3aeade0
SC
662 if ( item )
663 {
664 wxASSERT( itemMenu != NULL ) ;
b46dde27 665
e3aeade0
SC
666 switch ( cEvent.GetKind() )
667 {
668 case kEventProcessCommand :
6239ee05 669 result = itemMenu->MacHandleCommandProcess( item, id, focus );
e3aeade0 670 break ;
b46dde27 671
e3aeade0 672 case kEventCommandUpdateStatus:
6239ee05 673 result = itemMenu->MacHandleCommandUpdateStatus( item, id, focus );
e3aeade0 674 break ;
b46dde27 675
e3aeade0
SC
676 default :
677 break ;
678 }
679 }
680 return result ;
681}
682
facd6764
SC
683pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
684{
af6b7b80
SC
685 EventRef formerEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ;
686 EventHandlerCallRef formerEventHandlerCallRef = (EventHandlerCallRef) wxTheApp->MacGetCurrentEventHandlerCallRef() ;
687 wxTheApp->MacSetCurrentEvent( event , handler ) ;
facd6764
SC
688 OSStatus result = eventNotHandledErr ;
689
690 switch ( GetEventClass( event ) )
691 {
e3aeade0
SC
692 case kEventClassCommand :
693 result = wxMacWindowCommandEventHandler( handler , event , data ) ;
694 break ;
695
facd6764
SC
696 case kEventClassControl :
697 result = wxMacWindowControlEventHandler( handler, event, data ) ;
698 break ;
e15f0a5e 699
e4727773
SC
700 case kEventClassService :
701 result = wxMacWindowServiceEventHandler( handler, event , data ) ;
902725ee 702 break ;
e15f0a5e 703
980ee83f
SC
704 case kEventClassTextInput :
705 result = wxMacUnicodeTextEventHandler( handler , event , data ) ;
706 break ;
b46dde27 707
facd6764
SC
708 default :
709 break ;
710 }
e15f0a5e 711
af6b7b80 712 wxTheApp->MacSetCurrentEvent( formerEvent, formerEventHandlerCallRef ) ;
e15f0a5e 713
facd6764
SC
714 return result ;
715}
716
717DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler )
718
20b69855
SC
719#if !TARGET_API_MAC_OSX
720
facd6764
SC
721// ---------------------------------------------------------------------------
722// UserPane events for non OSX builds
723// ---------------------------------------------------------------------------
8b573fb8 724
facd6764
SC
725static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part)
726{
727 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
728 if ( win )
729 win->MacControlUserPaneDrawProc(part) ;
facd6764 730}
1f1c8bd4 731wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP , wxMacControlUserPaneDrawProc ) ;
facd6764
SC
732
733static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where)
734{
735 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
736 if ( win )
737 return win->MacControlUserPaneHitTestProc(where.h , where.v) ;
738 else
739 return kControlNoPart ;
facd6764 740}
1f1c8bd4 741wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP , wxMacControlUserPaneHitTestProc ) ;
facd6764
SC
742
743static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc)
744{
745 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
746 if ( win )
747 return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc) ;
748 else
749 return kControlNoPart ;
facd6764 750}
1f1c8bd4 751wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP , wxMacControlUserPaneTrackingProc ) ;
facd6764
SC
752
753static pascal void wxMacControlUserPaneIdleProc(ControlRef control)
754{
755 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
756 if ( win )
757 win->MacControlUserPaneIdleProc() ;
facd6764 758}
1f1c8bd4 759wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP , wxMacControlUserPaneIdleProc ) ;
facd6764
SC
760
761static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
762{
763 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
764 if ( win )
765 return win->MacControlUserPaneKeyDownProc(keyCode,charCode,modifiers) ;
766 else
767 return kControlNoPart ;
facd6764 768}
1f1c8bd4 769wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP , wxMacControlUserPaneKeyDownProc ) ;
facd6764
SC
770
771static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating)
772{
773 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
774 if ( win )
775 win->MacControlUserPaneActivateProc(activating) ;
facd6764 776}
1f1c8bd4 777wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP , wxMacControlUserPaneActivateProc ) ;
facd6764
SC
778
779static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action)
780{
781 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
782 if ( win )
783 return win->MacControlUserPaneFocusProc(action) ;
784 else
785 return kControlNoPart ;
facd6764 786}
1f1c8bd4 787wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP , wxMacControlUserPaneFocusProc ) ;
facd6764
SC
788
789static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info)
790{
791 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
792 if ( win )
793 win->MacControlUserPaneBackgroundProc(info) ;
facd6764 794}
1f1c8bd4 795wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP , wxMacControlUserPaneBackgroundProc ) ;
facd6764 796
8b573fb8 797void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part)
facd6764 798{
e15f0a5e 799 int x = 0 , y = 0;
bcbd6987
SC
800 RgnHandle rgn = NewRgn() ;
801 GetClip( rgn ) ;
8523a5f5 802 MacWindowToRootWindow( &x, &y ) ;
d35bd499 803 OffsetRgn( rgn , -x , -y ) ;
bcbd6987
SC
804 wxMacWindowStateSaver sv( this ) ;
805 SectRgn( rgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , rgn ) ;
806 MacDoRedraw( rgn , 0 ) ;
807 DisposeRgn( rgn ) ;
facd6764
SC
808}
809
8b573fb8 810wxInt16 wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
facd6764
SC
811{
812 return kControlNoPart ;
813}
814
8b573fb8 815wxInt16 wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
facd6764
SC
816{
817 return kControlNoPart ;
818}
819
8b573fb8 820void wxWindowMac::MacControlUserPaneIdleProc()
facd6764
SC
821{
822}
823
8b573fb8 824wxInt16 wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
facd6764
SC
825{
826 return kControlNoPart ;
827}
828
8b573fb8 829void wxWindowMac::MacControlUserPaneActivateProc(bool activating)
facd6764
SC
830{
831}
832
8b573fb8 833wxInt16 wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action)
facd6764 834{
fb5246be
WS
835 if ( AcceptsFocus() )
836 return 1 ;
837 else
838 return kControlNoPart ;
facd6764
SC
839}
840
8b573fb8 841void wxWindowMac::MacControlUserPaneBackgroundProc(void* info)
facd6764
SC
842{
843}
844
20b69855
SC
845#endif
846
1f1c8bd4
SC
847// ---------------------------------------------------------------------------
848// Scrollbar Tracking for all
849// ---------------------------------------------------------------------------
850
851pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode ) ;
852pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode )
853{
854 if ( partCode != 0)
855 {
856 wxWindow* wx = wxFindControlFromMacControl( control ) ;
857 if ( wx )
1f1c8bd4 858 wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ;
1f1c8bd4
SC
859 }
860}
861wxMAC_DEFINE_PROC_GETTER( ControlActionUPP , wxMacLiveScrollbarActionProc ) ;
862
e7549107
SC
863// ===========================================================================
864// implementation
865// ===========================================================================
866
71f2fb52
RN
867WX_DECLARE_HASH_MAP(ControlRef, wxWindow*, wxPointerHash, wxPointerEqual, MacControlMap);
868
869static MacControlMap wxWinMacControlList;
870
871wxWindow *wxFindControlFromMacControl(ControlRef inControl )
872{
873 MacControlMap::iterator node = wxWinMacControlList.find(inControl);
874
875 return (node == wxWinMacControlList.end()) ? NULL : node->second;
876}
877
878void wxAssociateControlWithMacControl(ControlRef inControl, wxWindow *control)
879{
880 // adding NULL ControlRef is (first) surely a result of an error and
881 // (secondly) breaks native event processing
882 wxCHECK_RET( inControl != (ControlRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
883
884 wxWinMacControlList[inControl] = control;
885}
886
887void wxRemoveMacControlAssociation(wxWindow *control)
888{
889 // iterate over all the elements in the class
a8683134
SC
890 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
891 // we should go on...
892
893 bool found = true ;
e15f0a5e 894 while ( found )
71f2fb52 895 {
a8683134
SC
896 found = false ;
897 MacControlMap::iterator it;
898 for ( it = wxWinMacControlList.begin(); it != wxWinMacControlList.end(); ++it )
71f2fb52 899 {
a8683134
SC
900 if ( it->second == control )
901 {
902 wxWinMacControlList.erase(it);
903 found = true ;
904 break;
905 }
71f2fb52
RN
906 }
907 }
908}
facd6764 909
e7549107 910// ----------------------------------------------------------------------------
facd6764 911 // constructors and such
e7549107
SC
912// ----------------------------------------------------------------------------
913
94f9b1f0 914wxWindowMac::wxWindowMac()
8b573fb8
VZ
915{
916 Init();
94f9b1f0
SC
917}
918
919wxWindowMac::wxWindowMac(wxWindowMac *parent,
920 wxWindowID id,
921 const wxPoint& pos ,
922 const wxSize& size ,
923 long style ,
924 const wxString& name )
925{
926 Init();
927 Create(parent, id, pos, size, style, name);
928}
929
e766c8a9 930void wxWindowMac::Init()
519cb848 931{
21fd5529 932 m_peer = NULL ;
79392158 933 m_frozenness = 0 ;
a9b456ff 934 m_macAlpha = 255 ;
898d9035 935
e15f0a5e
DS
936#if wxMAC_USE_CORE_GRAPHICS
937 m_cgContextRef = NULL ;
938#endif
939
e7549107 940 // as all windows are created with WS_VISIBLE style...
902725ee 941 m_isShown = true;
e7549107 942
6264b550
RR
943 m_hScrollBar = NULL ;
944 m_vScrollBar = NULL ;
c1142003
VZ
945 m_hScrollBarAlwaysShown = false;
946 m_vScrollBarAlwaysShown = false;
947
facd6764
SC
948 m_macBackgroundBrush = wxNullBrush ;
949
902725ee 950 m_macIsUserPane = true;
8adc196b 951 m_clipChildren = false ;
5c840e5b 952 m_cachedClippedRectValid = false ;
e15f0a5e 953
c6f9fb05
SC
954 // we need a valid font for the encodings
955 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
e9576ca5
SC
956}
957
e766c8a9 958wxWindowMac::~wxWindowMac()
e9576ca5 959{
7de59551
RD
960 SendDestroyEvent();
961
902725ee 962 m_isBeingDeleted = true;
6ed71b4f 963
6449b3a8 964 MacInvalidateBorders() ;
7ebf5540 965
d4380aaf
SC
966#ifndef __WXUNIVERSAL__
967 // VS: make sure there's no wxFrame with last focus set to us:
968 for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
969 {
970 wxFrame *frame = wxDynamicCast(win, wxFrame);
971 if ( frame )
972 {
973 if ( frame->GetLastFocus() == this )
d4380aaf 974 frame->SetLastFocus((wxWindow*)NULL);
d4380aaf
SC
975 break;
976 }
977 }
b46dde27 978#endif
8b573fb8
VZ
979
980 // destroy children before destroying this window itself
981 DestroyChildren();
982
facd6764
SC
983 // wxRemoveMacControlAssociation( this ) ;
984 // If we delete an item, we should initialize the parent panel,
985 // because it could now be invalid.
6c20e8f8
VZ
986 wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow);
987 if ( tlw )
facd6764 988 {
6c20e8f8
VZ
989 if ( tlw->GetDefaultItem() == (wxButton*) this)
990 tlw->SetDefaultItem(NULL);
facd6764 991 }
e15f0a5e 992
21fd5529 993 if ( m_peer && m_peer->Ok() )
facd6764
SC
994 {
995 // in case the callback might be called during destruction
996 wxRemoveMacControlAssociation( this) ;
229f6270 997 ::RemoveEventHandler( (EventHandlerRef ) m_macControlEventHandler ) ;
5ca0d812
SC
998 // we currently are not using this hook
999 // ::SetControlColorProc( *m_peer , NULL ) ;
1000 m_peer->Dispose() ;
facd6764 1001 }
d4380aaf 1002
facd6764 1003 if ( g_MacLastWindow == this )
facd6764 1004 g_MacLastWindow = NULL ;
7de59551 1005
6239ee05
SC
1006#ifndef __WXUNIVERSAL__
1007 wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( (wxWindow*)this ) , wxFrame ) ;
fd76aa8d
SC
1008 if ( frame )
1009 {
e40298d5
JS
1010 if ( frame->GetLastFocus() == this )
1011 frame->SetLastFocus( NULL ) ;
fd76aa8d 1012 }
6239ee05 1013#endif
e7549107 1014
42683dfb
SC
1015 // delete our drop target if we've got one
1016#if wxUSE_DRAG_AND_DROP
1017 if ( m_dropTarget != NULL )
1018 {
1019 delete m_dropTarget;
1020 m_dropTarget = NULL;
1021 }
e15f0a5e
DS
1022#endif
1023
21fd5529
SC
1024 delete m_peer ;
1025}
1026
8b573fb8
VZ
1027WXWidget wxWindowMac::GetHandle() const
1028{
1029 return (WXWidget) m_peer->GetControlRef() ;
e9576ca5
SC
1030}
1031
5ca0d812 1032void wxWindowMac::MacInstallEventHandler( WXWidget control )
facd6764 1033{
898d9035
DS
1034 wxAssociateControlWithMacControl( (ControlRef) control , this ) ;
1035 InstallControlEventHandler( (ControlRef)control , GetwxMacWindowEventHandlerUPP(),
8b573fb8 1036 GetEventTypeCount(eventList), eventList, this,
facd6764 1037 (EventHandlerRef *)&m_macControlEventHandler);
e15f0a5e 1038
4a63451b
SC
1039#if !TARGET_API_MAC_OSX
1040 if ( (ControlRef) control == m_peer->GetControlRef() )
1041 {
898d9035
DS
1042 m_peer->SetData<ControlUserPaneDrawUPP>(kControlEntireControl, kControlUserPaneDrawProcTag, GetwxMacControlUserPaneDrawProc()) ;
1043 m_peer->SetData<ControlUserPaneHitTestUPP>(kControlEntireControl, kControlUserPaneHitTestProcTag, GetwxMacControlUserPaneHitTestProc()) ;
1044 m_peer->SetData<ControlUserPaneTrackingUPP>(kControlEntireControl, kControlUserPaneTrackingProcTag, GetwxMacControlUserPaneTrackingProc()) ;
1045 m_peer->SetData<ControlUserPaneIdleUPP>(kControlEntireControl, kControlUserPaneIdleProcTag, GetwxMacControlUserPaneIdleProc()) ;
1046 m_peer->SetData<ControlUserPaneKeyDownUPP>(kControlEntireControl, kControlUserPaneKeyDownProcTag, GetwxMacControlUserPaneKeyDownProc()) ;
1047 m_peer->SetData<ControlUserPaneActivateUPP>(kControlEntireControl, kControlUserPaneActivateProcTag, GetwxMacControlUserPaneActivateProc()) ;
1048 m_peer->SetData<ControlUserPaneFocusUPP>(kControlEntireControl, kControlUserPaneFocusProcTag, GetwxMacControlUserPaneFocusProc()) ;
1049 m_peer->SetData<ControlUserPaneBackgroundUPP>(kControlEntireControl, kControlUserPaneBackgroundProcTag, GetwxMacControlUserPaneBackgroundProc()) ;
4a63451b
SC
1050 }
1051#endif
facd6764
SC
1052}
1053
e9576ca5 1054// Constructor
58603178
DS
1055bool wxWindowMac::Create(wxWindowMac *parent,
1056 wxWindowID id,
1057 const wxPoint& pos,
1058 const wxSize& size,
1059 long style,
1060 const wxString& name)
e9576ca5 1061{
902725ee 1062 wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") );
e9576ca5 1063
e7549107 1064 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
902725ee 1065 return false;
e9576ca5 1066
facd6764 1067 m_windowVariant = parent->GetWindowVariant() ;
8b573fb8 1068
facd6764
SC
1069 if ( m_macIsUserPane )
1070 {
1071 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
8b573fb8 1072
ebe86b1e 1073 UInt32 features = 0
8b573fb8 1074 | kControlSupportsEmbedding
1f1c8bd4
SC
1075 | kControlSupportsLiveFeedback
1076 | kControlGetsFocusOnClick
8b573fb8
VZ
1077// | kControlHasSpecialBackground
1078// | kControlSupportsCalcBestRect
1f1c8bd4 1079 | kControlHandlesTracking
8b573fb8 1080 | kControlSupportsFocus
1f1c8bd4 1081 | kControlWantsActivate
58603178 1082 | kControlWantsIdle ;
ebe86b1e 1083
6449b3a8 1084 m_peer = new wxMacControl(this) ;
58603178
DS
1085 OSStatus err =::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , m_peer->GetControlRefAddr() );
1086 verify_noerr( err );
8b573fb8 1087
898d9035 1088 MacPostControlCreate(pos, size) ;
facd6764 1089 }
898d9035 1090
e766c8a9 1091#ifndef __WXUNIVERSAL__
14c9cbdb 1092 // Don't give scrollbars to wxControls unless they ask for them
58603178
DS
1093 if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar)))
1094 || (IsKindOf(CLASSINFO(wxControl)) && ((style & wxHSCROLL) || (style & wxVSCROLL))))
6264b550
RR
1095 {
1096 MacCreateScrollBars( style ) ;
1097 }
e766c8a9 1098#endif
3dfafdb9
RD
1099
1100 wxWindowCreateEvent event(this);
7e4a196e 1101 GetEventHandler()->AddPendingEvent(event);
3dfafdb9 1102
902725ee 1103 return true;
e9576ca5
SC
1104}
1105
902725ee 1106void wxWindowMac::MacChildAdded()
08422003
SC
1107{
1108 if ( m_vScrollBar )
08422003 1109 m_vScrollBar->Raise() ;
08422003 1110 if ( m_hScrollBar )
08422003 1111 m_hScrollBar->Raise() ;
08422003
SC
1112}
1113
89954433 1114void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), const wxSize& size)
facd6764 1115{
21fd5529 1116 wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid mac control") ) ;
facd6764 1117
4f74e0d1 1118 m_peer->SetReference( (URefCon) this ) ;
58603178 1119 GetParent()->AddChild( this );
facd6764 1120
5ca0d812 1121 MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() );
facd6764
SC
1122
1123 ControlRef container = (ControlRef) GetParent()->GetHandle() ;
1124 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
5ca0d812 1125 ::EmbedControl( m_peer->GetControlRef() , container ) ;
08422003 1126 GetParent()->MacChildAdded() ;
facd6764
SC
1127
1128 // adjust font, controlsize etc
1129 DoSetWindowVariant( m_windowVariant ) ;
1130
32cd189d 1131 m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ;
facd6764 1132
facd6764 1133 if (!m_macIsUserPane)
170acdc9 1134 SetInitialSize(size);
facd6764
SC
1135
1136 SetCursor( *wxSTANDARD_CURSOR ) ;
facd6764
SC
1137}
1138
1139void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
1140{
23176131
JS
1141 // Don't assert, in case we set the window variant before
1142 // the window is created
21fd5529 1143 // wxASSERT( m_peer->Ok() ) ;
facd6764 1144
23176131
JS
1145 m_windowVariant = variant ;
1146
21fd5529 1147 if (m_peer == NULL || !m_peer->Ok())
23176131 1148 return;
facd6764 1149
8b573fb8 1150 ControlSize size ;
facd6764
SC
1151 ThemeFontID themeFont = kThemeSystemFont ;
1152
1153 // we will get that from the settings later
8b573fb8 1154 // and make this NORMAL later, but first
facd6764 1155 // we have a few calculations that we must fix
8b573fb8 1156
facd6764
SC
1157 switch ( variant )
1158 {
1159 case wxWINDOW_VARIANT_NORMAL :
8b573fb8
VZ
1160 size = kControlSizeNormal;
1161 themeFont = kThemeSystemFont ;
facd6764 1162 break ;
e15f0a5e 1163
facd6764 1164 case wxWINDOW_VARIANT_SMALL :
8b573fb8
VZ
1165 size = kControlSizeSmall;
1166 themeFont = kThemeSmallSystemFont ;
facd6764 1167 break ;
e15f0a5e 1168
facd6764
SC
1169 case wxWINDOW_VARIANT_MINI :
1170 if (UMAGetSystemVersion() >= 0x1030 )
1171 {
8b573fb8
VZ
1172 // not always defined in the headers
1173 size = 3 ;
1174 themeFont = 109 ;
facd6764
SC
1175 }
1176 else
1177 {
8b573fb8
VZ
1178 size = kControlSizeSmall;
1179 themeFont = kThemeSmallSystemFont ;
facd6764
SC
1180 }
1181 break ;
e15f0a5e 1182
facd6764 1183 case wxWINDOW_VARIANT_LARGE :
8b573fb8
VZ
1184 size = kControlSizeLarge;
1185 themeFont = kThemeSystemFont ;
facd6764 1186 break ;
e15f0a5e 1187
facd6764
SC
1188 default:
1189 wxFAIL_MSG(_T("unexpected window variant"));
1190 break ;
1191 }
e15f0a5e 1192
898d9035 1193 m_peer->SetData<ControlSize>(kControlEntireControl, kControlSizeTag, &size ) ;
facd6764
SC
1194
1195 wxFont font ;
1196 font.MacCreateThemeFont( themeFont ) ;
1197 SetFont( font ) ;
1198}
1199
8b573fb8 1200void wxWindowMac::MacUpdateControlFont()
facd6764 1201{
ac99838a 1202 m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
6239ee05
SC
1203 // do not trigger refreshes upon invisible and possible partly created objects
1204 if ( MacIsReallyShown() )
1205 Refresh() ;
facd6764
SC
1206}
1207
1208bool wxWindowMac::SetFont(const wxFont& font)
1209{
58603178 1210 bool retval = wxWindowBase::SetFont( font );
8b573fb8 1211
facd6764 1212 MacUpdateControlFont() ;
8b573fb8 1213
facd6764
SC
1214 return retval;
1215}
1216
1217bool wxWindowMac::SetForegroundColour(const wxColour& col )
1218{
58603178 1219 bool retval = wxWindowBase::SetForegroundColour( col );
8b573fb8 1220
898d9035 1221 if (retval)
58603178 1222 MacUpdateControlFont();
8b573fb8 1223
898d9035 1224 return retval;
facd6764
SC
1225}
1226
1227bool wxWindowMac::SetBackgroundColour(const wxColour& col )
1228{
1229 if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol )
1230 return false ;
1231
1232 wxBrush brush ;
b52acd03 1233 wxColour newCol(GetBackgroundColour());
58603178 1234
26af4dbd 1235 if ( newCol == wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) )
facd6764 1236 brush.MacSetTheme( kThemeBrushDocumentWindowBackground ) ;
58603178 1237 else if ( newCol == wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ) )
8b573fb8 1238 brush.MacSetTheme( kThemeBrushDialogBackgroundActive ) ;
facd6764 1239 else
b52acd03 1240 brush.SetColour( newCol ) ;
e15f0a5e 1241
facd6764 1242 MacSetBackgroundBrush( brush ) ;
db7a550b 1243 MacUpdateControlFont() ;
8b573fb8 1244
facd6764
SC
1245 return true ;
1246}
1247
7ea087b7
SC
1248void wxWindowMac::MacSetBackgroundBrush( const wxBrush &brush )
1249{
1250 m_macBackgroundBrush = brush ;
1251 m_peer->SetBackground( brush ) ;
1252}
facd6764
SC
1253
1254bool wxWindowMac::MacCanFocus() const
1255{
90b4f7b5 1256 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
2e91d506
DS
1257 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1258 // but the value range is nowhere documented
90b4f7b5 1259 Boolean keyExistsAndHasValidFormat ;
2e91d506
DS
1260 CFIndex fullKeyboardAccess = CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1261 kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat );
1262
90b4f7b5 1263 if ( keyExistsAndHasValidFormat && fullKeyboardAccess > 0 )
2e91d506 1264 {
90b4f7b5 1265 return true ;
2e91d506 1266 }
90b4f7b5
SC
1267 else
1268 {
1269 UInt32 features = 0 ;
1270 m_peer->GetFeatures( &features ) ;
1271
1272 return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ;
1273 }
facd6764
SC
1274}
1275
e766c8a9 1276void wxWindowMac::SetFocus()
e9576ca5 1277{
e15f0a5e 1278 if ( !AcceptsFocus() )
7d0cfe71
SC
1279 return ;
1280
e15f0a5e
DS
1281 wxWindow* former = FindFocus() ;
1282 if ( former == this )
1283 return ;
1284
1285 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1286 // we can only leave in case of an error
1287 OSStatus err = m_peer->SetFocus( kControlFocusNextPart ) ;
1288 if ( err == errCouldntSetFocus )
1289 return ;
1290
e15f0a5e 1291 SetUserFocusWindow( (WindowRef)MacGetTopLevelWindowRef() );
f1d527c1
SC
1292
1293#if !TARGET_API_MAC_OSX
e15f0a5e
DS
1294 // emulate carbon events when running under CarbonLib where they are not natively available
1295 if ( former )
1296 {
1297 EventRef evRef = NULL ;
58603178
DS
1298
1299 err = MacCreateEvent(
1300 NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) ,
1301 kEventAttributeUserEvent , &evRef );
1302 verify_noerr( err );
f1d527c1 1303
e15f0a5e
DS
1304 wxMacCarbonEvent cEvent( evRef ) ;
1305 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) former->GetHandle() ) ;
1306 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNoPart ) ;
8b573fb8 1307
e15f0a5e 1308 wxMacWindowEventHandler( NULL , evRef , former ) ;
58603178 1309 ReleaseEvent( evRef ) ;
e15f0a5e 1310 }
f1d527c1 1311
e15f0a5e
DS
1312 // send new focus event
1313 {
1314 EventRef evRef = NULL ;
58603178
DS
1315
1316 err = MacCreateEvent(
1317 NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) ,
1318 kEventAttributeUserEvent , &evRef );
1319 verify_noerr( err );
8b573fb8 1320
e15f0a5e
DS
1321 wxMacCarbonEvent cEvent( evRef ) ;
1322 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) GetHandle() ) ;
1323 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNextPart ) ;
1324
1325 wxMacWindowEventHandler( NULL , evRef , this ) ;
58603178 1326 ReleaseEvent( evRef ) ;
6264b550 1327 }
e15f0a5e 1328#endif
e9576ca5
SC
1329}
1330
4116c221 1331void wxWindowMac::DoCaptureMouse()
e9576ca5 1332{
2a1f999f 1333 wxApp::s_captureWindow = this ;
e9576ca5
SC
1334}
1335
2e91d506 1336wxWindow * wxWindowBase::GetCapture()
90b959ae 1337{
2a1f999f 1338 return wxApp::s_captureWindow ;
90b959ae
SC
1339}
1340
4116c221 1341void wxWindowMac::DoReleaseMouse()
e9576ca5 1342{
2a1f999f 1343 wxApp::s_captureWindow = NULL ;
e9576ca5
SC
1344}
1345
e15f0a5e 1346#if wxUSE_DRAG_AND_DROP
e9576ca5 1347
e766c8a9 1348void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
e9576ca5 1349{
e15f0a5e 1350 if ( m_dropTarget != NULL )
e40298d5 1351 delete m_dropTarget;
6ed71b4f 1352
e40298d5 1353 m_dropTarget = pDropTarget;
e15f0a5e 1354 if ( m_dropTarget != NULL )
e40298d5 1355 {
58603178 1356 // TODO:
e40298d5 1357 }
e9576ca5
SC
1358}
1359
1360#endif
1361
2e91d506 1362// Old-style File Manager Drag & Drop
89954433 1363void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept))
e9576ca5 1364{
58603178 1365 // TODO:
e9576ca5
SC
1366}
1367
055a486b
SC
1368// Returns the size of the native control. In the case of the toplevel window
1369// this is the content area root control
1370
89954433
VZ
1371void wxWindowMac::MacGetPositionAndSizeFromControl(int& WXUNUSED(x),
1372 int& WXUNUSED(y),
1373 int& WXUNUSED(w),
1374 int& WXUNUSED(h)) const
e9576ca5 1375{
898d9035 1376 wxFAIL_MSG( wxT("Not currently supported") ) ;
e9576ca5
SC
1377}
1378
055a486b 1379// From a wx position / size calculate the appropriate size of the native control
8b573fb8 1380
898d9035
DS
1381bool wxWindowMac::MacGetBoundsForControl(
1382 const wxPoint& pos,
1383 const wxSize& size,
1384 int& x, int& y,
1385 int& w, int& h , bool adjustOrigin ) const
51abe921 1386{
5ca0d812 1387 // the desired size, minus the border pixels gives the correct size of the control
facd6764
SC
1388 x = (int)pos.x;
1389 y = (int)pos.y;
58603178
DS
1390
1391 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
898d9035
DS
1392 w = wxMax(size.x, 0) ; // WidthDefault( size.x );
1393 h = wxMax(size.y, 0) ; // HeightDefault( size.y ) ;
789ae0cf 1394
5ca0d812
SC
1395 x += MacGetLeftBorderSize() ;
1396 y += MacGetTopBorderSize() ;
1397 w -= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1398 h -= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
8b573fb8 1399
79392158
SC
1400 if ( adjustOrigin )
1401 AdjustForParentClientOrigin( x , y ) ;
789ae0cf 1402
7ebf5540 1403 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
789ae0cf 1404 if ( !GetParent()->IsTopLevel() )
7ebf5540
SC
1405 {
1406 x -= GetParent()->MacGetLeftBorderSize() ;
1407 y -= GetParent()->MacGetTopBorderSize() ;
1408 }
789ae0cf 1409
facd6764
SC
1410 return true ;
1411}
1412
42ef83fa 1413// Get window size (not client size)
facd6764
SC
1414void wxWindowMac::DoGetSize(int *x, int *y) const
1415{
1f1c8bd4
SC
1416 Rect bounds ;
1417 m_peer->GetRect( &bounds ) ;
8b573fb8 1418
e15f0a5e
DS
1419 if (x)
1420 *x = bounds.right - bounds.left + MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1421 if (y)
1422 *y = bounds.bottom - bounds.top + MacGetTopBorderSize() + MacGetBottomBorderSize() ;
facd6764
SC
1423}
1424
42ef83fa 1425// get the position of the bounds of this window in client coordinates of its parent
facd6764
SC
1426void wxWindowMac::DoGetPosition(int *x, int *y) const
1427{
1f1c8bd4
SC
1428 Rect bounds ;
1429 m_peer->GetRect( &bounds ) ;
902725ee 1430
1f1c8bd4
SC
1431 int x1 = bounds.left ;
1432 int y1 = bounds.top ;
789ae0cf 1433
bc2b0c1b
SC
1434 // get the wx window position from the native one
1435 x1 -= MacGetLeftBorderSize() ;
1436 y1 -= MacGetTopBorderSize() ;
1437
facd6764 1438 if ( !IsTopLevel() )
2b5f62a0 1439 {
facd6764
SC
1440 wxWindow *parent = GetParent();
1441 if ( parent )
8950f7cc 1442 {
e15f0a5e
DS
1443 // we must first adjust it to be in window coordinates of the parent,
1444 // as otherwise it gets lost by the ClientAreaOrigin fix
1a02aff9
SC
1445 x1 += parent->MacGetLeftBorderSize() ;
1446 y1 += parent->MacGetTopBorderSize() ;
e15f0a5e 1447
1a02aff9 1448 // and now to client coordinates
facd6764
SC
1449 wxPoint pt(parent->GetClientAreaOrigin());
1450 x1 -= pt.x ;
1451 y1 -= pt.y ;
6ed71b4f 1452 }
2b5f62a0 1453 }
e15f0a5e
DS
1454
1455 if (x)
1456 *x = x1 ;
1457 if (y)
1458 *y = y1 ;
facd6764 1459}
51abe921 1460
e766c8a9 1461void wxWindowMac::DoScreenToClient(int *x, int *y) const
e9576ca5 1462{
facd6764 1463 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
58603178 1464 wxCHECK_RET( window , wxT("TopLevel Window missing") ) ;
8b573fb8 1465
58603178 1466 Point localwhere = { 0, 0 } ;
519cb848 1467
58603178
DS
1468 if (x)
1469 localwhere.h = *x ;
1470 if (y)
1471 localwhere.v = *y ;
8b573fb8 1472
4f74e0d1 1473 wxMacGlobalToLocal( window , &localwhere ) ;
6ed71b4f 1474
58603178
DS
1475 if (x)
1476 *x = localwhere.h ;
1477 if (y)
1478 *y = localwhere.v ;
e15f0a5e 1479
2078220e 1480 MacRootWindowToWindow( x , y ) ;
8b573fb8 1481
facd6764 1482 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1483 if (x)
1484 *x -= origin.x ;
1485 if (y)
1486 *y -= origin.y ;
e9576ca5
SC
1487}
1488
e766c8a9 1489void wxWindowMac::DoClientToScreen(int *x, int *y) const
e9576ca5 1490{
facd6764 1491 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
8523a5f5 1492 wxCHECK_RET( window , wxT("TopLevel window missing") ) ;
14c9cbdb 1493
facd6764 1494 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1495 if (x)
1496 *x += origin.x ;
1497 if (y)
1498 *y += origin.y ;
14c9cbdb 1499
2078220e 1500 MacWindowToRootWindow( x , y ) ;
14c9cbdb 1501
58603178
DS
1502 Point localwhere = { 0, 0 };
1503 if (x)
1504 localwhere.h = *x ;
1505 if (y)
1506 localwhere.v = *y ;
e15f0a5e 1507
4f74e0d1 1508 wxMacLocalToGlobal( window, &localwhere ) ;
e15f0a5e 1509
58603178
DS
1510 if (x)
1511 *x = localwhere.h ;
1512 if (y)
1513 *y = localwhere.v ;
519cb848
SC
1514}
1515
e766c8a9 1516void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const
519cb848 1517{
1c310985 1518 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1519 if (x)
1520 *x += origin.x ;
1521 if (y)
1522 *y += origin.y ;
14c9cbdb 1523
1c310985
SC
1524 MacWindowToRootWindow( x , y ) ;
1525}
1526
1527void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const
1528{
1c310985 1529 MacRootWindowToWindow( x , y ) ;
facd6764
SC
1530
1531 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1532 if (x)
1533 *x -= origin.x ;
1534 if (y)
1535 *y -= origin.y ;
1c310985
SC
1536}
1537
1538void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
1539{
5ca0d812 1540 wxPoint pt ;
58603178 1541
e15f0a5e
DS
1542 if (x)
1543 pt.x = *x ;
1544 if (y)
1545 pt.y = *y ;
facd6764 1546
125c7984 1547 if ( !IsTopLevel() )
5437ff47
RD
1548 {
1549 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
1550 if (top)
5ca0d812
SC
1551 {
1552 pt.x -= MacGetLeftBorderSize() ;
1553 pt.y -= MacGetTopBorderSize() ;
1554 wxMacControl::Convert( &pt , m_peer , top->m_peer ) ;
1555 }
5437ff47 1556 }
8b573fb8 1557
e15f0a5e
DS
1558 if (x)
1559 *x = (int) pt.x ;
1560 if (y)
1561 *y = (int) pt.y ;
facd6764
SC
1562}
1563
1564void wxWindowMac::MacWindowToRootWindow( short *x , short *y ) const
1565{
1566 int x1 , y1 ;
e15f0a5e
DS
1567
1568 if (x)
1569 x1 = *x ;
1570 if (y)
1571 y1 = *y ;
1572
facd6764 1573 MacWindowToRootWindow( &x1 , &y1 ) ;
e15f0a5e
DS
1574
1575 if (x)
1576 *x = x1 ;
1577 if (y)
1578 *y = y1 ;
519cb848
SC
1579}
1580
1c310985 1581void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
519cb848 1582{
5ca0d812 1583 wxPoint pt ;
e15f0a5e
DS
1584
1585 if (x)
1586 pt.x = *x ;
1587 if (y)
1588 pt.y = *y ;
facd6764 1589
125c7984 1590 if ( !IsTopLevel() )
5ca0d812 1591 {
5c840e5b
SC
1592 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
1593 if (top)
1594 {
1595 wxMacControl::Convert( &pt , top->m_peer , m_peer ) ;
1596 pt.x += MacGetLeftBorderSize() ;
1597 pt.y += MacGetTopBorderSize() ;
1598 }
5ca0d812 1599 }
8b573fb8 1600
e15f0a5e
DS
1601 if (x)
1602 *x = (int) pt.x ;
1603 if (y)
1604 *y = (int) pt.y ;
e9576ca5
SC
1605}
1606
facd6764 1607void wxWindowMac::MacRootWindowToWindow( short *x , short *y ) const
e9576ca5 1608{
facd6764 1609 int x1 , y1 ;
e15f0a5e
DS
1610
1611 if (x)
1612 x1 = *x ;
1613 if (y)
1614 y1 = *y ;
1615
facd6764 1616 MacRootWindowToWindow( &x1 , &y1 ) ;
e15f0a5e
DS
1617
1618 if (x)
1619 *x = x1 ;
1620 if (y)
1621 *y = y1 ;
facd6764 1622}
6ed71b4f 1623
29281095
SC
1624void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom )
1625{
1626 RgnHandle rgn = NewRgn() ;
898d9035 1627
5ca0d812 1628 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
29281095 1629 {
898d9035
DS
1630 Rect structure, content ;
1631
29281095 1632 GetRegionBounds( rgn , &content ) ;
1f1c8bd4
SC
1633 m_peer->GetRect( &structure ) ;
1634 OffsetRect( &structure, -structure.left , -structure.top ) ;
902725ee 1635
1f1c8bd4 1636 left = content.left - structure.left ;
898d9035 1637 top = content.top - structure.top ;
1f1c8bd4
SC
1638 right = structure.right - content.right ;
1639 bottom = structure.bottom - content.bottom ;
29281095
SC
1640 }
1641 else
1642 {
1f1c8bd4 1643 left = top = right = bottom = 0 ;
29281095 1644 }
898d9035 1645
7596e51d 1646 DisposeRgn( rgn ) ;
29281095
SC
1647}
1648
facd6764
SC
1649wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const
1650{
1651 wxSize sizeTotal = size;
1652
1653 RgnHandle rgn = NewRgn() ;
5ca0d812 1654 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
6618870d 1655 {
898d9035 1656 Rect content, structure ;
facd6764 1657 GetRegionBounds( rgn , &content ) ;
1f1c8bd4 1658 m_peer->GetRect( &structure ) ;
898d9035 1659
1f1c8bd4 1660 // structure is in parent coordinates, but we only need width and height, so it's ok
6ed71b4f 1661
1f1c8bd4 1662 sizeTotal.x += (structure.right - structure.left) - (content.right - content.left) ;
8523a5f5 1663 sizeTotal.y += (structure.bottom - structure.top) - (content.bottom - content.top) ;
1f1c8bd4 1664 }
898d9035 1665
1f1c8bd4 1666 DisposeRgn( rgn ) ;
6ed71b4f 1667
e15f0a5e
DS
1668 sizeTotal.x += MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1669 sizeTotal.y += MacGetTopBorderSize() + MacGetBottomBorderSize() ;
6ed71b4f 1670
facd6764 1671 return sizeTotal;
e9576ca5
SC
1672}
1673
e9576ca5 1674// Get size *available for subwindows* i.e. excluding menu bar etc.
e15f0a5e 1675void wxWindowMac::DoGetClientSize( int *x, int *y ) const
e9576ca5 1676{
9453cf2b 1677 int ww, hh;
6ed71b4f 1678
facd6764
SC
1679 RgnHandle rgn = NewRgn() ;
1680 Rect content ;
5ca0d812 1681 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
facd6764 1682 GetRegionBounds( rgn , &content ) ;
facd6764 1683 else
5ca0d812 1684 m_peer->GetRect( &content ) ;
7596e51d 1685 DisposeRgn( rgn ) ;
789ae0cf 1686
facd6764
SC
1687 ww = content.right - content.left ;
1688 hh = content.bottom - content.top ;
6ed71b4f 1689
db7a550b 1690 if (m_hScrollBar && m_hScrollBar->IsShown() )
e905b636 1691 hh -= m_hScrollBar->GetSize().y ;
e15f0a5e 1692
db7a550b 1693 if (m_vScrollBar && m_vScrollBar->IsShown() )
e905b636 1694 ww -= m_vScrollBar->GetSize().x ;
e15f0a5e
DS
1695
1696 if (x)
1697 *x = ww;
1698 if (y)
1699 *y = hh;
facd6764
SC
1700}
1701
1702bool wxWindowMac::SetCursor(const wxCursor& cursor)
1703{
a3ab1c18 1704 if (m_cursor.IsSameAs(cursor))
902725ee 1705 return false;
facd6764 1706
2e573683 1707 if (!cursor.IsOk())
facd6764
SC
1708 {
1709 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
902725ee 1710 return false ;
facd6764
SC
1711 }
1712 else
1713 {
1714 if ( ! wxWindowBase::SetCursor( cursor ) )
902725ee 1715 return false ;
facd6764
SC
1716 }
1717
1718 wxASSERT_MSG( m_cursor.Ok(),
1719 wxT("cursor must be valid after call to the base version"));
8b573fb8 1720
2d1760d3 1721 wxWindowMac *mouseWin = 0 ;
facd6764 1722 {
789ae0cf
SC
1723 wxTopLevelWindowMac *tlw = MacGetTopLevelWindow() ;
1724 WindowRef window = (WindowRef) ( tlw ? tlw->MacGetWindowRef() : 0 ) ;
4f74e0d1
SC
1725
1726 ControlPartCode part ;
1727 ControlRef control ;
1728 Point pt ;
1729 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1730 HIPoint hiPoint ;
1731 HIGetMousePosition(kHICoordSpaceWindow, window, &hiPoint);
1732 pt.h = hiPoint.x;
1733 pt.v = hiPoint.y;
89954433 1734 #else
2d1760d3
SC
1735 CGrafPtr savePort ;
1736 Boolean swapped = QDSwapPort( GetWindowPort( window ) , &savePort ) ;
8b573fb8 1737
58603178
DS
1738 // TODO: If we ever get a GetCurrentEvent... replacement
1739 // for the mouse position, use it...
8b573fb8 1740
58603178
DS
1741
1742 GetMouse( &pt ) ;
4f74e0d1 1743#endif
789ae0cf 1744 control = wxMacFindControlUnderMouse( tlw , pt , window , &part ) ;
2d1760d3
SC
1745 if ( control )
1746 mouseWin = wxFindControlFromMacControl( control ) ;
8b573fb8 1747
4f74e0d1
SC
1748#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1749 if ( swapped )
2d1760d3 1750 QDSwapPort( savePort , NULL ) ;
4f74e0d1 1751#endif
facd6764 1752 }
2d1760d3
SC
1753
1754 if ( mouseWin == this && !wxIsBusy() )
facd6764 1755 m_cursor.MacInstall() ;
facd6764 1756
902725ee 1757 return true ;
519cb848
SC
1758}
1759
facd6764
SC
1760#if wxUSE_MENUS
1761bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
1762{
6239ee05
SC
1763#ifndef __WXUNIVERSAL__
1764 menu->SetInvokingWindow((wxWindow*)this);
facd6764 1765 menu->UpdateUI();
8b573fb8 1766
851dee09 1767 if ( x == wxDefaultCoord && y == wxDefaultCoord )
971562cb
VS
1768 {
1769 wxPoint mouse = wxGetMousePosition();
898d9035
DS
1770 x = mouse.x;
1771 y = mouse.y;
971562cb
VS
1772 }
1773 else
1774 {
1775 ClientToScreen( &x , &y ) ;
1776 }
facd6764
SC
1777
1778 menu->MacBeforeDisplay( true ) ;
898d9035 1779 long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() , y, x, 0) ;
facd6764
SC
1780 if ( HiWord(menuResult) != 0 )
1781 {
e8027adb
SC
1782 MenuCommand macid;
1783 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &macid );
b46dde27
DS
1784 int id = wxMacCommandToId( macid );
1785 wxMenuItem* item = NULL ;
facd6764 1786 wxMenu* realmenu ;
58603178 1787 item = menu->FindItem( id, &realmenu ) ;
e8027adb
SC
1788 if ( item )
1789 {
1790 if (item->IsCheckable())
1791 item->Check( !item->IsChecked() ) ;
e15f0a5e 1792
e8027adb
SC
1793 menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
1794 }
facd6764 1795 }
facd6764 1796
898d9035 1797 menu->MacAfterDisplay( true ) ;
8523a5f5 1798 menu->SetInvokingWindow( NULL );
facd6764 1799
902725ee 1800 return true;
6239ee05
SC
1801#else
1802 // actually this shouldn't be called, because universal is having its own implementation
1803 return false;
1804#endif
facd6764
SC
1805}
1806#endif
51abe921
SC
1807
1808// ----------------------------------------------------------------------------
1809// tooltips
1810// ----------------------------------------------------------------------------
1811
1812#if wxUSE_TOOLTIPS
1813
e766c8a9 1814void wxWindowMac::DoSetToolTip(wxToolTip *tooltip)
51abe921
SC
1815{
1816 wxWindowBase::DoSetToolTip(tooltip);
6ed71b4f 1817
6264b550
RR
1818 if ( m_tooltip )
1819 m_tooltip->SetWindow(this);
51abe921
SC
1820}
1821
898d9035 1822#endif
51abe921 1823
902725ee 1824void wxWindowMac::MacInvalidateBorders()
6449b3a8
SC
1825{
1826 if ( m_peer == NULL )
1827 return ;
1828
1829 bool vis = MacIsReallyShown() ;
1830 if ( !vis )
1831 return ;
902725ee 1832
6449b3a8
SC
1833 int outerBorder = MacGetLeftBorderSize() ;
1834 if ( m_peer->NeedsFocusRect() && m_peer->HasFocus() )
1835 outerBorder += 4 ;
1836
1837 if ( outerBorder == 0 )
1838 return ;
902725ee
WS
1839
1840 // now we know that we have something to do at all
6449b3a8
SC
1841
1842 // as the borders are drawn on the parent we have to properly invalidate all these areas
58603178
DS
1843 RgnHandle updateInner , updateOuter;
1844 Rect rect ;
6449b3a8
SC
1845
1846 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
58603178
DS
1847 updateInner = NewRgn() ;
1848 updateOuter = NewRgn() ;
1849
6449b3a8 1850 m_peer->GetRect( &rect ) ;
898d9035 1851 RectRgn( updateInner, &rect ) ;
6449b3a8 1852 InsetRect( &rect , -outerBorder , -outerBorder ) ;
898d9035
DS
1853 RectRgn( updateOuter, &rect ) ;
1854 DiffRgn( updateOuter, updateInner , updateOuter ) ;
e15f0a5e 1855
6449b3a8 1856#ifdef __WXMAC_OSX__
1f1c8bd4 1857 GetParent()->m_peer->SetNeedsDisplay( updateOuter ) ;
6449b3a8
SC
1858#else
1859 WindowRef tlw = (WindowRef) MacGetTopLevelWindowRef() ;
1860 if ( tlw )
1861 InvalWindowRgn( tlw , updateOuter ) ;
1862#endif
e15f0a5e 1863
58603178
DS
1864 DisposeRgn( updateOuter ) ;
1865 DisposeRgn( updateInner ) ;
6449b3a8
SC
1866}
1867
e766c8a9 1868void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
51abe921 1869{
db7a550b 1870 // this is never called for a toplevel window, so we know we have a parent
facd6764 1871 int former_x , former_y , former_w, former_h ;
db7a550b
SC
1872
1873 // Get true coordinates of former position
facd6764
SC
1874 DoGetPosition( &former_x , &former_y ) ;
1875 DoGetSize( &former_w , &former_h ) ;
db7a550b
SC
1876
1877 wxWindow *parent = GetParent();
1878 if ( parent )
1879 {
1880 wxPoint pt(parent->GetClientAreaOrigin());
1881 former_x += pt.x ;
1882 former_y += pt.y ;
1883 }
6ed71b4f 1884
29ee02df
SC
1885 int actualWidth = width ;
1886 int actualHeight = height ;
e40298d5
JS
1887 int actualX = x;
1888 int actualY = y;
6ed71b4f 1889
14c9cbdb 1890 if ((m_minWidth != -1) && (actualWidth < m_minWidth))
6264b550 1891 actualWidth = m_minWidth;
14c9cbdb 1892 if ((m_minHeight != -1) && (actualHeight < m_minHeight))
6264b550 1893 actualHeight = m_minHeight;
14c9cbdb 1894 if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
6264b550 1895 actualWidth = m_maxWidth;
14c9cbdb 1896 if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
902725ee 1897 actualHeight = m_maxHeight;
6ed71b4f 1898
898d9035 1899 bool doMove = false, doResize = false ;
6ed71b4f 1900
6264b550 1901 if ( actualX != former_x || actualY != former_y )
6264b550 1902 doMove = true ;
e15f0a5e 1903
6264b550 1904 if ( actualWidth != former_w || actualHeight != former_h )
6264b550 1905 doResize = true ;
6ed71b4f 1906
6264b550
RR
1907 if ( doMove || doResize )
1908 {
902725ee 1909 // as the borders are drawn outside the native control, we adjust now
1f1c8bd4 1910
902725ee
WS
1911 wxRect bounds( wxPoint( actualX + MacGetLeftBorderSize() ,actualY + MacGetTopBorderSize() ),
1912 wxSize( actualWidth - (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1f1c8bd4
SC
1913 actualHeight - (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1914
1915 Rect r ;
1916 wxMacRectToNative( &bounds , &r ) ;
1917
1918 if ( !GetParent()->IsTopLevel() )
1f1c8bd4 1919 wxMacWindowToNative( GetParent() , &r ) ;
8b573fb8 1920
6449b3a8 1921 MacInvalidateBorders() ;
902725ee 1922
5c840e5b 1923 m_cachedClippedRectValid = false ;
8b573fb8 1924 m_peer->SetRect( &r ) ;
902725ee 1925
e905b636 1926 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
91ae6e3a 1927
6449b3a8
SC
1928 MacInvalidateBorders() ;
1929
6264b550
RR
1930 MacRepositionScrollBars() ;
1931 if ( doMove )
1932 {
898d9035 1933 wxPoint point(actualX, actualY);
6264b550
RR
1934 wxMoveEvent event(point, m_windowId);
1935 event.SetEventObject(this);
1936 GetEventHandler()->ProcessEvent(event) ;
1937 }
e15f0a5e 1938
6264b550
RR
1939 if ( doResize )
1940 {
e40298d5 1941 MacRepositionScrollBars() ;
facd6764 1942 wxSize size(actualWidth, actualHeight);
e40298d5
JS
1943 wxSizeEvent event(size, m_windowId);
1944 event.SetEventObject(this);
1945 GetEventHandler()->ProcessEvent(event);
6264b550
RR
1946 }
1947 }
954fc50b
SC
1948}
1949
facd6764
SC
1950wxSize wxWindowMac::DoGetBestSize() const
1951{
eb69d46e
SC
1952 if ( m_macIsUserPane || IsTopLevel() )
1953 return wxWindowBase::DoGetBestSize() ;
8b573fb8 1954
facd6764 1955 Rect bestsize = { 0 , 0 , 0 , 0 } ;
facd6764 1956 int bestWidth, bestHeight ;
facd6764 1957
898d9035 1958 m_peer->GetBestRect( &bestsize ) ;
facd6764
SC
1959 if ( EmptyRect( &bestsize ) )
1960 {
898d9035
DS
1961 bestsize.left =
1962 bestsize.top = 0 ;
1963 bestsize.right =
facd6764 1964 bestsize.bottom = 16 ;
898d9035 1965
facd6764
SC
1966 if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
1967 {
1968 bestsize.bottom = 16 ;
1969 }
902725ee 1970#if wxUSE_SPINBTN
facd6764
SC
1971 else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) )
1972 {
8b573fb8 1973 bestsize.bottom = 24 ;
facd6764 1974 }
898d9035 1975#endif
facd6764
SC
1976 else
1977 {
8b573fb8 1978 // return wxWindowBase::DoGetBestSize() ;
facd6764
SC
1979 }
1980 }
1981
1982 bestWidth = bestsize.right - bestsize.left ;
1983 bestHeight = bestsize.bottom - bestsize.top ;
1984 if ( bestHeight < 10 )
1985 bestHeight = 13 ;
8b573fb8 1986
facd6764
SC
1987 return wxSize(bestWidth, bestHeight);
1988}
1989
954fc50b
SC
1990// set the size of the window: if the dimensions are positive, just use them,
1991// but if any of them is equal to -1, it means that we must find the value for
1992// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1993// which case -1 is a valid value for x and y)
1994//
1995// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1996// the width/height to best suit our contents, otherwise we reuse the current
1997// width/height
1998void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags)
1999{
2000 // get the current size and position...
2001 int currentX, currentY;
898d9035 2002 int currentW, currentH;
6ed71b4f 2003
898d9035 2004 GetPosition(&currentX, &currentY);
954fc50b 2005 GetSize(&currentW, &currentH);
6ed71b4f 2006
954fc50b
SC
2007 // ... and don't do anything (avoiding flicker) if it's already ok
2008 if ( x == currentX && y == currentY &&
769ac869 2009 width == currentW && height == currentH && ( height != -1 && width != -1 ) )
954fc50b 2010 {
e15f0a5e 2011 // TODO: REMOVE
6264b550 2012 MacRepositionScrollBars() ; // we might have a real position shift
898d9035 2013
954fc50b
SC
2014 return;
2015 }
6ed71b4f 2016
58603178
DS
2017 if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
2018 {
2019 if ( x == wxDefaultCoord )
2020 x = currentX;
2021 if ( y == wxDefaultCoord )
2022 y = currentY;
2023 }
6ed71b4f 2024
58603178 2025 AdjustForParentClientOrigin( x, y, sizeFlags );
6ed71b4f 2026
3dee36ae
WS
2027 wxSize size = wxDefaultSize;
2028 if ( width == wxDefaultCoord )
954fc50b
SC
2029 {
2030 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
2031 {
2032 size = DoGetBestSize();
2033 width = size.x;
2034 }
2035 else
2036 {
2037 // just take the current one
2038 width = currentW;
2039 }
2040 }
6ed71b4f 2041
3dee36ae 2042 if ( height == wxDefaultCoord )
954fc50b
SC
2043 {
2044 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
2045 {
3dee36ae 2046 if ( size.x == wxDefaultCoord )
954fc50b 2047 size = DoGetBestSize();
898d9035 2048 // else: already called DoGetBestSize() above
6ed71b4f 2049
954fc50b
SC
2050 height = size.y;
2051 }
2052 else
2053 {
2054 // just take the current one
2055 height = currentH;
2056 }
2057 }
6ed71b4f 2058
58603178 2059 DoMoveWindow( x, y, width, height );
e9576ca5 2060}
519cb848 2061
e766c8a9 2062wxPoint wxWindowMac::GetClientAreaOrigin() const
e9576ca5 2063{
facd6764
SC
2064 RgnHandle rgn = NewRgn() ;
2065 Rect content ;
04d4e684 2066 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
21638402
SC
2067 {
2068 GetRegionBounds( rgn , &content ) ;
2069 }
2070 else
2071 {
898d9035
DS
2072 content.left =
2073 content.top = 0 ;
21638402 2074 }
898d9035 2075
facd6764 2076 DisposeRgn( rgn ) ;
e15f0a5e
DS
2077
2078 return wxPoint( content.left + MacGetLeftBorderSize() , content.top + MacGetTopBorderSize() );
facd6764
SC
2079}
2080
2081void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight)
2082{
d0dec992 2083 if ( clientwidth != wxDefaultCoord || clientheight != wxDefaultCoord )
facd6764
SC
2084 {
2085 int currentclientwidth , currentclientheight ;
2086 int currentwidth , currentheight ;
2087
2088 GetClientSize( &currentclientwidth , &currentclientheight ) ;
2089 GetSize( &currentwidth , &currentheight ) ;
2090
3dee36ae 2091 DoSetSize( wxDefaultCoord , wxDefaultCoord , currentwidth + clientwidth - currentclientwidth ,
facd6764
SC
2092 currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ;
2093 }
e9576ca5
SC
2094}
2095
fb5246be 2096void wxWindowMac::SetLabel(const wxString& title)
e9576ca5 2097{
6239ee05 2098 m_label = title ;
facd6764 2099
21fd5529 2100 if ( m_peer && m_peer->Ok() )
6239ee05 2101 m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ;
e15f0a5e 2102
6239ee05
SC
2103 // do not trigger refreshes upon invisible and possible partly created objects
2104 if ( MacIsReallyShown() )
2105 Refresh() ;
519cb848
SC
2106}
2107
fb5246be 2108wxString wxWindowMac::GetLabel() const
519cb848 2109{
ed60b502 2110 return m_label ;
519cb848
SC
2111}
2112
8ab50549
SC
2113bool wxWindowMac::Show(bool show)
2114{
542f604f 2115 bool former = MacIsReallyShown() ;
8ab50549 2116 if ( !wxWindowBase::Show(show) )
902725ee 2117 return false;
8b573fb8 2118
58603178 2119 // TODO: use visibilityChanged Carbon Event for OSX
2c899c20 2120 if ( m_peer )
2c899c20 2121 m_peer->SetVisibility( show , true ) ;
e15f0a5e 2122
542f604f
SC
2123 if ( former != MacIsReallyShown() )
2124 MacPropagateVisibilityChanged() ;
898d9035 2125
902725ee 2126 return true;
8ab50549
SC
2127}
2128
47a8a4d5 2129void wxWindowMac::DoEnable(bool enable)
8ab50549 2130{
5ca0d812 2131 m_peer->Enable( enable ) ;
8ab50549
SC
2132}
2133
8b573fb8 2134//
8ab50549
SC
2135// status change propagations (will be not necessary for OSX later )
2136//
2137
facd6764
SC
2138void wxWindowMac::MacPropagateVisibilityChanged()
2139{
73fe67bd 2140#if !TARGET_API_MAC_OSX
facd6764 2141 MacVisibilityChanged() ;
8b573fb8 2142
e15f0a5e 2143 wxWindowMac *child;
71f2fb52 2144 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
facd6764
SC
2145 while ( node )
2146 {
e15f0a5e 2147 child = node->GetData();
facd6764 2148 if ( child->IsShown() )
e15f0a5e
DS
2149 child->MacPropagateVisibilityChanged() ;
2150
facd6764
SC
2151 node = node->GetNext();
2152 }
73fe67bd 2153#endif
facd6764
SC
2154}
2155
89954433 2156void wxWindowMac::OnEnabled(bool WXUNUSED(enabled))
e9576ca5 2157{
73fe67bd 2158#if !TARGET_API_MAC_OSX
8ab50549 2159 MacEnabledStateChanged() ;
73fe67bd 2160#endif
8ab50549
SC
2161}
2162
e15f0a5e 2163void wxWindowMac::MacPropagateHiliteChanged()
8ab50549 2164{
73fe67bd 2165#if !TARGET_API_MAC_OSX
8ab50549 2166 MacHiliteChanged() ;
8b573fb8 2167
e15f0a5e 2168 wxWindowMac *child;
71f2fb52 2169 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
8ab50549
SC
2170 while ( node )
2171 {
e15f0a5e 2172 child = node->GetData();
898d9035 2173 if (child /* && child->IsEnabled() */)
8ab50549 2174 child->MacPropagateHiliteChanged() ;
e15f0a5e 2175
8ab50549
SC
2176 node = node->GetNext();
2177 }
73fe67bd 2178#endif
8ab50549
SC
2179}
2180
2181//
2182// status change notifications
8b573fb8 2183//
8ab50549 2184
8b573fb8 2185void wxWindowMac::MacVisibilityChanged()
8ab50549
SC
2186{
2187}
2188
8b573fb8 2189void wxWindowMac::MacHiliteChanged()
8ab50549
SC
2190{
2191}
2192
8b573fb8 2193void wxWindowMac::MacEnabledStateChanged()
8ab50549 2194{
facd6764 2195}
e7549107 2196
8ab50549
SC
2197//
2198// status queries on the inherited window's state
2199//
2200
8b573fb8 2201bool wxWindowMac::MacIsReallyShown()
facd6764
SC
2202{
2203 // only under OSX the visibility of the TLW is taken into account
66ffb23b
SC
2204 if ( m_isBeingDeleted )
2205 return false ;
902725ee 2206
facd6764 2207#if TARGET_API_MAC_OSX
aa522e33
SC
2208 if ( m_peer && m_peer->Ok() )
2209 return m_peer->IsVisible();
2210#endif
e15f0a5e 2211
facd6764 2212 wxWindow* win = this ;
898d9035 2213 while ( win->IsShown() )
facd6764
SC
2214 {
2215 if ( win->IsTopLevel() )
2216 return true ;
8b573fb8 2217
facd6764
SC
2218 win = win->GetParent() ;
2219 if ( win == NULL )
2220 return true ;
e15f0a5e 2221 }
8b573fb8 2222
facd6764 2223 return false ;
facd6764 2224}
4241baae 2225
8b573fb8 2226bool wxWindowMac::MacIsReallyEnabled()
facd6764 2227{
5ca0d812 2228 return m_peer->IsEnabled() ;
facd6764
SC
2229}
2230
8b573fb8 2231bool wxWindowMac::MacIsReallyHilited()
c809f3be 2232{
5ca0d812 2233 return m_peer->IsActive();
c809f3be
SC
2234}
2235
8b573fb8 2236void wxWindowMac::MacFlashInvalidAreas()
002c9672
SC
2237{
2238#if TARGET_API_MAC_OSX
2239 HIViewFlashDirtyArea( (WindowRef) MacGetTopLevelWindowRef() ) ;
2240#endif
2241}
2242
e766c8a9 2243int wxWindowMac::GetCharHeight() const
e9576ca5 2244{
e15f0a5e
DS
2245 wxClientDC dc( (wxWindowMac*)this ) ;
2246
6264b550 2247 return dc.GetCharHeight() ;
e9576ca5
SC
2248}
2249
e766c8a9 2250int wxWindowMac::GetCharWidth() const
e9576ca5 2251{
e15f0a5e
DS
2252 wxClientDC dc( (wxWindowMac*)this ) ;
2253
6264b550 2254 return dc.GetCharWidth() ;
e9576ca5
SC
2255}
2256
e766c8a9 2257void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
e7549107 2258 int *descent, int *externalLeading, const wxFont *theFont ) const
e9576ca5 2259{
e7549107
SC
2260 const wxFont *fontToUse = theFont;
2261 if ( !fontToUse )
2262 fontToUse = &m_font;
14c9cbdb 2263
e766c8a9 2264 wxClientDC dc( (wxWindowMac*) this ) ;
659863d8 2265 wxCoord lx,ly,ld,le ;
5fde6fcc 2266 dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ;
2f1ae414 2267 if ( externalLeading )
6264b550 2268 *externalLeading = le ;
2f1ae414 2269 if ( descent )
6264b550 2270 *descent = ld ;
2f1ae414 2271 if ( x )
6264b550 2272 *x = lx ;
2f1ae414 2273 if ( y )
6264b550 2274 *y = ly ;
e9576ca5
SC
2275}
2276
0a67a93b 2277/*
14c9cbdb 2278 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
1c310985
SC
2279 * we always intersect with the entire window, not only with the client area
2280 */
14c9cbdb 2281
89954433 2282void wxWindowMac::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect)
e9576ca5 2283{
065ab451
SC
2284 if ( m_peer == NULL )
2285 return ;
8b573fb8 2286
1f1c8bd4
SC
2287 if ( !MacIsReallyShown() )
2288 return ;
789ae0cf 2289
1f1c8bd4 2290 if ( rect )
1e8cde71 2291 {
1f1c8bd4 2292 Rect r ;
898d9035 2293
1f1c8bd4
SC
2294 wxMacRectToNative( rect , &r ) ;
2295 m_peer->SetNeedsDisplay( &r ) ;
facd6764 2296 }
1f1c8bd4 2297 else
9a456218 2298 {
1f1c8bd4 2299 m_peer->SetNeedsDisplay() ;
e9576ca5 2300 }
facd6764
SC
2301}
2302
79392158
SC
2303void wxWindowMac::Freeze()
2304{
2305#if TARGET_API_MAC_OSX
2306 if ( !m_frozenness++ )
2307 {
52ef5c3c
RD
2308 if ( m_peer && m_peer->Ok() )
2309 m_peer->SetDrawingEnabled( false ) ;
79392158
SC
2310 }
2311#endif
2312}
2313
2314void wxWindowMac::Thaw()
2315{
2316#if TARGET_API_MAC_OSX
898d9035 2317 wxASSERT_MSG( m_frozenness > 0, wxT("Thaw() without matching Freeze()") );
79392158
SC
2318
2319 if ( !--m_frozenness )
2320 {
52ef5c3c
RD
2321 if ( m_peer && m_peer->Ok() )
2322 {
2323 m_peer->SetDrawingEnabled( true ) ;
2324 m_peer->InvalidateWithChildren() ;
2325 }
79392158
SC
2326 }
2327#endif
2328}
2329
fd39f7a8
RD
2330bool wxWindowMac::IsFrozen() const
2331{
2332 return m_frozenness != 0;
2333}
2334
e766c8a9 2335wxWindowMac *wxGetActiveWindow()
e9576ca5 2336{
519cb848 2337 // actually this is a windows-only concept
e9576ca5
SC
2338 return NULL;
2339}
2340
e9576ca5 2341// Coordinates relative to the window
89954433 2342void wxWindowMac::WarpPointer(int WXUNUSED(x_pos), int WXUNUSED(y_pos))
e9576ca5 2343{
e40298d5 2344 // We really don't move the mouse programmatically under Mac.
e9576ca5
SC
2345}
2346
facd6764 2347void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
e9576ca5 2348{
3dee36ae
WS
2349 if ( MacGetTopLevelWindow() == NULL )
2350 return ;
898d9035 2351
be346c26 2352#if TARGET_API_MAC_OSX
4488a1d3
VZ
2353 if ( !m_macBackgroundBrush.Ok() || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT
2354 || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
94abc21f 2355 {
facd6764 2356 event.Skip() ;
94abc21f
SC
2357 }
2358 else
be346c26 2359#endif
7ebf5540 2360 {
8b573fb8 2361 event.GetDC()->Clear() ;
7ebf5540 2362 }
1c310985
SC
2363}
2364
2365void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
2366{
af6b7b80 2367 event.Skip() ;
e9576ca5
SC
2368}
2369
e766c8a9 2370int wxWindowMac::GetScrollPos(int orient) const
e9576ca5 2371{
1c310985
SC
2372 if ( orient == wxHORIZONTAL )
2373 {
2374 if ( m_hScrollBar )
2375 return m_hScrollBar->GetThumbPosition() ;
2376 }
2377 else
2378 {
2379 if ( m_vScrollBar )
2380 return m_vScrollBar->GetThumbPosition() ;
2381 }
e15f0a5e 2382
e9576ca5
SC
2383 return 0;
2384}
2385
2386// This now returns the whole range, not just the number
2387// of positions that we can scroll.
e766c8a9 2388int wxWindowMac::GetScrollRange(int orient) const
e9576ca5 2389{
1c310985
SC
2390 if ( orient == wxHORIZONTAL )
2391 {
2392 if ( m_hScrollBar )
2393 return m_hScrollBar->GetRange() ;
2394 }
2395 else
2396 {
2397 if ( m_vScrollBar )
2398 return m_vScrollBar->GetRange() ;
2399 }
e15f0a5e 2400
e9576ca5
SC
2401 return 0;
2402}
2403
e766c8a9 2404int wxWindowMac::GetScrollThumb(int orient) const
e9576ca5 2405{
1c310985
SC
2406 if ( orient == wxHORIZONTAL )
2407 {
2408 if ( m_hScrollBar )
2409 return m_hScrollBar->GetThumbSize() ;
2410 }
2411 else
2412 {
2413 if ( m_vScrollBar )
2414 return m_vScrollBar->GetThumbSize() ;
2415 }
e15f0a5e 2416
e9576ca5
SC
2417 return 0;
2418}
2419
89954433 2420void wxWindowMac::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh))
e9576ca5 2421{
1c310985 2422 if ( orient == wxHORIZONTAL )
6264b550 2423 {
1c310985
SC
2424 if ( m_hScrollBar )
2425 m_hScrollBar->SetThumbPosition( pos ) ;
6264b550
RR
2426 }
2427 else
2428 {
1c310985
SC
2429 if ( m_vScrollBar )
2430 m_vScrollBar->SetThumbPosition( pos ) ;
6264b550 2431 }
2f1ae414
SC
2432}
2433
c1142003
VZ
2434void
2435wxWindowMac::AlwaysShowScrollbars(bool hflag, bool vflag)
2436{
2437 bool needVisibilityUpdate = false;
2438
2439 if ( m_hScrollBarAlwaysShown != hflag )
2440 {
2441 m_hScrollBarAlwaysShown = hflag;
2442 needVisibilityUpdate = true;
2443 }
2444
2445 if ( m_vScrollBarAlwaysShown != vflag )
2446 {
2447 m_vScrollBarAlwaysShown = vflag;
2448 needVisibilityUpdate = true;
2449 }
2450
2451 if ( needVisibilityUpdate )
2452 DoUpdateScrollbarVisibility();
2453}
6239ee05 2454
c79aad8b
SC
2455//
2456// we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2457// our own window origin is at leftOrigin/rightOrigin
2458//
2459
6239ee05
SC
2460void wxWindowMac::MacPaintGrowBox()
2461{
2462 if ( IsTopLevel() )
2463 return ;
2464
2465#if wxMAC_USE_CORE_GRAPHICS
2466 if ( MacHasScrollBarCorner() )
2467 {
2468 Rect rect ;
2469
2470 CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ;
2471 wxASSERT( cgContext ) ;
2472
2473 m_peer->GetRect( &rect ) ;
2474
2475 int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
2476 CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
2477 CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
2478 CGContextSaveGState( cgContext );
2479
2480 if ( m_macBackgroundBrush.Ok() && m_macBackgroundBrush.GetStyle() != wxTRANSPARENT )
2481 {
2482 wxMacCoreGraphicsColour bkgnd( m_macBackgroundBrush ) ;
2483 bkgnd.Apply( cgContext );
2484 }
2485 else
2486 {
2487 CGContextSetRGBFillColor( cgContext, 1.0, 1.0 , 1.0 , 1.0 );
2488 }
2489 CGContextFillRect( cgContext, cgrect );
2490 CGContextRestoreGState( cgContext );
2491 }
2492#endif
2493}
2494
89954433 2495void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(rightOrigin) )
2f1ae414 2496{
e15f0a5e 2497 if ( IsTopLevel() )
6264b550 2498 return ;
8b573fb8 2499
fd926bcc 2500 Rect rect ;
c79aad8b 2501 bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ;
c79aad8b 2502
8f39b6c4 2503 // back to the surrounding frame rectangle
58603178 2504 m_peer->GetRect( &rect ) ;
8f39b6c4 2505 InsetRect( &rect, -1 , -1 ) ;
fd926bcc 2506
89954433 2507#if wxMAC_USE_CORE_GRAPHICS
c79aad8b 2508 {
8f39b6c4
SC
2509 CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left ,
2510 rect.bottom - rect.top ) ;
2511
c79aad8b 2512 HIThemeFrameDrawInfo info ;
58603178 2513 memset( &info, 0 , sizeof(info) ) ;
902725ee 2514
c79aad8b
SC
2515 info.version = 0 ;
2516 info.kind = 0 ;
2517 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
2518 info.isFocused = hasFocus ;
c79aad8b
SC
2519
2520 CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ;
2521 wxASSERT( cgContext ) ;
902725ee 2522
e15f0a5e 2523 if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
c79aad8b 2524 {
c79aad8b 2525 info.kind = kHIThemeFrameTextFieldSquare ;
8f39b6c4 2526 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
c79aad8b 2527 }
e15f0a5e 2528 else if ( HasFlag(wxSIMPLE_BORDER) )
c79aad8b 2529 {
c79aad8b 2530 info.kind = kHIThemeFrameListBox ;
c79aad8b
SC
2531 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
2532 }
2533 else if ( hasFocus )
2534 {
c79aad8b
SC
2535 HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ;
2536 }
6239ee05 2537#if 0 // TODO REMOVE now done in a separate call earlier in drawing the window itself
c79aad8b 2538 m_peer->GetRect( &rect ) ;
6239ee05 2539 if ( MacHasScrollBarCorner() )
c79aad8b 2540 {
6239ee05
SC
2541 int variant = (m_hScrollBar == NULL ? m_vScrollBar : m_hScrollBar ) ->GetWindowVariant();
2542 int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
8f39b6c4
SC
2543 CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
2544 CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
902725ee 2545 HIThemeGrowBoxDrawInfo info ;
e15f0a5e 2546 memset( &info, 0, sizeof(info) ) ;
c79aad8b
SC
2547 info.version = 0 ;
2548 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
2549 info.kind = kHIThemeGrowBoxKindNone ;
6239ee05 2550 // contrary to the docs ...SizeSmall does not work
c79aad8b 2551 info.size = kHIThemeGrowBoxSizeNormal ;
6239ee05 2552 info.direction = 0 ;
c79aad8b
SC
2553 HIThemeDrawGrowBox( &cgpoint , &info , cgContext , kHIThemeOrientationNormal ) ;
2554 }
6239ee05 2555#endif
c79aad8b 2556 }
4f74e0d1 2557 #else
fd926bcc
SC
2558 {
2559 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
e15f0a5e 2560 if ( top )
fd926bcc 2561 {
e15f0a5e 2562 wxPoint pt(0, 0) ;
fd926bcc 2563 wxMacControl::Convert( &pt , GetParent()->m_peer , top->m_peer ) ;
1f1c8bd4 2564 OffsetRect( &rect , pt.x , pt.y ) ;
fd926bcc 2565 }
8b573fb8 2566
e15f0a5e
DS
2567 if ( HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
2568 DrawThemeEditTextFrame( &rect, IsEnabled() ? kThemeStateActive : kThemeStateInactive ) ;
2569 else if ( HasFlag(wxSIMPLE_BORDER) )
2570 DrawThemeListBoxFrame( &rect, IsEnabled() ? kThemeStateActive : kThemeStateInactive ) ;
902725ee 2571
c79aad8b 2572 if ( hasFocus )
8f39b6c4 2573 DrawThemeFocusRect( &rect , true ) ;
6239ee05
SC
2574 // TODO REMOVE
2575 /*
2576 if ( hasBothScrollbars ) // hasBothScrollbars is not declared
c79aad8b 2577 {
902725ee 2578 // GetThemeStandaloneGrowBoxBounds
e15f0a5e 2579 // DrawThemeStandaloneNoGrowBox
c79aad8b 2580 }
6239ee05 2581 */
eec462f8 2582 }
4f74e0d1 2583#endif
8208e181
SC
2584}
2585
abda5788
SC
2586void wxWindowMac::RemoveChild( wxWindowBase *child )
2587{
2588 if ( child == m_hScrollBar )
2589 m_hScrollBar = NULL ;
2590 if ( child == m_vScrollBar )
2591 m_vScrollBar = NULL ;
14c9cbdb 2592
abda5788
SC
2593 wxWindowBase::RemoveChild( child ) ;
2594}
2595
c1142003 2596void wxWindowMac::DoUpdateScrollbarVisibility()
e9576ca5 2597{
42cc0b31 2598 bool triggerSizeEvent = false;
58603178 2599
c1142003 2600 if ( m_hScrollBar )
e40298d5 2601 {
c1142003 2602 bool showHScrollBar = m_hScrollBarAlwaysShown || m_hScrollBar->IsNeeded();
e15f0a5e 2603
c1142003
VZ
2604 if ( m_hScrollBar->IsShown() != showHScrollBar )
2605 {
2606 m_hScrollBar->Show( showHScrollBar );
2607 triggerSizeEvent = true;
6264b550 2608 }
e40298d5 2609 }
c1142003
VZ
2610
2611 if ( m_vScrollBar)
e40298d5 2612 {
c1142003 2613 bool showVScrollBar = m_vScrollBarAlwaysShown || m_vScrollBar->IsNeeded();
e15f0a5e 2614
c1142003
VZ
2615 if ( m_vScrollBar->IsShown() != showVScrollBar )
2616 {
2617 m_vScrollBar->Show( showVScrollBar ) ;
2618 triggerSizeEvent = true;
6264b550 2619 }
e40298d5 2620 }
e15f0a5e 2621
e40298d5 2622 MacRepositionScrollBars() ;
42cc0b31
SC
2623 if ( triggerSizeEvent )
2624 {
2625 wxSizeEvent event(GetSize(), m_windowId);
2626 event.SetEventObject(this);
2627 GetEventHandler()->ProcessEvent(event);
2628 }
e9576ca5
SC
2629}
2630
c1142003
VZ
2631// New function that will replace some of the above.
2632void wxWindowMac::SetScrollbar(int orient, int pos, int thumb,
2633 int range, bool refresh)
2634{
2635 if ( orient == wxHORIZONTAL && m_hScrollBar )
2636 m_hScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh);
2637 else if ( orient == wxVERTICAL && m_vScrollBar )
2638 m_vScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh);
2639
2640 DoUpdateScrollbarVisibility();
2641}
2642
e9576ca5 2643// Does a physical scroll
e766c8a9 2644void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
e9576ca5 2645{
898d9035 2646 if ( dx == 0 && dy == 0 )
ba87f54c 2647 return ;
8b573fb8 2648
3dee36ae
WS
2649 int width , height ;
2650 GetClientSize( &width , &height ) ;
e15f0a5e 2651
902725ee 2652 {
002c9672 2653 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
8b573fb8 2654 // area is scrolled, this does not occur if width and height are 2 pixels less,
58603178 2655 // TODO: write optimal workaround
898d9035 2656 wxRect scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ;
8b573fb8 2657 if ( rect )
5ca0d812 2658 scrollrect.Intersect( *rect ) ;
e15f0a5e 2659
5ca0d812 2660 if ( m_peer->GetNeedsDisplay() )
002c9672 2661 {
58603178 2662 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
8dd37b03 2663 // in case there is already a pending redraw on that area
002c9672
SC
2664 // either immediate redraw or full invalidate
2665#if 1
2666 // is the better overall solution, as it does not slow down scrolling
1f1c8bd4 2667 m_peer->SetNeedsDisplay() ;
002c9672 2668#else
8b573fb8 2669 // this would be the preferred version for fast drawing controls
92346151 2670
f474cc8c 2671#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
a9b456ff 2672 if ( UMAGetSystemVersion() >= 0x1030 )
42ef83fa 2673 HIViewRender(m_peer->GetControlRef()) ;
f474cc8c
SC
2674 else
2675#endif
2676 Update() ;
002c9672
SC
2677#endif
2678 }
e15f0a5e 2679
84e5d27d
SC
2680 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2681 scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
898d9035 2682 m_peer->ScrollRect( &scrollrect , dx , dy ) ;
92346151 2683
92346151 2684#if 0
902725ee 2685 // this would be the preferred version for fast drawing controls
4f74e0d1 2686 HIViewRender(m_peer->GetControlRef()) ;
92346151 2687#endif
902725ee 2688 }
6ed71b4f 2689
e15f0a5e
DS
2690 wxWindowMac *child;
2691 int x, y, w, h;
71f2fb52 2692 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
6264b550 2693 {
e15f0a5e
DS
2694 child = node->GetData();
2695 if (child == NULL)
2696 continue;
2697 if (child == m_vScrollBar)
2698 continue;
2699 if (child == m_hScrollBar)
2700 continue;
2701 if (child->IsTopLevel())
2702 continue;
6ed71b4f 2703
6264b550 2704 child->GetPosition( &x, &y );
6264b550 2705 child->GetSize( &w, &h );
00f55394
SC
2706 if (rect)
2707 {
e15f0a5e
DS
2708 wxRect rc( x, y, w, h );
2709 if (rect->Intersects( rc ))
8d1547ef 2710 child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
00f55394
SC
2711 }
2712 else
2713 {
8d1547ef 2714 child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
8b573fb8 2715 }
6264b550 2716 }
e9576ca5
SC
2717}
2718
e15f0a5e 2719void wxWindowMac::MacOnScroll( wxScrollEvent &event )
7c74e7fe 2720{
687706f5 2721 if ( event.GetEventObject() == m_vScrollBar || event.GetEventObject() == m_hScrollBar )
6264b550
RR
2722 {
2723 wxScrollWinEvent wevent;
2724 wevent.SetPosition(event.GetPosition());
2725 wevent.SetOrientation(event.GetOrientation());
687706f5
KH
2726 wevent.SetEventObject(this);
2727
2728 if (event.GetEventType() == wxEVT_SCROLL_TOP)
2729 wevent.SetEventType( wxEVT_SCROLLWIN_TOP );
2730 else if (event.GetEventType() == wxEVT_SCROLL_BOTTOM)
2731 wevent.SetEventType( wxEVT_SCROLLWIN_BOTTOM );
2732 else if (event.GetEventType() == wxEVT_SCROLL_LINEUP)
2733 wevent.SetEventType( wxEVT_SCROLLWIN_LINEUP );
2734 else if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN)
2735 wevent.SetEventType( wxEVT_SCROLLWIN_LINEDOWN );
2736 else if (event.GetEventType() == wxEVT_SCROLL_PAGEUP)
2737 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEUP );
2738 else if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN)
2739 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN );
2740 else if (event.GetEventType() == wxEVT_SCROLL_THUMBTRACK)
2741 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK );
2742 else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE)
2743 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE );
6ed71b4f
VZ
2744
2745 GetEventHandler()->ProcessEvent(wevent);
7c74e7fe
SC
2746 }
2747}
2748
e9576ca5 2749// Get the window with the focus
0fe02759 2750wxWindowMac *wxWindowBase::DoFindFocus()
e9576ca5 2751{
f1d527c1
SC
2752 ControlRef control ;
2753 GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
2754 return wxFindControlFromMacControl( control ) ;
519cb848
SC
2755}
2756
e15f0a5e 2757void wxWindowMac::OnSetFocus( wxFocusEvent& event )
7810c95b
SC
2758{
2759 // panel wants to track the window which was the last to have focus in it,
2760 // so we want to set ourselves as the window which last had focus
2761 //
dac390e9 2762 // notice that it's also important to do it upwards the tree because
7810c95b
SC
2763 // otherwise when the top level panel gets focus, it won't set it back to
2764 // us, but to some other sibling
6ed71b4f 2765
dac390e9 2766 // CS: don't know if this is still needed:
c1fb8167
SC
2767 //wxChildFocusEvent eventFocus(this);
2768 //(void)GetEventHandler()->ProcessEvent(eventFocus);
7810c95b 2769
5ca0d812
SC
2770 if ( MacGetTopLevelWindow() && m_peer->NeedsFocusRect() )
2771 {
dac390e9
DS
2772#if wxMAC_USE_CORE_GRAPHICS
2773 GetParent()->Refresh() ;
2774#else
788e118f 2775 wxMacWindowStateSaver sv( this ) ;
6449b3a8 2776 Rect rect ;
dac390e9 2777
6449b3a8 2778 m_peer->GetRect( &rect ) ;
6239ee05 2779 // auf den umgebenden Rahmen zurチᅡ゚ck
8f39b6c4 2780 InsetRect( &rect, -1 , -1 ) ;
1f1c8bd4 2781
6449b3a8 2782 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
dac390e9 2783 if ( top )
6449b3a8 2784 {
898d9035 2785 wxPoint pt(0, 0) ;
6449b3a8
SC
2786 wxMacControl::Convert( &pt , GetParent()->m_peer , top->m_peer ) ;
2787 rect.left += pt.x ;
2788 rect.right += pt.x ;
2789 rect.top += pt.y ;
2790 rect.bottom += pt.y ;
2791 }
5ca0d812 2792
fbc1d11b 2793 bool bIsFocusEvent = (event.GetEventType() == wxEVT_SET_FOCUS);
c394a432 2794 DrawThemeFocusRect( &rect , bIsFocusEvent ) ;
dac390e9 2795 if ( !bIsFocusEvent )
af6b7b80 2796 {
af6b7b80 2797 // as this erases part of the frame we have to redraw borders
101634b2
SC
2798 // and because our z-ordering is not always correct (staticboxes)
2799 // we have to invalidate things, we cannot simple redraw
6449b3a8 2800 MacInvalidateBorders() ;
af6b7b80 2801 }
ff3795ee 2802#endif
5ca0d812
SC
2803 }
2804
7810c95b
SC
2805 event.Skip();
2806}
2807
e39af974 2808void wxWindowMac::OnInternalIdle()
e9576ca5 2809{
e9576ca5
SC
2810 // This calls the UI-update mechanism (querying windows for
2811 // menu/toolbar/control state information)
6239ee05 2812 if (wxUpdateUIEvent::CanUpdate(this) && IsShown())
e39af974 2813 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
e9576ca5
SC
2814}
2815
2816// Raise the window to the top of the Z order
e766c8a9 2817void wxWindowMac::Raise()
e9576ca5 2818{
5ca0d812 2819 m_peer->SetZOrder( true , NULL ) ;
e9576ca5
SC
2820}
2821
2822// Lower the window to the bottom of the Z order
e766c8a9 2823void wxWindowMac::Lower()
e9576ca5 2824{
5ca0d812 2825 m_peer->SetZOrder( false , NULL ) ;
e9576ca5
SC
2826}
2827
facd6764 2828// static wxWindow *gs_lastWhich = NULL;
519cb848 2829
e15f0a5e 2830bool wxWindowMac::MacSetupCursor( const wxPoint& pt )
467e3168
SC
2831{
2832 // first trigger a set cursor event
6ed71b4f 2833
467e3168
SC
2834 wxPoint clientorigin = GetClientAreaOrigin() ;
2835 wxSize clientsize = GetClientSize() ;
2836 wxCursor cursor ;
2837 if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) )
7de59551 2838 {
467e3168 2839 wxSetCursorEvent event( pt.x , pt.y );
6ed71b4f 2840
467e3168
SC
2841 bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
2842 if ( processedEvtSetCursor && event.HasCursor() )
2843 {
e40298d5 2844 cursor = event.GetCursor() ;
467e3168
SC
2845 }
2846 else
2847 {
467e3168
SC
2848 // the test for processedEvtSetCursor is here to prevent using m_cursor
2849 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2850 // it - this is a way to say that our cursor shouldn't be used for this
2851 // point
2852 if ( !processedEvtSetCursor && m_cursor.Ok() )
467e3168 2853 cursor = m_cursor ;
e15f0a5e
DS
2854
2855 if ( !wxIsBusy() && !GetParent() )
2856 cursor = *wxSTANDARD_CURSOR ;
467e3168 2857 }
e15f0a5e 2858
467e3168
SC
2859 if ( cursor.Ok() )
2860 cursor.MacInstall() ;
2861 }
e15f0a5e 2862
467e3168
SC
2863 return cursor.Ok() ;
2864}
2865
89954433 2866wxString wxWindowMac::MacGetToolTipString( wxPoint &WXUNUSED(pt) )
2f1ae414 2867{
5e0526df 2868#if wxUSE_TOOLTIPS
6264b550 2869 if ( m_tooltip )
6264b550 2870 return m_tooltip->GetTip() ;
5e0526df 2871#endif
e15f0a5e 2872
427ff662 2873 return wxEmptyString ;
2f1ae414 2874}
6264b550 2875
cb4b0966
SC
2876void wxWindowMac::ClearBackground()
2877{
2878 Refresh() ;
2879 Update() ;
2880}
2881
1c310985 2882void wxWindowMac::Update()
519cb848 2883{
facd6764 2884#if TARGET_API_MAC_OSX
5bcdf503
JS
2885 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
2886 if (top)
2887 top->MacPerformUpdates() ;
facd6764 2888#else
5ca0d812 2889 ::Draw1Control( m_peer->GetControlRef() ) ;
bec721ec 2890#endif
519cb848
SC
2891}
2892
14c9cbdb 2893wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
519cb848 2894{
1c310985 2895 wxTopLevelWindowMac* win = NULL ;
facd6764 2896 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
1c310985 2897 if ( window )
1c310985 2898 win = wxFindWinFromMacWindow( window ) ;
e15f0a5e 2899
1c310985 2900 return win ;
519cb848 2901}
5c840e5b 2902
902725ee 2903const wxRect& wxWindowMac::MacGetClippedClientRect() const
e905b636
SC
2904{
2905 MacUpdateClippedRects() ;
e15f0a5e 2906
e905b636
SC
2907 return m_cachedClippedClientRect ;
2908}
2909
902725ee 2910const wxRect& wxWindowMac::MacGetClippedRect() const
5c840e5b
SC
2911{
2912 MacUpdateClippedRects() ;
e15f0a5e 2913
5c840e5b
SC
2914 return m_cachedClippedRect ;
2915}
2916
902725ee 2917const wxRect&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
5c840e5b
SC
2918{
2919 MacUpdateClippedRects() ;
e15f0a5e 2920
5c840e5b
SC
2921 return m_cachedClippedRectWithOuterStructure ;
2922}
2923
2924const wxRegion& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
94abc21f 2925{
5c840e5b 2926 static wxRegion emptyrgn ;
898d9035 2927
5c840e5b
SC
2928 if ( !m_isBeingDeleted && MacIsReallyShown() /*m_peer->IsVisible() */ )
2929 {
2930 MacUpdateClippedRects() ;
2931 if ( includeOuterStructures )
2932 return m_cachedClippedRegionWithOuterStructure ;
2933 else
2934 return m_cachedClippedRegion ;
2935 }
2936 else
2937 {
2938 return emptyrgn ;
2939 }
2940}
2941
2942void wxWindowMac::MacUpdateClippedRects() const
2943{
2944 if ( m_cachedClippedRectValid )
2945 return ;
2946
0fa8508d
SC
2947 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2948 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2949 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2950 // to add focus borders everywhere
8b573fb8 2951
e15f0a5e 2952 Rect r, rIncludingOuterStructures ;
902725ee 2953
5c840e5b
SC
2954 m_peer->GetRect( &r ) ;
2955 r.left -= MacGetLeftBorderSize() ;
2956 r.top -= MacGetTopBorderSize() ;
2957 r.bottom += MacGetBottomBorderSize() ;
2958 r.right += MacGetRightBorderSize() ;
2959
2960 r.right -= r.left ;
2961 r.bottom -= r.top ;
2962 r.left = 0 ;
2963 r.top = 0 ;
2964
2965 rIncludingOuterStructures = r ;
2966 InsetRect( &rIncludingOuterStructures , -4 , -4 ) ;
902725ee 2967
e905b636
SC
2968 wxRect cl = GetClientRect() ;
2969 Rect rClient = { cl.y , cl.x , cl.y + cl.height , cl.x + cl.width } ;
902725ee 2970
e15f0a5e
DS
2971 int x , y ;
2972 wxSize size ;
e905b636
SC
2973 const wxWindow* child = this ;
2974 const wxWindow* parent = NULL ;
898d9035 2975
e15f0a5e 2976 while ( !child->IsTopLevel() && ( parent = child->GetParent() ) != NULL )
e40298d5 2977 {
e905b636 2978 if ( parent->MacIsChildOfClientArea(child) )
94abc21f 2979 {
e905b636
SC
2980 size = parent->GetClientSize() ;
2981 wxPoint origin = parent->GetClientAreaOrigin() ;
2982 x = origin.x ;
2983 y = origin.y ;
2984 }
2985 else
2986 {
2987 // this will be true for scrollbars, toolbars etc.
2988 size = parent->GetSize() ;
2989 y = parent->MacGetTopBorderSize() ;
2990 x = parent->MacGetLeftBorderSize() ;
2991 size.x -= parent->MacGetLeftBorderSize() + parent->MacGetRightBorderSize() ;
2992 size.y -= parent->MacGetTopBorderSize() + parent->MacGetBottomBorderSize() ;
2993 }
21f9e953 2994
e905b636
SC
2995 parent->MacWindowToRootWindow( &x, &y ) ;
2996 MacRootWindowToWindow( &x , &y ) ;
21f9e953 2997
e905b636 2998 Rect rparent = { y , x , y + size.y , x + size.x } ;
5c840e5b 2999
e905b636
SC
3000 // the wxwindow and client rects will always be clipped
3001 SectRect( &r , &rparent , &r ) ;
3002 SectRect( &rClient , &rparent , &rClient ) ;
5c840e5b 3003
e905b636
SC
3004 // the structure only at 'hard' borders
3005 if ( parent->MacClipChildren() ||
3006 ( parent->GetParent() && parent->GetParent()->MacClipGrandChildren() ) )
3007 {
3008 SectRect( &rIncludingOuterStructures , &rparent , &rIncludingOuterStructures ) ;
94abc21f 3009 }
e15f0a5e 3010
e905b636 3011 child = parent ;
e40298d5 3012 }
902725ee 3013
5c840e5b 3014 m_cachedClippedRect = wxRect( r.left , r.top , r.right - r.left , r.bottom - r.top ) ;
902725ee 3015 m_cachedClippedClientRect = wxRect( rClient.left , rClient.top ,
e905b636 3016 rClient.right - rClient.left , rClient.bottom - rClient.top ) ;
902725ee
WS
3017 m_cachedClippedRectWithOuterStructure = wxRect(
3018 rIncludingOuterStructures.left , rIncludingOuterStructures.top ,
3019 rIncludingOuterStructures.right - rIncludingOuterStructures.left ,
5c840e5b 3020 rIncludingOuterStructures.bottom - rIncludingOuterStructures.top ) ;
902725ee 3021
5c840e5b
SC
3022 m_cachedClippedRegionWithOuterStructure = wxRegion( m_cachedClippedRectWithOuterStructure ) ;
3023 m_cachedClippedRegion = wxRegion( m_cachedClippedRect ) ;
e905b636 3024 m_cachedClippedClientRegion = wxRegion( m_cachedClippedClientRect ) ;
902725ee 3025
5c840e5b 3026 m_cachedClippedRectValid = true ;
94abc21f
SC
3027}
3028
facd6764
SC
3029/*
3030 This function must not change the updatergn !
3031 */
8b573fb8 3032bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time )
519cb848 3033{
facd6764 3034 bool handled = false ;
42ef83fa 3035 Rect updatebounds ;
e15f0a5e 3036 RgnHandle updatergn = (RgnHandle) updatergnr ;
42ef83fa 3037 GetRegionBounds( updatergn , &updatebounds ) ;
20b69855 3038
e15f0a5e 3039 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
c79aad8b 3040
902725ee 3041 if ( !EmptyRgn(updatergn) )
6264b550 3042 {
1c310985
SC
3043 RgnHandle newupdate = NewRgn() ;
3044 wxSize point = GetClientSize() ;
3045 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e 3046 SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y + point.y ) ;
facd6764 3047 SectRgn( newupdate , updatergn , newupdate ) ;
8b573fb8 3048
eec462f8
SC
3049 // first send an erase event to the entire update area
3050 {
c79aad8b
SC
3051 // for the toplevel window this really is the entire area
3052 // for all the others only their client area, otherwise they
3053 // might be drawing with full alpha and eg put blue into
3054 // the grow-box area of a scrolled window (scroll sample)
5c840e5b 3055 wxDC* dc = new wxWindowDC(this);
c79aad8b 3056 if ( IsTopLevel() )
5c840e5b 3057 dc->SetClippingRegion(wxRegion(updatergn));
c79aad8b 3058 else
5c840e5b 3059 dc->SetClippingRegion(wxRegion(newupdate));
902725ee 3060
c79aad8b 3061 wxEraseEvent eevent( GetId(), dc );
42ef83fa
SC
3062 eevent.SetEventObject( this );
3063 GetEventHandler()->ProcessEvent( eevent );
c79aad8b 3064 delete dc ;
eec462f8 3065 }
8b573fb8 3066
6239ee05
SC
3067 MacPaintGrowBox();
3068
42ef83fa 3069 // calculate a client-origin version of the update rgn and set m_updateRegion to that
1c310985
SC
3070 OffsetRgn( newupdate , -origin.x , -origin.y ) ;
3071 m_updateRegion = newupdate ;
8b573fb8 3072 DisposeRgn( newupdate ) ;
6ed71b4f 3073
1c310985 3074 if ( !m_updateRegion.Empty() )
6264b550 3075 {
facd6764 3076 // paint the window itself
ff3795ee 3077
e40298d5 3078 wxPaintEvent event;
687706f5 3079 event.SetTimestamp(time);
e40298d5 3080 event.SetEventObject(this);
ff3795ee
SC
3081 GetEventHandler()->ProcessEvent(event);
3082 handled = true ;
eec462f8 3083 }
8b573fb8 3084
eec462f8
SC
3085 // now we cannot rely on having its borders drawn by a window itself, as it does not
3086 // get the updateRgn wide enough to always do so, so we do it from the parent
3087 // this would also be the place to draw any custom backgrounds for native controls
3088 // in Composited windowing
36d7f54e 3089 wxPoint clientOrigin = GetClientAreaOrigin() ;
8b573fb8 3090
e15f0a5e
DS
3091 wxWindowMac *child;
3092 int x, y, w, h;
71f2fb52 3093 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
eec462f8 3094 {
e15f0a5e
DS
3095 child = node->GetData();
3096 if (child == NULL)
3097 continue;
3098 if (child == m_vScrollBar)
3099 continue;
3100 if (child == m_hScrollBar)
3101 continue;
3102 if (child->IsTopLevel())
3103 continue;
3104 if (!child->IsShown())
3105 continue;
fe779e40 3106
c79aad8b
SC
3107 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3108
af6b7b80 3109 child->GetPosition( &x, &y );
af6b7b80
SC
3110 child->GetSize( &w, &h );
3111 Rect childRect = { y , x , y + h , x + w } ;
36d7f54e 3112 OffsetRect( &childRect , clientOrigin.x , clientOrigin.y ) ;
c79aad8b
SC
3113 InsetRect( &childRect , -10 , -10) ;
3114
3115 if ( RectInRgn( &childRect , updatergn ) )
eec462f8 3116 {
c79aad8b
SC
3117 // paint custom borders
3118 wxNcPaintEvent eventNc( child->GetId() );
3119 eventNc.SetEventObject( child );
3120 if ( !child->GetEventHandler()->ProcessEvent( eventNc ) )
eec462f8 3121 {
89954433 3122#if wxMAC_USE_CORE_GRAPHICS
4f74e0d1
SC
3123 child->MacPaintBorders(0, 0) ;
3124#else
af6b7b80
SC
3125 {
3126 wxWindowDC dc(this) ;
3127 dc.SetClippingRegion(wxRegion(updatergn));
3128 wxMacPortSetter helper(&dc) ;
898d9035 3129 child->MacPaintBorders(0, 0) ;
c79aad8b 3130 }
4f74e0d1 3131#endif
eec462f8 3132 }
8b573fb8 3133 }
14c9cbdb 3134 }
6264b550 3135 }
e15f0a5e 3136
facd6764
SC
3137 return handled ;
3138}
6ed71b4f 3139
519cb848 3140
facd6764 3141WXWindow wxWindowMac::MacGetTopLevelWindowRef() const
519cb848 3142{
6264b550 3143 wxWindowMac *iter = (wxWindowMac*)this ;
14c9cbdb 3144
e15f0a5e 3145 while ( iter )
6264b550 3146 {
1c310985 3147 if ( iter->IsTopLevel() )
6239ee05
SC
3148 {
3149 wxTopLevelWindow* toplevel = wxDynamicCast(iter,wxTopLevelWindow);
3150 if ( toplevel )
3151 return toplevel->MacGetWindowRef();
3152#if wxUSE_POPUPWIN
3153 wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow);
3154 if ( popupwin )
3155 return popupwin->MacGetPopupWindowRef();
3156#endif
3157 }
6264b550 3158 iter = iter->GetParent() ;
14c9cbdb 3159 }
e15f0a5e 3160
6264b550 3161 return NULL ;
519cb848
SC
3162}
3163
6239ee05
SC
3164bool wxWindowMac::MacHasScrollBarCorner() const
3165{
3166 /* Returns whether the scroll bars in a wxScrolledWindow should be
3167 * shortened. Scroll bars should be shortened if either:
3168 *
3169 * - both scroll bars are visible, or
3170 *
3171 * - there is a resize box in the parent frame's corner and this
3172 * window shares the bottom and right edge with the parent
3173 * frame.
3174 */
3175
3176 if ( m_hScrollBar == NULL && m_vScrollBar == NULL )
3177 return false;
3178
3179 if ( ( m_hScrollBar && m_hScrollBar->IsShown() )
3180 && ( m_vScrollBar && m_vScrollBar->IsShown() ) )
3181 {
3182 // Both scroll bars visible
3183 return true;
3184 }
3185 else
3186 {
3187 wxPoint thisWindowBottomRight = GetScreenRect().GetBottomRight();
3188
3189 for ( const wxWindow *win = this; win; win = win->GetParent() )
3190 {
3191 const wxFrame *frame = wxDynamicCast( win, wxFrame ) ;
3192 if ( frame )
3193 {
3194 if ( frame->GetWindowStyleFlag() & wxRESIZE_BORDER )
3195 {
3196 // Parent frame has resize handle
3197 wxPoint frameBottomRight = frame->GetScreenRect().GetBottomRight();
3198
3199 // Note: allow for some wiggle room here as wxMac's
3200 // window rect calculations seem to be imprecise
3201 if ( abs( thisWindowBottomRight.x - frameBottomRight.x ) <= 2
3202 && abs( thisWindowBottomRight.y - frameBottomRight.y ) <= 2 )
3203 {
3204 // Parent frame has resize handle and shares
3205 // right bottom corner
3206 return true ;
3207 }
3208 else
3209 {
3210 // Parent frame has resize handle but doesn't
3211 // share right bottom corner
3212 return false ;
3213 }
3214 }
3215 else
3216 {
3217 // Parent frame doesn't have resize handle
3218 return false ;
3219 }
3220 }
3221 }
3222
3223 // No parent frame found
3224 return false ;
3225 }
3226}
3227
14c9cbdb 3228void wxWindowMac::MacCreateScrollBars( long style )
519cb848 3229{
427ff662 3230 wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ;
14c9cbdb 3231
aa99e0cd
SC
3232 if ( style & ( wxVSCROLL | wxHSCROLL ) )
3233 {
db7a550b 3234 int scrlsize = MAC_SCROLLBAR_SIZE ;
8b573fb8
VZ
3235 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL || GetWindowVariant() == wxWINDOW_VARIANT_MINI )
3236 {
3237 scrlsize = MAC_SMALL_SCROLLBAR_SIZE ;
8b573fb8 3238 }
db7a550b 3239
6239ee05 3240 int adjust = MacHasScrollBarCorner() ? scrlsize - 1: 0 ;
aa99e0cd
SC
3241 int width, height ;
3242 GetClientSize( &width , &height ) ;
3243
898d9035 3244 wxPoint vPoint(width - scrlsize, 0) ;
db7a550b 3245 wxSize vSize(scrlsize, height - adjust) ;
fbc1d11b
DS
3246 wxPoint hPoint(0, height - scrlsize) ;
3247 wxSize hSize(width - adjust, scrlsize) ;
aa99e0cd 3248
6239ee05 3249 // we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize)
aa99e0cd 3250 if ( style & wxVSCROLL )
6239ee05
SC
3251 {
3252 m_vScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, vPoint, vSize , wxVERTICAL);
3253 m_vScrollBar->SetMinSize( wxDefaultSize );
3254 }
aa99e0cd
SC
3255
3256 if ( style & wxHSCROLL )
6239ee05
SC
3257 {
3258 m_hScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, hPoint, hSize , wxHORIZONTAL);
3259 m_hScrollBar->SetMinSize( wxDefaultSize );
3260 }
aa99e0cd 3261 }
aa99e0cd 3262
6264b550 3263 // because the create does not take into account the client area origin
e15f0a5e
DS
3264 // we might have a real position shift
3265 MacRepositionScrollBars() ;
519cb848
SC
3266}
3267
e905b636
SC
3268bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const
3269{
fbc1d11b
DS
3270 bool result = ((child == NULL) || ((child != m_hScrollBar) && (child != m_vScrollBar)));
3271
3272 return result ;
e905b636
SC
3273}
3274
e766c8a9 3275void wxWindowMac::MacRepositionScrollBars()
519cb848 3276{
aa99e0cd
SC
3277 if ( !m_hScrollBar && !m_vScrollBar )
3278 return ;
8b573fb8 3279
db7a550b 3280 int scrlsize = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
6239ee05 3281 int adjust = MacHasScrollBarCorner() ? scrlsize - 1 : 0 ;
14c9cbdb 3282
6264b550 3283 // get real client area
e15f0a5e
DS
3284 int width, height ;
3285 GetSize( &width , &height );
6264b550
RR
3286
3287 width -= MacGetLeftBorderSize() + MacGetRightBorderSize();
3288 height -= MacGetTopBorderSize() + MacGetBottomBorderSize();
14c9cbdb 3289
e15f0a5e
DS
3290 wxPoint vPoint( width - scrlsize, 0 ) ;
3291 wxSize vSize( scrlsize, height - adjust ) ;
3292 wxPoint hPoint( 0 , height - scrlsize ) ;
3293 wxSize hSize( width - adjust, scrlsize ) ;
3294
3295#if 0
3296 int x = 0, y = 0, w, h ;
facd6764 3297 GetSize( &w , &h ) ;
14c9cbdb 3298
6264b550
RR
3299 MacClientToRootWindow( &x , &y ) ;
3300 MacClientToRootWindow( &w , &h ) ;
14c9cbdb 3301
6264b550 3302 wxWindowMac *iter = (wxWindowMac*)this ;
14c9cbdb 3303
6264b550 3304 int totW = 10000 , totH = 10000;
e15f0a5e 3305 while ( iter )
6264b550 3306 {
1c310985 3307 if ( iter->IsTopLevel() )
6264b550 3308 {
facd6764 3309 iter->GetSize( &totW , &totH ) ;
6264b550
RR
3310 break ;
3311 }
3312
3313 iter = iter->GetParent() ;
14c9cbdb
RD
3314 }
3315
6264b550
RR
3316 if ( x == 0 )
3317 {
3318 hPoint.x = -1 ;
3319 hSize.x += 1 ;
3320 }
3321 if ( y == 0 )
3322 {
3323 vPoint.y = -1 ;
3324 vSize.y += 1 ;
3325 }
14c9cbdb 3326
e15f0a5e 3327 if ( w - x >= totW )
6264b550
RR
3328 {
3329 hSize.x += 1 ;
3330 vPoint.x += 1 ;
3331 }
e15f0a5e 3332 if ( h - y >= totH )
6264b550
RR
3333 {
3334 vSize.y += 1 ;
3335 hPoint.y += 1 ;
3336 }
e15f0a5e
DS
3337#endif
3338
6264b550 3339 if ( m_vScrollBar )
e15f0a5e 3340 m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE );
6264b550 3341 if ( m_hScrollBar )
e15f0a5e 3342 m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE );
519cb848
SC
3343}
3344
e766c8a9 3345bool wxWindowMac::AcceptsFocus() const
7c551d95
SC
3346{
3347 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3348}
519cb848 3349
14c9cbdb 3350void wxWindowMac::MacSuperChangedPosition()
519cb848 3351{
6264b550 3352 // only window-absolute structures have to be moved i.e. controls
519cb848 3353
e15f0a5e
DS
3354 m_cachedClippedRectValid = false ;
3355
3356 wxWindowMac *child;
71f2fb52 3357 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
6264b550
RR
3358 while ( node )
3359 {
e15f0a5e 3360 child = node->GetData();
6264b550 3361 child->MacSuperChangedPosition() ;
e15f0a5e 3362
eb22f2a6 3363 node = node->GetNext();
6264b550 3364 }
519cb848 3365}
519cb848 3366
14c9cbdb 3367void wxWindowMac::MacTopLevelWindowChangedPosition()
a3bf4a62 3368{
6264b550 3369 // only screen-absolute structures have to be moved i.e. glcanvas
a3bf4a62 3370
e15f0a5e 3371 wxWindowMac *child;
71f2fb52 3372 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
6264b550
RR
3373 while ( node )
3374 {
e15f0a5e 3375 child = node->GetData();
6264b550 3376 child->MacTopLevelWindowChangedPosition() ;
e15f0a5e 3377
eb22f2a6 3378 node = node->GetNext();
6264b550 3379 }
a3bf4a62 3380}
facd6764 3381
e15f0a5e 3382long wxWindowMac::MacGetLeftBorderSize() const
2f1ae414 3383{
e15f0a5e 3384 if ( IsTopLevel() )
6264b550 3385 return 0 ;
2f1ae414 3386
8f39b6c4 3387 SInt32 border = 0 ;
902725ee 3388
e15f0a5e 3389 if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER))
2f1ae414 3390 {
fbc1d11b 3391 // this metric is only the 'outset' outside the simple frame rect
8f39b6c4 3392 GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ;
fbc1d11b 3393 border += 1 ;
2f1ae414 3394 }
8f39b6c4 3395 else if (HasFlag(wxSIMPLE_BORDER))
2f1ae414 3396 {
fbc1d11b 3397 // this metric is only the 'outset' outside the simple frame rect
8f39b6c4 3398 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
fbc1d11b 3399 border += 1 ;
2f1ae414 3400 }
e15f0a5e 3401
8f39b6c4 3402 return border ;
2f1ae414
SC
3403}
3404
e15f0a5e 3405long wxWindowMac::MacGetRightBorderSize() const
5b781a67 3406{
1c310985
SC
3407 // they are all symmetric in mac themes
3408 return MacGetLeftBorderSize() ;
5b781a67
SC
3409}
3410
e15f0a5e 3411long wxWindowMac::MacGetTopBorderSize() const
5b781a67 3412{
1c310985
SC
3413 // they are all symmetric in mac themes
3414 return MacGetLeftBorderSize() ;
5b781a67
SC
3415}
3416
e15f0a5e 3417long wxWindowMac::MacGetBottomBorderSize() const
5b781a67 3418{
1c310985
SC
3419 // they are all symmetric in mac themes
3420 return MacGetLeftBorderSize() ;
5b781a67
SC
3421}
3422
14c9cbdb 3423long wxWindowMac::MacRemoveBordersFromStyle( long style )
2f1ae414 3424{
055a486b 3425 return style & ~wxBORDER_MASK ;
2f1ae414 3426}
0a67a93b 3427
e766c8a9 3428// Find the wxWindowMac at the current mouse position, returning the mouse
3723b7b1 3429// position.
e15f0a5e 3430wxWindowMac * wxFindWindowAtPointer( wxPoint& pt )
3723b7b1 3431{
59a12e90 3432 pt = wxGetMousePosition();
e766c8a9 3433 wxWindowMac* found = wxFindWindowAtPoint(pt);
e15f0a5e 3434
59a12e90 3435 return found;
3723b7b1
JS
3436}
3437
3438// Get the current mouse position.
3439wxPoint wxGetMousePosition()
3440{
57591e0e 3441 int x, y;
e15f0a5e
DS
3442
3443 wxGetMousePosition( &x, &y );
3444
57591e0e 3445 return wxPoint(x, y);
3723b7b1
JS
3446}
3447
6ed71b4f 3448void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
8950f7cc 3449{
8b573fb8
VZ
3450 if ( event.GetEventType() == wxEVT_RIGHT_DOWN )
3451 {
3452 // copied from wxGTK : CS
fe224552
VZ
3453 // VZ: shouldn't we move this to base class then?
3454
249aad30 3455 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
8950f7cc
SC
3456 // except that:
3457 //
3458 // (a) it's a command event and so is propagated to the parent
3459 // (b) under MSW it can be generated from kbd too
3460 // (c) it uses screen coords (because of (a))
3461 wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
3462 this->GetId(),
3463 this->ClientToScreen(event.GetPosition()));
249aad30
SC
3464 if ( ! GetEventHandler()->ProcessEvent(evtCtx) )
3465 event.Skip() ;
8b573fb8 3466 }
facd6764
SC
3467 else
3468 {
8b573fb8 3469 event.Skip() ;
facd6764 3470 }
8950f7cc
SC
3471}
3472
89954433 3473void wxWindowMac::OnPaint( wxPaintEvent & WXUNUSED(event) )
ff3795ee 3474{
4488a1d3
VZ
3475 if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL
3476 && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT )
e15f0a5e
DS
3477 CallNextEventHandler(
3478 (EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() ,
3479 (EventRef) wxTheApp->MacGetCurrentEvent() ) ;
ff3795ee
SC
3480}
3481
89954433
VZ
3482void wxWindowMac::MacHandleControlClick(WXWidget WXUNUSED(control),
3483 wxInt16 WXUNUSED(controlpart),
3484 bool WXUNUSED(mouseStillDown))
facd6764 3485{
facd6764
SC
3486}
3487
8b573fb8 3488Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin )
3083eb85 3489{
e15f0a5e 3490 int x, y, w, h ;
8b573fb8 3491
58603178
DS
3492 window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ;
3493 Rect bounds = { y, x, y + h, x + w };
e15f0a5e 3494
3083eb85
SC
3495 return bounds ;
3496}
3497
8b573fb8 3498wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) )
f1d527c1
SC
3499{
3500 return eventNotHandledErr ;
3501}
3502
50779e06
JS
3503bool wxWindowMac::Reparent(wxWindowBase *newParentBase)
3504{
3505 wxWindowMac *newParent = (wxWindowMac *)newParentBase;
50779e06 3506 if ( !wxWindowBase::Reparent(newParent) )
3dee36ae
WS
3507 return false;
3508
e15f0a5e 3509 // copied from MacPostControlCreate
50779e06 3510 ControlRef container = (ControlRef) GetParent()->GetHandle() ;
e15f0a5e 3511
50779e06 3512 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
e15f0a5e 3513
50779e06 3514 ::EmbedControl( m_peer->GetControlRef() , container ) ;
facd6764 3515
3dee36ae
WS
3516 return true;
3517}
a9b456ff
SC
3518
3519bool wxWindowMac::SetTransparent(wxByte alpha)
3520{
3521#if wxMAC_USE_CORE_GRAPHICS
4488a1d3
VZ
3522 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
3523
a9b456ff
SC
3524 if ( alpha != m_macAlpha )
3525 {
3526 m_macAlpha = alpha ;
3527 Refresh() ;
3528 }
3529 return true ;
3530#else
3531 return false ;
3532#endif
3533}
3534
3535
3536bool wxWindowMac::CanSetTransparent()
3537{
3538#if wxMAC_USE_CORE_GRAPHICS
3539 return true ;
3540#else
3541 return false ;
3542#endif
3543}
3544
89954433 3545wxByte wxWindowMac::GetTransparent() const
a9b456ff
SC
3546{
3547 return m_macAlpha ;
8444b6cb 3548}