]> git.saurik.com Git - wxWidgets.git/commitdiff
Now updating and clearing are done in a delayed fashion.
authorRobert Roebling <robert@roebling.de>
Mon, 4 Feb 2002 14:05:28 +0000 (14:05 +0000)
committerRobert Roebling <robert@roebling.de>
Mon, 4 Feb 2002 14:05:28 +0000 (14:05 +0000)
    The m_updateRegion gets updated and the (often much
    smaller) m_clearRegion gets cleared. This removes the
    flicker introduced by having delayed updates and
    immediate clearings.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13994 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/gtk/window.h
include/wx/gtk1/window.h
src/gtk/window.cpp
src/gtk1/window.cpp

index 9c9bb4d739d9e103f882a56ddea547657f374f96..a0d1a66f2e65ae93d6351688854778890b176c6b 100644 (file)
@@ -183,6 +183,9 @@ public:
     GdkICAttr           *m_icattr;
 #endif
 
+    // The area to be cleared (and not just refreshed)
+    wxRegion             m_clearRegion;
+
     // scrolling stuff
     GtkAdjustment       *m_hAdjust,*m_vAdjust;
     float                m_oldHorizontalPos;
index 9c9bb4d739d9e103f882a56ddea547657f374f96..a0d1a66f2e65ae93d6351688854778890b176c6b 100644 (file)
@@ -183,6 +183,9 @@ public:
     GdkICAttr           *m_icattr;
 #endif
 
+    // The area to be cleared (and not just refreshed)
+    wxRegion             m_clearRegion;
+
     // scrolling stuff
     GtkAdjustment       *m_hAdjust,*m_vAdjust;
     float                m_oldHorizontalPos;
index 016b47c69be48934079417f3102d46f13c048542..688d7399cddbd7fdd11bb321777c0acf6a601e0d 100644 (file)
@@ -3320,8 +3320,8 @@ void wxWindowGTK::WarpPointer( int x, int y )
 {
     wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
 
-    /* we provide this function ourselves as it is
-       missing in GDK (top of this file)  */
+    // We provide this function ourselves as it is
+    // missing in GDK (top of this file).
 
     GdkWindow *window = (GdkWindow*) NULL;
     if (m_wxwindow)
@@ -3348,95 +3348,45 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect )
     {
         if (rect)
         {
-            gdk_window_clear_area( GTK_PIZZA(m_wxwindow)->bin_window,
-                                   rect->x, rect->y,
-                                   rect->width, rect->height );
+            // Schedule for later Updating in ::Update() or ::OnInternalIdle().
+            m_clearRegion.Union( rect->x, rect->y, rect->width, rect->height );
         }
         else
         {
-            gdk_window_clear( GTK_PIZZA(m_wxwindow)->bin_window );
+            // Schedule for later Updating in ::Update() or ::OnInternalIdle().
+            m_clearRegion.Clear();
+            m_clearRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height );
         }
     }
 
-    /* there is no GTK equivalent of "draw only, don't clear" so we
-       invent our own in the GtkPizza widget */
-
-    if (!rect)
+    if (rect)
     {
         if (m_wxwindow)
         {
-#if 0
-            GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
-            gboolean old_clear = pizza->clear_on_draw;
-            gtk_pizza_set_clear( pizza, FALSE );
-            gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
-            gtk_pizza_set_clear( pizza, old_clear );
-#endif
-
-#if 1
             // Schedule for later Updating in ::Update() or ::OnInternalIdle().
-            m_updateRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height );
-#else
-            GdkEventExpose gdk_event;
-            gdk_event.type = GDK_EXPOSE;
-            gdk_event.window = GTK_PIZZA(m_wxwindow)->bin_window;
-            gdk_event.count = 0;
-            gdk_event.area.x = 0;
-            gdk_event.area.y = 0;
-            gdk_event.area.width = m_wxwindow->allocation.width;
-            gdk_event.area.height = m_wxwindow->allocation.height;
-            gtk_window_expose_callback( m_wxwindow, &gdk_event, (wxWindow *)this );
-#endif
+            m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height );
         }
         else
         {
-            gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
+            GdkRectangle gdk_rect;
+            gdk_rect.x = rect->x;
+            gdk_rect.y = rect->y;
+            gdk_rect.width = rect->width;
+            gdk_rect.height = rect->height;
+            gtk_widget_draw( m_widget, &gdk_rect );
         }
     }
     else
     {
-
         if (m_wxwindow)
         {
-#if 0
-            GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
-            gboolean old_clear = pizza->clear_on_draw;
-            gtk_pizza_set_clear( pizza, FALSE );
-
-            GdkRectangle gdk_rect;
-            gdk_rect.x = rect->x;
-            gdk_rect.y = rect->y;
-            gdk_rect.width = rect->width;
-            gdk_rect.height = rect->height;
-            gtk_widget_draw( m_wxwindow, &gdk_rect );
-            gtk_window_draw_callback( m_wxwindow, &gdk_rect, this );
-
-            gtk_pizza_set_clear( pizza, old_clear );
-#endif
-
-#if 1
             // Schedule for later Updating in ::Update() or ::OnInternalIdle().
-            m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height );
-#else
-            GdkEventExpose gdk_event;
-            gdk_event.type = GDK_EXPOSE;
-            gdk_event.window = GTK_PIZZA(m_wxwindow)->bin_window;
-            gdk_event.count = 0;
-            gdk_event.area.x = rect->x;
-            gdk_event.area.y = rect->y;
-            gdk_event.area.width = rect->width;
-            gdk_event.area.height = rect->height;
-            gtk_window_expose_callback( m_wxwindow, &gdk_event, (wxWindow *)this );
-#endif
+            m_updateRegion.Clear();
+            m_updateRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height );
         }
         else
         {
-            GdkRectangle gdk_rect;
-            gdk_rect.x = rect->x;
-            gdk_rect.y = rect->y;
-            gdk_rect.width = rect->width;
-            gdk_rect.height = rect->height;
-            gtk_widget_draw( m_widget, &gdk_rect );
+            gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
         }
     }
 }
