Update Telegram button added to DialogsWidget/Intro. Three dot menu.

This commit is contained in:
John Preston 2016-11-05 11:36:24 +03:00
parent e693a98bd4
commit d12177befd
50 changed files with 624 additions and 462 deletions

View File

@ -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;

View File

@ -58,8 +58,6 @@ flatButton {
overFont: font;
duration: int;
cursor: cursor;
radius: pixels;
}
flatInput {

View File

@ -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;

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

View File

@ -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";

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
});
}

View File

@ -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:

View File

@ -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::IndexedList>(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<void()> 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<UserData*, bool> 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<MTPDialog> &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);
}
}

View File

@ -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<UserData*, bool> 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<FlatInput> _filter;
ChildWidget<Ui::IconButton> _cancelSearch;
ChildWidget<Ui::IconButton> _lockUnlock;
ScrollArea _scroll;
DialogsInner _inner;
ChildWidget<ScrollArea> _scroll;
ChildWidget<DialogsInner> _inner;
ChildWidget<FlatButton> _updateTelegram = { nullptr };
Animation _a_show;
QPixmap _cacheUnder, _cacheOver;

View File

@ -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();
}

View File

@ -130,8 +130,6 @@ private:
anim::fvalue a_opacity;
Animation _a_appearance;
QTimer _hideTimer;
friend class internal::FieldAutocompleteInner;
};

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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();

View File

@ -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 &regular = 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 &regular = selected ? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected) : (outbg ? st::msgOutDateFg : st::msgInDateFg);

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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<void()>(), st::introSlideDuration) {
, _back(this, new Ui::IconButton(this, st::introBackButton), base::lambda_unique<void()>(), 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) {

View File

@ -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<Ui::WidgetFadeWrap<Ui::IconButton>> _back;
ChildWidget<BoxButton> _settings;
ChildWidget<BoxButton> _update = { nullptr };
float64 _backFrom = 0.;
float64 _backTo = 0.;

View File

@ -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<QAction*(const QString &text, base::lambda_unique<void()> 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<base::Subscription>();
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<base::Subscription>();
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);
}

View File

@ -364,6 +364,8 @@ public:
void scheduleViewIncrement(HistoryItem *item);
void fillPeerMenu(PeerData *peer, base::lambda_unique<QAction*(const QString &text, base::lambda_unique<void()> handler)> callback);
void gotRangeDifference(ChannelData *channel, const MTPupdates_ChannelDifference &diff);
void onSelfParticipantUpdated(ChannelData *channel);

View File

@ -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());

View File

@ -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();

View File

@ -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);

View File

@ -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();
}

View File

@ -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<LinkButton> _askQuestion = { nullptr };
ChildWidget<LinkButton> _telegramFAQ = { nullptr };
ChildWidget<LinkButton> _about = { nullptr };
ChildWidget<LinkButton> _logOut = { nullptr };
mtpRequestId _supportGetRequest = 0;

View File

@ -42,9 +42,6 @@ public:
void showFinished();
signals:
void heightUpdated();
private slots:
void onBlockHeightUpdated();

View File

@ -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();
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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)));

View File

@ -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 &region, 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;
};

View File

@ -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.

View File

@ -35,6 +35,10 @@ public:
QAction *addSeparator();
void clearActions();
void setHiddenCallback(base::lambda_unique<void()> 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<void()> _hiddenCallback;
ChildWidget<Ui::Menu> _menu;

View File

@ -188,7 +188,9 @@ void InnerDropdown::hideFinished() {
_cache = QPixmap();
_ignoreShowEvents = false;
if (!isHidden()) {
emit beforeHidden();
if (_hiddenCallback) {
_hiddenCallback();
}
hide();
}
}

View File

@ -49,6 +49,10 @@ public:
void showFast();
void hideFast();
void setHiddenCallback(base::lambda_unique<void()> 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<void()> _hiddenCallback;
RectShadow _shadow;
ChildWidget<ScrollArea> _scroll;

View File

@ -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() {

View File

@ -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) {

View File

@ -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<void()> 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();

View File

@ -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<Ui::PeerAvatarButton> _info;
ChildWidget<Ui::RoundButton> _mediaType;
ChildWidget<Ui::MaskButton> _search;
ChildWidget<Ui::IconButton> _search;
ChildWidget<Ui::IconButton> _menuToggle;
ChildWidget<Ui::DropdownMenu> _menu = { nullptr };
ChildWidget<TWidget> _membersShowArea = { nullptr };
};