r=bryner, a=hyatt
This commit is contained in:
evaughan%netscape.com 2000-10-07 00:49:08 +00:00
Родитель 61271d46ca
Коммит f328cedeb9
21 изменённых файлов: 626 добавлений и 162 удалений

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

@ -274,7 +274,7 @@ public:
nsAttributeChangeType aType) = 0;
NS_IMETHOD PostReflowCallback(nsIReflowCallback* aCallback) = 0;
NS_IMETHOD CancelReflowCallback(nsIReflowCallback* aCallback) = 0;
/**
* Reflow batching
*/

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

@ -802,6 +802,7 @@ public:
* Post a callback that should be handled after reflow has finished.
*/
NS_IMETHOD PostReflowCallback(nsIReflowCallback* aCallback);
NS_IMETHOD CancelReflowCallback(nsIReflowCallback* aCallback);
/**
* Reflow batching
@ -3414,6 +3415,38 @@ PresShell::PostReflowCallback(nsIReflowCallback* aCallback)
return NS_OK;
}
NS_IMETHODIMP
PresShell::CancelReflowCallback(nsIReflowCallback* aCallback)
{
nsCallbackEventRequest* before = nsnull;
nsCallbackEventRequest* node = mFirstCallbackEventRequest;
while(node)
{
nsIReflowCallback* callback = node->callback;
if (callback == aCallback)
{
nsCallbackEventRequest* toFree = node;
if (node == mFirstCallbackEventRequest) {
mFirstCallbackEventRequest = node->next;
node = mFirstCallbackEventRequest;
before = nsnull;
} else {
node = node->next;
before->next = node;
}
FreeFrame(sizeof(nsCallbackEventRequest), toFree);
NS_RELEASE(callback);
} else {
before = node;
node = node->next;
}
}
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.
@ -3484,6 +3517,7 @@ PresShell::PostAttributeChange(nsIContent* aContent,
return NS_OK;
}
void
PresShell::HandlePostedReflowCallbacks()
{

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

@ -274,7 +274,7 @@ public:
nsAttributeChangeType aType) = 0;
NS_IMETHOD PostReflowCallback(nsIReflowCallback* aCallback) = 0;
NS_IMETHOD CancelReflowCallback(nsIReflowCallback* aCallback) = 0;
/**
* Reflow batching
*/

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

