mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 23:55:38 +00:00
Hooked up GuiSettingsMenu.
Settings now save/load from ~/.emulationstation/es_settings.cfg.
This commit is contained in:
parent
1534cec865
commit
62529029d7
|
@ -1,11 +1,15 @@
|
|||
#include "Settings.h"
|
||||
#include "Log.h"
|
||||
#include "pugiXML/pugixml.hpp"
|
||||
#include "platform.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
Settings* Settings::sInstance = NULL;
|
||||
|
||||
Settings::Settings()
|
||||
{
|
||||
setDefaults();
|
||||
loadFile();
|
||||
}
|
||||
|
||||
Settings* Settings::getInstance()
|
||||
|
@ -31,18 +35,67 @@ void Settings::setDefaults()
|
|||
mIntMap["DIMTIME"] = 30*1000;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void saveMap(pugi::xml_document& doc, std::map<K, V>& map, const char* type)
|
||||
{
|
||||
for(auto iter = map.begin(); iter != map.end(); iter++)
|
||||
{
|
||||
pugi::xml_node node = doc.append_child(type);
|
||||
node.append_attribute("name").set_value(iter->first.c_str());
|
||||
node.append_attribute("value").set_value(iter->second);
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::saveFile()
|
||||
{
|
||||
const std::string path = getHomePath() + "/.emulationstation/es_settings.cfg";
|
||||
|
||||
pugi::xml_document doc;
|
||||
|
||||
saveMap<std::string, bool>(doc, mBoolMap, "bool");
|
||||
saveMap<std::string, int>(doc, mIntMap, "int");
|
||||
saveMap<std::string, float>(doc, mFloatMap, "float");
|
||||
|
||||
doc.save_file(path.c_str());
|
||||
}
|
||||
|
||||
void Settings::loadFile()
|
||||
{
|
||||
const std::string path = getHomePath() + "/.emulationstation/es_settings.cfg";
|
||||
|
||||
if(!boost::filesystem::exists(path))
|
||||
return;
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result = doc.load_file(path.c_str());
|
||||
if(!result)
|
||||
{
|
||||
LOG(LogError) << "Could not parse Settings file!\n " << result.description();
|
||||
return;
|
||||
}
|
||||
|
||||
for(pugi::xml_node node = doc.child("bool"); node; node = node.next_sibling())
|
||||
setBool(node.attribute("name").as_string(), node.attribute("value").as_bool());
|
||||
for(pugi::xml_node node = doc.child("int"); node; node = node.next_sibling())
|
||||
setInt(node.attribute("name").as_string(), node.attribute("value").as_int());
|
||||
for(pugi::xml_node node = doc.child("float"); node; node = node.next_sibling())
|
||||
setFloat(node.attribute("name").as_string(), node.attribute("value").as_float());
|
||||
}
|
||||
|
||||
//Print a warning message if the setting we're trying to get doesn't already exist in the map, then return the value in the map.
|
||||
#define SETTINGS_GET(type, mapName, methodName) type Settings::##methodName##(const std::string& name) \
|
||||
#define SETTINGS_GETSET(type, mapName, getMethodName, setMethodName) type Settings::##getMethodName##(const std::string& name) \
|
||||
{ \
|
||||
if(mapName.find(name) == mapName.end()) \
|
||||
{ \
|
||||
LOG(LogError) << "Tried to use unset setting " << name << "!"; \
|
||||
} \
|
||||
return mapName[name]; \
|
||||
} \
|
||||
void Settings::##setMethodName##(const std::string& name, type value) \
|
||||
{ \
|
||||
mapName[name] = value; \
|
||||
}
|
||||
|
||||
SETTINGS_GET(bool, mBoolMap, getBool);
|
||||
SETTINGS_GET(int, mIntMap, getInt);
|
||||
|
||||
void Settings::setBool(const std::string& name, bool value) { mBoolMap[name] = value; }
|
||||
void Settings::setInt(const std::string& name, int value) { mIntMap[name] = value; }
|
||||
SETTINGS_GETSET(bool, mBoolMap, getBool, setBool);
|
||||
SETTINGS_GETSET(int, mIntMap, getInt, setInt);
|
||||
SETTINGS_GETSET(float, mFloatMap, getFloat, setFloat);
|
||||
|
|
|
@ -10,15 +10,17 @@ class Settings
|
|||
public:
|
||||
static Settings* getInstance();
|
||||
|
||||
void loadFile(const std::string& path);
|
||||
void saveFile(const std::string& path);
|
||||
void loadFile();
|
||||
void saveFile();
|
||||
|
||||
//You will get a warning if you try a get on a key that is not already present.
|
||||
bool getBool(const std::string& name);
|
||||
int getInt(const std::string& name);
|
||||
float getFloat(const std::string& name);
|
||||
|
||||
void setBool(const std::string& name, bool value);
|
||||
void setInt(const std::string& name, int value);
|
||||
void setFloat(const std::string& name, float value);
|
||||
|
||||
private:
|
||||
static Settings* sInstance;
|
||||
|
@ -30,6 +32,7 @@ private:
|
|||
|
||||
std::map<std::string, bool> mBoolMap;
|
||||
std::map<std::string, int> mIntMap;
|
||||
std::map<std::string, float> mFloatMap;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -310,3 +310,10 @@ void ComponentListComponent::onOffsetChanged()
|
|||
{
|
||||
updateComponentOffsets();
|
||||
}
|
||||
|
||||
GuiComponent* ComponentListComponent::getSelectedComponent()
|
||||
{
|
||||
if(!cursorValid())
|
||||
return NULL;
|
||||
return getCell(mCursor.x, mCursor.y)->component;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ public:
|
|||
void resetCursor();
|
||||
bool cursorValid();
|
||||
|
||||
GuiComponent* getSelectedComponent();
|
||||
|
||||
private:
|
||||
class ComponentEntry
|
||||
{
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
#include "GuiSettingsMenu.h"
|
||||
#include "../Renderer.h"
|
||||
#include "../Settings.h"
|
||||
#include "SliderComponent.h"
|
||||
#include "../VolumeControl.h"
|
||||
|
||||
GuiSettingsMenu::GuiSettingsMenu(Window* window) : GuiComponent(window),
|
||||
mList(window, Vector2u(2, 3)),
|
||||
mDrawFramerateSwitch(window)
|
||||
mDrawFramerateSwitch(window),
|
||||
mVolumeSlider(window, 0, 100, 1),
|
||||
mSaveLabel(window)
|
||||
{
|
||||
loadStates();
|
||||
|
||||
addChild(&mList);
|
||||
|
||||
mList.setOffset(Renderer::getScreenWidth() / 4, 0);
|
||||
|
@ -21,23 +25,19 @@ GuiSettingsMenu::GuiSettingsMenu(Window* window) : GuiComponent(window),
|
|||
mList.setEntry(Vector2u(1, 0), Vector2u(1, 1), &mDrawFramerateSwitch, true, ComponentListComponent::AlignCenter, Vector2<bool>(true, true));
|
||||
|
||||
label = new TextComponent(mWindow);
|
||||
label->setText("Volume: ");
|
||||
label->setText("System volume: ");
|
||||
label->setColor(0x0000FFFF);
|
||||
mList.setEntry(Vector2u(0, 1), Vector2u(1, 1), label, false, ComponentListComponent::AlignRight, Vector2<bool>(true, true));
|
||||
|
||||
//volume slider
|
||||
SliderComponent* slider = new SliderComponent(mWindow, 0, 1);
|
||||
mList.setEntry(Vector2u(1, 1), Vector2u(1, 1), slider, true, ComponentListComponent::AlignCenter, Vector2<bool>(true, true));
|
||||
mList.setEntry(Vector2u(1, 1), Vector2u(1, 1), &mVolumeSlider, true, ComponentListComponent::AlignCenter, Vector2<bool>(true, true));
|
||||
|
||||
label = new TextComponent(mWindow);
|
||||
label->setText("B TO CLOSE");
|
||||
label->setColor(0x00FF00FF);
|
||||
mList.setEntry(Vector2u(0, 2), Vector2u(2, 1), label, true, ComponentListComponent::AlignCenter, Vector2<bool>(false, true));
|
||||
mLabels.push_back(label);
|
||||
//save label
|
||||
mSaveLabel.setText("SAVE");
|
||||
mSaveLabel.setColor(0x000000FF);
|
||||
mList.setEntry(Vector2u(0, 2), Vector2u(2, 1), &mSaveLabel, true, ComponentListComponent::AlignCenter, Vector2<bool>(false, true));
|
||||
|
||||
mList.setOffset(Renderer::getScreenWidth() / 2 - mList.getSize().x / 2, 0);
|
||||
|
||||
loadStates();
|
||||
}
|
||||
|
||||
GuiSettingsMenu::~GuiSettingsMenu()
|
||||
|
@ -60,6 +60,13 @@ bool GuiSettingsMenu::input(InputConfig* config, Input input)
|
|||
return true;
|
||||
}
|
||||
|
||||
if(config->isMappedTo("a", input) && mList.getSelectedComponent() == &mSaveLabel && input.value)
|
||||
{
|
||||
applyStates();
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -67,4 +74,16 @@ void GuiSettingsMenu::loadStates()
|
|||
{
|
||||
Settings* s = Settings::getInstance();
|
||||
mDrawFramerateSwitch.setState(s->getBool("DRAWFRAMERATE"));
|
||||
|
||||
mVolumeSlider.setValue((float)VolumeControl::getInstance()->getVolume());
|
||||
}
|
||||
|
||||
void GuiSettingsMenu::applyStates()
|
||||
{
|
||||
Settings* s = Settings::getInstance();
|
||||
s->setBool("DRAWFRAMERATE", mDrawFramerateSwitch.getState());
|
||||
|
||||
VolumeControl::getInstance()->setVolume((int)mVolumeSlider.getValue());
|
||||
|
||||
s->saveFile();
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "ComponentListComponent.h"
|
||||
#include <vector>
|
||||
#include "SwitchComponent.h"
|
||||
#include "SliderComponent.h"
|
||||
#include "TextComponent.h"
|
||||
|
||||
class GuiSettingsMenu : public GuiComponent
|
||||
|
@ -22,6 +23,8 @@ private:
|
|||
ComponentListComponent mList;
|
||||
|
||||
SwitchComponent mDrawFramerateSwitch;
|
||||
SliderComponent mVolumeSlider;
|
||||
TextComponent mSaveLabel;
|
||||
|
||||
std::vector<GuiComponent*> mLabels;
|
||||
};
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
#include <assert.h>
|
||||
#include "../Renderer.h"
|
||||
|
||||
SliderComponent::SliderComponent(Window* window, float min, float max) : GuiComponent(window),
|
||||
mMin(min), mMax(max), mMoveRate(0)
|
||||
SliderComponent::SliderComponent(Window* window, float min, float max, float increment) : GuiComponent(window),
|
||||
mMin(min), mMax(max), mIncrement(increment), mMoveRate(0), mRepeatWaitTimer(0)
|
||||
{
|
||||
assert((min - max) != 0);
|
||||
|
||||
mValue = (max + min) / 2;
|
||||
|
||||
//calculate move scale
|
||||
mMoveScale = (max - min) * 0.0007f;
|
||||
mMoveScale = ((max - min) * 0.0007f) / increment;
|
||||
|
||||
setSize(Vector2u(128, 32));
|
||||
}
|
||||
|
@ -20,19 +20,24 @@ bool SliderComponent::input(InputConfig* config, Input input)
|
|||
if(config->isMappedTo("left", input))
|
||||
{
|
||||
if(input.value)
|
||||
mMoveRate = -1;
|
||||
mMoveRate = -mIncrement;
|
||||
else
|
||||
mMoveRate = 0;
|
||||
|
||||
//setting mRepeatWaitTimer to 0 will trigger an initial move in our update method
|
||||
mRepeatWaitTimer = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
if(config->isMappedTo("right", input))
|
||||
{
|
||||
if(input.value)
|
||||
mMoveRate = 1;
|
||||
mMoveRate = mIncrement;
|
||||
else
|
||||
mMoveRate = 0;
|
||||
|
||||
mRepeatWaitTimer = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -41,13 +46,22 @@ bool SliderComponent::input(InputConfig* config, Input input)
|
|||
|
||||
void SliderComponent::update(int deltaTime)
|
||||
{
|
||||
mValue += mMoveRate * deltaTime * mMoveScale;
|
||||
if(mMoveRate != 0)
|
||||
{
|
||||
if(mRepeatWaitTimer == 0)
|
||||
mValue += mMoveRate;
|
||||
else if(mRepeatWaitTimer >= 450)
|
||||
mValue += mMoveRate * deltaTime * mMoveScale;
|
||||
|
||||
if(mValue < mMin)
|
||||
mValue = mMin;
|
||||
if(mValue > mMax)
|
||||
mValue = mMax;
|
||||
if(mValue < mMin)
|
||||
mValue = mMin;
|
||||
if(mValue > mMax)
|
||||
mValue = mMax;
|
||||
|
||||
if(mRepeatWaitTimer < 450)
|
||||
mRepeatWaitTimer += deltaTime;
|
||||
}
|
||||
|
||||
GuiComponent::update(deltaTime);
|
||||
}
|
||||
|
||||
|
@ -75,3 +89,13 @@ void SliderComponent::setSize(Vector2u size)
|
|||
{
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
void SliderComponent::setValue(float value)
|
||||
{
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
float SliderComponent::getValue()
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
class SliderComponent : public GuiComponent
|
||||
{
|
||||
public:
|
||||
SliderComponent(Window* window, float min, float max);
|
||||
//Minimum value (far left of the slider), maximum value (far right of the slider), increment size (how much just pressing L/R moves by).
|
||||
SliderComponent(Window* window, float min, float max, float increment);
|
||||
|
||||
void setValue(float val);
|
||||
float getValue();
|
||||
|
@ -19,7 +20,9 @@ public:
|
|||
private:
|
||||
float mMin, mMax;
|
||||
float mValue;
|
||||
float mIncrement;
|
||||
float mMoveScale;
|
||||
int mRepeatWaitTimer;
|
||||
|
||||
float mMoveRate;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue