BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContainerView::SCROLL_ORIENTATION axis) const
{
	if(mScrollbar[axis]->getVisible())
	{
		LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
		const S32 AUTOSCROLL_SIZE = 10;
		if(mScrollbar[axis]->getVisible())
		{
			inner_rect_local.mRight -= SCROLLBAR_SIZE;
			inner_rect_local.mTop += AUTOSCROLL_SIZE;
			inner_rect_local.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE;
		}
		if( inner_rect_local.pointInRect( x, y ) && (mScrollbar[axis]->getDocPos() > 0) )
		{
			return TRUE;
		}

	}
	return FALSE;
}
bool LLScrollContainer::autoScroll(S32 x, S32 y)
{
	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);

	bool scrolling = false;
	if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
	{
		LLRect screen_local_extents;
		screenRectToLocal(getRootView()->getLocalRect(), &screen_local_extents);

		LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
		if(	mScrollbar[HORIZONTAL]->getVisible() )
		{
			inner_rect_local.mBottom += scrollbar_size;
		}
		if(	mScrollbar[VERTICAL]->getVisible() )
		{
			inner_rect_local.mRight -= scrollbar_size;
		}

		// clip rect against root view
		inner_rect_local.intersectWith(screen_local_extents);

		S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
		// autoscroll region should take up no more than one third of visible scroller area
		S32 auto_scroll_region_width = llmin(inner_rect_local.getWidth() / 3, 10); 
		S32 auto_scroll_region_height = llmin(inner_rect_local.getHeight() / 3, 10); 

		if(	mScrollbar[HORIZONTAL]->getVisible() )
		{
			LLRect left_scroll_rect = screen_local_extents;
			left_scroll_rect.mRight = inner_rect_local.mLeft + auto_scroll_region_width;
			if( left_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() > 0) )
			{
				mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() - auto_scroll_speed );
				mAutoScrolling = TRUE;
				scrolling = true;
			}

			LLRect right_scroll_rect = screen_local_extents;
			right_scroll_rect.mLeft = inner_rect_local.mRight - auto_scroll_region_width;
			if( right_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() < mScrollbar[HORIZONTAL]->getDocPosMax()) )
			{
				mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() + auto_scroll_speed );
				mAutoScrolling = TRUE;
				scrolling = true;
			}
		}
		if(	mScrollbar[VERTICAL]->getVisible() )
		{
			LLRect bottom_scroll_rect = screen_local_extents;
			bottom_scroll_rect.mTop = inner_rect_local.mBottom + auto_scroll_region_height;
			if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() < mScrollbar[VERTICAL]->getDocPosMax()) )
			{
				mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() + auto_scroll_speed );
				mAutoScrolling = TRUE;
				scrolling = true;
			}

			LLRect top_scroll_rect = screen_local_extents;
			top_scroll_rect.mBottom = inner_rect_local.mTop - auto_scroll_region_height;
			if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() > 0) )
			{
				mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() - auto_scroll_speed );
				mAutoScrolling = TRUE;
				scrolling = true;
			}
		}
	}
	return scrolling;
}
BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask,
												  BOOL drop,
												  EDragAndDropType cargo_type,
												  void* cargo_data,
												  EAcceptance* accept,
												  std::string& tooltip_msg)
{
	// Scroll folder view if needed.  Never accepts a drag or drop.
	*accept = ACCEPT_NO;
	BOOL handled = FALSE;
	if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
	{
		const S32 AUTOSCROLL_SIZE = 10;
		S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
		
		LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
		if(	mScrollbar[HORIZONTAL]->getVisible() )
		{
			inner_rect_local.mBottom += SCROLLBAR_SIZE;
		}
		if(	mScrollbar[VERTICAL]->getVisible() )
		{
			inner_rect_local.mRight -= SCROLLBAR_SIZE;
		}

		if(	mScrollbar[HORIZONTAL]->getVisible() )
		{
			LLRect left_scroll_rect = inner_rect_local;
			left_scroll_rect.mRight = AUTOSCROLL_SIZE;
			if( left_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() > 0) )
			{
				mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() - auto_scroll_speed );
				mAutoScrolling = TRUE;
				handled = TRUE;
			}

			LLRect right_scroll_rect = inner_rect_local;
			right_scroll_rect.mLeft = inner_rect_local.mRight - AUTOSCROLL_SIZE;
			if( right_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() < mScrollbar[HORIZONTAL]->getDocPosMax()) )
			{
				mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() + auto_scroll_speed );
				mAutoScrolling = TRUE;
				handled = TRUE;
			}
		}
		if(	mScrollbar[VERTICAL]->getVisible() )
		{
			LLRect bottom_scroll_rect = inner_rect_local;
			bottom_scroll_rect.mTop = AUTOSCROLL_SIZE + bottom_scroll_rect.mBottom;
			if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() < mScrollbar[VERTICAL]->getDocPosMax()) )
			{
				mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() + auto_scroll_speed );
				mAutoScrolling = TRUE;
				handled = TRUE;
			}

			LLRect top_scroll_rect = inner_rect_local;
			top_scroll_rect.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE;
			if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() > 0) )
			{
				mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() - auto_scroll_speed );
				mAutoScrolling = TRUE;
				handled = TRUE;
			}
		}
	}

	if( !handled )
	{
		handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type,
											cargo_data, accept, tooltip_msg) != NULL;
	}

	return TRUE;
}