mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 23:55:38 +00:00
Added some new theming tags.
See changelog.txt (September 15) for more details.
This commit is contained in:
parent
f87b6c48d7
commit
9901a07fb6
|
@ -63,12 +63,17 @@ Display tags must be at the root of the <theme> tree - for example, they can't b
|
|||
|
||||
`<listSelectorColor>` - the hex color to use for the "selector bar" on the GuiGameList.
|
||||
|
||||
`<listLeftAlign />` - if present, the games list names will be left aligned to $infoWidth.
|
||||
`<listLeftAlign />` - if present, the games list names will be left aligned to the value of `<listOffsetX>` (default 0.5).
|
||||
|
||||
`<hideHeader />` - if present, the system name header won't be displayed (useful for replacing it with an image).
|
||||
|
||||
`<hideDividers />` - if present, the divider between games on the detailed GuiGameList won't be displayed.
|
||||
|
||||
`<listOffsetX>` - the percentage to offset the list by. Default is 0.5 (half the screen). **Will also move the selector bar**.
|
||||
|
||||
`<listTextOffsetX>` - the percentage to offset the text in the list by. Default is 0.005. Only works in combination with `<listLeftAlign />`.
|
||||
|
||||
`<gameImageOffsetY>` - the percentage to offset the displayed game image by. Default is the height of the header font.
|
||||
|
||||
List of variables
|
||||
=================
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
September 15
|
||||
-Added <listOffsetX>, <listTextOffsetX>, and <gameImageOffsetY> theme tags. See THEMES.md for details.
|
||||
-Fixed a bug causing gamelists to be read incorrectly.
|
||||
|
||||
September 14
|
||||
-Joystick names are now saved during input configuration to es_input.cfg.
|
||||
-When loading an input config, if JOYNAME is defined, load the first joystick with that name. If it is not present, load the first joystick (old behavior).
|
||||
|
|
|
@ -170,7 +170,6 @@ void Font::drawText(std::string text, int startx, int starty, int color)
|
|||
starty += mMaxGlyphHeight;
|
||||
|
||||
//padding (another 0.5% is added to the bottom through the sizeText function)
|
||||
//starty += Renderer::getScreenHeight() * 0.01;
|
||||
starty += mMaxGlyphHeight * 0.1;
|
||||
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@ std::vector<GuiComponent*> GuiComponent::sComponentVector;
|
|||
GuiComponent::GuiComponent()
|
||||
{
|
||||
sComponentVector.push_back(this);
|
||||
|
||||
mOffsetX = 0;
|
||||
mOffsetY = 0;
|
||||
}
|
||||
|
||||
GuiComponent::~GuiComponent()
|
||||
|
@ -97,3 +100,8 @@ void GuiComponent::deinit()
|
|||
mChildren.at(i)->deinit();
|
||||
}
|
||||
}
|
||||
|
||||
void GuiComponent::setOffsetX(int val) { mOffsetX = val; }
|
||||
void GuiComponent::setOffsetY(int val) { mOffsetY = val; }
|
||||
int GuiComponent::getOffsetX() { return mOffsetX; }
|
||||
int GuiComponent::getOffsetY() { return mOffsetY; }
|
||||
|
|
|
@ -44,8 +44,16 @@ public:
|
|||
unsigned int getChildCount() { return mChildren.size(); }
|
||||
GuiComponent* getChild(unsigned int i) { return mChildren.at(i); }
|
||||
|
||||
|
||||
int getOffsetX();
|
||||
int getOffsetY();
|
||||
void setOffsetX(int val);
|
||||
void setOffsetY(int val);
|
||||
|
||||
static void processTicks(int deltaTime);
|
||||
private:
|
||||
int mOffsetX, mOffsetY;
|
||||
|
||||
static std::vector<GuiComponent*> sComponentVector;
|
||||
std::vector<GuiComponent*> mChildren;
|
||||
};
|
||||
|
|
|
@ -49,8 +49,8 @@ GameData* createGameFromPath(std::string gameAbsPath, SystemData* system)
|
|||
//make our way through the directory tree finding each folder in our path or creating it if it doesn't exist
|
||||
FolderData* folder = system->getRootFolder();
|
||||
|
||||
unsigned int separator = 0;
|
||||
unsigned int nextSeparator = 0;
|
||||
size_t separator = 0;
|
||||
size_t nextSeparator = 0;
|
||||
unsigned int loops = 0;
|
||||
while(nextSeparator != std::string::npos)
|
||||
{
|
||||
|
@ -83,7 +83,8 @@ GameData* createGameFromPath(std::string gameAbsPath, SystemData* system)
|
|||
folder = newFolder;
|
||||
}
|
||||
|
||||
if(loops > gamePath.length())
|
||||
//if for some reason this function is broken, break out of this while instead of freezing
|
||||
if(loops > gamePath.length() * 2)
|
||||
{
|
||||
std::cerr << "breaking out of loop for path \"" << gamePath << "\"\n";
|
||||
break;
|
||||
|
|
|
@ -13,6 +13,9 @@ GuiGameList::GuiGameList(bool useDetail)
|
|||
std::cout << "Creating GuiGameList\n";
|
||||
mDetailed = useDetail;
|
||||
|
||||
|
||||
mTheme = new GuiTheme(); //not a child because it's rendered manually by GuiGameList::onRender (to make sure it's rendered first)
|
||||
|
||||
//The GuiGameList can use the older, simple game list if so desired.
|
||||
//The old view only shows a list in the center of the screen; the new view can display an image and description.
|
||||
//Those with smaller displays may prefer the older view.
|
||||
|
@ -20,7 +23,7 @@ GuiGameList::GuiGameList(bool useDetail)
|
|||
{
|
||||
mList = new GuiList<FileData*>(Renderer::getScreenWidth() * sInfoWidth, Renderer::getFontHeight(Renderer::LARGE) + 2);
|
||||
|
||||
mScreenshot = new GuiImage(Renderer::getScreenWidth() * sInfoWidth * 0.5, Renderer::getFontHeight(Renderer::LARGE) + 2, "", Renderer::getScreenWidth() * sInfoWidth * 0.7);
|
||||
mScreenshot = new GuiImage(Renderer::getScreenWidth() * sInfoWidth * 0.5, Renderer::getScreenHeight() * mTheme->getGameImageOffsetY(), "", Renderer::getScreenWidth() * sInfoWidth * 0.7);
|
||||
mScreenshot->setOrigin(0.5, 0.0);
|
||||
addChild(mScreenshot);
|
||||
}else{
|
||||
|
@ -28,8 +31,6 @@ GuiGameList::GuiGameList(bool useDetail)
|
|||
mScreenshot = NULL;
|
||||
}
|
||||
|
||||
mTheme = new GuiTheme(); //not a child because it's rendered manually by GuiGameList::onRender (to make sure it's rendered first)
|
||||
|
||||
addChild(mList);
|
||||
|
||||
setSystemId(0);
|
||||
|
@ -99,10 +100,9 @@ void GuiGameList::onRender()
|
|||
{
|
||||
GameData* game = (GameData*)mList->getSelectedObject();
|
||||
|
||||
//todo: cache this
|
||||
std::string desc = game->getDescription();
|
||||
if(!desc.empty())
|
||||
Renderer::drawWrappedText(desc, Renderer::getScreenWidth() * 0.03, Renderer::getFontHeight(Renderer::LARGE) + mScreenshot->getHeight() + 10, Renderer::getScreenWidth() * (sInfoWidth - 0.03), mTheme->getDescColor(), Renderer::SMALL);
|
||||
Renderer::drawWrappedText(desc, Renderer::getScreenWidth() * 0.03, mScreenshot->getOffsetY() + mScreenshot->getHeight() + 8, Renderer::getScreenWidth() * (sInfoWidth - 0.03), mTheme->getDescColor(), Renderer::SMALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,6 +200,13 @@ void GuiGameList::updateTheme()
|
|||
|
||||
mList->setSelectorColor(mTheme->getSelectorColor());
|
||||
mList->setCentered(mTheme->getListCentered());
|
||||
|
||||
if(mDetailed)
|
||||
{
|
||||
mList->setOffsetX(mTheme->getListOffsetX() * Renderer::getScreenWidth());
|
||||
mList->setTextOffsetX(mTheme->getListTextOffsetX() * Renderer::getScreenWidth());
|
||||
mScreenshot->setOffsetY(mTheme->getGameImageOffsetY() * Renderer::getScreenHeight());
|
||||
}
|
||||
}
|
||||
|
||||
void GuiGameList::updateDetailData()
|
||||
|
|
|
@ -10,8 +10,8 @@ GuiImage::GuiImage(int offsetX, int offsetY, std::string path, unsigned int resi
|
|||
{
|
||||
mTextureID = 0;
|
||||
|
||||
mOffsetX = offsetX;
|
||||
mOffsetY = offsetY;
|
||||
setOffsetX(offsetX);
|
||||
setOffsetY(offsetY);
|
||||
|
||||
//default origin is the center of image
|
||||
mOriginX = 0.5;
|
||||
|
@ -245,7 +245,7 @@ void GuiImage::onRender()
|
|||
{
|
||||
for(unsigned int y = 0; y < yCount; y++)
|
||||
{
|
||||
buildImageArray(mOffsetX + x*mWidth, mOffsetY + y*mHeight, points + (12 * (x*yCount + y)), texs + (12 * (x*yCount + y)));
|
||||
buildImageArray(getOffsetX() + x*mWidth, getOffsetY() + y*mHeight, points + (12 * (x*yCount + y)), texs + (12 * (x*yCount + y)));
|
||||
}
|
||||
}
|
||||
drawImageArray(points, texs, xCount * yCount * 6);
|
||||
|
@ -253,7 +253,7 @@ void GuiImage::onRender()
|
|||
delete[] texs;
|
||||
}else{
|
||||
GLfloat points[12], texs[12];
|
||||
buildImageArray(mOffsetX, mOffsetY, points, texs);
|
||||
buildImageArray(getOffsetX(), getOffsetY(), points, texs);
|
||||
drawImageArray(points, texs, 6);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ private:
|
|||
|
||||
std::string mPath;
|
||||
|
||||
int mOffsetX, mOffsetY;
|
||||
unsigned int mWidth, mHeight; //Our rendered size.
|
||||
|
||||
GLuint mTextureID;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//This is *actually* part of the GuiList header and not meant to be compiled.
|
||||
|
||||
#include "GuiList.h"
|
||||
#include <iostream>
|
||||
|
||||
|
@ -9,8 +11,10 @@ GuiList<listType>::GuiList(int offsetX, int offsetY, Renderer::FontSize fontsize
|
|||
mScrolling = 0;
|
||||
mScrollAccumulator = 0;
|
||||
|
||||
mOffsetX = offsetX;
|
||||
mOffsetY = offsetY;
|
||||
setOffsetX(offsetX);
|
||||
setOffsetY(offsetY);
|
||||
|
||||
mTextOffsetX = 0;
|
||||
|
||||
mFont = fontsize;
|
||||
mSelectorColor = 0x000000;
|
||||
|
@ -28,7 +32,7 @@ GuiList<listType>::~GuiList()
|
|||
template <typename listType>
|
||||
void GuiList<listType>::onRender()
|
||||
{
|
||||
const int cutoff = mOffsetY;
|
||||
const int cutoff = getOffsetY();
|
||||
const int entrySize = Renderer::getFontHeight(mFont) + 5;
|
||||
|
||||
int startEntry = 0;
|
||||
|
@ -62,15 +66,15 @@ void GuiList<listType>::onRender()
|
|||
{
|
||||
if(mSelection == i)
|
||||
{
|
||||
Renderer::drawRect(mOffsetX, y, Renderer::getScreenWidth(), Renderer::getFontHeight(mFont), mSelectorColor);
|
||||
Renderer::drawRect(getOffsetX(), y, Renderer::getScreenWidth(), Renderer::getFontHeight(mFont), mSelectorColor);
|
||||
}
|
||||
|
||||
ListRow row = mRowVector.at((unsigned int)i);
|
||||
|
||||
if(mDrawCentered)
|
||||
Renderer::drawCenteredText(row.name, mOffsetX, y, row.color, mFont);
|
||||
Renderer::drawCenteredText(row.name, getOffsetX(), y, row.color, mFont);
|
||||
else
|
||||
Renderer::drawText(row.name, mOffsetX, y, row.color, mFont);
|
||||
Renderer::drawText(row.name, getOffsetX() + mTextOffsetX, y, row.color, mFont);
|
||||
|
||||
y += entrySize;
|
||||
}
|
||||
|
@ -213,3 +217,9 @@ void GuiList<listType>::setCentered(bool centered)
|
|||
{
|
||||
mDrawCentered = centered;
|
||||
}
|
||||
|
||||
template<typename listType>
|
||||
void GuiList<listType>::setTextOffsetX(int textoffsetx)
|
||||
{
|
||||
mTextOffsetX = textoffsetx;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,9 @@ public:
|
|||
|
||||
void setSelectorColor(int selectorColor);
|
||||
void setCentered(bool centered);
|
||||
|
||||
void setTextOffsetX(int textoffsetx);
|
||||
|
||||
private:
|
||||
int mScrollDir, mScrollAccumulator;
|
||||
bool mScrolling;
|
||||
|
@ -44,7 +47,7 @@ private:
|
|||
int mSelectorColor;
|
||||
bool mDrawCentered;
|
||||
|
||||
int mOffsetX, mOffsetY;
|
||||
int mTextOffsetX;
|
||||
|
||||
struct ListRow
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "GuiImage.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <sstream>
|
||||
#include "../Renderer.h"
|
||||
|
||||
int GuiTheme::getPrimaryColor() { return mListPrimaryColor; }
|
||||
int GuiTheme::getSecondaryColor() { return mListSecondaryColor; }
|
||||
|
@ -14,6 +15,11 @@ bool GuiTheme::getHeaderHidden() { return mHideHeader; }
|
|||
bool GuiTheme::getDividersHidden() { return mHideDividers; }
|
||||
bool GuiTheme::getListCentered() { return mListCentered; }
|
||||
|
||||
//not yet implemented
|
||||
float GuiTheme::getListOffsetX() { return mListOffsetX; }
|
||||
float GuiTheme::getGameImageOffsetY() { return mGameImageOffsetY; }
|
||||
float GuiTheme::getListTextOffsetX() { return mListTextOffsetX; }
|
||||
|
||||
GuiTheme::GuiTheme(std::string path)
|
||||
{
|
||||
setDefaults();
|
||||
|
@ -36,6 +42,10 @@ void GuiTheme::setDefaults()
|
|||
mHideHeader = false;
|
||||
mHideDividers = false;
|
||||
mListCentered = true;
|
||||
|
||||
mListOffsetX = 0.5;
|
||||
mListTextOffsetX = 0.005;
|
||||
mGameImageOffsetY = (float)Renderer::getFontHeight(Renderer::LARGE) / Renderer::getScreenHeight();
|
||||
}
|
||||
|
||||
void GuiTheme::deleteComponents()
|
||||
|
@ -80,22 +90,35 @@ void GuiTheme::readXML(std::string path)
|
|||
pugi::xml_node root = doc.child("theme");
|
||||
|
||||
//load non-component theme stuff
|
||||
mListPrimaryColor = resolveColor(root.child("listPrimaryColor").text().get(), 0x0000FF);
|
||||
mListSecondaryColor = resolveColor(root.child("listSecondaryColor").text().get(), 0x00FF00);
|
||||
mListSelectorColor = resolveColor(root.child("listSelectorColor").text().get(), 0x000000);
|
||||
mDescColor = resolveColor(root.child("descColor").text().get(), 0x0000FF);
|
||||
mListPrimaryColor = resolveColor(root.child("listPrimaryColor").text().get(), mListPrimaryColor);
|
||||
mListSecondaryColor = resolveColor(root.child("listSecondaryColor").text().get(), mListSecondaryColor);
|
||||
mListSelectorColor = resolveColor(root.child("listSelectorColor").text().get(), mListSelectorColor);
|
||||
mDescColor = resolveColor(root.child("descColor").text().get(), mDescColor);
|
||||
mHideHeader = root.child("hideHeader");
|
||||
mHideDividers = root.child("hideDividers");
|
||||
mListCentered = !root.child("listLeftAlign");
|
||||
|
||||
for(pugi::xml_node data = root.child("component"); data; data = data.next_sibling("component"))
|
||||
{
|
||||
createElement(data, this);
|
||||
}
|
||||
mListOffsetX = strToFloat(root.child("listOffsetX").text().get(), mListOffsetX);
|
||||
mGameImageOffsetY = strToFloat(root.child("gameImageOffsetY").text().get(), mGameImageOffsetY);
|
||||
mListTextOffsetX = strToFloat(root.child("listTextOffsetX").text().get(), mListTextOffsetX);
|
||||
|
||||
//recursively create children for all <components> with proper parenting
|
||||
createComponentChildren(root, this);
|
||||
|
||||
std::cout << "Finished parsing theme.\n";
|
||||
}
|
||||
|
||||
void GuiTheme::createComponentChildren(pugi::xml_node node, GuiComponent* parent)
|
||||
{
|
||||
for(pugi::xml_node data = node.child("component"); data; data = data.next_sibling("component"))
|
||||
{
|
||||
GuiComponent* nextComp = createElement(data, parent);
|
||||
|
||||
if(nextComp)
|
||||
createComponentChildren(data, nextComp);
|
||||
}
|
||||
}
|
||||
|
||||
GuiComponent* GuiTheme::createElement(pugi::xml_node data, GuiComponent* parent)
|
||||
{
|
||||
std::string type = data.child("type").text().get();
|
||||
|
@ -197,10 +220,10 @@ void GuiTheme::splitString(std::string str, char delim, std::string* before, std
|
|||
*after = str.substr(split + 1, str.length() - split - 1);
|
||||
}
|
||||
|
||||
float GuiTheme::strToFloat(std::string str)
|
||||
float GuiTheme::strToFloat(std::string str, float defaultVal)
|
||||
{
|
||||
if(str.empty())
|
||||
return 0;
|
||||
return defaultVal;
|
||||
|
||||
float ret;
|
||||
std::stringstream ss;
|
||||
|
|
|
@ -20,9 +20,14 @@ public:
|
|||
bool getHeaderHidden();
|
||||
bool getDividersHidden();
|
||||
bool getListCentered();
|
||||
|
||||
float getListOffsetX();
|
||||
float getListTextOffsetX();
|
||||
float getGameImageOffsetY();
|
||||
private:
|
||||
void setDefaults();
|
||||
void deleteComponents();
|
||||
void createComponentChildren(pugi::xml_node node, GuiComponent* parent);
|
||||
GuiComponent* createElement(pugi::xml_node data, GuiComponent* parent);
|
||||
|
||||
//utility functions
|
||||
|
@ -30,12 +35,14 @@ private:
|
|||
float resolveExp(std::string str);
|
||||
int resolveColor(std::string str, int defaultColor = 0x000000);
|
||||
void splitString(std::string str, char delim, std::string* before, std::string* after);
|
||||
float strToFloat(std::string str);
|
||||
float strToFloat(std::string str, float defaultVal = 0.0f);
|
||||
|
||||
std::vector<GuiComponent*> mComponentVector;
|
||||
std::string mPath;
|
||||
int mListPrimaryColor, mListSecondaryColor, mListSelectorColor, mDescColor;
|
||||
bool mHideHeader, mHideDividers, mListCentered;
|
||||
|
||||
float mListOffsetX, mGameImageOffsetY, mListTextOffsetX;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue