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