2013-07-03 01:01:58 +00:00
|
|
|
#include "ScrollableContainer.h"
|
|
|
|
#include "../Renderer.h"
|
|
|
|
#include "../Log.h"
|
|
|
|
|
2014-05-19 01:15:15 +00:00
|
|
|
#define AUTO_SCROLL_RESET_DELAY 10000 // ms to reset to top after we reach the bottom
|
|
|
|
#define AUTO_SCROLL_DELAY 8000 // ms to wait before we start to scroll
|
|
|
|
#define AUTO_SCROLL_SPEED 50 // ms between scrolls
|
|
|
|
|
2013-07-03 01:01:58 +00:00
|
|
|
ScrollableContainer::ScrollableContainer(Window* window) : GuiComponent(window),
|
2014-05-19 01:15:15 +00:00
|
|
|
mAutoScrollDelay(0), mAutoScrollSpeed(0), mAutoScrollAccumulator(0), mScrollPos(0, 0), mScrollDir(0, 0), mAutoScrollResetAccumulator(0)
|
2013-07-03 01:01:58 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-07-10 11:29:43 +00:00
|
|
|
void ScrollableContainer::render(const Eigen::Affine3f& parentTrans)
|
2013-07-03 01:01:58 +00:00
|
|
|
{
|
2013-07-10 11:29:43 +00:00
|
|
|
Eigen::Affine3f trans = parentTrans * getTransform();
|
2013-07-03 01:01:58 +00:00
|
|
|
|
2013-07-10 11:29:43 +00:00
|
|
|
Eigen::Vector2i clipPos((int)trans.translation().x(), (int)trans.translation().y());
|
2013-08-07 03:46:25 +00:00
|
|
|
|
|
|
|
Eigen::Vector3f dimScaled = trans * Eigen::Vector3f(mSize.x(), mSize.y(), 0);
|
|
|
|
Eigen::Vector2i clipDim((int)dimScaled.x() - trans.translation().x(), (int)dimScaled.y() - trans.translation().y());
|
2013-07-03 01:01:58 +00:00
|
|
|
|
2013-07-10 11:29:43 +00:00
|
|
|
Renderer::pushClipRect(clipPos, clipDim);
|
|
|
|
|
2014-05-19 01:15:15 +00:00
|
|
|
trans.translate(-Eigen::Vector3f(mScrollPos.x(), mScrollPos.y(), 0));
|
2013-07-10 11:29:43 +00:00
|
|
|
Renderer::setMatrix(trans);
|
2013-07-03 01:01:58 +00:00
|
|
|
|
2013-07-10 11:29:43 +00:00
|
|
|
GuiComponent::renderChildren(trans);
|
2013-07-03 01:01:58 +00:00
|
|
|
|
|
|
|
Renderer::popClipRect();
|
|
|
|
}
|
|
|
|
|
2014-05-19 01:15:15 +00:00
|
|
|
void ScrollableContainer::setAutoScroll(bool autoScroll)
|
2013-07-03 01:01:58 +00:00
|
|
|
{
|
2014-05-19 01:15:15 +00:00
|
|
|
if(autoScroll)
|
|
|
|
{
|
|
|
|
mScrollDir << 0, 1;
|
|
|
|
mAutoScrollDelay = AUTO_SCROLL_DELAY;
|
|
|
|
mAutoScrollSpeed = AUTO_SCROLL_SPEED;
|
|
|
|
reset();
|
|
|
|
}else{
|
|
|
|
mScrollDir << 0, 0;
|
|
|
|
mAutoScrollDelay = 0;
|
|
|
|
mAutoScrollSpeed = 0;
|
|
|
|
mAutoScrollAccumulator = 0;
|
|
|
|
}
|
2013-07-03 01:01:58 +00:00
|
|
|
}
|
|
|
|
|
2014-05-19 01:15:15 +00:00
|
|
|
Eigen::Vector2f ScrollableContainer::getScrollPos() const
|
2013-07-03 01:01:58 +00:00
|
|
|
{
|
|
|
|
return mScrollPos;
|
|
|
|
}
|
|
|
|
|
2014-05-19 01:15:15 +00:00
|
|
|
void ScrollableContainer::setScrollPos(const Eigen::Vector2f& pos)
|
2013-07-03 01:01:58 +00:00
|
|
|
{
|
|
|
|
mScrollPos = pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScrollableContainer::update(int deltaTime)
|
|
|
|
{
|
|
|
|
if(mAutoScrollSpeed != 0)
|
|
|
|
{
|
2014-05-19 01:15:15 +00:00
|
|
|
mAutoScrollAccumulator += deltaTime;
|
2013-07-03 01:01:58 +00:00
|
|
|
|
2014-05-19 01:15:15 +00:00
|
|
|
//scale speed by our width! more text per line = slower scrolling
|
|
|
|
const float widthMod = (680.0f / getSize().x());
|
|
|
|
while(mAutoScrollAccumulator >= mAutoScrollSpeed)
|
2013-07-03 01:01:58 +00:00
|
|
|
{
|
2014-05-19 01:15:15 +00:00
|
|
|
mScrollPos += mScrollDir;
|
|
|
|
mAutoScrollAccumulator -= mAutoScrollSpeed;
|
2013-07-03 01:01:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//clip scrolling within bounds
|
2013-07-10 11:29:43 +00:00
|
|
|
if(mScrollPos.x() < 0)
|
|
|
|
mScrollPos[0] = 0;
|
|
|
|
if(mScrollPos.y() < 0)
|
|
|
|
mScrollPos[1] = 0;
|
2013-07-03 01:01:58 +00:00
|
|
|
|
2014-05-19 01:15:15 +00:00
|
|
|
const Eigen::Vector2f contentSize = getContentSize();
|
2013-07-10 11:29:43 +00:00
|
|
|
if(mScrollPos.x() + getSize().x() > contentSize.x())
|
2014-05-19 01:15:15 +00:00
|
|
|
{
|
|
|
|
mScrollPos[0] = contentSize.x() - getSize().x();
|
|
|
|
mAtEnd = true;
|
|
|
|
}
|
2014-01-11 01:18:51 +00:00
|
|
|
|
|
|
|
if(contentSize.y() < getSize().y())
|
2014-05-19 01:15:15 +00:00
|
|
|
{
|
2014-01-11 01:18:51 +00:00
|
|
|
mScrollPos[1] = 0;
|
2014-05-19 01:15:15 +00:00
|
|
|
}else if(mScrollPos.y() + getSize().y() > contentSize.y())
|
|
|
|
{
|
|
|
|
mScrollPos[1] = contentSize.y() - getSize().y();
|
|
|
|
mAtEnd = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mAtEnd)
|
|
|
|
{
|
|
|
|
mAutoScrollResetAccumulator += deltaTime;
|
|
|
|
if(mAutoScrollResetAccumulator >= AUTO_SCROLL_RESET_DELAY)
|
|
|
|
reset();
|
|
|
|
}
|
2013-07-03 01:01:58 +00:00
|
|
|
|
|
|
|
GuiComponent::update(deltaTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
//this should probably return a box to allow for when controls don't start at 0,0
|
2013-07-10 11:29:43 +00:00
|
|
|
Eigen::Vector2f ScrollableContainer::getContentSize()
|
2013-07-03 01:01:58 +00:00
|
|
|
{
|
2013-07-10 11:29:43 +00:00
|
|
|
Eigen::Vector2f max(0, 0);
|
2013-07-03 01:01:58 +00:00
|
|
|
for(unsigned int i = 0; i < mChildren.size(); i++)
|
|
|
|
{
|
2013-07-10 11:29:43 +00:00
|
|
|
Eigen::Vector2f pos(mChildren.at(i)->getPosition()[0], mChildren.at(i)->getPosition()[1]);
|
|
|
|
Eigen::Vector2f bottomRight = mChildren.at(i)->getSize() + pos;
|
|
|
|
if(bottomRight.x() > max.x())
|
|
|
|
max.x() = bottomRight.x();
|
|
|
|
if(bottomRight.y() > max.y())
|
|
|
|
max.y() = bottomRight.y();
|
2013-07-03 01:01:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return max;
|
|
|
|
}
|
|
|
|
|
2014-05-19 01:15:15 +00:00
|
|
|
void ScrollableContainer::reset()
|
2013-07-03 01:01:58 +00:00
|
|
|
{
|
2014-05-19 01:15:15 +00:00
|
|
|
mScrollPos << 0, 0;
|
|
|
|
mAutoScrollResetAccumulator = 0;
|
|
|
|
mAutoScrollAccumulator = -mAutoScrollDelay + mAutoScrollSpeed;
|
|
|
|
mAtEnd = false;
|
2013-07-03 01:01:58 +00:00
|
|
|
}
|