Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add grid view scroll sound and adjust sound theming #669

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions THEMES.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,12 @@ Reference
- A header image. If a non-empty `path` is specified, `text name="logoText"` will be hidden and this image will be, by default, displayed roughly in its place.
* `textlist name="gamelist"` - ALL
- The gamelist. `primaryColor` is for games, `secondaryColor` is for folders. Centered by default.

* `sound name="launch"` - ALL
- The sound to be played when launching a game or entering a folder
* `sound name="back"` - ALL
- The sound to be played when going back to system menu or exiting a folder
* `sound name="scroll"` - ALL
- The sound to be played when scrolling the game list
---

#### detailed
Expand All @@ -375,6 +380,12 @@ Reference
- A header image. If a non-empty `path` is specified, `text name="logoText"` will be hidden and this image will be, by default, displayed roughly in its place.
* `textlist name="gamelist"` - ALL
- The gamelist. `primaryColor` is for games, `secondaryColor` is for folders. Left aligned by default.
* `sound name="launch"` - ALL
- The sound to be played when launching a game or entering a folder
* `sound name="back"` - ALL
- The sound to be played when going back to system menu or exiting a folder
* `sound name="scroll"` - ALL
- The sound to be played when scrolling the game list

* Metadata
* Labels
Expand Down Expand Up @@ -424,6 +435,12 @@ Reference
- A header image. If a non-empty `path` is specified, `text name="logoText"` will be hidden and this image will be, by default, displayed roughly in its place.
* `textlist name="gamelist"` - ALL
- The gamelist. `primaryColor` is for games, `secondaryColor` is for folders. Left aligned by default.
* `sound name="launch"` - ALL
- The sound to be played when launching a game or entering a folder
* `sound name="back"` - ALL
- The sound to be played when going back to system menu or exiting a folder
* `sound name="scroll"` - ALL
- The sound to be played when scrolling the game list

* Metadata
* Labels
Expand Down Expand Up @@ -483,6 +500,12 @@ Reference
- Note that many of the default gridtile parameters change the selected gridtile parameters if they are not explicitly set by the theme. For example, changing the background image of the default gridtile also change the background image of the selected gridtile. Refer to the gridtile documentation for more informations.
* `gridtile name="selected"` - ALL
- See default gridtile description right above.
* `sound name="launch"` - ALL
- The sound to be played when launching a game or entering a folder
* `sound name="back"` - ALL
- The sound to be played when going back to system menu or exiting a folder
* `sound name="scroll"` - ALL
- The sound to be played when scrolling the game list

* Metadata
* Labels
Expand Down Expand Up @@ -532,6 +555,10 @@ Reference
- A logo text, to be displayed system name in the system logo carousel when no logo is available.
* `text name="systemInfo"` - ALL
- Displays details of the system currently selected in the carousel.
* `sound name="launch"` - ALL
- The sound to be played when a system is selected
* `sound name="scroll"` - ALL
- The sound to be played when scrolling the system list
* You can use extra elements (elements with `extra="true"`) to add your own backgrounds, etc. They will be displayed behind the carousel, and scroll relative to the carousel.


Expand Down Expand Up @@ -713,7 +740,7 @@ Can be created as an extra.
* `fontPath` - type: PATH.
* `fontSize` - type: FLOAT.
* `scrollSound` - type: PATH.
- Sound that is played when the list is scrolled.
- **Deprecated**: Use global property `sound name="scroll"` instead. Sound that is played when the list is scrolled.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I read the code. This still works, which is a good choice, but I imagine that the majority of themes use this, so I'd rather not mark this as deprecated but rather as a fallback option (which seems to be what the code uses it for).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New themes should use global property sound name="scroll", "scrollSound" can still be used for backward compatibility. Maybe "deprecated" is not the right word, if you have a better suggestion I will take it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a fallback, I suppose - if you don't have a global setting defined for the system, it will use this one. I like the way you explain it - it can still be used for backward compatibility.

I don't have a strong opinion, but I'm mindful of there existing hundreds of themes right now, potentially using the previous syntax, and on the flipside, not wanting to risk this being effectively removed at some point.

