xpscrollbars

This commit is contained in:
evaughan%netscape.com 1999-08-19 22:16:23 +00:00
parent 3b54903181
commit a12f942778
35 changed files with 6352 additions and 361 deletions

View File

@ -0,0 +1,42 @@
/* -*- 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIAnonymousContent_h___
#define nsIAnonymousContent_h___
#include "nsISupports.h"
#include "nsIContent.h"
#include "nsCOMPtr.h"
class nsISupportsArray;
class nsIAtom;
#define NS_IANONYMOUS_CONTENT_IID { 0x41a69e00, 0x2d6d, 0x12d3, { 0xb0, 0x33, 0xa1, 0x38, 0x71, 0x39, 0x78, 0x7c } }
/**
* If a node is anonymous. Then it should implement this interface.
*/
class nsIAnonymousContent : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IANONYMOUS_CONTENT_IID; return iid; }
};
#endif

View File

@ -86,6 +86,7 @@ XUL_ATOM(crop, "crop")
XUL_ATOM(mode, "mode")
XUL_ATOM(box, "box")
XUL_ATOM(flex, "flex")
XUL_ATOM(spring, "spring")
XUL_ATOM(deck, "deck")
XUL_ATOM(tabcontrol, "tabcontrol")

View File

@ -79,6 +79,17 @@
#include "nsDocument.h"
#include "nsToolbarItemFrame.h"
#define IS_GFX
nsresult
NS_NewThumbFrame ( nsIFrame** aNewFrame );
nsresult
NS_NewScrollPortFrame ( nsIFrame** aNewFrame );
nsresult
NS_NewGfxScrollFrame ( nsIFrame** aNewFrame );
nsresult
NS_NewTabFrame ( nsIFrame** aNewFrame );
@ -1316,29 +1327,15 @@ nsCSSFrameConstructor::ConstructTableGroupFrameOnly(nsIPresContext* aPr
(const nsStyleDisplay*) aStyleContext->GetStyleData(eStyleStruct_Display);
if (IsScrollable(aPresContext, styleDisplay)) {
// Create a scroll frame and initialize it
rv = NS_NewScrollFrame(&aNewTopFrame);
if (NS_FAILED(rv)) return rv;
aNewTopFrame->Init(*aPresContext, aContent, aParentFrame, aStyleContext, nsnull);
// The scroll frame gets the original style context, the scrolled frame gets
// a pseudo element style context that inherits the background properties
nsCOMPtr<nsIStyleContext> scrolledPseudoStyle;
aPresContext->ResolvePseudoStyleContextFor(aContent, nsLayoutAtoms::scrolledContentPseudo,
aStyleContext, PR_FALSE,
getter_AddRefs(scrolledPseudoStyle));
// Create an area container for the frame
rv = (aIsRowGroup) ? aTableCreator.CreateTableRowGroupFrame(&aNewGroupFrame)
: aTableCreator.CreateTableColGroupFrame(&aNewGroupFrame);
if (NS_FAILED(rv)) return rv;
// Initialize the frame and force it to have a view
aNewGroupFrame->Init(*aPresContext, aContent, aNewTopFrame, scrolledPseudoStyle,
nsnull);
nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, aNewGroupFrame,
scrolledPseudoStyle, PR_TRUE);
aNewTopFrame->SetInitialChildList(*aPresContext, nsnull, aNewGroupFrame);
rv = BuildScrollFrame(aPresContext, aState, aContent, aNewGroupFrame, aParentFrame,
aStyleContext, aNewTopFrame, PR_FALSE, PR_FALSE, PR_FALSE,
PR_FALSE);
} else {
rv = (aIsRowGroup) ? aTableCreator.CreateTableRowGroupFrame(&aNewTopFrame)
: aTableCreator.CreateTableColGroupFrame(&aNewTopFrame);
@ -2154,6 +2151,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresContext* aPresCo
return NS_OK;
}
/*
NS_IMETHODIMP
nsCSSFrameConstructor::ConstructRootFrame(nsIPresContext* aPresContext,
nsIContent* aDocElement,
@ -2244,6 +2242,7 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresContext* aPresContext,
nsIFrame* scrollFrame;
nsCOMPtr<nsIStyleContext> scrollFrameStyle;
if (isScrollable) {
NS_NewScrollFrame(&scrollFrame);
aPresContext->ResolvePseudoStyleContextFor(nsnull, nsLayoutAtoms::viewportScrollPseudo,
viewportPseudoStyle, PR_FALSE,
@ -2251,6 +2250,7 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresContext* aPresContext,
scrollFrame->Init(*aPresContext, nsnull, viewportFrame, scrollFrameStyle,
nsnull);
// Inform the view manager about the root scrollable view
nsIView* scrollFrameView;
nsIScrollableView* scrollingView;
@ -2356,6 +2356,261 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresContext* aPresContext,
aNewFrame = viewportFrame;
return NS_OK;
}
*/
NS_IMETHODIMP
nsCSSFrameConstructor::ConstructRootFrame(nsIPresContext* aPresContext,
nsIContent* aDocElement,
nsIFrame*& aNewFrame)
{
#ifdef NS_DEBUG
nsCOMPtr<nsIDocument> doc;
nsIContent* rootContent;
// Verify that the content object is really the root content object
aDocElement->GetDocument(*getter_AddRefs(doc));
rootContent = doc->GetRootContent();
NS_ASSERTION(rootContent == aDocElement, "unexpected content");
NS_RELEASE(rootContent);
#endif
nsIFrame* viewportFrame;
nsCOMPtr<nsIStyleContext> viewportPseudoStyle;
// Create the viewport frame
NS_NewViewportFrame(&viewportFrame);
// Create a pseudo element style context
aPresContext->ResolvePseudoStyleContextFor(nsnull, nsLayoutAtoms::viewportPseudo,
nsnull, PR_FALSE,
getter_AddRefs(viewportPseudoStyle));
{ // ensure that the viewport thinks it is a block frame, layout goes pootsy if it doesn't
nsStyleDisplay* display = (nsStyleDisplay*)viewportPseudoStyle->GetMutableStyleData(eStyleStruct_Display);
display->mDisplay = NS_STYLE_DISPLAY_BLOCK;
}
// Initialize the viewport frame. It has a NULL content object
viewportFrame->Init(*aPresContext, nsnull, nsnull, viewportPseudoStyle, nsnull);
// Bind the viewport frame to the root view
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell));
nsCOMPtr<nsIViewManager> viewManager;
presShell->GetViewManager(getter_AddRefs(viewManager));
nsIView* rootView;
viewManager->GetRootView(rootView);
viewportFrame->SetView(rootView);
// If the device supports scrolling (e.g., in galley mode on the screen and
// for print-preview, but not when printing), then create a scroll frame that
// will act as the scrolling mechanism for the viewport.
// XXX Do we even need a viewport when printing to a printer?
// XXX It would be nice to have a better way to query for whether the device
// is scrollable
PRBool isScrollable = PR_TRUE;
if (aPresContext) {
nsIDeviceContext* dc;
aPresContext->GetDeviceContext(&dc);
if (dc) {
PRBool supportsWidgets;
if (NS_SUCCEEDED(dc->SupportsNativeWidgets(supportsWidgets))) {
isScrollable = supportsWidgets;
}
NS_RELEASE(dc);
}
}
// 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.
nsISupports* container;
if (nsnull != aPresContext) {
aPresContext->GetContainer(&container);
if (nsnull != container) {
nsIWebShell* webShell = nsnull;
container->QueryInterface(kIWebShellIID, (void**) &webShell);
if (nsnull != webShell) {
PRInt32 scrolling = -1;
webShell->GetScrolling(scrolling);
if (NS_STYLE_OVERFLOW_HIDDEN == scrolling) {
isScrollable = PR_FALSE;
}
NS_RELEASE(webShell);
}
NS_RELEASE(container);
}
}
// If the viewport should offer a scrolling mechanism, then create a
// scroll frame
nsIFrame* scrollFrame = nsnull;
nsIFrame* gfxScrollFrame = nsnull;
if (isScrollable) {
nsIFrame* parent = nsnull;
if (IsGfxMode(aPresContext)) {
NS_NewGfxScrollFrame(&gfxScrollFrame);
gfxScrollFrame->Init(*aPresContext, aDocElement, viewportFrame, viewportPseudoStyle,
nsnull);
NS_NewScrollPortFrame(&scrollFrame);
parent = gfxScrollFrame;
} else {
NS_NewScrollFrame(&scrollFrame);
parent = viewportFrame;
}
// XXX should probably be a scrolled content pseudo style context
scrollFrame->Init(*aPresContext, nsnull, parent, viewportPseudoStyle,
nsnull);
// Inform the view manager about the root scrollable view
nsIView* scrollFrameView;
nsIScrollableView* scrollingView;
scrollFrame->GetView(&scrollFrameView);
NS_ASSERTION(scrollFrameView, "scroll frame has no view");
scrollFrameView->QueryInterface(kScrollViewIID, (void**)&scrollingView);
viewManager->SetRootScrollableView(scrollingView);
}
PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated);
if (isPaginated) {
nsIFrame* pageSequenceFrame;
// Create a page sequence frame
NS_NewSimplePageSequenceFrame(&pageSequenceFrame);
// XXX should probably be a page sequence pseudo style context
pageSequenceFrame->Init(*aPresContext, nsnull, isScrollable ? scrollFrame :
viewportFrame, viewportPseudoStyle, nsnull);
if (isScrollable) {
nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, pageSequenceFrame,
viewportPseudoStyle, PR_TRUE);
}
// Create the first page
nsIFrame* pageFrame;
NS_NewPageFrame(&pageFrame);
// The page is the containing block for 'fixed' elements. which are repeated
// on every page
mFixedContainingBlock = pageFrame;
// Initialize the page and force it to have a view. This makes printing of
// the pages easier and faster.
// XXX Use a PAGE style context...
nsCOMPtr<nsIStyleContext> pagePseudoStyle;
aPresContext->ResolvePseudoStyleContextFor(nsnull, nsLayoutAtoms::pagePseudo,
viewportPseudoStyle, PR_FALSE,
getter_AddRefs(pagePseudoStyle));
pageFrame->Init(*aPresContext, nsnull, pageSequenceFrame, pagePseudoStyle,
nsnull);
nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, pageFrame,
pagePseudoStyle, PR_TRUE);
// The eventual parent of the document element frame
mDocElementContainingBlock = pageFrame;
// Set the initial child lists
pageSequenceFrame->SetInitialChildList(*aPresContext, nsnull, pageFrame);
if (isScrollable) {
scrollFrame->SetInitialChildList(*aPresContext, nsnull, pageSequenceFrame);
if (IsGfxMode(aPresContext)) {
nsFrameConstructorState state(aPresContext,
nsnull,
nsnull,
nsnull);
nsFrameItems children;
children.AddChild(scrollFrame);
// if there are any anonymous children for the nsScrollFrame create frames for them.
// for now make say its tag is "input". This is a hack to make sure we check for the anonymous interface
CreateAnonymousFrames(aPresContext, nsHTMLAtoms::input, state, aDocElement, gfxScrollFrame,
children);
//viewportFrame->SetInitialChildList(*aPresContext, nsnull, scrollFrame);
viewportFrame->SetInitialChildList(*aPresContext, nsnull, gfxScrollFrame);
gfxScrollFrame->SetInitialChildList(*aPresContext, nsnull, children.childList);
} else
viewportFrame->SetInitialChildList(*aPresContext, nsnull, scrollFrame);
} else {
viewportFrame->SetInitialChildList(*aPresContext, nsnull, pageSequenceFrame);
}
} else {
// The viewport is the containing block for 'fixed' elements
mFixedContainingBlock = viewportFrame;
// Create the root frame. The document element's frame is a child of the
// root frame.
//
// The root frame serves two purposes:
// - reserves space for any margins needed for the document element's frame
// - makes sure that the document element's frame covers the entire canvas
nsIFrame* rootFrame;
NS_NewRootFrame(&rootFrame);
// XXX this should be a root pseudo style context
rootFrame->Init(*aPresContext, nsnull, isScrollable ? scrollFrame :
viewportFrame, viewportPseudoStyle, nsnull);
if (isScrollable) {
nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, rootFrame,
viewportPseudoStyle, PR_TRUE);
}
// The eventual parent of the document element frame
mDocElementContainingBlock = rootFrame;
// Set the initial child lists
if (isScrollable) {
scrollFrame->SetInitialChildList(*aPresContext, nsnull, rootFrame);
if (IsGfxMode(aPresContext)) {
nsFrameConstructorState state(aPresContext,
nsnull,
nsnull,
nsnull);
nsFrameItems children;
children.AddChild(scrollFrame);
// if there are any anonymous children for the nsScrollFrame create frames for them.
// for now make say its tag is "input". This is a hack to make sure we check for the anonymous interface
CreateAnonymousFrames(aPresContext, nsHTMLAtoms::input, state, aDocElement, gfxScrollFrame,
children);
// viewportFrame->SetInitialChildList(*aPresContext, nsnull, scrollFrame);
viewportFrame->SetInitialChildList(*aPresContext, nsnull, gfxScrollFrame);
gfxScrollFrame->SetInitialChildList(*aPresContext, nsnull, children.childList);
} else
viewportFrame->SetInitialChildList(*aPresContext, nsnull, scrollFrame);
} else {
viewportFrame->SetInitialChildList(*aPresContext, nsnull, rootFrame);
}
}
aNewFrame = viewportFrame;
return NS_OK;
}
nsresult
nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresContext* aPresContext,
@ -2573,6 +2828,18 @@ nsCSSFrameConstructor::ConstructTextControlFrame(nsIPresContext* aPresC
return rv;
}
PRBool
nsCSSFrameConstructor::IsGfxMode(nsIPresContext* aPresContext)
{
return PR_FALSE;
/*
nsWidgetRendering mode;
aPresContext->GetWidgetRenderingMode(&mode);
return (eWidgetRendering_Gfx == mode);
*/
}
nsresult
nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
@ -2645,8 +2912,13 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContex
// Initialize the scroll frame positioned. Note that it is NOT initialized as
// absolutely positioned.
nsIFrame* newFrame = nsnull;
InitializeScrollFrame(aPresContext, aState, listFrame, aContent, comboboxFrame,
listStyle, newFrame, PR_FALSE, PR_FALSE, PR_TRUE);
nsIFrame* scrolledFrame = nsnull;
NS_NewAreaFrame(&scrolledFrame, NS_BLOCK_SHRINK_WRAP);
InitializeScrollFrame(aPresContext, aState, listFrame, scrolledFrame, aContent, comboboxFrame,
listStyle, PR_TRUE, PR_FALSE, PR_FALSE, PR_TRUE);
newFrame = listFrame;
// Set flag so the events go to the listFrame not child frames.
// XXX: We should replace this with a real widget manager similar
@ -2684,10 +2956,15 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContex
nsIFrame * listFrame;
rv = NS_NewListControlFrame(&listFrame);
aNewFrame = listFrame;
InitializeScrollFrame(aPresContext, aState, listFrame, aContent, aParentFrame,
aStyleContext, aNewFrame, aIsAbsolutelyPositioned, PR_FALSE,
nsIFrame* scrolledFrame = nsnull;
NS_NewAreaFrame(&scrolledFrame, NS_BLOCK_SHRINK_WRAP);
InitializeScrollFrame(aPresContext, aState, listFrame, scrolledFrame, aContent, aParentFrame,
aStyleContext, aIsAbsolutelyPositioned, PR_TRUE, PR_FALSE,
PR_TRUE);
aNewFrame = listFrame;
// Set flag so the events go to the listFrame not child frames.
// XXX: We should replace this with a real widget manager similar
// to how the nsFormControlFrame works.
@ -3226,18 +3503,15 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext,
isFixedPositioned = PR_TRUE;
}
// Create a scroll frame
nsIFrame* scrollFrame;
NS_NewScrollFrame(&scrollFrame);
// Initialize it
InitializeScrollFrame(aPresContext, aState, scrollFrame, aContent, aParentFrame,
aStyleContext, newFrame, isAbsolutelyPositioned, isFixedPositioned,
// Build it
BuildBoxScrollFrame(aPresContext, aState, aContent, aParentFrame,
aStyleContext, newFrame, PR_TRUE, isAbsolutelyPositioned, isFixedPositioned,
PR_FALSE);
frameHasBeenInitialized = PR_TRUE;
}
}
// End of BOX CONSTRUCTION logic
} // End of BOX CONSTRUCTION logic
// TITLED BUTTON CONSTRUCTION
else if (aTag == nsXULAtoms::titledbutton) {
@ -3292,7 +3566,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext,
else if (aTag == nsXULAtoms::thumb) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewTitledButtonFrame(&newFrame);
rv = NS_NewThumbFrame(&newFrame);
}
// End of THUMB CONSTRUCTION logic
@ -3384,14 +3658,146 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext,
}
#endif
/**
* Create a scroll frame whose scrolled content needs a block frame
*/
nsresult
nsCSSFrameConstructor::InitializeScrollFrame(nsIPresContext* aPresContext,
nsCSSFrameConstructor::BuildBlockScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock)
{
// Create an area container for the frame
nsIFrame* scrolledFrame;
NS_NewAreaFrame(&scrolledFrame, NS_BLOCK_SHRINK_WRAP);
nsresult rv = BuildScrollFrame(aPresContext, aState, aContent, scrolledFrame, aParentFrame,
aStyleContext, aNewFrame, aProcessChildren, aIsAbsolutelyPositioned, aIsFixedPositioned,
aCreateBlock);
return rv;
}
/**
* Create a scroll frame whose scrolled content needs a box frame
*/
nsresult
nsCSSFrameConstructor::BuildBoxScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock)
{
// Create an area container for the frame
nsIFrame* scrolledFrame;
NS_NewBoxFrame(&scrolledFrame);
nsresult rv = BuildScrollFrame(aPresContext, aState, aContent, scrolledFrame, aParentFrame,
aStyleContext, aNewFrame, aProcessChildren, aIsAbsolutelyPositioned, aIsFixedPositioned,
aCreateBlock);
return rv;
}
/**
* Create a new scroll frame. Populate it and return it.
*/
nsresult
nsCSSFrameConstructor::BuildScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aScrolledFrame,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock)
{
nsIFrame* scrollFrame = nsnull;
nsIFrame* gfxScrollFrame = nsnull;
nsFrameItems anonymousItems;
if (IsGfxMode(aPresContext)) {
// if gfx we need to make a special scrollframe
// create the frames
nsresult rv = BuildGfxScrollFrame(aPresContext, aState, aContent, aParentFrame,
aStyleContext, gfxScrollFrame, anonymousItems);
// get the scrollframe from the anonymous list
scrollFrame = anonymousItems.childList;
aParentFrame = gfxScrollFrame;
aNewFrame = gfxScrollFrame;
} else {
NS_NewScrollFrame(&scrollFrame);
aNewFrame = scrollFrame;
}
// Initialize it
nsresult rv = InitializeScrollFrame(aPresContext, aState, scrollFrame, aScrolledFrame, aContent, aParentFrame,
aStyleContext, aProcessChildren, aIsAbsolutelyPositioned, aIsFixedPositioned,
aCreateBlock);
if (IsGfxMode(aPresContext))
gfxScrollFrame->SetInitialChildList(*aPresContext, nsnull, anonymousItems.childList);
return rv;
}
nsresult
nsCSSFrameConstructor::BuildGfxScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIFrame* scrollFrame,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
nsFrameItems& aAnonymousFrames)
{
NS_NewGfxScrollFrame(&aNewFrame);
aNewFrame->Init(*aPresContext, aContent, aParentFrame, aStyleContext,
nsnull);
nsIFrame* scrollbox = nsnull;
NS_NewScrollPortFrame(&scrollbox);
aAnonymousFrames.AddChild(scrollbox);
// if there are any anonymous children for the nsScrollFrame create frames for them.
// for now make say its tag is "input". This is a hack to make sure we check for the anonymous interface
CreateAnonymousFrames(aPresContext, nsHTMLAtoms::input, aState, aContent, aNewFrame,
aAnonymousFrames);
return NS_OK;
}
nsresult
nsCSSFrameConstructor::InitializeScrollFrame(nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIFrame* scrollFrame,
nsIFrame* scrolledFrame,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock)
@ -3404,8 +3810,6 @@ nsCSSFrameConstructor::InitializeScrollFrame(nsIPresContext* aPresConte
} else if (aIsFixedPositioned) {
geometricParent = aState.mFixedItems.containingBlock;
}
scrollFrame->Init(*aPresContext, aContent, geometricParent, aStyleContext,
nsnull);
// The scroll frame gets the original style context, and the scrolled
// frame gets a SCROLLED-CONTENT pseudo element style context that
@ -3416,10 +3820,13 @@ nsCSSFrameConstructor::InitializeScrollFrame(nsIPresContext* aPresConte
aStyleContext, PR_FALSE,
getter_AddRefs(scrolledPseudoStyle));
// Create an area container for the frame
nsIFrame* scrolledFrame;
NS_NewAreaFrame(&scrolledFrame, NS_BLOCK_SHRINK_WRAP);
if (IsGfxMode(aPresContext)) {
scrollFrame->Init(*aPresContext, aContent, geometricParent, scrolledPseudoStyle,
nsnull);
} else {
scrollFrame->Init(*aPresContext, aContent, geometricParent, aStyleContext,
nsnull);
}
// Initialize the frame and force it to have a view
scrolledFrame->Init(*aPresContext, aContent, scrollFrame,
scrolledPseudoStyle, nsnull);
@ -3475,6 +3882,7 @@ nsCSSFrameConstructor::InitializeScrollFrame(nsIPresContext* aPresConte
nsLayoutAtoms::absoluteList,
aState.mAbsoluteItems.childList);
}
if (aState.mFloatedItems.childList) {
scrolledFrame->SetInitialChildList(*aPresContext,
nsLayoutAtoms::floaterList,
@ -3483,7 +3891,6 @@ nsCSSFrameConstructor::InitializeScrollFrame(nsIPresContext* aPresConte
// Set the scroll frame's initial child list
scrollFrame->SetInitialChildList(*aPresContext, nsnull, scrolledFrame);
aNewFrame = scrollFrame;
return NS_OK;
}
@ -3535,13 +3942,9 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPre
isFixedPositioned = PR_TRUE;
}
// Create a scroll frame
nsIFrame* scrollFrame;
NS_NewScrollFrame(&scrollFrame);
// Initialize it
InitializeScrollFrame(aPresContext, aState, scrollFrame, aContent, aParentFrame,
aStyleContext, newFrame, isAbsolutelyPositioned, isFixedPositioned,
// Build the scrollframe it
BuildBlockScrollFrame(aPresContext, aState, aContent, aParentFrame,
aStyleContext, newFrame, PR_TRUE, isAbsolutelyPositioned, isFixedPositioned,
PR_FALSE);
}
// See if the frame is absolute or fixed positioned

View File

@ -516,16 +516,67 @@ protected:
nsIFrame* GetFloaterContainingBlock(nsIPresContext* aPresContext,
nsIFrame* aFrame);
nsresult InitializeScrollFrame(nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIFrame* aScrollFrame,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock);
nsresult BuildBlockScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock);
nsresult BuildBoxScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock);
nsresult
BuildScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aScrolledFrame,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock);
nsresult
BuildGfxScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
nsFrameItems& aAnonymousFrames);
nsresult
InitializeScrollFrame(nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIFrame* scrollFrame,
nsIFrame* scrolledFrame,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock);
PRBool IsGfxMode(nsIPresContext* aPresContext);
nsresult RecreateFramesForContent(nsIPresContext* aPresContext,
nsIContent* aContent);

