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