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).
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 177 KiB |
Before Width: | Height: | Size: 240 KiB After Width: | Height: | Size: 239 KiB |
|
@ -56,6 +56,7 @@ adaptiveNormalWidth: 640px;
|
|||
adaptiveWideWidth: 1366px;
|
||||
|
||||
windowBg: #fff; // fallback for background: white
|
||||
windowActiveBg: #40ace3; // fallback for blue filled active areas
|
||||
windowTextFg: #000; // fallback for text color: black
|
||||
windowSubTextFg: #8a8a8a; // fallback for subtext color: gray
|
||||
windowActiveTextFg: #1485c2; // fallback for active color: blue online
|
||||
|
@ -114,6 +115,7 @@ defaultBoxButton: BoxButton {
|
|||
|
||||
width: -24px;
|
||||
height: 36px;
|
||||
padding: margins(0px, 0px, 0px, 0px);
|
||||
|
||||
textTop: 8px;
|
||||
|
||||
|
@ -149,7 +151,7 @@ boxLabel: flatLabel(labelDefFlat) {
|
|||
defaultLeftOutlineButton: OutlineButton {
|
||||
outlineWidth: 3px;
|
||||
outlineFg: windowBg;
|
||||
outlineFgOver: #3fb0e4;
|
||||
outlineFgOver: windowActiveBg;
|
||||
|
||||
textBg: windowBg;
|
||||
textBgOver: #f2f7fa;
|
||||
|
@ -230,9 +232,9 @@ defaultCheckbox: Checkbox {
|
|||
textFg: black;
|
||||
textBg: white;
|
||||
|
||||
checkFg: #d9d9d9;
|
||||
checkFgOver: #bfbfbf;
|
||||
checkFgActive: #4eb3ee;
|
||||
checkFg: #b3b3b3;
|
||||
checkFgOver: #b3b3b3;
|
||||
checkFgActive: #40ace3;
|
||||
|
||||
width: -46px;
|
||||
height: 22px;
|
||||
|
@ -240,7 +242,9 @@ defaultCheckbox: Checkbox {
|
|||
textPosition: point(34px, 0px);
|
||||
diameter: 22px;
|
||||
thickness: 2px;
|
||||
checkIcon: sprite(106px, 136px, 14px, 10px);
|
||||
checkIcon: icon {
|
||||
{ "default_checkbox_check", #ffffff, point(4px, 7px) }
|
||||
};
|
||||
|
||||
font: boxTextFont;
|
||||
duration: 120;
|
||||
|
@ -249,7 +253,7 @@ defaultRadiobutton: Radiobutton {
|
|||
textFg: black;
|
||||
textBg: white;
|
||||
|
||||
checkFg: #d9d9d9;
|
||||
checkFg: #b3b3b3;
|
||||
checkFgOver: #bfbfbf;
|
||||
checkFgActive: #4eb3ee;
|
||||
|
||||
|
@ -908,46 +912,22 @@ btnLogout: flatButton(btnDefFlat, btnDefBig) {
|
|||
overFont: font(18px);
|
||||
}
|
||||
|
||||
//// dialogs
|
||||
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) {
|
||||
searchFlatInput: flatInput(inpDefGray) {
|
||||
font: font(fsize);
|
||||
height: 34px;
|
||||
bgColor: #f2f2f2;
|
||||
phColor: #949494;
|
||||
phFocusColor: #a4a4a4;
|
||||
textMrg: margins(34px, 2px, 34px, 4px);
|
||||
imgRect: sprite(227px, 21px, 24px, 24px);
|
||||
imgPos: point(6px, 5px);
|
||||
width: 240px;
|
||||
|
||||
borderWidth: 2px;
|
||||
borderColor: #f2f2f2;
|
||||
borderActive: #80cff9;
|
||||
borderError: #ed8080;
|
||||
}
|
||||
dlgScroll: flatScroll(scrollDef) {
|
||||
topsh: 0px;
|
||||
bottomsh: 0px;
|
||||
}
|
||||
dlgFont: font(fsize);
|
||||
|
||||
noContactsHeight: 100px;
|
||||
noContactsFont: font(fsize);
|
||||
noContactsColor: #777;
|
||||
|
||||
dlgDblCheckImg: sprite(302px, 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);
|
||||
dlgActiveSendImg: sprite(142px, 25px, 17px, 11px);
|
||||
|
||||
dlgChatImgPos: point(1px, 4px);
|
||||
dlgChatImg: sprite(104px, 26px, 16px, 11px);
|
||||
dlgActiveChatImg: sprite(104px, 37px, 16px, 11px);
|
||||
dlgChannelImgPos: point(3px, 4px);
|
||||
dlgChannelImg: sprite(105px, 1px, 12px, 11px);
|
||||
dlgActiveChannelImg: sprite(105px, 14px, 12px, 11px);
|
||||
dlgImgSkip: 22px;
|
||||
|
||||
dlgCheckLeft: 5px;
|
||||
dlgCheckTop: 4px;
|
||||
dlgCheckSkip: 3px;
|
||||
|
||||
dlgHistFont: font(fsize);
|
||||
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;
|
||||
dlgFilter: flatInput(searchFlatInput) {
|
||||
width: 240px;
|
||||
height: 34px;
|
||||
textMrg: margins(34px, 2px, 34px, 4px);
|
||||
imgPos: point(6px, 5px);
|
||||
}
|
||||
|
||||
topBarHeight: 54px;
|
||||
topBarBG: white;
|
||||
|
@ -1024,24 +976,23 @@ topBarSearch: iconedButton(btnDefIconed) {
|
|||
height: topBarHeight;
|
||||
}
|
||||
topBarMinPadding: 5px;
|
||||
topBarButton: flatButton(btnDefFlat) {
|
||||
color: btnYesColor;
|
||||
overColor: btnYesHover;
|
||||
downColor: btnYesHover;
|
||||
topBarButton: BoxButton {
|
||||
textFg: #0084c4;
|
||||
textFgOver: #0084c4;
|
||||
textBg: white;
|
||||
textBgOver: #edf4f7;
|
||||
|
||||
bgColor: white;
|
||||
overBgColor: white;
|
||||
downBgColor: white;
|
||||
width: -22px;
|
||||
height: 28px;
|
||||
padding: margins(0px, 14px, 12px, 12px);
|
||||
|
||||
width: -40px;
|
||||
height: 54px;
|
||||
|
||||
textTop: 19px;
|
||||
overTextTop: 19px;
|
||||
downTextTop: 20px;
|
||||
textTop: 6px;
|
||||
|
||||
font: font(fsize);
|
||||
overFont: font(fsize underline);
|
||||
duration: 200;
|
||||
}
|
||||
topBarClearButton: BoxButton(topBarButton) {
|
||||
padding: margins(8px, 14px, 8px, 14px);
|
||||
}
|
||||
topBarActionButton: flatButton(btnDefNext, btnDefBig) {
|
||||
textTop: 8px;
|
||||
|
@ -1243,16 +1194,6 @@ medviewSaveAsTextStyle: textStyle(defaultTextStyle) {
|
|||
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) {
|
||||
lineHeight: 30px;
|
||||
}
|
||||
|
@ -1538,16 +1479,24 @@ taMsgField: flatTextarea(taDefFlat) {
|
|||
maxFieldHeight: 220px;
|
||||
// historyMinHeight: 56px;
|
||||
|
||||
reportSpamHide: flatButton(topBarButton) {
|
||||
reportSpamHide: flatButton(btnDefFlat) {
|
||||
color: btnYesColor;
|
||||
overColor: btnYesHover;
|
||||
downColor: btnYesHover;
|
||||
|
||||
bgColor: transparent;
|
||||
overBgColor: transparent;
|
||||
downBgColor: transparent;
|
||||
|
||||
width: -40px;
|
||||
height: 46px;
|
||||
|
||||
textTop: 15px;
|
||||
overTextTop: 15px;
|
||||
downTextTop: 16px;
|
||||
|
||||
bgColor: transparent;
|
||||
overBgColor: transparent;
|
||||
downBgColor: transparent;
|
||||
font: font(fsize);
|
||||
overFont: font(fsize underline);
|
||||
}
|
||||
reportSpamButton: flatButton(reportSpamHide) {
|
||||
textTop: 6px;
|
||||
|
@ -1687,134 +1636,16 @@ confirmCompressedSkip: 10px;
|
|||
|
||||
profileMaxWidth: 410px;
|
||||
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;
|
||||
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);
|
||||
|
||||
forwardMargins: margins(30px, 10px, 30px, 10px);
|
||||
forwardFont: font(16px);
|
||||
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;
|
||||
newGroupPadding: margins(4px, 6px, 4px, 3px);
|
||||
newGroupSkip: 17px;
|
||||
|
@ -1855,15 +1686,6 @@ connectionPasswordInputField: InputField(defaultInputField) {
|
|||
}
|
||||
connectionIPv6Skip: 11px;
|
||||
|
||||
contactsAdd: flatButton(topBarButton) {
|
||||
width: -40px;
|
||||
height: 52px;
|
||||
|
||||
textTop: 18px;
|
||||
overTextTop: 18px;
|
||||
downTextTop: 19px;
|
||||
}
|
||||
|
||||
aboutIcon: sprite(0px, 0px, 104px, 104px);
|
||||
aboutWidth: 390px;
|
||||
aboutVersionTop: -3px;
|
||||
|
@ -2131,8 +1953,6 @@ stickerPreviewDuration: 150;
|
|||
stickerPreviewBg: #FFFFFFB0;
|
||||
stickerPreviewMin: 0.1;
|
||||
|
||||
verifiedCheckProfile: sprite(285px, 235px, 18px, 18px);
|
||||
verifiedCheckProfilePos: point(7px, 6px);
|
||||
verifiedCheck: sprite(285px, 221px, 14px, 14px);
|
||||
verifiedCheckInv: sprite(299px, 221px, 14px, 14px);
|
||||
verifiedCheckPos: point(4px, 2px);
|
||||
|
@ -2419,7 +2239,7 @@ sessionNameFont: msgNameFont;
|
|||
sessionActiveFont: msgDateFont;
|
||||
sessionActiveColor: #aaa;
|
||||
sessionInfoFont: msgFont;
|
||||
sessionInfoColor: dlgTextColor;
|
||||
sessionInfoColor: #888888;
|
||||
sessionTerminateTop: 30px;
|
||||
sessionTerminateSkip: 18px;
|
||||
sessionTerminate: iconedButton(notifyClose) {
|
||||
|
|
|
@ -305,6 +305,7 @@ BoxButton {
|
|||
|
||||
width: pixels;
|
||||
height: pixels;
|
||||
padding: margins;
|
||||
|
||||
textTop: pixels;
|
||||
|
||||
|
@ -328,7 +329,7 @@ Checkbox {
|
|||
textPosition: point;
|
||||
diameter: pixels;
|
||||
thickness: pixels;
|
||||
checkIcon: sprite;
|
||||
checkIcon: icon;
|
||||
|
||||
font: font;
|
||||
duration: int;
|
||||
|
|
BIN
Telegram/Resources/icons/default_checkbox_check.png
Normal file
After Width: | Height: | Size: 136 B |
BIN
Telegram/Resources/icons/default_checkbox_check@2x.png
Normal file
After Width: | Height: | Size: 255 B |
Before Width: | Height: | Size: 247 B |
Before Width: | Height: | Size: 464 B |
Before Width: | Height: | Size: 313 B After Width: | Height: | Size: 300 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 559 B |
BIN
Telegram/Resources/icons/profile_verified_check.png
Normal file
After Width: | Height: | Size: 222 B |
BIN
Telegram/Resources/icons/profile_verified_check@2x.png
Normal file
After Width: | Height: | Size: 375 B |
BIN
Telegram/Resources/icons/profile_verified_star.png
Normal file
After Width: | Height: | Size: 345 B |
BIN
Telegram/Resources/icons/profile_verified_star@2x.png
Normal file
After Width: | Height: | Size: 750 B |
Before Width: | Height: | Size: 137 B After Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 252 B After Width: | Height: | Size: 344 B |
|
@ -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_gif_error" = "An error has occured while reading GIF animation :(";
|
||||
"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_too_long" = "Your message text is too long";
|
||||
"lng_edit_message" = "Edit message";
|
||||
|
|
|
@ -26,13 +26,16 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "application.h"
|
||||
#include "mainwindow.h"
|
||||
#include "mainwidget.h"
|
||||
#include "historywidget.h"
|
||||
#include "localstorage.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
|
||||
ApiWrap::ApiWrap(QObject *parent) : QObject(parent)
|
||||
, _messageDataResolveDelayed(new SingleDelayedCall(this, "resolveMessageDatas")) {
|
||||
App::initBackground();
|
||||
|
||||
connect(&_webPagesTimer, SIGNAL(timeout()), this, SLOT(resolveWebPages()));
|
||||
connect(&_draftsSaveTimer, SIGNAL(timeout()), this, SLOT(saveDraftsToCloud()));
|
||||
}
|
||||
|
||||
void ApiWrap::init() {
|
||||
|
@ -717,6 +720,9 @@ void ApiWrap::channelAmInDone(ChannelData *channel, const MTPUpdates &updates) {
|
|||
bool ApiWrap::channelAmInFail(ChannelData *channel, const RPCError &error) {
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
@ -798,6 +804,83 @@ void ApiWrap::requestNotifySetting(PeerData *peer) {
|
|||
_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) {
|
||||
if (auto requestedPeer = notifySettingReceived(notifyPeer, result)) {
|
||||
_notifySettingRequests.remove(requestedPeer);
|
||||
|
|
|
@ -59,6 +59,9 @@ public:
|
|||
void exportInviteLink(PeerData *peer);
|
||||
void requestNotifySetting(PeerData *peer);
|
||||
|
||||
void saveDraftToCloudDelayed(History *history);
|
||||
bool hasUnsavedDrafts() const;
|
||||
|
||||
~ApiWrap();
|
||||
|
||||
signals:
|
||||
|
@ -71,6 +74,7 @@ public slots:
|
|||
void resolveWebPages();
|
||||
|
||||
void delayedRequestParticipantsCount();
|
||||
void saveDraftsToCloud();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -150,5 +154,9 @@ private:
|
|||
PeerData *notifySettingReceived(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings);
|
||||
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);
|
||||
|
||||
};
|
||||
|
|
|
@ -2257,6 +2257,19 @@ namespace {
|
|||
if (quitting()) return;
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -2264,6 +2277,12 @@ namespace {
|
|||
return _launchState != Launched;
|
||||
}
|
||||
|
||||
void allDraftsSaved() {
|
||||
if (quitting()) {
|
||||
Application::quit();
|
||||
}
|
||||
}
|
||||
|
||||
LaunchState launchState() {
|
||||
return _launchState;
|
||||
}
|
||||
|
|
|
@ -228,6 +228,7 @@ namespace App {
|
|||
};
|
||||
void quit();
|
||||
bool quitting();
|
||||
void allDraftsSaved();
|
||||
LaunchState launchState();
|
||||
void setLaunchState(LaunchState state);
|
||||
|
||||
|
|
|
@ -656,7 +656,8 @@ void EditCaptionBox::onSave(bool ctrlShiftEnter) {
|
|||
if (!sentEntities.c_vector().v.isEmpty()) {
|
||||
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) {
|
||||
|
|
|
@ -151,8 +151,10 @@ enum {
|
|||
|
||||
WriteMapTimeout = 1000,
|
||||
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
|
||||
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
|
||||
|
||||
|
|
|
@ -19,7 +19,69 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
|||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
using "basic.style";
|
||||
using "basic_types.style";
|
||||
|
||||
dialogsDraft: icon {
|
||||
{ "dialogs_draft", #ffffff, point(5px, 4px) },
|
||||
};
|
||||
dialogsUnreadFg: #ffffff;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -42,80 +42,68 @@ void paintRowDate(Painter &p, const QDateTime &date, QRect &rectForName, bool ac
|
|||
} else {
|
||||
dt = lastDate.toString(qsl("d.MM.yy"));
|
||||
}
|
||||
int32 dtWidth = st::dlgDateFont->width(dt);
|
||||
rectForName.setWidth(rectForName.width() - dtWidth - st::dlgDateSkip);
|
||||
p.setFont(st::dlgDateFont);
|
||||
p.setPen(active ? st::dlgActiveDateColor : st::dlgDateColor);
|
||||
p.drawText(rectForName.left() + rectForName.width() + st::dlgDateSkip, rectForName.top() + st::msgNameFont->height - st::msgDateFont->descent, dt);
|
||||
int32 dtWidth = st::dialogsDateFont->width(dt);
|
||||
rectForName.setWidth(rectForName.width() - dtWidth - st::dialogsDateSkip);
|
||||
p.setFont(st::dialogsDateFont);
|
||||
p.setPen(active ? st::dialogsDateFgActive : st::dialogsDateFg);
|
||||
p.drawText(rectForName.left() + rectForName.width() + st::dialogsDateSkip, rectForName.top() + st::msgNameFont->height - st::msgDateFont->descent, dt);
|
||||
}
|
||||
|
||||
template <typename 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);
|
||||
p.fillRect(fullRect, active ? st::dlgActiveBG : (selected ? st::dlgHoverBG : st::dlgBG));
|
||||
QRect fullRect(0, 0, w, st::dialogsRowHeight);
|
||||
p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
|
||||
if (onlyBackground) return;
|
||||
|
||||
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 namewidth = w - nameleft - st::dlgPaddingHor;
|
||||
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height);
|
||||
int32 nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
||||
int32 namewidth = w - nameleft - st::dialogsPadding.x();
|
||||
QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height);
|
||||
|
||||
// draw chat icon
|
||||
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));
|
||||
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dialogsChatImgPos.x(), rectForName.top() + st::dialogsChatImgPos.y()), (active ? st::dlgActiveChatImg : st::dlgChatImg));
|
||||
rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
|
||||
} else if (history->peer->isChannel()) {
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dlgChannelImgPos.x(), rectForName.top() + st::dlgChannelImgPos.y()), (active ? st::dlgActiveChannelImg : st::dlgChannelImg));
|
||||
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dialogsChannelImgPos.x(), rectForName.top() + st::dialogsChannelImgPos.y()), (active ? st::dlgActiveChannelImg : st::dlgChannelImg));
|
||||
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) {
|
||||
paintRowDate(p, draft->date, rectForName, active);
|
||||
|
||||
// draw check
|
||||
if (draft->saveRequestId) {
|
||||
auto check = active ? &st::dlgActiveSendImg : &st::dlgSendImg;
|
||||
rectForName.setWidth(rectForName.width() - check->pxWidth() - st::dlgCheckSkip);
|
||||
p.drawSprite(QPoint(rectForName.left() + rectForName.width() + st::dlgCheckLeft, rectForName.top() + st::dlgCheckTop), *check);
|
||||
rectForName.setWidth(rectForName.width() - check->pxWidth() - st::dialogsCheckSkip);
|
||||
p.drawSprite(QPoint(rectForName.left() + rectForName.width() + st::dialogsCheckLeft, rectForName.top() + st::dialogsCheckTop), *check);
|
||||
}
|
||||
|
||||
bool hasDraftIcon = !active;
|
||||
if (hasDraftIcon) {
|
||||
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);
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFgService);
|
||||
if (history->typing.isEmpty() && history->sendActions.isEmpty()) {
|
||||
if (history->cloudDraftTextCache.isEmpty()) {
|
||||
TextCustomTagsMap custom;
|
||||
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));
|
||||
history->cloudDraftTextCache.setRichText(st::dlgHistFont, msg, _textDlgOptions, custom);
|
||||
history->cloudDraftTextCache.setRichText(st::dialogsTextFont, msg, _textDlgOptions, custom);
|
||||
}
|
||||
textstyleSet(&(active ? st::dlgActiveTextStyle : st::dlgTextStyle));
|
||||
p.setFont(st::dlgHistFont);
|
||||
p.setPen(active ? st::dlgActiveColor : st::dlgTextColor);
|
||||
history->cloudDraftTextCache.drawElided(p, nameleft, texttop, namewidth, st::dlgFont->height / st::dlgHistFont->height);
|
||||
textstyleSet(&(active ? st::dialogsTextStyleActive : st::dialogsTextStyleDraft));
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFg);
|
||||
history->cloudDraftTextCache.drawElided(p, nameleft, texttop, namewidth, 1);
|
||||
textstyleRestore();
|
||||
} else {
|
||||
history->typingText.drawElided(p, nameleft, texttop, namewidth);
|
||||
}
|
||||
} else if (!item) {
|
||||
p.setFont(st::dlgHistFont);
|
||||
p.setPen(active ? st::dlgActiveColor : st::dlgSystemColor);
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFgService);
|
||||
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 {
|
||||
history->typingText.drawElided(p, nameleft, texttop, namewidth);
|
||||
}
|
||||
|
@ -134,8 +122,8 @@ void paintRow(Painter &p, History *history, HistoryItem *item, HistoryDraft *dra
|
|||
} else {
|
||||
check = active ? &st::dlgActiveSendImg : &st::dlgSendImg;
|
||||
}
|
||||
rectForName.setWidth(rectForName.width() - check->pxWidth() - st::dlgCheckSkip);
|
||||
p.drawSprite(QPoint(rectForName.left() + rectForName.width() + st::dlgCheckLeft, rectForName.top() + st::dlgCheckTop), *check);
|
||||
rectForName.setWidth(rectForName.width() - check->pxWidth() - st::dialogsCheckSkip);
|
||||
p.drawSprite(QPoint(rectForName.left() + rectForName.width() + st::dialogsCheckLeft, rectForName.top() + st::dialogsCheckTop), *check);
|
||||
}
|
||||
|
||||
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.setPen(active ? st::dlgActiveColor : st::dlgNameColor);
|
||||
p.setPen(active ? st::dialogsTextFgActive : st::dialogsNameFg);
|
||||
history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
||||
}
|
||||
|
||||
|
@ -154,7 +142,7 @@ class UnreadBadgeStyle : public StyleSheet {
|
|||
public:
|
||||
QImage circle;
|
||||
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;
|
||||
|
||||
|
@ -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) {
|
||||
int unreadWidth = st::dlgUnreadFont->width(text);
|
||||
int unreadRectWidth = unreadWidth + 2 * st::dlgUnreadPaddingHor;
|
||||
int unreadRectHeight = st::dlgUnreadHeight;
|
||||
int unreadWidth = st::dialogsUnreadFont->width(text);
|
||||
int unreadRectWidth = unreadWidth + 2 * st::dialogsUnreadPadding;
|
||||
int unreadRectHeight = st::dialogsUnreadHeight;
|
||||
accumulate_max(unreadRectWidth, unreadRectHeight);
|
||||
|
||||
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);
|
||||
|
||||
p.setFont(st::dlgUnreadFont);
|
||||
p.setPen(active ? st::dlgActiveUnreadColor : st::dlgUnreadColor);
|
||||
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + st::dlgUnreadTop + st::dlgUnreadFont->ascent, text);
|
||||
p.setFont(st::dialogsUnreadFont);
|
||||
p.setPen(active ? st::dialogsUnreadFgActive : st::dialogsUnreadFg);
|
||||
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) {
|
||||
|
@ -241,30 +229,20 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele
|
|||
}
|
||||
}
|
||||
int availableWidth = namewidth;
|
||||
int texttop = st::dlgPaddingVer + st::dlgFont->height + st::dlgSep;
|
||||
auto cloudDraft = history->cloudDraft();
|
||||
bool hasDraftIcon = active ? false : (cloudDraft && cloudDraft->date.isValid());
|
||||
if (unread || hasDraftIcon) {
|
||||
QString counter;
|
||||
bool mutedCounter = false;
|
||||
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 texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
|
||||
if (unread) {
|
||||
auto counter = QString::number(unread);
|
||||
auto mutedCounter = history->mute();
|
||||
int unreadRight = w - st::dialogsPadding.x();
|
||||
int unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - st::dialogsUnreadTop;
|
||||
int unreadWidth = 0;
|
||||
paintUnreadCount(p, counter, unreadRight, unreadTop, style::al_right, active, mutedCounter, &unreadWidth);
|
||||
if (!showUnreadCounter) {
|
||||
st::dialogsDraft.paint(p, QPoint(w - st::dlgPaddingHor - st::dlgUnreadHeight, unreadTop), w);
|
||||
}
|
||||
availableWidth -= unreadWidth + st::dlgUnreadPaddingHor;
|
||||
availableWidth -= unreadWidth + st::dialogsUnreadPadding;
|
||||
}
|
||||
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 {
|
||||
p.setPen(active ? st::dlgActiveColor : st::dlgSystemColor);
|
||||
p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFgService);
|
||||
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 history = item->history();
|
||||
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;
|
||||
item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dlgFont->height), active, row->_cacheFor, row->_cache);
|
||||
int lastWidth = namewidth, texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
|
||||
item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dialogsTextFont->height), active, row->_cacheFor, row->_cache);
|
||||
});
|
||||
}
|
||||
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
@ -288,15 +266,15 @@ void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool o
|
|||
p.setFont(st::semiboldFont);
|
||||
p.setPen(st::black);
|
||||
|
||||
int unreadTop = (st::dlgImportantHeight - st::dlgUnreadHeight) / 2;
|
||||
int unreadTop = (st::dialogsImportantBarHeight - st::dialogsUnreadHeight) / 2;
|
||||
bool mutedHidden = (current == Dialogs::Mode::Important);
|
||||
QString text = mutedHidden ? qsl("Show all chats") : qsl("Hide muted chats");
|
||||
int textBaseline = unreadTop + st::dlgUnreadTop + st::dlgUnreadFont->ascent;
|
||||
p.drawText(st::dlgPaddingHor, textBaseline, text);
|
||||
int textBaseline = unreadTop + st::dialogsUnreadTop + st::dialogsUnreadFont->ascent;
|
||||
p.drawText(st::dialogsPadding.x(), textBaseline, text);
|
||||
|
||||
if (mutedHidden) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "dialogs/dialogs_list.h"
|
||||
|
||||
#include "dialogs/dialogs_layout.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "mainwidget.h"
|
||||
|
||||
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 {
|
||||
adjustCurrent(hFrom, st::dlgHeight);
|
||||
adjustCurrent(hFrom, st::dialogsRowHeight);
|
||||
|
||||
Row *row = _current;
|
||||
p.translate(0, row->_pos * st::dlgHeight);
|
||||
while (row != _end && row->_pos * st::dlgHeight < hTo) {
|
||||
p.translate(0, row->_pos * st::dialogsRowHeight);
|
||||
while (row != _end && row->_pos * st::dialogsRowHeight < hTo) {
|
||||
bool active = (row->history()->peer == act) || (row->history()->peer->migrateTo() && row->history()->peer->migrateTo() == act);
|
||||
bool selected = (row->history()->peer == sel);
|
||||
Layout::RowPainter::paint(p, row, w, active, selected, onlyBackground);
|
||||
row = row->_next;
|
||||
p.translate(0, st::dlgHeight);
|
||||
p.translate(0, st::dialogsRowHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
31
Telegram/SourceFiles/dialogs/dialogs_row.cpp
Normal 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
|
|
@ -59,8 +59,7 @@ private:
|
|||
|
||||
class FakeRow {
|
||||
public:
|
||||
FakeRow(HistoryItem *item) : _item(item) {
|
||||
}
|
||||
FakeRow(HistoryItem *item);
|
||||
|
||||
HistoryItem *item() const {
|
||||
return _item;
|
||||
|
@ -71,7 +70,7 @@ private:
|
|||
|
||||
HistoryItem *_item;
|
||||
mutable const HistoryItem *_cacheFor = nullptr;
|
||||
mutable Text _cache = Text{ int(st::dlgRichMinWidth) };
|
||||
mutable Text _cache;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "dialogs/dialogs_indexed_list.h"
|
||||
#include "dialogs/dialogs_layout.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "data/drafts.h"
|
||||
#include "lang.h"
|
||||
#include "application.h"
|
||||
|
@ -55,7 +56,7 @@ DialogsInner::DialogsInner(QWidget *parent, MainWidget *main) : SplittedWidget(p
|
|||
}
|
||||
|
||||
int DialogsInner::dialogsOffset() const {
|
||||
return importantDialogs ? st::dlgImportantHeight : 0;
|
||||
return importantDialogs ? st::dialogsImportantBarHeight : 0;
|
||||
}
|
||||
|
||||
int DialogsInner::filteredOffset() const {
|
||||
|
@ -63,12 +64,12 @@ int DialogsInner::filteredOffset() 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 result = peopleOffset() + (_peopleResults.isEmpty() ? 0 : ((_peopleResults.size() * st::dlgHeight) + st::searchedBarHeight));
|
||||
if (_searchInPeer) result += st::dlgHeight;
|
||||
int result = peopleOffset() + (_peopleResults.isEmpty() ? 0 : ((_peopleResults.size() * st::dialogsRowHeight) + st::searchedBarHeight));
|
||||
if (_searchInPeer) result += st::dialogsRowHeight;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -87,10 +88,10 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
|||
QRect dialogsClip = r;
|
||||
if (importantDialogs) {
|
||||
Dialogs::Layout::paintImportantSwitch(p, Global::DialogsMode(), fullWidth(), _importantSwitchSel, paintingOther);
|
||||
dialogsClip.translate(0, -st::dlgImportantHeight);
|
||||
p.translate(0, st::dlgImportantHeight);
|
||||
dialogsClip.translate(0, -st::dialogsImportantBarHeight);
|
||||
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);
|
||||
if (otherStart) {
|
||||
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 ®ion, bool paintingO
|
|||
int32 to = ceilclamp(r.y() + r.height(), st::mentionHeight, 0, _hashtagResults.size());
|
||||
p.translate(0, from * st::mentionHeight);
|
||||
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.setPen(st::black->p);
|
||||
|
@ -135,11 +136,11 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
|||
p.setFont(st::mentionFont->f);
|
||||
if (!first.isEmpty()) {
|
||||
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()) {
|
||||
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);
|
||||
|
@ -148,9 +149,9 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
|||
}
|
||||
if (!_filterResults.isEmpty()) {
|
||||
int32 skip = filteredOffset();
|
||||
int32 from = floorclamp(r.y() - skip, st::dlgHeight, 0, _filterResults.size());
|
||||
int32 to = ceilclamp(r.y() + r.height() - skip, st::dlgHeight, 0, _filterResults.size());
|
||||
p.translate(0, from * st::dlgHeight);
|
||||
int32 from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _filterResults.size());
|
||||
int32 to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _filterResults.size());
|
||||
p.translate(0, from * st::dialogsRowHeight);
|
||||
if (from < _filterResults.size()) {
|
||||
int32 w = fullWidth();
|
||||
PeerData *act = App::main()->activePeer();
|
||||
|
@ -159,7 +160,7 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
|||
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);
|
||||
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 ®ion, bool paintingO
|
|||
p.translate(0, st::searchedBarHeight);
|
||||
|
||||
int32 skip = peopleOffset();
|
||||
int32 from = floorclamp(r.y() - skip, st::dlgHeight, 0, _peopleResults.size());
|
||||
int32 to = ceilclamp(r.y() + r.height() - skip, st::dlgHeight, 0, _peopleResults.size());
|
||||
p.translate(0, from * st::dlgHeight);
|
||||
int32 from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _peopleResults.size());
|
||||
int32 to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _peopleResults.size());
|
||||
p.translate(0, from * st::dialogsRowHeight);
|
||||
if (from < _peopleResults.size()) {
|
||||
int32 w = fullWidth();
|
||||
PeerData *act = App::main()->activePeer();
|
||||
|
@ -185,14 +186,14 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
|||
bool active = ((_peopleResults[from] == act) || (_peopleResults[from]->migrateTo() && _peopleResults[from]->migrateTo() == act)) && !actId;
|
||||
bool selected = (from == _peopleSel);
|
||||
peopleResultPaint(_peopleResults[from], p, w, active, selected, paintingOther);
|
||||
p.translate(0, st::dlgHeight);
|
||||
p.translate(0, st::dialogsRowHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_searchInPeer) {
|
||||
searchInPeerPaint(p, fullWidth(), paintingOther);
|
||||
p.translate(0, st::dlgHeight);
|
||||
p.translate(0, st::dialogsRowHeight);
|
||||
if (_state == FilteredState && _searchResults.isEmpty()) {
|
||||
p.fillRect(0, 0, fullWidth(), st::searchedBarHeight, st::searchedBarBG->b);
|
||||
if (!paintingOther) {
|
||||
|
@ -215,9 +216,9 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
|||
p.translate(0, st::searchedBarHeight);
|
||||
|
||||
int32 skip = searchedOffset();
|
||||
int32 from = floorclamp(r.y() - skip, st::dlgHeight, 0, _searchResults.size());
|
||||
int32 to = ceilclamp(r.y() + r.height() - skip, st::dlgHeight, 0, _searchResults.size());
|
||||
p.translate(0, from * st::dlgHeight);
|
||||
int32 from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _searchResults.size());
|
||||
int32 to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _searchResults.size());
|
||||
p.translate(0, from * st::dialogsRowHeight);
|
||||
if (from < _searchResults.size()) {
|
||||
int32 w = fullWidth();
|
||||
PeerData *act = App::main()->activePeer();
|
||||
|
@ -229,7 +230,7 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
|||
bool active = (history->peer == act && item->id == actId) || (history->peer->migrateTo() && history->peer->migrateTo() == act && item->id == -actId);
|
||||
bool selected = (from == _searchedSel);
|
||||
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 ®ion, bool paintingO
|
|||
}
|
||||
|
||||
void DialogsInner::peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool active, bool selected, bool onlyBackground) const {
|
||||
QRect fullRect(0, 0, w, st::dlgHeight);
|
||||
p.fillRect(fullRect, active ? st::dlgActiveBG : (selected ? st::dlgHoverBG : st::dlgBG));
|
||||
QRect fullRect(0, 0, w, st::dialogsRowHeight);
|
||||
p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
|
||||
if (onlyBackground) return;
|
||||
|
||||
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 namewidth = w - nameleft - st::dlgPaddingHor;
|
||||
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height);
|
||||
int32 nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
||||
int32 namewidth = w - nameleft - st::dialogsPadding.x();
|
||||
QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height);
|
||||
|
||||
// draw chat icon
|
||||
if (peer->isChat() || peer->isMegagroup()) {
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dlgChatImgPos.x(), rectForName.top() + st::dlgChatImgPos.y()), (active ? st::dlgActiveChatImg : st::dlgChatImg));
|
||||
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dialogsChatImgPos.x(), rectForName.top() + st::dialogsChatImgPos.y()), (active ? st::dlgActiveChatImg : st::dlgChatImg));
|
||||
rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
|
||||
} else if (peer->isChannel()) {
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dlgChannelImgPos.x(), rectForName.top() + st::dlgChannelImgPos.y()), (active ? st::dlgActiveChannelImg : st::dlgChannelImg));
|
||||
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dialogsChannelImgPos.x(), rectForName.top() + st::dialogsChannelImgPos.y()), (active ? st::dlgActiveChannelImg : st::dlgChannelImg));
|
||||
rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
|
||||
}
|
||||
if (peer->isVerified()) {
|
||||
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));
|
||||
}
|
||||
|
||||
QRect tr(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, namewidth, st::dlgFont->height);
|
||||
p.setFont(st::dlgHistFont->f);
|
||||
QRect tr(nameleft, st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip, namewidth, st::dialogsTextFont->height);
|
||||
p.setFont(st::dialogsTextFont);
|
||||
QString username = peer->userName();
|
||||
if (!active && username.toLower().startsWith(_peopleQuery)) {
|
||||
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()) {
|
||||
p.setPen(st::dlgSystemColor->p);
|
||||
p.drawText(tr.left(), tr.top() + st::dlgHistFont->ascent, st::dlgHistFont->elided(first, tr.width()));
|
||||
p.setPen(st::dialogsTextFgService);
|
||||
p.drawText(tr.left(), tr.top() + st::dialogsTextFont->ascent, st::dialogsTextFont->elided(first, tr.width()));
|
||||
} else {
|
||||
p.setPen(st::dlgSystemColor->p);
|
||||
p.drawText(tr.left(), tr.top() + st::dlgHistFont->ascent, first);
|
||||
p.setPen(st::dlgTextColor->p);
|
||||
p.drawText(tr.left() + w, tr.top() + st::dlgHistFont->ascent, st::dlgHistFont->elided(second, tr.width() - w));
|
||||
p.setPen(st::dialogsTextFgService);
|
||||
p.drawText(tr.left(), tr.top() + st::dialogsTextFont->ascent, first);
|
||||
p.setPen(st::dialogsTextFg);
|
||||
p.drawText(tr.left() + w, tr.top() + st::dialogsTextFont->ascent, st::dialogsTextFont->elided(second, tr.width() - w));
|
||||
}
|
||||
} else {
|
||||
p.setPen((active ? st::dlgActiveColor : st::dlgSystemColor)->p);
|
||||
p.drawText(tr.left(), tr.top() + st::dlgHistFont->ascent, st::dlgHistFont->elided('@' + username, tr.width()));
|
||||
p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFgService);
|
||||
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());
|
||||
}
|
||||
|
||||
void DialogsInner::searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) const {
|
||||
QRect fullRect(0, 0, w, st::dlgHeight);
|
||||
p.fillRect(fullRect, st::dlgBG->b);
|
||||
QRect fullRect(0, 0, w, st::dialogsRowHeight);
|
||||
p.fillRect(fullRect, st::dialogsBg);
|
||||
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 namewidth = w - nameleft - st::dlgPaddingHor * 2 - st::btnCancelSearch.width;
|
||||
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height);
|
||||
int32 nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
||||
int32 namewidth = w - nameleft - st::dialogsPadding.x() * 2 - st::btnCancelSearch.width;
|
||||
QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height);
|
||||
|
||||
// draw chat icon
|
||||
if (_searchInPeer->isChat() || _searchInPeer->isMegagroup()) {
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dlgChatImgPos.x(), rectForName.top() + st::dlgChatImgPos.y()), st::dlgChatImg);
|
||||
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dialogsChatImgPos.x(), rectForName.top() + st::dialogsChatImgPos.y()), st::dlgChatImg);
|
||||
rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
|
||||
} else if (_searchInPeer->isChannel()) {
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dlgChannelImgPos.x(), rectForName.top() + st::dlgChannelImgPos.y()), st::dlgChannelImg);
|
||||
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dialogsChannelImgPos.x(), rectForName.top() + st::dialogsChannelImgPos.y()), st::dlgChannelImg);
|
||||
rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
|
||||
}
|
||||
|
||||
QRect tr(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, namewidth, st::dlgFont->height);
|
||||
p.setFont(st::dlgHistFont->f);
|
||||
p.setPen(st::dlgTextColor->p);
|
||||
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()));
|
||||
QRect tr(nameleft, st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip, namewidth, st::dialogsTextFont->height);
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.setPen(st::dialogsTextFg);
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -332,7 +333,7 @@ void DialogsInner::onUpdateSelected(bool force) {
|
|||
if (_state == DefaultState) {
|
||||
auto newImportantSwitchSel = (importantDialogs && mouseY >= 0 && 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) {
|
||||
updateSelectedRow();
|
||||
_sel = newSel;
|
||||
|
@ -357,7 +358,7 @@ void DialogsInner::onUpdateSelected(bool force) {
|
|||
}
|
||||
}
|
||||
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()) {
|
||||
newFilteredSel = -1;
|
||||
}
|
||||
|
@ -369,7 +370,7 @@ void DialogsInner::onUpdateSelected(bool force) {
|
|||
}
|
||||
}
|
||||
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()) {
|
||||
newPeopleSel = -1;
|
||||
}
|
||||
|
@ -381,7 +382,7 @@ void DialogsInner::onUpdateSelected(bool force) {
|
|||
}
|
||||
}
|
||||
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()) {
|
||||
newSearchedSel = -1;
|
||||
}
|
||||
|
@ -406,7 +407,7 @@ void DialogsInner::mousePressEvent(QMouseEvent *e) {
|
|||
|
||||
void DialogsInner::resizeEvent(QResizeEvent *e) {
|
||||
_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) {
|
||||
|
@ -457,14 +458,14 @@ void DialogsInner::createDialog(History *history) {
|
|||
}
|
||||
}
|
||||
|
||||
int from = dialogsOffset() + changed.movedFrom * st::dlgHeight;
|
||||
int to = dialogsOffset() + changed.movedTo * st::dlgHeight;
|
||||
int from = dialogsOffset() + changed.movedFrom * st::dialogsRowHeight;
|
||||
int to = dialogsOffset() + changed.movedTo * st::dialogsRowHeight;
|
||||
emit dialogMoved(from, to);
|
||||
|
||||
if (creating) {
|
||||
refresh();
|
||||
} 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) {
|
||||
if (_state == DefaultState) {
|
||||
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) {
|
||||
if (list == Dialogs::Mode::All) {
|
||||
for (int32 i = 0, l = _filterResults.size(); i < l; ++i) {
|
||||
if (_filterResults.at(i)->history() == row->history()) {
|
||||
update(0, i * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||
update(0, i * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -515,13 +516,13 @@ void DialogsInner::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
|
|||
void DialogsInner::dlgUpdated(History *history, MsgId msgId) {
|
||||
if (_state == DefaultState) {
|
||||
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) {
|
||||
int32 cnt = 0, add = filteredOffset();
|
||||
for (FilteredDialogs::const_iterator i = _filterResults.cbegin(), e = _filterResults.cend(); i != e; ++i) {
|
||||
if ((*i)->history() == history) {
|
||||
update(0, add + cnt * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||
update(0, add + cnt * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
|
||||
break;
|
||||
}
|
||||
++cnt;
|
||||
|
@ -530,7 +531,7 @@ void DialogsInner::dlgUpdated(History *history, MsgId msgId) {
|
|||
int32 cnt = 0, add = peopleOffset();
|
||||
for (PeopleResults::const_iterator i = _peopleResults.cbegin(), e = _peopleResults.cend(); i != e; ++i) {
|
||||
if ((*i) == history->peer) {
|
||||
update(0, add + cnt * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||
update(0, add + cnt * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
|
||||
break;
|
||||
}
|
||||
++cnt;
|
||||
|
@ -540,7 +541,7 @@ void DialogsInner::dlgUpdated(History *history, MsgId msgId) {
|
|||
int32 cnt = 0, add = searchedOffset();
|
||||
for (SearchResults::const_iterator i = _searchResults.cbegin(), e = _searchResults.cend(); i != e; ++i) {
|
||||
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;
|
||||
}
|
||||
++cnt;
|
||||
|
@ -560,30 +561,30 @@ void DialogsInner::updateSelectedRow(PeerData *peer) {
|
|||
if (peer) {
|
||||
if (History *h = App::historyLoaded(peer->id)) {
|
||||
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) {
|
||||
update(0, dialogsOffset() + _sel->pos() * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||
update(0, dialogsOffset() + _sel->pos() * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
|
||||
} else if (_importantSwitchSel) {
|
||||
update(0, 0, fullWidth(), st::dlgImportantHeight);
|
||||
update(0, 0, fullWidth(), st::dialogsImportantBarHeight);
|
||||
}
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
if (peer) {
|
||||
for (int32 i = 0, l = _filterResults.size(); i != l; ++i) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else if (_hashtagSel >= 0) {
|
||||
update(0, _hashtagSel * st::mentionHeight, fullWidth(), st::mentionHeight);
|
||||
} 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) {
|
||||
update(0, peopleOffset() + _peopleSel * st::dlgHeight, fullWidth(), st::dlgHeight);
|
||||
update(0, peopleOffset() + _peopleSel * st::dialogsRowHeight, fullWidth(), st::dialogsRowHeight);
|
||||
} 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;
|
||||
}
|
||||
|
||||
int from = dialogsOffset() + changed.movedFrom * st::dlgHeight;
|
||||
int to = dialogsOffset() + changed.movedTo * st::dlgHeight;
|
||||
int from = dialogsOffset() + changed.movedFrom * st::dialogsRowHeight;
|
||||
int to = dialogsOffset() + changed.movedTo * st::dialogsRowHeight;
|
||||
emit dialogMoved(from, to);
|
||||
|
||||
if (creating) {
|
||||
refresh();
|
||||
} 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();
|
||||
}
|
||||
} else {
|
||||
h = dialogsOffset() + shownDialogs()->size() * st::dlgHeight;
|
||||
h = dialogsOffset() + shownDialogs()->size() * st::dialogsRowHeight;
|
||||
if (!_addContactLnk.isHidden()) _addContactLnk.hide();
|
||||
}
|
||||
} else {
|
||||
if (!_addContactLnk.isHidden()) _addContactLnk.hide();
|
||||
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) {
|
||||
h = searchedOffset() + (_searchResults.count() * st::dlgHeight);
|
||||
h = searchedOffset() + (_searchResults.count() * st::dialogsRowHeight);
|
||||
}
|
||||
}
|
||||
setHeight(h);
|
||||
|
@ -1295,8 +1296,8 @@ void DialogsInner::selectSkip(int32 direction) {
|
|||
}
|
||||
}
|
||||
if (_importantSwitchSel || _sel) {
|
||||
int fromY = _importantSwitchSel ? 0 : (dialogsOffset() + _sel->pos() * st::dlgHeight);
|
||||
emit mustScrollTo(fromY, fromY + st::dlgHeight);
|
||||
int fromY = _importantSwitchSel ? 0 : (dialogsOffset() + _sel->pos() * st::dialogsRowHeight);
|
||||
emit mustScrollTo(fromY, fromY + st::dialogsRowHeight);
|
||||
}
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
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()) {
|
||||
emit mustScrollTo(_hashtagSel * st::mentionHeight, (_hashtagSel + 1) * st::mentionHeight);
|
||||
} 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()) {
|
||||
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 {
|
||||
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();
|
||||
|
@ -1347,13 +1348,13 @@ void DialogsInner::scrollToPeer(const PeerId &peer, MsgId msgId) {
|
|||
int32 fromY = -1;
|
||||
if (_state == DefaultState) {
|
||||
if (auto row = shownDialogs()->getRow(peer)) {
|
||||
fromY = dialogsOffset() + row->pos() * st::dlgHeight;
|
||||
fromY = dialogsOffset() + row->pos() * st::dialogsRowHeight;
|
||||
}
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
if (msgId) {
|
||||
for (int32 i = 0, c = _searchResults.size(); i < c; ++i) {
|
||||
if (_searchResults[i]->item()->history()->peer->id == peer && _searchResults[i]->item()->id == msgId) {
|
||||
fromY = searchedOffset() + i * st::dlgHeight;
|
||||
fromY = searchedOffset() + i * st::dialogsRowHeight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1361,19 +1362,19 @@ void DialogsInner::scrollToPeer(const PeerId &peer, MsgId msgId) {
|
|||
if (fromY < 0) {
|
||||
for (int32 i = 0, c = _filterResults.size(); i < c; ++i) {
|
||||
if (_filterResults[i]->history()->peer->id == peer) {
|
||||
fromY = filteredOffset() + (i * st::dlgHeight);
|
||||
fromY = filteredOffset() + (i * st::dialogsRowHeight);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fromY >= 0) {
|
||||
emit mustScrollTo(fromY, fromY + st::dlgHeight);
|
||||
emit mustScrollTo(fromY, fromY + st::dialogsRowHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsInner::selectSkipPage(int32 pixels, int32 direction) {
|
||||
int toSkip = pixels / int(st::dlgHeight);
|
||||
int toSkip = pixels / int(st::dialogsRowHeight);
|
||||
if (_state == DefaultState) {
|
||||
if (!_sel) {
|
||||
if (direction > 0 && !shownDialogs()->isEmpty()) {
|
||||
|
@ -1397,8 +1398,8 @@ void DialogsInner::selectSkipPage(int32 pixels, int32 direction) {
|
|||
}
|
||||
}
|
||||
if (_importantSwitchSel || _sel) {
|
||||
int fromY = (_importantSwitchSel ? 0 : (dialogsOffset() + _sel->pos() * st::dlgHeight));
|
||||
emit mustScrollTo(fromY, fromY + st::dlgHeight);
|
||||
int fromY = (_importantSwitchSel ? 0 : (dialogsOffset() + _sel->pos() * st::dialogsRowHeight));
|
||||
emit mustScrollTo(fromY, fromY + st::dialogsRowHeight);
|
||||
}
|
||||
} else {
|
||||
return selectSkip(direction * toSkip);
|
||||
|
@ -1412,10 +1413,10 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
|
|||
int32 yTo = yFrom + parentWidget()->height() * 5;
|
||||
MTP::clearLoaderPriorities();
|
||||
if (_state == DefaultState) {
|
||||
int32 otherStart = shownDialogs()->size() * st::dlgHeight;
|
||||
int32 otherStart = shownDialogs()->size() * st::dialogsRowHeight;
|
||||
if (yFrom < otherStart) {
|
||||
for (auto i = shownDialogs()->cfind(yFrom, st::dlgHeight), end = shownDialogs()->cend(); i != end; ++i) {
|
||||
if (((*i)->pos() * st::dlgHeight) >= yTo) {
|
||||
for (auto i = shownDialogs()->cfind(yFrom, st::dialogsRowHeight), end = shownDialogs()->cend(); i != end; ++i) {
|
||||
if (((*i)->pos() * st::dialogsRowHeight) >= yTo) {
|
||||
break;
|
||||
}
|
||||
(*i)->history()->peer->loadUserpic();
|
||||
|
@ -1426,10 +1427,10 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
|
|||
}
|
||||
yTo -= otherStart;
|
||||
} 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 < _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();
|
||||
|
||||
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 < _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();
|
||||
|
||||
for (; from < to; ++from) {
|
||||
_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 < _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();
|
||||
|
||||
for (; from < to; ++from) {
|
||||
|
@ -1761,7 +1762,7 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : TWidget(parent)
|
|||
, _newGroup(this, st::btnNewGroup)
|
||||
, _addContact(this, st::btnAddContact)
|
||||
, _cancelSearch(this, st::btnCancelSearch)
|
||||
, _scroll(this, st::dlgScroll)
|
||||
, _scroll(this, st::dialogsScroll)
|
||||
, _inner(&_scroll, parent)
|
||||
, _a_show(animation(this, &DialogsWidget::step_show))
|
||||
, _searchInPeer(0)
|
||||
|
@ -1800,15 +1801,15 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : TWidget(parent)
|
|||
|
||||
_scroll.show();
|
||||
_filter.show();
|
||||
_filter.move(st::dlgPaddingHor, st::dlgFilterPadding);
|
||||
_filter.move(st::dialogsPadding.x(), st::dialogsFilterPadding);
|
||||
_filter.setFocusPolicy(Qt::StrongFocus);
|
||||
_filter.customUpDown(true);
|
||||
_addContact.hide();
|
||||
_newGroup.show();
|
||||
_cancelSearch.hide();
|
||||
_newGroup.move(width() - _newGroup.width() - st::dlgPaddingHor, 0);
|
||||
_addContact.move(width() - _addContact.width() - st::dlgPaddingHor, 0);
|
||||
_cancelSearch.move(width() - _cancelSearch.width() - st::dlgPaddingHor, 0);
|
||||
_newGroup.move(width() - _newGroup.width() - st::dialogsPadding.x(), 0);
|
||||
_addContact.move(width() - _addContact.width() - st::dialogsPadding.x(), 0);
|
||||
_cancelSearch.move(width() - _cancelSearch.width() - st::dialogsPadding.x(), 0);
|
||||
}
|
||||
|
||||
void DialogsWidget::activate() {
|
||||
|
@ -2342,10 +2343,10 @@ void DialogsWidget::onListScroll() {
|
|||
|
||||
_inner.loadPeerPhotos(_scroll.scrollTop());
|
||||
if (_inner.state() == DialogsInner::SearchedState || (_inner.state() == DialogsInner::FilteredState && _searchInMigrated && _searchFull && !_searchFullMigrated)) {
|
||||
if (_scroll.scrollTop() > (_inner.searchList().size() + _inner.filteredList().size() + _inner.peopleList().size()) * st::dlgHeight - PreloadHeightsCount * _scroll.height()) {
|
||||
if (_scroll.scrollTop() > (_inner.searchList().size() + _inner.filteredList().size() + _inner.peopleList().size()) * st::dialogsRowHeight - PreloadHeightsCount * _scroll.height()) {
|
||||
onSearchMore();
|
||||
}
|
||||
} else if (_scroll.scrollTop() > _inner.dialogsList()->size() * st::dlgHeight - PreloadHeightsCount * _scroll.height()) {
|
||||
} else if (_scroll.scrollTop() > _inner.dialogsList()->size() * st::dialogsRowHeight - PreloadHeightsCount * _scroll.height()) {
|
||||
loadDialogs();
|
||||
}
|
||||
}
|
||||
|
@ -2425,15 +2426,15 @@ void DialogsWidget::onCompleteHashtag(QString tag) {
|
|||
|
||||
void DialogsWidget::resizeEvent(QResizeEvent *e) {
|
||||
int32 w = width();
|
||||
_filter.setGeometry(st::dlgPaddingHor, st::dlgFilterPadding, w - 2 * st::dlgPaddingHor, _filter.height());
|
||||
_newGroup.move(w - _newGroup.width() - st::dlgPaddingHor, _filter.y());
|
||||
_addContact.move(w - _addContact.width() - st::dlgPaddingHor, _filter.y());
|
||||
_cancelSearch.move(w - _cancelSearch.width() - st::dlgPaddingHor, _filter.y());
|
||||
_scroll.move(0, _filter.height() + 2 * st::dlgFilterPadding);
|
||||
_filter.setGeometry(st::dialogsPadding.x(), st::dialogsFilterPadding, w - 2 * st::dialogsPadding.x(), _filter.height());
|
||||
_newGroup.move(w - _newGroup.width() - st::dialogsPadding.x(), _filter.y());
|
||||
_addContact.move(w - _addContact.width() - st::dialogsPadding.x(), _filter.y());
|
||||
_cancelSearch.move(w - _cancelSearch.width() - st::dialogsPadding.x(), _filter.y());
|
||||
_scroll.move(0, _filter.height() + 2 * st::dialogsFilterPadding);
|
||||
|
||||
int32 addToY = App::main() ? App::main()->contentScrollAddToY() : 0;
|
||||
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) {
|
||||
_scroll.scrollToY(newScrollY);
|
||||
} else {
|
||||
|
@ -2583,6 +2584,6 @@ void DialogsWidget::onCancelSearchInPeer() {
|
|||
void DialogsWidget::onDialogMoved(int movedFrom, int movedTo) {
|
||||
int32 st = _scroll.scrollTop();
|
||||
if (st > movedTo && st < movedFrom) {
|
||||
_scroll.scrollToY(st + st::dlgHeight);
|
||||
_scroll.scrollToY(st + st::dialogsRowHeight);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,6 +95,8 @@ void activateBotCommand(const HistoryItem *msg, int row, int col) {
|
|||
auto getMessageBot = [msg]() -> UserData* {
|
||||
if (auto bot = msg->viaBot()) {
|
||||
return bot;
|
||||
} else if (auto bot = msg->from()->asUser()) {
|
||||
return bot;
|
||||
} else if (auto bot = msg->history()->peer->asUser()) {
|
||||
return bot;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "core/click_handler_types.h"
|
||||
#include "dialogs/dialogs_indexed_list.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "lang.h"
|
||||
#include "mainwidget.h"
|
||||
#include "application.h"
|
||||
|
@ -73,7 +74,7 @@ TextParseOptions _instagramDescriptionOptions = {
|
|||
|
||||
inline void _initTextOptions() {
|
||||
_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.maxh = st::webPageTitleFont->height * 2;
|
||||
_webpageDescriptionOptions.maxw = st::msgMaxWidth - st::msgPadding.left() - st::msgPadding.right() - st::webPageLeft;
|
||||
|
@ -129,6 +130,9 @@ void historyInit() {
|
|||
|
||||
History::History(const PeerId &peerId)
|
||||
: peer(App::peer(peerId))
|
||||
, lastItemTextCache(st::dialogsTextWidthMin)
|
||||
, typingText(st::dialogsTextWidthMin)
|
||||
, cloudDraftTextCache(st::dialogsTextWidthMin)
|
||||
, _mute(isNotifyMuted(peer->notify)) {
|
||||
if (peer->isUser() && peer->asUser()->botInfo) {
|
||||
outboxReadBefore = INT_MAX;
|
||||
|
@ -259,7 +263,7 @@ bool History::updateTyping(uint64 ms, bool force) {
|
|||
newTypingStr += qsl("...");
|
||||
}
|
||||
if (typingStr != newTypingStr) {
|
||||
typingText.setText(st::dlgHistFont, (typingStr = newTypingStr), _textNameOptions);
|
||||
typingText.setText(st::dialogsTextFont, (typingStr = newTypingStr), _textNameOptions);
|
||||
}
|
||||
}
|
||||
if (!typingStr.isEmpty()) {
|
||||
|
@ -7494,13 +7498,6 @@ HistoryTextState HistoryMessage::getState(int x, int y, HistoryStateRequest requ
|
|||
}
|
||||
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) {
|
||||
int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
||||
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);
|
||||
}
|
||||
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();
|
||||
if (!mediaDisplayed || !_media->customInfoLayout()) {
|
||||
|
@ -7568,16 +7572,16 @@ void HistoryMessage::drawInDialog(Painter &p, const QRect &r, bool act, const Hi
|
|||
TextCustomTagsMap custom;
|
||||
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));
|
||||
cache.setRichText(st::dlgHistFont, msg, _textDlgOptions, custom);
|
||||
cache.setRichText(st::dialogsTextFont, msg, _textDlgOptions, custom);
|
||||
} else {
|
||||
cache.setText(st::dlgHistFont, msg, _textDlgOptions);
|
||||
cache.setText(st::dialogsTextFont, msg, _textDlgOptions);
|
||||
}
|
||||
}
|
||||
if (r.width()) {
|
||||
textstyleSet(&(act ? st::dlgActiveTextStyle : st::dlgTextStyle));
|
||||
p.setFont(st::dlgHistFont->f);
|
||||
p.setPen((act ? st::dlgActiveColor : (emptyText() ? st::dlgSystemColor : st::dlgTextColor))->p);
|
||||
cache.drawElided(p, r.left(), r.top(), r.width(), r.height() / st::dlgHistFont->height);
|
||||
textstyleSet(&(act ? st::dialogsTextStyleActive : st::dialogsTextStyle));
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.setPen(act ? st::dialogsTextFgActive : (emptyText() ? st::dialogsTextFgService : st::dialogsTextFg));
|
||||
cache.drawElided(p, r.left(), r.top(), r.width(), r.height() / st::dialogsTextFont->height);
|
||||
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 {
|
||||
if (cacheFor != this) {
|
||||
cacheFor = this;
|
||||
cache.setText(st::dlgHistFont, inDialogsText(), _textDlgOptions);
|
||||
cache.setText(st::dialogsTextFont, inDialogsText(), _textDlgOptions);
|
||||
}
|
||||
QRect tr(r);
|
||||
p.setPen((act ? st::dlgActiveColor : st::dlgSystemColor)->p);
|
||||
cache.drawElided(p, tr.left(), tr.top(), tr.width(), tr.height() / st::dlgHistFont->height);
|
||||
p.setPen(act ? st::dialogsTextFgActive : st::dialogsTextFgService);
|
||||
cache.drawElided(p, tr.left(), tr.top(), tr.width(), tr.height() / st::dialogsTextFont->height);
|
||||
}
|
||||
|
||||
QString HistoryService::notificationText() const {
|
||||
|
|
|
@ -458,14 +458,14 @@ public:
|
|||
mtpRequestId sendRequestId = 0;
|
||||
|
||||
mutable const HistoryItem *textCachedFor = nullptr; // cache
|
||||
mutable Text lastItemTextCache = Text{ int(st::dlgRichMinWidth) };
|
||||
mutable Text lastItemTextCache;
|
||||
|
||||
typedef QMap<UserData*, uint64> TypingUsers;
|
||||
TypingUsers typing;
|
||||
typedef QMap<UserData*, SendAction> SendActionUsers;
|
||||
SendActionUsers sendActions;
|
||||
QString typingStr;
|
||||
Text typingText = Text{ int(st::dlgRichMinWidth) };
|
||||
Text typingText;
|
||||
uint32 typingDots;
|
||||
QMap<SendActionType, uint64> mySendActions;
|
||||
|
||||
|
@ -504,7 +504,7 @@ public:
|
|||
|
||||
void changeMsgId(MsgId oldId, MsgId newId);
|
||||
|
||||
Text cloudDraftTextCache = Text { int(st::dlgRichMinWidth) };
|
||||
Text cloudDraftTextCache;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "historywidget.h"
|
||||
|
||||
#include "styles/style_history.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "boxes/photosendbox.h"
|
||||
#include "ui/filedialog.h"
|
||||
|
@ -1552,6 +1553,15 @@ HistoryInner::~HistoryInner() {
|
|||
_dragAction = NoDrag;
|
||||
}
|
||||
|
||||
bool HistoryInner::focusNextPrevChild(bool next) {
|
||||
if (_selected.isEmpty()) {
|
||||
return focusNextPrevChild(next);
|
||||
} else {
|
||||
clearSelectedItems();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryInner::adjustCurrent(int32 y) const {
|
||||
int32 htop = historyTop(), hdrawtop = historyDrawTop(), mtop = migratedTop();
|
||||
_curHistory = 0;
|
||||
|
@ -3036,13 +3046,15 @@ void HistoryWidget::applyInlineBotQuery(UserData *bot, const QString &query) {
|
|||
}
|
||||
|
||||
void HistoryWidget::updateStickersByEmoji() {
|
||||
int32 len = 0;
|
||||
auto &text = _field.getTextWithTags().text;
|
||||
if (EmojiPtr emoji = emojiFromText(text, &len)) {
|
||||
if (text.size() > len) {
|
||||
len = 0;
|
||||
} else {
|
||||
_fieldAutocomplete->showStickers(emoji);
|
||||
int len = 0;
|
||||
if (!_editMsgId) {
|
||||
auto &text = _field.getTextWithTags().text;
|
||||
if (auto emoji = emojiFromText(text, &len)) {
|
||||
if (text.size() > len) {
|
||||
len = 0;
|
||||
} else {
|
||||
_fieldAutocomplete->showStickers(emoji);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!len) {
|
||||
|
@ -3187,7 +3199,7 @@ void HistoryWidget::writeDrafts(HistoryDraft **localDraft, HistoryDraft **editDr
|
|||
}
|
||||
|
||||
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")) {
|
||||
Ui::showLayer(new InformBox(lang((_peer && _peer->isMegagroup()) ? lng_group_not_accessible : lng_channel_not_accessible)));
|
||||
return true;
|
||||
} else if (error.type() == qstr("CHANNELS_TOO_MUCH")) {
|
||||
Ui::showLayer(new InformBox(lang(lng_join_channel_error)));
|
||||
}
|
||||
|
||||
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;
|
||||
decreaseWidth += increaseLeft;
|
||||
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()) {
|
||||
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 {
|
||||
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());
|
||||
|
||||
if (Adaptive::OneColumn()) {
|
||||
|
@ -5882,7 +5897,7 @@ void HistoryWidget::updateOnlineDisplay(int32 x, int32 w) {
|
|||
}
|
||||
if (_titlePeerText != text) {
|
||||
_titlePeerText = text;
|
||||
_titlePeerTextWidth = st::dlgHistFont->width(_titlePeerText);
|
||||
_titlePeerTextWidth = st::dialogsTextFont->width(_titlePeerText);
|
||||
if (App::main()) {
|
||||
App::main()->topBar()->update();
|
||||
}
|
||||
|
|
|
@ -115,6 +115,9 @@ public:
|
|||
|
||||
~HistoryInner();
|
||||
|
||||
protected:
|
||||
bool focusNextPrevChild(bool next) override;
|
||||
|
||||
public slots:
|
||||
|
||||
void onUpdateSelected();
|
||||
|
|
|
@ -21,7 +21,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "stdafx.h"
|
||||
#include "mainwidget.h"
|
||||
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "ui/buttons/peer_avatar_button.h"
|
||||
#include "ui/buttons/round_button.h"
|
||||
#include "window/section_memento.h"
|
||||
#include "window/section_widget.h"
|
||||
#include "window/top_bar_widget.h"
|
||||
|
@ -56,6 +58,7 @@ StackItemSection::~StackItemSection() {
|
|||
|
||||
MainWidget::MainWidget(MainWindow *window) : TWidget(window)
|
||||
, _a_show(animation(this, &MainWidget::step_show))
|
||||
, _dialogsWidth(st::dialogsWidthMin)
|
||||
, _sideShadow(this, st::shadowColor)
|
||||
, _dialogs(this)
|
||||
, _history(this)
|
||||
|
@ -2526,8 +2529,8 @@ void MainWidget::showAll() {
|
|||
cSetPasswordRecovered(false);
|
||||
Ui::showLayer(new InformBox(lang(lng_signin_password_removed)));
|
||||
}
|
||||
_sideShadow.show();
|
||||
if (Adaptive::OneColumn()) {
|
||||
_sideShadow.hide();
|
||||
if (_hider) {
|
||||
_hider->hide();
|
||||
if (!_forwardConfirm && _hider->wasOffered()) {
|
||||
|
@ -2562,6 +2565,7 @@ void MainWidget::showAll() {
|
|||
_dialogs->hide();
|
||||
}
|
||||
} else {
|
||||
_sideShadow.show();
|
||||
if (_hider) {
|
||||
_hider->show();
|
||||
if (_forwardConfirm) {
|
||||
|
@ -2593,6 +2597,14 @@ void MainWidget::showAll() {
|
|||
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) {
|
||||
int32 tbh = _topBar->isHidden() ? 0 : st::topBarHeight;
|
||||
if (Adaptive::OneColumn()) {
|
||||
|
@ -3451,9 +3463,12 @@ void MainWidget::inviteImportDone(const MTPUpdates &updates) {
|
|||
bool MainWidget::inviteImportFail(const RPCError &error) {
|
||||
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)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3761,24 +3776,7 @@ void MainWidget::saveDraftToCloud() {
|
|||
auto localDraft = history->localDraft();
|
||||
auto cloudDraft = history->cloudDraft();
|
||||
if (!historyDraftsAreEqual(localDraft, cloudDraft)) {
|
||||
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), peer->input, MTP_string(textWithTags.text), entities), rpcDone(&MainWidget::saveCloudDraftDone, peer), rpcFail(&MainWidget::saveCloudDraftFail, peer));
|
||||
App::api()->saveDraftToCloudDelayed(history);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3787,30 +3785,6 @@ void MainWidget::applyCloudDraft(History *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() {
|
||||
if (this != App::main()) return;
|
||||
if (psIdleTime() < uint64(Global::OfflineIdleTimeout())) {
|
||||
|
|
|
@ -129,10 +129,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
inline int chatsListWidth(int windowWidth) {
|
||||
return snap<int>((windowWidth * 5) / 14, st::dlgMinWidth, st::dlgMaxWidth);
|
||||
}
|
||||
|
||||
enum SilentNotifiesStatus {
|
||||
SilentNotifiesDontChange,
|
||||
SilentNotifiesSetSilent,
|
||||
|
@ -503,9 +499,6 @@ private:
|
|||
void messagesAffected(PeerData *peer, const MTPmessages_AffectedMessages &result);
|
||||
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);
|
||||
void showWideSectionAnimated(const Window::SectionMemento *memento, bool back);
|
||||
|
||||
|
@ -582,7 +575,7 @@ private:
|
|||
anim::ivalue a_coordUnder, a_coordOver;
|
||||
anim::fvalue a_shadow;
|
||||
|
||||
int _dialogsWidth = st::dlgMinWidth;
|
||||
int _dialogsWidth;
|
||||
|
||||
PlainShadow _sideShadow;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "stdafx.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "zip.h"
|
||||
#include "lang.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);
|
||||
if (!App::passcoded() && cNotifyView() <= dbinvShowName) {
|
||||
if (history->peer->isChat() || history->peer->isMegagroup()) {
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dlgChatImgPos.x(), rectForName.top() + st::dlgChatImgPos.y()), st::dlgChatImg);
|
||||
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dialogsChatImgPos.x(), rectForName.top() + st::dialogsChatImgPos.y()), st::dlgChatImg);
|
||||
rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
|
||||
} else if (history->peer->isChannel()) {
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dlgChannelImgPos.x(), rectForName.top() + st::dlgChannelImgPos.y()), st::dlgChannelImg);
|
||||
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
||||
p.drawSprite(QPoint(rectForName.left() + st::dialogsChannelImgPos.x(), rectForName.top() + st::dialogsChannelImgPos.y()), st::dlgChannelImg);
|
||||
rectForName.setLeft(rectForName.left() + st::dialogsImgSkip);
|
||||
}
|
||||
}
|
||||
|
||||
QDateTime now(QDateTime::currentDateTime()), lastTime(item->date);
|
||||
QDate nowDate(now.date()), lastDate(lastTime.date());
|
||||
QString dt = lastTime.toString(cTimeFormat());
|
||||
int32 dtWidth = st::dlgHistFont->width(dt);
|
||||
rectForName.setWidth(rectForName.width() - dtWidth - st::dlgDateSkip);
|
||||
p.setFont(st::dlgDateFont->f);
|
||||
p.setPen(st::dlgDateColor->p);
|
||||
p.drawText(rectForName.left() + rectForName.width() + st::dlgDateSkip, rectForName.top() + st::dlgHistFont->ascent, dt);
|
||||
int32 dtWidth = st::dialogsTextFont->width(dt);
|
||||
rectForName.setWidth(rectForName.width() - dtWidth - st::dialogsDateSkip);
|
||||
p.setFont(st::dialogsDateFont);
|
||||
p.setPen(st::dialogsDateFg);
|
||||
p.drawText(rectForName.left() + rectForName.width() + st::dialogsDateSkip, rectForName.top() + st::dialogsTextFont->ascent, dt);
|
||||
|
||||
if (!App::passcoded() && cNotifyView() <= dbinvShowPreview) {
|
||||
const HistoryItem *textCachedFor = 0;
|
||||
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) {
|
||||
bool active = false;
|
||||
item->drawInDialog(p, r, active, textCachedFor, itemTextCache);
|
||||
} else {
|
||||
p.setFont(st::dlgHistFont->f);
|
||||
p.setFont(st::dialogsTextFont);
|
||||
if (item->hasFromName() && !item->isPost()) {
|
||||
itemTextCache.setText(st::dlgHistFont, item->author()->name);
|
||||
p.setPen(st::dlgSystemColor->p);
|
||||
itemTextCache.drawElided(p, r.left(), r.top(), r.width(), st::dlgHistFont->height);
|
||||
r.setTop(r.top() + st::dlgHistFont->height);
|
||||
itemTextCache.setText(st::dialogsTextFont, item->author()->name);
|
||||
p.setPen(st::dialogsTextFgService);
|
||||
itemTextCache.drawElided(p, r.left(), r.top(), r.width(), st::dialogsTextFont->height);
|
||||
r.setTop(r.top() + st::dialogsTextFont->height);
|
||||
}
|
||||
p.setPen(st::dlgTextColor->p);
|
||||
p.drawText(r.left(), r.top() + st::dlgHistFont->ascent, lng_forward_messages(lt_count, fwdCount));
|
||||
p.setPen(st::dialogsTextFg);
|
||||
p.drawText(r.left(), r.top() + st::dialogsTextFont->ascent, lng_forward_messages(lt_count, fwdCount));
|
||||
}
|
||||
} else {
|
||||
static QString notifyText = st::dlgHistFont->elided(lang(lng_notification_preview), itemWidth);
|
||||
p.setPen(st::dlgSystemColor->p);
|
||||
p.drawText(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height + st::dlgHistFont->ascent, notifyText);
|
||||
static QString notifyText = st::dialogsTextFont->elided(lang(lng_notification_preview), itemWidth);
|
||||
p.setPen(st::dialogsTextFgService);
|
||||
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) {
|
||||
history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
||||
} else {
|
||||
|
@ -1282,9 +1283,8 @@ void MainWindow::toggleDisplayNotifyFromTray() {
|
|||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *e) {
|
||||
if (MTP::authedId() && !Sandbox::isSavingSession() && Ui::hideWindowNoQuit()) {
|
||||
e->ignore();
|
||||
} else {
|
||||
e->ignore();
|
||||
if (!MTP::authedId() || Sandbox::isSavingSession() || !Ui::hideWindowNoQuit()) {
|
||||
App::quit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,8 @@ linksBorder: 1px;
|
|||
linksBorderFg: #eaeaea;
|
||||
linksDateColor: #808080;
|
||||
linksDateMargin: margins(0px, 15px, 0px, 2px);
|
||||
linksPhotoSize: 46px;
|
||||
linksPhotoPadding: 12px;
|
||||
overviewLinksCheck: icon {
|
||||
{ "overview_links_check_bg", overviewCheckBg },
|
||||
{ "overview_links_check", #fff, point(4px, 5px) },
|
||||
|
|
|
@ -770,7 +770,7 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
|
|||
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));
|
||||
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());
|
||||
th = convertScale(_page->document->thumb->height());
|
||||
}
|
||||
if (tw > st::dlgPhotoSize) {
|
||||
if (tw > st::linksPhotoSize) {
|
||||
if (th > tw) {
|
||||
th = th * st::dlgPhotoSize / tw;
|
||||
tw = st::dlgPhotoSize;
|
||||
} else if (th > st::dlgPhotoSize) {
|
||||
tw = tw * st::dlgPhotoSize / th;
|
||||
th = st::dlgPhotoSize;
|
||||
th = th * st::linksPhotoSize / tw;
|
||||
tw = st::linksPhotoSize;
|
||||
} else if (th > st::linksPhotoSize) {
|
||||
tw = tw * st::linksPhotoSize / th;
|
||||
th = st::linksPhotoSize;
|
||||
}
|
||||
}
|
||||
_pixw = qMax(tw, 1);
|
||||
|
@ -1020,15 +1020,15 @@ void Link::initDimensions() {
|
|||
_minh += st::semiboldFont->height;
|
||||
}
|
||||
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 = 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) {
|
||||
_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) {
|
||||
_links.at(i).lnk->setFullDisplayed(w >= _links.at(i).width);
|
||||
}
|
||||
|
@ -1038,54 +1038,54 @@ int32 Link::resizeGetHeight(int32 width) {
|
|||
_height += st::semiboldFont->height;
|
||||
}
|
||||
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 = 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;
|
||||
}
|
||||
|
||||
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;
|
||||
if (clip.intersects(rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width))) {
|
||||
int32 left = st::linksPhotoSize + st::linksPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left;
|
||||
if (clip.intersects(rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width))) {
|
||||
if (_page && _page->photo) {
|
||||
QPixmap pix;
|
||||
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()) {
|
||||
pix = _page->photo->full->pixSingle(_pixw, _pixh, st::dlgPhotoSize, st::dlgPhotoSize);
|
||||
pix = _page->photo->full->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize);
|
||||
} 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);
|
||||
} 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 {
|
||||
int32 index = _letter.isEmpty() ? 0 : (_letter.at(0).unicode() % 4);
|
||||
switch (index) {
|
||||
case 0: App::roundRect(p, rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width), st::msgFileRedColor, DocRedCorners); break;
|
||||
case 1: App::roundRect(p, rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width), st::msgFileYellowColor, DocYellowCorners); break;
|
||||
case 2: App::roundRect(p, rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width), st::msgFileGreenColor, DocGreenCorners); break;
|
||||
case 3: App::roundRect(p, rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width), st::msgFileBlueColor, DocBlueCorners); 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::linksPhotoSize, st::linksPhotoSize, _width), st::msgFileYellowColor, DocYellowCorners); 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::linksPhotoSize, st::linksPhotoSize, _width), st::msgFileBlueColor, DocBlueCorners); break;
|
||||
}
|
||||
|
||||
if (!_letter.isEmpty()) {
|
||||
p.setFont(st::linksLetterFont->f);
|
||||
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) {
|
||||
App::roundRect(p, rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width), st::overviewPhotoSelectOverlay, PhotoSelectOverlayCorners);
|
||||
st::overviewLinksChecked.paint(p, QPoint(st::dlgPhotoSize - st::overviewLinksChecked.width(), top + st::dlgPhotoSize - st::overviewLinksChecked.height()), _width);
|
||||
App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::overviewPhotoSelectOverlay, PhotoSelectOverlayCorners);
|
||||
st::overviewLinksChecked.paint(p, QPoint(st::linksPhotoSize - st::overviewLinksChecked.width(), top + st::linksPhotoSize - st::overviewLinksChecked.height()), _width);
|
||||
} 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) {
|
||||
top += (st::dlgPhotoSize - st::semiboldFont->height - st::normalFont->height) / 2;
|
||||
top += (st::linksPhotoSize - st::semiboldFont->height - st::normalFont->height) / 2;
|
||||
} else {
|
||||
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 {
|
||||
int32 left = st::dlgPhotoSize + st::dlgPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left;
|
||||
if (rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width).contains(x, y)) {
|
||||
int32 left = st::linksPhotoSize + st::linksPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left;
|
||||
if (rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width).contains(x, y)) {
|
||||
link = _photol;
|
||||
return;
|
||||
}
|
||||
|
||||
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 (rtlrect(left, top, qMin(w, _titlew), st::semiboldFont->height, _width).contains(x, y)) {
|
||||
|
|
|
@ -24,29 +24,30 @@ using "basic_types.style";
|
|||
profileBg: windowBg;
|
||||
|
||||
profileTopBarHeight: topBarHeight;
|
||||
profileTopBarBackIconFg: #51b3e0;
|
||||
profileTopBarBackIconFg: #0290d7;
|
||||
profileTopBarBackIcon: icon {
|
||||
{ "topbar_back_arrow", profileTopBarBackIconFg },
|
||||
};
|
||||
profileTopBarBackIconPosition: point(15px, 19px);
|
||||
profileTopBarBackIconPosition: point(15px, 20px);
|
||||
profileTopBarBackFont: font(14px);
|
||||
profileTopBarBackFg: #1485c2;
|
||||
profileTopBarBackPosition: point(32px, 17px);
|
||||
profileFixedBarButton: flatButton(topBarButton) {
|
||||
profileFixedBarButton: BoxButton(topBarButton) {
|
||||
}
|
||||
|
||||
profileMarginTop: 13px;
|
||||
profilePhotoSize: 112px;
|
||||
profilePhotoLeftMin: 18px;
|
||||
profilePhotoLeftMax: 45px;
|
||||
profilePhotoLeftMax: 35px;
|
||||
profilePhotoDuration: 500;
|
||||
profileNameLeft: 26px;
|
||||
profileNameTop: 9px;
|
||||
profileNameLabel: flatLabel(labelDefFlat) {
|
||||
margin: margins(10px, 5px, 10px, 5px);
|
||||
font: font(16px);
|
||||
font: font(16px semibold);
|
||||
width: 160px;
|
||||
maxHeight: 24px;
|
||||
textFg: #333333;
|
||||
}
|
||||
profileNameTextStyle: textStyle(defaultTextStyle) {
|
||||
}
|
||||
|
@ -57,18 +58,18 @@ profileStatusFg: windowSubTextFg;
|
|||
profileStatusFgActive: windowActiveTextFg;
|
||||
profileMarginBottom: 30px;
|
||||
|
||||
profileActiveBg: #3fb0e4;
|
||||
profileButtonLeft: 27px;
|
||||
profileButtonTop: 88px;
|
||||
profileButtonSkip: 10px;
|
||||
profilePrimaryButton: BoxButton {
|
||||
textFg: #ffffff;
|
||||
textFgOver: #ffffff;
|
||||
textBg: profileActiveBg;
|
||||
textBgOver: profileActiveBg;
|
||||
textBg: windowActiveBg;
|
||||
textBgOver: windowActiveBg;
|
||||
|
||||
width: -34px;
|
||||
height: 34px;
|
||||
padding: margins(0px, 0px, 0px, 0px);
|
||||
|
||||
textTop: 8px;
|
||||
|
||||
|
@ -76,13 +77,13 @@ profilePrimaryButton: BoxButton {
|
|||
duration: 200;
|
||||
}
|
||||
profileSecondaryButton: BoxButton(profilePrimaryButton) {
|
||||
textFg: #189dda;
|
||||
textFgOver: #189dda;
|
||||
textFg: #2b99d5;
|
||||
textFgOver: #2b99d5;
|
||||
textBg: #ffffff;
|
||||
textBgOver: #f2f7fa;
|
||||
}
|
||||
profileAddMemberIcon: icon {
|
||||
{ "profile_add_member", profileActiveBg, point(20px, 10px) },
|
||||
{ "profile_add_member", windowActiveBg, point(20px, 10px) },
|
||||
};
|
||||
profileAddMemberButton: BoxButton(profileSecondaryButton) {
|
||||
width: 62px;
|
||||
|
@ -90,7 +91,7 @@ profileAddMemberButton: BoxButton(profileSecondaryButton) {
|
|||
}
|
||||
|
||||
profileDropAreaBg: profileBg;
|
||||
profileDropAreaFg: profileActiveBg;
|
||||
profileDropAreaFg: windowActiveBg;
|
||||
profileDropAreaPadding: margins(25px, 3px, 25px, 20px);
|
||||
profileDropAreaTitleFont: font(24px);
|
||||
profileDropAreaTitleTop: 30px;
|
||||
|
@ -120,7 +121,7 @@ profileBlockMarginRight: 10px;
|
|||
profileBlockMarginBottom: 4px;
|
||||
profileBlockTitleHeight: 25px;
|
||||
profileBlockTitleFont: font(14px semibold);
|
||||
profileBlockTitleFg: black;
|
||||
profileBlockTitleFg: #333333;
|
||||
profileBlockTitlePosition: point(24px, 0px);
|
||||
profileBlockLabel: flatLabel(labelDefFlat) {
|
||||
textFg: windowSubTextFg;
|
||||
|
@ -153,7 +154,7 @@ profileMemberStatusFg: windowSubTextFg;
|
|||
profileMemberStatusFgOver: windowSubTextFg;
|
||||
profileMemberStatusFgActive: windowActiveTextFg;
|
||||
profileMemberAdminIcon: icon {
|
||||
{ "profile_admin_star", profileActiveBg, point(4px, 2px) },
|
||||
{ "profile_admin_star", #3babe7, point(4px, 2px) },
|
||||
};
|
||||
profileLimitReachedLabel: flatLabel(labelDefFlat) {
|
||||
width: 180px;
|
||||
|
@ -167,3 +168,9 @@ profileReportReasonOther: InputArea(defaultInputArea) {
|
|||
textMargins: margins(1px, 6px, 1px, 4px);
|
||||
heightMax: 115px;
|
||||
}
|
||||
|
||||
profileVerifiedCheckPosition: point(-3px, 7px);
|
||||
profileVerifiedCheck: icon {
|
||||
{ "profile_verified_star", #4abcf1 },
|
||||
{ "profile_verified_check", #ffffff, point(4px, 4px) }
|
||||
};
|
||||
|
|
|
@ -129,9 +129,12 @@ void CoverWidget::refreshNameGeometry(int newWidth) {
|
|||
int infoLeft = _userpicButton->x() + _userpicButton->width();
|
||||
int nameLeft = infoLeft + st::profileNameLeft - st::profileNameLabel.margin.left();
|
||||
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();
|
||||
_name.resizeToWidth(qMin(nameWidth, _name.naturalWidth()) + marginsAdd);
|
||||
_name.resizeToWidth(qMin(nameWidth - marginsAdd, _name.naturalWidth()) + marginsAdd);
|
||||
_name.moveToLeft(nameLeft, nameTop);
|
||||
}
|
||||
|
||||
|
@ -183,6 +186,10 @@ void CoverWidget::paintEvent(QPaintEvent *e) {
|
|||
p.setPen(_statusTextIsOnline ? st::profileStatusFgActive : st::profileStatusFg);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -407,6 +414,7 @@ void CoverWidget::clearButtons() {
|
|||
void CoverWidget::addButton(const QString &text, const char *slot, const style::BoxButton *replacementStyle) {
|
||||
auto &buttonStyle = _buttons.isEmpty() ? st::profilePrimaryButton : st::profileSecondaryButton;
|
||||
auto button = new Ui::RoundButton(this, text, buttonStyle);
|
||||
button->setTextTransform(Ui::RoundButton::TextTransform::ToUpper);
|
||||
connect(button, SIGNAL(clicked()), this, slot);
|
||||
button->show();
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "profile/profile_fixed_bar.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "ui/buttons/round_button.h"
|
||||
#include "lang.h"
|
||||
#include "mainwidget.h"
|
||||
#include "boxes/addcontactbox.h"
|
||||
|
@ -165,7 +166,7 @@ void FixedBar::addRightAction(RightActionType type, const QString &text, const c
|
|||
}
|
||||
_rightActions[_currentAction].type = type;
|
||||
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);
|
||||
bool showButton = !_animatingMode && (type != RightActionType::ShareContact || !_hideShareContactButton);
|
||||
_rightActions[_currentAction].button->setVisible(showButton);
|
||||
|
|
|
@ -26,6 +26,10 @@ namespace Notify {
|
|||
struct PeerUpdate;
|
||||
} // namespace Notify
|
||||
|
||||
namespace Ui {
|
||||
class RoundButton;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Profile {
|
||||
|
||||
class BackButton;
|
||||
|
@ -96,7 +100,7 @@ private:
|
|||
int _currentAction = 0;
|
||||
struct RightAction {
|
||||
RightActionType type = RightActionType::None;
|
||||
FlatButton *button = nullptr;
|
||||
Ui::RoundButton *button = nullptr;
|
||||
};
|
||||
QList<RightAction> _rightActions;
|
||||
|
||||
|
|
|
@ -426,6 +426,9 @@ void MembersWidget::fillChatMembers(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())) {
|
||||
member->canBeKicked = false;
|
||||
} else if (chat->amCreator() || (chat->amAdmin() && !member->isAdmin)) {
|
||||
|
@ -433,7 +436,6 @@ void MembersWidget::setMemberFlags(Member *member, ChatData *chat) {
|
|||
} else {
|
||||
member->canBeKicked = chat->invitedByMe.contains(member->user);
|
||||
}
|
||||
member->isAdmin = chat->admins.contains(member->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) {
|
||||
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()) {
|
||||
member->canBeKicked = false;
|
||||
} else if (megagroup->amCreator() || (megagroup->amEditor() && !member->isAdmin)) {
|
||||
|
@ -497,7 +502,6 @@ void MembersWidget::setMemberFlags(Member *member, ChannelData *megagroup) {
|
|||
} else {
|
||||
member->canBeKicked = false;
|
||||
}
|
||||
member->isAdmin = megagroup->mgInfo->lastAdmins.contains(member->user);
|
||||
}
|
||||
|
||||
MembersWidget::Member *MembersWidget::getMember(UserData *user) {
|
||||
|
@ -640,7 +644,7 @@ void ChannelMembersWidget::addButton(const QString &text, ChildWidget<Ui::LeftOu
|
|||
} else if (*button) {
|
||||
(*button)->setText(text);
|
||||
} else {
|
||||
(*button) = new Ui::LeftOutlineButton(this, text);
|
||||
(*button) = new Ui::LeftOutlineButton(this, text, st::defaultLeftOutlineButton);
|
||||
(*button)->show();
|
||||
connect(*button, SIGNAL(clicked()), this, slot);
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ void SettingsWidget::refreshManageAdminsButton() {
|
|||
};
|
||||
_manageAdmins.destroy();
|
||||
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();
|
||||
connect(_manageAdmins, SIGNAL(clicked()), this, SLOT(onManageAdmins()));
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ void SettingsWidget::refreshInviteLinkButton() {
|
|||
};
|
||||
auto inviteLinkText = getInviteLinkText();
|
||||
if (!inviteLinkText.isEmpty()) {
|
||||
_inviteLink = new Ui::LeftOutlineButton(this, inviteLinkText);
|
||||
_inviteLink = new Ui::LeftOutlineButton(this, inviteLinkText, st::defaultLeftOutlineButton);
|
||||
_inviteLink->show();
|
||||
connect(_inviteLink, SIGNAL(clicked()), this, SLOT(onInviteLink()));
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ void SharedMediaWidget::refreshButton(MediaOverviewType type) {
|
|||
if (_mediaButtons[type]) {
|
||||
_mediaButtons[type]->setText(text);
|
||||
} else {
|
||||
_mediaButtons[type] = new Ui::LeftOutlineButton(this, text);
|
||||
_mediaButtons[type] = new Ui::LeftOutlineButton(this, text, st::defaultLeftOutlineButton);
|
||||
_mediaButtons[type]->show();
|
||||
connect(_mediaButtons[type], SIGNAL(clicked()), this, SLOT(onMediaChosen()));
|
||||
}
|
||||
|
|
|
@ -509,7 +509,9 @@ void PsMainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) {
|
|||
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);
|
||||
|
||||
_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) {
|
||||
|
|
|
@ -24,8 +24,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
namespace Ui {
|
||||
|
||||
RoundButton::RoundButton(QWidget *parent, const QString &text, const style::BoxButton &st) : Button(parent)
|
||||
, _text(text.toUpper())
|
||||
, _fullText(text.toUpper())
|
||||
, _text(text)
|
||||
, _fullText(text)
|
||||
, _textWidth(st.font->width(_text))
|
||||
, _st(st)
|
||||
, a_textBgOverOpacity(0)
|
||||
|
@ -36,34 +36,62 @@ RoundButton::RoundButton(QWidget *parent, const QString &text, const style::BoxB
|
|||
setCursor(style::cur_pointer);
|
||||
}
|
||||
|
||||
void RoundButton::setTextTransform(TextTransform transform) {
|
||||
_transform = transform;
|
||||
updateText();
|
||||
}
|
||||
|
||||
void RoundButton::setText(const QString &text) {
|
||||
_text = 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);
|
||||
resizeToText();
|
||||
}
|
||||
|
||||
int RoundButton::textWidth() const {
|
||||
return _textWidth;
|
||||
}
|
||||
|
||||
void RoundButton::resizeToText() {
|
||||
if (_st.width <= 0) {
|
||||
resize(_textWidth - _st.width, _st.height);
|
||||
if (_fullWidthOverride < 0) {
|
||||
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 {
|
||||
if (_st.width < _textWidth + (_st.height - _st.font->height)) {
|
||||
_text = _st.font->elided(_fullText, qMax(_st.width - (_st.height - _st.font->height), 1));
|
||||
_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) {
|
||||
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();
|
||||
if (o > 0) {
|
||||
p.setOpacity(o);
|
||||
App::roundRect(p, rect(), _st.textBgOver);
|
||||
App::roundRect(p, rounded, _st.textBgOver);
|
||||
p.setOpacity(1);
|
||||
}
|
||||
if (!_text.isEmpty()) {
|
||||
|
@ -73,9 +101,13 @@ void RoundButton::paintEvent(QPaintEvent *e) {
|
|||
p.setPen(_st.textFg);
|
||||
}
|
||||
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;
|
||||
}
|
||||
p.drawTextLeft(textLeft, _st.padding.top() + _st.textTop, width(), _text);
|
||||
}
|
||||
_st.icon.paint(p, QPoint(0, 0), width());
|
||||
_st.icon.paint(p, QPoint(_st.padding.left(), _st.padding.right()), width());
|
||||
}
|
||||
|
||||
void RoundButton::step_over(float64 ms, bool timer) {
|
||||
|
|
|
@ -29,6 +29,15 @@ public:
|
|||
RoundButton(QWidget *parent, const QString &text, const style::BoxButton &st);
|
||||
|
||||
void setText(const QString &text);
|
||||
int textWidth() const;
|
||||
|
||||
void setFullWidth(int newFullWidth);
|
||||
|
||||
enum class TextTransform {
|
||||
NoTransform,
|
||||
ToUpper,
|
||||
};
|
||||
void setTextTransform(TextTransform transform);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
@ -38,10 +47,12 @@ protected:
|
|||
private:
|
||||
void step_over(float64 ms, bool timer);
|
||||
|
||||
void updateText();
|
||||
void resizeToText();
|
||||
|
||||
QString _text, _fullText;
|
||||
int _textWidth;
|
||||
int _fullWidthOverride = 0;
|
||||
|
||||
const style::BoxButton &_st;
|
||||
|
||||
|
@ -49,6 +60,8 @@ private:
|
|||
anim::cvalue a_textFg;
|
||||
Animation _a_over;
|
||||
|
||||
TextTransform _transform = TextTransform::NoTransform;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -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)
|
||||
, _text(text)
|
||||
, _st(st)
|
||||
, _autoFontPadding(0)
|
||||
, a_bg(st.bgColor->c)
|
||||
, a_text(st.color->c)
|
||||
, _a_appearance(animation(this, &FlatButton::step_appearance))
|
||||
|
@ -63,35 +62,10 @@ void FlatButton::setWidth(int32 w) {
|
|||
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 {
|
||||
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) {
|
||||
float64 dt = ms / _st.duration;
|
||||
if (dt >= 1) {
|
||||
|
@ -129,12 +103,11 @@ void FlatButton::paintEvent(QPaintEvent *e) {
|
|||
p.setOpacity(_opacity);
|
||||
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.setPen(a_text.current());
|
||||
|
||||
int32 top = (_state & StateOver) ? ((_state & StateDown) ? _st.downTextTop : _st.overTextTop) : _st.textTop;
|
||||
if (_autoFont) top += (_st.font->height - _autoFont->height) / 2;
|
||||
r.setTop(top);
|
||||
|
||||
p.drawText(r, _text, style::al_top);
|
||||
|
|
|
@ -31,8 +31,6 @@ public:
|
|||
|
||||
FlatButton(QWidget *parent, const QString &text, const style::flatButton &st);
|
||||
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
void step_appearance(float64 ms, bool timer);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void setOpacity(float64 o);
|
||||
|
@ -40,7 +38,6 @@ public:
|
|||
|
||||
void setText(const QString &text);
|
||||
void setWidth(int32 w);
|
||||
void setAutoFontSize(int32 padding, const QString &txt);
|
||||
|
||||
int32 textWidth() const;
|
||||
|
||||
|
@ -58,9 +55,6 @@ private:
|
|||
|
||||
style::flatButton _st;
|
||||
|
||||
int32 _autoFontPadding;
|
||||
style::font _autoFont;
|
||||
|
||||
anim::cvalue a_bg, a_text;
|
||||
Animation _a_appearance;
|
||||
|
||||
|
|
|
@ -351,7 +351,7 @@ void Checkbox::paintEvent(QPaintEvent *e) {
|
|||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||
|
||||
if (checked > 0) {
|
||||
p.drawSpriteCenter(_checkRect, _st.checkIcon);
|
||||
_st.checkIcon.paint(p, QPoint(0, 0), width());
|
||||
}
|
||||
}
|
||||
if (_checkRect.contains(r)) return;
|
||||
|
|
|
@ -27,6 +27,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "shortcuts.h"
|
||||
#include "lang.h"
|
||||
#include "ui/buttons/peer_avatar_button.h"
|
||||
#include "ui/buttons/round_button.h"
|
||||
#include "ui/flatbutton.h"
|
||||
|
||||
namespace Window {
|
||||
|
@ -37,19 +38,15 @@ TopBarWidget::TopBarWidget(MainWidget *w) : TWidget(w)
|
|||
, _selPeer(0)
|
||||
, _selCount(0)
|
||||
, _canDelete(false)
|
||||
, _selStrLeft(-st::topBarButton.width / 2)
|
||||
, _selStrLeft((-st::topBarClearButton.width + st::topBarClearButton.padding.left() + st::topBarClearButton.padding.right()) / 2)
|
||||
, _selStrWidth(0)
|
||||
, _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)
|
||||
, _delete(this, lang(lng_selected_delete), st::topBarActionButton)
|
||||
, _selectionButtonsWidth(_clearSelection->width() + _forward->width() + _delete->width())
|
||||
, _forwardDeleteWidth(qMax(_forward->textWidth(), _delete->textWidth()))
|
||||
, _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)
|
||||
, _search(this, st::topBarSearch) {
|
||||
|
||||
|
@ -57,10 +54,6 @@ TopBarWidget::TopBarWidget(MainWidget *w) : TWidget(w)
|
|||
connect(_delete, SIGNAL(clicked()), this, SLOT(onDeleteSelection()));
|
||||
connect(_clearSelection, SIGNAL(clicked()), this, SLOT(onClearSelection()));
|
||||
connect(_info, SIGNAL(clicked()), this, SLOT(onInfoClicked()));
|
||||
connect(_addContact, SIGNAL(clicked()), this, SLOT(onAddContact()));
|
||||
connect(_deleteContact, SIGNAL(clicked()), this, SLOT(onDeleteContact()));
|
||||
connect(_edit, SIGNAL(clicked()), this, SLOT(onEdit()));
|
||||
connect(_leaveGroup, SIGNAL(clicked()), this, SLOT(onDeleteAndExit()));
|
||||
connect(_search, SIGNAL(clicked()), this, SLOT(onSearch()));
|
||||
|
||||
setCursor(style::cur_pointer);
|
||||
|
@ -84,65 +77,6 @@ void TopBarWidget::onInfoClicked() {
|
|||
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() {
|
||||
Shortcuts::launch(qsl("search"));
|
||||
}
|
||||
|
@ -197,7 +131,7 @@ void TopBarWidget::paintEvent(QPaintEvent *e) {
|
|||
} else {
|
||||
p.setFont(st::linkFont);
|
||||
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) {
|
||||
int32 r = width();
|
||||
if (!_forward->isHidden() || !_delete->isHidden()) {
|
||||
int32 fullW = r - (_selectionButtonsWidth + (_selStrWidth - st::topBarButton.width) + st::topBarActionSkip);
|
||||
int32 selectedClearWidth = st::topBarButton.width, forwardDeleteWidth = st::topBarActionButton.width - _forwardDeleteWidth, skip = st::topBarActionSkip;
|
||||
int fullW = r - (_selectionButtonsWidth + (_selStrWidth - st::topBarClearButton.width + st::topBarClearButton.padding.left() + st::topBarClearButton.padding.right()) + 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) {
|
||||
int fit = 0;
|
||||
if (selectedClearWidth < -2 * (st::topBarMinPadding + 1)) {
|
||||
|
@ -245,7 +181,7 @@ void TopBarWidget::resizeEvent(QResizeEvent *e) {
|
|||
}
|
||||
if (fullW >= 0 || fit >= 3) break;
|
||||
}
|
||||
_clearSelection->setWidth(selectedClearWidth);
|
||||
_clearSelection->setFullWidth(selectedClearWidth);
|
||||
_forward->setWidth(_forwardDeleteWidth + forwardDeleteWidth);
|
||||
_delete->setWidth(_forwardDeleteWidth + forwardDeleteWidth);
|
||||
_selStrLeft = -selectedClearWidth / 2;
|
||||
|
@ -262,20 +198,12 @@ void TopBarWidget::resizeEvent(QResizeEvent *e) {
|
|||
_clearSelection->move(r -= _clearSelection->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);
|
||||
_search->move(width() - (_info->isHidden() ? st::topBarForwardPadding.right() : _info->width()) - _search->width(), 0);
|
||||
}
|
||||
|
||||
void TopBarWidget::startAnim() {
|
||||
_info->hide();
|
||||
_edit->hide();
|
||||
_leaveGroup->hide();
|
||||
_addContact->hide();
|
||||
_deleteContact->hide();
|
||||
_clearSelection->hide();
|
||||
_delete->hide();
|
||||
_forward->hide();
|
||||
|
@ -295,74 +223,37 @@ void TopBarWidget::showAll() {
|
|||
resizeEvent(0);
|
||||
return;
|
||||
}
|
||||
PeerData *p = nullptr/*App::main() ? App::main()->profilePeer() : 0*/, *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 (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();
|
||||
PeerData *h = App::main() ? App::main()->historyPeer() : 0, *o = App::main() ? App::main()->overviewPeer() : 0;
|
||||
if (_selCount) {
|
||||
_clearSelection->show();
|
||||
if (_canDelete) {
|
||||
_delete->show();
|
||||
} else {
|
||||
_edit->hide();
|
||||
_leaveGroup->hide();
|
||||
_addContact->show();
|
||||
_deleteContact->hide();
|
||||
_delete->hide();
|
||||
}
|
||||
_forward->show();
|
||||
_mediaType->hide();
|
||||
} else {
|
||||
_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();
|
||||
if (App::main() && App::main()->mediaTypeSwitch()) {
|
||||
_mediaType->show();
|
||||
} else {
|
||||
_edit->hide();
|
||||
}
|
||||
_leaveGroup->hide();
|
||||
_addContact->hide();
|
||||
_deleteContact->hide();
|
||||
if (!p && _selCount) {
|
||||
_clearSelection->show();
|
||||
if (_canDelete) {
|
||||
_delete->show();
|
||||
} else {
|
||||
_delete->hide();
|
||||
}
|
||||
_forward->show();
|
||||
_mediaType->hide();
|
||||
} else {
|
||||
_clearSelection->hide();
|
||||
_delete->hide();
|
||||
_forward->hide();
|
||||
if (App::main() && App::main()->mediaTypeSwitch()) {
|
||||
_mediaType->show();
|
||||
} else {
|
||||
_mediaType->hide();
|
||||
}
|
||||
}
|
||||
if (h && !o && !p && _clearSelection->isHidden()) {
|
||||
if (Adaptive::OneColumn()) {
|
||||
_info->setPeer(h);
|
||||
_info->show();
|
||||
} else {
|
||||
_info->hide();
|
||||
}
|
||||
_search->show();
|
||||
}
|
||||
if (h && !o && _clearSelection->isHidden()) {
|
||||
if (Adaptive::OneColumn()) {
|
||||
_info->setPeer(h);
|
||||
_info->show();
|
||||
} else {
|
||||
_search->hide();
|
||||
_info->hide();
|
||||
}
|
||||
_search->show();
|
||||
} else {
|
||||
_search->hide();
|
||||
_info->hide();
|
||||
}
|
||||
resizeEvent(nullptr);
|
||||
}
|
||||
|
@ -382,7 +273,7 @@ void TopBarWidget::updateAdaptiveLayout() {
|
|||
showAll();
|
||||
}
|
||||
|
||||
FlatButton *TopBarWidget::mediaTypeButton() {
|
||||
Ui::RoundButton *TopBarWidget::mediaTypeButton() {
|
||||
return _mediaType;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
|
||||
namespace Ui {
|
||||
class PeerAvatarButton;
|
||||
class RoundButton;
|
||||
} // namespace Ui
|
||||
class FlatButton;
|
||||
class IconedButton;
|
||||
|
@ -34,7 +35,6 @@ class TopBarWidget : public TWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
TopBarWidget(MainWidget *w);
|
||||
|
||||
void enterEvent(QEvent *e) override;
|
||||
|
@ -54,28 +54,19 @@ public:
|
|||
|
||||
void updateAdaptiveLayout();
|
||||
|
||||
FlatButton *mediaTypeButton();
|
||||
Ui::RoundButton *mediaTypeButton();
|
||||
|
||||
public slots:
|
||||
|
||||
void onForwardSelection();
|
||||
void onDeleteSelection();
|
||||
void onClearSelection();
|
||||
void onInfoClicked();
|
||||
void onAddContact();
|
||||
void onEdit();
|
||||
void onDeleteContact();
|
||||
void onDeleteContactSure();
|
||||
void onDeleteAndExit();
|
||||
void onDeleteAndExitSure();
|
||||
void onSearch();
|
||||
|
||||
signals:
|
||||
|
||||
void clicked();
|
||||
|
||||
private:
|
||||
|
||||
MainWidget *main();
|
||||
anim::fvalue a_over;
|
||||
Animation _a_appearance;
|
||||
|
@ -88,13 +79,12 @@ private:
|
|||
|
||||
bool _animating;
|
||||
|
||||
ChildWidget<FlatButton> _clearSelection;
|
||||
ChildWidget<Ui::RoundButton> _clearSelection;
|
||||
ChildWidget<FlatButton> _forward, _delete;
|
||||
int _selectionButtonsWidth, _forwardDeleteWidth;
|
||||
|
||||
ChildWidget<Ui::PeerAvatarButton> _info;
|
||||
ChildWidget<FlatButton> _edit, _leaveGroup, _addContact, _deleteContact;
|
||||
ChildWidget<FlatButton> _mediaType;
|
||||
ChildWidget<Ui::RoundButton> _mediaType;
|
||||
|
||||
ChildWidget<IconedButton> _search;
|
||||
|
||||
|
|
|
@ -1231,6 +1231,7 @@
|
|||
<ClCompile Include="SourceFiles\dialogs\dialogs_indexed_list.cpp" />
|
||||
<ClCompile Include="SourceFiles\dialogs\dialogs_layout.cpp" />
|
||||
<ClCompile Include="SourceFiles\dialogs\dialogs_list.cpp" />
|
||||
<ClCompile Include="SourceFiles\dialogs\dialogs_row.cpp" />
|
||||
<ClCompile Include="SourceFiles\dropdown.cpp" />
|
||||
<ClCompile Include="SourceFiles\facades.cpp" />
|
||||
<ClCompile Include="SourceFiles\fileuploader.cpp" />
|
||||
|
|
|
@ -1296,6 +1296,9 @@
|
|||
<ClCompile Include="GeneratedFiles\Release\moc_report_box.cpp">
|
||||
<Filter>GeneratedFiles\Release</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\dialogs\dialogs_row.cpp">
|
||||
<Filter>SourceFiles\dialogs</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SourceFiles\stdafx.h">
|
||||
|
|