From d6abe407cd4af43d4eaa2a2ec93a738ae632f2da Mon Sep 17 00:00:00 2001 From: "roc+%cs.cmu.edu" Date: Fri, 21 Nov 2003 10:45:24 +0000 Subject: [PATCH] Bug 30579. Add a skinnable 'scrollcorner' element to fill in the gap when there are two scrollbars. r+sr=bryner,a=asa git-svn-id: svn://10.0.0.236/trunk@149611 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/shared/public/nsXULAtomList.h | 1 + mozilla/layout/base/nsCSSFrameConstructor.cpp | 3 +- mozilla/layout/generic/nsGfxScrollFrame.cpp | 72 +++++++++++++++---- .../layout/html/base/src/nsGfxScrollFrame.cpp | 72 +++++++++++++++---- .../html/style/src/nsCSSFrameConstructor.cpp | 3 +- .../classic/global/mac/nativescrollbars.css | 6 ++ .../classic/global/mac/xulscrollbars.css | 6 ++ .../themes/classic/global/win/scrollbars.css | 6 ++ .../themes/modern/global/scrollbars-mini.css | 6 ++ mozilla/themes/modern/global/scrollbars.css | 6 ++ 10 files changed, 153 insertions(+), 28 deletions(-) diff --git a/mozilla/content/shared/public/nsXULAtomList.h b/mozilla/content/shared/public/nsXULAtomList.h index 50c24890c0d..3b75573db11 100644 --- a/mozilla/content/shared/public/nsXULAtomList.h +++ b/mozilla/content/shared/public/nsXULAtomList.h @@ -62,6 +62,7 @@ XUL_ATOM(button, "button") XUL_ATOM(spinner, "spinner") XUL_ATOM(scrollbar, "scrollbar") XUL_ATOM(nativescrollbar, "nativescrollbar") +XUL_ATOM(scrollcorner, "scrollcorner") XUL_ATOM(slider, "slider") XUL_ATOM(palettename, "palettename") XUL_ATOM(fontpicker, "fontpicker") diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index 346aa503587..09b6528a6ef 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -5089,7 +5089,8 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell #ifdef MOZ_XUL // Only cut XUL scrollbars off if they're not in a XUL document. This allows // scrollbars to be styled from XUL (although not from XML or HTML). - if (content->Tag() == nsXULAtoms::scrollbar) { + nsIAtom* tag = content->Tag(); + if (tag == nsXULAtoms::scrollbar || tag == nsXULAtoms::scrollcorner) { nsCOMPtr xulDoc(do_QueryInterface(aDocument)); if (xulDoc) content->SetBindingParent(aParent); diff --git a/mozilla/layout/generic/nsGfxScrollFrame.cpp b/mozilla/layout/generic/nsGfxScrollFrame.cpp index daffdb8653e..4e6cb5b3536 100644 --- a/mozilla/layout/generic/nsGfxScrollFrame.cpp +++ b/mozilla/layout/generic/nsGfxScrollFrame.cpp @@ -135,6 +135,7 @@ public: nsIBox* mHScrollbarBox; nsIBox* mVScrollbarBox; nsIBox* mScrollAreaBox; + nsIBox* mScrollCornerBox; nscoord mOnePixel; nsGfxScrollFrame* mOuter; nsIScrollableView* mScrollableView; @@ -392,8 +393,9 @@ nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext, kNameSpaceID_XUL, getter_AddRefs(nodeInfo)); ScrollbarStyles styles = GetScrollbarStyles(); - if (styles.mHorizontal == NS_STYLE_OVERFLOW_AUTO - || styles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL) { + PRBool canHaveHorizontal = styles.mHorizontal == NS_STYLE_OVERFLOW_AUTO + || styles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL; + if (canHaveHorizontal) { nsCOMPtr content; elementFactory->CreateInstanceByTag(nodeInfo, getter_AddRefs(content)); content->SetAttr(kNameSpaceID_None, nsXULAtoms::orient, @@ -403,8 +405,9 @@ nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext, aAnonymousChildren.AppendElement(content); } - if (styles.mVertical == NS_STYLE_OVERFLOW_AUTO - || styles.mVertical == NS_STYLE_OVERFLOW_SCROLL) { + PRBool canHaveVertical = styles.mVertical == NS_STYLE_OVERFLOW_AUTO + || styles.mVertical == NS_STYLE_OVERFLOW_SCROLL; + if (canHaveVertical) { nsCOMPtr content; elementFactory->CreateInstanceByTag(nodeInfo, getter_AddRefs(content)); content->SetAttr(kNameSpaceID_None, nsXULAtoms::orient, @@ -414,6 +417,14 @@ nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext, aAnonymousChildren.AppendElement(content); } + if (canHaveHorizontal && canHaveVertical) { + nodeInfoManager->GetNodeInfo(NS_LITERAL_CSTRING("scrollcorner"), nsnull, + kNameSpaceID_XUL, getter_AddRefs(nodeInfo)); + nsCOMPtr content; + elementFactory->CreateInstanceByTag(nodeInfo, getter_AddRefs(content)); + aAnonymousChildren.AppendElement(content); + } + return NS_OK; } @@ -436,9 +447,8 @@ nsGfxScrollFrame::Init(nsIPresContext* aPresContext, nsIFrame* aPrevInFlow) { mPresContext = aPresContext; - nsresult rv = nsBoxFrame::Init(aPresContext, aContent, - aParent, aStyleContext, - aPrevInFlow); + nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aStyleContext, + aPrevInFlow); return rv; } @@ -447,6 +457,7 @@ void nsGfxScrollFrame::ReloadChildFrames(nsIPresContext* aPresContext) mInner->mScrollAreaBox = nsnull; mInner->mHScrollbarBox = nsnull; mInner->mVScrollbarBox = nsnull; + mInner->mScrollCornerBox = nsnull; nsIFrame* frame = nsnull; FirstChild(aPresContext, nsnull, &frame); @@ -475,6 +486,11 @@ void nsGfxScrollFrame::ReloadChildFrames(nsIPresContext* aPresContext) mInner->mVScrollbarBox = box; } understood = PR_TRUE; + } else { + // probably a scrollcorner + NS_ASSERTION(!mInner->mScrollCornerBox, "Found multiple scrollcorners"); + mInner->mScrollCornerBox = box; + understood = PR_TRUE; } } } @@ -869,12 +885,14 @@ NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame) //-------------------- Inner ---------------------- -nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsGfxScrollFrame* aOuter):mHScrollbarBox(nsnull), - mVScrollbarBox(nsnull), - mScrollAreaBox(nsnull), - mOnePixel(20), - mHasVerticalScrollbar(PR_FALSE), - mHasHorizontalScrollbar(PR_FALSE) +nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsGfxScrollFrame* aOuter) + : mHScrollbarBox(nsnull), + mVScrollbarBox(nsnull), + mScrollAreaBox(nsnull), + mScrollCornerBox(nsnull), + mOnePixel(20), + mHasVerticalScrollbar(PR_FALSE), + mHasHorizontalScrollbar(PR_FALSE) { mOuter = aOuter; mMaxElementWidth = 0; @@ -1548,6 +1566,34 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState) needsLayout = PR_FALSE; } + // place the scrollcorner + if (mScrollCornerBox) { + nsRect r(0, 0, 0, 0); + if (clientRect.x != scrollAreaRect.x) { + // scrollbar (if any) on left + r.x = clientRect.x; + r.width = scrollAreaRect.x - clientRect.x; + NS_ASSERTION(r.width >= 0, "Scroll area should be inside client rect"); + } else { + // scrollbar (if any) on right + r.x = scrollAreaRect.XMost(); + r.width = clientRect.XMost() - scrollAreaRect.XMost(); + NS_ASSERTION(r.width >= 0, "Scroll area should be inside client rect"); + } + if (clientRect.y != scrollAreaRect.y) { + // scrollbar (if any) on top + r.y = clientRect.y; + r.height = scrollAreaRect.y - clientRect.y; + NS_ASSERTION(r.height >= 0, "Scroll area should be inside client rect"); + } else { + // scrollbar (if any) on bottom + r.y = scrollAreaRect.YMost(); + r.height = clientRect.YMost() - scrollAreaRect.YMost(); + NS_ASSERTION(r.height >= 0, "Scroll area should be inside client rect"); + } + LayoutBox(aState, mScrollCornerBox, r); + } + // may need to update fixed position children of the viewport, // if the client area changed size because of some dirty reflow // (if the reflow is initial or resize, the fixed children will diff --git a/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp b/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp index daffdb8653e..4e6cb5b3536 100644 --- a/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp +++ b/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp @@ -135,6 +135,7 @@ public: nsIBox* mHScrollbarBox; nsIBox* mVScrollbarBox; nsIBox* mScrollAreaBox; + nsIBox* mScrollCornerBox; nscoord mOnePixel; nsGfxScrollFrame* mOuter; nsIScrollableView* mScrollableView; @@ -392,8 +393,9 @@ nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext, kNameSpaceID_XUL, getter_AddRefs(nodeInfo)); ScrollbarStyles styles = GetScrollbarStyles(); - if (styles.mHorizontal == NS_STYLE_OVERFLOW_AUTO - || styles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL) { + PRBool canHaveHorizontal = styles.mHorizontal == NS_STYLE_OVERFLOW_AUTO + || styles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL; + if (canHaveHorizontal) { nsCOMPtr content; elementFactory->CreateInstanceByTag(nodeInfo, getter_AddRefs(content)); content->SetAttr(kNameSpaceID_None, nsXULAtoms::orient, @@ -403,8 +405,9 @@ nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext, aAnonymousChildren.AppendElement(content); } - if (styles.mVertical == NS_STYLE_OVERFLOW_AUTO - || styles.mVertical == NS_STYLE_OVERFLOW_SCROLL) { + PRBool canHaveVertical = styles.mVertical == NS_STYLE_OVERFLOW_AUTO + || styles.mVertical == NS_STYLE_OVERFLOW_SCROLL; + if (canHaveVertical) { nsCOMPtr content; elementFactory->CreateInstanceByTag(nodeInfo, getter_AddRefs(content)); content->SetAttr(kNameSpaceID_None, nsXULAtoms::orient, @@ -414,6 +417,14 @@ nsGfxScrollFrame::CreateAnonymousContent(nsIPresContext* aPresContext, aAnonymousChildren.AppendElement(content); } + if (canHaveHorizontal && canHaveVertical) { + nodeInfoManager->GetNodeInfo(NS_LITERAL_CSTRING("scrollcorner"), nsnull, + kNameSpaceID_XUL, getter_AddRefs(nodeInfo)); + nsCOMPtr content; + elementFactory->CreateInstanceByTag(nodeInfo, getter_AddRefs(content)); + aAnonymousChildren.AppendElement(content); + } + return NS_OK; } @@ -436,9 +447,8 @@ nsGfxScrollFrame::Init(nsIPresContext* aPresContext, nsIFrame* aPrevInFlow) { mPresContext = aPresContext; - nsresult rv = nsBoxFrame::Init(aPresContext, aContent, - aParent, aStyleContext, - aPrevInFlow); + nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aStyleContext, + aPrevInFlow); return rv; } @@ -447,6 +457,7 @@ void nsGfxScrollFrame::ReloadChildFrames(nsIPresContext* aPresContext) mInner->mScrollAreaBox = nsnull; mInner->mHScrollbarBox = nsnull; mInner->mVScrollbarBox = nsnull; + mInner->mScrollCornerBox = nsnull; nsIFrame* frame = nsnull; FirstChild(aPresContext, nsnull, &frame); @@ -475,6 +486,11 @@ void nsGfxScrollFrame::ReloadChildFrames(nsIPresContext* aPresContext) mInner->mVScrollbarBox = box; } understood = PR_TRUE; + } else { + // probably a scrollcorner + NS_ASSERTION(!mInner->mScrollCornerBox, "Found multiple scrollcorners"); + mInner->mScrollCornerBox = box; + understood = PR_TRUE; } } } @@ -869,12 +885,14 @@ NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame) //-------------------- Inner ---------------------- -nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsGfxScrollFrame* aOuter):mHScrollbarBox(nsnull), - mVScrollbarBox(nsnull), - mScrollAreaBox(nsnull), - mOnePixel(20), - mHasVerticalScrollbar(PR_FALSE), - mHasHorizontalScrollbar(PR_FALSE) +nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsGfxScrollFrame* aOuter) + : mHScrollbarBox(nsnull), + mVScrollbarBox(nsnull), + mScrollAreaBox(nsnull), + mScrollCornerBox(nsnull), + mOnePixel(20), + mHasVerticalScrollbar(PR_FALSE), + mHasHorizontalScrollbar(PR_FALSE) { mOuter = aOuter; mMaxElementWidth = 0; @@ -1548,6 +1566,34 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState) needsLayout = PR_FALSE; } + // place the scrollcorner + if (mScrollCornerBox) { + nsRect r(0, 0, 0, 0); + if (clientRect.x != scrollAreaRect.x) { + // scrollbar (if any) on left + r.x = clientRect.x; + r.width = scrollAreaRect.x - clientRect.x; + NS_ASSERTION(r.width >= 0, "Scroll area should be inside client rect"); + } else { + // scrollbar (if any) on right + r.x = scrollAreaRect.XMost(); + r.width = clientRect.XMost() - scrollAreaRect.XMost(); + NS_ASSERTION(r.width >= 0, "Scroll area should be inside client rect"); + } + if (clientRect.y != scrollAreaRect.y) { + // scrollbar (if any) on top + r.y = clientRect.y; + r.height = scrollAreaRect.y - clientRect.y; + NS_ASSERTION(r.height >= 0, "Scroll area should be inside client rect"); + } else { + // scrollbar (if any) on bottom + r.y = scrollAreaRect.YMost(); + r.height = clientRect.YMost() - scrollAreaRect.YMost(); + NS_ASSERTION(r.height >= 0, "Scroll area should be inside client rect"); + } + LayoutBox(aState, mScrollCornerBox, r); + } + // may need to update fixed position children of the viewport, // if the client area changed size because of some dirty reflow // (if the reflow is initial or resize, the fixed children will diff --git a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp index 346aa503587..09b6528a6ef 100644 --- a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -5089,7 +5089,8 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell #ifdef MOZ_XUL // Only cut XUL scrollbars off if they're not in a XUL document. This allows // scrollbars to be styled from XUL (although not from XML or HTML). - if (content->Tag() == nsXULAtoms::scrollbar) { + nsIAtom* tag = content->Tag(); + if (tag == nsXULAtoms::scrollbar || tag == nsXULAtoms::scrollcorner) { nsCOMPtr xulDoc(do_QueryInterface(aDocument)); if (xulDoc) content->SetBindingParent(aParent); diff --git a/mozilla/themes/classic/global/mac/nativescrollbars.css b/mozilla/themes/classic/global/mac/nativescrollbars.css index 6d48c8b5cdb..b79acad6631 100644 --- a/mozilla/themes/classic/global/mac/nativescrollbars.css +++ b/mozilla/themes/classic/global/mac/nativescrollbars.css @@ -37,6 +37,12 @@ scrollbar { cursor: default; } +/* ::::: square at the corner of two scrollbars ::::: */ + +scrollcorner { + background-color: -moz-Dialog; +} + /* :::::::::::::::::::::::::::::::::::::::::::::::::::::::: */ /* ::::::::::::::::::::: MEDIA PRINT :::::::::::::::::::::: */ /* :::::::::::::::::::::::::::::::::::::::::::::::::::::::: */ diff --git a/mozilla/themes/classic/global/mac/xulscrollbars.css b/mozilla/themes/classic/global/mac/xulscrollbars.css index ab45fdd3c2e..65036404ff6 100644 --- a/mozilla/themes/classic/global/mac/xulscrollbars.css +++ b/mozilla/themes/classic/global/mac/xulscrollbars.css @@ -115,6 +115,12 @@ scrollbarbutton:hover:active { background-color: #666666; } +/* ::::: square at the corner of two scrollbars ::::: */ + +scrollcorner { + background-color: -moz-Dialog; +} + /* ..... increment .... */ scrollbarbutton[type="increment"] { diff --git a/mozilla/themes/classic/global/win/scrollbars.css b/mozilla/themes/classic/global/win/scrollbars.css index 6169981bf0d..449b6feae62 100644 --- a/mozilla/themes/classic/global/win/scrollbars.css +++ b/mozilla/themes/classic/global/win/scrollbars.css @@ -90,6 +90,12 @@ scrollbarbutton:hover:active { background-position: 1px 2px; } +/* ::::: square at the corner of two scrollbars ::::: */ + +scrollcorner { + background-color: -moz-Dialog; +} + /* ..... increment .... */ scrollbarbutton[type="increment"] { diff --git a/mozilla/themes/modern/global/scrollbars-mini.css b/mozilla/themes/modern/global/scrollbars-mini.css index 552097ca0f1..e915fe869ff 100644 --- a/mozilla/themes/modern/global/scrollbars-mini.css +++ b/mozilla/themes/modern/global/scrollbars-mini.css @@ -49,6 +49,12 @@ scrollbar { cursor: default; } +/* ::::: square at the corner of two scrollbars ::::: */ + +scrollcorner { + background-color: #B1BBC5; +} + /* ::::: slider ::::: */ slider { diff --git a/mozilla/themes/modern/global/scrollbars.css b/mozilla/themes/modern/global/scrollbars.css index 0bbef874ac3..b5febd40811 100644 --- a/mozilla/themes/modern/global/scrollbars.css +++ b/mozilla/themes/modern/global/scrollbars.css @@ -110,6 +110,12 @@ scrollbarbutton:hover:active { background-color: #9CA8B4; } +/* ::::: square at the corner of two scrollbars ::::: */ + +scrollcorner { + background-color: #B1BBC5; +} + /* ..... increment .... */ scrollbarbutton[type="increment"] {