box skinnablility changes.

-r Hyatt
This commit is contained in:
evaughan@netscape.com
2000-03-31 07:02:06 +00:00
parent 0323d432bf
commit 74c65e34ee
88 changed files with 10466 additions and 7899 deletions

View File

@@ -97,6 +97,7 @@ XUL_ATOM(crop, "crop")
XUL_ATOM(mode, "mode")
XUL_ATOM(box, "box")
XUL_ATOM(mousethrough, "mousethrough")
XUL_ATOM(flex, "flex")
XUL_ATOM(spring, "spring")
XUL_ATOM(orient, "orient")
@@ -130,6 +131,13 @@ XUL_ATOM(resizeafter, "resizeafter")
XUL_ATOM(state, "state")
XUL_ATOM(debug, "debug")
// grid
XUL_ATOM(grid, "grid")
XUL_ATOM(rows, "rows")
XUL_ATOM(columns, "columns")
XUL_ATOM(row, "row")
XUL_ATOM(column, "column")
// toolbar & toolbar d&d atoms
XUL_ATOM(ddDropLocation, "dd-droplocation")
XUL_ATOM(ddDropLocationCoord, "dd-droplocationcoord")

View File

@@ -206,6 +206,7 @@ menu.colorpicker {
margin-bottom: 2px;
}
menu.colorpicker:active {
border: 1px inset #CCCCCC;
}

View File

@@ -120,7 +120,7 @@
#include "nsIDOMDocument.h"
#include "nsDocument.h"
#include "nsToolbarItemFrame.h"
#include "nsXULCheckboxFrame.h"
#include "nsCheckBoxFrame.h"
#include "nsIScrollable.h"
#ifdef DEBUG
@@ -132,8 +132,28 @@ static PRBool gNoisyInlineConstruction = PR_FALSE;
#define NEWGFX_LIST_SCROLLFRAME
//------------------------------------------------------------------
#ifdef NEWGFX_LIST_SCROLLFRAME
nsresult
NS_NewGfxListControlFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
#endif
// grid
/*
nsresult
NS_NewGridFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewTempleFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsHorizontal);
nsresult
NS_NewObeliskFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsHorizontal);
// end grid
*/
nsresult
NS_NewRootBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewThumbFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
@@ -142,7 +162,7 @@ nsresult
NS_NewScrollPortFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewGfxScrollFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, nsIDocument* aDocument );
NS_NewGfxScrollFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, nsIDocument* aDocument, PRBool aIsRoot);
nsresult
NS_NewTabFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
@@ -163,7 +183,10 @@ nsresult
NS_NewTitledButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewXULTextFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
NS_NewImageBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewTextBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewTitledBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
@@ -178,7 +201,7 @@ nsresult
NS_NewBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot);
nsresult
NS_NewXULButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_NewButtonBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame);
nsresult
NS_NewSliderFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
@@ -2359,6 +2382,7 @@ nsCSSFrameConstructor::TableIsValidCellContent(nsIPresContext* aPresContext,
#ifdef INCLUDE_XUL
if ( (nsXULAtoms::button == tag.get()) ||
(nsXULAtoms::titledbutton == tag.get()) ||
(nsXULAtoms::box == tag.get()) ||
(nsXULAtoms::image == tag.get()) ||
(nsXULAtoms::grippy == tag.get()) ||
(nsXULAtoms::splitter == tag.get()) ||
@@ -2603,6 +2627,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell,
aParentFrame,
nsLayoutAtoms::scrolledContentPseudo,
document,
PR_FALSE,
scrollFrame,
newContext,
newScrollFrame);
@@ -2837,7 +2862,15 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell,
nsIAtom* rootPseudo;
if (!isPaginated) {
PRInt32 nameSpaceID;
if (NS_SUCCEEDED(aDocElement->GetNameSpaceID(nameSpaceID)) &&
nameSpaceID == nsXULAtoms::nameSpaceID)
{
NS_NewRootBoxFrame(aPresShell, &rootFrame);
} else {
NS_NewRootFrame(aPresShell, &rootFrame);
}
rootPseudo = nsLayoutAtoms::canvasPseudo;
mDocElementContainingBlock = rootFrame;
} else {
@@ -2868,6 +2901,8 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell,
}
}
//isScrollable = PR_FALSE;
// As long as the webshell doesn't prohibit it, and the device supports
// it, create a scroll frame that will act as the scolling mechanism for
// the viewport.
@@ -2941,6 +2976,7 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell,
viewportFrame,
rootPseudo,
document,
PR_TRUE,
newFrame,
rootPseudoStyle,
newScrollableFrame);
@@ -4656,7 +4692,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
else if (aTag == nsXULAtoms::button) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewXULButtonFrame(aPresShell, &newFrame);
rv = NS_NewButtonBoxFrame(aPresShell, &newFrame);
const nsStyleDisplay* display = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);
@@ -4679,15 +4715,18 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
} // End of BUTTON CONSTRUCTION logic
// TITLED BUTTON CONSTRUCTION
else if (aTag == nsXULAtoms::titledbutton ||
aTag == nsXULAtoms::image) {
else if (aTag == nsXULAtoms::titledbutton) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewTitledButtonFrame(aPresShell, &newFrame);
}
// End of TITLED BUTTON CONSTRUCTION logic
else if (aTag == nsXULAtoms::image) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewImageBoxFrame(aPresShell, &newFrame);
}
else if (aTag == nsXULAtoms::spring) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
@@ -4699,7 +4738,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
else if (aTag == nsXULAtoms::text) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewXULTextFrame(aPresShell, &newFrame);
rv = NS_NewTextBoxFrame(aPresShell, &newFrame);
}
// End of TEXT CONSTRUCTION logic
@@ -4737,6 +4776,89 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
isReplaced = PR_TRUE;
rv = NS_NewMenuPopupFrame(aPresShell, &newFrame);
}
/*
// ------- Begin Grid ---------
else if (aTag == nsXULAtoms::grid) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewGridFrame(aPresShell, &newFrame);
const nsStyleDisplay* display = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);
// Boxes can scroll.
if (IsScrollable(aPresContext, display)) {
// set the top to be the newly created scrollframe
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
topFrame, aStyleContext);
// we have a scrollframe so the parent becomes the scroll frame.
newFrame->GetParent(&aParentFrame);
primaryFrameSet = PR_TRUE;
frameHasBeenInitialized = PR_TRUE;
}
} //------- End Grid ------
// ------- Begin Rows/Columns ---------
else if (aTag == nsXULAtoms::rows || aTag == nsXULAtoms::columns) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
PRBool isHorizontal = (aTag == nsXULAtoms::columns);
rv = NS_NewTempleFrame(aPresShell, &newFrame, isHorizontal);
const nsStyleDisplay* display = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);
// Boxes can scroll.
if (IsScrollable(aPresContext, display)) {
// set the top to be the newly created scrollframe
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
topFrame, aStyleContext);
// we have a scrollframe so the parent becomes the scroll frame.
newFrame->GetParent(&aParentFrame);
primaryFrameSet = PR_TRUE;
frameHasBeenInitialized = PR_TRUE;
}
} //------- End Grid ------
// ------- Begin Row/Column ---------
else if (aTag == nsXULAtoms::row || aTag == nsXULAtoms::column) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
PRBool isHorizontal = (aTag == nsXULAtoms::row);
rv = NS_NewObeliskFrame(aPresShell, &newFrame, isHorizontal);
const nsStyleDisplay* display = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);
// Boxes can scroll.
if (IsScrollable(aPresContext, display)) {
// set the top to be the newly created scrollframe
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
topFrame, aStyleContext);
// we have a scrollframe so the parent becomes the scroll frame.
newFrame->GetParent(&aParentFrame);
primaryFrameSet = PR_TRUE;
frameHasBeenInitialized = PR_TRUE;
}
} //------- End Grid ------
*/
else if (aTag == nsXULAtoms::title) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
@@ -4949,7 +5071,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
aTag == nsXULAtoms::radio) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewXULCheckboxFrame(aPresShell, &newFrame);
rv = NS_NewCheckBoxFrame(aPresShell, &newFrame);
}
// End of XULCHECKBOX CONSTRUCTION logic
@@ -5123,6 +5245,7 @@ nsCSSFrameConstructor::BeginBuildingScrollFrame(nsIPresShell* aPresShell,
nsIFrame* aParentFrame,
nsIAtom* aScrolledPseudo,
nsIDocument* aDocument,
PRBool aIsRoot,
nsIFrame*& aNewFrame,
nsCOMPtr<nsIStyleContext>& aScrolledChildStyle,
nsIFrame*& aScrollableFrame)
@@ -5140,7 +5263,7 @@ nsCSSFrameConstructor::BeginBuildingScrollFrame(nsIPresShell* aPresShell,
if (isGfx) {
BuildGfxScrollFrame(aPresShell, aPresContext, aState, aContent, aDocument, aParentFrame,
contentStyle, gfxScrollFrame, anonymousItems);
contentStyle, aIsRoot, gfxScrollFrame, anonymousItems);
scrollFrame = anonymousItems.childList;
parentFrame = gfxScrollFrame;
@@ -5283,6 +5406,7 @@ nsCSSFrameConstructor::BuildScrollFrame (nsIPresShell* aPresShell,
aParentFrame,
nsLayoutAtoms::scrolledContentPseudo,
document,
PR_FALSE,
aNewFrame,
scrolledContentStyle,
scrollFrame);
@@ -5317,10 +5441,11 @@ nsCSSFrameConstructor::BuildGfxScrollFrame (nsIPresShell* aPresShell,
nsIDocument* aDocument,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
PRBool aIsRoot,
nsIFrame*& aNewFrame,
nsFrameItems& aAnonymousFrames)
{
NS_NewGfxScrollFrame(aPresShell, &aNewFrame,aDocument);
NS_NewGfxScrollFrame(aPresShell, &aNewFrame, aDocument, aIsRoot);
InitAndRestoreFrame(aPresContext, aState, aContent,
aParentFrame, aStyleContext, nsnull, aNewFrame);
@@ -7074,6 +7199,28 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
} else {
// Find the frame that precedes the insertion point.
nsIFrame* prevSibling = FindPreviousSibling(shell, aContainer, aIndexInContainer);
/*
if (prevSibling) {
nsIFrame* parent;
prevSibling->GetParent(&parent);
nsIFrame* first;
parent->FirstChild(aPresContext, nsnull, &first);
PRBool found = PR_FALSE;
while(first)
{
if (first == prevSibling) {
found = PR_TRUE;
break;
}
first->GetNextSibling(&first);
}
NS_ASSERTION(found,"Error sibling not in parent!!!!!");
}
*/
nsIFrame* nextSibling = nsnull;
PRBool isAppend = PR_FALSE;

View File

@@ -646,6 +646,7 @@ protected:
nsIFrame* aParentFrame,
nsIAtom* aScrolledPseudo,
nsIDocument* aDocument,
PRBool aIsRoot,
nsIFrame*& aNewFrame,
nsCOMPtr<nsIStyleContext>& aScrolledChildStyle,
nsIFrame*& aScrollableFrame);
@@ -671,6 +672,7 @@ protected:
nsIDocument* aDocument,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
PRBool aIsRoot,
nsIFrame*& aNewFrame,
nsFrameItems& aAnonymousFrames);

View File

@@ -110,6 +110,11 @@ public:
NS_IMETHOD AllocateFrame(size_t aSize, void** aResult) = 0;
NS_IMETHOD FreeFrame(size_t aSize, void* aFreeChunk) = 0;
// Dynamic stack memory allocation
NS_IMETHOD PushStackMemory() = 0;
NS_IMETHOD PopStackMemory() = 0;
NS_IMETHOD AllocateStackMemory(size_t aSize, void** aResult) = 0;
NS_IMETHOD GetDocument(nsIDocument** aResult) = 0;
NS_IMETHOD GetPresContext(nsIPresContext** aResult) = 0;

View File

@@ -147,7 +147,7 @@ static NS_DEFINE_CID(kCXIFConverterCID, NS_XIFFORMATCONVERTER_CID);
static PRInt32 gMaxRCProcessingTime = -1;
// Largest chunk size we recycle
static const size_t gMaxRecycledSize = 300;
static const size_t gMaxRecycledSize = 400;
// Flag for enabling/disabling asynchronous reflow
// Set via the "layout.reflow.async" pref
@@ -157,6 +157,173 @@ static PRBool gDoAsyncReflow = PR_FALSE;
// Set via the "layout.reflow.async.afterDocLoad" pref
static PRBool gDoAsyncReflowAfterDocLoad = PR_FALSE;
#define MARK_INCREMENT 50
#define BLOCK_INCREMENT 2048
/**A block of memory that the stack will
* chop up and hand out
*/
struct StackBlock {
// a block of memory
void* mBlock;
// another block of memory that would only be created
// if our stack overflowed. Yes we have the ability
// to grow on a stack overflow
StackBlock* mNext;
StackBlock()
{
mBlock = new char*[BLOCK_INCREMENT];
mNext = nsnull;
}
~StackBlock()
{
delete[] mBlock;
}
};
/* we hold an array of marks. A push pushes a mark on the stack
* a pop pops it off.
*/
struct StackMark {
// the block of memory we are currently handing out chunks of
StackBlock* mBlock;
// our current position in the memory
size_t mPos;
};
/* A stack arena allows a stack based interface to a block of memory.
* It should be used when you need to allocate some temporary memory that
* you will immediately return.
*/
class StackArena {
public:
StackArena();
~StackArena();
// Memory management functions
nsresult Allocate(size_t aSize, void** aResult);
nsresult Push();
nsresult Pop();
private:
// our current position in memory
size_t mPos;
// a list of memory block. Usually there is only one
// but if we overrun our stack size we can get more memory.
StackBlock* mBlocks;
// the current block of memory we are passing our chucks of
StackBlock* mCurBlock;
// our stack of mark where push has been called
StackMark* mMarks;
// the current top of the the mark list
PRUint32 mStackTop;
// the size of the mark array
PRUint32 mMarkLength;
};
StackArena::StackArena()
{
// allocate the marks array
mMarkLength = MARK_INCREMENT;
mMarks = new StackMark[mMarkLength];
// allocate our stack memory
mBlocks = new StackBlock();
mCurBlock = mBlocks;
mStackTop = 0;
mPos = 0;
}
StackArena::~StackArena()
{
// free up our data
delete[] mMarks;
while(mBlocks)
{
StackBlock* toDelete = mBlocks;
mBlocks = mBlocks->mNext;
delete toDelete;
}
}
nsresult
StackArena::Push()
{
// if the we overrun our mark array. Resize it.
if (mStackTop + 1 >= mMarkLength)
{
StackMark* oldMarks = mMarks;
PRUint32 oldLength = mMarkLength;
mMarkLength += MARK_INCREMENT;
void* marks = 0;
mMarks = new StackMark[mMarkLength];
nsCRT::memcpy(mMarks, oldMarks, sizeof(StackMark)*oldLength);
delete[] oldMarks;
}
// set a mark at the top
mMarks[mStackTop].mBlock = mCurBlock;
mMarks[mStackTop].mPos = mPos;
mStackTop++;
return NS_OK;
}
nsresult
StackArena::Allocate(size_t aSize, void** aResult)
{
NS_ASSERTION(mStackTop > 0, "Error allocate called before push!!!");
// make sure we are aligned. Beard said 8 was safer then 4.
// Round size to multiple of 8
aSize = PR_ROUNDUP(aSize, 8);
// if the size makes the stack overflow. Grab another block for the stack
if (mPos + aSize >= BLOCK_INCREMENT)
{
NS_ASSERTION(aSize <= BLOCK_INCREMENT,"Requested memory is greater that our block size!!");
if (mCurBlock->mNext == nsnull)
mCurBlock->mNext = new StackBlock();
mCurBlock = mCurBlock->mNext;
mPos = 0;
}
// return the chunk they need.
*aResult = ((char*)mCurBlock->mBlock) + mPos;
mPos += aSize;
return NS_OK;
}
nsresult
StackArena::Pop()
{
// pop off the mark
NS_ASSERTION(mStackTop > 0, "Error Pop called 1 too many times");
mStackTop--;
mCurBlock = mMarks[mStackTop].mBlock;
mPos = mMarks[mStackTop].mPos;
return NS_OK;
}
// Memory is allocated 4-byte aligned. We have recyclers for chunks up to
// 200 bytes
class FrameArena {
@@ -310,6 +477,11 @@ public:
NS_IMETHOD AllocateFrame(size_t aSize, void** aResult);
NS_IMETHOD FreeFrame(size_t aSize, void* aFreeChunk);
// Dynamic stack memory allocation
NS_IMETHOD PushStackMemory();
NS_IMETHOD PopStackMemory();
NS_IMETHOD AllocateStackMemory(size_t aSize, void** aResult);
NS_IMETHOD GetDocument(nsIDocument** aResult);
NS_IMETHOD GetPresContext(nsIPresContext** aResult);
NS_IMETHOD GetViewManager(nsIViewManager** aResult);
@@ -522,6 +694,7 @@ protected:
PRBool mPendingReflowEvent;
nsCOMPtr<nsIEventQueue> mEventQueue;
FrameArena mFrameArena;
StackArena* mStackArena;
PRInt32 mAccumulatedReflowTime; // Time spent in reflow command processing so far
PRPackedBool mDocumentIsLoading; // A flag that is true while the document is loading.
PRPackedBool mBatchReflows; // When set to true, the pres shell batches reflow commands.
@@ -540,6 +713,8 @@ protected:
private:
void FreeDynamicStack();
//helper funcs for disabing autoscrolling
void DisableScrolling(){mScrollingEnabled = PR_FALSE;}
void EnableScrolling(){mScrollingEnabled = PR_TRUE;}
@@ -650,7 +825,7 @@ NS_NewPresShell(nsIPresShell** aInstancePtrResult)
(void **) aInstancePtrResult);
}
PresShell::PresShell()
PresShell::PresShell():mStackArena(nsnull)
{
NS_INIT_REFCNT();
mIsDestroying = PR_FALSE;
@@ -718,6 +893,9 @@ PresShell::QueryInterface(const nsIID& aIID, void** aInstancePtr)
PresShell::~PresShell()
{
// if we allocated any stack memory free it.
FreeDynamicStack();
mRefCnt = 99;/* XXX hack! get around re-entrancy bugs */
mIsDestroying = PR_TRUE;
@@ -873,6 +1051,44 @@ PresShell::Init(nsIDocument* aDocument,
return NS_OK;
}
// Dynamic stack memory allocation
NS_IMETHODIMP
PresShell::PushStackMemory()
{
if (nsnull == mStackArena)
mStackArena = new StackArena();
return mStackArena->Push();
}
NS_IMETHODIMP
PresShell::PopStackMemory()
{
if (nsnull == mStackArena)
mStackArena = new StackArena();
return mStackArena->Pop();
}
NS_IMETHODIMP
PresShell::AllocateStackMemory(size_t aSize, void** aResult)
{
if (nsnull == mStackArena)
mStackArena = new StackArena();
return mStackArena->Allocate(aSize, aResult);
}
void
PresShell::FreeDynamicStack()
{
if (mStackArena) {
delete mStackArena;
mStackArena = nsnull;
}
}
NS_IMETHODIMP
PresShell::FreeFrame(size_t aSize, void* aPtr)
{
@@ -2138,6 +2354,9 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible)
MOZ_TIMER_DEBUGLOG(("Stop: Reflow: PresShell::ProcessReflowCommands(), this=%p\n", this));
MOZ_TIMER_STOP(mReflowWatch);
// if we allocated any stack memory during reflow free it.
//FreeDynamicStack();
return NS_OK;
}

View File

@@ -110,6 +110,11 @@ public:
NS_IMETHOD AllocateFrame(size_t aSize, void** aResult) = 0;
NS_IMETHOD FreeFrame(size_t aSize, void* aFreeChunk) = 0;
// Dynamic stack memory allocation
NS_IMETHOD PushStackMemory() = 0;
NS_IMETHOD PopStackMemory() = 0;
NS_IMETHOD AllocateStackMemory(size_t aSize, void** aResult) = 0;
NS_IMETHOD GetDocument(nsIDocument** aResult) = 0;
NS_IMETHOD GetPresContext(nsIPresContext** aResult) = 0;

File diff suppressed because it is too large Load Diff

View File

@@ -19,12 +19,12 @@
*
* Contributor(s):
*/
#ifndef nsScrollFrame_h___
#define nsScrollFrame_h___
#ifndef nsGfxScrollFrame_h___
#define nsGfxScrollFrame_h___
#include "nsHTMLContainerFrame.h"
#include "nsIAnonymousContentCreator.h"
#include "nsIBox.h"
#include "nsBoxFrame.h"
#include "nsIScrollableFrame.h"
class nsISupportsArray;
@@ -39,13 +39,12 @@ class nsGfxScrollFrameInner;
* Scroll frames don't support incremental changes, i.e. you can't replace
* or remove the scrolled frame
*/
class nsGfxScrollFrame : public nsHTMLContainerFrame,
public nsIAnonymousContentCreator,
public nsIBox,
class nsGfxScrollFrame : public nsIAnonymousContentCreator,
public nsBoxFrame,
public nsIScrollableFrame {
public:
friend nsresult NS_NewGfxScrollFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame,
nsIDocument* aDocument);
nsIDocument* aDocument, PRBool aIsRoot);
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,
@@ -53,8 +52,6 @@ public:
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug);
virtual ~nsGfxScrollFrame();
@@ -85,13 +82,6 @@ public:
nsIAtom* aListName,
nsIFrame* aOldFrame);
NS_IMETHOD DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus);
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@@ -105,18 +95,18 @@ public:
PRInt32& aContentOffsetEnd,
PRBool& aBeginFrameContent);
NS_IMETHOD ReflowDirtyChild(nsIPresShell* aPresShell, nsIFrame* aChild);
// nsIAnonymousContentCreator
NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext,
nsISupportsArray& aAnonymousItems);
// nsIBox methods
NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize);
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_IMETHOD_(nsrefcnt) AddRef(void) { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release(void) { return NS_OK; }
NS_IMETHOD InvalidateCache(nsIFrame* aChild);
NS_DECL_ISUPPORTS
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD GetPadding(nsMargin& aPadding);
// nsIScrollableFrame
NS_IMETHOD SetScrolledFrame(nsIPresContext* aPresContext, nsIFrame *aScrolledFrame);
@@ -138,8 +128,10 @@ public:
NS_IMETHOD GetFrameName(nsString& aResult) const;
#endif
virtual nsresult GetContentOf(nsIContent** aContent);
protected:
nsGfxScrollFrame(nsIDocument* aDocument);
nsGfxScrollFrame(nsIPresShell* aShell, nsIDocument* aDocument, PRBool aIsRoot);
virtual PRIntn GetSkipSides() const;
private:

File diff suppressed because it is too large Load Diff

View File

@@ -19,12 +19,12 @@
*
* Contributor(s):
*/
#ifndef nsScrollFrame_h___
#define nsScrollFrame_h___
#ifndef nsGfxScrollFrame_h___
#define nsGfxScrollFrame_h___
#include "nsHTMLContainerFrame.h"
#include "nsIAnonymousContentCreator.h"
#include "nsIBox.h"
#include "nsBoxFrame.h"
#include "nsIScrollableFrame.h"
class nsISupportsArray;
@@ -39,13 +39,12 @@ class nsGfxScrollFrameInner;
* Scroll frames don't support incremental changes, i.e. you can't replace
* or remove the scrolled frame
*/
class nsGfxScrollFrame : public nsHTMLContainerFrame,
public nsIAnonymousContentCreator,
public nsIBox,
class nsGfxScrollFrame : public nsIAnonymousContentCreator,
public nsBoxFrame,
public nsIScrollableFrame {
public:
friend nsresult NS_NewGfxScrollFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame,
nsIDocument* aDocument);
nsIDocument* aDocument, PRBool aIsRoot);
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,
@@ -53,8 +52,6 @@ public:
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug);
virtual ~nsGfxScrollFrame();
@@ -85,13 +82,6 @@ public:
nsIAtom* aListName,
nsIFrame* aOldFrame);
NS_IMETHOD DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus);
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@@ -105,18 +95,18 @@ public:
PRInt32& aContentOffsetEnd,
PRBool& aBeginFrameContent);
NS_IMETHOD ReflowDirtyChild(nsIPresShell* aPresShell, nsIFrame* aChild);
// nsIAnonymousContentCreator
NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext,
nsISupportsArray& aAnonymousItems);
// nsIBox methods
NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize);
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_IMETHOD_(nsrefcnt) AddRef(void) { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release(void) { return NS_OK; }
NS_IMETHOD InvalidateCache(nsIFrame* aChild);
NS_DECL_ISUPPORTS
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD GetPadding(nsMargin& aPadding);
// nsIScrollableFrame
NS_IMETHOD SetScrolledFrame(nsIPresContext* aPresContext, nsIFrame *aScrolledFrame);
@@ -138,8 +128,10 @@ public:
NS_IMETHOD GetFrameName(nsString& aResult) const;
#endif
virtual nsresult GetContentOf(nsIContent** aContent);
protected:
nsGfxScrollFrame(nsIDocument* aDocument);
nsGfxScrollFrame(nsIPresShell* aShell, nsIDocument* aDocument, PRBool aIsRoot);
virtual PRIntn GetSkipSides() const;
private:

View File

@@ -147,7 +147,7 @@ static NS_DEFINE_CID(kCXIFConverterCID, NS_XIFFORMATCONVERTER_CID);
static PRInt32 gMaxRCProcessingTime = -1;
// Largest chunk size we recycle
static const size_t gMaxRecycledSize = 300;
static const size_t gMaxRecycledSize = 400;
// Flag for enabling/disabling asynchronous reflow
// Set via the "layout.reflow.async" pref
@@ -157,6 +157,173 @@ static PRBool gDoAsyncReflow = PR_FALSE;
// Set via the "layout.reflow.async.afterDocLoad" pref
static PRBool gDoAsyncReflowAfterDocLoad = PR_FALSE;
#define MARK_INCREMENT 50
#define BLOCK_INCREMENT 2048
/**A block of memory that the stack will
* chop up and hand out
*/
struct StackBlock {
// a block of memory
void* mBlock;
// another block of memory that would only be created
// if our stack overflowed. Yes we have the ability
// to grow on a stack overflow
StackBlock* mNext;
StackBlock()
{
mBlock = new char*[BLOCK_INCREMENT];
mNext = nsnull;
}
~StackBlock()
{
delete[] mBlock;
}
};
/* we hold an array of marks. A push pushes a mark on the stack
* a pop pops it off.
*/
struct StackMark {
// the block of memory we are currently handing out chunks of
StackBlock* mBlock;
// our current position in the memory
size_t mPos;
};
/* A stack arena allows a stack based interface to a block of memory.
* It should be used when you need to allocate some temporary memory that
* you will immediately return.
*/
class StackArena {
public:
StackArena();
~StackArena();
// Memory management functions
nsresult Allocate(size_t aSize, void** aResult);
nsresult Push();
nsresult Pop();
private:
// our current position in memory
size_t mPos;
// a list of memory block. Usually there is only one
// but if we overrun our stack size we can get more memory.
StackBlock* mBlocks;
// the current block of memory we are passing our chucks of
StackBlock* mCurBlock;
// our stack of mark where push has been called
StackMark* mMarks;
// the current top of the the mark list
PRUint32 mStackTop;
// the size of the mark array
PRUint32 mMarkLength;
};
StackArena::StackArena()
{
// allocate the marks array
mMarkLength = MARK_INCREMENT;
mMarks = new StackMark[mMarkLength];
// allocate our stack memory
mBlocks = new StackBlock();
mCurBlock = mBlocks;
mStackTop = 0;
mPos = 0;
}
StackArena::~StackArena()
{
// free up our data
delete[] mMarks;
while(mBlocks)
{
StackBlock* toDelete = mBlocks;
mBlocks = mBlocks->mNext;
delete toDelete;
}
}
nsresult
StackArena::Push()
{
// if the we overrun our mark array. Resize it.
if (mStackTop + 1 >= mMarkLength)
{
StackMark* oldMarks = mMarks;
PRUint32 oldLength = mMarkLength;
mMarkLength += MARK_INCREMENT;
void* marks = 0;
mMarks = new StackMark[mMarkLength];
nsCRT::memcpy(mMarks, oldMarks, sizeof(StackMark)*oldLength);
delete[] oldMarks;
}
// set a mark at the top
mMarks[mStackTop].mBlock = mCurBlock;
mMarks[mStackTop].mPos = mPos;
mStackTop++;
return NS_OK;
}
nsresult
StackArena::Allocate(size_t aSize, void** aResult)
{
NS_ASSERTION(mStackTop > 0, "Error allocate called before push!!!");
// make sure we are aligned. Beard said 8 was safer then 4.
// Round size to multiple of 8
aSize = PR_ROUNDUP(aSize, 8);
// if the size makes the stack overflow. Grab another block for the stack
if (mPos + aSize >= BLOCK_INCREMENT)
{
NS_ASSERTION(aSize <= BLOCK_INCREMENT,"Requested memory is greater that our block size!!");
if (mCurBlock->mNext == nsnull)
mCurBlock->mNext = new StackBlock();
mCurBlock = mCurBlock->mNext;
mPos = 0;
}
// return the chunk they need.
*aResult = ((char*)mCurBlock->mBlock) + mPos;
mPos += aSize;
return NS_OK;
}
nsresult
StackArena::Pop()
{
// pop off the mark
NS_ASSERTION(mStackTop > 0, "Error Pop called 1 too many times");
mStackTop--;
mCurBlock = mMarks[mStackTop].mBlock;
mPos = mMarks[mStackTop].mPos;
return NS_OK;
}
// Memory is allocated 4-byte aligned. We have recyclers for chunks up to
// 200 bytes
class FrameArena {
@@ -310,6 +477,11 @@ public:
NS_IMETHOD AllocateFrame(size_t aSize, void** aResult);
NS_IMETHOD FreeFrame(size_t aSize, void* aFreeChunk);
// Dynamic stack memory allocation
NS_IMETHOD PushStackMemory();
NS_IMETHOD PopStackMemory();
NS_IMETHOD AllocateStackMemory(size_t aSize, void** aResult);
NS_IMETHOD GetDocument(nsIDocument** aResult);
NS_IMETHOD GetPresContext(nsIPresContext** aResult);
NS_IMETHOD GetViewManager(nsIViewManager** aResult);
@@ -522,6 +694,7 @@ protected:
PRBool mPendingReflowEvent;
nsCOMPtr<nsIEventQueue> mEventQueue;
FrameArena mFrameArena;
StackArena* mStackArena;
PRInt32 mAccumulatedReflowTime; // Time spent in reflow command processing so far
PRPackedBool mDocumentIsLoading; // A flag that is true while the document is loading.
PRPackedBool mBatchReflows; // When set to true, the pres shell batches reflow commands.
@@ -540,6 +713,8 @@ protected:
private:
void FreeDynamicStack();
//helper funcs for disabing autoscrolling
void DisableScrolling(){mScrollingEnabled = PR_FALSE;}
void EnableScrolling(){mScrollingEnabled = PR_TRUE;}
@@ -650,7 +825,7 @@ NS_NewPresShell(nsIPresShell** aInstancePtrResult)
(void **) aInstancePtrResult);
}
PresShell::PresShell()
PresShell::PresShell():mStackArena(nsnull)
{
NS_INIT_REFCNT();
mIsDestroying = PR_FALSE;
@@ -718,6 +893,9 @@ PresShell::QueryInterface(const nsIID& aIID, void** aInstancePtr)
PresShell::~PresShell()
{
// if we allocated any stack memory free it.
FreeDynamicStack();
mRefCnt = 99;/* XXX hack! get around re-entrancy bugs */
mIsDestroying = PR_TRUE;
@@ -873,6 +1051,44 @@ PresShell::Init(nsIDocument* aDocument,
return NS_OK;
}
// Dynamic stack memory allocation
NS_IMETHODIMP
PresShell::PushStackMemory()
{
if (nsnull == mStackArena)
mStackArena = new StackArena();
return mStackArena->Push();
}
NS_IMETHODIMP
PresShell::PopStackMemory()
{
if (nsnull == mStackArena)
mStackArena = new StackArena();
return mStackArena->Pop();
}
NS_IMETHODIMP
PresShell::AllocateStackMemory(size_t aSize, void** aResult)
{
if (nsnull == mStackArena)
mStackArena = new StackArena();
return mStackArena->Allocate(aSize, aResult);
}
void
PresShell::FreeDynamicStack()
{
if (mStackArena) {
delete mStackArena;
mStackArena = nsnull;
}
}
NS_IMETHODIMP
PresShell::FreeFrame(size_t aSize, void* aPtr)
{
@@ -2138,6 +2354,9 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible)
MOZ_TIMER_DEBUGLOG(("Stop: Reflow: PresShell::ProcessReflowCommands(), this=%p\n", this));
MOZ_TIMER_STOP(mReflowWatch);
// if we allocated any stack memory during reflow free it.
//FreeDynamicStack();
return NS_OK;
}

View File

@@ -38,6 +38,8 @@
#include "nsScrollPortFrame.h"
#include "nsLayoutAtoms.h"
#include "nsIBox.h"
#include "nsBoxLayoutState.h"
#include "nsIBoxToBlockAdaptor.h"
/*
@@ -68,7 +70,7 @@ NS_NewScrollPortFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsScrollPortFrame* it = new (aPresShell) nsScrollPortFrame;
nsScrollPortFrame* it = new (aPresShell) nsScrollPortFrame (aPresShell);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
@@ -76,28 +78,8 @@ NS_NewScrollPortFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
return NS_OK;
}
NS_IMETHODIMP
nsScrollPortFrame::SetDebug(nsIPresContext* aPresContext, PRBool aDebug)
nsScrollPortFrame::nsScrollPortFrame(nsIPresShell* aShell):nsBoxFrame(aShell)
{
nsIFrame* kid = mFrames.FirstChild();
while (nsnull != kid) {
nsIBox* ibox = nsnull;
if (NS_SUCCEEDED(kid->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox) {
ibox->SetDebug(aPresContext, aDebug);
}
kid->GetNextSibling(&kid);
}
mNeedsRecalc = PR_TRUE;
return NS_OK;
}
nsScrollPortFrame::nsScrollPortFrame()
{
//mIncremental = PR_FALSE;
mNeedsRecalc = PR_TRUE;
}
NS_IMETHODIMP
@@ -107,7 +89,7 @@ nsScrollPortFrame::Init(nsIPresContext* aPresContext,
nsIStyleContext* aStyleContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsHTMLContainerFrame::Init(aPresContext, aContent,
nsresult rv = nsBoxFrame::Init(aPresContext, aContent,
aParent, aStyleContext,
aPrevInFlow);
@@ -121,7 +103,7 @@ nsScrollPortFrame::SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
nsresult rv = nsHTMLContainerFrame::SetInitialChildList(aPresContext, aListName,
nsresult rv = nsBoxFrame::SetInitialChildList(aPresContext, aListName,
aChildList);
nsIFrame* frame = mFrames.FirstChild();
@@ -180,29 +162,6 @@ nsScrollPortFrame::RemoveFrame(nsIPresContext* aPresContext,
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsScrollPortFrame::DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus)
{
nsresult rv = NS_OK;
if (NS_FRAME_REFLOW_FINISHED == aStatus) {
// Let the default nsFrame implementation clear the state flags
// and size and position our view
rv = nsFrame::DidReflow(aPresContext, aStatus);
// Have the scrolling view layout
nsIScrollableView* scrollingView;
nsIView* view;
GetView(aPresContext, &view);
if (NS_SUCCEEDED(view->QueryInterface(kScrollViewIID, (void**)&scrollingView))) {
scrollingView->ComputeScrollOffsets(PR_TRUE);
}
}
return rv;
}
nsresult
nsScrollPortFrame::CreateScrollingViewWidget(nsIView* aView, const nsStylePosition* aPosition)
{
@@ -314,234 +273,127 @@ nsScrollPortFrame::CreateScrollingView(nsIPresContext* aPresContext)
return rv;
}
// Calculate the total amount of space needed for the child frame,
// including its child frames that stick outside its bounds and any
// absolutely positioned child frames.
// Updates the width/height members of the reflow metrics
nsresult
nsScrollPortFrame::CalculateChildTotalSize(nsIFrame* aKidFrame,
nsHTMLReflowMetrics& aKidReflowMetrics)
NS_IMETHODIMP
nsScrollPortFrame::GetMargin(nsMargin& aMargin)
{
// If the frame has child frames that stick outside its bounds, then take
// them into account, too
nsFrameState kidState;
aKidFrame->GetFrameState(&kidState);
if (NS_FRAME_OUTSIDE_CHILDREN & kidState) {
aKidReflowMetrics.width = aKidReflowMetrics.mOverflowArea.width;
aKidReflowMetrics.height = aKidReflowMetrics.mOverflowArea.height;
}
aMargin.SizeTo(0,0,0,0);
return NS_OK;
}
NS_IMETHODIMP
nsScrollPortFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
nsScrollPortFrame::GetPadding(nsMargin& aMargin)
{
NS_FRAME_TRACE_MSG(NS_FRAME_TRACE_CALLS,
("enter nsScrollPortFrame::Reflow: maxSize=%d,%d",
aReflowState.availableWidth,
aReflowState.availableHeight));
// if we have any padding then ignore it. It is inherited down to our scrolled frame
if (aReflowState.mComputedPadding.left != 0 ||
aReflowState.mComputedPadding.right != 0 ||
aReflowState.mComputedPadding.top != 0 ||
aReflowState.mComputedPadding.bottom != 0)
{
nsHTMLReflowState newState(aReflowState);
// get the padding to remove
nscoord pwidth = (newState.mComputedPadding.left + newState.mComputedPadding.right);
nscoord pheight = (newState.mComputedPadding.top + newState.mComputedPadding.bottom);
// adjust our computed size to add in the padding we are removing. Make sure
// the computed size doesn't go negative or anything.
if (newState.mComputedWidth != NS_INTRINSICSIZE)
newState.mComputedWidth += pwidth;
if (newState.mComputedHeight != NS_INTRINSICSIZE)
newState.mComputedHeight += pheight;
// fix up the borderpadding
((nsMargin&)newState.mComputedBorderPadding) -= newState.mComputedPadding;
// remove the padding
((nsMargin&)newState.mComputedPadding) = nsMargin(0,0,0,0);
// reflow us again with the correct values.
return Reflow(aPresContext, aDesiredSize, newState, aStatus);
}
// Handle Incremental Reflow
nsIFrame* incrementalChild = nsnull;
if ( aReflowState.reason == eReflowReason_Incremental ) {
nsIReflowCommand::ReflowType reflowType;
aReflowState.reflowCommand->GetType(reflowType);
// See if it's targeted at us
nsIFrame* targetFrame;
aReflowState.reflowCommand->GetTarget(targetFrame);
if (this == targetFrame) {
// if we are the target see what the type was
// and generate a normal non incremental reflow.
switch (reflowType) {
case nsIReflowCommand::StyleChanged:
{
nsHTMLReflowState newState(aReflowState);
newState.reason = eReflowReason_StyleChange;
return Reflow(aPresContext, aDesiredSize, newState, aStatus);
}
break;
// if its a dirty type then reflow us with a dirty reflow
case nsIReflowCommand::ReflowDirty:
{
nsHTMLReflowState newState(aReflowState);
newState.reason = eReflowReason_Dirty;
return Reflow(aPresContext, aDesiredSize, newState, aStatus);
}
break;
default:
NS_ASSERTION(PR_FALSE, "unexpected reflow command type");
}
}
// then get the child we need to flow incrementally
aReflowState.reflowCommand->GetNext(incrementalChild);
}
nsIFrame* kidFrame = mFrames.FirstChild();
// Reflow the child and get its desired size. Let it be as high as it
// wants
const nsMargin& border = aReflowState.mComputedBorderPadding;
/*
// we only worry about our border. Out scrolled frame worries about the padding.
// so lets remove the padding and add it to our computed size.
nsMargin padding = aReflowState.mComputedPadding;
if (aReflowState.mComputedWidth != NS_INTRINSICSIZE)
((nscoord&)aReflowState.mComputedWidth) += padding.left + padding.right;
if (aReflowState.mComputedHeight != NS_INTRINSICSIZE)
((nscoord&)aReflowState.mComputedHeight) += padding.top + padding.bottom;
((nsMargin&)aReflowState.mComputedPadding) = nsMargin(0,0,0,0);
((nsMargin&)aReflowState.mComputedBorderPadding) -= padding;
*/
nscoord theHeight;
nsIBox* box;
nsReflowReason reason = aReflowState.reason;
nsresult result = kidFrame->QueryInterface(NS_GET_IID(nsIBox), (void**)&box);
if (NS_SUCCEEDED(result))
theHeight = aReflowState.mComputedHeight;
else {
theHeight = NS_INTRINSICSIZE;
// html can't handle a reflow of dirty. Convert it to
// a resize reflow
if (reason == eReflowReason_Dirty)
reason = eReflowReason_Resize;
}
nsSize kidReflowSize(aReflowState.availableWidth, theHeight);
nsHTMLReflowState kidReflowState(aPresContext, aReflowState,
kidFrame, kidReflowSize);
nsHTMLReflowMetrics kidDesiredSize(aDesiredSize.maxElementSize);
kidReflowState.mComputedWidth = aReflowState.mComputedWidth;
kidReflowState.mComputedHeight = theHeight;
kidReflowState.reason = reason;
nscoord pwidth = (kidReflowState.mComputedBorderPadding.left + kidReflowState.mComputedBorderPadding.right);
nscoord pheight = (kidReflowState.mComputedBorderPadding.top + kidReflowState.mComputedBorderPadding.bottom);
// child's size is our computed size minus its border and padding.
if (kidReflowState.mComputedWidth != NS_INTRINSICSIZE && kidReflowState.mComputedWidth >= pwidth)
kidReflowState.mComputedWidth -= pwidth;
if (kidReflowState.mComputedHeight != NS_INTRINSICSIZE && kidReflowState.mComputedHeight >= pheight)
kidReflowState.mComputedHeight -= pheight;
// reflow and place the child.
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
border.left, border.top, NS_FRAME_NO_MOVE_VIEW, aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
CalculateChildTotalSize(kidFrame, kidDesiredSize);
// Place and size the child.
nscoord x = border.left;
nscoord y = border.top;
// Compute our desired size
if (aReflowState.mComputedWidth == NS_INTRINSICSIZE)
aDesiredSize.width = kidDesiredSize.width;
else
aDesiredSize.width = aReflowState.mComputedWidth;
if (aDesiredSize.width > kidDesiredSize.width)
kidDesiredSize.width = aDesiredSize.width;
aDesiredSize.width += border.left + border.right;
// Compute our desired size
if (aReflowState.mComputedHeight == NS_INTRINSICSIZE)
aDesiredSize.height = kidDesiredSize.height;
else
aDesiredSize.height = aReflowState.mComputedHeight;
if (aDesiredSize.height > kidDesiredSize.height)
kidDesiredSize.height = aDesiredSize.height;
aDesiredSize.height += border.top + border.bottom;
FinishReflowChild(kidFrame, aPresContext, kidDesiredSize, x, y, NS_FRAME_NO_MOVE_VIEW);
//printf("width=%d, height=%d\n", kidDesiredSize.width, kidDesiredSize.height);
if (nsnull != aDesiredSize.maxElementSize) {
// nscoord maxWidth = aDesiredSize.maxElementSize->width;
// maxWidth += aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right;
// nscoord maxHeight = aDesiredSize.maxElementSize->height;
// maxHeight += aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom;
// aDesiredSize.maxElementSize->width = maxWidth;
// aDesiredSize.maxElementSize->height = maxHeight;
*aDesiredSize.maxElementSize = *kidDesiredSize.maxElementSize;
}
//mIncremental = PR_FALSE;
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
/*
if (aReflowState.mComputedWidth != NS_INTRINSICSIZE)
((nscoord&)aReflowState.mComputedWidth) -= (padding.left + padding.right);
if (aReflowState.mComputedHeight != NS_INTRINSICSIZE)
((nscoord&)aReflowState.mComputedHeight) -= (padding.top + padding.bottom);
((nsMargin&)aReflowState.mComputedPadding) = padding;
((nsMargin&)aReflowState.mComputedBorderPadding) += padding;
*/
NS_FRAME_TRACE_MSG(NS_FRAME_TRACE_CALLS,
("exit nsScrollPortFrame::Reflow: status=%d width=%d height=%d",
aStatus, aDesiredSize.width, aDesiredSize.height));
aMargin.SizeTo(0,0,0,0);
return NS_OK;
}
NS_IMETHODIMP
nsScrollPortFrame::GetBorder(nsMargin& aMargin)
{
aMargin.SizeTo(0,0,0,0);
return NS_OK;
}
NS_IMETHODIMP
nsScrollPortFrame::Layout(nsBoxLayoutState& aState)
{
nsRect clientRect(0,0,0,0);
GetClientRect(clientRect);
nsIBox* kid = nsnull;
GetChildBox(&kid);
nsRect childRect(clientRect);
nsMargin margin(0,0,0,0);
kid->GetMargin(margin);
childRect.Deflate(margin);
nsSize min(0,0);
kid->GetMinSize(aState, min);
/*
// if our child is not html then get is min size
// and make sure we don't squeeze it smaller than that.
nsIBoxToBlockAdaptor* adaptor = nsnull;
if (NS_FAILED(kid->QueryInterface(NS_GET_IID(nsIBoxToBlockAdaptor), (void**)&adaptor))) {
if (min.height > childRect.height)
childRect.height = min.height;
}
*/
if (min.height > childRect.height)
childRect.height = min.height;
if (min.width > childRect.width)
childRect.width = min.width;
kid->SetBounds(aState, childRect);
kid->Layout(aState);
kid->GetBounds(childRect);
clientRect.Inflate(margin);
if (childRect.width < clientRect.width || childRect.height < childRect.height)
{
if (childRect.width < clientRect.width)
childRect.width = clientRect.width;
if (childRect.height < clientRect.height)
childRect.height = clientRect.height;
clientRect.Deflate(margin);
kid->SetBounds(aState, childRect);
}
SyncLayout(aState);
nsIPresContext* presContext = aState.GetPresContext();
nsIScrollableView* scrollingView;
nsIView* view;
GetView(presContext, &view);
if (NS_SUCCEEDED(view->QueryInterface(kScrollViewIID, (void**)&scrollingView))) {
scrollingView->ComputeScrollOffsets(PR_TRUE);
}
return NS_OK;
}
NS_IMETHODIMP
nsScrollPortFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
nsIBox* child = nsnull;
GetChildBox(&child);
nsresult rv = child->GetPrefSize(aBoxLayoutState, aSize);
AddMargin(child, aSize);
AddBorderAndPadding(aSize);
AddInset(aSize);
nsIBox::AddCSSPrefSize(aBoxLayoutState, this, aSize);
return rv;
}
NS_IMETHODIMP
nsScrollPortFrame::GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
nsIBox* child = nsnull;
GetChildBox(&child);
AddBorderAndPadding(aSize);
AddInset(aSize);
nsIBox::AddCSSMinSize(aBoxLayoutState, this, aSize);
return NS_OK;
}
NS_IMETHODIMP
nsScrollPortFrame::GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
nsIBox* child = nsnull;
GetChildBox(&child);
nsresult rv = child->GetMaxSize(aBoxLayoutState, aSize);
AddMargin(child, aSize);
AddBorderAndPadding(aSize);
AddInset(aSize);
nsIBox::AddCSSMaxSize(aBoxLayoutState, this, aSize);
return rv;
}
NS_IMETHODIMP
nsScrollPortFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@@ -565,7 +417,7 @@ nsScrollPortFrame::Paint(nsIPresContext* aPresContext,
}
// Paint our children
nsresult rv = nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect,
nsresult rv = nsBoxFrame::Paint(aPresContext, aRenderingContext, aDirtyRect,
aWhichLayer);
return rv;
@@ -577,6 +429,12 @@ nsScrollPortFrame::GetSkipSides() const
return 0;
}
nsresult
nsScrollPortFrame::GetContentOf(nsIContent** aContent)
{
return GetContent(aContent);
}
NS_IMETHODIMP
nsScrollPortFrame::GetFrameType(nsIAtom** aType) const
{
@@ -590,176 +448,26 @@ nsScrollPortFrame::GetFrameType(nsIAtom** aType) const
NS_IMETHODIMP
nsScrollPortFrame::GetFrameName(nsString& aResult) const
{
return MakeFrameName("Scroll", aResult);
return MakeFrameName("ScrollPort", aResult);
}
#endif
NS_IMETHODIMP
nsScrollPortFrame::InvalidateCache(nsIFrame* aChild)
NS_IMETHODIMP_(nsrefcnt)
nsScrollPortFrame::AddRef(void)
{
mNeedsRecalc = PR_TRUE;
return NS_OK;
}
/**
* Goes though each child asking for its size to determine our size. Returns our box size minus our border.
* This method is defined in nsIBox interface.
*/
NS_IMETHODIMP
nsScrollPortFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize)
NS_IMETHODIMP_(nsrefcnt)
nsScrollPortFrame::Release(void)
{
nsresult rv;
aSize.Clear();
nsIFrame* childFrame = mFrames.FirstChild();
// if incremental see if the next in chain is our child. Remove it if it is
// and make sure we pass it down.
if (aReflowState.reason == eReflowReason_Incremental)
{
nsIFrame* incrementalChild = nsnull;
aReflowState.reflowCommand->GetNext(incrementalChild, PR_FALSE);
if (incrementalChild == childFrame) {
aReflowState.reflowCommand->GetNext(incrementalChild);
mNeedsRecalc = PR_TRUE;
}
}
if (mNeedsRecalc) {
// get the size of the child. This is the min, max, preferred, and spring constant
// it does not include its border.
rv = GetChildBoxInfo(aPresContext, aReflowState, childFrame, mSpring);
NS_ASSERTION(rv == NS_OK,"failed to child box info");
if (NS_FAILED(rv))
return rv;
// add in the child's margin and border/padding if there is one.
const nsStyleSpacing* spacing;
rv = childFrame->GetStyleData(eStyleStruct_Spacing,
(const nsStyleStruct*&) spacing);
NS_ASSERTION(rv == NS_OK,"failed to get spacing info");
if (NS_FAILED(rv))
return rv;
nsMargin margin(0,0,0,0);
spacing->GetMargin(margin);
nsSize m(margin.left+margin.right,margin.top+margin.bottom);
mSpring.minSize += m;
mSpring.prefSize += m;
if (mSpring.maxSize.width != NS_INTRINSICSIZE)
mSpring.maxSize.width += m.width;
if (mSpring.maxSize.height != NS_INTRINSICSIZE)
mSpring.maxSize.height += m.height;
spacing->GetBorderPadding(margin);
nsSize b(margin.left+margin.right,margin.top+margin.bottom);
mSpring.minSize += b;
mSpring.prefSize += b;
if (mSpring.maxSize.width != NS_INTRINSICSIZE)
mSpring.maxSize.width += b.width;
if (mSpring.maxSize.height != NS_INTRINSICSIZE)
mSpring.maxSize.height += b.height;
// ok we don't need to calc this guy again
mNeedsRecalc = PR_FALSE;
}
aSize = mSpring;
return rv;
}
nsresult
nsScrollPortFrame::GetChildBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsIFrame* aFrame, nsBoxInfo& aSize)
{
aSize.Clear();
// see if the frame has IBox interface
// if it does ask it for its BoxSize and we are done
nsIBox* ibox;
if (NS_SUCCEEDED(aFrame->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox) {
ibox->GetBoxInfo(aPresContext, aReflowState, aSize);
return NS_OK;
}
// start the preferred size as intrinsic
aSize.prefSize.width = NS_INTRINSICSIZE;
aSize.prefSize.height = NS_INTRINSICSIZE;
nsSize kidReflowSize(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
nsHTMLReflowState kidReflowState(aPresContext, aReflowState,
aFrame, kidReflowSize);
nsHTMLReflowMetrics kidDesiredSize(nsnull);
kidReflowState.reason = eReflowReason_Resize;
kidReflowState.mComputedWidth = NS_INTRINSICSIZE;
kidReflowState.mComputedHeight = NS_INTRINSICSIZE;
nsReflowStatus status = NS_FRAME_COMPLETE;
ReflowChild(aFrame, aPresContext, kidDesiredSize, kidReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, status);
aFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "bad status");
const nsStyleSpacing* spacing;
nsresult rv = aFrame->GetStyleData(eStyleStruct_Spacing,
(const nsStyleStruct*&) spacing);
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get spacing");
if (NS_FAILED(rv))
return rv;
nsMargin border(0,0,0,0);;
spacing->GetBorderPadding(border);
// remove border
kidDesiredSize.width -= (border.left + border.right);
kidDesiredSize.height -= (border.top + border.bottom);
// get the size returned and the it as the preferredsize.
aSize.prefSize.width = kidDesiredSize.width;
aSize.prefSize.height = kidDesiredSize.height;
return NS_OK;
}
NS_IMETHODIMP
nsScrollPortFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
if (aIID.Equals(NS_GET_IID(nsIBox))) {
*aInstancePtr = (void*)(nsIBox*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
}
NS_IMETHODIMP
nsScrollPortFrame::ReflowDirtyChild(nsIPresShell* aPresShell, nsIFrame* aChild)
{
if (! (mState & NS_FRAME_IS_DIRTY)) {
mState |= NS_FRAME_IS_DIRTY;
return mParent->ReflowDirtyChild(aPresShell, aChild);
}
return NS_OK;
}
NS_INTERFACE_MAP_BEGIN(nsScrollPortFrame)
NS_INTERFACE_MAP_ENTRY(nsIBox)
#ifdef NS_DEBUG
NS_INTERFACE_MAP_ENTRY(nsIFrameDebug)
#endif
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIBox)
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)

