mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 12:50:09 +00:00
Bug 41708, support scrolling when hovering over the edge of a scrollframe while dragging, r=smaug
This commit is contained in:
parent
87a8f718ea
commit
3bcbbdcf40
@ -3331,6 +3331,20 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
{
|
||||
NS_ASSERTION(aEvent->mClass == eDragEventClass, "Expected a drag event");
|
||||
|
||||
// Check if the drag is occurring inside a scrollable area. If so, scroll
|
||||
// the area when the mouse is near the edges.
|
||||
if (mCurrentTarget && aEvent->mMessage == eDragOver) {
|
||||
nsIFrame* checkFrame = mCurrentTarget;
|
||||
while (checkFrame) {
|
||||
nsIScrollableFrame* scrollFrame = do_QueryFrame(checkFrame);
|
||||
// Break out so only the innermost scrollframe is scrolled.
|
||||
if (scrollFrame && scrollFrame->DragScroll(aEvent)) {
|
||||
break;
|
||||
}
|
||||
checkFrame = checkFrame->GetParent();
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
|
||||
if (!dragSession)
|
||||
break;
|
||||
|
@ -6159,3 +6159,60 @@ ScrollFrameHelper::UsesContainerScrolling() const
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ScrollFrameHelper::DragScroll(WidgetEvent* aEvent)
|
||||
{
|
||||
// Dragging is allowed while within a 20 pixel border. Note that device pixels
|
||||
// are used so that the same margin is used even when zoomed in or out.
|
||||
nscoord margin = 20 * mOuter->PresContext()->AppUnitsPerDevPixel();
|
||||
|
||||
// Don't drag scroll for small scrollareas.
|
||||
if (mScrollPort.width < margin * 2 || mScrollPort.height < margin * 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If willScroll is computed as false, then the frame is already scrolled as
|
||||
// far as it can go in both directions. Return false so that an ancestor
|
||||
// scrollframe can scroll instead.
|
||||
bool willScroll = false;
|
||||
nsPoint pnt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, mOuter);
|
||||
nsPoint scrollPoint = GetScrollPosition();
|
||||
nsRect rangeRect = GetScrollRangeForClamping();
|
||||
|
||||
// Only drag scroll when a scrollbar is present.
|
||||
nsPoint offset;
|
||||
if (mHasHorizontalScrollbar) {
|
||||
if (pnt.x >= mScrollPort.x && pnt.x <= mScrollPort.x + margin) {
|
||||
offset.x = -margin;
|
||||
if (scrollPoint.x > 0) {
|
||||
willScroll = true;
|
||||
}
|
||||
} else if (pnt.x >= mScrollPort.XMost() - margin && pnt.x <= mScrollPort.XMost()) {
|
||||
offset.x = margin;
|
||||
if (scrollPoint.x < rangeRect.width) {
|
||||
willScroll = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mHasVerticalScrollbar) {
|
||||
if (pnt.y >= mScrollPort.y && pnt.y <= mScrollPort.y + margin) {
|
||||
offset.y = -margin;
|
||||
if (scrollPoint.y > 0) {
|
||||
willScroll = true;
|
||||
}
|
||||
} else if (pnt.y >= mScrollPort.YMost() - margin && pnt.y <= mScrollPort.YMost()) {
|
||||
offset.y = margin;
|
||||
if (scrollPoint.y < rangeRect.height) {
|
||||
willScroll = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (offset.x || offset.y) {
|
||||
ScrollTo(GetScrollPosition() + offset, nsIScrollableFrame::NORMAL);
|
||||
}
|
||||
|
||||
return willScroll;
|
||||
}
|
||||
|
@ -460,6 +460,8 @@ public:
|
||||
return mSuppressScrollbarRepaints;
|
||||
}
|
||||
|
||||
bool DragScroll(WidgetEvent* aEvent);
|
||||
|
||||
// owning references to the nsIAnonymousContentCreator-built content
|
||||
nsCOMPtr<nsIContent> mHScrollbarContent;
|
||||
nsCOMPtr<nsIContent> mVScrollbarContent;
|
||||
@ -1033,6 +1035,10 @@ public:
|
||||
return mHelper.GetScrollSnapInfo();
|
||||
}
|
||||
|
||||
virtual bool DragScroll(mozilla::WidgetEvent* aEvent) override {
|
||||
return mHelper.DragScroll(aEvent);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FRAME_DUMP
|
||||
virtual nsresult GetFrameName(nsAString& aResult) const override;
|
||||
#endif
|
||||
@ -1456,6 +1462,10 @@ public:
|
||||
return mHelper.GetScrollSnapInfo();
|
||||
}
|
||||
|
||||
virtual bool DragScroll(mozilla::WidgetEvent* aEvent) override {
|
||||
return mHelper.DragScroll(aEvent);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FRAME_DUMP
|
||||
virtual nsresult GetFrameName(nsAString& aResult) const override;
|
||||
#endif
|
||||
|
@ -475,6 +475,14 @@ public:
|
||||
virtual ScrollSnapInfo GetScrollSnapInfo() const = 0;
|
||||
|
||||
virtual void SetScrollsClipOnUnscrolledOutOfFlow() = 0;
|
||||
|
||||
/**
|
||||
* Given the drag event aEvent, determine whether the mouse is near the edge
|
||||
* of the scrollable area, and scroll the view in the direction of that edge
|
||||
* if so. If scrolling occurred, true is returned. When false is returned, the
|
||||
* caller should look for an ancestor to scroll.
|
||||
*/
|
||||
virtual bool DragScroll(mozilla::WidgetEvent* aEvent) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user