From Jeremy Moles, fixed window resize problem

This commit is contained in:
Robert Osfield
2008-05-09 10:27:59 +00:00
parent f733bf17e9
commit 01f58ffbb2
3 changed files with 392 additions and 394 deletions

View File

@@ -1,5 +1,3 @@
// by: Jeremy Moles <jeremy@emperorlinux.com> 2007
#include "osggtkdrawingarea.h"
OSGGTKDrawingArea::OSGGTKDrawingArea():
@@ -9,140 +7,142 @@ _context (0),
_drawable (0),
_state (0),
_queue (*getEventQueue()) {
setCameraManipulator(new osgGA::TrackballManipulator());
setCameraManipulator(new osgGA::TrackballManipulator());
}
OSGGTKDrawingArea::~OSGGTKDrawingArea() {
}
bool OSGGTKDrawingArea::createWidget(int width, int height) {
_glconfig = gdk_gl_config_new_by_mode(static_cast<GdkGLConfigMode>(
GDK_GL_MODE_RGBA |
GDK_GL_MODE_DEPTH |
GDK_GL_MODE_DOUBLE
));
_glconfig = gdk_gl_config_new_by_mode(static_cast<GdkGLConfigMode>(
GDK_GL_MODE_RGBA |
GDK_GL_MODE_DEPTH |
GDK_GL_MODE_DOUBLE
));
if(not _glconfig) {
osg::notify(osg::FATAL) << "Fail!" << std::endl;
if(not _glconfig) {
osg::notify(osg::FATAL) << "Fail!" << std::endl;
return false;
}
return false;
}
gtk_widget_set_size_request(_widget, width, height);
gtk_widget_set_size_request(_widget, width, height);
gtk_widget_set_gl_capability(
_widget,
_glconfig,
0,
true,
GDK_GL_RGBA_TYPE
);
gtk_widget_set_gl_capability(
_widget,
_glconfig,
0,
true,
GDK_GL_RGBA_TYPE
);
gtk_widget_add_events(
_widget,
GDK_BUTTON1_MOTION_MASK |
GDK_BUTTON2_MOTION_MASK |
GDK_BUTTON3_MOTION_MASK |
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_VISIBILITY_NOTIFY_MASK
);
gtk_widget_add_events(
_widget,
GDK_BUTTON1_MOTION_MASK |
GDK_BUTTON2_MOTION_MASK |
GDK_BUTTON3_MOTION_MASK |
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK |
GDK_VISIBILITY_NOTIFY_MASK
);
// We do this so that we don't have to suck up ALL the input to the
// window, but instead just when the drawing area is focused.
g_object_set(_widget, "can-focus", true, NULL);
// We do this so that we don't have to suck up ALL the input to the
// window, but instead just when the drawing area is focused.
g_object_set(_widget, "can-focus", true, NULL);
_connect("realize", G_CALLBACK(&OSGGTKDrawingArea::_srealize));
_connect("unrealize", G_CALLBACK(&OSGGTKDrawingArea::_sunrealize));
_connect("expose_event", G_CALLBACK(&OSGGTKDrawingArea::_sexpose_event));
_connect("configure_event", G_CALLBACK(&OSGGTKDrawingArea::_sconfigure_event));
_connect("motion_notify_event", G_CALLBACK(&OSGGTKDrawingArea::_smotion_notify_event));
_connect("button_press_event", G_CALLBACK(&OSGGTKDrawingArea::_sbutton_press_event));
_connect("button_release_event", G_CALLBACK(&OSGGTKDrawingArea::_sbutton_press_event));
_connect("key_press_event", G_CALLBACK(&OSGGTKDrawingArea::_skey_press_event));
_connect("realize", G_CALLBACK(&OSGGTKDrawingArea::_srealize));
_connect("unrealize", G_CALLBACK(&OSGGTKDrawingArea::_sunrealize));
_connect("expose_event", G_CALLBACK(&OSGGTKDrawingArea::_sexpose_event));
_connect("configure_event", G_CALLBACK(&OSGGTKDrawingArea::_sconfigure_event));
_connect("motion_notify_event", G_CALLBACK(&OSGGTKDrawingArea::_smotion_notify_event));
_connect("button_press_event", G_CALLBACK(&OSGGTKDrawingArea::_sbutton_press_event));
_connect("button_release_event", G_CALLBACK(&OSGGTKDrawingArea::_sbutton_press_event));
_connect("key_press_event", G_CALLBACK(&OSGGTKDrawingArea::_skey_press_event));
setUpViewerAsEmbeddedInWindow(0, 0, width, height);
_gw = setUpViewerAsEmbeddedInWindow(0, 0, width, height);
return true;
return true;
}
void OSGGTKDrawingArea::_realize(GtkWidget* widget) {
_context = gtk_widget_get_gl_context(widget);
_drawable = gtk_widget_get_gl_drawable(widget);
_context = gtk_widget_get_gl_context(widget);
_drawable = gtk_widget_get_gl_drawable(widget);
gtkRealize();
gtkRealize();
}
void OSGGTKDrawingArea::_unrealize(GtkWidget* widget) {
gtkUnrealize();
gtkUnrealize();
}
bool OSGGTKDrawingArea::_expose_event(GtkWidget* widget, GdkEventExpose* event) {
if(not gtkGLBegin()) return false;
if(not gtkGLBegin()) return false;
frame();
frame();
gtkGLSwap();
gtkGLEnd();
gtkGLSwap();
gtkGLEnd();
return gtkExpose();
return gtkExpose();
}
bool OSGGTKDrawingArea::_configure_event(GtkWidget* widget, GdkEventConfigure* event) {
gtkGLBegin();
gtkGLBegin();
_queue.windowResize(0, 0, event->width, event->height);
_queue.windowResize(0, 0, event->width, event->height);
gtkGLEnd();
_gw->resized(0, 0, event->width, event->height);
return gtkConfigure(event->width, event->height);
gtkGLEnd();
return gtkConfigure(event->width, event->height);
}
bool OSGGTKDrawingArea::_motion_notify_event(GtkWidget* widget, GdkEventMotion* event) {
_state = event->state;
_state = event->state;
_queue.mouseMotion(event->x, event->y);
_queue.mouseMotion(event->x, event->y);
return gtkMotionNotify(event->x, event->y);
return gtkMotionNotify(event->x, event->y);
}
bool OSGGTKDrawingArea::_button_press_event(GtkWidget* widget, GdkEventButton* event) {
_state = event->state;
_state = event->state;
if(event->type == GDK_BUTTON_PRESS) {
if(event->button == 1) gtk_widget_grab_focus(_widget);
if(event->type == GDK_BUTTON_PRESS) {
if(event->button == 1) gtk_widget_grab_focus(_widget);
_queue.mouseButtonPress(event->x, event->y, event->button);
_queue.mouseButtonPress(event->x, event->y, event->button);
return gtkButtonPress(event->x, event->y, event->button);
}
return gtkButtonPress(event->x, event->y, event->button);
}
else if(event->type == GDK_BUTTON_RELEASE) {
_queue.mouseButtonRelease(event->x, event->y, event->button);
else if(event->type == GDK_BUTTON_RELEASE) {
_queue.mouseButtonRelease(event->x, event->y, event->button);
return gtkButtonRelease(event->x, event->y, event->button);
}
return gtkButtonRelease(event->x, event->y, event->button);
}
else return false;
else return false;
}
bool OSGGTKDrawingArea::_key_press_event(GtkWidget* widget, GdkEventKey* event) {
_state = event->state;
_state = event->state;
if(event->type == GDK_KEY_PRESS) {
_queue.keyPress(event->keyval);
if(event->type == GDK_KEY_PRESS) {
_queue.keyPress(event->keyval);
return gtkKeyPress(event->keyval);
}
return gtkKeyPress(event->keyval);
}
else if(event->type == GDK_KEY_RELEASE) {
_queue.keyRelease(event->keyval);
else if(event->type == GDK_KEY_RELEASE) {
_queue.keyRelease(event->keyval);
return gtkKeyRelease(event->keyval);
}
return gtkKeyRelease(event->keyval);
}
else return false;
else return false;
}