View File

@ -42,3 +42,4 @@ nsIStyleSheet.h
nsIStyleSheetLinkingElement.h
nsITextContent.h
nsTextFragment.h
nsIAnonymousContent.h

View File

@ -0,0 +1,42 @@
/* -*- 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIAnonymousContent_h___
#define nsIAnonymousContent_h___
#include "nsISupports.h"
#include "nsIContent.h"
#include "nsCOMPtr.h"
class nsISupportsArray;
class nsIAtom;
#define NS_IANONYMOUS_CONTENT_IID { 0x41a69e00, 0x2d6d, 0x12d3, { 0xb0, 0x33, 0xa1, 0x38, 0x71, 0x39, 0x78, 0x7c } }
/**
* If a node is anonymous. Then it should implement this interface.
*/
class nsIAnonymousContent : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IANONYMOUS_CONTENT_IID; return iid; }
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,255 @@
/* -*- 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.0 (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.
*/
#ifndef nsScrollFrame_h___
#define nsScrollFrame_h___
#include "nsHTMLContainerFrame.h"
#include "nsIAnonymousContentCreator.h"
#include "nsIDocumentObserver.h"
class nsISupportsArray;
/**
* The scroll frame creates and manages the scrolling view
*
* It only supports having a single child frame that typically is an area
* frame, but doesn't have to be. The child frame must have a view, though
*
* Scroll frames don't support incremental changes, i.e. you can't replace
* or remove the scrolled frame
*/
class nsGfxScrollFrame : public nsHTMLContainerFrame,
nsIAnonymousContentCreator,
nsIDocumentObserver {
public:
friend nsresult NS_NewGfxScrollFrame(nsIFrame** aNewFrame);
NS_IMETHOD Init(nsIPresContext& aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
// 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
NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList);
// Because there can be only one child frame, these two function return
// NS_ERROR_FAILURE
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 Destroy(nsIPresContext& aPresContext);
// This function returns NS_ERROR_NOT_IMPLEMENTED
NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext,
nsIPresShell& aPresShell,
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);
// added for anonymous content support
NS_IMETHOD CreateAnonymousContent(nsISupportsArray& aAnonymousItems);
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_IMETHOD_(nsrefcnt) AddRef(void) { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release(void) { return NS_OK; }
/**
* Get the "type" of the frame
*
* @see nsLayoutAtoms::scrollFrame
*/
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
NS_IMETHOD GetFrameName(nsString& aResult) const;
// nsIDocumentObserver
NS_IMETHOD BeginUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginReflow(nsIDocument *aDocument,
nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD EndReflow(nsIDocument *aDocument,
nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD ContentChanged(nsIDocument* aDoc,
nsIContent* aContent,
nsISupports* aSubContent) { return NS_OK; }
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
nsIContent* aContent1,
nsIContent* aContent2) { return NS_OK; }
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer) { return NS_OK; }
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) { return NS_OK; }
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
PRBool aDisabled) { return NS_OK; }
NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule,
PRInt32 aHint) { return NS_OK; }
NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) { return NS_OK; }
NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) { return NS_OK; }
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument) { return NS_OK; }
protected:
nsGfxScrollFrame();
virtual PRIntn GetSkipSides() const;
virtual void ScrollbarChanged(nscoord aX, nscoord aY);
private:
void SetAttribute(nsIFrame* aFrame, nsIAtom* aAtom, nscoord aSize);
nsresult CalculateChildTotalSize(nsIFrame* aKidFrame,
nsHTMLReflowMetrics& aKidReflowMetrics);
nsresult GetFrameSize( nsIFrame* aFrame,
nsSize& aSize);
nsresult SetFrameSize( nsIFrame* aFrame,
nsSize aSize);
nsresult CalculateScrollAreaSize(nsIPresContext& aPresContext,
const nsHTMLReflowState& aReflowState,
const nsSize& aSbSize,
nsSize& aScrollAreaSize);
void SetScrollbarVisibility(nsIFrame* aScrollbar, PRBool aVisible);
void DetermineReflowNeed(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
PRBool& aHscrollbarNeedsReflow,
PRBool& aVscrollbarNeedsReflow,
PRBool& aScrollAreaNeedsReflow,
nsIFrame*& aIncrementalChild);
void ReflowScrollbars( nsIPresContext& aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
PRBool& aHscrollbarNeedsReflow,
PRBool& aVscrollbarNeedsReflow,
PRBool& aScrollBarResized,
nsIFrame*& aIncrementalChild);
void ReflowScrollbar( nsIPresContext& aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
PRBool& aScrollBarResized,
nsIFrame* aScrollBarFrame,
nsIFrame*& aIncrementalChild);
nsresult ReflowFrame( nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
nsIFrame* aFrame,
const nsSize& aAvailable,
const nsSize& aComputed,
PRBool& aResized,
nsIFrame*& aIncrementalChild);
void ReflowScrollArea( nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
PRBool& aHscrollbarNeedsReflow,
PRBool& aVscrollbarNeedsReflow,
PRBool& aScrollAreaNeedsReflow,
nsIFrame*& aIncrementalChild);
void LayoutChildren(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState);
void GetScrollbarDimensions(nsIPresContext& aPresContext,
nsSize& aSbSize);
void AddRemoveScrollbar (PRBool& aHasScrollbar, nscoord& aSize, nscoord aSbSize, PRBool aAdd);
void AddHorizontalScrollbar (const nsSize& aSbSize, nsSize& aScrollAreaSize);
void AddVerticalScrollbar (const nsSize& aSbSize, nsSize& aScrollAreaSize);
void RemoveHorizontalScrollbar(const nsSize& aSbSize, nsSize& aScrollAreaSize);
void RemoveVerticalScrollbar (const nsSize& aSbSize, nsSize& aScrollAreaSize);
nsIScrollableView* GetScrollableView();
void GetScrolledContentSize(nsSize& aSize);
nsIFrame* mHScrollbarFrame;
nsIFrame* mVScrollbarFrame;
nsIFrame* mScrollAreaFrame;
PRBool mHasVerticalScrollbar;
PRBool mHasHorizontalScrollbar;
nscoord mOnePixel;
};
#endif /* nsScrollFrame_h___ */

View File

@ -21,7 +21,12 @@
#define nsIAnonymousContentCreator_h___
#include "nsISupports.h"
#include "nsIContent.h"
#include "nsCOMPtr.h"
class nsISupportsArray;
class nsIAtom;
// {41a69e00-2d6d-11d3-b033-a1357139787c}
#define NS_IANONYMOUS_CONTENT_CREATOR_IID { 0x41a69e00, 0x2d6d, 0x11d3, { 0xb0, 0x33, 0xa1, 0x35, 0x71, 0x39, 0x78, 0x7c } }
@ -38,6 +43,8 @@ public:
NS_IMETHOD CreateAnonymousContent(nsISupportsArray& aAnonymousItems)=0;
};
nsresult NS_CreateAnonymousNode(nsIContent* aParent, nsIAtom* aTag, PRInt32 aNameSpaceId, nsCOMPtr<nsIContent>& aNewNode);
#endif

View File

@ -63,6 +63,8 @@ CPPSRCS= \
nsTextFrame.cpp \
nsTextTransformer.cpp \
nsViewportFrame.cpp \
nsGfxScrollFrame.cpp \
nsScrollPortFrame.cpp \
$(NULL)
EXPORTS = \
@ -81,7 +83,7 @@ include $(topsrcdir)/config/config.mk
DEFINES += -D_IMPL_NS_HTML
INCLUDES += -I$(srcdir)/../../style/src -I$(srcdir)/../../content/src -I$(srcdir)/../../../base/src -I$(srcdir)/. -I$(DIST)/oji
INCLUDES += -I$(srcdir)/../../../xul/base/src -I$(srcdir)/../../../xul/content/src -I$(srcdir)/../../style/src -I$(srcdir)/../../content/src -I$(srcdir)/../../../base/src -I$(srcdir)/. -I$(DIST)/oji
MKSHLIB :=

View File

