From dcc76edd89005e40066a2d0ff0a16be47c69153b Mon Sep 17 00:00:00 2001 From: pieh Date: Mon, 23 Jul 2012 20:39:34 +0200 Subject: [PATCH 1/4] guicontrolfactory: factor out parsing code --- xbmc/guilib/GUIControlFactory.cpp | 27 ++++++++++++++++----------- xbmc/guilib/GUIControlFactory.h | 1 + 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/xbmc/guilib/GUIControlFactory.cpp b/xbmc/guilib/GUIControlFactory.cpp index 5f00ad2669bfa..808e8624e3731 100644 --- a/xbmc/guilib/GUIControlFactory.cpp +++ b/xbmc/guilib/GUIControlFactory.cpp @@ -174,6 +174,20 @@ bool CGUIControlFactory::GetFloatRange(const TiXmlNode* pRootNode, const char* s return true; } +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; + + const char* pos = pNode->FirstChild()->Value(); + char* end; + value = (float)strtod(pos, &end); + if (end && *end == 'r') + value = parentSize - value; + + return true; +} + bool CGUIControlFactory::GetDimension(const TiXmlNode *pRootNode, const char* strTag, float &value, float &min) { const TiXmlElement* pNode = pRootNode->FirstChildElement(strTag); @@ -691,17 +705,8 @@ CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlEl // 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 - XMLUtils::GetFloat(pControlNode, "posx", posX); - XMLUtils::GetFloat(pControlNode, "posy", posY); - // Convert these from relative coords - CStdString pos; - XMLUtils::GetString(pControlNode, "posx", pos); - if (pos.Right(1) == "r") - posX = rect.Width() - posX; - XMLUtils::GetString(pControlNode, "posy", pos); - if (pos.Right(1) == "r") - posY = rect.Height() - posY; - + GetPosition(pControlNode, "posx", posX, rect.Width()); + GetPosition(pControlNode, "posy", posY, rect.Height()); GetDimension(pControlNode, "width", width, minWidth); GetDimension(pControlNode, "height", height, minHeight); XMLUtils::GetFloat(pControlNode, "offsetx", offset.x); diff --git a/xbmc/guilib/GUIControlFactory.h b/xbmc/guilib/GUIControlFactory.h index 4f2bd03e3f295..6087b7b64c24c 100644 --- a/xbmc/guilib/GUIControlFactory.h +++ b/xbmc/guilib/GUIControlFactory.h @@ -102,6 +102,7 @@ class CGUIControlFactory static bool GetHitRect(const TiXmlNode* pRootNode, CRect &rect); static bool GetScroller(const TiXmlNode *pControlNode, const CStdString &scrollerTag, CScroller& scroller); private: + static bool GetPosition(const TiXmlElement *pControlNode, const char* strTag, float& value, float parentSize); static CStdString GetType(const TiXmlElement *pControlNode); static bool GetConditionalVisibility(const TiXmlNode* control, CStdString &condition, CStdString &allowHiddenFocus); bool GetString(const TiXmlNode* pRootNode, const char* strTag, CStdString& strString); From 3450f91db35c7c6869ca19a4a4de58236dbe6a84 Mon Sep 17 00:00:00 2001 From: pieh Date: Mon, 23 Jul 2012 21:05:57 +0200 Subject: [PATCH 2/4] guicontrolfactory: allow more flexible control placement and sizing - allow skinner using combination of 2 from , and : - using and will remain unchanged (control is anchored to the left and have constant width) - using and allow to anchor to the right edge - value specify distance that right edge of control have to right edge of parent group/window - using and will allow to anchor both to left and right edge allowing automatic width calculation similiar logic is present for vertical placement, , , are appropiate tags --- xbmc/guilib/GUIControlFactory.cpp | 55 ++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/xbmc/guilib/GUIControlFactory.cpp b/xbmc/guilib/GUIControlFactory.cpp index 808e8624e3731..6380fc9ecde67 100644 --- a/xbmc/guilib/GUIControlFactory.cpp +++ b/xbmc/guilib/GUIControlFactory.cpp @@ -705,10 +705,57 @@ CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlEl // 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 - GetPosition(pControlNode, "posx", posX, rect.Width()); - GetPosition(pControlNode, "posy", posY, rect.Height()); - GetDimension(pControlNode, "width", width, minWidth); - GetDimension(pControlNode, "height", height, minHeight); + { + // determine position and size of control + // horizontal + bool hasLeft = false; + bool hasWidth = false; + + if (GetPosition(pControlNode, "left", posX, rect.Width()) || + GetPosition(pControlNode, "posx", posX, rect.Width())) + hasLeft = true; + + if (GetDimension(pControlNode, "width", width, minWidth)) + hasWidth = true; + + if (hasLeft != hasWidth) // poor man xor, we have to have at least 1 to continue + { + // if we have just one of , we search for + 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)) + hasHeight = true; + + if (hasTop != hasHeight) // poor man xor, we have to have at least 1 to continue + { + // if we have just one of , we search for + 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, "offsety", offset.y); From af91417c640237fe050094ad58f6779f6a6dbf89 Mon Sep 17 00:00:00 2001 From: pieh Date: Mon, 23 Jul 2012 21:11:09 +0200 Subject: [PATCH 3/4] guicontrolfactory: factor out position string parsing --- xbmc/guilib/GUIControlFactory.cpp | 16 ++++++++++------ xbmc/guilib/GUIControlFactory.h | 1 + 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/xbmc/guilib/GUIControlFactory.cpp b/xbmc/guilib/GUIControlFactory.cpp index 6380fc9ecde67..f0f3c773cb733 100644 --- a/xbmc/guilib/GUIControlFactory.cpp +++ b/xbmc/guilib/GUIControlFactory.cpp @@ -174,17 +174,21 @@ bool CGUIControlFactory::GetFloatRange(const TiXmlNode* pRootNode, const char* s return true; } -bool CGUIControlFactory::GetPosition(const TiXmlElement *pControlNode, const char* strTag, float& value, float parentSize) +float CGUIControlFactory::ParsePosition(const char* pos, float parentSize) { - const TiXmlElement* pNode = pControlNode->FirstChildElement(strTag); - if (!pNode || !pNode->FirstChild()) return false; - - const char* pos = pNode->FirstChild()->Value(); char* end; - value = (float)strtod(pos, &end); + float value = (float)strtod(pos, &end); if (end && *end == 'r') value = parentSize - value; + 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; } diff --git a/xbmc/guilib/GUIControlFactory.h b/xbmc/guilib/GUIControlFactory.h index 6087b7b64c24c..dc9926e8d1d18 100644 --- a/xbmc/guilib/GUIControlFactory.h +++ b/xbmc/guilib/GUIControlFactory.h @@ -102,6 +102,7 @@ class CGUIControlFactory static bool GetHitRect(const TiXmlNode* pRootNode, CRect &rect); static bool GetScroller(const TiXmlNode *pControlNode, const CStdString &scrollerTag, CScroller& scroller); 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 bool GetConditionalVisibility(const TiXmlNode* control, CStdString &condition, CStdString &allowHiddenFocus); From cbdf43f60a1e80bdfaf61c2824d9acdea2b2b0c6 Mon Sep 17 00:00:00 2001 From: pieh Date: Mon, 23 Jul 2012 21:37:12 +0200 Subject: [PATCH 4/4] guicontrolfactory: allow using percentage values for , , , , , concrete value will be calculated based on parent group width or height --- xbmc/guilib/GUIControlFactory.cpp | 21 +++++++++++++-------- xbmc/guilib/GUIControlFactory.h | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/xbmc/guilib/GUIControlFactory.cpp b/xbmc/guilib/GUIControlFactory.cpp index f0f3c773cb733..c1584da0982f4 100644 --- a/xbmc/guilib/GUIControlFactory.cpp +++ b/xbmc/guilib/GUIControlFactory.cpp @@ -178,8 +178,13 @@ float CGUIControlFactory::ParsePosition(const char* pos, float parentSize) { char* end; float value = (float)strtod(pos, &end); - if (end && *end == 'r') - value = parentSize - value; + if (end) + { + if (*end == 'r') + value = parentSize - value; + else if (*end == '%') + value = value * parentSize / 100.0f; + } return value; } @@ -192,18 +197,18 @@ bool CGUIControlFactory::GetPosition(const TiXmlElement *pControlNode, const cha return true; } -bool CGUIControlFactory::GetDimension(const TiXmlNode *pRootNode, const char* strTag, float &value, float &min) +bool CGUIControlFactory::GetDimension(const TiXmlNode *pRootNode, const char* strTag, float &value, float &min, float parentSize) { const TiXmlElement* pNode = pRootNode->FirstChildElement(strTag); if (!pNode || !pNode->FirstChild()) return false; if (0 == strnicmp("auto", pNode->FirstChild()->Value(), 4)) { // auto-width - at least min must be set - pNode->QueryFloatAttribute("max", &value); - pNode->QueryFloatAttribute("min", &min); + value = ParsePosition(pNode->Attribute("max"), parentSize); + min = ParsePosition(pNode->Attribute("min"), parentSize); if (!min) min = 1; return true; } - value = (float)atof(pNode->FirstChild()->Value()); + value = ParsePosition(pNode->FirstChild()->Value(), parentSize); return true; } @@ -719,7 +724,7 @@ CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlEl GetPosition(pControlNode, "posx", posX, rect.Width())) hasLeft = true; - if (GetDimension(pControlNode, "width", width, minWidth)) + if (GetDimension(pControlNode, "width", width, minWidth, rect.Width())) hasWidth = true; if (hasLeft != hasWidth) // poor man xor, we have to have at least 1 to continue @@ -743,7 +748,7 @@ CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlEl GetPosition(pControlNode, "posy", posY, rect.Height())) hasTop = true; - if (GetDimension(pControlNode, "height", height, minHeight)) + 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 diff --git a/xbmc/guilib/GUIControlFactory.h b/xbmc/guilib/GUIControlFactory.h index dc9926e8d1d18..b3b482137f3ad 100644 --- a/xbmc/guilib/GUIControlFactory.h +++ b/xbmc/guilib/GUIControlFactory.h @@ -72,7 +72,7 @@ class CGUIControlFactory \param min minimum value - set != 0 if auto is used. \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 GetInfoTexture(const TiXmlNode* pRootNode, const char* strTag, CTextureInfo &image, CGUIInfoLabel &info, int parentID); static bool GetTexture(const TiXmlNode* pRootNode, const char* strTag, CTextureInfo &image);