5 * Copyright (C) 2005-2013 Team XBMC
8 * This Program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
13 * This Program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with XBMC; see the file COPYING. If not, see
20 * <http://www.gnu.org/licenses/>.
24 #include "settings/lib/ISettingCallback.h"
25 #include "windowing/XBMC_events.h"
27 #define XBMC_BUTTON(X) (1 << ((X)-1))
28 #define XBMC_BUTTON_LEFT 1
29 #define XBMC_BUTTON_MIDDLE 2
30 #define XBMC_BUTTON_RIGHT 3
31 #define XBMC_BUTTON_WHEELUP 4
32 #define XBMC_BUTTON_WHEELDOWN 5
33 #define XBMC_BUTTON_X1 6
34 #define XBMC_BUTTON_X2 7
35 #define XBMC_BUTTON_LMASK XBMC_BUTTON(XBMC_BUTTON_LEFT)
36 #define XBMC_BUTTON_MMASK XBMC_BUTTON(XBMC_BUTTON_MIDDLE)
37 #define XBMC_BUTTON_RMASK XBMC_BUTTON(XBMC_BUTTON_RIGHT)
38 #define XBMC_BUTTON_X1MASK XBMC_BUTTON(XBMC_BUTTON_X1)
39 #define XBMC_BUTTON_X2MASK XBMC_BUTTON(XBMC_BUTTON_X2)
41 #define MOUSE_MINIMUM_MOVEMENT 2
42 #define MOUSE_DOUBLE_CLICK_LENGTH 500L
43 #define MOUSE_ACTIVE_LENGTH 5000L
45 enum MOUSE_STATE { MOUSE_STATE_NORMAL = 1, MOUSE_STATE_FOCUS, MOUSE_STATE_DRAG, MOUSE_STATE_CLICK };
46 enum MOUSE_BUTTON { MOUSE_LEFT_BUTTON = 0, MOUSE_RIGHT_BUTTON, MOUSE_MIDDLE_BUTTON, MOUSE_EXTRA_BUTTON1, MOUSE_EXTRA_BUTTON2 };
48 // this holds everything we know about the current state of the mouse
53 int16_t dx; // change in x
54 int16_t dy; // change in y
55 int8_t dz; // change in z (wheel)
56 bool button[5]; // current state of the buttons
57 bool active; // true if the mouse is active
62 class CMouseStat : public ISettingCallback
66 virtual ~CMouseStat();
68 virtual void OnSettingChanged(const CSetting *setting);
71 void HandleEvent(XBMC_Event& newEvent);
72 void SetResolution(int maxX, int maxY, float speedX, float speedY);
74 bool IsEnabled() const;
76 void SetActive(bool active = true);
77 void SetState(MOUSE_STATE state) { m_pointerState = state; };
78 void SetEnabled(bool enabled = true);
79 MOUSE_STATE GetState() const { return m_pointerState; };
80 uint32_t GetAction() const;
82 int GetHold(int ButtonID) const;
83 inline int GetX(void) const { return m_mouseState.x; }
84 inline int GetY(void) const { return m_mouseState.y; }
85 inline int GetDX(void) const { return m_mouseState.dx; }
86 inline int GetDY(void) const { return m_mouseState.dy; }
89 /*! \brief Holds information regarding a particular mouse button state
91 The CButtonState class is used to track where in a button event the mouse currently is.
92 There is effectively 5 BUTTON_STATE's available, and transitioning between those states
93 is handled by the Update() function.
95 The actions we detect are:
96 * short clicks - down/up press of the mouse within short_click_time ms, where the pointer stays within click_confines pixels
97 * long clicks - down/up press of the mouse greater than short_click_time ms, where the pointers stays within click_confines pixels
98 * double clicks - a further down press of the mouse within double_click_time of the up press of a short click, where the pointer stays within click_confines pixels
99 * drag - the mouse is down and has been moved more than click_confines pixels
106 /*! \brief enum for the actions to perform as a result of an Update function
108 enum BUTTON_ACTION { MB_NONE = 0, ///< no action should occur
109 MB_SHORT_CLICK, ///< a short click has occurred (a double click may be in process)
110 MB_LONG_CLICK, ///< a long click has occurred
111 MB_DOUBLE_CLICK, ///< a double click has occurred
112 MB_DRAG_START, ///< a drag action has started
113 MB_DRAG, ///< a drag action is in progress
114 MB_DRAG_END }; ///< a drag action has finished
118 /*! \brief Update the button state, with where the mouse is, and whether the button is down or not
120 \param time frame time in ms
121 \param x horizontal coordinate of the mouse
122 \param y vertical coordinate of the mouse
123 \param down true if the button is down
124 \return action that should be performed
126 BUTTON_ACTION Update(unsigned int time, int x, int y, bool down);
128 static const unsigned int click_confines = 5; ///< number of pixels that the pointer may move while the button is down to trigger a click
129 static const unsigned int short_click_time = 1000; ///< time for mouse down/up to trigger a short click rather than a long click
130 static const unsigned int double_click_time = 500; ///< time for mouse down following a short click to trigger a double click
132 bool InClickRange(int x, int y) const;
134 enum BUTTON_STATE { STATE_RELEASED = 0, ///< mouse button is released, no events pending
135 STATE_IN_CLICK, ///< mouse button is down, a click is pending
136 STATE_IN_DOUBLE_CLICK, ///< mouse button is released, pending double click
137 STATE_IN_DOUBLE_IGNORE, ///< mouse button is down following double click
138 STATE_IN_DRAG }; ///< mouse button is down during a drag
140 BUTTON_STATE m_state;
146 /*! \brief detect whether the mouse has moved
148 Uses a trigger threshold of 2 pixels to detect mouse movement
150 \return whether the mouse has moved past the trigger threshold.
152 bool MovedPastThreshold() const;
154 // state of the mouse
155 MOUSE_STATE m_pointerState;
156 MouseState m_mouseState;
158 CButtonState m_buttonState[5];
165 // active/click timers
166 unsigned int m_lastActiveTime;
169 bool bDoubleClick[5];
175 extern CMouseStat g_Mouse;