summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorKonstantinos Sideris <sideris.konstantin@gmail.com>2017-04-26 02:23:12 +0300
committerKonstantinos Sideris <sideris.konstantin@gmail.com>2017-04-26 02:24:10 +0300
commit415ef7e9c7b9a44a3f5da725cd252a454e4969f8 (patch)
treebddc787765f8797fdc73da91af13197d2f9d8785 /src
parentMerge pull request #6 from MTRNord/patch-1 (diff)
downloadnheko-415ef7e9c7b9a44a3f5da725cd252a454e4969f8.tar.xz
Add spinner to hide uninitialized layout after login
Diffstat (limited to 'src')
-rw-r--r--src/MainWindow.cc41
-rw-r--r--src/ui/CircularProgress.cc190
-rw-r--r--src/ui/OverlayModal.cc72
-rw-r--r--src/ui/OverlayWidget.cc9
4 files changed, 307 insertions, 5 deletions
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)