]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/window.cpp
implementation changes to closer follow MSW, crashes fixed
[wxWidgets.git] / src / mac / window.cpp
index a75c421466051632ce0967c55276079e408eb934..701f4010ecee1243c02d663d4e5ea66d88604374 100644 (file)
@@ -75,7 +75,6 @@ BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase)
   EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground)
   EVT_SYS_COLOUR_CHANGED(wxWindowMac::OnSysColourChanged)
   EVT_INIT_DIALOG(wxWindowMac::OnInitDialog)
-  EVT_IDLE(wxWindowMac::OnIdle)
   EVT_SET_FOCUS(wxWindowMac::OnSetFocus)
   EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent)
 END_EVENT_TABLE()
@@ -923,48 +922,6 @@ void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect)
     }
 }
 
-#if wxUSE_CARET && WXWIN_COMPATIBILITY
-// ---------------------------------------------------------------------------
-// Caret manipulation
-// ---------------------------------------------------------------------------
-
-void wxWindowMac::CreateCaret(int w, int h)
-{
-    SetCaret(new wxCaret(this, w, h));
-}
-
-void wxWindowMac::CreateCaret(const wxBitmap *WXUNUSED(bitmap))
-{
-    wxFAIL_MSG("not implemented");
-}
-
-void wxWindowMac::ShowCaret(bool show)
-{
-    wxCHECK_RET( m_caret, "no caret to show" );
-
-    m_caret->Show(show);
-}
-
-void wxWindowMac::DestroyCaret()
-{
-    SetCaret(NULL);
-}
-
-void wxWindowMac::SetCaretPos(int x, int y)
-{
-    wxCHECK_RET( m_caret, "no caret to move" );
-
-    m_caret->Move(x, y);
-}
-
-void wxWindowMac::GetCaretPos(int *x, int *y) const
-{
-    wxCHECK_RET( m_caret, "no caret to get position of" );
-
-    m_caret->GetPosition(x, y);
-}
-#endif // wxUSE_CARET
-
 wxWindowMac *wxGetActiveWindow()
 {
     // actually this is a windows-only concept
@@ -1232,10 +1189,14 @@ void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible,
 // Does a physical scroll
 void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
 {
-    wxClientDC dc(this) ;
-    wxMacPortSetter helper(&dc) ;
+    if( dx == 0 && dy ==0 )
+        return ;
+        
 
     {
+        wxClientDC dc(this) ;
+        wxMacPortSetter helper(&dc) ;
+
         int width , height ;
         GetClientSize( &width , &height ) ;
 
@@ -1249,8 +1210,27 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
             SectRect( &scrollrect , &r , &scrollrect ) ;
         }
         ScrollRect( &scrollrect , dx , dy , updateRgn ) ;
-        InvalWindowRgn( (WindowRef) MacGetRootWindow() ,  updateRgn ) ;
+        // we also have to scroll the update rgn in this rectangle 
+        // in order not to loose updates
+        WindowRef rootWindow = (WindowRef) MacGetRootWindow() ;
+        RgnHandle formerUpdateRgn = NewRgn() ;
+        RgnHandle scrollRgn = NewRgn() ;
+        RectRgn( scrollRgn , &scrollrect ) ;
+        GetWindowUpdateRgn( rootWindow , formerUpdateRgn ) ;
+        Point pt = {0,0} ;
+        LocalToGlobal( &pt ) ;
+        OffsetRgn( formerUpdateRgn , -pt.h , -pt.v ) ;
+        SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
+        if ( !EmptyRgn( formerUpdateRgn ) )
+        {
+            MacOffsetRgn( formerUpdateRgn , dx , dy ) ;
+            SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
+            InvalWindowRgn(rootWindow  ,  formerUpdateRgn ) ;
+        }
+        InvalWindowRgn(rootWindow  ,  updateRgn ) ;
         DisposeRgn( updateRgn ) ;
+        DisposeRgn( formerUpdateRgn ) ;
+        DisposeRgn( scrollRgn ) ;
     }
 
     for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
@@ -1266,6 +1246,8 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
         child->GetSize( &w, &h );
         child->SetSize( x+dx, y+dy, w, h );
     }
+    
+    Update() ;
 
 }
 
@@ -1305,37 +1287,6 @@ wxWindowMac *wxWindowBase::FindFocus()
     return gFocusWindow ;
 }
 
-#if WXWIN_COMPATIBILITY
-// If nothing defined for this, try the parent.
-// E.g. we may be a button loaded from a resource, with no callback function
-// defined.
-void wxWindowMac::OnCommand(wxWindowMac& win, wxCommandEvent& event)
-{
-    if ( GetEventHandler()->ProcessEvent(event)  )
-        return;
-    if ( m_parent )
-        m_parent->GetEventHandler()->OnCommand(win, event);
-}
-#endif // WXWIN_COMPATIBILITY_2
-
-#if WXWIN_COMPATIBILITY
-wxObject* wxWindowMac::GetChild(int number) const
-{
-    // Return a pointer to the Nth object in the Panel
-    wxNode *node = GetChildren().GetFirst();
-    int n = number;
-    while (node && n--)
-        node = node->GetNext();
-    if ( node )
-    {
-        wxObject *obj = (wxObject *)node->GetData();
-        return(obj);
-    }
-    else
-        return NULL;
-}
-#endif // WXWIN_COMPATIBILITY
-
 void wxWindowMac::OnSetFocus(wxFocusEvent& event)
 {
     // panel wants to track the window which was the last to have focus in it,
@@ -1352,14 +1303,6 @@ void wxWindowMac::OnSetFocus(wxFocusEvent& event)
     event.Skip();
 }
 
