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 "GUIDialogProgress.h"
11 #include "guilib/GUIProgressControl.h"
12 #include "guilib/GUIWindowManager.h"
13 #include "guilib/LocalizeStrings.h"
14 #include "guilib/guiinfo/GUIInfoLabels.h"
15 #include "utils/Variant.h"
16 #include "utils/log.h"
20 using namespace std::chrono_literals
;
22 CGUIDialogProgress::CGUIDialogProgress(void)
23 : CGUIDialogBoxBase(WINDOW_DIALOG_PROGRESS
, "DialogConfirm.xml")
28 CGUIDialogProgress::~CGUIDialogProgress(void) = default;
30 void CGUIDialogProgress::Reset()
32 std::unique_lock
<CCriticalSection
> lock(m_section
);
36 m_showProgress
= true;
38 m_iChoice
= CHOICE_NONE
;
39 m_supportedChoices
= {};
44 void CGUIDialogProgress::SetCanCancel(bool bCanCancel
)
46 std::unique_lock
<CCriticalSection
> lock(m_section
);
47 m_bCanCancel
= bCanCancel
;
51 void CGUIDialogProgress::ShowChoice(int iChoice
, const CVariant
& label
)
53 if (iChoice
>= 0 && iChoice
< DIALOG_MAX_CHOICES
)
55 m_supportedChoices
[iChoice
] = true;
56 SetChoice(iChoice
, label
);
61 int CGUIDialogProgress::GetChoice() const
66 void CGUIDialogProgress::Open(const std::string
¶m
/* = "" */)
68 CLog::Log(LOGDEBUG
, "DialogProgress::Open called {}", m_active
? "(already running)!" : "");
71 std::unique_lock
<CCriticalSection
> lock(CServiceBroker::GetWinSystem()->GetGfxContext());
72 ShowProgressBar(true);
75 CGUIDialog::Open(false, param
);
77 while (m_active
&& IsAnimating(ANIM_TYPE_WINDOW_OPEN
))
80 // we should have rendered at least once by now - if we haven't, then
81 // we must be running from fullscreen video or similar where the
82 // calling thread handles rendering (ie not main app thread) but
83 // is waiting on this routine before rendering begins
89 void CGUIDialogProgress::Progress()
97 bool CGUIDialogProgress::OnMessage(CGUIMessage
& message
)
99 switch ( message
.GetMessage() )
102 case GUI_MSG_WINDOW_DEINIT
:
106 case GUI_MSG_CLICKED
:
108 int iControl
= message
.GetSenderId();
109 if (iControl
>= CONTROL_CHOICES_START
&& iControl
< (CONTROL_CHOICES_START
+ DIALOG_MAX_CHOICES
))
111 // special handling for choice 0 mapped to cancel button
112 if (m_bCanCancel
&& !m_supportedChoices
[0] && (iControl
== CONTROL_CHOICES_START
))
114 if (m_iChoice
!= CHOICE_CANCELED
)
116 std::string strHeading
= m_strHeading
;
117 strHeading
.append(" : ");
118 strHeading
.append(g_localizeStrings
.Get(16024));
119 CGUIDialogBoxBase::SetHeading(CVariant
{strHeading
});
120 m_iChoice
= CHOICE_CANCELED
;
125 m_iChoice
= iControl
- CONTROL_CHOICES_START
;
132 return CGUIDialog::OnMessage(message
);
135 bool CGUIDialogProgress::OnBack(int actionID
)
138 m_iChoice
= CHOICE_CANCELED
;
140 m_iChoice
= CHOICE_NONE
;
145 void CGUIDialogProgress::OnWindowLoaded()
147 CGUIDialog::OnWindowLoaded();
148 CGUIControl
*control
= GetControl(CONTROL_PROGRESS_BAR
);
149 if (control
&& control
->GetControlType() == CGUIControl::GUICONTROL_PROGRESS
)
151 // make sure we have the appropriate info set
152 CGUIProgressControl
*progress
= static_cast<CGUIProgressControl
*>(control
);
153 if (!progress
->GetInfo())
154 progress
->SetInfo(SYSTEM_PROGRESS_BAR
);
158 void CGUIDialogProgress::SetPercentage(int iPercentage
)
160 if (iPercentage
< 0) iPercentage
= 0;
161 if (iPercentage
> 100) iPercentage
= 100;
163 if (iPercentage
!= m_percentage
)
166 m_percentage
= iPercentage
;
169 void CGUIDialogProgress::SetProgressMax(int iMax
)
175 void CGUIDialogProgress::SetProgressAdvance(int nSteps
/*=1*/)
179 if (m_iCurrent
>m_iMax
)
183 SetPercentage((m_iCurrent
*100)/m_iMax
);
186 bool CGUIDialogProgress::Abort()
188 return m_active
? IsCanceled() : false;
191 void CGUIDialogProgress::ShowProgressBar(bool bOnOff
)
193 std::unique_lock
<CCriticalSection
> lock(m_section
);
194 m_showProgress
= bOnOff
;
198 bool CGUIDialogProgress::Wait(int progresstime
/*= 10*/)
201 while (!m_done
.Wait(std::chrono::milliseconds(progresstime
)) && m_active
&& !IsCanceled())
204 return !IsCanceled();
207 bool CGUIDialogProgress::WaitOnEvent(CEvent
& event
)
209 while (!event
.Wait(1ms
))
217 return !IsCanceled();
220 void CGUIDialogProgress::UpdateControls()
222 // take a copy to save holding the lock for too long
225 std::array
<bool, DIALOG_MAX_CHOICES
> choices
;
227 std::unique_lock
<CCriticalSection
> lock(m_section
);
228 bShowProgress
= m_showProgress
;
229 bShowCancel
= m_bCanCancel
;
230 choices
= m_supportedChoices
;
234 SET_CONTROL_VISIBLE(CONTROL_PROGRESS_BAR
);
236 SET_CONTROL_HIDDEN(CONTROL_PROGRESS_BAR
);
238 bool bAllHidden
= true;
239 for (int i
= 0; i
< DIALOG_MAX_CHOICES
; ++i
)
244 SET_CONTROL_VISIBLE(CONTROL_CHOICES_START
+ i
);
247 SET_CONTROL_HIDDEN(CONTROL_CHOICES_START
+ i
);
250 // special handling for choice 0 mapped to cancel button
251 if (bShowCancel
&& bAllHidden
)
252 SET_CONTROL_VISIBLE(CONTROL_CHOICES_START
);
255 void CGUIDialogProgress::Process(unsigned int currentTime
, CDirtyRegionList
&dirtyregions
)
260 CGUIDialogBoxBase::Process(currentTime
, dirtyregions
);
263 void CGUIDialogProgress::OnInitWindow()
267 bool bNoFocus
= true;
268 for (int i
= 0; i
< DIALOG_MAX_CHOICES
; ++i
)
270 if (m_supportedChoices
[i
])
273 SET_CONTROL_FOCUS(CONTROL_CHOICES_START
+ i
, 0);
278 // special handling for choice 0 mapped to cancel button
279 if (m_bCanCancel
&& bNoFocus
)
280 SET_CONTROL_FOCUS(CONTROL_CHOICES_START
,0 );
282 CGUIDialogBoxBase::OnInitWindow();
285 int CGUIDialogProgress::GetDefaultLabelID(int controlId
) const
287 // special handling for choice 0 mapped to cancel button
288 if (m_bCanCancel
&& !m_supportedChoices
[0] && (controlId
== CONTROL_CHOICES_START
))
289 return 222; // Cancel
291 return CGUIDialogBoxBase::GetDefaultLabelID(controlId
);