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