Changeset 8294
- Timestamp:
- 05/09/08 12:27:59
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
OpenSceneGraph/trunk/examples/osgviewerGTK/osggtkdrawingarea.cpp
r8290 r8294 1 // by: Jeremy Moles <jeremy@emperorlinux.com> 20072 3 1 #include "osggtkdrawingarea.h" 4 2 … … 10 8 _state (0), 11 9 _queue (*getEventQueue()) { 12 setCameraManipulator(new osgGA::TrackballManipulator());10 setCameraManipulator(new osgGA::TrackballManipulator()); 13 11 } 14 12 … … 17 15 18 16 bool OSGGTKDrawingArea::createWidget(int width, int height) { 19 _glconfig = gdk_gl_config_new_by_mode(static_cast<GdkGLConfigMode>(20 GDK_GL_MODE_RGBA |21 GDK_GL_MODE_DEPTH |22 GDK_GL_MODE_DOUBLE23 ));17 _glconfig = gdk_gl_config_new_by_mode(static_cast<GdkGLConfigMode>( 18 GDK_GL_MODE_RGBA | 19 GDK_GL_MODE_DEPTH | 20 GDK_GL_MODE_DOUBLE 21 )); 24 22 25 if(not _glconfig) {26 osg::notify(osg::FATAL) << "Fail!" << std::endl;23 if(not _glconfig) { 24 osg::notify(osg::FATAL) << "Fail!" << std::endl; 27 25 28 return false;29 }26 return false; 27 } 30 28 31 gtk_widget_set_size_request(_widget, width, height);29 gtk_widget_set_size_request(_widget, width, height); 32 30 33 gtk_widget_set_gl_capability(34 _widget,35 _glconfig,36 0,37 true,38 GDK_GL_RGBA_TYPE39 );31 gtk_widget_set_gl_capability( 32 _widget, 33 _glconfig, 34 0, 35 true, 36 GDK_GL_RGBA_TYPE 37 ); 40 38 41 gtk_widget_add_events(42 _widget,43 GDK_BUTTON1_MOTION_MASK |44 GDK_BUTTON2_MOTION_MASK |45 GDK_BUTTON3_MOTION_MASK |46 GDK_POINTER_MOTION_MASK |47 GDK_BUTTON_PRESS_MASK |48 GDK_BUTTON_RELEASE_MASK |49 GDK_KEY_PRESS_MASK |50 GDK_KEY_RELEASE_MASK |51 GDK_VISIBILITY_NOTIFY_MASK52 );39 gtk_widget_add_events( 40 _widget, 41 GDK_BUTTON1_MOTION_MASK | 42 GDK_BUTTON2_MOTION_MASK | 43 GDK_BUTTON3_MOTION_MASK | 44 GDK_POINTER_MOTION_MASK | 45 GDK_BUTTON_PRESS_MASK | 46 GDK_BUTTON_RELEASE_MASK | 47 GDK_KEY_PRESS_MASK | 48 GDK_KEY_RELEASE_MASK | 49 GDK_VISIBILITY_NOTIFY_MASK 50 ); 53 51 54 // We do this so that we don't have to suck up ALL the input to the55 // window, but instead just when the drawing area is focused.56 g_object_set(_widget, "can-focus", true, NULL);52 // We do this so that we don't have to suck up ALL the input to the 53 // window, but instead just when the drawing area is focused. 54 g_object_set(_widget, "can-focus", true, NULL); 57 55 58 _connect("realize", G_CALLBACK(&OSGGTKDrawingArea::_srealize));59 _connect("unrealize", G_CALLBACK(&OSGGTKDrawingArea::_sunrealize));60 _connect("expose_event", G_CALLBACK(&OSGGTKDrawingArea::_sexpose_event));61 _connect("configure_event", G_CALLBACK(&OSGGTKDrawingArea::_sconfigure_event));62 _connect("motion_notify_event", G_CALLBACK(&OSGGTKDrawingArea::_smotion_notify_event));63 _connect("button_press_event", G_CALLBACK(&OSGGTKDrawingArea::_sbutton_press_event));64 _connect("button_release_event", G_CALLBACK(&OSGGTKDrawingArea::_sbutton_press_event));65 _connect("key_press_event", G_CALLBACK(&OSGGTKDrawingArea::_skey_press_event));56 _connect("realize", G_CALLBACK(&OSGGTKDrawingArea::_srealize)); 57 _connect("unrealize", G_CALLBACK(&OSGGTKDrawingArea::_sunrealize)); 58 _connect("expose_event", G_CALLBACK(&OSGGTKDrawingArea::_sexpose_event)); 59 _connect("configure_event", G_CALLBACK(&OSGGTKDrawingArea::_sconfigure_event)); 60 _connect("motion_notify_event", G_CALLBACK(&OSGGTKDrawingArea::_smotion_notify_event)); 61 _connect("button_press_event", G_CALLBACK(&OSGGTKDrawingArea::_sbutton_press_event)); 62 _connect("button_release_event", G_CALLBACK(&OSGGTKDrawingArea::_sbutton_press_event)); 63 _connect("key_press_event", G_CALLBACK(&OSGGTKDrawingArea::_skey_press_event)); 66 64 67 setUpViewerAsEmbeddedInWindow(0, 0, width, height);65 _gw = setUpViewerAsEmbeddedInWindow(0, 0, width, height); 68 66 69 return true;67 return true; 70 68 } 71 69 72 70 void OSGGTKDrawingArea::_realize(GtkWidget* widget) { 73 _context = gtk_widget_get_gl_context(widget);74 _drawable = gtk_widget_get_gl_drawable(widget);71 _context = gtk_widget_get_gl_context(widget); 72 _drawable = gtk_widget_get_gl_drawable(widget); 75 73 76 gtkRealize();74 gtkRealize(); 77 75 } 78 76 79 77 void OSGGTKDrawingArea::_unrealize(GtkWidget* widget) { 80 gtkUnrealize();78 gtkUnrealize(); 81 79 } 82 80 83 81 bool OSGGTKDrawingArea::_expose_event(GtkWidget* widget, GdkEventExpose* event) { 84 if(not gtkGLBegin()) return false;82 if(not gtkGLBegin()) return false; 85 83 86 frame();84 frame(); 87 85 88 gtkGLSwap();89 gtkGLEnd();86 gtkGLSwap(); 87 gtkGLEnd(); 90 88 91 return gtkExpose();89 return gtkExpose(); 92 90 } 93 91 94 92 bool OSGGTKDrawingArea::_configure_event(GtkWidget* widget, GdkEventConfigure* event) { 95 gtkGLBegin();93 gtkGLBegin(); 96 94 97 _queue.windowResize(0, 0, event->width, event->height);95 _queue.windowResize(0, 0, event->width, event->height); 98 96 99 gtkGLEnd();97 _gw->resized(0, 0, event->width, event->height); 100 98 101 return gtkConfigure(event->width, event->height); 99 gtkGLEnd(); 100 101 return gtkConfigure(event->width, event->height); 102 102 } 103 103 104 104 bool OSGGTKDrawingArea::_motion_notify_event(GtkWidget* widget, GdkEventMotion* event) { 105 _state = event->state;105 _state = event->state; 106 106 107 _queue.mouseMotion(event->x, event->y);107 _queue.mouseMotion(event->x, event->y); 108 108 109 return gtkMotionNotify(event->x, event->y);109 return gtkMotionNotify(event->x, event->y); 110 110 } 111 111 112 112 bool OSGGTKDrawingArea::_button_press_event(GtkWidget* widget, GdkEventButton* event) { 113 _state = event->state;113 _state = event->state; 114 114 115 if(event->type == GDK_BUTTON_PRESS) {116 if(event->button == 1) gtk_widget_grab_focus(_widget);115 if(event->type == GDK_BUTTON_PRESS) { 116 if(event->button == 1) gtk_widget_grab_focus(_widget); 117 117 118 _queue.mouseButtonPress(event->x, event->y, event->button);118 _queue.mouseButtonPress(event->x, event->y, event->button); 119 119 120 return gtkButtonPress(event->x, event->y, event->button);121 }120 return gtkButtonPress(event->x, event->y, event->button); 121 } 122 122 123 else if(event->type == GDK_BUTTON_RELEASE) {124 _queue.mouseButtonRelease(event->x, event->y, event->button);123 else if(event->type == GDK_BUTTON_RELEASE) { 124 _queue.mouseButtonRelease(event->x, event->y, event->button); 125 125 126 return gtkButtonRelease(event->x, event->y, event->button);127 }126 return gtkButtonRelease(event->x, event->y, event->button); 127 } 128 128 129 else return false;129 else return false; 130 130 } 131 131 132 132 bool OSGGTKDrawingArea::_key_press_event(GtkWidget* widget, GdkEventKey* event) { 133 _state = event->state;133 _state = event->state; 134 134 135 if(event->type == GDK_KEY_PRESS) {136 _queue.keyPress(event->keyval);135 if(event->type == GDK_KEY_PRESS) { 136 _queue.keyPress(event->keyval); 137 137 138 return gtkKeyPress(event->keyval);139 }138 return gtkKeyPress(event->keyval); 139 } 140 140 141 else if(event->type == GDK_KEY_RELEASE) {142 _queue.keyRelease(event->keyval);141 else if(event->type == GDK_KEY_RELEASE) { 142 _queue.keyRelease(event->keyval); 143 143 144 return gtkKeyRelease(event->keyval);145 }144 return gtkKeyRelease(event->keyval); 145 } 146 146 147 else return false;147 else return false; 148 148 } OpenSceneGraph/trunk/examples/osgviewerGTK/osggtkdrawingarea.h
r8290 r8294 1 // by: Jeremy Moles <jeremy@emperorlinux.com> 20072 3 1 #include <gtk/gtk.h> 4 2 #include <gtk/gtkgl.h> … … 16 14 // subclass implementation (see: osgviewerGTK). 17 15 class OSGGTKDrawingArea : public osgViewer::Viewer { 18 GtkWidget* _widget; 19 GdkGLConfig* _glconfig; 20 GdkGLContext* _context; 21 GdkGLDrawable* _drawable; 22 23 unsigned int _state; 24 25 osgGA::EventQueue& _queue; 26 27 static OSGGTKDrawingArea* _self(gpointer self) { 28 return static_cast<OSGGTKDrawingArea*>(self); 29 } 30 31 // A simple helper function to connect us to the various GTK signals. 32 void _connect(const char* name, GCallback callback) { 33 g_signal_connect(G_OBJECT(_widget), name, callback, this); 34 } 35 36 void _realize (GtkWidget*); 37 void _unrealize (GtkWidget*); 38 bool _expose_event (GtkWidget*, GdkEventExpose*); 39 bool _configure_event (GtkWidget*, GdkEventConfigure*); 40 bool _motion_notify_event (GtkWidget*, GdkEventMotion*); 41 bool _button_press_event (GtkWidget*, GdkEventButton*); 42 bool _key_press_event (GtkWidget*, GdkEventKey*); 43 44 // The following functions are static "wrappers" so that we can invoke the 45 // bound methods of a class instance by passing the "this" pointer as the 46 // self argument and invoking it explicitly. 47 static void _srealize(GtkWidget* widget, gpointer self) { 48 _self(self)->_realize(widget); 49 } 50 51 static void _sunrealize(GtkWidget* widget, gpointer self) { 52 _self(self)->_unrealize(widget); 53 } 54 55 static bool _sexpose_event(GtkWidget* widget, GdkEventExpose* expose, gpointer self) { 56 return _self(self)->_expose_event(widget, expose); 57 } 58 59 static bool _sconfigure_event( 60 GtkWidget* widget, 61 GdkEventConfigure* event, 62 gpointer self 63 ) { 64 return _self(self)->_configure_event(widget, event); 65 } 66 67 static bool _smotion_notify_event( 68 GtkWidget* widget, 69 GdkEventMotion* event, 70 gpointer self 71 ) { 72 return _self(self)->_motion_notify_event(widget, event); 73 } 74 75 static bool _sbutton_press_event( 76 GtkWidget* widget, 77 GdkEventButton* event, 78 gpointer self 79 ) { 80 return _self(self)->_button_press_event(widget, event); 81 } 82 83 static bool _skey_press_event( 84 GtkWidget* widget, 85 GdkEventKey* event, 86 gpointer self 87 ) { 88 return _self(self)->_key_press_event(widget, event); 89 } 16 GtkWidget* _widget; 17 GdkGLConfig* _glconfig; 18 GdkGLContext* _context; 19 GdkGLDrawable* _drawable; 20 21 osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw; 22 23 unsigned int _state; 24 25 osgGA::EventQueue& _queue; 26 27 static OSGGTKDrawingArea* _self(gpointer self) { 28 return static_cast<OSGGTKDrawingArea*>(self); 29 } 30 31 // A simple helper function to connect us to the various GTK signals. 32 void _connect(const char* name, GCallback callback) { 33 g_signal_connect(G_OBJECT(_widget), name, callback, this); 34 } 35 36 void _realize (GtkWidget*); 37 void _unrealize (GtkWidget*); 38 bool _expose_event (GtkWidget*, GdkEventExpose*); 39 bool _configure_event (GtkWidget*, GdkEventConfigure*); 40 bool _motion_notify_event (GtkWidget*, GdkEventMotion*); 41 bool _button_press_event (GtkWidget*, GdkEventButton*); 42 bool _key_press_event (GtkWidget*, GdkEventKey*); 43 44 // The following functions are static "wrappers" so that we can invoke the 45 // bound methods of a class instance by passing the "this" pointer as the 46 // self argument and invoking it explicitly. 47 static void _srealize(GtkWidget* widget, gpointer self) { 48 _self(self)->_realize(widget); 49 } 50 51 static void _sunrealize(GtkWidget* widget, gpointer self) { 52 _self(self)->_unrealize(widget); 53 } 54 55 static bool _sexpose_event(GtkWidget* widget, GdkEventExpose* expose, gpointer self) { 56 return _self(self)->_expose_event(widget, expose); 57 } 58 59 static bool _sconfigure_event( 60 GtkWidget* widget, 61 GdkEventConfigure* event, 62 gpointer self 63 ) { 64 return _self(self)->_configure_event(widget, event); 65 } 66 67 static bool _smotion_notify_event( 68 GtkWidget* widget, 69 GdkEventMotion* event, 70 gpointer self 71 ) { 72 return _self(self)->_motion_notify_event(widget, event); 73 } 74 75 static bool _sbutton_press_event( 76 GtkWidget* widget, 77 GdkEventButton* event, 78 gpointer self 79 ) { 80 return _self(self)->_button_press_event(widget, event); 81 } 82 83 static bool _skey_press_event( 84 GtkWidget* widget, 85 GdkEventKey* event, 86 gpointer self 87 ) { 88 return _self(self)->_key_press_event(widget, event); 89 } 90 90 91 91 protected: 92 // You can override these in your subclass if you'd like. :)93 // Right now they're fairly uninformative, but they could be easily extended.94 // Note that the "state" information isn't passed around to each function95 // but is instead stored and abstracted internally. See below.96 97 virtual void gtkRealize () {};98 virtual void gtkUnrealize () {};99 virtual bool gtkExpose () {100 return true;101 };102 103 // The new width and height.104 virtual bool gtkConfigure(int, int) {105 return true;106 };107 108 // The "normalized" coordinates of the mouse.109 virtual bool gtkMotionNotify(double, double) {110 return true;111 };112 113 // The "normalized" coordinates of the mouse and the mouse button code on down.114 virtual bool gtkButtonPress(double, double, unsigned int) {115 return true;116 };117 118 // The "normalized" coordinates of the mouse and mouse button code on release.119 virtual bool gtkButtonRelease(double, double, unsigned int) {120 return true;121 }122 123 // The X key value on down.124 virtual bool gtkKeyPress(unsigned int) {125 return true;126 };127 128 // The X key value on release.129 virtual bool gtkKeyRelease(unsigned int) {130 return true;131 };132 133 // These functions wrap state tests of the most recent state in the134 // GtkDrawingArea.135 136 inline bool stateShift() {137 return _state & GDK_SHIFT_MASK;138 }139 140 inline bool stateLock() {141 return _state & GDK_LOCK_MASK;142 }143 144 inline bool stateControl() {145 return _state & GDK_CONTROL_MASK;146 }147 148 inline bool stateMod() {149 return _state & (150 GDK_MOD1_MASK |151 GDK_MOD2_MASK |152 GDK_MOD3_MASK |153 GDK_MOD4_MASK |154 GDK_MOD5_MASK155 );156 }157 158 inline bool stateButton() {159 return _state & (160 GDK_BUTTON1_MASK |161 GDK_BUTTON2_MASK |162 GDK_BUTTON3_MASK |163 GDK_BUTTON4_MASK |164 GDK_BUTTON5_MASK165 );166 }92 // You can override these in your subclass if you'd like. :) 93 // Right now they're fairly uninformative, but they could be easily extended. 94 // Note that the "state" information isn't passed around to each function 95 // but is instead stored and abstracted internally. See below. 96 97 virtual void gtkRealize () {}; 98 virtual void gtkUnrealize () {}; 99 virtual bool gtkExpose () { 100 return true; 101 }; 102 103 // The new width and height. 104 virtual bool gtkConfigure(int, int) { 105 return true; 106 }; 107 108 // The "normalized" coordinates of the mouse. 109 virtual bool gtkMotionNotify(double, double) { 110 return true; 111 }; 112 113 // The "normalized" coordinates of the mouse and the mouse button code on down. 114 virtual bool gtkButtonPress(double, double, unsigned int) { 115 return true; 116 }; 117 118 // The "normalized" coordinates of the mouse and mouse button code on release. 119 virtual bool gtkButtonRelease(double, double, unsigned int) { 120 return true; 121 } 122 123 // The X key value on down. 124 virtual bool gtkKeyPress(unsigned int) { 125 return true; 126 }; 127 128 // The X key value on release. 129 virtual bool gtkKeyRelease(unsigned int) { 130 return true; 131 }; 132 133 // These functions wrap state tests of the most recent state in the 134 // GtkDrawingArea. 135 136 inline bool stateShift() { 137 return _state & GDK_SHIFT_MASK; 138 } 139 140 inline bool stateLock() { 141 return _state & GDK_LOCK_MASK; 142 } 143 144 inline bool stateControl() { 145 return _state & GDK_CONTROL_MASK; 146 } 147 148 inline bool stateMod() { 149 return _state & ( 150 GDK_MOD1_MASK | 151 GDK_MOD2_MASK | 152 GDK_MOD3_MASK | 153 GDK_MOD4_MASK | 154 GDK_MOD5_MASK 155 ); 156 } 157 158 inline bool stateButton() { 159 return _state & ( 160 GDK_BUTTON1_MASK | 161 GDK_BUTTON2_MASK | 162 GDK_BUTTON3_MASK | 163 GDK_BUTTON4_MASK | 164 GDK_BUTTON5_MASK 165 ); 166 } 167 167 168 168 public: 169 OSGGTKDrawingArea ();170 ~OSGGTKDrawingArea ();171 172 bool createWidget(int, int);173 174 GtkWidget* getWidget() {175 return _widget;176 }177 178 bool gtkGLBegin() {179 if(_drawable and _context) return gdk_gl_drawable_gl_begin(_drawable, _context);180 181 else return false;182 }183 184 void gtkGLEnd() {185 if(_drawable) gdk_gl_drawable_gl_end(_drawable);186 }187 188 // Because of GTK's internal double buffering, I'm not sure if we're really189 // taking advantage of OpenGL's internal swapping.190 bool gtkGLSwap() {191 if(_drawable and gdk_gl_drawable_is_double_buffered(_drawable)) {192 gdk_gl_drawable_swap_buffers(_drawable);193 194 return true;195 }196 197 else {198 glFlush();199 200 return false;201 }202 }203 204 void queueDraw() {205 gtk_widget_queue_draw(_widget);206 }169 OSGGTKDrawingArea (); 170 ~OSGGTKDrawingArea (); 171 172 bool createWidget(int, int); 173 174 GtkWidget* getWidget() { 175 return _widget; 176 } 177 178 bool gtkGLBegin() { 179 if(_drawable and _context) return gdk_gl_drawable_gl_begin(_drawable, _context); 180 181 else return false; 182 } 183 184 void gtkGLEnd() { 185 if(_drawable) gdk_gl_drawable_gl_end(_drawable); 186 } 187 188 // Because of GTK's internal double buffering, I'm not sure if we're really 189 // taking advantage of OpenGL's internal swapping. 190 bool gtkGLSwap() { 191 if(_drawable and gdk_gl_drawable_is_double_buffered(_drawable)) { 192 gdk_gl_drawable_swap_buffers(_drawable); 193 194 return true; 195 } 196 197 else { 198 glFlush(); 199 200 return false; 201 } 202 } 203 204 void queueDraw() { 205 gtk_widget_queue_draw(_widget); 206 } 207 207 }; OpenSceneGraph/trunk/examples/osgviewerGTK/osgviewerGTK.cpp
r8290 r8294 1 // by: Jeremy Moles <jeremy@emperorlinux.com> 20072 3 1 #include <iostream> 4 2 #include <string> … … 9 7 10 8 const char* HELP_TEXT = 11 "Use CTRL or SHIFT plus right-click to pull up a fake menu.\n"12 "Use the standard TrackballManipulator keys to rotate the loaded\n"13 "model (with caveats; the model won't keep rotating).\n"14 "\n"15 "<b>OpenSceneGraph Project, 2008</b>"9 "Use CTRL or SHIFT plus right-click to pull up a fake menu.\n" 10 "Use the standard TrackballManipulator keys to rotate the loaded\n" 11 "model (with caveats; the model won't keep rotating).\n" 12 "\n" 13 "<b>OpenSceneGraph Project, 2008</b>" 16 14 ; 17 15 … … 20 18 // come up with. 21 19 bool activate(GtkWidget* widget, gpointer) { 22 GtkWidget* label = gtk_bin_get_child(GTK_BIN(widget));23 24 std::cout << "MENU: " << gtk_label_get_label(GTK_LABEL(label)) << std::endl;25 26 return true;20 GtkWidget* label = gtk_bin_get_child(GTK_BIN(widget)); 21 22 std::cout << "MENU: " << gtk_label_get_label(GTK_LABEL(label)) << std::endl; 23 24 return true; 27 25 } 28 26 … … 35 33 // itself. 36 34 class ExampleOSGGTKDrawingArea : public OSGGTKDrawingArea { 37 GtkWidget* _menu;38 39 unsigned int _tid;40 41 // A helper function to easily setup our menu entries.42 void _menuAdd(const std::string& title) {43 GtkWidget* item = gtk_menu_item_new_with_label(title.c_str());44 45 gtk_menu_shell_append(GTK_MENU_SHELL(_menu), item);46 47 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(activate), 0);48 }49 50 bool _clicked(GtkWidget* widget) {51 const char* text = gtk_label_get_label(52 GTK_LABEL(gtk_bin_get_child(GTK_BIN(widget)))53 );54 55 if(not std::strncmp(text, "Close", 5)) gtk_main_quit();56 57 else if(not std::strncmp(text, "Open File", 9)) {58 GtkWidget* of = gtk_file_chooser_dialog_new(59 "Please select an OSG file...",60 GTK_WINDOW(gtk_widget_get_toplevel(getWidget())),61 GTK_FILE_CHOOSER_ACTION_OPEN,62 GTK_STOCK_CANCEL,63 GTK_RESPONSE_CANCEL,64 GTK_STOCK_OPEN,65 GTK_RESPONSE_ACCEPT,66 NULL67 );68 69 if(gtk_dialog_run(GTK_DIALOG(of)) == GTK_RESPONSE_ACCEPT) {70 char* file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(of));71 72 osg::ref_ptr<osg::Node> model = osgDB::readNodeFile(file);73 74 if(model.valid()) {75 setSceneData(model.get());76 77 queueDraw();78 }79 80 g_free(file);81 }82 83 gtk_widget_destroy(of);84 }85 86 // Assume we're wanting FPS toggling.87 else {88 if(not _tid) {89 _tid = g_timeout_add(90 15,91 (GSourceFunc)(ExampleOSGGTKDrawingArea::timeout),92 this93 );94 95 gtk_button_set_label(GTK_BUTTON(widget), "Toggle 60 FPS (off)");96 }97 98 else {99 g_source_remove(_tid);100 gtk_button_set_label(GTK_BUTTON(widget), "Toggle 60 FPS (on)");101 102 _tid = 0;103 }104 }105 106 return true;107 }35 GtkWidget* _menu; 36 37 unsigned int _tid; 38 39 // A helper function to easily setup our menu entries. 40 void _menuAdd(const std::string& title) { 41 GtkWidget* item = gtk_menu_item_new_with_label(title.c_str()); 42 43 gtk_menu_shell_append(GTK_MENU_SHELL(_menu), item); 44 45 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(activate), 0); 46 } 47 48 bool _clicked(GtkWidget* widget) { 49 const char* text = gtk_label_get_label( 50 GTK_LABEL(gtk_bin_get_child(GTK_BIN(widget))) 51 ); 52 53 if(not std::strncmp(text, "Close", 5)) gtk_main_quit(); 54 55 else if(not std::strncmp(text, "Open File", 9)) { 56 GtkWidget* of = gtk_file_chooser_dialog_new( 57 "Please select an OSG file...", 58 GTK_WINDOW(gtk_widget_get_toplevel(getWidget())), 59 GTK_FILE_CHOOSER_ACTION_OPEN, 60 GTK_STOCK_CANCEL, 61 GTK_RESPONSE_CANCEL, 62 GTK_STOCK_OPEN, 63 GTK_RESPONSE_ACCEPT, 64 NULL 65 ); 66 67 if(gtk_dialog_run(GTK_DIALOG(of)) == GTK_RESPONSE_ACCEPT) { 68 char* file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(of)); 69 70 osg::ref_ptr<osg::Node> model = osgDB::readNodeFile(file); 71 72 if(model.valid()) { 73 setSceneData(model.get()); 74 75 queueDraw(); 76 } 77 78 g_free(file); 79 } 80 81 gtk_widget_destroy(of); 82 } 83 84 // Assume we're wanting FPS toggling. 85 else { 86 if(not _tid) { 87 _tid = g_timeout_add( 88 15, 89 (GSourceFunc)(ExampleOSGGTKDrawingArea::timeout), 90 this 91 ); 92 93 gtk_button_set_label(GTK_BUTTON(widget), "Toggle 60 FPS (off)"); 94 } 95 96 else { 97 g_source_remove(_tid); 98 gtk_button_set_label(GTK_BUTTON(widget), "Toggle 60 FPS (on)"); 99 100 _tid = 0; 101 } 102 } 103 104 return true; 105 } 108 106 109 107 protected: 110 // Check right-click release to see if we need to popup our menu.111 bool gtkButtonRelease(double, double, unsigned int button) {112 if(button == 3 and (stateControl() or stateShift())) gtk_menu_popup(113 GTK_MENU(_menu),114 0,115 0,116 0,117 0,118 button,119 0120 );121 122 return true;123 }124 125 // Our "main" drawing pump. Since our app is just a model viewer, we use126 // click+motion as our criteria for issuing OpenGL refreshes.127 bool gtkMotionNotify(double, double) {128 if(stateButton()) queueDraw();129 130 return true;131 }108 // Check right-click release to see if we need to popup our menu. 109 bool gtkButtonRelease(double, double, unsigned int button) { 110 if(button == 3 and (stateControl() or stateShift())) gtk_menu_popup( 111 GTK_MENU(_menu), 112 0, 113 0, 114 0, 115 0, 116 button, 117 0 118 ); 119 120 return true; 121 } 122 123 // Our "main" drawing pump. Since our app is just a model viewer, we use 124 // click+motion as our criteria for issuing OpenGL refreshes. 125 bool gtkMotionNotify(double, double) { 126 if(stateButton()) queueDraw(); 127 128 return true; 129 } 132 130 133 131 public: 134 ExampleOSGGTKDrawingArea():135 OSGGTKDrawingArea (),136 _menu (gtk_menu_new()),137 _tid (0) {138 _menuAdd("Option");139 _menuAdd("Another Option");140 _menuAdd("Still More Options");141 142 gtk_widget_show_all(_menu);143 144 getCamera()->setStats(new osg::Stats("omg"));145 }146 147 ~ExampleOSGGTKDrawingArea() {}148 149 // Public so that we can use this as a callback in main().150 static bool clicked(GtkWidget* widget, gpointer self) {151 return static_cast<ExampleOSGGTKDrawingArea*>(self)->_clicked(widget);152 }153 154 //static gboolean timeout(GtkWidget* widget) {155 static bool timeout(void* self) {156 static_cast<ExampleOSGGTKDrawingArea*>(self)->queueDraw();157 158 return true;159 }132 ExampleOSGGTKDrawingArea(): 133 OSGGTKDrawingArea (), 134 _menu (gtk_menu_new()), 135 _tid (0) { 136 _menuAdd("Option"); 137 _menuAdd("Another Option"); 138 _menuAdd("Still More Options"); 139 140 gtk_widget_show_all(_menu); 141 142 getCamera()->setStats(new osg::Stats("omg")); 143 } 144 145 ~ExampleOSGGTKDrawingArea() {} 146 147 // Public so that we can use this as a callback in main(). 148 static bool clicked(GtkWidget* widget, gpointer self) { 149 return static_cast<ExampleOSGGTKDrawingArea*>(self)->_clicked(widget); 150 } 151 152 //static gboolean timeout(GtkWidget* widget) { 153 static bool timeout(void* self) { 154 static_cast<ExampleOSGGTKDrawingArea*>(self)->queueDraw(); 155 156 return true; 157 } 160 158 }; 161 159 … … 164 162 // code or so. 165 163 int main(int argc, char** argv) { 166 gtk_init(&argc, &argv);167 gtk_gl_init(&argc, &argv);168 169 ExampleOSGGTKDrawingArea da;170 171 if(da.createWidget(640, 480)) {172 if(argc >= 2) {173 osg::ref_ptr<osg::Node> model = osgDB::readNodeFile(argv[1]);174 175 if(model.valid()) da.setSceneData(model.get());176 }177 178 GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);179 GtkWidget* vbox1 = gtk_vbox_new(false, 3);180 GtkWidget* vbox2 = gtk_vbox_new(false, 3);181 GtkWidget* hbox = gtk_hbox_new(false, 3);182 GtkWidget* label = gtk_label_new("");183 GtkWidget* buttons[] = {184 gtk_button_new_with_label("Open File"),185 gtk_button_new_with_label("Toggle 60 FPS (on)"),186 gtk_button_new_with_label("Close")187 };188 189 gtk_label_set_use_markup(GTK_LABEL(label), true);190 gtk_label_set_label(GTK_LABEL(label), HELP_TEXT);191 192 for(unsigned int i = 0; i < sizeof(buttons) / sizeof(GtkWidget*); i++) {193 gtk_box_pack_start(194 GTK_BOX(vbox2),195 buttons[i],196 false,197 false,198 0199 );200 201 g_signal_connect(202 G_OBJECT(buttons[i]),203 "clicked",204 G_CALLBACK(ExampleOSGGTKDrawingArea::clicked),205 &da206 );207 }208 209 gtk_window_set_title(GTK_WINDOW(window), "osgviewerGTK");210 211 gtk_box_pack_start(GTK_BOX(hbox), vbox2, true, true, 2);212 gtk_box_pack_start(GTK_BOX(hbox), label, true, true, 2);213 214 gtk_box_pack_start(GTK_BOX(vbox1), da.getWidget(), true, true, 2);215 gtk_box_pack_start(GTK_BOX(vbox1), hbox, false, false, 2);216 217 gtk_container_set_reallocate_redraws(GTK_CONTAINER(window), true);218 gtk_container_add(GTK_CONTAINER(window), vbox1);219 220 g_signal_connect(221 G_OBJECT(window),222 "delete_event",223 G_CALLBACK(gtk_main_quit),224 0225 );226 227 gtk_widget_show_all(window);228 gtk_main();229 }230 231 else return 1;232 233 return 0;164 gtk_init(&argc, &argv); 165 gtk_gl_init(&argc, &argv); 166 167 ExampleOSGGTKDrawingArea da; 168 169 if(da.createWidget(640, 480)) { 170 if(argc >= 2) { 171 osg::ref_ptr<osg::Node> model = osgDB::readNodeFile(argv[1]); 172 173 if(model.valid()) da.setSceneData(model.get());
