123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2013 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "console/consoleTypes.h"
- #include "console/console.h"
- #include "graphics/gBitmap.h"
- #include "graphics/TextureManager.h"
- #include "io/resource/resourceManager.h"
- #include "platform/event.h"
- #include "graphics/dgl.h"
- #include "gui/guiArrayCtrl.h"
- #include "gui/containers/guiSceneScrollCtrl.h"
- #include "gui/guiDefaultControlRender.h"
- #include "gui/guiCanvas.h"
- // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //
- GuiSceneScrollCtrl::GuiSceneScrollCtrl(SceneWindow* window) : GuiScrollCtrl()
- {
- mWindow = window;
- }
- void GuiSceneScrollCtrl::initPersistFields()
- {
- //Not a con object...
- }
- bool GuiSceneScrollCtrl::onWake()
- {
- if (mAwake)
- return false;
- if (mProfile != NULL)
- mProfile->incRefCount();
- if (mThumbProfile != NULL)
- mThumbProfile->incRefCount();
- if (mTrackProfile != NULL)
- mTrackProfile->incRefCount();
- if (mArrowProfile != NULL)
- mArrowProfile->incRefCount();
- mAwake = true;
- return true;
- }
- void GuiSceneScrollCtrl::onSleep()
- {
- if (!mAwake)
- return;
- if (mProfile != NULL)
- mProfile->decRefCount();
- if (mThumbProfile != NULL)
- mThumbProfile->decRefCount();
- if (mTrackProfile != NULL)
- mTrackProfile->decRefCount();
- if (mArrowProfile != NULL)
- mArrowProfile->decRefCount();
- mAwake = false;
- }
- #pragma region CalculationFunctions
- void GuiSceneScrollCtrl::calcContentExtents()
- {
- Vector2 v = mWindow->getCameraSize();
- mContentExt = Point2I(mCeil(v.x), mCeil(v.y));
- F32 zoom = getMax(mWindow->getCameraZoom(), 0.0000001f);
- mContentExt.x /= zoom;
- mContentExt.y /= zoom;
- //This will be removed later so we are countering it now.
- if (mHasVScrollBar)
- mContentExt.x += mScrollBarThickness;
- if (mHasHScrollBar)
- mContentExt.y += mScrollBarThickness;
- }
- bool GuiSceneScrollCtrl::calcChildExtents()
- {
- if (!mWindow->isViewLimitOn())
- return false;
- Vector2 v = mWindow->getViewLimitMax() - mWindow->getViewLimitMin();
- mChildExt = Point2I(mFloor(v.x), mFloor(v.y));
- return true;
- }
- void GuiSceneScrollCtrl::calcScrollOffset()
- {
- //Set the offset based on the position of the visible area of the window
- RectF cameraArea = mWindow->getCameraArea();
- F32 zoom = getMax(mWindow->getCameraZoom(), 0.0000001f);
- Point2F actualExtent = Point2F(cameraArea.extent);
- cameraArea.extent.x /= zoom;
- cameraArea.extent.y /= zoom;
- cameraArea.point.x += ((actualExtent.x - cameraArea.extent.x) / 2);
- cameraArea.point.y += ((actualExtent.y - cameraArea.extent.y) / 2);
- Vector2 min = mWindow->getViewLimitMin();
- Vector2 max = mWindow->getViewLimitMax();
- mScrollOffset.x = mRound(cameraArea.point.x - min.x);
- mScrollOffset.y = mRound(max.y - (cameraArea.point.y + cameraArea.extent.y));
- }
- void GuiSceneScrollCtrl::calcScrollRects(RectI &fillRect)
- {
- RectI rect = RectI(Point2I(0,0), mWindow->mBounds.extent);
- Parent::calcScrollRects(rect);
- }
- #pragma endregion
- #pragma region ScrollingFunctions
- void GuiSceneScrollCtrl::scrollDelta(S32 deltaX, S32 deltaY)
- {
- Vector2 pos = mWindow->getCameraPosition();
- Vector2 size = mWindow->getCameraSize() / mWindow->getCameraZoom();
- pos.x += deltaX;
- pos.y -= deltaY;
- Vector2 min = mWindow->getViewLimitMin();
- Vector2 max = mWindow->getViewLimitMax();
- pos.x = getMax(pos.x, min.x + (size.x / 2));
- pos.y = getMax(pos.y, min.y + (size.y / 2));
- pos.x = getMin(pos.x, max.x - (size.x / 2));
- pos.y = getMin(pos.y, max.y - (size.y / 2));
- mWindow->setTargetCameraPosition(pos);
- mWindow->startCameraMove(0.2);
- }
- void GuiSceneScrollCtrl::scrollTo(S32 x, S32 y)
- {
- Vector2 pos = mWindow->getCameraPosition();
- Vector2 size = mWindow->getCameraSize() / mWindow->getCameraZoom();
- Vector2 min = mWindow->getViewLimitMin();
- Vector2 max = mWindow->getViewLimitMax();
- if (x != mScrollOffset.x)
- {
- F32 halfW = size.x / 2;
- pos.x = getMin(getMax(x + halfW + min.x, min.x + halfW), max.x - halfW);
- }
- if (y != mScrollOffset.y)
- {
- F32 halfH = size.y / 2;
- pos.y = getMin(getMax(max.y - (y + halfH), min.y + halfH), max.y - halfH);
- }
- mWindow->setCameraPosition(pos);
- }
- void GuiSceneScrollCtrl::scrollByRegion(Region reg)
- {
- Vector2 v = mWindow->getCameraSize() / mWindow->getCameraZoom();
- U32 pageWidth = mCeil(v.x * 0.8);
- U32 pageHeight = mCeil(v.y * 0.8);
- U32 columnWidth = mCeil(v.x * 0.1);
- U32 rowHeight = mCeil(v.y * 0.1);
- if (mVBarEnabled)
- {
- switch (reg)
- {
- case UpPage:
- scrollDelta(0, -(S32)pageHeight);
- break;
- case DownPage:
- scrollDelta(0, pageHeight);
- break;
- case UpArrow:
- scrollDelta(0, -(S32)rowHeight);
- break;
- case DownArrow:
- scrollDelta(0, rowHeight);
- break;
- case LeftArrow:
- case RightArrow:
- case LeftPage:
- case RightPage:
- case VertThumb:
- case HorizThumb:
- case Content:
- //Con::errorf("Unhandled case in GuiSceneScrollCtrl::scrollByRegion");
- break;
- }
- }
- if (mHBarEnabled)
- {
- switch (reg)
- {
- case LeftPage:
- scrollDelta(-(S32)pageWidth, 0);
- break;
- case RightPage:
- scrollDelta(pageWidth, 0);
- break;
- case LeftArrow:
- scrollDelta(-(S32)columnWidth, 0);
- break;
- case RightArrow:
- scrollDelta(columnWidth, 0);
- break;
- case UpArrow:
- case DownArrow:
- case UpPage:
- case DownPage:
- case VertThumb:
- case HorizThumb:
- case Content:
- //Con::errorf("Unhandled case in GuiSceneScrollCtrl::scrollByRegion");
- break;
- }
- }
- }
- void GuiSceneScrollCtrl::scrollRectVisible(RectI rect)
- {
- //We don't do this...
- }
- #pragma endregion
- #pragma region Event_Processing
- Point2I GuiSceneScrollCtrl::localToGlobalCoord(const Point2I &src)
- {
- return mWindow->localToGlobalCoord(src);
- }
- Point2I GuiSceneScrollCtrl::globalToLocalCoord(const Point2I &src)
- {
- return mWindow->globalToLocalCoord(src);
- }
- void GuiSceneScrollCtrl::onTouchDown(const GuiEvent &event)
- {
- Point2I curMousePos = globalToLocalCoord(event.mousePoint);
- mDepressed = true;
- mouseLock();
- // Set a 0.5 second delay before we start scrolling
- mLastUpdated = Platform::getVirtualMilliseconds() + 500;
- scrollByRegion(curHitRegion);
- if (curHitRegion == VertThumb)
- {
- mScrollOffsetAnchor = mScrollOffset;
- mThumbMouseDelta = curMousePos.y - mVThumbPos;
- }
- else if (curHitRegion == HorizThumb)
- {
- mScrollOffsetAnchor = mScrollOffset;
- mThumbMouseDelta = curMousePos.x - mHThumbPos;
- }
- }
- void GuiSceneScrollCtrl::onTouchDragged(const GuiEvent &event)
- {
- Point2I curMousePos = globalToLocalCoord(event.mousePoint);
- mWindow->setUpdate();
- if ((curHitRegion != VertThumb) && (curHitRegion != HorizThumb))
- {
- Region hit = findHitRegion(curMousePos);
- if (hit != curHitRegion)
- mDepressed = false;
- else
- mDepressed = true;
- return;
- }
- // ok... if the mouse is 'near' the scroll bar, scroll with it
- // otherwise, snap back to the previous position.
- if (curHitRegion == VertThumb)
- {
- if (curMousePos.x >= mVTrackRect.point.x - mScrollBarDragTolerance &&
- curMousePos.x <= mVTrackRect.point.x + mVTrackRect.extent.x - 1 + mScrollBarDragTolerance &&
- curMousePos.y >= mVTrackRect.point.y - mScrollBarDragTolerance &&
- curMousePos.y <= mVTrackRect.point.y + mVTrackRect.extent.y - 1 + mScrollBarDragTolerance)
- {
- S32 newVThumbPos = curMousePos.y - mThumbMouseDelta;
- if (newVThumbPos != mVThumbPos)
- {
- S32 newVPos = (newVThumbPos) *
- (mChildExt.y - mContentExt.y) /
- (mVTrackRect.extent.y - mVThumbSize);
- scrollTo(mScrollOffset.x, newVPos);
- }
- }
- else
- scrollTo(mScrollOffset.x, mScrollOffsetAnchor.y);
- }
- else if (curHitRegion == HorizThumb)
- {
- if (curMousePos.x >= mHTrackRect.point.x - mScrollBarDragTolerance &&
- curMousePos.x <= mHTrackRect.point.x + mHTrackRect.extent.x - 1 + mScrollBarDragTolerance &&
- curMousePos.y >= mHTrackRect.point.y - mScrollBarDragTolerance &&
- curMousePos.y <= mHTrackRect.point.y + mHTrackRect.extent.y - 1 + mScrollBarDragTolerance)
- {
- S32 newHThumbPos = curMousePos.x - mThumbMouseDelta;
- if (newHThumbPos != mHThumbPos)
- {
- S32 newHPos = (newHThumbPos) *
- (mChildExt.x - mContentExt.x) /
- (mHTrackRect.extent.x - mHThumbSize);
- scrollTo(newHPos, mScrollOffset.y);
- }
- }
- else
- scrollTo(mScrollOffsetAnchor.x, mScrollOffset.y);
- }
- }
- bool GuiSceneScrollCtrl::isMouseLocked()
- {
- GuiCanvas *root = mWindow->getRoot();
- return root ? root->getMouseLockedControl() == this : false;
- }
- void GuiSceneScrollCtrl::mouseLock(GuiControl *lockingControl)
- {
- GuiCanvas *root = mWindow->getRoot();
- if (root)
- root->mouseLock(lockingControl);
- }
- void GuiSceneScrollCtrl::mouseLock()
- {
- GuiCanvas *root = mWindow->getRoot();
- if (root)
- root->mouseLock(this);
- }
- void GuiSceneScrollCtrl::mouseUnlock()
- {
- GuiCanvas *root = mWindow->getRoot();
- if (root)
- root->mouseUnlock(this);
- }
- #pragma endregion
- #pragma region rendering
- void GuiSceneScrollCtrl::onRender(Point2I offset, const RectI &updateRect)
- {
- RectI contentRect = applyScrollBarSpacing(offset, mBounds.extent);
- mChildArea.set(contentRect.point, contentRect.extent);
- renderVScrollBar(offset);
- renderHScrollBar(offset);
- }
- #pragma endregion
|