diff options
Diffstat (limited to 'indra/llui/lluicolortable.cpp')
-rw-r--r-- | indra/llui/lluicolortable.cpp | 175 |
1 files changed, 157 insertions, 18 deletions
diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp index 27ba6cc8b4..087a99c2b0 100644 --- a/indra/llui/lluicolortable.cpp +++ b/indra/llui/lluicolortable.cpp @@ -11,7 +11,10 @@ #include <queue> +#include "lldir.h" +#include "llui.h" #include "lluicolortable.h" +#include "lluictrlfactory.h" LLUIColorTable::ColorParams::ColorParams() : value("value"), @@ -26,17 +29,16 @@ LLUIColorTable::ColorEntryParams::ColorEntryParams() } LLUIColorTable::Params::Params() -: color_entries("color_entries") +: color_entries("color") { } -void LLUIColorTable::init(const Params& p) +void LLUIColorTable::insertFromParams(const Params& p) { // this map will contain all color references after the following loop typedef std::map<std::string, std::string> string_string_map_t; string_string_map_t unresolved_refs; - mColors.clear(); for(LLInitParam::ParamIterator<ColorEntryParams>::const_iterator it = p.color_entries().begin(); it != p.color_entries().end(); ++it) @@ -44,7 +46,7 @@ void LLUIColorTable::init(const Params& p) ColorEntryParams color_entry = *it; if(color_entry.color.value.isChosen()) { - mColors.insert(string_color_map_t::value_type(color_entry.name, color_entry.color.value)); + setColor(color_entry.name, color_entry.color.value, mLoadedColors); } else { @@ -66,19 +68,21 @@ void LLUIColorTable::init(const Params& p) // we haven't visited any references yet visited_refs.clear(); - string_string_map_t::iterator it = unresolved_refs.begin(); + string_string_map_t::iterator current = unresolved_refs.begin(); + string_string_map_t::iterator previous; + while(true) { - if(it != unresolved_refs.end()) + if(current != unresolved_refs.end()) { // locate the current reference in the previously visited references... - string_color_ref_iter_map_t::iterator visited = visited_refs.lower_bound(it->first); + string_color_ref_iter_map_t::iterator visited = visited_refs.lower_bound(current->first); if(visited != visited_refs.end() - && !(visited_refs.key_comp()(it->first, visited->first))) + && !(visited_refs.key_comp()(current->first, visited->first))) { // ...if we find the current reference in the previously visited references // we know that there is a cycle - std::string ending_ref = it->first; + std::string ending_ref = current->first; std::string warning("The following colors form a cycle: "); // warn about the references in the chain and remove them from @@ -102,17 +106,17 @@ void LLUIColorTable::init(const Params& p) else { // ...continue along the reference chain - ref_chain.push(it->first); - visited_refs.insert(visited, string_color_ref_iter_map_t::value_type(it->first, it)); + ref_chain.push(current->first); + visited_refs.insert(visited, string_color_ref_iter_map_t::value_type(current->first, current)); } } else { // since this reference does not refer to another reference it must refer to an // actual color, lets find it... - string_color_map_t::iterator color_value = mColors.find(it->second); + string_color_map_t::iterator color_value = mLoadedColors.find(previous->second); - if(color_value != mColors.end()) + if(color_value != mLoadedColors.end()) { // ...we found the color, and we now add every reference in the reference chain // to the color map @@ -120,7 +124,7 @@ void LLUIColorTable::init(const Params& p) iter != visited_refs.end(); ++iter) { - mColors.insert(string_color_map_t::value_type(iter->first, color_value->second)); + setColor(iter->first, color_value->second, mLoadedColors); unresolved_refs.erase(iter->second); } @@ -143,13 +147,148 @@ void LLUIColorTable::init(const Params& p) } // find the next color reference in the reference chain - it = unresolved_refs.find(it->second); + previous = current; + current = unresolved_refs.find(current->second); } } } -const LLColor4& LLUIColorTable::getColor(const std::string& name) const +void LLUIColorTable::clear() +{ + clearTable(mLoadedColors); + clearTable(mUserSetColors); +} + +LLUIColor LLUIColorTable::getColor(const std::string& name, const LLColor4& default_color) const +{ + string_color_map_t::const_iterator iter = mUserSetColors.find(name); + if(iter != mUserSetColors.end()) + { + return LLUIColor(&iter->second); + } + + iter = mLoadedColors.find(name); + return (iter != mLoadedColors.end() ? LLUIColor(&iter->second) : LLUIColor(default_color)); +} + +// update user color, loaded colors are parsed on initialization +void LLUIColorTable::setColor(const std::string& name, const LLColor4& color) +{ + setColor(name, color, mUserSetColors); +} + +bool LLUIColorTable::loadFromSettings() +{ + bool result = false; + + std::string default_filename = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "colors.xml"); + result |= loadFromFilename(default_filename); + + std::string current_filename = gDirUtilp->getExpandedFilename(LL_PATH_TOP_SKIN, "colors.xml"); + if(current_filename != default_filename) + { + result |= loadFromFilename(current_filename); + } + + std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml"); + loadFromFilename(user_filename); + + return result; +} + +void LLUIColorTable::saveUserSettings() const { - string_color_map_t::const_iterator iter = mColors.find(name); - return (iter != mColors.end() ? iter->second : LLColor4::magenta); + Params params; + + for(string_color_map_t::const_iterator it = mUserSetColors.begin(); + it != mUserSetColors.end(); + ++it) + { + ColorEntryParams color_entry; + color_entry.name = it->first; + color_entry.color.value = it->second; + + params.color_entries.add(color_entry); + } + + LLXMLNodePtr output_node = new LLXMLNode("colors", false); + LLXUIParser::instance().writeXUI(output_node, params); + + if(!output_node->isNull()) + { + const std::string& filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml"); + LLFILE *fp = LLFile::fopen(filename, "w"); + + if(fp != NULL) + { + LLXMLNode::writeHeaderToFile(fp); + output_node->writeToFile(fp); + + fclose(fp); + } + } +} + +bool LLUIColorTable::colorExists(const std::string& color_name) const +{ + return ((mLoadedColors.find(color_name) != mLoadedColors.end()) + || (mUserSetColors.find(color_name) != mUserSetColors.end())); +} + +void LLUIColorTable::clearTable(string_color_map_t& table) +{ + for(string_color_map_t::iterator it = table.begin(); + it != table.end(); + ++it) + { + it->second = LLColor4::magenta; + } +} + +// this method inserts a color into the table if it does not exist +// if the color already exists it changes the color +void LLUIColorTable::setColor(const std::string& name, const LLColor4& color, string_color_map_t& table) +{ + string_color_map_t::iterator it = table.lower_bound(name); + if(it != table.end() + && !(table.key_comp()(name, it->first))) + { + it->second = color; + } + else + { + table.insert(it, string_color_map_t::value_type(name, color)); + } +} + +bool LLUIColorTable::loadFromFilename(const std::string& filename) +{ + LLXMLNodePtr root; + + if(!LLXMLNode::parseFile(filename, root, NULL)) + { + llwarns << "Unable to parse color file " << filename << llendl; + return false; + } + + if(!root->hasName("colors")) + { + llwarns << filename << " is not a valid color definition file" << llendl; + return false; + } + + Params params; + LLXUIParser::instance().readXUI(root, params); + + if(params.validateBlock()) + { + insertFromParams(params); + } + else + { + llwarns << filename << " failed to load" << llendl; + return false; + } + + return true; } |