]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/window.cpp
use the window default colours, not hardcoded ones, in OnSysColourChanged()
[wxWidgets.git] / src / mac / carbon / window.cpp
index 808db5c2be435e879386963b3641ec1a11d76801..c30e7a0467f106e922d1be6984865099f2929d2a 100644 (file)
 #include <ToolUtils.h>
 #endif
 
+#if TARGET_API_MAC_OSX
 #ifndef __HIVIEW__
        #include <HIToolbox/HIView.h>
 #endif
+#endif
 
 #if  wxUSE_DRAG_AND_DROP
 #include "wx/dnd.h"
@@ -100,12 +102,23 @@ END_EVENT_TABLE()
 extern long wxMacTranslateKey(unsigned char key, unsigned char code) ;
 pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor ) ;
 
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3
+enum {
+  kEventControlVisibilityChanged = 157
+};
+#endif
+
 static const EventTypeSpec eventList[] =
 {
 #if TARGET_API_MAC_OSX
-       { kEventClassControl , kEventControlDraw } ,
+    { kEventClassControl , kEventControlDraw } ,
+    { kEventClassControl , kEventControlVisibilityChanged } ,
+    { kEventClassControl , kEventControlEnabledStateChanged } ,
+    { kEventClassControl , kEventControlHiliteChanged } ,
 //     { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
 //  { kEventClassControl , kEventControlBoundsChanged } ,
+
+    {}
 #else
     {}
 #endif
@@ -126,26 +139,51 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
     {
         case kEventControlDraw :
             {
-                RgnHandle updateRgn = cEvent.GetParameter<RgnHandle>(kEventParamRgnHandle) ;
+                RgnHandle updateRgn = NULL ;
+
+                wxRegion visRegion = thisWindow->MacGetVisibleRegion() ;
+                if ( cEvent.GetParameter<RgnHandle>(kEventParamRgnHandle, &updateRgn) != noErr ) 
+                {
+                    updateRgn = (RgnHandle) visRegion.GetWXHRGN() ;
+                }
                 // GrafPtr myport = cEvent.GetParameter<GrafPtr>(kEventParamGrafPort,typeGrafPtr) ;
 
-#if 0 // in case we would need a coregraphics compliant background erase first
+#if 0 
+                // in case we would need a coregraphics compliant background erase first
+                // now usable to track redraws
                 CGContextRef cgContext = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef) ;
                 if ( thisWindow->MacIsUserPane() )
                 {
+                    static float color = 0.5 ;
+                    static channel = 0 ;
                        HIRect bounds;
-                       err = HIViewGetBounds( controlRef, &bounds );
-                                   CGContextSetRGBFillColor( cgContext, 1 , 1 , 1 , 1 );
-//                                 CGContextSetRGBFillColor( cgContext, .95, .95, .95, 1 );
+                       HIViewGetBounds( controlRef, &bounds );
+                                   CGContextSetRGBFillColor( cgContext, channel == 0 ? color : 0.5 , 
+                                       channel == 1 ? color : 0.5 , channel == 2 ? color : 0.5 , 1 );
                                    CGContextFillRect( cgContext, bounds );
+                                   color += 0.1 ;
+                                   if ( color > 0.9 )
+                                   {
+                                       color = 0.5 ;
+                                       channel++ ;
+                                       if ( channel == 3 )
+                                           channel = 0 ;
+                                   }
                 }
 #endif
                 if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
                     result = noErr ;
-                else
-                    result = eventNotHandledErr; 
             }
             break ;
+        case kEventControlVisibilityChanged :
+                thisWindow->MacVisibilityChanged() ;
+            break ;
+        case kEventControlEnabledStateChanged :
+                thisWindow->MacEnabledStateChanged() ;
+            break ;
+        case kEventControlHiliteChanged :
+                thisWindow->MacHiliteChanged() ;
+            break ;
         default :
             break ;
     }
@@ -231,7 +269,12 @@ static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, Contro
 
 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part) 
 {
-    MacDoRedraw( MacGetVisibleRegion().GetWXHRGN() , 0 ) ;
+    RgnHandle rgn = NewRgn() ;
+    GetClip( rgn ) ;
+    wxMacWindowStateSaver sv( this ) ;
+    SectRgn( rgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , rgn ) ;
+    MacDoRedraw( rgn , 0 ) ;
+    DisposeRgn( rgn ) ;
 }
 
 wxInt16 wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y) 
