mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-04-10 19:15:13 +00:00
Added initial theme support. More work on this to come.
Sped up image rendering a bit. Added a framerate display - uncomment the #define DRAWFRAMERATE line in GuiGameList.cpp to see it.
This commit is contained in:
parent
2a0c338cdf
commit
5ae029cd89
3
Makefile
3
Makefile
|
@ -1,7 +1,7 @@
|
||||||
CC=g++
|
CC=g++
|
||||||
CFLAGS=-c -Wall
|
CFLAGS=-c -Wall
|
||||||
LDFLAGS=-lSDL -lSDL_ttf -lSDL_image -lSDL_gfx -lboost_system -lboost_filesystem
|
LDFLAGS=-lSDL -lSDL_ttf -lSDL_image -lSDL_gfx -lboost_system -lboost_filesystem
|
||||||
SRCSOURCES=main.cpp Renderer.cpp Renderer_draw.cpp GuiComponent.cpp InputManager.cpp SystemData.cpp GameData.cpp FolderData.cpp XMLReader.cpp components/GuiGameList.cpp components/GuiInputConfig.cpp components/GuiImage.cpp components/GuiMenu.cpp pugiXML/pugixml.cpp
|
SRCSOURCES=main.cpp Renderer.cpp Renderer_draw.cpp GuiComponent.cpp InputManager.cpp SystemData.cpp GameData.cpp FolderData.cpp XMLReader.cpp MathExp.cpp components/GuiGameList.cpp components/GuiInputConfig.cpp components/GuiImage.cpp components/GuiMenu.cpp components/GuiTheme.cpp pugiXML/pugixml.cpp
|
||||||
SOURCES=$(addprefix src/,$(SRCSOURCES))
|
SOURCES=$(addprefix src/,$(SRCSOURCES))
|
||||||
OBJECTS=$(SOURCES:.cpp=.o)
|
OBJECTS=$(SOURCES:.cpp=.o)
|
||||||
EXECUTABLE=emulationstation
|
EXECUTABLE=emulationstation
|
||||||
|
@ -16,3 +16,4 @@ $(EXECUTABLE): $(OBJECTS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf src/*o src/components/*o $(EXECUTABLE)
|
rm -rf src/*o src/components/*o $(EXECUTABLE)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
August 9
|
||||||
|
-Removed multithreaded image loading
|
||||||
|
-Improved GuiImage rendering speed by adding additional processing at load time (SDL_DisplayFormat)
|
||||||
|
-Began work on the GuiTheme class, allowing custom theming with an XML file
|
||||||
|
|
||||||
August 8
|
August 8
|
||||||
-Added automatic resizing of images using SDL_gfx
|
-Added automatic resizing of images using SDL_gfx
|
||||||
-Multithreaded image loading for the GuiImage class!
|
-Experimenting with multithreaded image loading for the GuiImage class
|
||||||
-Removed warning if an unknown variable is found in a systems config file (useful for additional utilities)
|
-Removed warning if an unknown variable is found in a systems config file (useful for additional utilities)
|
||||||
|
|
||||||
August 7
|
August 7
|
||||||
|
|
|
@ -33,7 +33,7 @@ void InputManager::unregisterComponent(GuiComponent* comp)
|
||||||
void InputManager::processEvent(SDL_Event* event)
|
void InputManager::processEvent(SDL_Event* event)
|
||||||
{
|
{
|
||||||
bool keyDown = false;
|
bool keyDown = false;
|
||||||
InputButton button;
|
InputButton button = UNKNOWN;
|
||||||
|
|
||||||
lastEvent = event;
|
lastEvent = event;
|
||||||
|
|
||||||
|
|
163
src/MathExp.cpp
Normal file
163
src/MathExp.cpp
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
#include "MathExp.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
bool MathExp::isOperator(const char c)
|
||||||
|
{
|
||||||
|
if(c == *"+" || c == *"-" || c == *"*" || c == *"/" || c == *"(")
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MathExp::isRParen(const char c)
|
||||||
|
{
|
||||||
|
if(c == *")")
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MathExp::getPrecedence(const char c)
|
||||||
|
{
|
||||||
|
if(c == *"(")
|
||||||
|
return -5;
|
||||||
|
|
||||||
|
if(c == *"+" || c == *"-")
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(c == *"*" || c == *"/")
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
std::cout << "Error - getPrecedence(): unknown character '" << c << "'\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MathExp::eval()
|
||||||
|
{
|
||||||
|
unsigned int start = 0;
|
||||||
|
for(unsigned int i = 0; i < mExpression.length(); i++)
|
||||||
|
{
|
||||||
|
if(isOperator(mExpression.at(i)))
|
||||||
|
{
|
||||||
|
//the string from start to i is an operand, and i is an operator
|
||||||
|
if(start != i) //if we actually do have an operand
|
||||||
|
mOperands.push(strToVal(mExpression.substr(start, i - start)));
|
||||||
|
else
|
||||||
|
std::cout << "skipping operand, start == i\n";
|
||||||
|
|
||||||
|
//now we must decide what to do with the operator
|
||||||
|
const char op = mExpression.at(i);
|
||||||
|
|
||||||
|
if(op != *"(")
|
||||||
|
{
|
||||||
|
while(mOperators.size() && getPrecedence(mOperators.top()) >= getPrecedence(op))
|
||||||
|
{
|
||||||
|
doNextOperation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mOperators.push(op);
|
||||||
|
|
||||||
|
start = i + 1;
|
||||||
|
}else{
|
||||||
|
if(isRParen(mExpression.at(i)))
|
||||||
|
{
|
||||||
|
while(mOperators.top() != *"(")
|
||||||
|
{
|
||||||
|
doNextOperation();
|
||||||
|
}
|
||||||
|
|
||||||
|
mOperators.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mOperands.push(strToVal(mExpression.substr(start, mExpression.length() - start)));
|
||||||
|
|
||||||
|
|
||||||
|
while(mOperators.size() > 0)
|
||||||
|
doNextOperation();
|
||||||
|
|
||||||
|
|
||||||
|
if(mOperands.size() != 1)
|
||||||
|
{
|
||||||
|
std::cout << "Error - mOperands.size() = " << mOperands.size() << " at the end of evaluation!\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float final = mOperands.top();
|
||||||
|
mOperands.pop();
|
||||||
|
|
||||||
|
return final;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathExp::doNextOperation()
|
||||||
|
{
|
||||||
|
//pop operator off and apply it, then push the value onto the operand stack
|
||||||
|
const char top = mOperators.top();
|
||||||
|
float val = 0;
|
||||||
|
|
||||||
|
if(top == *"+")
|
||||||
|
{
|
||||||
|
val = mOperands.top();
|
||||||
|
mOperands.pop();
|
||||||
|
val += mOperands.top();
|
||||||
|
mOperands.pop();
|
||||||
|
}
|
||||||
|
if(top == *"-")
|
||||||
|
{
|
||||||
|
val = mOperands.top();
|
||||||
|
mOperands.pop();
|
||||||
|
val -= mOperands.top();
|
||||||
|
mOperands.pop();
|
||||||
|
}
|
||||||
|
if(top == *"*")
|
||||||
|
{
|
||||||
|
val = mOperands.top();
|
||||||
|
mOperands.pop();
|
||||||
|
val *= mOperands.top();
|
||||||
|
mOperands.pop();
|
||||||
|
}
|
||||||
|
if(top == *"/")
|
||||||
|
{
|
||||||
|
val = mOperands.top();
|
||||||
|
mOperands.pop();
|
||||||
|
val /= mOperands.top();
|
||||||
|
mOperands.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
mOperands.push(val);
|
||||||
|
|
||||||
|
mOperators.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathExp::setExpression(std::string str)
|
||||||
|
{
|
||||||
|
mExpression = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathExp::setVariable(std::string name, float val)
|
||||||
|
{
|
||||||
|
mVariables[name] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MathExp::getVariable(std::string name)
|
||||||
|
{
|
||||||
|
return mVariables[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
float MathExp::strToVal(std::string str)
|
||||||
|
{
|
||||||
|
if(str[0] == *"$")
|
||||||
|
return getVariable(str.substr(1, str.length() - 1)); //it's a variable!
|
||||||
|
|
||||||
|
//it's a value!
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << str;
|
||||||
|
|
||||||
|
float value;
|
||||||
|
stream >> value;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
35
src/MathExp.h
Normal file
35
src/MathExp.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef _MATHEXP_H_
|
||||||
|
#define _MATHEXP_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <stack>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class MathExp {
|
||||||
|
public:
|
||||||
|
|
||||||
|
void setExpression(std::string str);
|
||||||
|
void setVariable(std::string name, float val);
|
||||||
|
float getVariable(std::string name);
|
||||||
|
|
||||||
|
float eval();
|
||||||
|
|
||||||
|
private:
|
||||||
|
//float apply(const char operatorChar, std::string operand);
|
||||||
|
void doNextOperation();
|
||||||
|
|
||||||
|
bool isOperator(const char c);
|
||||||
|
bool isRParen(const char c);
|
||||||
|
int getPrecedence(const char c);
|
||||||
|
|
||||||
|
float strToVal(std::string str);
|
||||||
|
|
||||||
|
std::string mExpression;
|
||||||
|
|
||||||
|
std::stack<float> mOperands;
|
||||||
|
std::stack<char> mOperators;
|
||||||
|
std::map<std::string, float> mVariables;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,9 +2,14 @@
|
||||||
#include "../InputManager.h"
|
#include "../InputManager.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "GuiMenu.h"
|
#include "GuiMenu.h"
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
#define SCREENSHOTWIDTH 256
|
//#define DRAWFRAMERATE
|
||||||
#define SCREENSHOTHEIGHT 256
|
|
||||||
|
#ifdef DRAWFRAMERATE
|
||||||
|
#include <sstream>
|
||||||
|
extern float FRAMERATE;
|
||||||
|
#endif
|
||||||
|
|
||||||
GuiGameList::GuiGameList(bool useDetail)
|
GuiGameList::GuiGameList(bool useDetail)
|
||||||
{
|
{
|
||||||
|
@ -12,17 +17,22 @@ GuiGameList::GuiGameList(bool useDetail)
|
||||||
mDetailed = useDetail;
|
mDetailed = useDetail;
|
||||||
|
|
||||||
//The GuiGameList can use the older, simple game list if so desired.
|
//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 a screenshto and description.
|
//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.
|
//Those with smaller displays may prefer the older view.
|
||||||
if(mDetailed)
|
if(mDetailed)
|
||||||
{
|
{
|
||||||
mList = new GuiList<FileData*>(Renderer::getScreenWidth() * 0.4, Renderer::getFontHeight(Renderer::LARGE) + 2);
|
mList = new GuiList<FileData*>(Renderer::getScreenWidth() * 0.4, Renderer::getFontHeight(Renderer::LARGE) + 2);
|
||||||
|
|
||||||
|
mTheme = new GuiTheme();
|
||||||
|
//addChild(mTheme);
|
||||||
|
updateTheme();
|
||||||
|
|
||||||
mScreenshot = new GuiImage(Renderer::getScreenWidth() * 0.2, Renderer::getFontHeight(Renderer::LARGE) + 2, "", Renderer::getScreenWidth() * 0.3);
|
mScreenshot = new GuiImage(Renderer::getScreenWidth() * 0.2, Renderer::getFontHeight(Renderer::LARGE) + 2, "", Renderer::getScreenWidth() * 0.3);
|
||||||
addChild(mScreenshot);
|
addChild(mScreenshot);
|
||||||
}else{
|
}else{
|
||||||
mList = new GuiList<FileData*>(0, Renderer::getFontHeight(Renderer::LARGE) + 2);
|
mList = new GuiList<FileData*>(0, Renderer::getFontHeight(Renderer::LARGE) + 2);
|
||||||
mScreenshot = NULL;
|
mScreenshot = NULL;
|
||||||
|
mTheme = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
addChild(mList);
|
addChild(mList);
|
||||||
|
@ -41,6 +51,7 @@ GuiGameList::~GuiGameList()
|
||||||
if(mDetailed)
|
if(mDetailed)
|
||||||
{
|
{
|
||||||
delete mScreenshot;
|
delete mScreenshot;
|
||||||
|
delete mTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputManager::unregisterComponent(this);
|
InputManager::unregisterComponent(this);
|
||||||
|
@ -73,11 +84,23 @@ void GuiGameList::setSystemId(int id)
|
||||||
|
|
||||||
void GuiGameList::onRender()
|
void GuiGameList::onRender()
|
||||||
{
|
{
|
||||||
Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0xFFFFFF);
|
if(mTheme)
|
||||||
|
mTheme->render();
|
||||||
|
else
|
||||||
|
Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0xFFFFFF);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DRAWFRAMERATE
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << FRAMERATE;
|
||||||
|
std::string fps;
|
||||||
|
ss >> fps;
|
||||||
|
Renderer::drawText(fps, 0, 0, 0x00FF00);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
Renderer::drawCenteredText(mSystem->getName(), 0, 1, 0x0000FF, Renderer::LARGE);
|
Renderer::drawCenteredText(mSystem->getName(), 0, 1, 0x0000FF, Renderer::LARGE);
|
||||||
|
|
||||||
|
|
||||||
if(mDetailed)
|
if(mDetailed)
|
||||||
{
|
{
|
||||||
Renderer::drawRect(Renderer::getScreenWidth() * 0.4, Renderer::getFontHeight(Renderer::LARGE) + 2, 8, Renderer::getScreenHeight(), 0x0000FF);
|
Renderer::drawRect(Renderer::getScreenWidth() * 0.4, Renderer::getFontHeight(Renderer::LARGE) + 2, 8, Renderer::getScreenHeight(), 0x0000FF);
|
||||||
|
@ -90,7 +113,7 @@ void GuiGameList::onRender()
|
||||||
//todo: cache this
|
//todo: cache this
|
||||||
std::string desc = game->getDescription();
|
std::string desc = game->getDescription();
|
||||||
if(!desc.empty())
|
if(!desc.empty())
|
||||||
Renderer::drawWrappedText(desc, 2, Renderer::getFontHeight(Renderer::LARGE) + SCREENSHOTHEIGHT + 12, Renderer::getScreenWidth() * 0.4, 0xFF0000);
|
Renderer::drawWrappedText(desc, 2, Renderer::getFontHeight(Renderer::LARGE) + mScreenshot->getHeight() + 10, Renderer::getScreenWidth() * 0.4, 0xFF0000, Renderer::SMALL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,6 +190,17 @@ void GuiGameList::updateList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GuiGameList::updateTheme()
|
||||||
|
{
|
||||||
|
std::string themePath = getenv("HOME");
|
||||||
|
themePath += "/.emulationstation/theme.xml";
|
||||||
|
|
||||||
|
if(boost::filesystem::exists(themePath))
|
||||||
|
{
|
||||||
|
mTheme->readXML(themePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//these are called when the menu opens/closes
|
//these are called when the menu opens/closes
|
||||||
//the second bit should be moved to GuiList
|
//the second bit should be moved to GuiList
|
||||||
void GuiGameList::onPause()
|
void GuiGameList::onPause()
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "../GuiComponent.h"
|
#include "../GuiComponent.h"
|
||||||
#include "GuiList.h"
|
#include "GuiList.h"
|
||||||
#include "GuiImage.h"
|
#include "GuiImage.h"
|
||||||
|
#include "GuiTheme.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include "../SystemData.h"
|
#include "../SystemData.h"
|
||||||
|
@ -25,6 +26,8 @@ public:
|
||||||
void onResume();
|
void onResume();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void updateTheme();
|
||||||
|
|
||||||
SystemData* mSystem;
|
SystemData* mSystem;
|
||||||
FolderData* mFolder;
|
FolderData* mFolder;
|
||||||
std::stack<FolderData*> mFolderStack;
|
std::stack<FolderData*> mFolderStack;
|
||||||
|
@ -33,6 +36,7 @@ private:
|
||||||
|
|
||||||
GuiList<FileData*>* mList;
|
GuiList<FileData*>* mList;
|
||||||
GuiImage* mScreenshot;
|
GuiImage* mScreenshot;
|
||||||
|
GuiTheme* mTheme;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,12 +7,8 @@
|
||||||
int GuiImage::getWidth() { if(mSurface) return mSurface->w; else return 0; }
|
int GuiImage::getWidth() { if(mSurface) return mSurface->w; else return 0; }
|
||||||
int GuiImage::getHeight() { if(mSurface) return mSurface->h; else return 0; }
|
int GuiImage::getHeight() { if(mSurface) return mSurface->h; else return 0; }
|
||||||
|
|
||||||
int startImageLoadThread(void*);
|
GuiImage::GuiImage(int offsetX, int offsetY, std::string path, unsigned int maxWidth, unsigned int maxHeight, bool resizeExact)
|
||||||
|
|
||||||
GuiImage::GuiImage(int offsetX, int offsetY, std::string path, unsigned int maxWidth, unsigned int maxHeight)
|
|
||||||
{
|
{
|
||||||
std::cout << "Creating GuiImage\n";
|
|
||||||
|
|
||||||
mSurface = NULL;
|
mSurface = NULL;
|
||||||
|
|
||||||
mOffsetX = offsetX;
|
mOffsetX = offsetX;
|
||||||
|
@ -20,6 +16,7 @@ GuiImage::GuiImage(int offsetX, int offsetY, std::string path, unsigned int maxW
|
||||||
|
|
||||||
mMaxWidth = maxWidth;
|
mMaxWidth = maxWidth;
|
||||||
mMaxHeight = maxHeight;
|
mMaxHeight = maxHeight;
|
||||||
|
mResizeExact = resizeExact;
|
||||||
|
|
||||||
if(!path.empty())
|
if(!path.empty())
|
||||||
setImage(path);
|
setImage(path);
|
||||||
|
@ -47,24 +44,41 @@ void GuiImage::loadImage(std::string path)
|
||||||
|
|
||||||
|
|
||||||
//resize it
|
//resize it
|
||||||
if(mMaxWidth && newSurf->w > mMaxWidth)
|
if(mResizeExact)
|
||||||
{
|
{
|
||||||
double scale = (double)mMaxWidth / (double)newSurf->w;
|
double scaleX = (double)mMaxWidth / (double)newSurf->w;
|
||||||
|
double scaleY = (double)mMaxHeight / (double)newSurf->h;
|
||||||
|
|
||||||
SDL_Surface* resSurf = zoomSurface(newSurf, scale, scale, SMOOTHING_OFF);
|
SDL_Surface* resSurf = zoomSurface(newSurf, scaleX, scaleY, SMOOTHING_OFF);
|
||||||
SDL_FreeSurface(newSurf);
|
SDL_FreeSurface(newSurf);
|
||||||
newSurf = resSurf;
|
newSurf = resSurf;
|
||||||
}
|
}else{
|
||||||
|
if(mMaxWidth && newSurf->w > mMaxWidth)
|
||||||
|
{
|
||||||
|
double scale = (double)mMaxWidth / (double)newSurf->w;
|
||||||
|
|
||||||
if(mMaxHeight && newSurf->h > mMaxHeight)
|
SDL_Surface* resSurf = zoomSurface(newSurf, scale, scale, SMOOTHING_OFF);
|
||||||
{
|
SDL_FreeSurface(newSurf);
|
||||||
double scale = (double)mMaxHeight / (double)newSurf->h;
|
newSurf = resSurf;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_Surface* resSurf = zoomSurface(newSurf, scale, scale, SMOOTHING_OFF);
|
if(mMaxHeight && newSurf->h > mMaxHeight)
|
||||||
SDL_FreeSurface(newSurf);
|
{
|
||||||
newSurf = resSurf;
|
double scale = (double)mMaxHeight / (double)newSurf->h;
|
||||||
|
|
||||||
|
SDL_Surface* resSurf = zoomSurface(newSurf, scale, scale, SMOOTHING_OFF);
|
||||||
|
SDL_FreeSurface(newSurf);
|
||||||
|
newSurf = resSurf;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//convert it into display format for faster rendering
|
||||||
|
SDL_Surface* dispSurf = SDL_DisplayFormat(newSurf);
|
||||||
|
SDL_FreeSurface(newSurf);
|
||||||
|
newSurf = dispSurf;
|
||||||
|
|
||||||
|
|
||||||
//finally set the image and delete the old one
|
//finally set the image and delete the old one
|
||||||
if(mSurface)
|
if(mSurface)
|
||||||
SDL_FreeSurface(mSurface);
|
SDL_FreeSurface(mSurface);
|
||||||
|
@ -74,8 +88,8 @@ void GuiImage::loadImage(std::string path)
|
||||||
//Also update the rect
|
//Also update the rect
|
||||||
mRect.x = mOffsetX - (mSurface->w / 2);
|
mRect.x = mOffsetX - (mSurface->w / 2);
|
||||||
mRect.y = mOffsetY;
|
mRect.y = mOffsetY;
|
||||||
mRect.w = 0;
|
mRect.w = mSurface->w;
|
||||||
mRect.h = 0;
|
mRect.h = mSurface->h;
|
||||||
}else{
|
}else{
|
||||||
std::cerr << "File \"" << path << "\" not found!\n";
|
std::cerr << "File \"" << path << "\" not found!\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
class GuiImage : public GuiComponent
|
class GuiImage : public GuiComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GuiImage(int offsetX = 0, int offsetY = 0, std::string path = "", unsigned int maxWidth = 0, unsigned int maxHeight = 0);
|
GuiImage(int offsetX = 0, int offsetY = 0, std::string path = "", unsigned int maxWidth = 0, unsigned int maxHeight = 0, bool resizeExact = false);
|
||||||
~GuiImage();
|
~GuiImage();
|
||||||
|
|
||||||
void setImage(std::string path);
|
void setImage(std::string path);
|
||||||
|
@ -21,6 +21,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int mMaxWidth, mMaxHeight;
|
int mMaxWidth, mMaxHeight;
|
||||||
|
bool mResizeExact;
|
||||||
|
|
||||||
void loadImage(std::string path);
|
void loadImage(std::string path);
|
||||||
|
|
||||||
|
|
104
src/components/GuiTheme.cpp
Normal file
104
src/components/GuiTheme.cpp
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
#include "GuiTheme.h"
|
||||||
|
#include "../MathExp.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include "GuiImage.h"
|
||||||
|
|
||||||
|
GuiTheme::GuiTheme(std::string path)
|
||||||
|
{
|
||||||
|
if(!path.empty())
|
||||||
|
readXML(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiTheme::~GuiTheme()
|
||||||
|
{
|
||||||
|
deleteComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiTheme::deleteComponents()
|
||||||
|
{
|
||||||
|
for(unsigned int i = 0; i < mComponentVector.size(); i++)
|
||||||
|
{
|
||||||
|
delete mComponentVector.at(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mComponentVector.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void GuiTheme::readXML(std::string path)
|
||||||
|
{
|
||||||
|
deleteComponents();
|
||||||
|
|
||||||
|
std::cout << "Loading theme \"" << path << "\"...\n";
|
||||||
|
|
||||||
|
pugi::xml_document doc;
|
||||||
|
pugi::xml_parse_result result = doc.load_file(path.c_str());
|
||||||
|
|
||||||
|
if(!result)
|
||||||
|
{
|
||||||
|
std::cerr << "Error parsing theme \"" << path << "\"!\n";
|
||||||
|
std::cerr << " " << result.description() << "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pugi::xml_node root = doc.child("theme");
|
||||||
|
|
||||||
|
for(pugi::xml_node data = root.child("component"); data; data = data.next_sibling("component"))
|
||||||
|
{
|
||||||
|
createElement(data, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Finished parsing theme.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiComponent* GuiTheme::createElement(pugi::xml_node data, GuiComponent* parent)
|
||||||
|
{
|
||||||
|
std::string type = data.child("type").text().get();
|
||||||
|
|
||||||
|
if(type == "image")
|
||||||
|
{
|
||||||
|
std::string path = data.child("path").text().get();
|
||||||
|
std::string pos = data.child("pos").text().get();
|
||||||
|
std::string dim = data.child("dim").text().get();
|
||||||
|
|
||||||
|
//split position and dimension information
|
||||||
|
size_t posSplit = pos.find(' ');
|
||||||
|
std::string posX = pos.substr(0, posSplit);
|
||||||
|
std::string posY = pos.substr(posSplit + 1, pos.length() - posSplit - 1);
|
||||||
|
|
||||||
|
size_t dimSplit = dim.find(' ');
|
||||||
|
std::string dimW = dim.substr(0, dimSplit);
|
||||||
|
std::string dimH = dim.substr(dimSplit + 1, dim.length() - dimSplit - 1);
|
||||||
|
|
||||||
|
std::cout << "image, x: " << posX << " y: " << posY << " w: " << dimW << " h: " << dimH << "\n";
|
||||||
|
|
||||||
|
//resolve to pixels from percentages/variables
|
||||||
|
int x = resolveExp(posX) * Renderer::getScreenWidth();
|
||||||
|
int y = resolveExp(posY) * Renderer::getScreenHeight();
|
||||||
|
int w = resolveExp(dimW) * Renderer::getScreenWidth();
|
||||||
|
int h = resolveExp(dimH) * Renderer::getScreenHeight();
|
||||||
|
|
||||||
|
std::cout << "w: " << w << " h: " << h << "\n";
|
||||||
|
|
||||||
|
GuiComponent* comp = new GuiImage(x, y, path, w, h, true);
|
||||||
|
parent->addChild(comp);
|
||||||
|
mComponentVector.push_back(comp);
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::cerr << "Type \"" << type << "\" unknown!\n";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GuiTheme::resolveExp(std::string str)
|
||||||
|
{
|
||||||
|
MathExp exp;
|
||||||
|
exp.setExpression(str);
|
||||||
|
|
||||||
|
//set variables
|
||||||
|
exp.setVariable("headerHeight", Renderer::getFontHeight(Renderer::LARGE) / Renderer::getScreenHeight());
|
||||||
|
|
||||||
|
return (int)exp.eval();
|
||||||
|
}
|
24
src/components/GuiTheme.h
Normal file
24
src/components/GuiTheme.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef _GUITHEME_H_
|
||||||
|
#define _GUITHEME_H_
|
||||||
|
|
||||||
|
#include "../GuiComponent.h"
|
||||||
|
#include "../pugiXML/pugixml.hpp"
|
||||||
|
|
||||||
|
class GuiTheme : public GuiComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GuiTheme(std::string path = "");
|
||||||
|
~GuiTheme();
|
||||||
|
|
||||||
|
void readXML(std::string path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void deleteComponents();
|
||||||
|
|
||||||
|
GuiComponent* createElement(pugi::xml_node data, GuiComponent* parent);
|
||||||
|
int resolveExp(std::string str);
|
||||||
|
|
||||||
|
std::vector<GuiComponent*> mComponentVector;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -8,6 +8,7 @@
|
||||||
#include "components/GuiInputConfig.h"
|
#include "components/GuiInputConfig.h"
|
||||||
|
|
||||||
bool PARSEGAMELISTONLY = false;
|
bool PARSEGAMELISTONLY = false;
|
||||||
|
float FRAMERATE = 0;
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
@ -166,6 +167,7 @@ int main(int argc, char* argv[])
|
||||||
int deltaTime = curTime - lastTime;
|
int deltaTime = curTime - lastTime;
|
||||||
lastTime = curTime;
|
lastTime = curTime;
|
||||||
|
|
||||||
|
FRAMERATE = 1/((float)deltaTime)*1000;
|
||||||
GuiComponent::processTicks(deltaTime);
|
GuiComponent::processTicks(deltaTime);
|
||||||
|
|
||||||
Renderer::render();
|
Renderer::render();
|
||||||
|
|
Loading…
Reference in a new issue