1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2014 Robert Osfield
2  *
3  * This library is open source and may be redistributed and/or modified under
4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5  * (at your option) any later version.  The full license is in LICENSE file
6  * included with this distribution, and on the openscenegraph.org website.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * OpenSceneGraph Public License for more details.
12 */
13 
14 
15 #include <osgUI/PushButton>
16 #include <osgText/String>
17 #include <osgText/Font>
18 #include <osgText/Text>
19 #include <osg/Notify>
20 
21 using namespace osgUI;
22 
23 PushButton::PushButton()
24 {
25 }
26 
27 PushButton::PushButton(const osgUI::PushButton& pb, const osg::CopyOp& copyop):
28     Widget(pb, copyop),
29     _text(pb._text)
30 {
31 }
32 
33 bool PushButton::handleImplementation(osgGA::EventVisitor* ev, osgGA::Event* event)
34 {
35     if (!getHasEventFocus()) return false;
36 
37     osgGA::GUIEventAdapter* ea = event->asGUIEventAdapter();
38     if (!ea) return false;
39 
40     switch(ea->getEventType())
41     {
42         case(osgGA::GUIEventAdapter::PUSH):
43             if (_buttonSwitch.valid())
44             {
45                 pressed();
46             }
47             break;
48         case(osgGA::GUIEventAdapter::RELEASE):
49             if (_buttonSwitch.valid())
50             {
51                 released();
52             }
53             break;
54         default:
55             break;
56     }
57 
58     return false;
59 }
60 
61 void PushButton::enterImplementation()
62 {
63     OSG_NOTICE<<"PushButton enter"<<std::endl;
64     if (_buttonSwitch.valid()) _buttonSwitch->setSingleChildOn(1);
65 }
66 
67 
68 void PushButton::leaveImplementation()
69 {
70     OSG_NOTICE<<"PushButton leave"<<std::endl;
71     if (_buttonSwitch.valid()) _buttonSwitch->setSingleChildOn(0);
72 }
73 
74 void PushButton::createGraphicsImplementation()
75 {
76     osg::ref_ptr<osg::Group> group = new osg::Group;
77 
78     Style* style = (getStyle()!=0) ? getStyle() : Style::instance().get();
79 
80 
81     float pressed = 0.88;
82     float unFocused = 0.92;
83     float withFocus = 0.97;
84 
85     osg::Vec4 frameColor(unFocused,unFocused,unFocused,1.0f);
86 
87     osg::BoundingBox extents(_extents);
88 
89     bool requiresFrame = (getFrameSettings() && getFrameSettings()->getShape()!=osgUI::FrameSettings::NO_FRAME);
90     if (requiresFrame)
91     {
92         group->addChild(style->createFrame(_extents, getFrameSettings(), frameColor));
93         extents.xMin() += getFrameSettings()->getLineWidth();
94         extents.xMax() -= getFrameSettings()->getLineWidth();
95         extents.yMin() += getFrameSettings()->getLineWidth();
96         extents.yMax() -= getFrameSettings()->getLineWidth();
97     }
98 
99     _buttonSwitch = new osg::Switch;
100     _buttonSwitch->addChild(style->createPanel(extents, osg::Vec4(unFocused, unFocused,unFocused, 1.0)));
101     _buttonSwitch->addChild(style->createPanel(extents, osg::Vec4(withFocus,withFocus,withFocus,1.0)));
102     _buttonSwitch->addChild(style->createPanel(extents, osg::Vec4(pressed,pressed,pressed,1.0)));
103     _buttonSwitch->setSingleChildOn(0);
104 
105     group->addChild(_buttonSwitch.get());
106 
107     // create label.
108     osg::ref_ptr<Node> node = style->createText(extents, getAlignmentSettings(), getTextSettings(), _text);
109     _textDrawable = dynamic_cast<osgText::Text*>(node.get());
110     _textDrawable->setDataVariance(osg::Object::DYNAMIC);
111 
112     group->addChild(_textDrawable.get());
113 
114     style->setupClipStateSet(_extents, getOrCreateWidgetStateSet());
115 
116     setGraphicsSubgraph(0, group.get());
117 }
118 
119 void PushButton::pressedImplementation()
120 {
121     _buttonSwitch->setSingleChildOn(2);
122 }
123 
124 void PushButton::releasedImplementation()
125 {
126     _buttonSwitch->setSingleChildOn(1);
127 }
128