]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/window.cpp
don't send incorrect char events when entering Unicode characters (patch 1640443)
[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 bool wxWindowMac::Enable(bool enable)
2143 {
2144 wxASSERT( m_peer->Ok() ) ;
2145 bool former = MacIsReallyEnabled() ;
2146 if ( !wxWindowBase::Enable(enable) )
2147 return false;
2148
2149 m_peer->Enable( enable ) ;
2150
2151 if ( former != MacIsReallyEnabled() )
2152 MacPropagateEnabledStateChanged() ;
2153
2154 return true;
2155 }
2156
2157 //
2158 // status change propagations (will be not necessary for OSX later )
2159 //
2160
2161 void wxWindowMac::MacPropagateVisibilityChanged()
2162 {
2163 #if !TARGET_API_MAC_OSX
2164 MacVisibilityChanged() ;
2165
2166 wxWindowMac *child;
2167 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
2168 while ( node )
2169 {
2170 child = node->GetData();
2171 if ( child->IsShown() )
2172 child->MacPropagateVisibilityChanged() ;
2173
2174 node = node->GetNext();
2175 }
2176 #endif
2177 }
2178
2179 void wxWindowMac::MacPropagateEnabledStateChanged()
2180 {
2181 #if !TARGET_API_MAC_OSX
2182 MacEnabledStateChanged() ;
2183
2184 wxWindowMac *child;
2185 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
2186 while ( node )
2187 {
2188 child = node->GetData();
2189 if ( child->IsEnabled() )
2190 child->MacPropagateEnabledStateChanged() ;
2191
2192 node = node->GetNext();
2193 }
2194 #endif
2195 }
2196
2197 void wxWindowMac::MacPropagateHiliteChanged()
2198 {
2199 #if !TARGET_API_MAC_OSX
2200 MacHiliteChanged() ;
2201
2202 wxWindowMac *child;
2203 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
2204 while ( node )
2205 {
2206 child = node->GetData();
2207 if (child /* && child->IsEnabled() */)
2208 child->MacPropagateHiliteChanged() ;
2209
2210 node = node->GetNext();
2211 }
2212 #endif
2213 }
2214
2215 //
2216 // status change notifications
2217 //
2218
2219 void wxWindowMac::MacVisibilityChanged()
2220 {
2221 }
2222
2223 void wxWindowMac::MacHiliteChanged()
2224 {
2225 }
2226
2227 void wxWindowMac::MacEnabledStateChanged()
2228 {
2229 }
2230
2231 //
2232 // status queries on the inherited window's state
2233 //
2234
2235 bool wxWindowMac::MacIsReallyShown()
2236 {
2237 // only under OSX the visibility of the TLW is taken into account
2238 if ( m_isBeingDeleted )
2239 return false ;
2240
2241 #if TARGET_API_MAC_OSX
2242 if ( m_peer && m_peer->Ok() )
2243 return m_peer->IsVisible();
2244 #endif
2245
2246 wxWindow* win = this ;
2247 while ( win->IsShown() )
2248 {
2249 if ( win->IsTopLevel() )
2250 return true ;
2251
2252 win = win->GetParent() ;
2253 if ( win == NULL )
2254 return true ;
2255 }
2256
2257 return false ;
2258 }
2259
2260 bool wxWindowMac::MacIsReallyEnabled()
2261 {
2262 return m_peer->IsEnabled() ;
2263 }
2264
2265 bool wxWindowMac::MacIsReallyHilited()
2266 {
2267 return m_peer->IsActive();
2268 }
2269
2270 void wxWindowMac::MacFlashInvalidAreas()
2271 {
2272 #if TARGET_API_MAC_OSX
2273 HIViewFlashDirtyArea( (WindowRef) MacGetTopLevelWindowRef() ) ;
2274 #endif
2275 }
2276
2277 int wxWindowMac::GetCharHeight() const
2278 {
2279 wxClientDC dc( (wxWindowMac*)this ) ;
2280
2281 return dc.GetCharHeight() ;
2282 }
2283
2284 int wxWindowMac::GetCharWidth() const
2285 {
2286 wxClientDC dc( (wxWindowMac*)this ) ;
2287
2288 return dc.GetCharWidth() ;
2289 }
2290
2291 void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
2292 int *descent, int *externalLeading, const wxFont *theFont ) const
2293 {
2294 const wxFont *fontToUse = theFont;
2295 if ( !fontToUse )
2296 fontToUse = &m_font;
2297
2298 wxClientDC dc( (wxWindowMac*) this ) ;
2299 long lx,ly,ld,le ;
2300 dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ;
2301 if ( externalLeading )
2302 *externalLeading = le ;
2303 if ( descent )
2304 *descent = ld ;
2305 if ( x )
2306 *x = lx ;
2307 if ( y )
2308 *y = ly ;
2309 }
2310
2311 /*
2312 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
2313 * we always intersect with the entire window, not only with the client area
2314 */
2315
2316 void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect)
2317 {
2318 if ( m_peer == NULL )
2319 return ;
2320
2321 if ( !MacIsReallyShown() )
2322 return ;
2323
2324 if ( rect )
2325 {
2326 Rect r ;
2327
2328 wxMacRectToNative( rect , &r ) ;
2329 m_peer->SetNeedsDisplay( &r ) ;
2330 }
2331 else
2332 {
2333 m_peer->SetNeedsDisplay() ;
2334 }
2335 }
2336
2337 void wxWindowMac::Freeze()
2338 {
2339 #if TARGET_API_MAC_OSX
2340 if ( !m_frozenness++ )
2341 {
2342 if ( m_peer && m_peer->Ok() )
2343 m_peer->SetDrawingEnabled( false ) ;
2344 }
2345 #endif
2346 }
2347
2348 void wxWindowMac::Thaw()
2349 {
2350 #if TARGET_API_MAC_OSX
2351 wxASSERT_MSG( m_frozenness > 0, wxT("Thaw() without matching Freeze()") );
2352
2353 if ( !--m_frozenness )
2354 {
2355 if ( m_peer && m_peer->Ok() )
2356 {
2357 m_peer->SetDrawingEnabled( true ) ;
2358 m_peer->InvalidateWithChildren() ;
2359 }
2360 }
2361 #endif
2362 }
2363
2364 bool wxWindowMac::IsFrozen() const
2365 {
2366 return m_frozenness != 0;
2367 }
2368
2369 wxWindowMac *wxGetActiveWindow()
2370 {
2371 // actually this is a windows-only concept
2372 return NULL;
2373 }
2374
2375 // Coordinates relative to the window
2376 void wxWindowMac::WarpPointer(int x_pos, int y_pos)
2377 {
2378 // We really don't move the mouse programmatically under Mac.
2379 }
2380
2381 void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
2382 {
2383 if ( MacGetTopLevelWindow() == NULL )
2384 return ;
2385
2386 #if TARGET_API_MAC_OSX
2387 if ( !m_macBackgroundBrush.Ok() || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT )
2388 {
2389 event.Skip() ;
2390 }
2391 else
2392 #endif
2393 {
2394 event.GetDC()->Clear() ;
2395 }
2396 }
2397
2398 void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
2399 {
2400 event.Skip() ;
2401 }
2402
2403 int wxWindowMac::GetScrollPos(int orient) const
2404 {
2405 if ( orient == wxHORIZONTAL )
2406 {
2407 if ( m_hScrollBar )
2408 return m_hScrollBar->GetThumbPosition() ;
2409 }
2410 else
2411 {
2412 if ( m_vScrollBar )
2413 return m_vScrollBar->GetThumbPosition() ;
2414 }
2415
2416 return 0;
2417 }
2418
2419 // This now returns the whole range, not just the number
2420 // of positions that we can scroll.
2421 int wxWindowMac::GetScrollRange(int orient) const
2422 {
2423 if ( orient == wxHORIZONTAL )
2424 {
2425 if ( m_hScrollBar )
2426 return m_hScrollBar->GetRange() ;
2427 }
2428 else
2429 {
2430 if ( m_vScrollBar )
2431 return m_vScrollBar->GetRange() ;
2432 }
2433
2434 return 0;
2435 }
2436
2437 int wxWindowMac::GetScrollThumb(int orient) const
2438 {
2439 if ( orient == wxHORIZONTAL )
2440 {
2441 if ( m_hScrollBar )
2442 return m_hScrollBar->GetThumbSize() ;
2443 }
2444 else
2445 {
2446 if ( m_vScrollBar )
2447 return m_vScrollBar->GetThumbSize() ;
2448 }
2449
2450 return 0;
2451 }
2452
2453 void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh)
2454 {
2455 if ( orient == wxHORIZONTAL )
2456 {
2457 if ( m_hScrollBar )
2458 m_hScrollBar->SetThumbPosition( pos ) ;
2459 }
2460 else
2461 {
2462 if ( m_vScrollBar )
2463 m_vScrollBar->SetThumbPosition( pos ) ;
2464 }
2465 }
2466
2467 //
2468 // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2469 // our own window origin is at leftOrigin/rightOrigin
2470 //
2471
2472 void wxWindowMac::MacPaintBorders( int leftOrigin , int rightOrigin )
2473 {
2474 if ( IsTopLevel() )
2475 return ;
2476
2477 Rect rect ;
2478 bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ;
2479 bool hasBothScrollbars = (m_hScrollBar && m_hScrollBar->IsShown()) && (m_vScrollBar && m_vScrollBar->IsShown()) ;
2480
2481 // back to the surrounding frame rectangle
2482 m_peer->GetRect( &rect ) ;
2483 InsetRect( &rect, -1 , -1 ) ;
2484
2485 #if wxMAC_USE_CORE_GRAPHICS
2486 {
2487 CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left ,
2488 rect.bottom - rect.top ) ;
2489
2490 HIThemeFrameDrawInfo info ;
2491 memset( &info, 0 , sizeof(info) ) ;
2492
2493 info.version = 0 ;
2494 info.kind = 0 ;
2495 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
2496 info.isFocused = hasFocus ;
2497
2498 CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ;
2499 wxASSERT( cgContext ) ;
2500
2501 if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
2502 {
2503 info.kind = kHIThemeFrameTextFieldSquare ;
2504 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
2505 }
2506 else if ( HasFlag(wxSIMPLE_BORDER) )
2507 {
2508 info.kind = kHIThemeFrameListBox ;
2509 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
2510 }
2511 else if ( hasFocus )
2512 {
2513 HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ;
2514 }
2515
2516 m_peer->GetRect( &rect ) ;
2517 if ( hasBothScrollbars )
2518 {
2519 int size = m_hScrollBar->GetWindowVariant() == wxWINDOW_VARIANT_NORMAL ? 16 : 12 ;
2520 CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
2521 CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
2522 HIThemeGrowBoxDrawInfo info ;
2523 memset( &info, 0, sizeof(info) ) ;
2524 info.version = 0 ;
2525 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
2526 info.kind = kHIThemeGrowBoxKindNone ;
2527 info.size = kHIThemeGrowBoxSizeNormal ;
2528 info.direction = kThemeGrowRight | kThemeGrowDown ;
2529 HIThemeDrawGrowBox( &cgpoint , &info , cgContext , kHIThemeOrientationNormal ) ;
2530 }
2531 }
2532 #else
2533 {
2534 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
2535 if ( top )
2536 {
2537 wxPoint pt(0, 0) ;
2538 wxMacControl::Convert( &pt , GetParent()->m_peer , top->m_peer ) ;
2539 OffsetRect( &rect , pt.x , pt.y ) ;
2540 }
2541
2542 if ( HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
2543 DrawThemeEditTextFrame( &rect, IsEnabled() ? kThemeStateActive : kThemeStateInactive ) ;
2544 else if ( HasFlag(wxSIMPLE_BORDER) )
2545 DrawThemeListBoxFrame( &rect, IsEnabled() ? kThemeStateActive : kThemeStateInactive ) ;
2546
2547 if ( hasFocus )
2548 DrawThemeFocusRect( &rect , true ) ;
2549
2550 if ( hasBothScrollbars )
2551 {
2552 // GetThemeStandaloneGrowBoxBounds
2553 // DrawThemeStandaloneNoGrowBox
2554 }
2555 }
2556 #endif
2557 }
2558
2559 void wxWindowMac::RemoveChild( wxWindowBase *child )
2560 {
2561 if ( child == m_hScrollBar )
2562 m_hScrollBar = NULL ;
2563 if ( child == m_vScrollBar )
2564 m_vScrollBar = NULL ;
2565
2566 wxWindowBase::RemoveChild( child ) ;
2567 }
2568
2569 // New function that will replace some of the above.
2570 void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible,
2571 int range, bool refresh)
2572 {
2573 bool showScroller;
2574 bool triggerSizeEvent = false;
2575
2576 if ( orient == wxHORIZONTAL )
2577 {
2578 if ( m_hScrollBar )
2579 {
2580 showScroller = ((range != 0) && (range > thumbVisible));
2581 if ( m_hScrollBar->IsShown() != showScroller )
2582 {
2583 m_hScrollBar->Show( showScroller );
2584 triggerSizeEvent = true;
2585 }
2586
2587 m_hScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
2588 }
2589 }
2590 else
2591 {
2592 if ( m_vScrollBar )
2593 {
2594 showScroller = ((range != 0) && (range > thumbVisible));
2595 if ( m_vScrollBar->IsShown() != showScroller )
2596 {
2597 m_vScrollBar->Show( showScroller ) ;
2598 triggerSizeEvent = true;
2599 }
2600
2601 m_vScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
2602 }
2603 }
2604
2605 MacRepositionScrollBars() ;
2606 if ( triggerSizeEvent )
2607 {
2608 wxSizeEvent event(GetSize(), m_windowId);
2609 event.SetEventObject(this);
2610 GetEventHandler()->ProcessEvent(event);
2611 }
2612 }
2613
2614 // Does a physical scroll
2615 void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
2616 {
2617 if ( dx == 0 && dy == 0 )
2618 return ;
2619
2620 int width , height ;
2621 GetClientSize( &width , &height ) ;
2622
2623 {
2624 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
2625 // area is scrolled, this does not occur if width and height are 2 pixels less,
2626 // TODO: write optimal workaround
2627 wxRect scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ;
2628 if ( rect )
2629 scrollrect.Intersect( *rect ) ;
2630
2631 if ( m_peer->GetNeedsDisplay() )
2632 {
2633 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
2634 // either immediate redraw or full invalidate
2635 #if 1
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 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
2642 if ( UMAGetSystemVersion() >= 0x1030 )
2643 HIViewRender(m_peer->GetControlRef()) ;
2644 else
2645 #endif
2646 Update() ;
2647 #endif
2648 }
2649
2650 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2651 scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
2652 m_peer->ScrollRect( &scrollrect , dx , dy ) ;
2653
2654 // becuase HIViewScrollRect does not scroll the already invalidated area we have two options
2655 // either immediate redraw or full invalidate
2656 #if 0
2657 // is the better overall solution, as it does not slow down scrolling
2658 m_peer->SetNeedsDisplay() ;
2659 #else
2660 // this would be the preferred version for fast drawing controls
2661
2662 HIViewRender(m_peer->GetControlRef()) ;
2663 #endif
2664 }
2665
2666 wxWindowMac *child;
2667 int x, y, w, h;
2668 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
2669 {
2670 child = node->GetData();
2671 if (child == NULL)
2672 continue;
2673 if (child == m_vScrollBar)
2674 continue;
2675 if (child == m_hScrollBar)
2676 continue;
2677 if (child->IsTopLevel())
2678 continue;
2679
2680 child->GetPosition( &x, &y );
2681 child->GetSize( &w, &h );
2682 if (rect)
2683 {
2684 wxRect rc( x, y, w, h );
2685 if (rect->Intersects( rc ))
2686 child->SetSize( x + dx, y + dy, w, h );
2687 }
2688 else
2689 {
2690 child->SetSize( x + dx, y + dy, w, h );
2691 }
2692 }
2693 }
2694
2695 void wxWindowMac::MacOnScroll( wxScrollEvent &event )
2696 {
2697 if ( event.GetEventObject() == m_vScrollBar || event.GetEventObject() == m_hScrollBar )
2698 {
2699 wxScrollWinEvent wevent;
2700 wevent.SetPosition(event.GetPosition());
2701 wevent.SetOrientation(event.GetOrientation());
2702 wevent.SetEventObject(this);
2703
2704 if (event.GetEventType() == wxEVT_SCROLL_TOP)
2705 wevent.SetEventType( wxEVT_SCROLLWIN_TOP );
2706 else if (event.GetEventType() == wxEVT_SCROLL_BOTTOM)
2707 wevent.SetEventType( wxEVT_SCROLLWIN_BOTTOM );
2708 else if (event.GetEventType() == wxEVT_SCROLL_LINEUP)
2709 wevent.SetEventType( wxEVT_SCROLLWIN_LINEUP );
2710 else if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN)
2711 wevent.SetEventType( wxEVT_SCROLLWIN_LINEDOWN );
2712 else if (event.GetEventType() == wxEVT_SCROLL_PAGEUP)
2713 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEUP );
2714 else if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN)
2715 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN );
2716 else if (event.GetEventType() == wxEVT_SCROLL_THUMBTRACK)
2717 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK );
2718 else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE)
2719 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE );
2720
2721 GetEventHandler()->ProcessEvent(wevent);
2722 }
2723 }
2724
2725 // Get the window with the focus
2726 wxWindowMac *wxWindowBase::DoFindFocus()
2727 {
2728 ControlRef control ;
2729 GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
2730 return wxFindControlFromMacControl( control ) ;
2731 }
2732
2733 void wxWindowMac::OnSetFocus( wxFocusEvent& event )
2734 {
2735 // panel wants to track the window which was the last to have focus in it,
2736 // so we want to set ourselves as the window which last had focus
2737 //
2738 // notice that it's also important to do it upwards the tree because
2739 // otherwise when the top level panel gets focus, it won't set it back to
2740 // us, but to some other sibling
2741
2742 // CS: don't know if this is still needed:
2743 //wxChildFocusEvent eventFocus(this);
2744 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2745
2746 if ( MacGetTopLevelWindow() && m_peer->NeedsFocusRect() )
2747 {
2748 #if wxMAC_USE_CORE_GRAPHICS
2749 GetParent()->Refresh() ;
2750 #else
2751 wxMacWindowStateSaver sv( this ) ;
2752 Rect rect ;
2753
2754 m_peer->GetRect( &rect ) ;
2755 // auf den umgebenden Rahmen zur\9fck
2756 InsetRect( &rect, -1 , -1 ) ;
2757
2758 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
2759 if ( top )
2760 {
2761 wxPoint pt(0, 0) ;
2762 wxMacControl::Convert( &pt , GetParent()->m_peer , top->m_peer ) ;
2763 rect.left += pt.x ;
2764 rect.right += pt.x ;
2765 rect.top += pt.y ;
2766 rect.bottom += pt.y ;
2767 }
2768
2769 bool bIsFocusEvent = (event.GetEventType() == wxEVT_SET_FOCUS);
2770 DrawThemeFocusRect( &rect , bIsFocusEvent ) ;
2771 if ( !bIsFocusEvent )
2772 {
2773 // as this erases part of the frame we have to redraw borders
2774 // and because our z-ordering is not always correct (staticboxes)
2775 // we have to invalidate things, we cannot simple redraw
2776 MacInvalidateBorders() ;
2777 }
2778 #endif
2779 }
2780
2781 event.Skip();
2782 }
2783
2784 void wxWindowMac::OnInternalIdle()
2785 {
2786 // This calls the UI-update mechanism (querying windows for
2787 // menu/toolbar/control state information)
2788 if (wxUpdateUIEvent::CanUpdate(this))
2789 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
2790 }
2791
2792 // Raise the window to the top of the Z order
2793 void wxWindowMac::Raise()
2794 {
2795 m_peer->SetZOrder( true , NULL ) ;
2796 }
2797
2798 // Lower the window to the bottom of the Z order
2799 void wxWindowMac::Lower()
2800 {
2801 m_peer->SetZOrder( false , NULL ) ;
2802 }
2803
2804 // static wxWindow *gs_lastWhich = NULL;
2805
2806 bool wxWindowMac::MacSetupCursor( const wxPoint& pt )
2807 {
2808 // first trigger a set cursor event
2809
2810 wxPoint clientorigin = GetClientAreaOrigin() ;
2811 wxSize clientsize = GetClientSize() ;
2812 wxCursor cursor ;
2813 if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) )
2814 {
2815 wxSetCursorEvent event( pt.x , pt.y );
2816
2817 bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
2818 if ( processedEvtSetCursor && event.HasCursor() )
2819 {
2820 cursor = event.GetCursor() ;
2821 }
2822 else
2823 {
2824 // the test for processedEvtSetCursor is here to prevent using m_cursor
2825 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2826 // it - this is a way to say that our cursor shouldn't be used for this
2827 // point
2828 if ( !processedEvtSetCursor && m_cursor.Ok() )
2829 cursor = m_cursor ;
2830
2831 if ( !wxIsBusy() && !GetParent() )
2832 cursor = *wxSTANDARD_CURSOR ;
2833 }
2834
2835 if ( cursor.Ok() )
2836 cursor.MacInstall() ;
2837 }
2838
2839 return cursor.Ok() ;
2840 }
2841
2842 wxString wxWindowMac::MacGetToolTipString( wxPoint &pt )
2843 {
2844 #if wxUSE_TOOLTIPS
2845 if ( m_tooltip )
2846 return m_tooltip->GetTip() ;
2847 #endif
2848
2849 return wxEmptyString ;
2850 }
2851
2852 void wxWindowMac::ClearBackground()
2853 {
2854 Refresh() ;
2855 Update() ;
2856 }
2857
2858 void wxWindowMac::Update()
2859 {
2860 #if TARGET_API_MAC_OSX
2861 MacGetTopLevelWindow()->MacPerformUpdates() ;
2862 #else
2863 ::Draw1Control( m_peer->GetControlRef() ) ;
2864 #endif
2865 }
2866
2867 wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
2868 {
2869 wxTopLevelWindowMac* win = NULL ;
2870 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
2871 if ( window )
2872 win = wxFindWinFromMacWindow( window ) ;
2873
2874 return win ;
2875 }
2876
2877 const wxRect& wxWindowMac::MacGetClippedClientRect() const
2878 {
2879 MacUpdateClippedRects() ;
2880
2881 return m_cachedClippedClientRect ;
2882 }
2883
2884 const wxRect& wxWindowMac::MacGetClippedRect() const
2885 {
2886 MacUpdateClippedRects() ;
2887
2888 return m_cachedClippedRect ;
2889 }
2890
2891 const wxRect&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
2892 {
2893 MacUpdateClippedRects() ;
2894
2895 return m_cachedClippedRectWithOuterStructure ;
2896 }
2897
2898 const wxRegion& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
2899 {
2900 static wxRegion emptyrgn ;
2901
2902 if ( !m_isBeingDeleted && MacIsReallyShown() /*m_peer->IsVisible() */ )
2903 {
2904 MacUpdateClippedRects() ;
2905 if ( includeOuterStructures )
2906 return m_cachedClippedRegionWithOuterStructure ;
2907 else
2908 return m_cachedClippedRegion ;
2909 }
2910 else
2911 {
2912 return emptyrgn ;
2913 }
2914 }
2915
2916 void wxWindowMac::MacUpdateClippedRects() const
2917 {
2918 if ( m_cachedClippedRectValid )
2919 return ;
2920
2921 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2922 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2923 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2924 // to add focus borders everywhere
2925
2926 Rect r, rIncludingOuterStructures ;
2927
2928 m_peer->GetRect( &r ) ;
2929 r.left -= MacGetLeftBorderSize() ;
2930 r.top -= MacGetTopBorderSize() ;
2931 r.bottom += MacGetBottomBorderSize() ;
2932 r.right += MacGetRightBorderSize() ;
2933
2934 r.right -= r.left ;
2935 r.bottom -= r.top ;
2936 r.left = 0 ;
2937 r.top = 0 ;
2938
2939 rIncludingOuterStructures = r ;
2940 InsetRect( &rIncludingOuterStructures , -4 , -4 ) ;
2941
2942 wxRect cl = GetClientRect() ;
2943 Rect rClient = { cl.y , cl.x , cl.y + cl.height , cl.x + cl.width } ;
2944
2945 int x , y ;
2946 wxSize size ;
2947 const wxWindow* child = this ;
2948 const wxWindow* parent = NULL ;
2949
2950 while ( !child->IsTopLevel() && ( parent = child->GetParent() ) != NULL )
2951 {
2952 if ( parent->MacIsChildOfClientArea(child) )
2953 {
2954 size = parent->GetClientSize() ;
2955 wxPoint origin = parent->GetClientAreaOrigin() ;
2956 x = origin.x ;
2957 y = origin.y ;
2958 }
2959 else
2960 {
2961 // this will be true for scrollbars, toolbars etc.
2962 size = parent->GetSize() ;
2963 y = parent->MacGetTopBorderSize() ;
2964 x = parent->MacGetLeftBorderSize() ;
2965 size.x -= parent->MacGetLeftBorderSize() + parent->MacGetRightBorderSize() ;
2966 size.y -= parent->MacGetTopBorderSize() + parent->MacGetBottomBorderSize() ;
2967 }
2968
2969 parent->MacWindowToRootWindow( &x, &y ) ;
2970 MacRootWindowToWindow( &x , &y ) ;
2971
2972 Rect rparent = { y , x , y + size.y , x + size.x } ;
2973
2974 // the wxwindow and client rects will always be clipped
2975 SectRect( &r , &rparent , &r ) ;
2976 SectRect( &rClient , &rparent , &rClient ) ;
2977
2978 // the structure only at 'hard' borders
2979 if ( parent->MacClipChildren() ||
2980 ( parent->GetParent() && parent->GetParent()->MacClipGrandChildren() ) )
2981 {
2982 SectRect( &rIncludingOuterStructures , &rparent , &rIncludingOuterStructures ) ;
2983 }
2984
2985 child = parent ;
2986 }
2987
2988 m_cachedClippedRect = wxRect( r.left , r.top , r.right - r.left , r.bottom - r.top ) ;
2989 m_cachedClippedClientRect = wxRect( rClient.left , rClient.top ,
2990 rClient.right - rClient.left , rClient.bottom - rClient.top ) ;
2991 m_cachedClippedRectWithOuterStructure = wxRect(
2992 rIncludingOuterStructures.left , rIncludingOuterStructures.top ,
2993 rIncludingOuterStructures.right - rIncludingOuterStructures.left ,
2994 rIncludingOuterStructures.bottom - rIncludingOuterStructures.top ) ;
2995
2996 m_cachedClippedRegionWithOuterStructure = wxRegion( m_cachedClippedRectWithOuterStructure ) ;
2997 m_cachedClippedRegion = wxRegion( m_cachedClippedRect ) ;
2998 m_cachedClippedClientRegion = wxRegion( m_cachedClippedClientRect ) ;
2999
3000 m_cachedClippedRectValid = true ;
3001 }
3002
3003 /*
3004 This function must not change the updatergn !
3005 */
3006 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time )
3007 {
3008 bool handled = false ;
3009 Rect updatebounds ;
3010 RgnHandle updatergn = (RgnHandle) updatergnr ;
3011 GetRegionBounds( updatergn , &updatebounds ) ;
3012
3013 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
3014
3015 if ( !EmptyRgn(updatergn) )
3016 {
3017 RgnHandle newupdate = NewRgn() ;
3018 wxSize point = GetClientSize() ;
3019 wxPoint origin = GetClientAreaOrigin() ;
3020 SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y + point.y ) ;
3021 SectRgn( newupdate , updatergn , newupdate ) ;
3022
3023 // first send an erase event to the entire update area
3024 {
3025 // for the toplevel window this really is the entire area
3026 // for all the others only their client area, otherwise they
3027 // might be drawing with full alpha and eg put blue into
3028 // the grow-box area of a scrolled window (scroll sample)
3029 wxDC* dc = new wxWindowDC(this);
3030 if ( IsTopLevel() )
3031 dc->SetClippingRegion(wxRegion(updatergn));
3032 else
3033 dc->SetClippingRegion(wxRegion(newupdate));
3034
3035 wxEraseEvent eevent( GetId(), dc );
3036 eevent.SetEventObject( this );
3037 GetEventHandler()->ProcessEvent( eevent );
3038 delete dc ;
3039 }
3040
3041 // calculate a client-origin version of the update rgn and set m_updateRegion to that
3042 OffsetRgn( newupdate , -origin.x , -origin.y ) ;
3043 m_updateRegion = newupdate ;
3044 DisposeRgn( newupdate ) ;
3045
3046 if ( !m_updateRegion.Empty() )
3047 {
3048 // paint the window itself
3049
3050 wxPaintEvent event;
3051 event.SetTimestamp(time);
3052 event.SetEventObject(this);
3053 GetEventHandler()->ProcessEvent(event);
3054 handled = true ;
3055 }
3056
3057 // now we cannot rely on having its borders drawn by a window itself, as it does not
3058 // get the updateRgn wide enough to always do so, so we do it from the parent
3059 // this would also be the place to draw any custom backgrounds for native controls
3060 // in Composited windowing
3061 wxPoint clientOrigin = GetClientAreaOrigin() ;
3062
3063 wxWindowMac *child;
3064 int x, y, w, h;
3065 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
3066 {
3067 child = node->GetData();
3068 if (child == NULL)
3069 continue;
3070 if (child == m_vScrollBar)
3071 continue;
3072 if (child == m_hScrollBar)
3073 continue;
3074 if (child->IsTopLevel())
3075 continue;
3076 if (!child->IsShown())
3077 continue;
3078
3079 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3080
3081 child->GetPosition( &x, &y );
3082 child->GetSize( &w, &h );
3083 Rect childRect = { y , x , y + h , x + w } ;
3084 OffsetRect( &childRect , clientOrigin.x , clientOrigin.y ) ;
3085 InsetRect( &childRect , -10 , -10) ;
3086
3087 if ( RectInRgn( &childRect , updatergn ) )
3088 {
3089 // paint custom borders
3090 wxNcPaintEvent eventNc( child->GetId() );
3091 eventNc.SetEventObject( child );
3092 if ( !child->GetEventHandler()->ProcessEvent( eventNc ) )
3093 {
3094 #if wxMAC_USE_CORE_GRAPHICS
3095 child->MacPaintBorders(0, 0) ;
3096 #else
3097 {
3098 wxWindowDC dc(this) ;
3099 dc.SetClippingRegion(wxRegion(updatergn));
3100 wxMacPortSetter helper(&dc) ;
3101 child->MacPaintBorders(0, 0) ;
3102 }
3103 #endif
3104 }
3105 }
3106 }
3107 }
3108
3109 return handled ;
3110 }
3111
3112
3113 WXWindow wxWindowMac::MacGetTopLevelWindowRef() const
3114 {
3115 wxWindowMac *iter = (wxWindowMac*)this ;
3116
3117 while ( iter )
3118 {
3119 if ( iter->IsTopLevel() )
3120 return ((wxTopLevelWindow*)iter)->MacGetWindowRef() ;
3121
3122 iter = iter->GetParent() ;
3123 }
3124
3125 return NULL ;
3126 }
3127
3128 void wxWindowMac::MacCreateScrollBars( long style )
3129 {
3130 wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ;
3131
3132 if ( style & ( wxVSCROLL | wxHSCROLL ) )
3133 {
3134 bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ;
3135 int scrlsize = MAC_SCROLLBAR_SIZE ;
3136 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL || GetWindowVariant() == wxWINDOW_VARIANT_MINI )
3137 {
3138 scrlsize = MAC_SMALL_SCROLLBAR_SIZE ;
3139 }
3140
3141 int adjust = hasBoth ? scrlsize - 1: 0 ;
3142 int width, height ;
3143 GetClientSize( &width , &height ) ;
3144
3145 wxPoint vPoint(width - scrlsize, 0) ;
3146 wxSize vSize(scrlsize, height - adjust) ;
3147 wxPoint hPoint(0, height - scrlsize) ;
3148 wxSize hSize(width - adjust, scrlsize) ;
3149
3150 if ( style & wxVSCROLL )
3151 m_vScrollBar = new wxScrollBar(this, wxID_ANY, vPoint, vSize , wxVERTICAL);
3152
3153 if ( style & wxHSCROLL )
3154 m_hScrollBar = new wxScrollBar(this, wxID_ANY, hPoint, hSize , wxHORIZONTAL);
3155 }
3156
3157 // because the create does not take into account the client area origin
3158 // we might have a real position shift
3159 MacRepositionScrollBars() ;
3160 }
3161
3162 bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const
3163 {
3164 bool result = ((child == NULL) || ((child != m_hScrollBar) && (child != m_vScrollBar)));
3165
3166 return result ;
3167 }
3168
3169 void wxWindowMac::MacRepositionScrollBars()
3170 {
3171 if ( !m_hScrollBar && !m_vScrollBar )
3172 return ;
3173
3174 bool hasBoth = (m_hScrollBar && m_hScrollBar->IsShown()) && ( m_vScrollBar && m_vScrollBar->IsShown()) ;
3175 int scrlsize = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
3176 int adjust = hasBoth ? scrlsize - 1 : 0 ;
3177
3178 // get real client area
3179 int width, height ;
3180 GetSize( &width , &height );
3181
3182 width -= MacGetLeftBorderSize() + MacGetRightBorderSize();
3183 height -= MacGetTopBorderSize() + MacGetBottomBorderSize();
3184
3185 wxPoint vPoint( width - scrlsize, 0 ) ;
3186 wxSize vSize( scrlsize, height - adjust ) ;
3187 wxPoint hPoint( 0 , height - scrlsize ) ;
3188 wxSize hSize( width - adjust, scrlsize ) ;
3189
3190 #if 0
3191 int x = 0, y = 0, w, h ;
3192 GetSize( &w , &h ) ;
3193
3194 MacClientToRootWindow( &x , &y ) ;
3195 MacClientToRootWindow( &w , &h ) ;
3196
3197 wxWindowMac *iter = (wxWindowMac*)this ;
3198
3199 int totW = 10000 , totH = 10000;
3200 while ( iter )
3201 {
3202 if ( iter->IsTopLevel() )
3203 {
3204 iter->GetSize( &totW , &totH ) ;
3205 break ;
3206 }
3207
3208 iter = iter->GetParent() ;
3209 }
3210
3211 if ( x == 0 )
3212 {
3213 hPoint.x = -1 ;
3214 hSize.x += 1 ;
3215 }
3216 if ( y == 0 )
3217 {
3218 vPoint.y = -1 ;
3219 vSize.y += 1 ;
3220 }
3221
3222 if ( w - x >= totW )
3223 {
3224 hSize.x += 1 ;
3225 vPoint.x += 1 ;
3226 }
3227 if ( h - y >= totH )
3228 {
3229 vSize.y += 1 ;
3230 hPoint.y += 1 ;
3231 }
3232 #endif
3233
3234 if ( m_vScrollBar )
3235 m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE );
3236 if ( m_hScrollBar )
3237 m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE );
3238 }
3239
3240 bool wxWindowMac::AcceptsFocus() const
3241 {
3242 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3243 }
3244
3245 void wxWindowMac::MacSuperChangedPosition()
3246 {
3247 // only window-absolute structures have to be moved i.e. controls
3248
3249 m_cachedClippedRectValid = false ;
3250
3251 wxWindowMac *child;
3252 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
3253 while ( node )
3254 {
3255 child = node->GetData();
3256 child->MacSuperChangedPosition() ;
3257
3258 node = node->GetNext();
3259 }
3260 }
3261
3262 void wxWindowMac::MacTopLevelWindowChangedPosition()
3263 {
3264 // only screen-absolute structures have to be moved i.e. glcanvas
3265
3266 wxWindowMac *child;
3267 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
3268 while ( node )
3269 {
3270 child = node->GetData();
3271 child->MacTopLevelWindowChangedPosition() ;
3272
3273 node = node->GetNext();
3274 }
3275 }
3276
3277 long wxWindowMac::MacGetLeftBorderSize() const
3278 {
3279 if ( IsTopLevel() )
3280 return 0 ;
3281
3282 SInt32 border = 0 ;
3283
3284 if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER))
3285 {
3286 // this metric is only the 'outset' outside the simple frame rect
3287 GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ;
3288 border += 1 ;
3289 }
3290 else if (HasFlag(wxSIMPLE_BORDER))
3291 {
3292 // this metric is only the 'outset' outside the simple frame rect
3293 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
3294 border += 1 ;
3295 }
3296
3297 return border ;
3298 }
3299
3300 long wxWindowMac::MacGetRightBorderSize() const
3301 {
3302 // they are all symmetric in mac themes
3303 return MacGetLeftBorderSize() ;
3304 }
3305
3306 long wxWindowMac::MacGetTopBorderSize() const
3307 {
3308 // they are all symmetric in mac themes
3309 return MacGetLeftBorderSize() ;
3310 }
3311
3312 long wxWindowMac::MacGetBottomBorderSize() const
3313 {
3314 // they are all symmetric in mac themes
3315 return MacGetLeftBorderSize() ;
3316 }
3317
3318 long wxWindowMac::MacRemoveBordersFromStyle( long style )
3319 {
3320 return style & ~wxBORDER_MASK ;
3321 }
3322
3323 // Find the wxWindowMac at the current mouse position, returning the mouse
3324 // position.
3325 wxWindowMac * wxFindWindowAtPointer( wxPoint& pt )
3326 {
3327 pt = wxGetMousePosition();
3328 wxWindowMac* found = wxFindWindowAtPoint(pt);
3329
3330 return found;
3331 }
3332
3333 // Get the current mouse position.
3334 wxPoint wxGetMousePosition()
3335 {
3336 int x, y;
3337
3338 wxGetMousePosition( &x, &y );
3339
3340 return wxPoint(x, y);
3341 }
3342
3343 void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
3344 {
3345 if ( event.GetEventType() == wxEVT_RIGHT_DOWN )
3346 {
3347 // copied from wxGTK : CS
3348 // VZ: shouldn't we move this to base class then?
3349
3350 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
3351 // except that:
3352 //
3353 // (a) it's a command event and so is propagated to the parent
3354 // (b) under MSW it can be generated from kbd too
3355 // (c) it uses screen coords (because of (a))
3356 wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
3357 this->GetId(),
3358 this->ClientToScreen(event.GetPosition()));
3359 if ( ! GetEventHandler()->ProcessEvent(evtCtx) )
3360 event.Skip() ;
3361 }
3362 else
3363 {
3364 event.Skip() ;
3365 }
3366 }
3367
3368 void wxWindowMac::OnPaint( wxPaintEvent & event )
3369 {
3370 if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL )
3371 CallNextEventHandler(
3372 (EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() ,
3373 (EventRef) wxTheApp->MacGetCurrentEvent() ) ;
3374 }
3375
3376 void wxWindowMac::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED( mouseStillDown ) )
3377 {
3378 }
3379
3380 Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin )
3381 {
3382 int x, y, w, h ;
3383
3384 window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ;
3385 Rect bounds = { y, x, y + h, x + w };
3386
3387 return bounds ;
3388 }
3389
3390 wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) )
3391 {
3392 return eventNotHandledErr ;
3393 }
3394
3395 bool wxWindowMac::Reparent(wxWindowBase *newParentBase)
3396 {
3397 wxWindowMac *newParent = (wxWindowMac *)newParentBase;
3398 if ( !wxWindowBase::Reparent(newParent) )
3399 return false;
3400
3401 // copied from MacPostControlCreate
3402 ControlRef container = (ControlRef) GetParent()->GetHandle() ;
3403
3404 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
3405
3406 ::EmbedControl( m_peer->GetControlRef() , container ) ;
3407
3408 return true;
3409 }
3410
3411 bool wxWindowMac::SetTransparent(wxByte alpha)
3412 {
3413 #if wxMAC_USE_CORE_GRAPHICS
3414 if ( alpha != m_macAlpha )
3415 {
3416 m_macAlpha = alpha ;
3417 Refresh() ;
3418 }
3419 return true ;
3420 #else
3421 return false ;
3422 #endif
3423 }
3424
3425
3426 bool wxWindowMac::CanSetTransparent()
3427 {
3428 #if wxMAC_USE_CORE_GRAPHICS
3429 return true ;
3430 #else
3431 return false ;
3432 #endif
3433 }
3434
3435 wxByte wxWindowMac::GetTransparent() const
3436 {
3437 return m_macAlpha ;
3438 }