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 // no compositing to take into account under carbon
91 wxWidgetImpl
* wxWidgetImpl::FindBestFromWXWidget(WXWidget control
)
93 return FindFromWXWidget(control
);
96 // ---------------------------------------------------------------------------
98 // ---------------------------------------------------------------------------
100 static const EventTypeSpec eventList
[] =
102 { kEventClassCommand
, kEventProcessCommand
} ,
103 { kEventClassCommand
, kEventCommandUpdateStatus
} ,
105 { kEventClassControl
, kEventControlGetClickActivation
} ,
106 { kEventClassControl
, kEventControlHit
} ,
108 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
109 { kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
} ,
111 { kEventClassControl
, kEventControlDraw
} ,
113 { kEventClassControl
, kEventControlVisibilityChanged
} ,
114 { kEventClassControl
, kEventControlEnabledStateChanged
} ,
115 { kEventClassControl
, kEventControlHiliteChanged
} ,
117 { kEventClassControl
, kEventControlActivate
} ,
118 { kEventClassControl
, kEventControlDeactivate
} ,
120 { kEventClassControl
, kEventControlSetFocusPart
} ,
121 { kEventClassControl
, kEventControlFocusPartChanged
} ,
123 { kEventClassService
, kEventServiceGetTypes
},
124 { kEventClassService
, kEventServiceCopy
},
125 { kEventClassService
, kEventServicePaste
},
127 // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
128 // { kEventClassControl , kEventControlBoundsChanged } ,
131 static pascal OSStatus
wxMacWindowControlEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
133 OSStatus result
= eventNotHandledErr
;
134 static wxWindowMac
* targetFocusWindow
= NULL
;
135 static wxWindowMac
* formerFocusWindow
= NULL
;
137 wxMacCarbonEvent
cEvent( event
) ;
139 ControlRef controlRef
;
140 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
142 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
144 switch ( GetEventKind( event
) )
146 case kEventControlDraw
:
148 HIShapeRef updateRgn
= NULL
;
149 HIMutableShapeRef allocatedRgn
= NULL
;
150 wxRegion visRegion
= thisWindow
->MacGetVisibleRegion() ;
152 // according to the docs: redraw entire control if param not present
153 if ( cEvent
.GetParameter
<HIShapeRef
>(kEventParamShape
, &updateRgn
) != noErr
)
155 updateRgn
= visRegion
.GetWXHRGN();
159 if ( thisWindow
->MacGetLeftBorderSize() != 0 || thisWindow
->MacGetTopBorderSize() != 0 )
161 // as this update region is in native window locals we must adapt it to wx window local
162 allocatedRgn
= HIShapeCreateMutableCopy(updateRgn
);
163 HIShapeOffset(allocatedRgn
, thisWindow
->MacGetLeftBorderSize() , thisWindow
->MacGetTopBorderSize());
164 // hide the given region by the new region that must be shifted
165 updateRgn
= allocatedRgn
;
169 #if wxMAC_DEBUG_REDRAW
170 if ( thisWindow
->MacIsUserPane() )
172 static float color
= 0.5 ;
173 static int channel
= 0 ;
175 CGContextRef cgContext
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
) ;
177 HIViewGetBounds( controlRef
, &bounds
);
178 CGContextSetRGBFillColor( cgContext
, channel
== 0 ? color
: 0.5 ,
179 channel
== 1 ? color
: 0.5 , channel
== 2 ? color
: 0.5 , 1 );
180 CGContextFillRect( cgContext
, bounds
);
193 CGContextRef cgContext
= NULL
;
194 OSStatus err
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
, &cgContext
) ;
197 // for non-composite drawing, since we don't support it ourselves, send it through the
198 // the default handler
199 // CallNextEventHandler( handler,event ) ;
202 CFRelease( allocatedRgn
) ;
206 thisWindow
->MacSetCGContextRef( cgContext
) ;
209 wxMacCGContextStateSaver
sg( cgContext
) ;
210 CGFloat alpha
= (CGFloat
)1.0 ;
212 wxWindow
* iter
= thisWindow
;
215 alpha
*= (CGFloat
)( iter
->GetTransparent()/255.0 ) ;
216 if ( iter
->IsTopLevel() )
219 iter
= iter
->GetParent() ;
222 CGContextSetAlpha( cgContext
, alpha
) ;
224 if ( thisWindow
->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
227 HIViewGetBounds( controlRef
, &bounds
);
228 CGContextClearRect( cgContext
, bounds
);
231 if ( !HIShapeIsEmpty(updateRgn
) )
233 // refcount increase because wxRegion constructor takes ownership of the native region
235 thisWindow
->GetUpdateRegion() = wxRegion(updateRgn
);
236 if ( !thisWindow
->MacDoRedraw( cEvent
.GetTicks() ) )
238 // for native controls: call their native paint method
239 if ( !thisWindow
->MacIsUserPane() ||
240 ( thisWindow
->IsTopLevel() && thisWindow
->GetBackgroundStyle() == wxBG_STYLE_SYSTEM
) )
242 if ( thisWindow
->GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT
)
244 CallNextEventHandler( handler
,event
) ;
253 thisWindow
->MacPaintChildrenBorders();
255 thisWindow
->MacSetCGContextRef( NULL
) ;
260 CFRelease( allocatedRgn
) ;
264 case kEventControlVisibilityChanged
:
265 // we might have two native controls attributed to the same wxWindow instance
266 // eg a scrollview and an embedded textview, make sure we only fire for the 'outer'
267 // control, as otherwise native and wx visibility are different
268 if ( thisWindow
->GetPeer() != NULL
&& thisWindow
->GetPeer()->GetControlRef() == controlRef
)
270 thisWindow
->MacVisibilityChanged() ;
274 case kEventControlEnabledStateChanged
:
275 thisWindow
->MacEnabledStateChanged();
278 case kEventControlHiliteChanged
:
279 thisWindow
->MacHiliteChanged() ;
282 case kEventControlActivate
:
283 case kEventControlDeactivate
:
284 // FIXME: we should have a virtual function for this!
286 if ( thisWindow
->IsKindOf( CLASSINFO( wxTreeCtrl
) ) )
287 thisWindow
->Refresh();
290 if ( thisWindow
->IsKindOf( CLASSINFO( wxListCtrl
) ) )
291 thisWindow
->Refresh();
297 // different handling on OS X
300 case kEventControlFocusPartChanged
:
301 // the event is emulated by wxmac for systems lower than 10.5
303 if ( UMAGetSystemVersion() < 0x1050 )
305 // as it is synthesized here, we have to manually avoid propagation
308 ControlPartCode previousControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPreviousPart
, typeControlPartCode
);
309 ControlPartCode currentControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlCurrentPart
, typeControlPartCode
);
311 if ( thisWindow
->MacGetTopLevelWindow() && thisWindow
->GetPeer()->NeedsFocusRect() )
313 thisWindow
->MacInvalidateBorders();
316 if ( currentControlPart
== 0 )
320 if ( thisWindow
->GetCaret() )
321 thisWindow
->GetCaret()->OnKillFocus();
324 wxLogTrace(wxT("Focus"), wxT("focus lost(%p)"), static_cast<void*>(thisWindow
));
326 // remove this as soon as posting the synthesized event works properly
327 static bool inKillFocusEvent
= false ;
329 if ( !inKillFocusEvent
)
331 inKillFocusEvent
= true ;
332 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
333 event
.SetEventObject(thisWindow
);
334 event
.SetWindow(targetFocusWindow
);
335 thisWindow
->HandleWindowEvent(event
) ;
336 inKillFocusEvent
= false ;
337 targetFocusWindow
= NULL
;
340 else if ( previousControlPart
== 0 )
343 // panel wants to track the window which was the last to have focus in it
344 wxLogTrace(wxT("Focus"), wxT("focus set(%p)"), static_cast<void*>(thisWindow
));
345 wxChildFocusEvent
eventFocus((wxWindow
*)thisWindow
);
346 thisWindow
->HandleWindowEvent(eventFocus
);
349 if ( thisWindow
->GetCaret() )
350 thisWindow
->GetCaret()->OnSetFocus();
353 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
354 event
.SetEventObject(thisWindow
);
355 event
.SetWindow(formerFocusWindow
);
356 thisWindow
->HandleWindowEvent(event
) ;
357 formerFocusWindow
= NULL
;
361 case kEventControlSetFocusPart
:
363 Boolean focusEverything
= false ;
364 if ( cEvent
.GetParameter
<Boolean
>(kEventParamControlFocusEverything
, &focusEverything
) == noErr
)
366 // put a breakpoint here to catch focus everything events
368 ControlPartCode controlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
369 if ( controlPart
!= kControlFocusNoPart
)
371 targetFocusWindow
= thisWindow
;
372 wxLogTrace(wxT("Focus"), wxT("focus to be set(%p)"), static_cast<void*>(thisWindow
));
376 formerFocusWindow
= thisWindow
;
377 wxLogTrace(wxT("Focus"), wxT("focus to be lost(%p)"), static_cast<void*>(thisWindow
));
380 ControlPartCode previousControlPart
= 0;
381 verify_noerr( HIViewGetFocusPart(controlRef
, &previousControlPart
));
383 if ( thisWindow
->MacIsUserPane() )
385 if ( controlPart
!= kControlFocusNoPart
)
386 cEvent
.SetParameter
<ControlPartCode
>( kEventParamControlPart
, typeControlPartCode
, 1 ) ;
390 result
= CallNextEventHandler(handler
, event
);
392 if ( UMAGetSystemVersion() < 0x1050 )
394 // set back to 0 if problems arise
396 if ( result
== noErr
)
398 ControlPartCode currentControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
399 // synthesize the event focus changed event
400 EventRef evRef
= NULL
;
402 OSStatus err
= MacCreateEvent(
403 NULL
, kEventClassControl
, kEventControlFocusPartChanged
, TicksToEventTime( TickCount() ) ,
404 kEventAttributeUserEvent
, &evRef
);
407 wxMacCarbonEvent
iEvent( evRef
) ;
408 iEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, controlRef
);
409 iEvent
.SetParameter
<EventTargetRef
>( kEventParamPostTarget
, typeEventTargetRef
, GetControlEventTarget( controlRef
) );
410 iEvent
.SetParameter
<ControlPartCode
>( kEventParamControlPreviousPart
, typeControlPartCode
, previousControlPart
);
411 iEvent
.SetParameter
<ControlPartCode
>( kEventParamControlCurrentPart
, typeControlPartCode
, currentControlPart
);
414 // TODO test this first, avoid double posts etc...
415 PostEventToQueue( GetMainEventQueue(), evRef
, kEventPriorityHigh
);
417 wxMacWindowControlEventHandler( NULL
, evRef
, data
) ;
419 ReleaseEvent( evRef
) ;
422 // old implementation, to be removed if the new one works
423 if ( controlPart
== kControlFocusNoPart
)
426 if ( thisWindow
->GetCaret() )
427 thisWindow
->GetCaret()->OnKillFocus();
430 wxLogTrace(wxT("Focus"), wxT("focus lost(%p)"), static_cast<void*>(thisWindow
));
432 static bool inKillFocusEvent
= false ;
434 if ( !inKillFocusEvent
)
436 inKillFocusEvent
= true ;
437 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
438 event
.SetEventObject(thisWindow
);
439 thisWindow
->HandleWindowEvent(event
) ;
440 inKillFocusEvent
= false ;
445 // panel wants to track the window which was the last to have focus in it
446 wxLogTrace(wxT("Focus"), wxT("focus set(%p)"), static_cast<void*>(thisWindow
));
447 wxChildFocusEvent
eventFocus((wxWindow
*)thisWindow
);
448 thisWindow
->HandleWindowEvent(eventFocus
);
451 if ( thisWindow
->GetCaret() )
452 thisWindow
->GetCaret()->OnSetFocus();
455 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
456 event
.SetEventObject(thisWindow
);
457 thisWindow
->HandleWindowEvent(event
) ;
464 case kEventControlHit
:
465 result
= thisWindow
->MacControlHit( handler
, event
) ;
468 case kEventControlGetClickActivation
:
470 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
471 WindowRef owner
= cEvent
.GetParameter
<WindowRef
>(kEventParamWindowRef
);
472 if ( !IsWindowActive(owner
) )
474 cEvent
.SetParameter(kEventParamClickActivation
,typeClickActivationResult
, (UInt32
) kActivateAndIgnoreClick
) ;
487 static pascal OSStatus
488 wxMacWindowServiceEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
492 OSStatus result
= eventNotHandledErr
;
494 wxMacCarbonEvent
cEvent( event
) ;
496 ControlRef controlRef
;
497 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
498 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
499 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
501 switch ( GetEventKind( event
) )
503 case kEventServiceGetTypes
:
507 textCtrl
->GetSelection( &from
, &to
) ;
509 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
511 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
512 if ( textCtrl
->IsEditable() )
513 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
515 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
516 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
518 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
522 CFArrayAppendValue(copyTypes
, typestring
) ;
524 CFArrayAppendValue(pasteTypes
, typestring
) ;
526 CFRelease( typestring
) ;
534 case kEventServiceCopy
:
539 textCtrl
->GetSelection( &from
, &to
) ;
540 wxString val
= textCtrl
->GetValue() ;
541 val
= val
.Mid( from
, to
- from
) ;
542 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
543 verify_noerr( PasteboardClear( pasteboard
) ) ;
544 PasteboardSynchronize( pasteboard
);
545 // TODO add proper conversion
546 CFDataRef data
= CFDataCreate( kCFAllocatorDefault
, (const UInt8
*)val
.c_str(), val
.length() );
547 PasteboardPutItemFlavor( pasteboard
, (PasteboardItemID
) 1, CFSTR("com.apple.traditional-mac-plain-text"), data
, 0);
553 case kEventServicePaste
:
556 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
557 PasteboardSynchronize( pasteboard
);
559 verify_noerr( PasteboardGetItemCount( pasteboard
, &itemCount
) );
560 for( UInt32 itemIndex
= 1; itemIndex
<= itemCount
; itemIndex
++ )
562 PasteboardItemID itemID
;
563 if ( PasteboardGetItemIdentifier( pasteboard
, itemIndex
, &itemID
) == noErr
)
565 CFDataRef flavorData
= NULL
;
566 if ( PasteboardCopyItemFlavorData( pasteboard
, itemID
, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData
) == noErr
)
568 CFIndex flavorDataSize
= CFDataGetLength( flavorData
);
569 char *content
= new char[flavorDataSize
+1] ;
570 memcpy( content
, CFDataGetBytePtr( flavorData
), flavorDataSize
);
571 content
[flavorDataSize
]=0;
572 CFRelease( flavorData
);
574 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
576 textCtrl
->WriteText( wxString( content
) ) ;
594 WXDLLEXPORT
pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
596 OSStatus result
= eventNotHandledErr
;
597 wxWindowMac
* focus
= (wxWindowMac
*) data
;
599 wchar_t* uniChars
= NULL
;
600 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
602 UniChar
* charBuf
= NULL
;
603 ByteCount dataSize
= 0 ;
606 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
608 numChars
= dataSize
/ sizeof( UniChar
) + 1;
611 if ( (size_t) numChars
* 2 > sizeof(buf
) )
612 charBuf
= new UniChar
[ numChars
] ;
616 uniChars
= new wchar_t[ numChars
] ;
617 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
618 charBuf
[ numChars
- 1 ] = 0;
619 // the resulting string will never have more chars than the utf16 version, so this is safe
620 wxMBConvUTF16 converter
;
621 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
624 switch ( GetEventKind( event
) )
626 case kEventTextInputUpdateActiveInputArea
:
628 // An IME input event may return several characters, but we need to send one char at a time to
630 for (int pos
=0 ; pos
< numChars
; pos
++)
632 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
633 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
634 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
636 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
638 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
639 multiple times to update the active range during inline input, so this handler will often receive
640 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
641 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
642 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
643 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
644 should add new event types to support advanced text input. For now, I would keep things as they are.
646 However, the code that was being used caused additional problems:
647 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
648 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
649 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
650 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
651 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
652 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
653 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
654 overlap with Unicode within the (7-bit) ASCII range.
655 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
656 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
657 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
658 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
659 I don't have time to look into that right now.
662 if ( wxTheApp
->MacSendCharEvent( focus
, message
, 0 , when
, uniChars
[pos
] ) )
667 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
671 case kEventTextInputUnicodeForKeyEvent
:
673 UInt32 keyCode
, modifiers
;
675 unsigned char charCode
;
677 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
678 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, 1, NULL
, &charCode
);
679 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
680 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
682 UInt32 message
= (keyCode
<< 8) + charCode
;
684 // An IME input event may return several characters, but we need to send one char at a time to
686 for (int pos
=0 ; pos
< numChars
; pos
++)
688 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
689 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
690 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
692 if ( wxTheApp
->MacSendCharEvent( focus
, message
, modifiers
, when
, uniChars
[pos
] ) )
697 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
706 if ( charBuf
!= buf
)
712 static pascal OSStatus
713 wxMacWindowCommandEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
717 OSStatus result
= eventNotHandledErr
;
718 wxWindowMac
* focus
= (wxWindowMac
*) data
;
722 wxMacCarbonEvent
cEvent( event
) ;
723 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
725 wxMenuItem
* item
= NULL
;
726 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
730 wxASSERT( itemMenu
!= NULL
) ;
732 switch ( cEvent
.GetKind() )
734 case kEventProcessCommand
:
735 if ( itemMenu
->HandleCommandProcess( item
, focus
) )
739 case kEventCommandUpdateStatus
:
740 if ( itemMenu
->HandleCommandUpdateStatus( item
, focus
) )
751 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
753 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
754 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
755 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
756 OSStatus result
= eventNotHandledErr
;
758 switch ( GetEventClass( event
) )
760 case kEventClassCommand
:
761 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
764 case kEventClassControl
:
765 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
768 case kEventClassService
:
769 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
772 case kEventClassTextInput
:
773 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
780 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
785 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
787 // ---------------------------------------------------------------------------
788 // Scrollbar Tracking for all
789 // ---------------------------------------------------------------------------
791 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
792 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
796 wxWindow
* wx
= wxFindWindowFromWXWidget( (WXWidget
) control
) ;
799 wxEventType scrollEvent
= wxEVT_NULL
;
802 case kControlUpButtonPart
:
803 scrollEvent
= wxEVT_SCROLL_LINEUP
;
806 case kControlDownButtonPart
:
807 scrollEvent
= wxEVT_SCROLL_LINEDOWN
;
810 case kControlPageUpPart
:
811 scrollEvent
= wxEVT_SCROLL_PAGEUP
;
814 case kControlPageDownPart
:
815 scrollEvent
= wxEVT_SCROLL_PAGEDOWN
;
818 case kControlIndicatorPart
:
819 scrollEvent
= wxEVT_SCROLL_THUMBTRACK
;
820 // when this is called as a live proc, mouse is always still down
821 // so no need for thumbrelease
822 // scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
825 wx
->TriggerScrollEvent(scrollEvent
) ;
829 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
831 wxWidgetImplType
* wxWidgetImpl::CreateUserPane( wxWindowMac
* wxpeer
,
832 wxWindowMac
* WXUNUSED(parent
),
833 wxWindowID
WXUNUSED(id
),
836 long WXUNUSED(style
),
837 long WXUNUSED(extraStyle
))
839 OSStatus err
= noErr
;
840 Rect bounds
= wxMacGetBoundsForControl( wxpeer
, pos
, size
) ;
841 wxMacControl
* c
= new wxMacControl(wxpeer
, false, true) ;
843 | kControlSupportsEmbedding
844 | kControlSupportsLiveFeedback
845 | kControlGetsFocusOnClick
846 // | kControlHasSpecialBackground
847 // | kControlSupportsCalcBestRect
848 | kControlHandlesTracking
849 | kControlSupportsFocus
850 | kControlWantsActivate
851 | kControlWantsIdle
;
853 err
=::CreateUserPaneControl( MAC_WXHWND(wxpeer
->GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, c
->GetControlRefAddr() );
859 void wxMacControl::InstallEventHandler( WXWidget control
)
861 wxWidgetImpl::Associate( control
? control
: (WXWidget
) m_controlRef
, this ) ;
862 ::InstallControlEventHandler( control
? (ControlRef
) control
: m_controlRef
, GetwxMacWindowEventHandlerUPP(),
863 GetEventTypeCount(eventList
), eventList
, GetWXPeer(), NULL
);
866 IMPLEMENT_DYNAMIC_CLASS( wxMacControl
, wxWidgetImpl
)
868 wxMacControl::wxMacControl()
873 wxMacControl::wxMacControl(wxWindowMac
* peer
, bool isRootControl
, bool isUserPane
) :
874 wxWidgetImpl( peer
, isRootControl
, isUserPane
)
879 wxMacControl::~wxMacControl()
881 if ( m_controlRef
&& !IsRootControl() )
883 wxASSERT_MSG( m_controlRef
!= NULL
, wxT("Control Handle already NULL, Dispose called twice ?") );
884 wxASSERT_MSG( IsValidControlHandle(m_controlRef
) , wxT("Invalid Control Handle (maybe already released) in Dispose") );
886 wxWidgetImpl::RemoveAssociations( this ) ;
887 // we cannot check the ref count here anymore, as autorelease objects might delete their refs later
888 // we can have situations when being embedded, where the control gets deleted behind our back, so only
889 // CFRelease if we are safe
890 if ( IsValidControlHandle(m_controlRef
) )
891 CFRelease(m_controlRef
);
896 void wxMacControl::Init()
899 m_macControlEventHandler
= NULL
;
902 void wxMacControl::RemoveFromParent()
904 // nothing to do here for carbon
905 HIViewRemoveFromSuperview(m_controlRef
);
908 void wxMacControl::Embed( wxWidgetImpl
*parent
)
910 HIViewAddSubview((ControlRef
)parent
->GetWXWidget(), m_controlRef
);
913 void wxMacControl::SetNeedsDisplay( const wxRect
* rect
)
920 HIRect updatearea
= CGRectMake( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
921 HIViewSetNeedsDisplayInRect( m_controlRef
, &updatearea
, true );
924 HIViewSetNeedsDisplay( m_controlRef
, true );
927 void wxMacControl::Raise()
929 verify_noerr( HIViewSetZOrder( m_controlRef
, kHIViewZOrderAbove
, NULL
) );
932 void wxMacControl::Lower()
934 verify_noerr( HIViewSetZOrder( m_controlRef
, kHIViewZOrderBelow
, NULL
) );
937 void wxMacControl::GetContentArea(int &left
, int &top
, int &width
, int &height
) const
939 HIShapeRef rgn
= NULL
;
942 if ( HIViewCopyShape(m_controlRef
, kHIViewContentMetaPart
, &rgn
) == noErr
)
945 HIShapeGetBounds(rgn
, &cgrect
);
946 content
= (Rect
){ (short)cgrect
.origin
.y
,
947 (short)cgrect
.origin
.x
,
948 (short)(cgrect
.origin
.y
+cgrect
.size
.height
),
949 (short)(cgrect
.origin
.x
+cgrect
.size
.width
) };
954 GetControlBounds(m_controlRef
, &content
);
955 content
.right
-= content
.left
;
957 content
.bottom
-= content
.top
;
964 width
= content
.right
- content
.left
;
965 height
= content
.bottom
- content
.top
;
968 void wxMacControl::Move(int x
, int y
, int width
, int height
)
971 GetWindowAttributes( GetControlOwner(m_controlRef
) , &attr
) ;
973 HIRect hir
= CGRectMake(x
,y
,width
,height
);
974 if ( !(attr
& kWindowCompositingAttribute
) )
977 HIViewGetFrame( HIViewGetSuperview(m_controlRef
), &parent
);
978 hir
.origin
.x
+= parent
.origin
.x
;
979 hir
.origin
.y
+= parent
.origin
.y
;
981 HIViewSetFrame ( m_controlRef
, &hir
);
984 void wxMacControl::GetPosition( int &x
, int &y
) const
987 GetControlBounds( m_controlRef
, &r
);
992 GetWindowAttributes( GetControlOwner(m_controlRef
) , &attr
) ;
994 if ( !(attr
& kWindowCompositingAttribute
) )
997 HIViewGetFrame( HIViewGetSuperview(m_controlRef
), &parent
);
998 x
-= (int)parent
.origin
.x
;
999 y
-= (int)parent
.origin
.y
;
1004 void wxMacControl::GetSize( int &width
, int &height
) const
1007 GetControlBounds( m_controlRef
, &r
);
1008 width
= r
.right
- r
.left
;
1009 height
= r
.bottom
- r
.top
;
1012 void wxMacControl::SetControlSize( wxWindowVariant variant
)
1017 case wxWINDOW_VARIANT_NORMAL
:
1018 size
= kControlSizeNormal
;
1021 case wxWINDOW_VARIANT_SMALL
:
1022 size
= kControlSizeSmall
;
1025 case wxWINDOW_VARIANT_MINI
:
1026 // not always defined in the headers
1030 case wxWINDOW_VARIANT_LARGE
:
1031 size
= kControlSizeLarge
;
1035 wxFAIL_MSG(wxT("unexpected window variant"));
1039 SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1042 void wxMacControl::ScrollRect( const wxRect
*rect
, int dx
, int dy
)
1044 if (GetNeedsDisplay() )
1046 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
1047 // in case there is already a pending redraw on that area
1048 // either immediate redraw or full invalidate
1050 // is the better overall solution, as it does not slow down scrolling
1053 // this would be the preferred version for fast drawing controls
1054 HIViewRender(GetControlRef()) ;
1058 // note there currently is a bug in OSX (10.3 +?) which makes inefficient refreshes in case an entire control
1059 // area is scrolled, this does not occur if width and height are 2 pixels less,
1060 // TODO: write optimal workaround
1062 HIRect scrollarea
= CGRectMake( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1063 HIViewScrollRect ( m_controlRef
, &scrollarea
, dx
,dy
);
1066 // this would be the preferred version for fast drawing controls
1067 HIViewRender(GetControlRef()) ;
1071 bool wxMacControl::CanFocus() const
1073 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1074 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1075 // but the value range is nowhere documented
1076 Boolean keyExistsAndHasValidFormat
;
1077 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1078 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1080 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1086 UInt32 features
= 0 ;
1087 GetControlFeatures( m_controlRef
, &features
) ;
1089 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1093 bool wxMacControl::GetNeedsDisplay() const
1095 return HIViewGetNeedsDisplay( m_controlRef
);
1098 void wxWidgetImpl::Convert( wxPoint
*pt
, wxWidgetImpl
*from
, wxWidgetImpl
*to
)
1104 HIViewConvertPoint( &hiPoint
, (ControlRef
) from
->GetWXWidget() , (ControlRef
) to
->GetWXWidget() );
1105 pt
->x
= (int)hiPoint
.x
;
1106 pt
->y
= (int)hiPoint
.y
;
1109 bool wxMacControl::SetFocus()
1111 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1112 // we can only leave in case of an error
1114 OSStatus err
= SetKeyboardFocus( GetControlOwner( m_controlRef
), m_controlRef
, kControlFocusNextPart
);
1115 if ( err
== errCouldntSetFocus
)
1117 SetUserFocusWindow(GetControlOwner( m_controlRef
) );
1122 bool wxMacControl::HasFocus() const
1125 GetKeyboardFocus( GetUserFocusWindow() , &control
);
1126 return control
== m_controlRef
;
1129 void wxMacControl::SetCursor(const wxCursor
& cursor
)
1131 wxWindowMac
*mouseWin
= 0 ;
1132 WindowRef window
= GetControlOwner( m_controlRef
) ;
1134 wxNonOwnedWindow
* tlwwx
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) window
) ;
1135 if ( tlwwx
!= NULL
)
1137 ControlPartCode part
;
1138 ControlRef control
;
1140 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1142 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1146 GetGlobalMouse( &pt
);
1149 tlwwx
->ScreenToClient(&x
, &y
);
1153 control
= FindControlUnderMouse( pt
, window
, &part
) ;
1155 mouseWin
= wxFindWindowFromWXWidget( (WXWidget
) control
) ;
1158 if ( mouseWin
== tlwwx
&& !wxIsBusy() )
1159 cursor
.MacInstall() ;
1162 void wxMacControl::CaptureMouse()
1166 void wxMacControl::ReleaseMouse()
1171 // subclass specifics
1174 OSStatus
wxMacControl::GetData(ControlPartCode inPartCode
, ResType inTag
, Size inBufferSize
, void * inOutBuffer
, Size
* outActualSize
) const
1176 return ::GetControlData( m_controlRef
, inPartCode
, inTag
, inBufferSize
, inOutBuffer
, outActualSize
);
1179 OSStatus
wxMacControl::GetDataSize(ControlPartCode inPartCode
, ResType inTag
, Size
* outActualSize
) const
1181 return ::GetControlDataSize( m_controlRef
, inPartCode
, inTag
, outActualSize
);
1184 OSStatus
wxMacControl::SetData(ControlPartCode inPartCode
, ResType inTag
, Size inSize
, const void * inData
)
1186 return ::SetControlData( m_controlRef
, inPartCode
, inTag
, inSize
, inData
);
1189 OSStatus
wxMacControl::SendEvent( EventRef event
, OptionBits inOptions
)
1191 return SendEventToEventTargetWithOptions( event
,
1192 HIObjectGetEventTarget( (HIObjectRef
) m_controlRef
), inOptions
);
1195 OSStatus
wxMacControl::SendHICommand( HICommand
&command
, OptionBits inOptions
)
1197 wxMacCarbonEvent
event( kEventClassCommand
, kEventCommandProcess
);
1199 event
.SetParameter
<HICommand
>(kEventParamDirectObject
,command
);
1201 return SendEvent( event
, inOptions
);
1204 OSStatus
wxMacControl::SendHICommand( UInt32 commandID
, OptionBits inOptions
)
1208 memset( &command
, 0 , sizeof(command
) );
1209 command
.commandID
= commandID
;
1210 return SendHICommand( command
, inOptions
);
1213 void wxMacControl::PerformClick()
1215 HIViewSimulateClick (m_controlRef
, kControlButtonPart
, 0, NULL
);
1218 wxInt32
wxMacControl::GetValue() const
1220 return ::GetControl32BitValue( m_controlRef
);
1223 wxInt32
wxMacControl::GetMaximum() const
1225 return ::GetControl32BitMaximum( m_controlRef
);
1228 wxInt32
wxMacControl::GetMinimum() const
1230 return ::GetControl32BitMinimum( m_controlRef
);
1233 void wxMacControl::SetValue( wxInt32 v
)
1235 ::SetControl32BitValue( m_controlRef
, v
);
1238 void wxMacControl::SetMinimum( wxInt32 v
)
1240 ::SetControl32BitMinimum( m_controlRef
, v
);
1243 void wxMacControl::SetMaximum( wxInt32 v
)
1245 ::SetControl32BitMaximum( m_controlRef
, v
);
1248 void wxMacControl::SetValueAndRange( SInt32 value
, SInt32 minimum
, SInt32 maximum
)
1250 ::SetControl32BitMinimum( m_controlRef
, minimum
);
1251 ::SetControl32BitMaximum( m_controlRef
, maximum
);
1252 ::SetControl32BitValue( m_controlRef
, value
);
1255 void wxMacControl::VisibilityChanged(bool WXUNUSED(shown
))
1259 void wxMacControl::SuperChangedPosition()
1263 void wxMacControl::SetFont( const wxFont
& font
, const wxColour
& foreground
, long windowStyle
, bool ignoreBlack
)
1266 #if wxOSX_USE_CORE_TEXT
1267 if ( UMAGetSystemVersion() >= 0x1050 )
1269 HIViewPartCode part
= 0;
1270 HIThemeTextHorizontalFlush flush
= kHIThemeTextHorizontalFlushDefault
;
1271 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1272 flush
= kHIThemeTextHorizontalFlushCenter
;
1273 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1274 flush
= kHIThemeTextHorizontalFlushRight
;
1275 HIViewSetTextFont( m_controlRef
, part
, (CTFontRef
) font
.OSXGetCTFont() );
1276 HIViewSetTextHorizontalFlush( m_controlRef
, part
, flush
);
1278 if ( foreground
!= *wxBLACK
|| ignoreBlack
== false )
1280 ControlFontStyleRec fontStyle
;
1281 foreground
.GetRGBColor( &fontStyle
.foreColor
);
1282 fontStyle
.flags
= kControlUseForeColorMask
;
1283 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1287 #if wxOSX_USE_ATSU_TEXT
1288 ControlFontStyleRec fontStyle
;
1289 if ( font
.MacGetThemeFontID() != kThemeCurrentPortFont
)
1291 switch ( font
.MacGetThemeFontID() )
1293 case kThemeSmallSystemFont
:
1294 fontStyle
.font
= kControlFontSmallSystemFont
;
1297 case 109 : // mini font
1298 fontStyle
.font
= -5;
1301 case kThemeSystemFont
:
1302 fontStyle
.font
= kControlFontBigSystemFont
;
1306 fontStyle
.font
= kControlFontBigSystemFont
;
1310 fontStyle
.flags
= kControlUseFontMask
;
1314 fontStyle
.font
= font
.MacGetFontNum();
1315 fontStyle
.style
= font
.MacGetFontStyle();
1316 fontStyle
.size
= font
.GetPointSize();
1317 fontStyle
.flags
= kControlUseFontMask
| kControlUseFaceMask
| kControlUseSizeMask
;
1320 fontStyle
.just
= teJustLeft
;
1321 fontStyle
.flags
|= kControlUseJustMask
;
1322 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1323 fontStyle
.just
= teJustCenter
;
1324 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1325 fontStyle
.just
= teJustRight
;
1328 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
1329 // won't get grayed out by the system anymore
1331 if ( foreground
!= *wxBLACK
|| ignoreBlack
== false )
1333 foreground
.GetRGBColor( &fontStyle
.foreColor
);
1334 fontStyle
.flags
|= kControlUseForeColorMask
;
1337 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1341 void wxMacControl::SetBackgroundColour( const wxColour
&WXUNUSED(col
) )
1343 // HITextViewSetBackgroundColor( m_textView , color );
1346 bool wxMacControl::SetBackgroundStyle(wxBackgroundStyle style
)
1348 if ( style
!= wxBG_STYLE_PAINT
)
1350 OSStatus err
= HIViewChangeFeatures(m_controlRef
, 0 , kHIViewIsOpaque
);
1351 verify_noerr( err
);
1355 OSStatus err
= HIViewChangeFeatures(m_controlRef
, kHIViewIsOpaque
, 0);
1356 verify_noerr( err
);
1362 void wxMacControl::SetRange( SInt32 minimum
, SInt32 maximum
)
1364 ::SetControl32BitMinimum( m_controlRef
, minimum
);
1365 ::SetControl32BitMaximum( m_controlRef
, maximum
);
1368 short wxMacControl::HandleKey( SInt16 keyCode
, SInt16 charCode
, EventModifiers modifiers
)
1370 return HandleControlKey( m_controlRef
, keyCode
, charCode
, modifiers
);
1373 void wxMacControl::SetActionProc( ControlActionUPP actionProc
)
1375 SetControlAction( m_controlRef
, actionProc
);
1378 SInt32
wxMacControl::GetViewSize() const
1380 return GetControlViewSize( m_controlRef
);
1383 bool wxMacControl::IsVisible() const
1385 return IsControlVisible( m_controlRef
);
1388 void wxMacControl::SetVisibility( bool visible
)
1390 SetControlVisibility( m_controlRef
, visible
, true );
1393 bool wxMacControl::IsEnabled() const
1395 return IsControlEnabled( m_controlRef
);
1398 bool wxMacControl::IsActive() const
1400 return IsControlActive( m_controlRef
);
1403 void wxMacControl::Enable( bool enable
)
1406 EnableControl( m_controlRef
);
1408 DisableControl( m_controlRef
);
1411 void wxMacControl::SetDrawingEnabled( bool enable
)
1415 HIViewSetDrawingEnabled( m_controlRef
, true );
1416 HIViewSetNeedsDisplay( m_controlRef
, true);
1420 HIViewSetDrawingEnabled( m_controlRef
, false );
1424 void wxMacControl::GetRectInWindowCoords( Rect
*r
)
1426 GetControlBounds( m_controlRef
, r
) ;
1428 WindowRef tlwref
= GetControlOwner( m_controlRef
) ;
1430 wxNonOwnedWindow
* tlwwx
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) tlwref
) ;
1431 if ( tlwwx
!= NULL
)
1433 ControlRef rootControl
= tlwwx
->GetPeer()->GetControlRef() ;
1434 HIPoint hiPoint
= CGPointMake( 0 , 0 ) ;
1435 HIViewConvertPoint( &hiPoint
, HIViewGetSuperview(m_controlRef
) , rootControl
) ;
1436 OffsetRect( r
, (short) hiPoint
.x
, (short) hiPoint
.y
) ;
1440 void wxMacControl::GetBestRect( wxRect
*rect
) const
1442 short baselineoffset
;
1445 GetBestControlRect( m_controlRef
, &r
, &baselineoffset
);
1446 *rect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
-r
.top
);
1449 void wxMacControl::GetBestRect( Rect
*r
) const
1451 short baselineoffset
;
1452 GetBestControlRect( m_controlRef
, r
, &baselineoffset
);
1455 void wxMacControl::SetLabel( const wxString
&title
, wxFontEncoding encoding
)
1457 SetControlTitleWithCFString( m_controlRef
, wxCFStringRef( title
, encoding
) );
1460 void wxMacControl::GetFeatures( UInt32
* features
)
1462 GetControlFeatures( m_controlRef
, features
);
1465 void wxMacControl::PulseGauge()
1469 // SetNeedsDisplay would not invalidate the children
1470 static void InvalidateControlAndChildren( HIViewRef control
)
1472 HIViewSetNeedsDisplay( control
, true );
1473 UInt16 childrenCount
= 0;
1474 OSStatus err
= CountSubControls( control
, &childrenCount
);
1475 if ( err
== errControlIsNotEmbedder
)
1478 wxASSERT_MSG( err
== noErr
, wxT("Unexpected error when accessing subcontrols") );
1480 for ( UInt16 i
= childrenCount
; i
>=1; --i
)
1484 err
= GetIndexedSubControl( control
, i
, & child
);
1485 if ( err
== errControlIsNotEmbedder
)
1488 InvalidateControlAndChildren( child
);
1492 void wxMacControl::InvalidateWithChildren()
1494 InvalidateControlAndChildren( m_controlRef
);
1497 OSType wxMacCreator
= 'WXMC';
1498 OSType wxMacControlProperty
= 'MCCT';
1500 void wxMacControl::SetReferenceInNativeControl()
1503 verify_noerr( SetControlProperty ( m_controlRef
,
1504 wxMacCreator
,wxMacControlProperty
, sizeof(data
), &data
) );
1507 wxMacControl
* wxMacControl::GetReferenceFromNativeControl(ControlRef control
)
1509 wxMacControl
* ctl
= NULL
;
1510 ByteCount actualSize
;
1511 if ( GetControlProperty( control
,wxMacCreator
,wxMacControlProperty
, sizeof(ctl
) ,
1512 &actualSize
, &ctl
) == noErr
)
1519 wxBitmap
wxMacControl::GetBitmap() const
1521 return wxNullBitmap
;
1524 void wxMacControl::SetBitmap( const wxBitmap
& WXUNUSED(bmp
) )
1526 // implemented in the respective subclasses
1529 void wxMacControl::SetBitmapPosition( wxDirection
WXUNUSED(dir
) )
1531 // implemented in the same subclasses that implement SetBitmap()
1534 void wxMacControl::SetScrollThumb( wxInt32
WXUNUSED(pos
), wxInt32
WXUNUSED(viewsize
) )
1536 // implemented in respective subclass
1543 OSStatus
wxMacControl::SetTabEnabled( SInt16 tabNo
, bool enable
)
1545 return ::SetTabEnabled( m_controlRef
, tabNo
, enable
);
1552 wxWidgetImplType
* wxWidgetImpl::CreateContentView( wxNonOwnedWindow
* now
)
1554 // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of
1555 // the content view, so we have to retrieve it explicitly
1557 wxMacControl
* contentview
= new wxMacControl(now
, true /*isRootControl*/);
1558 HIViewFindByID( HIViewGetRoot( (WindowRef
) now
->GetWXWindow() ) , kHIViewWindowContentID
,
1559 contentview
->GetControlRefAddr() ) ;
1560 if ( !contentview
->IsOk() )
1562 // compatibility mode fallback
1563 GetRootControl( (WindowRef
) now
->GetWXWindow() , contentview
->GetControlRefAddr() ) ;
1566 // the root control level handler
1567 if ( !now
->IsNativeWindowWrapper() )
1568 contentview
->InstallEventHandler() ;