1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/window.cpp
3 // Purpose: wxWindowMac
4 // Author: Stefan Csomor
7 // Copyright: (c) Stefan Csomor
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 #include "wx/wxprec.h"
13 #include "wx/window.h"
22 #include "wx/dcclient.h"
23 #include "wx/button.h"
25 #include "wx/dialog.h"
26 #include "wx/settings.h"
27 #include "wx/msgdlg.h"
28 #include "wx/scrolbar.h"
29 #include "wx/statbox.h"
30 #include "wx/textctrl.h"
31 #include "wx/toolbar.h"
32 #include "wx/layout.h"
33 #include "wx/statusbr.h"
34 #include "wx/menuitem.h"
35 #include "wx/treectrl.h"
36 #include "wx/listctrl.h"
39 #include "wx/tooltip.h"
40 #include "wx/spinctrl.h"
41 #include "wx/geometry.h"
44 #include "wx/listctrl.h"
48 #include "wx/treectrl.h"
56 #include "wx/popupwin.h"
59 #if wxUSE_DRAG_AND_DROP
64 #include "wx/osx/uma.h"
66 #include "wx/osx/private.h"
68 #include <Carbon/Carbon.h>
71 #define MAC_SCROLLBAR_SIZE 15
72 #define MAC_SMALL_SCROLLBAR_SIZE 11
76 #define wxMAC_DEBUG_REDRAW 0
77 #ifndef wxMAC_DEBUG_REDRAW
78 #define wxMAC_DEBUG_REDRAW 0
81 // Get the window with the focus
82 WXWidget
wxWidgetImpl::FindFocus()
84 ControlRef control
= NULL
;
85 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
89 // no compositing to take into account under carbon
90 wxWidgetImpl
* wxWidgetImpl::FindBestFromWXWidget(WXWidget control
)
92 return FindFromWXWidget(control
);
95 // ---------------------------------------------------------------------------
97 // ---------------------------------------------------------------------------
99 static const EventTypeSpec eventList
[] =
101 { kEventClassCommand
, kEventProcessCommand
} ,
102 { kEventClassCommand
, kEventCommandUpdateStatus
} ,
104 { kEventClassControl
, kEventControlGetClickActivation
} ,
105 { kEventClassControl
, kEventControlHit
} ,
107 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
108 { kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
} ,
110 { kEventClassControl
, kEventControlDraw
} ,
112 { kEventClassControl
, kEventControlVisibilityChanged
} ,
113 { kEventClassControl
, kEventControlEnabledStateChanged
} ,
114 { kEventClassControl
, kEventControlHiliteChanged
} ,
116 { kEventClassControl
, kEventControlActivate
} ,
117 { kEventClassControl
, kEventControlDeactivate
} ,
119 { kEventClassControl
, kEventControlSetFocusPart
} ,
120 { kEventClassControl
, kEventControlFocusPartChanged
} ,
122 { kEventClassService
, kEventServiceGetTypes
},
123 { kEventClassService
, kEventServiceCopy
},
124 { kEventClassService
, kEventServicePaste
},
126 // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
127 // { kEventClassControl , kEventControlBoundsChanged } ,
130 static pascal OSStatus
wxMacWindowControlEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
132 OSStatus result
= eventNotHandledErr
;
133 static wxWindowMac
* targetFocusWindow
= NULL
;
134 static wxWindowMac
* formerFocusWindow
= NULL
;
136 wxMacCarbonEvent
cEvent( event
) ;
138 ControlRef controlRef
;
139 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
141 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
143 switch ( GetEventKind( event
) )
145 case kEventControlDraw
:
147 HIShapeRef updateRgn
= NULL
;
148 HIMutableShapeRef allocatedRgn
= NULL
;
149 wxRegion visRegion
= thisWindow
->MacGetVisibleRegion() ;
151 // according to the docs: redraw entire control if param not present
152 if ( cEvent
.GetParameter
<HIShapeRef
>(kEventParamShape
, &updateRgn
) != noErr
)
154 updateRgn
= visRegion
.GetWXHRGN();
158 if ( thisWindow
->MacGetLeftBorderSize() != 0 || thisWindow
->MacGetTopBorderSize() != 0 )
160 // as this update region is in native window locals we must adapt it to wx window local
161 allocatedRgn
= HIShapeCreateMutableCopy(updateRgn
);
162 HIShapeOffset(allocatedRgn
, thisWindow
->MacGetLeftBorderSize() , thisWindow
->MacGetTopBorderSize());
163 // hide the given region by the new region that must be shifted
164 updateRgn
= allocatedRgn
;
168 #if wxMAC_DEBUG_REDRAW
169 if ( thisWindow
->MacIsUserPane() )
171 static float color
= 0.5 ;
172 static int channel
= 0 ;
174 CGContextRef cgContext
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
) ;
176 HIViewGetBounds( controlRef
, &bounds
);
177 CGContextSetRGBFillColor( cgContext
, channel
== 0 ? color
: 0.5 ,
178 channel
== 1 ? color
: 0.5 , channel
== 2 ? color
: 0.5 , 1 );
179 CGContextFillRect( cgContext
, bounds
);
192 CGContextRef cgContext
= NULL
;
193 OSStatus err
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
, &cgContext
) ;
196 // for non-composite drawing, since we don't support it ourselves, send it through the
197 // the default handler
198 // CallNextEventHandler( handler,event ) ;
201 CFRelease( allocatedRgn
) ;
205 thisWindow
->MacSetCGContextRef( cgContext
) ;
208 wxMacCGContextStateSaver
sg( cgContext
) ;
209 CGFloat alpha
= (CGFloat
)1.0 ;
211 wxWindow
* iter
= thisWindow
;
214 alpha
*= (CGFloat
)( iter
->GetTransparent()/255.0 ) ;
215 if ( iter
->IsTopLevel() )
218 iter
= iter
->GetParent() ;
221 CGContextSetAlpha( cgContext
, alpha
) ;
223 if ( thisWindow
->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
226 HIViewGetBounds( controlRef
, &bounds
);
227 CGContextClearRect( cgContext
, bounds
);
230 if ( !HIShapeIsEmpty(updateRgn
) )
232 // refcount increase because wxRegion constructor takes ownership of the native region
234 thisWindow
->GetUpdateRegion() = wxRegion(updateRgn
);
235 if ( !thisWindow
->MacDoRedraw( cEvent
.GetTicks() ) )
237 // for native controls: call their native paint method
238 if ( !thisWindow
->MacIsUserPane() ||
239 ( thisWindow
->IsTopLevel() && thisWindow
->GetBackgroundStyle() == wxBG_STYLE_SYSTEM
) )
241 if ( thisWindow
->GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT
)
243 CallNextEventHandler( handler
,event
) ;
252 thisWindow
->MacPaintChildrenBorders();
254 thisWindow
->MacSetCGContextRef( NULL
) ;
259 CFRelease( allocatedRgn
) ;
263 case kEventControlVisibilityChanged
:
264 // we might have two native controls attributed to the same wxWindow instance
265 // eg a scrollview and an embedded textview, make sure we only fire for the 'outer'
266 // control, as otherwise native and wx visibility are different
267 if ( thisWindow
->GetPeer() != NULL
&& thisWindow
->GetPeer()->GetControlRef() == controlRef
)
269 thisWindow
->MacVisibilityChanged() ;
273 case kEventControlEnabledStateChanged
:
274 thisWindow
->MacEnabledStateChanged();
277 case kEventControlHiliteChanged
:
278 thisWindow
->MacHiliteChanged() ;
281 case kEventControlActivate
:
282 case kEventControlDeactivate
:
283 // FIXME: we should have a virtual function for this!
285 if ( thisWindow
->IsKindOf( CLASSINFO( wxTreeCtrl
) ) )
286 thisWindow
->Refresh();
289 if ( thisWindow
->IsKindOf( CLASSINFO( wxListCtrl
) ) )
290 thisWindow
->Refresh();
296 // different handling on OS X
299 case kEventControlFocusPartChanged
:
300 // the event is emulated by wxmac for systems lower than 10.5
302 if ( UMAGetSystemVersion() < 0x1050 )
304 // as it is synthesized here, we have to manually avoid propagation
307 ControlPartCode previousControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPreviousPart
, typeControlPartCode
);
308 ControlPartCode currentControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlCurrentPart
, typeControlPartCode
);
310 if ( thisWindow
->MacGetTopLevelWindow() && thisWindow
->GetPeer()->NeedsFocusRect() )
312 thisWindow
->MacInvalidateBorders();
315 if ( currentControlPart
== 0 )
319 if ( thisWindow
->GetCaret() )
320 thisWindow
->GetCaret()->OnKillFocus();
323 wxLogTrace(wxT("Focus"), wxT("focus lost(%p)"), static_cast<void*>(thisWindow
));
325 // remove this as soon as posting the synthesized event works properly
326 static bool inKillFocusEvent
= false ;
328 if ( !inKillFocusEvent
)
330 inKillFocusEvent
= true ;
331 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
332 event
.SetEventObject(thisWindow
);
333 event
.SetWindow(targetFocusWindow
);
334 thisWindow
->HandleWindowEvent(event
) ;
335 inKillFocusEvent
= false ;
336 targetFocusWindow
= NULL
;
339 else if ( previousControlPart
== 0 )
342 // panel wants to track the window which was the last to have focus in it
343 wxLogTrace(wxT("Focus"), wxT("focus set(%p)"), static_cast<void*>(thisWindow
));
344 wxChildFocusEvent
eventFocus((wxWindow
*)thisWindow
);
345 thisWindow
->HandleWindowEvent(eventFocus
);
348 if ( thisWindow
->GetCaret() )
349 thisWindow
->GetCaret()->OnSetFocus();
352 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
353 event
.SetEventObject(thisWindow
);
354 event
.SetWindow(formerFocusWindow
);
355 thisWindow
->HandleWindowEvent(event
) ;
356 formerFocusWindow
= NULL
;
360 case kEventControlSetFocusPart
:
362 Boolean focusEverything
= false ;
363 if ( cEvent
.GetParameter
<Boolean
>(kEventParamControlFocusEverything
, &focusEverything
) == noErr
)
365 // put a breakpoint here to catch focus everything events
367 ControlPartCode controlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
368 if ( controlPart
!= kControlFocusNoPart
)
370 targetFocusWindow
= thisWindow
;
371 wxLogTrace(wxT("Focus"), wxT("focus to be set(%p)"), static_cast<void*>(thisWindow
));
375 formerFocusWindow
= thisWindow
;
376 wxLogTrace(wxT("Focus"), wxT("focus to be lost(%p)"), static_cast<void*>(thisWindow
));
379 ControlPartCode previousControlPart
= 0;
380 verify_noerr( HIViewGetFocusPart(controlRef
, &previousControlPart
));
382 if ( thisWindow
->MacIsUserPane() )
384 if ( controlPart
!= kControlFocusNoPart
)
385 cEvent
.SetParameter
<ControlPartCode
>( kEventParamControlPart
, typeControlPartCode
, 1 ) ;
389 result
= CallNextEventHandler(handler
, event
);
391 if ( UMAGetSystemVersion() < 0x1050 )
393 // set back to 0 if problems arise
395 if ( result
== noErr
)
397 ControlPartCode currentControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
398 // synthesize the event focus changed event
399 EventRef evRef
= NULL
;
401 OSStatus err
= MacCreateEvent(
402 NULL
, kEventClassControl
, kEventControlFocusPartChanged
, TicksToEventTime( TickCount() ) ,
403 kEventAttributeUserEvent
, &evRef
);
406 wxMacCarbonEvent
iEvent( evRef
) ;
407 iEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, controlRef
);
408 iEvent
.SetParameter
<EventTargetRef
>( kEventParamPostTarget
, typeEventTargetRef
, GetControlEventTarget( controlRef
) );
409 iEvent
.SetParameter
<ControlPartCode
>( kEventParamControlPreviousPart
, typeControlPartCode
, previousControlPart
);
410 iEvent
.SetParameter
<ControlPartCode
>( kEventParamControlCurrentPart
, typeControlPartCode
, currentControlPart
);
413 // TODO test this first, avoid double posts etc...
414 PostEventToQueue( GetMainEventQueue(), evRef
, kEventPriorityHigh
);
416 wxMacWindowControlEventHandler( NULL
, evRef
, data
) ;
418 ReleaseEvent( evRef
) ;
421 // old implementation, to be removed if the new one works
422 if ( controlPart
== kControlFocusNoPart
)
425 if ( thisWindow
->GetCaret() )
426 thisWindow
->GetCaret()->OnKillFocus();
429 wxLogTrace(wxT("Focus"), wxT("focus lost(%p)"), static_cast<void*>(thisWindow
));
431 static bool inKillFocusEvent
= false ;
433 if ( !inKillFocusEvent
)
435 inKillFocusEvent
= true ;
436 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
437 event
.SetEventObject(thisWindow
);
438 thisWindow
->HandleWindowEvent(event
) ;
439 inKillFocusEvent
= false ;
444 // panel wants to track the window which was the last to have focus in it
445 wxLogTrace(wxT("Focus"), wxT("focus set(%p)"), static_cast<void*>(thisWindow
));
446 wxChildFocusEvent
eventFocus((wxWindow
*)thisWindow
);
447 thisWindow
->HandleWindowEvent(eventFocus
);
450 if ( thisWindow
->GetCaret() )
451 thisWindow
->GetCaret()->OnSetFocus();
454 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
455 event
.SetEventObject(thisWindow
);
456 thisWindow
->HandleWindowEvent(event
) ;
463 case kEventControlHit
:
464 result
= thisWindow
->MacControlHit( handler
, event
) ;
467 case kEventControlGetClickActivation
:
469 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
470 WindowRef owner
= cEvent
.GetParameter
<WindowRef
>(kEventParamWindowRef
);
471 if ( !IsWindowActive(owner
) )
473 cEvent
.SetParameter(kEventParamClickActivation
,typeClickActivationResult
, (UInt32
) kActivateAndIgnoreClick
) ;
486 static pascal OSStatus
487 wxMacWindowServiceEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
491 OSStatus result
= eventNotHandledErr
;
493 wxMacCarbonEvent
cEvent( event
) ;
495 ControlRef controlRef
;
496 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
497 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
498 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
500 switch ( GetEventKind( event
) )
502 case kEventServiceGetTypes
:
506 textCtrl
->GetSelection( &from
, &to
) ;
508 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
510 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
511 if ( textCtrl
->IsEditable() )
512 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
514 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
515 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
517 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
521 CFArrayAppendValue(copyTypes
, typestring
) ;
523 CFArrayAppendValue(pasteTypes
, typestring
) ;
525 CFRelease( typestring
) ;
533 case kEventServiceCopy
:
538 textCtrl
->GetSelection( &from
, &to
) ;
539 wxString val
= textCtrl
->GetValue() ;
540 val
= val
.Mid( from
, to
- from
) ;
541 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
542 verify_noerr( PasteboardClear( pasteboard
) ) ;
543 PasteboardSynchronize( pasteboard
);
544 // TODO add proper conversion
545 CFDataRef data
= CFDataCreate( kCFAllocatorDefault
, (const UInt8
*)val
.c_str(), val
.length() );
546 PasteboardPutItemFlavor( pasteboard
, (PasteboardItemID
) 1, CFSTR("com.apple.traditional-mac-plain-text"), data
, 0);
552 case kEventServicePaste
:
555 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
556 PasteboardSynchronize( pasteboard
);
558 verify_noerr( PasteboardGetItemCount( pasteboard
, &itemCount
) );
559 for( UInt32 itemIndex
= 1; itemIndex
<= itemCount
; itemIndex
++ )
561 PasteboardItemID itemID
;
562 if ( PasteboardGetItemIdentifier( pasteboard
, itemIndex
, &itemID
) == noErr
)
564 CFDataRef flavorData
= NULL
;
565 if ( PasteboardCopyItemFlavorData( pasteboard
, itemID
, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData
) == noErr
)
567 CFIndex flavorDataSize
= CFDataGetLength( flavorData
);
568 char *content
= new char[flavorDataSize
+1] ;
569 memcpy( content
, CFDataGetBytePtr( flavorData
), flavorDataSize
);
570 content
[flavorDataSize
]=0;
571 CFRelease( flavorData
);
573 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
575 textCtrl
->WriteText( wxString( content
) ) ;
593 WXDLLEXPORT
pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
595 OSStatus result
= eventNotHandledErr
;
596 wxWindowMac
* focus
= (wxWindowMac
*) data
;
598 wchar_t* uniChars
= NULL
;
599 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
601 UniChar
* charBuf
= NULL
;
602 ByteCount dataSize
= 0 ;
605 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
607 numChars
= dataSize
/ sizeof( UniChar
) + 1;
610 if ( (size_t) numChars
* 2 > sizeof(buf
) )
611 charBuf
= new UniChar
[ numChars
] ;
615 uniChars
= new wchar_t[ numChars
] ;
616 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
617 charBuf
[ numChars
- 1 ] = 0;
618 // the resulting string will never have more chars than the utf16 version, so this is safe
619 wxMBConvUTF16 converter
;
620 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( focus
, message
, 0 , when
, uniChars
[pos
] ) )
666 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
670 case kEventTextInputUnicodeForKeyEvent
:
672 UInt32 keyCode
, modifiers
;
674 unsigned char charCode
;
676 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
677 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, 1, NULL
, &charCode
);
678 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
679 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
681 UInt32 message
= (keyCode
<< 8) + charCode
;
683 // An IME input event may return several characters, but we need to send one char at a time to
685 for (int pos
=0 ; pos
< numChars
; pos
++)
687 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
688 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
689 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
691 if ( wxTheApp
->MacSendCharEvent( focus
, message
, modifiers
, when
, uniChars
[pos
] ) )
696 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
705 if ( charBuf
!= buf
)
711 static pascal OSStatus
712 wxMacWindowCommandEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
716 OSStatus result
= eventNotHandledErr
;
717 wxWindowMac
* focus
= (wxWindowMac
*) data
;
721 wxMacCarbonEvent
cEvent( event
) ;
722 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
724 wxMenuItem
* item
= NULL
;
725 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
729 wxASSERT( itemMenu
!= NULL
) ;
731 switch ( cEvent
.GetKind() )
733 case kEventProcessCommand
:
734 if ( itemMenu
->HandleCommandProcess( item
, focus
) )
738 case kEventCommandUpdateStatus
:
739 if ( itemMenu
->HandleCommandUpdateStatus( item
, focus
) )
750 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
752 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
753 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
754 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
755 OSStatus result
= eventNotHandledErr
;
757 switch ( GetEventClass( event
) )
759 case kEventClassCommand
:
760 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
763 case kEventClassControl
:
764 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
767 case kEventClassService
:
768 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
771 case kEventClassTextInput
:
772 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
779 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
784 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
786 // ---------------------------------------------------------------------------
787 // Scrollbar Tracking for all
788 // ---------------------------------------------------------------------------
790 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
791 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
795 wxWindow
* wx
= wxFindWindowFromWXWidget( (WXWidget
) control
) ;
798 wxEventType scrollEvent
= wxEVT_NULL
;
801 case kControlUpButtonPart
:
802 scrollEvent
= wxEVT_SCROLL_LINEUP
;
805 case kControlDownButtonPart
:
806 scrollEvent
= wxEVT_SCROLL_LINEDOWN
;
809 case kControlPageUpPart
:
810 scrollEvent
= wxEVT_SCROLL_PAGEUP
;
813 case kControlPageDownPart
:
814 scrollEvent
= wxEVT_SCROLL_PAGEDOWN
;
817 case kControlIndicatorPart
:
818 scrollEvent
= wxEVT_SCROLL_THUMBTRACK
;
819 // when this is called as a live proc, mouse is always still down
820 // so no need for thumbrelease
821 // scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
824 wx
->TriggerScrollEvent(scrollEvent
) ;
828 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
830 wxWidgetImplType
* wxWidgetImpl::CreateUserPane( wxWindowMac
* wxpeer
,
831 wxWindowMac
* WXUNUSED(parent
),
832 wxWindowID
WXUNUSED(id
),
835 long WXUNUSED(style
),
836 long WXUNUSED(extraStyle
))
838 OSStatus err
= noErr
;
839 Rect bounds
= wxMacGetBoundsForControl( wxpeer
, pos
, size
) ;
840 wxMacControl
* c
= new wxMacControl(wxpeer
, false, true) ;
842 | kControlSupportsEmbedding
843 | kControlSupportsLiveFeedback
844 | kControlGetsFocusOnClick
845 // | kControlHasSpecialBackground
846 // | kControlSupportsCalcBestRect
847 | kControlHandlesTracking
848 | kControlSupportsFocus
849 | kControlWantsActivate
850 | kControlWantsIdle
;
852 err
=::CreateUserPaneControl( MAC_WXHWND(wxpeer
->GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, c
->GetControlRefAddr() );
858 void wxMacControl::InstallEventHandler( WXWidget control
)
860 wxWidgetImpl::Associate( control
? control
: (WXWidget
) m_controlRef
, this ) ;
861 ::InstallControlEventHandler( control
? (ControlRef
) control
: m_controlRef
, GetwxMacWindowEventHandlerUPP(),
862 GetEventTypeCount(eventList
), eventList
, GetWXPeer(), NULL
);
865 IMPLEMENT_DYNAMIC_CLASS( wxMacControl
, wxWidgetImpl
)
867 wxMacControl::wxMacControl()
872 wxMacControl::wxMacControl(wxWindowMac
* peer
, bool isRootControl
, bool isUserPane
) :
873 wxWidgetImpl( peer
, isRootControl
, isUserPane
)
878 wxMacControl::~wxMacControl()
880 if ( m_controlRef
&& !IsRootControl() )
882 wxASSERT_MSG( m_controlRef
!= NULL
, wxT("Control Handle already NULL, Dispose called twice ?") );
883 wxASSERT_MSG( IsValidControlHandle(m_controlRef
) , wxT("Invalid Control Handle (maybe already released) in Dispose") );
885 wxWidgetImpl::RemoveAssociations( this ) ;
886 // we cannot check the ref count here anymore, as autorelease objects might delete their refs later
887 // we can have situations when being embedded, where the control gets deleted behind our back, so only
888 // CFRelease if we are safe
889 if ( IsValidControlHandle(m_controlRef
) )
890 CFRelease(m_controlRef
);
895 void wxMacControl::Init()
898 m_macControlEventHandler
= NULL
;
901 void wxMacControl::RemoveFromParent()
903 // nothing to do here for carbon
904 HIViewRemoveFromSuperview(m_controlRef
);
907 void wxMacControl::Embed( wxWidgetImpl
*parent
)
909 HIViewAddSubview((ControlRef
)parent
->GetWXWidget(), m_controlRef
);
912 void wxMacControl::SetNeedsDisplay( const wxRect
* rect
)
919 HIRect updatearea
= CGRectMake( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
920 HIViewSetNeedsDisplayInRect( m_controlRef
, &updatearea
, true );
923 HIViewSetNeedsDisplay( m_controlRef
, true );
926 void wxMacControl::Raise()
928 verify_noerr( HIViewSetZOrder( m_controlRef
, kHIViewZOrderAbove
, NULL
) );
931 void wxMacControl::Lower()
933 verify_noerr( HIViewSetZOrder( m_controlRef
, kHIViewZOrderBelow
, NULL
) );
936 void wxMacControl::GetContentArea(int &left
, int &top
, int &width
, int &height
) const
938 HIShapeRef rgn
= NULL
;
941 if ( HIViewCopyShape(m_controlRef
, kHIViewContentMetaPart
, &rgn
) == noErr
)
944 HIShapeGetBounds(rgn
, &cgrect
);
945 content
= (Rect
){ (short)cgrect
.origin
.y
,
946 (short)cgrect
.origin
.x
,
947 (short)(cgrect
.origin
.y
+cgrect
.size
.height
),
948 (short)(cgrect
.origin
.x
+cgrect
.size
.width
) };
953 GetControlBounds(m_controlRef
, &content
);
954 content
.right
-= content
.left
;
956 content
.bottom
-= content
.top
;
963 width
= content
.right
- content
.left
;
964 height
= content
.bottom
- content
.top
;
967 void wxMacControl::Move(int x
, int y
, int width
, int height
)
970 GetWindowAttributes( GetControlOwner(m_controlRef
) , &attr
) ;
972 HIRect hir
= CGRectMake(x
,y
,width
,height
);
973 if ( !(attr
& kWindowCompositingAttribute
) )
976 HIViewGetFrame( HIViewGetSuperview(m_controlRef
), &parent
);
977 hir
.origin
.x
+= parent
.origin
.x
;
978 hir
.origin
.y
+= parent
.origin
.y
;
980 HIViewSetFrame ( m_controlRef
, &hir
);
983 void wxMacControl::GetPosition( int &x
, int &y
) const
986 GetControlBounds( m_controlRef
, &r
);
991 GetWindowAttributes( GetControlOwner(m_controlRef
) , &attr
) ;
993 if ( !(attr
& kWindowCompositingAttribute
) )
996 HIViewGetFrame( HIViewGetSuperview(m_controlRef
), &parent
);
997 x
-= (int)parent
.origin
.x
;
998 y
-= (int)parent
.origin
.y
;
1003 void wxMacControl::GetSize( int &width
, int &height
) const
1006 GetControlBounds( m_controlRef
, &r
);
1007 width
= r
.right
- r
.left
;
1008 height
= r
.bottom
- r
.top
;
1011 void wxMacControl::SetControlSize( wxWindowVariant variant
)
1016 case wxWINDOW_VARIANT_NORMAL
:
1017 size
= kControlSizeNormal
;
1020 case wxWINDOW_VARIANT_SMALL
:
1021 size
= kControlSizeSmall
;
1024 case wxWINDOW_VARIANT_MINI
:
1025 // not always defined in the headers
1029 case wxWINDOW_VARIANT_LARGE
:
1030 size
= kControlSizeLarge
;
1034 wxFAIL_MSG(wxT("unexpected window variant"));
1038 SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1041 void wxMacControl::ScrollRect( const wxRect
*rect
, int dx
, int dy
)
1043 if (GetNeedsDisplay() )
1045 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
1046 // in case there is already a pending redraw on that area
1047 // either immediate redraw or full invalidate
1049 // is the better overall solution, as it does not slow down scrolling
1052 // this would be the preferred version for fast drawing controls
1053 HIViewRender(GetControlRef()) ;
1057 // note there currently is a bug in OSX (10.3 +?) which makes inefficient refreshes in case an entire control
1058 // area is scrolled, this does not occur if width and height are 2 pixels less,
1059 // TODO: write optimal workaround
1061 HIRect scrollarea
= CGRectMake( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1062 HIViewScrollRect ( m_controlRef
, &scrollarea
, dx
,dy
);
1065 // this would be the preferred version for fast drawing controls
1066 HIViewRender(GetControlRef()) ;
1070 bool wxMacControl::CanFocus() const
1072 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1073 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1074 // but the value range is nowhere documented
1075 Boolean keyExistsAndHasValidFormat
;
1076 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1077 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1079 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1085 UInt32 features
= 0 ;
1086 GetControlFeatures( m_controlRef
, &features
) ;
1088 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1092 bool wxMacControl::GetNeedsDisplay() const
1094 return HIViewGetNeedsDisplay( m_controlRef
);
1097 void wxWidgetImpl::Convert( wxPoint
*pt
, wxWidgetImpl
*from
, wxWidgetImpl
*to
)
1103 HIViewConvertPoint( &hiPoint
, (ControlRef
) from
->GetWXWidget() , (ControlRef
) to
->GetWXWidget() );
1104 pt
->x
= (int)hiPoint
.x
;
1105 pt
->y
= (int)hiPoint
.y
;
1108 bool wxMacControl::SetFocus()
1110 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1111 // we can only leave in case of an error
1113 OSStatus err
= SetKeyboardFocus( GetControlOwner( m_controlRef
), m_controlRef
, kControlFocusNextPart
);
1114 if ( err
== errCouldntSetFocus
)
1116 SetUserFocusWindow(GetControlOwner( m_controlRef
) );
1121 bool wxMacControl::HasFocus() const
1124 GetKeyboardFocus( GetUserFocusWindow() , &control
);
1125 return control
== m_controlRef
;
1128 void wxMacControl::SetCursor(const wxCursor
& cursor
)
1130 wxWindowMac
*mouseWin
= 0 ;
1131 WindowRef window
= GetControlOwner( m_controlRef
) ;
1133 wxNonOwnedWindow
* tlwwx
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) window
) ;
1134 if ( tlwwx
!= NULL
)
1136 ControlPartCode part
;
1137 ControlRef control
;
1139 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1141 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1145 GetGlobalMouse( &pt
);
1148 tlwwx
->ScreenToClient(&x
, &y
);
1152 control
= FindControlUnderMouse( pt
, window
, &part
) ;
1154 mouseWin
= wxFindWindowFromWXWidget( (WXWidget
) control
) ;
1157 if ( mouseWin
== tlwwx
&& !wxIsBusy() )
1158 cursor
.MacInstall() ;
1161 void wxMacControl::CaptureMouse()
1165 void wxMacControl::ReleaseMouse()
1170 // subclass specifics
1173 OSStatus
wxMacControl::GetData(ControlPartCode inPartCode
, ResType inTag
, Size inBufferSize
, void * inOutBuffer
, Size
* outActualSize
) const
1175 return ::GetControlData( m_controlRef
, inPartCode
, inTag
, inBufferSize
, inOutBuffer
, outActualSize
);
1178 OSStatus
wxMacControl::GetDataSize(ControlPartCode inPartCode
, ResType inTag
, Size
* outActualSize
) const
1180 return ::GetControlDataSize( m_controlRef
, inPartCode
, inTag
, outActualSize
);
1183 OSStatus
wxMacControl::SetData(ControlPartCode inPartCode
, ResType inTag
, Size inSize
, const void * inData
)
1185 return ::SetControlData( m_controlRef
, inPartCode
, inTag
, inSize
, inData
);
1188 OSStatus
wxMacControl::SendEvent( EventRef event
, OptionBits inOptions
)
1190 return SendEventToEventTargetWithOptions( event
,
1191 HIObjectGetEventTarget( (HIObjectRef
) m_controlRef
), inOptions
);
1194 OSStatus
wxMacControl::SendHICommand( HICommand
&command
, OptionBits inOptions
)
1196 wxMacCarbonEvent
event( kEventClassCommand
, kEventCommandProcess
);
1198 event
.SetParameter
<HICommand
>(kEventParamDirectObject
,command
);
1200 return SendEvent( event
, inOptions
);
1203 OSStatus
wxMacControl::SendHICommand( UInt32 commandID
, OptionBits inOptions
)
1207 memset( &command
, 0 , sizeof(command
) );
1208 command
.commandID
= commandID
;
1209 return SendHICommand( command
, inOptions
);
1212 void wxMacControl::PerformClick()
1214 HIViewSimulateClick (m_controlRef
, kControlButtonPart
, 0, NULL
);
1217 wxInt32
wxMacControl::GetValue() const
1219 return ::GetControl32BitValue( m_controlRef
);
1222 wxInt32
wxMacControl::GetMaximum() const
1224 return ::GetControl32BitMaximum( m_controlRef
);
1227 wxInt32
wxMacControl::GetMinimum() const
1229 return ::GetControl32BitMinimum( m_controlRef
);
1232 void wxMacControl::SetValue( wxInt32 v
)
1234 ::SetControl32BitValue( m_controlRef
, v
);
1237 void wxMacControl::SetMinimum( wxInt32 v
)
1239 ::SetControl32BitMinimum( m_controlRef
, v
);
1242 void wxMacControl::SetMaximum( wxInt32 v
)
1244 ::SetControl32BitMaximum( m_controlRef
, v
);
1247 void wxMacControl::SetValueAndRange( SInt32 value
, SInt32 minimum
, SInt32 maximum
)
1249 ::SetControl32BitMinimum( m_controlRef
, minimum
);
1250 ::SetControl32BitMaximum( m_controlRef
, maximum
);
1251 ::SetControl32BitValue( m_controlRef
, value
);
1254 void wxMacControl::VisibilityChanged(bool WXUNUSED(shown
))
1258 void wxMacControl::SuperChangedPosition()
1262 void wxMacControl::SetFont( const wxFont
& font
, const wxColour
& foreground
, long windowStyle
, bool ignoreBlack
)
1265 #if wxOSX_USE_CORE_TEXT
1266 if ( UMAGetSystemVersion() >= 0x1050 )
1268 HIViewPartCode part
= 0;
1269 HIThemeTextHorizontalFlush flush
= kHIThemeTextHorizontalFlushDefault
;
1270 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1271 flush
= kHIThemeTextHorizontalFlushCenter
;
1272 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1273 flush
= kHIThemeTextHorizontalFlushRight
;
1274 HIViewSetTextFont( m_controlRef
, part
, (CTFontRef
) font
.OSXGetCTFont() );
1275 HIViewSetTextHorizontalFlush( m_controlRef
, part
, flush
);
1277 if ( foreground
!= *wxBLACK
|| ignoreBlack
== false )
1279 ControlFontStyleRec fontStyle
;
1280 foreground
.GetRGBColor( &fontStyle
.foreColor
);
1281 fontStyle
.flags
= kControlUseForeColorMask
;
1282 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1286 #if wxOSX_USE_ATSU_TEXT
1287 ControlFontStyleRec fontStyle
;
1288 if ( font
.MacGetThemeFontID() != kThemeCurrentPortFont
)
1290 switch ( font
.MacGetThemeFontID() )
1292 case kThemeSmallSystemFont
:
1293 fontStyle
.font
= kControlFontSmallSystemFont
;
1296 case 109 : // mini font
1297 fontStyle
.font
= -5;
1300 case kThemeSystemFont
:
1301 fontStyle
.font
= kControlFontBigSystemFont
;
1305 fontStyle
.font
= kControlFontBigSystemFont
;
1309 fontStyle
.flags
= kControlUseFontMask
;
1313 fontStyle
.font
= font
.MacGetFontNum();
1314 fontStyle
.style
= font
.MacGetFontStyle();
1315 fontStyle
.size
= font
.GetPointSize();
1316 fontStyle
.flags
= kControlUseFontMask
| kControlUseFaceMask
| kControlUseSizeMask
;
1319 fontStyle
.just
= teJustLeft
;
1320 fontStyle
.flags
|= kControlUseJustMask
;
1321 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1322 fontStyle
.just
= teJustCenter
;
1323 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1324 fontStyle
.just
= teJustRight
;
1327 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
1328 // won't get grayed out by the system anymore
1330 if ( foreground
!= *wxBLACK
|| ignoreBlack
== false )
1332 foreground
.GetRGBColor( &fontStyle
.foreColor
);
1333 fontStyle
.flags
|= kControlUseForeColorMask
;
1336 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1340 void wxMacControl::SetBackgroundColour( const wxColour
&WXUNUSED(col
) )
1342 // HITextViewSetBackgroundColor( m_textView , color );
1345 bool wxMacControl::SetBackgroundStyle(wxBackgroundStyle style
)
1347 if ( style
!= wxBG_STYLE_PAINT
)
1349 OSStatus err
= HIViewChangeFeatures(m_controlRef
, 0 , kHIViewIsOpaque
);
1350 verify_noerr( err
);
1354 OSStatus err
= HIViewChangeFeatures(m_controlRef
, kHIViewIsOpaque
, 0);
1355 verify_noerr( err
);
1361 void wxMacControl::SetRange( SInt32 minimum
, SInt32 maximum
)
1363 ::SetControl32BitMinimum( m_controlRef
, minimum
);
1364 ::SetControl32BitMaximum( m_controlRef
, maximum
);
1367 short wxMacControl::HandleKey( SInt16 keyCode
, SInt16 charCode
, EventModifiers modifiers
)
1369 return HandleControlKey( m_controlRef
, keyCode
, charCode
, modifiers
);
1372 void wxMacControl::SetActionProc( ControlActionUPP actionProc
)
1374 SetControlAction( m_controlRef
, actionProc
);
1377 SInt32
wxMacControl::GetViewSize() const
1379 return GetControlViewSize( m_controlRef
);
1382 bool wxMacControl::IsVisible() const
1384 return IsControlVisible( m_controlRef
);
1387 void wxMacControl::SetVisibility( bool visible
)
1389 SetControlVisibility( m_controlRef
, visible
, true );
1392 bool wxMacControl::IsEnabled() const
1394 return IsControlEnabled( m_controlRef
);
1397 bool wxMacControl::IsActive() const
1399 return IsControlActive( m_controlRef
);
1402 void wxMacControl::Enable( bool enable
)
1405 EnableControl( m_controlRef
);
1407 DisableControl( m_controlRef
);
1410 void wxMacControl::SetDrawingEnabled( bool enable
)
1414 HIViewSetDrawingEnabled( m_controlRef
, true );
1415 HIViewSetNeedsDisplay( m_controlRef
, true);
1419 HIViewSetDrawingEnabled( m_controlRef
, false );
1423 void wxMacControl::GetRectInWindowCoords( Rect
*r
)
1425 GetControlBounds( m_controlRef
, r
) ;
1427 WindowRef tlwref
= GetControlOwner( m_controlRef
) ;
1429 wxNonOwnedWindow
* tlwwx
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) tlwref
) ;
1430 if ( tlwwx
!= NULL
)
1432 ControlRef rootControl
= tlwwx
->GetPeer()->GetControlRef() ;
1433 HIPoint hiPoint
= CGPointMake( 0 , 0 ) ;
1434 HIViewConvertPoint( &hiPoint
, HIViewGetSuperview(m_controlRef
) , rootControl
) ;
1435 OffsetRect( r
, (short) hiPoint
.x
, (short) hiPoint
.y
) ;
1439 void wxMacControl::GetBestRect( wxRect
*rect
) const
1441 short baselineoffset
;
1444 GetBestControlRect( m_controlRef
, &r
, &baselineoffset
);
1445 *rect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
-r
.top
);
1448 void wxMacControl::GetBestRect( Rect
*r
) const
1450 short baselineoffset
;
1451 GetBestControlRect( m_controlRef
, r
, &baselineoffset
);
1454 void wxMacControl::SetLabel( const wxString
&title
, wxFontEncoding encoding
)
1456 SetControlTitleWithCFString( m_controlRef
, wxCFStringRef( title
, encoding
) );
1459 void wxMacControl::GetFeatures( UInt32
* features
)
1461 GetControlFeatures( m_controlRef
, features
);
1464 void wxMacControl::PulseGauge()
1468 // SetNeedsDisplay would not invalidate the children
1469 static void InvalidateControlAndChildren( HIViewRef control
)
1471 HIViewSetNeedsDisplay( control
, true );
1472 UInt16 childrenCount
= 0;
1473 OSStatus err
= CountSubControls( control
, &childrenCount
);
1474 if ( err
== errControlIsNotEmbedder
)
1477 wxASSERT_MSG( err
== noErr
, wxT("Unexpected error when accessing subcontrols") );
1479 for ( UInt16 i
= childrenCount
; i
>=1; --i
)
1483 err
= GetIndexedSubControl( control
, i
, & child
);
1484 if ( err
== errControlIsNotEmbedder
)
1487 InvalidateControlAndChildren( child
);
1491 void wxMacControl::InvalidateWithChildren()
1493 InvalidateControlAndChildren( m_controlRef
);
1496 OSType wxMacCreator
= 'WXMC';
1497 OSType wxMacControlProperty
= 'MCCT';
1499 void wxMacControl::SetReferenceInNativeControl()
1502 verify_noerr( SetControlProperty ( m_controlRef
,
1503 wxMacCreator
,wxMacControlProperty
, sizeof(data
), &data
) );
1506 wxMacControl
* wxMacControl::GetReferenceFromNativeControl(ControlRef control
)
1508 wxMacControl
* ctl
= NULL
;
1509 ByteCount actualSize
;
1510 if ( GetControlProperty( control
,wxMacCreator
,wxMacControlProperty
, sizeof(ctl
) ,
1511 &actualSize
, &ctl
) == noErr
)
1518 wxBitmap
wxMacControl::GetBitmap() const
1520 return wxNullBitmap
;
1523 void wxMacControl::SetBitmap( const wxBitmap
& WXUNUSED(bmp
) )
1525 // implemented in the respective subclasses
1528 void wxMacControl::SetBitmapPosition( wxDirection
WXUNUSED(dir
) )
1530 // implemented in the same subclasses that implement SetBitmap()
1533 void wxMacControl::SetScrollThumb( wxInt32
WXUNUSED(pos
), wxInt32
WXUNUSED(viewsize
) )
1535 // implemented in respective subclass
1542 OSStatus
wxMacControl::SetTabEnabled( SInt16 tabNo
, bool enable
)
1544 return ::SetTabEnabled( m_controlRef
, tabNo
, enable
);
1551 wxWidgetImplType
* wxWidgetImpl::CreateContentView( wxNonOwnedWindow
* now
)
1553 // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of
1554 // the content view, so we have to retrieve it explicitly
1556 wxMacControl
* contentview
= new wxMacControl(now
, true /*isRootControl*/);
1557 HIViewFindByID( HIViewGetRoot( (WindowRef
) now
->GetWXWindow() ) , kHIViewWindowContentID
,
1558 contentview
->GetControlRefAddr() ) ;
1559 if ( !contentview
->IsOk() )
1561 // compatibility mode fallback
1562 GetRootControl( (WindowRef
) now
->GetWXWindow() , contentview
->GetControlRefAddr() ) ;
1565 // the root control level handler
1566 if ( !now
->IsNativeWindowWrapper() )
1567 contentview
->InstallEventHandler() ;