]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/window.cpp
cleanup - reformat
[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
SC
469#if wxUSE_UNICODE
470 textCtrl->WriteText( wxString( content , wxConvLocal ) );
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
e766c8a9 850bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id,
e9576ca5
SC
851 const wxPoint& pos,
852 const wxSize& size,
853 long style,
854 const wxString& name)
855{
902725ee 856 wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") );
e9576ca5 857
e7549107 858 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
902725ee 859 return false;
e9576ca5 860
facd6764 861 m_windowVariant = parent->GetWindowVariant() ;
8b573fb8 862
facd6764
SC
863 if ( m_macIsUserPane )
864 {
865 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
8b573fb8 866
ebe86b1e 867 UInt32 features = 0
8b573fb8 868 | kControlSupportsEmbedding
1f1c8bd4
SC
869 | kControlSupportsLiveFeedback
870 | kControlGetsFocusOnClick
8b573fb8
VZ
871// | kControlHasSpecialBackground
872// | kControlSupportsCalcBestRect
1f1c8bd4 873 | kControlHandlesTracking
8b573fb8 874 | kControlSupportsFocus
1f1c8bd4
SC
875 | kControlWantsActivate
876 | kControlWantsIdle
8b573fb8 877 ;
ebe86b1e 878
6449b3a8 879 m_peer = new wxMacControl(this) ;
5ca0d812 880 ::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , m_peer->GetControlRefAddr() );
8b573fb8 881
898d9035 882 MacPostControlCreate(pos, size) ;
facd6764 883 }
898d9035 884
e766c8a9 885#ifndef __WXUNIVERSAL__
14c9cbdb
RD
886 // Don't give scrollbars to wxControls unless they ask for them
887 if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar))) ||
888 (IsKindOf(CLASSINFO(wxControl)) && ( style & wxHSCROLL || style & wxVSCROLL)))
6264b550
RR
889 {
890 MacCreateScrollBars( style ) ;
891 }
e766c8a9 892#endif
3dfafdb9
RD
893
894 wxWindowCreateEvent event(this);
7e4a196e 895 GetEventHandler()->AddPendingEvent(event);
3dfafdb9 896
902725ee 897 return true;
e9576ca5
SC
898}
899
902725ee 900void wxWindowMac::MacChildAdded()
08422003
SC
901{
902 if ( m_vScrollBar )
08422003 903 m_vScrollBar->Raise() ;
08422003 904 if ( m_hScrollBar )
08422003 905 m_hScrollBar->Raise() ;
08422003
SC
906}
907
facd6764
SC
908void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size)
909{
21fd5529 910 wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid mac control") ) ;
facd6764 911
5ca0d812 912 m_peer->SetReference( (long) this ) ;
488abb22 913 GetParent()->AddChild(this);
facd6764 914
5ca0d812 915 MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() );
facd6764
SC
916
917 ControlRef container = (ControlRef) GetParent()->GetHandle() ;
918 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
5ca0d812 919 ::EmbedControl( m_peer->GetControlRef() , container ) ;
08422003 920 GetParent()->MacChildAdded() ;
facd6764
SC
921
922 // adjust font, controlsize etc
923 DoSetWindowVariant( m_windowVariant ) ;
924
fb5246be 925 m_peer->SetLabel( wxStripMenuCodes(m_label) ) ;
facd6764 926
facd6764 927 if (!m_macIsUserPane)
d3b5db4b 928 SetInitialBestSize(size);
facd6764
SC
929
930 SetCursor( *wxSTANDARD_CURSOR ) ;
facd6764
SC
931}
932
933void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
934{
23176131
JS
935 // Don't assert, in case we set the window variant before
936 // the window is created
21fd5529 937 // wxASSERT( m_peer->Ok() ) ;
facd6764 938
23176131
JS
939 m_windowVariant = variant ;
940
21fd5529 941 if (m_peer == NULL || !m_peer->Ok())
23176131 942 return;
facd6764 943
8b573fb8 944 ControlSize size ;
facd6764
SC
945 ThemeFontID themeFont = kThemeSystemFont ;
946
947 // we will get that from the settings later
8b573fb8 948 // and make this NORMAL later, but first
facd6764 949 // we have a few calculations that we must fix
8b573fb8 950
facd6764
SC
951 switch ( variant )
952 {
953 case wxWINDOW_VARIANT_NORMAL :
8b573fb8
VZ
954 size = kControlSizeNormal;
955 themeFont = kThemeSystemFont ;
facd6764 956 break ;
e15f0a5e 957
facd6764 958 case wxWINDOW_VARIANT_SMALL :
8b573fb8
VZ
959 size = kControlSizeSmall;
960 themeFont = kThemeSmallSystemFont ;
facd6764 961 break ;
e15f0a5e 962
facd6764
SC
963 case wxWINDOW_VARIANT_MINI :
964 if (UMAGetSystemVersion() >= 0x1030 )
965 {
8b573fb8
VZ
966 // not always defined in the headers
967 size = 3 ;
968 themeFont = 109 ;
facd6764
SC
969 }
970 else
971 {
8b573fb8
VZ
972 size = kControlSizeSmall;
973 themeFont = kThemeSmallSystemFont ;
facd6764
SC
974 }
975 break ;
e15f0a5e 976
facd6764 977 case wxWINDOW_VARIANT_LARGE :
8b573fb8
VZ
978 size = kControlSizeLarge;
979 themeFont = kThemeSystemFont ;
facd6764 980 break ;
e15f0a5e 981
facd6764
SC
982 default:
983 wxFAIL_MSG(_T("unexpected window variant"));
984 break ;
985 }
e15f0a5e 986
898d9035 987 m_peer->SetData<ControlSize>(kControlEntireControl, kControlSizeTag, &size ) ;
facd6764
SC
988
989 wxFont font ;
990 font.MacCreateThemeFont( themeFont ) ;
991 SetFont( font ) ;
992}
993
8b573fb8 994void wxWindowMac::MacUpdateControlFont()
facd6764 995{
ac99838a 996 m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
8b573fb8 997 Refresh() ;
facd6764
SC
998}
999
1000bool wxWindowMac::SetFont(const wxFont& font)
1001{
d5ccba72 1002 bool retval = wxWindowBase::SetFont( font ) ;
8b573fb8 1003
facd6764 1004 MacUpdateControlFont() ;
8b573fb8 1005
facd6764
SC
1006 return retval;
1007}
1008
1009bool wxWindowMac::SetForegroundColour(const wxColour& col )
1010{
898d9035 1011 bool retval = wxWindowBase::SetForegroundColour(col);
8b573fb8 1012
898d9035
DS
1013 if (retval)
1014 MacUpdateControlFont() ;
8b573fb8 1015
898d9035 1016 return retval;
facd6764
SC
1017}
1018
1019bool wxWindowMac::SetBackgroundColour(const wxColour& col )
1020{
1021 if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol )
1022 return false ;
1023
1024 wxBrush brush ;
b52acd03
RD
1025 wxColour newCol(GetBackgroundColour());
1026 if ( newCol == wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) )
facd6764 1027 brush.MacSetTheme( kThemeBrushDocumentWindowBackground ) ;
b52acd03 1028 else if ( newCol == wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE ) )
8b573fb8 1029 brush.MacSetTheme( kThemeBrushDialogBackgroundActive ) ;
facd6764 1030 else
b52acd03 1031 brush.SetColour( newCol ) ;
e15f0a5e 1032
facd6764 1033 MacSetBackgroundBrush( brush ) ;
8b573fb8 1034
db7a550b 1035 MacUpdateControlFont() ;
8b573fb8 1036
facd6764
SC
1037 return true ;
1038}
1039
7ea087b7
SC
1040void wxWindowMac::MacSetBackgroundBrush( const wxBrush &brush )
1041{
1042 m_macBackgroundBrush = brush ;
1043 m_peer->SetBackground( brush ) ;
1044}
facd6764
SC
1045
1046bool wxWindowMac::MacCanFocus() const
1047{
f6e3849c
SC
1048 // there is currently no way to determine whether the window is running in full keyboard
1049 // access mode, therefore we cannot rely on these features, yet the only other way would be
1050 // to issue a SetKeyboardFocus event and verify after whether it succeeded, this would risk problems
1051 // in event handlers...
f1d527c1 1052 UInt32 features = 0 ;
898d9035 1053 m_peer->GetFeatures( &features ) ;
e15f0a5e 1054
8b573fb8 1055 return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ;
facd6764
SC
1056}
1057
e766c8a9 1058void wxWindowMac::SetFocus()
e9576ca5 1059{
e15f0a5e 1060 if ( !AcceptsFocus() )
7d0cfe71
SC
1061 return ;
1062
e15f0a5e
DS
1063 wxWindow* former = FindFocus() ;
1064 if ( former == this )
1065 return ;
1066
1067 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1068 // we can only leave in case of an error
1069 OSStatus err = m_peer->SetFocus( kControlFocusNextPart ) ;
1070 if ( err == errCouldntSetFocus )
1071 return ;
1072
e15f0a5e 1073 SetUserFocusWindow( (WindowRef)MacGetTopLevelWindowRef() );
f1d527c1
SC
1074
1075#if !TARGET_API_MAC_OSX
e15f0a5e
DS
1076 // emulate carbon events when running under CarbonLib where they are not natively available
1077 if ( former )
1078 {
1079 EventRef evRef = NULL ;
1080 verify_noerr( MacCreateEvent( NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) , kEventAttributeUserEvent ,
1081 &evRef ) );
f1d527c1 1082
e15f0a5e
DS
1083 wxMacCarbonEvent cEvent( evRef ) ;
1084 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) former->GetHandle() ) ;
1085 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNoPart ) ;
8b573fb8 1086
e15f0a5e
DS
1087 wxMacWindowEventHandler( NULL , evRef , former ) ;
1088 ReleaseEvent(evRef) ;
1089 }
f1d527c1 1090
e15f0a5e
DS
1091 // send new focus event
1092 {
1093 EventRef evRef = NULL ;
1094 verify_noerr( MacCreateEvent( NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) , kEventAttributeUserEvent ,
1095 &evRef ) );
8b573fb8 1096
e15f0a5e
DS
1097 wxMacCarbonEvent cEvent( evRef ) ;
1098 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) GetHandle() ) ;
1099 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNextPart ) ;
1100
1101 wxMacWindowEventHandler( NULL , evRef , this ) ;
1102 ReleaseEvent(evRef) ;
6264b550 1103 }
e15f0a5e 1104#endif
e9576ca5
SC
1105}
1106
4116c221 1107void wxWindowMac::DoCaptureMouse()
e9576ca5 1108{
2a1f999f 1109 wxApp::s_captureWindow = this ;
e9576ca5
SC
1110}
1111
90b959ae
SC
1112wxWindow* wxWindowBase::GetCapture()
1113{
2a1f999f 1114 return wxApp::s_captureWindow ;
90b959ae
SC
1115}
1116
4116c221 1117void wxWindowMac::DoReleaseMouse()
e9576ca5 1118{
2a1f999f 1119 wxApp::s_captureWindow = NULL ;
e9576ca5
SC
1120}
1121
e15f0a5e 1122#if wxUSE_DRAG_AND_DROP
e9576ca5 1123
e766c8a9 1124void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
e9576ca5 1125{
e15f0a5e 1126 if ( m_dropTarget != NULL )
e40298d5 1127 delete m_dropTarget;
6ed71b4f 1128
e40298d5 1129 m_dropTarget = pDropTarget;
e15f0a5e 1130 if ( m_dropTarget != NULL )
e40298d5
JS
1131 {
1132 // TODO
1133 }
e9576ca5
SC
1134}
1135
1136#endif
1137
1138// Old style file-manager drag&drop
e766c8a9 1139void wxWindowMac::DragAcceptFiles(bool accept)
e9576ca5
SC
1140{
1141 // TODO
1142}
1143
055a486b
SC
1144// Returns the size of the native control. In the case of the toplevel window
1145// this is the content area root control
1146
facd6764 1147void wxWindowMac::MacGetPositionAndSizeFromControl(int& x, int& y,
8b573fb8 1148 int& w, int& h) const
e9576ca5 1149{
898d9035 1150 wxFAIL_MSG( wxT("Not currently supported") ) ;
e9576ca5
SC
1151}
1152
055a486b 1153// From a wx position / size calculate the appropriate size of the native control
8b573fb8 1154
898d9035
DS
1155bool wxWindowMac::MacGetBoundsForControl(
1156 const wxPoint& pos,
1157 const wxSize& size,
1158 int& x, int& y,
1159 int& w, int& h , bool adjustOrigin ) const
51abe921 1160{
789ae0cf 1161 bool isCompositing = MacGetTopLevelWindow()->MacUsesCompositing() ;
902725ee 1162
5ca0d812 1163 // the desired size, minus the border pixels gives the correct size of the control
8b573fb8 1164
facd6764
SC
1165 x = (int)pos.x;
1166 y = (int)pos.y;
1167 // todo the default calls may be used as soon as PostCreateControl Is moved here
898d9035
DS
1168 w = wxMax(size.x, 0) ; // WidthDefault( size.x );
1169 h = wxMax(size.y, 0) ; // HeightDefault( size.y ) ;
789ae0cf
SC
1170
1171 if ( !isCompositing )
1172 GetParent()->MacWindowToRootWindow( &x , &y ) ;
5ca0d812
SC
1173
1174 x += MacGetLeftBorderSize() ;
1175 y += MacGetTopBorderSize() ;
1176 w -= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1177 h -= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
8b573fb8 1178
79392158
SC
1179 if ( adjustOrigin )
1180 AdjustForParentClientOrigin( x , y ) ;
789ae0cf 1181
7ebf5540 1182 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
789ae0cf 1183 if ( !GetParent()->IsTopLevel() )
7ebf5540
SC
1184 {
1185 x -= GetParent()->MacGetLeftBorderSize() ;
1186 y -= GetParent()->MacGetTopBorderSize() ;
1187 }
789ae0cf 1188
facd6764
SC
1189 return true ;
1190}
1191
42ef83fa 1192// Get window size (not client size)
facd6764
SC
1193void wxWindowMac::DoGetSize(int *x, int *y) const
1194{
1f1c8bd4
SC
1195 Rect bounds ;
1196 m_peer->GetRect( &bounds ) ;
8b573fb8 1197
e15f0a5e
DS
1198 if (x)
1199 *x = bounds.right - bounds.left + MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1200 if (y)
1201 *y = bounds.bottom - bounds.top + MacGetTopBorderSize() + MacGetBottomBorderSize() ;
facd6764
SC
1202}
1203
42ef83fa 1204// get the position of the bounds of this window in client coordinates of its parent
facd6764
SC
1205void wxWindowMac::DoGetPosition(int *x, int *y) const
1206{
1f1c8bd4
SC
1207 Rect bounds ;
1208 m_peer->GetRect( &bounds ) ;
902725ee 1209
1f1c8bd4
SC
1210 int x1 = bounds.left ;
1211 int y1 = bounds.top ;
789ae0cf 1212
bc2b0c1b
SC
1213 // get the wx window position from the native one
1214 x1 -= MacGetLeftBorderSize() ;
1215 y1 -= MacGetTopBorderSize() ;
1216
facd6764 1217 if ( !IsTopLevel() )
2b5f62a0 1218 {
facd6764
SC
1219 wxWindow *parent = GetParent();
1220 if ( parent )
8950f7cc 1221 {
e15f0a5e
DS
1222 // we must first adjust it to be in window coordinates of the parent,
1223 // as otherwise it gets lost by the ClientAreaOrigin fix
1a02aff9
SC
1224 x1 += parent->MacGetLeftBorderSize() ;
1225 y1 += parent->MacGetTopBorderSize() ;
e15f0a5e 1226
1a02aff9 1227 // and now to client coordinates
facd6764
SC
1228 wxPoint pt(parent->GetClientAreaOrigin());
1229 x1 -= pt.x ;
1230 y1 -= pt.y ;
6ed71b4f 1231 }
2b5f62a0 1232 }
e15f0a5e
DS
1233
1234 if (x)
1235 *x = x1 ;
1236 if (y)
1237 *y = y1 ;
facd6764 1238}
51abe921 1239
e766c8a9 1240void wxWindowMac::DoScreenToClient(int *x, int *y) const
e9576ca5 1241{
facd6764 1242 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
8b573fb8 1243
facd6764 1244 wxCHECK_RET( window , wxT("TopLevel Window Missing") ) ;
8b573fb8 1245
facd6764 1246 {
e15f0a5e 1247 Point localwhere = {0, 0} ;
519cb848 1248
e15f0a5e
DS
1249 if (x)
1250 localwhere.h = *x ;
1251 if (y)
1252 localwhere.v = *y ;
8b573fb8 1253
a9de2608 1254 QDGlobalToLocalPoint( GetWindowPort( window ) , &localwhere ) ;
6ed71b4f 1255
e15f0a5e
DS
1256 if (x)
1257 *x = localwhere.h ;
1258 if (y)
1259 *y = localwhere.v ;
facd6764 1260 }
e15f0a5e 1261
2078220e 1262 MacRootWindowToWindow( x , y ) ;
8b573fb8 1263
facd6764 1264 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1265 if (x)
1266 *x -= origin.x ;
1267 if (y)
1268 *y -= origin.y ;
e9576ca5
SC
1269}
1270
e766c8a9 1271void wxWindowMac::DoClientToScreen(int *x, int *y) const
e9576ca5 1272{
facd6764 1273 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
8523a5f5 1274 wxCHECK_RET( window , wxT("TopLevel window missing") ) ;
14c9cbdb 1275
facd6764 1276 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1277 if (x)
1278 *x += origin.x ;
1279 if (y)
1280 *y += origin.y ;
14c9cbdb 1281
2078220e 1282 MacWindowToRootWindow( x , y ) ;
14c9cbdb 1283
facd6764 1284 {
8523a5f5 1285 Point localwhere = { 0, 0 };
e15f0a5e
DS
1286 if (x)
1287 localwhere.h = * x ;
1288 if (y)
1289 localwhere.v = * y ;
1290
a9de2608 1291 QDLocalToGlobalPoint( GetWindowPort( window ) , &localwhere ) ;
e15f0a5e
DS
1292
1293 if (x)
1294 *x = localwhere.h ;
1295 if (y)
1296 *y = localwhere.v ;
facd6764 1297 }
519cb848
SC
1298}
1299
e766c8a9 1300void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const
519cb848 1301{
1c310985 1302 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1303 if (x)
1304 *x += origin.x ;
1305 if (y)
1306 *y += origin.y ;
14c9cbdb 1307
1c310985
SC
1308 MacWindowToRootWindow( x , y ) ;
1309}
1310
1311void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const
1312{
1c310985 1313 MacRootWindowToWindow( x , y ) ;
facd6764
SC
1314
1315 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1316 if (x)
1317 *x -= origin.x ;
1318 if (y)
1319 *y -= origin.y ;
1c310985
SC
1320}
1321
1322void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
1323{
5ca0d812 1324 wxPoint pt ;
e15f0a5e
DS
1325 if (x)
1326 pt.x = *x ;
1327 if (y)
1328 pt.y = *y ;
facd6764 1329
125c7984 1330 if ( !IsTopLevel() )
5437ff47
RD
1331 {
1332 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
1333 if (top)
5ca0d812
SC
1334 {
1335 pt.x -= MacGetLeftBorderSize() ;
1336 pt.y -= MacGetTopBorderSize() ;
1337 wxMacControl::Convert( &pt , m_peer , top->m_peer ) ;
1338 }
5437ff47 1339 }
8b573fb8 1340
e15f0a5e
DS
1341 if (x)
1342 *x = (int) pt.x ;
1343 if (y)
1344 *y = (int) pt.y ;
facd6764
SC
1345}
1346
1347void wxWindowMac::MacWindowToRootWindow( short *x , short *y ) const
1348{
1349 int x1 , y1 ;
e15f0a5e
DS
1350
1351 if (x)
1352 x1 = *x ;
1353 if (y)
1354 y1 = *y ;
1355
facd6764 1356 MacWindowToRootWindow( &x1 , &y1 ) ;
e15f0a5e
DS
1357
1358 if (x)
1359 *x = x1 ;
1360 if (y)
1361 *y = y1 ;
519cb848
SC
1362}
1363
1c310985 1364void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
519cb848 1365{
5ca0d812 1366 wxPoint pt ;
e15f0a5e
DS
1367
1368 if (x)
1369 pt.x = *x ;
1370 if (y)
1371 pt.y = *y ;
facd6764 1372
125c7984 1373 if ( !IsTopLevel() )
5ca0d812 1374 {
5c840e5b
SC
1375 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
1376 if (top)
1377 {
1378 wxMacControl::Convert( &pt , top->m_peer , m_peer ) ;
1379 pt.x += MacGetLeftBorderSize() ;
1380 pt.y += MacGetTopBorderSize() ;
1381 }
5ca0d812 1382 }
8b573fb8 1383
e15f0a5e
DS
1384 if (x)
1385 *x = (int) pt.x ;
1386 if (y)
1387 *y = (int) pt.y ;
e9576ca5
SC
1388}
1389
facd6764 1390void wxWindowMac::MacRootWindowToWindow( short *x , short *y ) const
e9576ca5 1391{
facd6764 1392 int x1 , y1 ;
e15f0a5e
DS
1393
1394 if (x)
1395 x1 = *x ;
1396 if (y)
1397 y1 = *y ;
1398
facd6764 1399 MacRootWindowToWindow( &x1 , &y1 ) ;
e15f0a5e
DS
1400
1401 if (x)
1402 *x = x1 ;
1403 if (y)
1404 *y = y1 ;
facd6764 1405}
6ed71b4f 1406
29281095
SC
1407void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom )
1408{
1409 RgnHandle rgn = NewRgn() ;
898d9035 1410
5ca0d812 1411 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
29281095 1412 {
898d9035
DS
1413 Rect structure, content ;
1414
29281095 1415 GetRegionBounds( rgn , &content ) ;
1f1c8bd4
SC
1416 m_peer->GetRect( &structure ) ;
1417 OffsetRect( &structure, -structure.left , -structure.top ) ;
902725ee 1418
1f1c8bd4 1419 left = content.left - structure.left ;
898d9035 1420 top = content.top - structure.top ;
1f1c8bd4
SC
1421 right = structure.right - content.right ;
1422 bottom = structure.bottom - content.bottom ;
29281095
SC
1423 }
1424 else
1425 {
1f1c8bd4 1426 left = top = right = bottom = 0 ;
29281095 1427 }
898d9035 1428
7596e51d 1429 DisposeRgn( rgn ) ;
29281095
SC
1430}
1431
facd6764
SC
1432wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const
1433{
1434 wxSize sizeTotal = size;
1435
1436 RgnHandle rgn = NewRgn() ;
5ca0d812 1437 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
6618870d 1438 {
898d9035 1439 Rect content, structure ;
facd6764 1440 GetRegionBounds( rgn , &content ) ;
1f1c8bd4 1441 m_peer->GetRect( &structure ) ;
898d9035 1442
1f1c8bd4 1443 // structure is in parent coordinates, but we only need width and height, so it's ok
6ed71b4f 1444
1f1c8bd4 1445 sizeTotal.x += (structure.right - structure.left) - (content.right - content.left) ;
8523a5f5 1446 sizeTotal.y += (structure.bottom - structure.top) - (content.bottom - content.top) ;
1f1c8bd4 1447 }
898d9035 1448
1f1c8bd4 1449 DisposeRgn( rgn ) ;
6ed71b4f 1450
e15f0a5e
DS
1451 sizeTotal.x += MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1452 sizeTotal.y += MacGetTopBorderSize() + MacGetBottomBorderSize() ;
6ed71b4f 1453
facd6764 1454 return sizeTotal;
e9576ca5
SC
1455}
1456
e9576ca5 1457// Get size *available for subwindows* i.e. excluding menu bar etc.
e15f0a5e 1458void wxWindowMac::DoGetClientSize( int *x, int *y ) const
e9576ca5 1459{
9453cf2b 1460 int ww, hh;
6ed71b4f 1461
facd6764
SC
1462 RgnHandle rgn = NewRgn() ;
1463 Rect content ;
5ca0d812 1464 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
facd6764 1465 GetRegionBounds( rgn , &content ) ;
facd6764 1466 else
5ca0d812 1467 m_peer->GetRect( &content ) ;
7596e51d 1468 DisposeRgn( rgn ) ;
789ae0cf 1469
facd6764
SC
1470 ww = content.right - content.left ;
1471 hh = content.bottom - content.top ;
6ed71b4f 1472
db7a550b 1473 if (m_hScrollBar && m_hScrollBar->IsShown() )
e905b636 1474 hh -= m_hScrollBar->GetSize().y ;
e15f0a5e 1475
db7a550b 1476 if (m_vScrollBar && m_vScrollBar->IsShown() )
e905b636 1477 ww -= m_vScrollBar->GetSize().x ;
e15f0a5e
DS
1478
1479 if (x)
1480 *x = ww;
1481 if (y)
1482 *y = hh;
facd6764
SC
1483}
1484
1485bool wxWindowMac::SetCursor(const wxCursor& cursor)
1486{
1487 if (m_cursor == cursor)
902725ee 1488 return false;
facd6764
SC
1489
1490 if (wxNullCursor == cursor)
1491 {
1492 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
902725ee 1493 return false ;
facd6764
SC
1494 }
1495 else
1496 {
1497 if ( ! wxWindowBase::SetCursor( cursor ) )
902725ee 1498 return false ;
facd6764
SC
1499 }
1500
1501 wxASSERT_MSG( m_cursor.Ok(),
1502 wxT("cursor must be valid after call to the base version"));
8b573fb8 1503
2d1760d3 1504 wxWindowMac *mouseWin = 0 ;
facd6764 1505 {
789ae0cf
SC
1506 wxTopLevelWindowMac *tlw = MacGetTopLevelWindow() ;
1507 WindowRef window = (WindowRef) ( tlw ? tlw->MacGetWindowRef() : 0 ) ;
2d1760d3
SC
1508 CGrafPtr savePort ;
1509 Boolean swapped = QDSwapPort( GetWindowPort( window ) , &savePort ) ;
8b573fb8 1510
2d1760d3
SC
1511 // TODO If we ever get a GetCurrentEvent.. replacement for the mouse
1512 // position, use it...
8b573fb8 1513
2d1760d3
SC
1514 Point pt ;
1515 GetMouse( &pt ) ;
1516 ControlPartCode part ;
1517 ControlRef control ;
789ae0cf 1518 control = wxMacFindControlUnderMouse( tlw , pt , window , &part ) ;
2d1760d3
SC
1519 if ( control )
1520 mouseWin = wxFindControlFromMacControl( control ) ;
8b573fb8 1521
2d1760d3
SC
1522 if ( swapped )
1523 QDSwapPort( savePort , NULL ) ;
facd6764 1524 }
2d1760d3
SC
1525
1526 if ( mouseWin == this && !wxIsBusy() )
facd6764 1527 m_cursor.MacInstall() ;
facd6764 1528
902725ee 1529 return true ;
519cb848
SC
1530}
1531
facd6764
SC
1532#if wxUSE_MENUS
1533bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
1534{
1535 menu->SetInvokingWindow(this);
1536 menu->UpdateUI();
8b573fb8 1537
971562cb
VS
1538 if ( x == -1 && y == -1 )
1539 {
1540 wxPoint mouse = wxGetMousePosition();
898d9035
DS
1541 x = mouse.x;
1542 y = mouse.y;
971562cb
VS
1543 }
1544 else
1545 {
1546 ClientToScreen( &x , &y ) ;
1547 }
facd6764
SC
1548
1549 menu->MacBeforeDisplay( true ) ;
898d9035 1550 long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() , y, x, 0) ;
facd6764
SC
1551 if ( HiWord(menuResult) != 0 )
1552 {
1553 MenuCommand id ;
1554 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &id ) ;
1555 wxMenuItem* item = NULL ;
1556 wxMenu* realmenu ;
1557 item = menu->FindItem(id, &realmenu) ;
1558 if (item->IsCheckable())
facd6764 1559 item->Check( !item->IsChecked() ) ;
e15f0a5e 1560
facd6764
SC
1561 menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
1562 }
facd6764 1563
898d9035 1564 menu->MacAfterDisplay( true ) ;
8523a5f5 1565 menu->SetInvokingWindow( NULL );
facd6764 1566
902725ee 1567 return true;
facd6764
SC
1568}
1569#endif
51abe921
SC
1570
1571// ----------------------------------------------------------------------------
1572// tooltips
1573// ----------------------------------------------------------------------------
1574
1575#if wxUSE_TOOLTIPS
1576
e766c8a9 1577void wxWindowMac::DoSetToolTip(wxToolTip *tooltip)
51abe921
SC
1578{
1579 wxWindowBase::DoSetToolTip(tooltip);
6ed71b4f 1580
6264b550
RR
1581 if ( m_tooltip )
1582 m_tooltip->SetWindow(this);
51abe921
SC
1583}
1584
898d9035 1585#endif
51abe921 1586
902725ee 1587void wxWindowMac::MacInvalidateBorders()
6449b3a8
SC
1588{
1589 if ( m_peer == NULL )
1590 return ;
1591
1592 bool vis = MacIsReallyShown() ;
1593 if ( !vis )
1594 return ;
902725ee 1595
6449b3a8
SC
1596 int outerBorder = MacGetLeftBorderSize() ;
1597 if ( m_peer->NeedsFocusRect() && m_peer->HasFocus() )
1598 outerBorder += 4 ;
1599
1600 if ( outerBorder == 0 )
1601 return ;
902725ee
WS
1602
1603 // now we know that we have something to do at all
6449b3a8
SC
1604
1605 // as the borders are drawn on the parent we have to properly invalidate all these areas
902725ee 1606 RgnHandle updateInner = NewRgn() ,
6449b3a8
SC
1607 updateOuter = NewRgn() ;
1608
1609 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
1610 Rect rect ;
1611 m_peer->GetRect( &rect ) ;
898d9035 1612 RectRgn( updateInner, &rect ) ;
6449b3a8 1613 InsetRect( &rect , -outerBorder , -outerBorder ) ;
898d9035
DS
1614 RectRgn( updateOuter, &rect ) ;
1615 DiffRgn( updateOuter, updateInner , updateOuter ) ;
e15f0a5e 1616
6449b3a8 1617#ifdef __WXMAC_OSX__
1f1c8bd4 1618 GetParent()->m_peer->SetNeedsDisplay( updateOuter ) ;
6449b3a8
SC
1619#else
1620 WindowRef tlw = (WindowRef) MacGetTopLevelWindowRef() ;
1621 if ( tlw )
1622 InvalWindowRgn( tlw , updateOuter ) ;
1623#endif
e15f0a5e 1624
6449b3a8
SC
1625 DisposeRgn(updateOuter) ;
1626 DisposeRgn(updateInner) ;
e15f0a5e
DS
1627
1628#if 0
1629 RgnHandle updateInner = NewRgn() , updateOuter = NewRgn() ;
1630 RectRgn( updateInner , &rect ) ;
1631 InsetRect( &rect , -4 , -4 ) ;
1632 RectRgn( updateOuter , &rect ) ;
898d9035
DS
1633 DiffRgn( updateOuter , updateInner , updateOuter ) ;
1634 wxPoint parent(0, 0);
e15f0a5e
DS
1635 GetParent()->MacWindowToRootWindow( &parent.x , &parent.y ) ;
1636 parent -= GetParent()->GetClientAreaOrigin() ;
1637 OffsetRgn( updateOuter , -parent.x , -parent.y ) ;
1638 GetParent()->m_peer->SetNeedsDisplay( true , updateOuter ) ;
1639 DisposeRgn(updateOuter) ;
1640 DisposeRgn(updateInner) ;
1641#endif
1642
1643#if 0
6449b3a8
SC
1644 if ( m_peer )
1645 {
fbc1d11b
DS
1646 // deleting a window while it is shown invalidates
1647 // the region occupied by border or focus
6449b3a8
SC
1648
1649 if ( IsShown() && ( outerBorder > 0 ) )
1650 {
1651 // as the borders are drawn on the parent we have to properly invalidate all these areas
1652 RgnHandle updateInner = NewRgn() , updateOuter = NewRgn() , updateTotal = NewRgn() ;
1653
1654 Rect rect ;
1655
1656 m_peer->GetRect( &rect ) ;
1657 RectRgn( updateInner , &rect ) ;
1658 InsetRect( &rect , -outerBorder , -outerBorder ) ;
1659 RectRgn( updateOuter , &rect ) ;
1660 DiffRgn( updateOuter , updateInner ,updateOuter ) ;
898d9035 1661 wxPoint parent(0, 0);
6449b3a8
SC
1662 GetParent()->MacWindowToRootWindow( &parent.x , &parent.y ) ;
1663 parent -= GetParent()->GetClientAreaOrigin() ;
1664 OffsetRgn( updateOuter , -parent.x , -parent.y ) ;
1665 CopyRgn( updateOuter , updateTotal ) ;
1666
1667 GetParent()->m_peer->SetNeedsDisplay( true , updateTotal ) ;
1668 DisposeRgn(updateOuter) ;
1669 DisposeRgn(updateInner) ;
1670 DisposeRgn(updateTotal) ;
1671 }
1672 }
e15f0a5e
DS
1673#endif
1674
6449b3a8
SC
1675#if 0
1676 Rect r = wxMacGetBoundsForControl(this , wxPoint( actualX,actualY), wxSize( actualWidth, actualHeight ) , false ) ;
1677
1678 int outerBorder = MacGetLeftBorderSize() ;
1679 if ( m_peer->NeedsFocusRect() && m_peer->HasFocus() )
1680 outerBorder += 4 ;
1681
1682 if ( vis && ( outerBorder > 0 ) )
1683 {
1684 // as the borders are drawn on the parent we have to properly invalidate all these areas
1685 RgnHandle updateInner = NewRgn() , updateOuter = NewRgn() , updateTotal = NewRgn() ;
1686
1687 Rect rect ;
1688
1689 m_peer->GetRect( &rect ) ;
1690 RectRgn( updateInner , &rect ) ;
1691 InsetRect( &rect , -outerBorder , -outerBorder ) ;
1692 RectRgn( updateOuter , &rect ) ;
1693 DiffRgn( updateOuter , updateInner ,updateOuter ) ;
898d9035 1694
fbc1d11b 1695/*
898d9035 1696 wxPoint parent(0, 0);
6449b3a8
SC
1697#if TARGET_API_MAC_OSX
1698 // no offsetting needed when compositing
1699#else
1700 GetParent()->MacWindowToRootWindow( &parent.x , &parent.y ) ;
1701 parent -= GetParent()->GetClientAreaOrigin() ;
1702 OffsetRgn( updateOuter , -parent.x , -parent.y ) ;
1703#endif
fbc1d11b
DS
1704*/
1705
6449b3a8
SC
1706 CopyRgn( updateOuter , updateTotal ) ;
1707
1708 rect = r ;
1709 RectRgn( updateInner , &rect ) ;
1710 InsetRect( &rect , -outerBorder , -outerBorder ) ;
1711 RectRgn( updateOuter , &rect ) ;
898d9035 1712 DiffRgn( updateOuter , updateInner , updateOuter ) ;
fbc1d11b 1713
6449b3a8
SC
1714/*
1715 OffsetRgn( updateOuter , -parent.x , -parent.y ) ;
1716*/
fbc1d11b 1717
6449b3a8
SC
1718 UnionRgn( updateOuter , updateTotal , updateTotal ) ;
1719
1f1c8bd4 1720 GetParent()->m_peer->SetNeedsDisplay( updateTotal ) ;
8523a5f5
DS
1721 DisposeRgn( updateOuter ) ;
1722 DisposeRgn( updateInner ) ;
1723 DisposeRgn( updateTotal ) ;
6449b3a8
SC
1724 }
1725#endif
1726}
1727
e766c8a9 1728void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
51abe921 1729{
db7a550b 1730 // this is never called for a toplevel window, so we know we have a parent
facd6764 1731 int former_x , former_y , former_w, former_h ;
db7a550b
SC
1732
1733 // Get true coordinates of former position
facd6764
SC
1734 DoGetPosition( &former_x , &former_y ) ;
1735 DoGetSize( &former_w , &former_h ) ;
db7a550b
SC
1736
1737 wxWindow *parent = GetParent();
1738 if ( parent )
1739 {
1740 wxPoint pt(parent->GetClientAreaOrigin());
1741 former_x += pt.x ;
1742 former_y += pt.y ;
1743 }
6ed71b4f 1744
29ee02df
SC
1745 int actualWidth = width ;
1746 int actualHeight = height ;
e40298d5
JS
1747 int actualX = x;
1748 int actualY = y;
6ed71b4f 1749
14c9cbdb 1750 if ((m_minWidth != -1) && (actualWidth < m_minWidth))
6264b550 1751 actualWidth = m_minWidth;
14c9cbdb 1752 if ((m_minHeight != -1) && (actualHeight < m_minHeight))
6264b550 1753 actualHeight = m_minHeight;
14c9cbdb 1754 if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
6264b550 1755 actualWidth = m_maxWidth;
14c9cbdb 1756 if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
902725ee 1757 actualHeight = m_maxHeight;
6ed71b4f 1758
898d9035 1759 bool doMove = false, doResize = false ;
6ed71b4f 1760
6264b550 1761 if ( actualX != former_x || actualY != former_y )
6264b550 1762 doMove = true ;
e15f0a5e 1763
6264b550 1764 if ( actualWidth != former_w || actualHeight != former_h )
6264b550 1765 doResize = true ;
6ed71b4f 1766
6264b550
RR
1767 if ( doMove || doResize )
1768 {
902725ee 1769 // as the borders are drawn outside the native control, we adjust now
1f1c8bd4 1770
902725ee
WS
1771 wxRect bounds( wxPoint( actualX + MacGetLeftBorderSize() ,actualY + MacGetTopBorderSize() ),
1772 wxSize( actualWidth - (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1f1c8bd4
SC
1773 actualHeight - (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1774
1775 Rect r ;
1776 wxMacRectToNative( &bounds , &r ) ;
1777
1778 if ( !GetParent()->IsTopLevel() )
1f1c8bd4 1779 wxMacWindowToNative( GetParent() , &r ) ;
8b573fb8 1780
6449b3a8 1781 MacInvalidateBorders() ;
902725ee 1782
5c840e5b 1783 m_cachedClippedRectValid = false ;
8b573fb8 1784 m_peer->SetRect( &r ) ;
902725ee 1785
e905b636 1786 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
91ae6e3a 1787
6449b3a8
SC
1788 MacInvalidateBorders() ;
1789
6264b550
RR
1790 MacRepositionScrollBars() ;
1791 if ( doMove )
1792 {
898d9035 1793 wxPoint point(actualX, actualY);
6264b550
RR
1794 wxMoveEvent event(point, m_windowId);
1795 event.SetEventObject(this);
1796 GetEventHandler()->ProcessEvent(event) ;
1797 }
e15f0a5e 1798
6264b550
RR
1799 if ( doResize )
1800 {
e40298d5 1801 MacRepositionScrollBars() ;
facd6764 1802 wxSize size(actualWidth, actualHeight);
e40298d5
JS
1803 wxSizeEvent event(size, m_windowId);
1804 event.SetEventObject(this);
1805 GetEventHandler()->ProcessEvent(event);
6264b550
RR
1806 }
1807 }
954fc50b
SC
1808}
1809
facd6764
SC
1810wxSize wxWindowMac::DoGetBestSize() const
1811{
eb69d46e
SC
1812 if ( m_macIsUserPane || IsTopLevel() )
1813 return wxWindowBase::DoGetBestSize() ;
8b573fb8 1814
facd6764 1815 Rect bestsize = { 0 , 0 , 0 , 0 } ;
facd6764 1816 int bestWidth, bestHeight ;
facd6764 1817
898d9035 1818 m_peer->GetBestRect( &bestsize ) ;
facd6764
SC
1819 if ( EmptyRect( &bestsize ) )
1820 {
898d9035
DS
1821 bestsize.left =
1822 bestsize.top = 0 ;
1823 bestsize.right =
facd6764 1824 bestsize.bottom = 16 ;
898d9035 1825
facd6764
SC
1826 if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
1827 {
1828 bestsize.bottom = 16 ;
1829 }
902725ee 1830#if wxUSE_SPINBTN
facd6764
SC
1831 else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) )
1832 {
8b573fb8 1833 bestsize.bottom = 24 ;
facd6764 1834 }
898d9035 1835#endif
facd6764
SC
1836 else
1837 {
8b573fb8 1838 // return wxWindowBase::DoGetBestSize() ;
facd6764
SC
1839 }
1840 }
1841
1842 bestWidth = bestsize.right - bestsize.left ;
1843 bestHeight = bestsize.bottom - bestsize.top ;
1844 if ( bestHeight < 10 )
1845 bestHeight = 13 ;
8b573fb8 1846
facd6764
SC
1847 return wxSize(bestWidth, bestHeight);
1848}
1849
954fc50b
SC
1850// set the size of the window: if the dimensions are positive, just use them,
1851// but if any of them is equal to -1, it means that we must find the value for
1852// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1853// which case -1 is a valid value for x and y)
1854//
1855// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1856// the width/height to best suit our contents, otherwise we reuse the current
1857// width/height
1858void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags)
1859{
1860 // get the current size and position...
1861 int currentX, currentY;
898d9035 1862 int currentW, currentH;
6ed71b4f 1863
898d9035 1864 GetPosition(&currentX, &currentY);
954fc50b 1865 GetSize(&currentW, &currentH);
6ed71b4f 1866
954fc50b
SC
1867 // ... and don't do anything (avoiding flicker) if it's already ok
1868 if ( x == currentX && y == currentY &&
769ac869 1869 width == currentW && height == currentH && ( height != -1 && width != -1 ) )
954fc50b 1870 {
e15f0a5e 1871 // TODO: REMOVE
6264b550 1872 MacRepositionScrollBars() ; // we might have a real position shift
898d9035 1873
954fc50b
SC
1874 return;
1875 }
6ed71b4f 1876
3dee36ae 1877 if ( x == wxDefaultCoord && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
954fc50b 1878 x = currentX;
3dee36ae 1879 if ( y == wxDefaultCoord && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
954fc50b 1880 y = currentY;
6ed71b4f 1881
954fc50b 1882 AdjustForParentClientOrigin(x, y, sizeFlags);
6ed71b4f 1883
3dee36ae
WS
1884 wxSize size = wxDefaultSize;
1885 if ( width == wxDefaultCoord )
954fc50b
SC
1886 {
1887 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
1888 {
1889 size = DoGetBestSize();
1890 width = size.x;
1891 }
1892 else
1893 {
1894 // just take the current one
1895 width = currentW;
1896 }
1897 }
6ed71b4f 1898
3dee36ae 1899 if ( height == wxDefaultCoord )
954fc50b
SC
1900 {
1901 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
1902 {
3dee36ae 1903 if ( size.x == wxDefaultCoord )
954fc50b 1904 size = DoGetBestSize();
898d9035 1905 // else: already called DoGetBestSize() above
6ed71b4f 1906
954fc50b
SC
1907 height = size.y;
1908 }
1909 else
1910 {
1911 // just take the current one
1912 height = currentH;
1913 }
1914 }
6ed71b4f 1915
954fc50b 1916 DoMoveWindow(x, y, width, height);
e9576ca5 1917}
519cb848 1918
e766c8a9 1919wxPoint wxWindowMac::GetClientAreaOrigin() const
e9576ca5 1920{
facd6764
SC
1921 RgnHandle rgn = NewRgn() ;
1922 Rect content ;
04d4e684 1923 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
21638402
SC
1924 {
1925 GetRegionBounds( rgn , &content ) ;
1926 }
1927 else
1928 {
898d9035
DS
1929 content.left =
1930 content.top = 0 ;
21638402 1931 }
898d9035 1932
facd6764 1933 DisposeRgn( rgn ) ;
e15f0a5e
DS
1934
1935 return wxPoint( content.left + MacGetLeftBorderSize() , content.top + MacGetTopBorderSize() );
facd6764
SC
1936}
1937
1938void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight)
1939{
3dee36ae 1940 if ( clientheight != wxDefaultCoord || clientheight != wxDefaultCoord )
facd6764
SC
1941 {
1942 int currentclientwidth , currentclientheight ;
1943 int currentwidth , currentheight ;
1944
1945 GetClientSize( &currentclientwidth , &currentclientheight ) ;
1946 GetSize( &currentwidth , &currentheight ) ;
1947
3dee36ae 1948 DoSetSize( wxDefaultCoord , wxDefaultCoord , currentwidth + clientwidth - currentclientwidth ,
facd6764
SC
1949 currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ;
1950 }
e9576ca5
SC
1951}
1952
fb5246be 1953void wxWindowMac::SetLabel(const wxString& title)
e9576ca5 1954{
facd6764
SC
1955 m_label = wxStripMenuCodes(title) ;
1956
21fd5529 1957 if ( m_peer && m_peer->Ok() )
fb5246be 1958 m_peer->SetLabel( m_label ) ;
e15f0a5e 1959
facd6764 1960 Refresh() ;
519cb848
SC
1961}
1962
fb5246be 1963wxString wxWindowMac::GetLabel() const
519cb848 1964{
ed60b502 1965 return m_label ;
519cb848
SC
1966}
1967
8ab50549
SC
1968bool wxWindowMac::Show(bool show)
1969{
542f604f 1970 bool former = MacIsReallyShown() ;
8ab50549 1971 if ( !wxWindowBase::Show(show) )
902725ee 1972 return false;
8b573fb8 1973
8ab50549 1974 // TODO use visibilityChanged Carbon Event for OSX
2c899c20 1975 if ( m_peer )
2c899c20 1976 m_peer->SetVisibility( show , true ) ;
e15f0a5e 1977
542f604f
SC
1978 if ( former != MacIsReallyShown() )
1979 MacPropagateVisibilityChanged() ;
898d9035
DS
1980
1981#if 1
1982 // patch from Sailesh Agrawal
1983 wxShowEvent eventShow(GetId(), show);
1984 eventShow.SetEventObject(this);
1985 GetEventHandler()->ProcessEvent(eventShow);
1986#endif
1987
902725ee 1988 return true;
8ab50549
SC
1989}
1990
1991bool wxWindowMac::Enable(bool enable)
1992{
21fd5529 1993 wxASSERT( m_peer->Ok() ) ;
542f604f 1994 bool former = MacIsReallyEnabled() ;
8ab50549 1995 if ( !wxWindowBase::Enable(enable) )
902725ee 1996 return false;
8ab50549 1997
5ca0d812 1998 m_peer->Enable( enable ) ;
8ab50549
SC
1999
2000 if ( former != MacIsReallyEnabled() )
2001 MacPropagateEnabledStateChanged() ;
e15f0a5e 2002
902725ee 2003 return true;
8ab50549
SC
2004}
2005
8b573fb8 2006//
8ab50549
SC
2007// status change propagations (will be not necessary for OSX later )
2008//
2009
facd6764
SC
2010void wxWindowMac::MacPropagateVisibilityChanged()
2011{
73fe67bd 2012#if !TARGET_API_MAC_OSX
facd6764 2013 MacVisibilityChanged() ;
8b573fb8 2014
e15f0a5e 2015 wxWindowMac *child;
71f2fb52 2016 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
facd6764
SC
2017 while ( node )
2018 {
e15f0a5e 2019 child = node->GetData();
facd6764 2020 if ( child->IsShown() )
e15f0a5e
DS
2021 child->MacPropagateVisibilityChanged() ;
2022
facd6764
SC
2023 node = node->GetNext();
2024 }
73fe67bd 2025#endif
facd6764
SC
2026}
2027
e15f0a5e 2028void wxWindowMac::MacPropagateEnabledStateChanged()
e9576ca5 2029{
73fe67bd 2030#if !TARGET_API_MAC_OSX
8ab50549 2031 MacEnabledStateChanged() ;
8b573fb8 2032
e15f0a5e 2033 wxWindowMac *child;
71f2fb52 2034 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
8ab50549
SC
2035 while ( node )
2036 {
e15f0a5e 2037 child = node->GetData();
8ab50549
SC
2038 if ( child->IsEnabled() )
2039 child->MacPropagateEnabledStateChanged() ;
e15f0a5e 2040
8ab50549
SC
2041 node = node->GetNext();
2042 }
73fe67bd 2043#endif
8ab50549
SC
2044}
2045
e15f0a5e 2046void wxWindowMac::MacPropagateHiliteChanged()
8ab50549 2047{
73fe67bd 2048#if !TARGET_API_MAC_OSX
8ab50549 2049 MacHiliteChanged() ;
8b573fb8 2050
e15f0a5e 2051 wxWindowMac *child;
71f2fb52 2052 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
8ab50549
SC
2053 while ( node )
2054 {
e15f0a5e 2055 child = node->GetData();
898d9035 2056 if (child /* && child->IsEnabled() */)
8ab50549 2057 child->MacPropagateHiliteChanged() ;
e15f0a5e 2058
8ab50549
SC
2059 node = node->GetNext();
2060 }
73fe67bd 2061#endif
8ab50549
SC
2062}
2063
2064//
2065// status change notifications
8b573fb8 2066//
8ab50549 2067
8b573fb8 2068void wxWindowMac::MacVisibilityChanged()
8ab50549
SC
2069{
2070}
2071
8b573fb8 2072void wxWindowMac::MacHiliteChanged()
8ab50549
SC
2073{
2074}
2075
8b573fb8 2076void wxWindowMac::MacEnabledStateChanged()
8ab50549 2077{
facd6764 2078}
e7549107 2079
8ab50549
SC
2080//
2081// status queries on the inherited window's state
2082//
2083
8b573fb8 2084bool wxWindowMac::MacIsReallyShown()
facd6764
SC
2085{
2086 // only under OSX the visibility of the TLW is taken into account
66ffb23b
SC
2087 if ( m_isBeingDeleted )
2088 return false ;
902725ee 2089
facd6764 2090#if TARGET_API_MAC_OSX
aa522e33
SC
2091 if ( m_peer && m_peer->Ok() )
2092 return m_peer->IsVisible();
2093#endif
e15f0a5e 2094
facd6764 2095 wxWindow* win = this ;
898d9035 2096 while ( win->IsShown() )
facd6764
SC
2097 {
2098 if ( win->IsTopLevel() )
2099 return true ;
8b573fb8 2100
facd6764
SC
2101 win = win->GetParent() ;
2102 if ( win == NULL )
2103 return true ;
e15f0a5e 2104 }
8b573fb8 2105
facd6764 2106 return false ;
facd6764 2107}
4241baae 2108
8b573fb8 2109bool wxWindowMac::MacIsReallyEnabled()
facd6764 2110{
5ca0d812 2111 return m_peer->IsEnabled() ;
facd6764
SC
2112}
2113
8b573fb8 2114bool wxWindowMac::MacIsReallyHilited()
c809f3be 2115{
5ca0d812 2116 return m_peer->IsActive();
c809f3be
SC
2117}
2118
8b573fb8 2119void wxWindowMac::MacFlashInvalidAreas()
002c9672
SC
2120{
2121#if TARGET_API_MAC_OSX
2122 HIViewFlashDirtyArea( (WindowRef) MacGetTopLevelWindowRef() ) ;
2123#endif
2124}
2125
e766c8a9 2126int wxWindowMac::GetCharHeight() const
e9576ca5 2127{
e15f0a5e
DS
2128 wxClientDC dc( (wxWindowMac*)this ) ;
2129
6264b550 2130 return dc.GetCharHeight() ;
e9576ca5
SC
2131}
2132
e766c8a9 2133int wxWindowMac::GetCharWidth() const
e9576ca5 2134{
e15f0a5e
DS
2135 wxClientDC dc( (wxWindowMac*)this ) ;
2136
6264b550 2137 return dc.GetCharWidth() ;
e9576ca5
SC
2138}
2139
e766c8a9 2140void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
e7549107 2141 int *descent, int *externalLeading, const wxFont *theFont ) const
e9576ca5 2142{
e7549107
SC
2143 const wxFont *fontToUse = theFont;
2144 if ( !fontToUse )
2145 fontToUse = &m_font;
14c9cbdb 2146
e766c8a9 2147 wxClientDC dc( (wxWindowMac*) this ) ;
7c74e7fe 2148 long lx,ly,ld,le ;
5fde6fcc 2149 dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ;
2f1ae414 2150 if ( externalLeading )
6264b550 2151 *externalLeading = le ;
2f1ae414 2152 if ( descent )
6264b550 2153 *descent = ld ;
2f1ae414 2154 if ( x )
6264b550 2155 *x = lx ;
2f1ae414 2156 if ( y )
6264b550 2157 *y = ly ;
e9576ca5
SC
2158}
2159
0a67a93b 2160/*
14c9cbdb 2161 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
1c310985
SC
2162 * we always intersect with the entire window, not only with the client area
2163 */
14c9cbdb 2164
e766c8a9 2165void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect)
e9576ca5 2166{
065ab451
SC
2167 if ( m_peer == NULL )
2168 return ;
8b573fb8 2169
1f1c8bd4
SC
2170 if ( !MacIsReallyShown() )
2171 return ;
789ae0cf 2172
1f1c8bd4 2173 if ( rect )
1e8cde71 2174 {
1f1c8bd4 2175 Rect r ;
898d9035 2176
1f1c8bd4
SC
2177 wxMacRectToNative( rect , &r ) ;
2178 m_peer->SetNeedsDisplay( &r ) ;
facd6764 2179 }
1f1c8bd4 2180 else
9a456218 2181 {
1f1c8bd4 2182 m_peer->SetNeedsDisplay() ;
e9576ca5 2183 }
facd6764
SC
2184}
2185
79392158
SC
2186void wxWindowMac::Freeze()
2187{
2188#if TARGET_API_MAC_OSX
2189 if ( !m_frozenness++ )
2190 {
52ef5c3c
RD
2191 if ( m_peer && m_peer->Ok() )
2192 m_peer->SetDrawingEnabled( false ) ;
79392158
SC
2193 }
2194#endif
2195}
2196
2197void wxWindowMac::Thaw()
2198{
2199#if TARGET_API_MAC_OSX
898d9035 2200 wxASSERT_MSG( m_frozenness > 0, wxT("Thaw() without matching Freeze()") );
79392158
SC
2201
2202 if ( !--m_frozenness )
2203 {
52ef5c3c
RD
2204 if ( m_peer && m_peer->Ok() )
2205 {
2206 m_peer->SetDrawingEnabled( true ) ;
2207 m_peer->InvalidateWithChildren() ;
2208 }
79392158
SC
2209 }
2210#endif
2211}
2212
e766c8a9 2213wxWindowMac *wxGetActiveWindow()
e9576ca5 2214{
519cb848 2215 // actually this is a windows-only concept
e9576ca5
SC
2216 return NULL;
2217}
2218
e9576ca5 2219// Coordinates relative to the window
898d9035 2220void wxWindowMac::WarpPointer(int x_pos, int y_pos)
e9576ca5 2221{
e40298d5 2222 // We really don't move the mouse programmatically under Mac.
e9576ca5
SC
2223}
2224
facd6764 2225void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
e9576ca5 2226{
3dee36ae
WS
2227 if ( MacGetTopLevelWindow() == NULL )
2228 return ;
898d9035 2229
be346c26 2230#if TARGET_API_MAC_OSX
898d9035 2231 if ( MacGetTopLevelWindow()->MacUsesCompositing() && (!m_macBackgroundBrush.Ok() || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT ) )
94abc21f 2232 {
facd6764 2233 event.Skip() ;
94abc21f
SC
2234 }
2235 else
be346c26 2236#endif
7ebf5540 2237 {
8b573fb8 2238 event.GetDC()->Clear() ;
7ebf5540 2239 }
1c310985
SC
2240}
2241
2242void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
2243{
af6b7b80 2244 event.Skip() ;
e9576ca5
SC
2245}
2246
e766c8a9 2247int wxWindowMac::GetScrollPos(int orient) const
e9576ca5 2248{
1c310985
SC
2249 if ( orient == wxHORIZONTAL )
2250 {
2251 if ( m_hScrollBar )
2252 return m_hScrollBar->GetThumbPosition() ;
2253 }
2254 else
2255 {
2256 if ( m_vScrollBar )
2257 return m_vScrollBar->GetThumbPosition() ;
2258 }
e15f0a5e 2259
e9576ca5
SC
2260 return 0;
2261}
2262
2263// This now returns the whole range, not just the number
2264// of positions that we can scroll.
e766c8a9 2265int wxWindowMac::GetScrollRange(int orient) const
e9576ca5 2266{
1c310985
SC
2267 if ( orient == wxHORIZONTAL )
2268 {
2269 if ( m_hScrollBar )
2270 return m_hScrollBar->GetRange() ;
2271 }
2272 else
2273 {
2274 if ( m_vScrollBar )
2275 return m_vScrollBar->GetRange() ;
2276 }
e15f0a5e 2277
e9576ca5
SC
2278 return 0;
2279}
2280
e766c8a9 2281int wxWindowMac::GetScrollThumb(int orient) const
e9576ca5 2282{
1c310985
SC
2283 if ( orient == wxHORIZONTAL )
2284 {
2285 if ( m_hScrollBar )
2286 return m_hScrollBar->GetThumbSize() ;
2287 }
2288 else
2289 {
2290 if ( m_vScrollBar )
2291 return m_vScrollBar->GetThumbSize() ;
2292 }
e15f0a5e 2293
e9576ca5
SC
2294 return 0;
2295}
2296
e766c8a9 2297void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh)
e9576ca5 2298{
1c310985 2299 if ( orient == wxHORIZONTAL )
6264b550 2300 {
1c310985
SC
2301 if ( m_hScrollBar )
2302 m_hScrollBar->SetThumbPosition( pos ) ;
6264b550
RR
2303 }
2304 else
2305 {
1c310985
SC
2306 if ( m_vScrollBar )
2307 m_vScrollBar->SetThumbPosition( pos ) ;
6264b550 2308 }
2f1ae414
SC
2309}
2310
c79aad8b
SC
2311//
2312// we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2313// our own window origin is at leftOrigin/rightOrigin
2314//
2315
2316void wxWindowMac::MacPaintBorders( int leftOrigin , int rightOrigin )
2f1ae414 2317{
e15f0a5e 2318 if ( IsTopLevel() )
6264b550 2319 return ;
8b573fb8 2320
fd926bcc 2321 Rect rect ;
c79aad8b 2322 bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ;
e15f0a5e 2323 bool hasBothScrollbars = (m_hScrollBar && m_hScrollBar->IsShown()) && (m_vScrollBar && m_vScrollBar->IsShown()) ;
c79aad8b 2324
8b573fb8 2325 m_peer->GetRect( &rect ) ;
8f39b6c4
SC
2326 // back to the surrounding frame rectangle
2327 InsetRect( &rect, -1 , -1 ) ;
fd926bcc 2328
c79aad8b 2329#if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
e15f0a5e 2330 if ( UMAGetSystemVersion() >= 0x1030 )
c79aad8b 2331 {
8f39b6c4
SC
2332 CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left ,
2333 rect.bottom - rect.top ) ;
2334
c79aad8b
SC
2335 HIThemeFrameDrawInfo info ;
2336 memset( &info, 0 , sizeof( info ) ) ;
902725ee 2337
c79aad8b
SC
2338 info.version = 0 ;
2339 info.kind = 0 ;
2340 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
2341 info.isFocused = hasFocus ;
c79aad8b
SC
2342
2343 CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ;
2344 wxASSERT( cgContext ) ;
902725ee 2345
e15f0a5e 2346 if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
c79aad8b 2347 {
c79aad8b 2348 info.kind = kHIThemeFrameTextFieldSquare ;
8f39b6c4 2349 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
c79aad8b 2350 }
e15f0a5e 2351 else if ( HasFlag(wxSIMPLE_BORDER) )
c79aad8b 2352 {
c79aad8b 2353 info.kind = kHIThemeFrameListBox ;
c79aad8b
SC
2354 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
2355 }
2356 else if ( hasFocus )
2357 {
c79aad8b
SC
2358 HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ;
2359 }
902725ee 2360
c79aad8b
SC
2361 m_peer->GetRect( &rect ) ;
2362 if ( hasBothScrollbars )
2363 {
c79aad8b 2364 int size = m_hScrollBar->GetWindowVariant() == wxWINDOW_VARIANT_NORMAL ? 16 : 12 ;
8f39b6c4
SC
2365 CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
2366 CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
902725ee 2367 HIThemeGrowBoxDrawInfo info ;
e15f0a5e 2368 memset( &info, 0, sizeof(info) ) ;
c79aad8b
SC
2369 info.version = 0 ;
2370 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
2371 info.kind = kHIThemeGrowBoxKindNone ;
2372 info.size = kHIThemeGrowBoxSizeNormal ;
2373 info.direction = kThemeGrowRight | kThemeGrowDown ;
2374 HIThemeDrawGrowBox( &cgpoint , &info , cgContext , kHIThemeOrientationNormal ) ;
2375 }
2376 }
2377 else
2378#endif
fd926bcc
SC
2379 {
2380 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
e15f0a5e 2381 if ( top )
fd926bcc 2382 {
e15f0a5e 2383 wxPoint pt(0, 0) ;
fd926bcc 2384 wxMacControl::Convert( &pt , GetParent()->m_peer , top->m_peer ) ;
1f1c8bd4 2385 OffsetRect( &rect , pt.x , pt.y ) ;
fd926bcc 2386 }
8b573fb8 2387
e15f0a5e
DS
2388 if ( HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
2389 DrawThemeEditTextFrame( &rect, IsEnabled() ? kThemeStateActive : kThemeStateInactive ) ;
2390 else if ( HasFlag(wxSIMPLE_BORDER) )
2391 DrawThemeListBoxFrame( &rect, IsEnabled() ? kThemeStateActive : kThemeStateInactive ) ;
902725ee 2392
c79aad8b 2393 if ( hasFocus )
8f39b6c4 2394 DrawThemeFocusRect( &rect , true ) ;
8f39b6c4 2395
c79aad8b
SC
2396 if ( hasBothScrollbars )
2397 {
902725ee 2398 // GetThemeStandaloneGrowBoxBounds
e15f0a5e 2399 // DrawThemeStandaloneNoGrowBox
c79aad8b 2400 }
eec462f8 2401 }
8208e181
SC
2402}
2403
abda5788
SC
2404void wxWindowMac::RemoveChild( wxWindowBase *child )
2405{
2406 if ( child == m_hScrollBar )
2407 m_hScrollBar = NULL ;
2408 if ( child == m_vScrollBar )
2409 m_vScrollBar = NULL ;
14c9cbdb 2410
abda5788
SC
2411 wxWindowBase::RemoveChild( child ) ;
2412}
2413
e9576ca5 2414// New function that will replace some of the above.
e766c8a9 2415void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible,
e9576ca5
SC
2416 int range, bool refresh)
2417{
e40298d5
JS
2418 if ( orient == wxHORIZONTAL )
2419 {
2420 if ( m_hScrollBar )
6264b550 2421 {
e40298d5 2422 if ( range == 0 || thumbVisible >= range )
6264b550 2423 {
e40298d5
JS
2424 if ( m_hScrollBar->IsShown() )
2425 m_hScrollBar->Show(false) ;
2426 }
2427 else
2428 {
2429 if ( !m_hScrollBar->IsShown() )
2430 m_hScrollBar->Show(true) ;
6264b550 2431 }
e15f0a5e 2432
11ca2edf 2433 m_hScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
6264b550 2434 }
e40298d5
JS
2435 }
2436 else
2437 {
2438 if ( m_vScrollBar )
6264b550 2439 {
e40298d5 2440 if ( range == 0 || thumbVisible >= range )
6264b550 2441 {
e40298d5
JS
2442 if ( m_vScrollBar->IsShown() )
2443 m_vScrollBar->Show(false) ;
2444 }
2445 else
2446 {
2447 if ( !m_vScrollBar->IsShown() )
2448 m_vScrollBar->Show(true) ;
6264b550 2449 }
e15f0a5e 2450
11ca2edf 2451 m_vScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
6264b550 2452 }
e40298d5 2453 }
e15f0a5e 2454
e40298d5 2455 MacRepositionScrollBars() ;
e9576ca5
SC
2456}
2457
2458// Does a physical scroll
e766c8a9 2459void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
e9576ca5 2460{
898d9035 2461 if ( dx == 0 && dy == 0 )
ba87f54c 2462 return ;
8b573fb8 2463
3dee36ae
WS
2464 int width , height ;
2465 GetClientSize( &width , &height ) ;
e15f0a5e 2466
adb8a71b 2467#if TARGET_API_MAC_OSX
e15f0a5e 2468 if ( true /* m_peer->IsCompositing() */ )
902725ee 2469 {
002c9672 2470 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
8b573fb8 2471 // area is scrolled, this does not occur if width and height are 2 pixels less,
002c9672 2472 // TODO write optimal workaround
898d9035 2473 wxRect scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ;
8b573fb8 2474 if ( rect )
5ca0d812 2475 scrollrect.Intersect( *rect ) ;
e15f0a5e 2476
5ca0d812 2477 if ( m_peer->GetNeedsDisplay() )
002c9672
SC
2478 {
2479 // becuase HIViewScrollRect does not scroll the already invalidated area we have two options
2480 // either immediate redraw or full invalidate
2481#if 1
2482 // is the better overall solution, as it does not slow down scrolling
1f1c8bd4 2483 m_peer->SetNeedsDisplay() ;
002c9672 2484#else
8b573fb8 2485 // this would be the preferred version for fast drawing controls
92346151 2486
f474cc8c 2487#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
e15f0a5e 2488 if ( UMAGetSystemVersion() >= 0x1030 && m_peer->IsCompositing() )
42ef83fa 2489 HIViewRender(m_peer->GetControlRef()) ;
f474cc8c
SC
2490 else
2491#endif
2492 Update() ;
002c9672
SC
2493#endif
2494 }
e15f0a5e 2495
84e5d27d
SC
2496 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2497 scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
898d9035 2498 m_peer->ScrollRect( &scrollrect , dx , dy ) ;
92346151
SC
2499
2500 // becuase HIViewScrollRect does not scroll the already invalidated area we have two options
2501 // either immediate redraw or full invalidate
2502#if 0
2503 // is the better overall solution, as it does not slow down scrolling
2504 m_peer->SetNeedsDisplay() ;
adb8a71b 2505#else
902725ee 2506 // this would be the preferred version for fast drawing controls
92346151 2507
f474cc8c 2508#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
e15f0a5e 2509 if ( UMAGetSystemVersion() >= 0x1030 && m_peer->IsCompositing() )
f474cc8c
SC
2510 HIViewRender(m_peer->GetControlRef()) ;
2511 else
2512#endif
902725ee 2513 Update() ;
92346151 2514#endif
902725ee
WS
2515 }
2516 else
92346151 2517#endif
902725ee 2518 {
facd6764 2519 wxPoint pos;
898d9035
DS
2520 pos.x =
2521 pos.y = 0;
430e1eed 2522
facd6764 2523 Rect scrollrect;
6264b550 2524 RgnHandle updateRgn = NewRgn() ;
430e1eed 2525
3dee36ae 2526 {
430e1eed
SC
2527 wxClientDC dc(this) ;
2528 wxMacPortSetter helper(&dc) ;
8b573fb8 2529
92346151
SC
2530 m_peer->GetRectInWindowCoords( &scrollrect ) ;
2531 //scrollrect.top += MacGetTopBorderSize() ;
2532 //scrollrect.left += MacGetLeftBorderSize() ;
430e1eed
SC
2533 scrollrect.bottom = scrollrect.top + height ;
2534 scrollrect.right = scrollrect.left + width ;
8b573fb8 2535
430e1eed
SC
2536 if ( rect )
2537 {
2538 Rect r = { dc.YLOG2DEVMAC(rect->y) , dc.XLOG2DEVMAC(rect->x) , dc.YLOG2DEVMAC(rect->y + rect->height) ,
2539 dc.XLOG2DEVMAC(rect->x + rect->width) } ;
2540 SectRect( &scrollrect , &r , &scrollrect ) ;
2541 }
e15f0a5e 2542
430e1eed 2543 ScrollRect( &scrollrect , dx , dy , updateRgn ) ;
20b69855
SC
2544
2545 // now scroll the former update region as well and add the new update region
20b69855
SC
2546 WindowRef rootWindow = (WindowRef) MacGetTopLevelWindowRef() ;
2547 RgnHandle formerUpdateRgn = NewRgn() ;
2548 RgnHandle scrollRgn = NewRgn() ;
2549 RectRgn( scrollRgn , &scrollrect ) ;
2550 GetWindowUpdateRgn( rootWindow , formerUpdateRgn ) ;
898d9035 2551 Point pt = {0, 0} ;
20b69855
SC
2552 LocalToGlobal( &pt ) ;
2553 OffsetRgn( formerUpdateRgn , -pt.h , -pt.v ) ;
2554 SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
e15f0a5e 2555
20b69855
SC
2556 if ( !EmptyRgn( formerUpdateRgn ) )
2557 {
2558 MacOffsetRgn( formerUpdateRgn , dx , dy ) ;
2559 SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
898d9035 2560 InvalWindowRgn( rootWindow, formerUpdateRgn ) ;
20b69855 2561 }
e15f0a5e 2562
898d9035 2563 InvalWindowRgn(rootWindow, updateRgn ) ;
20b69855
SC
2564 DisposeRgn( updateRgn ) ;
2565 DisposeRgn( formerUpdateRgn ) ;
2566 DisposeRgn( scrollRgn ) ;
ba87f54c 2567 }
e15f0a5e 2568
92346151 2569 Update() ;
6264b550 2570 }
6ed71b4f 2571
e15f0a5e
DS
2572 wxWindowMac *child;
2573 int x, y, w, h;
71f2fb52 2574 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
6264b550 2575 {
e15f0a5e
DS
2576 child = node->GetData();
2577 if (child == NULL)
2578 continue;
2579 if (child == m_vScrollBar)
2580 continue;
2581 if (child == m_hScrollBar)
2582 continue;
2583 if (child->IsTopLevel())
2584 continue;
6ed71b4f 2585
6264b550 2586 child->GetPosition( &x, &y );
6264b550 2587 child->GetSize( &w, &h );
00f55394
SC
2588 if (rect)
2589 {
e15f0a5e
DS
2590 wxRect rc( x, y, w, h );
2591 if (rect->Intersects( rc ))
2592 child->SetSize( x + dx, y + dy, w, h );
00f55394
SC
2593 }
2594 else
2595 {
e15f0a5e 2596 child->SetSize( x + dx, y + dy, w, h );
8b573fb8 2597 }
6264b550 2598 }
e9576ca5
SC
2599}
2600
e15f0a5e 2601void wxWindowMac::MacOnScroll( wxScrollEvent &event )
7c74e7fe 2602{
687706f5 2603 if ( event.GetEventObject() == m_vScrollBar || event.GetEventObject() == m_hScrollBar )
6264b550
RR
2604 {
2605 wxScrollWinEvent wevent;
2606 wevent.SetPosition(event.GetPosition());
2607 wevent.SetOrientation(event.GetOrientation());
687706f5
KH
2608 wevent.SetEventObject(this);
2609
2610 if (event.GetEventType() == wxEVT_SCROLL_TOP)
2611 wevent.SetEventType( wxEVT_SCROLLWIN_TOP );
2612 else if (event.GetEventType() == wxEVT_SCROLL_BOTTOM)
2613 wevent.SetEventType( wxEVT_SCROLLWIN_BOTTOM );
2614 else if (event.GetEventType() == wxEVT_SCROLL_LINEUP)
2615 wevent.SetEventType( wxEVT_SCROLLWIN_LINEUP );
2616 else if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN)
2617 wevent.SetEventType( wxEVT_SCROLLWIN_LINEDOWN );
2618 else if (event.GetEventType() == wxEVT_SCROLL_PAGEUP)
2619 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEUP );
2620 else if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN)
2621 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN );
2622 else if (event.GetEventType() == wxEVT_SCROLL_THUMBTRACK)
2623 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK );
2624 else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE)
2625 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE );
6ed71b4f
VZ
2626
2627 GetEventHandler()->ProcessEvent(wevent);
7c74e7fe
SC
2628 }
2629}
2630
e9576ca5 2631// Get the window with the focus
0fe02759 2632wxWindowMac *wxWindowBase::DoFindFocus()
e9576ca5 2633{
f1d527c1
SC
2634 ControlRef control ;
2635 GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
2636 return wxFindControlFromMacControl( control ) ;
519cb848
SC
2637}
2638
e15f0a5e 2639void wxWindowMac::OnSetFocus( wxFocusEvent& event )
7810c95b
SC
2640{
2641 // panel wants to track the window which was the last to have focus in it,
2642 // so we want to set ourselves as the window which last had focus
2643 //
dac390e9 2644 // notice that it's also important to do it upwards the tree because
7810c95b
SC
2645 // otherwise when the top level panel gets focus, it won't set it back to
2646 // us, but to some other sibling
6ed71b4f 2647
dac390e9 2648 // CS: don't know if this is still needed:
c1fb8167
SC
2649 //wxChildFocusEvent eventFocus(this);
2650 //(void)GetEventHandler()->ProcessEvent(eventFocus);
7810c95b 2651
5ca0d812
SC
2652 if ( MacGetTopLevelWindow() && m_peer->NeedsFocusRect() )
2653 {
dac390e9
DS
2654#if wxMAC_USE_CORE_GRAPHICS
2655 GetParent()->Refresh() ;
2656#else
788e118f 2657 wxMacWindowStateSaver sv( this ) ;
6449b3a8 2658 Rect rect ;
dac390e9 2659
6449b3a8 2660 m_peer->GetRect( &rect ) ;
8f39b6c4
SC
2661