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 #include <osgUI/Callbacks>
15 #include <osgUI/Widget>
16 #include <osgUI/Dialog>
17
18 #include <osg/ValueObject>
19 #include <osg/MatrixTransform>
20 #include <osg/io_utils>
21
22 using namespace osgUI;
23
CloseCallback(const std::string & callbackName,osgUI::Widget * closeWidget)24 CloseCallback::CloseCallback(const std::string& callbackName, osgUI::Widget* closeWidget):
25 _closeWidget(closeWidget)
26 {
27 setName(callbackName);
28 }
29
CloseCallback(const CloseCallback & hc,const osg::CopyOp & copyop)30 CloseCallback::CloseCallback(const CloseCallback& hc, const osg::CopyOp& copyop)
31 {
32 }
33
run(osg::Object * object,osg::Parameters &,osg::Parameters &) const34 bool CloseCallback::run(osg::Object* object, osg::Parameters&, osg::Parameters&) const
35 {
36 if (_closeWidget.valid())
37 {
38 _closeWidget->setVisible(false);
39 }
40
41 osg::Node* node = dynamic_cast<osg::Node*>(object);
42 if (node)
43 {
44 osg::NodePathList nodePathList = node->getParentalNodePaths();
45 for(osg::NodePathList::iterator itr = nodePathList.begin();
46 itr != nodePathList.end();
47 ++itr)
48 {
49 osg::NodePath& nodePath = *itr;
50 for(osg::NodePath::reverse_iterator ritr = nodePath.rbegin();
51 ritr != nodePath.rend();
52 ++ritr)
53 {
54 osgUI::Dialog* dialog = dynamic_cast<osgUI::Dialog*>(*ritr);
55 if (dialog)
56 {
57 dialog->setVisible(false);
58 break;
59 }
60 }
61 }
62 return true;
63 }
64 return false;
65 }
66
HandleCallback()67 HandleCallback::HandleCallback()
68 {
69 setName("handle");
70 }
71
HandleCallback(const HandleCallback & hc,const osg::CopyOp & copyop)72 HandleCallback::HandleCallback(const HandleCallback& hc, const osg::CopyOp& copyop):
73 osg::CallbackObject(hc, copyop)
74 {
75 }
76
run(osg::Object * object,osg::Parameters & inputParameters,osg::Parameters & outputParameters) const77 bool HandleCallback::run(osg::Object* object, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const
78 {
79 if (inputParameters.size()>=2)
80 {
81 osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(inputParameters[0].get());
82 osgGA::Event* event = dynamic_cast<osgGA::Event*>(inputParameters[1].get());
83 if (ev && event)
84 {
85 outputParameters.push_back(new osg::BoolValueObject("return",handle(ev,event)));
86 return true;
87 }
88 }
89 return false;
90 }
91
handle(osgGA::EventVisitor * ev,osgGA::Event * event) const92 bool HandleCallback::handle(osgGA::EventVisitor* ev, osgGA::Event* event) const
93 {
94 return false;
95 }
96
97
DragCallback()98 DragCallback::DragCallback():
99 _dragging(false)
100 {
101 }
102
DragCallback(const DragCallback & hc,const osg::CopyOp & copyop)103 DragCallback::DragCallback(const DragCallback& hc, const osg::CopyOp& copyop):
104 HandleCallback(hc, copyop)
105 {
106 }
107
findNearestTransform(const osg::NodePath & nodePath)108 osg::Transform* findNearestTransform(const osg::NodePath& nodePath)
109 {
110 osg::Transform* transform = 0;
111 for(osg::NodePath::const_reverse_iterator itr = nodePath.rbegin();
112 itr != nodePath.rend();
113 ++itr)
114 {
115 if ((*itr)->asTransform())
116 {
117 transform = (*itr)->asTransform();
118 break;
119 }
120 }
121 return transform;
122 }
123
handle(osgGA::EventVisitor * ev,osgGA::Event * event) const124 bool DragCallback::handle(osgGA::EventVisitor* ev, osgGA::Event* event) const
125 {
126 osgGA::GUIEventAdapter* ea = event ? event->asGUIEventAdapter() : 0;
127 if (!ev || !ea) return false;
128
129 osgUI::Widget* widget = dynamic_cast<osgUI::Widget*>(ev->getNodePath().empty() ? 0 : ev->getNodePath().back());
130 if (widget && widget->getHasEventFocus())
131 {
132 DragCallback* dc = const_cast<DragCallback*>(this);
133 switch(ea->getEventType())
134 {
135 case(osgGA::GUIEventAdapter::SCROLL):
136 {
137 osg::Vec3d localPosition;
138 if (!widget->computeExtentsPositionInLocalCoordinates(ev, ea, localPosition)) break;
139
140 OSG_NOTICE<<"Scroll motion: "<<ea->getScrollingMotion()<<", "<<localPosition<<std::endl;
141 double scale = 1.0;
142
143 switch(ea->getScrollingMotion())
144 {
145 case(osgGA::GUIEventAdapter::SCROLL_UP): scale = 0.9; break;
146 case(osgGA::GUIEventAdapter::SCROLL_DOWN): scale = 1.0/0.9; break;
147 default: break;
148 }
149
150 if (scale!=1.0)
151 {
152 osg::MatrixTransform* transform = dynamic_cast<osg::MatrixTransform*>(findNearestTransform(ev->getNodePath()));
153 if (transform)
154 {
155 transform->setMatrix(
156 osg::Matrixd::translate(-localPosition)*
157 osg::Matrixd::scale(osg::Vec3d(scale, scale, scale))*
158 osg::Matrixd::translate(localPosition)*
159 transform->getMatrix());
160 }
161 }
162
163 break;
164 }
165 case(osgGA::GUIEventAdapter::PUSH):
166 {
167 dc->_dragging = (ea->getButtonMask()==osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON);
168 if (dc->_dragging)
169 {
170 osg::Vec3d localPosition;
171 if (widget->computeExtentsPositionInLocalCoordinates(ev, ea, localPosition))
172
173 {
174 dc->_previousPosition = localPosition;
175 }
176 }
177 break;
178 }
179 case(osgGA::GUIEventAdapter::DRAG):
180 {
181 if (dc->_dragging)
182 {
183 osg::MatrixTransform* transform = dynamic_cast<osg::MatrixTransform*>(findNearestTransform(ev->getNodePath()));
184 if (transform)
185 {
186 osg::Vec3d position;
187 if (widget->computeExtentsPositionInLocalCoordinates(ev, ea, position, false))
188 {
189 osg::Vec3d delta = position-_previousPosition;
190 osg::MatrixTransform* mt = transform->asMatrixTransform();
191 mt->setMatrix(osg::Matrixd::translate(delta)*mt->getMatrix());
192 // OSG_NOTICE<<"Move to local "<<position<<", "<<position-_previousPosition<<std::endl;
193 }
194 }
195 else
196 {
197 OSG_NOTICE<<"Failed to drag, No Transform to move"<<std::endl;
198 }
199 }
200 break;
201 }
202 case(osgGA::GUIEventAdapter::RELEASE):
203 dc->_dragging = false;
204 default:
205 break;
206 }
207 }
208 return false;
209 }
210