@@ -382,6 +425,7 @@ pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode p
 
 void wxWindowMac::Init()
 {
+    m_frozenness = 0 ;
     m_backgroundTransparent = FALSE;
 
     // as all windows are created with WS_VISIBLE style...
@@ -418,6 +462,8 @@ void wxWindowMac::Init()
         wxMacSetupControlBackgroundUPP = NewControlColorUPP( wxMacSetupControlBackground ) ;
     }
 
+    // we need a valid font for the encodings
+    wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
 }
 
 // Destructor
@@ -520,9 +566,10 @@ bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id,
     {
         Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
         
-        UInt32 features = kControlSupportsEmbedding | kControlSupportsLiveFeedback /*| kControlHasSpecialBackground */ | kControlSupportsCalcBestRect | kControlHandlesTracking | kControlSupportsFocus | kControlWantsActivate | kControlWantsIdle; 
+        UInt32 features = kControlSupportsEmbedding | kControlSupportsLiveFeedback | kControlHasSpecialBackground  | 
+        kControlSupportsCalcBestRect | kControlHandlesTracking | kControlSupportsFocus | kControlWantsActivate | kControlWantsIdle; 
 
-        ::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features, (ControlRef*) &m_macControl); 
+        ::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, kControlSupportsEmbedding , (ControlRef*) &m_macControl); 
 
         MacPostControlCreate(pos,size) ;
 #if !TARGET_API_MAC_OSX
@@ -673,8 +720,18 @@ void wxWindowMac::MacUpdateControlFont()
            fontStyle.size = m_font.MacGetFontSize() ;
            fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask ;
        }
+
+    fontStyle.just = teJustLeft ;
+    fontStyle.flags |= kControlUseJustMask ;
+    if ( ( GetWindowStyle() & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL )
+        fontStyle.just = teJustCenter ;
+    else if ( ( GetWindowStyle() & wxALIGN_MASK ) & wxALIGN_RIGHT )
+        fontStyle.just = teJustRight ;
+
+    
     fontStyle.foreColor = MAC_WXCOLORREF(GetForegroundColour().GetPixel() ) ;
     fontStyle.flags |= kControlUseForeColorMask ;
+       
        ::SetControlFontStyle( (ControlRef) m_macControl , &fontStyle );
        Refresh() ;
 }