View File

@@ -22,8 +22,7 @@
#ifndef nsScrollPortFrame_h___
#define nsScrollPortFrame_h___
#include "nsHTMLContainerFrame.h"
#include "nsIBox.h"
#include "nsBoxFrame.h"
/**
* The scroll frame creates and manages the scrolling view
@@ -34,7 +33,7 @@
* Scroll frames don't support incremental changes, i.e. you can't replace
* or remove the scrolled frame
*/
class nsScrollPortFrame : public nsHTMLContainerFrame, public nsIBox {
class nsScrollPortFrame : nsBoxFrame {
public:
friend nsresult NS_NewScrollPortFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
@@ -44,8 +43,6 @@ public:
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug);
// Called to set the one and only child frame. Returns NS_ERROR_INVALID_ARG
// if the child frame is NULL, and NS_ERROR_UNEXPECTED if the child list
// contains more than one frame
@@ -71,21 +68,12 @@ public:
nsIAtom* aListName,
nsIFrame* aOldFrame);
NS_IMETHOD DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus);
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
NS_IMETHOD ReflowDirtyChild(nsIPresShell* aPresShell, nsIFrame* aChild);
/**
* Get the "type" of the frame
*
@@ -98,14 +86,20 @@ public:
#endif
// nsIBox methods
NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize);
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_IMETHOD_(nsrefcnt) AddRef(void) { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release(void) { return NS_OK; }
NS_IMETHOD InvalidateCache(nsIFrame* aChild);
NS_DECL_ISUPPORTS
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD GetPadding(nsMargin& aMargin);
NS_IMETHOD GetBorder(nsMargin& aMargin);
NS_IMETHOD GetMargin(nsMargin& aMargin);
virtual nsresult GetContentOf(nsIContent** aContent);
protected:
nsScrollPortFrame();
nsScrollPortFrame(nsIPresShell* aShell);
virtual PRIntn GetSkipSides() const;
// Creation of the widget for the scrolling view is factored into a virtual method so
@@ -119,14 +113,6 @@ protected:
private:
nsresult CreateScrollingView(nsIPresContext* aPresContext);
nsresult CalculateChildTotalSize(nsIFrame* aKidFrame,
nsHTMLReflowMetrics& aKidReflowMetrics);
nsresult GetChildBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsIFrame* aFrame, nsBoxInfo& aSize);
PRBool mNeedsRecalc;
nsBoxInfo mSpring;
PRBool mIncremental;
};
#endif /* nsScrollPortFrame_h___ */

View File

@@ -120,7 +120,7 @@
#include "nsIDOMDocument.h"
#include "nsDocument.h"
#include "nsToolbarItemFrame.h"
#include "nsXULCheckboxFrame.h"
#include "nsCheckBoxFrame.h"
#include "nsIScrollable.h"
#ifdef DEBUG
@@ -132,8 +132,28 @@ static PRBool gNoisyInlineConstruction = PR_FALSE;
#define NEWGFX_LIST_SCROLLFRAME
//------------------------------------------------------------------
#ifdef NEWGFX_LIST_SCROLLFRAME
nsresult
NS_NewGfxListControlFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
#endif
// grid
/*
nsresult
NS_NewGridFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewTempleFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsHorizontal);
nsresult
NS_NewObeliskFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsHorizontal);
// end grid
*/
nsresult
NS_NewRootBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewThumbFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
@@ -142,7 +162,7 @@ nsresult
NS_NewScrollPortFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewGfxScrollFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, nsIDocument* aDocument );
NS_NewGfxScrollFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, nsIDocument* aDocument, PRBool aIsRoot);
nsresult
NS_NewTabFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
@@ -163,7 +183,10 @@ nsresult
NS_NewTitledButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewXULTextFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
NS_NewImageBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewTextBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewTitledBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
@@ -178,7 +201,7 @@ nsresult
NS_NewBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot);
nsresult
NS_NewXULButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_NewButtonBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame);
nsresult
NS_NewSliderFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
@@ -2359,6 +2382,7 @@ nsCSSFrameConstructor::TableIsValidCellContent(nsIPresContext* aPresContext,
#ifdef INCLUDE_XUL
if ( (nsXULAtoms::button == tag.get()) ||
(nsXULAtoms::titledbutton == tag.get()) ||
(nsXULAtoms::box == tag.get()) ||
(nsXULAtoms::image == tag.get()) ||
(nsXULAtoms::grippy == tag.get()) ||
(nsXULAtoms::splitter == tag.get()) ||
@@ -2603,6 +2627,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell,
aParentFrame,
nsLayoutAtoms::scrolledContentPseudo,
document,
PR_FALSE,
scrollFrame,
newContext,
newScrollFrame);
@@ -2837,7 +2862,15 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell,
nsIAtom* rootPseudo;
if (!isPaginated) {
PRInt32 nameSpaceID;
if (NS_SUCCEEDED(aDocElement->GetNameSpaceID(nameSpaceID)) &&
nameSpaceID == nsXULAtoms::nameSpaceID)
{
NS_NewRootBoxFrame(aPresShell, &rootFrame);
} else {
NS_NewRootFrame(aPresShell, &rootFrame);
}
rootPseudo = nsLayoutAtoms::canvasPseudo;
mDocElementContainingBlock = rootFrame;
} else {
@@ -2868,6 +2901,8 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell,
}
}
//isScrollable = PR_FALSE;
// As long as the webshell doesn't prohibit it, and the device supports
// it, create a scroll frame that will act as the scolling mechanism for
// the viewport.
@@ -2941,6 +2976,7 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell,
viewportFrame,
rootPseudo,
document,
PR_TRUE,
newFrame,
rootPseudoStyle,
newScrollableFrame);
@@ -4656,7 +4692,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
else if (aTag == nsXULAtoms::button) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewXULButtonFrame(aPresShell, &newFrame);
rv = NS_NewButtonBoxFrame(aPresShell, &newFrame);
const nsStyleDisplay* display = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);
@@ -4679,15 +4715,18 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
} // End of BUTTON CONSTRUCTION logic
// TITLED BUTTON CONSTRUCTION
else if (aTag == nsXULAtoms::titledbutton ||
aTag == nsXULAtoms::image) {
else if (aTag == nsXULAtoms::titledbutton) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewTitledButtonFrame(aPresShell, &newFrame);
}
// End of TITLED BUTTON CONSTRUCTION logic
else if (aTag == nsXULAtoms::image) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewImageBoxFrame(aPresShell, &newFrame);
}
else if (aTag == nsXULAtoms::spring) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
@@ -4699,7 +4738,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
else if (aTag == nsXULAtoms::text) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewXULTextFrame(aPresShell, &newFrame);
rv = NS_NewTextBoxFrame(aPresShell, &newFrame);
}
// End of TEXT CONSTRUCTION logic
@@ -4737,6 +4776,89 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
isReplaced = PR_TRUE;
rv = NS_NewMenuPopupFrame(aPresShell, &newFrame);
}
/*
// ------- Begin Grid ---------
else if (aTag == nsXULAtoms::grid) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewGridFrame(aPresShell, &newFrame);
const nsStyleDisplay* display = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);
// Boxes can scroll.
if (IsScrollable(aPresContext, display)) {
// set the top to be the newly created scrollframe
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
topFrame, aStyleContext);
// we have a scrollframe so the parent becomes the scroll frame.
newFrame->GetParent(&aParentFrame);
primaryFrameSet = PR_TRUE;
frameHasBeenInitialized = PR_TRUE;
}
} //------- End Grid ------
// ------- Begin Rows/Columns ---------
else if (aTag == nsXULAtoms::rows || aTag == nsXULAtoms::columns) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
PRBool isHorizontal = (aTag == nsXULAtoms::columns);
rv = NS_NewTempleFrame(aPresShell, &newFrame, isHorizontal);
const nsStyleDisplay* display = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);
// Boxes can scroll.
if (IsScrollable(aPresContext, display)) {
// set the top to be the newly created scrollframe
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
topFrame, aStyleContext);
// we have a scrollframe so the parent becomes the scroll frame.
newFrame->GetParent(&aParentFrame);
primaryFrameSet = PR_TRUE;
frameHasBeenInitialized = PR_TRUE;
}
} //------- End Grid ------
// ------- Begin Row/Column ---------
else if (aTag == nsXULAtoms::row || aTag == nsXULAtoms::column) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
PRBool isHorizontal = (aTag == nsXULAtoms::row);
rv = NS_NewObeliskFrame(aPresShell, &newFrame, isHorizontal);
const nsStyleDisplay* display = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);
// Boxes can scroll.
if (IsScrollable(aPresContext, display)) {
// set the top to be the newly created scrollframe
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
topFrame, aStyleContext);
// we have a scrollframe so the parent becomes the scroll frame.
newFrame->GetParent(&aParentFrame);
primaryFrameSet = PR_TRUE;
frameHasBeenInitialized = PR_TRUE;
}
} //------- End Grid ------
*/
else if (aTag == nsXULAtoms::title) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
@@ -4949,7 +5071,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
aTag == nsXULAtoms::radio) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewXULCheckboxFrame(aPresShell, &newFrame);
rv = NS_NewCheckBoxFrame(aPresShell, &newFrame);
}
// End of XULCHECKBOX CONSTRUCTION logic
@@ -5123,6 +5245,7 @@ nsCSSFrameConstructor::BeginBuildingScrollFrame(nsIPresShell* aPresShell,
nsIFrame* aParentFrame,
nsIAtom* aScrolledPseudo,
nsIDocument* aDocument,
PRBool aIsRoot,
nsIFrame*& aNewFrame,
nsCOMPtr<nsIStyleContext>& aScrolledChildStyle,
nsIFrame*& aScrollableFrame)
@@ -5140,7 +5263,7 @@ nsCSSFrameConstructor::BeginBuildingScrollFrame(nsIPresShell* aPresShell,
if (isGfx) {
BuildGfxScrollFrame(aPresShell, aPresContext, aState, aContent, aDocument, aParentFrame,
contentStyle, gfxScrollFrame, anonymousItems);
contentStyle, aIsRoot, gfxScrollFrame, anonymousItems);
scrollFrame = anonymousItems.childList;
parentFrame = gfxScrollFrame;
@@ -5283,6 +5406,7 @@ nsCSSFrameConstructor::BuildScrollFrame (nsIPresShell* aPresShell,
aParentFrame,
nsLayoutAtoms::scrolledContentPseudo,
document,
PR_FALSE,
aNewFrame,
scrolledContentStyle,
scrollFrame);
@@ -5317,10 +5441,11 @@ nsCSSFrameConstructor::BuildGfxScrollFrame (nsIPresShell* aPresShell,
nsIDocument* aDocument,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
PRBool aIsRoot,
nsIFrame*& aNewFrame,
nsFrameItems& aAnonymousFrames)
{
NS_NewGfxScrollFrame(aPresShell, &aNewFrame,aDocument);
NS_NewGfxScrollFrame(aPresShell, &aNewFrame, aDocument, aIsRoot);
InitAndRestoreFrame(aPresContext, aState, aContent,
aParentFrame, aStyleContext, nsnull, aNewFrame);
@@ -7074,6 +7199,28 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
} else {
// Find the frame that precedes the insertion point.
nsIFrame* prevSibling = FindPreviousSibling(shell, aContainer, aIndexInContainer);
/*
if (prevSibling) {
nsIFrame* parent;
prevSibling->GetParent(&parent);
nsIFrame* first;
parent->FirstChild(aPresContext, nsnull, &first);
PRBool found = PR_FALSE;
while(first)
{
if (first == prevSibling) {
found = PR_TRUE;
break;
}
first->GetNextSibling(&first);
}
NS_ASSERTION(found,"Error sibling not in parent!!!!!");
}
*/
nsIFrame* nextSibling = nsnull;
PRBool isAppend = PR_FALSE;

View File

@@ -646,6 +646,7 @@ protected:
nsIFrame* aParentFrame,
nsIAtom* aScrolledPseudo,
nsIDocument* aDocument,
PRBool aIsRoot,
nsIFrame*& aNewFrame,
nsCOMPtr<nsIStyleContext>& aScrolledChildStyle,
nsIFrame*& aScrollableFrame);
@@ -671,6 +672,7 @@ protected:
nsIDocument* aDocument,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
PRBool aIsRoot,
nsIFrame*& aNewFrame,
nsFrameItems& aAnonymousFrames);

Binary file not shown.

View File

@@ -30,11 +30,21 @@ MODULE = layout
LIBRARY_NAME = raptorxulbase_s
CPPSRCS = \
nsXULButtonFrame.cpp \
nsImageBoxFrame.cpp \
nsRootBoxFrame.cpp \
nsBox.cpp \
nsBoxLayoutState.cpp \
nsBoxToBlockAdaptor.cpp \
nsButtonBoxFrame.cpp \
nsCheckBoxFrame.cpp \
nsContainerBox.cpp \
nsLeafBoxFrame.cpp \
nsSprocketLayout.cpp \
nsBoxLayout.cpp \
nsStackLayout.cpp \
nsTextBoxFrame.cpp \
nsStackFrame.cpp \
nsSpringFrame.cpp \
nsXULLeafFrame.cpp \
nsXULTextFrame.cpp \
nsTitledBoxFrame.cpp \
nsTitleFrame.cpp \
nsFrameNavigator.cpp \
@@ -72,7 +82,6 @@ CPPSRCS = \
nsMenuDismissalListener.cpp \
nsPopupSetFrame.cpp \
nsRepeatService.cpp \
nsXULCheckboxFrame.cpp \
$(NULL)
include $(topsrcdir)/config/config.mk

View File

@@ -28,24 +28,35 @@ REQUIRES=xpcom raptor pref
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
CPPSRCS= \
nsXULButtonFrame.cpp \
nsSpringFrame.cpp \
nsXULLeafFrame.cpp \
nsXULTextFrame.cpp \
nsImageBoxFrame.cpp \
nsRootBoxFrame.cpp \
nsStackLayout.cpp \
nsSplitterFrame.cpp \
nsTitleFrame.cpp \
nsButtonBoxFrame.cpp \
nsSpringFrame.cpp \
nsSliderFrame.cpp \
nsProgressMeterFrame.cpp \
nsTitledButtonFrame.cpp \
nsCheckBoxFrame.cpp \
nsTitledBoxFrame.cpp \
nsBox.cpp \
nsContainerBox.cpp \
nsBoxFrame.cpp \
nsBoxLayoutState.cpp \
nsBoxToBlockAdaptor.cpp \
nsSprocketLayout.cpp \
nsBoxLayout.cpp \
nsLeafBoxFrame.cpp \
nsTextBoxFrame.cpp \
nsFrameNavigator.cpp \
nsRepeatService.cpp \
nsToolbarDragListener.cpp \
nsToolbarItemFrame.cpp \
nsSplitterFrame.cpp \
nsGrippyFrame.cpp \
nsTabFrame.cpp \
nsStackFrame.cpp \
nsDeckFrame.cpp \
nsBoxFrame.cpp \
nsProgressMeterFrame.cpp \
nsTitledButtonFrame.cpp \
nsToolboxFrame.cpp \
nsToolbarFrame.cpp \
nsTreeOuterFrame.cpp \
@@ -59,7 +70,6 @@ CPPSRCS= \
nsSpinnerFrame.cpp \
nsScrollbarFrame.cpp \
nsScrollbarButtonFrame.cpp \
nsSliderFrame.cpp \
nsColorPickerFrame.cpp \
nsStdColorPicker.cpp \
nsFontPickerFrame.cpp \
@@ -70,30 +80,43 @@ CPPSRCS= \
nsMenuListener.cpp \
nsMenuDismissalListener.cpp \
nsPopupSetFrame.cpp \
nsXULCheckboxFrame.cpp \
$(NULL)
CPP_OBJS= \
.\$(OBJDIR)\nsXULButtonFrame.obj \
.\$(OBJDIR)\nsSpringFrame.obj \
.\$(OBJDIR)\nsXULLeafFrame.obj \
.\$(OBJDIR)\nsXULTextFrame.obj \
.\$(OBJDIR)\nsImageBoxFrame.obj \
.\$(OBJDIR)\nsRootBoxFrame.obj \
.\$(OBJDIR)\nsStackLayout.obj \
.\$(OBJDIR)\nsToolboxFrame.obj \
.\$(OBJDIR)\nsToolbarFrame.obj \
.\$(OBJDIR)\nsPopupSetFrame.obj \
.\$(OBJDIR)\nsMenuBarFrame.obj \
.\$(OBJDIR)\nsMenuFrame.obj \
.\$(OBJDIR)\nsSplitterFrame.obj \
.\$(OBJDIR)\nsTitleFrame.obj \
.\$(OBJDIR)\nsButtonBoxFrame.obj \
.\$(OBJDIR)\nsSpringFrame.obj \
.\$(OBJDIR)\nsSliderFrame.obj \
.\$(OBJDIR)\nsProgressMeterFrame.obj \
.\$(OBJDIR)\nsCheckBoxFrame.obj \
.\$(OBJDIR)\nsTitledButtonFrame.obj \
.\$(OBJDIR)\nsTitledBoxFrame.obj \
.\$(OBJDIR)\nsBox.obj \
.\$(OBJDIR)\nsContainerBox.obj \
.\$(OBJDIR)\nsBoxFrame.obj \
.\$(OBJDIR)\nsBoxLayoutState.obj \
.\$(OBJDIR)\nsBoxToBlockAdaptor.obj \
.\$(OBJDIR)\nsSprocketLayout.obj \
.\$(OBJDIR)\nsBoxLayout.obj \
.\$(OBJDIR)\nsLeafBoxFrame.obj \
.\$(OBJDIR)\nsTextBoxFrame.obj \
.\$(OBJDIR)\nsFrameNavigator.obj \
.\$(OBJDIR)\nsRepeatService.obj \
.\$(OBJDIR)\nsToolbarDragListener.obj \
.\$(OBJDIR)\nsToolbarItemFrame.obj \
.\$(OBJDIR)\nsGrippyFrame.obj \
.\$(OBJDIR)\nsSplitterFrame.obj \
.\$(OBJDIR)\nsTabFrame.obj \
.\$(OBJDIR)\nsDeckFrame.obj \
.\$(OBJDIR)\nsStackFrame.obj \
.\$(OBJDIR)\nsBoxFrame.obj \
.\$(OBJDIR)\nsProgressMeterFrame.obj \
.\$(OBJDIR)\nsTitledButtonFrame.obj \
.\$(OBJDIR)\nsToolboxFrame.obj \
.\$(OBJDIR)\nsToolbarFrame.obj \
.\$(OBJDIR)\nsTreeOuterFrame.obj \
.\$(OBJDIR)\nsTreeFrame.obj \
.\$(OBJDIR)\nsTreeRowFrame.obj \
@@ -105,18 +128,13 @@ CPP_OBJS= \
.\$(OBJDIR)\nsSpinnerFrame.obj \
.\$(OBJDIR)\nsScrollbarFrame.obj \
.\$(OBJDIR)\nsScrollbarButtonFrame.obj \
.\$(OBJDIR)\nsSliderFrame.obj \
.\$(OBJDIR)\nsColorPickerFrame.obj \
.\$(OBJDIR)\nsStdColorPicker.obj \
.\$(OBJDIR)\nsFontPickerFrame.obj \
.\$(OBJDIR)\nsMenuPopupFrame.obj \
.\$(OBJDIR)\nsMenuFrame.obj \
.\$(OBJDIR)\nsMenuBarFrame.obj \
.\$(OBJDIR)\nsMenuBarListener.obj \
.\$(OBJDIR)\nsMenuListener.obj \
.\$(OBJDIR)\nsMenuDismissalListener.obj \
.\$(OBJDIR)\nsPopupSetFrame.obj \
.\$(OBJDIR)\nsXULCheckboxFrame.obj \
$(NULL)
EXPORTS = \

File diff suppressed because it is too large Load Diff

120
layout/xul/base/src/nsBox.h Normal file
View File

