This commit is contained in:
hyatt%netscape.com 2000-07-13 23:00:59 +00:00
Родитель c50218030b
Коммит 5c42c520a8
15 изменённых файлов: 304 добавлений и 8 удалений

Просмотреть файл

@ -65,6 +65,7 @@ class nsIFrameSelection;
class nsIFrameManager;
class nsILayoutHistoryState;
class nsIArena;
class nsIReflowCallback;
#define NS_IPRESSHELL_IID \
{ 0x76e79c60, 0x944e, 0x11d1, \
@ -271,6 +272,8 @@ public:
PRBool aNotify,
nsAttributeChangeType aType) = 0;
NS_IMETHOD PostReflowCallback(nsIReflowCallback* aCallback) = 0;
/**
* Reflow batching
*/

Просмотреть файл

@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author: David Hyatt (hyatt@netscape.com)
*
* Contributor(s):
*/
#ifndef nsIReflowCallback_h___
#define nsIReflowCallback_h___
// {03E6FD70-889C-44b1-8639-A7EF5A80ED5C}
#define NS_IREFLOWCALLBACK_IID \
{ 0x3e6fd70, 0x889c, 0x44b1, { 0x86, 0x39, 0xa7, 0xef, 0x5a, 0x80, 0xed, 0x5c } }
class nsIPresShell;
/**
* Reflow callback interface
*/
class nsIReflowCallback : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IREFLOWCALLBACK_IID; return iid; }
NS_IMETHOD ReflowFinished(nsIPresShell* aShell, PRBool* aFlushFlag) = 0;
};
#endif /* nsIFrameUtil_h___ */

Просмотреть файл