View File

@@ -1,5 +1,3 @@
// by: Jeremy Moles <jeremy@emperorlinux.com> 2007
#include <gtk/gtk.h>
#include <gtk/gtkgl.h>
#include <osgViewer/Viewer>
@@ -15,193 +13,195 @@
// interesting without calls to queueDraw, which ideally are done in the user's
// subclass implementation (see: osgviewerGTK).
class OSGGTKDrawingArea : public osgViewer::Viewer {
GtkWidget* _widget;
GdkGLConfig* _glconfig;
GdkGLContext* _context;
GdkGLDrawable* _drawable;
GtkWidget* _widget;
GdkGLConfig* _glconfig;
GdkGLContext* _context;
GdkGLDrawable* _drawable;
osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw;
unsigned int _state;
unsigned int _state;
osgGA::EventQueue& _queue;
osgGA::EventQueue& _queue;
static OSGGTKDrawingArea* _self(gpointer self) {
return static_cast<OSGGTKDrawingArea*>(self);
}
static OSGGTKDrawingArea* _self(gpointer self) {
return static_cast<OSGGTKDrawingArea*>(self);
}
// A simple helper function to connect us to the various GTK signals.
void _connect(const char* name, GCallback callback) {
g_signal_connect(G_OBJECT(_widget), name, callback, this);
}
// A simple helper function to connect us to the various GTK signals.
void _connect(const char* name, GCallback callback) {
g_signal_connect(G_OBJECT(_widget), name, callback, this);
}
void _realize (GtkWidget*);
void _unrealize (GtkWidget*);
bool _expose_event (GtkWidget*, GdkEventExpose*);
bool _configure_event (GtkWidget*, GdkEventConfigure*);
bool _motion_notify_event (GtkWidget*, GdkEventMotion*);
bool _button_press_event (GtkWidget*, GdkEventButton*);
bool _key_press_event (GtkWidget*, GdkEventKey*);
void _realize (GtkWidget*);
void _unrealize (GtkWidget*);
bool _expose_event (GtkWidget*, GdkEventExpose*);
bool _configure_event (GtkWidget*, GdkEventConfigure*);
bool _motion_notify_event (GtkWidget*, GdkEventMotion*);
bool _button_press_event (GtkWidget*, GdkEventButton*);
bool _key_press_event (GtkWidget*, GdkEventKey*);
// The following functions are static "wrappers" so that we can invoke the
// bound methods of a class instance by passing the "this" pointer as the
// self argument and invoking it explicitly.
static void _srealize(GtkWidget* widget, gpointer self) {
_self(self)->_realize(widget);
}
// The following functions are static "wrappers" so that we can invoke the
// bound methods of a class instance by passing the "this" pointer as the
// self argument and invoking it explicitly.
static void _srealize(GtkWidget* widget, gpointer self) {
_self(self)->_realize(widget);
}
static void _sunrealize(GtkWidget* widget, gpointer self) {
_self(self)->_unrealize(widget);
}
static void _sunrealize(GtkWidget* widget, gpointer self) {
_self(self)->_unrealize(widget);
}
static bool _sexpose_event(GtkWidget* widget, GdkEventExpose* expose, gpointer self) {
return _self(self)->_expose_event(widget, expose);
}
static bool _sexpose_event(GtkWidget* widget, GdkEventExpose* expose, gpointer self) {
return _self(self)->_expose_event(widget, expose);
}
static bool _sconfigure_event(
GtkWidget* widget,
GdkEventConfigure* event,
gpointer self
) {
return _self(self)->_configure_event(widget, event);
}
static bool _sconfigure_event(
GtkWidget* widget,
GdkEventConfigure* event,
gpointer self
) {
return _self(self)->_configure_event(widget, event);
}
static bool _smotion_notify_event(
GtkWidget* widget,
GdkEventMotion* event,
gpointer self
) {
return _self(self)->_motion_notify_event(widget, event);
}
static bool _smotion_notify_event(
GtkWidget* widget,
GdkEventMotion* event,
gpointer self
) {
return _self(self)->_motion_notify_event(widget, event);
}
static bool _sbutton_press_event(
GtkWidget* widget,
GdkEventButton* event,
gpointer self
) {
return _self(self)->_button_press_event(widget, event);
}
static bool _sbutton_press_event(
GtkWidget* widget,
GdkEventButton* event,
gpointer self
) {
return _self(self)->_button_press_event(widget, event);
}
static bool _skey_press_event(
GtkWidget* widget,
GdkEventKey* event,
gpointer self
) {
return _self(self)->_key_press_event(widget, event);
}
static bool _skey_press_event(
GtkWidget* widget,
GdkEventKey* event,
gpointer self
) {
return _self(self)->_key_press_event(widget, event);
}
protected:
// You can override these in your subclass if you'd like. :)
// Right now they're fairly uninformative, but they could be easily extended.
// Note that the "state" information isn't passed around to each function
// but is instead stored and abstracted internally. See below.
// You can override these in your subclass if you'd like. :)
// Right now they're fairly uninformative, but they could be easily extended.
// Note that the "state" information isn't passed around to each function
// but is instead stored and abstracted internally. See below.
virtual void gtkRealize () {};
virtual void gtkUnrealize () {};
virtual bool gtkExpose () {
return true;
};
virtual void gtkRealize () {};
virtual void gtkUnrealize () {};
virtual bool gtkExpose () {
return true;
};
// The new width and height.
virtual bool gtkConfigure(int, int) {
return true;
};
// The new width and height.
virtual bool gtkConfigure(int, int) {
return true;
};
// The "normalized" coordinates of the mouse.
virtual bool gtkMotionNotify(double, double) {
return true;
};
// The "normalized" coordinates of the mouse.
virtual bool gtkMotionNotify(double, double) {
return true;
};
// The "normalized" coordinates of the mouse and the mouse button code on down.
virtual bool gtkButtonPress(double, double, unsigned int) {
return true;
};
// The "normalized" coordinates of the mouse and the mouse button code on down.
virtual bool gtkButtonPress(double, double, unsigned int) {
return true;
};
// The "normalized" coordinates of the mouse and mouse button code on release.
virtual bool gtkButtonRelease(double, double, unsigned int) {
return true;
}
// The "normalized" coordinates of the mouse and mouse button code on release.
virtual bool gtkButtonRelease(double, double, unsigned int) {
return true;
}
// The X key value on down.
virtual bool gtkKeyPress(unsigned int) {
return true;
};
// The X key value on down.
virtual bool gtkKeyPress(unsigned int) {
return true;
};
// The X key value on release.
virtual bool gtkKeyRelease(unsigned int) {
return true;
};
// The X key value on release.
virtual bool gtkKeyRelease(unsigned int) {
return true;
};
// These functions wrap state tests of the most recent state in the
// GtkDrawingArea.
// These functions wrap state tests of the most recent state in the
// GtkDrawingArea.
inline bool stateShift() {
return _state & GDK_SHIFT_MASK;
}
inline bool stateShift() {
return _state & GDK_SHIFT_MASK;
}
inline bool stateLock() {
return _state & GDK_LOCK_MASK;
}
inline bool stateLock() {
return _state & GDK_LOCK_MASK;
}
inline bool stateControl() {
return _state & GDK_CONTROL_MASK;
}
inline bool stateControl() {
return _state & GDK_CONTROL_MASK;
}
inline bool stateMod() {
return _state & (
GDK_MOD1_MASK |
GDK_MOD2_MASK |
GDK_MOD3_MASK |
GDK_MOD4_MASK |
GDK_MOD5_MASK
);
}
inline bool stateMod() {
return _state & (
GDK_MOD1_MASK |
GDK_MOD2_MASK |
GDK_MOD3_MASK |
GDK_MOD4_MASK |
GDK_MOD5_MASK
);
}
inline bool stateButton() {
return _state & (
GDK_BUTTON1_MASK |
GDK_BUTTON2_MASK |
GDK_BUTTON3_MASK |
GDK_BUTTON4_MASK |
GDK_BUTTON5_MASK
);
}
inline bool stateButton() {
return _state & (
GDK_BUTTON1_MASK |
GDK_BUTTON2_MASK |
GDK_BUTTON3_MASK |
GDK_BUTTON4_MASK |
GDK_BUTTON5_MASK
);
}
public:
OSGGTKDrawingArea ();
~OSGGTKDrawingArea ();
OSGGTKDrawingArea ();
~OSGGTKDrawingArea ();
bool createWidget(int, int);
bool createWidget(int, int);
GtkWidget* getWidget() {
return _widget;
}
GtkWidget* getWidget() {
return _widget;
}
bool gtkGLBegin() {
if(_drawable and _context) return gdk_gl_drawable_gl_begin(_drawable, _context);
bool gtkGLBegin() {
if(_drawable and _context) return gdk_gl_drawable_gl_begin(_drawable, _context);
else return false;
}
else return false;
}
void gtkGLEnd() {
if(_drawable) gdk_gl_drawable_gl_end(_drawable);
}
void gtkGLEnd() {
if(_drawable) gdk_gl_drawable_gl_end(_drawable);
}
// Because of GTK's internal double buffering, I'm not sure if we're really
// taking advantage of OpenGL's internal swapping.
bool gtkGLSwap() {
if(_drawable and gdk_gl_drawable_is_double_buffered(_drawable)) {
gdk_gl_drawable_swap_buffers(_drawable);
// Because of GTK's internal double buffering, I'm not sure if we're really
// taking advantage of OpenGL's internal swapping.
bool gtkGLSwap() {
if(_drawable and gdk_gl_drawable_is_double_buffered(_drawable)) {
gdk_gl_drawable_swap_buffers(_drawable);
return true;
}
return true;
}
else {
glFlush();
else {
glFlush();
return false;
}
}
return false;
}
}
void queueDraw() {
gtk_widget_queue_draw(_widget);
}
void queueDraw() {
gtk_widget_queue_draw(_widget);
}
};

