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.
9 #include "GUISpinControl.h"
11 #include "GUIMessage.h"
12 #include "input/Key.h"
13 #include "utils/StringUtils.h"
17 #define SPIN_BUTTON_DOWN 1
18 #define SPIN_BUTTON_UP 2
22 // Additional space between text and spin buttons
23 constexpr float TEXT_SPACE
= 5.0f
;
24 } // unnamed namespace
26 CGUISpinControl::CGUISpinControl(int parentID
,
32 const CTextureInfo
& textureUp
,
33 const CTextureInfo
& textureDown
,
34 const CTextureInfo
& textureUpFocus
,
35 const CTextureInfo
& textureDownFocus
,
36 const CTextureInfo
& textureUpDisabled
,
37 const CTextureInfo
& textureDownDisabled
,
38 const CLabelInfo
& labelInfo
,
40 : CGUIControl(parentID
, controlID
, posX
, posY
, width
, height
),
41 m_imgspinUp(CGUITexture::CreateTexture(posX
, posY
, width
, height
, textureUp
)),
42 m_imgspinDown(CGUITexture::CreateTexture(posX
, posY
, width
, height
, textureDown
)),
43 m_imgspinUpFocus(CGUITexture::CreateTexture(posX
, posY
, width
, height
, textureUpFocus
)),
44 m_imgspinDownFocus(CGUITexture::CreateTexture(posX
, posY
, width
, height
, textureDownFocus
)),
45 m_imgspinUpDisabled(CGUITexture::CreateTexture(posX
, posY
, width
, height
, textureUpDisabled
)),
46 m_imgspinDownDisabled(
47 CGUITexture::CreateTexture(posX
, posY
, width
, height
, textureDownDisabled
)),
48 m_label(posX
, posY
, width
, height
, labelInfo
)
59 m_iSelect
= SPIN_BUTTON_DOWN
;
62 strcpy(m_szTyped
, "");
63 ControlType
= GUICONTROL_SPIN
;
70 CGUISpinControl::CGUISpinControl(const CGUISpinControl
& control
)
71 : CGUIControl(control
),
72 m_iStart(control
.m_iStart
),
73 m_iEnd(control
.m_iEnd
),
74 m_fStart(control
.m_fStart
),
75 m_fEnd(control
.m_fEnd
),
76 m_iValue(control
.m_iValue
),
77 m_fValue(control
.m_fValue
),
78 m_iType(control
.m_iType
),
79 m_iSelect(control
.m_iSelect
),
80 m_bReverse(control
.m_bReverse
),
81 m_fInterval(control
.m_fInterval
),
82 m_vecLabels(control
.m_vecLabels
),
83 m_vecValues(control
.m_vecValues
),
84 m_vecStrValues(control
.m_vecStrValues
),
85 m_imgspinUp(control
.m_imgspinUp
->Clone()),
86 m_imgspinDown(control
.m_imgspinDown
->Clone()),
87 m_imgspinUpFocus(control
.m_imgspinUpFocus
->Clone()),
88 m_imgspinDownFocus(control
.m_imgspinDownFocus
->Clone()),
89 m_imgspinUpDisabled(control
.m_imgspinUpDisabled
->Clone()),
90 m_imgspinDownDisabled(control
.m_imgspinDownDisabled
->Clone()),
91 m_label(control
.m_label
),
92 m_bShowRange(control
.m_bShowRange
),
93 m_iTypedPos(control
.m_iTypedPos
),
94 m_currentItem(control
.m_currentItem
),
95 m_itemsPerPage(control
.m_itemsPerPage
),
96 m_numItems(control
.m_numItems
),
97 m_showOnePage(control
.m_showOnePage
)
99 std::strcpy(m_szTyped
, control
.m_szTyped
);
102 bool CGUISpinControl::OnAction(const CAction
&action
)
104 switch (action
.GetID())
117 if (strlen(m_szTyped
) >= 3)
120 strcpy(m_szTyped
, "");
122 int iNumber
= action
.GetID() - REMOTE_0
;
124 m_szTyped
[m_iTypedPos
] = iNumber
+ '0';
126 m_szTyped
[m_iTypedPos
] = 0;
128 sscanf(m_szTyped
, "%i", &iValue
);
131 case SPIN_CONTROL_TYPE_INT
:
133 if (iValue
< m_iStart
|| iValue
> m_iEnd
)
136 m_szTyped
[m_iTypedPos
] = iNumber
+ '0';
138 m_szTyped
[m_iTypedPos
] = 0;
139 sscanf(m_szTyped
, "%i", &iValue
);
140 if (iValue
< m_iStart
|| iValue
> m_iEnd
)
143 strcpy(m_szTyped
, "");
148 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
149 SendWindowMessage(msg
);
153 case SPIN_CONTROL_TYPE_TEXT
:
155 if (iValue
< 0 || iValue
>= (int)m_vecLabels
.size())
158 m_szTyped
[m_iTypedPos
] = iNumber
+ '0';
160 m_szTyped
[m_iTypedPos
] = 0;
161 sscanf(m_szTyped
, "%i", &iValue
);
162 if (iValue
< 0 || iValue
>= (int)m_vecLabels
.size())
165 strcpy(m_szTyped
, "");
170 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
171 SendWindowMessage(msg
);
186 case ACTION_PAGE_DOWN
:
193 case ACTION_SELECT_ITEM
:
194 if (m_iSelect
== SPIN_BUTTON_UP
)
199 if (m_iSelect
== SPIN_BUTTON_DOWN
)
206 /* static float m_fSmoothScrollOffset = 0.0f;
207 if (action.GetID() == ACTION_SCROLL_UP)
209 m_fSmoothScrollOffset += action.GetAmount() * action.GetAmount();
210 bool handled = false;
211 while (m_fSmoothScrollOffset > 0.4)
214 m_fSmoothScrollOffset -= 0.4f;
219 return CGUIControl::OnAction(action
);
222 void CGUISpinControl::OnLeft()
224 if (m_iSelect
== SPIN_BUTTON_UP
)
226 // select the down button
227 m_iSelect
= SPIN_BUTTON_DOWN
;
232 CGUIControl::OnLeft();
236 void CGUISpinControl::OnRight()
238 if (m_iSelect
== SPIN_BUTTON_DOWN
)
240 // select the up button
241 m_iSelect
= SPIN_BUTTON_UP
;
246 CGUIControl::OnRight();
250 void CGUISpinControl::Clear()
254 m_vecStrValues
.clear();
258 bool CGUISpinControl::OnMessage(CGUIMessage
& message
)
260 if (CGUIControl::OnMessage(message
) )
262 if (message
.GetControlId() == GetID() )
264 switch (message
.GetMessage())
266 case GUI_MSG_ITEM_SELECT
:
267 if (SPIN_CONTROL_TYPE_PAGE
== m_iType
)
269 m_currentItem
= message
.GetParam1();
272 SetValue( message
.GetParam1());
273 if (message
.GetParam2() == SPIN_BUTTON_DOWN
|| message
.GetParam2() == SPIN_BUTTON_UP
)
274 m_iSelect
= message
.GetParam2();
278 case GUI_MSG_LABEL_RESET
:
279 if (SPIN_CONTROL_TYPE_PAGE
== m_iType
)
281 m_itemsPerPage
= message
.GetParam1();
282 m_numItems
= message
.GetParam2();
291 case GUI_MSG_SHOWRANGE
:
292 if (message
.GetParam1() )
295 m_bShowRange
= false;
298 case GUI_MSG_SET_LABELS
:
299 if (message
.GetPointer())
302 static_cast<const std::vector
<std::pair
<std::string
, int>>*>(message
.GetPointer());
304 for (const auto& i
: *labels
)
305 AddLabel(i
.first
, i
.second
);
306 SetValue( message
.GetParam1());
310 case GUI_MSG_LABEL_ADD
:
312 AddLabel(message
.GetLabel(), message
.GetParam1());
317 case GUI_MSG_ITEM_SELECTED
:
319 message
.SetParam1( GetValue() );
320 message
.SetParam2(m_iSelect
);
322 if (m_iType
== SPIN_CONTROL_TYPE_TEXT
)
324 if ( m_iValue
>= 0 && m_iValue
< (int)m_vecLabels
.size() )
325 message
.SetLabel( m_vecLabels
[m_iValue
]);
330 case GUI_MSG_PAGE_UP
:
335 case GUI_MSG_PAGE_DOWN
:
340 case GUI_MSG_MOVE_OFFSET
:
342 int count
= message
.GetParam1();
361 void CGUISpinControl::AllocResources()
363 CGUIControl::AllocResources();
364 m_imgspinUp
->AllocResources();
365 m_imgspinUpFocus
->AllocResources();
366 m_imgspinDown
->AllocResources();
367 m_imgspinDownFocus
->AllocResources();
368 m_imgspinUpDisabled
->AllocResources();
369 m_imgspinDownDisabled
->AllocResources();
371 m_imgspinDownFocus
->SetPosition(m_posX
, m_posY
);
372 m_imgspinDown
->SetPosition(m_posX
, m_posY
);
373 m_imgspinDownDisabled
->SetPosition(m_posX
, m_posY
);
374 m_imgspinUp
->SetPosition(m_posX
+ m_imgspinDown
->GetWidth(), m_posY
);
375 m_imgspinUpFocus
->SetPosition(m_posX
+ m_imgspinDownFocus
->GetWidth(), m_posY
);
376 m_imgspinUpDisabled
->SetPosition(m_posX
+ m_imgspinDownDisabled
->GetWidth(), m_posY
);
379 void CGUISpinControl::FreeResources(bool immediately
)
381 CGUIControl::FreeResources(immediately
);
382 m_imgspinUp
->FreeResources(immediately
);
383 m_imgspinUpFocus
->FreeResources(immediately
);
384 m_imgspinDown
->FreeResources(immediately
);
385 m_imgspinDownFocus
->FreeResources(immediately
);
386 m_imgspinUpDisabled
->FreeResources(immediately
);
387 m_imgspinDownDisabled
->FreeResources(immediately
);
389 strcpy(m_szTyped
, "");
392 void CGUISpinControl::DynamicResourceAlloc(bool bOnOff
)
394 CGUIControl::DynamicResourceAlloc(bOnOff
);
395 m_imgspinUp
->DynamicResourceAlloc(bOnOff
);
396 m_imgspinUpFocus
->DynamicResourceAlloc(bOnOff
);
397 m_imgspinDown
->DynamicResourceAlloc(bOnOff
);
398 m_imgspinDownFocus
->DynamicResourceAlloc(bOnOff
);
399 m_imgspinUpDisabled
->DynamicResourceAlloc(bOnOff
);
400 m_imgspinDownDisabled
->DynamicResourceAlloc(bOnOff
);
403 void CGUISpinControl::SetInvalid()
405 CGUIControl::SetInvalid();
406 m_label
.SetInvalid();
407 m_imgspinUp
->SetInvalid();
408 m_imgspinUpFocus
->SetInvalid();
409 m_imgspinDown
->SetInvalid();
410 m_imgspinDownFocus
->SetInvalid();
411 m_imgspinUpDisabled
->SetInvalid();
412 m_imgspinDownDisabled
->SetInvalid();
415 void CGUISpinControl::Process(unsigned int currentTime
, CDirtyRegionList
&dirtyregions
)
417 bool changed
= false;
422 strcpy(m_szTyped
, "");
427 if (m_iType
== SPIN_CONTROL_TYPE_INT
)
431 text
= StringUtils::Format("{}/{}", m_iValue
, m_iEnd
);
435 text
= std::to_string(m_iValue
);
438 else if (m_iType
== SPIN_CONTROL_TYPE_PAGE
)
440 // work out number of pages and current page
441 int numPages
= (m_numItems
+ m_itemsPerPage
- 1) / m_itemsPerPage
;
442 int currentPage
= m_currentItem
/ m_itemsPerPage
+ 1;
443 if (m_currentItem
>= m_numItems
- m_itemsPerPage
)
444 currentPage
= numPages
;
445 text
= StringUtils::Format("{}/{}", currentPage
, numPages
);
447 else if (m_iType
== SPIN_CONTROL_TYPE_FLOAT
)
451 text
= StringUtils::Format("{:02.2f}/{:02.2f}", m_fValue
, m_fEnd
);
455 text
= StringUtils::Format("{:02.2f}", m_fValue
);
460 if (m_iValue
>= 0 && m_iValue
< (int)m_vecLabels
.size() )
464 text
= StringUtils::Format("({}/{}) {}", m_iValue
+ 1, (int)m_vecLabels
.size(),
465 m_vecLabels
[m_iValue
]);
469 text
= m_vecLabels
[m_iValue
];
473 text
= StringUtils::Format("?{}?", m_iValue
);
476 changed
|= m_label
.SetText(text
);
478 float textWidth
= m_label
.GetTextWidth() + 2 * m_label
.GetLabelInfo().offsetX
;
479 // Position the arrows
480 bool arrowsOnRight(0 != (m_label
.GetLabelInfo().align
& (XBFONT_RIGHT
| XBFONT_CENTER_X
)));
483 changed
|= m_imgspinDownFocus
->SetPosition(m_posX
+ textWidth
+ TEXT_SPACE
, m_posY
);
484 changed
|= m_imgspinDown
->SetPosition(m_posX
+ textWidth
+ TEXT_SPACE
, m_posY
);
485 changed
|= m_imgspinDownDisabled
->SetPosition(m_posX
+ textWidth
+ TEXT_SPACE
, m_posY
);
486 changed
|= m_imgspinUpFocus
->SetPosition(
487 m_posX
+ textWidth
+ TEXT_SPACE
+ m_imgspinDown
->GetWidth(), m_posY
);
488 changed
|= m_imgspinUp
->SetPosition(m_posX
+ textWidth
+ TEXT_SPACE
+ m_imgspinDown
->GetWidth(),
490 changed
|= m_imgspinUpDisabled
->SetPosition(
491 m_posX
+ textWidth
+ TEXT_SPACE
+ m_imgspinDownDisabled
->GetWidth(), m_posY
);
494 changed
|= m_imgspinDownFocus
->Process(currentTime
);
495 changed
|= m_imgspinDown
->Process(currentTime
);
496 changed
|= m_imgspinUp
->Process(currentTime
);
497 changed
|= m_imgspinUpFocus
->Process(currentTime
);
498 changed
|= m_imgspinUpDisabled
->Process(currentTime
);
499 changed
|= m_imgspinDownDisabled
->Process(currentTime
);
500 changed
|= m_label
.Process(currentTime
);
505 CGUIControl::Process(currentTime
, dirtyregions
);
508 void CGUISpinControl::Render()
510 if (m_label
.GetLabelInfo().font
)
512 float textWidth
= m_label
.GetTextWidth() + 2 * m_label
.GetLabelInfo().offsetX
;
513 // Position the arrows
514 bool arrowsOnRight(0 != (m_label
.GetLabelInfo().align
& (XBFONT_RIGHT
| XBFONT_CENTER_X
)));
517 RenderText(m_posX
- TEXT_SPACE
- textWidth
, m_posY
, textWidth
, m_height
);
519 RenderText(m_posX
+ m_imgspinDown
->GetWidth() + m_imgspinUp
->GetWidth() + TEXT_SPACE
, m_posY
,
520 textWidth
, m_height
);
522 // set our hit rectangle for MouseOver events
523 m_hitRect
= m_label
.GetRenderRect();
528 if (m_iSelect
== SPIN_BUTTON_UP
)
529 m_imgspinUpFocus
->Render();
531 m_imgspinUp
->Render();
533 if (m_iSelect
== SPIN_BUTTON_DOWN
)
534 m_imgspinDownFocus
->Render();
536 m_imgspinDown
->Render();
538 else if (!HasFocus() && !IsDisabled())
540 m_imgspinUp
->Render();
541 m_imgspinDown
->Render();
545 m_imgspinUpDisabled
->Render();
546 m_imgspinDownDisabled
->Render();
549 CGUIControl::Render();
552 void CGUISpinControl::RenderText(float posX
, float posY
, float width
, float height
)
554 m_label
.SetMaxRect(posX
, posY
, width
, height
);
555 m_label
.SetColor(GetTextColor());
559 CGUILabel::COLOR
CGUISpinControl::GetTextColor() const
562 return CGUILabel::COLOR_DISABLED
;
564 return CGUILabel::COLOR_FOCUSED
;
565 return CGUILabel::COLOR_TEXT
;
568 void CGUISpinControl::SetRange(int iStart
, int iEnd
)
574 void CGUISpinControl::SetFloatRange(float fStart
, float fEnd
)
580 void CGUISpinControl::SetValueFromLabel(const std::string
&label
)
582 if (m_iType
== SPIN_CONTROL_TYPE_TEXT
)
585 for (unsigned int i
= 0; i
< m_vecLabels
.size(); i
++)
586 if (label
== m_vecLabels
[i
])
590 m_iValue
= atoi(label
.c_str());
596 void CGUISpinControl::SetValue(int iValue
)
598 if (m_iType
== SPIN_CONTROL_TYPE_TEXT
)
601 for (unsigned int i
= 0; i
< m_vecValues
.size(); i
++)
602 if (iValue
== m_vecValues
[i
])
612 void CGUISpinControl::SetFloatValue(float fValue
)
617 void CGUISpinControl::SetStringValue(const std::string
& strValue
)
619 if (m_iType
== SPIN_CONTROL_TYPE_TEXT
)
622 for (unsigned int i
= 0; i
< m_vecStrValues
.size(); i
++)
623 if (strValue
== m_vecStrValues
[i
])
630 int CGUISpinControl::GetValue() const
632 if (m_iType
== SPIN_CONTROL_TYPE_TEXT
)
634 if (m_iValue
>= 0 && m_iValue
< (int)m_vecValues
.size())
635 return m_vecValues
[m_iValue
];
640 float CGUISpinControl::GetFloatValue() const
645 std::string
CGUISpinControl::GetStringValue() const
647 if (m_iType
== SPIN_CONTROL_TYPE_TEXT
&& m_iValue
>= 0 && m_iValue
< (int)m_vecLabels
.size())
649 if (m_iValue
< (int)m_vecStrValues
.size())
650 return m_vecStrValues
[m_iValue
];
652 return m_vecLabels
[m_iValue
];
657 void CGUISpinControl::AddLabel(const std::string
& strLabel
, int iValue
)
659 m_vecLabels
.push_back(strLabel
);
660 m_vecValues
.push_back(iValue
);
663 void CGUISpinControl::AddLabel(const std::string
& strLabel
, const std::string
& strValue
)
665 m_vecLabels
.push_back(strLabel
);
666 m_vecStrValues
.push_back(strValue
);
669 const std::string
CGUISpinControl::GetLabel() const
671 if (m_iValue
>= 0 && m_iValue
< (int)m_vecLabels
.size())
673 return m_vecLabels
[m_iValue
];
678 void CGUISpinControl::SetPosition(float posX
, float posY
)
680 CGUIControl::SetPosition(posX
, posY
);
682 m_imgspinDownFocus
->SetPosition(posX
, posY
);
683 m_imgspinDown
->SetPosition(posX
, posY
);
684 m_imgspinDownDisabled
->SetPosition(posX
, posY
);
686 m_imgspinUp
->SetPosition(m_posX
+ m_imgspinDown
->GetWidth(), m_posY
);
687 m_imgspinUpFocus
->SetPosition(m_posX
+ m_imgspinDownFocus
->GetWidth(), m_posY
);
688 m_imgspinUpDisabled
->SetPosition(m_posX
+ m_imgspinDownDisabled
->GetWidth(), m_posY
);
691 float CGUISpinControl::GetWidth() const
693 return m_imgspinDown
->GetWidth() * 2;
696 bool CGUISpinControl::CanMoveUp(bool bTestReverse
)
698 // test for reverse...
699 if (bTestReverse
&& m_bReverse
) return CanMoveDown(false);
703 case SPIN_CONTROL_TYPE_PAGE
:
704 return m_currentItem
> 0;
705 case SPIN_CONTROL_TYPE_INT
:
707 if (m_iValue
- 1 >= m_iStart
)
713 case SPIN_CONTROL_TYPE_FLOAT
:
715 if (m_fValue
- m_fInterval
>= m_fStart
)
721 case SPIN_CONTROL_TYPE_TEXT
:
723 if (m_iValue
- 1 >= 0)
732 bool CGUISpinControl::CanMoveDown(bool bTestReverse
)
734 // test for reverse...
735 if (bTestReverse
&& m_bReverse
) return CanMoveUp(false);
738 case SPIN_CONTROL_TYPE_PAGE
:
739 return m_currentItem
< m_numItems
;
740 case SPIN_CONTROL_TYPE_INT
:
742 if (m_iValue
+ 1 <= m_iEnd
)
748 case SPIN_CONTROL_TYPE_FLOAT
:
750 if (m_fValue
+ m_fInterval
<= m_fEnd
)
756 case SPIN_CONTROL_TYPE_TEXT
:
758 if (m_iValue
+ 1 < (int)m_vecLabels
.size())
767 void CGUISpinControl::PageUp()
771 case SPIN_CONTROL_TYPE_INT
:
773 if (m_iValue
- 10 >= m_iStart
)
777 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
778 SendWindowMessage(msg
);
782 case SPIN_CONTROL_TYPE_PAGE
:
785 case SPIN_CONTROL_TYPE_TEXT
:
787 if (m_iValue
- 10 >= 0)
791 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
792 SendWindowMessage(msg
);
800 void CGUISpinControl::PageDown()
804 case SPIN_CONTROL_TYPE_INT
:
806 if (m_iValue
+ 10 <= m_iEnd
)
810 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
811 SendWindowMessage(msg
);
815 case SPIN_CONTROL_TYPE_PAGE
:
818 case SPIN_CONTROL_TYPE_TEXT
:
820 if (m_iValue
+ 10 < (int)m_vecLabels
.size() )
822 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
823 SendWindowMessage(msg
);
829 void CGUISpinControl::MoveUp(bool bTestReverse
)
831 if (bTestReverse
&& m_bReverse
)
832 { // actually should move down.
838 case SPIN_CONTROL_TYPE_INT
:
840 if (m_iValue
- 1 >= m_iStart
)
842 else if (m_iValue
== m_iStart
)
844 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
845 SendWindowMessage(msg
);
850 case SPIN_CONTROL_TYPE_PAGE
:
854 case SPIN_CONTROL_TYPE_FLOAT
:
856 if (m_fValue
- m_fInterval
>= m_fStart
)
857 m_fValue
-= m_fInterval
;
860 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
861 SendWindowMessage(msg
);
866 case SPIN_CONTROL_TYPE_TEXT
:
868 if (m_iValue
- 1 >= 0)
870 else if (m_iValue
== 0)
871 m_iValue
= (int)m_vecLabels
.size() - 1;
872 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
873 SendWindowMessage(msg
);
880 void CGUISpinControl::MoveDown(bool bTestReverse
)
882 if (bTestReverse
&& m_bReverse
)
883 { // actually should move up.
889 case SPIN_CONTROL_TYPE_INT
:
891 if (m_iValue
+ 1 <= m_iEnd
)
893 else if (m_iValue
== m_iEnd
)
895 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
896 SendWindowMessage(msg
);
901 case SPIN_CONTROL_TYPE_PAGE
:
905 case SPIN_CONTROL_TYPE_FLOAT
:
907 if (m_fValue
+ m_fInterval
<= m_fEnd
)
908 m_fValue
+= m_fInterval
;
911 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
912 SendWindowMessage(msg
);
917 case SPIN_CONTROL_TYPE_TEXT
:
919 if (m_iValue
+ 1 < (int)m_vecLabels
.size() )
921 else if (m_iValue
== (int)m_vecLabels
.size() - 1)
923 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
924 SendWindowMessage(msg
);
930 void CGUISpinControl::SetReverse(bool bReverse
)
932 m_bReverse
= bReverse
;
935 void CGUISpinControl::SetFloatInterval(float fInterval
)
937 m_fInterval
= fInterval
;
940 void CGUISpinControl::SetShowRange(bool bOnoff
)
942 m_bShowRange
= bOnoff
;
945 int CGUISpinControl::GetMinimum() const
949 case SPIN_CONTROL_TYPE_PAGE
:
951 case SPIN_CONTROL_TYPE_INT
:
955 case SPIN_CONTROL_TYPE_TEXT
:
959 case SPIN_CONTROL_TYPE_FLOAT
:
960 return (int)(m_fStart
*10.0f
);
966 int CGUISpinControl::GetMaximum() const
970 case SPIN_CONTROL_TYPE_PAGE
:
972 case SPIN_CONTROL_TYPE_INT
:
976 case SPIN_CONTROL_TYPE_TEXT
:
977 return (int)m_vecLabels
.size();
980 case SPIN_CONTROL_TYPE_FLOAT
:
981 return (int)(m_fEnd
*10.0f
);
987 bool CGUISpinControl::HitTest(const CPoint
&point
) const
989 if (m_imgspinUpFocus
->HitTest(point
) || m_imgspinDownFocus
->HitTest(point
))
991 return CGUIControl::HitTest(point
);
994 bool CGUISpinControl::OnMouseOver(const CPoint
&point
)
996 int select
= m_iSelect
;
997 if (m_imgspinDownFocus
->HitTest(point
))
998 m_iSelect
= SPIN_BUTTON_DOWN
;
1000 m_iSelect
= SPIN_BUTTON_UP
;
1002 if (select
!= m_iSelect
)
1005 return CGUIControl::OnMouseOver(point
);
1008 EVENT_RESULT
CGUISpinControl::OnMouseEvent(const CPoint
&point
, const CMouseEvent
&event
)
1010 if (event
.m_id
== ACTION_MOUSE_LEFT_CLICK
)
1012 if (m_imgspinUpFocus
->HitTest(point
))
1014 else if (m_imgspinDownFocus
->HitTest(point
))
1016 return EVENT_RESULT_HANDLED
;
1018 else if (event
.m_id
== ACTION_MOUSE_WHEEL_UP
)
1020 if (m_imgspinUpFocus
->HitTest(point
) || m_imgspinDownFocus
->HitTest(point
))
1023 return EVENT_RESULT_HANDLED
;
1026 else if (event
.m_id
== ACTION_MOUSE_WHEEL_DOWN
)
1028 if (m_imgspinUpFocus
->HitTest(point
) || m_imgspinDownFocus
->HitTest(point
))
1031 return EVENT_RESULT_HANDLED
;
1034 return EVENT_RESULT_UNHANDLED
;
1037 std::string
CGUISpinControl::GetDescription() const
1039 return StringUtils::Format("{}/{}", 1 + GetValue(), GetMaximum());
1042 bool CGUISpinControl::IsFocusedOnUp() const
1044 return (m_iSelect
== SPIN_BUTTON_UP
);
1047 void CGUISpinControl::ChangePage(int amount
)
1049 m_currentItem
+= amount
* m_itemsPerPage
;
1050 if (m_currentItem
> m_numItems
- m_itemsPerPage
)
1051 m_currentItem
= m_numItems
- m_itemsPerPage
;
1052 if (m_currentItem
< 0)
1054 CGUIMessage
message(GUI_MSG_NOTIFY_ALL
, GetParentID(), GetID(), GUI_MSG_PAGE_CHANGE
, m_currentItem
);
1055 SendWindowMessage(message
);
1058 bool CGUISpinControl::UpdateColors(const CGUIListItem
* item
)
1060 bool changed
= CGUIControl::UpdateColors(nullptr);
1061 changed
|= m_label
.UpdateColors();
1062 changed
|= m_imgspinDownFocus
->SetDiffuseColor(m_diffuseColor
);
1063 changed
|= m_imgspinDown
->SetDiffuseColor(m_diffuseColor
);
1064 changed
|= m_imgspinUp
->SetDiffuseColor(m_diffuseColor
);
1065 changed
|= m_imgspinUpFocus
->SetDiffuseColor(m_diffuseColor
);
1066 changed
|= m_imgspinUpDisabled
->SetDiffuseColor(m_diffuseColor
);
1067 changed
|= m_imgspinDownDisabled
->SetDiffuseColor(m_diffuseColor
);
1072 bool CGUISpinControl::IsVisible() const
1074 // page controls can be optionally disabled if the number of pages is 1
1075 if (m_iType
== SPIN_CONTROL_TYPE_PAGE
&& m_numItems
<= m_itemsPerPage
&& !m_showOnePage
)
1077 return CGUIControl::IsVisible();