@ -802,6 +802,7 @@ public:
* Post a callback that should be handled after reflow has finished.
*/
NS_IMETHOD PostReflowCallback(nsIReflowCallback* aCallback);
NS_IMETHOD CancelReflowCallback(nsIReflowCallback* aCallback);
/**
* Reflow batching
@ -3414,6 +3415,38 @@ PresShell::PostReflowCallback(nsIReflowCallback* aCallback)
return NS_OK;
}
NS_IMETHODIMP
PresShell::CancelReflowCallback(nsIReflowCallback* aCallback)
{
nsCallbackEventRequest* before = nsnull;
nsCallbackEventRequest* node = mFirstCallbackEventRequest;
while(node)
{
nsIReflowCallback* callback = node->callback;
if (callback == aCallback)
{
nsCallbackEventRequest* toFree = node;
if (node == mFirstCallbackEventRequest) {
mFirstCallbackEventRequest = node->next;
node = mFirstCallbackEventRequest;
before = nsnull;
} else {
node = node->next;
before->next = node;
}
FreeFrame(sizeof(nsCallbackEventRequest), toFree);
NS_RELEASE(callback);
} else {
before = node;
node = node->next;
}
}
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.
@ -3484,6 +3517,7 @@ PresShell::PostAttributeChange(nsIContent* aContent,
return NS_OK;
}
void
PresShell::HandlePostedReflowCallbacks()
{

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

@ -1089,6 +1089,9 @@ nsBox::Redraw(nsBoxLayoutState& aState,
const nsRect* aDamageRect,
PRBool aImmediate)
{
if (aState.GetDisablePainting())
return NS_OK;
nsIPresContext* presContext = aState.GetPresContext();
const nsHTMLReflowState* s = aState.GetReflowState();
if (s) {

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

@ -764,6 +764,20 @@ nsBoxFrame::Reflow(nsIPresContext* aPresContext,
computedSize.height += m.top + m.bottom;
}
// handle reflow state min and max sizes
if (computedSize.width > aReflowState.mComputedMaxWidth)
computedSize.width = aReflowState.mComputedMaxWidth;
if (computedSize.height > aReflowState.mComputedMaxHeight)
computedSize.height = aReflowState.mComputedMaxHeight;
if (computedSize.width < aReflowState.mComputedMinWidth)
computedSize.width = aReflowState.mComputedMinWidth;
if (computedSize.height < aReflowState.mComputedMinHeight)
computedSize.height = aReflowState.mComputedMinHeight;
nsRect r(mRect.x, mRect.y, computedSize.width, computedSize.height);
SetBounds(state, r);

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

@ -43,7 +43,8 @@ nsBoxLayoutState::nsBoxLayoutState(nsIPresContext* aPresContext):mPresContext(aP
mMaxElementSize(nsnull),
mOverFlowSize(0,0),
mIncludeOverFlow(PR_TRUE),
mLayoutFlags(0)
mLayoutFlags(0),
mDisablePainting(PR_FALSE)
{
}
@ -55,6 +56,7 @@ nsBoxLayoutState::nsBoxLayoutState(const nsBoxLayoutState& aState)
mMaxElementSize = aState.mMaxElementSize;
mOverFlowSize = aState.mOverFlowSize;
mLayoutFlags = aState.mLayoutFlags;
mDisablePainting = aState.mDisablePainting;
}
nsBoxLayoutState::nsBoxLayoutState(nsIPresShell* aShell):mReflowState(nsnull),
@ -62,7 +64,8 @@ nsBoxLayoutState::nsBoxLayoutState(nsIPresShell* aShell):mReflowState(nsnull),
mMaxElementSize(nsnull),
mOverFlowSize(0,0),
mIncludeOverFlow(PR_TRUE),
mLayoutFlags(0)
mLayoutFlags(0),
mDisablePainting(PR_FALSE)
{
aShell->GetPresContext(getter_AddRefs(mPresContext));
}
@ -74,7 +77,8 @@ nsBoxLayoutState::nsBoxLayoutState(nsIPresContext* aPresContext,
mType(Dirty),
mOverFlowSize(0,0),
mIncludeOverFlow(PR_TRUE),
mLayoutFlags(0)
mLayoutFlags(0),
mDisablePainting(PR_FALSE)

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

@ -70,6 +70,10 @@ public:
virtual void GetLayoutFlags(PRUint32& aFlags);
virtual void SetLayoutFlags(const PRUint32& aFlags);
// if true no one under us will paint during reflow.
virtual void SetDisablePainting(PRBool aDisable) { mDisablePainting = aDisable; }
virtual PRBool GetDisablePainting() { return mDisablePainting; }
virtual eBoxLayoutReason GetLayoutReason() { return mType; }
virtual void SetLayoutReason(eBoxLayoutReason aReason) { mType = aReason; }
virtual const nsHTMLReflowState* GetReflowState() { return mReflowState; }
@ -95,6 +99,7 @@ private:
nsSize mOverFlowSize;
PRBool mIncludeOverFlow;
PRUint32 mLayoutFlags;
PRBool mDisablePainting;
};
#endif

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

@ -39,7 +39,7 @@ public:
static const nsIID& GetIID() { static nsIID iid = NS_ISCROLLBARLISTENER_IID; return iid; }
NS_IMETHOD PositionChanged(nsIPresContext* aPresContext, PRInt32 aOldIndex, PRInt32 aNewIndex) = 0;
NS_IMETHOD PositionChanged(nsIPresContext* aPresContext, PRInt32 aOldIndex, PRInt32& aNewIndex) = 0;
NS_IMETHOD PagedUpDown() = 0;
};

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

@ -36,7 +36,7 @@ class nsIScrollbarMediator : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_ISCROLLBARMEDIATOR_IID; return iid; }
NS_IMETHOD PositionChanged(PRInt32 aOldIndex, PRInt32 aNewIndex) = 0;
NS_IMETHOD PositionChanged(PRInt32 aOldIndex, PRInt32& aNewIndex) = 0;
NS_IMETHOD ScrollbarButtonPressed(PRInt32 aOldIndex, PRInt32 aNewIndex) = 0;
NS_IMETHOD VisibilityChanged(PRBool aVisible) = 0;

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

@ -38,6 +38,7 @@ public:
NS_IMETHOD IsOutermostFrame(PRBool* aResult) = 0;
NS_IMETHOD IsGroupFrame(PRBool* aResult) = 0;
NS_IMETHOD IsRowFrame(PRBool* aResult) = 0;
NS_IMETHOD GetOnScreenRowCount(PRInt32* aCount) = 0;
}; // class nsIXULTreeSlice

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

@ -201,6 +201,9 @@ nsSliderFrame::AttributeChanged(nsIPresContext* aPresContext,
scrollbarFrame->GetScrollbarMediator(getter_AddRefs(mediator));
if (mediator) {
mediator->PositionChanged(GetCurrentPosition(scrollbar), current);
char ch[100];
sprintf(ch,"%d", current);
scrollbar->SetAttribute(kNameSpaceID_None, nsXULAtoms::curpos, NS_ConvertASCIItoUCS2(ch), PR_FALSE);
return NS_OK;
}
}
@ -692,12 +695,18 @@ nsSliderFrame::SetCurrentPosition(nsIContent* scrollbar, nsIFrame* aThumbFrame,
nsIBox* scrollbarBox = GetScrollbar();
nsCOMPtr<nsIScrollbarFrame> scrollbarFrame(do_QueryInterface(scrollbarBox));
if (scrollbarFrame) {
// See if we have a mediator.
nsCOMPtr<nsIScrollbarMediator> mediator;
scrollbarFrame->GetScrollbarMediator(getter_AddRefs(mediator));
if (mediator) {
mediator->PositionChanged(GetCurrentPosition(scrollbar), newpos);
char ch[100];
sprintf(ch,"%d", newpos);
scrollbar->SetAttribute(kNameSpaceID_None, nsXULAtoms::curpos, NS_ConvertASCIItoUCS2(ch), PR_FALSE);
CurrentPositionChanged(mPresContext);
return;
}
}

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

@ -1087,10 +1087,8 @@ nsSplitterFrameInner::AdjustChildren(nsIPresContext* aPresContext)
mParentBox->Layout(state);
shell->ExitReflowLock(PR_TRUE);
*/
shell->FlushPendingNotifications();
nsCOMPtr<nsIViewManager> viewManager;
nsCOMPtr<nsIViewManager> viewManager;
nsIView* view = nsnull;
frame->GetView(aPresContext, &view);
@ -1099,19 +1097,23 @@ nsSplitterFrameInner::AdjustChildren(nsIPresContext* aPresContext)
if (view) {
view->GetViewManager(*getter_AddRefs(viewManager));
viewManager->UpdateView(view, damageRect, NS_VMREFRESH_IMMEDIATE);
} else {
nsRect rect(damageRect);
nsPoint offset;
frame->GetOffsetFromView(aPresContext, offset, &view);
NS_ASSERTION(nsnull != view, "no view");
rect += offset;
damageRect += offset;
view->GetViewManager(*getter_AddRefs(viewManager));
viewManager->UpdateView(view, rect, NS_VMREFRESH_IMMEDIATE);
}
viewManager->DisableRefresh();
shell->FlushPendingNotifications();
viewManager->EnableRefresh(NS_VMREFRESH_NO_SYNC);
viewManager->UpdateView(view, damageRect, NS_VMREFRESH_IMMEDIATE);
#else
//mOuter->mState |= NS_FRAME_IS_DIRTY;
//mOuter->mParent->ReflowDirtyChild(shell, mOuter->mParent);

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

