Added the ability to theme multiple elements of the same type

simultaneously.
This commit is contained in:
Aloshi 2014-01-24 19:25:15 -06:00
parent 420dc912e0
commit 612b196b11
2 changed files with 71 additions and 8 deletions

View file

@ -179,6 +179,60 @@ Notice that you can still override the "common" view in a specific view definiti
You probably should not use the "common" view for element positioning. You also should not use it to create "extra" elements.
### Theming more than one elements at once
You can theme multiple elements *of the same type* simultaneously. The `name` attribute actually works as a list (delimited by any characters of ` \t\n,` - that is, whitespace and commas). This is useful if you want to, say, apply the same color to all the metadata labels:
```xml
<theme>
<version>3</version>
<!-- Weird spaces/newline on purpose! -->
<view name="detailed">
<text name="md_lbl_rating, md_lbl_releasedate, md_lbl_developer, md_lbl_publisher,
md_lbl_genre, md_lbl_players, md_lbl_lastplayed, md_lbl_playcount">
<color>48474D</color>
</text>
</view>
</theme>
```
Is equivalent to:
```xml
<theme>
<version>3</version>
<view name="detailed">
<text name="md_lbl_rating">
<color>48474D</color>
</text>
<text name="md_lbl_releasedate">
<color>48474D</color>
</text>
<text name="md_lbl_developer">
<color>48474D</color>
</text>
<text name="md_lbl_publisher">
<color>48474D</color>
</text>
<text name="md_lbl_genre">
<color>48474D</color>
</text>
<text name="md_lbl_players">
<color>48474D</color>
</text>
<text name="md_lbl_lastplayed">
<color>48474D</color>
</text>
<text name="md_lbl_playcount">
<color>48474D</color>
</text>
</view>
</theme>
```
Just remember, *this only works if the elements have the same type!*
Reference
=========

View file

@ -222,7 +222,15 @@ void ThemeData::parseView(const pugi::xml_node& root, ThemeView& view)
if(elemTypeIt == sElementMap.end())
throw error << "Unknown element of type \"" << node.name() << "\"!";
const char* elemKey = node.attribute("name").as_string();
const char* delim = " \t\n,";
const std::string nameAttr = node.attribute("name").as_string();
size_t prevOff = nameAttr.find_first_not_of(delim, 0);
size_t off = nameAttr.find_first_of(delim, prevOff);
while(off != std::string::npos || prevOff != std::string::npos)
{
std::string elemKey = nameAttr.substr(prevOff, off - prevOff);
prevOff = nameAttr.find_first_not_of(delim, off);
off = nameAttr.find_first_of(delim, prevOff);
parseElement(node, elemTypeIt->second,
view.elements.insert(std::make_pair<std::string, ThemeElement>(elemKey, ThemeElement())).first->second);
@ -231,6 +239,7 @@ void ThemeData::parseView(const pugi::xml_node& root, ThemeView& view)
view.orderedKeys.push_back(elemKey);
}
}
}
void ThemeData::parseElement(const pugi::xml_node& root, const std::map<std::string, ElementPropertyType>& typeMap, ThemeElement& element)
@ -255,7 +264,7 @@ void ThemeData::parseElement(const pugi::xml_node& root, const std::map<std::str
size_t divider = str.find(' ');
if(divider == std::string::npos)
throw error << "invalid normalized pair (\"" << str.c_str() << "\")";
throw error << "invalid normalized pair (property \"" << node.name() << "\", value \"" << str.c_str() << "\")";
std::string first = str.substr(0, divider);
std::string second = str.substr(divider, std::string::npos);
@ -293,7 +302,7 @@ void ThemeData::parseElement(const pugi::xml_node& root, const std::map<std::str
element.properties[node.name()] = node.text().as_bool();
break;
default:
throw error << "Unknown ElementPropertyType for " << root.attribute("name").as_string() << " property " << node.name();
throw error << "Unknown ElementPropertyType for \"" << root.attribute("name").as_string() << "\", property " << node.name();
}
}
}