Spinning Topp Logo BlackTopp Studios
inc
mouse.cpp
1 // © Copyright 2010 - 2016 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _inputmouse_cpp
41 #define _inputmouse_cpp
42 
43 #include "Input/mouse.h"
44 #include "Graphics/viewport.h"
45 #include "Graphics/gamewindow.h"
46 #include "exception.h"
47 
48 #include "timer.h"
49 
50 #include <limits>
51 
52 #include "SDL.h"
53 #include "../src/video/SDL_sysvideo.h"
54 
55 namespace Mezzanine
56 {
57  namespace Input
58  {
60  CurrentViewport(NULL),
61  HorizontalWheelState(Input::DIRECTIONALMOTION_UNCHANGED),
62  VerticalWheelState(Input::DIRECTIONALMOTION_UNCHANGED)
63  {
65 
66  this->MulticlickTimer = new Timer();
69  }
70 
72  {
73  delete MulticlickTimer;
74  }
75 
76  void Mouse::UpdateImpl(const MetaCodeContainer& DeltaCodes, MetaCodeContainer& GeneratedCodes)
77  {
78  /// @todo Getting the mouse focus doesn't do what I originally thought it would. When a mouse leaves a window, the focus isn't set to NULL
79  /// as expected. If you have only one window, then it just stays pointing to that window. If you have two then it will stay on the first
80  /// window until you mouse over the second, even if there is a space between the windows. This should be updated somehow so that we can set
81  /// "HoveredWindow" to NULL when none of our windows are being hovered.
82  // First do some setup. Get the window and save our position.
83  SDL_Window* Focus = SDL_GetMouseFocus();
84  Vector2 OldPosition = this->Position;
85  // Update our states
86  for( Whole X = 0 ; X < DeltaCodes.size() ; ++X )
87  {
88  const MetaCode& CurrCode = DeltaCodes[X];
89  const Input::InputCode ICode = CurrCode.GetCode();
90  if( ICode >= Input::MOUSEBUTTON_FIRST && ICode <= Input::MOUSEBUTTON_LAST ) {
91  // Mark the index for transition on the next update and then place it's state in the button vector
93  Buttons.at( ICode - Input::MOUSEBUTTON_FIRST ) = static_cast<Input::ButtonState>(CurrCode.GetMetaValue());
94  // Now do our checks for multi-click
95  if( this->IsMultiClickable(ICode) && Input::BUTTON_PRESSING == CurrCode.GetMetaValueAsButtonState() ) {
96  /// @todo This code isn't as graceful as I am sure it can be made.
97  // Update our multiclick timer
98  if( this->MulticlickTimer->IsStopped() ) {
100  this->MulticlickCode.SetMetaValue(0);
101  }else{
102  this->MulticlickTimer->Reset(500 * 1000);
103  }
104 
105  const Input::InputCode MCICode = this->ConvertToMultiClickCode(ICode);
106  if( this->MulticlickCode.GetCode() != MCICode ) {
107  this->MulticlickCode.SetMetaValue(1);
108  this->MulticlickCode.SetCode(MCICode);
109  }else{
110  Int32 ClickCount = this->MulticlickCode.GetMetaValue();
111  this->MulticlickCode.SetMetaValue( ++ClickCount );
112  }
113  this->MulticlickTimer->Start();
114  }
115  }else if( Input::MOUSEWHEELVERTICAL == ICode ) {
116  this->VerticalWheelState = static_cast<Input::DirectionalMotionState>(CurrCode.GetMetaValue());
117  }else if( Input::MOUSEWHEELHORIZONTAL == ICode ) {
118  this->HorizontalWheelState = static_cast<Input::DirectionalMotionState>(CurrCode.GetMetaValue());
119  }
120  // Only if we're on a window
121  if( Focus ) {
122  if( Input::MOUSEABSOLUTEVERTICAL == ICode ) {
123  this->Position.Y = (Real)(CurrCode.GetMetaValue());
124  }else if( Input::MOUSEABSOLUTEHORIZONTAL == ICode ) {
125  this->Position.X = (Real)(CurrCode.GetMetaValue());
126  }/*else if( Input::MOUSEVERTICAL == ICode ) {
127  Delta.Y = (Real)(CurrCode.GetMetaValue());
128  }else if( Input::MOUSEHORIZONTAL == ICode ) {
129  Delta.X = (Real)(CurrCode.GetMetaValue());
130  }*/
131  }
132  }
133 
134  // Update our current window
135  if( NULL != Focus ) {
136  Graphics::GameWindow* Win = static_cast<Graphics::GameWindow*>(Focus->data->data);
137  for( Graphics::GameWindow::ReverseViewportIterator ViewIt = Win->ReverseBeginViewport() ; ViewIt != Win->ReverseEndViewport() ; ++ViewIt )
138  {
139  Graphics::Viewport* VP = (*ViewIt);
140  if( (this->Position.X >= (Real)(VP->GetActualLeft()) && this->Position.X <= (Real)(VP->GetActualLeft() + VP->GetActualWidth())) &&
141  (this->Position.Y >= (Real)(VP->GetActualTop()) && this->Position.Y <= (Real)(VP->GetActualTop() + VP->GetActualHeight()) ) )
142  {
143  this->CurrentViewport = VP;
144  break;
145  }
146  }
147  }else{
148  this->CurrentViewport = NULL;
149  this->Position.SetIdentity();
150  this->Delta.SetIdentity();
151  }
152  this->Delta = this->Position - OldPosition;
153 
154  // Do our Multiclick check
155  if( this->MulticlickCode.GetMetaValue() > 1 )
156  GeneratedCodes.push_back(MulticlickCode);
157 
158  // Do our sequence updates
159  this->Sequences.Update(DeltaCodes,GeneratedCodes);
160  }
161 
162  void Mouse::VerifySequenceImpl(const MetaCodeContainer& Sequence) const
163  {
164  for( ConstMetaCodeIterator MCIt = Sequence.begin() ; MCIt != Sequence.end() ; ++MCIt )
165  {
166  if( !MCIt->IsMouseEvent() )
167  { MEZZ_EXCEPTION(ExceptionBase::PARAMETERS_EXCEPTION,"Non-Mouse MetaCode detected when attempting to insert an Input Sequence into Mouse input device.") }
168  }
169  }
170 
171  void Mouse::AddPressedButtons(MetaCodeContainer& GeneratedCodes) const
172  {
173  for( UInt32 Index = 0 ; Index < this->Buttons.size() ; ++Index )
174  {
175  if( this->Buttons.at(Index) == Input::BUTTON_DOWN )
176  GeneratedCodes.push_back( MetaCode(Input::BUTTON_DOWN,static_cast<Input::InputCode>(Input::MOUSEBUTTON_FIRST + Index),GetDeviceIndex()) );
177  }
178  }
179 
181  {
182  return (Input::MOUSEBUTTON_1 <= Code && Input::MOUSEBUTTON_2 >= Code);
183  }
184 
186  {
187  switch(Code)
188  {
189  case Input::MOUSEBUTTON_1: return Input::COMPOUNDINPUT_MOUSELEFTMULTICLICK; break;
190  case Input::MOUSEBUTTON_2: return Input::COMPOUNDINPUT_MOUSERIGHTMULTICLICK; break;
191  default:
192  {
193  MEZZ_EXCEPTION(ExceptionBase::PARAMETERS_EXCEPTION,"Attempting to convert unsupported mouse button code into a multiclick code.");
194  }
195  }
196  }
197 
198  ///////////////////////////////////////////////////////////////////////////////
199  // Query Methods
200 
202  { return this->CurrentViewport; }
203 
205  { return ( this->CurrentViewport ? this->CurrentViewport->GetParentWindow() : NULL ); }
206 
208  { return this->Position; }
209 
211  { return this->Position.X; }
212 
214  { return this->Position.Y; }
215 
217  { return ( this->CurrentViewport ? this->Position - Vector2( this->CurrentViewport->GetLeft(),this->CurrentViewport->GetTop() ) : Vector2(0,0) ); }
218 
220  { return this->GetViewportPosition().X; }
221 
223  { return this->GetViewportPosition().Y; }
224 
226  { return this->Delta; }
227 
229  { return this->Delta.X; }
230 
232  { return this->Delta.Y; }
233 
235  { return std::numeric_limits<UInt16>::max(); }
236 
238  { return this->Buttons.at( Button - 1 ); }
239 
241  { return this->Buttons.at( Button - Input::MOUSEBUTTON_FIRST ); }
242 
244  { return this->VerticalWheelState; }
245 
247  { return this->HorizontalWheelState; }
248 
249  ///////////////////////////////////////////////////////////////////////////////
250  // Configuration Methods
251 
253  { SDL_ShowCursor(Visible); }
254 
256  { return 0 != SDL_ShowCursor(-1); }
257 
259  { return 0 == SDL_SetRelativeMouseMode( (Enable?SDL_TRUE:SDL_FALSE) ); }
260 
262  { return SDL_GetRelativeMouseMode(); }
263 
265  { MEZZ_EXCEPTION(ExceptionBase::NOT_IMPLEMENTED_EXCEPTION,"Mouse cursor setting is currently not implemented."); } /// @todo Implement this.
266 
268  { MEZZ_EXCEPTION(ExceptionBase::NOT_IMPLEMENTED_EXCEPTION,"Mouse cursor getting is currently not implemented."); } /// @todo Implement this.
269 
270  ///////////////////////////////////////////////////////////////////////////////
271  // Utility Methods
272 
274  { if(Win) SDL_WarpMouseInWindow(Win->_GetSDLWindowPointer(),(int)Position.X,(int)Position.Y); }
275  }//Input
276 }//Mezzanine
277 
278 #endif
DirectionalMotionState
An Optional listing of values that can be used in a metacode Indicate spin, digital or binary travel ...
int32_t Int32
An 32-bit integer.
Definition: datatypes.h:124
This is the lowest mouse button value, all mice values will be larger of equal to this...
InputCode
The InputCode enum defines all the posible types of inputs.
Whole GetActualTop() const
Gets the top position of the viewport in pixels.
Definition: viewport.cpp:144
Input::InputCode ConvertToMultiClickCode(const Input::InputCode Code) const
Converts a standard mouse button code to the appropriate multiclick code for that button...
Definition: mouse.cpp:185
Boole GetRelativeMode()
Gets whether or not relative mode is enabled.
Definition: mouse.cpp:261
void SetMouseCursor()
Sets the mouse cursor.
Definition: mouse.cpp:264
void SetCode(const Input::InputCode NewCode)
This Sets The InputCode.
Definition: metacode.cpp:238
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
const Input::ButtonState & GetButtonState(const UInt16 Button) const
Definition: mouse.cpp:237
Boole GetCursorVisibility()
Gets the current state of the visibility of the cursor.
Definition: mouse.cpp:255
Vector2 Position
The current screen position of the mouse cursor.
Definition: mouse.h:68
Real GetTop() const
Gets the relative top position of the viewport.
Definition: viewport.cpp:126
Boole IsStopped()
Gets whether or not this Timer is currently running.
Definition: timer.cpp:139
The Last mouse button event, all mouse button event will be lower or equal to this.
const Vector2 & GetWindowPosition() const
Gets the position of the mouse cursor relative to the origin of the window with the mouse focus...
Definition: mouse.cpp:207
#define MEZZ_EXCEPTION(num, desc)
An easy way to throw exceptions with rich information.
Definition: exception.h:3048
Thrown when we just have not coded a thing yet, but we knew what the API should look like...
Definition: exception.h:117
const Input::DirectionalMotionState & GetHorizontalWheelState() const
Gets the current state of the horizontal mouse wheel.
Definition: mouse.cpp:246
Graphics::Viewport * CurrentViewport
The viewport that the mouse cursor is currently in.
Definition: mouse.h:74
Boole IsMultiClickable(const Input::InputCode Code) const
Checks to see if this code pertains to a button we can track multiple clicks for. ...
Definition: mouse.cpp:180
Most Commonly Right click.
Real GetDeltaX() const
Gets the X delta of the mouse position from the last update.
Definition: mouse.cpp:228
MetaCode MulticlickCode
A copy of the current MetaCode being tracked for multi-click detection.
Definition: mouse.h:65
const Input::DirectionalMotionState & GetVerticalWheelState() const
Gets the current state of the vertical mouse wheel.
Definition: mouse.cpp:243
SequenceContainer Sequences
A container for storing and detecting input sequences for an input device.
Definition: device.h:60
Whole GetActualWidth() const
Gets the width of the viewport in pixels.
Definition: viewport.cpp:147
This implements the exception hiearchy for Mezzanine.
ReverseViewportIterator ReverseBeginViewport()
Gets an iterator to the last viewport in this window.
Definition: gamewindow.cpp:267
Int32 GetMetaValue() const
This Returns the MetaValue.
Definition: metacode.cpp:250
ViewportContainer::reverse_iterator ReverseViewportIterator
Reverse Iterator type for Viewport instances stored by this class.
Definition: gamewindow.h:73
float Real
A Datatype used to represent a real floating point number.
Definition: datatypes.h:141
Mouse()
Class constructor.
Definition: mouse.cpp:59
ReverseViewportIterator ReverseEndViewport()
Gets an iterator to one before the first viewport in this window.
Definition: gamewindow.cpp:270
uint16_t UInt16
An 16-bit unsigned integer.
Definition: datatypes.h:122
void WarpCursorToPosition(Graphics::GameWindow *Win, const Vector2 &Position)
Sets the mouse cursor's position to the specified point in the specified window.
Definition: mouse.cpp:273
This class is for creating and managing viewports within a game window.
Definition: viewport.h:65
Real GetDeltaY() const
Gets the Y delta of the mouse position from the last update.
Definition: mouse.cpp:231
Real Y
Coordinate on the Y vector.
Definition: vector2.h:69
Real GetLeft() const
Gets the relative left position of the viewport.
Definition: viewport.cpp:123
UInt16 GetDeviceIndex() const
Gets the device index of this controller.
Definition: mouse.cpp:234
Real GetViewportY() const
Gets the Y position of the mouse relative to the viewport.
Definition: mouse.cpp:222
GameWindow * GetParentWindow() const
Gets the game window this viewport belongs to.
Definition: viewport.cpp:90
Real X
Coordinate on the X vector.
Definition: vector2.h:67
uint32_t UInt32
An 32-bit unsigned integer.
Definition: datatypes.h:126
Boole SetRelativeMode(Boole Enable)
Sets whether or not relative mode is enabled.
Definition: mouse.cpp:258
This is used to represent a point on a 2 dimentional area, such as a screen.
Definition: vector2.h:63
void SetCursorVisibility(Boole Visible)
Sets the visibility of the mouse cursor.
Definition: mouse.cpp:252
std::vector< Whole > TransitioningIndexes
A container of indexes being tracked due to state transitions.
Definition: buttondevice.h:58
Real GetWindowX() const
Gets the X position of the mouse relative to the window.
Definition: mouse.cpp:210
void Start()
Activates the Timer.
Definition: timer.cpp:113
void SetIdentity()
Sets the values of this vector2 to identity values(0,0).
Definition: vector2.cpp:99
Whole GetActualHeight() const
Gets the height of the viewport in pixels.
Definition: viewport.cpp:150
Most commonly left click.
void SetCountMode(const Mezzanine::CountMode Mode)
Sets the mode the timer should use to increment time.
Definition: timer.cpp:101
void SetCurrentTimeInMilliseconds(const Whole Current)
Sets the current time in Milliseconds. The time that resetting sets the Timer to. ...
Definition: timer.cpp:92
void Reset(const Whole StartTime=0)
Sets the current time to an initial value and stops the Timer if it is running.
Definition: timer.cpp:127
Input::InputCode GetCode() const
This Returns the Inputcode.
Definition: metacode.cpp:244
void VerifySequenceImpl(const MetaCodeContainer &Sequence) const
Definition: mouse.cpp:162
void GetMouseCursor()
Gets the current mouse cursor.
Definition: mouse.cpp:267
Real GetViewportX() const
Gets the X position of the mouse relative to the viewport.
Definition: mouse.cpp:219
Thrown when parameters are checked at runtime and found invalid.
Definition: exception.h:108
Input::MetaCode::ConstMetaCodeIterator ConstMetaCodeIterator
Const Iterator type for convenient MetaCode storage.
Definition: metacode.h:355
This Determines the kind of user input.
Definition: metacode.h:93
Input::MetaCode::MetaCodeContainer MetaCodeContainer
Convenience datatype for storage of MetaCodes.
Definition: metacode.h:351
const Vector2 & GetMouseDelta() const
Gets the change in the mouse position from the previous update.
Definition: mouse.cpp:225
Input::DirectionalMotionState HorizontalWheelState
The current state of the horizontal mouse wheel (if present).
Definition: mouse.h:80
Graphics::Viewport * GetHoveredViewport() const
Gets a pointer to the current viewport the mouse cursor is hovered over.
Definition: mouse.cpp:201
The timer counts down, meaning the Timer current time is showing remaining time.
Definition: timer.h:61
Whole GetActualLeft() const
Gets the left position of the viewport in pixels.
Definition: viewport.cpp:141
A basic timer class to assist in timed operations.
Definition: timer.h:67
SDL_Window * _GetSDLWindowPointer()
This will get a pointer to the SDL Window.
Definition: gamewindow.cpp:583
void SetMetaValue(const Int32 Value)
This Sets The MetaValue.
Definition: metacode.cpp:247
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
ButtonState
An Optional listing of value that can be used in a metacode to represent the information of a button ...
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
Real GetWindowY() const
Gets the Y position of the mouse relative to the window.
Definition: mouse.cpp:213
Timer * MulticlickTimer
The timer used to detect multi-clicks.
Definition: mouse.h:77
Input::DirectionalMotionState VerticalWheelState
The current state of the vertical mouse wheel (if present).
Definition: mouse.h:83
void Update(const MetaCodeContainer &NormalCodes, MetaCodeContainer &SequenceCodes)
Adds provided codes to the cache if necessary and checks for sequences that have been met...
Vector2 GetViewportPosition() const
Gets the position of the mouse cursor relative to the origin of the viewport in the window with the m...
Definition: mouse.cpp:216
virtual ~Mouse()
Class destructor.
Definition: mouse.cpp:71
void UpdateImpl(const MetaCodeContainer &DeltaCodes, MetaCodeContainer &GeneratedCodes)
Definition: mouse.cpp:76
Input::ButtonState GetMetaValueAsButtonState() const
Get the MetaValue as a Input::ButtonState.
Definition: metacode.cpp:269
std::vector< Input::ButtonState > Buttons
A container of states for each button on the input device.
Definition: buttondevice.h:61
Graphics::GameWindow * GetHoveredWindow() const
Gets a pointer to the window with the current mouse focus.
Definition: mouse.cpp:204
void AddPressedButtons(MetaCodeContainer &GeneratedCodes) const
Definition: mouse.cpp:171
This class is for creating and managing game windows.
Definition: gamewindow.h:63
Vector2 Delta
The change in the mouse cursor position since the last update.
Definition: mouse.h:71