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