-r jevering
This commit is contained in:
evaughan%netscape.com 2000-02-16 23:00:52 +00:00
Родитель e3d02556ec
Коммит c7ba739a87
14 изменённых файлов: 1165 добавлений и 117 удалений

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

@ -150,6 +150,9 @@ NS_NewProgressMeterFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewTitledButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewXULTextFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewTitledBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
@ -4376,8 +4379,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
// TITLED BUTTON CONSTRUCTION
else if (aTag == nsXULAtoms::titledbutton ||
aTag == nsXULAtoms::image ||
aTag == nsXULAtoms::text) {
aTag == nsXULAtoms::image) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
@ -4385,6 +4387,15 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
}
// End of TITLED BUTTON CONSTRUCTION logic
// TEXT CONSTRUCTION
else if (aTag == nsXULAtoms::text) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewXULTextFrame(aPresShell, &newFrame);
}
// End of TEXT CONSTRUCTION logic
// DECK CONSTRUCTION
else if (aTag == nsXULAtoms::deck || aTag == nsXULAtoms::tabpanel) {
processChildren = PR_TRUE;

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

@ -150,6 +150,9 @@ NS_NewProgressMeterFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewTitledButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewXULTextFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
nsresult
NS_NewTitledBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
@ -4376,8 +4379,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
// TITLED BUTTON CONSTRUCTION
else if (aTag == nsXULAtoms::titledbutton ||
aTag == nsXULAtoms::image ||
aTag == nsXULAtoms::text) {
aTag == nsXULAtoms::image) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
@ -4385,6 +4387,15 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
}
// End of TITLED BUTTON CONSTRUCTION logic
// TEXT CONSTRUCTION
else if (aTag == nsXULAtoms::text) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewXULTextFrame(aPresShell, &newFrame);
}
// End of TEXT CONSTRUCTION logic
// DECK CONSTRUCTION
else if (aTag == nsXULAtoms::deck || aTag == nsXULAtoms::tabpanel) {
processChildren = PR_TRUE;

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

@ -30,6 +30,7 @@ MODULE = layout
LIBRARY_NAME = raptorxulbase_s
CPPSRCS = \
nsXULTextFrame.cpp \
nsTitledBoxFrame.cpp \
nsTitleFrame.cpp \
nsFrameNavigator.cpp \

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

@ -28,6 +28,7 @@ REQUIRES=xpcom raptor pref
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
CPPSRCS= \
nsXULTextFrame.cpp \
nsTitleFrame.cpp \
nsTitledBoxFrame.cpp \
nsFrameNavigator.cpp \
@ -69,6 +70,7 @@ CPPSRCS= \
CPP_OBJS= \
.\$(OBJDIR)\nsTitleFrame.obj \
.\$(OBJDIR)\nsXULTextFrame.obj \
.\$(OBJDIR)\nsTitledBoxFrame.obj \
.\$(OBJDIR)\nsFrameNavigator.obj \
.\$(OBJDIR)\nsRepeatService.obj \

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

@ -78,7 +78,7 @@
#define DEBUG_BORDER_SIZE 2
#define COIL_SIZE 8
#define TEST_SANITY
//#define TEST_SANITY
#define NS_STATE_IS_HORIZONTAL 0x00400000
@ -206,6 +206,8 @@ public:
PRBool& needsRedraw,
const nsString& aReason);
void PlaceChild(nsIPresContext* aPresContext, nsIFrame* aFrame, nscoord aX, nscoord aY);
void UpdatePseudoElements(nsIPresContext* aPresContext);
void TranslateEventCoords(nsIPresContext* aPresContext,
@ -218,7 +220,9 @@ public:
nsBoxFrame::Halignment GetHAlign();
nsBoxFrame::Valignment GetVAlign();
void InitializeReflowState(nsIPresContext* aPresContext, const nsCalculatedBoxInfo& aInfo, nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aParentReflowState, nsIFrame* aFrame, const nsSize& aAvailSize, nsReflowReason reason);
void CreateResizedArray(PRBool*& aResized, PRInt32 aCount);
#ifdef DEBUG_REFLOW
void MakeReason(nsIFrame* aFrame, const nsString& aText, nsString& aReason);
@ -273,6 +277,7 @@ nsBoxFrame::nsBoxFrame()
// if not otherwise specified boxes by default are horizontal.
mState |= NS_STATE_IS_HORIZONTAL;
mState |= NS_STATE_AUTO_STRETCH;
mInner->mValign = nsBoxFrame::vAlign_Top;
mInner->mHalign = nsBoxFrame::hAlign_Left;
mInner->mInnerSize = 0;
@ -465,9 +470,9 @@ nsBoxFrame::GetInitialVAlignment(nsBoxFrame::Valignment& aValign)
if (textStyle->mVerticalAlign.GetUnit() == eStyleUnit_Enumerated) {
PRInt32 value = textStyle->mVerticalAlign.GetIntValue();
PRInt32 type = textStyle->mVerticalAlign.GetIntValue();
switch (value)
switch (type)
{
case NS_STYLE_VERTICAL_ALIGN_BASELINE:
aValign = nsBoxFrame::vAlign_BaseLine;
@ -707,6 +712,7 @@ nsBoxFrame::GetChildBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowStat
nsIBox* ibox = nsnull;
if (NS_SUCCEEDED(aFrame->QueryInterface(NS_GET_IID(nsIBox), (void**)&ibox)) && ibox) {
ibox->GetBoxInfo(aPresContext, aReflowState, aSize);
aSize.mFlags |= NS_FRAME_IS_BOX;
// add in the border, padding, width, min, max
GetRedefinedMinPrefMax(aPresContext, aFrame, aSize);
return NS_OK;
@ -1068,17 +1074,21 @@ printf("\n");
if (aReflowState.mComputedHeight != NS_INTRINSICSIZE && layoutRect.height < aReflowState.mComputedHeight)
layoutRect.height = aReflowState.mComputedHeight;
nsSize actualSize(layoutRect.width, layoutRect.height);
nsRect actualRect(layoutRect);
actualRect.Deflate(inset);
// flow each child at the new sizes we have calculated.
nsSize actualSize(actualRect.width, actualRect.height);
// flow each child at the new sizes we have calculated. With the actual size we are giving them to layout our and the
// size of the rect they were computed to layout in.
mInner->FlowChildren(aPresContext, aDesiredSize, aReflowState, aStatus, incrementalChild, rect, actualSize, maxAscent);
//-----------------------------------------------------------------------------------
//------------------------- Add our border and insets in ----------------------------
//-----------------------------------------------------------------------------------
// flow children may have changed the rect so lets use it.
rect.Inflate(inset);
if (aReflowState.mComputedWidth != NS_INTRINSICSIZE && rect.width < aReflowState.mComputedWidth)
@ -1229,10 +1239,7 @@ nsBoxFrameInner::FlowChildren(nsIPresContext* aPresContext,
nsAutoString reason;
nsAutoString nextReason;
PRInt32 infoCount = mInfoList->GetCount();
PRBool* resized = new PRBool[infoCount];
for (int i=0; i < infoCount; i++)
resized[i] = PR_FALSE;
PRBool* resized = nsnull;
// ----------------------
// Flow all children
@ -1314,7 +1321,7 @@ nsBoxFrameInner::FlowChildren(nsIPresContext* aPresContext,
FlowChildAt(childFrame, aPresContext, aDesiredSize, aReflowState, aStatus, *info, x, y, PR_TRUE, aIncrementalChild, redraw, reason);
// if the child got bigger then adjust our rect and all the children.
mOuter->ChildResized(childFrame, aDesiredSize, aRect, aMaxAscent, *info, resized, changedIndex, finished, count, nextReason);
mOuter->ChildResized(childFrame, aDesiredSize, aRect, aMaxAscent, *info, resized, infoCount, changedIndex, finished, count, nextReason);
}
// ok if we are collapsed make sure the view and all its children
@ -1355,7 +1362,7 @@ nsBoxFrameInner::FlowChildren(nsIPresContext* aPresContext,
FlowChildAt(childFrame, aPresContext, aDesiredSize, aReflowState, aStatus, *info, x, y, PR_TRUE, aIncrementalChild, redraw, reason);
// if the child got bigger then adjust our rect and all the children.
mOuter->ChildResized(childFrame, aDesiredSize, aRect, aMaxAscent, *info, resized, changedIndex, finished, count, nextReason);
mOuter->ChildResized(childFrame, aDesiredSize, aRect, aMaxAscent, *info, resized, infoCount, changedIndex, finished, count, nextReason);
/*
#ifdef DEBUG_REFLOW
@ -1433,7 +1440,8 @@ nsBoxFrameInner::FlowChildren(nsIPresContext* aPresContext,
mOuter->Invalidate(aPresContext, nsRect(0,0,mOuter->mRect.width, mOuter->mRect.height), PR_FALSE);
}
delete[] resized;
if (resized)
delete[] resized;
return NS_OK;
}
@ -1473,7 +1481,16 @@ nsBoxFrameInner::MakeReason(nsIFrame* aFrame, const nsString& aText, nsString& a
#endif
void
nsBoxFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool* aResized, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason)
nsBoxFrameInner::CreateResizedArray(PRBool*& aResized, PRInt32 aCount)
{
aResized = new PRBool[aCount];
for (int i=0; i < aCount; i++)
aResized[i] = PR_FALSE;
}
void
nsBoxFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool*& aResized, PRInt32 aInfoCount, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason)
{
if (mState & NS_STATE_IS_HORIZONTAL) {
// if we are a horizontal box see if the child will fit inside us.
@ -1530,6 +1547,9 @@ nsBoxFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, ns
InvalidateChildren();
if (aResized == nsnull)
mInner->CreateResizedArray(aResized, aInfoCount);
// our index resized
aResized[aIndex] = PR_TRUE;
@ -1582,6 +1602,9 @@ nsBoxFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, ns
// if the width changed then clear out the resized list
// but only do this if we are vertical box. On a horizontal box increasing the height will not change the
// width of its children.
if (aResized == nsnull)
mInner->CreateResizedArray(aResized, aInfoCount);
PRInt32 infoCount = mInner->mInfoList->GetCount();
for (int i=0; i < infoCount; i++)
aResized[i] = PR_FALSE;
@ -1602,6 +1625,9 @@ nsBoxFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, ns
InvalidateChildren();
if (aResized == nsnull)
mInner->CreateResizedArray(aResized, aInfoCount);
// our index resized
aResized[aIndex] = PR_TRUE;
@ -1785,6 +1811,69 @@ nsBoxFrame::PlaceChildren(nsIPresContext* aPresContext, nsRect& boxRect)
return NS_OK;
}
void
nsBoxFrameInner::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
nsBoxFrameInner::InitializeReflowState(nsIPresContext* aPresContext, const nsCalculatedBoxInfo& aInfo, nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aParentReflowState, nsIFrame* aFrame, const nsSize& aAvailSize, nsReflowReason aReason)
{
aFrame->GetStyleData(eStyleStruct_Position,
(const nsStyleStruct*&)aReflowState.mStylePosition);
aFrame->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&)aReflowState.mStyleDisplay);
aFrame->GetStyleData(eStyleStruct_Spacing,
(const nsStyleStruct*&)aReflowState.mStyleSpacing);
aReflowState.mReflowDepth = aParentReflowState.mReflowDepth + 1;
aReflowState.parentReflowState = &aParentReflowState;
aReflowState.frame = aFrame;
aReflowState.reason = aReason;
aReflowState.reflowCommand = aReflowState.reflowCommand;
aReflowState.availableWidth = aAvailSize.width;
aReflowState.availableHeight = aAvailSize.height;
aReflowState.rendContext = aParentReflowState.rendContext;
aReflowState.mSpaceManager = aParentReflowState.mSpaceManager;
aReflowState.mLineLayout = aParentReflowState.mLineLayout;
aReflowState.isTopOfPage = aParentReflowState.isTopOfPage;
// if we are not a box then to the regular html thing.
// otherwise do the efficient thing for boxes.
// if (!(aInfo.mFlags & NS_FRAME_IS_BOX)) {
// aReflowState.Init(aPresContext);
/// } else {
aReflowState.mComputedMargin.SizeTo(0,0,0,0);
aReflowState.mStyleSpacing->GetMargin(aReflowState.mComputedMargin);
aReflowState.mComputedBorderPadding.SizeTo(0,0,0,0);
aReflowState.mStyleSpacing->GetBorderPadding(aReflowState.mComputedBorderPadding);
aReflowState.mComputedPadding.SizeTo(0,0,0,0);
aReflowState.mStyleSpacing->GetPadding(aReflowState.mComputedPadding);
aReflowState.mComputedOffsets.SizeTo(0, 0, 0, 0);
aReflowState.mComputedMinWidth = aReflowState.mComputedMinHeight = 0;
aReflowState.mComputedMaxWidth = aReflowState.mComputedMaxHeight = NS_UNCONSTRAINEDSIZE;
aReflowState.mCompactMarginWidth = 0;
aReflowState.mAlignCharOffset = 0;
aReflowState.mUseAlignCharOffset = 0;
aReflowState.mFrameType = NS_CSS_FRAME_TYPE_BLOCK;
//}
}
/**
* Flow an individual child. Special args:
@ -1951,40 +2040,12 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame,
size.width -= (margin.left + margin.right);
// create a reflow state to tell our child to flow at the given size.
nsHTMLReflowState reflowState(aPresContext, aReflowState, childFrame, nsSize(size.width, NS_INTRINSICSIZE));
reflowState.reason = reason;
if (size.height != NS_INTRINSICSIZE)
size.height -= (border.top + border.bottom);
if (size.width != NS_INTRINSICSIZE)
size.width -= (border.left + border.right);
reflowState.mComputedWidth = size.width;
reflowState.mComputedHeight = size.height;
// nsSize maxElementSize(0, 0);
// desiredSize.maxElementSize = &maxElementSize;
/*
#if DEBUG_REFLOW
ListTag(stdout);
if (reason == eReflowReason_Incremental && aInfo.isIncremental)
printf(": INCREMENTALLY reflowing ");
else
printf(": reflowing ");
nsFrame::ListTag(stdout, childFrame);
char ch[100];
aReason.ToCString(ch,100);
printf("because (%s)\n", ch);
#endif
*/
#ifdef DEBUG_REFLOW
#ifdef DEBUG_REFLOW
char* reflowReasonString;
switch(reflowState.reason)
switch(reason)
{
case eReflowReason_Initial:
reflowReasonString = "initial";
@ -2015,20 +2076,49 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame,
printf(" reason=%s %s\n",reflowReasonString,ch);
#endif
// place the child and reflow
childFrame->WillReflow(aPresContext);
if (!(aInfo.mFlags & NS_FRAME_IS_BOX)) {
nsHTMLReflowState reflowState(aPresContext, aReflowState, childFrame, nsSize(size.width, NS_INTRINSICSIZE));
reflowState.reason = reason;
if (aMoveFrame) {
childFrame->MoveTo(aPresContext, aX + margin.left, aY + margin.top);
if (size.height != NS_INTRINSICSIZE)
size.height -= (border.top + border.bottom);
nsIView* view;
childFrame->GetView(aPresContext, &view);
if (view) {
nsContainerFrame::PositionFrameView(aPresContext, childFrame, view);
if (size.width != NS_INTRINSICSIZE)
size.width -= (border.left + border.right);
reflowState.mComputedWidth = size.width;
reflowState.mComputedHeight = size.height;
// place the child and reflow
childFrame->WillReflow(aPresContext);
if (aMoveFrame) {
PlaceChild(aPresContext, childFrame, aX + margin.left, aY + margin.top);
}
}
childFrame->Reflow(aPresContext, desiredSize, reflowState, aStatus);
childFrame->Reflow(aPresContext, desiredSize, reflowState, aStatus);
} else {
nsHTMLReflowState reflowState(aReflowState);
InitializeReflowState(aPresContext, aInfo, reflowState, aReflowState, childFrame, nsSize(size.width, NS_INTRINSICSIZE), reason);
if (size.height != NS_INTRINSICSIZE)
size.height -= (border.top + border.bottom);
if (size.width != NS_INTRINSICSIZE)
size.width -= (border.left + border.right);
reflowState.mComputedWidth = size.width;
reflowState.mComputedHeight = size.height;
// place the child and reflow
childFrame->WillReflow(aPresContext);
if (aMoveFrame) {
PlaceChild(aPresContext, childFrame, aX + margin.left, aY + margin.top);
}
childFrame->Reflow(aPresContext, desiredSize, reflowState, aStatus);
}
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
@ -2080,44 +2170,13 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame,
nsContainerFrame::FinishReflowChild(childFrame, aPresContext, desiredSize, aX + margin.left, aY + margin.top, NS_FRAME_NO_MOVE_FRAME);
/*
// set the rect and size the view (if it has one).. Don't position the view
// and sync its properties (like opacity) until later when we know its final
// position
childFrame->SizeTo(aPresContext, desiredSize.width, desiredSize.height);
nsIView* view;
childFrame->GetView(aPresContext, &view);
if (view) {
nsIViewManager *vm;
view->GetViewManager(vm);
vm->ResizeView(view, desiredSize.width, desiredSize.height);
NS_RELEASE(vm);
}
childFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
*/
// Stub out desiredSize.maxElementSize so that when go out of
// scope, nothing bad happens!
//desiredSize.maxElementSize = nsnull;
} else {
if (aMoveFrame) {
nsPoint curOrigin;
childFrame->GetOrigin(curOrigin);
// only if the origin changed
//if ((curOrigin.x != aX + margin.left) || (curOrigin.y != aY + margin.top)) {
childFrame->MoveTo(aPresContext, aX + margin.left, aY + margin.top);
nsIView* view;
childFrame->GetView(aPresContext, &view);
if (view)
nsContainerFrame::PositionFrameView(aPresContext, childFrame, view);
else
nsContainerFrame::PositionChildViews(aPresContext, childFrame);
// }
PlaceChild(aPresContext, childFrame, aX + margin.left, aY + margin.top);
}
}
@ -2250,10 +2309,7 @@ nsBoxFrameInner::GetHAlign()
void
nsBoxFrame::LayoutChildrenInRect(nsRect& aGivenSize, nscoord& aMaxAscent)
{
nsBoxFrame::Valignment valign = mInner->GetVAlign();
nsBoxFrame::Halignment halign = mInner->GetHAlign();
{
nsCalculatedBoxInfo* first = mInner->mInfoList->GetFirst();
if (!first)
@ -2375,7 +2431,6 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& aGivenSize, nscoord& aMaxAscent)
nscoord pref = GET_WIDTH(info->prefSize);
nscoord max = GET_WIDTH(info->maxSize);
nscoord min = GET_WIDTH(info->minSize);
nscoord calculated = GET_WIDTH(info->calculatedSize);
if (!(info->mFlags & NS_FRAME_BOX_SIZE_VALID)) {
PRInt32 newSize = pref + (sizeRemaining*info->flex/springConstantsRemaining);
@ -2514,7 +2569,7 @@ nsBoxFrame::InsertFrames(nsIPresContext* aPresContext,
mInner->mInfoList->Insert(aPrevFrame, aFrameList);
// insert the frames in out regular frame list
mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
mFrames.InsertFrames(this, aPrevFrame, aFrameList);
mInner->SanityCheck();
@ -2536,7 +2591,7 @@ nsBoxFrame::AppendFrames(nsIPresContext* aPresContext,
mInner->mInfoList->Append(aFrameList);
// append in regular frames
mFrames.AppendFrames(nsnull, aFrameList);
mFrames.AppendFrames(this, aFrameList);
mInner->SanityCheck();
@ -2599,12 +2654,14 @@ nsBoxFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aR
// it does not include its border.
rv = GetChildBoxInfo(aPresContext, aReflowState, info->frame, *info);
/*
// make sure we can see the debug info
if (info->prefSize.width < debugInset.left)
info->prefSize.width = debugInset.left;
if (info->prefSize.height < debugInset.top)
info->prefSize.height = debugInset.top;
*/
NS_ASSERTION(rv == NS_OK,"failed to child box info");
if (NS_FAILED(rv))
@ -2674,12 +2731,14 @@ nsBoxFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aR
aSize.minSize += in;
aSize.prefSize += in;
/*
// make sure we can see the debug info
if (aSize.maxSize.width < debugInset.left + debugInset.right)
aSize.maxSize.width = debugInset.left + debugInset.right;
if (aSize.maxSize.height < debugInset.top + debugInset.bottom)
aSize.maxSize.height = debugInset.top + debugInset.bottom;
*/
aSize.ascent += inset.top;
aSize.ascent += debugInset.top;
@ -3144,10 +3203,9 @@ nsBoxDebugInner::DisplayDebugInfoFor(nsIPresContext* aPresContext,
if (mDebugChild == childFrame)
return PR_TRUE;
nsCOMPtr<nsIContent> content;
childFrame->GetContent(getter_AddRefs(content));
if (content) {
nsCOMPtr<nsIContent> content;
mOuter->mInner->GetContentOf(mOuter, getter_AddRefs(content));
nsString id;
content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id);
@ -3175,6 +3233,10 @@ nsBoxDebugInner::DisplayDebugInfoFor(nsIPresContext* aPresContext,
childFrame->GetContent(getter_AddRefs(content));
if (content) {
content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id);
id.ToCString(idValue,100);
@ -3211,7 +3273,7 @@ nsBoxDebugInner::DisplayDebugInfoFor(nsIPresContext* aPresContext,
// add in the css min, max, pref
const nsStylePosition* position;
nsresult rv = childFrame->GetStyleData(eStyleStruct_Position,
rv = childFrame->GetStyleData(eStyleStruct_Position,
(const nsStyleStruct*&) position);
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get position");

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

@ -44,6 +44,7 @@ class nsHTMLInfo;
#define NS_FRAME_BOX_SIZE_VALID 0x0001
#define NS_FRAME_BOX_IS_COLLAPSED 0x0002
#define NS_FRAME_BOX_NEEDS_RECALC 0x0004
#define NS_FRAME_IS_BOX 0x0008
class nsCalculatedBoxInfo : public nsBoxInfo {
public:
@ -178,7 +179,8 @@ protected:
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, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason);
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);

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

@ -350,7 +350,7 @@ nsDeckFrame::DidReflow(nsIPresContext* aPresContext,
void
nsDeckFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool* aResized, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason)
nsDeckFrame::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;

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

@ -84,7 +84,7 @@ protected:
virtual nsIFrame* GetSelectedFrame();
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, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason);
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);

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

@ -64,6 +64,17 @@ public:
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aFrameList);
NS_IMETHOD InsertFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList);
#ifdef DEBUG
NS_IMETHOD GetFrameName(nsString& aResult) const {
return MakeFrameName("GroupBoxFrame", aResult);
@ -77,7 +88,8 @@ public:
virtual PRBool GetInitialOrientation(PRBool& aHorizontal) { aHorizontal = PR_FALSE; return PR_TRUE; }
nsIFrame* GetGroupTitle(nsIPresContext* aPresContext, nsRect& aRect);
nsIFrame* GetTitleFrame(nsIPresContext* aPresContext, nsRect& aRect);
nsIFrame* GetContentFrame(nsIPresContext* aPresContext);
};
@ -171,7 +183,7 @@ nsTitledBoxFrame::Paint(nsIPresContext* aPresContext,
nscoord yoff = 0;
nsRect titleRect;
nsIFrame* titleFrame = GetGroupTitle(aPresContext, titleRect);
nsIFrame* titleFrame = GetTitleFrame(aPresContext, titleRect);
if (titleFrame) {
// if the border is smaller than the legend. Move the border down
@ -269,7 +281,7 @@ nsTitledBoxFrame::Paint(nsIPresContext* aPresContext,
}
nsIFrame*
nsTitledBoxFrame::GetGroupTitle(nsIPresContext* aPresContext, nsRect& aTitleRect)
nsTitledBoxFrame::GetTitleFrame(nsIPresContext* aPresContext, nsRect& aTitleRect)
{
// if we only have one child fail
nsIFrame* frame = mFrames.FirstChild();
@ -295,6 +307,20 @@ nsTitledBoxFrame::GetGroupTitle(nsIPresContext* aPresContext, nsRect& aTitleRect
return child;
}
nsIFrame*
nsTitledBoxFrame::GetContentFrame(nsIPresContext* aPresContext)
{
// the content frame is always our second frame. The title frame
// is the first.
nsIFrame* frame = mFrames.FirstChild();
nsIFrame* next = nsnull;
frame->GetNextSibling(&next);
if (!next)
return frame;
else
return next;
}
NS_IMETHODIMP
nsTitledBoxFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -319,3 +345,27 @@ nsTitledBoxFrame::Reflow(nsIPresContext* aPresContext,
return nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
}
NS_IMETHODIMP
nsTitledBoxFrame::InsertFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
nsIFrame* content = GetContentFrame(aPresContext);
NS_ASSERTION(content, "ERROR TitledBoxFrame has no content!!!");
return content->InsertFrames(aPresContext, aPresShell, aListName, aPrevFrame, aFrameList);
}
NS_IMETHODIMP
nsTitledBoxFrame::AppendFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aFrameList)
{
nsIFrame* content = GetContentFrame(aPresContext);
NS_ASSERTION(content, "ERROR TitledBoxFrame has no content!!!");
return content->AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
}

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

@ -64,6 +64,17 @@ public:
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aFrameList);
NS_IMETHOD InsertFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList);
#ifdef DEBUG
NS_IMETHOD GetFrameName(nsString& aResult) const {
return MakeFrameName("GroupBoxFrame", aResult);
@ -77,7 +88,8 @@ public:
virtual PRBool GetInitialOrientation(PRBool& aHorizontal) { aHorizontal = PR_FALSE; return PR_TRUE; }
nsIFrame* GetGroupTitle(nsIPresContext* aPresContext, nsRect& aRect);
nsIFrame* GetTitleFrame(nsIPresContext* aPresContext, nsRect& aRect);
nsIFrame* GetContentFrame(nsIPresContext* aPresContext);
};
@ -171,7 +183,7 @@ nsTitledBoxFrame::Paint(nsIPresContext* aPresContext,
nscoord yoff = 0;
nsRect titleRect;
nsIFrame* titleFrame = GetGroupTitle(aPresContext, titleRect);
nsIFrame* titleFrame = GetTitleFrame(aPresContext, titleRect);
if (titleFrame) {
// if the border is smaller than the legend. Move the border down
@ -269,7 +281,7 @@ nsTitledBoxFrame::Paint(nsIPresContext* aPresContext,
}
nsIFrame*
nsTitledBoxFrame::GetGroupTitle(nsIPresContext* aPresContext, nsRect& aTitleRect)
nsTitledBoxFrame::GetTitleFrame(nsIPresContext* aPresContext, nsRect& aTitleRect)
{
// if we only have one child fail
nsIFrame* frame = mFrames.FirstChild();
@ -295,6 +307,20 @@ nsTitledBoxFrame::GetGroupTitle(nsIPresContext* aPresContext, nsRect& aTitleRect
return child;
}
nsIFrame*
nsTitledBoxFrame::GetContentFrame(nsIPresContext* aPresContext)
{
// the content frame is always our second frame. The title frame
// is the first.
nsIFrame* frame = mFrames.FirstChild();
nsIFrame* next = nsnull;
frame->GetNextSibling(&next);
if (!next)
return frame;
else
return next;
}
NS_IMETHODIMP
nsTitledBoxFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -319,3 +345,27 @@ nsTitledBoxFrame::Reflow(nsIPresContext* aPresContext,
return nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
}
NS_IMETHODIMP
nsTitledBoxFrame::InsertFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
nsIFrame* content = GetContentFrame(aPresContext);
NS_ASSERTION(content, "ERROR TitledBoxFrame has no content!!!");
return content->InsertFrames(aPresContext, aPresShell, aListName, aPrevFrame, aFrameList);
}
NS_IMETHODIMP
nsTitledBoxFrame::AppendFrames(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aFrameList)
{
nsIFrame* content = GetContentFrame(aPresContext);
NS_ASSERTION(content, "ERROR TitledBoxFrame has no content!!!");
return content->AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
}

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

@ -0,0 +1,744 @@
/* -*- 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 "nsXULTextFrame.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 "nsButtonFrameRenderer.h"
#include "nsHTMLAtoms.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsButtonFrameRenderer.h"
#include "nsHTMLParts.h"
#include "nsString.h"
#include "nsLeafFrame.h"
#include "nsIPresShell.h"
#include "nsHTMLIIDs.h"
#include "nsIImage.h"
#include "nsIWidget.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 "nsTextFragment.h"
#include "nsIDOMHTMLMapElement.h"
#include "nsIStyleSet.h"
#include "nsFormControlHelper.h"
*/
#define ELIPSIS "..."
#define CROP_LEFT "left"
#define CROP_RIGHT "right"
#define CROP_CENTER "center"
#define NS_STATE_NEED_LAYOUT 0x00400000
class nsAccessKeyInfo
{
public:
PRInt32 mAccesskeyIndex;
nscoord mBeforeWidth, mAccessWidth, mAccessUnderlineSize, mAccessOffset;
};
//
// NS_NewToolbarFrame
//
// Creates a new Toolbar frame and returns it in |aNewFrame|
//
nsresult
NS_NewXULTextFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsXULTextFrame* it = new (aPresShell) nsXULTextFrame;
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
// it->SetFlags(aFlags);
*aNewFrame = it;
return NS_OK;
} // NS_NewTextFrame
NS_IMETHODIMP
nsXULTextFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint)
{
mState |= NS_STATE_NEED_LAYOUT;
PRBool aResize;
PRBool aRedraw;
PRBool aUpdateAccessUnderline;
UpdateAttributes(aPresContext, aAttribute, aResize, aRedraw, aUpdateAccessUnderline);
if (aUpdateAccessUnderline)
UpdateAccessUnderline();
if (aResize) {
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
mState |= NS_FRAME_IS_DIRTY;
mParent->ReflowDirtyChild(shell, this);
} else if (aRedraw) {
Invalidate(aPresContext, nsRect(0,0,mRect.width, mRect.height), PR_FALSE);
}
return NS_OK;
}
nsXULTextFrame::nsXULTextFrame():mTitle(""), mCropType(CropRight),mAccessKeyInfo(nsnull)
{
mState |= NS_STATE_NEED_LAYOUT;
}
nsXULTextFrame::~nsXULTextFrame()
{
if (mAccessKeyInfo)
delete mAccessKeyInfo;
}
NS_IMETHODIMP
nsXULTextFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsLeafFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
PRBool a,b,c;
UpdateAttributes(aPresContext, nsnull, a, b, c /* all */);
// the following block is to append the accesskey to to mTitle if there is an accesskey
// but the mTitle doesn't have the character
#ifndef XP_UNIX
nsAutoString accesskey;
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey,
accesskey);
if (accesskey != "") {
if (!mAccessKeyInfo)
mAccessKeyInfo = new nsAccessKeyInfo();
mAccessKeyInfo->mAccesskeyIndex = -1;
mAccessKeyInfo->mAccesskeyIndex = mTitle.Find(accesskey, PR_TRUE);
if (mAccessKeyInfo->mAccesskeyIndex == -1) {
nsString tmpstring = "(" ;
accesskey.ToUpperCase();
tmpstring += accesskey;
tmpstring += ")";
PRUint32 offset = mTitle.RFind("...");
if ( offset != kNotFound)
mTitle.Insert(tmpstring,offset);
else
mTitle += tmpstring;
}
} else {
if (mAccessKeyInfo) {
delete mAccessKeyInfo;
mAccessKeyInfo = nsnull;
}
}
#endif
return rv;
}
void
nsXULTextFrame::UpdateAttributes(nsIPresContext* aPresContext, nsIAtom* aAttribute, PRBool& aResize, PRBool& aRedraw, PRBool& aUpdateAccessUnderline)
{
aResize = PR_FALSE;
aRedraw = PR_FALSE;
aUpdateAccessUnderline = PR_FALSE;
if (aAttribute == nsnull || aAttribute == nsXULAtoms::crop) {
nsAutoString value;
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::crop, value);
CroppingStyle cropType;
if (value.EqualsIgnoreCase(CROP_LEFT))
cropType = CropLeft;
else if (value.EqualsIgnoreCase(CROP_CENTER))
cropType = CropCenter;
else if (value.EqualsIgnoreCase(CROP_RIGHT))
cropType = CropRight;
else
cropType = CropNone;
if (cropType != mCropType) {
aResize = PR_TRUE;
mCropType = cropType;
aUpdateAccessUnderline = PR_TRUE;
}
}
if (aAttribute == nsnull || aAttribute == nsHTMLAtoms::value) {
nsAutoString value;
mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, value);
if (!value.Equals(mTitle)) {
/*
ListTag(stdout);
char a[100];
char b[100];
mTitle.ToCString(a,100);
value.ToCString(b,100);
printf(" value changed '%s'->'%s'\n",a,b);
*/
aResize = PR_TRUE;
mTitle = value;
aUpdateAccessUnderline = PR_TRUE;
}
}
if (aAttribute == nsXULAtoms::accesskey) {
aRedraw = PR_TRUE;
aUpdateAccessUnderline = PR_TRUE;
}
}
NS_IMETHODIMP
nsXULTextFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (!disp->mVisible)
return NS_OK;
if (eFramePaintLayer_Content == aWhichLayer) {
// remove the border and padding
const nsStyleSpacing* spacing = (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin border(0,0,0,0);
spacing->GetBorderPadding(border);
nsRect textRect(0,0,mRect.width, mRect.height);
textRect.Deflate(border);
LayoutTitle(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, textRect);
PaintTitle(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, textRect);
}
return nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
void
nsXULTextFrame::LayoutTitle(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer,
const nsRect& aRect)
{
// and do caculations if our size changed
if (!(mState & NS_STATE_NEED_LAYOUT))
return;
// get title and center it
CalculateTitleForWidth(aPresContext, aRenderingContext, aRect.width);
if (mAccessKeyInfo)
{
if (mAccessKeyInfo->mAccesskeyIndex != -1) {
// get all the underline-positioning stuff
// XXX are attribute values always two byte?
const PRUnichar *titleString;
titleString = mCroppedTitle.GetUnicode();
if (mAccessKeyInfo->mAccesskeyIndex)
aRenderingContext.GetWidth(titleString, mAccessKeyInfo->mAccesskeyIndex,
mAccessKeyInfo->mBeforeWidth);
else
mAccessKeyInfo->mBeforeWidth = 0;
aRenderingContext.GetWidth(titleString[mAccessKeyInfo->mAccesskeyIndex],
mAccessKeyInfo->mAccessWidth);
nscoord offset, baseline;
nsIFontMetrics *metrics;
aRenderingContext.GetFontMetrics(metrics);
metrics->GetUnderline(offset, mAccessKeyInfo->mAccessUnderlineSize);
metrics->GetMaxAscent(baseline);
NS_RELEASE(metrics);
mAccessKeyInfo->mAccessOffset = baseline - offset;
}
}
// ok layout complete
mState &= ~NS_STATE_NEED_LAYOUT;
}
NS_IMETHODIMP
nsXULTextFrame::PaintTitle(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer,
const nsRect& aRect)
{
if (mTitle.Length() == 0)
return NS_OK;
// make the rect as small as our text.
nsRect textRect(aRect);
textRect.width = mTitleWidth;
// don't draw if the title is not dirty
if (PR_FALSE == aDirtyRect.Intersects(aRect))
return NS_OK;
// paint the title
const nsStyleFont* fontStyle = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
const nsStyleColor* colorStyle = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
aRenderingContext.SetFont(fontStyle->mFont);
if (mAccessKeyInfo) {
if (mAccessKeyInfo->mAccesskeyIndex != -1) {
// get all the underline-positioning stuff
// XXX are attribute values always two byte?
const PRUnichar *titleString;
titleString = mCroppedTitle.GetUnicode();
if (mAccessKeyInfo->mAccesskeyIndex)
aRenderingContext.GetWidth(titleString, mAccessKeyInfo->mAccesskeyIndex,
mAccessKeyInfo->mBeforeWidth);
else
mAccessKeyInfo->mBeforeWidth = 0;
aRenderingContext.GetWidth(titleString[mAccessKeyInfo->mAccesskeyIndex],
mAccessKeyInfo->mAccessWidth);
nscoord offset, baseline;
nsIFontMetrics *metrics;
aRenderingContext.GetFontMetrics(metrics);
metrics->GetUnderline(offset, mAccessKeyInfo->mAccessUnderlineSize);
metrics->GetMaxAscent(baseline);
NS_RELEASE(metrics);
mAccessKeyInfo->mAccessOffset = baseline - offset;
}
}
aRenderingContext.SetColor(colorStyle->mColor);
aRenderingContext.DrawString(mCroppedTitle, textRect.x, textRect.y);
if (mAccessKeyInfo) {
if (mAccessKeyInfo->mAccesskeyIndex != -1) {
aRenderingContext.FillRect(textRect.x + mAccessKeyInfo->mBeforeWidth,
textRect.y + mAccessKeyInfo->mAccessOffset,
mAccessKeyInfo->mAccessWidth, mAccessKeyInfo->mAccessUnderlineSize);
}
}
return NS_OK;
}
void
nsXULTextFrame::GetTextSize(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext,
const nsString& aString, nsSize& aSize, nscoord& aAscent)
{
const nsStyleFont* fontStyle = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
nsCOMPtr<nsIDeviceContext> deviceContext;
aPresContext->GetDeviceContext(getter_AddRefs(deviceContext));
nsCOMPtr<nsIFontMetrics> fontMet;
deviceContext->GetMetricsFor(fontStyle->mFont, *getter_AddRefs(fontMet));
fontMet->GetHeight(aSize.height);
aRenderingContext.SetFont(fontMet);
aRenderingContext.GetWidth(aString, aSize.width);
fontMet->GetMaxAscent(aAscent);
}
void
nsXULTextFrame::CalculateTitleForWidth(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, nscoord aWidth)
{
if (mTitle.Length() == 0)
return;
const nsStyleFont* fontStyle = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
nsCOMPtr<nsIDeviceContext> deviceContext;
aPresContext->GetDeviceContext(getter_AddRefs(deviceContext));
nsCOMPtr<nsIFontMetrics> fontMet;
deviceContext->GetMetricsFor(fontStyle->mFont, *getter_AddRefs(fontMet));
aRenderingContext.SetFont(fontMet);
// see if the text will completely fit in the width given
aRenderingContext.GetWidth(mTitle, mTitleWidth);
mCroppedTitle = mTitle;
if ( aWidth >= mTitleWidth)
return; // fits done.
// see if the width is even smaller or equal to the elipsis the
// text become the elipsis.
nscoord elipsisWidth;
aRenderingContext.GetWidth(ELIPSIS, elipsisWidth);
mTitleWidth = aWidth;
if (aWidth <= elipsisWidth) {
mCroppedTitle = "";
return;
}
mCroppedTitle = ELIPSIS;
aWidth -= elipsisWidth;
// ok crop things
switch (mCropType)
{
case CropNone:
case CropRight:
{
nscoord cwidth;
nscoord twidth = 0;
int length = mTitle.Length();
int i = 0;
for (i = 0; i < length; i++)
{
PRUnichar ch = mTitle.CharAt(i);
aRenderingContext.GetWidth(ch,cwidth);
if (twidth + cwidth > aWidth)
break;
twidth += cwidth;
}
if (i == 0)
return;
// insert what character we can in.
nsString title = mTitle;
title.Truncate(i);
mCroppedTitle = title + mCroppedTitle;
}
break;
case CropLeft:
{
nscoord cwidth;
nscoord twidth = 0;
int length = mTitle.Length();
int i = length-1;
for (i=length-1; i >= 0; i--)
{
PRUnichar ch = mTitle.CharAt(i);
aRenderingContext.GetWidth(ch,cwidth);
if (twidth + cwidth > aWidth)
break;
twidth += cwidth;
}
if (i == 0)
break;
nsString copy = "";
mTitle.Right(copy, length-i-1);
mCroppedTitle = mCroppedTitle + copy;
}
break;
case CropCenter:
nsString elipsisLeft = ELIPSIS;
if (aWidth <= elipsisWidth)
elipsisLeft = "";
else
aWidth -= elipsisWidth;
nscoord cwidth;
nscoord twidth = 0;
aRenderingContext.GetWidth(mTitle, twidth);
int length = mTitle.Length();
int i = 0;
int i2 = length-1;
for (i = 0; i < length;)
{
PRUnichar ch = mTitle.CharAt(i);
aRenderingContext.GetWidth(ch,cwidth);
twidth -= cwidth;
i++;
if (twidth <= aWidth)
break;
ch = mTitle.CharAt(i2);
aRenderingContext.GetWidth(ch,cwidth);
i2--;
twidth -= cwidth;
if (twidth <= aWidth) {
break;
}
}
nsString copy = "";
if (i2 > i)
mTitle.Mid(copy, i,i2-i);
/*
char cht[100];
mTitle.ToCString(cht,100);
char chc[100];
copy.ToCString(chc,100);
printf("i=%d, i2=%d, diff=%d, old='%s', new='%s', aWidth=%d\n", i, i2, i2-i, cht,chc, aWidth);
*/
mCroppedTitle = elipsisLeft + copy + mCroppedTitle;
break;
}
aRenderingContext.GetWidth(mCroppedTitle, mTitleWidth);
}
void
nsXULTextFrame::UpdateAccessUnderline()
{
#ifndef XP_UNIX
nsAutoString accesskey;
mContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::accesskey,
accesskey);
if (accesskey == "") {
if (mAccessKeyInfo) {
delete mAccessKeyInfo;
mAccessKeyInfo = nsnull;
}
return; // our work here is done
}
if (!mAccessKeyInfo)
mAccessKeyInfo = new nsAccessKeyInfo();
mAccessKeyInfo->mAccesskeyIndex = -1;
mAccessKeyInfo->mAccesskeyIndex = mCroppedTitle.Find(accesskey, PR_TRUE);
#endif
}
NS_IMETHODIMP
nsXULTextFrame::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);
}
mState |= NS_STATE_NEED_LAYOUT;
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
nsXULTextFrame::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
nsXULTextFrame::InvalidateCache(nsIFrame* aChild)
{
// we don't cache any information
return NS_OK;
}
/**
* Ok return our dimensions
*/
NS_IMETHODIMP
nsXULTextFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& 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);
aSize.ascent = ascent;
aSize.prefSize = size;
aSize.minSize = size;
// if there is cropping our min width becomes 0
if (mCropType != CropNone)
aSize.minSize.width = 0;
return NS_OK;
}
/**
* We can be a nsIBox
*/
NS_IMETHODIMP
nsXULTextFrame::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)
nsXULTextFrame::AddRef(void)
{
return NS_OK;
}
NS_IMETHODIMP_(nsrefcnt)
nsXULTextFrame::Release(void)
{
return NS_OK;
}
NS_IMETHODIMP
nsXULTextFrame::GetFrameName(nsString& aResult) const
{
aResult = "Text[value=";
aResult += mTitle;
aResult += "]";
return NS_OK;
}

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

