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