-void wxWindowMac::Clear()
-{
-    wxClientDC dc(this);
-    wxBrush brush(GetBackgroundColour(), wxSOLID);
-    dc.SetBackground(brush);
-    dc.Clear();
-}
-
 // Setup background and foreground colours correctly
 void wxWindowMac::SetupColours()
 {
@@ -1367,12 +1310,12 @@ void wxWindowMac::SetupColours()
         SetBackgroundColour(GetParent()->GetBackgroundColour());
 }
 
-void wxWindowMac::OnIdle(wxIdleEvent& event)
+void wxWindowMac::OnInternalIdle()
 {
     // This calls the UI-update mechanism (querying windows for
     // menu/toolbar/control state information)
-    if (wxUpdateUIEvent::CanUpdate())
-        UpdateWindowUI();
+    if (wxUpdateUIEvent::CanUpdate(this))
+        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
 }
 
 // Raise the window to the top of the Z order
@@ -1605,17 +1548,34 @@ wxString wxWindowMac::MacGetToolTipString( wxPoint &pt )
 
 void wxWindowMac::Update()
 {
-    wxTopLevelWindowMac* win = MacGetTopLevelWindow(  ) ;
-    if ( win )
-    {
-      win->MacUpdate( 0 ) ;
+    wxRegion visRgn = MacGetVisibleRegion( false ) ;
+    int top = 0 , left = 0 ;
+    MacWindowToRootWindow( &left , &top ) ;
+    WindowRef rootWindow = (WindowRef) MacGetRootWindow() ;
+    RgnHandle updateRgn = NewRgn() ;    
+    // getting the update region in macos local coordinates
+    GetWindowUpdateRgn( rootWindow , updateRgn ) ;
+    GrafPtr     port ;
+    ::GetPort( &port ) ;
+    ::SetPort( UMAGetWindowPort( rootWindow ) ) ;
+    Point pt = {0,0} ;
+    LocalToGlobal( &pt ) ;
+    ::SetPort( port ) ;
+    OffsetRgn( updateRgn , -pt.h , -pt.v ) ;
+    // translate to window local coordinates
+    OffsetRgn( updateRgn , -left , -top ) ;
+    SectRgn( updateRgn , (RgnHandle) visRgn.GetWXHRGN() , updateRgn ) ;
+    MacRedraw( updateRgn , 0 , true ) ;
+    // for flushing and validating we need macos-local coordinates again
+    OffsetRgn( updateRgn , left , top ) ;
 #if TARGET_API_MAC_CARBON
-        if ( QDIsPortBuffered( GetWindowPort( (WindowRef) win->MacGetWindowRef() ) ) )
-        {
-                QDFlushPortBuffer( GetWindowPort( (WindowRef) win->MacGetWindowRef() ) , NULL ) ;
-        }
+    if ( QDIsPortBuffered( GetWindowPort( rootWindow ) ) )
+    {
+        QDFlushPortBuffer( GetWindowPort( rootWindow ) , updateRgn ) ;
+    }
 #endif
-      }
+    ValidWindowRgn( rootWindow , updateRgn ) ;
+    DisposeRgn( updateRgn ) ;
 }
 
 wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
@@ -1773,10 +1733,32 @@ void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase)
         DisposeRgn( ownUpdateRgn ) ;
         if ( !m_updateRegion.Empty() )
         {
+            wxWindowList hiddenWindows ;
+            for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
+            {
+                wxControl *child = wxDynamicCast( ( wxWindow*)node->GetData() , wxControl ) ;
+
+                if ( child && child->MacGetRootWindow() == window && child->IsShown() && child->GetMacControl() )
+                {
+                    SetControlVisibility( (ControlHandle) child->GetMacControl() , false , false ) ;
+                    hiddenWindows.Append( child ) ;
+                }
+            }
+            
             wxPaintEvent event;
             event.m_timeStamp = time ;
             event.SetEventObject(this);
             GetEventHandler()->ProcessEvent(event);
+            for (wxWindowListNode *node = hiddenWindows.GetFirst(); node; node = node->GetNext())
+            {
+                wxControl *child = wxDynamicCast( ( wxWindow*)node->GetData() , wxControl ) ;
+
+                if ( child && child->GetMacControl() )
+                {
+                    SetControlVisibility( (ControlHandle) child->GetMacControl() , true , false ) ;
+                }
+            }
         }
     }