diff --git a/Telegram/Resources/lang.txt b/Telegram/Resources/lang.txt index 39027f7b8..29fc0aeb3 100644 --- a/Telegram/Resources/lang.txt +++ b/Telegram/Resources/lang.txt @@ -24,8 +24,7 @@ lng_menu_settings: "Settings"; lng_menu_about: "About"; lng_menu_update: "Update"; lng_menu_restart: "Restart"; -lng_menu_start_messaging: "Start Messaging"; -lng_menu_conversations: "Conversations List"; +lng_menu_back: "Back"; lng_open_from_tray: "Open Telegram"; lng_minimize_to_tray: "Minimize to tray"; @@ -272,6 +271,7 @@ some of the new settings. Restart now?"; lng_settings_restart_now: "Restart"; lng_settings_restart_later: "Later"; +lng_topbar_info: "Info"; lng_profile_settings_section: "Settings"; lng_profile_participants_section: "Participants"; lng_profile_info: "Contact info"; diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index 0b0ab8a7c..9e6d40cf7 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -64,7 +64,7 @@ titleHeight: 39px; titleShadowColor: rgba(0, 0, 0, 24);//#ebebeb titleShadow: 1px; titleIconPos: point(7px, 7px); -titleIconRect: sprite(160px, 100px, 26px, 26px); +titleIconImg: sprite(160px, 100px, 26px, 26px); titleFont: font(17px); titlePos: point(44px, 29px); titleMenuOffset: 36px; @@ -695,9 +695,10 @@ dlgActiveDateColor: #d3e2ee; topBarHeight: 54px; topBarBG: white; topBarDuration: 200; -topBarForwardPadding: margins(17px, 8px, 40px, 8px); +topBarForwardPadding: margins(17px, 8px, 39px, 8px); topBarForwardAlpha: 0.6; topBarForwardImg: sprite(45px, 112px, 9px, 16px); +topBarBackwardImg: sprite(35px, 112px, 9px, 16px); topBarBackPadding: margins(15px, 7px, 9px, 7px); topBarBackAlpha: 0.8; topBarBackImg: sprite(65px, 112px, 9px, 16px); @@ -1584,6 +1585,7 @@ medviewDocumentSprite: sprite(341px, 150px, 20px, 22px); medviewDocumentSpritePos: point(16px, 13px); medviewPhotoSprite: sprite(363px, 150px, 23px, 20px); medviewPhotoSpritePos: point(14px, 14px); +medviewTransparentBrush: sprite(148px, 197px, 8px, 8px); overviewPhotoSkip: 10px; overviewPhotoMinSize: 100px; diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index aacdbd56a..d079e1421 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -1963,7 +1963,7 @@ namespace App { ::quiting = true; } - QImage readImage(QByteArray data, QByteArray *format) { + QImage readImage(QByteArray data, QByteArray *format, bool opaque) { QByteArray tmpFormat; QImage result; QBuffer buffer(&data); @@ -1999,7 +1999,7 @@ namespace App { } exif_data_free(exifData); } - } else { + } else if (opaque) { QImage solid(result.width(), result.height(), QImage::Format_ARGB32_Premultiplied); solid.fill(st::white->c); { @@ -2010,12 +2010,12 @@ namespace App { return result; } - QImage readImage(const QString &file, QByteArray *format) { + QImage readImage(const QString &file, QByteArray *format, bool opaque) { QFile f(file); if (!f.open(QIODevice::ReadOnly)) { return QImage(); } - return readImage(f.readAll(), format); + return readImage(f.readAll(), format, opaque); } void regVideoItem(VideoData *data, HistoryItem *item) { diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index 6aa525acc..b509343c8 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -168,9 +168,8 @@ namespace App { bool quiting(); void setQuiting(); - - QImage readImage(QByteArray data, QByteArray *format = 0); - QImage readImage(const QString &file, QByteArray *format = 0); + QImage readImage(QByteArray data, QByteArray *format = 0, bool opaque = true); + QImage readImage(const QString &file, QByteArray *format = 0, bool opaque = true); void regVideoItem(VideoData *data, HistoryItem *item); void unregVideoItem(VideoData *data, HistoryItem *item); diff --git a/Telegram/SourceFiles/art/sprite.png b/Telegram/SourceFiles/art/sprite.png index a60025e09..de873f401 100644 Binary files a/Telegram/SourceFiles/art/sprite.png and b/Telegram/SourceFiles/art/sprite.png differ diff --git a/Telegram/SourceFiles/art/sprite_200x.png b/Telegram/SourceFiles/art/sprite_200x.png index c6d94a8aa..c14bf4f47 100644 Binary files a/Telegram/SourceFiles/art/sprite_200x.png and b/Telegram/SourceFiles/art/sprite_200x.png differ diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index 721c14393..103fe2192 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -93,6 +93,7 @@ enum { MediaViewImageSizeLimit = 100 * 1024 * 1024, // show up to 100mb jpg/png/gif docs in app MaxZoomLevel = 7, // x8 + ZoomToScreenLevel = 1024, // just constant PreloadHeightsCount = 3, // when 3 screens to scroll left make a preload request EmojiPadPerRow = 7, diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 457bedaa0..d241c6600 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -596,7 +596,7 @@ void DialogsListWidget::dialogsReceived(const QVector &added) { addDialog(i->c_dialog()); } } - if (App::wnd()) App::wnd()->psUpdateCounter(); + if (App::wnd()) App::wnd()->updateCounter(); if (!sel && dialogs.list.count) { sel = dialogs.list.begin; contactSel = false; @@ -1309,7 +1309,7 @@ void DialogsWidget::unreadCountsReceived(const QVector &dialogs) { } } } - if (App::wnd()) App::wnd()->psUpdateCounter(); + if (App::wnd()) App::wnd()->updateCounter(); } void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs) { diff --git a/Telegram/SourceFiles/gui/twidget.h b/Telegram/SourceFiles/gui/twidget.h index 7feb6458d..033d238f9 100644 --- a/Telegram/SourceFiles/gui/twidget.h +++ b/Telegram/SourceFiles/gui/twidget.h @@ -33,6 +33,8 @@ public: virtual void leaveToChildEvent(QEvent *e) { // e -- from enterEvent() of child TWidget } + virtual void enterFromChildEvent(QEvent *e) { // e -- from leaveEvent() of child TWidget + } bool event(QEvent *e) { return QWidget::event(e); @@ -44,6 +46,10 @@ protected: TWidget *p(tparent()); if (p) p->leaveToChildEvent(e); } + void leaveEvent(QEvent *e) { + TWidget *p(tparent()); + if (p) p->enterFromChildEvent(e); + } private: diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 8f24af298..655015e4c 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -637,7 +637,7 @@ void DocumentOpenLink::onClick(Qt::MouseButton button) const { if (reader.supportsAnimation() && reader.imageCount() > 1 && App::hoveredLinkItem()) { startGif(App::hoveredLinkItem(), already); } else { - App::wnd()->showDocument(data, QPixmap::fromImage(App::readImage(already)), App::hoveredLinkItem()); + App::wnd()->showDocument(data, QPixmap::fromImage(App::readImage(already, 0, false)), App::hoveredLinkItem()); } } else { psOpenFile(already); @@ -1631,7 +1631,7 @@ void History::setUnreadCount(int32 newUnreadCount, bool psUpdate) { App::histories().unreadFull += newUnreadCount - unreadCount; if (mute) App::histories().unreadMuted += newUnreadCount - unreadCount; unreadCount = newUnreadCount; - if (psUpdate) App::wnd()->psUpdateCounter(); + if (psUpdate) App::wnd()->updateCounter(); if (unreadBar) unreadBar->setCount(unreadCount); } } @@ -1646,7 +1646,7 @@ void History::setMsgCount(int32 newMsgCount) { if (mute != newMute) { App::histories().unreadMuted += newMute ? unreadCount : (-unreadCount); mute = newMute; - App::wnd()->psUpdateCounter(); + App::wnd()->updateCounter(); } } diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index e9949fe93..517b0c358 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -2718,7 +2718,9 @@ void HistoryWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) if (!hist) return; - QRect rectForName(st::topBarForwardPadding.left(), st::topBarForwardPadding.top(), width() - decreaseWidth - st::topBarForwardPadding.left() - st::topBarForwardPadding.right(), st::msgNameFont->height); + int32 increaseLeft = decreaseWidth; + if (!cWideMode()) decreaseWidth += (st::topBarForwardPadding.right() - st::topBarForwardPadding.left()); + QRect rectForName(st::topBarForwardPadding.left() + increaseLeft, st::topBarForwardPadding.top(), width() - decreaseWidth - st::topBarForwardPadding.left() - st::topBarForwardPadding.right(), st::msgNameFont->height); p.setFont(st::dlgHistFont->f); if (hist->typing.isEmpty()) { p.setPen(st::titleStatusColor->p); @@ -2731,9 +2733,12 @@ void HistoryWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) p.setPen(st::dlgNameColor->p); hist->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); - if (!decreaseWidth) { + if (cWideMode()) { p.setOpacity(st::topBarForwardAlpha + (1 - st::topBarForwardAlpha) * over); p.drawPixmap(QPoint(width() - (st::topBarForwardPadding.right() + st::topBarForwardImg.pxWidth()) / 2, (st::topBarHeight - st::topBarForwardImg.pxHeight()) / 2), App::sprite(), st::topBarForwardImg); + } else { + p.setOpacity(st::topBarForwardAlpha + (1 - st::topBarForwardAlpha) * over); + p.drawPixmap(QPoint((st::topBarForwardPadding.right() - st::topBarBackwardImg.pxWidth()) / 2, (st::topBarHeight - st::topBarBackwardImg.pxHeight()) / 2), App::sprite(), st::topBarBackwardImg); } } @@ -2745,7 +2750,11 @@ void HistoryWidget::topBarShadowParams(int32 &x, float64 &o) { } void HistoryWidget::topBarClick() { - if (hist) App::main()->showPeerProfile(histPeer); + if (cWideMode()) { + if (hist) App::main()->showPeerProfile(histPeer); + } else { + App::main()->onShowDialogs(); + } } void HistoryWidget::updateOnlineDisplay(int32 x, int32 w) { diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 1c92c05da..5c59b6941 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -28,11 +28,12 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "audio.h" -TopBarWidget::TopBarWidget(MainWidget *w) : QWidget(w), +TopBarWidget::TopBarWidget(MainWidget *w) : TWidget(w), a_over(0), _drawShadow(true), _selCount(0), _selStrWidth(0), _animating(false), _clearSelection(this, lang(lng_selected_clear), st::topBarButton), _forward(this, lang(lng_selected_forward), st::topBarActionButton), _delete(this, lang(lng_selected_delete), st::topBarActionButton), + _info(this, lang(lng_topbar_info), st::topBarButton), _edit(this, lang(lng_profile_edit_contact), st::topBarButton), _leaveGroup(this, lang(lng_profile_delete_and_exit), st::topBarButton), _addContact(this, lang(lng_profile_add_contact), st::topBarButton), @@ -42,6 +43,7 @@ TopBarWidget::TopBarWidget(MainWidget *w) : QWidget(w), connect(&_forward, SIGNAL(clicked()), this, SLOT(onForwardSelection())); connect(&_delete, SIGNAL(clicked()), this, SLOT(onDeleteSelection())); connect(&_clearSelection, SIGNAL(clicked()), this, SLOT(onClearSelection())); + connect(&_info, SIGNAL(clicked()), this, SLOT(onInfoClicked())); connect(&_addContact, SIGNAL(clicked()), this, SLOT(onAddContact())); connect(&_deleteContact, SIGNAL(clicked()), this, SLOT(onDeleteContact())); connect(&_edit, SIGNAL(clicked()), this, SLOT(onEdit())); @@ -63,9 +65,9 @@ void TopBarWidget::onClearSelection() { if (App::main()) App::main()->clearSelectedItems(); } -void TopBarWidget::onEdit() { - PeerData *p = App::main() ? App::main()->profilePeer() : 0; - if (p) App::wnd()->showLayer(new AddContactBox(p)); +void TopBarWidget::onInfoClicked() { + PeerData *p = App::main() ? App::main()->historyPeer() : 0; + if (p) App::main()->showPeerProfile(p); } void TopBarWidget::onAddContact() { @@ -74,6 +76,11 @@ void TopBarWidget::onAddContact() { if (u) App::wnd()->showLayer(new AddContactBox(u->firstName, u->lastName, u->phone)); } +void TopBarWidget::onEdit() { + PeerData *p = App::main() ? App::main()->profilePeer() : 0; + if (p) App::wnd()->showLayer(new AddContactBox(p)); +} + void TopBarWidget::onDeleteContact() { PeerData *p = App::main() ? App::main()->profilePeer() : 0; UserData *u = (p && !p->chat) ? p->asUser() : 0; @@ -119,11 +126,21 @@ void TopBarWidget::enterEvent(QEvent *e) { anim::start(this); } +void TopBarWidget::enterFromChildEvent(QEvent *e) { + a_over.start(1); + anim::start(this); +} + void TopBarWidget::leaveEvent(QEvent *e) { a_over.start(0); anim::start(this); } +void TopBarWidget::leaveToChildEvent(QEvent *e) { + a_over.start(0); + anim::start(this); +} + bool TopBarWidget::animStep(float64 ms) { float64 dt = ms / st::topBarDuration; bool res = true; @@ -148,7 +165,7 @@ void TopBarWidget::paintEvent(QPaintEvent *e) { p.fillRect(QRect(0, 0, width(), st::topBarHeight), st::topBarBG->b); if (_clearSelection.isHidden()) { p.save(); - main()->paintTopBar(p, a_over.current(), 0); + main()->paintTopBar(p, a_over.current(), _info.isHidden() ? 0 : _info.width()); p.restore(); } else { p.setFont(st::linkFont->f); @@ -184,6 +201,7 @@ void TopBarWidget::resizeEvent(QResizeEvent *e) { _forward.move(availX + (availW - _forward.width() - _delete.width() - st::topBarActionSkip) / 2, (st::topBarHeight - _forward.height()) / 2); _delete.move(availX + (availW + _forward.width() - _delete.width() + st::topBarActionSkip) / 2, (st::topBarHeight - _forward.height()) / 2); } + if (!_info.isHidden()) _info.move(r -= _info.width(), 0); if (!_clearSelection.isHidden()) _clearSelection.move(r -= _clearSelection.width(), 0); if (!_deleteContact.isHidden()) _deleteContact.move(r -= _deleteContact.width(), 0); if (!_leaveGroup.isHidden()) _leaveGroup.move(r -= _leaveGroup.width(), 0); @@ -193,6 +211,7 @@ void TopBarWidget::resizeEvent(QResizeEvent *e) { } void TopBarWidget::startAnim() { + _info.hide(); _edit.hide(); _leaveGroup.hide(); _addContact.hide(); @@ -237,6 +256,7 @@ void TopBarWidget::showAll() { _deleteContact.hide(); } _clearSelection.hide(); + _info.hide(); _delete.hide(); _forward.hide(); _mediaType.hide(); @@ -260,6 +280,11 @@ void TopBarWidget::showAll() { _mediaType.hide(); } } + if (App::main() && App::main()->historyPeer() && !cWideMode()) { + _info.show(); + } else { + _info.hide(); + } } resizeEvent(0); } @@ -1043,7 +1068,7 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) { if (reader.supportsAnimation() && reader.imageCount() > 1 && item) { startGif(item, already); } else { - App::wnd()->showDocument(document, QPixmap::fromImage(App::readImage(already)), item); + App::wnd()->showDocument(document, QPixmap::fromImage(App::readImage(already, 0, false)), item); } } else { psOpenFile(already); @@ -1262,6 +1287,10 @@ void MainWidget::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPe dialogs.peerAfter(inPeer, inMsg, outPeer, outMsg); } +PeerData *MainWidget::historyPeer() { + return history.peer(); +} + PeerData *MainWidget::peer() { return overview ? overview->peer() : history.peer(); } @@ -1754,13 +1783,14 @@ void MainWidget::keyPressEvent(QKeyEvent *e) { void MainWidget::updateWideMode() { showAll(); + _topBar.showAll(); } bool MainWidget::needBackButton() { return overview || profile || (history.peer() && history.peer()->id); } -void MainWidget::onTitleBack() { +void MainWidget::onShowDialogs() { showPeer(0, 0, false, true); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 772fed892..d6cb446e3 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -30,7 +30,7 @@ struct DialogRow; class MainWidget; class ConfirmBox; -class TopBarWidget : public QWidget, public Animated { +class TopBarWidget : public TWidget, public Animated { Q_OBJECT public: @@ -38,7 +38,9 @@ public: TopBarWidget(MainWidget *w); void enterEvent(QEvent *e); + void enterFromChildEvent(QEvent *e); void leaveEvent(QEvent *e); + void leaveToChildEvent(QEvent *e); void paintEvent(QPaintEvent *e); void mousePressEvent(QMouseEvent *e); void resizeEvent(QResizeEvent *e); @@ -58,6 +60,7 @@ public slots: void onForwardSelection(); void onDeleteSelection(); void onClearSelection(); + void onInfoClicked(); void onAddContact(); void onEdit(); void onDeleteContact(); @@ -83,6 +86,7 @@ private: FlatButton _clearSelection; FlatButton _forward, _delete; + FlatButton _info; FlatButton _edit, _leaveGroup, _addContact, _deleteContact; FlatButton _mediaType; @@ -170,7 +174,7 @@ public: void updateWideMode(); bool needBackButton(); - void onTitleBack(); + void onShowDialogs(); void paintTopBar(QPainter &p, float64 over, int32 decreaseWidth); void topBarShadowParams(int32 &x, float64 &o); @@ -211,6 +215,7 @@ public: void peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg); void peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg); + PeerData *historyPeer(); PeerData *peer(); PeerData *activePeer(); MsgId activeMsgId(); diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 50b65e8a6..75649a738 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -46,7 +46,7 @@ namespace { MediaView::MediaView() : TWidget(App::wnd()), _photo(0), _doc(0), _availBottom(0), _leftNavVisible(false), _rightNavVisible(false), _animStarted(getms()), _maxWidth(0), _maxHeight(0), _width(0), _x(0), _y(0), _w(0), _h(0), _xStart(0), _yStart(0), -_zoom(0), _pressed(false), _dragging(0), _full(-1), _history(0), _peer(0), _user(0), _from(0), _index(-1), _msgid(0), +_zoom(0), _zoomToScreen(0), _pressed(false), _dragging(0), _full(-1), _history(0), _peer(0), _user(0), _from(0), _index(-1), _msgid(0), _loadRequest(0), _over(OverNone), _down(OverNone), _lastAction(-st::medviewDeltaFromLastAction, -st::medviewDeltaFromLastAction), _close(this, st::medviewClose), _save(this, st::medviewSaveAs, lang(lng_mediaview_save)), @@ -62,6 +62,8 @@ _saveMsgStarted(0), _saveMsgOpacity(0) _saveMsg = QRect(0, 0, _saveMsgText.maxWidth() + st::medviewSaveMsgPadding.left() + st::medviewSaveMsgPadding.right(), st::medviewSaveMsgFont->height + st::medviewSaveMsgPadding.top() + st::medviewSaveMsgPadding.bottom()); _saveMsgText.setLink(1, TextLinkPtr(new SaveMsgLink(this))); + _transparentBrush = QBrush(App::sprite().copy(st::medviewTransparentBrush)); + setWindowFlags(Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::Tool | Qt::NoDropShadowWindowHint); moveToScreen(); setAttribute(Qt::WA_NoSystemBackground, true); @@ -392,12 +394,12 @@ void MediaView::showPhoto(PhotoData *photo, PeerData *context) { _saveMsgStarted = 0; _loadRequest = 0; _over = OverNone; + setCursor(style::cur_default); if (!_animations.isEmpty()) { _animations.clear(); anim::stop(this); } if (!_animOpacities.isEmpty()) _animOpacities.clear(); - setCursor(style::cur_default); _msgid = 0; _index = -1; @@ -427,7 +429,6 @@ void MediaView::showDocument(DocumentData *doc, QPixmap pix, HistoryItem *contex _saveMsgStarted = 0; _peer = 0; _user = 0; - _zoom = 0; _msgid = context ? context->id : 0; _index = -1; _loadRequest = 0; @@ -440,9 +441,7 @@ void MediaView::showDocument(DocumentData *doc, QPixmap pix, HistoryItem *contex anim::stop(this); } if (!_animOpacities.isEmpty()) _animOpacities.clear(); - setCursor(style::cur_default); - QString name = doc->already(); _current = pix; _current.setDevicePixelRatio(cRetinaFactor()); _doc = doc; @@ -452,9 +451,35 @@ void MediaView::showDocument(DocumentData *doc, QPixmap pix, HistoryItem *contex } _w = _current.width() / cIntRetinaFactor(); _h = _current.height() / cIntRetinaFactor(); - _x = (_avail.width() - _w) / 2; - _y = st::medviewPolaroid.top() + (_avail.height() - st::medviewPolaroid.top() - st::medviewPolaroid.bottom() - st::medviewBottomBar - _h) / 2; _width = _w; + if (_w > 0 && _h > 0) { + _zoomToScreen = float64(_avail.width()) / _w; + if (_h * _zoomToScreen > (_avail.height() - st::medviewBottomBar)) { + _zoomToScreen = float64(_avail.height() - st::medviewBottomBar) / _h; + } + if (_zoomToScreen >= 1.) { + _zoomToScreen -= 1.; + } else { + _zoomToScreen = 1. - (1. / _zoomToScreen); + } + } else { + _zoomToScreen = 0; + } + if ((_w > _avail.width()) || (_h > (_avail.height() - st::medviewBottomBar))) { + _zoom = ZoomToScreenLevel; + if (_zoomToScreen >= 0) { + _w = qRound(_w * (_zoomToScreen + 1)); + _h = qRound(_h * (_zoomToScreen + 1)); + } else { + _w = qRound(_w / (-_zoomToScreen + 1)); + _h = qRound(_h / (-_zoomToScreen + 1)); + } + snapXY(); + } else { + _zoom = 0; + } + _x = (_avail.width() - _w) / 2; + _y = (_avail.height() - st::medviewBottomBar - _h) / 2; _from = App::user(_doc->user); _full = 1; updateControls(); @@ -469,6 +494,7 @@ void MediaView::showPhoto(PhotoData *photo) { _photo = photo; _doc = 0; _zoom = 0; + _zoomToScreen = 0; MTP::clearLoaderPriorities(); _full = -1; _current = QPixmap(); @@ -555,6 +581,9 @@ void MediaView::paintEvent(QPaintEvent *e) { if (_photo || !_current.isNull()) { QRect imgRect(_x, _y, _w, _h); if (imgRect.intersects(r)) { + if (_current.hasAlpha()) { + p.fillRect(imgRect, _transparentBrush); + } if (_zoom) { bool was = (p.renderHints() & QPainter::SmoothPixmapTransform); if (!was) p.setRenderHint(QPainter::SmoothPixmapTransform, true); @@ -564,7 +593,7 @@ void MediaView::paintEvent(QPaintEvent *e) { p.drawPixmap(_x, _y, _current); } } - if (_polaroidOut.intersects(r)) { + if (!_doc && _polaroidOut.intersects(r)) { // polaroid p.fillRect(_polaroidOut.x(), _polaroidOut.y(), _polaroidIn.x() - _polaroidOut.x(), _polaroidOut.height(), st::white->b); p.fillRect(_polaroidIn.x() + _polaroidIn.width(), _polaroidOut.y(), _polaroidOut.x() + _polaroidOut.width() - _polaroidIn.x() - _polaroidIn.width(), _polaroidOut.height(), st::white->b); @@ -573,10 +602,10 @@ void MediaView::paintEvent(QPaintEvent *e) { } if (imgRect.intersects(r)) { uint64 ms = 0; - if (imgRect.intersects(_leftNav)) { + if (!_doc && imgRect.intersects(_leftNav)) { p.fillRect(imgRect.intersected(_leftNav), _leftNavVisible ? overColor(st::medviewBG->c, 1, st::black->c, overLevel(OverLeftNav) * st::medviewNavBGOpacity) : st::medviewBG->c); } - if (imgRect.intersects(_rightNav)) { + if (!_doc && imgRect.intersects(_rightNav)) { p.fillRect(imgRect.intersected(_rightNav), _rightNavVisible ? overColor(st::medviewBG->c, 1, st::black->c, overLevel(OverRightNav) * st::medviewNavBGOpacity) : st::medviewBG->c); } if (imgRect.intersects(_bottomBar)) { @@ -685,13 +714,25 @@ void MediaView::paintEvent(QPaintEvent *e) { } // name - p.setPen(st::medviewNameColor->p); + if (_doc) { + float64 o = overLevel(OverName); + p.setOpacity(st::medviewOverview.overOpacity * o + st::medviewOverview.opacity * (1 - o)); + p.setPen(st::white->p); + } else { + p.setPen(st::medviewNameColor->p); + } if (_over == OverName) _fromName.replaceFont(st::medviewNameFont->underline()); if (_nameNav.intersects(r)) _fromName.drawElided(p, _nameNav.left(), _nameNav.top(), _nameNav.width()); if (_over == OverName) _fromName.replaceFont(st::medviewNameFont); // date - p.setPen(st::medviewDateColor->p); + if (_doc) { + float64 o = overLevel(OverDate); + p.setOpacity(st::medviewOverview.overOpacity * o + st::medviewOverview.opacity * (1 - o)); + p.setPen(st::white->p); + } else { + p.setPen(st::medviewDateColor->p); + } p.setFont((_over == OverDate ? st::medviewDateFont->underline() : st::medviewDateFont)->f); if (_dateNav.intersects(r)) p.drawText(_dateNav.left(), _dateNav.top() + st::medviewDateFont->ascent, _dateText); } @@ -710,50 +751,82 @@ void MediaView::keyPressEvent(QKeyEvent *e) { } else if (e->modifiers().testFlag(Qt::ControlModifier) && (e->key() == Qt::Key_Plus || e->key() == Qt::Key_Equal || e->key() == Qt::Key_Minus || e->key() == Qt::Key_Underscore || e->key() == Qt::Key_0)) { int32 newZoom = _zoom; if (e->key() == Qt::Key_Plus || e->key() == Qt::Key_Equal) { - if (newZoom < MaxZoomLevel) ++newZoom; - } else if (e->key() == Qt::Key_Minus || e->key() == Qt::Key_Underscore) { - if (newZoom > -MaxZoomLevel) --newZoom; - } else { - newZoom = 0; - _x = -_width / 2; - _y = st::medviewPolaroid.top() - ((_current.height() / cIntRetinaFactor()) / 2); - if (_zoom >= 0) { - _x *= _zoom + 1; - _y *= _zoom + 1; + if (newZoom == ZoomToScreenLevel) { + if (qCeil(_zoomToScreen) <= MaxZoomLevel) { + newZoom = qCeil(_zoomToScreen); + } } else { - _x /= -_zoom + 1; - _y /= -_zoom + 1; + if (newZoom < _zoomToScreen && (newZoom + 1 > _zoomToScreen || (_zoomToScreen > MaxZoomLevel && newZoom == MaxZoomLevel))) { + newZoom = ZoomToScreenLevel; + } else if (newZoom < MaxZoomLevel) { + ++newZoom; + } + } + } else if (e->key() == Qt::Key_Minus || e->key() == Qt::Key_Underscore) { + if (newZoom == ZoomToScreenLevel) { + if (qFloor(_zoomToScreen) >= -MaxZoomLevel) { + newZoom = qFloor(_zoomToScreen); + } + } else { + if (newZoom > _zoomToScreen && (newZoom - 1 < _zoomToScreen || (_zoomToScreen < -MaxZoomLevel && newZoom == -MaxZoomLevel))) { + newZoom = ZoomToScreenLevel; + } else if (newZoom > -MaxZoomLevel) { + --newZoom; + } + } + } else { + if (_zoom == 0) { + if (qFloor(_zoomToScreen) == qCeil(_zoomToScreen) && qRound(_zoomToScreen) >= -MaxZoomLevel && qRound(_zoomToScreen) <= MaxZoomLevel) { + newZoom = qRound(_zoomToScreen); + } else { + newZoom = ZoomToScreenLevel; + } + } else { + newZoom = 0; + } + _x = -_width / 2; + _y = (_doc ? 0 : st::medviewPolaroid.top()) - ((_current.height() / cIntRetinaFactor()) / 2); + float64 z = (_zoom == ZoomToScreenLevel) ? _zoomToScreen : _zoom; + if (z >= 0) { + _x = qRound(_x * (z + 1)); + _y = qRound(_y * (z + 1)); + } else { + _x = qRound(_x / (-z + 1)); + _y = qRound(_y / (-z + 1)); } _x += _avail.width() / 2; - _y += (_avail.height() - st::medviewBottomBar - st::medviewPolaroid.top() - st::medviewPolaroid.bottom()) / 2; + _y += (_avail.height() - st::medviewBottomBar - (_doc ? 0 : (st::medviewPolaroid.top() + st::medviewPolaroid.bottom()))) / 2; updatePolaroid(); update(); } - while ((newZoom < 0 && (-newZoom + 1) > _w) || (-newZoom + 1) > _h) { - ++newZoom; + if (newZoom != ZoomToScreenLevel) { + while ((newZoom < 0 && (-newZoom + 1) > _w) || (-newZoom + 1) > _h) { + ++newZoom; + } } if (_zoom != newZoom) { - float64 nx, ny; + float64 nx, ny, z = (_zoom == ZoomToScreenLevel) ? _zoomToScreen : _zoom; _w = _current.width() / cIntRetinaFactor(); _h = _current.height() / cIntRetinaFactor(); - if (_zoom >= 0) { - nx = (_x - _avail.width() / 2.) / float64(_zoom + 1); - ny = (_y - _avail.height() / 2.) / float64(_zoom + 1); + if (z >= 0) { + nx = (_x - _avail.width() / 2.) / (z + 1); + ny = (_y - _avail.height() / 2.) / (z + 1); } else { - nx = (_x - _avail.width() / 2.) * float64(-_zoom + 1); - ny = (_y - _avail.height() / 2.) * float64(-_zoom + 1); + nx = (_x - _avail.width() / 2.) * (-z + 1); + ny = (_y - _avail.height() / 2.) * (-z + 1); } _zoom = newZoom; - if (_zoom > 0) { - _w *= _zoom + 1; - _h *= _zoom + 1; - _x = int32(nx * (_zoom + 1) + _avail.width() / 2.); - _y = int32(ny * (_zoom + 1) + _avail.height() / 2.); + z = (_zoom == ZoomToScreenLevel) ? _zoomToScreen : _zoom; + if (z > 0) { + _w = qRound(_w * (z + 1)); + _h = qRound(_h * (z + 1)); + _x = qRound(nx * (z + 1) + _avail.width() / 2.); + _y = qRound(ny * (z + 1) + _avail.height() / 2.); } else { - _w /= (-_zoom + 1); - _h /= (-_zoom + 1); - _x = int32(nx / (-_zoom + 1) + _avail.width() / 2.); - _y = int32(ny / (-_zoom + 1) + _avail.height() / 2.); + _w = qRound(_w / (-z + 1)); + _h = qRound(_h / (-z + 1)); + _x = qRound(nx / (-z + 1) + _avail.width() / 2.); + _y = qRound(ny / (-z + 1) + _avail.height() / 2.); } snapXY(); update(); @@ -864,12 +937,12 @@ void MediaView::mousePressEvent(QMouseEvent *e) { } void MediaView::snapXY() { - int32 xmin = _avail.width() - _w - st::medviewNavBarWidth - st::medviewPolaroid.right(), xmax = st::medviewPolaroid.left() + st::medviewNavBarWidth; - int32 ymin = _avail.height() - _h - st::medviewPolaroid.bottom() - st::medviewBottomBar, ymax = st::medviewPolaroid.top(); + int32 xmin = _avail.width() - _w - (_doc ? 0 : (st::medviewNavBarWidth + st::medviewPolaroid.right())), xmax = _doc ? 0 : (st::medviewPolaroid.left() + st::medviewNavBarWidth); + int32 ymin = _avail.height() - _h - (_doc ? 0 : st::medviewPolaroid.bottom()) - st::medviewBottomBar, ymax = (_doc ? 0 : st::medviewPolaroid.top()); if (xmin > (_avail.width() - _w) / 2) xmin = (_avail.width() - _w) / 2; if (xmax < (_avail.width() - _w) / 2) xmax = (_avail.width() - _w) / 2; - if (ymin > (_avail.height() - _h - st::medviewBottomBar - st::medviewPolaroid.bottom() + st::medviewPolaroid.top()) / 2) ymin = (_avail.height() - _h - st::medviewBottomBar - st::medviewPolaroid.bottom() + st::medviewPolaroid.top()) / 2; - if (ymax < (_avail.height() - _h - st::medviewBottomBar - st::medviewPolaroid.bottom() + st::medviewPolaroid.top()) / 2) ymax = (_avail.height() - _h - st::medviewBottomBar - st::medviewPolaroid.bottom() + st::medviewPolaroid.top()) / 2; + if (ymin > (_avail.height() - _h - st::medviewBottomBar - (_doc ? 0 : (st::medviewPolaroid.bottom() - st::medviewPolaroid.top()))) / 2) ymin = (_avail.height() - _h - st::medviewBottomBar - (_doc ? 0 : (st::medviewPolaroid.bottom() - st::medviewPolaroid.top()))) / 2; + if (ymax < (_avail.height() - _h - st::medviewBottomBar - (_doc ? 0 : (st::medviewPolaroid.bottom() - st::medviewPolaroid.top()))) / 2) ymax = (_avail.height() - _h - st::medviewBottomBar - (_doc ? 0 : (st::medviewPolaroid.bottom() - st::medviewPolaroid.top()))) / 2; if (_x < xmin) _x = xmin; if (_x > xmax) _x = xmax; if (_y < ymin) _y = ymin; @@ -886,7 +959,7 @@ void MediaView::mouseMoveEvent(QMouseEvent *e) { if (!_dragging && (e->pos() - _mStart).manhattanLength() >= QApplication::startDragDistance()) { _dragging = QRect(_x, _y, _w, _h).contains(_mStart) ? 1 : -1; if (_dragging > 0) { - if (_w > _avail.width() - 2 * st::medviewNavBarWidth - st::medviewPolaroid.left() - st::medviewPolaroid.right() || _h > _avail.height() - st::medviewPolaroid.top() - st::medviewPolaroid.bottom() - st::medviewBottomBar) { + if (_w > _avail.width() - (_doc ? 0 : (2 * st::medviewNavBarWidth + st::medviewPolaroid.left() + st::medviewPolaroid.right())) || _h > _avail.height() - (_doc ? 0 : (st::medviewPolaroid.top() + st::medviewPolaroid.bottom())) - st::medviewBottomBar) { setCursor(style::cur_sizeall); } else { setCursor(style::cur_default); @@ -1246,43 +1319,59 @@ void MediaView::updateHeader() { } void MediaView::updatePolaroid() { - int32 pminw = qMin(st::medviewPolaroidMin.width(), int(_avail.width() - 2 * st::medviewNavBarWidth)); + if (_doc) { + _polaroidIn = _polaroidOut = QRect(0, 0, _avail.width(), _avail.height() - st::medviewBottomBar); + int32 minus1 = width() - _delete.x(), minus2 = _overview.x() + st::medviewHeaderFont->m.width(_header) - st::medviewOverview.width; + if (minus2 > minus1) minus1 = minus2; - int32 pl = _x - st::medviewPolaroid.left(), plw = st::medviewPolaroid.left(); - if (pl < st::medviewNavBarWidth) pl = st::medviewNavBarWidth; - int32 pr = _x + _w + st::medviewPolaroid.right(), prw = st::medviewPolaroid.right(); - if (pr > _avail.width() - st::medviewNavBarWidth) pr = _avail.width() - st::medviewNavBarWidth; + int32 nameWidth = _fromName.maxWidth(), maxWidth = width() - 2 * minus1, dateWidth = st::medviewDateFont->m.width(_dateText); + if (maxWidth < dateWidth) { + maxWidth = dateWidth; + } + if (nameWidth > maxWidth) { + nameWidth = maxWidth; + } + _nameNav = QRect((_avail.width() - nameWidth) / 2, _avail.y() + _avail.height() - ((st::medviewPolaroid.bottom() + st::medviewBottomBar) / 2) + st::medviewNameTop, nameWidth, st::medviewNameFont->height); + _dateNav = QRect((_avail.width() - dateWidth) / 2, _avail.y() + _avail.height() - ((st::medviewPolaroid.bottom() + st::medviewBottomBar) / 2) + st::medviewDateTop, dateWidth, st::medviewDateFont->height); + } else { + int32 pminw = qMin(st::medviewPolaroidMin.width(), int(_avail.width() - 2 * st::medviewNavBarWidth)); - if (_w + st::medviewPolaroid.left() + st::medviewPolaroid.right() < pminw) { - pl = (_avail.width() - pminw) / 2; - plw = _x - pl; - pr = pl + pminw; - prw = pr - (_x + _w); + int32 pl = _x - st::medviewPolaroid.left(), plw = st::medviewPolaroid.left(); + if (pl < st::medviewNavBarWidth) pl = st::medviewNavBarWidth; + int32 pr = _x + _w + st::medviewPolaroid.right(), prw = st::medviewPolaroid.right(); + if (pr > _avail.width() - st::medviewNavBarWidth) pr = _avail.width() - st::medviewNavBarWidth; + + if (_w + st::medviewPolaroid.left() + st::medviewPolaroid.right() < pminw) { + pl = (_avail.width() - pminw) / 2; + plw = _x - pl; + pr = pl + pminw; + prw = pr - (_x + _w); + } + + int32 pminh = qMin(st::medviewPolaroidMin.height(), int(_avail.height() - st::medviewBottomBar)); + + int32 pt = _y - st::medviewPolaroid.top(), pth = st::medviewPolaroid.top(); + if (pt < 0) pt = 0; + int32 pb = _y + _h + st::medviewPolaroid.bottom(), pbh = st::medviewPolaroid.bottom(); + if (pb > _avail.height() - st::medviewBottomBar) pb = _avail.height() - st::medviewBottomBar; + + if (_h + st::medviewPolaroid.top() + st::medviewPolaroid.bottom() < pminh) { + pt = (_avail.height() - st::medviewBottomBar - pminh) / 2; + pth = _y - pt; + pb = pt + pminh; + pbh = pb - (_y + _h); + } + + _polaroidOut = QRect(pl, pt, pr - pl, pb - pt); + _polaroidIn = QRect(pl + plw, pt + pth, pr - pl - prw - plw, pb - pt - pbh - pth); + + int32 nameWidth = _fromName.maxWidth(), maxWidth = _polaroidOut.width() - st::medviewPolaroid.left() - st::medviewPolaroid.right(), dateWidth = st::medviewDateFont->m.width(_dateText); + if (nameWidth > maxWidth) { + nameWidth = maxWidth; + } + _nameNav = QRect(_polaroidIn.x() + ((_polaroidIn.width() - nameWidth) / 2), _polaroidOut.y() + _polaroidOut.height() - st::medviewPolaroid.bottom() + st::medviewNameTop, nameWidth, st::medviewNameFont->height); + _dateNav = QRect(_polaroidIn.x() + ((_polaroidIn.width() - dateWidth) / 2), _polaroidOut.y() + _polaroidOut.height() - st::medviewPolaroid.bottom() + st::medviewDateTop, dateWidth, st::medviewDateFont->height); } - - int32 pminh = qMin(st::medviewPolaroidMin.height(), int(_avail.height() - st::medviewBottomBar)); - - int32 pt = _y - st::medviewPolaroid.top(), pth = st::medviewPolaroid.top(); - if (pt < 0) pt = 0; - int32 pb = _y + _h + st::medviewPolaroid.bottom(), pbh = st::medviewPolaroid.bottom(); - if (pb > _avail.height() - st::medviewBottomBar) pb = _avail.height() - st::medviewBottomBar; - - if (_h + st::medviewPolaroid.top() + st::medviewPolaroid.bottom() < pminh) { - pt = (_avail.height() - st::medviewBottomBar - pminh) / 2; - pth = _y - pt; - pb = pt + pminh; - pbh = pb - (_y + _h); - } - - _polaroidOut = QRect(pl, pt, pr - pl, pb - pt); - _polaroidIn = QRect(pl + plw, pt + pth, pr - pl - prw - plw, pb - pt - pbh - pth); - - int32 nameWidth = _fromName.maxWidth(), maxWidth = _polaroidOut.width() - st::medviewPolaroid.left() - st::medviewPolaroid.right(), dateWidth = st::medviewDateFont->m.width(_dateText); - if (nameWidth > maxWidth) { - nameWidth = maxWidth; - } - _nameNav = QRect(_polaroidIn.x() + ((_polaroidIn.width() - nameWidth) / 2), _polaroidOut.y() + _polaroidOut.height() - st::medviewPolaroid.bottom() + st::medviewNameTop, nameWidth, st::medviewNameFont->height); - _dateNav = QRect(_polaroidIn.x() + ((_polaroidIn.width() - dateWidth) / 2), _polaroidOut.y() + _polaroidOut.height() - st::medviewPolaroid.bottom() + st::medviewDateTop, dateWidth, st::medviewDateFont->height); } QColor MediaView::overColor(const QColor &a, float64 ca, const QColor &b, float64 cb) { diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index f2ac6758d..33d90fba6 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -86,6 +86,8 @@ private: void updatePolaroid(); void snapXY(); + QBrush _transparentBrush; + QTimer _timer; PhotoData *_photo; DocumentData *_doc; @@ -98,6 +100,7 @@ private: int32 _maxWidth, _maxHeight, _width, _x, _y, _w, _h, _xStart, _yStart; int32 _zoom; // < 0 - out, 0 - none, > 0 - in + float64 _zoomToScreen; // for documents QPoint _mStart; bool _pressed; int32 _dragging; diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index 91c7e154c..33a1559b6 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -1611,7 +1611,7 @@ void OverviewWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) p.drawPixmap(QPoint(st::topBarBackPadding.left(), (st::topBarHeight - st::topBarBackImg.pxHeight()) / 2), App::sprite(), st::topBarBackImg); p.setFont(st::topBarBackFont->f); p.setPen(st::topBarBackColor->p); - p.drawText(st::topBarBackPadding.left() + st::topBarBackImg.pxWidth() + st::topBarBackPadding.right(), (st::topBarHeight - st::titleFont->height) / 2 + st::titleFont->ascent, _header); + p.drawText(st::topBarBackPadding.left() + st::topBarBackImg.pxWidth() + st::topBarBackPadding.right(), (st::topBarHeight - st::topBarBackFont->height) / 2 + st::topBarBackFont->ascent, _header); } } diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index a26cea712..6260e75bb 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -935,7 +935,7 @@ void ProfileWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) p.drawPixmap(QPoint(st::topBarBackPadding.left(), (st::topBarHeight - st::topBarBackImg.pxHeight()) / 2), App::sprite(), st::topBarBackImg); p.setFont(st::topBarBackFont->f); p.setPen(st::topBarBackColor->p); - p.drawText(st::topBarBackPadding.left() + st::topBarBackImg.pxWidth() + st::topBarBackPadding.right(), (st::topBarHeight - st::titleFont->height) / 2 + st::titleFont->ascent, lang(peer()->chat ? lng_profile_group_info : lng_profile_info)); + p.drawText(st::topBarBackPadding.left() + st::topBarBackImg.pxWidth() + st::topBarBackPadding.right(), (st::topBarHeight - st::topBarBackFont->height) / 2 + st::topBarBackFont->ascent, lang(peer()->chat ? lng_profile_group_info : lng_profile_info)); } } diff --git a/Telegram/SourceFiles/pspecific_linux.h b/Telegram/SourceFiles/pspecific_linux.h index 8cedc407e..2e762a453 100644 --- a/Telegram/SourceFiles/pspecific_linux.h +++ b/Telegram/SourceFiles/pspecific_linux.h @@ -69,12 +69,15 @@ public: void psNotifyShown(NotifyWindow *w); void psPlatformNotify(HistoryItem *item); + void psUpdateCounter(); + + virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0; + ~PsMainWindow(); public slots: void psStateChanged(Qt::WindowState state); - void psUpdateCounter(); void psUpdateDelegate(); void psSavePosition(Qt::WindowState state = Qt::WindowActive); void psIdleTimeout(); @@ -91,7 +94,6 @@ protected: QIcon wndIcon; virtual void setupTrayIcon() = 0; - virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0; QTimer psUpdatedPositionTimer; diff --git a/Telegram/SourceFiles/pspecific_mac.cpp b/Telegram/SourceFiles/pspecific_mac.cpp index 2cf8b5cd5..0c7e8e30a 100644 --- a/Telegram/SourceFiles/pspecific_mac.cpp +++ b/Telegram/SourceFiles/pspecific_mac.cpp @@ -51,7 +51,7 @@ void MacPrivate::activeSpaceChanged() { void MacPrivate::darkModeChanged() { if (App::wnd()) { - App::wnd()->psUpdateCounter(); + App::wnd()->updateCounter(); } } diff --git a/Telegram/SourceFiles/pspecific_mac.h b/Telegram/SourceFiles/pspecific_mac.h index ad9f671ce..18e0a2d15 100644 --- a/Telegram/SourceFiles/pspecific_mac.h +++ b/Telegram/SourceFiles/pspecific_mac.h @@ -82,12 +82,15 @@ public: bool eventFilter(QObject *obj, QEvent *evt); + void psUpdateCounter(); + + virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0; + ~PsMainWindow(); public slots: void psStateChanged(Qt::WindowState state); - void psUpdateCounter(); void psUpdateDelegate(); void psSavePosition(Qt::WindowState state = Qt::WindowActive); void psIdleTimeout(); @@ -118,7 +121,6 @@ protected: virtual void setupTrayIcon() = 0; virtual void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) = 0; - virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0; QTimer psUpdatedPositionTimer; diff --git a/Telegram/SourceFiles/pspecific_wnd.cpp b/Telegram/SourceFiles/pspecific_wnd.cpp index 82e95b966..da85996bc 100644 --- a/Telegram/SourceFiles/pspecific_wnd.cpp +++ b/Telegram/SourceFiles/pspecific_wnd.cpp @@ -704,7 +704,7 @@ namespace { } else { _psShadowWindows.setColor(_shInactive); } - QTimer::singleShot(0, Application::wnd(), SLOT(psUpdateCounter())); + QTimer::singleShot(0, Application::wnd(), SLOT(updateCounter())); Application::wnd()->update(); } return false; diff --git a/Telegram/SourceFiles/pspecific_wnd.h b/Telegram/SourceFiles/pspecific_wnd.h index 123996adf..e2d25ce06 100644 --- a/Telegram/SourceFiles/pspecific_wnd.h +++ b/Telegram/SourceFiles/pspecific_wnd.h @@ -68,12 +68,15 @@ public: void psNotifyShown(NotifyWindow *w); void psPlatformNotify(HistoryItem *item); + void psUpdateCounter(); + + virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0; + ~PsMainWindow(); public slots: void psStateChanged(Qt::WindowState state); - void psUpdateCounter(); void psUpdateDelegate(); void psSavePosition(Qt::WindowState state = Qt::WindowActive); void psIdleTimeout(); @@ -90,7 +93,6 @@ protected: QIcon wndIcon; virtual void setupTrayIcon() = 0; - virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0; QTimer psUpdatedPositionTimer; diff --git a/Telegram/SourceFiles/title.cpp b/Telegram/SourceFiles/title.cpp index 0570f255a..2ca6e2382 100644 --- a/Telegram/SourceFiles/title.cpp +++ b/Telegram/SourceFiles/title.cpp @@ -51,7 +51,7 @@ TitleWidget::TitleWidget(Window *window) , wnd(window) , hideLevel(0) , hider(0) - , _back(this, st::titleBackButton) + , _back(this, st::titleBackButton, lang(lng_menu_back)) , _cancel(this, lang(lng_cancel), st::titleTextButton) , _settings(this, lang(lng_menu_settings), st::titleTextButton) , _contacts(this, lang(lng_menu_contacts), st::titleTextButton) @@ -70,7 +70,7 @@ TitleWidget::TitleWidget(Window *window) } stateChanged(); - connect(&_back, SIGNAL(clicked()), window, SLOT(onTitleBack())); + connect(&_back, SIGNAL(clicked()), window, SLOT(hideSettings())); connect(&_cancel, SIGNAL(clicked()), this, SIGNAL(hiderClicked())); connect(&_settings, SIGNAL(clicked()), window, SLOT(showSettings())); connect(&_contacts, SIGNAL(clicked()), this, SLOT(onContacts())); @@ -95,7 +95,10 @@ void TitleWidget::paintEvent(QPaintEvent *e) { p.setFont(st::titleTextButton.font->f); p.drawText(st::titleMenuOffset - st::titleTextButton.width / 2, st::titleTextButton.textTop + st::titleTextButton.font->ascent, lang(lng_forward_choose)); } - p.drawPixmap(st::titleIconPos, App::sprite(), st::titleIconRect); + p.drawPixmap(st::titleIconPos, App::sprite(), st::titleIconImg); + if (!cWideMode() && !_counter.isNull() && App::main()) { + p.drawPixmap(st::titleIconPos.x() + st::titleIconImg.pxWidth() - (_counter.width() / cIntRetinaFactor()), st::titleIconPos.y() + st::titleIconImg.pxHeight() - (_counter.height() / cIntRetinaFactor()), _counter); + } } bool TitleWidget::animStep(float64 ms) { @@ -167,6 +170,7 @@ void TitleWidget::resizeEvent(QResizeEvent *e) { _settings.move(st::titleMenuOffset, 0); _back.move(st::titleMenuOffset, 0); + _back.resize((_minimize.isHidden() ? (_update.isHidden() ? width() : _update.x()) : _minimize.x()) - st::titleMenuOffset, _back.height()); if (MTP::authedId() && _back.isHidden() && _cancel.isHidden()) { _contacts.show(); _contacts.move(_settings.x() + _settings.width(), 0); @@ -179,7 +183,7 @@ void TitleWidget::resizeEvent(QResizeEvent *e) { if (hider) hider->resize(size()); } -void TitleWidget::updateBackButton(int authedChanged) { +void TitleWidget::updateBackButton() { if (!cWideMode() && App::main() && App::main()->selectingPeer()) { _cancel.show(); if (!_back.isHidden()) _back.hide(); @@ -188,10 +192,7 @@ void TitleWidget::updateBackButton(int authedChanged) { _about.hide(); } else { _cancel.hide(); - bool authed = authedChanged ? (authedChanged > 0) : (MTP::authedId() > 0); - if (authedChanged) { - _back.setText(lang((authedChanged > 0) ? lng_menu_conversations : lng_menu_start_messaging)); - } + bool authed = (MTP::authedId() > 0); if (cWideMode()) { if (!_back.isHidden()) _back.hide(); _settings.show(); @@ -218,6 +219,9 @@ void TitleWidget::updateBackButton(int authedChanged) { void TitleWidget::updateWideMode() { updateBackButton(); + if (!cWideMode()) { + updateCounter(); + } if (hider) { if (cWideMode()) { hider->show(); @@ -227,6 +231,30 @@ void TitleWidget::updateWideMode() { } } +void TitleWidget::updateCounter() { + if (cWideMode() || !MTP::authedId()) return; + + int32 counter = App::histories().unreadFull; + style::color bg = (App::histories().unreadMuted < counter) ? st::counterBG : st::counterMuteBG; + + if (counter > 0) { + int32 size = -16; + switch (cScale()) { + case dbisOneAndQuarter: size = -20; break; + case dbisOneAndHalf: size = -24; break; + case dbisTwo: size = -32; break; + } + _counter = QPixmap::fromImage(App::wnd()->iconWithCounter(size, counter, bg, false)); + _counter.setDevicePixelRatio(cRetinaFactor()); + update(QRect(st::titleIconPos, st::titleIconImg.pxSize())); + } else { + if (!_counter.isNull()) { + _counter = QPixmap(); + update(QRect(st::titleIconPos, st::titleIconImg.pxSize())); + } + } +} + void TitleWidget::mousePressEvent(QMouseEvent *e) { if (wnd->psHandleTitle()) return; if (e->buttons() & Qt::LeftButton) { @@ -307,7 +335,7 @@ HitTestType TitleWidget::hitTest(const QPoint &p) { int x(p.x()), y(p.y()), w(width()), h(height() - st::titleShadow); if (cWideMode() && hider && x >= App::main()->dlgsWidth()) return HitTestNone; - if (x >= st::titleIconPos.x() && y >= st::titleIconPos.y() && x < st::titleIconPos.x() + st::titleIconRect.pxWidth() && y < st::titleIconPos.y() + st::titleIconRect.pxHeight()) { + if (x >= st::titleIconPos.x() && y >= st::titleIconPos.y() && x < st::titleIconPos.x() + st::titleIconImg.pxWidth() && y < st::titleIconPos.y() + st::titleIconImg.pxHeight()) { return HitTestIcon; } else if (false || (_update.hitTest(p - _update.geometry().topLeft()) == HitTestSysButton && _update.isVisible()) diff --git a/Telegram/SourceFiles/title.h b/Telegram/SourceFiles/title.h index d9fde83d4..3879d35ee 100644 --- a/Telegram/SourceFiles/title.h +++ b/Telegram/SourceFiles/title.h @@ -45,8 +45,9 @@ public: void paintEvent(QPaintEvent *e); void resizeEvent(QResizeEvent *e); - void updateBackButton(int authedChanged = 0); + void updateBackButton(); void updateWideMode(); + void updateCounter(); void mousePressEvent(QMouseEvent *e); void mouseDoubleClickEvent(QMouseEvent *e); @@ -94,4 +95,6 @@ private: bool lastMaximized; + QPixmap _counter; + }; diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index f4424dd66..000673575 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -438,7 +438,6 @@ void Window::clearWidgets() { void Window::setupIntro(bool anim) { cSetContactsReceived(false); - title->updateBackButton(false); if (intro && (intro->animating() || intro->isVisible()) && !main) return; QPixmap bg = myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)); @@ -494,8 +493,6 @@ void Window::sendServiceHistoryRequest() { } void Window::setupMain(bool anim) { - title->updateBackButton(true); - QPixmap bg = myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)); clearWidgets(); main = new MainWidget(this); @@ -514,13 +511,9 @@ void Window::setupMain(bool anim) { _mediaView = new MediaView(); } -void Window::onTitleBack() { - if (main) { - main->onTitleBack(); - } - if (settings) { - hideSettings(); - } +void Window::updateCounter() { + psUpdateCounter(); + title->updateCounter(); } void Window::showSettings() { @@ -786,7 +779,7 @@ HitTestType Window::hitTest(const QPoint &p) const { } QRect Window::iconRect() const { - return QRect(st::titleIconPos + title->geometry().topLeft(), st::titleIconRect.pxSize()); + return QRect(st::titleIconPos + title->geometry().topLeft(), st::titleIconImg.pxSize()); } bool Window::eventFilter(QObject *obj, QEvent *evt) { @@ -868,7 +861,7 @@ void Window::setupTrayIcon() { } updateTrayMenu(); } - psUpdateCounter(); + updateCounter(); trayIcon->show(); psUpdateDelegate(); @@ -987,7 +980,7 @@ void Window::noTopWidget(QWidget *w) { void Window::showFromTray(QSystemTrayIcon::ActivationReason reason) { if (reason != QSystemTrayIcon::Context) { activate(); - psUpdateCounter(); + updateCounter(); if (App::main()) App::main()->setOnline(windowState()); QTimer::singleShot(1, this, SLOT(updateTrayMenu())); QTimer::singleShot(1, this, SLOT(updateGlobalMenu())); @@ -1041,7 +1034,7 @@ void Window::updateWideMode() { } bool Window::needBackButton() { - return settings || (main && main->needBackButton()); + return !!settings; } Window::TempDirState Window::tempDirState() { @@ -1440,7 +1433,7 @@ QImage Window::iconWithCounter(int size, int count, style::color bg, bool smallI layer = true; } if (layer) { - if (size != 16) size = 32; + if (size != 16 && size != 20 && size != 24) size = 32; QString cnt = (count < 1000) ? QString("%1").arg(count) : QString("..%1").arg(count % 100, 2, 10, QChar('0')); QImage result(size, size, QImage::Format_ARGB32); @@ -1452,21 +1445,26 @@ QImage Window::iconWithCounter(int size, int count, style::color bg, bool smallI p.setPen(Qt::NoPen); p.setRenderHint(QPainter::Antialiasing); int32 fontSize; - if (size == 8) { - fontSize = 6; - } else if (size == 16) { + if (size == 16) { fontSize = (cntSize < 2) ? 11 : ((cntSize < 3) ? 11 : 8); + } else if (size == 20) { + fontSize = (cntSize < 2) ? 14 : ((cntSize < 3) ? 13 : 10); + } else if (size == 24) { + fontSize = (cntSize < 2) ? 17 : ((cntSize < 3) ? 16 : 12); } else { fontSize = (cntSize < 2) ? 22 : ((cntSize < 3) ? 20 : 16); } style::font f(fontSize); int32 w = f->m.width(cnt), d, r; - if (size == 8) { - d = (cntSize < 2) ? 2 : 1; - r = (cntSize < 2) ? 4 : 3; - } else if (size == 16) { + if (size == 16) { d = (cntSize < 2) ? 5 : ((cntSize < 3) ? 2 : 1); r = (cntSize < 2) ? 8 : ((cntSize < 3) ? 7 : 3); + } else if (size == 20) { + d = (cntSize < 2) ? 6 : ((cntSize < 3) ? 2 : 1); + r = (cntSize < 2) ? 10 : ((cntSize < 3) ? 9 : 5); + } else if (size == 24) { + d = (cntSize < 2) ? 7 : ((cntSize < 3) ? 3 : 1); + r = (cntSize < 2) ? 12 : ((cntSize < 3) ? 11 : 6); } else { d = (cntSize < 2) ? 9 : ((cntSize < 3) ? 4 : 2); r = (cntSize < 2) ? 16 : ((cntSize < 3) ? 14 : 8); diff --git a/Telegram/SourceFiles/window.h b/Telegram/SourceFiles/window.h index 45781f33f..d13001fde 100644 --- a/Telegram/SourceFiles/window.h +++ b/Telegram/SourceFiles/window.h @@ -169,7 +169,6 @@ public: void hideConnecting(); bool connectingVisible() const; - void hideSettings(bool fast = false); void showPhoto(const PhotoLink *lnk, HistoryItem *item = 0); void showPhoto(PhotoData *photo, HistoryItem *item); void showPhoto(PhotoData *photo, PeerData *item); @@ -229,10 +228,10 @@ public: public slots: void checkHistoryActivation(int state = -1); + void updateCounter(); - void onTitleBack(); - void showSettings(); + void hideSettings(bool fast = false); void layerHidden(); void updateTitleStatus(); @@ -255,6 +254,8 @@ public slots: void onLogoutSure(); void updateGlobalMenu(); // for OS X top menu + QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon); + signals: void resized(const QSize &size); @@ -268,7 +269,6 @@ protected: private: void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color); - QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon); QImage icon16, icon32, icon64, iconbig16, iconbig32, iconbig64; QWidget *centralwidget;