* `alignment` - type: STRING.
- Valid values are "left", "center", or "right". Controls alignment on the X axis.
* `horizontalMargin` - type: FLOAT.
Expand Down
3 changes: 2 additions & 1 deletion es-app/src/components/TextListComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ void TextListComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme, c
const float selectorHeight = Math::max(mFont->getHeight(1.0), (float)mFont->getSize()) * mLineSpacing;
setSelectorHeight(selectorHeight);

if(properties & SOUND && elem->has("scrollSound"))
mScrollSound = Sound::getPath(theme, view, "scroll");
if(mScrollSound.empty() && properties & SOUND && elem->has("scrollSound"))
mScrollSound = elem->get<std::string>("scrollSound");

if(properties & ALIGNMENT)
Expand Down
26 changes: 19 additions & 7 deletions es-app/src/views/SystemView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "Settings.h"
#include "SystemData.h"
#include "Window.h"
#include "Sound.h"

// buffer values for scrolling velocity (left, stopped, right)
const int logoBuffersLeft[] = { -5, -2, -1 };
Expand Down Expand Up @@ -151,12 +152,14 @@ bool SystemView::input(InputConfig* config, Input input)
case VERTICAL_WHEEL:
if (config->isMappedLike("up", input))
{
listInput(-1);
if (listInput(-1))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In what cases will listInput return false in the wheel - doesn't it loop around? Is the "if" needed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

listInput return lastCursorPos != newCursorPos so it made sense to me to handle it like this, to directly tie the scroll sound to the "cursor changed position" event. Maybe I can add an intermediary var to make the code look more explicit. That or maybe put the scroll sound up in the IList, since ImageGridComponent, TextListComponent and SystemView all inherit from the IList. The pb is the IList don't have anything to do with theme, so that would have to be set from the child class.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. I suppose you're using the "if" to cater for the case where the list only has one item, so that the sound doesn't play if the same element stays selected.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idk if there is other edge case where this can happen. But I think it's more logic to tie the scroll sound to if the cursor moved or not, than tie it directly to user input.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

Sound::get(mScrollSound)->play();
return true;
}
if (config->isMappedLike("down", input))
{
listInput(1);
if (listInput(1))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment.

Sound::get(mScrollSound)->play();
return true;
}
break;
Expand All @@ -165,19 +168,22 @@ bool SystemView::input(InputConfig* config, Input input)
default:
if (config->isMappedLike("left", input))
{
listInput(-1);
if (listInput(-1))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same - won't repeat for the others.

Sound::get(mScrollSound)->play();
return true;
}
if (config->isMappedLike("right", input))
{
listInput(1);
if (listInput(1))
Sound::get(mScrollSound)->play();
return true;
}
break;
}

if(config->isMappedTo("a", input))
{
Sound::get(mLaunchSound)->play();
stopScrolling();
ViewController::get()->goToGameList(getSelected());
return true;
Expand All @@ -186,15 +192,18 @@ bool SystemView::input(InputConfig* config, Input input)
{
// get random system
// go to system
setCursor(SystemData::getRandomSystem());
if (setCursor(SystemData::getRandomSystem()))
Sound::get(mScrollSound)->play();
return true;
}
}else{
if(config->isMappedLike("left", input) ||
config->isMappedLike("right", input) ||
config->isMappedLike("up", input) ||
config->isMappedLike("down", input))
listInput(0);
config->isMappedLike("down", input)) {
if (listInput(0))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we playing the sound on scroll and on stopping the scroll? I believe this is run when the button is released - is this deliberate?

Sound::get(mScrollSound)->play();
}
if(!UIModeController::getInstance()->isUIModeKid() && config->isMappedTo("select", input) && Settings::getInstance()->getBool("ScreenSaverControls"))
{
mWindow->startScreenSaver();
Expand Down Expand Up @@ -419,6 +428,9 @@ void SystemView::getViewElements(const std::shared_ptr<ThemeData>& theme)
if (sysInfoElem)
mSystemInfo.applyTheme(theme, "system", "systemInfo", ThemeFlags::ALL);

mScrollSound = Sound::getPath(theme, "system", "scroll");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These seem to be set in applyTheme - is there a case where sysInfoElem doesn't exist yet we'll reload these sounds without applying the theme?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry - just re-read: probably it's the other way around - you only want to set these if the new theme is applied, then (meaning, inside the if)?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "if" is only there to make sure the ThemeElement is not null, Sound::getPath already do that check and return an empty string if it happen.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that the getPath getter is safe. Still, unless there is a use case for the sound to be updated when the theme is not, this is a case where these should be inside the if.

I take it that mScrollSound and mLaunchSound are initialized somewhere else with default values.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you mean. The 2 "if" that we see before just check if the theme element is here and if it is, it is applied. The "systemInfo" is just a sub element of the system theme, just like the sound.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it - nevermind.

mLaunchSound = Sound::getPath(theme, "system", "launch");

mViewNeedsReload = false;
}

