зеркало из https://github.com/mozilla/gecko-dev.git
Родитель
95adc8b187
Коммит
969d067559
|
@ -50,7 +50,7 @@ static char* mEventNames[] = {
|
|||
"submit", "reset", "change", "select", "input", "paint" ,"text",
|
||||
"create", "close", "destroy", "command", "broadcast", "commandupdate",
|
||||
"dragenter", "dragover", "dragexit", "dragdrop", "draggesture", "resize",
|
||||
"scroll"
|
||||
"scroll","overflow", "underflow"
|
||||
};
|
||||
|
||||
nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsString& aEventType) {
|
||||
|
@ -311,29 +311,48 @@ nsDOMEvent::GetDetail(PRInt32* aDetail)
|
|||
{
|
||||
//detail is valid for more than just mouseevents but we don't
|
||||
//use it for anything else right now
|
||||
if (!mEvent || mEvent->eventStructType != NS_MOUSE_EVENT) {
|
||||
|
||||
if (!mEvent) {
|
||||
*aDetail = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
switch (mEvent->message) {
|
||||
case NS_MOUSE_LEFT_BUTTON_UP:
|
||||
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
||||
case NS_MOUSE_LEFT_CLICK:
|
||||
case NS_MOUSE_LEFT_DOUBLECLICK:
|
||||
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
||||
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
|
||||
case NS_MOUSE_MIDDLE_CLICK:
|
||||
case NS_MOUSE_MIDDLE_DOUBLECLICK:
|
||||
case NS_MOUSE_RIGHT_BUTTON_UP:
|
||||
case NS_MOUSE_RIGHT_BUTTON_DOWN:
|
||||
case NS_MOUSE_RIGHT_CLICK:
|
||||
case NS_MOUSE_RIGHT_DOUBLECLICK:
|
||||
*aDetail = ((nsMouseEvent*)mEvent)->clickCount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch(mEvent->eventStructType)
|
||||
{
|
||||
case NS_SCROLLPORT_EVENT:
|
||||
{
|
||||
nsScrollPortEvent* scrollEvent = (nsScrollPortEvent*)mEvent;
|
||||
*aDetail = (PRInt32)scrollEvent->orient;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
case NS_MOUSE_EVENT:
|
||||
{
|
||||
switch (mEvent->message) {
|
||||
case NS_MOUSE_LEFT_BUTTON_UP:
|
||||
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
||||
case NS_MOUSE_LEFT_CLICK:
|
||||
case NS_MOUSE_LEFT_DOUBLECLICK:
|
||||
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
||||
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
|
||||
case NS_MOUSE_MIDDLE_CLICK:
|
||||
case NS_MOUSE_MIDDLE_DOUBLECLICK:
|
||||
case NS_MOUSE_RIGHT_BUTTON_UP:
|
||||
case NS_MOUSE_RIGHT_BUTTON_DOWN:
|
||||
case NS_MOUSE_RIGHT_CLICK:
|
||||
case NS_MOUSE_RIGHT_DOUBLECLICK:
|
||||
*aDetail = ((nsMouseEvent*)mEvent)->clickCount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
*aDetail = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1123,6 +1142,10 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
|||
return mEventNames[eDOMEvents_dragdrop];
|
||||
case NS_DRAGDROP_GESTURE:
|
||||
return mEventNames[eDOMEvents_draggesture];
|
||||
case NS_SCROLLPORT_OVERFLOW:
|
||||
return mEventNames[eDOMEvents_overflow];
|
||||
case NS_SCROLLPORT_UNDERFLOW:
|
||||
return mEventNames[eDOMEvents_underflow];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,9 @@ public:
|
|||
eDOMEvents_dragdrop,
|
||||
eDOMEvents_draggesture,
|
||||
eDOMEvents_resize,
|
||||
eDOMEvents_scroll
|
||||
eDOMEvents_scroll,
|
||||
eDOMEvents_overflow,
|
||||
eDOMEvents_underflow
|
||||
};
|
||||
|
||||
nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsString& aEventType);
|
||||
|
|
|
@ -450,6 +450,14 @@ nsresult nsEventListenerManager::GetIdentifiersForType(nsIAtom* aType, nsIID& aI
|
|||
aIID = kIDOMMenuListenerIID;
|
||||
*aFlags = NS_EVENT_BITS_XUL_COMMAND_UPDATE;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onoverflow) {
|
||||
aIID = kIDOMMenuListenerIID;
|
||||
*aFlags = NS_EVENT_BITS_SCROLLPORT_OVERFLOW;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onunderflow) {
|
||||
aIID = kIDOMMenuListenerIID;
|
||||
*aFlags = NS_EVENT_BITS_SCROLLPORT_UNDERFLOW;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::ondragenter) {
|
||||
aIID = NS_GET_IID(nsIDOMDragListener);
|
||||
*aFlags = NS_EVENT_BITS_DRAG_ENTER;
|
||||
|
@ -1479,6 +1487,8 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
|
|||
case NS_MENU_DESTROY:
|
||||
case NS_MENU_ACTION:
|
||||
case NS_XUL_BROADCAST:
|
||||
case NS_SCROLLPORT_OVERFLOW:
|
||||
case NS_SCROLLPORT_UNDERFLOW:
|
||||
case NS_XUL_COMMAND_UPDATE:
|
||||
if (nsnull != mMenuListeners) {
|
||||
if (nsnull == *aDOMEvent) {
|
||||
|
@ -1509,6 +1519,12 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
|
|||
case NS_XUL_BROADCAST:
|
||||
ret = mMenuListener->Broadcast(*aDOMEvent);
|
||||
break;
|
||||
case NS_SCROLLPORT_OVERFLOW:
|
||||
ret = mMenuListener->Overflow(*aDOMEvent);
|
||||
break;
|
||||
case NS_SCROLLPORT_UNDERFLOW:
|
||||
ret = mMenuListener->Underflow(*aDOMEvent);
|
||||
break;
|
||||
case NS_XUL_COMMAND_UPDATE:
|
||||
ret = mMenuListener->CommandUpdate(*aDOMEvent);
|
||||
break;
|
||||
|
@ -1551,6 +1567,18 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
|
|||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_SCROLLPORT_OVERFLOW:
|
||||
subType = NS_EVENT_BITS_SCROLLPORT_OVERFLOW;
|
||||
if (ls->mSubType & NS_EVENT_BITS_SCROLLPORT_OVERFLOW) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_SCROLLPORT_UNDERFLOW:
|
||||
subType = NS_EVENT_BITS_SCROLLPORT_UNDERFLOW;
|
||||
if (ls->mSubType & NS_EVENT_BITS_SCROLLPORT_UNDERFLOW) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_XUL_COMMAND_UPDATE:
|
||||
subType = NS_EVENT_BITS_XUL_COMMAND_UPDATE;
|
||||
if (ls->mSubType & NS_EVENT_BITS_XUL_COMMAND_UPDATE) {
|
||||
|
|
|
@ -213,13 +213,15 @@ protected:
|
|||
#define NS_EVENT_BITS_LOAD_ERROR 0x08
|
||||
|
||||
//nsIDOMMenuListener
|
||||
#define NS_EVENT_BITS_MENU_NONE 0x00
|
||||
#define NS_EVENT_BITS_MENU_CREATE 0x01
|
||||
#define NS_EVENT_BITS_XUL_CLOSE 0x02
|
||||
#define NS_EVENT_BITS_MENU_DESTROY 0x04
|
||||
#define NS_EVENT_BITS_MENU_ACTION 0x08
|
||||
#define NS_EVENT_BITS_XUL_BROADCAST 0x10
|
||||
#define NS_EVENT_BITS_XUL_COMMAND_UPDATE 0x20
|
||||
#define NS_EVENT_BITS_MENU_NONE 0x00
|
||||
#define NS_EVENT_BITS_MENU_CREATE 0x01
|
||||
#define NS_EVENT_BITS_XUL_CLOSE 0x02
|
||||
#define NS_EVENT_BITS_MENU_DESTROY 0x04
|
||||
#define NS_EVENT_BITS_MENU_ACTION 0x08
|
||||
#define NS_EVENT_BITS_XUL_BROADCAST 0x10
|
||||
#define NS_EVENT_BITS_XUL_COMMAND_UPDATE 0x20
|
||||
#define NS_EVENT_BITS_SCROLLPORT_OVERFLOW 0x40
|
||||
#define NS_EVENT_BITS_SCROLLPORT_UNDERFLOW 0x80
|
||||
|
||||
//nsIDOMDragListener
|
||||
#define NS_EVENT_BITS_DRAG_NONE 0x00
|
||||
|
|
|
@ -159,6 +159,11 @@ LAYOUT_ATOM(onselect, "onselect")
|
|||
LAYOUT_ATOM(onsubmit, "onsubmit")
|
||||
LAYOUT_ATOM(onunload, "onunload")
|
||||
|
||||
// scrolling
|
||||
LAYOUT_ATOM(onoverflow, "onoverflow")
|
||||
LAYOUT_ATOM(onunderflow, "onunderflow")
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
// Alphabetical list of atoms used by debugging code
|
||||
LAYOUT_ATOM(cellMap, "TableCellMap")
|
||||
|
|
|
@ -98,13 +98,19 @@ XUL_ATOM(titledbutton, "titledbutton")
|
|||
XUL_ATOM(crop, "crop")
|
||||
|
||||
XUL_ATOM(mode, "mode")
|
||||
XUL_ATOM(equalsize, "equalsize")
|
||||
XUL_ATOM(box, "box")
|
||||
XUL_ATOM(hbox, "hbox")
|
||||
XUL_ATOM(vbox, "vbox")
|
||||
XUL_ATOM(scrollbox, "scrollbox")
|
||||
XUL_ATOM(mousethrough, "mousethrough")
|
||||
XUL_ATOM(flex, "flex")
|
||||
XUL_ATOM(spring, "spring")
|
||||
XUL_ATOM(orient, "orient")
|
||||
XUL_ATOM(autostretch, "autostretch")
|
||||
|
||||
XUL_ATOM(autorepeatbutton, "autorepeatbutton")
|
||||
|
||||
XUL_ATOM(titledbox, "titledbox")
|
||||
XUL_ATOM(title, "title")
|
||||
XUL_ATOM(titledboxContentPseudo, ":titledbox-content")
|
||||
|
|
|
@ -184,6 +184,8 @@ nsXBLBinding::kEventHandlerMap[] = {
|
|||
{ "command", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "broadcast", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "commandupdate", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "overflow", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "underflow", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
|
||||
{ "focus", nsnull, &NS_GET_IID(nsIDOMFocusListener) },
|
||||
{ "blur", nsnull, &NS_GET_IID(nsIDOMFocusListener) },
|
||||
|
@ -1428,7 +1430,9 @@ PRBool
|
|||
nsXBLBinding::IsXULHandler(const nsString& aName)
|
||||
{
|
||||
return ((aName.EqualsWithConversion("create")) || (aName.EqualsWithConversion("destroy")) || (aName.EqualsWithConversion("broadcast")) ||
|
||||
(aName.EqualsWithConversion("command")) || (aName.EqualsWithConversion("commandupdate")) || (aName.EqualsWithConversion("close")));
|
||||
(aName.EqualsWithConversion("command")) || (aName.EqualsWithConversion("commandupdate")) || (aName.EqualsWithConversion("close")) ||
|
||||
(aName.EqualsWithConversion("overflow")) ||
|
||||
(aName.EqualsWithConversion("underflow")) );
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -275,6 +275,24 @@ nsresult nsXBLEventHandler::CommandUpdate(nsIDOMEvent* aEvent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXBLEventHandler::Overflow(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mEventName.EqualsWithConversion("overflow"))
|
||||
return NS_OK;
|
||||
|
||||
ExecuteHandler(NS_ConvertASCIItoUCS2("overflow"), aEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXBLEventHandler::Underflow(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mEventName.EqualsWithConversion("underflow"))
|
||||
return NS_OK;
|
||||
|
||||
ExecuteHandler(NS_ConvertASCIItoUCS2("underflow"), aEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXBLEventHandler::Destroy(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mEventName.EqualsWithConversion("destroy"))
|
||||
|
|
|
@ -70,6 +70,8 @@ public:
|
|||
NS_IMETHOD Action(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Broadcast(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD CommandUpdate(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Overflow(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Underflow(nsIDOMEvent* aEvent);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
|
|
|
@ -84,3 +84,4 @@ NS_XULATOM(value);
|
|||
NS_XULATOM(width);
|
||||
NS_XULATOM(window);
|
||||
NS_XULATOM(xulcontentsgenerated);
|
||||
NS_XULATOM(scrollbox);
|
||||
|
|
|
@ -344,6 +344,7 @@ nsXULElement::Init()
|
|||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
rv = nsComponentManager::CreateInstance(kNameSpaceManagerCID,
|
||||
nsnull,
|
||||
kINameSpaceManagerIID,
|
||||
|
@ -397,6 +398,7 @@ nsXULElement::~nsXULElement()
|
|||
gRDFService = nsnull;
|
||||
}
|
||||
|
||||
|
||||
NS_IF_RELEASE(gNameSpaceManager);
|
||||
|
||||
if (gXULUtils) {
|
||||
|
@ -4035,6 +4037,9 @@ nsXULElement::GetBoxObject(nsIBoxObject** aResult)
|
|||
progID += "-popupset";
|
||||
else if (tag.get() == nsXULAtoms::tree)
|
||||
progID += "-tree";
|
||||
else if (tag.get() == nsXULAtoms::scrollbox)
|
||||
progID += "-scrollbox";
|
||||
|
||||
|
||||
mBoxObject = do_CreateInstance(progID);
|
||||
if (!mBoxObject)
|
||||
|
|
|
@ -330,6 +330,7 @@ protected:
|
|||
static PRInt32 kNameSpaceID_RDF;
|
||||
static PRInt32 kNameSpaceID_XUL;
|
||||
|
||||
|
||||
public:
|
||||
static nsresult
|
||||
Create(nsXULPrototypeElement* aPrototype, nsIDocument* aDocument, PRBool aIsScriptable, nsIContent** aResult);
|
||||
|
|
|
@ -218,6 +218,8 @@ nsXULContentUtils::kEventHandlerMap[] = {
|
|||
{ "oncommand", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "onbroadcast", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "oncommandupdate", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "onoverflow", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "onunderflow", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
|
||||
{ "onfocus", nsnull, &NS_GET_IID(nsIDOMFocusListener) },
|
||||
{ "onblur", nsnull, &NS_GET_IID(nsIDOMFocusListener) },
|
||||
|
|
|
@ -42,6 +42,8 @@ public:
|
|||
NS_IMETHOD Action(nsIDOMEvent* aEvent) = 0;
|
||||
NS_IMETHOD Broadcast(nsIDOMEvent* aEvent) = 0;
|
||||
NS_IMETHOD CommandUpdate(nsIDOMEvent* aEvent) = 0;
|
||||
NS_IMETHOD Overflow(nsIDOMEvent* aEvent) = 0;
|
||||
NS_IMETHOD Underflow(nsIDOMEvent* aEvent) = 0;
|
||||
};
|
||||
|
||||
#endif // nsIDOMMenuListener_h__
|
||||
|
|
|
@ -169,6 +169,9 @@ NS_NewGfxListControlFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
|||
#endif
|
||||
|
||||
|
||||
nsresult
|
||||
NS_NewAutoRepeatBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
nsresult
|
||||
NS_NewRootBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
|
@ -244,6 +247,9 @@ NS_NewMenuPopupFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
|||
nsresult
|
||||
NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
nsresult
|
||||
NS_NewScrollBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
nsresult
|
||||
NS_NewMenuFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRUint32 aFlags );
|
||||
|
||||
|
@ -5513,7 +5519,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
|
|||
// Create a frame based on the tag
|
||||
// box is first because it is created the most.
|
||||
// BOX CONSTRUCTION
|
||||
if (aTag == nsXULAtoms::box || aTag == nsXULAtoms::tabbox ||
|
||||
if (aTag == nsXULAtoms::box || aTag == nsXULAtoms::vbox || aTag == nsXULAtoms::hbox || aTag == nsXULAtoms::tabbox ||
|
||||
aTag == nsXULAtoms::tabpage || aTag == nsXULAtoms::tabcontrol
|
||||
#ifdef XULTREE
|
||||
|| aTag == nsXULAtoms::treecell
|
||||
|
@ -5527,7 +5533,10 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
|
|||
rv = NS_NewXULTreeCellFrame(aPresShell, &newFrame);
|
||||
else
|
||||
#endif
|
||||
rv = NS_NewBoxFrame(aPresShell, &newFrame);
|
||||
|
||||
// create a box. Its not root, its layout manager is default (nsnull) which is "sprocket" and
|
||||
// its default orientation is horizontal for hbox and vertical for vbox
|
||||
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, nsnull, aTag != nsXULAtoms::vbox);
|
||||
|
||||
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
||||
aStyleContext->GetStyleData(eStyleStruct_Display);
|
||||
|
@ -5574,8 +5583,33 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
|
|||
|
||||
}
|
||||
} // End of BUTTON CONSTRUCTION logic
|
||||
// BUTTON CONSTRUCTION
|
||||
else if (aTag == nsXULAtoms::autorepeatbutton) {
|
||||
processChildren = PR_TRUE;
|
||||
isReplaced = PR_TRUE;
|
||||
rv = NS_NewAutoRepeatBoxFrame(aPresShell, &newFrame);
|
||||
|
||||
// TITLED BUTTON CONSTRUCTION
|
||||
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
||||
aStyleContext->GetStyleData(eStyleStruct_Display);
|
||||
|
||||
// Boxes can scroll.
|
||||
if (IsScrollable(aPresContext, display)) {
|
||||
|
||||
// set the top to be the newly created scrollframe
|
||||
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
||||
topFrame, aStyleContext);
|
||||
|
||||
// we have a scrollframe so the parent becomes the scroll frame.
|
||||
newFrame->GetParent(&aParentFrame);
|
||||
|
||||
primaryFrameSet = PR_TRUE;
|
||||
|
||||
frameHasBeenInitialized = PR_TRUE;
|
||||
|
||||
}
|
||||
} // End of BUTTON CONSTRUCTION logic
|
||||
|
||||
// TITLED BUTTON CONSTRUCTION
|
||||
else if (aTag == nsXULAtoms::titledbutton) {
|
||||
|
||||
processChildren = PR_TRUE;
|
||||
|
@ -5832,6 +5866,13 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
|
|||
frameHasBeenInitialized = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else if (aTag == nsXULAtoms::scrollbox) {
|
||||
rv = NS_NewScrollBoxFrame(aPresShell, &newFrame);
|
||||
|
||||
//ConstructTitledBoxFrame(aPresShell, aPresContext, aState, aContent, aParentFrame, aTag, aStyleContext, newFrame);
|
||||
processChildren = PR_TRUE;
|
||||
isReplaced = PR_TRUE;
|
||||
}
|
||||
|
||||
else if (aTag == nsXULAtoms::spinner)
|
||||
rv = NS_NewSpinnerFrame(aPresShell, &newFrame);
|
||||
|
|
|
@ -95,6 +95,12 @@ class nsIArena;
|
|||
#define VERIFY_REFLOW_INCLUDE_SPACE_MANAGER 0x40
|
||||
#define VERIFY_REFLOW_DURING_RESIZE_REFLOW 0x80
|
||||
|
||||
// for PostAttributeChanged
|
||||
enum nsAttributeChangeType {
|
||||
eChangeType_Set = 0, // Set attribute
|
||||
eChangeType_Remove = 1, // Remove attribute
|
||||
};
|
||||
|
||||
/**
|
||||
* Presentation shell interface. Presentation shells are the
|
||||
* controlling point for managing the presentation of a document. The
|
||||
|
@ -251,6 +257,21 @@ public:
|
|||
NS_IMETHOD FlushPendingNotifications() = 0;
|
||||
|
||||
/**
|
||||
* Post a request to handle a DOM event after Reflow has finished.
|
||||
*/
|
||||
NS_IMETHOD PostDOMEvent(nsIContent* aContent, nsEvent* aEvent)=0;
|
||||
|
||||
/**
|
||||
* Post a request to set and attribute after reflow has finished.
|
||||
*/
|
||||
NS_IMETHOD PostAttributeChange(nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aName,
|
||||
const nsString& aValue,
|
||||
PRBool aNotify,
|
||||
nsAttributeChangeType aType) = 0;
|
||||
|
||||
/**
|
||||
* Reflow batching
|
||||
*/
|
||||
NS_IMETHOD BeginReflowBatching() = 0;
|
||||
|
|
|
@ -159,6 +159,11 @@ LAYOUT_ATOM(onselect, "onselect")
|
|||
LAYOUT_ATOM(onsubmit, "onsubmit")
|
||||
LAYOUT_ATOM(onunload, "onunload")
|
||||
|
||||
// scrolling
|
||||
LAYOUT_ATOM(onoverflow, "onoverflow")
|
||||
LAYOUT_ATOM(onunderflow, "onunderflow")
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
// Alphabetical list of atoms used by debugging code
|
||||
LAYOUT_ATOM(cellMap, "TableCellMap")
|
||||
|
|
|
@ -553,6 +553,24 @@ private:
|
|||
PRInt32 mCallCount;
|
||||
};
|
||||
|
||||
struct nsDOMEventRequest
|
||||
{
|
||||
nsIContent* content;
|
||||
nsEvent* event;
|
||||
nsDOMEventRequest* next;
|
||||
};
|
||||
|
||||
struct nsAttributeChangeRequest
|
||||
{
|
||||
nsIContent* content;
|
||||
PRInt32 nameSpaceID;
|
||||
nsIAtom* name;
|
||||
nsAutoString value;
|
||||
PRBool notify;
|
||||
nsAttributeChangeType type;
|
||||
nsAttributeChangeRequest* next;
|
||||
};
|
||||
|
||||
class PresShell : public nsIPresShell, public nsIViewObserver,
|
||||
private nsIDocumentObserver, public nsIFocusTracker,
|
||||
public nsISelectionController,
|
||||
|
@ -618,6 +636,20 @@ public:
|
|||
NS_IMETHOD CancelReflowCommand(nsIFrame* aTargetFrame, nsIReflowCommand::ReflowType* aCmdType);
|
||||
NS_IMETHOD FlushPendingNotifications();
|
||||
|
||||
/**
|
||||
* Post a request to handle a DOM event after Reflow has finished.
|
||||
*/
|
||||
NS_IMETHOD PostDOMEvent(nsIContent* aContent, nsEvent* aEvent);
|
||||
|
||||
/**
|
||||
* Post a request to set and attribute after reflow has finished.
|
||||
*/
|
||||
NS_IMETHOD PostAttributeChange(nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aName,
|
||||
const nsString& aValue,
|
||||
PRBool aNotify,
|
||||
nsAttributeChangeType aType);
|
||||
/**
|
||||
* Reflow batching
|
||||
*/
|
||||
|
@ -753,6 +785,9 @@ public:
|
|||
protected:
|
||||
virtual ~PresShell();
|
||||
|
||||
void HandlePostedDOMEvents();
|
||||
void HandlePostedAttributeChanges();
|
||||
|
||||
/** notify all external reflow observers that reflow of type "aData" is about
|
||||
* to begin.
|
||||
*/
|
||||
|
@ -819,7 +854,14 @@ protected:
|
|||
PRPackedBool mBatchReflows; // When set to true, the pres shell batches reflow commands.
|
||||
nsCOMPtr<nsIObserverService> mObserverService; // Observer service for reflow events
|
||||
nsCOMPtr<nsIDragService> mDragService;
|
||||
|
||||
|
||||
// used for list of posted events and attribute changes. To be done
|
||||
// after reflow.
|
||||
nsDOMEventRequest* mFirstDOMEventRequest;
|
||||
nsDOMEventRequest* mLastDOMEventRequest;
|
||||
nsAttributeChangeRequest* mFirstAttributeRequest;
|
||||
nsAttributeChangeRequest* mLastAttributeRequest;
|
||||
|
||||
// subshell map
|
||||
nsDST* mSubShellMap; // map of content/subshell pairs
|
||||
nsDST::NodeArena* mDSTNodeArena; // weak link. DST owns (mSubShellMap object)
|
||||
|
@ -942,7 +984,11 @@ NS_NewPresShell(nsIPresShell** aInstancePtrResult)
|
|||
(void **) aInstancePtrResult);
|
||||
}
|
||||
|
||||
PresShell::PresShell():mStackArena(nsnull)
|
||||
PresShell::PresShell():mStackArena(nsnull),
|
||||
mFirstDOMEventRequest(nsnull),
|
||||
mLastDOMEventRequest(nsnull),
|
||||
mFirstAttributeRequest(nsnull),
|
||||
mLastAttributeRequest(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mIsDestroying = PR_FALSE;
|
||||
|
@ -1828,6 +1874,8 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
|
|||
#endif
|
||||
|
||||
mViewManager->CacheWidgetChanges(PR_FALSE);
|
||||
HandlePostedDOMEvents();
|
||||
HandlePostedAttributeChanges();
|
||||
|
||||
//Send resize event from here.
|
||||
nsEvent event;
|
||||
|
@ -3052,6 +3100,114 @@ PresShell::GetGeneratedContentIterator(nsIContent* aContent,
|
|||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post a request to handle a DOM event after Reflow has finished.
|
||||
* The event must have been created with the "new" operator.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
PresShell::PostDOMEvent(nsIContent* aContent, nsEvent* aEvent)
|
||||
{
|
||||
// ok we have a list of events to handle. Queue them up and handle them
|
||||
// after we finish reflow.
|
||||
nsDOMEventRequest* request = nsnull;
|
||||
void* result = nsnull;
|
||||
AllocateFrame(sizeof(nsDOMEventRequest), &result);
|
||||
request = (nsDOMEventRequest*)result;
|
||||
|
||||
request->content = aContent;
|
||||
NS_ADDREF(aContent);
|
||||
|
||||
request->event = aEvent;
|
||||
request->next = nsnull;
|
||||
|
||||
if (mLastDOMEventRequest) {
|
||||
mLastDOMEventRequest = mLastDOMEventRequest->next = request;
|
||||
} else {
|
||||
mFirstDOMEventRequest = request;
|
||||
mLastDOMEventRequest = request;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Post a request to set and attribute after reflow has finished.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
PresShell::PostAttributeChange(nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aName,
|
||||
const nsString& aValue,
|
||||
PRBool aNotify,
|
||||
nsAttributeChangeType aType)
|
||||
{
|
||||
// ok we have a list of events to handle. Queue them up and handle them
|
||||
// after we finish reflow.
|
||||
nsAttributeChangeRequest* request = nsnull;
|
||||
|
||||
void* result = nsnull;
|
||||
AllocateFrame(sizeof(nsAttributeChangeRequest), &result);
|
||||
request = (nsAttributeChangeRequest*)result;
|
||||
|
||||
request->content = aContent;
|
||||
NS_ADDREF(aContent);
|
||||
|
||||
request->nameSpaceID = aNameSpaceID;
|
||||
request->name = aName;
|
||||
request->value = aValue;
|
||||
request->notify = aNotify;
|
||||
request->type = aType;
|
||||
request->next = nsnull;
|
||||
|
||||
if (mLastAttributeRequest) {
|
||||
mLastAttributeRequest = mLastAttributeRequest->next = request;
|
||||
} else {
|
||||
mFirstAttributeRequest = request;
|
||||
mLastAttributeRequest = request;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::HandlePostedDOMEvents()
|
||||
{
|
||||
nsDOMEventRequest* node = mFirstDOMEventRequest;
|
||||
while(node)
|
||||
{
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
node->content->HandleDOMEvent(mPresContext, node->event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
NS_RELEASE(node->content);
|
||||
delete node->event;
|
||||
nsDOMEventRequest* toFree = node;
|
||||
node = node->next;
|
||||
FreeFrame(sizeof(nsDOMEventRequest), toFree);
|
||||
}
|
||||
|
||||
mFirstDOMEventRequest = mLastDOMEventRequest = nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::HandlePostedAttributeChanges()
|
||||
{
|
||||
nsAttributeChangeRequest* node = mFirstAttributeRequest;
|
||||
while(node)
|
||||
{
|
||||
if (node->type == eChangeType_Set)
|
||||
node->content->SetAttribute(node->nameSpaceID, node->name, node->value, node->notify);
|
||||
else
|
||||
node->content->UnsetAttribute(node->nameSpaceID, node->name, node->notify);
|
||||
|
||||
NS_RELEASE(node->content);
|
||||
nsAttributeChangeRequest* toFree = node;
|
||||
node = node->next;
|
||||
FreeFrame(sizeof(nsAttributeChangeRequest), toFree);
|
||||
}
|
||||
|
||||
mFirstAttributeRequest = mLastAttributeRequest = nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::FlushPendingNotifications()
|
||||
{
|
||||
|
@ -4001,8 +4157,8 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible)
|
|||
MOZ_TIMER_DEBUGLOG(("Stop: Reflow: PresShell::ProcessReflowCommands(), this=%p\n", this));
|
||||
MOZ_TIMER_STOP(mReflowWatch);
|
||||
|
||||
// if we allocated any stack memory during reflow free it.
|
||||
//FreeDynamicStack();
|
||||
HandlePostedDOMEvents();
|
||||
HandlePostedAttributeChanges();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,12 @@ class nsIArena;
|
|||
#define VERIFY_REFLOW_INCLUDE_SPACE_MANAGER 0x40
|
||||
#define VERIFY_REFLOW_DURING_RESIZE_REFLOW 0x80
|
||||
|
||||
// for PostAttributeChanged
|
||||
enum nsAttributeChangeType {
|
||||
eChangeType_Set = 0, // Set attribute
|
||||
eChangeType_Remove = 1, // Remove attribute
|
||||
};
|
||||
|
||||
/**
|
||||
* Presentation shell interface. Presentation shells are the
|
||||
* controlling point for managing the presentation of a document. The
|
||||
|
@ -251,6 +257,21 @@ public:
|
|||
NS_IMETHOD FlushPendingNotifications() = 0;
|
||||
|
||||
/**
|
||||
* Post a request to handle a DOM event after Reflow has finished.
|
||||
*/
|
||||
NS_IMETHOD PostDOMEvent(nsIContent* aContent, nsEvent* aEvent)=0;
|
||||
|
||||
/**
|
||||
* Post a request to set and attribute after reflow has finished.
|
||||
*/
|
||||
NS_IMETHOD PostAttributeChange(nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aName,
|
||||
const nsString& aValue,
|
||||
PRBool aNotify,
|
||||
nsAttributeChangeType aType) = 0;
|
||||
|
||||
/**
|
||||
* Reflow batching
|
||||
*/
|
||||
NS_IMETHOD BeginReflowBatching() = 0;
|
||||
|
|
|
@ -159,6 +159,11 @@ LAYOUT_ATOM(onselect, "onselect")
|
|||
LAYOUT_ATOM(onsubmit, "onsubmit")
|
||||
LAYOUT_ATOM(onunload, "onunload")
|
||||
|
||||
// scrolling
|
||||
LAYOUT_ATOM(onoverflow, "onoverflow")
|
||||
LAYOUT_ATOM(onunderflow, "onunderflow")
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
// Alphabetical list of atoms used by debugging code
|
||||
LAYOUT_ATOM(cellMap, "TableCellMap")
|
||||
|
|
|
@ -163,6 +163,10 @@
|
|||
#define NS_TREEBOXOBJECT_CID \
|
||||
{ 0x26621935, 0xf272, 0x4979, { 0x90, 0xa9, 0xe6, 0xed, 0x83, 0x56, 0x6c, 0x2e } }
|
||||
|
||||
// {56E2ADA8-4631-11d4-BA11-001083023C1E}
|
||||
#define NS_SCROLLBOXOBJECT_CID \
|
||||
{ 0x56e2ada8, 0x4631, 0x11d4, { 0xba, 0x11, 0x0, 0x10, 0x83, 0x2, 0x3c, 0x1e } }
|
||||
|
||||
// {AA40253B-4C42-4056-8132-37BCD07862FD}
|
||||
#define NS_MENUBOXOBJECT_CID \
|
||||
{ 0xaa40253b, 0x4c42, 0x4056, { 0x81, 0x32, 0x37, 0xbc, 0xd0, 0x78, 0x62, 0xfd } }
|
||||
|
|
|
@ -109,6 +109,7 @@ static NS_DEFINE_CID(kBindingManagerCID, NS_BINDINGMANAGER_CID);
|
|||
|
||||
static NS_DEFINE_CID(kBoxObjectCID, NS_BOXOBJECT_CID);
|
||||
static NS_DEFINE_CID(kTreeBoxObjectCID, NS_TREEBOXOBJECT_CID);
|
||||
static NS_DEFINE_CID(kScrollBoxObjectCID, NS_SCROLLBOXOBJECT_CID);
|
||||
static NS_DEFINE_CID(kMenuBoxObjectCID, NS_MENUBOXOBJECT_CID);
|
||||
static NS_DEFINE_CID(kPopupSetBoxObjectCID, NS_POPUPSETBOXOBJECT_CID);
|
||||
static NS_DEFINE_CID(kBrowserBoxObjectCID, NS_BROWSERBOXOBJECT_CID);
|
||||
|
@ -148,6 +149,7 @@ extern nsresult NS_NewBindingManager(nsIBindingManager** aResult);
|
|||
|
||||
extern nsresult NS_NewBoxObject(nsIBoxObject** aResult);
|
||||
extern nsresult NS_NewTreeBoxObject(nsIBoxObject** aResult);
|
||||
extern nsresult NS_NewScrollBoxObject(nsIBoxObject** aResult);
|
||||
extern nsresult NS_NewMenuBoxObject(nsIBoxObject** aResult);
|
||||
extern nsresult NS_NewEditorBoxObject(nsIBoxObject** aResult);
|
||||
extern nsresult NS_NewPopupSetBoxObject(nsIBoxObject** aResult);
|
||||
|
@ -515,6 +517,13 @@ nsLayoutFactory::CreateInstance(nsISupports *aOuter,
|
|||
return res;
|
||||
}
|
||||
}
|
||||
else if (mClassID.Equals(kScrollBoxObjectCID)) {
|
||||
res = NS_NewScrollBoxObject((nsIBoxObject**) &inst);
|
||||
if (NS_FAILED(res)) {
|
||||
LOG_NEW_FAILURE("NS_NewScrollBoxObject", res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
|
|
@ -368,6 +368,7 @@ static Components gComponents[] = {
|
|||
{ "XUL Browser Box Object", NS_BROWSERBOXOBJECT_CID, "component://netscape/layout/xul-boxobject-browser" },
|
||||
{ "XUL Editor Box Object", NS_EDITORBOXOBJECT_CID, "component://netscape/layout/xul-boxobject-editor" },
|
||||
{ "XUL Iframe Object", NS_IFRAMEBOXOBJECT_CID, "component://netscape/layout/xul-boxobject-iframe" },
|
||||
{ "XUL ScrollBox Object", NS_SCROLLBOXOBJECT_CID, "component://netscape/layout/xul-boxobject-scrollbox" },
|
||||
|
||||
{ "AutoCopy Service", NS_AUTOCOPYSERVICE_CID, "component://netscape/autocopy" },
|
||||
{ "Content policy service", NS_CONTENTPOLICY_CID, NS_CONTENTPOLICY_PROGID },
|
||||
|
|
|
@ -50,7 +50,7 @@ static char* mEventNames[] = {
|
|||
"submit", "reset", "change", "select", "input", "paint" ,"text",
|
||||
"create", "close", "destroy", "command", "broadcast", "commandupdate",
|
||||
"dragenter", "dragover", "dragexit", "dragdrop", "draggesture", "resize",
|
||||
"scroll"
|
||||
"scroll","overflow", "underflow"
|
||||
};
|
||||
|
||||
nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsString& aEventType) {
|
||||
|
@ -311,29 +311,48 @@ nsDOMEvent::GetDetail(PRInt32* aDetail)
|
|||
{
|
||||
//detail is valid for more than just mouseevents but we don't
|
||||
//use it for anything else right now
|
||||
if (!mEvent || mEvent->eventStructType != NS_MOUSE_EVENT) {
|
||||
|
||||
if (!mEvent) {
|
||||
*aDetail = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
switch (mEvent->message) {
|
||||
case NS_MOUSE_LEFT_BUTTON_UP:
|
||||
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
||||
case NS_MOUSE_LEFT_CLICK:
|
||||
case NS_MOUSE_LEFT_DOUBLECLICK:
|
||||
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
||||
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
|
||||
case NS_MOUSE_MIDDLE_CLICK:
|
||||
case NS_MOUSE_MIDDLE_DOUBLECLICK:
|
||||
case NS_MOUSE_RIGHT_BUTTON_UP:
|
||||
case NS_MOUSE_RIGHT_BUTTON_DOWN:
|
||||
case NS_MOUSE_RIGHT_CLICK:
|
||||
case NS_MOUSE_RIGHT_DOUBLECLICK:
|
||||
*aDetail = ((nsMouseEvent*)mEvent)->clickCount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch(mEvent->eventStructType)
|
||||
{
|
||||
case NS_SCROLLPORT_EVENT:
|
||||
{
|
||||
nsScrollPortEvent* scrollEvent = (nsScrollPortEvent*)mEvent;
|
||||
*aDetail = (PRInt32)scrollEvent->orient;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
case NS_MOUSE_EVENT:
|
||||
{
|
||||
switch (mEvent->message) {
|
||||
case NS_MOUSE_LEFT_BUTTON_UP:
|
||||
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
||||
case NS_MOUSE_LEFT_CLICK:
|
||||
case NS_MOUSE_LEFT_DOUBLECLICK:
|
||||
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
||||
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
|
||||
case NS_MOUSE_MIDDLE_CLICK:
|
||||
case NS_MOUSE_MIDDLE_DOUBLECLICK:
|
||||
case NS_MOUSE_RIGHT_BUTTON_UP:
|
||||
case NS_MOUSE_RIGHT_BUTTON_DOWN:
|
||||
case NS_MOUSE_RIGHT_CLICK:
|
||||
case NS_MOUSE_RIGHT_DOUBLECLICK:
|
||||
*aDetail = ((nsMouseEvent*)mEvent)->clickCount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
*aDetail = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1123,6 +1142,10 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
|||
return mEventNames[eDOMEvents_dragdrop];
|
||||
case NS_DRAGDROP_GESTURE:
|
||||
return mEventNames[eDOMEvents_draggesture];
|
||||
case NS_SCROLLPORT_OVERFLOW:
|
||||
return mEventNames[eDOMEvents_overflow];
|
||||
case NS_SCROLLPORT_UNDERFLOW:
|
||||
return mEventNames[eDOMEvents_underflow];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,9 @@ public:
|
|||
eDOMEvents_dragdrop,
|
||||
eDOMEvents_draggesture,
|
||||
eDOMEvents_resize,
|
||||
eDOMEvents_scroll
|
||||
eDOMEvents_scroll,
|
||||
eDOMEvents_overflow,
|
||||
eDOMEvents_underflow
|
||||
};
|
||||
|
||||
nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsString& aEventType);
|
||||
|
|
|
@ -450,6 +450,14 @@ nsresult nsEventListenerManager::GetIdentifiersForType(nsIAtom* aType, nsIID& aI
|
|||
aIID = kIDOMMenuListenerIID;
|
||||
*aFlags = NS_EVENT_BITS_XUL_COMMAND_UPDATE;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onoverflow) {
|
||||
aIID = kIDOMMenuListenerIID;
|
||||
*aFlags = NS_EVENT_BITS_SCROLLPORT_OVERFLOW;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onunderflow) {
|
||||
aIID = kIDOMMenuListenerIID;
|
||||
*aFlags = NS_EVENT_BITS_SCROLLPORT_UNDERFLOW;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::ondragenter) {
|
||||
aIID = NS_GET_IID(nsIDOMDragListener);
|
||||
*aFlags = NS_EVENT_BITS_DRAG_ENTER;
|
||||
|
@ -1479,6 +1487,8 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
|
|||
case NS_MENU_DESTROY:
|
||||
case NS_MENU_ACTION:
|
||||
case NS_XUL_BROADCAST:
|
||||
case NS_SCROLLPORT_OVERFLOW:
|
||||
case NS_SCROLLPORT_UNDERFLOW:
|
||||
case NS_XUL_COMMAND_UPDATE:
|
||||
if (nsnull != mMenuListeners) {
|
||||
if (nsnull == *aDOMEvent) {
|
||||
|
@ -1509,6 +1519,12 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
|
|||
case NS_XUL_BROADCAST:
|
||||
ret = mMenuListener->Broadcast(*aDOMEvent);
|
||||
break;
|
||||
case NS_SCROLLPORT_OVERFLOW:
|
||||
ret = mMenuListener->Overflow(*aDOMEvent);
|
||||
break;
|
||||
case NS_SCROLLPORT_UNDERFLOW:
|
||||
ret = mMenuListener->Underflow(*aDOMEvent);
|
||||
break;
|
||||
case NS_XUL_COMMAND_UPDATE:
|
||||
ret = mMenuListener->CommandUpdate(*aDOMEvent);
|
||||
break;
|
||||
|
@ -1551,6 +1567,18 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
|
|||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_SCROLLPORT_OVERFLOW:
|
||||
subType = NS_EVENT_BITS_SCROLLPORT_OVERFLOW;
|
||||
if (ls->mSubType & NS_EVENT_BITS_SCROLLPORT_OVERFLOW) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_SCROLLPORT_UNDERFLOW:
|
||||
subType = NS_EVENT_BITS_SCROLLPORT_UNDERFLOW;
|
||||
if (ls->mSubType & NS_EVENT_BITS_SCROLLPORT_UNDERFLOW) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_XUL_COMMAND_UPDATE:
|
||||
subType = NS_EVENT_BITS_XUL_COMMAND_UPDATE;
|
||||
if (ls->mSubType & NS_EVENT_BITS_XUL_COMMAND_UPDATE) {
|
||||
|
|
|
@ -213,13 +213,15 @@ protected:
|
|||
#define NS_EVENT_BITS_LOAD_ERROR 0x08
|
||||
|
||||
//nsIDOMMenuListener
|
||||
#define NS_EVENT_BITS_MENU_NONE 0x00
|
||||
#define NS_EVENT_BITS_MENU_CREATE 0x01
|
||||
#define NS_EVENT_BITS_XUL_CLOSE 0x02
|
||||
#define NS_EVENT_BITS_MENU_DESTROY 0x04
|
||||
#define NS_EVENT_BITS_MENU_ACTION 0x08
|
||||
#define NS_EVENT_BITS_XUL_BROADCAST 0x10
|
||||
#define NS_EVENT_BITS_XUL_COMMAND_UPDATE 0x20
|
||||
#define NS_EVENT_BITS_MENU_NONE 0x00
|
||||
#define NS_EVENT_BITS_MENU_CREATE 0x01
|
||||
#define NS_EVENT_BITS_XUL_CLOSE 0x02
|
||||
#define NS_EVENT_BITS_MENU_DESTROY 0x04
|
||||
#define NS_EVENT_BITS_MENU_ACTION 0x08
|
||||
#define NS_EVENT_BITS_XUL_BROADCAST 0x10
|
||||
#define NS_EVENT_BITS_XUL_COMMAND_UPDATE 0x20
|
||||
#define NS_EVENT_BITS_SCROLLPORT_OVERFLOW 0x40
|
||||
#define NS_EVENT_BITS_SCROLLPORT_UNDERFLOW 0x80
|
||||
|
||||
//nsIDOMDragListener
|
||||
#define NS_EVENT_BITS_DRAG_NONE 0x00
|
||||
|
|
|
@ -553,6 +553,24 @@ private:
|
|||
PRInt32 mCallCount;
|
||||
};
|
||||
|
||||
struct nsDOMEventRequest
|
||||
{
|
||||
nsIContent* content;
|
||||
nsEvent* event;
|
||||
nsDOMEventRequest* next;
|
||||
};
|
||||
|
||||
struct nsAttributeChangeRequest
|
||||
{
|
||||
nsIContent* content;
|
||||
PRInt32 nameSpaceID;
|
||||
nsIAtom* name;
|
||||
nsAutoString value;
|
||||
PRBool notify;
|
||||
nsAttributeChangeType type;
|
||||
nsAttributeChangeRequest* next;
|
||||
};
|
||||
|
||||
class PresShell : public nsIPresShell, public nsIViewObserver,
|
||||
private nsIDocumentObserver, public nsIFocusTracker,
|
||||
public nsISelectionController,
|
||||
|
@ -618,6 +636,20 @@ public:
|
|||
NS_IMETHOD CancelReflowCommand(nsIFrame* aTargetFrame, nsIReflowCommand::ReflowType* aCmdType);
|
||||
NS_IMETHOD FlushPendingNotifications();
|
||||
|
||||
/**
|
||||
* Post a request to handle a DOM event after Reflow has finished.
|
||||
*/
|
||||
NS_IMETHOD PostDOMEvent(nsIContent* aContent, nsEvent* aEvent);
|
||||
|
||||
/**
|
||||
* Post a request to set and attribute after reflow has finished.
|
||||
*/
|
||||
NS_IMETHOD PostAttributeChange(nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aName,
|
||||
const nsString& aValue,
|
||||
PRBool aNotify,
|
||||
nsAttributeChangeType aType);
|
||||
/**
|
||||
* Reflow batching
|
||||
*/
|
||||
|
@ -753,6 +785,9 @@ public:
|
|||
protected:
|
||||
virtual ~PresShell();
|
||||
|
||||
void HandlePostedDOMEvents();
|
||||
void HandlePostedAttributeChanges();
|
||||
|
||||
/** notify all external reflow observers that reflow of type "aData" is about
|
||||
* to begin.
|
||||
*/
|
||||
|
@ -819,7 +854,14 @@ protected:
|
|||
PRPackedBool mBatchReflows; // When set to true, the pres shell batches reflow commands.
|
||||
nsCOMPtr<nsIObserverService> mObserverService; // Observer service for reflow events
|
||||
nsCOMPtr<nsIDragService> mDragService;
|
||||
|
||||
|
||||
// used for list of posted events and attribute changes. To be done
|
||||
// after reflow.
|
||||
nsDOMEventRequest* mFirstDOMEventRequest;
|
||||
nsDOMEventRequest* mLastDOMEventRequest;
|
||||
nsAttributeChangeRequest* mFirstAttributeRequest;
|
||||
nsAttributeChangeRequest* mLastAttributeRequest;
|
||||
|
||||
// subshell map
|
||||
nsDST* mSubShellMap; // map of content/subshell pairs
|
||||
nsDST::NodeArena* mDSTNodeArena; // weak link. DST owns (mSubShellMap object)
|
||||
|
@ -942,7 +984,11 @@ NS_NewPresShell(nsIPresShell** aInstancePtrResult)
|
|||
(void **) aInstancePtrResult);
|
||||
}
|
||||
|
||||
PresShell::PresShell():mStackArena(nsnull)
|
||||
PresShell::PresShell():mStackArena(nsnull),
|
||||
mFirstDOMEventRequest(nsnull),
|
||||
mLastDOMEventRequest(nsnull),
|
||||
mFirstAttributeRequest(nsnull),
|
||||
mLastAttributeRequest(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mIsDestroying = PR_FALSE;
|
||||
|
@ -1828,6 +1874,8 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
|
|||
#endif
|
||||
|
||||
mViewManager->CacheWidgetChanges(PR_FALSE);
|
||||
HandlePostedDOMEvents();
|
||||
HandlePostedAttributeChanges();
|
||||
|
||||
//Send resize event from here.
|
||||
nsEvent event;
|
||||
|
@ -3052,6 +3100,114 @@ PresShell::GetGeneratedContentIterator(nsIContent* aContent,
|
|||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post a request to handle a DOM event after Reflow has finished.
|
||||
* The event must have been created with the "new" operator.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
PresShell::PostDOMEvent(nsIContent* aContent, nsEvent* aEvent)
|
||||
{
|
||||
// ok we have a list of events to handle. Queue them up and handle them
|
||||
// after we finish reflow.
|
||||
nsDOMEventRequest* request = nsnull;
|
||||
void* result = nsnull;
|
||||
AllocateFrame(sizeof(nsDOMEventRequest), &result);
|
||||
request = (nsDOMEventRequest*)result;
|
||||
|
||||
request->content = aContent;
|
||||
NS_ADDREF(aContent);
|
||||
|
||||
request->event = aEvent;
|
||||
request->next = nsnull;
|
||||
|
||||
if (mLastDOMEventRequest) {
|
||||
mLastDOMEventRequest = mLastDOMEventRequest->next = request;
|
||||
} else {
|
||||
mFirstDOMEventRequest = request;
|
||||
mLastDOMEventRequest = request;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Post a request to set and attribute after reflow has finished.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
PresShell::PostAttributeChange(nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aName,
|
||||
const nsString& aValue,
|
||||
PRBool aNotify,
|
||||
nsAttributeChangeType aType)
|
||||
{
|
||||
// ok we have a list of events to handle. Queue them up and handle them
|
||||
// after we finish reflow.
|
||||
nsAttributeChangeRequest* request = nsnull;
|
||||
|
||||
void* result = nsnull;
|
||||
AllocateFrame(sizeof(nsAttributeChangeRequest), &result);
|
||||
request = (nsAttributeChangeRequest*)result;
|
||||
|
||||
request->content = aContent;
|
||||
NS_ADDREF(aContent);
|
||||
|
||||
request->nameSpaceID = aNameSpaceID;
|
||||
request->name = aName;
|
||||
request->value = aValue;
|
||||
request->notify = aNotify;
|
||||
request->type = aType;
|
||||
request->next = nsnull;
|
||||
|
||||
if (mLastAttributeRequest) {
|
||||
mLastAttributeRequest = mLastAttributeRequest->next = request;
|
||||
} else {
|
||||
mFirstAttributeRequest = request;
|
||||
mLastAttributeRequest = request;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::HandlePostedDOMEvents()
|
||||
{
|
||||
nsDOMEventRequest* node = mFirstDOMEventRequest;
|
||||
while(node)
|
||||
{
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
node->content->HandleDOMEvent(mPresContext, node->event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
NS_RELEASE(node->content);
|
||||
delete node->event;
|
||||
nsDOMEventRequest* toFree = node;
|
||||
node = node->next;
|
||||
FreeFrame(sizeof(nsDOMEventRequest), toFree);
|
||||
}
|
||||
|
||||
mFirstDOMEventRequest = mLastDOMEventRequest = nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::HandlePostedAttributeChanges()
|
||||
{
|
||||
nsAttributeChangeRequest* node = mFirstAttributeRequest;
|
||||
while(node)
|
||||
{
|
||||
if (node->type == eChangeType_Set)
|
||||
node->content->SetAttribute(node->nameSpaceID, node->name, node->value, node->notify);
|
||||
else
|
||||
node->content->UnsetAttribute(node->nameSpaceID, node->name, node->notify);
|
||||
|
||||
NS_RELEASE(node->content);
|
||||
nsAttributeChangeRequest* toFree = node;
|
||||
node = node->next;
|
||||
FreeFrame(sizeof(nsAttributeChangeRequest), toFree);
|
||||
}
|
||||
|
||||
mFirstAttributeRequest = mLastAttributeRequest = nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::FlushPendingNotifications()
|
||||
{
|
||||
|
@ -4001,8 +4157,8 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible)
|
|||
MOZ_TIMER_DEBUGLOG(("Stop: Reflow: PresShell::ProcessReflowCommands(), this=%p\n", this));
|
||||
MOZ_TIMER_STOP(mReflowWatch);
|
||||
|
||||
// if we allocated any stack memory during reflow free it.
|
||||
//FreeDynamicStack();
|
||||
HandlePostedDOMEvents();
|
||||
HandlePostedAttributeChanges();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,57 +17,17 @@
|
|||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Author: Eric D Vaughan (evaughan@netscape.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*/
|
||||
#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 "nsScrollPortFrame.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIBox.h"
|
||||
#include "nsBoxLayoutState.h"
|
||||
#include "nsIBoxToBlockAdaptor.h"
|
||||
#include "nsIFormControlFrame.h"
|
||||
#include "nsIStatefulFrame.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIPresState.h"
|
||||
|
||||
/*
|
||||
|
||||
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);
|
||||
|
||||
|
||||
*/
|
||||
|
||||
static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID);
|
||||
static NS_DEFINE_IID(kScrollPortViewCID, NS_SCROLL_PORT_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(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_NewScrollPortFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
|
@ -83,114 +43,8 @@ NS_NewScrollPortFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsScrollPortFrame::nsScrollPortFrame(nsIPresShell* aShell):nsBoxFrame(aShell)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aStyleContext,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
nsresult rv = nsBoxFrame::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 = nsBoxFrame::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(aPresContext, &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;
|
||||
}
|
||||
|
||||
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(nsIPresContext* aPresContext,
|
||||
nsIFrame* aParent,
|
||||
nsIView** aParentView)
|
||||
{
|
||||
nsresult rv = aParent->GetView(aPresContext, aParentView);
|
||||
NS_ASSERTION(aParentView, "GetParentWithView failed");
|
||||
return(rv);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsScrollPortFrame::IsInsideFormControlFrame()
|
||||
nsScrollPortFrame::NeedsClipWidget()
|
||||
{
|
||||
// XXX: This code will go away when a general solution for creating
|
||||
// widgets only when needed is implemented.
|
||||
|
@ -208,444 +62,14 @@ nsScrollPortFrame::IsInsideFormControlFrame()
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsScrollPortFrame::CreateScrollingView(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsIView* view;
|
||||
|
||||
//Get parent frame
|
||||
nsIFrame* parent;
|
||||
GetParentWithView(aPresContext, &parent);
|
||||
NS_ASSERTION(parent, "GetParentWithView failed");
|
||||
|
||||
// Get parent view
|
||||
nsIView* parentView = nsnull;
|
||||
GetScrollingParentView(aPresContext, parent, &parentView);
|
||||
|
||||
// Get the view manager
|
||||
nsIViewManager* viewManager;
|
||||
parentView->GetViewManager(viewManager);
|
||||
|
||||
|
||||
// Create the scrolling view
|
||||
nsresult rv = nsComponentManager::CreateInstance(kScrollPortViewCID,
|
||||
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, display->IsVisibleOrCollapsed() ?
|
||||
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
|
||||
if (! IsInsideFormControlFrame()) {
|
||||
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(aPresContext, view);
|
||||
}
|
||||
|
||||
NS_RELEASE(viewManager);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::GetMargin(nsMargin& aMargin)
|
||||
{
|
||||
aMargin.SizeTo(0,0,0,0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::GetPadding(nsMargin& aMargin)
|
||||
{
|
||||
aMargin.SizeTo(0,0,0,0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::GetBorder(nsMargin& aMargin)
|
||||
{
|
||||
aMargin.SizeTo(0,0,0,0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::Layout(nsBoxLayoutState& aState)
|
||||
{
|
||||
PRUint32 flags = 0;
|
||||
aState.GetLayoutFlags(flags);
|
||||
|
||||
nsRect clientRect(0,0,0,0);
|
||||
GetClientRect(clientRect);
|
||||
nsIBox* kid = nsnull;
|
||||
GetChildBox(&kid);
|
||||
nsRect childRect(clientRect);
|
||||
nsMargin margin(0,0,0,0);
|
||||
kid->GetMargin(margin);
|
||||
childRect.Deflate(margin);
|
||||
nsSize min(0,0);
|
||||
kid->GetMinSize(aState, min);
|
||||
|
||||
/*
|
||||
// if our child is not html then get is min size
|
||||
// and make sure we don't squeeze it smaller than that.
|
||||
nsIBoxToBlockAdaptor* adaptor = nsnull;
|
||||
if (NS_FAILED(kid->QueryInterface(NS_GET_IID(nsIBoxToBlockAdaptor), (void**)&adaptor))) {
|
||||
if (min.height > childRect.height)
|
||||
childRect.height = min.height;
|
||||
}
|
||||
*/
|
||||
|
||||
if (min.height > childRect.height)
|
||||
childRect.height = min.height;
|
||||
|
||||
if (min.width > childRect.width)
|
||||
childRect.width = min.width;
|
||||
|
||||
aState.SetLayoutFlags(NS_FRAME_NO_MOVE_VIEW);
|
||||
kid->SetBounds(aState, childRect);
|
||||
kid->Layout(aState);
|
||||
|
||||
kid->GetBounds(childRect);
|
||||
|
||||
clientRect.Inflate(margin);
|
||||
|
||||
if (childRect.width < clientRect.width || childRect.height < childRect.height)
|
||||
{
|
||||
if (childRect.width < clientRect.width)
|
||||
childRect.width = clientRect.width;
|
||||
|
||||
if (childRect.height < clientRect.height)
|
||||
childRect.height = clientRect.height;
|
||||
|
||||
clientRect.Deflate(margin);
|
||||
|
||||
kid->SetBounds(aState, childRect);
|
||||
}
|
||||
|
||||
aState.SetLayoutFlags(flags);
|
||||
|
||||
SyncLayout(aState);
|
||||
|
||||
nsIPresContext* presContext = aState.GetPresContext();
|
||||
nsIScrollableView* scrollingView;
|
||||
nsIView* view;
|
||||
GetView(presContext, &view);
|
||||
if (NS_SUCCEEDED(view->QueryInterface(kScrollViewIID, (void**)&scrollingView))) {
|
||||
scrollingView->ComputeScrollOffsets(PR_TRUE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::GetAscent(nsBoxLayoutState& aState, nscoord& aAscent)
|
||||
{
|
||||
aAscent = 0;
|
||||
nsIBox* child = nsnull;
|
||||
GetChildBox(&child);
|
||||
nsresult rv = child->GetAscent(aState, aAscent);
|
||||
nsMargin m(0,0,0,0);
|
||||
GetBorderAndPadding(m);
|
||||
aAscent += m.top;
|
||||
GetMargin(m);
|
||||
aAscent += m.top;
|
||||
GetInset(m);
|
||||
aAscent += m.top;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
|
||||
{
|
||||
nsIBox* child = nsnull;
|
||||
GetChildBox(&child);
|
||||
nsresult rv = child->GetPrefSize(aBoxLayoutState, aSize);
|
||||
AddMargin(child, aSize);
|
||||
AddBorderAndPadding(aSize);
|
||||
AddInset(aSize);
|
||||
nsIBox::AddCSSPrefSize(aBoxLayoutState, this, aSize);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
|
||||
{
|
||||
aSize.width = 0;
|
||||
aSize.height = 0;
|
||||
AddBorderAndPadding(aSize);
|
||||
AddInset(aSize);
|
||||
nsIBox::AddCSSMinSize(aBoxLayoutState, this, aSize);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
|
||||
{
|
||||
nsIBox* child = nsnull;
|
||||
GetChildBox(&child);
|
||||
nsresult rv = child->GetMaxSize(aBoxLayoutState, aSize);
|
||||
AddMargin(child, aSize);
|
||||
AddBorderAndPadding(aSize);
|
||||
AddInset(aSize);
|
||||
nsIBox::AddCSSMaxSize(aBoxLayoutState, this, aSize);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
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->IsVisibleOrCollapsed()) {
|
||||
// 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
|
||||
nsresult rv = nsBoxFrame::Paint(aPresContext, aRenderingContext, aDirtyRect,
|
||||
aWhichLayer);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRIntn
|
||||
nsScrollPortFrame::GetSkipSides() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScrollPortFrame::GetContentOf(nsIContent** aContent)
|
||||
{
|
||||
return GetContent(aContent);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIStatefulFrame
|
||||
//----------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::GetStateType(nsIPresContext* aPresContext,
|
||||
nsIStatefulFrame::StateType* aStateType)
|
||||
{
|
||||
*aStateType = nsIStatefulFrame::eScrollType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::SaveState(nsIPresContext* aPresContext,
|
||||
nsIPresState** aState)
|
||||
{
|
||||
nsresult res = NS_OK;
|
||||
PRInt32 x,y;
|
||||
nsIScrollableView* scrollingView;
|
||||
nsIView* view;
|
||||
GetView(aPresContext, &view);
|
||||
if (NS_SUCCEEDED(view->QueryInterface(kScrollViewIID, (void**)&scrollingView))) {
|
||||
scrollingView->GetScrollPosition(x,y);
|
||||
}
|
||||
nsIView* child = nsnull;
|
||||
nsRect childRect(0,0,0,0);
|
||||
if (NS_SUCCEEDED(scrollingView->GetScrolledView(child)) && child) {
|
||||
child->GetBounds(childRect);
|
||||
}
|
||||
|
||||
res = NS_NewPresState(aState);
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset;
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(xoffset));
|
||||
if (NS_SUCCEEDED(res) && xoffset) {
|
||||
res = xoffset->SetData(x);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
(*aState)->SetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("x-offset"), xoffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset;
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(yoffset));
|
||||
if (NS_SUCCEEDED(res) && yoffset) {
|
||||
res = yoffset->SetData(y);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
(*aState)->SetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("y-offset"), yoffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsISupportsPRInt32> width;
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(width));
|
||||
if (NS_SUCCEEDED(res) && width) {
|
||||
res = width->SetData(childRect.width);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
(*aState)->SetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("width"), width);
|
||||
}
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsISupportsPRInt32> height;
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(height));
|
||||
if (NS_SUCCEEDED(res) && height) {
|
||||
res = height->SetData(childRect.height);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
(*aState)->SetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("height"), height);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::RestoreState(nsIPresContext* aPresContext,
|
||||
nsIPresState* aState)
|
||||
{
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> width;
|
||||
nsCOMPtr<nsISupportsPRInt32> height;
|
||||
aState->GetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("x-offset"), getter_AddRefs(xoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("y-offset"), getter_AddRefs(yoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("width"), getter_AddRefs(width));
|
||||
aState->GetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("height"), getter_AddRefs(height));
|
||||
|
||||
nsresult res = NS_ERROR_NULL_POINTER;
|
||||
if (xoffset && yoffset) {
|
||||
PRInt32 x,y,w,h;
|
||||
res = xoffset->GetData(&x);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = yoffset->GetData(&y);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = width->GetData(&w);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = height->GetData(&h);
|
||||
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
|
||||
nsIScrollableView* scrollingView;
|
||||
nsIView* view;
|
||||
GetView(aPresContext, &view);
|
||||
if (NS_SUCCEEDED(view->QueryInterface(kScrollViewIID, (void**)&scrollingView))) {
|
||||
|
||||
nsIView* child = nsnull;
|
||||
nsRect childRect(0,0,0,0);
|
||||
if (NS_SUCCEEDED(scrollingView->GetScrolledView(child)) && child) {
|
||||
child->GetBounds(childRect);
|
||||
}
|
||||
x = (int)(((float)childRect.width / w) * x);
|
||||
y = (int)(((float)childRect.height / h) * y);
|
||||
|
||||
scrollingView->ScrollTo(x,y,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::GetFrameType(nsIAtom** aType) const
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer");
|
||||
*aType = nsLayoutAtoms::scrollFrame;
|
||||
NS_ADDREF(*aType);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
NS_IMETHODIMP
|
||||
nsScrollPortFrame::GetFrameName(nsString& aResult) const
|
||||
{
|
||||
return MakeFrameName("ScrollPort", aResult);
|
||||
return MakeFrameName("ScrollPortFrame", aResult);
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsScrollPortFrame::AddRef(void)
|
||||
nsScrollPortFrame::nsScrollPortFrame(nsIPresShell* aShell):nsScrollBoxFrame(aShell)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsScrollPortFrame::Release(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsScrollPortFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIBox)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStatefulFrame)
|
||||
#ifdef NS_DEBUG
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFrameDebug)
|
||||
#endif
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIBox)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
|
||||
|
|
|
@ -22,108 +22,28 @@
|
|||
#ifndef nsScrollPortFrame_h___
|
||||
#define nsScrollPortFrame_h___
|
||||
|
||||
#include "nsBoxFrame.h"
|
||||
#include "nsIStatefulFrame.h"
|
||||
|
||||
#include "nsScrollBoxFrame.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
|
||||
* This is a specialized subclass for HTML only.
|
||||
*
|
||||
* Scroll frames don't support incremental changes, i.e. you can't replace
|
||||
* or remove the scrolled frame
|
||||
*/
|
||||
class nsScrollPortFrame : nsBoxFrame,
|
||||
public nsIStatefulFrame {
|
||||
class nsScrollPortFrame : public nsScrollBoxFrame {
|
||||
|
||||
public:
|
||||
friend nsresult NS_NewScrollPortFrame(nsIPresShell* aPresShell, 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 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;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
NS_IMETHOD GetFrameName(nsString& aResult) const;
|
||||
NS_IMETHOD GetFrameName(nsString& aResult) const;
|
||||
#endif
|
||||
|
||||
// nsIBox methods
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
|
||||
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
|
||||
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
|
||||
NS_IMETHOD GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent);
|
||||
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
|
||||
NS_IMETHOD GetPadding(nsMargin& aMargin);
|
||||
NS_IMETHOD GetBorder(nsMargin& aMargin);
|
||||
NS_IMETHOD GetMargin(nsMargin& aMargin);
|
||||
|
||||
virtual nsresult GetContentOf(nsIContent** aContent);
|
||||
|
||||
//nsIStatefulFrame
|
||||
NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType);
|
||||
NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState);
|
||||
NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState);
|
||||
|
||||
|
||||
protected:
|
||||
nsScrollPortFrame(nsIPresShell* aShell);
|
||||
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(nsIPresContext* aPresContext,
|
||||
nsIFrame* aParent,
|
||||
nsIView** aParentView);
|
||||
|
||||
private:
|
||||
nsresult CreateScrollingView(nsIPresContext* aPresContext);
|
||||
PRBool IsInsideFormControlFrame();
|
||||
|
||||
virtual PRBool NeedsClipWidget();
|
||||
};
|
||||
|
||||
#endif /* nsScrollPortFrame_h___ */
|
||||
|
|
|
@ -169,6 +169,9 @@ NS_NewGfxListControlFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
|||
#endif
|
||||
|
||||
|
||||
nsresult
|
||||
NS_NewAutoRepeatBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
nsresult
|
||||
NS_NewRootBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
|
@ -244,6 +247,9 @@ NS_NewMenuPopupFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
|||
nsresult
|
||||
NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
nsresult
|
||||
NS_NewScrollBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
nsresult
|
||||
NS_NewMenuFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRUint32 aFlags );
|
||||
|
||||
|
@ -5513,7 +5519,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
|
|||
// Create a frame based on the tag
|
||||
// box is first because it is created the most.
|
||||
// BOX CONSTRUCTION
|
||||
if (aTag == nsXULAtoms::box || aTag == nsXULAtoms::tabbox ||
|
||||
if (aTag == nsXULAtoms::box || aTag == nsXULAtoms::vbox || aTag == nsXULAtoms::hbox || aTag == nsXULAtoms::tabbox ||
|
||||
aTag == nsXULAtoms::tabpage || aTag == nsXULAtoms::tabcontrol
|
||||
#ifdef XULTREE
|
||||
|| aTag == nsXULAtoms::treecell
|
||||
|
@ -5527,7 +5533,10 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
|
|||
rv = NS_NewXULTreeCellFrame(aPresShell, &newFrame);
|
||||
else
|
||||
#endif
|
||||
rv = NS_NewBoxFrame(aPresShell, &newFrame);
|
||||
|
||||
// create a box. Its not root, its layout manager is default (nsnull) which is "sprocket" and
|
||||
// its default orientation is horizontal for hbox and vertical for vbox
|
||||
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, nsnull, aTag != nsXULAtoms::vbox);
|
||||
|
||||
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
||||
aStyleContext->GetStyleData(eStyleStruct_Display);
|
||||
|
@ -5574,8 +5583,33 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
|
|||
|
||||
}
|
||||
} // End of BUTTON CONSTRUCTION logic
|
||||
// BUTTON CONSTRUCTION
|
||||
else if (aTag == nsXULAtoms::autorepeatbutton) {
|
||||
processChildren = PR_TRUE;
|
||||
isReplaced = PR_TRUE;
|
||||
rv = NS_NewAutoRepeatBoxFrame(aPresShell, &newFrame);
|
||||
|
||||
// TITLED BUTTON CONSTRUCTION
|
||||
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
||||
aStyleContext->GetStyleData(eStyleStruct_Display);
|
||||
|
||||
// Boxes can scroll.
|
||||
if (IsScrollable(aPresContext, display)) {
|
||||
|
||||
// set the top to be the newly created scrollframe
|
||||
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
||||
topFrame, aStyleContext);
|
||||
|
||||
// we have a scrollframe so the parent becomes the scroll frame.
|
||||
newFrame->GetParent(&aParentFrame);
|
||||
|
||||
primaryFrameSet = PR_TRUE;
|
||||
|
||||
frameHasBeenInitialized = PR_TRUE;
|
||||
|
||||
}
|
||||
} // End of BUTTON CONSTRUCTION logic
|
||||
|
||||
// TITLED BUTTON CONSTRUCTION
|
||||
else if (aTag == nsXULAtoms::titledbutton) {
|
||||
|
||||
processChildren = PR_TRUE;
|
||||
|
@ -5832,6 +5866,13 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
|
|||
frameHasBeenInitialized = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else if (aTag == nsXULAtoms::scrollbox) {
|
||||
rv = NS_NewScrollBoxFrame(aPresShell, &newFrame);
|
||||
|
||||
//ConstructTitledBoxFrame(aPresShell, aPresContext, aState, aContent, aParentFrame, aTag, aStyleContext, newFrame);
|
||||
processChildren = PR_TRUE;
|
||||
isReplaced = PR_TRUE;
|
||||
}
|
||||
|
||||
else if (aTag == nsXULAtoms::spinner)
|
||||
rv = NS_NewSpinnerFrame(aPresShell, &newFrame);
|
||||
|
|
|
@ -184,6 +184,8 @@ nsXBLBinding::kEventHandlerMap[] = {
|
|||
{ "command", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "broadcast", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "commandupdate", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "overflow", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "underflow", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
|
||||
{ "focus", nsnull, &NS_GET_IID(nsIDOMFocusListener) },
|
||||
{ "blur", nsnull, &NS_GET_IID(nsIDOMFocusListener) },
|
||||
|
@ -1428,7 +1430,9 @@ PRBool
|
|||
nsXBLBinding::IsXULHandler(const nsString& aName)
|
||||
{
|
||||
return ((aName.EqualsWithConversion("create")) || (aName.EqualsWithConversion("destroy")) || (aName.EqualsWithConversion("broadcast")) ||
|
||||
(aName.EqualsWithConversion("command")) || (aName.EqualsWithConversion("commandupdate")) || (aName.EqualsWithConversion("close")));
|
||||
(aName.EqualsWithConversion("command")) || (aName.EqualsWithConversion("commandupdate")) || (aName.EqualsWithConversion("close")) ||
|
||||
(aName.EqualsWithConversion("overflow")) ||
|
||||
(aName.EqualsWithConversion("underflow")) );
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -275,6 +275,24 @@ nsresult nsXBLEventHandler::CommandUpdate(nsIDOMEvent* aEvent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXBLEventHandler::Overflow(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mEventName.EqualsWithConversion("overflow"))
|
||||
return NS_OK;
|
||||
|
||||
ExecuteHandler(NS_ConvertASCIItoUCS2("overflow"), aEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXBLEventHandler::Underflow(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mEventName.EqualsWithConversion("underflow"))
|
||||
return NS_OK;
|
||||
|
||||
ExecuteHandler(NS_ConvertASCIItoUCS2("underflow"), aEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXBLEventHandler::Destroy(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mEventName.EqualsWithConversion("destroy"))
|
||||
|
|
|
@ -70,6 +70,8 @@ public:
|
|||
NS_IMETHOD Action(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Broadcast(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD CommandUpdate(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Overflow(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Underflow(nsIDOMEvent* aEvent);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
|
|
|
@ -36,9 +36,11 @@ EXPORTS = \
|
|||
$(NULL)
|
||||
|
||||
XPIDLSRCS= nsIBoxObject.idl \
|
||||
nsIScrollBoxObject.idl \
|
||||
nsIBoxLayoutManager.idl \
|
||||
nsIBoxPaintManager.idl \
|
||||
nsITreeBoxObject.idl \
|
||||
nsIScrollBoxObject.idl \
|
||||
nsIPopupSetBoxObject.idl \
|
||||
nsIMenuBoxObject.idl \
|
||||
nsIBrowserBoxObject.idl \
|
||||
|
|
|
@ -32,6 +32,7 @@ XPIDLSRCS= .\nsIBoxObject.idl \
|
|||
.\nsIBoxLayoutManager.idl \
|
||||
.\nsIBoxPaintManager.idl \
|
||||
.\nsITreeBoxObject.idl \
|
||||
.\nsIScrollBoxObject.idl \
|
||||
.\nsIPopupSetBoxObject.idl \
|
||||
.\nsIMenuBoxObject.idl \
|
||||
.\nsIBrowserBoxObject.idl \
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: Eric D. Vaughan (evaughan@netscape.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsIBoxObject.idl"
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(56E2ADA8-4631-11d4-BA11-001083023C1E)]
|
||||
interface nsIScrollBoxObject : nsISupports
|
||||
{
|
||||
void scrollTo(in long x, in long y);
|
||||
void scrollBy(in long dx, in long dy);
|
||||
void scrollByLine(in long dlines);
|
||||
void scrollByIndex(in long dindexes);
|
||||
void scrollToLine(in long line);
|
||||
void scrollToElement(in nsIDOMElement child);
|
||||
void scrollToIndex(in long index);
|
||||
void getPosition(out long x, out long y);
|
||||
void getScrolledSize(out long width, out long height);
|
||||
void ensureElementIsVisible(in nsIDOMElement child);
|
||||
void ensureIndexIsVisible(in long index);
|
||||
void ensureLineIsVisible(in long line);
|
||||
};
|
||||
|
||||
%{C++
|
||||
nsresult
|
||||
NS_NewScrollBoxObject(nsIBoxObject** aResult);
|
||||
|
||||
%}
|
|
@ -30,6 +30,8 @@ MODULE = layout
|
|||
LIBRARY_NAME = raptorxulbase_s
|
||||
|
||||
CPPSRCS = \
|
||||
nsScrollBoxObject.cpp \
|
||||
nsScrollBoxFrame.cpp \
|
||||
nsTreeLayout.cpp \
|
||||
nsXULTreeCellFrame.cpp \
|
||||
nsXULTreeFrame.cpp \
|
||||
|
@ -41,6 +43,7 @@ CPPSRCS = \
|
|||
nsEditorBoxObject.cpp \
|
||||
nsMenuBoxObject.cpp \
|
||||
nsTreeBoxObject.cpp \
|
||||
nsScrollBoxObject.cpp \
|
||||
nsPopupSetBoxObject.cpp \
|
||||
nsBoxObject.cpp \
|
||||
nsGridLayout.cpp \
|
||||
|
|
|
@ -28,10 +28,12 @@ REQUIRES=xpcom raptor pref
|
|||
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
CPPSRCS= \
|
||||
nsScrollBoxFrame.cpp \
|
||||
nsEditorBoxObject.cpp \
|
||||
nsIFrameBoxObject.cpp \
|
||||
nsBrowserBoxObject.cpp \
|
||||
nsTreeBoxObject.cpp \
|
||||
nsScrollBoxObject.cpp \
|
||||
nsPopupSetBoxObject.cpp \
|
||||
nsMenuBoxObject.cpp \
|
||||
nsBoxObject.cpp \
|
||||
|
@ -96,10 +98,12 @@ CPPSRCS= \
|
|||
$(NULL)
|
||||
|
||||
CPP_OBJS= \
|
||||
.\$(OBJDIR)\nsScrollBoxFrame.obj \
|
||||
.\$(OBJDIR)\nsEditorBoxObject.obj \
|
||||
.\$(OBJDIR)\nsIFrameBoxObject.obj \
|
||||
.\$(OBJDIR)\nsBrowserBoxObject.obj \
|
||||
.\$(OBJDIR)\nsTreeBoxObject.obj \
|
||||
.\$(OBJDIR)\nsScrollBoxObject.obj \
|
||||
.\$(OBJDIR)\nsPopupSetBoxObject.obj \
|
||||
.\$(OBJDIR)\nsMenuBoxObject.obj \
|
||||
.\$(OBJDIR)\nsBoxObject.obj \
|
||||
|
|
|
@ -160,6 +160,8 @@ public:
|
|||
void DrawLine(nsIRenderingContext& aRenderingContext, PRBool aHorizontal, nscoord x1, nscoord y1, nscoord x2, nscoord y2);
|
||||
void FillRect(nsIRenderingContext& aRenderingContext, PRBool aHorizontal, nscoord x, nscoord y, nscoord width, nscoord height);
|
||||
|
||||
void CacheAttributes();
|
||||
|
||||
nsIBox* GetBoxForFrame(nsIFrame* aFrame, PRBool& aIsAdaptor);
|
||||
|
||||
nsBoxFrame::Halignment GetHAlign();
|
||||
|
@ -170,6 +172,8 @@ public:
|
|||
|
||||
nsBoxFrame::Valignment mValign;
|
||||
nsBoxFrame::Halignment mHalign;
|
||||
|
||||
PRBool mAttributesCached;
|
||||
|
||||
nsIPresContext* mPresContext;
|
||||
|
||||
|
@ -203,6 +207,8 @@ nsBoxFrame::nsBoxFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* a
|
|||
{
|
||||
mInner = new (aPresShell) nsBoxFrameInner(aPresShell, this);
|
||||
|
||||
mInner->mAttributesCached = PR_FALSE;
|
||||
|
||||
// if not otherwise specified boxes by default are horizontal.
|
||||
if (aIsHorizontal) {
|
||||
mState |= NS_STATE_IS_HORIZONTAL;
|
||||
|
@ -317,43 +323,8 @@ nsBoxFrame::Init(nsIPresContext* aPresContext,
|
|||
view->CreateWidget(kWidgetCID);
|
||||
}
|
||||
}
|
||||
|
||||
mInner->mValign = nsBoxFrame::vAlign_Top;
|
||||
mInner->mHalign = nsBoxFrame::hAlign_Left;
|
||||
|
||||
GetInitialVAlignment(mInner->mValign);
|
||||
GetInitialHAlignment(mInner->mHalign);
|
||||
|
||||
PRBool orient = PR_FALSE;
|
||||
if (mState & NS_STATE_DEFAULT_HORIZONTAL)
|
||||
orient = PR_TRUE;
|
||||
|
||||
GetInitialOrientation(orient);
|
||||
if (orient)
|
||||
mState |= NS_STATE_IS_HORIZONTAL;
|
||||
else
|
||||
mState &= ~NS_STATE_IS_HORIZONTAL;
|
||||
|
||||
|
||||
PRBool autostretch = mState & NS_STATE_AUTO_STRETCH;
|
||||
GetInitialAutoStretch(autostretch);
|
||||
if (autostretch)
|
||||
mState |= NS_STATE_AUTO_STRETCH;
|
||||
else
|
||||
mState &= ~NS_STATE_AUTO_STRETCH;
|
||||
|
||||
|
||||
PRBool debug = mState & NS_STATE_SET_TO_DEBUG;
|
||||
PRBool debugSet = mInner->GetInitialDebug(debug);
|
||||
if (debugSet) {
|
||||
mState |= NS_STATE_DEBUG_WAS_SET;
|
||||
if (debug)
|
||||
mState |= NS_STATE_SET_TO_DEBUG;
|
||||
else
|
||||
mState &= ~NS_STATE_SET_TO_DEBUG;
|
||||
} else {
|
||||
mState &= ~NS_STATE_DEBUG_WAS_SET;
|
||||
}
|
||||
mInner->CacheAttributes();
|
||||
|
||||
// if we are root and this
|
||||
if (mState & NS_STATE_IS_ROOT)
|
||||
|
@ -376,6 +347,60 @@ nsBoxFrame::Init(nsIPresContext* aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsBoxFrameInner::CacheAttributes()
|
||||
{
|
||||
/*
|
||||
printf("Caching: ");
|
||||
mOuter->DumpBox(stdout);
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
mValign = nsBoxFrame::vAlign_Top;
|
||||
mHalign = nsBoxFrame::hAlign_Left;
|
||||
|
||||
|
||||
mOuter->GetInitialVAlignment(mValign);
|
||||
mOuter->GetInitialHAlignment(mHalign);
|
||||
|
||||
PRBool orient = PR_FALSE;
|
||||
if (mOuter->mState & NS_STATE_DEFAULT_HORIZONTAL)
|
||||
orient = PR_TRUE;
|
||||
|
||||
mOuter->GetInitialOrientation(orient);
|
||||
if (orient)
|
||||
mOuter->mState |= NS_STATE_IS_HORIZONTAL;
|
||||
else
|
||||
mOuter->mState &= ~NS_STATE_IS_HORIZONTAL;
|
||||
|
||||
PRBool equalSize = PR_FALSE;
|
||||
mOuter->GetInitialEqualSize(equalSize);
|
||||
if (equalSize)
|
||||
mOuter->mState |= NS_STATE_EQUAL_SIZE;
|
||||
else
|
||||
mOuter->mState &= ~NS_STATE_EQUAL_SIZE;
|
||||
|
||||
PRBool autostretch = mOuter->mState & NS_STATE_AUTO_STRETCH;
|
||||
mOuter->GetInitialAutoStretch(autostretch);
|
||||
if (autostretch)
|
||||
mOuter->mState |= NS_STATE_AUTO_STRETCH;
|
||||
else
|
||||
mOuter->mState &= ~NS_STATE_AUTO_STRETCH;
|
||||
|
||||
|
||||
PRBool debug = mOuter->mState & NS_STATE_SET_TO_DEBUG;
|
||||
PRBool debugSet = GetInitialDebug(debug);
|
||||
if (debugSet) {
|
||||
mOuter->mState |= NS_STATE_DEBUG_WAS_SET;
|
||||
if (debug)
|
||||
mOuter->mState |= NS_STATE_SET_TO_DEBUG;
|
||||
else
|
||||
mOuter->mState &= ~NS_STATE_SET_TO_DEBUG;
|
||||
} else {
|
||||
mOuter->mState &= ~NS_STATE_DEBUG_WAS_SET;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsBoxFrameInner::GetInitialDebug(PRBool& aDebug)
|
||||
{
|
||||
|
@ -553,6 +578,31 @@ nsBoxFrame::GetInitialOrientation(PRBool& aIsHorizontal)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* Returns true if it was set.
|
||||
*/
|
||||
PRBool
|
||||
nsBoxFrame::GetInitialEqualSize(PRBool& aEqualSize)
|
||||
{
|
||||
// see if we are a vertical or horizontal box.
|
||||
nsAutoString value;
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
GetContentOf(getter_AddRefs(content));
|
||||
|
||||
if (!content)
|
||||
return PR_FALSE;
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsXULAtoms::equalsize, value))
|
||||
{
|
||||
if (value.EqualsIgnoreCase("always")) {
|
||||
aEqualSize = PR_TRUE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* Returns true if it was set.
|
||||
*/
|
||||
PRBool
|
||||
|
@ -662,10 +712,7 @@ nsBoxFrame::Reflow(nsIPresContext* aPresContext,
|
|||
else
|
||||
computedSize.height += m.top + m.bottom;
|
||||
|
||||
nsRect r(0,0,computedSize.width, computedSize.height);
|
||||
//r.Inflate(m);
|
||||
r.x = mRect.x;
|
||||
r.y = mRect.y;
|
||||
nsRect r(mRect.x, mRect.y, computedSize.width, computedSize.height);
|
||||
|
||||
SetBounds(state, r);
|
||||
|
||||
|
@ -773,6 +820,14 @@ nsBoxFrame::GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
// @@@ hack to fix bug in xbl where it won't set flex -EDV
|
||||
if ((mState & NS_FRAME_FIRST_REFLOW) && !mInner->mAttributesCached) {
|
||||
mInner->CacheAttributes();
|
||||
mInner->mAttributesCached = PR_TRUE;
|
||||
}
|
||||
*/
|
||||
|
||||
PropagateDebug(aBoxLayoutState);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
@ -819,6 +874,7 @@ nsBoxFrame::PropagateDebug(nsBoxLayoutState& aState)
|
|||
NS_IMETHODIMP
|
||||
nsBoxFrame::Layout(nsBoxLayoutState& aState)
|
||||
{
|
||||
|
||||
// mark ourselves as dirty so no child under us
|
||||
// can post an incremental layout.
|
||||
mState |= NS_FRAME_HAS_DIRTY_CHILDREN;
|
||||
|
@ -1012,6 +1068,7 @@ nsBoxFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|||
aAttribute == nsHTMLAtoms::valign ||
|
||||
aAttribute == nsXULAtoms::flex ||
|
||||
aAttribute == nsXULAtoms::orient ||
|
||||
aAttribute == nsXULAtoms::equalsize ||
|
||||
aAttribute == nsXULAtoms::autostretch) {
|
||||
|
||||
if (aAttribute == nsXULAtoms::orient || aAttribute == nsXULAtoms::debug || aAttribute == nsHTMLAtoms::align || aAttribute == nsHTMLAtoms::valign) {
|
||||
|
@ -1021,13 +1078,20 @@ nsBoxFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|||
GetInitialVAlignment(mInner->mValign);
|
||||
GetInitialHAlignment(mInner->mHalign);
|
||||
|
||||
PRBool orient = mState & NS_STATE_IS_HORIZONTAL;
|
||||
PRBool orient = mState & NS_STATE_DEFAULT_HORIZONTAL;
|
||||
GetInitialOrientation(orient);
|
||||
if (orient)
|
||||
mState |= NS_STATE_IS_HORIZONTAL;
|
||||
else
|
||||
mState &= ~NS_STATE_IS_HORIZONTAL;
|
||||
|
||||
|
||||
PRBool equalSize = PR_FALSE;
|
||||
GetInitialEqualSize(equalSize);
|
||||
if (equalSize)
|
||||
mState |= NS_STATE_EQUAL_SIZE;
|
||||
else
|
||||
mState &= ~NS_STATE_EQUAL_SIZE;
|
||||
|
||||
PRBool debug = mState & NS_STATE_SET_TO_DEBUG;
|
||||
PRBool debugSet = mInner->GetInitialDebug(debug);
|
||||
if (debugSet) {
|
||||
|
|
|
@ -58,6 +58,7 @@ class nsHTMLInfo;
|
|||
#define NS_STATE_IS_COLLAPSED 0x10000000
|
||||
#define NS_STATE_DEFAULT_HORIZONTAL 0x20000000
|
||||
#define NS_STATE_STYLE_CHANGE 0x40000000
|
||||
#define NS_STATE_EQUAL_SIZE 0x80000000
|
||||
|
||||
class nsBoxFrame : public nsHTMLContainerFrame, public nsContainerBox
|
||||
{
|
||||
|
@ -194,6 +195,7 @@ protected:
|
|||
virtual PRIntn GetSkipSides() const { return 0; }
|
||||
|
||||
|
||||
virtual PRBool GetInitialEqualSize(PRBool& aEqualSize);
|
||||
virtual PRBool GetInitialOrientation(PRBool& aIsHorizontal);
|
||||
virtual PRBool GetInitialHAlignment(Halignment& aHalign);
|
||||
virtual PRBool GetInitialVAlignment(Valignment& aValign);
|
||||
|
|
|
@ -0,0 +1,825 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Author: Eric D Vaughan (evaughan@netscape.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*/
|
||||
|
||||
#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 "nsScrollBoxFrame.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIBox.h"
|
||||
#include "nsBoxLayoutState.h"
|
||||
#include "nsIBoxToBlockAdaptor.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIPresState.h"
|
||||
#include "nsButtonBoxFrame.h"
|
||||
#include "nsITimerCallback.h"
|
||||
#include "nsRepeatService.h"
|
||||
|
||||
static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID);
|
||||
static NS_DEFINE_IID(kScrollBoxViewCID, NS_SCROLL_PORT_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);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_NewScrollBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsScrollBoxFrame* it = new (aPresShell) nsScrollBoxFrame (aPresShell);
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
*aNewFrame = it;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsScrollBoxFrame::nsScrollBoxFrame(nsIPresShell* aShell):nsBoxFrame(aShell), mVerticalOverflow(PR_FALSE), mHorizontalOverflow(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsScrollBoxFrame::NeedsClipWidget()
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aStyleContext,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
nsresult rv = nsBoxFrame::Init(aPresContext, aContent,
|
||||
aParent, aStyleContext,
|
||||
aPrevInFlow);
|
||||
|
||||
// Create the scrolling view
|
||||
CreateScrollingView(aPresContext);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList)
|
||||
{
|
||||
nsresult rv = nsBoxFrame::SetInitialChildList(aPresContext, aListName,
|
||||
aChildList);
|
||||
|
||||
SetUpScrolledFrame(aPresContext);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollBoxFrame::SetUpScrolledFrame(nsIPresContext* aPresContext)
|
||||
{
|
||||
NS_ASSERTION(mFrames.GetLength() <= 1, "ScrollBoxes can only have 1 child!");
|
||||
|
||||
|
||||
nsIFrame* frame = mFrames.FirstChild();
|
||||
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
// create a view if we don't already have one.
|
||||
nsCOMPtr<nsIStyleContext> context;
|
||||
frame->GetStyleContext(getter_AddRefs(context));
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, frame,
|
||||
context, PR_TRUE);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::AppendFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
nsresult rv = nsBoxFrame::AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
|
||||
|
||||
#ifdef DEBUG
|
||||
// make sure we only have 1 child.
|
||||
nsIFrame* frame = mFrames.FirstChild();
|
||||
frame->GetNextSibling(&frame);
|
||||
NS_ASSERTION(!frame, "Error ScrollBoxes can only have 1 child");
|
||||
#endif
|
||||
|
||||
SetUpScrolledFrame(aPresContext);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::InsertFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
nsresult rv = nsBoxFrame::InsertFrames(aPresContext, aPresShell, aListName, aPrevFrame, aFrameList);
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
// make sure we only have 1 child.
|
||||
nsIFrame* frame = mFrames.FirstChild();
|
||||
frame->GetNextSibling(&frame);
|
||||
NS_ASSERTION(!frame, "Error ScrollBoxes can only have 1 child");
|
||||
#endif
|
||||
|
||||
SetUpScrolledFrame(aPresContext);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::RemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
nsresult rv = nsBoxFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
|
||||
|
||||
SetUpScrolledFrame(aPresContext);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScrollBoxFrame::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
|
||||
nsScrollBoxFrame::GetScrollingParentView(nsIPresContext* aPresContext,
|
||||
nsIFrame* aParent,
|
||||
nsIView** aParentView)
|
||||
{
|
||||
nsresult rv = aParent->GetView(aPresContext, aParentView);
|
||||
NS_ASSERTION(aParentView, "GetParentWithView failed");
|
||||
return(rv);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScrollBoxFrame::CreateScrollingView(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsIView* view;
|
||||
|
||||
//Get parent frame
|
||||
nsIFrame* parent;
|
||||
GetParentWithView(aPresContext, &parent);
|
||||
NS_ASSERTION(parent, "GetParentWithView failed");
|
||||
|
||||
// Get parent view
|
||||
nsIView* parentView = nsnull;
|
||||
GetScrollingParentView(aPresContext, parent, &parentView);
|
||||
|
||||
// Get the view manager
|
||||
nsIViewManager* viewManager;
|
||||
parentView->GetViewManager(viewManager);
|
||||
|
||||
|
||||
// Create the scrolling view
|
||||
nsresult rv = nsComponentManager::CreateInstance(kScrollBoxViewCID,
|
||||
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, display->IsVisibleOrCollapsed() ?
|
||||
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(aPresContext, view);
|
||||
}
|
||||
|
||||
NS_RELEASE(viewManager);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetMargin(nsMargin& aMargin)
|
||||
{
|
||||
aMargin.SizeTo(0,0,0,0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetPadding(nsMargin& aMargin)
|
||||
{
|
||||
aMargin.SizeTo(0,0,0,0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetBorder(nsMargin& aMargin)
|
||||
{
|
||||
aMargin.SizeTo(0,0,0,0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::Layout(nsBoxLayoutState& aState)
|
||||
{
|
||||
PRUint32 flags = 0;
|
||||
aState.GetLayoutFlags(flags);
|
||||
|
||||
nsRect clientRect(0,0,0,0);
|
||||
GetClientRect(clientRect);
|
||||
nsIBox* kid = nsnull;
|
||||
GetChildBox(&kid);
|
||||
nsRect childRect(clientRect);
|
||||
nsMargin margin(0,0,0,0);
|
||||
kid->GetMargin(margin);
|
||||
childRect.Deflate(margin);
|
||||
nsSize min(0,0);
|
||||
kid->GetMinSize(aState, min);
|
||||
|
||||
/*
|
||||
// if our child is not html then get is min size
|
||||
// and make sure we don't squeeze it smaller than that.
|
||||
nsIBoxToBlockAdaptor* adaptor = nsnull;
|
||||
if (NS_FAILED(kid->QueryInterface(NS_GET_IID(nsIBoxToBlockAdaptor), (void**)&adaptor))) {
|
||||
if (min.height > childRect.height)
|
||||
childRect.height = min.height;
|
||||
}
|
||||
*/
|
||||
|
||||
if (min.height > childRect.height)
|
||||
childRect.height = min.height;
|
||||
|
||||
if (min.width > childRect.width)
|
||||
childRect.width = min.width;
|
||||
|
||||
aState.SetLayoutFlags(NS_FRAME_NO_MOVE_VIEW);
|
||||
kid->SetBounds(aState, childRect);
|
||||
kid->Layout(aState);
|
||||
|
||||
kid->GetBounds(childRect);
|
||||
|
||||
clientRect.Inflate(margin);
|
||||
|
||||
if (childRect.width < clientRect.width || childRect.height < childRect.height)
|
||||
{
|
||||
if (childRect.width < clientRect.width)
|
||||
childRect.width = clientRect.width;
|
||||
|
||||
if (childRect.height < clientRect.height)
|
||||
childRect.height = clientRect.height;
|
||||
|
||||
clientRect.Deflate(margin);
|
||||
|
||||
kid->SetBounds(aState, childRect);
|
||||
}
|
||||
|
||||
aState.SetLayoutFlags(flags);
|
||||
|
||||
SyncLayout(aState);
|
||||
|
||||
nsIPresContext* presContext = aState.GetPresContext();
|
||||
nsIScrollableView* scrollingView;
|
||||
nsIView* view;
|
||||
GetView(presContext, &view);
|
||||
if (NS_SUCCEEDED(view->QueryInterface(kScrollViewIID, (void**)&scrollingView))) {
|
||||
scrollingView->ComputeScrollOffsets(PR_TRUE);
|
||||
}
|
||||
|
||||
nsRect scrollPort;
|
||||
GetBounds(scrollPort);
|
||||
|
||||
kid->GetBounds(childRect);
|
||||
|
||||
// first see what changed
|
||||
PRBool vertChanged = PR_FALSE;
|
||||
PRBool horizChanged = PR_FALSE;
|
||||
|
||||
if (mVerticalOverflow && childRect.height <= scrollPort.height) {
|
||||
mVerticalOverflow = PR_FALSE;
|
||||
vertChanged = PR_TRUE;
|
||||
} else if (!mVerticalOverflow && childRect.height > scrollPort.height) {
|
||||
mVerticalOverflow = PR_TRUE;
|
||||
vertChanged = PR_TRUE;
|
||||
}
|
||||
|
||||
if (mHorizontalOverflow && childRect.width <= scrollPort.width) {
|
||||
mHorizontalOverflow = PR_FALSE;
|
||||
horizChanged = PR_TRUE;
|
||||
} else if (!mHorizontalOverflow && childRect.width > scrollPort.width) {
|
||||
mHorizontalOverflow = PR_TRUE;
|
||||
horizChanged = PR_TRUE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aState.GetPresShell(getter_AddRefs(shell));
|
||||
|
||||
// if either changed
|
||||
if (vertChanged || horizChanged)
|
||||
{
|
||||
// are there 2 events or 1?
|
||||
if (vertChanged && horizChanged) {
|
||||
if (mVerticalOverflow == mHorizontalOverflow)
|
||||
{
|
||||
// both either overflowed or underflowed. 1 event
|
||||
PostScrollPortEvent(shell, mVerticalOverflow, nsScrollPortEvent::both);
|
||||
} else {
|
||||
// one overflowed and one underflowed
|
||||
PostScrollPortEvent(shell, mVerticalOverflow, nsScrollPortEvent::vertical);
|
||||
PostScrollPortEvent(shell, mHorizontalOverflow, nsScrollPortEvent::horizontal);
|
||||
}
|
||||
} else if (vertChanged) // only one changed either vert or horiz
|
||||
PostScrollPortEvent(shell, mVerticalOverflow, nsScrollPortEvent::vertical);
|
||||
else
|
||||
PostScrollPortEvent(shell, mHorizontalOverflow, nsScrollPortEvent::horizontal);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollBoxFrame::PostScrollPortEvent(nsIPresShell* aShell, PRBool aOverflow, nsScrollPortEvent::orientType aType)
|
||||
{
|
||||
if (!mContent)
|
||||
return;
|
||||
|
||||
nsScrollPortEvent* event = new nsScrollPortEvent();
|
||||
event->eventStructType = NS_SCROLLPORT_EVENT;
|
||||
event->widget = nsnull;
|
||||
event->orient = aType;
|
||||
event->nativeMsg = nsnull;
|
||||
event->message = aOverflow ? NS_SCROLLPORT_OVERFLOW : NS_SCROLLPORT_UNDERFLOW;
|
||||
|
||||
aShell->PostDOMEvent(mContent, event);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetAscent(nsBoxLayoutState& aState, nscoord& aAscent)
|
||||
{
|
||||
aAscent = 0;
|
||||
nsIBox* child = nsnull;
|
||||
GetChildBox(&child);
|
||||
nsresult rv = child->GetAscent(aState, aAscent);
|
||||
nsMargin m(0,0,0,0);
|
||||
GetBorderAndPadding(m);
|
||||
aAscent += m.top;
|
||||
GetMargin(m);
|
||||
aAscent += m.top;
|
||||
GetInset(m);
|
||||
aAscent += m.top;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
|
||||
{
|
||||
nsIBox* child = nsnull;
|
||||
GetChildBox(&child);
|
||||
nsresult rv = child->GetPrefSize(aBoxLayoutState, aSize);
|
||||
AddMargin(child, aSize);
|
||||
AddBorderAndPadding(aSize);
|
||||
AddInset(aSize);
|
||||
nsIBox::AddCSSPrefSize(aBoxLayoutState, this, aSize);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
|
||||
{
|
||||
aSize.width = 0;
|
||||
aSize.height = 0;
|
||||
AddBorderAndPadding(aSize);
|
||||
AddInset(aSize);
|
||||
nsIBox::AddCSSMinSize(aBoxLayoutState, this, aSize);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
|
||||
{
|
||||
nsIBox* child = nsnull;
|
||||
GetChildBox(&child);
|
||||
nsresult rv = child->GetMaxSize(aBoxLayoutState, aSize);
|
||||
AddMargin(child, aSize);
|
||||
AddBorderAndPadding(aSize);
|
||||
AddInset(aSize);
|
||||
nsIBox::AddCSSMaxSize(aBoxLayoutState, this, aSize);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::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->IsVisibleOrCollapsed()) {
|
||||
// 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
|
||||
nsresult rv = nsBoxFrame::Paint(aPresContext, aRenderingContext, aDirtyRect,
|
||||
aWhichLayer);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRIntn
|
||||
nsScrollBoxFrame::GetSkipSides() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScrollBoxFrame::GetContentOf(nsIContent** aContent)
|
||||
{
|
||||
return GetContent(aContent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetFrameType(nsIAtom** aType) const
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer");
|
||||
*aType = nsLayoutAtoms::scrollFrame;
|
||||
NS_ADDREF(*aType);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetFrameName(nsString& aResult) const
|
||||
{
|
||||
return MakeFrameName("ScrollBox", aResult);
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsScrollBoxFrame::AddRef(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsScrollBoxFrame::Release(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIStatefulFrame
|
||||
//----------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::GetStateType(nsIPresContext* aPresContext,
|
||||
nsIStatefulFrame::StateType* aStateType)
|
||||
{
|
||||
*aStateType = nsIStatefulFrame::eScrollType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::SaveState(nsIPresContext* aPresContext,
|
||||
nsIPresState** aState)
|
||||
{
|
||||
nsresult res = NS_OK;
|
||||
PRInt32 x,y;
|
||||
nsIScrollableView* scrollingView;
|
||||
nsIView* view;
|
||||
GetView(aPresContext, &view);
|
||||
if (NS_SUCCEEDED(view->QueryInterface(kScrollViewIID, (void**)&scrollingView))) {
|
||||
scrollingView->GetScrollPosition(x,y);
|
||||
}
|
||||
nsIView* child = nsnull;
|
||||
nsRect childRect(0,0,0,0);
|
||||
if (NS_SUCCEEDED(scrollingView->GetScrolledView(child)) && child) {
|
||||
child->GetBounds(childRect);
|
||||
}
|
||||
|
||||
res = NS_NewPresState(aState);
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset;
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(xoffset));
|
||||
if (NS_SUCCEEDED(res) && xoffset) {
|
||||
res = xoffset->SetData(x);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
(*aState)->SetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("x-offset"), xoffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset;
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(yoffset));
|
||||
if (NS_SUCCEEDED(res) && yoffset) {
|
||||
res = yoffset->SetData(y);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
(*aState)->SetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("y-offset"), yoffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsISupportsPRInt32> width;
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(width));
|
||||
if (NS_SUCCEEDED(res) && width) {
|
||||
res = width->SetData(childRect.width);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
(*aState)->SetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("width"), width);
|
||||
}
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsISupportsPRInt32> height;
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(height));
|
||||
if (NS_SUCCEEDED(res) && height) {
|
||||
res = height->SetData(childRect.height);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
(*aState)->SetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("height"), height);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::RestoreState(nsIPresContext* aPresContext,
|
||||
nsIPresState* aState)
|
||||
{
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> width;
|
||||
nsCOMPtr<nsISupportsPRInt32> height;
|
||||
aState->GetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("x-offset"), getter_AddRefs(xoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("y-offset"), getter_AddRefs(yoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("width"), getter_AddRefs(width));
|
||||
aState->GetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("height"), getter_AddRefs(height));
|
||||
|
||||
nsresult res = NS_ERROR_NULL_POINTER;
|
||||
if (xoffset && yoffset) {
|
||||
PRInt32 x,y,w,h;
|
||||
res = xoffset->GetData(&x);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = yoffset->GetData(&y);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = width->GetData(&w);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = height->GetData(&h);
|
||||
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
|
||||
nsIScrollableView* scrollingView;
|
||||
nsIView* view;
|
||||
GetView(aPresContext, &view);
|
||||
if (NS_SUCCEEDED(view->QueryInterface(kScrollViewIID, (void**)&scrollingView))) {
|
||||
|
||||
nsIView* child = nsnull;
|
||||
nsRect childRect(0,0,0,0);
|
||||
if (NS_SUCCEEDED(scrollingView->GetScrolledView(child)) && child) {
|
||||
child->GetBounds(childRect);
|
||||
}
|
||||
x = (int)(((float)childRect.width / w) * x);
|
||||
y = (int)(((float)childRect.height / h) * y);
|
||||
|
||||
scrollingView->ScrollTo(x,y,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsScrollBoxFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIBox)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStatefulFrame)
|
||||
#ifdef NS_DEBUG
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFrameDebug)
|
||||
#endif
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIBox)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
|
||||
|
||||
|
||||
class nsAutoRepeatBoxFrame : public nsButtonBoxFrame,
|
||||
public nsITimerCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
nsAutoRepeatBoxFrame(nsIPresShell* aPresShell);
|
||||
friend nsresult NS_NewAutoRepeatBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
|
||||
|
||||
NS_IMETHOD HandleEvent(nsIPresContext* aPresContext,
|
||||
nsGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
NS_IMETHOD Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
NS_IMETHOD_(void) Notify(nsITimer *timer);
|
||||
|
||||
nsIPresContext* mPresContext;
|
||||
|
||||
};
|
||||
|
||||
nsresult
|
||||
NS_NewAutoRepeatBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsAutoRepeatBoxFrame* it = new (aPresShell) nsAutoRepeatBoxFrame (aPresShell);
|
||||
if (nsnull == it)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
*aNewFrame = it;
|
||||
return NS_OK;
|
||||
|
||||
} // NS_NewScrollBarButtonFrame
|
||||
|
||||
|
||||
nsAutoRepeatBoxFrame::nsAutoRepeatBoxFrame(nsIPresShell* aPresShell)
|
||||
:nsButtonBoxFrame(aPresShell)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoRepeatBoxFrame::Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
mPresContext = aPresContext;
|
||||
return nsButtonBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsAutoRepeatBoxFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsButtonBoxFrame)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsAutoRepeatBoxFrame, nsButtonBoxFrame)
|
||||
NS_IMPL_RELEASE_INHERITED(nsAutoRepeatBoxFrame, nsButtonBoxFrame)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoRepeatBoxFrame::HandleEvent(nsIPresContext* aPresContext,
|
||||
nsGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus)
|
||||
{
|
||||
switch(aEvent->message)
|
||||
{
|
||||
case NS_MOUSE_ENTER:
|
||||
case NS_MOUSE_ENTER_SYNTH:
|
||||
nsRepeatService::GetInstance()->Start(this);
|
||||
break;
|
||||
|
||||
case NS_MOUSE_EXIT:
|
||||
case NS_MOUSE_EXIT_SYNTH:
|
||||
nsRepeatService::GetInstance()->Stop();
|
||||
break;
|
||||
}
|
||||
|
||||
return nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
nsAutoRepeatBoxFrame::Notify(nsITimer *timer)
|
||||
{
|
||||
MouseClicked(mPresContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoRepeatBoxFrame::Destroy(nsIPresContext* aPresContext)
|
||||
{
|
||||
// Ensure our repeat service isn't going... it's possible that a scrollbar can disappear out
|
||||
// from under you while you're in the process of scrolling.
|
||||
nsRepeatService::GetInstance()->Stop();
|
||||
return nsButtonBoxFrame::Destroy(aPresContext);
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#ifndef nsScrollBoxFrame_h___
|
||||
#define nsScrollBoxFrame_h___
|
||||
|
||||
#include "nsBoxFrame.h"
|
||||
#include "nsIStatefulFrame.h"
|
||||
#include "nsGUIEvent.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 nsScrollBoxFrame : public nsBoxFrame, public nsIStatefulFrame {
|
||||
public:
|
||||
friend nsresult NS_NewScrollBoxFrame(nsIPresShell* aPresShell, 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 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;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
NS_IMETHOD GetFrameName(nsString& aResult) const;
|
||||
#endif
|
||||
|
||||
// nsIBox methods
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
|
||||
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
|
||||
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
|
||||
NS_IMETHOD GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent);
|
||||
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
|
||||
NS_IMETHOD GetPadding(nsMargin& aMargin);
|
||||
NS_IMETHOD GetBorder(nsMargin& aMargin);
|
||||
NS_IMETHOD GetMargin(nsMargin& aMargin);
|
||||
|
||||
virtual nsresult GetContentOf(nsIContent** aContent);
|
||||
|
||||
protected:
|
||||
nsScrollBoxFrame(nsIPresShell* aShell);
|
||||
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(nsIPresContext* aPresContext,
|
||||
nsIFrame* aParent,
|
||||
nsIView** aParentView);
|
||||
|
||||
//nsIStatefulFrame
|
||||
NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType);
|
||||
NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState);
|
||||
NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState);
|
||||
|
||||
private:
|
||||
nsresult CreateScrollingView(nsIPresContext* aPresContext);
|
||||
PRBool mVerticalOverflow;
|
||||
PRBool mHorizontalOverflow;
|
||||
|
||||
protected:
|
||||
virtual PRBool NeedsClipWidget();
|
||||
virtual void PostScrollPortEvent(nsIPresShell* aShell, PRBool aOverflow, nsScrollPortEvent::orientType aType);
|
||||
virtual void SetUpScrolledFrame(nsIPresContext* aPresContext);
|
||||
};
|
||||
|
||||
#endif /* nsScrollBoxFrame_h___ */
|
|
@ -0,0 +1,452 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIScrollBoxObject.h"
|
||||
#include "nsBoxObject.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsIBox.h"
|
||||
|
||||
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
|
||||
|
||||
class nsScrollBoxObject : public nsIScrollBoxObject, public nsBoxObject
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSISCROLLBOXOBJECT
|
||||
|
||||
nsScrollBoxObject();
|
||||
virtual ~nsScrollBoxObject();
|
||||
|
||||
virtual nsIScrollableView* GetScrollableView();
|
||||
|
||||
/* additional members */
|
||||
};
|
||||
|
||||
/* Implementation file */
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsScrollBoxObject)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScrollBoxObject)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsBoxObject)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsScrollBoxObject, nsBoxObject)
|
||||
NS_IMPL_RELEASE_INHERITED(nsScrollBoxObject, nsBoxObject)
|
||||
|
||||
nsScrollBoxObject::nsScrollBoxObject()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
||||
nsScrollBoxObject::~nsScrollBoxObject()
|
||||
{
|
||||
/* destructor code */
|
||||
}
|
||||
|
||||
/* void scrollTo (in long x, in long y); */
|
||||
NS_IMETHODIMP nsScrollBoxObject::ScrollTo(PRInt32 x, PRInt32 y)
|
||||
{
|
||||
nsIScrollableView* scrollableView = GetScrollableView();
|
||||
if (!scrollableView)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return scrollableView->ScrollTo(x,y, NS_SCROLL_PROPERTY_ALWAYS_BLIT);
|
||||
}
|
||||
|
||||
/* void scrollBy (in long dx, in long dy); */
|
||||
NS_IMETHODIMP nsScrollBoxObject::ScrollBy(PRInt32 dx, PRInt32 dy)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void scrollByLine (in long dlines); */
|
||||
NS_IMETHODIMP nsScrollBoxObject::ScrollByLine(PRInt32 dlines)
|
||||
{
|
||||
nsIScrollableView* scrollableView = GetScrollableView();
|
||||
if (!scrollableView)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return scrollableView->ScrollByLines(0, dlines);
|
||||
}
|
||||
|
||||
/* void scrollByIndex (in long dindexes); */
|
||||
NS_IMETHODIMP nsScrollBoxObject::ScrollByIndex(PRInt32 dindexes)
|
||||
{
|
||||
nsIScrollableView* scrollableView = GetScrollableView();
|
||||
if (!scrollableView)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// get our box
|
||||
nsIFrame* frame = GetFrame();
|
||||
nsCOMPtr<nsIBox> box (do_QueryInterface(frame));
|
||||
|
||||
nsRect rect;
|
||||
nsIBox* scrolledBox;
|
||||
nsIBox* child;
|
||||
|
||||
// get the scrolled box
|
||||
box->GetChildBox(&scrolledBox);
|
||||
|
||||
// now get the scrolled boxes first child.
|
||||
scrolledBox->GetChildBox(&child);
|
||||
|
||||
PRBool horiz = PR_FALSE;
|
||||
scrolledBox->GetOrientation(horiz);
|
||||
nsPoint cp;
|
||||
scrollableView->GetScrollPosition(cp.x,cp.y);
|
||||
nscoord diff = 0;
|
||||
PRInt32 curIndex = 0;
|
||||
|
||||
// first find out what index we are currently at
|
||||
while(child) {
|
||||
child->GetBounds(rect);
|
||||
if (horiz) {
|
||||
diff = rect.x + rect.width;
|
||||
if (diff > cp.x) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
diff = rect.y + rect.height;
|
||||
if (diff > cp.y) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
child->GetNextBox(&child);
|
||||
curIndex++;
|
||||
}
|
||||
|
||||
PRInt32 count = 0;
|
||||
|
||||
if (dindexes == 0)
|
||||
return NS_OK;
|
||||
|
||||
if (dindexes > 0) {
|
||||
while(child) {
|
||||
child->GetNextBox(&child);
|
||||
child->GetBounds(rect);
|
||||
count++;
|
||||
if (count >= dindexes)
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (dindexes < 0) {
|
||||
scrolledBox->GetChildBox(&child);
|
||||
while(child) {
|
||||
child->GetBounds(rect);
|
||||
if (count >= curIndex + dindexes)
|
||||
break;
|
||||
|
||||
count++;
|
||||
child->GetNextBox(&child);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (horiz)
|
||||
return scrollableView->ScrollTo(rect.x, cp.y, NS_SCROLL_PROPERTY_ALWAYS_BLIT);
|
||||
else
|
||||
return scrollableView->ScrollTo(cp.x, rect.y, NS_SCROLL_PROPERTY_ALWAYS_BLIT);
|
||||
}
|
||||
|
||||
/* void scrollToLine (in long line); */
|
||||
NS_IMETHODIMP nsScrollBoxObject::ScrollToLine(PRInt32 line)
|
||||
{
|
||||
nsIScrollableView* scrollableView = GetScrollableView();
|
||||
if (!scrollableView)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nscoord height = 0;
|
||||
scrollableView->GetLineHeight(&height);
|
||||
scrollableView->ScrollTo(0,height*line, NS_SCROLL_PROPERTY_ALWAYS_BLIT);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void scrollToElement (in nsIDOMElement child); */
|
||||
NS_IMETHODIMP nsScrollBoxObject::ScrollToElement(nsIDOMElement *child)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void scrollToIndex (in long index); */
|
||||
NS_IMETHODIMP nsScrollBoxObject::ScrollToIndex(PRInt32 index)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void getPosition (out long x, out long y); */
|
||||
NS_IMETHODIMP nsScrollBoxObject::GetPosition(PRInt32 *x, PRInt32 *y)
|
||||
{
|
||||
nsIScrollableView* scrollableView = GetScrollableView();
|
||||
if (!scrollableView)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return scrollableView->GetScrollPosition(*x,*y);
|
||||
}
|
||||
|
||||
/* void getScrolledSize (out long width, out long height); */
|
||||
NS_IMETHODIMP nsScrollBoxObject::GetScrolledSize(PRInt32 *width, PRInt32 *height)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void ensureElementIsVisible (in nsIDOMElement child); */
|
||||
NS_IMETHODIMP nsScrollBoxObject::EnsureElementIsVisible(nsIDOMElement *child)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void ensureIndexIsVisible (in long index); */
|
||||
NS_IMETHODIMP nsScrollBoxObject::EnsureIndexIsVisible(PRInt32 index)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void ensureLineIsVisible (in long line); */
|
||||
NS_IMETHODIMP nsScrollBoxObject::EnsureLineIsVisible(PRInt32 line)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsIScrollableView*
|
||||
nsScrollBoxObject::GetScrollableView()
|
||||
{
|
||||
// get the frame.
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIPresContext> context;
|
||||
mPresShell->GetPresContext(getter_AddRefs(context));
|
||||
nsIView* view;
|
||||
frame->GetView(context, &view);
|
||||
nsIScrollableView* scrollingView = nsnull;
|
||||
if (NS_SUCCEEDED(view->QueryInterface(kScrollViewIID, (void**)&scrollingView))) {
|
||||
return scrollingView;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewScrollBoxObject(nsIBoxObject** aResult)
|
||||
{
|
||||
*aResult = new nsScrollBoxObject;
|
||||
if (!*aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
//#define XULTREE
|
||||
|
||||
// XXX Hack
|
||||
#include "nsTreeOuterFrame.h"
|
||||
|
||||
class nsTreeBoxObject : public nsITreeBoxObject, public nsBoxObject
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITREEBOXOBJECT
|
||||
|
||||
nsTreeBoxObject();
|
||||
virtual ~nsTreeBoxObject();
|
||||
|
||||
// XXX Will go away as soon as I get off tables.
|
||||
nsIFrame* GetFrame();
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
/* Implementation file */
|
||||
NS_IMPL_ADDREF(nsTreeBoxObject)
|
||||
NS_IMPL_RELEASE(nsTreeBoxObject)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeBoxObject::QueryInterface(REFNSIID iid, void** aResult)
|
||||
{
|
||||
if (!aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (iid.Equals(NS_GET_IID(nsITreeBoxObject))) {
|
||||
*aResult = (nsITreeBoxObject*)this;
|
||||
NS_ADDREF(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsBoxObject::QueryInterface(iid, aResult);
|
||||
}
|
||||
|
||||
nsTreeBoxObject::nsTreeBoxObject()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsTreeBoxObject::~nsTreeBoxObject()
|
||||
{
|
||||
/* destructor code */
|
||||
}
|
||||
|
||||
// XXX Whole function is a hack that will go away.
|
||||
nsIFrame*
|
||||
nsTreeBoxObject::GetFrame()
|
||||
{
|
||||
#ifdef XULTREE
|
||||
return nsBoxObject::GetFrame();
|
||||
#else
|
||||
nsIFrame* frame = nsBoxObject::GetFrame();
|
||||
if (!frame)
|
||||
return nsnull;
|
||||
|
||||
nsTreeOuterFrame* outerFrame = (nsTreeOuterFrame*)frame;
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
mPresShell->GetPresContext(getter_AddRefs(presContext));
|
||||
|
||||
nsITreeFrame* treeFrame = outerFrame->FindTreeFrame(presContext);
|
||||
if (!treeFrame)
|
||||
return nsnull;
|
||||
|
||||
return (nsIFrame*)treeFrame;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* void ensureIndexIsVisible (in long rowIndex); */
|
||||
NS_IMETHODIMP nsTreeBoxObject::EnsureIndexIsVisible(PRInt32 aRowIndex)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsITreeFrame> treeFrame(do_QueryInterface(frame));
|
||||
return treeFrame->EnsureRowIsVisible(aRowIndex);
|
||||
}
|
||||
|
||||
/* void scrollToIndex (in long rowIndex); */
|
||||
NS_IMETHODIMP nsTreeBoxObject::ScrollToIndex(PRInt32 aRowIndex)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsITreeFrame> treeFrame(do_QueryInterface(frame));
|
||||
return treeFrame->ScrollToIndex(aRowIndex);
|
||||
}
|
||||
|
||||
/* nsIDOMElement getNextItem (in nsIDOMElement startItem, in long delta); */
|
||||
NS_IMETHODIMP nsTreeBoxObject::GetNextItem(nsIDOMElement *aStartItem, PRInt32 aDelta, nsIDOMElement **aResult)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsITreeFrame> treeFrame(do_QueryInterface(frame));
|
||||
|
||||
return treeFrame->GetNextItem(aStartItem, aDelta, aResult);
|
||||
}
|
||||
|
||||
/* nsIDOMElement getPreviousItem (in nsIDOMElement startItem, in long delta); */
|
||||
NS_IMETHODIMP nsTreeBoxObject::GetPreviousItem(nsIDOMElement *aStartItem, PRInt32 aDelta, nsIDOMElement **aResult)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsITreeFrame> treeFrame(do_QueryInterface(frame));
|
||||
return treeFrame->GetPreviousItem(aStartItem, aDelta, aResult);
|
||||
}
|
||||
|
||||
/* nsIDOMElement getItemAtIndex (in long index); */
|
||||
NS_IMETHODIMP nsTreeBoxObject::GetItemAtIndex(PRInt32 index, nsIDOMElement **_retval)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsITreeFrame> treeFrame(do_QueryInterface(frame));
|
||||
return treeFrame->GetItemAtIndex(index, _retval);
|
||||
}
|
||||
|
||||
/* long getIndexOfItem (in nsIDOMElement item); */
|
||||
NS_IMETHODIMP nsTreeBoxObject::GetIndexOfItem(nsIDOMElement* aElement, PRInt32 *aResult)
|
||||
{
|
||||
*aResult = -1;
|
||||
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsITreeFrame> treeFrame(do_QueryInterface(frame));
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
mPresShell->GetPresContext(getter_AddRefs(presContext));
|
||||
return treeFrame->GetIndexOfItem(presContext, aElement, aResult);
|
||||
}
|
||||
|
||||
/* void getNumberOfVisibleRows (); */
|
||||
NS_IMETHODIMP nsTreeBoxObject::GetNumberOfVisibleRows(PRInt32 *aResult)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsITreeFrame> treeFrame(do_QueryInterface(frame));
|
||||
return treeFrame->GetNumberOfVisibleRows(aResult);
|
||||
}
|
||||
|
||||
/* void getIndexOfFirstVisibleRow (); */
|
||||
NS_IMETHODIMP nsTreeBoxObject::GetIndexOfFirstVisibleRow(PRInt32 *aResult)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsITreeFrame> treeFrame(do_QueryInterface(frame));
|
||||
return treeFrame->GetIndexOfFirstVisibleRow(aResult);
|
||||
}
|
||||
|
||||
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewTreeBoxObject(nsIBoxObject** aResult)
|
||||
{
|
||||
*aResult = new nsTreeBoxObject;
|
||||
if (!*aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -207,7 +207,7 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
|
|||
x = clientRect.x;
|
||||
y = clientRect.y;
|
||||
|
||||
if (!(frameState & NS_STATE_AUTO_STRETCH)) {
|
||||
//if (!(frameState & NS_STATE_AUTO_STRETCH)) {
|
||||
if (frameState & NS_STATE_IS_HORIZONTAL) {
|
||||
switch(halign) {
|
||||
case nsBoxFrame::hAlign_Left:
|
||||
|
@ -238,7 +238,7 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
origX = x;
|
||||
origY = y;
|
||||
|
@ -535,7 +535,7 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
|
|||
x = clientRect.x;
|
||||
y = clientRect.y;
|
||||
|
||||
if (!(frameState & NS_STATE_AUTO_STRETCH)) {
|
||||
//if (!(frameState & NS_STATE_AUTO_STRETCH)) {
|
||||
if (frameState & NS_STATE_IS_HORIZONTAL) {
|
||||
switch(halign) {
|
||||
case nsBoxFrame::hAlign_Left:
|
||||
|
@ -566,7 +566,7 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
if (x != origX || y != origY) {
|
||||
nsIBox* child = nsnull;
|
||||
|
@ -596,6 +596,11 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
|
|||
void
|
||||
nsSprocketLayout::PopulateBoxSizes(nsIBox* aBox, nsBoxLayoutState& aState, nsBoxSize*& aBoxSizes, nsComputedBoxSize*& aComputedBoxSizes, nscoord& aMinSize, nscoord& aMaxSize, PRInt32& aFlexes)
|
||||
{
|
||||
// used for the equal size flag
|
||||
nscoord biggestPrefWidth = 0;
|
||||
nscoord biggestMinWidth = 0;
|
||||
nscoord smallestMaxWidth = NS_INTRINSICSIZE;
|
||||
|
||||
nsFrameState frameState = 0;
|
||||
GetFrameState(aBox, frameState);
|
||||
|
||||
|
@ -737,11 +742,22 @@ nsSprocketLayout::PopulateBoxSizes(nsIBox* aBox, nsBoxLayoutState& aState, nsBox
|
|||
else
|
||||
currentBox->flex = flex;
|
||||
|
||||
//currentBox->collapsed = PR_FALSE;
|
||||
currentBox->pref = prefWidth;
|
||||
currentBox->min = minWidth;
|
||||
currentBox->max = maxWidth;
|
||||
// we we specified all our children are equal size;
|
||||
if (frameState & NS_STATE_EQUAL_SIZE) {
|
||||
|
||||
if (prefWidth > biggestPrefWidth)
|
||||
biggestPrefWidth = prefWidth;
|
||||
|
||||
if (minWidth > biggestMinWidth)
|
||||
biggestMinWidth = minWidth;
|
||||
|
||||
if (maxWidth < smallestMaxWidth)
|
||||
smallestMaxWidth = maxWidth;
|
||||
} else { // not we can set our children right now.
|
||||
currentBox->pref = prefWidth;
|
||||
currentBox->min = minWidth;
|
||||
currentBox->max = maxWidth;
|
||||
}
|
||||
|
||||
NS_ASSERTION(minWidth <= prefWidth && prefWidth <= maxWidth,"Bad min, pref, max widths!");
|
||||
|
||||
|
@ -763,6 +779,7 @@ nsSprocketLayout::PopulateBoxSizes(nsIBox* aBox, nsBoxLayoutState& aState, nsBox
|
|||
}
|
||||
|
||||
currentBox->ascent = ascent;
|
||||
currentBox->collapsed = collapsed;
|
||||
aFlexes += currentBox->flex;
|
||||
|
||||
child->GetNextBox(&child);
|
||||
|
@ -771,6 +788,26 @@ nsSprocketLayout::PopulateBoxSizes(nsIBox* aBox, nsBoxLayoutState& aState, nsBox
|
|||
currentBox = currentBox->next;
|
||||
|
||||
}
|
||||
|
||||
// we we specified all our children are equal size;
|
||||
if (frameState & NS_STATE_EQUAL_SIZE) {
|
||||
currentBox = aBoxSizes;
|
||||
|
||||
while(currentBox)
|
||||
{
|
||||
if (!currentBox->collapsed) {
|
||||
currentBox->pref = biggestPrefWidth;
|
||||
currentBox->min = biggestMinWidth;
|
||||
currentBox->max = smallestMaxWidth;
|
||||
} else {
|
||||
currentBox->pref = 0;
|
||||
currentBox->min = 0;
|
||||
currentBox->max = 0;
|
||||
}
|
||||
currentBox = currentBox->next;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1133,7 +1170,9 @@ nsSprocketLayout::ComputeChildSizes(nsIBox* aBox,
|
|||
NS_IMETHODIMP
|
||||
nsSprocketLayout::GetPrefSize(nsIBox* aBox, nsBoxLayoutState& aState, nsSize& aSize)
|
||||
{
|
||||
PRBool isHorizontal = IsHorizontal(aBox);
|
||||
PRBool isHorizontal = IsHorizontal(aBox);
|
||||
|
||||
nscoord biggestPref = 0;
|
||||
|
||||
aSize.width = 0;
|
||||
aSize.height = 0;
|
||||
|
@ -1143,24 +1182,49 @@ nsSprocketLayout::GetPrefSize(nsIBox* aBox, nsBoxLayoutState& aState, nsSize& aS
|
|||
|
||||
nsIBox* child = nsnull;
|
||||
aBox->GetChildBox(&child);
|
||||
|
||||
nsFrameState frameState = 0;
|
||||
GetFrameState(aBox, frameState);
|
||||
PRBool isEqual = frameState & NS_STATE_EQUAL_SIZE;
|
||||
PRInt32 count = 0;
|
||||
|
||||
while (child)
|
||||
{
|
||||
// ignore collapsed children
|
||||
//PRBool isCollapsed = PR_FALSE;
|
||||
//child->IsCollapsed(aState, isCollapsed);
|
||||
PRBool isCollapsed = PR_FALSE;
|
||||
child->IsCollapsed(aState, isCollapsed);
|
||||
|
||||
//if (!isCollapsed)
|
||||
//{
|
||||
if (!isCollapsed)
|
||||
{
|
||||
nsSize pref(0,0);
|
||||
child->GetPrefSize(aState, pref);
|
||||
AddMargin(child, pref);
|
||||
|
||||
if (isEqual) {
|
||||
if (isHorizontal)
|
||||
{
|
||||
if (pref.width > biggestPref)
|
||||
biggestPref = pref.width;
|
||||
} else {
|
||||
if (pref.height > biggestPref)
|
||||
biggestPref = pref.height;
|
||||
}
|
||||
}
|
||||
|
||||
AddLargestSize(aSize, pref, isHorizontal);
|
||||
//}
|
||||
count++;
|
||||
}
|
||||
|
||||
child->GetNextBox(&child);
|
||||
}
|
||||
|
||||
if (isEqual) {
|
||||
if (isHorizontal)
|
||||
aSize.width = biggestPref*count;
|
||||
else
|
||||
aSize.height = biggestPref*count;
|
||||
}
|
||||
|
||||
// now add our border and padding and insets
|
||||
AddBorderAndPadding(aBox, aSize);
|
||||
AddInset(aBox, aSize);
|
||||
|
@ -1171,8 +1235,9 @@ nsSprocketLayout::GetPrefSize(nsIBox* aBox, nsBoxLayoutState& aState, nsSize& aS
|
|||
NS_IMETHODIMP
|
||||
nsSprocketLayout::GetMinSize(nsIBox* aBox, nsBoxLayoutState& aState, nsSize& aSize)
|
||||
{
|
||||
PRBool isHorizontal = IsHorizontal(aBox);
|
||||
PRBool isHorizontal = IsHorizontal(aBox);
|
||||
|
||||
nscoord biggestMin = 0;
|
||||
|
||||
aSize.width = 0;
|
||||
aSize.height = 0;
|
||||
|
@ -1182,15 +1247,19 @@ nsSprocketLayout::GetMinSize(nsIBox* aBox, nsBoxLayoutState& aState, nsSize& aSi
|
|||
|
||||
nsIBox* child = nsnull;
|
||||
aBox->GetChildBox(&child);
|
||||
|
||||
nsFrameState frameState = 0;
|
||||
GetFrameState(aBox, frameState);
|
||||
PRBool isEqual = frameState & NS_STATE_EQUAL_SIZE;
|
||||
PRInt32 count = 0;
|
||||
|
||||
while (child)
|
||||
{
|
||||
// ignore collapsed children
|
||||
//PRBool isCollapsed = PR_FALSE;
|
||||
//aBox->IsCollapsed(aState, isCollapsed);
|
||||
PRBool isCollapsed = PR_FALSE;
|
||||
aBox->IsCollapsed(aState, isCollapsed);
|
||||
|
||||
//if (!isCollapsed)
|
||||
//{
|
||||
if (!isCollapsed)
|
||||
{
|
||||
nsSize min(0,0);
|
||||
nsSize pref(0,0);
|
||||
nscoord flex = 0;
|
||||
|
@ -1208,13 +1277,33 @@ nsSprocketLayout::GetMinSize(nsIBox* aBox, nsBoxLayoutState& aState, nsSize& aSi
|
|||
min.height = pref.height;
|
||||
}
|
||||
|
||||
if (isEqual) {
|
||||
if (isHorizontal)
|
||||
{
|
||||
if (min.width > biggestMin)
|
||||
biggestMin = min.width;
|
||||
} else {
|
||||
if (min.height > biggestMin)
|
||||
biggestMin = min.height;
|
||||
}
|
||||
}
|
||||
|
||||
AddMargin(child, min);
|
||||
AddLargestSize(aSize, min, isHorizontal);
|
||||
//}
|
||||
count++;
|
||||
}
|
||||
|
||||
child->GetNextBox(&child);
|
||||
}
|
||||
|
||||
|
||||
if (isEqual) {
|
||||
if (isHorizontal)
|
||||
aSize.width = biggestMin*count;
|
||||
else
|
||||
aSize.height = biggestMin*count;
|
||||
}
|
||||
|
||||
// now add our border and padding and insets
|
||||
AddBorderAndPadding(aBox, aSize);
|
||||
AddInset(aBox,aSize);
|
||||
|
@ -1228,6 +1317,7 @@ nsSprocketLayout::GetMaxSize(nsIBox* aBox, nsBoxLayoutState& aState, nsSize& aSi
|
|||
|
||||
PRBool isHorizontal = IsHorizontal(aBox);
|
||||
|
||||
nscoord smallestMax = NS_INTRINSICSIZE;
|
||||
|
||||
aSize.width = NS_INTRINSICSIZE;
|
||||
aSize.height = NS_INTRINSICSIZE;
|
||||
|
@ -1238,25 +1328,54 @@ nsSprocketLayout::GetMaxSize(nsIBox* aBox, nsBoxLayoutState& aState, nsSize& aSi
|
|||
|
||||
nsIBox* child = nsnull;
|
||||
aBox->GetChildBox(&child);
|
||||
|
||||
nsFrameState frameState = 0;
|
||||
GetFrameState(aBox, frameState);
|
||||
PRBool isEqual = frameState & NS_STATE_EQUAL_SIZE;
|
||||
PRInt32 count = 0;
|
||||
|
||||
while (child)
|
||||
{
|
||||
// ignore collapsed children
|
||||
//PRBool isCollapsed = PR_FALSE;
|
||||
//aBox->IsCollapsed(aState, isCollapsed);
|
||||
PRBool isCollapsed = PR_FALSE;
|
||||
aBox->IsCollapsed(aState, isCollapsed);
|
||||
|
||||
//if (!isCollapsed)
|
||||
//{
|
||||
if (!isCollapsed)
|
||||
{
|
||||
// if completely redefined don't even ask our child for its size.
|
||||
nsSize max(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
|
||||
child->GetMaxSize(aState, max);
|
||||
|
||||
AddMargin(child, max);
|
||||
AddSmallestSize(aSize, max, isHorizontal);
|
||||
//}
|
||||
|
||||
child->GetNextBox(&child);
|
||||
|
||||
if (isEqual) {
|
||||
if (isHorizontal)
|
||||
{
|
||||
if (max.width < smallestMax)
|
||||
smallestMax = max.width;
|
||||
} else {
|
||||
if (max.height < smallestMax)
|
||||
smallestMax = max.height;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
child->GetNextBox(&child);
|
||||
}
|
||||
|
||||
if (isEqual) {
|
||||
if (isHorizontal) {
|
||||
if (smallestMax != NS_INTRINSICSIZE)
|
||||
aSize.width = smallestMax*count;
|
||||
else
|
||||
aSize.width = NS_INTRINSICSIZE;
|
||||
} else {
|
||||
if (smallestMax != NS_INTRINSICSIZE)
|
||||
aSize.height = smallestMax*count;
|
||||
else
|
||||
aSize.height = NS_INTRINSICSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
// now add our border and padding and insets
|
||||
|
@ -1474,7 +1593,7 @@ nsBoxSize::Clear()
|
|||
pref = 0;
|
||||
min = 0;
|
||||
max = NS_INTRINSICSIZE;
|
||||
//collapsed = PR_FALSE;
|
||||
collapsed = PR_FALSE;
|
||||
ascent = 0;
|
||||
left = 0;
|
||||
right = 0;
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
nscoord flex;
|
||||
nscoord left;
|
||||
nscoord right;
|
||||
//PRBool collapsed;
|
||||
PRBool collapsed;
|
||||
PRBool bogus;
|
||||
|
||||
nsBoxSize* next;
|
||||
|
|
|
@ -98,13 +98,19 @@ XUL_ATOM(titledbutton, "titledbutton")
|
|||
XUL_ATOM(crop, "crop")
|
||||
|
||||
XUL_ATOM(mode, "mode")
|
||||
XUL_ATOM(equalsize, "equalsize")
|
||||
XUL_ATOM(box, "box")
|
||||
XUL_ATOM(hbox, "hbox")
|
||||
XUL_ATOM(vbox, "vbox")
|
||||
XUL_ATOM(scrollbox, "scrollbox")
|
||||
XUL_ATOM(mousethrough, "mousethrough")
|
||||
XUL_ATOM(flex, "flex")
|
||||
XUL_ATOM(spring, "spring")
|
||||
XUL_ATOM(orient, "orient")
|
||||
XUL_ATOM(autostretch, "autostretch")
|
||||
|
||||
XUL_ATOM(autorepeatbutton, "autorepeatbutton")
|
||||
|
||||
XUL_ATOM(titledbox, "titledbox")
|
||||
XUL_ATOM(title, "title")
|
||||
XUL_ATOM(titledboxContentPseudo, ":titledbox-content")
|
||||
|
|
|
@ -84,3 +84,4 @@ NS_XULATOM(value);
|
|||
NS_XULATOM(width);
|
||||
NS_XULATOM(window);
|
||||
NS_XULATOM(xulcontentsgenerated);
|
||||
NS_XULATOM(scrollbox);
|
||||
|
|
|
@ -218,6 +218,8 @@ nsXULContentUtils::kEventHandlerMap[] = {
|
|||
{ "oncommand", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "onbroadcast", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "oncommandupdate", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "onoverflow", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
{ "onunderflow", nsnull, &NS_GET_IID(nsIDOMMenuListener) },
|
||||
|
||||
{ "onfocus", nsnull, &NS_GET_IID(nsIDOMFocusListener) },
|
||||
{ "onblur", nsnull, &NS_GET_IID(nsIDOMFocusListener) },
|
||||
|
|
|
@ -344,6 +344,7 @@ nsXULElement::Init()
|
|||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
rv = nsComponentManager::CreateInstance(kNameSpaceManagerCID,
|
||||
nsnull,
|
||||
kINameSpaceManagerIID,
|
||||
|
@ -397,6 +398,7 @@ nsXULElement::~nsXULElement()
|
|||
gRDFService = nsnull;
|
||||
}
|
||||
|
||||
|
||||
NS_IF_RELEASE(gNameSpaceManager);
|
||||
|
||||
if (gXULUtils) {
|
||||
|
@ -4035,6 +4037,9 @@ nsXULElement::GetBoxObject(nsIBoxObject** aResult)
|
|||
progID += "-popupset";
|
||||
else if (tag.get() == nsXULAtoms::tree)
|
||||
progID += "-tree";
|
||||
else if (tag.get() == nsXULAtoms::scrollbox)
|
||||
progID += "-scrollbox";
|
||||
|
||||
|
||||
mBoxObject = do_CreateInstance(progID);
|
||||
if (!mBoxObject)
|
||||
|
|
|
@ -330,6 +330,7 @@ protected:
|
|||
static PRInt32 kNameSpaceID_RDF;
|
||||
static PRInt32 kNameSpaceID_XUL;
|
||||
|
||||
|
||||
public:
|
||||
static nsresult
|
||||
Create(nsXULPrototypeElement* aPrototype, nsIDocument* aDocument, PRBool aIsScriptable, nsIContent** aResult);
|
||||
|
|
|
@ -183,6 +183,28 @@ menuitem[checked="true"][menuactive="true"]
|
|||
padding : 3px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Autorepeatbutton
|
||||
*/
|
||||
.autorepeatbutton-up {
|
||||
list-style-image: url("chrome://global/skin/scroll-up.gif")
|
||||
}
|
||||
|
||||
.autorepeatbutton-down {
|
||||
list-style-image: url("chrome://global/skin/scroll-down.gif")
|
||||
}
|
||||
|
||||
autorepeatbutton {
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
autorepeatbutton:hover {
|
||||
background-color : #336699;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -186,6 +186,30 @@ menuitem[checked="true"][disabled="true"]
|
|||
font : smaller;
|
||||
padding : 3px;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Autorepeatbutton
|
||||
*/
|
||||
.autorepeatbutton-up {
|
||||
list-style-image: url("chrome://global/skin/scroll-up.gif")
|
||||
}
|
||||
|
||||
.autorepeatbutton-down {
|
||||
list-style-image: url("chrome://global/skin/scroll-down.gif")
|
||||
}
|
||||
|
||||
autorepeatbutton {
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
autorepeatbutton:hover {
|
||||
background-color: highlight;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -186,6 +186,30 @@ menuitem[checked="true"][disabled="true"]
|
|||
font : smaller;
|
||||
padding : 3px;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Autorepeatbutton
|
||||
*/
|
||||
.autorepeatbutton-up {
|
||||
list-style-image: url("chrome://global/skin/scroll-up.gif")
|
||||
}
|
||||
|
||||
.autorepeatbutton-down {
|
||||
list-style-image: url("chrome://global/skin/scroll-down.gif")
|
||||
}
|
||||
|
||||
autorepeatbutton {
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
autorepeatbutton:hover {
|
||||
background-color : highlight;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -185,6 +185,29 @@ menuitem[checked="true"][menuactive="true"]
|
|||
font : smaller;
|
||||
padding : 3px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Autorepeatbutton
|
||||
*/
|
||||
.autorepeatbutton-up {
|
||||
list-style-image: url("chrome://global/skin/scroll-up.gif")
|
||||
}
|
||||
|
||||
.autorepeatbutton-down {
|
||||
list-style-image: url("chrome://global/skin/scroll-down.gif")
|
||||
}
|
||||
|
||||
autorepeatbutton {
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
autorepeatbutton:hover {
|
||||
background-color: #336699;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -151,6 +151,15 @@ struct nsScrollbarEvent : public nsGUIEvent {
|
|||
PRUint32 position;
|
||||
};
|
||||
|
||||
struct nsScrollPortEvent : public nsGUIEvent {
|
||||
enum orientType {
|
||||
vertical = 0,
|
||||
horizontal = 1,
|
||||
both = 2
|
||||
};
|
||||
|
||||
orientType orient;
|
||||
};
|
||||
|
||||
struct nsInputEvent : public nsGUIEvent {
|
||||
/// PR_TRUE indicates the shift key is down
|
||||
|
@ -278,8 +287,8 @@ enum nsDragDropEventStatus {
|
|||
#define NS_COMPOSITION_END 15
|
||||
#define NS_MOUSE_SCROLL_EVENT 16
|
||||
#define NS_COMPOSITION_QUERY 17
|
||||
#define NS_SCROLLPORT_EVENT 18
|
||||
|
||||
|
||||
/**
|
||||
* GUI MESSAGES
|
||||
*/
|
||||
|
@ -411,6 +420,10 @@ enum nsDragDropEventStatus {
|
|||
#define NS_MOUSE_SCROLL_START 1600
|
||||
#define NS_MOUSE_SCROLL (NS_MOUSE_SCROLL_START)
|
||||
|
||||
#define NS_SCROLLPORT_START 1700
|
||||
#define NS_SCROLLPORT_UNDERFLOW (NS_SCROLLPORT_START)
|
||||
#define NS_SCROLLPORT_OVERFLOW (NS_SCROLLPORT_START+1)
|
||||
|
||||
#define NS_IS_MOUSE_EVENT(evnt) \
|
||||
(((evnt)->message == NS_MOUSE_LEFT_BUTTON_DOWN) || \
|
||||
((evnt)->message == NS_MOUSE_LEFT_BUTTON_UP) || \
|
||||
|
|
|
@ -99,16 +99,26 @@ iframe {
|
|||
behavior: url(chrome://global/content/xulBindings.xml#iframe);
|
||||
}
|
||||
|
||||
/******** ScrollBox ********/
|
||||
|
||||
scrollbox {
|
||||
behavior: url(chrome://global/content/xulBindings.xml#scrollbox);
|
||||
}
|
||||
|
||||
.scrollbox-innerbox {
|
||||
text-align: inherit;
|
||||
vertical-align: inherit;
|
||||
}
|
||||
|
||||
|
||||
/******** ArrowScrollBox ******/
|
||||
|
||||
arrowscrollbox {
|
||||
behavior: url(chrome://global/content/xulBindings.xml#arrowscrollbox);
|
||||
}
|
||||
|
||||
/******** Box *******/
|
||||
|
||||
hbox {
|
||||
behavior: url(chrome://global/content/xulBindings.xml#hbox);
|
||||
}
|
||||
|
||||
vbox {
|
||||
behavior: url(chrome://global/content/xulBindings.xml#vbox);
|
||||
}
|
||||
|
||||
/******** TitledBox *******/
|
||||
|
||||
box.titledbox-title {
|
||||
|
@ -553,4 +563,19 @@ statusbarpanel
|
|||
{
|
||||
user-focus : ignore;
|
||||
behavior : url("chrome://global/content/xulBindings.xml#statusbar-panel");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AutoRepeater
|
||||
*/
|
||||
autorepeater {
|
||||
user-focus : ignore;
|
||||
}
|
||||
|
||||
autorepeatbutton.up {
|
||||
behavior : url("chrome://global/content/xulBindings.xml#autorepeatbutton-up");
|
||||
}
|
||||
|
||||
autorepeatbutton.down {
|
||||
behavior : url("chrome://global/content/xulBindings.xml#autorepeatbutton-down");
|
||||
}
|
|
@ -5,12 +5,6 @@
|
|||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<binding id="hbox" extends="xul:box"/>
|
||||
|
||||
<binding id="vbox" extends="xul:box">
|
||||
<content orient="vertical"/>
|
||||
</binding>
|
||||
|
||||
<binding id="thumb" extends="xul:box">
|
||||
<content>
|
||||
<xul:spring flex="1"/>
|
||||
|
@ -308,9 +302,16 @@
|
|||
|
||||
<binding id="popups">
|
||||
<content>
|
||||
<xul:box class="popup-internal-box" orient="vertical" flex="1" style="overflow: auto">
|
||||
<!--xul:box class="popup-internal-box" orient="vertical" flex="1" style="overflow: auto">
|
||||
<children/>
|
||||
</xul:box>
|
||||
</xul:box-->
|
||||
|
||||
<xul:arrowscrollbox flex="1" orient="vertical">
|
||||
<!--xul:box class="popup-internal-box" orient="vertical"-->
|
||||
<children/>
|
||||
<!--/xul:box-->
|
||||
</xul:arrowscrollbox>
|
||||
|
||||
</content>
|
||||
<interface>
|
||||
<method name="openPopup">
|
||||
|
@ -582,5 +583,51 @@
|
|||
</content>
|
||||
</binding>
|
||||
|
||||
<binding id="autorepeatbutton-up">
|
||||
<content>
|
||||
<xul:image class="autorepeatbutton-up"/>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
<binding id="autorepeatbutton-down">
|
||||
<content>
|
||||
<xul:image class="autorepeatbutton-down"/>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
<binding id="scrollbox">
|
||||
<content>
|
||||
<xul:box class="scrollbox-innerbox" inherits="orient,autostretch,align,valign">
|
||||
<children/>
|
||||
</xul:box>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
<binding id="arrowscrollbox" extends="xul:stack">
|
||||
<content>
|
||||
<xul:vbox
|
||||
onunderflow="
|
||||
var button1 = this.firstChild;
|
||||
var button2 = this.childNodes[2];
|
||||
button1.setAttribute('collapsed', 'true');
|
||||
button2.setAttribute('collapsed', 'true');
|
||||
"
|
||||
onoverflow="
|
||||
var button1 = this.firstChild;
|
||||
var button2 = this.childNodes[2];
|
||||
button1.removeAttribute('collapsed');
|
||||
button2.removeAttribute('collapsed');
|
||||
">
|
||||
<xul:autorepeatbutton autostretch="never" class="up" collapsed="true"
|
||||
oncommand="parentNode.childNodes[1].boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject).scrollByIndex(-1);"/>
|
||||
<xul:scrollbox orient="vertical" flex="1">
|
||||
<children/>
|
||||
</xul:scrollbox>
|
||||
<xul:autorepeatbutton autostretch="never" class="down" collapsed="true"
|
||||
oncommand="parentNode.childNodes[1].boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject).scrollByIndex(1);"/>
|
||||
</xul:vbox>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
</bindings>
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче