GUIListBox::GUIListBox(xml_node<>* node) : GUIScrollList(node)
{
	xml_attribute<>* attr;
	xml_node<>* child;
	mIconSelected = mIconUnselected = NULL;
	mUpdate = 0;

	// Get the icons, if any
	child = FindNode(node, "icon");
	if (child) {
		mIconSelected = LoadAttrImage(child, "selected");
		mIconUnselected = LoadAttrImage(child, "unselected");
	}
	int iconWidth = std::max(mIconSelected->GetWidth(), mIconUnselected->GetWidth());
	int iconHeight = std::max(mIconSelected->GetHeight(), mIconUnselected->GetHeight());
	SetMaxIconSize(iconWidth, iconHeight);

	// Handle the result variable
	child = FindNode(node, "data");
	if (child) {
		attr = child->first_attribute("name");
		if (attr)
			mVariable = attr->value();
		attr = child->first_attribute("default");
		if (attr)
			DataManager::SetValue(mVariable, attr->value());
		// Get the currently selected value for the list
		DataManager::GetValue(mVariable, currentValue);
	}
	else
		allowSelection = false;		// allows using listbox as a read-only list

	// Get the data for the list
	child = FindNode(node, "listitem");
	if (!child) return;
	while (child) {
		ListData data;

		attr = child->first_attribute("name");
		if (!attr)
			continue;
		data.displayName = gui_parse_text(attr->value());
		data.variableValue = gui_parse_text(child->value());
		if (child->value() == currentValue) {
			data.selected = 1;
		} else {
			data.selected = 0;
		}
		data.action = NULL;
		xml_node<>* action = child->first_node("action");
		if (action) {
			data.action = new GUIAction(action);
			allowSelection = true;
		}

		mList.push_back(data);

		child = child->next_sibling("listitem");
	}
}
int GUIAction::compute(std::string arg)
{
	if (arg.find("+") != string::npos)
	{
		string varName = arg.substr(0, arg.find('+'));
		string string_to_add = arg.substr(arg.find('+') + 1, string::npos);
		int amount_to_add = atoi(string_to_add.c_str());
		int value;

		DataManager::GetValue(varName, value);
		DataManager::SetValue(varName, value + amount_to_add);
		return 0;
	}
	if (arg.find("-") != string::npos)
	{
		string varName = arg.substr(0, arg.find('-'));
		string string_to_subtract = arg.substr(arg.find('-') + 1, string::npos);
		int amount_to_subtract = atoi(string_to_subtract.c_str());
		int value;

		DataManager::GetValue(varName, value);
		value -= amount_to_subtract;
		if (value <= 0)
			value = 0;
		DataManager::SetValue(varName, value);
		return 0;
	}
	if (arg.find("*") != string::npos)
	{
		string varName = arg.substr(0, arg.find('*'));
		string multiply_by_str = gui_parse_text(arg.substr(arg.find('*') + 1, string::npos));
		int multiply_by = atoi(multiply_by_str.c_str());
		int value;

		DataManager::GetValue(varName, value);
		DataManager::SetValue(varName, value*multiply_by);
		return 0;
	}
	if (arg.find("/") != string::npos)
	{
		string varName = arg.substr(0, arg.find('/'));
		string divide_by_str = gui_parse_text(arg.substr(arg.find('/') + 1, string::npos));
		int divide_by = atoi(divide_by_str.c_str());
		int value;

		if(divide_by != 0)
		{
			DataManager::GetValue(varName, value);
			DataManager::SetValue(varName, value/divide_by);
		}
		return 0;
	}
	LOGERR("Unable to perform compute '%s'\n", arg.c_str());
	return -1;
}
Example #3
0
int GUIAction::doAction(const Action& action)
{
    std::string function = gui_parse_text(action.mFunction);
    std::string arg = gui_parse_text(action.mArg);

    // find function and execute it
    auto funcitr = mf.find(function);
    if (funcitr != mf.end()) {
        return (this->*funcitr->second)(arg);
    }

    LOGE("Unknown action '%s'", function.c_str());
    return -1;
}
int GUIAction::doAction(Action action)
{
	DataManager::GetValue(TW_SIMULATE_ACTIONS, simulate);

	std::string function = gui_parse_text(action.mFunction);
	std::string arg = gui_parse_text(action.mArg);

	// find function and execute it
	mapFunc::const_iterator funcitr = mf.find(function);
	if (funcitr != mf.end())
		return (this->*funcitr->second)(arg);

	LOGERR("Unknown action '%s'\n", function.c_str());
	return -1;
}
int GUIFileSelector::NotifyVarChange(std::string varName, std::string value)
{
	if (varName.empty())
	{
		// Always clear the data variable so we know to use it
		DataManager::SetValue(mVariable, "");
	}
	if (!mHeaderIsStatic) {
		std::string newValue = gui_parse_text(mHeaderText);
		if (mLastValue != newValue) {
			mLastValue = newValue;
			mStart = 0;
			scrollingY = 0;
			scrollingSpeed = 0;
			mUpdate = 1;
		}
	}
	if (varName == mPathVar || varName == mSortVariable)
	{
		DataManager::GetValue(mPathVar, value);  // sometimes the value will be the sort order instead of the path, so we read the path everytime
		DataManager::GetValue(mSortVariable, mSortOrder);
		mStart = 0;
		scrollingY = 0;
		scrollingSpeed = 0;
		GetFileList(value);
		mUpdate = 1;
		return 0;
	}
	return 0;
}
Example #6
0
GUIAction::ThreadType GUIAction::getThreadType(const Action& action)
{
    std::string func = gui_parse_text(action.mFunction);
    bool needsThread = setActionsRunningInCallerThread.find(func) == setActionsRunningInCallerThread.end();
    if (needsThread) {
        return THREAD_ACTION;
    }
    return THREAD_NONE;
}
GUIAction::ThreadType GUIAction::getThreadType(const GUIAction::Action& action)
{
	string func = gui_parse_text(action.mFunction);
	bool needsThread = setActionsRunningInCallerThread.find(func) == setActionsRunningInCallerThread.end();
	if (needsThread) {
		if (func == "cancelbackup")
			return THREAD_CANCEL;
		else
			return THREAD_ACTION;
	}
	return THREAD_NONE;
}
int GUIPartitionList::NotifyVarChange(const std::string& varName, const std::string& value)
{
	GUIObject::NotifyVarChange(varName, value);

	if(!isConditionTrue())
		return 0;

	if (!mHeaderIsStatic) {
		std::string newValue = gui_parse_text(mHeaderText);
		if (mLastValue != newValue) {
			mLastValue = newValue;
			mStart = 0;
			scrollingY = 0;
			scrollingSpeed = 0;
			mUpdate = 1;
		}
	}
	if (varName == mVariable && !mUpdate)
	{
		if (ListType == "storage") {
			int i, listSize = mList.size(), selected_index = 0;

			currentValue = value;

			for (i=0; i<listSize; i++) {
				if (mList.at(i).Mount_Point == currentValue) {
					mList.at(i).selected = 1;
					selected_index = i;
				} else
					mList.at(i).selected = 0;
			}

			int lines = mRenderH / (mLineHeight + mLineSpacing);
			int line;

			if (selected_index > mStart + lines - 1) {
				mStart = selected_index;
			} else if (selected_index < mStart) {
				mStart = selected_index;
			}
		} else if (ListType == "backup") {
			MatchList();
		} else if (ListType == "restore") {
			updateList = true;
		}

		mUpdate = 1;
		return 0;
	}
	return 0;
}
int GUIListBox::NotifyVarChange(const std::string& varName, const std::string& value)
{
	GUIObject::NotifyVarChange(varName, value);

	if(!isConditionTrue())
		return 0;

	if (!mHeaderIsStatic) {
		std::string newValue = gui_parse_text(mHeaderText);
		if (mLastValue != newValue) {
			mLastValue = newValue;
			mStart = 0;
			scrollingY = 0;
			scrollingSpeed = 0;
			mUpdate = 1;
		}
	}
	if (varName == mVariable)
	{
		int i, listSize = mList.size(), selected_index = 0;

		currentValue = value;

		for (i=0; i<listSize; i++) {
			if (mList.at(i).variableValue == currentValue) {
				mList.at(i).selected = 1;
				selected_index = i;
			} else
				mList.at(i).selected = 0;
		}

		int lines = mRenderH / (mLineHeight + mLineSpacing);
		int line;

		if (selected_index > mStart + lines - 1)
			mStart = selected_index;
		if (mStart > listSize - lines) {
			mStart = listSize - lines;
		} else if (selected_index < mStart) {
			mStart = selected_index;
		}

		mUpdate = 1;
		return 0;
	}
	return 0;
}
int GUIListBox::NotifyVarChange(std::string varName, std::string value)
{
	if (!mHeaderIsStatic) {
		std::string newValue = gui_parse_text(mHeaderText);
		if (mLastValue != newValue) {
			mLastValue = newValue;
			mStart = 0;
			scrollingY = 0;
			scrollingSpeed = 0;
			mUpdate = 1;
		}
    }

    if(!varName.empty() && mItemsVar == varName)
	{
		std::string n;
		char *cstr = new char[value.size()+1];
		strcpy(cstr, value.c_str());

		mList.clear();

		char *p = strtok(cstr, "\n");
		while(p)
		{
			n = std::string(p);

			ListData data;
			data.displayName = n;
			data.variableValue = n;
			if(n == currentValue)
				data.selected = 1;
			else
				data.selected = 0;

			mList.push_back(data);

			p = strtok(NULL, "\n");
		}
		delete[] cstr;
		mUpdate = 1;
	}
	else if (varName == mVariable)
    {
		if(mList.empty())
			return 0;

		int i, listSize = mList.size(), selected_index = 0;

		currentValue = value;

		for (i=0; i<listSize; i++) {
			if (mList.at(i).variableValue == currentValue) {
				mList.at(i).selected = 1;
				selected_index = i;
			} else
				mList.at(i).selected = 0;
		}

		int lines = mRenderH / (mLineHeight + mLineSpacing);
		int line;

		if (selected_index > mStart + lines - 1)
			mStart = selected_index;
		if (mStart > listSize - lines) {
			mStart = listSize - lines;
		} else if (selected_index < mStart) {
			mStart = selected_index;
		}

		if(mStart < 0)
			mStart = 0;

		mUpdate = 1;
		return 0;
	}
	return 0;
}
GUIInput::GUIInput(xml_node<>* node)
	: GUIObject(node)
{
	xml_attribute<>* attr;
	xml_node<>* child;

	mInputText = NULL;
	mAction = NULL;
	mBackground = NULL;
	mCursor = NULL;
	mFont = NULL;
	mRendered = false;
	HasMask = false;
	DrawCursor = false;
	isLocalChange = true;
	HasAllowed = false;
	HasDisabled = false;
	skipChars = scrollingX = mFontHeight = mFontY = lastX = 0;
	mBackgroundX = mBackgroundY = mBackgroundW = mBackgroundH = MinLen = MaxLen = 0;
	mCursorLocation = -1; // -1 is always the end of the string
	CursorWidth = 3;
	ConvertStrToColor("black", &mBackgroundColor);
	ConvertStrToColor("white", &mCursorColor);

	if (!node)
		return;

	// Load text directly from the node
	mInputText = new GUIText(node);
	// Load action directly from the node
	mAction = new GUIAction(node);

	if (mInputText->Render() < 0)
	{
		delete mInputText;
		mInputText = NULL;
	}

	// Load the background
	child = node->first_node("background");
	if (child)
	{
		attr = child->first_attribute("resource");
		if (attr)
			mBackground = PageManager::FindResource(attr->value());
		attr = child->first_attribute("color");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mBackgroundColor);
		}
	}
	if (mBackground && mBackground->GetResource())
	{
		mBackgroundW = gr_get_width(mBackground->GetResource());
		mBackgroundH = gr_get_height(mBackground->GetResource());
	}

	// Load the cursor color
	child = node->first_node("cursor");
	if (child)
	{
		attr = child->first_attribute("resource");
		if (attr)
			mCursor = PageManager::FindResource(attr->value());
		attr = child->first_attribute("color");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mCursorColor);
		}
		attr = child->first_attribute("hasfocus");
		if (attr)
		{
			std::string color = attr->value();
			SetInputFocus(atoi(color.c_str()));
		}
		attr = child->first_attribute("width");
		if (attr)
		{
			std::string cwidth = gui_parse_text(attr->value());
			CursorWidth = atoi(cwidth.c_str());
		}
	}
	DrawCursor = HasInputFocus;

	// 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());
			mFontHeight = gr_getMaxFontHeight(mFont ? mFont->GetResource() : NULL);
		}
	}

	child = node->first_node("text");
	if (child)  mText = child->value();
	mLastValue = gui_parse_text(mText);

	child = node->first_node("data");
	if (child)
	{
		attr = child->first_attribute("name");
		if (attr)
			mVariable = attr->value();
		attr = child->first_attribute("default");
		if (attr)
			DataManager::SetValue(mVariable, attr->value());
		attr = child->first_attribute("mask");
		if (attr) {
			mMask = attr->value();
			HasMask = true;
		}
		attr = child->first_attribute("maskvariable");
		if (attr)
			mMaskVariable = attr->value();
		else
			mMaskVariable = mVariable;
	}

	// Load input restrictions
	child = node->first_node("restrict");
	if (child)
	{
		attr = child->first_attribute("minlen");
		if (attr) {
			std::string attrib = attr->value();
			MinLen = atoi(attrib.c_str());
		}
		attr = child->first_attribute("maxlen");
		if (attr) {
			std::string attrib = attr->value();
			MaxLen = atoi(attrib.c_str());
		}
		attr = child->first_attribute("allow");
		if (attr) {
			HasAllowed = true;
			AllowedList = attr->value();
		}
		attr = child->first_attribute("disable");
		if (attr) {
			HasDisabled = true;
			DisabledList = attr->value();
		}
	}

	// Load the placement
	LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH);
	SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);

	if (mInputText && mFontHeight && mFontHeight < (unsigned)mRenderH) {
		mFontY = ((mRenderH - mFontHeight) / 2) + mRenderY;
		mInputText->SetRenderPos(mRenderX, mFontY);
	} else
		mFontY = mRenderY;

	if (mInputText)
		mInputText->SetMaxWidth(mRenderW);

	isLocalChange = false;
	HandleTextLocation(-3);
}
GUIPartitionList::GUIPartitionList(xml_node<>* node) : GUIObject(node)
{
	xml_attribute<>* attr;
	xml_node<>* child;
	int header_separator_color_specified = 0, header_separator_height_specified = 0, header_text_color_specified = 0, header_background_color_specified = 0;

	mStart = mLineSpacing = startY = mFontHeight = mSeparatorH = scrollingY = scrollingSpeed = 0;
	mIconWidth = mIconHeight = mSelectedIconHeight = mSelectedIconWidth = mUnselectedIconHeight = mUnselectedIconWidth = mHeaderIconHeight = mHeaderIconWidth = 0;
	mHeaderSeparatorH = mLineHeight = mHeaderIsStatic = mHeaderH = actualLineHeight = 0;
	mIconSelected = mIconUnselected = mBackground = mFont = mHeaderIcon = NULL;
	mBackgroundX = mBackgroundY = mBackgroundW = mBackgroundH = 0;
	mFastScrollW = mFastScrollLineW = mFastScrollRectW = mFastScrollRectH = 0;
	mFastScrollRectX = mFastScrollRectY = -1;
	mUpdate = 0;
	touchDebounce = 6;
	ConvertStrToColor("black", &mBackgroundColor);
	ConvertStrToColor("black", &mHeaderBackgroundColor);
	ConvertStrToColor("black", &mSeparatorColor);
	ConvertStrToColor("black", &mHeaderSeparatorColor);
	ConvertStrToColor("white", &mFontColor);
	ConvertStrToColor("white", &mHeaderFontColor);
	ConvertStrToColor("white", &mFastScrollLineColor);
	ConvertStrToColor("white", &mFastScrollRectColor);
	hasHighlightColor = false;
	hasFontHighlightColor = false;
	isHighlighted = false;
	updateList = false;
	startSelection = -1;

	// Load header text
	child = node->first_node("header");
	if (child)
	{
		attr = child->first_attribute("icon");
		if (attr)
			mHeaderIcon = PageManager::FindResource(attr->value());

		attr = child->first_attribute("background");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mHeaderBackgroundColor);
			header_background_color_specified = -1;
		}
		attr = child->first_attribute("textcolor");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mHeaderFontColor);
			header_text_color_specified = -1;
		}
		attr = child->first_attribute("separatorcolor");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mHeaderSeparatorColor);
			header_separator_color_specified = -1;
		}
		attr = child->first_attribute("separatorheight");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mHeaderSeparatorH = atoi(parsevalue.c_str());
			header_separator_height_specified = -1;
		}
	}
	child = node->first_node("text");
	if (child)  mHeaderText = child->value();

	memset(&mHighlightColor, 0, sizeof(COLOR));
	child = node->first_node("highlight");
	if (child) {
		attr = child->first_attribute("color");
		if (attr) {
			hasHighlightColor = true;
			std::string color = attr->value();
			ConvertStrToColor(color, &mHighlightColor);
		}
	}

	// Simple way to check for static state
	mLastValue = gui_parse_text(mHeaderText);
	if (mLastValue != mHeaderText)
		mHeaderIsStatic = 0;
	else
		mHeaderIsStatic = -1;

	child = node->first_node("icon");
	if (child)
	{
		attr = child->first_attribute("selected");
		if (attr)
			mIconSelected = PageManager::FindResource(attr->value());
		attr = child->first_attribute("unselected");
		if (attr)
			mIconUnselected = PageManager::FindResource(attr->value());
	}
	child = node->first_node("background");
	if (child)
	{
		attr = child->first_attribute("resource");
		if (attr)
			mBackground = PageManager::FindResource(attr->value());
		attr = child->first_attribute("color");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mBackgroundColor);
			if (!header_background_color_specified)
				ConvertStrToColor(color, &mHeaderBackgroundColor);
		}
	}

	// Load the placement
	LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH);
	SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);

	// 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, &mFontColor);
			if (!header_text_color_specified)
				ConvertStrToColor(color, &mHeaderFontColor);
		}

		attr = child->first_attribute("spacing");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mLineSpacing = atoi(parsevalue.c_str());
		}

		attr = child->first_attribute("highlightcolor");
		memset(&mFontHighlightColor, 0, sizeof(COLOR));
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mFontHighlightColor);
			hasFontHighlightColor = true;
		}
	}

	// Load the separator if it exists
	child = node->first_node("separator");
	if (child)
	{
		attr = child->first_attribute("color");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mSeparatorColor);
			if (!header_separator_color_specified)
				ConvertStrToColor(color, &mHeaderSeparatorColor);
		}

		attr = child->first_attribute("height");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mSeparatorH = atoi(parsevalue.c_str());
			if (!header_separator_height_specified)
				mHeaderSeparatorH = mSeparatorH;
		}
	}

	// Handle the result variable
	child = node->first_node("data");
	if (child)
	{
		attr = child->first_attribute("name");
		if (attr)
			mVariable = attr->value();
		attr = child->first_attribute("selectedlist");
		if (attr)
			selectedList = attr->value();
	}

	// Fast scroll colors
	child = node->first_node("fastscroll");
	if (child)
	{
		attr = child->first_attribute("linecolor");
		if(attr)
			ConvertStrToColor(attr->value(), &mFastScrollLineColor);

		attr = child->first_attribute("rectcolor");
		if(attr)
			ConvertStrToColor(attr->value(), &mFastScrollRectColor);

		attr = child->first_attribute("w");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mFastScrollW = atoi(parsevalue.c_str());
		}

		attr = child->first_attribute("linew");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mFastScrollLineW = atoi(parsevalue.c_str());
		}

		attr = child->first_attribute("rectw");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mFastScrollRectW = atoi(parsevalue.c_str());
		}

		attr = child->first_attribute("recth");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mFastScrollRectH = atoi(parsevalue.c_str());
		}
	}

	// Retrieve the line height
	gr_getFontDetails(mFont ? mFont->GetResource() : NULL, &mFontHeight, NULL);
	mLineHeight = mFontHeight;
	mHeaderH = mFontHeight;

	if (mIconSelected && mIconSelected->GetResource())
	{
		mSelectedIconWidth = gr_get_width(mIconSelected->GetResource());
		mSelectedIconHeight = gr_get_height(mIconSelected->GetResource());
		if (mSelectedIconHeight > (int)mLineHeight)
			mLineHeight = mSelectedIconHeight;
		mIconWidth = mSelectedIconWidth;
	}

	if (mIconUnselected && mIconUnselected->GetResource())
	{
		mUnselectedIconWidth = gr_get_width(mIconUnselected->GetResource());
		mUnselectedIconHeight = gr_get_height(mIconUnselected->GetResource());
		if (mUnselectedIconHeight > (int)mLineHeight)
			mLineHeight = mUnselectedIconHeight;
		if (mUnselectedIconWidth > mIconWidth)
			mIconWidth = mUnselectedIconWidth;
	}

	if (mHeaderIcon && mHeaderIcon->GetResource())
	{
		mHeaderIconWidth = gr_get_width(mHeaderIcon->GetResource());
		mHeaderIconHeight = gr_get_height(mHeaderIcon->GetResource());
		if (mHeaderIconHeight > mHeaderH)
			mHeaderH = mHeaderIconHeight;
		if (mHeaderIconWidth > mIconWidth)
			mIconWidth = mHeaderIconWidth;
	}

	mHeaderH += mLineSpacing + mHeaderSeparatorH;
	actualLineHeight = mLineHeight + mLineSpacing + mSeparatorH;
	if (mHeaderH < actualLineHeight)
		mHeaderH = actualLineHeight;

	if (actualLineHeight / 3 > 6)
		touchDebounce = actualLineHeight / 3;

	if (mBackground && mBackground->GetResource())
	{
		mBackgroundW = gr_get_width(mBackground->GetResource());
		mBackgroundH = gr_get_height(mBackground->GetResource());
	}

	child = node->first_node("listtype");
	if (child) {
		attr = child->first_attribute("name");
		if (attr) {
			ListType = attr->value();
			PartitionManager.Get_Partition_List(ListType, &mList);
		} else {
			mList.clear();
			LOGERR("No partition listtype name specified for partitionlist GUI element\n");
			return;
		}
	} else {
		mList.clear();
		LOGERR("No partition listtype specified for partitionlist GUI element\n");
		return;
	}
}
GUIFileSelector::GUIFileSelector(xml_node<>* node)
{
	xml_attribute<>* attr;
	xml_node<>* child;
	int header_separator_color_specified = 0, header_separator_height_specified = 0, header_text_color_specified = 0, header_background_color_specified = 0;

	mStart = mLineSpacing = startY = mFontHeight = mSeparatorH = scrollingY = scrollingSpeed = 0;
	mIconWidth = mIconHeight = mFolderIconHeight = mFileIconHeight = mFolderIconWidth = mFileIconWidth = mHeaderIconHeight = mHeaderIconWidth = 0;
	mHeaderSeparatorH = mLineHeight = mHeaderIsStatic = mHeaderH = actualLineHeight = 0;
	mFolderIcon = mFileIcon = mBackground = mFont = mHeaderIcon = NULL;
	mBackgroundX = mBackgroundY = mBackgroundW = mBackgroundH = 0;
	mShowFolders = mShowFiles = mShowNavFolders = 1;
	mUpdate = 0;
	touchDebounce = 6;
	mPathVar = "cwd";
	ConvertStrToColor("black", &mBackgroundColor);
	ConvertStrToColor("black", &mHeaderBackgroundColor);
	ConvertStrToColor("black", &mSeparatorColor);
	ConvertStrToColor("black", &mHeaderSeparatorColor);
	ConvertStrToColor("white", &mFontColor);
	ConvertStrToColor("white", &mHeaderFontColor);

	// Load header text
	child = node->first_node("header");
	if (child)
	{
		attr = child->first_attribute("icon");
		if (attr)
			mHeaderIcon = PageManager::FindResource(attr->value());

		attr = child->first_attribute("background");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mHeaderBackgroundColor);
			header_background_color_specified = -1;
		}
		attr = child->first_attribute("textcolor");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mHeaderFontColor);
			header_text_color_specified = -1;
		}
		attr = child->first_attribute("separatorcolor");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mHeaderSeparatorColor);
			header_separator_color_specified = -1;
		}
		attr = child->first_attribute("separatorheight");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mHeaderSeparatorH = atoi(parsevalue.c_str());
			header_separator_height_specified = -1;
		}
	}
	child = node->first_node("text");
	if (child)  mHeaderText = child->value();

	// Simple way to check for static state
	mLastValue = gui_parse_text(mHeaderText);
	if (mLastValue != mHeaderText)
		mHeaderIsStatic = 0;
	else
		mHeaderIsStatic = -1;

	child = node->first_node("icon");
	if (child)
	{
		attr = child->first_attribute("folder");
		if (attr)
			mFolderIcon = PageManager::FindResource(attr->value());
		attr = child->first_attribute("file");
		if (attr)
			mFileIcon = PageManager::FindResource(attr->value());
	}
	child = node->first_node("background");
	if (child)
	{
		attr = child->first_attribute("resource");
		if (attr)
			mBackground = PageManager::FindResource(attr->value());
		attr = child->first_attribute("color");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mBackgroundColor);
			if (!header_background_color_specified)
				ConvertStrToColor(color, &mHeaderBackgroundColor);
		}
	}

	// Load the placement
	LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH);
	SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);

	// 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, &mFontColor);
			if (!header_text_color_specified)
				ConvertStrToColor(color, &mHeaderFontColor);
		}

		attr = child->first_attribute("spacing");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mLineSpacing = atoi(parsevalue.c_str());
		}
	}

	// Load the separator if it exists
	child = node->first_node("separator");
	if (child)
	{
		attr = child->first_attribute("color");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mSeparatorColor);
			if (!header_separator_color_specified)
				ConvertStrToColor(color, &mHeaderSeparatorColor);
		}

		attr = child->first_attribute("height");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mSeparatorH = atoi(parsevalue.c_str());
			if (!header_separator_height_specified)
				mHeaderSeparatorH = mSeparatorH;
		}
	}

	child = node->first_node("filter");
	if (child)
	{
		attr = child->first_attribute("extn");
		if (attr)
			mExtn = attr->value();
		attr = child->first_attribute("folders");
		if (attr)
			mShowFolders = atoi(attr->value());
		attr = child->first_attribute("files");
		if (attr)
			mShowFiles = atoi(attr->value());
		attr = child->first_attribute("nav");
		if (attr)
			mShowNavFolders = atoi(attr->value());
	}

	// Handle the path variable
	child = node->first_node("path");
	if (child)
	{
		attr = child->first_attribute("name");
		if (attr)
			mPathVar = attr->value();
		attr = child->first_attribute("default");
		if (attr)
			DataManager::SetValue(mPathVar, attr->value());
	}

	// Handle the result variable
	child = node->first_node("data");
	if (child)
	{
		attr = child->first_attribute("name");
		if (attr)
			mVariable = attr->value();
		attr = child->first_attribute("default");
		if (attr)
			DataManager::SetValue(mVariable, attr->value());
	}

	// Handle the sort variable
	child = node->first_node("sort");
	if (child)
	{
		attr = child->first_attribute("name");
		if (attr)
			mSortVariable = attr->value();
		attr = child->first_attribute("default");
		if (attr)
			DataManager::SetValue(mSortVariable, attr->value());

		DataManager::GetValue(mSortVariable, mSortOrder);
	}

	// Handle the selection variable
	child = node->first_node("selection");
	if (child)
	{
		attr = child->first_attribute("name");
		if (attr)
			mSelection = attr->value();
		else
			mSelection = "0";
	} else
		mSelection = "0";

	// Retrieve the line height
	gr_getFontDetails(mFont ? mFont->GetResource() : NULL, &mFontHeight, NULL);
	mLineHeight = mFontHeight;
	mHeaderH = mFontHeight;

	if (mFolderIcon && mFolderIcon->GetResource())
	{
		mFolderIconWidth = gr_get_width(mFolderIcon->GetResource());
		mFolderIconHeight = gr_get_height(mFolderIcon->GetResource());
		if (mFolderIconHeight > (int)mLineHeight)
			mLineHeight = mFolderIconHeight;
		mIconWidth = mFolderIconWidth;
	}

	if (mFileIcon && mFileIcon->GetResource())
	{
		mFileIconWidth = gr_get_width(mFileIcon->GetResource());
		mFileIconHeight = gr_get_height(mFileIcon->GetResource());
		if (mFileIconHeight > (int)mLineHeight)
			mLineHeight = mFileIconHeight;
		if (mFileIconWidth > mIconWidth)
			mIconWidth = mFileIconWidth;
	}

	if (mHeaderIcon && mHeaderIcon->GetResource())
	{
		mHeaderIconWidth = gr_get_width(mHeaderIcon->GetResource());
		mHeaderIconHeight = gr_get_height(mHeaderIcon->GetResource());
		if (mHeaderIconHeight > mHeaderH)
			mHeaderH = mHeaderIconHeight;
		if (mHeaderIconWidth > mIconWidth)
			mIconWidth = mHeaderIconWidth;
	}

	mHeaderH += mLineSpacing + mHeaderSeparatorH;
	actualLineHeight = mLineHeight + mLineSpacing + mSeparatorH;
	if (mHeaderH < actualLineHeight)
		mHeaderH = actualLineHeight;

	if (actualLineHeight / 3 > 6)
		touchDebounce = actualLineHeight / 3;

	if (mBackground && mBackground->GetResource())
	{
		mBackgroundW = gr_get_width(mBackground->GetResource());
		mBackgroundH = gr_get_height(mBackground->GetResource());
	}

	// Fetch the file/folder list
	std::string value;
	DataManager::GetValue(mPathVar, value);
	if (GetFileList(value) != 0 && (mShowNavFolders != 0 || mShowFiles != 0)) {
		GetFileList(DataManager::GetCurrentStoragePath());
		DataManager::SetValue(mPathVar, DataManager::GetCurrentStoragePath());
	}
}
int GUIPartitionList::Update(void)
{
	if(!isConditionTrue())
		return 0;

	if (!mHeaderIsStatic) {
		std::string newValue = gui_parse_text(mHeaderText);
		if (mLastValue != newValue) {
			mLastValue = newValue;
			mUpdate = 1;
		}
	}

	// Check for changes in mount points if the list type is mount and update the list and render if needed
	if (ListType == "mount") {
		int listSize = mList.size();
		for (int i = 0; i < listSize; i++) {
			if (PartitionManager.Is_Mounted_By_Path(mList.at(i).Mount_Point) && !mList.at(i).selected) {
				mList.at(i).selected = 1;
				mUpdate = 1;
			} else if (!PartitionManager.Is_Mounted_By_Path(mList.at(i).Mount_Point) && mList.at(i).selected) {
				mList.at(i).selected = 0;
				mUpdate = 1;
			}
		}
	}

	if (mUpdate)
	{
		mUpdate = 0;
		if (Render() == 0)
			return 2;
	}

	// Handle kinetic scrolling
	if (scrollingSpeed == 0) {
		// Do nothing
	} else if (scrollingSpeed > 0) {
		if (scrollingSpeed < ((int) (actualLineHeight * 2.5))) {
			scrollingY += scrollingSpeed;
			scrollingSpeed -= SCROLLING_SPEED_DECREMENT;
		} else {
			scrollingY += ((int) (actualLineHeight * 2.5));
			scrollingSpeed -= SCROLLING_SPEED_DECREMENT;
		}
		while (mStart && scrollingY > 0) {
			mStart--;
			scrollingY -= actualLineHeight;
		}
		if (mStart == 0 && scrollingY > 0) {
			scrollingY = 0;
			scrollingSpeed = 0;
		} else if (scrollingSpeed < SCROLLING_FLOOR)
			scrollingSpeed = 0;
		mUpdate = 1;
	} else if (scrollingSpeed < 0) {
		int totalSize = mList.size();
		int lines = (mRenderH - mHeaderH) / (actualLineHeight);

		if (totalSize > lines) {
			int bottom_offset = ((int)(mRenderH) - mHeaderH) - (lines * actualLineHeight);

			bottom_offset -= actualLineHeight;

			if (abs(scrollingSpeed) < ((int) (actualLineHeight * 2.5))) {
				scrollingY += scrollingSpeed;
				scrollingSpeed += SCROLLING_SPEED_DECREMENT;
			} else {
				scrollingY -= ((int) (actualLineHeight * 2.5));
				scrollingSpeed += SCROLLING_SPEED_DECREMENT;
			}
			while (mStart + lines + (bottom_offset ? 1 : 0) < totalSize && abs(scrollingY) > actualLineHeight) {
				mStart++;
				scrollingY += actualLineHeight;
			}
			if (bottom_offset != 0 && mStart + lines + 1 >= totalSize && scrollingY <= bottom_offset) {
				mStart = totalSize - lines - 1;
				scrollingY = bottom_offset;
			} else if (mStart + lines >= totalSize && scrollingY < 0) {
				mStart = totalSize - lines;
				scrollingY = 0;
			} else if (scrollingSpeed * -1 < SCROLLING_FLOOR)
				scrollingSpeed = 0;
			mUpdate = 1;
		}
	}

	return 0;
}
int GUIAction::page(std::string arg)
{
	std::string page_name = gui_parse_text(arg);
	return gui_changePage(page_name);
}
int GUIFileSelector::Update(void)
{
	if (!mHeaderIsStatic) {
		std::string newValue = gui_parse_text(mHeaderText);
		if (mLastValue != newValue) {
			mLastValue = newValue;
			mUpdate = 1;
		}
	}

	if (mUpdate)
	{
		mUpdate = 0;
		if (Render() == 0)
			return 2;
	}

	// Handle kinetic scrolling
	if (scrollingSpeed == 0) {
		// Do nothing
	} else if (scrollingSpeed > 0) {
		if (scrollingSpeed < ((int) (actualLineHeight * 2.5))) {
			scrollingY += scrollingSpeed;
			scrollingSpeed -= SCROLLING_SPEED_DECREMENT;
		} else {
			scrollingY += ((int) (actualLineHeight * 2.5));
			scrollingSpeed -= SCROLLING_SPEED_DECREMENT;
		}
		while (mStart && scrollingY > 0) {
			mStart--;
			scrollingY -= actualLineHeight;
		}
		if (mStart == 0 && scrollingY > 0) {
			scrollingY = 0;
			scrollingSpeed = 0;
		} else if (scrollingSpeed < SCROLLING_FLOOR)
			scrollingSpeed = 0;
		mUpdate = 1;
	} else if (scrollingSpeed < 0) {
		int totalSize = (mShowFolders ? mFolderList.size() : 0) + (mShowFiles ? mFileList.size() : 0);
		int lines = (mRenderH - mHeaderH) / (actualLineHeight);

		if (totalSize > lines) {
			int bottom_offset = ((int)(mRenderH) - mHeaderH) - (lines * actualLineHeight);

			bottom_offset -= actualLineHeight;

			if (abs(scrollingSpeed) < ((int) (actualLineHeight * 2.5))) {
				scrollingY += scrollingSpeed;
				scrollingSpeed += SCROLLING_SPEED_DECREMENT;
			} else {
				scrollingY -= ((int) (actualLineHeight * 2.5));
				scrollingSpeed += SCROLLING_SPEED_DECREMENT;
			}
			while (mStart + lines + (bottom_offset ? 1 : 0) < totalSize && abs(scrollingY) > actualLineHeight) {
				mStart++;
				scrollingY += actualLineHeight;
			}
			if (bottom_offset != 0 && mStart + lines + 1 >= totalSize && scrollingY <= bottom_offset) {
				mStart = totalSize - lines - 1;
				scrollingY = bottom_offset;
			} else if (mStart + lines >= totalSize && scrollingY < 0) {
				mStart = totalSize - lines;
				scrollingY = 0;
			} else if (scrollingSpeed * -1 < SCROLLING_FLOOR)
				scrollingSpeed = 0;
			mUpdate = 1;
		}
	}

	return 0;
}
bool GUIObject::isConditionTrue(Condition* condition)
{
	// This is used to hold the proper value of "true" based on the '!' NOT flag
	bool bTrue = true;

	if (condition->mVar1.empty())
		return bTrue;

	if (!condition->mCompareOp.empty() && condition->mCompareOp[0] == '!')
		bTrue = false;

	if (condition->mVar2.empty() && condition->mCompareOp != "modified")
	{
		if (!DataManager::GetStrValue(condition->mVar1).empty())
			return bTrue;

		return !bTrue;
	}

	string var1, var2;
	if (DataManager::GetValue(condition->mVar1, var1))
		var1 = condition->mVar1;
	if (DataManager::GetValue(condition->mVar2, var2))
		var2 = condition->mVar2;

	if (var2.substr(0, 2) == "{@")
		// translate resource string in value
		var2 = gui_parse_text(var2);

	// This is a special case, we stat the file and that determines our result
	if (var1 == "fileexists")
	{
		struct stat st;
		if (stat(var2.c_str(), &st) == 0)
			var2 = var1;
		else
			var2 = "FAILED";
	}
	if (var1 == "mounted")
	{
		if (isMounted(condition->mVar2))
			var2 = var1;
		else
			var2 = "FAILED";
	}

	if (condition->mCompareOp.find('=') != string::npos && var1 == var2)
		return bTrue;

	if (condition->mCompareOp.find('>') != string::npos && (atof(var1.c_str()) > atof(var2.c_str())))
		return bTrue;

	if (condition->mCompareOp.find('<') != string::npos && (atof(var1.c_str()) < atof(var2.c_str())))
		return bTrue;

	if (condition->mCompareOp == "modified")
	{
		// This is a hack to allow areas to reset the default value
		if (var1.empty())
		{
			condition->mLastVal = var1;
			return !bTrue;
		}

		if (var1 != condition->mLastVal)
			return bTrue;
	}

	return !bTrue;
}
GUIListBox::GUIListBox(xml_node<>* node) : Conditional(node)
{
	xml_attribute<>* attr;
	xml_node<>* child;
	int header_separator_color_specified = 0, header_separator_height_specified = 0, header_text_color_specified = 0, header_background_color_specified = 0;

	mStart = mLineSpacing = startY = mFontHeight = mSeparatorH = scrollingY = scrollingSpeed = 0;
	mIconWidth = mIconHeight = mSelectedIconHeight = mSelectedIconWidth = mUnselectedIconHeight = mUnselectedIconWidth = mHeaderIconHeight = mHeaderIconWidth = 0;
	mHeaderSeparatorH = mLineHeight = mHeaderIsStatic = mHeaderH = actualLineHeight = 0;
	mIconSelected = mIconUnselected = mBackground = mFont = mHeaderIcon = NULL;
	mBackgroundX = mBackgroundY = mBackgroundW = mBackgroundH = 0;
	mFastScrollW = mFastScrollLineW = mFastScrollRectW = mFastScrollRectH = 0;
	mFastScrollRectX = mFastScrollRectY = -1;
	mUpdate = 0;
	touchDebounce = 6;
	ConvertStrToColor("black", &mBackgroundColor);
	ConvertStrToColor("black", &mHeaderBackgroundColor);
	ConvertStrToColor("black", &mSeparatorColor);
	ConvertStrToColor("black", &mHeaderSeparatorColor);
	ConvertStrToColor("white", &mFontColor);
	ConvertStrToColor("white", &mHeaderFontColor);
	ConvertStrToColor("white", &mFastScrollLineColor);
	ConvertStrToColor("white", &mFastScrollRectColor);
	hasHighlightColor = false;
	hasFontHighlightColor = false;
	isHighlighted = false;
	startSelection = -1;

	// Load header text
	child = node->first_node("header");
	if (child)
	{
		attr = child->first_attribute("icon");
		if (attr)
			mHeaderIcon = PageManager::FindResource(attr->value());

		attr = child->first_attribute("background");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mHeaderBackgroundColor);
			header_background_color_specified = -1;
		}
		attr = child->first_attribute("textcolor");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mHeaderFontColor);
			header_text_color_specified = -1;
		}
		attr = child->first_attribute("separatorcolor");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mHeaderSeparatorColor);
			header_separator_color_specified = -1;
		}
		attr = child->first_attribute("separatorheight");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mHeaderSeparatorH = atoi(parsevalue.c_str());
			header_separator_height_specified = -1;
		}
	}
	child = node->first_node("text");
	if (child)  mHeaderText = child->value();

	memset(&mHighlightColor, 0, sizeof(COLOR));
	child = node->first_node("highlight");
	if (child) {
		attr = child->first_attribute("color");
		if (attr) {
			hasHighlightColor = true;
			std::string color = attr->value();
			ConvertStrToColor(color, &mHighlightColor);
		}
	}

	// Simple way to check for static state
	mLastValue = gui_parse_text(mHeaderText);
	if (mLastValue != mHeaderText)
		mHeaderIsStatic = 0;
	else
		mHeaderIsStatic = -1;

	child = node->first_node("icon");
	if (child)
	{
		attr = child->first_attribute("selected");
		if (attr)
			mIconSelected = PageManager::FindResource(attr->value());
		attr = child->first_attribute("unselected");
		if (attr)
			mIconUnselected = PageManager::FindResource(attr->value());
	}
	child = node->first_node("background");
	if (child)
	{
		attr = child->first_attribute("resource");
		if (attr)
			mBackground = PageManager::FindResource(attr->value());
		attr = child->first_attribute("color");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mBackgroundColor);
			if (!header_background_color_specified)
				ConvertStrToColor(color, &mHeaderBackgroundColor);
		}
	}

	// Load the placement
	LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH);
	SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);

	// 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, &mFontColor);
			if (!header_text_color_specified)
				ConvertStrToColor(color, &mHeaderFontColor);
		}

		attr = child->first_attribute("spacing");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mLineSpacing = atoi(parsevalue.c_str());
		}

		attr = child->first_attribute("highlightcolor");
		memset(&mFontHighlightColor, 0, sizeof(COLOR));
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mFontHighlightColor);
			hasFontHighlightColor = true;
		}
	}

	// Load the separator if it exists
	child = node->first_node("separator");
	if (child)
	{
		attr = child->first_attribute("color");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mSeparatorColor);
			if (!header_separator_color_specified)
				ConvertStrToColor(color, &mHeaderSeparatorColor);
		}

		attr = child->first_attribute("height");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mSeparatorH = atoi(parsevalue.c_str());
			if (!header_separator_height_specified)
				mHeaderSeparatorH = mSeparatorH;
		}
	}

	// Handle the result variable
	child = node->first_node("data");
	if (child)
	{
		attr = child->first_attribute("name");
		if (attr)
			mVariable = attr->value();
		attr = child->first_attribute("default");
		if (attr)
			DataManager::SetValue(mVariable, attr->value());
	}

	// Fast scroll colors
	child = node->first_node("fastscroll");
	if (child)
	{
		attr = child->first_attribute("linecolor");
		if(attr)
			ConvertStrToColor(attr->value(), &mFastScrollLineColor);

		attr = child->first_attribute("rectcolor");
		if(attr)
			ConvertStrToColor(attr->value(), &mFastScrollRectColor);

		attr = child->first_attribute("w");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mFastScrollW = atoi(parsevalue.c_str());
		}

		attr = child->first_attribute("linew");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mFastScrollLineW = atoi(parsevalue.c_str());
		}

		attr = child->first_attribute("rectw");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mFastScrollRectW = atoi(parsevalue.c_str());
		}

		attr = child->first_attribute("recth");
		if (attr) {
			string parsevalue = gui_parse_text(attr->value());
			mFastScrollRectH = atoi(parsevalue.c_str());
		}
	}

	// Retrieve the line height
	gr_getFontDetails(mFont ? mFont->GetResource() : NULL, &mFontHeight, NULL);
	mLineHeight = mFontHeight;
	mHeaderH = mFontHeight;

	if (mIconSelected && mIconSelected->GetResource())
	{
		mSelectedIconWidth = gr_get_width(mIconSelected->GetResource());
		mSelectedIconHeight = gr_get_height(mIconSelected->GetResource());
		if (mSelectedIconHeight > (int)mLineHeight)
			mLineHeight = mSelectedIconHeight;
		mIconWidth = mSelectedIconWidth;
	}

	if (mIconUnselected && mIconUnselected->GetResource())
	{
		mUnselectedIconWidth = gr_get_width(mIconUnselected->GetResource());
		mUnselectedIconHeight = gr_get_height(mIconUnselected->GetResource());
		if (mUnselectedIconHeight > (int)mLineHeight)
			mLineHeight = mUnselectedIconHeight;
		if (mUnselectedIconWidth > mIconWidth)
			mIconWidth = mUnselectedIconWidth;
	}

	if (mHeaderIcon && mHeaderIcon->GetResource())
	{
		mHeaderIconWidth = gr_get_width(mHeaderIcon->GetResource());
		mHeaderIconHeight = gr_get_height(mHeaderIcon->GetResource());
		if (mHeaderIconHeight > mHeaderH)
			mHeaderH = mHeaderIconHeight;
		if (mHeaderIconWidth > mIconWidth)
			mIconWidth = mHeaderIconWidth;
	}

	mHeaderH += mLineSpacing + mHeaderSeparatorH;
	actualLineHeight = mLineHeight + mLineSpacing + mSeparatorH;
	if (mHeaderH < actualLineHeight)
		mHeaderH = actualLineHeight;

	if (actualLineHeight / 3 > 6)
		touchDebounce = actualLineHeight / 3;

	if (mBackground && mBackground->GetResource())
	{
		mBackgroundW = gr_get_width(mBackground->GetResource());
		mBackgroundH = gr_get_height(mBackground->GetResource());
	}

	// Get the currently selected value for the list
	DataManager::GetValue(mVariable, currentValue);

	// Get the data for the list
	child = node->first_node("listitem");
	while (child)
	{
		ListData data;

		attr = child->first_attribute("name");
		if (!attr) return;
		data.displayName = attr->value();

		data.variableValue = child->value();
		if (child->value() == currentValue) {
			data.selected = 1;
		} else {
			data.selected = 0;
		}

		mList.push_back(data);

		child = child->next_sibling("listitem");
	}

	// Load dynamic data
	child = node->first_node("items");
	if (child)
		mItemsVar = child->value();

	// Call this to get the selected item to be shown in the list on first render
	NotifyVarChange(mVariable, currentValue);
	if(!mItemsVar.empty())
		NotifyVarChange(mItemsVar, DataManager::GetStrValue(mItemsVar));
}
Example #19
0
GUIInput::GUIInput(xml_node<>* node)
	: GUIObject(node)
{
	xml_attribute<>* attr;
	xml_node<>* child;

	mInputText = NULL;
	mAction = NULL;
	mBackground = NULL;
	mCursor = NULL;
	mFont = NULL;
	mRendered = false;
	HasMask = false;
	DrawCursor = false;
	isLocalChange = true;
	HasAllowed = false;
	HasDisabled = false;
	skipChars = scrollingX = mFontHeight = mFontY = lastX = 0;
	mBackgroundX = mBackgroundY = mBackgroundW = mBackgroundH = MinLen = MaxLen = 0;
	mCursorLocation = -1; // -1 is always the end of the string
	CursorWidth = 3;
	ConvertStrToColor("black", &mBackgroundColor);
	ConvertStrToColor("white", &mCursorColor);

	if (!node)
		return;

	// Load text directly from the node
	mInputText = new GUIText(node);
	// Load action directly from the node
	mAction = new GUIAction(node);

	if (mInputText->Render() < 0)
	{
		delete mInputText;
		mInputText = NULL;
	}

	// Load the background
	child = FindNode(node, "background");
	if (child)
	{
		mBackground = LoadAttrImage(child, "resource");
		mBackgroundColor = LoadAttrColor(child, "color", mBackgroundColor);
	}
	if (mBackground && mBackground->GetResource())
	{
		mBackgroundW = mBackground->GetWidth();
		mBackgroundH = mBackground->GetHeight();
	}

	// Load the cursor color
	child = FindNode(node, "cursor");
	if (child)
	{
		mCursor = LoadAttrImage(child, "resource");
		mCursorColor = LoadAttrColor(child, "color", mCursorColor);
		attr = child->first_attribute("hasfocus");
		if (attr)
		{
			std::string focus = attr->value();
			SetInputFocus(atoi(focus.c_str()));
		}
		CursorWidth = LoadAttrIntScaleX(child, "width", CursorWidth);
	}
	DrawCursor = HasInputFocus;

	// Load the font
	child = FindNode(node, "font");
	if (child)
	{
		mFont = LoadAttrFont(child, "resource");
		mFontHeight = mFont->GetHeight();
	}

	child = FindNode(node, "text");
	if (child)  mText = child->value();
	mLastValue = gui_parse_text(mText);

	child = FindNode(node, "data");
	if (child)
	{
		attr = child->first_attribute("name");
		if (attr)
			mVariable = attr->value();
		attr = child->first_attribute("default");
		if (attr)
			DataManager::SetValue(mVariable, attr->value());
		mMask = LoadAttrString(child, "mask");
		HasMask = !mMask.empty();
		attr = child->first_attribute("maskvariable");
		if (attr)
			mMaskVariable = attr->value();
		else
			mMaskVariable = mVariable;
	}

	// Load input restrictions
	child = FindNode(node, "restrict");
	if (child)
	{
		MinLen = LoadAttrInt(child, "minlen", MinLen);
		MaxLen = LoadAttrInt(child, "maxlen", MaxLen);
		AllowedList = LoadAttrString(child, "allow");
		HasAllowed = !AllowedList.empty();
		DisabledList = LoadAttrString(child, "disable");
		HasDisabled = !DisabledList.empty();
	}

	// Load the placement
	LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH);
	SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);

	if (mInputText && mFontHeight && mFontHeight < (unsigned)mRenderH) {
		mFontY = ((mRenderH - mFontHeight) / 2) + mRenderY;
		mInputText->SetRenderPos(mRenderX, mFontY);
	} else
		mFontY = mRenderY;

	if (mInputText)
		mInputText->SetMaxWidth(mRenderW);

	isLocalChange = false;
	HandleTextLocation(-3);
}
Example #20
0
int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
{
	static string zip_queue[10];
	static int zip_queue_index;
	int simulate;

	std::string arg = gui_parse_text(action.mArg);

	std::string function = gui_parse_text(action.mFunction);

	DataManager::GetValue(TW_SIMULATE_ACTIONS, simulate);

    if (function == "reboot")
    {
        //curtainClose(); this sometimes causes a crash

        sync();

        if (arg == "recovery")
            tw_reboot(rb_recovery);
        else if (arg == "poweroff")
            tw_reboot(rb_poweroff);
        else if (arg == "bootloader")
            tw_reboot(rb_bootloader);
        else if (arg == "download")
	    tw_reboot(rb_download);
        else
            tw_reboot(rb_system);

        // This should never occur
        return -1;
    }
    if (function == "home")
    {
        PageManager::SelectPackage("TWRP");
        gui_changePage("main");
        return 0;
    }

    if (function == "key")
    {
        PageManager::NotifyKey(getKeyByName(arg));
        return 0;
    }

    if (function == "page") {
		std::string page_name = gui_parse_text(arg);
        return gui_changePage(page_name);
	}

    if (function == "reload") {
		int check = 0, ret_val = 0;
		std::string theme_path;

		operation_start("Reload Theme");
		theme_path = DataManager::GetSettingsStoragePath();
		if (ensure_path_mounted(theme_path.c_str()) < 0) {
			LOGE("Unable to mount %s during reload function startup.\n", theme_path.c_str());
			check = 1;
		}

		theme_path += "/TWRP/theme/ui.zip";
		if (check != 0 || PageManager::ReloadPackage("TWRP", theme_path) != 0)
		{
			// Loading the custom theme failed - try loading the stock theme
			LOGI("Attempting to reload stock theme...\n");
			if (PageManager::ReloadPackage("TWRP", "/res/ui.xml"))
			{
				LOGE("Failed to load base packages.\n");
				ret_val = 1;
			}
		}
        operation_end(ret_val, simulate);
	}

    if (function == "readBackup")
    {
		set_restore_files();
        return 0;
    }

    if (function == "set")
    {
        if (arg.find('=') != string::npos)
        {
            string varName = arg.substr(0, arg.find('='));
            string value = arg.substr(arg.find('=') + 1, string::npos);

            DataManager::GetValue(value, value);
            DataManager::SetValue(varName, value);
        }
        else
            DataManager::SetValue(arg, "1");
        return 0;
    }
    if (function == "clear")
    {
        DataManager::SetValue(arg, "0");
        return 0;
    }

    if (function == "mount")
    {
        if (arg == "usb")
        {
            DataManager::SetValue(TW_ACTION_BUSY, 1);
			if (!simulate)
				usb_storage_enable();
			else
				ui_print("Simulating actions...\n");
        }
        else if (!simulate)
        {
            string cmd;
			if (arg == "EXTERNAL")
				cmd = "mount " + DataManager::GetStrValue(TW_EXTERNAL_MOUNT);
			else if (arg == "INTERNAL")
				cmd = "mount " + DataManager::GetStrValue(TW_INTERNAL_MOUNT);
			else
				cmd = "mount " + arg;
            __system(cmd.c_str());
			if (arg == "/data" && DataManager::GetIntValue(TW_HAS_DATADATA) == 1)
				__system("mount /datadata");
        } else
			ui_print("Simulating actions...\n");
        return 0;
    }

    if (function == "umount" || function == "unmount")
    {
        if (arg == "usb")
        {
            if (!simulate)
				usb_storage_disable();
			else
				ui_print("Simulating actions...\n");
			DataManager::SetValue(TW_ACTION_BUSY, 0);
        }
        else if (!simulate)
        {
            string cmd;
			if (arg == "EXTERNAL")
				cmd = "umount " + DataManager::GetStrValue(TW_EXTERNAL_MOUNT);
			else if (arg == "INTERNAL")
				cmd = "umount " + DataManager::GetStrValue(TW_INTERNAL_MOUNT);
			else if (DataManager::GetIntValue(TW_DONT_UNMOUNT_SYSTEM) == 1 && (arg == "system" || arg == "/system"))
				return 0;
			else
				cmd = "umount " + arg;
            __system(cmd.c_str());
			if (arg == "/data" && DataManager::GetIntValue(TW_HAS_DATADATA) == 1)
				__system("umount /datadata");
        } else
			ui_print("Simulating actions...\n");
        return 0;
    }
	
	if (function == "restoredefaultsettings")
	{
		operation_start("Restore Defaults");
		if (simulate) // Simulated so that people don't accidently wipe out the "simulation is on" setting
			ui_print("Simulating actions...\n");
		else {
			DataManager::ResetDefaults();
			mount_current_storage();
		}
		operation_end(0, simulate);
	}
	
	if (function == "copylog")
	{
		operation_start("Copy Log");
		if (!simulate)
		{
			char command[255];

			mount_current_storage();
			sprintf(command, "cp /tmp/recovery.log %s", DataManager::GetCurrentStoragePath().c_str());
			__system(command);
			sync();
			ui_print("Copied recovery log to %s.\n", DataManager::GetCurrentStoragePath().c_str());
		} else
			simulate_progress_bar();
		operation_end(0, simulate);
		return 0;
	}
	
	if (function == "compute" || function == "addsubtract")
	{
		if (arg.find("+") != string::npos)
        {
            string varName = arg.substr(0, arg.find('+'));
            string string_to_add = arg.substr(arg.find('+') + 1, string::npos);
			int amount_to_add = atoi(string_to_add.c_str());
			int value;

			DataManager::GetValue(varName, value);
            DataManager::SetValue(varName, value + amount_to_add);
			return 0;
        }
		if (arg.find("-") != string::npos)
        {
            string varName = arg.substr(0, arg.find('-'));
            string string_to_subtract = arg.substr(arg.find('-') + 1, string::npos);
			int amount_to_subtract = atoi(string_to_subtract.c_str());
			int value;

			DataManager::GetValue(varName, value);
			value -= amount_to_subtract;
			if (value <= 0)
				value = 0;
            DataManager::SetValue(varName, value);
			return 0;
        }
	}
	
	if (function == "setguitimezone")
	{
		string SelectedZone;
		DataManager::GetValue(TW_TIME_ZONE_GUISEL, SelectedZone); // read the selected time zone into SelectedZone
		string Zone = SelectedZone.substr(0, SelectedZone.find(';')); // parse to get time zone
		string DSTZone = SelectedZone.substr(SelectedZone.find(';') + 1, string::npos); // parse to get DST component
		
		int dst;
		DataManager::GetValue(TW_TIME_ZONE_GUIDST, dst); // check wether user chose to use DST
		
		string offset;
		DataManager::GetValue(TW_TIME_ZONE_GUIOFFSET, offset); // pull in offset
		
		string NewTimeZone = Zone;
		if (offset != "0")
			NewTimeZone += ":" + offset;
		
		if (dst != 0)
			NewTimeZone += DSTZone;
		
		DataManager::SetValue(TW_TIME_ZONE_VAR, NewTimeZone);
		update_tz_environment_variables();
		return 0;
	}

	if (function == "togglestorage") {
		if (arg == "internal") {
			DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0);
			DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcint.sze - sdcint.used) / 1048576LLU));
		} else if (arg == "external") {
			DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 1);
			DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcext.sze - sdcext.used) / 1048576LLU));
		}
		if (mount_current_storage() == 0) {
			if (arg == "internal") {
				// Save the current zip location to the external variable
				DataManager::SetValue(TW_ZIP_EXTERNAL_VAR, DataManager::GetStrValue(TW_ZIP_LOCATION_VAR));
				// Change the current zip location to the internal variable
				DataManager::SetValue(TW_ZIP_LOCATION_VAR, DataManager::GetStrValue(TW_ZIP_INTERNAL_VAR));
			} else if (arg == "external") {
				// Save the current zip location to the internal variable
				DataManager::SetValue(TW_ZIP_INTERNAL_VAR, DataManager::GetStrValue(TW_ZIP_LOCATION_VAR));
				// Change the current zip location to the external variable
				DataManager::SetValue(TW_ZIP_LOCATION_VAR, DataManager::GetStrValue(TW_ZIP_EXTERNAL_VAR));
			}
		} else {
			// We weren't able to toggle for some reason, restore original setting
			if (arg == "internal") {
				DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 1);
				DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcext.sze - sdcext.used) / 1048576LLU));
			} else if (arg == "external") {
				DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0);
				DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)((sdcint.sze - sdcint.used) / 1048576LLU));
			}
		}
		return 0;
	}
	
	if (function == "overlay")
        return gui_changeOverlay(arg);

	if (function == "queuezip")
    {
        if (zip_queue_index >= 10) {
			ui_print("Maximum zip queue reached!\n");
			return 0;
		}
		DataManager::GetValue("tw_filename", zip_queue[zip_queue_index]);
		if (strlen(zip_queue[zip_queue_index].c_str()) > 0) {
			zip_queue_index++;
			DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
		}
		return 0;
	}

	if (function == "cancelzip")
    {
        if (zip_queue_index <= 0) {
			ui_print("Minimum zip queue reached!\n");
			return 0;
		} else {
			zip_queue_index--;
			DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
		}
		return 0;
	}

	if (function == "queueclear")
	{
		zip_queue_index = 0;
		DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
		return 0;
	}

	if (function == "sleep")
	{
		usleep(atoi(arg.c_str()));
		return 0;
	}

    if (isThreaded)
    {
        if (function == "flash")
        {
			int i, ret_val = 0;

			for (i=0; i<zip_queue_index; i++) {
				operation_start("Flashing");
		        DataManager::SetValue("tw_filename", zip_queue[i]);
		        DataManager::SetValue(TW_ZIP_INDEX, (i + 1));

				ret_val = flash_zip(zip_queue[i], arg, simulate);
				if (ret_val != 0) {
					ui_print("Error flashing zip '%s'\n", zip_queue[i].c_str());
					i = 10; // Error flashing zip - exit queue
					ret_val = 1;
				}
			}
			zip_queue_index = 0;
			DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);

			if (DataManager::GetIntValue(TW_HAS_INJECTTWRP) == 1 && DataManager::GetIntValue(TW_INJECT_AFTER_ZIP) == 1) {
				operation_start("ReinjectTWRP");
				ui_print("Injecting TWRP into boot image...\n");
				if (simulate) {
					simulate_progress_bar();
				} else {
					__system("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash");
					ui_print("TWRP injection complete.\n");
				}
			}
			operation_end(ret_val, simulate);
            return 0;
        }
        if (function == "wipe")
        {
            operation_start("Format");
            DataManager::SetValue("tw_partition", arg);

			if (simulate) {
				simulate_progress_bar();
			} else {
				if (arg == "data")
					wipe_data(0);
				else if (arg == "battery")
					wipe_battery_stats();
				else if (arg == "rotate")
					wipe_rotate_data();
				else if (arg == "dalvik")
					wipe_dalvik_cache();
				else
					erase_volume(arg.c_str());
				
				if (arg == "/sdcard") {
					ensure_path_mounted(SDCARD_ROOT);
					mkdir("/sdcard/TWRP", 0777);
					DataManager::Flush();
				}
			}
			update_system_details();
            operation_end(0, simulate);
            return 0;
        }
		if (function == "refreshsizes")
		{
			operation_start("Refreshing Sizes");
			if (simulate) {
				simulate_progress_bar();
			} else
				update_system_details();
			operation_end(0, simulate);
		}
        if (function == "nandroid")
        {
            operation_start("Nandroid");

			if (simulate) {
				DataManager::SetValue("tw_partition", "Simulation");
				simulate_progress_bar();
			} else {
				if (arg == "backup")
					nandroid_back_exe();
				else if (arg == "restore")
					nandroid_rest_exe();
				else {
					operation_end(1, simulate);
					return -1;
				}
			}
            operation_end(0, simulate);
			return 0;
        }
		if (function == "fixpermissions")
		{
			operation_start("Fix Permissions");
            LOGI("fix permissions started!\n");
			if (simulate) {
				simulate_progress_bar();
			} else
				fix_perms();

			LOGI("fix permissions DONE!\n");
			operation_end(0, simulate);
			return 0;
		}
        if (function == "dd")
        {
            operation_start("imaging");

			if (simulate) {
				simulate_progress_bar();
			} else {
				char cmd[512];
				sprintf(cmd, "dd %s", arg.c_str());
				__system(cmd);
			}
            operation_end(0, simulate);
            return 0;
        }
		if (function == "partitionsd")
		{
			operation_start("Partition SD Card");

			if (simulate) {
				simulate_progress_bar();
			} else {
				int allow_partition;
				DataManager::GetValue(TW_ALLOW_PARTITION_SDCARD, allow_partition);
				if (allow_partition == 0) {
					ui_print("This device does not have a real SD Card!\nAborting!\n");
				} else {
					// Below seen in Koush's recovery
					char sddevice[256];
					Volume *vol = volume_for_path("/sdcard");
					strcpy(sddevice, vol->device);
					// Just need block not whole partition
					sddevice[strlen("/dev/block/mmcblkX")] = NULL;

					char es[64];
					std::string ext_format;
					int ext, swap;
					DataManager::GetValue("tw_sdext_size", ext);
					DataManager::GetValue("tw_swap_size", swap);
					DataManager::GetValue("tw_sdpart_file_system", ext_format);
					sprintf(es, "/sbin/sdparted -es %dM -ss %dM -efs %s -s > /cache/part.log",ext,swap,ext_format.c_str());
					LOGI("\nrunning script: %s\n", es);
					run_script("\nContinue partitioning?",
						   "\nPartitioning sdcard : ",
						   es,
						   "\nunable to execute parted!\n(%s)\n",
						   "\nOops... something went wrong!\nPlease check the recovery log!\n",
						   "\nPartitioning complete!\n\n",
						   "\nPartitioning aborted!\n\n", 0);
					
					// recreate TWRP folder and rewrite settings - these will be gone after sdcard is partitioned
					ensure_path_mounted(SDCARD_ROOT);
					mkdir("/sdcard/TWRP", 0777);
					DataManager::Flush();
					DataManager::SetValue(TW_ZIP_EXTERNAL_VAR, "/sdcard");
					if (DataManager::GetIntValue(TW_USE_EXTERNAL_STORAGE) == 1)
						DataManager::SetValue(TW_ZIP_LOCATION_VAR, "/sdcard");

					update_system_details();
				}
			}
			operation_end(0, simulate);
			return 0;
		}
		if (function == "installhtcdumlock")
		{
			operation_start("Install HTC Dumlock");
			if (simulate) {
				simulate_progress_bar();
			} else
				install_htc_dumlock();

			operation_end(0, simulate);
			return 0;
		}
		if (function == "htcdumlockrestoreboot")
		{
			operation_start("HTC Dumlock Restore Boot");
			if (simulate) {
				simulate_progress_bar();
			} else
				htc_dumlock_restore_original_boot();

			operation_end(0, simulate);
			return 0;
		}
		if (function == "htcdumlockreflashrecovery")
		{
			operation_start("HTC Dumlock Reflash Recovery");
			if (simulate) {
				simulate_progress_bar();
			} else
				htc_dumlock_reflash_recovery_to_boot();

			operation_end(0, simulate);
			return 0;
		}
		if (function == "cmd")
		{
			int op_status = 0;

			operation_start("Command");
			ui_print("Running command: '%s'\n", arg.c_str());
			if (simulate) {
				simulate_progress_bar();
			} else {
				op_status = __system(arg.c_str());
				if (op_status != 0)
					op_status = 1;
			}

			operation_end(op_status, simulate);
			return 0;
		}
		if (function == "reinjecttwrp")
		{
			int op_status = 0;

			operation_start("ReinjectTWRP");
			ui_print("Injecting TWRP into boot image...\n");
			if (simulate) {
				simulate_progress_bar();
			} else {
				__system("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash");
				ui_print("TWRP injection complete.\n");
			}

			operation_end(op_status, simulate);
			return 0;
		}
    }
    else
    {
        pthread_t t;
        pthread_create(&t, NULL, thread_start, this);
        return 0;
    }
    return -1;
}
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;

	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("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);
}