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
This commit is contained in:
Robert Osfield 2014-09-09 13:37:33 +00:00
parent 0db0bcdd5e
commit e93e7ca1f2
13 changed files with 107 additions and 20 deletions

View File

@ -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<osgUI::Widget> _widget;
};
@ -92,8 +85,14 @@ public:
protected:
virtual ~TabWidget() {}
void _activateWidgets();
Tabs _tabs;
unsigned int _currentIndex;
osg::ref_ptr<osg::Switch> _unselectedHeaderSwitch;
osg::ref_ptr<osg::Switch> _selectedHeaderSwitch;
osg::ref_ptr<osg::Switch> _tabWidgetSwitch;
};
}

View File

@ -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<osg::StateSet> _widgetStateSet;
osg::BoundingBoxf _extents;

View File

@ -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());

View File

@ -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());

View File

@ -37,6 +37,6 @@ void Label::createGraphicsImplementation()
osg::ref_ptr<Node> node = style->createText(_extents, getAlignmentSettings(), getTextSettings(), _text);
_textDrawable = dynamic_cast<osgText::Text*>(node.get());
style->setupClipStateSet(_extents, getOrCreateStateSet());
style->setupClipStateSet(_extents, getOrCreateWidgetStateSet());
setGraphicsSubgraph(0, node.get());
}

View File

@ -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());
}

View File

@ -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

View File

@ -111,7 +111,7 @@ void PushButton::createGraphicsImplementation()
group->addChild(_textDrawable.get());
style->setupClipStateSet(_extents, getOrCreateStateSet());
style->setupClipStateSet(_extents, getOrCreateWidgetStateSet());
setGraphicsSubgraph(0, group.get());
}

View File

@ -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("
<<extents.xMin()<<", "<<extents.yMin()<<", "<<extents.zMin()<<", "
<<extents.xMax()<<", "<<extents.yMax()<<", "<<extents.zMax()<<")"<<std::endl;
osg::ref_ptr<osg::TexGen> texgen = new osg::TexGen;
texgen->setPlanesFromMatrix(matrix);
texgen->setMode(osg::TexGen::OBJECT_LINEAR);

View File

@ -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 = "
<<headerExtents.xMin()<<", "<<headerExtents.yMin()<<", "<<headerExtents.zMin()<<", "
<<headerExtents.xMax()<<", "<<headerExtents.yMax()<<", "<<headerExtents.zMax()<<std::endl;
osg::ref_ptr<Node> text = style->createText(headerExtents, getAlignmentSettings(), getTextSettings(), tab->getText());
osg::ref_ptr<Node> selected_panel = style->createPanel(headerExtents, osg::Vec4(unselected, unselected, unselected, 1.0f));
osg::ref_ptr<Node> 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<<std::endl;
_unselectedHeaderSwitch->setAllChildrenOn();
_unselectedHeaderSwitch->setValue(_currentIndex, false);
_selectedHeaderSwitch->setAllChildrenOff();
_selectedHeaderSwitch->setValue(_currentIndex, true);
_tabWidgetSwitch->setAllChildrenOff();
_tabWidgetSwitch->setValue(_currentIndex, true);
}
}

View File

@ -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<osgUtil::CullVisitor*>(&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();
}
}

View File

@ -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);
}

View File

@ -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());