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 // the resulting string will never have more chars than the utf16 version, so this is safe
614 wxMBConvUTF16 converter
;
615 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
618 switch ( GetEventKind( event
) )
620 case kEventTextInputUpdateActiveInputArea
:
622 // An IME input event may return several characters, but we need to send one char at a time to
624 for (int pos
=0 ; pos
< numChars
; pos
++)
626 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
627 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
628 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
630 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
632 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
633 multiple times to update the active range during inline input, so this handler will often receive
634 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
635 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
636 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
637 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
638 should add new event types to support advanced text input. For now, I would keep things as they are.
640 However, the code that was being used caused additional problems:
641 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
642 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
643 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
644 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
645 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
646 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
647 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
648 overlap with Unicode within the (7-bit) ASCII range.
649 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
650 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
651 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
652 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
653 I don't have time to look into that right now.
656 if ( wxTheApp
->MacSendCharEvent(
657 focus
, message
, 0 , when
, 0 , 0 , uniChars
[pos
] ) )
662 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
666 case kEventTextInputUnicodeForKeyEvent
:
668 UInt32 keyCode
, modifiers
;
671 unsigned char charCode
;
673 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
674 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
675 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
676 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
677 GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
679 UInt32 message
= (keyCode
<< 8) + charCode
;
681 // An IME input event may return several characters, but we need to send one char at a time to
683 for (int pos
=0 ; pos
< numChars
; pos
++)
685 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
686 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
687 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
689 if ( wxTheApp
->MacSendCharEvent(
690 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChars
[pos
] ) )
695 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
704 if ( charBuf
!= buf
)
710 static pascal OSStatus
711 wxMacWindowCommandEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
715 OSStatus result
= eventNotHandledErr
;
716 wxWindowMac
* focus
= (wxWindowMac
*) data
;
720 wxMacCarbonEvent
cEvent( event
) ;
721 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
723 wxMenuItem
* item
= NULL
;
724 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
728 wxASSERT( itemMenu
!= NULL
) ;
730 switch ( cEvent
.GetKind() )
732 case kEventProcessCommand
:
733 if ( itemMenu
->HandleCommandProcess( item
, focus
) )
737 case kEventCommandUpdateStatus
:
738 if ( itemMenu
->HandleCommandUpdateStatus( item
, focus
) )
749 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
751 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
752 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
753 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
754 OSStatus result
= eventNotHandledErr
;
756 switch ( GetEventClass( event
) )
758 case kEventClassCommand
:
759 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
762 case kEventClassControl
:
763 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
766 case kEventClassService
:
767 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
770 case kEventClassTextInput
:
771 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
778 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
783 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
785 // ---------------------------------------------------------------------------
786 // Scrollbar Tracking for all
787 // ---------------------------------------------------------------------------
789 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
790 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
794 wxWindow
* wx
= wxFindWindowFromWXWidget( (WXWidget
) control
) ;
797 wxEventType scrollEvent
= wxEVT_NULL
;
800 case kControlUpButtonPart
:
801 scrollEvent
= wxEVT_SCROLL_LINEUP
;
804 case kControlDownButtonPart
:
805 scrollEvent
= wxEVT_SCROLL_LINEDOWN
;
808 case kControlPageUpPart
:
809 scrollEvent
= wxEVT_SCROLL_PAGEUP
;
812 case kControlPageDownPart
:
813 scrollEvent
= wxEVT_SCROLL_PAGEDOWN
;
816 case kControlIndicatorPart
:
817 scrollEvent
= wxEVT_SCROLL_THUMBTRACK
;
818 // when this is called as a live proc, mouse is always still down
819 // so no need for thumbrelease
820 // scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
823 wx
->TriggerScrollEvent(scrollEvent
) ;
827 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
829 wxWidgetImplType
* wxWidgetImpl::CreateUserPane( wxWindowMac
* wxpeer
,
830 wxWindowMac
* WXUNUSED(parent
),
831 wxWindowID
WXUNUSED(id
),
834 long WXUNUSED(style
),
835 long WXUNUSED(extraStyle
))
837 OSStatus err
= noErr
;
838 Rect bounds
= wxMacGetBoundsForControl( wxpeer
, pos
, size
) ;
839 wxMacControl
* c
= new wxMacControl(wxpeer
, false, true) ;
841 | kControlSupportsEmbedding
842 | kControlSupportsLiveFeedback
843 | kControlGetsFocusOnClick
844 // | kControlHasSpecialBackground
845 // | kControlSupportsCalcBestRect
846 | kControlHandlesTracking
847 | kControlSupportsFocus
848 | kControlWantsActivate
849 | kControlWantsIdle
;
851 err
=::CreateUserPaneControl( MAC_WXHWND(wxpeer
->GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, c
->GetControlRefAddr() );
857 void wxMacControl::InstallEventHandler( WXWidget control
)
859 wxWidgetImpl::Associate( control
? control
: (WXWidget
) m_controlRef
, this ) ;
860 ::InstallControlEventHandler( control
? (ControlRef
) control
: m_controlRef
, GetwxMacWindowEventHandlerUPP(),
861 GetEventTypeCount(eventList
), eventList
, GetWXPeer(), NULL
);
864 IMPLEMENT_DYNAMIC_CLASS( wxMacControl
, wxWidgetImpl
)
866 wxMacControl::wxMacControl()
871 wxMacControl::wxMacControl(wxWindowMac
* peer
, bool isRootControl
, bool isUserPane
) :
872 wxWidgetImpl( peer
, isRootControl
, isUserPane
)
877 wxMacControl::~wxMacControl()
879 if ( m_controlRef
&& !IsRootControl() )
881 wxASSERT_MSG( m_controlRef
!= NULL
, wxT("Control Handle already NULL, Dispose called twice ?") );
882 wxASSERT_MSG( IsValidControlHandle(m_controlRef
) , wxT("Invalid Control Handle (maybe already released) in Dispose") );
884 wxWidgetImpl::RemoveAssociations( this ) ;
885 // we cannot check the ref count here anymore, as autorelease objects might delete their refs later
886 // we can have situations when being embedded, where the control gets deleted behind our back, so only
887 // CFRelease if we are safe
888 if ( IsValidControlHandle(m_controlRef
) )
889 CFRelease(m_controlRef
);
894 void wxMacControl::Init()
897 m_macControlEventHandler
= NULL
;
900 void wxMacControl::RemoveFromParent()
902 // nothing to do here for carbon
903 HIViewRemoveFromSuperview(m_controlRef
);
906 void wxMacControl::Embed( wxWidgetImpl
*parent
)
908 HIViewAddSubview((ControlRef
)parent
->GetWXWidget(), m_controlRef
);
911 void wxMacControl::SetNeedsDisplay( const wxRect
* rect
)
918 HIRect updatearea
= CGRectMake( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
919 HIViewSetNeedsDisplayInRect( m_controlRef
, &updatearea
, true );
922 HIViewSetNeedsDisplay( m_controlRef
, true );
925 void wxMacControl::Raise()
927 verify_noerr( HIViewSetZOrder( m_controlRef
, kHIViewZOrderAbove
, NULL
) );
930 void wxMacControl::Lower()
932 verify_noerr( HIViewSetZOrder( m_controlRef
, kHIViewZOrderBelow
, NULL
) );
935 void wxMacControl::GetContentArea(int &left
, int &top
, int &width
, int &height
) const
937 HIShapeRef rgn
= NULL
;
940 if ( HIViewCopyShape(m_controlRef
, kHIViewContentMetaPart
, &rgn
) == noErr
)
943 HIShapeGetBounds(rgn
, &cgrect
);
944 content
= (Rect
){ (short)cgrect
.origin
.y
,
945 (short)cgrect
.origin
.x
,
946 (short)(cgrect
.origin
.y
+cgrect
.size
.height
),
947 (short)(cgrect
.origin
.x
+cgrect
.size
.width
) };
952 GetControlBounds(m_controlRef
, &content
);
953 content
.right
-= content
.left
;
955 content
.bottom
-= content
.top
;
962 width
= content
.right
- content
.left
;
963 height
= content
.bottom
- content
.top
;
966 void wxMacControl::Move(int x
, int y
, int width
, int height
)
969 GetWindowAttributes( GetControlOwner(m_controlRef
) , &attr
) ;
971 HIRect hir
= CGRectMake(x
,y
,width
,height
);
972 if ( !(attr
& kWindowCompositingAttribute
) )
975 HIViewGetFrame( HIViewGetSuperview(m_controlRef
), &parent
);
976 hir
.origin
.x
+= parent
.origin
.x
;
977 hir
.origin
.y
+= parent
.origin
.y
;
979 HIViewSetFrame ( m_controlRef
, &hir
);
982 void wxMacControl::GetPosition( int &x
, int &y
) const
985 GetControlBounds( m_controlRef
, &r
);
990 GetWindowAttributes( GetControlOwner(m_controlRef
) , &attr
) ;
992 if ( !(attr
& kWindowCompositingAttribute
) )
995 HIViewGetFrame( HIViewGetSuperview(m_controlRef
), &parent
);
996 x
-= (int)parent
.origin
.x
;
997 y
-= (int)parent
.origin
.y
;
1002 void wxMacControl::GetSize( int &width
, int &height
) const
1005 GetControlBounds( m_controlRef
, &r
);
1006 width
= r
.right
- r
.left
;
1007 height
= r
.bottom
- r
.top
;
1010 void wxMacControl::SetControlSize( wxWindowVariant variant
)
1015 case wxWINDOW_VARIANT_NORMAL
:
1016 size
= kControlSizeNormal
;
1019 case wxWINDOW_VARIANT_SMALL
:
1020 size
= kControlSizeSmall
;
1023 case wxWINDOW_VARIANT_MINI
:
1024 // not always defined in the headers
1028 case wxWINDOW_VARIANT_LARGE
:
1029 size
= kControlSizeLarge
;
1033 wxFAIL_MSG(wxT("unexpected window variant"));
1037 SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1040 void wxMacControl::ScrollRect( const wxRect
*rect
, int dx
, int dy
)
1042 if (GetNeedsDisplay() )
1044 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
1045 // in case there is already a pending redraw on that area
1046 // either immediate redraw or full invalidate
1048 // is the better overall solution, as it does not slow down scrolling
1051 // this would be the preferred version for fast drawing controls
1052 HIViewRender(GetControlRef()) ;
1056 // note there currently is a bug in OSX (10.3 +?) which makes inefficient refreshes in case an entire control
1057 // area is scrolled, this does not occur if width and height are 2 pixels less,
1058 // TODO: write optimal workaround
1060 HIRect scrollarea
= CGRectMake( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1061 HIViewScrollRect ( m_controlRef
, &scrollarea
, dx
,dy
);
1064 // this would be the preferred version for fast drawing controls
1065 HIViewRender(GetControlRef()) ;
1069 bool wxMacControl::CanFocus() const
1071 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1072 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1073 // but the value range is nowhere documented
1074 Boolean keyExistsAndHasValidFormat
;
1075 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1076 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1078 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1084 UInt32 features
= 0 ;
1085 GetControlFeatures( m_controlRef
, &features
) ;
1087 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1091 bool wxMacControl::GetNeedsDisplay() const
1093 return HIViewGetNeedsDisplay( m_controlRef
);
1096 void wxWidgetImpl::Convert( wxPoint
*pt
, wxWidgetImpl
*from
, wxWidgetImpl
*to
)
1102 HIViewConvertPoint( &hiPoint
, (ControlRef
) from
->GetWXWidget() , (ControlRef
) to
->GetWXWidget() );
1103 pt
->x
= (int)hiPoint
.x
;
1104 pt
->y
= (int)hiPoint
.y
;
1107 bool wxMacControl::SetFocus()
1109 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1110 // we can only leave in case of an error
1112 OSStatus err
= SetKeyboardFocus( GetControlOwner( m_controlRef
), m_controlRef
, kControlFocusNextPart
);
1113 if ( err
== errCouldntSetFocus
)
1115 SetUserFocusWindow(GetControlOwner( m_controlRef
) );
1120 bool wxMacControl::HasFocus() const
1123 GetKeyboardFocus( GetUserFocusWindow() , &control
);
1124 return control
== m_controlRef
;
1127 void wxMacControl::SetCursor(const wxCursor
& cursor
)
1129 wxWindowMac
*mouseWin
= 0 ;
1130 WindowRef window
= GetControlOwner( m_controlRef
) ;
1132 wxNonOwnedWindow
* tlwwx
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) window
) ;
1133 if ( tlwwx
!= NULL
)
1135 ControlPartCode part
;
1136 ControlRef control
;
1138 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1140 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1144 GetGlobalMouse( &pt
);
1147 tlwwx
->ScreenToClient(&x
, &y
);
1151 control
= FindControlUnderMouse( pt
, window
, &part
) ;
1153 mouseWin
= wxFindWindowFromWXWidget( (WXWidget
) control
) ;
1156 if ( mouseWin
== tlwwx
&& !wxIsBusy() )
1157 cursor
.MacInstall() ;
1160 void wxMacControl::CaptureMouse()
1164 void wxMacControl::ReleaseMouse()
1169 // subclass specifics
1172 OSStatus
wxMacControl::GetData(ControlPartCode inPartCode
, ResType inTag
, Size inBufferSize
, void * inOutBuffer
, Size
* outActualSize
) const
1174 return ::GetControlData( m_controlRef
, inPartCode
, inTag
, inBufferSize
, inOutBuffer
, outActualSize
);
1177 OSStatus
wxMacControl::GetDataSize(ControlPartCode inPartCode
, ResType inTag
, Size
* outActualSize
) const
1179 return ::GetControlDataSize( m_controlRef
, inPartCode
, inTag
, outActualSize
);
1182 OSStatus
wxMacControl::SetData(ControlPartCode inPartCode
, ResType inTag
, Size inSize
, const void * inData
)
1184 return ::SetControlData( m_controlRef
, inPartCode
, inTag
, inSize
, inData
);
1187 OSStatus
wxMacControl::SendEvent( EventRef event
, OptionBits inOptions
)
1189 return SendEventToEventTargetWithOptions( event
,
1190 HIObjectGetEventTarget( (HIObjectRef
) m_controlRef
), inOptions
);
1193 OSStatus
wxMacControl::SendHICommand( HICommand
&command
, OptionBits inOptions
)
1195 wxMacCarbonEvent
event( kEventClassCommand
, kEventCommandProcess
);
1197 event
.SetParameter
<HICommand
>(kEventParamDirectObject
,command
);
1199 return SendEvent( event
, inOptions
);
1202 OSStatus
wxMacControl::SendHICommand( UInt32 commandID
, OptionBits inOptions
)
1206 memset( &command
, 0 , sizeof(command
) );
1207 command
.commandID
= commandID
;
1208 return SendHICommand( command
, inOptions
);
1211 void wxMacControl::PerformClick()
1213 HIViewSimulateClick (m_controlRef
, kControlButtonPart
, 0, NULL
);
1216 wxInt32
wxMacControl::GetValue() const
1218 return ::GetControl32BitValue( m_controlRef
);
1221 wxInt32
wxMacControl::GetMaximum() const
1223 return ::GetControl32BitMaximum( m_controlRef
);
1226 wxInt32
wxMacControl::GetMinimum() const
1228 return ::GetControl32BitMinimum( m_controlRef
);
1231 void wxMacControl::SetValue( wxInt32 v
)
1233 ::SetControl32BitValue( m_controlRef
, v
);
1236 void wxMacControl::SetMinimum( wxInt32 v
)
1238 ::SetControl32BitMinimum( m_controlRef
, v
);
1241 void wxMacControl::SetMaximum( wxInt32 v
)
1243 ::SetControl32BitMaximum( m_controlRef
, v
);
1246 void wxMacControl::SetValueAndRange( SInt32 value
, SInt32 minimum
, SInt32 maximum
)
1248 ::SetControl32BitMinimum( m_controlRef
, minimum
);
1249 ::SetControl32BitMaximum( m_controlRef
, maximum
);
1250 ::SetControl32BitValue( m_controlRef
, value
);
1253 void wxMacControl::VisibilityChanged(bool WXUNUSED(shown
))
1257 void wxMacControl::SuperChangedPosition()
1261 void wxMacControl::SetFont( const wxFont
& font
, const wxColour
& foreground
, long windowStyle
, bool ignoreBlack
)
1264 #if wxOSX_USE_CORE_TEXT
1265 if ( UMAGetSystemVersion() >= 0x1050 )
1267 HIViewPartCode part
= 0;
1268 HIThemeTextHorizontalFlush flush
= kHIThemeTextHorizontalFlushDefault
;
1269 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1270 flush
= kHIThemeTextHorizontalFlushCenter
;
1271 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1272 flush
= kHIThemeTextHorizontalFlushRight
;
1273 HIViewSetTextFont( m_controlRef
, part
, (CTFontRef
) font
.OSXGetCTFont() );
1274 HIViewSetTextHorizontalFlush( m_controlRef
, part
, flush
);
1276 if ( foreground
!= *wxBLACK
|| ignoreBlack
== false )
1278 ControlFontStyleRec fontStyle
;
1279 foreground
.GetRGBColor( &fontStyle
.foreColor
);
1280 fontStyle
.flags
= kControlUseForeColorMask
;
1281 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1285 #if wxOSX_USE_ATSU_TEXT
1286 ControlFontStyleRec fontStyle
;
1287 if ( font
.MacGetThemeFontID() != kThemeCurrentPortFont
)
1289 switch ( font
.MacGetThemeFontID() )
1291 case kThemeSmallSystemFont
:
1292 fontStyle
.font
= kControlFontSmallSystemFont
;
1295 case 109 : // mini font
1296 fontStyle
.font
= -5;
1299 case kThemeSystemFont
:
1300 fontStyle
.font
= kControlFontBigSystemFont
;
1304 fontStyle
.font
= kControlFontBigSystemFont
;
1308 fontStyle
.flags
= kControlUseFontMask
;
1312 fontStyle
.font
= font
.MacGetFontNum();
1313 fontStyle
.style
= font
.MacGetFontStyle();
1314 fontStyle
.size
= font
.GetPointSize();
1315 fontStyle
.flags
= kControlUseFontMask
| kControlUseFaceMask
| kControlUseSizeMask
;
1318 fontStyle
.just
= teJustLeft
;
1319 fontStyle
.flags
|= kControlUseJustMask
;
1320 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1321 fontStyle
.just
= teJustCenter
;
1322 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1323 fontStyle
.just
= teJustRight
;
1326 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
1327 // won't get grayed out by the system anymore
1329 if ( foreground
!= *wxBLACK
|| ignoreBlack
== false )
1331 foreground
.GetRGBColor( &fontStyle
.foreColor
);
1332 fontStyle
.flags
|= kControlUseForeColorMask
;
1335 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1339 void wxMacControl::SetBackgroundColour( const wxColour
&WXUNUSED(col
) )
1341 // HITextViewSetBackgroundColor( m_textView , color );
1344 bool wxMacControl::SetBackgroundStyle(wxBackgroundStyle style
)
1346 if ( style
!= wxBG_STYLE_PAINT
)
1348 OSStatus err
= HIViewChangeFeatures(m_controlRef
, 0 , kHIViewIsOpaque
);
1349 verify_noerr( err
);
1353 OSStatus err
= HIViewChangeFeatures(m_controlRef
, kHIViewIsOpaque
, 0);
1354 verify_noerr( err
);
1360 void wxMacControl::SetRange( SInt32 minimum
, SInt32 maximum
)
1362 ::SetControl32BitMinimum( m_controlRef
, minimum
);
1363 ::SetControl32BitMaximum( m_controlRef
, maximum
);
1366 short wxMacControl::HandleKey( SInt16 keyCode
, SInt16 charCode
, EventModifiers modifiers
)
1368 return HandleControlKey( m_controlRef
, keyCode
, charCode
, modifiers
);
1371 void wxMacControl::SetActionProc( ControlActionUPP actionProc
)
1373 SetControlAction( m_controlRef
, actionProc
);
1376 SInt32
wxMacControl::GetViewSize() const
1378 return GetControlViewSize( m_controlRef
);
1381 bool wxMacControl::IsVisible() const
1383 return IsControlVisible( m_controlRef
);
1386 void wxMacControl::SetVisibility( bool visible
)
1388 SetControlVisibility( m_controlRef
, visible
, true );
1391 bool wxMacControl::IsEnabled() const
1393 return IsControlEnabled( m_controlRef
);
1396 bool wxMacControl::IsActive() const
1398 return IsControlActive( m_controlRef
);
1401 void wxMacControl::Enable( bool enable
)
1404 EnableControl( m_controlRef
);
1406 DisableControl( m_controlRef
);
1409 void wxMacControl::SetDrawingEnabled( bool enable
)
1411 HIViewSetDrawingEnabled( m_controlRef
, enable
);
1414 void wxMacControl::GetRectInWindowCoords( Rect
*r
)
1416 GetControlBounds( m_controlRef
, r
) ;
1418 WindowRef tlwref
= GetControlOwner( m_controlRef
) ;
1420 wxNonOwnedWindow
* tlwwx
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) tlwref
) ;
1421 if ( tlwwx
!= NULL
)
1423 ControlRef rootControl
= tlwwx
->GetPeer()->GetControlRef() ;
1424 HIPoint hiPoint
= CGPointMake( 0 , 0 ) ;
1425 HIViewConvertPoint( &hiPoint
, HIViewGetSuperview(m_controlRef
) , rootControl
) ;
1426 OffsetRect( r
, (short) hiPoint
.x
, (short) hiPoint
.y
) ;
1430 void wxMacControl::GetBestRect( wxRect
*rect
) const
1432 short baselineoffset
;
1435 GetBestControlRect( m_controlRef
, &r
, &baselineoffset
);
1436 *rect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
-r
.top
);
1439 void wxMacControl::GetBestRect( Rect
*r
) const
1441 short baselineoffset
;
1442 GetBestControlRect( m_controlRef
, r
, &baselineoffset
);
1445 void wxMacControl::SetLabel( const wxString
&title
, wxFontEncoding encoding
)
1447 SetControlTitleWithCFString( m_controlRef
, wxCFStringRef( title
, encoding
) );
1450 void wxMacControl::GetFeatures( UInt32
* features
)
1452 GetControlFeatures( m_controlRef
, features
);
1455 void wxMacControl::PulseGauge()
1459 // SetNeedsDisplay would not invalidate the children
1460 static void InvalidateControlAndChildren( HIViewRef control
)
1462 HIViewSetNeedsDisplay( control
, true );
1463 UInt16 childrenCount
= 0;
1464 OSStatus err
= CountSubControls( control
, &childrenCount
);
1465 if ( err
== errControlIsNotEmbedder
)
1468 wxASSERT_MSG( err
== noErr
, wxT("Unexpected error when accessing subcontrols") );
1470 for ( UInt16 i
= childrenCount
; i
>=1; --i
)
1474 err
= GetIndexedSubControl( control
, i
, & child
);
1475 if ( err
== errControlIsNotEmbedder
)
1478 InvalidateControlAndChildren( child
);
1482 void wxMacControl::InvalidateWithChildren()
1484 InvalidateControlAndChildren( m_controlRef
);
1487 OSType wxMacCreator
= 'WXMC';
1488 OSType wxMacControlProperty
= 'MCCT';
1490 void wxMacControl::SetReferenceInNativeControl()
1493 verify_noerr( SetControlProperty ( m_controlRef
,
1494 wxMacCreator
,wxMacControlProperty
, sizeof(data
), &data
) );
1497 wxMacControl
* wxMacControl::GetReferenceFromNativeControl(ControlRef control
)
1499 wxMacControl
* ctl
= NULL
;
1500 ByteCount actualSize
;
1501 if ( GetControlProperty( control
,wxMacCreator
,wxMacControlProperty
, sizeof(ctl
) ,
1502 &actualSize
, &ctl
) == noErr
)
1509 wxBitmap
wxMacControl::GetBitmap() const
1511 return wxNullBitmap
;
1514 void wxMacControl::SetBitmap( const wxBitmap
& WXUNUSED(bmp
) )
1516 // implemented in the respective subclasses
1519 void wxMacControl::SetBitmapPosition( wxDirection
WXUNUSED(dir
) )
1521 // implemented in the same subclasses that implement SetBitmap()
1524 void wxMacControl::SetScrollThumb( wxInt32
WXUNUSED(pos
), wxInt32
WXUNUSED(viewsize
) )
1526 // implemented in respective subclass
1533 OSStatus
wxMacControl::SetTabEnabled( SInt16 tabNo
, bool enable
)
1535 return ::SetTabEnabled( m_controlRef
, tabNo
, enable
);
1542 wxWidgetImplType
* wxWidgetImpl::CreateContentView( wxNonOwnedWindow
* now
)
1544 // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of
1545 // the content view, so we have to retrieve it explicitly
1547 wxMacControl
* contentview
= new wxMacControl(now
, true /*isRootControl*/);
1548 HIViewFindByID( HIViewGetRoot( (WindowRef
) now
->GetWXWindow() ) , kHIViewWindowContentID
,
1549 contentview
->GetControlRefAddr() ) ;
1550 if ( !contentview
->IsOk() )
1552 // compatibility mode fallback
1553 GetRootControl( (WindowRef
) now
->GetWXWindow() , contentview
->GetControlRefAddr() ) ;
1556 // the root control level handler
1557 if ( !now
->IsNativeWindowWrapper() )
1558 contentview
->InstallEventHandler() ;