Beispiel #1
0
void wxScrollBar::SetRange(int range)
{
    SetScrollbar(GetThumbPosition(), GetThumbSize(), range, GetPageSize());
}
Beispiel #2
0
wxRect wxScrollBar::GetScrollbarRect(wxScrollBar::Element elem,
                                     int thumbPos) const
{
    if ( thumbPos == -1 )
    {
        thumbPos = GetThumbPosition();
    }

    const wxSize sizeArrow = m_renderer->GetScrollbarArrowSize();

    wxSize sizeTotal = GetClientSize();
    wxCoord *start, *width;
    wxCoord length, arrow;
    wxRect rect;
    if ( IsVertical() )
    {
        rect.x = 0;
        rect.width = sizeTotal.x;
        length = sizeTotal.y;
        start = &rect.y;
        width = &rect.height;
        arrow = sizeArrow.y;
    }
    else // horizontal
    {
        rect.y = 0;
        rect.height = sizeTotal.y;
        length = sizeTotal.x;
        start = &rect.x;
        width = &rect.width;
        arrow = sizeArrow.x;
    }

    switch ( elem )
    {
        case wxScrollBar::Element_Arrow_Line_1:
            *start = 0;
            *width = arrow;
            break;

        case wxScrollBar::Element_Arrow_Line_2:
            *start = length - arrow;
            *width = arrow;
            break;

        case wxScrollBar::Element_Arrow_Page_1:
        case wxScrollBar::Element_Arrow_Page_2:
            // we don't have them at all
            break;

        case wxScrollBar::Element_Thumb:
        case wxScrollBar::Element_Bar_1:
        case wxScrollBar::Element_Bar_2:
            // we need to calculate the thumb position - do it
            {
                length -= 2*arrow;
                wxCoord thumbStart, thumbEnd;
                int range = GetRange();
                if ( !range )
                {
                    thumbStart =
                    thumbEnd = 0;
                }
                else
                {
                    GetScrollBarThumbSize(length,
                                          thumbPos,
                                          GetThumbSize(),
                                          range,
                                          &thumbStart,
                                          &thumbEnd);
                }

                if ( elem == wxScrollBar::Element_Thumb )
                {
                    *start = thumbStart;
                    *width = thumbEnd - thumbStart;
                }
                else if ( elem == wxScrollBar::Element_Bar_1 )
                {
                    *start = 0;
                    *width = thumbStart;
                }
                else // elem == wxScrollBar::Element_Bar_2
                {
                    *start = thumbEnd;
                    *width = length - thumbEnd;
                }

                // everything is relative to the start of the shaft so far
                *start += arrow;
            }
            break;

        case wxScrollBar::Element_Max:
        default:
            wxFAIL_MSG( wxT("unknown scrollbar element") );
    }

    return rect;
}
Beispiel #3
0
void wxScrollBar::SetPageSize( int pageLength )
{
    SetScrollbar(GetThumbPosition(), GetThumbSize(), GetRange(), pageLength);
}
Beispiel #4
0
wxHitTest wxScrollBar::HitTestBar(const wxPoint& pt) const
{
    // we only need to work with either x or y coord depending on the
    // orientation, choose one (but still check the other one to verify if the
    // mouse is in the window at all)
    const wxSize sizeArrowSB = m_renderer->GetScrollbarArrowSize();

    wxCoord coord, sizeArrow, sizeTotal;
    wxSize size = GetSize();
    if ( GetWindowStyle() & wxVERTICAL )
    {
        if ( pt.x < 0 || pt.x > size.x )
            return wxHT_NOWHERE;

        coord = pt.y;
        sizeArrow = sizeArrowSB.y;
        sizeTotal = size.y;
    }
    else // horizontal
    {
        if ( pt.y < 0 || pt.y > size.y )
            return wxHT_NOWHERE;

        coord = pt.x;
        sizeArrow = sizeArrowSB.x;
        sizeTotal = size.x;
    }

    // test for the arrows first as it's faster
    if ( coord < 0 || coord > sizeTotal )
    {
        return wxHT_NOWHERE;
    }
    else if ( coord < sizeArrow )
    {
        return wxHT_SCROLLBAR_ARROW_LINE_1;
    }
    else if ( coord > sizeTotal - sizeArrow )
    {
        return wxHT_SCROLLBAR_ARROW_LINE_2;
    }
    else
    {
        // calculate the thumb position in pixels
        sizeTotal -= 2*sizeArrow;
        wxCoord thumbStart, thumbEnd;
        int range = GetRange();
        if ( !range )
        {
            // clicking the scrollbar without range has no effect
            return wxHT_NOWHERE;
        }
        else
        {
            GetScrollBarThumbSize(sizeTotal,
                                  GetThumbPosition(),
                                  GetThumbSize(),
                                  range,
                                  &thumbStart,
                                  &thumbEnd);
        }

        // now compare with the thumb position
        coord -= sizeArrow;
        if ( coord < thumbStart )
            return wxHT_SCROLLBAR_BAR_1;
        else if ( coord > thumbEnd )
            return wxHT_SCROLLBAR_BAR_2;
        else
            return wxHT_SCROLLBAR_THUMB;
    }
}
//+---------------------------------------------------------------------------
//
//  Member:     CScrollbarController::MouseMove
//              
//  Synopsis:   Handle mouse move events.
//              
//  Arguments:  pt      new mouse location
//              
//  Notes:      
//              
//----------------------------------------------------------------------------
void CScrollbarController::MouseMove(const CPoint& pt)
{
	_ptMouse = pt;
	_pDispScroller->TransformPoint(&_ptMouse, COORDSYS_GLOBAL, COORDSYS_CONTAINER);

	switch(_partPressedStart)
	{
	case SBP_NONE:
	case SBP_TRACK:
		AssertSz(FALSE, "unexpected call to CScrollbarController::MouseMoved");
		break;

	case SBP_THUMB:
		{
			LONG contentSize = _pDispScroller->GetContentSize()[_direction];
			Assert(contentSize >= 0);
			LONG trackSize =
				GetTrackSize(_direction, _rcScrollbar, _buttonWidth) -
				GetThumbSize(_direction, _rcScrollbar, contentSize,
				_rcScrollbar.Size(_direction), _buttonWidth,
				&_drawInfo);
			if(trackSize <= 0)
			{
				break; // can't move thumb
			}

			// NOTE: we're not currently checking to see if the mouse point
			// is out of range perpendicular to the scroll bar axis
			BOOL fRightToLeft = (_direction==0 && _pDispScroller->IsRightToLeft());
			LONG trackPos;
			if(!fRightToLeft)
			{
				trackPos = _ptMouse[_direction] - _rcScrollbar[_direction] -
					GetScaledButtonWidth(_direction, _rcScrollbar, _buttonWidth) - _mouseInThumb;
			}
			else
			{
				trackPos = _rcScrollbar.right -
					GetScaledButtonWidth(_direction, _rcScrollbar, _buttonWidth) -
					_mouseInThumb - _ptMouse.x;
			}
			LONG scrollOffset;
			if(trackPos <= 0)
			{
				scrollOffset = 0;
			}
			else
			{
				contentSize -= _rcScrollbar.Size(_direction);
				scrollOffset = MulDivQuick(trackPos, contentSize, trackSize);
				if(fRightToLeft)
				{
					scrollOffset = -scrollOffset;
				}
			}

			_pLayout->OnScroll(_direction, SB_THUMBPOSITION, scrollOffset);
		}
		break;

	default:
		{
			// find out what the mouse would be pressing in its new location.
			// If it's not the same as it used to be, invalidate the part.
			SCROLLBARPART partPressedOld = _partPressed;
			LONG contentSize, containerSize, scrollAmount;
			GetScrollInfo(&contentSize, &containerSize, &scrollAmount);
			_partPressed = GetPart(
				_direction,
				_rcScrollbar,
				_ptMouse,
				contentSize,
				containerSize,
				scrollAmount,
				_buttonWidth,
				&_drawInfo,
				_pDispScroller->IsRightToLeft());
			if(_partPressed != _partPressedStart)
			{
				_partPressed = SBP_NONE;
			}
			if(_partPressed != partPressedOld)
			{
				SCROLLBARPART invalidPart = _partPressed;
				if(_partPressed != SBP_NONE)
				{
					// perform scroll action and set timer
					OnTick(SB_REPEAT_TIMER);
				}
				else
				{
					invalidPart = partPressedOld;
				}
				Verify(_pLayout->OpenView());
				InvalidatePart(
					invalidPart,
					_direction,
					_rcScrollbar,
					contentSize,
					containerSize,
					scrollAmount,
					_buttonWidth,
					_pDispScroller,
					&_drawInfo);
			}
		}
		break;
	}
}
//+---------------------------------------------------------------------------
//
//  Member:     CScrollbarController::StartScrollbarController
//              
//  Synopsis:   Start a scroll bar controller if necessary.
//              
//  Arguments:  pLayout         layout object to be called on scroll changes
//              pDispScroller   display scroller node
//              pServerHost     server host
//              buttonWidth     custom scroll bar button width
//              pMessage        message that caused creation of controller
//              
//  Notes:      
//              
//----------------------------------------------------------------------------
void CScrollbarController::StartScrollbarController(
	CLayout*		pLayout,
	CDispScroller*	pDispScroller,
	CServer*		pServerHost,
	long			buttonWidth,
	CMessage*		pMessage)
{
	Assert(pLayout != NULL);
	Assert(pDispScroller != NULL);
	Assert(pServerHost != NULL);
	Assert(pMessage != NULL);
	BOOL fRightToLeft;

	CScrollbarController* pSBC = TLS(pSBC);
	Assert(pSBC != NULL);

	// just to make sure previous controller is stopped
	if(pSBC->_pLayout != NULL)
	{
		StopScrollbarController();
	}

	pSBC->_direction = (pMessage->htc==HTC_HSCROLLBAR ? 0 : 1);
	pSBC->_pDispScroller = pDispScroller;
	pSBC->_drawInfo.Init(pLayout->ElementOwner());
	fRightToLeft = (pSBC->_direction==0 && pDispScroller->IsRightToLeft());

	// calculate scroll bar rect
	pDispScroller->GetClientRect(
		&pSBC->_rcScrollbar,
		(pSBC->_direction==0?CLIENTRECT_HSCROLLBAR:CLIENTRECT_VSCROLLBAR));
	Assert(pSBC->_rcScrollbar.Contains(pMessage->ptContent));

	LONG contentSize, containerSize, scrollAmount;
	pSBC->GetScrollInfo(&contentSize, &containerSize, &scrollAmount);

	// if the scrollbar is inactive, it doesn't matter what was pressed
	if(contentSize <= containerSize)
	{
		return;
	}

	// what was pressed?
	pSBC->_partPressed = GetPart(
		pSBC->_direction,
		pSBC->_rcScrollbar,
		pMessage->ptContent,
		contentSize,
		containerSize,
		scrollAmount,
		buttonWidth,
		pSBC->GetDrawInfo(),
		pDispScroller->IsRightToLeft());
	Assert(pSBC->_partPressed != SBP_NONE);

	// if inactive track was pressed, no more work to do
	if(pSBC->_partPressed == SBP_TRACK)
	{
		return;
	}

	// make scroll bar controller active
	pSBC->_partPressedStart = pSBC->_partPressed;
	pSBC->_pLayout = pLayout;
	pSBC->_pDispScroller = pDispScroller;
	pSBC->_pServerHost = pServerHost;
	pSBC->_buttonWidth = buttonWidth;
	pSBC->_ptMouse = pMessage->ptContent;

	LONG lScrollTime = MAX_SCROLLTIME;

	// if thumbing, compute hit point offset from top of thumb
	if(pSBC->_partPressed == SBP_THUMB)
	{
		long trackSize = GetTrackSize(
			pSBC->_direction, pSBC->_rcScrollbar, pSBC->_buttonWidth);
		long thumbSize = GetThumbSize(
			pSBC->_direction, pSBC->_rcScrollbar, contentSize, containerSize,
			pSBC->_buttonWidth, pSBC->GetDrawInfo());
		// _mouseInThumb is the xPos of the mouse in from the left edge of the thumb in LTR cases
		// and xPos of the mouse in from the right edge of the thumb in RTL HSCROLL cases
		if(!fRightToLeft)
		{
			pSBC->_mouseInThumb = 
				pSBC->_ptMouse[pSBC->_direction] -
				pSBC->_rcScrollbar[pSBC->_direction] -
				GetScaledButtonWidth(pSBC->_direction, pSBC->_rcScrollbar, pSBC->_buttonWidth) -
				GetThumbOffset(contentSize, containerSize, scrollAmount, trackSize, thumbSize);
		}
		else
		{
			pSBC->_mouseInThumb = 
				pSBC->_rcScrollbar.right -
				GetScaledButtonWidth(pSBC->_direction, pSBC->_rcScrollbar, pSBC->_buttonWidth) +
				GetThumbOffset(contentSize, containerSize, scrollAmount, trackSize, thumbSize) -
				pSBC->_ptMouse.x;
		}
		Assert(pSBC->_mouseInThumb >= 0);
		// no smooth scrolling
		lScrollTime = 0;
	}

	// capture the mouse
	HWND hwnd = pServerHost->_pInPlace->_hwnd;
	if(FAILED(GWSetCapture(
		pSBC,
		ONMESSAGE_METHOD(CScrollbarController, OnMessage, onmessage),
		hwnd)))
	{
		pSBC->_pLayout = NULL;
		return;
	}

	// set timer for repeating actions
	if(pSBC->_partPressed != SBP_THUMB)
	{
		// perform first action
		pLayout->OnScroll(
			pSBC->_direction, TranslateSBAction(pSBC->_partPressed), 0, FALSE, lScrollTime);

		CSize scrollOffset;
		pSBC->_pDispScroller->GetScrollOffset(&scrollOffset);
		scrollAmount = scrollOffset[pSBC->_direction];

		// set timer for subsequent action
		FormsSetTimer(
			pSBC,
			ONTICK_METHOD(CScrollbarController, OnTick, ontick),
			SB_REPEAT_TIMER,
			GetRepeatDelay());
	}

	// invalidate the part we hit, if necessary
	pLayout->OpenView();
	InvalidatePart(
		pSBC->_partPressed,
		pSBC->_direction,
		pSBC->_rcScrollbar,
		contentSize,
		containerSize,
		scrollAmount,
		buttonWidth,
		pDispScroller,
		pSBC->GetDrawInfo());
}
Beispiel #7
0
gg_tl_dat BigScrollBar::GetBigThumbSize()
{
	gg_tl_dat result = (((gg_tl_dat)GetThumbSize())*m_BigRange)/SCROLLBAR_LENGTH;
	return result;
}
Beispiel #8
0
//+---------------------------------------------------------------------------
//
//  Member:     CScrollbar::GetPartRect
//              
//  Synopsis:   Return the rect bounding the given scroll bar part.
//              
//  Arguments:  prcPart         returns part rect
//              part            which scroll bar part
//              direction       0 for horizontal scroll bar, 1 for vertical
//              rcScrollbar     scroll bar bounds
//              contentSize     size of content controlled by scroll bar
//              containerSize   size of container
//              scrollAmount    current scroll amount
//              buttonWidth     width of scroll bar buttons
//              fRightToLeft    The text flow is RTL...0,0 is at top right
//              
//  Notes:      
//              
//----------------------------------------------------------------------------
void CScrollbar::GetPartRect(
							 CRect*			prcPart,
							 SCROLLBARPART	part,
							 int			direction,
							 const CRect&	rcScrollbar,
							 long			contentSize,
							 long			containerSize,
							 long			scrollAmount,
							 long			buttonWidth,
							 CDrawInfo*		pDI,
							 BOOL			fRightToLeft)
{
	// adjust button width if there isn't room for both buttons at full size
	long scaledButtonWidth = GetScaledButtonWidth(direction, rcScrollbar, buttonWidth);

	switch(part)
	{
	case SBP_NONE:
		AssertSz(FALSE, "CScrollbar::GetPartRect called with no part");
		prcPart->SetRectEmpty();
		break;

	case SBP_PREVBUTTON:
		*prcPart = rcScrollbar;
		(*prcPart)[direction+2] = rcScrollbar[direction] + scaledButtonWidth;
		break;

	case SBP_NEXTBUTTON:
		*prcPart = rcScrollbar;
		(*prcPart)[direction] = rcScrollbar[direction+2] - scaledButtonWidth;
		break;

	case SBP_TRACK:
	case SBP_PREVTRACK:
	case SBP_NEXTTRACK:
	case SBP_THUMB:
		{
			if(contentSize<=containerSize && part!=SBP_TRACK)
			{
				prcPart->SetRectEmpty();
				break;
			}

			*prcPart = rcScrollbar;
			(*prcPart)[direction] += scaledButtonWidth;
			(*prcPart)[direction+2] -= scaledButtonWidth;
			if(part == SBP_TRACK)
			{
				break;
			}

			// calculate thumb size
			long trackSize = prcPart->Size(direction);
			long thumbSize = GetThumbSize(
				direction, rcScrollbar, contentSize, containerSize, buttonWidth, pDI);
			long thumbOffset = GetThumbOffset(
				contentSize, containerSize, scrollAmount, trackSize, thumbSize);

			if(part == SBP_THUMB)
			{
				// We need to special case RTL HSCROLL
				if(direction==0 && fRightToLeft)
				{
					prcPart->right += thumbOffset;
					prcPart->left = prcPart->right - thumbSize;
				}
				else
				{
					(*prcPart)[direction] += thumbOffset;
					(*prcPart)[direction+2] = (*prcPart)[direction] + thumbSize;
				}
			}
			else if(part == SBP_PREVTRACK)
			{
				if(direction==0 && fRightToLeft)
				{
					prcPart->right += thumbOffset - thumbSize;
				}
				else
				{
					(*prcPart)[direction+2] = (*prcPart)[direction] + thumbOffset;
				}
			}
			else
			{
				if(direction==0 && fRightToLeft)
				{
					prcPart->left = prcPart->right + thumbOffset;
				}
				else
				{
					(*prcPart)[direction] += thumbOffset + thumbSize;
				}
			}
		}
		break;
	}
}