@@ -0,0 +1,120 @@
/* -*- 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.
*
* Author:
* Eric D Vaughan
*
* Contributor(s):
*/
#ifndef nsBox_h___
#define nsBox_h___
#include "nsIBox.h"
class nsBox : public nsIBox {
public:
NS_DECL_ISUPPORTS
NS_IMETHOD GetChildBox(nsIBox** aBox);
NS_IMETHOD GetNextBox(nsIBox** aBox);
NS_IMETHOD SetNextBox(nsIBox* aBox);
NS_IMETHOD GetParentBox(nsIBox** aParent);
NS_IMETHOD SetParentBox(nsIBox* aParent);
NS_IMETHOD IsDirty(PRBool& aIsDirty);
NS_IMETHOD HasDirtyChildren(PRBool& aIsDirty);
NS_IMETHOD MarkDirty(nsBoxLayoutState& aState);
NS_IMETHOD MarkDirtyChildren(nsBoxLayoutState& aState);
NS_IMETHOD SetDebug(nsBoxLayoutState& aState, PRBool aDebug);
NS_IMETHOD SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect);
NS_IMETHOD GetBounds(nsRect& aRect);
NS_IMETHOD GetBorderAndPadding(nsMargin& aBorderAndPadding);
NS_IMETHOD GetBorder(nsMargin& aBorderAndPadding);
NS_IMETHOD GetPadding(nsMargin& aBorderAndPadding);
NS_IMETHOD GetMargin(nsMargin& aMargin);
NS_IMETHOD SetLayoutManager(nsIBoxLayout* aLayout);
NS_IMETHOD GetLayoutManager(nsIBoxLayout** aLayout);
NS_IMETHOD GetContentRect(nsRect& aContentRect);
NS_IMETHOD GetClientRect(nsRect& aContentRect);
NS_IMETHOD GetVAlign(Valignment& aAlign);
NS_IMETHOD GetHAlign(Halignment& aAlign);
NS_IMETHOD GetInset(nsMargin& aInset);
NS_IMETHOD GetOrientation(PRBool& aIsHorizontal);
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetFlex(nsBoxLayoutState& aBoxLayoutState, nscoord& aFlex);
NS_IMETHOD GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent);
NS_IMETHOD IsCollapsed(nsBoxLayoutState& aBoxLayoutState, PRBool& aCollapsed);
NS_IMETHOD Collapse(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD UnCollapse(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD Redraw(nsBoxLayoutState& aState, const nsRect* aRect = nsnull, PRBool aImmediate = PR_FALSE);
NS_IMETHOD NeedsRecalc();
NS_IMETHOD GetDebugBoxAt(const nsPoint& aPoint, nsIBox** aBox);
NS_IMETHOD GetDebug(PRBool& aDebug);
nsBox(nsIPresShell* aShell);
virtual nsresult SyncLayout(nsBoxLayoutState& aBoxLayoutState);
virtual PRBool DoesNeedRecalc(const nsSize& aSize);
virtual PRBool DoesNeedRecalc(nscoord aCoord);
virtual void SizeNeedsRecalc(nsSize& aSize);
virtual void CoordNeedsRecalc(nscoord& aCoord);
virtual void AddBorderAndPadding(nsSize& aSize);
virtual void AddInset(nsSize& aSize);
virtual void AddMargin(nsSize& aSize);
static void AddBorderAndPadding(nsIBox* aBox, nsSize& aSize);
static void AddInset(nsIBox* aBox, nsSize& aSize);
static void AddMargin(nsIBox* aChild, nsSize& aSize);
static void AddMargin(nsSize& aSize, const nsMargin& aMargin);
static nsresult UnCollapseChild(nsBoxLayoutState& aState, nsIBox* aFrame);
static nsresult CollapseChild(nsBoxLayoutState& aState, nsIFrame* aFrame, PRBool aHide);
static void BoundsCheck(nsSize& aMinSize, nsSize& aPrefSize, nsSize& aMaxSize);
protected:
virtual PRBool GetWasCollapsed(nsBoxLayoutState& aState);
virtual void SetWasCollapsed(nsBoxLayoutState& aState, PRBool aWas);
enum eMouseThrough {
never,
sometimes,
always
};
eMouseThrough mMouseThrough;
private:
nsIBox* mNextChild;
nsIBox* mParentBox;
//nscoord mX;
//nscoord mY;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -33,8 +33,8 @@
#include "nsCOMPtr.h"
#include "nsHTMLContainerFrame.h"
#include "nsIBox.h"
#include "nsISpaceManager.h"
#include "nsContainerBox.h"
class nsBoxLayoutState;
class nsBoxFrameInner;
class nsBoxDebugInner;
@@ -47,23 +47,6 @@ class nsHTMLInfo;
#define NS_FRAME_BOX_NEEDS_RECALC 0x0004
#define NS_FRAME_IS_BOX 0x0008
class nsCalculatedBoxInfo : public nsBoxInfo {
public:
nsSize calculatedSize;
PRInt16 mFlags;
nsCalculatedBoxInfo* next;
nsIFrame* frame;
virtual void Recycle(nsIPresShell* aShell);
};
class nsInfoList
{
public:
virtual nsCalculatedBoxInfo* GetFirst()=0;
virtual nsCalculatedBoxInfo* GetLast()=0;
virtual PRInt32 GetCount()=0;
};
// flags from box
#define NS_STATE_IS_HORIZONTAL 0x00400000
@@ -72,8 +55,9 @@ public:
#define NS_STATE_CURRENTLY_IN_DEBUG 0x02000000
#define NS_STATE_SET_TO_DEBUG 0x04000000
#define NS_STATE_DEBUG_WAS_SET 0x08000000
#define NS_STATE_IS_COLLAPSED 0x10000000
class nsBoxFrame : public nsHTMLContainerFrame, public nsIBox
class nsBoxFrame : public nsHTMLContainerFrame, public nsContainerBox
{
public:
@@ -81,7 +65,29 @@ public:
// gets the rect inside our border and debug border. If you wish to paint inside a box
// call this method to get the rect so you don't draw on the debug border or outer border.
virtual void GetInnerRect(nsRect& aInner);
// ------ nsISupports --------
NS_DECL_ISUPPORTS
// ------ nsIBox -------------
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetFlex(nsBoxLayoutState& aBoxLayoutState, nscoord& aFlex);
NS_IMETHOD GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent);
NS_IMETHOD SetDebug(nsBoxLayoutState& aBoxLayoutState, PRBool aDebug);
NS_IMETHOD GetFrame(nsIFrame** aFrame);
NS_IMETHOD GetVAlign(Valignment& aAlign);
NS_IMETHOD GetHAlign(Halignment& aAlign);
NS_IMETHOD NeedsRecalc();
NS_IMETHOD GetInset(nsMargin& aInset);
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD GetDebug(PRBool& aDebug);
// ----- child and sibling operations ---
// ----- public methods -------
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
@@ -93,9 +99,6 @@ public:
PRInt32& aCursor);
NS_IMETHOD DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus);
NS_IMETHOD ReflowDirtyChild(nsIPresShell* aPresShell, nsIFrame* aChild);
NS_IMETHOD Init(nsIPresContext* aPresContext,
@@ -146,37 +149,22 @@ public:
NS_IMETHOD GetFrameName(nsString& aResult) const;
NS_IMETHOD DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus);
virtual PRBool IsHorizontal() const;
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
virtual ~nsBoxFrame();
virtual void GetChildBoxInfo(PRInt32 aIndex, nsBoxInfo& aSize);
virtual nsresult GetContentOf(nsIContent** aContent);
// nsIBox methods
NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize);
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_IMETHOD InvalidateCache(nsIFrame* aChild);
NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug);
enum Halignment {
hAlign_Left,
hAlign_Right,
hAlign_Center
};
enum Valignment {
vAlign_Top,
vAlign_Middle,
vAlign_BaseLine,
vAlign_Bottom
};
protected:
nsBoxFrame(nsIPresShell* aPresShell, PRBool aIsRoot = PR_FALSE);
virtual void PropagateDebug(nsBoxLayoutState& aState);
// Paint one child frame
virtual void PaintChild(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@@ -189,36 +177,14 @@ protected:
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
virtual void GetRedefinedMinPrefMax(nsIPresContext* aPresContext, nsIFrame* aFrame, nsCalculatedBoxInfo& aSize);
virtual nsresult GetChildBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsIFrame* aFrame, nsCalculatedBoxInfo& aSize);
virtual void ComputeChildsNextPosition( nsCalculatedBoxInfo* aInfo, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect, nscoord aMaxAscent);
virtual nsresult PlaceChildren(nsIPresContext* aPresContext, nsRect& boxRect);
virtual void ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool*& aResized, PRInt32 aInfoCount, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason);
virtual void LayoutChildrenInRect(nsRect& aSize, nscoord& aMaxAscent);
virtual void AddChildSize(nsBoxInfo& aInfo, nsBoxInfo& aChildInfo);
virtual void BoundsCheck(const nsBoxInfo& aBoxInfo, nsRect& aRect);
virtual void InvalidateChildren();
virtual void AddSize(const nsSize& a, nsSize& b, PRBool largest);
virtual PRIntn GetSkipSides() const { return 0; }
virtual void GetInset(nsMargin& margin);
virtual void CollapseChild(nsIPresContext* aPresContext, nsIFrame* frame, PRBool hide);
nsresult GenerateDirtyReflowCommand(nsIPresContext* aPresContext,
nsIPresShell& aPresShell);
virtual PRBool GetInitialOrientation(PRBool& aIsHorizontal);
virtual PRBool GetInitialHAlignment(Halignment& aHalign);
virtual PRBool GetInitialVAlignment(Valignment& aValign);
virtual PRBool GetInitialAutoStretch(PRBool& aStretch);
virtual PRBool GetDefaultFlex(PRInt32& aFlex);
virtual nsInfoList* GetInfoList();
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
private:

View File

@@ -0,0 +1,381 @@
/* -*- 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 "nsBoxLayoutState.h"
#include "nsIReflowCommand.h"
#include "nsBoxFrame.h"
#include "nsIStyleContext.h"
#include "nsHTMLAtoms.h"
#include "nsXULAtoms.h"
#include "nsIContent.h"
#include "nsINameSpaceManager.h"
#include "nsIPresContext.h"
nsBoxLayoutState::nsBoxLayoutState(nsIPresContext* aPresContext):mPresContext(aPresContext), mReflowState(nsnull)
{
}
nsBoxLayoutState::nsBoxLayoutState(const nsBoxLayoutState& aState)
{
mPresContext = aState.mPresContext;
mType = aState.mType;
mReflowState = aState.mReflowState;
}
nsBoxLayoutState::nsBoxLayoutState(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState):mReflowState(&aReflowState),mPresContext(aPresContext),mType(Dirty)
{
}
PRBool
nsBoxLayoutState::HandleReflow(nsIBox* aRootBox, PRBool aCoelesce)
{
switch(mReflowState->reason)
{
case eReflowReason_Incremental:
{
nsIReflowCommand::ReflowType type;
mReflowState->reflowCommand->GetType(type);
// atempt to coelesce style changes and reflows
// see if the target is a box
/*
PRBool isAdaptor = PR_FALSE;
nsIBox* box = GetTargetBox(mReflowState->reflowCommand, isAdaptor);
// if it is mark it dirty. Generating a dirty reflow targeted at us unless on is already
// done.
if (box && box != aRootBox) {
if (type == nsIReflowCommand::StyleChanged) {
// could be a visiblity change need to dirty
// parent so it gets redrawn.
nsIBox* parent;
box->GetParentBox(&parent);
parent->MarkDirty(*this);
DirtyAllChildren(*this, box);
} else
box->MarkDirty(*this);
return PR_TRUE;
}
*/
// ok if the target was not a box. Then unwind it down
if (UnWind(mReflowState->reflowCommand, aRootBox, aCoelesce)) {
mType = Dirty;
return PR_TRUE;
}
} // fall into dirty
case eReflowReason_Dirty:
mType = Dirty;
break;
// if the a resize reflow then it doesn't need to be reflowed. Only if the size is different
// from the new size would we actually do a reflow
case eReflowReason_Resize:
mType = Resize;
break;
// if its an initial reflow we must place the child.
// otherwise we might think it was already placed when it wasn't
case eReflowReason_Initial:
mType = Initial;
break;
default:
mType = Dirty;
}
return PR_FALSE;
}
PRBool
nsBoxLayoutState::UnWind(nsIReflowCommand* aCommand, nsIBox* aBox, PRBool aCoelesce)
{
// if incremental unwindow the chain
nsIFrame* incrementalChild = nsnull;
nsIBox* lastBox = nsnull;
nsIFrame* target = nsnull;
aCommand->GetTarget(target);
nsIReflowCommand::ReflowType type;
mReflowState->reflowCommand->GetType(type);
while(1)
{
aCommand->GetNext(incrementalChild, PR_FALSE);
if (incrementalChild == nsnull)
return PR_FALSE;
// get the box for the given incrementalChild. If adaptor is true then
// it is some wrapped HTML frame.
PRBool isAdaptor = PR_FALSE;
nsIBox* ibox = GetBoxForFrame(incrementalChild, isAdaptor);
if (ibox) {
nsFrameState state;
incrementalChild->GetFrameState(&state);
state &= ~NS_FRAME_HAS_DIRTY_CHILDREN;
incrementalChild->SetFrameState(state);
// ok we got a box is it the target?
if (incrementalChild == target) {
if (!aCoelesce) {
nsFrameState state;
nsIFrame* frame;
aBox->GetFrame(&frame);
frame->GetFrameState(&state);
state |= NS_FRAME_HAS_DIRTY_CHILDREN;
frame->SetFrameState(state);
}
// the target is a box?
// mark it dirty generating a new reflow command targeted
// at us and coelesce out this one.
ibox->MarkDirty(*this);
if (type == nsIReflowCommand::StyleChanged) {
// could be a visiblity change need to dirty
// parent so it gets redrawn.
nsIBox* parent;
ibox->GetParentBox(&parent);
parent->MarkDirty(*this);
//DirtyAllChildren(*this, box);
}
// yes we coelesed
return aCoelesce ? PR_TRUE : PR_FALSE;
}
// was the child html?
if (isAdaptor) {
// the target is deep inside html we will have to honor this one.
// mark us as dirty so we don't post
// a dirty reflow
nsFrameState state;
nsIFrame* frame;
aBox->GetFrame(&frame);
frame->GetFrameState(&state);
state |= NS_FRAME_HAS_DIRTY_CHILDREN;
frame->SetFrameState(state);
incrementalChild->GetFrameState(&state);
state &= ~NS_FRAME_IS_DIRTY;
incrementalChild->SetFrameState(state);
// mark the adaptor dirty
ibox->MarkDirty(*this);
// we are done and we did not coelesce
return PR_FALSE;
}
} else {
NS_ERROR("This should not happen! We should always get a box");
break;
}
aCommand->GetNext(incrementalChild);
}
return PR_FALSE;
}
/*
void
nsBoxLayoutState::UnWind(nsIReflowCommand* aCommand, nsIBox* aBox)
{
nsFrameState state;
nsIFrame* frame;
aBox->GetFrame(&frame);
frame->GetFrameState(&state);
state |= NS_FRAME_HAS_DIRTY_CHILDREN;
frame->SetFrameState(state);
// if incremental unwindow the chain
nsIFrame* incrementalChild = nsnull;
while(1)
{
aCommand->GetNext(incrementalChild, PR_FALSE);
if (incrementalChild == nsnull)
break;
nsIFrame* target = nsnull;
aCommand->GetTarget(target);
PRBool isAdaptor = PR_FALSE;
nsIBox* ibox = GetBoxForFrame(incrementalChild, isAdaptor);
if (ibox) {
if (incrementalChild == target || isAdaptor) {
ibox->MarkDirty(*this);
if (isAdaptor)
break;
} else
ibox->MarkDirtyChildren(*this);
} else {
break;
}
aCommand->GetNext(incrementalChild);
}
}
*/
nsIBox*
nsBoxLayoutState::GetTargetBox(nsIReflowCommand* mCommand, PRBool& aIsAdaptor)
{
nsIFrame* target = nsnull;
mReflowState->reflowCommand->GetTarget(target);
return GetBoxForFrame(target, aIsAdaptor);
}
nsIBox*
nsBoxLayoutState::GetBoxForFrame(nsIFrame* aFrame, PRBool& aIsAdaptor)
{
if (aFrame == nsnull)
return nsnull;
nsIBox* ibox = nsnull;
if (NS_FAILED(aFrame->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox))) {
aIsAdaptor = PR_TRUE;
// if we hit a non box. Find the box in out last container
// and clear its cache.
nsIFrame* parent = nsnull;
aFrame->GetParent(&parent);
nsIBox* parentBox = nsnull;
if (NS_FAILED(parent->QueryInterface(NS_GET_IID(nsIBox), (void**)&parentBox)))
return nsnull;
if (parentBox) {
nsIBox* start = nsnull;
parentBox->GetChildBox(&start);
while (start) {
nsIFrame* frame = nsnull;
start->GetFrame(&frame);
if (frame == aFrame) {
ibox = start;
break;
}
start->GetNextBox(&start);
}
}
}
return ibox;
}
void
nsBoxLayoutState::DirtyAllChildren(nsBoxLayoutState& aState, nsIBox* aBox)
{
aBox->MarkDirty(aState);
nsIBox* first = nsnull;
aBox->GetChildBox(&first);
if (first)
aBox->MarkDirtyChildren(aState);
while(first)
{
DirtyAllChildren(aState, first);
first->GetNextBox(&first);
}
}
void*
nsBoxLayoutState::Allocate(size_t sz, nsIPresShell* aPresShell)
{
// Check the recycle list first.
void* result = nsnull;
aPresShell->AllocateFrame(sz, &result);
if (result) {
nsCRT::zero(result, sz);
}
return result;
}
// Overridden to prevent the global delete from being called, since the memory
// came out of an nsIArena instead of the global delete operator's heap.
void
nsBoxLayoutState::Free(void* aPtr, size_t sz)
{
// Don't let the memory be freed, since it will be recycled
// instead. Don't call the global operator delete.
// Stash the size of the object in the first four bytes of the
// freed up memory. The Destroy method can then use this information
// to recycle the object.
size_t* szPtr = (size_t*)aPtr;
*szPtr = sz;
}
void
nsBoxLayoutState::RecycleFreedMemory(nsIPresShell* aShell, void* aMem)
{
size_t* sz = (size_t*)aMem;
aShell->FreeFrame(*sz, aMem);
}
nsresult
nsBoxLayoutState::GetPresShell(nsIPresShell** aShell)
{
return mPresContext->GetShell(aShell);
}
nsresult
nsBoxLayoutState::PushStackMemory()
{
nsCOMPtr<nsIPresShell> shell;
mPresContext->GetShell(getter_AddRefs(shell));
return shell->PushStackMemory();
}
nsresult
nsBoxLayoutState::PopStackMemory()
{
nsCOMPtr<nsIPresShell> shell;
mPresContext->GetShell(getter_AddRefs(shell));
return shell->PopStackMemory();
}
nsresult
nsBoxLayoutState::AllocateStackMemory(size_t aSize, void** aResult)
{
nsCOMPtr<nsIPresShell> shell;
mPresContext->GetShell(getter_AddRefs(shell));
return shell->AllocateStackMemory(aSize, aResult);
}

View File

@@ -0,0 +1,87 @@
/* -*- 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):
*/
/**
Author:
Eric D Vaughan
**/
#ifndef nsBoxLayoutState_h___
#define nsBoxLayoutState_h___
#include "nsIFrame.h"
#include "nsCOMPtr.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
class nsReflowState;
class nsCalculatedBoxInfo;
struct nsHTMLReflowMetrics;
class nsString;
class nsIBox;
class nsIReflowCommand;
class nsBoxLayoutState
{
public:
enum eBoxLayoutReason {
Dirty,
Resize,
Initial
};
nsBoxLayoutState(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState);
nsBoxLayoutState(nsIPresContext* aPresContext);
nsBoxLayoutState(const nsBoxLayoutState& aState);
virtual PRBool HandleReflow(nsIBox* aRootBox, PRBool aCoalesce);
virtual nsIPresContext* GetPresContext() { return mPresContext; }
virtual nsresult GetPresShell(nsIPresShell** aShell);
virtual eBoxLayoutReason GetLayoutReason() { return mType; }
virtual void SetLayoutReason(eBoxLayoutReason aReason) { mType = aReason; }
virtual const nsHTMLReflowState* GetReflowState() { return mReflowState; }
static void* Allocate(size_t sz, nsIPresShell* aPresShell);
static void Free(void* aPtr, size_t sz);
static void RecycleFreedMemory(nsIPresShell* aPresShell, void* mem);
nsresult PushStackMemory();
nsresult PopStackMemory();
nsresult AllocateStackMemory(size_t aSize, void** aResult);
private:
void DirtyAllChildren(nsBoxLayoutState& aState, nsIBox* aBox);
PRBool UnWind(nsIReflowCommand* aCommand, nsIBox* aRootBox, PRBool aCoalesce);
nsIBox* GetTargetBox(nsIReflowCommand* mCommand, PRBool& aIsAdaptor);
nsIBox* GetBoxForFrame(nsIFrame* aFrame, PRBool& aIsAdaptor);
nsIPresContext* mPresContext;
const nsHTMLReflowState* mReflowState;
eBoxLayoutReason mType;
};
#endif

View File

@@ -0,0 +1,806 @@
/* -*- 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 "nsBoxLayoutState.h"
#include "nsBoxFrame.h"
#include "nsIStyleContext.h"
#include "nsIPresContext.h"
#include "nsCOMPtr.h"
#include "nsHTMLIIDs.h"
#include "nsUnitConversion.h"
#include "nsINameSpaceManager.h"
#include "nsHTMLAtoms.h"
#include "nsXULAtoms.h"
#include "nsIReflowCommand.h"
#include "nsIContent.h"
#include "nsSpaceManager.h"
#include "nsHTMLParts.h"
#include "nsIViewManager.h"
#include "nsIView.h"
#include "nsIPresShell.h"
#include "nsGenericHTMLElement.h"
#include "nsFrameNavigator.h"
#include "nsCSSRendering.h"
#include "nsISelfScrollingFrame.h"
#include "nsIPref.h"
#include "nsIServiceManager.h"
#include "nsBoxToBlockAdaptor.h"
#include "nsILineIterator.h"
#include "nsIFontMetrics.h"
nsBoxToBlockAdaptor::nsBoxToBlockAdaptor(nsIPresShell* aPresShell, nsIFrame* aFrame):nsBox(aPresShell)
{
NS_INIT_ISUPPORTS();
mFrame = aFrame;
mSpaceManager = nsnull;
mWasCollapsed = PR_FALSE;
NeedsRecalc();
}
void*
nsBoxToBlockAdaptor::operator new(size_t sz, nsIPresShell* aPresShell)
{
return nsBoxLayoutState::Allocate(sz,aPresShell);
}
NS_IMETHODIMP
nsBoxToBlockAdaptor::Recycle(nsIPresShell* aPresShell)
{
delete this;
nsBoxLayoutState::RecycleFreedMemory(aPresShell, this);
return NS_OK;
}
NS_IMETHODIMP
nsBoxToBlockAdaptor::GetFrame(nsIFrame** aFrame)
{
*aFrame = mFrame;
return NS_OK;
}
// Overridden to prevent the global delete from being called, since the memory
// came out of an nsIArena instead of the global delete operator's heap.
void
nsBoxToBlockAdaptor::operator delete(void* aPtr, size_t sz)
{
nsBoxLayoutState::Free(aPtr, sz);
}
nsBoxToBlockAdaptor::~nsBoxToBlockAdaptor()
{
if (mSpaceManager)
NS_RELEASE(mSpaceManager);
}
NS_IMETHODIMP
nsBoxToBlockAdaptor::NeedsRecalc()
{
nsIBox* parent;
GetParentBox(&parent);
nsIFrame* frame;
if (parent) {
parent->GetFrame(&frame);
nsFrameState frameState = 0;
frame->GetFrameState(&frameState);
}
mMinWidth = -1;
mPrefNeedsRecalc = PR_TRUE;
SizeNeedsRecalc(mMinSize);
SizeNeedsRecalc(mMaxSize);
CoordNeedsRecalc(mFlex);
CoordNeedsRecalc(mAscent);
return NS_OK;
}
NS_IMETHODIMP
nsBoxToBlockAdaptor::GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
if (!mPrefNeedsRecalc) {
aSize = mPrefSize;
return NS_OK;
}
nsresult rv = NS_OK;
// see if anything is defined in css. If pref size is competely
// defined in css we are golden. We do nothing. But is its not
// in css we will have to reflow the child.
nsSize pref(0,0);
PRBool completelyRedefined = nsIBox::AddCSSPrefSize(aBoxLayoutState, this, mPrefSize);
if (!completelyRedefined) {
const nsHTMLReflowState* reflowState = aBoxLayoutState.GetReflowState();
if (reflowState) {
nsIPresContext* presContext = aBoxLayoutState.GetPresContext();
nsReflowStatus status = NS_FRAME_COMPLETE;
nsHTMLReflowMetrics desiredSize(nsnull);
PRBool isDirty = PR_FALSE;
IsDirty(isDirty);
//nsRect oldRect;
// mFrame->GetRect(oldRect);
rv = Reflow(presContext,
desiredSize,
*reflowState,
status,
0,
0,
NS_INTRINSICSIZE,
NS_INTRINSICSIZE,
PR_FALSE);
nsFrameState frameState = 0;
mFrame->GetFrameState(&frameState);
frameState |= NS_FRAME_IS_DIRTY;
mFrame->SetFrameState(frameState);
//mFrame->SetRect(presContext, oldRect);
mPrefSize.width = desiredSize.width;
mPrefSize.height = desiredSize.height;
mAscent = desiredSize.ascent;
nsMargin m(0,0,0,0);
GetInset(m);
mAscent += m.top;
// ok the sizes might be bigger than our css preferred size.
// check it.
AddInset(mPrefSize);
nsIBox::AddCSSPrefSize(aBoxLayoutState, this, mPrefSize);
mPrefNeedsRecalc = PR_FALSE;
}
}
aSize = mPrefSize;
return rv;
}
NS_IMETHODIMP
nsBoxToBlockAdaptor::GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
if (!DoesNeedRecalc(mMinSize)) {
aSize = mMinSize;
return NS_OK;
}
mMinSize.width = 0;
mMinSize.height = 0;
AddBorderAndPadding(mMinSize);
AddInset(mMinSize);
if (mMinWidth != -1)
mMinSize.width = mMinWidth;
nsIBox::AddCSSMinSize(aBoxLayoutState, this, mMinSize);
aSize = mMinSize;
return NS_OK;
}
NS_IMETHODIMP
nsBoxToBlockAdaptor::GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
if (!DoesNeedRecalc(mMaxSize)) {
aSize = mMaxSize;
return NS_OK;
}
nsresult rv = nsBox::GetMaxSize(aBoxLayoutState, mMaxSize);
aSize = mMaxSize;
return rv;
}
NS_IMETHODIMP
nsBoxToBlockAdaptor::GetFlex(nsBoxLayoutState& aBoxLayoutState, nscoord& aFlex)
{
if (!DoesNeedRecalc(mFlex)) {
aFlex = mFlex;
return NS_OK;
}
mFlex = 0;
nsBox::GetFlex(aBoxLayoutState, mFlex);
aFlex = mFlex;
return NS_OK;
}
NS_IMETHODIMP
nsBoxToBlockAdaptor::GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent)
{
if (!DoesNeedRecalc(mAscent)) {
aAscent = mAscent;
return NS_OK;
}
nsSize size;
GetPrefSize(aBoxLayoutState, size);
aAscent = mAscent;
return NS_OK;
}
NS_IMETHODIMP
nsBoxToBlockAdaptor::IsCollapsed(nsBoxLayoutState& aBoxLayoutState, PRBool& aCollapsed)
{
return nsBox::IsCollapsed(aBoxLayoutState, aCollapsed);
}
nsresult
nsBoxToBlockAdaptor::Layout(nsBoxLayoutState& aBoxLayoutState)
{
nsRect ourRect(0,0,0,0);
GetBounds(ourRect);
const nsHTMLReflowState* reflowState = aBoxLayoutState.GetReflowState();
nsIPresContext* presContext = aBoxLayoutState.GetPresContext();
nsReflowStatus status = NS_FRAME_COMPLETE;
nsHTMLReflowMetrics desiredSize(nsnull);
nsresult rv;
if (reflowState) {
// nsRect oldRect;
// mFrame->GetRect(oldRect);
rv = Reflow(presContext,
desiredSize,
*reflowState,
status,
ourRect.x,
ourRect.y,
ourRect.width,
ourRect.height);
mAscent = desiredSize.ascent;
PRBool isCollapsed = PR_FALSE;
IsCollapsed(aBoxLayoutState, isCollapsed);
// if (!isCollapsed) {
mFrame->SizeTo(presContext, desiredSize.width, desiredSize.height);
// } else {
// mFrame->SetRect(presContext, oldRect);
// }
}
SyncLayout(aBoxLayoutState);
return rv;
}
nsresult
nsBoxToBlockAdaptor::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
nscoord aX,
nscoord aY,
nscoord aWidth,
nscoord aHeight,
PRBool aMoveFrame)
{
//printf("width=%d, height=%d\n", aWidth, aHeight);
nsIBox* parent;
GetParentBox(&parent);
nsIFrame* frame;
parent->GetFrame(&frame);
nsFrameState frameState = 0;
frame->GetFrameState(&frameState);
// if (frameState & NS_STATE_CURRENTLY_IN_DEBUG)
// printf("In debug\n");
if (mSpaceManager == nsnull) {
mSpaceManager = new nsSpaceManager(mFrame);
NS_ADDREF(mSpaceManager);
}
// Modify the reflow state and set the space manager
nsHTMLReflowState& nonConstState = (nsHTMLReflowState&)aReflowState;
nonConstState.mSpaceManager = mSpaceManager;
// Clear the spacemanager's regions.
mSpaceManager->ClearRegions();
aStatus = NS_FRAME_COMPLETE;
PRBool needsReflow = PR_FALSE;
// get our frame its size and the reflow state
nsReflowReason reason = aReflowState.reason;
nsFrameState childState;
mFrame->GetFrameState(&childState);
// childState |= NS_BLOCK_SPACE_MGR;
// mFrame->SetFrameState(childState);
if (childState & NS_FRAME_FIRST_REFLOW) {
if (reason != eReflowReason_Initial)
{
// if incremental then make sure we send a initial reflow first.
if (reason == eReflowReason_Incremental) {
nsHTMLReflowState state(aReflowState);
state.reason = eReflowReason_Initial;
state.reflowCommand = nsnull;
Reflow(aPresContext, aDesiredSize, state, aStatus, aX, aY, aWidth, aHeight, aMoveFrame);
} else {
// convert to initial if not incremental.
reason = eReflowReason_Initial;
}
}
} else if (reason == eReflowReason_Initial) {
reason = eReflowReason_Resize;
}
// handle or different types of reflow
switch(reason)
{
// if the child we are reflowing is the child we popped off the incremental
// reflow chain then we need to reflow it no matter what.
// if its not the child we got from the reflow chain then this child needs reflow
// because as a side effect of the incremental child changing aize andit needs to be resized.
// This will happen with a lot when a box that contains 2 children with different flexabilities
// if on child gets bigger the other is affected because it is proprotional to the first.
// so it might need to be resized. But we don't need to reflow it. If it is already the
// needed size then we will do nothing.
case eReflowReason_Incremental: {
// if incremental see if the next child in the chain is the child. If so then
// we will just let it go down. If not then convert it to a dirty. It will get converted back when
// needed in the case just below this one.
nsIFrame* incrementalChild = nsnull;
aReflowState.reflowCommand->GetNext(incrementalChild, PR_FALSE);
if (incrementalChild == nsnull)
aReflowState.reflowCommand->GetTarget(incrementalChild);
if (incrementalChild == mFrame) {
needsReflow = PR_TRUE;
aReflowState.reflowCommand->GetNext(incrementalChild);
break;
}
// fall into dirty
}
// if its dirty then see if the child we want to reflow is dirty. If it is then
// mark it as needing to be reflowed.
case eReflowReason_Dirty: {
// only frames that implement nsIBox seem to be able to handle a reason of Dirty. For everyone else
// send down a resize.
reason = eReflowReason_Resize;
// get the frame state to see if it needs reflow
needsReflow = (childState & NS_FRAME_IS_DIRTY) || (childState & NS_FRAME_HAS_DIRTY_CHILDREN);
} break;
// if the a resize reflow then it doesn't need to be reflowed. Only if the size is different
// from the new size would we actually do a reflow
case eReflowReason_Resize:
needsReflow = PR_FALSE;
break;
// if its an initial reflow we must place the child.
// otherwise we might think it was already placed when it wasn't
case eReflowReason_Initial:
aMoveFrame = PR_TRUE;
needsReflow = PR_TRUE;
break;
default:
needsReflow = PR_TRUE;
}
//nsMargin margin(0,0,0,0);
// GetMargin(margin);
// if we don't need a reflow then
// lets see if we are already that size. Yes? then don't even reflow. We are done.
if (!needsReflow) {
if (aWidth != NS_INTRINSICSIZE && aHeight != NS_INTRINSICSIZE) {
// if the new calculated size has a 0 width or a 0 height
if ((mLastSize.width == 0 || mLastSize.height == 0) && (aWidth == 0 || aHeight == 0)) {
needsReflow = PR_FALSE;
aDesiredSize.width = aWidth;
aDesiredSize.height = aHeight;
mFrame->SizeTo(aPresContext, aDesiredSize.width, aDesiredSize.height);
} else {
aDesiredSize.width = mLastSize.width;
aDesiredSize.height = mLastSize.height;
// remove the margin. The rect of our child does not include it but our calculated size does.
nscoord calcWidth = aWidth;
nscoord calcHeight = aHeight;
// don't reflow if we are already the right size
if (mLastSize.width == calcWidth && mLastSize.height == calcHeight)
needsReflow = PR_FALSE;
else
needsReflow = PR_TRUE;
}
} else {
// if the width or height are intrinsic alway reflow because
// we don't know what it should be.
needsReflow = PR_TRUE;
}
}
// ok now reflow the child into the springs calculated space
if (needsReflow) {
nsMargin border(0,0,0,0);
GetBorderAndPadding(border);
aDesiredSize.width = 0;
aDesiredSize.height = 0;
nsSize size(aWidth, aHeight);
// create a reflow state to tell our child to flow at the given size.
#ifdef DEBUG_REFLOW
char* reflowReasonString;
switch(reason)
{
case eReflowReason_Initial:
reflowReasonString = "initial";
break;
case eReflowReason_Resize:
reflowReasonString = "resize";
break;
case eReflowReason_Dirty:
reflowReasonString = "dirty";
break;
case eReflowReason_StyleChange:
reflowReasonString = "stylechange";
break;
case eReflowReason_Incremental:
reflowReasonString = "incremental";
break;
default:
reflowReasonString = "unknown";
break;
}
AddIndents();
nsFrame::ListTag(stdout, childFrame);
char ch[100];
aReason.ToCString(ch,100);
printf(" reason=%s %s",reflowReasonString,ch);
#endif
nsHTMLReflowState reflowState(aPresContext, aReflowState, mFrame, nsSize(size.width, NS_INTRINSICSIZE));
reflowState.reason = reason;
if (size.height != NS_INTRINSICSIZE) {
size.height -= (border.top + border.bottom);
NS_ASSERTION(size.height >= 0,"Error top bottom border too large");
}
if (size.width != NS_INTRINSICSIZE) {
size.width -= (border.left + border.right);
NS_ASSERTION(size.height >= 0,"Error left right border too large");
}
reflowState.mComputedWidth = size.width;
reflowState.mComputedHeight = size.height;
#ifdef DEBUG_REFLOW
printf(" Size=(%d,%d)\n",reflowState.mComputedWidth, reflowState.mComputedHeight);
#endif
// place the child and reflow
mFrame->WillReflow(aPresContext);
// if (aMoveFrame) {
// PlaceChild(aPresContext, mFrame, aX + margin.left, aY + margin.top);
// }
mFrame->Reflow(aPresContext, aDesiredSize, reflowState, aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
nsFrameState kidState;
mFrame->GetFrameState(&kidState);
// printf("width: %d, height: %d\n", aDesiredSize.mCombinedArea.width, aDesiredSize.mCombinedArea.height);
// XXX EDV hack to fix bug in block
//if (reflowState.reason != eReflowReason_Initial) {
/*
if (kidState & NS_FRAME_OUTSIDE_CHILDREN) {
printf("OutsideChildren width=%d, height=%d\n", aDesiredSize.mOverflowArea.width, aDesiredSize.mOverflowArea.height);
if (aDesiredSize.mOverflowArea.width > aWidth)
{
reflowState.mComputedWidth = aDesiredSize.mOverflowArea.width - (border.left + border.right);
reflowState.availableWidth = reflowState.mComputedWidth;
//Reflow(aPresContext, aDesiredSize, aReflowState, aStatus, aX, aY, aDesiredSize.mOverflowArea.width, aHeight, aMoveFrame);
mFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
mFrame->WillReflow(aPresContext);
mFrame->Reflow(aPresContext, aDesiredSize, reflowState, aStatus);
mFrame->GetFrameState(&kidState);
if (kidState & NS_FRAME_OUTSIDE_CHILDREN)
aDesiredSize.height = aDesiredSize.mOverflowArea.height;
} else {
aDesiredSize.height = aDesiredSize.mOverflowArea.height;
}
}
*/
if (kidState & NS_FRAME_OUTSIDE_CHILDREN) {
//printf("OutsideChildren width=%d, height=%d\n", aDesiredSize.mOverflowArea.width, aDesiredSize.mOverflowArea.height);
aDesiredSize.width = aDesiredSize.mOverflowArea.width;
if (aDesiredSize.width <= aWidth)
aDesiredSize.height = aDesiredSize.mOverflowArea.height;
else {
if (aDesiredSize.width > aWidth)
{
reflowState.mComputedWidth = aDesiredSize.width - (border.left + border.right);
reflowState.availableWidth = reflowState.mComputedWidth;
reflowState.reason = eReflowReason_Resize;
reflowState.reflowCommand = nsnull;
mFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
mFrame->WillReflow(aPresContext);
mFrame->Reflow(aPresContext, aDesiredSize, reflowState, aStatus);
mFrame->GetFrameState(&kidState);
if (kidState & NS_FRAME_OUTSIDE_CHILDREN)
aDesiredSize.height = aDesiredSize.mOverflowArea.height;
}
}
}
// ok we need the max ascent of the items on the line. So to do this
// ask the block for its line iterator. Get the max ascent.
nsILineIterator* lines = nsnull;
if (NS_SUCCEEDED(mFrame->QueryInterface(NS_GET_IID(nsILineIterator), (void**)&lines)) && lines)
{
nsIFrame* firstFrame = nsnull;
PRInt32 framesOnLine;
nsRect lineBounds;
PRUint32 lineFlags;
lines->GetLine(0, &firstFrame, &framesOnLine, lineBounds, &lineFlags);
if (firstFrame) {
nsRect rect(0,0,0,0);
firstFrame->GetRect(rect);
const nsStyleFont* font;
firstFrame->GetStyleData(eStyleStruct_Font,
(const nsStyleStruct*&) font);
nsIRenderingContext& rc = *aReflowState.rendContext;
rc.SetFont(font->mFont);
nsIFontMetrics* fm;
nsresult rv = rc.GetFontMetrics(fm);
if (NS_SUCCEEDED(rv) && (nsnull != fm)) {
fm->GetMaxAscent(aDesiredSize.ascent);
NS_RELEASE(fm);
}
rv = NS_OK;
aDesiredSize.ascent += rect.y;
/*
nsHTMLReflowMetrics d(nsnull);
nsHTMLReflowState lineReflowState(aPresContext, reflowState, firstFrame, nsSize(NS_INTRINSICSIZE, NS_INTRINSICSIZE));
lineReflowState.mComputedWidth = rect.width - (lineReflowState.mComputedBorderPadding.left + lineReflowState.mComputedBorderPadding.right);
lineReflowState.mComputedHeight = NS_INTRINSICSIZE;
reason = eReflowReason_Resize;
firstFrame->WillReflow(aPresContext);
firstFrame->Reflow(aPresContext, d, lineReflowState, aStatus);
aDesiredSize.ascent = d.ascent + rect.y + border.top;
*/
}
}
// look at the first child
/*
const nsStyleFont* font;
firstFrame->GetStyleData(eStyleStruct_Font,
(const nsStyleStruct*&) font);
nsIRenderingContext& rc = *aReflowState.mReflowState.rendContext;
rc.SetFont(font->mFont);
nsIFontMetrics* fm;
rv = rc.GetFontMetrics(fm);
if (NS_SUCCEEDED(rv) && (nsnull != fm)) {
fm->GetMaxAscent(aDesiredSize.ascent);
NS_RELEASE(fm);
}
rv = NS_OK;
// add top border and padding to the ascent
nsRect rect(0,0,0,0);
firstFrame->GetRect(&rect);
// now our max ascent is acent + the y offset of the the first child
aDesiredSize.ascent += rect.y;
}
*/
PRBool changedSize = PR_FALSE;
if (mLastSize.width != aDesiredSize.width || mLastSize.height != aDesiredSize.height)
changedSize = PR_TRUE;
// if the child got bigger then make sure the new size in our min max range
if (changedSize) {
// redraw if we changed size.
//aRedraw = PR_TRUE;
}
nsContainerFrame::FinishReflowChild(mFrame, aPresContext, aDesiredSize, aX, aY, NS_FRAME_NO_MOVE_FRAME);
} else {
/*
if (aMoveFrame) {
PlaceChild(aPresContext, mFrame, aX + margin.left, aY + margin.top);
}
*/
}
// add the margin back in. The child should add its border automatically
//aDesiredSize.height += (margin.top + margin.bottom);
//aDesiredSize.width += (margin.left + margin.right);
#ifdef DEBUG_REFLOW
if (aHeight != NS_INTRINSICSIZE && aDesiredSize.height != aHeight)
{
AddIndents();
printf("**** Child ");
nsFrame::ListTag(stdout, childFrame);
printf(" got taller!******\n");
}
if (aWidth != NS_INTRINSICSIZE && aDesiredSize.width != aWidth)
{
AddIndents();
printf("**** Child ");
nsFrame::ListTag(stdout, childFrame);
printf(" got wider!******\n");
}
#endif
if (aWidth == NS_INTRINSICSIZE)
aWidth = aDesiredSize.width;
if (aHeight == NS_INTRINSICSIZE)
aHeight = aDesiredSize.height;
mLastSize.width = aDesiredSize.width;
mLastSize.height = aDesiredSize.height;
if (aDesiredSize.width > aWidth && mMinWidth != aDesiredSize.width) {
mMinWidth = aDesiredSize.width;
SizeNeedsRecalc(mMinSize);
}
return NS_OK;
}
void
nsBoxToBlockAdaptor::PlaceChild(nsIPresContext* aPresContext, nsIFrame* aFrame, nscoord aX, nscoord aY)
{
nsPoint curOrigin;
aFrame->GetOrigin(curOrigin);
// only if the origin changed
if ((curOrigin.x != aX) || (curOrigin.y != aY)) {
aFrame->MoveTo(aPresContext, aX, aY);
nsIView* view;
aFrame->GetView(aPresContext, &view);
if (view) {
nsContainerFrame::PositionFrameView(aPresContext, aFrame, view);
} else
nsContainerFrame::PositionChildViews(aPresContext, aFrame);
}
}
/*
void
nsBoxToBlockAdaptor::BuildReflowChain(nsIFrame* aFrame, nsIFrame* aTargetParent, const nsHTMLReflowState& aRoot, nsHTMLReflowState& aState)
{
nsIFrame* parent;
aFrame->GetParent(parent);
if (aFrame != aTargetParent)
{
BuildReflowChain(parent, aTargetFrame, aRoot, aState);
nsHTMLReflowState state(aPresContext, aRoot, aFrame, nsSize(NS_INTRINSICSIZE, NS_INTRINSICSIZE));
aRoot = state;
}
}
*/
PRBool
nsBoxToBlockAdaptor::GetWasCollapsed(nsBoxLayoutState& aBoxLayoutState)
{
return mWasCollapsed;
}
void
nsBoxToBlockAdaptor::SetWasCollapsed(nsBoxLayoutState& aBoxLayoutState, PRBool aCollapsed)
{
mWasCollapsed = aCollapsed;
}
NS_IMETHODIMP_(nsrefcnt)
nsBoxToBlockAdaptor::AddRef(void)
{
return NS_OK;
}
NS_IMETHODIMP_(nsrefcnt)
nsBoxToBlockAdaptor::Release(void)
{
return NS_OK;
}
//
// QueryInterface
//
NS_INTERFACE_MAP_BEGIN(nsBoxToBlockAdaptor)
NS_INTERFACE_MAP_ENTRY(nsIBoxToBlockAdaptor)
NS_INTERFACE_MAP_END_INHERITING(nsBox)

