Cleaned up the scrolling list code.

This commit is contained in:
Pieter Hulshoff 2017-06-30 11:41:25 +02:00
parent 1c155f710f
commit a7f50c9b03
4 changed files with 437 additions and 408 deletions

View File

@ -14,6 +14,7 @@
* along with RetroFE. If not, see <http://www.gnu.org/licenses/>. * along with RetroFE. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "ScrollingList.h" #include "ScrollingList.h"
#include "../Animate/Tween.h" #include "../Animate/Tween.h"
#include "../Animate/TweenSet.h" #include "../Animate/TweenSet.h"
@ -26,7 +27,7 @@
#include "VideoComponent.h" #include "VideoComponent.h"
#include "ReloadableMedia.h" #include "ReloadableMedia.h"
#include "Text.h" #include "Text.h"
#include "../../Database/Configuration.h" // todo: decouple the GUI from the data #include "../../Database/Configuration.h"
#include "../../Collection/Item.h" #include "../../Collection/Item.h"
#include "../../Utility/Utils.h" #include "../../Utility/Utils.h"
#include "../../Utility/Log.h" #include "../../Utility/Log.h"
@ -38,7 +39,7 @@
#include <cctype> #include <cctype>
#include <iomanip> #include <iomanip>
//todo: remove coupling from configuration data (if possible)
ScrollingList::ScrollingList( Configuration &c, ScrollingList::ScrollingList( Configuration &c,
Page &p, Page &p,
bool layoutMode, bool layoutMode,
@ -54,7 +55,6 @@ ScrollingList::ScrollingList(Configuration &c,
, scrollPoints_(NULL ) , scrollPoints_(NULL )
, tweenPoints_(NULL ) , tweenPoints_(NULL )
, itemIndex_(0 ) , itemIndex_(0 )
, componentIndex_(0)
, selectedOffsetIndex_(0 ) , selectedOffsetIndex_(0 )
, scrollAcceleration_(0 ) , scrollAcceleration_(0 )
, startScrollTime_(0.500 ) , startScrollTime_(0.500 )
@ -69,13 +69,13 @@ ScrollingList::ScrollingList(Configuration &c,
{ {
} }
ScrollingList::ScrollingList( const ScrollingList &copy ) ScrollingList::ScrollingList( const ScrollingList &copy )
: Component(copy ) : Component(copy )
, horizontalScroll(copy.horizontalScroll ) , horizontalScroll(copy.horizontalScroll )
, layoutMode_(copy.layoutMode_ ) , layoutMode_(copy.layoutMode_ )
, spriteList_(NULL ) , spriteList_(NULL )
, itemIndex_(0 ) , itemIndex_(0 )
, componentIndex_(0)
, selectedOffsetIndex_(copy.selectedOffsetIndex_ ) , selectedOffsetIndex_(copy.selectedOffsetIndex_ )
, scrollAcceleration_(copy.scrollAcceleration_ ) , scrollAcceleration_(copy.scrollAcceleration_ )
, startScrollTime_(copy.startScrollTime_ ) , startScrollTime_(copy.startScrollTime_ )
@ -111,12 +111,14 @@ void ScrollingList::setItems(std::vector<Item *> *items)
} }
} }
unsigned int ScrollingList::loopIncrement( unsigned int offset, unsigned int i, unsigned int size ) unsigned int ScrollingList::loopIncrement( unsigned int offset, unsigned int i, unsigned int size )
{ {
if ( size == 0 ) return 0; if ( size == 0 ) return 0;
return (offset + i ) % size; return (offset + i ) % size;
} }
unsigned int ScrollingList::loopDecrement( unsigned int offset, unsigned int i, unsigned int size ) unsigned int ScrollingList::loopDecrement( unsigned int offset, unsigned int i, unsigned int size )
{ {
if ( size == 0 ) return 0; if ( size == 0 ) return 0;
@ -129,11 +131,13 @@ void ScrollingList::setScrollAcceleration(float value)
scrollAcceleration_ = value; scrollAcceleration_ = value;
} }
void ScrollingList::setStartScrollTime( float value ) void ScrollingList::setStartScrollTime( float value )
{ {
startScrollTime_ = value; startScrollTime_ = value;
} }
void ScrollingList::deallocateSpritePoints( ) void ScrollingList::deallocateSpritePoints( )
{ {
for ( unsigned int i = 0; i < components_.size( ); ++i ) for ( unsigned int i = 0; i < components_.size( ); ++i )
@ -142,6 +146,7 @@ void ScrollingList::deallocateSpritePoints()
} }
} }
void ScrollingList::allocateSpritePoints( ) void ScrollingList::allocateSpritePoints( )
{ {
if ( !items_ || items_->size( ) == 0 ) return; if ( !items_ || items_->size( ) == 0 ) return;
@ -151,31 +156,28 @@ void ScrollingList::allocateSpritePoints()
for ( unsigned int i = 0; i < scrollPoints_->size( ); ++i ) for ( unsigned int i = 0; i < scrollPoints_->size( ); ++i )
{ {
unsigned int index = loopIncrement( itemIndex_, i, items_->size( ) ); unsigned int index = loopIncrement( itemIndex_, i, items_->size( ) );
unsigned int oindex = loopIncrement(componentIndex_, i, components_.size());
Item *item = items_->at( index ); Item *item = items_->at( index );
Component *o = components_.at(oindex); Component *old = components_.at( i );
allocateTexture(oindex, item); allocateTexture( i, item );
Component *c = components_.at(oindex); Component *c = components_.at( i );
ViewInfo *current = scrollPoints_->at(oindex); ViewInfo *view = scrollPoints_->at( i );
unsigned int nextI = loopIncrement(oindex, 1, scrollPoints_->size()); resetTweens( c, tweenPoints_->at( i ), view, view, 0 );
ViewInfo *next = scrollPoints_->at(nextI);
resetTweens(c, tweenPoints_->at(i), current, next, 0); if ( old )
if(o)
{ {
c->baseViewInfo = o->baseViewInfo; c->baseViewInfo = old->baseViewInfo;
delete o; delete old;
} }
} }
} }
void ScrollingList::destroyItems( ) void ScrollingList::destroyItems( )
{ {
for ( unsigned int i = 0; i < components_.size( ); ++i ) for ( unsigned int i = 0; i < components_.size( ); ++i )
@ -183,8 +185,6 @@ void ScrollingList::destroyItems()
delete components_.at( i ); delete components_.at( i );
components_.at( i ) = NULL; components_.at( i ) = NULL;
} }
componentIndex_ = 0;
} }
@ -198,7 +198,10 @@ void ScrollingList::setPoints(std::vector<ViewInfo *> *scrollPoints, std::vector
int size = 0; int size = 0;
if(scrollPoints) size = scrollPoints_->size(); if ( scrollPoints )
{
size = scrollPoints_->size( );
}
components_.resize( size ); components_.resize( size );
if ( items_ ) if ( items_ )
@ -207,41 +210,49 @@ void ScrollingList::setPoints(std::vector<ViewInfo *> *scrollPoints, std::vector
} }
} }
unsigned int ScrollingList::getScrollOffsetIndex( ) unsigned int ScrollingList::getScrollOffsetIndex( )
{ {
return itemIndex_; return loopIncrement( itemIndex_, selectedOffsetIndex_, items_->size( ) );
} }
void ScrollingList::setScrollOffsetIndex( unsigned int index ) void ScrollingList::setScrollOffsetIndex( unsigned int index )
{ {
itemIndex_ = index; itemIndex_ = loopDecrement( index, selectedOffsetIndex_, items_->size( ) );
} }
void ScrollingList::setSelectedIndex( int selectedIndex ) void ScrollingList::setSelectedIndex( int selectedIndex )
{ {
selectedOffsetIndex_ = selectedIndex; selectedOffsetIndex_ = selectedIndex;
} }
Item *ScrollingList::getItemByOffset( int offset ) Item *ScrollingList::getItemByOffset( int offset )
{ {
if ( !items_ || items_->size( ) == 0 ) return NULL; if ( !items_ || items_->size( ) == 0 ) return NULL;
unsigned int index = getSelectedIndex( ); unsigned int index = getSelectedIndex( );
if(offset > 0) { if ( offset >= 0 )
{
index = loopIncrement( index, offset, items_->size( ) ); index = loopIncrement( index, offset, items_->size( ) );
} }
else if(offset < 0) { else
{
index = loopDecrement( index, offset*-1, items_->size( ) ); index = loopDecrement( index, offset*-1, items_->size( ) );
} }
return items_->at( index ); return items_->at( index );
} }
Item *ScrollingList::getSelectedItem( ) Item *ScrollingList::getSelectedItem( )
{ {
if ( !items_ || items_->size( ) == 0 ) return NULL; if ( !items_ || items_->size( ) == 0 ) return NULL;
unsigned index = loopIncrement(itemIndex_, selectedOffsetIndex_, items_->size()); return items_->at( loopIncrement( itemIndex_, selectedOffsetIndex_, items_->size( ) ) );
return items_->at(index);
} }
@ -251,28 +262,33 @@ void ScrollingList::pageUp()
itemIndex_ = loopDecrement( itemIndex_, components_.size( ), items_->size( ) ); itemIndex_ = loopDecrement( itemIndex_, components_.size( ), items_->size( ) );
} }
void ScrollingList::pageDown( ) void ScrollingList::pageDown( )
{ {
if ( components_.size( ) == 0 ) return; if ( components_.size( ) == 0 ) return;
itemIndex_ = loopIncrement( itemIndex_, components_.size( ), items_->size( ) ); itemIndex_ = loopIncrement( itemIndex_, components_.size( ), items_->size( ) );
} }
void ScrollingList::random( ) void ScrollingList::random( )
{ {
if ( !items_ || items_->size( ) == 0 ) return; if ( !items_ || items_->size( ) == 0 ) return;
itemIndex_ = rand( ) % items_->size( ); itemIndex_ = rand( ) % items_->size( );
} }
void ScrollingList::letterUp( ) void ScrollingList::letterUp( )
{ {
letterChange( true ); letterChange( true );
} }
void ScrollingList::letterDown( ) void ScrollingList::letterDown( )
{ {
letterChange( false ); letterChange( false );
} }
void ScrollingList::letterChange( bool increment ) void ScrollingList::letterChange( bool increment )
{ {
@ -283,8 +299,14 @@ void ScrollingList::letterChange(bool increment)
for ( unsigned int i = 0; i < items_->size( ); ++i ) for ( unsigned int i = 0; i < items_->size( ); ++i )
{ {
unsigned int index = 0; unsigned int index = 0;
if(increment) index = loopIncrement(itemIndex_, i, items_->size()); if ( increment )
else index = loopDecrement(itemIndex_, i, items_->size()); {
index = loopIncrement( itemIndex_, i, items_->size( ) );
}
else
{
index = loopDecrement( itemIndex_, i, items_->size( ) );
}
std::string endname = items_->at( (index+selectedOffsetIndex_ ) % items_->size( ) )->lowercaseFullTitle( ); std::string endname = items_->at( (index+selectedOffsetIndex_ ) % items_->size( ) )->lowercaseFullTitle( );
@ -426,18 +448,19 @@ void ScrollingList::update(float dt)
for ( unsigned int i = 0; i < scrollPoints_->size( ); i++ ) for ( unsigned int i = 0; i < scrollPoints_->size( ); i++ )
{ {
unsigned int cindex = loopIncrement(componentIndex_, i, components_.size()); Component *c = components_.at( i );
Component *c = components_.at(cindex);
if ( c ) c->update(dt ); if ( c ) c->update(dt );
} }
} }
unsigned int ScrollingList::getSelectedIndex( ) unsigned int ScrollingList::getSelectedIndex( )
{ {
if ( !items_ ) return 0; if ( !items_ ) return 0;
return loopIncrement( itemIndex_, selectedOffsetIndex_, items_->size( ) ); return loopIncrement( itemIndex_, selectedOffsetIndex_, items_->size( ) );
} }
void ScrollingList::setSelectedIndex( unsigned int index ) void ScrollingList::setSelectedIndex( unsigned int index )
{ {
if ( !items_ ) return; if ( !items_ ) return;
@ -448,10 +471,10 @@ void ScrollingList::setSelectedIndex(unsigned int index)
unsigned int ScrollingList::getSize( ) unsigned int ScrollingList::getSize( )
{ {
if ( !items_ ) return 0; if ( !items_ ) return 0;
return items_->size( ); return items_->size( );
} }
void ScrollingList::resetTweens( Component *c, AnimationEvents *sets, ViewInfo *currentViewInfo, ViewInfo *nextViewInfo, double scrollTime ) void ScrollingList::resetTweens( Component *c, AnimationEvents *sets, ViewInfo *currentViewInfo, ViewInfo *nextViewInfo, double scrollTime )
{ {
if ( !c ) return; if ( !c ) return;
@ -465,7 +488,6 @@ void ScrollingList::resetTweens(Component *c, AnimationEvents *sets, ViewInfo *c
nextViewInfo->ImageWidth = c->baseViewInfo.ImageWidth; nextViewInfo->ImageWidth = c->baseViewInfo.ImageWidth;
nextViewInfo->BackgroundAlpha = c->baseViewInfo.BackgroundAlpha; nextViewInfo->BackgroundAlpha = c->baseViewInfo.BackgroundAlpha;
//todo: delete properly, memory leak (big), proof of concept
c->setTweens(sets ); c->setTweens(sets );
Animation *scrollTween = sets->getAnimation("menuScroll" ); Animation *scrollTween = sets->getAnimation("menuScroll" );
@ -497,9 +519,6 @@ bool ScrollingList::allocateTexture(unsigned int index, Item *item)
if ( index >= components_.size( ) ) return false; if ( index >= components_.size( ) ) return false;
//todo: will create a runtime fault if not of the right type
//todo: remove coupling from knowing the collection name
std::string videoKey ="collections." + collectionName + ".media.video"; std::string videoKey ="collections." + collectionName + ".media.video";
std::string imagePath; std::string imagePath;
std::string videoPath; std::string videoPath;
@ -626,6 +645,7 @@ bool ScrollingList::allocateTexture(unsigned int index, Item *item)
return true; return true;
} }
void ScrollingList::deallocateTexture( unsigned int index ) void ScrollingList::deallocateTexture( unsigned int index )
{ {
if ( components_.size( ) <= index ) return; if ( components_.size( ) <= index ) return;
@ -644,6 +664,7 @@ void ScrollingList::draw()
// caller should instead call ScrollingList::Draw( unsigned int layer ) // caller should instead call ScrollingList::Draw( unsigned int layer )
} }
void ScrollingList::draw( unsigned int layer ) void ScrollingList::draw( unsigned int layer )
{ {
@ -692,27 +713,28 @@ void ScrollingList::scroll(bool forward)
{ {
if ( !items_ || items_->size( ) == 0 ) return; if ( !items_ || items_->size( ) == 0 ) return;
if ( !scrollPoints_ || scrollPoints_->size( ) == 0 ) return;
// Replace the item that's scrolled out
if ( forward ) if ( forward )
{ {
Item *i = items_->at( loopIncrement( itemIndex_, scrollPoints_->size( ), items_->size( ) ) ); Item *i = items_->at( loopIncrement( itemIndex_, scrollPoints_->size( ), items_->size( ) ) );
deallocateTexture(componentIndex_); itemIndex_ = loopIncrement( itemIndex_, 1, items_->size( ) );
allocateTexture(componentIndex_, i); deallocateTexture( 0 );
allocateTexture( 0, i );
} }
else else
{ {
Item *i = items_->at( loopDecrement( itemIndex_, 1, items_->size( ) ) ); Item *i = items_->at( loopDecrement( itemIndex_, 1, items_->size( ) ) );
deallocateTexture(loopDecrement(componentIndex_, 1, components_.size())); itemIndex_ = loopDecrement( itemIndex_, 1, items_->size( ) );
allocateTexture(loopDecrement(componentIndex_, 1, components_.size()), i); deallocateTexture( loopDecrement( 0, 1, components_.size( ) ) );
allocateTexture( loopDecrement( 0, 1, components_.size( ) ), i );
} }
// Set the animations
for ( unsigned int i = 0; i < scrollPoints_->size( ); i++ ) for ( unsigned int i = 0; i < scrollPoints_->size( ); i++ )
{ {
unsigned int cindex = loopIncrement(componentIndex_, i, components_.size()); unsigned int nextI;
Component *c = components_.at(cindex);
unsigned int nextI = 0;
if ( forward ) if ( forward )
{ {
nextI = loopDecrement( i, 1, scrollPoints_->size( ) ); nextI = loopDecrement( i, 1, scrollPoints_->size( ) );
@ -722,24 +744,36 @@ void ScrollingList::scroll(bool forward)
nextI = loopIncrement( i, 1, scrollPoints_->size( ) ); nextI = loopIncrement( i, 1, scrollPoints_->size( ) );
} }
ViewInfo *currentvi = scrollPoints_->at(i); Component *c = components_.at( i );
ViewInfo *nextvi = scrollPoints_->at(nextI);
resetTweens resetTweens( c, tweenPoints_->at( nextI ), scrollPoints_->at( i ), scrollPoints_->at( nextI ), scrollPeriod_ );
(c, tweenPoints_->at(nextI), currentvi, nextvi, scrollPeriod_); c->baseViewInfo.font = scrollPoints_->at( nextI )->font; // Use the font settings of the next index
c->baseViewInfo.font = nextvi->font; // Use the font settings of the next index
c->triggerEvent( "menuScroll" ); c->triggerEvent( "menuScroll" );
} }
// Reorder the components
Component *c = components_.at( 0 );
if ( forward ) if ( forward )
{ {
itemIndex_ = loopIncrement(itemIndex_, 1, items_->size()); for ( unsigned int i = scrollPoints_->size( ); i > 0; i-- )
componentIndex_ = loopIncrement(componentIndex_, 1, components_.size()); {
unsigned int prevI = loopDecrement( i, 1, scrollPoints_->size( ) );
Component *store = components_.at( prevI );
components_[prevI] = c;
c = store;
}
} }
else else
{ {
itemIndex_ = loopDecrement(itemIndex_, 1, items_->size()); for ( unsigned int i = 0; i < scrollPoints_->size( ); i++ )
componentIndex_ = loopDecrement(componentIndex_, 1, components_.size()); {
unsigned int nextI = loopIncrement( i, 1, scrollPoints_->size( ) );
Component *store = components_.at( nextI );
components_[nextI] = c;
c = store;
}
} }
return; return;

View File

@ -15,6 +15,7 @@
*/ */
#pragma once #pragma once
#include <vector> #include <vector>
#include "Component.h" #include "Component.h"
#include "../Animate/Tween.h" #include "../Animate/Tween.h"
@ -24,16 +25,14 @@
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
//todo: This scrolling implementation needs to be overhauled
// It needs to have a common interface to support different menu types
// (It was originally sandbox code that creeped into here)
class Configuration; class Configuration;
class Font; class Font;
class ScrollingList : public Component class ScrollingList : public Component
{ {
public: public:
ScrollingList( Configuration &c, ScrollingList( Configuration &c,
Page &p, Page &p,
bool layoutMode, bool layoutMode,
@ -88,8 +87,8 @@ public:
void updateScrollPeriod( ); void updateScrollPeriod( );
void scroll( bool forward ); void scroll( bool forward );
private: private:
void resetTweens( Component *c, AnimationEvents *sets, ViewInfo *currentViewInfo, ViewInfo *nextViewInfo, double scrollTime ); 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 loopIncrement( unsigned int offset, unsigned int i, unsigned int size );
unsigned int loopDecrement( unsigned int offset, unsigned int i, unsigned int size ); unsigned int loopDecrement( unsigned int offset, unsigned int i, unsigned int size );
@ -100,7 +99,6 @@ private:
std::vector<AnimationEvents *> *tweenPoints_; std::vector<AnimationEvents *> *tweenPoints_;
unsigned int itemIndex_; unsigned int itemIndex_;
unsigned int componentIndex_;
unsigned int selectedOffsetIndex_; unsigned int selectedOffsetIndex_;
float scrollAcceleration_; float scrollAcceleration_;
@ -114,10 +112,7 @@ private:
std::string layoutKey_; std::string layoutKey_;
std::string imageType_; std::string imageType_;
std::vector<Item *> *items_; std::vector<Item *> *items_;
std::vector<Component *> components_; std::vector<Component *> components_;
}; };

View File

@ -529,11 +529,11 @@ void Page::selectRandom()
if(activeMenu_.size() > 0 && activeMenu_[0]) if(activeMenu_.size() > 0 && activeMenu_[0])
{ {
activeMenu_[0]->random(); activeMenu_[0]->random();
unsigned int index = activeMenu_[0]->getSelectedIndex(); unsigned int index = activeMenu_[0]->getScrollOffsetIndex();
for(std::vector<ScrollingList *>::iterator it = activeMenu_.begin(); it != activeMenu_.end(); it++) for(std::vector<ScrollingList *>::iterator it = activeMenu_.begin(); it != activeMenu_.end(); it++)
{ {
ScrollingList *menu = *it; ScrollingList *menu = *it;
menu->setSelectedIndex(index); menu->setScrollOffsetIndex(index);
} }
} }
} }

View File

@ -21,7 +21,7 @@
std::string retrofe_version_major = "0"; std::string retrofe_version_major = "0";
std::string retrofe_version_minor = "8"; std::string retrofe_version_minor = "8";
std::string retrofe_version_build = "9"; std::string retrofe_version_build = "10";
std::string Version::getString( ) std::string Version::getString( )