diff --git a/CMakeLists.txt b/CMakeLists.txt index 98ebd288c..71d987bcc 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 bff94baf8..d8a9b9e7d 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 8ef8aa381..9adf9d36e 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 4ccfc6d03..c1b385a63 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 @@ public: 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 @@ public: // Called whenever help prompts change. void updateHelpPrompts(); + + virtual HelpStyle getHelpStyle(); protected: void renderChildren(const Eigen::Affine3f& transform) const; @@ -106,5 +109,3 @@ private: 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 000000000..4d4f5999f --- /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 000000000..204c44423 --- /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 775bb6a6d..4dff3ee28 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 d67c8262a..fcfdb5e1f 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 752ee66fd..6a007610e 100644 --- a/src/Window.h +++ b/src/Window.h @@ -38,7 +38,7 @@ public: 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 6cd83710e..36a110184 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 7a3a6ef06..cd30be666 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 @@ public: 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 @@ private: void updateGrid(); std::vector mPrompts; + HelpStyle mStyle; }; diff --git a/src/views/SystemView.cpp b/src/views/SystemView.cpp index c8d6ab2f0..67e3caa30 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 69bb4952c..6916227e5 100644 --- a/src/views/SystemView.h +++ b/src/views/SystemView.h @@ -29,7 +29,8 @@ public: 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 6eb81900e..387119ec2 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 1eff1696c..c706dbb41 100644 --- a/src/views/ViewController.h +++ b/src/views/ViewController.h @@ -60,6 +60,7 @@ public: 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 dc2c39d62..9b9f59dba 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 b2229dfd7..930affa35 100644 --- a/src/views/gamelist/IGameListView.h +++ b/src/views/gamelist/IGameListView.h @@ -34,6 +34,8 @@ public: 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;