View File

@@ -0,0 +1,89 @@
/* -*- 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.
*
* Author:
* Eric D Vaughan
*
* Contributor(s):
*/
#ifndef nsBoxToBlockAdaptor_h___
#define nsBoxToBlockAdaptor_h___
#include "nsIBoxToBlockAdaptor.h"
#include "nsBox.h"
class nsSpaceManager;
class nsBoxToBlockAdaptor : public nsBox, nsIBoxToBlockAdaptor {
public:
NS_DECL_ISUPPORTS
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetFlex(nsBoxLayoutState& aBoxLayoutState, nscoord& aFlex);
NS_IMETHOD GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent);
NS_IMETHOD IsCollapsed(nsBoxLayoutState& aBoxLayoutState, PRBool& aCollapsed);
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD GetFrame(nsIFrame** aFrame);
NS_IMETHOD NeedsRecalc();
NS_IMETHOD Recycle(nsIPresShell* aPresShell);
void* operator new(size_t sz, nsIPresShell* aPresShell);
void operator delete(void* aPtr, size_t sz);
nsBoxToBlockAdaptor(nsIPresShell* aShell, nsIFrame* aFrame);
~nsBoxToBlockAdaptor();
protected:
virtual PRBool GetWasCollapsed(nsBoxLayoutState& aState);
virtual void SetWasCollapsed(nsBoxLayoutState& aState, PRBool aWas);
virtual nsresult Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
nscoord aX,
nscoord aY,
nscoord aWidth,
nscoord aHeight,
PRBool aMoveFrame = PR_TRUE);
virtual void PlaceChild(nsIPresContext* aPresContext, nsIFrame* aFrame, nscoord aX, nscoord aY);
nsIFrame* mFrame;
nsSize mPrefSize;
nsSize mMinSize;
nsSize mMaxSize;
nscoord mFlex;
nscoord mAscent;
PRBool mPrefNeedsRecalc;
nsSpaceManager* mSpaceManager;
nsSize mLastSize;
nscoord mMinWidth;
PRBool mWasCollapsed;
};
#endif

View File

@@ -22,7 +22,7 @@
* Contributor(s):
*/
#include "nsCOMPtr.h"
#include "nsXULButtonFrame.h"
#include "nsButtonBoxFrame.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsIDOMXULDocument.h"
@@ -36,13 +36,13 @@
// Creates a new Button frame and returns it in |aNewFrame|
//
nsresult
NS_NewXULButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
NS_NewButtonBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsXULButtonFrame* it = new (aPresShell) nsXULButtonFrame(aPresShell);
nsButtonBoxFrame* it = new (aPresShell) nsButtonBoxFrame(aPresShell);
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
@@ -52,11 +52,11 @@ NS_NewXULButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
} // NS_NewXULButtonFrame
nsXULButtonFrame::nsXULButtonFrame(nsIPresShell* aPresShell)
nsButtonBoxFrame::nsButtonBoxFrame(nsIPresShell* aPresShell)
:nsBoxFrame(aPresShell, PR_FALSE)
{}
NS_IMETHODIMP nsXULButtonFrame::GetFrameForPoint(nsIPresContext* aPresContext,
NS_IMETHODIMP nsButtonBoxFrame::GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame)
@@ -66,7 +66,7 @@ NS_IMETHODIMP nsXULButtonFrame::GetFrameForPoint(nsIPresContext* aPresContext,
}
NS_IMETHODIMP
nsXULButtonFrame::HandleEvent(nsIPresContext* aPresContext,
nsButtonBoxFrame::HandleEvent(nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus)
{
@@ -89,7 +89,7 @@ nsXULButtonFrame::HandleEvent(nsIPresContext* aPresContext,
}
void
nsXULButtonFrame::MouseClicked (nsIPresContext* aPresContext)
nsButtonBoxFrame::MouseClicked (nsIPresContext* aPresContext)
{
// Execute the oncommand event handler.
nsEventStatus status = nsEventStatus_eIgnore;

View File

@@ -21,17 +21,17 @@
*
* Contributor(s):
*/
#ifndef nsXULButtonFrame_h___
#define nsXULButtonFrame_h___
#ifndef nsButtonBoxFrame_h___
#define nsButtonBoxFrame_h___
#include "nsBoxFrame.h"
class nsXULButtonFrame : public nsBoxFrame
class nsButtonBoxFrame : public nsBoxFrame
{
public:
friend nsresult NS_NewXULButtonFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
friend nsresult NS_NewButtonBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
nsXULButtonFrame(nsIPresShell* aPresShell);
nsButtonBoxFrame(nsIPresShell* aPresShell);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
@@ -45,6 +45,6 @@ public:
virtual void MouseClicked (nsIPresContext* aPresContext);
}; // class nsXULButtonFrame
}; // class nsButtonBoxFrame
#endif /* nsXULButtonFrame_h___ */
#endif /* nsButtonBoxFrame_h___ */

View File

@@ -17,12 +17,10 @@
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author: David W. Hyatt (hyatt@netscape.com)
*
* Contributor(s):
*/
#include "nsCOMPtr.h"
#include "nsXULCheckboxFrame.h"
#include "nsCheckBoxFrame.h"
#include "nsIDOMXULCheckboxElement.h"
#include "nsIContent.h"
#include "nsIDOMXULRadioElement.h"
@@ -34,27 +32,31 @@
//
// NS_NewXULCheckboxFrame
// NS_NewCheckBoxFrame
//
// Creates a new checkbox frame and returns it in |aNewFrame|
//
nsresult
NS_NewXULCheckboxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
NS_NewCheckBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsXULCheckboxFrame* it = new (aPresShell) nsXULCheckboxFrame(aPresShell);
nsCheckBoxFrame* it = new (aPresShell) nsCheckBoxFrame (aPresShell);
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
// it->SetFlags(aFlags);
*aNewFrame = it;
return NS_OK;
} // NS_NewXULCheckboxFrame
} // NS_NewCheckBoxFrame
nsXULCheckboxFrame::nsXULCheckboxFrame(nsIPresShell* aPresShell)
:nsXULButtonFrame(aPresShell)
{}
PRIntn nsCheckBoxFrame::GetDefaultAlignment()
{
return NS_SIDE_LEFT;
}
nsCheckBoxFrame::nsCheckBoxFrame(nsIPresShell* aPresShell):nsButtonBoxFrame(aPresShell)
{
}

View File

@@ -17,22 +17,23 @@
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author: David W. Hyatt (hyatt@netscape.com)
*
* Contributor(s):
*/
#ifndef nsXULCheckboxFrame_h___
#define nsXULCheckboxFrame_h___
#ifndef nsCheckBoxFrame_h___
#define nsCheckBoxFrame_h___
#include "nsXULButtonFrame.h"
#include "nsButtonBoxFrame.h"
class nsXULCheckboxFrame : public nsXULButtonFrame
class nsCheckBoxFrame : public nsButtonBoxFrame
{
public:
nsXULCheckboxFrame(nsIPresShell* aPresShell);
friend nsresult NS_NewXULCheckboxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
friend nsresult NS_NewCheckBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
}; // class nsXULCheckboxFrame
PRIntn GetDefaultAlignment();
#endif /* nsXULCheckboxFrame_h___ */
nsCheckBoxFrame(nsIPresShell* aPresShell);
}; // class nsCheckBoxFrame
#endif /* nsCheckBoxFrame_h___ */

View File

@@ -36,6 +36,7 @@
#include "nsIServiceManager.h"
#include "nsStdColorPicker.h"
#include "nsColorPickerCID.h"
#include "nsBoxLayoutState.h"
//
// NS_NewColorPickerFrame
//
@@ -48,7 +49,7 @@ NS_NewColorPickerFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsColorPickerFrame* it = new (aPresShell) nsColorPickerFrame;
nsColorPickerFrame* it = new (aPresShell) nsColorPickerFrame (aPresShell);
if ( !it )
return NS_ERROR_OUT_OF_MEMORY;
*aNewFrame = it;
@@ -60,10 +61,6 @@ NS_NewColorPickerFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
//
// nsColorPickerFrame cntr
//
nsColorPickerFrame::nsColorPickerFrame()
{
}
nsColorPickerFrame::~nsColorPickerFrame()
{
@@ -192,6 +189,28 @@ nsColorPickerFrame::Paint(nsIPresContext* aPresContext,
}
NS_IMETHODIMP
nsColorPickerFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
float p2t;
nsIPresContext* presContext = aBoxLayoutState.GetPresContext();
presContext->GetScaledPixelsToTwips(&p2t);
nsSize pixelSize(0,0);
mColorPicker->GetSize(&pixelSize.width, &pixelSize.height);
aSize.width = nscoord(pixelSize.width * p2t);
aSize.height = nscoord(pixelSize.height * p2t);
AddBorderAndPadding(aSize);
AddInset(aSize);
return NS_OK;
}
/*
//
// GetDesiredSize
//
@@ -202,34 +221,6 @@ nsColorPickerFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aDesiredSize)
{
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
// if the width is set use it
if (NS_INTRINSICSIZE != aReflowState.mComputedWidth)
aDesiredSize.width = aReflowState.mComputedWidth;
else
aDesiredSize.width = -1;
// if the height is set use it
if (NS_INTRINSICSIZE != aReflowState.mComputedHeight)
aDesiredSize.height = aReflowState.mComputedHeight;
else
aDesiredSize.height = -1;
mColorPicker->SetSize((aDesiredSize.width == -1) ? -1 : PRInt32(aDesiredSize.width/p2t),
(aDesiredSize.height == -1) ? -1 : PRInt32(aDesiredSize.height/p2t));
int width, height;
mColorPicker->GetSize(&width, &height);
aDesiredSize.width = nscoord(width * p2t);
aDesiredSize.height = nscoord(height * p2t);
aDesiredSize.ascent = nscoord(height * p2t);
aDesiredSize.descent = 0;
} // GetDesiredSize
*/

View File

@@ -28,7 +28,7 @@
#define nsColorPickerFrame_h__
#include "nsLeafFrame.h"
#include "nsLeafBoxFrame.h"
#include "prtypes.h"
#include "nsIAtom.h"
#include "nsCOMPtr.h"
@@ -40,12 +40,15 @@ class nsString;
nsresult NS_NewColorPickerFrame(nsIPresShell* aPresShell, nsIFrame** aResult) ;
class nsColorPickerFrame : public nsLeafFrame
class nsColorPickerFrame : public nsLeafBoxFrame
{
public:
nsColorPickerFrame();
nsColorPickerFrame(nsIPresShell* aShell):nsLeafBoxFrame(aShell) {}
virtual ~nsColorPickerFrame();
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
@@ -72,10 +75,6 @@ public:
nsFramePaintLayer aWhichLayer);
protected:
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aDesiredSize) ;
private:
nsIColorPicker *mColorPicker;

View File

@@ -0,0 +1,536 @@
/* -*- 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):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
//
// Eric Vaughan
// Netscape Communications
//
// See documentation in associated header file
//
#include "nsBoxLayoutState.h"
#include "nsBox.h"
#include "nsIStyleContext.h"
#include "nsIPresContext.h"
#include "nsCOMPtr.h"
#include "nsIContent.h"
#include "nsIViewManager.h"
#include "nsIView.h"
#include "nsIPresShell.h"
#include "nsHTMLContainerFrame.h"
#include "nsBoxToBlockAdaptor.h"
#include "nsBoxLayoutState.h"
#include "nsBoxFrame.h"
#include "nsIStyleContext.h"
#include "nsIPresContext.h"
#include "nsCOMPtr.h"
#include "nsHTMLIIDs.h"
#include "nsUnitConversion.h"
#include "nsINameSpaceManager.h"
#include "nsHTMLAtoms.h"
#include "nsXULAtoms.h"
#include "nsIReflowCommand.h"
#include "nsIContent.h"
#include "nsSpaceManager.h"
#include "nsHTMLParts.h"
#include "nsIViewManager.h"
#include "nsIView.h"
#include "nsIPresShell.h"
#include "nsGenericHTMLElement.h"
#include "nsFrameNavigator.h"
#include "nsCSSRendering.h"
#include "nsISelfScrollingFrame.h"
#include "nsIPref.h"
#include "nsIServiceManager.h"
#include "nsContainerBox.h"
nsContainerBox::nsContainerBox(nsIPresShell* aShell):nsBox(aShell)
{
mFirstChild = nsnull;
mLastChild = nsnull;
mChildCount = 0;
}
NS_IMETHODIMP
nsContainerBox::GetChildBox(nsIBox** aBox)
{
*aBox = mFirstChild;
return NS_OK;
}
PRInt32
nsContainerBox::GetChildCount()
{
return mChildCount;
}
PRInt32
nsContainerBox::CreateBoxList(nsIPresShell* aPresShell, nsIFrame* aFrameList, nsIBox*& aFirst, nsIBox*& aLast)
{
PRInt32 count = 0;
if (aFrameList) {
nsIBox* ibox = nsnull;
if (NS_SUCCEEDED(aFrameList->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox)
aFirst = ibox;
else
aFirst = new (aPresShell) nsBoxToBlockAdaptor(aPresShell, aFrameList);
aFirst->SetParentBox(this);
count++;
aLast = aFirst;
aFrameList->GetNextSibling(&aFrameList);
nsIBox* last = aLast;
while(aFrameList) {
if (NS_SUCCEEDED(aFrameList->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox)
aLast = ibox;
else
aLast = new (aPresShell) nsBoxToBlockAdaptor(aPresShell, aFrameList);
aLast->SetParentBox(this);
last->SetNextBox(aLast);
last = aLast;
aFrameList->GetNextSibling(&aFrameList);
count++;
}
}
return count;
}
nsIBox*
nsContainerBox::GetPrevious(nsIFrame* aFrame)
{
if (aFrame == nsnull)
return nsnull;
// find the frame to remove
nsIBox* box = mFirstChild;
nsIBox* prev = nsnull;
while (box)
{
nsIFrame* frame = nsnull;
box->GetFrame(&frame);
if (frame == aFrame) {
return prev;
}
prev = box;
box->GetNextBox(&box);
}
return nsnull;
}
nsIBox*
nsContainerBox::GetBox(nsIFrame* aFrame)
{
if (aFrame == nsnull)
return nsnull;
// recycle adaptors
// nsIBox* ibox = nsnull;
// if (NS_SUCCEEDED(aFrame->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox)
// return ibox;
// find the frame to remove
nsIBox* box = mFirstChild;
while (box)
{
nsIFrame* frame = nsnull;
box->GetFrame(&frame);
if (frame == aFrame) {
return box;
}
box->GetNextBox(&box);
}
return nsnull;
}
nsIBox*
nsContainerBox::GetBoxAt(PRInt32 aIndex)
{
// find the frame to remove
nsIBox* child = mFirstChild;
PRInt32 count = 0;
while (child)
{
if (count == aIndex) {
return child;
}
child->GetNextBox(&child);
count++;
}
return nsnull;
}
PRInt32
nsContainerBox::GetIndexOf(nsIBox* aBox)
{
// find the frame to remove
nsIBox* child = mFirstChild;
PRInt32 count = 0;
while (child)
{
if (aBox == child) {
return count;
}
child->GetNextBox(&child);
count++;
}
return -1;
}
void
nsContainerBox::Remove(nsIPresShell* aShell, nsIFrame* aFrame)
{
// get the info before the frame
nsIBox* prevBox = GetPrevious(aFrame);
RemoveAfter(aShell, prevBox);
}
void
nsContainerBox::Insert(nsIPresShell* aShell, nsIFrame* aPrevFrame, nsIFrame* aFrameList)
{
nsIBox* prevBox = GetBox(aPrevFrame);
//NS_ASSERTION(aPrevFrame == nsnull || prevBox,"Error! The previous frame given is not in our list!");
// find the frame before this one
// if no previous frame then we are inserting in front
if (prevBox == nsnull) {
// prepend them
Prepend(aShell, aFrameList);
} else {
// insert insert after previous info
InsertAfter(aShell, prevBox, aFrameList);
}
}
void
nsContainerBox::RemoveAfter(nsIPresShell* aPresShell, nsIBox* aPrevious)
{
nsIBox* toDelete = nsnull;
if (aPrevious == nsnull)
{
NS_ASSERTION(mFirstChild,"Can't find first child");
toDelete = mFirstChild;
if (mLastChild == mFirstChild) {
nsIBox* next = nsnull;
mFirstChild->GetNextBox(&next);
mLastChild = next;
}
mFirstChild->GetNextBox(&mFirstChild);
} else {
aPrevious->GetNextBox(&toDelete);
NS_ASSERTION(toDelete,"Can't find child to delete");
nsIBox* next = nsnull;
toDelete->GetNextBox(&next);
aPrevious->SetNextBox(next);
if (mLastChild == toDelete)
mLastChild = aPrevious;
}
// recycle adaptors
nsIBoxToBlockAdaptor* adaptor = nsnull;
if (NS_SUCCEEDED(toDelete->QueryInterface(NS_GET_IID(nsIBoxToBlockAdaptor), (void**)&adaptor)) && adaptor)
adaptor->Recycle(aPresShell);
mChildCount--;
}
void
nsContainerBox::ClearChildren(nsIPresShell* aShell)
{
nsIBox* box = mFirstChild;
while(box) {
nsIBox* it = box;
box->GetNextBox(&box);
// recycle adaptors
nsIBoxToBlockAdaptor* adaptor = nsnull;
if (NS_SUCCEEDED(it->QueryInterface(NS_GET_IID(nsIBoxToBlockAdaptor), (void**)&adaptor)) && adaptor)
adaptor->Recycle(aShell);
}
mFirstChild= nsnull;
mLastChild= nsnull;
mChildCount = 0;
}
void
nsContainerBox::Prepend(nsIPresShell* aPresShell, nsIFrame* aList)
{
nsIBox* first;
nsIBox* last;
mChildCount += CreateBoxList(aPresShell, aList, first, last);
if (!mFirstChild)
mFirstChild= mLastChild= first;
else {
last->SetNextBox(mFirstChild);
mFirstChild= first;
}
}
void
nsContainerBox::Append(nsIPresShell* aPresShell, nsIFrame* aList)
{
nsIBox* first;
nsIBox* last;
mChildCount += CreateBoxList(aPresShell, aList, first, last);
if (!mFirstChild)
mFirstChild= first;
else
mLastChild->SetNextBox(first);
mLastChild= last;
}
void
nsContainerBox::InsertAfter(nsIPresShell* aPresShell, nsIBox* aPrev, nsIFrame* aList)
{
nsIBox* first = nsnull;
nsIBox* last = nsnull;
mChildCount += CreateBoxList(aPresShell, aList, first, last);
nsIBox* next = nsnull;
aPrev->GetNextBox(&next);
last->SetNextBox(next);
aPrev->SetNextBox(first);
if (aPrev == mLastChild)
mLastChild = last;
}
void
nsContainerBox::InitChildren(nsIPresShell* aPresShell, nsIFrame* aList)
{
ClearChildren(aPresShell);
mChildCount += CreateBoxList(aPresShell, aList, mFirstChild, mLastChild);
}
void
nsContainerBox::SetDebugOnChildList(nsBoxLayoutState& aState, nsIBox* aChild, PRBool aDebug)
{
nsIBox* child = nsnull;
GetChildBox(&child);
while (child)
{
child->SetDebug(aState, aDebug);
child->GetNextBox(&child);
}
}
void
nsContainerBox::SanityCheck(nsFrameList& aFrameList)
{
// make sure the length match
PRInt32 length = aFrameList.GetLength();
NS_ASSERTION(length == mChildCount,"nsBox::ERROR!! Box info list count does not match frame count!!");
// make sure last makes sense
nsIBox* next = nsnull;
NS_ASSERTION(mLastChild == nsnull || (NS_SUCCEEDED(mLastChild->GetNextBox(&next)) && next == nsnull),"nsBox::ERROR!! The last child is not really the last!!!");
nsIFrame* child = aFrameList.FirstChild();
nsIBox* box = mFirstChild;
PRInt32 count = 0;
while(box)
{
NS_ASSERTION(count <= mChildCount,"too many children!!!");
nsIFrame* frame = nsnull;
nsIBox* parent = nsnull;
NS_ASSERTION(NS_SUCCEEDED(box->GetFrame(&frame)) && frame == child,"nsBox::ERROR!! box info list and child info lists don't match!!!");
NS_ASSERTION(NS_SUCCEEDED(box->GetParentBox(&parent)) && parent == this,"nsBox::ERROR!! parent's don't match!!!");
box->GetNextBox(&box);
child->GetNextSibling(&child);
count++;
}
}
NS_IMETHODIMP
nsContainerBox::GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
nsresult rv = NS_OK;
aSize.width = 0;
aSize.height = 0;
// if the size was not completely redefined in CSS then ask our children
if (!nsIBox::AddCSSPrefSize(aBoxLayoutState, this, aSize))
{
aSize.width = 0;
aSize.height = 0;
if (mLayoutManager) {
rv = mLayoutManager->GetPrefSize(this, aBoxLayoutState, aSize);
nsIBox::AddCSSPrefSize(aBoxLayoutState, this, aSize);
} else
rv = nsBox::GetPrefSize(aBoxLayoutState, aSize);
}
nsSize minSize(0,0);
nsSize maxSize(0,0);
GetMinSize(aBoxLayoutState, minSize);
GetMaxSize(aBoxLayoutState, maxSize);
BoundsCheck(minSize, aSize, maxSize);
return rv;
}
NS_IMETHODIMP
nsContainerBox::GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
nsresult rv = NS_OK;
aSize.width = 0;
aSize.height = 0;
// if the size was not completely redefined in CSS then ask our children
if (!nsIBox::AddCSSMinSize(aBoxLayoutState, this, aSize))
{
aSize.width = 0;
aSize.height = 0;
if (mLayoutManager) {
rv = mLayoutManager->GetMinSize(this, aBoxLayoutState, aSize);
nsIBox::AddCSSMinSize(aBoxLayoutState, this, aSize);
} else {
rv = nsBox::GetMinSize(aBoxLayoutState, aSize);
}
}
return rv;
}
NS_IMETHODIMP
nsContainerBox::GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
nsresult rv = NS_OK;
aSize.width = NS_INTRINSICSIZE;
aSize.height = NS_INTRINSICSIZE;
// if the size was not completely redefined in CSS then ask our children
if (!nsIBox::AddCSSMaxSize(aBoxLayoutState, this, aSize))
{
aSize.width = NS_INTRINSICSIZE;
aSize.height = NS_INTRINSICSIZE;
if (mLayoutManager) {
rv = mLayoutManager->GetMaxSize(this, aBoxLayoutState, aSize);
nsIBox::AddCSSMaxSize(aBoxLayoutState, this, aSize);
} else {
rv = nsBox::GetMaxSize(aBoxLayoutState, aSize);
}
}
return rv;
}
NS_IMETHODIMP
nsContainerBox::GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent)
{
nsresult rv = NS_OK;
aAscent = 0;
if (mLayoutManager)
rv = mLayoutManager->GetAscent(this, aBoxLayoutState, aAscent);
else
rv = nsBox::GetAscent(aBoxLayoutState, aAscent);
return rv;
}
NS_IMETHODIMP
nsContainerBox::Layout(nsBoxLayoutState& aBoxLayoutState)
{
nsresult rv = NS_OK;
if (mLayoutManager)
rv = mLayoutManager->Layout(this, aBoxLayoutState);
nsBox::Layout(aBoxLayoutState);
return rv;
}
NS_IMETHODIMP
nsContainerBox::SetLayoutManager(nsIBoxLayout* aLayout)
{
mLayoutManager = aLayout;
return NS_OK;
}
NS_IMETHODIMP
nsContainerBox::GetLayoutManager(nsIBoxLayout** aLayout)
{
*aLayout = mLayoutManager;
return NS_OK;
}
nsresult
nsContainerBox::LayoutChildAt(nsBoxLayoutState& aState, nsIBox* aBox, const nsRect& aRect)
{
// get the current rect
nsRect oldRect(0,0,0,0);
aBox->GetBounds(oldRect);
aBox->SetBounds(aState, aRect);
PRBool dirty = PR_FALSE;
PRBool dirtyChildren = PR_FALSE;
aBox->IsDirty(dirty);
aBox->HasDirtyChildren(dirtyChildren);
PRBool layout = PR_TRUE;
if (!(dirty || dirtyChildren) && aState.GetLayoutReason() != nsBoxLayoutState::Initial)
layout = PR_FALSE;
if (layout || (oldRect.width != aRect.width || oldRect.height != aRect.height)) {
return aBox->Layout(aState);
}
return NS_OK;
}

View File

@@ -0,0 +1,77 @@
/* -*- 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.
*
* Author:
* Eric D Vaughan
*
* Contributor(s):
*/
#ifndef nsContainerBox_h___
#define nsContainerBox_h___
#include "nsBox.h"
#include "nsCOMPtr.h"
#include "nsIBoxLayout.h"
class nsContainerBox : public nsBox {
public:
NS_IMETHOD GetChildBox(nsIBox** aBox);
nsContainerBox(nsIPresShell* aShell);
NS_IMETHOD SetLayoutManager(nsIBoxLayout* aLayout);
NS_IMETHOD GetLayoutManager(nsIBoxLayout** aLayout);
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent);
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
virtual nsIBox* GetBoxAt(PRInt32 aIndex);
virtual nsIBox* GetBox(nsIFrame* aFrame);
virtual PRInt32 GetIndexOf(nsIBox* aBox);
virtual PRInt32 GetChildCount();
virtual void ClearChildren(nsIPresShell* aShell);
virtual PRInt32 CreateBoxList(nsIPresShell* aShell, nsIFrame* aList, nsIBox*& first, nsIBox*& last);
virtual void RemoveAfter(nsIPresShell* aShell, nsIBox* aPrev);
virtual void Remove(nsIPresShell* aShell, nsIFrame* aChild);
virtual void Prepend(nsIPresShell* aShell, nsIFrame* aList);
virtual void Append(nsIPresShell* aShell, nsIFrame* aList);
virtual void Insert(nsIPresShell* aShell, nsIFrame* aPrevFrame, nsIFrame* aList);
virtual void InsertAfter(nsIPresShell* aShell, nsIBox* aPrev, nsIFrame* aList);
virtual void InitChildren(nsIPresShell* aShell, nsIFrame* aList);
virtual nsIBox* GetPrevious(nsIFrame* aChild);
virtual void SanityCheck(nsFrameList& aFrameList);
virtual void SetDebugOnChildList(nsBoxLayoutState& aState, nsIBox* aChild, PRBool aDebug);
protected:
virtual nsresult LayoutChildAt(nsBoxLayoutState& aState, nsIBox* aBox, const nsRect& aRect);
nsIBox* mFirstChild;
nsIBox* mLastChild;
PRInt32 mChildCount;
nsCOMPtr<nsIBoxLayout> mLayoutManager;
};
#endif

View File

@@ -43,7 +43,8 @@
#include "nsStyleChangeList.h"
#include "nsCSSRendering.h"
#include "nsIViewManager.h"
#include "nsBoxLayoutState.h"
#include "nsStackLayout.h"
nsresult
NS_NewDeckFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
@@ -56,14 +57,21 @@ NS_NewDeckFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
*aNewFrame = it;
return NS_OK;
} // NS_NewDeckFrame
nsDeckFrame::nsDeckFrame(nsIPresShell* aPresShell):nsStackFrame(aPresShell)
nsCOMPtr<nsIBoxLayout> nsDeckFrame::gLayout = nsnull;
nsDeckFrame::nsDeckFrame(nsIPresShell* aPresShell):nsBoxFrame(aPresShell)
{
if (!gLayout)
gLayout = new nsStackLayout(aPresShell);
SetLayoutManager(gLayout);
}
NS_IMETHODIMP
@@ -73,49 +81,14 @@ nsDeckFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIAtom* aAttribute,
PRInt32 aHint)
{
nsresult rv = nsStackFrame::AttributeChanged(aPresContext, aChild,
nsresult rv = nsBoxFrame::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;
nsBoxLayoutState state(aPresContext);
MarkDirty(state);
}
return NS_OK;
@@ -154,11 +127,11 @@ nsDeckFrame::Paint(nsIPresContext* aPresContext,
// if a tab is hidden all its children are too.
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisibleOrCollapsed())
if (!disp->mVisible)
return NS_OK;
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
if (disp->IsVisibleOrCollapsed() && mRect.width && mRect.height) {
if (disp->IsVisible() && mRect.width && mRect.height) {
// Paint our background and border
PRIntn skipSides = GetSkipSides();
const nsStyleColor* color = (const nsStyleColor*)
@@ -189,41 +162,30 @@ NS_IMETHODIMP nsDeckFrame::GetFrameForPoint(nsIPresContext* aPresContext,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame)
{
// If it's not in this frame, then it's not going to be in any
// children (since there cannot be overflowing children).
// if it is not inside us fail
if (!mRect.Contains(aPoint)) {
return NS_ERROR_FAILURE;
}
// 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();
nsPoint tmp;
tmp.MoveTo(aPoint.x - mRect.x, aPoint.y - mRect.y);
if (nsnull != selectedFrame)
{
// adjust the point
nsPoint p = aPoint;
p.x -= mRect.x;
p.y -= mRect.y;
return selectedFrame->GetFrameForPoint(aPresContext, p, aWhichLayer, aFrame);
return selectedFrame->GetFrameForPoint(aPresContext, tmp, aWhichLayer, aFrame);
}
if (aWhichLayer == NS_FRAME_PAINT_LAYER_BACKGROUND) {
// if its not in our child just return us.
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->IsVisible()) {
*aFrame = this;
return NS_OK;
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDeckFrame::DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus)
nsDeckFrame::Layout(nsBoxLayoutState& aState)
{
int index = 0;
@@ -237,21 +199,34 @@ nsDeckFrame::DidReflow(nsIPresContext* aPresContext,
index = value.ToInteger(&error);
}
nsresult rv = nsBoxFrame::DidReflow(aPresContext, aStatus);
NS_ASSERTION(rv == NS_OK,"DidReflow failed");
nsIBox* box = nsnull;
GetChildBox(&box);
nsIFrame* childFrame = mFrames.FirstChild();
nscoord count = 0;
while (nsnull != childFrame)
while (nsnull != box)
{
// make collapsed children not show up
if (index == count)
box->UnCollapse(aState);
nsresult rv2 = box->GetNextBox(&box);
NS_ASSERTION(rv2 == NS_OK,"failed to get next child");
count++;
}
nsresult rv = nsBoxFrame::Layout(aState);
GetChildBox(&box);
count = 0;
while (nsnull != box)
{
// make collapsed children not show up
if (index != count)
CollapseChild(aPresContext, childFrame, PR_TRUE);
else
CollapseChild(aPresContext, childFrame, PR_FALSE);
box->Collapse(aState);
rv = childFrame->GetNextSibling(&childFrame);
NS_ASSERTION(rv == NS_OK,"failed to get next child");
nsresult rv2 = box->GetNextBox(&box);
NS_ASSERTION(rv2 == NS_OK,"failed to get next child");
count++;
}

View File

@@ -31,9 +31,9 @@
#ifndef nsDeckFrame_h___
#define nsDeckFrame_h___
#include "nsStackFrame.h"
#include "nsBoxFrame.h"
class nsDeckFrame : public nsStackFrame
class nsDeckFrame : public nsBoxFrame
{
public:
@@ -47,8 +47,7 @@ public:
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus);
NS_IMETHOD Layout(nsBoxLayoutState& aState);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@@ -75,6 +74,7 @@ protected:
private:
static nsCOMPtr<nsIBoxLayout> gLayout;
nsIFrame* mSelected;
}; // class nsDeckFrame

View File

@@ -30,10 +30,14 @@
#include "nsFrameNavigator.h"
#include "nsCOMPtr.h"
#include "nsIContent.h"
#include "nsIBox.h"
nsIAtom*
nsFrameNavigator::GetTag(nsIFrame* frame)
nsFrameNavigator::GetTag(nsIBox* aBox)
{
nsIFrame* frame = nsnull;
aBox->GetFrame(&frame);
nsCOMPtr<nsIContent> content;
frame->GetContent(getter_AddRefs(content));
if (content) {
@@ -45,11 +49,11 @@ nsFrameNavigator::GetTag(nsIFrame* frame)
return nsnull;
}
nsIFrame*
nsFrameNavigator::GetChildBeforeAfter(nsIPresContext* aPresContext, nsIFrame* start, PRBool before)
nsIBox*
nsFrameNavigator::GetChildBeforeAfter(nsIPresContext* aPresContext, nsIBox* start, PRBool before)
{
nsIFrame* parent = nsnull;
start->GetParent(&parent);
nsIBox* parent = nsnull;
start->GetParentBox(&parent);
PRInt32 index = IndexOf(aPresContext, parent,start);
PRInt32 count = CountFrames(aPresContext, parent);
@@ -72,18 +76,18 @@ nsFrameNavigator::GetChildBeforeAfter(nsIPresContext* aPresContext, nsIFrame* st
}
PRInt32
nsFrameNavigator::IndexOf(nsIPresContext* aPresContext, nsIFrame* parent, nsIFrame* child)
nsFrameNavigator::IndexOf(nsIPresContext* aPresContext, nsIBox* parent, nsIBox* child)
{
PRInt32 count = 0;
nsIFrame* childFrame;
parent->FirstChild(aPresContext, nsnull, &childFrame);
while (nsnull != childFrame)
nsIBox* box = nsnull;
parent->GetChildBox(&box);
while (nsnull != box)
{
if (childFrame == child)
if (box == child)
return count;
nsresult rv = childFrame->GetNextSibling(&childFrame);
nsresult rv = box->GetNextBox(&box);
NS_ASSERTION(rv == NS_OK,"failed to get next child");
count++;
}
@@ -92,15 +96,15 @@ nsFrameNavigator::IndexOf(nsIPresContext* aPresContext, nsIFrame* parent, nsIFra
}
PRInt32
nsFrameNavigator::CountFrames(nsIPresContext* aPresContext, nsIFrame* aFrame)
nsFrameNavigator::CountFrames(nsIPresContext* aPresContext, nsIBox* aBox)
{
PRInt32 count = 0;
nsIFrame* childFrame;
aFrame->FirstChild(aPresContext, nsnull, &childFrame);
while (nsnull != childFrame)
nsIBox* box;
aBox->GetChildBox(&box);
while (nsnull != box)
{
nsresult rv = childFrame->GetNextSibling(&childFrame);
nsresult rv = box->GetNextBox(&box);
NS_ASSERTION(rv == NS_OK,"failed to get next child");
count++;
}
@@ -108,19 +112,19 @@ nsFrameNavigator::CountFrames(nsIPresContext* aPresContext, nsIFrame* aFrame)
return count;
}
nsIFrame*
nsFrameNavigator::GetChildAt(nsIPresContext* aPresContext, nsIFrame* parent, PRInt32 index)
nsIBox*
nsFrameNavigator::GetChildAt(nsIPresContext* aPresContext, nsIBox* parent, PRInt32 index)
{
PRInt32 count = 0;
nsIFrame* childFrame;
parent->FirstChild(aPresContext, nsnull, &childFrame);
while (nsnull != childFrame)
nsIBox* box;
parent->GetChildBox(&box);
while (nsnull != box)
{
if (count == index)
return childFrame;
return box;
nsresult rv = childFrame->GetNextSibling(&childFrame);
nsresult rv = box->GetNextBox(&box);
NS_ASSERTION(rv == NS_OK,"failed to get next child");
count++;
}

View File

@@ -31,16 +31,17 @@
#define nsGrippyFrame_h___
#include "nsIFrame.h"
class nsIBox;
class nsFrameNavigator
{
public:
static nsIFrame* GetChildBeforeAfter(nsIPresContext* aPresContext, nsIFrame* start, PRBool before);
static nsIFrame* GetChildAt(nsIPresContext* aPresContext, nsIFrame* parent, PRInt32 index);
static PRInt32 IndexOf(nsIPresContext* aPresContext, nsIFrame* parent, nsIFrame* child);
static PRInt32 CountFrames(nsIPresContext* aPresContext, nsIFrame* aFrame);
static nsIAtom* GetTag(nsIFrame* frame);
static nsIBox* GetChildBeforeAfter(nsIPresContext* aPresContext, nsIBox* start, PRBool before);
static nsIBox* GetChildAt(nsIPresContext* aPresContext, nsIBox* parent, PRInt32 index);
static PRInt32 IndexOf(nsIPresContext* aPresContext, nsIBox* parent, nsIBox* child);
static PRInt32 CountFrames(nsIPresContext* aPresContext, nsIBox* aFrame);
static nsIAtom* GetTag(nsIBox* frame);
};

View File

@@ -62,7 +62,7 @@ NS_NewGrippyFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsGrippyFrame* it = new (aPresShell) nsGrippyFrame;
nsGrippyFrame* it = new (aPresShell) nsGrippyFrame (aPresShell);
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
@@ -71,7 +71,7 @@ NS_NewGrippyFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
} // NS_NewGrippyFrame
nsGrippyFrame::nsGrippyFrame():mCollapsed(PR_FALSE)
nsGrippyFrame::nsGrippyFrame(nsIPresShell* aShell):nsTitledButtonFrame(aShell),mCollapsed(PR_FALSE)
{
}

View File

@@ -47,7 +47,7 @@ public:
static nsIFrame* GetChildAt(nsIPresContext* aPresContext, nsIFrame* parent, PRInt32 index);
static PRInt32 IndexOf(nsIPresContext* aPresContext, nsIFrame* parent, nsIFrame* child);
static PRInt32 CountFrames(nsIPresContext* aPresContext, nsIFrame* aFrame);
nsGrippyFrame();
nsGrippyFrame(nsIPresShell* aShell);
protected:
virtual void MouseClicked(nsIPresContext* aPresContext);

View File

@@ -59,6 +59,9 @@ public:
nsIAtom* aListName,
nsIFrame* aChildList);
NS_IMETHOD GetBorderAndPadding(nsMargin& aBorderAndPadding);
NS_METHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
@@ -81,11 +84,6 @@ public:
}
#endif
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
virtual PRBool GetInitialOrientation(PRBool& aHorizontal) { aHorizontal = PR_FALSE; return PR_TRUE; }
nsIFrame* GetTitleFrame(nsIPresContext* aPresContext, nsRect& aRect);
@@ -322,27 +320,10 @@ nsTitledBoxFrame::GetContentFrame(nsIPresContext* aPresContext)
}
NS_IMETHODIMP
nsTitledBoxFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
nsTitledBoxFrame::GetBorderAndPadding(nsMargin& aBorderAndPadding)
{
if (aReflowState.mComputedBorderPadding.top != 0)
{
nsHTMLReflowState newState(aReflowState);
if (newState.mComputedHeight != NS_INTRINSICSIZE)
newState.mComputedHeight += aReflowState.mComputedBorderPadding.top;
// remove the border from border padding
((nsMargin&)newState.mComputedBorderPadding).top = 0;
((nsMargin&)newState.mComputedPadding).top = 0;
// reflow us again with the correct values.
return Reflow(aPresContext, aDesiredSize, newState, aStatus);
}
return nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
aBorderAndPadding.SizeTo(0,0,0,0);
return NS_OK;
}
NS_IMETHODIMP

View File

@@ -31,27 +31,15 @@
#ifndef nsIBox_h___
#define nsIBox_h___
class nsIPresContext;
class nsIFrame;
struct nsHTMLReflowState;
class nsBoxInfo;
#include "nsISupports.h"
#include "nsIBoxLayout.h"
// {02A560C0-01BF-11d3-B35C-00A0CC3C1CDE}
#define NS_IBOX_IID { 0x2a560c0, 0x1bf, 0x11d3, { 0xb3, 0x5c, 0x0, 0xa0, 0xcc, 0x3c, 0x1c, 0xde } }
class nsBoxLayoutState;
struct nsRect;
struct nsSize;
class nsBoxInfo {
public:
nsSize prefSize;
nsSize minSize;
nsSize maxSize;
PRInt32 flex;
nscoord ascent;
nsBoxInfo();
virtual void Clear();
virtual ~nsBoxInfo();
};
// {162F6B5A-F926-11d3-BA06-001083023C1E}
#define NS_IBOX_IID { 0x162f6b5a, 0xf926, 0x11d3, { 0xba, 0x6, 0x0, 0x10, 0x83, 0x2, 0x3c, 0x1e } }
class nsIBox : public nsISupports {
@@ -59,19 +47,63 @@ public:
static const nsIID& GetIID() { static nsIID iid = NS_IBOX_IID; return iid; }
/** Get the layout information object for this box. It will contains things like flexiblity,
* preferred, min, max sizes.
*/
NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize)=0;
enum Halignment {
hAlign_Left,
hAlign_Right,
hAlign_Center
};
/** clear any cached layout info about our children. If the child is specifically specified
* then only clear cached layout information for that specific child. If the child is not
* then clear all childrens cached information.
*/
NS_IMETHOD InvalidateCache(nsIFrame* aChild)=0;
enum Valignment {
vAlign_Top,
vAlign_Middle,
vAlign_BaseLine,
vAlign_Bottom
};
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)=0;
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)=0;
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)=0;
NS_IMETHOD GetFlex(nsBoxLayoutState& aBoxLayoutState, nscoord& aFlex)=0;
NS_IMETHOD GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent)=0;
NS_IMETHOD IsCollapsed(nsBoxLayoutState& aBoxLayoutState, PRBool& aCollapsed)=0;
NS_IMETHOD Collapse(nsBoxLayoutState& aBoxLayoutState)=0;
NS_IMETHOD UnCollapse(nsBoxLayoutState& aBoxLayoutState)=0;
NS_IMETHOD SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect)=0;
NS_IMETHOD GetBounds(nsRect& aRect)=0;
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState)=0;
NS_IMETHOD IsDirty(PRBool& aIsDirty)=0;
NS_IMETHOD HasDirtyChildren(PRBool& aIsDirty)=0;
NS_IMETHOD MarkDirty(nsBoxLayoutState& aState)=0;
NS_IMETHOD MarkDirtyChildren(nsBoxLayoutState& aState)=0;
NS_IMETHOD SetDebug(nsBoxLayoutState& aState, PRBool aDebug)=0;
NS_IMETHOD GetDebug(PRBool& aDebug)=0;
NS_IMETHOD GetChildBox(nsIBox** aBox)=0;
NS_IMETHOD GetNextBox(nsIBox** aBox)=0;
NS_IMETHOD SetNextBox(nsIBox* aBox)=0;
NS_IMETHOD GetParentBox(nsIBox** aParent)=0;
NS_IMETHOD SetParentBox(nsIBox* aParent)=0;
NS_IMETHOD GetFrame(nsIFrame** aFrame)=0;
NS_IMETHOD GetBorderAndPadding(nsMargin& aBorderAndPadding)=0;
NS_IMETHOD GetBorder(nsMargin& aBorderAndPadding)=0;
NS_IMETHOD GetPadding(nsMargin& aBorderAndPadding)=0;
NS_IMETHOD GetInset(nsMargin& aInset)=0;
NS_IMETHOD GetMargin(nsMargin& aMargin)=0;
NS_IMETHOD SetLayoutManager(nsIBoxLayout* aLayout)=0;
NS_IMETHOD GetLayoutManager(nsIBoxLayout** aLayout)=0;
NS_IMETHOD GetContentRect(nsRect& aContentRect) = 0;
NS_IMETHOD GetClientRect(nsRect& aContentRect) = 0;
NS_IMETHOD GetVAlign(Valignment& aAlign) = 0;
NS_IMETHOD GetHAlign(Halignment& aAlign) = 0;
NS_IMETHOD GetOrientation(PRBool& aIsHorizontal)=0;
NS_IMETHOD Redraw(nsBoxLayoutState& aState, const nsRect* aRect = nsnull, PRBool aImmediate = PR_FALSE)=0;
NS_IMETHOD NeedsRecalc()=0;
NS_IMETHOD GetDebugBoxAt(const nsPoint& aPoint, nsIBox** aBox)=0;
NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug)=0;
static PRBool AddCSSPrefSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize);
static PRBool AddCSSMinSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize);
static PRBool AddCSSMaxSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize);
static PRBool AddCSSFlex(nsBoxLayoutState& aState, nsIBox* aBox, nscoord& aFlex);
static PRBool AddCSSCollapsed(nsBoxLayoutState& aState, nsIBox* aBox, PRBool& aCollapsed);
};

