diff --git a/src/MainWindow.cc b/src/MainWindow.cc
index 3d591755..e43cd383 100644
--- a/src/MainWindow.cc
+++ b/src/MainWindow.cc
@@ -25,6 +25,8 @@
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui_(new Ui::MainWindow)
+ , progress_modal_{nullptr}
+ , spinner_{nullptr}
{
ui_->setupUi(this);
client_ = QSharedPointer<MatrixClient>(new MatrixClient("matrix.org"));
@@ -54,11 +56,39 @@ MainWindow::MainWindow(QWidget *parent)
connect(chat_page_, SIGNAL(changeWindowTitle(QString)), this, SLOT(setWindowTitle(QString)));
connect(client_.data(),
+ SIGNAL(initialSyncCompleted(const SyncResponse &)),
+ this,
+ SLOT(removeOverlayProgressBar()));
+
+ connect(client_.data(),
SIGNAL(loginSuccess(QString, QString, QString)),
this,
SLOT(showChatPage(QString, QString, QString)));
}
+void MainWindow::removeOverlayProgressBar()
+{
+ QTimer *timer = new QTimer(this);
+ timer->setSingleShot(true);
+
+ connect(timer, &QTimer::timeout, [=]() {
+ timer->deleteLater();
+
+ if (progress_modal_ != nullptr) {
+ progress_modal_->deleteLater();
+ progress_modal_->fadeOut();
+ }
+
+ if (progress_modal_ != nullptr)
+ spinner_->deleteLater();
+
+ progress_modal_ = nullptr;
+ spinner_ = nullptr;
+ });
+
+ timer->start(500);
+}
+
void MainWindow::showChatPage(QString userid, QString homeserver, QString token)
{
QSettings settings;
@@ -69,6 +99,17 @@ void MainWindow::showChatPage(QString userid, QString homeserver, QString token)
int index = sliding_stack_->getWidgetIndex(chat_page_);
sliding_stack_->slideInIndex(index, SlidingStackWidget::AnimationDirection::LEFT_TO_RIGHT);
+ if (spinner_ == nullptr) {
+ spinner_ = new CircularProgress(this);
+ spinner_->setColor("#acc7dc");
+ spinner_->setSize(100);
+ }
+
+ if (progress_modal_ == nullptr) {
+ progress_modal_ = new OverlayModal(this, spinner_);
+ progress_modal_->fadeIn();
+ }
+
login_page_->reset();
chat_page_->bootstrap(userid, homeserver, token);
}
diff --git a/src/ui/CircularProgress.cc b/src/ui/CircularProgress.cc
new file mode 100644
index 00000000..fa74b64c
--- /dev/null
+++ b/src/ui/CircularProgress.cc
@@ -0,0 +1,190 @@
+#include <QPainter>
+#include <QParallelAnimationGroup>
+#include <QPen>
+#include <QPropertyAnimation>
+
+#include "CircularProgress.h"
+#include "Theme.h"
+
+CircularProgress::CircularProgress(QWidget *parent)
+ : QProgressBar{parent}
+ , progress_type_{ui::ProgressType::IndeterminateProgress}
+ , width_{6.25}
+ , size_{64}
+{
+ delegate_ = new CircularProgressDelegate(this);
+
+ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
+
+ auto group = new QParallelAnimationGroup(this);
+ group->setLoopCount(-1);
+
+ auto length_animation = new QPropertyAnimation(this);
+ length_animation->setPropertyName("dashLength");
+ length_animation->setTargetObject(delegate_);
+ length_animation->setEasingCurve(QEasingCurve::InOutQuad);
+ length_animation->setStartValue(0.1);
+ length_animation->setKeyValueAt(0.15, 0.2);
+ length_animation->setKeyValueAt(0.6, 20);
+ length_animation->setKeyValueAt(0.7, 20);
+ length_animation->setEndValue(20);
+ length_animation->setDuration(2050);
+
+ auto offset_animation = new QPropertyAnimation(this);
+ offset_animation->setPropertyName("dashOffset");
+ offset_animation->setTargetObject(delegate_);
+ offset_animation->setEasingCurve(QEasingCurve::InOutSine);
+ offset_animation->setStartValue(0);
+ offset_animation->setKeyValueAt(0.15, 0);
+ offset_animation->setKeyValueAt(0.6, -7);
+ offset_animation->setKeyValueAt(0.7, -7);
+ offset_animation->setEndValue(-25);
+ offset_animation->setDuration(2050);
+
+ auto angle_animation = new QPropertyAnimation(this);
+ angle_animation->setPropertyName("angle");
+ angle_animation->setTargetObject(delegate_);
+ angle_animation->setStartValue(0);
+ angle_animation->setEndValue(719);
+ angle_animation->setDuration(2050);
+
+ group->addAnimation(length_animation);
+ group->addAnimation(offset_animation);
+ group->addAnimation(angle_animation);
+
+ group->start();
+}
+
+void CircularProgress::setProgressType(ui::ProgressType type)
+{
+ progress_type_ = type;
+ update();
+}
+
+void CircularProgress::setLineWidth(qreal width)
+{
+ width_ = width;
+ update();
+ updateGeometry();
+}
+
+void CircularProgress::setSize(int size)
+{
+ size_ = size;
+ update();
+ updateGeometry();
+}
+
+ui::ProgressType CircularProgress::progressType() const
+{
+ return progress_type_;
+}
+
+qreal CircularProgress::lineWidth() const
+{
+ return width_;
+}
+
+int CircularProgress::size() const
+{
+ return size_;
+}
+
+void CircularProgress::setColor(const QColor &color)
+{
+ color_ = color;
+}
+
+QColor CircularProgress::color() const
+{
+ if (!color_.isValid()) {
+ return QColor("red");
+ }
+
+ return color_;
+}
+
+QSize CircularProgress::sizeHint() const
+{
+ const qreal s = size_ + width_ + 8;
+ return QSize(s, s);
+}
+
+void CircularProgress::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing);
+
+ /*
+ * If the progress bar is disabled draw an X instead
+ */
+ if (!isEnabled()) {
+ QPen pen;
+ pen.setCapStyle(Qt::RoundCap);
+ pen.setWidthF(lineWidth());
+ pen.setColor("gray");
+
+ auto center = rect().center();
+
+ painter.setPen(pen);
+ painter.drawLine(center - QPointF(20, 20), center + QPointF(20, 20));
+ painter.drawLine(center + QPointF(20, -20), center - QPointF(20, -20));
+
+ return;
+ }
+
+ if (progress_type_ == ui::ProgressType::IndeterminateProgress) {
+ painter.translate(width() / 2, height() / 2);
+ painter.rotate(delegate_->angle());
+ }
+
+ QPen pen;
+ pen.setCapStyle(Qt::RoundCap);
+ pen.setWidthF(width_);
+ pen.setColor(color());
+
+ if (ui::IndeterminateProgress == progress_type_) {
+ QVector<qreal> pattern;
+ pattern << delegate_->dashLength() * size_ / 50 << 30 * size_ / 50;
+
+ pen.setDashOffset(delegate_->dashOffset() * size_ / 50);
+ pen.setDashPattern(pattern);
+
+ painter.setPen(pen);
+
+ painter.drawEllipse(QPoint(0, 0), size_ / 2, size_ / 2);
+ } else {
+ painter.setPen(pen);
+
+ const qreal x = (width() - size_) / 2;
+ const qreal y = (height() - size_) / 2;
+
+ const qreal a = 360 * (value() - minimum()) / (maximum() - minimum());
+
+ QPainterPath path;
+ path.arcMoveTo(x, y, size_, size_, 0);
+ path.arcTo(x, y, size_, size_, 0, a);
+
+ painter.drawPath(path);
+ }
+}
+
+CircularProgress::~CircularProgress()
+{
+}
+
+CircularProgressDelegate::CircularProgressDelegate(CircularProgress *parent)
+ : QObject(parent)
+ , progress_(parent)
+ , dash_offset_(0)
+ , dash_length_(89)
+ , angle_(0)
+{
+ Q_ASSERT(parent);
+}
+
+CircularProgressDelegate::~CircularProgressDelegate()
+{
+}
diff --git a/src/ui/OverlayModal.cc b/src/ui/OverlayModal.cc
new file mode 100644
index 00000000..7af29268
--- /dev/null
+++ b/src/ui/OverlayModal.cc
@@ -0,0 +1,72 @@
+/*
+ * nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <QDebug>
+#include <QPainter>
+#include <QVBoxLayout>
+
+#include "OverlayModal.h"
+
+OverlayModal::OverlayModal(QWidget *parent, QWidget *content)
+ : OverlayWidget(parent)
+ , duration_{500}
+ , color_{QColor(55, 55, 55)}
+{
+ setAttribute(Qt::WA_TranslucentBackground);
+
+ auto layout = new QVBoxLayout();
+ layout->addWidget(content);
+ layout->setAlignment(Qt::AlignCenter);
+
+ setLayout(layout);
+
+ opacity_ = new QGraphicsOpacityEffect(this);
+ setGraphicsEffect(opacity_);
+
+ opacity_->setOpacity(1);
+ animation_ = new QPropertyAnimation(opacity_, "opacity", this);
+ animation_->setStartValue(1);
+ animation_->setEndValue(0);
+ animation_->setDuration(duration_);
+ animation_->setEasingCurve(QEasingCurve::Linear);
+
+ connect(animation_, &QPropertyAnimation::finished, [this]() {
+ if (animation_->direction() == QAbstractAnimation::Forward)
+ this->close();
+ });
+}
+
+void OverlayModal::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+
+ QPainter painter(this);
+ painter.fillRect(rect(), color_);
+}
+
+void OverlayModal::fadeIn()
+{
+ animation_->setDirection(QAbstractAnimation::Backward);
+ animation_->start();
+ show();
+}
+
+void OverlayModal::fadeOut()
+{
+ animation_->setDirection(QAbstractAnimation::Forward);
+ animation_->start();
+}
diff --git a/src/ui/OverlayWidget.cc b/src/ui/OverlayWidget.cc
index b4dfb918..d7e6337b 100644
--- a/src/ui/OverlayWidget.cc
+++ b/src/ui/OverlayWidget.cc
@@ -4,12 +4,11 @@
OverlayWidget::OverlayWidget(QWidget *parent)
: QWidget(parent)
{
- if (parent)
+ if (parent) {
parent->installEventFilter(this);
-}
-
-OverlayWidget::~OverlayWidget()
-{
+ setGeometry(overlayGeometry());
+ raise();
+ }
}
bool OverlayWidget::event(QEvent *event)
|