@ -103,6 +103,8 @@
#include "nsIFrameDebug.h"
#endif
#include "nsIReflowCallback.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindow.h"
#include "nsPIDOMWindow.h"
@ -572,6 +574,12 @@ struct nsAttributeChangeRequest
nsAttributeChangeRequest* next;
};
struct nsCallbackEventRequest
{
nsIReflowCallback* callback;
nsCallbackEventRequest* next;
};
class PresShell : public nsIPresShell, public nsIViewObserver,
private nsIDocumentObserver, public nsIFocusTracker,
public nsISelectionController,
@ -651,6 +659,12 @@ public:
const nsString& aValue,
PRBool aNotify,
nsAttributeChangeType aType);
/**
* Post a callback that should be handled after reflow has finished.
*/
NS_IMETHOD PostReflowCallback(nsIReflowCallback* aCallback);
/**
* Reflow batching
*/
@ -792,6 +806,7 @@ protected:
void HandlePostedDOMEvents();
void HandlePostedAttributeChanges();
void HandlePostedReflowCallbacks();
/** notify all external reflow observers that reflow of type "aData" is about
* to begin.
@ -866,6 +881,8 @@ protected:
nsDOMEventRequest* mLastDOMEventRequest;
nsAttributeChangeRequest* mFirstAttributeRequest;
nsAttributeChangeRequest* mLastAttributeRequest;
nsCallbackEventRequest* mFirstCallbackEventRequest;
nsCallbackEventRequest* mLastCallbackEventRequest;
// subshell map
nsDST* mSubShellMap; // map of content/subshell pairs
@ -993,7 +1010,9 @@ PresShell::PresShell():mStackArena(nsnull),
mFirstDOMEventRequest(nsnull),
mLastDOMEventRequest(nsnull),
mFirstAttributeRequest(nsnull),
mLastAttributeRequest(nsnull)
mLastAttributeRequest(nsnull),
mFirstCallbackEventRequest(nsnull),
mLastCallbackEventRequest(nsnull)
{
NS_INIT_REFCNT();
mIsDestroying = PR_FALSE;
@ -1881,6 +1900,7 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
mViewManager->CacheWidgetChanges(PR_FALSE);
HandlePostedDOMEvents();
HandlePostedAttributeChanges();
HandlePostedReflowCallbacks();
//Send resize event from here.
nsEvent event;
@ -3105,6 +3125,29 @@ PresShell::GetGeneratedContentIterator(nsIContent* aContent,
return rv;
}
// Post a request to handle an arbitrary callback after reflow has finished.
NS_IMETHODIMP
PresShell::PostReflowCallback(nsIReflowCallback* aCallback)
{
nsCallbackEventRequest* request = nsnull;
void* result = nsnull;
AllocateFrame(sizeof(nsCallbackEventRequest), &result);
request = (nsCallbackEventRequest*)result;
request->callback = aCallback;
NS_ADDREF(aCallback);
request->next = nsnull;
if (mLastCallbackEventRequest) {
mLastCallbackEventRequest = mLastCallbackEventRequest->next = request;
} else {
mFirstCallbackEventRequest = request;
mLastCallbackEventRequest = request;
}
return NS_OK;
}
/**
* Post a request to handle a DOM event after Reflow has finished.
* The event must have been created with the "new" operator.
@ -3175,6 +3218,28 @@ PresShell::PostAttributeChange(nsIContent* aContent,
return NS_OK;
}
void
PresShell::HandlePostedReflowCallbacks()
{
PRBool shouldFlush = PR_FALSE;
nsCallbackEventRequest* node = mFirstCallbackEventRequest;
while(node)
{
nsIReflowCallback* callback = node->callback;
nsCallbackEventRequest* toFree = node;
node = node->next;
mFirstCallbackEventRequest = node;
FreeFrame(sizeof(nsCallbackEventRequest), toFree);
callback->ReflowFinished(this, &shouldFlush);
NS_RELEASE(callback);
}
mFirstCallbackEventRequest = mLastCallbackEventRequest = nsnull;
if (shouldFlush)
FlushPendingNotifications();
}
void
PresShell::HandlePostedDOMEvents()
{
@ -4197,6 +4262,7 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible)
HandlePostedDOMEvents();
HandlePostedAttributeChanges();
HandlePostedReflowCallbacks();
return NS_OK;
}

Просмотреть файл

@ -31,6 +31,7 @@ nsIPageSequenceFrame.h
nsIPresContext.h
nsIPresShell.h
nsIPresState.h
nsIReflowCallback.h
nsIReflowCommand.h
nsISpaceManager.h
nsFrameList.h

Просмотреть файл

@ -58,6 +58,7 @@ nsIPageSequenceFrame.h \
nsIPresContext.h \
nsIPresShell.h \
nsIPresState.h \
nsIReflowCallback.h \
nsIReflowCommand.h \
nsIFrameSelection.h \
nsISpaceManager.h \

Просмотреть файл

@ -51,6 +51,7 @@ EXPORTS = \
nsIPresContext.h \
nsIPresShell.h \
nsIPresState.h \
nsIReflowCallback.h \
nsIReflowCommand.h \
nsIFrameSelection.h \
nsISpaceManager.h \

Просмотреть файл

@ -65,6 +65,7 @@ class nsIFrameSelection;
class nsIFrameManager;
class nsILayoutHistoryState;
class nsIArena;
class nsIReflowCallback;
#define NS_IPRESSHELL_IID \
{ 0x76e79c60, 0x944e, 0x11d1, \
@ -271,6 +272,8 @@ public:
PRBool aNotify,
nsAttributeChangeType aType) = 0;
NS_IMETHOD PostReflowCallback(nsIReflowCallback* aCallback) = 0;
/**
* Reflow batching
*/

Просмотреть файл

@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author: David Hyatt (hyatt@netscape.com)
*
* Contributor(s):
*/
#ifndef nsIReflowCallback_h___
#define nsIReflowCallback_h___
// {03E6FD70-889C-44b1-8639-A7EF5A80ED5C}
#define NS_IREFLOWCALLBACK_IID \
{ 0x3e6fd70, 0x889c, 0x44b1, { 0x86, 0x39, 0xa7, 0xef, 0x5a, 0x80, 0xed, 0x5c } }
class nsIPresShell;
/**
* Reflow callback interface
*/
class nsIReflowCallback : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IREFLOWCALLBACK_IID; return iid; }
NS_IMETHOD ReflowFinished(nsIPresShell* aShell, PRBool* aFlushFlag) = 0;
};
#endif /* nsIFrameUtil_h___ */

Просмотреть файл

