// text.cpp - GUIText object #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern "C" { #include "../common.h" #include "../minuitwrp/minui.h" #include "../recovery_ui.h" } #include "rapidxml.hpp" #include "objects.hpp" GUIText::GUIText(xml_node<>* node) : Conditional(node) { xml_attribute<>* attr; xml_node<>* child; mFont = NULL; mIsStatic = 1; mVarChanged = 0; mFontHeight = 0; maxWidth = 0; charSkip = 0; isHighlighted = false; hasHighlightColor = false; if (!node) return; // Initialize color to solid black memset(&mColor, 0, sizeof(COLOR)); mColor.alpha = 255; memset(&mHighlightColor, 0, sizeof(COLOR)); mHighlightColor.alpha = 255; attr = node->first_attribute("color"); if (attr) { std::string color = attr->value(); ConvertStrToColor(color, &mColor); } attr = node->first_attribute("highlightcolor"); if (attr) { std::string color = attr->value(); ConvertStrToColor(color, &mHighlightColor); hasHighlightColor = true; } // Load the font, and possibly override the color child = node->first_node("font"); if (child) { attr = child->first_attribute("resource"); if (attr) mFont = PageManager::FindResource(attr->value()); attr = child->first_attribute("color"); if (attr) { std::string color = attr->value(); ConvertStrToColor(color, &mColor); } attr = child->first_attribute("highlightcolor"); if (attr) { std::string color = attr->value(); ConvertStrToColor(color, &mHighlightColor); hasHighlightColor = true; } } // Load the placement LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH, &mPlacement); child = node->first_node("text"); if (child) mText = child->value(); // Simple way to check for static state mLastValue = parseText(); if (mLastValue != mText) mIsStatic = 0; gr_getFontDetails(mFont ? mFont->GetResource() : NULL, (unsigned*) &mFontHeight, NULL); return; } int GUIText::Render(void) { if (!isConditionTrue()) return 0; void* fontResource = NULL; string displayValue; if (mFont) fontResource = mFont->GetResource(); mLastValue = parseText(); displayValue = mLastValue; if (charSkip) displayValue.erase(0, charSkip); mVarChanged = 0; int x = mRenderX, y = mRenderY; int width = gr_measureEx(displayValue.c_str(), fontResource); if (mPlacement != TOP_LEFT && mPlacement != BOTTOM_LEFT) { if (mPlacement == CENTER || mPlacement == CENTER_X_ONLY) x -= (width / 2); else x -= width; } if (mPlacement != TOP_LEFT && mPlacement != TOP_RIGHT) { if (mPlacement == CENTER) y -= (mFontHeight / 2); else if (mPlacement == BOTTOM_LEFT || mPlacement == BOTTOM_RIGHT) y -= mFontHeight; } if (hasHighlightColor && isHighlighted) gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha); else gr_color(mColor.red, mColor.green, mColor.blue, mColor.alpha); if (maxWidth) gr_textExW(x, y, displayValue.c_str(), fontResource, maxWidth + x); else gr_textEx(x, y, displayValue.c_str(), fontResource); return 0; } int GUIText::Update(void) { if (!isConditionTrue()) return 0; static int updateCounter = 3; // This hack just makes sure we update at least once a minute for things like clock and battery if (updateCounter) updateCounter--; else { mVarChanged = 1; updateCounter = 3; } if (mIsStatic || !mVarChanged) return 0; std::string newValue = parseText(); if (mLastValue == newValue) return 0; return 2; } int GUIText::GetCurrentBounds(int& w, int& h) { void* fontResource = NULL; if (mFont) fontResource = mFont->GetResource(); h = mFontHeight; w = gr_measureEx(mLastValue.c_str(), fontResource); return 0; } std::string GUIText::parseText(void) { static int counter = 0; std::string str = mText; size_t pos = 0; size_t next = 0, end = 0; while (1) { next = str.find('%', pos); if (next == std::string::npos) return str; end = str.find('%', next + 1); if (end == std::string::npos) return str; // We have a block of data std::string var = str.substr(next + 1, (end - next) - 1); str.erase(next, (end - next) + 1); if (next + 1 == end) { str.insert(next, 1, '%'); } else { std::string value; if (DataManager::GetValue(var, value) == 0) str.insert(next, value); } pos = next + 1; } } int GUIText::NotifyVarChange(std::string varName, std::string value) { mVarChanged = 1; return 0; } int GUIText::SetMaxWidth(unsigned width) { maxWidth = width; mVarChanged = 1; return 0; } int GUIText::SkipCharCount(unsigned skip) { charSkip = skip; mVarChanged = 1; return 0; }