View File

@@ -0,0 +1,447 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 "nsImageBoxFrame.h"
#include "nsIDeviceContext.h"
#include "nsIFontMetrics.h"
#include "nsHTMLAtoms.h"
#include "nsXULAtoms.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsCOMPtr.h"
#include "nsIPresContext.h"
#include "nsButtonFrameRenderer.h"
#include "nsBoxLayoutState.h"
#include "nsHTMLParts.h"
#include "nsString.h"
#include "nsLeafFrame.h"
#include "nsIPresContext.h"
#include "nsIRenderingContext.h"
#include "nsIPresShell.h"
#include "nsHTMLIIDs.h"
#include "nsIImage.h"
#include "nsIWidget.h"
#include "nsHTMLAtoms.h"
#include "nsIHTMLAttributes.h"
#include "nsIDocument.h"
#include "nsIHTMLDocument.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsImageMap.h"
#include "nsILinkHandler.h"
#include "nsIURL.h"
#include "nsIView.h"
#include "nsIViewManager.h"
#include "nsHTMLContainerFrame.h"
#include "prprf.h"
#include "nsISizeOfHandler.h"
#include "nsIFontMetrics.h"
#include "nsCSSRendering.h"
#include "nsIDOMHTMLImageElement.h"
#include "nsIDeviceContext.h"
#include "nsINameSpaceManager.h"
#include "nsTextFragment.h"
#include "nsIDOMHTMLMapElement.h"
#include "nsIStyleSet.h"
#include "nsIStyleContext.h"
#include "nsBoxLayoutState.h"
#include "nsFormControlHelper.h"
#define ONLOAD_CALLED_TOO_EARLY 1
nsresult
nsImageBoxFrame::UpdateImageFrame(nsIPresContext* aPresContext,
nsHTMLImageLoader* aLoader,
nsIFrame* aFrame,
void* aClosure,
PRUint32 aStatus)
{
if (NS_IMAGE_LOAD_STATUS_SIZE_AVAILABLE & aStatus) {
nsImageBoxFrame* us = (nsImageBoxFrame*)aFrame;
nsBoxLayoutState state(aPresContext);
us->MarkDirty(state);
}
return NS_OK;
}
//
// NS_NewToolbarFrame
//
// Creates a new Toolbar frame and returns it in |aNewFrame|
//
nsresult
NS_NewImageBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsImageBoxFrame* it = new (aPresShell) nsImageBoxFrame (aPresShell);
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
*aNewFrame = it;
return NS_OK;
} // NS_NewTitledButtonFrame
NS_IMETHODIMP
nsImageBoxFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint)
{
PRBool aResize;
PRBool aRedraw;
UpdateAttributes(aPresContext, aAttribute, aResize, aRedraw);
nsBoxLayoutState state(aPresContext);
if (aResize) {
MarkDirty(state);
} else if (aRedraw) {
Redraw(state);
}
return NS_OK;
}
nsImageBoxFrame::nsImageBoxFrame(nsIPresShell* aShell):nsLeafBoxFrame(aShell)
{
mSizeFrozen = PR_FALSE;
mHasImage = PR_FALSE;
NeedsRecalc();
}
nsImageBoxFrame::~nsImageBoxFrame()
{
}
NS_IMETHODIMP
nsImageBoxFrame::NeedsRecalc()
{
SizeNeedsRecalc(mImageSize);
return NS_OK;
}
NS_METHOD
nsImageBoxFrame::Destroy(nsIPresContext* aPresContext)
{
// Release image loader first so that it's refcnt can go to zero
mImageLoader.StopAllLoadImages(aPresContext);
return nsLeafBoxFrame::Destroy(aPresContext);
}
NS_IMETHODIMP
nsImageBoxFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsLeafBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mHasImage = PR_FALSE;
// Always set the image loader's base URL, because someone may
// decide to change a button _without_ an image to have an image
// later.
nsIURI* baseURL = nsnull;
nsIHTMLContent* htmlContent;
if (NS_SUCCEEDED(mContent->QueryInterface(kIHTMLContentIID, (void**)&htmlContent))) {
htmlContent->GetBaseURL(baseURL);
NS_RELEASE(htmlContent);
}
else {
nsIDocument* doc;
if (NS_SUCCEEDED(mContent->GetDocument(doc))) {
doc->GetBaseURL(baseURL);
NS_RELEASE(doc);
}
}
// Initialize the image loader. Make sure the source is correct so
// that UpdateAttributes doesn't double start an image load.
nsAutoString src;
GetImageSource(src);
if (!src.Equals("")) {
mHasImage = PR_TRUE;
}
mImageLoader.Init(this, UpdateImageFrame, nsnull, baseURL, src);
NS_IF_RELEASE(baseURL);
PRBool a,b;
UpdateAttributes(aPresContext, nsnull, a, b);
return rv;
}
void
nsImageBoxFrame::GetImageSource(nsString& aResult)
{
// get the new image src
mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::src, aResult);
// if the new image is empty
if (aResult.Equals("")) {
// get the list-style-image
const nsStyleList* myList =
(const nsStyleList*)mStyleContext->GetStyleData(eStyleStruct_List);
if (myList->mListStyleImage.Length() > 0) {
aResult = myList->mListStyleImage;
}
}
}
void
nsImageBoxFrame::UpdateAttributes(nsIPresContext* aPresContext, nsIAtom* aAttribute, PRBool& aResize, PRBool& aRedraw)
{
aResize = PR_FALSE;
aRedraw = PR_FALSE;
if (aAttribute == nsnull || aAttribute == nsHTMLAtoms::src) {
UpdateImage(aPresContext, aResize);
}
}
void
nsImageBoxFrame::UpdateImage(nsIPresContext* aPresContext, PRBool& aResize)
{
aResize = PR_FALSE;
// see if the source changed
// get the old image src
nsAutoString oldSrc ="";
mImageLoader.GetURLSpec(oldSrc);
// get the new image src
nsAutoString src;
GetImageSource(src);
// see if the images are different
if (!oldSrc.Equals(src)) {
if (!src.Equals("")) {
mSizeFrozen = PR_FALSE;
mHasImage = PR_TRUE;
} else {
mSizeFrozen = PR_TRUE;
mHasImage = PR_FALSE;
}
mImageLoader.UpdateURLSpec(aPresContext, src);
aResize = PR_TRUE;
}
}
NS_IMETHODIMP
nsImageBoxFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisible())
return NS_OK;
nsresult rv = nsLeafBoxFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
nsRect rect (0,0, mRect.width, mRect.height);
PaintImage(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
return rv;
}
NS_IMETHODIMP
nsImageBoxFrame::PaintImage(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
if ((0 == mRect.width) || (0 == mRect.height)) {
// Do not render when given a zero area. This avoids some useless
// scaling work while we wait for our image dimensions to arrive
// asynchronously.
return NS_OK;
}
nsRect rect;
GetClientRect(rect);
// don't draw if the image is not dirty
if (!mHasImage || !aDirtyRect.Intersects(rect))
return NS_OK;
if (NS_FRAME_PAINT_LAYER_FOREGROUND != aWhichLayer)
return NS_OK;
nsCOMPtr<nsIImage> image ( dont_AddRef(mImageLoader.GetImage()) );
if ( !image ) {
}
else {
// Now render the image into our content area (the area inside the
// borders and padding)
aRenderingContext.DrawImage(image, rect);
}
return NS_OK;
}
//
// DidSetStyleContext
//
// When the style context changes, make sure that all of our image is up to date.
//
NS_IMETHODIMP
nsImageBoxFrame :: DidSetStyleContext( nsIPresContext* aPresContext )
{
// if list-style-image change we want to change the image
PRBool aResize;
UpdateImage(aPresContext, aResize);
return NS_OK;
} // DidSetStyleContext
void
nsImageBoxFrame::GetImageSize(nsIPresContext* aPresContext)
{
nsSize s(0,0);
nsHTMLReflowMetrics desiredSize(&s);
const PRInt32 kDefaultSize = 0;
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
const PRInt32 kDefaultSizeInTwips = NSIntPixelsToTwips(kDefaultSize, p2t);
// not calculated? Get the intrinsic size
if (mHasImage) {
// get the size of the image and set the desired size
if (mSizeFrozen) {
mImageSize.width = kDefaultSizeInTwips;
mImageSize.height = kDefaultSizeInTwips;
return;
} else {
// Ask the image loader for the *intrinsic* image size
mImageLoader.GetDesiredSize(aPresContext, nsnull, desiredSize);
if (desiredSize.width == 1 || desiredSize.height == 1)
{
mImageSize.width = kDefaultSizeInTwips;
mImageSize.height = kDefaultSizeInTwips;
return;
}
}
}
mImageSize.width = desiredSize.width;
mImageSize.height = desiredSize.height;
}
/**
* Ok return our dimensions
*/
NS_IMETHODIMP
nsImageBoxFrame::Layout(nsBoxLayoutState& aState)
{
return nsLeafBoxFrame::Layout(aState);
}
/**
* Ok return our dimensions
*/
NS_IMETHODIMP
nsImageBoxFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
{
if (DoesNeedRecalc(mImageSize)) {
CacheImageSize(aState);
}
aSize = mImageSize;
AddBorderAndPadding(aSize);
AddInset(aSize);
nsIBox::AddCSSPrefSize(aState, this, aSize);
return NS_OK;
}
/**
* Ok return our dimensions
*/
NS_IMETHODIMP
nsImageBoxFrame::GetMinSize(nsBoxLayoutState& aState, nsSize& aSize)
{
if (DoesNeedRecalc(mImageSize)) {
CacheImageSize(aState);
}
aSize = mImageSize;
AddBorderAndPadding(aSize);
AddInset(aSize);
nsIBox::AddCSSMinSize(aState, this, aSize);
return NS_OK;
}
NS_IMETHODIMP
nsImageBoxFrame::GetAscent(nsBoxLayoutState& aState, nscoord& aCoord)
{
nsSize size(0,0);
GetPrefSize(aState, size);
aCoord = size.height;
return NS_OK;
}
/**
* Ok return our dimensions
*/
void
nsImageBoxFrame::CacheImageSize(nsBoxLayoutState& aState)
{
nsIPresContext* presContext = aState.GetPresContext();
GetImageSize(presContext);
}
NS_IMETHODIMP
nsImageBoxFrame::GetFrameName(nsString& aResult) const
{
aResult = "ImageBox";
return NS_OK;
}

View File

@@ -0,0 +1,102 @@
/* -*- 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):
*/
#ifndef nsImageBoxFrame_h___
#define nsImageBoxFrame_h___
#include "nsHTMLImageLoader.h"
#include "nsLeafBoxFrame.h"
class nsImageBoxFrame : public nsLeafBoxFrame
{
public:
// nsIBox
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent);
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD NeedsRecalc();
friend nsresult NS_NewImageBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
// nsIBox frame interface
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* asPrevInFlow);
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD DidSetStyleContext (nsIPresContext* aPresContext);
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
NS_IMETHOD GetFrameName(nsString& aResult) const;
virtual void UpdateAttributes(nsIPresContext* aPresContext, nsIAtom* aAttribute, PRBool& aResize, PRBool& aRedraw);
virtual void UpdateImage(nsIPresContext* aPresContext, PRBool& aResize);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
~nsImageBoxFrame();
protected:
void CacheImageSize(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD PaintImage(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
nsImageBoxFrame(nsIPresShell* aShell);
static nsresult UpdateImageFrame(nsIPresContext* aPresContext,
nsHTMLImageLoader* aLoader,
nsIFrame* aFrame,
void* aClosure,
PRUint32 aStatus);
void GetImageSource(nsString& aResult);
virtual void GetImageSize(nsIPresContext* aPresContext);
private:
nsHTMLImageLoader mImageLoader;
PRBool mSizeFrozen;
nsSize mImageSize;
PRBool mHasImage;
}; // class nsImageBoxFrame
#endif /* nsImageBoxFrame_h___ */

View File

@@ -0,0 +1,246 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 "nsLeafBoxFrame.h"
#include "nsBoxFrame.h"
#include "nsCOMPtr.h"
#include "nsIDeviceContext.h"
#include "nsIFontMetrics.h"
#include "nsHTMLAtoms.h"
#include "nsXULAtoms.h"
#include "nsIPresContext.h"
#include "nsIRenderingContext.h"
#include "nsIStyleContext.h"
#include "nsIContent.h"
#include "nsINameSpaceManager.h"
#include "nsBoxLayoutState.h"
//
// NS_NewToolbarFrame
//
// Creates a new Toolbar frame and returns it in |aNewFrame|
//
nsresult
NS_NewLeafBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsLeafBoxFrame* it = new (aPresShell) nsLeafBoxFrame(aPresShell);
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
// it->SetFlags(aFlags);
*aNewFrame = it;
return NS_OK;
} // NS_NewTextFrame
nsLeafBoxFrame::nsLeafBoxFrame(nsIPresShell* aShell):nsBox(aShell)
{
}
/**
* Initialize us. This is a good time to get the alignment of the box
*/
NS_IMETHODIMP
nsLeafBoxFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsLeafFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mMouseThrough = sometimes;
if (mContent) {
nsAutoString value;
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::mousethrough, value)) {
if (value.EqualsIgnoreCase("never"))
mMouseThrough = never;
else if (value.EqualsIgnoreCase("always"))
mMouseThrough = always;
}
}
return rv;
}
NS_IMETHODIMP
nsLeafBoxFrame::GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame)
{
if (!mRect.Contains(aPoint))
return NS_ERROR_FAILURE;
if (mMouseThrough != never)
{
*aFrame = this;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsLeafBoxFrame::GetFrame(nsIFrame** aFrame)
{
*aFrame = this;
return NS_OK;
}
NS_IMETHODIMP
nsLeafBoxFrame::DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus)
{
PRBool isDirty = mState & NS_FRAME_IS_DIRTY;
PRBool hasDirtyChildren = mState & NS_FRAME_HAS_DIRTY_CHILDREN;
nsresult rv = nsFrame::DidReflow(aPresContext, aStatus);
if (isDirty)
mState |= NS_FRAME_IS_DIRTY;
if (hasDirtyChildren)
mState |= NS_FRAME_HAS_DIRTY_CHILDREN;
return rv;
}
NS_IMETHODIMP
nsLeafBoxFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
NS_ASSERTION(aReflowState.mComputedWidth >=0 && aReflowState.mComputedHeight >= 0, "Computed Size < 0");
aStatus = NS_FRAME_COMPLETE;
// create the layout state
nsBoxLayoutState state(aPresContext, aReflowState);
state.HandleReflow(this, PR_FALSE);
nsSize computedSize(aReflowState.mComputedWidth,aReflowState.mComputedHeight);
nsMargin m;
GetBorderAndPadding(m);
// this happens sometimes. So lets handle it gracefully.
if (aReflowState.mComputedHeight == 0) {
nsSize minSize(0,0);
GetMinSize(state, minSize);
computedSize.height = minSize.height - m.top - m.bottom;
}
// if we are told to layout intrinic then get our preferred size.
if (computedSize.width == NS_INTRINSICSIZE || computedSize.height == NS_INTRINSICSIZE) {
nsSize prefSize;
nsSize minSize;
nsSize maxSize;
GetPrefSize(state, prefSize);
GetMinSize(state, minSize);
GetMaxSize(state, maxSize);
BoundsCheck(minSize, prefSize, maxSize);
// get our desiredSize
if (aReflowState.mComputedWidth == NS_INTRINSICSIZE)
computedSize.width = prefSize.width - m.left - m.right;
if (aReflowState.mComputedHeight == NS_INTRINSICSIZE || aReflowState.mComputedHeight == 0)
computedSize.height = prefSize.height - m.top - m.bottom;
}
nsRect r(0,0,computedSize.width, computedSize.height);
r.Inflate(m);
r.x = mRect.x;
r.y = mRect.y;
SetBounds(state, r);
// layout our children
Layout(state);
// ok our child could have gotten bigger. So lets get its bounds
GetBounds(r);
// get the ascent
nscoord ascent;
GetAscent(state, ascent);
aDesiredSize.width = r.width;
aDesiredSize.height = r.height;
aDesiredSize.ascent = ascent;
aDesiredSize.descent = 0;
return NS_OK;
}
NS_IMETHODIMP
nsLeafBoxFrame::GetFrameName(nsString& aResult) const
{
aResult = "LeafBox";
return NS_OK;
}
NS_IMETHODIMP_(nsrefcnt)
nsLeafBoxFrame::AddRef(void)
{
return NS_OK;
}
NS_IMETHODIMP_(nsrefcnt)
nsLeafBoxFrame::Release(void)
{
return NS_OK;
}
NS_IMETHODIMP
nsLeafBoxFrame::ContentChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
nsISupports* aSubContent)
{
NeedsRecalc();
return nsLeafFrame::ContentChanged(aPresContext, aChild, aSubContent);
}
NS_INTERFACE_MAP_BEGIN(nsLeafBoxFrame)
NS_INTERFACE_MAP_ENTRY(nsIBox)
#ifdef NS_DEBUG
NS_INTERFACE_MAP_ENTRY(nsIFrameDebug)
#endif
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIBox)
NS_INTERFACE_MAP_END_INHERITING(nsLeafFrame)

View File

@@ -19,27 +19,24 @@
*
* Contributor(s):
*/
#ifndef nsXULLeafFrame_h___
#define nsXULLeafFrame_h___
#ifndef nsLeafBoxFrame_h___
#define nsLeafBoxFrame_h___
#include "nsLeafFrame.h"
#include "nsIBox.h"
#include "nsBox.h"
class nsAccessKeyInfo;
class nsXULLeafFrame : public nsLeafFrame, public nsIBox
class nsLeafBoxFrame : public nsLeafFrame, public nsBox
{
public:
friend nsresult NS_NewXULLeafFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
// nsIBox frame interface
NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize);
NS_IMETHOD InvalidateCache(nsIFrame* aChild);
NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug) { return NS_OK; }
friend nsresult NS_NewLeafBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_DECL_ISUPPORTS
// nsIBox frame interface
NS_IMETHOD GetFrame(nsIFrame** aFrame);
NS_IMETHOD GetFrameName(nsString& aResult) const;
@@ -53,18 +50,30 @@ public:
nsIContent* aChild,
nsISupports* aSubContent);
NS_IMETHOD DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus);
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* asPrevInFlow);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
protected:
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aDesiredSize);
nsHTMLReflowMetrics& aDesiredSize) {}
nsXULLeafFrame() {}
nsLeafBoxFrame(nsIPresShell* aShell);
private:
}; // class nsXULLeafFrame
}; // class nsLeafBoxFrame
#endif /* nsXULLeafFrame_h___ */
#endif /* nsLeafBoxFrame_h___ */

View File

@@ -55,6 +55,7 @@
#include "nsILookAndFeel.h"
#include "nsIComponentManager.h"
#include "nsWidgetsCID.h"
#include "nsBoxLayoutState.h"
#define NS_MENU_POPUP_LIST_INDEX (NS_AREA_FRAME_ABSOLUTE_LIST_INDEX + 1)
@@ -220,9 +221,10 @@ nsMenuFrame::GetFrameForPoint(nsIPresContext* aPresContext,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame)
{
if (!mRect.Contains(aPoint)) {
// if it is not inside us or not in the layer in which we paint, fail
if (!mRect.Contains(aPoint))
return NS_ERROR_FAILURE;
}
nsresult result = nsBoxFrame::GetFrameForPoint(aPresContext, aPoint, aWhichLayer, aFrame);
if ((result != NS_OK) || (*aFrame == this)) {
return result;
@@ -665,6 +667,53 @@ nsMenuFrame::GetMenuChildrenElement(nsIContent** aResult)
}
}
NS_IMETHODIMP
nsMenuFrame::Layout(nsBoxLayoutState& aState)
{
nsRect contentRect;
GetContentRect(contentRect);
// lay us out
nsresult rv = nsBoxFrame::Layout(aState);
// layout the popup. First we need to get it.
nsIFrame* popupChild = mPopupFrames.FirstChild();
if (popupChild) {
nsCOMPtr<nsIDOMXULMenuListElement> menulist = do_QueryInterface(mContent);
nsIBox* ibox = nsnull;
nsresult rv2 = popupChild->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox);
NS_ASSERTION(NS_SUCCEEDED(rv2) && ibox,"popupChild is not box!!");
// then get its preferred size
nsSize prefSize(0,0);
nsSize minSize(0,0);
nsSize maxSize(0,0);
ibox->GetPrefSize(aState, prefSize);
ibox->GetMinSize(aState, minSize);
ibox->GetMaxSize(aState, maxSize);
BoundsCheck(minSize, prefSize, maxSize);
AddMargin(ibox, prefSize);
if (menulist && prefSize.width < contentRect.width)
prefSize.width = contentRect.width;
// lay it out
LayoutChildAt(aState, ibox, nsRect(0,0,prefSize.width, prefSize.height));
}
SyncLayout(aState);
LayoutFinished(aState);
return rv;
}
/** Replaced by Layout
NS_IMETHODIMP
nsMenuFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@@ -777,9 +826,10 @@ nsMenuFrame::Reflow(nsIPresContext* aPresContext,
}
return rv;
}
*/
NS_IMETHODIMP
nsMenuFrame::SetDebug(nsIPresContext* aPresContext, PRBool aDebug)
nsMenuFrame::SetDebug(nsBoxLayoutState& aState, PRBool aDebug)
{
// see if our state matches the given debug state
PRBool debugSet = mState & NS_STATE_CURRENTLY_IN_DEBUG;
@@ -788,15 +838,15 @@ nsMenuFrame::SetDebug(nsIPresContext* aPresContext, PRBool aDebug)
// if it doesn't then tell each child below us the new debug state
if (debugChanged)
{
nsBoxFrame::SetDebug(aPresContext, aDebug);
SetDebug(aPresContext, mPopupFrames.FirstChild(), aDebug);
nsBoxFrame::SetDebug(aState, aDebug);
SetDebug(aState, mPopupFrames.FirstChild(), aDebug);
}
return NS_OK;
}
nsresult
nsMenuFrame::SetDebug(nsIPresContext* aPresContext, nsIFrame* aList, PRBool aDebug)
nsMenuFrame::SetDebug(nsBoxLayoutState& aState, nsIFrame* aList, PRBool aDebug)
{
if (!aList)
return NS_OK;
@@ -804,7 +854,7 @@ nsMenuFrame::SetDebug(nsIPresContext* aPresContext, nsIFrame* aList, PRBool aDeb
while (aList) {
nsIBox* ibox = nsnull;
if (NS_SUCCEEDED(aList->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox) {
ibox->SetDebug(aPresContext, aDebug);
ibox->SetDebug(aState, aDebug);
}
aList->GetNextSibling(&aList);
@@ -814,13 +864,9 @@ nsMenuFrame::SetDebug(nsIPresContext* aPresContext, nsIFrame* aList, PRBool aDeb
}
NS_IMETHODIMP
nsMenuFrame::DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus)
void
nsMenuFrame::LayoutFinished(nsBoxLayoutState& aState)
{
nsresult rv;
rv = nsBoxFrame::DidReflow(aPresContext, aStatus);
// Sync up the view.
nsIFrame* frame = mPopupFrames.FirstChild();
nsMenuPopupFrame* menuPopup = (nsMenuPopupFrame*)frame;
@@ -849,10 +895,10 @@ nsMenuFrame::DidReflow(nsIPresContext* aPresContext,
popupAlign = "topleft";
}
menuPopup->SyncViewWithFrame(aPresContext, popupAnchor, popupAlign, this, -1, -1);
nsIPresContext* presContext = aState.GetPresContext();
menuPopup->SyncViewWithFrame(presContext, popupAnchor, popupAlign, this, -1, -1);
}
return rv;
}
NS_IMETHODIMP
@@ -1088,6 +1134,12 @@ nsMenuFrame::UpdateMenuSpecialState(nsIPresContext* aPresContext) {
}
NS_IMETHODIMP
nsMenuFrame::CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aAnonymousChildren)
{
return NS_OK;
}
void
nsMenuFrame::BuildAcceleratorText(nsString& aAccelString)
{
@@ -1295,7 +1347,8 @@ nsMenuFrame::RemoveFrame(nsIPresContext* aPresContext,
if (mPopupFrames.ContainsFrame(aOldFrame)) {
// Go ahead and remove this frame.
mPopupFrames.DestroyFrame(aPresContext, aOldFrame);
rv = GenerateDirtyReflowCommand(aPresContext, aPresShell);
nsBoxLayoutState state(aPresContext);
rv = MarkDirtyChildren(state);
} else {
rv = nsBoxFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
}
@@ -1319,8 +1372,9 @@ nsMenuFrame::InsertFrames(nsIPresContext* aPresContext,
frameChild->GetTag(*getter_AddRefs(tag));
if (tag && tag.get() == nsXULAtoms::menupopup) {
mPopupFrames.InsertFrames(nsnull, nsnull, aFrameList);
SetDebug(aPresContext, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG);
rv = GenerateDirtyReflowCommand(aPresContext, aPresShell);
nsBoxLayoutState state(aPresContext);
SetDebug(state, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG);
rv = MarkDirtyChildren(state);
} else {
rv = nsBoxFrame::InsertFrames(aPresContext, aPresShell, aListName, aPrevFrame, aFrameList);
}
@@ -1346,8 +1400,9 @@ nsMenuFrame::AppendFrames(nsIPresContext* aPresContext,
frameChild->GetTag(*getter_AddRefs(tag));
if (tag && tag.get() == nsXULAtoms::menupopup) {
mPopupFrames.AppendFrames(nsnull, aFrameList);
SetDebug(aPresContext, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG);
rv = GenerateDirtyReflowCommand(aPresContext, aPresShell);
nsBoxLayoutState state(aPresContext);
SetDebug(state, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG);
rv = MarkDirtyChildren(state);
} else {
rv = nsBoxFrame::AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
}
@@ -1370,14 +1425,69 @@ nsMenuFrame::UpdateDismissalListener(nsIMenuParent* aMenuParent)
nsMenuFrame::mDismissalListener->SetCurrentMenuParent(aMenuParent);
}
NS_IMETHODIMP
nsMenuFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
{
aSize.width = 0;
aSize.height = 0;
nsresult rv = nsBoxFrame::GetPrefSize(aState, aSize);
nsCOMPtr<nsIDOMXULMenuListElement> menulist(do_QueryInterface(mContent));
if (menulist) {
nsCOMPtr<nsIDOMElement> element;
menulist->GetSelectedItem(getter_AddRefs(element));
if (!element) {
nsAutoString value;
menulist->GetValue(value);
if (value == "") {
nsCOMPtr<nsIContent> child;
GetMenuChildrenElement(getter_AddRefs(child));
if (child) {
PRInt32 count;
child->ChildCount(count);
if (count > 0) {
nsCOMPtr<nsIContent> item;
child->ChildAt(0, *getter_AddRefs(item));
nsCOMPtr<nsIDOMElement> selectedElement(do_QueryInterface(item));
if (selectedElement)
menulist->SetSelectedItem(selectedElement);
}
}
}
}
nsSize tmpSize(-1,0);
nsIBox::AddCSSPrefSize(aState, this, tmpSize);
nscoord flex;
GetFlex(aState, flex);
if (tmpSize.width == -1 && flex==0) {
nsIFrame* frame = mPopupFrames.FirstChild();
if (!frame) {
MarkAsGenerated();
frame = mPopupFrames.FirstChild();
}
nsIBox* ibox = nsnull;
nsresult rv2 = frame->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox);
NS_ASSERTION(NS_SUCCEEDED(rv2) && ibox,"popupChild is not box!!");
ibox->GetPrefSize(aState, tmpSize);
aSize.width = tmpSize.width;
}
}
return rv;
}
/* Need to figure out what this does.
NS_IMETHODIMP
nsMenuFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize)
{
nsresult rv = nsBoxFrame::GetBoxInfo(aPresContext, aReflowState, aSize);
nsCOMPtr<nsIDOMXULMenuListElement> menulist(do_QueryInterface(mContent));
if (menulist) {
nsCalculatedBoxInfo boxInfo;
boxInfo.frame = this;
nsCalculatedBoxInfo boxInfo(this);
boxInfo.prefSize.width = NS_UNCONSTRAINEDSIZE;
boxInfo.prefSize.height = NS_UNCONSTRAINEDSIZE;
boxInfo.flex = 0;
@@ -1392,8 +1502,7 @@ nsMenuFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& a
}
nsCOMPtr<nsIBox> box(do_QueryInterface(frame));
nsCalculatedBoxInfo childInfo;
childInfo.frame = frame;
nsCalculatedBoxInfo childInfo(frame);
box->GetBoxInfo(aPresContext, aReflowState, childInfo);
GetRedefinedMinPrefMax(aPresContext, this, childInfo);
aSize.prefSize.width = childInfo.prefSize.width;
@@ -1406,4 +1515,5 @@ nsMenuFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& a
}
return rv;
}
*/

View File

@@ -59,6 +59,13 @@ public:
NS_DECL_ISUPPORTS
// nsIBox
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
// The nsIAnonymousContentCreator interface
NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext, nsISupportsArray& aAnonymousItems);
// The nsITimerCallback interface
NS_IMETHOD_(void) Notify(nsITimer *timer);
@@ -68,7 +75,7 @@ public:
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug);
NS_IMETHOD SetDebug(nsBoxLayoutState& aState, PRBool aDebug);
NS_IMETHOD IsActive(PRBool& aResult) { aResult = PR_TRUE; return NS_OK; };
@@ -95,14 +102,6 @@ public:
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus);
// Reflow methods
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus);
NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
@@ -161,6 +160,9 @@ public:
protected:
virtual void LayoutFinished(nsBoxLayoutState& aState);
static void UpdateDismissalListener(nsIMenuParent* aMenuParent);
void UpdateMenuType(nsIPresContext* aPresContext);
void UpdateMenuSpecialState(nsIPresContext* aPresContext);
@@ -185,10 +187,9 @@ protected:
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize);
protected:
nsresult SetDebug(nsIPresContext* aPresContext, nsIFrame* aList, PRBool aDebug);
nsresult SetDebug(nsBoxLayoutState& aState, nsIFrame* aList, PRBool aDebug);
nsFrameList mPopupFrames;
PRPackedBool mIsMenu; // Whether or not we can even have children or not.

View File

@@ -103,7 +103,10 @@ public:
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext, const nsPoint& aPoint, nsFramePaintLayer aWhichLayer, nsIFrame** aFrame);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
void GetViewOffset(nsIViewManager* aManager, nsIView* aView, nsPoint& aPoint);
static void GetNearestEnclosingView(nsIPresContext* aPresContext, nsIFrame* aStartFrame, nsIView** aResult);

View File

