From e93e7ca1f2bcaf578c0431bd044027c91373dba6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 9 Sep 2014 13:37:33 +0000 Subject: [PATCH] Introduced Widget::WidgetStateSet to help localize the StateSet set up by Widget implementations from being serialized or affecting what end users apply via the standard Node::s/getStateSet(). Further work on TabWidget. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14440 16af8721-9629-0410-8352-f15c8da7e697 --- include/osgUI/TabWidget | 19 +++--- include/osgUI/Widget | 9 +++ src/osgUI/ComboBox.cpp | 2 +- src/osgUI/Dialog.cpp | 4 +- src/osgUI/Label.cpp | 2 +- src/osgUI/LineEdit.cpp | 2 +- src/osgUI/Popup.cpp | 6 +- src/osgUI/PushButton.cpp | 2 +- src/osgUI/Style.cpp | 5 ++ src/osgUI/TabWidget.cpp | 66 ++++++++++++++++++++ src/osgUI/Widget.cpp | 5 ++ src/osgWrappers/serializers/osgUI/Tab.cpp | 1 - src/osgWrappers/serializers/osgUI/Widget.cpp | 4 ++ 13 files changed, 107 insertions(+), 20 deletions(-) diff --git a/include/osgUI/TabWidget b/include/osgUI/TabWidget index c2e2f06e1..566e09535 100644 --- a/include/osgUI/TabWidget +++ b/include/osgUI/TabWidget @@ -25,12 +25,10 @@ class OSGUI_EXPORT Tab : public osg::Object { public: - Tab() : _color(1.0f,1.0f,1.0f,0.0f) {} - Tab(const std::string& str) : _text(str), _color(1.0f,1.0f,1.0f,0.0f) {} - Tab(const std::string& str, const osg::Vec4& col) : _text(str), _color(col) {} - Tab(const osg::Vec4& col) : _color(col) {} + Tab() {} + Tab(const std::string& str) : _text(str) {} - Tab(const Tab& item, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osg::Object(item,copyop), _text(item._text), _color(item._color) {} + Tab(const Tab& item, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osg::Object(item,copyop), _text(item._text) {} META_Object(osgUI, Tab); @@ -38,10 +36,6 @@ public: std::string& getText() { return _text; } const std::string& getText() const { return _text; } - void setColor(const osg::Vec4f& color) { _color = color; } - osg::Vec4f& getColor() { return _color; } - const osg::Vec4f& getColor() const { return _color; } - void setWidget(osgUI::Widget* widget) { _widget = widget; } osgUI::Widget* getWidget() { return _widget.get(); } const osgUI::Widget* getWidget() const { return _widget.get(); } @@ -50,7 +44,6 @@ protected: virtual ~Tab() {} std::string _text; - osg::Vec4 _color; osg::ref_ptr _widget; }; @@ -92,8 +85,14 @@ public: protected: virtual ~TabWidget() {} + void _activateWidgets(); + Tabs _tabs; unsigned int _currentIndex; + + osg::ref_ptr _unselectedHeaderSwitch; + osg::ref_ptr _selectedHeaderSwitch; + osg::ref_ptr _tabWidgetSwitch; }; } diff --git a/include/osgUI/Widget b/include/osgUI/Widget index dc285a993..6f6ec21a0 100644 --- a/include/osgUI/Widget +++ b/include/osgUI/Widget @@ -58,6 +58,14 @@ public: GraphicsSubgraphMap& getGraphicsSubgraphMap() { return _graphicsSubgraphMap; } const GraphicsSubgraphMap& getGraphicsSubgraphMap() const { return _graphicsSubgraphMap; } + /** Set the WidgetStateSet is used internally by Widgets to manage state that decorates the subgraph. + * WidgetStateSet is not serialized and is typically populated by teh Widget::createGraphics() implementation, + * end users will not normally touoch the WidgetStateSet, use the normal Node::setStateSet() if you want to apply + * your own state to the Widget and it's subgraphs.*/ + void setWidgetStateSet(osg::StateSet* stateset) { _widgetStateSet = stateset; } + osg::StateSet* getWidgetStateSet() { return _widgetStateSet.get(); } + const osg::StateSet* getWidgetStateSet() const { return _widgetStateSet.get(); } + osg::StateSet* getOrCreateWidgetStateSet() { if (!_widgetStateSet) _widgetStateSet = new osg::StateSet; return _widgetStateSet.get(); } /** createGraphics entry method, calls either callback object named "createGraphics" or the createGraphicsImplementation() method.*/ @@ -152,6 +160,7 @@ protected: bool _graphicsInitialized; GraphicsSubgraphMap _graphicsSubgraphMap; + osg::ref_ptr _widgetStateSet; osg::BoundingBoxf _extents; diff --git a/src/osgUI/ComboBox.cpp b/src/osgUI/ComboBox.cpp index 9088f299e..5dd1f70db 100644 --- a/src/osgUI/ComboBox.cpp +++ b/src/osgUI/ComboBox.cpp @@ -305,7 +305,7 @@ void ComboBox::createGraphicsImplementation() _buttonSwitch->setSingleChildOn(_currentIndex); - style->setupClipStateSet(_extents, getOrCreateStateSet()); + style->setupClipStateSet(_extents, getOrCreateWidgetStateSet()); setGraphicsSubgraph(0, group.get()); addChild(_popup.get()); diff --git a/src/osgUI/Dialog.cpp b/src/osgUI/Dialog.cpp index 6819f3723..e3ca38493 100644 --- a/src/osgUI/Dialog.cpp +++ b/src/osgUI/Dialog.cpp @@ -114,8 +114,8 @@ void Dialog::createGraphicsImplementation() titleLabel->getOrCreateUserDataContainer()->addUserObject(new osgUI::DragCallback); addChild(titleLabel.get()); - style->setupDialogStateSet(getOrCreateStateSet(), 5); - style->setupClipStateSet(dialogWithTitleExtents, getOrCreateStateSet()); + style->setupDialogStateSet(getOrCreateWidgetStateSet(), 5); + style->setupClipStateSet(dialogWithTitleExtents, getOrCreateWidgetStateSet()); // render before the subgraph setGraphicsSubgraph(-1, _group.get()); diff --git a/src/osgUI/Label.cpp b/src/osgUI/Label.cpp index aa1b3649b..e5d4274d9 100644 --- a/src/osgUI/Label.cpp +++ b/src/osgUI/Label.cpp @@ -37,6 +37,6 @@ void Label::createGraphicsImplementation() osg::ref_ptr node = style->createText(_extents, getAlignmentSettings(), getTextSettings(), _text); _textDrawable = dynamic_cast(node.get()); - style->setupClipStateSet(_extents, getOrCreateStateSet()); + style->setupClipStateSet(_extents, getOrCreateWidgetStateSet()); setGraphicsSubgraph(0, node.get()); } diff --git a/src/osgUI/LineEdit.cpp b/src/osgUI/LineEdit.cpp index d10f63512..217b77895 100644 --- a/src/osgUI/LineEdit.cpp +++ b/src/osgUI/LineEdit.cpp @@ -175,7 +175,7 @@ void LineEdit::createGraphicsImplementation() _textDrawable->setDataVariance(osg::Object::DYNAMIC); group->addChild(node.get()); - style->setupClipStateSet(_extents, getOrCreateStateSet()); + style->setupClipStateSet(_extents, getOrCreateWidgetStateSet()); setGraphicsSubgraph(0, group.get()); } diff --git a/src/osgUI/Popup.cpp b/src/osgUI/Popup.cpp index de01aab7b..fc9568cb8 100644 --- a/src/osgUI/Popup.cpp +++ b/src/osgUI/Popup.cpp @@ -77,11 +77,11 @@ void Popup::createGraphicsImplementation() bool requiresFrame = (getFrameSettings() && getFrameSettings()->getShape()!=osgUI::FrameSettings::NO_FRAME); if (requiresFrame) { _transform->addChild(style->createFrame(_extents, getFrameSettings(), dialogBackgroundColor)); } #if 1 - style->setupDialogStateSet(getOrCreateStateSet(),6); + style->setupDialogStateSet(getOrCreateWidgetStateSet(),6); #else - style->setupPopupStateSet(getOrCreateStateSet(),6); + style->setupPopupStateSet(getOrCreateWidgetStateSet(),6); #endif - style->setupClipStateSet(_extents, getOrCreateStateSet()); + style->setupClipStateSet(_extents, getOrCreateWidgetStateSet()); // render before the subgraph diff --git a/src/osgUI/PushButton.cpp b/src/osgUI/PushButton.cpp index c8ec36402..695f7bf1c 100644 --- a/src/osgUI/PushButton.cpp +++ b/src/osgUI/PushButton.cpp @@ -111,7 +111,7 @@ void PushButton::createGraphicsImplementation() group->addChild(_textDrawable.get()); - style->setupClipStateSet(_extents, getOrCreateStateSet()); + style->setupClipStateSet(_extents, getOrCreateWidgetStateSet()); setGraphicsSubgraph(0, group.get()); } diff --git a/src/osgUI/Style.cpp b/src/osgUI/Style.cpp index fcc91aabe..2b80ae4b7 100644 --- a/src/osgUI/Style.cpp +++ b/src/osgUI/Style.cpp @@ -438,6 +438,11 @@ void Style::setupClipStateSet(const osg::BoundingBox& extents, osg::StateSet* st osg::Matrixd matrix = osg::Matrixd::translate(osg::Vec3(-extents.xMin(), -extents.yMin(), -extents.zMin()))* osg::Matrixd::scale(osg::Vec3(1.0f/(extents.xMax()-extents.xMin()), 1.0f/(extents.yMax()-extents.yMin()), 1.0f)); + OSG_NOTICE<<"setupClipState(" + < texgen = new osg::TexGen; texgen->setPlanesFromMatrix(matrix); texgen->setMode(osg::TexGen::OBJECT_LINEAR); diff --git a/src/osgUI/TabWidget.cpp b/src/osgUI/TabWidget.cpp index 132e63a3e..196fae0ca 100644 --- a/src/osgUI/TabWidget.cpp +++ b/src/osgUI/TabWidget.cpp @@ -57,6 +57,7 @@ void TabWidget::setCurrentIndex(unsigned int i) if (_currentIndex==i) return; _currentIndex = i; + _activateWidgets(); currrentIndexChanged(_currentIndex); } @@ -85,4 +86,69 @@ void TabWidget::currentIndexChangedImplementation(unsigned int i) void TabWidget::createGraphicsImplementation() { + Style* style = (getStyle()!=0) ? getStyle() : Style::instance().get(); + + _unselectedHeaderSwitch = new osg::Switch; + _selectedHeaderSwitch = new osg::Switch; + _tabWidgetSwitch = new osg::Switch; + + float unselected = 0.92f; + float selected = 0.97f; + float titleHeight = 10.0f; + float characterWidth = titleHeight*0.5f; + float margin = titleHeight*0.1f; + float xPos = _extents.xMin(); + float yMin = _extents.yMax()-titleHeight; + float yMax = _extents.yMax(); + float zMin = _extents.zMin(); + float zMax = _extents.zMax(); + + for(Tabs::iterator itr = _tabs.begin(); + itr != _tabs.end(); + ++itr) + { + Tab* tab = itr->get(); + + float width = tab->getText().size() * characterWidth; + + osg::BoundingBox headerExtents( xPos, yMin, zMin, xPos+width, yMax, zMax); + + OSG_NOTICE<<"headerExtents = " + < text = style->createText(headerExtents, getAlignmentSettings(), getTextSettings(), tab->getText()); + osg::ref_ptr selected_panel = style->createPanel(headerExtents, osg::Vec4(unselected, unselected, unselected, 1.0f)); + osg::ref_ptr unselected_panel = style->createPanel(headerExtents, osg::Vec4(selected, selected, selected, 1.0f)); + + _selectedHeaderSwitch->addChild(selected_panel.get()); + _selectedHeaderSwitch->addChild(unselected_panel.get()); + _tabWidgetSwitch->addChild(tab->getWidget()); + + xPos += width+margin; + + } + + setGraphicsSubgraph(-3, _unselectedHeaderSwitch.get()); + setGraphicsSubgraph(-2, _selectedHeaderSwitch.get()); + setGraphicsSubgraph(-1, _tabWidgetSwitch.get()); + + _activateWidgets(); +} + +void TabWidget::_activateWidgets() +{ + if (_graphicsInitialized && _currentIndex<_tabs.size()) + { + OSG_NOTICE<<"Activating widget "<<_currentIndex<setAllChildrenOn(); + _unselectedHeaderSwitch->setValue(_currentIndex, false); + + _selectedHeaderSwitch->setAllChildrenOff(); + _selectedHeaderSwitch->setValue(_currentIndex, true); + + _tabWidgetSwitch->setAllChildrenOff(); + _tabWidgetSwitch->setValue(_currentIndex, true); + } } diff --git a/src/osgUI/Widget.cpp b/src/osgUI/Widget.cpp index 5bec327d7..c385a41fd 100644 --- a/src/osgUI/Widget.cpp +++ b/src/osgUI/Widget.cpp @@ -241,6 +241,9 @@ void Widget::traverseImplementation(osg::NodeVisitor& nv) else if (_visible || (nv.getVisitorType()!=osg::NodeVisitor::UPDATE_VISITOR && nv.getVisitorType()!=osg::NodeVisitor::CULL_VISITOR && nv.getVisitorType()!=osg::NodeVisitor::INTERSECTION_VISITOR) ) { + osgUtil::CullVisitor* cv = (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR) ? dynamic_cast(&nv) : 0; + if (cv && _widgetStateSet.valid()) cv->pushStateSet(_widgetStateSet.get()); + GraphicsSubgraphMap::iterator itr = _graphicsSubgraphMap.begin(); while(itr!= _graphicsSubgraphMap.end() && itr->first<=0) { @@ -255,6 +258,8 @@ void Widget::traverseImplementation(osg::NodeVisitor& nv) itr->second->accept(nv); ++itr; } + + if (cv && _widgetStateSet.valid()) cv->popStateSet(); } } diff --git a/src/osgWrappers/serializers/osgUI/Tab.cpp b/src/osgWrappers/serializers/osgUI/Tab.cpp index f5d8f3cdd..83ca76d4a 100644 --- a/src/osgWrappers/serializers/osgUI/Tab.cpp +++ b/src/osgWrappers/serializers/osgUI/Tab.cpp @@ -11,6 +11,5 @@ REGISTER_OBJECT_WRAPPER( Tab, "osg::Object osgUI::Tab" ) { ADD_STRING_SERIALIZER(Text, ""); - ADD_VEC4F_SERIALIZER(Color, osg::Vec4(1.0f,1.0f,1.0f,0.0f)); ADD_OBJECT_SERIALIZER(Widget, osgUI::Widget, NULL); } diff --git a/src/osgWrappers/serializers/osgUI/Widget.cpp b/src/osgWrappers/serializers/osgUI/Widget.cpp index 91d3b5c29..02ab639b8 100644 --- a/src/osgWrappers/serializers/osgUI/Widget.cpp +++ b/src/osgWrappers/serializers/osgUI/Widget.cpp @@ -70,6 +70,10 @@ REGISTER_OBJECT_WRAPPER( Widget, ADD_BOOL_SERIALIZER(HasEventFocus, false); ADD_MAP_SERIALIZER(GraphicsSubgraphMap, osgUI::Widget::GraphicsSubgraphMap, osgDB::BaseSerializer::RW_INT, osgDB::BaseSerializer::RW_OBJECT); + SET_USAGE( osgDB::BaseSerializer::GET_SET_PROPERTY); + + ADD_OBJECT_SERIALIZER( WidgetStateSet, osg::StateSet, NULL ); + SET_USAGE( osgDB::BaseSerializer::GET_SET_PROPERTY); ADD_BOUNDINGBOXF_SERIALIZER(Extents, osg::BoundingBoxf());