@ -32,6 +32,8 @@ EXPORTS = \
$(NULL)
CPPSRCS= \
nsScrollPortFrame.cpp \
nsGfxScrollFrame.cpp \
nsAbsoluteContainingBlock.cpp \
nsAreaFrame.cpp \
nsBRFrame.cpp \
@ -72,6 +74,8 @@ CPPSRCS= \
$(NULL)
CPP_OBJS= \
.\$(OBJDIR)\nsScrollPortFrame.obj \
.\$(OBJDIR)\nsGfxScrollFrame.obj \
.\$(OBJDIR)\nsAbsoluteContainingBlock.obj \
.\$(OBJDIR)\nsAreaFrame.obj \
.\$(OBJDIR)\nsBRFrame.obj \
@ -119,7 +123,9 @@ LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I$(PUBLIC)\js \
-I$(PUBLIC)\pref \
-I$(PUBLIC)\lwbrk \
-I$(PUBLIC)\unicharutil \
-I$(PUBLIC)\oji
-I$(PUBLIC)\oji \
-I..\..\..\xul\content\src \
-I..\..\..\xul\base\src \
LCFLAGS = \
$(LCFLAGS) \

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,255 @@
/* -*- 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.0 (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.
*/
#ifndef nsScrollFrame_h___
#define nsScrollFrame_h___
#include "nsHTMLContainerFrame.h"
#include "nsIAnonymousContentCreator.h"
#include "nsIDocumentObserver.h"
class nsISupportsArray;
/**
* The scroll frame creates and manages the scrolling view
*
* It only supports having a single child frame that typically is an area
* frame, but doesn't have to be. The child frame must have a view, though
*
* Scroll frames don't support incremental changes, i.e. you can't replace
* or remove the scrolled frame
*/
class nsGfxScrollFrame : public nsHTMLContainerFrame,
nsIAnonymousContentCreator,
nsIDocumentObserver {
public:
friend nsresult NS_NewGfxScrollFrame(nsIFrame** aNewFrame);
NS_IMETHOD Init(nsIPresContext& aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
// 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
NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList);
// Because there can be only one child frame, these two function return
// NS_ERROR_FAILURE
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 Destroy(nsIPresContext& aPresContext);
// This function returns NS_ERROR_NOT_IMPLEMENTED
NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext,
nsIPresShell& aPresShell,
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);
// added for anonymous content support
NS_IMETHOD CreateAnonymousContent(nsISupportsArray& aAnonymousItems);
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_IMETHOD_(nsrefcnt) AddRef(void) { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release(void) { return NS_OK; }
/**
* Get the "type" of the frame
*
* @see nsLayoutAtoms::scrollFrame
*/
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
NS_IMETHOD GetFrameName(nsString& aResult) const;
// nsIDocumentObserver
NS_IMETHOD BeginUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginReflow(nsIDocument *aDocument,
nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD EndReflow(nsIDocument *aDocument,
nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD ContentChanged(nsIDocument* aDoc,
nsIContent* aContent,
nsISupports* aSubContent) { return NS_OK; }
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
nsIContent* aContent1,
nsIContent* aContent2) { return NS_OK; }
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer) { return NS_OK; }
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer) { return NS_OK; }
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
PRBool aDisabled) { return NS_OK; }
NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule,
PRInt32 aHint) { return NS_OK; }
NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) { return NS_OK; }
NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) { return NS_OK; }
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument) { return NS_OK; }
protected:
nsGfxScrollFrame();
virtual PRIntn GetSkipSides() const;
virtual void ScrollbarChanged(nscoord aX, nscoord aY);
private:
void SetAttribute(nsIFrame* aFrame, nsIAtom* aAtom, nscoord aSize);
nsresult CalculateChildTotalSize(nsIFrame* aKidFrame,
nsHTMLReflowMetrics& aKidReflowMetrics);
nsresult GetFrameSize( nsIFrame* aFrame,
nsSize& aSize);
nsresult SetFrameSize( nsIFrame* aFrame,
nsSize aSize);
nsresult CalculateScrollAreaSize(nsIPresContext& aPresContext,
const nsHTMLReflowState& aReflowState,
const nsSize& aSbSize,
nsSize& aScrollAreaSize);
void SetScrollbarVisibility(nsIFrame* aScrollbar, PRBool aVisible);
void DetermineReflowNeed(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
PRBool& aHscrollbarNeedsReflow,
PRBool& aVscrollbarNeedsReflow,
PRBool& aScrollAreaNeedsReflow,
nsIFrame*& aIncrementalChild);
void ReflowScrollbars( nsIPresContext& aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
PRBool& aHscrollbarNeedsReflow,
PRBool& aVscrollbarNeedsReflow,
PRBool& aScrollBarResized,
nsIFrame*& aIncrementalChild);
void ReflowScrollbar( nsIPresContext& aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
PRBool& aScrollBarResized,
nsIFrame* aScrollBarFrame,
nsIFrame*& aIncrementalChild);
nsresult ReflowFrame( nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
nsIFrame* aFrame,
const nsSize& aAvailable,
const nsSize& aComputed,
PRBool& aResized,
nsIFrame*& aIncrementalChild);
void ReflowScrollArea( nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
PRBool& aHscrollbarNeedsReflow,
PRBool& aVscrollbarNeedsReflow,
PRBool& aScrollAreaNeedsReflow,
nsIFrame*& aIncrementalChild);
void LayoutChildren(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState);
void GetScrollbarDimensions(nsIPresContext& aPresContext,
nsSize& aSbSize);
void AddRemoveScrollbar (PRBool& aHasScrollbar, nscoord& aSize, nscoord aSbSize, PRBool aAdd);
void AddHorizontalScrollbar (const nsSize& aSbSize, nsSize& aScrollAreaSize);
void AddVerticalScrollbar (const nsSize& aSbSize, nsSize& aScrollAreaSize);
void RemoveHorizontalScrollbar(const nsSize& aSbSize, nsSize& aScrollAreaSize);
void RemoveVerticalScrollbar (const nsSize& aSbSize, nsSize& aScrollAreaSize);
nsIScrollableView* GetScrollableView();
void GetScrolledContentSize(nsSize& aSize);
nsIFrame* mHScrollbarFrame;
nsIFrame* mVScrollbarFrame;
nsIFrame* mScrollAreaFrame;
PRBool mHasVerticalScrollbar;
PRBool mHasHorizontalScrollbar;
nscoord mOnePixel;
};
#endif /* nsScrollFrame_h___ */

View File

@ -21,7 +21,12 @@
#define nsIAnonymousContentCreator_h___
#include "nsISupports.h"
#include "nsIContent.h"
#include "nsCOMPtr.h"
class nsISupportsArray;
class nsIAtom;
// {41a69e00-2d6d-11d3-b033-a1357139787c}
#define NS_IANONYMOUS_CONTENT_CREATOR_IID { 0x41a69e00, 0x2d6d, 0x11d3, { 0xb0, 0x33, 0xa1, 0x35, 0x71, 0x39, 0x78, 0x7c } }
@ -38,6 +43,8 @@ public:
NS_IMETHOD CreateAnonymousContent(nsISupportsArray& aAnonymousItems)=0;
};
nsresult NS_CreateAnonymousNode(nsIContent* aParent, nsIAtom* aTag, PRInt32 aNameSpaceId, nsCOMPtr<nsIContent>& aNewNode);
#endif

View File

@ -0,0 +1,588 @@
/* -*- 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsCOMPtr.h"
#include "nsHTMLParts.h"
#include "nsIPresContext.h"
#include "nsIStyleContext.h"
#include "nsIReflowCommand.h"
#include "nsIDeviceContext.h"
#include "nsPageFrame.h"
#include "nsViewsCID.h"
#include "nsIView.h"
#include "nsIViewManager.h"
#include "nsHTMLContainerFrame.h"
#include "nsHTMLIIDs.h"
#include "nsCSSRendering.h"
#include "nsIScrollableView.h"
#include "nsWidgetsCID.h"
#include "nsIAreaFrame.h"
#include "nsScrollPortFrame.h"
#include "nsLayoutAtoms.h"
#include "nsIWebShell.h"
#include "nsIBox.h"
static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID);
static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID);
static NS_DEFINE_IID(kScrollingViewCID, NS_SCROLLING_VIEW_CID);
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID);
//----------------------------------------------------------------------
nsresult
NS_NewScrollPortFrame(nsIFrame** aNewFrame)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsScrollPortFrame* it = new nsScrollPortFrame;
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aNewFrame = it;
return NS_OK;
}
nsScrollPortFrame::nsScrollPortFrame()
{
}
NS_IMETHODIMP
nsScrollPortFrame::Init(nsIPresContext& aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aStyleContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsHTMLContainerFrame::Init(aPresContext, aContent,
aParent, aStyleContext,
aPrevInFlow);
// Create the scrolling view
CreateScrollingView(aPresContext);
return rv;
}
NS_IMETHODIMP
nsScrollPortFrame::SetInitialChildList(nsIPresContext& aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
nsresult rv = nsHTMLContainerFrame::SetInitialChildList(aPresContext, aListName,
aChildList);
nsIFrame* frame = mFrames.FirstChild();
// There must be one and only one child frame
if (!frame) {
return NS_ERROR_INVALID_ARG;
} else if (mFrames.GetLength() > 1) {
return NS_ERROR_UNEXPECTED;
}
#ifdef NS_DEBUG
// Verify that the scrolled frame has a view
nsIView* scrolledView;
frame->GetView(&scrolledView);
NS_ASSERTION(nsnull != scrolledView, "no view");
#endif
// We need to allow the view's position to be different than the
// frame's position
nsFrameState state;
frame->GetFrameState(&state);
state &= ~NS_FRAME_SYNC_FRAME_AND_VIEW;
frame->SetFrameState(state);
return rv;
}
NS_IMETHODIMP
nsScrollPortFrame::AppendFrames(nsIPresContext& aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aFrameList)
{
// Only one child frame allowed
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsScrollPortFrame::InsertFrames(nsIPresContext& aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList)
{
// Only one child frame allowed
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsScrollPortFrame::RemoveFrame(nsIPresContext& aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aOldFrame)
{
// Scroll frame doesn't support incremental changes
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);
// Send the DidReflow notification to the scrolled frame's view
nsIFrame* frame = mFrames.FirstChild();
nsIHTMLReflow* htmlReflow;
frame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow);
htmlReflow->DidReflow(aPresContext, aStatus);
// Size the scrolled frame's view. Leave its position alone
nsSize size;
nsRect bounds;
nsIViewManager* vm;
nsIView* scrolledView;
frame->GetSize(size);
frame->GetView(&scrolledView);
scrolledView->GetBounds(bounds);
// only resize the view if things changed.
if (bounds.width != size.width || bounds.height != size.height) {
scrolledView->GetViewManager(vm);
vm->ResizeView(scrolledView, size.width, size.height);
NS_RELEASE(vm);
// Have the scrolling view layout
nsIScrollableView* scrollingView;
nsIView* view;
GetView(&view);
if (NS_SUCCEEDED(view->QueryInterface(kScrollViewIID, (void**)&scrollingView))) {
scrollingView->ComputeScrollOffsets(PR_TRUE);
}
}
}
return rv;
}
nsresult
nsScrollPortFrame::CreateScrollingViewWidget(nsIView* aView, const nsStylePosition* aPosition)
{
nsresult rv = NS_OK;
// If it's fixed positioned, then create a widget
if (NS_STYLE_POSITION_FIXED == aPosition->mPosition) {
rv = aView->CreateWidget(kWidgetCID);
}
return(rv);
}
nsresult
nsScrollPortFrame::GetScrollingParentView(nsIFrame* aParent, nsIView** aParentView)
{
nsresult rv = aParent->GetView(aParentView);
NS_ASSERTION(aParentView, "GetParentWithView failed");
return(rv);
}
nsresult
nsScrollPortFrame::CreateScrollingView(nsIPresContext& aPresContext)
{
nsIView* view;
//Get parent frame
nsIFrame* parent;
GetParentWithView(&parent);
NS_ASSERTION(parent, "GetParentWithView failed");
// Get parent view
nsIView* parentView = nsnull;
GetScrollingParentView(parent, &parentView);
// Get the view manager
nsIViewManager* viewManager;
parentView->GetViewManager(viewManager);
// Create the scrolling view
nsresult rv = nsComponentManager::CreateInstance(kScrollingViewCID,
nsnull,
kIViewIID,
(void **)&view);
if (NS_OK == rv) {
const nsStylePosition* position = (const nsStylePosition*)
mStyleContext->GetStyleData(eStyleStruct_Position);
const nsStyleColor* color = (const nsStyleColor*)
mStyleContext->GetStyleData(eStyleStruct_Color);
const nsStyleSpacing* spacing = (const nsStyleSpacing*)
mStyleContext->GetStyleData(eStyleStruct_Spacing);
const nsStyleDisplay* display = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
// Get the z-index
PRInt32 zIndex = 0;
if (eStyleUnit_Integer == position->mZIndex.GetUnit()) {
zIndex = position->mZIndex.GetIntValue();
}
// Initialize the scrolling view
view->Init(viewManager, mRect, parentView, nsnull, display->mVisible ?
nsViewVisibility_kShow : nsViewVisibility_kHide);
// Insert the view into the view hierarchy
viewManager->InsertChild(parentView, view, zIndex);
// Set the view's opacity
viewManager->SetViewOpacity(view, color->mOpacity);
// Because we only paint the border and we don't paint a background,
// inform the view manager that we have transparent content
viewManager->SetViewContentTransparency(view, PR_TRUE);
// If it's fixed positioned, then create a widget too
CreateScrollingViewWidget(view, position);
// Get the nsIScrollableView interface
nsIScrollableView* scrollingView;
view->QueryInterface(kScrollViewIID, (void**)&scrollingView);
scrollingView->SetScrollPreference(nsScrollPreference_kNeverScroll);
// Have the scrolling view create its internal widgets
scrollingView->CreateScrollControls();
// Set the scrolling view's insets to whatever our border is
nsMargin border;
if (!spacing->GetBorder(border)) {
NS_NOTYETIMPLEMENTED("percentage border");
border.SizeTo(0, 0, 0, 0);
}
scrollingView->SetControlInsets(border);
// Remember our view
SetView(view);
}
NS_RELEASE(viewManager);
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)
{
// 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.mCombinedArea.width;
aKidReflowMetrics.height = aKidReflowMetrics.mCombinedArea.height;
}
// If it's an area frame, then get the total size which includes the
// space taken up by absolutely positioned child elements
nsIAreaFrame* areaFrame;
if (NS_SUCCEEDED(aKidFrame->QueryInterface(kAreaFrameIID, (void**)&areaFrame))) {
nscoord xMost, yMost;
areaFrame->GetPositionedInfo(xMost, yMost);
if (xMost > aKidReflowMetrics.width) {
aKidReflowMetrics.width = xMost;
}
if (yMost > aKidReflowMetrics.height) {
aKidReflowMetrics.height = yMost;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsScrollPortFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
NS_FRAME_TRACE_MSG(NS_FRAME_TRACE_CALLS,
("enter nsScrollPortFrame::Reflow: maxSize=%d,%d",
aReflowState.availableWidth,
aReflowState.availableHeight));
nsIFrame* kidFrame = mFrames.FirstChild();
nsIFrame* targetFrame;
nsIFrame* nextFrame;
// Special handling for incremental reflow
if (eReflowReason_Incremental == aReflowState.reason) {
// See whether we're the target of the reflow command
aReflowState.reflowCommand->GetTarget(targetFrame);
if (this == targetFrame) {
nsIReflowCommand::ReflowType type;
// The only type of reflow command we expect to get is a style
// change reflow command
aReflowState.reflowCommand->GetType(type);
NS_ASSERTION(nsIReflowCommand::StyleChanged == type, "unexpected reflow type");
// Make a copy of the reflow state (with a different reflow reason) and
// then recurse
nsHTMLReflowState reflowState(aReflowState);
reflowState.reason = eReflowReason_StyleChange;
reflowState.reflowCommand = nsnull;
return Reflow(aPresContext, aDesiredSize, reflowState, aStatus);
}
// Get the next frame in the reflow chain, and verify that it's our
// child frame
aReflowState.reflowCommand->GetNext(nextFrame);
NS_ASSERTION(nextFrame == kidFrame, "unexpected reflow command next-frame");
}
// Reflow the child and get its desired size. Let it be as high as it
// wants
nscoord theHeight;
nsIBox* box;
nsresult result = kidFrame->QueryInterface(kIBoxIID, (void**)&box);
if (NS_SUCCEEDED(result))
theHeight = aReflowState.mComputedHeight;
else
theHeight = NS_INTRINSICSIZE;
nsSize kidReflowSize(aReflowState.availableWidth, theHeight);
nsHTMLReflowState kidReflowState(aPresContext, aReflowState,
kidFrame, kidReflowSize);
nsHTMLReflowMetrics kidDesiredSize(aDesiredSize.maxElementSize);
/*
if (mIncremental) {
kidReflowState.reason = eReflowReason_Incremental;
mIncremental = PR_FALSE;
}
*/
kidReflowState.mComputedWidth = aReflowState.mComputedWidth;
// if the computed width is not intrinsic make sure we subtract out the child's borders.
// if (kidReflowState.mComputedWidth != NS_INTRINSICSIZE)
// kidReflowState.mComputedWidth -= aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right;
kidReflowState.mComputedHeight = theHeight;
//if (kidReflowState.mComputedHeight != NS_INTRINSICSIZE)
// kidReflowState.mComputedHeight -= aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right;
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
CalculateChildTotalSize(kidFrame, kidDesiredSize);
// Place and size the child.
nscoord x = aReflowState.mComputedBorderPadding.left;
nscoord y = aReflowState.mComputedBorderPadding.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 += aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.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 += aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom;
nsRect rect(x, y, kidDesiredSize.width, kidDesiredSize.height);
kidFrame->SetRect(rect);
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.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
NS_FRAME_TRACE_MSG(NS_FRAME_TRACE_CALLS,
("exit nsScrollPortFrame::Reflow: status=%d width=%d height=%d",
aStatus, aDesiredSize.width, aDesiredSize.height));
return NS_OK;
}
NS_IMETHODIMP
nsScrollPortFrame::Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
// Only paint the border and background if we're visible
const nsStyleDisplay* display = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (display->mVisible) {
// Paint our border only (no background)
const nsStyleSpacing* spacing = (const nsStyleSpacing*)
mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsRect rect(0, 0, mRect.width, mRect.height);
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
aDirtyRect, rect, *spacing, mStyleContext, 0);
}
}
// Paint our children
return nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect,
aWhichLayer);
}
PRIntn
nsScrollPortFrame::GetSkipSides() const
{
return 0;
}
NS_IMETHODIMP
nsScrollPortFrame::GetFrameType(nsIAtom** aType) const
{
NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer");
*aType = nsLayoutAtoms::scrollFrame;
NS_ADDREF(*aType);
return NS_OK;
}
NS_IMETHODIMP
nsScrollPortFrame::GetFrameName(nsString& aResult) const
{
return MakeFrameName("Scroll", aResult);
}
/*
NS_IMETHODIMP
nsScrollPortFrame::GetBoxInfo(nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize)
{
nsresult rv;
nsIBox ibox = nsnull;
rv = mScrollAreaFrame->QueryInterface(nsIBox::GetIID(), (void**)&ibox))
ibox->GetBoxInfo(aPresContext, aReflowState, aSize);
NS_ASSERTION(NS_SUCCEEDED(rv),"Scrollport must implement box!!");
return rv;
}
NS_IMETHODIMP
nsScrollPortFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
if (aIID.Equals(kIBoxIID)) {
*aInstancePtr = (void*)(nsIBox*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
}
NS_IMETHODIMP
nsScrollPortFrame::Dirty(const nsHTMLReflowState& aReflowState, nsIFrame*& incrementalChild)
{
mIncrementalChild = PR_FALSE;
incrementalChild = nsnull;
nsIFrame* frame;
aReflowState.reflowCommand->GetNext(frame);
nscoord count = 0;
nsIFrame* childFrame = mFrames.FirstChild();
nsIBox* ibox;
if (NS_SUCCEEDED(childFrame->QueryInterface(nsIBox::GetIID(), (void**)&ibox)) && ibox)
ibox->Dirty(aReflowState, incrementalChild);
else
incrementalChild = frame;
// if we found a leaf. Then mark it as being incremental. So when we
// flow it we will flow it incrementally
if (incrementalChild == childFrame)
mIncrementalChild = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP_(nsrefcnt)
nsScrollPortFrame::AddRef(void)
{
return NS_OK;
}
NS_IMETHODIMP_(nsrefcnt)
nsScrollPortFrame::Release(void)
{
return NS_OK;
}
*/

