1 /* 2 * Copyright (C) 2005-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 #pragma once 10 11 #include "windowing/XBMC_events.h" 12 13 #define XBMC_BUTTON(X) (1 << ((X)-1)) 14 #define XBMC_BUTTON_LEFT 1 15 #define XBMC_BUTTON_MIDDLE 2 16 #define XBMC_BUTTON_RIGHT 3 17 #define XBMC_BUTTON_WHEELUP 4 18 #define XBMC_BUTTON_WHEELDOWN 5 19 #define XBMC_BUTTON_X1 6 20 #define XBMC_BUTTON_X2 7 21 #define XBMC_BUTTON_X3 8 22 #define XBMC_BUTTON_X4 9 23 #define XBMC_BUTTON_LMASK XBMC_BUTTON(XBMC_BUTTON_LEFT) 24 #define XBMC_BUTTON_MMASK XBMC_BUTTON(XBMC_BUTTON_MIDDLE) 25 #define XBMC_BUTTON_RMASK XBMC_BUTTON(XBMC_BUTTON_RIGHT) 26 #define XBMC_BUTTON_X1MASK XBMC_BUTTON(XBMC_BUTTON_X1) 27 #define XBMC_BUTTON_X2MASK XBMC_BUTTON(XBMC_BUTTON_X2) 28 #define XBMC_BUTTON_X3MASK XBMC_BUTTON(XBMC_BUTTON_X3) 29 #define XBMC_BUTTON_X4MASK XBMC_BUTTON(XBMC_BUTTON_X4) 30 31 #define MOUSE_MINIMUM_MOVEMENT 2 32 #define MOUSE_DOUBLE_CLICK_LENGTH 500L 33 #define MOUSE_ACTIVE_LENGTH 5000L 34 35 #define MOUSE_MAX_BUTTON 7 36 37 enum MOUSE_STATE 38 { 39 MOUSE_STATE_NORMAL = 1, /*! < Normal state */ 40 MOUSE_STATE_FOCUS, /*! < Control below the mouse is currently in focus */ 41 MOUSE_STATE_DRAG, /*! < A drag operation is being performed */ 42 MOUSE_STATE_CLICK /*! < A mousebutton is being clicked */ 43 }; 44 45 enum MOUSE_BUTTON 46 { 47 MOUSE_LEFT_BUTTON = 0, 48 MOUSE_RIGHT_BUTTON, 49 MOUSE_MIDDLE_BUTTON, 50 MOUSE_EXTRA_BUTTON1, 51 MOUSE_EXTRA_BUTTON2, 52 MOUSE_EXTRA_BUTTON3, 53 MOUSE_EXTRA_BUTTON4 54 }; 55 56 // this holds everything we know about the current state of the mouse 57 struct MouseState 58 { 59 int x; // x location 60 int y; // y location 61 int16_t dx; // change in x 62 int16_t dy; // change in y 63 int8_t dz; // change in z (wheel) 64 bool button[MOUSE_MAX_BUTTON]; // current state of the buttons 65 bool active; // true if the mouse is active 66 }; 67 68 struct MousePosition 69 { 70 int x; 71 int y; 72 }; 73 74 class CAction; 75 76 class CMouseStat 77 { 78 public: 79 CMouseStat(); 80 virtual ~CMouseStat(); 81 82 void Initialize(); 83 void HandleEvent(XBMC_Event& newEvent); 84 void SetResolution(int maxX, int maxY, float speedX, float speedY); 85 bool IsActive(); 86 bool IsEnabled() const; 87 88 void SetActive(bool active = true); SetState(MOUSE_STATE state)89 void SetState(MOUSE_STATE state) { m_pointerState = state; }; 90 void SetEnabled(bool enabled = true); GetState()91 MOUSE_STATE GetState() const { return m_pointerState; }; 92 uint32_t GetKey() const; 93 94 int GetHold(int ButtonID) const; GetX(void)95 inline int GetX(void) const { return m_mouseState.x; } GetY(void)96 inline int GetY(void) const { return m_mouseState.y; } GetDX(void)97 inline int GetDX(void) const { return m_mouseState.dx; } GetDY(void)98 inline int GetDY(void) const { return m_mouseState.dy; } GetPosition()99 MousePosition GetPosition() { return MousePosition{m_mouseState.x, m_mouseState.y}; } 100 101 private: 102 /*! \brief Holds information regarding a particular mouse button state 103 104 The CButtonState class is used to track where in a button event the mouse currently is. 105 There is effectively 5 BUTTON_STATE's available, and transitioning between those states 106 is handled by the Update() function. 107 108 The actions we detect are: 109 * short clicks - down/up press of the mouse within short_click_time ms, where the pointer stays 110 within click_confines pixels 111 * long clicks - down/up press of the mouse greater than short_click_time ms, where the pointers 112 stays within click_confines pixels 113 * double clicks - a further down press of the mouse within double_click_time of the up press of 114 a short click, where the pointer stays within click_confines pixels 115 * drag - the mouse is down and has been moved more than click_confines pixels 116 117 \sa CMouseStat 118 */ 119 class CButtonState 120 { 121 public: 122 /*! \brief enum for the actions to perform as a result of an Update function 123 */ 124 enum BUTTON_ACTION 125 { 126 MB_NONE = 0, ///< no action should occur 127 MB_SHORT_CLICK, ///< a short click has occurred (a double click may be in process) 128 MB_LONG_CLICK, ///< a long click has occurred 129 MB_DOUBLE_CLICK, ///< a double click has occurred 130 MB_DRAG_START, ///< a drag action has started 131 MB_DRAG, ///< a drag action is in progress 132 MB_DRAG_END 133 }; ///< a drag action has finished 134 135 CButtonState(); 136 137 /*! \brief Update the button state, with where the mouse is, and whether the button is down or 138 not 139 140 \param time frame time in ms 141 \param x horizontal coordinate of the mouse 142 \param y vertical coordinate of the mouse 143 \param down true if the button is down 144 \return action that should be performed 145 */ 146 BUTTON_ACTION Update(unsigned int time, int x, int y, bool down); 147 148 private: 149 //! number of pixels that the pointer may move while the button is down to 150 //! trigger a click 151 static const unsigned int click_confines = 5; 152 153 //! Time for mouse down/up to trigger a short click rather than a long click 154 static const unsigned int short_click_time = 1000; 155 156 //! Time for mouse down following a short click to trigger a double click 157 static const unsigned int double_click_time = 500; 158 159 bool InClickRange(int x, int y) const; 160 161 enum BUTTON_STATE 162 { 163 STATE_RELEASED = 0, ///< mouse button is released, no events pending 164 STATE_IN_CLICK, ///< mouse button is down, a click is pending 165 STATE_IN_DOUBLE_CLICK, ///< mouse button is released, pending double click 166 STATE_IN_DOUBLE_IGNORE, ///< mouse button is down following double click 167 STATE_IN_DRAG 168 }; ///< mouse button is down during a drag 169 170 BUTTON_STATE m_state; 171 unsigned int m_time; 172 int m_x; 173 int m_y; 174 }; 175 176 /*! \brief detect whether the mouse has moved 177 178 Uses a trigger threshold of 2 pixels to detect mouse movement 179 180 \return whether the mouse has moved past the trigger threshold. 181 */ 182 bool MovedPastThreshold() const; 183 184 // state of the mouse 185 MOUSE_STATE m_pointerState; 186 MouseState m_mouseState; 187 bool m_mouseEnabled; 188 CButtonState m_buttonState[MOUSE_MAX_BUTTON]; 189 190 int m_maxX; 191 int m_maxY; 192 float m_speedX; 193 float m_speedY; 194 195 // active/click timers 196 unsigned int m_lastActiveTime; 197 198 bool bClick[MOUSE_MAX_BUTTON]; 199 bool bDoubleClick[MOUSE_MAX_BUTTON]; 200 int bHold[MOUSE_MAX_BUTTON]; 201 bool bLongClick[MOUSE_MAX_BUTTON]; 202 203 uint32_t m_Key; 204 }; 205