Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make skin controls positioning more flexible #1208

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
95 changes: 78 additions & 17 deletions xbmc/guilib/GUIControlFactory.cpp
Expand Up @@ -174,18 +174,41 @@ bool CGUIControlFactory::GetFloatRange(const TiXmlNode* pRootNode, const char* s
return true; return true;
} }


bool CGUIControlFactory::GetDimension(const TiXmlNode *pRootNode, const char* strTag, float &value, float &min) float CGUIControlFactory::ParsePosition(const char* pos, float parentSize)
{
char* end;
float value = (float)strtod(pos, &end);
if (end)
{
if (*end == 'r')
value = parentSize - value;
else if (*end == '%')
value = value * parentSize / 100.0f;
}
return value;
}

bool CGUIControlFactory::GetPosition(const TiXmlElement *pControlNode, const char* strTag, float& value, float parentSize)
{
const TiXmlElement* pNode = pControlNode->FirstChildElement(strTag);
if (!pNode || !pNode->FirstChild()) return false;

value = ParsePosition(pNode->FirstChild()->Value(), parentSize);
return true;
}

bool CGUIControlFactory::GetDimension(const TiXmlNode *pRootNode, const char* strTag, float &value, float &min, float parentSize)
{ {
const TiXmlElement* pNode = pRootNode->FirstChildElement(strTag); const TiXmlElement* pNode = pRootNode->FirstChildElement(strTag);
if (!pNode || !pNode->FirstChild()) return false; if (!pNode || !pNode->FirstChild()) return false;
if (0 == strnicmp("auto", pNode->FirstChild()->Value(), 4)) if (0 == strnicmp("auto", pNode->FirstChild()->Value(), 4))
{ // auto-width - at least min must be set { // auto-width - at least min must be set
pNode->QueryFloatAttribute("max", &value); value = ParsePosition(pNode->Attribute("max"), parentSize);
pNode->QueryFloatAttribute("min", &min); min = ParsePosition(pNode->Attribute("min"), parentSize);
if (!min) min = 1; if (!min) min = 1;
return true; return true;
} }
value = (float)atof(pNode->FirstChild()->Value()); value = ParsePosition(pNode->FirstChild()->Value(), parentSize);
return true; return true;
} }


Expand Down Expand Up @@ -691,19 +714,57 @@ CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlEl
// TODO: Perhaps we should check here whether id is valid for focusable controls // TODO: Perhaps we should check here whether id is valid for focusable controls
// such as buttons etc. For labels/fadelabels/images it does not matter // such as buttons etc. For labels/fadelabels/images it does not matter


XMLUtils::GetFloat(pControlNode, "posx", posX); {
XMLUtils::GetFloat(pControlNode, "posy", posY); // determine position and size of control
// Convert these from relative coords // horizontal
CStdString pos; bool hasLeft = false;
XMLUtils::GetString(pControlNode, "posx", pos); bool hasWidth = false;
if (pos.Right(1) == "r")
posX = rect.Width() - posX; if (GetPosition(pControlNode, "left", posX, rect.Width()) ||
XMLUtils::GetString(pControlNode, "posy", pos); GetPosition(pControlNode, "posx", posX, rect.Width()))
if (pos.Right(1) == "r") hasLeft = true;
posY = rect.Height() - posY;

if (GetDimension(pControlNode, "width", width, minWidth, rect.Width()))
GetDimension(pControlNode, "width", width, minWidth); hasWidth = true;
GetDimension(pControlNode, "height", height, minHeight);
if (hasLeft != hasWidth) // poor man xor, we have to have at least 1 to continue
{
// if we have just one of <posx>, <width> we search for <right>
float right;
if (GetPosition(pControlNode, "right", right, rect.Width()))
{
if (hasLeft)
width = (rect.Width() - right) - posX;
else // if (hasWidth)
posX = (rect.Width() - right) - width;
}
}

// vertical
bool hasTop = false;
bool hasHeight = false;

if (GetPosition(pControlNode, "top", posY, rect.Height()) ||
GetPosition(pControlNode, "posy", posY, rect.Height()))
hasTop = true;

if (GetDimension(pControlNode, "height", height, minHeight, rect.Height()))
hasHeight = true;

if (hasTop != hasHeight) // poor man xor, we have to have at least 1 to continue
{
// if we have just one of <posy>, <height> we search for <bottom>
float bottom;
if (GetPosition(pControlNode, "bottom", bottom, rect.Height()))
{
if (hasTop)
height = (rect.Height() - bottom) - posY;
else // if (hasHeight)
posY = (rect.Height() - bottom) - height;
}
}
}

XMLUtils::GetFloat(pControlNode, "offsetx", offset.x); XMLUtils::GetFloat(pControlNode, "offsetx", offset.x);
XMLUtils::GetFloat(pControlNode, "offsety", offset.y); XMLUtils::GetFloat(pControlNode, "offsety", offset.y);


Expand Down
4 changes: 3 additions & 1 deletion xbmc/guilib/GUIControlFactory.h
Expand Up @@ -72,7 +72,7 @@ class CGUIControlFactory
\param min minimum value - set != 0 if auto is used. \param min minimum value - set != 0 if auto is used.
\return true if we found and read the tag. \return true if we found and read the tag.
*/ */
static bool GetDimension(const TiXmlNode* pRootNode, const char* strTag, float &value, float &min); static bool GetDimension(const TiXmlNode* pRootNode, const char* strTag, float &value, float &min, float parentSize);
static bool GetAspectRatio(const TiXmlNode* pRootNode, const char* strTag, CAspectRatio &aspectRatio); static bool GetAspectRatio(const TiXmlNode* pRootNode, const char* strTag, CAspectRatio &aspectRatio);
static bool GetInfoTexture(const TiXmlNode* pRootNode, const char* strTag, CTextureInfo &image, CGUIInfoLabel &info, int parentID); static bool GetInfoTexture(const TiXmlNode* pRootNode, const char* strTag, CTextureInfo &image, CGUIInfoLabel &info, int parentID);
static bool GetTexture(const TiXmlNode* pRootNode, const char* strTag, CTextureInfo &image); static bool GetTexture(const TiXmlNode* pRootNode, const char* strTag, CTextureInfo &image);
Expand Down Expand Up @@ -102,6 +102,8 @@ class CGUIControlFactory
static bool GetHitRect(const TiXmlNode* pRootNode, CRect &rect); static bool GetHitRect(const TiXmlNode* pRootNode, CRect &rect);
static bool GetScroller(const TiXmlNode *pControlNode, const CStdString &scrollerTag, CScroller& scroller); static bool GetScroller(const TiXmlNode *pControlNode, const CStdString &scrollerTag, CScroller& scroller);
private: private:
static float ParsePosition(const char* pos, float parentSize);
static bool GetPosition(const TiXmlElement *pControlNode, const char* strTag, float& value, float parentSize);
static CStdString GetType(const TiXmlElement *pControlNode); static CStdString GetType(const TiXmlElement *pControlNode);
static bool GetConditionalVisibility(const TiXmlNode* control, CStdString &condition, CStdString &allowHiddenFocus); static bool GetConditionalVisibility(const TiXmlNode* control, CStdString &condition, CStdString &allowHiddenFocus);
bool GetString(const TiXmlNode* pRootNode, const char* strTag, CStdString& strString); bool GetString(const TiXmlNode* pRootNode, const char* strTag, CStdString& strString);
Expand Down