@ -32,6 +32,9 @@
#include "nsIBox.h"
#include "nsIScrollableFrame.h"
#include "nsBox.h"
#include "nsIReflowCallback.h"
#include "nsBoxLayoutState.h"
// ------ nsTreeLayout ------
@ -141,17 +144,23 @@ nsTreeLayout::GetMaxSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsSize
return rv;
}
/**
* Called to layout our our children. Does no frame construction
*/
NS_IMETHODIMP
nsTreeLayout::LayoutInternal(nsIBox* aBox, nsBoxLayoutState& aState)
{
PRInt32 redrawStart = -1;
// Get the start y position.
nsXULTreeGroupFrame* frame = GetGroupFrame(aBox);
if (!frame) {
nsXULTreeGroupFrame* group = GetGroupFrame(aBox);
if (!group) {
NS_ERROR("Frame encountered that isn't a tree row group!\n");
return NS_ERROR_FAILURE;
}
nsXULTreeOuterGroupFrame* outer = group->GetOuterFrame();
nsMargin margin;
// Get our client rect.
@ -160,14 +169,16 @@ nsTreeLayout::LayoutInternal(nsIBox* aBox, nsBoxLayoutState& aState)
// Get the starting y position and the remaining available
// height.
nscoord availableHeight = frame->GetAvailableHeight();
nscoord yOffset = frame->GetYPosition();
nscoord availableHeight = group->GetAvailableHeight();
nscoord yOffset = group->GetYPosition();
if (availableHeight <= 0)
return NS_OK;
// Walk our frames, building them dynamically as needed.
nsIBox* box = frame->GetFirstTreeBox();
// run through all our currently created children
nsIBox* box = nsnull;
group->GetChildBox(&box);
while (box) {
// If this box is dirty or if it has dirty children, we
// call layout on it.
@ -175,12 +186,7 @@ nsTreeLayout::LayoutInternal(nsIBox* aBox, nsBoxLayoutState& aState)
PRBool dirtyChildren = PR_FALSE;
box->IsDirty(dirty);
box->HasDirtyChildren(dirtyChildren);
nsIFrame* childFrame;
box->GetFrame(&childFrame);
nsFrameState state;
childFrame->GetFrameState(&state);
PRBool isRow = PR_TRUE;
nsXULTreeGroupFrame* childGroup = GetGroupFrame(box);
if (childGroup) {
@ -189,71 +195,154 @@ nsTreeLayout::LayoutInternal(nsIBox* aBox, nsBoxLayoutState& aState)
isRow = PR_FALSE;
}
PRBool relayoutAll = (frame->GetOuterFrame()->GetTreeLayoutState() == eTreeLayoutDirtyAll);
// if the reason is resize or initial we must relayout.
PRBool relayout = (aState.GetLayoutReason() == nsBoxLayoutState::Resize || aState.GetLayoutReason() == nsBoxLayoutState::Initial);
nsRect childRect;
PRBool sizeChanged = PR_FALSE;
if (isRow) {
nsSize size;
box->GetPrefSize(aState, size);
if (size.width != clientRect.width)
sizeChanged = PR_TRUE;
}
if (relayoutAll || childGroup || sizeChanged || dirty || dirtyChildren || aState.GetLayoutReason() == nsBoxLayoutState::Initial) {
nsRect childRect;
box->GetMargin(margin);
// relayout if we must or we are dirty or some of our children are
// dirty
if (relayout || dirty || dirtyChildren) {
childRect.x = 0;
childRect.y = yOffset;
childRect.width = clientRect.width;
if (isRow)
childRect.height = frame->GetOuterFrame()->GetRowHeightTwips();
// of we can determine the height of the child be getting the number
// of row inside it and multiplying it by the height of a row.
// remember this is on screen rows not total row. We create things
// lazily and we only worry about what is on screen during layout.
nsCOMPtr<nsIXULTreeSlice> slice(do_QueryInterface(box));
PRInt32 rowCount = 0;
slice->GetOnScreenRowCount(&rowCount);
box->GetMargin(margin);
// if we are a row then we could potential change the row size. We
// don't know the height of a row until layout so tell the outer group
// now. If the row height is greater than the current. We may have to
// reflow everyone again!
if (isRow) {
nsSize size;
box->GetPrefSize(aState, size);
outer->SetRowHeight(size.height);
}
// of now get the row height and figure out our child's total height.
nscoord rowHeight = outer->GetRowHeightTwips();
childRect.height = rowHeight*rowCount;
childRect.Deflate(margin);
box->SetBounds(aState, childRect);
box->Layout(aState);
} else {
// if the child did not need to be relayed out. Then its easy.
// Place the child by just grabbing its rect and adjusting the y.
box->GetBounds(childRect);
PRInt32 newPos = yOffset+margin.top;
nsSize size;
if (!isRow) {
// We are a row group that might have dynamically
// constructed new rows. We need to clear out
// and recompute our pref size and then adjust our
// rect accordingly.
box->NeedsRecalc();
box->GetPrefSize(aState, size);
childRect.height = size.height;
box->SetBounds(aState, childRect);
}
else {// Check to see if the row height of the tree has changed.
box->GetPrefSize(aState, size);
frame->GetOuterFrame()->SetRowHeight(size.height);
}
// are we pushing down or pulling up any rows?
// Then we may have to redraw everything below the the moved
// rows.
if (redrawStart == -1 && childRect.y != newPos)
redrawStart = newPos;
childRect.y = newPos;
box->SetBounds(aState, childRect);
}
// Place the child by just grabbing its rect and adjusting the x,y.
box->GetContentRect(childRect);
childRect.x = 0;
childRect.y = yOffset;
yOffset += childRect.height;
availableHeight -= childRect.height;
box->GetMargin(margin);
childRect.Deflate(margin);
childRect.width = childRect.width < 0 ? 0 : childRect.width;
childRect.height = childRect.height < 0 ? 0 : childRect.height;
// Ok now the available size gets smaller and we move the
// starting position of the next child down some.
nscoord size = childRect.height + margin.top + margin.bottom;
yOffset += size;
availableHeight -= size;
box->SetBounds(aState, childRect);
box->GetNextBox(&box);
}
if ((frame->GetOuterFrame()->GetTreeLayoutState() == eTreeLayoutAbort) ||
(!frame->ContinueReflow(availableHeight)))
break;
if (availableHeight > outer->GetRowHeightTwips() || availableHeight < 0) {
// of if we have enough available height left to add some more rows
// or we have to much then we need to add or create some rows. We
// can't do this durning layout but we can do it after. So post
// a callback to do it after.
outer->PostReflowCallback();
}
box = frame->GetNextTreeBox(box);
// if rows were pushed down or pulled up because some rows were added
// before them then redraw everything under the inserted rows. The inserted
// rows will automatically be redrawn because the were marked dirty on insertion.
if (redrawStart > -1) {
nsRect bounds;
aBox->GetBounds(bounds);
aBox->Redraw(aState, &nsRect(0,redrawStart,bounds.width, bounds.height - redrawStart));
}
return NS_OK;
}
/**
* This method creates or removes rows lazily. This is done after layout because
* It is illegal to add or remove frames during layout in the box system.
*/
NS_IMETHODIMP
nsTreeLayout::LazyRowCreator(nsBoxLayoutState& aState, nsXULTreeGroupFrame* aGroup)
{
nsXULTreeOuterGroupFrame* outer = aGroup->GetOuterFrame();
// Get our client rect.
nsRect clientRect;
aGroup->GetClientRect(clientRect);
// Get the starting y position and the remaining available
// height.
nscoord availableHeight = aGroup->GetAvailableHeight();
if (availableHeight <= 0)
return NS_OK;
nsSize size;
// get the first tree box. If there isn't one create one.
PRBool created = PR_FALSE;
nsIBox* box = aGroup->GetFirstTreeBox(&created);
while (box) {
// if its a group recursizely dive into it to build its rows.
PRBool isRow = PR_TRUE;
nsXULTreeGroupFrame* childGroup = GetGroupFrame(box);
if (childGroup) {
childGroup->SetAvailableHeight(availableHeight);
LazyRowCreator(aState, childGroup);
isRow = PR_FALSE;
}
nscoord rowHeight = outer->GetRowHeightTwips();
// if the row height is 0 then fail. Wait until someone
// laid out and sets the row height.
if (rowHeight == 0)
return NS_OK;
// figure out the child's height. Its the number of rows
// the child contains * the row height. Remember this is
// on screen rows not total rows.
nsCOMPtr<nsIXULTreeSlice> slice(do_QueryInterface(box));
PRInt32 rowCount = 0;
slice->GetOnScreenRowCount(&rowCount);
availableHeight -= rowHeight*rowCount;
// should we continue? Is the enought height?
if (!aGroup->ContinueReflow(availableHeight))
break;
// get the next tree box. Create one if needed.
box = aGroup->GetNextTreeBox(box, &created);
}
return NS_OK;
}
NS_IMETHODIMP
@ -265,7 +354,6 @@ nsTreeLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
if (isOuterGroup) {
nsXULTreeOuterGroupFrame* outer = (nsXULTreeOuterGroupFrame*) frame;
nsTreeLayoutState state = outer->GetTreeLayoutState();
// Always ensure an accurate scrollview position
// This is an edge case that was caused by the row height
@ -283,12 +371,6 @@ nsTreeLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
nsresult rv = LayoutInternal(aBox, aState);
if (NS_FAILED(rv)) return rv;
state = outer->GetTreeLayoutState();
if (state == eTreeLayoutDirtyAll)
outer->SetTreeLayoutState(eTreeLayoutNormal);
else if (state == eTreeLayoutAbort)
outer->SetTreeLayoutState(eTreeLayoutDirtyAll);
state = outer->GetTreeLayoutState();
}
else
return LayoutInternal(aBox, aState);

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

@ -34,6 +34,9 @@
#include "nsXULTreeOuterGroupFrame.h"
#include "nsXULTreeSliceFrame.h"
class nsIBox;
class nsBoxLayoutState;
class nsTreeLayout : public nsTempleLayout
{
public:
@ -45,6 +48,8 @@ public:
NS_IMETHOD Layout(nsIBox* aBox, nsBoxLayoutState& aState);
NS_IMETHOD LazyRowCreator(nsBoxLayoutState& aState, nsXULTreeGroupFrame* aGroup);
protected:
nsXULTreeOuterGroupFrame* GetOuterFrame(nsIBox* aBox);
nsXULTreeGroupFrame* GetGroupFrame(nsIBox* aBox);

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

@ -110,14 +110,8 @@ nsXULTreeFrame::DoLayout(nsBoxLayoutState& aBoxLayoutState)
nsXULTreeOuterGroupFrame* treeOuterGroup = nsnull;
GetTreeBody(&treeOuterGroup);
if (treeOuterGroup)
treeOuterGroup->SetLayingOut(PR_TRUE);
nsresult rv = nsBoxFrame::DoLayout(aBoxLayoutState);
if (treeOuterGroup)
treeOuterGroup->SetLayingOut(PR_FALSE);
return rv;
}

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

@ -90,7 +90,8 @@ NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
nsXULTreeGroupFrame::nsXULTreeGroupFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal), mFrameConstructor(nsnull), mPresContext(nsnull),
mOuterFrame(nsnull), mAvailableHeight(10000), mTopFrame(nsnull), mBottomFrame(nsnull), mLinkupFrame(nsnull),
mContentChain(nsnull), mYDropLoc(nsTreeItemDragCapturer::kNoDropLoc), mDropOnContainer(PR_FALSE)
mContentChain(nsnull), mYDropLoc(nsTreeItemDragCapturer::kNoDropLoc), mDropOnContainer(PR_FALSE),
mOnScreenRowCount(-1)
{}
// Destructor
@ -156,6 +157,34 @@ void nsXULTreeGroupFrame::LocateFrame(nsIFrame* aStartFrame, nsIFrame** aResult)
else aStartFrame->GetNextSibling(aResult);
}
NS_IMETHODIMP
nsXULTreeGroupFrame::NeedsRecalc()
{
mOnScreenRowCount = -1;
return nsBoxFrame::NeedsRecalc();
}
NS_IMETHODIMP
nsXULTreeGroupFrame::GetOnScreenRowCount(PRInt32* aCount)
{
if (mOnScreenRowCount == -1)
{
mOnScreenRowCount = 0;
nsIBox* box = nsnull;
GetChildBox(&box);
while(box) {
PRInt32 count = 0;
nsCOMPtr<nsIXULTreeSlice> slice(do_QueryInterface(box));
slice->GetOnScreenRowCount(&count);
mOnScreenRowCount += count;
box->GetNextBox(&box);
}
}
*aCount = mOnScreenRowCount;
return NS_OK;
}
nsIFrame*
nsXULTreeGroupFrame::GetFirstFrame()
{
@ -178,8 +207,12 @@ nsXULTreeGroupFrame::GetLastFrame()
}
nsIBox*
nsXULTreeGroupFrame::GetFirstTreeBox()
nsXULTreeGroupFrame::GetFirstTreeBox(PRBool* aCreated)
{
if (aCreated)
*aCreated = PR_FALSE;
// Clear ourselves out.
mLinkupFrame = nsnull;
mBottomFrame = mTopFrame;
@ -250,6 +283,10 @@ nsXULTreeGroupFrame::GetFirstTreeBox()
mFrameConstructor->CreateTreeWidgetContent(mPresContext, this, nsnull, startContent,
&mTopFrame, isAppend, PR_FALSE,
nsnull);
if (aCreated)
*aCreated = PR_TRUE;
//if (mTopFrame)
// mOuterFrame->PostReflowCallback();
@ -267,8 +304,9 @@ nsXULTreeGroupFrame::GetFirstTreeBox()
}
SetContentChain(nsnull);
nsCOMPtr<nsIBox> box(do_QueryInterface(mTopFrame));
return box;
}
return nsnull;
@ -276,8 +314,11 @@ nsXULTreeGroupFrame::GetFirstTreeBox()
}
nsIBox*
nsXULTreeGroupFrame::GetNextTreeBox(nsIBox* aBox)
nsXULTreeGroupFrame::GetNextTreeBox(nsIBox* aBox, PRBool* aCreated)
{
if (aCreated)
*aCreated = PR_FALSE;
// We're ultra-cool. We build our frames on the fly.
nsIFrame* result;
nsIFrame* frame;
@ -329,6 +370,10 @@ nsXULTreeGroupFrame::GetNextTreeBox(nsIBox* aBox)
mFrameConstructor->CreateTreeWidgetContent(mPresContext, this, prevFrame, nextContent,
&result, isAppend, PR_FALSE,
nsnull);
if (aCreated)
*aCreated = PR_TRUE;
//if (result)
// mOuterFrame->PostReflowCallback();
}
@ -346,8 +391,8 @@ nsXULTreeGroupFrame::TreeInsertFrames(nsIFrame* aPrevFrame, nsIFrame* aFrameList
// insert the frames to our info list
nsBoxLayoutState state(mPresContext);
Insert(state, aPrevFrame, aFrameList);
mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
MarkDirtyChildren(state);
return NS_OK;
}
@ -357,8 +402,9 @@ nsXULTreeGroupFrame::TreeAppendFrames(nsIFrame* aFrameList)
// append them after
nsBoxLayoutState state(mPresContext);
Append(state,aFrameList);
mFrames.AppendFrames(nsnull, aFrameList);
MarkDirtyChildren(state);
return NS_OK;
}
@ -392,8 +438,10 @@ nsXULTreeGroupFrame::OnContentInserted(nsIPresContext* aPresContext, nsIFrame* a
mFrameConstructor->RemoveMappingsForFrameSubtree(aPresContext, currFrame, nsnull);
nsBoxLayoutState state(aPresContext);
Remove(state, currFrame);
mFrames.DestroyFrame(aPresContext, currFrame);
currFrame = nextFrame;
}
nsBoxLayoutState state(aPresContext);
@ -412,9 +460,11 @@ void nsXULTreeGroupFrame::OnContentRemoved(nsIPresContext* aPresContext,
nsBoxLayoutState state(aPresContext);
if (aChildFrame) {
mFrameConstructor->RemoveMappingsForFrameSubtree(aPresContext, aChildFrame, nsnull);
Remove(state, aChildFrame);
mFrames.DestroyFrame(aPresContext, aChildFrame);
MarkDirtyChildren(state);
// Get our old row count.
PRInt32 rowCount = mOuterFrame->GetRowCount();
@ -460,18 +510,21 @@ PRBool nsXULTreeGroupFrame::ContinueReflow(nscoord height)
// Nuke them.
nsIFrame* currFrame;
startingPoint->GetNextSibling(&currFrame);
nsBoxLayoutState state(mPresContext);
while (currFrame) {
nsIFrame* nextFrame;
currFrame->GetNextSibling(&nextFrame);
mFrameConstructor->RemoveMappingsForFrameSubtree(mPresContext, currFrame, nsnull);
nsBoxLayoutState state(mPresContext);
Remove(state, currFrame);
mFrames.DestroyFrame(mPresContext, currFrame);
currFrame = nextFrame;
}
MarkDirtyChildren(state);
}
return PR_FALSE;
}
@ -510,8 +563,11 @@ void nsXULTreeGroupFrame::DestroyRows(PRInt32& aRowsToLose)
nsIFrame* nextFrame = GetNextFrame(childFrame);
mFrameConstructor->RemoveMappingsForFrameSubtree(mPresContext, childFrame, nsnull);
nsBoxLayoutState state(mPresContext);
Remove(state, childFrame);
mFrames.DestroyFrame(mPresContext, childFrame);
MarkDirtyChildren(state);
mTopFrame = childFrame = nextFrame;
}
}
@ -547,8 +603,11 @@ void nsXULTreeGroupFrame::ReverseDestroyRows(PRInt32& aRowsToLose)
prevFrame = mFrames.GetPrevSiblingFor(childFrame);
mFrameConstructor->RemoveMappingsForFrameSubtree(mPresContext, childFrame, nsnull);
nsBoxLayoutState state(mPresContext);
Remove(state, childFrame);
mFrames.DestroyFrame(mPresContext, childFrame);
MarkDirtyChildren(state);
mBottomFrame = childFrame = prevFrame;
}
}
@ -914,7 +973,7 @@ nsXULTreeGroupFrame :: FindFirstChildTreeItemFrame ( nsIPresContext* inPresConte
break;
currChildFrame->GetNextSibling ( &currChildFrame );
} // foreach child of the treeItem
NS_ASSERTION ( currChildFrame, "Can't find <treechildren>" );
//NS_ASSERTION ( currChildFrame, "Can't find <treechildren>" );
// |currChildFrame| now holds the correct frame if we found it
if ( currChildFrame )

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

