Fix keymap.
[vuplus_xbmc] / xbmc / guilib / GUIResizeControl.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 "GUIResizeControl.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 CGUIResizeControl::CGUIResizeControl(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_RESIZE;
41   SetLimits(0, 0, 720, 576); // defaults
42   m_nDirection = DIRECTION_NONE;
43 }
44
45 CGUIResizeControl::~CGUIResizeControl(void)
46 {}
47
48 void CGUIResizeControl::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   CGUIControl::Process(currentTime, dirtyregions);
84 }
85
86 void CGUIResizeControl::Render()
87 {
88   m_imgFocus.Render();
89   m_imgNoFocus.Render();
90   CGUIControl::Render();
91 }
92
93 bool CGUIResizeControl::OnAction(const CAction &action)
94 {
95   if (action.GetID() == ACTION_SELECT_ITEM)
96   {
97     // button selected - send message to parent
98     CGUIMessage message(GUI_MSG_CLICKED, GetID(), GetParentID());
99     SendWindowMessage(message);
100     return true;
101   }
102   if (action.GetID() == ACTION_ANALOG_MOVE)
103   {
104     Resize(m_fAnalogSpeed*action.GetAmount(), -m_fAnalogSpeed*action.GetAmount(1));
105     return true;
106   }
107   return CGUIControl::OnAction(action);
108 }
109
110 void CGUIResizeControl::OnUp()
111 {
112   UpdateSpeed(DIRECTION_UP);
113   Resize(0, -m_fSpeed);
114 }
115
116 void CGUIResizeControl::OnDown()
117 {
118   UpdateSpeed(DIRECTION_DOWN);
119   Resize(0, m_fSpeed);
120 }
121
122 void CGUIResizeControl::OnLeft()
123 {
124   UpdateSpeed(DIRECTION_LEFT);
125   Resize(-m_fSpeed, 0);
126 }
127
128 void CGUIResizeControl::OnRight()
129 {
130   UpdateSpeed(DIRECTION_RIGHT);
131   Resize(m_fSpeed, 0);
132 }
133
134 EVENT_RESULT CGUIResizeControl::OnMouseEvent(const CPoint &point, const CMouseEvent &event)
135 {
136   if (event.m_id == ACTION_MOUSE_DRAG)
137   {
138     if (event.m_state == 1)
139     { // grab exclusive access
140       CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, GetID(), GetParentID());
141       SendWindowMessage(msg);
142     }
143     else if (event.m_state == 3)
144     { // release exclusive access
145       CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, 0, GetParentID());
146       SendWindowMessage(msg);
147     }
148     Resize(event.m_offsetX, event.m_offsetY);
149     return EVENT_RESULT_HANDLED;
150   }
151   return EVENT_RESULT_UNHANDLED;
152 }
153
154 void CGUIResizeControl::UpdateSpeed(int nDirection)
155 {
156   if (CTimeUtils::GetFrameTime() - m_lastMoveTime > MOVE_TIME_OUT)
157   {
158     m_fSpeed = 1;
159     m_nDirection = DIRECTION_NONE;
160   }
161   m_lastMoveTime = CTimeUtils::GetFrameTime();
162   if (nDirection == m_nDirection)
163   { // accelerate
164     m_fSpeed += m_fAcceleration;
165     if (m_fSpeed > m_fMaxSpeed) m_fSpeed = m_fMaxSpeed;
166   }
167   else
168   { // reset direction and speed
169     m_fSpeed = 1;
170     m_nDirection = nDirection;
171   }
172 }
173
174 void CGUIResizeControl::AllocResources()
175 {
176   CGUIControl::AllocResources();
177   m_frameCounter = 0;
178   m_imgFocus.AllocResources();
179   m_imgNoFocus.AllocResources();
180   m_width = m_imgFocus.GetWidth();
181   m_height = m_imgFocus.GetHeight();
182 }
183
184 void CGUIResizeControl::FreeResources(bool immediately)
185 {
186   CGUIControl::FreeResources(immediately);
187   m_imgFocus.FreeResources(immediately);
188   m_imgNoFocus.FreeResources(immediately);
189 }
190
191 void CGUIResizeControl::DynamicResourceAlloc(bool bOnOff)
192 {
193   CGUIControl::DynamicResourceAlloc(bOnOff);
194   m_imgFocus.DynamicResourceAlloc(bOnOff);
195   m_imgNoFocus.DynamicResourceAlloc(bOnOff);
196 }
197
198 void CGUIResizeControl::SetInvalid()
199 {
200   CGUIControl::SetInvalid();
201   m_imgFocus.SetInvalid();
202   m_imgNoFocus.SetInvalid();
203 }
204
205 void CGUIResizeControl::Resize(float x, float y)
206 {
207   float width = m_width + x;
208   float height = m_height + y;
209   // check if we are within the bounds
210   if (width < m_x1) width = m_x1;
211   if (height < m_y1) height = m_y1;
212   if (width > m_x2) width = m_x2;
213   if (height > m_y2) height = m_y2;
214   // ok, now set the default size of the resize control
215   SetWidth(width);
216   SetHeight(height);
217 }
218
219 void CGUIResizeControl::SetPosition(float posX, float posY)
220 {
221   CGUIControl::SetPosition(posX, posY);
222   m_imgFocus.SetPosition(posX, posY);
223   m_imgNoFocus.SetPosition(posX, posY);
224 }
225
226 bool CGUIResizeControl::SetAlpha(unsigned char alpha)
227 {
228   return m_imgFocus.SetAlpha(alpha) | 
229          m_imgNoFocus.SetAlpha(alpha);
230 }
231
232 bool CGUIResizeControl::UpdateColors()
233 {
234   bool changed = CGUIControl::UpdateColors();
235   changed |= m_imgFocus.SetDiffuseColor(m_diffuseColor);
236   changed |= m_imgNoFocus.SetDiffuseColor(m_diffuseColor);
237
238   return changed;
239 }
240
241 void CGUIResizeControl::SetLimits(float x1, float y1, float x2, float y2)
242 {
243   m_x1 = x1;
244   m_y1 = y1;
245   m_x2 = x2;
246   m_y2 = y2;
247 }