Esempio n. 1
0
void wxWindowDFB::PaintWindow(const wxRect& rect)
{
    wxCHECK_RET( !IsFrozen() && IsShown(), "shouldn't be called" );

    wxLogTrace(TRACE_PAINT,
               "%p ('%s'): painting region [%i,%i,%i,%i]",
               this, GetName().c_str(),
               rect.x, rect.y, rect.GetRight(), rect.GetBottom());

    m_updateRegion = rect;

    // FIXME_DFB: don't waste time rendering the area if it's fully covered
    //            by some children, go directly to rendering the children
    //            (unless some child has HasTransparentBackground()=true!)

    // NB: unconditionally send wxEraseEvent, because our implementation of
    //     wxWindow::Refresh() ignores the eraseBack argument
    wxWindowDC dc((wxWindow*)this);
    wxEraseEvent eventEr(m_windowId, &dc);
    eventEr.SetEventObject(this);
    HandleWindowEvent(eventEr);

    wxRect clientRect(GetClientRect());

    // only send wxNcPaintEvent if drawing at least part of nonclient area:
    if ( !clientRect.Contains(rect) )
    {
        wxNcPaintEvent eventNc(GetId());
        eventNc.SetEventObject(this);
        HandleWindowEvent(eventNc);
    }
    else
    {
        wxLogTrace(TRACE_PAINT, "%p ('%s'): not sending wxNcPaintEvent",
                   this, GetName().c_str());
    }

    // only send wxPaintEvent if drawing at least part of client area:
    if ( rect.Intersects(clientRect) )
    {
        wxPaintEvent eventPt(GetId());
        eventPt.SetEventObject(this);
        HandleWindowEvent(eventPt);
    }
    else
    {
        wxLogTrace(TRACE_PAINT, "%p ('%s'): not sending wxPaintEvent",
                   this, GetName().c_str());
    }

    // draw window's overlays on top of the painted window, if we have any:
    PaintOverlays(rect);

    m_updateRegion.Clear();

    // client area portion of 'rect':
    wxRect rectClientOnly(rect);
    rectClientOnly.Intersect(clientRect);

    // paint the children:
    wxPoint origin = GetClientAreaOrigin();
    wxWindowList& children = GetChildren();
    for ( wxWindowList::iterator i = children.begin();
          i != children.end(); ++i )
    {
        wxWindow *child = *i;

        if ( child->IsFrozen() || !child->IsShown() )
            continue; // don't paint anything if the window is frozen or hidden

        // compute child's area to repaint
        wxRect childrect(child->GetRect());
        childrect.Offset(origin);

        if ( child->CanBeOutsideClientArea() )
            childrect.Intersect(rect);
        else
            childrect.Intersect(rectClientOnly);

        if ( childrect.IsEmpty() )
            continue;

        // and repaint it:
        childrect.Offset(-child->GetPosition());
        childrect.Offset(-origin);
        child->PaintWindow(childrect);
    }
}
Esempio n. 2
0
void wxWindow::Refresh(bool eraseBackground, const wxRect *rect)
{
    wxRect rectClient; // the same rectangle in client coordinates
    wxPoint origin = GetClientAreaOrigin();

    wxSize size = GetClientSize();

    if ( rect )
    {
        // the rectangle passed as argument is in client coordinates
        rectClient = *rect;

        // don't refresh anything beyond the client area (scrollbars for
        // example)
        if ( rectClient.GetRight() > size.x )
            rectClient.SetRight(size.x);
        if ( rectClient.GetBottom() > size.y )
            rectClient.SetBottom(size.y);

    }
    else // refresh the entire client area
    {
        // x,y is already set to 0 by default
        rectClient.SetSize(size);
    }

    // convert refresh rectangle to window coordinates:
    wxRect rectWin(rectClient);
    rectWin.Offset(origin);

    // debugging helper
#ifdef WXDEBUG_REFRESH
    static bool s_refreshDebug = false;
    if ( s_refreshDebug )
    {
        wxWindowDC dc(this);
        dc.SetBrush(*wxCYAN_BRUSH);
        dc.SetPen(*wxTRANSPARENT_PEN);
        dc.DrawRectangle(rectWin);

        // under Unix we use "--sync" X option for this
        #if defined(__WXMSW__) && !defined(__WXMICROWIN__)
            ::GdiFlush();
            ::Sleep(200);
        #endif // __WXMSW__
    }
#endif // WXDEBUG_REFRESH

    wxWindowNative::Refresh(eraseBackground, &rectWin);

    // Refresh all sub controls if any.
    wxWindowList& children = GetChildren();
    for ( wxWindowList::iterator i = children.begin(); i != children.end(); ++i )
    {
        wxWindow *child = *i;
        // only refresh subcontrols if they are visible:
        if ( child->IsTopLevel() || !child->IsShown() || child->IsFrozen() )
            continue;

        // ...and when the subcontrols are in the update region:
        wxRect childrect(child->GetRect());
        childrect.Intersect(rectClient);
        if ( childrect.IsEmpty() )
            continue;

        // refresh the subcontrol now:
        childrect.Offset(-child->GetPosition());
        // NB: We must call wxWindowNative version because we need to refresh
        //     the entire control, not just its client area, and this is why we
        //     don't account for child client area origin here neither. Also
        //     note that we don't pass eraseBackground to the child, but use
        //     true instead: this is because we can't be sure that
        //     eraseBackground=false is safe for children as well and not only
        //     for the parent.
        child->wxWindowNative::Refresh(eraseBackground, &childrect);
    }
}