View File

@ -0,0 +1,107 @@
/* -*- 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.0 (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.
*/
#ifndef nsScrollPortFrame_h___
#define nsScrollPortFrame_h___
#include "nsHTMLContainerFrame.h"
/**
* The scroll frame creates and manages the scrolling view
*
* It only supports having a single child frame that typically is an area
* frame, but doesn't have to be. The child frame must have a view, though
*
* Scroll frames don't support incremental changes, i.e. you can't replace
* or remove the scrolled frame
*/
class nsScrollPortFrame : public nsHTMLContainerFrame {
public:
friend nsresult NS_NewScrollPortFrame(nsIFrame** aNewFrame);
NS_IMETHOD Init(nsIPresContext& aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
// 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
NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList);
// Because there can be only one child frame, these two function return
// NS_ERROR_FAILURE
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aFrameList);
NS_IMETHOD InsertFrames(nsIPresContext& aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList);
// This function returns NS_ERROR_NOT_IMPLEMENTED
NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext,
nsIPresShell& aPresShell,
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);
/**
* Get the "type" of the frame
*
* @see nsLayoutAtoms::scrollFrame
*/
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
NS_IMETHOD GetFrameName(nsString& aResult) const;
protected:
nsScrollPortFrame();
virtual PRIntn GetSkipSides() const;
// Creation of the widget for the scrolling view is factored into a virtual method so
// that sub-classes may control widget creation.
virtual nsresult CreateScrollingViewWidget(nsIView* aView,const nsStylePosition* aPosition);
// Getting the view for scollframe may be overriden to provide a parent view for te scroll frame
virtual nsresult GetScrollingParentView(nsIFrame* aParent, nsIView** aParentView);
private:
nsresult CreateScrollingView(nsIPresContext& aPresContext);
nsresult CalculateChildTotalSize(nsIFrame* aKidFrame,
nsHTMLReflowMetrics& aKidReflowMetrics);
};
#endif /* nsScrollPortFrame_h___ */

View File

