[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / guilib / GUISliderControl.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://www.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 "GUISliderControl.h"
22 #include "GUIInfoManager.h"
23 #include "Key.h"
24 #include "utils/MathUtils.h"
25 #include "GUIWindowManager.h"
26
27 static const SliderAction actions[] = {
28   {"seek",    "PlayerControl(SeekPercentage(%2d))", PLAYER_PROGRESS, false},
29   {"volume",  "SetVolume(%2d)",                     PLAYER_VOLUME,   true}
30  };
31
32 CGUISliderControl::CGUISliderControl(int parentID, int controlID, float posX, float posY, float width, float height, const CTextureInfo& backGroundTexture, const CTextureInfo& nibTexture, const CTextureInfo& nibTextureFocus, int iType)
33     : CGUIControl(parentID, controlID, posX, posY, width, height)
34     , m_guiBackground(posX, posY, width, height, backGroundTexture)
35     , m_guiSelectorLower(posX, posY, width, height, nibTexture)
36     , m_guiSelectorUpper(posX, posY, width, height, nibTexture)
37     , m_guiSelectorLowerFocus(posX, posY, width, height, nibTextureFocus)
38     , m_guiSelectorUpperFocus(posX, posY, width, height, nibTextureFocus)
39 {
40   m_iType = iType;
41   m_rangeSelection = false;
42   m_currentSelector = RangeSelectorLower; // use lower selector by default
43   m_percentValues[0] = 0;
44   m_percentValues[1] = 100;
45   m_iStart = 0;
46   m_iEnd = 100;
47   m_iInterval = 1;
48   m_fStart = 0.0f;
49   m_fEnd = 1.0f;
50   m_fInterval = 0.1f;
51   m_intValues[0] = m_iStart;
52   m_intValues[1] = m_iEnd;
53   m_floatValues[0] = m_fStart;
54   m_floatValues[1] = m_fEnd;
55   ControlType = GUICONTROL_SLIDER;
56   m_iInfoCode = 0;
57   m_dragging = false;
58   m_action = NULL;
59 }
60
61 CGUISliderControl::~CGUISliderControl(void)
62 {
63 }
64
65 void CGUISliderControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
66 {
67   bool dirty = false;
68
69   dirty |= m_guiBackground.SetPosition( m_posX, m_posY );
70   int infoCode = m_iInfoCode;
71   if (m_action && (!m_dragging || m_action->fireOnDrag))
72     infoCode = m_action->infoCode;
73   if (infoCode)
74   {
75     int val;
76     if (g_infoManager.GetInt(val, infoCode))
77       SetIntValue(val);
78   }
79
80   float fScaleY = m_height == 0 ? 1.0f : m_height / m_guiBackground.GetTextureHeight();
81
82   dirty |= m_guiBackground.SetHeight(m_height);
83   dirty |= m_guiBackground.SetWidth(m_width);
84   dirty |= m_guiBackground.Process(currentTime);
85
86   CGUITexture &nibLower = (m_bHasFocus && !IsDisabled() && m_currentSelector == RangeSelectorLower) ? m_guiSelectorLowerFocus : m_guiSelectorLower;
87   dirty |= ProcessSelector(nibLower, currentTime, fScaleY, RangeSelectorLower);
88   if (m_rangeSelection)
89   {
90     CGUITexture &nibUpper = (m_bHasFocus && !IsDisabled() && m_currentSelector == RangeSelectorUpper) ? m_guiSelectorUpperFocus : m_guiSelectorUpper;
91     dirty |= ProcessSelector(nibUpper, currentTime, fScaleY, RangeSelectorUpper);
92   }
93
94   if (dirty)
95     MarkDirtyRegion();
96
97   CGUIControl::Process(currentTime, dirtyregions);
98 }
99
100 bool CGUISliderControl::ProcessSelector(CGUITexture &nib, unsigned int currentTime, float fScaleY, RangeSelector selector)
101 {
102   bool dirty = false;
103   // we render the nib centered at the appropriate percentage, except where the nib
104   // would overflow the background image
105   dirty |= nib.SetHeight(nib.GetTextureHeight() * fScaleY);
106   dirty |= nib.SetWidth(nib.GetHeight() * 2);
107   CAspectRatio ratio(CAspectRatio::AR_KEEP);
108   ratio.align = ASPECT_ALIGN_LEFT | ASPECT_ALIGNY_CENTER;
109   dirty |= nib.SetAspectRatio(ratio);
110   dirty |= nib.Process(currentTime);
111   CRect rect = nib.GetRenderRect();
112
113   float offset = GetProportion(selector) * m_width - rect.Width() / 2;
114   if (offset > m_width - rect.Width())
115     offset = m_width - rect.Width();
116   if (offset < 0)
117     offset = 0;
118   dirty |= nib.SetPosition(m_guiBackground.GetXPosition() + offset, m_guiBackground.GetYPosition());
119   dirty |= nib.Process(currentTime); // need to process again as the position may have changed
120
121   return dirty;
122 }
123
124 void CGUISliderControl::Render()
125 {
126   m_guiBackground.Render();
127   CGUITexture &nibLower = (m_bHasFocus && !IsDisabled() && m_currentSelector == RangeSelectorLower) ? m_guiSelectorLowerFocus : m_guiSelectorLower;
128   nibLower.Render();
129   if (m_rangeSelection)
130   {
131     CGUITexture &nibUpper = (m_bHasFocus && !IsDisabled() && m_currentSelector == RangeSelectorUpper) ? m_guiSelectorUpperFocus : m_guiSelectorUpper;
132     nibUpper.Render();
133   }
134   CGUIControl::Render();
135 }
136
137 bool CGUISliderControl::OnMessage(CGUIMessage& message)
138 {
139   if (message.GetControlId() == GetID() )
140   {
141     switch (message.GetMessage())
142     {
143     case GUI_MSG_ITEM_SELECT:
144       SetPercentage( message.GetParam1() );
145       return true;
146       break;
147
148     case GUI_MSG_LABEL_RESET:
149       {
150         SetPercentage(0, RangeSelectorLower);
151         SetPercentage(100, RangeSelectorUpper);
152         return true;
153       }
154       break;
155     }
156   }
157
158   return CGUIControl::OnMessage(message);
159 }
160
161 bool CGUISliderControl::OnAction(const CAction &action)
162 {
163   switch ( action.GetID() )
164   {
165   case ACTION_MOVE_LEFT:
166     //case ACTION_OSD_SHOW_VALUE_MIN:
167     Move(-1);
168     return true;
169
170   case ACTION_MOVE_RIGHT:
171     //case ACTION_OSD_SHOW_VALUE_PLUS:
172     Move(1);
173     return true;
174
175   case ACTION_SELECT_ITEM:
176     // switch between the two sliders
177     SwitchRangeSelector();
178     return true;
179
180   default:
181     break;
182   }
183
184   return CGUIControl::OnAction(action);
185 }
186
187 void CGUISliderControl::Move(int iNumSteps)
188 {
189   bool rangeSwap = false;
190   switch (m_iType)
191   {
192   case SPIN_CONTROL_TYPE_FLOAT:
193     {
194       float &value = m_floatValues[m_currentSelector];
195       value += m_fInterval * iNumSteps;
196       if (value < m_fStart) value = m_fStart;
197       if (value > m_fEnd) value = m_fEnd;
198       if (m_floatValues[0] > m_floatValues[1])
199       {
200         float valueLower = m_floatValues[0];
201         m_floatValues[0] = m_floatValues[1];
202         m_floatValues[1] = valueLower;
203         rangeSwap = true;
204       }
205       break;
206     }
207
208   case SPIN_CONTROL_TYPE_INT:
209     {
210       int &value = m_intValues[m_currentSelector];
211       value += m_iInterval * iNumSteps;
212       if (value < m_iStart) value = m_iStart;
213       if (value > m_iEnd) value = m_iEnd;
214       if (m_intValues[0] > m_intValues[1])
215       {
216         int valueLower = m_intValues[0];
217         m_intValues[0] = m_intValues[1];
218         m_intValues[1] = valueLower;
219         rangeSwap = true;
220       }
221       break;
222     }
223
224   default:
225     {
226       int &value = m_percentValues[m_currentSelector];
227       value += m_iInterval * iNumSteps;
228       if (value < 0) value = 0;
229       if (value > 100) value = 100;
230       if (m_percentValues[0] > m_percentValues[1])
231       {
232         int valueLower = m_percentValues[0];
233         m_percentValues[0] = m_percentValues[1];
234         m_percentValues[1] = valueLower;
235         rangeSwap = true;
236       }
237       break;
238     }
239   }
240
241   if (rangeSwap)
242     SwitchRangeSelector();
243
244   SendClick();
245 }
246
247 void CGUISliderControl::SendClick()
248 {
249   int percent = MathUtils::round_int(100*GetProportion());
250   SEND_CLICK_MESSAGE(GetID(), GetParentID(), percent);
251   if (m_action && (!m_dragging || m_action->fireOnDrag))
252   {
253     CStdString action;
254     action.Format(m_action->formatString, percent);
255     CGUIMessage message(GUI_MSG_EXECUTE, m_controlID, m_parentID);
256     message.SetStringParam(action);
257     g_windowManager.SendMessage(message);    
258   }
259 }
260
261 void CGUISliderControl::SetRangeSelection(bool rangeSelection)
262 {
263   if (m_rangeSelection == rangeSelection)
264     return;
265
266   m_rangeSelection = rangeSelection;
267   SetRangeSelector(RangeSelectorLower);
268   SetInvalid();
269 }
270
271 void CGUISliderControl::SetRangeSelector(RangeSelector selector)
272 {
273   if (m_currentSelector == selector)
274     return;
275
276   m_currentSelector = selector;
277   SetInvalid();
278 }
279
280 void CGUISliderControl::SwitchRangeSelector()
281 {
282   if (m_currentSelector == RangeSelectorLower)
283     SetRangeSelector(RangeSelectorUpper);
284   else
285     SetRangeSelector(RangeSelectorLower);
286 }
287
288 void CGUISliderControl::SetPercentage(int iPercent, RangeSelector selector /* = RangeSelectorLower */, bool updateCurrent /* = false */)
289 {
290   if (iPercent > 100) iPercent = 100;
291   else if (iPercent < 0) iPercent = 0;
292
293   int iPercentLower = selector == RangeSelectorLower ? iPercent : m_percentValues[0];
294   int iPercentUpper = selector == RangeSelectorUpper ? iPercent : m_percentValues[1];
295
296   if (!m_rangeSelection || iPercentLower <= iPercentUpper)
297   {
298     m_percentValues[0] = iPercentLower;
299     m_percentValues[1] = iPercentUpper;
300     if (updateCurrent)
301       m_currentSelector = selector;
302   }
303   else
304   {
305     m_percentValues[0] = iPercentUpper;
306     m_percentValues[1] = iPercentLower;
307     if (updateCurrent)
308         m_currentSelector = (selector == RangeSelectorLower ? RangeSelectorUpper : RangeSelectorLower);
309   }
310 }
311
312 int CGUISliderControl::GetPercentage(RangeSelector selector /* = RangeSelectorLower */) const
313 {
314   return m_percentValues[selector];
315 }
316
317 void CGUISliderControl::SetIntValue(int iValue, RangeSelector selector /* = RangeSelectorLower */, bool updateCurrent /* = false */)
318 {
319   if (m_iType == SPIN_CONTROL_TYPE_FLOAT)
320     SetFloatValue((float)iValue);
321   else if (m_iType == SPIN_CONTROL_TYPE_INT)
322   {
323     if (iValue > m_iEnd) iValue = m_iEnd;
324     else if (iValue < m_iStart) iValue = m_iStart;
325
326     int iValueLower = selector == RangeSelectorLower ? iValue : m_intValues[0];
327     int iValueUpper = selector == RangeSelectorUpper ? iValue : m_intValues[1];
328
329     if (!m_rangeSelection || iValueLower <= iValueUpper)
330     {
331       m_intValues[0] = iValueLower;
332       m_intValues[1] = iValueUpper;
333       if (updateCurrent)
334         m_currentSelector = selector;
335     }
336     else
337     {
338       m_intValues[0] = iValueUpper;
339       m_intValues[1] = iValueLower;
340       if (updateCurrent)
341         m_currentSelector = (selector == RangeSelectorLower ? RangeSelectorUpper : RangeSelectorLower);
342     }
343   }
344   else
345     SetPercentage(iValue);
346 }
347
348 int CGUISliderControl::GetIntValue(RangeSelector selector /* = RangeSelectorLower */) const
349 {
350   if (m_iType == SPIN_CONTROL_TYPE_FLOAT)
351     return (int)m_floatValues[selector];
352   else if (m_iType == SPIN_CONTROL_TYPE_INT)
353     return m_intValues[selector];
354   else
355     return m_percentValues[selector];
356 }
357
358 void CGUISliderControl::SetFloatValue(float fValue, RangeSelector selector /* = RangeSelectorLower */, bool updateCurrent /* = false */)
359 {
360   if (m_iType == SPIN_CONTROL_TYPE_FLOAT)
361   {
362     if (fValue > m_fEnd) fValue = m_fEnd;
363     else if (fValue < m_fStart) fValue = m_fStart;
364
365     float fValueLower = selector == RangeSelectorLower ? fValue : m_floatValues[0];
366     float fValueUpper = selector == RangeSelectorUpper ? fValue : m_floatValues[1];
367
368     if (!m_rangeSelection || fValueLower <= fValueUpper)
369     {
370       m_floatValues[0] = fValueLower;
371       m_floatValues[1] = fValueUpper;
372       if (updateCurrent)
373         m_currentSelector = selector;
374     }
375     else
376     {
377       m_floatValues[0] = fValueUpper;
378       m_floatValues[1] = fValueLower;
379       if (updateCurrent)
380         m_currentSelector = (selector == RangeSelectorLower ? RangeSelectorUpper : RangeSelectorLower);
381     }
382   }
383   else if (m_iType == SPIN_CONTROL_TYPE_INT)
384     SetIntValue((int)fValue);
385   else
386     SetPercentage((int)fValue);
387 }
388
389 float CGUISliderControl::GetFloatValue(RangeSelector selector /* = RangeSelectorLower */) const
390 {
391   if (m_iType == SPIN_CONTROL_TYPE_FLOAT)
392     return m_floatValues[selector];
393   else if (m_iType == SPIN_CONTROL_TYPE_INT)
394     return (float)m_intValues[selector];
395   else
396     return (float)m_percentValues[selector];
397 }
398
399 void CGUISliderControl::SetIntInterval(int iInterval)
400 {
401   if (m_iType == SPIN_CONTROL_TYPE_FLOAT)
402     m_fInterval = (float)iInterval;
403   else
404     m_iInterval = iInterval;
405 }
406
407 void CGUISliderControl::SetFloatInterval(float fInterval)
408 {
409   if (m_iType == SPIN_CONTROL_TYPE_FLOAT)
410     m_fInterval = fInterval;
411   else
412     m_iInterval = (int)fInterval;
413 }
414
415 void CGUISliderControl::SetRange(int iStart, int iEnd)
416 {
417   if (m_iType == SPIN_CONTROL_TYPE_FLOAT)
418     SetFloatRange((float)iStart,(float)iEnd);
419   else
420   {
421     m_intValues[0] = m_iStart = iStart;
422     m_intValues[1] = m_iEnd = iEnd;
423   }
424 }
425
426 void CGUISliderControl::SetFloatRange(float fStart, float fEnd)
427 {
428   if (m_iType == SPIN_CONTROL_TYPE_INT)
429     SetRange((int)fStart, (int)fEnd);
430   else
431   {
432     m_floatValues[0] = m_fStart = fStart;
433     m_floatValues[1] = m_fEnd = fEnd;
434   }
435 }
436
437 void CGUISliderControl::FreeResources(bool immediately)
438 {
439   CGUIControl::FreeResources(immediately);
440   m_guiBackground.FreeResources(immediately);
441   m_guiSelectorLower.FreeResources(immediately);
442   m_guiSelectorUpper.FreeResources(immediately);
443   m_guiSelectorLowerFocus.FreeResources(immediately);
444   m_guiSelectorUpperFocus.FreeResources(immediately);
445 }
446
447 void CGUISliderControl::DynamicResourceAlloc(bool bOnOff)
448 {
449   CGUIControl::DynamicResourceAlloc(bOnOff);
450   m_guiBackground.DynamicResourceAlloc(bOnOff);
451   m_guiSelectorLower.DynamicResourceAlloc(bOnOff);
452   m_guiSelectorUpper.DynamicResourceAlloc(bOnOff);
453   m_guiSelectorLowerFocus.DynamicResourceAlloc(bOnOff);
454   m_guiSelectorUpperFocus.DynamicResourceAlloc(bOnOff);
455 }
456
457 void CGUISliderControl::AllocResources()
458 {
459   CGUIControl::AllocResources();
460   m_guiBackground.AllocResources();
461   m_guiSelectorLower.AllocResources();
462   m_guiSelectorUpper.AllocResources();
463   m_guiSelectorLowerFocus.AllocResources();
464   m_guiSelectorUpperFocus.AllocResources();
465 }
466
467 void CGUISliderControl::SetInvalid()
468 {
469   CGUIControl::SetInvalid();
470   m_guiBackground.SetInvalid();
471   m_guiSelectorLower.SetInvalid();
472   m_guiSelectorUpper.SetInvalid();
473   m_guiSelectorLowerFocus.SetInvalid();
474   m_guiSelectorUpperFocus.SetInvalid();
475 }
476
477 bool CGUISliderControl::HitTest(const CPoint &point) const
478 {
479   if (m_guiBackground.HitTest(point)) return true;
480   if (m_guiSelectorLower.HitTest(point)) return true;
481   if (m_rangeSelection && m_guiSelectorUpper.HitTest(point)) return true;
482   return false;
483 }
484
485 void CGUISliderControl::SetFromPosition(const CPoint &point, bool guessSelector /* = false */)
486 {
487   float fPercent = (point.x - m_guiBackground.GetXPosition()) / m_guiBackground.GetWidth();
488   if (fPercent < 0) fPercent = 0;
489   if (fPercent > 1) fPercent = 1;
490
491   if (m_rangeSelection && guessSelector)
492   {
493     // choose selector which value is closer to value calculated from position
494     if (fabs(GetPercentage(RangeSelectorLower) - 100 * fPercent) <= fabs(GetPercentage(RangeSelectorUpper) - 100 * fPercent))
495       m_currentSelector = RangeSelectorLower;
496     else
497       m_currentSelector = RangeSelectorUpper;
498   }
499
500   switch (m_iType)
501   {
502   case SPIN_CONTROL_TYPE_FLOAT:
503     {
504       float fValue = m_fStart + (m_fEnd - m_fStart) * fPercent;
505       SetFloatValue(fValue, m_currentSelector, true);
506       break;
507     }
508
509   case SPIN_CONTROL_TYPE_INT:
510     {
511       int iValue = (int)(m_iStart + (float)(m_iEnd - m_iStart) * fPercent + 0.49f);
512       SetIntValue(iValue, m_currentSelector, true);
513       break;
514     }
515
516   default:
517     {
518       int iValue = (int)(fPercent * 100 + 0.49f);
519       SetPercentage(iValue, m_currentSelector, true);
520       break;
521     }
522   }
523   SendClick();
524 }
525
526 EVENT_RESULT CGUISliderControl::OnMouseEvent(const CPoint &point, const CMouseEvent &event)
527 {
528   m_dragging = false;
529   if (event.m_id == ACTION_MOUSE_DRAG)
530   {
531     m_dragging = true;
532     bool guessSelector = false;
533     if (event.m_state == 1)
534     { // grab exclusive access
535       CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, GetID(), GetParentID());
536       SendWindowMessage(msg);
537       guessSelector = true;
538     }
539     else if (event.m_state == 3)
540     { // release exclusive access
541       m_dragging = false;
542       CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, 0, GetParentID());
543       SendWindowMessage(msg);
544     }
545     SetFromPosition(point, guessSelector);
546     return EVENT_RESULT_HANDLED;
547   }
548   else if (event.m_id == ACTION_MOUSE_LEFT_CLICK && m_guiBackground.HitTest(point))
549   {
550     SetFromPosition(point, true);
551     return EVENT_RESULT_HANDLED;
552   }
553   else if (event.m_id == ACTION_MOUSE_WHEEL_UP)
554   {
555     Move(10);
556     return EVENT_RESULT_HANDLED;
557   }
558   else if (event.m_id == ACTION_MOUSE_WHEEL_DOWN)
559   {
560     Move(-10);
561     return EVENT_RESULT_HANDLED;
562   }
563   else if (event.m_id == ACTION_GESTURE_NOTIFY)
564   {
565     return EVENT_RESULT_PAN_HORIZONTAL_WITHOUT_INERTIA;
566   }  
567   else if (event.m_id == ACTION_GESTURE_BEGIN)
568   { // grab exclusive access
569     CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, GetID(), GetParentID());
570     SendWindowMessage(msg);
571     return EVENT_RESULT_HANDLED;
572   }
573   else if (event.m_id == ACTION_GESTURE_PAN)
574   { // do the drag 
575     SetFromPosition(point);
576     return EVENT_RESULT_HANDLED;
577   }
578   else if (event.m_id == ACTION_GESTURE_END)
579   { // release exclusive access
580     CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, 0, GetParentID());
581     SendWindowMessage(msg);
582     return EVENT_RESULT_HANDLED;
583   }
584   return EVENT_RESULT_UNHANDLED;
585 }
586
587 void CGUISliderControl::SetInfo(int iInfo)
588 {
589   m_iInfoCode = iInfo;
590 }
591
592 CStdString CGUISliderControl::GetDescription() const
593 {
594   if (!m_textValue.IsEmpty())
595     return m_textValue;
596   CStdString description;
597   if (m_iType == SPIN_CONTROL_TYPE_FLOAT)
598   {
599     if (m_rangeSelection)
600       description.Format("[%2.2f, %2.2f]", m_floatValues[0], m_floatValues[1]);
601     else
602       description.Format("%2.2f", m_floatValues[0]);
603   }
604   else if (m_iType == SPIN_CONTROL_TYPE_INT)
605   {
606     if (m_rangeSelection)
607       description.Format("[%i, %i]", m_intValues[0], m_intValues[1]);
608     else
609       description.Format("%i", m_intValues[0]);
610   }
611   else
612   {
613     if (m_rangeSelection)
614       description.Format("[%i%%, %i%%]", m_percentValues[0], m_percentValues[1]);
615     else
616       description.Format("%i%%", m_percentValues[0]);
617   }
618   return description;
619 }
620
621 bool CGUISliderControl::UpdateColors()
622 {
623   bool changed = CGUIControl::UpdateColors();
624   changed |= m_guiBackground.SetDiffuseColor(m_diffuseColor);
625   changed |= m_guiSelectorLower.SetDiffuseColor(m_diffuseColor);
626   changed |= m_guiSelectorUpper.SetDiffuseColor(m_diffuseColor);
627   changed |= m_guiSelectorLowerFocus.SetDiffuseColor(m_diffuseColor);
628   changed |= m_guiSelectorUpperFocus.SetDiffuseColor(m_diffuseColor);
629
630   return changed;
631 }
632
633 float CGUISliderControl::GetProportion(RangeSelector selector /* = RangeSelectorLower */) const
634 {
635   if (m_iType == SPIN_CONTROL_TYPE_FLOAT)
636     return (GetFloatValue(selector) - m_fStart) / (m_fEnd - m_fStart);
637   else if (m_iType == SPIN_CONTROL_TYPE_INT)
638     return (float)(GetIntValue(selector) - m_iStart) / (float)(m_iEnd - m_iStart);
639   return 0.01f * GetPercentage(selector);
640 }
641
642 void CGUISliderControl::SetAction(const CStdString &action)
643 {
644   for (size_t i = 0; i < sizeof(actions)/sizeof(SliderAction); i++)
645   {
646     if (action.CompareNoCase(actions[i].action) == 0)
647     {
648       m_action = &actions[i];
649       return;
650     }
651   }
652   m_action = NULL;
653 }