Rewrote the animation activation functions and state machines to

remove/reduce the glitch behaviour.
WARNING: This will disable workarounds that have been used in the themes so
far; many if not all themes will need to be changed to work properly!
This commit is contained in:
Pieter Hulshoff 2016-06-05 09:32:48 +02:00
parent 4b05992a19
commit 9da55a844e
12 changed files with 308 additions and 493 deletions

View File

@ -22,9 +22,8 @@
Component::Component(Page &p) Component::Component(Page &p)
: page(p) : page(p)
{ {
tweens_ = NULL; tweens_ = NULL;
newItemSelectedSinceEnter = false; backgroundTexture_ = NULL;
backgroundTexture_ = NULL;
freeGraphicsMemory(); freeGraphicsMemory();
} }
@ -33,7 +32,6 @@ Component::Component(const Component &copy)
: page(copy.page) : page(copy.page)
{ {
tweens_ = NULL; tweens_ = NULL;
newItemSelectedSinceEnter = false;
backgroundTexture_ = NULL; backgroundTexture_ = NULL;
freeGraphicsMemory(); freeGraphicsMemory();
@ -53,23 +51,16 @@ Component::~Component()
void Component::freeGraphicsMemory() void Component::freeGraphicsMemory()
{ {
currentAnimationState = HIDDEN; animationRequestedType_ = "";
enterRequested = false; animationType_ = "";
exitRequested = false; animationRequested_ = false;
menuEnterRequested = false; newItemSelected = false;
menuEnterIndex = -1; menuIndex_ = -1;
menuScrollRequested = false;
menuExitRequested = false;
menuExitIndex = -1;
newItemSelected = false; currentTweens_ = NULL;
playlistChanged = false; currentTweenIndex_ = 0;
highlightExitComplete = false; currentTweenComplete_ = true;
currentTweens_ = NULL; elapsedTweenTime_ = 0;
currentTweenIndex_ = 0;
currentTweenComplete_ = false;
elapsedTweenTime_ = 0;
scrollActive = false;
if(backgroundTexture_) if(backgroundTexture_)
{ {
@ -98,244 +89,71 @@ void Component::allocateGraphicsMemory()
} }
} }
void Component::triggerEnterEvent() void Component::triggerEvent(std::string event, int menuIndex)
{ {
enterRequested = true; animationRequestedType_ = event;
animationRequested_ = true;
menuIndex_ = menuIndex;
} }
void Component::triggerExitEvent() void Component::setPlaylist(std::string name)
{ {
exitRequested = true;
}
void Component::triggerMenuEnterEvent(int menuIndex)
{
menuEnterRequested = true;
menuEnterIndex = menuIndex;
}
void Component::triggerMenuScrollEvent()
{
menuScrollRequested = true;
}
void Component::triggerMenuExitEvent(int menuIndex)
{
menuExitRequested = true;
menuExitIndex = menuIndex;
}
void Component::triggerHighlightEvent()
{
newItemSelected = true;
}
void Component::triggerPlaylistChangeEvent(std::string name)
{
playlistChanged = true;
this->playlistName = name; this->playlistName = name;
} }
void Component::setNewItemSelected()
{
newItemSelected = true;
}
bool Component::isIdle() bool Component::isIdle()
{ {
return (currentAnimationState == IDLE); return (currentTweenComplete_ || animationType_ == "idle");
}
bool Component::isHidden()
{
return (currentAnimationState == HIDDEN);
}
bool Component::isWaiting()
{
return (currentAnimationState == HIGHLIGHT_WAIT);
} }
bool Component::isMenuScrolling() bool Component::isMenuScrolling()
{ {
return (currentAnimationState == MENU_ENTER || currentAnimationState == MENU_SCROLL || currentAnimationState == MENU_EXIT || menuScrollRequested); return (!currentTweenComplete_ && animationType_ == "menuScroll");
} }
void Component::setTweens(AnimationEvents *set) void Component::setTweens(AnimationEvents *set)
{ {
tweens_ = set; tweens_ = set;
forceIdle();
} }
void Component::forceIdle()
{
currentAnimationState = IDLE;
currentTweenIndex_ = 0;
currentTweenComplete_ = false;
elapsedTweenTime_ = 0;
currentTweens_ = NULL;
}
void Component::update(float dt) void Component::update(float dt)
{ {
elapsedTweenTime_ += dt; elapsedTweenTime_ += dt;
highlightExitComplete = false;
if(isHidden() || isWaiting() || (isIdle() && (exitRequested || menuExitRequested || enterRequested || menuEnterRequested))) if(animationRequested_ && animationRequestedType_ != "")
{ {
currentTweenComplete_ = true; Animation *newTweens = tweens_->getAnimation( animationRequestedType_, menuIndex_ );
if (newTweens)
{
animationType_ = animationRequestedType_;
currentTweens_ = newTweens;
currentTweenIndex_ = 0;
elapsedTweenTime_ = 0;
currentTweenComplete_ = false;
}
animationRequested_ = false;
}
else if (tweens_ && currentTweenComplete_)
{
animationType_ = "idle";
currentTweens_ = tweens_->getAnimation( "idle", menuIndex_ );
currentTweenIndex_ = 0;
elapsedTweenTime_ = 0;
currentTweenComplete_ = false;
animationRequested_ = false;
} }
currentTweenComplete_ = animate();
if(currentTweenComplete_) if(currentTweenComplete_)
{ {
currentTweens_ = NULL; currentTweens_ = NULL;
currentTweenIndex_ = 0;
// There was no request to override our state path. Continue on as normal.
std::stringstream ss;
switch(currentAnimationState)
{
case MENU_ENTER:
currentTweens_ = NULL;
currentAnimationState = IDLE;
break;
case MENU_SCROLL:
currentTweens_ = NULL;
currentAnimationState = IDLE;
break;
case MENU_EXIT:
currentTweens_ = NULL;
currentAnimationState = IDLE;
break;
case ENTER:
currentTweens_ = tweens_->getAnimation("enter", menuEnterIndex);
currentAnimationState = HIGHLIGHT_ENTER;
break;
case EXIT:
currentTweens_ = NULL;
currentAnimationState = HIDDEN;
break;
case HIGHLIGHT_ENTER:
currentTweens_ = tweens_->getAnimation("idle", menuEnterIndex);
currentAnimationState = IDLE;
break;
case IDLE:
// prevent us from automatically jumping to the exit tween upon enter
if(enterRequested)
{
enterRequested = false;
newItemSelected = false;
}
else if(menuExitRequested && (!menuEnterRequested || menuExitRequested <= menuEnterRequested))
{
currentTweens_ = tweens_->getAnimation("menuExit", menuExitIndex);
currentAnimationState = MENU_EXIT;
menuExitRequested = false;
}
else if(menuEnterRequested && (!menuExitRequested || menuExitRequested > menuEnterRequested))
{
currentTweens_ = tweens_->getAnimation("menuEnter", menuEnterIndex);
currentAnimationState = MENU_ENTER;
menuEnterRequested = false;
}
else if(menuScrollRequested)
{
menuScrollRequested = false;
currentTweens_ = tweens_->getAnimation("menuScroll", menuEnterIndex);
currentAnimationState = MENU_SCROLL;
}
else if(scrollActive || newItemSelected || exitRequested)
{
currentTweens_ = tweens_->getAnimation("highlightExit", menuEnterIndex);
currentAnimationState = HIGHLIGHT_EXIT;
}
else
{
currentTweens_ = tweens_->getAnimation("idle", menuEnterIndex);
currentAnimationState = IDLE;
}
break;
case HIGHLIGHT_EXIT:
// intentionally break down
case HIGHLIGHT_WAIT:
if(exitRequested && (currentAnimationState == HIGHLIGHT_WAIT))
{
currentTweens_ = tweens_->getAnimation("highlightExit", menuEnterIndex);
currentAnimationState = HIGHLIGHT_EXIT;
}
else if(exitRequested && (currentAnimationState == HIGHLIGHT_EXIT))
{
currentTweens_ = tweens_->getAnimation("exit", menuEnterIndex);
currentAnimationState = EXIT;
exitRequested = false;
}
else if(scrollActive)
{
currentTweens_ = NULL;
currentAnimationState = HIGHLIGHT_WAIT;
}
else if(newItemSelected)
{
currentTweens_ = tweens_->getAnimation("highlightEnter", menuEnterIndex);
currentAnimationState = HIGHLIGHT_ENTER;
highlightExitComplete = true;
newItemSelected = false;
}
else
{
currentTweens_ = NULL;
currentAnimationState = HIGHLIGHT_WAIT;
}
break;
case HIDDEN:
if(enterRequested || exitRequested)
{
currentTweens_ = tweens_->getAnimation("enter", menuEnterIndex);
currentAnimationState = ENTER;
}
else if(menuExitRequested && (!menuEnterRequested || menuExitRequested <= menuEnterRequested))
{
currentTweens_ = tweens_->getAnimation("menuExit", menuExitIndex);
currentAnimationState = MENU_EXIT;
menuExitRequested = false;
}
else if(menuEnterRequested && (!menuExitRequested || menuExitRequested > menuEnterRequested))
{
currentTweens_ = tweens_->getAnimation("menuEnter", menuEnterIndex);
currentAnimationState = MENU_ENTER;
menuEnterRequested = false;
}
else if(menuScrollRequested)
{
menuScrollRequested = false;
currentTweens_ = tweens_->getAnimation("menuScroll", menuEnterIndex);
currentAnimationState = MENU_SCROLL;
}
else
{
currentTweens_ = NULL;
currentAnimationState = HIDDEN;
}
}
currentTweenIndex_ = 0;
currentTweenComplete_ = false;
elapsedTweenTime_ = 0;
} }
currentTweenComplete_ = animate(isIdle());
} }
void Component::draw() void Component::draw()
@ -359,7 +177,7 @@ void Component::draw()
} }
} }
bool Component::animate(bool loop) bool Component::animate()
{ {
bool completeDone = false; bool completeDone = false;
if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->size()) if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->size())
@ -449,10 +267,6 @@ bool Component::animate(bool loop)
if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->tweenSets()->size()) if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->tweenSets()->size())
{ {
if(loop)
{
currentTweenIndex_ = 0;
}
completeDone = true; completeDone = true;
} }

