12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 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 "platform/platform.h"
- #include "platform/typetraits.h"
- #include "gui/containers/guiScrollCtrl.h"
- #include "console/engineAPI.h"
- #include "console/console.h"
- #include "gfx/bitmap/gBitmap.h"
- #include "gui/core/guiDefaultControlRender.h"
- #include "gfx/gfxDevice.h"
- #include "gfx/gfxDrawUtil.h"
- #include "gui/core/guiCanvas.h"
- IMPLEMENT_CONOBJECT( GuiScrollCtrl );
- ConsoleDocClass( GuiScrollCtrl,
- "@brief A container that allows to view one or more possibly larger controls inside its area by "
- "providing horizontal and/or vertical scroll bars.\n\n"
-
- "@ingroup GuiContainers"
- );
- ImplementEnumType( GuiScrollBarBehavior,
- "Display behavior of a scroll bar. Determines when a scrollbar will be visible.\n\n"
- "@ingroup GuiContainers" )
- { GuiScrollCtrl::ScrollBarAlwaysOn, "alwaysOn", "Always visible." },
- { GuiScrollCtrl::ScrollBarAlwaysOff, "alwaysOff", "Never visible." },
- { GuiScrollCtrl::ScrollBarDynamic, "dynamic", "Only visible when actually needed, i.e. when the child control(s) exceed the visible space on the given axis." },
- EndImplementEnumType;
- IMPLEMENT_CALLBACK( GuiScrollCtrl, onScroll, void, (), (),
- "Called each time the child controls are scrolled by some amount." );
- //-----------------------------------------------------------------------------
- GuiScrollCtrl::GuiScrollCtrl()
- : mBorderThickness( 1 ),
- mChildMargin( 0, 0 ),
- mScrollBarThickness( 16 ),
- mScrollBarArrowBtnLength( 16 ),
- mScrollBarDragTolerance( 130 ),
- mStateDepressed( false ),
- mHitRegion( None ),
- mForceVScrollBar( ScrollBarAlwaysOn ),
- mUseConstantHeightThumb( false ),
- mWillFirstRespond( true ),
- mForceHScrollBar( ScrollBarAlwaysOn ),
- mLockHorizScroll( false ),
- mLockVertScroll( false ),
- mIgnoreChildResized( false ),
- mAnimating( false ),
- mScrollAnimSpeed( -1 ),
- mChildPos(0, 0),
- mChildExt(0, 0),
- mScrollTargetPos( -1, -1 ),
- mBaseThumbSize(0),
- mHBarEnabled(false),
- mVBarEnabled(false),
- mHasHScrollBar(false),
- mHasVScrollBar(false),
- mHThumbSize(1),
- mHThumbPos(0),
- mVThumbSize(1),
- mVThumbPos(0),
- mThumbMouseDelta(0)
- {
- mBitmapBounds = NULL;
- mIsContainer = true;
- setExtent(200,200);
- mLastPreRender = Platform::getVirtualMilliseconds();
- mLastUpdated = Platform::getVirtualMilliseconds();
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::initPersistFields()
- {
- docsURL;
- addGroup( "Scolling" );
-
- addField( "willFirstRespond", TypeBool, Offset(mWillFirstRespond, GuiScrollCtrl));
- addField( "hScrollBar", TYPEID< ScrollBarBehavior >(), Offset(mForceHScrollBar, GuiScrollCtrl),
- "When to display the horizontal scrollbar.");
- addField( "vScrollBar", TYPEID< ScrollBarBehavior >(), Offset(mForceVScrollBar, GuiScrollCtrl),
- "When to display the vertical scrollbar.");
- addField( "lockHorizScroll", TypeBool, Offset(mLockHorizScroll, GuiScrollCtrl),
- "Horizontal scrolling not allowed if set.");
- addField( "lockVertScroll", TypeBool, Offset(mLockVertScroll, GuiScrollCtrl),
- "Vertical scrolling not allowed if set.");
- addField( "constantThumbHeight", TypeBool, Offset(mUseConstantHeightThumb, GuiScrollCtrl));
- addField( "childMargin", TypePoint2I, Offset(mChildMargin, GuiScrollCtrl),
- "Padding region to put around child contents." );
- addField( "mouseWheelScrollSpeed", TypeS32, Offset(mScrollAnimSpeed, GuiScrollCtrl),
- "Pixels/Tick - if not positive then mousewheel scrolling occurs instantly (like other scrolling).");
-
- endGroup( "Scrolling" );
- Parent::initPersistFields();
- }
- //-----------------------------------------------------------------------------
- bool GuiScrollCtrl::resize(const Point2I &newPos, const Point2I &newExt)
- {
- if( !Parent::resize(newPos, newExt) )
- return false;
- computeSizes();
- return true;
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::childResized(GuiControl *child)
- {
- if ( mIgnoreChildResized )
- return;
- Parent::childResized(child);
- computeSizes();
- }
- //-----------------------------------------------------------------------------
- bool GuiScrollCtrl::onWake()
- {
- if (! Parent::onWake())
- return false;
- mTextureObject = mProfile->getBitmapResource();
- if (mTextureObject && (mProfile->constructBitmapArray() >= BmpStates * BmpCount))
- {
- mBitmapBounds = mProfile->mBitmapArrayRects.address();
- //init
- mBaseThumbSize = mBitmapBounds[BmpStates * BmpVThumbTopCap].extent.y +
- mBitmapBounds[BmpStates * BmpVThumbBottomCap].extent.y;
- mScrollBarThickness = mBitmapBounds[BmpStates * BmpVPage].extent.x;
- mScrollBarArrowBtnLength = mBitmapBounds[BmpStates * BmpUp].extent.y;
- computeSizes();
- }
- else
- {
- Con::warnf("No texture loaded for scroll control named %s with profile %s", getName(), mProfile->getName());
- }
-
- return true;
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::onSleep()
- {
- // Reset the mouse tracking state of this control
- // when it is put to sleep
- mStateDepressed = false;
- mHitRegion = None;
- Parent::onSleep();
- mTextureObject = NULL;
- }
- //-----------------------------------------------------------------------------
- bool GuiScrollCtrl::calcChildExtents()
- {
- // scroll control should deal well with multiple gui controls
- if( !size() )
- return false;
- // Find size and relative position of the client rectangle.
-
- Point2I maxPos( TypeTraits< S32 >::MIN, TypeTraits< S32 >::MIN );
- Point2I minPos( TypeTraits< S32 >::MAX, TypeTraits< S32 >::MAX );
-
- bool haveVisibleChild = false;
- for( U32 i = 0; i < size(); i++ )
- {
- GuiControl *ctrl = (GuiControl*)at(i);
- if( ctrl->isVisible() )
- {
- haveVisibleChild = true;
-
- minPos.x = getMin( ctrl->getPosition().x, minPos.x );
- minPos.y = getMin( ctrl->getPosition().y, minPos.y );
- // This is +1 but the remaining code here all works with extents +1.
- Point2I ctrlMax = ctrl->getPosition() + ctrl->getExtent();
-
- maxPos.x = getMax( ctrlMax.x, maxPos.x );
- maxPos.y = getMax( ctrlMax.y, maxPos.y );
- }
- }
-
- if( !haveVisibleChild )
- return false;
-
- mChildPos = minPos;
- mChildExt = maxPos - minPos;
- return true;
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::scrollRectVisible(RectI rect)
- {
- // rect is passed in virtual client space
- if(rect.extent.x > mContentExt.x)
- rect.extent.x = mContentExt.x;
- if(rect.extent.y > mContentExt.y)
- rect.extent.y = mContentExt.y;
- // Determine the points bounding the requested rectangle
- Point2I rectUpperLeft = rect.point;
- Point2I rectLowerRight = rect.point + rect.extent;
- // Determine the points bounding the actual visible area...
- Point2I visUpperLeft = mChildRelPos;
- Point2I visLowerRight = mChildRelPos + mContentExt;
- Point2I delta(0,0);
- // We basically try to make sure that first the top left of the given
- // rect is visible, and if it is, then that the bottom right is visible.
- // Make sure the rectangle is visible along the X axis...
- if(rectUpperLeft.x < visUpperLeft.x)
- delta.x = rectUpperLeft.x - visUpperLeft.x;
- else if(rectLowerRight.x > visLowerRight.x)
- delta.x = rectLowerRight.x - visLowerRight.x;
- // Make sure the rectangle is visible along the Y axis...
- if(rectUpperLeft.y < visUpperLeft.y)
- delta.y = rectUpperLeft.y - visUpperLeft.y;
- else if(rectLowerRight.y > visLowerRight.y)
- delta.y = rectLowerRight.y - visLowerRight.y;
- // If we had any changes, scroll, otherwise don't.
- if(delta.x || delta.y)
- scrollDelta(delta.x, delta.y);
- }
- //-----------------------------------------------------------------------------
- bool GuiScrollCtrl::isPointVisible( const Point2I& point )
- {
- return ( point.x >= mChildRelPos.x && point.x <= ( mChildRelPos.x + mContentExt.x ) )
- && ( point.y >= mChildRelPos.y && point.y <= ( mChildRelPos.y + mContentExt.y ) );
- }
- //-----------------------------------------------------------------------------
- bool GuiScrollCtrl::isRectCompletelyVisible(const RectI& rect)
- {
- // rect is passed in virtual client space
- // Determine the points bounding the requested rectangle
- Point2I rectUpperLeft = rect.point;
- Point2I rectLowerRight = rect.point + rect.extent;
- // Determine the points bounding the actual visible area...
- Point2I visUpperLeft = mChildRelPos;
- Point2I visLowerRight = mChildRelPos + mContentExt;
- // Make sure the rectangle is visible along the X axis...
- if(rectUpperLeft.x < visUpperLeft.x)
- return false;
- else if(rectLowerRight.x > visLowerRight.x)
- return false;
- // Make sure the rectangle is visible along the Y axis...
- if(rectUpperLeft.y < visUpperLeft.y)
- return false;
- else if(rectLowerRight.y > visLowerRight.y)
- return false;
- return true;
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::addObject(SimObject *object)
- {
- Parent::addObject(object);
- computeSizes();
- }
- //-----------------------------------------------------------------------------
- GuiControl* GuiScrollCtrl::findHitControl(const Point2I &pt, S32 initialLayer)
- {
- if(pt.x < mProfile->mBorderThickness || pt.y < mProfile->mBorderThickness)
- return this;
- if(pt.x >= getWidth() - mProfile->mBorderThickness - (mHasVScrollBar ? mScrollBarThickness : 0) ||
- pt.y >= getHeight() - mProfile->mBorderThickness - (mHasHScrollBar ? mScrollBarThickness : 0))
- return this;
- return Parent::findHitControl(pt, initialLayer);
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::computeSizes()
- {
- S32 thickness = (mProfile ? mProfile->mBorderThickness : 1);
- Point2I borderExtent(thickness, thickness);
- mContentPos = borderExtent + mChildMargin;
- mContentExt = getExtent() - (mChildMargin * 2)
- - (borderExtent * 2);
- Point2I childLowerRight;
- mHBarEnabled = false;
- mVBarEnabled = false;
- mHasVScrollBar = (mForceVScrollBar == ScrollBarAlwaysOn);
- mHasHScrollBar = (mForceHScrollBar == ScrollBarAlwaysOn);
- setUpdate();
- if (calcChildExtents())
- {
- childLowerRight = mChildPos + mChildExt;
- if (mHasVScrollBar)
- mContentExt.x -= mScrollBarThickness;
- if (mHasHScrollBar)
- mContentExt.y -= mScrollBarThickness;
- if (mChildExt.x > mContentExt.x && (mForceHScrollBar == ScrollBarDynamic))
- {
- mHasHScrollBar = true;
- mContentExt.y -= mScrollBarThickness;
- }
- if (mChildExt.y > mContentExt.y && (mForceVScrollBar == ScrollBarDynamic))
- {
- mHasVScrollBar = true;
- mContentExt.x -= mScrollBarThickness;
- // If Extent X Changed, check Horiz Scrollbar.
- if (mChildExt.x > mContentExt.x && !mHasHScrollBar && (mForceHScrollBar == ScrollBarDynamic))
- {
- mHasHScrollBar = true;
- mContentExt.y -= mScrollBarThickness;
- }
- }
- Point2I contentLowerRight = mContentPos + mContentExt;
- // see if the child controls need to be repositioned (null space in control)
- Point2I delta(0,0);
- if (mChildPos.x > mContentPos.x)
- delta.x = mContentPos.x - mChildPos.x;
- else if (contentLowerRight.x > childLowerRight.x)
- {
- S32 diff = contentLowerRight.x - childLowerRight.x;
- delta.x = getMin(mContentPos.x - mChildPos.x, diff);
- }
- //reposition the children if the child extent > the scroll content extent
- if (mChildPos.y > mContentPos.y)
- delta.y = mContentPos.y - mChildPos.y;
- else if (contentLowerRight.y > childLowerRight.y)
- {
- S32 diff = contentLowerRight.y - childLowerRight.y;
- delta.y = getMin(mContentPos.y - mChildPos.y, diff);
- }
- // apply the deltas to the children...
- if (delta.x || delta.y)
- {
- SimGroup::iterator i;
- for(i = begin(); i != end();i++)
- {
- GuiControl *ctrl = (GuiControl *) (*i);
- ctrl->setPosition( ctrl->getPosition() + delta );
- }
- mChildPos += delta;
- childLowerRight += delta;
- }
- // enable needed scroll bars
- if (mChildExt.x > mContentExt.x)
- mHBarEnabled = true;
- if (mChildExt.y > mContentExt.y)
- mVBarEnabled = true;
- mChildRelPos = mContentPos - mChildPos;
- }
- // Prevent resizing our children from recalling this function!
- mIgnoreChildResized = true;
- if ( mLockVertScroll )
- {
- // If vertical scroll is locked we size our child's height to our own
- SimGroup::iterator i;
- for(i = begin(); i != end();i++)
- {
- GuiControl *ctrl = (GuiControl *) (*i);
- ctrl->setHeight( mContentExt.y );
- }
- }
- if ( mLockHorizScroll )
- {
- // If horizontal scroll is locked we size our child's width to our own
- SimGroup::iterator i;
- for(i = begin(); i != end();i++)
- {
- GuiControl *ctrl = (GuiControl *) (*i);
- ctrl->setWidth( mContentExt.x );
- }
- }
- mIgnoreChildResized = false;
- // build all the rectangles and such...
- calcScrollRects();
- calcThumbs();
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::calcScrollRects(void)
- {
- S32 thickness = ( mProfile ? mProfile->mBorderThickness : 1 );
- if (mHasHScrollBar)
- {
- mLeftArrowRect.set(thickness,
- getHeight() - thickness - mScrollBarThickness,
- mScrollBarArrowBtnLength,
- mScrollBarThickness);
- mRightArrowRect.set(getWidth() - thickness - (mHasVScrollBar ? mScrollBarThickness - 1 : 0) - mScrollBarArrowBtnLength,
- getHeight() - thickness - mScrollBarThickness,
- mScrollBarArrowBtnLength,
- mScrollBarThickness);
- mHTrackRect.set(mLeftArrowRect.point.x + mLeftArrowRect.extent.x,
- mLeftArrowRect.point.y,
- mRightArrowRect.point.x - (mLeftArrowRect.point.x + mLeftArrowRect.extent.x),
- mScrollBarThickness);
- }
- if (mHasVScrollBar)
- {
- mUpArrowRect.set(getWidth() - thickness - mScrollBarThickness,
- thickness,
- mScrollBarThickness,
- mScrollBarArrowBtnLength);
- mDownArrowRect.set(getWidth() - thickness - mScrollBarThickness,
- getHeight() - thickness - (mHasHScrollBar ? mScrollBarThickness - 1 : 0) - mScrollBarArrowBtnLength,
- mScrollBarThickness,
- mScrollBarArrowBtnLength);
- mVTrackRect.set(mUpArrowRect.point.x,
- mUpArrowRect.point.y + mUpArrowRect.extent.y,
- mScrollBarThickness,
- mDownArrowRect.point.y - (mUpArrowRect.point.y + mUpArrowRect.extent.y) );
- }
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::calcThumbs()
- {
- if (mHBarEnabled && mChildExt.x > 0)
- {
- U32 trackSize = mHTrackRect.len_x();
- if (mUseConstantHeightThumb)
- mHThumbSize = mBaseThumbSize;
- else
- mHThumbSize = getMax(mBaseThumbSize, ( S32 )mCeil( ( F32 )( mContentExt.x * trackSize) / ( F32 )mChildExt.x ) );
- mHThumbPos = mHTrackRect.point.x + (mChildRelPos.x * (trackSize - mHThumbSize)) / (mChildExt.x - mContentExt.x);
- }
- if (mVBarEnabled && mChildExt.y > 0)
- {
- U32 trackSize = mVTrackRect.len_y();
- if (mUseConstantHeightThumb)
- mVThumbSize = mBaseThumbSize;
- else
- mVThumbSize = getMax(mBaseThumbSize, ( S32 )mCeil( ( F32 )( mContentExt.y * trackSize ) / ( F32 )mChildExt.y ) );
- mVThumbPos = mVTrackRect.point.y + (mChildRelPos.y * (trackSize - mVThumbSize)) / (mChildExt.y - mContentExt.y);
- }
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::scrollDelta(S32 deltaX, S32 deltaY)
- {
- scrollTo(mChildRelPos.x + deltaX, mChildRelPos.y + deltaY);
- onScroll_callback();
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::scrollDeltaAnimate(S32 x, S32 y)
- {
- if ( !size() )
- return;
- if ( mAnimating )
- mScrollTargetPos += Point2I( x, y );
- else
- mScrollTargetPos = mChildRelPos + Point2I( x, y );
- setUpdate();
- mScrollTargetPos.setMin( mChildExt - mContentExt );
- mScrollTargetPos.setMax( Point2I::Zero );
-
- mAnimating = true;
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::scrollTo(S32 x, S32 y)
- {
- if( !size() )
- return;
- if ( x == mChildRelPos.x && y == mChildRelPos.y )
- return;
- setUpdate();
- if (x > mChildExt.x - mContentExt.x)
- x = mChildExt.x - mContentExt.x;
- if (x < 0)
- x = 0;
- if (y > mChildExt.y - mContentExt.y)
- y = mChildExt.y - mContentExt.y;
- if (y < 0)
- y = 0;
- Point2I delta(x - mChildRelPos.x, y - mChildRelPos.y);
- mChildRelPos += delta;
- mChildPos -= delta;
- for(SimSet::iterator i = begin(); i != end();i++)
- {
- GuiControl *ctrl = (GuiControl *) (*i);
- ctrl->setPosition( ctrl->getPosition() - delta );
- }
- calcThumbs();
- onScroll_callback();
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::scrollToObject(GuiControl *targetControl)
- {
- bool isValidChild = false;
- Point2I relativePosition = targetControl->getPosition();
- GuiControl* parentControl = targetControl->getParent();
- while (parentControl)
- {
- GuiScrollCtrl* scrollControl = dynamic_cast<GuiScrollCtrl*>(parentControl);
- if (scrollControl == this)
- {
- relativePosition += scrollControl->getChildRelPos();
- isValidChild = true;
- break;
- }
- relativePosition += parentControl->getPosition();
- parentControl = parentControl->getParent();
- }
- if (isValidChild)
- {
- scrollRectVisible(RectI(relativePosition, targetControl->getExtent()));
- }
- else
- {
- Con::errorf("GuiScrollCtrl::scrollToObject() - Specified object is not a child of this scroll control (%d)!", targetControl->getId());
- }
- }
- //-----------------------------------------------------------------------------
- GuiScrollCtrl::Region GuiScrollCtrl::findHitRegion(const Point2I &pt)
- {
- if (mVBarEnabled && mHasVScrollBar)
- {
- if (mUpArrowRect.pointInRect(pt))
- return UpArrow;
- else if (mDownArrowRect.pointInRect(pt))
- return DownArrow;
- else if (mVTrackRect.pointInRect(pt))
- {
- if (pt.y < mVThumbPos)
- return UpPage;
- else if (pt.y < mVThumbPos + mVThumbSize)
- return VertThumb;
- else
- return DownPage;
- }
- }
- if (mHBarEnabled && mHasHScrollBar)
- {
- if (mLeftArrowRect.pointInRect(pt))
- return LeftArrow;
- else if (mRightArrowRect.pointInRect(pt))
- return RightArrow;
- else if (mHTrackRect.pointInRect(pt))
- {
- if (pt.x < mHThumbPos)
- return LeftPage;
- else if (pt.x < mHThumbPos + mHThumbSize)
- return HorizThumb;
- else
- return RightPage;
- }
- }
- return None;
- }
- //-----------------------------------------------------------------------------
- bool GuiScrollCtrl::wantsTabListMembership()
- {
- return true;
- }
- //-----------------------------------------------------------------------------
- bool GuiScrollCtrl::loseFirstResponder()
- {
- setUpdate();
- return true;
- }
- //-----------------------------------------------------------------------------
- bool GuiScrollCtrl::becomeFirstResponder()
- {
- setUpdate();
- return mWillFirstRespond;
- }
- //-----------------------------------------------------------------------------
- bool GuiScrollCtrl::onKeyDown(const GuiEvent &event)
- {
- if (mWillFirstRespond)
- {
- switch (event.keyCode)
- {
- case KEY_RIGHT:
- scrollByRegion(RightArrow);
- return true;
- case KEY_LEFT:
- scrollByRegion(LeftArrow);
- return true;
- case KEY_DOWN:
- scrollByRegion(DownArrow);
- return true;
- case KEY_UP:
- scrollByRegion(UpArrow);
- return true;
- case KEY_PAGE_UP:
- scrollByRegion(UpPage);
- return true;
- case KEY_PAGE_DOWN:
- scrollByRegion(DownPage);
- return true;
-
- default:
- break;
- }
- }
- return Parent::onKeyDown(event);
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::_onMouseDown( const GuiEvent &event, bool lockMouse )
- {
- if( lockMouse )
- {
- mouseLock();
- mStateDepressed = true;
- }
- setUpdate();
- Point2I curMousePos = globalToLocalCoord(event.mousePoint);
- mHitRegion = findHitRegion(curMousePos);
- // Set a 0.5 second delay before we start scrolling
- mLastUpdated = Platform::getVirtualMilliseconds() + 500;
- scrollByRegion(mHitRegion);
- if (mHitRegion == VertThumb)
- {
- mChildRelPosAnchor = mChildRelPos;
- mThumbMouseDelta = curMousePos.y - mVThumbPos;
- }
- else if (mHitRegion == HorizThumb)
- {
- mChildRelPosAnchor = mChildRelPos;
- mThumbMouseDelta = curMousePos.x - mHThumbPos;
- }
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::onMouseDown(const GuiEvent &event)
- {
- _onMouseDown( event, true );
- }
- //-----------------------------------------------------------------------------
- bool GuiScrollCtrl::onMouseDownEditor( const GuiEvent& event, Point2I offset )
- {
- // If ALT is pressed while clicking on a horizontal or vertical scrollbar,
- // do a scroll.
-
- if( event.modifier & SI_PRIMARY_ALT )
- {
- Region hitRegion = findHitRegion( globalToLocalCoord( event.mousePoint ) );
- if( hitRegion != None )
- {
- _onMouseDown( event, false );
- return true;
- }
- }
-
- return false;
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::onMouseUp(const GuiEvent &)
- {
- mouseUnlock();
- setUpdate();
- mHitRegion = None;
- mStateDepressed = false;
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::onMouseDragged(const GuiEvent &event)
- {
- Point2I curMousePos = globalToLocalCoord(event.mousePoint);
- setUpdate();
- if ( (mHitRegion != VertThumb) && (mHitRegion != HorizThumb) )
- {
- Region hit = findHitRegion(curMousePos);
- if (hit != mHitRegion)
- mStateDepressed = false;
- else
- mStateDepressed = true;
- return;
- }
- // ok... if the mouse is 'near' the scroll bar, scroll with it
- // otherwise, snap back to the previous position.
- if (mHitRegion == 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 - mVTrackRect.point.y) *
- (mChildExt.y - mContentExt.y) /
- (mVTrackRect.extent.y - mVThumbSize);
- scrollTo(mChildRelPosAnchor.x, newVPos);
- }
- }
- else
- scrollTo(mChildRelPosAnchor.x, mChildRelPosAnchor.y);
- }
- else if (mHitRegion == 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 - mHTrackRect.point.x) *
- (mChildExt.x - mContentExt.x) /
- (mHTrackRect.extent.x - mHThumbSize);
- scrollTo(newHPos, mChildRelPosAnchor.y);
- }
- }
- else
- scrollTo(mChildRelPosAnchor.x, mChildRelPosAnchor.y);
- }
- }
- //-----------------------------------------------------------------------------
- bool GuiScrollCtrl::onMouseWheelUp(const GuiEvent &event)
- {
- if ( !mAwake || !mVisible )
- return false;
- scrollByMouseWheel( event );
- return true;
- }
- //-----------------------------------------------------------------------------
- bool GuiScrollCtrl::onMouseWheelDown(const GuiEvent &event)
- {
- if ( !mAwake || !mVisible )
- return false;
- scrollByMouseWheel( event );
- return true;
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::updateChildMousePos()
- {
- // We pass a fake GuiEvent to child controls onMouseMove
- // since although the mouse has not moved 'they' have.
- //
- // Its possible this could cause problems if a GuiControl
- // responds to more than just the mouse position in the onMouseMove
- // event, like for example doing something different depending on
- // a modifier key, which we aren't filling in to the structure!
- GuiEvent event;
- event.mousePoint = getRoot()->getCursorPos();
- iterator itr;
- for ( itr = begin(); itr != end(); itr++ )
- {
- GuiControl *child = static_cast<GuiControl*>( *itr );
- child->onMouseMove( event );
- }
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::onPreRender()
- {
- Parent::onPreRender();
- S32 currentTime = Platform::getVirtualMilliseconds();
- S32 deltaMs = currentTime - mLastPreRender;
- mLastPreRender = currentTime;
- // Update mouse-wheel scroll animation if we are currently doing one...
- if ( mAnimating )
- {
- //U32 frames = Con::getIntVariable( "$frames", 0 );
- //frames++;
- //Con::setIntVariable( "$frames", frames );
- F32 deltaTicks = deltaMs / 32.0f;
- if ( mScrollAnimSpeed <= 0 )
- {
- scrollTo( mScrollTargetPos.x, mScrollTargetPos.y );
- }
- else
- {
- S32 maxPixels = deltaTicks * mScrollAnimSpeed;
- Point2I toTarget = mScrollTargetPos - mChildRelPos;
- S32 signx = toTarget.x > 0 ? 1 : -1;
- S32 signy = toTarget.y > 0 ? 1 : -1;
- S32 deltaX = getMin( mAbs(toTarget.x), maxPixels ) * signx;
- S32 deltaY = getMin( mAbs(toTarget.y), maxPixels ) * signy;
- scrollDelta( deltaX, deltaY );
- }
- if ( mChildRelPos == mScrollTargetPos )
- {
- //Con::printf( "Animated Frames : %d", frames );
- //Con::setIntVariable( "$frames", 0 );
- mAnimating = false;
- }
- updateChildMousePos();
- }
- // Now scroll in response to a 'depressed state' if appropriate...
- // Short circuit if not depressed to save cycles
- if( mStateDepressed != true )
- return;
-
- //default to one second, though it shouldn't be necessary
- U32 timeThreshold = 1000;
- // We don't want to scroll by pages at an interval the same as when we're scrolling
- // using the arrow buttons, so adjust accordingly.
- switch( mHitRegion )
- {
- case UpPage:
- case DownPage:
- case LeftPage:
- case RightPage:
- timeThreshold = 200;
- break;
- case UpArrow:
- case DownArrow:
- case LeftArrow:
- case RightArrow:
- timeThreshold = 20;
- break;
- default:
- // Neither a button or a page, don't scroll (shouldn't get here)
- return;
- break;
- };
- S32 timeElapsed = Platform::getVirtualMilliseconds() - mLastUpdated;
- if ( ( timeElapsed > 0 ) && ( timeElapsed > timeThreshold ) )
- {
- mLastUpdated = Platform::getVirtualMilliseconds();
- scrollByRegion(mHitRegion);
- }
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::scrollByRegion(Region reg)
- {
- setUpdate();
- if(!size())
- return;
- GuiControl *content = (GuiControl *) front();
- U32 rowHeight, columnWidth;
- U32 pageHeight, pageWidth;
- content->getScrollLineSizes(&rowHeight, &columnWidth);
- if(rowHeight >= mContentExt.y)
- pageHeight = 1;
- else
- pageHeight = mContentExt.y - rowHeight;
- if(columnWidth >= mContentExt.x)
- pageWidth = 1;
- else
- pageWidth = mContentExt.x - columnWidth;
- 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;
- default:
- 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;
- default:
- break;
- }
- }
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::scrollByMouseWheel( const GuiEvent &event )
- {
- setUpdate();
- if ( !size() )
- return;
- if( event.mouseAxis == 1 )
- scrollDeltaAnimate( 0, -event.fval );
- else
- scrollDeltaAnimate( -event.fval, 0 );
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::onRender(Point2I offset, const RectI &updateRect)
- {
- // draw content controls
- // create a rect to intersect with the updateRect
- RectI contentRect(mContentPos.x + offset.x, mContentPos.y + offset.y, mContentExt.x, mContentExt.y);
- contentRect.intersect(updateRect);
-
- // Always call parent
- Parent::onRender(offset, contentRect);
-
- if( mTextureObject )
- {
- // Reset the ClipRect as the parent call can modify it when rendering
- // the child controls
- GFX->setClipRect( updateRect );
- //draw the scroll corner
- if (mHasVScrollBar && mHasHScrollBar)
- drawScrollCorner(offset);
- // draw scroll bars
- if (mHasVScrollBar)
- drawVScrollBar(offset);
- if (mHasHScrollBar)
- drawHScrollBar(offset);
- }
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::drawBorder( const Point2I &offset, bool /*isFirstResponder*/ )
- {
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::drawVScrollBar(const Point2I &offset)
- {
- if ( mTextureObject.isNull() )
- {
- return;
- }
- // Start Point.
- Point2I pos = ( offset + mUpArrowRect.point );
- // Up Arrow.
- S32 upArrowBitmap = ( BmpStates * BmpUp );
- if ( !mVBarEnabled )
- {
- upArrowBitmap += BmpDisabled;
- }
- else if ( mHitRegion == UpArrow && mStateDepressed )
- {
- upArrowBitmap += BmpHilite;
- }
- // Render Up Arrow.
- GFXDrawUtil* drawUtil = GFX->getDrawUtil();
- drawUtil->clearBitmapModulation();
- drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[upArrowBitmap]);
- // Update Pos.
- pos.y += mBitmapBounds[upArrowBitmap].extent.y;
- // Track.
- S32 trackBitmap = ( BmpStates * BmpVPage );
- if ( !mVBarEnabled )
- {
- trackBitmap += BmpDisabled;
- }
- else if ( mHitRegion == DownPage && mStateDepressed )
- {
- trackBitmap += BmpHilite;
- }
- // Determine the Track Rect.
- RectI trackRect;
- trackRect.point = pos;
- trackRect.extent.x = mBitmapBounds[trackBitmap].extent.x;
- trackRect.extent.y = ( offset.y + mDownArrowRect.point.y ) - pos.y;
- // Render Track?
- if ( trackRect.extent.y > 0 )
- {
- // Render Track.
- drawUtil->clearBitmapModulation();
- drawUtil->drawBitmapStretchSR(mTextureObject, trackRect, mBitmapBounds[trackBitmap]);
- }
- // Update Pos.
- pos.y += trackRect.extent.y;
- // Down Arrow.
- S32 downArrowBitmap = ( BmpStates * BmpDown );
- if ( !mVBarEnabled )
- {
- downArrowBitmap += BmpDisabled;
- }
- else if ( mHitRegion == DownArrow && mStateDepressed )
- {
- downArrowBitmap += BmpHilite;
- }
- // Render Down Arrow.
- drawUtil->clearBitmapModulation();
- drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[downArrowBitmap]);
- // Render the Thumb?
- if ( !mVBarEnabled )
- {
- // Nope.
- return;
- }
- // Reset the Pos.
- pos.y = ( offset.y + mVThumbPos );
- // Determine the Bitmaps.
- S32 thumbBitmapTop = ( BmpStates * BmpVThumbTopCap );
- S32 thumbBitmapMiddle = ( BmpStates * BmpVThumb );
- S32 thumbBitmapBottom = ( BmpStates * BmpVThumbBottomCap );
- if ( mHitRegion == VertThumb && mStateDepressed )
- {
- thumbBitmapTop += BmpHilite;
- thumbBitmapMiddle += BmpHilite;
- thumbBitmapBottom += BmpHilite;
- }
- // Render Thumb Top.
- drawUtil->clearBitmapModulation();
- drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[thumbBitmapTop]);
- // Update Pos.
- pos.y += mBitmapBounds[thumbBitmapTop].extent.y;
- // Determine the Thumb Rect.
- RectI thumbRect;
- thumbRect.point = pos;
- thumbRect.extent.x = mBitmapBounds[thumbBitmapMiddle].extent.x;
- thumbRect.extent.y = mVThumbSize - ( mBitmapBounds[thumbBitmapTop].extent.y + mBitmapBounds[thumbBitmapBottom].extent.y );
- // Render Thumb?
- if ( thumbRect.extent.y > 0 )
- {
- // Render Track.
- drawUtil->clearBitmapModulation();
- drawUtil->drawBitmapStretchSR(mTextureObject, thumbRect, mBitmapBounds[thumbBitmapMiddle]);
- }
- // Update Pos.
- pos.y += thumbRect.extent.y;
- // Render the Thumb Bottom.
- drawUtil->clearBitmapModulation();
- drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[thumbBitmapBottom]);
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::drawHScrollBar(const Point2I &offset)
- {
- if ( mTextureObject.isNull() )
- {
- return;
- }
- // Start Point.
- Point2I pos = ( offset + mLeftArrowRect.point );
- // Left Arrow.
- S32 leftArrowBitmap = ( BmpStates * BmpLeft );
- if ( !mHBarEnabled )
- {
- leftArrowBitmap += BmpDisabled;
- }
- else if ( mHitRegion == LeftArrow && mStateDepressed )
- {
- leftArrowBitmap += BmpHilite;
- }
- // Render Up Arrow.
- GFXDrawUtil* drawUtil = GFX->getDrawUtil();
- drawUtil->clearBitmapModulation();
- drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[leftArrowBitmap]);
- // Update Pos.
- pos.x += mBitmapBounds[leftArrowBitmap].extent.x;
- // Track.
- S32 trackBitmap = ( BmpStates * BmpHPage );
- if ( !mHBarEnabled )
- {
- trackBitmap += BmpDisabled;
- }
- else if ( mHitRegion == LeftPage && mStateDepressed )
- {
- trackBitmap += BmpHilite;
- }
- // Determine the Track Rect.
- RectI trackRect;
- trackRect.point = pos;
- trackRect.extent.x = ( offset.x + mRightArrowRect.point.x ) - pos.x;
- trackRect.extent.y = mBitmapBounds[trackBitmap].extent.y;
- // Render Track?
- if ( trackRect.extent.x > 0 )
- {
- // Render Track.
- drawUtil->clearBitmapModulation();
- drawUtil->drawBitmapStretchSR(mTextureObject, trackRect, mBitmapBounds[trackBitmap]);
- }
- // Update Pos.
- pos.x += trackRect.extent.x;
- // Right Arrow.
- S32 rightArrowBitmap = ( BmpStates * BmpRight );
- if ( !mHBarEnabled )
- {
- rightArrowBitmap += BmpDisabled;
- }
- else if ( mHitRegion == RightArrow && mStateDepressed )
- {
- rightArrowBitmap += BmpHilite;
- }
- // Render Right Arrow.
- drawUtil->clearBitmapModulation();
- drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[rightArrowBitmap]);
- // Render the Thumb?
- if ( !mHBarEnabled )
- {
- // Nope.
- return;
- }
- // Reset the Pos.
- pos.x = ( offset.x + mHThumbPos );
- // Determine the Bitmaps.
- S32 thumbBitmapLeft = ( BmpStates * BmpHThumbLeftCap );
- S32 thumbBitmapMiddle = ( BmpStates * BmpHThumb );
- S32 thumbBitmapRight = ( BmpStates * BmpHThumbRightCap );
- if ( mHitRegion == HorizThumb && mStateDepressed )
- {
- thumbBitmapLeft += BmpHilite;
- thumbBitmapMiddle += BmpHilite;
- thumbBitmapRight += BmpHilite;
- }
- // Render Thumb Left.
- drawUtil->clearBitmapModulation();
- drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[thumbBitmapLeft]);
- // Update Pos.
- pos.x += mBitmapBounds[thumbBitmapLeft].extent.x;
- // Determine the Thumb Rect.
- RectI thumbRect;
- thumbRect.point = pos;
- thumbRect.extent.x = mHThumbSize - ( mBitmapBounds[thumbBitmapLeft].extent.x + mBitmapBounds[thumbBitmapRight].extent.x );
- thumbRect.extent.y = mBitmapBounds[thumbBitmapMiddle].extent.y;
- // Render Thumb?
- if ( thumbRect.extent.x > 0 )
- {
- // Render Track.
- drawUtil->clearBitmapModulation();
- drawUtil->drawBitmapStretchSR(mTextureObject, thumbRect, mBitmapBounds[thumbBitmapMiddle]);
- }
- // Update Pos.
- pos.x += thumbRect.extent.x;
- // Render the Thumb Bottom.
- drawUtil->clearBitmapModulation();
- drawUtil->drawBitmapSR(mTextureObject, pos, mBitmapBounds[thumbBitmapRight]);
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::drawScrollCorner(const Point2I &offset)
- {
- Point2I pos = offset;
- pos.x += mRightArrowRect.point.x + mRightArrowRect.extent.x - 1;
- pos.y += mRightArrowRect.point.y;
- GFX->getDrawUtil()->clearBitmapModulation();
- GFX->getDrawUtil()->drawBitmapSR(mTextureObject, pos, mBitmapBounds[BmpStates * BmpResize]);
- }
- //-----------------------------------------------------------------------------
- void GuiScrollCtrl::autoScroll(Region reg)
- {
- scrollByRegion(reg);
- }
- //=============================================================================
- // API.
- //=============================================================================
- // MARK: ---- API ----
- //-----------------------------------------------------------------------------
- DefineEngineMethod( GuiScrollCtrl, scrollToTop, void, (),,
- "Scroll all the way to the top of the vertical and left of the horizontal scrollbar." )
- {
- object->scrollTo( 0, 0 );
- }
- //-----------------------------------------------------------------------------
- DefineEngineMethod( GuiScrollCtrl, scrollToBottom, void, (),,
- "Scroll all the way to the bottom of the vertical scrollbar and the left of the horizontal bar." )
- {
- object->scrollTo( 0, 0x7FFFFFFF );
- }
- //-----------------------------------------------------------------------------
- DefineEngineMethod( GuiScrollCtrl, setScrollPosition, void, ( S32 x, S32 y ),,
- "Set the position of the scrolled content.\n\n"
- "@param x Position on X axis.\n"
- "@param y Position on y axis.\n" )
- {
- object->scrollTo( x, y );
- }
- //-----------------------------------------------------------------------------
- DefineEngineMethod( GuiScrollCtrl, scrollToObject, void, ( GuiControl* control ),,
- "Scroll the control so that the given child @a control is visible.\n\n"
- "@param control A child control." )
- {
- if( control )
- object->scrollToObject( control );
- }
- //-----------------------------------------------------------------------------
- DefineEngineMethod( GuiScrollCtrl, getScrollPosition, Point2I, (),,
- "Get the current coordinates of the scrolled content.\n\n"
- "@return The current position of the scrolled content." )
- {
- return object->getChildRelPos();
- }
- //-----------------------------------------------------------------------------
- DefineEngineMethod( GuiScrollCtrl, getScrollPositionX, S32, (),,
- "Get the current X coordinate of the scrolled content.\n\n"
- "@return The current X coordinate of the scrolled content." )
- {
- return object->getChildRelPos().x;
- }
- //-----------------------------------------------------------------------------
- DefineEngineMethod( GuiScrollCtrl, getScrollPositionY, S32, (),,
- "Get the current Y coordinate of the scrolled content."
- "@return The current Y coordinate of the scrolled content." )
- {
- return object->getChildRelPos().y;
- }
- //-----------------------------------------------------------------------------
- DefineEngineMethod( GuiScrollCtrl, computeSizes, void, (),,
- "Refresh sizing and positioning of child controls." )
- {
- object->computeSizes();
- }
|