openscenegraph
StyleManager
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14// Code by: Jeremy Moles (cubicool) 2007-2008
15
16#ifndef OSGWIDGET_STYLE_MANAGER
17#define OSGWIDGET_STYLE_MANAGER
18
19#include <map>
20#include <osgDB/Input>
21#include <osgWidget/Box>
22#include <osgWidget/Frame>
23#include <osgWidget/Input>
24#include <osgWidget/Canvas>
25
26namespace osgWidget {
27
28typedef osgDB::FieldReaderIterator& Reader;
29
30class OSGWIDGET_EXPORT Style: public osg::Object
31{
32 public:
33 META_Object(osgWidget, Style);
34
35 // Class and contents...
36 Style (const std::string& = "", const std::string& = "");
37 Style (const Style&, const osg::CopyOp&);
38
39 virtual bool applyStyle (Widget*, Reader);
40 virtual bool applyStyle (Label*, Reader);
41 virtual bool applyStyle (Input*, Reader);
42 virtual bool applyStyle (Window*, Reader);
43 virtual bool applyStyle (Window::EmbeddedWindow*, Reader);
44 virtual bool applyStyle (Box*, Reader);
45 virtual bool applyStyle (Frame::Corner*, Reader);
46 virtual bool applyStyle (Frame::Border*, Reader);
47 virtual bool applyStyle (Canvas*, Reader);
48
49
50
51 void setStyle(const std::string& style) {
52 _style = style;
53 }
54
55 std::string& getStyle() {
56 return _style;
57 }
58
59 const std::string& getStyle() const {
60 return _style;
61 }
62
63 static Widget::Layer strToLayer (const std::string&);
64 static Widget::VerticalAlignment strToVAlign (const std::string&);
65 static Widget::HorizontalAlignment strToHAlign (const std::string&);
66 static Widget::CoordinateMode strToCoordMode (const std::string&);
67 static bool strToFill (const std::string&);
68
69 protected:
70
71 std::string _style;
72
73 bool _match(const char* seq, Reader r) {
74 if(r.matchSequence(seq)) {
75 ++r;
76
77 return true;
78 }
79
80 return false;
81 }
82};
83
84class OSGWIDGET_EXPORT StyleManager: public osg::Object
85{
86 public:
87 typedef std::map<std::string, osg::ref_ptr<Style> > Styles;
88 typedef Styles::iterator Iterator;
89 typedef Styles::const_iterator ConstIterator;
90
91 META_Object(osgWidget, StyleManager);
92
93 StyleManager ();
94 StyleManager (const StyleManager&, const osg::CopyOp&);
95
96 bool addStyle(Style*);
97
98 bool applyStyles(Widget* widget) {
99 return _applyStyles(widget);
100 }
101
102 bool applyStyles(Window* window) {
103 return _applyStyles(window);
104 }
105
106 private:
107 Styles _styles;
108
109 template<typename T>
110 bool _applySpecificStyle(T* t, const std::string& style)
111 {
112 osgDB::FieldReaderIterator r;
113
114 std::istringstream input(_styles[style]->getStyle());
115
116 r.attach(&input);
117
118 bool inc = false;
119
120 while(!r.eof())
121 {
122 if(_styles[style]->applyStyle(t, r))
123 inc = true;
124 else
125 r.advanceOverCurrentFieldOrBlock();
126 }
127
128
129
130 return inc;
131 }
132
133 template<typename T>
134 bool _coerceAndApply(
135 osg::Object* obj,
136 const std::string& style,
137 const std::string& className
138 ) {
139 T* t = dynamic_cast<T*>(obj);
140
141 if(!t) {
142 warn()
143 << "An attempt was made to coerce Object [" << obj->getName()
144 << "] into a " << className << " but failed." << std::endl
145 ;
146
147 return 0;
148 }
149
150 return _applySpecificStyle(t, style);
151 }
152
153
154 bool _applyStyleToObject(osg::Object*, const std::string&);
155
156 // 1. Check and see if the explicit FULL path is available.
157 // 2. Check and see if each component working backward--minus the last--is available.
158 // 3. Check to see if just the className() is available.
159 template<typename T>
160 bool _applyStyles(T* t)
161 {
162 osg::Object* obj = dynamic_cast<osg::Object*>(t);
163 if(!obj)
164 {
165 warn()
166 << "Cannot call StyleManager::applyStyle with a NULL object or coerce object into osg::Object."
167 << std::endl;
168
169 return false;
170 }
171
172 std::string c = obj->className();
173
174 // Case 3; there's no explicit Style set, so see if there's one for the class.
175 if(t->getStyle().empty())
176 {
177 // Couldn't find the className, so we exit.
178 if(_styles.find(c) == _styles.end()) return false;
179
180 return _applyStyleToObject(obj, c);
181 }
182
183 // Case 1...
184 if(_styles.find(t->getStyle()) != _styles.end()) return _applyStyleToObject(
185 obj,
186 t->getStyle()
187 );
188
189 return false;
190 }
191
192};
193
194}
195
196#endif