1 /*
2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9 #include "GUIDialogExtendedProgressBar.h"
10
11 #include "guilib/GUIMessage.h"
12 #include "guilib/GUIProgressControl.h"
13 #include "threads/SingleLock.h"
14 #include "threads/SystemClock.h"
15
16 #include <cmath>
17
18 #define CONTROL_LABELHEADER 30
19 #define CONTROL_LABELTITLE 31
20 #define CONTROL_PROGRESS 32
21
22 #define ITEM_SWITCH_TIME_MS 2000
23
Text(void) const24 std::string CGUIDialogProgressBarHandle::Text(void) const
25 {
26 CSingleLock lock(m_critSection);
27 std::string retVal(m_strText);
28 return retVal;
29 }
30
SetText(const std::string & strText)31 void CGUIDialogProgressBarHandle::SetText(const std::string &strText)
32 {
33 CSingleLock lock(m_critSection);
34 m_strText = strText;
35 }
36
SetTitle(const std::string & strTitle)37 void CGUIDialogProgressBarHandle::SetTitle(const std::string &strTitle)
38 {
39 CSingleLock lock(m_critSection);
40 m_strTitle = strTitle;
41 }
42
SetProgress(int currentItem,int itemCount)43 void CGUIDialogProgressBarHandle::SetProgress(int currentItem, int itemCount)
44 {
45 float fPercentage = (currentItem*100.0f)/itemCount;
46 if (!std::isnan(fPercentage))
47 m_fPercentage = std::min(100.0f, fPercentage);
48 }
49
CGUIDialogExtendedProgressBar(void)50 CGUIDialogExtendedProgressBar::CGUIDialogExtendedProgressBar(void)
51 : CGUIDialog(WINDOW_DIALOG_EXT_PROGRESS, "DialogExtendedProgressBar.xml", DialogModalityType::MODELESS)
52 {
53 m_loadType = LOAD_ON_GUI_INIT;
54 m_iLastSwitchTime = 0;
55 m_iCurrentItem = 0;
56 }
57
GetHandle(const std::string & strTitle)58 CGUIDialogProgressBarHandle *CGUIDialogExtendedProgressBar::GetHandle(const std::string &strTitle)
59 {
60 CGUIDialogProgressBarHandle *handle = new CGUIDialogProgressBarHandle(strTitle);
61 {
62 CSingleLock lock(m_critSection);
63 m_handles.push_back(handle);
64 }
65
66 Open();
67
68 return handle;
69 }
70
OnMessage(CGUIMessage & message)71 bool CGUIDialogExtendedProgressBar::OnMessage(CGUIMessage& message)
72 {
73 switch (message.GetMessage())
74 {
75 case GUI_MSG_WINDOW_INIT:
76 {
77 m_iLastSwitchTime = XbmcThreads::SystemClockMillis();
78 m_iCurrentItem = 0;
79 CGUIDialog::OnMessage(message);
80
81 UpdateState(0);
82 return true;
83 }
84 break;
85 }
86
87 return CGUIDialog::OnMessage(message);
88 }
89
Process(unsigned int currentTime,CDirtyRegionList & dirtyregions)90 void CGUIDialogExtendedProgressBar::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
91 {
92 if (m_active)
93 UpdateState(currentTime);
94
95 CGUIDialog::Process(currentTime, dirtyregions);
96 }
97
UpdateState(unsigned int currentTime)98 void CGUIDialogExtendedProgressBar::UpdateState(unsigned int currentTime)
99 {
100 std::string strHeader;
101 std::string strTitle;
102 float fProgress(-1.0f);
103
104 {
105 CSingleLock lock(m_critSection);
106
107 // delete finished items
108 for (int iPtr = m_handles.size() - 1; iPtr >= 0; iPtr--)
109 {
110 if (m_handles.at(iPtr)->IsFinished())
111 {
112 delete m_handles.at(iPtr);
113 m_handles.erase(m_handles.begin() + iPtr);
114 }
115 }
116
117 if (!m_handles.size())
118 {
119 Close(false, 0, true, false);
120 return;
121 }
122
123 // ensure the current item is in our range
124 if (m_iCurrentItem >= m_handles.size())
125 m_iCurrentItem = m_handles.size() - 1;
126
127 // update the current item ptr
128 if (currentTime > m_iLastSwitchTime &&
129 currentTime - m_iLastSwitchTime >= ITEM_SWITCH_TIME_MS)
130 {
131 m_iLastSwitchTime = currentTime;
132
133 // select next item
134 if (++m_iCurrentItem > m_handles.size() - 1)
135 m_iCurrentItem = 0;
136 }
137
138 CGUIDialogProgressBarHandle *handle = m_handles.at(m_iCurrentItem);
139 if (handle)
140 {
141 strTitle = handle->Text();
142 strHeader = handle->Title();
143 fProgress = handle->Percentage();
144 }
145 }
146
147 SET_CONTROL_LABEL(CONTROL_LABELHEADER, strHeader);
148 SET_CONTROL_LABEL(CONTROL_LABELTITLE, strTitle);
149
150 if (fProgress > -1.0f)
151 {
152 SET_CONTROL_VISIBLE(CONTROL_PROGRESS);
153 CONTROL_SELECT_ITEM(CONTROL_PROGRESS, (unsigned int)fProgress);
154 }
155 }
156