Expand Down
2 changes: 2 additions & 0 deletions es-app/src/views/SystemView.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ class SystemView : public IList<SystemViewData, SystemData*>

bool mViewNeedsReload;
bool mShowing;
std::string mScrollSound;
std::string mLaunchSound;
};

#endif // ES_APP_VIEWS_SYSTEM_VIEW_H
3 changes: 2 additions & 1 deletion es-app/src/views/gamelist/ISimpleGameListView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
// it's a folder
if(cursor->getChildren().size() > 0)
{
Sound::getFromTheme(getTheme(), getName(), "launch")->play();
mCursorStack.push(cursor);
populateList(cursor->getChildrenListToDisplay());
FileData* cursor = getCursor();
Expand All @@ -101,12 +102,12 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
return true;
}else if(config->isMappedTo("b", input))
{
Sound::getFromTheme(getTheme(), getName(), "back")->play();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a change in the feature set - can you elaborate? It seems we're now adding the "back" sound when changing from the system view to the carousel.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the game* view to the system* view.

if(mCursorStack.size())
{
populateList(mCursorStack.top()->getParent()->getChildren());
setCursor(mCursorStack.top());
mCursorStack.pop();
Sound::getFromTheme(getTheme(), getName(), "back")->play();
}else{
onFocusLost();
SystemData* systemToView = getCursor()->getSystem();
Expand Down
11 changes: 8 additions & 3 deletions es-core/src/Sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,23 @@ std::shared_ptr<Sound> Sound::get(const std::string& path)
return sound;
}

std::shared_ptr<Sound> Sound::getFromTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element)
const std::string Sound::getPath(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element)
{
LOG(LogInfo) << " req sound [" << view << "." << element << "]";

const ThemeData::ThemeElement* elem = theme->getElement(view, element, "sound");
if(!elem || !elem->has("path"))
{
LOG(LogInfo) << " (missing)";
return get("");
return "";
}

return get(elem->get<std::string>("path"));
return elem->get<std::string>("path");
}

std::shared_ptr<Sound> Sound::getFromTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element)
{
return get(getPath(theme, view, element));
}

Sound::Sound(const std::string & path) : mSampleData(NULL), mSamplePos(0), mSampleLength(0), playing(false)
Expand Down
3 changes: 2 additions & 1 deletion es-core/src/Sound.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ class Sound

public:
static std::shared_ptr<Sound> get(const std::string& path);
static std::shared_ptr<Sound> getFromTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& elem);
static const std::string getPath(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element);
static std::shared_ptr<Sound> getFromTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element);

~Sound();

Expand Down
5 changes: 5 additions & 0 deletions es-core/src/components/ImageGridComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "components/IList.h"
#include "resources/TextureResource.h"
#include "GridTileComponent.h"
#include "Sound.h"

#define EXTRAITEMS 2

Expand Down Expand Up @@ -63,6 +64,7 @@ class ImageGridComponent : public IList<ImageGridData, T>
ImageSource getImageSource() { return mImageSource; };

protected:
virtual void onScroll(int /*amt*/) { if(!mScrollSound.empty()) Sound::get(mScrollSound)->play(); }
virtual void onCursorChanged(const CursorState& state) override;

private:
Expand Down Expand Up @@ -91,6 +93,7 @@ class ImageGridComponent : public IList<ImageGridData, T>
Vector2f mMargin;
Vector2f mTileSize;
Vector2i mGridDimension;
std::string mScrollSound;
std::shared_ptr<ThemeData> mTheme;
std::vector< std::shared_ptr<GridTileComponent> > mTiles;

Expand Down Expand Up @@ -300,6 +303,8 @@ void ImageGridComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
else
mAnimate = true;

mScrollSound = Sound::getPath(theme, view, "scroll");

if (elem->has("gameImage"))
{
std::string path = elem->get<std::string>("gameImage");
Expand Down