@@ -3451,33 +3401,35 @@ void wxWindowGTK::Update()
 
 void wxWindowGTK::GtkSendPaintEvents()
 {
-    m_clipPaintRegion = TRUE;
+    if (!m_wxwindow)
+    {
+        m_clearRegion.Clear();
+        m_updateRegion.Clear();
+        return;
+    }
 
-    wxWindowDC dc( (wxWindow*)this );
-    dc.SetClippingRegion( m_updateRegion );
-    wxEraseEvent erase_event( GetId(), &dc );
-    erase_event.SetEventObject( this );
+    m_clipPaintRegion = TRUE;
 
-#if 1
-    GetEventHandler()->ProcessEvent( erase_event );
-#else
-    if (!GetEventHandler()->ProcessEvent(erase_event))
+    if (!m_clearRegion.IsEmpty())
     {
+        wxWindowDC dc( (wxWindow*)this );
+        dc.SetClippingRegion( m_clearRegion );
+        
+        wxEraseEvent erase_event( GetId(), &dc );
+        erase_event.SetEventObject( this );
+    
         if (!GetEventHandler()->ProcessEvent(erase_event))
         {
-            wxClientDC dc( this );
-            dc.SetBrush( wxBrush( GetBackgroundColour(), wxSOLID ) );
-            dc.SetPen( *wxTRANSPARENT_PEN );
-
-            wxRegionIterator upd( m_updateRegion );
+            wxRegionIterator upd( m_clearRegion );
             while (upd)
             {
-                dc.DrawRectangle( upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() );
+                gdk_window_clear_area( GTK_PIZZA(m_wxwindow)->bin_window,
+                                       upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() );
                 upd ++;
             }
         }
+        m_clearRegion.Clear();
     }
-#endif
 
     wxNcPaintEvent nc_paint_event( GetId() );
     nc_paint_event.SetEventObject( this );
@@ -4101,6 +4053,16 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
         m_updateRegion.Intersect( 0, 0, cw, ch );
     }
     
+    if (!m_clearRegion.IsEmpty())
+    {
+        m_clearRegion.Offset( dx, dy );
+        
+        int cw = 0;
+        int ch = 0;
+        GetClientSize( &cw, &ch );
+        m_clearRegion.Intersect( 0, 0, cw, ch );
+    }
+    
 #if 1
 
     m_clipPaintRegion = TRUE;
index 016b47c69be48934079417f3102d46f13c048542..688d7399cddbd7fdd11bb321777c0acf6a601e0d 100644 (file)
@@ -3320,8 +3320,8 @@ void wxWindowGTK::WarpPointer( int x, int y )
 {
     wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
 
-    /* we provide this function ourselves as it is
-       missing in GDK (top of this file)  */
+    // We provide this function ourselves as it is
+    // missing in GDK (top of this file).
 
     GdkWindow *window = (GdkWindow*) NULL;
     if (m_wxwindow)
@@ -3348,95 +3348,45 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect )
     {
         if (rect)
         {
-            gdk_window_clear_area( GTK_PIZZA(m_wxwindow)->bin_window,
-                                   rect->x, rect->y,
-                                   rect->width, rect->height );
+            // Schedule for later Updating in ::Update() or ::OnInternalIdle().
+            m_clearRegion.Union( rect->x, rect->y, rect->width, rect->height );
         }
         else
         {
-            gdk_window_clear( GTK_PIZZA(m_wxwindow)->bin_window );
+            // Schedule for later Updating in ::Update() or ::OnInternalIdle().
+            m_clearRegion.Clear();
+            m_clearRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height );
         }
     }
 
