1 // Some helper functions for accessing the property tree
3 // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "property_helper.hxx"
21 #include <boost/algorithm/string/predicate.hpp>
22 #include <boost/algorithm/string/trim.hpp>
23 #include <boost/lexical_cast.hpp>
24 #include <boost/tokenizer.hpp>
30 //----------------------------------------------------------------------------
31 std::vector<float> splitAndConvert(const char del[], const std::string& str)
33 std::vector<float> values;
37 pos = str.find_first_not_of(del, pos);
38 if( pos == std::string::npos )
42 float val = strtod(&str[pos], &end);
43 if( end == &str[pos] || !end )
46 values.push_back(val);
52 //----------------------------------------------------------------------------
53 osg::Vec4 parseColor(std::string str)
56 osg::Vec4 color(0,0,0,1);
64 const int offsets[] = {2,2,2};
65 const boost::offset_separator hex_separator( boost::begin(offsets),
66 boost::end(offsets) );
67 typedef boost::tokenizer<boost::offset_separator> offset_tokenizer;
68 offset_tokenizer tokens(str.begin() + 1, str.end(), hex_separator);
71 for( offset_tokenizer::const_iterator tok = tokens.begin();
72 tok != tokens.end() && comp < 4;
75 color._v[comp] = strtol(std::string(*tok).c_str(), 0, 16) / 255.f;
80 else if( boost::ends_with(str, ")") )
82 const std::string RGB = "rgb(",
85 if( boost::starts_with(str, RGB) )
87 else if( boost::starts_with(str, RGBA) )
92 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
93 const boost::char_separator<char> del(", \t\n");
95 tokenizer tokens(str.begin() + pos, str.end() - 1, del);
97 for( tokenizer::const_iterator tok = tokens.begin();
98 tok != tokens.end() && comp < 4;
101 color._v[comp] = boost::lexical_cast<float>(*tok)
102 // rgb = [0,255], a = [0,1]
103 / (comp < 3 ? 255 : 1);
107 SG_LOG(SG_GENERAL, SG_WARN, "Unknown color: " << str);
112 //----------------------------------------------------------------------------
113 void linkColorNodes( const char* name,
114 SGPropertyNode* parent,
115 std::vector<SGPropertyNode_ptr>& nodes,
116 const osg::Vec4& def )
118 static const char* channels[] = {"red", "green", "blue", "alpha"};
119 static const size_t num_channels = sizeof(channels)/sizeof(channels[0]);
124 // Don't tie to allow the usage of aliases
125 SGPropertyNode_ptr color = parent->getChild(name, 0, true);
127 // We need to be carefull do not get any unitialized nodes or null pointers
128 // because while creating the node a valueChanged event will be triggered.
130 nodes.reserve(num_channels);
132 for( size_t i = 0; i < num_channels; ++i )
133 nodes.push_back( getChildDefault(color, channels[i], def[i]) );
136 //----------------------------------------------------------------------------
137 void triggerChangeRecursive(SGPropertyNode* node)
139 node->getParent()->fireChildAdded(node);
141 if( node->nChildren() == 0 && node->getType() != simgear::props::NONE )
142 return node->fireValueChanged();
144 for( int i = 0; i < node->nChildren(); ++i )
145 triggerChangeRecursive( node->getChild(i) );