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