-    /* there is no GTK equivalent of "draw only, don't clear" so we
-       invent our own in the GtkPizza widget */
-
-    if (!rect)
+    if (rect)
     {
         if (m_wxwindow)
         {
-#if 0
-            GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
-            gboolean old_clear = pizza->clear_on_draw;
-            gtk_pizza_set_clear( pizza, FALSE );
-            gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
-            gtk_pizza_set_clear( pizza, old_clear );
-#endif
-
-#if 1
             // Schedule for later Updating in ::Update() or ::OnInternalIdle().
-            m_updateRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height );
-#else
-            GdkEventExpose gdk_event;
-            gdk_event.type = GDK_EXPOSE;
-            gdk_event.window = GTK_PIZZA(m_wxwindow)->bin_window;
-            gdk_event.count = 0;
-            gdk_event.area.x = 0;
-            gdk_event.area.y = 0;
-            gdk_event.area.width = m_wxwindow->allocation.width;
-            gdk_event.area.height = m_wxwindow->allocation.height;
-            gtk_window_expose_callback( m_wxwindow, &gdk_event, (wxWindow *)this );
-#endif
+            m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height );
         }
         else
         {
-            gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
+            GdkRectangle gdk_rect;
+            gdk_rect.x = rect->x;
+            gdk_rect.y = rect->y;
+            gdk_rect.width = rect->width;
+            gdk_rect.height = rect->height;
+            gtk_widget_draw( m_widget, &gdk_rect );
         }
     }
     else
     {
-
         if (m_wxwindow)
         {
-#if 0
-            GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
-            gboolean old_clear = pizza->clear_on_draw;
-            gtk_pizza_set_clear( pizza, FALSE );
-
-            GdkRectangle gdk_rect;
-            gdk_rect.x = rect->x;
-            gdk_rect.y = rect->y;
-            gdk_rect.width = rect->width;
-            gdk_rect.height = rect->height;
-            gtk_widget_draw( m_wxwindow, &gdk_rect );
-            gtk_window_draw_callback( m_wxwindow, &gdk_rect, this );
-
-            gtk_pizza_set_clear( pizza, old_clear );
-#endif
-
-#if 1
             // Schedule for later Updating in ::Update() or ::OnInternalIdle().
-            m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height );
-#else
-            GdkEventExpose gdk_event;
-            gdk_event.type = GDK_EXPOSE;
-            gdk_event.window = GTK_PIZZA(m_wxwindow)->bin_window;
-            gdk_event.count = 0;
-            gdk_event.area.x = rect->x;
-            gdk_event.area.y = rect->y;
-            gdk_event.area.width = rect->width;
-            gdk_event.area.height = rect->height;
-            gtk_window_expose_callback( m_wxwindow, &gdk_event, (wxWindow *)this );
-#endif
+            m_updateRegion.Clear();
+            m_updateRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height );
         }
         else
         {
-            GdkRectangle gdk_rect;
-            gdk_rect.x = rect->x;
-            gdk_rect.y = rect->y;
-            gdk_rect.width = rect->width;
-            gdk_rect.height = rect->height;
-            gtk_widget_draw( m_widget, &gdk_rect );
+            gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
         }
     }
 }
@@ -3451,33 +3401,35 @@ void wxWindowGTK::Update()
 
 void wxWindowGTK::GtkSendPaintEvents()
 {
-    m_clipPaintRegion = TRUE;
+    if (!m_wxwindow)
+    {
+        m_clearRegion.Clear();
+        m_updateRegion.Clear();
+        return;
+    }
 
-    wxWindowDC dc( (wxWindow*)this );
-    dc.SetClippingRegion( m_updateRegion );
-    wxEraseEvent erase_event( GetId(), &dc );
-    erase_event.SetEventObject( this );
+    m_clipPaintRegion = TRUE;
 
-#if 1
-    GetEventHandler()->ProcessEvent( erase_event );
-#else
-    if (!GetEventHandler()->ProcessEvent(erase_event))
+    if (!m_clearRegion.IsEmpty())
     {
+        wxWindowDC dc( (wxWindow*)this );
+        dc.SetClippingRegion( m_clearRegion );
+        
+        wxEraseEvent erase_event( GetId(), &dc );
+        erase_event.SetEventObject( this );
+    
         if (!GetEventHandler()->ProcessEvent(erase_event))
         {
-            wxClientDC dc( this );
-            dc.SetBrush( wxBrush( GetBackgroundColour(), wxSOLID ) );
-            dc.SetPen( *wxTRANSPARENT_PEN );
-
-            wxRegionIterator upd( m_updateRegion );
+            wxRegionIterator upd( m_clearRegion );
             while (upd)
             {
-                dc.DrawRectangle( upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() );
+                gdk_window_clear_area( GTK_PIZZA(m_wxwindow)->bin_window,
+                                       upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() );
                 upd ++;
             }
         }
+        m_clearRegion.Clear();
     }
-#endif
 
     wxNcPaintEvent nc_paint_event( GetId() );
     nc_paint_event.SetEventObject( this );
@@ -4101,6 +4053,16 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
         m_updateRegion.Intersect( 0, 0, cw, ch );
     }
     
+    if (!m_clearRegion.IsEmpty())
+    {
+        m_clearRegion.Offset( dx, dy );
+        
+        int cw = 0;
+        int ch = 0;
+        GetClientSize( &cw, &ch );
+        m_clearRegion.Intersect( 0, 0, cw, ch );
+    }
+    
 #if 1
 
     m_clipPaintRegion = TRUE;