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