@@ -864,7 +921,7 @@ void wxWindowMac::MacGetPositionAndSizeFromControl(int& x, int& y,
 bool wxWindowMac::MacGetBoundsForControl(const wxPoint& pos,
                                        const wxSize& size,
                                        int& x, int& y,
-                                       int& w, int& h) const 
+                                       int& w, int& h , bool adjustOrigin ) const 
 {
     x = (int)pos.x;
     y = (int)pos.y;
@@ -874,7 +931,8 @@ bool wxWindowMac::MacGetBoundsForControl(const wxPoint& pos,
 #if !TARGET_API_MAC_OSX
     GetParent()->MacWindowToRootWindow( &x , &y ) ;
 #endif
-
+    if ( adjustOrigin )
+        AdjustForParentClientOrigin( x , y ) ;
     return true ;
 }
 
@@ -1304,14 +1362,27 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
 
     if ( doMove || doResize )
     {
-        Rect r = wxMacGetBoundsForControl(this , wxPoint( actualX,actualY), wxSize( actualWidth, actualHeight ) ) ;
+        // we don't adjust twice for the origin
+        Rect r = wxMacGetBoundsForControl(this , wxPoint( actualX,actualY), wxSize( actualWidth, actualHeight ) , false ) ;
+        bool vis = IsControlVisible( (ControlRef) m_macControl ) ;
 #if TARGET_API_MAC_OSX
-        SetControlBounds( (ControlRef) m_macControl , &r ) ;
+        // the HIViewSetFrame call itself should invalidate the areas, but when testing with the UnicodeTextCtrl it does not !
+        if ( vis )
+            SetControlVisibility(  (ControlRef)m_macControl , false , true ) ;
+        HIRect hir = { r.left , r.top , r.right - r.left , r.bottom - r.top } ;
+        HIViewSetFrame ( (ControlRef) m_macControl , &hir ) ;
+        if ( vis )
+            SetControlVisibility(  (ControlRef)m_macControl , true , true ) ;
 #else
+// TODO TEST        SetControlBounds( (ControlRef) m_macControl , &r ) ;
+        if ( vis )
+            SetControlVisibility(  (ControlRef)m_macControl , false , true ) ;
         if ( doMove )
             MoveControl( (ControlRef) m_macControl , r.left , r.top ) ;
         if ( doSize )
             SizeControl( (ControlRef) m_macControl , r.right-r.left , r.bottom-r.top ) ;
+        if ( vis )
+            SetControlVisibility(  (ControlRef)m_macControl , true , true ) ;
 #endif
         MacRepositionScrollBars() ;
         if ( doMove )
@@ -1335,6 +1406,9 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
 
 wxSize wxWindowMac::DoGetBestSize() const
 {
+    if ( m_macIsUserPane || IsTopLevel() )
+        return wxWindowBase::DoGetBestSize() ;
+        
     Rect    bestsize = { 0 , 0 , 0 , 0 } ;
     short   baselineoffset ;
     int bestWidth, bestHeight ;
@@ -1366,6 +1440,7 @@ wxSize wxWindowMac::DoGetBestSize() const
         bestHeight = 13 ;
         
     return wxSize(bestWidth, bestHeight);
+//    return wxWindowBase::DoGetBestSize() ;
 }
 
 
@@ -1388,7 +1463,7 @@ void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 
     // ... and don't do anything (avoiding flicker) if it's already ok
     if ( x == currentX && y == currentY &&
-        width == currentW && height == currentH )
+        width == currentW && height == currentH && ( height != -1 && width != -1 ) )
     {
         // TODO REMOVE
         MacRepositionScrollBars() ; // we might have a real position shift
@@ -1487,8 +1562,44 @@ wxString wxWindowMac::GetTitle() const
     return m_label ;
 }
 
+bool wxWindowMac::Show(bool show)
+{
+    if ( !wxWindowBase::Show(show) )
+        return FALSE;
+    
+    // TODO use visibilityChanged Carbon Event for OSX
+    bool former = MacIsReallyShown() ;
+    
+    SetControlVisibility( (ControlRef) m_macControl , show , true ) ;
+    if ( former != MacIsReallyShown() )
+        MacPropagateVisibilityChanged() ;
+    return TRUE;
+}
+
+bool wxWindowMac::Enable(bool enable)
+{
+    wxASSERT( m_macControl != NULL ) ;
+    if ( !wxWindowBase::Enable(enable) )
+        return FALSE;
+
+    bool former = MacIsReallyEnabled() ;
+    if ( enable )
+        EnableControl( (ControlRef) m_macControl ) ;
+    else
+        DisableControl( (ControlRef) m_macControl ) ;
+
+    if ( former != MacIsReallyEnabled() )
+        MacPropagateEnabledStateChanged() ;
+    return TRUE;
+}
+
+//  
+// status change propagations (will be not necessary for OSX later )
+//
+
 void wxWindowMac::MacPropagateVisibilityChanged()
 {
+#if !TARGET_API_MAC_OSX
     MacVisibilityChanged() ;
     
     wxWindowListNode *node = GetChildren().GetFirst();
@@ -1499,22 +1610,61 @@ void wxWindowMac::MacPropagateVisibilityChanged()
             child->MacPropagateVisibilityChanged(  ) ;
         node = node->GetNext();
     }
+#endif
 }
 
-bool wxWindowMac::Show(bool show)
+void wxWindowMac::MacPropagateEnabledStateChanged( )
 {
-    if ( !wxWindowBase::Show(show) )
-        return FALSE;
+#if !TARGET_API_MAC_OSX
+    MacEnabledStateChanged() ;
     
-    // TODO use visibilityChanged Carbon Event for OSX
-    bool former = MacIsReallyShown() ;
+    wxWindowListNode *node = GetChildren().GetFirst();
+    while ( node )
+    {
+        wxWindowMac *child = node->GetData();
+        if ( child->IsEnabled() )
+            child->MacPropagateEnabledStateChanged() ;
+        node = node->GetNext();
+    }
+#endif
+}
+
+void wxWindowMac::MacPropagateHiliteChanged( )
+{
+#if !TARGET_API_MAC_OSX
+    MacHiliteChanged() ;
     
-    SetControlVisibility( (ControlRef) m_macControl , show , true ) ;
-    if ( former != MacIsReallyShown() )
-        MacPropagateVisibilityChanged() ;
-    return TRUE;
+    wxWindowListNode *node = GetChildren().GetFirst();
+    while ( node )
+    {
+        wxWindowMac *child = node->GetData();
+        // if ( child->IsEnabled() )
+            child->MacPropagateHiliteChanged() ;
+        node = node->GetNext();
+    }
+#endif
 }
 
