зеркало из https://github.com/mozilla/pjs.git
Paint only the damaged area instead of the whole widget. Reuse the rendering context to update the children. Scroll the children.
This commit is contained in:
Родитель
434b3ec6d6
Коммит
9b2c45c82a
|
@ -554,12 +554,14 @@ void nsWindow::StartDraw(nsIRenderingContext* aRenderingContext)
|
||||||
{
|
{
|
||||||
// make sure we have a rendering context
|
// make sure we have a rendering context
|
||||||
mTempRenderingContext = GetRenderingContext();
|
mTempRenderingContext = GetRenderingContext();
|
||||||
|
mTempRenderingContextMadeHere = PR_TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if we already have a rendering context, save its state
|
// if we already have a rendering context, save its state
|
||||||
NS_IF_ADDREF(aRenderingContext);
|
NS_IF_ADDREF(aRenderingContext);
|
||||||
mTempRenderingContext = aRenderingContext;
|
mTempRenderingContext = aRenderingContext;
|
||||||
|
mTempRenderingContextMadeHere = PR_FALSE;
|
||||||
mTempRenderingContext->PushState();
|
mTempRenderingContext->PushState();
|
||||||
|
|
||||||
// set the environment to the current widget
|
// set the environment to the current widget
|
||||||
|
@ -597,12 +599,15 @@ void nsWindow::StartDraw(nsIRenderingContext* aRenderingContext)
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
void nsWindow::EndDraw()
|
void nsWindow::EndDraw()
|
||||||
{
|
{
|
||||||
if (! mDrawing)
|
if (! mDrawing)
|
||||||
return;
|
return;
|
||||||
mDrawing = PR_FALSE;
|
mDrawing = PR_FALSE;
|
||||||
|
|
||||||
PRBool clipEmpty;
|
if (mTempRenderingContextMadeHere)
|
||||||
mTempRenderingContext->PopState(clipEmpty);
|
{
|
||||||
|
PRBool clipEmpty;
|
||||||
|
mTempRenderingContext->PopState(clipEmpty);
|
||||||
|
}
|
||||||
NS_RELEASE(mTempRenderingContext);
|
NS_RELEASE(mTempRenderingContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,62 +649,21 @@ NS_IMETHODIMP nsWindow::Update()
|
||||||
::SectRgn(mWindowPtr->visRgn, updateRgn, updateRgn);
|
::SectRgn(mWindowPtr->visRgn, updateRgn, updateRgn);
|
||||||
if (!::EmptyRgn(updateRgn))
|
if (!::EmptyRgn(updateRgn))
|
||||||
{
|
{
|
||||||
nsIRenderingContext* renderingContext = GetRenderingContext(); // this sets the origin
|
nsIRenderingContext* renderingContext = GetRenderingContext();
|
||||||
if (renderingContext)
|
if (renderingContext)
|
||||||
{
|
{
|
||||||
// initialize the paint event for that widget
|
// determine the rect to draw
|
||||||
nsRect rect;
|
nsRect rect;
|
||||||
#if 1
|
//GetBounds(rect);
|
||||||
GetBounds(rect);
|
//rect.x = rect.y = 0;
|
||||||
rect.x = rect.y = 0; // the origin is set on the topLeft corner of the widget
|
|
||||||
#else
|
|
||||||
//¥TODO: fix this: we don't want to always pass the entire rect
|
|
||||||
Rect macRect = (*updateRgn)->rgnBBox;
|
Rect macRect = (*updateRgn)->rgnBBox;
|
||||||
::OffsetRect(&macRect, -bounds.x, -bounds.y);
|
::OffsetRect(&macRect, -bounds.x, -bounds.y);
|
||||||
rect.x = macRect.left;
|
rect.SetRect(macRect.left, macRect.top, macRect.right - macRect.left, macRect.bottom - macRect.top);
|
||||||
rect.y = macRect.top;
|
|
||||||
rect.width = macRect.right - macRect.left;
|
|
||||||
rect.height = macRect.bottom - macRect.top;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// nsEvent
|
// update the widget
|
||||||
nsPaintEvent paintEvent;
|
UpdateWidget(rect, renderingContext);
|
||||||
paintEvent.eventStructType = NS_PAINT_EVENT;
|
|
||||||
paintEvent.message = NS_PAINT;
|
|
||||||
paintEvent.point.x = 0;
|
|
||||||
paintEvent.point.y = 0;
|
|
||||||
paintEvent.time = PR_IntervalNow();
|
|
||||||
|
|
||||||
// nsGUIEvent
|
NS_RELEASE(renderingContext);
|
||||||
paintEvent.widget = this;
|
|
||||||
paintEvent.nativeMsg = nsnull;
|
|
||||||
|
|
||||||
// nsPaintEvent
|
|
||||||
paintEvent.renderingContext = renderingContext;
|
|
||||||
paintEvent.rect = ▭
|
|
||||||
|
|
||||||
// draw the widget
|
|
||||||
StartDraw(renderingContext);
|
|
||||||
if (OnPaint(paintEvent))
|
|
||||||
DispatchWindowEvent(paintEvent);
|
|
||||||
EndDraw();
|
|
||||||
|
|
||||||
// recursively scan through its children to draw them too
|
|
||||||
nsIEnumerator* children = GetChildren();
|
|
||||||
if (children)
|
|
||||||
{
|
|
||||||
nsWindow* child;
|
|
||||||
children->First();
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (NS_SUCCEEDED(children->CurrentItem((nsISupports **)&child))) {
|
|
||||||
child->Update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (NS_SUCCEEDED(children->Next()));
|
|
||||||
delete children;
|
|
||||||
}
|
|
||||||
NS_RELEASE(renderingContext); // this restores the origin to (0, 0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
::DisposeRgn(updateRgn);
|
::DisposeRgn(updateRgn);
|
||||||
|
@ -707,6 +671,55 @@ NS_IMETHODIMP nsWindow::Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
void nsWindow::UpdateWidget(nsRect& aRect, nsIRenderingContext* aContext)
|
||||||
|
{
|
||||||
|
// initialize the paint event
|
||||||
|
nsPaintEvent paintEvent;
|
||||||
|
paintEvent.eventStructType = NS_PAINT_EVENT; // nsEvent
|
||||||
|
paintEvent.message = NS_PAINT;
|
||||||
|
paintEvent.widget = this; // nsGUIEvent
|
||||||
|
paintEvent.nativeMsg = nsnull;
|
||||||
|
paintEvent.renderingContext = aContext; // nsPaintEvent
|
||||||
|
paintEvent.rect = &aRect;
|
||||||
|
|
||||||
|
// draw the widget
|
||||||
|
StartDraw(aContext);
|
||||||
|
if (OnPaint(paintEvent))
|
||||||
|
DispatchWindowEvent(paintEvent);
|
||||||
|
EndDraw();
|
||||||
|
|
||||||
|
// recursively draw the children
|
||||||
|
nsIEnumerator* children = GetChildren();
|
||||||
|
if (children)
|
||||||
|
{
|
||||||
|
nsWindow* child;
|
||||||
|
children->First();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (NS_SUCCEEDED(children->CurrentItem((nsISupports **)&child)))
|
||||||
|
{
|
||||||
|
nsRect childBounds;
|
||||||
|
child->GetBounds(childBounds);
|
||||||
|
|
||||||
|
// redraw only the intersection of the child rect and the update rect
|
||||||
|
nsRect intersection;
|
||||||
|
if (intersection.IntersectRect(aRect, childBounds))
|
||||||
|
{
|
||||||
|
intersection.MoveBy(-childBounds.x, -childBounds.y);
|
||||||
|
child->UpdateWidget(intersection, aContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (NS_SUCCEEDED(children->Next()));
|
||||||
|
delete children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Scroll the bits of a window
|
// Scroll the bits of a window
|
||||||
|
@ -714,7 +727,44 @@ NS_IMETHODIMP nsWindow::Update()
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
NS_IMETHODIMP nsWindow::Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect)
|
NS_IMETHODIMP nsWindow::Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect)
|
||||||
{
|
{
|
||||||
Invalidate(PR_FALSE);
|
StartDraw();
|
||||||
|
|
||||||
|
// scroll the rect
|
||||||
|
Rect macRect;
|
||||||
|
nsRectToMacRect(*aClipRect, macRect);
|
||||||
|
|
||||||
|
RgnHandle updateRgn = ::NewRgn();
|
||||||
|
if (updateRgn == nil)
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
::ClipRect(&macRect);
|
||||||
|
::ScrollRect(&macRect, aDx, aDy, updateRgn);
|
||||||
|
::InvalRgn(updateRgn);
|
||||||
|
::DisposeRgn(updateRgn);
|
||||||
|
|
||||||
|
// scroll the children
|
||||||
|
nsIEnumerator* children = GetChildren();
|
||||||
|
if (children)
|
||||||
|
{
|
||||||
|
nsWindow* child;
|
||||||
|
children->First();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (NS_SUCCEEDED(children->CurrentItem((nsISupports **)&child))) {
|
||||||
|
nsRect bounds;
|
||||||
|
child->GetBounds(bounds);
|
||||||
|
bounds.x += aDx;
|
||||||
|
bounds.y += aDy;
|
||||||
|
child->SetBounds(bounds);
|
||||||
|
|
||||||
|
child->Scroll(aDx, aDy, &bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (NS_SUCCEEDED(children->Next()));
|
||||||
|
delete children;
|
||||||
|
}
|
||||||
|
|
||||||
|
EndDraw();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,7 @@ public:
|
||||||
virtual void EndDraw();
|
virtual void EndDraw();
|
||||||
virtual PRBool OnPaint(nsPaintEvent &event);
|
virtual PRBool OnPaint(nsPaintEvent &event);
|
||||||
NS_IMETHOD Update();
|
NS_IMETHOD Update();
|
||||||
|
virtual void UpdateWidget(nsRect& aRect, nsIRenderingContext* aContext);
|
||||||
|
|
||||||
virtual void ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY);
|
virtual void ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY);
|
||||||
virtual void LocalToWindowCoordinate(nsPoint& aPoint);
|
virtual void LocalToWindowCoordinate(nsPoint& aPoint);
|
||||||
|
@ -156,23 +157,19 @@ protected:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsIWidget* mParent;
|
nsIWidget* mParent;
|
||||||
|
|
||||||
PRBool mVisible;
|
PRBool mVisible;
|
||||||
PRBool mEnabled;
|
PRBool mEnabled;
|
||||||
|
PRInt32 mPreferredWidth;
|
||||||
|
PRInt32 mPreferredHeight;
|
||||||
|
nsIFontMetrics* mFontMetrics;
|
||||||
|
nsIMenuBar* mMenuBar;
|
||||||
|
RgnHandle mWindowRegion; // the region defining this window
|
||||||
|
WindowPtr mWindowPtr;
|
||||||
|
PRBool mDestroyCalled;
|
||||||
|
|
||||||
PRInt32 mPreferredWidth;
|
PRBool mDrawing;
|
||||||
PRInt32 mPreferredHeight;
|
|
||||||
|
|
||||||
nsIFontMetrics* mFontMetrics;
|
|
||||||
nsIMenuBar* mMenuBar;
|
|
||||||
nsIRenderingContext* mTempRenderingContext;
|
nsIRenderingContext* mTempRenderingContext;
|
||||||
|
PRBool mTempRenderingContextMadeHere;
|
||||||
// MAC SPECIFIC MEMBERS
|
|
||||||
protected:
|
|
||||||
RgnHandle mWindowRegion; // the region defining this window
|
|
||||||
WindowPtr mWindowPtr;
|
|
||||||
PRBool mDrawing;
|
|
||||||
PRBool mDestroyCalled;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
Загрузка…
Ссылка в новой задаче