X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/beab25bde380ccff9bb0ebb8d8743a8d4b13fcdd..6540eefca769382fe0eb926fe40ae14405e440f3:/src/gtk1/window.cpp diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 784407129e..748fa87aa0 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -805,30 +805,6 @@ static int gtk_window_expose_callback( GtkWidget *widget, if (gdk_event->count == 0) win->GtkSendPaintEvents(); - // The following code will result in all window-less widgets - // being redrawn if the wxWindows class is given a chance to - // paint *anything* because it will then be allowed to paint - // over the window-less widgets. - GList *children = pizza->children; - while (children) - { - GtkPizzaChild *child = (GtkPizzaChild*) children->data; - children = children->next; - - GdkEventExpose child_event = *gdk_event; - - if (GTK_WIDGET_NO_WINDOW (child->widget) && - GTK_WIDGET_DRAWABLE (child->widget) /* && - gtk_widget_intersect (child->widget, &gdk_event->area, &child_event.area)*/ ) - { - child_event.area.x = child->widget->allocation.x; - child_event.area.y = child->widget->allocation.y; - child_event.area.width = child->widget->allocation.width; - child_event.area.height = child->widget->allocation.height; - gtk_widget_event (child->widget, (GdkEvent*) &child_event); - } - } - return TRUE; } @@ -3320,8 +3296,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,84 +3324,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) { - -/* - 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 ); -*/ - 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 ); + // Schedule for later Updating in ::Update() or ::OnInternalIdle(). + 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) { -/* - 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 ); -*/ - 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 ); + // Schedule for later Updating in ::Update() or ::OnInternalIdle(). + 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 ); } } } @@ -3434,39 +3371,41 @@ void wxWindowGTK::Update() { if (!m_updateRegion.IsEmpty()) { - printf( "never gets called\n" ); + GtkSendPaintEvents(); } } void wxWindowGTK::GtkSendPaintEvents() { - m_clipPaintRegion = TRUE; + if (!m_wxwindow) + { + m_clearRegion.Clear(); + m_updateRegion.Clear(); + return; + } - wxWindowDC dc( 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 ); @@ -3476,9 +3415,38 @@ void wxWindowGTK::GtkSendPaintEvents() paint_event.SetEventObject( this ); GetEventHandler()->ProcessEvent( paint_event ); - m_updateRegion.Clear(); - m_clipPaintRegion = FALSE; + + GtkPizza *pizza = GTK_PIZZA(m_wxwindow); + if (g_list_length(pizza->children) > 0) + { + // The following code will result in all window-less widgets + // being redrawn because the wxWindows class is allowed to + // paint over the window-less widgets. + GList *children = pizza->children; + while (children) + { + GtkPizzaChild *child = (GtkPizzaChild*) children->data; + children = children->next; + + if (GTK_WIDGET_NO_WINDOW (child->widget) && + GTK_WIDGET_DRAWABLE (child->widget)) + { + // Get intersection of widget area and update region + wxRegion region( m_updateRegion ); + region.Intersect( child->widget->allocation.x, + child->widget->allocation.y, + child->widget->allocation.width, + child->widget->allocation.height ); + + // Redraw the whole widget anyway + if (!region.IsEmpty()) + gtk_widget_draw( child->widget, NULL ); + } + } + } + + m_updateRegion.Clear(); } void wxWindowGTK::Clear() @@ -4077,13 +4045,39 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") ); + // No scrolling requested. if ((dx == 0) && (dy == 0)) return; + + if (!m_updateRegion.IsEmpty()) + { + m_updateRegion.Offset( dx, dy ); + + int cw = 0; + int ch = 0; + GetClientSize( &cw, &ch ); + 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; + gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); + m_clipPaintRegion = FALSE; -/* +#else + if (m_children.GetCount() > 0) { gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); @@ -4133,7 +4127,7 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) gdk_gc_unref( m_scrollGC ); } -*/ +#endif } // Find the wxWindow at the current mouse position, also returning the mouse