diff --git a/CMakeLists.txt b/CMakeLists.txt index 98ebd288c0..71d987bcc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,6 +141,7 @@ set(ES_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/FileData.h ${CMAKE_CURRENT_SOURCE_DIR}/src/FileSorts.h ${CMAKE_CURRENT_SOURCE_DIR}/src/GuiComponent.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/HelpStyle.h ${CMAKE_CURRENT_SOURCE_DIR}/src/HttpReq.h ${CMAKE_CURRENT_SOURCE_DIR}/src/ImageIO.h ${CMAKE_CURRENT_SOURCE_DIR}/src/InputConfig.h @@ -232,6 +233,7 @@ set(ES_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/FileData.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/FileSorts.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/GuiComponent.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/HelpStyle.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/HttpReq.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/ImageIO.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/InputConfig.cpp diff --git a/THEMES.md b/THEMES.md index bff94baf87..d8a9b9e7dd 100644 --- a/THEMES.md +++ b/THEMES.md @@ -270,6 +270,8 @@ Reference ## Views, their elements, and themable properties: #### basic +* `helpsystem name="help"` - ALL + - The help system style for this view. * `image name="background"` - ALL - This is a background image that exists for convenience. It goes from (0, 0) to (1, 1). * `text name="logoText"` - ALL @@ -282,6 +284,8 @@ Reference --- #### detailed +* `helpsystem name="help"` - ALL + - The help system style for this view. * `image name="background"` - ALL - This is a background image that exists for convenience. It goes from (0, 0) to (1, 1). * `text name="logoText"` - ALL @@ -329,6 +333,8 @@ Reference --- #### grid +* `helpsystem name="help"` - ALL + - The help system style for this view. * `image name="background"` - ALL - This is a background image that exists for convenience. It goes from (0, 0) to (1, 1). * `text name="logoText"` - ALL @@ -339,32 +345,12 @@ Reference --- #### system +* `helpsystem name="help"` - ALL + - The help system style for this view. * `image name="logo"` - PATH - A logo image, to be displayed in the system logo carousel. * 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. ---- - -#### fastSelect -* `ninepatch name="windowBackground"` - PATH - - Fit around the fast select UI as a background. -* `text name="letter"` - FONT_PATH | COLOR - - The big letter that shows what letter you'll jump to when you let go of the fast select button. -* `text name="subtext"` - FONT_PATH | COLOR - - The text that displays the current sort mode. - ---- - -#### menu -* `ninepatch name="windowBackground"` - PATH - - Background for the menu. Fit from top-left corner at (0.175, 0.05) to bottom-right corner at (0.825, 0.95). -* `textlist name="menulist"` - FONT_PATH | COLOR | SOUND - - The list of menu options. `primaryColor` is for most options, `secondaryColor` is for the "shutdown" option. -* `sound name="menuOpen"` - PATH - - Played when the menu opens. -* `sound name="menuClose"` - PATH - - Played when the menu closes. - ## Types of properties: @@ -479,7 +465,14 @@ EmulationStation borrows the concept of "nine patches" from Android (or "9-Slice * `path` - type: PATH. - Path to the sound file. Only .wav files are currently supported. +#### helpsystem + +* `pos` - type: NORMALIZED_PAIR. +* `textColor` - type: COLOR. +* `fontPath` - type: PATH. +* `fontSize` - type: FLOAT. +The help system is a special element that displays a context-sensitive list of actions the user can take at any time. You should try and keep the position constant throughout every screen. Keep in mind the "default" settings (including position) are used whenever the user opens a menu. [*Check out the "official" themes for some more examples!*](http://aloshi.com/emulationstation#themes) diff --git a/src/GuiComponent.cpp b/src/GuiComponent.cpp index 8ef8aa3810..9adf9d36eb 100644 --- a/src/GuiComponent.cpp +++ b/src/GuiComponent.cpp @@ -169,7 +169,7 @@ void GuiComponent::setOpacity(unsigned char opacity) } } -const Eigen::Affine3f GuiComponent::getTransform() +const Eigen::Affine3f& GuiComponent::getTransform() { mTransform.setIdentity(); mTransform.translate(mPosition); @@ -325,5 +325,10 @@ void GuiComponent::updateHelpPrompts() std::vector prompts = getHelpPrompts(); if(mWindow->peekGui() == this) - mWindow->setHelpPrompts(prompts); + mWindow->setHelpPrompts(prompts, getHelpStyle()); +} + +HelpStyle GuiComponent::getHelpStyle() +{ + return HelpStyle(); } diff --git a/src/GuiComponent.h b/src/GuiComponent.h index 4ccfc6d03d..c1b385a635 100644 --- a/src/GuiComponent.h +++ b/src/GuiComponent.h @@ -1,14 +1,15 @@ -#ifndef _GUICOMPONENT_H_ -#define _GUICOMPONENT_H_ +#pragma once #include "InputConfig.h" #include #include +#include "HelpStyle.h" class Window; class Animation; class AnimationController; class ThemeData; +class Font; typedef std::pair HelpPrompt; @@ -69,7 +70,7 @@ class GuiComponent virtual unsigned char getOpacity() const; virtual void setOpacity(unsigned char opacity); - const Eigen::Affine3f getTransform(); + const Eigen::Affine3f& getTransform(); virtual std::string getValue() const; virtual void setValue(const std::string& value); @@ -86,6 +87,8 @@ class GuiComponent // Called whenever help prompts change. void updateHelpPrompts(); + + virtual HelpStyle getHelpStyle(); protected: void renderChildren(const Eigen::Affine3f& transform) const; @@ -106,5 +109,3 @@ class GuiComponent Eigen::Affine3f mTransform; //Don't access this directly! Use getTransform()! AnimationController* mAnimationMap[MAX_ANIMATIONS]; }; - -#endif diff --git a/src/HelpStyle.cpp b/src/HelpStyle.cpp new file mode 100644 index 0000000000..4d4f5999f1 --- /dev/null +++ b/src/HelpStyle.cpp @@ -0,0 +1,28 @@ +#include "HelpStyle.h" +#include "ThemeData.h" +#include "Renderer.h" +#include "resources/Font.h" + +HelpStyle::HelpStyle() +{ + position = Eigen::Vector2f(12.0f, Renderer::getScreenHeight() * 0.955f); + iconColor = 0x777777FF; + textColor = 0x777777FF; + font = Font::get(FONT_SIZE_SMALL); +} + +void HelpStyle::applyTheme(const std::shared_ptr& theme, const std::string& view) +{ + auto elem = theme->getElement(view, "help", "helpsystem"); + if(!elem) + return; + + if(elem->has("pos")) + position = elem->get("pos").cwiseProduct(Eigen::Vector2f((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight())); + + if(elem->has("textColor")) + textColor = elem->get("textColor"); + + if(elem->has("fontPath") || elem->has("fontSize")) + font = Font::getFromTheme(elem, ThemeFlags::ALL, font); +} diff --git a/src/HelpStyle.h b/src/HelpStyle.h new file mode 100644 index 0000000000..204c444238 --- /dev/null +++ b/src/HelpStyle.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include +#include + +class ThemeData; +class Font; + +struct HelpStyle +{ + Eigen::Vector2f position; + unsigned int iconColor; + unsigned int textColor; + std::shared_ptr font; + + HelpStyle(); // default values + void applyTheme(const std::shared_ptr& theme, const std::string& view); +}; \ No newline at end of file diff --git a/src/ThemeData.cpp b/src/ThemeData.cpp index 775bb6a6d7..4dff3ee281 100644 --- a/src/ThemeData.cpp +++ b/src/ThemeData.cpp @@ -76,7 +76,12 @@ std::map< std::string, ElementMapType > ThemeData::sElementMap = boost::assign:: ("filledPath", PATH) ("unfilledPath", PATH))) ("sound", makeMap(boost::assign::map_list_of - ("path", PATH))); + ("path", PATH))) + ("helpsystem", makeMap(boost::assign::map_list_of + ("pos", NORMALIZED_PAIR) + ("textColor", COLOR) + ("fontPath", PATH) + ("fontSize", FLOAT))); namespace fs = boost::filesystem; diff --git a/src/Window.cpp b/src/Window.cpp index d67c8262a8..fcfdb5e1f8 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -37,7 +37,7 @@ Window::~Window() void Window::pushGui(GuiComponent* gui) { mGuiStack.push_back(gui); - setHelpPrompts(gui->getHelpPrompts()); + gui->updateHelpPrompts(); } void Window::removeGui(GuiComponent* gui) @@ -49,7 +49,7 @@ void Window::removeGui(GuiComponent* gui) i = mGuiStack.erase(i); if(i == mGuiStack.end() && mGuiStack.size()) // we just popped the stack and the stack is not empty - setHelpPrompts(mGuiStack.back()->getHelpPrompts()); + mGuiStack.back()->updateHelpPrompts(); return; } @@ -88,7 +88,7 @@ bool Window::init(unsigned int width, unsigned int height) // update our help because font sizes probably changed if(peekGui()) - setHelpPrompts(peekGui()->getHelpPrompts()); + peekGui()->updateHelpPrompts(); return true; } @@ -257,9 +257,10 @@ void Window::renderHelpPromptsEarly() mRenderedHelpPrompts = true; } -void Window::setHelpPrompts(const std::vector& prompts) +void Window::setHelpPrompts(const std::vector& prompts, const HelpStyle& style) { mHelp->clearPrompts(); + mHelp->setStyle(style); std::vector addPrompts; diff --git a/src/Window.h b/src/Window.h index 752ee66fd6..6a007610ee 100644 --- a/src/Window.h +++ b/src/Window.h @@ -38,7 +38,7 @@ class Window void renderLoadingScreen(); void renderHelpPromptsEarly(); // used by ViewController to render HelpPrompts before a fade - void setHelpPrompts(const std::vector& prompts); + void setHelpPrompts(const std::vector& prompts, const HelpStyle& style); private: ViewController* mViewController; diff --git a/src/components/HelpComponent.cpp b/src/components/HelpComponent.cpp index 6cd83710e4..36a110184b 100644 --- a/src/components/HelpComponent.cpp +++ b/src/components/HelpComponent.cpp @@ -46,6 +46,12 @@ void HelpComponent::setPrompts(const std::vector& prompts) updateGrid(); } +void HelpComponent::setStyle(const HelpStyle& style) +{ + mStyle = style; + updateGrid(); +} + void HelpComponent::updateGrid() { if(!Settings::getInstance()->getBool("ShowHelpPrompts") || mPrompts.empty()) @@ -54,10 +60,10 @@ void HelpComponent::updateGrid() return; } + std::shared_ptr& font = mStyle.font; + mGrid = std::make_shared(mWindow, Vector2i(mPrompts.size() * 4, 1)); // [icon] [spacer1] [text] [spacer2] - - std::shared_ptr font = Font::get(FONT_SIZE_SMALL); std::vector< std::shared_ptr > icons; std::vector< std::shared_ptr > labels; @@ -71,7 +77,7 @@ void HelpComponent::updateGrid() icon->setResize(0, height); icons.push_back(icon); - auto lbl = std::make_shared(mWindow, strToUpper(it->second), font, 0x777777FF); + auto lbl = std::make_shared(mWindow, strToUpper(it->second), font, mStyle.textColor); labels.push_back(lbl); width += icon->getSize().x() + lbl->getSize().x() + ICON_TEXT_SPACING + ENTRY_SPACING; @@ -89,7 +95,8 @@ void HelpComponent::updateGrid() mGrid->setEntry(labels.at(i), Vector2i(col + 2, 0), false, false); } - mGrid->setPosition(OFFSET_X, Renderer::getScreenHeight() - mGrid->getSize().y() - OFFSET_Y); + mGrid->setPosition(Eigen::Vector3f(mStyle.position.x(), mStyle.position.y(), 0.0f)); + //mGrid->setPosition(OFFSET_X, Renderer::getScreenHeight() - mGrid->getSize().y() - OFFSET_Y); } std::shared_ptr HelpComponent::getIconTexture(const char* name) diff --git a/src/components/HelpComponent.h b/src/components/HelpComponent.h index 7a3a6ef062..cd30be666c 100644 --- a/src/components/HelpComponent.h +++ b/src/components/HelpComponent.h @@ -1,6 +1,7 @@ #pragma once #include "../GuiComponent.h" +#include "../HelpStyle.h" class ImageComponent; class TextureResource; @@ -17,6 +18,8 @@ class HelpComponent : public GuiComponent void render(const Eigen::Affine3f& parent) override; void setOpacity(unsigned char opacity) override; + void setStyle(const HelpStyle& style); + private: std::shared_ptr getIconTexture(const char* name); std::map< std::string, std::shared_ptr > mIconCache; @@ -25,4 +28,5 @@ class HelpComponent : public GuiComponent void updateGrid(); std::vector mPrompts; + HelpStyle mStyle; }; diff --git a/src/views/SystemView.cpp b/src/views/SystemView.cpp index c8d6ab2f05..67e3caa304 100644 --- a/src/views/SystemView.cpp +++ b/src/views/SystemView.cpp @@ -316,3 +316,10 @@ std::vector SystemView::getHelpPrompts() prompts.push_back(HelpPrompt("a", "select")); return prompts; } + +HelpStyle SystemView::getHelpStyle() +{ + HelpStyle style; + style.applyTheme(mEntries.at(mCursor).object->getTheme(), "system"); + return style; +} diff --git a/src/views/SystemView.h b/src/views/SystemView.h index 69bb4952c4..6916227e5a 100644 --- a/src/views/SystemView.h +++ b/src/views/SystemView.h @@ -29,7 +29,8 @@ class SystemView : public IList void render(const Eigen::Affine3f& parentTrans) override; std::vector getHelpPrompts() override; - + virtual HelpStyle getHelpStyle() override; + protected: void onCursorChanged(const CursorState& state) override; diff --git a/src/views/ViewController.cpp b/src/views/ViewController.cpp index 6eb81900e5..387119ec25 100644 --- a/src/views/ViewController.cpp +++ b/src/views/ViewController.cpp @@ -364,3 +364,11 @@ std::vector ViewController::getHelpPrompts() return prompts; } + +HelpStyle ViewController::getHelpStyle() +{ + if(!mCurrentView) + return GuiComponent::getHelpStyle(); + + return mCurrentView->getHelpStyle(); +} diff --git a/src/views/ViewController.h b/src/views/ViewController.h index 1eff1696c4..c706dbb410 100644 --- a/src/views/ViewController.h +++ b/src/views/ViewController.h @@ -60,6 +60,7 @@ class ViewController : public GuiComponent inline const State& getState() const { return mState; } virtual std::vector getHelpPrompts() override; + virtual HelpStyle getHelpStyle() override; std::shared_ptr getGameListView(SystemData* system); std::shared_ptr getSystemListView(); diff --git a/src/views/gamelist/IGameListView.cpp b/src/views/gamelist/IGameListView.cpp index dc2c39d627..9b9f59dbaa 100644 --- a/src/views/gamelist/IGameListView.cpp +++ b/src/views/gamelist/IGameListView.cpp @@ -34,3 +34,10 @@ void IGameListView::setTheme(const std::shared_ptr& theme) mTheme = theme; onThemeChanged(theme); } + +HelpStyle IGameListView::getHelpStyle() +{ + HelpStyle style; + style.applyTheme(mTheme, getName()); + return style; +} diff --git a/src/views/gamelist/IGameListView.h b/src/views/gamelist/IGameListView.h index b2229dfd77..930affa359 100644 --- a/src/views/gamelist/IGameListView.h +++ b/src/views/gamelist/IGameListView.h @@ -34,6 +34,8 @@ class IGameListView : public GuiComponent virtual bool input(InputConfig* config, Input input) override; virtual const char* getName() const = 0; + + virtual HelpStyle getHelpStyle() override; protected: FileData* mRoot; std::shared_ptr mTheme;