[ExecString] combine SplitParameters with identical function of CUtil
[xbmc.git] / xbmc / guilib / GUISliderControl.cpp
blob8158f1751be11a33ccef20737d18aee91f4e6f3e
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "GUISliderControl.h"
11 #include "GUIComponent.h"
12 #include "GUIInfoManager.h"
13 #include "GUIWindowManager.h"
14 #include "ServiceBroker.h"
15 #include "guilib/guiinfo/GUIInfoLabels.h"
16 #include "input/actions/Action.h"
17 #include "input/actions/ActionIDs.h"
18 #include "input/mouse/MouseEvent.h"
19 #include "input/mouse/MouseStat.h"
20 #include "utils/MathUtils.h"
21 #include "utils/StringUtils.h"
23 using namespace KODI;
25 static const SliderAction actions[] = {
26 {"seek", "PlayerControl(SeekPercentage({:2f}))", PLAYER_PROGRESS, false},
27 {"pvr.seek", "PVR.SeekPercentage({:2f})", PVR_TIMESHIFT_PROGRESS_PLAY_POS, false},
28 {"volume", "SetVolume({:2f})", PLAYER_VOLUME, true}};
30 CGUISliderControl::CGUISliderControl(int parentID,
31 int controlID,
32 float posX,
33 float posY,
34 float width,
35 float height,
36 const CTextureInfo& backGroundTexture,
37 const CTextureInfo& backGroundTextureDisabled,
38 const CTextureInfo& nibTexture,
39 const CTextureInfo& nibTextureFocus,
40 const CTextureInfo& nibTextureDisabled,
41 int iType,
42 ORIENTATION orientation)
43 : CGUIControl(parentID, controlID, posX, posY, width, height),
44 m_guiBackground(CGUITexture::CreateTexture(posX, posY, width, height, backGroundTexture)),
45 m_guiBackgroundDisabled(
46 CGUITexture::CreateTexture(posX, posY, width, height, backGroundTextureDisabled)),
47 m_guiSelectorLower(CGUITexture::CreateTexture(posX, posY, width, height, nibTexture)),
48 m_guiSelectorUpper(CGUITexture::CreateTexture(posX, posY, width, height, nibTexture)),
49 m_guiSelectorLowerFocus(CGUITexture::CreateTexture(posX, posY, width, height, nibTextureFocus)),
50 m_guiSelectorUpperFocus(CGUITexture::CreateTexture(posX, posY, width, height, nibTextureFocus)),
51 m_guiSelectorLowerDisabled(
52 CGUITexture::CreateTexture(posX, posY, width, height, nibTextureDisabled)),
53 m_guiSelectorUpperDisabled(
54 CGUITexture::CreateTexture(posX, posY, width, height, nibTextureDisabled))
56 m_iType = iType;
57 m_rangeSelection = false;
58 m_currentSelector = RangeSelectorLower; // use lower selector by default
59 m_percentValues[0] = 0;
60 m_percentValues[1] = 100;
61 m_iStart = 0;
62 m_iEnd = 100;
63 m_iInterval = 1;
64 m_fStart = 0.0f;
65 m_fEnd = 1.0f;
66 m_fInterval = 0.1f;
67 m_intValues[0] = m_iStart;
68 m_intValues[1] = m_iEnd;
69 m_floatValues[0] = m_fStart;
70 m_floatValues[1] = m_fEnd;
71 ControlType = GUICONTROL_SLIDER;
72 m_orientation = orientation;
73 m_iInfoCode = 0;
74 m_dragging = false;
75 m_action = NULL;
78 CGUISliderControl::CGUISliderControl(const CGUISliderControl& control)
79 : CGUIControl(control),
80 m_guiBackground(control.m_guiBackground->Clone()),
81 m_guiBackgroundDisabled(control.m_guiBackgroundDisabled->Clone()),
82 m_guiSelectorLower(control.m_guiSelectorLower->Clone()),
83 m_guiSelectorUpper(control.m_guiSelectorUpper->Clone()),
84 m_guiSelectorLowerFocus(control.m_guiSelectorLowerFocus->Clone()),
85 m_guiSelectorUpperFocus(control.m_guiSelectorUpperFocus->Clone()),
86 m_guiSelectorLowerDisabled(control.m_guiSelectorLowerDisabled->Clone()),
87 m_guiSelectorUpperDisabled(control.m_guiSelectorUpperDisabled->Clone()),
88 m_iType(control.m_iType),
89 m_rangeSelection(control.m_rangeSelection),
90 m_currentSelector(control.m_currentSelector),
91 m_percentValues(control.m_percentValues),
92 m_intValues(control.m_intValues),
93 m_iStart(control.m_iStart),
94 m_iInterval(control.m_iInterval),
95 m_iEnd(control.m_iEnd),
96 m_floatValues(control.m_floatValues),
97 m_fStart(control.m_fStart),
98 m_fInterval(control.m_fInterval),
99 m_fEnd(control.m_fEnd),
100 m_iInfoCode(control.m_iInfoCode),
101 m_textValue(control.m_textValue),
102 m_action(control.m_action),
103 m_dragging(control.m_dragging),
104 m_orientation(control.m_orientation)
108 void CGUISliderControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
110 bool dirty = false;
111 CGUITexture* guiBackground =
112 !IsDisabled() ? m_guiBackground.get() : m_guiBackgroundDisabled.get();
114 dirty |= guiBackground->SetPosition(m_posX, m_posY);
115 int infoCode = m_iInfoCode;
116 if (m_action && (!m_dragging || m_action->fireOnDrag))
117 infoCode = m_action->infoCode;
118 if (infoCode)
120 int val;
121 if (CServiceBroker::GetGUI()->GetInfoManager().GetInt(val, infoCode, INFO::DEFAULT_CONTEXT))
122 SetIntValue(val);
125 dirty |= guiBackground->SetHeight(m_height);
126 dirty |= guiBackground->SetWidth(m_width);
127 dirty |= guiBackground->Process(currentTime);
129 CGUITexture* nibLower = nullptr;
130 if (IsActive() && m_bHasFocus && !IsDisabled() && m_currentSelector == RangeSelectorLower)
131 nibLower = m_guiSelectorLowerFocus.get();
132 else if (!IsDisabled())
133 nibLower = m_guiSelectorLower.get();
134 else
135 nibLower = m_guiSelectorLowerDisabled.get();
137 float fScale = 1.0f;
139 if (m_orientation == HORIZONTAL && guiBackground->GetTextureHeight() != 0)
140 fScale = m_height / guiBackground->GetTextureHeight();
141 else if (m_width != 0 && nibLower->GetTextureWidth() != 0)
142 fScale = m_width / nibLower->GetTextureWidth();
143 dirty |= ProcessSelector(guiBackground, nibLower, currentTime, fScale, RangeSelectorLower);
144 if (m_rangeSelection)
146 CGUITexture* nibUpper = nullptr;
147 if (IsActive() && m_bHasFocus && !IsDisabled() && m_currentSelector == RangeSelectorUpper)
148 nibUpper = m_guiSelectorUpperFocus.get();
149 else if (!IsDisabled())
150 nibUpper = m_guiSelectorUpper.get();
151 else
152 nibUpper = m_guiSelectorUpperDisabled.get();
154 if (m_orientation == HORIZONTAL && guiBackground->GetTextureHeight() != 0)
155 fScale = m_height / guiBackground->GetTextureHeight();
156 else if (m_width != 0 && nibUpper->GetTextureWidth() != 0)
157 fScale = m_width / nibUpper->GetTextureWidth();
159 dirty |= ProcessSelector(guiBackground, nibUpper, currentTime, fScale, RangeSelectorUpper);
162 if (dirty)
163 MarkDirtyRegion();
165 CGUIControl::Process(currentTime, dirtyregions);
168 bool CGUISliderControl::ProcessSelector(CGUITexture* background,
169 CGUITexture* nib,
170 unsigned int currentTime,
171 float fScale,
172 RangeSelector selector)
174 bool dirty = false;
175 // we render the nib centered at the appropriate percentage, except where the nib
176 // would overflow the background image
177 if (m_orientation == HORIZONTAL)
179 dirty |= nib->SetHeight(nib->GetTextureHeight() * fScale);
180 dirty |= nib->SetWidth(nib->GetHeight() * 2);
182 else
184 dirty |= nib->SetWidth(nib->GetTextureWidth() * fScale);
185 dirty |= nib->SetHeight(nib->GetWidth() * 2);
187 CAspectRatio ratio(CAspectRatio::AR_KEEP);
188 ratio.align = ASPECT_ALIGN_LEFT | ASPECT_ALIGNY_CENTER;
189 dirty |= nib->SetAspectRatio(ratio);
190 dirty |= nib->Process(currentTime);
191 CRect rect = nib->GetRenderRect();
193 float offset;
194 if (m_orientation == HORIZONTAL)
196 offset = GetProportion(selector) * m_width - rect.Width() / 2;
197 if (offset > m_width - rect.Width())
198 offset = m_width - rect.Width();
199 if (offset < 0)
200 offset = 0;
201 dirty |= nib->SetPosition(background->GetXPosition() + offset, background->GetYPosition());
203 else
205 offset = GetProportion(selector) * m_height - rect.Height() / 2;
206 if (offset > m_height - rect.Height())
207 offset = m_height - rect.Height();
208 if (offset < 0)
209 offset = 0;
210 dirty |= nib->SetPosition(background->GetXPosition(),
211 background->GetYPosition() + background->GetHeight() - offset -
212 ((nib->GetHeight() - rect.Height()) / 2 + rect.Height()));
214 dirty |= nib->Process(currentTime); // need to process again as the position may have changed
216 return dirty;
219 void CGUISliderControl::Render()
221 if (!IsDisabled())
222 m_guiBackground->Render();
223 else
224 m_guiBackgroundDisabled->Render();
226 CGUITexture* nibLower = nullptr;
227 if (IsActive() && m_bHasFocus && !IsDisabled() && m_currentSelector == RangeSelectorLower)
228 nibLower = m_guiSelectorLowerFocus.get();
229 else if (!IsDisabled())
230 nibLower = m_guiSelectorLower.get();
231 else
232 nibLower = m_guiSelectorLowerDisabled.get();
233 nibLower->Render();
234 if (m_rangeSelection)
236 CGUITexture* nibUpper = nullptr;
237 if (IsActive() && m_bHasFocus && !IsDisabled() && m_currentSelector == RangeSelectorUpper)
238 nibUpper = m_guiSelectorUpperFocus.get();
239 else if (!IsDisabled())
240 nibUpper = m_guiSelectorUpper.get();
241 else
242 nibUpper = m_guiSelectorUpperDisabled.get();
243 nibUpper->Render();
245 CGUIControl::Render();
248 bool CGUISliderControl::OnMessage(CGUIMessage& message)
250 if (message.GetControlId() == GetID() )
252 switch (message.GetMessage())
254 case GUI_MSG_ITEM_SELECT:
255 SetPercentage( (float)message.GetParam1() );
256 return true;
257 break;
259 case GUI_MSG_LABEL_RESET:
261 SetPercentage(0, RangeSelectorLower);
262 SetPercentage(100, RangeSelectorUpper);
263 return true;
265 break;
269 return CGUIControl::OnMessage(message);
272 bool CGUISliderControl::OnAction(const CAction &action)
274 switch ( action.GetID() )
276 case ACTION_MOVE_LEFT:
277 if (IsActive() && m_orientation == HORIZONTAL)
279 Move(-1);
280 return true;
282 break;
284 case ACTION_MOVE_RIGHT:
285 if (IsActive() && m_orientation == HORIZONTAL)
287 Move(1);
288 return true;
290 break;
292 case ACTION_MOVE_UP:
293 if (IsActive() && m_orientation == VERTICAL)
295 Move(1);
296 return true;
298 break;
300 case ACTION_MOVE_DOWN:
301 if (IsActive() && m_orientation == VERTICAL)
303 Move(-1);
304 return true;
306 break;
308 case ACTION_SELECT_ITEM:
309 if (m_rangeSelection)
310 SwitchRangeSelector();
311 return true;
313 default:
314 break;
316 return CGUIControl::OnAction(action);
319 void CGUISliderControl::Move(int iNumSteps)
321 bool rangeSwap = false;
322 switch (m_iType)
324 case SLIDER_CONTROL_TYPE_FLOAT:
326 float &value = m_floatValues[m_currentSelector];
327 value += m_fInterval * iNumSteps;
328 if (value < m_fStart) value = m_fStart;
329 if (value > m_fEnd) value = m_fEnd;
330 if (m_floatValues[0] > m_floatValues[1])
332 float valueLower = m_floatValues[0];
333 m_floatValues[0] = m_floatValues[1];
334 m_floatValues[1] = valueLower;
335 rangeSwap = true;
337 break;
340 case SLIDER_CONTROL_TYPE_INT:
342 int &value = m_intValues[m_currentSelector];
343 value += m_iInterval * iNumSteps;
344 if (value < m_iStart) value = m_iStart;
345 if (value > m_iEnd) value = m_iEnd;
346 if (m_intValues[0] > m_intValues[1])
348 int valueLower = m_intValues[0];
349 m_intValues[0] = m_intValues[1];
350 m_intValues[1] = valueLower;
351 rangeSwap = true;
353 break;
356 case SLIDER_CONTROL_TYPE_PERCENTAGE:
357 default:
359 float &value = m_percentValues[m_currentSelector];
360 value += m_iInterval * iNumSteps;
361 if (value < 0) value = 0;
362 if (value > 100) value = 100;
363 if (m_percentValues[0] > m_percentValues[1])
365 float valueLower = m_percentValues[0];
366 m_percentValues[0] = m_percentValues[1];
367 m_percentValues[1] = valueLower;
368 rangeSwap = true;
370 break;
374 if (rangeSwap)
375 SwitchRangeSelector();
377 SendClick();
380 void CGUISliderControl::SendClick()
382 float percent = 100*GetProportion();
383 SEND_CLICK_MESSAGE(GetID(), GetParentID(), MathUtils::round_int(static_cast<double>(percent)));
384 if (m_action && (!m_dragging || m_action->fireOnDrag))
386 std::string action = StringUtils::Format(m_action->formatString, percent);
387 CGUIMessage message(GUI_MSG_EXECUTE, m_controlID, m_parentID);
388 message.SetStringParam(action);
389 CServiceBroker::GetGUI()->GetWindowManager().SendMessage(message);
393 void CGUISliderControl::SetRangeSelection(bool rangeSelection)
395 if (m_rangeSelection == rangeSelection)
396 return;
398 m_rangeSelection = rangeSelection;
399 SetRangeSelector(RangeSelectorLower);
400 SetInvalid();
403 void CGUISliderControl::SetRangeSelector(RangeSelector selector)
405 if (m_currentSelector == selector)
406 return;
408 m_currentSelector = selector;
409 SetInvalid();
412 void CGUISliderControl::SwitchRangeSelector()
414 if (m_currentSelector == RangeSelectorLower)
415 SetRangeSelector(RangeSelectorUpper);
416 else
417 SetRangeSelector(RangeSelectorLower);
420 void CGUISliderControl::SetPercentage(float percent, RangeSelector selector /* = RangeSelectorLower */, bool updateCurrent /* = false */)
422 if (percent > 100) percent = 100;
423 else if (percent < 0) percent = 0;
425 float percentLower = selector == RangeSelectorLower ? percent : m_percentValues[0];
426 float percentUpper = selector == RangeSelectorUpper ? percent : m_percentValues[1];
427 const float oldValues[2] = {m_percentValues[0], m_percentValues[1]};
429 if (!m_rangeSelection || percentLower <= percentUpper)
431 m_percentValues[0] = percentLower;
432 m_percentValues[1] = percentUpper;
433 if (updateCurrent)
434 m_currentSelector = selector;
436 else
438 m_percentValues[0] = percentUpper;
439 m_percentValues[1] = percentLower;
440 if (updateCurrent)
441 m_currentSelector = (selector == RangeSelectorLower ? RangeSelectorUpper : RangeSelectorLower);
443 if (oldValues[0] != m_percentValues[0] || oldValues[1] != m_percentValues[1])
444 MarkDirtyRegion();
447 float CGUISliderControl::GetPercentage(RangeSelector selector /* = RangeSelectorLower */) const
449 return m_percentValues[selector];
452 void CGUISliderControl::SetIntValue(int iValue, RangeSelector selector /* = RangeSelectorLower */, bool updateCurrent /* = false */)
454 if (m_iType == SLIDER_CONTROL_TYPE_FLOAT)
455 SetFloatValue((float)iValue, selector, updateCurrent);
456 else if (m_iType == SLIDER_CONTROL_TYPE_INT)
458 if (iValue > m_iEnd) iValue = m_iEnd;
459 else if (iValue < m_iStart) iValue = m_iStart;
461 int iValueLower = selector == RangeSelectorLower ? iValue : m_intValues[0];
462 int iValueUpper = selector == RangeSelectorUpper ? iValue : m_intValues[1];
464 if (!m_rangeSelection || iValueLower <= iValueUpper)
466 m_intValues[0] = iValueLower;
467 m_intValues[1] = iValueUpper;
468 if (updateCurrent)
469 m_currentSelector = selector;
471 else
473 m_intValues[0] = iValueUpper;
474 m_intValues[1] = iValueLower;
475 if (updateCurrent)
476 m_currentSelector = (selector == RangeSelectorLower ? RangeSelectorUpper : RangeSelectorLower);
479 else
480 SetPercentage((float)iValue, selector, updateCurrent);
483 int CGUISliderControl::GetIntValue(RangeSelector selector /* = RangeSelectorLower */) const
485 if (m_iType == SLIDER_CONTROL_TYPE_FLOAT)
486 return (int)m_floatValues[selector];
487 else if (m_iType == SLIDER_CONTROL_TYPE_INT)
488 return m_intValues[selector];
489 else
490 return MathUtils::round_int(static_cast<double>(m_percentValues[selector]));
493 void CGUISliderControl::SetFloatValue(float fValue, RangeSelector selector /* = RangeSelectorLower */, bool updateCurrent /* = false */)
495 if (m_iType == SLIDER_CONTROL_TYPE_FLOAT)
497 if (fValue > m_fEnd) fValue = m_fEnd;
498 else if (fValue < m_fStart) fValue = m_fStart;
500 float fValueLower = selector == RangeSelectorLower ? fValue : m_floatValues[0];
501 float fValueUpper = selector == RangeSelectorUpper ? fValue : m_floatValues[1];
503 if (!m_rangeSelection || fValueLower <= fValueUpper)
505 m_floatValues[0] = fValueLower;
506 m_floatValues[1] = fValueUpper;
507 if (updateCurrent)
508 m_currentSelector = selector;
510 else
512 m_floatValues[0] = fValueUpper;
513 m_floatValues[1] = fValueLower;
514 if (updateCurrent)
515 m_currentSelector = (selector == RangeSelectorLower ? RangeSelectorUpper : RangeSelectorLower);
518 else if (m_iType == SLIDER_CONTROL_TYPE_INT)
519 SetIntValue((int)fValue, selector, updateCurrent);
520 else
521 SetPercentage(fValue, selector, updateCurrent);
524 float CGUISliderControl::GetFloatValue(RangeSelector selector /* = RangeSelectorLower */) const
526 if (m_iType == SLIDER_CONTROL_TYPE_FLOAT)
527 return m_floatValues[selector];
528 else if (m_iType == SLIDER_CONTROL_TYPE_INT)
529 return (float)m_intValues[selector];
530 else
531 return m_percentValues[selector];
534 void CGUISliderControl::SetIntInterval(int iInterval)
536 if (m_iType == SLIDER_CONTROL_TYPE_FLOAT)
537 m_fInterval = (float)iInterval;
538 else
539 m_iInterval = iInterval;
542 void CGUISliderControl::SetFloatInterval(float fInterval)
544 if (m_iType == SLIDER_CONTROL_TYPE_FLOAT)
545 m_fInterval = fInterval;
546 else
547 m_iInterval = (int)fInterval;
550 void CGUISliderControl::SetRange(int iStart, int iEnd)
552 if (m_iType == SLIDER_CONTROL_TYPE_FLOAT)
553 SetFloatRange((float)iStart,(float)iEnd);
554 else
556 m_intValues[0] = m_iStart = iStart;
557 m_intValues[1] = m_iEnd = iEnd;
561 void CGUISliderControl::SetFloatRange(float fStart, float fEnd)
563 if (m_iType == SLIDER_CONTROL_TYPE_INT)
564 SetRange((int)fStart, (int)fEnd);
565 else
567 m_floatValues[0] = m_fStart = fStart;
568 m_floatValues[1] = m_fEnd = fEnd;
572 void CGUISliderControl::FreeResources(bool immediately)
574 CGUIControl::FreeResources(immediately);
575 m_guiBackground->FreeResources(immediately);
576 m_guiBackgroundDisabled->FreeResources(immediately);
577 m_guiSelectorLower->FreeResources(immediately);
578 m_guiSelectorUpper->FreeResources(immediately);
579 m_guiSelectorLowerFocus->FreeResources(immediately);
580 m_guiSelectorUpperFocus->FreeResources(immediately);
581 m_guiSelectorLowerDisabled->FreeResources(immediately);
582 m_guiSelectorUpperDisabled->FreeResources(immediately);
585 void CGUISliderControl::DynamicResourceAlloc(bool bOnOff)
587 CGUIControl::DynamicResourceAlloc(bOnOff);
588 m_guiBackground->DynamicResourceAlloc(bOnOff);
589 m_guiBackgroundDisabled->DynamicResourceAlloc(bOnOff);
590 m_guiSelectorLower->DynamicResourceAlloc(bOnOff);
591 m_guiSelectorUpper->DynamicResourceAlloc(bOnOff);
592 m_guiSelectorLowerFocus->DynamicResourceAlloc(bOnOff);
593 m_guiSelectorUpperFocus->DynamicResourceAlloc(bOnOff);
594 m_guiSelectorLowerDisabled->DynamicResourceAlloc(bOnOff);
595 m_guiSelectorUpperDisabled->DynamicResourceAlloc(bOnOff);
598 void CGUISliderControl::AllocResources()
600 CGUIControl::AllocResources();
601 m_guiBackground->AllocResources();
602 m_guiBackgroundDisabled->AllocResources();
603 m_guiSelectorLower->AllocResources();
604 m_guiSelectorUpper->AllocResources();
605 m_guiSelectorLowerFocus->AllocResources();
606 m_guiSelectorUpperFocus->AllocResources();
607 m_guiSelectorLowerDisabled->AllocResources();
608 m_guiSelectorUpperDisabled->AllocResources();
611 void CGUISliderControl::SetInvalid()
613 CGUIControl::SetInvalid();
614 m_guiBackground->SetInvalid();
615 m_guiBackgroundDisabled->SetInvalid();
616 m_guiSelectorLower->SetInvalid();
617 m_guiSelectorUpper->SetInvalid();
618 m_guiSelectorLowerFocus->SetInvalid();
619 m_guiSelectorUpperFocus->SetInvalid();
620 m_guiSelectorLowerDisabled->SetInvalid();
621 m_guiSelectorUpperDisabled->SetInvalid();
624 bool CGUISliderControl::HitTest(const CPoint &point) const
626 if (m_guiBackground->HitTest(point))
627 return true;
628 if (m_guiSelectorLower->HitTest(point))
629 return true;
630 if (m_rangeSelection && m_guiSelectorUpper->HitTest(point))
631 return true;
632 return false;
635 void CGUISliderControl::SetFromPosition(const CPoint &point, bool guessSelector /* = false */)
638 float fPercent;
639 if (m_orientation == HORIZONTAL)
640 fPercent = (point.x - m_guiBackground->GetXPosition()) / m_guiBackground->GetWidth();
641 else
642 fPercent = (m_guiBackground->GetYPosition() + m_guiBackground->GetHeight() - point.y) /
643 m_guiBackground->GetHeight();
645 if (fPercent < 0) fPercent = 0;
646 if (fPercent > 1) fPercent = 1;
648 if (m_rangeSelection && guessSelector)
650 // choose selector which value is closer to value calculated from position
651 if (fabs(GetPercentage(RangeSelectorLower) - 100 * fPercent) <= fabs(GetPercentage(RangeSelectorUpper) - 100 * fPercent))
652 m_currentSelector = RangeSelectorLower;
653 else
654 m_currentSelector = RangeSelectorUpper;
657 switch (m_iType)
659 case SLIDER_CONTROL_TYPE_FLOAT:
661 float fValue = m_fStart + (m_fEnd - m_fStart) * fPercent;
662 SetFloatValue(MathUtils::RoundF(fValue, m_fInterval), m_currentSelector, true);
663 break;
666 case SLIDER_CONTROL_TYPE_INT:
668 int iValue = (int)(m_iStart + (float)(m_iEnd - m_iStart) * fPercent + 0.49f);
669 SetIntValue(iValue, m_currentSelector, true);
670 break;
673 case SLIDER_CONTROL_TYPE_PERCENTAGE:
674 default:
676 SetPercentage(fPercent * 100, m_currentSelector, true);
677 break;
680 SendClick();
683 EVENT_RESULT CGUISliderControl::OnMouseEvent(const CPoint& point, const MOUSE::CMouseEvent& event)
685 m_dragging = false;
686 if (event.m_id == ACTION_MOUSE_DRAG || event.m_id == ACTION_MOUSE_DRAG_END)
688 m_dragging = true;
689 bool guessSelector = false;
690 if (static_cast<HoldAction>(event.m_state) == HoldAction::DRAG)
691 { // grab exclusive access
692 CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, GetID(), GetParentID());
693 SendWindowMessage(msg);
694 guessSelector = true;
696 else if (static_cast<HoldAction>(event.m_state) == HoldAction::DRAG_END)
697 { // release exclusive access
698 m_dragging = false;
699 CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, 0, GetParentID());
700 SendWindowMessage(msg);
702 SetFromPosition(point, guessSelector);
703 return EVENT_RESULT_HANDLED;
705 else if (event.m_id == ACTION_MOUSE_LEFT_CLICK && m_guiBackground->HitTest(point))
707 SetFromPosition(point, true);
708 return EVENT_RESULT_HANDLED;
710 else if (event.m_id == ACTION_MOUSE_WHEEL_UP)
712 if (m_guiBackground->HitTest(point))
714 Move(10);
715 return EVENT_RESULT_HANDLED;
718 else if (event.m_id == ACTION_MOUSE_WHEEL_DOWN)
720 if (m_guiBackground->HitTest(point))
722 Move(-10);
723 return EVENT_RESULT_HANDLED;
726 else if (event.m_id == ACTION_GESTURE_NOTIFY)
728 return EVENT_RESULT_PAN_HORIZONTAL_WITHOUT_INERTIA;
730 else if (event.m_id == ACTION_GESTURE_BEGIN)
731 { // grab exclusive access
732 CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, GetID(), GetParentID());
733 SendWindowMessage(msg);
734 return EVENT_RESULT_HANDLED;
736 else if (event.m_id == ACTION_GESTURE_PAN)
737 { // do the drag
738 SetFromPosition(point);
739 return EVENT_RESULT_HANDLED;
741 else if (event.m_id == ACTION_GESTURE_END || event.m_id == ACTION_GESTURE_ABORT)
742 { // release exclusive access
743 CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, 0, GetParentID());
744 SendWindowMessage(msg);
745 return EVENT_RESULT_HANDLED;
747 return EVENT_RESULT_UNHANDLED;
750 void CGUISliderControl::SetInfo(int iInfo)
752 m_iInfoCode = iInfo;
755 std::string CGUISliderControl::GetDescription() const
757 if (!m_textValue.empty())
758 return m_textValue;
759 std::string description;
760 if (m_iType == SLIDER_CONTROL_TYPE_FLOAT)
762 if (m_rangeSelection)
763 description = StringUtils::Format("[{:2.2f}, {:2.2f}]", m_floatValues[0], m_floatValues[1]);
764 else
765 description = StringUtils::Format("{:2.2f}", m_floatValues[0]);
767 else if (m_iType == SLIDER_CONTROL_TYPE_INT)
769 if (m_rangeSelection)
770 description = StringUtils::Format("[{}, {}]", m_intValues[0], m_intValues[1]);
771 else
772 description = std::to_string(m_intValues[0]);
774 else
776 if (m_rangeSelection)
777 description = StringUtils::Format("[{}%, {}%]", MathUtils::round_int(static_cast<double>(m_percentValues[0])),
778 MathUtils::round_int(static_cast<double>(m_percentValues[1])));
779 else
780 description = StringUtils::Format("{}%", MathUtils::round_int(static_cast<double>(m_percentValues[0])));
782 return description;
785 bool CGUISliderControl::UpdateColors(const CGUIListItem* item)
787 bool changed = CGUIControl::UpdateColors(nullptr);
788 changed |= m_guiBackground->SetDiffuseColor(m_diffuseColor);
789 changed |= m_guiBackgroundDisabled->SetDiffuseColor(m_diffuseColor);
790 changed |= m_guiSelectorLower->SetDiffuseColor(m_diffuseColor);
791 changed |= m_guiSelectorUpper->SetDiffuseColor(m_diffuseColor);
792 changed |= m_guiSelectorLowerFocus->SetDiffuseColor(m_diffuseColor);
793 changed |= m_guiSelectorUpperFocus->SetDiffuseColor(m_diffuseColor);
794 changed |= m_guiSelectorLowerDisabled->SetDiffuseColor(m_diffuseColor);
795 changed |= m_guiSelectorUpperDisabled->SetDiffuseColor(m_diffuseColor);
797 return changed;
800 float CGUISliderControl::GetProportion(RangeSelector selector /* = RangeSelectorLower */) const
802 if (m_iType == SLIDER_CONTROL_TYPE_FLOAT)
803 return m_fStart != m_fEnd ? (GetFloatValue(selector) - m_fStart) / (m_fEnd - m_fStart) : 0.0f;
804 else if (m_iType == SLIDER_CONTROL_TYPE_INT)
805 return m_iStart != m_iEnd ? (float)(GetIntValue(selector) - m_iStart) / (float)(m_iEnd - m_iStart) : 0.0f;
806 return 0.01f * GetPercentage(selector);
809 void CGUISliderControl::SetAction(const std::string &action)
811 for (const SliderAction& a : actions)
813 if (StringUtils::EqualsNoCase(action, a.action))
815 m_action = &a;
816 return;
819 m_action = NULL;