@ -68,8 +68,8 @@ public:
PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aHint) ;
nsXULTreeOuterGroupFrame* GetOuterFrame() { return mOuterFrame; };
nsIBox* GetFirstTreeBox();
nsIBox* GetNextTreeBox(nsIBox* aBox);
nsIBox* GetFirstTreeBox(PRBool* aCreated = nsnull);
nsIBox* GetNextTreeBox(nsIBox* aBox, PRBool* aCreated = nsnull);
nsIFrame* GetFirstFrame();
nsIFrame* GetNextFrame(nsIFrame* aCurrFrame);
@ -92,7 +92,11 @@ public:
NS_IMETHOD IsOutermostFrame(PRBool* aResult) { *aResult = PR_FALSE; return NS_OK; };
NS_IMETHOD IsGroupFrame(PRBool* aResult) { *aResult = PR_TRUE; return NS_OK; };
NS_IMETHOD IsRowFrame(PRBool* aResult) { *aResult = PR_FALSE; return NS_OK; };
NS_IMETHOD GetOnScreenRowCount(PRInt32* aCount);
// nsIBox
NS_IMETHOD NeedsRecalc();
virtual nscoord GetAvailableHeight() { return mAvailableHeight; };
void SetAvailableHeight(nscoord aHeight) { mAvailableHeight = aHeight; };
@ -133,6 +137,7 @@ protected:
nsIFrame* mBottomFrame;
nsIFrame* mLinkupFrame;
nsISupportsArray* mContentChain; // Our content chain
PRInt32 mOnScreenRowCount;
// -- members for drag and drop --

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

