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/actions/Action.h"
13 #include "input/actions/ActionIDs.h"
14 #include "input/mouse/MouseEvent.h"
15 #include "utils/StringUtils.h"
19 #define SPIN_BUTTON_DOWN 1
20 #define SPIN_BUTTON_UP 2
26 // Additional space between text and spin buttons
27 constexpr float TEXT_SPACE
= 5.0f
;
28 } // unnamed namespace
30 CGUISpinControl::CGUISpinControl(int parentID
,
36 const CTextureInfo
& textureUp
,
37 const CTextureInfo
& textureDown
,
38 const CTextureInfo
& textureUpFocus
,
39 const CTextureInfo
& textureDownFocus
,
40 const CTextureInfo
& textureUpDisabled
,
41 const CTextureInfo
& textureDownDisabled
,
42 const CLabelInfo
& labelInfo
,
44 : CGUIControl(parentID
, controlID
, posX
, posY
, width
, height
),
45 m_imgspinUp(CGUITexture::CreateTexture(posX
, posY
, width
, height
, textureUp
)),
46 m_imgspinDown(CGUITexture::CreateTexture(posX
, posY
, width
, height
, textureDown
)),
47 m_imgspinUpFocus(CGUITexture::CreateTexture(posX
, posY
, width
, height
, textureUpFocus
)),
48 m_imgspinDownFocus(CGUITexture::CreateTexture(posX
, posY
, width
, height
, textureDownFocus
)),
49 m_imgspinUpDisabled(CGUITexture::CreateTexture(posX
, posY
, width
, height
, textureUpDisabled
)),
50 m_imgspinDownDisabled(
51 CGUITexture::CreateTexture(posX
, posY
, width
, height
, textureDownDisabled
)),
52 m_label(posX
, posY
, width
, height
, labelInfo
)
63 m_iSelect
= SPIN_BUTTON_DOWN
;
66 strcpy(m_szTyped
, "");
67 ControlType
= GUICONTROL_SPIN
;
74 CGUISpinControl::CGUISpinControl(const CGUISpinControl
& control
)
75 : CGUIControl(control
),
76 m_iStart(control
.m_iStart
),
77 m_iEnd(control
.m_iEnd
),
78 m_fStart(control
.m_fStart
),
79 m_fEnd(control
.m_fEnd
),
80 m_iValue(control
.m_iValue
),
81 m_fValue(control
.m_fValue
),
82 m_iType(control
.m_iType
),
83 m_iSelect(control
.m_iSelect
),
84 m_bReverse(control
.m_bReverse
),
85 m_fInterval(control
.m_fInterval
),
86 m_vecLabels(control
.m_vecLabels
),
87 m_vecValues(control
.m_vecValues
),
88 m_vecStrValues(control
.m_vecStrValues
),
89 m_imgspinUp(control
.m_imgspinUp
->Clone()),
90 m_imgspinDown(control
.m_imgspinDown
->Clone()),
91 m_imgspinUpFocus(control
.m_imgspinUpFocus
->Clone()),
92 m_imgspinDownFocus(control
.m_imgspinDownFocus
->Clone()),
93 m_imgspinUpDisabled(control
.m_imgspinUpDisabled
->Clone()),
94 m_imgspinDownDisabled(control
.m_imgspinDownDisabled
->Clone()),
95 m_label(control
.m_label
),
96 m_bShowRange(control
.m_bShowRange
),
97 m_iTypedPos(control
.m_iTypedPos
),
98 m_currentItem(control
.m_currentItem
),
99 m_itemsPerPage(control
.m_itemsPerPage
),
100 m_numItems(control
.m_numItems
),
101 m_showOnePage(control
.m_showOnePage
)
103 std::strcpy(m_szTyped
, control
.m_szTyped
);
106 bool CGUISpinControl::OnAction(const CAction
&action
)
108 switch (action
.GetID())
121 if (strlen(m_szTyped
) >= 3)
124 strcpy(m_szTyped
, "");
126 int iNumber
= action
.GetID() - REMOTE_0
;
128 m_szTyped
[m_iTypedPos
] = iNumber
+ '0';
130 m_szTyped
[m_iTypedPos
] = 0;
132 sscanf(m_szTyped
, "%i", &iValue
);
135 case SPIN_CONTROL_TYPE_INT
:
137 if (iValue
< m_iStart
|| iValue
> m_iEnd
)
140 m_szTyped
[m_iTypedPos
] = iNumber
+ '0';
142 m_szTyped
[m_iTypedPos
] = 0;
143 sscanf(m_szTyped
, "%i", &iValue
);
144 if (iValue
< m_iStart
|| iValue
> m_iEnd
)
147 strcpy(m_szTyped
, "");
152 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
153 SendWindowMessage(msg
);
157 case SPIN_CONTROL_TYPE_TEXT
:
159 if (iValue
< 0 || iValue
>= (int)m_vecLabels
.size())
162 m_szTyped
[m_iTypedPos
] = iNumber
+ '0';
164 m_szTyped
[m_iTypedPos
] = 0;
165 sscanf(m_szTyped
, "%i", &iValue
);
166 if (iValue
< 0 || iValue
>= (int)m_vecLabels
.size())
169 strcpy(m_szTyped
, "");
174 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
175 SendWindowMessage(msg
);
190 case ACTION_PAGE_DOWN
:
197 case ACTION_SELECT_ITEM
:
198 if (m_iSelect
== SPIN_BUTTON_UP
)
203 if (m_iSelect
== SPIN_BUTTON_DOWN
)
210 /* static float m_fSmoothScrollOffset = 0.0f;
211 if (action.GetID() == ACTION_SCROLL_UP)
213 m_fSmoothScrollOffset += action.GetAmount() * action.GetAmount();
214 bool handled = false;
215 while (m_fSmoothScrollOffset > 0.4)
218 m_fSmoothScrollOffset -= 0.4f;
223 return CGUIControl::OnAction(action
);
226 void CGUISpinControl::OnLeft()
228 if (m_iSelect
== SPIN_BUTTON_UP
)
230 // select the down button
231 m_iSelect
= SPIN_BUTTON_DOWN
;
236 CGUIControl::OnLeft();
240 void CGUISpinControl::OnRight()
242 if (m_iSelect
== SPIN_BUTTON_DOWN
)
244 // select the up button
245 m_iSelect
= SPIN_BUTTON_UP
;
250 CGUIControl::OnRight();
254 void CGUISpinControl::Clear()
258 m_vecStrValues
.clear();
262 bool CGUISpinControl::OnMessage(CGUIMessage
& message
)
264 if (CGUIControl::OnMessage(message
) )
266 if (message
.GetControlId() == GetID() )
268 switch (message
.GetMessage())
270 case GUI_MSG_ITEM_SELECT
:
271 if (SPIN_CONTROL_TYPE_PAGE
== m_iType
)
273 m_currentItem
= message
.GetParam1();
276 SetValue( message
.GetParam1());
277 if (message
.GetParam2() == SPIN_BUTTON_DOWN
|| message
.GetParam2() == SPIN_BUTTON_UP
)
278 m_iSelect
= message
.GetParam2();
282 case GUI_MSG_LABEL_RESET
:
283 if (SPIN_CONTROL_TYPE_PAGE
== m_iType
)
285 m_itemsPerPage
= message
.GetParam1();
286 m_numItems
= message
.GetParam2();
295 case GUI_MSG_SHOWRANGE
:
296 if (message
.GetParam1() )
299 m_bShowRange
= false;
302 case GUI_MSG_SET_LABELS
:
303 if (message
.GetPointer())
306 static_cast<const std::vector
<std::pair
<std::string
, int>>*>(message
.GetPointer());
308 for (const auto& i
: *labels
)
309 AddLabel(i
.first
, i
.second
);
310 SetValue( message
.GetParam1());
314 case GUI_MSG_LABEL_ADD
:
316 AddLabel(message
.GetLabel(), message
.GetParam1());
321 case GUI_MSG_ITEM_SELECTED
:
323 message
.SetParam1( GetValue() );
324 message
.SetParam2(m_iSelect
);
326 if (m_iType
== SPIN_CONTROL_TYPE_TEXT
)
328 if ( m_iValue
>= 0 && m_iValue
< (int)m_vecLabels
.size() )
329 message
.SetLabel( m_vecLabels
[m_iValue
]);
334 case GUI_MSG_PAGE_UP
:
339 case GUI_MSG_PAGE_DOWN
:
344 case GUI_MSG_MOVE_OFFSET
:
346 int count
= message
.GetParam1();
365 void CGUISpinControl::AllocResources()
367 CGUIControl::AllocResources();
368 m_imgspinUp
->AllocResources();
369 m_imgspinUpFocus
->AllocResources();
370 m_imgspinDown
->AllocResources();
371 m_imgspinDownFocus
->AllocResources();
372 m_imgspinUpDisabled
->AllocResources();
373 m_imgspinDownDisabled
->AllocResources();
375 m_imgspinDownFocus
->SetPosition(m_posX
, m_posY
);
376 m_imgspinDown
->SetPosition(m_posX
, m_posY
);
377 m_imgspinDownDisabled
->SetPosition(m_posX
, m_posY
);
378 m_imgspinUp
->SetPosition(m_posX
+ m_imgspinDown
->GetWidth(), m_posY
);
379 m_imgspinUpFocus
->SetPosition(m_posX
+ m_imgspinDownFocus
->GetWidth(), m_posY
);
380 m_imgspinUpDisabled
->SetPosition(m_posX
+ m_imgspinDownDisabled
->GetWidth(), m_posY
);
383 void CGUISpinControl::FreeResources(bool immediately
)
385 CGUIControl::FreeResources(immediately
);
386 m_imgspinUp
->FreeResources(immediately
);
387 m_imgspinUpFocus
->FreeResources(immediately
);
388 m_imgspinDown
->FreeResources(immediately
);
389 m_imgspinDownFocus
->FreeResources(immediately
);
390 m_imgspinUpDisabled
->FreeResources(immediately
);
391 m_imgspinDownDisabled
->FreeResources(immediately
);
393 strcpy(m_szTyped
, "");
396 void CGUISpinControl::DynamicResourceAlloc(bool bOnOff
)
398 CGUIControl::DynamicResourceAlloc(bOnOff
);
399 m_imgspinUp
->DynamicResourceAlloc(bOnOff
);
400 m_imgspinUpFocus
->DynamicResourceAlloc(bOnOff
);
401 m_imgspinDown
->DynamicResourceAlloc(bOnOff
);
402 m_imgspinDownFocus
->DynamicResourceAlloc(bOnOff
);
403 m_imgspinUpDisabled
->DynamicResourceAlloc(bOnOff
);
404 m_imgspinDownDisabled
->DynamicResourceAlloc(bOnOff
);
407 void CGUISpinControl::SetInvalid()
409 CGUIControl::SetInvalid();
410 m_label
.SetInvalid();
411 m_imgspinUp
->SetInvalid();
412 m_imgspinUpFocus
->SetInvalid();
413 m_imgspinDown
->SetInvalid();
414 m_imgspinDownFocus
->SetInvalid();
415 m_imgspinUpDisabled
->SetInvalid();
416 m_imgspinDownDisabled
->SetInvalid();
419 void CGUISpinControl::Process(unsigned int currentTime
, CDirtyRegionList
&dirtyregions
)
421 bool changed
= false;
426 strcpy(m_szTyped
, "");
431 if (m_iType
== SPIN_CONTROL_TYPE_INT
)
435 text
= StringUtils::Format("{}/{}", m_iValue
, m_iEnd
);
439 text
= std::to_string(m_iValue
);
442 else if (m_iType
== SPIN_CONTROL_TYPE_PAGE
)
444 // work out number of pages and current page
445 int numPages
= (m_numItems
+ m_itemsPerPage
- 1) / m_itemsPerPage
;
446 int currentPage
= m_currentItem
/ m_itemsPerPage
+ 1;
447 if (m_currentItem
>= m_numItems
- m_itemsPerPage
)
448 currentPage
= numPages
;
449 text
= StringUtils::Format("{}/{}", currentPage
, numPages
);
451 else if (m_iType
== SPIN_CONTROL_TYPE_FLOAT
)
455 text
= StringUtils::Format("{:02.2f}/{:02.2f}", m_fValue
, m_fEnd
);
459 text
= StringUtils::Format("{:02.2f}", m_fValue
);
464 if (m_iValue
>= 0 && m_iValue
< (int)m_vecLabels
.size() )
468 text
= StringUtils::Format("({}/{}) {}", m_iValue
+ 1, (int)m_vecLabels
.size(),
469 m_vecLabels
[m_iValue
]);
473 text
= m_vecLabels
[m_iValue
];
477 text
= StringUtils::Format("?{}?", m_iValue
);
480 changed
|= m_label
.SetText(text
);
482 float textWidth
= m_label
.GetTextWidth() + 2 * m_label
.GetLabelInfo().offsetX
;
483 // Position the arrows
484 bool arrowsOnRight(0 != (m_label
.GetLabelInfo().align
& (XBFONT_RIGHT
| XBFONT_CENTER_X
)));
487 changed
|= m_imgspinDownFocus
->SetPosition(m_posX
+ textWidth
+ TEXT_SPACE
, m_posY
);
488 changed
|= m_imgspinDown
->SetPosition(m_posX
+ textWidth
+ TEXT_SPACE
, m_posY
);
489 changed
|= m_imgspinDownDisabled
->SetPosition(m_posX
+ textWidth
+ TEXT_SPACE
, m_posY
);
490 changed
|= m_imgspinUpFocus
->SetPosition(
491 m_posX
+ textWidth
+ TEXT_SPACE
+ m_imgspinDown
->GetWidth(), m_posY
);
492 changed
|= m_imgspinUp
->SetPosition(m_posX
+ textWidth
+ TEXT_SPACE
+ m_imgspinDown
->GetWidth(),
494 changed
|= m_imgspinUpDisabled
->SetPosition(
495 m_posX
+ textWidth
+ TEXT_SPACE
+ m_imgspinDownDisabled
->GetWidth(), m_posY
);
498 changed
|= m_imgspinDownFocus
->Process(currentTime
);
499 changed
|= m_imgspinDown
->Process(currentTime
);
500 changed
|= m_imgspinUp
->Process(currentTime
);
501 changed
|= m_imgspinUpFocus
->Process(currentTime
);
502 changed
|= m_imgspinUpDisabled
->Process(currentTime
);
503 changed
|= m_imgspinDownDisabled
->Process(currentTime
);
504 changed
|= m_label
.Process(currentTime
);
509 CGUIControl::Process(currentTime
, dirtyregions
);
512 void CGUISpinControl::Render()
514 if (m_label
.GetLabelInfo().font
)
516 float textWidth
= m_label
.GetTextWidth() + 2 * m_label
.GetLabelInfo().offsetX
;
517 // Position the arrows
518 bool arrowsOnRight(0 != (m_label
.GetLabelInfo().align
& (XBFONT_RIGHT
| XBFONT_CENTER_X
)));
521 RenderText(m_posX
- TEXT_SPACE
- textWidth
, m_posY
, textWidth
, m_height
);
523 RenderText(m_posX
+ m_imgspinDown
->GetWidth() + m_imgspinUp
->GetWidth() + TEXT_SPACE
, m_posY
,
524 textWidth
, m_height
);
526 // set our hit rectangle for MouseOver events
527 m_hitRect
= m_label
.GetRenderRect();
532 if (m_iSelect
== SPIN_BUTTON_UP
)
533 m_imgspinUpFocus
->Render();
535 m_imgspinUp
->Render();
537 if (m_iSelect
== SPIN_BUTTON_DOWN
)
538 m_imgspinDownFocus
->Render();
540 m_imgspinDown
->Render();
542 else if (!HasFocus() && !IsDisabled())
544 m_imgspinUp
->Render();
545 m_imgspinDown
->Render();
549 m_imgspinUpDisabled
->Render();
550 m_imgspinDownDisabled
->Render();
553 CGUIControl::Render();
556 void CGUISpinControl::RenderText(float posX
, float posY
, float width
, float height
)
558 m_label
.SetMaxRect(posX
, posY
, width
, height
);
559 m_label
.SetColor(GetTextColor());
563 CGUILabel::COLOR
CGUISpinControl::GetTextColor() const
566 return CGUILabel::COLOR_DISABLED
;
568 return CGUILabel::COLOR_FOCUSED
;
569 return CGUILabel::COLOR_TEXT
;
572 void CGUISpinControl::SetRange(int iStart
, int iEnd
)
578 void CGUISpinControl::SetFloatRange(float fStart
, float fEnd
)
584 void CGUISpinControl::SetValueFromLabel(const std::string
&label
)
586 if (m_iType
== SPIN_CONTROL_TYPE_TEXT
)
589 for (unsigned int i
= 0; i
< m_vecLabels
.size(); i
++)
590 if (label
== m_vecLabels
[i
])
594 m_iValue
= atoi(label
.c_str());
600 void CGUISpinControl::SetValue(int iValue
)
602 if (m_iType
== SPIN_CONTROL_TYPE_TEXT
)
605 for (unsigned int i
= 0; i
< m_vecValues
.size(); i
++)
606 if (iValue
== m_vecValues
[i
])
616 void CGUISpinControl::SetFloatValue(float fValue
)
621 void CGUISpinControl::SetStringValue(const std::string
& strValue
)
623 if (m_iType
== SPIN_CONTROL_TYPE_TEXT
)
626 for (unsigned int i
= 0; i
< m_vecStrValues
.size(); i
++)
627 if (strValue
== m_vecStrValues
[i
])
634 int CGUISpinControl::GetValue() const
636 if (m_iType
== SPIN_CONTROL_TYPE_TEXT
)
638 if (m_iValue
>= 0 && m_iValue
< (int)m_vecValues
.size())
639 return m_vecValues
[m_iValue
];
644 float CGUISpinControl::GetFloatValue() const
649 std::string
CGUISpinControl::GetStringValue() const
651 if (m_iType
== SPIN_CONTROL_TYPE_TEXT
&& m_iValue
>= 0 && m_iValue
< (int)m_vecLabels
.size())
653 if (m_iValue
< (int)m_vecStrValues
.size())
654 return m_vecStrValues
[m_iValue
];
656 return m_vecLabels
[m_iValue
];
661 void CGUISpinControl::AddLabel(const std::string
& strLabel
, int iValue
)
663 m_vecLabels
.push_back(strLabel
);
664 m_vecValues
.push_back(iValue
);
667 void CGUISpinControl::AddLabel(const std::string
& strLabel
, const std::string
& strValue
)
669 m_vecLabels
.push_back(strLabel
);
670 m_vecStrValues
.push_back(strValue
);
673 const std::string
CGUISpinControl::GetLabel() const
675 if (m_iValue
>= 0 && m_iValue
< (int)m_vecLabels
.size())
677 return m_vecLabels
[m_iValue
];
682 void CGUISpinControl::SetPosition(float posX
, float posY
)
684 CGUIControl::SetPosition(posX
, posY
);
686 m_imgspinDownFocus
->SetPosition(posX
, posY
);
687 m_imgspinDown
->SetPosition(posX
, posY
);
688 m_imgspinDownDisabled
->SetPosition(posX
, posY
);
690 m_imgspinUp
->SetPosition(m_posX
+ m_imgspinDown
->GetWidth(), m_posY
);
691 m_imgspinUpFocus
->SetPosition(m_posX
+ m_imgspinDownFocus
->GetWidth(), m_posY
);
692 m_imgspinUpDisabled
->SetPosition(m_posX
+ m_imgspinDownDisabled
->GetWidth(), m_posY
);
695 float CGUISpinControl::GetWidth() const
697 return m_imgspinDown
->GetWidth() * 2;
700 bool CGUISpinControl::CanMoveUp(bool bTestReverse
)
702 // test for reverse...
703 if (bTestReverse
&& m_bReverse
) return CanMoveDown(false);
707 case SPIN_CONTROL_TYPE_PAGE
:
708 return m_currentItem
> 0;
709 case SPIN_CONTROL_TYPE_INT
:
711 if (m_iValue
- 1 >= m_iStart
)
717 case SPIN_CONTROL_TYPE_FLOAT
:
719 if (m_fValue
- m_fInterval
>= m_fStart
)
725 case SPIN_CONTROL_TYPE_TEXT
:
727 if (m_iValue
- 1 >= 0)
736 bool CGUISpinControl::CanMoveDown(bool bTestReverse
)
738 // test for reverse...
739 if (bTestReverse
&& m_bReverse
) return CanMoveUp(false);
742 case SPIN_CONTROL_TYPE_PAGE
:
743 return m_currentItem
< m_numItems
;
744 case SPIN_CONTROL_TYPE_INT
:
746 if (m_iValue
+ 1 <= m_iEnd
)
752 case SPIN_CONTROL_TYPE_FLOAT
:
754 if (m_fValue
+ m_fInterval
<= m_fEnd
)
760 case SPIN_CONTROL_TYPE_TEXT
:
762 if (m_iValue
+ 1 < (int)m_vecLabels
.size())
771 void CGUISpinControl::PageUp()
775 case SPIN_CONTROL_TYPE_INT
:
777 if (m_iValue
- 10 >= m_iStart
)
781 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
782 SendWindowMessage(msg
);
786 case SPIN_CONTROL_TYPE_PAGE
:
789 case SPIN_CONTROL_TYPE_TEXT
:
791 if (m_iValue
- 10 >= 0)
795 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
796 SendWindowMessage(msg
);
804 void CGUISpinControl::PageDown()
808 case SPIN_CONTROL_TYPE_INT
:
810 if (m_iValue
+ 10 <= m_iEnd
)
814 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
815 SendWindowMessage(msg
);
819 case SPIN_CONTROL_TYPE_PAGE
:
822 case SPIN_CONTROL_TYPE_TEXT
:
824 if (m_iValue
+ 10 < (int)m_vecLabels
.size() )
826 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
827 SendWindowMessage(msg
);
833 void CGUISpinControl::MoveUp(bool bTestReverse
)
835 if (bTestReverse
&& m_bReverse
)
836 { // actually should move down.
842 case SPIN_CONTROL_TYPE_INT
:
844 if (m_iValue
- 1 >= m_iStart
)
846 else if (m_iValue
== m_iStart
)
848 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
849 SendWindowMessage(msg
);
854 case SPIN_CONTROL_TYPE_PAGE
:
858 case SPIN_CONTROL_TYPE_FLOAT
:
860 if (m_fValue
- m_fInterval
>= m_fStart
)
861 m_fValue
-= m_fInterval
;
864 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
865 SendWindowMessage(msg
);
870 case SPIN_CONTROL_TYPE_TEXT
:
872 if (m_iValue
- 1 >= 0)
874 else if (m_iValue
== 0)
875 m_iValue
= (int)m_vecLabels
.size() - 1;
876 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
877 SendWindowMessage(msg
);
884 void CGUISpinControl::MoveDown(bool bTestReverse
)
886 if (bTestReverse
&& m_bReverse
)
887 { // actually should move up.
893 case SPIN_CONTROL_TYPE_INT
:
895 if (m_iValue
+ 1 <= m_iEnd
)
897 else if (m_iValue
== m_iEnd
)
899 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
900 SendWindowMessage(msg
);
905 case SPIN_CONTROL_TYPE_PAGE
:
909 case SPIN_CONTROL_TYPE_FLOAT
:
911 if (m_fValue
+ m_fInterval
<= m_fEnd
)
912 m_fValue
+= m_fInterval
;
915 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
916 SendWindowMessage(msg
);
921 case SPIN_CONTROL_TYPE_TEXT
:
923 if (m_iValue
+ 1 < (int)m_vecLabels
.size() )
925 else if (m_iValue
== (int)m_vecLabels
.size() - 1)
927 CGUIMessage
msg(GUI_MSG_CLICKED
, GetID(), GetParentID());
928 SendWindowMessage(msg
);
934 void CGUISpinControl::SetReverse(bool bReverse
)
936 m_bReverse
= bReverse
;
939 void CGUISpinControl::SetFloatInterval(float fInterval
)
941 m_fInterval
= fInterval
;
944 void CGUISpinControl::SetShowRange(bool bOnoff
)
946 m_bShowRange
= bOnoff
;
949 int CGUISpinControl::GetMinimum() const
953 case SPIN_CONTROL_TYPE_PAGE
:
955 case SPIN_CONTROL_TYPE_INT
:
959 case SPIN_CONTROL_TYPE_TEXT
:
963 case SPIN_CONTROL_TYPE_FLOAT
:
964 return (int)(m_fStart
*10.0f
);
970 int CGUISpinControl::GetMaximum() const
974 case SPIN_CONTROL_TYPE_PAGE
:
976 case SPIN_CONTROL_TYPE_INT
:
980 case SPIN_CONTROL_TYPE_TEXT
:
981 return (int)m_vecLabels
.size();
984 case SPIN_CONTROL_TYPE_FLOAT
:
985 return (int)(m_fEnd
*10.0f
);
991 bool CGUISpinControl::HitTest(const CPoint
&point
) const
993 if (m_imgspinUpFocus
->HitTest(point
) || m_imgspinDownFocus
->HitTest(point
))
995 return CGUIControl::HitTest(point
);
998 bool CGUISpinControl::OnMouseOver(const CPoint
&point
)
1000 int select
= m_iSelect
;
1001 if (m_imgspinDownFocus
->HitTest(point
))
1002 m_iSelect
= SPIN_BUTTON_DOWN
;
1004 m_iSelect
= SPIN_BUTTON_UP
;
1006 if (select
!= m_iSelect
)
1009 return CGUIControl::OnMouseOver(point
);
1012 EVENT_RESULT
CGUISpinControl::OnMouseEvent(const CPoint
& point
, const MOUSE::CMouseEvent
& event
)
1014 if (event
.m_id
== ACTION_MOUSE_LEFT_CLICK
)
1016 if (m_imgspinUpFocus
->HitTest(point
))
1018 else if (m_imgspinDownFocus
->HitTest(point
))
1020 return EVENT_RESULT_HANDLED
;
1022 else if (event
.m_id
== ACTION_MOUSE_WHEEL_UP
)
1024 if (m_imgspinUpFocus
->HitTest(point
) || m_imgspinDownFocus
->HitTest(point
))
1027 return EVENT_RESULT_HANDLED
;
1030 else if (event
.m_id
== ACTION_MOUSE_WHEEL_DOWN
)
1032 if (m_imgspinUpFocus
->HitTest(point
) || m_imgspinDownFocus
->HitTest(point
))
1035 return EVENT_RESULT_HANDLED
;
1038 return EVENT_RESULT_UNHANDLED
;
1041 std::string
CGUISpinControl::GetDescription() const
1043 return StringUtils::Format("{}/{}", 1 + GetValue(), GetMaximum());
1046 bool CGUISpinControl::IsFocusedOnUp() const
1048 return (m_iSelect
== SPIN_BUTTON_UP
);
1051 void CGUISpinControl::ChangePage(int amount
)
1053 m_currentItem
+= amount
* m_itemsPerPage
;
1054 if (m_currentItem
> m_numItems
- m_itemsPerPage
)
1055 m_currentItem
= m_numItems
- m_itemsPerPage
;
1056 if (m_currentItem
< 0)
1058 CGUIMessage
message(GUI_MSG_NOTIFY_ALL
, GetParentID(), GetID(), GUI_MSG_PAGE_CHANGE
, m_currentItem
);
1059 SendWindowMessage(message
);
1062 bool CGUISpinControl::UpdateColors(const CGUIListItem
* item
)
1064 bool changed
= CGUIControl::UpdateColors(nullptr);
1065 changed
|= m_label
.UpdateColors();
1066 changed
|= m_imgspinDownFocus
->SetDiffuseColor(m_diffuseColor
);
1067 changed
|= m_imgspinDown
->SetDiffuseColor(m_diffuseColor
);
1068 changed
|= m_imgspinUp
->SetDiffuseColor(m_diffuseColor
);
1069 changed
|= m_imgspinUpFocus
->SetDiffuseColor(m_diffuseColor
);
1070 changed
|= m_imgspinUpDisabled
->SetDiffuseColor(m_diffuseColor
);
1071 changed
|= m_imgspinDownDisabled
->SetDiffuseColor(m_diffuseColor
);
1076 bool CGUISpinControl::IsVisible() const
1078 // page controls can be optionally disabled if the number of pages is 1
1079 if (m_iType
== SPIN_CONTROL_TYPE_PAGE
&& m_numItems
<= m_itemsPerPage
&& !m_showOnePage
)
1081 return CGUIControl::IsVisible();