OpenSceneGraph/examples/osgwidgetmenu/osgwidgetmenu.cpp
Robert Osfield dd996a3289 Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods,
forcing users to use osgDB::readRef*File() methods.  The later is preferable as it closes a potential threading bug when using paging databases in conjunction
with the osgDB::Registry Object Cache.  This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only
a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another
thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero.  Using osgDB::readREf*File() makes sure the a ref_ptr<> is
passed back and the referenceCount never goes to zero.

To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File()
usage.  The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of
templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group:

    bool addChild(Node* child); // old method which can only be used with a Node*

    tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method

These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache
and multi-threaded loaded more robust.



git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15164 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 13:42:19 +00:00

129 lines
3.5 KiB
C++

// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
// $Id: osgwidgetmenu.cpp 66 2008-07-14 21:54:09Z cubicool $
#include <iostream>
#include <osgDB/ReadFile>
#include <osgWidget/Util>
#include <osgWidget/WindowManager>
#include <osgWidget/Box>
#include <osgWidget/Label>
// For now this is just an example, but osgWidget::Menu will later be it's own Window.
// I just wanted to get this out there so that people could see it was possible.
const unsigned int MASK_2D = 0xF0000000;
const unsigned int MASK_3D = 0x0F000000;
struct ColorLabel: public osgWidget::Label {
ColorLabel(const char* label):
osgWidget::Label("", "") {
setFont("fonts/Vera.ttf");
setFontSize(14);
setFontColor(1.0f, 1.0f, 1.0f, 1.0f);
setColor(0.3f, 0.3f, 0.3f, 1.0f);
addHeight(18.0f);
setCanFill(true);
setLabel(label);
setEventMask(osgWidget::EVENT_MOUSE_PUSH | osgWidget::EVENT_MASK_MOUSE_MOVE);
}
bool mousePush(double, double, const osgWidget::WindowManager*) {
return true;
}
bool mouseEnter(double, double, const osgWidget::WindowManager*) {
setColor(0.6f, 0.6f, 0.6f, 1.0f);
return true;
}
bool mouseLeave(double, double, const osgWidget::WindowManager*) {
setColor(0.3f, 0.3f, 0.3f, 1.0f);
return true;
}
};
class ColorLabelMenu: public ColorLabel {
osg::ref_ptr<osgWidget::Window> _window;
public:
ColorLabelMenu(const char* label):
ColorLabel(label) {
_window = new osgWidget::Box(
std::string("Menu_") + label,
osgWidget::Box::VERTICAL,
true
);
_window->addWidget(new ColorLabel("Open Some Stuff"));
_window->addWidget(new ColorLabel("Do It Now"));
_window->addWidget(new ColorLabel("Hello, How Are U?"));
_window->addWidget(new ColorLabel("Hmmm..."));
_window->addWidget(new ColorLabel("Option 5"));
_window->resize();
setColor(0.8f, 0.8f, 0.8f, 0.8f);
}
void managed(osgWidget::WindowManager* wm) {
osgWidget::Label::managed(wm);
wm->addChild(_window.get());
_window->hide();
}
void positioned() {
osgWidget::Label::positioned();
_window->setOrigin(getX(), getHeight());
_window->resize(getWidth());
}
bool mousePush(double, double, const osgWidget::WindowManager*) {
if(!_window->isVisible()) _window->show();
else _window->hide();
return true;
}
bool mouseLeave(double, double, const osgWidget::WindowManager*) {
if(!_window->isVisible()) setColor(0.8f, 0.8f, 0.8f, 0.8f);
return true;
}
};
int main(int argc, char** argv) {
osgViewer::Viewer viewer;
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D,
osgWidget::WindowManager::WM_PICK_DEBUG
);
osgWidget::Window* menu = new osgWidget::Box("menu", osgWidget::Box::HORIZONTAL);
menu->addWidget(new ColorLabelMenu("Pick me!"));
menu->addWidget(new ColorLabelMenu("No, wait, pick me!"));
menu->addWidget(new ColorLabelMenu("Don't pick them..."));
menu->addWidget(new ColorLabelMenu("Grarar!?!"));
wm->addChild(menu);
menu->getBackground()->setColor(1.0f, 1.0f, 1.0f, 0.0f);
menu->resizePercent(100.0f);
osg::ref_ptr<osg::Node> model = osgDB::readRefNodeFile("osgcool.osgt");
model->setNodeMask(MASK_3D);
return osgWidget::createExample(viewer, wm, model.get());
}