Fix keymap.
[vuplus_xbmc] / xbmc / guilib / GUIMoverControl.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "GUIMoverControl.h"
22 #include "GUIWindowManager.h"
23 #include "Key.h"
24 #include "utils/TimeUtils.h"
25
26 // time to reset accelerated cursors (digital movement)
27 #define MOVE_TIME_OUT 500L
28
29 CGUIMoverControl::CGUIMoverControl(int parentID, int controlID, float posX, float posY, float width, float height, const CTextureInfo& textureFocus, const CTextureInfo& textureNoFocus)
30     : CGUIControl(parentID, controlID, posX, posY, width, height)
31     , m_imgFocus(posX, posY, width, height, textureFocus)
32     , m_imgNoFocus(posX, posY, width, height, textureNoFocus)
33 {
34   m_frameCounter = 0;
35   m_lastMoveTime = 0;
36   m_fSpeed = 1.0;
37   m_fAnalogSpeed = 2.0f; // TODO: implement correct analog speed
38   m_fAcceleration = 0.2f; // TODO: implement correct computation of acceleration
39   m_fMaxSpeed = 10.0;  // TODO: implement correct computation of maxspeed
40   ControlType = GUICONTROL_MOVER;
41   SetLimits(0, 0, 720, 576); // defaults
42   SetLocation(0, 0, false);  // defaults
43 }
44
45 CGUIMoverControl::~CGUIMoverControl(void)
46 {}
47
48 void CGUIMoverControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
49 {
50   if (m_bInvalidated)
51   {
52     m_imgFocus.SetWidth(m_width);
53     m_imgFocus.SetHeight(m_height);
54
55     m_imgNoFocus.SetWidth(m_width);
56     m_imgNoFocus.SetHeight(m_height);
57   }
58   if (HasFocus())
59   {
60     unsigned int alphaCounter = m_frameCounter + 2;
61     unsigned int alphaChannel;
62     if ((alphaCounter % 128) >= 64)
63       alphaChannel = alphaCounter % 64;
64     else
65       alphaChannel = 63 - (alphaCounter % 64);
66
67     alphaChannel += 192;
68     if (SetAlpha( (unsigned char)alphaChannel ))
69       MarkDirtyRegion();
70     m_imgFocus.SetVisible(true);
71     m_imgNoFocus.SetVisible(false);
72     m_frameCounter++;
73   }
74   else
75   {
76     if (SetAlpha(0xff))
77       MarkDirtyRegion();
78     m_imgFocus.SetVisible(false);
79     m_imgNoFocus.SetVisible(true);
80   }
81   m_imgFocus.Process(currentTime);
82   m_imgNoFocus.Process(currentTime);
83
84   CGUIControl::Process(currentTime, dirtyregions);
85 }
86
87 void CGUIMoverControl::Render()
88 {
89   // render both so the visibility settings cause the frame counter to resetcorrectly
90   m_imgFocus.Render();
91   m_imgNoFocus.Render();
92   CGUIControl::Render();
93 }
94
95 bool CGUIMoverControl::OnAction(const CAction &action)
96 {
97   if (action.GetID() == ACTION_SELECT_ITEM)
98   {
99     // button selected - send message to parent
100     CGUIMessage message(GUI_MSG_CLICKED, GetID(), GetParentID());
101     SendWindowMessage(message);
102     return true;
103   }
104   if (action.GetID() == ACTION_ANALOG_MOVE)
105   {
106     //  if (m_dwAllowedDirections == ALLOWED_DIRECTIONS_UPDOWN)
107     //   Move(0, (int)(-m_fAnalogSpeed*action.GetAmount(1)));
108     //  else if (m_dwAllowedDirections == ALLOWED_DIRECTIONS_LEFTRIGHT)
109     //   Move((int)(m_fAnalogSpeed*action.GetAmount()), 0);
110     //  else // ALLOWED_DIRECTIONS_ALL
111     Move((int)(m_fAnalogSpeed*action.GetAmount()), (int)( -m_fAnalogSpeed*action.GetAmount(1)));
112     return true;
113   }
114   // base class
115   return CGUIControl::OnAction(action);
116 }
117
118 void CGUIMoverControl::OnUp()
119 {
120   // if (m_dwAllowedDirections == ALLOWED_DIRECTIONS_LEFTRIGHT) return;
121   UpdateSpeed(DIRECTION_UP);
122   Move(0, (int) - m_fSpeed);
123 }
124
125 void CGUIMoverControl::OnDown()
126 {
127   // if (m_dwAllowedDirections == ALLOWED_DIRECTIONS_LEFTRIGHT) return;
128   UpdateSpeed(DIRECTION_DOWN);
129   Move(0, (int)m_fSpeed);
130 }
131
132 void CGUIMoverControl::OnLeft()
133 {
134   // if (m_dwAllowedDirections == ALLOWED_DIRECTIONS_UPDOWN) return;
135   UpdateSpeed(DIRECTION_LEFT);
136   Move((int) - m_fSpeed, 0);
137 }
138
139 void CGUIMoverControl::OnRight()
140 {
141   // if (m_dwAllowedDirections == ALLOWED_DIRECTIONS_UPDOWN) return;
142   UpdateSpeed(DIRECTION_RIGHT);
143   Move((int)m_fSpeed, 0);
144 }
145
146 EVENT_RESULT CGUIMoverControl::OnMouseEvent(const CPoint &point, const CMouseEvent &event)
147 {
148   if (event.m_id == ACTION_MOUSE_DRAG)
149   {
150     if (event.m_state == 1)
151     { // grab exclusive access
152       CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, GetID(), GetParentID());
153       SendWindowMessage(msg);
154     }
155     else if (event.m_state == 3)
156     { // release exclusive access
157       CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, 0, GetParentID());
158       SendWindowMessage(msg);
159     }
160     Move((int)event.m_offsetX, (int)event.m_offsetY);
161     return EVENT_RESULT_HANDLED;
162   }
163   return EVENT_RESULT_UNHANDLED;
164 }
165
166 void CGUIMoverControl::UpdateSpeed(int nDirection)
167 {
168   if (CTimeUtils::GetFrameTime() - m_lastMoveTime > MOVE_TIME_OUT)
169   {
170     m_fSpeed = 1;
171     m_nDirection = DIRECTION_NONE;
172   }
173   m_lastMoveTime = CTimeUtils::GetFrameTime();
174   if (nDirection == m_nDirection)
175   { // accelerate
176     m_fSpeed += m_fAcceleration;
177     if (m_fSpeed > m_fMaxSpeed) m_fSpeed = m_fMaxSpeed;
178   }
179   else
180   { // reset direction and speed
181     m_fSpeed = 1;
182     m_nDirection = nDirection;
183   }
184 }
185
186 void CGUIMoverControl::AllocResources()
187 {
188   CGUIControl::AllocResources();
189   m_frameCounter = 0;
190   m_imgFocus.AllocResources();
191   m_imgNoFocus.AllocResources();
192   float width = m_width ? m_width : m_imgFocus.GetWidth();
193   float height = m_height ? m_height : m_imgFocus.GetHeight();
194   SetWidth(width);
195   SetHeight(height);
196 }
197
198 void CGUIMoverControl::FreeResources(bool immediately)
199 {
200   CGUIControl::FreeResources(immediately);
201   m_imgFocus.FreeResources(immediately);
202   m_imgNoFocus.FreeResources(immediately);
203 }
204
205 void CGUIMoverControl::DynamicResourceAlloc(bool bOnOff)
206 {
207   CGUIControl::DynamicResourceAlloc(bOnOff);
208   m_imgFocus.DynamicResourceAlloc(bOnOff);
209   m_imgNoFocus.DynamicResourceAlloc(bOnOff);
210 }
211
212 void CGUIMoverControl::SetInvalid()
213 {
214   CGUIControl::SetInvalid();
215   m_imgFocus.SetInvalid();
216   m_imgNoFocus.SetInvalid();
217 }
218
219 void CGUIMoverControl::Move(int iX, int iY)
220 {
221   int iLocX = m_iLocationX + iX;
222   int iLocY = m_iLocationY + iY;
223   // check if we are within the bounds
224   if (iLocX < m_iX1) iLocX = m_iX1;
225   if (iLocY < m_iY1) iLocY = m_iY1;
226   if (iLocX > m_iX2) iLocX = m_iX2;
227   if (iLocY > m_iY2) iLocY = m_iY2;
228   // ok, now set the location of the mover
229   SetLocation(iLocX, iLocY);
230 }
231
232 void CGUIMoverControl::SetLocation(int iLocX, int iLocY, bool bSetPosition)
233 {
234   if (bSetPosition) SetPosition(GetXPosition() + iLocX - m_iLocationX, GetYPosition() + iLocY - m_iLocationY);
235   m_iLocationX = iLocX;
236   m_iLocationY = iLocY;
237 }
238
239 void CGUIMoverControl::SetPosition(float posX, float posY)
240 {
241   CGUIControl::SetPosition(posX, posY);
242   m_imgFocus.SetPosition(posX, posY);
243   m_imgNoFocus.SetPosition(posX, posY);
244 }
245
246 bool CGUIMoverControl::SetAlpha(unsigned char alpha)
247 {
248   return m_imgFocus.SetAlpha(alpha) | 
249          m_imgNoFocus.SetAlpha(alpha);
250 }
251
252 bool CGUIMoverControl::UpdateColors()
253 {
254   bool changed = CGUIControl::UpdateColors();
255   changed |= m_imgFocus.SetDiffuseColor(m_diffuseColor);
256   changed |= m_imgNoFocus.SetDiffuseColor(m_diffuseColor);
257
258   return changed;
259 }
260
261 void CGUIMoverControl::SetLimits(int iX1, int iY1, int iX2, int iY2)
262 {
263   m_iX1 = iX1;
264   m_iY1 = iY1;
265   m_iX2 = iX2;
266   m_iY2 = iY2;
267 }