root/OpenSceneGraph/trunk/examples/osgviewerGTK/osgviewerGTK.cpp @ 8290

Revision 8290, 5.9 kB (checked in by robert, 6 years ago)

From Jeremy Moles, osgviewerGTK example

Line 
1// by: Jeremy Moles <jeremy@emperorlinux.com> 2007
2
3#include <iostream>
4#include <string>
5#include <osg/Stats>
6#include <osgDB/ReadFile>
7
8#include "osggtkdrawingarea.h"
9
10const 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>"
16;
17
18// If you want to see how to connect class method to callbacks, take a look at the
19// implementation of OSGGTKDrawingArea. It's dirty, but it's the only way I could
20// come up with.
21bool 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;
27}
28
29// Our derived OSGGTKDrawingArea "widget." Redraws occur while the mouse buttons
30// are held down and mouse motion is detected.
31//
32// This is the easiest way to demonstrate the use of OSGGTKDrawingArea. We override
33// a few of the event methods to setup our menu and to issue redraws. Note that an
34// unmodified OSGGTKDrawingArea never calls queueDraw, so OSG is never asked to render
35// itself.
36class 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                                NULL
67                        );
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                                        this
93                                );
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        }
108
109protected:
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                        0
120                );
121
122                return true;
123        }
124
125        // Our "main" drawing pump. Since our app is just a model viewer, we use
126        // click+motion as our criteria for issuing OpenGL refreshes.
127        bool gtkMotionNotify(double, double) {
128                if(stateButton()) queueDraw();
129
130                return true;
131        }
132
133public:
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        }
160};
161
162// Our main() function! FINALLY! Most of this code is GTK stuff, so it's mostly boilerplate.
163// If we wanted to get real jiggy with it we could use Glade and cut down about 20 lines of
164// code or so.
165int 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                                0
199                        );
200
201                        g_signal_connect(
202                                G_OBJECT(buttons[i]),
203                                "clicked",
204                                G_CALLBACK(ExampleOSGGTKDrawingArea::clicked),
205                                &da
206                        );
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                        0
225                );
226
227                gtk_widget_show_all(window);
228                gtk_main();
229        }
230
231        else return 1;
232
233        return 0;
234}
Note: See TracBrowser for help on using the browser.