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