View File

@ -34,59 +34,26 @@ public:
virtual void allocateGraphicsMemory(); virtual void allocateGraphicsMemory();
virtual void launchEnter() {} virtual void launchEnter() {}
virtual void launchExit() {} virtual void launchExit() {}
void triggerEnterEvent(); void triggerEvent(std::string event, int menuIndex = -1);
void triggerExitEvent(); void setPlaylist(std::string name );
void triggerMenuEnterEvent(int menuIndex = -1); void setNewItemSelected();
void triggerMenuExitEvent(int menuIndex = -1);
void triggerMenuScrollEvent();
void triggerHighlightEvent();
void triggerPlaylistChangeEvent(std::string name);
bool isIdle(); bool isIdle();
bool isHidden();
bool isWaiting();
bool isMenuScrolling(); bool isMenuScrolling();
bool newItemSelected;
virtual void update(float dt); virtual void update(float dt);
virtual void draw(); virtual void draw();
void setTweens(AnimationEvents *set); void setTweens(AnimationEvents *set);
void forceIdle();
ViewInfo baseViewInfo; ViewInfo baseViewInfo;
std::string collectionName; std::string collectionName;
bool scrollActive;
protected: protected:
Page &page; Page &page;
enum AnimationState
{
IDLE,
ENTER,
HIGHLIGHT_EXIT,
HIGHLIGHT_WAIT,
HIGHLIGHT_ENTER,
EXIT,
MENU_ENTER,
MENU_SCROLL,
MENU_EXIT,
HIDDEN
};
AnimationState currentAnimationState;
bool enterRequested;
bool exitRequested;
bool menuEnterRequested;
int menuEnterIndex;
bool menuScrollRequested;
bool menuExitRequested;
int menuExitIndex;
bool newItemSelected;
bool playlistChanged;
std::string playlistName; std::string playlistName;
bool highlightExitComplete;
bool newItemSelectedSinceEnter;
private: private:
bool animate(bool loop); bool animate();
bool tweenSequencingComplete(); bool tweenSequencingComplete();
AnimationEvents *tweens_; AnimationEvents *tweens_;
@ -94,6 +61,10 @@ private:
SDL_Texture *backgroundTexture_; SDL_Texture *backgroundTexture_;
unsigned int currentTweenIndex_; unsigned int currentTweenIndex_;
bool currentTweenComplete_; bool currentTweenComplete_;
float elapsedTweenTime_; float elapsedTweenTime_;
std::string animationRequestedType_;
std::string animationType_;
bool animationRequested_;
int menuIndex_;
}; };

