From 6af6ffa1b2069dd33f2abe85967261ecf339b63c Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 21 Jun 2016 21:09:48 +0300 Subject: [PATCH] Field autocomplete now replaces text part only up to cursor position. New radial photo load progress in MediaView instead the old 3-dots. --- Telegram/Resources/basic.style | 2 +- Telegram/SourceFiles/mediaview.cpp | 129 +++++++++++++++-------- Telegram/SourceFiles/mediaview.h | 11 +- Telegram/SourceFiles/ui/flattextarea.cpp | 4 +- 4 files changed, 97 insertions(+), 49 deletions(-) diff --git a/Telegram/Resources/basic.style b/Telegram/Resources/basic.style index 2fff5e0de..8b693196f 100644 --- a/Telegram/Resources/basic.style +++ b/Telegram/Resources/basic.style @@ -2169,7 +2169,7 @@ photoLoaderDuration2: 150; // ms fade out photoLoaderAlphaMin: 0.1; // not less than that radialSize: size(50px, 50px); -radialLine: 2px; +radialLine: 3px; radialDuration: 350; radialPeriod: 3000; radialBgOpacity: 0.4; diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index a0b1c5694..b0fb9328b 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -74,10 +74,10 @@ namespace { MediaView::MediaView() : TWidget(App::wnd()) , _animStarted(getms()) -, _docRadial(animation(this, &MediaView::step_radial)) , _docDownload(this, lang(lng_media_download), st::mvDocLink) , _docSaveAs(this, lang(lng_mediaview_save_as), st::mvDocLink) , _docCancel(this, lang(lng_cancel), st::mvDocLink) +, _radial(animation(this, &MediaView::step_radial)) , _lastAction(-st::mvDeltaFromLastAction, -st::mvDeltaFromLastAction) , _a_state(animation(this, &MediaView::step_state)) , _dropdown(this, st::mvDropdown) @@ -280,9 +280,6 @@ void MediaView::updateControls() { _docSaveAs.hide(); _docCancel.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocIconSize, _docRect.y() + st::mvDocPadding + st::mvDocLinksTop); _docCancel.show(); - if (!_docRadial.animating()) { - _docRadial.start(_doc->progress()); - } } else { if (_doc->loaded(DocumentData::FilePathResolveChecked)) { _docDownload.hide(); @@ -303,6 +300,7 @@ void MediaView::updateControls() { _docSaveAs.hide(); _docCancel.hide(); } + radialStart(); _saveVisible = ((_photo && _photo->loaded()) || (_doc && (_doc->loaded(DocumentData::FilePathResolveChecked) || (!fileShown() && (_photo || _doc))))); _saveNav = myrtlrect(width() - st::mvIconSize.width() * 2, height() - st::mvIconSize.height(), st::mvIconSize.width(), st::mvIconSize.height()); @@ -425,16 +423,56 @@ void MediaView::step_state(uint64 ms, bool timer) { } } +float64 MediaView::radialProgress() const { + if (_doc) { + return _doc->progress(); + } else if (_photo) { + return _photo->full->progress(); + } + return 1.; +} + +bool MediaView::radialLoading() const { + if (_doc) { + return _doc->loading(); + } else if (_photo) { + return _photo->full->loading(); + } + return false; +} + +QRect MediaView::radialRect() const { + if (_doc) { + return _docIconRect; + } else if (_photo) { + return _photoRadialRect; + } + return QRect(); +} + +void MediaView::radialStart() { + if (radialLoading() && !_radial.animating()) { + _radial.start(radialProgress()); + if (auto shift = radialTimeShift()) { + _radial.update(radialProgress(), !radialLoading(), getms() + shift); + } + } +} + +uint64 MediaView::radialTimeShift() const { + return _photo ? st::radialDuration : 0; +} + void MediaView::step_radial(uint64 ms, bool timer) { - if (!_doc) { - _docRadial.stop(); + if (!_doc && !_photo) { + _radial.stop(); return; } - _docRadial.update(_doc->progress(), !_doc->loading(), ms); - if (timer && _docRadial.animating()) { - update(_docIconRect); + _radial.update(radialProgress(), !radialLoading(), ms + radialTimeShift()); + if (timer && _radial.animating()) { + update(radialRect()); } - if (_doc->loaded() && _doc->size < MediaViewImageSizeLimit && (!_docRadial.animating() || _doc->isAnimation())) { + if (_doc && _doc->loaded() && _doc->size < MediaViewImageSizeLimit && (!_radial.animating() || _doc->isAnimation())) { if (!_doc->data().isEmpty() && _doc->isAnimation()) { displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid)); } else { @@ -581,8 +619,8 @@ void MediaView::onDocClick() { onSaveCancel(); } else { DocumentOpenClickHandler::doOpen(_doc, ActionOnLoadNone); - if (_doc->loading() && !_docRadial.animating()) { - _docRadial.start(_doc->progress()); + if (_doc->loading() && !_radial.animating()) { + _radial.start(_doc->progress()); } } } @@ -892,8 +930,11 @@ void MediaView::showDocument(DocumentData *doc, HistoryItem *context) { void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) { stopGif(); - _doc = 0; + _doc = nullptr; _photo = photo; + _radial.stop(); + + _photoRadialRect = QRect(QPoint((width() - st::radialSize.width()) / 2, (height() - st::radialSize.height()) / 2), st::radialSize); _zoom = 0; @@ -930,8 +971,8 @@ void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) { } else { _from = _user; } - updateControls(); _photo->download(); + updateControls(); if (isHidden()) { psUpdateOverlayed(this); show(); @@ -947,6 +988,7 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty } _doc = doc; _photo = nullptr; + _radial.stop(); _current = QPixmap(); @@ -1030,7 +1072,6 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty _docNameWidth = st::mvDocNameFont->width(_docName); } - _docRadial.stop(); // _docSize is updated in updateControls() _docRect = QRect((width() - st::mvDocSize.width()) / 2, (height() - st::mvDocSize.height()) / 2, st::mvDocSize.width(), st::mvDocSize.height()); @@ -1152,33 +1193,30 @@ void MediaView::paintEvent(QPaintEvent *e) { p.drawPixmap(_x, _y, toDraw); } - uint64 ms = 0; - if (_full < 1) { - ms = getms(); - uint64 dt = ms - _animStarted; - int32 cnt = int32(st::photoLoaderCnt), period = int32(st::photoLoaderPeriod), t = dt % period, delta = int32(st::photoLoaderDelta); - - int32 x = (width() - st::mediaviewLoader.width()) / 2; - int32 y = (height() - st::mediaviewLoader.height()) / 2; - p.fillRect(x, y, st::mediaviewLoader.width(), st::mediaviewLoader.height(), st::photoLoaderBg->b); - - x += (st::mediaviewLoader.width() - cnt * st::mediaviewLoaderPoint.width() - (cnt - 1) * st::mediaviewLoaderSkip) / 2; - y += (st::mediaviewLoader.height() - st::mediaviewLoaderPoint.height()) / 2; - QColor c(st::white->c); - QBrush b(c); - for (int32 i = 0; i < cnt; ++i) { - t -= delta; - while (t < 0) t += period; - - float64 alpha = (t >= st::photoLoaderDuration1 + st::photoLoaderDuration2) ? 0 : ((t > st::photoLoaderDuration1 ? ((st::photoLoaderDuration1 + st::photoLoaderDuration2 - t) / st::photoLoaderDuration2) : (t / st::photoLoaderDuration1))); - c.setAlphaF(st::photoLoaderAlphaMin + alpha * (1 - st::photoLoaderAlphaMin)); - b.setColor(c); - p.fillRect(x + i * (st::mediaviewLoaderPoint.width() + st::mediaviewLoaderSkip), y, st::mediaviewLoaderPoint.width(), st::mediaviewLoaderPoint.height(), b); - } - _saveMsgUpdater.start(AnimationTimerDelta); + bool radial = false; + float64 radialOpacity = 0; + if (_radial.animating()) { + _radial.step(ms); + radial = _radial.animating(); + radialOpacity = _radial.opacity(); } + if (radial) { + QRect inner(QPoint(_photoRadialRect.x(), _photoRadialRect.y()), st::radialSize); + p.setPen(Qt::NoPen); + p.setBrush(st::black); + p.setOpacity(radialOpacity * st::radialBgOpacity); + + p.setRenderHint(QPainter::HighQualityAntialiasing); + p.drawEllipse(inner); + p.setRenderHint(QPainter::HighQualityAntialiasing, false); + + p.setOpacity(1); + QRect arc(inner.marginsRemoved(QMargins(st::radialLine, st::radialLine, st::radialLine, st::radialLine))); + _radial.draw(p, arc, st::radialLine, st::white); + } + if (_saveMsgStarted) { - if (!ms) ms = getms(); + auto ms = getms(); float64 dt = float64(ms) - _saveMsgStarted, hidingDt = dt - st::medviewSaveMsgShowing - st::medviewSaveMsgShown; if (dt < st::medviewSaveMsgShowing + st::medviewSaveMsgShown + st::medviewSaveMsgHiding) { if (hidingDt >= 0 && _saveMsgOpacity.to() > 0.5) { @@ -1212,10 +1250,10 @@ void MediaView::paintEvent(QPaintEvent *e) { if (_docIconRect.intersects(r)) { bool radial = false; float64 radialOpacity = 0; - if (_docRadial.animating()) { - _docRadial.step(ms); - radial = _docRadial.animating(); - radialOpacity = _docRadial.opacity(); + if (_radial.animating()) { + _radial.step(ms); + radial = _radial.animating(); + radialOpacity = _radial.opacity(); } icon = true; if (!_doc || _doc->thumb->isNull()) { @@ -1254,7 +1292,7 @@ void MediaView::paintEvent(QPaintEvent *e) { p.setOpacity(1); QRect arc(inner.marginsRemoved(QMargins(st::radialLine, st::radialLine, st::radialLine, st::radialLine))); - _docRadial.draw(p, arc, st::radialLine, st::white); + _radial.draw(p, arc, st::radialLine, st::white); } else if (_doc && !_doc->loaded()) { p.setOpacity((o * 1. + (1 - o) * st::radialDownloadOpacity)); p.drawSpriteCenter(_docIconRect, st::radialDownload); @@ -2004,6 +2042,7 @@ void MediaView::hide() { a_cOpacity = anim::fvalue(1, 1); QWidget::hide(); stopGif(); + _radial.stop(); Notify::clipStopperHidden(ClipStopperMediaview); } diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index ec34e421c..5ccd57b55 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -111,6 +111,13 @@ private: void findCurrent(); void loadBack(); + // Radial animation interface. + float64 radialProgress() const; + bool radialLoading() const; + QRect radialRect() const; + void radialStart(); + uint64 radialTimeShift() const; + // Computes the last OverviewChatPhotos PhotoData* from _history or _migrated. struct LastChatPhoto { HistoryItem *item; @@ -173,9 +180,11 @@ private: int _docNameWidth = 0, _docSizeWidth = 0, _docExtWidth = 0; QRect _docRect, _docIconRect; int _docThumbx = 0, _docThumby = 0, _docThumbw = 0; - RadialAnimation _docRadial; LinkButton _docDownload, _docSaveAs, _docCancel; + QRect _photoRadialRect; + RadialAnimation _radial; + History *_migrated = nullptr; History *_history = nullptr; // if conversation photos or files overview PeerData *_peer = nullptr; diff --git a/Telegram/SourceFiles/ui/flattextarea.cpp b/Telegram/SourceFiles/ui/flattextarea.cpp index 4d9431344..3e0d2c318 100644 --- a/Telegram/SourceFiles/ui/flattextarea.cpp +++ b/Telegram/SourceFiles/ui/flattextarea.cpp @@ -465,9 +465,9 @@ void FlatTextarea::insertTag(const QString &text, QString tagId) { (i < 2 || !(fragmentText.at(i - 2).isLetterOrNumber() || fragmentText.at(i - 2) == '_'))) { cursor.setPosition(fragmentPosition + i - 1); int till = fragmentPosition + i; - for (; (till < fragmentEnd); ++till) { + for (; (till < fragmentEnd && till < pos); ++till) { auto ch = fragmentText.at(till - fragmentPosition); - if (!ch.isLetterOrNumber() && ch != '_') { + if (!ch.isLetterOrNumber() && ch != '_' && ch != '@') { break; } }