@ -0,0 +1,108 @@
/* -*- 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 nsXULTextFrame_h___
#define nsXULTextFrame_h___
#include "nsLeafFrame.h"
#include "nsIBox.h"
class nsAccessKeyInfo;
class nsXULTextFrame : public nsLeafFrame, public nsIBox
{
public:
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);
NS_IMETHOD InvalidateCache(nsIFrame* aChild);
NS_DECL_ISUPPORTS
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 GetFrameName(nsString& aResult) const;
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,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
~nsXULTextFrame();
protected:
void UpdateAccessUnderline();
NS_IMETHOD PaintTitle(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer,
const nsRect& aTextRect);
virtual void LayoutTitle(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer,
const nsRect& aTextRect);
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aDesiredSize);
nsXULTextFrame();
virtual void CalculateTitleForWidth(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, nscoord aWidth);
virtual void GetTextSize(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsString& aString, nsSize& aSize, nscoord& aAscent);
private:
CroppingStyle mCropType;
nsString mTitle;
nsString mCroppedTitle;
nscoord mTitleWidth;
nsAccessKeyInfo* mAccessKeyInfo;
}; // class nsXULTextFrame
#endif /* nsTitledButtonFrame_h___ */

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

@ -223,7 +223,7 @@ Contributor(s): ______________________________________. -->
ondragover="return DragOverPersonalToolbar(event);">
<!-- button area of personal toolbar -->
<box align="horizontal" flex="1" style="min-width: 1px">
<box align="horizontal" flex="1">
<!--
// I added the container=true on this button as a temp hack until
@ -267,7 +267,7 @@ Contributor(s): ______________________________________. -->
<spring class="personaltoolbarspacer" flex="1"/>
</menu>
<box align="horizontal"
<box align="horizontal"
flex="1"
style="min-width: 1px; overflow: hidden"
datasources="rdf:bookmarks"
@ -282,13 +282,13 @@ Contributor(s): ______________________________________. -->
align="right" class="bookmarkFolder toolbar-flat"/>
<menupopup class="standard"/>
</menu>
<spring uri="rdf:*" class="personaltoolbarspacer" flex="1"/>
<spring uri="rdf:*" class="personaltoolbarspacer" flex="0"/>
</rule>
<rule parent="box">
<titledbutton class="bookmarkbutton toolbar-flat" uri="rdf:*" align="left"
value="rdf:http://home.netscape.com/NC-rdf#Name" crop="right"
oncommand="OpenBookmarkURL(event.target, document.getElementById('innermostBox').database)"/>
<spring uri="rdf:*" class="personaltoolbarspacer" flex="1"/>
<spring uri="rdf:*" class="personaltoolbarspacer" flex="0"/>
</rule>
<!-- Recursive rules for nested folders -->
@ -318,10 +318,10 @@ Contributor(s): ______________________________________. -->
value="&homeButton.label;"
class="bookmarkbutton toolbar-flat"
onclick="BrowserHome(); event.preventBubble();"/>
<spring class="personaltoolbarspacer" flex="1"/>
<spring class="personaltoolbarspacer" flex="0"/>
</box>
<spring flex="9999999"/>
<spring flex="1"/>
</box>
<!-- throbber area of personal toolbar -->

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

@ -613,6 +613,13 @@ progressmeter[mode="undetermined"]
background-image: url(chrome://global/skin/progressmeter-busy.gif);
}
/********* Box ********/
box
{
vertical-align: top;
}
/********* TitledBox **********/
titledbox