Rewritten menu scrolling methodology.

This commit is contained in:
Pieter Hulshoff 2017-01-01 15:15:11 +01:00
parent c6c21ea0ff
commit 6f68195258
5 changed files with 137 additions and 185 deletions

View File

@ -56,9 +56,6 @@ ScrollingList::ScrollingList(Configuration &c,
, itemIndex_(0)
, componentIndex_(0)
, selectedOffsetIndex_(0)
, currentScrollDirection_(ScrollDirectionIdle)
, requestedScrollDirection_(ScrollDirectionIdle)
, currentScrollState_(ScrollStateIdle)
, scrollAcceleration_(0)
, startScrollTime_(0.500)
, scrollPeriod_(0)
@ -79,9 +76,6 @@ ScrollingList::ScrollingList(const ScrollingList &copy)
, itemIndex_(0)
, componentIndex_(0)
, selectedOffsetIndex_(copy.selectedOffsetIndex_)
, currentScrollDirection_(ScrollDirectionIdle)
, requestedScrollDirection_(ScrollDirectionIdle)
, currentScrollState_(ScrollStateIdle)
, scrollAcceleration_(copy.scrollAcceleration_)
, startScrollTime_(copy.startScrollTime_)
, scrollPeriod_(0)
@ -237,39 +231,6 @@ Item *ScrollingList::getSelectedItem()
}
void ScrollingList::click(double nextScrollTime)
{
if(currentScrollDirection_ == ScrollDirectionBack)
{
// get the previous item
itemIndex_ = loopDecrement(itemIndex_, 1, items_->size());
Item *i = items_->at(itemIndex_);
componentIndex_ = loopDecrement(componentIndex_, 1, components_.size());
deallocateTexture(componentIndex_);
allocateTexture(componentIndex_, i);
Component *c = components_.at(componentIndex_);
ViewInfo *v = scrollPoints_->at(0);
resetTweens(c, tweenPoints_->at(componentIndex_), v, v, 0);
}
else if(currentScrollDirection_ == ScrollDirectionForward)
{
unsigned int itemIncrement = loopIncrement(itemIndex_, scrollPoints_->size(), items_->size());
itemIndex_ = loopIncrement(itemIndex_, 1, items_->size());
Item *i = items_->at(itemIncrement);
deallocateTexture(componentIndex_);
allocateTexture(componentIndex_, i);
Component *c = components_.at(componentIndex_);
ViewInfo *v = scrollPoints_->back();
resetTweens(c, tweenPoints_->at(componentIndex_), v, v, 0);
componentIndex_ = loopIncrement(componentIndex_, 1, components_.size());
}
}
void ScrollingList::pageUp()
{
if(components_.size() == 0) return;
@ -345,9 +306,6 @@ void ScrollingList::letterChange(bool increment)
void ScrollingList::freeGraphicsMemory()
{
Component::freeGraphicsMemory();
currentScrollDirection_ = ScrollDirectionIdle;
requestedScrollDirection_ = ScrollDirectionIdle;
currentScrollState_ = ScrollStateIdle;
scrollPeriod_ = 0;
deallocateSpritePoints();
@ -411,110 +369,14 @@ void ScrollingList::update(float dt)
{
Component::update(dt);
bool readyToScroll = true;
bool scrollChanged = false;
bool scrollRequested = false;
bool scrollStopped = false;
if(components_.size() == 0) return;
if(!items_ || items_->size() == 0) return;
// validate all scroll points are done tweening to the next position
for(std::vector<Component *>::iterator c = components_.begin(); c != components_.end(); c++)
{
if(*c && (*c)->isMenuScrolling())
{
readyToScroll = false;
break;
}
}
// check if it was requested to change directions
if(currentScrollState_ == ScrollStateActive && requestedScrollDirection_ != currentScrollDirection_)
{
currentScrollState_ = ScrollStateStopping;
}
else if(currentScrollState_ == ScrollStateIdle && readyToScroll)
{
scrollPeriod_ = startScrollTime_;
// check to see if requested to scroll
if(requestedScrollDirection_ != ScrollDirectionIdle)
{
currentScrollState_ = ScrollStateActive;
currentScrollDirection_ = requestedScrollDirection_;
scrollRequested = true;
}
}
// if currently scrolling, process it
if(!scrollRequested && readyToScroll)
{
if(currentScrollState_ == ScrollStateStopping)
{
currentScrollState_ = ScrollStateIdle;
scrollStopped = true;
click(0);
for(unsigned int i = 0; i < tweenPoints_->size(); ++i)
{
unsigned int cindex = loopIncrement(componentIndex_, i, components_.size());
Component *c = components_.at(cindex);
if(c) c->setTweens(tweenPoints_->at(i));
}
}
else if(currentScrollState_ == ScrollStateActive)
{
scrollPeriod_ -= scrollAcceleration_;
if(scrollPeriod_ < scrollAcceleration_)
{
scrollPeriod_ = scrollAcceleration_;
}
click(scrollPeriod_);
scrollChanged = true;
}
}
for(unsigned int i = 0; i < scrollPoints_->size(); i++)
{
unsigned int cindex = loopIncrement(componentIndex_, i, components_.size());
Component *c = components_.at(cindex);
if(c && readyToScroll && (scrollRequested || scrollChanged))
{
unsigned int nextI = 0;
if(currentScrollDirection_ == ScrollDirectionBack)
{
nextI = loopIncrement(i, 1, scrollPoints_->size());
}
if(currentScrollDirection_ == ScrollDirectionForward)
{
nextI = loopDecrement(i, 1, scrollPoints_->size());
}
ViewInfo *currentvi = scrollPoints_->at(i);
ViewInfo *nextvi = scrollPoints_->at(nextI);
resetTweens(c, tweenPoints_->at(i), currentvi, nextvi, scrollPeriod_);
c->baseViewInfo.font = nextvi->font; // Use the font settings of the next index
c->triggerEvent( "menuScroll" );
}
if(c) c->update(dt);
}
if(scrollStopped)
{
if(currentScrollState_ == ScrollStatePageChange)
{
currentScrollState_ = ScrollStateIdle;
}
}
}
@ -737,15 +599,9 @@ void ScrollingList::draw(unsigned int layer)
}
void ScrollingList::setScrollDirection(ScrollDirection direction)
{
requestedScrollDirection_ = direction;
}
bool ScrollingList::isIdle()
{
if(!Component::isIdle() || currentScrollState_ != ScrollStateIdle) return false;
if(!Component::isIdle()) return false;
for(unsigned int i = 0; i < components_.size(); ++i)
{
@ -757,3 +613,73 @@ bool ScrollingList::isIdle()
}
void ScrollingList::resetScrollPeriod()
{
scrollPeriod_ = startScrollTime_;
return;
}
void ScrollingList::updateScrollPeriod()
{
scrollPeriod_ -= scrollAcceleration_;
if(scrollPeriod_ < scrollAcceleration_)
{
scrollPeriod_ = scrollAcceleration_;
}
}
void ScrollingList::scroll(bool forward)
{
if(forward)
{
Item *i = items_->at(loopIncrement(itemIndex_, scrollPoints_->size(), items_->size()));
deallocateTexture(componentIndex_);
allocateTexture(componentIndex_, i);
}
else
{
Item *i = items_->at(loopDecrement(itemIndex_, 1, items_->size()));
deallocateTexture(loopDecrement(componentIndex_, 1, components_.size()));
allocateTexture(loopDecrement(componentIndex_, 1, components_.size()), i);
}
for(unsigned int i = 0; i < scrollPoints_->size(); i++)
{
unsigned int cindex = loopIncrement(componentIndex_, i, components_.size());
Component *c = components_.at(cindex);
unsigned int nextI = 0;
if(forward)
{
nextI = loopDecrement(i, 1, scrollPoints_->size());
}
else
{
nextI = loopIncrement(i, 1, scrollPoints_->size());
}
ViewInfo *currentvi = scrollPoints_->at(i);
ViewInfo *nextvi = scrollPoints_->at(nextI);
resetTweens(c, tweenPoints_->at(i), currentvi, nextvi, scrollPeriod_);
c->baseViewInfo.font = nextvi->font; // Use the font settings of the next index
c->triggerEvent( "menuScroll" );
}
if(forward)
{
itemIndex_ = loopIncrement(itemIndex_, 1, items_->size());
componentIndex_ = loopIncrement(componentIndex_, 1, components_.size());
}
else
{
itemIndex_ = loopDecrement(itemIndex_, 1, items_->size());
componentIndex_ = loopDecrement(componentIndex_, 1, components_.size());
}
return;
}

View File

@ -34,14 +34,6 @@ class Font;
class ScrollingList : public Component
{
public:
enum ScrollDirection
{
ScrollDirectionBack,
ScrollDirectionForward,
ScrollDirectionIdle,
};
ScrollingList(Configuration &c,
Page &p,
bool layoutMode,
@ -65,7 +57,6 @@ public:
void setItems(std::vector<Item *> *items);
void destroyItems();
void setPoints(std::vector<ViewInfo *> *scrollPoints, std::vector<AnimationEvents *> *tweenPoints);
void setScrollDirection(ScrollDirection direction);
unsigned int getSelectedIndex();
unsigned int getSize();
void pageUp();
@ -89,22 +80,16 @@ public:
bool horizontalScroll;
void deallocateSpritePoints();
void allocateSpritePoints();
void resetScrollPeriod();
void updateScrollPeriod();
void scroll(bool forward);
private:
void click(double nextScrollTime);
void resetTweens(Component *c, AnimationEvents *sets, ViewInfo *currentViewInfo, ViewInfo *nextViewInfo, double scrollTime);
unsigned int loopIncrement(unsigned int offset, unsigned int i, unsigned int size);
unsigned int loopDecrement(unsigned int offset, unsigned int i, unsigned int size);
enum ScrollState
{
ScrollStateActive,
ScrollStatePageChange,
ScrollStateStopping,
ScrollStateIdle
};
bool layoutMode_;
std::vector<Component *> *spriteList_;
std::vector<ViewInfo *> *scrollPoints_;
@ -114,10 +99,6 @@ private:
unsigned int componentIndex_;
unsigned int selectedOffsetIndex_;
ScrollDirection currentScrollDirection_;
ScrollDirection requestedScrollDirection_;
ScrollState currentScrollState_;
float scrollAcceleration_;
float startScrollTime_;
float scrollPeriod_;

View File

@ -390,9 +390,6 @@ void Page::highlightExit()
void Page::setScrolling(ScrollDirection direction)
{
ScrollingList::ScrollDirection menuDirection;
bool prevScrollActive = scrollActive_;
switch(direction)
{
case ScrollDirectionForward:
@ -400,7 +397,6 @@ void Page::setScrolling(ScrollDirection direction)
{
menuScroll();
}
menuDirection = ScrollingList::ScrollDirectionForward;
scrollActive_ = true;
break;
case ScrollDirectionBack:
@ -408,23 +404,14 @@ void Page::setScrolling(ScrollDirection direction)
{
menuScroll();
}
menuDirection = ScrollingList::ScrollDirectionBack;
scrollActive_ = true;
break;
case ScrollDirectionIdle:
default:
menuDirection = ScrollingList::ScrollDirectionIdle;
scrollActive_ = false;
break;
}
if(!prevScrollActive && scrollActive_ && highlightSoundChunk_)
{
highlightSoundChunk_->play();
}
activeMenu_->setScrollDirection(menuDirection);
}
bool Page::isHorizontalScroll()
@ -856,4 +843,35 @@ bool Page::isPlaying()
return retVal;
}
}
void Page::resetScrollPeriod()
{
if(activeMenu_)
{
activeMenu_->resetScrollPeriod();
}
return;
}
void Page::updateScrollPeriod()
{
if(activeMenu_)
{
activeMenu_->updateScrollPeriod();
}
return;
}
void Page::scroll(bool forward)
{
if(activeMenu_)
{
activeMenu_->scroll(forward);
highlightSoundChunk_->play();
}
return;
}

View File

@ -96,6 +96,9 @@ public:
void reallocateMenuSpritePoints();
bool isMenuScrolling();
bool isPlaying();
void resetScrollPeriod();
void updateScrollPeriod();
void scroll(bool forward);
private:
void playlistChange();

View File

@ -257,7 +257,7 @@ void RetroFE::run()
float lastTime = 0;
float deltaTime = 0;
SDL_Event e;
if (SDL_PollEvent(&e))
if (splashMode && SDL_PollEvent(&e))
{
if(input_.update(e))
{
@ -281,7 +281,10 @@ void RetroFE::run()
// account for when returning from a menu and the previous key was still "stuck"
if(lastLaunchReturnTime_ == 0 || (currentTime_ - lastLaunchReturnTime_ > .3))
{
state = processUserInput(currentPage_);
if(currentPage_->isMenuIdle())
{
state = processUserInput(currentPage_);
}
lastLaunchReturnTime_ = 0;
}
}
@ -398,7 +401,7 @@ void RetroFE::run()
break;
case RETROFE_HIGHLIGHT_EXIT:
if (processUserInput(currentPage_) == RETROFE_HIGHLIGHT_REQUEST)
if (currentPage_->isMenuIdle() && processUserInput(currentPage_) == RETROFE_HIGHLIGHT_REQUEST)
{
state = RETROFE_HIGHLIGHT_MENU_IDLE;
}
@ -415,7 +418,7 @@ void RetroFE::run()
break;
case RETROFE_HIGHLIGHT_ENTER:
if (processUserInput(currentPage_) == RETROFE_HIGHLIGHT_REQUEST)
if (currentPage_->isMenuIdle() && processUserInput(currentPage_) == RETROFE_HIGHLIGHT_REQUEST)
{
state = RETROFE_HIGHLIGHT_REQUEST;
}
@ -655,15 +658,29 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
bool exit = false;
RETROFE_STATE state = RETROFE_IDLE;
SDL_Event e;
while (SDL_PollEvent(&e))
{
input_.update(e);
if(e.type == SDL_KEYDOWN && !e.key.repeat)
{
break;
}
}
if(page->isHorizontalScroll())
{
if (input_.keystate(UserInput::KeyCodeLeft))
{
page->setScrolling(Page::ScrollDirectionBack);
page->scroll(false);
page->updateScrollPeriod();
}
if (input_.keystate(UserInput::KeyCodeRight))
{
page->setScrolling(Page::ScrollDirectionForward);
page->scroll(true);
page->updateScrollPeriod();
}
}
else
@ -671,10 +688,14 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
if (input_.keystate(UserInput::KeyCodeUp))
{
page->setScrolling(Page::ScrollDirectionBack);
page->scroll(false);
page->updateScrollPeriod();
}
if (input_.keystate(UserInput::KeyCodeDown))
{
page->setScrolling(Page::ScrollDirectionForward);
page->scroll(true);
page->updateScrollPeriod();
}
}
@ -790,8 +811,11 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
!input_.keystate(UserInput::KeyCodePageDown) &&
!attract_.isActive())
{
page->resetScrollPeriod();
if (page->isMenuScrolling())
{
state = RETROFE_HIGHLIGHT_REQUEST;
}
}
return state;