X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ed9a7a63b811a49214bb97d41cb464d4877da5d7..35bb3cb155917b4287fb2a3841bea22919a3d499:/src/mac/carbon/window.cpp?ds=inline diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index b8a268cd53..b13a595ec9 100644 --- a/src/mac/carbon/window.cpp +++ b/src/mac/carbon/window.cpp @@ -41,6 +41,14 @@ #include "wx/spinctrl.h" #include "wx/geometry.h" +#if wxUSE_LISTCTRL + #include "wx/listctrl.h" +#endif + +#if wxUSE_TREECTRL + #include "wx/treectrl.h" +#endif + #if wxUSE_CARET #include "wx/caret.h" #endif @@ -260,7 +268,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl float alpha = 1.0 ; { wxWindow* iter = thisWindow ; - while ( iter ) + while ( iter ) { alpha *= (float) iter->GetTransparent()/255.0 ; if ( iter->IsTopLevel() ) @@ -270,6 +278,15 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl } } CGContextSetAlpha( cgContext , alpha ) ; + + if ( thisWindow->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT ) + { + HIRect bounds; + HIViewGetBounds( controlRef, &bounds ); + CGContextClearRect( cgContext, bounds ); + } + + #endif if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) ) result = noErr ; @@ -299,17 +316,20 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl case kEventControlHiliteChanged : thisWindow->MacHiliteChanged() ; break ; - + case kEventControlActivate : case kEventControlDeactivate : - if ( thisWindow->IsKindOf( CLASSINFO( wxTreeCtrl ) ) - || thisWindow->IsKindOf( CLASSINFO( wxListCtrl ) ) - ) + // FIXME: we should have a virtual function for this! +#if wxUSE_TREECTRL + if ( thisWindow->IsKindOf( CLASSINFO( wxTreeCtrl ) ) ) + thisWindow->Refresh(); +#endif +#if wxUSE_LISTCTRL + if ( thisWindow->IsKindOf( CLASSINFO( wxListCtrl ) ) ) thisWindow->Refresh(); - - //thisWindow->MacActivateStateChanged() ; - break ; #endif + break ; +#endif // TARGET_API_MAC_OSX // we emulate this event under Carbon CFM case kEventControlSetFocusPart : @@ -323,6 +343,9 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl } #endif + if ( thisWindow->MacIsUserPane() ) + result = noErr ; + if ( controlPart == kControlFocusNoPart ) { #if wxUSE_CARET @@ -356,9 +379,6 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl event.SetEventObject(thisWindow); thisWindow->GetEventHandler()->ProcessEvent(event) ; } - - if ( thisWindow->MacIsUserPane() ) - result = noErr ; } break ; @@ -385,7 +405,10 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl return result ; } -static pascal OSStatus wxMacWindowServiceEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +static pascal OSStatus +wxMacWindowServiceEventHandler(EventHandlerCallRef WXUNUSED(handler), + EventRef event, + void *data) { OSStatus result = eventNotHandledErr ; @@ -500,7 +523,7 @@ pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , Even charBuf[ numChars - 1 ] = 0; #if SIZEOF_WCHAR_T == 2 uniChars = (wchar_t*) charBuf ; - memcpy( uniChars , charBuf , numChars * 2 ) ; +/* 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 ; @@ -520,7 +543,32 @@ pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , Even WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ; wxTheApp->MacSetCurrentEvent( event , handler ) ; + 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: 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 +*/ if ( wxTheApp->MacSendCharEvent( focus , message , 0 , when , 0 , 0 , uniChars[pos] ) ) { @@ -575,7 +623,10 @@ pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , Even return result ; } -static pascal OSStatus wxMacWindowCommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +static pascal OSStatus +wxMacWindowCommandEventHandler(EventHandlerCallRef WXUNUSED(handler), + EventRef event, + void *data) { OSStatus result = eventNotHandledErr ; wxWindowMac* focus = (wxWindowMac*) data ; @@ -926,10 +977,6 @@ void wxWindowMac::Init() m_frozenness = 0 ; m_macAlpha = 255 ; -#if WXWIN_COMPATIBILITY_2_4 - m_backgroundTransparent = false; -#endif - #if wxMAC_USE_CORE_GRAPHICS m_cgContextRef = NULL ; #endif @@ -939,6 +986,9 @@ void wxWindowMac::Init() m_hScrollBar = NULL ; m_vScrollBar = NULL ; + m_hScrollBarAlwaysShown = false; + m_vScrollBarAlwaysShown = false; + m_macBackgroundBrush = wxNullBrush ; m_macIsUserPane = true; @@ -1103,7 +1153,7 @@ void wxWindowMac::MacChildAdded() m_hScrollBar->Raise() ; } -void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size) +void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), const wxSize& size) { wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid mac control") ) ; @@ -1350,7 +1400,7 @@ void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget) #endif // Old-style File Manager Drag & Drop -void wxWindowMac::DragAcceptFiles(bool accept) +void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept)) { // TODO: } @@ -1358,8 +1408,10 @@ void wxWindowMac::DragAcceptFiles(bool accept) // Returns the size of the native control. In the case of the toplevel window // this is the content area root control -void wxWindowMac::MacGetPositionAndSizeFromControl(int& x, int& y, - int& w, int& h) const +void wxWindowMac::MacGetPositionAndSizeFromControl(int& WXUNUSED(x), + int& WXUNUSED(y), + int& WXUNUSED(w), + int& WXUNUSED(h)) const { wxFAIL_MSG( wxT("Not currently supported") ) ; } @@ -1719,7 +1771,7 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor) HIGetMousePosition(kHICoordSpaceWindow, window, &hiPoint); pt.h = hiPoint.x; pt.v = hiPoint.y; - #else + #else CGrafPtr savePort ; Boolean swapped = QDSwapPort( GetWindowPort( window ) , &savePort ) ; @@ -2107,19 +2159,9 @@ bool wxWindowMac::Show(bool show) return true; } -bool wxWindowMac::Enable(bool enable) +void wxWindowMac::DoEnable(bool enable) { - wxASSERT( m_peer->Ok() ) ; - bool former = MacIsReallyEnabled() ; - if ( !wxWindowBase::Enable(enable) ) - return false; - m_peer->Enable( enable ) ; - - if ( former != MacIsReallyEnabled() ) - MacPropagateEnabledStateChanged() ; - - return true; } // @@ -2144,21 +2186,10 @@ void wxWindowMac::MacPropagateVisibilityChanged() #endif } -void wxWindowMac::MacPropagateEnabledStateChanged() +void wxWindowMac::OnEnabled(bool WXUNUSED(enabled)) { #if !TARGET_API_MAC_OSX MacEnabledStateChanged() ; - - wxWindowMac *child; - wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - while ( node ) - { - child = node->GetData(); - if ( child->IsEnabled() ) - child->MacPropagateEnabledStateChanged() ; - - node = node->GetNext(); - } #endif } @@ -2264,7 +2295,7 @@ void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y, fontToUse = &m_font; wxClientDC dc( (wxWindowMac*) this ) ; - long lx,ly,ld,le ; + wxCoord lx,ly,ld,le ; dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ; if ( externalLeading ) *externalLeading = le ; @@ -2281,7 +2312,7 @@ void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y, * we always intersect with the entire window, not only with the client area */ -void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect) +void wxWindowMac::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect) { if ( m_peer == NULL ) return ; @@ -2341,7 +2372,7 @@ wxWindowMac *wxGetActiveWindow() } // Coordinates relative to the window -void wxWindowMac::WarpPointer(int x_pos, int y_pos) +void wxWindowMac::WarpPointer(int WXUNUSED(x_pos), int WXUNUSED(y_pos)) { // We really don't move the mouse programmatically under Mac. } @@ -2352,7 +2383,8 @@ void wxWindowMac::OnEraseBackground(wxEraseEvent& event) return ; #if TARGET_API_MAC_OSX - if ( !m_macBackgroundBrush.Ok() || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT ) + if ( !m_macBackgroundBrush.Ok() || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT + || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT ) { event.Skip() ; } @@ -2418,7 +2450,7 @@ int wxWindowMac::GetScrollThumb(int orient) const return 0; } -void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh) +void wxWindowMac::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh)) { if ( orient == wxHORIZONTAL ) { @@ -2432,12 +2464,32 @@ void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh) } } +void +wxWindowMac::AlwaysShowScrollbars(bool hflag, bool vflag) +{ + bool needVisibilityUpdate = false; + + if ( m_hScrollBarAlwaysShown != hflag ) + { + m_hScrollBarAlwaysShown = hflag; + needVisibilityUpdate = true; + } + + if ( m_vScrollBarAlwaysShown != vflag ) + { + m_vScrollBarAlwaysShown = vflag; + needVisibilityUpdate = true; + } + + if ( needVisibilityUpdate ) + DoUpdateScrollbarVisibility(); +} // // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef // our own window origin is at leftOrigin/rightOrigin // -void wxWindowMac::MacPaintBorders( int leftOrigin , int rightOrigin ) +void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(rightOrigin) ) { if ( IsTopLevel() ) return ; @@ -2450,7 +2502,7 @@ void wxWindowMac::MacPaintBorders( int leftOrigin , int rightOrigin ) m_peer->GetRect( &rect ) ; InsetRect( &rect, -1 , -1 ) ; -#if wxMAC_USE_CORE_GRAPHICS +#if wxMAC_USE_CORE_GRAPHICS { CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left , rect.bottom - rect.top ) ; @@ -2534,39 +2586,29 @@ void wxWindowMac::RemoveChild( wxWindowBase *child ) wxWindowBase::RemoveChild( child ) ; } -// New function that will replace some of the above. -void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible, - int range, bool refresh) +void wxWindowMac::DoUpdateScrollbarVisibility() { - bool showScroller; bool triggerSizeEvent = false; - if ( orient == wxHORIZONTAL ) + if ( m_hScrollBar ) { - if ( m_hScrollBar ) - { - showScroller = ((range != 0) && (range > thumbVisible)); - if ( m_hScrollBar->IsShown() != showScroller ) - { - m_hScrollBar->Show( showScroller ); - triggerSizeEvent = true; - } + bool showHScrollBar = m_hScrollBarAlwaysShown || m_hScrollBar->IsNeeded(); - m_hScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ; + if ( m_hScrollBar->IsShown() != showHScrollBar ) + { + m_hScrollBar->Show( showHScrollBar ); + triggerSizeEvent = true; } } - else + + if ( m_vScrollBar) { - if ( m_vScrollBar ) - { - showScroller = ((range != 0) && (range > thumbVisible)); - if ( m_vScrollBar->IsShown() != showScroller ) - { - m_vScrollBar->Show( showScroller ) ; - triggerSizeEvent = true; - } + bool showVScrollBar = m_vScrollBarAlwaysShown || m_vScrollBar->IsNeeded(); - m_vScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ; + if ( m_vScrollBar->IsShown() != showVScrollBar ) + { + m_vScrollBar->Show( showVScrollBar ) ; + triggerSizeEvent = true; } } @@ -2579,6 +2621,18 @@ void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible, } } +// New function that will replace some of the above. +void wxWindowMac::SetScrollbar(int orient, int pos, int thumb, + int range, bool refresh) +{ + if ( orient == wxHORIZONTAL && m_hScrollBar ) + m_hScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh); + else if ( orient == wxVERTICAL && m_vScrollBar ) + m_vScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh); + + DoUpdateScrollbarVisibility(); +} + // Does a physical scroll void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) { @@ -2599,6 +2653,7 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) if ( m_peer->GetNeedsDisplay() ) { // because HIViewScrollRect does not scroll the already invalidated area we have two options: + // in case there is already a pending redraw on that area // either immediate redraw or full invalidate #if 1 // is the better overall solution, as it does not slow down scrolling @@ -2619,14 +2674,8 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ; m_peer->ScrollRect( &scrollrect , dx , dy ) ; - // becuase HIViewScrollRect does not scroll the already invalidated area we have two options - // either immediate redraw or full invalidate #if 0 - // is the better overall solution, as it does not slow down scrolling - m_peer->SetNeedsDisplay() ; -#else // this would be the preferred version for fast drawing controls - HIViewRender(m_peer->GetControlRef()) ; #endif } @@ -2651,11 +2700,11 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) { wxRect rc( x, y, w, h ); if (rect->Intersects( rc )) - child->SetSize( x + dx, y + dy, w, h ); + child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE ); } else { - child->SetSize( x + dx, y + dy, w, h ); + child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE ); } } } @@ -2720,7 +2769,7 @@ void wxWindowMac::OnSetFocus( wxFocusEvent& event ) Rect rect ; m_peer->GetRect( &rect ) ; - // auf den umgebenden Rahmen zurŸck + // auf den umgebenden Rahmen zurÂŸck InsetRect( &rect, -1 , -1 ) ; wxTopLevelWindowMac* top = MacGetTopLevelWindow(); @@ -2807,7 +2856,7 @@ bool wxWindowMac::MacSetupCursor( const wxPoint& pt ) return cursor.Ok() ; } -wxString wxWindowMac::MacGetToolTipString( wxPoint &pt ) +wxString wxWindowMac::MacGetToolTipString( wxPoint &WXUNUSED(pt) ) { #if wxUSE_TOOLTIPS if ( m_tooltip ) @@ -2826,7 +2875,9 @@ void wxWindowMac::ClearBackground() void wxWindowMac::Update() { #if TARGET_API_MAC_OSX - MacGetTopLevelWindow()->MacPerformUpdates() ; + wxTopLevelWindowMac* top = MacGetTopLevelWindow(); + if (top) + top->MacPerformUpdates() ; #else ::Draw1Control( m_peer->GetControlRef() ) ; #endif @@ -3059,7 +3110,7 @@ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time ) eventNc.SetEventObject( child ); if ( !child->GetEventHandler()->ProcessEvent( eventNc ) ) { -#if wxMAC_USE_CORE_GRAPHICS +#if wxMAC_USE_CORE_GRAPHICS child->MacPaintBorders(0, 0) ; #else { @@ -3333,15 +3384,18 @@ void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) } } -void wxWindowMac::OnPaint( wxPaintEvent & event ) +void wxWindowMac::OnPaint( wxPaintEvent & WXUNUSED(event) ) { - if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL ) + if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL + && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT ) CallNextEventHandler( (EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() , (EventRef) wxTheApp->MacGetCurrentEvent() ) ; } -void wxWindowMac::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED( mouseStillDown ) ) +void wxWindowMac::MacHandleControlClick(WXWidget WXUNUSED(control), + wxInt16 WXUNUSED(controlpart), + bool WXUNUSED(mouseStillDown)) { } @@ -3379,6 +3433,8 @@ bool wxWindowMac::Reparent(wxWindowBase *newParentBase) bool wxWindowMac::SetTransparent(wxByte alpha) { #if wxMAC_USE_CORE_GRAPHICS + SetBackgroundStyle(wxBG_STYLE_TRANSPARENT); + if ( alpha != m_macAlpha ) { m_macAlpha = alpha ; @@ -3400,7 +3456,7 @@ bool wxWindowMac::CanSetTransparent() #endif } -wxByte wxWindowMac::GetTransparent() const +wxByte wxWindowMac::GetTransparent() const { return m_macAlpha ; }