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