1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
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.
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.
14// Code by: Jeremy Moles (cubicool) 2007-2008
16#ifndef OSGWIDGET_STYLE_MANAGER
17#define OSGWIDGET_STYLE_MANAGER
21#include <osgWidget/Box>
22#include <osgWidget/Frame>
23#include <osgWidget/Input>
24#include <osgWidget/Canvas>
28typedef osgDB::FieldReaderIterator& Reader;
30class OSGWIDGET_EXPORT Style: public osg::Object
33 META_Object(osgWidget, Style);
35 // Class and contents...
36 Style (const std::string& = "", const std::string& = "");
37 Style (const Style&, const osg::CopyOp&);
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);
51 void setStyle(const std::string& style) {
55 std::string& getStyle() {
59 const std::string& getStyle() const {
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&);
73 bool _match(const char* seq, Reader r) {
74 if(r.matchSequence(seq)) {
84class OSGWIDGET_EXPORT StyleManager: public osg::Object
87 typedef std::map<std::string, osg::ref_ptr<Style> > Styles;
88 typedef Styles::iterator Iterator;
89 typedef Styles::const_iterator ConstIterator;
91 META_Object(osgWidget, StyleManager);
94 StyleManager (const StyleManager&, const osg::CopyOp&);
96 bool addStyle(Style*);
98 bool applyStyles(Widget* widget) {
99 return _applyStyles(widget);
102 bool applyStyles(Window* window) {
103 return _applyStyles(window);
110 bool _applySpecificStyle(T* t, const std::string& style)
112 osgDB::FieldReaderIterator r;
114 std::istringstream input(_styles[style]->getStyle());
122 if(_styles[style]->applyStyle(t, r))
125 r.advanceOverCurrentFieldOrBlock();
134 bool _coerceAndApply(
136 const std::string& style,
137 const std::string& className
139 T* t = dynamic_cast<T*>(obj);
143 << "An attempt was made to coerce Object [" << obj->getName()
144 << "] into a " << className << " but failed." << std::endl
150 return _applySpecificStyle(t, style);
154 bool _applyStyleToObject(osg::Object*, const std::string&);
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.
160 bool _applyStyles(T* t)
162 osg::Object* obj = dynamic_cast<osg::Object*>(t);
166 << "Cannot call StyleManager::applyStyle with a NULL object or coerce object into osg::Object."
172 std::string c = obj->className();
174 // Case 3; there's no explicit Style set, so see if there's one for the class.
175 if(t->getStyle().empty())
177 // Couldn't find the className, so we exit.
178 if(_styles.find(c) == _styles.end()) return false;
180 return _applyStyleToObject(obj, c);
184 if(_styles.find(t->getStyle()) != _styles.end()) return _applyStyleToObject(