diff --git a/Telegram/Resources/basic.style b/Telegram/Resources/basic.style index 36f48aa708..234e9f2dcf 100644 --- a/Telegram/Resources/basic.style +++ b/Telegram/Resources/basic.style @@ -404,7 +404,6 @@ noContactsColor: #777777; topBarHeight: 54px; topBarDuration: 200; -topBarForward: icon {{ "title_back-flip_horizontal", #a3a3a3 }}; topBarBackward: icon {{ "title_back", #a3a3a3 }}; topBarForwardAlpha: 0.6; topBarBack: icon {{ "title_back", #259fd8 }}; @@ -504,6 +503,8 @@ msgReplyBarSize: size(2px, 36px); msgReplyBarSkip: 10px; msgInReplyBarColor: #2fa9e2; msgInReplyBarSelColor: #2fa9e2; +msgOutReplyBarColor: historyOutIconFg; +msgOutReplyBarSelColor: historyOutIconFgSelected; msgImgReplyBarColor: #ffffff; msgBotKbDuration: 200; diff --git a/Telegram/Resources/basic_types.style b/Telegram/Resources/basic_types.style index 2ca21038af..3e343c13b4 100644 --- a/Telegram/Resources/basic_types.style +++ b/Telegram/Resources/basic_types.style @@ -58,8 +58,6 @@ flatButton { overFont: font; duration: int; cursor: cursor; - - radius: pixels; } flatInput { diff --git a/Telegram/Resources/colors.palette b/Telegram/Resources/colors.palette index 8ed27047e7..24ac18d9f9 100644 --- a/Telegram/Resources/colors.palette +++ b/Telegram/Resources/colors.palette @@ -22,9 +22,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org // basic windowBg: #ffffff; // white: fallback for background windowTextFg: #000000; // black: fallback for text color -windowSubTextFg: #8a8a8a; // gray: fallback for subtext color +windowSubTextFg: #999999; // gray: fallback for subtext color windowActiveFill: #40ace3; // bright blue: fallback for blue filled active areas -windowOverBg: #f3f3f3; // light blue: fallback for over background +windowOverBg: #f0f0f0; // light gray: fallback for over background windowSubTextFgOver: #7c99b2; // gray over light blue: fallback for subtext over color windowActiveTextFg: #1485c2; // online blue: fallback for active color windowShadowFg: #000000; // black: fallback for shadow color @@ -47,8 +47,6 @@ lightButtonFgOver: lightButtonFg; menuIconFg: windowSubTextFg; -dialogsMenuIconFg: menuIconFg; - // custom title bar for Windows titleBg: windowOverBg; titleShadow: #00000003; @@ -106,6 +104,45 @@ notificationSampleNameFg: #939393 | windowSubTextFg; introHeaderFg: windowTextFg; introErrorFg: windowTextFg; +// dialogs +dialogsMenuIconFg: menuIconFg; + +dialogsBg: windowBg; +dialogsNameFg: #373737 | windowTextFg; +dialogsChatIconFg: dialogsNameFg; +dialogsDateFg: windowSubTextFg; +dialogsTextFg: windowSubTextFg; +dialogsTextFgService: #4981af; +dialogsDraftFg: #dd4b39; +dialogsVerifiedIconBg: #4abcf1; +dialogsVerifiedIconFg: #ffffff; +dialogsSendingIconFg: #c1c1c1; +dialogsSentIconFg: #5dc452; + +dialogsBgOver: windowOverBg; +dialogsNameFgOver: windowTextFg; +dialogsChatIconFgOver: dialogsNameFgOver; +dialogsDateFgOver: #8a8a8a | dialogsDateFg; +dialogsTextFgOver: dialogsTextFg; +dialogsTextFgServiceOver: dialogsTextFgService; +dialogsDraftFgOver: dialogsDraftFg; +dialogsVerifiedIconBgOver: dialogsVerifiedIconBg; +dialogsVerifiedIconFgOver: dialogsVerifiedIconFg; +dialogsSendingIconFgOver: dialogsSendingIconFg; +dialogsSentIconFgOver: dialogsSentIconFg; + +dialogsBgActive: dialogsBgOver; +dialogsNameFgActive: dialogsNameFgOver; +dialogsChatIconFgActive: dialogsNameFgActive; +dialogsDateFgActive: dialogsDateFgOver; +dialogsTextFgActive: dialogsTextFgOver; +dialogsTextFgServiceActive: dialogsTextFgServiceOver; +dialogsDraftFgActive: dialogsDraftFgOver; +dialogsVerifiedIconBgActive: dialogsVerifiedIconBgOver; +dialogsVerifiedIconFgActive: dialogsVerifiedIconFgOver; +dialogsSendingIconFgActive: dialogsSendingIconFgOver; +dialogsSentIconFgActive: dialogsSentIconFgOver; + // history topBarBg: windowBg; @@ -132,6 +169,9 @@ historyCaptionInFg: historyTextInFg; historyCaptionOutFg: historyTextOutFg; historyFileNameInFg: historyTextInFg; historyFileNameOutFg: historyTextOutFg; +historyOutIconFg: dialogsSentIconFg; +historyOutIconFgSelected: #4da79f; +historyIconFgInverted: #ffffff; historySystemBg: #89a0b47f; historySystemBgSelected: #bbc8d4a2; diff --git a/Telegram/Resources/icons/title_menu_dots.png b/Telegram/Resources/icons/title_menu_dots.png new file mode 100644 index 0000000000..228a2a3bc9 Binary files /dev/null and b/Telegram/Resources/icons/title_menu_dots.png differ diff --git a/Telegram/Resources/icons/title_menu_dots@2x.png b/Telegram/Resources/icons/title_menu_dots@2x.png new file mode 100644 index 0000000000..0020d07f11 Binary files /dev/null and b/Telegram/Resources/icons/title_menu_dots@2x.png differ diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index c7b5a66fc0..6ca0bc71db 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -212,6 +212,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_dlg_search_chat" = "Search in this chat"; "lng_dlg_search_channel" = "Search in this channel"; "lng_dlg_search_for_messages" = "Search for messages"; +"lng_update_telegram" = "Update Telegram"; "lng_settings_save" = "Save"; "lng_settings_upload" = "Set Profile Photo"; diff --git a/Telegram/Resources/sample.tdesktop-theme b/Telegram/Resources/sample.tdesktop-theme index 2c23392a54..56cddb35ce 100644 --- a/Telegram/Resources/sample.tdesktop-theme +++ b/Telegram/Resources/sample.tdesktop-theme @@ -23,9 +23,9 @@ windowBg: #ffffff; windowTextFg: #000000; -windowSubTextFg: #8a8a8a; +windowSubTextFg: #999999; windowActiveFill: #40ace3; -windowOverBg: #f3f3f3; +windowOverBg: #f0f0f0; windowSubTextFgOver: #7c99b2; windowActiveTextFg: #1485c2; windowShadowFg: #000000; @@ -42,7 +42,6 @@ lightButtonBgOver: #f2f7fa; // lightButtonBg; lightButtonFg: #2b99d5; lightButtonFgOver: lightButtonFg; menuIconFg: windowSubTextFg; -dialogsMenuIconFg: menuIconFg; titleBg: windowOverBg; titleShadow: #00000003; titleButtonFg: #ababab; @@ -82,10 +81,44 @@ notificationSampleTextFg: #d7d7d7; // windowSubTextFg; notificationSampleNameFg: #939393; // windowSubTextFg; introHeaderFg: windowTextFg; introErrorFg: windowTextFg; +dialogsMenuIconFg: menuIconFg; +dialogsBg: windowBg; +dialogsNameFg: #373737; // windowTextFg; +dialogsChatIconFg: dialogsNameFg; +dialogsDateFg: windowSubTextFg; +dialogsTextFg: windowSubTextFg; +dialogsTextFgService: #4981af; +dialogsDraftFg: #dd4b39; +dialogsVerifiedIconBg: #4abcf1; +dialogsVerifiedIconFg: #ffffff; +dialogsSendingIconFg: #c1c1c1; +dialogsSentIconFg: #5dc452; +dialogsBgOver: windowOverBg; +dialogsNameFgOver: windowTextFg; +dialogsChatIconFgOver: dialogsNameFgOver; +dialogsDateFgOver: #8a8a8a; // dialogsDateFg; +dialogsTextFgOver: dialogsTextFg; +dialogsTextFgServiceOver: dialogsTextFgService; +dialogsDraftFgOver: dialogsDraftFg; +dialogsVerifiedIconBgOver: dialogsVerifiedIconBg; +dialogsVerifiedIconFgOver: dialogsVerifiedIconFg; +dialogsSendingIconFgOver: dialogsSendingIconFg; +dialogsSentIconFgOver: dialogsSentIconFg; +dialogsBgActive: dialogsBgOver; +dialogsNameFgActive: dialogsNameFgOver; +dialogsChatIconFgActive: dialogsNameFgActive; +dialogsDateFgActive: dialogsDateFgOver; +dialogsTextFgActive: dialogsTextFgOver; +dialogsTextFgServiceActive: dialogsTextFgServiceOver; +dialogsDraftFgActive: dialogsDraftFgOver; +dialogsVerifiedIconBgActive: dialogsVerifiedIconBgOver; +dialogsVerifiedIconFgActive: dialogsVerifiedIconFgOver; +dialogsSendingIconFgActive: dialogsSendingIconFgOver; +dialogsSentIconFgActive: dialogsSentIconFgOver; topBarBg: windowBg; emojiPanBg: windowBg; emojiPanCategories: #f7f7f7; // windowBg; -emojiPanHeaderFg: #999999; // windowSubTextFg; +emojiPanHeaderFg: windowSubTextFg; emojiPanHeaderBg: #fffffff2; // emojiPanBg; historyComposeAreaBg: windowBg; historyComposeIconFg: #cccccc; @@ -103,6 +136,9 @@ historyCaptionInFg: historyTextInFg; historyCaptionOutFg: historyTextOutFg; historyFileNameInFg: historyTextInFg; historyFileNameOutFg: historyTextOutFg; +historyOutIconFg: dialogsSentIconFg; +historyOutIconFgSelected: #4da79f; +historyIconFgInverted: #ffffff; historySystemBg: #89a0b47f; historySystemBgSelected: #bbc8d4a2; historySystemFg: #ffffff; diff --git a/Telegram/SourceFiles/boxes/abstractbox.cpp b/Telegram/SourceFiles/boxes/abstractbox.cpp index bf2cd382b1..4aeb358605 100644 --- a/Telegram/SourceFiles/boxes/abstractbox.cpp +++ b/Telegram/SourceFiles/boxes/abstractbox.cpp @@ -35,7 +35,7 @@ void BlueTitleShadow::paintEvent(QPaintEvent *e) { st::boxBlueTitleShadow.fill(p, QRect(r.left(), 0, r.width(), height())); } -AbstractBox::AbstractBox(int w) : LayerWidget() { +AbstractBox::AbstractBox(int w) : LayerWidget(App::wnd()->bodyWidget()) { setAttribute(Qt::WA_OpaquePaintEvent); resize(w, 0); } @@ -64,8 +64,9 @@ void AbstractBox::resizeEvent(QResizeEvent *e) { } void AbstractBox::parentResized() { - int32 newHeight = countHeight(); - setGeometry((App::wnd()->width() - width()) / 2, (App::wnd()->height() - newHeight) / 2, width(), newHeight); + auto newHeight = countHeight(); + auto parentSize = parentWidget()->size(); + setGeometry((parentSize.width() - width()) / 2, (parentSize.height() - newHeight) / 2, width(), newHeight); update(); } @@ -123,7 +124,7 @@ void AbstractBox::resizeMaxHeight(int32 newWidth, int32 maxHeight) { } int AbstractBox::countHeight() const { - return qMin(_maxHeight, App::wnd()->height() - 2 * st::boxVerticalMargin); + return qMin(_maxHeight, parentWidget()->height() - 2 * st::boxVerticalMargin); } void AbstractBox::onClose() { @@ -163,7 +164,6 @@ void ScrollableBox::init(TWidget *inner, int bottomSkip, int topSkip) { _bottomSkip = bottomSkip; _topSkip = topSkip; _scroll->setOwnedWidget(inner); - _scroll->setFocusPolicy(Qt::NoFocus); updateScrollGeometry(); } diff --git a/Telegram/SourceFiles/boxes/contactsbox.cpp b/Telegram/SourceFiles/boxes/contactsbox.cpp index a59f7608bb..4504d8a2fb 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.cpp +++ b/Telegram/SourceFiles/boxes/contactsbox.cpp @@ -854,7 +854,8 @@ void ContactsBox::Inner::peerUpdated(PeerData *peer) { } void ContactsBox::Inner::loadProfilePhotos(int32 yFrom) { - int32 yTo = yFrom + (parentWidget() ? parentWidget()->height() : App::wnd()->height()) * 5; + if (!parentWidget()) return; + int32 yTo = yFrom + parentWidget()->height() * 5; MTP::clearLoaderPriorities(); if (yTo < 0) return; diff --git a/Telegram/SourceFiles/boxes/members_box.cpp b/Telegram/SourceFiles/boxes/members_box.cpp index 9292d671b7..00c654e3cb 100644 --- a/Telegram/SourceFiles/boxes/members_box.cpp +++ b/Telegram/SourceFiles/boxes/members_box.cpp @@ -310,7 +310,8 @@ void MembersBox::Inner::selectSkipPage(int32 h, int32 dir) { } void MembersBox::Inner::loadProfilePhotos(int32 yFrom) { - int32 yTo = yFrom + (parentWidget() ? parentWidget()->height() : App::wnd()->height()) * 5; + if (!parentWidget()) return; + int32 yTo = yFrom + parentWidget()->height() * 5; MTP::clearLoaderPriorities(); if (yTo < 0) return; diff --git a/Telegram/SourceFiles/boxes/sharebox.cpp b/Telegram/SourceFiles/boxes/sharebox.cpp index fd5482118f..7ce9e54059 100644 --- a/Telegram/SourceFiles/boxes/sharebox.cpp +++ b/Telegram/SourceFiles/boxes/sharebox.cpp @@ -427,13 +427,14 @@ int ShareBox::Inner::chatIndex(PeerData *peer) const { } void ShareBox::Inner::loadProfilePhotos(int yFrom) { + if (!parentWidget()) return; if (yFrom < 0) { yFrom = 0; } if (auto part = (yFrom % _rowHeight)) { yFrom -= part; } - int yTo = yFrom + (parentWidget() ? parentWidget()->height() : App::wnd()->height()) * 5 * _columnCount; + int yTo = yFrom + parentWidget()->height() * 5 * _columnCount; if (!yTo) { return; } diff --git a/Telegram/SourceFiles/dialogs/dialogs.style b/Telegram/SourceFiles/dialogs/dialogs.style index cc84abd455..38f8fdd2ec 100644 --- a/Telegram/SourceFiles/dialogs/dialogs.style +++ b/Telegram/SourceFiles/dialogs/dialogs.style @@ -33,18 +33,9 @@ dialogsUnreadFont: font(12px bold); dialogsUnreadHeight: 19px; dialogsUnreadPadding: 5px; -dialogsBg: windowBg; -dialogsBgOver: #f5f5f5; -dialogsBgActive: #6a91b1; dialogsTextFont: font(fsize); -dialogsTextFg: #888888; -dialogsTextFgService: #4981af; -dialogsTextFgActive: #ffffff; dialogsDateFont: font(13px); -dialogsDateFgActive: #ffffff; -dialogsDateFg: #a8a8a8; dialogsDateSkip: 5px; -dialogsNameFg: #000000; dialogsNameTop: 2px; dialogsRowHeight: 62px; @@ -70,17 +61,25 @@ dialogsTextStyle: textStyle(defaultTextStyle) { linkFgDown: dialogsTextFgService; linkFlagsOver: font(fsize); } -dialogsTextStyleDraft: textStyle(dialogsTextStyle) { - linkFg: #dd4b39; - linkFgDown: #dd4b39; +dialogsTextStyleOver: textStyle(dialogsTextStyle) { + linkFg: dialogsTextFgServiceOver; + linkFgDown: dialogsTextFgServiceOver; } dialogsTextStyleActive: textStyle(dialogsTextStyle) { - linkFg: dialogsTextFgActive; - linkFgDown: dialogsTextFgActive; + linkFg: dialogsTextFgServiceActive; + linkFgDown: dialogsTextFgServiceActive; +} +dialogsTextStyleDraft: textStyle(dialogsTextStyle) { + linkFg: dialogsDraftFg; + linkFgDown: dialogsDraftFg; +} +dialogsTextStyleDraftOver: textStyle(dialogsTextStyle) { + linkFg: dialogsDraftFgOver; + linkFgDown: dialogsDraftFgOver; } dialogsTextStyleDraftActive: textStyle(dialogsTextStyle) { - linkFg: #c6e1f7; - linkFgDown: #c6e1f7; + linkFg: dialogsDraftFgActive; + linkFgDown: dialogsDraftFgActive; } dialogsMenuToggle: IconButton { @@ -127,30 +126,61 @@ dialogsMenuSettings: icon {{ "menu_settings", menuIconFg }}; dialogsMenuHelp: icon {{ "menu_help", menuIconFg }}; dialogsChatTypeSkip: 22px; -dialogsChatIcon: icon {{ "dialogs_chat", #373737, point(1px, 4px) }}; -dialogsChatActiveIcon: icon {{ "dialogs_chat", #ffffff, point(1px, 4px) }}; -dialogsChannelIcon: icon {{ "dialogs_channel", #373737, point(3px, 4px) }}; -dialogsChannelActiveIcon: icon {{ "dialogs_channel", #ffffff, point(3px, 4px) }}; +dialogsChatIcon: icon {{ "dialogs_chat", dialogsChatIconFg, point(1px, 4px) }}; +dialogsChatIconOver: icon {{ "dialogs_chat", dialogsChatIconFgOver, point(1px, 4px) }}; +dialogsChatIconActive: icon {{ "dialogs_chat", dialogsChatIconFgActive, point(1px, 4px) }}; +dialogsChannelIcon: icon {{ "dialogs_channel", dialogsChatIconFg, point(3px, 4px) }}; +dialogsChannelIconOver: icon {{ "dialogs_channel", dialogsChatIconFgOver, point(3px, 4px) }}; +dialogsChannelIconActive: icon {{ "dialogs_channel", dialogsChatIconFgActive, point(3px, 4px) }}; -dialogsSentStateFg: #5dc452; dialogsSendStateSkip: 20px; -dialogsSendingIcon: icon {{ "dialogs_sending", #c1c1c1, point(8px, 4px) }}; -dialogsSendingActiveIcon: icon {{ "dialogs_sending", #ffffff99, point(8px, 4px) }}; -dialogsSentIcon: icon {{ "dialogs_sent", dialogsSentStateFg, point(10px, 4px) }}; -dialogsSentActiveIcon: icon {{ "dialogs_sent", #ffffff, point(10px, 4px) }}; -dialogsReceivedIcon: icon {{ "dialogs_received", dialogsSentStateFg, point(5px, 4px) }}; -dialogsReceivedActiveIcon: icon {{ "dialogs_received", #ffffff, point(5px, 4px) }}; +dialogsSendingIcon: icon {{ "dialogs_sending", dialogsSendingIconFg, point(8px, 4px) }}; +dialogsSendingIconOver: icon {{ "dialogs_sending", dialogsSendingIconFgOver, point(8px, 4px) }}; +dialogsSendingIconActive: icon {{ "dialogs_sending", dialogsSendingIconFgActive, point(8px, 4px) }}; +dialogsSentIcon: icon {{ "dialogs_sent", dialogsSentIconFg, point(10px, 4px) }}; +dialogsSentIconOver: icon {{ "dialogs_sent", dialogsSentIconFgOver, point(10px, 4px) }}; +dialogsSentIconActive: icon {{ "dialogs_sent", dialogsSentIconFgActive, point(10px, 4px) }}; +dialogsReceivedIcon: icon {{ "dialogs_received", dialogsSentIconFg, point(5px, 4px) }}; +dialogsReceivedIconOver: icon {{ "dialogs_received", dialogsSentIconFgOver, point(5px, 4px) }}; +dialogsReceivedIconActive: icon {{ "dialogs_received", dialogsSentIconFgActive, point(5px, 4px) }}; dialogsVerifiedIcon: icon { - { "dialogs_verified_star", #4abcf1, point(4px, 2px) }, - { "dialogs_verified_check", #ffffff, point(7px, 7px) }, + { "dialogs_verified_star", dialogsVerifiedIconBg, point(4px, 2px) }, + { "dialogs_verified_check", dialogsVerifiedIconFg, point(7px, 7px) }, }; -dialogsVerifiedActiveIcon: icon { - { "dialogs_verified_star", #ffffff, point(4px, 2px) }, - { "dialogs_verified_check", #6a91b1, point(7px, 7px) }, +dialogsVerifiedIconOver: icon { + { "dialogs_verified_star", dialogsVerifiedIconBgOver, point(4px, 2px) }, + { "dialogs_verified_check", dialogsVerifiedIconFgOver, point(7px, 7px) }, +}; +dialogsVerifiedIconActive: icon { + { "dialogs_verified_star", dialogsVerifiedIconBgActive, point(4px, 2px) }, + { "dialogs_verified_check", dialogsVerifiedIconFgActive, point(7px, 7px) }, }; historySendingIcon: icon {{ "dialogs_sending", #98d292, point(5px, 5px) }}; historySendingInvertedIcon: icon {{ "dialogs_sending", #ffffffc8, point(5px, 5px) }}; historyViewsSendingIcon: icon {{ "dialogs_sending", #a0adb5, point(3px, 0px) }}; historyViewsSendingInvertedIcon: icon {{ "dialogs_sending", #ffffffc8, point(3px, 0px) }}; + +dialogsUpdateButton: flatButton { + duration: 0; + cursor: cursor(pointer); + + color: activeButtonFg; + overColor: activeButtonFgOver; + downColor: activeButtonFgOver; + + bgColor: activeButtonBg; + overBgColor: activeButtonBgOver; + downBgColor: activeButtonBgOver; + + width: -34px; + height: 46px; + + textTop: 14px; + overTextTop: 14px; + downTextTop: 15px; + + font: semiboldFont; + overFont: semiboldFont; +} diff --git a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp index 6f3bbf1e4f..bae24e0965 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp @@ -35,9 +35,12 @@ namespace { // Show all dates that are in the last 20 hours in time format. constexpr int kRecentlyInSeconds = 20 * 3600; -void paintRowDate(Painter &p, const QDateTime &date, QRect &rectForName, bool active) { - QDateTime now(QDateTime::currentDateTime()), lastTime(date); - QDate nowDate(now.date()), lastDate(lastTime.date()); +void paintRowDate(Painter &p, const QDateTime &date, QRect &rectForName, bool active, bool selected) { + auto now = QDateTime::currentDateTime(); + auto lastTime = date; + auto nowDate = now.date(); + auto lastDate = lastTime.date(); + QString dt; bool wasSameDay = (lastDate == nowDate); bool wasRecently = qAbs(lastTime.secsTo(now)) < kRecentlyInSeconds; @@ -51,7 +54,7 @@ void paintRowDate(Painter &p, const QDateTime &date, QRect &rectForName, bool ac int32 dtWidth = st::dialogsDateFont->width(dt); rectForName.setWidth(rectForName.width() - dtWidth - st::dialogsDateSkip); p.setFont(st::dialogsDateFont); - p.setPen(active ? st::dialogsDateFgActive : st::dialogsDateFg); + p.setPen(active ? st::dialogsDateFgActive : (selected ? st::dialogsDateFgOver : st::dialogsDateFg)); p.drawText(rectForName.left() + rectForName.width() + st::dialogsDateSkip, rectForName.top() + st::msgNameFont->height - st::msgDateFont->descent, dt); } @@ -68,57 +71,56 @@ void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draf int32 namewidth = w - nameleft - st::dialogsPadding.x(); QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height); - if (auto chatTypeIcon = ChatTypeIcon(history->peer, active)) { + if (auto chatTypeIcon = ChatTypeIcon(history->peer, active, selected)) { chatTypeIcon->paint(p, rectForName.topLeft(), w); rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip); } int texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip; if (draft) { - paintRowDate(p, date, rectForName, active); + paintRowDate(p, date, rectForName, active, selected); p.setFont(st::dialogsTextFont); - p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFgService); if (history->typing.isEmpty() && history->sendActions.isEmpty()) { if (history->cloudDraftTextCache.isEmpty()) { auto draftWrapped = textcmdLink(1, lng_dialogs_text_from_wrapped(lt_from, lang(lng_from_draft))); auto draftText = lng_dialogs_text_with_from(lt_from_part, draftWrapped, lt_message, textClean(draft->textWithTags.text)); history->cloudDraftTextCache.setText(st::dialogsTextFont, draftText, _textDlgOptions); } - textstyleSet(&(active ? st::dialogsTextStyleDraftActive : st::dialogsTextStyleDraft)); - p.setFont(st::dialogsTextFont); - p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFg); + p.setPen(active ? st::dialogsTextFgActive : (selected ? st::dialogsTextFgOver : st::dialogsTextFg)); + textstyleSet(&(active ? st::dialogsTextStyleDraftActive : (selected ? st::dialogsTextStyleDraftOver : st::dialogsTextStyleDraft))); history->cloudDraftTextCache.drawElided(p, nameleft, texttop, namewidth, 1); textstyleRestore(); } else { + p.setPen(active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService)); history->typingText.drawElided(p, nameleft, texttop, namewidth); } } else if (!item) { p.setFont(st::dialogsTextFont); - p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFgService); + p.setPen(active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService)); if (history->typing.isEmpty() && history->sendActions.isEmpty()) { p.drawText(nameleft, texttop + st::msgNameFont->ascent, lang(lng_empty_history)); } else { history->typingText.drawElided(p, nameleft, texttop, namewidth); } } else if (!item->isEmpty()) { - paintRowDate(p, date, rectForName, active); + paintRowDate(p, date, rectForName, active, selected); paintItemCallback(nameleft, namewidth, item); } - auto sendStateIcon = ([draft, item, active]() -> const style::icon* { + auto sendStateIcon = ([draft, item, active, selected]() -> const style::icon* { if (draft) { if (draft->saveRequestId) { - return &(active ? st::dialogsSendingActiveIcon : st::dialogsSendingIcon); + return &(active ? st::dialogsSendingIconActive : (selected ? st::dialogsSendingIconOver : st::dialogsSendingIcon)); } } else if (item && !item->isEmpty() && item->needCheck()) { if (item->id > 0) { if (item->unread()) { - return &(active ? st::dialogsSentActiveIcon : st::dialogsSentIcon); + return &(active ? st::dialogsSentIconActive : (selected ? st::dialogsSentIconOver : st::dialogsSentIcon)); } - return &(active ? st::dialogsReceivedActiveIcon : st::dialogsReceivedIcon); + return &(active ? st::dialogsReceivedIconActive : (selected ? st::dialogsReceivedIconOver : st::dialogsReceivedIcon)); } - return &(active ? st::dialogsSendingActiveIcon : st::dialogsSendingIcon); + return &(active ? st::dialogsSendingIconActive : (selected ? st::dialogsSendingIconOver : st::dialogsSendingIcon)); } return nullptr; })(); @@ -128,12 +130,12 @@ void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draf } if (history->peer->isUser() && history->peer->isVerified()) { - auto icon = &(active ? st::dialogsVerifiedActiveIcon : st::dialogsVerifiedIcon); + auto icon = &(active ? st::dialogsVerifiedIconActive : (selected ? st::dialogsVerifiedIconOver : st::dialogsVerifiedIcon)); rectForName.setWidth(rectForName.width() - icon->width()); icon->paint(p, rectForName.topLeft() + QPoint(qMin(history->peer->dialogName().maxWidth(), rectForName.width()), 0), w); } - p.setPen(active ? st::dialogsTextFgActive : st::dialogsNameFg); + p.setPen(active ? st::dialogsNameFgActive : (selected ? st::dialogsNameFgOver : st::dialogsNameFg)); history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } @@ -167,11 +169,11 @@ QImage colorizeCircleHalf(UnreadBadgeSizeData *data, int size, int half, int xof } // namepsace -const style::icon *ChatTypeIcon(PeerData *peer, bool active) { +const style::icon *ChatTypeIcon(PeerData *peer, bool active, bool selected) { if (peer->isChat() || peer->isMegagroup()) { - return &(active ? st::dialogsChatActiveIcon : st::dialogsChatIcon); + return &(active ? st::dialogsChatIconActive : (selected ? st::dialogsChatIconOver : st::dialogsChatIcon)); } else if (peer->isChannel()) { - return &(active ? st::dialogsChannelActiveIcon : st::dialogsChannelIcon); + return &(active ? st::dialogsChannelIconActive : (selected ? st::dialogsChannelIconOver : st::dialogsChannelIcon)); } return nullptr; } @@ -263,7 +265,7 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele if (item && cloudDraft && unreadCount > 0) { cloudDraft = nullptr; // Draw item, if draft is older. } - paintRow(p, history, item, cloudDraft, displayDate(), w, active, selected, onlyBackground, [&p, w, active, history, unreadCount](int nameleft, int namewidth, HistoryItem *item) { + paintRow(p, history, item, cloudDraft, displayDate(), w, active, selected, onlyBackground, [&p, w, active, selected, history, unreadCount](int nameleft, int namewidth, HistoryItem *item) { int availableWidth = namewidth; int texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip; if (unreadCount) { @@ -280,9 +282,9 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele availableWidth -= unreadWidth + st::dialogsUnreadPadding; } if (history->typing.isEmpty() && history->sendActions.isEmpty()) { - item->drawInDialog(p, QRect(nameleft, texttop, availableWidth, st::dialogsTextFont->height), active, history->textCachedFor, history->lastItemTextCache); + item->drawInDialog(p, QRect(nameleft, texttop, availableWidth, st::dialogsTextFont->height), active, selected, history->textCachedFor, history->lastItemTextCache); } else { - p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFgService); + p.setPen(active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService)); history->typingText.drawElided(p, nameleft, texttop, availableWidth); } }); @@ -291,9 +293,9 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele void RowPainter::paint(Painter &p, const FakeRow *row, int w, bool active, bool selected, bool onlyBackground) { auto item = row->item(); auto history = item->history(); - paintRow(p, history, item, nullptr, item->date, w, active, selected, onlyBackground, [&p, row, active](int nameleft, int namewidth, HistoryItem *item) { + paintRow(p, history, item, nullptr, item->date, w, active, selected, onlyBackground, [&p, row, active, selected](int nameleft, int namewidth, HistoryItem *item) { int lastWidth = namewidth, texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip; - item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dialogsTextFont->height), active, row->_cacheFor, row->_cache); + item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dialogsTextFont->height), active, selected, row->_cacheFor, row->_cache); }); } diff --git a/Telegram/SourceFiles/dialogs/dialogs_layout.h b/Telegram/SourceFiles/dialogs/dialogs_layout.h index 6e81e317be..d5765bc607 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_layout.h +++ b/Telegram/SourceFiles/dialogs/dialogs_layout.h @@ -27,7 +27,7 @@ class FakeRow; namespace Layout { -const style::icon *ChatTypeIcon(PeerData *peer, bool active); +const style::icon *ChatTypeIcon(PeerData *peer, bool active, bool selected); class RowPainter { public: diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 0342e855f8..48ae1070c5 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -40,6 +40,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "localstorage.h" #include "apiwrap.h" #include "ui/widgets/dropdown_menu.h" +#include "autoupdater.h" DialogsInner::DialogsInner(QWidget *parent, QWidget *main) : SplittedWidget(parent) , dialogs(std_::make_unique(Dialogs::SortMode::Date)) @@ -259,12 +260,12 @@ void DialogsInner::peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool a QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height); // draw chat icon - if (auto chatTypeIcon = Dialogs::Layout::ChatTypeIcon(peer, active)) { + if (auto chatTypeIcon = Dialogs::Layout::ChatTypeIcon(peer, active, selected)) { chatTypeIcon->paint(p, rectForName.topLeft(), w); rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip); } if (peer->isVerified()) { - auto icon = &(active ? st::dialogsVerifiedActiveIcon : st::dialogsVerifiedIcon); + auto icon = &(active ? st::dialogsVerifiedIconActive : (selected ? st::dialogsVerifiedIconOver : st::dialogsVerifiedIcon)); rectForName.setWidth(rectForName.width() - icon->width()); icon->paint(p, rectForName.topLeft() + QPoint(qMin(peer->dialogName().maxWidth(), rectForName.width()), 0), w); } @@ -304,7 +305,7 @@ void DialogsInner::searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) c int32 namewidth = w - nameleft - st::dialogsPadding.x() * 2 - st::dialogsCancelSearch.width; QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height); - if (auto chatTypeIcon = Dialogs::Layout::ChatTypeIcon(_searchInPeer, false)) { + if (auto chatTypeIcon = Dialogs::Layout::ChatTypeIcon(_searchInPeer, false, false)) { chatTypeIcon->paint(p, rectForName.topLeft(), w); rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip); } @@ -616,12 +617,11 @@ void DialogsInner::clearSelection() { void DialogsInner::contextMenuEvent(QContextMenuEvent *e) { if (_menu) { _menu->deleteLater(); - _menu = 0; + _menu = nullptr; } if (_menuPeer) { updateSelectedRow(_menuPeer); - _menuPeer = 0; - disconnect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*))); + _menuPeer = nullptr; } if (e->reason() == QContextMenuEvent::Mouse) { @@ -630,7 +630,7 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) { onUpdateSelected(true); } - History *history = 0; + History *history = nullptr; if (_state == DefaultState) { if (_sel) history = _sel->history(); } else if (_state == FilteredState || _state == SearchedState) { @@ -642,109 +642,19 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) { _menuPeer = history->peer; _menu = new Ui::PopupMenu(); - _menu->addAction(lang((_menuPeer->isChat() || _menuPeer->isMegagroup()) ? lng_context_view_group : (_menuPeer->isUser() ? lng_context_view_profile : lng_context_view_channel)), this, SLOT(onContextProfile()))->setEnabled(true); - _menu->addAction(lang(menuPeerMuted() ? lng_enable_notifications_from_tray : lng_disable_notifications_from_tray), this, SLOT(onContextToggleNotifications()))->setEnabled(true); - _menu->addAction(lang(lng_profile_search_messages), this, SLOT(onContextSearch()))->setEnabled(true); - if (_menuPeer->isUser()) { - _menu->addAction(lang(lng_profile_clear_history), this, SLOT(onContextClearHistory()))->setEnabled(true); - _menu->addAction(lang(lng_profile_delete_conversation), this, SLOT(onContextDeleteAndLeave()))->setEnabled(true); - if (_menuPeer->asUser()->access != UserNoAccess && _menuPeer != App::self()) { - _menu->addAction(lang(_menuPeer->asUser()->isBlocked() ? (_menuPeer->asUser()->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (_menuPeer->asUser()->botInfo ? lng_profile_block_bot : lng_profile_block_user)), this, SLOT(onContextToggleBlock()))->setEnabled(true); - connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*))); - } - } else if (_menuPeer->isChat()) { - _menu->addAction(lang(lng_profile_clear_history), this, SLOT(onContextClearHistory()))->setEnabled(true); - _menu->addAction(lang(lng_profile_clear_and_exit), this, SLOT(onContextDeleteAndLeave()))->setEnabled(true); - } else if (_menuPeer->isChannel() && _menuPeer->asChannel()->amIn() && !_menuPeer->asChannel()->amCreator()) { - _menu->addAction(lang(_menuPeer->isMegagroup() ? lng_profile_leave_group : lng_profile_leave_channel), this, SLOT(onContextDeleteAndLeave()))->setEnabled(true); - } - + App::main()->fillPeerMenu(_menuPeer, [this](const QString &text, base::lambda_unique callback) { + return _menu->addAction(text, std_::move(callback)); + }); connect(_menu, SIGNAL(destroyed(QObject*)), this, SLOT(onMenuDestroyed(QObject*))); _menu->popup(e->globalPos()); e->accept(); } -bool DialogsInner::menuPeerMuted() { - return _menuPeer && _menuPeer->notify != EmptyNotifySettings && _menuPeer->notify != UnknownNotifySettings && _menuPeer->notify->mute >= unixtime(); -} - -void DialogsInner::onContextProfile() { - if (!_menuPeer) return; - Ui::showPeerProfile(_menuPeer); -} - -void DialogsInner::onContextToggleNotifications() { - if (!_menuPeer) return; - App::main()->updateNotifySetting(_menuPeer, menuPeerMuted() ? NotifySettingSetNotify : NotifySettingSetMuted); -} - -void DialogsInner::onContextSearch() { - if (!_menuPeer) return; - App::main()->searchInPeer(_menuPeer); -} - -void DialogsInner::onContextClearHistory() { - if (!_menuPeer || _menuPeer->isChannel()) return; - - _menuActionPeer = _menuPeer; - ConfirmBox *box = new ConfirmBox(_menuPeer->isUser() ? lng_sure_delete_history(lt_contact, _menuPeer->name) : lng_sure_delete_group_history(lt_group, _menuPeer->name), lang(lng_box_delete), st::attentionBoxButton); - connect(box, SIGNAL(confirmed()), this, SLOT(onContextClearHistorySure())); - Ui::showLayer(box); -} - -void DialogsInner::onContextClearHistorySure() { - if (!_menuActionPeer || _menuActionPeer->isChannel()) return; - Ui::hideLayer(); - App::main()->clearHistory(_menuActionPeer); -} - -void DialogsInner::onContextDeleteAndLeave() { - if (!_menuPeer) return; - - _menuActionPeer = _menuPeer; - ConfirmBox *box = new ConfirmBox(_menuPeer->isUser() ? lng_sure_delete_history(lt_contact, _menuPeer->name) : (_menuPeer->isChat() ? lng_sure_delete_and_exit(lt_group, _menuPeer->name) : lang(_menuPeer->isMegagroup() ? lng_sure_leave_group : lng_sure_leave_channel)), lang(_menuPeer->isUser() ? lng_box_delete : lng_box_leave), _menuPeer->isChannel() ? st::defaultBoxButton : st::attentionBoxButton); - connect(box, SIGNAL(confirmed()), this, SLOT(onContextDeleteAndLeaveSure())); - Ui::showLayer(box); -} - -void DialogsInner::onContextDeleteAndLeaveSure() { - if (!_menuActionPeer) return; - - Ui::hideLayer(); - Ui::showChatsList(); - if (_menuActionPeer->isUser()) { - App::main()->deleteConversation(_menuActionPeer); - } else if (_menuActionPeer->isChat()) { - MTP::send(MTPmessages_DeleteChatUser(_menuActionPeer->asChat()->inputChat, App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, _menuActionPeer), App::main()->rpcFail(&MainWidget::leaveChatFailed, _menuActionPeer)); - } else if (_menuActionPeer->isChannel()) { - if (_menuActionPeer->migrateFrom()) { - App::main()->deleteConversation(_menuActionPeer->migrateFrom()); - } - MTP::send(MTPchannels_LeaveChannel(_menuActionPeer->asChannel()->inputChannel), App::main()->rpcDone(&MainWidget::sentUpdatesReceived)); - } -} - -void DialogsInner::onContextToggleBlock() { - if (!_menuPeer || !_menuPeer->isUser()) return; - if (_menuPeer->asUser()->isBlocked()) { - MTP::send(MTPcontacts_Unblock(_menuPeer->asUser()->inputUser), rpcDone(&DialogsInner::contextBlockDone, qMakePair(_menuPeer->asUser(), false))); - } else { - MTP::send(MTPcontacts_Block(_menuPeer->asUser()->inputUser), rpcDone(&DialogsInner::contextBlockDone, qMakePair(_menuPeer->asUser(), true))); - } -} - -void DialogsInner::contextBlockDone(QPair data, const MTPBool &result) { - data.first->setBlockStatus(data.second ? UserData::BlockStatus::Blocked : UserData::BlockStatus::NotBlocked); - emit App::main()->peerUpdated(data.first); -} - void DialogsInner::onMenuDestroyed(QObject *obj) { if (_menu == obj) { - _menu = 0; + _menu = nullptr; if (_menuPeer) { - updateSelectedRow(_menuPeer); - _menuPeer = 0; - disconnect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*))); + updateSelectedRow(base::take(_menuPeer)); } lastMousePos = QCursor::pos(); if (rect().contains(mapFromGlobal(lastMousePos))) { @@ -935,18 +845,6 @@ void DialogsInner::clearSearchResults(bool clearPeople) { _lastSearchId = _lastSearchMigratedId = 0; } -void DialogsInner::updateNotifySettings(PeerData *peer) { - if (_menu && _menuPeer == peer && _menu->actions().size() > 1) { - _menu->actions().at(1)->setText(lang(menuPeerMuted() ? lng_enable_notifications_from_tray : lng_disable_notifications_from_tray)); - } -} - -void DialogsInner::peerUpdated(PeerData *peer) { - if (_menu && _menuPeer == peer && _menuPeer->isUser() && _menu->actions().size() > 5) { - _menu->actions().at(5)->setText(lang(_menuPeer->asUser()->isBlocked() ? (_menuPeer->asUser()->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (_menuPeer->asUser()->botInfo ? lng_profile_block_bot : lng_profile_block_user))); - } -} - PeerData *DialogsInner::updateFromParentDrag(QPoint globalPos) { lastMousePos = globalPos; _selByMouse = true; @@ -1774,23 +1672,29 @@ DialogsWidget::DialogsWidget(QWidget *parent) : TWidget(parent) , _cancelSearch(this, st::dialogsCancelSearch) , _lockUnlock(this, st::dialogsLock) , _scroll(this, st::dialogsScroll) -, _inner(&_scroll, parent) +, _inner(this, parent) , _a_show(animation(this, &DialogsWidget::step_show)) { - _scroll.setWidget(&_inner); - _scroll.setFocusPolicy(Qt::NoFocus); - connect(&_inner, SIGNAL(mustScrollTo(int,int)), &_scroll, SLOT(scrollToY(int,int))); - connect(&_inner, SIGNAL(dialogMoved(int,int)), this, SLOT(onDialogMoved(int,int))); - connect(&_inner, SIGNAL(searchMessages()), this, SLOT(onNeedSearchMessages())); - connect(&_inner, SIGNAL(searchResultChosen()), this, SLOT(onCancel())); - connect(&_inner, SIGNAL(completeHashtag(QString)), this, SLOT(onCompleteHashtag(QString))); - connect(&_inner, SIGNAL(refreshHashtags()), this, SLOT(onFilterCursorMoved())); - connect(&_inner, SIGNAL(cancelSearchInPeer()), this, SLOT(onCancelSearchInPeer())); - connect(&_scroll, SIGNAL(geometryChanged()), &_inner, SLOT(onParentGeometryChanged())); - connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll())); + _scroll->setOwnedWidget(_inner); + connect(_inner, SIGNAL(mustScrollTo(int,int)), _scroll, SLOT(scrollToY(int,int))); + connect(_inner, SIGNAL(dialogMoved(int,int)), this, SLOT(onDialogMoved(int,int))); + connect(_inner, SIGNAL(searchMessages()), this, SLOT(onNeedSearchMessages())); + connect(_inner, SIGNAL(searchResultChosen()), this, SLOT(onCancel())); + connect(_inner, SIGNAL(completeHashtag(QString)), this, SLOT(onCompleteHashtag(QString))); + connect(_inner, SIGNAL(refreshHashtags()), this, SLOT(onFilterCursorMoved())); + connect(_inner, SIGNAL(cancelSearchInPeer()), this, SLOT(onCancelSearchInPeer())); + connect(_scroll, SIGNAL(geometryChanged()), _inner, SLOT(onParentGeometryChanged())); + connect(_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll())); connect(_filter, SIGNAL(cancelled()), this, SLOT(onCancel())); connect(_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate())); connect(_filter, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(onFilterCursorMoved(int,int))); +#ifndef TDESKTOP_DISABLE_AUTOUPDATE + Sandbox::connect(SIGNAL(updateLatest()), this, SLOT(onCheckUpdateStatus())); + Sandbox::connect(SIGNAL(updateFailed()), this, SLOT(onCheckUpdateStatus())); + Sandbox::connect(SIGNAL(updateReady()), this, SLOT(onCheckUpdateStatus())); + onCheckUpdateStatus(); +#endif // !TDESKTOP_DISABLE_AUTOUPDATE + _cancelSearch->setClickedCallback([this] { onCancelSearch(); }); _lockUnlock->setVisible(Global::LocalPasscode()); subscribe(Global::RefLocalPasscodeChanged(), [this] { updateLockUnlockVisibility(); }); @@ -1814,34 +1718,52 @@ DialogsWidget::DialogsWidget(QWidget *parent) : TWidget(parent) _cancelSearch->hide(); } +#ifndef TDESKTOP_DISABLE_AUTOUPDATE +void DialogsWidget::onCheckUpdateStatus() { + if (Sandbox::updatingState() == Application::UpdatingReady) { + if (_updateTelegram) return; + _updateTelegram.create(this, lang(lng_update_telegram).toUpper(), st::dialogsUpdateButton); + _updateTelegram->show(); + _updateTelegram->setClickedCallback([] { + checkReadyUpdate(); + App::restart(); + }); + } else { + if (!_updateTelegram) return; + _updateTelegram.destroy(); + } + updateControlsGeometry(); +} +#endif // TDESKTOP_DISABLE_AUTOUPDATE + void DialogsWidget::activate() { _filter->setFocus(); - _inner.activate(); + _inner->activate(); } void DialogsWidget::createDialog(History *history) { - bool creating = !history->inChatList(Dialogs::Mode::All); - _inner.createDialog(history); + auto creating = !history->inChatList(Dialogs::Mode::All); + _inner->createDialog(history); if (creating && history->peer->migrateFrom()) { - if (History *h = App::historyLoaded(history->peer->migrateFrom()->id)) { - if (h->inChatList(Dialogs::Mode::All)) { - removeDialog(h); + if (auto migrated = App::historyLoaded(history->peer->migrateFrom()->id)) { + if (migrated->inChatList(Dialogs::Mode::All)) { + removeDialog(migrated); } } } } void DialogsWidget::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) { - _inner.dlgUpdated(list, row); + _inner->dlgUpdated(list, row); } void DialogsWidget::dlgUpdated(History *row, MsgId msgId) { - _inner.dlgUpdated(row, msgId); + _inner->dlgUpdated(row, msgId); } void DialogsWidget::dialogsToUp() { if (_filter->getLastText().trimmed().isEmpty()) { - _scroll.scrollToY(0); + _scroll->scrollToY(0); } } @@ -1854,7 +1776,7 @@ void DialogsWidget::showAnimated(Window::SlideDirection direction, const Window: _a_show.stop(); - _scroll.hide(); + _scroll->hide(); _mainMenuToggle->hide(); _filter->hide(); _cancelSearch->hide(); @@ -1885,7 +1807,7 @@ void DialogsWidget::step_show(float64 ms, bool timer) { _cacheUnder = _cacheOver = QPixmap(); - _scroll.show(); + _scroll->show(); _mainMenuToggle->show(); _filter->show(); updateLockUnlockVisibility(); @@ -1909,21 +1831,17 @@ void DialogsWidget::onCancel() { } } -void DialogsWidget::updateNotifySettings(PeerData *peer) { - _inner.updateNotifySettings(peer); -} - void DialogsWidget::notify_userIsContactChanged(UserData *user, bool fromThisApp) { if (fromThisApp) { _filter->setText(QString()); _filter->updatePlaceholder(); onFilterUpdate(); } - _inner.notify_userIsContactChanged(user, fromThisApp); + _inner->notify_userIsContactChanged(user, fromThisApp); } void DialogsWidget::notify_historyMuteUpdated(History *history) { - _inner.notify_historyMuteUpdated(history); + _inner->notify_historyMuteUpdated(history); } void DialogsWidget::unreadCountsReceived(const QVector &dialogs) { @@ -1961,7 +1879,7 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque } if (dialogsList) { unreadCountsReceived(*dialogsList); - _inner.dialogsReceived(*dialogsList); + _inner->dialogsReceived(*dialogsList); onListScroll(); TimeId lastDate = 0; @@ -2080,7 +1998,7 @@ void DialogsWidget::onNeedSearchMessages() { } void DialogsWidget::onChooseByDrag() { - _inner.choosePeer(); + _inner->choosePeer(); } void DialogsWidget::showMainMenu() { @@ -2112,7 +2030,7 @@ void DialogsWidget::searchMessages(const QString &query, PeerData *inPeer) { onCancelSearch(); _searchInPeer = inPeer->migrateTo() ? inPeer->migrateTo() : inPeer; _searchInMigrated = _searchInPeer ? _searchInPeer->migrateFrom() : 0; - _inner.searchInPeer(_searchInPeer); + _inner->searchInPeer(_searchInPeer); } _filter->setText(query); _filter->updatePlaceholder(); @@ -2120,16 +2038,16 @@ void DialogsWidget::searchMessages(const QString &query, PeerData *inPeer) { _searchTimer.stop(); onSearchMessages(); - _inner.saveRecentHashtags(query); + _inner->saveRecentHashtags(query); } } void DialogsWidget::onSearchMore() { if (!_searchRequest) { if (!_searchFull) { - int32 offsetDate = _inner.lastSearchDate(); - PeerData *offsetPeer = _inner.lastSearchPeer(); - MsgId offsetId = _inner.lastSearchId(); + int32 offsetDate = _inner->lastSearchDate(); + PeerData *offsetPeer = _inner->lastSearchPeer(); + MsgId offsetId = _inner->lastSearchId(); if (_searchInPeer) { MTPmessages_Search::Flags flags = 0; _searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _searchInPeer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(offsetId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart), rpcFail(&DialogsWidget::searchFailed, offsetId ? DialogsSearchPeerFromOffset : DialogsSearchPeerFromStart)); @@ -2140,7 +2058,7 @@ void DialogsWidget::onSearchMore() { _searchQueries.insert(_searchRequest, _searchQuery); } } else if (_searchInMigrated && !_searchFullMigrated) { - MsgId offsetMigratedId = _inner.lastSearchMigratedId(); + MsgId offsetMigratedId = _inner->lastSearchMigratedId(); MTPmessages_Search::Flags flags = 0; _searchRequest = MTP::send(MTPmessages_Search(MTP_flags(flags), _searchInMigrated->input, MTP_string(_searchQuery), MTP_inputMessagesFilterEmpty(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(offsetMigratedId), MTP_int(SearchPerPage)), rpcDone(&DialogsWidget::searchReceived, offsetMigratedId ? DialogsSearchMigratedFromOffset : DialogsSearchMigratedFromStart), rpcFail(&DialogsWidget::searchFailed, offsetMigratedId ? DialogsSearchMigratedFromOffset : DialogsSearchMigratedFromStart)); } @@ -2150,7 +2068,7 @@ void DialogsWidget::onSearchMore() { void DialogsWidget::loadDialogs() { if (_dialogsRequest) return; if (_dialogsFull) { - _inner.addAllSavedPeers(); + _inner->addAllSavedPeers(); cSetDialogsReceived(true); return; } @@ -2164,7 +2082,7 @@ void DialogsWidget::contactsReceived(const MTPcontacts_Contacts &contacts) { if (contacts.type() == mtpc_contacts_contacts) { const auto &d(contacts.c_contacts_contacts()); App::feedUsers(d.vusers); - _inner.contactsReceived(d.vcontacts.c_vector().v); + _inner->contactsReceived(d.vcontacts.c_vector().v); } if (App::main()) App::main()->contactsReceived(); } @@ -2176,7 +2094,7 @@ bool DialogsWidget::contactsFailed(const RPCError &error) { } void DialogsWidget::searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req) { - if (_inner.state() == DialogsInner::FilteredState || _inner.state() == DialogsInner::SearchedState) { + if (_inner->state() == DialogsInner::FilteredState || _inner->state() == DialogsInner::SearchedState) { if (type == DialogsSearchFromStart || type == DialogsSearchPeerFromStart) { SearchQueries::iterator i = _searchQueries.find(req); if (i != _searchQueries.cend()) { @@ -2193,7 +2111,7 @@ void DialogsWidget::searchReceived(DialogsSearchRequestType type, const MTPmessa App::feedUsers(d.vusers); App::feedChats(d.vchats); auto &msgs(d.vmessages.c_vector().v); - if (!_inner.searchReceived(msgs, type, msgs.size())) { + if (!_inner->searchReceived(msgs, type, msgs.size())) { if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) { _searchFullMigrated = true; } else { @@ -2207,7 +2125,7 @@ void DialogsWidget::searchReceived(DialogsSearchRequestType type, const MTPmessa App::feedUsers(d.vusers); App::feedChats(d.vchats); auto &msgs(d.vmessages.c_vector().v); - if (!_inner.searchReceived(msgs, type, d.vcount.v)) { + if (!_inner->searchReceived(msgs, type, d.vcount.v)) { if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) { _searchFullMigrated = true; } else { @@ -2226,7 +2144,7 @@ void DialogsWidget::searchReceived(DialogsSearchRequestType type, const MTPmessa App::feedUsers(d.vusers); App::feedChats(d.vchats); auto &msgs(d.vmessages.c_vector().v); - if (!_inner.searchReceived(msgs, type, d.vcount.v)) { + if (!_inner->searchReceived(msgs, type, d.vcount.v)) { if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) { _searchFullMigrated = true; } else { @@ -2244,7 +2162,7 @@ void DialogsWidget::searchReceived(DialogsSearchRequestType type, const MTPmessa void DialogsWidget::peopleReceived(const MTPcontacts_Found &result, mtpRequestId req) { auto q = _peopleQuery; - if (_inner.state() == DialogsInner::FilteredState || _inner.state() == DialogsInner::SearchedState) { + if (_inner->state() == DialogsInner::FilteredState || _inner->state() == DialogsInner::SearchedState) { auto i = _peopleQueries.find(req); if (i != _peopleQueries.cend()) { q = i.value(); @@ -2258,7 +2176,7 @@ void DialogsWidget::peopleReceived(const MTPcontacts_Found &result, mtpRequestId auto &d = result.c_contacts_found(); App::feedUsers(d.vusers); App::feedChats(d.vchats); - _inner.peopleReceived(q, d.vresults.c_vector().v); + _inner->peopleReceived(q, d.vresults.c_vector().v); } break; } @@ -2302,7 +2220,7 @@ void DialogsWidget::dragEnterEvent(QDragEnterEvent *e) { if (_dragForward) { e->setDropAction(Qt::CopyAction); e->accept(); - updateDragInScroll(_scroll.geometry().contains(e->pos())); + updateDragInScroll(_scroll->geometry().contains(e->pos())); } else if (App::main() && App::main()->getDragState(e->mimeData()) != DragStateNone) { e->setDropAction(Qt::CopyAction); e->accept(); @@ -2311,13 +2229,13 @@ void DialogsWidget::dragEnterEvent(QDragEnterEvent *e) { } void DialogsWidget::dragMoveEvent(QDragMoveEvent *e) { - if (_scroll.geometry().contains(e->pos())) { + if (_scroll->geometry().contains(e->pos())) { if (_dragForward) { updateDragInScroll(true); } else { _chooseByDragTimer.start(ChoosePeerByDragTimeout); } - PeerData *p = _inner.updateFromParentDrag(mapToGlobal(e->pos())); + PeerData *p = _inner->updateFromParentDrag(mapToGlobal(e->pos())); if (p) { e->setDropAction(Qt::CopyAction); } else { @@ -2325,7 +2243,7 @@ void DialogsWidget::dragMoveEvent(QDragMoveEvent *e) { } } else { if (_dragForward) updateDragInScroll(false); - _inner.leaveEvent(0); + _inner->leaveEvent(0); e->setDropAction(Qt::IgnoreAction); } e->accept(); @@ -2337,7 +2255,7 @@ void DialogsWidget::dragLeaveEvent(QDragLeaveEvent *e) { } else { _chooseByDragTimer.stop(); } - _inner.leaveEvent(0); + _inner->leaveEvent(0); e->accept(); } @@ -2354,8 +2272,8 @@ void DialogsWidget::updateDragInScroll(bool inScroll) { void DialogsWidget::dropEvent(QDropEvent *e) { _chooseByDragTimer.stop(); - if (_scroll.geometry().contains(e->pos())) { - PeerData *p = _inner.updateFromParentDrag(mapToGlobal(e->pos())); + if (_scroll->geometry().contains(e->pos())) { + PeerData *p = _inner->updateFromParentDrag(mapToGlobal(e->pos())); if (p) { e->acceptProposedAction(); App::main()->onFilesOrForwardDrop(p->id, e->mimeData()); @@ -2366,12 +2284,12 @@ void DialogsWidget::dropEvent(QDropEvent *e) { void DialogsWidget::onListScroll() { // if (!App::self()) return; - _inner.loadPeerPhotos(_scroll.scrollTop()); - if (_inner.state() == DialogsInner::SearchedState || (_inner.state() == DialogsInner::FilteredState && _searchInMigrated && _searchFull && !_searchFullMigrated)) { - if (_scroll.scrollTop() > (_inner.searchList().size() + _inner.filteredList().size() + _inner.peopleList().size()) * st::dialogsRowHeight - PreloadHeightsCount * _scroll.height()) { + _inner->loadPeerPhotos(_scroll->scrollTop()); + if (_inner->state() == DialogsInner::SearchedState || (_inner->state() == DialogsInner::FilteredState && _searchInMigrated && _searchFull && !_searchFullMigrated)) { + if (_scroll->scrollTop() > (_inner->searchList().size() + _inner->filteredList().size() + _inner->peopleList().size()) * st::dialogsRowHeight - PreloadHeightsCount * _scroll->height()) { onSearchMore(); } - } else if (_scroll.scrollTop() > _inner.dialogsList()->size() * st::dialogsRowHeight - PreloadHeightsCount * _scroll.height()) { + } else if (_scroll->scrollTop() > _inner->dialogsList()->size() * st::dialogsRowHeight - PreloadHeightsCount * _scroll->height()) { loadDialogs(); } } @@ -2380,7 +2298,7 @@ void DialogsWidget::onFilterUpdate(bool force) { if (_a_show.animating() && !force) return; QString filterText = _filter->getLastText(); - _inner.onFilterUpdate(filterText, force); + _inner->onFilterUpdate(filterText, force); if (filterText.isEmpty()) { _searchCache.clear(); _searchQueries.clear(); @@ -2400,7 +2318,7 @@ void DialogsWidget::searchInPeer(PeerData *peer) { onCancelSearch(); _searchInPeer = peer ? (peer->migrateTo() ? peer->migrateTo() : peer) : 0; _searchInMigrated = _searchInPeer ? _searchInPeer->migrateFrom() : 0; - _inner.searchInPeer(_searchInPeer); + _inner->searchInPeer(_searchInPeer); onFilterUpdate(true); } @@ -2417,7 +2335,7 @@ void DialogsWidget::onFilterCursorMoved(int from, int to) { } if (!t.at(start).isLetterOrNumber() && t.at(start) != '_') break; } - _inner.onHashtagFilterUpdate(r); + _inner->onHashtagFilterUpdate(r); } void DialogsWidget::onCompleteHashtag(QString tag) { @@ -2449,19 +2367,7 @@ void DialogsWidget::onCompleteHashtag(QString tag) { void DialogsWidget::resizeEvent(QResizeEvent *e) { updateControlsGeometry(); - - _scroll.move(0, _filter->height() + 2 * st::dialogsFilterPadding.y()); - updateMainMenuGeometry(); - - int32 addToY = App::main() ? App::main()->contentScrollAddToY() : 0; - int32 newScrollY = _scroll.scrollTop() + addToY; - _scroll.resize(width(), height() - _filter->y() - _filter->height() - st::dialogsFilterPadding.y() - st::dialogsPadding.y()); - if (addToY) { - _scroll.scrollToY(newScrollY); - } else { - onListScroll(); - } } void DialogsWidget::updateLockUnlockVisibility() { @@ -2482,6 +2388,24 @@ void DialogsWidget::updateControlsGeometry() { _mainMenuToggle->moveToLeft(st::dialogsFilterPadding.x(), _filter->y()); _lockUnlock->moveToRight(st::dialogsFilterPadding.x(), _filter->y()); _cancelSearch->moveToLeft(filterLeft + filterWidth - _cancelSearch->width(), _filter->y()); + + auto addToScroll = App::main() ? App::main()->contentScrollAddToY() : 0; + auto newScrollTop = _scroll->scrollTop() + addToScroll; + auto scrollTop = _filter->height() + 2 * st::dialogsFilterPadding.y(); + auto scrollHeight = height() - scrollTop; + if (_updateTelegram) { + auto updateHeight = _updateTelegram->height(); + _updateTelegram->setGeometry(0, height() - updateHeight, width(), updateHeight); + scrollHeight -= updateHeight; + } else { + scrollHeight -= st::dialogsPadding.y(); + } + _scroll->setGeometry(0, scrollTop, width(), scrollHeight); + if (addToScroll) { + _scroll->scrollToY(newScrollTop); + } else { + onListScroll(); + } } void DialogsWidget::updateMainMenuGeometry() { @@ -2494,26 +2418,26 @@ void DialogsWidget::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Escape) { e->ignore(); } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { - if (!_inner.choosePeer()) { - if (_inner.state() == DialogsInner::DefaultState || _inner.state() == DialogsInner::SearchedState || (_inner.state() == DialogsInner::FilteredState && _inner.hasFilteredResults())) { - _inner.selectSkip(1); - _inner.choosePeer(); + if (!_inner->choosePeer()) { + if (_inner->state() == DialogsInner::DefaultState || _inner->state() == DialogsInner::SearchedState || (_inner->state() == DialogsInner::FilteredState && _inner->hasFilteredResults())) { + _inner->selectSkip(1); + _inner->choosePeer(); } else { onSearchMessages(); } } } else if (e->key() == Qt::Key_Down) { - _inner.setMouseSel(false); - _inner.selectSkip(1); + _inner->setMouseSel(false); + _inner->selectSkip(1); } else if (e->key() == Qt::Key_Up) { - _inner.setMouseSel(false); - _inner.selectSkip(-1); + _inner->setMouseSel(false); + _inner->selectSkip(-1); } else if (e->key() == Qt::Key_PageDown) { - _inner.setMouseSel(false); - _inner.selectSkipPage(_scroll.height(), 1); + _inner->setMouseSel(false); + _inner->selectSkipPage(_scroll->height(), 1); } else if (e->key() == Qt::Key_PageUp) { - _inner.setMouseSel(false); - _inner.selectSkipPage(_scroll.height(), -1); + _inner->setMouseSel(false); + _inner->selectSkipPage(_scroll->height(), -1); } else { e->ignore(); } @@ -2540,43 +2464,43 @@ void DialogsWidget::paintEvent(QPaintEvent *e) { st::slideShadow.fill(p, QRect(a_coordOver.current() - st::slideShadow.width(), 0, st::slideShadow.width(), _cacheOver.height() / retina)); return; } - QRect above(0, 0, width(), _scroll.y()); + QRect above(0, 0, width(), _scroll->y()); if (above.intersects(r)) { p.fillRect(above.intersected(r), st::dialogsBg); } - QRect below(0, _scroll.y() + qMin(_scroll.height(), _inner.height()), width(), height()); + QRect below(0, _scroll->y() + qMin(_scroll->height(), _inner->height()), width(), height()); if (below.intersects(r)) { p.fillRect(below.intersected(r), st::dialogsBg); } } void DialogsWidget::destroyData() { - _inner.destroyData(); + _inner->destroyData(); } void DialogsWidget::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const { - return _inner.peerBefore(inPeer, inMsg, outPeer, outMsg); + return _inner->peerBefore(inPeer, inMsg, outPeer, outMsg); } void DialogsWidget::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const { - return _inner.peerAfter(inPeer, inMsg, outPeer, outMsg); + return _inner->peerAfter(inPeer, inMsg, outPeer, outMsg); } void DialogsWidget::scrollToPeer(const PeerId &peer, MsgId msgId) { - _inner.scrollToPeer(peer, msgId); + _inner->scrollToPeer(peer, msgId); } void DialogsWidget::removeDialog(History *history) { - _inner.removeDialog(history); + _inner->removeDialog(history); onFilterUpdate(); } Dialogs::IndexedList *DialogsWidget::contactsList() { - return _inner.contactsList(); + return _inner->contactsList(); } Dialogs::IndexedList *DialogsWidget::dialogsList() { - return _inner.dialogsList(); + return _inner->dialogsList(); } bool DialogsWidget::onCancelSearch() { @@ -2590,10 +2514,10 @@ bool DialogsWidget::onCancelSearch() { Ui::showPeerHistory(_searchInPeer, ShowAtUnreadMsgId); } _searchInPeer = _searchInMigrated = 0; - _inner.searchInPeer(0); + _inner->searchInPeer(0); clearing = true; } - _inner.clearFilter(); + _inner->clearFilter(); _filter->clear(); _filter->updatePlaceholder(); onFilterUpdate(); @@ -2610,9 +2534,9 @@ void DialogsWidget::onCancelSearchInPeer() { Ui::showPeerHistory(_searchInPeer, ShowAtUnreadMsgId); } _searchInPeer = _searchInMigrated = 0; - _inner.searchInPeer(0); + _inner->searchInPeer(0); } - _inner.clearFilter(); + _inner->clearFilter(); _filter->clear(); _filter->updatePlaceholder(); onFilterUpdate(); @@ -2622,8 +2546,8 @@ void DialogsWidget::onCancelSearchInPeer() { } void DialogsWidget::onDialogMoved(int movedFrom, int movedTo) { - int32 st = _scroll.scrollTop(); + int32 st = _scroll->scrollTop(); if (st > movedTo && st < movedFrom) { - _scroll.scrollToY(st + st::dialogsRowHeight); + _scroll->scrollToY(st + st::dialogsRowHeight); } } diff --git a/Telegram/SourceFiles/dialogswidget.h b/Telegram/SourceFiles/dialogswidget.h index 7778e6ab0c..f2f735213b 100644 --- a/Telegram/SourceFiles/dialogswidget.h +++ b/Telegram/SourceFiles/dialogswidget.h @@ -134,19 +134,8 @@ public slots: void onPeerPhotoChanged(PeerData *peer); void onDialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRow); - void onContextProfile(); - void onContextToggleNotifications(); - void onContextSearch(); - void onContextClearHistory(); - void onContextClearHistorySure(); - void onContextDeleteAndLeave(); - void onContextDeleteAndLeaveSure(); - void onContextToggleBlock(); - void onMenuDestroyed(QObject*); - void peerUpdated(PeerData *peer); - signals: void mustScrollTo(int scrollToTop, int scrollToBottom); void dialogMoved(int movedFrom, int movedTo); @@ -173,8 +162,6 @@ private: void clearSelection(); void clearSearchResults(bool clearPeople = true); void updateSelectedRow(PeerData *peer = 0); - bool menuPeerMuted(); - void contextBlockDone(QPair data, const MTPBool &result); Dialogs::IndexedList *shownDialogs() const { return (Global::DialogsMode() == Dialogs::Mode::Important) ? importantDialogs.get() : dialogs.get(); @@ -227,7 +214,6 @@ private: PeerData *_searchInPeer = nullptr; PeerData *_searchInMigrated = nullptr; PeerData *_menuPeer = nullptr; - PeerData *_menuActionPeer = nullptr; Ui::PopupMenu *_menu = nullptr; @@ -283,10 +269,8 @@ public: void searchMessages(const QString &query, PeerData *inPeer = 0); void onSearchMore(); - void updateNotifySettings(PeerData *peer); - void rpcClear() override { - _inner.rpcClear(); + _inner->rpcClear(); RPCSender::rpcClear(); } @@ -313,6 +297,11 @@ public slots: void onChooseByDrag(); +#ifndef TDESKTOP_DISABLE_AUTOUPDATE +private slots: + void onCheckUpdateStatus(); +#endif // TDESKTOP_DISABLE_AUTOUPDATE + private: void showMainMenu(); void updateLockUnlockVisibility(); @@ -341,8 +330,9 @@ private: ChildWidget _filter; ChildWidget _cancelSearch; ChildWidget _lockUnlock; - ScrollArea _scroll; - DialogsInner _inner; + ChildWidget _scroll; + ChildWidget _inner; + ChildWidget _updateTelegram = { nullptr }; Animation _a_show; QPixmap _cacheUnder, _cacheOver; diff --git a/Telegram/SourceFiles/history/field_autocomplete.cpp b/Telegram/SourceFiles/history/field_autocomplete.cpp index b46b759a81..b4db5ee2fd 100644 --- a/Telegram/SourceFiles/history/field_autocomplete.cpp +++ b/Telegram/SourceFiles/history/field_autocomplete.cpp @@ -33,19 +33,12 @@ FieldAutocomplete::FieldAutocomplete(QWidget *parent) : TWidget(parent) , _inner(this, &_mrows, &_hrows, &_brows, &_srows) , a_opacity(0) , _a_appearance(animation(this, &FieldAutocomplete::step_appearance)) { - _hideTimer.setSingleShot(true); - connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideStart())); - connect(_inner, SIGNAL(mentionChosen(UserData*,FieldAutocomplete::ChooseMethod)), this, SIGNAL(mentionChosen(UserData*,FieldAutocomplete::ChooseMethod))); connect(_inner, SIGNAL(hashtagChosen(QString,FieldAutocomplete::ChooseMethod)), this, SIGNAL(hashtagChosen(QString,FieldAutocomplete::ChooseMethod))); connect(_inner, SIGNAL(botCommandChosen(QString,FieldAutocomplete::ChooseMethod)), this, SIGNAL(botCommandChosen(QString,FieldAutocomplete::ChooseMethod))); connect(_inner, SIGNAL(stickerChosen(DocumentData*,FieldAutocomplete::ChooseMethod)), this, SIGNAL(stickerChosen(DocumentData*,FieldAutocomplete::ChooseMethod))); connect(_inner, SIGNAL(mustScrollTo(int, int)), _scroll, SLOT(scrollToY(int, int))); - setFocusPolicy(Qt::NoFocus); - _scroll->setFocusPolicy(Qt::NoFocus); - _scroll->viewport()->setFocusPolicy(Qt::NoFocus); - _inner->setGeometry(rect()); _scroll->setGeometry(rect()); @@ -402,7 +395,6 @@ void FieldAutocomplete::hideFast() { _a_appearance.stop(); } a_opacity = anim::fvalue(0, 0); - _hideTimer.stop(); hideFinish(); } diff --git a/Telegram/SourceFiles/history/field_autocomplete.h b/Telegram/SourceFiles/history/field_autocomplete.h index 751035ffc8..8324ada7f7 100644 --- a/Telegram/SourceFiles/history/field_autocomplete.h +++ b/Telegram/SourceFiles/history/field_autocomplete.h @@ -130,8 +130,6 @@ private: anim::fvalue a_opacity; Animation _a_appearance; - QTimer _hideTimer; - friend class internal::FieldAutocompleteInner; }; diff --git a/Telegram/SourceFiles/history/history.style b/Telegram/SourceFiles/history/history.style index 6988e7ff97..b17f4e898a 100644 --- a/Telegram/SourceFiles/history/history.style +++ b/Telegram/SourceFiles/history/history.style @@ -80,25 +80,22 @@ historyFileOutPlaySelected: icon {{ "history_file_play", msgOutBgSelected }}; historyFileInPlay: icon {{ "history_file_play", msgInBg }}; historyFileInPlaySelected: icon {{ "history_file_play", msgInBgSelected }}; -historyOutFg: dialogsSentStateFg; -historyOutSelectedFg: #4da79f; -historyInvertedFg: #ffffff; historySendStateSpace: 24px; historySendStatePosition: point(-17px, -19px); -historySentIcon: icon {{ "history_sent", historyOutFg, point(2px, 4px) }}; -historySentSelectedIcon: icon {{ "history_sent", historyOutSelectedFg, point(2px, 4px) }}; -historySentInvertedIcon: icon {{ "history_sent", historyInvertedFg, point(2px, 4px) }}; -historyReceivedIcon: icon {{ "history_received", historyOutFg, point(2px, 4px) }}; -historyReceivedSelectedIcon: icon {{ "history_received", historyOutSelectedFg, point(2px, 4px) }}; -historyReceivedInvertedIcon: icon {{ "history_received", historyInvertedFg, point(2px, 4px) }}; +historySentIcon: icon {{ "history_sent", historyOutIconFg, point(2px, 4px) }}; +historySentSelectedIcon: icon {{ "history_sent", historyOutIconFgSelected, point(2px, 4px) }}; +historySentInvertedIcon: icon {{ "history_sent", historyIconFgInverted, point(2px, 4px) }}; +historyReceivedIcon: icon {{ "history_received", historyOutIconFg, point(2px, 4px) }}; +historyReceivedSelectedIcon: icon {{ "history_received", historyOutIconFgSelected, point(2px, 4px) }}; +historyReceivedInvertedIcon: icon {{ "history_received", historyIconFgInverted, point(2px, 4px) }}; historyViewsSpace: 11px; historyViewsWidth: 20px; historyViewsTop: -15px; historyViewsInIcon: icon {{ "history_views", #a0acb6 }}; historyViewsInSelectedIcon: icon {{ "history_views", #6a9bc5 }}; -historyViewsOutIcon: icon {{ "history_views", historyOutFg }}; -historyViewsOutSelectedIcon: icon {{ "history_views", historyOutSelectedFg }}; +historyViewsOutIcon: icon {{ "history_views", historyOutIconFg }}; +historyViewsOutSelectedIcon: icon {{ "history_views", historyOutIconFgSelected }}; historyViewsInvertedIcon: icon {{ "history_views", #ffffffe6 }}; historyPeer1NameFg: #c03d33; // red @@ -279,16 +276,20 @@ historyInlineBotCancel: MaskButton(historyReplyCancel) { height: 46px; } -topBarSearch: MaskButton { +topBarSearch: IconButton { width: 44px; height: topBarHeight; - bg: topBarBg; - icon: icon {{ "title_search-invert", topBarBg }}; - - iconBg: #c7c7c7; - iconBgOver: #a3a3a3; + icon: icon {{ "title_search", #a8a8a8 }}; + iconOver: icon {{ "title_search", #a3a3a3 }}; iconPosition: point(13px, 18px); iconPositionDown: point(13px, 18px); } +topBarMenuToggle: IconButton(topBarSearch) { + icon: icon {{ "title_menu_dots", #a8a8a8 }}; + iconOver: icon {{ "title_menu_dots", #a3a3a3 }}; + + iconPosition: point(18px, 17px); + iconPositionDown: point(18px, 17px); +} diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index e3adc56e4d..6eccdee610 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -859,15 +859,15 @@ QString HistoryItem::inDialogsText() const { return plainText; } -void HistoryItem::drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const { +void HistoryItem::drawInDialog(Painter &p, const QRect &r, bool active, bool selected, const HistoryItem *&cacheFor, Text &cache) const { if (cacheFor != this) { cacheFor = this; cache.setText(st::dialogsTextFont, inDialogsText(), _textDlgOptions); } if (r.width()) { - textstyleSet(&(act ? st::dialogsTextStyleActive : st::dialogsTextStyle)); + textstyleSet(&(active ? st::dialogsTextStyleActive : (selected ? st::dialogsTextStyleOver : st::dialogsTextStyle))); p.setFont(st::dialogsTextFont); - p.setPen(act ? st::dialogsTextFgActive : st::dialogsTextFg); + p.setPen(active ? st::dialogsTextFgActive : (selected ? st::dialogsTextFgOver : st::dialogsTextFg)); cache.drawElided(p, r.left(), r.top(), r.width(), r.height() / st::dialogsTextFont->height); textstyleRestore(); } diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 0c61b2a87b..4ffdaf629a 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -659,7 +659,7 @@ public: virtual void setViewsCount(int32 count) { } virtual void setId(MsgId newId); - void drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const; + void drawInDialog(Painter &p, const QRect &r, bool active, bool selected, const HistoryItem *&cacheFor, Text &cache) const; bool emptyText() const { return _text.isEmpty(); diff --git a/Telegram/SourceFiles/history/history_media_types.cpp b/Telegram/SourceFiles/history/history_media_types.cpp index 0f8be9e4ea..759cb3f608 100644 --- a/Telegram/SourceFiles/history/history_media_types.cpp +++ b/Telegram/SourceFiles/history/history_media_types.cpp @@ -2649,7 +2649,7 @@ void HistoryWebPage::draw(Painter &p, const QRect &r, TextSelection selection, u bool out = _parent->out(), isPost = _parent->isPost(), outbg = out && !isPost; bool selected = (selection == FullSelection); - auto &barfg = selected ? (outbg ? st::historyOutSelectedFg : st::msgInReplyBarSelColor) : (outbg ? st::historyOutFg : st::msgInReplyBarColor); + auto &barfg = selected ? (outbg ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (outbg ? st::msgOutReplyBarColor : st::msgInReplyBarColor); auto &semibold = selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg); auto ®ular = selected ? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected) : (outbg ? st::msgOutDateFg : st::msgInDateFg); @@ -3048,7 +3048,7 @@ void HistoryGame::draw(Painter &p, const QRect &r, TextSelection selection, uint bool out = _parent->out(), isPost = _parent->isPost(), outbg = out && !isPost; bool selected = (selection == FullSelection); - auto &barfg = selected ? (outbg ? st::historyOutSelectedFg : st::msgInReplyBarSelColor) : (outbg ? st::historyOutFg : st::msgInReplyBarColor); + auto &barfg = selected ? (outbg ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (outbg ? st::msgOutReplyBarColor : st::msgInReplyBarColor); auto &semibold = selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg); auto ®ular = selected ? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected) : (outbg ? st::msgOutDateFg : st::msgInDateFg); diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index 99e12e1d4a..0d32d39bce 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -245,7 +245,7 @@ void HistoryMessageReply::paint(Painter &p, const HistoryItem *holder, int x, in const style::color *bar = &st::msgImgReplyBarColor; if (flags & PaintInBubble) { - bar = &((flags & PaintSelected) ? (outbg ? st::historyOutSelectedFg : st::msgInReplyBarSelColor) : (outbg ? st::historyOutFg : st::msgInReplyBarColor)); + bar = &((flags & PaintSelected) ? (outbg ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (outbg ? st::msgOutReplyBarColor : st::msgInReplyBarColor)); } QRect rbar(rtlrect(x + st::msgReplyBarPos.x(), y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height(), w + 2 * x)); p.fillRect(rbar, *bar); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 6768ad0354..d4c86564fe 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -3019,8 +3019,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) , _fileLoader(this, FileLoaderQueueStopTimeout) , _a_show(animation(this, &HistoryWidget::step_show)) , _topShadow(this, st::shadowColor) { - _scroll.setFocusPolicy(Qt::NoFocus); - setAcceptDrops(true); subscribe(FileDownload::ImageLoaded(), [this] { update(); }); @@ -3086,8 +3084,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) _scroll.hide(); - _kbScroll.setFocusPolicy(Qt::NoFocus); - _kbScroll.viewport()->setFocusPolicy(Qt::NoFocus); _kbScroll.setWidget(&_keyboard); _kbScroll.hide(); @@ -6279,9 +6275,6 @@ void HistoryWidget::paintTopBar(Painter &p, float64 over, int32 decreaseWidth) { if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) { p.setOpacity(st::topBarForwardAlpha + (1 - st::topBarForwardAlpha) * over); st::topBarBackward.paint(p, (st::topBarArrowPadding.left() - st::topBarBackward.width()) / 2, (st::topBarHeight - st::topBarBackward.height()) / 2, width()); - } else { - p.setOpacity(st::topBarForwardAlpha + (1 - st::topBarForwardAlpha) * over); - st::topBarForward.paint(p, width() - (st::topBarArrowPadding.left() + st::topBarForward.width()) / 2, (st::topBarHeight - st::topBarForward.height()) / 2, width()); } } @@ -6318,7 +6311,7 @@ void HistoryWidget::onMembersDropdownShow() { _membersDropdown->setMaxHeight(countMembersDropdownHeightMax()); _membersDropdown->moveToLeft(0, 0); - connect(_membersDropdown, SIGNAL(beforeHidden()), this, SLOT(onMembersDropdownHidden())); + _membersDropdown->setHiddenCallback([this] { _membersDropdown.destroyDelayed(); }); } _membersDropdown->otherEnter(); } @@ -6327,10 +6320,6 @@ void HistoryWidget::onModerateKeyActivate(int index, bool *outHandled) { *outHandled = _keyboard.isHidden() ? false : _keyboard.moderateKeyActivate(index); } -void HistoryWidget::onMembersDropdownHidden() { - _membersDropdown.destroyDelayed(); -} - void HistoryWidget::topBarClick() { if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) { App::main()->showBackFromStack(); diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 2ba364b927..45536b0360 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -855,7 +855,6 @@ private slots: void onHashtagOrBotCommandInsert(QString str, FieldAutocomplete::ChooseMethod method); void onMentionInsert(UserData *user); void onInlineBotCancel(); - void onMembersDropdownHidden(); void onMembersDropdownShow(); void onModerateKeyActivate(int index, bool *outHandled); diff --git a/Telegram/SourceFiles/intro/intro.style b/Telegram/SourceFiles/intro/intro.style index 1a7d836f06..3117d19306 100644 --- a/Telegram/SourceFiles/intro/intro.style +++ b/Telegram/SourceFiles/intro/intro.style @@ -44,12 +44,12 @@ introCountry: countryInput { } introBtnTop: 288px; -introSkip: 45px; +introSkip: 25px; introFinishSkip: 15px; introPhotoSize: 98px; introHeaderFont: font(24px); introHeaderSkip: 14px; -introIconSkip: 54px; +introIconSkip: 50px; introFont: font(16px); introLink: linkButton(btnDefLink) { font: introFont; @@ -61,7 +61,7 @@ introLabel: flatLabel(labelDefFlat) { } introStepSize: size(400px, 200px); -introSize: size(400px, 400px); +introSize: size(400px, 460px); introSlideShift: 500px; // intro hiding animation introSlideDuration: 200; introSlideDelta: 0; // between hide start and show start diff --git a/Telegram/SourceFiles/intro/introwidget.cpp b/Telegram/SourceFiles/intro/introwidget.cpp index 58c63c048f..d29791b216 100644 --- a/Telegram/SourceFiles/intro/introwidget.cpp +++ b/Telegram/SourceFiles/intro/introwidget.cpp @@ -35,20 +35,25 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "ui/buttons/icon_button.h" #include "ui/effects/widget_fade_wrap.h" #include "styles/style_intro.h" +#include "autoupdater.h" IntroWidget::IntroWidget(QWidget *parent) : TWidget(parent) , _a_stage(animation(this, &IntroWidget::step_stage)) , _a_show(animation(this, &IntroWidget::step_show)) -, _back(this, new Ui::IconButton(this, st::introBackButton), base::lambda_unique(), st::introSlideDuration) { +, _back(this, new Ui::IconButton(this, st::introBackButton), base::lambda_unique(), st::introSlideDuration) +, _settings(this, lang(lng_menu_settings), st::defaultBoxButton) { _back->entity()->setClickedCallback([this] { onBack(); }); _back->hideFast(); + _settings->setClickedCallback([] { App::wnd()->showSettings(); }); + _countryForReg = psCurrentCountry(); MTP::send(MTPhelp_GetNearestDc(), rpcDone(&IntroWidget::gotNearestDC)); _stepHistory.push_back(new IntroStart(this)); _back->raise(); + _settings->raise(); show(); setFocus(); @@ -58,10 +63,32 @@ IntroWidget::IntroWidget(QWidget *parent) : TWidget(parent) _back->moveToLeft(st::introBackPosition.x(), st::introBackPosition.y()); #ifndef TDESKTOP_DISABLE_AUTOUPDATE + Sandbox::connect(SIGNAL(updateLatest()), this, SLOT(onCheckUpdateStatus())); + Sandbox::connect(SIGNAL(updateFailed()), this, SLOT(onCheckUpdateStatus())); + Sandbox::connect(SIGNAL(updateReady()), this, SLOT(onCheckUpdateStatus())); Sandbox::startUpdateCheck(); + onCheckUpdateStatus(); #endif // !TDESKTOP_DISABLE_AUTOUPDATE } +#ifndef TDESKTOP_DISABLE_AUTOUPDATE +void IntroWidget::onCheckUpdateStatus() { + if (Sandbox::updatingState() == Application::UpdatingReady) { + if (_update) return; + _update.create(this, lang(lng_menu_update).toUpper(), st::defaultBoxButton); + _update->show(); + _update->setClickedCallback([] { + checkReadyUpdate(); + App::restart(); + }); + } else { + if (!_update) return; + _update.destroy(); + } + updateControlsGeometry(); +} +#endif // TDESKTOP_DISABLE_AUTOUPDATE + void IntroWidget::langChangeTo(int32 langId) { _langChangeTo = langId; } @@ -136,6 +163,10 @@ void IntroWidget::historyMove(MoveType type) { void IntroWidget::pushStep(IntroStep *step, MoveType type) { _stepHistory.push_back(step); _back->raise(); + _settings->raise(); + if (_update) { + _update->raise(); + } _stepHistory.back()->hide(); historyMove(type); @@ -335,6 +366,14 @@ void IntroWidget::resizeEvent(QResizeEvent *e) { for (auto step : _stepHistory) { step->setGeometry(r); } + updateControlsGeometry(); +} + +void IntroWidget::updateControlsGeometry() { + _settings->moveToLeft(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _settings->height()); + if (_update) { + _update->moveToLeft(st::boxButtonPadding.right() + _settings->width() + st::boxButtonPadding.left(), _settings->y()); + } } void IntroWidget::finish(const MTPUser &user, const QImage &photo) { diff --git a/Telegram/SourceFiles/intro/introwidget.h b/Telegram/SourceFiles/intro/introwidget.h index 9837539f4c..24b6bd4524 100644 --- a/Telegram/SourceFiles/intro/introwidget.h +++ b/Telegram/SourceFiles/intro/introwidget.h @@ -35,10 +35,6 @@ class IntroWidget : public TWidget, public RPCSender { public: IntroWidget(QWidget *window); - void paintEvent(QPaintEvent *e) override; - void resizeEvent(QResizeEvent *e) override; - void keyPressEvent(QKeyEvent *e) override; - void animShow(const QPixmap &bgAnimCache, bool back = false); void step_show(float64 ms, bool timer); void stop_show(); @@ -87,7 +83,12 @@ public: pushStep(step, MoveReplace); } - ~IntroWidget() override; + ~IntroWidget(); + +protected: + void paintEvent(QPaintEvent *e) override; + void resizeEvent(QResizeEvent *e) override; + void keyPressEvent(QKeyEvent *e) override; public slots: void onStepSubmit(); @@ -97,7 +98,13 @@ public slots: signals: void countryChanged(); +#ifndef TDESKTOP_DISABLE_AUTOUPDATE +private slots: + void onCheckUpdateStatus(); +#endif // TDESKTOP_DISABLE_AUTOUPDATE + private: + void updateControlsGeometry(); QPixmap grabStep(int skip = 0); int _langChangeTo = 0; @@ -145,6 +152,8 @@ private: QString _firstname, _lastname; ChildWidget> _back; + ChildWidget _settings; + ChildWidget _update = { nullptr }; float64 _backFrom = 0.; float64 _backTo = 0.; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index db1c94f6fc..a2bf332d29 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -83,7 +83,7 @@ MainWidget::MainWidget(QWidget *parent) : TWidget(parent) updateScrollColors(); connect(_dialogs, SIGNAL(cancelled()), this, SLOT(dialogsCancelled())); - connect(this, SIGNAL(dialogsUpdated()), this, SLOT(onListScroll())); + connect(this, SIGNAL(dialogsUpdated()), _dialogs, SLOT(onListScroll())); connect(_history, SIGNAL(cancelled()), _dialogs, SLOT(activate())); connect(this, SIGNAL(peerPhotoChanged(PeerData*)), this, SIGNAL(dialogsUpdated())); connect(&noUpdatesTimer, SIGNAL(timeout()), this, SLOT(mtpPing())); @@ -1993,6 +1993,94 @@ void MainWidget::scheduleViewIncrement(HistoryItem *item) { j.value().insert(item->id, true); } +void MainWidget::fillPeerMenu(PeerData *peer, base::lambda_unique handler)> callback) { + callback(lang((peer->isChat() || peer->isMegagroup()) ? lng_context_view_group : (peer->isUser() ? lng_context_view_profile : lng_context_view_channel)), [peer] { + Ui::showPeerProfile(peer); + }); + auto muteSubscription = MakeShared(); + auto muteAction = callback(lang(peer->isMuted() ? lng_enable_notifications_from_tray : lng_disable_notifications_from_tray), [peer, muteSubscription] { + App::main()->updateNotifySetting(peer, peer->isMuted() ? NotifySettingSetNotify : NotifySettingSetMuted); + }); + auto muteChangedHandler = Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::NotificationsEnabled, [muteAction, peer](const Notify::PeerUpdate &update) { + if (update.peer != peer) return; + muteAction->setText(lang(peer->isMuted() ? lng_enable_notifications_from_tray : lng_disable_notifications_from_tray)); + }); + *muteSubscription = Notify::PeerUpdated().add_subscription(std_::move(muteChangedHandler)); + + callback(lang(lng_profile_search_messages), [peer] { + App::main()->searchInPeer(peer); + }); + + auto clearHistoryHandler = [peer] { + auto box = new ConfirmBox(peer->isUser() ? lng_sure_delete_history(lt_contact, peer->name) : lng_sure_delete_group_history(lt_group, peer->name), lang(lng_box_delete), st::attentionBoxButton); + box->setConfirmedCallback([peer] { + if (!App::main()) return; + + Ui::hideLayer(); + App::main()->clearHistory(peer); + }); + Ui::showLayer(box); + }; + auto deleteAndLeaveHandler = [peer] { + auto warningText = peer->isUser() ? lng_sure_delete_history(lt_contact, peer->name) : + peer->isChat() ? lng_sure_delete_and_exit(lt_group, peer->name) : + lang(peer->isMegagroup() ? lng_sure_leave_group : lng_sure_leave_channel); + auto confirmText = lang(peer->isUser() ? lng_box_delete : lng_box_leave); + auto &confirmStyle = peer->isChannel() ? st::defaultBoxButton : st::attentionBoxButton; + auto box = new ConfirmBox(warningText, confirmText, confirmStyle); + box->setConfirmedCallback([peer] { + if (!App::main()) return; + + Ui::hideLayer(); + Ui::showChatsList(); + if (peer->isUser()) { + App::main()->deleteConversation(peer); + } else if (peer->isChat()) { + MTP::send(MTPmessages_DeleteChatUser(peer->asChat()->inputChat, App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, peer), App::main()->rpcFail(&MainWidget::leaveChatFailed, peer)); + } else if (peer->isChannel()) { + if (peer->migrateFrom()) { + App::main()->deleteConversation(peer->migrateFrom()); + } + MTP::send(MTPchannels_LeaveChannel(peer->asChannel()->inputChannel), App::main()->rpcDone(&MainWidget::sentUpdatesReceived)); + } + }); + Ui::showLayer(box); + }; + if (auto user = peer->asUser()) { + callback(lang(lng_profile_clear_history), std_::move(clearHistoryHandler)); + callback(lang(lng_profile_delete_conversation), std_::move(deleteAndLeaveHandler)); + if (user->access != UserNoAccess && user != App::self()) { + auto blockSubscription = MakeShared(); + auto blockAction = callback(lang(user->isBlocked() ? (user->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (user->botInfo ? lng_profile_block_bot : lng_profile_block_user)), [user, blockSubscription] { + auto willBeBlocked = !user->isBlocked(); + auto handler = ::rpcDone([user, willBeBlocked](const MTPBool &result) { + user->setBlockStatus(willBeBlocked ? UserData::BlockStatus::Blocked : UserData::BlockStatus::NotBlocked); + emit App::main()->peerUpdated(user); + }); + if (willBeBlocked) { + MTP::send(MTPcontacts_Block(user->inputUser), std_::move(handler)); + } else { + MTP::send(MTPcontacts_Unblock(user->inputUser), std_::move(handler)); + } + }); + auto blockChangedHandler = Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::UserIsBlocked, [blockAction, peer](const Notify::PeerUpdate &update) { + if (update.peer != peer) return; + blockAction->setText(lang(peer->asUser()->isBlocked() ? (peer->asUser()->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (peer->asUser()->botInfo ? lng_profile_block_bot : lng_profile_block_user))); + }); + *blockSubscription = Notify::PeerUpdated().add_subscription(std_::move(blockChangedHandler)); + + if (user->blockStatus() == UserData::BlockStatus::Unknown) { + App::api()->requestFullPeer(user); + } + } + } else if (peer->isChat()) { + callback(lang(lng_profile_clear_history), std_::move(clearHistoryHandler)); + callback(lang(lng_profile_clear_and_exit), std_::move(deleteAndLeaveHandler)); + } else if (peer->isChannel() && peer->asChannel()->amIn() && !peer->asChannel()->amCreator()) { + callback(lang(peer->isMegagroup() ? lng_profile_leave_group : lng_profile_leave_channel), std_::move(deleteAndLeaveHandler)); + } +} + void MainWidget::onViewsIncrement() { if (!App::main() || !MTP::authedId()) return; @@ -3817,7 +3905,6 @@ void MainWidget::applyNotifySetting(const MTPNotifyPeer &peer, const MTPPeerNoti if (_history->peer() == updatePeer) { _history->updateNotifySettings(); } - _dialogs->updateNotifySettings(updatePeer); if (changed) { Notify::peerUpdatedDelayed(updatePeer, Notify::PeerUpdate::Flag::NotificationsEnabled); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 8840579ef6..5da1b0b7e2 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -364,6 +364,8 @@ public: void scheduleViewIncrement(HistoryItem *item); + void fillPeerMenu(PeerData *peer, base::lambda_unique handler)> callback); + void gotRangeDifference(ChannelData *channel, const MTPupdates_ChannelDifference &diff); void onSelfParticipantUpdated(ChannelData *channel); diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index b43afe02f0..d287884259 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -134,7 +134,7 @@ MediaView::MediaView() : TWidget(App::wnd()) connect(&_docSaveAs, SIGNAL(clicked()), this, SLOT(onSaveAs())); connect(&_docCancel, SIGNAL(clicked()), this, SLOT(onSaveCancel())); - connect(_dropdown, SIGNAL(beforeHidden()), this, SLOT(onDropdownHidden())); + _dropdown->setHiddenCallback([this] { dropdownHidden(); }); } void MediaView::moveToScreen() { @@ -142,7 +142,7 @@ void MediaView::moveToScreen() { windowHandle()->setScreen(App::wnd()->windowHandle()->screen()); } - QPoint wndCenter(App::wnd()->x() + App::wnd()->width() / 2, App::wnd()->y() + App::wnd()->height() / 2); + auto wndCenter = App::wnd()->geometry().center(); QRect avail = Sandbox::screenGeometry(wndCenter); if (avail != geometry()) { setGeometry(avail); @@ -679,7 +679,7 @@ void MediaView::onHideControls(bool force) { if (!_a_state.animating()) _a_state.start(); } -void MediaView::onDropdownHidden() { +void MediaView::dropdownHidden() { setFocus(); _ignoringDropdown = true; _lastMouseMovePos = mapFromGlobal(QCursor::pos()); diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index ed7872c637..b54900c1e2 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -80,9 +80,23 @@ public: void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override; void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override; +protected: + void paintEvent(QPaintEvent *e) override; + + void keyPressEvent(QKeyEvent *e) override; + void wheelEvent(QWheelEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseDoubleClickEvent(QMouseEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void contextMenuEvent(QContextMenuEvent *e) override; + void touchEvent(QTouchEvent *e); + + bool event(QEvent *e) override; + bool eventFilter(QObject *obj, QEvent *e) override; + private slots: void onHideControls(bool force = false); - void onDropdownHidden(); void onScreenResized(int screen); @@ -105,22 +119,6 @@ private slots: void updateImage(); -protected: - void paintEvent(QPaintEvent *e) override; - - void keyPressEvent(QKeyEvent *e) override; - void wheelEvent(QWheelEvent *e) override; - void mousePressEvent(QMouseEvent *e) override; - void mouseDoubleClickEvent(QMouseEvent *e) override; - void mouseMoveEvent(QMouseEvent *e) override; - void mouseReleaseEvent(QMouseEvent *e) override; - void contextMenuEvent(QContextMenuEvent *e) override; - void touchEvent(QTouchEvent *e); - - bool event(QEvent *e) override; - bool eventFilter(QObject *obj, QEvent *e) override; - -private slots: void onVideoPauseResume(); void onVideoSeekProgress(int64 positionMs); void onVideoSeekFinished(int64 positionMs); @@ -129,6 +127,7 @@ private slots: void onVideoPlayProgress(const AudioMsgId &audioId); private: + void dropdownHidden(); void updateDocSize(); void updateControls(); void updateActions(); diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index 0b648782e3..ffa8c8da3d 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -1879,7 +1879,6 @@ OverviewWidget::OverviewWidget(QWidget *parent, PeerData *peer, MediaOverviewTyp , _inner(this, &_scroll, peer, type) , _a_show(animation(this, &OverviewWidget::step_show)) , _topShadow(this, st::shadowColor) { - _scroll.setFocusPolicy(Qt::NoFocus); _scroll.setWidget(&_inner); _scroll.move(0, 0); _inner.move(0, 0); diff --git a/Telegram/SourceFiles/settings/settings_advanced_widget.cpp b/Telegram/SourceFiles/settings/settings_advanced_widget.cpp index 86437d3896..9502a6b140 100644 --- a/Telegram/SourceFiles/settings/settings_advanced_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_advanced_widget.cpp @@ -63,7 +63,8 @@ void AdvancedWidget::createControls() { if (self()) { addChildRow(_askQuestion, marginSmall, lang(lng_settings_ask_question), SLOT(onAskQuestion())); } - addChildRow(_telegramFAQ, marginLarge, lang(lng_settings_faq), SLOT(onTelegramFAQ())); + addChildRow(_telegramFAQ, marginSmall, lang(lng_settings_faq), SLOT(onTelegramFAQ())); + addChildRow(_about, marginLarge, lang(lng_menu_about), SLOT(onAbout())); if (self()) { style::margins marginLogout(0, 0, 0, 2 * st::settingsLargeSkip); addChildRow(_logOut, marginLogout, lang(lng_settings_logout), SLOT(onLogOut())); @@ -123,6 +124,10 @@ void AdvancedWidget::onTelegramFAQ() { QDesktopServices::openUrl(telegramFaqLink()); } +void AdvancedWidget::onAbout() { + Ui::showLayer(new AboutBox()); +} + void AdvancedWidget::onLogOut() { App::wnd()->onLogout(); } diff --git a/Telegram/SourceFiles/settings/settings_advanced_widget.h b/Telegram/SourceFiles/settings/settings_advanced_widget.h index 81e8c5e38b..a6c8b75a2f 100644 --- a/Telegram/SourceFiles/settings/settings_advanced_widget.h +++ b/Telegram/SourceFiles/settings/settings_advanced_widget.h @@ -39,6 +39,7 @@ private slots: void onAskQuestion(); void onAskQuestionSure(); void onTelegramFAQ(); + void onAbout(); void onLogOut(); private: @@ -54,6 +55,7 @@ private: #endif // !TDESKTOP_DISABLE_NETWORK_PROXY ChildWidget _askQuestion = { nullptr }; ChildWidget _telegramFAQ = { nullptr }; + ChildWidget _about = { nullptr }; ChildWidget _logOut = { nullptr }; mtpRequestId _supportGetRequest = 0; diff --git a/Telegram/SourceFiles/settings/settings_inner_widget.h b/Telegram/SourceFiles/settings/settings_inner_widget.h index 0a5fcf5576..7091124e28 100644 --- a/Telegram/SourceFiles/settings/settings_inner_widget.h +++ b/Telegram/SourceFiles/settings/settings_inner_widget.h @@ -42,9 +42,6 @@ public: void showFinished(); -signals: - void heightUpdated(); - private slots: void onBlockHeightUpdated(); diff --git a/Telegram/SourceFiles/settings/settings_widget.cpp b/Telegram/SourceFiles/settings/settings_widget.cpp index 0bad833c0b..c3ae485e82 100644 --- a/Telegram/SourceFiles/settings/settings_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_widget.cpp @@ -142,7 +142,8 @@ Widget::Widget(QWidget *parent) : LayerWidget(parent) } void Widget::parentResized() { - int windowWidth = App::wnd()->width(); + auto parentSize = parentWidget()->size(); + int windowWidth = parentSize.width(); int newWidth = st::settingsMaxWidth; int newContentLeft = st::settingsMaxPadding; if (windowWidth <= st::settingsMaxWidth) { @@ -177,8 +178,9 @@ void Widget::onInnerHeightUpdated() { void Widget::resizeUsingInnerHeight(int newWidth, int newContentLeft) { if (!App::wnd()) return; - int windowWidth = App::wnd()->width(); - int windowHeight = App::wnd()->height(); + auto parentSize = parentWidget()->size(); + int windowWidth = parentSize.width(); + int windowHeight = parentSize.height(); int maxHeight = st::settingsFixedBarHeight + _inner->height(); int newHeight = maxHeight; if (newHeight > windowHeight || newWidth >= windowWidth) { @@ -189,7 +191,7 @@ void Widget::resizeUsingInnerHeight(int newWidth, int newContentLeft) { _contentLeft = newContentLeft; } - setGeometry((App::wnd()->width() - newWidth) / 2, (App::wnd()->height() - newHeight) / 2, newWidth, newHeight); + setGeometry((windowWidth - newWidth) / 2, (windowHeight - newHeight) / 2, newWidth, newHeight); update(); } diff --git a/Telegram/SourceFiles/stickers/emoji_pan.cpp b/Telegram/SourceFiles/stickers/emoji_pan.cpp index abe0d71435..3576aeedb3 100644 --- a/Telegram/SourceFiles/stickers/emoji_pan.cpp +++ b/Telegram/SourceFiles/stickers/emoji_pan.cpp @@ -49,7 +49,6 @@ EmojiColorPicker::EmojiColorPicker() : TWidget() memset(_hovers, 0, sizeof(_hovers)); setMouseTracking(true); - setFocusPolicy(Qt::NoFocus); int32 w = st::emojiPanSize.width() * (EmojiColorsCount + 1) + 4 * st::emojiColorsPadding + st::emojiColorsSep + st::defaultDropdownShadow.width() * 2; int32 h = 2 * st::emojiColorsPadding + st::emojiPanSize.height() + st::defaultDropdownShadow.height() * 2; @@ -299,7 +298,6 @@ EmojiPanInner::EmojiPanInner() : TWidget() resize(st::emojiPanWidth - st::emojiScroll.width, countHeight()); setMouseTracking(true); - setFocusPolicy(Qt::NoFocus); setAttribute(Qt::WA_OpaquePaintEvent); _picker.hide(); @@ -804,7 +802,6 @@ StickerPanInner::StickerPanInner() : TWidget() setMaxHeight(st::emojiPanMaxHeight - st::emojiCategory.height); setMouseTracking(true); - setFocusPolicy(Qt::NoFocus); setAttribute(Qt::WA_OpaquePaintEvent); connect(&_settings, SIGNAL(clicked()), this, SLOT(onSettings())); @@ -2431,7 +2428,6 @@ EmojiPanel::EmojiPanel(QWidget *parent, const QString &text, uint64 setId, bool , _delete(special ? 0 : new Ui::IconButton(this, st::hashtagClose)) { // Stickers::NoneSetId if in emoji resize(st::emojiPanWidth, st::emojiPanHeader); setMouseTracking(true); - setFocusPolicy(Qt::NoFocus); setText(text); if (_delete) { _delete->hide(); @@ -2569,12 +2565,6 @@ EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent) , s_scroll(this, st::emojiScroll) , s_inner() , s_switch(&s_scroll, false) { - setFocusPolicy(Qt::NoFocus); - e_scroll.setFocusPolicy(Qt::NoFocus); - e_scroll.viewport()->setFocusPolicy(Qt::NoFocus); - s_scroll.setFocusPolicy(Qt::NoFocus); - s_scroll.viewport()->setFocusPolicy(Qt::NoFocus); - _width = st::defaultDropdownPadding.left() + st::emojiPanWidth + st::defaultDropdownPadding.right(); _height = st::defaultDropdownPadding.top() + _contentHeight + st::defaultDropdownPadding.bottom(); _bottom = 0; diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 432f67c497..4cfaa501c6 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -266,6 +266,9 @@ public: } bool isVerified() const; bool isMegagroup() const; + bool isMuted() const { + return (notify != EmptyNotifySettings) && (notify != UnknownNotifySettings) && (notify->mute >= unixtime()); + } bool canWrite() const; UserData *asUser(); const UserData *asUser() const; diff --git a/Telegram/SourceFiles/ui/flatbutton.cpp b/Telegram/SourceFiles/ui/flatbutton.cpp index 0b83cb6495..108b77a0ba 100644 --- a/Telegram/SourceFiles/ui/flatbutton.cpp +++ b/Telegram/SourceFiles/ui/flatbutton.cpp @@ -107,17 +107,7 @@ void FlatButton::paintEvent(QPaintEvent *e) { auto &bg = (_state & StateOver) ? ((_state & StateDown) ? _st.downBgColor : _st.overBgColor) : _st.bgColor; auto &fg = (_state & StateOver) ? ((_state & StateDown) ? _st.downColor : _st.overColor) : _st.color; p.setOpacity(_opacity); - if (_st.radius > 0) { - p.setRenderHint(QPainter::HighQualityAntialiasing); - p.setPen(Qt::NoPen); - if (animating) { - p.setBrush(a_bg.current()); - } else { - p.setBrush(bg); - } - p.drawRoundedRect(r, _st.radius, _st.radius); - p.setRenderHint(QPainter::HighQualityAntialiasing, false); - } else if (animating) { + if (animating) { p.fillRect(r, a_bg.current()); } else { p.fillRect(r, bg); diff --git a/Telegram/SourceFiles/ui/scrollarea.cpp b/Telegram/SourceFiles/ui/scrollarea.cpp index 7aac81107c..5dd8e58a7d 100644 --- a/Telegram/SourceFiles/ui/scrollarea.cpp +++ b/Telegram/SourceFiles/ui/scrollarea.cpp @@ -328,6 +328,7 @@ ScrollArea::ScrollArea(QWidget *parent, const style::flatScroll &st, bool handle , _bottomShadow(this, &_st) , _touchEnabled(handleTouch) { setLayoutDirection(cLangDir()); + setFocusPolicy(Qt::NoFocus); connect(_verticalBar, SIGNAL(topShadowVisibility(bool)), _topShadow, SLOT(changeVisibility(bool))); connect(_verticalBar, SIGNAL(bottomShadowVisibility(bool)), _bottomShadow, SLOT(changeVisibility(bool))); diff --git a/Telegram/SourceFiles/ui/scrollarea.h b/Telegram/SourceFiles/ui/scrollarea.h index b09348c96f..4f4a7e37f7 100644 --- a/Telegram/SourceFiles/ui/scrollarea.h +++ b/Telegram/SourceFiles/ui/scrollarea.h @@ -106,11 +106,9 @@ class SplittedWidget : public TWidget { Q_OBJECT public: - - SplittedWidget(QWidget *parent) : TWidget(parent), _otherWidth(0) { + SplittedWidget(QWidget *parent) : TWidget(parent) { setAttribute(Qt::WA_OpaquePaintEvent); } - void paintEvent(QPaintEvent *e); // paintEvent done through paintRegion void setHeight(int32 newHeight) { resize(width(), newHeight); emit resizeOther(); @@ -122,18 +120,17 @@ public: void update(const QRegion&); public slots: - void update() { update(0, 0, fullWidth(), height()); } signals: - void resizeOther(); void updateOther(const QRect&); void updateOther(const QRegion&); protected: + void paintEvent(QPaintEvent *e) override; // paintEvent done through paintRegion int32 otherWidth() const { return _otherWidth; @@ -144,8 +141,7 @@ protected: virtual void paintRegion(Painter &p, const QRegion ®ion, bool paintingOther) = 0; private: - - int32 _otherWidth; + int32 _otherWidth = 0; void setOtherWidth(int32 otherWidth) { _otherWidth = otherWidth; } @@ -163,7 +159,6 @@ class ScrollArea : public QScrollArea { T_WIDGET public: - ScrollArea(QWidget *parent, const style::flatScroll &st = st::scrollDef, bool handleTouch = true); int scrollWidth() const; @@ -190,7 +185,6 @@ public: ~ScrollArea(); protected: - bool eventFilter(QObject *obj, QEvent *e) override; void resizeEvent(QResizeEvent *e) override; @@ -201,7 +195,6 @@ protected: void leaveEventHook(QEvent *e); public slots: - void scrollToY(int toTop, int toBottom = -1); void disableScroll(bool dis); void onScrolled(); @@ -215,18 +208,15 @@ public slots: void onVerticalScroll(); signals: - void scrolled(); void scrollStarted(); void scrollFinished(); void geometryChanged(); protected: - void scrollContentsBy(int dx, int dy) override; private: - bool touchScroll(const QPoint &delta); void touchScrollUpdated(const QPoint &screenPos); @@ -271,5 +261,8 @@ class SplittedWidgetOther : public TWidget { public: SplittedWidgetOther(ScrollArea *parent) : TWidget(parent) { } - void paintEvent(QPaintEvent *e); + +protected: + void paintEvent(QPaintEvent *e) override; + }; diff --git a/Telegram/SourceFiles/ui/widgets/dropdown_menu.cpp b/Telegram/SourceFiles/ui/widgets/dropdown_menu.cpp index 938a86bf82..b3ba1c5d12 100644 --- a/Telegram/SourceFiles/ui/widgets/dropdown_menu.cpp +++ b/Telegram/SourceFiles/ui/widgets/dropdown_menu.cpp @@ -44,7 +44,7 @@ DropdownMenu::DropdownMenu(QWidget *parent, const style::DropdownMenu &st) : Inn //} void DropdownMenu::init() { - connect(this, SIGNAL(beforeHidden()), this, SLOT(onHidden())); + InnerDropdown::setHiddenCallback([this] { hideFinish(); }); setOwnedWidget(_menu); @@ -216,6 +216,9 @@ void DropdownMenu::childHiding(DropdownMenu *child) { void DropdownMenu::hideFinish() { _menu->clearSelection(); + if (_hiddenCallback) { + _hiddenCallback(); + } } // Not ready with submenus yet. diff --git a/Telegram/SourceFiles/ui/widgets/dropdown_menu.h b/Telegram/SourceFiles/ui/widgets/dropdown_menu.h index 6d63733ab3..80b106eec4 100644 --- a/Telegram/SourceFiles/ui/widgets/dropdown_menu.h +++ b/Telegram/SourceFiles/ui/widgets/dropdown_menu.h @@ -35,6 +35,10 @@ public: QAction *addSeparator(); void clearActions(); + void setHiddenCallback(base::lambda_unique callback) { + _hiddenCallback = std_::move(callback); + } + using Actions = Ui::Menu::Actions; Actions &actions(); @@ -91,6 +95,7 @@ private: void showMenu(const QPoint &p, DropdownMenu *parent, TriggeredSource source); const style::DropdownMenu &_st; + base::lambda_unique _hiddenCallback; ChildWidget _menu; diff --git a/Telegram/SourceFiles/ui/widgets/inner_dropdown.cpp b/Telegram/SourceFiles/ui/widgets/inner_dropdown.cpp index d7f5cd622a..0805d1a179 100644 --- a/Telegram/SourceFiles/ui/widgets/inner_dropdown.cpp +++ b/Telegram/SourceFiles/ui/widgets/inner_dropdown.cpp @@ -188,7 +188,9 @@ void InnerDropdown::hideFinished() { _cache = QPixmap(); _ignoreShowEvents = false; if (!isHidden()) { - emit beforeHidden(); + if (_hiddenCallback) { + _hiddenCallback(); + } hide(); } } diff --git a/Telegram/SourceFiles/ui/widgets/inner_dropdown.h b/Telegram/SourceFiles/ui/widgets/inner_dropdown.h index 9b251042a1..b955f43f52 100644 --- a/Telegram/SourceFiles/ui/widgets/inner_dropdown.h +++ b/Telegram/SourceFiles/ui/widgets/inner_dropdown.h @@ -49,6 +49,10 @@ public: void showFast(); void hideFast(); + void setHiddenCallback(base::lambda_unique callback) { + _hiddenCallback = std_::move(callback); + } + bool isHiding() const { return _hiding && _a_appearance.animating(); } @@ -60,9 +64,6 @@ public: }; void hideAnimated(HideOption option = HideOption::Default); -signals: - void beforeHidden(); - protected: void resizeEvent(QResizeEvent *e) override; void paintEvent(QPaintEvent *e) override; @@ -102,6 +103,7 @@ private: QTimer _hideTimer; bool _ignoreShowEvents = false; + base::lambda_unique _hiddenCallback; RectShadow _shadow; ChildWidget _scroll; diff --git a/Telegram/SourceFiles/window/main_window.h b/Telegram/SourceFiles/window/main_window.h index aeffea7039..319b521632 100644 --- a/Telegram/SourceFiles/window/main_window.h +++ b/Telegram/SourceFiles/window/main_window.h @@ -44,12 +44,13 @@ public: virtual ~MainWindow(); + QWidget *bodyWidget() { + return _body; + } + protected: void resizeEvent(QResizeEvent *e) override; - QWidget *bodyWidget() { // temp - return _body; - } void savePosition(Qt::WindowState state = Qt::WindowActive); virtual void initHook() { diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index 16348efff7..c12e34f7db 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -638,7 +638,7 @@ void Notification::updateNotifyDisplay() { QRect rectForName(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height); if (!options.hideNameAndPhoto) { - if (auto chatTypeIcon = Dialogs::Layout::ChatTypeIcon(_history->peer, false)) { + if (auto chatTypeIcon = Dialogs::Layout::ChatTypeIcon(_history->peer, false, false)) { chatTypeIcon->paint(p, rectForName.topLeft(), w); rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip); } @@ -649,8 +649,8 @@ void Notification::updateNotifyDisplay() { Text itemTextCache(itemWidth); QRect r(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dialogsTextFont->height); if (_item) { - bool active = false; - _item->drawInDialog(p, r, active, textCachedFor, itemTextCache); + auto active = false, selected = false; + _item->drawInDialog(p, r, active, selected, textCachedFor, itemTextCache); } else if (_forwardedCount > 1) { p.setFont(st::dialogsTextFont); if (_author) { diff --git a/Telegram/SourceFiles/window/top_bar_widget.cpp b/Telegram/SourceFiles/window/top_bar_widget.cpp index 28900ff048..6ba1389814 100644 --- a/Telegram/SourceFiles/window/top_bar_widget.cpp +++ b/Telegram/SourceFiles/window/top_bar_widget.cpp @@ -25,11 +25,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "boxes/addcontactbox.h" #include "boxes/confirmbox.h" #include "mainwidget.h" +#include "mainwindow.h" #include "shortcuts.h" #include "lang.h" #include "ui/buttons/peer_avatar_button.h" #include "ui/buttons/round_button.h" #include "ui/buttons/icon_button.h" +#include "ui/widgets/dropdown_menu.h" #include "ui/flatbutton.h" namespace Window { @@ -41,16 +43,18 @@ TopBarWidget::TopBarWidget(MainWidget *w) : TWidget(w) , _delete(this, lang(lng_selected_delete), st::defaultActiveButton) , _info(this, nullptr, st::infoButton) , _mediaType(this, lang(lng_media_type), st::topBarButton) -, _search(this, st::topBarSearch) { +, _search(this, st::topBarSearch) +, _menuToggle(this, st::topBarMenuToggle) { _clearSelection->setTextTransform(Ui::RoundButton::TextTransform::ToUpper); _forward->setTextTransform(Ui::RoundButton::TextTransform::ToUpper); _delete->setTextTransform(Ui::RoundButton::TextTransform::ToUpper); - 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(_search, SIGNAL(clicked()), this, SLOT(onSearch())); + _forward->setClickedCallback([this] { onForwardSelection(); }); + _delete->setClickedCallback([this] { onDeleteSelection(); }); + _clearSelection->setClickedCallback([this] { onClearSelection(); }); + _info->setClickedCallback([this] { onInfoClicked(); }); + _search->setClickedCallback([this] { onSearch(); }); + _menuToggle->setClickedCallback([this] { showMenu(); }); subscribe(Adaptive::Changed(), [this]() { updateAdaptiveLayout(); }); @@ -83,6 +87,22 @@ void TopBarWidget::onSearch() { } } +void TopBarWidget::showMenu() { + if (auto main = App::main()) { + if (auto peer = main->peer()) { + _menu.create(App::main()); + App::main()->fillPeerMenu(peer, [this](const QString &text, base::lambda_unique callback) { + return _menu->addAction(text, std_::move(callback)); + }); + _menu->setHiddenCallback([this] { + _menu.destroyDelayed(); + }); + _menu->moveToRight(0, 0); + _menu->showAnimated(); + } + } +} + void TopBarWidget::enterEvent(QEvent *e) { a_over.start(1); _a_appearance.start(); @@ -163,13 +183,11 @@ void TopBarWidget::mousePressEvent(QMouseEvent *e) { } void TopBarWidget::resizeEvent(QResizeEvent *e) { - int r = width(); - int buttonsLeft = st::topBarActionSkip + (Adaptive::OneColumn() ? 0 : st::lineWidth); int buttonsWidth = _forward->contentWidth() + _delete->contentWidth() + _clearSelection->width(); buttonsWidth += buttonsLeft + st::topBarActionSkip * 3; - int widthLeft = qMin(r - buttonsWidth, -2 * st::defaultActiveButton.width); + int widthLeft = qMin(width() - buttonsWidth, -2 * st::defaultActiveButton.width); _forward->setFullWidth(-(widthLeft / 2)); _delete->setFullWidth(-(widthLeft / 2)); @@ -181,9 +199,10 @@ void TopBarWidget::resizeEvent(QResizeEvent *e) { _delete->moveToLeft(buttonsLeft, buttonsTop); _clearSelection->moveToRight(st::topBarActionSkip, buttonsTop); - if (!_info->isHidden()) _info->move(r -= _info->width(), 0); - if (!_mediaType->isHidden()) _mediaType->move(r -= _mediaType->width(), 0); - _search->move(width() - (_info->isHidden() ? st::topBarArrowPadding.left() : _info->width()) - _search->width(), 0); + _info->moveToRight(0, 0); + _menuToggle->moveToRight(0, 0); + _mediaType->moveToRight(0, 0); + _search->moveToRight(_info->isHidden() ? _menuToggle->width() : _info->width(), 0); } void TopBarWidget::startAnim() { @@ -193,6 +212,7 @@ void TopBarWidget::startAnim() { _forward->hide(); _mediaType->hide(); _search->hide(); + _menuToggle->hide(); if (_membersShowArea) { _membersShowArea->hide(); } @@ -235,13 +255,16 @@ void TopBarWidget::showAll() { if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) { _info->setPeer(h); _info->show(); + _menuToggle->hide(); } else { _info->hide(); + _menuToggle->show(); } _search->show(); } else { _search->hide(); _info->hide(); + _menuToggle->hide(); } if (_membersShowArea) { _membersShowArea->show(); diff --git a/Telegram/SourceFiles/window/top_bar_widget.h b/Telegram/SourceFiles/window/top_bar_widget.h index cd4c1711d9..9a133a9ec6 100644 --- a/Telegram/SourceFiles/window/top_bar_widget.h +++ b/Telegram/SourceFiles/window/top_bar_widget.h @@ -25,7 +25,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Ui { class PeerAvatarButton; class RoundButton; -class MaskButton; +class IconButton; +class DropdownMenu; } // namespace Ui namespace Window { @@ -58,17 +59,17 @@ public: protected: bool eventFilter(QObject *obj, QEvent *e) override; -public slots: +signals: + void clicked(); + +private: void onForwardSelection(); void onDeleteSelection(); void onClearSelection(); void onInfoClicked(); void onSearch(); + void showMenu(); -signals: - void clicked(); - -private: void updateAdaptiveLayout(); MainWidget *main(); @@ -87,7 +88,10 @@ private: ChildWidget _info; ChildWidget _mediaType; - ChildWidget _search; + ChildWidget _search; + ChildWidget _menuToggle; + ChildWidget _menu = { nullptr }; + ChildWidget _membersShowArea = { nullptr }; };