Added ReparentFrameView() and changed the block and inline code

to call it when pushing/pulling frames
This commit is contained in:
troy%netscape.com 1999-04-11 04:22:00 +00:00
Родитель 5deed64036
Коммит 4fda80d9f5
12 изменённых файлов: 296 добавлений и 0 удалений

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

@ -1839,6 +1839,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
PRInt32 n = line->ChildCount();
while (--n >= 0) {
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsHTMLContainerFrame::ReparentFrameView(frame, mNextInFlow, this);
lastFrame = frame;
frame->GetNextSibling(&frame);
}
@ -2070,8 +2073,16 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
// Change geometric parents
if (aUpdateGeometricParent) {
// Before we set the new parent frame get the current parent
nsIFrame* oldParentFrame;
frame->GetParent(&oldParentFrame);
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
NS_ASSERTION(oldParentFrame != this, "unexpected parent frame");
nsHTMLContainerFrame::ReparentFrameView(frame, oldParentFrame, this);
// The frame is being pulled from a next-in-flow; therefore we
// need to add it to our sibling list.
if (nsnull != aState.mPrevChild) {
@ -3451,6 +3462,12 @@ nsBlockFrame::DrainOverflowLines()
nsIFrame* frame = line->mFirstChild;
while (nsnull != frame) {
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsHTMLContainerFrame::ReparentFrameView(frame, prevBlock, this);
// Get the next frame
lastFrame = frame;
frame->GetNextSibling(&frame);
}

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

@ -1839,6 +1839,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
PRInt32 n = line->ChildCount();
while (--n >= 0) {
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsHTMLContainerFrame::ReparentFrameView(frame, mNextInFlow, this);
lastFrame = frame;
frame->GetNextSibling(&frame);
}
@ -2070,8 +2073,16 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
// Change geometric parents
if (aUpdateGeometricParent) {
// Before we set the new parent frame get the current parent
nsIFrame* oldParentFrame;
frame->GetParent(&oldParentFrame);
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
NS_ASSERTION(oldParentFrame != this, "unexpected parent frame");
nsHTMLContainerFrame::ReparentFrameView(frame, oldParentFrame, this);
// The frame is being pulled from a next-in-flow; therefore we
// need to add it to our sibling list.
if (nsnull != aState.mPrevChild) {
@ -3451,6 +3462,12 @@ nsBlockFrame::DrainOverflowLines()
nsIFrame* frame = line->mFirstChild;
while (nsnull != frame) {
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsHTMLContainerFrame::ReparentFrameView(frame, prevBlock, this);
// Get the next frame
lastFrame = frame;
frame->GetNextSibling(&frame);
}

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

@ -1839,6 +1839,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
PRInt32 n = line->ChildCount();
while (--n >= 0) {
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsHTMLContainerFrame::ReparentFrameView(frame, mNextInFlow, this);
lastFrame = frame;
frame->GetNextSibling(&frame);
}
@ -2070,8 +2073,16 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
// Change geometric parents
if (aUpdateGeometricParent) {
// Before we set the new parent frame get the current parent
nsIFrame* oldParentFrame;
frame->GetParent(&oldParentFrame);
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
NS_ASSERTION(oldParentFrame != this, "unexpected parent frame");
nsHTMLContainerFrame::ReparentFrameView(frame, oldParentFrame, this);
// The frame is being pulled from a next-in-flow; therefore we
// need to add it to our sibling list.
if (nsnull != aState.mPrevChild) {
@ -3451,6 +3462,12 @@ nsBlockFrame::DrainOverflowLines()
nsIFrame* frame = line->mFirstChild;
while (nsnull != frame) {
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsHTMLContainerFrame::ReparentFrameView(frame, prevBlock, this);
// Get the next frame
lastFrame = frame;
frame->GetNextSibling(&frame);
}

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

@ -123,6 +123,91 @@ nsHTMLContainerFrame::CreateNextInFlow(nsIPresContext& aPresContext,
return NS_OK;
}
static nsresult
ReparentFrameViewTo(nsIFrame* aFrame,
nsIView* aNewParentView,
nsIView* aOldParentView)
{
nsIView* view;
// Does aFrame have a view?
aFrame->GetView(&view);
if (view) {
nsIViewManager* viewManager;
#ifdef NS_DEBUG
// Verify that the current parent view is what we think it is
nsIView* parentView;
view->GetParent(parentView);
NS_ASSERTION(parentView == aOldParentView, "unexpected parent view");
#endif
// Get the view manager
aNewParentView->GetViewManager(viewManager);
NS_ASSERTION(nsnull != viewManager, "null view manager");
// Change the parent view.
PRInt32 zIndex;
view->GetZIndex(zIndex);
viewManager->RemoveChild(aOldParentView, view);
// XXX We need to insert this view in the correct place within its z-order...
viewManager->InsertChild(aNewParentView, view, zIndex);
NS_RELEASE(viewManager);
} else {
// Iterate the child frames, and check each child frame to see if it has
// a view
nsIFrame* childFrame;
aFrame->FirstChild(nsnull, &childFrame);
while (childFrame) {
ReparentFrameViewTo(childFrame, aNewParentView, aOldParentView);
childFrame->GetNextSibling(&childFrame);
}
}
return NS_OK;
}
static nsIView*
GetViewFor(nsIFrame* aFrame)
{
nsIView* view;
aFrame->GetView(&view);
if (!view) {
nsPoint offset;
aFrame->GetOffsetFromView(offset, &view);
}
NS_POSTCONDITION(view, "no containing view");
return view;
}
nsresult
nsHTMLContainerFrame::ReparentFrameView(nsIFrame* aChildFrame,
nsIFrame* aOldParentFrame,
nsIFrame* aNewParentFrame)
{
NS_PRECONDITION(aChildFrame, "null child frame pointer");
NS_PRECONDITION(aOldParentFrame, "null old parent frame pointer");
NS_PRECONDITION(aNewParentFrame, "null new parent frame pointer");
NS_PRECONDITION(aOldParentFrame != aNewParentFrame, "same old and new parent frame");
// First see if the old parent frame and the new parent frame are in the
// same view sub-hierarchy
nsIView* oldParentView = GetViewFor(aOldParentFrame);
nsIView* newParentView = GetViewFor(aNewParentFrame);
if (oldParentView != newParentView) {
return ReparentFrameViewTo(aChildFrame, newParentView, oldParentView);
}
return NS_OK;
}
nsresult
nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext,
nsIFrame* aFrame,

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

@ -62,6 +62,10 @@ public:
nsIStyleContext* aStyleContext,
PRBool aForce);
static nsresult ReparentFrameView(nsIFrame* aChildFrame,
nsIFrame* aOldParentFrame,
nsIFrame* aNewParentFrame);
protected:
virtual PRIntn GetSkipSides() const = 0;
};

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

@ -1284,6 +1284,14 @@ nsInlineFrame::DrainOverflow()
nsInlineFrame* prevInFlow = (nsInlineFrame*)mPrevInFlow;
if (nsnull != prevInFlow) {
if (prevInFlow->mOverflowFrames.NotEmpty()) {
// When pushing and pulling frames we need to check for whether any
// views need to be reparented.
// XXX Doing it this way means an extra pass over the frames. We could
// change InsertFrames() to do this, but that's a general purpose
// function and it doesn't seem like this functionality belongs there...
for (nsIFrame* f = prevInFlow->mOverflowFrames.FirstChild(); f; f->GetNextSibling(&f)) {
nsHTMLContainerFrame::ReparentFrameView(f, prevInFlow, this);
}
mFrames.InsertFrames(this, nsnull, prevInFlow->mOverflowFrames);
changedFirstFrame = PR_TRUE;
}

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

@ -1839,6 +1839,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
PRInt32 n = line->ChildCount();
while (--n >= 0) {
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsHTMLContainerFrame::ReparentFrameView(frame, mNextInFlow, this);
lastFrame = frame;
frame->GetNextSibling(&frame);
}
@ -2070,8 +2073,16 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
// Change geometric parents
if (aUpdateGeometricParent) {
// Before we set the new parent frame get the current parent
nsIFrame* oldParentFrame;
frame->GetParent(&oldParentFrame);
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
NS_ASSERTION(oldParentFrame != this, "unexpected parent frame");
nsHTMLContainerFrame::ReparentFrameView(frame, oldParentFrame, this);
// The frame is being pulled from a next-in-flow; therefore we
// need to add it to our sibling list.
if (nsnull != aState.mPrevChild) {
@ -3451,6 +3462,12 @@ nsBlockFrame::DrainOverflowLines()
nsIFrame* frame = line->mFirstChild;
while (nsnull != frame) {
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsHTMLContainerFrame::ReparentFrameView(frame, prevBlock, this);
// Get the next frame
lastFrame = frame;
frame->GetNextSibling(&frame);
}

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

@ -1839,6 +1839,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
PRInt32 n = line->ChildCount();
while (--n >= 0) {
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsHTMLContainerFrame::ReparentFrameView(frame, mNextInFlow, this);
lastFrame = frame;
frame->GetNextSibling(&frame);
}
@ -2070,8 +2073,16 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
// Change geometric parents
if (aUpdateGeometricParent) {
// Before we set the new parent frame get the current parent
nsIFrame* oldParentFrame;
frame->GetParent(&oldParentFrame);
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
NS_ASSERTION(oldParentFrame != this, "unexpected parent frame");
nsHTMLContainerFrame::ReparentFrameView(frame, oldParentFrame, this);
// The frame is being pulled from a next-in-flow; therefore we
// need to add it to our sibling list.
if (nsnull != aState.mPrevChild) {
@ -3451,6 +3462,12 @@ nsBlockFrame::DrainOverflowLines()
nsIFrame* frame = line->mFirstChild;
while (nsnull != frame) {
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsHTMLContainerFrame::ReparentFrameView(frame, prevBlock, this);
// Get the next frame
lastFrame = frame;
frame->GetNextSibling(&frame);
}

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

@ -1839,6 +1839,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
PRInt32 n = line->ChildCount();
while (--n >= 0) {
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsHTMLContainerFrame::ReparentFrameView(frame, mNextInFlow, this);
lastFrame = frame;
frame->GetNextSibling(&frame);
}
@ -2070,8 +2073,16 @@ nsBlockFrame::PullFrame(nsBlockReflowState& aState,
// Change geometric parents
if (aUpdateGeometricParent) {
// Before we set the new parent frame get the current parent
nsIFrame* oldParentFrame;
frame->GetParent(&oldParentFrame);
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
NS_ASSERTION(oldParentFrame != this, "unexpected parent frame");
nsHTMLContainerFrame::ReparentFrameView(frame, oldParentFrame, this);
// The frame is being pulled from a next-in-flow; therefore we
// need to add it to our sibling list.
if (nsnull != aState.mPrevChild) {
@ -3451,6 +3462,12 @@ nsBlockFrame::DrainOverflowLines()
nsIFrame* frame = line->mFirstChild;
while (nsnull != frame) {
frame->SetParent(this);
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsHTMLContainerFrame::ReparentFrameView(frame, prevBlock, this);
// Get the next frame
lastFrame = frame;
frame->GetNextSibling(&frame);
}

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

@ -123,6 +123,91 @@ nsHTMLContainerFrame::CreateNextInFlow(nsIPresContext& aPresContext,
return NS_OK;
}
static nsresult
ReparentFrameViewTo(nsIFrame* aFrame,
nsIView* aNewParentView,
nsIView* aOldParentView)
{
nsIView* view;
// Does aFrame have a view?
aFrame->GetView(&view);
if (view) {
nsIViewManager* viewManager;
#ifdef NS_DEBUG
// Verify that the current parent view is what we think it is
nsIView* parentView;
view->GetParent(parentView);
NS_ASSERTION(parentView == aOldParentView, "unexpected parent view");
#endif
// Get the view manager
aNewParentView->GetViewManager(viewManager);
NS_ASSERTION(nsnull != viewManager, "null view manager");
// Change the parent view.
PRInt32 zIndex;
view->GetZIndex(zIndex);
viewManager->RemoveChild(aOldParentView, view);
// XXX We need to insert this view in the correct place within its z-order...
viewManager->InsertChild(aNewParentView, view, zIndex);
NS_RELEASE(viewManager);
} else {
// Iterate the child frames, and check each child frame to see if it has
// a view
nsIFrame* childFrame;
aFrame->FirstChild(nsnull, &childFrame);
while (childFrame) {
ReparentFrameViewTo(childFrame, aNewParentView, aOldParentView);
childFrame->GetNextSibling(&childFrame);
}
}
return NS_OK;
}
static nsIView*
GetViewFor(nsIFrame* aFrame)
{
nsIView* view;
aFrame->GetView(&view);
if (!view) {
nsPoint offset;
aFrame->GetOffsetFromView(offset, &view);
}
NS_POSTCONDITION(view, "no containing view");
return view;
}
nsresult
nsHTMLContainerFrame::ReparentFrameView(nsIFrame* aChildFrame,
nsIFrame* aOldParentFrame,
nsIFrame* aNewParentFrame)
{
NS_PRECONDITION(aChildFrame, "null child frame pointer");
NS_PRECONDITION(aOldParentFrame, "null old parent frame pointer");
NS_PRECONDITION(aNewParentFrame, "null new parent frame pointer");
NS_PRECONDITION(aOldParentFrame != aNewParentFrame, "same old and new parent frame");
// First see if the old parent frame and the new parent frame are in the
// same view sub-hierarchy
nsIView* oldParentView = GetViewFor(aOldParentFrame);
nsIView* newParentView = GetViewFor(aNewParentFrame);
if (oldParentView != newParentView) {
return ReparentFrameViewTo(aChildFrame, newParentView, oldParentView);
}
return NS_OK;
}
nsresult
nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext,
nsIFrame* aFrame,

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

@ -62,6 +62,10 @@ public:
nsIStyleContext* aStyleContext,
PRBool aForce);
static nsresult ReparentFrameView(nsIFrame* aChildFrame,
nsIFrame* aOldParentFrame,
nsIFrame* aNewParentFrame);
protected:
virtual PRIntn GetSkipSides() const = 0;
};

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

@ -1284,6 +1284,14 @@ nsInlineFrame::DrainOverflow()
nsInlineFrame* prevInFlow = (nsInlineFrame*)mPrevInFlow;
if (nsnull != prevInFlow) {
if (prevInFlow->mOverflowFrames.NotEmpty()) {
// When pushing and pulling frames we need to check for whether any
// views need to be reparented.
// XXX Doing it this way means an extra pass over the frames. We could
// change InsertFrames() to do this, but that's a general purpose
// function and it doesn't seem like this functionality belongs there...
for (nsIFrame* f = prevInFlow->mOverflowFrames.FirstChild(); f; f->GetNextSibling(&f)) {
nsHTMLContainerFrame::ReparentFrameView(f, prevInFlow, this);
}
mFrames.InsertFrames(this, nsnull, prevInFlow->mOverflowFrames);
changedFirstFrame = PR_TRUE;
}