@@ -50,6 +50,7 @@
#include "nsIDOMElement.h"
#include "nsISupportsArray.h"
#include "nsIDOMText.h"
#include "nsBoxLayoutState.h"
#define NS_MENU_POPUP_LIST_INDEX (NS_AREA_FRAME_ABSOLUTE_LIST_INDEX + 1)
@@ -198,6 +199,40 @@ nsPopupSetFrame::Destroy(nsIPresContext* aPresContext)
return nsBoxFrame::Destroy(aPresContext);
}
NS_IMETHODIMP
nsPopupSetFrame::Layout(nsBoxLayoutState& aState)
{
// lay us out
nsresult rv = nsBoxFrame::Layout(aState);
// layout the popup. First we need to get it.
nsIFrame* popupChild = GetActiveChild();
if (popupChild) {
nsIBox* ibox = nsnull;
nsresult rv2 = popupChild->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox);
NS_ASSERTION(NS_SUCCEEDED(rv2) && ibox,"popupChild is not box!!");
// then get its preferred size
nsSize prefSize(0,0);
nsSize minSize(0,0);
nsSize maxSize(0,0);
ibox->GetPrefSize(aState, prefSize);
ibox->GetMinSize(aState, minSize);
ibox->GetMaxSize(aState, maxSize);
BoundsCheck(minSize, prefSize, maxSize);
// lay it out
LayoutChildAt(aState, ibox, nsRect(0,0,prefSize.width, prefSize.height));
}
SyncLayout(aState);
return rv;
}
/** Replaced by layout
NS_IMETHODIMP
nsPopupSetFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@@ -283,9 +318,10 @@ nsPopupSetFrame::Reflow(nsIPresContext* aPresContext,
return rv;
}
*/
NS_IMETHODIMP
nsPopupSetFrame::SetDebug(nsIPresContext* aPresContext, PRBool aDebug)
nsPopupSetFrame::SetDebug(nsBoxLayoutState& aState, PRBool aDebug)
{
// see if our state matches the given debug state
PRBool debugSet = mState & NS_STATE_CURRENTLY_IN_DEBUG;
@@ -294,15 +330,15 @@ nsPopupSetFrame::SetDebug(nsIPresContext* aPresContext, PRBool aDebug)
// if it doesn't then tell each child below us the new debug state
if (debugChanged)
{
nsBoxFrame::SetDebug(aPresContext, aDebug);
SetDebug(aPresContext, mPopupFrames.FirstChild(), aDebug);
nsBoxFrame::SetDebug(aState, aDebug);
SetDebug(aState, mPopupFrames.FirstChild(), aDebug);
}
return NS_OK;
}
nsresult
nsPopupSetFrame::SetDebug(nsIPresContext* aPresContext, nsIFrame* aList, PRBool aDebug)
nsPopupSetFrame::SetDebug(nsBoxLayoutState& aState, nsIFrame* aList, PRBool aDebug)
{
if (!aList)
return NS_OK;
@@ -310,7 +346,7 @@ nsPopupSetFrame::SetDebug(nsIPresContext* aPresContext, nsIFrame* aList, PRBool
while (aList) {
nsIBox* ibox = nsnull;
if (NS_SUCCEEDED(aList->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox) {
ibox->SetDebug(aPresContext, aDebug);
ibox->SetDebug(aState, aDebug);
}
aList->GetNextSibling(&aList);
@@ -358,7 +394,8 @@ nsPopupSetFrame::RemoveFrame(nsIPresContext* aPresContext,
if (mPopupFrames.ContainsFrame(aOldFrame)) {
// Go ahead and remove this frame.
mPopupFrames.DestroyFrame(aPresContext, aOldFrame);
rv = GenerateDirtyReflowCommand(aPresContext, aPresShell);
nsBoxLayoutState state(aPresContext);
rv = MarkDirtyChildren(state);
} else {
rv = nsBoxFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
}
@@ -381,8 +418,9 @@ nsPopupSetFrame::InsertFrames(nsIPresContext* aPresContext,
frameChild->GetTag(*getter_AddRefs(tag));
if (tag && tag.get() == nsXULAtoms::popup) {
mPopupFrames.InsertFrames(nsnull, nsnull, aFrameList);
SetDebug(aPresContext, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG);
rv = GenerateDirtyReflowCommand(aPresContext, aPresShell);
nsBoxLayoutState state(aPresContext);
SetDebug(state, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG);
rv = MarkDirtyChildren(state);
} else {
rv = nsBoxFrame::InsertFrames(aPresContext, aPresShell, aListName, aPrevFrame, aFrameList);
}
@@ -408,8 +446,9 @@ nsPopupSetFrame::AppendFrames(nsIPresContext* aPresContext,
frameChild->GetTag(*getter_AddRefs(tag));
if (tag && tag.get() == nsXULAtoms::popup) {
mPopupFrames.AppendFrames(nsnull, aFrameList);
SetDebug(aPresContext, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG);
rv = GenerateDirtyReflowCommand(aPresContext, aPresShell);
nsBoxLayoutState state(aPresContext);
SetDebug(state, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG);
rv = MarkDirtyChildren(state);
} else {
rv = nsBoxFrame::AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
}

View File

@@ -55,7 +55,9 @@ public:
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug);
// nsIBox
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD SetDebug(nsBoxLayoutState& aState, PRBool aDebug);
// The following four methods are all overridden so that the menu children
// can be stored in a separate list (so that they don't impact reflow of the
@@ -71,10 +73,6 @@ public:
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
// Reflow methods
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus);
@@ -123,7 +121,7 @@ protected:
void UpdateDismissalListener(nsIMenuParent* aMenuParent);
protected:
nsresult SetDebug(nsIPresContext* aPresContext, nsIFrame* aList, PRBool aDebug);
nsresult SetDebug(nsBoxLayoutState& aState, nsIFrame* aList, PRBool aDebug);
nsFrameList mPopupFrames;
nsIPresContext* mPresContext; // Our pres context.

View File

@@ -49,7 +49,7 @@ nsRepeatService::GetInstance()
{
if (!gInstance) {
gInstance = new nsRepeatService();
gInstance->mRefCnt = 1;
NS_ADDREF(gInstance);
}
return gInstance;

View File

@@ -0,0 +1,261 @@
/* -*- 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.org 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):
*/
#include "nsHTMLParts.h"
#include "nsContainerFrame.h"
#include "nsCSSRendering.h"
#include "nsIDocument.h"
#include "nsIReflowCommand.h"
#include "nsIPresContext.h"
#include "nsIStyleContext.h"
#include "nsViewsCID.h"
#include "nsIView.h"
#include "nsIViewManager.h"
#include "nsIWidget.h"
#include "nsHTMLIIDs.h"
#include "nsPageFrame.h"
#include "nsIRenderingContext.h"
#include "nsGUIEvent.h"
#include "nsDOMEvent.h"
#include "nsStyleConsts.h"
#include "nsIViewManager.h"
#include "nsHTMLAtoms.h"
#include "nsIEventStateManager.h"
#include "nsIDeviceContext.h"
#include "nsIScrollableView.h"
#include "nsLayoutAtoms.h"
#include "nsIPresShell.h"
#include "nsBoxFrame.h"
#include "nsStackLayout.h"
// Interface IDs
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
/**
* Root frame class.
*
* The root frame is the parent frame for the document element's frame.
* It only supports having a single child frame which must be an area
* frame
*/
class nsRootBoxFrame : public nsBoxFrame {
public:
friend nsresult NS_NewBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
nsRootBoxFrame(nsIPresShell* aShell);
NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aFrameList);
NS_IMETHOD InsertFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList);
NS_IMETHOD RemoveFrame(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aOldFrame);
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD HandleEvent(nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
/**
* Get the "type" of the frame
*
* @see nsLayoutAtoms::rootFrame
*/
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
#ifdef DEBUG
NS_IMETHOD GetFrameName(nsString& aResult) const;
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
#endif
};
//----------------------------------------------------------------------
nsresult
NS_NewRootBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsRootBoxFrame* it = new (aPresShell) nsRootBoxFrame (aPresShell);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
it->SetLayoutManager(new nsStackLayout(aPresShell));
*aNewFrame = it;
return NS_OK;
}
nsRootBoxFrame::nsRootBoxFrame(nsIPresShell* aShell):nsBoxFrame(aShell, PR_TRUE)
{
}
NS_IMETHODIMP
nsRootBoxFrame::AppendFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aFrameList)
{
nsresult rv;
NS_ASSERTION(!aListName, "unexpected child list name");
NS_PRECONDITION(mFrames.IsEmpty(), "already have a child frame");
if (aListName) {
// We only support unnamed principal child list
rv = NS_ERROR_INVALID_ARG;
} else if (!mFrames.IsEmpty()) {
// We only allow a single child frame
rv = NS_ERROR_FAILURE;
} else {
rv = nsBoxFrame::AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
}
return rv;
}
NS_IMETHODIMP
nsRootBoxFrame::InsertFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
nsresult rv;
// Because we only support a single child frame inserting is the same
// as appending
NS_PRECONDITION(!aPrevFrame, "unexpected previous sibling frame");
if (aPrevFrame) {
rv = NS_ERROR_UNEXPECTED;
} else {
rv = AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
}
return rv;
}
NS_IMETHODIMP
nsRootBoxFrame::RemoveFrame(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aOldFrame)
{
nsresult rv;
NS_ASSERTION(!aListName, "unexpected child list name");
if (aListName) {
// We only support the unnamed principal child list
rv = NS_ERROR_INVALID_ARG;
} else if (aOldFrame == mFrames.FirstChild()) {
rv = nsBoxFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
} else {
rv = NS_ERROR_FAILURE;
}
return rv;
}
NS_IMETHODIMP
nsRootBoxFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
return nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
}
NS_IMETHODIMP
nsRootBoxFrame::HandleEvent(nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus)
{
NS_ENSURE_ARG_POINTER(aEventStatus);
if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
return NS_OK;
}
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP ||
aEvent->message == NS_MOUSE_MIDDLE_BUTTON_UP ||
aEvent->message == NS_MOUSE_RIGHT_BUTTON_UP) {
nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
return NS_OK;
}
NS_IMETHODIMP
nsRootBoxFrame::GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame)
{
// this should act like a block, so we need to override
return nsBoxFrame::GetFrameForPoint(aPresContext, aPoint, aWhichLayer, aFrame);
}
NS_IMETHODIMP
nsRootBoxFrame::GetFrameType(nsIAtom** aType) const
{
NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer");
*aType = nsLayoutAtoms::rootFrame;
NS_ADDREF(*aType);
return NS_OK;
}
#ifdef DEBUG
NS_IMETHODIMP
nsRootBoxFrame::GetFrameName(nsString& aResult) const
{
return MakeFrameName("RootBox", aResult);
}
NS_IMETHODIMP
nsRootBoxFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
{
if (!aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = sizeof(*this);
return NS_OK;
}
#endif

View File

@@ -64,7 +64,7 @@ NS_NewScrollbarButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
nsScrollbarButtonFrame::nsScrollbarButtonFrame(nsIPresShell* aPresShell)
:nsXULButtonFrame(aPresShell)
:nsButtonBoxFrame(aPresShell)
{
}
@@ -79,7 +79,7 @@ nsScrollbarButtonFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
return NS_OK;
}
return nsXULButtonFrame::QueryInterface(aIID, aInstancePtr);
return nsButtonBoxFrame::QueryInterface(aIID, aInstancePtr);
}
NS_IMETHODIMP
@@ -91,7 +91,7 @@ nsScrollbarButtonFrame::HandleEvent(nsIPresContext* aPresContext,
if (aEvent->message == NS_MOUSE_EXIT|| aEvent->message == NS_MOUSE_RIGHT_BUTTON_UP || aEvent->message == NS_MOUSE_LEFT_BUTTON_UP)
HandleRelease(aPresContext, aEvent, aEventStatus);
return nsXULButtonFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
return nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
@@ -245,5 +245,5 @@ nsScrollbarButtonFrame::Destroy(nsIPresContext* aPresContext)
// Ensure our repeat service isn't going... it's possible that a scrollbar can disappear out
// from under you while you're in the process of scrolling.
nsRepeatService::GetInstance()->Stop();
return nsXULButtonFrame::Destroy(aPresContext);
return nsButtonBoxFrame::Destroy(aPresContext);
}

View File

@@ -30,12 +30,12 @@
#ifndef nsScrollbarButtonFrame_h___
#define nsScrollbarButtonFrame_h___
#include "nsXULButtonFrame.h"
#include "nsButtonBoxFrame.h"
#include "nsITimerCallback.h"
class nsSliderFrame;
class nsScrollbarButtonFrame : public nsXULButtonFrame,
class nsScrollbarButtonFrame : public nsButtonBoxFrame,
public nsITimerCallback
{
public:

View File

@@ -57,6 +57,7 @@
#include "nsINameSpaceManager.h"
#include "nsIScrollableView.h"
#include "nsRepeatService.h"
#include "nsBoxLayoutState.h"
#define DEBUG_SLIDER PR_FALSE
@@ -68,7 +69,7 @@ NS_NewSliderFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame)
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsSliderFrame* it = new (aPresShell) nsSliderFrame();
nsSliderFrame* it = new (aPresShell) nsSliderFrame(aPresShell);
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
@@ -77,8 +78,8 @@ NS_NewSliderFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame)
} // NS_NewSliderFrame
nsSliderFrame::nsSliderFrame()
: mCurPos(0), mScrollbarListener(nsnull),mChange(0)
nsSliderFrame::nsSliderFrame(nsIPresShell* aPresShell):nsBoxFrame(aPresShell),
mCurPos(0), mScrollbarListener(nsnull),mChange(0)
{
}
@@ -95,7 +96,7 @@ nsSliderFrame::Init(nsIPresContext* aPresContext,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsHTMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
CreateViewForFrame(aPresContext,this,aContext,PR_TRUE);
nsIView* view;
GetView(aPresContext, &view);
@@ -153,7 +154,7 @@ nsSliderFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIAtom* aAttribute,
PRInt32 aHint)
{
nsresult rv = nsHTMLContainerFrame::AttributeChanged(aPresContext, aChild,
nsresult rv = nsBoxFrame::AttributeChanged(aPresContext, aChild,
aNameSpaceID, aAttribute, aHint);
// if the current position changes
if (aAttribute == nsXULAtoms::curpos) {
@@ -164,7 +165,8 @@ nsSliderFrame::AttributeChanged(nsIPresContext* aPresContext,
} else if (aAttribute == nsXULAtoms::maxpos) {
// bounds check it.
nsIContent* scrollbar = GetScrollBar();
nsIBox* scrollbarBox = GetScrollbar();
nsIContent* scrollbar = GetContentOf(scrollbarBox);
PRInt32 current = GetCurrentPosition(scrollbar);
PRInt32 max = GetMaxPosition(scrollbar);
if (current < 0 || current > max)
@@ -189,16 +191,8 @@ nsSliderFrame::AttributeChanged(nsIPresContext* aPresContext,
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
/*
nsCOMPtr<nsIReflowCommand> reflowCmd;
rv = NS_NewHTMLReflowCommand(getter_AddRefs(reflowCmd), this,
nsIReflowCommand::StyleChanged);
if (NS_SUCCEEDED(rv))
shell->AppendReflowCommand(reflowCmd);
*/
mState |= NS_FRAME_IS_DIRTY;
return mParent->ReflowDirtyChild(shell, this);
nsBoxLayoutState state(aPresContext);
MarkDirtyChildren(state);
}
return rv;
@@ -211,12 +205,21 @@ nsSliderFrame::Paint(nsIPresContext* aPresContext,
nsFramePaintLayer aWhichLayer)
{
// if we are too small to have a thumb don't paint it.
nsIFrame* thumbFrame = mFrames.FirstChild();
NS_ASSERTION(thumbFrame,"Slider does not have a thumb!!!!");
nsIBox* thumb;
GetChildBox(&thumb);
nsSize size(0,0);
thumbFrame->GetSize(size);
if (mRect.width < size.width || mRect.height < size.height)
NS_ASSERTION(thumb,"Slider does not have a thumb!!!!");
nsRect thumbRect;
thumb->GetBounds(thumbRect);
nsMargin m;
thumb->GetMargin(m);
thumbRect.Inflate(m);
nsRect rect;
GetClientRect(rect);
if (rect.width < thumbRect.width || rect.height < thumbRect.height)
{
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
const nsStyleDisplay* disp = (const nsStyleDisplay*)
@@ -236,92 +239,44 @@ nsSliderFrame::Paint(nsIPresContext* aPresContext,
return NS_OK;
}
return nsHTMLContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
nsresult
nsSliderFrame::ReflowThumb(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
nsIFrame* thumbFrame,
nsSize available,
nsSize computed)
{
nsHTMLReflowState thumbReflowState(aPresContext, aReflowState,
thumbFrame, available);
// always give the thumb as much size as it needs
thumbReflowState.mComputedWidth = computed.width;
thumbReflowState.mComputedHeight = computed.height;
// subtract out the childs margin and border if computed
const nsStyleSpacing* spacing;
nsresult rv = thumbFrame->GetStyleData(eStyleStruct_Spacing,
(const nsStyleStruct*&) spacing);
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get spacing");
if (NS_FAILED(rv))
return rv;
nsMargin margin(0,0,0,0);
spacing->GetMargin(margin);
nsMargin border(0,0,0,0);
spacing->GetBorderPadding(border);
nsMargin total = margin + border;
if (thumbReflowState.mComputedWidth != NS_INTRINSICSIZE)
thumbReflowState.mComputedWidth -= total.left + total.right;
if (thumbReflowState.mComputedHeight != NS_INTRINSICSIZE)
thumbReflowState.mComputedHeight -= total.top + total.bottom;
ReflowChild(thumbFrame, aPresContext, aDesiredSize, thumbReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
thumbFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
// add the margin back in
aDesiredSize.width += margin.left + margin.right;
aDesiredSize.height += margin.top + margin.bottom;
return NS_OK;
}
PRBool
nsSliderFrame::IsHorizontal(nsIContent* scrollbar)
{
PRBool isHorizontal = PR_TRUE;
nsAutoString value;
if (NS_CONTENT_ATTR_HAS_VALUE == scrollbar->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value))
{
if (value.Equals("vertical"))
isHorizontal = PR_FALSE;
}
return isHorizontal;
return nsBoxFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
NS_IMETHODIMP
nsSliderFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
nsSliderFrame::Layout(nsBoxLayoutState& aBoxLayoutState)
{
nsIContent* scrollbar = GetScrollBar();
EnsureOrient();
PRBool isHorizontal = IsHorizontal(scrollbar);
if (mState & NS_STATE_DEBUG_WAS_SET) {
if (mState & NS_STATE_SET_TO_DEBUG)
SetDebug(aBoxLayoutState, PR_TRUE);
else
SetDebug(aBoxLayoutState, PR_FALSE);
}
// flow our thumb with our computed width and its intrinsic height
nsIFrame* thumbFrame = mFrames.FirstChild();
NS_ASSERTION(thumbFrame,"Slider does not have a thumb!!!!");
// get the content area inside our borders
nsRect clientRect(0,0,0,0);
GetClientRect(clientRect);
nsHTMLReflowMetrics thumbSize(nsnull);
// get the scrollbar
nsIBox* scrollbarBox = GetScrollbar();
nsIContent* scrollbar = GetContentOf(scrollbarBox);
PRBool isHorizontal = IsHorizontal();
nsSize availableSize(isHorizontal ? NS_INTRINSICSIZE: aReflowState.mComputedWidth, isHorizontal ? aReflowState.mComputedHeight : NS_INTRINSICSIZE);
nsSize computedSize(isHorizontal ? NS_INTRINSICSIZE: aReflowState.mComputedWidth, isHorizontal ? aReflowState.mComputedHeight : NS_INTRINSICSIZE);
// get the thumb should be our only child
nsIBox* thumbBox = nsnull;
GetChildBox(&thumbBox);
ReflowThumb(aPresContext, thumbSize, aReflowState, aStatus, thumbFrame, availableSize, computedSize);
NS_ASSERTION(thumbBox,"Slider does not have a thumb!!!!");
// get the thumb's pref size
nsSize thumbSize(0,0);
thumbBox->GetPrefSize(aBoxLayoutState, thumbSize);
if (isHorizontal)
thumbSize.height = clientRect.height;
else
thumbSize.width = clientRect.width;
// get our current position and max position from our content node
PRInt32 curpospx = GetCurrentPosition(scrollbar);
@@ -332,11 +287,11 @@ nsSliderFrame::Reflow(nsIPresContext* aPresContext,
else if (curpospx > maxpospx)
curpospx = maxpospx;
// if the computed height we are given is intrinsic then set it to some default height
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
aBoxLayoutState.GetPresContext()->GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
/*
if (aReflowState.mComputedHeight == NS_INTRINSICSIZE)
aDesiredSize.height = isHorizontal ? thumbSize.height : 200*onePixel;
else {
@@ -353,75 +308,56 @@ nsSliderFrame::Reflow(nsIPresContext* aPresContext,
// if (aDesiredSize.width < thumbSize.width)
// aDesiredSize.width = thumbSize.width;
}
*/
// get max pos in twips
nscoord maxpos = maxpospx*onePixel;
// get our maxpos in twips. This is the space we have left over in the scrollbar
// after the height of the thumb has been removed
nscoord& desiredcoord = isHorizontal ? aDesiredSize.width : aDesiredSize.height;
nscoord& desiredcoord = isHorizontal ? clientRect.width : clientRect.height;
nscoord& thumbcoord = isHorizontal ? thumbSize.width : thumbSize.height;
nscoord ourmaxpos = desiredcoord;
mRatio = float(ourmaxpos)/float(maxpos + ourmaxpos);
nscoord thumbsize = nscoord(ourmaxpos * mRatio);
// if there is more room than the thumb need stretch the
// thumb
nscoord thumbsize = nscoord(ourmaxpos * mRatio);
if (thumbsize > thumbcoord) {
nscoord flex = 0;
thumbBox->GetFlex(aBoxLayoutState, flex);
// if the thumb is flexible make the thumb bigger.
nsCOMPtr<nsIContent> content;
thumbFrame->GetContent(getter_AddRefs(content));
PRInt32 error;
nsAutoString value;
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsXULAtoms::flex, value))
{
value.Trim("%");
// convert to a percent.
if (value.ToFloat(&error) > 0.0) {
if (flex > 0) {
if (isHorizontal)
computedSize.width = thumbsize;
thumbSize.width = nscoord(ourmaxpos * mRatio);
else
computedSize.height = thumbsize;
ReflowThumb(aPresContext, thumbSize, aReflowState, aStatus, thumbFrame, availableSize, computedSize);
}
thumbSize.height = nscoord(ourmaxpos * mRatio);
}
} else {
ourmaxpos -= thumbcoord;
mRatio = float(ourmaxpos)/float(maxpos);
}
// get our border
const nsMargin& borderPadding = aReflowState.mComputedBorderPadding;
nscoord curpos = curpospx*onePixel;
// set the thumbs y coord to be the current pos * the ratio.
nscoord pos = nscoord(float(curpos)*mRatio);
nsRect thumbRect(borderPadding.left, borderPadding.top, thumbSize.width, thumbSize.height);
nsRect thumbRect(clientRect.x, clientRect.y, thumbSize.width, thumbSize.height);
if (isHorizontal)
thumbRect.x += pos;
else
thumbRect.y += pos;
nsIView* view;
thumbFrame->SetRect(aPresContext, thumbRect);
thumbFrame->GetView(aPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, thumbFrame,
view, nsnull);
}
thumbBox->SetBounds(aBoxLayoutState, thumbRect);
thumbBox->Layout(aBoxLayoutState);
// add in our border
aDesiredSize.width += borderPadding.left + borderPadding.right;
aDesiredSize.height += borderPadding.top + borderPadding.bottom;
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
SyncLayout(aBoxLayoutState);
if (DEBUG_SLIDER) {
PRInt32 c = GetCurrentPosition(scrollbar);
@@ -438,9 +374,9 @@ nsSliderFrame::HandleEvent(nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus)
{
nsIContent* scrollbar = GetScrollBar();
PRBool isHorizontal = IsHorizontal(scrollbar);
nsIBox* scrollbarBox = GetScrollbar();
nsIContent* scrollbar = GetContentOf(scrollbarBox);
PRBool isHorizontal = IsHorizontal();
if (isDraggingThumb(aPresContext))
{
@@ -536,8 +472,8 @@ nsSliderFrame::HandleEvent(nsIPresContext* aPresContext,
nsIContent*
nsSliderFrame::GetScrollBar()
nsIBox*
nsSliderFrame::GetScrollbar()
{
// if we are in a scrollbar then return the scrollbar's content node
// if we are not then return ours.
@@ -545,11 +481,24 @@ nsSliderFrame::GetScrollBar()
nsScrollbarButtonFrame::GetParentWithTag(nsXULAtoms::scrollbar, this, scrollbar);
if (scrollbar == nsnull)
scrollbar = this;
return this;
nsCOMPtr<nsIContent> content;
scrollbar->GetContent(getter_AddRefs(content));
nsIBox* ibox = nsnull;
scrollbar->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox);
if (ibox == nsnull)
return this;
return ibox;
}
nsIContent*
nsSliderFrame::GetContentOf(nsIBox* aBox)
{
nsIFrame* frame = nsnull;
aBox->GetFrame(&frame);
nsIContent* content = nsnull;
frame->GetContent(&content);
return content;
}
@@ -559,7 +508,8 @@ nsSliderFrame::PageUpDown(nsIFrame* aThumbFrame, nscoord change)
// on a page up or down get our page increment. We get this by getting the scrollbar we are in and
// asking it for the current position and the page increment. If we are not in a scrollbar we will
// get the values from our own node.
nsIContent* scrollbar = GetScrollBar();
nsIBox* scrollbarBox = GetScrollbar();
nsIContent* scrollbar = GetContentOf(scrollbarBox);
if (mScrollbarListener)
mScrollbarListener->PagedUpDown(); // Let the listener decide our increment.
@@ -573,9 +523,10 @@ nsSliderFrame::PageUpDown(nsIFrame* aThumbFrame, nscoord change)
nsresult
nsSliderFrame::CurrentPositionChanged(nsIPresContext* aPresContext)
{
nsIContent* scrollbar = GetScrollBar();
nsIBox* scrollbarBox = GetScrollbar();
nsIContent* scrollbar = GetContentOf(scrollbarBox);
PRBool isHorizontal = IsHorizontal(scrollbar);
PRBool isHorizontal = IsHorizontal();
// get the current position
PRInt32 curpos = GetCurrentPosition(scrollbar);
@@ -678,35 +629,12 @@ NS_IMETHODIMP nsSliderFrame::GetFrameForPoint(nsIPresContext* aPresContext,
return NS_OK;
}
if ((! mRect.Contains(aPoint)) ||
(aWhichLayer != NS_FRAME_PAINT_LAYER_FOREGROUND)) {
if (!mRect.Contains(aPoint))
return NS_ERROR_FAILURE;
}
nsIFrame* thumbFrame = mFrames.FirstChild();
// XXX If thumbFrame always considers itself FOREGROUND, then it
// would be better to just call thumbFrame->GetFrameForPoint and
// return if it returns NS_OK.
nsRect thumbRect;
thumbFrame->GetRect(thumbRect);
nsPoint tmp;
tmp.MoveTo(aPoint.x - mRect.x, aPoint.y - mRect.y);
if (thumbRect.Contains(tmp)) {
nsIStyleContext *tsc;
thumbFrame->GetStyleContext(&tsc);
if (tsc) {
const nsStyleDisplay* disp = (const nsStyleDisplay*)
tsc->GetStyleData(eStyleStruct_Display);
if (disp->IsVisible()) {
*aFrame = thumbFrame;
NS_RELEASE(tsc);
if (NS_SUCCEEDED(nsBoxFrame::GetFrameForPoint(aPresContext, aPoint, aWhichLayer, aFrame)))
return NS_OK;
}
NS_RELEASE(tsc);
}
}
// always return us (if visible)
const nsStyleDisplay* disp = (const nsStyleDisplay*)
@@ -717,8 +645,6 @@ NS_IMETHODIMP nsSliderFrame::GetFrameForPoint(nsIPresContext* aPresContext,
}
return NS_ERROR_FAILURE;
//return nsHTMLContainerFrame::GetFrameForPoint(aPresContext, aPoint, aFrame);
}
@@ -728,55 +654,19 @@ nsSliderFrame::SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
nsresult r = nsHTMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
nsresult r = nsBoxFrame::SetInitialChildList(aPresContext, aListName, aChildList);
AddListener();
return r;
}
NS_IMETHODIMP
nsSliderFrame::RemoveFrame(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aOldFrame)
{
// remove the child frame
nsresult rv = nsHTMLContainerFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
mFrames.DestroyFrame(aPresContext, aOldFrame);
return rv;
}
NS_IMETHODIMP
nsSliderFrame::InsertFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
return nsHTMLContainerFrame::InsertFrames(aPresContext, aPresShell, aListName, aPrevFrame, aFrameList);
}
NS_IMETHODIMP
nsSliderFrame::AppendFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aFrameList)
{
mFrames.AppendFrames(nsnull, aFrameList);
return nsHTMLContainerFrame::AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
}
nsresult
nsSliderFrame::MouseDown(nsIDOMEvent* aMouseEvent)
{
//printf("Begin dragging\n");
nsIContent* scrollbar = GetScrollBar();
PRBool isHorizontal = IsHorizontal(scrollbar);
PRBool isHorizontal = IsHorizontal();
nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(aMouseEvent));
@@ -885,7 +775,7 @@ nsSliderFrame::RemoveListener()
NS_INTERFACE_MAP_BEGIN(nsSliderFrame)
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_END_INHERITING(nsHTMLContainerFrame)
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
NS_IMETHODIMP_(nsrefcnt)
@@ -905,8 +795,7 @@ nsSliderFrame::HandlePress(nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus)
{
nsIContent* scrollbar = GetScrollBar();
PRBool isHorizontal = IsHorizontal(scrollbar);
PRBool isHorizontal = IsHorizontal();
nsIFrame* thumbFrame = mFrames.FirstChild();
nsRect thumbRect;
@@ -969,7 +858,47 @@ nsSliderFrame::Destroy(nsIPresContext* aPresContext)
RemoveListener(); // remove this line when 21571 is fixed properly
// call base class Destroy()
return nsHTMLContainerFrame::Destroy(aPresContext);
return nsBoxFrame::Destroy(aPresContext);
}
NS_IMETHODIMP
nsSliderFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
{
EnsureOrient();
return nsBoxFrame::GetPrefSize(aState, aSize);
}
NS_IMETHODIMP
nsSliderFrame::GetMinSize(nsBoxLayoutState& aState, nsSize& aSize)
{
EnsureOrient();
// our min size is just our borders and padding
return nsBox::GetMinSize(aState, aSize);
}
NS_IMETHODIMP
nsSliderFrame::GetMaxSize(nsBoxLayoutState& aState, nsSize& aSize)
{
EnsureOrient();
return nsBoxFrame::GetMaxSize(aState, aSize);
}
void
nsSliderFrame::EnsureOrient()
{
nsIBox* scrollbarBox = GetScrollbar();
nsIFrame* frame = nsnull;
scrollbarBox->GetFrame(&frame);
nsFrameState state;
frame->GetFrameState(&state);
PRBool isHorizontal = state & NS_STATE_IS_HORIZONTAL;
if (isHorizontal)
mState |= NS_STATE_IS_HORIZONTAL;
else
mState &= ~NS_STATE_IS_HORIZONTAL;
}
@@ -988,8 +917,7 @@ NS_IMETHODIMP_(void) nsSliderFrame::Notify(nsITimer *timer)
nsRect thumbRect;
thumbFrame->GetRect(thumbRect);
nsIContent* scrollbar = GetScrollBar();
PRBool isHorizontal = IsHorizontal(scrollbar);
PRBool isHorizontal = IsHorizontal();
// see if the thumb has moved passed our original click point.
// if it has we want to stop.
@@ -1018,3 +946,46 @@ NS_IMETHODIMP_(void) nsSliderFrame::Notify(nsITimer *timer)
PageUpDown(thumbFrame, mChange);
}
}
class nsThumbFrame : public nsTitledButtonFrame
{
public:
friend nsresult NS_NewThumbFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD HandlePress(nsIPresContext* aPresContext,
nsGUIEvent * aEvent,
nsEventStatus* aEventStatus) { return NS_OK; }
NS_IMETHOD HandleMultiplePress(nsIPresContext* aPresContext,
nsGUIEvent * aEvent,
nsEventStatus* aEventStatus) { return NS_OK; }
NS_IMETHOD HandleDrag(nsIPresContext* aPresContext,
nsGUIEvent * aEvent,
nsEventStatus* aEventStatus) { return NS_OK; }
NS_IMETHOD HandleRelease(nsIPresContext* aPresContext,
nsGUIEvent * aEvent,
nsEventStatus* aEventStatus) { return NS_OK; }
nsThumbFrame(nsIPresShell* aPresShell):nsTitledButtonFrame(aPresShell) {}
};
nsresult
NS_NewThumbFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsThumbFrame* it = new (aPresShell) nsThumbFrame(aPresShell);
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
*aNewFrame = it;
return NS_OK;
} // NS_NewSliderFrame

View File

@@ -28,7 +28,7 @@
#define nsSliderFrame_h__
#include "nsHTMLContainerFrame.h"
#include "nsBoxFrame.h"
#include "prtypes.h"
#include "nsIAtom.h"
#include "nsCOMPtr.h"
@@ -47,12 +47,12 @@ class nsITimer;
nsresult NS_NewSliderFrame(nsIPresShell* aPresShell, nsIFrame** aResult) ;
class nsSliderFrame : public nsHTMLContainerFrame,
class nsSliderFrame : public nsBoxFrame,
public nsIDOMMouseListener,
public nsITimerCallback
{
public:
nsSliderFrame();
nsSliderFrame(nsIPresShell* aShell);
virtual ~nsSliderFrame();
#ifdef DEBUG
@@ -61,6 +61,12 @@ public:
}
#endif
// nsIBox
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
// nsIFrame overrides
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
@@ -83,34 +89,15 @@ public:
nsIStyleContext* aContext,
nsIFrame* asPrevInFlow);
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aFrameList);
NS_IMETHOD InsertFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList);
NS_IMETHOD RemoveFrame(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aOldFrame);
NS_IMETHOD HandleEvent(nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint, nsFramePaintLayer aWhichLayer, nsIFrame** aFrame);
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
@@ -171,7 +158,7 @@ public:
static PRInt32 GetIncrement(nsIContent* content);
static PRInt32 GetPageIncrement(nsIContent* content);
static PRInt32 GetIntegerAttribute(nsIContent* content, nsIAtom* atom, PRInt32 defaultValue);
static PRInt32 IsHorizontal(nsIContent* content);
void EnsureOrient();
void SetScrollbarListener(nsIScrollbarListener* aListener);
@@ -196,20 +183,14 @@ public:
protected:
virtual nsresult ReflowThumb(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
nsIFrame* thumbFrame,
nsSize available,
nsSize computed);
virtual PRIntn GetSkipSides() const { return 0; }
private:
nsIContent* GetScrollBar();
nsIBox* GetScrollbar();
nsIContent* GetContentOf(nsIBox* aBox);
void PageUpDown(nsIFrame* aThumbFrame, nscoord change);
void SetCurrentPosition(nsIContent* scrollbar, nsIFrame* aThumbFrame, nscoord pos);
NS_IMETHOD DragThumb(nsIPresContext* aPresContext, PRBool aGrabMouseEvents);

View File

@@ -50,8 +50,9 @@
#include "nsIPresShell.h"
#include "nsIStyleContext.h"
#include "nsWidgetsCID.h"
#include "nsBoxLayoutState.h"
#define REAL_TIME_DRAG PR_FALSE
#define REAL_TIME_DRAG
const PRInt32 kMaxZ = 0x7fffffff; //XXX: Shouldn't there be a define somewhere for MaxInt for PRInt32
@@ -63,7 +64,7 @@ public:
nscoord max;
nscoord current;
nscoord changed;
nsIFrame* child;
nsIBox* child;
PRInt32 flex;
PRInt32 index;
};
@@ -133,12 +134,13 @@ public:
CollapseDirection GetCollapseDirection();
void MoveSplitterBy(nsIPresContext* aPresContext, nscoord aDiff);
void EnsureOrient();
nsSplitterFrame* mOuter;
PRBool mDidDrag;
nscoord mDragStartPx;
nscoord mCurrentPos;
nsBoxFrame* mParentBox;
nsIBox* mParentBox;
PRBool mPressed;
nsSplitterInfo* mChildInfosBefore;
nsSplitterInfo* mChildInfosAfter;
@@ -148,6 +150,7 @@ public:
nscoord mSplitterPos;
nscoord mSplitterViewPos;
};
@@ -343,11 +346,11 @@ nsSplitterFrame::Init(nsIPresContext* aPresContext,
nsIView* view;
GetView(aPresContext, &view);
// currently this only works on win32 and mac
#ifdef XP_UNIX
#if defined(REAL_TIME_DRAG) || defined(XP_UNIX)
view->SetContentTransparency(PR_TRUE);
view->SetZIndex(kMaxZ);
#else
// currently this only works on win32 and mac
static NS_DEFINE_CID(kCChildCID, NS_CHILD_CID);
nsCOMPtr<nsIViewManager> viewManager;
view->GetViewManager(*getter_AddRefs(viewManager));
@@ -359,12 +362,22 @@ nsSplitterFrame::Init(nsIPresContext* aPresContext,
#endif
mInner->mState = nsSplitterFrameInner::Open;
mInner->UpdateState();
mInner->AddListener(aPresContext);
mInner->mParentBox = nsnull;
return rv;
}
NS_IMETHODIMP
nsSplitterFrame::Layout(nsBoxLayoutState& aState)
{
if (aState.GetLayoutReason() == nsBoxLayoutState::Initial) {
GetParentBox(&mInner->mParentBox);
mInner->UpdateState();
}
return nsBoxFrame::Layout(aState);
}
PRBool
nsSplitterFrame::GetInitialOrientation(PRBool& aIsHorizontal)
{
@@ -428,8 +441,19 @@ NS_IMETHODIMP nsSplitterFrame::GetFrameForPoint(nsIPresContext* aPresContext,
// XXX It's probably better not to check visibility here, right?
*aFrame = this;
return NS_OK;
} else
return nsBoxFrame::GetFrameForPoint(aPresContext, aPoint, aWhichLayer, aFrame);
} else {
if (!mRect.Contains(aPoint))
return NS_ERROR_FAILURE;
nsresult rv = nsBoxFrame::GetFrameForPoint(aPresContext, aPoint, aWhichLayer, aFrame);
if (rv == NS_ERROR_FAILURE) {
*aFrame = this;
rv = NS_OK;
}
return rv;
}
}
NS_IMETHODIMP
@@ -477,7 +501,6 @@ nsSplitterFrameInner::MouseDrag(nsIPresContext* aPresContext, nsGUIEvent* aEvent
//printf("Dragging\n");
PRBool isHorizontal = !mOuter->IsHorizontal();
// convert coord to pixels
nscoord pos = isHorizontal ? aEvent->point.x : aEvent->point.y;
@@ -576,7 +599,7 @@ nsSplitterFrameInner::MouseDrag(nsIPresContext* aPresContext, nsGUIEvent* aEvent
if (currentState != Dragging)
mOuter->mContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::state, "dragging", PR_TRUE);
#if REAL_TIME_DRAG
#ifdef REAL_TIME_DRAG
AdjustChildren(aPresContext);
#else
MoveSplitterBy(aPresContext, pos);
@@ -702,14 +725,13 @@ nsSplitterFrameInner::MouseUp(nsIDOMEvent* aMouseEvent)
nsresult
nsSplitterFrameInner::MouseDown(nsIDOMEvent* aMouseEvent)
{
nsBoxLayoutState state(mOuter->mPresContext);
mCurrentPos = 0;
mPressed = PR_TRUE;
mDidDrag = PR_FALSE;
nsIFrame* parent = nsnull;
mOuter->GetParent(&parent);
mParentBox = (nsBoxFrame*)parent;
mOuter->GetParentBox(&mParentBox);
// get our index
nscoord childIndex = nsFrameNavigator::IndexOf(mOuter->mPresContext, mParentBox, mOuter);
@@ -721,13 +743,14 @@ nsSplitterFrameInner::MouseDown(nsIDOMEvent* aMouseEvent)
return NS_OK;
}
PRBool isHorizontal = mParentBox->IsHorizontal();
EnsureOrient();
PRBool isHorizontal = !mOuter->IsHorizontal();
ResizeType resizeBefore = GetResizeBefore();
ResizeType resizeAfter = GetResizeAfter();
delete mChildInfosBefore;
delete mChildInfosAfter;
delete[] mChildInfosBefore;
delete[] mChildInfosAfter;
mChildInfosBefore = new nsSplitterInfo[childCount];
mChildInfosAfter = new nsSplitterInfo[childCount];
@@ -737,11 +760,14 @@ nsSplitterFrameInner::MouseDown(nsIDOMEvent* aMouseEvent)
mChildInfosBeforeCount = 0;
mChildInfosAfterCount = 0;
nsIFrame* childFrame = nsnull;
mParentBox->FirstChild(mOuter->mPresContext, nsnull, &childFrame);
nsIBox* childBox = nsnull;
mParentBox->GetChildBox(&childBox);
while (nsnull != childFrame)
while (nsnull != childBox)
{
nsIFrame* childFrame = nsnull;
childBox->GetFrame(&childFrame);
nsCOMPtr<nsIContent> content;
childFrame->GetContent(getter_AddRefs(content));
nsIAtom* atom;
@@ -749,41 +775,48 @@ nsSplitterFrameInner::MouseDown(nsIDOMEvent* aMouseEvent)
// skip over any splitters
if (atom != nsXULAtoms::splitter) {
nsBoxInfo info;
mParentBox->GetChildBoxInfo(count, info);
nsSize prefSize(0,0);
nsSize minSize(0,0);
nsSize maxSize(0,0);
nscoord flex = 0;
const nsStyleSpacing* spacing;
nsresult rv = childFrame->GetStyleData(eStyleStruct_Spacing,
(const nsStyleStruct*&) spacing);
childBox->GetPrefSize(state, prefSize);
childBox->GetMinSize(state, minSize);
childBox->GetMaxSize(state, maxSize);
nsBox::BoundsCheck(minSize, prefSize, maxSize);
NS_ASSERTION(rv == NS_OK,"failed to get spacing info");
mOuter->AddMargin(childBox, minSize);
mOuter->AddMargin(childBox, prefSize);
mOuter->AddMargin(childBox, maxSize);
childBox->GetFlex(state, flex);
nsMargin margin(0,0,0,0);
spacing->GetMargin(margin);
childBox->GetMargin(margin);
nsRect r(0,0,0,0);
childFrame->GetRect(r);
childBox->GetBounds(r);
r.Inflate(margin);
if (count < childIndex) {
mChildInfosBefore[mChildInfosBeforeCount].child = childFrame;
mChildInfosBefore[mChildInfosBeforeCount].min = isHorizontal ? info.minSize.width : info.minSize.height;
mChildInfosBefore[mChildInfosBeforeCount].max = isHorizontal ? info.maxSize.width : info.maxSize.height;
mChildInfosBefore[mChildInfosBeforeCount].child = childBox;
mChildInfosBefore[mChildInfosBeforeCount].min = isHorizontal ? minSize.width : minSize.height;
mChildInfosBefore[mChildInfosBeforeCount].max = isHorizontal ? maxSize.width : maxSize.height;
mChildInfosBefore[mChildInfosBeforeCount].current = isHorizontal ? r.width : r.height;
mChildInfosBefore[mChildInfosBeforeCount].flex = info.flex;
mChildInfosBefore[mChildInfosBeforeCount].flex = flex;
mChildInfosBefore[mChildInfosBeforeCount].index = count;
mChildInfosBeforeCount++;
} else if (count > childIndex) {
mChildInfosAfter[mChildInfosAfterCount].child = childFrame;
mChildInfosAfter[mChildInfosAfterCount].min = isHorizontal ? info.minSize.width : info.minSize.height;
mChildInfosAfter[mChildInfosAfterCount].max = isHorizontal ? info.maxSize.width : info.maxSize.height;
mChildInfosAfter[mChildInfosAfterCount].child = childBox;
mChildInfosAfter[mChildInfosAfterCount].min = isHorizontal ? minSize.width : minSize.height;
mChildInfosAfter[mChildInfosAfterCount].max = isHorizontal ? maxSize.width : maxSize.height;
mChildInfosAfter[mChildInfosAfterCount].current = isHorizontal ? r.width : r.height;
mChildInfosAfter[mChildInfosAfterCount].flex = info.flex;
mChildInfosAfter[mChildInfosAfterCount].flex = flex;
mChildInfosAfter[mChildInfosAfterCount].index = count;
mChildInfosAfterCount++;
}
}
nsresult rv = childFrame->GetNextSibling(&childFrame);
nsresult rv = childBox->GetNextBox(&childBox);
NS_ASSERTION(rv == NS_OK,"failed to get next child");
count++;
}
@@ -823,7 +856,7 @@ nsSplitterFrameInner::MouseDown(nsIDOMEvent* aMouseEvent)
mDragStartPx = c;
//printf("Pressed mDragStartPx=%d\n",mDragStartPx);
printf("Pressed mDragStartPx=%d\n",mDragStartPx);
return NS_OK;
}
@@ -896,14 +929,16 @@ nsSplitterFrameInner::UpdateState()
CollapseDirection direction = GetCollapseDirection();
if (direction != None) {
nsIFrame* splitter = mOuter;
nsIBox* splitter = mOuter;
// Find the splitter's immediate sibling.
nsIFrame* splitterSibling =
nsIBox* splitterSibling =
nsFrameNavigator::GetChildBeforeAfter(mOuter->mPresContext, splitter,
(direction == Before));
if (splitterSibling) {
nsIFrame* splitterSiblingFrame = nsnull;
splitterSibling->GetFrame(&splitterSiblingFrame);
nsCOMPtr<nsIContent> sibling;
if (NS_SUCCEEDED(splitterSibling->GetContent(getter_AddRefs(sibling)))
if (NS_SUCCEEDED(splitterSiblingFrame->GetContent(getter_AddRefs(sibling)))
&& sibling) {
if (mState == Collapsed) {
// Collapsed -> Open
@@ -921,45 +956,130 @@ nsSplitterFrameInner::UpdateState()
}
}
mState = newState;
}
void
nsSplitterFrameInner::EnsureOrient()
{
nsIFrame* frame = nsnull;
mParentBox->GetFrame(&frame);
nsFrameState state;
frame->GetFrameState(&state);
PRBool isHorizontal = !(state & NS_STATE_IS_HORIZONTAL);
if (isHorizontal)
mOuter->mState |= NS_STATE_IS_HORIZONTAL;
else
mOuter->mState &= ~NS_STATE_IS_HORIZONTAL;
}
void
nsSplitterFrameInner::AdjustChildren(nsIPresContext* aPresContext)
{
PRBool isHorizontal = mParentBox->IsHorizontal();
EnsureOrient();
PRBool isHorizontal = !mOuter->IsHorizontal();
AdjustChildren(aPresContext, mChildInfosBefore, mChildInfosBeforeCount, isHorizontal);
AdjustChildren(aPresContext, mChildInfosAfter, mChildInfosAfterCount, isHorizontal);
// printf("----- Posting Dirty -----\n");
#ifdef REAL_TIME_DRAG
// nsBoxLayoutState state(aPresContext);
// state.SetLayoutReason(nsBoxLayoutState::Resize);
//mParentBox->Layout(state);
/*
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
mOuter->mState |= NS_FRAME_IS_DIRTY;
mOuter->mParent->ReflowDirtyChild(shell, mOuter->mParent);
shell->EnterReflowLock();
shell->ProcessReflowCommands(PR_TRUE);
shell->ExitReflowLock(PR_FALSE);
*/
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
nsIFrame* frame = nsnull;
mParentBox->GetFrame(&frame);
/*
shell->EnterReflowLock();
nsRect bounds;
mParentBox->GetBounds(bounds);
nsSize maxSize(bounds.width, bounds.height);
nsIRenderingContext* rcx = nsnull;
nsresult rv = shell->CreateRenderingContext(frame, &rcx);
nsHTMLReflowState reflowState(aPresContext, frame,
eReflowReason_Resize, rcx, maxSize);
nsBoxLayoutState state(aPresContext, reflowState);
mParentBox->Layout(state);
shell->ExitReflowLock(PR_TRUE);
*/
shell->FlushPendingNotifications();
nsCOMPtr<nsIViewManager> viewManager;
nsIView* view = nsnull;
frame->GetView(aPresContext, &view);
nsRect damageRect(0,0,0,0);
mParentBox->GetContentRect(damageRect);
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;
view->GetViewManager(*getter_AddRefs(viewManager));
viewManager->UpdateView(view, rect, NS_VMREFRESH_IMMEDIATE);
}
#else
//mOuter->mState |= NS_FRAME_IS_DIRTY;
//mOuter->mParent->ReflowDirtyChild(shell, mOuter->mParent);
nsBoxLayoutState state(aPresContext);
mOuter->MarkDirty(state);
#endif
}
void
nsSplitterFrameInner::AdjustChildren(nsIPresContext* aPresContext, nsSplitterInfo* aChildInfos, PRInt32 aCount, PRBool aIsHorizontal)
{
// printf("------- AdjustChildren------\n");
///printf("------- AdjustChildren------\n");
nsBoxLayoutState state(aPresContext);
nsCOMPtr<nsIPresShell> shell;
state.GetPresShell(getter_AddRefs(shell));
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
for (int i=0; i < aCount; i++)
{
nscoord pref = aChildInfos[i].changed;
nsIFrame* childFrame = aChildInfos[i].child;
nsresult rv;
nscoord current = aChildInfos[i].current;
nsIBox* childBox = aChildInfos[i].child;
PRInt32 index = aChildInfos[i].index;
const nsStyleSpacing* spacing;
rv = childFrame->GetStyleData(eStyleStruct_Spacing,
(const nsStyleStruct*&) spacing);
//printf("current=%d, pref=%d", current/onePixel, pref/onePixel);
NS_ASSERTION(rv == NS_OK,"failed to get spacing info");
if (current/onePixel == pref/onePixel)
continue;
nsMargin margin(0,0,0,0);
spacing->GetMargin(margin);
nsMargin border(0,0,0,0);
spacing->GetBorderPadding(border);
margin += border;
childBox->GetMargin(margin);
nsIAtom* attribute;
@@ -971,9 +1091,8 @@ nsSplitterFrameInner::AdjustChildren(nsIPresContext* aPresContext, nsSplitterInf
attribute = nsHTMLAtoms::height;
}
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
nsIFrame* childFrame = nsnull;
childBox->GetFrame(&childFrame);
nsCOMPtr<nsIContent> content;
childFrame->GetContent(getter_AddRefs(content));
@@ -981,10 +1100,17 @@ nsSplitterFrameInner::AdjustChildren(nsIPresContext* aPresContext, nsSplitterInf
// set its preferred size.
char ch[50];
sprintf(ch,"%d",pref/onePixel);
//printf("index=%d, pref=%s\n", i, ch);
content->SetAttribute(kNameSpaceID_None, attribute, ch, PR_FALSE);
mParentBox->InvalidateCache(childFrame);
#ifndef REAL_TIME_DRAG
childBox->MarkDirty(state);
#else
childBox->MarkDirty(state);
#endif
}
//printf("\n");
}
@@ -1068,7 +1194,9 @@ nsSplitterFrameInner::MoveSplitterBy(nsIPresContext* aPresContext, nscoord aDiff
v->GetViewManager(*getter_AddRefs(vm));
v->GetBounds(vr);
nsRect invalid;
if (mParentBox->IsHorizontal()) {
EnsureOrient();
PRBool isHorizontal = !mOuter->IsHorizontal();
if (isHorizontal) {
mOuter->MoveTo(aPresContext, mSplitterPos + aDiff, r.y);
vm->MoveViewTo(v, mSplitterViewPos + aDiff, vr.y);
invalid.UnionRect(r,mOuter->mRect);
@@ -1080,7 +1208,9 @@ nsSplitterFrameInner::MoveSplitterBy(nsIPresContext* aPresContext, nscoord aDiff
// redraw immediately only what changed. This is animation so
// it must be immediate.
mParentBox->Invalidate(aPresContext, invalid, PR_TRUE);
nsBoxLayoutState state(aPresContext);
mParentBox->Redraw(state, &invalid, PR_TRUE);
}

View File

@@ -48,6 +48,7 @@ public:
}
#endif
// nsIFrame overrides
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
@@ -65,6 +66,7 @@ public:
nsPoint& aPoint,
PRInt32& aCursor);
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
// nsIAnonymousContentCreator
NS_IMETHOD CreateAnonymousContent(nsIPresContext* aPresContext,
@@ -93,7 +95,10 @@ public:
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext, const nsPoint& aPoint, nsFramePaintLayer aWhichLayer, nsIFrame** aFrame);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
virtual PRBool GetInitialOrientation(PRBool& aIsHorizontal);

View File

@@ -37,7 +37,7 @@ NS_NewSpringFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsSpringFrame* it = new (aPresShell) nsSpringFrame;
nsSpringFrame* it = new (aPresShell) nsSpringFrame (aPresShell);
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
@@ -51,22 +51,20 @@ NS_IMETHODIMP nsSpringFrame::GetFrameForPoint(nsIPresContext* aPresContext,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame)
{
if (!mRect.Contains(aPoint)) {
if (!mRect.Contains(aPoint))
return NS_ERROR_FAILURE;
}
// always return us (if visible)
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->IsVisible()) {
// see if it is in our border, padding, or inset
nsRect r(mRect);
nsMargin m;
GetInset(m);
r.Deflate(m);
GetBorderAndPadding(m);
r.Deflate(m);
if (!r.Contains(aPoint)) {
*aFrame = this;
return NS_OK;
}
return NS_ERROR_FAILURE;
/*
// clicks just go right through springs.
return NS_ERROR_FAILURE;
*/
}

View File

@@ -31,9 +31,10 @@
#ifndef nsSpringFrame_h___
#define nsSpringFrame_h___
#include "nsXULLeafFrame.h"
#include "nsLeafBoxFrame.h"
struct nsPoint;
class nsSpringFrame : public nsXULLeafFrame
class nsSpringFrame : public nsLeafBoxFrame
{
public:
@@ -50,6 +51,8 @@ public:
aResult = "Spring";
return NS_OK;
}
nsSpringFrame(nsIPresShell* aShell):nsLeafBoxFrame(aShell) {}
}; // class nsSpringFrame

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,175 @@
/* -*- 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.
*
* Author:
* Eric D Vaughan
*
* Contributor(s):
*/
#ifndef nsSprocketLayout_h___
#define nsSprocketLayout_h___
#include "nsBoxLayout.h"
class nsBoxSize
{
public:
nsBoxSize();
nscoord pref;
nscoord min;
nscoord max;
nscoord ascent;
nscoord flex;
nscoord left;
nscoord right;
PRBool collapsed;
nsBoxSize* next;
void Add(nsSize minSize,
nsSize prefSize,
nsSize maxSize,
nscoord ascent,
nscoord flex,
PRBool aIsHorizontal);
void Add(const nsMargin& aMargin, PRBool aIsHorizontal);
void* operator new(size_t sz, nsBoxLayoutState& aState);
void operator delete(void* aPtr, size_t sz);
};
class nsComputedBoxSize
{
public:
nsComputedBoxSize();
nscoord size;
PRBool valid;
PRBool resized;
nsComputedBoxSize* next;
void* operator new(size_t sz, nsBoxLayoutState& aState);
void operator delete(void* aPtr, size_t sz);
};
#define GET_WIDTH(size, isHorizontal) (isHorizontal ? size.width : size.height)
#define GET_HEIGHT(size, isHorizontal) (isHorizontal ? size.height : size.width)
#define GET_X(size, isHorizontal) (isHorizontal ? size.x : size.y)
#define GET_Y(size, isHorizontal) (isHorizontal ? size.y : size.x)
#define GET_COORD(aX, aY, isHorizontal) (isHorizontal ? aX : aY)
#define SET_WIDTH(size, coord, isHorizontal) if (isHorizontal) { (size).width = (coord); } else { (size).height = (coord); }
#define SET_HEIGHT(size, coord, isHorizontal) if (isHorizontal) { (size).height = (coord); } else { (size).width = (coord); }
#define SET_X(size, coord, isHorizontal) if (isHorizontal) { (size).x = (coord); } else { (size).y = (coord); }
#define SET_Y(size, coord, isHorizontal) if (isHorizontal) { (size).y = (coord); } else { (size).x = (coord); }
#define SET_COORD(aX, aY, coord, isHorizontal) if (isHorizontal) { aX = (coord); } else { aY = (coord); }
class nsBoxSizeList
{
public:
virtual nsBoxSize* GetBoxSize(nsBoxLayoutState& aState)=0;
virtual nsBoxSizeList* GetFirst()=0;
virtual nsBoxSizeList* GetLast()=0;
virtual nsBoxSizeList* GetNext()=0;
virtual nsBoxSizeList* GetParent()=0;
virtual void SetParent(nsBoxSizeList* aParent)=0;
virtual void SetNext(nsIPresShell* aShell, nsBoxSizeList* aNext)=0;
virtual void Append(nsIPresShell* aShell, nsBoxSizeList* aChild)=0;
virtual void Clear(nsIPresShell* aShell)=0;
virtual PRInt32 GetCount()=0;
virtual void Desecrate()=0;
virtual void AddRef()=0;
virtual void Release(nsIPresShell* aShell)=0;
};
class nsSprocketLayout : public nsBoxLayout {
public:
NS_IMETHOD Layout(nsIBox* aBox, nsBoxLayoutState& aState);
NS_IMETHOD GetPrefSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMaxSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetFlex(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nscoord& aFlex);
NS_IMETHOD GetAscent(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent);
NS_IMETHOD IsCollapsed(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, PRBool& aCollapsed);
nsSprocketLayout(nsIPresShell* aShell);
protected:
virtual PRBool IsHorizontal(nsIBox* aBox) const;
virtual void SetLargestSize(nsSize& aSize1, const nsSize& aSize2, PRBool aIsHorizontal);
virtual void SetSmallestSize(nsSize& aSize1, const nsSize& aSize2, PRBool aIsHorizontal);
virtual void AddLargestSize(nsSize& aSize, const nsSize& aSizeToAdd, PRBool aIsHorizontal);
virtual void AddSmallestSize(nsSize& aSize, const nsSize& aSizeToAdd, PRBool aIsHorizontal);
virtual void AddCoord(nscoord& aCoord, nscoord aCoordToAdd);
virtual void ComputeChildsNextPosition(nsIBox* aBox,
nsIBox* aChild,
nscoord& aCurX,
nscoord& aCurY,
nscoord& aNextX,
nscoord& aNextY,
const nsRect& aChildSize,
const nsRect& aContainingRect,
nscoord childAscent,
nscoord aMaxAscent);
virtual void ChildResized(nsIBox* aBox,
nsBoxLayoutState& aState,
nsIBox* aChild,
nsBoxSize* aChildBoxSize,
nsComputedBoxSize* aChildComputedBoxSize,
nsBoxSize* aBoxSizes,
nsComputedBoxSize* aComputedBoxSizes,
const nsRect& aChildLayoutRect,
nsRect& aChildActualRect,
nsRect& aContainingRect,
PRInt32 aFlexes,
PRBool& aFinished);
virtual void ComputeChildSizes(nsBoxLayoutState& aState,
nscoord& aGivenSize,
nsBoxSize* aBoxSizes,
nsComputedBoxSize* aComputedBoxSizes);
virtual void PopulateBoxSizes(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsBoxSize*& aBoxSizes, nsComputedBoxSize*& aComputedBoxSizes, nscoord& aMinSize, nscoord& aMaxSize, PRInt32& aFlexes);
virtual void InvalidateComputedSizes(nsComputedBoxSize* aComputedBoxSizes);
virtual PRBool GetDefaultFlex(PRInt32& aFlex);
virtual void GetFrameState(nsIBox* aBox, nsFrameState& aState);
virtual void SetFrameState(nsIBox* aBox, nsFrameState aState);
};
#endif

View File

@@ -43,7 +43,8 @@
#include "nsStyleChangeList.h"
#include "nsCSSRendering.h"
#include "nsIViewManager.h"
#include "nsBoxLayoutState.h"
#include "nsStackLayout.h"
nsresult
NS_NewStackFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
@@ -59,108 +60,32 @@ NS_NewStackFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
*aNewFrame = it;
return NS_OK;
} // NS_NewDeckFrame
} // NS_NewStackFrame
nsCOMPtr<nsIBoxLayout> nsStackFrame::gLayout = nsnull;
nsStackFrame::nsStackFrame(nsIPresShell* aPresShell):nsBoxFrame(aPresShell)
{
if (!gLayout)
gLayout = new nsStackLayout(aPresShell);
SetLayoutManager(gLayout);
}
NS_IMETHODIMP
nsStackFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
// Get the element's tag
nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
return rv;
}
void
nsStackFrame::AddChildSize(nsBoxInfo& aInfo, nsBoxInfo& aChildInfo)
{
// largest preferred size
if (aChildInfo.prefSize.width > aInfo.prefSize.width)
aInfo.prefSize.width = aChildInfo.prefSize.width;
if (aChildInfo.prefSize.height > aInfo.prefSize.height)
aInfo.prefSize.height = aChildInfo.prefSize.height;
// largest min size
if (aChildInfo.minSize.width > aInfo.minSize.width)
aInfo.minSize.width = aChildInfo.minSize.width;
if (aChildInfo.minSize.height > aInfo.minSize.height)
aInfo.minSize.height = aChildInfo.minSize.height;
// smallest max size
if (aChildInfo.maxSize.width < aInfo.maxSize.width)
aInfo.maxSize.width = aChildInfo.maxSize.width;
if (aChildInfo.maxSize.height < aInfo.maxSize.height)
aInfo.maxSize.height = aChildInfo.maxSize.height;
}
void
nsStackFrame::ComputeChildsNextPosition(nsCalculatedBoxInfo* aInfo, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect, nscoord aMaxAscent)
{
// let everything layout on top of each other.
aCurX = aNextX = aBoxRect.x;
aCurY = aNextY = aBoxRect.y;
}
void
nsStackFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool*& aResized, PRInt32 aInfoCount, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason)
{
if (aDesiredSize.width > aRect.width) {
aRect.width = aDesiredSize.width;
InvalidateChildren();
LayoutChildrenInRect(aRect, aMaxAscent);
aReason = "child's width got bigger";
aChangedIndex = aIndex;
aFinished = PR_FALSE;
} else if (aDesiredSize.height > aRect.height) {
aRect.height = aDesiredSize.height;
InvalidateChildren();
LayoutChildrenInRect(aRect, aMaxAscent);
aReason = "child's height got bigger";
aChangedIndex = aIndex;
aFinished = PR_FALSE;
}
}
void
nsStackFrame::LayoutChildrenInRect(nsRect& aGivenSize, nscoord& aMaxAscent)
{
nsInfoList* list = GetInfoList();
nsCalculatedBoxInfo* info = list->GetFirst();
while(info) {
info->calculatedSize.width = aGivenSize.width;
info->calculatedSize.height = aGivenSize.height;
info->mFlags |= NS_FRAME_BOX_SIZE_VALID;
info = info->next;
}
aMaxAscent = 0;
}
NS_IMETHODIMP
nsStackFrame::GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame)
{
return nsBoxFrame::GetFrameForPoint(aPresContext, aPoint, aWhichLayer, aFrame);
/*
nsRect r(mRect);
// if it is not inside us or not in the layer in which we paint, fail
if ((aWhichLayer != NS_FRAME_PAINT_LAYER_BACKGROUND) ||
(!r.Contains(aPoint))) {
if (!r.Contains(aPoint))
return NS_ERROR_FAILURE;
}
// is it inside our border, padding, and debugborder or insets?
nsMargin im(0,0,0,0);
@@ -209,6 +134,7 @@ nsStackFrame::GetFrameForPoint(nsIPresContext* aPresContext,
}
}
#ifdef NS_DEBUG
printf("\n------------");
@@ -217,8 +143,9 @@ nsStackFrame::GetFrameForPoint(nsIPresContext* aPresContext,
printf("--------------\n");
#endif
return rv;
return rv;
*/
}
@@ -278,4 +205,3 @@ nsStackFrame::PaintChild(nsIPresContext* aPresContext,
nsBoxFrame::PaintChild(aPresContext, aRenderingContext, aDirtyRect, aFrame, NS_FRAME_PAINT_LAYER_FOREGROUND);
}
}

