108757 - dispatch DOM events for mouse wheel scrolling, r=?, sr=?

This commit is contained in:
hewitt%netscape.com 2001-11-14 10:06:21 +00:00
parent c76d3a0afe
commit 76b5876544
17 changed files with 212 additions and 113 deletions

View File

@ -684,9 +684,13 @@ nsGenericDOMDataNode::HandleDOMEvent(nsIPresContext* aPresContext,
nsresult ret = NS_OK; nsresult ret = NS_OK;
nsIDOMEvent* domEvent = nsnull; nsIDOMEvent* domEvent = nsnull;
PRBool externalDOMEvent = PR_FALSE;
if (NS_EVENT_FLAG_INIT & aFlags) { if (NS_EVENT_FLAG_INIT & aFlags) {
if (!aDOMEvent) { if (!aDOMEvent) {
aDOMEvent = &domEvent; aDOMEvent = &domEvent;
} else {
externalDOMEvent = PR_TRUE;
} }
aEvent->flags = aFlags; aEvent->flags = aFlags;
aFlags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL); aFlags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL);
@ -723,7 +727,7 @@ nsGenericDOMDataNode::HandleDOMEvent(nsIPresContext* aPresContext,
if (NS_EVENT_FLAG_INIT & aFlags) { if (NS_EVENT_FLAG_INIT & aFlags) {
// We're leaving the DOM event loop so if we created a DOM event, // We're leaving the DOM event loop so if we created a DOM event,
// release here. // release here.
if (nsnull != *aDOMEvent) { if (!externalDOMEvent && nsnull != *aDOMEvent) {
if (0 != (*aDOMEvent)->Release()) { if (0 != (*aDOMEvent)->Release()) {
// Okay, so someone in the DOM loop (a listener, JS object) // Okay, so someone in the DOM loop (a listener, JS object)
// still has a ref to the DOM Event but the internal data // still has a ref to the DOM Event but the internal data

View File

@ -1071,6 +1071,7 @@ nsGenericElement::InternalIsSupported(const nsAReadableString& aFeature,
feature.EqualsWithConversion("Events", PR_TRUE) || feature.EqualsWithConversion("Events", PR_TRUE) ||
// feature.EqualsWithConversion("UIEvents", PR_TRUE) || // feature.EqualsWithConversion("UIEvents", PR_TRUE) ||
feature.EqualsWithConversion("MouseEvents", PR_TRUE) || feature.EqualsWithConversion("MouseEvents", PR_TRUE) ||
feature.EqualsWithConversion("MouseScrollEvents", PR_TRUE) ||
feature.EqualsWithConversion("HTMLEvents", PR_TRUE) || feature.EqualsWithConversion("HTMLEvents", PR_TRUE) ||
feature.EqualsWithConversion("Range", PR_TRUE)) { feature.EqualsWithConversion("Range", PR_TRUE)) {
if (!aVersion.Length() || aVersion.Equals(NS_LITERAL_STRING("2.0"))) { if (!aVersion.Length() || aVersion.Equals(NS_LITERAL_STRING("2.0"))) {

View File

@ -166,6 +166,10 @@ nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent,
mEvent = PR_NEWZAP(nsMouseEvent); mEvent = PR_NEWZAP(nsMouseEvent);
mEvent->eventStructType = NS_MOUSE_EVENT; mEvent->eventStructType = NS_MOUSE_EVENT;
} }
else if (eventType.EqualsIgnoreCase("MouseScrollEvents")) {
mEvent = PR_NEWZAP(nsMouseScrollEvent);
mEvent->eventStructType = NS_MOUSE_SCROLL_EVENT;
}
else if (eventType.EqualsIgnoreCase("KeyEvents")) { else if (eventType.EqualsIgnoreCase("KeyEvents")) {
mEvent = PR_NEWZAP(nsKeyEvent); mEvent = PR_NEWZAP(nsKeyEvent);
mEvent->eventStructType = NS_KEY_EVENT; mEvent->eventStructType = NS_KEY_EVENT;
@ -506,6 +510,7 @@ nsDOMEvent::GetDetail(PRInt32* aDetail)
case NS_MOUSE_RIGHT_BUTTON_DOWN: case NS_MOUSE_RIGHT_BUTTON_DOWN:
case NS_MOUSE_RIGHT_CLICK: case NS_MOUSE_RIGHT_CLICK:
case NS_MOUSE_RIGHT_DOUBLECLICK: case NS_MOUSE_RIGHT_DOUBLECLICK:
case NS_USER_DEFINED_EVENT:
*aDetail = ((nsMouseEvent*)mEvent)->clickCount; *aDetail = ((nsMouseEvent*)mEvent)->clickCount;
break; break;
default: default:
@ -514,6 +519,12 @@ nsDOMEvent::GetDetail(PRInt32* aDetail)
return NS_OK; return NS_OK;
} }
case NS_MOUSE_SCROLL_EVENT:
{
*aDetail = ((nsMouseScrollEvent*)mEvent)->delta;
break;
}
default: default:
*aDetail = 0; *aDetail = 0;
return NS_OK; return NS_OK;
@ -1212,7 +1223,7 @@ nsDOMEvent::InitUIEvent(const nsAReadableString& aTypeArg, PRBool aCanBubbleArg,
NS_IMETHODIMP NS_IMETHODIMP
nsDOMEvent::InitMouseEvent(const nsAReadableString & aTypeArg, PRBool aCanBubbleArg, PRBool aCancelableArg, nsDOMEvent::InitMouseEvent(const nsAReadableString & aTypeArg, PRBool aCanBubbleArg, PRBool aCancelableArg,
nsIDOMAbstractView *aViewArg, PRUint16 aDetailArg, PRInt32 aScreenXArg, nsIDOMAbstractView *aViewArg, PRInt32 aDetailArg, PRInt32 aScreenXArg,
PRInt32 aScreenYArg, PRInt32 aClientXArg, PRInt32 aClientYArg, PRInt32 aScreenYArg, PRInt32 aClientXArg, PRInt32 aClientYArg,
PRBool aCtrlKeyArg, PRBool aAltKeyArg, PRBool aShiftKeyArg, PRBool aCtrlKeyArg, PRBool aAltKeyArg, PRBool aShiftKeyArg,
PRBool aMetaKeyArg, PRUint16 aButtonArg, nsIDOMEventTarget *aRelatedTargetArg) PRBool aMetaKeyArg, PRUint16 aButtonArg, nsIDOMEventTarget *aRelatedTargetArg)
@ -1221,22 +1232,28 @@ nsDOMEvent::InitMouseEvent(const nsAReadableString & aTypeArg, PRBool aCanBubble
mEvent->flags |= aCanBubbleArg ? NS_EVENT_FLAG_NONE : NS_EVENT_FLAG_CANT_BUBBLE; mEvent->flags |= aCanBubbleArg ? NS_EVENT_FLAG_NONE : NS_EVENT_FLAG_CANT_BUBBLE;
mEvent->flags |= aCancelableArg ? NS_EVENT_FLAG_NONE : NS_EVENT_FLAG_CANT_CANCEL; mEvent->flags |= aCancelableArg ? NS_EVENT_FLAG_NONE : NS_EVENT_FLAG_CANT_CANCEL;
if (mEvent->eventStructType == NS_MOUSE_EVENT) { if (mEvent->eventStructType == NS_MOUSE_EVENT || mEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
nsMouseEvent* mouseEvent = NS_STATIC_CAST(nsMouseEvent*, mEvent); nsInputEvent* inputEvent = NS_STATIC_CAST(nsInputEvent*, mEvent);
mouseEvent->isControl = aCtrlKeyArg; inputEvent->isControl = aCtrlKeyArg;
mouseEvent->isAlt = aAltKeyArg; inputEvent->isAlt = aAltKeyArg;
mouseEvent->isShift = aShiftKeyArg; inputEvent->isShift = aShiftKeyArg;
mouseEvent->isMeta = aMetaKeyArg; inputEvent->isMeta = aMetaKeyArg;
mouseEvent->point.x = aClientXArg; inputEvent->point.x = aClientXArg;
mouseEvent->point.y = aClientYArg; inputEvent->point.y = aClientYArg;
mouseEvent->refPoint.x = aScreenXArg; inputEvent->refPoint.x = aScreenXArg;
mouseEvent->refPoint.y = aScreenYArg; inputEvent->refPoint.y = aScreenYArg;
mScreenPoint.x = aScreenXArg; mScreenPoint.x = aScreenXArg;
mScreenPoint.y = aScreenYArg; mScreenPoint.y = aScreenYArg;
mClientPoint.x = aClientXArg; mClientPoint.x = aClientXArg;
mClientPoint.y = aClientYArg; mClientPoint.y = aClientYArg;
mButton = aButtonArg; mButton = aButtonArg;
mouseEvent->clickCount = aDetailArg; if (mEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
nsMouseScrollEvent* scrollEvent = NS_STATIC_CAST(nsMouseScrollEvent*, mEvent);
scrollEvent->delta = aDetailArg;
} else {
nsMouseEvent* mouseEvent = NS_STATIC_CAST(nsMouseEvent*, mEvent);
mouseEvent->clickCount = aDetailArg;
}
} }
//include a way to set view once we have more than one //include a way to set view once we have more than one

View File

@ -161,7 +161,7 @@ public:
NS_IMETHOD GetKeyCode(PRUint32* aKeyCode); NS_IMETHOD GetKeyCode(PRUint32* aKeyCode);
NS_IMETHOD InitMouseEvent(const nsAReadableString & aTypeArg, NS_IMETHOD InitMouseEvent(const nsAReadableString & aTypeArg,
PRBool aCanBubbleArg, PRBool aCancelableArg, PRBool aCanBubbleArg, PRBool aCancelableArg,
nsIDOMAbstractView *aViewArg, PRUint16 aDetailArg, nsIDOMAbstractView *aViewArg, PRInt32 aDetailArg,
PRInt32 aScreenXArg, PRInt32 aDcreenYArg, PRInt32 aScreenXArg, PRInt32 aDcreenYArg,
PRInt32 aClientXArg, PRInt32 aClientYArg, PRInt32 aClientXArg, PRInt32 aClientYArg,
PRBool aCtrlKeyArg, PRBool aAltKeyArg, PRBool aCtrlKeyArg, PRBool aAltKeyArg,

View File

@ -2342,7 +2342,7 @@ nsEventListenerManager::CreateEvent(nsIPresContext* aPresContext,
nsAutoString str(aEventType); nsAutoString str(aEventType);
if (!aEvent && !str.EqualsIgnoreCase("MouseEvents") && !str.EqualsIgnoreCase("KeyEvents") && if (!aEvent && !str.EqualsIgnoreCase("MouseEvents") && !str.EqualsIgnoreCase("KeyEvents") &&
!str.EqualsIgnoreCase("HTMLEvents") && !str.EqualsIgnoreCase("MutationEvents") && !str.EqualsIgnoreCase("HTMLEvents") && !str.EqualsIgnoreCase("MutationEvents") &&
!str.EqualsIgnoreCase("Events")) { !str.EqualsIgnoreCase("MouseScrollEvents") && !str.EqualsIgnoreCase("Events")) {
return NS_ERROR_DOM_NOT_SUPPORTED_ERR; return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
} }

View File

@ -93,6 +93,12 @@
#include "nsIOutlinerBoxObject.h" #include "nsIOutlinerBoxObject.h"
#include "nsIScrollableViewProvider.h" #include "nsIScrollableViewProvider.h"
#include "nsIDOMDocumentRange.h" #include "nsIDOMDocumentRange.h"
#include "nsIDOMDocumentEvent.h"
#include "nsIDOMMouseEvent.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMDocumentView.h"
#include "nsIDOMAbstractView.h"
#include "nsIDOMNSUIEvent.h"
#include "nsIDOMRange.h" #include "nsIDOMRange.h"
#include "nsICaret.h" #include "nsICaret.h"
@ -1200,63 +1206,6 @@ nsEventStateManager::ChangeTextSize(PRInt32 change)
// //
// DoTreeScroll
//
// Trees know best how to deal with scrolling, so use the tree scroll api's instead
// of just blindly scrolling the view.
//
nsresult
nsEventStateManager::DoTreeScroll(nsIPresContext* inPresContext, PRInt32 inNumLines,
PRBool inScrollPage, nsITreeFrame* inTreeFrame)
{
PRInt32 scrollIndex, visibleRows;
inTreeFrame->GetIndexOfFirstVisibleRow(&scrollIndex);
inTreeFrame->GetNumberOfVisibleRows(&visibleRows);
if (inScrollPage)
scrollIndex += ((inNumLines > 0) ? visibleRows : -visibleRows);
else
scrollIndex += inNumLines;
if (scrollIndex < 0)
scrollIndex = 0;
else {
PRInt32 numRows;
inTreeFrame->GetRowCount(&numRows);
PRInt32 lastPageTopRow = numRows - visibleRows;
if (scrollIndex > lastPageTopRow)
scrollIndex = lastPageTopRow;
}
inTreeFrame->ScrollToIndex(scrollIndex);
// we have to do a sync update for mac because if we scroll too quickly
// w/out going back to the main event loop we can easily scroll the wrong
// bits and it looks like garbage (bug 63465).
nsIFrame* frame = nsnull;
if ( NS_SUCCEEDED(inTreeFrame->QueryInterface(NS_GET_IID(nsIFrame),
(void **)&frame)) ) {
nsIView* treeView = nsnull;
frame->GetView(inPresContext, &treeView);
if (!treeView) {
nsIFrame* frameWithView;
frame->GetParentWithView(inPresContext, &frameWithView);
if (frameWithView)
frameWithView->GetView(inPresContext, &treeView);
else
return NS_ERROR_FAILURE;
}
if (treeView)
ForceViewUpdate(treeView);
}
else
return NS_ERROR_FAILURE;
return NS_OK;
} // DoTreeScroll
nsresult nsresult
nsEventStateManager::DoWheelScroll(nsIPresContext* aPresContext, nsEventStateManager::DoWheelScroll(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame, nsIFrame* aTargetFrame,
@ -1264,27 +1213,50 @@ nsEventStateManager::DoWheelScroll(nsIPresContext* aPresContext,
PRInt32 numLines, PRBool scrollPage, PRInt32 numLines, PRBool scrollPage,
PRBool aUseTargetFrame) PRBool aUseTargetFrame)
{ {
nsCOMPtr<nsIContent> targetContent;
aTargetFrame->GetContent(getter_AddRefs(targetContent));
nsCOMPtr<nsIDocument> targetDoc;
targetContent->GetDocument(*getter_AddRefs(targetDoc));
if (!targetDoc) return NS_OK;
nsCOMPtr<nsIDOMDocumentEvent> targetDOMDoc(do_QueryInterface(targetDoc));
nsCOMPtr<nsIDOMEvent> event;
targetDOMDoc->CreateEvent(NS_LITERAL_STRING("MouseScrollEvents"), getter_AddRefs(event));
if (event) {
nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(event));
nsCOMPtr<nsIDOMDocumentView> docView = do_QueryInterface(targetDoc);
if (!docView) return nsnull;
nsCOMPtr<nsIDOMAbstractView> view;
docView->GetDefaultView(getter_AddRefs(view));
if (scrollPage)
numLines = numLines > 0 ? nsIDOMNSUIEvent::SCROLL_PAGE_DOWN : nsIDOMNSUIEvent::SCROLL_PAGE_UP;
mouseEvent->InitMouseEvent(NS_LITERAL_STRING("DOMMouseScroll"), PR_TRUE, PR_TRUE,
view, numLines,
msEvent->refPoint.x, msEvent->refPoint.y,
msEvent->point.x, msEvent->point.y,
msEvent->isControl, msEvent->isAlt, msEvent->isShift, msEvent->isMeta,
0, nsnull);
PRBool allowDefault;
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(targetContent));
if (target) {
target->DispatchEvent(event, &allowDefault);
if (!allowDefault)
return NS_OK;
}
}
targetDOMDoc->CreateEvent(NS_LITERAL_STRING("MouseScrollEvents"), getter_AddRefs(event));
if (event) {
nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(event));
}
nsIView* focusView = nsnull; nsIView* focusView = nsnull;
nsIScrollableView* sv = nsnull; nsIScrollableView* sv = nsnull;
nsIFrame* focusFrame = nsnull; nsIFrame* focusFrame = nsnull;
// Special case for tree/list frames - they handle their own scrolling
nsITreeFrame* treeFrame = nsnull;
nsCOMPtr<nsIOutlinerBoxObject> outlinerBoxObject;
nsIFrame* curFrame = aTargetFrame;
while (curFrame) {
if (NS_OK == curFrame->QueryInterface(NS_GET_IID(nsITreeFrame),
(void**) &treeFrame))
break;
outlinerBoxObject = do_QueryInterface(curFrame);
if (outlinerBoxObject)
break;
curFrame->GetParent(&curFrame);
}
// Create a mouseout event that we fire to the content before // Create a mouseout event that we fire to the content before
// scrolling, to allow tooltips to disappear, etc. // scrolling, to allow tooltips to disappear, etc.
@ -1300,27 +1272,8 @@ nsEventStateManager::DoWheelScroll(nsIPresContext* aPresContext,
mouseOutEvent.isAlt = PR_FALSE; mouseOutEvent.isAlt = PR_FALSE;
mouseOutEvent.isMeta = PR_FALSE; mouseOutEvent.isMeta = PR_FALSE;
nsCOMPtr<nsIContent> targetContent;
aTargetFrame->GetContent(getter_AddRefs(targetContent));
nsEventStatus mouseoutStatus = nsEventStatus_eIgnore; nsEventStatus mouseoutStatus = nsEventStatus_eIgnore;
if (treeFrame) {
if (targetContent)
targetContent->HandleDOMEvent(aPresContext, &mouseOutEvent, nsnull,
NS_EVENT_FLAG_INIT, &mouseoutStatus);
return DoTreeScroll(aPresContext, numLines, scrollPage, treeFrame);
} else if (outlinerBoxObject) {
if (targetContent)
targetContent->HandleDOMEvent(aPresContext, &mouseOutEvent, nsnull,
NS_EVENT_FLAG_INIT, &mouseoutStatus);
if (scrollPage)
outlinerBoxObject->ScrollByPages((numLines > 0) ? 1 : -1);
else
outlinerBoxObject->ScrollByLines(numLines);
return NS_OK;
}
nsCOMPtr<nsIPresShell> presShell; nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell)); aPresContext->GetShell(getter_AddRefs(presShell));

View File

@ -174,8 +174,6 @@ protected:
nsIFrame* aTargetFrame, nsIFrame* aTargetFrame,
nsMouseScrollEvent* msEvent, PRInt32 numLines, nsMouseScrollEvent* msEvent, PRInt32 numLines,
PRBool scrollPage, PRBool aUseTargetFrame); PRBool scrollPage, PRBool aUseTargetFrame);
nsresult DoTreeScroll(nsIPresContext* inPresContext, PRInt32 inNumLines,
PRBool inScrollPage, nsITreeFrame* inTreeFrame);
void ForceViewUpdate(nsIView* aView); void ForceViewUpdate(nsIView* aView);
nsresult getPrefService(); nsresult getPrefService();
nsresult ChangeTextSize(PRInt32 change); nsresult ChangeTextSize(PRInt32 change);

View File

@ -2388,9 +2388,17 @@ nsXULDocument::HandleDOMEvent(nsIPresContext* aPresContext,
{ {
nsresult ret = NS_OK; nsresult ret = NS_OK;
nsIDOMEvent* domEvent = nsnull; nsIDOMEvent* domEvent = nsnull;
PRBool externalDOMEvent = PR_FALSE;
if (NS_EVENT_FLAG_INIT & aFlags) { if (NS_EVENT_FLAG_INIT & aFlags) {
aDOMEvent = &domEvent; if (aDOMEvent) {
if (*aDOMEvent) {
externalDOMEvent = PR_TRUE;
}
}
else {
aDOMEvent = &domEvent;
}
aEvent->flags = aFlags; aEvent->flags = aFlags;
aFlags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL); aFlags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL);
} }
@ -2414,7 +2422,7 @@ nsXULDocument::HandleDOMEvent(nsIPresContext* aPresContext,
if (NS_EVENT_FLAG_INIT & aFlags) { if (NS_EVENT_FLAG_INIT & aFlags) {
// We're leaving the DOM event loop so if we created a DOM event, release here. // We're leaving the DOM event loop so if we created a DOM event, release here.
if (nsnull != *aDOMEvent) { if (nsnull != *aDOMEvent && !externalDOMEvent) {
nsrefcnt rc; nsrefcnt rc;
NS_RELEASE2(*aDOMEvent, rc); NS_RELEASE2(*aDOMEvent, rc);
if (0 != rc) { if (0 != rc) {

View File

@ -61,7 +61,7 @@ interface nsIDOMMouseEvent : nsIDOMUIEvent
in boolean canBubbleArg, in boolean canBubbleArg,
in boolean cancelableArg, in boolean cancelableArg,
in nsIDOMAbstractView viewArg, in nsIDOMAbstractView viewArg,
in unsigned short detailArg, in long detailArg,
in long screenXArg, in long screenXArg,
in long screenYArg, in long screenYArg,
in long clientXArg, in long clientXArg,

View File

@ -43,6 +43,9 @@
[scriptable, uuid(a6cf90c4-15b3-11d2-932e-00805f8add32)] [scriptable, uuid(a6cf90c4-15b3-11d2-932e-00805f8add32)]
interface nsIDOMNSUIEvent : nsISupports interface nsIDOMNSUIEvent : nsISupports
{ {
const long SCROLL_PAGE_UP = -32768;
const long SCROLL_PAGE_DOWN = 32768;
boolean getPreventDefault(); boolean getPreventDefault();
readonly attribute long layerX; readonly attribute long layerX;

View File

@ -46,6 +46,7 @@ interface nsITreeBoxObject : nsISupports
{ {
void ensureIndexIsVisible(in long rowIndex); void ensureIndexIsVisible(in long rowIndex);
void scrollToIndex(in long rowIndex); void scrollToIndex(in long rowIndex);
void scrollByLines(in long numLines);
nsIDOMElement getNextItem(in nsIDOMElement startItem, in long delta); nsIDOMElement getNextItem(in nsIDOMElement startItem, in long delta);
nsIDOMElement getPreviousItem(in nsIDOMElement startItem, in long delta); nsIDOMElement getPreviousItem(in nsIDOMElement startItem, in long delta);

View File

@ -57,6 +57,7 @@ public:
NS_IMETHOD GetNextItem(nsIDOMElement* aStartItem, PRInt32 aDelta, nsIDOMElement** aResult) = 0; NS_IMETHOD GetNextItem(nsIDOMElement* aStartItem, PRInt32 aDelta, nsIDOMElement** aResult) = 0;
NS_IMETHOD GetPreviousItem(nsIDOMElement* aStartItem, PRInt32 aDelta, nsIDOMElement** aResult) = 0; NS_IMETHOD GetPreviousItem(nsIDOMElement* aStartItem, PRInt32 aDelta, nsIDOMElement** aResult) = 0;
NS_IMETHOD ScrollToIndex(PRInt32 aRowIndex) = 0; NS_IMETHOD ScrollToIndex(PRInt32 aRowIndex) = 0;
NS_IMETHOD ScrollByLines(nsIPresContext* aPresContext, PRInt32 aNumLines)=0;
NS_IMETHOD GetItemAtIndex(PRInt32 aIndex, nsIDOMElement** aResult) = 0; NS_IMETHOD GetItemAtIndex(PRInt32 aIndex, nsIDOMElement** aResult) = 0;
NS_IMETHOD GetIndexOfItem(nsIPresContext* aPresContext, nsIDOMElement* aElement, PRInt32* aResult) = 0; NS_IMETHOD GetIndexOfItem(nsIPresContext* aPresContext, nsIDOMElement* aElement, PRInt32* aResult) = 0;
NS_IMETHOD GetNumberOfVisibleRows(PRInt32* aResult) = 0; NS_IMETHOD GetNumberOfVisibleRows(PRInt32* aResult) = 0;

View File

@ -110,6 +110,19 @@ NS_IMETHODIMP nsTreeBoxObject::ScrollToIndex(PRInt32 aRowIndex)
return treeFrame->ScrollToIndex(aRowIndex); return treeFrame->ScrollToIndex(aRowIndex);
} }
NS_IMETHODIMP
nsTreeBoxObject::ScrollByLines(PRInt32 aNumLines)
{
nsIFrame* frame = GetFrame();
if (!frame)
return NS_OK;
nsCOMPtr<nsITreeFrame> treeFrame(do_QueryInterface(frame));
nsCOMPtr<nsIPresContext> presContext;
mPresShell->GetPresContext(getter_AddRefs(presContext));
return treeFrame->ScrollByLines(presContext, aNumLines);
}
/* nsIDOMElement getNextItem (in nsIDOMElement startItem, in long delta); */ /* nsIDOMElement getNextItem (in nsIDOMElement startItem, in long delta); */
NS_IMETHODIMP nsTreeBoxObject::GetNextItem(nsIDOMElement *aStartItem, PRInt32 aDelta, nsIDOMElement **aResult) NS_IMETHODIMP nsTreeBoxObject::GetNextItem(nsIDOMElement *aStartItem, PRInt32 aDelta, nsIDOMElement **aResult)
{ {

View File

@ -154,6 +154,58 @@ nsXULTreeFrame::ScrollToIndex(PRInt32 aRowIndex)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsXULTreeFrame::ScrollByLines(nsIPresContext* aPresContext, PRInt32 aNumLines)
{
PRInt32 scrollIndex, visibleRows;
GetIndexOfFirstVisibleRow(&scrollIndex);
GetNumberOfVisibleRows(&visibleRows);
scrollIndex += aNumLines;
if (scrollIndex < 0)
scrollIndex = 0;
else {
PRInt32 numRows;
GetRowCount(&numRows);
PRInt32 lastPageTopRow = numRows - visibleRows;
if (scrollIndex > lastPageTopRow)
scrollIndex = lastPageTopRow;
}
ScrollToIndex(scrollIndex);
// we have to do a sync update for mac because if we scroll too quickly
// w/out going back to the main event loop we can easily scroll the wrong
// bits and it looks like garbage (bug 63465).
nsIFrame* frame = nsnull;
if ( NS_SUCCEEDED(QueryInterface(NS_GET_IID(nsIFrame), (void **)&frame)) ) {
nsIView* treeView = nsnull;
frame->GetView(aPresContext, &treeView);
if (!treeView) {
nsIFrame* frameWithView;
frame->GetParentWithView(aPresContext, &frameWithView);
if (frameWithView)
frameWithView->GetView(aPresContext, &treeView);
else
return NS_ERROR_FAILURE;
}
if (treeView) {
nsCOMPtr<nsIViewManager> vm;
if (treeView->GetViewManager(*getter_AddRefs(vm)) && nsnull != vm) {
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
vm->ForceUpdate();
}
}
}
else
return NS_ERROR_FAILURE;
return NS_OK;
}
/* nsIDOMElement getNextItem (in nsIDOMElement startItem, in long delta); */ /* nsIDOMElement getNextItem (in nsIDOMElement startItem, in long delta); */
NS_IMETHODIMP NS_IMETHODIMP
nsXULTreeFrame::GetNextItem(nsIDOMElement *aStartItem, PRInt32 aDelta, nsIDOMElement **aResult) nsXULTreeFrame::GetNextItem(nsIDOMElement *aStartItem, PRInt32 aDelta, nsIDOMElement **aResult)

View File

@ -59,6 +59,7 @@ public:
NS_IMETHOD GetNextItem(nsIDOMElement* aStartItem, PRInt32 aDelta, nsIDOMElement** aResult); NS_IMETHOD GetNextItem(nsIDOMElement* aStartItem, PRInt32 aDelta, nsIDOMElement** aResult);
NS_IMETHOD GetPreviousItem(nsIDOMElement* aStartItem, PRInt32 aDelta, nsIDOMElement** aResult); NS_IMETHOD GetPreviousItem(nsIDOMElement* aStartItem, PRInt32 aDelta, nsIDOMElement** aResult);
NS_IMETHOD ScrollToIndex(PRInt32 aRowIndex); NS_IMETHOD ScrollToIndex(PRInt32 aRowIndex);
NS_IMETHOD ScrollByLines(nsIPresContext* aPresContext, PRInt32 aNumLines);
NS_IMETHOD GetItemAtIndex(PRInt32 aIndex, nsIDOMElement** aResult); NS_IMETHOD GetItemAtIndex(PRInt32 aIndex, nsIDOMElement** aResult);
NS_IMETHOD GetIndexOfItem(nsIPresContext* aPresContext, nsIDOMElement* aElement, PRInt32* aResult); NS_IMETHOD GetIndexOfItem(nsIPresContext* aPresContext, nsIDOMElement* aElement, PRInt32* aResult);
NS_IMETHOD GetNumberOfVisibleRows(PRInt32 *aResult); NS_IMETHOD GetNumberOfVisibleRows(PRInt32 *aResult);

View File

@ -23,6 +23,10 @@
</content> </content>
<implementation> <implementation>
<constructor>
this.addEventListener("DOMMouseScroll", this._handleMouseScroll, true);
</constructor>
<property name="outlinerBoxObject" <property name="outlinerBoxObject"
onget="return this.boxObject.QueryInterface(Components.interfaces.nsIOutlinerBoxObject);" onget="return this.boxObject.QueryInterface(Components.interfaces.nsIOutlinerBoxObject);"
readonly="true"/> readonly="true"/>
@ -58,6 +62,24 @@
<field name="_columnsDirty">true</field> <field name="_columnsDirty">true</field>
<field name="_handleMouseScroll">
<![CDATA[
({
subject: this,
handleEvent: function(aEvent)
{
var rows = aEvent.detail;
if (rows == NSUIEvent.SCROLL_PAGE_UP)
this.subject.outlinerBoxObject.scrollByPages(-1);
else if (rows == NSUIEvent.SCROLL_PAGE_DOWN)
this.subject.outlinerBoxObject.scrollByPages(1);
else
this.subject.outlinerBoxObject.scrollByLines(aEvent.detail);
}
})
]]>
</field>
<method name="_ensureColumnOrder"> <method name="_ensureColumnOrder">
<body><![CDATA[ <body><![CDATA[
if (this._columnsDirty) { if (this._columnsDirty) {

View File

@ -284,6 +284,31 @@
<binding id="treerows" <binding id="treerows"
extends="chrome://global/content/bindings/tree.xml#tree-base"> extends="chrome://global/content/bindings/tree.xml#tree-base">
<content outer="true"/> <content outer="true"/>
<implementation>
<constructor>
this.addEventListener("DOMMouseScroll", this._handleMouseScroll, true);
</constructor>
<field name="_handleMouseScroll">
<![CDATA[
({
subject: this,
handleEvent: function(aEvent)
{
var treeBox = this.subject.parentNode.treeBoxObject;
var rows = aEvent.detail;
if (rows == NSUIEvent.SCROLL_PAGE_UP)
rows = -1 * treeBox.getNumberOfVisibleRows();
else if (rows == NSUIEvent.SCROLL_PAGE_DOWN)
rows = treeBox.getNumberOfVisibleRows();
treeBox.scrollByLines(rows);
}
})
]]>
</field>
</implementation>
<handlers> <handlers>
<!-- If there is no modifier key, we select on mousedown, not <!-- If there is no modifier key, we select on mousedown, not
click, so that drags work correctly. --> click, so that drags work correctly. -->