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