osgviewerGtkmm/osgviewerGtkmm.cpp
This example illustrates how to use ViewerGtkmm and GraphicsWindowGtkmm to display an OSG scenegraph in a Gtk-- application. Additionally, this example incorporates several Gtk-- widgets to demonstrate several aspects of ViewerGtkmm control as well as how to connect your own functions to GraphicsWindowGtkmm mouse events.
#include <gtkmm.h>
#include <osgDB/ReadFile>
#include <osgGA/TrackballManipulator>
#include <osgGtkmm/ViewerGtkmm.h>
const char* HELP_TEXT =
"<b><i>Right-click</i></b> while holding <b><i>CTRL</i></b> <u>or</u> <b><i>SHIFT</i></b> to pop up a fake Gtkmm menu.\n"
"\n"
"Use the standard OSG TrackballManipulator keys and mouse actions to\n"
"rotate, zoom and move the loaded model.\n"
"\n"
"<i>Note:\n"
"<small>\tIf the viewer is stopped, user actions won't be processed until the viewer is restarted.\n"
"\tIn this example events are only processed when the viewer is running.</small></i>\n"
;
osgViewer::ViewerGtkmm* viewer = NULL;
Gtk::ToggleButton* fps_button;
bool on_button_event(GdkEventButton* event);
void on_open_file_clicked();
void on_run_frames_button_clicked();
void on_fps_toggled();
int main( int argc, char** argv )
{
int width=800, height=600;
Gtk::Main gtkmm_main( argc, argv );
Gtk::GL::init( argc, argv );
viewer = new osgViewer::ViewerGtkmm();
viewer->setCameraManipulator(new osgGA::TrackballManipulator);
viewer->set_fps(60);
if ( argc >= 2 ) {
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile(argv[1]);
if ( model.valid() ) viewer->setSceneData(model.get());
}
osgViewer::GraphicsWindowGtkmm* gw = viewer->setup_viewer_in_gtkmm_window(width, height);
Gtk::Window window(Gtk::WINDOW_TOPLEVEL);
window.set_title("osgviewerGtkmm");
Gtk::VBox main_vbox;
Gtk::HBox bottom_hbox;
Gtk::VBox button_vbox;
Gtk::Label help_text(HELP_TEXT);
Gtk::Button file_button("Open File");
Gtk::Button run_frames_button("Run 120 frames");
Gtk::Button close_button("Close");
fps_button = Gtk::manage(new Gtk::ToggleButton());
window.add(main_vbox);
main_vbox.pack_start(*gw);
main_vbox.pack_start(bottom_hbox);
bottom_hbox.pack_start(button_vbox);
help_text.set_use_markup();
bottom_hbox.pack_start(help_text);
button_vbox.pack_start(file_button);
button_vbox.pack_start(run_frames_button);
button_vbox.pack_start(*fps_button);
button_vbox.pack_start(close_button);
window.show_all();
gw->signal_button_press_event().connect(&on_button_event);
gw->signal_button_release_event().connect(&on_button_event);
file_button.signal_clicked().connect(&on_open_file_clicked);
run_frames_button.signal_clicked().connect(&on_run_frames_button_clicked);
fps_button->signal_toggled().connect(&on_fps_toggled);
close_button.signal_clicked().connect(&Gtk::Main::quit);
fps_button->set_active(true);
Gtk::Main::run(window);
return 0;
}
bool on_button_event(GdkEventButton* event)
{
if ( event->button == 3 and ( event->state & GDK_SHIFT_MASK or event->state & GDK_CONTROL_MASK ) )
{
if ( event->type == GDK_BUTTON_RELEASE )
{
Gtk::Menu* menu = Gtk::manage(new Gtk::Menu());
menu->append(*Gtk::manage(new Gtk::MenuItem("Option")));
menu->append(*Gtk::manage(new Gtk::MenuItem("Another Option")));
menu->append(*Gtk::manage(new Gtk::MenuItem("Still More Options")));
menu->show_all();
menu->popup(event->button, event->time);
}
return true;
}
return false;
}
void on_open_file_clicked()
{
Gtk::FileChooserDialog fc("Please select an OSG file to load...",
Gtk::FILE_CHOOSER_ACTION_OPEN);
fc.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
fc.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
if ( fc.run() == Gtk::RESPONSE_ACCEPT )
{
Glib::ustring file = fc.get_filename();
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile(file);
if ( model.valid() )
viewer->setSceneData(model.get());
}
}
void on_run_frames_button_clicked()
{
fps_button->set_active(false);
if ( viewer ) viewer->run_frames(120);
}
void on_fps_toggled()
{
if ( fps_button->get_active() )
{
if ( viewer ) viewer->run();
fps_button->set_label("Click to stop");
}
else
{
if ( viewer ) viewer->stop();
fps_button->set_label("Click to run at 60fps");
}
}