-r hyatt, -a jar git-svn-id: svn://10.0.0.236/trunk@62022 18797224-902f-48f8-a5cc-f745e15eee43
251 lines
6.8 KiB
C++
251 lines
6.8 KiB
C++
/* -*- 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.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
|
|
//
|
|
// Eric Vaughan
|
|
// Netscape Communications
|
|
//
|
|
// See documentation in associated header file
|
|
//
|
|
|
|
#include "nsDeckFrame.h"
|
|
#include "nsIStyleContext.h"
|
|
#include "nsIPresContext.h"
|
|
#include "nsIContent.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsHTMLIIDs.h"
|
|
#include "nsUnitConversion.h"
|
|
#include "nsINameSpaceManager.h"
|
|
#include "nsXULAtoms.h"
|
|
#include "nsHTMLAtoms.h"
|
|
#include "nsIReflowCommand.h"
|
|
#include "nsHTMLParts.h"
|
|
#include "nsIPresShell.h"
|
|
#include "nsStyleChangeList.h"
|
|
#include "nsCSSRendering.h"
|
|
#include "nsIViewManager.h"
|
|
|
|
|
|
nsresult
|
|
NS_NewDeckFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
|
|
{
|
|
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
|
if (nsnull == aNewFrame) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
nsDeckFrame* it = new (aPresShell) nsDeckFrame(aPresShell);
|
|
if (nsnull == it)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
*aNewFrame = it;
|
|
return NS_OK;
|
|
|
|
} // NS_NewDeckFrame
|
|
|
|
|
|
nsDeckFrame::nsDeckFrame(nsIPresShell* aPresShell):nsStackFrame(aPresShell)
|
|
{
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDeckFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|
nsIContent* aChild,
|
|
PRInt32 aNameSpaceID,
|
|
nsIAtom* aAttribute,
|
|
PRInt32 aHint)
|
|
{
|
|
nsresult rv = nsStackFrame::AttributeChanged(aPresContext, aChild,
|
|
aNameSpaceID, aAttribute, aHint);
|
|
|
|
|
|
// if the index changed hide the old element and make the now element visible
|
|
if (aAttribute == nsHTMLAtoms::index) {
|
|
|
|
Invalidate(aPresContext, nsRect(0,0,mRect.width,mRect.height), PR_FALSE);
|
|
|
|
int index = 0;
|
|
|
|
// get the index attribute
|
|
nsAutoString value;
|
|
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::index, value))
|
|
{
|
|
PRInt32 error;
|
|
|
|
// convert it to an integer
|
|
index = value.ToInteger(&error);
|
|
}
|
|
|
|
nsIFrame* childFrame = mFrames.FirstChild();
|
|
nscoord count = 0;
|
|
while (nsnull != childFrame)
|
|
{
|
|
// make collapsed children not show up
|
|
if (index != count)
|
|
CollapseChild(aPresContext, childFrame, PR_TRUE);
|
|
else
|
|
CollapseChild(aPresContext, childFrame, PR_FALSE);
|
|
|
|
rv = childFrame->GetNextSibling(&childFrame);
|
|
NS_ASSERTION(rv == NS_OK,"failed to get next child");
|
|
count++;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NS_OK != rv) {
|
|
return rv;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsIFrame*
|
|
nsDeckFrame::GetSelectedFrame()
|
|
{
|
|
// ok we want to paint only the child that as at the given index
|
|
|
|
// default index is 0
|
|
int index = 0;
|
|
|
|
// get the index attribute
|
|
nsAutoString value;
|
|
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::index, value))
|
|
{
|
|
PRInt32 error;
|
|
|
|
// convert it to an integer
|
|
index = value.ToInteger(&error);
|
|
}
|
|
|
|
// get the child at that index.
|
|
nsIFrame* childFrame = mFrames.FrameAt(index);
|
|
return childFrame;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsDeckFrame::Paint(nsIPresContext* aPresContext,
|
|
nsIRenderingContext& aRenderingContext,
|
|
const nsRect& aDirtyRect,
|
|
nsFramePaintLayer aWhichLayer)
|
|
{
|
|
// if a tab is hidden all its children are too.
|
|
const nsStyleDisplay* disp = (const nsStyleDisplay*)
|
|
mStyleContext->GetStyleData(eStyleStruct_Display);
|
|
if (!disp->mVisible)
|
|
return NS_OK;
|
|
|
|
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
|
|
if (disp->mVisible && mRect.width && mRect.height) {
|
|
// Paint our background and border
|
|
PRIntn skipSides = GetSkipSides();
|
|
const nsStyleColor* color = (const nsStyleColor*)
|
|
mStyleContext->GetStyleData(eStyleStruct_Color);
|
|
const nsStyleSpacing* spacing = (const nsStyleSpacing*)
|
|
mStyleContext->GetStyleData(eStyleStruct_Spacing);
|
|
|
|
nsRect rect(0, 0, mRect.width, mRect.height);
|
|
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
|
|
aDirtyRect, rect, *color, *spacing, 0, 0);
|
|
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
|
|
aDirtyRect, rect, *spacing, mStyleContext, skipSides);
|
|
}
|
|
}
|
|
|
|
nsIFrame* frame = GetSelectedFrame();
|
|
|
|
if (frame != nsnull)
|
|
PaintChild(aPresContext, aRenderingContext, aDirtyRect, frame, aWhichLayer);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsDeckFrame::GetFrameForPoint(nsIPresContext* aPresContext,
|
|
const nsPoint& aPoint,
|
|
nsIFrame** aFrame)
|
|
{
|
|
// if its not in our child just return us.
|
|
*aFrame = this;
|
|
|
|
// get the selected frame and see if the point is in it.
|
|
nsIFrame* selectedFrame = GetSelectedFrame();
|
|
|
|
if (nsnull != selectedFrame)
|
|
{
|
|
nsRect childRect;
|
|
selectedFrame->GetRect(childRect);
|
|
|
|
if (childRect.Contains(aPoint)) {
|
|
// adjust the point
|
|
nsPoint p = aPoint;
|
|
p.x -= childRect.x;
|
|
p.y -= childRect.y;
|
|
return selectedFrame->GetFrameForPoint(aPresContext, p, aFrame);
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDeckFrame::DidReflow(nsIPresContext* aPresContext,
|
|
nsDidReflowStatus aStatus)
|
|
{
|
|
int index = 0;
|
|
|
|
// get the index attribute
|
|
nsAutoString value;
|
|
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::index, value))
|
|
{
|
|
PRInt32 error;
|
|
|
|
// convert it to an integer
|
|
index = value.ToInteger(&error);
|
|
}
|
|
|
|
nsresult rv = nsBoxFrame::DidReflow(aPresContext, aStatus);
|
|
NS_ASSERTION(rv == NS_OK,"DidReflow failed");
|
|
|
|
nsIFrame* childFrame = mFrames.FirstChild();
|
|
nscoord count = 0;
|
|
while (nsnull != childFrame)
|
|
{
|
|
// make collapsed children not show up
|
|
if (index != count)
|
|
CollapseChild(aPresContext, childFrame, PR_TRUE);
|
|
else
|
|
CollapseChild(aPresContext, childFrame, PR_FALSE);
|
|
|
|
rv = childFrame->GetNextSibling(&childFrame);
|
|
NS_ASSERTION(rv == NS_OK,"failed to get next child");
|
|
count++;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|