root/OpenSceneGraph/trunk/examples/osgwidgetmessagebox/osgwidgetmessagebox.cpp @ 13788

Revision 12529, 20.2 kB (checked in by robert, 4 years ago)

Replaced .osg with .osgt file usage

  • Property svn:eol-style set to native
Line 
1// -*-c++-*- osgWidget - Copyright Cedric Pinson 2008
2
3
4#include <osgWidget/Util>
5#include <osgWidget/WindowManager>
6#include <osgWidget/Frame>
7#include <osgWidget/Box>
8#include <osgWidget/Widget>
9#include <osgWidget/Types>
10#include <osgDB/ReadFile>
11#include <osgAnimation/EaseMotion>
12#include <osg/io_utils>
13#include <iostream>
14
15const unsigned int MASK_2D = 0xF0000000;
16
17class MessageBox
18{
19protected:
20       
21    osgWidget::Frame* createButtonOk(const std::string& theme, const std::string& text, const std::string& font, int fontSize);
22    osgWidget::Label* createLabel(const std::string& string, const std::string& font, int size, const osgWidget::Color& color);
23       
24    osg::ref_ptr<osgWidget::Frame> _window;
25    osg::ref_ptr<osgWidget::Frame> _button;
26
27public:
28       
29    osgWidget::Frame* getButton();
30    osgWidget::Frame* getWindow();
31
32    bool create(const std::string& themeMessage,
33                const std::string& themeButton,
34                const std::string& titleText,
35                const std::string& messageText,
36                const std::string& buttonText,
37                const std::string& font,
38                int fontSize);
39
40};
41osgWidget::Frame* MessageBox::getButton() { return _button.get(); }
42osgWidget::Frame* MessageBox::getWindow() { return _window.get(); }
43
44struct AlphaSetterVisitor : public osg::NodeVisitor
45{
46    float _alpha;
47    AlphaSetterVisitor( float alpha = 1.0):osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) { _alpha = alpha;}
48
49    void apply(osg::MatrixTransform& node)
50    {
51        osgWidget::Window* win = dynamic_cast<osgWidget::Window*>(&node);
52
53        if (win) {
54//             osgWidget::warn() << "I am in Window: " << win->getName() << std::endl;
55
56            for (osgWidget::Window::Iterator it = win->begin(); it != win->end(); it++)
57            {
58//                 osgWidget::warn() << "   I am operating on Widget: " << it->get()->getName() << std::endl;
59               
60                osgWidget::Color color = it->get()->getColor();
61                color[3] = color[3] *_alpha;
62                it->get()->setColor(color);
63            }
64            {
65                osgWidget::Color color = win->getBackground()->getColor();
66                color[3] = color[3] *_alpha;
67                win->getBackground()->setColor(color);
68            }
69        }
70        traverse(node);
71    }
72};
73
74
75struct ColorSetterVisitor : public osg::NodeVisitor
76{
77    osgWidget::Color _color;
78    ColorSetterVisitor( const osgWidget::Color& color):osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) { _color = color;}
79
80    void apply(osg::MatrixTransform& node)
81    {
82        osgWidget::Window* win = dynamic_cast<osgWidget::Window*>(&node);
83
84        if (win) {
85//            osgWidget::warn() << "I am in Window: " << win->getName() << std::endl;
86
87            for (osgWidget::Window::Iterator it = win->begin(); it != win->end(); it++)
88            {
89//                osgWidget::warn() << "   I am operating on Widget: " << it->get()->getName() << std::endl;
90               
91//                 osgWidget::Color color = it->get()->getColor();
92//                 color[3] = color[3] *_alpha;
93                it->get()->setColor(_color);
94            }
95            {
96//                 osgWidget::Color color = win->getBackground()->getColor();
97//                 color[3] = color[3] *_alpha;
98                win->getBackground()->setColor(osgWidget::Color(0,0,0,0));
99            }
100        }
101        traverse(node);
102    }
103};
104
105
106
107struct EventOK : public osgWidget::Callback, osg::NodeCallback
108{
109    typedef osgAnimation::OutCubicMotion WidgetMotion;
110//    typedef osgAnimation::OutQuartMotion WidgetMotion;
111    WidgetMotion _motionOver;
112    WidgetMotion _motionLeave;
113   
114    double _lastUpdate;
115    osgWidget::Color _defaultColor;
116    osgWidget::Color _overColor;
117    bool _over;
118    osg::ref_ptr<osgWidget::Frame> _frame;
119    float _width;
120    float _height;
121    osg::Matrix _matrix;
122    EventOK(osgWidget::Frame* frame) : osgWidget::Callback(osgWidget::EVENT_ALL), _frame(frame)
123    {
124        _motionOver = WidgetMotion(0.0, 0.4);
125        _motionLeave = WidgetMotion(0.0, 0.5);
126        _defaultColor = _frame->getEmbeddedWindow()->getColor();
127        _overColor = osgWidget::Color(229.0/255.0,
128                                      103.0/255.0,
129                                      17.0/255,
130                                      _defaultColor[3]);
131        _over  = false;
132    }
133
134    bool operator()(osgWidget::Event& ev)
135    {
136        if (ev.type == osgWidget::EVENT_MOUSE_ENTER)
137        {
138            _over = true;
139            _width = _frame->getWidth();
140            _height = _frame->getHeight();
141            _motionOver.reset();
142            _matrix = _frame->getMatrix();
143            //_frame->setMatrix(osg::Matrix::scale(2, 2, 1) * _frame->getMatrix());
144            _frame->setScale(1.1f); //osg::Matrix::scale(2, 2, 1) * _frame->getMatrix());
145            _frame->update(); //osg::Matrix::scale(2, 2, 1) * _frame->getMatrix());
146            std::cout << "enter" << std::endl;
147            return true;
148        }
149        else if (ev.type == osgWidget::EVENT_MOUSE_LEAVE)
150        {
151            _over = false;
152            _motionLeave.reset();
153            //_frame->setMatrix(_matrix);
154            _frame->setScale(1.0f);
155            _frame->update();
156            std::cout << "leave" << std::endl;
157            return true;
158        }
159        return false;
160    }
161
162    void operator()(osg::Node* node, osg::NodeVisitor* nv)
163    {
164        if (nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
165        {
166            const osg::FrameStamp* fs = nv->getFrameStamp();
167            double dt = fs->getSimulationTime() - _lastUpdate;
168            _lastUpdate = fs->getSimulationTime();
169
170            if (_frame.valid())
171            {
172                float value;
173                if (_over)
174                {
175                    _motionOver.update(dt);
176                    value = _motionOver.getValue();
177                }
178                else
179                {
180                    _motionLeave.update(dt);
181                    value = 1.0 - _motionLeave.getValue();
182                }
183
184                osgWidget::Color c = _defaultColor + ((_overColor - _defaultColor) * value);
185                ColorSetterVisitor colorSetter(c);
186                _frame->accept(colorSetter);
187            }
188        }
189        node->traverse(*nv);
190    }
191};
192
193
194
195osgWidget::Label* MessageBox::createLabel(const std::string& string, const std::string& font, int size, const osgWidget::Color& color)
196{
197    osgWidget::Label* label = new osgWidget::Label("", "");
198    label->setFont(font);
199    label->setFontSize(size);
200    label->setFontColor(color);
201    label->setColor(osgWidget::Color(0,0,0,0));
202    label->setLabel(string);
203    label->setCanFill(true);
204    return label;
205}
206
207osgWidget::Frame* MessageBox::createButtonOk(const std::string& theme,
208                                                 const std::string& text,
209                                                 const std::string& font,
210                                                 int fontSize)
211{
212    osg::ref_ptr<osgWidget::Frame> frame = osgWidget::Frame::createSimpleFrameFromTheme(
213        "ButtonOK",
214        osgDB::readImageFile(theme),
215        300.0f,
216        50.0f,
217        osgWidget::Frame::FRAME_TEXTURE
218        );
219    frame->getBackground()->setColor(0.0f, 0.0f, 0.0f, 0.0f);
220
221    osgWidget::Label* label = createLabel(text, font, fontSize, osgWidget::Color(0,0,0,1));
222
223    osgWidget::Box* box = new osgWidget::Box("HBOX", osgWidget::Box::HORIZONTAL);
224    box->addWidget(label);
225    box->resize();
226    osgWidget::Color colorBack = frame->getEmbeddedWindow()->getColor();
227    box->getBackground()->setColor(colorBack);
228    frame->getEmbeddedWindow()->setWindow(box);
229    box->setVisibilityMode(osgWidget::Window::VM_ENTIRE);
230    box->setEventMask(osgWidget::EVENT_NONE);
231    frame->setVisibilityMode(osgWidget::Window::VM_ENTIRE);
232
233    frame->resizeFrame(box->getWidth(), box->getHeight());
234    frame->resizeAdd(0, 0);
235
236    EventOK* event = new EventOK(frame.get());
237    frame->setUpdateCallback(event);
238    frame->addCallback(event);
239
240    return frame.release();
241}
242
243bool MessageBox::create(const std::string& themeMessage,
244                        const std::string& themeButton,
245                        const std::string& titleText,
246                        const std::string& messageText,
247                        const std::string& buttonText,
248                        const std::string& font,
249                        int fontSize)
250{
251
252    osg::ref_ptr<osgWidget::Frame> frame = osgWidget::Frame::createSimpleFrameFromTheme(
253        "error",
254        osgDB::readImageFile(themeMessage),
255        300.0f,
256        50.0f,
257        osgWidget::Frame::FRAME_ALL
258        );
259    frame->getBackground()->setColor(0.0f, 0.0f, 0.0f, 0.0f);
260
261    osgWidget::Label* labelText = createLabel(messageText, font, fontSize, osgWidget::Color(0,0,0,1));
262    osgWidget::Label* labelTitle = createLabel(titleText, font, fontSize+5, osgWidget::Color(0.4,0,0,1));
263
264    osgWidget::Box*   box   = new osgWidget::Box("VBOX", osgWidget::Box::VERTICAL);
265
266    _button = createButtonOk(themeButton, buttonText, font, fontSize);
267    osgWidget::Widget* buttonOK = _button->embed();
268    _button->setVisibilityMode(osgWidget::Window::VM_ENTIRE);
269    buttonOK->setColor(osgWidget::Color(0,0,0,0));
270    buttonOK->setCanFill(false);
271
272    labelTitle->setPadBottom(30.0f);
273    labelText->setPadBottom(30.0f);
274
275    box->addWidget(buttonOK);
276    box->addWidget(labelText);
277    box->addWidget(labelTitle);
278
279    osgWidget::Color colorBack = frame->getEmbeddedWindow()->getColor();
280    box->getBackground()->setColor(colorBack);
281
282    frame->setWindow(box);
283
284    box->resize();
285    frame->resizeFrame(box->getWidth(), box->getHeight());
286    _window = frame;
287    return true;
288}
289
290
291
292
293
294
295
296const char* LABEL1 =
297    "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed\n"
298    "do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n"
299    "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris\n"
300    "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in..."
301;
302
303int main(int argc, char** argv)
304{
305
306    osgViewer::Viewer viewer;
307
308    osgWidget::WindowManager* wm = new osgWidget::WindowManager(
309        &viewer,
310        1280.0f,
311        1024.0f,
312        MASK_2D,
313        osgWidget::WindowManager::WM_PICK_DEBUG
314    );
315
316    int fontSize = 20;
317    std::string font="fonts/arial.ttf";
318    std::string buttonTheme = "osgWidget/theme-8-shadow.png";
319    std::string borderTheme = "osgWidget/theme-8.png";
320
321    MessageBox message;
322    message.create(borderTheme,
323                   buttonTheme,
324                   "Error - Critical",
325                   LABEL1,
326                   "Quit",
327                   font,
328                   fontSize);
329
330    AlphaSetterVisitor alpha(.8f);
331    message.getWindow()->accept(alpha);
332
333    wm->addChild(message.getWindow());
334
335    // center
336    osgWidget::point_type w = wm->getWidth();
337    osgWidget::point_type h = wm->getHeight();
338    osgWidget::point_type ww = message.getWindow()->getWidth();
339    osgWidget::point_type hw = message.getWindow()->getHeight();
340    osgWidget::point_type ox = (w - ww) / 2;
341    osgWidget::point_type oy = (h - hw) / 2;
342    message.getWindow()->setPosition(osgWidget::Point(
343        osg::round(ox), osg::round(oy), message.getWindow()->getPosition()[2])
344    );
345//    frame->resizeAdd(30, 30);
346
347//    AlphaSetterVisitor alpha(.8f);
348//    frame->accept(alpha);
349    return osgWidget::createExample(viewer, wm); //osgDB::readNodeFile("cow.osgt"));
350
351}
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409#if 0
410struct AlphaSetterVisitor : public osg::NodeVisitor
411{
412    float _alpha;
413    AlphaSetterVisitor( float alpha = 1.0):osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) { _alpha = alpha;}
414
415    void apply(osg::MatrixTransform& node)
416    {
417        osgWidget::Window* win = dynamic_cast<osgWidget::Window*>(&node);
418
419        if (win) {
420//             osgWidget::warn() << "I am in Window: " << win->getName() << std::endl;
421
422            for (osgWidget::Window::Iterator it = win->begin(); it != win->end(); it++)
423            {
424//                 osgWidget::warn() << "   I am operating on Widget: " << it->get()->getName() << std::endl;
425               
426                osgWidget::Color color = it->get()->getColor();
427                color[3] = color[3] *_alpha;
428                it->get()->setColor(color);
429            }
430            {
431                osgWidget::Color color = win->getBackground()->getColor();
432                color[3] = color[3] *_alpha;
433                win->getBackground()->setColor(color);
434            }
435        }
436        traverse(node);
437    }
438};
439
440
441struct ColorSetterVisitor : public osg::NodeVisitor
442{
443    osgWidget::Color _color;
444    ColorSetterVisitor( const osgWidget::Color& color):osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) { _color = color;}
445
446    void apply(osg::MatrixTransform& node)
447    {
448        osgWidget::Window* win = dynamic_cast<osgWidget::Window*>(&node);
449
450        if (win) {
451//            osgWidget::warn() << "I am in Window: " << win->getName() << std::endl;
452
453            for (osgWidget::Window::Iterator it = win->begin(); it != win->end(); it++)
454            {
455//                osgWidget::warn() << "   I am operating on Widget: " << it->get()->getName() << std::endl;
456               
457//                 osgWidget::Color color = it->get()->getColor();
458//                 color[3] = color[3] *_alpha;
459                it->get()->setColor(_color);
460            }
461            {
462//                 osgWidget::Color color = win->getBackground()->getColor();
463//                 color[3] = color[3] *_alpha;
464                win->getBackground()->setColor(osgWidget::Color(0,0,0,0));
465            }
466        }
467        traverse(node);
468    }
469};
470
471
472struct EventOK : public osgWidget::Callback, osg::NodeCallback
473{
474    typedef osgAnimation::OutQuartMotion WidgetMotion;
475    WidgetMotion _motionOver;
476    WidgetMotion _motionLeave;
477   
478    double _lastUpdate;
479    osgWidget::Color _defaultColor;
480    osgWidget::Color _overColor;
481    bool _over;
482    osg::ref_ptr<osgWidget::Frame> _frame;
483    float _width;
484    float _height;
485    EventOK(osgWidget::Frame* frame) : osgWidget::Callback(osgWidget::EVENT_ALL), _frame(frame)
486    {
487        _motionOver = WidgetMotion(0.0, 0.4);
488        _motionLeave = WidgetMotion(0.0, 0.5);
489        _defaultColor = _frame->getEmbeddedWindow()->getColor();
490        _overColor = osgWidget::Color(229.0/255.0,
491                                      103.0/255.0,
492                                      17.0/255,
493                                      _defaultColor[3]);
494        _over  = false;
495    }
496
497    bool operator()(osgWidget::Event& ev)
498    {
499        if (ev.type == osgWidget::EVENT_MOUSE_ENTER)
500        {
501            _over = true;
502//            std::cout << "Enter" << std::endl;
503            _width = _frame->getWidth();
504            _height = _frame->getHeight();
505            _motionOver.reset();
506
507//             _frame->resize(_width * 1.2, _height * 1.2);
508            return true;
509        }
510        else if (ev.type == osgWidget::EVENT_MOUSE_LEAVE)
511        {
512            _over = false;
513//            std::cout << "Leave" << std::endl;
514//             _frame->resize(_width, _height);
515            _motionLeave.reset();
516            return true;
517        }
518        return false;
519    }
520
521    void operator()(osg::Node* node, osg::NodeVisitor* nv)
522    {
523        if (nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
524        {
525            const osg::FrameStamp* fs = nv->getFrameStamp();
526            double dt = fs->getSimulationTime() - _lastUpdate;
527            _lastUpdate = fs->getSimulationTime();
528
529            if (_frame.valid())
530            {
531                float value;
532                if (_over)
533                {
534                    _motionOver.update(dt);
535                    value = _motionOver.getValue();
536                }
537                else
538                {
539                    _motionLeave.update(dt);
540                    value = 1.0 - _motionLeave.getValue();
541                }
542
543                osgWidget::Color c = _defaultColor + ((_overColor - _defaultColor) * value);
544                ColorSetterVisitor colorSetter(c);
545                _frame->accept(colorSetter);
546            }
547        }
548        node->traverse(*nv);
549    }
550};
551
552
553
554osgWidget::Label* createLabel(const std::string& string, const std::string& font, int size, const osgWidget::Color& color)
555{
556    osgWidget::Label* label = new osgWidget::Label("", "");
557    label->setFont(font);
558    label->setFontSize(size);
559    label->setFontColor(color);
560    label->setColor(osgWidget::Color(0,0,0,0));
561    label->setLabel(string);
562    label->setCanFill(true);
563    return label;
564}
565
566osgWidget::Window* createButtonOk(const std::string& theme, const std::string& text, int fontSize)
567{
568    osg::ref_ptr<osgWidget::Frame> frame = osgWidget::Frame::createSimpleFrameFromTheme(
569        "ButtonOK",
570        osgDB::readImageFile(theme),
571        300.0f,
572        50.0f,
573        osgWidget::Frame::FRAME_TEXTURE
574        );
575    frame->getBackground()->setColor(0.0f, 0.0f, 0.0f, 0.0f);
576
577    osgWidget::Label* label = createLabel(text, "fonts/Vera.ttf", fontSize, osgWidget::Color(0,0,0,1));
578
579    osgWidget::Box* box = new osgWidget::Box("HBOX", osgWidget::Box::HORIZONTAL);
580    box->addWidget(label);
581    box->resize();
582    osgWidget::Color colorBack = frame->getEmbeddedWindow()->getColor();
583    box->getBackground()->setColor(colorBack);
584    frame->getEmbeddedWindow()->setWindow(box);
585    box->setVisibilityMode(osgWidget::Window::VM_ENTIRE);
586    box->setEventMask(osgWidget::EVENT_NONE);
587
588    frame->resizeFrame(box->getWidth(), box->getHeight());
589    frame->resizeAdd(0, 0);
590
591    EventOK* event = new EventOK(frame);
592    frame->setUpdateCallback(event);
593    frame->addCallback(event);
594
595
596    return frame.release();
597}
598
599osgWidget::Frame* createErrorMessage(const std::string& themeMessage,
600                              const std::string& themeButton,
601                              const std::string& titleText,
602                              const std::string& messageText,
603                              const std::string& buttonText,
604                              const std::string& font,
605                              int fontSize)
606{
607
608    osg::ref_ptr<osgWidget::Frame> frame = osgWidget::Frame::createSimpleFrameFromTheme(
609        "error",
610        osgDB::readImageFile(themeMessage),
611        300.0f,
612        50.0f,
613        osgWidget::Frame::FRAME_ALL
614        );
615    frame->getBackground()->setColor(0.0f, 0.0f, 0.0f, 0.0f);
616
617    osgWidget::Label* labelText = createLabel(messageText, font, fontSize, osgWidget::Color(0,0,0,1));
618    osgWidget::Label* labelTitle = createLabel(titleText, font, fontSize+5, osgWidget::Color(0.4,0,0,1));
619
620    osgWidget::Box*   box   = new osgWidget::Box("VBOX", osgWidget::Box::VERTICAL);
621
622    osgWidget::Widget* buttonOK = createButtonOk(themeButton, buttonText, fontSize)->embed();
623    buttonOK->setColor(osgWidget::Color(0,0,0,0));
624    buttonOK->setCanFill(false);
625
626    box->addWidget(buttonOK);
627    box->addWidget(labelText);
628    box->addWidget(labelTitle);
629
630    osgWidget::Color colorBack = frame->getEmbeddedWindow()->getColor();
631    box->getBackground()->setColor(colorBack);
632
633    frame->setWindow(box);
634
635    box->resize();
636    frame->resizeFrame(box->getWidth(), box->getHeight());
637    return frame.release();
638}
639
640
641const char* LABEL1 =
642    "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed\n"
643    "do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n"
644    "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris\n"
645    "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in..."
646;
647
648int main(int argc, char** argv)
649{
650    std::string theme = "osgWidget/theme-1.png";
651    if (argc > 1)
652        theme = std::string(argv[1]);
653
654    osgViewer::Viewer viewer;
655
656    osgWidget::WindowManager* wm = new osgWidget::WindowManager(
657        &viewer,
658        1280.0f,
659        1024.0f,
660        MASK_2D,
661        osgWidget::WindowManager::WM_PICK_DEBUG
662    );
663
664    osgWidget::Frame* frame = createErrorMessage(theme,
665                                          "osgWidget/theme-8-shadow.png",
666                                          "Error - Critical",
667                                          LABEL1,
668                                          "Ok",
669                                          "fonts/Vera.ttf",
670                                          20);
671    // Add everything to the WindowManager.
672    wm->addChild(frame);
673    frame->resizeAdd(30, 30);
674
675    AlphaSetterVisitor alpha(.8f);
676    frame->accept(alpha);
677    return osgWidget::createExample(viewer, wm, osgDB::readNodeFile("cow.osgt"));
678}
679#endif
Note: See TracBrowser for help on using the browser.