StyleManager 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. // Code by: Jeremy Moles (cubicool) 2007-2008
  14. #ifndef OSGWIDGET_STYLE_MANAGER
  15. #define OSGWIDGET_STYLE_MANAGER
  16. #include <map>
  17. #include <osgDB/Input>
  18. #include <osgWidget/Box>
  19. #include <osgWidget/Frame>
  20. #include <osgWidget/Input>
  21. #include <osgWidget/Canvas>
  22. namespace osgWidget {
  23. typedef osgDB::FieldReaderIterator& Reader;
  24. class OSGWIDGET_EXPORT Style: public osg::Object
  25. {
  26. public:
  27. META_Object(osgWidget, Style);
  28. // Class and contents...
  29. Style (const std::string& = "", const std::string& = "");
  30. Style (const Style&, const osg::CopyOp&);
  31. virtual bool applyStyle (Widget*, Reader);
  32. virtual bool applyStyle (Label*, Reader);
  33. virtual bool applyStyle (Input*, Reader);
  34. virtual bool applyStyle (Window*, Reader);
  35. virtual bool applyStyle (Window::EmbeddedWindow*, Reader);
  36. virtual bool applyStyle (Box*, Reader);
  37. virtual bool applyStyle (Frame::Corner*, Reader);
  38. virtual bool applyStyle (Frame::Border*, Reader);
  39. virtual bool applyStyle (Canvas*, Reader);
  40. void setStyle(const std::string& style) {
  41. _style = style;
  42. }
  43. std::string& getStyle() {
  44. return _style;
  45. }
  46. const std::string& getStyle() const {
  47. return _style;
  48. }
  49. static Widget::Layer strToLayer (const std::string&);
  50. static Widget::VerticalAlignment strToVAlign (const std::string&);
  51. static Widget::HorizontalAlignment strToHAlign (const std::string&);
  52. static Widget::CoordinateMode strToCoordMode (const std::string&);
  53. static bool strToFill (const std::string&);
  54. protected:
  55. std::string _style;
  56. bool _match(const char* seq, Reader r) {
  57. if(r.matchSequence(seq)) {
  58. ++r;
  59. return true;
  60. }
  61. return false;
  62. }
  63. };
  64. class OSGWIDGET_EXPORT StyleManager: public osg::Object
  65. {
  66. public:
  67. typedef std::map<std::string, osg::ref_ptr<Style> > Styles;
  68. typedef Styles::iterator Iterator;
  69. typedef Styles::const_iterator ConstIterator;
  70. META_Object(osgWidget, StyleManager);
  71. StyleManager ();
  72. StyleManager (const StyleManager&, const osg::CopyOp&);
  73. bool addStyle(Style*);
  74. bool applyStyles(Widget* widget) {
  75. return _applyStyles(widget);
  76. }
  77. bool applyStyles(Window* window) {
  78. return _applyStyles(window);
  79. }
  80. private:
  81. Styles _styles;
  82. template<typename T>
  83. bool _applySpecificStyle(T* t, const std::string& style)
  84. {
  85. osgDB::FieldReaderIterator r;
  86. std::istringstream input(_styles[style]->getStyle());
  87. r.attach(&input);
  88. bool inc = false;
  89. while(!r.eof())
  90. {
  91. if(_styles[style]->applyStyle(t, r))
  92. inc = true;
  93. else
  94. r.advanceOverCurrentFieldOrBlock();
  95. }
  96. return inc;
  97. }
  98. template<typename T>
  99. bool _coerceAndApply(
  100. osg::Object* obj,
  101. const std::string& style,
  102. const std::string& className
  103. ) {
  104. T* t = dynamic_cast<T*>(obj);
  105. if(!t) {
  106. warn()
  107. << "An attempt was made to coerce Object [" << obj->getName()
  108. << "] into a " << className << " but failed." << std::endl
  109. ;
  110. return 0;
  111. }
  112. return _applySpecificStyle(t, style);
  113. }
  114. bool _applyStyleToObject(osg::Object*, const std::string&);
  115. // 1. Check and see if the explicit FULL path is available.
  116. // 2. Check and see if each component working backward--minus the last--is available.
  117. // 3. Check to see if just the className() is available.
  118. template<typename T>
  119. bool _applyStyles(T* t)
  120. {
  121. osg::Object* obj = dynamic_cast<osg::Object*>(t);
  122. if(!obj)
  123. {
  124. warn()
  125. << "Cannot call StyleManager::applyStyle with a NULL object or coerce object into osg::Object."
  126. << std::endl;
  127. return false;
  128. }
  129. std::string c = obj->className();
  130. // Case 3; there's no explicit Style set, so see if there's one for the class.
  131. if(t->getStyle().empty())
  132. {
  133. // Couldn't find the className, so we exit.
  134. if(_styles.find(c) == _styles.end()) return false;
  135. return _applyStyleToObject(obj, c);
  136. }
  137. // Case 1...
  138. if(_styles.find(t->getStyle()) != _styles.end()) return _applyStyleToObject(
  139. obj,
  140. t->getStyle()
  141. );
  142. return false;
  143. }
  144. };
  145. }
  146. #endif