Dialog styles moved from basic.style to dialogs.style.

Many minor design improvements in the new profiles.
New drafts design in the dialogs list: no icon, red badge.
Verified checkbox added to the new profile implementation.
Drafts saving to cloud is delayed for 1 second when switching chats.
Before quitting the app makes an attempt to save drafts (timeout 1.5s).
This commit is contained in:
John Preston 2016-06-07 22:59:39 +03:00
parent 6aca90c478
commit 1859b83e8d
56 changed files with 725 additions and 801 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 KiB

After

Width:  |  Height:  |  Size: 239 KiB

View File

@ -56,6 +56,7 @@ adaptiveNormalWidth: 640px;
adaptiveWideWidth: 1366px; adaptiveWideWidth: 1366px;
windowBg: #fff; // fallback for background: white windowBg: #fff; // fallback for background: white
windowActiveBg: #40ace3; // fallback for blue filled active areas
windowTextFg: #000; // fallback for text color: black windowTextFg: #000; // fallback for text color: black
windowSubTextFg: #8a8a8a; // fallback for subtext color: gray windowSubTextFg: #8a8a8a; // fallback for subtext color: gray
windowActiveTextFg: #1485c2; // fallback for active color: blue online windowActiveTextFg: #1485c2; // fallback for active color: blue online
@ -114,6 +115,7 @@ defaultBoxButton: BoxButton {
width: -24px; width: -24px;
height: 36px; height: 36px;
padding: margins(0px, 0px, 0px, 0px);
textTop: 8px; textTop: 8px;
@ -149,7 +151,7 @@ boxLabel: flatLabel(labelDefFlat) {
defaultLeftOutlineButton: OutlineButton { defaultLeftOutlineButton: OutlineButton {
outlineWidth: 3px; outlineWidth: 3px;
outlineFg: windowBg; outlineFg: windowBg;
outlineFgOver: #3fb0e4; outlineFgOver: windowActiveBg;
textBg: windowBg; textBg: windowBg;
textBgOver: #f2f7fa; textBgOver: #f2f7fa;
@ -230,9 +232,9 @@ defaultCheckbox: Checkbox {
textFg: black; textFg: black;
textBg: white; textBg: white;
checkFg: #d9d9d9; checkFg: #b3b3b3;
checkFgOver: #bfbfbf; checkFgOver: #b3b3b3;
checkFgActive: #4eb3ee; checkFgActive: #40ace3;
width: -46px; width: -46px;
height: 22px; height: 22px;
@ -240,7 +242,9 @@ defaultCheckbox: Checkbox {
textPosition: point(34px, 0px); textPosition: point(34px, 0px);
diameter: 22px; diameter: 22px;
thickness: 2px; thickness: 2px;
checkIcon: sprite(106px, 136px, 14px, 10px); checkIcon: icon {
{ "default_checkbox_check", #ffffff, point(4px, 7px) }
};
font: boxTextFont; font: boxTextFont;
duration: 120; duration: 120;
@ -249,7 +253,7 @@ defaultRadiobutton: Radiobutton {
textFg: black; textFg: black;
textBg: white; textBg: white;
checkFg: #d9d9d9; checkFg: #b3b3b3;
checkFgOver: #bfbfbf; checkFgOver: #bfbfbf;
checkFgActive: #4eb3ee; checkFgActive: #4eb3ee;
@ -908,46 +912,22 @@ btnLogout: flatButton(btnDefFlat, btnDefBig) {
overFont: font(18px); overFont: font(18px);
} }
//// dialogs searchFlatInput: flatInput(inpDefGray) {
dlgFilterPadding: 10px;
dlgPhotoSize: 46px;
dlgPaddingHor: 10px;
dlgPaddingVer: 8px;
dlgHeight: 62px;
dlgPhotoPadding: 12px;
dlgImportantHeight: 37px;
noContactsHeight: 100px;
noContactsFont: font(fsize);
noContactsColor: #777;
dlgSep: 8px;
dlgMinWidth: 260px;
dlgRichMinWidth: 150px;
dlgMaxWidth: 540px;
dlgFilter: flatInput(inpDefGray) {
font: font(fsize); font: font(fsize);
height: 34px;
bgColor: #f2f2f2; bgColor: #f2f2f2;
phColor: #949494; phColor: #949494;
phFocusColor: #a4a4a4; phFocusColor: #a4a4a4;
textMrg: margins(34px, 2px, 34px, 4px);
imgRect: sprite(227px, 21px, 24px, 24px); imgRect: sprite(227px, 21px, 24px, 24px);
imgPos: point(6px, 5px);
width: 240px;
borderWidth: 2px; borderWidth: 2px;
borderColor: #f2f2f2; borderColor: #f2f2f2;
borderActive: #80cff9; borderActive: #80cff9;
borderError: #ed8080; borderError: #ed8080;
} }
dlgScroll: flatScroll(scrollDef) {
topsh: 0px; noContactsHeight: 100px;
bottomsh: 0px; noContactsFont: font(fsize);
} noContactsColor: #777;
dlgFont: font(fsize);
dlgDblCheckImg: sprite(302px, 23px, 17px, 11px); dlgDblCheckImg: sprite(302px, 23px, 17px, 11px);
dlgCheckImg: sprite(320px, 23px, 17px, 11px); dlgCheckImg: sprite(320px, 23px, 17px, 11px);
@ -956,45 +936,17 @@ dlgActiveCheckImg: sprite(320px, 36px, 17px, 11px);
dlgSendImg: sprite(122px, 25px, 17px, 11px); dlgSendImg: sprite(122px, 25px, 17px, 11px);
dlgActiveSendImg: sprite(142px, 25px, 17px, 11px); dlgActiveSendImg: sprite(142px, 25px, 17px, 11px);
dlgChatImgPos: point(1px, 4px);
dlgChatImg: sprite(104px, 26px, 16px, 11px); dlgChatImg: sprite(104px, 26px, 16px, 11px);
dlgActiveChatImg: sprite(104px, 37px, 16px, 11px); dlgActiveChatImg: sprite(104px, 37px, 16px, 11px);
dlgChannelImgPos: point(3px, 4px);
dlgChannelImg: sprite(105px, 1px, 12px, 11px); dlgChannelImg: sprite(105px, 1px, 12px, 11px);
dlgActiveChannelImg: sprite(105px, 14px, 12px, 11px); dlgActiveChannelImg: sprite(105px, 14px, 12px, 11px);
dlgImgSkip: 22px;
dlgCheckLeft: 5px; dlgFilter: flatInput(searchFlatInput) {
dlgCheckTop: 4px; width: 240px;
dlgCheckSkip: 3px; height: 34px;
textMrg: margins(34px, 2px, 34px, 4px);
dlgHistFont: font(fsize); imgPos: point(6px, 5px);
dlgNameColor: #000; }
dlgNameTop: 2px;
dlgSystemColor: #4981af;
dlgTextColor: #888;
dlgDateFont: font(13px);
dlgDateColor: #a8a8a8;
dlgDateSkip: 5px;
dlgUnreadColor: #FFF;
dlgUnreadBG: #009ce6;//#6fc766;
dlgUnreadMutedBG: #bbb;
dlgUnreadFont: font(12px bold);
dlgUnreadHeight: 19px;
dlgUnreadTop: 1px;
dlgUnreadPaddingHor: 5px;
dlgUnreadRadius: 2px;
dlgBG: #FFF;
dlgHoverBG: #f5f5f5;
dlgActiveBG: #6a91b1;
dlgActiveUnreadColor: #5b94bf;
dlgActiveUnreadBG: white;
dlgActiveColor: white;
dlgActiveDateColor: #d3e2ee;
dlgActiveUnreadMutedBG: dlgActiveDateColor;
topBarHeight: 54px; topBarHeight: 54px;
topBarBG: white; topBarBG: white;
@ -1024,24 +976,23 @@ topBarSearch: iconedButton(btnDefIconed) {
height: topBarHeight; height: topBarHeight;
} }
topBarMinPadding: 5px; topBarMinPadding: 5px;
topBarButton: flatButton(btnDefFlat) { topBarButton: BoxButton {
color: btnYesColor; textFg: #0084c4;
overColor: btnYesHover; textFgOver: #0084c4;
downColor: btnYesHover; textBg: white;
textBgOver: #edf4f7;
bgColor: white; width: -22px;
overBgColor: white; height: 28px;
downBgColor: white; padding: margins(0px, 14px, 12px, 12px);
width: -40px; textTop: 6px;
height: 54px;
textTop: 19px;
overTextTop: 19px;
downTextTop: 20px;
font: font(fsize); font: font(fsize);
overFont: font(fsize underline); duration: 200;
}
topBarClearButton: BoxButton(topBarButton) {
padding: margins(8px, 14px, 8px, 14px);
} }
topBarActionButton: flatButton(btnDefNext, btnDefBig) { topBarActionButton: flatButton(btnDefNext, btnDefBig) {
textTop: 8px; textTop: 8px;
@ -1243,16 +1194,6 @@ medviewSaveAsTextStyle: textStyle(defaultTextStyle) {
linkFgDown: #91d9ff; linkFgDown: #91d9ff;
} }
dlgTextStyle: textStyle(defaultTextStyle) {
linkFg: dlgSystemColor;
linkFgDown: dlgSystemColor;
linkFlagsOver: font(fsize);
}
dlgActiveTextStyle: textStyle(defaultTextStyle) {
linkFg: dlgActiveColor;
linkFgDown: dlgActiveColor;
linkFlagsOver: font(fsize);
}
introLabelTextStyle: textStyle(defaultTextStyle) { introLabelTextStyle: textStyle(defaultTextStyle) {
lineHeight: 30px; lineHeight: 30px;
} }
@ -1538,16 +1479,24 @@ taMsgField: flatTextarea(taDefFlat) {
maxFieldHeight: 220px; maxFieldHeight: 220px;
// historyMinHeight: 56px; // historyMinHeight: 56px;
reportSpamHide: flatButton(topBarButton) { reportSpamHide: flatButton(btnDefFlat) {
color: btnYesColor;
overColor: btnYesHover;
downColor: btnYesHover;
bgColor: transparent;
overBgColor: transparent;
downBgColor: transparent;
width: -40px;
height: 46px; height: 46px;
textTop: 15px; textTop: 15px;
overTextTop: 15px; overTextTop: 15px;
downTextTop: 16px; downTextTop: 16px;
bgColor: transparent; font: font(fsize);
overBgColor: transparent; overFont: font(fsize underline);
downBgColor: transparent;
} }
reportSpamButton: flatButton(reportSpamHide) { reportSpamButton: flatButton(reportSpamHide) {
textTop: 6px; textTop: 6px;
@ -1687,134 +1636,16 @@ confirmCompressedSkip: 10px;
profileMaxWidth: 410px; profileMaxWidth: 410px;
profilePadding: margins(28px, 30px, 28px, 0px); profilePadding: margins(28px, 30px, 28px, 0px);
//profilePhotoSize: 120px;
//profileNameLeft: 21px;
//profileNameTop: -1px;
//profileNameFont: font(20px);
//profileStatusLeft: 22px;
//profileStatusTop: 31px;
//profileStatusFont: font(fsize);
profilePhoneLeft: 22px;
profilePhoneTop: 62px;
profilePhoneFont: font(16px);
//profileButtonTop: 18px;
//profileButtonSkip: 10px;
profileHeaderFont: font(20px);
profileHeaderColor: black;
profileHeaderSkip: 59px;
profileHeaderLeft: -1px;
profileHeaderTop: 22px;
profileListPhotoSize: 46px;
profileListPadding: size(12px, 6px);
profileListNameTop: 8px;
profileListStatusBottom: 6px;
profileHoverBG: #f5f5f5;
profileActiveBG: #6294b9;
profileSubFont: font(fsize);
profileListNameFont: semiboldFont;
profileListNameColor: #000;
profileOnlineColor: titleTypingColor; profileOnlineColor: titleTypingColor;
profileOfflineColor: titleStatusColor; profileOfflineColor: titleStatusColor;
btnShareContact: flatButton(btnDefNext, btnDefBig) {
width: 145px;
height: 42px;
textTop: 9px;
overTextTop: 9px;
downTextTop: 10px;
font: font(17px);
overFont: font(17px);
}
btnMigrateToMega: flatButton(btnShareContact) {
width: -40px;
}
profileMinBtnPadding: 10px;
membersPadding: margins(0px, 10px, 0px, 10px); membersPadding: margins(0px, 10px, 0px, 10px);
forwardMargins: margins(30px, 10px, 30px, 10px); forwardMargins: margins(30px, 10px, 30px, 10px);
forwardFont: font(16px); forwardFont: font(16px);
forwardBg: rgba(0, 0, 0, 76); forwardBg: rgba(0, 0, 0, 76);
btnProfileCancel: flatButton(btnDefFlat, btnDefBig) {
color: #666d78;
overColor: #666d78;
downColor: #50565e;
bgColor: rgba(0, 0, 0, 63);
overBgColor: rgba(0, 0, 0, 47);
downBgColor: rgba(0, 0, 0, 95);
width: 145px;
height: 40px;
textTop: 9px;
overTextTop: 9px;
downTextTop: 10px;
font: font(18px);
overFont: font(18px);
}
btnDeleteContact: flatButton(btnDefFlat, btnDefBig) {
color: #fff;
overColor: #fff;
downColor: #ffcbc1;
bgColor: #ee4928bf;
overBgColor: #ee4928;
downBgColor: #d14024;
width: 300px;
height: 40px;
textTop: 9px;
overTextTop: 9px;
downTextTop: 10px;
font: font(18px);
overFont: font(18px);
}
profileNameInput: flatInput(setNameInput) {
width: 230px;
}
participantInnerAdd: flatButton(btnDefNext) {
width: 145px;
height: 40px;
font: font(18px);
overFont: font(18px);
textTop: 9px;
overTextTop: 9px;
downTextTop: 10px;
}
participantInnerCancel: flatButton(participantInnerAdd, btnDefBack) {
}
participantCancel: flatButton(participantInnerAdd, btnDefBack) {
width: 300px;
}
participantFilter: flatInput(inpDefFlat) {
width: 364px;
height: 52px;
font: font(16px);
textMrg: margins(39px, 11px, 10px, 10px);
imgRect: sprite(227px, 21px, 24px, 24px);
imgPos: point(10px, 15px);
}
participantDelta: 12px;
contactsFilter: flatInput(dlgFilter) {
width: 340px;
height: 38px;
textMrg: margins(34px, 3px, 5px, 4px);
imgPos: point(6px, 7px);
}
inpCountry: flatInput(contactsFilter) {
}
newGroupLimitFg: #a4a4a4;
newGroupAboutFg: #808080; newGroupAboutFg: #808080;
newGroupPadding: margins(4px, 6px, 4px, 3px); newGroupPadding: margins(4px, 6px, 4px, 3px);
newGroupSkip: 17px; newGroupSkip: 17px;
@ -1855,15 +1686,6 @@ connectionPasswordInputField: InputField(defaultInputField) {
} }
connectionIPv6Skip: 11px; connectionIPv6Skip: 11px;
contactsAdd: flatButton(topBarButton) {
width: -40px;
height: 52px;
textTop: 18px;
overTextTop: 18px;
downTextTop: 19px;
}
aboutIcon: sprite(0px, 0px, 104px, 104px); aboutIcon: sprite(0px, 0px, 104px, 104px);
aboutWidth: 390px; aboutWidth: 390px;
aboutVersionTop: -3px; aboutVersionTop: -3px;
@ -2131,8 +1953,6 @@ stickerPreviewDuration: 150;
stickerPreviewBg: #FFFFFFB0; stickerPreviewBg: #FFFFFFB0;
stickerPreviewMin: 0.1; stickerPreviewMin: 0.1;
verifiedCheckProfile: sprite(285px, 235px, 18px, 18px);
verifiedCheckProfilePos: point(7px, 6px);
verifiedCheck: sprite(285px, 221px, 14px, 14px); verifiedCheck: sprite(285px, 221px, 14px, 14px);
verifiedCheckInv: sprite(299px, 221px, 14px, 14px); verifiedCheckInv: sprite(299px, 221px, 14px, 14px);
verifiedCheckPos: point(4px, 2px); verifiedCheckPos: point(4px, 2px);
@ -2419,7 +2239,7 @@ sessionNameFont: msgNameFont;
sessionActiveFont: msgDateFont; sessionActiveFont: msgDateFont;
sessionActiveColor: #aaa; sessionActiveColor: #aaa;
sessionInfoFont: msgFont; sessionInfoFont: msgFont;
sessionInfoColor: dlgTextColor; sessionInfoColor: #888888;
sessionTerminateTop: 30px; sessionTerminateTop: 30px;
sessionTerminateSkip: 18px; sessionTerminateSkip: 18px;
sessionTerminate: iconedButton(notifyClose) { sessionTerminate: iconedButton(notifyClose) {

View File

@ -305,6 +305,7 @@ BoxButton {
width: pixels; width: pixels;
height: pixels; height: pixels;
padding: margins;
textTop: pixels; textTop: pixels;
@ -328,7 +329,7 @@ Checkbox {
textPosition: point; textPosition: point;
diameter: pixels; diameter: pixels;
thickness: pixels; thickness: pixels;
checkIcon: sprite; checkIcon: icon;
font: font; font: font;
duration: int; duration: int;

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 B

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

After

Width:  |  Height:  |  Size: 344 B

View File

@ -124,6 +124,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_flood_error" = "Too many tries. Please try again later."; "lng_flood_error" = "Too many tries. Please try again later.";
"lng_gif_error" = "An error has occured while reading GIF animation :("; "lng_gif_error" = "An error has occured while reading GIF animation :(";
"lng_edit_error" = "You cannot edit this message"; "lng_edit_error" = "You cannot edit this message";
"lng_join_channel_error" = "Sorry, you have joined too many channels and supergroups. Please leave some before joining.";
"lng_edit_deleted" = "This message was deleted"; "lng_edit_deleted" = "This message was deleted";
"lng_edit_too_long" = "Your message text is too long"; "lng_edit_too_long" = "Your message text is too long";
"lng_edit_message" = "Edit message"; "lng_edit_message" = "Edit message";

View File

@ -26,13 +26,16 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "application.h" #include "application.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "historywidget.h"
#include "localstorage.h" #include "localstorage.h"
#include "boxes/confirmbox.h"
ApiWrap::ApiWrap(QObject *parent) : QObject(parent) ApiWrap::ApiWrap(QObject *parent) : QObject(parent)
, _messageDataResolveDelayed(new SingleDelayedCall(this, "resolveMessageDatas")) { , _messageDataResolveDelayed(new SingleDelayedCall(this, "resolveMessageDatas")) {
App::initBackground(); App::initBackground();
connect(&_webPagesTimer, SIGNAL(timeout()), this, SLOT(resolveWebPages())); connect(&_webPagesTimer, SIGNAL(timeout()), this, SLOT(resolveWebPages()));
connect(&_draftsSaveTimer, SIGNAL(timeout()), this, SLOT(saveDraftsToCloud()));
} }
void ApiWrap::init() { void ApiWrap::init() {
@ -717,6 +720,9 @@ void ApiWrap::channelAmInDone(ChannelData *channel, const MTPUpdates &updates) {
bool ApiWrap::channelAmInFail(ChannelData *channel, const RPCError &error) { bool ApiWrap::channelAmInFail(ChannelData *channel, const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false; if (MTP::isDefaultHandledError(error)) return false;
if (error.type() == qstr("CHANNELS_TOO_MUCH")) {
Ui::showLayer(new InformBox(lang(lng_join_channel_error)));
}
_channelAmInRequests.remove(channel); _channelAmInRequests.remove(channel);
return true; return true;
} }
@ -798,6 +804,83 @@ void ApiWrap::requestNotifySetting(PeerData *peer) {
_notifySettingRequests.insert(peer, requestId); _notifySettingRequests.insert(peer, requestId);
} }
void ApiWrap::saveDraftToCloudDelayed(History *history) {
_draftsSaveRequestIds.insert(history, 0);
if (!_draftsSaveTimer.isActive()) {
_draftsSaveTimer.start(SaveCloudDraftTimeout);
}
}
bool ApiWrap::hasUnsavedDrafts() const {
return !_draftsSaveRequestIds.isEmpty();
}
void ApiWrap::saveDraftsToCloud() {
for (auto i = _draftsSaveRequestIds.begin(), e = _draftsSaveRequestIds.end(); i != e; ++i) {
if (i.value()) continue; // sent already
auto history = i.key();
auto cloudDraft = history->cloudDraft();
auto localDraft = history->localDraft();
if (cloudDraft && cloudDraft->saveRequestId) {
MTP::cancel(cloudDraft->saveRequestId);
}
cloudDraft = history->createCloudDraft(localDraft);
MTPmessages_SaveDraft::Flags flags = 0;
auto &textWithTags = cloudDraft->textWithTags;
if (cloudDraft->previewCancelled) {
flags |= MTPmessages_SaveDraft::Flag::f_no_webpage;
}
if (cloudDraft->msgId) {
flags |= MTPmessages_SaveDraft::Flag::f_reply_to_msg_id;
}
if (!textWithTags.tags.isEmpty()) {
flags |= MTPmessages_SaveDraft::Flag::f_entities;
}
auto entities = linksToMTP(entitiesFromTextTags(textWithTags.tags), true);
cloudDraft->saveRequestId = MTP::send(MTPmessages_SaveDraft(MTP_flags(flags), MTP_int(cloudDraft->msgId), history->peer->input, MTP_string(textWithTags.text), entities), rpcDone(&ApiWrap::saveCloudDraftDone, history), rpcFail(&ApiWrap::saveCloudDraftFail, history));
i.value() = cloudDraft->saveRequestId;
}
if (_draftsSaveRequestIds.isEmpty()) {
App::allDraftsSaved(); // can quit the application
}
}
void ApiWrap::saveCloudDraftDone(History *history, const MTPBool &result, mtpRequestId requestId) {
if (auto cloudDraft = history->cloudDraft()) {
if (cloudDraft->saveRequestId == requestId) {
cloudDraft->saveRequestId = 0;
history->updateChatListEntry();
}
}
auto i = _draftsSaveRequestIds.find(history);
if (i != _draftsSaveRequestIds.cend() && i.value() == requestId) {
_draftsSaveRequestIds.remove(history);
if (_draftsSaveRequestIds.isEmpty()) {
App::allDraftsSaved(); // can quit the application
}
}
}
bool ApiWrap::saveCloudDraftFail(History *history, const RPCError &error, mtpRequestId requestId) {
if (MTP::isDefaultHandledError(error)) return false;
if (auto cloudDraft = history->cloudDraft()) {
if (cloudDraft->saveRequestId == requestId) {
history->clearCloudDraft();
}
}
auto i = _draftsSaveRequestIds.find(history);
if (i != _draftsSaveRequestIds.cend() && i.value() == requestId) {
_draftsSaveRequestIds.remove(history);
if (_draftsSaveRequestIds.isEmpty()) {
App::allDraftsSaved(); // can quit the application
}
}
return true;
}
void ApiWrap::notifySettingDone(MTPInputNotifyPeer notifyPeer, const MTPPeerNotifySettings &result) { void ApiWrap::notifySettingDone(MTPInputNotifyPeer notifyPeer, const MTPPeerNotifySettings &result) {
if (auto requestedPeer = notifySettingReceived(notifyPeer, result)) { if (auto requestedPeer = notifySettingReceived(notifyPeer, result)) {
_notifySettingRequests.remove(requestedPeer); _notifySettingRequests.remove(requestedPeer);

View File

@ -59,6 +59,9 @@ public:
void exportInviteLink(PeerData *peer); void exportInviteLink(PeerData *peer);
void requestNotifySetting(PeerData *peer); void requestNotifySetting(PeerData *peer);
void saveDraftToCloudDelayed(History *history);
bool hasUnsavedDrafts() const;
~ApiWrap(); ~ApiWrap();
signals: signals:
@ -71,6 +74,7 @@ public slots:
void resolveWebPages(); void resolveWebPages();
void delayedRequestParticipantsCount(); void delayedRequestParticipantsCount();
void saveDraftsToCloud();
private: private:
@ -150,5 +154,9 @@ private:
PeerData *notifySettingReceived(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings); PeerData *notifySettingReceived(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings);
bool notifySettingFail(PeerData *peer, const RPCError &error); bool notifySettingFail(PeerData *peer, const RPCError &error);
QMap<History*, mtpRequestId> _draftsSaveRequestIds;
SingleTimer _draftsSaveTimer;
void saveCloudDraftDone(History *history, const MTPBool &result, mtpRequestId requestId);
bool saveCloudDraftFail(History *history, const RPCError &error, mtpRequestId requestId);
}; };

View File

@ -2257,6 +2257,19 @@ namespace {
if (quitting()) return; if (quitting()) return;
setLaunchState(QuitRequested); setLaunchState(QuitRequested);
if (auto window = wnd()) {
window->hide();
}
if (auto mainwidget = main()) {
mainwidget->saveDraftToCloud();
}
if (auto apiwrap = api()) {
if (apiwrap->hasUnsavedDrafts()) {
apiwrap->saveDraftsToCloud();
QTimer::singleShot(SaveDraftBeforeQuitTimeout, Application::instance(), SLOT(quit()));
return;
}
}
Application::quit(); Application::quit();
} }
@ -2264,6 +2277,12 @@ namespace {
return _launchState != Launched; return _launchState != Launched;
} }
void allDraftsSaved() {
if (quitting()) {
Application::quit();
}
}
LaunchState launchState() { LaunchState launchState() {
return _launchState; return _launchState;
} }

View File

@ -228,6 +228,7 @@ namespace App {
}; };
void quit(); void quit();
bool quitting(); bool quitting();
void allDraftsSaved();
LaunchState launchState(); LaunchState launchState();
void setLaunchState(LaunchState state); void setLaunchState(LaunchState state);

View File

@ -656,7 +656,8 @@ void EditCaptionBox::onSave(bool ctrlShiftEnter) {
if (!sentEntities.c_vector().v.isEmpty()) { if (!sentEntities.c_vector().v.isEmpty()) {
flags |= MTPmessages_EditMessage::Flag::f_entities; flags |= MTPmessages_EditMessage::Flag::f_entities;
} }
_saveRequestId = MTP::send(MTPmessages_EditMessage(MTP_flags(flags), item->history()->peer->input, MTP_int(item->id), MTP_string(_field->getLastText()), MTPnullMarkup, sentEntities), rpcDone(&EditCaptionBox::saveDone), rpcFail(&EditCaptionBox::saveFail)); auto text = prepareText(_field->getLastText(), true);
_saveRequestId = MTP::send(MTPmessages_EditMessage(MTP_flags(flags), item->history()->peer->input, MTP_int(item->id), MTP_string(text), MTPnullMarkup, sentEntities), rpcDone(&EditCaptionBox::saveDone), rpcFail(&EditCaptionBox::saveFail));
} }
void EditCaptionBox::saveDone(const MTPUpdates &updates) { void EditCaptionBox::saveDone(const MTPUpdates &updates) {

View File

@ -151,8 +151,10 @@ enum {
WriteMapTimeout = 1000, WriteMapTimeout = 1000,
SaveDraftTimeout = 1000, // save draft after 1 secs of not changing text SaveDraftTimeout = 1000, // save draft after 1 secs of not changing text
SaveCloudDraftTimeout = 14000, // save draft to the cloud after 14 more seconds
SaveDraftAnywayTimeout = 5000, // or save anyway each 5 secs SaveDraftAnywayTimeout = 5000, // or save anyway each 5 secs
SaveCloudDraftIdleTimeout = 14000, // save draft to the cloud after 14 more seconds
SaveCloudDraftTimeout = 1000, // save draft to the cloud with 1 sec extra delay
SaveDraftBeforeQuitTimeout = 1500, // give the app 1.5 secs to save drafts to cloud when quitting
SetOnlineAfterActivity = 30, // user with hidden last seen stays online for such amount of seconds in the interface SetOnlineAfterActivity = 30, // user with hidden last seen stays online for such amount of seconds in the interface

View File

@ -19,7 +19,69 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/ */
using "basic.style"; using "basic.style";
using "basic_types.style";
dialogsDraft: icon { dialogsUnreadFg: #ffffff;
{ "dialogs_draft", #ffffff, point(5px, 4px) }, dialogsUnreadFgActive: #5b94bf;
}; dialogsUnreadBg: #009ce6;//#6fc766;
dialogsUnreadBgMuted: #bbb;
dialogsUnreadBgActive: #ffffff;
dialogsUnreadBgMutedActive: #d3e2ee;
dialogsUnreadFont: font(12px bold);
dialogsUnreadHeight: 19px;
dialogsUnreadTop: 1px;
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: #000;
dialogsNameTop: 2px;
dialogsRowHeight: 62px;
dialogsFilterPadding: 10px;
dialogsPhotoSize: 46px;
dialogsPhotoPadding: 12px;
dialogsPadding: point(10px, 8px);
dialogsImportantBarHeight: 37px;
dialogsSkip: 8px;
dialogsWidthMin: 260px;
dialogsWidthMax: 540px;
dialogsTextWidthMin: 150px;
dialogsScroll: flatScroll(scrollDef) {
topsh: 0px;
bottomsh: 0px;
}
dialogsChatImgPos: point(1px, 4px);
dialogsChannelImgPos: point(3px, 4px);
dialogsImgSkip: 22px;
dialogsCheckLeft: 5px;
dialogsCheckTop: 4px;
dialogsCheckSkip: 3px;
dialogsTextStyle: textStyle(defaultTextStyle) {
linkFg: dialogsTextFgService;
linkFgDown: dialogsTextFgService;
linkFlagsOver: font(fsize);
}
dialogsTextStyleDraft: textStyle(dialogsTextStyle) {
linkFg: #dd4b39;
linkFgDown: #dd4b39;
}
dialogsTextStyleActive: textStyle(dialogsTextStyle) {
linkFg: dialogsTextFgActive;
linkFgDown: dialogsTextFgActive;
}

View File

@ -42,80 +42,68 @@ void paintRowDate(Painter &p, const QDateTime &date, QRect &rectForName, bool ac
} else { } else {
dt = lastDate.toString(qsl("d.MM.yy")); dt = lastDate.toString(qsl("d.MM.yy"));
} }
int32 dtWidth = st::dlgDateFont->width(dt); int32 dtWidth = st::dialogsDateFont->width(dt);
rectForName.setWidth(rectForName.width() - dtWidth - st::dlgDateSkip); rectForName.setWidth(rectForName.width() - dtWidth - st::dialogsDateSkip);
p.setFont(st::dlgDateFont); p.setFont(st::dialogsDateFont);
p.setPen(active ? st::dlgActiveDateColor : st::dlgDateColor); p.setPen(active ? st::dialogsDateFgActive : st::dialogsDateFg);
p.drawText(rectForName.left() + rectForName.width() + st::dlgDateSkip, rectForName.top() + st::msgNameFont->height - st::msgDateFont->descent, dt); p.drawText(rectForName.left() + rectForName.width() + st::dialogsDateSkip, rectForName.top() + st::msgNameFont->height - st::msgDateFont->descent, dt);
} }
template <typename PaintItemCallback> template <typename PaintItemCallback>
void paintRow(Painter &p, History *history, HistoryItem *item, HistoryDraft *draft, int w, bool active, bool selected, bool onlyBackground, PaintItemCallback paintItemCallback) { void paintRow(Painter &p, History *history, HistoryItem *item, HistoryDraft *draft, int w, bool active, bool selected, bool onlyBackground, PaintItemCallback paintItemCallback) {
QRect fullRect(0, 0, w, st::dlgHeight); QRect fullRect(0, 0, w, st::dialogsRowHeight);
p.fillRect(fullRect, active ? st::dlgActiveBG : (selected ? st::dlgHoverBG : st::dlgBG)); p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
if (onlyBackground) return; if (onlyBackground) return;
PeerData *userpicPeer = (history->peer->migrateTo() ? history->peer->migrateTo() : history->peer); PeerData *userpicPeer = (history->peer->migrateTo() ? history->peer->migrateTo() : history->peer);
userpicPeer->paintUserpicLeft(p, st::dlgPhotoSize, st::dlgPaddingHor, st::dlgPaddingVer, w); userpicPeer->paintUserpicLeft(p, st::dialogsPhotoSize, st::dialogsPadding.x(), st::dialogsPadding.y(), w);
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding; int32 nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
int32 namewidth = w - nameleft - st::dlgPaddingHor; int32 namewidth = w - nameleft - st::dialogsPadding.x();
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height); QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height);
// draw chat icon // draw chat icon
if (history->peer->isChat() || history->peer->isMegagroup()) { if (history->peer->isChat() || history->peer->isMegagroup()) {
p.drawSprite(QPoint(rectForName.left() + st::dlgChatImgPos.x(), rectForName.top() + st::dlgChatImgPos.y()), (active ? st::dlgActiveChatImg : st::dlgChatImg)); p.drawSprite(QPoint(rectForName.left() + st::dialogsChatImgPos.x(), rectForName.top() + st::dialogsChatImgPos.y()), (active ? st::dlgActiveChatImg : st::dlgChatImg));
rectForName.setLeft(rectForName.left() + st::dlgImgSkip); rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
} else if (history->peer->isChannel()) { } else if (history->peer->isChannel()) {
p.drawSprite(QPoint(rectForName.left() + st::dlgChannelImgPos.x(), rectForName.top() + st::dlgChannelImgPos.y()), (active ? st::dlgActiveChannelImg : st::dlgChannelImg)); p.drawSprite(QPoint(rectForName.left() + st::dialogsChannelImgPos.x(), rectForName.top() + st::dialogsChannelImgPos.y()), (active ? st::dlgActiveChannelImg : st::dlgChannelImg));
rectForName.setLeft(rectForName.left() + st::dlgImgSkip); rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
} }
int texttop = st::dlgPaddingVer + st::dlgFont->height + st::dlgSep; int texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
if (draft) { if (draft) {
paintRowDate(p, draft->date, rectForName, active); paintRowDate(p, draft->date, rectForName, active);
// draw check // draw check
if (draft->saveRequestId) { if (draft->saveRequestId) {
auto check = active ? &st::dlgActiveSendImg : &st::dlgSendImg; auto check = active ? &st::dlgActiveSendImg : &st::dlgSendImg;
rectForName.setWidth(rectForName.width() - check->pxWidth() - st::dlgCheckSkip); rectForName.setWidth(rectForName.width() - check->pxWidth() - st::dialogsCheckSkip);
p.drawSprite(QPoint(rectForName.left() + rectForName.width() + st::dlgCheckLeft, rectForName.top() + st::dlgCheckTop), *check); p.drawSprite(QPoint(rectForName.left() + rectForName.width() + st::dialogsCheckLeft, rectForName.top() + st::dialogsCheckTop), *check);
} }
bool hasDraftIcon = !active; p.setFont(st::dialogsTextFont);
if (hasDraftIcon) { p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFgService);
QString counter;
bool mutedCounter = false;
int unreadRight = w - st::dlgPaddingHor;
int unreadTop = texttop + st::dlgHistFont->ascent - st::dlgUnreadFont->ascent - st::dlgUnreadTop;
int unreadWidth = 0;
paintUnreadCount(p, counter, unreadRight, unreadTop, style::al_right, active, mutedCounter, &unreadWidth);
st::dialogsDraft.paint(p, QPoint(w - st::dlgPaddingHor - st::dlgUnreadHeight, unreadTop), w);
namewidth -= unreadWidth + st::dlgUnreadPaddingHor;
}
p.setFont(st::dlgHistFont);
p.setPen(active ? st::dlgActiveColor : st::dlgSystemColor);
if (history->typing.isEmpty() && history->sendActions.isEmpty()) { if (history->typing.isEmpty() && history->sendActions.isEmpty()) {
if (history->cloudDraftTextCache.isEmpty()) { if (history->cloudDraftTextCache.isEmpty()) {
TextCustomTagsMap custom; TextCustomTagsMap custom;
custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink())); custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
QString msg = lng_message_with_from(lt_from, textRichPrepare(lang(lng_from_draft)), lt_message, textRichPrepare(draft->textWithTags.text)); QString msg = lng_message_with_from(lt_from, textRichPrepare(lang(lng_from_draft)), lt_message, textRichPrepare(draft->textWithTags.text));
history->cloudDraftTextCache.setRichText(st::dlgHistFont, msg, _textDlgOptions, custom); history->cloudDraftTextCache.setRichText(st::dialogsTextFont, msg, _textDlgOptions, custom);
} }
textstyleSet(&(active ? st::dlgActiveTextStyle : st::dlgTextStyle)); textstyleSet(&(active ? st::dialogsTextStyleActive : st::dialogsTextStyleDraft));
p.setFont(st::dlgHistFont); p.setFont(st::dialogsTextFont);
p.setPen(active ? st::dlgActiveColor : st::dlgTextColor); p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFg);
history->cloudDraftTextCache.drawElided(p, nameleft, texttop, namewidth, st::dlgFont->height / st::dlgHistFont->height); history->cloudDraftTextCache.drawElided(p, nameleft, texttop, namewidth, 1);
textstyleRestore(); textstyleRestore();
} else { } else {
history->typingText.drawElided(p, nameleft, texttop, namewidth); history->typingText.drawElided(p, nameleft, texttop, namewidth);
} }
} else if (!item) { } else if (!item) {
p.setFont(st::dlgHistFont); p.setFont(st::dialogsTextFont);
p.setPen(active ? st::dlgActiveColor : st::dlgSystemColor); p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFgService);
if (history->typing.isEmpty() && history->sendActions.isEmpty()) { if (history->typing.isEmpty() && history->sendActions.isEmpty()) {
p.drawText(nameleft, texttop + st::dlgFont->ascent, lang(lng_empty_history)); p.drawText(nameleft, texttop + st::msgNameFont->ascent, lang(lng_empty_history));
} else { } else {
history->typingText.drawElided(p, nameleft, texttop, namewidth); history->typingText.drawElided(p, nameleft, texttop, namewidth);
} }
@ -134,8 +122,8 @@ void paintRow(Painter &p, History *history, HistoryItem *item, HistoryDraft *dra
} else { } else {
check = active ? &st::dlgActiveSendImg : &st::dlgSendImg; check = active ? &st::dlgActiveSendImg : &st::dlgSendImg;
} }
rectForName.setWidth(rectForName.width() - check->pxWidth() - st::dlgCheckSkip); rectForName.setWidth(rectForName.width() - check->pxWidth() - st::dialogsCheckSkip);
p.drawSprite(QPoint(rectForName.left() + rectForName.width() + st::dlgCheckLeft, rectForName.top() + st::dlgCheckTop), *check); p.drawSprite(QPoint(rectForName.left() + rectForName.width() + st::dialogsCheckLeft, rectForName.top() + st::dialogsCheckTop), *check);
} }
paintItemCallback(nameleft, namewidth, item); paintItemCallback(nameleft, namewidth, item);
@ -146,7 +134,7 @@ void paintRow(Painter &p, History *history, HistoryItem *item, HistoryDraft *dra
p.drawSprite(rectForName.topLeft() + QPoint(qMin(history->peer->dialogName().maxWidth(), rectForName.width()), 0) + st::verifiedCheckPos, (active ? st::verifiedCheckInv : st::verifiedCheck)); p.drawSprite(rectForName.topLeft() + QPoint(qMin(history->peer->dialogName().maxWidth(), rectForName.width()), 0) + st::verifiedCheckPos, (active ? st::verifiedCheckInv : st::verifiedCheck));
} }
p.setPen(active ? st::dlgActiveColor : st::dlgNameColor); p.setPen(active ? st::dialogsTextFgActive : st::dialogsNameFg);
history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
} }
@ -154,7 +142,7 @@ class UnreadBadgeStyle : public StyleSheet {
public: public:
QImage circle; QImage circle;
QPixmap left[4], right[4]; QPixmap left[4], right[4];
style::color bg[4] = { st::dlgUnreadBG, st::dlgActiveUnreadBG, st::dlgUnreadMutedBG, st::dlgActiveUnreadMutedBG }; style::color bg[4] = { st::dialogsUnreadBg, st::dialogsUnreadBgActive, st::dialogsUnreadBgMuted, st::dialogsUnreadBgMutedActive };
}; };
StyleSheetPointer<UnreadBadgeStyle> unreadBadgeStyle; StyleSheetPointer<UnreadBadgeStyle> unreadBadgeStyle;
@ -203,9 +191,9 @@ void paintUnreadBadge(Painter &p, const QRect &rect, bool active, bool muted) {
} }
void paintUnreadCount(Painter &p, const QString &text, int x, int y, style::align align, bool active, bool muted, int *outUnreadWidth) { void paintUnreadCount(Painter &p, const QString &text, int x, int y, style::align align, bool active, bool muted, int *outUnreadWidth) {
int unreadWidth = st::dlgUnreadFont->width(text); int unreadWidth = st::dialogsUnreadFont->width(text);
int unreadRectWidth = unreadWidth + 2 * st::dlgUnreadPaddingHor; int unreadRectWidth = unreadWidth + 2 * st::dialogsUnreadPadding;
int unreadRectHeight = st::dlgUnreadHeight; int unreadRectHeight = st::dialogsUnreadHeight;
accumulate_max(unreadRectWidth, unreadRectHeight); accumulate_max(unreadRectWidth, unreadRectHeight);
int unreadRectLeft = x; int unreadRectLeft = x;
@ -221,9 +209,9 @@ void paintUnreadCount(Painter &p, const QString &text, int x, int y, style::alig
paintUnreadBadge(p, QRect(unreadRectLeft, unreadRectTop, unreadRectWidth, unreadRectHeight), active, muted); paintUnreadBadge(p, QRect(unreadRectLeft, unreadRectTop, unreadRectWidth, unreadRectHeight), active, muted);
p.setFont(st::dlgUnreadFont); p.setFont(st::dialogsUnreadFont);
p.setPen(active ? st::dlgActiveUnreadColor : st::dlgUnreadColor); p.setPen(active ? st::dialogsUnreadFgActive : st::dialogsUnreadFg);
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + st::dlgUnreadTop + st::dlgUnreadFont->ascent, text); p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + st::dialogsUnreadTop + st::dialogsUnreadFont->ascent, text);
} }
void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool selected, bool onlyBackground) { void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool selected, bool onlyBackground) {
@ -241,30 +229,20 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele
} }
} }
int availableWidth = namewidth; int availableWidth = namewidth;
int texttop = st::dlgPaddingVer + st::dlgFont->height + st::dlgSep; int texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
auto cloudDraft = history->cloudDraft(); if (unread) {
bool hasDraftIcon = active ? false : (cloudDraft && cloudDraft->date.isValid()); auto counter = QString::number(unread);
if (unread || hasDraftIcon) { auto mutedCounter = history->mute();
QString counter; int unreadRight = w - st::dialogsPadding.x();
bool mutedCounter = false; int unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - st::dialogsUnreadTop;
bool showUnreadCounter = unread && (!hasDraftIcon || !history->mute());
if (showUnreadCounter) {
counter = QString::number(unread);
mutedCounter = history->mute();
}
int unreadRight = w - st::dlgPaddingHor;
int unreadTop = texttop + st::dlgHistFont->ascent - st::dlgUnreadFont->ascent - st::dlgUnreadTop;
int unreadWidth = 0; int unreadWidth = 0;
paintUnreadCount(p, counter, unreadRight, unreadTop, style::al_right, active, mutedCounter, &unreadWidth); paintUnreadCount(p, counter, unreadRight, unreadTop, style::al_right, active, mutedCounter, &unreadWidth);
if (!showUnreadCounter) { availableWidth -= unreadWidth + st::dialogsUnreadPadding;
st::dialogsDraft.paint(p, QPoint(w - st::dlgPaddingHor - st::dlgUnreadHeight, unreadTop), w);
}
availableWidth -= unreadWidth + st::dlgUnreadPaddingHor;
} }
if (history->typing.isEmpty() && history->sendActions.isEmpty()) { if (history->typing.isEmpty() && history->sendActions.isEmpty()) {
item->drawInDialog(p, QRect(nameleft, texttop, availableWidth, st::dlgFont->height), active, history->textCachedFor, history->lastItemTextCache); item->drawInDialog(p, QRect(nameleft, texttop, availableWidth, st::dialogsTextFont->height), active, history->textCachedFor, history->lastItemTextCache);
} else { } else {
p.setPen(active ? st::dlgActiveColor : st::dlgSystemColor); p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFgService);
history->typingText.drawElided(p, nameleft, texttop, availableWidth); history->typingText.drawElided(p, nameleft, texttop, availableWidth);
} }
}); });
@ -274,13 +252,13 @@ void RowPainter::paint(Painter &p, const FakeRow *row, int w, bool active, bool
auto item = row->item(); auto item = row->item();
auto history = item->history(); auto history = item->history();
paintRow(p, history, item, nullptr, w, active, selected, onlyBackground, [&p, row, active](int nameleft, int namewidth, HistoryItem *item) { paintRow(p, history, item, nullptr, w, active, selected, onlyBackground, [&p, row, active](int nameleft, int namewidth, HistoryItem *item) {
int lastWidth = namewidth, texttop = st::dlgPaddingVer + st::dlgFont->height + st::dlgSep; int lastWidth = namewidth, texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dlgFont->height), active, row->_cacheFor, row->_cache); item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dialogsTextFont->height), active, row->_cacheFor, row->_cache);
}); });
} }
void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool onlyBackground) { void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool onlyBackground) {
p.fillRect(0, 0, w, st::dlgImportantHeight, selected ? st::dlgHoverBG : st::white); p.fillRect(0, 0, w, st::dialogsImportantBarHeight, selected ? st::dialogsBgOver : st::white);
if (onlyBackground) { if (onlyBackground) {
return; return;
} }
@ -288,15 +266,15 @@ void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool o
p.setFont(st::semiboldFont); p.setFont(st::semiboldFont);
p.setPen(st::black); p.setPen(st::black);
int unreadTop = (st::dlgImportantHeight - st::dlgUnreadHeight) / 2; int unreadTop = (st::dialogsImportantBarHeight - st::dialogsUnreadHeight) / 2;
bool mutedHidden = (current == Dialogs::Mode::Important); bool mutedHidden = (current == Dialogs::Mode::Important);
QString text = mutedHidden ? qsl("Show all chats") : qsl("Hide muted chats"); QString text = mutedHidden ? qsl("Show all chats") : qsl("Hide muted chats");
int textBaseline = unreadTop + st::dlgUnreadTop + st::dlgUnreadFont->ascent; int textBaseline = unreadTop + st::dialogsUnreadTop + st::dialogsUnreadFont->ascent;
p.drawText(st::dlgPaddingHor, textBaseline, text); p.drawText(st::dialogsPadding.x(), textBaseline, text);
if (mutedHidden) { if (mutedHidden) {
if (int32 unread = App::histories().unreadMutedCount()) { if (int32 unread = App::histories().unreadMutedCount()) {
int unreadRight = w - st::dlgPaddingHor; int unreadRight = w - st::dialogsPadding.x();
paintUnreadCount(p, QString::number(unread), unreadRight, unreadTop, style::al_right, false, true, nullptr); paintUnreadCount(p, QString::number(unread), unreadRight, unreadTop, style::al_right, false, true, nullptr);
} }
} }

View File

@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "dialogs/dialogs_list.h" #include "dialogs/dialogs_list.h"
#include "dialogs/dialogs_layout.h" #include "dialogs/dialogs_layout.h"
#include "styles/style_dialogs.h"
#include "mainwidget.h" #include "mainwidget.h"
namespace Dialogs { namespace Dialogs {
@ -47,16 +48,16 @@ void List::adjustCurrent(int32 y, int32 h) const {
} }
void List::paint(Painter &p, int32 w, int32 hFrom, int32 hTo, PeerData *act, PeerData *sel, bool onlyBackground) const { void List::paint(Painter &p, int32 w, int32 hFrom, int32 hTo, PeerData *act, PeerData *sel, bool onlyBackground) const {
adjustCurrent(hFrom, st::dlgHeight); adjustCurrent(hFrom, st::dialogsRowHeight);
Row *row = _current; Row *row = _current;
p.translate(0, row->_pos * st::dlgHeight); p.translate(0, row->_pos * st::dialogsRowHeight);
while (row != _end && row->_pos * st::dlgHeight < hTo) { while (row != _end && row->_pos * st::dialogsRowHeight < hTo) {
bool active = (row->history()->peer == act) || (row->history()->peer->migrateTo() && row->history()->peer->migrateTo() == act); bool active = (row->history()->peer == act) || (row->history()->peer->migrateTo() && row->history()->peer->migrateTo() == act);
bool selected = (row->history()->peer == sel); bool selected = (row->history()->peer == sel);
Layout::RowPainter::paint(p, row, w, active, selected, onlyBackground); Layout::RowPainter::paint(p, row, w, active, selected, onlyBackground);
row = row->_next; row = row->_next;
p.translate(0, st::dlgHeight); p.translate(0, st::dialogsRowHeight);
} }
} }

View File

@ -0,0 +1,31 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#include "stdafx.h"
#include "dialogs/dialogs_row.h"
#include "styles/style_dialogs.h"
namespace Dialogs {
FakeRow::FakeRow(HistoryItem *item) : _item(item), _cache(st::dialogsTextWidthMin) {
}
} // namespace Dialogs

View File

@ -59,8 +59,7 @@ private:
class FakeRow { class FakeRow {
public: public:
FakeRow(HistoryItem *item) : _item(item) { FakeRow(HistoryItem *item);
}
HistoryItem *item() const { HistoryItem *item() const {
return _item; return _item;
@ -71,7 +70,7 @@ private:
HistoryItem *_item; HistoryItem *_item;
mutable const HistoryItem *_cacheFor = nullptr; mutable const HistoryItem *_cacheFor = nullptr;
mutable Text _cache = Text{ int(st::dlgRichMinWidth) }; mutable Text _cache;
}; };

View File

@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "dialogs/dialogs_indexed_list.h" #include "dialogs/dialogs_indexed_list.h"
#include "dialogs/dialogs_layout.h" #include "dialogs/dialogs_layout.h"
#include "styles/style_dialogs.h"
#include "data/drafts.h" #include "data/drafts.h"
#include "lang.h" #include "lang.h"
#include "application.h" #include "application.h"
@ -55,7 +56,7 @@ DialogsInner::DialogsInner(QWidget *parent, MainWidget *main) : SplittedWidget(p
} }
int DialogsInner::dialogsOffset() const { int DialogsInner::dialogsOffset() const {
return importantDialogs ? st::dlgImportantHeight : 0; return importantDialogs ? st::dialogsImportantBarHeight : 0;
} }
int DialogsInner::filteredOffset() const { int DialogsInner::filteredOffset() const {
@ -63,12 +64,12 @@ int DialogsInner::filteredOffset() const {
} }
int DialogsInner::peopleOffset() const { int DialogsInner::peopleOffset() const {
return filteredOffset() + (_filterResults.size() * st::dlgHeight) + st::searchedBarHeight; return filteredOffset() + (_filterResults.size() * st::dialogsRowHeight) + st::searchedBarHeight;
} }
int DialogsInner::searchedOffset() const { int DialogsInner::searchedOffset() const {
int result = peopleOffset() + (_peopleResults.isEmpty() ? 0 : ((_peopleResults.size() * st::dlgHeight) + st::searchedBarHeight)); int result = peopleOffset() + (_peopleResults.isEmpty() ? 0 : ((_peopleResults.size() * st::dialogsRowHeight) + st::searchedBarHeight));
if (_searchInPeer) result += st::dlgHeight; if (_searchInPeer) result += st::dialogsRowHeight;
return result; return result;
} }
@ -87,10 +88,10 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
QRect dialogsClip = r; QRect dialogsClip = r;
if (importantDialogs) { if (importantDialogs) {
Dialogs::Layout::paintImportantSwitch(p, Global::DialogsMode(), fullWidth(), _importantSwitchSel, paintingOther); Dialogs::Layout::paintImportantSwitch(p, Global::DialogsMode(), fullWidth(), _importantSwitchSel, paintingOther);
dialogsClip.translate(0, -st::dlgImportantHeight); dialogsClip.translate(0, -st::dialogsImportantBarHeight);
p.translate(0, st::dlgImportantHeight); p.translate(0, st::dialogsImportantBarHeight);
} }
int32 otherStart = shownDialogs()->size() * st::dlgHeight; int32 otherStart = shownDialogs()->size() * st::dialogsRowHeight;
PeerData *active = App::main()->activePeer(), *selected = _menuPeer ? _menuPeer : (_sel ? _sel->history()->peer : 0); PeerData *active = App::main()->activePeer(), *selected = _menuPeer ? _menuPeer : (_sel ? _sel->history()->peer : 0);
if (otherStart) { if (otherStart) {
shownDialogs()->all().paint(p, fullWidth(), dialogsClip.top(), dialogsClip.top() + dialogsClip.height(), active, selected, paintingOther); shownDialogs()->all().paint(p, fullWidth(), dialogsClip.top(), dialogsClip.top() + dialogsClip.height(), active, selected, paintingOther);
@ -109,7 +110,7 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
int32 to = ceilclamp(r.y() + r.height(), st::mentionHeight, 0, _hashtagResults.size()); int32 to = ceilclamp(r.y() + r.height(), st::mentionHeight, 0, _hashtagResults.size());
p.translate(0, from * st::mentionHeight); p.translate(0, from * st::mentionHeight);
if (from < _hashtagResults.size()) { if (from < _hashtagResults.size()) {
int32 w = fullWidth(), htagwidth = w - st::dlgPaddingHor * 2; int32 w = fullWidth(), htagwidth = w - st::dialogsPadding.x() * 2;
p.setFont(st::mentionFont->f); p.setFont(st::mentionFont->f);
p.setPen(st::black->p); p.setPen(st::black->p);
@ -135,11 +136,11 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
p.setFont(st::mentionFont->f); p.setFont(st::mentionFont->f);
if (!first.isEmpty()) { if (!first.isEmpty()) {
p.setPen((selected ? st::mentionFgOverActive : st::mentionFgActive)->p); p.setPen((selected ? st::mentionFgOverActive : st::mentionFgActive)->p);
p.drawText(st::dlgPaddingHor, st::mentionTop + st::mentionFont->ascent, first); p.drawText(st::dialogsPadding.x(), st::mentionTop + st::mentionFont->ascent, first);
} }
if (!second.isEmpty()) { if (!second.isEmpty()) {
p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p); p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p);
p.drawText(st::dlgPaddingHor + firstwidth, st::mentionTop + st::mentionFont->ascent, second); p.drawText(st::dialogsPadding.x() + firstwidth, st::mentionTop + st::mentionFont->ascent, second);
} }
} }
p.translate(0, st::mentionHeight); p.translate(0, st::mentionHeight);
@ -148,9 +149,9 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
} }
if (!_filterResults.isEmpty()) { if (!_filterResults.isEmpty()) {
int32 skip = filteredOffset(); int32 skip = filteredOffset();
int32 from = floorclamp(r.y() - skip, st::dlgHeight, 0, _filterResults.size()); int32 from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _filterResults.size());
int32 to = ceilclamp(r.y() + r.height() - skip, st::dlgHeight, 0, _filterResults.size()); int32 to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _filterResults.size());
p.translate(0, from * st::dlgHeight); p.translate(0, from * st::dialogsRowHeight);
if (from < _filterResults.size()) { if (from < _filterResults.size()) {
int32 w = fullWidth(); int32 w = fullWidth();
PeerData *act = App::main()->activePeer(); PeerData *act = App::main()->activePeer();
@ -159,7 +160,7 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
bool active = ((_filterResults[from]->history()->peer == act) || (_filterResults[from]->history()->peer->migrateTo() && _filterResults[from]->history()->peer->migrateTo() == act)) && !actId; bool active = ((_filterResults[from]->history()->peer == act) || (_filterResults[from]->history()->peer->migrateTo() && _filterResults[from]->history()->peer->migrateTo() == act)) && !actId;
bool selected = (from == _filteredSel) || (_filterResults[from]->history()->peer == _menuPeer); bool selected = (from == _filteredSel) || (_filterResults[from]->history()->peer == _menuPeer);
Dialogs::Layout::RowPainter::paint(p, _filterResults[from], w, active, selected, paintingOther); Dialogs::Layout::RowPainter::paint(p, _filterResults[from], w, active, selected, paintingOther);
p.translate(0, st::dlgHeight); p.translate(0, st::dialogsRowHeight);
} }
} }
} }
@ -174,9 +175,9 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
p.translate(0, st::searchedBarHeight); p.translate(0, st::searchedBarHeight);
int32 skip = peopleOffset(); int32 skip = peopleOffset();
int32 from = floorclamp(r.y() - skip, st::dlgHeight, 0, _peopleResults.size()); int32 from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _peopleResults.size());
int32 to = ceilclamp(r.y() + r.height() - skip, st::dlgHeight, 0, _peopleResults.size()); int32 to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _peopleResults.size());
p.translate(0, from * st::dlgHeight); p.translate(0, from * st::dialogsRowHeight);
if (from < _peopleResults.size()) { if (from < _peopleResults.size()) {
int32 w = fullWidth(); int32 w = fullWidth();
PeerData *act = App::main()->activePeer(); PeerData *act = App::main()->activePeer();
@ -185,14 +186,14 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
bool active = ((_peopleResults[from] == act) || (_peopleResults[from]->migrateTo() && _peopleResults[from]->migrateTo() == act)) && !actId; bool active = ((_peopleResults[from] == act) || (_peopleResults[from]->migrateTo() && _peopleResults[from]->migrateTo() == act)) && !actId;
bool selected = (from == _peopleSel); bool selected = (from == _peopleSel);
peopleResultPaint(_peopleResults[from], p, w, active, selected, paintingOther); peopleResultPaint(_peopleResults[from], p, w, active, selected, paintingOther);
p.translate(0, st::dlgHeight); p.translate(0, st::dialogsRowHeight);
} }
} }
} }
if (_searchInPeer) { if (_searchInPeer) {
searchInPeerPaint(p, fullWidth(), paintingOther); searchInPeerPaint(p, fullWidth(), paintingOther);
p.translate(0, st::dlgHeight); p.translate(0, st::dialogsRowHeight);
if (_state == FilteredState && _searchResults.isEmpty()) { if (_state == FilteredState && _searchResults.isEmpty()) {
p.fillRect(0, 0, fullWidth(), st::searchedBarHeight, st::searchedBarBG->b); p.fillRect(0, 0, fullWidth(), st::searchedBarHeight, st::searchedBarBG->b);
if (!paintingOther) { if (!paintingOther) {
@ -215,9 +216,9 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
p.translate(0, st::searchedBarHeight); p.translate(0, st::searchedBarHeight);
int32 skip = searchedOffset(); int32 skip = searchedOffset();
int32 from = floorclamp(r.y() - skip, st::dlgHeight, 0, _searchResults.size()); int32 from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _searchResults.size());
int32 to = ceilclamp(r.y() + r.height() - skip, st::dlgHeight, 0, _searchResults.size()); int32 to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _searchResults.size());
p.translate(0, from * st::dlgHeight); p.translate(0, from * st::dialogsRowHeight);
if (from < _searchResults.size()) { if (from < _searchResults.size()) {
int32 w = fullWidth(); int32 w = fullWidth();
PeerData *act = App::main()->activePeer(); PeerData *act = App::main()->activePeer();
@ -229,7 +230,7 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
bool active = (history->peer == act && item->id == actId) || (history->peer->migrateTo() && history->peer->migrateTo() == act && item->id == -actId); bool active = (history->peer == act && item->id == actId) || (history->peer->migrateTo() && history->peer->migrateTo() == act && item->id == -actId);
bool selected = (from == _searchedSel); bool selected = (from == _searchedSel);
Dialogs::Layout::RowPainter::paint(p, result, w, active, selected, paintingOther); Dialogs::Layout::RowPainter::paint(p, result, w, active, selected, paintingOther);
p.translate(0, st::dlgHeight); p.translate(0, st::dialogsRowHeight);
} }
} }
} }
@ -237,80 +238,80 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
} }
void DialogsInner::peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool active, bool selected, bool onlyBackground) const { void DialogsInner::peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool active, bool selected, bool onlyBackground) const {
QRect fullRect(0, 0, w, st::dlgHeight); QRect fullRect(0, 0, w, st::dialogsRowHeight);
p.fillRect(fullRect, active ? st::dlgActiveBG : (selected ? st::dlgHoverBG : st::dlgBG)); p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
if (onlyBackground) return; if (onlyBackground) return;
PeerData *userpicPeer = (peer->migrateTo() ? peer->migrateTo() : peer); PeerData *userpicPeer = (peer->migrateTo() ? peer->migrateTo() : peer);
userpicPeer->paintUserpicLeft(p, st::dlgPhotoSize, st::dlgPaddingHor, st::dlgPaddingVer, fullWidth()); userpicPeer->paintUserpicLeft(p, st::dialogsPhotoSize, st::dialogsPadding.x(), st::dialogsPadding.y(), fullWidth());
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding; int32 nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
int32 namewidth = w - nameleft - st::dlgPaddingHor; int32 namewidth = w - nameleft - st::dialogsPadding.x();
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height); QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height);
// draw chat icon // draw chat icon
if (peer->isChat() || peer->isMegagroup()) { if (peer->isChat() || peer->isMegagroup()) {
p.drawSprite(QPoint(rectForName.left() + st::dlgChatImgPos.x(), rectForName.top() + st::dlgChatImgPos.y()), (active ? st::dlgActiveChatImg : st::dlgChatImg)); p.drawSprite(QPoint(rectForName.left() + st::dialogsChatImgPos.x(), rectForName.top() + st::dialogsChatImgPos.y()), (active ? st::dlgActiveChatImg : st::dlgChatImg));
rectForName.setLeft(rectForName.left() + st::dlgImgSkip); rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
} else if (peer->isChannel()) { } else if (peer->isChannel()) {
p.drawSprite(QPoint(rectForName.left() + st::dlgChannelImgPos.x(), rectForName.top() + st::dlgChannelImgPos.y()), (active ? st::dlgActiveChannelImg : st::dlgChannelImg)); p.drawSprite(QPoint(rectForName.left() + st::dialogsChannelImgPos.x(), rectForName.top() + st::dialogsChannelImgPos.y()), (active ? st::dlgActiveChannelImg : st::dlgChannelImg));
rectForName.setLeft(rectForName.left() + st::dlgImgSkip); rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
} }
if (peer->isVerified()) { if (peer->isVerified()) {
rectForName.setWidth(rectForName.width() - st::verifiedCheck.pxWidth() - st::verifiedCheckPos.x()); rectForName.setWidth(rectForName.width() - st::verifiedCheck.pxWidth() - st::verifiedCheckPos.x());
p.drawSprite(rectForName.topLeft() + QPoint(qMin(peer->dialogName().maxWidth(), rectForName.width()), 0) + st::verifiedCheckPos, (active ? st::verifiedCheckInv : st::verifiedCheck)); p.drawSprite(rectForName.topLeft() + QPoint(qMin(peer->dialogName().maxWidth(), rectForName.width()), 0) + st::verifiedCheckPos, (active ? st::verifiedCheckInv : st::verifiedCheck));
} }
QRect tr(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, namewidth, st::dlgFont->height); QRect tr(nameleft, st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip, namewidth, st::dialogsTextFont->height);
p.setFont(st::dlgHistFont->f); p.setFont(st::dialogsTextFont);
QString username = peer->userName(); QString username = peer->userName();
if (!active && username.toLower().startsWith(_peopleQuery)) { if (!active && username.toLower().startsWith(_peopleQuery)) {
QString first = '@' + username.mid(0, _peopleQuery.size()), second = username.mid(_peopleQuery.size()); QString first = '@' + username.mid(0, _peopleQuery.size()), second = username.mid(_peopleQuery.size());
int32 w = st::dlgHistFont->width(first); int32 w = st::dialogsTextFont->width(first);
if (w >= tr.width()) { if (w >= tr.width()) {
p.setPen(st::dlgSystemColor->p); p.setPen(st::dialogsTextFgService);
p.drawText(tr.left(), tr.top() + st::dlgHistFont->ascent, st::dlgHistFont->elided(first, tr.width())); p.drawText(tr.left(), tr.top() + st::dialogsTextFont->ascent, st::dialogsTextFont->elided(first, tr.width()));
} else { } else {
p.setPen(st::dlgSystemColor->p); p.setPen(st::dialogsTextFgService);
p.drawText(tr.left(), tr.top() + st::dlgHistFont->ascent, first); p.drawText(tr.left(), tr.top() + st::dialogsTextFont->ascent, first);
p.setPen(st::dlgTextColor->p); p.setPen(st::dialogsTextFg);
p.drawText(tr.left() + w, tr.top() + st::dlgHistFont->ascent, st::dlgHistFont->elided(second, tr.width() - w)); p.drawText(tr.left() + w, tr.top() + st::dialogsTextFont->ascent, st::dialogsTextFont->elided(second, tr.width() - w));
} }
} else { } else {
p.setPen((active ? st::dlgActiveColor : st::dlgSystemColor)->p); p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFgService);
p.drawText(tr.left(), tr.top() + st::dlgHistFont->ascent, st::dlgHistFont->elided('@' + username, tr.width())); p.drawText(tr.left(), tr.top() + st::dialogsTextFont->ascent, st::dialogsTextFont->elided('@' + username, tr.width()));
} }
p.setPen((active ? st::dlgActiveColor : st::dlgNameColor)->p); p.setPen(active ? st::dialogsTextFgActive : st::dialogsNameFg);
peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
} }
void DialogsInner::searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) const { void DialogsInner::searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) const {
QRect fullRect(0, 0, w, st::dlgHeight); QRect fullRect(0, 0, w, st::dialogsRowHeight);
p.fillRect(fullRect, st::dlgBG->b); p.fillRect(fullRect, st::dialogsBg);
if (onlyBackground) return; if (onlyBackground) return;
_searchInPeer->paintUserpicLeft(p, st::dlgPhotoSize, st::dlgPaddingHor, st::dlgPaddingVer, fullWidth()); _searchInPeer->paintUserpicLeft(p, st::dialogsPhotoSize, st::dialogsPadding.x(), st::dialogsPadding.y(), fullWidth());
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding; int32 nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
int32 namewidth = w - nameleft - st::dlgPaddingHor * 2 - st::btnCancelSearch.width; int32 namewidth = w - nameleft - st::dialogsPadding.x() * 2 - st::btnCancelSearch.width;
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height); QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height);
// draw chat icon // draw chat icon
if (_searchInPeer->isChat() || _searchInPeer->isMegagroup()) { if (_searchInPeer->isChat() || _searchInPeer->isMegagroup()) {
p.drawSprite(QPoint(rectForName.left() + st::dlgChatImgPos.x(), rectForName.top() + st::dlgChatImgPos.y()), st::dlgChatImg); p.drawSprite(QPoint(rectForName.left() + st::dialogsChatImgPos.x(), rectForName.top() + st::dialogsChatImgPos.y()), st::dlgChatImg);
rectForName.setLeft(rectForName.left() + st::dlgImgSkip); rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
} else if (_searchInPeer->isChannel()) { } else if (_searchInPeer->isChannel()) {
p.drawSprite(QPoint(rectForName.left() + st::dlgChannelImgPos.x(), rectForName.top() + st::dlgChannelImgPos.y()), st::dlgChannelImg); p.drawSprite(QPoint(rectForName.left() + st::dialogsChannelImgPos.x(), rectForName.top() + st::dialogsChannelImgPos.y()), st::dlgChannelImg);
rectForName.setLeft(rectForName.left() + st::dlgImgSkip); rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
} }
QRect tr(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, namewidth, st::dlgFont->height); QRect tr(nameleft, st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip, namewidth, st::dialogsTextFont->height);
p.setFont(st::dlgHistFont->f); p.setFont(st::dialogsTextFont);
p.setPen(st::dlgTextColor->p); p.setPen(st::dialogsTextFg);
p.drawText(tr.left(), tr.top() + st::dlgHistFont->ascent, st::dlgHistFont->elided(lang((_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) ? lng_dlg_search_channel : lng_dlg_search_chat), tr.width())); p.drawText(tr.left(), tr.top() + st::dialogsTextFont->ascent, st::dialogsTextFont->elided(lang((_searchInPeer->isChannel() && !_searchInPeer->isMegagroup()) ? lng_dlg_search_channel : lng_dlg_search_chat), tr.width()));
p.setPen(st::dlgNameColor->p); p.setPen(st::dialogsNameFg);
_searchInPeer->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); _searchInPeer->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
} }
@ -332,7 +333,7 @@ void DialogsInner::onUpdateSelected(bool force) {
if (_state == DefaultState) { if (_state == DefaultState) {
auto newImportantSwitchSel = (importantDialogs && mouseY >= 0 && mouseY < dialogsOffset()); auto newImportantSwitchSel = (importantDialogs && mouseY >= 0 && mouseY < dialogsOffset());
mouseY -= dialogsOffset(); mouseY -= dialogsOffset();
auto newSel = newImportantSwitchSel ? nullptr : shownDialogs()->rowAtY(mouseY, st::dlgHeight); auto newSel = newImportantSwitchSel ? nullptr : shownDialogs()->rowAtY(mouseY, st::dialogsRowHeight);
if (newSel != _sel || newImportantSwitchSel != _importantSwitchSel) { if (newSel != _sel || newImportantSwitchSel != _importantSwitchSel) {
updateSelectedRow(); updateSelectedRow();
_sel = newSel; _sel = newSel;
@ -357,7 +358,7 @@ void DialogsInner::onUpdateSelected(bool force) {
} }
} }
if (!_filterResults.isEmpty()) { if (!_filterResults.isEmpty()) {
int32 skip = filteredOffset(), newFilteredSel = (mouseY >= skip) ? ((mouseY - skip) / int32(st::dlgHeight)) : -1; int32 skip = filteredOffset(), newFilteredSel = (mouseY >= skip) ? ((mouseY - skip) / int32(st::dialogsRowHeight)) : -1;
if (newFilteredSel < 0 || newFilteredSel >= _filterResults.size()) { if (newFilteredSel < 0 || newFilteredSel >= _filterResults.size()) {
newFilteredSel = -1; newFilteredSel = -1;
} }
@ -369,7 +370,7 @@ void DialogsInner::onUpdateSelected(bool force) {
} }
} }
if (!_peopleResults.isEmpty()) { if (!_peopleResults.isEmpty()) {
int32 skip = peopleOffset(), newPeopleSel = (mouseY >= skip) ? ((mouseY - skip) / int32(st::dlgHeight)) : -1; int32 skip = peopleOffset(), newPeopleSel = (mouseY >= skip) ? ((mouseY - skip) / int32(st::dialogsRowHeight)) : -1;
if (newPeopleSel < 0 || newPeopleSel >= _peopleResults.size()) { if (newPeopleSel < 0 || newPeopleSel >= _peopleResults.size()) {
newPeopleSel = -1; newPeopleSel = -1;
} }
@ -381,7 +382,7 @@ void DialogsInner::onUpdateSelected(bool force) {
} }
} }
if (_state == SearchedState && !_searchResults.isEmpty()) { if (_state == SearchedState && !_searchResults.isEmpty()) {
int32 skip = searchedOffset(), newSearchedSel = (mouseY >= skip) ? ((mouseY - skip) / int32(st::dlgHeight)) : -1; int32 skip = searchedOffset(), newSearchedSel = (mouseY >= skip) ? ((mouseY - skip) / int32(st::dialogsRowHeight)) : -1;
if (newSearchedSel < 0 || newSearchedSel >= _searchResults.size()) { if (newSearchedSel < 0 || newSearchedSel >= _searchResults.size()) {
newSearchedSel = -1; newSearchedSel = -1;
} }
@ -406,7 +407,7 @@ void DialogsInner::mousePressEvent(QMouseEvent *e) {
void DialogsInner::resizeEvent(QResizeEvent *e) { void DialogsInner::resizeEvent(QResizeEvent *e) {
_addContactLnk.move((width() - _addContactLnk.width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2); _addContactLnk.move((width() - _addContactLnk.width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2);
_cancelSearchInPeer.move(width() - st::dlgPaddingHor - st::btnCancelSearch.width, (st::dlgHeight - st::btnCancelSearch.height) / 2); _cancelSearchInPeer.move(width() - st::dialogsPadding.x() - st::btnCancelSearch.width, (st::dialogsRowHeight - st::btnCancelSearch.height) / 2);
} }
void DialogsInner::onDialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRow) { void DialogsInner::onDialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRow) {
@ -457,14 +458,14 @@ void DialogsInner::createDialog(History *history) {
} }
} }
int from = dialogsOffset() + changed.movedFrom * st::dlgHeight; int from = dialogsOffset() + changed.movedFrom * st::dialogsRowHeight;
int to = dialogsOffset() + changed.movedTo * st::dlgHeight; int to = dialogsOffset() + changed.movedTo * st::dialogsRowHeight;
emit dialogMoved(from, to); emit dialogMoved(from, to);
if (creating) { if (creating) {
refresh(); refresh();
} else if (_state == DefaultState && changed.movedFrom != changed.movedTo) { } else if (_state == DefaultState && changed.movedFrom != changed.movedTo) {
update(0, qMin(from, to), fullWidth(), qAbs(from - to) + st::dlgHeight); update(0, qMin(from, to), fullWidth(), qAbs(from - to) + st::dialogsRowHeight);
} }
} }
@ -498,13 +499,13 @@ void DialogsInner::removeDialog(History *history) {
void DialogsInner::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) { void DialogsInner::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
if (_state == DefaultState) { if (_state == DefaultState) {
if (Global::DialogsMode() == list) { if (Global::DialogsMode() == list) {
update(0, dialogsOffset() + row->pos() * st::dlgHeight, fullWidth(), st::dlgHeight); update(0, dialogsOffset() + row->pos() * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
} }
} else if (_state == FilteredState || _state == SearchedState) { } else if (_state == FilteredState || _state == SearchedState) {
if (list == Dialogs::Mode::All) { if (list == Dialogs::Mode::All) {
for (int32 i = 0, l = _filterResults.size(); i < l; ++i) { for (int32 i = 0, l = _filterResults.size(); i < l; ++i) {
if (_filterResults.at(i)->history() == row->history()) { if (_filterResults.at(i)->history() == row->history()) {
update(0, i * st::dlgHeight, fullWidth(), st::dlgHeight); update(0, i * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
break; break;
} }
} }
@ -515,13 +516,13 @@ void DialogsInner::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
void DialogsInner::dlgUpdated(History *history, MsgId msgId) { void DialogsInner::dlgUpdated(History *history, MsgId msgId) {
if (_state == DefaultState) { if (_state == DefaultState) {
if (auto row = shownDialogs()->getRow(history->peer->id)) { if (auto row = shownDialogs()->getRow(history->peer->id)) {
update(0, dialogsOffset() + row->pos() * st::dlgHeight, fullWidth(), st::dlgHeight); update(0, dialogsOffset() + row->pos() * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
} }
} else if (_state == FilteredState || _state == SearchedState) { } else if (_state == FilteredState || _state == SearchedState) {
int32 cnt = 0, add = filteredOffset(); int32 cnt = 0, add = filteredOffset();
for (FilteredDialogs::const_iterator i = _filterResults.cbegin(), e = _filterResults.cend(); i != e; ++i) { for (FilteredDialogs::const_iterator i = _filterResults.cbegin(), e = _filterResults.cend(); i != e; ++i) {
if ((*i)->history() == history) { if ((*i)->history() == history) {
update(0, add + cnt * st::dlgHeight, fullWidth(), st::dlgHeight); update(0, add + cnt * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
break; break;
} }
++cnt; ++cnt;
@ -530,7 +531,7 @@ void DialogsInner::dlgUpdated(History *history, MsgId msgId) {
int32 cnt = 0, add = peopleOffset(); int32 cnt = 0, add = peopleOffset();
for (PeopleResults::const_iterator i = _peopleResults.cbegin(), e = _peopleResults.cend(); i != e; ++i) { for (PeopleResults::const_iterator i = _peopleResults.cbegin(), e = _peopleResults.cend(); i != e; ++i) {
if ((*i) == history->peer) { if ((*i) == history->peer) {
update(0, add + cnt * st::dlgHeight, fullWidth(), st::dlgHeight); update(0, add + cnt * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
break; break;
} }
++cnt; ++cnt;
@ -540,7 +541,7 @@ void DialogsInner::dlgUpdated(History *history, MsgId msgId) {
int32 cnt = 0, add = searchedOffset(); int32 cnt = 0, add = searchedOffset();
for (SearchResults::const_iterator i = _searchResults.cbegin(), e = _searchResults.cend(); i != e; ++i) { for (SearchResults::const_iterator i = _searchResults.cbegin(), e = _searchResults.cend(); i != e; ++i) {
if ((*i)->item()->history() == history && (*i)->item()->id == msgId) { if ((*i)->item()->history() == history && (*i)->item()->id == msgId) {
update(0, add + cnt * st::dlgHeight, fullWidth(), st::dlgHeight); update(0, add + cnt * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
break; break;
} }
++cnt; ++cnt;
@ -560,30 +561,30 @@ void DialogsInner::updateSelectedRow(PeerData *peer) {
if (peer) { if (peer) {
if (History *h = App::historyLoaded(peer->id)) { if (History *h = App::historyLoaded(peer->id)) {
if (h->inChatList(Global::DialogsMode())) { if (h->inChatList(Global::DialogsMode())) {
update(0, dialogsOffset() + h->posInChatList(Global::DialogsMode()) * st::dlgHeight, fullWidth(), st::dlgHeight); update(0, dialogsOffset() + h->posInChatList(Global::DialogsMode()) * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
} }
} }
} else if (_sel) { } else if (_sel) {
update(0, dialogsOffset() + _sel->pos() * st::dlgHeight, fullWidth(), st::dlgHeight); update(0, dialogsOffset() + _sel->pos() * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
} else if (_importantSwitchSel) { } else if (_importantSwitchSel) {
update(0, 0, fullWidth(), st::dlgImportantHeight); update(0, 0, fullWidth(), st::dialogsImportantBarHeight);
} }
} else if (_state == FilteredState || _state == SearchedState) { } else if (_state == FilteredState || _state == SearchedState) {
if (peer) { if (peer) {
for (int32 i = 0, l = _filterResults.size(); i != l; ++i) { for (int32 i = 0, l = _filterResults.size(); i != l; ++i) {
if (_filterResults.at(i)->history()->peer == peer) { if (_filterResults.at(i)->history()->peer == peer) {
update(0, filteredOffset() + i * st::dlgHeight, fullWidth(), st::dlgHeight); update(0, filteredOffset() + i * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
break; break;
} }
} }
} else if (_hashtagSel >= 0) { } else if (_hashtagSel >= 0) {
update(0, _hashtagSel * st::mentionHeight, fullWidth(), st::mentionHeight); update(0, _hashtagSel * st::mentionHeight, fullWidth(), st::mentionHeight);
} else if (_filteredSel >= 0) { } else if (_filteredSel >= 0) {
update(0, filteredOffset() + _filteredSel * st::dlgHeight, fullWidth(), st::dlgHeight); update(0, filteredOffset() + _filteredSel * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
} else if (_peopleSel >= 0) { } else if (_peopleSel >= 0) {
update(0, peopleOffset() + _peopleSel * st::dlgHeight, fullWidth(), st::dlgHeight); update(0, peopleOffset() + _peopleSel * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
} else if (_searchedSel >= 0) { } else if (_searchedSel >= 0) {
update(0, searchedOffset() + _searchedSel * st::dlgHeight, fullWidth(), st::dlgHeight); update(0, searchedOffset() + _searchedSel * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
} }
} }
@ -1156,14 +1157,14 @@ void DialogsInner::notify_historyMuteUpdated(History *history) {
return; return;
} }
int from = dialogsOffset() + changed.movedFrom * st::dlgHeight; int from = dialogsOffset() + changed.movedFrom * st::dialogsRowHeight;
int to = dialogsOffset() + changed.movedTo * st::dlgHeight; int to = dialogsOffset() + changed.movedTo * st::dialogsRowHeight;
emit dialogMoved(from, to); emit dialogMoved(from, to);
if (creating) { if (creating) {
refresh(); refresh();
} else if (_state == DefaultState && changed.movedFrom != changed.movedTo) { } else if (_state == DefaultState && changed.movedFrom != changed.movedTo) {
update(0, qMin(from, to), fullWidth(), qAbs(from - to) + st::dlgHeight); update(0, qMin(from, to), fullWidth(), qAbs(from - to) + st::dialogsRowHeight);
} }
} }
} }
@ -1179,15 +1180,15 @@ void DialogsInner::refresh(bool toTop) {
if (!_addContactLnk.isHidden()) _addContactLnk.hide(); if (!_addContactLnk.isHidden()) _addContactLnk.hide();
} }
} else { } else {
h = dialogsOffset() + shownDialogs()->size() * st::dlgHeight; h = dialogsOffset() + shownDialogs()->size() * st::dialogsRowHeight;
if (!_addContactLnk.isHidden()) _addContactLnk.hide(); if (!_addContactLnk.isHidden()) _addContactLnk.hide();
} }
} else { } else {
if (!_addContactLnk.isHidden()) _addContactLnk.hide(); if (!_addContactLnk.isHidden()) _addContactLnk.hide();
if (_state == FilteredState) { if (_state == FilteredState) {
h = searchedOffset() + (_searchResults.count() * st::dlgHeight) + ((_searchResults.isEmpty() && !_searchInPeer) ? -st::searchedBarHeight : 0); h = searchedOffset() + (_searchResults.count() * st::dialogsRowHeight) + ((_searchResults.isEmpty() && !_searchInPeer) ? -st::searchedBarHeight : 0);
} else if (_state == SearchedState) { } else if (_state == SearchedState) {
h = searchedOffset() + (_searchResults.count() * st::dlgHeight); h = searchedOffset() + (_searchResults.count() * st::dialogsRowHeight);
} }
} }
setHeight(h); setHeight(h);
@ -1295,8 +1296,8 @@ void DialogsInner::selectSkip(int32 direction) {
} }
} }
if (_importantSwitchSel || _sel) { if (_importantSwitchSel || _sel) {
int fromY = _importantSwitchSel ? 0 : (dialogsOffset() + _sel->pos() * st::dlgHeight); int fromY = _importantSwitchSel ? 0 : (dialogsOffset() + _sel->pos() * st::dialogsRowHeight);
emit mustScrollTo(fromY, fromY + st::dlgHeight); emit mustScrollTo(fromY, fromY + st::dialogsRowHeight);
} }
} else if (_state == FilteredState || _state == SearchedState) { } else if (_state == FilteredState || _state == SearchedState) {
if (_hashtagResults.isEmpty() && _filterResults.isEmpty() && _peopleResults.isEmpty() && _searchResults.isEmpty()) return; if (_hashtagResults.isEmpty() && _filterResults.isEmpty() && _peopleResults.isEmpty() && _searchResults.isEmpty()) return;
@ -1333,11 +1334,11 @@ void DialogsInner::selectSkip(int32 direction) {
if (_hashtagSel >= 0 && _hashtagSel < _hashtagResults.size()) { if (_hashtagSel >= 0 && _hashtagSel < _hashtagResults.size()) {
emit mustScrollTo(_hashtagSel * st::mentionHeight, (_hashtagSel + 1) * st::mentionHeight); emit mustScrollTo(_hashtagSel * st::mentionHeight, (_hashtagSel + 1) * st::mentionHeight);
} else if (_filteredSel >= 0 && _filteredSel < _filterResults.size()) { } else if (_filteredSel >= 0 && _filteredSel < _filterResults.size()) {
emit mustScrollTo(filteredOffset() + _filteredSel * st::dlgHeight, filteredOffset() + (_filteredSel + 1) * st::dlgHeight); emit mustScrollTo(filteredOffset() + _filteredSel * st::dialogsRowHeight, filteredOffset() + (_filteredSel + 1) * st::dialogsRowHeight);
} else if (_peopleSel >= 0 && _peopleSel < _peopleResults.size()) { } else if (_peopleSel >= 0 && _peopleSel < _peopleResults.size()) {
emit mustScrollTo(peopleOffset() + _peopleSel * st::dlgHeight + (_peopleSel ? 0 : -st::searchedBarHeight), peopleOffset() + (_peopleSel + 1) * st::dlgHeight); emit mustScrollTo(peopleOffset() + _peopleSel * st::dialogsRowHeight + (_peopleSel ? 0 : -st::searchedBarHeight), peopleOffset() + (_peopleSel + 1) * st::dialogsRowHeight);
} else { } else {
emit mustScrollTo(searchedOffset() + _searchedSel * st::dlgHeight + (_searchedSel ? 0 : -st::searchedBarHeight), searchedOffset() + (_searchedSel + 1) * st::dlgHeight); emit mustScrollTo(searchedOffset() + _searchedSel * st::dialogsRowHeight + (_searchedSel ? 0 : -st::searchedBarHeight), searchedOffset() + (_searchedSel + 1) * st::dialogsRowHeight);
} }
} }
update(); update();
@ -1347,13 +1348,13 @@ void DialogsInner::scrollToPeer(const PeerId &peer, MsgId msgId) {
int32 fromY = -1; int32 fromY = -1;
if (_state == DefaultState) { if (_state == DefaultState) {
if (auto row = shownDialogs()->getRow(peer)) { if (auto row = shownDialogs()->getRow(peer)) {
fromY = dialogsOffset() + row->pos() * st::dlgHeight; fromY = dialogsOffset() + row->pos() * st::dialogsRowHeight;
} }
} else if (_state == FilteredState || _state == SearchedState) { } else if (_state == FilteredState || _state == SearchedState) {
if (msgId) { if (msgId) {
for (int32 i = 0, c = _searchResults.size(); i < c; ++i) { for (int32 i = 0, c = _searchResults.size(); i < c; ++i) {
if (_searchResults[i]->item()->history()->peer->id == peer && _searchResults[i]->item()->id == msgId) { if (_searchResults[i]->item()->history()->peer->id == peer && _searchResults[i]->item()->id == msgId) {
fromY = searchedOffset() + i * st::dlgHeight; fromY = searchedOffset() + i * st::dialogsRowHeight;
break; break;
} }
} }
@ -1361,19 +1362,19 @@ void DialogsInner::scrollToPeer(const PeerId &peer, MsgId msgId) {
if (fromY < 0) { if (fromY < 0) {
for (int32 i = 0, c = _filterResults.size(); i < c; ++i) { for (int32 i = 0, c = _filterResults.size(); i < c; ++i) {
if (_filterResults[i]->history()->peer->id == peer) { if (_filterResults[i]->history()->peer->id == peer) {
fromY = filteredOffset() + (i * st::dlgHeight); fromY = filteredOffset() + (i * st::dialogsRowHeight);
break; break;
} }
} }
} }
} }
if (fromY >= 0) { if (fromY >= 0) {
emit mustScrollTo(fromY, fromY + st::dlgHeight); emit mustScrollTo(fromY, fromY + st::dialogsRowHeight);
} }
} }
void DialogsInner::selectSkipPage(int32 pixels, int32 direction) { void DialogsInner::selectSkipPage(int32 pixels, int32 direction) {
int toSkip = pixels / int(st::dlgHeight); int toSkip = pixels / int(st::dialogsRowHeight);
if (_state == DefaultState) { if (_state == DefaultState) {
if (!_sel) { if (!_sel) {
if (direction > 0 && !shownDialogs()->isEmpty()) { if (direction > 0 && !shownDialogs()->isEmpty()) {
@ -1397,8 +1398,8 @@ void DialogsInner::selectSkipPage(int32 pixels, int32 direction) {
} }
} }
if (_importantSwitchSel || _sel) { if (_importantSwitchSel || _sel) {
int fromY = (_importantSwitchSel ? 0 : (dialogsOffset() + _sel->pos() * st::dlgHeight)); int fromY = (_importantSwitchSel ? 0 : (dialogsOffset() + _sel->pos() * st::dialogsRowHeight));
emit mustScrollTo(fromY, fromY + st::dlgHeight); emit mustScrollTo(fromY, fromY + st::dialogsRowHeight);
} }
} else { } else {
return selectSkip(direction * toSkip); return selectSkip(direction * toSkip);
@ -1412,10 +1413,10 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
int32 yTo = yFrom + parentWidget()->height() * 5; int32 yTo = yFrom + parentWidget()->height() * 5;
MTP::clearLoaderPriorities(); MTP::clearLoaderPriorities();
if (_state == DefaultState) { if (_state == DefaultState) {
int32 otherStart = shownDialogs()->size() * st::dlgHeight; int32 otherStart = shownDialogs()->size() * st::dialogsRowHeight;
if (yFrom < otherStart) { if (yFrom < otherStart) {
for (auto i = shownDialogs()->cfind(yFrom, st::dlgHeight), end = shownDialogs()->cend(); i != end; ++i) { for (auto i = shownDialogs()->cfind(yFrom, st::dialogsRowHeight), end = shownDialogs()->cend(); i != end; ++i) {
if (((*i)->pos() * st::dlgHeight) >= yTo) { if (((*i)->pos() * st::dialogsRowHeight) >= yTo) {
break; break;
} }
(*i)->history()->peer->loadUserpic(); (*i)->history()->peer->loadUserpic();
@ -1426,10 +1427,10 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
} }
yTo -= otherStart; yTo -= otherStart;
} else if (_state == FilteredState || _state == SearchedState) { } else if (_state == FilteredState || _state == SearchedState) {
int32 from = (yFrom - filteredOffset()) / st::dlgHeight; int32 from = (yFrom - filteredOffset()) / st::dialogsRowHeight;
if (from < 0) from = 0; if (from < 0) from = 0;
if (from < _filterResults.size()) { if (from < _filterResults.size()) {
int32 to = (yTo / int32(st::dlgHeight)) + 1, w = width(); int32 to = (yTo / int32(st::dialogsRowHeight)) + 1, w = width();
if (to > _filterResults.size()) to = _filterResults.size(); if (to > _filterResults.size()) to = _filterResults.size();
for (; from < to; ++from) { for (; from < to; ++from) {
@ -1437,20 +1438,20 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
} }
} }
from = (yFrom > filteredOffset() + st::searchedBarHeight ? ((yFrom - filteredOffset() - st::searchedBarHeight) / int32(st::dlgHeight)) : 0) - _filterResults.size(); from = (yFrom > filteredOffset() + st::searchedBarHeight ? ((yFrom - filteredOffset() - st::searchedBarHeight) / int32(st::dialogsRowHeight)) : 0) - _filterResults.size();
if (from < 0) from = 0; if (from < 0) from = 0;
if (from < _peopleResults.size()) { if (from < _peopleResults.size()) {
int32 to = (yTo > filteredOffset() + st::searchedBarHeight ? ((yTo - filteredOffset() - st::searchedBarHeight) / int32(st::dlgHeight)) : 0) - _filterResults.size() + 1, w = width(); int32 to = (yTo > filteredOffset() + st::searchedBarHeight ? ((yTo - filteredOffset() - st::searchedBarHeight) / int32(st::dialogsRowHeight)) : 0) - _filterResults.size() + 1, w = width();
if (to > _peopleResults.size()) to = _peopleResults.size(); if (to > _peopleResults.size()) to = _peopleResults.size();
for (; from < to; ++from) { for (; from < to; ++from) {
_peopleResults[from]->loadUserpic(); _peopleResults[from]->loadUserpic();
} }
} }
from = (yFrom > filteredOffset() + ((_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight) ? ((yFrom - filteredOffset() - (_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(st::dlgHeight)) : 0) - _filterResults.size() - _peopleResults.size(); from = (yFrom > filteredOffset() + ((_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight) ? ((yFrom - filteredOffset() - (_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(st::dialogsRowHeight)) : 0) - _filterResults.size() - _peopleResults.size();
if (from < 0) from = 0; if (from < 0) from = 0;
if (from < _searchResults.size()) { if (from < _searchResults.size()) {
int32 to = (yTo > filteredOffset() + (_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight ? ((yTo - filteredOffset() - (_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(st::dlgHeight)) : 0) - _filterResults.size() - _peopleResults.size() + 1, w = width(); int32 to = (yTo > filteredOffset() + (_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight ? ((yTo - filteredOffset() - (_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(st::dialogsRowHeight)) : 0) - _filterResults.size() - _peopleResults.size() + 1, w = width();
if (to > _searchResults.size()) to = _searchResults.size(); if (to > _searchResults.size()) to = _searchResults.size();
for (; from < to; ++from) { for (; from < to; ++from) {
@ -1761,7 +1762,7 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : TWidget(parent)
, _newGroup(this, st::btnNewGroup) , _newGroup(this, st::btnNewGroup)
, _addContact(this, st::btnAddContact) , _addContact(this, st::btnAddContact)
, _cancelSearch(this, st::btnCancelSearch) , _cancelSearch(this, st::btnCancelSearch)
, _scroll(this, st::dlgScroll) , _scroll(this, st::dialogsScroll)
, _inner(&_scroll, parent) , _inner(&_scroll, parent)
, _a_show(animation(this, &DialogsWidget::step_show)) , _a_show(animation(this, &DialogsWidget::step_show))
, _searchInPeer(0) , _searchInPeer(0)
@ -1800,15 +1801,15 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : TWidget(parent)
_scroll.show(); _scroll.show();
_filter.show(); _filter.show();
_filter.move(st::dlgPaddingHor, st::dlgFilterPadding); _filter.move(st::dialogsPadding.x(), st::dialogsFilterPadding);
_filter.setFocusPolicy(Qt::StrongFocus); _filter.setFocusPolicy(Qt::StrongFocus);
_filter.customUpDown(true); _filter.customUpDown(true);
_addContact.hide(); _addContact.hide();
_newGroup.show(); _newGroup.show();
_cancelSearch.hide(); _cancelSearch.hide();
_newGroup.move(width() - _newGroup.width() - st::dlgPaddingHor, 0); _newGroup.move(width() - _newGroup.width() - st::dialogsPadding.x(), 0);
_addContact.move(width() - _addContact.width() - st::dlgPaddingHor, 0); _addContact.move(width() - _addContact.width() - st::dialogsPadding.x(), 0);
_cancelSearch.move(width() - _cancelSearch.width() - st::dlgPaddingHor, 0); _cancelSearch.move(width() - _cancelSearch.width() - st::dialogsPadding.x(), 0);
} }
void DialogsWidget::activate() { void DialogsWidget::activate() {
@ -2342,10 +2343,10 @@ void DialogsWidget::onListScroll() {
_inner.loadPeerPhotos(_scroll.scrollTop()); _inner.loadPeerPhotos(_scroll.scrollTop());
if (_inner.state() == DialogsInner::SearchedState || (_inner.state() == DialogsInner::FilteredState && _searchInMigrated && _searchFull && !_searchFullMigrated)) { 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::dlgHeight - PreloadHeightsCount * _scroll.height()) { if (_scroll.scrollTop() > (_inner.searchList().size() + _inner.filteredList().size() + _inner.peopleList().size()) * st::dialogsRowHeight - PreloadHeightsCount * _scroll.height()) {
onSearchMore(); onSearchMore();
} }
} else if (_scroll.scrollTop() > _inner.dialogsList()->size() * st::dlgHeight - PreloadHeightsCount * _scroll.height()) { } else if (_scroll.scrollTop() > _inner.dialogsList()->size() * st::dialogsRowHeight - PreloadHeightsCount * _scroll.height()) {
loadDialogs(); loadDialogs();
} }
} }
@ -2425,15 +2426,15 @@ void DialogsWidget::onCompleteHashtag(QString tag) {
void DialogsWidget::resizeEvent(QResizeEvent *e) { void DialogsWidget::resizeEvent(QResizeEvent *e) {
int32 w = width(); int32 w = width();
_filter.setGeometry(st::dlgPaddingHor, st::dlgFilterPadding, w - 2 * st::dlgPaddingHor, _filter.height()); _filter.setGeometry(st::dialogsPadding.x(), st::dialogsFilterPadding, w - 2 * st::dialogsPadding.x(), _filter.height());
_newGroup.move(w - _newGroup.width() - st::dlgPaddingHor, _filter.y()); _newGroup.move(w - _newGroup.width() - st::dialogsPadding.x(), _filter.y());
_addContact.move(w - _addContact.width() - st::dlgPaddingHor, _filter.y()); _addContact.move(w - _addContact.width() - st::dialogsPadding.x(), _filter.y());
_cancelSearch.move(w - _cancelSearch.width() - st::dlgPaddingHor, _filter.y()); _cancelSearch.move(w - _cancelSearch.width() - st::dialogsPadding.x(), _filter.y());
_scroll.move(0, _filter.height() + 2 * st::dlgFilterPadding); _scroll.move(0, _filter.height() + 2 * st::dialogsFilterPadding);
int32 addToY = App::main() ? App::main()->contentScrollAddToY() : 0; int32 addToY = App::main() ? App::main()->contentScrollAddToY() : 0;
int32 newScrollY = _scroll.scrollTop() + addToY; int32 newScrollY = _scroll.scrollTop() + addToY;
_scroll.resize(w, height() - _filter.y() - _filter.height() - st::dlgFilterPadding - st::dlgPaddingVer); _scroll.resize(w, height() - _filter.y() - _filter.height() - st::dialogsFilterPadding - st::dialogsPadding.y());
if (addToY) { if (addToY) {
_scroll.scrollToY(newScrollY); _scroll.scrollToY(newScrollY);
} else { } else {
@ -2583,6 +2584,6 @@ void DialogsWidget::onCancelSearchInPeer() {
void DialogsWidget::onDialogMoved(int movedFrom, int movedTo) { void DialogsWidget::onDialogMoved(int movedFrom, int movedTo) {
int32 st = _scroll.scrollTop(); int32 st = _scroll.scrollTop();
if (st > movedTo && st < movedFrom) { if (st > movedTo && st < movedFrom) {
_scroll.scrollToY(st + st::dlgHeight); _scroll.scrollToY(st + st::dialogsRowHeight);
} }
} }

View File

@ -95,6 +95,8 @@ void activateBotCommand(const HistoryItem *msg, int row, int col) {
auto getMessageBot = [msg]() -> UserData* { auto getMessageBot = [msg]() -> UserData* {
if (auto bot = msg->viaBot()) { if (auto bot = msg->viaBot()) {
return bot; return bot;
} else if (auto bot = msg->from()->asUser()) {
return bot;
} else if (auto bot = msg->history()->peer->asUser()) { } else if (auto bot = msg->history()->peer->asUser()) {
return bot; return bot;
} }

View File

@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "core/click_handler_types.h" #include "core/click_handler_types.h"
#include "dialogs/dialogs_indexed_list.h" #include "dialogs/dialogs_indexed_list.h"
#include "styles/style_dialogs.h"
#include "lang.h" #include "lang.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "application.h" #include "application.h"
@ -73,7 +74,7 @@ TextParseOptions _instagramDescriptionOptions = {
inline void _initTextOptions() { inline void _initTextOptions() {
_historySrvOptions.dir = _textNameOptions.dir = _textDlgOptions.dir = cLangDir(); _historySrvOptions.dir = _textNameOptions.dir = _textDlgOptions.dir = cLangDir();
_textDlgOptions.maxw = st::dlgMaxWidth * 2; _textDlgOptions.maxw = st::dialogsWidthMax * 2;
_webpageTitleOptions.maxw = st::msgMaxWidth - st::msgPadding.left() - st::msgPadding.right() - st::webPageLeft; _webpageTitleOptions.maxw = st::msgMaxWidth - st::msgPadding.left() - st::msgPadding.right() - st::webPageLeft;
_webpageTitleOptions.maxh = st::webPageTitleFont->height * 2; _webpageTitleOptions.maxh = st::webPageTitleFont->height * 2;
_webpageDescriptionOptions.maxw = st::msgMaxWidth - st::msgPadding.left() - st::msgPadding.right() - st::webPageLeft; _webpageDescriptionOptions.maxw = st::msgMaxWidth - st::msgPadding.left() - st::msgPadding.right() - st::webPageLeft;
@ -129,6 +130,9 @@ void historyInit() {
History::History(const PeerId &peerId) History::History(const PeerId &peerId)
: peer(App::peer(peerId)) : peer(App::peer(peerId))
, lastItemTextCache(st::dialogsTextWidthMin)
, typingText(st::dialogsTextWidthMin)
, cloudDraftTextCache(st::dialogsTextWidthMin)
, _mute(isNotifyMuted(peer->notify)) { , _mute(isNotifyMuted(peer->notify)) {
if (peer->isUser() && peer->asUser()->botInfo) { if (peer->isUser() && peer->asUser()->botInfo) {
outboxReadBefore = INT_MAX; outboxReadBefore = INT_MAX;
@ -259,7 +263,7 @@ bool History::updateTyping(uint64 ms, bool force) {
newTypingStr += qsl("..."); newTypingStr += qsl("...");
} }
if (typingStr != newTypingStr) { if (typingStr != newTypingStr) {
typingText.setText(st::dlgHistFont, (typingStr = newTypingStr), _textNameOptions); typingText.setText(st::dialogsTextFont, (typingStr = newTypingStr), _textNameOptions);
} }
} }
if (!typingStr.isEmpty()) { if (!typingStr.isEmpty()) {
@ -7494,13 +7498,6 @@ HistoryTextState HistoryMessage::getState(int x, int y, HistoryStateRequest requ
} }
trect.setTop(trect.top() + fwdheight); trect.setTop(trect.top() + fwdheight);
} }
if (via && !displayFromName() && !displayForwardedFrom()) {
if (x >= trect.left() && y >= trect.top() && y < trect.top() + st::msgNameFont->height && x < trect.left() + via->_width) {
result.link = via->_lnk;
return result;
}
trect.setTop(trect.top() + st::msgNameFont->height);
}
if (reply) { if (reply) {
int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
if (y >= trect.top() && y < trect.top() + h) { if (y >= trect.top() && y < trect.top() + h) {
@ -7511,6 +7508,13 @@ HistoryTextState HistoryMessage::getState(int x, int y, HistoryStateRequest requ
} }
trect.setTop(trect.top() + h); trect.setTop(trect.top() + h);
} }
if (via && !displayFromName() && !displayForwardedFrom()) {
if (x >= trect.left() && y >= trect.top() && y < trect.top() + st::msgNameFont->height && x < trect.left() + via->_width) {
result.link = via->_lnk;
return result;
}
trect.setTop(trect.top() + st::msgNameFont->height);
}
bool inDate = false, mediaDisplayed = _media && _media->isDisplayed(); bool inDate = false, mediaDisplayed = _media && _media->isDisplayed();
if (!mediaDisplayed || !_media->customInfoLayout()) { if (!mediaDisplayed || !_media->customInfoLayout()) {
@ -7568,16 +7572,16 @@ void HistoryMessage::drawInDialog(Painter &p, const QRect &r, bool act, const Hi
TextCustomTagsMap custom; TextCustomTagsMap custom;
custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink())); custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
msg = lng_message_with_from(lt_from, textRichPrepare((author() == App::self()) ? lang(lng_from_you) : author()->shortName()), lt_message, textRichPrepare(msg)); msg = lng_message_with_from(lt_from, textRichPrepare((author() == App::self()) ? lang(lng_from_you) : author()->shortName()), lt_message, textRichPrepare(msg));
cache.setRichText(st::dlgHistFont, msg, _textDlgOptions, custom); cache.setRichText(st::dialogsTextFont, msg, _textDlgOptions, custom);
} else { } else {
cache.setText(st::dlgHistFont, msg, _textDlgOptions); cache.setText(st::dialogsTextFont, msg, _textDlgOptions);
} }
} }
if (r.width()) { if (r.width()) {
textstyleSet(&(act ? st::dlgActiveTextStyle : st::dlgTextStyle)); textstyleSet(&(act ? st::dialogsTextStyleActive : st::dialogsTextStyle));
p.setFont(st::dlgHistFont->f); p.setFont(st::dialogsTextFont);
p.setPen((act ? st::dlgActiveColor : (emptyText() ? st::dlgSystemColor : st::dlgTextColor))->p); p.setPen(act ? st::dialogsTextFgActive : (emptyText() ? st::dialogsTextFgService : st::dialogsTextFg));
cache.drawElided(p, r.left(), r.top(), r.width(), r.height() / st::dlgHistFont->height); cache.drawElided(p, r.left(), r.top(), r.width(), r.height() / st::dialogsTextFont->height);
textstyleRestore(); textstyleRestore();
} }
} }
@ -8087,11 +8091,11 @@ HistoryTextState HistoryService::getState(int x, int y, HistoryStateRequest requ
void HistoryService::drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const { void HistoryService::drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const {
if (cacheFor != this) { if (cacheFor != this) {
cacheFor = this; cacheFor = this;
cache.setText(st::dlgHistFont, inDialogsText(), _textDlgOptions); cache.setText(st::dialogsTextFont, inDialogsText(), _textDlgOptions);
} }
QRect tr(r); QRect tr(r);
p.setPen((act ? st::dlgActiveColor : st::dlgSystemColor)->p); p.setPen(act ? st::dialogsTextFgActive : st::dialogsTextFgService);
cache.drawElided(p, tr.left(), tr.top(), tr.width(), tr.height() / st::dlgHistFont->height); cache.drawElided(p, tr.left(), tr.top(), tr.width(), tr.height() / st::dialogsTextFont->height);
} }
QString HistoryService::notificationText() const { QString HistoryService::notificationText() const {

View File

@ -458,14 +458,14 @@ public:
mtpRequestId sendRequestId = 0; mtpRequestId sendRequestId = 0;
mutable const HistoryItem *textCachedFor = nullptr; // cache mutable const HistoryItem *textCachedFor = nullptr; // cache
mutable Text lastItemTextCache = Text{ int(st::dlgRichMinWidth) }; mutable Text lastItemTextCache;
typedef QMap<UserData*, uint64> TypingUsers; typedef QMap<UserData*, uint64> TypingUsers;
TypingUsers typing; TypingUsers typing;
typedef QMap<UserData*, SendAction> SendActionUsers; typedef QMap<UserData*, SendAction> SendActionUsers;
SendActionUsers sendActions; SendActionUsers sendActions;
QString typingStr; QString typingStr;
Text typingText = Text{ int(st::dlgRichMinWidth) }; Text typingText;
uint32 typingDots; uint32 typingDots;
QMap<SendActionType, uint64> mySendActions; QMap<SendActionType, uint64> mySendActions;
@ -504,7 +504,7 @@ public:
void changeMsgId(MsgId oldId, MsgId newId); void changeMsgId(MsgId oldId, MsgId newId);
Text cloudDraftTextCache = Text { int(st::dlgRichMinWidth) }; Text cloudDraftTextCache;
protected: protected:

View File

@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "historywidget.h" #include "historywidget.h"
#include "styles/style_history.h" #include "styles/style_history.h"
#include "styles/style_dialogs.h"
#include "boxes/confirmbox.h" #include "boxes/confirmbox.h"
#include "boxes/photosendbox.h" #include "boxes/photosendbox.h"
#include "ui/filedialog.h" #include "ui/filedialog.h"
@ -1552,6 +1553,15 @@ HistoryInner::~HistoryInner() {
_dragAction = NoDrag; _dragAction = NoDrag;
} }
bool HistoryInner::focusNextPrevChild(bool next) {
if (_selected.isEmpty()) {
return focusNextPrevChild(next);
} else {
clearSelectedItems();
return true;
}
}
void HistoryInner::adjustCurrent(int32 y) const { void HistoryInner::adjustCurrent(int32 y) const {
int32 htop = historyTop(), hdrawtop = historyDrawTop(), mtop = migratedTop(); int32 htop = historyTop(), hdrawtop = historyDrawTop(), mtop = migratedTop();
_curHistory = 0; _curHistory = 0;
@ -3036,15 +3046,17 @@ void HistoryWidget::applyInlineBotQuery(UserData *bot, const QString &query) {
} }
void HistoryWidget::updateStickersByEmoji() { void HistoryWidget::updateStickersByEmoji() {
int32 len = 0; int len = 0;
if (!_editMsgId) {
auto &text = _field.getTextWithTags().text; auto &text = _field.getTextWithTags().text;
if (EmojiPtr emoji = emojiFromText(text, &len)) { if (auto emoji = emojiFromText(text, &len)) {
if (text.size() > len) { if (text.size() > len) {
len = 0; len = 0;
} else { } else {
_fieldAutocomplete->showStickers(emoji); _fieldAutocomplete->showStickers(emoji);
} }
} }
}
if (!len) { if (!len) {
_fieldAutocomplete->showStickers(nullptr); _fieldAutocomplete->showStickers(nullptr);
} }
@ -3187,7 +3199,7 @@ void HistoryWidget::writeDrafts(HistoryDraft **localDraft, HistoryDraft **editDr
} }
if (!_editMsgId) { if (!_editMsgId) {
_saveCloudDraftTimer.start(SaveCloudDraftTimeout); _saveCloudDraftTimer.start(SaveCloudDraftIdleTimeout);
} }
} }
@ -4906,7 +4918,10 @@ bool HistoryWidget::joinFail(const RPCError &error, mtpRequestId req) {
if (error.type() == qstr("CHANNEL_PRIVATE") || error.type() == qstr("CHANNEL_PUBLIC_GROUP_NA") || error.type() == qstr("USER_BANNED_IN_CHANNEL")) { if (error.type() == qstr("CHANNEL_PRIVATE") || error.type() == qstr("CHANNEL_PUBLIC_GROUP_NA") || error.type() == qstr("USER_BANNED_IN_CHANNEL")) {
Ui::showLayer(new InformBox(lang((_peer && _peer->isMegagroup()) ? lng_group_not_accessible : lng_channel_not_accessible))); Ui::showLayer(new InformBox(lang((_peer && _peer->isMegagroup()) ? lng_group_not_accessible : lng_channel_not_accessible)));
return true; return true;
} else if (error.type() == qstr("CHANNELS_TOO_MUCH")) {
Ui::showLayer(new InformBox(lang(lng_join_channel_error)));
} }
return false; return false;
} }
@ -5801,16 +5816,16 @@ void HistoryWidget::paintTopBar(Painter &p, float64 over, int32 decreaseWidth) {
int32 increaseLeft = Adaptive::OneColumn() ? (st::topBarForwardPadding.right() - st::topBarForwardPadding.left()) : 0; int32 increaseLeft = Adaptive::OneColumn() ? (st::topBarForwardPadding.right() - st::topBarForwardPadding.left()) : 0;
decreaseWidth += increaseLeft; decreaseWidth += increaseLeft;
QRect rectForName(st::topBarForwardPadding.left() + increaseLeft, st::topBarForwardPadding.top(), width() - decreaseWidth - st::topBarForwardPadding.left() - st::topBarForwardPadding.right(), st::msgNameFont->height); QRect rectForName(st::topBarForwardPadding.left() + increaseLeft, st::topBarForwardPadding.top(), width() - decreaseWidth - st::topBarForwardPadding.left() - st::topBarForwardPadding.right(), st::msgNameFont->height);
p.setFont(st::dlgHistFont->f); p.setFont(st::dialogsTextFont);
if (_history->typing.isEmpty() && _history->sendActions.isEmpty()) { if (_history->typing.isEmpty() && _history->sendActions.isEmpty()) {
p.setPen(st::titleStatusColor->p); p.setPen(st::titleStatusColor->p);
p.drawText(rectForName.x(), st::topBarHeight - st::topBarForwardPadding.bottom() - st::dlgHistFont->height + st::dlgHistFont->ascent, _titlePeerText); p.drawText(rectForName.x(), st::topBarHeight - st::topBarForwardPadding.bottom() - st::dialogsTextFont->height + st::dialogsTextFont->ascent, _titlePeerText);
} else { } else {
p.setPen(st::titleTypingColor->p); p.setPen(st::titleTypingColor->p);
_history->typingText.drawElided(p, rectForName.x(), st::topBarHeight - st::topBarForwardPadding.bottom() - st::dlgHistFont->height, rectForName.width()); _history->typingText.drawElided(p, rectForName.x(), st::topBarHeight - st::topBarForwardPadding.bottom() - st::dialogsTextFont->height, rectForName.width());
} }
p.setPen(st::dlgNameColor->p); p.setPen(st::dialogsNameFg);
_peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); _peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
if (Adaptive::OneColumn()) { if (Adaptive::OneColumn()) {
@ -5882,7 +5897,7 @@ void HistoryWidget::updateOnlineDisplay(int32 x, int32 w) {
} }
if (_titlePeerText != text) { if (_titlePeerText != text) {
_titlePeerText = text; _titlePeerText = text;
_titlePeerTextWidth = st::dlgHistFont->width(_titlePeerText); _titlePeerTextWidth = st::dialogsTextFont->width(_titlePeerText);
if (App::main()) { if (App::main()) {
App::main()->topBar()->update(); App::main()->topBar()->update();
} }

View File

@ -115,6 +115,9 @@ public:
~HistoryInner(); ~HistoryInner();
protected:
bool focusNextPrevChild(bool next) override;
public slots: public slots:
void onUpdateSelected(); void onUpdateSelected();

View File

@ -21,7 +21,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "stdafx.h" #include "stdafx.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "styles/style_dialogs.h"
#include "ui/buttons/peer_avatar_button.h" #include "ui/buttons/peer_avatar_button.h"
#include "ui/buttons/round_button.h"
#include "window/section_memento.h" #include "window/section_memento.h"
#include "window/section_widget.h" #include "window/section_widget.h"
#include "window/top_bar_widget.h" #include "window/top_bar_widget.h"
@ -56,6 +58,7 @@ StackItemSection::~StackItemSection() {
MainWidget::MainWidget(MainWindow *window) : TWidget(window) MainWidget::MainWidget(MainWindow *window) : TWidget(window)
, _a_show(animation(this, &MainWidget::step_show)) , _a_show(animation(this, &MainWidget::step_show))
, _dialogsWidth(st::dialogsWidthMin)
, _sideShadow(this, st::shadowColor) , _sideShadow(this, st::shadowColor)
, _dialogs(this) , _dialogs(this)
, _history(this) , _history(this)
@ -2526,8 +2529,8 @@ void MainWidget::showAll() {
cSetPasswordRecovered(false); cSetPasswordRecovered(false);
Ui::showLayer(new InformBox(lang(lng_signin_password_removed))); Ui::showLayer(new InformBox(lang(lng_signin_password_removed)));
} }
_sideShadow.show();
if (Adaptive::OneColumn()) { if (Adaptive::OneColumn()) {
_sideShadow.hide();
if (_hider) { if (_hider) {
_hider->hide(); _hider->hide();
if (!_forwardConfirm && _hider->wasOffered()) { if (!_forwardConfirm && _hider->wasOffered()) {
@ -2562,6 +2565,7 @@ void MainWidget::showAll() {
_dialogs->hide(); _dialogs->hide();
} }
} else { } else {
_sideShadow.show();
if (_hider) { if (_hider) {
_hider->show(); _hider->show();
if (_forwardConfirm) { if (_forwardConfirm) {
@ -2593,6 +2597,14 @@ void MainWidget::showAll() {
App::wnd()->checkHistoryActivation(); App::wnd()->checkHistoryActivation();
} }
namespace {
inline int chatsListWidth(int windowWidth) {
return snap<int>((windowWidth * 5) / 14, st::dialogsWidthMin, st::dialogsWidthMax);
}
} // namespace
void MainWidget::resizeEvent(QResizeEvent *e) { void MainWidget::resizeEvent(QResizeEvent *e) {
int32 tbh = _topBar->isHidden() ? 0 : st::topBarHeight; int32 tbh = _topBar->isHidden() ? 0 : st::topBarHeight;
if (Adaptive::OneColumn()) { if (Adaptive::OneColumn()) {
@ -3451,9 +3463,12 @@ void MainWidget::inviteImportDone(const MTPUpdates &updates) {
bool MainWidget::inviteImportFail(const RPCError &error) { bool MainWidget::inviteImportFail(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false; if (MTP::isDefaultHandledError(error)) return false;
if (error.code() == 400) { if (error.type() == qstr("CHANNELS_TOO_MUCH")) {
Ui::showLayer(new InformBox(lang(lng_join_channel_error)));
} else if (error.code() == 400) {
Ui::showLayer(new InformBox(lang(error.type() == qstr("USERS_TOO_MUCH") ? lng_group_invite_no_room : lng_group_invite_bad_link))); Ui::showLayer(new InformBox(lang(error.type() == qstr("USERS_TOO_MUCH") ? lng_group_invite_no_room : lng_group_invite_bad_link)));
} }
return true; return true;
} }
@ -3761,24 +3776,7 @@ void MainWidget::saveDraftToCloud() {
auto localDraft = history->localDraft(); auto localDraft = history->localDraft();
auto cloudDraft = history->cloudDraft(); auto cloudDraft = history->cloudDraft();
if (!historyDraftsAreEqual(localDraft, cloudDraft)) { if (!historyDraftsAreEqual(localDraft, cloudDraft)) {
if (cloudDraft && cloudDraft->saveRequestId) { App::api()->saveDraftToCloudDelayed(history);
MTP::cancel(cloudDraft->saveRequestId);
}
cloudDraft = history->createCloudDraft(localDraft);
MTPmessages_SaveDraft::Flags flags = 0;
auto &textWithTags = cloudDraft->textWithTags;
if (cloudDraft->previewCancelled) {
flags |= MTPmessages_SaveDraft::Flag::f_no_webpage;
}
if (cloudDraft->msgId) {
flags |= MTPmessages_SaveDraft::Flag::f_reply_to_msg_id;
}
if (!textWithTags.tags.isEmpty()) {
flags |= MTPmessages_SaveDraft::Flag::f_entities;
}
auto entities = linksToMTP(entitiesFromTextTags(textWithTags.tags), true);
cloudDraft->saveRequestId = MTP::send(MTPmessages_SaveDraft(MTP_flags(flags), MTP_int(cloudDraft->msgId), peer->input, MTP_string(textWithTags.text), entities), rpcDone(&MainWidget::saveCloudDraftDone, peer), rpcFail(&MainWidget::saveCloudDraftFail, peer));
} }
} }
} }
@ -3787,30 +3785,6 @@ void MainWidget::applyCloudDraft(History *history) {
_history->applyCloudDraft(history); _history->applyCloudDraft(history);
} }
void MainWidget::saveCloudDraftDone(PeerData *peer, const MTPBool &result, mtpRequestId requestId) {
if (auto history = App::historyLoaded(peer)) {
if (auto cloudDraft = history->cloudDraft()) {
if (cloudDraft->saveRequestId == requestId) {
cloudDraft->saveRequestId = 0;
history->updateChatListEntry();
}
}
}
}
bool MainWidget::saveCloudDraftFail(PeerData *peer, const RPCError &error, mtpRequestId requestId) {
if (MTP::isDefaultHandledError(error)) return false;
if (auto history = App::historyLoaded(peer)) {
if (auto cloudDraft = history->cloudDraft()) {
if (cloudDraft->saveRequestId == requestId) {
history->clearCloudDraft();
}
}
}
return true;
}
void MainWidget::checkIdleFinish() { void MainWidget::checkIdleFinish() {
if (this != App::main()) return; if (this != App::main()) return;
if (psIdleTime() < uint64(Global::OfflineIdleTimeout())) { if (psIdleTime() < uint64(Global::OfflineIdleTimeout())) {

View File

@ -129,10 +129,6 @@ public:
} }
}; };
inline int chatsListWidth(int windowWidth) {
return snap<int>((windowWidth * 5) / 14, st::dlgMinWidth, st::dlgMaxWidth);
}
enum SilentNotifiesStatus { enum SilentNotifiesStatus {
SilentNotifiesDontChange, SilentNotifiesDontChange,
SilentNotifiesSetSilent, SilentNotifiesSetSilent,
@ -503,9 +499,6 @@ private:
void messagesAffected(PeerData *peer, const MTPmessages_AffectedMessages &result); void messagesAffected(PeerData *peer, const MTPmessages_AffectedMessages &result);
void overviewLoaded(History *history, const MTPmessages_Messages &result, mtpRequestId req); void overviewLoaded(History *history, const MTPmessages_Messages &result, mtpRequestId req);
void saveCloudDraftDone(PeerData *peer, const MTPBool &result, mtpRequestId requestId);
bool saveCloudDraftFail(PeerData *peer, const RPCError &error, mtpRequestId requestId);
Window::SectionSlideParams prepareShowAnimation(bool willHaveTopBarShadow); Window::SectionSlideParams prepareShowAnimation(bool willHaveTopBarShadow);
void showWideSectionAnimated(const Window::SectionMemento *memento, bool back); void showWideSectionAnimated(const Window::SectionMemento *memento, bool back);
@ -582,7 +575,7 @@ private:
anim::ivalue a_coordUnder, a_coordOver; anim::ivalue a_coordUnder, a_coordOver;
anim::fvalue a_shadow; anim::fvalue a_shadow;
int _dialogsWidth = st::dlgMinWidth; int _dialogsWidth;
PlainShadow _sideShadow; PlainShadow _sideShadow;

View File

@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "stdafx.h" #include "stdafx.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "styles/style_dialogs.h"
#include "zip.h" #include "zip.h"
#include "lang.h" #include "lang.h"
#include "shortcuts.h" #include "shortcuts.h"
@ -182,48 +183,48 @@ void NotifyWindow::updateNotifyDisplay() {
QRect rectForName(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height); QRect rectForName(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height);
if (!App::passcoded() && cNotifyView() <= dbinvShowName) { if (!App::passcoded() && cNotifyView() <= dbinvShowName) {
if (history->peer->isChat() || history->peer->isMegagroup()) { if (history->peer->isChat() || history->peer->isMegagroup()) {
p.drawSprite(QPoint(rectForName.left() + st::dlgChatImgPos.x(), rectForName.top() + st::dlgChatImgPos.y()), st::dlgChatImg); p.drawSprite(QPoint(rectForName.left() + st::dialogsChatImgPos.x(), rectForName.top() + st::dialogsChatImgPos.y()), st::dlgChatImg);
rectForName.setLeft(rectForName.left() + st::dlgImgSkip); rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
} else if (history->peer->isChannel()) { } else if (history->peer->isChannel()) {
p.drawSprite(QPoint(rectForName.left() + st::dlgChannelImgPos.x(), rectForName.top() + st::dlgChannelImgPos.y()), st::dlgChannelImg); p.drawSprite(QPoint(rectForName.left() + st::dialogsChannelImgPos.x(), rectForName.top() + st::dialogsChannelImgPos.y()), st::dlgChannelImg);
rectForName.setLeft(rectForName.left() + st::dlgImgSkip); rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
} }
} }
QDateTime now(QDateTime::currentDateTime()), lastTime(item->date); QDateTime now(QDateTime::currentDateTime()), lastTime(item->date);
QDate nowDate(now.date()), lastDate(lastTime.date()); QDate nowDate(now.date()), lastDate(lastTime.date());
QString dt = lastTime.toString(cTimeFormat()); QString dt = lastTime.toString(cTimeFormat());
int32 dtWidth = st::dlgHistFont->width(dt); int32 dtWidth = st::dialogsTextFont->width(dt);
rectForName.setWidth(rectForName.width() - dtWidth - st::dlgDateSkip); rectForName.setWidth(rectForName.width() - dtWidth - st::dialogsDateSkip);
p.setFont(st::dlgDateFont->f); p.setFont(st::dialogsDateFont);
p.setPen(st::dlgDateColor->p); p.setPen(st::dialogsDateFg);
p.drawText(rectForName.left() + rectForName.width() + st::dlgDateSkip, rectForName.top() + st::dlgHistFont->ascent, dt); p.drawText(rectForName.left() + rectForName.width() + st::dialogsDateSkip, rectForName.top() + st::dialogsTextFont->ascent, dt);
if (!App::passcoded() && cNotifyView() <= dbinvShowPreview) { if (!App::passcoded() && cNotifyView() <= dbinvShowPreview) {
const HistoryItem *textCachedFor = 0; const HistoryItem *textCachedFor = 0;
Text itemTextCache(itemWidth); Text itemTextCache(itemWidth);
QRect r(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dlgFont->height); QRect r(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dialogsTextFont->height);
if (fwdCount < 2) { if (fwdCount < 2) {
bool active = false; bool active = false;
item->drawInDialog(p, r, active, textCachedFor, itemTextCache); item->drawInDialog(p, r, active, textCachedFor, itemTextCache);
} else { } else {
p.setFont(st::dlgHistFont->f); p.setFont(st::dialogsTextFont);
if (item->hasFromName() && !item->isPost()) { if (item->hasFromName() && !item->isPost()) {
itemTextCache.setText(st::dlgHistFont, item->author()->name); itemTextCache.setText(st::dialogsTextFont, item->author()->name);
p.setPen(st::dlgSystemColor->p); p.setPen(st::dialogsTextFgService);
itemTextCache.drawElided(p, r.left(), r.top(), r.width(), st::dlgHistFont->height); itemTextCache.drawElided(p, r.left(), r.top(), r.width(), st::dialogsTextFont->height);
r.setTop(r.top() + st::dlgHistFont->height); r.setTop(r.top() + st::dialogsTextFont->height);
} }
p.setPen(st::dlgTextColor->p); p.setPen(st::dialogsTextFg);
p.drawText(r.left(), r.top() + st::dlgHistFont->ascent, lng_forward_messages(lt_count, fwdCount)); p.drawText(r.left(), r.top() + st::dialogsTextFont->ascent, lng_forward_messages(lt_count, fwdCount));
} }
} else { } else {
static QString notifyText = st::dlgHistFont->elided(lang(lng_notification_preview), itemWidth); static QString notifyText = st::dialogsTextFont->elided(lang(lng_notification_preview), itemWidth);
p.setPen(st::dlgSystemColor->p); p.setPen(st::dialogsTextFgService);
p.drawText(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height + st::dlgHistFont->ascent, notifyText); p.drawText(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height + st::dialogsTextFont->ascent, notifyText);
} }
p.setPen(st::dlgNameColor->p); p.setPen(st::dialogsNameFg);
if (!App::passcoded() && cNotifyView() <= dbinvShowName) { if (!App::passcoded() && cNotifyView() <= dbinvShowName) {
history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
} else { } else {
@ -1282,9 +1283,8 @@ void MainWindow::toggleDisplayNotifyFromTray() {
} }
void MainWindow::closeEvent(QCloseEvent *e) { void MainWindow::closeEvent(QCloseEvent *e) {
if (MTP::authedId() && !Sandbox::isSavingSession() && Ui::hideWindowNoQuit()) {
e->ignore(); e->ignore();
} else { if (!MTP::authedId() || Sandbox::isSavingSession() || !Ui::hideWindowNoQuit()) {
App::quit(); App::quit();
} }
} }

View File

@ -63,6 +63,8 @@ linksBorder: 1px;
linksBorderFg: #eaeaea; linksBorderFg: #eaeaea;
linksDateColor: #808080; linksDateColor: #808080;
linksDateMargin: margins(0px, 15px, 0px, 2px); linksDateMargin: margins(0px, 15px, 0px, 2px);
linksPhotoSize: 46px;
linksPhotoPadding: 12px;
overviewLinksCheck: icon { overviewLinksCheck: icon {
{ "overview_links_check_bg", overviewCheckBg }, { "overview_links_check_bg", overviewCheckBg },
{ "overview_links_check", #fff, point(4px, 5px) }, { "overview_links_check", #fff, point(4px, 5px) },

View File

@ -770,7 +770,7 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
if (selected || context->selecting) { if (selected || context->selecting) {
QRect check(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - st::defaultCheckbox.diameter), rthumb.height() - st::defaultCheckbox.diameter), QSize(st::defaultCheckbox.diameter, st::defaultCheckbox.diameter)); QRect check(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - st::defaultCheckbox.diameter), rthumb.height() - st::defaultCheckbox.diameter), QSize(st::defaultCheckbox.diameter, st::defaultCheckbox.diameter));
p.fillRect(check, selected ? st::overviewFileChecked : st::overviewFileCheck); p.fillRect(check, selected ? st::overviewFileChecked : st::overviewFileCheck);
p.drawSpriteCenter(check, st::defaultCheckbox.checkIcon); st::defaultCheckbox.checkIcon.paint(p, QPoint(rthumb.width() - st::defaultCheckbox.diameter, rthumb.y() + rthumb.height() - st::defaultCheckbox.diameter), _width);
} }
} }
} }
@ -979,13 +979,13 @@ Link::Link(HistoryMedia *media, HistoryItem *parent) : ItemBase(parent) {
tw = convertScale(_page->document->thumb->width()); tw = convertScale(_page->document->thumb->width());
th = convertScale(_page->document->thumb->height()); th = convertScale(_page->document->thumb->height());
} }
if (tw > st::dlgPhotoSize) { if (tw > st::linksPhotoSize) {
if (th > tw) { if (th > tw) {
th = th * st::dlgPhotoSize / tw; th = th * st::linksPhotoSize / tw;
tw = st::dlgPhotoSize; tw = st::linksPhotoSize;
} else if (th > st::dlgPhotoSize) { } else if (th > st::linksPhotoSize) {
tw = tw * st::dlgPhotoSize / th; tw = tw * st::linksPhotoSize / th;
th = st::dlgPhotoSize; th = st::linksPhotoSize;
} }
} }
_pixw = qMax(tw, 1); _pixw = qMax(tw, 1);
@ -1020,15 +1020,15 @@ void Link::initDimensions() {
_minh += st::semiboldFont->height; _minh += st::semiboldFont->height;
} }
if (!_text.isEmpty()) { if (!_text.isEmpty()) {
_minh += qMin(3 * st::normalFont->height, _text.countHeight(_maxw - st::dlgPhotoSize - st::dlgPhotoPadding)); _minh += qMin(3 * st::normalFont->height, _text.countHeight(_maxw - st::linksPhotoSize - st::linksPhotoPadding));
} }
_minh += _links.size() * st::normalFont->height; _minh += _links.size() * st::normalFont->height;
_minh = qMax(_minh, int32(st::dlgPhotoSize)) + st::linksMargin.top() + st::linksMargin.bottom() + st::linksBorder; _minh = qMax(_minh, int32(st::linksPhotoSize)) + st::linksMargin.top() + st::linksMargin.bottom() + st::linksBorder;
} }
int32 Link::resizeGetHeight(int32 width) { int32 Link::resizeGetHeight(int32 width) {
_width = qMin(width, _maxw); _width = qMin(width, _maxw);
int32 w = _width - st::dlgPhotoSize - st::dlgPhotoPadding; int32 w = _width - st::linksPhotoSize - st::linksPhotoPadding;
for (int32 i = 0, l = _links.size(); i < l; ++i) { for (int32 i = 0, l = _links.size(); i < l; ++i) {
_links.at(i).lnk->setFullDisplayed(w >= _links.at(i).width); _links.at(i).lnk->setFullDisplayed(w >= _links.at(i).width);
} }
@ -1038,54 +1038,54 @@ int32 Link::resizeGetHeight(int32 width) {
_height += st::semiboldFont->height; _height += st::semiboldFont->height;
} }
if (!_text.isEmpty()) { if (!_text.isEmpty()) {
_height += qMin(3 * st::normalFont->height, _text.countHeight(_width - st::dlgPhotoSize - st::dlgPhotoPadding)); _height += qMin(3 * st::normalFont->height, _text.countHeight(_width - st::linksPhotoSize - st::linksPhotoPadding));
} }
_height += _links.size() * st::normalFont->height; _height += _links.size() * st::normalFont->height;
_height = qMax(_height, int32(st::dlgPhotoSize)) + st::linksMargin.top() + st::linksMargin.bottom() + st::linksBorder; _height = qMax(_height, int32(st::linksPhotoSize)) + st::linksMargin.top() + st::linksMargin.bottom() + st::linksBorder;
return _height; return _height;
} }
void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) const { void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) const {
int32 left = st::dlgPhotoSize + st::dlgPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left; int32 left = st::linksPhotoSize + st::linksPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left;
if (clip.intersects(rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width))) { if (clip.intersects(rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width))) {
if (_page && _page->photo) { if (_page && _page->photo) {
QPixmap pix; QPixmap pix;
if (_page->photo->medium->loaded()) { if (_page->photo->medium->loaded()) {
pix = _page->photo->medium->pixSingle(_pixw, _pixh, st::dlgPhotoSize, st::dlgPhotoSize); pix = _page->photo->medium->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize);
} else if (_page->photo->loaded()) { } else if (_page->photo->loaded()) {
pix = _page->photo->full->pixSingle(_pixw, _pixh, st::dlgPhotoSize, st::dlgPhotoSize); pix = _page->photo->full->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize);
} else { } else {
pix = _page->photo->thumb->pixSingle(_pixw, _pixh, st::dlgPhotoSize, st::dlgPhotoSize); pix = _page->photo->thumb->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize);
} }
p.drawPixmapLeft(0, top, _width, pix); p.drawPixmapLeft(0, top, _width, pix);
} else if (_page && _page->document && !_page->document->thumb->isNull()) { } else if (_page && _page->document && !_page->document->thumb->isNull()) {
p.drawPixmapLeft(0, top, _width, _page->document->thumb->pixSingle(_pixw, _pixh, st::dlgPhotoSize, st::dlgPhotoSize)); p.drawPixmapLeft(0, top, _width, _page->document->thumb->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize));
} else { } else {
int32 index = _letter.isEmpty() ? 0 : (_letter.at(0).unicode() % 4); int32 index = _letter.isEmpty() ? 0 : (_letter.at(0).unicode() % 4);
switch (index) { switch (index) {
case 0: App::roundRect(p, rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width), st::msgFileRedColor, DocRedCorners); break; case 0: App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::msgFileRedColor, DocRedCorners); break;
case 1: App::roundRect(p, rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width), st::msgFileYellowColor, DocYellowCorners); break; case 1: App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::msgFileYellowColor, DocYellowCorners); break;
case 2: App::roundRect(p, rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width), st::msgFileGreenColor, DocGreenCorners); break; case 2: App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::msgFileGreenColor, DocGreenCorners); break;
case 3: App::roundRect(p, rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width), st::msgFileBlueColor, DocBlueCorners); break; case 3: App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::msgFileBlueColor, DocBlueCorners); break;
} }
if (!_letter.isEmpty()) { if (!_letter.isEmpty()) {
p.setFont(st::linksLetterFont->f); p.setFont(st::linksLetterFont->f);
p.setPen(st::white->p); p.setPen(st::white->p);
p.drawText(rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width), _letter, style::al_center); p.drawText(rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), _letter, style::al_center);
} }
} }
if (selection == FullSelection) { if (selection == FullSelection) {
App::roundRect(p, rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width), st::overviewPhotoSelectOverlay, PhotoSelectOverlayCorners); App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::overviewPhotoSelectOverlay, PhotoSelectOverlayCorners);
st::overviewLinksChecked.paint(p, QPoint(st::dlgPhotoSize - st::overviewLinksChecked.width(), top + st::dlgPhotoSize - st::overviewLinksChecked.height()), _width); st::overviewLinksChecked.paint(p, QPoint(st::linksPhotoSize - st::overviewLinksChecked.width(), top + st::linksPhotoSize - st::overviewLinksChecked.height()), _width);
} else if (context->selecting) { } else if (context->selecting) {
st::overviewLinksCheck.paint(p, QPoint(st::dlgPhotoSize - st::overviewLinksCheck.width(), top + st::dlgPhotoSize - st::overviewLinksCheck.height()), _width); st::overviewLinksCheck.paint(p, QPoint(st::linksPhotoSize - st::overviewLinksCheck.width(), top + st::linksPhotoSize - st::overviewLinksCheck.height()), _width);
} }
} }
if (!_title.isEmpty() && _text.isEmpty() && _links.size() == 1) { if (!_title.isEmpty() && _text.isEmpty() && _links.size() == 1) {
top += (st::dlgPhotoSize - st::semiboldFont->height - st::normalFont->height) / 2; top += (st::linksPhotoSize - st::semiboldFont->height - st::normalFont->height) / 2;
} else { } else {
top = st::linksTextTop; top = st::linksTextTop;
} }
@ -1123,14 +1123,14 @@ void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const P
} }
void Link::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, int y) const { void Link::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, int y) const {
int32 left = st::dlgPhotoSize + st::dlgPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left; int32 left = st::linksPhotoSize + st::linksPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left;
if (rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width).contains(x, y)) { if (rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width).contains(x, y)) {
link = _photol; link = _photol;
return; return;
} }
if (!_title.isEmpty() && _text.isEmpty() && _links.size() == 1) { if (!_title.isEmpty() && _text.isEmpty() && _links.size() == 1) {
top += (st::dlgPhotoSize - st::semiboldFont->height - st::normalFont->height) / 2; top += (st::linksPhotoSize - st::semiboldFont->height - st::normalFont->height) / 2;
} }
if (!_title.isEmpty()) { if (!_title.isEmpty()) {
if (rtlrect(left, top, qMin(w, _titlew), st::semiboldFont->height, _width).contains(x, y)) { if (rtlrect(left, top, qMin(w, _titlew), st::semiboldFont->height, _width).contains(x, y)) {

View File

@ -24,29 +24,30 @@ using "basic_types.style";
profileBg: windowBg; profileBg: windowBg;
profileTopBarHeight: topBarHeight; profileTopBarHeight: topBarHeight;
profileTopBarBackIconFg: #51b3e0; profileTopBarBackIconFg: #0290d7;
profileTopBarBackIcon: icon { profileTopBarBackIcon: icon {
{ "topbar_back_arrow", profileTopBarBackIconFg }, { "topbar_back_arrow", profileTopBarBackIconFg },
}; };
profileTopBarBackIconPosition: point(15px, 19px); profileTopBarBackIconPosition: point(15px, 20px);
profileTopBarBackFont: font(14px); profileTopBarBackFont: font(14px);
profileTopBarBackFg: #1485c2; profileTopBarBackFg: #1485c2;
profileTopBarBackPosition: point(32px, 17px); profileTopBarBackPosition: point(32px, 17px);
profileFixedBarButton: flatButton(topBarButton) { profileFixedBarButton: BoxButton(topBarButton) {
} }
profileMarginTop: 13px; profileMarginTop: 13px;
profilePhotoSize: 112px; profilePhotoSize: 112px;
profilePhotoLeftMin: 18px; profilePhotoLeftMin: 18px;
profilePhotoLeftMax: 45px; profilePhotoLeftMax: 35px;
profilePhotoDuration: 500; profilePhotoDuration: 500;
profileNameLeft: 26px; profileNameLeft: 26px;
profileNameTop: 9px; profileNameTop: 9px;
profileNameLabel: flatLabel(labelDefFlat) { profileNameLabel: flatLabel(labelDefFlat) {
margin: margins(10px, 5px, 10px, 5px); margin: margins(10px, 5px, 10px, 5px);
font: font(16px); font: font(16px semibold);
width: 160px; width: 160px;
maxHeight: 24px; maxHeight: 24px;
textFg: #333333;
} }
profileNameTextStyle: textStyle(defaultTextStyle) { profileNameTextStyle: textStyle(defaultTextStyle) {
} }
@ -57,18 +58,18 @@ profileStatusFg: windowSubTextFg;
profileStatusFgActive: windowActiveTextFg; profileStatusFgActive: windowActiveTextFg;
profileMarginBottom: 30px; profileMarginBottom: 30px;
profileActiveBg: #3fb0e4;
profileButtonLeft: 27px; profileButtonLeft: 27px;
profileButtonTop: 88px; profileButtonTop: 88px;
profileButtonSkip: 10px; profileButtonSkip: 10px;
profilePrimaryButton: BoxButton { profilePrimaryButton: BoxButton {
textFg: #ffffff; textFg: #ffffff;
textFgOver: #ffffff; textFgOver: #ffffff;
textBg: profileActiveBg; textBg: windowActiveBg;
textBgOver: profileActiveBg; textBgOver: windowActiveBg;
width: -34px; width: -34px;
height: 34px; height: 34px;
padding: margins(0px, 0px, 0px, 0px);
textTop: 8px; textTop: 8px;
@ -76,13 +77,13 @@ profilePrimaryButton: BoxButton {
duration: 200; duration: 200;
} }
profileSecondaryButton: BoxButton(profilePrimaryButton) { profileSecondaryButton: BoxButton(profilePrimaryButton) {
textFg: #189dda; textFg: #2b99d5;
textFgOver: #189dda; textFgOver: #2b99d5;
textBg: #ffffff; textBg: #ffffff;
textBgOver: #f2f7fa; textBgOver: #f2f7fa;
} }
profileAddMemberIcon: icon { profileAddMemberIcon: icon {
{ "profile_add_member", profileActiveBg, point(20px, 10px) }, { "profile_add_member", windowActiveBg, point(20px, 10px) },
}; };
profileAddMemberButton: BoxButton(profileSecondaryButton) { profileAddMemberButton: BoxButton(profileSecondaryButton) {
width: 62px; width: 62px;
@ -90,7 +91,7 @@ profileAddMemberButton: BoxButton(profileSecondaryButton) {
} }
profileDropAreaBg: profileBg; profileDropAreaBg: profileBg;
profileDropAreaFg: profileActiveBg; profileDropAreaFg: windowActiveBg;
profileDropAreaPadding: margins(25px, 3px, 25px, 20px); profileDropAreaPadding: margins(25px, 3px, 25px, 20px);
profileDropAreaTitleFont: font(24px); profileDropAreaTitleFont: font(24px);
profileDropAreaTitleTop: 30px; profileDropAreaTitleTop: 30px;
@ -120,7 +121,7 @@ profileBlockMarginRight: 10px;
profileBlockMarginBottom: 4px; profileBlockMarginBottom: 4px;
profileBlockTitleHeight: 25px; profileBlockTitleHeight: 25px;
profileBlockTitleFont: font(14px semibold); profileBlockTitleFont: font(14px semibold);
profileBlockTitleFg: black; profileBlockTitleFg: #333333;
profileBlockTitlePosition: point(24px, 0px); profileBlockTitlePosition: point(24px, 0px);
profileBlockLabel: flatLabel(labelDefFlat) { profileBlockLabel: flatLabel(labelDefFlat) {
textFg: windowSubTextFg; textFg: windowSubTextFg;
@ -153,7 +154,7 @@ profileMemberStatusFg: windowSubTextFg;
profileMemberStatusFgOver: windowSubTextFg; profileMemberStatusFgOver: windowSubTextFg;
profileMemberStatusFgActive: windowActiveTextFg; profileMemberStatusFgActive: windowActiveTextFg;
profileMemberAdminIcon: icon { profileMemberAdminIcon: icon {
{ "profile_admin_star", profileActiveBg, point(4px, 2px) }, { "profile_admin_star", #3babe7, point(4px, 2px) },
}; };
profileLimitReachedLabel: flatLabel(labelDefFlat) { profileLimitReachedLabel: flatLabel(labelDefFlat) {
width: 180px; width: 180px;
@ -167,3 +168,9 @@ profileReportReasonOther: InputArea(defaultInputArea) {
textMargins: margins(1px, 6px, 1px, 4px); textMargins: margins(1px, 6px, 1px, 4px);
heightMax: 115px; heightMax: 115px;
} }
profileVerifiedCheckPosition: point(-3px, 7px);
profileVerifiedCheck: icon {
{ "profile_verified_star", #4abcf1 },
{ "profile_verified_check", #ffffff, point(4px, 4px) }
};

View File

@ -129,9 +129,12 @@ void CoverWidget::refreshNameGeometry(int newWidth) {
int infoLeft = _userpicButton->x() + _userpicButton->width(); int infoLeft = _userpicButton->x() + _userpicButton->width();
int nameLeft = infoLeft + st::profileNameLeft - st::profileNameLabel.margin.left(); int nameLeft = infoLeft + st::profileNameLeft - st::profileNameLabel.margin.left();
int nameTop = _userpicButton->y() + st::profileNameTop - st::profileNameLabel.margin.top(); int nameTop = _userpicButton->y() + st::profileNameTop - st::profileNameLabel.margin.top();
int nameWidth = newWidth - infoLeft - st::profileNameLeft - st::profileButtonSkip; int nameWidth = newWidth - infoLeft - st::profileNameLeft;
if (_peer->isVerified()) {
nameWidth -= st::profileVerifiedCheckPosition.x() + st::profileVerifiedCheck.width();
}
int marginsAdd = st::profileNameLabel.margin.left() + st::profileNameLabel.margin.right(); int marginsAdd = st::profileNameLabel.margin.left() + st::profileNameLabel.margin.right();
_name.resizeToWidth(qMin(nameWidth, _name.naturalWidth()) + marginsAdd); _name.resizeToWidth(qMin(nameWidth - marginsAdd, _name.naturalWidth()) + marginsAdd);
_name.moveToLeft(nameLeft, nameTop); _name.moveToLeft(nameLeft, nameTop);
} }
@ -183,6 +186,10 @@ void CoverWidget::paintEvent(QPaintEvent *e) {
p.setPen(_statusTextIsOnline ? st::profileStatusFgActive : st::profileStatusFg); p.setPen(_statusTextIsOnline ? st::profileStatusFgActive : st::profileStatusFg);
p.drawTextLeft(_statusPosition.x(), _statusPosition.y(), width(), _statusText); p.drawTextLeft(_statusPosition.x(), _statusPosition.y(), width(), _statusText);
if (_peer->isVerified()) {
st::profileVerifiedCheck.paint(p, QPoint(_name.x() + _name.width(), _name.y()) + st::profileVerifiedCheckPosition, width());
}
paintDivider(p); paintDivider(p);
} }
@ -407,6 +414,7 @@ void CoverWidget::clearButtons() {
void CoverWidget::addButton(const QString &text, const char *slot, const style::BoxButton *replacementStyle) { void CoverWidget::addButton(const QString &text, const char *slot, const style::BoxButton *replacementStyle) {
auto &buttonStyle = _buttons.isEmpty() ? st::profilePrimaryButton : st::profileSecondaryButton; auto &buttonStyle = _buttons.isEmpty() ? st::profilePrimaryButton : st::profileSecondaryButton;
auto button = new Ui::RoundButton(this, text, buttonStyle); auto button = new Ui::RoundButton(this, text, buttonStyle);
button->setTextTransform(Ui::RoundButton::TextTransform::ToUpper);
connect(button, SIGNAL(clicked()), this, slot); connect(button, SIGNAL(clicked()), this, slot);
button->show(); button->show();

View File

@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "profile/profile_fixed_bar.h" #include "profile/profile_fixed_bar.h"
#include "styles/style_profile.h" #include "styles/style_profile.h"
#include "ui/buttons/round_button.h"
#include "lang.h" #include "lang.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "boxes/addcontactbox.h" #include "boxes/addcontactbox.h"
@ -165,7 +166,7 @@ void FixedBar::addRightAction(RightActionType type, const QString &text, const c
} }
_rightActions[_currentAction].type = type; _rightActions[_currentAction].type = type;
delete _rightActions[_currentAction].button; delete _rightActions[_currentAction].button;
_rightActions[_currentAction].button = new FlatButton(this, text, st::profileFixedBarButton); _rightActions[_currentAction].button = new Ui::RoundButton(this, text, st::profileFixedBarButton);
connect(_rightActions[_currentAction].button, SIGNAL(clicked()), this, slot); connect(_rightActions[_currentAction].button, SIGNAL(clicked()), this, slot);
bool showButton = !_animatingMode && (type != RightActionType::ShareContact || !_hideShareContactButton); bool showButton = !_animatingMode && (type != RightActionType::ShareContact || !_hideShareContactButton);
_rightActions[_currentAction].button->setVisible(showButton); _rightActions[_currentAction].button->setVisible(showButton);

View File

@ -26,6 +26,10 @@ namespace Notify {
struct PeerUpdate; struct PeerUpdate;
} // namespace Notify } // namespace Notify
namespace Ui {
class RoundButton;
} // namespace Ui
namespace Profile { namespace Profile {
class BackButton; class BackButton;
@ -96,7 +100,7 @@ private:
int _currentAction = 0; int _currentAction = 0;
struct RightAction { struct RightAction {
RightActionType type = RightActionType::None; RightActionType type = RightActionType::None;
FlatButton *button = nullptr; Ui::RoundButton *button = nullptr;
}; };
QList<RightAction> _rightActions; QList<RightAction> _rightActions;

View File

@ -426,6 +426,9 @@ void MembersWidget::fillChatMembers(ChatData *chat) {
} }
void MembersWidget::setMemberFlags(Member *member, ChatData *chat) { void MembersWidget::setMemberFlags(Member *member, ChatData *chat) {
auto isCreator = (chat->creator == peerToUser(member->user->id));
auto isAdmin = chat->admins.contains(member->user);
member->isAdmin = isCreator || isAdmin;
if (member->user->id == peerFromUser(MTP::authedId())) { if (member->user->id == peerFromUser(MTP::authedId())) {
member->canBeKicked = false; member->canBeKicked = false;
} else if (chat->amCreator() || (chat->amAdmin() && !member->isAdmin)) { } else if (chat->amCreator() || (chat->amAdmin() && !member->isAdmin)) {
@ -433,7 +436,6 @@ void MembersWidget::setMemberFlags(Member *member, ChatData *chat) {
} else { } else {
member->canBeKicked = chat->invitedByMe.contains(member->user); member->canBeKicked = chat->invitedByMe.contains(member->user);
} }
member->isAdmin = chat->admins.contains(member->user);
} }
MembersWidget::Member *MembersWidget::addUser(ChannelData *megagroup, UserData *user) { MembersWidget::Member *MembersWidget::addUser(ChannelData *megagroup, UserData *user) {
@ -490,6 +492,9 @@ bool MembersWidget::addUsersToEnd(ChannelData *megagroup) {
} }
void MembersWidget::setMemberFlags(Member *member, ChannelData *megagroup) { void MembersWidget::setMemberFlags(Member *member, ChannelData *megagroup) {
auto amCreatorOrAdmin = (peerFromUser(member->user->id) == MTP::authedId()) && (megagroup->amCreator() || megagroup->amEditor());
auto isAdmin = megagroup->mgInfo->lastAdmins.contains(member->user);
member->isAdmin = amCreatorOrAdmin || isAdmin;
if (member->user->isSelf()) { if (member->user->isSelf()) {
member->canBeKicked = false; member->canBeKicked = false;
} else if (megagroup->amCreator() || (megagroup->amEditor() && !member->isAdmin)) { } else if (megagroup->amCreator() || (megagroup->amEditor() && !member->isAdmin)) {
@ -497,7 +502,6 @@ void MembersWidget::setMemberFlags(Member *member, ChannelData *megagroup) {
} else { } else {
member->canBeKicked = false; member->canBeKicked = false;
} }
member->isAdmin = megagroup->mgInfo->lastAdmins.contains(member->user);
} }
MembersWidget::Member *MembersWidget::getMember(UserData *user) { MembersWidget::Member *MembersWidget::getMember(UserData *user) {
@ -640,7 +644,7 @@ void ChannelMembersWidget::addButton(const QString &text, ChildWidget<Ui::LeftOu
} else if (*button) { } else if (*button) {
(*button)->setText(text); (*button)->setText(text);
} else { } else {
(*button) = new Ui::LeftOutlineButton(this, text); (*button) = new Ui::LeftOutlineButton(this, text, st::defaultLeftOutlineButton);
(*button)->show(); (*button)->show();
connect(*button, SIGNAL(clicked()), this, slot); connect(*button, SIGNAL(clicked()), this, slot);
} }

View File

@ -127,7 +127,7 @@ void SettingsWidget::refreshManageAdminsButton() {
}; };
_manageAdmins.destroy(); _manageAdmins.destroy();
if (hasManageAdmins()) { if (hasManageAdmins()) {
_manageAdmins = new Ui::LeftOutlineButton(this, lang(lng_profile_manage_admins)); _manageAdmins = new Ui::LeftOutlineButton(this, lang(lng_profile_manage_admins), st::defaultLeftOutlineButton);
_manageAdmins->show(); _manageAdmins->show();
connect(_manageAdmins, SIGNAL(clicked()), this, SLOT(onManageAdmins())); connect(_manageAdmins, SIGNAL(clicked()), this, SLOT(onManageAdmins()));
} }
@ -148,7 +148,7 @@ void SettingsWidget::refreshInviteLinkButton() {
}; };
auto inviteLinkText = getInviteLinkText(); auto inviteLinkText = getInviteLinkText();
if (!inviteLinkText.isEmpty()) { if (!inviteLinkText.isEmpty()) {
_inviteLink = new Ui::LeftOutlineButton(this, inviteLinkText); _inviteLink = new Ui::LeftOutlineButton(this, inviteLinkText, st::defaultLeftOutlineButton);
_inviteLink->show(); _inviteLink->show();
connect(_inviteLink, SIGNAL(clicked()), this, SLOT(onInviteLink())); connect(_inviteLink, SIGNAL(clicked()), this, SLOT(onInviteLink()));
} }

View File

@ -108,7 +108,7 @@ void SharedMediaWidget::refreshButton(MediaOverviewType type) {
if (_mediaButtons[type]) { if (_mediaButtons[type]) {
_mediaButtons[type]->setText(text); _mediaButtons[type]->setText(text);
} else { } else {
_mediaButtons[type] = new Ui::LeftOutlineButton(this, text); _mediaButtons[type] = new Ui::LeftOutlineButton(this, text, st::defaultLeftOutlineButton);
_mediaButtons[type]->show(); _mediaButtons[type]->show();
connect(_mediaButtons[type], SIGNAL(clicked()), this, SLOT(onMediaChosen())); connect(_mediaButtons[type], SIGNAL(clicked()), this, SLOT(onMediaChosen()));
} }

View File

@ -509,7 +509,9 @@ void PsMainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) {
QPixmap pix = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->genUserpic(st::notifyMacPhotoSize) : QPixmap(); QPixmap pix = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->genUserpic(st::notifyMacPhotoSize) : QPixmap();
QString msg = (!App::passcoded() && cNotifyView() <= dbinvShowPreview) ? (fwdCount < 2 ? item->notificationText() : lng_forward_messages(lt_count, fwdCount)) : lang(lng_notification_preview); QString msg = (!App::passcoded() && cNotifyView() <= dbinvShowPreview) ? (fwdCount < 2 ? item->notificationText() : lng_forward_messages(lt_count, fwdCount)) : lang(lng_notification_preview);
_private.showNotify(item->history()->peer->id, item->id, pix, title, subtitle, msg, !App::passcoded() && (cNotifyView() <= dbinvShowPreview)); bool withReply = !App::passcoded() && (cNotifyView() <= dbinvShowPreview) && item->history()->peer->canWrite();
_private.showNotify(item->history()->peer->id, item->id, pix, title, subtitle, msg, withReply);
} }
bool PsMainWindow::eventFilter(QObject *obj, QEvent *evt) { bool PsMainWindow::eventFilter(QObject *obj, QEvent *evt) {

View File

@ -24,8 +24,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
namespace Ui { namespace Ui {
RoundButton::RoundButton(QWidget *parent, const QString &text, const style::BoxButton &st) : Button(parent) RoundButton::RoundButton(QWidget *parent, const QString &text, const style::BoxButton &st) : Button(parent)
, _text(text.toUpper()) , _text(text)
, _fullText(text.toUpper()) , _fullText(text)
, _textWidth(st.font->width(_text)) , _textWidth(st.font->width(_text))
, _st(st) , _st(st)
, a_textBgOverOpacity(0) , a_textBgOverOpacity(0)
@ -36,34 +36,62 @@ RoundButton::RoundButton(QWidget *parent, const QString &text, const style::BoxB
setCursor(style::cur_pointer); setCursor(style::cur_pointer);
} }
void RoundButton::setTextTransform(TextTransform transform) {
_transform = transform;
updateText();
}
void RoundButton::setText(const QString &text) { void RoundButton::setText(const QString &text) {
_text = text;
_fullText = text; _fullText = text;
updateText();
}
void RoundButton::setFullWidth(int newFullWidth) {
_fullWidthOverride = newFullWidth;
resizeToText();
}
void RoundButton::updateText() {
if (_transform == TextTransform::ToUpper) {
_text = _fullText.toUpper();
} else {
_text = _fullText;
}
_textWidth = _st.font->width(_text); _textWidth = _st.font->width(_text);
resizeToText(); resizeToText();
} }
int RoundButton::textWidth() const {
return _textWidth;
}
void RoundButton::resizeToText() { void RoundButton::resizeToText() {
if (_st.width <= 0) { if (_fullWidthOverride < 0) {
resize(_textWidth - _st.width, _st.height); resize(_textWidth - _fullWidthOverride, _st.height + _st.padding.top() + _st.padding.bottom());
} else if (_st.width <= 0) {
resize(_textWidth - _st.width + _st.padding.left() + _st.padding.right(), _st.height + _st.padding.top() + _st.padding.bottom());
} else { } else {
if (_st.width < _textWidth + (_st.height - _st.font->height)) { if (_st.width < _textWidth + (_st.height - _st.font->height)) {
_text = _st.font->elided(_fullText, qMax(_st.width - (_st.height - _st.font->height), 1)); _text = _st.font->elided(_fullText, qMax(_st.width - (_st.height - _st.font->height), 1));
_textWidth = _st.font->width(_text); _textWidth = _st.font->width(_text);
} }
resize(_st.width, _st.height); resize(_st.width + _st.padding.left() + _st.padding.right(), _st.height + _st.padding.top() + _st.padding.bottom());
} }
} }
void RoundButton::paintEvent(QPaintEvent *e) { void RoundButton::paintEvent(QPaintEvent *e) {
Painter p(this); Painter p(this);
App::roundRect(p, rect(), _st.textBg); auto rounded = rtlrect(rect().marginsRemoved(_st.padding), width());
if (_fullWidthOverride < 0) {
rounded = QRect(-_fullWidthOverride / 4, rounded.top(), _textWidth - _fullWidthOverride / 2, rounded.height());
}
App::roundRect(p, rounded, _st.textBg);
float64 o = a_textBgOverOpacity.current(); float64 o = a_textBgOverOpacity.current();
if (o > 0) { if (o > 0) {
p.setOpacity(o); p.setOpacity(o);
App::roundRect(p, rect(), _st.textBgOver); App::roundRect(p, rounded, _st.textBgOver);
p.setOpacity(1); p.setOpacity(1);
} }
if (!_text.isEmpty()) { if (!_text.isEmpty()) {
@ -73,9 +101,13 @@ void RoundButton::paintEvent(QPaintEvent *e) {
p.setPen(_st.textFg); p.setPen(_st.textFg);
} }
p.setFont(_st.font); p.setFont(_st.font);
p.drawText((width() - _textWidth) / 2, _st.textTop + _st.font->ascent, _text); int textLeft = _st.padding.left() + ((width() - _textWidth - _st.padding.left() - _st.padding.right()) / 2);
if (_fullWidthOverride < 0) {
textLeft = -_fullWidthOverride / 2;
} }
_st.icon.paint(p, QPoint(0, 0), width()); p.drawTextLeft(textLeft, _st.padding.top() + _st.textTop, width(), _text);
}
_st.icon.paint(p, QPoint(_st.padding.left(), _st.padding.right()), width());
} }
void RoundButton::step_over(float64 ms, bool timer) { void RoundButton::step_over(float64 ms, bool timer) {

View File

@ -29,6 +29,15 @@ public:
RoundButton(QWidget *parent, const QString &text, const style::BoxButton &st); RoundButton(QWidget *parent, const QString &text, const style::BoxButton &st);
void setText(const QString &text); void setText(const QString &text);
int textWidth() const;
void setFullWidth(int newFullWidth);
enum class TextTransform {
NoTransform,
ToUpper,
};
void setTextTransform(TextTransform transform);
protected: protected:
void paintEvent(QPaintEvent *e) override; void paintEvent(QPaintEvent *e) override;
@ -38,10 +47,12 @@ protected:
private: private:
void step_over(float64 ms, bool timer); void step_over(float64 ms, bool timer);
void updateText();
void resizeToText(); void resizeToText();
QString _text, _fullText; QString _text, _fullText;
int _textWidth; int _textWidth;
int _fullWidthOverride = 0;
const style::BoxButton &_st; const style::BoxButton &_st;
@ -49,6 +60,8 @@ private:
anim::cvalue a_textFg; anim::cvalue a_textFg;
Animation _a_over; Animation _a_over;
TextTransform _transform = TextTransform::NoTransform;
}; };
} // namespace Ui } // namespace Ui

View File

@ -24,7 +24,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
FlatButton::FlatButton(QWidget *parent, const QString &text, const style::flatButton &st) : Button(parent) FlatButton::FlatButton(QWidget *parent, const QString &text, const style::flatButton &st) : Button(parent)
, _text(text) , _text(text)
, _st(st) , _st(st)
, _autoFontPadding(0)
, a_bg(st.bgColor->c) , a_bg(st.bgColor->c)
, a_text(st.color->c) , a_text(st.color->c)
, _a_appearance(animation(this, &FlatButton::step_appearance)) , _a_appearance(animation(this, &FlatButton::step_appearance))
@ -63,35 +62,10 @@ void FlatButton::setWidth(int32 w) {
resize(_st.width, height()); resize(_st.width, height());
} }
void FlatButton::setAutoFontSize(int32 padding, const QString &txt) {
_autoFontPadding = padding;
if (_autoFontPadding) {
_textForAutoSize = txt;
resizeEvent(0);
} else {
_textForAutoSize = QString();
_autoFont = style::font();
}
update();
}
int32 FlatButton::textWidth() const { int32 FlatButton::textWidth() const {
return _st.font->width(_text); return _st.font->width(_text);
} }
void FlatButton::resizeEvent(QResizeEvent *e) {
if (_autoFontPadding) {
_autoFont = _st.font;
for (int32 s = _st.font->f.pixelSize(); s >= st::fsize; --s) {
_autoFont = style::font(s, _st.font->flags(), _st.font->family());
if (2 * _autoFontPadding + _autoFont->width(_textForAutoSize) <= width()) {
break;
}
}
}
return Button::resizeEvent(e);
}
void FlatButton::step_appearance(float64 ms, bool timer) { void FlatButton::step_appearance(float64 ms, bool timer) {
float64 dt = ms / _st.duration; float64 dt = ms / _st.duration;
if (dt >= 1) { if (dt >= 1) {
@ -129,12 +103,11 @@ void FlatButton::paintEvent(QPaintEvent *e) {
p.setOpacity(_opacity); p.setOpacity(_opacity);
p.fillRect(r, a_bg.current()); p.fillRect(r, a_bg.current());
p.setFont((_autoFont ? _autoFont : ((_state & StateOver) ? _st.overFont : _st.font))->f); p.setFont((_state & StateOver) ? _st.overFont : _st.font);
p.setRenderHint(QPainter::TextAntialiasing); p.setRenderHint(QPainter::TextAntialiasing);
p.setPen(a_text.current()); p.setPen(a_text.current());
int32 top = (_state & StateOver) ? ((_state & StateDown) ? _st.downTextTop : _st.overTextTop) : _st.textTop; int32 top = (_state & StateOver) ? ((_state & StateDown) ? _st.downTextTop : _st.overTextTop) : _st.textTop;
if (_autoFont) top += (_st.font->height - _autoFont->height) / 2;
r.setTop(top); r.setTop(top);
p.drawText(r, _text, style::al_top); p.drawText(r, _text, style::al_top);

View File

@ -31,8 +31,6 @@ public:
FlatButton(QWidget *parent, const QString &text, const style::flatButton &st); FlatButton(QWidget *parent, const QString &text, const style::flatButton &st);
void resizeEvent(QResizeEvent *e);
void step_appearance(float64 ms, bool timer); void step_appearance(float64 ms, bool timer);
void paintEvent(QPaintEvent *e); void paintEvent(QPaintEvent *e);
void setOpacity(float64 o); void setOpacity(float64 o);
@ -40,7 +38,6 @@ public:
void setText(const QString &text); void setText(const QString &text);
void setWidth(int32 w); void setWidth(int32 w);
void setAutoFontSize(int32 padding, const QString &txt);
int32 textWidth() const; int32 textWidth() const;
@ -58,9 +55,6 @@ private:
style::flatButton _st; style::flatButton _st;
int32 _autoFontPadding;
style::font _autoFont;
anim::cvalue a_bg, a_text; anim::cvalue a_bg, a_text;
Animation _a_appearance; Animation _a_appearance;

View File

@ -351,7 +351,7 @@ void Checkbox::paintEvent(QPaintEvent *e) {
p.setRenderHint(QPainter::HighQualityAntialiasing, false); p.setRenderHint(QPainter::HighQualityAntialiasing, false);
if (checked > 0) { if (checked > 0) {
p.drawSpriteCenter(_checkRect, _st.checkIcon); _st.checkIcon.paint(p, QPoint(0, 0), width());
} }
} }
if (_checkRect.contains(r)) return; if (_checkRect.contains(r)) return;

View File

@ -27,6 +27,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "shortcuts.h" #include "shortcuts.h"
#include "lang.h" #include "lang.h"
#include "ui/buttons/peer_avatar_button.h" #include "ui/buttons/peer_avatar_button.h"
#include "ui/buttons/round_button.h"
#include "ui/flatbutton.h" #include "ui/flatbutton.h"
namespace Window { namespace Window {
@ -37,19 +38,15 @@ TopBarWidget::TopBarWidget(MainWidget *w) : TWidget(w)
, _selPeer(0) , _selPeer(0)
, _selCount(0) , _selCount(0)
, _canDelete(false) , _canDelete(false)
, _selStrLeft(-st::topBarButton.width / 2) , _selStrLeft((-st::topBarClearButton.width + st::topBarClearButton.padding.left() + st::topBarClearButton.padding.right()) / 2)
, _selStrWidth(0) , _selStrWidth(0)
, _animating(false) , _animating(false)
, _clearSelection(this, lang(lng_selected_clear), st::topBarButton) , _clearSelection(this, lang(lng_selected_clear), st::topBarClearButton)
, _forward(this, lang(lng_selected_forward), st::topBarActionButton) , _forward(this, lang(lng_selected_forward), st::topBarActionButton)
, _delete(this, lang(lng_selected_delete), st::topBarActionButton) , _delete(this, lang(lng_selected_delete), st::topBarActionButton)
, _selectionButtonsWidth(_clearSelection->width() + _forward->width() + _delete->width()) , _selectionButtonsWidth(_clearSelection->width() + _forward->width() + _delete->width())
, _forwardDeleteWidth(qMax(_forward->textWidth(), _delete->textWidth())) , _forwardDeleteWidth(qMax(_forward->textWidth(), _delete->textWidth()))
, _info(this, nullptr, st::infoButton) , _info(this, nullptr, st::infoButton)
, _edit(this, lang(lng_profile_edit_contact), st::topBarButton)
, _leaveGroup(this, lang(lng_profile_delete_and_exit), st::topBarButton)
, _addContact(this, lang(lng_profile_add_contact), st::topBarButton)
, _deleteContact(this, lang(lng_profile_delete_contact), st::topBarButton)
, _mediaType(this, lang(lng_media_type), st::topBarButton) , _mediaType(this, lang(lng_media_type), st::topBarButton)
, _search(this, st::topBarSearch) { , _search(this, st::topBarSearch) {
@ -57,10 +54,6 @@ TopBarWidget::TopBarWidget(MainWidget *w) : TWidget(w)
connect(_delete, SIGNAL(clicked()), this, SLOT(onDeleteSelection())); connect(_delete, SIGNAL(clicked()), this, SLOT(onDeleteSelection()));
connect(_clearSelection, SIGNAL(clicked()), this, SLOT(onClearSelection())); connect(_clearSelection, SIGNAL(clicked()), this, SLOT(onClearSelection()));
connect(_info, SIGNAL(clicked()), this, SLOT(onInfoClicked())); connect(_info, SIGNAL(clicked()), this, SLOT(onInfoClicked()));
connect(_addContact, SIGNAL(clicked()), this, SLOT(onAddContact()));
connect(_deleteContact, SIGNAL(clicked()), this, SLOT(onDeleteContact()));
connect(_edit, SIGNAL(clicked()), this, SLOT(onEdit()));
connect(_leaveGroup, SIGNAL(clicked()), this, SLOT(onDeleteAndExit()));
connect(_search, SIGNAL(clicked()), this, SLOT(onSearch())); connect(_search, SIGNAL(clicked()), this, SLOT(onSearch()));
setCursor(style::cur_pointer); setCursor(style::cur_pointer);
@ -84,65 +77,6 @@ void TopBarWidget::onInfoClicked() {
if (p) Ui::showPeerProfile(p); if (p) Ui::showPeerProfile(p);
} }
void TopBarWidget::onAddContact() {
PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0;
UserData *u = p ? p->asUser() : 0;
if (u) Ui::showLayer(new AddContactBox(u->firstName, u->lastName, u->phone().isEmpty() ? App::phoneFromSharedContact(peerToUser(u->id)) : u->phone()));
}
void TopBarWidget::onEdit() {
PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0;
if (p) {
if (p->isChannel()) {
Ui::showLayer(new EditChannelBox(p->asChannel()));
} else if (p->isChat()) {
Ui::showLayer(new EditNameTitleBox(p));
} else if (p->isUser()) {
Ui::showLayer(new AddContactBox(p->asUser()));
}
}
}
void TopBarWidget::onDeleteContact() {
PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0;
UserData *u = p ? p->asUser() : 0;
if (u) {
ConfirmBox *box = new ConfirmBox(lng_sure_delete_contact(lt_contact, p->name), lang(lng_box_delete));
connect(box, SIGNAL(confirmed()), this, SLOT(onDeleteContactSure()));
Ui::showLayer(box);
}
}
void TopBarWidget::onDeleteContactSure() {
PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0;
UserData *u = p ? p->asUser() : 0;
if (u) {
Ui::showChatsList();
Ui::hideLayer();
MTP::send(MTPcontacts_DeleteContact(u->inputUser), App::main()->rpcDone(&MainWidget::deletedContact, u));
}
}
void TopBarWidget::onDeleteAndExit() {
PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0;
ChatData *c = p ? p->asChat() : 0;
if (c) {
ConfirmBox *box = new ConfirmBox(lng_sure_delete_and_exit(lt_group, p->name), lang(lng_box_leave), st::attentionBoxButton);
connect(box, SIGNAL(confirmed()), this, SLOT(onDeleteAndExitSure()));
Ui::showLayer(box);
}
}
void TopBarWidget::onDeleteAndExitSure() {
PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0;
ChatData *c = p ? p->asChat() : 0;
if (c) {
Ui::showChatsList();
Ui::hideLayer();
MTP::send(MTPmessages_DeleteChatUser(c->inputChat, App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, p), App::main()->rpcFail(&MainWidget::leaveChatFailed, p));
}
}
void TopBarWidget::onSearch() { void TopBarWidget::onSearch() {
Shortcuts::launch(qsl("search")); Shortcuts::launch(qsl("search"));
} }
@ -197,7 +131,7 @@ void TopBarWidget::paintEvent(QPaintEvent *e) {
} else { } else {
p.setFont(st::linkFont); p.setFont(st::linkFont);
p.setPen(st::btnDefLink.color); p.setPen(st::btnDefLink.color);
p.drawText(_selStrLeft, st::topBarButton.textTop + st::linkFont->ascent, _selStr); p.drawText(_selStrLeft, st::topBarClearButton.padding.top() + st::topBarClearButton.textTop + st::linkFont->ascent, _selStr);
} }
} }
@ -211,8 +145,10 @@ void TopBarWidget::mousePressEvent(QMouseEvent *e) {
void TopBarWidget::resizeEvent(QResizeEvent *e) { void TopBarWidget::resizeEvent(QResizeEvent *e) {
int32 r = width(); int32 r = width();
if (!_forward->isHidden() || !_delete->isHidden()) { if (!_forward->isHidden() || !_delete->isHidden()) {
int32 fullW = r - (_selectionButtonsWidth + (_selStrWidth - st::topBarButton.width) + st::topBarActionSkip); int fullW = r - (_selectionButtonsWidth + (_selStrWidth - st::topBarClearButton.width + st::topBarClearButton.padding.left() + st::topBarClearButton.padding.right()) + st::topBarActionSkip);
int32 selectedClearWidth = st::topBarButton.width, forwardDeleteWidth = st::topBarActionButton.width - _forwardDeleteWidth, skip = st::topBarActionSkip; int selectedClearWidth = st::topBarClearButton.width - st::topBarClearButton.padding.left() - st::topBarClearButton.padding.right();
int forwardDeleteWidth = st::topBarActionButton.width - _forwardDeleteWidth;
int skip = st::topBarActionSkip;
while (fullW < 0) { while (fullW < 0) {
int fit = 0; int fit = 0;
if (selectedClearWidth < -2 * (st::topBarMinPadding + 1)) { if (selectedClearWidth < -2 * (st::topBarMinPadding + 1)) {
@ -245,7 +181,7 @@ void TopBarWidget::resizeEvent(QResizeEvent *e) {
} }
if (fullW >= 0 || fit >= 3) break; if (fullW >= 0 || fit >= 3) break;
} }
_clearSelection->setWidth(selectedClearWidth); _clearSelection->setFullWidth(selectedClearWidth);
_forward->setWidth(_forwardDeleteWidth + forwardDeleteWidth); _forward->setWidth(_forwardDeleteWidth + forwardDeleteWidth);
_delete->setWidth(_forwardDeleteWidth + forwardDeleteWidth); _delete->setWidth(_forwardDeleteWidth + forwardDeleteWidth);
_selStrLeft = -selectedClearWidth / 2; _selStrLeft = -selectedClearWidth / 2;
@ -262,20 +198,12 @@ void TopBarWidget::resizeEvent(QResizeEvent *e) {
_clearSelection->move(r -= _clearSelection->width(), 0); _clearSelection->move(r -= _clearSelection->width(), 0);
} }
if (!_info->isHidden()) _info->move(r -= _info->width(), 0); if (!_info->isHidden()) _info->move(r -= _info->width(), 0);
if (!_deleteContact->isHidden()) _deleteContact->move(r -= _deleteContact->width(), 0);
if (!_leaveGroup->isHidden()) _leaveGroup->move(r -= _leaveGroup->width(), 0);
if (!_edit->isHidden()) _edit->move(r -= _edit->width(), 0);
if (!_addContact->isHidden()) _addContact->move(r -= _addContact->width(), 0);
if (!_mediaType->isHidden()) _mediaType->move(r -= _mediaType->width(), 0); if (!_mediaType->isHidden()) _mediaType->move(r -= _mediaType->width(), 0);
_search->move(width() - (_info->isHidden() ? st::topBarForwardPadding.right() : _info->width()) - _search->width(), 0); _search->move(width() - (_info->isHidden() ? st::topBarForwardPadding.right() : _info->width()) - _search->width(), 0);
} }
void TopBarWidget::startAnim() { void TopBarWidget::startAnim() {
_info->hide(); _info->hide();
_edit->hide();
_leaveGroup->hide();
_addContact->hide();
_deleteContact->hide();
_clearSelection->hide(); _clearSelection->hide();
_delete->hide(); _delete->hide();
_forward->hide(); _forward->hide();
@ -295,44 +223,8 @@ void TopBarWidget::showAll() {
resizeEvent(0); resizeEvent(0);
return; return;
} }
PeerData *p = nullptr/*App::main() ? App::main()->profilePeer() : 0*/, *h = App::main() ? App::main()->historyPeer() : 0, *o = App::main() ? App::main()->overviewPeer() : 0; PeerData *h = App::main() ? App::main()->historyPeer() : 0, *o = App::main() ? App::main()->overviewPeer() : 0;
if (p && (p->isChat() || (p->isUser() && (p->asUser()->contact >= 0 || !App::phoneFromSharedContact(peerToUser(p->id)).isEmpty())))) { if (_selCount) {
if (p->isChat()) {
if (p->asChat()->canEdit()) {
_edit->show();
} else {
_edit->hide();
}
_leaveGroup->show();
_addContact->hide();
_deleteContact->hide();
} else if (p->asUser()->contact > 0) {
_edit->show();
_leaveGroup->hide();
_addContact->hide();
_deleteContact->show();
} else {
_edit->hide();
_leaveGroup->hide();
_addContact->show();
_deleteContact->hide();
}
_clearSelection->hide();
_info->hide();
_delete->hide();
_forward->hide();
_mediaType->hide();
_search->hide();
} else {
if (p && p->isChannel() && (p->asChannel()->amCreator() || (p->isMegagroup() && p->asChannel()->amEditor()))) {
_edit->show();
} else {
_edit->hide();
}
_leaveGroup->hide();
_addContact->hide();
_deleteContact->hide();
if (!p && _selCount) {
_clearSelection->show(); _clearSelection->show();
if (_canDelete) { if (_canDelete) {
_delete->show(); _delete->show();
@ -351,7 +243,7 @@ void TopBarWidget::showAll() {
_mediaType->hide(); _mediaType->hide();
} }
} }
if (h && !o && !p && _clearSelection->isHidden()) { if (h && !o && _clearSelection->isHidden()) {
if (Adaptive::OneColumn()) { if (Adaptive::OneColumn()) {
_info->setPeer(h); _info->setPeer(h);
_info->show(); _info->show();
@ -363,7 +255,6 @@ void TopBarWidget::showAll() {
_search->hide(); _search->hide();
_info->hide(); _info->hide();
} }
}
resizeEvent(nullptr); resizeEvent(nullptr);
} }
@ -382,7 +273,7 @@ void TopBarWidget::updateAdaptiveLayout() {
showAll(); showAll();
} }
FlatButton *TopBarWidget::mediaTypeButton() { Ui::RoundButton *TopBarWidget::mediaTypeButton() {
return _mediaType; return _mediaType;
} }

View File

@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
namespace Ui { namespace Ui {
class PeerAvatarButton; class PeerAvatarButton;
class RoundButton;
} // namespace Ui } // namespace Ui
class FlatButton; class FlatButton;
class IconedButton; class IconedButton;
@ -34,7 +35,6 @@ class TopBarWidget : public TWidget {
Q_OBJECT Q_OBJECT
public: public:
TopBarWidget(MainWidget *w); TopBarWidget(MainWidget *w);
void enterEvent(QEvent *e) override; void enterEvent(QEvent *e) override;
@ -54,28 +54,19 @@ public:
void updateAdaptiveLayout(); void updateAdaptiveLayout();
FlatButton *mediaTypeButton(); Ui::RoundButton *mediaTypeButton();
public slots: public slots:
void onForwardSelection(); void onForwardSelection();
void onDeleteSelection(); void onDeleteSelection();
void onClearSelection(); void onClearSelection();
void onInfoClicked(); void onInfoClicked();
void onAddContact();
void onEdit();
void onDeleteContact();
void onDeleteContactSure();
void onDeleteAndExit();
void onDeleteAndExitSure();
void onSearch(); void onSearch();
signals: signals:
void clicked(); void clicked();
private: private:
MainWidget *main(); MainWidget *main();
anim::fvalue a_over; anim::fvalue a_over;
Animation _a_appearance; Animation _a_appearance;
@ -88,13 +79,12 @@ private:
bool _animating; bool _animating;
ChildWidget<FlatButton> _clearSelection; ChildWidget<Ui::RoundButton> _clearSelection;
ChildWidget<FlatButton> _forward, _delete; ChildWidget<FlatButton> _forward, _delete;
int _selectionButtonsWidth, _forwardDeleteWidth; int _selectionButtonsWidth, _forwardDeleteWidth;
ChildWidget<Ui::PeerAvatarButton> _info; ChildWidget<Ui::PeerAvatarButton> _info;
ChildWidget<FlatButton> _edit, _leaveGroup, _addContact, _deleteContact; ChildWidget<Ui::RoundButton> _mediaType;
ChildWidget<FlatButton> _mediaType;
ChildWidget<IconedButton> _search; ChildWidget<IconedButton> _search;

View File

@ -1231,6 +1231,7 @@
<ClCompile Include="SourceFiles\dialogs\dialogs_indexed_list.cpp" /> <ClCompile Include="SourceFiles\dialogs\dialogs_indexed_list.cpp" />
<ClCompile Include="SourceFiles\dialogs\dialogs_layout.cpp" /> <ClCompile Include="SourceFiles\dialogs\dialogs_layout.cpp" />
<ClCompile Include="SourceFiles\dialogs\dialogs_list.cpp" /> <ClCompile Include="SourceFiles\dialogs\dialogs_list.cpp" />
<ClCompile Include="SourceFiles\dialogs\dialogs_row.cpp" />
<ClCompile Include="SourceFiles\dropdown.cpp" /> <ClCompile Include="SourceFiles\dropdown.cpp" />
<ClCompile Include="SourceFiles\facades.cpp" /> <ClCompile Include="SourceFiles\facades.cpp" />
<ClCompile Include="SourceFiles\fileuploader.cpp" /> <ClCompile Include="SourceFiles\fileuploader.cpp" />

View File

@ -1296,6 +1296,9 @@
<ClCompile Include="GeneratedFiles\Release\moc_report_box.cpp"> <ClCompile Include="GeneratedFiles\Release\moc_report_box.cpp">
<Filter>GeneratedFiles\Release</Filter> <Filter>GeneratedFiles\Release</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="SourceFiles\dialogs\dialogs_row.cpp">
<Filter>SourceFiles\dialogs</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="SourceFiles\stdafx.h"> <ClInclude Include="SourceFiles\stdafx.h">