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

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 KiB

After

Width:  |  Height:  |  Size: 239 KiB

View file

@ -56,6 +56,7 @@ adaptiveNormalWidth: 640px;
adaptiveWideWidth: 1366px;
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) {

View file

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 B

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

After

Width:  |  Height:  |  Size: 344 B

View file

@ -124,6 +124,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_flood_error" = "Too many tries. Please try again later.";
"lng_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";

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -19,7 +19,69 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
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;
}

View file

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

View file

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

View file

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

View file

@ -59,8 +59,7 @@ private:
class FakeRow {
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;
};

View file

@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "dialogs/dialogs_indexed_list.h"
#include "dialogs/dialogs_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 &region, 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 &region, 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 &region, 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 &region, 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 &region, 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 &region, 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 &region, 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 &region, 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 &region, 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 &region, 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);
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -509,7 +509,9 @@ void PsMainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) {
QPixmap pix = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->genUserpic(st::notifyMacPhotoSize) : QPixmap();
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) {

View file

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

View file

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

View file

@ -24,7 +24,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
FlatButton::FlatButton(QWidget *parent, const QString &text, const style::flatButton &st) : Button(parent)
, _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);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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