@ -51,6 +51,8 @@
#include "nsIElementFactory.h"
#include "nsBoxLayoutState.h"
#include "nsINodeInfo.h"
#include "nsIScrollbarFrame.h"
#include "nsIScrollbarMediator.h"
static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID);
static NS_DEFINE_IID(kScrollingViewCID, NS_SCROLLING_VIEW_CID);
@ -1367,6 +1369,17 @@ nsGfxScrollFrameInner::SetScrollbarVisibility(nsIBox* aScrollbar, PRBool aVisibl
content->SetAttribute(kNameSpaceID_None, nsXULAtoms::collapsed, NS_ConvertToString("true"), PR_TRUE);
else
content->UnsetAttribute(kNameSpaceID_None, nsXULAtoms::collapsed, PR_TRUE);
nsCOMPtr<nsIScrollbarFrame> scrollbar(do_QueryInterface(aScrollbar));
if (scrollbar) {
// See if we have a mediator.
nsCOMPtr<nsIScrollbarMediator> mediator;
scrollbar->GetScrollbarMediator(getter_AddRefs(mediator));
if (mediator) {
// Inform the mediator of the visibility change.
mediator->VisibilityChanged(aVisible);
}
}
}
PRInt32

Просмотреть файл

@ -51,6 +51,8 @@
#include "nsIElementFactory.h"
#include "nsBoxLayoutState.h"
#include "nsINodeInfo.h"
#include "nsIScrollbarFrame.h"
#include "nsIScrollbarMediator.h"
static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID);
static NS_DEFINE_IID(kScrollingViewCID, NS_SCROLLING_VIEW_CID);
@ -1367,6 +1369,17 @@ nsGfxScrollFrameInner::SetScrollbarVisibility(nsIBox* aScrollbar, PRBool aVisibl
content->SetAttribute(kNameSpaceID_None, nsXULAtoms::collapsed, NS_ConvertToString("true"), PR_TRUE);
else
content->UnsetAttribute(kNameSpaceID_None, nsXULAtoms::collapsed, PR_TRUE);
nsCOMPtr<nsIScrollbarFrame> scrollbar(do_QueryInterface(aScrollbar));
if (scrollbar) {
// See if we have a mediator.
nsCOMPtr<nsIScrollbarMediator> mediator;
scrollbar->GetScrollbarMediator(getter_AddRefs(mediator));
if (mediator) {
// Inform the mediator of the visibility change.
mediator->VisibilityChanged(aVisible);
}
}
}
PRInt32

Просмотреть файл