View File

@ -33,8 +33,6 @@ ReloadableMedia::ReloadableMedia(Configuration &config, bool systemMode, std::st
, config_(config) , config_(config)
, systemMode_(systemMode) , systemMode_(systemMode)
, loadedComponent_(NULL) , loadedComponent_(NULL)
, reloadRequested_(false)
, firstLoad_(true)
, videoInst_(NULL) , videoInst_(NULL)
, isVideo_(isVideo) , isVideo_(isVideo)
, FfntInst_(font) , FfntInst_(font)
@ -63,23 +61,11 @@ void ReloadableMedia::enableTextFallback_(bool value)
void ReloadableMedia::update(float dt) void ReloadableMedia::update(float dt)
{ {
if(newItemSelected) if (newItemSelected)
{
std::string collection;
config_.getProperty("currentCollection", collection);
if(!systemMode_ || (systemMode_ && currentCollection_ != collection))
{
reloadRequested_ = true;
}
}
// wait for the right moment to reload the image
if (reloadRequested_ && (highlightExitComplete || firstLoad_))
{ {
reloadTexture(); reloadTexture();
reloadRequested_ = false; newItemSelected = false;
firstLoad_ = false;
} }
if(loadedComponent_) if(loadedComponent_)
@ -102,8 +88,6 @@ void ReloadableMedia::update(float dt)
void ReloadableMedia::allocateGraphicsMemory() void ReloadableMedia::allocateGraphicsMemory()
{ {
firstLoad_ = true;
if(loadedComponent_) if(loadedComponent_)
{ {
loadedComponent_->allocateGraphicsMemory(); loadedComponent_->allocateGraphicsMemory();

View File

@ -44,8 +44,6 @@ private:
Configuration &config_; Configuration &config_;
bool systemMode_; bool systemMode_;
Component *loadedComponent_; Component *loadedComponent_;
bool reloadRequested_;
bool firstLoad_;
IVideo *videoInst_; IVideo *videoInst_;
bool isVideo_; bool isVideo_;
Font *FfntInst_; Font *FfntInst_;

View File

@ -30,8 +30,6 @@ ReloadableText::ReloadableText(std::string type, Page &page, Configuration &conf
, imageInst_(NULL) , imageInst_(NULL)
, type_(type) , type_(type)
, layoutKey_(layoutKey) , layoutKey_(layoutKey)
, reloadRequested_(false)
, firstLoad_(true)
, fontInst_(font) , fontInst_(font)
, timeFormat_(timeFormat) , timeFormat_(timeFormat)
, scaleX_(scaleX) , scaleX_(scaleX)
@ -52,18 +50,10 @@ ReloadableText::~ReloadableText()
void ReloadableText::update(float dt) void ReloadableText::update(float dt)
{ {
if((type_ != "playlist" && newItemSelected) || if (newItemSelected || type_ == "time")
(type_ == "playlist" && playlistChanged) ||
(type_ == "time"))
{
reloadRequested_ = true;
}
// wait for the right moment to reload the image
if (reloadRequested_ && (type_ == "time" || highlightExitComplete || firstLoad_))
{ {
ReloadTexture(); ReloadTexture();
reloadRequested_ = false; newItemSelected = false;
firstLoad_ = false;
} }
// needs to be ran at the end to prevent the NewItemSelected flag from being detected // needs to be ran at the end to prevent the NewItemSelected flag from being detected
@ -73,8 +63,6 @@ void ReloadableText::update(float dt)
void ReloadableText::allocateGraphicsMemory() void ReloadableText::allocateGraphicsMemory()
{ {
firstLoad_ = true;
ReloadTexture(); ReloadTexture();
// NOTICE! needs to be done last to prevent flags from being missed // NOTICE! needs to be done last to prevent flags from being missed

View File

@ -41,8 +41,6 @@ private:
Text *imageInst_; Text *imageInst_;
std::string type_; std::string type_;
std::string layoutKey_; std::string layoutKey_;
bool reloadRequested_;
bool firstLoad_;
Font *fontInst_; Font *fontInst_;
std::string timeFormat_; std::string timeFormat_;

View File

@ -381,7 +381,7 @@ void ScrollingList::freeGraphicsMemory()
deallocateSpritePoints(); deallocateSpritePoints();
} }
void ScrollingList::triggerMenuEnterEvent() void ScrollingList::triggerMenuEnterEvent( int menuIndex )
{ {
focus_ = true; focus_ = true;
notifyAllRequested_ = true; notifyAllRequested_ = true;
@ -389,11 +389,11 @@ void ScrollingList::triggerMenuEnterEvent()
for(unsigned int i = 0; i < components_.size(); ++i) for(unsigned int i = 0; i < components_.size(); ++i)
{ {
Component *c = components_.at(i); Component *c = components_.at(i);
if(c) c->triggerMenuEnterEvent(); if(c) c->triggerEvent( "menuEnter", menuIndex );
} }
} }
void ScrollingList::triggerMenuExitEvent() void ScrollingList::triggerMenuExitEvent( int menuIndex )
{ {
focus_ = false; focus_ = false;
notifyAllRequested_ = true; notifyAllRequested_ = true;
@ -401,7 +401,7 @@ void ScrollingList::triggerMenuExitEvent()
for(unsigned int i = 0; i < components_.size(); ++i) for(unsigned int i = 0; i < components_.size(); ++i)
{ {
Component *c = components_.at(i); Component *c = components_.at(i);
if(c) c->triggerMenuExitEvent(); if(c) c->triggerEvent( "menuExit", menuIndex );
} }
} }
@ -500,7 +500,7 @@ void ScrollingList::update(float dt)
resetTweens(c, tweenPoints_->at(i), currentvi, nextvi, scrollPeriod_); resetTweens(c, tweenPoints_->at(i), currentvi, nextvi, scrollPeriod_);
c->baseViewInfo.font = nextvi->font; // Use the font settings of the next index c->baseViewInfo.font = nextvi->font; // Use the font settings of the next index
c->triggerMenuScrollEvent(); c->triggerEvent( "menuScroll" );
} }
if(c) c->update(dt); if(c) c->update(dt);

View File

@ -53,8 +53,8 @@ public:
ScrollingList(const ScrollingList &copy); ScrollingList(const ScrollingList &copy);
virtual ~ScrollingList(); virtual ~ScrollingList();
void triggerMenuEnterEvent(); void triggerMenuEnterEvent(int menuIndex = -1);
void triggerMenuExitEvent(); void triggerMenuExitEvent(int menuIndex = -1);
bool allocateTexture(unsigned int index, Item *i); bool allocateTexture(unsigned int index, Item *i);
void deallocateTexture(unsigned int index); void deallocateTexture(unsigned int index);

View File

@ -33,8 +33,6 @@ Page::Page(Configuration &config)
, scrollActive_(false) , scrollActive_(false)
, selectedItem_(NULL) , selectedItem_(NULL)
, textStatusComponent_(NULL) , textStatusComponent_(NULL)
, selectedItemChanged_(false)
, playlistChanged_(false)
, loadSoundChunk_(NULL) , loadSoundChunk_(NULL)
, unloadSoundChunk_(NULL) , unloadSoundChunk_(NULL)
, highlightSoundChunk_(NULL) , highlightSoundChunk_(NULL)
@ -132,12 +130,34 @@ void Page::setSelectSound(Sound *chunk)
{ {
selectSoundChunk_ = chunk; selectSoundChunk_ = chunk;
} }
void Page::onNewItemSelected(Item *item) void Page::onNewItemSelected(Item *item)
{ {
selectedItem_ = item; selectedItem_ = item;
selectedItemChanged_ = true;
for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++)
{
ScrollingList *menu = *it;
menu->setNewItemSelected();
}
if(unloadSoundChunk_)
{
unloadSoundChunk_->play();
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->setNewItemSelected();
}
}
} }
void Page::pushMenu(ScrollingList *s) void Page::pushMenu(ScrollingList *s)
{ {
menus_.push_back(s); menus_.push_back(s);
@ -214,39 +234,12 @@ bool Page::isIdle()
} }
bool Page::isHidden()
{
bool hidden = true;
for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++)
{
ScrollingList *menu = *it;
if(!menu->isHidden())
{
hidden = false;
break;
}
}
for(unsigned int i = 0; hidden && i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); hidden && it != LayerComponents[i].end(); ++it)
{
hidden = (*it)->isHidden();
}
}
return hidden;
}
void Page::start() void Page::start()
{ {
for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++) for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++)
{ {
ScrollingList *menu = *it; ScrollingList *menu = *it;
menu->triggerEnterEvent(); menu->triggerEvent( "enter" );
} }
if(loadSoundChunk_) if(loadSoundChunk_)
@ -264,7 +257,7 @@ void Page::startComponents()
{ {
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{ {
(*it)->triggerEnterEvent(); (*it)->triggerEvent( "enter" );
} }
} }
} }
@ -274,7 +267,7 @@ void Page::stop()
for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++) for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++)
{ {
ScrollingList *menu = *it; ScrollingList *menu = *it;
menu->triggerExitEvent(); menu->triggerEvent( "exit" );
} }
if(unloadSoundChunk_) if(unloadSoundChunk_)
@ -286,12 +279,32 @@ void Page::stop()
{ {
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{ {
(*it)->triggerExitEvent(); (*it)->triggerEvent( "exit" );
} }
} }
} }
void Page::setNewItemSelected()
{
if(activeMenu_)
{
activeMenu_->setNewItemSelected();
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->setNewItemSelected();
}
}
return;
}
Item *Page::getSelectedItem() Item *Page::getSelectedItem()
{ {
return selectedItem_; return selectedItem_;
@ -344,35 +357,54 @@ void Page::playlistChange()
{ {
if(activeMenu_) if(activeMenu_)
{ {
activeMenu_->triggerPlaylistChangeEvent(playlist_->first); activeMenu_->setPlaylist(playlist_->first);
} }
for(unsigned int i = 0; i < NUM_LAYERS; ++i) for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{ {
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{ {
(*it)->triggerPlaylistChangeEvent(playlist_->first); (*it)->setPlaylist(playlist_->first);
} }
} }
} }
void Page::highlight()
void Page::highlightEnter()
{ {
Item *item = selectedItem_; Item *item = selectedItem_;
if(!item) return; if(!item) return;
if(activeMenu_) if(activeMenu_)
{ {
activeMenu_->triggerHighlightEvent(); activeMenu_->triggerEvent( "highlightEnter" );
activeMenu_->scrollActive = scrollActive_;
} }
for(unsigned int i = 0; i < NUM_LAYERS; ++i) for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{ {
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{ {
(*it)->triggerHighlightEvent(); (*it)->triggerEvent( "highlightEnter" );
(*it)->scrollActive = scrollActive_; }
}
}
void Page::highlightExit()
{
Item *item = selectedItem_;
if(!item) return;
if(activeMenu_)
{
activeMenu_->triggerEvent( "highlightExit" );
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->triggerEvent( "highlightExit" );
} }
} }
} }
@ -465,28 +497,13 @@ unsigned int Page::getSelectedIndex()
bool Page::pushCollection(CollectionInfo *collection) bool Page::pushCollection(CollectionInfo *collection)
{ {
int menuExitIndex = -1;
int menuEnterIndex = -1;
if(activeMenu_)
{
activeMenu_->triggerMenuExitEvent();
}
if(menuDepth_ > 0)
{
menuExitIndex = menuDepth_ - 1;
}
// grow the menu as needed // grow the menu as needed
if(menus_.size() >= menuDepth_ && activeMenu_) if(menus_.size() >= menuDepth_ && activeMenu_)
{ {
activeMenu_ = new ScrollingList(*activeMenu_); activeMenu_ = new ScrollingList(*activeMenu_);
activeMenu_->forceIdle();
pushMenu(activeMenu_); pushMenu(activeMenu_);
} }
activeMenu_ = menus_[menuDepth_]; activeMenu_ = menus_[menuDepth_];
activeMenu_->collectionName = collection->name; activeMenu_->collectionName = collection->name;
activeMenu_->setItems(&collection->items); activeMenu_->setItems(&collection->items);
@ -501,11 +518,10 @@ bool Page::pushCollection(CollectionInfo *collection)
collections_.push_back(info); collections_.push_back(info);
playlist_ = info.playlist; playlist_ = info.playlist;
playlistChanged_ = true; playlistChange();
if(menuDepth_ < menus_.size()) if(menuDepth_ < menus_.size())
{ {
menuEnterIndex = menuDepth_;
menuDepth_++; menuDepth_++;
} }
@ -514,15 +530,6 @@ bool Page::pushCollection(CollectionInfo *collection)
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{ {
(*it)->collectionName = collection->name; (*it)->collectionName = collection->name;
if(menuEnterIndex >= 0)
{
(*it)->triggerMenuEnterEvent(menuEnterIndex);
}
if(menuExitIndex >= 0)
{
(*it)->triggerMenuExitEvent(menuExitIndex);
}
} }
} }
@ -531,8 +538,6 @@ bool Page::pushCollection(CollectionInfo *collection)
bool Page::popCollection() bool Page::popCollection()
{ {
int menuExitIndex = -1;
int menuEnterIndex = -1;
if(!activeMenu_) return false; if(!activeMenu_) return false;
if(menuDepth_ <= 1) return false; if(menuDepth_ <= 1) return false;
@ -547,44 +552,63 @@ bool Page::popCollection()
collections_.pop_back(); collections_.pop_back();
info = &collections_.back(); info = &collections_.back();
playlist_ = info->playlist; playlist_ = info->playlist;
playlistChanged_ = true; playlistChange();
if(activeMenu_)
{
activeMenu_->triggerMenuExitEvent();
}
menuDepth_--; menuDepth_--;
menuExitIndex = menuDepth_;
menuEnterIndex = menuExitIndex - 1;
activeMenu_ = menus_[menuDepth_ - 1]; activeMenu_ = menus_[menuDepth_ - 1];
if(activeMenu_)
{
activeMenu_->triggerMenuEnterEvent();
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i) for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{ {
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it) for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{ {
(*it)->collectionName = info->collection->name; (*it)->collectionName = info->collection->name;
if(menuEnterIndex >= 0)
{
(*it)->triggerMenuEnterEvent(menuEnterIndex);
}
if(menuExitIndex >= 0)
{
(*it)->triggerMenuExitEvent(menuExitIndex);
}
} }
} }
return true; return true;
} }
void Page::enterMenu()
{
if(activeMenu_)
{
activeMenu_->triggerMenuEnterEvent( menuDepth_ - 1 );
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->triggerEvent( "menuEnter", menuDepth_ - 1 );
}
}
return;
}
void Page::exitMenu()
{
if(activeMenu_)
{
activeMenu_->triggerMenuExitEvent( menuDepth_ - 1 );
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->triggerEvent( "menuExit", menuDepth_ - 1 );
}
}
return;
}
void Page::nextPlaylist() void Page::nextPlaylist()
{ {
MenuInfo_S &info = collections_.back(); MenuInfo_S &info = collections_.back();
@ -603,7 +627,7 @@ void Page::nextPlaylist()
activeMenu_->setItems(playlist_->second); activeMenu_->setItems(playlist_->second);
activeMenu_->triggerMenuEnterEvent(); activeMenu_->triggerMenuEnterEvent();
playlistChanged_ = true; playlistChange();
} }
void Page::favPlaylist() void Page::favPlaylist()
@ -631,7 +655,7 @@ void Page::favPlaylist()
activeMenu_->setItems(playlist_->second); activeMenu_->setItems(playlist_->second);
activeMenu_->triggerMenuEnterEvent(); activeMenu_->triggerMenuEnterEvent();
playlistChanged_ = true; playlistChange();
} }
void Page::update(float dt) void Page::update(float dt)
@ -643,18 +667,6 @@ void Page::update(float dt)
menu->update(dt); menu->update(dt);
} }
if(playlistChanged_)
{
playlistChange();
playlistChanged_ = false;
}
if(selectedItemChanged_ && !scrollActive_)
{
highlight();
selectedItemChanged_ = false;
}
if(textStatusComponent_) if(textStatusComponent_)
{ {
std::string status; std::string status;

View File

@ -47,6 +47,8 @@ public:
virtual void onNewItemSelected(Item *); virtual void onNewItemSelected(Item *);
bool pushCollection(CollectionInfo *collection); bool pushCollection(CollectionInfo *collection);
bool popCollection(); bool popCollection();
void enterMenu();
void exitMenu();
void nextPlaylist(); void nextPlaylist();
void favPlaylist(); void favPlaylist();
void pushMenu(ScrollingList *s); void pushMenu(ScrollingList *s);
@ -67,6 +69,7 @@ public:
void setScrolling(ScrollDirection direction); void setScrolling(ScrollDirection direction);
bool isHorizontalScroll(); bool isHorizontalScroll();
unsigned int getMenuDepth(); unsigned int getMenuDepth();
void setNewItemSelected();
Item *getSelectedItem(); Item *getSelectedItem();
Item *getSelectedItem(int offset); Item *getSelectedItem(int offset);
void removeSelectedItem(); void removeSelectedItem();
@ -74,7 +77,6 @@ public:
unsigned int getScrollOffsetIndex(); unsigned int getScrollOffsetIndex();
bool isIdle(); bool isIdle();
bool isMenuIdle(); bool isMenuIdle();
bool isHidden();
void setStatusTextComponent(Text *t); void setStatusTextComponent(Text *t);
void update(float dt); void update(float dt);
void draw(); void draw();
@ -89,7 +91,8 @@ public:
void removePlaylist(); void removePlaylist();
private: private:
void highlight(); void highlightEnter();
void highlightExit();
void playlistChange(); void playlistChange();
std::string collectionName_; std::string collectionName_;
Configuration &config_; Configuration &config_;
@ -120,8 +123,6 @@ private:
Item *selectedItem_; Item *selectedItem_;
Text *textStatusComponent_; Text *textStatusComponent_;
bool selectedItemChanged_;
bool playlistChanged_;
Sound *loadSoundChunk_; Sound *loadSoundChunk_;
Sound *unloadSoundChunk_; Sound *unloadSoundChunk_;
Sound *highlightSoundChunk_; Sound *highlightSoundChunk_;

View File

@ -167,7 +167,6 @@ void RetroFE::allocateGraphicsMemory()
if(currentPage_) if(currentPage_)
{ {
currentPage_->allocateGraphicsMemory(); currentPage_->allocateGraphicsMemory();
currentPage_->start();
} }
} }
@ -239,7 +238,8 @@ void RetroFE::run()
int initializeStatus = 0; int initializeStatus = 0;
// load the initial splash screen, unload it once it is complete // load the initial splash screen, unload it once it is complete
currentPage_ = loadSplashPage(); currentPage_ = loadSplashPage();
state = RETROFE_ENTER;
bool splashMode = true; bool splashMode = true;
Launcher l(*this, config_); Launcher l(*this, config_);
@ -288,6 +288,22 @@ void RetroFE::run()
break; break;
} }
currentPage_->stop();
state = RETROFE_EXIT;
}
break;
case RETROFE_ENTER:
if(currentPage_->isIdle())
{
state = RETROFE_IDLE;
}
break;
case RETROFE_EXIT:
if(currentPage_->isIdle())
{
// delete the splash screen and use the standard menu // delete the splash screen and use the standard menu
currentPage_->DeInitialize(); currentPage_->DeInitialize();
delete currentPage_; delete currentPage_;
@ -301,8 +317,6 @@ void RetroFE::run()
config_.getProperty("firstCollection", firstCollection); config_.getProperty("firstCollection", firstCollection);
config_.getProperty("collections." + firstCollection + ".list.menuSort", menuSort); config_.getProperty("collections." + firstCollection + ".list.menuSort", menuSort);
currentPage_->start();
config_.setProperty("currentCollection", firstCollection); config_.setProperty("currentCollection", firstCollection);
CollectionInfo *info = getCollection(firstCollection); CollectionInfo *info = getCollection(firstCollection);
MenuParser mp; MenuParser mp;
@ -310,22 +324,62 @@ void RetroFE::run()
mp.buildMenuItems(info, menuSort); mp.buildMenuItems(info, menuSort);
currentPage_->pushCollection(info); currentPage_->pushCollection(info);
state = RETROFE_ENTER;
} }
else else
{ {
state = RETROFE_QUIT_REQUEST; state = RETROFE_QUIT_REQUEST;
} }
} }
break; break;
case RETROFE_NEXT_PAGE_REQUEST: case RETROFE_NEXT_PAGE_REQUEST:
currentPage_->exitMenu();
state = RETROFE_NEXT_PAGE_MENU_EXIT;
break;
case RETROFE_NEXT_PAGE_MENU_EXIT:
if(currentPage_->isIdle()) if(currentPage_->isIdle())
{ {
state = RETROFE_NEW; bool menuSort = true;
} config_.setProperty("currentCollection", nextPageItem_->name);
break; config_.getProperty("collections." + nextPageItem_->name + ".list.menuSort", menuSort);
CollectionInfo *info = getCollection(nextPageItem_->name);
MenuParser mp;
mp.buildMenuItems(info, menuSort);
currentPage_->pushCollection(info);
bool rememberMenu = false;
config_.getProperty("rememberMenu", rememberMenu);
if(rememberMenu && lastMenuOffsets_.find(nextPageItem_->name) != lastMenuOffsets_.end())
{
currentPage_->setScrollOffsetIndex(lastMenuOffsets_[nextPageItem_->name]);
}
bool autoFavorites = true;
config_.getProperty("autoFavorites", autoFavorites);
if (autoFavorites)
currentPage_->favPlaylist(); // Switch to favorites if it exists
currentPage_->setNewItemSelected();
currentPage_->enterMenu();
state = RETROFE_NEXT_PAGE_MENU_ENTER;
}
break;
case RETROFE_NEXT_PAGE_MENU_ENTER:
if(currentPage_->isIdle())
{
state = RETROFE_IDLE;
}
break;
case RETROFE_LAUNCH_REQUEST: case RETROFE_LAUNCH_REQUEST:
nextPageItem_ = currentPage_->getSelectedItem(); nextPageItem_ = currentPage_->getSelectedItem();
@ -334,14 +388,28 @@ void RetroFE::run()
break; break;
case RETROFE_BACK_REQUEST: case RETROFE_BACK_REQUEST:
currentPage_->exitMenu();
state = RETROFE_BACK_MENU_EXIT;
break;
case RETROFE_BACK_MENU_EXIT:
if(currentPage_->isIdle())
{
lastMenuOffsets_[currentPage_->getCollectionName()] = currentPage_->getScrollOffsetIndex(); lastMenuOffsets_[currentPage_->getCollectionName()] = currentPage_->getScrollOffsetIndex();
currentPage_->popCollection(); currentPage_->popCollection();
config_.setProperty("currentCollection", currentPage_->getCollectionName()); config_.setProperty("currentCollection", currentPage_->getCollectionName());
currentPage_->setNewItemSelected();
currentPage_->enterMenu();
state = RETROFE_BACK_MENU_ENTER;
}
break;
state = RETROFE_NEW; case RETROFE_BACK_MENU_ENTER:
if(currentPage_->isIdle())
break; {
state = RETROFE_IDLE;
}
break;
case RETROFE_NEW: case RETROFE_NEW:
if(currentPage_->isIdle()) if(currentPage_->isIdle())
@ -356,11 +424,10 @@ void RetroFE::run()
break; break;
case RETROFE_QUIT: case RETROFE_QUIT:
if(currentPage_->isHidden()) if(currentPage_->isIdle())
{ {
running = false; running = false;
} }
break; break;
} }
@ -419,9 +486,6 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
bool exit = false; bool exit = false;
RETROFE_STATE state = RETROFE_IDLE; RETROFE_STATE state = RETROFE_IDLE;
bool rememberMenu = false;
config_.getProperty("rememberMenu", rememberMenu);
if(page->isHorizontalScroll()) if(page->isHorizontalScroll())
{ {
if (input_.keystate(UserInput::KeyCodeLeft)) if (input_.keystate(UserInput::KeyCodeLeft))
@ -441,7 +505,7 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
} }
if (input_.keystate(UserInput::KeyCodeDown)) if (input_.keystate(UserInput::KeyCodeDown))
{ {
page->setScrolling(Page::ScrollDirectionForward); page->setScrolling(Page::ScrollDirectionForward);
} }
} }
@ -514,27 +578,6 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
} }
else else
{ {
bool menuSort = true;
config_.setProperty("currentCollection", nextPageItem_->name);
config_.getProperty("collections." + nextPageItem_->name + ".list.menuSort", menuSort);
CollectionInfo *info = getCollection(nextPageItem_->name);
MenuParser mp;
mp.buildMenuItems(info, menuSort);
page->pushCollection(info);
if(rememberMenu && lastMenuOffsets_.find(nextPageItem_->name) != lastMenuOffsets_.end())
{
page->setScrollOffsetIndex(lastMenuOffsets_[nextPageItem_->name]);
}
bool autoFavorites = true;
config_.getProperty("autoFavorites", autoFavorites);
if (autoFavorites)
page->favPlaylist(); // Switch to favorites if it exists
state = RETROFE_NEXT_PAGE_REQUEST; state = RETROFE_NEXT_PAGE_REQUEST;
} }
} }

View File

@ -52,9 +52,15 @@ private:
enum RETROFE_STATE enum RETROFE_STATE
{ {
RETROFE_IDLE, RETROFE_IDLE,
RETROFE_ENTER,
RETROFE_EXIT,
RETROFE_NEXT_PAGE_REQUEST, RETROFE_NEXT_PAGE_REQUEST,
RETROFE_NEXT_PAGE_MENU_EXIT,
RETROFE_NEXT_PAGE_MENU_ENTER,
RETROFE_LAUNCH_REQUEST, RETROFE_LAUNCH_REQUEST,
RETROFE_BACK_REQUEST, RETROFE_BACK_REQUEST,
RETROFE_BACK_MENU_EXIT,
RETROFE_BACK_MENU_ENTER,
RETROFE_NEW, RETROFE_NEW,
RETROFE_QUIT_REQUEST, RETROFE_QUIT_REQUEST,
RETROFE_QUIT, RETROFE_QUIT,