OpenWalnut  1.5.0dev
WEEGViewHandler.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <cstddef>
26 #include <memory>
27 
28 #include <osg/ref_ptr>
29 #include <osgGA/GUIActionAdapter>
30 #include <osgGA/GUIEventAdapter>
31 
32 #include "WEEGEvent.h"
33 #include "WEEGViewHandler.h"
34 #include "core/common/WAssert.h"
35 #include "core/common/WFlag.h"
36 #include "core/common/WPropertyTypes.h"
37 #include "core/common/WPropertyVariable.h"
38 #include "core/common/exceptions/WOutOfBounds.h"
39 #include "core/dataHandler/WDataSetDipoles.h"
40 #include "core/dataHandler/WEEG2.h"
41 #include "core/graphicsEngine/WGEGroupNode.h"
42 
43 
44 WEEGViewHandler::WEEGViewHandler( WPropInt labelsWidth,
45  WPropDouble timePos,
46  WPropDouble timeRange,
47  WPropInt graphWidth,
48  WPropDouble yPos,
49  WPropDouble ySpacing,
50  WPropDouble ySensitivity,
51  WPropDouble colorSensitivity,
52  std::shared_ptr< WFlag< std::shared_ptr< WEEGEvent > > > event,
53  osg::ref_ptr< WGEGroupNode > eventParentNode,
54  std::shared_ptr< WEEG2 > eeg,
55  std::size_t segmentID,
56  WPropBool snapToDipole,
57  WPropBool proofOfConcept,
58  std::shared_ptr< WDataSetDipoles > dipoles )
59  : m_labelsWidth( labelsWidth ),
60  m_timePos( timePos ),
61  m_timeRange( timeRange ),
62  m_graphWidth( graphWidth ),
63  m_yPos( yPos ),
64  m_ySpacing( ySpacing ),
65  m_ySensitivity( ySensitivity ),
66  m_colorSensitivity( colorSensitivity ),
67  m_event( event ),
68  m_eventParentNode( eventParentNode ),
69  m_eeg( eeg ),
70  m_segmentID( segmentID ),
71  m_snapToDipole( snapToDipole ),
72  m_proofOfConcept( proofOfConcept ),
73  m_dipoles( dipoles )
74 {
75  WAssert( eventParentNode.valid(), "No Event Parent Node" );
76  WAssert( eeg, "No EEG data" );
77  WAssert( segmentID < eeg->getNumberOfSegments(), "Invalid segment number" );
78 }
79 
80 bool WEEGViewHandler::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& /*aa*/ )
81 {
82  bool handled = false;
83 
84  switch( ea.getEventType() )
85  {
86  case osgGA::GUIEventAdapter::PUSH:
87  {
88  if( ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON )
89  {
90  // mark an event position
91  handled = markEvent( ea.getX() );
92  }
93  else if( ea.getButton() == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON
94  || ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON )
95  {
96  // save old mouse positions for panning and zooming
97  m_oldX = ea.getX();
98  m_oldY = ea.getY();
99 
100  handled = true;
101  }
102 
103  break;
104  }
105  case osgGA::GUIEventAdapter::DRAG:
106  {
107  if( ea.getButtonMask() & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON )
108  {
109  // mark an event position
110  handled = markEvent( ea.getX() );
111  }
112 
113  if( ea.getButtonMask() & ( osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON | osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON ) )
114  {
115  if( ea.getButtonMask() & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON )
116  {
117  // panning
118  m_timePos->set( m_timePos->get() - ( ea.getX() - m_oldX ) * m_timeRange->get() / m_graphWidth->get() );
119  m_yPos->set( m_yPos->get() - ( ea.getY() - m_oldY ) );
120  }
121 
122  if( ea.getButtonMask() & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON )
123  {
124  // zooming in time
125  const int labelsWidth = m_labelsWidth->get();
126  if( labelsWidth < m_oldX && labelsWidth < ea.getX() )
127  {
128  m_timeRange->set( m_timeRange->get() * ( ( m_oldX - labelsWidth ) / ( ea.getX() - labelsWidth ) ) );
129  }
130  }
131 
132  // save old mouse positions
133  m_oldX = ea.getX();
134  m_oldY = ea.getY();
135 
136  handled = true;
137  }
138 
139  break;
140  }
141  case osgGA::GUIEventAdapter::RESIZE:
142  {
143  // windows resize
144  m_graphWidth->set( ea.getWindowWidth() - m_labelsWidth->get() );
145 
146  handled = true;
147 
148  break;
149  }
150  case osgGA::GUIEventAdapter::SCROLL:
151  {
152  float delta;
153  switch( ea.getScrollingMotion() )
154  {
155  case osgGA::GUIEventAdapter::SCROLL_UP:
156  {
157  delta = 120.0f;
158  break;
159  }
160  case osgGA::GUIEventAdapter::SCROLL_DOWN:
161  {
162  delta = -120.0f;
163  break;
164  }
165  case osgGA::GUIEventAdapter::SCROLL_2D:
166  {
167  delta = ea.getScrollingDeltaY();
168  break;
169  }
170  default:
171  {
172  delta = 0.0f;
173  break;
174  }
175  }
176 
177  if( delta != 0.0f )
178  {
179  switch( ea.getButtonMask() )
180  {
181  case osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON:
182  {
183  // change the sensitivity of the color map
184  m_colorSensitivity->set( m_colorSensitivity->get() * ( 1.0f + 0.001f * delta ) );
185 
186  handled = true;
187  break;
188  }
189  case osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON:
190  {
191  // change the spacing of the different graphs
192  const float addend = -0.001f * delta;
193  m_ySpacing->set( m_ySpacing->get() * ( 1.0f + addend ) );
194 
195  // adjust yPos to zoom into the current mouse position
196  m_yPos->set( m_yPos->get() * ( 1.0f + addend ) + ea.getY() * addend );
197 
198  handled = true;
199  break;
200  }
201  case 0u: // no button pressed
202  {
203  // change the sensitivity of the graphs
204  m_ySensitivity->set( m_ySensitivity->get() * ( 1.0f + 0.001f * delta ) );
205 
206  handled = true;
207  break;
208  }
209  default:
210  {
211  // do nothing
212  break;
213  }
214  }
215  }
216 
217  break;
218  }
219  default:
220  {
221  // do nothing
222  break;
223  }
224  }
225  return handled;
226 }
227 
229 {
230  bool handled = false;
231  const int labelsWidth = m_labelsWidth->get();
232  if( labelsWidth <= x )
233  {
234  try
235  {
236  std::shared_ptr< WEEGEvent > event( new WEEGEvent(
237  m_timePos->get() + ( x - labelsWidth ) * m_timeRange->get() / m_graphWidth->get(),
238  m_yPos->get(),
239  m_eeg,
240  m_segmentID,
242  m_snapToDipole->get(),
243  m_proofOfConcept->get(),
244  m_dipoles ) );
245  m_event->set( event );
246  handled = true;
247  }
248  catch( const WOutOfBounds& )
249  {
250  // do nothing
251  }
252  }
253  return handled;
254 }
A special time position in an EEG recording with corresponding data.
Definition: WEEGEvent.h:45
bool markEvent(float x)
Update the event position according to the clicked position.
std::size_t m_segmentID
number of the segment
WPropDouble m_colorSensitivity
The sensitivity of the color map as property.
WPropInt m_graphWidth
the width of the graph in pixel as property
float m_oldY
previous mouse y position
WPropDouble m_timePos
the time position in seconds where to start the graph at the left edge as property
WPropDouble m_ySpacing
the distance between two curves of the graph in pixel as property
WPropDouble m_timeRange
the width of the graph in seconds as property
WPropDouble m_yPos
the y position in pixel at the lower edge as property
std::shared_ptr< WDataSetDipoles > m_dipoles
Pointer to the loaded dipoles dataset.
WEEGViewHandler(WPropInt labelsWidth, WPropDouble timePos, WPropDouble timeRange, WPropInt graphWidth, WPropDouble yPos, WPropDouble ySpacing, WPropDouble ySensitivity, WPropDouble colorSensitivity, std::shared_ptr< WFlag< std::shared_ptr< WEEGEvent > > > event, osg::ref_ptr< WGEGroupNode > eventParentNode, std::shared_ptr< WEEG2 > eeg, std::size_t segmentID, WPropBool snapToDipole, WPropBool proofOfConcept, std::shared_ptr< WDataSetDipoles > dipoles)
Constructor.
WPropInt m_labelsWidth
the width of the label display in pixel as property
WPropDouble m_ySensitivity
the sensitivity of the graph in microvolt per pixel as property
osg::ref_ptr< WGEGroupNode > m_eventParentNode
parent node, where an marked event position is inserted and removed from
float m_oldX
previous mouse x position
std::shared_ptr< WFlag< std::shared_ptr< WEEGEvent > > > m_event
event marking a special time position as WFlag
virtual bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &)
Handle events.
WPropBool m_proofOfConcept
Property determining whether we only show the proof of concept or the real dipoles.
std::shared_ptr< WEEG2 > m_eeg
pointer to the loaded EEG dataset
WPropBool m_snapToDipole
Property determining whether the selected time position should be snapped to an active dipole.
Class to have a simple notification/condition system for simple flags.
Definition: WFlag.h:39
Indicates invalid element access of a container.
Definition: WOutOfBounds.h:37