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