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