View File

@@ -24,7 +24,7 @@
Eric D Vaughan
A frame that can have multiple children. Only one child may be displayed at one time. So the
can be flipped though like a deck of cards.
can be flipped though like a Stack of cards.
**/
@@ -39,32 +39,12 @@ public:
friend nsresult NS_NewStackFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* asPrevInFlow);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
NS_IMETHOD GetFrameName(nsString& aResult) const
{
aResult = "Stack";
return NS_OK;
}
protected:
nsStackFrame(nsIPresShell* aShell);
// Paint one child frame
virtual void PaintChild(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@@ -76,10 +56,11 @@ protected:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
virtual void ComputeChildsNextPosition( nsCalculatedBoxInfo* aInfo, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect, nscoord aMaxAscent);
virtual void ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool*& aResized, PRInt32 aInfoCount, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason);
virtual void LayoutChildrenInRect(nsRect& aSize, nscoord& aMaxAscent);
virtual void AddChildSize(nsBoxInfo& aInfo, nsBoxInfo& aChildInfo);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
private:
virtual nsresult GetStackedFrameForPoint(nsIPresContext* aPresContext,
@@ -87,6 +68,14 @@ private:
const nsRect& aRect,
const nsPoint& aPoint,
nsIFrame** aFrame);
protected:
nsStackFrame(nsIPresShell* aPresShell);
private:
static nsCOMPtr<nsIBoxLayout> gLayout;
}; // class nsStackFrame

View File

@@ -0,0 +1,266 @@
/* -*- 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 "nsStackLayout.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"
#include "nsBoxLayoutState.h"
#include "nsIBox.h"
nsStackLayout::nsStackLayout(nsIPresShell* aPresShell)
{
}
NS_IMETHODIMP
nsStackLayout::GetPrefSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
aSize.width = 0;
aSize.height = 0;
// run through all the children and get there min, max, and preferred sizes
// return us the size of the box
nsIBox* child = nsnull;
aBox->GetChildBox(&child);
while (child)
{
// ignore collapsed children
PRBool isCollapsed = PR_FALSE;
child->IsCollapsed(aBoxLayoutState, isCollapsed);
if (!isCollapsed)
{
nsSize pref(0,0);
child->GetPrefSize(aBoxLayoutState, pref);
AddMargin(child, pref);
AddLargestSize(aSize, pref);
}
child->GetNextBox(&child);
}
// now add our border and padding and insets
AddBorderAndPadding(aBox, aSize);
AddInset(aBox, aSize);
return NS_OK;
}
NS_IMETHODIMP
nsStackLayout::GetMinSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
aSize.width = 0;
aSize.height = 0;
// run through all the children and get there min, max, and preferred sizes
// return us the size of the box
nsIBox* child = nsnull;
aBox->GetChildBox(&child);
while (child)
{
// ignore collapsed children
PRBool isCollapsed = PR_FALSE;
aBox->IsCollapsed(aBoxLayoutState, isCollapsed);
if (!isCollapsed)
{
nsSize min(0,0);
child->GetMinSize(aBoxLayoutState, min);
AddMargin(child, min);
AddLargestSize(aSize, min);
}
child->GetNextBox(&child);
}
// now add our border and padding and insets
AddBorderAndPadding(aBox, aSize);
AddInset(aBox,aSize);
return NS_OK;
}
NS_IMETHODIMP
nsStackLayout::GetMaxSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
aSize.width = NS_INTRINSICSIZE;
aSize.height = NS_INTRINSICSIZE;
// run through all the children and get there min, max, and preferred sizes
// return us the size of the box
nsIBox* child = nsnull;
aBox->GetChildBox(&child);
while (child)
{
// ignore collapsed children
PRBool isCollapsed = PR_FALSE;
aBox->IsCollapsed(aBoxLayoutState, isCollapsed);
if (!isCollapsed)
{
// if completely redefined don't even ask our child for its size.
nsSize max(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
child->GetMaxSize(aBoxLayoutState, max);
AddMargin(child, max);
AddSmallestSize(aSize, max);
}
child->GetNextBox(&child);
}
// now add our border and padding and insets
AddBorderAndPadding(aBox, aSize);
AddInset(aBox, aSize);
return NS_OK;
}
NS_IMETHODIMP
nsStackLayout::GetAscent(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent)
{
aAscent = 0;
// run through all the children and get there min, max, and preferred sizes
// return us the size of the box
nsIBox* child = nsnull;
aBox->GetChildBox(&child);
while (child)
{
// ignore collapsed children
PRBool isCollapsed = PR_FALSE;
aBox->IsCollapsed(aBoxLayoutState, isCollapsed);
if (!isCollapsed)
{
// if completely redefined don't even ask our child for its size.
nscoord ascent = 0;
child->GetAscent(aBoxLayoutState, ascent);
nsMargin margin;
child->GetMargin(margin);
ascent += margin.top + margin.bottom;
if (ascent > aAscent)
aAscent = ascent;
}
child->GetNextBox(&child);
}
return NS_OK;
}
NS_IMETHODIMP
nsStackLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
{
nsRect clientRect;
aBox->GetClientRect(clientRect);
nsIBox* child = nsnull;
PRBool grow;
do {
aBox->GetChildBox(&child);
grow = PR_FALSE;
while (child)
{
nsMargin margin;
child->GetMargin(margin);
nsRect childRect(clientRect);
childRect.Deflate(margin);
child->SetBounds(aState, childRect);
child->Layout(aState);
child->GetBounds(childRect);
childRect.Inflate(margin);
// did the child push back on us and get bigger?
if (childRect.width > clientRect.width) {
clientRect.width = childRect.width;
grow = PR_TRUE;
}
if (childRect.height > clientRect.height) {
clientRect.height = childRect.height;
grow = PR_TRUE;
}
child->GetNextBox(&child);
}
} while(grow);
// if some HTML inside us got bigger we need to force ourselves to
// get bigger
nsRect bounds;
aBox->GetBounds(bounds);
nsMargin bp;
aBox->GetBorderAndPadding(bp);
clientRect.Inflate(bp);
aBox->GetInset(bp);
clientRect.Inflate(bp);
if (clientRect.width > bounds.width || clientRect.height > bounds.height)
{
if (clientRect.width > bounds.width)
bounds.width = clientRect.width;
if (clientRect.height > bounds.height)
bounds.height = clientRect.height;
aBox->SetBounds(aState, bounds);
}
return NS_OK;
}

View File

@@ -0,0 +1,53 @@
/* -*- 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 D Vaughan
A frame that can have multiple children. Only one child may be displayed at one time. So the
can be flipped though like a deck of cards.
**/
#ifndef nsStackLayout_h___
#define nsStackLayout_h___
#include "nsBoxLayout.h"
class nsStackLayout : public nsBoxLayout
{
public:
nsStackLayout(nsIPresShell* aShell);
NS_IMETHOD Layout(nsIBox* aBox, nsBoxLayoutState& aState);
NS_IMETHOD GetPrefSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMaxSize(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetAscent(nsIBox* aBox, nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent);
}; // class nsStackLayout
#endif

View File

@@ -62,7 +62,7 @@ NS_NewTabFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
} // NS_NewTabFrame
nsTabFrame::nsTabFrame(nsIPresShell* aPresShell)
:nsXULButtonFrame(aPresShell)
:nsButtonBoxFrame(aPresShell)
{
}

View File

