mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-23 07:15:35 +08:00
228 lines
6.5 KiB
C++
228 lines
6.5 KiB
C++
/* Copyright (C) 2015
|
|
* swift project Community / Contributors
|
|
*
|
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
|
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
|
|
* or distributed except according to the terms contained in the LICENSE file.
|
|
*
|
|
* Class based on qLed: Copyright (C) 2010 by P. Sereno, http://www.sereno-online.com
|
|
*/
|
|
|
|
#include "loadindicator.h"
|
|
#include "guiapplication.h"
|
|
|
|
#include <QColor>
|
|
#include <QPainter>
|
|
#include <QPointer>
|
|
#include <QRect>
|
|
#include <QSizePolicy>
|
|
#include <QtGlobal>
|
|
|
|
namespace BlackGui
|
|
{
|
|
CLoadIndicator::CLoadIndicator(int width, int height, QWidget *parent)
|
|
: QWidget(parent)
|
|
{
|
|
this->resize(width, height);
|
|
this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
|
this->setFocusPolicy(Qt::NoFocus);
|
|
this->setAutoFillBackground(true);
|
|
this->setStyleSheet("background-color: transparent;");
|
|
}
|
|
|
|
bool CLoadIndicator::isAnimated() const
|
|
{
|
|
return (m_timerId != -1);
|
|
}
|
|
|
|
void CLoadIndicator::setDisplayedWhenStopped(bool state)
|
|
{
|
|
m_displayedWhenStopped = state;
|
|
this->update();
|
|
}
|
|
|
|
bool CLoadIndicator::isDisplayedWhenStopped() const
|
|
{
|
|
return m_displayedWhenStopped;
|
|
}
|
|
|
|
int CLoadIndicator::startAnimation(int timeoutMs, bool processEvents)
|
|
{
|
|
m_angle = 0;
|
|
this->show();
|
|
this->setEnabled(true);
|
|
|
|
QPointer<CLoadIndicator> myself(this);
|
|
if (m_timerId == -1) { m_timerId = startTimer(m_delayMs); }
|
|
if (processEvents && sGui)
|
|
{
|
|
sGui->processEventsToRefreshGui();
|
|
if (!myself) { return -1; } // deleted in meantime (process events)
|
|
}
|
|
|
|
const int stopId = m_currentId++; // copy
|
|
if (timeoutMs > 0)
|
|
{
|
|
QTimer::singleShot(timeoutMs, this, [ = ]
|
|
{
|
|
if (!myself) { return; }
|
|
|
|
// only timeout myself id
|
|
this->stopAnimation(stopId);
|
|
emit this->timedOut();
|
|
});
|
|
}
|
|
m_pendingIds.push_back(stopId);
|
|
return stopId;
|
|
}
|
|
|
|
void CLoadIndicator::stopAnimation(int indicatorId)
|
|
{
|
|
if (indicatorId > 0)
|
|
{
|
|
m_pendingIds.removeOne(indicatorId);
|
|
// if others pending do not stop
|
|
if (!m_pendingIds.isEmpty()) { return; }
|
|
}
|
|
m_pendingIds.clear();
|
|
if (m_timerId != -1) { killTimer(m_timerId); }
|
|
m_timerId = -1;
|
|
this->hide();
|
|
this->setEnabled(false);
|
|
this->update();
|
|
}
|
|
|
|
void CLoadIndicator::setAnimationDelay(int delay)
|
|
{
|
|
m_delayMs = delay;
|
|
if (m_timerId != -1) { this->killTimer(m_timerId); }
|
|
m_timerId = this->startTimer(m_delayMs);
|
|
}
|
|
|
|
void CLoadIndicator::setColor(const QColor &color)
|
|
{
|
|
m_color = color;
|
|
update();
|
|
}
|
|
|
|
QSize CLoadIndicator::sizeHint() const
|
|
{
|
|
return QSize(64, 64);
|
|
}
|
|
|
|
int CLoadIndicator::heightForWidth(int w) const
|
|
{
|
|
return w;
|
|
}
|
|
|
|
void CLoadIndicator::timerEvent(QTimerEvent *event)
|
|
{
|
|
Q_UNUSED(event);
|
|
m_angle = (m_angle + 30) % 360;
|
|
this->update();
|
|
}
|
|
|
|
void CLoadIndicator::paintEvent(QPaintEvent *event)
|
|
{
|
|
Q_UNUSED(event);
|
|
QPainter p(this);
|
|
this->paint(p);
|
|
}
|
|
|
|
bool CLoadIndicator::isParentVisible() const
|
|
{
|
|
if (this->parentWidget()) { return parentWidget()->isVisible(); }
|
|
return false;
|
|
}
|
|
|
|
void CLoadIndicator::paint(QPainter &painter) const
|
|
{
|
|
if (!m_displayedWhenStopped && !isAnimated()) { return; }
|
|
if (!this->isVisible() || !this->isEnabled()) { return; }
|
|
if (!isParentVisible()) { return; }
|
|
|
|
int width = qMin(this->width(), this->height());
|
|
painter.setRenderHint(QPainter::Antialiasing);
|
|
|
|
// painter.setBrush(QBrush(QColor(0, 0, 255)));
|
|
// painter.drawEllipse(0, 0, width, width);
|
|
|
|
int outerRadius = qRound((width - 1) * 0.5);
|
|
int innerRadius = qRound((width - 1) * 0.5 * 0.38);
|
|
|
|
int capsuleHeight = outerRadius - innerRadius;
|
|
int capsuleWidth = (width > 32) ? qRound(capsuleHeight * .23) : qRound(capsuleHeight * .35);
|
|
int capsuleRadius = capsuleWidth / 2;
|
|
|
|
for (int i = 0; i < 12; i++)
|
|
{
|
|
QColor color = m_color;
|
|
color.setAlphaF(qRound(1.0f - (i / 12.0f)));
|
|
painter.setPen(Qt::NoPen);
|
|
painter.setBrush(color);
|
|
painter.save();
|
|
painter.translate(rect().center());
|
|
painter.rotate(m_angle - qRound(i * 30.0f));
|
|
painter.drawRoundedRect(-qRound(capsuleWidth * 0.5), -(innerRadius + capsuleHeight), capsuleWidth, capsuleHeight, capsuleRadius, capsuleRadius);
|
|
painter.restore();
|
|
}
|
|
}
|
|
|
|
void CLoadIndicator::centerLoadIndicator(const QPoint &middle)
|
|
{
|
|
const int w = this->width();
|
|
const int h = this->height();
|
|
const int x = middle.x() - w / 2;
|
|
const int y = middle.y() - h / 2;
|
|
this->setGeometry(x, y, w, h);
|
|
}
|
|
|
|
CLoadIndicatorEnabled::CLoadIndicatorEnabled(QWidget *usingWidget) :
|
|
m_usingWidget(usingWidget)
|
|
{
|
|
Q_ASSERT_X(usingWidget, Q_FUNC_INFO, "need widget");
|
|
}
|
|
|
|
bool CLoadIndicatorEnabled::isShowingLoadIndicator() const
|
|
{
|
|
return m_loadIndicator && m_usingWidget->isVisible() && m_loadIndicator->isAnimated();
|
|
}
|
|
|
|
bool CLoadIndicatorEnabled::isLoadInProgress() const
|
|
{
|
|
return m_loadInProgress;
|
|
}
|
|
|
|
void CLoadIndicatorEnabled::showLoading(int timeoutMs, bool processEvents)
|
|
{
|
|
if (!m_loadIndicator)
|
|
{
|
|
m_loadIndicator = new CLoadIndicator(64, 64, m_usingWidget);
|
|
QObject::connect(m_loadIndicator, &CLoadIndicator::timedOut, [this] { this->indicatorTimedOut(); });
|
|
}
|
|
|
|
this->centerLoadIndicator();
|
|
m_indicatorId = m_loadIndicator->startAnimation(timeoutMs, processEvents);
|
|
}
|
|
|
|
void CLoadIndicatorEnabled::hideLoading()
|
|
{
|
|
if (m_loadIndicator)
|
|
{
|
|
m_loadIndicator->stopAnimation();
|
|
}
|
|
}
|
|
|
|
void CLoadIndicatorEnabled::centerLoadIndicator()
|
|
{
|
|
if (!m_loadIndicator) { return; }
|
|
const QPoint middle = m_usingWidget->visibleRegion().boundingRect().center();
|
|
m_loadIndicator->centerLoadIndicator(middle);
|
|
}
|
|
|
|
void CLoadIndicatorEnabled::indicatorTimedOut()
|
|
{
|
|
// to be overridden
|
|
}
|
|
} // ns
|