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