1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/window.cpp
3 // Purpose: wxWindowMac
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
14 #include "wx/window.h"
23 #include "wx/dcclient.h"
24 #include "wx/button.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"
40 #include "wx/tooltip.h"
41 #include "wx/spinctrl.h"
42 #include "wx/geometry.h"
45 #include "wx/listctrl.h"
49 #include "wx/treectrl.h"
57 #include "wx/popupwin.h"
60 #if wxUSE_DRAG_AND_DROP
65 #include "wx/osx/uma.h"
67 #include "wx/osx/private.h"
69 #include <Carbon/Carbon.h>
72 #define MAC_SCROLLBAR_SIZE 15
73 #define MAC_SMALL_SCROLLBAR_SIZE 11
77 #define wxMAC_DEBUG_REDRAW 0
78 #ifndef wxMAC_DEBUG_REDRAW
79 #define wxMAC_DEBUG_REDRAW 0
82 // Get the window with the focus
83 WXWidget
wxWidgetImpl::FindFocus()
85 ControlRef control
= NULL
;
86 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
90 // ---------------------------------------------------------------------------
92 // ---------------------------------------------------------------------------
94 static const EventTypeSpec eventList
[] =
96 { kEventClassCommand
, kEventProcessCommand
} ,
97 { kEventClassCommand
, kEventCommandUpdateStatus
} ,
99 { kEventClassControl
, kEventControlGetClickActivation
} ,
100 { kEventClassControl
, kEventControlHit
} ,
102 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
103 { kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
} ,
105 { kEventClassControl
, kEventControlDraw
} ,
107 { kEventClassControl
, kEventControlVisibilityChanged
} ,
108 { kEventClassControl
, kEventControlEnabledStateChanged
} ,
109 { kEventClassControl
, kEventControlHiliteChanged
} ,
111 { kEventClassControl
, kEventControlActivate
} ,
112 { kEventClassControl
, kEventControlDeactivate
} ,
114 { kEventClassControl
, kEventControlSetFocusPart
} ,
115 { kEventClassControl
, kEventControlFocusPartChanged
} ,
117 { kEventClassService
, kEventServiceGetTypes
},
118 { kEventClassService
, kEventServiceCopy
},
119 { kEventClassService
, kEventServicePaste
},
121 // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
122 // { kEventClassControl , kEventControlBoundsChanged } ,
125 static pascal OSStatus
wxMacWindowControlEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
127 OSStatus result
= eventNotHandledErr
;
128 static wxWindowMac
* targetFocusWindow
= NULL
;
129 static wxWindowMac
* formerFocusWindow
= NULL
;
131 wxMacCarbonEvent
cEvent( event
) ;
133 ControlRef controlRef
;
134 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
136 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
138 switch ( GetEventKind( event
) )
140 case kEventControlDraw
:
142 HIShapeRef updateRgn
= NULL
;
143 HIMutableShapeRef allocatedRgn
= NULL
;
144 wxRegion visRegion
= thisWindow
->MacGetVisibleRegion() ;
146 // according to the docs: redraw entire control if param not present
147 if ( cEvent
.GetParameter
<HIShapeRef
>(kEventParamShape
, &updateRgn
) != noErr
)
149 updateRgn
= visRegion
.GetWXHRGN();
153 if ( thisWindow
->MacGetLeftBorderSize() != 0 || thisWindow
->MacGetTopBorderSize() != 0 )
155 // as this update region is in native window locals we must adapt it to wx window local
156 allocatedRgn
= HIShapeCreateMutableCopy(updateRgn
);
157 HIShapeOffset(allocatedRgn
, thisWindow
->MacGetLeftBorderSize() , thisWindow
->MacGetTopBorderSize());
158 // hide the given region by the new region that must be shifted
159 updateRgn
= allocatedRgn
;
163 #if wxMAC_DEBUG_REDRAW
164 if ( thisWindow
->MacIsUserPane() )
166 static float color
= 0.5 ;
167 static int channel
= 0 ;
169 CGContextRef cgContext
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
) ;
171 HIViewGetBounds( controlRef
, &bounds
);
172 CGContextSetRGBFillColor( cgContext
, channel
== 0 ? color
: 0.5 ,
173 channel
== 1 ? color
: 0.5 , channel
== 2 ? color
: 0.5 , 1 );
174 CGContextFillRect( cgContext
, bounds
);
187 CGContextRef cgContext
= NULL
;
188 OSStatus err
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
, &cgContext
) ;
191 // for non-composite drawing, since we don't support it ourselves, send it through the
192 // the default handler
193 // CallNextEventHandler( handler,event ) ;
196 CFRelease( allocatedRgn
) ;
200 thisWindow
->MacSetCGContextRef( cgContext
) ;
203 wxMacCGContextStateSaver
sg( cgContext
) ;
204 CGFloat alpha
= (CGFloat
)1.0 ;
206 wxWindow
* iter
= thisWindow
;
209 alpha
*= (CGFloat
)( iter
->GetTransparent()/255.0 ) ;
210 if ( iter
->IsTopLevel() )
213 iter
= iter
->GetParent() ;
216 CGContextSetAlpha( cgContext
, alpha
) ;
218 if ( thisWindow
->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
221 HIViewGetBounds( controlRef
, &bounds
);
222 CGContextClearRect( cgContext
, bounds
);
225 if ( !HIShapeIsEmpty(updateRgn
) )
227 // refcount increase because wxRegion constructor takes ownership of the native region
229 thisWindow
->GetUpdateRegion() = wxRegion(updateRgn
);
230 if ( !thisWindow
->MacDoRedraw( cEvent
.GetTicks() ) )
232 // for native controls: call their native paint method
233 if ( !thisWindow
->MacIsUserPane() ||
234 ( thisWindow
->IsTopLevel() && thisWindow
->GetBackgroundStyle() == wxBG_STYLE_SYSTEM
) )
236 if ( thisWindow
->GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT
)
238 CallNextEventHandler( handler
,event
) ;
247 thisWindow
->MacPaintChildrenBorders();
249 thisWindow
->MacSetCGContextRef( NULL
) ;
254 CFRelease( allocatedRgn
) ;
258 case kEventControlVisibilityChanged
:
259 // we might have two native controls attributed to the same wxWindow instance
260 // eg a scrollview and an embedded textview, make sure we only fire for the 'outer'
261 // control, as otherwise native and wx visibility are different
262 if ( thisWindow
->GetPeer() != NULL
&& thisWindow
->GetPeer()->GetControlRef() == controlRef
)
264 thisWindow
->MacVisibilityChanged() ;
268 case kEventControlEnabledStateChanged
:
269 thisWindow
->MacEnabledStateChanged();
272 case kEventControlHiliteChanged
:
273 thisWindow
->MacHiliteChanged() ;
276 case kEventControlActivate
:
277 case kEventControlDeactivate
:
278 // FIXME: we should have a virtual function for this!
280 if ( thisWindow
->IsKindOf( CLASSINFO( wxTreeCtrl
) ) )
281 thisWindow
->Refresh();
284 if ( thisWindow
->IsKindOf( CLASSINFO( wxListCtrl
) ) )
285 thisWindow
->Refresh();
291 // different handling on OS X
294 case kEventControlFocusPartChanged
:
295 // the event is emulated by wxmac for systems lower than 10.5
297 if ( UMAGetSystemVersion() < 0x1050 )
299 // as it is synthesized here, we have to manually avoid propagation
302 ControlPartCode previousControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPreviousPart
, typeControlPartCode
);
303 ControlPartCode currentControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlCurrentPart
, typeControlPartCode
);
305 if ( thisWindow
->MacGetTopLevelWindow() && thisWindow
->GetPeer()->NeedsFocusRect() )
307 thisWindow
->MacInvalidateBorders();
310 if ( currentControlPart
== 0 )
314 if ( thisWindow
->GetCaret() )
315 thisWindow
->GetCaret()->OnKillFocus();
318 wxLogTrace(wxT("Focus"), wxT("focus lost(%p)"), static_cast<void*>(thisWindow
));
320 // remove this as soon as posting the synthesized event works properly
321 static bool inKillFocusEvent
= false ;
323 if ( !inKillFocusEvent
)
325 inKillFocusEvent
= true ;
326 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
327 event
.SetEventObject(thisWindow
);
328 event
.SetWindow(targetFocusWindow
);
329 thisWindow
->HandleWindowEvent(event
) ;
330 inKillFocusEvent
= false ;
331 targetFocusWindow
= NULL
;
334 else if ( previousControlPart
== 0 )
337 // panel wants to track the window which was the last to have focus in it
338 wxLogTrace(wxT("Focus"), wxT("focus set(%p)"), static_cast<void*>(thisWindow
));
339 wxChildFocusEvent
eventFocus((wxWindow
*)thisWindow
);
340 thisWindow
->HandleWindowEvent(eventFocus
);
343 if ( thisWindow
->GetCaret() )
344 thisWindow
->GetCaret()->OnSetFocus();
347 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
348 event
.SetEventObject(thisWindow
);
349 event
.SetWindow(formerFocusWindow
);
350 thisWindow
->HandleWindowEvent(event
) ;
351 formerFocusWindow
= NULL
;
355 case kEventControlSetFocusPart
:
357 Boolean focusEverything
= false ;
358 if ( cEvent
.GetParameter
<Boolean
>(kEventParamControlFocusEverything
, &focusEverything
) == noErr
)
360 // put a breakpoint here to catch focus everything events
362 ControlPartCode controlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
363 if ( controlPart
!= kControlFocusNoPart
)
365 targetFocusWindow
= thisWindow
;
366 wxLogTrace(wxT("Focus"), wxT("focus to be set(%p)"), static_cast<void*>(thisWindow
));
370 formerFocusWindow
= thisWindow
;
371 wxLogTrace(wxT("Focus"), wxT("focus to be lost(%p)"), static_cast<void*>(thisWindow
));
374 ControlPartCode previousControlPart
= 0;
375 verify_noerr( HIViewGetFocusPart(controlRef
, &previousControlPart
));
377 if ( thisWindow
->MacIsUserPane() )
379 if ( controlPart
!= kControlFocusNoPart
)
380 cEvent
.SetParameter
<ControlPartCode
>( kEventParamControlPart
, typeControlPartCode
, 1 ) ;
384 result
= CallNextEventHandler(handler
, event
);
386 if ( UMAGetSystemVersion() < 0x1050 )
388 // set back to 0 if problems arise
390 if ( result
== noErr
)
392 ControlPartCode currentControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
393 // synthesize the event focus changed event
394 EventRef evRef
= NULL
;
396 OSStatus err
= MacCreateEvent(
397 NULL
, kEventClassControl
, kEventControlFocusPartChanged
, TicksToEventTime( TickCount() ) ,
398 kEventAttributeUserEvent
, &evRef
);
401 wxMacCarbonEvent
iEvent( evRef
) ;
402 iEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, controlRef
);
403 iEvent
.SetParameter
<EventTargetRef
>( kEventParamPostTarget
, typeEventTargetRef
, GetControlEventTarget( controlRef
) );
404 iEvent
.SetParameter
<ControlPartCode
>( kEventParamControlPreviousPart
, typeControlPartCode
, previousControlPart
);
405 iEvent
.SetParameter
<ControlPartCode
>( kEventParamControlCurrentPart
, typeControlPartCode
, currentControlPart
);
408 // TODO test this first, avoid double posts etc...
409 PostEventToQueue( GetMainEventQueue(), evRef
, kEventPriorityHigh
);
411 wxMacWindowControlEventHandler( NULL
, evRef
, data
) ;
413 ReleaseEvent( evRef
) ;
416 // old implementation, to be removed if the new one works
417 if ( controlPart
== kControlFocusNoPart
)
420 if ( thisWindow
->GetCaret() )
421 thisWindow
->GetCaret()->OnKillFocus();
424 wxLogTrace(wxT("Focus"), wxT("focus lost(%p)"), static_cast<void*>(thisWindow
));
426 static bool inKillFocusEvent
= false ;
428 if ( !inKillFocusEvent
)
430 inKillFocusEvent
= true ;
431 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
432 event
.SetEventObject(thisWindow
);
433 thisWindow
->HandleWindowEvent(event
) ;
434 inKillFocusEvent
= false ;
439 // panel wants to track the window which was the last to have focus in it
440 wxLogTrace(wxT("Focus"), wxT("focus set(%p)"), static_cast<void*>(thisWindow
));
441 wxChildFocusEvent
eventFocus((wxWindow
*)thisWindow
);
442 thisWindow
->HandleWindowEvent(eventFocus
);
445 if ( thisWindow
->GetCaret() )
446 thisWindow
->GetCaret()->OnSetFocus();
449 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
450 event
.SetEventObject(thisWindow
);
451 thisWindow
->HandleWindowEvent(event
) ;
458 case kEventControlHit
:
459 result
= thisWindow
->MacControlHit( handler
, event
) ;
462 case kEventControlGetClickActivation
:
464 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
465 WindowRef owner
= cEvent
.GetParameter
<WindowRef
>(kEventParamWindowRef
);
466 if ( !IsWindowActive(owner
) )
468 cEvent
.SetParameter(kEventParamClickActivation
,typeClickActivationResult
, (UInt32
) kActivateAndIgnoreClick
) ;
481 static pascal OSStatus
482 wxMacWindowServiceEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
486 OSStatus result
= eventNotHandledErr
;
488 wxMacCarbonEvent
cEvent( event
) ;
490 ControlRef controlRef
;
491 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
492 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
493 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
495 switch ( GetEventKind( event
) )
497 case kEventServiceGetTypes
:
501 textCtrl
->GetSelection( &from
, &to
) ;
503 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
505 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
506 if ( textCtrl
->IsEditable() )
507 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
509 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
510 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
512 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
516 CFArrayAppendValue(copyTypes
, typestring
) ;
518 CFArrayAppendValue(pasteTypes
, typestring
) ;
520 CFRelease( typestring
) ;
528 case kEventServiceCopy
:
533 textCtrl
->GetSelection( &from
, &to
) ;
534 wxString val
= textCtrl
->GetValue() ;
535 val
= val
.Mid( from
, to
- from
) ;
536 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
537 verify_noerr( PasteboardClear( pasteboard
) ) ;
538 PasteboardSynchronize( pasteboard
);
539 // TODO add proper conversion
540 CFDataRef data
= CFDataCreate( kCFAllocatorDefault
, (const UInt8
*)val
.c_str(), val
.length() );
541 PasteboardPutItemFlavor( pasteboard
, (PasteboardItemID
) 1, CFSTR("com.apple.traditional-mac-plain-text"), data
, 0);
547 case kEventServicePaste
:
550 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
551 PasteboardSynchronize( pasteboard
);
553 verify_noerr( PasteboardGetItemCount( pasteboard
, &itemCount
) );
554 for( UInt32 itemIndex
= 1; itemIndex
<= itemCount
; itemIndex
++ )
556 PasteboardItemID itemID
;
557 if ( PasteboardGetItemIdentifier( pasteboard
, itemIndex
, &itemID
) == noErr
)
559 CFDataRef flavorData
= NULL
;
560 if ( PasteboardCopyItemFlavorData( pasteboard
, itemID
, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData
) == noErr
)
562 CFIndex flavorDataSize
= CFDataGetLength( flavorData
);
563 char *content
= new char[flavorDataSize
+1] ;
564 memcpy( content
, CFDataGetBytePtr( flavorData
), flavorDataSize
);
565 content
[flavorDataSize
]=0;
566 CFRelease( flavorData
);
568 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
570 textCtrl
->WriteText( wxString( content
) ) ;
588 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
590 OSStatus result
= eventNotHandledErr
;
591 wxWindowMac
* focus
= (wxWindowMac
*) data
;
593 wchar_t* uniChars
= NULL
;
594 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
596 UniChar
* charBuf
= NULL
;
597 ByteCount dataSize
= 0 ;
600 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
602 numChars
= dataSize
/ sizeof( UniChar
) + 1;
605 if ( (size_t) numChars
* 2 > sizeof(buf
) )
606 charBuf
= new UniChar
[ numChars
] ;
610 uniChars
= new wchar_t[ numChars
] ;
611 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
612 charBuf
[ numChars
- 1 ] = 0;
613 #if SIZEOF_WCHAR_T == 2
614 uniChars
= (wchar_t*) charBuf
;
615 /* 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...)
617 // the resulting string will never have more chars than the utf16 version, so this is safe
618 wxMBConvUTF16 converter
;
619 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
623 switch ( GetEventKind( event
) )
625 case kEventTextInputUpdateActiveInputArea
:
627 // An IME input event may return several characters, but we need to send one char at a time to
629 for (int pos
=0 ; pos
< numChars
; pos
++)
631 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
632 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
633 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
635 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
637 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
638 multiple times to update the active range during inline input, so this handler will often receive
639 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
640 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
641 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
642 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
643 should add new event types to support advanced text input. For now, I would keep things as they are.
645 However, the code that was being used caused additional problems:
646 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
647 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
648 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
649 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
650 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
651 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
652 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
653 overlap with Unicode within the (7-bit) ASCII range.
654 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
655 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
656 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
657 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
658 I don't have time to look into that right now.
661 if ( wxTheApp
->MacSendCharEvent(
662 focus
, message
, 0 , when
, 0 , 0 , uniChars
[pos
] ) )
667 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
671 case kEventTextInputUnicodeForKeyEvent
:
673 UInt32 keyCode
, modifiers
;
676 unsigned char charCode
;
678 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
679 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
680 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
681 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
682 GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
684 UInt32 message
= (keyCode
<< 8) + charCode
;
686 // An IME input event may return several characters, but we need to send one char at a time to
688 for (int pos
=0 ; pos
< numChars
; pos
++)
690 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
691 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
692 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
694 if ( wxTheApp
->MacSendCharEvent(
695 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChars
[pos
] ) )
700 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
709 if ( charBuf
!= buf
)
715 static pascal OSStatus
716 wxMacWindowCommandEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
720 OSStatus result
= eventNotHandledErr
;
721 wxWindowMac
* focus
= (wxWindowMac
*) data
;
725 wxMacCarbonEvent
cEvent( event
) ;
726 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
728 wxMenuItem
* item
= NULL
;
729 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
733 wxASSERT( itemMenu
!= NULL
) ;
735 switch ( cEvent
.GetKind() )
737 case kEventProcessCommand
:
738 if ( itemMenu
->HandleCommandProcess( item
, focus
) )
742 case kEventCommandUpdateStatus
:
743 if ( itemMenu
->HandleCommandUpdateStatus( item
, focus
) )
754 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
756 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
757 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
758 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
759 OSStatus result
= eventNotHandledErr
;
761 switch ( GetEventClass( event
) )
763 case kEventClassCommand
:
764 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
767 case kEventClassControl
:
768 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
771 case kEventClassService
:
772 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
775 case kEventClassTextInput
:
776 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
783 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
788 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
790 // ---------------------------------------------------------------------------
791 // Scrollbar Tracking for all
792 // ---------------------------------------------------------------------------
794 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
795 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
799 wxWindow
* wx
= wxFindWindowFromWXWidget( (WXWidget
) control
) ;
802 wxEventType scrollEvent
= wxEVT_NULL
;
805 case kControlUpButtonPart
:
806 scrollEvent
= wxEVT_SCROLL_LINEUP
;
809 case kControlDownButtonPart
:
810 scrollEvent
= wxEVT_SCROLL_LINEDOWN
;
813 case kControlPageUpPart
:
814 scrollEvent
= wxEVT_SCROLL_PAGEUP
;
817 case kControlPageDownPart
:
818 scrollEvent
= wxEVT_SCROLL_PAGEDOWN
;
821 case kControlIndicatorPart
:
822 scrollEvent
= wxEVT_SCROLL_THUMBTRACK
;
823 // when this is called as a live proc, mouse is always still down
824 // so no need for thumbrelease
825 // scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
828 wx
->TriggerScrollEvent(scrollEvent
) ;
832 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
834 wxWidgetImplType
* wxWidgetImpl::CreateUserPane( wxWindowMac
* wxpeer
,
835 wxWindowMac
* WXUNUSED(parent
),
836 wxWindowID
WXUNUSED(id
),
839 long WXUNUSED(style
),
840 long WXUNUSED(extraStyle
))
842 OSStatus err
= noErr
;
843 Rect bounds
= wxMacGetBoundsForControl( wxpeer
, pos
, size
) ;
844 wxMacControl
* c
= new wxMacControl(wxpeer
) ;
846 | kControlSupportsEmbedding
847 | kControlSupportsLiveFeedback
848 | kControlGetsFocusOnClick
849 // | kControlHasSpecialBackground
850 // | kControlSupportsCalcBestRect
851 | kControlHandlesTracking
852 | kControlSupportsFocus
853 | kControlWantsActivate
854 | kControlWantsIdle
;
856 err
=::CreateUserPaneControl( MAC_WXHWND(wxpeer
->GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, c
->GetControlRefAddr() );
862 void wxMacControl::InstallEventHandler( WXWidget control
)
864 wxWidgetImpl::Associate( control
? control
: (WXWidget
) m_controlRef
, this ) ;
865 ::InstallControlEventHandler( control
? (ControlRef
) control
: m_controlRef
, GetwxMacWindowEventHandlerUPP(),
866 GetEventTypeCount(eventList
), eventList
, GetWXPeer(), NULL
);
869 IMPLEMENT_DYNAMIC_CLASS( wxMacControl
, wxWidgetImpl
)
871 wxMacControl::wxMacControl()
876 wxMacControl::wxMacControl(wxWindowMac
* peer
, bool isRootControl
) :
877 wxWidgetImpl( peer
, isRootControl
)
882 wxMacControl::~wxMacControl()
884 if ( m_controlRef
&& !IsRootControl() )
886 wxASSERT_MSG( m_controlRef
!= NULL
, wxT("Control Handle already NULL, Dispose called twice ?") );
887 wxASSERT_MSG( IsValidControlHandle(m_controlRef
) , wxT("Invalid Control Handle (maybe already released) in Dispose") );
889 wxWidgetImpl::RemoveAssociations( this ) ;
890 // we cannot check the ref count here anymore, as autorelease objects might delete their refs later
891 // we can have situations when being embedded, where the control gets deleted behind our back, so only
892 // CFRelease if we are safe
893 if ( IsValidControlHandle(m_controlRef
) )
894 CFRelease(m_controlRef
);
899 void wxMacControl::Init()
902 m_macControlEventHandler
= NULL
;
905 void wxMacControl::RemoveFromParent()
907 // nothing to do here for carbon
908 HIViewRemoveFromSuperview(m_controlRef
);
911 void wxMacControl::Embed( wxWidgetImpl
*parent
)
913 HIViewAddSubview((ControlRef
)parent
->GetWXWidget(), m_controlRef
);
916 void wxMacControl::SetNeedsDisplay( const wxRect
* rect
)
923 HIRect updatearea
= CGRectMake( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
924 HIViewSetNeedsDisplayInRect( m_controlRef
, &updatearea
, true );
927 HIViewSetNeedsDisplay( m_controlRef
, true );
930 void wxMacControl::Raise()
932 verify_noerr( HIViewSetZOrder( m_controlRef
, kHIViewZOrderAbove
, NULL
) );
935 void wxMacControl::Lower()
937 verify_noerr( HIViewSetZOrder( m_controlRef
, kHIViewZOrderBelow
, NULL
) );
940 void wxMacControl::GetContentArea(int &left
, int &top
, int &width
, int &height
) const
942 HIShapeRef rgn
= NULL
;
945 if ( HIViewCopyShape(m_controlRef
, kHIViewContentMetaPart
, &rgn
) == noErr
)
948 HIShapeGetBounds(rgn
, &cgrect
);
949 content
= (Rect
){ (short)cgrect
.origin
.y
,
950 (short)cgrect
.origin
.x
,
951 (short)(cgrect
.origin
.y
+cgrect
.size
.height
),
952 (short)(cgrect
.origin
.x
+cgrect
.size
.width
) };
957 GetControlBounds(m_controlRef
, &content
);
958 content
.right
-= content
.left
;
960 content
.bottom
-= content
.top
;
967 width
= content
.right
- content
.left
;
968 height
= content
.bottom
- content
.top
;
971 void wxMacControl::Move(int x
, int y
, int width
, int height
)
974 GetWindowAttributes( GetControlOwner(m_controlRef
) , &attr
) ;
976 HIRect hir
= CGRectMake(x
,y
,width
,height
);
977 if ( !(attr
& kWindowCompositingAttribute
) )
980 HIViewGetFrame( HIViewGetSuperview(m_controlRef
), &parent
);
981 hir
.origin
.x
+= parent
.origin
.x
;
982 hir
.origin
.y
+= parent
.origin
.y
;
984 HIViewSetFrame ( m_controlRef
, &hir
);
987 void wxMacControl::GetPosition( int &x
, int &y
) const
990 GetControlBounds( m_controlRef
, &r
);
995 GetWindowAttributes( GetControlOwner(m_controlRef
) , &attr
) ;
997 if ( !(attr
& kWindowCompositingAttribute
) )
1000 HIViewGetFrame( HIViewGetSuperview(m_controlRef
), &parent
);
1001 x
-= parent
.origin
.x
;
1002 y
-= parent
.origin
.y
;
1007 void wxMacControl::GetSize( int &width
, int &height
) const
1010 GetControlBounds( m_controlRef
, &r
);
1011 width
= r
.right
- r
.left
;
1012 height
= r
.bottom
- r
.top
;
1015 void wxMacControl::SetControlSize( wxWindowVariant variant
)
1020 case wxWINDOW_VARIANT_NORMAL
:
1021 size
= kControlSizeNormal
;
1024 case wxWINDOW_VARIANT_SMALL
:
1025 size
= kControlSizeSmall
;
1028 case wxWINDOW_VARIANT_MINI
:
1029 // not always defined in the headers
1033 case wxWINDOW_VARIANT_LARGE
:
1034 size
= kControlSizeLarge
;
1038 wxFAIL_MSG(wxT("unexpected window variant"));
1042 SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1045 void wxMacControl::ScrollRect( const wxRect
*rect
, int dx
, int dy
)
1047 if (GetNeedsDisplay() )
1049 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
1050 // in case there is already a pending redraw on that area
1051 // either immediate redraw or full invalidate
1053 // is the better overall solution, as it does not slow down scrolling
1056 // this would be the preferred version for fast drawing controls
1057 HIViewRender(GetControlRef()) ;
1061 // note there currently is a bug in OSX (10.3 +?) which makes inefficient refreshes in case an entire control
1062 // area is scrolled, this does not occur if width and height are 2 pixels less,
1063 // TODO: write optimal workaround
1065 HIRect scrollarea
= CGRectMake( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1066 HIViewScrollRect ( m_controlRef
, &scrollarea
, dx
,dy
);
1069 // this would be the preferred version for fast drawing controls
1070 HIViewRender(GetControlRef()) ;
1074 bool wxMacControl::CanFocus() const
1076 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1077 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1078 // but the value range is nowhere documented
1079 Boolean keyExistsAndHasValidFormat
;
1080 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1081 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1083 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1089 UInt32 features
= 0 ;
1090 GetControlFeatures( m_controlRef
, &features
) ;
1092 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1096 bool wxMacControl::GetNeedsDisplay() const
1098 return HIViewGetNeedsDisplay( m_controlRef
);
1101 void wxWidgetImpl::Convert( wxPoint
*pt
, wxWidgetImpl
*from
, wxWidgetImpl
*to
)
1107 HIViewConvertPoint( &hiPoint
, (ControlRef
) from
->GetWXWidget() , (ControlRef
) to
->GetWXWidget() );
1108 pt
->x
= (int)hiPoint
.x
;
1109 pt
->y
= (int)hiPoint
.y
;
1112 bool wxMacControl::SetFocus()
1114 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1115 // we can only leave in case of an error
1117 OSStatus err
= SetKeyboardFocus( GetControlOwner( m_controlRef
), m_controlRef
, kControlFocusNextPart
);
1118 if ( err
== errCouldntSetFocus
)
1120 SetUserFocusWindow(GetControlOwner( m_controlRef
) );
1125 bool wxMacControl::HasFocus() const
1128 GetKeyboardFocus( GetUserFocusWindow() , &control
);
1129 return control
== m_controlRef
;
1132 void wxMacControl::SetCursor(const wxCursor
& cursor
)
1134 wxWindowMac
*mouseWin
= 0 ;
1135 WindowRef window
= GetControlOwner( m_controlRef
) ;
1137 wxNonOwnedWindow
* tlwwx
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) window
) ;
1138 if ( tlwwx
!= NULL
)
1140 ControlPartCode part
;
1141 ControlRef control
;
1143 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1145 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1149 GetGlobalMouse( &pt
);
1152 tlwwx
->ScreenToClient(&x
, &y
);
1156 control
= FindControlUnderMouse( pt
, window
, &part
) ;
1158 mouseWin
= wxFindWindowFromWXWidget( (WXWidget
) control
) ;
1161 if ( mouseWin
== tlwwx
&& !wxIsBusy() )
1162 cursor
.MacInstall() ;
1165 void wxMacControl::CaptureMouse()
1169 void wxMacControl::ReleaseMouse()
1174 // subclass specifics
1177 OSStatus
wxMacControl::GetData(ControlPartCode inPartCode
, ResType inTag
, Size inBufferSize
, void * inOutBuffer
, Size
* outActualSize
) const
1179 return ::GetControlData( m_controlRef
, inPartCode
, inTag
, inBufferSize
, inOutBuffer
, outActualSize
);
1182 OSStatus
wxMacControl::GetDataSize(ControlPartCode inPartCode
, ResType inTag
, Size
* outActualSize
) const
1184 return ::GetControlDataSize( m_controlRef
, inPartCode
, inTag
, outActualSize
);
1187 OSStatus
wxMacControl::SetData(ControlPartCode inPartCode
, ResType inTag
, Size inSize
, const void * inData
)
1189 return ::SetControlData( m_controlRef
, inPartCode
, inTag
, inSize
, inData
);
1192 OSStatus
wxMacControl::SendEvent( EventRef event
, OptionBits inOptions
)
1194 return SendEventToEventTargetWithOptions( event
,
1195 HIObjectGetEventTarget( (HIObjectRef
) m_controlRef
), inOptions
);
1198 OSStatus
wxMacControl::SendHICommand( HICommand
&command
, OptionBits inOptions
)
1200 wxMacCarbonEvent
event( kEventClassCommand
, kEventCommandProcess
);
1202 event
.SetParameter
<HICommand
>(kEventParamDirectObject
,command
);
1204 return SendEvent( event
, inOptions
);
1207 OSStatus
wxMacControl::SendHICommand( UInt32 commandID
, OptionBits inOptions
)
1211 memset( &command
, 0 , sizeof(command
) );
1212 command
.commandID
= commandID
;
1213 return SendHICommand( command
, inOptions
);
1216 void wxMacControl::PerformClick()
1218 HIViewSimulateClick (m_controlRef
, kControlButtonPart
, 0, NULL
);
1221 wxInt32
wxMacControl::GetValue() const
1223 return ::GetControl32BitValue( m_controlRef
);
1226 wxInt32
wxMacControl::GetMaximum() const
1228 return ::GetControl32BitMaximum( m_controlRef
);
1231 wxInt32
wxMacControl::GetMinimum() const
1233 return ::GetControl32BitMinimum( m_controlRef
);
1236 void wxMacControl::SetValue( wxInt32 v
)
1238 ::SetControl32BitValue( m_controlRef
, v
);
1241 void wxMacControl::SetMinimum( wxInt32 v
)
1243 ::SetControl32BitMinimum( m_controlRef
, v
);
1246 void wxMacControl::SetMaximum( wxInt32 v
)
1248 ::SetControl32BitMaximum( m_controlRef
, v
);
1251 void wxMacControl::SetValueAndRange( SInt32 value
, SInt32 minimum
, SInt32 maximum
)
1253 ::SetControl32BitMinimum( m_controlRef
, minimum
);
1254 ::SetControl32BitMaximum( m_controlRef
, maximum
);
1255 ::SetControl32BitValue( m_controlRef
, value
);
1258 void wxMacControl::VisibilityChanged(bool WXUNUSED(shown
))
1262 void wxMacControl::SuperChangedPosition()
1266 void wxMacControl::SetFont( const wxFont
& font
, const wxColour
& foreground
, long windowStyle
, bool ignoreBlack
)
1269 #if wxOSX_USE_CORE_TEXT
1270 if ( UMAGetSystemVersion() >= 0x1050 )
1272 HIViewPartCode part
= 0;
1273 HIThemeTextHorizontalFlush flush
= kHIThemeTextHorizontalFlushDefault
;
1274 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1275 flush
= kHIThemeTextHorizontalFlushCenter
;
1276 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1277 flush
= kHIThemeTextHorizontalFlushRight
;
1278 HIViewSetTextFont( m_controlRef
, part
, (CTFontRef
) font
.OSXGetCTFont() );
1279 HIViewSetTextHorizontalFlush( m_controlRef
, part
, flush
);
1281 if ( foreground
!= *wxBLACK
|| ignoreBlack
== false )
1283 ControlFontStyleRec fontStyle
;
1284 foreground
.GetRGBColor( &fontStyle
.foreColor
);
1285 fontStyle
.flags
= kControlUseForeColorMask
;
1286 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1290 #if wxOSX_USE_ATSU_TEXT
1291 ControlFontStyleRec fontStyle
;
1292 if ( font
.MacGetThemeFontID() != kThemeCurrentPortFont
)
1294 switch ( font
.MacGetThemeFontID() )
1296 case kThemeSmallSystemFont
:
1297 fontStyle
.font
= kControlFontSmallSystemFont
;
1300 case 109 : // mini font
1301 fontStyle
.font
= -5;
1304 case kThemeSystemFont
:
1305 fontStyle
.font
= kControlFontBigSystemFont
;
1309 fontStyle
.font
= kControlFontBigSystemFont
;
1313 fontStyle
.flags
= kControlUseFontMask
;
1317 fontStyle
.font
= font
.MacGetFontNum();
1318 fontStyle
.style
= font
.MacGetFontStyle();
1319 fontStyle
.size
= font
.GetPointSize();
1320 fontStyle
.flags
= kControlUseFontMask
| kControlUseFaceMask
| kControlUseSizeMask
;
1323 fontStyle
.just
= teJustLeft
;
1324 fontStyle
.flags
|= kControlUseJustMask
;
1325 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1326 fontStyle
.just
= teJustCenter
;
1327 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1328 fontStyle
.just
= teJustRight
;
1331 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
1332 // won't get grayed out by the system anymore
1334 if ( foreground
!= *wxBLACK
|| ignoreBlack
== false )
1336 foreground
.GetRGBColor( &fontStyle
.foreColor
);
1337 fontStyle
.flags
|= kControlUseForeColorMask
;
1340 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1344 void wxMacControl::SetBackgroundColour( const wxColour
&WXUNUSED(col
) )
1346 // HITextViewSetBackgroundColor( m_textView , color );
1349 bool wxMacControl::SetBackgroundStyle(wxBackgroundStyle style
)
1351 if ( style
!= wxBG_STYLE_PAINT
)
1353 OSStatus err
= HIViewChangeFeatures(m_controlRef
, 0 , kHIViewIsOpaque
);
1354 verify_noerr( err
);
1358 OSStatus err
= HIViewChangeFeatures(m_controlRef
, kHIViewIsOpaque
, 0);
1359 verify_noerr( err
);
1365 void wxMacControl::SetRange( SInt32 minimum
, SInt32 maximum
)
1367 ::SetControl32BitMinimum( m_controlRef
, minimum
);
1368 ::SetControl32BitMaximum( m_controlRef
, maximum
);
1371 short wxMacControl::HandleKey( SInt16 keyCode
, SInt16 charCode
, EventModifiers modifiers
)
1373 return HandleControlKey( m_controlRef
, keyCode
, charCode
, modifiers
);
1376 void wxMacControl::SetActionProc( ControlActionUPP actionProc
)
1378 SetControlAction( m_controlRef
, actionProc
);
1381 SInt32
wxMacControl::GetViewSize() const
1383 return GetControlViewSize( m_controlRef
);
1386 bool wxMacControl::IsVisible() const
1388 return IsControlVisible( m_controlRef
);
1391 void wxMacControl::SetVisibility( bool visible
)
1393 SetControlVisibility( m_controlRef
, visible
, true );
1396 bool wxMacControl::IsEnabled() const
1398 return IsControlEnabled( m_controlRef
);
1401 bool wxMacControl::IsActive() const
1403 return IsControlActive( m_controlRef
);
1406 void wxMacControl::Enable( bool enable
)
1409 EnableControl( m_controlRef
);
1411 DisableControl( m_controlRef
);
1414 void wxMacControl::SetDrawingEnabled( bool enable
)
1416 HIViewSetDrawingEnabled( m_controlRef
, enable
);
1419 void wxMacControl::GetRectInWindowCoords( Rect
*r
)
1421 GetControlBounds( m_controlRef
, r
) ;
1423 WindowRef tlwref
= GetControlOwner( m_controlRef
) ;
1425 wxNonOwnedWindow
* tlwwx
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) tlwref
) ;
1426 if ( tlwwx
!= NULL
)
1428 ControlRef rootControl
= tlwwx
->GetPeer()->GetControlRef() ;
1429 HIPoint hiPoint
= CGPointMake( 0 , 0 ) ;
1430 HIViewConvertPoint( &hiPoint
, HIViewGetSuperview(m_controlRef
) , rootControl
) ;
1431 OffsetRect( r
, (short) hiPoint
.x
, (short) hiPoint
.y
) ;
1435 void wxMacControl::GetBestRect( wxRect
*rect
) const
1437 short baselineoffset
;
1440 GetBestControlRect( m_controlRef
, &r
, &baselineoffset
);
1441 *rect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
-r
.top
);
1444 void wxMacControl::GetBestRect( Rect
*r
) const
1446 short baselineoffset
;
1447 GetBestControlRect( m_controlRef
, r
, &baselineoffset
);
1450 void wxMacControl::SetLabel( const wxString
&title
, wxFontEncoding encoding
)
1452 SetControlTitleWithCFString( m_controlRef
, wxCFStringRef( title
, encoding
) );
1455 void wxMacControl::GetFeatures( UInt32
* features
)
1457 GetControlFeatures( m_controlRef
, features
);
1460 void wxMacControl::PulseGauge()
1464 // SetNeedsDisplay would not invalidate the children
1465 static void InvalidateControlAndChildren( HIViewRef control
)
1467 HIViewSetNeedsDisplay( control
, true );
1468 UInt16 childrenCount
= 0;
1469 OSStatus err
= CountSubControls( control
, &childrenCount
);
1470 if ( err
== errControlIsNotEmbedder
)
1473 wxASSERT_MSG( err
== noErr
, wxT("Unexpected error when accessing subcontrols") );
1475 for ( UInt16 i
= childrenCount
; i
>=1; --i
)
1479 err
= GetIndexedSubControl( control
, i
, & child
);
1480 if ( err
== errControlIsNotEmbedder
)
1483 InvalidateControlAndChildren( child
);
1487 void wxMacControl::InvalidateWithChildren()
1489 InvalidateControlAndChildren( m_controlRef
);
1492 OSType wxMacCreator
= 'WXMC';
1493 OSType wxMacControlProperty
= 'MCCT';
1495 void wxMacControl::SetReferenceInNativeControl()
1498 verify_noerr( SetControlProperty ( m_controlRef
,
1499 wxMacCreator
,wxMacControlProperty
, sizeof(data
), &data
) );
1502 wxMacControl
* wxMacControl::GetReferenceFromNativeControl(ControlRef control
)
1504 wxMacControl
* ctl
= NULL
;
1505 ByteCount actualSize
;
1506 if ( GetControlProperty( control
,wxMacCreator
,wxMacControlProperty
, sizeof(ctl
) ,
1507 &actualSize
, &ctl
) == noErr
)
1514 wxBitmap
wxMacControl::GetBitmap() const
1516 return wxNullBitmap
;
1519 void wxMacControl::SetBitmap( const wxBitmap
& WXUNUSED(bmp
) )
1521 // implemented in the respective subclasses
1524 void wxMacControl::SetBitmapPosition( wxDirection
WXUNUSED(dir
) )
1526 // implemented in the same subclasses that implement SetBitmap()
1529 void wxMacControl::SetScrollThumb( wxInt32
WXUNUSED(pos
), wxInt32
WXUNUSED(viewsize
) )
1531 // implemented in respective subclass
1538 OSStatus
wxMacControl::SetTabEnabled( SInt16 tabNo
, bool enable
)
1540 return ::SetTabEnabled( m_controlRef
, tabNo
, enable
);
1547 wxWidgetImplType
* wxWidgetImpl::CreateContentView( wxNonOwnedWindow
* now
)
1549 // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of
1550 // the content view, so we have to retrieve it explicitly
1552 wxMacControl
* contentview
= new wxMacControl(now
, true /*isRootControl*/);
1553 HIViewFindByID( HIViewGetRoot( (WindowRef
) now
->GetWXWindow() ) , kHIViewWindowContentID
,
1554 contentview
->GetControlRefAddr() ) ;
1555 if ( !contentview
->IsOk() )
1557 // compatibility mode fallback
1558 GetRootControl( (WindowRef
) now
->GetWXWindow() , contentview
->GetControlRefAddr() ) ;
1561 // the root control level handler
1562 if ( !now
->IsNativeWindowWrapper() )
1563 contentview
->InstallEventHandler() ;