EVT_NC_PAINT(wxWindowMac::OnNcPaint)
EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground)
EVT_PAINT(wxWindowMac::OnPaint)
- EVT_SET_FOCUS(wxWindowMac::OnSetFocus)
- EVT_KILL_FOCUS(wxWindowMac::OnSetFocus)
EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent)
END_EVENT_TABLE()
{ kEventClassControl , kEventControlDeactivate } ,
{ kEventClassControl , kEventControlSetFocusPart } ,
+ { kEventClassControl , kEventControlFocusPartChanged } ,
{ kEventClassService , kEventServiceGetTypes },
{ kEventClassService , kEventServiceCopy },
CGContextClearRect( cgContext, bounds );
}
-
-
+
+
if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
result = noErr ;
#endif
break ;
- // we emulate this event under Carbon CFM
- case kEventControlSetFocusPart :
+ //
+ // focus handling
+ // different handling on OS X
+ //
+
+ case kEventControlFocusPartChanged :
+ // the event is emulated by wxmac for systems lower than 10.5
{
- Boolean focusEverything = false ;
- ControlPartCode controlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
+ ControlPartCode previousControlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPreviousPart , typeControlPartCode );
+ ControlPartCode currentControlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlCurrentPart , typeControlPartCode );
- if ( cEvent.GetParameter<Boolean>(kEventParamControlFocusEverything , &focusEverything ) == noErr )
+ if ( thisWindow->MacGetTopLevelWindow() && thisWindow->GetPeer()->NeedsFocusRect() )
{
+ thisWindow->MacInvalidateBorders();
}
- if ( thisWindow->MacIsUserPane() )
- result = noErr ;
-
- if ( controlPart == kControlFocusNoPart )
+ if ( currentControlPart == 0 )
{
+ // kill focus
#if wxUSE_CARET
if ( thisWindow->GetCaret() )
thisWindow->GetCaret()->OnKillFocus();
#endif
+ wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow));
+
+ // remove this as soon as posting the synthesized event works properly
static bool inKillFocusEvent = false ;
if ( !inKillFocusEvent )
inKillFocusEvent = true ;
wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
- thisWindow->GetEventHandler()->ProcessEvent(event) ;
+ thisWindow->HandleWindowEvent(event) ;
inKillFocusEvent = false ;
}
}
- else
+ else if ( previousControlPart == 0 )
{
+ // set focus
// panel wants to track the window which was the last to have focus in it
- wxChildFocusEvent eventFocus(thisWindow);
- thisWindow->GetEventHandler()->ProcessEvent(eventFocus);
+ wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow));
+ wxChildFocusEvent eventFocus((wxWindow*)thisWindow);
+ thisWindow->HandleWindowEvent(eventFocus);
#if wxUSE_CARET
if ( thisWindow->GetCaret() )
wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
- thisWindow->GetEventHandler()->ProcessEvent(event) ;
+ thisWindow->HandleWindowEvent(event) ;
+ }
+ }
+ break;
+ case kEventControlSetFocusPart :
+ {
+#ifdef __WXMAC_OSX__
+ Boolean focusEverything = false ;
+ if ( cEvent.GetParameter<Boolean>(kEventParamControlFocusEverything , &focusEverything ) == noErr )
+ {
+ // put a breakpoint here to catch focus everything events
+ }
+#endif
+ ControlPartCode controlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
+
+ ControlPartCode previousControlPart = 0;
+ verify_noerr( HIViewGetFocusPart(controlRef, &previousControlPart));
+
+ if ( thisWindow->MacIsUserPane() )
+ {
+ if ( controlPart != kControlFocusNoPart )
+ cEvent.SetParameter<ControlPartCode>( kEventParamControlPart, typeControlPartCode, 1 ) ;
+ result = noErr ;
+ }
+ else
+ result = CallNextEventHandler(handler, event);
+
+ if ( UMAGetSystemVersion() < 0x1050 )
+ {
+// set back to 0 if problems arise
+#if 1
+ ControlPartCode currentControlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
+ // synthesize the event focus changed event
+ EventRef evRef = NULL ;
+
+ OSStatus err = MacCreateEvent(
+ NULL , kEventClassControl , kEventControlFocusPartChanged , TicksToEventTime( TickCount() ) ,
+ kEventAttributeUserEvent , &evRef );
+ verify_noerr( err );
+
+ wxMacCarbonEvent iEvent( evRef ) ;
+ iEvent.SetParameter<ControlRef>( kEventParamDirectObject , controlRef ) ;
+ iEvent.SetParameter<ControlPartCode>( kEventParamControlPreviousPart, typeControlPartCode, previousControlPart ) ;
+ iEvent.SetParameter<ControlPartCode>( kEventParamControlCurrentPart, typeControlPartCode, currentControlPart ) ;
+
+#if 0
+ // TODO test this first, avoid double posts etc...
+ PostEventToQueue( GetMainEventQueue(), evRef , kEventPriorityHigh );
+#else
+ wxMacWindowControlEventHandler( NULL , evRef , data ) ;
+#endif
+ ReleaseEvent( evRef ) ;
+#else
+ // old implementation, to be removed if the new one works
+ if ( controlPart == kControlFocusNoPart )
+ {
+#if wxUSE_CARET
+ if ( thisWindow->GetCaret() )
+ thisWindow->GetCaret()->OnKillFocus();
+#endif
+
+ wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow));
+
+ static bool inKillFocusEvent = false ;
+
+ if ( !inKillFocusEvent )
+ {
+ inKillFocusEvent = true ;
+ wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
+ event.SetEventObject(thisWindow);
+ thisWindow->HandleWindowEvent(event) ;
+ inKillFocusEvent = false ;
+ }
+ }
+ else
+ {
+ // panel wants to track the window which was the last to have focus in it
+ wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow));
+ wxChildFocusEvent eventFocus((wxWindow*)thisWindow);
+ thisWindow->HandleWindowEvent(eventFocus);
+
+ #if wxUSE_CARET
+ if ( thisWindow->GetCaret() )
+ thisWindow->GetCaret()->OnSetFocus();
+ #endif
+
+ wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
+ event.SetEventObject(thisWindow);
+ thisWindow->HandleWindowEvent(event) ;
+ }
+#endif
}
}
break ;
case kEventControlGetClickActivation :
{
- // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
+ // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
WindowRef owner = cEvent.GetParameter<WindowRef>(kEventParamWindowRef);
if ( !IsWindowActive(owner) )
{
charBuf[ numChars - 1 ] = 0;
#if SIZEOF_WCHAR_T == 2
uniChars = (wchar_t*) charBuf ;
-/* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
+/* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
#else
// the resulting string will never have more chars than the utf16 version, so this is safe
wxMBConvUTF16 converter ;
UInt32 message = uniChars[pos] < 128 ? (char)uniChars[pos] : '?';
/*
- NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
- multiple times to update the active range during inline input, so this handler will often receive
- uncommited text, which should usually not trigger side effects. It might be a good idea to check the
- kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
- On the other hand, it can be useful for some applications to react to uncommitted text (for example,
- to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
- should add new event types to support advanced text input. For now, I would keep things as they are.
-
- However, the code that was being used caused additional problems:
+ NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
+ multiple times to update the active range during inline input, so this handler will often receive
+ uncommited text, which should usually not trigger side effects. It might be a good idea to check the
+ kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
+ On the other hand, it can be useful for some applications to react to uncommitted text (for example,
+ to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
+ should add new event types to support advanced text input. For now, I would keep things as they are.
+
+ However, the code that was being used caused additional problems:
UInt32 message = (0 << 8) + ((char)uniChars[pos] );
- Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
- input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
- for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
- (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
- (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
- Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
- overlap with Unicode within the (7-bit) ASCII range.
- But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
- for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
- characters as they are and replaces the rest with '?', ensuring that update events are triggered.
- It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
- I don't have time to look into that right now.
- -- CL
+ Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
+ input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
+ for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
+ (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
+ (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
+ Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
+ overlap with Unicode within the (7-bit) ASCII range.
+ But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
+ for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
+ characters as they are and replaces the rest with '?', ensuring that update events are triggered.
+ It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
+ I don't have time to look into that right now.
+ -- CL
*/
if ( wxTheApp->MacSendCharEvent(
focus , message , 0 , when , 0 , 0 , uniChars[pos] ) )
void wxWindowMac::Init()
{
m_peer = NULL ;
- m_frozenness = 0 ;
m_macAlpha = 255 ;
m_cgContextRef = NULL ;
m_peer->SetData<ControlSize>(kControlEntireControl, kControlSizeTag, &size ) ;
wxFont font ;
- font.MacCreateThemeFont( themeFont ) ;
+ font.MacCreateFromThemeFont( themeFont ) ;
SetFont( font ) ;
}
return ;
int outerBorder = MacGetLeftBorderSize() ;
- if ( m_peer->NeedsFocusRect() && m_peer->HasFocus() )
+ if ( m_peer->NeedsFocusRect() /* && m_peer->HasFocus() */ )
outerBorder += 4 ;
if ( outerBorder == 0 )
wxPoint point(actualX, actualY);
wxMoveEvent event(point, m_windowId);
event.SetEventObject(this);
- GetEventHandler()->ProcessEvent(event) ;
+ HandleWindowEvent(event) ;
}
if ( doResize )
wxSize size(actualWidth, actualHeight);
wxSizeEvent event(size, m_windowId);
event.SetEventObject(this);
- GetEventHandler()->ProcessEvent(event);
+ HandleWindowEvent(event);
}
}
}
}
}
-void wxWindowMac::Freeze()
+void wxWindowMac::DoFreeze()
{
#if TARGET_API_MAC_OSX
- if ( !m_frozenness++ )
- {
- if ( m_peer && m_peer->Ok() )
- m_peer->SetDrawingEnabled( false ) ;
- }
+ if ( m_peer && m_peer->Ok() )
+ m_peer->SetDrawingEnabled( false ) ;
#endif
}
-void wxWindowMac::Thaw()
+void wxWindowMac::DoThaw()
{
#if TARGET_API_MAC_OSX
- wxASSERT_MSG( m_frozenness > 0, wxT("Thaw() without matching Freeze()") );
-
- if ( !--m_frozenness )
+ if ( m_peer && m_peer->Ok() )
{
- if ( m_peer && m_peer->Ok() )
- {
- m_peer->SetDrawingEnabled( true ) ;
- m_peer->InvalidateWithChildren() ;
- }
+ m_peer->SetDrawingEnabled( true ) ;
+ m_peer->InvalidateWithChildren() ;
}
#endif
}
-bool wxWindowMac::IsFrozen() const
-{
- return m_frozenness != 0;
-}
-
wxWindowMac *wxGetActiveWindow()
{
// actually this is a windows-only concept
CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ;
wxASSERT( cgContext ) ;
-
+
m_peer->GetRect( &rect ) ;
int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
CGContextSaveGState( cgContext );
-
+
if ( m_backgroundColour.Ok() )
{
- CGContextSetFillColorWithColor( cgContext, m_backgroundColour.GetCGColor() );
+ CGContextSetFillColorWithColor( cgContext, m_backgroundColour.GetCGColor() );
}
else
{
- CGContextSetRGBFillColor( cgContext, 1.0, 1.0 , 1.0 , 1.0 );
+ CGContextSetRGBFillColor( cgContext, 1.0, 1.0 , 1.0 , 1.0 );
}
CGContextFillRect( cgContext, cgrect );
CGContextRestoreGState( cgContext );
{
wxSizeEvent event(GetSize(), m_windowId);
event.SetEventObject(this);
- GetEventHandler()->ProcessEvent(event);
+ HandleWindowEvent(event);
}
}
else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE)
wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE );
- GetEventHandler()->ProcessEvent(wevent);
+ HandleWindowEvent(wevent);
}
}
return wxFindControlFromMacControl( control ) ;
}
-void wxWindowMac::OnSetFocus( wxFocusEvent& event )
-{
- // panel wants to track the window which was the last to have focus in it,
- // so we want to set ourselves as the window which last had focus
- //
- // notice that it's also important to do it upwards the tree because
- // otherwise when the top level panel gets focus, it won't set it back to
- // us, but to some other sibling
-
- // CS: don't know if this is still needed:
- //wxChildFocusEvent eventFocus(this);
- //(void)GetEventHandler()->ProcessEvent(eventFocus);
-
- if ( MacGetTopLevelWindow() && m_peer->NeedsFocusRect() )
- {
- GetParent()->Refresh() ;
- wxMacWindowStateSaver sv( this ) ;
- Rect rect ;
-
- m_peer->GetRect( &rect ) ;
- // auf den umgebenden Rahmen zurチᅡ゚ck
- InsetRect( &rect, -1 , -1 ) ;
-
- wxTopLevelWindowMac* top = MacGetTopLevelWindow();
- if ( top )
- {
- wxPoint pt(0, 0) ;
- wxMacControl::Convert( &pt , GetParent()->m_peer , top->m_peer ) ;
- rect.left += pt.x ;
- rect.right += pt.x ;
- rect.top += pt.y ;
- rect.bottom += pt.y ;
- }
-
- bool bIsFocusEvent = (event.GetEventType() == wxEVT_SET_FOCUS);
- DrawThemeFocusRect( &rect , bIsFocusEvent ) ;
- if ( !bIsFocusEvent )
- {
- // as this erases part of the frame we have to redraw borders
- // and because our z-ordering is not always correct (staticboxes)
- // we have to invalidate things, we cannot simple redraw
- MacInvalidateBorders() ;
- }
- }
-
- event.Skip();
-}
-
void wxWindowMac::OnInternalIdle()
{
// This calls the UI-update mechanism (querying windows for
{
wxSetCursorEvent event( pt.x , pt.y );
- bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
+ bool processedEvtSetCursor = HandleWindowEvent(event);
if ( processedEvtSetCursor && event.HasCursor() )
{
cursor = event.GetCursor() ;
wxEraseEvent eevent( GetId(), dc );
eevent.SetEventObject( this );
- GetEventHandler()->ProcessEvent( eevent );
+ HandleWindowEvent( eevent );
delete dc ;
}
wxPaintEvent event;
event.SetTimestamp(time);
event.SetEventObject(this);
- GetEventHandler()->ProcessEvent(event);
+ HandleWindowEvent(event);
handled = true ;
}
// paint custom borders
wxNcPaintEvent eventNc( child->GetId() );
eventNc.SetEventObject( child );
- if ( !child->GetEventHandler()->ProcessEvent( eventNc ) )
+ if ( !child->HandleWindowEvent( eventNc ) )
{
child->MacPaintBorders(0, 0) ;
}
wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
this->GetId(),
this->ClientToScreen(event.GetPosition()));
- if ( ! GetEventHandler()->ProcessEvent(evtCtx) )
+ evtCtx.SetEventObject(this);
+ if ( ! HandleWindowEvent(evtCtx) )
event.Skip() ;
}
else