+//
+// status change notifications
+// 
+
+void wxWindowMac::MacVisibilityChanged() 
+{
+}
+
+void wxWindowMac::MacHiliteChanged() 
+{
+}
+
+void wxWindowMac::MacEnabledStateChanged() 
+{
+}
+
+//
+// status queries on the inherited window's state
+//
+
 bool wxWindowMac::MacIsReallyShown() 
 {
     // only under OSX the visibility of the TLW is taken into account
@@ -1536,50 +1686,20 @@ bool wxWindowMac::MacIsReallyShown()
 #endif
 }
 
-void wxWindowMac::MacVisibilityChanged() 
-{
-}
-
-void wxWindowMac::MacPropagateEnabledStateChanged( )
-{
-    MacEnabledStateChanged() ;
-    
-    wxWindowListNode *node = GetChildren().GetFirst();
-    while ( node )
-    {
-        wxWindowMac *child = node->GetData();
-        if ( child->IsEnabled() )
-            child->MacPropagateEnabledStateChanged() ;
-        node = node->GetNext();
-    }
-}
-
-bool wxWindowMac::Enable(bool enable)
-{
-    wxASSERT( m_macControl != NULL ) ;
-    if ( !wxWindowBase::Enable(enable) )
-        return FALSE;
-
-    bool former = MacIsReallyEnabled() ;
-    if ( enable )
-        UMAActivateControl( (ControlRef) m_macControl ) ;
-    else
-        UMADeactivateControl( (ControlRef) m_macControl ) ;
-
-    if ( former != MacIsReallyEnabled() )
-        MacPropagateEnabledStateChanged() ;
-    return TRUE;
-}
-
 bool wxWindowMac::MacIsReallyEnabled() 
 {
     return IsControlEnabled( (ControlRef) m_macControl ) ;
 }
 
-void wxWindowMac::MacEnabledStateChanged() 
+bool wxWindowMac::MacIsReallyHilited() 
 {
+    return IsControlActive( (ControlRef) m_macControl ) ;
 }
 
+//
+//
+//
+
 int wxWindowMac::GetCharHeight() const
 {
     wxClientDC dc ( (wxWindowMac*)this ) ;
@@ -1620,8 +1740,32 @@ void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
 void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect)
 {
 #if TARGET_API_MAC_OSX
-    HIViewSetNeedsDisplay( (ControlRef) m_macControl , true ) ; 
+    if ( rect == NULL )
+        HIViewSetNeedsDisplay( (ControlRef) m_macControl , true ) ; 
+    else
+    {
+        RgnHandle update = NewRgn() ;
+        SetRectRgn( update , rect->x , rect->y , rect->x + rect->width , rect->y + rect->height ) ;
+        SectRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , update , update ) ;
+        wxPoint origin = GetClientAreaOrigin() ;
+        OffsetRgn( update, origin.x , origin.y ) ;        
+        HIViewSetNeedsDisplayInRegion( (ControlRef) m_macControl , update , true ) ;
+    }
 #else
+/*
+        RgnHandle updateRgn = NewRgn() ;
+        if ( rect == NULL )
+        {
+            CopyRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , updateRgn ) ;
+        }
+        else
+        {
+            SetRectRgn( updateRgn , rect->x , rect->y , rect->x + rect->width , rect->y + rect->height ) ;
+            SectRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , updateRgn , updateRgn ) ;        
+        }
+        InvalWindowRgn( (WindowRef) MacGetTopLevelWindowRef() , updateRgn ) ;
+        DisposeRgn(updateRgn) ;
+*/
     if ( IsControlVisible( (ControlRef) m_macControl ) )
     {
         SetControlVisibility( (ControlRef) m_macControl , false , false ) ;
@@ -1670,6 +1814,29 @@ void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect)
 #endif
 }
 