View File

@@ -1,5 +1,3 @@
// by: Jeremy Moles <jeremy@emperorlinux.com> 2007
#include <iostream>
#include <string>
#include <osg/Stats>
@@ -8,22 +6,22 @@
#include "osggtkdrawingarea.h"
const char* HELP_TEXT =
"Use CTRL or SHIFT plus right-click to pull up a fake menu.\n"
"Use the standard TrackballManipulator keys to rotate the loaded\n"
"model (with caveats; the model won't keep rotating).\n"
"\n"
"<b>OpenSceneGraph Project, 2008</b>"
"Use CTRL or SHIFT plus right-click to pull up a fake menu.\n"
"Use the standard TrackballManipulator keys to rotate the loaded\n"
"model (with caveats; the model won't keep rotating).\n"
"\n"
"<b>OpenSceneGraph Project, 2008</b>"
;
// If you want to see how to connect class method to callbacks, take a look at the
// implementation of OSGGTKDrawingArea. It's dirty, but it's the only way I could
// come up with.
bool activate(GtkWidget* widget, gpointer) {
GtkWidget* label = gtk_bin_get_child(GTK_BIN(widget));
GtkWidget* label = gtk_bin_get_child(GTK_BIN(widget));
std::cout << "MENU: " << gtk_label_get_label(GTK_LABEL(label)) << std::endl;
std::cout << "MENU: " << gtk_label_get_label(GTK_LABEL(label)) << std::endl;
return true;
return true;
}
// Our derived OSGGTKDrawingArea "widget." Redraws occur while the mouse buttons
@@ -34,201 +32,201 @@ bool activate(GtkWidget* widget, gpointer) {
// unmodified OSGGTKDrawingArea never calls queueDraw, so OSG is never asked to render
// itself.
class ExampleOSGGTKDrawingArea : public OSGGTKDrawingArea {
GtkWidget* _menu;
unsigned int _tid;
GtkWidget* _menu;
unsigned int _tid;
// A helper function to easily setup our menu entries.
void _menuAdd(const std::string& title) {
GtkWidget* item = gtk_menu_item_new_with_label(title.c_str());
gtk_menu_shell_append(GTK_MENU_SHELL(_menu), item);
// A helper function to easily setup our menu entries.
void _menuAdd(const std::string& title) {
GtkWidget* item = gtk_menu_item_new_with_label(title.c_str());
gtk_menu_shell_append(GTK_MENU_SHELL(_menu), item);
g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(activate), 0);
}
g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(activate), 0);
}
bool _clicked(GtkWidget* widget) {
const char* text = gtk_label_get_label(
GTK_LABEL(gtk_bin_get_child(GTK_BIN(widget)))
);
bool _clicked(GtkWidget* widget) {
const char* text = gtk_label_get_label(
GTK_LABEL(gtk_bin_get_child(GTK_BIN(widget)))
);
if(not std::strncmp(text, "Close", 5)) gtk_main_quit();
else if(not std::strncmp(text, "Open File", 9)) {
GtkWidget* of = gtk_file_chooser_dialog_new(
"Please select an OSG file...",
GTK_WINDOW(gtk_widget_get_toplevel(getWidget())),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN,
GTK_RESPONSE_ACCEPT,
NULL
);
if(not std::strncmp(text, "Close", 5)) gtk_main_quit();
else if(not std::strncmp(text, "Open File", 9)) {
GtkWidget* of = gtk_file_chooser_dialog_new(
"Please select an OSG file...",
GTK_WINDOW(gtk_widget_get_toplevel(getWidget())),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN,
GTK_RESPONSE_ACCEPT,
NULL
);
if(gtk_dialog_run(GTK_DIALOG(of)) == GTK_RESPONSE_ACCEPT) {
char* file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(of));
if(gtk_dialog_run(GTK_DIALOG(of)) == GTK_RESPONSE_ACCEPT) {
char* file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(of));
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile(file);
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile(file);
if(model.valid()) {
setSceneData(model.get());
queueDraw();
}
if(model.valid()) {
setSceneData(model.get());
queueDraw();
}
g_free(file);
}
gtk_widget_destroy(of);
}
g_free(file);
}
gtk_widget_destroy(of);
}
// Assume we're wanting FPS toggling.
else {
if(not _tid) {
_tid = g_timeout_add(
15,
(GSourceFunc)(ExampleOSGGTKDrawingArea::timeout),
this
);
// Assume we're wanting FPS toggling.
else {
if(not _tid) {
_tid = g_timeout_add(
15,
(GSourceFunc)(ExampleOSGGTKDrawingArea::timeout),
this
);
gtk_button_set_label(GTK_BUTTON(widget), "Toggle 60 FPS (off)");
}
gtk_button_set_label(GTK_BUTTON(widget), "Toggle 60 FPS (off)");
}
else {
g_source_remove(_tid);
gtk_button_set_label(GTK_BUTTON(widget), "Toggle 60 FPS (on)");
else {
g_source_remove(_tid);
gtk_button_set_label(GTK_BUTTON(widget), "Toggle 60 FPS (on)");
_tid = 0;
}
}
_tid = 0;
}
}
return true;
}
return true;
}
protected:
// Check right-click release to see if we need to popup our menu.
bool gtkButtonRelease(double, double, unsigned int button) {
if(button == 3 and (stateControl() or stateShift())) gtk_menu_popup(
GTK_MENU(_menu),
0,
0,
0,
0,
button,
0
);
// Check right-click release to see if we need to popup our menu.
bool gtkButtonRelease(double, double, unsigned int button) {
if(button == 3 and (stateControl() or stateShift())) gtk_menu_popup(
GTK_MENU(_menu),
0,
0,
0,
0,
button,
0
);
return true;
}
return true;
}
// Our "main" drawing pump. Since our app is just a model viewer, we use
// click+motion as our criteria for issuing OpenGL refreshes.
bool gtkMotionNotify(double, double) {
if(stateButton()) queueDraw();
// Our "main" drawing pump. Since our app is just a model viewer, we use
// click+motion as our criteria for issuing OpenGL refreshes.
bool gtkMotionNotify(double, double) {
if(stateButton()) queueDraw();
return true;
}
return true;
}
public:
ExampleOSGGTKDrawingArea():
OSGGTKDrawingArea (),
_menu (gtk_menu_new()),
_tid (0) {
_menuAdd("Option");
_menuAdd("Another Option");
_menuAdd("Still More Options");
ExampleOSGGTKDrawingArea():
OSGGTKDrawingArea (),
_menu (gtk_menu_new()),
_tid (0) {
_menuAdd("Option");
_menuAdd("Another Option");
_menuAdd("Still More Options");
gtk_widget_show_all(_menu);
gtk_widget_show_all(_menu);
getCamera()->setStats(new osg::Stats("omg"));
}
getCamera()->setStats(new osg::Stats("omg"));
}
~ExampleOSGGTKDrawingArea() {}
~ExampleOSGGTKDrawingArea() {}
// Public so that we can use this as a callback in main().
static bool clicked(GtkWidget* widget, gpointer self) {
return static_cast<ExampleOSGGTKDrawingArea*>(self)->_clicked(widget);
}
// Public so that we can use this as a callback in main().
static bool clicked(GtkWidget* widget, gpointer self) {
return static_cast<ExampleOSGGTKDrawingArea*>(self)->_clicked(widget);
}
//static gboolean timeout(GtkWidget* widget) {
static bool timeout(void* self) {
static_cast<ExampleOSGGTKDrawingArea*>(self)->queueDraw();
//static gboolean timeout(GtkWidget* widget) {
static bool timeout(void* self) {
static_cast<ExampleOSGGTKDrawingArea*>(self)->queueDraw();
return true;
}
return true;
}
};
// Our main() function! FINALLY! Most of this code is GTK stuff, so it's mostly boilerplate.
// If we wanted to get real jiggy with it we could use Glade and cut down about 20 lines of
// code or so.
int main(int argc, char** argv) {
gtk_init(&argc, &argv);
gtk_gl_init(&argc, &argv);
gtk_init(&argc, &argv);
gtk_gl_init(&argc, &argv);
ExampleOSGGTKDrawingArea da;
ExampleOSGGTKDrawingArea da;
if(da.createWidget(640, 480)) {
if(argc >= 2) {
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile(argv[1]);
if(da.createWidget(640, 480)) {
if(argc >= 2) {
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile(argv[1]);
if(model.valid()) da.setSceneData(model.get());
}
if(model.valid()) da.setSceneData(model.get());
}
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget* vbox1 = gtk_vbox_new(false, 3);
GtkWidget* vbox2 = gtk_vbox_new(false, 3);
GtkWidget* hbox = gtk_hbox_new(false, 3);
GtkWidget* label = gtk_label_new("");
GtkWidget* buttons[] = {
gtk_button_new_with_label("Open File"),
gtk_button_new_with_label("Toggle 60 FPS (on)"),
gtk_button_new_with_label("Close")
};
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget* vbox1 = gtk_vbox_new(false, 3);
GtkWidget* vbox2 = gtk_vbox_new(false, 3);
GtkWidget* hbox = gtk_hbox_new(false, 3);
GtkWidget* label = gtk_label_new("");
GtkWidget* buttons[] = {
gtk_button_new_with_label("Open File"),
gtk_button_new_with_label("Toggle 60 FPS (on)"),
gtk_button_new_with_label("Close")
};
gtk_label_set_use_markup(GTK_LABEL(label), true);
gtk_label_set_label(GTK_LABEL(label), HELP_TEXT);
gtk_label_set_use_markup(GTK_LABEL(label), true);
gtk_label_set_label(GTK_LABEL(label), HELP_TEXT);
for(unsigned int i = 0; i < sizeof(buttons) / sizeof(GtkWidget*); i++) {
gtk_box_pack_start(
GTK_BOX(vbox2),
buttons[i],
false,
false,
0
);
for(unsigned int i = 0; i < sizeof(buttons) / sizeof(GtkWidget*); i++) {
gtk_box_pack_start(
GTK_BOX(vbox2),
buttons[i],
false,
false,
0
);
g_signal_connect(
G_OBJECT(buttons[i]),
"clicked",
G_CALLBACK(ExampleOSGGTKDrawingArea::clicked),
&da
);
}
g_signal_connect(
G_OBJECT(buttons[i]),
"clicked",
G_CALLBACK(ExampleOSGGTKDrawingArea::clicked),
&da
);
}
gtk_window_set_title(GTK_WINDOW(window), "osgviewerGTK");
gtk_window_set_title(GTK_WINDOW(window), "osgviewerGTK");
gtk_box_pack_start(GTK_BOX(hbox), vbox2, true, true, 2);
gtk_box_pack_start(GTK_BOX(hbox), label, true, true, 2);
gtk_box_pack_start(GTK_BOX(hbox), vbox2, true, true, 2);
gtk_box_pack_start(GTK_BOX(hbox), label, true, true, 2);
gtk_box_pack_start(GTK_BOX(vbox1), da.getWidget(), true, true, 2);
gtk_box_pack_start(GTK_BOX(vbox1), hbox, false, false, 2);
gtk_box_pack_start(GTK_BOX(vbox1), da.getWidget(), true, true, 2);
gtk_box_pack_start(GTK_BOX(vbox1), hbox, false, false, 2);
gtk_container_set_reallocate_redraws(GTK_CONTAINER(window), true);
gtk_container_add(GTK_CONTAINER(window), vbox1);
gtk_container_set_reallocate_redraws(GTK_CONTAINER(window), true);
gtk_container_add(GTK_CONTAINER(window), vbox1);
g_signal_connect(
G_OBJECT(window),
"delete_event",
G_CALLBACK(gtk_main_quit),
0
);
g_signal_connect(
G_OBJECT(window),
"delete_event",
G_CALLBACK(gtk_main_quit),
0
);
gtk_widget_show_all(window);
gtk_main();
}
gtk_widget_show_all(window);
gtk_main();
}
else return 1;
else return 1;
return 0;
return 0;
}