scrolling views are now self-contained. preparations have been made for horizontal scrolling.

This commit is contained in:
michaelp 1998-05-07 23:07:10 +00:00
Родитель 442e49f74c
Коммит 61b60abf2b
5 изменённых файлов: 106 добавлений и 70 удалений

Просмотреть файл

@ -35,23 +35,26 @@ public:
virtual void ComputeContainerSize(void) = 0;
/**
* Get the height of the container
* @result height of container
* Get the dimensions of the container
* @param aWidth return value for width of container
* @param aHeight return value for height of container
*/
virtual PRInt32 GetContainerSize(void) = 0;
virtual void GetContainerSize(nscoord *aWidth, nscoord *aHeight) = 0;
/**
* Set the offset into the container of the
* topmost visible coordinate
* @param aOffset offset in twips
* top/left most visible coordinate
* @param aOffsetX X offset in twips
* @param aOffsetY Y offset in twips
*/
virtual void SetVisibleOffset(PRInt32 aOffset) = 0;
virtual void SetVisibleOffset(nscoord aOffsetX, nscoord aOffsetY) = 0;
/**
* Get the offset of the topmost visible coordinate
* @result coordinate in twips
* Get the offset of the top/left most visible coordinate
* @param aOffsetX return value for X coordinate in twips
* @param aOffsetY return value for Y coordinate in twips
*/
virtual PRInt32 GetVisibleOffset(void) = 0;
virtual void GetVisibleOffset(nscoord *aOffsetX, nscoord *aOffsetY) = 0;
/**
* Get the view that we are scrolling within the

Просмотреть файл

@ -79,14 +79,24 @@ static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
nsScrollingView :: nsScrollingView()
{
mSizeX = mSizeY = 0;
mOffsetX = mOffsetY = 0;
mVScrollBarView = nsnull;
mHScrollBarView = nsnull;
}
nsScrollingView :: ~nsScrollingView()
{
if (nsnull != mScrollBarView)
if (nsnull != mVScrollBarView)
{
NS_RELEASE(mScrollBarView);
mScrollBarView = nsnull;
NS_RELEASE(mVScrollBarView);
mVScrollBarView = nsnull;
}
if (nsnull != mHScrollBarView)
{
NS_RELEASE(mHScrollBarView);
mHScrollBarView = nsnull;
}
}
@ -139,11 +149,11 @@ nsresult nsScrollingView :: Init(nsIViewManager* aManager,
// Create a view
mScrollBarView = new ScrollBarView();
mVScrollBarView = new ScrollBarView();
if (nsnull != mScrollBarView)
if (nsnull != mVScrollBarView)
{
NS_ADDREF(mScrollBarView);
NS_ADDREF(mVScrollBarView);
nsRect trect = aBounds;
@ -152,9 +162,9 @@ nsresult nsScrollingView :: Init(nsIViewManager* aManager,
static NS_DEFINE_IID(kCScrollbarIID, NS_VERTSCROLLBAR_CID);
rv = mScrollBarView->Init(mViewManager, trect, this, &kCScrollbarIID);
rv = mVScrollBarView->Init(mViewManager, trect, this, &kCScrollbarIID);
mViewManager->InsertChild(this, mScrollBarView, 0);
mViewManager->InsertChild(this, mVScrollBarView, 0);
}
NS_RELEASE(dx);
@ -172,18 +182,18 @@ void nsScrollingView :: SetDimensions(nscoord width, nscoord height)
nsView :: SetDimensions(width, height);
if (nsnull != mScrollBarView)
if (nsnull != mVScrollBarView)
{
cx = mViewManager->GetPresContext();
dx = cx->GetDeviceContext();
mScrollBarView->GetDimensions(&trect.width, &trect.height);
mVScrollBarView->GetDimensions(&trect.width, &trect.height);
trect.height = height;
trect.x = width - NS_TO_INT_ROUND(dx->GetScrollBarWidth());
trect.y = 0;
mScrollBarView->SetBounds(trect);
mVScrollBarView->SetBounds(trect);
//this will fix the size of the thumb when we resize the root window,
//but unfortunately it will also cause scrollbar flashing. so long as
@ -208,30 +218,28 @@ nsEventStatus nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEvent
case NS_SCROLLBAR_LINE_NEXT:
case NS_SCROLLBAR_LINE_PREV:
{
nscoord ox, oy, ny;
nscoord oy;
nsIPresContext *px = mViewManager->GetPresContext();
nscoord dy;
float scale = px->GetTwipsToPixels();
mViewManager->GetWindowOffsets(&ox, &oy);
oy = mOffsetY;
//now, this horrible thing makes sure that as we scroll
//the document a pixel at a time, we keep the logical position of
//our scroll bar at the top edge of the same pixel that
//is displayed.
ny = NS_TO_INT_ROUND(NS_TO_INT_ROUND(((nsScrollbarEvent *)aEvent)->position * scale) * px->GetPixelsToTwips());
mOffsetY = NS_TO_INT_ROUND(NS_TO_INT_ROUND(((nsScrollbarEvent *)aEvent)->position * scale) * px->GetPixelsToTwips());
mViewManager->SetWindowOffsets(ox, ny);
dy = NS_TO_INT_ROUND(scale * (oy - ny));
dy = NS_TO_INT_ROUND(scale * (oy - mOffsetY));
if (dy != 0)
{
nsRect clip;
nscoord sx, sy;
mScrollBarView->GetDimensions(&sx, &sy);
mVScrollBarView->GetDimensions(&sx, &sy);
clip.x = 0;
clip.y = 0;
@ -246,7 +254,7 @@ nsEventStatus nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEvent
//a full pixel. if didn't adjust the thumb only if the delta is non-zero,
//very slow scrolling would never actually work.
((nsScrollbarEvent *)aEvent)->position = ny;
((nsScrollbarEvent *)aEvent)->position = mOffsetY;
AdjustChildWidgets(0, dy);
}
@ -272,55 +280,53 @@ void nsScrollingView :: ComputeContainerSize()
if (nsnull != scrollview)
{
if (nsnull != mScrollBarView)
if (nsnull != mVScrollBarView)
{
nsIPresContext *px = mViewManager->GetPresContext();
nscoord width, height;
nsIScrollbar *scroll;
nsIWidget *win;
PRUint32 oldsize = mSize;
PRUint32 oldsize = mSizeY;
nsRect area(0, 0, 0, 0);
PRInt32 offx, offy, dy;
PRInt32 offy, dy;
float scale = px->GetTwipsToPixels();
ComputeScrollArea(scrollview, area, 0, 0);
mSize = area.YMost();
mSizeY = area.YMost();
mScrollBarView->GetDimensions(&width, &height);
mViewManager->GetWindowOffsets(&offx, &offy);
mVScrollBarView->GetDimensions(&width, &height);
offy = mOffsetY;
win = mScrollBarView->GetWidget();
win = mVScrollBarView->GetWidget();
static NS_DEFINE_IID(kscroller, NS_ISCROLLBAR_IID);
if (NS_OK == win->QueryInterface(kscroller, (void **)&scroll))
{
if (mSize > mBounds.height)
if (mSizeY > mBounds.height)
{
//we need to be able to scroll
mScrollBarView->SetVisibility(nsViewVisibility_kShow);
mVScrollBarView->SetVisibility(nsViewVisibility_kShow);
//now update the scroller position for the new size
PRUint32 newpos, oldpos = scroll->GetPosition();
PRUint32 oldpos = scroll->GetPosition();
newpos = NS_TO_INT_ROUND(NS_TO_INT_ROUND((((float)oldpos * mSize) / oldsize) * scale) * px->GetPixelsToTwips());
mOffsetY = NS_TO_INT_ROUND(NS_TO_INT_ROUND((((float)oldpos * mSizeY) / oldsize) * scale) * px->GetPixelsToTwips());
mViewManager->SetWindowOffsets(offx, newpos);
dy = NS_TO_INT_ROUND(scale * (offy - mOffsetY));
dy = NS_TO_INT_ROUND(scale * (offy - newpos));
scroll->SetParameters(mSize, mBounds.height, newpos, NS_POINTS_TO_TWIPS_INT(12));
scroll->SetParameters(mSizeY, mBounds.height, mOffsetY, NS_POINTS_TO_TWIPS_INT(12));
NS_RELEASE(px);
}
else
{
mViewManager->SetWindowOffsets(offx, 0);
mOffsetY = 0;
dy = NS_TO_INT_ROUND(scale * offy);
mScrollBarView->SetVisibility(nsViewVisibility_kHide);
mVScrollBarView->SetVisibility(nsViewVisibility_kHide);
}
if (dy != 0)
@ -336,19 +342,22 @@ void nsScrollingView :: ComputeContainerSize()
}
}
PRInt32 nsScrollingView :: GetContainerSize()
void nsScrollingView :: GetContainerSize(nscoord *aWidth, nscoord *aHeight)
{
return mSize;
*aWidth = mSizeX;
*aHeight = mSizeY;
}
void nsScrollingView :: SetVisibleOffset(PRInt32 aOffset)
void nsScrollingView :: SetVisibleOffset(nscoord aOffsetX, nscoord aOffsetY)
{
mOffset = aOffset;
mOffsetX = aOffsetX;
mOffsetY = aOffsetY;
}
PRInt32 nsScrollingView :: GetVisibleOffset()
void nsScrollingView :: GetVisibleOffset(nscoord *aOffsetX, nscoord *aOffsetY)
{
return mOffset;
*aOffsetX = mOffsetX;
*aOffsetY = mOffsetY;
}
void nsScrollingView :: AdjustChildWidgets(nscoord aDx, nscoord aDy)
@ -359,7 +368,7 @@ void nsScrollingView :: AdjustChildWidgets(nscoord aDx, nscoord aDy)
{
nsIView *kid = GetChild(cnt);
if (kid != mScrollBarView)
if ((kid != mVScrollBarView) && (kid != mHScrollBarView))
{
nsIWidget *win = kid->GetWidget();
@ -389,7 +398,7 @@ nsIView * nsScrollingView :: GetScrolledView(void)
{
retview = GetChild(cnt);
if (retview != mScrollBarView)
if ((retview != mVScrollBarView) && (retview != mHScrollBarView))
break;
else
retview = nsnull;

Просмотреть файл

@ -54,20 +54,19 @@ public:
//nsIScrollableView interface
virtual void ComputeContainerSize();
virtual PRInt32 GetContainerSize();
virtual void SetVisibleOffset(PRInt32 aOffset);
virtual PRInt32 GetVisibleOffset();
virtual void GetContainerSize(nscoord *aWidth, nscoord *aHeight);
virtual void SetVisibleOffset(nscoord aOffsetX, nscoord aOffsetY);
virtual void GetVisibleOffset(nscoord *aOffsetX, nscoord *aOffsetY);
virtual nsIView * GetScrolledView(void);
//private
void ComputeScrollArea(nsIView *aView, nsRect &aRect, nscoord aOffX, nscoord aOffY);
protected:
PRInt32 mSize;
PRInt32 mOffset;
nsIView *mScrollBarView;
nscoord mSizeX, mSizeY;
nscoord mOffsetX, mOffsetY;
nsIView *mVScrollBarView;
nsIView *mHScrollBarView;
};
#endif

Просмотреть файл

@ -23,6 +23,7 @@
#include "nsIRenderingContext.h"
#include "nsIDeviceContext.h"
#include "nsGfxCIID.h"
#include "nsIScrollableView.h"
static const PRBool gsDebug = PR_FALSE;
@ -123,8 +124,6 @@ nsresult nsViewManager::Init(nsIPresContext* aPresContext)
}
mContext = aPresContext;
mOffset.x = mOffset.y = 0;
mDSBounds.Empty();
mDrawingSurface = nsnull;
mTimer = nsnull;
@ -221,14 +220,38 @@ void nsViewManager :: SetWindowDimensions(nscoord width, nscoord height)
void nsViewManager :: GetWindowOffsets(nscoord *xoffset, nscoord *yoffset)
{
*xoffset = mOffset.x;
*yoffset = mOffset.y;
if (nsnull != mRootView)
{
nsIScrollableView *scroller;
static NS_DEFINE_IID(kscroller, NS_ISCROLLABLEVIEW_IID);
if (NS_OK == mRootView->QueryInterface(kscroller, (void **)&scroller))
{
scroller->GetVisibleOffset(xoffset, yoffset);
NS_RELEASE(scroller);
}
else
*xoffset = *yoffset = 0;
}
else
*xoffset = *yoffset = 0;
}
void nsViewManager :: SetWindowOffsets(nscoord xoffset, nscoord yoffset)
{
mOffset.x = xoffset;
mOffset.y = yoffset;
if (nsnull != mRootView)
{
nsIScrollableView *scroller;
static NS_DEFINE_IID(kscroller, NS_ISCROLLABLEVIEW_IID);
if (NS_OK == mRootView->QueryInterface(kscroller, (void **)&scroller))
{
scroller->SetVisibleOffset(xoffset, yoffset);
NS_RELEASE(scroller);
}
}
}
void nsViewManager :: Refresh(nsIRenderingContext *aContext, nsRegion *region, PRUint32 aUpdateFlags)
@ -239,6 +262,7 @@ void nsViewManager :: Refresh(nsIView *aView, nsIRenderingContext *aContext, nsR
{
nsRect wrect;
nsIRenderingContext *localcx = nsnull;
nscoord xoff, yoff;
if (nsnull == aContext)
{
@ -262,12 +286,14 @@ void nsViewManager :: Refresh(nsIView *aView, nsIRenderingContext *aContext, nsR
if (aUpdateFlags & NS_VMREFRESH_SCREEN_RECT)
localcx->SetClipRect(*rect, PR_FALSE);
localcx->Translate(-mOffset.x, -mOffset.y);
GetWindowOffsets(&xoff, &yoff);
localcx->Translate(-xoff, -yoff);
nsRect trect = *rect;
if (aUpdateFlags & NS_VMREFRESH_SCREEN_RECT)
trect.MoveBy(mOffset.x, mOffset.y);
trect.MoveBy(xoff, yoff);
else
localcx->SetClipRect(trect, PR_FALSE);

Просмотреть файл

@ -170,7 +170,6 @@ private:
nsIPresContext *mContext;
nsIWidget *mRootWindow;
nsPoint mOffset;
nsRect mDSBounds;
nsDrawingSurface mDrawingSurface;