+void wxWindowMac::Freeze()
+{
+#if TARGET_API_MAC_OSX
+    if ( !m_frozenness++ )
+    {
+        HIViewSetDrawingEnabled( (HIViewRef) m_macControl , false ) ;
+    }
+#endif
+}
+
+void wxWindowMac::Thaw()
+{
+#if TARGET_API_MAC_OSX
+    wxASSERT_MSG( m_frozenness > 0, _T("Thaw() without matching Freeze()") );
+
+    if ( !--m_frozenness )
+    {
+        HIViewSetDrawingEnabled( (HIViewRef) m_macControl , true ) ;
+        HIViewSetNeedsDisplay( (HIViewRef) m_macControl , true ) ;
+    }
+#endif
+}
+
 void wxWindowMac::MacRedrawControl()
 {
 /*
@@ -1709,15 +1876,12 @@ void wxWindowMac::WarpPointer (int x_pos, int y_pos)
 
 void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
 {
-    event.Skip() ;
-/*
     if ( m_macBackgroundBrush.Ok() == false || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT )
     {
         event.Skip() ;
     }
     else
         event.GetDC()->Clear() ;
-*/
 }
 
 void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
@@ -2184,7 +2348,9 @@ wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
             {
                 int x , y ;
                 wxSize size ;
-                if ( parent->IsTopLevel() && child->IsKindOf( CLASSINFO( wxToolBar ) ) )
+                // we have to find a better clipping algorithm here, in order not to clip things
+                // positioned like status and toolbar
+                if ( 1 /* parent->IsTopLevel() && child->IsKindOf( CLASSINFO( wxToolBar ) ) */ )
                 {
                     size = parent->GetSize() ;
                     x = y = 0 ;
@@ -2224,6 +2390,10 @@ wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
  */
 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time ) 
 {
+    // we let the OS handle root control redraws
+    if ( m_macControl == MacGetTopLevelWindow()->GetHandle() )
+        return false ;
+        
     RgnHandle updatergn = (RgnHandle) updatergnr ;
     bool handled = false ;
     
@@ -2562,7 +2732,6 @@ void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
             x += origin.x ;
             y += origin.y ;
         }
-        ControlRef   control ;
         Point       localwhere ;
         SInt16      controlpart ;
         
@@ -2585,20 +2754,21 @@ void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
     
         if ( event.m_metaDown )
             modifiers |= cmdKey ;
+
+        bool handled = false ;
+
+        if ( ::IsControlActive( (ControlRef) m_macControl ) )
         {
-            control = (ControlRef) m_macControl ;
-            if ( control && ::IsControlActive( control ) )
+            controlpart = ::HandleControlClick( (ControlRef) m_macControl , localwhere , modifiers , (ControlActionUPP) -1 ) ;
+            wxTheApp->s_lastMouseDown = 0 ;
+            if ( controlpart != kControlNoPart ) 
             {
-                {
-                    controlpart = ::HandleControlClick( control , localwhere , modifiers , (ControlActionUPP) -1 ) ;
-                    wxTheApp->s_lastMouseDown = 0 ;
-                    if ( control && controlpart != kControlNoPart ) 
-                    {
-                        MacHandleControlClick((WXWidget)  control , controlpart , false /* mouse not down anymore */ ) ;
-                    }
-                }
+                MacHandleControlClick((WXWidget)  (ControlRef) m_macControl , controlpart , false /* mouse not down anymore */ ) ;
+                handled = true ;
             }
         }
+        if ( !handled )
+            event.Skip() ;
     }
     else
     {
@@ -2611,11 +2781,11 @@ void wxWindowMac::MacHandleControlClick( WXWidget control , wxInt16 controlpart
     wxASSERT_MSG( (ControlRef) m_macControl != NULL , wxT("No valid mac control") ) ;
 }
 
-Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size ) 
+Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin 
 {
     int x ,y , w ,h ;
     
-    window->MacGetBoundsForControl( pos , size , x , y, w, h ) ;
+    window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin) ;
     Rect bounds =  { y , x , y+h , x+w  };
     return bounds ;
 }