mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 04:34:48 +00:00
Takes the makeFullPath in findTSShapeConstructor and turn it into a string before passing it along to the Filename to make stricter compilers happy Removed some referenced to fields that don't exist in the current build Removed unneeded ASM language activation for the cmake files Adjustments to material map assembling macros to better comply to stricter compilers
361 lines
11 KiB
C++
361 lines
11 KiB
C++
//-----------------------------------------------------------------------------
|
|
// 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 "gui/containers/guiAutoScrollCtrl.h"
|
|
#include "console/consoleTypes.h"
|
|
#include "console/engineAPI.h"
|
|
|
|
|
|
IMPLEMENT_CONOBJECT( GuiAutoScrollCtrl );
|
|
|
|
ConsoleDocClass( GuiAutoScrollCtrl,
|
|
"@brief A container that scrolls its child control up over time.\n\n"
|
|
|
|
"This container can be used to scroll a single child control in either of the four directions.\n\n"
|
|
|
|
"@tsexample\n"
|
|
"// Create a GuiAutoScrollCtrl that scrolls a long text of credits.\n"
|
|
"new GuiAutoScrollCtrl( CreditsScroller )\n"
|
|
"{\n"
|
|
" position = \"0 0\";\n"
|
|
" extent = Canvas.extent.x SPC Canvas.extent.y;\n"
|
|
"\n"
|
|
" scrollDirection = \"Up\"; // Scroll upwards.\n"
|
|
" startDelay = 4; // Wait 4 seconds before starting to scroll.\n"
|
|
" isLooping = false; // Don't loop the credits.\n"
|
|
" scrollOutOfSight = true; // Scroll up fully.\n"
|
|
"\n"
|
|
" new GuiMLTextCtrl()\n"
|
|
" {\n"
|
|
" text = $CREDITS;\n"
|
|
" };\n"
|
|
"};\n"
|
|
"\n"
|
|
"function CreditsScroller::onComplete( %this )\n"
|
|
"{\n"
|
|
" // Switch back to main menu after credits have rolled.\n"
|
|
" Canvas.setContent( MainMenu );\n"
|
|
"}\n"
|
|
"\n"
|
|
"// Start rolling credits.\n"
|
|
"Canvas.setContent( CreditsScroller );\n"
|
|
"@endtsexample\n\n"
|
|
|
|
"@note Only the first child will be scrolled.\n\n"
|
|
|
|
"@ingroup GuiContainers"
|
|
);
|
|
|
|
|
|
IMPLEMENT_CALLBACK( GuiAutoScrollCtrl, onTick, void, (), (),
|
|
"Called every 32ms on the control." );
|
|
IMPLEMENT_CALLBACK( GuiAutoScrollCtrl, onStart, void, (), (),
|
|
"Called when the control starts to scroll." );
|
|
IMPLEMENT_CALLBACK( GuiAutoScrollCtrl, onComplete, void, (), (),
|
|
"Called when the child control has been scrolled in entirety." );
|
|
IMPLEMENT_CALLBACK( GuiAutoScrollCtrl, onReset, void, (), (),
|
|
"Called when the child control is reset to its initial position and the cycle starts again." );
|
|
|
|
|
|
ImplementEnumType( GuiAutoScrollDirection,
|
|
"Direction in which to scroll the child control.\n\n"
|
|
"@ingroup GuiContainers" )
|
|
{ GuiAutoScrollCtrl::Up, "Up", "Scroll from bottom towards top." },
|
|
{ GuiAutoScrollCtrl::Down, "Down", "Scroll from top towards bottom." },
|
|
{ GuiAutoScrollCtrl::Left, "Left", "Scroll from right towards left." },
|
|
{ GuiAutoScrollCtrl::Right, "Right", "Scroll from left towards right." },
|
|
EndImplementEnumType;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
GuiAutoScrollCtrl::GuiAutoScrollCtrl()
|
|
: mDirection( Up ),
|
|
mIsLooping( true ),
|
|
mCurrentPhase( GuiAutoScrollCtrl::PhaseComplete ),
|
|
mCurrentTime( 0.f ),
|
|
mCompleteTime(F32_MAX),
|
|
mCurrentPosition(0.0f),
|
|
mStartDelay( 3.f ),
|
|
mResetDelay( 5.f ),
|
|
mChildBorder( 10 ),
|
|
mScrollOutOfSight( false ),
|
|
mScrollSpeed( 1.f )
|
|
{
|
|
mIsContainer = true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void GuiAutoScrollCtrl::initPersistFields()
|
|
{
|
|
addGroup( "Scrolling" );
|
|
|
|
addField( "scrollDirection", TYPEID< Direction >(), Offset( mDirection, GuiAutoScrollCtrl ),
|
|
"Direction in which the child control is moved." );
|
|
addField( "startDelay", TypeF32, Offset( mStartDelay, GuiAutoScrollCtrl ),
|
|
"Seconds to wait before starting to scroll." );
|
|
addField( "resetDelay", TypeF32, Offset( mResetDelay, GuiAutoScrollCtrl ),
|
|
"Seconds to wait after scrolling completes before resetting and starting over.\n\n"
|
|
"@note Only takes effect if #isLooping is true." );
|
|
addField( "childBorder", TypeS32, Offset( mChildBorder, GuiAutoScrollCtrl ),
|
|
"Padding to put around child control (in pixels)." );
|
|
addField( "scrollSpeed", TypeF32, Offset( mScrollSpeed, GuiAutoScrollCtrl ),
|
|
"Scrolling speed in pixels per second." );
|
|
addField( "isLooping", TypeBool, Offset( mIsLooping, GuiAutoScrollCtrl ),
|
|
"If true, the scrolling will reset to the beginning once completing a cycle." );
|
|
addField( "scrollOutOfSight", TypeBool, Offset( mScrollOutOfSight, GuiAutoScrollCtrl ),
|
|
"If true, the child control will be completely scrolled out of sight; otherwise it will only scroll "
|
|
"until the other end becomes visible." );
|
|
|
|
endGroup( "Scrolling" );
|
|
|
|
Parent::initPersistFields();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool GuiAutoScrollCtrl::onWake()
|
|
{
|
|
if( !Parent::onWake() )
|
|
return false;
|
|
|
|
setProcessTicks( true );
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void GuiAutoScrollCtrl::onSleep()
|
|
{
|
|
setProcessTicks( false );
|
|
Parent::onSleep();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void GuiAutoScrollCtrl::onChildAdded( GuiControl* control )
|
|
{
|
|
_reset( control );
|
|
Parent::onChildAdded( control );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void GuiAutoScrollCtrl::onChildRemoved( GuiControl* control )
|
|
{
|
|
mCurrentPhase = PhaseComplete;
|
|
Parent::onChildRemoved( control );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool GuiAutoScrollCtrl::_isScrollComplete() const
|
|
{
|
|
if( empty() )
|
|
return true;
|
|
|
|
GuiControl* control = static_cast< GuiControl* >( at( 0 ) );
|
|
U32 axis = _getScrollAxis();
|
|
F32 amount = _getScrollAmount();
|
|
|
|
if( mScrollOutOfSight )
|
|
{
|
|
// If scrolling out of sight, scrolling is complete when the control's rectangle
|
|
// does not intersect our own rectangle anymore.
|
|
|
|
RectI thisRect( Point2I( 0, 0 ), getExtent() );
|
|
return !( thisRect.overlaps( control->getBounds() ) );
|
|
}
|
|
else
|
|
{
|
|
if( amount < 0 )
|
|
return ( control->getPosition()[ axis ] + control->getExtent()[ axis ] ) < ( getExtent()[ axis ] - mChildBorder );
|
|
else
|
|
return ( control->getPosition()[ axis ] >= mChildBorder );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void GuiAutoScrollCtrl::_reset( GuiControl* control )
|
|
{
|
|
U32 axis = _getScrollAxis();
|
|
U32 counterAxis = ( axis == 1 ? 0 : 1 );
|
|
|
|
Point2I newPosition( mChildBorder, mChildBorder );
|
|
Point2I newExtent = control->getExtent();
|
|
|
|
// Fit control on axis that is not scrolled.
|
|
newExtent[ counterAxis ] = getExtent()[ counterAxis ] - mChildBorder * 2;
|
|
|
|
// For the right and down scrolls, position the control away from the
|
|
// right/bottom edge of our control.
|
|
|
|
if( mDirection == Right )
|
|
newPosition.x = - ( newExtent.x - getExtent().x + mChildBorder );
|
|
else if( mDirection == Down )
|
|
newPosition.y = - ( newExtent.y - getExtent().y + mChildBorder );
|
|
|
|
// Set the child geometry.
|
|
|
|
control->setPosition( newPosition );
|
|
control->setExtent( newExtent );
|
|
|
|
// Reset counters.
|
|
|
|
mCurrentTime = 0.0f;
|
|
mCurrentPhase = PhaseInitial;
|
|
mCurrentPosition = control->getPosition()[ axis ];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void GuiAutoScrollCtrl::reset()
|
|
{
|
|
if( !empty() )
|
|
_reset( static_cast< GuiControl* >( at( 0 ) ) );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool GuiAutoScrollCtrl::resize( const Point2I &newPosition, const Point2I &newExtent )
|
|
{
|
|
if( !Parent::resize( newPosition, newExtent ) )
|
|
return false;
|
|
|
|
for( iterator i = begin(); i != end(); ++ i )
|
|
{
|
|
GuiControl* control = static_cast< GuiControl* >( *i );
|
|
if( control )
|
|
_reset( control );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void GuiAutoScrollCtrl::childResized( GuiControl* child )
|
|
{
|
|
Parent::childResized( child );
|
|
_reset(child);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void GuiAutoScrollCtrl::processTick()
|
|
{
|
|
onTick_callback();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void GuiAutoScrollCtrl::advanceTime( F32 timeDelta )
|
|
{
|
|
if( mCurrentPhase == PhaseComplete )
|
|
return;
|
|
|
|
// Wait out initial delay.
|
|
|
|
if( ( mCurrentTime + timeDelta ) < mStartDelay)
|
|
{
|
|
mCurrentTime += timeDelta;
|
|
return;
|
|
}
|
|
|
|
// Start scrolling if we haven't already.
|
|
|
|
if( mCurrentPhase == PhaseInitial )
|
|
{
|
|
onStart_callback();
|
|
mCurrentPhase = PhaseScrolling;
|
|
}
|
|
|
|
GuiControl* control = static_cast< GuiControl* >( at( 0 ) );
|
|
if( !control ) // Should not happen.
|
|
return;
|
|
|
|
// If not yet complete, scroll some more.
|
|
|
|
if( !_isScrollComplete() )
|
|
{
|
|
U32 axis = _getScrollAxis();
|
|
F32 amount = _getScrollAmount();
|
|
|
|
mCurrentPosition += amount * timeDelta;
|
|
Point2I newPosition = control->getPosition();
|
|
newPosition[ axis ] = mCurrentPosition;
|
|
|
|
control->setPosition( newPosition );
|
|
}
|
|
else
|
|
{
|
|
mCurrentTime += timeDelta;
|
|
|
|
if( mCurrentPhase != PhaseComplete && mCurrentPhase != PhaseWait )
|
|
{
|
|
if( mCurrentPhase != PhaseWait )
|
|
{
|
|
onComplete_callback();
|
|
mCurrentPhase = PhaseComplete;
|
|
}
|
|
|
|
mCompleteTime = mCurrentTime;
|
|
}
|
|
|
|
// Reset, if looping.
|
|
|
|
if( mIsLooping )
|
|
{
|
|
// Wait out reset time and restart.
|
|
|
|
mCurrentPhase = PhaseWait;
|
|
if( mCurrentTime > ( mCompleteTime + mResetDelay ) )
|
|
{
|
|
onReset_callback();
|
|
_reset( control );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void GuiAutoScrollCtrl::inspectPostApply()
|
|
{
|
|
Parent::inspectPostApply();
|
|
reset();
|
|
}
|
|
|
|
//=============================================================================
|
|
// API.
|
|
//=============================================================================
|
|
// MARK: ---- API ----
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
DefineEngineMethod( GuiAutoScrollCtrl, reset, void, (),,
|
|
"Reset scrolling." )
|
|
{
|
|
object->reset();
|
|
}
|