Bug 526394. Part 33: Remove nsScrollPortView etc. r=mats
This commit is contained in:
Родитель
91c9eac43f
Коммит
97d576d819
|
@ -49,7 +49,6 @@
|
|||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsCSSAnonBoxes.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsPlaceholderFrame.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsCSSFrameConstructor.h"
|
||||
|
@ -670,15 +669,6 @@ nsLayoutUtils::GetScrollableFrameFor(nsIFrame *aScrolledFrame)
|
|||
return sf;
|
||||
}
|
||||
|
||||
//static
|
||||
nsIScrollableFrame*
|
||||
nsLayoutUtils::GetScrollableFrameFor(nsIScrollableView *aScrollableView)
|
||||
{
|
||||
nsIFrame *frame = GetFrameFor(aScrollableView->View()->GetParent());
|
||||
nsIScrollableFrame *sf = do_QueryFrame(frame);
|
||||
return sf;
|
||||
}
|
||||
|
||||
// static
|
||||
nsIScrollableFrame*
|
||||
nsLayoutUtils::GetNearestScrollableFrameForDirection(nsIFrame* aFrame,
|
||||
|
|
|
@ -45,7 +45,6 @@ class nsIFormControlFrame;
|
|||
class nsPresContext;
|
||||
class nsIContent;
|
||||
class nsIAtom;
|
||||
class nsIScrollableView;
|
||||
class nsIScrollableFrame;
|
||||
class nsIDOMEvent;
|
||||
class nsRegion;
|
||||
|
@ -296,14 +295,6 @@ public:
|
|||
static nsIFrame* GetFrameFor(nsIView *aView)
|
||||
{ return static_cast<nsIFrame*>(aView->GetClientData()); }
|
||||
|
||||
/**
|
||||
* GetScrollableFrameFor returns the scrollable frame for a scrollable view
|
||||
* @param aScrollableView is the scrollable view to return the
|
||||
* scrollable frame for.
|
||||
* @return the scrollable frame for the scrollable view
|
||||
*/
|
||||
static nsIScrollableFrame* GetScrollableFrameFor(nsIScrollableView *aScrollableView);
|
||||
|
||||
/**
|
||||
* GetScrollableFrameFor returns the scrollable frame for a scrolled frame
|
||||
*/
|
||||
|
|
|
@ -51,9 +51,6 @@
|
|||
#include "nsDisplayList.h"
|
||||
#include "nsAbsoluteContainingBlock.h"
|
||||
|
||||
// for focus
|
||||
#include "nsIScrollableView.h"
|
||||
|
||||
/**
|
||||
* Root frame class.
|
||||
*
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
#include "nsStyleContext.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsCRT.h"
|
||||
|
|
|
@ -47,7 +47,6 @@ MODULE = view
|
|||
EXPORTS = \
|
||||
nsIView.h \
|
||||
nsIViewManager.h \
|
||||
nsIScrollableView.h \
|
||||
nsViewsCID.h \
|
||||
nsIViewObserver.h \
|
||||
nsIScrollPositionListener.h \
|
||||
|
|
|
@ -1,215 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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 the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsIScrollableView_h___
|
||||
#define nsIScrollableView_h___
|
||||
|
||||
#include "nsCoord.h"
|
||||
#include "nsNativeWidget.h"
|
||||
|
||||
class nsIView;
|
||||
class nsIScrollPositionListener;
|
||||
struct nsSize;
|
||||
|
||||
// IID for the nsIScrollableView interface
|
||||
#define NS_ISCROLLABLEVIEW_IID \
|
||||
{ 0x74254899, 0xccc9, 0x4e67, \
|
||||
{ 0xa6, 0x78, 0x6b, 0x79, 0xfa, 0x72, 0xb4, 0x86 } }
|
||||
|
||||
/**
|
||||
* A scrolling view allows an arbitrary view that you supply to be scrolled
|
||||
* vertically or horizontally (or both). The scrolling view creates and
|
||||
* manages the scrollbars.
|
||||
*
|
||||
* You must use SetScrolledView() to specify the view that is to be scrolled,
|
||||
* because the scrolled view is made a child of the clip view (an internal
|
||||
* child view created by the scrolling view).
|
||||
*
|
||||
*/
|
||||
class nsIScrollableView {
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCROLLABLEVIEW_IID)
|
||||
|
||||
/**
|
||||
* Get the dimensions of the container
|
||||
* @param aWidth return value for width of container
|
||||
* @param aHeight return value for height of container
|
||||
*/
|
||||
NS_IMETHOD GetContainerSize(nscoord *aWidth, nscoord *aHeight) const = 0;
|
||||
|
||||
/**
|
||||
* Set the view that we are scrolling within the scrolling view.
|
||||
*/
|
||||
NS_IMETHOD SetScrolledView(nsIView *aScrolledView) = 0;
|
||||
|
||||
/**
|
||||
* Get the view that we are scrolling within the scrolling view.
|
||||
* @result child view
|
||||
*/
|
||||
NS_IMETHOD GetScrolledView(nsIView *&aScrolledView) const = 0;
|
||||
|
||||
/**
|
||||
* Get the position of the scrolled view.
|
||||
*/
|
||||
NS_IMETHOD GetScrollPosition(nscoord &aX, nscoord& aY) const = 0;
|
||||
|
||||
/**
|
||||
* Scroll the view to the given x,y, update's the scrollbar's thumb
|
||||
* positions and the view's offset. Clamps the values to be
|
||||
* legal. Updates the display based on aUpdateFlags.
|
||||
* @param aX left edge to scroll to
|
||||
* @param aY top edge to scroll to
|
||||
* @param aUpdateFlags indicate smooth or async scrolling
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD ScrollTo(nscoord aX, nscoord aY, PRUint32 aUpdateFlags) = 0;
|
||||
|
||||
/**
|
||||
* Set the height of a line used for line scrolling.
|
||||
* @param aHeight new line height in app units. the default
|
||||
* height is 12 points.
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD SetLineHeight(nscoord aHeight) = 0;
|
||||
|
||||
/**
|
||||
* Get the height of a line used for line scrolling.
|
||||
* @param aHeight out parameter for line height
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD GetLineHeight(nscoord *aHeight) = 0;
|
||||
|
||||
/**
|
||||
* Scroll the view left or right by aNumLinesX columns. Positive values move right.
|
||||
* Scroll the view up or down by aNumLinesY lines. Positive values move down.
|
||||
* Prevents scrolling off the end of the view.
|
||||
* @param aNumLinesX number of lines to scroll the view horizontally
|
||||
* @param aNumLinesY number of lines to scroll the view vertically
|
||||
* @param aUpdateFlags indicate smooth or async scrolling
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD ScrollByLines(PRInt32 aNumLinesX, PRInt32 aNumLinexY,
|
||||
PRUint32 aUpdateFlags = 0) = 0;
|
||||
/**
|
||||
* Identical to ScrollByLines while also returning overscroll values.
|
||||
* @param aNumLinesX number of lines to scroll the view horizontally
|
||||
* @param aNumLinesY number of lines to scroll the view vertically
|
||||
* @param aOverflowX returns the number of pixels that could not
|
||||
* be scrolled due to scroll bounds.
|
||||
* @param aOverflowY returns the number of pixels that could not
|
||||
* be scrolled due to scroll bounds.
|
||||
* @param aUpdateFlags indicate smooth or async scrolling
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD ScrollByLinesWithOverflow(PRInt32 aNumLinesX, PRInt32 aNumLinexY,
|
||||
PRInt32& aOverflowX, PRInt32& aOverflowY,
|
||||
PRUint32 aUpdateFlags = 0) = 0;
|
||||
|
||||
/**
|
||||
* Get the desired size of a page scroll in each dimension.
|
||||
* ScrollByPages will scroll by independent multiples of these amounts
|
||||
* unless it hits the edge of the view.
|
||||
*/
|
||||
NS_IMETHOD GetPageScrollDistances(nsSize *aDistances) = 0;
|
||||
|
||||
/**
|
||||
* Scroll the view left or right by aNumPagesX pages. Positive values move right.
|
||||
* Scroll the view up or down by aNumPagesY pages. Positive values move down.
|
||||
* A page is considered to be the amount displayed by the clip view.
|
||||
* Prevents scrolling off the end of the view.
|
||||
* @param aNumPagesX number of pages to scroll the view horizontally
|
||||
* @param aNumPagesY number of pages to scroll the view vertically
|
||||
* @param aUpdateFlags indicate smooth or async scrolling
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD ScrollByPages(PRInt32 aNumPagesX, PRInt32 aNumPagesY,
|
||||
PRUint32 aUpdateFlags = 0) = 0;
|
||||
|
||||
/**
|
||||
* Scroll the view to the top or bottom of the document depending
|
||||
* on the value of aTop.
|
||||
* @param aForward indicates whether to scroll to top or bottom
|
||||
* @param aUpdateFlags indicate smooth or async scrolling
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD ScrollByWhole(PRBool aTop, PRUint32 aUpdateFlags = 0) = 0;
|
||||
|
||||
/**
|
||||
* Scroll the view left or right by aNumLinesX pixels. Positive values move
|
||||
* right. Scroll the view up or down by aNumLinesY pixels. Positive values
|
||||
* move down. Prevents scrolling off the end of the view.
|
||||
* @param aNumPixelsX number of pixels to scroll the view horizontally
|
||||
* @param aNumPixelsY number of pixels to scroll the view vertically
|
||||
* @param aOverflowX returns the number of pixels that could not
|
||||
* be scrolled due to scroll bounds.
|
||||
* @param aOverflowY returns the number of pixels that could not
|
||||
* be scrolled due to scroll bounds.
|
||||
* @param aUpdateFlags indicate smooth, async, or immediate scrolling
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD ScrollByPixels(PRInt32 aNumPixelsX, PRInt32 aNumPixelsY,
|
||||
PRInt32& aOverflowX, PRInt32& aOverflowY,
|
||||
PRUint32 aUpdateFlags = 0) = 0;
|
||||
|
||||
/**
|
||||
* Check the view can scroll from current offset.
|
||||
* @param aHorizontal If checking to Left or to Right, true. Otherwise, false.
|
||||
* @param aForward If checking to Right or Bottom, true. Otherwise, false.
|
||||
* @param aResult If the view can scroll, true. Otherwise, false.
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD CanScroll(PRBool aHorizontal, PRBool aForward, PRBool &aResult) = 0;
|
||||
|
||||
/**
|
||||
* Returns the view as an nsIView*
|
||||
*/
|
||||
NS_IMETHOD_(nsIView*) View() = 0;
|
||||
|
||||
/**
|
||||
* Adds a scroll position listener.
|
||||
*/
|
||||
NS_IMETHOD AddScrollPositionListener(nsIScrollPositionListener* aListener) = 0;
|
||||
|
||||
/**
|
||||
* Removes a scroll position listener.
|
||||
*/
|
||||
NS_IMETHOD RemoveScrollPositionListener(nsIScrollPositionListener* aListener) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScrollableView, NS_ISCROLLABLEVIEW_IID)
|
||||
|
||||
#endif
|
|
@ -43,7 +43,6 @@
|
|||
#include "nsEvent.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
|
||||
class nsIScrollableView;
|
||||
class nsIWidget;
|
||||
struct nsRect;
|
||||
class nsRegion;
|
||||
|
@ -51,8 +50,8 @@ class nsIDeviceContext;
|
|||
class nsIViewObserver;
|
||||
|
||||
#define NS_IVIEWMANAGER_IID \
|
||||
{ 0x9c2c1a6a, 0x2573, 0x49b1, \
|
||||
{ 0xbd, 0x37, 0x8f, 0x57, 0xde, 0x05, 0xc7, 0xb2 } }
|
||||
{ 0x6ca2fd1c, 0xa57e, 0x4802, \
|
||||
{ 0xad, 0x55, 0x85, 0xf6, 0x6f, 0x4a, 0x2c, 0x04 } }
|
||||
|
||||
class nsIViewManager : public nsISupports
|
||||
{
|
||||
|
@ -83,19 +82,6 @@ public:
|
|||
const nsIView* aParent,
|
||||
nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow) = 0;
|
||||
|
||||
/**
|
||||
* Create an scrollable view
|
||||
* @param aBounds initial bounds for view
|
||||
* XXX We should eliminate this parameter; you can set the bounds after CreateScrollableView
|
||||
* @param aParent intended parent for view. this is not actually set in the
|
||||
* nsIView through this method. it is only used by the initialization
|
||||
* code to walk up the view tree, if necessary, to find resources.
|
||||
* XXX We should eliminate this parameter!
|
||||
* @result The new view
|
||||
*/
|
||||
NS_IMETHOD_(nsIScrollableView*) CreateScrollableView(const nsRect& aBounds,
|
||||
const nsIView* aParent) = 0;
|
||||
|
||||
/**
|
||||
* Get the root of the view tree.
|
||||
* @result the root view
|
||||
|
|
|
@ -1,769 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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 the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Neil Cronin (neil@rackle.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsScrollPortView.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsViewsCID.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsILookAndFeel.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsIScrollPositionListener.h"
|
||||
#include "nsIRegion.h"
|
||||
#include "nsViewManager.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID);
|
||||
|
||||
#define SMOOTH_SCROLL_MSECS_PER_FRAME 10
|
||||
#define SMOOTH_SCROLL_FRAMES 10
|
||||
|
||||
#define SMOOTH_SCROLL_PREF_NAME "general.smoothScroll"
|
||||
|
||||
class AsyncScroll {
|
||||
public:
|
||||
AsyncScroll() {}
|
||||
~AsyncScroll() {
|
||||
if (mScrollTimer) mScrollTimer->Cancel();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITimer> mScrollTimer;
|
||||
PRInt32 mVelocities[SMOOTH_SCROLL_FRAMES*2];
|
||||
PRInt32 mFrameIndex;
|
||||
PRPackedBool mIsSmoothScroll;
|
||||
};
|
||||
|
||||
nsScrollPortView::nsScrollPortView(nsViewManager* aViewManager)
|
||||
: nsView(aViewManager)
|
||||
{
|
||||
mOffsetX = mOffsetY = 0;
|
||||
mDestinationX = mDestinationY = 0;
|
||||
nsCOMPtr<nsIDeviceContext> dev;
|
||||
mViewManager->GetDeviceContext(*getter_AddRefs(dev));
|
||||
mLineHeight = dev->AppUnitsPerInch() / 6; // 12 pt
|
||||
|
||||
mListeners = nsnull;
|
||||
mAsyncScroll = nsnull;
|
||||
}
|
||||
|
||||
nsScrollPortView::~nsScrollPortView()
|
||||
{
|
||||
if (nsnull != mListeners) {
|
||||
mListeners->Clear();
|
||||
NS_RELEASE(mListeners);
|
||||
}
|
||||
|
||||
delete mAsyncScroll;
|
||||
}
|
||||
|
||||
nsresult nsScrollPortView::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (nsnull == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
*aInstancePtr = nsnull;
|
||||
if (aIID.Equals(NS_GET_IID(nsIScrollableView))) {
|
||||
*aInstancePtr = (void*)(nsIScrollableView*)this;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsView::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsIView*) nsScrollPortView::View()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::AddScrollPositionListener(nsIScrollPositionListener* aListener)
|
||||
{
|
||||
if (nsnull == mListeners) {
|
||||
nsresult rv = NS_NewISupportsArray(&mListeners);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
return mListeners->AppendElement(aListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::RemoveScrollPositionListener(nsIScrollPositionListener* aListener)
|
||||
{
|
||||
if (nsnull != mListeners) {
|
||||
return mListeners->RemoveElement(aListener);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::GetContainerSize(nscoord *aWidth, nscoord *aHeight) const
|
||||
{
|
||||
if (!aWidth || !aHeight)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aWidth = 0;
|
||||
*aHeight = 0;
|
||||
|
||||
nsView *scrolledView = GetScrolledView();
|
||||
|
||||
if (!scrolledView)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsSize sz;
|
||||
scrolledView->GetDimensions(sz);
|
||||
*aWidth = sz.width;
|
||||
*aHeight = sz.height;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void ComputeVelocities(PRInt32 aCurVelocity, nscoord aCurPos, nscoord aDstPos,
|
||||
PRInt32* aVelocities, PRInt32 aP2A) {
|
||||
// scrolling always works in units of whole pixels. So compute velocities
|
||||
// in pixels and then scale them up. This ensures, for example, that
|
||||
// a 1-pixel scroll isn't broken into N frames of 1/N pixels each, each
|
||||
// frame increment being rounded to 0 whole pixels.
|
||||
aCurPos = NSAppUnitsToIntPixels(aCurPos, aP2A);
|
||||
aDstPos = NSAppUnitsToIntPixels(aDstPos, aP2A);
|
||||
|
||||
PRInt32 i;
|
||||
PRInt32 direction = (aCurPos < aDstPos ? 1 : -1);
|
||||
PRInt32 absDelta = (aDstPos - aCurPos)*direction;
|
||||
PRInt32 baseVelocity = absDelta/SMOOTH_SCROLL_FRAMES;
|
||||
|
||||
for (i = 0; i < SMOOTH_SCROLL_FRAMES; i++) {
|
||||
aVelocities[i*2] = baseVelocity;
|
||||
}
|
||||
nscoord total = baseVelocity*SMOOTH_SCROLL_FRAMES;
|
||||
for (i = 0; i < SMOOTH_SCROLL_FRAMES; i++) {
|
||||
if (total < absDelta) {
|
||||
aVelocities[i*2]++;
|
||||
total++;
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(total == absDelta, "Invalid velocity sum");
|
||||
|
||||
PRInt32 scale = NSIntPixelsToAppUnits(direction, aP2A);
|
||||
for (i = 0; i < SMOOTH_SCROLL_FRAMES; i++) {
|
||||
aVelocities[i*2] *= scale;
|
||||
}
|
||||
}
|
||||
|
||||
static nsresult ClampScrollValues(nscoord& aX, nscoord& aY, nsScrollPortView* aThis) {
|
||||
// make sure the new position is in bounds
|
||||
nsView* scrolledView = aThis->GetScrolledView();
|
||||
if (!scrolledView) return NS_ERROR_FAILURE;
|
||||
|
||||
nsRect scrolledRect;
|
||||
scrolledView->GetDimensions(scrolledRect);
|
||||
|
||||
nsSize portSize;
|
||||
aThis->GetDimensions(portSize);
|
||||
|
||||
nscoord maxX = scrolledRect.XMost() - portSize.width;
|
||||
nscoord maxY = scrolledRect.YMost() - portSize.height;
|
||||
|
||||
if (aX > maxX)
|
||||
aX = maxX;
|
||||
|
||||
if (aY > maxY)
|
||||
aY = maxY;
|
||||
|
||||
if (aX < scrolledRect.x)
|
||||
aX = scrolledRect.x;
|
||||
|
||||
if (aY < scrolledRect.y)
|
||||
aY = scrolledRect.y;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* this method wraps calls to ScrollToImpl(), either in one shot or incrementally,
|
||||
* based on the setting of the smooth scroll pref
|
||||
*/
|
||||
NS_IMETHODIMP nsScrollPortView::ScrollTo(nscoord aDestinationX, nscoord aDestinationY,
|
||||
PRUint32 aUpdateFlags)
|
||||
{
|
||||
mDestinationX = aDestinationX;
|
||||
mDestinationY = aDestinationY;
|
||||
ClampScrollValues(mDestinationX, mDestinationY, this);
|
||||
|
||||
if (!(aUpdateFlags & (NS_VMREFRESH_DEFERRED | NS_VMREFRESH_SMOOTHSCROLL))) {
|
||||
// Asynchronous scrolling is not allowed, so we'll kill any existing
|
||||
// async-scrolling process and do an instant scroll
|
||||
delete mAsyncScroll;
|
||||
mAsyncScroll = nsnull;
|
||||
return ScrollToImpl(mDestinationX, mDestinationY);
|
||||
}
|
||||
|
||||
PRInt32 currentVelocityX = 0;
|
||||
PRInt32 currentVelocityY = 0;
|
||||
PRBool isSmoothScroll = (aUpdateFlags & NS_VMREFRESH_SMOOTHSCROLL) &&
|
||||
IsSmoothScrollingEnabled();
|
||||
|
||||
if (mAsyncScroll) {
|
||||
if (mAsyncScroll->mIsSmoothScroll) {
|
||||
currentVelocityX = mAsyncScroll->mVelocities[mAsyncScroll->mFrameIndex*2];
|
||||
currentVelocityY = mAsyncScroll->mVelocities[mAsyncScroll->mFrameIndex*2 + 1];
|
||||
}
|
||||
} else {
|
||||
mAsyncScroll = new AsyncScroll;
|
||||
if (mAsyncScroll) {
|
||||
mAsyncScroll->mScrollTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if (!mAsyncScroll->mScrollTimer) {
|
||||
delete mAsyncScroll;
|
||||
mAsyncScroll = nsnull;
|
||||
}
|
||||
}
|
||||
if (!mAsyncScroll) {
|
||||
// some allocation failed. Scroll the normal way.
|
||||
return ScrollToImpl(mDestinationX, mDestinationY);
|
||||
}
|
||||
if (isSmoothScroll) {
|
||||
mAsyncScroll->mScrollTimer->InitWithFuncCallback(
|
||||
AsyncScrollCallback, this, SMOOTH_SCROLL_MSECS_PER_FRAME,
|
||||
nsITimer::TYPE_REPEATING_PRECISE);
|
||||
} else {
|
||||
mAsyncScroll->mScrollTimer->InitWithFuncCallback(
|
||||
AsyncScrollCallback, this, 0, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
}
|
||||
|
||||
mAsyncScroll->mFrameIndex = 0;
|
||||
mAsyncScroll->mIsSmoothScroll = isSmoothScroll;
|
||||
|
||||
if (isSmoothScroll) {
|
||||
nsCOMPtr<nsIDeviceContext> dev;
|
||||
mViewManager->GetDeviceContext(*getter_AddRefs(dev));
|
||||
PRInt32 p2a = dev->AppUnitsPerDevPixel();
|
||||
|
||||
// compute velocity vectors
|
||||
ComputeVelocities(currentVelocityX, mOffsetX, mDestinationX,
|
||||
mAsyncScroll->mVelocities, p2a);
|
||||
ComputeVelocities(currentVelocityY, mOffsetY, mDestinationY,
|
||||
mAsyncScroll->mVelocities + 1, p2a);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void AdjustChildWidgets(nsView *aView,
|
||||
nsPoint aWidgetToParentViewOrigin, PRInt32 aP2A, PRBool aInvalidate)
|
||||
{
|
||||
if (aView->HasWidget()) {
|
||||
nsIWidget* widget = aView->GetWidget();
|
||||
nsWindowType type;
|
||||
widget->GetWindowType(type);
|
||||
if (type != eWindowType_popup) {
|
||||
nsRect bounds = aView->GetBounds();
|
||||
nsPoint widgetOrigin = aWidgetToParentViewOrigin
|
||||
+ nsPoint(bounds.x, bounds.y);
|
||||
widget->Move(NSAppUnitsToIntPixels(widgetOrigin.x, aP2A),
|
||||
NSAppUnitsToIntPixels(widgetOrigin.y, aP2A));
|
||||
if (aInvalidate) {
|
||||
// Force the widget and everything in it to repaint. We can't
|
||||
// just use Invalidate because the widget might have child
|
||||
// widgets and they wouldn't get updated. We can't call
|
||||
// UpdateView(aView) because the area to be repainted might be
|
||||
// outside aView's clipped bounds. This isn't the greatest way
|
||||
// to achieve this, perhaps, but it works.
|
||||
widget->Show(PR_FALSE);
|
||||
widget->Show(PR_TRUE);
|
||||
}
|
||||
}
|
||||
// Don't recurse if the view has a widget, because we adjusted the view's
|
||||
// widget position, and its child widgets are relative to its position
|
||||
} else {
|
||||
nsPoint widgetToViewOrigin = aWidgetToParentViewOrigin
|
||||
+ aView->GetPosition();
|
||||
|
||||
for (nsView* kid = aView->GetFirstChild(); kid; kid = kid->GetNextSibling())
|
||||
{
|
||||
AdjustChildWidgets(kid, widgetToViewOrigin, aP2A, aInvalidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::SetScrolledView(nsIView *aScrolledView)
|
||||
{
|
||||
NS_ASSERTION(GetFirstChild() == nsnull || GetFirstChild()->GetNextSibling() == nsnull,
|
||||
"Error scroll port has too many children");
|
||||
|
||||
// if there is already a child so remove it
|
||||
if (GetFirstChild() != nsnull)
|
||||
{
|
||||
mViewManager->RemoveChild(GetFirstChild());
|
||||
}
|
||||
|
||||
return mViewManager->InsertChild(this, aScrolledView, 0);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::GetScrolledView(nsIView *&aScrolledView) const
|
||||
{
|
||||
aScrolledView = GetScrolledView();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::GetScrollPosition(nscoord &aX, nscoord &aY) const
|
||||
{
|
||||
aX = mOffsetX;
|
||||
aY = mOffsetY;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::SetLineHeight(nscoord aHeight)
|
||||
{
|
||||
mLineHeight = aHeight;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::GetLineHeight(nscoord *aHeight)
|
||||
{
|
||||
*aHeight = mLineHeight;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScrollPortView::CalcScrollOverflow(nscoord aX, nscoord aY,
|
||||
PRInt32& aPixelOverflowX, PRInt32& aPixelOverflowY)
|
||||
{
|
||||
// make sure the new position is in bounds
|
||||
nsView* scrolledView = GetScrolledView();
|
||||
if (!scrolledView) return NS_ERROR_FAILURE;
|
||||
|
||||
nsRect scrolledRect;
|
||||
scrolledView->GetDimensions(scrolledRect);
|
||||
|
||||
nsSize portSize;
|
||||
this->GetDimensions(portSize);
|
||||
|
||||
nscoord maxX = scrolledRect.XMost() - portSize.width;
|
||||
nscoord maxY = scrolledRect.YMost() - portSize.height;
|
||||
|
||||
nsCOMPtr<nsIDeviceContext> dev;
|
||||
mViewManager->GetDeviceContext(*getter_AddRefs(dev));
|
||||
float p2a = (float)dev->AppUnitsPerDevPixel();
|
||||
|
||||
if (maxX != 0 && aX > maxX)
|
||||
aPixelOverflowX = NSAppUnitsToIntPixels(aX - maxX, p2a);
|
||||
|
||||
if (maxY != 0 && aY > maxY)
|
||||
aPixelOverflowY = NSAppUnitsToIntPixels(aY - maxY, p2a);
|
||||
|
||||
if (maxX != 0 && aX < scrolledRect.x)
|
||||
aPixelOverflowX = NSAppUnitsToIntPixels(scrolledRect.x - aX, p2a);
|
||||
|
||||
if (maxY != 0 && aY < scrolledRect.y)
|
||||
aPixelOverflowY = NSAppUnitsToIntPixels(scrolledRect.y - aY, p2a);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::ScrollByLines(PRInt32 aNumLinesX,
|
||||
PRInt32 aNumLinesY,
|
||||
PRUint32 aUpdateFlags)
|
||||
{
|
||||
nscoord dx = mLineHeight*aNumLinesX;
|
||||
nscoord dy = mLineHeight*aNumLinesY;
|
||||
|
||||
return ScrollTo(mDestinationX + dx, mDestinationY + dy, aUpdateFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::ScrollByLinesWithOverflow(PRInt32 aNumLinesX,
|
||||
PRInt32 aNumLinesY,
|
||||
PRInt32& aOverflowX,
|
||||
PRInt32& aOverflowY,
|
||||
PRUint32 aUpdateFlags)
|
||||
{
|
||||
nscoord dx = mLineHeight*aNumLinesX;
|
||||
nscoord dy = mLineHeight*aNumLinesY;
|
||||
|
||||
CalcScrollOverflow(mDestinationX + dx, mDestinationY + dy, aOverflowX, aOverflowY);
|
||||
|
||||
return ScrollTo(mDestinationX + dx, mDestinationY + dy, aUpdateFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::GetPageScrollDistances(nsSize *aDistances)
|
||||
{
|
||||
nsSize size;
|
||||
GetDimensions(size);
|
||||
|
||||
// The page increment is the size of the page, minus the smaller of
|
||||
// 10% of the size or 2 lines.
|
||||
aDistances->width = size.width - PR_MIN(size.width / 10, 2 * mLineHeight);
|
||||
aDistances->height = size.height - PR_MIN(size.height / 10, 2 * mLineHeight);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::ScrollByPages(PRInt32 aNumPagesX, PRInt32 aNumPagesY,
|
||||
PRUint32 aUpdateFlags)
|
||||
{
|
||||
nsSize delta;
|
||||
GetPageScrollDistances(&delta);
|
||||
|
||||
// put in the number of pages.
|
||||
delta.width *= aNumPagesX;
|
||||
delta.height *= aNumPagesY;
|
||||
|
||||
return ScrollTo(mDestinationX + delta.width, mDestinationY + delta.height,
|
||||
aUpdateFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::ScrollByWhole(PRBool aTop,
|
||||
PRUint32 aUpdateFlags)
|
||||
{
|
||||
nscoord newPos = 0;
|
||||
|
||||
if (!aTop) {
|
||||
nsSize scrolledSize;
|
||||
nsView* scrolledView = GetScrolledView();
|
||||
scrolledView->GetDimensions(scrolledSize);
|
||||
newPos = scrolledSize.height;
|
||||
}
|
||||
|
||||
ScrollTo(mDestinationX, newPos, aUpdateFlags);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::ScrollByPixels(PRInt32 aNumPixelsX,
|
||||
PRInt32 aNumPixelsY,
|
||||
PRInt32& aOverflowX,
|
||||
PRInt32& aOverflowY,
|
||||
PRUint32 aUpdateFlags)
|
||||
{
|
||||
nsCOMPtr<nsIDeviceContext> dev;
|
||||
mViewManager->GetDeviceContext(*getter_AddRefs(dev));
|
||||
PRInt32 p2a = dev->AppUnitsPerDevPixel();
|
||||
|
||||
nscoord dx = NSIntPixelsToAppUnits(aNumPixelsX, p2a);
|
||||
nscoord dy = NSIntPixelsToAppUnits(aNumPixelsY, p2a);
|
||||
|
||||
CalcScrollOverflow(mDestinationX + dx, mDestinationY + dy, aOverflowX, aOverflowY);
|
||||
|
||||
return ScrollTo(mDestinationX + dx, mDestinationY + dy, aUpdateFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::CanScroll(PRBool aHorizontal,
|
||||
PRBool aForward,
|
||||
PRBool &aResult)
|
||||
{
|
||||
nscoord offset = aHorizontal ? mOffsetX : mOffsetY;
|
||||
|
||||
nsView* scrolledView = GetScrolledView();
|
||||
if (!scrolledView) {
|
||||
aResult = PR_FALSE;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRect scrolledRect;
|
||||
scrolledView->GetDimensions(scrolledRect);
|
||||
|
||||
// Can scroll to Top or to Left?
|
||||
if (!aForward) {
|
||||
aResult = offset > (aHorizontal ? scrolledRect.x : scrolledRect.y);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsSize portSize;
|
||||
GetDimensions(portSize);
|
||||
|
||||
nsCOMPtr<nsIDeviceContext> dev;
|
||||
mViewManager->GetDeviceContext(*getter_AddRefs(dev));
|
||||
PRInt32 p2a = dev->AppUnitsPerDevPixel();
|
||||
|
||||
nscoord max;
|
||||
if (aHorizontal) {
|
||||
max = scrolledRect.XMost() - portSize.width;
|
||||
// Round by pixel
|
||||
nscoord maxPx = NSAppUnitsToIntPixels(max, p2a);
|
||||
max = NSIntPixelsToAppUnits(maxPx, p2a);
|
||||
} else {
|
||||
max = scrolledRect.YMost() - portSize.height;
|
||||
// Round by pixel
|
||||
nscoord maxPx = NSAppUnitsToIntPixels(max, p2a);
|
||||
max = NSIntPixelsToAppUnits(maxPx, p2a);
|
||||
}
|
||||
|
||||
// Can scroll to Bottom or to Right?
|
||||
aResult = (offset < max) ? PR_TRUE : PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given aBlitRegion in appunits, create and return an nsRegion in
|
||||
* device pixels that represents the device pixels whose centers are
|
||||
* contained in aBlitRegion. Whatever appunit area was removed from
|
||||
* aBlitRegion in that process is added to aRepaintRegion. An appunits
|
||||
* version of the result is placed in aAppunitsBlitRegion.
|
||||
*
|
||||
* We convert the blit region to pixels this way because in general
|
||||
* frames touch the pixels whose centers are contained in the
|
||||
* (possibly not pixel-aligned) frame bounds.
|
||||
*/
|
||||
static void
|
||||
ConvertBlitRegionToPixelRects(const nsRegion& aBlitRegion,
|
||||
nscoord aAppUnitsPerPixel,
|
||||
nsTArray<nsIntRect>* aPixelRects,
|
||||
nsRegion* aRepaintRegion,
|
||||
nsRegion* aAppunitsBlitRegion)
|
||||
{
|
||||
const nsRect* r;
|
||||
|
||||
aPixelRects->Clear();
|
||||
aAppunitsBlitRegion->SetEmpty();
|
||||
// The rectangles in aBlitRegion don't overlap so converting them via
|
||||
// ToNearestPixels also produces a sequence of non-overlapping rectangles
|
||||
for (nsRegionRectIterator iter(aBlitRegion); (r = iter.Next());) {
|
||||
nsIntRect pixRect = r->ToNearestPixels(aAppUnitsPerPixel);
|
||||
aPixelRects->AppendElement(pixRect);
|
||||
aAppunitsBlitRegion->Or(*aAppunitsBlitRegion,
|
||||
pixRect.ToAppUnits(aAppUnitsPerPixel));
|
||||
}
|
||||
|
||||
nsRegion repaint;
|
||||
repaint.Sub(aBlitRegion, *aAppunitsBlitRegion);
|
||||
aRepaintRegion->Or(*aRepaintRegion, repaint);
|
||||
}
|
||||
|
||||
void nsScrollPortView::Scroll(nsView *aScrolledView, nsPoint aTwipsDelta,
|
||||
nsIntPoint aPixDelta, PRInt32 aP2A,
|
||||
const nsTArray<nsIWidget::Configuration>& aConfigurations)
|
||||
{
|
||||
if (aTwipsDelta.x != 0 || aTwipsDelta.y != 0)
|
||||
{
|
||||
/* If we should invalidate our wrapped view, we should do so at this
|
||||
* point.
|
||||
*/
|
||||
if (aScrolledView->NeedsInvalidateFrameOnScroll()) {
|
||||
mViewManager->GetViewObserver()->InvalidateFrameForScrolledView(aScrolledView);
|
||||
}
|
||||
|
||||
nsPoint nearestWidgetOffset;
|
||||
nsIWidget *nearestWidget = GetNearestWidget(&nearestWidgetOffset);
|
||||
if (!nearestWidget ||
|
||||
nearestWidget->GetTransparencyMode() == eTransparencyTransparent) {
|
||||
// Just update the view and adjust widgets
|
||||
// Recall that our widget's origin is at our bounds' top-left
|
||||
if (nearestWidget) {
|
||||
nearestWidget->ConfigureChildren(aConfigurations);
|
||||
}
|
||||
nsRect bounds(GetBounds());
|
||||
nsPoint topLeft(bounds.x, bounds.y);
|
||||
AdjustChildWidgets(aScrolledView,
|
||||
GetPosition() - topLeft, aP2A, PR_FALSE);
|
||||
// We should call this after fixing up the widget positions to be
|
||||
// consistent with the view hierarchy.
|
||||
mViewManager->GetViewObserver()->InvalidateFrameForScrolledView(aScrolledView);
|
||||
} else {
|
||||
nsRegion blitRegion;
|
||||
nsRegion repaintRegion;
|
||||
mViewManager->GetRegionsForBlit(aScrolledView, aTwipsDelta,
|
||||
&blitRegion, &repaintRegion);
|
||||
blitRegion.MoveBy(nearestWidgetOffset);
|
||||
repaintRegion.MoveBy(nearestWidgetOffset);
|
||||
|
||||
// We're going to bit-blit. Let the viewmanager know so it can
|
||||
// adjust dirty regions appropriately.
|
||||
mViewManager->WillBitBlit(this, aTwipsDelta);
|
||||
|
||||
// innerPixRegion is in device pixels
|
||||
nsTArray<nsIntRect> blitRects;
|
||||
nsRegion blitRectsRegion;
|
||||
ConvertBlitRegionToPixelRects(blitRegion, aP2A, &blitRects, &repaintRegion,
|
||||
&blitRectsRegion);
|
||||
|
||||
nearestWidget->Scroll(aPixDelta, blitRects, aConfigurations);
|
||||
AdjustChildWidgets(aScrolledView, nearestWidgetOffset, aP2A, PR_TRUE);
|
||||
repaintRegion.MoveBy(-nearestWidgetOffset);
|
||||
blitRectsRegion.MoveBy(-nearestWidgetOffset);
|
||||
mViewManager->UpdateViewAfterScroll(this, blitRectsRegion, repaintRegion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::ScrollToImpl(nscoord aX, nscoord aY)
|
||||
{
|
||||
PRInt32 dxPx = 0, dyPx = 0;
|
||||
|
||||
// convert to pixels
|
||||
nsCOMPtr<nsIDeviceContext> dev;
|
||||
mViewManager->GetDeviceContext(*getter_AddRefs(dev));
|
||||
PRInt32 p2a = dev->AppUnitsPerDevPixel();
|
||||
|
||||
// Update the scrolled view's position
|
||||
nsresult rv = ClampScrollValues(aX, aY, this);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32 xPixels = NSAppUnitsToIntPixels(aX, p2a);
|
||||
PRInt32 yPixels = NSAppUnitsToIntPixels(aY, p2a);
|
||||
|
||||
aX = NSIntPixelsToAppUnits(xPixels, p2a);
|
||||
aY = NSIntPixelsToAppUnits(yPixels, p2a);
|
||||
|
||||
// do nothing if we aren't scrolling.
|
||||
// this needs to be rechecked because of the clamping and
|
||||
// rounding
|
||||
if (aX == mOffsetX && aY == mOffsetY) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// figure out the diff by comparing old pos to new
|
||||
dxPx = NSAppUnitsToIntPixels(mOffsetX, p2a) - xPixels;
|
||||
dyPx = NSAppUnitsToIntPixels(mOffsetY, p2a) - yPixels;
|
||||
|
||||
// notify the listeners.
|
||||
PRUint32 listenerCount;
|
||||
const nsIID& kScrollPositionListenerIID = NS_GET_IID(nsIScrollPositionListener);
|
||||
nsIScrollPositionListener* listener;
|
||||
if (nsnull != mListeners) {
|
||||
if (NS_SUCCEEDED(mListeners->Count(&listenerCount))) {
|
||||
for (PRUint32 i = 0; i < listenerCount; i++) {
|
||||
if (NS_SUCCEEDED(mListeners->QueryElementAt(i, kScrollPositionListenerIID, (void**)&listener))) {
|
||||
listener->ScrollPositionWillChange(aX, aY);
|
||||
NS_RELEASE(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsView* scrolledView = GetScrolledView();
|
||||
if (!scrolledView) return NS_ERROR_FAILURE;
|
||||
|
||||
// move the scrolled view to the new location
|
||||
scrolledView->SetPositionIgnoringChildWidgets(-aX, -aY);
|
||||
|
||||
// notify the listeners.
|
||||
nsTArray<nsIWidget::Configuration> configurations;
|
||||
if (nsnull != mListeners) {
|
||||
if (NS_SUCCEEDED(mListeners->Count(&listenerCount))) {
|
||||
for (PRUint32 i = 0; i < listenerCount; i++) {
|
||||
if (NS_SUCCEEDED(mListeners->QueryElementAt(i, kScrollPositionListenerIID, (void**)&listener))) {
|
||||
listener->ViewPositionDidChange(&configurations);
|
||||
NS_RELEASE(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsPoint twipsDelta(aX - mOffsetX, aY - mOffsetY);
|
||||
|
||||
// store the new position
|
||||
mOffsetX = aX;
|
||||
mOffsetY = aY;
|
||||
|
||||
Scroll(scrolledView, twipsDelta, nsIntPoint(dxPx, dyPx), p2a, configurations);
|
||||
|
||||
mViewManager->SynthesizeMouseMove(PR_TRUE);
|
||||
|
||||
// notify the listeners.
|
||||
if (nsnull != mListeners) {
|
||||
if (NS_SUCCEEDED(mListeners->Count(&listenerCount))) {
|
||||
for (PRUint32 i = 0; i < listenerCount; i++) {
|
||||
if (NS_SUCCEEDED(mListeners->QueryElementAt(i, kScrollPositionListenerIID, (void**)&listener))) {
|
||||
listener->ScrollPositionDidChange(aX, aY);
|
||||
NS_RELEASE(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsScrollPortView::IsSmoothScrollingEnabled() {
|
||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (prefs) {
|
||||
PRBool enabled;
|
||||
nsresult rv = prefs->GetBoolPref(SMOOTH_SCROLL_PREF_NAME, &enabled);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback function from timer used in nsScrollPortView::ScrollTo
|
||||
*/
|
||||
void
|
||||
nsScrollPortView::AsyncScrollCallback(nsITimer *aTimer, void* anInstance)
|
||||
{
|
||||
nsScrollPortView* self = static_cast<nsScrollPortView*>(anInstance);
|
||||
if (self) {
|
||||
self->IncrementalScroll();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* manages data members and calls to ScrollTo from the (static) AsyncScrollCallback method
|
||||
*/
|
||||
void
|
||||
nsScrollPortView::IncrementalScroll()
|
||||
{
|
||||
if (!mAsyncScroll)
|
||||
return;
|
||||
|
||||
nsWeakView thisView = this;
|
||||
if (mAsyncScroll->mIsSmoothScroll) {
|
||||
if (mAsyncScroll->mFrameIndex < SMOOTH_SCROLL_FRAMES) {
|
||||
ScrollToImpl(mOffsetX + mAsyncScroll->mVelocities[mAsyncScroll->mFrameIndex*2],
|
||||
mOffsetY + mAsyncScroll->mVelocities[mAsyncScroll->mFrameIndex*2 + 1]);
|
||||
if (!thisView.IsAlive())
|
||||
return;
|
||||
mAsyncScroll->mFrameIndex++;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ScrollToImpl(mDestinationX, mDestinationY);
|
||||
if (!thisView.IsAlive())
|
||||
return;
|
||||
}
|
||||
delete mAsyncScroll;
|
||||
mAsyncScroll = nsnull;
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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 the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsScrollPortView_h___
|
||||
#define nsScrollPortView_h___
|
||||
|
||||
#include "nsView.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
class nsISupportsArray;
|
||||
class AsyncScroll;
|
||||
|
||||
//this is a class that acts as a container for other views and provides
|
||||
//automatic management of scrolling of the views it contains.
|
||||
|
||||
class nsScrollPortView : public nsView, public nsIScrollableView
|
||||
{
|
||||
public:
|
||||
nsScrollPortView(nsViewManager* aViewManager = nsnull);
|
||||
|
||||
virtual nsIScrollableView* ToScrollableView() { return this; }
|
||||
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID,
|
||||
void** aInstancePtr);
|
||||
|
||||
//nsIScrollableView interface
|
||||
NS_IMETHOD GetContainerSize(nscoord *aWidth, nscoord *aHeight) const;
|
||||
NS_IMETHOD SetScrolledView(nsIView *aScrolledView);
|
||||
NS_IMETHOD GetScrolledView(nsIView *&aScrolledView) const;
|
||||
|
||||
NS_IMETHOD GetScrollPosition(nscoord &aX, nscoord &aY) const;
|
||||
NS_IMETHOD ScrollTo(nscoord aX, nscoord aY, PRUint32 aUpdateFlags);
|
||||
NS_IMETHOD SetLineHeight(nscoord aHeight);
|
||||
NS_IMETHOD GetLineHeight(nscoord *aHeight);
|
||||
NS_IMETHOD ScrollByLines(PRInt32 aNumLinesX, PRInt32 aNumLinesY,
|
||||
PRUint32 aUpdateFlags = 0);
|
||||
NS_IMETHOD ScrollByLinesWithOverflow(PRInt32 aNumLinesX, PRInt32 aNumLinesY,
|
||||
PRInt32& aOverflowX, PRInt32& aOverflowY,
|
||||
PRUint32 aUpdateFlags = 0);
|
||||
NS_IMETHOD GetPageScrollDistances(nsSize *aDistances);
|
||||
NS_IMETHOD ScrollByPages(PRInt32 aNumPagesX, PRInt32 aNumPagesY,
|
||||
PRUint32 aUpdateFlags = 0);
|
||||
NS_IMETHOD ScrollByWhole(PRBool aTop, PRUint32 aUpdateFlags = 0);
|
||||
NS_IMETHOD ScrollByPixels(PRInt32 aNumPixelsX, PRInt32 aNumPixelsY,
|
||||
PRInt32& aOverflowX, PRInt32& aOverflowY,
|
||||
PRUint32 aUpdateFlags = 0);
|
||||
NS_IMETHOD CanScroll(PRBool aHorizontal, PRBool aForward, PRBool &aResult);
|
||||
|
||||
NS_IMETHOD_(nsIView*) View();
|
||||
|
||||
NS_IMETHOD AddScrollPositionListener(nsIScrollPositionListener* aListener);
|
||||
NS_IMETHOD RemoveScrollPositionListener(nsIScrollPositionListener* aListener);
|
||||
|
||||
// local to the view module
|
||||
|
||||
nsView* GetScrolledView() const { return GetFirstChild(); }
|
||||
|
||||
private:
|
||||
NS_IMETHOD ScrollToImpl(nscoord aX, nscoord aY);
|
||||
|
||||
// data members
|
||||
AsyncScroll* mAsyncScroll;
|
||||
|
||||
// methods
|
||||
void IncrementalScroll();
|
||||
PRBool IsSmoothScrollingEnabled();
|
||||
static void AsyncScrollCallback(nsITimer *aTimer, void* aSPV);
|
||||
|
||||
protected:
|
||||
virtual ~nsScrollPortView();
|
||||
|
||||
//private
|
||||
void Scroll(nsView *aScrolledView, nsPoint aTwipsDelta,
|
||||
nsIntPoint aPixDelta, nscoord aP2A,
|
||||
const nsTArray<nsIWidget::Configuration>& aConfigurations);
|
||||
PRBool CannotBitBlt(nsView* aScrolledView);
|
||||
nsresult CalcScrollOverflow(nscoord aX, nscoord aY, PRInt32& aOverflowX, PRInt32& aOverflowY);
|
||||
|
||||
nscoord mOffsetX, mOffsetY;
|
||||
nscoord mDestinationX, mDestinationY;
|
||||
nscoord mLineHeight;
|
||||
nsISupportsArray *mListeners;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -47,7 +47,6 @@
|
|||
#include "nsIRenderingContext.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsGfxCIID.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsView.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
@ -57,7 +56,6 @@
|
|||
#include "nsIPrefService.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsInt64.h"
|
||||
#include "nsScrollPortView.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
@ -278,20 +276,6 @@ nsViewManager::CreateView(const nsRect& aBounds,
|
|||
return v;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsIScrollableView *)
|
||||
nsViewManager::CreateScrollableView(const nsRect& aBounds,
|
||||
const nsIView* aParent)
|
||||
{
|
||||
nsScrollPortView *v = new nsScrollPortView(this);
|
||||
if (v) {
|
||||
v->SetPosition(aBounds.x, aBounds.y);
|
||||
nsRect dim(0, 0, aBounds.width, aBounds.height);
|
||||
v->SetDimensions(dim, PR_FALSE);
|
||||
v->SetParent(static_cast<nsView*>(const_cast<nsIView*>(aParent)));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsViewManager::GetRootView(nsIView *&aView)
|
||||
{
|
||||
aView = mRootView;
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include "prinrval.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsIRegion.h"
|
||||
#include "nsView.h"
|
||||
#include "nsIViewObserver.h"
|
||||
|
@ -109,9 +108,6 @@ public:
|
|||
const nsIView* aParent,
|
||||
nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow);
|
||||
|
||||
NS_IMETHOD_(nsIScrollableView*) CreateScrollableView(const nsRect& aBounds,
|
||||
const nsIView* aParent);
|
||||
|
||||
NS_IMETHOD GetRootView(nsIView *&aView);
|
||||
NS_IMETHOD SetRootView(nsIView *aView);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче