xbmc/xbmc/dialogs/GUIDialogExtendedProgressBa...

156 lines
3.7 KiB
C++

/*
* Copyright (C) 2012-2018 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#include "GUIDialogExtendedProgressBar.h"
#include "guilib/GUIMessage.h"
#include "guilib/GUIProgressControl.h"
#include "utils/TimeUtils.h"
#include <cmath>
#include <mutex>
#define CONTROL_LABELHEADER 30
#define CONTROL_LABELTITLE 31
#define CONTROL_PROGRESS 32
#define ITEM_SWITCH_TIME_MS 2000
std::string CGUIDialogProgressBarHandle::Text(void) const
{
std::unique_lock lock(m_critSection);
std::string retVal(m_strText);
return retVal;
}
void CGUIDialogProgressBarHandle::SetText(const std::string &strText)
{
std::unique_lock lock(m_critSection);
m_strText = strText;
}
void CGUIDialogProgressBarHandle::SetTitle(const std::string &strTitle)
{
std::unique_lock lock(m_critSection);
m_strTitle = strTitle;
}
void CGUIDialogProgressBarHandle::SetProgress(int currentItem, int itemCount)
{
float fPercentage = (currentItem*100.0f)/itemCount;
if (!std::isnan(fPercentage))
m_fPercentage = std::min(100.0f, fPercentage);
}
CGUIDialogExtendedProgressBar::CGUIDialogExtendedProgressBar(void)
: CGUIDialog(WINDOW_DIALOG_EXT_PROGRESS, "DialogExtendedProgressBar.xml", DialogModalityType::MODELESS)
{
m_loadType = LOAD_ON_GUI_INIT;
m_iLastSwitchTime = 0;
m_iCurrentItem = 0;
}
CGUIDialogProgressBarHandle *CGUIDialogExtendedProgressBar::GetHandle(const std::string &strTitle)
{
CGUIDialogProgressBarHandle *handle = new CGUIDialogProgressBarHandle(strTitle);
{
std::unique_lock lock(m_critSection);
m_handles.push_back(handle);
}
Open();
return handle;
}
bool CGUIDialogExtendedProgressBar::OnMessage(CGUIMessage& message)
{
switch (message.GetMessage())
{
case GUI_MSG_WINDOW_INIT:
{
m_iLastSwitchTime = CTimeUtils::GetFrameTime();
m_iCurrentItem = 0;
CGUIDialog::OnMessage(message);
UpdateState(0);
return true;
}
break;
}
return CGUIDialog::OnMessage(message);
}
void CGUIDialogExtendedProgressBar::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
{
if (m_active)
UpdateState(currentTime);
CGUIDialog::Process(currentTime, dirtyregions);
}
void CGUIDialogExtendedProgressBar::UpdateState(unsigned int currentTime)
{
std::string strHeader;
std::string strTitle;
float fProgress(-1.0f);
{
std::unique_lock lock(m_critSection);
// delete finished items
for (int iPtr = m_handles.size() - 1; iPtr >= 0; iPtr--)
{
if (m_handles.at(iPtr)->IsFinished())
{
delete m_handles.at(iPtr);
m_handles.erase(m_handles.begin() + iPtr);
}
}
if (m_handles.empty())
{
Close(false, 0, true, false);
return;
}
// ensure the current item is in our range
if (m_iCurrentItem >= m_handles.size())
m_iCurrentItem = m_handles.size() - 1;
// update the current item ptr
if (currentTime > m_iLastSwitchTime &&
currentTime - m_iLastSwitchTime >= ITEM_SWITCH_TIME_MS)
{
m_iLastSwitchTime = currentTime;
// select next item
if (++m_iCurrentItem > m_handles.size() - 1)
m_iCurrentItem = 0;
}
CGUIDialogProgressBarHandle *handle = m_handles.at(m_iCurrentItem);
if (handle)
{
strTitle = handle->Text();
strHeader = handle->Title();
fProgress = handle->Percentage();
}
}
SET_CONTROL_LABEL(CONTROL_LABELHEADER, strHeader);
SET_CONTROL_LABEL(CONTROL_LABELTITLE, strTitle);
if (fProgress > -1.0f)
{
SET_CONTROL_VISIBLE(CONTROL_PROGRESS);
CONTROL_SELECT_ITEM(CONTROL_PROGRESS, (unsigned int)fProgress);
}
}