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