@ -103,6 +103,8 @@
#include "nsIFrameDebug.h"
#endif
#include "nsIReflowCallback.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindow.h"
#include "nsPIDOMWindow.h"
@ -572,6 +574,12 @@ struct nsAttributeChangeRequest
nsAttributeChangeRequest* next;
};
struct nsCallbackEventRequest
{
nsIReflowCallback* callback;
nsCallbackEventRequest* next;
};
class PresShell : public nsIPresShell, public nsIViewObserver,
private nsIDocumentObserver, public nsIFocusTracker,
public nsISelectionController,
@ -651,6 +659,12 @@ public:
const nsString& aValue,
PRBool aNotify,
nsAttributeChangeType aType);
/**
* Post a callback that should be handled after reflow has finished.
*/
NS_IMETHOD PostReflowCallback(nsIReflowCallback* aCallback);
/**
* Reflow batching
*/
@ -792,6 +806,7 @@ protected:
void HandlePostedDOMEvents();
void HandlePostedAttributeChanges();
void HandlePostedReflowCallbacks();
/** notify all external reflow observers that reflow of type "aData" is about
* to begin.
@ -866,6 +881,8 @@ protected:
nsDOMEventRequest* mLastDOMEventRequest;
nsAttributeChangeRequest* mFirstAttributeRequest;
nsAttributeChangeRequest* mLastAttributeRequest;
nsCallbackEventRequest* mFirstCallbackEventRequest;
nsCallbackEventRequest* mLastCallbackEventRequest;
// subshell map
nsDST* mSubShellMap; // map of content/subshell pairs
@ -993,7 +1010,9 @@ PresShell::PresShell():mStackArena(nsnull),
mFirstDOMEventRequest(nsnull),
mLastDOMEventRequest(nsnull),
mFirstAttributeRequest(nsnull),
mLastAttributeRequest(nsnull)
mLastAttributeRequest(nsnull),
mFirstCallbackEventRequest(nsnull),
mLastCallbackEventRequest(nsnull)
{
NS_INIT_REFCNT();
mIsDestroying = PR_FALSE;
@ -1881,6 +1900,7 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
mViewManager->CacheWidgetChanges(PR_FALSE);
HandlePostedDOMEvents();
HandlePostedAttributeChanges();
HandlePostedReflowCallbacks();
//Send resize event from here.
nsEvent event;
@ -3105,6 +3125,29 @@ PresShell::GetGeneratedContentIterator(nsIContent* aContent,
return rv;
}
// Post a request to handle an arbitrary callback after reflow has finished.
NS_IMETHODIMP
PresShell::PostReflowCallback(nsIReflowCallback* aCallback)
{
nsCallbackEventRequest* request = nsnull;
void* result = nsnull;
AllocateFrame(sizeof(nsCallbackEventRequest), &result);
request = (nsCallbackEventRequest*)result;
request->callback = aCallback;
NS_ADDREF(aCallback);
request->next = nsnull;
if (mLastCallbackEventRequest) {
mLastCallbackEventRequest = mLastCallbackEventRequest->next = request;
} else {
mFirstCallbackEventRequest = request;
mLastCallbackEventRequest = request;
}
return NS_OK;
}
/**
* Post a request to handle a DOM event after Reflow has finished.
* The event must have been created with the "new" operator.
@ -3175,6 +3218,28 @@ PresShell::PostAttributeChange(nsIContent* aContent,
return NS_OK;
}
void
PresShell::HandlePostedReflowCallbacks()
{
PRBool shouldFlush = PR_FALSE;
nsCallbackEventRequest* node = mFirstCallbackEventRequest;
while(node)
{
nsIReflowCallback* callback = node->callback;
nsCallbackEventRequest* toFree = node;
node = node->next;
mFirstCallbackEventRequest = node;
FreeFrame(sizeof(nsCallbackEventRequest), toFree);
callback->ReflowFinished(this, &shouldFlush);
NS_RELEASE(callback);
}
mFirstCallbackEventRequest = mLastCallbackEventRequest = nsnull;
if (shouldFlush)
FlushPendingNotifications();
}
void
PresShell::HandlePostedDOMEvents()
{
@ -4197,6 +4262,7 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible)
HandlePostedDOMEvents();
HandlePostedAttributeChanges();
HandlePostedReflowCallbacks();
return NS_OK;
}

Просмотреть файл

@ -38,6 +38,8 @@ public:
NS_IMETHOD PositionChanged(PRInt32 aOldIndex, PRInt32 aNewIndex) = 0;
NS_IMETHOD ScrollbarButtonPressed(PRInt32 aOldIndex, PRInt32 aNewIndex) = 0;
NS_IMETHOD VisibilityChanged(PRBool aVisible) = 0;
};
#endif

Просмотреть файл

@ -243,7 +243,9 @@ nsXULTreeGroupFrame::GetFirstTreeBox()
mFrameConstructor->CreateTreeWidgetContent(mPresContext, this, nsnull, startContent,
&mTopFrame, isAppend, PR_FALSE,
nsnull);
if (mTopFrame)
mOuterFrame->PostReflowCallback();
mBottomFrame = mTopFrame;
nsCOMPtr<nsIXULTreeSlice> slice(do_QueryInterface(mTopFrame));
PRBool isGroup = PR_FALSE;
@ -320,6 +322,8 @@ nsXULTreeGroupFrame::GetNextTreeBox(nsIBox* aBox)
mFrameConstructor->CreateTreeWidgetContent(mPresContext, this, prevFrame, nextContent,
&result, isAppend, PR_FALSE,
nsnull);
if (result)
mOuterFrame->PostReflowCallback();
}
}

Просмотреть файл

@ -40,7 +40,6 @@
#include "nsIDragService.h"
#include "nsIServiceManager.h"
#define TICK_FACTOR 50
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
@ -175,7 +174,7 @@ nsXULTreeOuterGroupFrame::nsXULTreeOuterGroupFrame(nsIPresShell* aPresShell, PRB
:nsXULTreeGroupFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal),
mRowGroupInfo(nsnull), mRowHeight(0), mCurrentIndex(0), mAutoScrollTimer(nsnull),
mTreeIsSorted(PR_FALSE), mDragOverListener(nsnull), mCurrentlyTrackingAutoScroll(PR_FALSE),
mTreeLayoutState(eTreeLayoutNormal)
mTreeLayoutState(eTreeLayoutNormal), mReflowCallbackPosted(PR_FALSE)
{
}
@ -216,6 +215,7 @@ nsXULTreeOuterGroupFrame::Release(void)
NS_INTERFACE_MAP_BEGIN(nsXULTreeOuterGroupFrame)
NS_INTERFACE_MAP_ENTRY(nsIScrollbarMediator)
NS_INTERFACE_MAP_ENTRY(nsIDragTracker)
NS_INTERFACE_MAP_ENTRY(nsIReflowCallback)
NS_INTERFACE_MAP_END_INHERITING(nsXULTreeGroupFrame)
@ -303,6 +303,8 @@ nsXULTreeOuterGroupFrame::SetRowHeight(nscoord aRowHeight)
mTreeLayoutState = eTreeLayoutAbort;
if (mCurrentIndex > 0)
VerticalScroll(mCurrentIndex * mRowHeight);
PostReflowCallback();
}
}
@ -410,6 +412,26 @@ nsXULTreeOuterGroupFrame::ComputeTotalRowCount(PRInt32& aCount, nsIContent* aPar
}
}
void
nsXULTreeOuterGroupFrame::PostReflowCallback()
{
if (!mReflowCallbackPosted) {
mReflowCallbackPosted = PR_TRUE;
nsCOMPtr<nsIPresShell> shell;
mPresContext->GetShell(getter_AddRefs(shell));
shell->PostReflowCallback(this);
}
}
NS_IMETHODIMP
nsXULTreeOuterGroupFrame::VisibilityChanged(PRBool aVisible)
{
if (!aVisible && mCurrentIndex > 0)
EnsureRowIsVisible(0);
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeOuterGroupFrame::ScrollbarButtonPressed(PRInt32 aOldIndex, PRInt32 aNewIndex)
{
@ -1020,6 +1042,15 @@ nsXULTreeOuterGroupFrame::IndexOfItem(nsIContent* aRoot, nsIContent* aContent,
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsXULTreeOuterGroupFrame::ReflowFinished(nsIPresShell* aPresShell, PRBool* aFlushFlag)
{
mReflowCallbackPosted = PR_FALSE;
nsBoxLayoutState state(mPresContext);
MarkDirtyChildren(state);
*aFlushFlag = PR_TRUE;
return NS_OK;
}
//
// Paint

Просмотреть файл

@ -36,7 +36,7 @@
#include "nsITimerCallback.h"
#include "nsITimer.h"
#include "nsIDragTracker.h"
#include "nsIReflowCallback.h"
class nsCSSFrameConstructor;
class nsDragOverListener;
@ -147,7 +147,7 @@ private:
class nsXULTreeOuterGroupFrame : public nsXULTreeGroupFrame, public nsIScrollbarMediator,
public nsIDragTracker
public nsIDragTracker, public nsIReflowCallback
{
public:
NS_DECL_ISUPPORTS
@ -164,6 +164,9 @@ public:
NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent,
nsIFrame* aParent, nsIStyleContext* aContext, nsIFrame* aPrevInFlow);
// nsIReflowCallback
NS_IMETHOD ReflowFinished(nsIPresShell* aPresShell, PRBool* aFlushFlag);
protected:
nsXULTreeOuterGroupFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull, PRBool aDefaultHorizontal = PR_TRUE);
virtual ~nsXULTreeOuterGroupFrame();
@ -207,6 +210,7 @@ public:
NS_IMETHOD PositionChanged(PRInt32 aOldIndex, PRInt32 aNewIndex);
NS_IMETHOD ScrollbarButtonPressed(PRInt32 aOldIndex, PRInt32 aNewIndex);
NS_IMETHOD VisibilityChanged(PRBool aVisible);
void VerticalScroll(PRInt32 aDelta);
@ -243,6 +247,8 @@ public:
nsTreeLayoutState GetTreeLayoutState() { return mTreeLayoutState; }
void SetTreeLayoutState(nsTreeLayoutState aState) { mTreeLayoutState = aState; }
void PostReflowCallback();
protected: // Data Members
void ComputeTotalRowCount(PRInt32& aRowCount, nsIContent* aParent);
@ -268,7 +274,7 @@ protected: // Data Members
nsDragOverListener* mDragOverListener;
nsDragAutoScrollTimer* mAutoScrollTimer; // actually a strong ref
nsTreeLayoutState mTreeLayoutState;
PRBool mReflowCallbackPosted;
}; // class nsXULTreeOuterGroupFrame