Exemplo n.º 1
0
tbool CScrollBar::OnMouse(EMouseMsg MouseMsg, const SPos& Pos)
{
	if (!IsVisible()) {
		return false;
	}

	if (CPane::OnMouse(MouseMsg, Pos)) {
		return true;
	}

	if (mbScrolling) {
		// We're currently scrolling
		switch(MouseMsg) {
			case MouseMove:
				{
					switch(mType) {
						case TypeHorizontal:
							{
								// Calculate the mouse delta
								tint iMouseDelta = Pos.iX - mMousePosOrg.iX;

								// Calculate where we want the handle to be
								tint iHandlePosX = mScrollBarRectOrg.iX + iMouseDelta;

								// Calculate movememt from mouse delta
								std::list<IControl*>::iterator it = mControls.begin();
								if (mControls.size() > 2) {
									it++;
								}
								IControl* pControl = *it++;
								SRect RctArrowLeft;
								pControl->GetRect(RctArrowLeft);

								// Left-most possible handle position
								SPos PosLeftMost(RctArrowLeft.iX + RctArrowLeft.iCX, RctArrowLeft.iY);

								pControl = *it;
								SPos PosRightArrow;
								pControl->GetPos(PosRightArrow);
								tint iMaxWidth = PosRightArrow.iX - PosLeftMost.iX;

								// Calculate the relative width we occupy
								tfloat64 fWidthRelative = mScrollPos.VisibleRect.iCX / (double)mScrollPos.AreaSize.iCX;

								// Calculate the ralative position to be
								tfloat64 fPositionRelative = (iHandlePosX - PosLeftMost.iX) / (iMaxWidth - (fWidthRelative * iMaxWidth));

								// Update scrolling position
								mScrollPos = mScrollPosOrg;
								mScrollPos.VisibleRect.iX = (int)((fPositionRelative * (mScrollPos.AreaSize.iCX - mScrollPos.VisibleRect.iCX)) + 0.5f);

								// Limit scrolling position
								if (mScrollPos.VisibleRect.iX < 0) {
									mScrollPos.VisibleRect.iX = 0;
								}
								if (mScrollPos.VisibleRect.iX > mScrollPos.AreaSize.iCX - mScrollPos.VisibleRect.iCX) {
									mScrollPos.VisibleRect.iX = mScrollPos.AreaSize.iCX - mScrollPos.VisibleRect.iCX;
								}

								// Redraw and set scroll pos (which will cause scroll pane to redraw)
								CControl::Redraw();
								mpScrollPane->SetScrollPos(mScrollPos);

								SetValue(0);
							}
							break;
						case TypeVertical:
							{
								// Calculate the mouse delta
								tint iMouseDelta = Pos.iY - mMousePosOrg.iY;

								// Calculate where we want the handle to be
								tint iHandlePosY = mScrollBarRectOrg.iY + iMouseDelta;

								// Calculate movememt from mouse delta
								std::list<IControl*>::iterator it = mControls.begin();
								if (mControls.size() > 2) {
									it++;
								}
								IControl* pControl = *it++;
								SRect RctArrowTop;
								pControl->GetRect(RctArrowTop);

								// Top-most possible handle position
								SPos PosTopMost(RctArrowTop.iX, RctArrowTop.iY + RctArrowTop.iCY);

								pControl = *it;
								SPos PosBottomArrow;
								pControl->GetPos(PosBottomArrow);
								tint iMaxHeight = PosBottomArrow.iY - PosTopMost.iY;

								// Calculate the relative height we occupy
								tfloat64 fHeightRelative = mScrollPos.VisibleRect.iCY / (double)mScrollPos.AreaSize.iCY;

								// Calculate the ralative position to be
								tfloat64 fPositionRelative = (iHandlePosY - PosTopMost.iY) / (iMaxHeight - (fHeightRelative * iMaxHeight));

								// Update scrolling position
								mScrollPos = mScrollPosOrg;
								mScrollPos.VisibleRect.iY = (int)((fPositionRelative * (mScrollPos.AreaSize.iCY - mScrollPos.VisibleRect.iCY)) + 0.5f);

								// Limit scrolling position
								if (mScrollPos.VisibleRect.iY < 0) {
									mScrollPos.VisibleRect.iY = 0;
								}
								if (mScrollPos.VisibleRect.iY > mScrollPos.AreaSize.iCY - mScrollPos.VisibleRect.iCY) {
									mScrollPos.VisibleRect.iY = mScrollPos.AreaSize.iCY - mScrollPos.VisibleRect.iCY;
								}

								// Redraw and set scroll pos (which will cause scroll pane to redraw)
								CControl::Redraw();
								mpScrollPane->SetScrollPos(mScrollPos);

								SetValue(0);
							}
							break;
					}
				}
				break;
			case LeftButtonUp:
				{
					dynamic_cast<CWindow*>(GetParentWindow())->ReleaseMouseFocus();

					mbScrolling = false;

					return true;
				}
				break;
		}
	}

	SRect rctHandle = GetHandleRect();
	if (rctHandle.Inside(Pos)) {
		// We hit the handle with the mouse
		if (MouseMsg == LeftButtonDown) {
			mMousePosOrg = Pos;
			mScrollPosOrg = mScrollPos;
			mScrollBarRectOrg = rctHandle;

			dynamic_cast<CWindow*>(GetParentWindow())->GetMouseFocus(dynamic_cast<IControl*>(this));

			mbScrolling = true;

			return true;
		}
	}
	else {
		if (MouseMsg == LeftButtonDown) {
			SRect RctThis;
			GetRect(RctThis);
			if (RctThis.Inside(Pos)) {
				// We hit inside the control (but not the handle)
				switch(mType) {
					case TypeHorizontal:
						{
							// Calculate the mouse delta
							tint iMouseDelta;
							if (Pos.iX < rctHandle.iX) {
								iMouseDelta = -rctHandle.iCX;
							}
							else {
								iMouseDelta = rctHandle.iCX;
							}

							// Calculate where we want the handle to be
							tint iHandlePosX = rctHandle.iX + iMouseDelta;

							// Calculate movememt from mouse delta
							std::list<IControl*>::iterator it = mControls.begin();
							if (mControls.size() > 2) {
								it++;
							}
							IControl* pControl = *it++;
							SRect RctArrowLeft;
							pControl->GetRect(RctArrowLeft);

							// Left-most possible handle position
							SPos PosLeftMost(RctArrowLeft.iX + RctArrowLeft.iCX, RctArrowLeft.iY);

							pControl = *it;
							SPos PosRightArrow;
							pControl->GetPos(PosRightArrow);
							tint iMaxWidth = PosRightArrow.iX - PosLeftMost.iX;

							// Calculate the relative width we occupy
							tfloat64 fWidthRelative = mScrollPos.VisibleRect.iCX / (double)mScrollPos.AreaSize.iCX;

							// Calculate the ralative position to be
							tfloat64 fPositionRelative = (iHandlePosX - PosLeftMost.iX) / (iMaxWidth - (fWidthRelative * iMaxWidth));

							// Update scrolling position
							mScrollPos = mScrollPos;
							mScrollPos.VisibleRect.iX = (int)((fPositionRelative * (mScrollPos.AreaSize.iCX - mScrollPos.VisibleRect.iCX)) + 0.5f);

							// Limit scrolling position
							if (mScrollPos.VisibleRect.iX < 0) {
								mScrollPos.VisibleRect.iX = 0;
							}
							if (mScrollPos.VisibleRect.iX > mScrollPos.AreaSize.iCX - mScrollPos.VisibleRect.iCX) {
								mScrollPos.VisibleRect.iX = mScrollPos.AreaSize.iCX - mScrollPos.VisibleRect.iCX;
							}

							// Redraw and set scroll pos (which will cause scroll pane to redraw)
							CControl::Redraw();
							mpScrollPane->SetScrollPos(mScrollPos);
							
							// Lasse, added 2008-04-17 - bug-fix, didn't fire listeners' EventValueChange
							SetValue(0);
							// .. Lasse
						}
						break;

					case TypeVertical:
						{
							// Calculate the mouse delta
							tint iMouseDelta;
							if (Pos.iY < rctHandle.iY) {
								iMouseDelta = -rctHandle.iCY;
							}
							else {
								iMouseDelta = rctHandle.iCY;
							}

							// Calculate where we want the handle to be
							tint iHandlePosY = rctHandle.iY + iMouseDelta;

							// Calculate movememt from mouse delta
							std::list<IControl*>::iterator it = mControls.begin();
							if (mControls.size() > 2) {
								it++;
							}
							IControl* pControl = *it++;
							SRect RctArrowTop;
							pControl->GetRect(RctArrowTop);

							// Top-most possible handle position
							SPos PosTopMost(RctArrowTop.iX, RctArrowTop.iY + RctArrowTop.iCY);

							pControl = *it;
							SPos PosBottomArrow;
							pControl->GetPos(PosBottomArrow);
							tint iMaxHeight = PosBottomArrow.iY - PosTopMost.iY;

							// Calculate the relative height we occupy
							tfloat64 fHeightRelative = mScrollPos.VisibleRect.iCY / (double)mScrollPos.AreaSize.iCY;

							// Calculate the ralative position to be
							tfloat64 fPositionRelative = (iHandlePosY - PosTopMost.iY) / (iMaxHeight - (fHeightRelative * iMaxHeight));

							// Update scrolling position
							mScrollPos = mScrollPos;
							mScrollPos.VisibleRect.iY = (int)((fPositionRelative * (mScrollPos.AreaSize.iCY - mScrollPos.VisibleRect.iCY)) + 0.5f);

							// Limit scrolling position
							if (mScrollPos.VisibleRect.iY < 0) {
								mScrollPos.VisibleRect.iY = 0;
							}
							if (mScrollPos.VisibleRect.iY > mScrollPos.AreaSize.iCY - mScrollPos.VisibleRect.iCY) {
								mScrollPos.VisibleRect.iY = mScrollPos.AreaSize.iCY - mScrollPos.VisibleRect.iCY;
							}

							// Redraw and set scroll pos (which will cause scroll pane to redraw)
							CControl::Redraw();
							mpScrollPane->SetScrollPos(mScrollPos);
							
							// Lasse, added 2008-04-17 - bug-fix, didn't fire listeners' EventValueChange
							SetValue(0);
							// .. Lasse
						}
						break;
				}
			}
		}
	}

	return false;
}
Exemplo n.º 2
0
void CScrollBar::EventValueChange(IControl *pSender, tint32 /*iValueNew*/)
{
	// Lasse, add 2008-05-09
	if ((mpScrollPane) && (pSender == mpScrollPane)) {
		SScrollPos sp;
		mpScrollPane->GetScrollPos(sp);
		if (mScrollPos != sp) {
			SRect rectTest1 = GetHandleRect();
			SetScrollPos(sp, true);
			//PositionControls();
			Redraw(GetRect());
			SRect rectTest2 = GetHandleRect();
			int iDummy = 0;
		}
		return;
	}
	// .. Lasse

	// Figure out which one of the controls it is
	std::list<IControl*>::iterator it = mControls.begin();
	if (mControls.size() > 2) {
		it++;
	}
	tint iDelta;
	if (pSender == *it) {
		// Up / left
		iDelta = -10;
	}
	else {
		// Down / right
		iDelta = 10;
	}

	SRect rctHandle = GetHandleRect();

	switch(mType) {
		case TypeHorizontal:
			{
				// Calculate where we want the handle to be
				tint iHandlePosX = rctHandle.iX + iDelta;

				// Calculate movememt from mouse delta
				std::list<IControl*>::iterator it = mControls.begin();
				if (mControls.size() > 2) {
					it++;
				}
				IControl* pControl = *it++;
				SRect RctArrowLeft;
				pControl->GetRect(RctArrowLeft);

				// Left-most possible handle position
				SPos PosLeftMost(RctArrowLeft.iX + RctArrowLeft.iCX, RctArrowLeft.iY);

				pControl = *it;
				SPos PosRightArrow;
				pControl->GetPos(PosRightArrow);
				tint iMaxWidth = PosRightArrow.iX - PosLeftMost.iX;

				// Calculate the relative width we occupy
				tfloat64 fWidthRelative = mScrollPos.VisibleRect.iCX / (double)mScrollPos.AreaSize.iCX;

				// Calculate the ralative position to be
				tfloat64 fPositionRelative = (iHandlePosX - PosLeftMost.iX) / (iMaxWidth - (fWidthRelative * iMaxWidth));

				// Update scrolling position
				mScrollPos.VisibleRect.iX = (int)((fPositionRelative * (mScrollPos.AreaSize.iCX - mScrollPos.VisibleRect.iCX)) + 0.5f);

				// Limit scrolling position
				if (mScrollPos.VisibleRect.iX < 0) {
					mScrollPos.VisibleRect.iX = 0;
				}
				if (mScrollPos.VisibleRect.iX > mScrollPos.AreaSize.iCX - mScrollPos.VisibleRect.iCX) {
					mScrollPos.VisibleRect.iX = mScrollPos.AreaSize.iCX - mScrollPos.VisibleRect.iCX;
				}

				// Redraw and set scroll pos (which will cause scroll pane to redraw)
				CControl::Redraw();
				mpScrollPane->SetScrollPos(mScrollPos);
			}
			break;
		case TypeVertical:
			{
				// Calculate where we want the handle to be
				tint iHandlePosY = rctHandle.iY + iDelta;

				// Calculate movememt from mouse delta
				std::list<IControl*>::iterator it = mControls.begin();
				if (mControls.size() > 2) {
					it++;
				}
				IControl* pControl = *it++;
				SRect RctArrowTop;
				pControl->GetRect(RctArrowTop);

				// Top-most possible handle position
				SPos PosTopMost(RctArrowTop.iX, RctArrowTop.iY + RctArrowTop.iCY);

				pControl = *it;
				SPos PosBottomArrow;
				pControl->GetPos(PosBottomArrow);
				tint iMaxHeight = PosBottomArrow.iY - PosTopMost.iY;

				// Calculate the relative height we occupy
				tfloat64 fHeightRelative = mScrollPos.VisibleRect.iCY / (double)mScrollPos.AreaSize.iCY;

				// Calculate the ralative position to be
				tfloat64 fPositionRelative = (iHandlePosY - PosTopMost.iY) / (iMaxHeight - (fHeightRelative * iMaxHeight));

				// Update scrolling position
				mScrollPos.VisibleRect.iY = (int)((fPositionRelative * (mScrollPos.AreaSize.iCY - mScrollPos.VisibleRect.iCY)) + 0.5f);

				// Limit scrolling position
				if (mScrollPos.VisibleRect.iY < 0) {
					mScrollPos.VisibleRect.iY = 0;
				}
				if (mScrollPos.VisibleRect.iY > mScrollPos.AreaSize.iCY - mScrollPos.VisibleRect.iCY) {
					mScrollPos.VisibleRect.iY = mScrollPos.AreaSize.iCY - mScrollPos.VisibleRect.iCY;
				}

				// Redraw and set scroll pos (which will cause scroll pane to redraw)
				CControl::Redraw();
				mpScrollPane->SetScrollPos(mScrollPos);
			}
			break;
	}
}
Exemplo n.º 3
0
SRect CScrollBar::GetHandleRect()
{
	SRect rctHandle;

	if (mpScrollPane)
		mpScrollPane->GetScrollPos(mScrollPos);

	switch(mType) {
		case TypeHorizontal:
			{
				// The leftmost top-left point is 1 pixel to the right of the top-right point of the left arrow
				std::list<IControl*>::iterator it = mControls.begin();
				if (mControls.size() > 2) {
					it++;
				}
				IControl* pControl = *it++;
				SRect RctArrow;
				pControl->GetRect(RctArrow);

				SPos Pos(RctArrow.iX + RctArrow.iCX, RctArrow.iY);

				// Calculate the relative position (top-left point)
				tint iDiff = mScrollPos.AreaSize.iCX - mScrollPos.VisibleRect.iCX;
				tfloat64 fPositionRelative;
				if (iDiff == 0) {
					fPositionRelative = 0;
				}
				else {
					fPositionRelative = (double)mScrollPos.VisibleRect.iX / iDiff;
				}

				// Calculate the maximum width of the handle
				pControl = *it;
				SPos PosRightArrow;
				pControl->GetPos(PosRightArrow);
				tint iMaxWidth = PosRightArrow.iX - Pos.iX;

				// Calculate the relative width we occupy
				tfloat64 fWidthRelative = mScrollPos.VisibleRect.iCX / (double)mScrollPos.AreaSize.iCX;

				// Calculate the absolute size
				rctHandle = SRect(Pos, SSize(0, 0));
				rctHandle.iCY = mpBitmapSizes[BitmapCenterHandle].iCY;
				rctHandle.iCX = (int)((fWidthRelative * iMaxWidth) + 0.5);

				// Calculate the absolute position
				rctHandle.iX += (int)((fPositionRelative * (iMaxWidth - rctHandle.iCX)) + 0.5);

				if (rctHandle.iCX < mpBitmapSizes[BitmapLeftTopHandle].iCX + mpBitmapSizes[BitmapRightDownHandle].iCX) {
					rctHandle.iCX = mpBitmapSizes[BitmapLeftTopHandle].iCX + mpBitmapSizes[BitmapRightDownHandle].iCX;
				}
			}
			break;
		case TypeVertical:
			{
				// The topmost top-left point is 1 pixel below the bottom-left point of the up arrow
				std::list<IControl*>::iterator it = mControls.begin();
				if (mControls.size() > 2) {
					it++;
				}
				IControl* pControl = *it++;
				SRect RctArrow;
				pControl->GetRect(RctArrow);

				SPos Pos(RctArrow.iX, RctArrow.iY + RctArrow.iCY);

				// Calculate the relative position (top-left point)
				tint iDiff = mScrollPos.AreaSize.iCY - mScrollPos.VisibleRect.iCY;
				tfloat64 fPositionRelative;
				if (iDiff == 0) {
					fPositionRelative = 0;
				}
				else {
					fPositionRelative = (double)mScrollPos.VisibleRect.iY / iDiff;
				}

				// Calculate the maximum height of the handle
				pControl = *it;
				SPos PosDownArrow;
				pControl->GetPos(PosDownArrow);
				tint iMaxHeight = PosDownArrow.iY - Pos.iY;

				// Calculate the relative height we occupy
				tfloat64 fHeightRelative = mScrollPos.VisibleRect.iCY / (double)mScrollPos.AreaSize.iCY;

				// Calculate the absolute size
				rctHandle = SRect(Pos, SSize(0, 0));
				rctHandle.iCX = mpBitmapSizes[BitmapCenterHandle].iCX;
				rctHandle.iCY = (int)((fHeightRelative * iMaxHeight) + 0.5);

				// Calculate the absolute position
				rctHandle.iY += (int)((fPositionRelative * (iMaxHeight - rctHandle.iCY)) + 0.5);

				if (rctHandle.iCY < mpBitmapSizes[BitmapLeftTopHandle].iCY + mpBitmapSizes[BitmapRightDownHandle].iCY) {
					rctHandle.iCY = mpBitmapSizes[BitmapLeftTopHandle].iCY + mpBitmapSizes[BitmapRightDownHandle].iCY;
				}
			}
			break;
	}

	return rctHandle;
}