mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-21 21:55:38 +00:00
Both user changes and scraper changes are now color marked in the metadata editor.
User changes are marked with blue and scraper changes with red.
This commit is contained in:
parent
1b65eaac2e
commit
70d0057295
4
NEWS.md
4
NEWS.md
|
@ -8,7 +8,7 @@ v1.0.0
|
|||
* Many quality of life improvements and removal of GUI inconsistencies
|
||||
* New game media file logic using a media directory with files matching the ROM names instead of pointing to the media files in gamelist.xml
|
||||
* Updated scraper to support additional media files, detailed configuration of what to scrape, semi-automatic mode etc.
|
||||
* For single-game scraping, any values updated by the scraper are now highlighted using a different font color in the metadata editor
|
||||
* In the metadata editor, any values updated by the single-game scraper or by the user are now highlighted using a different font color
|
||||
* Gamelist sorting now working as expected and is persistent throughout the application session
|
||||
* Full navigation sound support, configurable per theme
|
||||
* New default theme rbsimple-DE bundled with the software, this theme is largely based on recalbox-multi by the Recalbox community
|
||||
|
@ -37,7 +37,7 @@ v1.0.0
|
|||
### Bug fixes
|
||||
|
||||
* Metadata editor insisted that changes were made although nothing was updated
|
||||
Note: The editor will still ask for save confirmations after automatically rounding fractional game ratings to half-star values
|
||||
Note: The editor will still ask for save confirmations after automatically rounding fractional game ratings to half-star values, but any time such a rounding has taken place, the rating stars will be colored green in the metadata editor to nofity the user
|
||||
* Game images were sometimes scaled incorrectly
|
||||
* Non-transparent favorite icons were not rendered correctly
|
||||
* Restart and power-off menu entries not working
|
||||
|
|
|
@ -46,8 +46,7 @@ GuiMetaDataEd::GuiMetaDataEd(
|
|||
mMetaDataDecl(mdd),
|
||||
mMetaData(md),
|
||||
mSavedCallback(saveCallback),
|
||||
mDeleteFunc(deleteFunc),
|
||||
mMetadataUpdated(false)
|
||||
mDeleteFunc(deleteFunc)
|
||||
{
|
||||
addChild(&mBackground);
|
||||
addChild(&mGrid);
|
||||
|
@ -70,6 +69,7 @@ GuiMetaDataEd::GuiMetaDataEd(
|
|||
// Populate list.
|
||||
for (auto iter = mdd.cbegin(); iter != mdd.cend(); iter++) {
|
||||
std::shared_ptr<GuiComponent> ed;
|
||||
std::string originalValue;
|
||||
|
||||
// Don't add statistics.
|
||||
if (iter->isStatistic)
|
||||
|
@ -99,6 +99,7 @@ GuiMetaDataEd::GuiMetaDataEd(
|
|||
switch (iter->type) {
|
||||
case MD_BOOL: {
|
||||
ed = std::make_shared<SwitchComponent>(window);
|
||||
ed->setChangedColor(ICONCOLOR_USERMARKED);
|
||||
row.addElement(ed, false, true);
|
||||
break;
|
||||
}
|
||||
|
@ -107,7 +108,8 @@ GuiMetaDataEd::GuiMetaDataEd(
|
|||
spacer->setSize(Renderer::getScreenWidth() * 0.0025f, 0);
|
||||
row.addElement(spacer, false);
|
||||
|
||||
ed = std::make_shared<RatingComponent>(window);
|
||||
ed = std::make_shared<RatingComponent>(window, true);
|
||||
ed->setChangedColor(ICONCOLOR_USERMARKED);
|
||||
const float height = lbl->getSize().y() * 0.71f;
|
||||
ed->setSize(0, height);
|
||||
row.addElement(ed, false, true);
|
||||
|
@ -123,6 +125,7 @@ GuiMetaDataEd::GuiMetaDataEd(
|
|||
row.addElement(spacer, false);
|
||||
|
||||
ed = std::make_shared<DateTimeEditComponent>(window);
|
||||
ed->setChangedColor(TEXTCOLOR_USERMARKED);
|
||||
row.addElement(ed, false);
|
||||
|
||||
// Pass input to the actual DateTimeEditComponent instead of the spacer.
|
||||
|
@ -130,12 +133,14 @@ GuiMetaDataEd::GuiMetaDataEd(
|
|||
std::placeholders::_1, std::placeholders::_2);
|
||||
break;
|
||||
}
|
||||
case MD_TIME: {
|
||||
ed = std::make_shared<DateTimeEditComponent>(window,
|
||||
DateTimeEditComponent::DISP_RELATIVE_TO_NOW);
|
||||
row.addElement(ed, false);
|
||||
break;
|
||||
}
|
||||
// Not in use as 'lastplayed' is flagged as statistics and these are skipped.
|
||||
// Let's still keep the code because it may be needed in the future.
|
||||
// case MD_TIME: {
|
||||
// ed = std::make_shared<DateTimeEditComponent>(window,
|
||||
// DateTimeEditComponent::DISP_RELATIVE_TO_NOW);
|
||||
// row.addElement(ed, false);
|
||||
// break;
|
||||
// }
|
||||
case MD_LAUNCHCOMMAND: {
|
||||
ed = std::make_shared<TextComponent>(window, "",
|
||||
Font::get(FONT_SIZE_SMALL, FONT_PATH_LIGHT), 0x777777FF, ALIGN_RIGHT);
|
||||
|
@ -152,8 +157,17 @@ GuiMetaDataEd::GuiMetaDataEd(
|
|||
|
||||
bool multiLine = false;
|
||||
const std::string title = iter->displayPrompt;
|
||||
auto updateVal = [ed](const std::string& newVal) {
|
||||
ed->setValue(newVal); }; // OK callback (apply new value to ed).
|
||||
|
||||
originalValue = mMetaData->get(iter->key);
|
||||
|
||||
// OK callback (apply new value to ed).
|
||||
auto updateVal = [ed, originalValue](const std::string& newVal) {
|
||||
ed->setValue(newVal);
|
||||
if (newVal == originalValue)
|
||||
ed->setColor(DEFAULT_TEXTCOLOR);
|
||||
else
|
||||
ed->setColor(TEXTCOLOR_USERMARKED);
|
||||
};
|
||||
|
||||
std::string staticTextString = "Default value from es_systems.cfg:";
|
||||
std::string defaultLaunchCommand = scraperParams.system->
|
||||
|
@ -186,8 +200,17 @@ GuiMetaDataEd::GuiMetaDataEd(
|
|||
bool multiLine = iter->type == MD_MULTILINE_STRING;
|
||||
const std::string title = iter->displayPrompt;
|
||||
|
||||
originalValue = mMetaData->get(iter->key);
|
||||
|
||||
// OK callback (apply new value to ed).
|
||||
auto updateVal = [ed](const std::string& newVal) { ed->setValue(newVal); };
|
||||
auto updateVal = [ed, originalValue](const std::string& newVal) {
|
||||
ed->setValue(newVal);
|
||||
if (newVal == originalValue)
|
||||
ed->setColor(DEFAULT_TEXTCOLOR);
|
||||
else
|
||||
ed->setColor(TEXTCOLOR_USERMARKED);
|
||||
};
|
||||
|
||||
row.makeAcceptInputHandler([this, title, ed, updateVal, multiLine] {
|
||||
mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), title,
|
||||
ed->getValue(), updateVal, multiLine, "APPLY", "APPLY CHANGES?"));
|
||||
|
@ -202,7 +225,7 @@ GuiMetaDataEd::GuiMetaDataEd(
|
|||
mEditors.push_back(ed);
|
||||
}
|
||||
|
||||
std::vector< std::shared_ptr<ButtonComponent> > buttons;
|
||||
std::vector<std::shared_ptr<ButtonComponent>> buttons;
|
||||
|
||||
if (mScraperParams.game->getType() != FOLDER) {
|
||||
if (!scraperParams.system->hasPlatformId(PlatformIds::PLATFORM_IGNORE))
|
||||
|
@ -217,10 +240,10 @@ GuiMetaDataEd::GuiMetaDataEd(
|
|||
|
||||
if (mDeleteFunc) {
|
||||
auto deleteFileAndSelf = [&] { mDeleteFunc(); delete this; };
|
||||
auto deleteBtnFunc = [this, deleteFileAndSelf] { mWindow->pushGui(
|
||||
new GuiMsgBox(mWindow, getHelpStyle(),
|
||||
"THIS WILL DELETE THE ACTUAL GAME FILE(S)!\nARE YOU SURE?",
|
||||
"YES", deleteFileAndSelf, "NO", nullptr)); };
|
||||
auto deleteBtnFunc = [this, deleteFileAndSelf] {
|
||||
mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(),
|
||||
"THIS WILL DELETE THE ACTUAL GAME FILE(S)!\nARE YOU SURE?",
|
||||
"YES", deleteFileAndSelf, "NO", nullptr)); };
|
||||
buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "DELETE",
|
||||
"delete game", deleteBtnFunc));
|
||||
}
|
||||
|
@ -303,20 +326,21 @@ void GuiMetaDataEd::fetchDone(const ScraperSearchResult& result)
|
|||
metadata->set(key, mEditors[i]->getValue());
|
||||
}
|
||||
|
||||
mMetadataUpdated = GuiScraperSearch::saveMetadata(result, *metadata);
|
||||
GuiScraperSearch::saveMetadata(result, *metadata);
|
||||
|
||||
// Update the list with the scraped metadata values.
|
||||
for (unsigned int i = 0; i < mEditors.size(); i++) {
|
||||
const std::string& key = mMetaDataDecl.at(i).key;
|
||||
if (mEditors.at(i)->getValue() != metadata->get(key)) {
|
||||
if (key == "rating") {
|
||||
mEditors.at(i)->setColorShift(0xDD2222FF);
|
||||
}
|
||||
else {
|
||||
mEditors.at(i)->setColor(0x994444FF);
|
||||
}
|
||||
if (key == "rating")
|
||||
mEditors.at(i)->setOriginalColor(ICONCOLOR_SCRAPERMARKED);
|
||||
else
|
||||
mEditors.at(i)->setColor(TEXTCOLOR_SCRAPERMARKED);
|
||||
}
|
||||
mEditors.at(i)->setValue(metadata->get(key));
|
||||
// Save all the keys, except the following which can't be scraped.
|
||||
if (key != "favorite" && key != "completed" && key != "broken" &&
|
||||
key != "hidden" && key != "kidgame")
|
||||
mEditors.at(i)->setValue(metadata->get(key));
|
||||
}
|
||||
|
||||
delete metadata;
|
||||
|
@ -325,7 +349,7 @@ void GuiMetaDataEd::fetchDone(const ScraperSearchResult& result)
|
|||
void GuiMetaDataEd::close()
|
||||
{
|
||||
// Find out if the user made any changes.
|
||||
bool dirty = mMetadataUpdated;
|
||||
bool metadataUpdated = false;
|
||||
for (unsigned int i = 0; i < mEditors.size(); i++) {
|
||||
const std::string& key = mMetaDataDecl.at(i).key;
|
||||
std::string mMetaDataValue = mMetaData->get(key);
|
||||
|
@ -337,7 +361,7 @@ void GuiMetaDataEd::close()
|
|||
mMetaDataValue = "19700101T010000";
|
||||
|
||||
if (mMetaDataValue != mEditorsValue) {
|
||||
dirty = true;
|
||||
metadataUpdated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -358,7 +382,7 @@ void GuiMetaDataEd::close()
|
|||
std::function<void()> closeFunc;
|
||||
closeFunc = [this] { delete this; };
|
||||
|
||||
if (dirty) {
|
||||
if (metadataUpdated) {
|
||||
// Changes were made, ask if the user wants to save them.
|
||||
mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(),
|
||||
"SAVE CHANGES?",
|
||||
|
|
|
@ -54,14 +54,13 @@ private:
|
|||
|
||||
ScraperSearchParams mScraperParams;
|
||||
|
||||
std::vector< std::shared_ptr<GuiComponent> > mEditors;
|
||||
std::vector<std::shared_ptr<GuiComponent>> mEditors;
|
||||
|
||||
std::vector<MetaDataDecl> mMetaDataDecl;
|
||||
MetaDataList* mMetaData;
|
||||
std::function<void()> mSavedCallback;
|
||||
std::function<void()> mDeleteFunc;
|
||||
|
||||
bool mMetadataUpdated;
|
||||
bool mMediaFilesUpdated;
|
||||
};
|
||||
|
||||
|
|
|
@ -16,6 +16,14 @@
|
|||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#define DEFAULT_TEXTCOLOR 0x777777FF
|
||||
#define DEFAULT_INVERTED_TEXTCOLOR 0x444444FF
|
||||
#define DEFAULT_COLORSHIFT 0xFFFFFFFF
|
||||
#define ICONCOLOR_SCRAPERMARKED 0xFF5555FF
|
||||
#define ICONCOLOR_USERMARKED 0x5555FFFF
|
||||
#define TEXTCOLOR_SCRAPERMARKED 0x992222FF
|
||||
#define TEXTCOLOR_USERMARKED 0x222299FF
|
||||
|
||||
class Animation;
|
||||
class AnimationController;
|
||||
class Font;
|
||||
|
@ -132,6 +140,8 @@ public:
|
|||
virtual void setOpacity(unsigned char opacity);
|
||||
virtual void setColor(unsigned int color);
|
||||
virtual void setColorShift(unsigned int color);
|
||||
virtual void setOriginalColor(unsigned int color) { mColorOriginalValue = color; };
|
||||
virtual void setChangedColor(unsigned int color) { mColorChangedValue = color; };
|
||||
virtual unsigned int getColor() const;
|
||||
|
||||
const Transform4x4f& getTransform();
|
||||
|
@ -177,6 +187,9 @@ protected:
|
|||
unsigned char mColorOpacity;
|
||||
unsigned int mColorShift;
|
||||
unsigned int mColorShiftEnd;
|
||||
unsigned int mColorOriginalValue;
|
||||
unsigned int mColorChangedValue;
|
||||
|
||||
Window* mWindow;
|
||||
|
||||
GuiComponent* mParent;
|
||||
|
|
|
@ -203,15 +203,20 @@ void ComponentList::render(const Transform4x4f& parentTrans)
|
|||
it->component->render(trans);
|
||||
}
|
||||
else {
|
||||
// If there is a hue, average the brightness values to make
|
||||
// an equivalent gray value before inverting the text.
|
||||
// This is not the proper way to do a BW conversion as the RGB values
|
||||
// should not be evenly distributed, but it's definitely good enough
|
||||
// for this situation.
|
||||
unsigned char byteAverage = (byteRed + byteGreen + byteBlue) / 3;
|
||||
unsigned int averageColor = byteAverage << 24 | byteAverage << 16 |
|
||||
byteAverage << 8 | 0xFF;
|
||||
it->component->setColor(averageColor);
|
||||
// Note: I've disabled this code as it's overly complicated,
|
||||
// instead we're now using a simple constant which should be
|
||||
// good enough. Let's keep the code though if needed in the
|
||||
// future for some reason.
|
||||
// // If there is a hue, average the brightness values to make
|
||||
// // an equivalent gray value before inverting the text.
|
||||
// // This is not the proper way to do a BW conversion as the RGB values
|
||||
// // should not be evenly distributed, but it's definitely good enough
|
||||
// // for this situation.
|
||||
// unsigned char byteAverage = (byteRed + byteGreen + byteBlue) / 3;
|
||||
// unsigned int averageColor = byteAverage << 24 | byteAverage << 16 |
|
||||
// byteAverage << 8 | 0xFF;
|
||||
// it->component->setColor(averageColor);
|
||||
it->component->setColor(DEFAULT_INVERTED_TEXTCOLOR);
|
||||
it->component->render(trans);
|
||||
// Revert to the original color after rendering.
|
||||
it->component->setColor(origColor);
|
||||
|
@ -221,8 +226,9 @@ void ComponentList::render(const Transform4x4f& parentTrans)
|
|||
it->component->render(trans);
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
drawAfterCursor.push_back(it->component.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ struct ComponentListRow
|
|||
elements.push_back(ComponentListElement(component, resize_width, invert_when_selected));
|
||||
}
|
||||
|
||||
// Utility method for making an input handler for "when the users presses A on this, do func".
|
||||
// Utility function for making an input handler for "when the users presses A on this, do func".
|
||||
inline void makeAcceptInputHandler(const std::function<void()>& func)
|
||||
{
|
||||
input_handler = [func](InputConfig* config, Input input) -> bool {
|
||||
|
|
|
@ -107,6 +107,12 @@ bool DateTimeEditComponent::input(InputConfig* config, Input input)
|
|||
|
||||
mTime = new_tm;
|
||||
|
||||
// Change the color of the text to reflect the changes.
|
||||
if (mTime == mOriginalValue)
|
||||
setColor(mColorOriginalValue);
|
||||
else
|
||||
setColor(mColorChangedValue);
|
||||
|
||||
updateTextCache();
|
||||
return true;
|
||||
}
|
||||
|
@ -170,6 +176,7 @@ void DateTimeEditComponent::render(const Transform4x4f& parentTrans)
|
|||
void DateTimeEditComponent::setValue(const std::string& val)
|
||||
{
|
||||
mTime = val;
|
||||
mOriginalValue = val;
|
||||
updateTextCache();
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,10 @@ public:
|
|||
// Text color.
|
||||
void setColor(unsigned int color) override;
|
||||
// Font to use. Default is Font::get(FONT_SIZE_MEDIUM).
|
||||
|
||||
void setOriginalColor(unsigned int color) override { mColorOriginalValue = color; };
|
||||
void setChangedColor(unsigned int color) override { mColorChangedValue = color; };
|
||||
|
||||
void setFont(std::shared_ptr<Font> font);
|
||||
// Force text to be uppercase when in DISP_RELATIVE_TO_NOW mode.
|
||||
void setUppercase(bool uppercase);
|
||||
|
@ -76,6 +80,10 @@ private:
|
|||
std::vector<Vector4f> mCursorBoxes;
|
||||
|
||||
unsigned int mColor;
|
||||
Utils::Time::DateTime mOriginalValue;
|
||||
unsigned int mColorOriginalValue;
|
||||
unsigned int mColorChangedValue;
|
||||
|
||||
std::shared_ptr<Font> mFont;
|
||||
bool mUppercase;
|
||||
bool mAutoSize;
|
||||
|
|
|
@ -363,7 +363,6 @@ void ImageComponent::render(const Transform4x4f& parentTrans)
|
|||
// 'jump' in when it finally loads.
|
||||
fadeIn(mTexture->bind());
|
||||
Renderer::drawTriangleStrips(&mVertices[0], 4);
|
||||
|
||||
}
|
||||
else {
|
||||
LOG(LogError) << "Image texture is not initialized!";
|
||||
|
|
|
@ -11,8 +11,16 @@
|
|||
#include "Settings.h"
|
||||
#include "ThemeData.h"
|
||||
|
||||
RatingComponent::RatingComponent(Window* window) : GuiComponent(window),
|
||||
mColorShift(0xFFFFFFFF), mColorShiftEnd(0xFFFFFFFF), mUnfilledColor(0xFFFFFFFF)
|
||||
RatingComponent::RatingComponent(
|
||||
Window* window,
|
||||
bool colorizeChanges)
|
||||
: GuiComponent(window),
|
||||
mColorShift(DEFAULT_COLORSHIFT),
|
||||
mColorShiftEnd(DEFAULT_COLORSHIFT),
|
||||
mUnfilledColor(DEFAULT_COLORSHIFT),
|
||||
mColorizeChanges(colorizeChanges),
|
||||
mColorOriginalValue(DEFAULT_COLORSHIFT),
|
||||
mColorChangedValue(DEFAULT_COLORSHIFT)
|
||||
{
|
||||
mFilledTexture = TextureResource::get(":/graphics/star_filled.svg", true);
|
||||
mUnfilledTexture = TextureResource::get(":/graphics/star_unfilled.svg", true);
|
||||
|
@ -30,6 +38,26 @@ void RatingComponent::setValue(const std::string& value)
|
|||
else {
|
||||
// Round up to the closest .1 value, i.e. to the closest half-icon.
|
||||
mValue = Math::ceilf(stof(value) / 0.1) / 10;
|
||||
mOriginalValue = static_cast<int>(mValue * 10);
|
||||
|
||||
// If the argument to colorize the rating icons has been passed, set the
|
||||
// color shift accordingly.
|
||||
if (mColorizeChanges) {
|
||||
if (static_cast<int>(mValue * 10) == mOriginalValue)
|
||||
setColorShift(mColorOriginalValue);
|
||||
else
|
||||
setColorShift(mColorChangedValue);
|
||||
}
|
||||
|
||||
// For the special situation where there is a fractional rating in the gamelist.xml
|
||||
// file that has been rounded to a half-star rating, render the rating icons green.
|
||||
// This should only happen if an external scraper has been used or if the file has
|
||||
// been manually edited.
|
||||
if (mColorizeChanges && mValue != stof(value)) {
|
||||
mOriginalValue = ICONCOLOR_USERMARKED;
|
||||
setColorShift(0x449944FF);
|
||||
}
|
||||
|
||||
if (mValue > 1.0f)
|
||||
mValue = 1.0f;
|
||||
else if (mValue < 0.0f)
|
||||
|
@ -102,11 +130,12 @@ void RatingComponent::updateVertices()
|
|||
mVertices[6] = { { fw, 0.0f }, { numStars, 1.0f }, color };
|
||||
mVertices[7] = { { fw, h }, { numStars, 0.0f }, color };
|
||||
|
||||
// Round vertices.
|
||||
// Disabled as it caused subtle but strange rendering errors where
|
||||
// the icons changed size slightly when changing rating scores.
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// mVertices[i].pos.round();
|
||||
|
||||
// Disabled this code as it caused subtle but strange rendering errors
|
||||
// where the icons changed size slightly when changing rating scores.
|
||||
// // Round vertices.
|
||||
// for (int i = 0; i < 8; ++i)
|
||||
// mVertices[i].pos.round();
|
||||
}
|
||||
|
||||
void RatingComponent::updateColors()
|
||||
|
@ -162,6 +191,14 @@ bool RatingComponent::input(InputConfig* config, Input input)
|
|||
if (mValue > 1.05f)
|
||||
mValue = 0.0f;
|
||||
|
||||
// If the argument to colorize the rating icons has been passed,
|
||||
// set the color shift accordingly.
|
||||
if (mColorizeChanges) {
|
||||
if (static_cast<int>(mValue * 10) == mOriginalValue)
|
||||
setColorShift(mColorOriginalValue);
|
||||
else
|
||||
setColorShift(mColorChangedValue);
|
||||
}
|
||||
updateVertices();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ class TextureResource;
|
|||
class RatingComponent : public GuiComponent
|
||||
{
|
||||
public:
|
||||
RatingComponent(Window* window);
|
||||
RatingComponent(Window* window, bool colorizeChanges = false);
|
||||
|
||||
std::string getValue() const override;
|
||||
// Should be a normalized float (in the range [0..1]) - if it's not, it will be clamped.
|
||||
|
@ -40,6 +40,9 @@ public:
|
|||
// Multiply all pixels in the image by this color when rendering.
|
||||
void setColorShift(unsigned int color) override;
|
||||
|
||||
void setOriginalColor(unsigned int color) override { mColorOriginalValue = color; };
|
||||
void setChangedColor(unsigned int color) override { mColorChangedValue = color; };
|
||||
|
||||
virtual void applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view,
|
||||
const std::string& element, unsigned int properties) override;
|
||||
|
||||
|
@ -52,6 +55,9 @@ private:
|
|||
void updateColors();
|
||||
|
||||
float mValue;
|
||||
int mOriginalValue;
|
||||
unsigned int mColorOriginalValue;
|
||||
unsigned int mColorChangedValue;
|
||||
|
||||
Renderer::Vertex mVertices[8];
|
||||
|
||||
|
@ -61,6 +67,8 @@ private:
|
|||
|
||||
std::shared_ptr<TextureResource> mFilledTexture;
|
||||
std::shared_ptr<TextureResource> mUnfilledTexture;
|
||||
|
||||
bool mColorizeChanges;
|
||||
};
|
||||
|
||||
#endif // ES_APP_COMPONENTS_RATING_COMPONENT_H
|
||||
|
|
|
@ -13,7 +13,9 @@ SwitchComponent::SwitchComponent(
|
|||
bool state)
|
||||
: GuiComponent(window),
|
||||
mImage(window),
|
||||
mState(state)
|
||||
mState(state),
|
||||
mColorOriginalValue(DEFAULT_COLORSHIFT),
|
||||
mColorChangedValue(DEFAULT_COLORSHIFT)
|
||||
{
|
||||
mImage.setImage(":/graphics/off.svg");
|
||||
mImage.setResize(0, Font::get(FONT_SIZE_MEDIUM)->getLetterHeight());
|
||||
|
@ -65,12 +67,20 @@ void SwitchComponent::setValue(const std::string& statestring)
|
|||
mState = true;
|
||||
else
|
||||
mState = false;
|
||||
|
||||
mOriginalValue = mState;
|
||||
onStateChanged();
|
||||
}
|
||||
|
||||
void SwitchComponent::onStateChanged()
|
||||
{
|
||||
mImage.setImage(mState ? ":/graphics/on.svg" : ":/graphics/off.svg");
|
||||
|
||||
// Change the color of the switch to reflect the changes.
|
||||
if (mState == mOriginalValue)
|
||||
mImage.setColorShift(mColorOriginalValue);
|
||||
else
|
||||
mImage.setColorShift(mColorChangedValue);
|
||||
}
|
||||
|
||||
std::vector<HelpPrompt> SwitchComponent::getHelpPrompts()
|
||||
|
|
|
@ -26,6 +26,9 @@ public:
|
|||
std::string getValue() const override;
|
||||
void setValue(const std::string& statestring) override;
|
||||
|
||||
void setOriginalColor(unsigned int color) override { mColorOriginalValue = color; };
|
||||
void setChangedColor(unsigned int color) override { mColorChangedValue = color; };
|
||||
|
||||
virtual std::vector<HelpPrompt> getHelpPrompts() override;
|
||||
|
||||
private:
|
||||
|
@ -33,6 +36,9 @@ private:
|
|||
|
||||
ImageComponent mImage;
|
||||
bool mState;
|
||||
bool mOriginalValue;
|
||||
unsigned int mColorOriginalValue;
|
||||
unsigned int mColorChangedValue;
|
||||
};
|
||||
|
||||
#endif // ES_CORE_COMPONENTS_SWITCH_COMPONENT_H
|
||||
|
|
|
@ -88,10 +88,9 @@ void TextComponent::setRenderBackground(bool render)
|
|||
// Scale the opacity.
|
||||
void TextComponent::setOpacity(unsigned char opacity)
|
||||
{
|
||||
// This method is mostly called to do fading in-out of the Text component element.
|
||||
// This function is mostly called to do fading in-out of the Text component element.
|
||||
// Therefore, we assume here that opacity is a fractional value (expressed as an int 0-255),
|
||||
// of the opacity originally set with setColor() or setBackgroundColor().
|
||||
|
||||
unsigned char o = (unsigned char)((float)opacity / 255.f * (float) mColorOpacity);
|
||||
mColor = (mColor & 0xFFFFFF00) | (unsigned char) o;
|
||||
|
||||
|
|
|
@ -552,7 +552,7 @@ TextCache* Font::buildTextCache(
|
|||
float y = offset[1] + (yBot + yTop)/2.0f;
|
||||
|
||||
// Vertices by texture.
|
||||
std::map< FontTexture*, std::vector<Renderer::Vertex> > vertMap;
|
||||
std::map<FontTexture*, std::vector<Renderer::Vertex>> vertMap;
|
||||
|
||||
size_t cursor = 0;
|
||||
while (cursor < text.length()) {
|
||||
|
@ -581,8 +581,8 @@ TextCache* Font::buildTextCache(
|
|||
verts.resize(oldVertSize + 6);
|
||||
Renderer::Vertex* vertices = verts.data() + oldVertSize;
|
||||
|
||||
const float glyphStartX = x + glyph->bearing.x();
|
||||
const Vector2i& textureSize = glyph->texture->textureSize;
|
||||
const float glyphStartX = x + glyph->bearing.x();
|
||||
const Vector2i& textureSize = glyph->texture->textureSize;
|
||||
const unsigned int convertedColor = Renderer::convertColor(color);
|
||||
|
||||
vertices[1] = {
|
||||
|
|
Loading…
Reference in a new issue