@ -1252,3 +1252,127 @@ select[-moz-dropdown-active]:-moz-dropdown-list {
:-moz-letter-frame {
}
xul|titledbutton {
display: block;
border:2px solid blue;
}
xul|thumb {
display: block;
background-color: rgb(206, 207, 206);
border: 2px outset rgb(156, 154, 156);
list-style-image: url(chrome://global/skin/scroll-thumb-horiz.gif)
}
xul|thumb:hover {
list-style-image: url(chrome://global/skin/scroll-thumb-horiz-hover.gif);
}
xul|thumb[disabled="true"] {
list-style-image: url(chrome://global/skin/scroll-thumb-horiz-disabled.gif);
}
xul|slider[align="vertical"] xul|thumb {
list-style-image: url(chrome://global/skin/scroll-thumb-vert.gif)
}
xul|slider[align="vertical"] xul|thumb:hover {
list-style-image: url(chrome://global/skin/scroll-thumb-vert-hover.gif);
}
xul|slider[align="vertical"] xul|thumb[disabled="true"] {
list-style-image: url(chrome://global/skin/scroll-thumb-vert-disabled.gif);
}
xul|thumb:active {
background-color: rgb(220, 210, 210);
}
xul|slider[align="vertical"] xul|thumb:active {
background-color: rgb(220, 210, 210);
}
xul|slider {
display: block;
border: 1px solid black;
background-color: rgb(240,240,240);
// background-image: url("resource:/res/samples/bg.jpg");
}
xul|scrollbarbutton {
display: inline;
vertical-align: bottom;
cursor: default;
border: 2px outset rgb(156, 154, 156);
background-color: rgb(206, 207, 206);
color:black;
padding: 1px;
}
xul|scrollbarbutton:active {
border-style: inset;
padding-left: 2px;
padding-right: 0px;
padding-top: 2px;
padding-bottom: 0px;
}
xul|scrollbarbutton[type="decrement"] {
list-style-image: url(chrome://global/skin/scroll-left.gif)
}
xul|scrollbarbutton[type="decrement"]:hover {
list-style-image: url(chrome://global/skin/scroll-left-hover.gif)
}
xul|scrollbarbutton[type="decrement"][disabled="true"] {
list-style-image: url(chrome://global/skin/scroll-left-disabled.gif)
}
xul|scrollbarbutton[type="increment"] {
list-style-image: url(chrome://global/skin/scroll-right.gif)
}
xul|scrollbarbutton[type="increment"]:hover {
list-style-image: url(chrome://global/skin/scroll-right-hover.gif)
}
xul|scrollbarbutton[type="increment"][disabled="true"] {
list-style-image: url(chrome://global/skin/scroll-right-disabled.gif)
}
xul|scrollbar[align="vertical"] xul|scrollbarbutton[type="decrement"] {
list-style-image: url(chrome://global/skin/scrollUp.gif)
}
xul|scrollbar[align="vertical"] xul|scrollbarbutton[type="decrement"]:hover {
list-style-image: url(chrome://global/skin/scrollUp_mo.gif)
}
xul|scrollbar[align="vertical"] xul|scrollbarbutton[type="decrement"][disabled="true"] {
list-style-image: url(chrome://global/skin/scrollUp_dis.gif)
}
xul|scrollbar[align="vertical"] xul|scrollbarbutton[type="increment"] {
list-style-image: url(chrome://global/skin/scrollDown.gif)
}
xul|scrollbar[align="vertical"] xul|scrollbarbutton[type="increment"]:hover {
list-style-image: url(chrome://global/skin/scrollDown_mo.gif)
}
xul|scrollbar[align="vertical"] xul|scrollbarbutton[type="increment"][disabled="true"] {
list-style-image: url(chrome://global/skin/scrollDown_dis.gif)
}
xul|scrollbar[value="hidden"] {
visibility: hidden;
}

View File

@ -79,6 +79,17 @@
#include "nsDocument.h"
#include "nsToolbarItemFrame.h"
#define IS_GFX
nsresult
NS_NewThumbFrame ( nsIFrame** aNewFrame );
nsresult
NS_NewScrollPortFrame ( nsIFrame** aNewFrame );
nsresult
NS_NewGfxScrollFrame ( nsIFrame** aNewFrame );
nsresult
NS_NewTabFrame ( nsIFrame** aNewFrame );
@ -1316,29 +1327,15 @@ nsCSSFrameConstructor::ConstructTableGroupFrameOnly(nsIPresContext* aPr
(const nsStyleDisplay*) aStyleContext->GetStyleData(eStyleStruct_Display);
if (IsScrollable(aPresContext, styleDisplay)) {
// Create a scroll frame and initialize it
rv = NS_NewScrollFrame(&aNewTopFrame);
if (NS_FAILED(rv)) return rv;
aNewTopFrame->Init(*aPresContext, aContent, aParentFrame, aStyleContext, nsnull);
// The scroll frame gets the original style context, the scrolled frame gets
// a pseudo element style context that inherits the background properties
nsCOMPtr<nsIStyleContext> scrolledPseudoStyle;
aPresContext->ResolvePseudoStyleContextFor(aContent, nsLayoutAtoms::scrolledContentPseudo,
aStyleContext, PR_FALSE,
getter_AddRefs(scrolledPseudoStyle));
// Create an area container for the frame
rv = (aIsRowGroup) ? aTableCreator.CreateTableRowGroupFrame(&aNewGroupFrame)
: aTableCreator.CreateTableColGroupFrame(&aNewGroupFrame);
if (NS_FAILED(rv)) return rv;
// Initialize the frame and force it to have a view
aNewGroupFrame->Init(*aPresContext, aContent, aNewTopFrame, scrolledPseudoStyle,
nsnull);
nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, aNewGroupFrame,
scrolledPseudoStyle, PR_TRUE);
aNewTopFrame->SetInitialChildList(*aPresContext, nsnull, aNewGroupFrame);
rv = BuildScrollFrame(aPresContext, aState, aContent, aNewGroupFrame, aParentFrame,
aStyleContext, aNewTopFrame, PR_FALSE, PR_FALSE, PR_FALSE,
PR_FALSE);
} else {
rv = (aIsRowGroup) ? aTableCreator.CreateTableRowGroupFrame(&aNewTopFrame)
: aTableCreator.CreateTableColGroupFrame(&aNewTopFrame);
@ -2154,6 +2151,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresContext* aPresCo
return NS_OK;
}
/*
NS_IMETHODIMP
nsCSSFrameConstructor::ConstructRootFrame(nsIPresContext* aPresContext,
nsIContent* aDocElement,
@ -2244,6 +2242,7 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresContext* aPresContext,
nsIFrame* scrollFrame;
nsCOMPtr<nsIStyleContext> scrollFrameStyle;
if (isScrollable) {
NS_NewScrollFrame(&scrollFrame);
aPresContext->ResolvePseudoStyleContextFor(nsnull, nsLayoutAtoms::viewportScrollPseudo,
viewportPseudoStyle, PR_FALSE,
@ -2251,6 +2250,7 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresContext* aPresContext,
scrollFrame->Init(*aPresContext, nsnull, viewportFrame, scrollFrameStyle,
nsnull);
// Inform the view manager about the root scrollable view
nsIView* scrollFrameView;
nsIScrollableView* scrollingView;
@ -2356,6 +2356,261 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIPresContext* aPresContext,
aNewFrame = viewportFrame;
return NS_OK;
}
*/
NS_IMETHODIMP
nsCSSFrameConstructor::ConstructRootFrame(nsIPresContext* aPresContext,
nsIContent* aDocElement,
nsIFrame*& aNewFrame)
{
#ifdef NS_DEBUG
nsCOMPtr<nsIDocument> doc;
nsIContent* rootContent;
// Verify that the content object is really the root content object
aDocElement->GetDocument(*getter_AddRefs(doc));
rootContent = doc->GetRootContent();
NS_ASSERTION(rootContent == aDocElement, "unexpected content");
NS_RELEASE(rootContent);
#endif
nsIFrame* viewportFrame;
nsCOMPtr<nsIStyleContext> viewportPseudoStyle;
// Create the viewport frame
NS_NewViewportFrame(&viewportFrame);
// Create a pseudo element style context
aPresContext->ResolvePseudoStyleContextFor(nsnull, nsLayoutAtoms::viewportPseudo,
nsnull, PR_FALSE,
getter_AddRefs(viewportPseudoStyle));
{ // ensure that the viewport thinks it is a block frame, layout goes pootsy if it doesn't
nsStyleDisplay* display = (nsStyleDisplay*)viewportPseudoStyle->GetMutableStyleData(eStyleStruct_Display);
display->mDisplay = NS_STYLE_DISPLAY_BLOCK;
}
// Initialize the viewport frame. It has a NULL content object
viewportFrame->Init(*aPresContext, nsnull, nsnull, viewportPseudoStyle, nsnull);
// Bind the viewport frame to the root view
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell));
nsCOMPtr<nsIViewManager> viewManager;
presShell->GetViewManager(getter_AddRefs(viewManager));
nsIView* rootView;
viewManager->GetRootView(rootView);
viewportFrame->SetView(rootView);
// If the device supports scrolling (e.g., in galley mode on the screen and
// for print-preview, but not when printing), then create a scroll frame that
// will act as the scrolling mechanism for the viewport.
// XXX Do we even need a viewport when printing to a printer?
// XXX It would be nice to have a better way to query for whether the device
// is scrollable
PRBool isScrollable = PR_TRUE;
if (aPresContext) {
nsIDeviceContext* dc;
aPresContext->GetDeviceContext(&dc);
if (dc) {
PRBool supportsWidgets;
if (NS_SUCCEEDED(dc->SupportsNativeWidgets(supportsWidgets))) {
isScrollable = supportsWidgets;
}
NS_RELEASE(dc);
}
}
// 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.
nsISupports* container;
if (nsnull != aPresContext) {
aPresContext->GetContainer(&container);
if (nsnull != container) {
nsIWebShell* webShell = nsnull;
container->QueryInterface(kIWebShellIID, (void**) &webShell);
if (nsnull != webShell) {
PRInt32 scrolling = -1;
webShell->GetScrolling(scrolling);
if (NS_STYLE_OVERFLOW_HIDDEN == scrolling) {
isScrollable = PR_FALSE;
}
NS_RELEASE(webShell);
}
NS_RELEASE(container);
}
}
// If the viewport should offer a scrolling mechanism, then create a
// scroll frame
nsIFrame* scrollFrame = nsnull;
nsIFrame* gfxScrollFrame = nsnull;
if (isScrollable) {
nsIFrame* parent = nsnull;
if (IsGfxMode(aPresContext)) {
NS_NewGfxScrollFrame(&gfxScrollFrame);
gfxScrollFrame->Init(*aPresContext, aDocElement, viewportFrame, viewportPseudoStyle,
nsnull);
NS_NewScrollPortFrame(&scrollFrame);
parent = gfxScrollFrame;
} else {
NS_NewScrollFrame(&scrollFrame);
parent = viewportFrame;
}
// XXX should probably be a scrolled content pseudo style context
scrollFrame->Init(*aPresContext, nsnull, parent, viewportPseudoStyle,
nsnull);
// Inform the view manager about the root scrollable view
nsIView* scrollFrameView;
nsIScrollableView* scrollingView;
scrollFrame->GetView(&scrollFrameView);
NS_ASSERTION(scrollFrameView, "scroll frame has no view");
scrollFrameView->QueryInterface(kScrollViewIID, (void**)&scrollingView);
viewManager->SetRootScrollableView(scrollingView);
}
PRBool isPaginated;
aPresContext->IsPaginated(&isPaginated);
if (isPaginated) {
nsIFrame* pageSequenceFrame;
// Create a page sequence frame
NS_NewSimplePageSequenceFrame(&pageSequenceFrame);
// XXX should probably be a page sequence pseudo style context
pageSequenceFrame->Init(*aPresContext, nsnull, isScrollable ? scrollFrame :
viewportFrame, viewportPseudoStyle, nsnull);
if (isScrollable) {
nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, pageSequenceFrame,
viewportPseudoStyle, PR_TRUE);
}
// Create the first page
nsIFrame* pageFrame;
NS_NewPageFrame(&pageFrame);
// The page is the containing block for 'fixed' elements. which are repeated
// on every page
mFixedContainingBlock = pageFrame;
// Initialize the page and force it to have a view. This makes printing of
// the pages easier and faster.
// XXX Use a PAGE style context...
nsCOMPtr<nsIStyleContext> pagePseudoStyle;
aPresContext->ResolvePseudoStyleContextFor(nsnull, nsLayoutAtoms::pagePseudo,
viewportPseudoStyle, PR_FALSE,
getter_AddRefs(pagePseudoStyle));
pageFrame->Init(*aPresContext, nsnull, pageSequenceFrame, pagePseudoStyle,
nsnull);
nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, pageFrame,
pagePseudoStyle, PR_TRUE);
// The eventual parent of the document element frame
mDocElementContainingBlock = pageFrame;
// Set the initial child lists
pageSequenceFrame->SetInitialChildList(*aPresContext, nsnull, pageFrame);
if (isScrollable) {
scrollFrame->SetInitialChildList(*aPresContext, nsnull, pageSequenceFrame);
if (IsGfxMode(aPresContext)) {
nsFrameConstructorState state(aPresContext,
nsnull,
nsnull,
nsnull);
nsFrameItems children;
children.AddChild(scrollFrame);
// if there are any anonymous children for the nsScrollFrame create frames for them.
// for now make say its tag is "input". This is a hack to make sure we check for the anonymous interface
CreateAnonymousFrames(aPresContext, nsHTMLAtoms::input, state, aDocElement, gfxScrollFrame,
children);
//viewportFrame->SetInitialChildList(*aPresContext, nsnull, scrollFrame);
viewportFrame->SetInitialChildList(*aPresContext, nsnull, gfxScrollFrame);
gfxScrollFrame->SetInitialChildList(*aPresContext, nsnull, children.childList);
} else
viewportFrame->SetInitialChildList(*aPresContext, nsnull, scrollFrame);
} else {
viewportFrame->SetInitialChildList(*aPresContext, nsnull, pageSequenceFrame);
}
} else {
// The viewport is the containing block for 'fixed' elements
mFixedContainingBlock = viewportFrame;
// Create the root frame. The document element's frame is a child of the
// root frame.
//
// The root frame serves two purposes:
// - reserves space for any margins needed for the document element's frame
// - makes sure that the document element's frame covers the entire canvas
nsIFrame* rootFrame;
NS_NewRootFrame(&rootFrame);
// XXX this should be a root pseudo style context
rootFrame->Init(*aPresContext, nsnull, isScrollable ? scrollFrame :
viewportFrame, viewportPseudoStyle, nsnull);
if (isScrollable) {
nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, rootFrame,
viewportPseudoStyle, PR_TRUE);
}
// The eventual parent of the document element frame
mDocElementContainingBlock = rootFrame;
// Set the initial child lists
if (isScrollable) {
scrollFrame->SetInitialChildList(*aPresContext, nsnull, rootFrame);
if (IsGfxMode(aPresContext)) {
nsFrameConstructorState state(aPresContext,
nsnull,
nsnull,
nsnull);
nsFrameItems children;
children.AddChild(scrollFrame);
// if there are any anonymous children for the nsScrollFrame create frames for them.
// for now make say its tag is "input". This is a hack to make sure we check for the anonymous interface
CreateAnonymousFrames(aPresContext, nsHTMLAtoms::input, state, aDocElement, gfxScrollFrame,
children);
// viewportFrame->SetInitialChildList(*aPresContext, nsnull, scrollFrame);
viewportFrame->SetInitialChildList(*aPresContext, nsnull, gfxScrollFrame);
gfxScrollFrame->SetInitialChildList(*aPresContext, nsnull, children.childList);
} else
viewportFrame->SetInitialChildList(*aPresContext, nsnull, scrollFrame);
} else {
viewportFrame->SetInitialChildList(*aPresContext, nsnull, rootFrame);
}
}
aNewFrame = viewportFrame;
return NS_OK;
}
nsresult
nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresContext* aPresContext,
@ -2573,6 +2828,18 @@ nsCSSFrameConstructor::ConstructTextControlFrame(nsIPresContext* aPresC
return rv;
}
PRBool
nsCSSFrameConstructor::IsGfxMode(nsIPresContext* aPresContext)
{
return PR_FALSE;
/*
nsWidgetRendering mode;
aPresContext->GetWidgetRenderingMode(&mode);
return (eWidgetRendering_Gfx == mode);
*/
}
nsresult
nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
@ -2645,8 +2912,13 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContex
// Initialize the scroll frame positioned. Note that it is NOT initialized as
// absolutely positioned.
nsIFrame* newFrame = nsnull;
InitializeScrollFrame(aPresContext, aState, listFrame, aContent, comboboxFrame,
listStyle, newFrame, PR_FALSE, PR_FALSE, PR_TRUE);
nsIFrame* scrolledFrame = nsnull;
NS_NewAreaFrame(&scrolledFrame, NS_BLOCK_SHRINK_WRAP);
InitializeScrollFrame(aPresContext, aState, listFrame, scrolledFrame, aContent, comboboxFrame,
listStyle, PR_TRUE, PR_FALSE, PR_FALSE, PR_TRUE);
newFrame = listFrame;
// Set flag so the events go to the listFrame not child frames.
// XXX: We should replace this with a real widget manager similar
@ -2684,10 +2956,15 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContex
nsIFrame * listFrame;
rv = NS_NewListControlFrame(&listFrame);
aNewFrame = listFrame;
InitializeScrollFrame(aPresContext, aState, listFrame, aContent, aParentFrame,
aStyleContext, aNewFrame, aIsAbsolutelyPositioned, PR_FALSE,
nsIFrame* scrolledFrame = nsnull;
NS_NewAreaFrame(&scrolledFrame, NS_BLOCK_SHRINK_WRAP);
InitializeScrollFrame(aPresContext, aState, listFrame, scrolledFrame, aContent, aParentFrame,
aStyleContext, aIsAbsolutelyPositioned, PR_TRUE, PR_FALSE,
PR_TRUE);
aNewFrame = listFrame;
// Set flag so the events go to the listFrame not child frames.
// XXX: We should replace this with a real widget manager similar
// to how the nsFormControlFrame works.
@ -3226,18 +3503,15 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext,
isFixedPositioned = PR_TRUE;
}
// Create a scroll frame
nsIFrame* scrollFrame;
NS_NewScrollFrame(&scrollFrame);
// Initialize it
InitializeScrollFrame(aPresContext, aState, scrollFrame, aContent, aParentFrame,
aStyleContext, newFrame, isAbsolutelyPositioned, isFixedPositioned,
// Build it
BuildBoxScrollFrame(aPresContext, aState, aContent, aParentFrame,
aStyleContext, newFrame, PR_TRUE, isAbsolutelyPositioned, isFixedPositioned,
PR_FALSE);
frameHasBeenInitialized = PR_TRUE;
}
}
// End of BOX CONSTRUCTION logic
} // End of BOX CONSTRUCTION logic
// TITLED BUTTON CONSTRUCTION
else if (aTag == nsXULAtoms::titledbutton) {
@ -3292,7 +3566,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext,
else if (aTag == nsXULAtoms::thumb) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
rv = NS_NewTitledButtonFrame(&newFrame);
rv = NS_NewThumbFrame(&newFrame);
}
// End of THUMB CONSTRUCTION logic
@ -3384,14 +3658,146 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext,
}
#endif
/**
* Create a scroll frame whose scrolled content needs a block frame
*/
nsresult
nsCSSFrameConstructor::InitializeScrollFrame(nsIPresContext* aPresContext,
nsCSSFrameConstructor::BuildBlockScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock)
{
// Create an area container for the frame
nsIFrame* scrolledFrame;
NS_NewAreaFrame(&scrolledFrame, NS_BLOCK_SHRINK_WRAP);
nsresult rv = BuildScrollFrame(aPresContext, aState, aContent, scrolledFrame, aParentFrame,
aStyleContext, aNewFrame, aProcessChildren, aIsAbsolutelyPositioned, aIsFixedPositioned,
aCreateBlock);
return rv;
}
/**
* Create a scroll frame whose scrolled content needs a box frame
*/
nsresult
nsCSSFrameConstructor::BuildBoxScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock)
{
// Create an area container for the frame
nsIFrame* scrolledFrame;
NS_NewBoxFrame(&scrolledFrame);
nsresult rv = BuildScrollFrame(aPresContext, aState, aContent, scrolledFrame, aParentFrame,
aStyleContext, aNewFrame, aProcessChildren, aIsAbsolutelyPositioned, aIsFixedPositioned,
aCreateBlock);
return rv;
}
/**
* Create a new scroll frame. Populate it and return it.
*/
nsresult
nsCSSFrameConstructor::BuildScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aScrolledFrame,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock)
{
nsIFrame* scrollFrame = nsnull;
nsIFrame* gfxScrollFrame = nsnull;
nsFrameItems anonymousItems;
if (IsGfxMode(aPresContext)) {
// if gfx we need to make a special scrollframe
// create the frames
nsresult rv = BuildGfxScrollFrame(aPresContext, aState, aContent, aParentFrame,
aStyleContext, gfxScrollFrame, anonymousItems);
// get the scrollframe from the anonymous list
scrollFrame = anonymousItems.childList;
aParentFrame = gfxScrollFrame;
aNewFrame = gfxScrollFrame;
} else {
NS_NewScrollFrame(&scrollFrame);
aNewFrame = scrollFrame;
}
// Initialize it
nsresult rv = InitializeScrollFrame(aPresContext, aState, scrollFrame, aScrolledFrame, aContent, aParentFrame,
aStyleContext, aProcessChildren, aIsAbsolutelyPositioned, aIsFixedPositioned,
aCreateBlock);
if (IsGfxMode(aPresContext))
gfxScrollFrame->SetInitialChildList(*aPresContext, nsnull, anonymousItems.childList);
return rv;
}
nsresult
nsCSSFrameConstructor::BuildGfxScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIFrame* scrollFrame,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
nsFrameItems& aAnonymousFrames)
{
NS_NewGfxScrollFrame(&aNewFrame);
aNewFrame->Init(*aPresContext, aContent, aParentFrame, aStyleContext,
nsnull);
nsIFrame* scrollbox = nsnull;
NS_NewScrollPortFrame(&scrollbox);
aAnonymousFrames.AddChild(scrollbox);
// if there are any anonymous children for the nsScrollFrame create frames for them.
// for now make say its tag is "input". This is a hack to make sure we check for the anonymous interface
CreateAnonymousFrames(aPresContext, nsHTMLAtoms::input, aState, aContent, aNewFrame,
aAnonymousFrames);
return NS_OK;
}
nsresult
nsCSSFrameConstructor::InitializeScrollFrame(nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIFrame* scrollFrame,
nsIFrame* scrolledFrame,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock)
@ -3404,8 +3810,6 @@ nsCSSFrameConstructor::InitializeScrollFrame(nsIPresContext* aPresConte
} else if (aIsFixedPositioned) {
geometricParent = aState.mFixedItems.containingBlock;
}
scrollFrame->Init(*aPresContext, aContent, geometricParent, aStyleContext,
nsnull);
// The scroll frame gets the original style context, and the scrolled
// frame gets a SCROLLED-CONTENT pseudo element style context that
@ -3416,10 +3820,13 @@ nsCSSFrameConstructor::InitializeScrollFrame(nsIPresContext* aPresConte
aStyleContext, PR_FALSE,
getter_AddRefs(scrolledPseudoStyle));
// Create an area container for the frame
nsIFrame* scrolledFrame;
NS_NewAreaFrame(&scrolledFrame, NS_BLOCK_SHRINK_WRAP);
if (IsGfxMode(aPresContext)) {
scrollFrame->Init(*aPresContext, aContent, geometricParent, scrolledPseudoStyle,
nsnull);
} else {
scrollFrame->Init(*aPresContext, aContent, geometricParent, aStyleContext,
nsnull);
}
// Initialize the frame and force it to have a view
scrolledFrame->Init(*aPresContext, aContent, scrollFrame,
scrolledPseudoStyle, nsnull);
@ -3475,6 +3882,7 @@ nsCSSFrameConstructor::InitializeScrollFrame(nsIPresContext* aPresConte
nsLayoutAtoms::absoluteList,
aState.mAbsoluteItems.childList);
}
if (aState.mFloatedItems.childList) {
scrolledFrame->SetInitialChildList(*aPresContext,
nsLayoutAtoms::floaterList,
@ -3483,7 +3891,6 @@ nsCSSFrameConstructor::InitializeScrollFrame(nsIPresContext* aPresConte
// Set the scroll frame's initial child list
scrollFrame->SetInitialChildList(*aPresContext, nsnull, scrolledFrame);
aNewFrame = scrollFrame;
return NS_OK;
}
@ -3535,13 +3942,9 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPre
isFixedPositioned = PR_TRUE;
}
// Create a scroll frame
nsIFrame* scrollFrame;
NS_NewScrollFrame(&scrollFrame);
// Initialize it
InitializeScrollFrame(aPresContext, aState, scrollFrame, aContent, aParentFrame,
aStyleContext, newFrame, isAbsolutelyPositioned, isFixedPositioned,
// Build the scrollframe it
BuildBlockScrollFrame(aPresContext, aState, aContent, aParentFrame,
aStyleContext, newFrame, PR_TRUE, isAbsolutelyPositioned, isFixedPositioned,
PR_FALSE);
}
// See if the frame is absolute or fixed positioned

View File

@ -516,16 +516,67 @@ protected:
nsIFrame* GetFloaterContainingBlock(nsIPresContext* aPresContext,
nsIFrame* aFrame);
nsresult InitializeScrollFrame(nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIFrame* aScrollFrame,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock);
nsresult BuildBlockScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock);
nsresult BuildBoxScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock);
nsresult
BuildScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aScrolledFrame,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock);
nsresult
BuildGfxScrollFrame (nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aNewFrame,
nsFrameItems& aAnonymousFrames);
nsresult
InitializeScrollFrame(nsIPresContext* aPresContext,
nsFrameConstructorState& aState,
nsIFrame* scrollFrame,
nsIFrame* scrolledFrame,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
PRBool aProcessChildren,
PRBool aIsAbsolutelyPositioned,
PRBool aIsFixedPositioned,
PRBool aCreateBlock);
PRBool IsGfxMode(nsIPresContext* aPresContext);
nsresult RecreateFramesForContent(nsIPresContext* aPresContext,
nsIContent* aContent);

View File

@ -1252,3 +1252,127 @@ select[-moz-dropdown-active]:-moz-dropdown-list {
:-moz-letter-frame {
}
xul|titledbutton {
display: block;
border:2px solid blue;
}
xul|thumb {
display: block;
background-color: rgb(206, 207, 206);
border: 2px outset rgb(156, 154, 156);
list-style-image: url(chrome://global/skin/scroll-thumb-horiz.gif)
}
xul|thumb:hover {
list-style-image: url(chrome://global/skin/scroll-thumb-horiz-hover.gif);
}
xul|thumb[disabled="true"] {
list-style-image: url(chrome://global/skin/scroll-thumb-horiz-disabled.gif);
}
xul|slider[align="vertical"] xul|thumb {
list-style-image: url(chrome://global/skin/scroll-thumb-vert.gif)
}
xul|slider[align="vertical"] xul|thumb:hover {
list-style-image: url(chrome://global/skin/scroll-thumb-vert-hover.gif);
}
xul|slider[align="vertical"] xul|thumb[disabled="true"] {
list-style-image: url(chrome://global/skin/scroll-thumb-vert-disabled.gif);
}
xul|thumb:active {
background-color: rgb(220, 210, 210);
}
xul|slider[align="vertical"] xul|thumb:active {
background-color: rgb(220, 210, 210);
}
xul|slider {
display: block;
border: 1px solid black;
background-color: rgb(240,240,240);
// background-image: url("resource:/res/samples/bg.jpg");
}
xul|scrollbarbutton {
display: inline;
vertical-align: bottom;
cursor: default;
border: 2px outset rgb(156, 154, 156);
background-color: rgb(206, 207, 206);
color:black;
padding: 1px;
}
xul|scrollbarbutton:active {
border-style: inset;
padding-left: 2px;
padding-right: 0px;
padding-top: 2px;
padding-bottom: 0px;
}
xul|scrollbarbutton[type="decrement"] {
list-style-image: url(chrome://global/skin/scroll-left.gif)
}
xul|scrollbarbutton[type="decrement"]:hover {
list-style-image: url(chrome://global/skin/scroll-left-hover.gif)
}
xul|scrollbarbutton[type="decrement"][disabled="true"] {
list-style-image: url(chrome://global/skin/scroll-left-disabled.gif)
}
xul|scrollbarbutton[type="increment"] {
list-style-image: url(chrome://global/skin/scroll-right.gif)
}
xul|scrollbarbutton[type="increment"]:hover {
list-style-image: url(chrome://global/skin/scroll-right-hover.gif)
}
xul|scrollbarbutton[type="increment"][disabled="true"] {
list-style-image: url(chrome://global/skin/scroll-right-disabled.gif)
}
xul|scrollbar[align="vertical"] xul|scrollbarbutton[type="decrement"] {
list-style-image: url(chrome://global/skin/scrollUp.gif)
}
xul|scrollbar[align="vertical"] xul|scrollbarbutton[type="decrement"]:hover {
list-style-image: url(chrome://global/skin/scrollUp_mo.gif)
}
xul|scrollbar[align="vertical"] xul|scrollbarbutton[type="decrement"][disabled="true"] {
list-style-image: url(chrome://global/skin/scrollUp_dis.gif)
}
xul|scrollbar[align="vertical"] xul|scrollbarbutton[type="increment"] {
list-style-image: url(chrome://global/skin/scrollDown.gif)
}
xul|scrollbar[align="vertical"] xul|scrollbarbutton[type="increment"]:hover {
list-style-image: url(chrome://global/skin/scrollDown_mo.gif)
}
xul|scrollbar[align="vertical"] xul|scrollbarbutton[type="increment"][disabled="true"] {
list-style-image: url(chrome://global/skin/scrollDown_dis.gif)
}
xul|scrollbar[value="hidden"] {
visibility: hidden;
}

View File

@ -32,6 +32,8 @@ LOCAL_INCLUDES = \
-I$(srcdir)/../../../html/forms/src \
-I$(srcdir)/../../content/src \
-I$(srcdir)/../../../html/content/src \
-I$(srcdir)/../../../xml/content/src \
-I$(srcdir)/../../../base/public \
$(NULL)
# Note the sophisticated alphabetical ordering :-|
@ -63,6 +65,7 @@ CPPSRCS = \
nsMenuBarFrame.cpp \
nsMenuBarListener.cpp \
nsPopupSetFrame.cpp \
nsRepeatService.cpp \
$(NULL)
include $(topsrcdir)/config/config.mk

View File

@ -24,6 +24,7 @@ REQUIRES=xpcom raptor pref
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
CPPSRCS= \
nsRepeatService.cpp \
nsToolbarDragListener.cpp \
nsToolbarItemFrame.cpp \
nsSplitterFrame.cpp \
@ -54,6 +55,7 @@ CPPSRCS= \
$(NULL)
CPP_OBJS= \
.\$(OBJDIR)\nsRepeatService.obj \
.\$(OBJDIR)\nsToolbarDragListener.obj \
.\$(OBJDIR)\nsToolbarItemFrame.obj \
.\$(OBJDIR)\nsGrippyFrame.obj \
@ -93,7 +95,9 @@ LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I$(PUBLIC)\js \
-I..\..\..\html\table\src \
-I..\..\content\src \
-I..\..\..\html\forms\src \
-I$(PUBLIC)\netlib -I..\..\..\base\src -I$(PUBLIC)\pref
-I$(PUBLIC)\netlib -I..\..\..\base\src -I$(PUBLIC)\pref \
-I..\..\..\xml\content\src \
-I..\..\..\base\public
LCFLAGS = \
$(LCFLAGS) \

View File

@ -357,6 +357,12 @@ printf("\n");
//------------------------- Add our border and insets in ----------------------------
//-----------------------------------------------------------------------------------
if (aReflowState.mComputedWidth != NS_INTRINSICSIZE && rect.width < aReflowState.mComputedWidth)
rect.width = aReflowState.mComputedWidth;
if (aReflowState.mComputedHeight != NS_INTRINSICSIZE && rect.height < aReflowState.mComputedHeight)
rect.height = aReflowState.mComputedHeight;
// the rect might have gotten bigger so recalc ourSize
rect.Inflate(inset);
rect.Inflate(aReflowState.mComputedBorderPadding);

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.0 (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.
*/
//
// Eric Vaughan
// Netscape Communications
//
// See documentation in associated header file
//
#include "nsRepeatService.h"
#define INITAL_REPEAT_DELAY 250
#define REPEAT_DELAY 50
nsRepeatService* nsRepeatService::gInstance = nsnull;
nsRepeatService::nsRepeatService()
{
}
nsRepeatService::~nsRepeatService()
{
mCallback = nsnull;
Stop();
}
nsRepeatService*
nsRepeatService::GetInstance()
{
if (!gInstance) {
gInstance = new nsRepeatService();
gInstance->mRefCnt = 1;
}
return gInstance;
}
void nsRepeatService::Start(nsITimerCallback* aCallback)
{
mCallback = aCallback;
nsresult rv = NS_NewTimer(getter_AddRefs(mRepeatTimer));
if (NS_OK == rv) {
mRepeatTimer->Init(this, INITAL_REPEAT_DELAY);
}
}
void nsRepeatService::Stop()
{
//printf("Stopping repeat timer\n");
if (mRepeatTimer) {
mRepeatTimer->Cancel();
mRepeatTimer = nsnull;
}
}
void nsRepeatService::Notify(nsITimer *timer)
{
// if the repeat delay is the initial one reset it.
if (mRepeatTimer) {
mRepeatTimer->Cancel();
nsresult rv = NS_NewTimer(getter_AddRefs(mRepeatTimer));
mRepeatTimer->Init(this, REPEAT_DELAY);
}
mCallback->Notify(timer);
}
static NS_DEFINE_IID(kITimerCallbackIID, NS_ITIMERCALLBACK_IID);
NS_IMPL_ISUPPORTS(nsRepeatService, kITimerCallbackIID);

View File

@ -0,0 +1,55 @@
/* -*- 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
//
// nsRepeatService
//
#ifndef nsRepeatService_h__
#define nsRepeatService_h__
#include "nsCOMPtr.h"
#include "nsITimerCallback.h"
#include "nsITimer.h"
class nsITimer;
class nsRepeatService : public nsITimerCallback
{
public:
virtual void Notify(nsITimer *timer);
void Start(nsITimerCallback* aCallback);
void Stop();
static nsRepeatService* GetInstance();
NS_DECL_ISUPPORTS
virtual ~nsRepeatService();
protected:
nsRepeatService();
private:
nsCOMPtr<nsITimerCallback> mCallback;
nsCOMPtr<nsITimer> mRepeatTimer;
static nsRepeatService* gInstance;
}; // class nsRepeatService
#endif

View File

@ -36,6 +36,7 @@
#include "nsXULAtoms.h"
#include "nsIReflowCommand.h"
#include "nsSliderFrame.h"
#include "nsRepeatService.h"
//
// NS_NewToolbarFrame
@ -61,32 +62,68 @@ NS_NewScrollbarButtonFrame ( nsIFrame** aNewFrame )
/*
nsScrollbarButtonFrame::nsScrollbarButtonFrame()
{
}*/
static NS_DEFINE_IID(kITimerCallbackIID, NS_ITIMERCALLBACK_IID);
NS_IMETHODIMP
nsScrollbarButtonFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (aIID.Equals(kITimerCallbackIID)) {
*aInstancePtr = (void*)(nsITimerCallback*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return nsTitledButtonFrame::QueryInterface(aIID, aInstancePtr);
}
*/
NS_IMETHODIMP
nsScrollbarButtonFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
/*
XXX Eric, this seems to be redundant, since titledbutton's handle event
also calls MouseClicked. I'm commenting this out to avoid receiving two
mouse clicked messages - Dave H.
*/
/*
switch (aEvent->message) {
case NS_MOUSE_LEFT_CLICK:
MouseClicked(aPresContext);
break;
}
*/
// XXX hack until handle release is actually called in nsframe.
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 nsTitledButtonFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
NS_IMETHODIMP
nsScrollbarButtonFrame::HandlePress(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
nsRepeatService::GetInstance()->Start(this);
return NS_OK;
}
NS_IMETHODIMP
nsScrollbarButtonFrame::HandleRelease(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
nsRepeatService::GetInstance()->Stop();
return NS_OK;
}
void nsScrollbarButtonFrame::Notify(nsITimer *timer)
{
MouseClicked();
}
void
nsScrollbarButtonFrame::MouseClicked(nsIPresContext& aPresContext)
{
MouseClicked();
}
void
nsScrollbarButtonFrame::MouseClicked()
{
// when we are clicked either increment or decrement the slider position.
@ -111,7 +148,7 @@ nsScrollbarButtonFrame::MouseClicked(nsIPresContext& aPresContext)
PRInt32 increment = nsSliderFrame::GetIncrement(content);
nsString value;
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::kClass, value))
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, value))
{
// if our class is DecrementButton subtract the current pos by increment amount
// if our class is IncrementButton increment the current pos by the decrement amount

View File

@ -28,10 +28,12 @@
#define nsScrollbarButtonFrame_h___
#include "nsTitledButtonFrame.h"
#include "nsITimerCallback.h"
class nsSliderFrame;
class nsScrollbarButtonFrame : public nsTitledButtonFrame
class nsScrollbarButtonFrame : public nsTitledButtonFrame,
nsITimerCallback
{
public:
@ -45,8 +47,32 @@ public:
static nsresult GetChildWithTag(nsIAtom* atom, nsIFrame* start, nsIFrame*& result);
static nsresult GetParentWithTag(nsIAtom* atom, nsIFrame* start, nsIFrame*& result);
NS_IMETHOD HandlePress(nsIPresContext& aPresContext,
nsGUIEvent * aEvent,
nsEventStatus& aEventStatus);
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);
virtual void Notify(nsITimer *timer);
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_IMETHOD_(nsrefcnt) AddRef(void) { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release(void) { return NS_OK; }
protected:
virtual void MouseClicked(nsIPresContext& aPresContext);
virtual void MouseClicked();
}; // class nsTabFrame

View File

@ -29,12 +29,208 @@
#include "nsXULAtoms.h"
#include "nsHTMLAtoms.h"
#include "nsISupportsArray.h"
#include "nsIDOMElement.h"
#include "nsIDOMDocument.h"
#include "nsDocument.h"
#include "nsXULAtoms.h"
#include "nsHTMLAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsIXMLContent.h"
#include "nsIDOMDocument.h"
#include "nsIDocument.h"
#include "nsIDOMElement.h"
#include "nsXMLElement.h"
#include "nsIStyledContent.h"
#include "nsGenericElement.h"
#include "nsIStyleRule.h"
#include "nsHTMLValue.h"
#include "nsIAnonymousContent.h"
static NS_DEFINE_IID(kIAnonymousContentCreatorIID, NS_IANONYMOUS_CONTENT_CREATOR_IID);
static NS_DEFINE_IID(kIStyledContentIID, NS_ISTYLEDCONTENT_IID);
static NS_DEFINE_IID(kIAnonymousContentIID, NS_IANONYMOUS_CONTENT_IID);
class AnonymousElement : public nsXMLElement, nsIStyledContent, nsIAnonymousContent
{
public:
AnonymousElement(nsIAtom *aTag):nsXMLElement(aTag) {}
// nsIStyledContent
NS_IMETHOD GetID(nsIAtom*& aResult) const;
NS_IMETHOD GetClasses(nsVoidArray& aArray) const;
NS_IMETHOD HasClass(nsIAtom* aClass) const;
NS_IMETHOD GetContentStyleRules(nsISupportsArray* aRules);
NS_IMETHOD GetInlineStyleRules(nsISupportsArray* aRules);
NS_IMETHOD GetMappedAttributeImpact(const nsIAtom* aAttribute,
PRInt32& aHint) const;
// nsISupports
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
NS_IMPL_ICONTENT_USING_GENERIC(mInner)
// NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner)
};
/*
NS_IMETHODIMP
AnonymousElement::GetTag(nsIAtom*& aResult) const
{
return mInner.GetTag(aResult);
}
NS_IMETHODIMP
AnonymousElement::List(FILE* out, PRInt32 aIndent) const
{
NS_PRECONDITION(nsnull != mInner.mDocument, "bad content");
PRInt32 indx;
for (indx = aIndent; --indx >= 0; ) fputs(" ", out);
fprintf(out, "Comment refcount=%d<", mRefCnt);
nsAutoString tmp;
mInner.ToCString(tmp, 0, mInner.mText.GetLength());
fputs(tmp, out);
fputs(">\n", out);
return mInner.List(out, aIndent);
}
*/
NS_IMETHODIMP
AnonymousElement::HandleDOMEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus& aEventStatus)
{
// if our parent is not anonymous then we don't want to bubble the event
// so lets set our parent in nsnull to prevent it. Then we will set it
// back.
nsIContent* parent = nsnull;
GetParent(parent);
nsCOMPtr<nsIAnonymousContent> anonymousParent(do_QueryInterface(parent));
if (!anonymousParent)
SetParent(nsnull);
nsresult rv = mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
if (!anonymousParent)
SetParent(parent);
return rv;
}
// nsIStyledContent Implementation
NS_IMETHODIMP
AnonymousElement::GetID(nsIAtom*& aResult) const
{
/*
nsAutoString value;
GetAttribute(kNameSpaceID_None, kIdAtom, value);
aResult = NS_NewAtom(value); // The NewAtom call does the AddRef.
*/
return NS_OK;
}
NS_IMETHODIMP
AnonymousElement::GetClasses(nsVoidArray& aArray) const
{
return NS_OK;
}
NS_IMETHODIMP
AnonymousElement::HasClass(nsIAtom* aClass) const
{
return NS_OK;
}
NS_IMETHODIMP
AnonymousElement::GetContentStyleRules(nsISupportsArray* aRules)
{
return NS_OK;
}
NS_IMETHODIMP
AnonymousElement::GetInlineStyleRules(nsISupportsArray* aRules)
{
// we don't currently support the style attribute
return NS_OK;
}
NS_IMETHODIMP
AnonymousElement::GetMappedAttributeImpact(const nsIAtom* aAttribute,
PRInt32& aHint) const
{
aHint = NS_STYLE_HINT_CONTENT; // we never map attribtes to style
return NS_OK;
}
NS_IMETHODIMP
AnonymousElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (aIID.Equals(kIStyledContentIID)) {
nsIStyledContent* tmp = this;
*aInstancePtr = (void*) tmp;
return NS_OK;
} else if (aIID.Equals(kIAnonymousContentIID)) {
nsIAnonymousContent* tmp = this;
*aInstancePtr = (void*) tmp;
return NS_OK;
}
return nsXMLElement::QueryInterface(aIID, aInstancePtr);
}
nsresult NS_CreateAnonymousNode(nsIContent* aParent, nsIAtom* aTag, PRInt32 aNameSpaceId, nsCOMPtr<nsIContent>& aNewNode)
{
// get the document
nsIDocument* document = nsnull;
aParent->GetDocument(document);
// create the xml element
nsCOMPtr<nsIXMLContent> content;
//NS_NewXMLElement(getter_AddRefs(content), aTag);
content = new AnonymousElement(aTag);
content->SetNameSpaceID(aNameSpaceId);
// set the document
content->SetDocument(document, PR_TRUE);
aNewNode = content;
/*
nsCOMPtr<nsIDocument> document;
aParent->GetDocument(*getter_AddRefs(document));
nsCOMPtr<nsIDOMDocument> domDocument(do_QueryInterface(document));
nsCOMPtr<nsIDOMElement> element;
nsString name;
aTag->ToString(name);
domDocument->CreateElement(name, getter_AddRefs(element));
aNewNode = do_QueryInterface(element);
*/
return NS_OK;
}
//
// NS_NewToolbarFrame
@ -68,37 +264,27 @@ nsScrollbarFrame::CreateAnonymousContent(nsISupportsArray& aAnonymousChildren)
mContent->ChildCount(count);
if (count == 0) {
// get the document
nsCOMPtr<nsIDocument> idocument;
mContent->GetDocument(*getter_AddRefs(idocument));
nsCOMPtr<nsIDOMDocument> document(do_QueryInterface(idocument));
// create a decrement button
nsCOMPtr<nsIDOMElement> node;
document->CreateElement("scrollbarbutton",getter_AddRefs(node));
nsCOMPtr<nsIContent> content;
content = do_QueryInterface(node);
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::kClass, "decrement", PR_TRUE);
NS_CreateAnonymousNode(mContent, nsXULAtoms::scrollbarbutton, nsXULAtoms::nameSpaceID, content);
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, "decrement", PR_FALSE);
aAnonymousChildren.AppendElement(content);
// a slider
document->CreateElement("slider",getter_AddRefs(node));
content = do_QueryInterface(node);
content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_TRUE);
NS_CreateAnonymousNode(mContent, nsXULAtoms::slider, nsXULAtoms::nameSpaceID, content);
content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_FALSE);
aAnonymousChildren.AppendElement(content);
// and increment button
document->CreateElement("scrollbarbutton",getter_AddRefs(node));
content = do_QueryInterface(node);
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::kClass, "increment", PR_TRUE);
NS_CreateAnonymousNode(mContent, nsXULAtoms::scrollbarbutton, nsXULAtoms::nameSpaceID, content);
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, "increment", PR_FALSE);
aAnonymousChildren.AppendElement(content);
}
return NS_OK;
}
NS_IMETHODIMP
nsScrollbarFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
@ -108,7 +294,10 @@ nsScrollbarFrame::AttributeChanged(nsIPresContext* aPresContext,
nsresult rv = nsBoxFrame::AttributeChanged(aPresContext, aChild,
aAttribute, aHint);
// if the current position changes
if (aAttribute == nsXULAtoms::curpos) {
if ( aAttribute == nsXULAtoms::curpos ||
aAttribute == nsXULAtoms::maxpos ||
aAttribute == nsXULAtoms::pageincrement ||
aAttribute == nsXULAtoms::increment) {
// tell the slider its attribute changed so it can
// update itself
nsIFrame* slider;
@ -135,6 +324,44 @@ nsScrollbarFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
return NS_OK;
}
if (aIID.Equals(kIStyledContentIID)) {
*aInstancePtr = (void*)(nsIStyledContent*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return nsBoxFrame::QueryInterface(aIID, aInstancePtr);
}
NS_IMETHODIMP
nsScrollbarFrame::HandlePress(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
return NS_OK;
}
NS_IMETHODIMP
nsScrollbarFrame::HandleMultiplePress(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
return NS_OK;
}
NS_IMETHODIMP
nsScrollbarFrame::HandleDrag(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
return NS_OK;
}
NS_IMETHODIMP
nsScrollbarFrame::HandleRelease(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
return NS_OK;
}

View File

@ -55,6 +55,24 @@ public:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
NS_IMETHOD HandlePress(nsIPresContext& aPresContext,
nsGUIEvent * aEvent,
nsEventStatus& aEventStatus);
NS_IMETHOD HandleMultiplePress(nsIPresContext& aPresContext,
nsGUIEvent * aEvent,
nsEventStatus& aEventStatus);
NS_IMETHOD HandleDrag(nsIPresContext& aPresContext,
nsGUIEvent * aEvent,
nsEventStatus& aEventStatus);
NS_IMETHOD HandleRelease(nsIPresContext& aPresContext,
nsGUIEvent * aEvent,
nsEventStatus& aEventStatus);
}; // class nsScrollbarFrame
#endif

View File

@ -42,16 +42,23 @@
#include "nsHTMLAtoms.h"
#include "nsIDOMEventReceiver.h"
#include "nsIViewManager.h"
#include "nsIDOMElement.h"
#include "nsIDOMDocument.h"
#include "nsIDOMUIEvent.h"
#include "nsDocument.h"
#include "nsTitledButtonFrame.h"
#include "nsScrollbarButtonFrame.h"
#include "nsIScrollbarListener.h"
#include "nsISupportsArray.h"
#include "nsIXMLContent.h"
#include "nsXULAtoms.h"
#include "nsHTMLAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsIScrollableView.h"
#include "nsRepeatService.h"
nscoord nsSliderFrame::gChange = 0;
static NS_DEFINE_IID(kIAnonymousContentCreatorIID, NS_IANONYMOUS_CONTENT_CREATOR_IID);
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
nsresult
NS_NewSliderFrame ( nsIFrame** aNewFrame)
@ -74,6 +81,14 @@ nsSliderFrame::nsSliderFrame()
{
}
// stop timer
nsSliderFrame::~nsSliderFrame()
{
}
nsresult NS_CreateAnonymousNode(nsIContent* aParent, nsIAtom* aTag, PRInt32 aNameSpaceId, nsCOMPtr<nsIContent>& aNewNode);
/**
* Anonymous interface
*/
@ -85,24 +100,20 @@ nsSliderFrame::CreateAnonymousContent(nsISupportsArray& aAnonymousChildren)
mContent->ChildCount(count);
if (count == 0)
{
// get the document
nsCOMPtr<nsIDocument> idocument;
mContent->GetDocument(*getter_AddRefs(idocument));
nsCOMPtr<nsIDOMDocument> document(do_QueryInterface(idocument));
// create a thumb
nsCOMPtr<nsIDOMElement> node;
document->CreateElement("thumb",getter_AddRefs(node));
nsCOMPtr<nsIContent> content;
content = do_QueryInterface(node);
NS_CreateAnonymousNode(mContent, nsXULAtoms::thumb, nsXULAtoms::nameSpaceID, content);
content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, "horizontal", PR_FALSE);
// if we are not in a scrollbar default our thumbs flex to be
// flexible.
nsIContent* scrollbar = GetScrollBar();
if (scrollbar)
content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_TRUE);
if (scrollbar) {
content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_FALSE);
nsString value;
if (NS_CONTENT_ATTR_HAS_VALUE == scrollbar->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value))
mContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value, PR_FALSE);
}
aAnonymousChildren.AppendElement(content);
}
@ -121,6 +132,9 @@ nsSliderFrame::Init(nsIPresContext& aPresContext,
{
nsresult rv = nsHTMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
CreateViewForFrame(aPresContext,this,aContext,PR_TRUE);
nsIView* view;
GetView(&view);
view->SetContentTransparency(PR_TRUE);
return rv;
}
@ -176,6 +190,17 @@ nsSliderFrame::AttributeChanged(nsIPresContext* aPresContext,
// if the current position changes
if (aAttribute == nsXULAtoms::curpos) {
CurrentPositionChanged(aPresContext);
} else if (aAttribute == nsXULAtoms::maxpos ||
aAttribute == nsXULAtoms::pageincrement ||
aAttribute == nsXULAtoms::increment) {
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
nsCOMPtr<nsIReflowCommand> reflowCmd;
nsresult rv = NS_NewHTMLReflowCommand(getter_AddRefs(reflowCmd), this,
nsIReflowCommand::StyleChanged);
if (NS_SUCCEEDED(rv))
shell->AppendReflowCommand(reflowCmd);
}
return rv;
@ -187,6 +212,32 @@ nsSliderFrame::Paint(nsIPresContext& aPresContext,
const nsRect& aDirtyRect,
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!!!!");
nsSize size(0,0);
thumbFrame->GetSize(size);
if (mRect.width < size.width || mRect.height < size.height)
{
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->mVisible) {
const nsStyleColor* myColor = (const nsStyleColor*)
mStyleContext->GetStyleData(eStyleStruct_Color);
const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)
mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsRect rect(0, 0, mRect.width, mRect.height);
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
aDirtyRect, rect, *myColor, *mySpacing, 0, 0);
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
aDirtyRect, rect, *mySpacing, mStyleContext, 0);
}
}
return NS_OK;
}
return nsHTMLContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
@ -266,13 +317,13 @@ nsSliderFrame::Reflow(nsIPresContext& aPresContext,
ReflowThumb(aPresContext, thumbSize, aReflowState, aStatus, thumbFrame, availableSize, computedSize);
// get our current position and max position from our content node
PRInt32 curpos = GetCurrentPosition(scrollbar);
PRInt32 maxpos = GetMaxPosition(scrollbar);
PRInt32 curpospx = GetCurrentPosition(scrollbar);
PRInt32 maxpospx = GetMaxPosition(scrollbar);
if (curpos < 0)
curpos = 0;
else if (curpos > maxpos)
curpos = maxpos;
if (curpospx < 0)
curpospx = 0;
else if (curpospx > maxpospx)
curpospx = maxpospx;
// if the computed height we are given is intrinsic then set it to some default height
float p2t;
@ -283,8 +334,8 @@ nsSliderFrame::Reflow(nsIPresContext& aPresContext,
aDesiredSize.height = isHorizontal ? thumbSize.height : 200*onePixel;
else {
aDesiredSize.height = aReflowState.mComputedHeight;
if (aDesiredSize.height < thumbSize.height)
aDesiredSize.height = thumbSize.height;
// if (aDesiredSize.height < thumbSize.height)
// aDesiredSize.height = thumbSize.height;
}
// set the width to the computed or if intrinsic then the width of the thumb.
@ -292,33 +343,26 @@ nsSliderFrame::Reflow(nsIPresContext& aPresContext,
aDesiredSize.width = isHorizontal ? 200*onePixel : thumbSize.width;
else {
aDesiredSize.width = aReflowState.mComputedWidth;
if (aDesiredSize.width < thumbSize.width)
aDesiredSize.width = thumbSize.width;
// if (aDesiredSize.width < thumbSize.width)
// aDesiredSize.width = thumbSize.width;
}
// convert the set max size to pixels
nscoord maxpospx = maxpos * onePixel;
// get max pos in twips
nscoord maxpos = maxpospx*onePixel;
// get our maxpos in pixels. This is the space we have left over in the scrollbar
// 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& thumbcoord = isHorizontal ? thumbSize.width : thumbSize.height;
nscoord ourmaxpospx = desiredcoord - thumbcoord; // maxpos in pixels
mRatio = 1.0;
nscoord ourmaxpos = desiredcoord;
// now if we remove the max positon we now know the difference in pixels between the
// 2 and can create a ratio between them.
nscoord diffpx = ourmaxpospx - maxpospx;
mRatio = float(ourmaxpos)/float(maxpos + ourmaxpos);
// create a variable called ratio set it to 1.
// 1) If the above subtraction is 0 do nothing
// 2) If less than 0 then make the ratio squash it
// 3) If greater than 0 try to reflow the thumb to that height. Take what ever
// height that was returned and us it to calculate the ratio.
if (diffpx < 0)
mRatio = float(ourmaxpospx)/float(maxpospx);
else if (diffpx > 0) {
nscoord thumbsize = nscoord(ourmaxpos * mRatio);
// if there is more room than the thumb need stretch the
// thumb
if (thumbsize > thumbcoord) {
// if the thumb is flexible make the thumb bigger.
nsCOMPtr<nsIContent> content;
thumbFrame->GetContent(getter_AddRefs(content));
@ -331,31 +375,31 @@ nsSliderFrame::Reflow(nsIPresContext& aPresContext,
// convert to a percent.
if (value.ToFloat(&error) > 0.0) {
if (isHorizontal)
computedSize.width = diffpx+thumbcoord;
computedSize.width = thumbsize;
else
computedSize.height = diffpx+thumbcoord;
computedSize.height = thumbsize;
ReflowThumb(aPresContext, thumbSize, aReflowState, aStatus, thumbFrame, availableSize, computedSize);
ourmaxpospx = desiredcoord - thumbcoord; // recalc ourmaxpospx
}
}
mRatio = float(ourmaxpospx)/float(maxpospx);
} else {
ourmaxpos -= thumbcoord;
mRatio = float(ourmaxpos)/float(maxpos);
}
// get our border
const nsMargin& borderPadding = aReflowState.mComputedBorderPadding;
nscoord curpospx = curpos*onePixel;
nscoord curpos = curpospx*onePixel;
// set the thumbs y coord to be the current pos * the ratio.
nscoord pospx = nscoord(float(curpospx)*mRatio);
nscoord pos = nscoord(float(curpos)*mRatio);
nsRect thumbRect(borderPadding.left, borderPadding.top, thumbSize.width, thumbSize.height);
if (isHorizontal)
thumbRect.x += pospx;
thumbRect.x += pos;
else
thumbRect.y += pospx;
thumbRect.y += pos;
thumbFrame->SetRect(thumbRect);
@ -379,7 +423,7 @@ nsSliderFrame::HandleEvent(nsIPresContext& aPresContext,
PRBool isHorizontal = IsHorizontal(scrollbar);
if (isCapturingEvents())
if (isDraggingThumb())
{
switch (aEvent->message) {
case NS_MOUSE_MOVE: {
@ -399,10 +443,26 @@ nsSliderFrame::HandleEvent(nsIPresContext& aPresContext,
nsIFrame* thumbFrame = mFrames.FirstChild();
// get it into our coordintate system by subtracting our parents offsets.
nsIFrame* parent = this;
while(parent != nsnull)
{
// if we hit a scrollable view make sure we take into account
// how much we are scrolled.
nsIScrollableView* scrollingView;
nsIView* view;
parent->GetView(&view);
if (view) {
nsresult result = view->QueryInterface(kScrollViewIID, (void**)&scrollingView);
if (NS_SUCCEEDED(result)) {
nscoord xoff = 0;
nscoord yoff = 0;
scrollingView->GetScrollPosition(xoff, yoff);
isHorizontal ? start += xoff : start += yoff;
}
}
nsRect r;
parent->GetRect(r);
isHorizontal ? start -= r.x : start -= r.y;
@ -423,66 +483,31 @@ nsSliderFrame::HandleEvent(nsIPresContext& aPresContext,
pospx = nscoord(pospx/mRatio);
// set it
SetCurrentPosition(aPresContext, scrollbar, thumbFrame, pospx);
SetCurrentPosition(scrollbar, thumbFrame, pospx);
}
break;
case NS_MOUSE_RIGHT_BUTTON_UP:
case NS_MOUSE_LEFT_BUTTON_UP:
// stop capturing
//printf("stop capturing\n");
nsIFrame* thumbFrame = mFrames.FirstChild();
AddListener();
CaptureMouseEvents(PR_FALSE);
DragThumb(PR_FALSE);
}
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
//return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
return NS_OK;
}
nsIFrame* thumbFrame = mFrames.FirstChild();
nsRect thumbRect;
thumbFrame->GetRect(thumbRect);
// XXX hack until handle release is actually called in nsframe.
if (aEvent->message == NS_MOUSE_EXIT|| aEvent->message == NS_MOUSE_RIGHT_BUTTON_UP || aEvent->message == NS_MOUSE_LEFT_BUTTON_UP)
HandleRelease(aPresContext, aEvent, aEventStatus);
if (thumbRect.Contains(aEvent->point))
{
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
// on a mouse press grab the cursor
// if the cursor moves up or down by n pixels divide them by the ratio and add or subtract them from from
// the current pos. Do bounds checking, make sure the current pos is greater or equal to 0 and less that max pos.
// redraw
break;
}
return nsHTMLContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
// on release stop grabbing.
} else if ((isHorizontal && aEvent->point.x < thumbRect.x) || (!isHorizontal && aEvent->point.y < thumbRect.y)) {
// if the mouse is above the thumb
// on a left mouse press
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
// decrease the current pos by the page size
PageUpDown(aPresContext, thumbFrame, -1);
break;
}
} else {
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
// increase the current pos by the page size
PageUpDown(aPresContext, thumbFrame, 1);
break;
}
}
// don't invoke any sort of dragging or selection code.
return NS_OK; //nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
NS_IMETHODIMP nsSliderFrame::HandleDrag(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
return NS_OK;
}
nsIContent*
nsSliderFrame::GetScrollBar()
@ -502,7 +527,7 @@ nsSliderFrame::GetScrollBar()
}
void
nsSliderFrame::PageUpDown(nsIPresContext& aPresContext, nsIFrame* aThumbFrame, nscoord change)
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
@ -514,7 +539,7 @@ nsSliderFrame::PageUpDown(nsIPresContext& aPresContext, nsIFrame* aThumbFrame, n
nscoord pageIncrement = GetPageIncrement(scrollbar);
PRInt32 curpos = GetCurrentPosition(scrollbar);
SetCurrentPosition(aPresContext, scrollbar, aThumbFrame, curpos + change*pageIncrement);
SetCurrentPosition(scrollbar, aThumbFrame, curpos + change*pageIncrement);
}
// called when the current position changed and we need to update the thumb's location
@ -582,13 +607,9 @@ nsSliderFrame::CurrentPositionChanged(nsIPresContext* aPresContext)
}
void
nsSliderFrame::SetCurrentPosition(nsIPresContext& aPresContext, nsIContent* scrollbar, nsIFrame* aThumbFrame, nscoord newpos)
nsSliderFrame::SetCurrentPosition(nsIContent* scrollbar, nsIFrame* aThumbFrame, nscoord newpos)
{
float p2t;
aPresContext.GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
// get our current position and max position from our content node
PRInt32 curpos = GetCurrentPosition(scrollbar);
PRInt32 maxpos = GetMaxPosition(scrollbar);
@ -605,14 +626,14 @@ nsSliderFrame::SetCurrentPosition(nsIPresContext& aPresContext, nsIContent* scro
// set the new position
scrollbar->SetAttribute(kNameSpaceID_None, nsXULAtoms::curpos, nsString(ch), PR_TRUE);
//printf("Current Pos=%d\n",newpos);
printf("Current Pos=%s\n",ch);
}
NS_IMETHODIMP nsSliderFrame::GetFrameForPoint(const nsPoint& aPoint,
nsIFrame** aFrame)
{
if (isCapturingEvents())
if (isDraggingThumb())
{
*aFrame = this;
return NS_OK;
@ -695,7 +716,7 @@ nsSliderFrame::MouseDown(nsIDOMEvent* aMouseEvent)
nsCOMPtr<nsIDOMUIEvent> uiEvent(do_QueryInterface(aMouseEvent));
RemoveListener();
CaptureMouseEvents(PR_TRUE);
DragThumb(PR_TRUE);
PRInt32 c = 0;
if (isHorizontal)
uiEvent->GetClientX(&c);
@ -721,11 +742,12 @@ nsresult
nsSliderFrame::MouseUp(nsIDOMEvent* aMouseEvent)
{
// printf("Finish dragging\n");
return NS_OK;
}
NS_IMETHODIMP
nsSliderFrame :: CaptureMouseEvents(PRBool aGrabMouseEvents)
nsSliderFrame :: DragThumb(PRBool aGrabMouseEvents)
{
// get its view
nsIView* view = nsnull;
@ -749,7 +771,7 @@ nsSliderFrame :: CaptureMouseEvents(PRBool aGrabMouseEvents)
}
PRBool
nsSliderFrame :: isCapturingEvents()
nsSliderFrame :: isDraggingThumb()
{
// get its view
nsIView* view = nsnull;
@ -794,6 +816,8 @@ nsSliderFrame::RemoveListener()
reciever->RemoveEventListenerByIID(this,kIDOMMouseListenerIID);
}
static NS_DEFINE_IID(kITimerCallbackIID, NS_ITIMERCALLBACK_IID);
NS_IMETHODIMP nsSliderFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
@ -811,6 +835,10 @@ NS_IMETHODIMP nsSliderFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
*aInstancePtr = (void*)(nsIDOMMouseListener*) this;
NS_ADDREF_THIS();
return NS_OK;
} else if (aIID.Equals(kITimerCallbackIID)) {
*aInstancePtr = (void*)(nsITimerCallback*) this;
NS_ADDREF_THIS();
return NS_OK;
}
return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
@ -828,9 +856,95 @@ nsSliderFrame::Release(void)
return NS_OK;
}
NS_IMETHODIMP
nsSliderFrame::HandlePress(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
nsIContent* scrollbar = GetScrollBar();
PRBool isHorizontal = IsHorizontal(scrollbar);
nsIFrame* thumbFrame = mFrames.FirstChild();
nsRect thumbRect;
thumbFrame->GetRect(thumbRect);
nscoord change = 1;
if ((isHorizontal && aEvent->point.x < thumbRect.x) || (!isHorizontal && aEvent->point.y < thumbRect.y))
change = -1;
gChange = change;
nsRepeatService::GetInstance()->Start(this);
PageUpDown(thumbFrame, change);
return NS_OK;
}
NS_IMETHODIMP
nsSliderFrame::HandleRelease(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
nsRepeatService::GetInstance()->Stop();
return NS_OK;
}
void
nsSliderFrame::SetScrollbarListener(nsIScrollbarListener* aListener)
{
// Don't addref/release this, since it's actually a frame.
mScrollbarListener = aListener;
}
void nsSliderFrame::Notify(nsITimer *timer)
{
nsIFrame* thumbFrame = mFrames.FirstChild();
PageUpDown(thumbFrame, gChange);
}
class nsThumbFrame : public nsTitledButtonFrame
{
public:
friend nsresult NS_NewThumbFrame(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; }
};
nsresult
NS_NewThumbFrame ( nsIFrame** aNewFrame)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsThumbFrame* it = new nsThumbFrame();
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
*aNewFrame = it;
return NS_OK;
} // NS_NewSliderFrame

View File

@ -30,20 +30,27 @@
#include "nsCOMPtr.h"
#include "nsIDOMMouseListener.h"
#include "nsIAnonymousContentCreator.h"
#include "nsITimerCallback.h"
class nsString;
class nsIScrollbarListener;
class nsISupportsArray;
class nsITimer;
#define INITAL_REPEAT_DELAY 500
#define REPEAT_DELAY 50
nsresult NS_NewSliderFrame(nsIFrame** aResult) ;
class nsSliderFrame : public nsHTMLContainerFrame,
nsIDOMMouseListener,
nsIAnonymousContentCreator
nsIAnonymousContentCreator,
nsITimerCallback
{
public:
nsSliderFrame();
virtual ~nsSliderFrame();
// nsIFrame overrides
NS_IMETHOD GetFrameName(nsString& aResult) const {
@ -75,10 +82,6 @@ public:
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD HandleDrag(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
@ -106,7 +109,7 @@ public:
nsIAtom* aListName,
nsIFrame* aChildList);
/**
/**
* Processes a mouse down event
* @param aMouseEvent @see nsIDOMEvent.h
* @returns whether the event was consumed or ignored. @see nsresult
@ -165,6 +168,25 @@ public:
void SetScrollbarListener(nsIScrollbarListener* aListener);
NS_IMETHOD HandlePress(nsIPresContext& aPresContext,
nsGUIEvent * aEvent,
nsEventStatus& aEventStatus);
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);
virtual void Notify(nsITimer *timer);
protected:
virtual void ReflowThumb(nsIPresContext& aPresContext,
@ -177,15 +199,16 @@ protected:
virtual PRIntn GetSkipSides() const { return 0; }
private:
nsIContent* GetScrollBar();
void PageUpDown(nsIPresContext& aPresContext, nsIFrame* aThumbFrame, nscoord change);
void SetCurrentPosition(nsIPresContext& aPresContext, nsIContent* scrollbar, nsIFrame* aThumbFrame, nscoord pos);
NS_IMETHOD CaptureMouseEvents(PRBool aGrabMouseEvents);
void PageUpDown(nsIFrame* aThumbFrame, nscoord change);
void SetCurrentPosition(nsIContent* scrollbar, nsIFrame* aThumbFrame, nscoord pos);
NS_IMETHOD DragThumb(PRBool aGrabMouseEvents);
void AddListener();
void RemoveListener();
PRBool isCapturingEvents();
PRBool isDraggingThumb();
float mRatio;
@ -196,6 +219,7 @@ private:
nsIScrollbarListener* mScrollbarListener;
static nscoord gChange;
}; // class nsSliderFrame
#endif

View File

@ -58,6 +58,8 @@ NS_NewSplitterFrame ( nsIFrame** aNewFrame )
} // NS_NewSplitterFrame
nsresult NS_CreateAnonymousNode(nsIContent* aParent, nsIAtom* aTag, PRInt32 aNameSpaceId, nsCOMPtr<nsIContent>& aNewNode);
/**
* Anonymous interface
*/
@ -69,31 +71,19 @@ nsSplitterFrame::CreateAnonymousContent(nsISupportsArray& aAnonymousChildren)
mContent->ChildCount(count);
if (count == 0) {
// get the document
nsCOMPtr<nsIDocument> idocument;
mContent->GetDocument(*getter_AddRefs(idocument));
nsCOMPtr<nsIDOMDocument> document(do_QueryInterface(idocument));
// create a spring
nsCOMPtr<nsIDOMElement> node;
document->CreateElement("spring",getter_AddRefs(node));
nsCOMPtr<nsIXMLContent> content;
content = do_QueryInterface(node);
content->SetNameSpaceID(nsXULAtoms::nameSpaceID);
content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_TRUE);
nsCOMPtr<nsIContent> content;
NS_CreateAnonymousNode(mContent, nsXULAtoms::spring, nsXULAtoms::nameSpaceID, content);
content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_FALSE);
aAnonymousChildren.AppendElement(content);
// a grippy
document->CreateElement("grippy",getter_AddRefs(node));
content = do_QueryInterface(node);
content->SetNameSpaceID(nsXULAtoms::nameSpaceID);
NS_CreateAnonymousNode(mContent, nsXULAtoms::grippy, nsXULAtoms::nameSpaceID, content);
aAnonymousChildren.AppendElement(content);
// create a spring
document->CreateElement("spring",getter_AddRefs(node));
content = do_QueryInterface(node);
content->SetNameSpaceID(nsXULAtoms::nameSpaceID);
content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_TRUE);
NS_CreateAnonymousNode(mContent, nsXULAtoms::spring, nsXULAtoms::nameSpaceID, content);
content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_FALSE);
aAnonymousChildren.AppendElement(content);
}

View File

@ -86,6 +86,7 @@ XUL_ATOM(crop, "crop")
XUL_ATOM(mode, "mode")
XUL_ATOM(box, "box")
XUL_ATOM(flex, "flex")
XUL_ATOM(spring, "spring")
XUL_ATOM(deck, "deck")
XUL_ATOM(tabcontrol, "tabcontrol")

View File

@ -943,47 +943,48 @@ NS_IMETHODIMP nsScrollingView::ComputeScrollOffsets(PRBool aAdjustWidgets)
mVScrollBarView->GetWidget(win);
if (NS_OK == win->QueryInterface(kIScrollbarIID, (void **)&scrollv)) {
if ((mSizeY > (controlRect.height - ((nsnull != scrollh) ? hheight : 0))) &&
(mScrollPref != nsScrollPreference_kNeverScroll)) {
//we need to be able to scroll
if ((mSizeY > (controlRect.height - ((nsnull != scrollh) ? hheight : 0)))) {
// if we are scrollable
if (mScrollPref != nsScrollPreference_kNeverScroll) {
//we need to be able to scroll
((ScrollBarView *)mVScrollBarView)->SetEnabled(PR_TRUE);
win->Enable(PR_TRUE);
((ScrollBarView *)mVScrollBarView)->SetEnabled(PR_TRUE);
win->Enable(PR_TRUE);
//now update the scroller position for the new size
//now update the scroller position for the new size
PRUint32 oldpos = 0;
float p2t;
PRInt32 availheight;
PRUint32 oldpos = 0;
float p2t;
PRInt32 availheight;
scrollv->GetPosition(oldpos);
px->GetDevUnitsToAppUnits(p2t);
scrollv->GetPosition(oldpos);
px->GetDevUnitsToAppUnits(p2t);
availheight = controlRect.height - ((nsnull != scrollh) ? hheight : 0);
availheight = controlRect.height - ((nsnull != scrollh) ? hheight : 0);
// XXX Check for 0 initial size. This is really indicative
// of a problem.
if (0 == oldsizey)
mOffsetY = 0;
else
{
mOffsetY = NSIntPixelsToTwips(NSTwipsToIntPixels(nscoord(((float)oldpos * mSizeY) / oldsizey), scale), p2t);
if ((mSizeY - mOffsetY) < availheight)
// XXX Check for 0 initial size. This is really indicative
// of a problem.
if (0 == oldsizey)
mOffsetY = 0;
else
{
mOffsetY = mSizeY - availheight;
mOffsetY = NSIntPixelsToTwips(NSTwipsToIntPixels(nscoord(((float)oldpos * mSizeY) / oldsizey), scale), p2t);
if (mOffsetY < 0)
mOffsetY = 0;
if ((mSizeY - mOffsetY) < availheight)
{
mOffsetY = mSizeY - availheight;
if (mOffsetY < 0)
mOffsetY = 0;
}
}
dy = NSTwipsToIntPixels((offy - mOffsetY), scale);
scrollv->SetParameters(mSizeY, availheight,
mOffsetY, mLineHeight);
}
dy = NSTwipsToIntPixels((offy - mOffsetY), scale);
scrollv->SetParameters(mSizeY, availheight,
mOffsetY, mLineHeight);
}
else
} else
{
// The scrolled view is entirely visible vertically. Either hide the
// vertical scrollbar or disable it
@ -1019,48 +1020,47 @@ NS_IMETHODIMP nsScrollingView::ComputeScrollOffsets(PRBool aAdjustWidgets)
mHScrollBarView->GetWidget(win);
if (NS_OK == win->QueryInterface(kIScrollbarIID, (void **)&scrollh)) {
if ((mSizeX > (controlRect.width - ((nsnull != scrollv) ? vwidth : 0))) &&
(mScrollPref != nsScrollPreference_kNeverScroll)) {
//we need to be able to scroll
if ((mSizeX > (controlRect.width - ((nsnull != scrollv) ? vwidth : 0)))) {
if (mScrollPref != nsScrollPreference_kNeverScroll) {
//we need to be able to scroll
((ScrollBarView *)mHScrollBarView)->SetEnabled(PR_TRUE);
win->Enable(PR_TRUE);
((ScrollBarView *)mHScrollBarView)->SetEnabled(PR_TRUE);
win->Enable(PR_TRUE);
//now update the scroller position for the new size
//now update the scroller position for the new size
PRUint32 oldpos = 0;
float p2t;
PRInt32 availwidth;
PRUint32 oldpos = 0;
float p2t;
PRInt32 availwidth;
scrollh->GetPosition(oldpos);
px->GetDevUnitsToAppUnits(p2t);
scrollh->GetPosition(oldpos);
px->GetDevUnitsToAppUnits(p2t);
availwidth = controlRect.width - ((nsnull != scrollv) ? vwidth : 0);
availwidth = controlRect.width - ((nsnull != scrollv) ? vwidth : 0);
// XXX Check for 0 initial size. This is really indicative
// of a problem.
if (0 == oldsizex)
mOffsetX = 0;
else
{
mOffsetX = NSIntPixelsToTwips(NSTwipsToIntPixels(nscoord(((float)oldpos * mSizeX) / oldsizex), scale), p2t);
if ((mSizeX - mOffsetX) < availwidth)
// XXX Check for 0 initial size. This is really indicative
// of a problem.
if (0 == oldsizex)
mOffsetX = 0;
else
{
mOffsetX = mSizeX - availwidth;
mOffsetX = NSIntPixelsToTwips(NSTwipsToIntPixels(nscoord(((float)oldpos * mSizeX) / oldsizex), scale), p2t);
if (mOffsetX < 0)
mOffsetX = 0;
if ((mSizeX - mOffsetX) < availwidth)
{
mOffsetX = mSizeX - availwidth;
if (mOffsetX < 0)
mOffsetX = 0;
}
}
dx = NSTwipsToIntPixels((offx - mOffsetX), scale);
scrollh->SetParameters(mSizeX, availwidth,
mOffsetX, mLineHeight);
}
dx = NSTwipsToIntPixels((offx - mOffsetX), scale);
scrollh->SetParameters(mSizeX, availwidth,
mOffsetX, mLineHeight);
}
else
{
} else {
// The scrolled view is entirely visible horizontally. Either hide the
// horizontal scrollbar or disable it
mOffsetX = 0;

View File

@ -615,7 +615,7 @@ void nsViewManager :: RenderViews(nsIView *aRootView, nsIRenderingContext& aRC,
PRBool useopaque = PR_FALSE;
nsRegionRectSet onerect, *rectset;
//printf("begin paint\n");
//printf("-------------begin paint------------\n");
if (aRootView && mRootView)
{
nscoord ox = 0, oy = 0;