@ -42,14 +42,27 @@
#include "nsIScrollableView.h"
#include "nsIMonument.h"
#include "nsTempleLayout.h"
#include "nsTreeLayout.h"
#include "nsITimer.h"
#define TICK_FACTOR 50
// the longest amount of time that can go by before the use
// notices it as a delay.
#define USER_TIME_THRESHOLD 150000
// how long it takes to layout a single row inital value.
// we will time this after we scroll a few rows.
#define TIME_PER_ROW_INITAL 50000
// if we decide we can't layout the rows in the amount of time. How long
// do we wait before checking again?
#define SMOOTH_INTERVAL 100
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
nsresult NS_NewAutoScrollTimer(nsXULTreeOuterGroupFrame* aTree, nsDragAutoScrollTimer **aResult) ;
//
// nsDragOverListener
//
@ -114,6 +127,82 @@ nsDragOverListener :: DragOver(nsIDOMEvent* aDragEvent)
#pragma mark -
#endif
/* A mediator used to smooth out scrolling. It works by seeing if
* we have time to scroll the amount of rows requested. This is determined
* by measuring how long it takes to scroll a row. If we can scroll the
* rows in time we do so. If not we start a timer and skip the request. We
* do this until the timer finally first because the user has stopped moving
* the mouse. Then do all the queued requests in on shot.
*/
class nsScrollSmoother : public nsITimerCallback
{
public:
NS_IMETHOD_(void) Notify(nsITimer *timer);
void Start();
void Stop();
PRBool IsRunning();
NS_DECL_ISUPPORTS
virtual ~nsScrollSmoother();
nsScrollSmoother(nsXULTreeOuterGroupFrame* aOuter);
nsCOMPtr<nsITimer> mRepeatTimer;
PRBool mDelta;
nsXULTreeOuterGroupFrame* mOuter;
};
nsScrollSmoother::nsScrollSmoother(nsXULTreeOuterGroupFrame* aOuter)
{
NS_INIT_REFCNT();
nsresult rv = NS_OK;
mDelta = 0;
mOuter = aOuter;
}
nsScrollSmoother::~nsScrollSmoother()
{
Stop();
}
PRBool nsScrollSmoother::IsRunning()
{
if (mRepeatTimer)
return PR_TRUE;
else
return PR_FALSE;
}
void nsScrollSmoother::Start()
{
Stop();
mRepeatTimer = do_CreateInstance("@mozilla.org/timer;1");
mRepeatTimer->Init(this, SMOOTH_INTERVAL);
}
void nsScrollSmoother::Stop()
{
if ( mRepeatTimer ) {
mRepeatTimer->Cancel();
mRepeatTimer = nsnull;
}
}
NS_IMETHODIMP_(void) nsScrollSmoother::Notify(nsITimer *timer)
{
//printf("Timer Callback!\n");
Stop();
// actually do some work.
mOuter->InternalPositionChangedCallback();
}
NS_IMPL_ISUPPORTS1(nsScrollSmoother, nsITimerCallback)
//
// NS_NewXULTreeOuterGroupFrame
@ -143,14 +232,34 @@ nsXULTreeOuterGroupFrame::nsXULTreeOuterGroupFrame(nsIPresShell* aPresShell, PRB
:nsXULTreeGroupFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal),
mRowGroupInfo(nsnull), mRowHeight(0), mCurrentIndex(0),
mTreeIsSorted(PR_FALSE), mDragOverListener(nsnull), mCanDropBetweenRows(PR_TRUE),
mTreeLayoutState(eTreeLayoutNormal), mReflowCallbackPosted(PR_FALSE)
mRowHeightWasSet(PR_FALSE), mReflowCallbackPosted(PR_FALSE), mYPosition(0), mScrolling(PR_FALSE),
mScrollSmoother(nsnull), mTimePerRow(TIME_PER_ROW_INITAL), mAdjustScroll(PR_FALSE)
{
}
NS_IMETHODIMP
nsXULTreeOuterGroupFrame::Destroy(nsIPresContext* aPresContext)
{
// make sure we cancel any posted callbacks.
if (mReflowCallbackPosted) {
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
shell->CancelReflowCallback(this);
}
return nsXULTreeGroupFrame::Destroy(aPresContext);
}
// Destructor
nsXULTreeOuterGroupFrame::~nsXULTreeOuterGroupFrame()
{
NS_IF_RELEASE(mScrollSmoother);
// TODO cancel posted events.
nsCOMPtr<nsIContent> content;
GetContent(getter_AddRefs(content));
nsCOMPtr<nsIDOMEventReceiver> receiver(do_QueryInterface(content));
@ -200,7 +309,7 @@ nsXULTreeOuterGroupFrame::Init(nsIPresContext* aPresContext, nsIContent* aConten
{
nsresult rv = nsXULTreeGroupFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mLayingOut = PR_FALSE;
// mLayingOut = PR_FALSE;
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
@ -257,7 +366,19 @@ nsXULTreeOuterGroupFrame::Init(nsIPresContext* aPresContext, nsIContent* aConten
NS_IMETHODIMP
nsXULTreeOuterGroupFrame::DoLayout(nsBoxLayoutState& aBoxLayoutState)
{
if (mScrolling)
aBoxLayoutState.SetDisablePainting(PR_TRUE);
nsresult rv = nsXULTreeGroupFrame::DoLayout(aBoxLayoutState);
if (mScrolling)
aBoxLayoutState.SetDisablePainting(PR_FALSE);
// if we are scrolled and the row height changed
// make sure we are scrolled to a correct index.
if (mAdjustScroll)
PostReflowCallback();
return rv;
}
@ -292,10 +413,11 @@ nsXULTreeOuterGroupFrame::SetRowHeight(nscoord aRowHeight)
value.AppendInt(rowHeight*count);
parent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::height, value, PR_FALSE);
}
nsBoxLayoutState state(mPresContext);
MarkDirtyChildren(state);
mTreeLayoutState = eTreeLayoutAbort;
// signal we need to dirty everything
// and we want to be notified after reflow
// so we can create or destory rows as needed
mRowHeightWasSet = PR_TRUE;
PostReflowCallback();
}
}
@ -303,22 +425,7 @@ nsXULTreeOuterGroupFrame::SetRowHeight(nscoord aRowHeight)
nscoord
nsXULTreeOuterGroupFrame::GetYPosition()
{
nsIBox* box;
GetParentBox(&box);
if (!box)
return 0;
box->GetParentBox(&box);
if (!box)
return 0;
nsCOMPtr<nsIScrollableFrame> scrollFrame(do_QueryInterface(box));
if (!scrollFrame)
return 0;
nscoord x, y;
scrollFrame->GetScrollPosition(mPresContext, x, y);
return y;
return mYPosition;
}
void
@ -341,6 +448,8 @@ nsXULTreeOuterGroupFrame::VerticalScroll(PRInt32 aPosition)
scrollFrame->GetScrollPosition(mPresContext, x, y);
scrollFrame->ScrollTo(mPresContext, x, aPosition, NS_SCROLL_PROPERTY_ALWAYS_BLIT);
mYPosition = aPosition;
}
nscoord
@ -429,41 +538,105 @@ nsXULTreeOuterGroupFrame::ScrollbarButtonPressed(PRInt32 aOldIndex, PRInt32 aNew
return NS_OK;
}
InternalPositionChanged(aNewIndex < aOldIndex, 1);
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeOuterGroupFrame::PositionChanged(PRInt32 aOldIndex, PRInt32 aNewIndex)
{
if (aOldIndex == aNewIndex)
return NS_OK;
nsXULTreeOuterGroupFrame::PositionChanged(PRInt32 aOldIndex, PRInt32& aNewIndex)
{
PRInt32 oldTwipIndex, newTwipIndex;
oldTwipIndex = (aOldIndex*mOnePixel);
oldTwipIndex = mCurrentIndex*mRowHeight;
newTwipIndex = (aNewIndex*mOnePixel);
PRInt32 twipDelta = newTwipIndex > oldTwipIndex ? newTwipIndex - oldTwipIndex : oldTwipIndex - newTwipIndex;
PRInt32 delta = twipDelta / mRowHeight;
PRInt32 rowDelta = twipDelta / mRowHeight;
PRInt32 remainder = twipDelta % mRowHeight;
if (remainder > (mRowHeight/2))
delta++;
rowDelta++;
if (delta == 0)
if (rowDelta == 0)
return NS_OK;
mCurrentIndex = newTwipIndex > oldTwipIndex ? mCurrentIndex + delta : mCurrentIndex - delta;
// update the position to be row based.
PRInt32 newIndex = newTwipIndex > oldTwipIndex ? mCurrentIndex + rowDelta : mCurrentIndex - rowDelta;
//aNewIndex = newIndex*mRowHeight/mOnePixel;
nsScrollSmoother* smoother = GetSmoother();
//printf("%d rows, %d per row, Estimated time needed %d, Threshhold %d (%s)\n", rowDelta, mTimePerRow, mTimePerRow * rowDelta, USER_TIME_THRESHOLD, (mTimePerRow * rowDelta > USER_TIME_THRESHOLD) ? "Nope" : "Yep");
// if we can't scroll the rows in time then start a timer. We will eat
// events until the user stops moving and the timer stops.
if (smoother->IsRunning() || rowDelta*mTimePerRow > USER_TIME_THRESHOLD) {
smoother->Stop();
nsCOMPtr<nsIPresShell> shell;
mPresContext->GetShell(getter_AddRefs(shell));
shell->FlushPendingNotifications();
smoother->mDelta = newTwipIndex > oldTwipIndex ? rowDelta : -rowDelta;
//printf("Eating scroll!\n");
smoother->Start();
return NS_OK;
}
smoother->Stop();
mCurrentIndex = newIndex;
smoother->mDelta = 0;
if (mCurrentIndex < 0) {
mCurrentIndex = 0;
return NS_OK;
}
return InternalPositionChanged(newTwipIndex < oldTwipIndex, delta);
return InternalPositionChanged(newTwipIndex < oldTwipIndex, rowDelta);
}
nsScrollSmoother*
nsXULTreeOuterGroupFrame::GetSmoother()
{
if (!mScrollSmoother) {
mScrollSmoother = new nsScrollSmoother(this);
NS_ADDREF(mScrollSmoother);
}
return mScrollSmoother;
}
NS_IMETHODIMP
nsXULTreeOuterGroupFrame::InternalPositionChangedCallback()
{
nsScrollSmoother* smoother = GetSmoother();
if (smoother->mDelta == 0)
return NS_OK;
mCurrentIndex += smoother->mDelta;
if (mCurrentIndex < 0)
mCurrentIndex = 0;
return InternalPositionChanged(smoother->mDelta < 0, smoother->mDelta < 0 ? -smoother->mDelta : smoother->mDelta);
}
NS_IMETHODIMP
nsXULTreeOuterGroupFrame::InternalPositionChanged(PRBool aUp, PRInt32 aDelta)
{
{
if (aDelta == 0)
return NS_OK;
// begin timing how long it takes to scroll a row
PRTime start = PR_Now();
//printf("Actually doing scroll mCurrentIndex=%d, delta=%d!\n", mCurrentIndex, aDelta);
//if (mContentChain) {
// XXX Eventually we need to make the code smart enough to look at a content chain
// when building ANOTHER content chain.
@ -534,16 +707,31 @@ nsXULTreeOuterGroupFrame::InternalPositionChanged(PRBool aUp, PRInt32 aDelta)
}
mTopFrame = mBottomFrame = nsnull; // Make sure everything is cleared out.
VerticalScroll(mCurrentIndex*mRowHeight);
if (mLayingOut) {
PostReflowCallback();
}
else {
nsBoxLayoutState state(mPresContext);
MarkDirtyChildren(state);
}
mYPosition = mCurrentIndex*mRowHeight;
nsBoxLayoutState state(mPresContext);
nsCOMPtr<nsIBoxLayout> layout;
GetLayoutManager(getter_AddRefs(layout));
nsTreeLayout* treeLayout = (nsTreeLayout*)layout.get();
treeLayout->LazyRowCreator(state, this);
mScrolling = PR_TRUE;
shell->FlushPendingNotifications();
mScrolling = PR_FALSE;
VerticalScroll(mYPosition);
PRTime end = PR_Now();
PRTime difTime;
LL_SUB(difTime, end, start);
PRInt32 newTime;
LL_L2I(newTime, difTime);
newTime /= aDelta;
// average old and new
mTimePerRow = (newTime + mTimePerRow)/2;
//printf("time per row=%d\n", mTimePerRow);
return NS_OK;
}
@ -937,14 +1125,16 @@ nsXULTreeOuterGroupFrame::EnsureRowIsVisible(PRInt32 aRowIndex)
InternalPositionChanged(up, delta);
/*
// This change has to happen immediately.
if (mLayingOut) {
PostReflowCallback();
}
else {
nsBoxLayoutState state(mPresContext);
MarkDirtyChildren(state);
//nsBoxLayoutState state(mPresContext);
//MarkDirtyChildren(state);
}
*/
}
void
@ -1047,10 +1237,33 @@ nsXULTreeOuterGroupFrame::ReflowFinished(nsIPresShell* aPresShell, PRBool* aFlus
nsCOMPtr<nsIBox> treeBox(do_QueryInterface(treeFrame));
mReflowCallbackPosted = PR_FALSE;
nsBoxLayoutState state(mPresContext);
//MarkDirtyChildren(state);
treeBox->MarkStyleChange(state);
// now build or destroy any needed rows.
nsCOMPtr<nsIBoxLayout> layout;
GetLayoutManager(getter_AddRefs(layout));
nsTreeLayout* treeLayout = (nsTreeLayout*)layout.get();
treeLayout->LazyRowCreator(state, this);
if (mAdjustScroll) {
PRInt32 pos = mCurrentIndex*mRowHeight;
VerticalScroll(mYPosition);
mAdjustScroll = PR_FALSE;
}
// if the row height changed
// then mark everything as a style change. That
// will dirty the tree all the way to its leaves.
if (mRowHeightWasSet) {
treeBox->MarkStyleChange(state);
PRInt32 pos = mCurrentIndex*mRowHeight;
if (mYPosition != pos)
mAdjustScroll = PR_TRUE;
mRowHeightWasSet = PR_FALSE;
}
mReflowCallbackPosted = PR_FALSE;
*aFlushFlag = PR_TRUE;
return NS_OK;

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

@ -40,6 +40,7 @@
class nsCSSFrameConstructor;
class nsDragOverListener;
class nsDragAutoScrollTimer;
class nsScrollSmoother;
// I want to eventually use a delay so that the user has to hover over
@ -50,13 +51,6 @@ class nsDragAutoScrollTimer;
// good (pinkerton)
#define USE_TIMER_TO_DELAY_SCROLLING 0
enum nsTreeLayoutState {
eTreeLayoutNormal,
eTreeLayoutAbort,
eTreeLayoutDirtyAll
};
class nsXULTreeRowGroupInfo {
public:
PRInt32 mRowCount;
@ -141,8 +135,6 @@ public:
void SetRowHeight(PRInt32 aRowHeight);
PRBool IsFixedRowSize();
void SetLayingOut(PRBool aLayingOut) { mLayingOut = aLayingOut; };
nscoord GetYPosition();
nscoord GetAvailableHeight();
NS_IMETHOD GetNumberOfVisibleRows(PRInt32 *aResult) {
@ -155,7 +147,7 @@ public:
NS_IMETHOD GetRowCount(PRInt32* aResult) { *aResult = GetRowCount(); return NS_OK; }
NS_IMETHOD PositionChanged(PRInt32 aOldIndex, PRInt32 aNewIndex);
NS_IMETHOD PositionChanged(PRInt32 aOldIndex, PRInt32& aNewIndex);
NS_IMETHOD ScrollbarButtonPressed(PRInt32 aOldIndex, PRInt32 aNewIndex);
NS_IMETHOD VisibilityChanged(PRBool aVisible);
@ -188,17 +180,20 @@ public:
PRInt32 *aResult);
NS_IMETHOD InternalPositionChanged(PRBool aUp, PRInt32 aDelta);
NS_IMETHOD InternalPositionChangedCallback();
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
PRBool IsTreeSorted ( ) const { return mTreeIsSorted; }
PRBool CanDropBetweenRows ( ) const { return mCanDropBetweenRows; }
nsTreeLayoutState GetTreeLayoutState() { return mTreeLayoutState; }
void SetTreeLayoutState(nsTreeLayoutState aState) { mTreeLayoutState = aState; }
void PostReflowCallback();
protected:
nsScrollSmoother* GetSmoother();
void ComputeTotalRowCount(PRInt32& aRowCount, nsIContent* aParent);
// Drag Auto-scrolling
@ -225,9 +220,13 @@ protected:
// in Init() for why this is a weak ref.
nsDragOverListener* mDragOverListener;
nsTreeLayoutState mTreeLayoutState;
PRBool mReflowCallbackPosted;
PRBool mLayingOut;
PRPackedBool mRowHeightWasSet;
PRPackedBool mReflowCallbackPosted;
PRPackedBool mScrolling;
PRPackedBool mAdjustScroll;
PRInt32 mYPosition;
nsScrollSmoother* mScrollSmoother;
PRInt32 mTimePerRow;
}; // class nsXULTreeOuterGroupFrame

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

@ -40,6 +40,7 @@ public:
NS_IMETHOD IsOutermostFrame(PRBool* aResult) { *aResult = PR_FALSE; return NS_OK; };
NS_IMETHOD IsGroupFrame(PRBool* aResult) { *aResult = PR_FALSE; return NS_OK; };
NS_IMETHOD IsRowFrame(PRBool* aResult) { *aResult = PR_TRUE; return NS_OK; };
NS_IMETHOD GetOnScreenRowCount(PRInt32* aCount) { *aCount = 1; return NS_OK; }
// nsIBox
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize);