// slidervalue.cpp - GUISliderValue object #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern "C" { #include "../twcommon.h" #include "../minuitwrp/minui.h" } #include "rapidxml.hpp" #include "objects.hpp" GUISliderValue::GUISliderValue(xml_node<>* node) : GUIObject(node) { xml_attribute<>* attr; xml_node<>* child; mMin = 0; mMax = 100; mValue = 0; mLineH = 2; mLinePadding = 10; mSliderW = 5; mSliderH = 30; mLineX = 0; mLineY = 0; mValueStr = NULL; mAction = NULL; mShowCurr = true; mShowRange = false; mChangeOnDrag = false; mRendered = false; mBackgroundImage = NULL; mHandleImage = NULL; mHandleHoverImage = NULL; mDragging = false; mLabel = NULL; ConvertStrToColor("white", &mTextColor); ConvertStrToColor("white", &mLineColor); ConvertStrToColor("blue", &mSliderColor); if (!node) { LOGERR("GUISliderValue created without XML node\n"); return; } mLabel = new GUIText(node); if(mLabel->Render() < 0) { delete mLabel; mLabel = NULL; } mAction = new GUIAction(node); 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, &mTextColor); } } // Load the placement LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW); child = node->first_node("colors"); if (child) { attr = child->first_attribute("line"); if (attr) ConvertStrToColor(attr->value(), &mLineColor); attr = child->first_attribute("slider"); if (attr) ConvertStrToColor(attr->value(), &mSliderColor); } child = node->first_node("resource"); if (child) { attr = child->first_attribute("background"); if(attr) mBackgroundImage = PageManager::FindResource(attr->value()); attr = child->first_attribute("handle"); if(attr) mHandleImage = PageManager::FindResource(attr->value()); attr = child->first_attribute("handlehover"); if(attr) mHandleHoverImage = PageManager::FindResource(attr->value()); } child = node->first_node("data"); if (child) { attr = child->first_attribute("variable"); if (attr) mVariable = attr->value(); attr = child->first_attribute("min"); if (attr) { mMinStr = gui_parse_text(attr->value()); mMin = atoi(mMinStr.c_str()); } attr = child->first_attribute("max"); if (attr) { mMaxStr = gui_parse_text(attr->value()); mMax = atoi(mMaxStr.c_str()); } if (mMin > mMax) mMin = mMax; attr = child->first_attribute("default"); if (attr) { string parsevalue = gui_parse_text(attr->value()); int def = atoi(parsevalue.c_str()); if (def < mMin) def = mMin; else if (def > mMax) def = mMax; DataManager::SetValue(mVariable, def); } attr = child->first_attribute("showrange"); if (attr) mShowRange = atoi(attr->value()); attr = child->first_attribute("showcurr"); if (attr) mShowCurr = atoi(attr->value()); attr = child->first_attribute("changeondrag"); if (attr) mChangeOnDrag = atoi(attr->value()); } child = node->first_node("dimensions"); if (child) { attr = child->first_attribute("lineh"); if (attr) { string parsevalue = gui_parse_text(attr->value()); mLineH = atoi(parsevalue.c_str()); } attr = child->first_attribute("linepadding"); if (attr) { string parsevalue = gui_parse_text(attr->value()); mPadding = atoi(parsevalue.c_str()); } attr = child->first_attribute("sliderw"); if (attr) { string parsevalue = gui_parse_text(attr->value()); mSliderW = atoi(parsevalue.c_str()); } attr = child->first_attribute("sliderh"); if (attr) { string parsevalue = gui_parse_text(attr->value()); mSliderH = atoi(parsevalue.c_str()); } } gr_getFontDetails(mFont ? mFont->GetResource() : NULL, (unsigned*) &mFontHeight, NULL); if(mShowCurr) { int maxLen = std::max(strlen(mMinStr.c_str()), strlen(mMaxStr.c_str())); mValueStr = new char[maxLen+1]; } loadValue(true); mLinePadding = mPadding; if (mShowRange) { int textW = std::max(measureText(mMaxStr), measureText(mMinStr)); mLinePadding += textW; } SetRenderPos(mRenderX, mRenderY, mRenderW); } GUISliderValue::~GUISliderValue() { delete mLabel; delete mAction; delete[] mValueStr; } void GUISliderValue::loadValue(bool force) { if(!mVariable.empty()) { int value = DataManager::GetIntValue(mVariable); if(mValue == value && !force) return; mValue = value; } mValue = std::max(mValue, mMin); mValue = std::min(mValue, mMax); mValuePct = pctFromValue(mValue); mRendered = false; } int GUISliderValue::SetRenderPos(int x, int y, int w, int h) { mRenderX = x; mRenderY = y; if (w || h) { mRenderW = w; mRenderH = h; } mRenderH = mSliderH; if(mShowCurr) mRenderH += mFontHeight; if (mLabel) { int lw, lh; mLabel->GetCurrentBounds(lw, lh); int textX = mRenderX + (mRenderW/2 - lw/2); mLabel->SetRenderPos(textX, mRenderY); y += lh; mRenderH += lh; } mSliderY = y; mActionX = mRenderX; mActionY = mRenderY; mActionW = mRenderW; mActionH = mRenderH; if(mBackgroundImage && mBackgroundImage->GetResource()) { mLineW = gr_get_width(mBackgroundImage->GetResource()); mLineH = gr_get_height(mBackgroundImage->GetResource()); } else mLineW = mRenderW - (mLinePadding * 2); mLineY = y + (mSliderH/2 - mLineH/2); mLineX = mRenderX + (mRenderW/2 - mLineW/2); return 0; } int GUISliderValue::measureText(const std::string& str) { void* fontResource = NULL; if (mFont) fontResource = mFont->GetResource(); return gr_measureEx(str.c_str(), fontResource); } int GUISliderValue::Render(void) { if (!isConditionTrue()) { mRendered = false; return 0; } if(mLabel) { int w, h; mLabel->GetCurrentBounds(w, h); if (w != mLabelW) { mLabelW = w; int textX = mRenderX + (mRenderW/2 - mLabelW/2); mLabel->SetRenderPos(textX, mRenderY); } int res = mLabel->Render(); if(res < 0) return res; } // line if(mBackgroundImage && mBackgroundImage->GetResource()) { gr_blit(mBackgroundImage->GetResource(), 0, 0, mLineW, mLineH, mLineX, mLineY); } else { gr_color(mLineColor.red, mLineColor.green, mLineColor.blue, mLineColor.alpha); gr_fill(mLineX, mLineY, mLineW, mLineH); } // slider uint32_t sliderX = mLineX + (mValuePct*(mLineW - mSliderW))/100; if(mHandleImage && mHandleImage->GetResource()) { gr_surface s = mHandleImage->GetResource(); if(mDragging && mHandleHoverImage && mHandleHoverImage->GetResource()) s = mHandleHoverImage->GetResource(); gr_blit(s, 0, 0, mSliderW, mSliderH, sliderX, mLineY + (mLineH/2 - mSliderH/2)); } else { gr_color(mSliderColor.red, mSliderColor.green, mSliderColor.blue, mSliderColor.alpha); gr_fill(sliderX, mSliderY, mSliderW, mSliderH); } void *fontResource = NULL; if(mFont) fontResource = mFont->GetResource(); gr_color(mTextColor.red, mTextColor.green, mTextColor.blue, mTextColor.alpha); if(mShowRange) { int rangeY = (mLineY - mLineH/2) - mFontHeight/2; gr_textEx(mRenderX + mPadding/2, rangeY, mMinStr.c_str(), fontResource); gr_textEx(mLineX + mLineW + mPadding/2, rangeY, mMaxStr.c_str(), fontResource); } if(mValueStr && mShowCurr) { sprintf(mValueStr, "%d", mValue); int textW = measureText(mValueStr); gr_textEx(mRenderX + (mRenderW/2 - textW/2), mSliderY+mSliderH, mValueStr, fontResource); } mRendered = true; return 0; } int GUISliderValue::Update(void) { if (!isConditionTrue()) return mRendered ? 2 : 0; if (!mRendered) return 2; if(mLabel) return mLabel->Update(); return 0; } int GUISliderValue::valueFromPct(float pct) { int range = abs(mMax - mMin); return mMin + (pct * range) / 100; } float GUISliderValue::pctFromValue(int value) { return float((value - mMin) * 100) / abs(mMax - mMin); } int GUISliderValue::NotifyTouch(TOUCH_STATE state, int x, int y) { if (!isConditionTrue()) return -1; switch (state) { case TOUCH_START: if (x >= mLineX && x <= mLineX + mLineW && y >= mRenderY && y <= mRenderY + mRenderH) { mDragging = true; } // no break case TOUCH_DRAG: { if (!mDragging) return 0; x = std::max(mLineX + mSliderW/2, x); x = std::min(mLineX + mLineW - mSliderW/2, x); mValuePct = float(((x - (mLineX + mSliderW/2)) * 100) / (mLineW - mSliderW)); int newVal = valueFromPct(mValuePct); if (newVal != mValue) { mRendered = false; mValue = newVal; if (mChangeOnDrag) { if (!mVariable.empty()) DataManager::SetValue(mVariable, mValue); if (mAction) mAction->doActions(); } } break; } case TOUCH_RELEASE: { if (!mDragging) return 0; mDragging = false; if (!mVariable.empty()) DataManager::SetValue(mVariable, mValue); if (mAction) mAction->doActions(); break; } case TOUCH_REPEAT: case TOUCH_HOLD: break; } return 0; } int GUISliderValue::NotifyVarChange(const std::string& varName, const std::string& value) { GUIObject::NotifyVarChange(varName, value); if (mLabel) mLabel->NotifyVarChange(varName, value); if (varName == mVariable) { int newVal = atoi(value.c_str()); if(newVal != mValue) { mValue = newVal; mValuePct = pctFromValue(mValue); mRendered = false; } } return 0; } void GUISliderValue::SetPageFocus(int inFocus) { if (inFocus) loadValue(); }