@@ -30,11 +30,11 @@
#ifndef nsTabFrame_h___
#define nsTabFrame_h___
#include "nsXULButtonFrame.h"
#include "nsButtonBoxFrame.h"
class nsTabControlFrame;
class nsTabFrame : public nsXULButtonFrame
class nsTabFrame : public nsButtonBoxFrame
{
public:

View File

@@ -27,7 +27,7 @@
// See documentation in associated header file
//
#include "nsXULTextFrame.h"
#include "nsTextBoxFrame.h"
#include "nsCOMPtr.h"
#include "nsIDeviceContext.h"
#include "nsIFontMetrics.h"
@@ -38,6 +38,7 @@
#include "nsIStyleContext.h"
#include "nsIContent.h"
#include "nsINameSpaceManager.h"
#include "nsBoxLayoutState.h"
#define ELIPSIS "..."
@@ -61,13 +62,13 @@ public:
// Creates a new Toolbar frame and returns it in |aNewFrame|
//
nsresult
NS_NewXULTextFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
NS_NewTextBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsXULTextFrame* it = new (aPresShell) nsXULTextFrame;
nsTextBoxFrame* it = new (aPresShell) nsTextBoxFrame (aPresShell);
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
@@ -79,7 +80,7 @@ NS_NewXULTextFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
NS_IMETHODIMP
nsXULTextFrame::AttributeChanged(nsIPresContext* aPresContext,
nsTextBoxFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
@@ -96,23 +97,23 @@ nsXULTextFrame::AttributeChanged(nsIPresContext* aPresContext,
UpdateAccessUnderline();
if (aResize) {
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
mState |= NS_FRAME_IS_DIRTY;
mParent->ReflowDirtyChild(shell, this);
nsBoxLayoutState state(aPresContext);
MarkDirty(state);
} else if (aRedraw) {
Invalidate(aPresContext, nsRect(0,0,mRect.width, mRect.height), PR_FALSE);
nsBoxLayoutState state(aPresContext);
Redraw(state);
}
return NS_OK;
}
nsXULTextFrame::nsXULTextFrame():mCropType(CropRight),mTitle(""), mAccessKeyInfo(nsnull)
nsTextBoxFrame::nsTextBoxFrame(nsIPresShell* aShell):nsLeafBoxFrame(aShell),mTitle(""), mCropType(CropRight),mAccessKeyInfo(nsnull)
{
mState |= NS_STATE_NEED_LAYOUT;
NeedsRecalc();
}
nsXULTextFrame::~nsXULTextFrame()
nsTextBoxFrame::~nsTextBoxFrame()
{
if (mAccessKeyInfo)
delete mAccessKeyInfo;
@@ -120,13 +121,13 @@ nsXULTextFrame::~nsXULTextFrame()
NS_IMETHODIMP
nsXULTextFrame::Init(nsIPresContext* aPresContext,
nsTextBoxFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsXULLeafFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
nsresult rv = nsLeafBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
PRBool a,b,c;
UpdateAttributes(aPresContext, nsnull, a, b, c /* all */);
@@ -139,7 +140,7 @@ nsXULTextFrame::Init(nsIPresContext* aPresContext,
nsAutoString accesskey;
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey,
accesskey);
if (!accesskey.IsEmpty()) {
if (accesskey != "") {
if (!mAccessKeyInfo)
mAccessKeyInfo = new nsAccessKeyInfo();
@@ -168,7 +169,7 @@ nsXULTextFrame::Init(nsIPresContext* aPresContext,
}
void
nsXULTextFrame::UpdateAttributes(nsIPresContext* aPresContext, nsIAtom* aAttribute, PRBool& aResize, PRBool& aRedraw, PRBool& aUpdateAccessUnderline)
nsTextBoxFrame::UpdateAttributes(nsIPresContext* aPresContext, nsIAtom* aAttribute, PRBool& aResize, PRBool& aRedraw, PRBool& aUpdateAccessUnderline)
{
aResize = PR_FALSE;
aRedraw = PR_FALSE;
@@ -222,14 +223,14 @@ nsXULTextFrame::UpdateAttributes(nsIPresContext* aPresContext, nsIAtom* aAttrib
}
NS_IMETHODIMP
nsXULTextFrame::Paint(nsIPresContext* aPresContext,
nsTextBoxFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisibleOrCollapsed())
if (!disp->IsVisible())
return NS_OK;
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
@@ -251,7 +252,7 @@ nsXULTextFrame::Paint(nsIPresContext* aPresContext,
void
nsXULTextFrame::LayoutTitle(nsIPresContext* aPresContext,
nsTextBoxFrame::LayoutTitle(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer,
@@ -298,7 +299,7 @@ nsXULTextFrame::LayoutTitle(nsIPresContext* aPresContext,
}
NS_IMETHODIMP
nsXULTextFrame::PaintTitle(nsIPresContext* aPresContext,
nsTextBoxFrame::PaintTitle(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer,
@@ -364,7 +365,7 @@ nsXULTextFrame::PaintTitle(nsIPresContext* aPresContext,
}
void
nsXULTextFrame::GetTextSize(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext,
nsTextBoxFrame::GetTextSize(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext,
const nsString& aString, nsSize& aSize, nscoord& aAscent)
{
const nsStyleFont* fontStyle = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
@@ -381,7 +382,7 @@ nsXULTextFrame::GetTextSize(nsIPresContext* aPresContext, nsIRenderingContext& a
}
void
nsXULTextFrame::CalculateTitleForWidth(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, nscoord aWidth)
nsTextBoxFrame::CalculateTitleForWidth(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, nscoord aWidth)
{
if (mTitle.Length() == 0)
return;
@@ -534,13 +535,13 @@ nsXULTextFrame::CalculateTitleForWidth(nsIPresContext* aPresContext, nsIRenderin
}
void
nsXULTextFrame::UpdateAccessUnderline()
nsTextBoxFrame::UpdateAccessUnderline()
{
#ifndef XP_UNIX
nsAutoString accesskey;
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey,
accesskey);
if (accesskey.IsEmpty()) {
if (accesskey == "") {
if (mAccessKeyInfo) {
delete mAccessKeyInfo;
mAccessKeyInfo = nsnull;
@@ -559,41 +560,95 @@ nsXULTextFrame::UpdateAccessUnderline()
NS_IMETHODIMP
nsXULTextFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
nsTextBoxFrame::Layout(nsBoxLayoutState& aBoxLayoutState)
{
mState |= NS_STATE_NEED_LAYOUT;
return nsXULLeafFrame::Reflow(aPresContext, aMetrics, aReflowState, aStatus);
return nsLeafBoxFrame::Layout(aBoxLayoutState);
}
NS_IMETHODIMP
nsTextBoxFrame::NeedsRecalc()
{
mNeedsRecalc = PR_TRUE;
return NS_OK;
}
void
nsTextBoxFrame::CalcTextSize(nsBoxLayoutState& aBoxLayoutState)
{
if (mNeedsRecalc)
{
nsSize size;
nscoord ascent = 0;
nsIPresContext* presContext = aBoxLayoutState.GetPresContext();
nsIRenderingContext* rendContext = aBoxLayoutState.GetReflowState()->rendContext;
if (rendContext) {
GetTextSize(presContext, *rendContext,
mTitle, size, mAscent);
mTextSize = size;
mNeedsRecalc = PR_FALSE;
}
}
}
/**
* Ok return our dimensions
*/
NS_IMETHODIMP
nsXULTextFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize)
nsTextBoxFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
// depending on the type of alignment add in the space for the text
nsSize size;
nscoord ascent = 0;
GetTextSize(aPresContext, *aReflowState.rendContext,
mTitle, size, ascent);
CalcTextSize(aBoxLayoutState);
aSize.ascent = ascent;
aSize.prefSize = size;
aSize.minSize = size;
aSize = mTextSize;
// if there is cropping our min width becomes 0
if (mCropType != CropNone)
aSize.minSize.width = 0;
AddBorderAndPadding(aSize);
AddInset(aSize);
nsIBox::AddCSSPrefSize(aBoxLayoutState, this, aSize);
return NS_OK;
}
/**
* Ok return our dimensions
*/
NS_IMETHODIMP
nsTextBoxFrame::GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
CalcTextSize(aBoxLayoutState);
aSize = mTextSize;
// if there is cropping our min width becomes our border and padding
if (mCropType != CropNone) {
aSize.width = 0;
}
AddBorderAndPadding(aSize);
AddInset(aSize);
nsIBox::AddCSSMinSize(aBoxLayoutState, this, aSize);
return NS_OK;
}
NS_IMETHODIMP
nsXULTextFrame::GetFrameName(nsString& aResult) const
nsTextBoxFrame::GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent)
{
CalcTextSize(aBoxLayoutState);
aAscent = mAscent;
nsMargin m(0,0,0,0);
GetBorderAndPadding(m);
aAscent += m.top;
GetInset(m);
aAscent += m.top;
return NS_OK;
}
NS_IMETHODIMP
nsTextBoxFrame::GetFrameName(nsString& aResult) const
{
aResult = "Text[value=";
aResult += mTitle;

View File

@@ -19,23 +19,27 @@
*
* Contributor(s):
*/
#ifndef nsXULTextFrame_h___
#define nsXULTextFrame_h___
#ifndef nsTextBoxFrame_h___
#define nsTextBoxFrame_h___
#include "nsXULLeafFrame.h"
#include "nsLeafBoxFrame.h"
class nsAccessKeyInfo;
class nsXULTextFrame : public nsXULLeafFrame
class nsTextBoxFrame : public nsLeafBoxFrame
{
public:
// nsIBox
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent);
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD NeedsRecalc();
enum CroppingStyle { CropNone, CropLeft, CropRight, CropCenter };
friend nsresult NS_NewXULTextFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
// nsIBox frame interface
NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize);
friend nsresult NS_NewTextBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,
@@ -53,11 +57,6 @@ public:
virtual void UpdateAttributes(nsIPresContext* aPresContext, nsIAtom* aAttribute, PRBool& aResize, PRBool& aRedraw, PRBool& aUpdateAccessUnderline);
// nsIHTMLReflow overrides
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@@ -65,7 +64,7 @@ public:
nsFramePaintLayer aWhichLayer);
~nsXULTextFrame();
~nsTextBoxFrame();
protected:
void UpdateAccessUnderline();
@@ -82,8 +81,9 @@ protected:
nsFramePaintLayer aWhichLayer,
const nsRect& aTextRect);
virtual void CalcTextSize(nsBoxLayoutState& aBoxLayoutState);
nsXULTextFrame();
nsTextBoxFrame(nsIPresShell* aShell);
virtual void CalculateTitleForWidth(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, nscoord aWidth);
virtual void GetTextSize(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsString& aString, nsSize& aSize, nscoord& aAscent);
@@ -95,6 +95,9 @@ private:
nsString mCroppedTitle;
nscoord mTitleWidth;
nsAccessKeyInfo* mAccessKeyInfo;
}; // class nsXULTextFrame
PRBool mNeedsRecalc;
nsSize mTextSize;
nscoord mAscent;
}; // class nsTextBoxFrame
#endif /* nsXULTextFrame_h___ */
#endif /* nsTextBoxFrame_h___ */

View File

@@ -59,6 +59,9 @@ public:
nsIAtom* aListName,
nsIFrame* aChildList);
NS_IMETHOD GetBorderAndPadding(nsMargin& aBorderAndPadding);
NS_METHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
@@ -81,11 +84,6 @@ public:
}
#endif
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
virtual PRBool GetInitialOrientation(PRBool& aHorizontal) { aHorizontal = PR_FALSE; return PR_TRUE; }
nsIFrame* GetTitleFrame(nsIPresContext* aPresContext, nsRect& aRect);
@@ -322,27 +320,10 @@ nsTitledBoxFrame::GetContentFrame(nsIPresContext* aPresContext)
}
NS_IMETHODIMP
nsTitledBoxFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
nsTitledBoxFrame::GetBorderAndPadding(nsMargin& aBorderAndPadding)
{
if (aReflowState.mComputedBorderPadding.top != 0)
{
nsHTMLReflowState newState(aReflowState);
if (newState.mComputedHeight != NS_INTRINSICSIZE)
newState.mComputedHeight += aReflowState.mComputedBorderPadding.top;
// remove the border from border padding
((nsMargin&)newState.mComputedBorderPadding).top = 0;
((nsMargin&)newState.mComputedPadding).top = 0;
// reflow us again with the correct values.
return Reflow(aPresContext, aDesiredSize, newState, aStatus);
}
return nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
aBorderAndPadding.SizeTo(0,0,0,0);
return NS_OK;
}
NS_IMETHODIMP

View File

@@ -38,6 +38,7 @@
#include "nsCOMPtr.h"
#include "nsIPresContext.h"
#include "nsButtonFrameRenderer.h"
#include "nsBoxLayoutState.h"
#include "nsHTMLParts.h"
#include "nsString.h"
@@ -71,6 +72,7 @@
#include "nsIDOMHTMLMapElement.h"
#include "nsIStyleSet.h"
#include "nsIStyleContext.h"
#include "nsBoxLayoutState.h"
#include "nsFormControlHelper.h"
@@ -130,6 +132,11 @@ nsTitledButtonFrame::UpdateImageFrame(nsIPresContext* aPresContext,
PRUint32 aStatus)
{
if (NS_IMAGE_LOAD_STATUS_SIZE_AVAILABLE & aStatus) {
nsTitledButtonFrame* us = (nsTitledButtonFrame*)aFrame;
nsBoxLayoutState state(aPresContext);
us->MarkDirty(state);
/*
// Now that the size is available, trigger a content-changed reflow
nsIContent* content = nsnull;
aFrame->GetContent(&content);
@@ -142,6 +149,7 @@ nsTitledButtonFrame::UpdateImageFrame(nsIPresContext* aPresContext,
}
NS_RELEASE(content);
}
*/
}
return NS_OK;
}
@@ -158,7 +166,7 @@ NS_NewTitledButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsTitledButtonFrame* it = new (aPresShell) nsTitledButtonFrame;
nsTitledButtonFrame* it = new (aPresShell) nsTitledButtonFrame (aPresShell);
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
@@ -187,10 +195,8 @@ nsTitledButtonFrame::AttributeChanged(nsIPresContext* aPresContext,
UpdateAccessUnderline();
if (aResize) {
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
mState |= NS_FRAME_IS_DIRTY;
mParent->ReflowDirtyChild(shell, this);
nsBoxLayoutState state(aPresContext);
MarkDirty(state);
} else if (aRedraw) {
mRenderer->Redraw(aPresContext);
}
@@ -210,7 +216,10 @@ nsTitledButtonFrame::AttributeChanged(nsIPresContext* aPresContext,
return NS_OK;
}
nsTitledButtonFrame::nsTitledButtonFrame()
nsTitledButtonFrame::nsTitledButtonFrame(nsIPresShell* aShell):nsLeafBoxFrame(aShell),
mPrefSize(0,0),
mMinSize(0,0),
mAscent(0)
{
mTitle = "";
mAlign = GetDefaultAlignment();
@@ -220,6 +229,7 @@ nsTitledButtonFrame::nsTitledButtonFrame()
mHasImage = PR_FALSE;
mHasOnceBeenInMixedState = PR_FALSE;
mRenderer = new nsTitledButtonRenderer();
NeedsRecalc();
}
nsTitledButtonFrame::~nsTitledButtonFrame()
@@ -227,13 +237,21 @@ nsTitledButtonFrame::~nsTitledButtonFrame()
delete mRenderer;
}
NS_IMETHODIMP
nsTitledButtonFrame::NeedsRecalc()
{
mNeedsRecalc = PR_TRUE;
return NS_OK;
}
NS_METHOD
nsTitledButtonFrame::Destroy(nsIPresContext* aPresContext)
{
// Release image loader first so that it's refcnt can go to zero
mImageLoader.StopAllLoadImages(aPresContext);
return nsXULLeafFrame::Destroy(aPresContext);
return nsLeafBoxFrame::Destroy(aPresContext);
}
@@ -244,7 +262,7 @@ nsTitledButtonFrame::Init(nsIPresContext* aPresContext,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsXULLeafFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
nsresult rv = nsLeafBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mRenderer->SetNameSpace(kNameSpaceID_None);
mRenderer->SetFrame(this,aPresContext);
@@ -938,21 +956,6 @@ nsTitledButtonFrame::PaintImage(nsIPresContext* aPresContext,
return NS_OK;
}
NS_IMETHODIMP
nsTitledButtonFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
mNeedsLayout = PR_TRUE;
nsresult result = nsXULLeafFrame::Reflow(aPresContext, aMetrics, aReflowState, aStatus);
return result;
}
struct nsTitleRecessedBorder : public nsStyleSpacing {
nsTitleRecessedBorder(nscoord aBorderWidth)
: nsStyleSpacing()
@@ -1204,7 +1207,7 @@ nsTitledButtonFrame::HandleEvent(nsIPresContext* aPresContext,
break;
}
return nsXULLeafFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
return nsLeafBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
//
@@ -1388,22 +1391,79 @@ nsTitledButtonFrame::GetImageSize(nsIPresContext* aPresContext)
* Ok return our dimensions
*/
NS_IMETHODIMP
nsTitledButtonFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize)
nsTitledButtonFrame::Layout(nsBoxLayoutState& aState)
{
GetImageSize(aPresContext);
mNeedsLayout = PR_TRUE;
return nsLeafBoxFrame::Layout(aState);
}
aSize.minSize.width = mImageRect.width;
aSize.minSize.height = mImageRect.height;
aSize.prefSize.width = mImageRect.width;
aSize.prefSize.height = mImageRect.height;
/**
* Ok return our dimensions
*/
NS_IMETHODIMP
nsTitledButtonFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
if (mNeedsRecalc) {
CacheSizes(aBoxLayoutState);
}
aSize = mPrefSize;
return NS_OK;
}
/**
* Ok return our dimensions
*/
NS_IMETHODIMP
nsTitledButtonFrame::GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
if (mNeedsRecalc) {
CacheSizes(aBoxLayoutState);
}
aSize = mMinSize;
return NS_OK;
}
NS_IMETHODIMP
nsTitledButtonFrame::GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aCoord)
{
if (mNeedsRecalc) {
CacheSizes(aBoxLayoutState);
}
aCoord = mAscent;
return NS_OK;
}
/**
* Ok return our dimensions
*/
void
nsTitledButtonFrame::CacheSizes(nsBoxLayoutState& aBoxLayoutState)
{
nsIPresContext* presContext = aBoxLayoutState.GetPresContext();
const nsHTMLReflowState* state = aBoxLayoutState.GetReflowState();
if (!state)
return;
nsIRenderingContext* rendContext = state->rendContext;
GetImageSize(presContext);
mMinSize.width = mImageRect.width;
mMinSize.height = mImageRect.height;
mPrefSize.width = mImageRect.width;
mPrefSize.height = mImageRect.height;
// depending on the type of alignment add in the space for the text
nsSize size;
nscoord ascent = 0;
GetTextSize(aPresContext, *aReflowState.rendContext,
GetTextSize(presContext, *rendContext,
mTitle, size, ascent);
aSize.ascent = ascent;
mAscent = ascent;
switch (mAlign) {
case NS_SIDE_TOP:
@@ -1411,59 +1471,81 @@ nsTitledButtonFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflow
// if we have an image add the image to our min size
if (mHasImage)
aSize.minSize.width = aSize.prefSize.width;
mMinSize.width = mPrefSize.width;
// if we are not cropped then our min size also includes the text.
if (mCropType == CropNone)
aSize.minSize.width = PR_MAX(size.width, aSize.minSize.width);
mMinSize.width = PR_MAX(size.width, mMinSize.width);
if (size.width > aSize.prefSize.width)
aSize.prefSize.width = size.width;
if (size.width > mPrefSize.width)
mPrefSize.width = size.width;
if (mTitle.Length() > 0) {
aSize.prefSize.height += size.height;
mPrefSize.height += size.height;
if (mHasImage)
aSize.prefSize.height += mSpacing;
mPrefSize.height += mSpacing;
}
aSize.minSize.height = aSize.prefSize.height;
mMinSize.height = mPrefSize.height;
break;
case NS_SIDE_LEFT:
case NS_SIDE_RIGHT:
if (size.height > aSize.prefSize.height)
aSize.prefSize.height = size.height;
if (size.height > mPrefSize.height)
mPrefSize.height = size.height;
if (mHasImage)
aSize.minSize.width = aSize.prefSize.width;
mMinSize.width = mPrefSize.width;
// if we are not cropped then our min size also includes the text.
if (mCropType == CropNone)
aSize.minSize.width += size.width;
mMinSize.width += size.width;
if (mTitle.Length() > 0) {
aSize.prefSize.width += size.width;
mPrefSize.width += size.width;
if (mHasImage) {
aSize.prefSize.width += mSpacing;
aSize.minSize.width += mSpacing;
mPrefSize.width += mSpacing;
mMinSize.width += mSpacing;
}
}
break;
}
nscoord oldHeight = mPrefSize.height;
nsMargin focusBorder = mRenderer->GetAddedButtonBorderAndPadding();
aSize.prefSize.width += focusBorder.left + focusBorder.right;
aSize.prefSize.height += focusBorder.top + focusBorder.bottom;
mPrefSize.width += focusBorder.left + focusBorder.right;
mPrefSize.height += focusBorder.top + focusBorder.bottom;
aSize.minSize.width += focusBorder.left + focusBorder.right;
aSize.minSize.height += focusBorder.top + focusBorder.bottom;
mMinSize.width += focusBorder.left + focusBorder.right;
mMinSize.height += focusBorder.top + focusBorder.bottom;
ascent += focusBorder.top;
return NS_OK;
AddBorderAndPadding(mPrefSize);
AddInset(mPrefSize);
nsIBox::AddCSSPrefSize(aBoxLayoutState, this, mPrefSize);
AddBorderAndPadding(mMinSize);
AddInset(mMinSize);
nsIBox::AddCSSMinSize(aBoxLayoutState, this, mMinSize);
if (mPrefSize.width < mMinSize.width)
mPrefSize.width = mMinSize.width;
if (mPrefSize.height < mMinSize.height)
mPrefSize.height = mMinSize.height;
nsMargin m(0,0,0,0);
GetBorderAndPadding(m);
mAscent += m.top;
GetInset(m);
mAscent += m.top;
mAscent += focusBorder.top;
mNeedsRecalc = PR_FALSE;
}
NS_IMETHODIMP

View File

@@ -23,23 +23,28 @@
#define nsTitledButtonFrame_h___
#include "nsHTMLImageLoader.h"
#include "nsXULLeafFrame.h"
#include "nsLeafBoxFrame.h"
class nsIPopUpMenu;
class nsTitledButtonRenderer;
class nsTitledButtonFrame : public nsXULLeafFrame
class nsTitledButtonFrame : public nsLeafBoxFrame
{
public:
// nsIBox
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent);
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD NeedsRecalc();
// our methods
enum CroppingStyle { CropNone, CropLeft, CropRight, CropCenter };
friend nsresult NS_NewTitledButtonFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
// nsIBox frame interface
NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize);
NS_IMETHOD SetDebug(nsIPresContext* aPresContext, PRBool aDebug) { return NS_OK; }
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,
@@ -67,11 +72,6 @@ public:
virtual void UpdateAttributes(nsIPresContext* aPresContext, nsIAtom* aAttribute, PRBool& aResize, PRBool& aRedraw, PRBool& aUpdateAccessUnderline);
virtual void UpdateImage(nsIPresContext* aPresContext, PRBool& aResize);
// nsIHTMLReflow overrides
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@@ -86,6 +86,8 @@ public:
~nsTitledButtonFrame();
protected:
void CacheSizes(nsBoxLayoutState& aBoxLayoutState);
enum CheckState { eUnset, eOff, eOn, eMixed } ;
CheckState GetCurrentCheckState();
@@ -124,7 +126,7 @@ protected:
PRUint32& aMaxFit,
nsIRenderingContext& aContext);
nsTitledButtonFrame();
nsTitledButtonFrame(nsIPresShell* aShell);
virtual void CalculateTitleForWidth(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, nscoord aWidth);
@@ -170,6 +172,12 @@ private:
PRInt32 mAccesskeyIndex;
nscoord mBeforeWidth, mAccessWidth, mAccessUnderlineSize, mAccessOffset;
nsSize mPrefSize;
nsSize mMinSize;
nscoord mAscent;
PRBool mNeedsRecalc;
// nsIPopUpMenu * mPopUpMenu;
// PRBool mMenuIsPoppedUp;

View File

@@ -284,39 +284,6 @@ nsToolbarFrame :: Paint ( nsIPresContext* aPresContext,
} // Paint
#if 0
//
// GetFrameForPoint
//
// Override to process events in our own frame
//
NS_IMETHODIMP
nsToolbarFrame :: GetFrameForPoint ( nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame)
{
nsresult retVal = nsHTMLContainerFrame::GetFrameForPoint(aPresContext, aPoint, aWhichLayer, aFrame);
if (! mRect.Contains(aPoint)) {
return retVal;
}
// returning NS_OK means that we tell the frame finding code that we have something
// and to stop looking elsewhere for a frame.
if ( aFrame && *aFrame == this )
retVal = NS_OK;
else if ( retVal != NS_OK ) {
*aFrame = this;
retVal = NS_OK;
}
return retVal;
} // GetFrameForPoint
#endif
//
// HandleEvent
//

View File

@@ -73,13 +73,6 @@ public:
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
// nsFrame overrides
#if 0
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint, // Overridden to capture events
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
#endif
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,

View File

@@ -41,6 +41,7 @@
#include "nsIPresContext.h"
#include "nsIWidget.h"
#include "nsINameSpaceManager.h"
#include "nsBoxLayoutState.h"
#include "nsIServiceManager.h"
#include "nsWidgetsCID.h"
@@ -103,7 +104,7 @@ nsToolboxFrame :: nsToolboxFrame (nsIPresShell* aShell):nsBoxFrame(aShell)
mGrippyHilighted(kNoGrippyHilighted),
kCollapsedAtom(dont_AddRef( NS_NewAtom("collapsed"))),
kHiddenAtom(dont_AddRef( NS_NewAtom("hidden"))),
mDragListenerDelegate(nsnull)
mDragListenerDelegate(nsnull), mNeedsCalc(PR_TRUE)
{
}
@@ -203,6 +204,8 @@ nsToolboxFrame::Init(nsIPresContext* aPresContext,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
mPresContext = aPresContext;
nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
UpdateStyles(aPresContext);
@@ -313,39 +316,67 @@ nsToolboxFrame :: DrawGrippy ( nsIPresContext* aPresContext, nsIRenderingContex
} // DrawGrippy
/*
NS_IMETHODIMP
nsToolboxFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize)
{
CalculateGrippies(aPresContext);
return nsBoxFrame::GetBoxInfo(aPresContext, aReflowState, aSize);
}
*/
NS_IMETHODIMP
nsToolboxFrame :: Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
nsToolboxFrame::NeedsRecalc()
{
nsresult errCode = nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
errCode = ReflowGrippies(aPresContext, aDesiredSize, aReflowState, aStatus);
return errCode;
nsresult rv = nsBoxFrame::NeedsRecalc();
mNeedsCalc = PR_TRUE;
return rv;
}
} // Reflow
NS_IMETHODIMP
nsToolboxFrame::GetInset(nsMargin& aMargin)
{
if (mNeedsCalc)
{
CalculateGrippies(mPresContext);
mNeedsCalc = PR_FALSE;
}
nsBoxFrame::GetInset(aMargin);
aMargin += mInset;
return NS_OK;
}
NS_IMETHODIMP
nsToolboxFrame::Layout(nsBoxLayoutState& aState)
{
// lay us out
nsresult rv = nsBoxFrame::Layout(aState);
LayoutGrippies(aState);
return rv;
}
// After we have been flowed this should be flowed to place the grippies at there
// physical locations.
nsresult
nsToolboxFrame::ReflowGrippies(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
nsToolboxFrame::LayoutGrippies(nsBoxLayoutState& aState)
{
// get the rect we can place the grippies in. This is inside our borders and debug rect.
nsRect innerRect(0,0,0,0);
GetInnerRect(innerRect);
nsRect ourRect(0,0,0,0);
GetRect(ourRect);
ourRect.x = 0;
ourRect.y = 0;
nsRect innerRect(ourRect);
nsMargin border(0,0,0,0);
GetBorderAndPadding(border);
innerRect.Deflate(border);
nsIPresContext* presContext = aState.GetPresContext();
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
presContext->GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
nscoord grippyWidth = kGrippyWidthInPixels * onePixel; // remember to leave room for the grippy on the right
nscoord collapsedGrippyHeight = kCollapsedGrippyHeightInPixels * onePixel;
@@ -356,14 +387,19 @@ nsToolboxFrame::ReflowGrippies(nsIPresContext* aPresContext,
// iterate over all visible toolbar frames, moving the associated grippy
// next to the toolbar
mNumToolbars = 0;
nsIFrame* childFrame = mFrames.FirstChild();
while ( childFrame ) {
nsIBox* childBox;
GetChildBox(&childBox);
while ( childBox ) {
// get the childs rect and figure out the grippy size
nsIFrame* childFrame = nsnull;
childBox->GetFrame(&childFrame);
nsCOMPtr<nsIContent> childContent;
childFrame->GetContent(getter_AddRefs(childContent));
nsRect grippyRect;
childFrame->GetRect(grippyRect);
childBox->GetBounds(grippyRect);
if ( isHorz ) {
grippyRect.y = innerRect.y;
@@ -380,7 +416,7 @@ nsToolboxFrame::ReflowGrippies(nsIPresContext* aPresContext,
// Set the location of the grippy to the left...
grippyInfo->SetBounds(grippyRect);
errCode = childFrame->GetNextSibling(&childFrame);
errCode = childBox->GetNextBox(&childBox);
NS_ASSERTION(errCode == NS_OK, "failed to get next child");
mNumToolbars++;
}
@@ -393,9 +429,9 @@ nsToolboxFrame::ReflowGrippies(nsIPresContext* aPresContext,
// horzontal toolbox our height is our width. Thats why we just use
// height here on both x and y coords.
if ( isHorz )
currGrippy->mBoundingRect.x = aDesiredSize.width - collapsedGrippyHeight;
currGrippy->mBoundingRect.x = ourRect.width - collapsedGrippyHeight;
else
currGrippy->mBoundingRect.y = aDesiredSize.height - collapsedGrippyHeight;
currGrippy->mBoundingRect.y = ourRect.height - collapsedGrippyHeight;
}
}
@@ -407,6 +443,7 @@ nsToolboxFrame::ReflowGrippies(nsIPresContext* aPresContext,
void
nsToolboxFrame::CalculateGrippies(nsIPresContext* aPresContext)
{
// compute amount (in twips) each toolbar will be offset from the right because of
// the grippy
float p2t;
@@ -562,52 +599,6 @@ nsToolboxFrame :: ClearGrippyList ( nsVoidArray & inList )
} // ClearGrippyList
//
// GetInset
//
// Our Reflow() method computes a margin for the grippies and for collased grippies (if
// any). Return this pre-computed margin when asked by the box.
//
void
nsToolboxFrame::GetInset(nsMargin& margin)
{
nsBoxFrame::GetInset(margin);
margin += mInset;
}
#if 0
//
// GetFrameForPoint
//
// Override to process events in our own frame
//
NS_IMETHODIMP
nsToolboxFrame :: GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame)
{
nsresult retVal = nsHTMLContainerFrame::GetFrameForPoint(aPresContext, aPoint, aWhichLayer, aFrame);
if (! mRect.Contains(aPoint)) {
return retVal;
}
// returning NS_OK means that we tell the frame finding code that we have something
// and to stop looking elsewhere for a frame.
if ( aFrame && *aFrame == this )
retVal = NS_OK;
else if ( retVal != NS_OK ) {
*aFrame = this;
retVal = NS_OK;
}
return retVal;
} // GetFrameForPoint
#endif
//
// HandleEvent
//

View File

@@ -58,14 +58,12 @@ class nsToolboxFrame : public nsBoxFrame
public:
friend nsresult NS_NewToolboxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
// nsIHTMLReflow overrides
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize);
// nsIBox
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD GetInset(nsMargin& aInset);
NS_IMETHOD NeedsRecalc();
// nsIFrame
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
@@ -85,14 +83,6 @@ public:
NS_IMETHOD SetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext* aStyleContext);
#if 0
// Overridden to capture events
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
#endif
/*BEGIN implementations of dragevent handler interface*/
virtual nsresult HandleEvent(nsIDOMEvent* aEvent);
virtual nsresult DragEnter(nsIDOMEvent* aDragEvent);
@@ -135,10 +125,7 @@ protected:
virtual void UpdateStyles(nsIPresContext* aPresContext);
virtual void CalculateGrippies(nsIPresContext* aPresContext);
virtual nsresult ReflowGrippies(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
virtual nsresult LayoutGrippies(nsBoxLayoutState& aBoxLayoutState);
void RefreshStyleContext(nsIPresContext* aPresContext,
@@ -167,7 +154,6 @@ protected:
nsCOMPtr<nsIStyleContext> mGrippyRolloverStyle;
nsMargin mInset;
virtual void GetInset(nsMargin& margin);
unsigned long mSumOfToolbarHeights;
nsVoidArray mGrippies; // list of all active grippies
@@ -186,6 +172,7 @@ protected:
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIDOMEventListener interface
virtual nsresult HandleEvent(nsIDOMEvent* aEvent)
{
@@ -235,6 +222,8 @@ protected:
nsToolboxFrame ( const nsToolboxFrame& aFrame ) ; // DO NOT IMPLEMENT
nsToolboxFrame& operator= ( const nsToolboxFrame& aFrame ) ; // DO NOT IMPLEMENT
PRBool mNeedsCalc;
nsIPresContext* mPresContext;
}; // class nsToolboxFrame
#endif

View File

@@ -1,211 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 "nsXULLeafFrame.h"
#include "nsCOMPtr.h"
#include "nsIDeviceContext.h"
#include "nsIFontMetrics.h"
#include "nsHTMLAtoms.h"
#include "nsXULAtoms.h"
#include "nsIPresContext.h"
#include "nsIRenderingContext.h"
#include "nsIStyleContext.h"
#include "nsIContent.h"
#include "nsINameSpaceManager.h"
//
// NS_NewToolbarFrame
//
// Creates a new Toolbar frame and returns it in |aNewFrame|
//
nsresult
NS_NewXULLeafFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsXULLeafFrame* it = new (aPresShell) nsXULLeafFrame;
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
// it->SetFlags(aFlags);
*aNewFrame = it;
return NS_OK;
} // NS_NewTextFrame
NS_IMETHODIMP
nsXULLeafFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
if (eReflowReason_Incremental == aReflowState.reason) {
nsIFrame* targetFrame;
// See if it's targeted at us
aReflowState.reflowCommand->GetTarget(targetFrame);
if (this == targetFrame) {
Invalidate(aPresContext, nsRect(0,0,mRect.width,mRect.height), PR_FALSE);
}
} else if (eReflowReason_Dirty == aReflowState.reason) {
Invalidate(aPresContext, nsRect(0,0,mRect.width,mRect.height), PR_FALSE);
}
nsresult result = nsLeafFrame::Reflow(aPresContext, aMetrics, aReflowState, aStatus);
if (aReflowState.mComputedWidth != NS_INTRINSICSIZE)
NS_ASSERTION(aMetrics.width == aReflowState.mComputedWidth + aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right,
"Text width is wrong!!!");
if (aReflowState.mComputedHeight != NS_INTRINSICSIZE)
NS_ASSERTION(aMetrics.height == aReflowState.mComputedHeight + aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom,
"Text height is wrong!!!");
return result;
}
void
nsXULLeafFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aDesiredSize)
{
// get our info object.
nsBoxInfo info;
info.Clear();
GetBoxInfo(aPresContext, aReflowState, info);
// size is our preferred unless calculated.
aDesiredSize.width = info.prefSize.width;
aDesiredSize.height = info.prefSize.height;
// if either the width or the height was not computed use our intrinsic size
if (aReflowState.mComputedWidth != NS_INTRINSICSIZE)
aDesiredSize.width = aReflowState.mComputedWidth;
if (aReflowState.mComputedHeight != NS_INTRINSICSIZE) {
aDesiredSize.height = aReflowState.mComputedHeight;
nscoord descent = info.prefSize.height - info.ascent;
aDesiredSize.ascent = aDesiredSize.height - descent;
if (aDesiredSize.ascent < 0)
aDesiredSize.ascent = 0;
} else {
aDesiredSize.ascent = info.ascent;
}
}
NS_IMETHODIMP
nsXULLeafFrame::InvalidateCache(nsIFrame* aChild)
{
// we don't cache any information
return NS_OK;
}
/**
* Ok return our dimensions
*/
NS_IMETHODIMP
nsXULLeafFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize)
{
aSize.prefSize.width = 0;
aSize.prefSize.height = 0;
aSize.minSize.width = 0;
aSize.minSize.height = 0;
aSize.maxSize.width = NS_INTRINSICSIZE;
aSize.maxSize.height = NS_INTRINSICSIZE;
aSize.ascent = 0;
return NS_OK;
}
/**
* We can be a nsIBox
*/
NS_IMETHODIMP
nsXULLeafFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
if (aIID.Equals(NS_GET_IID(nsIBox))) {
*aInstancePtr = (void*)(nsIBox*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return nsLeafFrame::QueryInterface(aIID, aInstancePtr);
}
/*
* We are a frame and we do not maintain a ref count
*/
NS_IMETHODIMP_(nsrefcnt)
nsXULLeafFrame::AddRef(void)
{
return NS_OK;
}
NS_IMETHODIMP_(nsrefcnt)
nsXULLeafFrame::Release(void)
{
return NS_OK;
}
NS_IMETHODIMP
nsXULLeafFrame::GetFrameName(nsString& aResult) const
{
aResult = "Leaf";
return NS_OK;
}
NS_IMETHODIMP
nsXULLeafFrame::ContentChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
nsISupports* aSubContent)
{
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
mState |= NS_FRAME_IS_DIRTY;
return mParent->ReflowDirtyChild(shell, this);
}

View File

@@ -97,6 +97,7 @@ XUL_ATOM(crop, "crop")
XUL_ATOM(mode, "mode")
XUL_ATOM(box, "box")
XUL_ATOM(mousethrough, "mousethrough")
XUL_ATOM(flex, "flex")
XUL_ATOM(spring, "spring")
XUL_ATOM(orient, "orient")
@@ -130,6 +131,13 @@ XUL_ATOM(resizeafter, "resizeafter")
XUL_ATOM(state, "state")
XUL_ATOM(debug, "debug")
// grid
XUL_ATOM(grid, "grid")
XUL_ATOM(rows, "rows")
XUL_ATOM(columns, "columns")
XUL_ATOM(row, "row")
XUL_ATOM(column, "column")
// toolbar & toolbar d&d atoms
XUL_ATOM(ddDropLocation, "dd-droplocation")
XUL_ATOM(ddDropLocationCoord, "dd-droplocationcoord")

View File

@@ -54,9 +54,7 @@
<!-- instructions -->
<deck id="prattle">
<box orient="vertical" id="selection">
<html>&introgeneral.label;</html>
</box>
<html id="intro" flex="1">&introgeneral.label;</html>
<box orient="vertical" id="manager">
<html class="label" style="width: 200px;">&pmTextA.label;</html>
<spring flex="1"/>

View File

@@ -48,8 +48,8 @@ box[type="largeheader"] > toolbar > .circle {
}
/* profile selection dialog */
deck#prattle {
max-width: 17em;
html#intro {
width: 17em;
}
box#managebuttons > button {

View File

@@ -24,8 +24,6 @@
splitter#sidebar-splitter {
margin-right: 2px;
margin-top: 2px;
min-width: 8px;
max-width: 8px;
padding: 0px;
border: none;
background-color: #003366;
@@ -68,7 +66,6 @@ box#sidebar-box {
margin-top: 2px;
width: 162px;
min-height: 1px;
min-width: 1px;
max-width: 400px;
border: none;
border-bottom: 8px solid #003366;
@@ -151,3 +148,7 @@ box#sidebar-panels-bottom > box.texttab + box.texttab {
*[hidden="true"] {
display: none;
}
box#title-box {
min-width: 10px;
}

View File

@@ -535,28 +535,51 @@ grippy:hover:active{
background-color: #99CCFF;
}
box[align="vertical"]>splitter grippy {
box[orient="vertical"]>splitter grippy {
/* a horizontal splitter */
min-width: 60px;
max-height: 4px;
width: 60px;
height:8px;
}
box[align="horizontal"]>splitter grippy {
box>splitter grippy {
/* a vertical splitter */
max-width: 4px;
min-height: 60px;
width: 8px;
height: 60px;
}
window[orient="vertical"]>splitter grippy {
/* a horizontal splitter */
width: 8px;
height: 10px;
}
window>splitter grippy {
/* a vertical splitter */
width: 8px;
height: 60px;
}
box[orient="vertical"]>splitter {
/* a vertical splitter */
cursor: n-resize;
}
window[orient="vertical"]>splitter {
/* a vertical splitter */
cursor: n-resize;
}
/* for backwards compatibility */
box[align="vertical"]>splitter grippy {
/* a horizontal splitter */
width: 60px;
height: 8px;
}
window[align="vertical"]>splitter grippy {
/* a horizontal splitter */
min-width: 60px;
max-height: 4px;
}
window[align="horizontal"]>splitter grippy {
/* a vertical splitter */
max-width: 4px;
min-height: 60px;
width: 60px;
height: 8px;
}
box[align="vertical"]>splitter {
@@ -596,7 +619,7 @@ splitter.gray-horizontal-splitter grippy:active {
splitter.gray-horizontal-splitter #begincap {
min-width: 8px;
max-width: 8px;
width: 8px;
background-image: url("chrome://global/skin/gray-bottomleft.gif");
background-repeat: no-repeat;
background-position: 0% 100%;
@@ -604,10 +627,34 @@ splitter.gray-horizontal-splitter #begincap {
splitter.gray-horizontal-splitter #endcap {
min-width: 8px;
max-width: 8px;
width: 8px;
}
/****** Progress Meter ********/
progressmeter[align="horizontal"] {
height: 1em;
}
box.progress-bar {
background-color : #9999cc;
}
box.progress-remainder {
background-color: #999999;
}
progressmeter[mode="undetermined"] > .internal-box
{
background-image: url(chrome://global/skin/progressmeter-busy.gif);
}
progressmeter[mode="undetermined"] > .internal-box > stack > progressbar
{
display: none;
}
/********* Box ********/
box
@@ -660,6 +707,7 @@ menubar {
menu {
color: black;
vertical-align: middle;
}
menu[disabled="true"] {
@@ -668,6 +716,7 @@ menu[disabled="true"] {
menuitem {
color: black;
vertical-align: middle;
}
menuitem[disabled="true"] {
@@ -808,7 +857,6 @@ popup > menuitem[menuactive="true"][disabled="true"] {
.menu-right {
padding: 0px;
border: 0px;
width: 10px;
margin-top: 0px;
margin-bottom: 0px;
margin-left: 6px;
@@ -819,7 +867,6 @@ popup > menuitem[menuactive="true"][disabled="true"] {
color: inherit;
padding: 0px;
border: 0px;
width: 13px;
margin-top: 0px;
margin-bottom: 0px;
margin-right: 2px;
@@ -888,6 +935,80 @@ menu[menuactive="true"] > .menu-right {
list-style-image: url("chrome://global/skin/menu-arrow-hover.gif");
}
menulist, menubutton {
padding: 1px 0px 1px 0px;
}
menulist > .menu-text,
menubutton > .menu-text {
padding-left: 4px;
padding-right: 4px;
border: 1px inset #CCCCCC;
}
menubutton > .menu-button {
border: 1px outset #CCCCCC;
padding: 2px;
}
menubutton > .menu-button:active {
border: 1px inset #CCCCCC;
padding: 3px 1px 1px 3px;
}
menubutton > .menu-dropmarker,
menulist > .menu-dropmarker {
border: 1px outset #CCCCCC;
list-style-image: url("chrome://global/skin/scroll-down.gif");
padding: 0px 2px 0px 2px;
}
menubutton[open="true"] > .menu-dropmarker,
menulist[open="true"] > .menu-dropmarker {
border: 1px inset #CCCCCC;
padding: 1px 1px -1px 3px;
}
menubutton menupopup, menulist menupopup {
border: 1px outset #CCCCCC;
}
menulist[editable="true"] {
padding: 0px;
}
menulist[editable="true"] > .menu-text {
border-left: none;
border-top: 1px inset #CCCCCC;
border-right: 1px inset #CCCCCC;
border-bottom: 1px inset #CCCCCC;
margin: 0px 2px 0px 0px;
}
menulist[editable="true"] > .menu-dropmarker {
border: 1px outset #CCCCCC;
}
menulist[editable="true"][open="true"] > .menu-dropmarker {
border: 1px inset #CCCCCC;
}
menulist[editable="true"] > .menu-icon {
list-style-image: url("chrome://bookmarks/skin/bookmark-item.gif");
background-color: white;
padding: 1px;
border-left: 1px inset #CCCCCC;
border-top: 1px inset #CCCCCC;
border-right: none;
border-bottom: 1px inset #CCCCCC;
}
menulist menupopup > menuseparator {
border-bottom: 2px groove #CCCCCC;
}
/******** Rules for menus on the standard toolbars ***************/
menu.standard {

View File

@@ -44,8 +44,6 @@ template {
window {
overflow: hidden;
height: 100%;
width: 100%;
}
/**********************************

View File

@@ -48,9 +48,9 @@
</binding>
<binding name="menus">
<content excludes="template,observes,menupopup">
<content autostretch="never" excludes="template,observes,menupopup">
<xul:image class="menu-left"/>
<xul:titledbutton class="menu-text" flex="1" align="left" inherits="value,accesskey,crop" crop="right"/>
<xul:text class="menu-text" flex="1" align="left" inherits="value,accesskey,crop" crop="right"/>
<xul:text class="menu-accel" inherits="acceltext:value"/>
<xul:image class="menu-right"/>
</content>